import { ENTITY_TYPE , PRIMARY_KEY , Entity } from '../glossary' ; import { Database , DatabaseEventsMap , SerializedEntity , SERIALIZED_INTERNAL_PROPERTIES_KEY , } from '../db/Database' ; import { inheritInternalProperties } from '../utils/inheritInternalProperties' ; export type DatabaseMessageEventData = { operationType : 'create' ; payload : Parameters < DatabaseEventsMap [ 'create' ] > ; } | { operationType : 'update' ; payload : Parameters < DatabaseEventsMap [ 'update' ] > ; } | { operationType : 'delete' ; payload : Parameters < DatabaseEventsMap [ 'delete' ] > ; } ; function removeListeners < Event extends keyof DatabaseEventsMap > ( event , db ) { const listeners = db . events . listeners ( event ) as DatabaseEventsMap [ Event ] [ ] ; listeners . forEach ( ( listener ) => { db . events . removeListener ( event , listener ) ; } ) ; return ( ) => { listeners . forEach ( ( listener ) => { db . events . addListener ( event , listener ) ; } ) ; } ; } note function deserializeEntity ( entity ) { const { [ SERIALIZED_INTERNAL_PROPERTIES_KEY ] : internalProperties , ... publicProperties } = entity ; inheritInternalProperties ( publicProperties , { [ ENTITY_TYPE ] : internalProperties . entityType , [ PRIMARY_KEY ] : internalProperties . primaryKey } ) ; return publicProperties ; } /**
 * Synchronizes database operations across multiple clients.
 */ export function sync ( db ) { const IS_BROWSER = typeof window !== 'undefined' ; const SUPPORTS_BROADCAST_CHANNEL = typeof BroadcastChannel !== 'undefined' ; if ( ! IS_BROWSER || ! SUPPORTS_BROADCAST_CHANNEL ) { return ; } const channel = new BroadcastChannel ( 'mswjs/data/sync' ) ; channel . addEventListener ( 'message' , ( event ) => { const [ sourceId ] = event . data . payload ; if ( db . id !== sourceId ) { return ; } const restoreListeners = removeListeners ( event . data . operationType , db ) ; switch ( event . data . operationType ) { case 'create' : { const [ modelName , entity , customPrimaryKey ] = event . data . payload [ 1 ] ; db . create ( modelName , deserializeEntity ( entity ) , customPrimaryKey ) ; break ; } case 'update' : { const [ modelName , prevEntity , nextEntity ] = event . data . payload [ 1 ] ; db . update ( modelName , deserializeEntity ( prevEntity ) , deserializeEntity ( nextEntity ) ) ; break ; } default : { db [ event . data . operationType ] ( ... event . data . payload [ 1 ] ) ; } } restoreListeners ( ) ; } ) ; function broadcastDatabaseEvent < Event extends keyof DatabaseEventsMap > ( operationType ) { return ( ... payload ) => { channel . postMessage ( { operationType , payload } as DatabaseMessageEventData ) ; } ; } db . events . on ( 'create' , broadcastDatabaseEvent ( 'create' ) ) ; db . events . on ( 'update' , broadcastDatabaseEvent ( 'update' ) ) ; db . events . on ( 'delete' , broadcastDatabaseEvent ( 'delete' ) ) ; }