@ricardojbd/ngrx-signals-broadcast-sync
Version:
Enables seamless synchronization of state between browser contexts
1 lines • 9.13 kB
Source Map (JSON)
{"version":3,"file":"ricardojbd-ngrx-signals-broadcast-sync.mjs","sources":["../../../../libs/ngrx-signals-broadcast-sync/src/lib/with-broadcast-sync.ts","../../../../libs/ngrx-signals-broadcast-sync/src/ricardojbd-ngrx-signals-broadcast-sync.ts"],"sourcesContent":["import {\n signalStoreFeature,\n SignalStoreFeature,\n SignalStoreFeatureResult,\n withMethods,\n withHooks,\n getState,\n patchState\n} from '@ngrx/signals';\nimport { effect, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformServer } from '@angular/common';\nimport isEqual from 'lodash.isequal';\nimport { Message, Options, BroadcastSyncFeatureResult } from './models';\n\nconst NOOP = () => null;\n\nconst BroadcastSyncStub: Pick<BroadcastSyncFeatureResult, 'methods'>['methods'] = {\n getBroadcastChannel: NOOP,\n broadcastState: NOOP,\n _requestBroadcastState: NOOP,\n _patchStateFromBroadcast: NOOP\n};\n\n/**\n * Adds broadcast synchronization capabilities to a Signal Store.\n *\n * This function enables state synchronization between multiple clients using the `BroadcastChannel` API.\n * It allows clients to request, send, and patch the state across multiple contexts.\n *\n * @template Input The type of the store feature result, extending `SignalStoreFeatureResult`.\n * @param channel The name of the broadcast channel to use for synchronizing state across clients.\n * @returns A Signal Store feature with broadcast capabilities.\n */\nexport function withBroadcastSync<Input extends SignalStoreFeatureResult>(\n channel: string\n): SignalStoreFeature<Input, BroadcastSyncFeatureResult>;\n\n/**\n * Adds broadcast synchronization capabilities to a Signal Store.\n *\n * This function enables state synchronization between multiple clients using the `BroadcastChannel` API.\n * It allows clients to request, send, and patch the state across multiple contexts.\n *\n * @template Input The type of the store feature result, extending `SignalStoreFeatureResult`.\n * @param options A configuration object specifying the broadcast channel and additional behavior for state synchronization.\n * @returns A Signal Store feature with customizable broadcast capabilities.\n */\nexport function withBroadcastSync<Input extends SignalStoreFeatureResult>(\n options: Options<Input['state']>\n): SignalStoreFeature<Input, BroadcastSyncFeatureResult>;\n\n/**\n * Adds broadcast synchronization capabilities to a Signal Store.\n *\n * This function enables state synchronization between multiple clients using the `BroadcastChannel` API.\n * It can be invoked either with a broadcast channel name or with a configuration object (`Options`).\n * It allows clients to request, send, and patch the state across multiple contexts.\n *\n * @template Input The type of the store feature result, extending `SignalStoreFeatureResult`.\n * @param channelOrOptions Either the name of the broadcast channel or a configuration object.\n * If a string is provided, it is treated as the broadcast channel name.\n * If an `Options` object is provided, it allows further configuration of the broadcast behavior.\n * @returns A Signal Store feature that adds methods for broadcast synchronization.\n */\nexport function withBroadcastSync<Input extends SignalStoreFeatureResult>(\n channelOrOptions: Options<Input['state']> | string\n): SignalStoreFeature<Input, BroadcastSyncFeatureResult> {\n const {\n channel,\n requestState = false,\n select = (state: Input['state']) => state,\n messageEventInterceptor = (event: MessageEvent<Message<Input['state']>>) => event.data,\n broadcastStateInterceptor = (state: Input['state']) => state,\n onMessageError = () => null\n } = typeof channelOrOptions === 'string' ? { channel: channelOrOptions } : channelOrOptions;\n\n const runGuard = (platformId: object) =>\n isPlatformServer(platformId) || typeof window?.BroadcastChannel === 'undefined';\n let stateChannel: BroadcastChannel | null;\n let lastSyncedState: Partial<Input['state']> | null = null;\n\n return signalStoreFeature(\n withMethods((store, platformId = inject(PLATFORM_ID)) => {\n if (runGuard(platformId)) {\n console.warn(`'withBroadcastSync' provides non-functional implementation due to server-side execution`);\n return BroadcastSyncStub;\n }\n\n return {\n getBroadcastChannel(): BroadcastChannel | null {\n return stateChannel;\n },\n\n broadcastState(): void {\n let state = select(getState(store));\n\n if (isEqual(state, lastSyncedState)) {\n return;\n }\n\n state = broadcastStateInterceptor(state);\n\n if (stateChannel != null) {\n lastSyncedState = state; // Avoid broadcast duplicated state\n stateChannel.postMessage({ type: 'UPDATE_STATE', state });\n }\n },\n\n _requestBroadcastState(): void {\n lastSyncedState = select(getState(store)); // Avoid broadcast initial state\n stateChannel?.postMessage({ type: 'REQUEST_STATE' });\n },\n\n _patchStateFromBroadcast(state: Input['state']) {\n lastSyncedState = state; // Avoid broadcast this state change\n patchState(store, state);\n }\n };\n }),\n withHooks({\n onInit(store, platformId = inject(PLATFORM_ID)) {\n if (runGuard(platformId)) {\n return;\n }\n\n stateChannel = new BroadcastChannel(channel);\n\n if (requestState) {\n store._requestBroadcastState();\n }\n\n stateChannel.onmessage = (event: MessageEvent<Message<Input['state']>>) => {\n const message = messageEventInterceptor(event);\n\n switch (message.type) {\n case 'REQUEST_STATE': {\n lastSyncedState = null; // Force broadcast state\n store.broadcastState();\n break;\n }\n case 'UPDATE_STATE': {\n store._patchStateFromBroadcast(message.state);\n break;\n }\n default: {\n console.warn(`Unknown message type \"${message}\" in the broadcast channel \"${channel}\"`);\n }\n }\n };\n\n stateChannel.onmessageerror = (event: MessageEvent) => onMessageError(event);\n\n effect(() => {\n store.broadcastState();\n });\n },\n\n onDestroy() {\n stateChannel?.close();\n }\n })\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}