atom.io 0.44.12 → 0.44.13

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 (38) hide show
  1. package/dist/internal/index.js +8 -8
  2. package/dist/internal/index.js.map +1 -1
  3. package/dist/introspection/index.d.ts.map +1 -1
  4. package/dist/main/index.d.ts +6 -4
  5. package/dist/main/index.d.ts.map +1 -1
  6. package/dist/main/index.js +4 -3
  7. package/dist/main/index.js.map +1 -1
  8. package/dist/realtime/index.d.ts +94 -31
  9. package/dist/realtime/index.d.ts.map +1 -1
  10. package/dist/realtime/index.js +34 -1
  11. package/dist/realtime/index.js.map +1 -1
  12. package/dist/realtime-react/index.d.ts +3 -1
  13. package/dist/realtime-react/index.d.ts.map +1 -1
  14. package/dist/realtime-react/index.js +7 -4
  15. package/dist/realtime-react/index.js.map +1 -1
  16. package/dist/realtime-server/index.d.ts +43 -13
  17. package/dist/realtime-server/index.d.ts.map +1 -1
  18. package/dist/realtime-server/index.js +120 -63
  19. package/dist/realtime-server/index.js.map +1 -1
  20. package/package.json +10 -10
  21. package/src/internal/families/create-readonly-held-selector-family.ts +2 -2
  22. package/src/internal/families/create-readonly-pure-selector-family.ts +2 -2
  23. package/src/internal/families/create-regular-atom-family.ts +2 -2
  24. package/src/internal/families/create-writable-held-selector-family.ts +2 -2
  25. package/src/internal/families/create-writable-pure-selector-family.ts +2 -2
  26. package/src/internal/mutable/create-mutable-atom-family.ts +2 -2
  27. package/src/internal/not-found-error.ts +2 -2
  28. package/src/main/logger.ts +8 -4
  29. package/src/realtime/cast-socket.ts +73 -0
  30. package/src/realtime/index.ts +2 -0
  31. package/src/realtime/socket-interface.ts +1 -1
  32. package/src/realtime/standard-schema.ts +72 -0
  33. package/src/realtime-react/index.ts +1 -0
  34. package/src/realtime-react/realtime-context.tsx +0 -9
  35. package/src/realtime-react/use-realtime-rooms.ts +13 -0
  36. package/src/realtime-server/realtime-server-stores/index.ts +1 -1
  37. package/src/realtime-server/realtime-server-stores/provide-rooms.ts +368 -0
  38. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +0 -227
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["redactorAtoms: RegularAtomFamilyToken<\n\t{\n\t\tocclude: (updates: TransactionSubEvent[]) => TransactionSubEvent[]\n\t},\n\tUserKey\n>","unacknowledgedUpdatesAtoms: RegularAtomFamilyToken<\n\tContinuitySyncTransactionUpdate[],\n\tUserKey\n>","initialPayload: Json.Serializable[]","isAvailable","socketAtoms: RegularAtomFamilyToken<Socket | null, SocketKey>","socketKeysAtom: MutableAtomToken<UList<SocketKey>>","userKeysAtom: MutableAtomToken<UList<UserKey>>","usersOfSockets: JoinToken<\n\t`user`,\n\tUserKey,\n\t`socket`,\n\tSocketKey,\n\t`1:1`\n>","selfListSelectors: PureSelectorFamilyToken<UserKey[], UserKey>","ROOMS: RoomMap","roomMeta: { count: number }","roomQueue: [string, ...Json.Array][]","forward: AllEventsListener<EventsMap>"],"sources":["../../src/realtime-server/continuity/continuity-store.ts","../../src/realtime-server/continuity/provide-outcomes.ts","../../src/realtime-server/continuity/provide-perspectives.ts","../../src/realtime-server/continuity/provide-startup-payloads.ts","../../src/realtime-server/continuity/receive-action-requests.ts","../../src/realtime-server/continuity/track-acknowledgements.ts","../../src/realtime-server/continuity/provide-continuity.ts","../../src/realtime-server/ipc-sockets/custom-socket.ts","../../src/realtime-server/ipc-sockets/child-socket.ts","../../src/realtime-server/ipc-sockets/parent-socket.ts","../../src/realtime-server/realtime-family-provider.ts","../../src/realtime-server/realtime-mutable-family-provider.ts","../../src/realtime-server/realtime-mutable-provider.ts","../../src/realtime-server/realtime-server-stores/server-user-store.ts","../../src/realtime-server/realtime-server-stores/server-room-external-store.ts","../../src/realtime-server/realtime-state-provider.ts","../../src/realtime-server/realtime-state-receiver.ts"],"sourcesContent":["import type {\n\tRegularAtomFamilyToken,\n\tTransactionOutcomeEvent,\n\tTransactionSubEvent,\n} from \"atom.io\"\nimport { atomFamily } from \"atom.io\"\nimport type { UserKey } from \"atom.io/realtime\"\n\nexport function redactTransactionUpdateContent(\n\tvisibleStateKeys: string[],\n\tupdates: TransactionSubEvent[],\n): TransactionSubEvent[] {\n\treturn updates\n\t\t.map((update): TransactionSubEvent => {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase `transaction_outcome`: {\n\t\t\t\t\tconst redacted = redactTransactionUpdateContent(\n\t\t\t\t\t\tvisibleStateKeys,\n\t\t\t\t\t\tupdate.subEvents,\n\t\t\t\t\t)\n\t\t\t\t\treturn { ...update, subEvents: redacted }\n\t\t\t\t}\n\t\t\t\tcase `atom_update`:\n\t\t\t\tcase `molecule_creation`:\n\t\t\t\tcase `molecule_disposal`:\n\t\t\t\tcase `molecule_transfer`:\n\t\t\t\tcase `state_creation`:\n\t\t\t\tcase `state_disposal`:\n\t\t\t\t\treturn update\n\t\t\t}\n\t\t})\n\t\t.filter((update) => {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase `atom_update`:\n\t\t\t\tcase `state_creation`:\n\t\t\t\tcase `state_disposal`:\n\t\t\t\t\treturn visibleStateKeys.includes(update.token.key)\n\t\t\t\tcase `molecule_creation`:\n\t\t\t\tcase `transaction_outcome`:\n\t\t\t\tcase `molecule_disposal`:\n\t\t\t\tcase `molecule_transfer`:\n\t\t\t\t\treturn true\n\t\t\t}\n\t\t})\n}\n\nexport const redactorAtoms: RegularAtomFamilyToken<\n\t{\n\t\tocclude: (updates: TransactionSubEvent[]) => TransactionSubEvent[]\n\t},\n\tUserKey\n> = atomFamily({\n\tkey: `redactor`,\n\tdefault: { occlude: (updates) => updates },\n})\n\nexport type ContinuitySyncTransactionUpdate = Pick<\n\tTransactionOutcomeEvent<any>,\n\t`epoch` | `id` | `output` | `subEvents` | `token`\n>\nexport const unacknowledgedUpdatesAtoms: RegularAtomFamilyToken<\n\tContinuitySyncTransactionUpdate[],\n\tUserKey\n> = atomFamily({\n\tkey: `unacknowledgedUpdates`,\n\tdefault: () => [],\n})\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetUpdateToken,\n\tsetIntoStore,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\n\nimport {\n\tredactTransactionUpdateContent,\n\tunacknowledgedUpdatesAtoms,\n} from \"./continuity-store\"\n\nexport function provideOutcomes(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst unsubscribeFunctions = new Set<() => void>()\n\n\tfor (const transaction of continuity.actions) {\n\t\tconst unsubscribeFromTransaction = subscribeToTransaction(\n\t\t\tstore,\n\t\t\ttransaction,\n\t\t\t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\t(outcomes) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst visibleKeys = continuity.globals\n\t\t\t\t\t\t.map((atom) => {\n\t\t\t\t\t\t\tif (atom.type === `atom`) {\n\t\t\t\t\t\t\t\treturn atom.key\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn getUpdateToken(atom).key\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\tcontinuity.perspectives.flatMap((perspective) => {\n\t\t\t\t\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\t\t\t\t\tconst userPerspectiveTokenState = findInStore(\n\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\tviewAtoms,\n\t\t\t\t\t\t\t\t\tuserKey,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tconst visibleTokens = getFromStore(\n\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\tuserPerspectiveTokenState,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\treturn visibleTokens.map((token) => {\n\t\t\t\t\t\t\t\t\tconst key =\n\t\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? `*` + token.key : token.key\n\t\t\t\t\t\t\t\t\treturn key\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\tconst redactedUpdates = redactTransactionUpdateContent(\n\t\t\t\t\t\tvisibleKeys,\n\t\t\t\t\t\toutcomes.subEvents,\n\t\t\t\t\t)\n\t\t\t\t\tconst redactedUpdate = {\n\t\t\t\t\t\t...outcomes,\n\t\t\t\t\t\tupdates: redactedUpdates,\n\t\t\t\t\t}\n\t\t\t\t\tsetIntoStore(store, unacknowledgedUpdatesAtoms, userKey, (updates) => {\n\t\t\t\t\t\tif (redactedUpdate) {\n\t\t\t\t\t\t\tupdates.push(redactedUpdate)\n\t\t\t\t\t\t\tupdates.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t\t`${userKey} unacknowledged update queue now has`,\n\t\t\t\t\t\t\t\tupdates.length,\n\t\t\t\t\t\t\t\t`items`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn updates\n\t\t\t\t\t})\n\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\t\t\tredactedUpdate as Json.Serializable,\n\t\t\t\t\t)\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t`āŒ`,\n\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t`${userKey} failed to send update from transaction ${transaction.key} to ${userKey}`,\n\t\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tunsubscribeFunctions.add(unsubscribeFromTransaction)\n\t}\n\treturn () => {\n\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t}\n}\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\n\nexport function providePerspectives(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst unsubFns = new Set<() => void>()\n\tfor (const perspective of continuity.perspectives) {\n\t\tconst { viewAtoms } = perspective\n\t\tconst userViewState = findInStore(store, viewAtoms, userKey)\n\t\tconst unsubscribeFromUserView = subscribeToState(\n\t\t\tstore,\n\t\t\tuserViewState,\n\t\t\t`sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,\n\t\t\t({ oldValue, newValue }) => {\n\t\t\t\tconst oldKeys = oldValue?.map((token) => token.key)\n\t\t\t\tconst newKeys = newValue.map((token) => token.key)\n\t\t\t\tconst concealed = oldValue?.filter(\n\t\t\t\t\t(token) => !newKeys.includes(token.key),\n\t\t\t\t)\n\t\t\t\tconst revealed = newValue\n\t\t\t\t\t.filter((token) => !oldKeys?.includes(token.key))\n\t\t\t\t\t.flatMap((token) => {\n\t\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? getJsonToken(store, token) : token\n\t\t\t\t\t\tconst resource = getFromStore(store, resourceToken)\n\t\t\t\t\t\treturn [resourceToken, resource]\n\t\t\t\t\t})\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t`atom`,\n\t\t\t\t\tperspective.resourceAtoms.key,\n\t\t\t\t\t`${userKey} has a new perspective`,\n\t\t\t\t\t{ oldKeys, newKeys, revealed, concealed },\n\t\t\t\t)\n\t\t\t\tif (revealed.length > 0) {\n\t\t\t\t\tsocket.emit(`reveal:${continuityKey}`, revealed)\n\t\t\t\t}\n\t\t\t\tif (concealed && concealed.length > 0) {\n\t\t\t\t\tsocket.emit(`conceal:${continuityKey}`, concealed)\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tunsubFns.add(unsubscribeFromUserView)\n\t}\n\treturn () => {\n\t\tfor (const unsubscribe of unsubFns) unsubscribe()\n\t}\n}\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tisRootStore,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nexport function provideStartupPayloads(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tfunction sendInitialPayload(): void {\n\t\tconst initialPayload: Json.Serializable[] = []\n\t\tfor (const atom of continuity.globals) {\n\t\t\tconst resourceToken =\n\t\t\t\tatom.type === `mutable_atom` ? getJsonToken(store, atom) : atom\n\t\t\tconst resource = getFromStore(store, resourceToken)\n\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t}\n\t\tfor (const perspective of continuity.perspectives) {\n\t\t\tconst { viewAtoms, resourceAtoms } = perspective\n\t\t\tconst userViewState = findInStore(store, viewAtoms, userKey)\n\t\t\tconst userView = getFromStore(store, userViewState)\n\t\t\tstore.logger.info(`šŸ‘`, `atom`, resourceAtoms.key, `${userKey} can see`, {\n\t\t\t\tviewAtoms,\n\t\t\t\tresourceAtoms,\n\t\t\t\tuserView,\n\t\t\t})\n\t\t\tfor (const visibleToken of userView) {\n\t\t\t\tconst resourceToken =\n\t\t\t\t\tvisibleToken.type === `mutable_atom`\n\t\t\t\t\t\t? getJsonToken(store, visibleToken)\n\t\t\t\t\t\t: visibleToken\n\t\t\t\tconst resource = getFromStore(store, resourceToken)\n\n\t\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t\t}\n\t\t}\n\n\t\tconst epoch = isRootStore(store)\n\t\t\t? (store.transactionMeta.epoch.get(continuityKey) ?? null)\n\t\t\t: null\n\n\t\tsocket.emit(`continuity-init:${continuityKey}`, epoch, initialPayload)\n\t}\n\treturn employSocket(socket, `get:${continuityKey}`, sendInitialPayload)\n}\n","import type { TransactionOutcomeEvent, TransactionToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { actUponStore } from \"atom.io/internal\"\nimport type { Json, JsonIO } from \"atom.io/json\"\nimport type { ContinuityToken, Socket } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nexport function receiveActionRequests(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: string,\n): () => void {\n\tconst continuityKey = continuity.key\n\n\treturn employSocket(\n\t\tsocket,\n\t\t`tx-run:${continuityKey}`,\n\t\tfunction serveTransactionRequest(\n\t\t\ttxOutcome: Json.Serializable &\n\t\t\t\tPick<\n\t\t\t\t\tTransactionOutcomeEvent<TransactionToken<JsonIO>>,\n\t\t\t\t\t`id` | `params` | `token`\n\t\t\t\t>,\n\t\t) {\n\t\t\tstore.logger.info(`šŸ›Žļø`, `continuity`, continuityKey, `received`, txOutcome)\n\t\t\tconst transactionKey = txOutcome.token.key\n\t\t\tconst updateId = txOutcome.id\n\t\t\tconst performanceKey = `tx-run:${transactionKey}:${updateId}`\n\t\t\tconst performanceKeyStart = `${performanceKey}:start`\n\t\t\tconst performanceKeyEnd = `${performanceKey}:end`\n\t\t\tperformance.mark(performanceKeyStart)\n\t\t\ttry {\n\t\t\t\tactUponStore(\n\t\t\t\t\tstore,\n\t\t\t\t\t{ type: `transaction`, key: transactionKey },\n\t\t\t\t\tupdateId,\n\t\t\t\t)(...txOutcome.params)\n\t\t\t} catch (thrown) {\n\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t`āŒ`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`failed to run transaction ${transactionKey} from ${userKey} with update ${updateId}`,\n\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tperformance.mark(performanceKeyEnd)\n\t\t\tconst metric = performance.measure(\n\t\t\t\tperformanceKey,\n\t\t\t\tperformanceKeyStart,\n\t\t\t\tperformanceKeyEnd,\n\t\t\t)\n\t\t\tstore.logger.info(\n\t\t\t\t`šŸš€`,\n\t\t\t\t`transaction`,\n\t\t\t\ttransactionKey,\n\t\t\t\tupdateId,\n\t\t\t\tuserKey,\n\t\t\t\tmetric.duration,\n\t\t\t)\n\t\t},\n\t)\n}\n","import type { Store } from \"atom.io/internal\"\nimport { getFromStore, setIntoStore } from \"atom.io/internal\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport { unacknowledgedUpdatesAtoms } from \"./continuity-store\"\n\nexport function trackAcknowledgements(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst userUnacknowledgedUpdates = getFromStore(\n\t\tstore,\n\t\tunacknowledgedUpdatesAtoms,\n\t\tuserKey,\n\t)\n\tfunction trackClientAcknowledgement(epoch: number): void {\n\t\tstore.logger.info(\n\t\t\t`šŸ‘`,\n\t\t\t`continuity`,\n\t\t\tcontinuityKey,\n\t\t\t`${userKey} acknowledged epoch ${epoch}`,\n\t\t)\n\t\tconst isUnacknowledged = userUnacknowledgedUpdates[0]?.epoch === epoch\n\t\tif (isUnacknowledged) {\n\t\t\tsetIntoStore(store, unacknowledgedUpdatesAtoms, userKey, (updates) => {\n\t\t\t\tupdates.shift()\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`${userKey} unacknowledged update queue now has`,\n\t\t\t\t\tupdates.length,\n\t\t\t\t\t`items`,\n\t\t\t\t)\n\t\t\t\treturn updates\n\t\t\t})\n\t\t}\n\t}\n\treturn employSocket(socket, `ack:${continuityKey}`, trackClientAcknowledgement)\n}\n","import { getFromStore, IMPLICIT } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, UserKey } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \"..\"\nimport { unacknowledgedUpdatesAtoms } from \"./continuity-store\"\nimport { provideOutcomes } from \"./provide-outcomes\"\nimport { providePerspectives } from \"./provide-perspectives\"\nimport { provideStartupPayloads } from \"./provide-startup-payloads\"\nimport { receiveActionRequests } from \"./receive-action-requests\"\nimport { trackAcknowledgements } from \"./track-acknowledgements\"\n\nexport type ProvideContinuity = (\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n) => () => void\nexport function prepareToProvideContinuity({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig): ProvideContinuity {\n\treturn function syncRealtimeContinuity(continuity, userKey) {\n\t\tconst continuityKey = continuity.key\n\n\t\tconst unacknowledgedUpdates = getFromStore(\n\t\t\tstore,\n\t\t\tunacknowledgedUpdatesAtoms,\n\t\t\tuserKey,\n\t\t)\n\t\tfor (const unacknowledgedUpdate of unacknowledgedUpdates) {\n\t\t\tsocket.emit(\n\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\tunacknowledgedUpdate as Json.Serializable,\n\t\t\t)\n\t\t}\n\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsubscribe of subscriptions) unsubscribe()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tsubscriptions.add(providePerspectives(store, socket, continuity, userKey))\n\t\tsubscriptions.add(provideOutcomes(store, socket, continuity, userKey))\n\t\tsubscriptions.add(provideStartupPayloads(store, socket, continuity, userKey))\n\t\tsubscriptions.add(receiveActionRequests(store, socket, continuity, userKey))\n\t\tsubscriptions.add(trackAcknowledgements(store, socket, continuity, userKey))\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type { Json, stringified } from \"atom.io/json\"\nimport type { Socket } from \"atom.io/realtime\"\n\nexport type Events = Json.Object<string, Json.Serializable[]>\n\nexport type EventPayload<\n\treceiveRelay extends Events,\n\tK extends string & keyof receiveRelay = string & keyof receiveRelay,\n> = [string, ...receiveRelay[K]]\n\nexport interface EventBuffer<\n\tE extends Events,\n\tK extends string & keyof E = string & keyof E,\n> extends Buffer {\n\ttoString(): stringified<EventPayload<E, K>>\n}\n\nexport abstract class CustomSocket<I extends Events, O extends Events>\n\timplements Socket\n{\n\tprotected listeners: Map<keyof O, Set<(...args: Json.Array) => void>>\n\tprotected globalListeners: Set<(event: string, ...args: Json.Array) => void>\n\tprotected handleEvent<K extends string & keyof I>(\n\t\t...args: EventPayload<I, K>\n\t): void {\n\t\tconst [event, ...rest] = args\n\t\tfor (const listener of this.globalListeners) {\n\t\t\tlistener(event, ...rest)\n\t\t}\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...rest)\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic id = `no_id_retrieved`\n\tpublic emit: <Event extends keyof I>(\n\t\tevent: Event,\n\t\t...args: I[Event]\n\t) => CustomSocket<I, O>\n\n\tpublic constructor(\n\t\temit: <Event extends keyof I>(\n\t\t\tevent: Event,\n\t\t\t...args: I[Event]\n\t\t) => CustomSocket<I, O>,\n\t) {\n\t\tthis.emit = emit\n\t\tthis.listeners = new Map()\n\t\tthis.globalListeners = new Set()\n\t}\n\n\tpublic on<Event extends keyof O>(\n\t\tevent: Event,\n\t\tlistener: (...args: O[Event]) => void,\n\t): this {\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tlisteners.add(listener)\n\t\t} else {\n\t\t\tthis.listeners.set(event, new Set([listener]))\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic onAny(listener: (event: string, ...args: Json.Array) => void): this {\n\t\tthis.globalListeners.add(listener)\n\t\treturn this\n\t}\n\n\tpublic off<Event extends keyof O>(\n\t\tevent: Event,\n\t\tlistener?: (...args: O[Event]) => void,\n\t): this {\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tif (listener) {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t} else {\n\t\t\t\tthis.listeners.delete(event)\n\t\t\t}\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic offAny(listener: (event: string, ...args: Json.Array) => void): this {\n\t\tthis.globalListeners.delete(listener)\n\t\treturn this\n\t}\n}\n","import type { Readable, Writable } from \"node:stream\"\n\nimport type { Json, stringified } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\n\nimport type { EventBuffer, EventPayload, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\n/* eslint-disable no-console */\n\nexport type ChildProcess = {\n\tpid?: number | undefined\n\tstdin: Writable\n\tstdout: Readable\n\tstderr: Readable\n}\n\nexport type StderrLog = [`e` | `i` | `w`, ...Json.Array]\n\nexport class ChildSocket<\n\tI extends Events,\n\tO extends Events,\n\tP extends ChildProcess = ChildProcess,\n> extends CustomSocket<I, O> {\n\tprotected incompleteData = ``\n\tprotected unprocessedEvents: string[] = []\n\tprotected incompleteLog = ``\n\tprotected unprocessedLogs: string[] = []\n\n\tpublic id = `#####`\n\n\tpublic proc: P\n\tpublic key: string\n\tpublic logger: Pick<Console, `error` | `info` | `warn`>\n\n\tprotected handleLog(log: StderrLog): void {\n\t\tif (Array.isArray(log)) {\n\t\t\tconst [level, ...rest] = log\n\t\t\tswitch (level) {\n\t\t\t\tcase `i`:\n\t\t\t\t\tthis.logger.info(...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `w`:\n\t\t\t\t\tthis.logger.warn(...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `e`:\n\t\t\t\t\tthis.logger.error(...rest)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tproc: P,\n\t\tkey: string,\n\t\tlogger?: Pick<Console, `error` | `info` | `warn`>,\n\t) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args]) + `\\x03`\n\t\t\tconst errorHandler = (err: { code: string }) => {\n\t\t\t\tif (err.code === `EPIPE`) {\n\t\t\t\t\tconsole.error(`EPIPE error during write`, this.proc.stdin)\n\t\t\t\t}\n\t\t\t\tthis.proc.stdin.removeListener(`error`, errorHandler)\n\t\t\t}\n\n\t\t\tthis.proc.stdin.once(`error`, errorHandler)\n\t\t\tthis.proc.stdin.write(stringifiedEvent)\n\n\t\t\treturn this\n\t\t})\n\t\tthis.proc = proc\n\t\tthis.key = key\n\t\tthis.logger = logger ?? {\n\t\t\tinfo: (...args: unknown[]) => {\n\t\t\t\tconsole.info(this.id, this.key, ...args)\n\t\t\t},\n\t\t\twarn: (...args: unknown[]) => {\n\t\t\t\tconsole.warn(this.id, this.key, ...args)\n\t\t\t},\n\t\t\terror: (...args: unknown[]) => {\n\t\t\t\tconsole.error(this.id, this.key, ...args)\n\t\t\t},\n\t\t}\n\t\tthis.proc.stdout.on(\n\t\t\t`data`,\n\t\t\t<K extends string & keyof I>(buffer: EventBuffer<I, K>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\n\t\t\t\tif (chunk === `ALIVE`) {\n\t\t\t\t\tthis.logger.info(chunk)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\t\tlet idx = 0\n\t\t\t\tfor (const piece of pieces) {\n\t\t\t\t\tif (piece === ``) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst jsonPiece = parseJson(piece as stringified<EventPayload<I, K>>)\n\t\t\t\t\t\tthis.handleEvent(...jsonPiece)\n\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t} catch (thrown0) {\n\t\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`āŒ Malformed data received from child process`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(\n\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed as stringified<EventPayload<I, K>>,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.handleEvent(...maybeActualJsonPiece)\n\t\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t`āŒ Malformed data received from child process`,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t++idx\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tthis.proc.stderr.on(`data`, (buffer: Buffer) => {\n\t\t\tconst chunk = buffer.toString()\n\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\tlet idx = 0\n\t\t\tfor (const piece of pieces) {\n\t\t\t\tif (piece === ``) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst jsonPiece = parseJson(piece as stringified<StderrLog>)\n\t\t\t\t\tthis.handleLog(jsonPiece)\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (thrown0) {\n\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t`āŒ Malformed log received from child process`,\n\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(\n\t\t\t\t\t\t\t\tinitialMaybeWellFormed as stringified<StderrLog>,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.handleLog(maybeActualJsonPiece)\n\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`āŒ Malformed log received from child process...`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++idx\n\t\t\t}\n\t\t})\n\t\tif (proc.pid) {\n\t\t\tthis.id = proc.pid.toString()\n\t\t}\n\t}\n}\n","import type { Readable, Writable } from \"node:stream\"\n\nimport { Subject } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\nimport type { UserKey } from \"atom.io/realtime\"\nimport { UList } from \"atom.io/transceivers/u-list\"\n\nimport type { StderrLog } from \"./child-socket\"\nimport type { EventBuffer, EventPayload, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\nexport class SubjectSocket<\n\tI extends Events,\n\tO extends Events,\n> extends CustomSocket<I, O> {\n\tpublic in: Subject<EventPayload<I>>\n\tpublic out: Subject<EventPayload<O>>\n\tpublic id = `no_id_retrieved`\n\tpublic disposalFunctions: (() => void)[] = []\n\n\tpublic constructor(id: string) {\n\t\tsuper((...args) => {\n\t\t\tthis.out.next(args as any)\n\t\t\treturn this\n\t\t})\n\t\tthis.id = id\n\t\tthis.in = new Subject()\n\t\tthis.out = new Subject()\n\t\tthis.in.subscribe(`socket`, (event) => {\n\t\t\tthis.handleEvent(...event)\n\t\t})\n\t}\n\n\tpublic dispose(): void {\n\t\tfor (const dispose of this.disposalFunctions) {\n\t\t\tdispose()\n\t\t}\n\t}\n}\n\nexport type ParentProcess = {\n\tpid?: number | undefined\n\tstdin: Readable\n\tstdout: Writable\n\tstderr: Writable\n\texit: (code?: number) => void\n}\n\nexport class ParentSocket<\n\tI extends Events & {\n\t\t[id in string as `relay::${id}`]: [string, ...Json.Array[]]\n\t},\n\tO extends Events & {\n\t\t[id in string as `user::${id}`]: [string, ...Json.Array[]]\n\t} & {\n\t\t/* eslint-disable quotes */\n\t\t\"user-joins\": [key: UserKey]\n\t\t\"user-leaves\": [key: UserKey]\n\t\t/* eslint-enable quotes */\n\t},\n\tP extends ParentProcess = ParentProcess,\n> extends CustomSocket<I, O> {\n\tprotected incompleteData = ``\n\tprotected unprocessedEvents: string[] = []\n\tprotected relays: Map<string, SubjectSocket<any, any>>\n\tprotected relayServices: ((\n\t\tsocket: SubjectSocket<any, any>,\n\t\tuserKey: UserKey,\n\t) => (() => void) | void)[]\n\tpublic proc: P\n\n\tpublic id = `#####`\n\n\tprotected log(...args: StderrLog): void {\n\t\tthis.proc.stderr.write(\n\t\t\tstringifyJson(\n\t\t\t\targs.map((arg) =>\n\t\t\t\t\targ instanceof UList ? `{ ${arg.toJSON().join(` | `)} }` : arg,\n\t\t\t\t),\n\t\t\t) + `\\x03`,\n\t\t)\n\t}\n\tpublic logger = {\n\t\tinfo: (...args: Json.Array): void => {\n\t\t\tthis.log(`i`, ...args)\n\t\t},\n\t\twarn: (...args: Json.Array): void => {\n\t\t\tthis.log(`w`, ...args)\n\t\t},\n\t\terror: (...args: Json.Array): void => {\n\t\t\tthis.log(`e`, ...args)\n\t\t},\n\t}\n\n\tpublic constructor(proc: P) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args])\n\t\t\tthis.proc.stdout.write(stringifiedEvent + `\\x03`)\n\t\t\treturn this\n\t\t})\n\t\tthis.proc = proc\n\t\tthis.proc.stdin.resume()\n\t\tthis.relays = new Map()\n\t\tthis.relayServices = []\n\n\t\tthis.proc.stdin.on(\n\t\t\t`data`,\n\t\t\t<K extends string & keyof I>(buffer: EventBuffer<I, K>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\t\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\t\tlet idx = 0\n\t\t\t\tfor (const piece of pieces) {\n\t\t\t\t\tif (piece === ``) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst jsonPiece = parseJson(piece)\n\t\t\t\t\t\tthis.logger.info(`šŸŽ°`, `received`, jsonPiece)\n\t\t\t\t\t\tthis.handleEvent(...(jsonPiece as EventPayload<I>))\n\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t} catch (thrown0) {\n\t\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`received malformed data from parent process:`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(initialMaybeWellFormed)\n\t\t\t\t\t\t\t\tthis.logger.info(`šŸŽ°`, `received`, maybeActualJsonPiece)\n\t\t\t\t\t\t\t\tthis.handleEvent(...(maybeActualJsonPiece as EventPayload<I>))\n\t\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t`received malformed data from parent process:`,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t++idx\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\n\t\tthis.on(`exit`, () => {\n\t\t\tthis.logger.info(`šŸ”„`, this.id, `received \"exit\"`)\n\t\t\tthis.proc.exit(0)\n\t\t})\n\n\t\tif (this.proc.pid) {\n\t\t\tthis.id = this.proc.pid?.toString()\n\t\t}\n\n\t\tthis.on(`user-joins`, (username: string) => {\n\t\t\tthis.logger.info(`šŸ‘¤`, `user`, username, `joined`)\n\t\t\tconst userKey = `user::${username}` satisfies UserKey\n\t\t\tconst relay = new SubjectSocket(userKey)\n\t\t\tthis.relays.set(username, relay)\n\t\t\tthis.logger.info(\n\t\t\t\t`šŸ”—`,\n\t\t\t\t`attaching services:`,\n\t\t\t\t`[${[...this.relayServices.keys()].join(`, `)}]`,\n\t\t\t)\n\t\t\tfor (const attachRelay of this.relayServices) {\n\t\t\t\tconst cleanupRelay = attachRelay(relay, userKey)\n\t\t\t\tif (cleanupRelay) {\n\t\t\t\t\trelay.disposalFunctions.push(cleanupRelay)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.on(userKey, (...data) => {\n\t\t\t\trelay.in.next(data)\n\t\t\t})\n\t\t\trelay.out.subscribe(`socket`, (data) => {\n\t\t\t\tthis.emit(...(data as [string, ...I[keyof I]]))\n\t\t\t})\n\t\t})\n\n\t\tthis.on(`user-leaves`, (username) => {\n\t\t\tconst relay = this.relays.get(username)\n\t\t\tthis.off(`relay:${username}`)\n\t\t\tif (relay) {\n\t\t\t\trelay.dispose()\n\t\t\t\tthis.relays.delete(username)\n\t\t\t}\n\t\t})\n\n\t\tthis.proc.stdout.write(`ALIVE`)\n\t}\n\n\tpublic receiveRelay(\n\t\tattachServices: (\n\t\t\tsocket: SubjectSocket<any, any>,\n\t\t\tuserKey: UserKey,\n\t\t) => (() => void) | void,\n\t): void {\n\t\tthis.logger.info(`šŸ”—`, `running relay method`)\n\t\tthis.relayServices.push(attachServices)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Canonical, Json, stringified } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type FamilyProvider = ReturnType<typeof realtimeAtomFamilyProvider>\nexport function realtimeAtomFamilyProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function familyProvider<\n\t\tJ extends Json.Serializable,\n\t\tK extends Canonical,\n\t>(\n\t\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst coreSubscriptions = new Set<() => void>()\n\t\tconst clearCoreSubscriptions = () => {\n\t\t\tfor (const unsub of coreSubscriptions) unsub()\n\t\t\tcoreSubscriptions.clear()\n\t\t}\n\t\tconst familyMemberSubscriptionsWanted = new Set<stringified<K>>()\n\t\tconst familyMemberSubscriptions = new Map<string, () => void>()\n\t\tconst clearFamilySubscriptions = () => {\n\t\t\tfor (const unsub of familyMemberSubscriptions.values()) unsub()\n\t\t\tfamilyMemberSubscriptions.clear()\n\t\t}\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tconst unsubUnsub = familyMemberSubscriptions.get(`${key}:unsub`)\n\t\t\tif (unsubUnsub) {\n\t\t\t\tunsubUnsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(`${key}:unsub`)\n\t\t\t}\n\t\t\tconst unsub = familyMemberSubscriptions.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst exposeFamilyMembers = (subKey: K) => {\n\t\t\tconst token = findInStore(store, family, subKey)\n\t\t\tgetFromStore(store, token)\n\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(store, token))\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\ttoken.key,\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\ttoken,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\t`${token.key}:unsub`,\n\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst isAvailable = (exposedSubKeys: Iterable<K>, subKey: K): boolean => {\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tcoreSubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${family.key}`, (subKey: K) => {\n\t\t\t\t\tconst exposedSubKeys = getFromStore(store, index)\n\t\t\t\t\tconst shouldExpose = isAvailable(exposedSubKeys, subKey)\n\t\t\t\t\tif (shouldExpose) {\n\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfamilyMemberSubscriptionsWanted.add(stringifyJson(subKey))\n\t\t\t\t\t\tsocket.emit(`unavailable:${family.key}`, subKey)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\tcoreSubscriptions.add(\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tindex,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue: newExposedSubKeys }) => {\n\t\t\t\t\t\tfor (const subKey of newExposedSubKeys) {\n\t\t\t\t\t\t\tif (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {\n\t\t\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn () => {\n\t\t\tclearCoreSubscriptions()\n\t\t\tclearFamilySubscriptions()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Canonical, stringified } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nconst isAvailable = <K extends Canonical>(\n\texposedSubKeys: Iterable<K>,\n\tsubKey: K,\n): boolean => {\n\tfor (const exposedSubKey of exposedSubKeys) {\n\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nexport type MutableFamilyProvider = ReturnType<\n\ttypeof realtimeMutableFamilyProvider\n>\nexport function realtimeMutableFamilyProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function mutableFamilyProvider<\n\t\tT extends Transceiver<any, any, any>,\n\t\tK extends Canonical,\n\t>(\n\t\tfamily: AtomIO.MutableAtomFamilyToken<T, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst coreSubscriptions = new Set<() => void>()\n\t\tconst clearCoreSubscriptions = () => {\n\t\t\tfor (const unsub of coreSubscriptions) unsub()\n\t\t\tcoreSubscriptions.clear()\n\t\t}\n\t\tconst familyMemberSubscriptionsWanted = new Set<stringified<K>>()\n\t\tconst familyMemberSubscriptions = new Map<string, () => void>()\n\t\tconst clearFamilySubscriptions = () => {\n\t\t\tfor (const unsub of familyMemberSubscriptions.values()) unsub()\n\t\t\tfamilyMemberSubscriptions.clear()\n\t\t}\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tconst unsubUnsub = familyMemberSubscriptions.get(`${key}:unsub`)\n\t\t\tif (unsubUnsub) {\n\t\t\t\tunsubUnsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(`${key}:unsub`)\n\t\t\t}\n\t\t\tconst unsub = familyMemberSubscriptions.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst exposeFamilyMembers = (subKey: K) => {\n\t\t\tconst token = findInStore(store, family, subKey)\n\t\t\tgetFromStore(store, token)\n\t\t\tconst jsonToken = getJsonToken(store, token)\n\t\t\tconst updateToken = getUpdateToken(token)\n\t\t\tsocket.emit(`init:${token.key}`, getFromStore(store, jsonToken))\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\ttoken.key,\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tupdateToken,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\t`${token.key}:unsub`,\n\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tcoreSubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${family.key}`, (subKey: K) => {\n\t\t\t\t\tconst exposedSubKeys = getFromStore(store, index)\n\t\t\t\t\tconst shouldExpose = isAvailable(exposedSubKeys, subKey)\n\t\t\t\t\tif (shouldExpose) {\n\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfamilyMemberSubscriptionsWanted.add(stringifyJson(subKey))\n\t\t\t\t\t\tsocket.emit(`unavailable:${family.key}`, subKey)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\tcoreSubscriptions.add(\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tindex,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue: newExposedSubKeys }) => {\n\t\t\t\t\t\tfor (const subKey of newExposedSubKeys) {\n\t\t\t\t\t\t\tif (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {\n\t\t\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn () => {\n\t\t\tclearCoreSubscriptions()\n\t\t\tclearFamilySubscriptions()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type MutableProvider = ReturnType<typeof realtimeMutableProvider>\nexport function realtimeMutableProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function mutableProvider<\n\t\tCore extends Transceiver<any, Json.Serializable, Json.Serializable>,\n\t>(token: AtomIO.MutableAtomToken<Core>): () => void {\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst jsonToken = getJsonToken(store, token)\n\t\tconst trackerToken = getUpdateToken(token)\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${token.key}`, () => {\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tsocket.emit(`init:${token.key}`, getFromStore(store, jsonToken))\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\tsubscribeToState(\n\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\ttrackerToken,\n\t\t\t\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\t\tstart()\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type {\n\tHierarchy,\n\tJoinToken,\n\tMutableAtomToken,\n\tPureSelectorFamilyToken,\n\tRegularAtomFamilyToken,\n} from \"atom.io\"\nimport { atomFamily, join, mutableAtom, selectorFamily } from \"atom.io\"\nimport type { RoomKey, Socket, SocketKey, UserKey } from \"atom.io/realtime\"\nimport { isSocketKey, isUserKey } from \"atom.io/realtime\"\nimport { UList } from \"atom.io/transceivers/u-list\"\n\nexport type SocketSystemHierarchy = Hierarchy<\n\t[\n\t\t{\n\t\t\tabove: `root`\n\t\t\tbelow: [UserKey, SocketKey, RoomKey]\n\t\t},\n\t]\n>\n\nexport const socketAtoms: RegularAtomFamilyToken<Socket | null, SocketKey> =\n\tatomFamily({\n\t\tkey: `sockets`,\n\t\tdefault: null,\n\t})\n\nexport const socketKeysAtom: MutableAtomToken<UList<SocketKey>> = mutableAtom({\n\tkey: `socketsIndex`,\n\tclass: UList,\n})\nexport const userKeysAtom: MutableAtomToken<UList<UserKey>> = mutableAtom({\n\tkey: `usersIndex`,\n\tclass: UList,\n})\nexport const usersOfSockets: JoinToken<\n\t`user`,\n\tUserKey,\n\t`socket`,\n\tSocketKey,\n\t`1:1`\n> = join({\n\tkey: `usersOfSockets`,\n\tbetween: [`user`, `socket`],\n\tcardinality: `1:1`,\n\tisAType: isUserKey,\n\tisBType: isSocketKey,\n})\n\nexport const selfListSelectors: PureSelectorFamilyToken<UserKey[], UserKey> =\n\tselectorFamily({\n\t\tkey: `selfList`,\n\t\tget: (userId) => () => [userId],\n\t})\n","import type { ChildProcessWithoutNullStreams } from \"node:child_process\"\nimport { spawn } from \"node:child_process\"\n\nimport type { Store } from \"atom.io/internal\"\nimport {\n\teditRelationsInStore,\n\tfindInStore,\n\tfindRelationsInStore,\n\tgetFromStore,\n\tgetInternalRelationsFromStore,\n\tIMPLICIT,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type {\n\tAllEventsListener,\n\tEventsMap,\n\tRoomKey,\n\tRoomSocketInterface,\n\tSocket,\n\tSocketKey,\n\tTypedSocket,\n\tUserKey,\n} from \"atom.io/realtime\"\nimport { ownersOfRooms, roomKeysAtom, usersInRooms } from \"atom.io/realtime\"\n\nimport { ChildSocket } from \"../ipc-sockets\"\nimport { realtimeMutableFamilyProvider } from \"../realtime-mutable-family-provider\"\nimport { realtimeMutableProvider } from \"../realtime-mutable-provider\"\nimport type { ServerConfig } from \"../server-config\"\nimport {\n\tselfListSelectors,\n\tsocketKeysAtom,\n\tuserKeysAtom,\n\tusersOfSockets,\n} from \"./server-user-store\"\n\nexport type RoomMap = Map<\n\tstring,\n\tChildSocket<any, any, ChildProcessWithoutNullStreams>\n>\n\ndeclare global {\n\tvar ATOM_IO_REALTIME_SERVER_ROOMS: RoomMap\n}\n\nexport const ROOMS: RoomMap =\n\tglobalThis.ATOM_IO_REALTIME_SERVER_ROOMS ??\n\t(globalThis.ATOM_IO_REALTIME_SERVER_ROOMS = new Map())\n\nexport const roomMeta: { count: number } = { count: 0 }\n\nexport async function spawnRoom(\n\tstore: Store,\n\tuserKey: UserKey,\n\troomKey: RoomKey,\n\tcommand: string,\n\targs: string[],\n): Promise<ChildSocket<any, any>> {\n\tconst child = await new Promise<ChildProcessWithoutNullStreams>((resolve) => {\n\t\tconst room = spawn(command, args, { env: process.env })\n\t\tconst resolver = (data: Buffer) => {\n\t\t\tif (data.toString() === `ALIVE`) {\n\t\t\t\troom.stdout.off(`data`, resolver)\n\t\t\t\tresolve(room)\n\t\t\t}\n\t\t}\n\t\troom.stdout.on(`data`, resolver)\n\t})\n\tconst roomSocket = new ChildSocket(child, roomKey)\n\tROOMS.set(roomKey, roomSocket)\n\tsetIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index))\n\n\teditRelationsInStore(store, ownersOfRooms, (relations) => {\n\t\trelations.set({ room: roomKey, user: userKey })\n\t})\n\n\troomSocket.on(`close`, () => {\n\t\tdestroyRoom(store)(roomKey)\n\t})\n\n\treturn roomSocket\n}\n\nexport function provideEnterAndExit(\n\tstore: Store,\n\tuserKey: UserKey,\n\tsocket: Socket,\n): {\n\tenterRoom: (roomKey: RoomKey) => void\n} {\n\tconst enterRoom = (roomKey: RoomKey) => {\n\t\tconst exitRoom = () => {\n\t\t\tsocket.offAny(forward)\n\t\t\ttoRoom([`user-leaves`])\n\t\t\tleaveRoom(store, roomKey, userKey)\n\t\t\tsocket.off(`leaveRoom`, exitRoom)\n\t\t\tsocket.on(`joinRoom`, enterRoom)\n\t\t}\n\n\t\tsocket.on(`leaveRoom`, exitRoom)\n\t\tsocket.off(`joinRoom`, enterRoom)\n\n\t\tconst roomQueue: [string, ...Json.Array][] = []\n\t\tconst pushToRoomQueue = (payload: [string, ...Json.Array]): void => {\n\t\t\troomQueue.push(payload)\n\t\t}\n\t\tlet toRoom = pushToRoomQueue\n\t\tconst forward: AllEventsListener<EventsMap> = (...payload) => {\n\t\t\ttoRoom(payload)\n\t\t}\n\t\tsocket.onAny(forward)\n\n\t\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\t\trelations.set({ room: roomKey, user: userKey })\n\t\t})\n\t\tconst roomSocket = ROOMS.get(roomKey)\n\t\tif (!roomSocket) {\n\t\t\tstore.logger.error(`āŒ`, `unknown`, roomKey, `no room found with this id`)\n\t\t\treturn null\n\t\t}\n\t\troomSocket.onAny((...payload) => {\n\t\t\tsocket.emit(...payload)\n\t\t})\n\t\troomSocket.emit(`user-joins`, userKey)\n\n\t\ttoRoom = (payload) => {\n\t\t\troomSocket.emit(`user::${userKey}`, ...payload)\n\t\t}\n\t\twhile (roomQueue.length > 0) {\n\t\t\tconst payload = roomQueue.shift()\n\t\t\tif (payload) toRoom(payload)\n\t\t}\n\t}\n\tsocket.on(`joinRoom`, enterRoom)\n\treturn { enterRoom }\n}\n\nexport function leaveRoom(\n\tstore: Store,\n\troomKey: RoomKey,\n\tuserKey: UserKey,\n): void {\n\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\trelations.delete({ room: roomKey, user: userKey })\n\t})\n}\n\nexport function destroyRoom(store: Store): (roomKey: RoomKey) => void {\n\treturn (roomKey: RoomKey) => {\n\t\t// logger.info(`[${shortId}]:${username}`, `deleting room \"${roomId}\"`)\n\t\tsetIntoStore(store, roomKeysAtom, (s) => (s.delete(roomKey), s))\n\t\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\t\trelations.delete({ room: roomKey })\n\t\t})\n\t\tconst room = ROOMS.get(roomKey)\n\t\tif (room) {\n\t\t\troom.emit(`exit`)\n\t\t\tROOMS.delete(roomKey)\n\t\t}\n\t}\n}\n\nexport type ProvideRoomsConfig = {\n\tresolveRoomScript: (path: string) => [string, string[]]\n\troomTimeLimit?: number\n}\nexport function provideRooms<RoomNames extends string>({\n\tstore = IMPLICIT.STORE,\n\tsocket,\n\tresolveRoomScript,\n}: ProvideRoomsConfig & ServerConfig): void {\n\tconst socketKey = `socket::${socket.id}` satisfies SocketKey\n\tconst userKey = getFromStore(\n\t\tstore,\n\t\tfindRelationsInStore(store, usersOfSockets, socketKey).userKeyOfSocket,\n\t)!\n\tconst roomSocket = socket as TypedSocket<RoomSocketInterface<RoomNames>, {}>\n\n\tconst exposeMutable = realtimeMutableProvider({ socket, store })\n\tconst exposeMutableFamily = realtimeMutableFamilyProvider({\n\t\tsocket,\n\t\tstore,\n\t})\n\n\texposeMutable(roomKeysAtom)\n\n\tconst [, usersInRoomsAtoms] = getInternalRelationsFromStore(\n\t\tstore,\n\t\tusersInRooms,\n\t\t`split`,\n\t)\n\tconst usersWhoseRoomsCanBeSeenSelector = findInStore(\n\t\tstore,\n\t\tselfListSelectors,\n\t\tuserKey,\n\t)\n\texposeMutableFamily(usersInRoomsAtoms, usersWhoseRoomsCanBeSeenSelector)\n\tconst usersOfSocketsAtoms = getInternalRelationsFromStore(\n\t\tstore,\n\t\tusersOfSockets,\n\t)\n\texposeMutableFamily(usersOfSocketsAtoms, socketKeysAtom)\n\n\tconst createRoom = async (roomName: RoomNames) => {\n\t\t// logger.info(`[${shortId}]:${username}`, `creating room \"${roomId}\"`)\n\t\tconst roomKey = `room::${roomMeta.count++}` satisfies RoomKey\n\t\tawait spawnRoom(store, userKey, roomKey, ...resolveRoomScript(roomName))\n\t}\n\n\tconst { enterRoom } = provideEnterAndExit(store, userKey, roomSocket)\n\n\tconst userRoomSet = getFromStore(store, usersInRoomsAtoms, userKey)\n\tfor (const userRoomKey of userRoomSet) {\n\t\tenterRoom(userRoomKey)\n\t\tbreak\n\t}\n\n\troomSocket.on(`createRoom`, createRoom)\n\troomSocket.on(`deleteRoom`, destroyRoom(store))\n\tsocket.on(`disconnect`, () => {\n\t\t// logger.info(`${socket.id} disconnected`)\n\t\teditRelationsInStore(store, usersOfSockets, (rel) => rel.delete(socketKey))\n\t\tsetIntoStore(store, userKeysAtom, (keys) => (keys.delete(userKey), keys))\n\t\tsetIntoStore(store, socketKeysAtom, (keys) => (keys.delete(socketKey), keys))\n\t})\n}\n","import type * as AtomIO from \"atom.io\"\nimport { getFromStore, IMPLICIT, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type StateProvider = ReturnType<typeof realtimeStateProvider>\nexport function realtimeStateProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateProvider<J extends Json.Serializable>(\n\t\ttoken: AtomIO.WritableToken<J>,\n\t): () => void {\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${token.key}`, () => {\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(store, token))\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\tsubscribeToState(\n\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\t\tstart()\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type { WritableToken } from \"atom.io\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tIMPLICIT,\n\toperateOnStore,\n\tOWN_OP,\n\tsetIntoStore,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket, mutexAtoms } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type StateReceiver = ReturnType<typeof realtimeStateReceiver>\nexport function realtimeStateReceiver({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateReceiver<S extends Json.Serializable, C extends S>(\n\t\tclientToken: WritableToken<C>,\n\t\tserverToken: WritableToken<S> = clientToken,\n\t): () => void {\n\t\tconst mutexAtom = findInStore(store, mutexAtoms, serverToken.key)\n\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst permitPublish = () => {\n\t\t\tclearSubscriptions()\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `pub:${clientToken.key}`, (newValue) => {\n\t\t\t\t\tsetIntoStore(store, serverToken, newValue as C)\n\t\t\t\t}),\n\t\t\t)\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `unclaim:${clientToken.key}`, () => {\n\t\t\t\t\tsetIntoStore(store, mutexAtom, false)\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tstart()\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `claim:${clientToken.key}`, () => {\n\t\t\t\t\tif (getFromStore(store, mutexAtom)) {\n\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\t\tsubscribeToState(store, mutexAtom, socket.id!, () => {\n\t\t\t\t\t\t\t\tconst currentValue = getFromStore(store, mutexAtom)\n\t\t\t\t\t\t\t\tif (currentValue === false) {\n\t\t\t\t\t\t\t\t\toperateOnStore(OWN_OP, store, mutexAtom, true)\n\t\t\t\t\t\t\t\t\tpermitPublish()\n\t\t\t\t\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, true)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, false)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tsetIntoStore(store, mutexAtom, true)\n\t\t\t\t\tpermitPublish()\n\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, true)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["redactorAtoms: RegularAtomFamilyToken<\n\t{\n\t\tocclude: (updates: TransactionSubEvent[]) => TransactionSubEvent[]\n\t},\n\tUserKey\n>","unacknowledgedUpdatesAtoms: RegularAtomFamilyToken<\n\tContinuitySyncTransactionUpdate[],\n\tUserKey\n>","initialPayload: Json.Serializable[]","isAvailable","socketAtoms: RegularAtomFamilyToken<Socket | null, SocketKey>","socketKeysAtom: MutableAtomToken<UList<SocketKey>>","userKeysAtom: MutableAtomToken<UList<UserKey>>","usersOfSockets: JoinToken<\n\t`user`,\n\tUserKey,\n\t`socket`,\n\tSocketKey,\n\t`1:1`\n>","selfListSelectors: PureSelectorFamilyToken<UserKey[], UserKey>","ROOMS: RoomMap","roomMeta: { count: number }","roomQueue: [string, ...Json.Array][]","forward: AllEventsListener<EventsMap>","roomKeySchema: StandardSchemaV1<Json.Array, [RoomKey]>"],"sources":["../../src/realtime-server/continuity/continuity-store.ts","../../src/realtime-server/continuity/provide-outcomes.ts","../../src/realtime-server/continuity/provide-perspectives.ts","../../src/realtime-server/continuity/provide-startup-payloads.ts","../../src/realtime-server/continuity/receive-action-requests.ts","../../src/realtime-server/continuity/track-acknowledgements.ts","../../src/realtime-server/continuity/provide-continuity.ts","../../src/realtime-server/ipc-sockets/custom-socket.ts","../../src/realtime-server/ipc-sockets/child-socket.ts","../../src/realtime-server/ipc-sockets/parent-socket.ts","../../src/realtime-server/realtime-family-provider.ts","../../src/realtime-server/realtime-mutable-family-provider.ts","../../src/realtime-server/realtime-mutable-provider.ts","../../src/realtime-server/realtime-server-stores/server-user-store.ts","../../src/realtime-server/realtime-server-stores/provide-rooms.ts","../../src/realtime-server/realtime-state-provider.ts","../../src/realtime-server/realtime-state-receiver.ts"],"sourcesContent":["import type {\n\tRegularAtomFamilyToken,\n\tTransactionOutcomeEvent,\n\tTransactionSubEvent,\n} from \"atom.io\"\nimport { atomFamily } from \"atom.io\"\nimport type { UserKey } from \"atom.io/realtime\"\n\nexport function redactTransactionUpdateContent(\n\tvisibleStateKeys: string[],\n\tupdates: TransactionSubEvent[],\n): TransactionSubEvent[] {\n\treturn updates\n\t\t.map((update): TransactionSubEvent => {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase `transaction_outcome`: {\n\t\t\t\t\tconst redacted = redactTransactionUpdateContent(\n\t\t\t\t\t\tvisibleStateKeys,\n\t\t\t\t\t\tupdate.subEvents,\n\t\t\t\t\t)\n\t\t\t\t\treturn { ...update, subEvents: redacted }\n\t\t\t\t}\n\t\t\t\tcase `atom_update`:\n\t\t\t\tcase `molecule_creation`:\n\t\t\t\tcase `molecule_disposal`:\n\t\t\t\tcase `molecule_transfer`:\n\t\t\t\tcase `state_creation`:\n\t\t\t\tcase `state_disposal`:\n\t\t\t\t\treturn update\n\t\t\t}\n\t\t})\n\t\t.filter((update) => {\n\t\t\tswitch (update.type) {\n\t\t\t\tcase `atom_update`:\n\t\t\t\tcase `state_creation`:\n\t\t\t\tcase `state_disposal`:\n\t\t\t\t\treturn visibleStateKeys.includes(update.token.key)\n\t\t\t\tcase `molecule_creation`:\n\t\t\t\tcase `transaction_outcome`:\n\t\t\t\tcase `molecule_disposal`:\n\t\t\t\tcase `molecule_transfer`:\n\t\t\t\t\treturn true\n\t\t\t}\n\t\t})\n}\n\nexport const redactorAtoms: RegularAtomFamilyToken<\n\t{\n\t\tocclude: (updates: TransactionSubEvent[]) => TransactionSubEvent[]\n\t},\n\tUserKey\n> = atomFamily({\n\tkey: `redactor`,\n\tdefault: { occlude: (updates) => updates },\n})\n\nexport type ContinuitySyncTransactionUpdate = Pick<\n\tTransactionOutcomeEvent<any>,\n\t`epoch` | `id` | `output` | `subEvents` | `token`\n>\nexport const unacknowledgedUpdatesAtoms: RegularAtomFamilyToken<\n\tContinuitySyncTransactionUpdate[],\n\tUserKey\n> = atomFamily({\n\tkey: `unacknowledgedUpdates`,\n\tdefault: () => [],\n})\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetUpdateToken,\n\tsetIntoStore,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\n\nimport {\n\tredactTransactionUpdateContent,\n\tunacknowledgedUpdatesAtoms,\n} from \"./continuity-store\"\n\nexport function provideOutcomes(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst unsubscribeFunctions = new Set<() => void>()\n\n\tfor (const transaction of continuity.actions) {\n\t\tconst unsubscribeFromTransaction = subscribeToTransaction(\n\t\t\tstore,\n\t\t\ttransaction,\n\t\t\t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\t(outcomes) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst visibleKeys = continuity.globals\n\t\t\t\t\t\t.map((atom) => {\n\t\t\t\t\t\t\tif (atom.type === `atom`) {\n\t\t\t\t\t\t\t\treturn atom.key\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn getUpdateToken(atom).key\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\tcontinuity.perspectives.flatMap((perspective) => {\n\t\t\t\t\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\t\t\t\t\tconst userPerspectiveTokenState = findInStore(\n\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\tviewAtoms,\n\t\t\t\t\t\t\t\t\tuserKey,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tconst visibleTokens = getFromStore(\n\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\tuserPerspectiveTokenState,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\treturn visibleTokens.map((token) => {\n\t\t\t\t\t\t\t\t\tconst key =\n\t\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? `*` + token.key : token.key\n\t\t\t\t\t\t\t\t\treturn key\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\tconst redactedUpdates = redactTransactionUpdateContent(\n\t\t\t\t\t\tvisibleKeys,\n\t\t\t\t\t\toutcomes.subEvents,\n\t\t\t\t\t)\n\t\t\t\t\tconst redactedUpdate = {\n\t\t\t\t\t\t...outcomes,\n\t\t\t\t\t\tupdates: redactedUpdates,\n\t\t\t\t\t}\n\t\t\t\t\tsetIntoStore(store, unacknowledgedUpdatesAtoms, userKey, (updates) => {\n\t\t\t\t\t\tif (redactedUpdate) {\n\t\t\t\t\t\t\tupdates.push(redactedUpdate)\n\t\t\t\t\t\t\tupdates.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t\t`${userKey} unacknowledged update queue now has`,\n\t\t\t\t\t\t\t\tupdates.length,\n\t\t\t\t\t\t\t\t`items`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn updates\n\t\t\t\t\t})\n\n\t\t\t\t\tsocket.emit(\n\t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\t\t\tredactedUpdate as Json.Serializable,\n\t\t\t\t\t)\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t`āŒ`,\n\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t`${userKey} failed to send update from transaction ${transaction.key} to ${userKey}`,\n\t\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tunsubscribeFunctions.add(unsubscribeFromTransaction)\n\t}\n\treturn () => {\n\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t}\n}\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\n\nexport function providePerspectives(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst unsubFns = new Set<() => void>()\n\tfor (const perspective of continuity.perspectives) {\n\t\tconst { viewAtoms } = perspective\n\t\tconst userViewState = findInStore(store, viewAtoms, userKey)\n\t\tconst unsubscribeFromUserView = subscribeToState(\n\t\t\tstore,\n\t\t\tuserViewState,\n\t\t\t`sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,\n\t\t\t({ oldValue, newValue }) => {\n\t\t\t\tconst oldKeys = oldValue?.map((token) => token.key)\n\t\t\t\tconst newKeys = newValue.map((token) => token.key)\n\t\t\t\tconst concealed = oldValue?.filter(\n\t\t\t\t\t(token) => !newKeys.includes(token.key),\n\t\t\t\t)\n\t\t\t\tconst revealed = newValue\n\t\t\t\t\t.filter((token) => !oldKeys?.includes(token.key))\n\t\t\t\t\t.flatMap((token) => {\n\t\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? getJsonToken(store, token) : token\n\t\t\t\t\t\tconst resource = getFromStore(store, resourceToken)\n\t\t\t\t\t\treturn [resourceToken, resource]\n\t\t\t\t\t})\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t`atom`,\n\t\t\t\t\tperspective.resourceAtoms.key,\n\t\t\t\t\t`${userKey} has a new perspective`,\n\t\t\t\t\t{ oldKeys, newKeys, revealed, concealed },\n\t\t\t\t)\n\t\t\t\tif (revealed.length > 0) {\n\t\t\t\t\tsocket.emit(`reveal:${continuityKey}`, revealed)\n\t\t\t\t}\n\t\t\t\tif (concealed && concealed.length > 0) {\n\t\t\t\t\tsocket.emit(`conceal:${continuityKey}`, concealed)\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tunsubFns.add(unsubscribeFromUserView)\n\t}\n\treturn () => {\n\t\tfor (const unsubscribe of unsubFns) unsubscribe()\n\t}\n}\n","import type { Store } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tisRootStore,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nexport function provideStartupPayloads(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tfunction sendInitialPayload(): void {\n\t\tconst initialPayload: Json.Serializable[] = []\n\t\tfor (const atom of continuity.globals) {\n\t\t\tconst resourceToken =\n\t\t\t\tatom.type === `mutable_atom` ? getJsonToken(store, atom) : atom\n\t\t\tconst resource = getFromStore(store, resourceToken)\n\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t}\n\t\tfor (const perspective of continuity.perspectives) {\n\t\t\tconst { viewAtoms, resourceAtoms } = perspective\n\t\t\tconst userViewState = findInStore(store, viewAtoms, userKey)\n\t\t\tconst userView = getFromStore(store, userViewState)\n\t\t\tstore.logger.info(`šŸ‘`, `atom`, resourceAtoms.key, `${userKey} can see`, {\n\t\t\t\tviewAtoms,\n\t\t\t\tresourceAtoms,\n\t\t\t\tuserView,\n\t\t\t})\n\t\t\tfor (const visibleToken of userView) {\n\t\t\t\tconst resourceToken =\n\t\t\t\t\tvisibleToken.type === `mutable_atom`\n\t\t\t\t\t\t? getJsonToken(store, visibleToken)\n\t\t\t\t\t\t: visibleToken\n\t\t\t\tconst resource = getFromStore(store, resourceToken)\n\n\t\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t\t}\n\t\t}\n\n\t\tconst epoch = isRootStore(store)\n\t\t\t? (store.transactionMeta.epoch.get(continuityKey) ?? null)\n\t\t\t: null\n\n\t\tsocket.emit(`continuity-init:${continuityKey}`, epoch, initialPayload)\n\t}\n\treturn employSocket(socket, `get:${continuityKey}`, sendInitialPayload)\n}\n","import type { TransactionOutcomeEvent, TransactionToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { actUponStore } from \"atom.io/internal\"\nimport type { Json, JsonIO } from \"atom.io/json\"\nimport type { ContinuityToken, Socket } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nexport function receiveActionRequests(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: string,\n): () => void {\n\tconst continuityKey = continuity.key\n\n\treturn employSocket(\n\t\tsocket,\n\t\t`tx-run:${continuityKey}`,\n\t\tfunction serveTransactionRequest(\n\t\t\ttxOutcome: Json.Serializable &\n\t\t\t\tPick<\n\t\t\t\t\tTransactionOutcomeEvent<TransactionToken<JsonIO>>,\n\t\t\t\t\t`id` | `params` | `token`\n\t\t\t\t>,\n\t\t) {\n\t\t\tstore.logger.info(`šŸ›Žļø`, `continuity`, continuityKey, `received`, txOutcome)\n\t\t\tconst transactionKey = txOutcome.token.key\n\t\t\tconst updateId = txOutcome.id\n\t\t\tconst performanceKey = `tx-run:${transactionKey}:${updateId}`\n\t\t\tconst performanceKeyStart = `${performanceKey}:start`\n\t\t\tconst performanceKeyEnd = `${performanceKey}:end`\n\t\t\tperformance.mark(performanceKeyStart)\n\t\t\ttry {\n\t\t\t\tactUponStore(\n\t\t\t\t\tstore,\n\t\t\t\t\t{ type: `transaction`, key: transactionKey },\n\t\t\t\t\tupdateId,\n\t\t\t\t)(...txOutcome.params)\n\t\t\t} catch (thrown) {\n\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t`āŒ`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`failed to run transaction ${transactionKey} from ${userKey} with update ${updateId}`,\n\t\t\t\t\t\tthrown.message,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tperformance.mark(performanceKeyEnd)\n\t\t\tconst metric = performance.measure(\n\t\t\t\tperformanceKey,\n\t\t\t\tperformanceKeyStart,\n\t\t\t\tperformanceKeyEnd,\n\t\t\t)\n\t\t\tstore.logger.info(\n\t\t\t\t`šŸš€`,\n\t\t\t\t`transaction`,\n\t\t\t\ttransactionKey,\n\t\t\t\tupdateId,\n\t\t\t\tuserKey,\n\t\t\t\tmetric.duration,\n\t\t\t)\n\t\t},\n\t)\n}\n","import type { Store } from \"atom.io/internal\"\nimport { getFromStore, setIntoStore } from \"atom.io/internal\"\nimport type { ContinuityToken, Socket, UserKey } from \"atom.io/realtime\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport { unacknowledgedUpdatesAtoms } from \"./continuity-store\"\n\nexport function trackAcknowledgements(\n\tstore: Store,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst userUnacknowledgedUpdates = getFromStore(\n\t\tstore,\n\t\tunacknowledgedUpdatesAtoms,\n\t\tuserKey,\n\t)\n\tfunction trackClientAcknowledgement(epoch: number): void {\n\t\tstore.logger.info(\n\t\t\t`šŸ‘`,\n\t\t\t`continuity`,\n\t\t\tcontinuityKey,\n\t\t\t`${userKey} acknowledged epoch ${epoch}`,\n\t\t)\n\t\tconst isUnacknowledged = userUnacknowledgedUpdates[0]?.epoch === epoch\n\t\tif (isUnacknowledged) {\n\t\t\tsetIntoStore(store, unacknowledgedUpdatesAtoms, userKey, (updates) => {\n\t\t\t\tupdates.shift()\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`šŸ‘`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`${userKey} unacknowledged update queue now has`,\n\t\t\t\t\tupdates.length,\n\t\t\t\t\t`items`,\n\t\t\t\t)\n\t\t\t\treturn updates\n\t\t\t})\n\t\t}\n\t}\n\treturn employSocket(socket, `ack:${continuityKey}`, trackClientAcknowledgement)\n}\n","import { getFromStore, IMPLICIT } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken, UserKey } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \"..\"\nimport { unacknowledgedUpdatesAtoms } from \"./continuity-store\"\nimport { provideOutcomes } from \"./provide-outcomes\"\nimport { providePerspectives } from \"./provide-perspectives\"\nimport { provideStartupPayloads } from \"./provide-startup-payloads\"\nimport { receiveActionRequests } from \"./receive-action-requests\"\nimport { trackAcknowledgements } from \"./track-acknowledgements\"\n\nexport type ProvideContinuity = (\n\tcontinuity: ContinuityToken,\n\tuserKey: UserKey,\n) => () => void\nexport function prepareToProvideContinuity({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig): ProvideContinuity {\n\treturn function syncRealtimeContinuity(continuity, userKey) {\n\t\tconst continuityKey = continuity.key\n\n\t\tconst unacknowledgedUpdates = getFromStore(\n\t\t\tstore,\n\t\t\tunacknowledgedUpdatesAtoms,\n\t\t\tuserKey,\n\t\t)\n\t\tfor (const unacknowledgedUpdate of unacknowledgedUpdates) {\n\t\t\tsocket.emit(\n\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\tunacknowledgedUpdate as Json.Serializable,\n\t\t\t)\n\t\t}\n\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsubscribe of subscriptions) unsubscribe()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tsubscriptions.add(providePerspectives(store, socket, continuity, userKey))\n\t\tsubscriptions.add(provideOutcomes(store, socket, continuity, userKey))\n\t\tsubscriptions.add(provideStartupPayloads(store, socket, continuity, userKey))\n\t\tsubscriptions.add(receiveActionRequests(store, socket, continuity, userKey))\n\t\tsubscriptions.add(trackAcknowledgements(store, socket, continuity, userKey))\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type { Json, stringified } from \"atom.io/json\"\nimport type { Socket } from \"atom.io/realtime\"\n\nexport type Events = Json.Object<string, Json.Serializable[]>\n\nexport type EventPayload<\n\treceiveRelay extends Events,\n\tK extends string & keyof receiveRelay = string & keyof receiveRelay,\n> = [string, ...receiveRelay[K]]\n\nexport interface EventBuffer<\n\tE extends Events,\n\tK extends string & keyof E = string & keyof E,\n> extends Buffer {\n\ttoString(): stringified<EventPayload<E, K>>\n}\n\nexport abstract class CustomSocket<I extends Events, O extends Events>\n\timplements Socket\n{\n\tprotected listeners: Map<keyof O, Set<(...args: Json.Array) => void>>\n\tprotected globalListeners: Set<(event: string, ...args: Json.Array) => void>\n\tprotected handleEvent<K extends string & keyof I>(\n\t\t...args: EventPayload<I, K>\n\t): void {\n\t\tconst [event, ...rest] = args\n\t\tfor (const listener of this.globalListeners) {\n\t\t\tlistener(event, ...rest)\n\t\t}\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...rest)\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic id = `no_id_retrieved`\n\tpublic emit: <Event extends keyof I>(\n\t\tevent: Event,\n\t\t...args: I[Event]\n\t) => CustomSocket<I, O>\n\n\tpublic constructor(\n\t\temit: <Event extends keyof I>(\n\t\t\tevent: Event,\n\t\t\t...args: I[Event]\n\t\t) => CustomSocket<I, O>,\n\t) {\n\t\tthis.emit = emit\n\t\tthis.listeners = new Map()\n\t\tthis.globalListeners = new Set()\n\t}\n\n\tpublic on<Event extends keyof O>(\n\t\tevent: Event,\n\t\tlistener: (...args: O[Event]) => void,\n\t): this {\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tlisteners.add(listener)\n\t\t} else {\n\t\t\tthis.listeners.set(event, new Set([listener]))\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic onAny(listener: (event: string, ...args: Json.Array) => void): this {\n\t\tthis.globalListeners.add(listener)\n\t\treturn this\n\t}\n\n\tpublic off<Event extends keyof O>(\n\t\tevent: Event,\n\t\tlistener?: (...args: O[Event]) => void,\n\t): this {\n\t\tconst listeners = this.listeners.get(event)\n\t\tif (listeners) {\n\t\t\tif (listener) {\n\t\t\t\tlisteners.delete(listener)\n\t\t\t} else {\n\t\t\t\tthis.listeners.delete(event)\n\t\t\t}\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic offAny(listener: (event: string, ...args: Json.Array) => void): this {\n\t\tthis.globalListeners.delete(listener)\n\t\treturn this\n\t}\n}\n","import type { Readable, Writable } from \"node:stream\"\n\nimport type { Json, stringified } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\n\nimport type { EventBuffer, EventPayload, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\n/* eslint-disable no-console */\n\nexport type ChildProcess = {\n\tpid?: number | undefined\n\tstdin: Writable\n\tstdout: Readable\n\tstderr: Readable\n}\n\nexport type StderrLog = [`e` | `i` | `w`, ...Json.Array]\n\nexport class ChildSocket<\n\tI extends Events,\n\tO extends Events,\n\tP extends ChildProcess = ChildProcess,\n> extends CustomSocket<I, O> {\n\tprotected incompleteData = ``\n\tprotected unprocessedEvents: string[] = []\n\tprotected incompleteLog = ``\n\tprotected unprocessedLogs: string[] = []\n\n\tpublic id = `#####`\n\n\tpublic proc: P\n\tpublic key: string\n\tpublic logger: Pick<Console, `error` | `info` | `warn`>\n\n\tprotected handleLog(log: StderrLog): void {\n\t\tif (Array.isArray(log)) {\n\t\t\tconst [level, ...rest] = log\n\t\t\tswitch (level) {\n\t\t\t\tcase `i`:\n\t\t\t\t\tthis.logger.info(...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `w`:\n\t\t\t\t\tthis.logger.warn(...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `e`:\n\t\t\t\t\tthis.logger.error(...rest)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tproc: P,\n\t\tkey: string,\n\t\tlogger?: Pick<Console, `error` | `info` | `warn`>,\n\t) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args]) + `\\x03`\n\t\t\tconst errorHandler = (err: { code: string }) => {\n\t\t\t\tif (err.code === `EPIPE`) {\n\t\t\t\t\tconsole.error(`EPIPE error during write`, this.proc.stdin)\n\t\t\t\t}\n\t\t\t\tthis.proc.stdin.removeListener(`error`, errorHandler)\n\t\t\t}\n\n\t\t\tthis.proc.stdin.once(`error`, errorHandler)\n\t\t\tthis.proc.stdin.write(stringifiedEvent)\n\n\t\t\treturn this\n\t\t})\n\t\tthis.proc = proc\n\t\tthis.key = key\n\t\tthis.logger = logger ?? {\n\t\t\tinfo: (...args: unknown[]) => {\n\t\t\t\tconsole.info(this.id, this.key, ...args)\n\t\t\t},\n\t\t\twarn: (...args: unknown[]) => {\n\t\t\t\tconsole.warn(this.id, this.key, ...args)\n\t\t\t},\n\t\t\terror: (...args: unknown[]) => {\n\t\t\t\tconsole.error(this.id, this.key, ...args)\n\t\t\t},\n\t\t}\n\t\tthis.proc.stdout.on(\n\t\t\t`data`,\n\t\t\t<K extends string & keyof I>(buffer: EventBuffer<I, K>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\n\t\t\t\tif (chunk === `ALIVE`) {\n\t\t\t\t\tthis.logger.info(chunk)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\t\tlet idx = 0\n\t\t\t\tfor (const piece of pieces) {\n\t\t\t\t\tif (piece === ``) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst jsonPiece = parseJson(piece as stringified<EventPayload<I, K>>)\n\t\t\t\t\t\tthis.handleEvent(...jsonPiece)\n\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t} catch (thrown0) {\n\t\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`āŒ Malformed data received from child process`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(\n\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed as stringified<EventPayload<I, K>>,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.handleEvent(...maybeActualJsonPiece)\n\t\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t`āŒ Malformed data received from child process`,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t++idx\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tthis.proc.stderr.on(`data`, (buffer: Buffer) => {\n\t\t\tconst chunk = buffer.toString()\n\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\tlet idx = 0\n\t\t\tfor (const piece of pieces) {\n\t\t\t\tif (piece === ``) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst jsonPiece = parseJson(piece as stringified<StderrLog>)\n\t\t\t\t\tthis.handleLog(jsonPiece)\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (thrown0) {\n\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t`āŒ Malformed log received from child process`,\n\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(\n\t\t\t\t\t\t\t\tinitialMaybeWellFormed as stringified<StderrLog>,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.handleLog(maybeActualJsonPiece)\n\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`āŒ Malformed log received from child process...`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++idx\n\t\t\t}\n\t\t})\n\t\tif (proc.pid) {\n\t\t\tthis.id = proc.pid.toString()\n\t\t}\n\t}\n}\n","import type { Readable, Writable } from \"node:stream\"\n\nimport { Subject } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\nimport type { UserKey } from \"atom.io/realtime\"\nimport { UList } from \"atom.io/transceivers/u-list\"\n\nimport type { StderrLog } from \"./child-socket\"\nimport type { EventBuffer, EventPayload, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\nexport class SubjectSocket<\n\tI extends Events,\n\tO extends Events,\n> extends CustomSocket<I, O> {\n\tpublic in: Subject<EventPayload<I>>\n\tpublic out: Subject<EventPayload<O>>\n\tpublic id = `no_id_retrieved`\n\tpublic disposalFunctions: (() => void)[] = []\n\n\tpublic constructor(id: string) {\n\t\tsuper((...args) => {\n\t\t\tthis.out.next(args as any)\n\t\t\treturn this\n\t\t})\n\t\tthis.id = id\n\t\tthis.in = new Subject()\n\t\tthis.out = new Subject()\n\t\tthis.in.subscribe(`socket`, (event) => {\n\t\t\tthis.handleEvent(...event)\n\t\t})\n\t}\n\n\tpublic dispose(): void {\n\t\tfor (const dispose of this.disposalFunctions) {\n\t\t\tdispose()\n\t\t}\n\t}\n}\n\nexport type ParentProcess = {\n\tpid?: number | undefined\n\tstdin: Readable\n\tstdout: Writable\n\tstderr: Writable\n\texit: (code?: number) => void\n}\n\nexport class ParentSocket<\n\tI extends Events & {\n\t\t[id in string as `relay::${id}`]: [string, ...Json.Array[]]\n\t},\n\tO extends Events & {\n\t\t[id in string as `user::${id}`]: [string, ...Json.Array[]]\n\t} & {\n\t\t/* eslint-disable quotes */\n\t\t\"user-joins\": [key: UserKey]\n\t\t\"user-leaves\": [key: UserKey]\n\t\t/* eslint-enable quotes */\n\t},\n\tP extends ParentProcess = ParentProcess,\n> extends CustomSocket<I, O> {\n\tprotected incompleteData = ``\n\tprotected unprocessedEvents: string[] = []\n\tprotected relays: Map<string, SubjectSocket<any, any>>\n\tprotected relayServices: ((\n\t\tsocket: SubjectSocket<any, any>,\n\t\tuserKey: UserKey,\n\t) => (() => void) | void)[]\n\tpublic proc: P\n\n\tpublic id = `#####`\n\n\tprotected log(...args: StderrLog): void {\n\t\tthis.proc.stderr.write(\n\t\t\tstringifyJson(\n\t\t\t\targs.map((arg) =>\n\t\t\t\t\targ instanceof UList ? `{ ${arg.toJSON().join(` | `)} }` : arg,\n\t\t\t\t),\n\t\t\t) + `\\x03`,\n\t\t)\n\t}\n\tpublic logger = {\n\t\tinfo: (...args: Json.Array): void => {\n\t\t\tthis.log(`i`, ...args)\n\t\t},\n\t\twarn: (...args: Json.Array): void => {\n\t\t\tthis.log(`w`, ...args)\n\t\t},\n\t\terror: (...args: Json.Array): void => {\n\t\t\tthis.log(`e`, ...args)\n\t\t},\n\t}\n\n\tpublic constructor(proc: P) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args])\n\t\t\tthis.proc.stdout.write(stringifiedEvent + `\\x03`)\n\t\t\treturn this\n\t\t})\n\t\tthis.proc = proc\n\t\tthis.proc.stdin.resume()\n\t\tthis.relays = new Map()\n\t\tthis.relayServices = []\n\n\t\tthis.proc.stdin.on(\n\t\t\t`data`,\n\t\t\t<K extends string & keyof I>(buffer: EventBuffer<I, K>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\t\t\t\tconst pieces = chunk.split(`\\x03`)\n\t\t\t\tconst initialMaybeWellFormed = pieces[0]\n\t\t\t\tpieces[0] = this.incompleteData + initialMaybeWellFormed\n\t\t\t\tlet idx = 0\n\t\t\t\tfor (const piece of pieces) {\n\t\t\t\t\tif (piece === ``) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst jsonPiece = parseJson(piece)\n\t\t\t\t\t\tthis.logger.info(`šŸŽ°`, `received`, jsonPiece)\n\t\t\t\t\t\tthis.handleEvent(...(jsonPiece as EventPayload<I>))\n\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t} catch (thrown0) {\n\t\t\t\t\t\tif (thrown0 instanceof Error) {\n\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t`received malformed data from parent process:`,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tpiece,\n\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\tthrown0.message,\n\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = piece\n\t\t\t\t\t\t\t\tconst maybeActualJsonPiece = parseJson(initialMaybeWellFormed)\n\t\t\t\t\t\t\t\tthis.logger.info(`šŸŽ°`, `received`, maybeActualJsonPiece)\n\t\t\t\t\t\t\t\tthis.handleEvent(...(maybeActualJsonPiece as EventPayload<I>))\n\t\t\t\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.incompleteData += piece\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (thrown1) {\n\t\t\t\t\t\t\tif (thrown1 instanceof Error) {\n\t\t\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t`received malformed data from parent process:`,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tinitialMaybeWellFormed,\n\t\t\t\t\t\t\t\t\t\t``,\n\t\t\t\t\t\t\t\t\t\tthrown1.message,\n\t\t\t\t\t\t\t\t\t].join(`\\nāŒ\\t`),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t++idx\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\n\t\tthis.on(`exit`, () => {\n\t\t\tthis.logger.info(`šŸ”„`, this.id, `received \"exit\"`)\n\t\t\tthis.proc.exit(0)\n\t\t})\n\n\t\tif (this.proc.pid) {\n\t\t\tthis.id = this.proc.pid?.toString()\n\t\t}\n\n\t\tthis.on(`user-joins`, (username: string) => {\n\t\t\tthis.logger.info(`šŸ‘¤`, `user`, username, `joined`)\n\t\t\tconst userKey = `user::${username}` satisfies UserKey\n\t\t\tconst relay = new SubjectSocket(userKey)\n\t\t\tthis.relays.set(username, relay)\n\t\t\tthis.logger.info(\n\t\t\t\t`šŸ”—`,\n\t\t\t\t`attaching services:`,\n\t\t\t\t`[${[...this.relayServices.keys()].join(`, `)}]`,\n\t\t\t)\n\t\t\tfor (const attachRelay of this.relayServices) {\n\t\t\t\tconst cleanupRelay = attachRelay(relay, userKey)\n\t\t\t\tif (cleanupRelay) {\n\t\t\t\t\trelay.disposalFunctions.push(cleanupRelay)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.on(userKey, (...data) => {\n\t\t\t\trelay.in.next(data)\n\t\t\t})\n\t\t\trelay.out.subscribe(`socket`, (data) => {\n\t\t\t\tthis.emit(...(data as [string, ...I[keyof I]]))\n\t\t\t})\n\t\t})\n\n\t\tthis.on(`user-leaves`, (username) => {\n\t\t\tconst relay = this.relays.get(username)\n\t\t\tthis.off(`relay:${username}`)\n\t\t\tif (relay) {\n\t\t\t\trelay.dispose()\n\t\t\t\tthis.relays.delete(username)\n\t\t\t}\n\t\t})\n\n\t\tthis.proc.stdout.write(`ALIVE`)\n\t}\n\n\tpublic receiveRelay(\n\t\tattachServices: (\n\t\t\tsocket: SubjectSocket<any, any>,\n\t\t\tuserKey: UserKey,\n\t\t) => (() => void) | void,\n\t): void {\n\t\tthis.logger.info(`šŸ”—`, `running relay method`)\n\t\tthis.relayServices.push(attachServices)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Canonical, Json, stringified } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type FamilyProvider = ReturnType<typeof realtimeAtomFamilyProvider>\nexport function realtimeAtomFamilyProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function familyProvider<\n\t\tJ extends Json.Serializable,\n\t\tK extends Canonical,\n\t>(\n\t\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst coreSubscriptions = new Set<() => void>()\n\t\tconst clearCoreSubscriptions = () => {\n\t\t\tfor (const unsub of coreSubscriptions) unsub()\n\t\t\tcoreSubscriptions.clear()\n\t\t}\n\t\tconst familyMemberSubscriptionsWanted = new Set<stringified<K>>()\n\t\tconst familyMemberSubscriptions = new Map<string, () => void>()\n\t\tconst clearFamilySubscriptions = () => {\n\t\t\tfor (const unsub of familyMemberSubscriptions.values()) unsub()\n\t\t\tfamilyMemberSubscriptions.clear()\n\t\t}\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tconst unsubUnsub = familyMemberSubscriptions.get(`${key}:unsub`)\n\t\t\tif (unsubUnsub) {\n\t\t\t\tunsubUnsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(`${key}:unsub`)\n\t\t\t}\n\t\t\tconst unsub = familyMemberSubscriptions.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst exposeFamilyMembers = (subKey: K) => {\n\t\t\tconst token = findInStore(store, family, subKey)\n\t\t\tgetFromStore(store, token)\n\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(store, token))\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\ttoken.key,\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\ttoken,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\t`${token.key}:unsub`,\n\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst isAvailable = (exposedSubKeys: Iterable<K>, subKey: K): boolean => {\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tcoreSubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${family.key}`, (subKey: K) => {\n\t\t\t\t\tconst exposedSubKeys = getFromStore(store, index)\n\t\t\t\t\tconst shouldExpose = isAvailable(exposedSubKeys, subKey)\n\t\t\t\t\tif (shouldExpose) {\n\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfamilyMemberSubscriptionsWanted.add(stringifyJson(subKey))\n\t\t\t\t\t\tsocket.emit(`unavailable:${family.key}`, subKey)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\tcoreSubscriptions.add(\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tindex,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue: newExposedSubKeys }) => {\n\t\t\t\t\t\tfor (const subKey of newExposedSubKeys) {\n\t\t\t\t\t\t\tif (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {\n\t\t\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn () => {\n\t\t\tclearCoreSubscriptions()\n\t\t\tclearFamilySubscriptions()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Canonical, stringified } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nconst isAvailable = <K extends Canonical>(\n\texposedSubKeys: Iterable<K>,\n\tsubKey: K,\n): boolean => {\n\tfor (const exposedSubKey of exposedSubKeys) {\n\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nexport type MutableFamilyProvider = ReturnType<\n\ttypeof realtimeMutableFamilyProvider\n>\nexport function realtimeMutableFamilyProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function mutableFamilyProvider<\n\t\tT extends Transceiver<any, any, any>,\n\t\tK extends Canonical,\n\t>(\n\t\tfamily: AtomIO.MutableAtomFamilyToken<T, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst coreSubscriptions = new Set<() => void>()\n\t\tconst clearCoreSubscriptions = () => {\n\t\t\tfor (const unsub of coreSubscriptions) unsub()\n\t\t\tcoreSubscriptions.clear()\n\t\t}\n\t\tconst familyMemberSubscriptionsWanted = new Set<stringified<K>>()\n\t\tconst familyMemberSubscriptions = new Map<string, () => void>()\n\t\tconst clearFamilySubscriptions = () => {\n\t\t\tfor (const unsub of familyMemberSubscriptions.values()) unsub()\n\t\t\tfamilyMemberSubscriptions.clear()\n\t\t}\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tconst unsubUnsub = familyMemberSubscriptions.get(`${key}:unsub`)\n\t\t\tif (unsubUnsub) {\n\t\t\t\tunsubUnsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(`${key}:unsub`)\n\t\t\t}\n\t\t\tconst unsub = familyMemberSubscriptions.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tfamilyMemberSubscriptions.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst exposeFamilyMembers = (subKey: K) => {\n\t\t\tconst token = findInStore(store, family, subKey)\n\t\t\tgetFromStore(store, token)\n\t\t\tconst jsonToken = getJsonToken(store, token)\n\t\t\tconst updateToken = getUpdateToken(token)\n\t\t\tsocket.emit(`init:${token.key}`, getFromStore(store, jsonToken))\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\ttoken.key,\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tupdateToken,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t\tfamilyMemberSubscriptions.set(\n\t\t\t\t`${token.key}:unsub`,\n\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tcoreSubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${family.key}`, (subKey: K) => {\n\t\t\t\t\tconst exposedSubKeys = getFromStore(store, index)\n\t\t\t\t\tconst shouldExpose = isAvailable(exposedSubKeys, subKey)\n\t\t\t\t\tif (shouldExpose) {\n\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfamilyMemberSubscriptionsWanted.add(stringifyJson(subKey))\n\t\t\t\t\t\tsocket.emit(`unavailable:${family.key}`, subKey)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\tcoreSubscriptions.add(\n\t\t\t\tsubscribeToState(\n\t\t\t\t\tstore,\n\t\t\t\t\tindex,\n\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t({ newValue: newExposedSubKeys }) => {\n\t\t\t\t\t\tfor (const subKey of newExposedSubKeys) {\n\t\t\t\t\t\t\tif (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {\n\t\t\t\t\t\t\t\texposeFamilyMembers(subKey)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn () => {\n\t\t\tclearCoreSubscriptions()\n\t\t\tclearFamilySubscriptions()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tIMPLICIT,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type MutableProvider = ReturnType<typeof realtimeMutableProvider>\nexport function realtimeMutableProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function mutableProvider<\n\t\tCore extends Transceiver<any, Json.Serializable, Json.Serializable>,\n\t>(token: AtomIO.MutableAtomToken<Core>): () => void {\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst jsonToken = getJsonToken(store, token)\n\t\tconst trackerToken = getUpdateToken(token)\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${token.key}`, () => {\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tsocket.emit(`init:${token.key}`, getFromStore(store, jsonToken))\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\tsubscribeToState(\n\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\ttrackerToken,\n\t\t\t\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\t\tstart()\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type {\n\tHierarchy,\n\tJoinToken,\n\tMutableAtomToken,\n\tPureSelectorFamilyToken,\n\tRegularAtomFamilyToken,\n} from \"atom.io\"\nimport { atomFamily, join, mutableAtom, selectorFamily } from \"atom.io\"\nimport type { RoomKey, Socket, SocketKey, UserKey } from \"atom.io/realtime\"\nimport { isSocketKey, isUserKey } from \"atom.io/realtime\"\nimport { UList } from \"atom.io/transceivers/u-list\"\n\nexport type SocketSystemHierarchy = Hierarchy<\n\t[\n\t\t{\n\t\t\tabove: `root`\n\t\t\tbelow: [UserKey, SocketKey, RoomKey]\n\t\t},\n\t]\n>\n\nexport const socketAtoms: RegularAtomFamilyToken<Socket | null, SocketKey> =\n\tatomFamily({\n\t\tkey: `sockets`,\n\t\tdefault: null,\n\t})\n\nexport const socketKeysAtom: MutableAtomToken<UList<SocketKey>> = mutableAtom({\n\tkey: `socketsIndex`,\n\tclass: UList,\n})\nexport const userKeysAtom: MutableAtomToken<UList<UserKey>> = mutableAtom({\n\tkey: `usersIndex`,\n\tclass: UList,\n})\nexport const usersOfSockets: JoinToken<\n\t`user`,\n\tUserKey,\n\t`socket`,\n\tSocketKey,\n\t`1:1`\n> = join({\n\tkey: `usersOfSockets`,\n\tbetween: [`user`, `socket`],\n\tcardinality: `1:1`,\n\tisAType: isUserKey,\n\tisBType: isSocketKey,\n})\n\nexport const selfListSelectors: PureSelectorFamilyToken<UserKey[], UserKey> =\n\tselectorFamily({\n\t\tkey: `selfList`,\n\t\tget: (userId) => () => [userId],\n\t})\n","import type { ChildProcessWithoutNullStreams } from \"node:child_process\"\nimport { spawn } from \"node:child_process\"\n\nimport type { RootStore } from \"atom.io/internal\"\nimport {\n\teditRelationsInStore,\n\tfindInStore,\n\tfindRelationsInStore,\n\tgetFromStore,\n\tgetInternalRelationsFromStore,\n\tIMPLICIT,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type {\n\tAllEventsListener,\n\tEventsMap,\n\tRoomKey,\n\tRoomSocketInterface,\n\tSocket,\n\tSocketGuard,\n\tSocketKey,\n\tStandardSchemaV1,\n\tTypedSocket,\n\tUserKey,\n} from \"atom.io/realtime\"\nimport {\n\tcastSocket,\n\tisRoomKey,\n\townersOfRooms,\n\troomKeysAtom,\n\tusersInRooms,\n} from \"atom.io/realtime\"\n\nimport { ChildSocket } from \"../ipc-sockets\"\nimport { realtimeMutableFamilyProvider } from \"../realtime-mutable-family-provider\"\nimport { realtimeMutableProvider } from \"../realtime-mutable-provider\"\nimport type { ServerConfig } from \"../server-config\"\nimport {\n\tselfListSelectors,\n\tsocketKeysAtom,\n\tuserKeysAtom,\n\tusersOfSockets,\n} from \"./server-user-store\"\n\nexport type RoomMap = Map<\n\tstring,\n\tChildSocket<any, any, ChildProcessWithoutNullStreams>\n>\n\ndeclare global {\n\tvar ATOM_IO_REALTIME_SERVER_ROOMS: RoomMap\n}\nexport const ROOMS: RoomMap =\n\tglobalThis.ATOM_IO_REALTIME_SERVER_ROOMS ??\n\t(globalThis.ATOM_IO_REALTIME_SERVER_ROOMS = new Map())\n\nexport const roomMeta: { count: number } = { count: 0 }\n\nexport type SpawnRoomConfig<RoomNames extends string> = {\n\tstore: RootStore\n\tsocket: Socket\n\tuserKey: UserKey\n\tresolveRoomScript: (roomName: RoomNames) => [string, string[]]\n}\nexport function spawnRoom<RoomNames extends string>({\n\tstore,\n\tsocket,\n\tuserKey,\n\tresolveRoomScript,\n}: SpawnRoomConfig<RoomNames>): (\n\troomName: RoomNames,\n) => Promise<ChildSocket<any, any>> {\n\treturn async (roomName) => {\n\t\tstore.logger.info(\n\t\t\t`šŸ“”`,\n\t\t\t`socket`,\n\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t`šŸ‘¤ ${userKey} spawns room ${roomName}`,\n\t\t)\n\t\tconst roomKey = `room::${roomMeta.count++}` satisfies RoomKey\n\t\tconst [command, args] = resolveRoomScript(roomName)\n\t\tconst child = await new Promise<ChildProcessWithoutNullStreams>(\n\t\t\t(resolve) => {\n\t\t\t\tconst room = spawn(command, args, { env: process.env })\n\t\t\t\tconst resolver = (data: Buffer) => {\n\t\t\t\t\tif (data.toString() === `ALIVE`) {\n\t\t\t\t\t\troom.stdout.off(`data`, resolver)\n\t\t\t\t\t\tresolve(room)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\troom.stdout.on(`data`, resolver)\n\t\t\t},\n\t\t)\n\t\tconst roomSocket = new ChildSocket(child, roomKey)\n\t\tROOMS.set(roomKey, roomSocket)\n\t\tsetIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index))\n\n\t\teditRelationsInStore(store, ownersOfRooms, (relations) => {\n\t\t\trelations.set({ room: roomKey, user: userKey })\n\t\t})\n\n\t\troomSocket.on(`close`, () => {\n\t\t\tdestroyRoom({ store, socket, userKey })(roomKey)\n\t\t})\n\n\t\treturn roomSocket\n\t}\n}\n\nexport type ProvideEnterAndExitConfig = {\n\tstore: RootStore\n\tsocket: Socket\n\troomSocket: TypedSocket<RoomSocketInterface<any>, any>\n\tuserKey: UserKey\n}\nexport function provideEnterAndExit({\n\tstore,\n\tsocket,\n\troomSocket,\n\tuserKey,\n}: ProvideEnterAndExitConfig): (roomKey: RoomKey) => void {\n\tconst enterRoom = (roomKey: RoomKey) => {\n\t\tstore.logger.info(\n\t\t\t`šŸ“”`,\n\t\t\t`socket`,\n\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t`šŸ‘¤ ${userKey} enters room ${roomKey}`,\n\t\t)\n\n\t\tconst exitRoom = () => {\n\t\t\tstore.logger.info(\n\t\t\t\t`šŸ“”`,\n\t\t\t\t`socket`,\n\t\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t\t`šŸ‘¤ ${userKey} leaves room ${roomKey}`,\n\t\t\t)\n\t\t\tsocket.offAny(forward)\n\t\t\ttoRoom([`user-leaves`])\n\t\t\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\t\t\trelations.delete({ room: roomKey, user: userKey })\n\t\t\t})\n\t\t\troomSocket.off(`leaveRoom`, exitRoom)\n\t\t\troomSocket.on(`joinRoom`, enterRoom)\n\t\t}\n\n\t\troomSocket.on(`leaveRoom`, exitRoom)\n\t\troomSocket.off(`joinRoom`, enterRoom)\n\n\t\tconst roomQueue: [string, ...Json.Array][] = []\n\t\tconst pushToRoomQueue = (payload: [string, ...Json.Array]): void => {\n\t\t\troomQueue.push(payload)\n\t\t}\n\t\tlet toRoom = pushToRoomQueue\n\t\tconst forward: AllEventsListener<EventsMap> = (...payload) => {\n\t\t\ttoRoom(payload)\n\t\t}\n\t\tsocket.onAny(forward)\n\n\t\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\t\trelations.set({ room: roomKey, user: userKey })\n\t\t})\n\t\tconst childSocket = ROOMS.get(roomKey)\n\t\tif (!childSocket) {\n\t\t\tstore.logger.error(`āŒ`, `unknown`, roomKey, `no room found with this id`)\n\t\t\treturn null\n\t\t}\n\t\tchildSocket.onAny((...payload) => {\n\t\t\tsocket.emit(...payload)\n\t\t})\n\t\tchildSocket.emit(`user-joins`, userKey)\n\n\t\ttoRoom = (payload) => {\n\t\t\tchildSocket.emit(`user::${userKey}`, ...payload)\n\t\t}\n\t\twhile (roomQueue.length > 0) {\n\t\t\tconst payload = roomQueue.shift()\n\t\t\tif (payload) toRoom(payload)\n\t\t}\n\t}\n\troomSocket.on(`joinRoom`, enterRoom)\n\treturn enterRoom\n}\n\nexport type DestroyRoomConfig = {\n\tstore: RootStore\n\tsocket: Socket\n\tuserKey: UserKey\n}\nexport function destroyRoom({\n\tstore,\n\tsocket,\n\tuserKey,\n}: DestroyRoomConfig): (roomKey: RoomKey) => void {\n\treturn (roomKey: RoomKey) => {\n\t\tstore.logger.info(\n\t\t\t`šŸ“”`,\n\t\t\t`socket`,\n\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t`šŸ‘¤ ${userKey} attempts to delete room ${roomKey}`,\n\t\t)\n\t\tconst owner = getFromStore(\n\t\t\tstore,\n\t\t\tfindRelationsInStore(store, ownersOfRooms, roomKey).userKeyOfRoom,\n\t\t)\n\t\tif (owner === userKey) {\n\t\t\tstore.logger.info(\n\t\t\t\t`šŸ“”`,\n\t\t\t\t`socket`,\n\t\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t\t`šŸ‘¤ ${userKey} deletes room ${roomKey}`,\n\t\t\t)\n\t\t\tsetIntoStore(store, roomKeysAtom, (s) => (s.delete(roomKey), s))\n\t\t\teditRelationsInStore(store, usersInRooms, (relations) => {\n\t\t\t\trelations.delete({ room: roomKey })\n\t\t\t})\n\t\t\tconst room = ROOMS.get(roomKey)\n\t\t\tif (room) {\n\t\t\t\troom.emit(`exit`)\n\t\t\t\tROOMS.delete(roomKey)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tstore.logger.info(\n\t\t\t`šŸ“”`,\n\t\t\t`socket`,\n\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t`šŸ‘¤ ${userKey} failed to delete room ${roomKey}; room owner is ${owner}`,\n\t\t)\n\t}\n}\n\nexport type ProvideRoomsConfig<RoomNames extends string> = {\n\tresolveRoomScript: (path: RoomNames) => [string, string[]]\n\troomNames: RoomNames[]\n\troomTimeLimit?: number\n}\nexport function provideRooms<RoomNames extends string>({\n\tstore = IMPLICIT.STORE,\n\tsocket,\n\tresolveRoomScript,\n\troomNames,\n}: ProvideRoomsConfig<RoomNames> & ServerConfig): void {\n\tconst socketKey = `socket::${socket.id}` satisfies SocketKey\n\tconst userKey = getFromStore(\n\t\tstore,\n\t\tfindRelationsInStore(store, usersOfSockets, socketKey).userKeyOfSocket,\n\t)!\n\t// const roomSocket = socket as TypedSocket<RoomSocketInterface<RoomNames>, {}>\n\tconst roomSocket = castSocket<TypedSocket<RoomSocketInterface<RoomNames>, {}>>(\n\t\tsocket,\n\t\tcreateRoomSocketGuard(roomNames),\n\t)\n\n\tconst exposeMutable = realtimeMutableProvider({ socket, store })\n\tconst exposeMutableFamily = realtimeMutableFamilyProvider({\n\t\tsocket,\n\t\tstore,\n\t})\n\n\texposeMutable(roomKeysAtom)\n\n\tconst [, usersInRoomsAtoms] = getInternalRelationsFromStore(\n\t\tstore,\n\t\tusersInRooms,\n\t\t`split`,\n\t)\n\tconst usersWhoseRoomsCanBeSeenSelector = findInStore(\n\t\tstore,\n\t\tselfListSelectors,\n\t\tuserKey,\n\t)\n\texposeMutableFamily(usersInRoomsAtoms, usersWhoseRoomsCanBeSeenSelector)\n\tconst usersOfSocketsAtoms = getInternalRelationsFromStore(\n\t\tstore,\n\t\tusersOfSockets,\n\t)\n\texposeMutableFamily(usersOfSocketsAtoms, socketKeysAtom)\n\n\tconst enterRoom = provideEnterAndExit({ store, socket, roomSocket, userKey })\n\n\tconst userRoomSet = getFromStore(store, usersInRoomsAtoms, userKey)\n\tfor (const userRoomKey of userRoomSet) {\n\t\tenterRoom(userRoomKey)\n\t\tbreak\n\t}\n\n\troomSocket.on(\n\t\t`createRoom`,\n\t\tspawnRoom({ store, socket, userKey, resolveRoomScript }),\n\t)\n\troomSocket.on(`deleteRoom`, destroyRoom({ store, socket, userKey }))\n\tsocket.on(`disconnect`, () => {\n\t\tstore.logger.info(\n\t\t\t`šŸ“”`,\n\t\t\t`socket`,\n\t\t\tsocket.id ?? `[ID MISSING?!]`,\n\t\t\t`šŸ‘¤ ${userKey} disconnects`,\n\t\t)\n\t\teditRelationsInStore(store, usersOfSockets, (rel) => rel.delete(socketKey))\n\t\tsetIntoStore(store, userKeysAtom, (keys) => (keys.delete(userKey), keys))\n\t\tsetIntoStore(store, socketKeysAtom, (keys) => (keys.delete(socketKey), keys))\n\t})\n}\n\nconst roomKeySchema: StandardSchemaV1<Json.Array, [RoomKey]> = {\n\t\"~standard\": {\n\t\tversion: 1,\n\t\tvendor: `atom.io`,\n\t\tvalidate: ([maybeRoomKey]: Json.Array) => {\n\t\t\tif (typeof maybeRoomKey === `string`) {\n\t\t\t\tif (isRoomKey(maybeRoomKey)) {\n\t\t\t\t\treturn { value: [maybeRoomKey] }\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tissues: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmessage: `Room key must start with \"room::\"`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tissues: [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage: `Room key must be a string`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t},\n}\n\nfunction createRoomSocketGuard<RoomNames extends string>(\n\troomNames: RoomNames[],\n): SocketGuard<RoomSocketInterface<RoomNames>> {\n\treturn {\n\t\tcreateRoom: {\n\t\t\t\"~standard\": {\n\t\t\t\tversion: 1,\n\t\t\t\tvendor: `atom.io`,\n\t\t\t\tvalidate: ([maybeRoomName]) => {\n\t\t\t\t\tif (roomNames.includes(maybeRoomName as RoomNames)) {\n\t\t\t\t\t\treturn { value: [maybeRoomName as RoomNames] }\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tissues: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t`Room name must be one of the following:\\n - ` +\n\t\t\t\t\t\t\t\t\troomNames.join(`\\n - `),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tjoinRoom: roomKeySchema,\n\t\tdeleteRoom: roomKeySchema,\n\t\tleaveRoom: {\n\t\t\t\"~standard\": {\n\t\t\t\tversion: 1,\n\t\t\t\tvendor: `atom.io`,\n\t\t\t\tvalidate: () => ({ value: [] }),\n\t\t\t},\n\t\t},\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { getFromStore, IMPLICIT, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type StateProvider = ReturnType<typeof realtimeStateProvider>\nexport function realtimeStateProvider({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateProvider<J extends Json.Serializable>(\n\t\ttoken: AtomIO.WritableToken<J>,\n\t): () => void {\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `sub:${token.key}`, () => {\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(store, token))\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\tsubscribeToState(\n\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\temploySocket(socket, `unsub:${token.key}`, () => {\n\t\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\t\tstart()\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n","import type { WritableToken } from \"atom.io\"\nimport {\n\tfindInStore,\n\tgetFromStore,\n\tIMPLICIT,\n\toperateOnStore,\n\tOWN_OP,\n\tsetIntoStore,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket, mutexAtoms } from \"atom.io/realtime\"\n\nimport type { ServerConfig } from \".\"\n\nexport type StateReceiver = ReturnType<typeof realtimeStateReceiver>\nexport function realtimeStateReceiver({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateReceiver<S extends Json.Serializable, C extends S>(\n\t\tclientToken: WritableToken<C>,\n\t\tserverToken: WritableToken<S> = clientToken,\n\t): () => void {\n\t\tconst mutexAtom = findInStore(store, mutexAtoms, serverToken.key)\n\n\t\tconst subscriptions = new Set<() => void>()\n\t\tconst clearSubscriptions = () => {\n\t\t\tfor (const unsub of subscriptions) unsub()\n\t\t\tsubscriptions.clear()\n\t\t}\n\n\t\tconst permitPublish = () => {\n\t\t\tclearSubscriptions()\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `pub:${clientToken.key}`, (newValue) => {\n\t\t\t\t\tsetIntoStore(store, serverToken, newValue as C)\n\t\t\t\t}),\n\t\t\t)\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `unclaim:${clientToken.key}`, () => {\n\t\t\t\t\tsetIntoStore(store, mutexAtom, false)\n\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\tstart()\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tconst start = () => {\n\t\t\tsubscriptions.add(\n\t\t\t\temploySocket(socket, `claim:${clientToken.key}`, () => {\n\t\t\t\t\tif (getFromStore(store, mutexAtom)) {\n\t\t\t\t\t\tclearSubscriptions()\n\t\t\t\t\t\tsubscriptions.add(\n\t\t\t\t\t\t\tsubscribeToState(store, mutexAtom, socket.id!, () => {\n\t\t\t\t\t\t\t\tconst currentValue = getFromStore(store, mutexAtom)\n\t\t\t\t\t\t\t\tif (currentValue === false) {\n\t\t\t\t\t\t\t\t\toperateOnStore(OWN_OP, store, mutexAtom, true)\n\t\t\t\t\t\t\t\t\tpermitPublish()\n\t\t\t\t\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, true)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, false)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tsetIntoStore(store, mutexAtom, true)\n\t\t\t\t\tpermitPublish()\n\t\t\t\t\tsocket.emit(`claim-result:${clientToken.key}`, true)\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tstart()\n\n\t\treturn clearSubscriptions\n\t}\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.44.12",
3
+ "version": "0.44.13",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -60,9 +60,9 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@storybook/addon-docs": "10.0.8",
64
- "@storybook/addon-onboarding": "10.0.8",
65
- "@storybook/react-vite": "10.0.8",
63
+ "@storybook/addon-docs": "10.1.0",
64
+ "@storybook/addon-onboarding": "10.1.0",
65
+ "@storybook/react-vite": "10.1.0",
66
66
  "@testing-library/react": "16.3.0",
67
67
  "@types/eslint": "9.6.1",
68
68
  "@types/estree": "1.0.8",
@@ -72,9 +72,9 @@
72
72
  "@typescript-eslint/parser": "8.47.0",
73
73
  "@typescript-eslint/rule-tester": "8.47.0",
74
74
  "@typescript-eslint/utils": "8.47.0",
75
- "@typescript/native-preview": "7.0.0-dev.20251124.1",
76
- "@vitest/coverage-v8": "4.0.13",
77
- "@vitest/ui": "4.0.13",
75
+ "@typescript/native-preview": "7.0.0-dev.20251126.1",
76
+ "@vitest/coverage-v8": "4.0.14",
77
+ "@vitest/ui": "4.0.14",
78
78
  "arktype": "2.1.27",
79
79
  "concurrently": "9.2.1",
80
80
  "drizzle-kit": "0.31.7",
@@ -91,12 +91,12 @@
91
91
  "recoverage": "0.1.13",
92
92
  "socket.io": "4.8.1",
93
93
  "socket.io-client": "4.8.1",
94
- "storybook": "10.0.8",
94
+ "storybook": "10.1.0",
95
95
  "tmp": "0.2.5",
96
- "tsdown": "0.16.6",
96
+ "tsdown": "0.16.7",
97
97
  "vite": "7.2.4",
98
98
  "vite-tsconfig-paths": "5.1.4",
99
- "vitest": "4.0.13",
99
+ "vitest": "4.0.14",
100
100
  "break-check": "0.6.23",
101
101
  "takua": "0.1.1"
102
102
  },
@@ -5,7 +5,7 @@ import type {
5
5
  ReadonlyHeldSelectorToken,
6
6
  StateLifecycleEvent,
7
7
  } from "atom.io"
8
- import { PRETTY_TOKEN_TYPES } from "atom.io"
8
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
9
9
  import type { Canonical } from "atom.io/json"
10
10
  import { stringifyJson } from "atom.io/json"
11
11
 
@@ -37,7 +37,7 @@ export function createReadonlyHeldSelectorFamily<
37
37
  `ā—`,
38
38
  type,
39
39
  familyKey,
40
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
40
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
41
41
  )
42
42
  }
43
43
 
@@ -8,7 +8,7 @@ import type {
8
8
  ReadonlyPureSelectorToken,
9
9
  StateLifecycleEvent,
10
10
  } from "atom.io"
11
- import { PRETTY_TOKEN_TYPES } from "atom.io"
11
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
12
12
  import type { Canonical } from "atom.io/json"
13
13
  import { stringifyJson } from "atom.io/json"
14
14
 
@@ -40,7 +40,7 @@ export function createReadonlyPureSelectorFamily<T, K extends Canonical, E>(
40
40
  `ā—`,
41
41
  type,
42
42
  familyKey,
43
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
43
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
44
44
  )
45
45
  }
46
46
 
@@ -6,7 +6,7 @@ import type {
6
6
  RegularAtomToken,
7
7
  StateLifecycleEvent,
8
8
  } from "atom.io"
9
- import { PRETTY_TOKEN_TYPES } from "atom.io"
9
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
10
10
  import type { Canonical } from "atom.io/json"
11
11
  import { stringifyJson } from "atom.io/json"
12
12
 
@@ -33,7 +33,7 @@ export function createRegularAtomFamily<T, K extends Canonical, E>(
33
33
  `ā—`,
34
34
  `atom_family`,
35
35
  options.key,
36
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
36
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
37
37
  )
38
38
  }
39
39
 
@@ -5,7 +5,7 @@ import type {
5
5
  WritableHeldSelectorFamilyToken,
6
6
  WritableHeldSelectorToken,
7
7
  } from "atom.io"
8
- import { PRETTY_TOKEN_TYPES } from "atom.io"
8
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
9
9
  import type { Canonical } from "atom.io/json"
10
10
  import { stringifyJson } from "atom.io/json"
11
11
 
@@ -38,7 +38,7 @@ export function createWritableHeldSelectorFamily<
38
38
  `ā—`,
39
39
  type,
40
40
  familyKey,
41
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
41
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
42
42
  )
43
43
  }
44
44
  const subject = new Subject<
@@ -8,7 +8,7 @@ import type {
8
8
  WritablePureSelectorOptions,
9
9
  WritablePureSelectorToken,
10
10
  } from "atom.io"
11
- import { PRETTY_TOKEN_TYPES } from "atom.io"
11
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
12
12
  import type { Canonical } from "atom.io/json"
13
13
  import { stringifyJson } from "atom.io/json"
14
14
 
@@ -41,7 +41,7 @@ export function createWritablePureSelectorFamily<T, K extends Canonical, E>(
41
41
  `ā—`,
42
42
  type,
43
43
  familyKey,
44
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
44
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
45
45
  )
46
46
  }
47
47
  const subject = new Subject<
@@ -6,7 +6,7 @@ import type {
6
6
  MutableAtomToken,
7
7
  StateLifecycleEvent,
8
8
  } from "atom.io"
9
- import { PRETTY_TOKEN_TYPES } from "atom.io"
9
+ import { PRETTY_ENTITY_NAMES } from "atom.io"
10
10
  import type { Canonical } from "atom.io/json"
11
11
  import { stringifyJson } from "atom.io/json"
12
12
 
@@ -39,7 +39,7 @@ export function createMutableAtomFamily<
39
39
  `ā—`,
40
40
  `mutable_atom_family`,
41
41
  options.key,
42
- `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
42
+ `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
43
43
  )
44
44
  }
45
45
 
@@ -1,4 +1,4 @@
1
- import { type AtomIOToken, PRETTY_TOKEN_TYPES } from "atom.io"
1
+ import { type AtomIOToken, PRETTY_ENTITY_NAMES } from "atom.io"
2
2
  import { stringifyJson } from "atom.io/json"
3
3
 
4
4
  import type { Store } from "./store"
@@ -6,7 +6,7 @@ import type { Store } from "./store"
6
6
  export class NotFoundError extends Error {
7
7
  public constructor(token: AtomIOToken, store: Store) {
8
8
  super(
9
- `${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${
9
+ `${PRETTY_ENTITY_NAMES[token.type]} ${stringifyJson(token.key)} not found in store "${
10
10
  store.config.name
11
11
  }".`,
12
12
  )
@@ -50,6 +50,8 @@ const LOGGER_ICON_DICTIONARY = {
50
50
  "šŸ“¢": `Notify subscribers`,
51
51
 
52
52
  // Realtime
53
+ "šŸ›°ļø": `Server socket`,
54
+ "šŸ“”": `Client socket`,
53
55
  "šŸš€": `Performance measure`,
54
56
  "āœ…": `Realtime transaction success`,
55
57
  "šŸ”„": `Realtime transaction synchronized`,
@@ -64,7 +66,7 @@ const LOGGER_ICON_DICTIONARY = {
64
66
  "šŸ‘": `Realtime acknowledgment`,
65
67
  } as const
66
68
  export type LoggerIcon = keyof typeof LOGGER_ICON_DICTIONARY
67
- export type TokenDenomination =
69
+ export type EntityDenomination =
68
70
  | `atom_family`
69
71
  | `atom`
70
72
  | `continuity`
@@ -75,6 +77,7 @@ export type TokenDenomination =
75
77
  | `readonly_held_selector`
76
78
  | `readonly_pure_selector_family`
77
79
  | `readonly_pure_selector`
80
+ | `socket`
78
81
  | `state`
79
82
  | `timeline`
80
83
  | `transaction`
@@ -84,7 +87,7 @@ export type TokenDenomination =
84
87
  | `writable_pure_selector_family`
85
88
  | `writable_pure_selector`
86
89
 
87
- export const PRETTY_TOKEN_TYPES: Record<TokenDenomination, string> = {
90
+ export const PRETTY_ENTITY_NAMES: Record<EntityDenomination, string> = {
88
91
  atom_family: `atom family`,
89
92
  atom: `atom`,
90
93
  continuity: `continuity`,
@@ -95,6 +98,7 @@ export const PRETTY_TOKEN_TYPES: Record<TokenDenomination, string> = {
95
98
  readonly_held_selector: `selector [h]`,
96
99
  readonly_pure_selector_family: `selector family`,
97
100
  readonly_pure_selector: `selector`,
101
+ socket: `socket`,
98
102
  state: `state`,
99
103
  timeline: `timeline`,
100
104
  transaction: `transaction`,
@@ -110,7 +114,7 @@ export type LogLevel = (typeof LOG_LEVELS)[number]
110
114
 
111
115
  export type LogFn = (
112
116
  icon: LoggerIcon,
113
- denomination: TokenDenomination,
117
+ denomination: EntityDenomination,
114
118
  tokenKey: string,
115
119
  message: string,
116
120
  ...rest: unknown[]
@@ -126,7 +130,7 @@ export const simpleLog =
126
130
  (icon, denomination, tokenKey, message, ...rest) => {
127
131
  /* eslint-disable-next-line no-console */
128
132
  console[logLevel](
129
- `${icon} ${PRETTY_TOKEN_TYPES[denomination]} \`${tokenKey}\` ${message}`,
133
+ `${icon} ${PRETTY_ENTITY_NAMES[denomination]} \`${tokenKey}\` ${message}`,
130
134
  ...rest,
131
135
  )
132
136
  }