forked from TanStack/query
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(broadcastQueryClient): experimental support for tab/window synci…
…ng (TanStack#1793) * feat(subscriptions): add event types and metadata to subscriptions * feat(broadcastQueryClient): experimental support for tab/window syncing * better types, update tests * feat(broadcastQueryClient): experimental support for tab/window syncing * rebase and update * use transactions * update docs * Update broadcastQueryClient.md * Update index.ts
- Loading branch information
1 parent
9fad892
commit 4bbfe2a
Showing
9 changed files
with
230 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"internal": true, | ||
"main": "../lib/broadcastQueryClient-experimental/index.js", | ||
"module": "../es/broadcastQueryClient-experimental/index.js", | ||
"types": "../types/broadcastQueryClient-experimental/index.d.ts" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
id: broadcastQueryClient | ||
title: broadcastQueryClient (Experimental) | ||
--- | ||
|
||
> VERY IMPORTANT: This utility is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages. | ||
`broadcastQueryClient` is a utility for broadcasting and syncing the state of your queryClient between browser tabs/windows with the same origin. | ||
|
||
## Installation | ||
|
||
This utility comes packaged with `react-query` and is available under the `react-query/broadcastQueryClient-experimental` import. | ||
|
||
## Usage | ||
|
||
Import the `broadcastQueryClient` function, and pass it your `QueryClient` instance, and optionally, set a `broadcastChannel`. | ||
|
||
```ts | ||
import { broadcastQueryClient } from 'react-query/broadcastQueryClient-experimental' | ||
|
||
const queryClient = new QueryClient() | ||
|
||
broadcastQueryClient({ | ||
queryClient, | ||
broadcastChannel: 'my-app', | ||
}) | ||
``` | ||
|
||
## API | ||
|
||
### `broadcastQueryClient` | ||
|
||
Pass this function a `QueryClient` instance and optionally, a `broadcastChannel`. | ||
|
||
```ts | ||
broadcastQueryClient({ queryClient, broadcastChannel }) | ||
``` | ||
|
||
### `Options` | ||
|
||
An object of options: | ||
|
||
```ts | ||
interface broadcastQueryClient { | ||
/** The QueryClient to sync */ | ||
queryClient: QueryClient | ||
/** This is the unique channel name that will be used | ||
* to communicate between tabs and windows */ | ||
broadcastChannel?: string | ||
} | ||
``` | ||
|
||
The default options are: | ||
|
||
```ts | ||
{ | ||
broadcastChannel = 'react-query', | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { BroadcastChannel } from 'broadcast-channel' | ||
import { QueryClient } from '../core' | ||
|
||
interface BroadcastQueryClientOptions { | ||
queryClient: QueryClient | ||
broadcastChannel: string | ||
} | ||
|
||
export function broadcastQueryClient({ | ||
queryClient, | ||
broadcastChannel = 'react-query', | ||
}: BroadcastQueryClientOptions) { | ||
let transaction = false | ||
const tx = (cb: () => void) => { | ||
transaction = true | ||
cb() | ||
transaction = false | ||
} | ||
|
||
const channel = new BroadcastChannel(broadcastChannel, { | ||
webWorkerSupport: false, | ||
}) | ||
|
||
const queryCache = queryClient.getQueryCache() | ||
|
||
queryClient.getQueryCache().subscribe(queryEvent => { | ||
if (transaction || !queryEvent?.query) { | ||
return | ||
} | ||
|
||
const { | ||
query: { queryHash, queryKey, state }, | ||
} = queryEvent | ||
|
||
if ( | ||
queryEvent.type === 'queryUpdated' && | ||
queryEvent.action?.type === 'success' | ||
) { | ||
channel.postMessage({ | ||
type: 'queryUpdated', | ||
queryHash, | ||
queryKey, | ||
state, | ||
}) | ||
} | ||
|
||
if (queryEvent.type === 'queryRemoved') { | ||
channel.postMessage({ | ||
type: 'queryRemoved', | ||
queryHash, | ||
queryKey, | ||
}) | ||
} | ||
}) | ||
|
||
channel.onmessage = action => { | ||
if (!action?.type) { | ||
return | ||
} | ||
|
||
tx(() => { | ||
const { type, queryHash, queryKey, state } = action | ||
|
||
if (type === 'queryUpdated') { | ||
const query = queryCache.get(queryHash) | ||
|
||
if (query) { | ||
query.setState(state) | ||
return | ||
} | ||
|
||
queryCache.build( | ||
queryClient, | ||
{ | ||
queryKey, | ||
queryHash, | ||
}, | ||
state | ||
) | ||
} else if (type === 'queryRemoved') { | ||
const query = queryCache.get(queryHash) | ||
|
||
if (query) { | ||
queryCache.remove(query) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1944,6 +1944,13 @@ | |
dependencies: | ||
regenerator-runtime "^0.13.4" | ||
|
||
"@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": | ||
version "7.12.13" | ||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" | ||
integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== | ||
dependencies: | ||
regenerator-runtime "^0.13.4" | ||
|
||
"@babel/runtime@^7.8.4": | ||
version "7.10.2" | ||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" | ||
|
@@ -3088,6 +3095,11 @@ bcrypt-pbkdf@^1.0.0: | |
dependencies: | ||
tweetnacl "^0.14.3" | ||
|
||
big-integer@^1.6.16: | ||
version "1.6.48" | ||
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" | ||
integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== | ||
|
||
binary-extensions@^1.0.0: | ||
version "1.13.1" | ||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" | ||
|
@@ -3136,6 +3148,19 @@ braces@^3.0.1: | |
dependencies: | ||
fill-range "^7.0.1" | ||
|
||
broadcast-channel@^3.4.1: | ||
version "3.4.1" | ||
resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.4.1.tgz#65b63068d0a5216026a19905c9b2d5e9adf0928a" | ||
integrity sha512-VXYivSkuBeQY+pL5hNQQNvBdKKQINBAROm4G8lAbWQfOZ7Yn4TMcgLNlJyEqlkxy5G8JJBsI3VJ1u8FUTOROcg== | ||
dependencies: | ||
"@babel/runtime" "^7.7.2" | ||
detect-node "^2.0.4" | ||
js-sha3 "0.8.0" | ||
microseconds "0.2.0" | ||
nano-time "1.0.0" | ||
rimraf "3.0.2" | ||
unload "2.2.0" | ||
|
||
brotli-size@^4.0.0: | ||
version "4.0.0" | ||
resolved "https://registry.yarnpkg.com/brotli-size/-/brotli-size-4.0.0.tgz#a05ee3faad3c0e700a2f2da826ba6b4d76e69e5e" | ||
|
@@ -3652,6 +3677,11 @@ detect-newline@^3.0.0: | |
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" | ||
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== | ||
|
||
detect-node@^2.0.4: | ||
version "2.0.4" | ||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" | ||
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== | ||
|
||
diff-sequences@^25.2.6: | ||
version "25.2.6" | ||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" | ||
|
@@ -5468,6 +5498,11 @@ jest@^26.0.1: | |
import-local "^3.0.2" | ||
jest-cli "^26.0.1" | ||
|
||
[email protected]: | ||
version "0.8.0" | ||
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" | ||
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== | ||
|
||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: | ||
version "4.0.0" | ||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" | ||
|
@@ -5863,6 +5898,11 @@ micromatch@^4.0.2: | |
braces "^3.0.1" | ||
picomatch "^2.0.5" | ||
|
||
[email protected]: | ||
version "0.2.0" | ||
resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" | ||
integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== | ||
|
||
[email protected]: | ||
version "1.42.0" | ||
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" | ||
|
@@ -5945,6 +5985,13 @@ nan@^2.12.1: | |
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" | ||
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== | ||
|
||
[email protected]: | ||
version "1.0.0" | ||
resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" | ||
integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= | ||
dependencies: | ||
big-integer "^1.6.16" | ||
|
||
nanoid@^3.0.1: | ||
version "3.1.3" | ||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.3.tgz#b2bcfcfda4b4d6838bc22a0c8dd3c0a17a204c20" | ||
|
@@ -6823,7 +6870,7 @@ [email protected]: | |
dependencies: | ||
glob "^7.1.3" | ||
|
||
rimraf@^3.0.0, rimraf@^3.0.2: | ||
rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: | ||
version "3.0.2" | ||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" | ||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== | ||
|
@@ -7755,6 +7802,14 @@ universalify@^0.1.0: | |
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" | ||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== | ||
|
||
[email protected]: | ||
version "2.2.0" | ||
resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" | ||
integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== | ||
dependencies: | ||
"@babel/runtime" "^7.6.2" | ||
detect-node "^2.0.4" | ||
|
||
unquote@~1.1.1: | ||
version "1.1.1" | ||
resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" | ||
|