-
Notifications
You must be signed in to change notification settings - Fork 44
Open
Description
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
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.- 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
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 :)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels