atom.io 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/chunk-H4Q5FTPZ.js +11 -0
  2. package/dist/chunk-H4Q5FTPZ.js.map +1 -0
  3. package/dist/index.cjs +35 -60
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +8 -8
  6. package/dist/index.js +12 -36
  7. package/dist/index.js.map +1 -1
  8. package/internal/dist/index.cjs +268 -195
  9. package/internal/dist/index.cjs.map +1 -1
  10. package/internal/dist/index.d.ts +36 -11
  11. package/internal/dist/index.js +258 -195
  12. package/internal/dist/index.js.map +1 -1
  13. package/internal/src/atom/create-regular-atom.ts +2 -3
  14. package/internal/src/families/find-in-store.ts +74 -0
  15. package/internal/src/families/index.ts +1 -0
  16. package/internal/src/get-state/get-from-store.ts +14 -0
  17. package/internal/src/get-state/index.ts +2 -0
  18. package/internal/src/{read-or-compute-value.ts → get-state/read-or-compute-value.ts} +3 -3
  19. package/internal/src/index.ts +1 -1
  20. package/internal/src/ingest-updates/ingest-atom-update.ts +2 -2
  21. package/internal/src/ingest-updates/ingest-transaction-update.ts +1 -0
  22. package/internal/src/mutable/create-mutable-atom.ts +3 -4
  23. package/internal/src/mutable/tracker.ts +43 -35
  24. package/internal/src/mutable/transceiver.ts +1 -1
  25. package/internal/src/not-found-error.ts +14 -3
  26. package/internal/src/operation.ts +2 -1
  27. package/internal/src/selector/create-writable-selector.ts +2 -1
  28. package/internal/src/selector/register-selector.ts +6 -5
  29. package/internal/src/set-state/index.ts +1 -0
  30. package/internal/src/set-state/set-atom.ts +17 -3
  31. package/internal/src/set-state/set-into-store.ts +24 -0
  32. package/internal/src/set-state/stow-update.ts +2 -4
  33. package/internal/src/store/store.ts +13 -4
  34. package/internal/src/subscribe/subscribe-to-root-atoms.ts +1 -1
  35. package/internal/src/timeline/add-atom-to-timeline.ts +5 -5
  36. package/internal/src/transaction/abort-transaction.ts +2 -1
  37. package/internal/src/transaction/apply-transaction.ts +5 -3
  38. package/internal/src/transaction/build-transaction.ts +20 -11
  39. package/internal/src/transaction/create-transaction.ts +2 -3
  40. package/internal/src/transaction/index.ts +3 -2
  41. package/internal/src/transaction/is-root-store.ts +23 -0
  42. package/package.json +10 -10
  43. package/react/dist/index.cjs +27 -21
  44. package/react/dist/index.cjs.map +1 -1
  45. package/react/dist/index.d.ts +8 -2
  46. package/react/dist/index.js +28 -22
  47. package/react/dist/index.js.map +1 -1
  48. package/react/src/index.ts +4 -1
  49. package/react/src/use-i.ts +35 -0
  50. package/react/src/use-json.ts +38 -0
  51. package/react/src/use-o.ts +33 -0
  52. package/react/src/use-tl.ts +45 -0
  53. package/realtime-client/dist/index.cjs +167 -64
  54. package/realtime-client/dist/index.cjs.map +1 -1
  55. package/realtime-client/dist/index.d.ts +10 -6
  56. package/realtime-client/dist/index.js +158 -63
  57. package/realtime-client/dist/index.js.map +1 -1
  58. package/realtime-client/src/index.ts +2 -1
  59. package/realtime-client/src/pull-family-member.ts +3 -3
  60. package/realtime-client/src/pull-mutable-family-member.ts +4 -4
  61. package/realtime-client/src/pull-mutable.ts +4 -4
  62. package/realtime-client/src/pull-state.ts +7 -6
  63. package/realtime-client/src/{realtime-client-store.ts → realtime-client-stores/client-main-store.ts} +0 -8
  64. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +15 -0
  65. package/realtime-client/src/realtime-client-stores/index.ts +2 -0
  66. package/realtime-client/src/sync-server-action.ts +134 -40
  67. package/realtime-client/src/sync-state.ts +19 -0
  68. package/realtime-react/dist/index.cjs +43 -26
  69. package/realtime-react/dist/index.cjs.map +1 -1
  70. package/realtime-react/dist/index.d.ts +3 -1
  71. package/realtime-react/dist/index.js +41 -25
  72. package/realtime-react/dist/index.js.map +1 -1
  73. package/realtime-react/src/index.ts +1 -0
  74. package/realtime-react/src/on-mount.ts +3 -21
  75. package/realtime-react/src/use-realtime-service.ts +1 -1
  76. package/realtime-react/src/use-single-effect.ts +29 -0
  77. package/realtime-react/src/use-sync-server-action.ts +4 -7
  78. package/realtime-react/src/use-sync.ts +17 -0
  79. package/realtime-server/dist/index.cjs +239 -56
  80. package/realtime-server/dist/index.cjs.map +1 -1
  81. package/realtime-server/dist/index.d.ts +140 -9
  82. package/realtime-server/dist/index.js +228 -58
  83. package/realtime-server/dist/index.js.map +1 -1
  84. package/realtime-server/src/index.ts +2 -0
  85. package/realtime-server/src/realtime-action-synchronizer.ts +95 -14
  86. package/realtime-server/src/realtime-family-provider.ts +11 -6
  87. package/realtime-server/src/realtime-mutable-family-provider.ts +8 -6
  88. package/realtime-server/src/realtime-mutable-provider.ts +3 -2
  89. package/realtime-server/src/realtime-server-stores/index.ts +2 -0
  90. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +115 -0
  91. package/realtime-server/src/realtime-server-stores/server-user-store.ts +45 -0
  92. package/realtime-server/src/realtime-state-provider.ts +18 -11
  93. package/realtime-server/src/realtime-state-receiver.ts +2 -2
  94. package/realtime-server/src/realtime-state-synchronizer.ts +23 -0
  95. package/realtime-testing/dist/index.cjs +65 -26
  96. package/realtime-testing/dist/index.cjs.map +1 -1
  97. package/realtime-testing/dist/index.d.ts +11 -7
  98. package/realtime-testing/dist/index.js +64 -26
  99. package/realtime-testing/dist/index.js.map +1 -1
  100. package/realtime-testing/src/setup-realtime-test.tsx +83 -43
  101. package/src/find-state.ts +8 -16
  102. package/src/get-state.ts +2 -11
  103. package/src/logger.ts +1 -0
  104. package/src/set-state.ts +1 -13
  105. package/src/silo.ts +7 -3
  106. package/src/transaction.ts +3 -3
  107. package/react/src/store-hooks.ts +0 -87
  108. package/realtime-server/src/realtime-server-store.ts +0 -39
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/realtime-context.tsx","../src/use-pull.ts","../src/use-realtime-service.ts","../src/on-mount.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts","../src/use-sync-server-action.ts"],"names":["RTC","React","StoreContext","AtomIO"],"mappings":"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","sourcesContent":["import { useI } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nexport type RealtimeReactStore = {\n\tsocket: Socket | null\n\tservices: Map<\n\t\tstring,\n\t\t[consumerCount: number, dispose: (() => void) | undefined]\n\t> | null\n}\n\nexport const RealtimeContext = React.createContext<RealtimeReactStore>({\n\tsocket: null,\n\tservices: null,\n})\n\nexport const RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}> = ({ children, socket }) => {\n\tconst services = React.useRef(new Map<string, [number, () => void]>()).current\n\tconst setMyId = useI(RTC.myIdState__INTERNAL)\n\tReact.useEffect(() => {\n\t\tsetMyId(socket?.id)\n\t\tsocket?.on(`connect`, () => {\n\t\t\tsetMyId(socket.id)\n\t\t})\n\t\tsocket?.on(`disconnect`, () => {\n\t\t\tsetMyId(undefined)\n\t\t})\n\t}, [socket, setMyId])\n\treturn (\n\t\t<RealtimeContext.Provider value={{ socket, services }}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePull<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullState(token, socket, store),\n\t)\n}\n","import * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\nimport { onMount } from \"./on-mount\"\nimport { RealtimeContext } from \"./realtime-context\"\n\nexport function useRealtimeService(\n\tkey: string,\n\tcreate: (socket: Socket) => (() => void) | undefined,\n): void {\n\tconst { socket, services } = React.useContext(RealtimeContext)\n\tonMount(() => {\n\t\tlet service = services?.get(key)\n\t\tif (service) {\n\t\t\tservice[0]++\n\t\t} else {\n\t\t\tconst dispose = socket ? create(socket) : undefined\n\t\t\tservice = [1, dispose]\n\t\t\tservices?.set(key, service)\n\t\t}\n\t\treturn () => {\n\t\t\tif (service) {\n\t\t\t\tservice[0]--\n\t\t\t\tif (service[0] === 0) {\n\t\t\t\t\tservice[1]?.()\n\t\t\t\t\tservices?.delete(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [socket?.id])\n}\n","import * as React from \"react\"\n\nexport function onMount(\n\teffect: () => (() => void) | undefined,\n\tdeps?: any[],\n): void {\n\tif (process.env.NODE_ENV === `development`) {\n\t\tconst cleanup = React.useRef<(() => void) | undefined>()\n\t\tReact.useEffect(() => {\n\t\t\tlet dispose = cleanup.current\n\t\t\tif (dispose) {\n\t\t\t\treturn () => {\n\t\t\t\t\tdispose?.()\n\t\t\t\t\tcleanup.current = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t\tdispose = effect()\n\t\t\tcleanup.current = dispose\n\t\t}, deps)\n\t} else {\n\t\tReact.useEffect(effect, deps)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullFamilyMember(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutable<\n\tT extends Transceiver<any>,\n\tJ extends Json.Serializable,\n>(token: AtomIO.MutableAtomToken<T, J>): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableState(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutableFamilyMember<\n\tT extends Transceiver<any>,\n\tJ extends Json.Serializable,\n>(token: AtomIO.MutableAtomToken<T, J>): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableFamilyMember(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePush<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`push:${token.key}`, (socket) =>\n\t\tRTC.pushState(token, socket, store),\n\t)\n}\n","import * as AtomIO from \"atom.io\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useServerAction<ƒ extends AtomIO.ƒn>(\n\ttoken: AtomIO.TransactionToken<ƒ>,\n): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {\n\tconst store = React.useContext(StoreContext)\n\n\tuseRealtimeService(`tx:${token.key}`, (socket) =>\n\t\tRTC.serverAction(token, socket, store),\n\t)\n\treturn AtomIO.runTransaction(token, undefined, store)\n}\n","import * as AtomIO from \"atom.io\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useSyncAction<ƒ extends AtomIO.ƒn>(\n\ttoken: AtomIO.TransactionToken<ƒ>,\n): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {\n\tconst store = React.useContext(StoreContext)\n\tconst updateQueueState = AtomIO.findState(RTC.updateQueueAtoms, token)\n\tconst updateQueue = useO(updateQueueState)\n\n\tuseRealtimeService(`tx:${token.key}`, (socket) =>\n\t\tRTC.syncAction(token, socket, updateQueue, store),\n\t)\n\treturn AtomIO.runTransaction(token, undefined, store)\n}\n"]}
1
+ {"version":3,"sources":["../src/realtime-context.tsx","../src/use-pull.ts","../src/use-realtime-service.ts","../src/use-single-effect.ts","../src/on-mount.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts","../src/use-sync-server-action.ts","../src/use-sync.ts"],"names":["RTC","React","StoreContext","AtomIO"],"mappings":"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","sourcesContent":["import { useI } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nexport type RealtimeReactStore = {\n\tsocket: Socket | null\n\tservices: Map<\n\t\tstring,\n\t\t[consumerCount: number, dispose: (() => void) | undefined]\n\t> | null\n}\n\nexport const RealtimeContext = React.createContext<RealtimeReactStore>({\n\tsocket: null,\n\tservices: null,\n})\n\nexport const RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}> = ({ children, socket }) => {\n\tconst services = React.useRef(new Map<string, [number, () => void]>()).current\n\tconst setMyId = useI(RTC.myIdState__INTERNAL)\n\tReact.useEffect(() => {\n\t\tsetMyId(socket?.id)\n\t\tsocket?.on(`connect`, () => {\n\t\t\tsetMyId(socket.id)\n\t\t})\n\t\tsocket?.on(`disconnect`, () => {\n\t\t\tsetMyId(undefined)\n\t\t})\n\t}, [socket, setMyId])\n\treturn (\n\t\t<RealtimeContext.Provider value={{ socket, services }}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePull<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullState(token, socket, store),\n\t)\n}\n","import * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\nimport { onMount } from \"./on-mount\"\nimport { RealtimeContext } from \"./realtime-context\"\n\nexport function useRealtimeService(\n\tkey: string,\n\tcreate: (socket: Socket) => (() => void) | undefined,\n): void {\n\tconst { socket, services } = React.useContext(RealtimeContext)\n\tonMount(() => {\n\t\tlet service = services?.get(key)\n\t\tif (service) {\n\t\t\tservice[0]++\n\t\t} else {\n\t\t\tconst dispose = socket ? create(socket) : undefined\n\t\t\tservice = [1, dispose]\n\t\t\tservices?.set(key, service)\n\t\t}\n\t\treturn () => {\n\t\t\tif (service) {\n\t\t\t\tservice[0]--\n\t\t\t\tif (service[0] === 0) {\n\t\t\t\t\tservice[1]?.()\n\t\t\t\t\tservices?.delete(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n}\n","import * as React from \"react\"\n\nconst { NODE_ENV } = process.env\nconst IN_DEV = NODE_ENV === `development` || NODE_ENV === `test`\n\nfunction noop() {}\n\nexport function useSingleEffect(\n\teffect: () => (() => void) | undefined,\n\tdeps: unknown[],\n): void {\n\tif (IN_DEV) {\n\t\tconst cleanup = React.useRef<() => void>(noop)\n\t\tReact.useEffect(() => {\n\t\t\tlet dispose = cleanup.current\n\t\t\tif (dispose === noop) {\n\t\t\t\tdispose = effect() ?? noop\n\t\t\t\tcleanup.current = dispose\n\t\t\t} else {\n\t\t\t\treturn () => {\n\t\t\t\t\tdispose()\n\t\t\t\t\tcleanup.current = noop\n\t\t\t\t}\n\t\t\t}\n\t\t}, deps)\n\t} else {\n\t\tReact.useEffect(effect, deps)\n\t}\n}\n","import { useSingleEffect } from \"./use-single-effect\"\n\nexport function onMount(effect: () => (() => void) | undefined): void {\n\tuseSingleEffect(effect, [])\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullFamilyMember(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutable<\n\tT extends Transceiver<any>,\n\tJ extends Json.Serializable,\n>(token: AtomIO.MutableAtomToken<T, J>): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableState(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutableFamilyMember<\n\tT extends Transceiver<any>,\n\tJ extends Json.Serializable,\n>(token: AtomIO.MutableAtomToken<T, J>): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableFamilyMember(token, socket, store),\n\t)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePush<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`push:${token.key}`, (socket) =>\n\t\tRTC.pushState(token, socket, store),\n\t)\n}\n","import * as AtomIO from \"atom.io\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useServerAction<ƒ extends AtomIO.ƒn>(\n\ttoken: AtomIO.TransactionToken<ƒ>,\n): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {\n\tconst store = React.useContext(StoreContext)\n\n\tuseRealtimeService(`tx:${token.key}`, (socket) =>\n\t\tRTC.serverAction(token, socket, store),\n\t)\n\treturn AtomIO.runTransaction(token, undefined, store)\n}\n","import * as AtomIO from \"atom.io\"\nimport { StoreContext } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useSyncAction<ƒ extends AtomIO.ƒn>(\n\ttoken: AtomIO.TransactionToken<ƒ>,\n): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`tx-sync:${token.key}`, (socket) => {\n\t\treturn RTC.syncAction(token, socket, store)\n\t})\n\treturn AtomIO.runTransaction(token, undefined, store)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useSync<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): J {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`sync:${token.key}`, (socket) =>\n\t\tRTC.syncState(token, socket, store),\n\t)\n\treturn useO(token)\n}\n"]}
@@ -6,3 +6,4 @@ export * from "./use-pull-mutable-family-member"
6
6
  export * from "./use-push"
7
7
  export * from "./use-server-action"
8
8
  export * from "./use-sync-server-action"
9
+ export * from "./use-sync"
@@ -1,23 +1,5 @@
1
- import * as React from "react"
1
+ import { useSingleEffect } from "./use-single-effect"
2
2
 
3
- export function onMount(
4
- effect: () => (() => void) | undefined,
5
- deps?: any[],
6
- ): void {
7
- if (process.env.NODE_ENV === `development`) {
8
- const cleanup = React.useRef<(() => void) | undefined>()
9
- React.useEffect(() => {
10
- let dispose = cleanup.current
11
- if (dispose) {
12
- return () => {
13
- dispose?.()
14
- cleanup.current = undefined
15
- }
16
- }
17
- dispose = effect()
18
- cleanup.current = dispose
19
- }, deps)
20
- } else {
21
- React.useEffect(effect, deps)
22
- }
3
+ export function onMount(effect: () => (() => void) | undefined): void {
4
+ useSingleEffect(effect, [])
23
5
  }
@@ -26,5 +26,5 @@ export function useRealtimeService(
26
26
  }
27
27
  }
28
28
  }
29
- }, [socket?.id])
29
+ })
30
30
  }
@@ -0,0 +1,29 @@
1
+ import * as React from "react"
2
+
3
+ const { NODE_ENV } = process.env
4
+ const IN_DEV = NODE_ENV === `development` || NODE_ENV === `test`
5
+
6
+ function noop() {}
7
+
8
+ export function useSingleEffect(
9
+ effect: () => (() => void) | undefined,
10
+ deps: unknown[],
11
+ ): void {
12
+ if (IN_DEV) {
13
+ const cleanup = React.useRef<() => void>(noop)
14
+ React.useEffect(() => {
15
+ let dispose = cleanup.current
16
+ if (dispose === noop) {
17
+ dispose = effect() ?? noop
18
+ cleanup.current = dispose
19
+ } else {
20
+ return () => {
21
+ dispose()
22
+ cleanup.current = noop
23
+ }
24
+ }
25
+ }, deps)
26
+ } else {
27
+ React.useEffect(effect, deps)
28
+ }
29
+ }
@@ -1,5 +1,5 @@
1
1
  import * as AtomIO from "atom.io"
2
- import { StoreContext, useO } from "atom.io/react"
2
+ import { StoreContext } from "atom.io/react"
3
3
  import * as RTC from "atom.io/realtime-client"
4
4
  import * as React from "react"
5
5
 
@@ -9,11 +9,8 @@ export function useSyncAction<ƒ extends AtomIO.ƒn>(
9
9
  token: AtomIO.TransactionToken<ƒ>,
10
10
  ): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {
11
11
  const store = React.useContext(StoreContext)
12
- const updateQueueState = AtomIO.findState(RTC.updateQueueAtoms, token)
13
- const updateQueue = useO(updateQueueState)
14
-
15
- useRealtimeService(`tx:${token.key}`, (socket) =>
16
- RTC.syncAction(token, socket, updateQueue, store),
17
- )
12
+ useRealtimeService(`tx-sync:${token.key}`, (socket) => {
13
+ return RTC.syncAction(token, socket, store)
14
+ })
18
15
  return AtomIO.runTransaction(token, undefined, store)
19
16
  }
@@ -0,0 +1,17 @@
1
+ import type * as AtomIO from "atom.io"
2
+ import type { Json } from "atom.io/json"
3
+ import { StoreContext, useO } from "atom.io/react"
4
+ import * as RTC from "atom.io/realtime-client"
5
+ import * as React from "react"
6
+
7
+ import { useRealtimeService } from "./use-realtime-service"
8
+
9
+ export function useSync<J extends Json.Serializable>(
10
+ token: AtomIO.WritableToken<J>,
11
+ ): J {
12
+ const store = React.useContext(StoreContext)
13
+ useRealtimeService(`sync:${token.key}`, (socket) =>
14
+ RTC.syncState(token, socket, store),
15
+ )
16
+ return useO(token)
17
+ }
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var AtomIO7 = require('atom.io');
3
+ var AtomIO = require('atom.io');
4
+ var data = require('atom.io/data');
5
+ var setRtx = require('atom.io/transceivers/set-rtx');
4
6
  var internal = require('atom.io/internal');
5
7
  var json = require('atom.io/json');
6
8
 
@@ -22,7 +24,7 @@ function _interopNamespace(e) {
22
24
  return Object.freeze(n);
23
25
  }
24
26
 
25
- var AtomIO7__namespace = /*#__PURE__*/_interopNamespace(AtomIO7);
27
+ var AtomIO__namespace = /*#__PURE__*/_interopNamespace(AtomIO);
26
28
 
27
29
  var __defProp = Object.defineProperty;
28
30
  var __defProps = Object.defineProperties;
@@ -43,19 +45,121 @@ var __spreadValues = (a, b) => {
43
45
  return a;
44
46
  };
45
47
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
48
+ var userIndex = AtomIO.atom({
49
+ key: `usersIndex`,
50
+ mutable: true,
51
+ default: () => new setRtx.SetRTX(),
52
+ toJson: (set) => set.toJSON(),
53
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
54
+ });
55
+ var usersOfSockets = data.join({
56
+ key: `usersOfSockets`,
57
+ between: [`user`, `socket`],
58
+ cardinality: `1:1`
59
+ });
60
+ var roomIndex = AtomIO.atom({
61
+ key: `conclaveIndex`,
62
+ default: () => new setRtx.SetRTX(),
63
+ mutable: true,
64
+ toJson: (set) => set.toJSON(),
65
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
66
+ });
67
+ var DEFAULT_USER_IN_ROOM_META = {
68
+ enteredAtEpoch: 0
69
+ };
70
+ var usersInRooms = data.join(
71
+ {
72
+ key: `usersInRooms`,
73
+ between: [`room`, `user`],
74
+ cardinality: `1:n`
75
+ },
76
+ DEFAULT_USER_IN_ROOM_META
77
+ );
78
+ var completeUpdateAtoms = AtomIO.atomFamily({
79
+ key: `completeUpdate`,
80
+ default: null
81
+ });
82
+ var transactionRedactorAtoms = AtomIO.atomFamily({
83
+ key: `transactionRedactor`,
84
+ default: { filter: (updates) => updates }
85
+ });
86
+ var redactedUpdateSelectors = AtomIO.selectorFamily({
87
+ key: `redactedUpdate`,
88
+ get: ([transactionKey, updateId]) => ({ get, find }) => {
89
+ const update = get(find(completeUpdateAtoms, updateId));
90
+ const { filter } = get(find(transactionRedactorAtoms, transactionKey));
91
+ if (update && filter) {
92
+ return __spreadProps(__spreadValues({}, update), { updates: filter(update.updates) });
93
+ }
94
+ return null;
95
+ }
96
+ });
97
+ var userUnacknowledgedUpdatesAtoms = AtomIO.atomFamily({
98
+ key: `unacknowledgedUpdates`,
99
+ default: () => []
100
+ });
101
+ var socketUnacknowledgedUpdatesSelectors = AtomIO.selectorFamily({
102
+ key: `socketUnacknowledgedUpdates`,
103
+ get: (socketId) => ({ get, find }) => {
104
+ const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
105
+ const userKey = get(userKeyState);
106
+ if (!userKey) {
107
+ return [];
108
+ }
109
+ const unacknowledgedUpdatesState = find(
110
+ userUnacknowledgedUpdatesAtoms,
111
+ userKey
112
+ );
113
+ const unacknowledgedUpdates = get(unacknowledgedUpdatesState);
114
+ return unacknowledgedUpdates;
115
+ },
116
+ set: (socketId) => ({ set, get, find }, newUpdates) => {
117
+ const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
118
+ const userKey = get(userKeyState);
119
+ if (!userKey) {
120
+ return;
121
+ }
122
+ const unacknowledgedUpdatesState = find(
123
+ userUnacknowledgedUpdatesAtoms,
124
+ userKey
125
+ );
126
+ set(unacknowledgedUpdatesState, newUpdates);
127
+ }
128
+ });
129
+ var userEpochAtoms = AtomIO.atomFamily({
130
+ key: `clientEpoch`,
131
+ default: null
132
+ });
133
+ var socketEpochSelectors = AtomIO.selectorFamily({
134
+ key: `socketEpoch`,
135
+ get: (socketId) => ({ get, find }) => {
136
+ const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
137
+ const userKey = get(userKeyState);
138
+ if (!userKey) {
139
+ return null;
140
+ }
141
+ const userEpochState = find(userEpochAtoms, userKey);
142
+ const userEpoch = get(userEpochState);
143
+ return userEpoch;
144
+ },
145
+ set: (socketId) => ({ set, get, find }, newEpoch) => {
146
+ const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
147
+ const userKey = get(userKeyState);
148
+ if (!userKey) {
149
+ return;
150
+ }
151
+ const userEpochState = find(userEpochAtoms, userKey);
152
+ set(userEpochState, newEpoch);
153
+ }
154
+ });
46
155
  function realtimeStateProvider({
47
156
  socket,
48
157
  store = internal.IMPLICIT.STORE
49
158
  }) {
50
159
  return function stateProvider(token) {
51
- let unsubscribeFromStateUpdates = null;
52
- const fillUnsubRequest = () => {
53
- socket.off(`unsub:${token.key}`, fillUnsubRequest);
54
- unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
55
- unsubscribeFromStateUpdates = null;
56
- };
160
+ let unsubscribeFromStateUpdates;
57
161
  const fillSubRequest = () => {
58
- socket.emit(`serve:${token.key}`, AtomIO7__namespace.getState(token, store));
162
+ socket.emit(`serve:${token.key}`, internal.getFromStore(token, store));
59
163
  unsubscribeFromStateUpdates = internal.subscribeToState(
60
164
  token,
61
165
  ({ newValue }) => {
@@ -64,12 +168,36 @@ function realtimeStateProvider({
64
168
  `expose-single:${socket.id}`,
65
169
  store
66
170
  );
171
+ const fillUnsubRequest = () => {
172
+ socket.off(`unsub:${token.key}`, fillUnsubRequest);
173
+ if (unsubscribeFromStateUpdates) {
174
+ unsubscribeFromStateUpdates();
175
+ unsubscribeFromStateUpdates = void 0;
176
+ }
177
+ };
67
178
  socket.on(`unsub:${token.key}`, fillUnsubRequest);
68
179
  };
69
180
  socket.on(`sub:${token.key}`, fillSubRequest);
70
181
  return () => {
71
182
  socket.off(`sub:${token.key}`, fillSubRequest);
72
- unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
183
+ if (unsubscribeFromStateUpdates) {
184
+ unsubscribeFromStateUpdates();
185
+ unsubscribeFromStateUpdates = void 0;
186
+ }
187
+ };
188
+ };
189
+ }
190
+ function realtimeStateSynchronizer({
191
+ socket,
192
+ store = internal.IMPLICIT.STORE
193
+ }) {
194
+ return function stateSynchronizer(token) {
195
+ const fillGetRequest = () => {
196
+ socket.emit(`value:${token.key}`, internal.getFromStore(token, store));
197
+ };
198
+ socket.on(`get:${token.key}`, fillGetRequest);
199
+ return () => {
200
+ socket.off(`get:${token.key}`, fillGetRequest);
73
201
  };
74
202
  };
75
203
  }
@@ -98,13 +226,13 @@ function realtimeFamilyProvider({
98
226
  const fillSubRequest = (subKey) => {
99
227
  var _a;
100
228
  if (subKey === void 0) {
101
- const keys = AtomIO7__namespace.getState(index, store);
229
+ const keys = internal.getFromStore(index, store);
102
230
  for (const key of keys) {
103
- const token = AtomIO7__namespace.findInStore(family, key, store);
231
+ const token = internal.findInStore(family, key, store);
104
232
  socket.emit(
105
233
  `serve:${family.key}`,
106
234
  json.parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
107
- AtomIO7__namespace.getState(token, store)
235
+ internal.getFromStore(token, store)
108
236
  );
109
237
  }
110
238
  const unsubscribeFromTokenCreation = family.subject.subscribe(
@@ -130,7 +258,7 @@ function realtimeFamilyProvider({
130
258
  socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest);
131
259
  } else {
132
260
  const token = family(subKey);
133
- socket.emit(`serve:${token.key}`, AtomIO7__namespace.getState(token, store));
261
+ socket.emit(`serve:${token.key}`, internal.getFromStore(token, store));
134
262
  const unsubscribe = internal.subscribeToState(
135
263
  token,
136
264
  ({ newValue }) => {
@@ -173,7 +301,7 @@ function realtimeMutableProvider({
173
301
  unsubscribeFromStateUpdates = null;
174
302
  };
175
303
  const fillSubRequest = () => {
176
- socket.emit(`init:${token.key}`, AtomIO7__namespace.getState(jsonToken, store));
304
+ socket.emit(`init:${token.key}`, internal.getFromStore(jsonToken, store));
177
305
  unsubscribeFromStateUpdates = internal.subscribeToState(
178
306
  trackerToken,
179
307
  ({ newValue }) => {
@@ -216,15 +344,15 @@ function realtimeMutableFamilyProvider({
216
344
  const fillSubRequest = (subKey) => {
217
345
  var _a;
218
346
  if (subKey === void 0) {
219
- const keys = AtomIO7__namespace.getState(index, store);
347
+ const keys = internal.getFromStore(index, store);
220
348
  for (const key of keys) {
221
- const token = family(key);
349
+ const token = internal.findInStore(family, key, store);
222
350
  const jsonToken = internal.getJsonToken(token);
223
351
  const trackerToken = internal.getUpdateToken(token);
224
352
  socket.emit(
225
353
  `init:${family.key}`,
226
354
  json.parseJson(((_a = jsonToken.family) == null ? void 0 : _a.subKey) || `null`),
227
- AtomIO7__namespace.getState(jsonToken, store)
355
+ internal.getFromStore(jsonToken, store)
228
356
  );
229
357
  const unsubFromUpdates = internal.subscribeToState(
230
358
  trackerToken,
@@ -250,7 +378,7 @@ function realtimeMutableFamilyProvider({
250
378
  socket.emit(
251
379
  `init:${family.key}`,
252
380
  json.parseJson(((_a2 = jsonToken.family) == null ? void 0 : _a2.subKey) || `null`),
253
- AtomIO7__namespace.getState(jsonToken, store)
381
+ internal.getFromStore(jsonToken, store)
254
382
  );
255
383
  const unsubFromUpdates = internal.subscribeToState(
256
384
  trackerToken,
@@ -274,7 +402,7 @@ function realtimeMutableFamilyProvider({
274
402
  const token = family(subKey);
275
403
  const jsonToken = internal.getJsonToken(token);
276
404
  const updateToken = internal.getUpdateToken(token);
277
- socket.emit(`init:${token.key}`, AtomIO7__namespace.getState(jsonToken, store));
405
+ socket.emit(`init:${token.key}`, internal.getFromStore(jsonToken, store));
278
406
  const unsubscribe = internal.subscribeToState(
279
407
  updateToken,
280
408
  ({ newValue }) => {
@@ -308,7 +436,7 @@ function realtimeStateReceiver({
308
436
  store = internal.IMPLICIT.STORE
309
437
  }) {
310
438
  return function stateReceiver(token) {
311
- const publish = (newValue) => AtomIO7.setState(token, newValue, store);
439
+ const publish = (newValue) => internal.setIntoStore(token, newValue, store);
312
440
  const fillPubUnclaim = () => {
313
441
  socket.off(`pub:${token.key}`, publish);
314
442
  socket.off(`unclaim:${token.key}`, fillPubUnclaim);
@@ -334,7 +462,7 @@ function realtimeActionReceiver({
334
462
  const performanceKeyStart = `${performanceKey}:start`;
335
463
  const performanceKeyEnd = `${performanceKey}:end`;
336
464
  performance.mark(performanceKeyStart);
337
- AtomIO7__namespace.runTransaction(tx, update.id, store)(...update.params);
465
+ AtomIO__namespace.runTransaction(tx, update.id, store)(...update.params);
338
466
  performance.mark(performanceKeyEnd);
339
467
  const metric = performance.measure(
340
468
  performanceKey,
@@ -347,45 +475,36 @@ function realtimeActionReceiver({
347
475
  return () => socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
348
476
  };
349
477
  }
350
- var completeUpdateAtoms = AtomIO7__namespace.atomFamily({
351
- key: `completeUpdate`,
352
- default: null
353
- });
354
- var transactionRedactorAtoms = AtomIO7__namespace.atomFamily({
355
- key: `transactionRedactor`,
356
- default: { filter: (updates) => updates }
357
- });
358
- var redactedUpdateSelectors = AtomIO7__namespace.selectorFamily({
359
- key: `redactedUpdate`,
360
- get: ([transactionKey, updateId]) => ({ get, find }) => {
361
- const update = get(find(completeUpdateAtoms, updateId));
362
- const { filter } = get(find(transactionRedactorAtoms, transactionKey));
363
- if (update && filter) {
364
- return __spreadProps(__spreadValues({}, update), { updates: filter(update.updates) });
365
- }
366
- return null;
367
- }
368
- });
369
-
370
- // realtime-server/src/realtime-action-synchronizer.ts
371
478
  function realtimeActionSynchronizer({
372
479
  socket,
373
480
  store = internal.IMPLICIT.STORE
374
481
  }) {
375
482
  return function actionSynchronizer(tx, filter) {
483
+ const userKeyState = internal.findInStore(
484
+ usersOfSockets.states.userKeyOfSocket,
485
+ socket.id,
486
+ store
487
+ );
488
+ const userKey = internal.getFromStore(userKeyState, store);
489
+ const socketUnacknowledgedUpdatesState = internal.findInStore(
490
+ socketUnacknowledgedUpdatesSelectors,
491
+ socket.id,
492
+ store
493
+ );
494
+ const socketUnacknowledgedUpdates = internal.getFromStore(
495
+ socketUnacknowledgedUpdatesState,
496
+ store
497
+ );
376
498
  if (filter) {
377
- AtomIO7__namespace.setState(
378
- AtomIO7__namespace.findState(transactionRedactorAtoms, tx.key),
379
- { filter },
380
- store
381
- );
499
+ const redactorState = internal.findInStore(transactionRedactorAtoms, tx.key, store);
500
+ internal.setIntoStore(redactorState, { filter }, store);
382
501
  }
383
502
  const fillTransactionRequest = (update) => {
384
503
  const performanceKey = `tx-run:${tx.key}:${update.id}`;
385
504
  const performanceKeyStart = `${performanceKey}:start`;
386
505
  const performanceKeyEnd = `${performanceKey}:end`;
387
506
  performance.mark(performanceKeyStart);
388
- AtomIO7__namespace.runTransaction(tx, update.id, store)(...update.params);
507
+ AtomIO__namespace.runTransaction(tx, update.id, store)(...update.params);
389
508
  performance.mark(performanceKeyEnd);
390
509
  const metric = performance.measure(
391
510
  performanceKey,
@@ -394,32 +513,85 @@ function realtimeActionSynchronizer({
394
513
  );
395
514
  store == null ? void 0 : store.logger.info(`\u{1F680}`, `transaction`, tx.key, update.id, metric.duration);
396
515
  };
516
+ socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
397
517
  socket.on(`tx-run:${tx.key}`, fillTransactionRequest);
518
+ let unsubscribeFromTransaction;
398
519
  const fillTransactionSubscriptionRequest = () => {
399
- const unsubscribe = internal.subscribeToTransaction(
520
+ unsubscribeFromTransaction = internal.subscribeToTransaction(
400
521
  tx,
401
522
  (update) => {
402
- unsubscribe();
403
- const updateState = AtomIO7__namespace.findState(completeUpdateAtoms, update.id);
404
- AtomIO7__namespace.setState(updateState, update, store);
405
- const toEmit = filter ? AtomIO7__namespace.getState(
406
- AtomIO7__namespace.findState(redactedUpdateSelectors, [tx.key, update.id]),
523
+ const updateState = internal.findInStore(completeUpdateAtoms, update.id, store);
524
+ internal.setIntoStore(updateState, update, store);
525
+ const toEmit = filter ? internal.getFromStore(
526
+ internal.findInStore(redactedUpdateSelectors, [tx.key, update.id], store),
407
527
  store
408
528
  ) : update;
529
+ internal.setIntoStore(
530
+ socketUnacknowledgedUpdatesState,
531
+ (updates) => {
532
+ if (toEmit) {
533
+ updates.push(toEmit);
534
+ updates.sort((a, b) => a.epoch - b.epoch);
535
+ }
536
+ return updates;
537
+ },
538
+ store
539
+ );
409
540
  socket.emit(`tx-new:${tx.key}`, toEmit);
410
541
  },
411
542
  `tx-sub:${tx.key}:${socket.id}`,
412
543
  store
413
544
  );
414
- socket.on(`tx-unsub:${tx.key}`, unsubscribe);
545
+ socket.on(`tx-unsub:${tx.key}`, unsubscribeFromTransaction);
415
546
  };
416
547
  socket.on(`tx-sub:${tx.key}`, fillTransactionSubscriptionRequest);
548
+ let i = 1;
549
+ let next = 1;
550
+ const retry = setInterval(() => {
551
+ const toEmit = socketUnacknowledgedUpdates[0];
552
+ console.log(userKey, socketUnacknowledgedUpdates);
553
+ if (toEmit && i === next) {
554
+ socket.emit(`tx-new:${tx.key}`, toEmit);
555
+ next *= 2;
556
+ }
557
+ i++;
558
+ }, 250);
559
+ const trackClientAcknowledgement = (epoch) => {
560
+ var _a;
561
+ i = 1;
562
+ next = 1;
563
+ const socketEpochState = internal.findInStore(
564
+ socketEpochSelectors,
565
+ socket.id,
566
+ store
567
+ );
568
+ internal.setIntoStore(socketEpochState, epoch, store);
569
+ if (((_a = socketUnacknowledgedUpdates[0]) == null ? void 0 : _a.epoch) === epoch) {
570
+ internal.setIntoStore(
571
+ socketUnacknowledgedUpdatesState,
572
+ (updates) => {
573
+ updates.shift();
574
+ return updates;
575
+ },
576
+ store
577
+ );
578
+ }
579
+ };
580
+ socket.on(`tx-ack:${tx.key}`, trackClientAcknowledgement);
417
581
  return () => {
582
+ if (unsubscribeFromTransaction) {
583
+ unsubscribeFromTransaction();
584
+ unsubscribeFromTransaction = void 0;
585
+ }
586
+ clearInterval(retry);
418
587
  socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
588
+ socket.off(`tx-sub:${tx.key}`, fillTransactionSubscriptionRequest);
419
589
  };
420
590
  };
421
591
  }
422
592
 
593
+ exports.DEFAULT_USER_IN_ROOM_META = DEFAULT_USER_IN_ROOM_META;
594
+ exports.completeUpdateAtoms = completeUpdateAtoms;
423
595
  exports.realtimeActionReceiver = realtimeActionReceiver;
424
596
  exports.realtimeActionSynchronizer = realtimeActionSynchronizer;
425
597
  exports.realtimeFamilyProvider = realtimeFamilyProvider;
@@ -427,5 +599,16 @@ exports.realtimeMutableFamilyProvider = realtimeMutableFamilyProvider;
427
599
  exports.realtimeMutableProvider = realtimeMutableProvider;
428
600
  exports.realtimeStateProvider = realtimeStateProvider;
429
601
  exports.realtimeStateReceiver = realtimeStateReceiver;
602
+ exports.realtimeStateSynchronizer = realtimeStateSynchronizer;
603
+ exports.redactedUpdateSelectors = redactedUpdateSelectors;
604
+ exports.roomIndex = roomIndex;
605
+ exports.socketEpochSelectors = socketEpochSelectors;
606
+ exports.socketUnacknowledgedUpdatesSelectors = socketUnacknowledgedUpdatesSelectors;
607
+ exports.transactionRedactorAtoms = transactionRedactorAtoms;
608
+ exports.userEpochAtoms = userEpochAtoms;
609
+ exports.userIndex = userIndex;
610
+ exports.userUnacknowledgedUpdatesAtoms = userUnacknowledgedUpdatesAtoms;
611
+ exports.usersInRooms = usersInRooms;
612
+ exports.usersOfSockets = usersOfSockets;
430
613
  //# sourceMappingURL=out.js.map
431
614
  //# sourceMappingURL=index.cjs.map