Initial discussion about this feature can be found here: #289.
Adding the withTabSync extension to a store would synchronize the state between browser tabs and windows. The suggested implementation is inspired by use-broadcast-ts
Behavior
- When the state changes in one tab, it posts a message using
BroadcastChannel. When a tab receives a message, it updates it's own state.
- When a new tab opens, it populates the store normally and sends the data to other tabs. This helps keep tabs converged after initialization.
- Conflict resolution: last message arrival wins (updates are applied in the order received).
Implementation
This feature could follow a similar pattern to withStorageSync.
File structure
src/lib/tab-sync/
broadcast-channel.service.ts
with-tab-sync.ts
tests/
broadcast-channel.service.ts
Manages the BroadcastChannel, providing a wrapper for postMessage and closing the BroadcastChannel when the beforeunload event fires.
with-tab-sync.ts
Similar to with-storage-sync.ts but uses BroadcastChannelService instead of LocalStorageService. Provides the following config:
export type SyncConfig<State> = {
/**
* The name of the BroadcastChannel. Must be unique per origin.
*/
name: string;
/**
* Flag indicating whether tabs should sync automatically.
*
* `true` by default
*/
autoSync?: boolean;
/**
* Function to select that portion of the state which should be synced with other tabs
*
* Returns the whole state object by default
*/
select?: (state: State) => unknown;
};
Constraints / Support
BroadcastChannel is same-origin only so it can only be used within a single app.
BroadcastChannel is not supported on old browsers https://caniuse.com/?search=broadcastchannel. If BroadcastChannel is not available, this extension is a no-op and logs a warning.
- If executed in a non-browser environment (e.g. SSR), this extension is a no-op and logs a warning.
Possible Improvements
- We could only send properties that are patched instead of the whole state. This would potentially improve performance and lessen the chances of conflicts.
- Add an
initSync config option that specifies whether a new tab's store should be populated normally and broadcast to other tabs ('push') or from other tabs ('pull')
If the maintainers agree with the approach and it's okay with them I'd like to take a crack and implementing it :)
Initial discussion about this feature can be found here: #289.
Adding the
withTabSyncextension to a store would synchronize the state between browser tabs and windows. The suggested implementation is inspired by use-broadcast-tsBehavior
BroadcastChannel. When a tab receives a message, it updates it's own state.Implementation
This feature could follow a similar pattern to
withStorageSync.File structure
broadcast-channel.service.ts
Manages the BroadcastChannel, providing a wrapper for
postMessageand closing the BroadcastChannel when thebeforeunloadevent fires.with-tab-sync.ts
Similar to
with-storage-sync.tsbut usesBroadcastChannelServiceinstead ofLocalStorageService. Provides the following config:Constraints / Support
BroadcastChannelis same-origin only so it can only be used within a single app.BroadcastChannelis not supported on old browsers https://caniuse.com/?search=broadcastchannel. IfBroadcastChannelis not available, this extension is a no-op and logs a warning.Possible Improvements
initSyncconfig option that specifies whether a new tab's store should be populated normally and broadcast to other tabs ('push') or from other tabs ('pull')If the maintainers agree with the approach and it's okay with them I'd like to take a crack and implementing it :)