atom.io 0.18.1 → 0.18.2

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 (45) hide show
  1. package/dist/chunk-3J2EGSBE.js +31 -0
  2. package/dist/chunk-3J2EGSBE.js.map +1 -0
  3. package/dist/{chunk-JDUNWJFB.js → chunk-A4ZCNKWQ.js} +2 -2
  4. package/dist/chunk-A4ZCNKWQ.js.map +1 -0
  5. package/internal/dist/index.cjs +46 -100
  6. package/internal/dist/index.cjs.map +1 -1
  7. package/internal/dist/index.d.ts +23 -23
  8. package/internal/dist/index.js +46 -100
  9. package/internal/dist/index.js.map +1 -1
  10. package/internal/src/families/create-regular-atom-family.ts +4 -4
  11. package/internal/src/get-state/get-from-store.ts +2 -5
  12. package/internal/src/mutable/create-mutable-atom-family.ts +4 -4
  13. package/internal/src/selector/register-selector.ts +3 -14
  14. package/internal/src/set-state/set-into-store.ts +2 -5
  15. package/internal/src/store/withdraw-new-family-member.ts +38 -28
  16. package/internal/src/store/withdraw.ts +20 -23
  17. package/internal/src/subscribe/subscribe-to-state.ts +2 -3
  18. package/internal/src/subscribe/subscribe-to-timeline.ts +0 -5
  19. package/internal/src/subscribe/subscribe-to-transaction.ts +0 -5
  20. package/internal/src/timeline/add-atom-to-timeline.ts +6 -15
  21. package/internal/src/timeline/create-timeline.ts +0 -27
  22. package/package.json +6 -5
  23. package/react/dist/index.cjs +2 -3
  24. package/react/dist/index.cjs.map +1 -1
  25. package/react/dist/index.js +2 -3
  26. package/react/dist/index.js.map +1 -1
  27. package/react/src/use-tl.ts +2 -2
  28. package/react-devtools/dist/index.cjs +1 -1
  29. package/react-devtools/dist/index.cjs.map +1 -1
  30. package/react-devtools/dist/index.js +1 -1
  31. package/realtime-client/dist/index.cjs +1 -1
  32. package/realtime-client/dist/index.cjs.map +1 -1
  33. package/realtime-client/dist/index.js +13 -37
  34. package/realtime-client/dist/index.js.map +1 -1
  35. package/realtime-server/dist/index.cjs +3 -3
  36. package/realtime-server/dist/index.cjs.map +1 -1
  37. package/realtime-server/dist/index.js +3 -3
  38. package/realtime-server/dist/index.js.map +1 -1
  39. package/realtime-server/src/ipc-sockets/parent-socket.ts +4 -3
  40. package/realtime-testing/dist/index.cjs +43 -5
  41. package/realtime-testing/dist/index.cjs.map +1 -1
  42. package/realtime-testing/dist/index.js +4 -5
  43. package/realtime-testing/dist/index.js.map +1 -1
  44. package/realtime-testing/src/setup-realtime-test.tsx +3 -5
  45. package/dist/chunk-JDUNWJFB.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ipc-sockets/child-socket.ts","../src/ipc-sockets/custom-socket.ts","../src/ipc-sockets/parent-socket.ts","../src/realtime-continuity-synchronizer.ts","../src/realtime-server-stores/realtime-continuity-store.ts","../src/realtime-server-stores/server-room-external-actions.ts","../src/realtime-server-stores/server-room-external-store.ts","../src/realtime-server-stores/server-sync-store.ts","../src/realtime-server-stores/server-user-store.ts","../src/realtime-state-provider.ts","../src/realtime-state-synchronizer.ts","../src/realtime-family-provider.ts","../src/realtime-mutable-provider.ts","../src/realtime-mutable-family-provider.ts","../src/realtime-state-receiver.ts","../src/realtime-action-receiver.ts"],"names":["process","parsedEvent","parsedLog","parseJson","IMPLICIT","getJsonToken","selectorFamily","atomFamily","SetRTX","unsubscribeFunctions","atom","transaction","getFromStore","subscribeToState","findInStore","stringifyJson","getUpdateToken","actUponStore"],"mappings":"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","sourcesContent":["import type { ChildProcessWithoutNullStreams } from \"child_process\"\n\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\n\nimport type { EventBuffer, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\nexport class ChildSocket<\n\tI extends Events,\n\tO extends Events & {\n\t\t/* eslint-disable quotes */\n\t\t\"setup-relay\": [string]\n\t\t/* eslint-enable quotes */\n\t},\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\tprotected handleLog(arg: Json.Serializable): void {\n\t\tif (Array.isArray(arg)) {\n\t\t\tconst [level, ...rest] = arg\n\t\t\tswitch (level) {\n\t\t\t\tcase `i`:\n\t\t\t\t\tthis.logger.info(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `w`:\n\t\t\t\t\tthis.logger.warn(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `e`:\n\t\t\t\t\tthis.logger.error(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tpublic process: ChildProcessWithoutNullStreams,\n\t\tpublic key: string,\n\t\tpublic logger: {\n\t\t\tinfo: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t\twarn: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t\terror: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t} = console,\n\t) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args]) + `\\x03`\n\t\t\tconst errorHandler = (err) => {\n\t\t\t\tif (err.code === `EPIPE`) {\n\t\t\t\t\tconsole.error(`EPIPE error during write`, this.process.stdin)\n\t\t\t\t}\n\t\t\t\tthis.process.stdin.removeListener(`error`, errorHandler)\n\t\t\t}\n\n\t\t\tthis.process.stdin.once(`error`, errorHandler)\n\t\t\tthis.process.stdin.write(stringifiedEvent)\n\n\t\t\treturn this\n\t\t})\n\t\tthis.process = process\n\t\tthis.process.stdout.on(\n\t\t\t`data`,\n\t\t\t<Event extends keyof I>(buffer: EventBuffer<string, I[Event]>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\n\t\t\t\tif (chunk === `✨`) {\n\t\t\t\t\t// console.log(chunk)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.unprocessedEvents.push(...chunk.split(`\\x03`))\n\t\t\t\t// console.log(`🤓`, chunk.length)\n\t\t\t\t// console.log(`🤓`, this.unprocessedEvents.length)\n\t\t\t\t// console.log(`🤓`, ...this.unprocessedEvents.map((x) => x.length))\n\t\t\t\tconst newInput = this.unprocessedEvents.shift()\n\t\t\t\tthis.incompleteData += newInput || ``\n\t\t\t\ttry {\n\t\t\t\t\tif (this.incompleteData.startsWith(`error`)) {\n\t\t\t\t\t\tconsole.log(`❗`, this.incompleteData)\n\t\t\t\t\t}\n\t\t\t\t\tconst parsedEvent = parseJson(this.incompleteData)\n\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\twhile (this.unprocessedEvents.length > 0) {\n\t\t\t\t\t\tconst event = this.unprocessedEvents.shift()\n\t\t\t\t\t\tif (event) {\n\t\t\t\t\t\t\tif (this.unprocessedEvents.length === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = event\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst parsedEvent = parseJson(event)\n\t\t\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.warn(`⚠️----------------⚠️`)\n\t\t\t\t\tconsole.warn(this.incompleteData)\n\t\t\t\t\tconsole.warn(`⚠️----------------⚠️`)\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tthis.process.stderr.on(`data`, (buf) => {\n\t\t\tconst chunk = buf.toString()\n\t\t\tthis.unprocessedLogs.push(...chunk.split(`\\x03`))\n\t\t\t// console.log(`🤫`, chunk.length)\n\t\t\t// console.log(`🤫`, this.unprocessedLogs.length)\n\t\t\t// console.log(`🤫`, ...this.unprocessedLogs.map((x) => x.length))\n\t\t\tconst newInput = this.unprocessedLogs.shift()\n\t\t\tthis.incompleteLog += newInput || ``\n\t\t\ttry {\n\t\t\t\tconst parsedLog = parseJson(this.incompleteLog)\n\t\t\t\t// console.log(`🤫`, parsedLog)\n\t\t\t\tthis.handleLog(parsedLog)\n\t\t\t\twhile (this.unprocessedLogs.length > 0) {\n\t\t\t\t\tthis.incompleteLog = this.unprocessedLogs.shift() ?? ``\n\t\t\t\t\tif (this.incompleteLog) {\n\t\t\t\t\t\tconst parsedLog = parseJson(this.incompleteLog)\n\t\t\t\t\t\tthis.handleLog(parsedLog)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`❌❌❌`)\n\t\t\t\tconsole.error(this.incompleteLog)\n\t\t\t\tconsole.error(error)\n\t\t\t\tconsole.error(`❌❌❌️`)\n\t\t\t}\n\t\t})\n\t\tif (process.pid) {\n\t\t\tthis.id = process.pid.toString()\n\t\t}\n\t}\n}\n","import type { Json, Stringified } from \"atom.io/json\"\n\nimport type { Socket } from \"..\"\n\nexport type Events = Json.Object<string, Json.Serializable[]>\n\nexport type StringifiedEvent<\n\tKey extends string,\n\tParams extends Json.Serializable[],\n> = Stringified<[Key, ...Params]>\n\nexport interface EventBuffer<\n\tKey extends string,\n\tParams extends Json.Serializable[],\n> extends Buffer {\n\ttoString(): StringifiedEvent<Key, Params>\n}\n\nexport class CustomSocket<I extends Events, O extends Events> implements Socket {\n\tprotected listeners: Map<keyof I, Set<(...args: Json.Array) => void>>\n\tprotected globalListeners: Set<(event: string, ...args: Json.Array) => void>\n\tprotected handleEvent<Event extends keyof I>(\n\t\tevent: string,\n\t\t...args: I[Event]\n\t): void {\n\t\tfor (const listener of this.globalListeners) {\n\t\t\tlistener(event, ...args)\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(...args)\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic id = `no_id_retrieved`\n\n\tpublic constructor(\n\t\tpublic emit: <Event extends keyof O>(\n\t\t\tevent: Event,\n\t\t\t...args: O[Event]\n\t\t) => CustomSocket<I, O>,\n\t) {\n\t\tthis.listeners = new Map()\n\t\tthis.globalListeners = new Set()\n\t}\n\n\tpublic on<Event extends keyof I>(\n\t\tevent: Event,\n\t\tlistener: (...args: I[Event]) => void,\n\t): CustomSocket<I, O> {\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(\n\t\tlistener: (event: string, ...args: Json.Array) => void,\n\t): CustomSocket<I, O> {\n\t\tthis.globalListeners.add(listener)\n\t\treturn this\n\t}\n\n\tpublic off<Event extends keyof I>(\n\t\tevent: Event,\n\t\tlistener?: (...args: I[Event]) => void,\n\t): CustomSocket<I, O> {\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(\n\t\tlistener: (event: string, ...args: Json.Array) => void,\n\t): CustomSocket<I, O> {\n\t\tthis.globalListeners.delete(listener)\n\t\treturn this\n\t}\n}\n","import { IMPLICIT, Subject } from \"atom.io/internal\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\n\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\nimport { CustomSocket } from \"./custom-socket\"\nimport type { EventBuffer, Events } from \"./custom-socket\"\n\nexport class SubjectSocket<\n\tI extends Events,\n\tO extends Events,\n> extends CustomSocket<I, O> {\n\tpublic in: Subject<[string, ...Json.Serializable[]]>\n\tpublic out: Subject<[string, ...Json.Serializable[]]>\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 as [string, ...I[keyof I]]))\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 class ParentSocket<\n\tI extends Events & {\n\t\t[id in string as `user:${id}`]: [string, ...Json.Serializable[]]\n\t} & {\n\t\t/* eslint-disable quotes */\n\t\t\"user-joins\": [string]\n\t\t\"user-leaves\": [string]\n\t\t/* eslint-enable quotes */\n\t},\n\tO extends Events & {\n\t\t[id in string as `relay:${id}`]: [string, ...Json.Serializable[]]\n\t},\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) => (() => void) | void)[]\n\tprotected process: NodeJS.Process\n\n\tpublic id = `#####`\n\n\tprotected log(...args: any[]): void {\n\t\tthis.process.stderr.write(\n\t\t\tstringifyJson(\n\t\t\t\targs.map((arg) =>\n\t\t\t\t\targ instanceof SetRTX\n\t\t\t\t\t\t? `{ ${arg.toJSON().members.join(` | `)} }`\n\t\t\t\t\t\t: arg,\n\t\t\t\t),\n\t\t\t) + `\\x03`,\n\t\t)\n\t}\n\tpublic logger = {\n\t\tinfo: (...args: any[]): void => this.log(`i`, ...args),\n\t\twarn: (...args: any[]): void => this.log(`w`, ...args),\n\t\terror: (...args: any[]): void => this.log(`e`, ...args),\n\t}\n\n\tpublic constructor() {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args])\n\t\t\tthis.process.stdout.write(stringifiedEvent + `\\x03`)\n\t\t\treturn this\n\t\t})\n\t\tthis.process = process\n\t\tthis.process.stdin.resume()\n\t\tthis.relays = new Map()\n\t\tthis.relayServices = []\n\n\t\tthis.process.stdin.on(\n\t\t\t`data`,\n\t\t\t<Event extends keyof I>(buffer: EventBuffer<string, I[Event]>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\t\t\t\tthis.unprocessedEvents.push(...chunk.split(`\\x03`))\n\t\t\t\tconst newInput = this.unprocessedEvents.shift()\n\t\t\t\tthis.incompleteData += newInput || ``\n\n\t\t\t\ttry {\n\t\t\t\t\tconst parsedEvent = parseJson(this.incompleteData)\n\t\t\t\t\tthis.logger.info(`🎰`, `received`, parsedEvent)\n\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\twhile (this.unprocessedEvents.length > 0) {\n\t\t\t\t\t\tconst event = this.unprocessedEvents.shift()\n\t\t\t\t\t\tif (event) {\n\t\t\t\t\t\t\tif (this.unprocessedEvents.length === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = event\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst parsedEvent = parseJson(event)\n\t\t\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tthis.logger.error(`❗`, thrown.message, thrown.cause, thrown.stack)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\n\t\tthis.on(`exit`, () => {\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`exit`, () => {\n\t\t\tthis.logger.info(`🔥`, this.id, `exited`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`end`, () => {\n\t\t\tthis.logger.info(`🔥`, this.id, `ended`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`SIGTERM`, () => {\n\t\t\tthis.logger.error(`🔥`, this.id, `terminated`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`SIGINT`, () => {\n\t\t\tthis.logger.error(`🔥`, this.id, `interrupted`)\n\t\t\tprocess.exit(0)\n\t\t})\n\n\t\tif (process.pid) {\n\t\t\tthis.id = process.pid?.toString()\n\t\t}\n\n\t\tthis.on(`user-joins`, (username) => {\n\t\t\tthis.logger.info(`👤`, `user`, username, `joined`)\n\t\t\tconst relay = new SubjectSocket(`user:${username}`)\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 attachServices of this.relayServices) {\n\t\t\t\tconst cleanup = attachServices(relay)\n\t\t\t\tif (cleanup) {\n\t\t\t\t\trelay.disposalFunctions.push(cleanup)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.on(`user:${username}`, (...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, ...O[keyof O]]))\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\tprocess.stdout.write(`✨`)\n\t}\n\n\tpublic relay(\n\t\tattachServices: (socket: SubjectSocket<any, any>) => (() => 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\tIMPLICIT,\n\tactUponStore,\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tisRootStore,\n\tsubscribeToState,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json, JsonIO } from \"atom.io/json\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\n\nimport type { ServerConfig, Socket } from \".\"\nimport { socketAtoms, usersOfSockets } from \".\"\n\nimport {\n\tredactTransactionUpdateContent,\n\tuserUnacknowledgedQueues,\n} from \"./realtime-server-stores\"\n\nexport type RealtimeContinuitySynchronizer = ReturnType<\n\ttypeof realtimeContinuitySynchronizer\n>\nexport function realtimeContinuitySynchronizer({\n\tsocket: initialSocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function synchronizer(continuity: ContinuityToken): () => void {\n\t\tlet socket: Socket | null = initialSocket\n\n\t\tconst continuityKey = continuity.key\n\t\tconst userKeyState = findInStore(\n\t\t\tusersOfSockets.states.userKeyOfSocket,\n\t\t\tsocket.id,\n\t\t\tstore,\n\t\t)\n\t\tconst userKey = getFromStore(userKeyState, store)\n\t\tif (!userKey) {\n\t\t\tstore.logger.error(\n\t\t\t\t`❌`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`Tried to create a synchronizer for a socket (${socket.id}) that is not connected to a user.`,\n\t\t\t)\n\t\t\treturn () => {}\n\t\t}\n\t\tconst socketKeyState = findInStore(\n\t\t\tusersOfSockets.states.socketKeyOfUser,\n\t\t\tuserKey,\n\t\t\tstore,\n\t\t)\n\t\tsubscribeToState(\n\t\t\tsocketKeyState,\n\t\t\t({ newValue: newSocketKey }) => {\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`seeing ${userKey} on new socket ${newSocketKey}`,\n\t\t\t\t)\n\t\t\t\tif (newSocketKey === null) {\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`Tried to create a synchronizer for a user (${userKey}) that is not connected to a socket.`,\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst newSocketState = findInStore(socketAtoms, newSocketKey, store)\n\t\t\t\tconst newSocket = getFromStore(newSocketState, store)\n\t\t\t\tsocket = newSocket\n\t\t\t},\n\t\t\t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\tstore,\n\t\t)\n\n\t\tconst userUnacknowledgedQueue = findInStore(\n\t\t\tuserUnacknowledgedQueues,\n\t\t\tuserKey,\n\t\t\tstore,\n\t\t)\n\t\tconst userUnacknowledgedUpdates = getFromStore(\n\t\t\tuserUnacknowledgedQueue,\n\t\t\tstore,\n\t\t)\n\t\tconst unsubscribeFunctions: (() => void)[] = []\n\n\t\tconst revealPerspectives = (): (() => void) => {\n\t\t\tconst unsubscribeFunctions: (() => void)[] = []\n\t\t\tfor (const perspective of continuity.perspectives) {\n\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\tconst userViewState = findInStore(viewAtoms, userKey, store)\n\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\tuserViewState,\n\t\t\t\t\t({ oldValue, newValue }) => {\n\t\t\t\t\t\tconst oldKeys = oldValue.map((token) => token.key)\n\t\t\t\t\t\tconst newKeys = newValue.map((token) => token.key)\n\t\t\t\t\t\tconst concealed = oldValue.filter(\n\t\t\t\t\t\t\t(token) => !newKeys.includes(token.key),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst revealed = newValue\n\t\t\t\t\t\t\t.filter((token) => !oldKeys.includes(token.key))\n\t\t\t\t\t\t\t.flatMap((token) => {\n\t\t\t\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? getJsonToken(token) : token\n\t\t\t\t\t\t\t\tconst resource = getFromStore(resourceToken, store)\n\t\t\t\t\t\t\t\treturn [resourceToken, resource]\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t\t`👁`,\n\t\t\t\t\t\t\t`atom`,\n\t\t\t\t\t\t\tperspective.resourceAtoms.key,\n\t\t\t\t\t\t\t`${userKey} has a new perspective`,\n\t\t\t\t\t\t\t{ oldKeys, newKeys, revealed, concealed },\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (revealed.length > 0) {\n\t\t\t\t\t\t\tsocket?.emit(`reveal:${continuityKey}`, revealed)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (concealed.length > 0) {\n\t\t\t\t\t\t\tsocket?.emit(`conceal:${continuityKey}`, concealed)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t`sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,\n\t\t\t\t\tstore,\n\t\t\t\t)\n\t\t\t\tunsubscribeFunctions.push(unsubscribe)\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t\t}\n\t\t}\n\t\tconst unsubscribeFromPerspectives = revealPerspectives()\n\n\t\tconst sendInitialPayload = () => {\n\t\t\tconst initialPayload: Json.Serializable[] = []\n\t\t\tfor (const atom of continuity.globals) {\n\t\t\t\tconst resourceToken =\n\t\t\t\t\tatom.type === `mutable_atom` ? getJsonToken(atom) : atom\n\t\t\t\tinitialPayload.push(resourceToken, getFromStore(atom, store))\n\t\t\t}\n\t\t\tfor (const perspective of continuity.perspectives) {\n\t\t\t\tconst { viewAtoms, resourceAtoms } = perspective\n\t\t\t\tconst userViewState = findInStore(viewAtoms, userKey, store)\n\t\t\t\tconst userView = getFromStore(userViewState, store)\n\t\t\t\tstore.logger.info(`👁`, `atom`, resourceAtoms.key, `${userKey} can see`, {\n\t\t\t\t\tviewAtoms,\n\t\t\t\t\tresourceAtoms,\n\t\t\t\t\tuserView,\n\t\t\t\t})\n\t\t\t\tfor (const visibleToken of userView) {\n\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\tvisibleToken.type === `mutable_atom`\n\t\t\t\t\t\t\t? getJsonToken(visibleToken)\n\t\t\t\t\t\t\t: visibleToken\n\t\t\t\t\tconst resource = getFromStore(resourceToken, store)\n\n\t\t\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst epoch = isRootStore(store)\n\t\t\t\t? store.transactionMeta.epoch.get(continuityKey) ?? null\n\t\t\t\t: null\n\n\t\t\tsocket?.emit(`continuity-init:${continuityKey}`, epoch, initialPayload)\n\n\t\t\tfor (const transaction of continuity.actions) {\n\t\t\t\tconst unsubscribeFromTransaction = subscribeToTransaction(\n\t\t\t\t\ttransaction,\n\t\t\t\t\t(update) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst visibleKeys = continuity.globals\n\t\t\t\t\t\t\t\t.map((atom) => atom.key)\n\t\t\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\t\t\tcontinuity.perspectives.flatMap((perspective) => {\n\t\t\t\t\t\t\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\t\t\t\t\t\t\tconst userPerspectiveTokenState = findInStore(\n\t\t\t\t\t\t\t\t\t\t\tviewAtoms,\n\t\t\t\t\t\t\t\t\t\t\tuserKey,\n\t\t\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tconst visibleTokens = getFromStore(\n\t\t\t\t\t\t\t\t\t\t\tuserPerspectiveTokenState,\n\t\t\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\treturn visibleTokens.map((token) => {\n\t\t\t\t\t\t\t\t\t\t\tconst key =\n\t\t\t\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom`\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `*` + token.key\n\t\t\t\t\t\t\t\t\t\t\t\t\t: token.key\n\t\t\t\t\t\t\t\t\t\t\treturn key\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst redactedUpdates = redactTransactionUpdateContent(\n\t\t\t\t\t\t\t\tvisibleKeys,\n\t\t\t\t\t\t\t\tupdate.updates,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst redactedUpdate = {\n\t\t\t\t\t\t\t\t...update,\n\t\t\t\t\t\t\t\tupdates: redactedUpdates,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// setIntoStore(\n\t\t\t\t\t\t\t// \tuserUnacknowledgedQueue,\n\t\t\t\t\t\t\t// \t(updates) => {\n\t\t\t\t\t\t\t// \t\tif (redactedUpdate) {\n\t\t\t\t\t\t\t// \t\t\tupdates.push(redactedUpdate)\n\t\t\t\t\t\t\t// \t\t\tupdates.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\t\t// \t\t}\n\t\t\t\t\t\t\t// \t\treturn updates\n\t\t\t\t\t\t\t// \t},\n\t\t\t\t\t\t\t// \tstore,\n\t\t\t\t\t\t\t// )\n\n\t\t\t\t\t\t\tsocket?.emit(\n\t\t\t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\t\t\t\t\tredactedUpdate as Json.Serializable,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} catch (thrown) {\n\t\t\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t\t\t`❌`,\n\t\t\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t\t\t`failed to send update from transaction ${transaction.key} to ${userKey}`,\n\t\t\t\t\t\t\t\t\tthrown.message,\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`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\t\t\tstore,\n\t\t\t\t)\n\t\t\t\tunsubscribeFunctions.push(unsubscribeFromTransaction)\n\t\t\t}\n\t\t}\n\t\tsocket.off(`get:${continuityKey}`, sendInitialPayload)\n\t\tsocket.on(`get:${continuityKey}`, sendInitialPayload)\n\n\t\tconst fillTransactionRequest = (\n\t\t\tupdate: Pick<AtomIO.TransactionUpdate<JsonIO>, `id` | `key` | `params`>,\n\t\t) => {\n\t\t\tstore.logger.info(`🛎️`, `continuity`, continuityKey, `received`, update)\n\t\t\tconst transactionKey = update.key\n\t\t\tconst updateId = update.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\t{ type: `transaction`, key: transactionKey },\n\t\t\t\t\tupdateId,\n\t\t\t\t\tstore,\n\t\t\t\t)(...update.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} 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\tmetric.duration,\n\t\t\t)\n\n\t\t\tconst valuesOfCardsViewKey = `valuesOfCardsView(\"${userKey}\")`\n\t\t\tconst rootsOfCardValueView =\n\t\t\t\tstore.selectorAtoms.getRelatedKeys(valuesOfCardsViewKey)\n\t\t\tconst myCardValueView = store.valueMap.get(valuesOfCardsViewKey)\n\n\t\t\tstore.logger.info(\n\t\t\t\t`👁`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`seeing ${userKey} card values`,\n\t\t\t\t{\n\t\t\t\t\tvaluesOfCardsViewKey,\n\t\t\t\t\trootsOfCardValueView,\n\t\t\t\t\tmyCardValueView,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tsocket.off(`tx-run:${continuityKey}`, fillTransactionRequest)\n\t\tsocket.on(`tx-run:${continuityKey}`, fillTransactionRequest)\n\n\t\t// let i = 0\n\t\t// let n = 1\n\t\t// let retryTimeout: NodeJS.Timeout | undefined\n\t\t// const trackClientAcknowledgement = (epoch: number) => {\n\t\t// \tstore.logger.info(\n\t\t// \t\t`👍`,\n\t\t// \t\t`continuity`,\n\t\t// \t\tcontinuityKey,\n\t\t// \t\t`${userKey} acknowledged epoch ${epoch}`,\n\t\t// \t)\n\t\t// \tconst isUnacknowledged = userUnacknowledgedUpdates[0]?.epoch === epoch\n\t\t// \tif (isUnacknowledged) {\n\t\t// \t\tsetIntoStore(\n\t\t// \t\t\tuserUnacknowledgedQueue,\n\t\t// \t\t\t(updates) => {\n\t\t// \t\t\t\tupdates.shift()\n\t\t// \t\t\t\treturn updates\n\t\t// \t\t\t},\n\t\t// \t\t\tstore,\n\t\t// \t\t)\n\t\t// \t}\n\t\t// }\n\t\t// subscribeToState(\n\t\t// \tuserUnacknowledgedQueue,\n\t\t// \t({ newValue }) => {\n\t\t// \t\tif (newValue.length === 0) {\n\t\t// \t\t\tclearInterval(retryTimeout)\n\t\t// \t\t\tsocket?.off(`ack:${continuityKey}`, trackClientAcknowledgement)\n\t\t// \t\t\tretryTimeout = undefined\n\t\t// \t\t}\n\t\t// \t\tif (newValue.length > 0) {\n\t\t// \t\t\tif (retryTimeout) {\n\t\t// \t\t\t\treturn\n\t\t// \t\t\t}\n\n\t\t// \t\t\tsocket?.on(`ack:${continuityKey}`, trackClientAcknowledgement)\n\n\t\t// \t\t\tretryTimeout = setInterval(() => {\n\t\t// \t\t\t\ti++\n\t\t// \t\t\t\tif (i === n) {\n\t\t// \t\t\t\t\tn += i\n\t\t// \t\t\t\t\tconst toEmit = newValue[0]\n\t\t// \t\t\t\t\tif (!toEmit) return\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`${store.config.name} retrying ${userKey}`,\n\t\t// \t\t\t\t\t\tsocket?.id,\n\t\t// \t\t\t\t\t\tnewValue,\n\t\t// \t\t\t\t\t)\n\t\t// \t\t\t\t\tsocket?.emit(\n\t\t// \t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t// \t\t\t\t\t\ttoEmit as Json.Serializable,\n\t\t// \t\t\t\t\t)\n\t\t// \t\t\t\t}\n\t\t// \t\t\t}, 250)\n\t\t// \t\t}\n\t\t// \t},\n\t\t// \t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t// \tstore,\n\t\t// )\n\n\t\treturn () => {\n\t\t\t// clearInterval(retryTimeout)\n\t\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t\t// socket?.off(`ack:${continuityKey}`, trackClientAcknowledgement)\n\t\t\tunsubscribeFromPerspectives()\n\t\t\tsocket?.off(`get:${continuityKey}`, sendInitialPayload)\n\t\t\tsocket?.off(`tx-run:${continuityKey}`, fillTransactionRequest)\n\t\t}\n\t}\n}\n","import { selectorFamily } from \"atom.io\"\nimport type { TransactionUpdate } from \"atom.io\"\nimport { IMPLICIT, getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { JsonIO } from \"atom.io/json\"\nimport { SyncGroup } from \"atom.io/realtime\"\n// import { completeUpdateAtoms } from \"atom.io/realtime-server\"\n\nconst redactorAtoms = selectorFamily<\n\t(update: TransactionUpdate<any>) => TransactionUpdate<any>,\n\t{ userId: string; syncGroupKey: string }\n>({\n\tkey: `perspectiveRedactor`,\n\tget:\n\t\t({ userId, syncGroupKey }) =>\n\t\t({ get, find }) => {\n\t\t\tconst syncGroup = SyncGroup.existing.get(syncGroupKey)\n\t\t\tif (!syncGroup) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tried to create a synchronizer for a sync group that does not exist.`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst userPerspectiveTokens = syncGroup.perspectives.flatMap(\n\t\t\t\t({ viewAtoms }) => {\n\t\t\t\t\tconst userPerspectiveToken = find(viewAtoms, userId)\n\t\t\t\t\tconst userPerspective = get(userPerspectiveToken)\n\t\t\t\t\tconst visibleTokens = [...userPerspective].map((token) => {\n\t\t\t\t\t\treturn token.type === `mutable_atom`\n\t\t\t\t\t\t\t? getUpdateToken(token).key\n\t\t\t\t\t\t\t: token.key\n\t\t\t\t\t})\n\t\t\t\t\tIMPLICIT.STORE.logger.info(\n\t\t\t\t\t\t`🔭`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tsyncGroupKey,\n\t\t\t\t\t\t`${userId} can see ${visibleTokens.length} tokens in ${viewAtoms.key}`,\n\t\t\t\t\t\tvisibleTokens,\n\t\t\t\t\t)\n\t\t\t\t\treturn visibleTokens\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tconst filterTransactionUpdate = (\n\t\t\t\tvisible: string[],\n\t\t\t\ttransactionUpdate: TransactionUpdate<any>,\n\t\t\t): TransactionUpdate<any> => {\n\t\t\t\tIMPLICIT.STORE.logger.info(\n\t\t\t\t\t`🖌`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tsyncGroupKey,\n\t\t\t\t\t`redacting updates from ${transactionUpdate.epoch}:${transactionUpdate.key}:${transactionUpdate.id}`,\n\t\t\t\t\tvisible,\n\t\t\t\t\ttransactionUpdate.updates,\n\t\t\t\t)\n\t\t\t\tconst updates = transactionUpdate.updates\n\t\t\t\t\t.filter((update) => {\n\t\t\t\t\t\tif (`newValue` in update) {\n\t\t\t\t\t\t\treturn visible.includes(update.key)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true\n\t\t\t\t\t})\n\t\t\t\t\t.map((update) => {\n\t\t\t\t\t\tif (`updates` in update) {\n\t\t\t\t\t\t\treturn filterTransactionUpdate(visible, update)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn update\n\t\t\t\t\t})\n\t\t\t\tconst filtered: TransactionUpdate<any> = {\n\t\t\t\t\t...transactionUpdate,\n\t\t\t\t\tupdates,\n\t\t\t\t}\n\t\t\t\treturn filtered\n\t\t\t}\n\t\t\tconst filter: (updates: TransactionUpdate<any>) => TransactionUpdate<any> =\n\t\t\t\t(update) => {\n\t\t\t\t\tconst visibleKeys: string[] = syncGroup.globals.map((atomToken) =>\n\t\t\t\t\t\tatomToken.type === `mutable_atom`\n\t\t\t\t\t\t\t? getUpdateToken(atomToken).key\n\t\t\t\t\t\t\t: atomToken.key,\n\t\t\t\t\t)\n\t\t\t\t\tvisibleKeys.push(...userPerspectiveTokens)\n\t\t\t\t\treturn filterTransactionUpdate(visibleKeys, update)\n\t\t\t\t}\n\t\t\treturn filter\n\t\t},\n})\n// export const occludedUpdateSelectors = selectorFamily<\n// \tPick<\n// \t\tTransactionUpdate<JsonIO>,\n// \t\t`epoch` | `id` | `key` | `output` | `updates`\n// \t> | null,\n// \t{ userId: string; syncGroupKey: string; updateId: string }\n// >({\n// \tkey: `occludedUpdate`,\n// \tget:\n// \t\t({ userId, syncGroupKey, updateId }) =>\n// \t\t({ get, find }) => {\n// \t\t\tconst updateState = find(completeUpdateAtoms, updateId)\n// \t\t\tconst update = get(updateState)\n// \t\t\tconst redactorKey = { userId, syncGroupKey }\n// \t\t\tconst redactorState = find(redactorAtoms, redactorKey)\n// \t\t\tconst redact = get(redactorState)\n// \t\t\tif (update) {\n// \t\t\t\t// return redact(update)\n// \t\t\t\treturn update\n// \t\t\t}\n// \t\t\treturn null\n// \t\t},\n// })\n","import * as AtomIO from \"atom.io\"\nimport type { Loadable } from \"atom.io/data\"\nimport type { UserInRoomMeta } from \"atom.io/realtime\"\nimport { roomIndex, usersInRooms } from \"atom.io/realtime\"\n\nimport type { ChildSocket } from \"../ipc-sockets\"\nimport type { RoomArguments } from \"./server-room-external-store\"\nimport { roomArgumentsAtoms, roomSelectors } from \"./server-room-external-store\"\n\nexport const createRoomTX = AtomIO.transaction<\n\t(\n\t\troomId: string,\n\t\tscript: string,\n\t\toptions?: string[],\n\t) => Loadable<ChildSocket<any, any>>\n>({\n\tkey: `createRoom`,\n\tdo: ({ get, set, find }, roomId, script, options) => {\n\t\tconst args: RoomArguments = options ? [script, options] : [script]\n\t\tconst roomArgumentsState = find(roomArgumentsAtoms, roomId)\n\t\tset(roomArgumentsState, args)\n\t\tset(roomIndex, (s) => s.add(roomId))\n\t\tconst roomState = find(roomSelectors, roomId)\n\t\tconst room = get(roomState)\n\t\treturn room\n\t},\n})\nexport type CreateRoomIO = AtomIO.TransactionIO<typeof createRoomTX>\n\nexport const joinRoomTX = AtomIO.transaction<\n\t(roomId: string, userId: string, enteredAtEpoch: number) => UserInRoomMeta\n>({\n\tkey: `joinRoom`,\n\tdo: (transactors, roomId, userId, enteredAtEpoch) => {\n\t\tconst meta = { enteredAtEpoch }\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.set(roomId, userId, meta)\n\t\t})\n\t\treturn meta\n\t},\n})\nexport type JoinRoomIO = AtomIO.TransactionIO<typeof joinRoomTX>\n\nexport const leaveRoomTX = AtomIO.transaction<\n\t(roomId: string, userId: string) => void\n>({\n\tkey: `leaveRoom`,\n\tdo: (transactors, roomId, userId) => {\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.delete({ room: roomId, user: userId })\n\t\t})\n\t},\n})\nexport type LeaveRoomIO = AtomIO.TransactionIO<typeof leaveRoomTX>\n\nexport const destroyRoomTX = AtomIO.transaction<(roomId: string) => void>({\n\tkey: `destroyRoom`,\n\tdo: (transactors, roomId) => {\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.delete({ room: roomId })\n\t\t})\n\t\ttransactors.set(roomIndex, (s) => (s.delete(roomId), s))\n\t},\n})\n","import type { ChildProcessWithoutNullStreams } from \"child_process\"\nimport { spawn } from \"child_process\"\n\nimport { atomFamily, selectorFamily } from \"atom.io\"\nimport type { Loadable } from \"atom.io/data\"\nimport { ChildSocket } from \"../ipc-sockets\"\n\nexport type RoomArguments =\n\t| [script: string, options: string[]]\n\t| [script: string]\n\nexport const roomArgumentsAtoms = atomFamily<RoomArguments, string>({\n\tkey: `roomArguments`,\n\tdefault: [`echo`, [`Hello World!`]],\n})\n\nexport const roomSelectors = selectorFamily<\n\tLoadable<ChildSocket<any, any>>,\n\tstring\n>({\n\tkey: `room`,\n\tget:\n\t\t(roomId) =>\n\t\tasync ({ get, find }) => {\n\t\t\tconst argumentsState = find(roomArgumentsAtoms, roomId)\n\t\t\tconst args = get(argumentsState)\n\t\t\tconst [script, options] = args\n\t\t\tconst child = await new Promise<ChildProcessWithoutNullStreams>(\n\t\t\t\t(resolve) => {\n\t\t\t\t\tconst room = spawn(script, options, { env: process.env })\n\t\t\t\t\tconst resolver = (data: Buffer) => {\n\t\t\t\t\t\tif (data.toString() === `✨`) {\n\t\t\t\t\t\t\troom.stdout.off(`data`, resolver)\n\t\t\t\t\t\t\tresolve(room)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\troom.stdout.on(`data`, resolver)\n\t\t\t\t},\n\t\t\t)\n\t\t\treturn new ChildSocket(child, roomId)\n\t\t},\n})\n","import type { TransactionUpdate, TransactionUpdateContent } from \"atom.io\"\nimport { atomFamily, selectorFamily } from \"atom.io\"\n\n// export const completeUpdateAtoms = atomFamily<\n// \tTransactionUpdate<any> | null,\n// \tstring\n// >({\n// \tkey: `completeUpdate`,\n// \tdefault: null,\n// })\n\nexport function redactTransactionUpdateContent(\n\tvisibleStateKeys: string[],\n\tupdates: TransactionUpdateContent[],\n): TransactionUpdateContent[] {\n\treturn updates\n\t\t.map((update): TransactionUpdateContent => {\n\t\t\tif (`newValue` in update) {\n\t\t\t\treturn update\n\t\t\t}\n\t\t\tconst redacted = redactTransactionUpdateContent(\n\t\t\t\tvisibleStateKeys,\n\t\t\t\tupdate.updates,\n\t\t\t)\n\t\t\treturn { ...update, updates: redacted }\n\t\t})\n\t\t.filter((update) => {\n\t\t\tif (`newValue` in update) {\n\t\t\t\treturn visibleStateKeys.includes(update.key)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n}\n\nexport const actionOcclusionAtoms = atomFamily<\n\t{\n\t\tocclude: (updates: TransactionUpdateContent[]) => TransactionUpdateContent[]\n\t},\n\tstring\n>({\n\tkey: `transactionRedactor`,\n\tdefault: { occlude: (updates) => updates },\n})\n// export const redactedUpdateSelectors = selectorFamily<\n// \tTransactionUpdate<any> | null,\n// \t[transactionKey: string, updateId: string]\n// >({\n// \tkey: `redactedUpdate`,\n// \tget:\n// \t\t([transactionKey, updateId]) =>\n// \t\t({ get, find }) => {\n// \t\t\tconst update = get(find(completeUpdateAtoms, updateId))\n// \t\t\tconst { filter } = get(find(transactionRedactorAtoms, transactionKey))\n\n// \t\t\tif (update && filter) {\n// \t\t\t\treturn { ...update, updates: filter(update.updates) }\n// \t\t\t}\n// \t\t\treturn null\n// \t\t},\n// })\n\nexport const userUnacknowledgedQueues = atomFamily<\n\tPick<TransactionUpdate<any>, `epoch` | `id` | `key` | `output` | `updates`>[],\n\tstring\n>({\n\tkey: `unacknowledgedUpdates`,\n\tdefault: () => [],\n})\n","import { atom, atomFamily } from \"atom.io\"\nimport { join } from \"atom.io/data\"\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\n\nimport type { Socket } from \"..\"\n\nexport const socketAtoms = atomFamily<Socket | null, string>({\n\tkey: `sockets`,\n\tdefault: null,\n})\n\nexport const socketIndex = atom({\n\tkey: `socketsIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\nexport const userIndex = atom({\n\tkey: `usersIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\nexport const usersOfSockets = join({\n\tkey: `usersOfSockets`,\n\tbetween: [`user`, `socket`],\n\tcardinality: `1:1`,\n})\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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\tlet unsubscribeFromStateUpdates: (() => void) | undefined\n\n\t\tconst fillSubRequest = () => {\n\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(token, store))\n\n\t\t\tunsubscribeFromStateUpdates = subscribeToState(\n\t\t\t\ttoken,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t},\n\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\tstore,\n\t\t\t)\n\n\t\t\tconst fillUnsubRequest = () => {\n\t\t\t\tsocket.off(`unsub:${token.key}`, fillUnsubRequest)\n\t\t\t\tif (unsubscribeFromStateUpdates) {\n\t\t\t\t\tunsubscribeFromStateUpdates()\n\t\t\t\t\tunsubscribeFromStateUpdates = undefined\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsocket.on(`unsub:${token.key}`, fillUnsubRequest)\n\t\t}\n\n\t\tsocket.on(`sub:${token.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${token.key}`, fillSubRequest)\n\t\t\tif (unsubscribeFromStateUpdates) {\n\t\t\t\tunsubscribeFromStateUpdates()\n\t\t\t\tunsubscribeFromStateUpdates = undefined\n\t\t\t}\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, getFromStore } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\n\nexport function realtimeStateSynchronizer({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateSynchronizer<J extends Json.Serializable>(\n\t\ttoken: AtomIO.WritableToken<J>,\n\t): () => void {\n\t\tconst fillGetRequest = () => {\n\t\t\tsocket.emit(`value:${token.key}`, getFromStore(token, store))\n\t\t}\n\n\t\tsocket.on(`get:${token.key}`, fillGetRequest)\n\t\treturn () => {\n\t\t\tsocket.off(`get:${token.key}`, fillGetRequest)\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tfindInStore,\n\tgetFromStore,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport { type Json, stringifyJson } from \"atom.io/json\"\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 Json.Serializable,\n\t>(\n\t\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst unsubCallbacksByKey = new Map<string, () => void>()\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tsocket.off(`unsub:${key}`, fillUnsubRequest)\n\t\t\tconst unsub = unsubCallbacksByKey.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tunsubCallbacksByKey.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst fillSubRequest = (subKey: K) => {\n\t\t\tconst exposedSubKeys = getFromStore(index, store)\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\tconst token = findInStore(family, subKey, store)\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(token, store))\n\t\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t\tstore,\n\t\t\t\t\t)\n\t\t\t\t\tunsubCallbacksByKey.set(token.key, unsubscribe)\n\t\t\t\t\tsocket.on(`unsub:${token.key}`, () => {\n\t\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsocket.on(`sub:${family.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${family.key}`, fillSubRequest)\n\n\t\t\tfor (const [, unsub] of unsubCallbacksByKey) {\n\t\t\t\tunsub()\n\t\t\t}\n\t\t\tunsubCallbacksByKey.clear()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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<Json.Serializable>,\n\t\tSerializableCore extends Json.Serializable,\n\t>(token: AtomIO.MutableAtomToken<Core, SerializableCore>): () => void {\n\t\tlet unsubscribeFromStateUpdates: (() => void) | null = null\n\n\t\tconst jsonToken = getJsonToken(token)\n\t\tconst trackerToken = getUpdateToken(token)\n\n\t\tconst fillUnsubRequest = () => {\n\t\t\tsocket.off(`unsub:${token.key}`, fillUnsubRequest)\n\t\t\tunsubscribeFromStateUpdates?.()\n\t\t\tunsubscribeFromStateUpdates = null\n\t\t}\n\n\t\tconst fillSubRequest = () => {\n\t\t\tsocket.emit(`init:${token.key}`, getFromStore(jsonToken, store))\n\t\t\tunsubscribeFromStateUpdates = subscribeToState(\n\t\t\t\ttrackerToken,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t},\n\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\tstore,\n\t\t\t)\n\t\t\tsocket.on(`unsub:${token.key}`, fillUnsubRequest)\n\t\t}\n\n\t\tsocket.on(`sub:${token.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${token.key}`, fillSubRequest)\n\t\t\tunsubscribeFromStateUpdates?.()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tIMPLICIT,\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\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>,\n\t\tJ extends Json.Serializable,\n\t\tK extends Json.Serializable,\n\t>(\n\t\tfamily: AtomIO.MutableAtomFamilyToken<T, J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst unsubCallbacksByKey = new Map<string, () => void>()\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tsocket.off(`unsub:${key}`, fillUnsubRequest)\n\t\t\tconst unsub = unsubCallbacksByKey.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tunsubCallbacksByKey.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst fillSubRequest = (subKey: K) => {\n\t\t\tconst exposedSubKeys = getFromStore(index, store)\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\tconst token = findInStore(family, subKey, store)\n\t\t\t\t\tconst jsonToken = getJsonToken(token)\n\t\t\t\t\tconst updateToken = getUpdateToken(token)\n\t\t\t\t\tsocket.emit(`init:${token.key}`, getFromStore(jsonToken, store))\n\t\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\t\tupdateToken,\n\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t\tstore,\n\t\t\t\t\t)\n\t\t\t\t\tunsubCallbacksByKey.set(token.key, unsubscribe)\n\t\t\t\t\tsocket.on(`unsub:${token.key}`, () => {\n\t\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsocket.on(`sub:${family.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${family.key}`, fillSubRequest)\n\t\t\tfor (const [, unsub] of unsubCallbacksByKey) {\n\t\t\t\tunsub()\n\t\t\t}\n\t\t\tunsubCallbacksByKey.clear()\n\t\t}\n\t}\n}\n","import type { WritableToken } from \"atom.io\"\nimport { IMPLICIT, setIntoStore } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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<J extends Json.Serializable>(\n\t\ttoken: WritableToken<J>,\n\t): () => void {\n\t\tconst publish = (newValue: J) => setIntoStore(token, newValue, store)\n\n\t\tconst fillPubUnclaim = () => {\n\t\t\tsocket.off(`pub:${token.key}`, publish)\n\t\t\tsocket.off(`unclaim:${token.key}`, fillPubUnclaim)\n\t\t}\n\t\tconst fillPubClaim = () => {\n\t\t\tsocket.on(`pub:${token.key}`, publish)\n\t\t\tsocket.on(`unclaim:${token.key}`, fillPubUnclaim)\n\t\t}\n\n\t\tsocket.on(`claim:${token.key}`, fillPubClaim)\n\n\t\treturn () => {\n\t\t\tsocket.off(`claim:${token.key}`, fillPubClaim)\n\t\t\tsocket.off(`pub:${token.key}`, publish)\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, actUponStore } from \"atom.io/internal\"\nimport type { JsonIO } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\n\nexport type ActionReceiver = ReturnType<typeof realtimeActionReceiver>\nexport function realtimeActionReceiver({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function actionReceiver<ƒ extends JsonIO>(\n\t\ttx: AtomIO.TransactionToken<ƒ>,\n\t): () => void {\n\t\tconst fillTransactionRequest = (\n\t\t\tupdate: Pick<AtomIO.TransactionUpdate<ƒ>, `id` | `params`>,\n\t\t) => {\n\t\t\tconst performanceKey = `tx-run:${tx.key}:${update.id}`\n\t\t\tconst performanceKeyStart = `${performanceKey}:start`\n\t\t\tconst performanceKeyEnd = `${performanceKey}:end`\n\t\t\tperformance.mark(performanceKeyStart)\n\t\t\tactUponStore<ƒ>(tx, update.id, store)(...update.params)\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(`🚀`, `transaction`, tx.key, update.id, metric.duration)\n\t\t}\n\t\tsocket.on(`tx-run:${tx.key}`, fillTransactionRequest)\n\n\t\treturn () => socket.off(`tx-run:${tx.key}`, fillTransactionRequest)\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/ipc-sockets/child-socket.ts","../src/ipc-sockets/custom-socket.ts","../src/ipc-sockets/parent-socket.ts","../src/realtime-continuity-synchronizer.ts","../src/realtime-server-stores/realtime-continuity-store.ts","../src/realtime-server-stores/server-room-external-actions.ts","../src/realtime-server-stores/server-room-external-store.ts","../src/realtime-server-stores/server-sync-store.ts","../src/realtime-server-stores/server-user-store.ts","../src/realtime-state-provider.ts","../src/realtime-state-synchronizer.ts","../src/realtime-family-provider.ts","../src/realtime-mutable-provider.ts","../src/realtime-mutable-family-provider.ts","../src/realtime-state-receiver.ts","../src/realtime-action-receiver.ts"],"names":["process","parsedEvent","parsedLog","parseJson","IMPLICIT","getJsonToken","selectorFamily","atomFamily","SetRTX","unsubscribeFunctions","atom","transaction","getFromStore","subscribeToState","findInStore","stringifyJson","getUpdateToken","actUponStore"],"mappings":";;;;;;AAGA,SAAS,iBAAiB;;;ACenB,IAAM,eAAN,MAAyE;AAAA,EAoBxE,YACC,MAIN;AAJM;AAHR,SAAO,KAAK;AAQX,SAAK,YAAY,oBAAI,IAAI;AACzB,SAAK,kBAAkB,oBAAI,IAAI;AAAA,EAChC;AAAA,EAzBU,YACT,UACG,MACI;AACP,eAAW,YAAY,KAAK,iBAAiB;AAC5C,eAAS,OAAO,GAAG,IAAI;AAAA,IACxB;AACA,UAAM,YAAY,KAAK,UAAU,IAAI,KAAK;AAC1C,QAAI,WAAW;AACd,iBAAW,YAAY,WAAW;AACjC,iBAAS,GAAG,IAAI;AAAA,MACjB;AAAA,IACD;AAAA,EACD;AAAA,EAcO,GACN,OACA,UACqB;AACrB,UAAM,YAAY,KAAK,UAAU,IAAI,KAAK;AAC1C,QAAI,WAAW;AACd,gBAAU,IAAI,QAAQ;AAAA,IACvB,OAAO;AACN,WAAK,UAAU,IAAI,OAAO,oBAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAAA,IAC9C;AACA,WAAO;AAAA,EACR;AAAA,EAEO,MACN,UACqB;AACrB,SAAK,gBAAgB,IAAI,QAAQ;AACjC,WAAO;AAAA,EACR;AAAA,EAEO,IACN,OACA,UACqB;AACrB,UAAM,YAAY,KAAK,UAAU,IAAI,KAAK;AAC1C,QAAI,WAAW;AACd,UAAI,UAAU;AACb,kBAAU,OAAO,QAAQ;AAAA,MAC1B,OAAO;AACN,aAAK,UAAU,OAAO,KAAK;AAAA,MAC5B;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEO,OACN,UACqB;AACrB,SAAK,gBAAgB,OAAO,QAAQ;AACpC,WAAO;AAAA,EACR;AACD;;;ADjFO,IAAM,cAAN,cAOG,aAAmB;AAAA,EAyBrB,YACCA,UACA,KACA,SAIH,SACH;AACD,UAAM,CAAC,UAAU,SAAS;AACzB,YAAM,mBAAmB,KAAK,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI;AAC5D,YAAM,eAAe,CAAC,QAAQ;AAC7B,YAAI,IAAI,SAAS,SAAS;AACzB,kBAAQ,MAAM,4BAA4B,KAAK,QAAQ,KAAK;AAAA,QAC7D;AACA,aAAK,QAAQ,MAAM,eAAe,SAAS,YAAY;AAAA,MACxD;AAEA,WAAK,QAAQ,MAAM,KAAK,SAAS,YAAY;AAC7C,WAAK,QAAQ,MAAM,MAAM,gBAAgB;AAEzC,aAAO;AAAA,IACR,CAAC;AArBM,mBAAAA;AACA;AACA;AA3BR,SAAU,iBAAiB;AAC3B,SAAU,oBAA8B,CAAC;AACzC,SAAU,gBAAgB;AAC1B,SAAU,kBAA4B,CAAC;AAEvC,SAAO,KAAK;AA0CX,SAAK,UAAUA;AACf,SAAK,QAAQ,OAAO;AAAA,MACnB;AAAA,MACA,CAAwB,WAA0C;AACjE,cAAM,QAAQ,OAAO,SAAS;AAE9B,YAAI,UAAU,UAAK;AAElB;AAAA,QACD;AACA,aAAK,kBAAkB,KAAK,GAAG,MAAM,MAAM,GAAM,CAAC;AAIlD,cAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,aAAK,kBAAkB,YAAY;AACnC,YAAI;AACH,cAAI,KAAK,eAAe,WAAW,OAAO,GAAG;AAC5C,oBAAQ,IAAI,UAAK,KAAK,cAAc;AAAA,UACrC;AACA,gBAAM,cAAc,UAAU,KAAK,cAAc;AACjD,eAAK,YAAY,GAAI,WAAuC;AAC5D,iBAAO,KAAK,kBAAkB,SAAS,GAAG;AACzC,kBAAM,QAAQ,KAAK,kBAAkB,MAAM;AAC3C,gBAAI,OAAO;AACV,kBAAI,KAAK,kBAAkB,WAAW,GAAG;AACxC,qBAAK,iBAAiB;AAAA,cACvB;AACA,oBAAMC,eAAc,UAAU,KAAK;AACnC,mBAAK,YAAY,GAAIA,YAAuC;AAAA,YAC7D;AAAA,UACD;AACA,eAAK,iBAAiB;AAAA,QACvB,SAAS,OAAO;AACf,kBAAQ,KAAK,0CAAsB;AACnC,kBAAQ,KAAK,KAAK,cAAc;AAChC,kBAAQ,KAAK,0CAAsB;AACnC,kBAAQ,MAAM,KAAK;AAAA,QACpB;AAAA,MACD;AAAA,IACD;AACA,SAAK,QAAQ,OAAO,GAAG,QAAQ,CAAC,QAAQ;AAxG1C;AAyGG,YAAM,QAAQ,IAAI,SAAS;AAC3B,WAAK,gBAAgB,KAAK,GAAG,MAAM,MAAM,GAAM,CAAC;AAIhD,YAAM,WAAW,KAAK,gBAAgB,MAAM;AAC5C,WAAK,iBAAiB,YAAY;AAClC,UAAI;AACH,cAAM,YAAY,UAAU,KAAK,aAAa;AAE9C,aAAK,UAAU,SAAS;AACxB,eAAO,KAAK,gBAAgB,SAAS,GAAG;AACvC,eAAK,iBAAgB,UAAK,gBAAgB,MAAM,MAA3B,YAAgC;AACrD,cAAI,KAAK,eAAe;AACvB,kBAAMC,aAAY,UAAU,KAAK,aAAa;AAC9C,iBAAK,UAAUA,UAAS;AAAA,UACzB;AAAA,QACD;AAAA,MACD,SAAS,OAAO;AACf,gBAAQ,MAAM,oBAAK;AACnB,gBAAQ,MAAM,KAAK,aAAa;AAChC,gBAAQ,MAAM,KAAK;AACnB,gBAAQ,MAAM,0BAAM;AAAA,MACrB;AAAA,IACD,CAAC;AACD,QAAIF,SAAQ,KAAK;AAChB,WAAK,KAAKA,SAAQ,IAAI,SAAS;AAAA,IAChC;AAAA,EACD;AAAA,EA9GU,UAAU,KAA8B;AACjD,QAAI,MAAM,QAAQ,GAAG,GAAG;AACvB,YAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AACzB,cAAQ,OAAO;AAAA,QACd,KAAK;AACJ,eAAK,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAC3C;AAAA,QACD,KAAK;AACJ,eAAK,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAC3C;AAAA,QACD,KAAK;AACJ,eAAK,OAAO,MAAM,KAAK,IAAI,KAAK,KAAK,GAAG,IAAI;AAC5C;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAgGD;;;AEtIA,SAAmB,eAAe;AAClC,SAAS,aAAAG,YAAW,qBAAqB;AAGzC,SAAS,cAAc;AAIhB,IAAM,gBAAN,cAGG,aAAmB;AAAA,EAMrB,YAAY,IAAY;AAC9B,UAAM,IAAI,SAAS;AAClB,WAAK,IAAI,KAAK,IAAW;AACzB,aAAO;AAAA,IACR,CAAC;AAPF,SAAO,KAAK;AACZ,SAAO,oBAAoC,CAAC;AAO3C,SAAK,KAAK;AACV,SAAK,KAAK,IAAI,QAAQ;AACtB,SAAK,MAAM,IAAI,QAAQ;AACvB,SAAK,GAAG,UAAU,UAAU,CAAC,UAAU;AACtC,WAAK,YAAY,GAAI,KAAiC;AAAA,IACvD,CAAC;AAAA,EACF;AAAA,EAEO,UAAgB;AACtB,eAAW,WAAW,KAAK,mBAAmB;AAC7C,cAAQ;AAAA,IACT;AAAA,EACD;AACD;AAEO,IAAM,eAAN,cAYG,aAAmB;AAAA,EA4BrB,cAAc;AA7EtB;AA8EE,UAAM,CAAC,UAAU,SAAS;AACzB,YAAM,mBAAmB,KAAK,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;AACxD,WAAK,QAAQ,OAAO,MAAM,mBAAmB,GAAM;AACnD,aAAO;AAAA,IACR,CAAC;AAhCF,SAAU,iBAAiB;AAC3B,SAAU,oBAA8B,CAAC;AAOzC,SAAO,KAAK;AAaZ,SAAO,SAAS;AAAA,MACf,MAAM,IAAI,SAAsB,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,MACrD,MAAM,IAAI,SAAsB,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,MACrD,OAAO,IAAI,SAAsB,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,IACvD;AAQC,SAAK,UAAU;AACf,SAAK,QAAQ,MAAM,OAAO;AAC1B,SAAK,SAAS,oBAAI,IAAI;AACtB,SAAK,gBAAgB,CAAC;AAGtB,SAAK,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA,CAAwB,WAA0C;AACjE,cAAM,QAAQ,OAAO,SAAS;AAC9B,aAAK,kBAAkB,KAAK,GAAG,MAAM,MAAM,GAAM,CAAC;AAClD,cAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,aAAK,kBAAkB,YAAY;AAEnC,YAAI;AACH,gBAAM,cAAcA,WAAU,KAAK,cAAc;AACjD,eAAK,OAAO,KAAK,aAAM,YAAY,WAAW;AAC9C,eAAK,YAAY,GAAI,WAAuC;AAC5D,iBAAO,KAAK,kBAAkB,SAAS,GAAG;AACzC,kBAAM,QAAQ,KAAK,kBAAkB,MAAM;AAC3C,gBAAI,OAAO;AACV,kBAAI,KAAK,kBAAkB,WAAW,GAAG;AACxC,qBAAK,iBAAiB;AAAA,cACvB;AACA,oBAAMF,eAAcE,WAAU,KAAK;AACnC,mBAAK,YAAY,GAAIF,YAAuC;AAAA,YAC7D;AAAA,UACD;AACA,eAAK,iBAAiB;AAAA,QACvB,SAAS,QAAQ;AAChB,cAAI,kBAAkB,OAAO;AAC5B,iBAAK,OAAO,MAAM,UAAK,OAAO,SAAS,OAAO,OAAO,OAAO,KAAK;AAAA,UAClE;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,SAAK,GAAG,QAAQ,MAAM;AACrB,WAAK,OAAO,KAAK,aAAM,KAAK,IAAI,iBAAiB;AACjD,cAAQ,KAAK,CAAC;AAAA,IACf,CAAC;AACD,YAAQ,GAAG,QAAQ,CAAC,SAAS;AAC5B,WAAK,OAAO,KAAK,aAAM,KAAK,IAAI,oBAAoB,IAAI,EAAE;AAAA,IAC3D,CAAC;AACD,YAAQ,GAAG,OAAO,MAAM;AACvB,WAAK,OAAO,KAAK,aAAM,KAAK,IAAI,OAAO;AACvC,cAAQ,KAAK,CAAC;AAAA,IACf,CAAC;AACD,YAAQ,GAAG,WAAW,MAAM;AAC3B,WAAK,OAAO,MAAM,aAAM,KAAK,IAAI,YAAY;AAC7C,cAAQ,KAAK,CAAC;AAAA,IACf,CAAC;AACD,YAAQ,GAAG,UAAU,MAAM;AAC1B,WAAK,OAAO,MAAM,aAAM,KAAK,IAAI,aAAa;AAC9C,cAAQ,KAAK,CAAC;AAAA,IACf,CAAC;AAED,QAAI,QAAQ,KAAK;AAChB,WAAK,MAAK,aAAQ,QAAR,mBAAa;AAAA,IACxB;AAEA,SAAK,GAAG,cAAc,CAAC,aAAa;AACnC,WAAK,OAAO,KAAK,aAAM,QAAQ,UAAU,QAAQ;AACjD,YAAM,QAAQ,IAAI,cAAc,QAAQ,QAAQ,EAAE;AAClD,WAAK,OAAO,IAAI,UAAU,KAAK;AAC/B,WAAK,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA,IAAI,CAAC,GAAG,KAAK,cAAc,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,MAC9C;AACA,iBAAW,kBAAkB,KAAK,eAAe;AAChD,cAAM,UAAU,eAAe,KAAK;AACpC,YAAI,SAAS;AACZ,gBAAM,kBAAkB,KAAK,OAAO;AAAA,QACrC;AAAA,MACD;AACA,WAAK,GAAG,QAAQ,QAAQ,IAAI,IAAI,SAAS;AACxC,cAAM,GAAG,KAAK,IAAI;AAAA,MACnB,CAAC;AACD,YAAM,IAAI,UAAU,UAAU,CAAC,SAAS;AACvC,aAAK,KAAK,GAAI,IAAgC;AAAA,MAC/C,CAAC;AAAA,IACF,CAAC;AAED,SAAK,GAAG,eAAe,CAAC,aAAa;AACpC,YAAM,QAAQ,KAAK,OAAO,IAAI,QAAQ;AACtC,WAAK,IAAI,SAAS,QAAQ,EAAE;AAC5B,UAAI,OAAO;AACV,cAAM,QAAQ;AACd,aAAK,OAAO,OAAO,QAAQ;AAAA,MAC5B;AAAA,IACD,CAAC;AAED,YAAQ,OAAO,MAAM,QAAG;AAAA,EACzB;AAAA,EArHU,OAAO,MAAmB;AACnC,SAAK,QAAQ,OAAO;AAAA,MACnB;AAAA,QACC,KAAK;AAAA,UAAI,CAAC,QACT,eAAe,SACZ,KAAK,IAAI,OAAO,EAAE,QAAQ,KAAK,KAAK,CAAC,OACrC;AAAA,QACJ;AAAA,MACD,IAAI;AAAA,IACL;AAAA,EACD;AAAA,EA6GO,MACN,gBACO;AACP,SAAK,OAAO,KAAK,aAAM,sBAAsB;AAC7C,SAAK,cAAc,KAAK,cAAc;AAAA,EACvC;AACD;;;ACxLA;AAAA,EACC,YAAAG;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;;;ACVP,SAAS,sBAAsB;AAE/B,SAAS,YAAAD,WAAwB,sBAAsB;AAEvD,SAAS,iBAAiB;AAG1B,IAAM,gBAAgB,eAGpB;AAAA,EACD,KAAK;AAAA,EACL,KACC,CAAC,EAAE,QAAQ,aAAa,MACxB,CAAC,EAAE,KAAK,KAAK,MAAM;AAClB,UAAM,YAAY,UAAU,SAAS,IAAI,YAAY;AACrD,QAAI,CAAC,WAAW;AACf,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAEA,UAAM,wBAAwB,UAAU,aAAa;AAAA,MACpD,CAAC,EAAE,UAAU,MAAM;AAClB,cAAM,uBAAuB,KAAK,WAAW,MAAM;AACnD,cAAM,kBAAkB,IAAI,oBAAoB;AAChD,cAAM,gBAAgB,CAAC,GAAG,eAAe,EAAE,IAAI,CAAC,UAAU;AACzD,iBAAO,MAAM,SAAS,iBACnB,eAAe,KAAK,EAAE,MACtB,MAAM;AAAA,QACV,CAAC;AACD,QAAAA,UAAS,MAAM,OAAO;AAAA,UACrB;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG,MAAM,YAAY,cAAc,MAAM,cAAc,UAAU,GAAG;AAAA,UACpE;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA,IACD;AAEA,UAAM,0BAA0B,CAC/B,SACA,sBAC4B;AAC5B,MAAAA,UAAS,MAAM,OAAO;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA,0BAA0B,kBAAkB,KAAK,IAAI,kBAAkB,GAAG,IAAI,kBAAkB,EAAE;AAAA,QAClG;AAAA,QACA,kBAAkB;AAAA,MACnB;AACA,YAAM,UAAU,kBAAkB,QAChC,OAAO,CAAC,WAAW;AACnB,YAAI,cAAc,QAAQ;AACzB,iBAAO,QAAQ,SAAS,OAAO,GAAG;AAAA,QACnC;AACA,eAAO;AAAA,MACR,CAAC,EACA,IAAI,CAAC,WAAW;AAChB,YAAI,aAAa,QAAQ;AACxB,iBAAO,wBAAwB,SAAS,MAAM;AAAA,QAC/C;AACA,eAAO;AAAA,MACR,CAAC;AACF,YAAM,WAAmC,iCACrC,oBADqC;AAAA,QAExC;AAAA,MACD;AACA,aAAO;AAAA,IACR;AACA,UAAM,SACL,CAAC,WAAW;AACX,YAAM,cAAwB,UAAU,QAAQ;AAAA,QAAI,CAAC,cACpD,UAAU,SAAS,iBAChB,eAAe,SAAS,EAAE,MAC1B,UAAU;AAAA,MACd;AACA,kBAAY,KAAK,GAAG,qBAAqB;AACzC,aAAO,wBAAwB,aAAa,MAAM;AAAA,IACnD;AACD,WAAO;AAAA,EACR;AACF,CAAC;;;ACrFD,YAAY,YAAY;AAGxB,SAAS,WAAW,oBAAoB;;;ACFxC,SAAS,aAAa;AAEtB,SAAS,YAAY,kBAAAE,uBAAsB;AAQpC,IAAM,qBAAqB,WAAkC;AAAA,EACnE,KAAK;AAAA,EACL,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC;AACnC,CAAC;AAEM,IAAM,gBAAgBA,gBAG3B;AAAA,EACD,KAAK;AAAA,EACL,KACC,CAAC,WACD,OAAO,EAAE,KAAK,KAAK,MAAM;AACxB,UAAM,iBAAiB,KAAK,oBAAoB,MAAM;AACtD,UAAM,OAAO,IAAI,cAAc;AAC/B,UAAM,CAAC,QAAQ,OAAO,IAAI;AAC1B,UAAM,QAAQ,MAAM,IAAI;AAAA,MACvB,CAAC,YAAY;AACZ,cAAM,OAAO,MAAM,QAAQ,SAAS,EAAE,KAAK,QAAQ,IAAI,CAAC;AACxD,cAAM,WAAW,CAAC,SAAiB;AAClC,cAAI,KAAK,SAAS,MAAM,UAAK;AAC5B,iBAAK,OAAO,IAAI,QAAQ,QAAQ;AAChC,oBAAQ,IAAI;AAAA,UACb;AAAA,QACD;AACA,aAAK,OAAO,GAAG,QAAQ,QAAQ;AAAA,MAChC;AAAA,IACD;AACA,WAAO,IAAI,YAAY,OAAO,MAAM;AAAA,EACrC;AACF,CAAC;;;ADhCM,IAAM,eAAsB,mBAMjC;AAAA,EACD,KAAK;AAAA,EACL,IAAI,CAAC,EAAE,KAAK,KAAK,KAAK,GAAG,QAAQ,QAAQ,YAAY;AACpD,UAAM,OAAsB,UAAU,CAAC,QAAQ,OAAO,IAAI,CAAC,MAAM;AACjE,UAAM,qBAAqB,KAAK,oBAAoB,MAAM;AAC1D,QAAI,oBAAoB,IAAI;AAC5B,QAAI,WAAW,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC;AACnC,UAAM,YAAY,KAAK,eAAe,MAAM;AAC5C,UAAM,OAAO,IAAI,SAAS;AAC1B,WAAO;AAAA,EACR;AACD,CAAC;AAGM,IAAM,aAAoB,mBAE/B;AAAA,EACD,KAAK;AAAA,EACL,IAAI,CAAC,aAAa,QAAQ,QAAQ,mBAAmB;AACpD,UAAM,OAAO,EAAE,eAAe;AAC9B,iBAAa,SAAS,aAAa,CAAC,EAAE,UAAU,MAAM;AACrD,gBAAU,IAAI,QAAQ,QAAQ,IAAI;AAAA,IACnC,CAAC;AACD,WAAO;AAAA,EACR;AACD,CAAC;AAGM,IAAM,cAAqB,mBAEhC;AAAA,EACD,KAAK;AAAA,EACL,IAAI,CAAC,aAAa,QAAQ,WAAW;AACpC,iBAAa,SAAS,aAAa,CAAC,EAAE,UAAU,MAAM;AACrD,gBAAU,OAAO,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,IAChD,CAAC;AAAA,EACF;AACD,CAAC;AAGM,IAAM,gBAAuB,mBAAsC;AAAA,EACzE,KAAK;AAAA,EACL,IAAI,CAAC,aAAa,WAAW;AAC5B,iBAAa,SAAS,aAAa,CAAC,EAAE,UAAU,MAAM;AACrD,gBAAU,OAAO,EAAE,MAAM,OAAO,CAAC;AAAA,IAClC,CAAC;AACD,gBAAY,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,MAAM,GAAG,EAAE;AAAA,EACxD;AACD,CAAC;;;AE9DD,SAAS,cAAAC,mBAAkC;AAUpC,SAAS,+BACf,kBACA,SAC6B;AAC7B,SAAO,QACL,IAAI,CAAC,WAAqC;AAC1C,QAAI,cAAc,QAAQ;AACzB,aAAO;AAAA,IACR;AACA,UAAM,WAAW;AAAA,MAChB;AAAA,MACA,OAAO;AAAA,IACR;AACA,WAAO,iCAAK,SAAL,EAAa,SAAS,SAAS;AAAA,EACvC,CAAC,EACA,OAAO,CAAC,WAAW;AACnB,QAAI,cAAc,QAAQ;AACzB,aAAO,iBAAiB,SAAS,OAAO,GAAG;AAAA,IAC5C;AACA,WAAO;AAAA,EACR,CAAC;AACH;AAEO,IAAM,uBAAuBA,YAKlC;AAAA,EACD,KAAK;AAAA,EACL,SAAS,EAAE,SAAS,CAAC,YAAY,QAAQ;AAC1C,CAAC;AAmBM,IAAM,2BAA2BA,YAGtC;AAAA,EACD,KAAK;AAAA,EACL,SAAS,MAAM,CAAC;AACjB,CAAC;;;ACnED,SAAS,MAAM,cAAAA,mBAAkB;AACjC,SAAS,YAAY;AACrB,SAAS,UAAAC,eAAc;AAIhB,IAAM,cAAcD,YAAkC;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AACV,CAAC;AAEM,IAAM,cAAc,KAAK;AAAA,EAC/B,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS,MAAM,IAAIC,QAAe;AAAA,EAClC,QAAQ,CAAC,QAAQ,IAAI,OAAO;AAAA,EAC5B,UAAU,CAAC,SAASA,QAAO,SAAS,IAAI;AACzC,CAAC;AACM,IAAM,YAAY,KAAK;AAAA,EAC7B,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS,MAAM,IAAIA,QAAe;AAAA,EAClC,QAAQ,CAAC,QAAQ,IAAI,OAAO;AAAA,EAC5B,UAAU,CAAC,SAASA,QAAO,SAAS,IAAI;AACzC,CAAC;AACM,IAAM,iBAAiB,KAAK;AAAA,EAClC,KAAK;AAAA,EACL,SAAS,CAAC,QAAQ,QAAQ;AAAA,EAC1B,aAAa;AACd,CAAC;;;ALJM,SAAS,+BAA+B;AAAA,EAC9C,QAAQ;AAAA,EACR,QAAQJ,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,aAAa,YAAyC;AACrE,QAAI,SAAwB;AAE5B,UAAM,gBAAgB,WAAW;AACjC,UAAM,eAAe;AAAA,MACpB,eAAe,OAAO;AAAA,MACtB,OAAO;AAAA,MACP;AAAA,IACD;AACA,UAAM,UAAU,aAAa,cAAc,KAAK;AAChD,QAAI,CAAC,SAAS;AACb,YAAM,OAAO;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,gDAAgD,OAAO,EAAE;AAAA,MAC1D;AACA,aAAO,MAAM;AAAA,MAAC;AAAA,IACf;AACA,UAAM,iBAAiB;AAAA,MACtB,eAAe,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,IACD;AACA;AAAA,MACC;AAAA,MACA,CAAC,EAAE,UAAU,aAAa,MAAM;AAC/B,cAAM,OAAO;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU,OAAO,kBAAkB,YAAY;AAAA,QAChD;AACA,YAAI,iBAAiB,MAAM;AAC1B,gBAAM,OAAO;AAAA,YACZ;AAAA,YACA;AAAA,YACA;AAAA,YACA,8CAA8C,OAAO;AAAA,UACtD;AACA;AAAA,QACD;AACA,cAAM,iBAAiB,YAAY,aAAa,cAAc,KAAK;AACnE,cAAM,YAAY,aAAa,gBAAgB,KAAK;AACpD,iBAAS;AAAA,MACV;AAAA,MACA,mBAAmB,aAAa,IAAI,OAAO;AAAA,MAC3C;AAAA,IACD;AAEA,UAAM,0BAA0B;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,UAAM,4BAA4B;AAAA,MACjC;AAAA,MACA;AAAA,IACD;AACA,UAAM,uBAAuC,CAAC;AAE9C,UAAM,qBAAqB,MAAoB;AAC9C,YAAMK,wBAAuC,CAAC;AAC9C,iBAAW,eAAe,WAAW,cAAc;AAClD,cAAM,EAAE,UAAU,IAAI;AACtB,cAAM,gBAAgB,YAAY,WAAW,SAAS,KAAK;AAC3D,cAAM,cAAc;AAAA,UACnB;AAAA,UACA,CAAC,EAAE,UAAU,SAAS,MAAM;AAC3B,kBAAM,UAAU,SAAS,IAAI,CAAC,UAAU,MAAM,GAAG;AACjD,kBAAM,UAAU,SAAS,IAAI,CAAC,UAAU,MAAM,GAAG;AACjD,kBAAM,YAAY,SAAS;AAAA,cAC1B,CAAC,UAAU,CAAC,QAAQ,SAAS,MAAM,GAAG;AAAA,YACvC;AACA,kBAAM,WAAW,SACf,OAAO,CAAC,UAAU,CAAC,QAAQ,SAAS,MAAM,GAAG,CAAC,EAC9C,QAAQ,CAAC,UAAU;AACnB,oBAAM,gBACL,MAAM,SAAS,iBAAiBJ,cAAa,KAAK,IAAI;AACvD,oBAAM,WAAW,aAAa,eAAe,KAAK;AAClD,qBAAO,CAAC,eAAe,QAAQ;AAAA,YAChC,CAAC;AACF,kBAAM,OAAO;AAAA,cACZ;AAAA,cACA;AAAA,cACA,YAAY,cAAc;AAAA,cAC1B,GAAG,OAAO;AAAA,cACV,EAAE,SAAS,SAAS,UAAU,UAAU;AAAA,YACzC;AACA,gBAAI,SAAS,SAAS,GAAG;AACxB,+CAAQ,KAAK,UAAU,aAAa,IAAI;AAAA,YACzC;AACA,gBAAI,UAAU,SAAS,GAAG;AACzB,+CAAQ,KAAK,WAAW,aAAa,IAAI;AAAA,YAC1C;AAAA,UACD;AAAA,UACA,mBAAmB,aAAa,IAAI,OAAO,gBAAgB,YAAY,cAAc,GAAG;AAAA,UACxF;AAAA,QACD;AACA,QAAAI,sBAAqB,KAAK,WAAW;AAAA,MACtC;AACA,aAAO,MAAM;AACZ,mBAAW,eAAeA;AAAsB,sBAAY;AAAA,MAC7D;AAAA,IACD;AACA,UAAM,8BAA8B,mBAAmB;AAEvD,UAAM,qBAAqB,MAAM;AAxInC;AAyIG,YAAM,iBAAsC,CAAC;AAC7C,iBAAWC,SAAQ,WAAW,SAAS;AACtC,cAAM,gBACLA,MAAK,SAAS,iBAAiBL,cAAaK,KAAI,IAAIA;AACrD,uBAAe,KAAK,eAAe,aAAaA,OAAM,KAAK,CAAC;AAAA,MAC7D;AACA,iBAAW,eAAe,WAAW,cAAc;AAClD,cAAM,EAAE,WAAW,cAAc,IAAI;AACrC,cAAM,gBAAgB,YAAY,WAAW,SAAS,KAAK;AAC3D,cAAM,WAAW,aAAa,eAAe,KAAK;AAClD,cAAM,OAAO,KAAK,aAAM,QAAQ,cAAc,KAAK,GAAG,OAAO,YAAY;AAAA,UACxE;AAAA,UACA;AAAA,UACA;AAAA,QACD,CAAC;AACD,mBAAW,gBAAgB,UAAU;AACpC,gBAAM,gBACL,aAAa,SAAS,iBACnBL,cAAa,YAAY,IACzB;AACJ,gBAAM,WAAW,aAAa,eAAe,KAAK;AAElD,yBAAe,KAAK,eAAe,QAAQ;AAAA,QAC5C;AAAA,MACD;AAEA,YAAM,QAAQ,YAAY,KAAK,KAC5B,WAAM,gBAAgB,MAAM,IAAI,aAAa,MAA7C,YAAkD,OAClD;AAEH,uCAAQ,KAAK,mBAAmB,aAAa,IAAI,OAAO;AAExD,iBAAWM,gBAAe,WAAW,SAAS;AAC7C,cAAM,6BAA6B;AAAA,UAClCA;AAAA,UACA,CAAC,WAAW;AACX,gBAAI;AACH,oBAAM,cAAc,WAAW,QAC7B,IAAI,CAACD,UAASA,MAAK,GAAG,EACtB;AAAA,gBACA,WAAW,aAAa,QAAQ,CAAC,gBAAgB;AAChD,wBAAM,EAAE,UAAU,IAAI;AACtB,wBAAM,4BAA4B;AAAA,oBACjC;AAAA,oBACA;AAAA,oBACA;AAAA,kBACD;AACA,wBAAM,gBAAgB;AAAA,oBACrB;AAAA,oBACA;AAAA,kBACD;AACA,yBAAO,cAAc,IAAI,CAAC,UAAU;AACnC,0BAAM,MACL,MAAM,SAAS,iBACZ,MAAM,MAAM,MACZ,MAAM;AACV,2BAAO;AAAA,kBACR,CAAC;AAAA,gBACF,CAAC;AAAA,cACF;AACD,oBAAM,kBAAkB;AAAA,gBACvB;AAAA,gBACA,OAAO;AAAA,cACR;AACA,oBAAM,iBAAiB,iCACnB,SADmB;AAAA,gBAEtB,SAAS;AAAA,cACV;AAaA,+CAAQ;AAAA,gBACP,UAAU,aAAa;AAAA,gBACvB;AAAA;AAAA,YAEF,SAAS,QAAQ;AAChB,kBAAI,kBAAkB,OAAO;AAC5B,sBAAM,OAAO;AAAA,kBACZ;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,0CAA0CC,aAAY,GAAG,OAAO,OAAO;AAAA,kBACvE,OAAO;AAAA,gBACR;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,UACA,mBAAmB,aAAa,IAAI,OAAO;AAAA,UAC3C;AAAA,QACD;AACA,6BAAqB,KAAK,0BAA0B;AAAA,MACrD;AAAA,IACD;AACA,WAAO,IAAI,OAAO,aAAa,IAAI,kBAAkB;AACrD,WAAO,GAAG,OAAO,aAAa,IAAI,kBAAkB;AAEpD,UAAM,yBAAyB,CAC9B,WACI;AACJ,YAAM,OAAO,KAAK,mBAAO,cAAc,eAAe,YAAY,MAAM;AACxE,YAAM,iBAAiB,OAAO;AAC9B,YAAM,WAAW,OAAO;AACxB,YAAM,iBAAiB,UAAU,cAAc,IAAI,QAAQ;AAC3D,YAAM,sBAAsB,GAAG,cAAc;AAC7C,YAAM,oBAAoB,GAAG,cAAc;AAC3C,kBAAY,KAAK,mBAAmB;AACpC,UAAI;AACH;AAAA,UACC,EAAE,MAAM,eAAe,KAAK,eAAe;AAAA,UAC3C;AAAA,UACA;AAAA,QACD,EAAE,GAAG,OAAO,MAAM;AAAA,MACnB,SAAS,QAAQ;AAChB,YAAI,kBAAkB,OAAO;AAC5B,gBAAM,OAAO;AAAA,YACZ;AAAA,YACA;AAAA,YACA;AAAA,YACA,6BAA6B,cAAc,gBAAgB,QAAQ;AAAA,YACnE,OAAO;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,kBAAY,KAAK,iBAAiB;AAClC,YAAM,SAAS,YAAY;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,qCAAO,OAAO;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA;AAGR,YAAM,uBAAuB,sBAAsB,OAAO;AAC1D,YAAM,uBACL,MAAM,cAAc,eAAe,oBAAoB;AACxD,YAAM,kBAAkB,MAAM,SAAS,IAAI,oBAAoB;AAE/D,YAAM,OAAO;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,OAAO;AAAA,QACjB;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,WAAO,IAAI,UAAU,aAAa,IAAI,sBAAsB;AAC5D,WAAO,GAAG,UAAU,aAAa,IAAI,sBAAsB;AAiE3D,WAAO,MAAM;AAEZ,iBAAW,eAAe;AAAsB,oBAAY;AAE5D,kCAA4B;AAC5B,uCAAQ,IAAI,OAAO,aAAa,IAAI;AACpC,uCAAQ,IAAI,UAAU,aAAa,IAAI;AAAA,IACxC;AAAA,EACD;AACD;;;AMtXA,SAAS,YAAAP,WAAU,gBAAAQ,eAAc,oBAAAC,yBAAwB;AAMlD,SAAS,sBAAsB;AAAA,EACrC;AAAA,EACA,QAAQT,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,cACf,OACa;AACb,QAAI;AAEJ,UAAM,iBAAiB,MAAM;AAC5B,aAAO,KAAK,SAAS,MAAM,GAAG,IAAIQ,cAAa,OAAO,KAAK,CAAC;AAE5D,oCAA8BC;AAAA,QAC7B;AAAA,QACA,CAAC,EAAE,SAAS,MAAM;AACjB,iBAAO,KAAK,SAAS,MAAM,GAAG,IAAI,QAAQ;AAAA,QAC3C;AAAA,QACA,iBAAiB,OAAO,EAAE;AAAA,QAC1B;AAAA,MACD;AAEA,YAAM,mBAAmB,MAAM;AAC9B,eAAO,IAAI,SAAS,MAAM,GAAG,IAAI,gBAAgB;AACjD,YAAI,6BAA6B;AAChC,sCAA4B;AAC5B,wCAA8B;AAAA,QAC/B;AAAA,MACD;AAEA,aAAO,GAAG,SAAS,MAAM,GAAG,IAAI,gBAAgB;AAAA,IACjD;AAEA,WAAO,GAAG,OAAO,MAAM,GAAG,IAAI,cAAc;AAE5C,WAAO,MAAM;AACZ,aAAO,IAAI,OAAO,MAAM,GAAG,IAAI,cAAc;AAC7C,UAAI,6BAA6B;AAChC,oCAA4B;AAC5B,sCAA8B;AAAA,MAC/B;AAAA,IACD;AAAA,EACD;AACD;;;AChDA,SAAS,YAAAT,WAAU,gBAAAQ,qBAAoB;AAKhC,SAAS,0BAA0B;AAAA,EACzC;AAAA,EACA,QAAQR,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,kBACf,OACa;AACb,UAAM,iBAAiB,MAAM;AAC5B,aAAO,KAAK,SAAS,MAAM,GAAG,IAAIQ,cAAa,OAAO,KAAK,CAAC;AAAA,IAC7D;AAEA,WAAO,GAAG,OAAO,MAAM,GAAG,IAAI,cAAc;AAC5C,WAAO,MAAM;AACZ,aAAO,IAAI,OAAO,MAAM,GAAG,IAAI,cAAc;AAAA,IAC9C;AAAA,EACD;AACD;;;ACrBA;AAAA,EACC,YAAAR;AAAA,EACA,eAAAU;AAAA,EACA,gBAAAF;AAAA,EACA,oBAAAC;AAAA,OACM;AACP,SAAoB,iBAAAE,sBAAqB;AAKlC,SAAS,2BAA2B;AAAA,EAC1C;AAAA,EACA,QAAQX,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,eAIf,QACA,OACa;AACb,UAAM,sBAAsB,oBAAI,IAAwB;AAExD,UAAM,mBAAmB,CAAC,QAAgB;AACzC,aAAO,IAAI,SAAS,GAAG,IAAI,gBAAgB;AAC3C,YAAM,QAAQ,oBAAoB,IAAI,GAAG;AACzC,UAAI,OAAO;AACV,cAAM;AACN,4BAAoB,OAAO,GAAG;AAAA,MAC/B;AAAA,IACD;AAEA,UAAM,iBAAiB,CAAC,WAAc;AACrC,YAAM,iBAAiBQ,cAAa,OAAO,KAAK;AAChD,iBAAW,iBAAiB,gBAAgB;AAC3C,YAAIG,eAAc,aAAa,MAAMA,eAAc,MAAM,GAAG;AAC3D,gBAAM,QAAQD,aAAY,QAAQ,QAAQ,KAAK;AAC/C,iBAAO,KAAK,SAAS,MAAM,GAAG,IAAIF,cAAa,OAAO,KAAK,CAAC;AAC5D,gBAAM,cAAcC;AAAA,YACnB;AAAA,YACA,CAAC,EAAE,SAAS,MAAM;AACjB,qBAAO,KAAK,SAAS,MAAM,GAAG,IAAI,QAAQ;AAAA,YAC3C;AAAA,YACA,iBAAiB,OAAO,GAAG,IAAI,OAAO,EAAE;AAAA,YACxC;AAAA,UACD;AACA,8BAAoB,IAAI,MAAM,KAAK,WAAW;AAC9C,iBAAO,GAAG,SAAS,MAAM,GAAG,IAAI,MAAM;AACrC,6BAAiB,MAAM,GAAG;AAAA,UAC3B,CAAC;AACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,WAAO,GAAG,OAAO,OAAO,GAAG,IAAI,cAAc;AAE7C,WAAO,MAAM;AACZ,aAAO,IAAI,OAAO,OAAO,GAAG,IAAI,cAAc;AAE9C,iBAAW,CAAC,EAAE,KAAK,KAAK,qBAAqB;AAC5C,cAAM;AAAA,MACP;AACA,0BAAoB,MAAM;AAAA,IAC3B;AAAA,EACD;AACD;;;ACnEA;AAAA,EACC,YAAAT;AAAA,EACA,gBAAAQ;AAAA,EACA,gBAAAP;AAAA,EACA,kBAAAW;AAAA,EACA,oBAAAH;AAAA,OACM;AAOA,SAAS,wBAAwB;AAAA,EACvC;AAAA,EACA,QAAQT,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,gBAGd,OAAoE;AACrE,QAAI,8BAAmD;AAEvD,UAAM,YAAYC,cAAa,KAAK;AACpC,UAAM,eAAeW,gBAAe,KAAK;AAEzC,UAAM,mBAAmB,MAAM;AAC9B,aAAO,IAAI,SAAS,MAAM,GAAG,IAAI,gBAAgB;AACjD;AACA,oCAA8B;AAAA,IAC/B;AAEA,UAAM,iBAAiB,MAAM;AAC5B,aAAO,KAAK,QAAQ,MAAM,GAAG,IAAIJ,cAAa,WAAW,KAAK,CAAC;AAC/D,oCAA8BC;AAAA,QAC7B;AAAA,QACA,CAAC,EAAE,SAAS,MAAM;AACjB,iBAAO,KAAK,QAAQ,MAAM,GAAG,IAAI,QAAQ;AAAA,QAC1C;AAAA,QACA,iBAAiB,OAAO,EAAE;AAAA,QAC1B;AAAA,MACD;AACA,aAAO,GAAG,SAAS,MAAM,GAAG,IAAI,gBAAgB;AAAA,IACjD;AAEA,WAAO,GAAG,OAAO,MAAM,GAAG,IAAI,cAAc;AAE5C,WAAO,MAAM;AACZ,aAAO,IAAI,OAAO,MAAM,GAAG,IAAI,cAAc;AAC7C;AAAA,IACD;AAAA,EACD;AACD;;;ACnDA;AAAA,EACC,YAAAT;AAAA,EACA,eAAAU;AAAA,EACA,gBAAAF;AAAA,EACA,gBAAAP;AAAA,EACA,kBAAAW;AAAA,EACA,oBAAAH;AAAA,OACM;AAEP,SAAS,iBAAAE,sBAAqB;AAOvB,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA,QAAQX,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,sBAKf,QACA,OACa;AACb,UAAM,sBAAsB,oBAAI,IAAwB;AAExD,UAAM,mBAAmB,CAAC,QAAgB;AACzC,aAAO,IAAI,SAAS,GAAG,IAAI,gBAAgB;AAC3C,YAAM,QAAQ,oBAAoB,IAAI,GAAG;AACzC,UAAI,OAAO;AACV,cAAM;AACN,4BAAoB,OAAO,GAAG;AAAA,MAC/B;AAAA,IACD;AAEA,UAAM,iBAAiB,CAAC,WAAc;AACrC,YAAM,iBAAiBQ,cAAa,OAAO,KAAK;AAChD,iBAAW,iBAAiB,gBAAgB;AAC3C,YAAIG,eAAc,aAAa,MAAMA,eAAc,MAAM,GAAG;AAC3D,gBAAM,QAAQD,aAAY,QAAQ,QAAQ,KAAK;AAC/C,gBAAM,YAAYT,cAAa,KAAK;AACpC,gBAAM,cAAcW,gBAAe,KAAK;AACxC,iBAAO,KAAK,QAAQ,MAAM,GAAG,IAAIJ,cAAa,WAAW,KAAK,CAAC;AAC/D,gBAAM,cAAcC;AAAA,YACnB;AAAA,YACA,CAAC,EAAE,SAAS,MAAM;AACjB,qBAAO,KAAK,QAAQ,MAAM,GAAG,IAAI,QAAQ;AAAA,YAC1C;AAAA,YACA,iBAAiB,OAAO,GAAG,IAAI,OAAO,EAAE;AAAA,YACxC;AAAA,UACD;AACA,8BAAoB,IAAI,MAAM,KAAK,WAAW;AAC9C,iBAAO,GAAG,SAAS,MAAM,GAAG,IAAI,MAAM;AACrC,6BAAiB,MAAM,GAAG;AAAA,UAC3B,CAAC;AACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,WAAO,GAAG,OAAO,OAAO,GAAG,IAAI,cAAc;AAE7C,WAAO,MAAM;AACZ,aAAO,IAAI,OAAO,OAAO,GAAG,IAAI,cAAc;AAC9C,iBAAW,CAAC,EAAE,KAAK,KAAK,qBAAqB;AAC5C,cAAM;AAAA,MACP;AACA,0BAAoB,MAAM;AAAA,IAC3B;AAAA,EACD;AACD;;;AC3EA,SAAS,YAAAT,WAAU,oBAAoB;AAMhC,SAAS,sBAAsB;AAAA,EACrC;AAAA,EACA,QAAQA,UAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,cACf,OACa;AACb,UAAM,UAAU,CAAC,aAAgB,aAAa,OAAO,UAAU,KAAK;AAEpE,UAAM,iBAAiB,MAAM;AAC5B,aAAO,IAAI,OAAO,MAAM,GAAG,IAAI,OAAO;AACtC,aAAO,IAAI,WAAW,MAAM,GAAG,IAAI,cAAc;AAAA,IAClD;AACA,UAAM,eAAe,MAAM;AAC1B,aAAO,GAAG,OAAO,MAAM,GAAG,IAAI,OAAO;AACrC,aAAO,GAAG,WAAW,MAAM,GAAG,IAAI,cAAc;AAAA,IACjD;AAEA,WAAO,GAAG,SAAS,MAAM,GAAG,IAAI,YAAY;AAE5C,WAAO,MAAM;AACZ,aAAO,IAAI,SAAS,MAAM,GAAG,IAAI,YAAY;AAC7C,aAAO,IAAI,OAAO,MAAM,GAAG,IAAI,OAAO;AAAA,IACvC;AAAA,EACD;AACD;;;AC/BA,SAAS,YAAAA,YAAU,gBAAAa,qBAAoB;AAMhC,SAAS,uBAAuB;AAAA,EACtC;AAAA,EACA,QAAQb,WAAS;AAClB,GAAiB;AAChB,SAAO,SAAS,eACf,IACa;AACb,UAAM,yBAAyB,CAC9B,WACI;AACJ,YAAM,iBAAiB,UAAU,GAAG,GAAG,IAAI,OAAO,EAAE;AACpD,YAAM,sBAAsB,GAAG,cAAc;AAC7C,YAAM,oBAAoB,GAAG,cAAc;AAC3C,kBAAY,KAAK,mBAAmB;AACpC,MAAAa,cAAgB,IAAI,OAAO,IAAI,KAAK,EAAE,GAAG,OAAO,MAAM;AACtD,kBAAY,KAAK,iBAAiB;AAClC,YAAM,SAAS,YAAY;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,qCAAO,OAAO,KAAK,aAAM,eAAe,GAAG,KAAK,OAAO,IAAI,OAAO;AAAA,IACnE;AACA,WAAO,GAAG,UAAU,GAAG,GAAG,IAAI,sBAAsB;AAEpD,WAAO,MAAM,OAAO,IAAI,UAAU,GAAG,GAAG,IAAI,sBAAsB;AAAA,EACnE;AACD","sourcesContent":["import type { ChildProcessWithoutNullStreams } from \"child_process\"\n\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\n\nimport type { EventBuffer, Events } from \"./custom-socket\"\nimport { CustomSocket } from \"./custom-socket\"\n\nexport class ChildSocket<\n\tI extends Events,\n\tO extends Events & {\n\t\t/* eslint-disable quotes */\n\t\t\"setup-relay\": [string]\n\t\t/* eslint-enable quotes */\n\t},\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\tprotected handleLog(arg: Json.Serializable): void {\n\t\tif (Array.isArray(arg)) {\n\t\t\tconst [level, ...rest] = arg\n\t\t\tswitch (level) {\n\t\t\t\tcase `i`:\n\t\t\t\t\tthis.logger.info(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `w`:\n\t\t\t\t\tthis.logger.warn(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t\tcase `e`:\n\t\t\t\t\tthis.logger.error(this.id, this.key, ...rest)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic constructor(\n\t\tpublic process: ChildProcessWithoutNullStreams,\n\t\tpublic key: string,\n\t\tpublic logger: {\n\t\t\tinfo: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t\twarn: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t\terror: (prefix: string, message: string, ...args: unknown[]) => void\n\t\t} = console,\n\t) {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args]) + `\\x03`\n\t\t\tconst errorHandler = (err) => {\n\t\t\t\tif (err.code === `EPIPE`) {\n\t\t\t\t\tconsole.error(`EPIPE error during write`, this.process.stdin)\n\t\t\t\t}\n\t\t\t\tthis.process.stdin.removeListener(`error`, errorHandler)\n\t\t\t}\n\n\t\t\tthis.process.stdin.once(`error`, errorHandler)\n\t\t\tthis.process.stdin.write(stringifiedEvent)\n\n\t\t\treturn this\n\t\t})\n\t\tthis.process = process\n\t\tthis.process.stdout.on(\n\t\t\t`data`,\n\t\t\t<Event extends keyof I>(buffer: EventBuffer<string, I[Event]>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\n\t\t\t\tif (chunk === `✨`) {\n\t\t\t\t\t// console.log(chunk)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.unprocessedEvents.push(...chunk.split(`\\x03`))\n\t\t\t\t// console.log(`🤓`, chunk.length)\n\t\t\t\t// console.log(`🤓`, this.unprocessedEvents.length)\n\t\t\t\t// console.log(`🤓`, ...this.unprocessedEvents.map((x) => x.length))\n\t\t\t\tconst newInput = this.unprocessedEvents.shift()\n\t\t\t\tthis.incompleteData += newInput || ``\n\t\t\t\ttry {\n\t\t\t\t\tif (this.incompleteData.startsWith(`error`)) {\n\t\t\t\t\t\tconsole.log(`❗`, this.incompleteData)\n\t\t\t\t\t}\n\t\t\t\t\tconst parsedEvent = parseJson(this.incompleteData)\n\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\twhile (this.unprocessedEvents.length > 0) {\n\t\t\t\t\t\tconst event = this.unprocessedEvents.shift()\n\t\t\t\t\t\tif (event) {\n\t\t\t\t\t\t\tif (this.unprocessedEvents.length === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = event\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst parsedEvent = parseJson(event)\n\t\t\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.warn(`⚠️----------------⚠️`)\n\t\t\t\t\tconsole.warn(this.incompleteData)\n\t\t\t\t\tconsole.warn(`⚠️----------------⚠️`)\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\tthis.process.stderr.on(`data`, (buf) => {\n\t\t\tconst chunk = buf.toString()\n\t\t\tthis.unprocessedLogs.push(...chunk.split(`\\x03`))\n\t\t\t// console.log(`🤫`, chunk.length)\n\t\t\t// console.log(`🤫`, this.unprocessedLogs.length)\n\t\t\t// console.log(`🤫`, ...this.unprocessedLogs.map((x) => x.length))\n\t\t\tconst newInput = this.unprocessedLogs.shift()\n\t\t\tthis.incompleteLog += newInput || ``\n\t\t\ttry {\n\t\t\t\tconst parsedLog = parseJson(this.incompleteLog)\n\t\t\t\t// console.log(`🤫`, parsedLog)\n\t\t\t\tthis.handleLog(parsedLog)\n\t\t\t\twhile (this.unprocessedLogs.length > 0) {\n\t\t\t\t\tthis.incompleteLog = this.unprocessedLogs.shift() ?? ``\n\t\t\t\t\tif (this.incompleteLog) {\n\t\t\t\t\t\tconst parsedLog = parseJson(this.incompleteLog)\n\t\t\t\t\t\tthis.handleLog(parsedLog)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`❌❌❌`)\n\t\t\t\tconsole.error(this.incompleteLog)\n\t\t\t\tconsole.error(error)\n\t\t\t\tconsole.error(`❌❌❌️`)\n\t\t\t}\n\t\t})\n\t\tif (process.pid) {\n\t\t\tthis.id = process.pid.toString()\n\t\t}\n\t}\n}\n","import type { Json, Stringified } from \"atom.io/json\"\n\nimport type { Socket } from \"..\"\n\nexport type Events = Json.Object<string, Json.Serializable[]>\n\nexport type StringifiedEvent<\n\tKey extends string,\n\tParams extends Json.Serializable[],\n> = Stringified<[Key, ...Params]>\n\nexport interface EventBuffer<\n\tKey extends string,\n\tParams extends Json.Serializable[],\n> extends Buffer {\n\ttoString(): StringifiedEvent<Key, Params>\n}\n\nexport class CustomSocket<I extends Events, O extends Events> implements Socket {\n\tprotected listeners: Map<keyof I, Set<(...args: Json.Array) => void>>\n\tprotected globalListeners: Set<(event: string, ...args: Json.Array) => void>\n\tprotected handleEvent<Event extends keyof I>(\n\t\tevent: string,\n\t\t...args: I[Event]\n\t): void {\n\t\tfor (const listener of this.globalListeners) {\n\t\t\tlistener(event, ...args)\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(...args)\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic id = `no_id_retrieved`\n\n\tpublic constructor(\n\t\tpublic emit: <Event extends keyof O>(\n\t\t\tevent: Event,\n\t\t\t...args: O[Event]\n\t\t) => CustomSocket<I, O>,\n\t) {\n\t\tthis.listeners = new Map()\n\t\tthis.globalListeners = new Set()\n\t}\n\n\tpublic on<Event extends keyof I>(\n\t\tevent: Event,\n\t\tlistener: (...args: I[Event]) => void,\n\t): CustomSocket<I, O> {\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(\n\t\tlistener: (event: string, ...args: Json.Array) => void,\n\t): CustomSocket<I, O> {\n\t\tthis.globalListeners.add(listener)\n\t\treturn this\n\t}\n\n\tpublic off<Event extends keyof I>(\n\t\tevent: Event,\n\t\tlistener?: (...args: I[Event]) => void,\n\t): CustomSocket<I, O> {\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(\n\t\tlistener: (event: string, ...args: Json.Array) => void,\n\t): CustomSocket<I, O> {\n\t\tthis.globalListeners.delete(listener)\n\t\treturn this\n\t}\n}\n","import { IMPLICIT, Subject } from \"atom.io/internal\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\n\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\nimport { CustomSocket } from \"./custom-socket\"\nimport type { EventBuffer, Events } from \"./custom-socket\"\n\nexport class SubjectSocket<\n\tI extends Events,\n\tO extends Events,\n> extends CustomSocket<I, O> {\n\tpublic in: Subject<[string, ...Json.Serializable[]]>\n\tpublic out: Subject<[string, ...Json.Serializable[]]>\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 as [string, ...I[keyof I]]))\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 class ParentSocket<\n\tI extends Events & {\n\t\t[id in string as `user:${id}`]: [string, ...Json.Serializable[]]\n\t} & {\n\t\t/* eslint-disable quotes */\n\t\t\"user-joins\": [string]\n\t\t\"user-leaves\": [string]\n\t\t/* eslint-enable quotes */\n\t},\n\tO extends Events & {\n\t\t[id in string as `relay:${id}`]: [string, ...Json.Serializable[]]\n\t},\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) => (() => void) | void)[]\n\tprotected process: NodeJS.Process\n\n\tpublic id = `#####`\n\n\tprotected log(...args: any[]): void {\n\t\tthis.process.stderr.write(\n\t\t\tstringifyJson(\n\t\t\t\targs.map((arg) =>\n\t\t\t\t\targ instanceof SetRTX\n\t\t\t\t\t\t? `{ ${arg.toJSON().members.join(` | `)} }`\n\t\t\t\t\t\t: arg,\n\t\t\t\t),\n\t\t\t) + `\\x03`,\n\t\t)\n\t}\n\tpublic logger = {\n\t\tinfo: (...args: any[]): void => this.log(`i`, ...args),\n\t\twarn: (...args: any[]): void => this.log(`w`, ...args),\n\t\terror: (...args: any[]): void => this.log(`e`, ...args),\n\t}\n\n\tpublic constructor() {\n\t\tsuper((event, ...args) => {\n\t\t\tconst stringifiedEvent = JSON.stringify([event, ...args])\n\t\t\tthis.process.stdout.write(stringifiedEvent + `\\x03`)\n\t\t\treturn this\n\t\t})\n\t\tthis.process = process\n\t\tthis.process.stdin.resume()\n\t\tthis.relays = new Map()\n\t\tthis.relayServices = []\n\t\t// this.logger.info(`🔗`, `uplink`, process.pid)\n\n\t\tthis.process.stdin.on(\n\t\t\t`data`,\n\t\t\t<Event extends keyof I>(buffer: EventBuffer<string, I[Event]>) => {\n\t\t\t\tconst chunk = buffer.toString()\n\t\t\t\tthis.unprocessedEvents.push(...chunk.split(`\\x03`))\n\t\t\t\tconst newInput = this.unprocessedEvents.shift()\n\t\t\t\tthis.incompleteData += newInput || ``\n\n\t\t\t\ttry {\n\t\t\t\t\tconst parsedEvent = parseJson(this.incompleteData)\n\t\t\t\t\tthis.logger.info(`🎰`, `received`, parsedEvent)\n\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\twhile (this.unprocessedEvents.length > 0) {\n\t\t\t\t\t\tconst event = this.unprocessedEvents.shift()\n\t\t\t\t\t\tif (event) {\n\t\t\t\t\t\t\tif (this.unprocessedEvents.length === 0) {\n\t\t\t\t\t\t\t\tthis.incompleteData = event\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst parsedEvent = parseJson(event)\n\t\t\t\t\t\t\tthis.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.incompleteData = ``\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\tthis.logger.error(`❗`, thrown.message, thrown.cause, thrown.stack)\n\t\t\t\t\t}\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\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`exit`, (code) => {\n\t\t\tthis.logger.info(`🔥`, this.id, `exited with code ${code}`)\n\t\t})\n\t\tprocess.on(`end`, () => {\n\t\t\tthis.logger.info(`🔥`, this.id, `ended`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`SIGTERM`, () => {\n\t\t\tthis.logger.error(`🔥`, this.id, `terminated`)\n\t\t\tprocess.exit(0)\n\t\t})\n\t\tprocess.on(`SIGINT`, () => {\n\t\t\tthis.logger.error(`🔥`, this.id, `interrupted`)\n\t\t\tprocess.exit(0)\n\t\t})\n\n\t\tif (process.pid) {\n\t\t\tthis.id = process.pid?.toString()\n\t\t}\n\n\t\tthis.on(`user-joins`, (username) => {\n\t\t\tthis.logger.info(`👤`, `user`, username, `joined`)\n\t\t\tconst relay = new SubjectSocket(`user:${username}`)\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 attachServices of this.relayServices) {\n\t\t\t\tconst cleanup = attachServices(relay)\n\t\t\t\tif (cleanup) {\n\t\t\t\t\trelay.disposalFunctions.push(cleanup)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.on(`user:${username}`, (...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, ...O[keyof O]]))\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\tprocess.stdout.write(`✨`)\n\t}\n\n\tpublic relay(\n\t\tattachServices: (socket: SubjectSocket<any, any>) => (() => 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\tIMPLICIT,\n\tactUponStore,\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tisRootStore,\n\tsubscribeToState,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json, JsonIO } from \"atom.io/json\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\n\nimport type { ServerConfig, Socket } from \".\"\nimport { socketAtoms, usersOfSockets } from \".\"\n\nimport {\n\tredactTransactionUpdateContent,\n\tuserUnacknowledgedQueues,\n} from \"./realtime-server-stores\"\n\nexport type RealtimeContinuitySynchronizer = ReturnType<\n\ttypeof realtimeContinuitySynchronizer\n>\nexport function realtimeContinuitySynchronizer({\n\tsocket: initialSocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function synchronizer(continuity: ContinuityToken): () => void {\n\t\tlet socket: Socket | null = initialSocket\n\n\t\tconst continuityKey = continuity.key\n\t\tconst userKeyState = findInStore(\n\t\t\tusersOfSockets.states.userKeyOfSocket,\n\t\t\tsocket.id,\n\t\t\tstore,\n\t\t)\n\t\tconst userKey = getFromStore(userKeyState, store)\n\t\tif (!userKey) {\n\t\t\tstore.logger.error(\n\t\t\t\t`❌`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`Tried to create a synchronizer for a socket (${socket.id}) that is not connected to a user.`,\n\t\t\t)\n\t\t\treturn () => {}\n\t\t}\n\t\tconst socketKeyState = findInStore(\n\t\t\tusersOfSockets.states.socketKeyOfUser,\n\t\t\tuserKey,\n\t\t\tstore,\n\t\t)\n\t\tsubscribeToState(\n\t\t\tsocketKeyState,\n\t\t\t({ newValue: newSocketKey }) => {\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`seeing ${userKey} on new socket ${newSocketKey}`,\n\t\t\t\t)\n\t\t\t\tif (newSocketKey === null) {\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`Tried to create a synchronizer for a user (${userKey}) that is not connected to a socket.`,\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst newSocketState = findInStore(socketAtoms, newSocketKey, store)\n\t\t\t\tconst newSocket = getFromStore(newSocketState, store)\n\t\t\t\tsocket = newSocket\n\t\t\t},\n\t\t\t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\tstore,\n\t\t)\n\n\t\tconst userUnacknowledgedQueue = findInStore(\n\t\t\tuserUnacknowledgedQueues,\n\t\t\tuserKey,\n\t\t\tstore,\n\t\t)\n\t\tconst userUnacknowledgedUpdates = getFromStore(\n\t\t\tuserUnacknowledgedQueue,\n\t\t\tstore,\n\t\t)\n\t\tconst unsubscribeFunctions: (() => void)[] = []\n\n\t\tconst revealPerspectives = (): (() => void) => {\n\t\t\tconst unsubscribeFunctions: (() => void)[] = []\n\t\t\tfor (const perspective of continuity.perspectives) {\n\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\tconst userViewState = findInStore(viewAtoms, userKey, store)\n\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\tuserViewState,\n\t\t\t\t\t({ oldValue, newValue }) => {\n\t\t\t\t\t\tconst oldKeys = oldValue.map((token) => token.key)\n\t\t\t\t\t\tconst newKeys = newValue.map((token) => token.key)\n\t\t\t\t\t\tconst concealed = oldValue.filter(\n\t\t\t\t\t\t\t(token) => !newKeys.includes(token.key),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst revealed = newValue\n\t\t\t\t\t\t\t.filter((token) => !oldKeys.includes(token.key))\n\t\t\t\t\t\t\t.flatMap((token) => {\n\t\t\t\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom` ? getJsonToken(token) : token\n\t\t\t\t\t\t\t\tconst resource = getFromStore(resourceToken, store)\n\t\t\t\t\t\t\t\treturn [resourceToken, resource]\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t\t`👁`,\n\t\t\t\t\t\t\t`atom`,\n\t\t\t\t\t\t\tperspective.resourceAtoms.key,\n\t\t\t\t\t\t\t`${userKey} has a new perspective`,\n\t\t\t\t\t\t\t{ oldKeys, newKeys, revealed, concealed },\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (revealed.length > 0) {\n\t\t\t\t\t\t\tsocket?.emit(`reveal:${continuityKey}`, revealed)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (concealed.length > 0) {\n\t\t\t\t\t\t\tsocket?.emit(`conceal:${continuityKey}`, concealed)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t`sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,\n\t\t\t\t\tstore,\n\t\t\t\t)\n\t\t\t\tunsubscribeFunctions.push(unsubscribe)\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t\t}\n\t\t}\n\t\tconst unsubscribeFromPerspectives = revealPerspectives()\n\n\t\tconst sendInitialPayload = () => {\n\t\t\tconst initialPayload: Json.Serializable[] = []\n\t\t\tfor (const atom of continuity.globals) {\n\t\t\t\tconst resourceToken =\n\t\t\t\t\tatom.type === `mutable_atom` ? getJsonToken(atom) : atom\n\t\t\t\tinitialPayload.push(resourceToken, getFromStore(atom, store))\n\t\t\t}\n\t\t\tfor (const perspective of continuity.perspectives) {\n\t\t\t\tconst { viewAtoms, resourceAtoms } = perspective\n\t\t\t\tconst userViewState = findInStore(viewAtoms, userKey, store)\n\t\t\t\tconst userView = getFromStore(userViewState, store)\n\t\t\t\tstore.logger.info(`👁`, `atom`, resourceAtoms.key, `${userKey} can see`, {\n\t\t\t\t\tviewAtoms,\n\t\t\t\t\tresourceAtoms,\n\t\t\t\t\tuserView,\n\t\t\t\t})\n\t\t\t\tfor (const visibleToken of userView) {\n\t\t\t\t\tconst resourceToken =\n\t\t\t\t\t\tvisibleToken.type === `mutable_atom`\n\t\t\t\t\t\t\t? getJsonToken(visibleToken)\n\t\t\t\t\t\t\t: visibleToken\n\t\t\t\t\tconst resource = getFromStore(resourceToken, store)\n\n\t\t\t\t\tinitialPayload.push(resourceToken, resource)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst epoch = isRootStore(store)\n\t\t\t\t? store.transactionMeta.epoch.get(continuityKey) ?? null\n\t\t\t\t: null\n\n\t\t\tsocket?.emit(`continuity-init:${continuityKey}`, epoch, initialPayload)\n\n\t\t\tfor (const transaction of continuity.actions) {\n\t\t\t\tconst unsubscribeFromTransaction = subscribeToTransaction(\n\t\t\t\t\ttransaction,\n\t\t\t\t\t(update) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst visibleKeys = continuity.globals\n\t\t\t\t\t\t\t\t.map((atom) => atom.key)\n\t\t\t\t\t\t\t\t.concat(\n\t\t\t\t\t\t\t\t\tcontinuity.perspectives.flatMap((perspective) => {\n\t\t\t\t\t\t\t\t\t\tconst { viewAtoms } = perspective\n\t\t\t\t\t\t\t\t\t\tconst userPerspectiveTokenState = findInStore(\n\t\t\t\t\t\t\t\t\t\t\tviewAtoms,\n\t\t\t\t\t\t\t\t\t\t\tuserKey,\n\t\t\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tconst visibleTokens = getFromStore(\n\t\t\t\t\t\t\t\t\t\t\tuserPerspectiveTokenState,\n\t\t\t\t\t\t\t\t\t\t\tstore,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\treturn visibleTokens.map((token) => {\n\t\t\t\t\t\t\t\t\t\t\tconst key =\n\t\t\t\t\t\t\t\t\t\t\t\ttoken.type === `mutable_atom`\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `*` + token.key\n\t\t\t\t\t\t\t\t\t\t\t\t\t: token.key\n\t\t\t\t\t\t\t\t\t\t\treturn key\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst redactedUpdates = redactTransactionUpdateContent(\n\t\t\t\t\t\t\t\tvisibleKeys,\n\t\t\t\t\t\t\t\tupdate.updates,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst redactedUpdate = {\n\t\t\t\t\t\t\t\t...update,\n\t\t\t\t\t\t\t\tupdates: redactedUpdates,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// setIntoStore(\n\t\t\t\t\t\t\t// \tuserUnacknowledgedQueue,\n\t\t\t\t\t\t\t// \t(updates) => {\n\t\t\t\t\t\t\t// \t\tif (redactedUpdate) {\n\t\t\t\t\t\t\t// \t\t\tupdates.push(redactedUpdate)\n\t\t\t\t\t\t\t// \t\t\tupdates.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\t\t// \t\t}\n\t\t\t\t\t\t\t// \t\treturn updates\n\t\t\t\t\t\t\t// \t},\n\t\t\t\t\t\t\t// \tstore,\n\t\t\t\t\t\t\t// )\n\n\t\t\t\t\t\t\tsocket?.emit(\n\t\t\t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t\t\t\t\t\t\tredactedUpdate as Json.Serializable,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} catch (thrown) {\n\t\t\t\t\t\t\tif (thrown instanceof Error) {\n\t\t\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t\t\t`❌`,\n\t\t\t\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t\t\t\t`failed to send update from transaction ${transaction.key} to ${userKey}`,\n\t\t\t\t\t\t\t\t\tthrown.message,\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`sync-continuity:${continuityKey}:${userKey}`,\n\t\t\t\t\tstore,\n\t\t\t\t)\n\t\t\t\tunsubscribeFunctions.push(unsubscribeFromTransaction)\n\t\t\t}\n\t\t}\n\t\tsocket.off(`get:${continuityKey}`, sendInitialPayload)\n\t\tsocket.on(`get:${continuityKey}`, sendInitialPayload)\n\n\t\tconst fillTransactionRequest = (\n\t\t\tupdate: Pick<AtomIO.TransactionUpdate<JsonIO>, `id` | `key` | `params`>,\n\t\t) => {\n\t\t\tstore.logger.info(`🛎️`, `continuity`, continuityKey, `received`, update)\n\t\t\tconst transactionKey = update.key\n\t\t\tconst updateId = update.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\t{ type: `transaction`, key: transactionKey },\n\t\t\t\t\tupdateId,\n\t\t\t\t\tstore,\n\t\t\t\t)(...update.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} 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\tmetric.duration,\n\t\t\t)\n\n\t\t\tconst valuesOfCardsViewKey = `valuesOfCardsView(\"${userKey}\")`\n\t\t\tconst rootsOfCardValueView =\n\t\t\t\tstore.selectorAtoms.getRelatedKeys(valuesOfCardsViewKey)\n\t\t\tconst myCardValueView = store.valueMap.get(valuesOfCardsViewKey)\n\n\t\t\tstore.logger.info(\n\t\t\t\t`👁`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`seeing ${userKey} card values`,\n\t\t\t\t{\n\t\t\t\t\tvaluesOfCardsViewKey,\n\t\t\t\t\trootsOfCardValueView,\n\t\t\t\t\tmyCardValueView,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tsocket.off(`tx-run:${continuityKey}`, fillTransactionRequest)\n\t\tsocket.on(`tx-run:${continuityKey}`, fillTransactionRequest)\n\n\t\t// let i = 0\n\t\t// let n = 1\n\t\t// let retryTimeout: NodeJS.Timeout | undefined\n\t\t// const trackClientAcknowledgement = (epoch: number) => {\n\t\t// \tstore.logger.info(\n\t\t// \t\t`👍`,\n\t\t// \t\t`continuity`,\n\t\t// \t\tcontinuityKey,\n\t\t// \t\t`${userKey} acknowledged epoch ${epoch}`,\n\t\t// \t)\n\t\t// \tconst isUnacknowledged = userUnacknowledgedUpdates[0]?.epoch === epoch\n\t\t// \tif (isUnacknowledged) {\n\t\t// \t\tsetIntoStore(\n\t\t// \t\t\tuserUnacknowledgedQueue,\n\t\t// \t\t\t(updates) => {\n\t\t// \t\t\t\tupdates.shift()\n\t\t// \t\t\t\treturn updates\n\t\t// \t\t\t},\n\t\t// \t\t\tstore,\n\t\t// \t\t)\n\t\t// \t}\n\t\t// }\n\t\t// subscribeToState(\n\t\t// \tuserUnacknowledgedQueue,\n\t\t// \t({ newValue }) => {\n\t\t// \t\tif (newValue.length === 0) {\n\t\t// \t\t\tclearInterval(retryTimeout)\n\t\t// \t\t\tsocket?.off(`ack:${continuityKey}`, trackClientAcknowledgement)\n\t\t// \t\t\tretryTimeout = undefined\n\t\t// \t\t}\n\t\t// \t\tif (newValue.length > 0) {\n\t\t// \t\t\tif (retryTimeout) {\n\t\t// \t\t\t\treturn\n\t\t// \t\t\t}\n\n\t\t// \t\t\tsocket?.on(`ack:${continuityKey}`, trackClientAcknowledgement)\n\n\t\t// \t\t\tretryTimeout = setInterval(() => {\n\t\t// \t\t\t\ti++\n\t\t// \t\t\t\tif (i === n) {\n\t\t// \t\t\t\t\tn += i\n\t\t// \t\t\t\t\tconst toEmit = newValue[0]\n\t\t// \t\t\t\t\tif (!toEmit) return\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`${store.config.name} retrying ${userKey}`,\n\t\t// \t\t\t\t\t\tsocket?.id,\n\t\t// \t\t\t\t\t\tnewValue,\n\t\t// \t\t\t\t\t)\n\t\t// \t\t\t\t\tsocket?.emit(\n\t\t// \t\t\t\t\t\t`tx-new:${continuityKey}`,\n\t\t// \t\t\t\t\t\ttoEmit as Json.Serializable,\n\t\t// \t\t\t\t\t)\n\t\t// \t\t\t\t}\n\t\t// \t\t\t}, 250)\n\t\t// \t\t}\n\t\t// \t},\n\t\t// \t`sync-continuity:${continuityKey}:${userKey}`,\n\t\t// \tstore,\n\t\t// )\n\n\t\treturn () => {\n\t\t\t// clearInterval(retryTimeout)\n\t\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t\t// socket?.off(`ack:${continuityKey}`, trackClientAcknowledgement)\n\t\t\tunsubscribeFromPerspectives()\n\t\t\tsocket?.off(`get:${continuityKey}`, sendInitialPayload)\n\t\t\tsocket?.off(`tx-run:${continuityKey}`, fillTransactionRequest)\n\t\t}\n\t}\n}\n","import { selectorFamily } from \"atom.io\"\nimport type { TransactionUpdate } from \"atom.io\"\nimport { IMPLICIT, getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { JsonIO } from \"atom.io/json\"\nimport { SyncGroup } from \"atom.io/realtime\"\n// import { completeUpdateAtoms } from \"atom.io/realtime-server\"\n\nconst redactorAtoms = selectorFamily<\n\t(update: TransactionUpdate<any>) => TransactionUpdate<any>,\n\t{ userId: string; syncGroupKey: string }\n>({\n\tkey: `perspectiveRedactor`,\n\tget:\n\t\t({ userId, syncGroupKey }) =>\n\t\t({ get, find }) => {\n\t\t\tconst syncGroup = SyncGroup.existing.get(syncGroupKey)\n\t\t\tif (!syncGroup) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tried to create a synchronizer for a sync group that does not exist.`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst userPerspectiveTokens = syncGroup.perspectives.flatMap(\n\t\t\t\t({ viewAtoms }) => {\n\t\t\t\t\tconst userPerspectiveToken = find(viewAtoms, userId)\n\t\t\t\t\tconst userPerspective = get(userPerspectiveToken)\n\t\t\t\t\tconst visibleTokens = [...userPerspective].map((token) => {\n\t\t\t\t\t\treturn token.type === `mutable_atom`\n\t\t\t\t\t\t\t? getUpdateToken(token).key\n\t\t\t\t\t\t\t: token.key\n\t\t\t\t\t})\n\t\t\t\t\tIMPLICIT.STORE.logger.info(\n\t\t\t\t\t\t`🔭`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tsyncGroupKey,\n\t\t\t\t\t\t`${userId} can see ${visibleTokens.length} tokens in ${viewAtoms.key}`,\n\t\t\t\t\t\tvisibleTokens,\n\t\t\t\t\t)\n\t\t\t\t\treturn visibleTokens\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tconst filterTransactionUpdate = (\n\t\t\t\tvisible: string[],\n\t\t\t\ttransactionUpdate: TransactionUpdate<any>,\n\t\t\t): TransactionUpdate<any> => {\n\t\t\t\tIMPLICIT.STORE.logger.info(\n\t\t\t\t\t`🖌`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tsyncGroupKey,\n\t\t\t\t\t`redacting updates from ${transactionUpdate.epoch}:${transactionUpdate.key}:${transactionUpdate.id}`,\n\t\t\t\t\tvisible,\n\t\t\t\t\ttransactionUpdate.updates,\n\t\t\t\t)\n\t\t\t\tconst updates = transactionUpdate.updates\n\t\t\t\t\t.filter((update) => {\n\t\t\t\t\t\tif (`newValue` in update) {\n\t\t\t\t\t\t\treturn visible.includes(update.key)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true\n\t\t\t\t\t})\n\t\t\t\t\t.map((update) => {\n\t\t\t\t\t\tif (`updates` in update) {\n\t\t\t\t\t\t\treturn filterTransactionUpdate(visible, update)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn update\n\t\t\t\t\t})\n\t\t\t\tconst filtered: TransactionUpdate<any> = {\n\t\t\t\t\t...transactionUpdate,\n\t\t\t\t\tupdates,\n\t\t\t\t}\n\t\t\t\treturn filtered\n\t\t\t}\n\t\t\tconst filter: (updates: TransactionUpdate<any>) => TransactionUpdate<any> =\n\t\t\t\t(update) => {\n\t\t\t\t\tconst visibleKeys: string[] = syncGroup.globals.map((atomToken) =>\n\t\t\t\t\t\tatomToken.type === `mutable_atom`\n\t\t\t\t\t\t\t? getUpdateToken(atomToken).key\n\t\t\t\t\t\t\t: atomToken.key,\n\t\t\t\t\t)\n\t\t\t\t\tvisibleKeys.push(...userPerspectiveTokens)\n\t\t\t\t\treturn filterTransactionUpdate(visibleKeys, update)\n\t\t\t\t}\n\t\t\treturn filter\n\t\t},\n})\n// export const occludedUpdateSelectors = selectorFamily<\n// \tPick<\n// \t\tTransactionUpdate<JsonIO>,\n// \t\t`epoch` | `id` | `key` | `output` | `updates`\n// \t> | null,\n// \t{ userId: string; syncGroupKey: string; updateId: string }\n// >({\n// \tkey: `occludedUpdate`,\n// \tget:\n// \t\t({ userId, syncGroupKey, updateId }) =>\n// \t\t({ get, find }) => {\n// \t\t\tconst updateState = find(completeUpdateAtoms, updateId)\n// \t\t\tconst update = get(updateState)\n// \t\t\tconst redactorKey = { userId, syncGroupKey }\n// \t\t\tconst redactorState = find(redactorAtoms, redactorKey)\n// \t\t\tconst redact = get(redactorState)\n// \t\t\tif (update) {\n// \t\t\t\t// return redact(update)\n// \t\t\t\treturn update\n// \t\t\t}\n// \t\t\treturn null\n// \t\t},\n// })\n","import * as AtomIO from \"atom.io\"\nimport type { Loadable } from \"atom.io/data\"\nimport type { UserInRoomMeta } from \"atom.io/realtime\"\nimport { roomIndex, usersInRooms } from \"atom.io/realtime\"\n\nimport type { ChildSocket } from \"../ipc-sockets\"\nimport type { RoomArguments } from \"./server-room-external-store\"\nimport { roomArgumentsAtoms, roomSelectors } from \"./server-room-external-store\"\n\nexport const createRoomTX = AtomIO.transaction<\n\t(\n\t\troomId: string,\n\t\tscript: string,\n\t\toptions?: string[],\n\t) => Loadable<ChildSocket<any, any>>\n>({\n\tkey: `createRoom`,\n\tdo: ({ get, set, find }, roomId, script, options) => {\n\t\tconst args: RoomArguments = options ? [script, options] : [script]\n\t\tconst roomArgumentsState = find(roomArgumentsAtoms, roomId)\n\t\tset(roomArgumentsState, args)\n\t\tset(roomIndex, (s) => s.add(roomId))\n\t\tconst roomState = find(roomSelectors, roomId)\n\t\tconst room = get(roomState)\n\t\treturn room\n\t},\n})\nexport type CreateRoomIO = AtomIO.TransactionIO<typeof createRoomTX>\n\nexport const joinRoomTX = AtomIO.transaction<\n\t(roomId: string, userId: string, enteredAtEpoch: number) => UserInRoomMeta\n>({\n\tkey: `joinRoom`,\n\tdo: (transactors, roomId, userId, enteredAtEpoch) => {\n\t\tconst meta = { enteredAtEpoch }\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.set(roomId, userId, meta)\n\t\t})\n\t\treturn meta\n\t},\n})\nexport type JoinRoomIO = AtomIO.TransactionIO<typeof joinRoomTX>\n\nexport const leaveRoomTX = AtomIO.transaction<\n\t(roomId: string, userId: string) => void\n>({\n\tkey: `leaveRoom`,\n\tdo: (transactors, roomId, userId) => {\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.delete({ room: roomId, user: userId })\n\t\t})\n\t},\n})\nexport type LeaveRoomIO = AtomIO.TransactionIO<typeof leaveRoomTX>\n\nexport const destroyRoomTX = AtomIO.transaction<(roomId: string) => void>({\n\tkey: `destroyRoom`,\n\tdo: (transactors, roomId) => {\n\t\tusersInRooms.transact(transactors, ({ relations }) => {\n\t\t\trelations.delete({ room: roomId })\n\t\t})\n\t\ttransactors.set(roomIndex, (s) => (s.delete(roomId), s))\n\t},\n})\n","import type { ChildProcessWithoutNullStreams } from \"child_process\"\nimport { spawn } from \"child_process\"\n\nimport { atomFamily, selectorFamily } from \"atom.io\"\nimport type { Loadable } from \"atom.io/data\"\nimport { ChildSocket } from \"../ipc-sockets\"\n\nexport type RoomArguments =\n\t| [script: string, options: string[]]\n\t| [script: string]\n\nexport const roomArgumentsAtoms = atomFamily<RoomArguments, string>({\n\tkey: `roomArguments`,\n\tdefault: [`echo`, [`Hello World!`]],\n})\n\nexport const roomSelectors = selectorFamily<\n\tLoadable<ChildSocket<any, any>>,\n\tstring\n>({\n\tkey: `room`,\n\tget:\n\t\t(roomId) =>\n\t\tasync ({ get, find }) => {\n\t\t\tconst argumentsState = find(roomArgumentsAtoms, roomId)\n\t\t\tconst args = get(argumentsState)\n\t\t\tconst [script, options] = args\n\t\t\tconst child = await new Promise<ChildProcessWithoutNullStreams>(\n\t\t\t\t(resolve) => {\n\t\t\t\t\tconst room = spawn(script, options, { env: process.env })\n\t\t\t\t\tconst resolver = (data: Buffer) => {\n\t\t\t\t\t\tif (data.toString() === `✨`) {\n\t\t\t\t\t\t\troom.stdout.off(`data`, resolver)\n\t\t\t\t\t\t\tresolve(room)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\troom.stdout.on(`data`, resolver)\n\t\t\t\t},\n\t\t\t)\n\t\t\treturn new ChildSocket(child, roomId)\n\t\t},\n})\n","import type { TransactionUpdate, TransactionUpdateContent } from \"atom.io\"\nimport { atomFamily, selectorFamily } from \"atom.io\"\n\n// export const completeUpdateAtoms = atomFamily<\n// \tTransactionUpdate<any> | null,\n// \tstring\n// >({\n// \tkey: `completeUpdate`,\n// \tdefault: null,\n// })\n\nexport function redactTransactionUpdateContent(\n\tvisibleStateKeys: string[],\n\tupdates: TransactionUpdateContent[],\n): TransactionUpdateContent[] {\n\treturn updates\n\t\t.map((update): TransactionUpdateContent => {\n\t\t\tif (`newValue` in update) {\n\t\t\t\treturn update\n\t\t\t}\n\t\t\tconst redacted = redactTransactionUpdateContent(\n\t\t\t\tvisibleStateKeys,\n\t\t\t\tupdate.updates,\n\t\t\t)\n\t\t\treturn { ...update, updates: redacted }\n\t\t})\n\t\t.filter((update) => {\n\t\t\tif (`newValue` in update) {\n\t\t\t\treturn visibleStateKeys.includes(update.key)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n}\n\nexport const actionOcclusionAtoms = atomFamily<\n\t{\n\t\tocclude: (updates: TransactionUpdateContent[]) => TransactionUpdateContent[]\n\t},\n\tstring\n>({\n\tkey: `transactionRedactor`,\n\tdefault: { occlude: (updates) => updates },\n})\n// export const redactedUpdateSelectors = selectorFamily<\n// \tTransactionUpdate<any> | null,\n// \t[transactionKey: string, updateId: string]\n// >({\n// \tkey: `redactedUpdate`,\n// \tget:\n// \t\t([transactionKey, updateId]) =>\n// \t\t({ get, find }) => {\n// \t\t\tconst update = get(find(completeUpdateAtoms, updateId))\n// \t\t\tconst { filter } = get(find(transactionRedactorAtoms, transactionKey))\n\n// \t\t\tif (update && filter) {\n// \t\t\t\treturn { ...update, updates: filter(update.updates) }\n// \t\t\t}\n// \t\t\treturn null\n// \t\t},\n// })\n\nexport const userUnacknowledgedQueues = atomFamily<\n\tPick<TransactionUpdate<any>, `epoch` | `id` | `key` | `output` | `updates`>[],\n\tstring\n>({\n\tkey: `unacknowledgedUpdates`,\n\tdefault: () => [],\n})\n","import { atom, atomFamily } from \"atom.io\"\nimport { join } from \"atom.io/data\"\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\n\nimport type { Socket } from \"..\"\n\nexport const socketAtoms = atomFamily<Socket | null, string>({\n\tkey: `sockets`,\n\tdefault: null,\n})\n\nexport const socketIndex = atom({\n\tkey: `socketsIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\nexport const userIndex = atom({\n\tkey: `usersIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\nexport const usersOfSockets = join({\n\tkey: `usersOfSockets`,\n\tbetween: [`user`, `socket`],\n\tcardinality: `1:1`,\n})\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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\tlet unsubscribeFromStateUpdates: (() => void) | undefined\n\n\t\tconst fillSubRequest = () => {\n\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(token, store))\n\n\t\t\tunsubscribeFromStateUpdates = subscribeToState(\n\t\t\t\ttoken,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t},\n\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\tstore,\n\t\t\t)\n\n\t\t\tconst fillUnsubRequest = () => {\n\t\t\t\tsocket.off(`unsub:${token.key}`, fillUnsubRequest)\n\t\t\t\tif (unsubscribeFromStateUpdates) {\n\t\t\t\t\tunsubscribeFromStateUpdates()\n\t\t\t\t\tunsubscribeFromStateUpdates = undefined\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsocket.on(`unsub:${token.key}`, fillUnsubRequest)\n\t\t}\n\n\t\tsocket.on(`sub:${token.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${token.key}`, fillSubRequest)\n\t\t\tif (unsubscribeFromStateUpdates) {\n\t\t\t\tunsubscribeFromStateUpdates()\n\t\t\t\tunsubscribeFromStateUpdates = undefined\n\t\t\t}\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, getFromStore } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\n\nexport function realtimeStateSynchronizer({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function stateSynchronizer<J extends Json.Serializable>(\n\t\ttoken: AtomIO.WritableToken<J>,\n\t): () => void {\n\t\tconst fillGetRequest = () => {\n\t\t\tsocket.emit(`value:${token.key}`, getFromStore(token, store))\n\t\t}\n\n\t\tsocket.on(`get:${token.key}`, fillGetRequest)\n\t\treturn () => {\n\t\t\tsocket.off(`get:${token.key}`, fillGetRequest)\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tfindInStore,\n\tgetFromStore,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport { type Json, stringifyJson } from \"atom.io/json\"\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 Json.Serializable,\n\t>(\n\t\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst unsubCallbacksByKey = new Map<string, () => void>()\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tsocket.off(`unsub:${key}`, fillUnsubRequest)\n\t\t\tconst unsub = unsubCallbacksByKey.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tunsubCallbacksByKey.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst fillSubRequest = (subKey: K) => {\n\t\t\tconst exposedSubKeys = getFromStore(index, store)\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\tconst token = findInStore(family, subKey, store)\n\t\t\t\t\tsocket.emit(`serve:${token.key}`, getFromStore(token, store))\n\t\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\tsocket.emit(`serve:${token.key}`, newValue)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t\tstore,\n\t\t\t\t\t)\n\t\t\t\t\tunsubCallbacksByKey.set(token.key, unsubscribe)\n\t\t\t\t\tsocket.on(`unsub:${token.key}`, () => {\n\t\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsocket.on(`sub:${family.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${family.key}`, fillSubRequest)\n\n\t\t\tfor (const [, unsub] of unsubCallbacksByKey) {\n\t\t\t\tunsub()\n\t\t\t}\n\t\t\tunsubCallbacksByKey.clear()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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<Json.Serializable>,\n\t\tSerializableCore extends Json.Serializable,\n\t>(token: AtomIO.MutableAtomToken<Core, SerializableCore>): () => void {\n\t\tlet unsubscribeFromStateUpdates: (() => void) | null = null\n\n\t\tconst jsonToken = getJsonToken(token)\n\t\tconst trackerToken = getUpdateToken(token)\n\n\t\tconst fillUnsubRequest = () => {\n\t\t\tsocket.off(`unsub:${token.key}`, fillUnsubRequest)\n\t\t\tunsubscribeFromStateUpdates?.()\n\t\t\tunsubscribeFromStateUpdates = null\n\t\t}\n\n\t\tconst fillSubRequest = () => {\n\t\t\tsocket.emit(`init:${token.key}`, getFromStore(jsonToken, store))\n\t\t\tunsubscribeFromStateUpdates = subscribeToState(\n\t\t\t\ttrackerToken,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t},\n\t\t\t\t`expose-single:${socket.id}`,\n\t\t\t\tstore,\n\t\t\t)\n\t\t\tsocket.on(`unsub:${token.key}`, fillUnsubRequest)\n\t\t}\n\n\t\tsocket.on(`sub:${token.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${token.key}`, fillSubRequest)\n\t\t\tunsubscribeFromStateUpdates?.()\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport {\n\tIMPLICIT,\n\tfindInStore,\n\tgetFromStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsubscribeToState,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\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>,\n\t\tJ extends Json.Serializable,\n\t\tK extends Json.Serializable,\n\t>(\n\t\tfamily: AtomIO.MutableAtomFamilyToken<T, J, K>,\n\t\tindex: AtomIO.ReadableToken<Iterable<K>>,\n\t): () => void {\n\t\tconst unsubCallbacksByKey = new Map<string, () => void>()\n\n\t\tconst fillUnsubRequest = (key: string) => {\n\t\t\tsocket.off(`unsub:${key}`, fillUnsubRequest)\n\t\t\tconst unsub = unsubCallbacksByKey.get(key)\n\t\t\tif (unsub) {\n\t\t\t\tunsub()\n\t\t\t\tunsubCallbacksByKey.delete(key)\n\t\t\t}\n\t\t}\n\n\t\tconst fillSubRequest = (subKey: K) => {\n\t\t\tconst exposedSubKeys = getFromStore(index, store)\n\t\t\tfor (const exposedSubKey of exposedSubKeys) {\n\t\t\t\tif (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {\n\t\t\t\t\tconst token = findInStore(family, subKey, store)\n\t\t\t\t\tconst jsonToken = getJsonToken(token)\n\t\t\t\t\tconst updateToken = getUpdateToken(token)\n\t\t\t\t\tsocket.emit(`init:${token.key}`, getFromStore(jsonToken, store))\n\t\t\t\t\tconst unsubscribe = subscribeToState(\n\t\t\t\t\t\tupdateToken,\n\t\t\t\t\t\t({ newValue }) => {\n\t\t\t\t\t\t\tsocket.emit(`next:${token.key}`, newValue)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t`expose-family:${family.key}:${socket.id}`,\n\t\t\t\t\t\tstore,\n\t\t\t\t\t)\n\t\t\t\t\tunsubCallbacksByKey.set(token.key, unsubscribe)\n\t\t\t\t\tsocket.on(`unsub:${token.key}`, () => {\n\t\t\t\t\t\tfillUnsubRequest(token.key)\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsocket.on(`sub:${family.key}`, fillSubRequest)\n\n\t\treturn () => {\n\t\t\tsocket.off(`sub:${family.key}`, fillSubRequest)\n\t\t\tfor (const [, unsub] of unsubCallbacksByKey) {\n\t\t\t\tunsub()\n\t\t\t}\n\t\t\tunsubCallbacksByKey.clear()\n\t\t}\n\t}\n}\n","import type { WritableToken } from \"atom.io\"\nimport { IMPLICIT, setIntoStore } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\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<J extends Json.Serializable>(\n\t\ttoken: WritableToken<J>,\n\t): () => void {\n\t\tconst publish = (newValue: J) => setIntoStore(token, newValue, store)\n\n\t\tconst fillPubUnclaim = () => {\n\t\t\tsocket.off(`pub:${token.key}`, publish)\n\t\t\tsocket.off(`unclaim:${token.key}`, fillPubUnclaim)\n\t\t}\n\t\tconst fillPubClaim = () => {\n\t\t\tsocket.on(`pub:${token.key}`, publish)\n\t\t\tsocket.on(`unclaim:${token.key}`, fillPubUnclaim)\n\t\t}\n\n\t\tsocket.on(`claim:${token.key}`, fillPubClaim)\n\n\t\treturn () => {\n\t\t\tsocket.off(`claim:${token.key}`, fillPubClaim)\n\t\t\tsocket.off(`pub:${token.key}`, publish)\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { IMPLICIT, actUponStore } from \"atom.io/internal\"\nimport type { JsonIO } from \"atom.io/json\"\n\nimport type { ServerConfig } from \".\"\n\nexport type ActionReceiver = ReturnType<typeof realtimeActionReceiver>\nexport function realtimeActionReceiver({\n\tsocket,\n\tstore = IMPLICIT.STORE,\n}: ServerConfig) {\n\treturn function actionReceiver<ƒ extends JsonIO>(\n\t\ttx: AtomIO.TransactionToken<ƒ>,\n\t): () => void {\n\t\tconst fillTransactionRequest = (\n\t\t\tupdate: Pick<AtomIO.TransactionUpdate<ƒ>, `id` | `params`>,\n\t\t) => {\n\t\t\tconst performanceKey = `tx-run:${tx.key}:${update.id}`\n\t\t\tconst performanceKeyStart = `${performanceKey}:start`\n\t\t\tconst performanceKeyEnd = `${performanceKey}:end`\n\t\t\tperformance.mark(performanceKeyStart)\n\t\t\tactUponStore<ƒ>(tx, update.id, store)(...update.params)\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(`🚀`, `transaction`, tx.key, update.id, metric.duration)\n\t\t}\n\t\tsocket.on(`tx-run:${tx.key}`, fillTransactionRequest)\n\n\t\treturn () => socket.off(`tx-run:${tx.key}`, fillTransactionRequest)\n\t}\n}\n"]}
@@ -85,6 +85,7 @@ export class ParentSocket<
85
85
  this.process.stdin.resume()
86
86
  this.relays = new Map()
87
87
  this.relayServices = []
88
+ // this.logger.info(`🔗`, `uplink`, process.pid)
88
89
 
89
90
  this.process.stdin.on(
90
91
  `data`,
@@ -118,11 +119,11 @@ export class ParentSocket<
118
119
  )
119
120
 
120
121
  this.on(`exit`, () => {
122
+ this.logger.info(`🔥`, this.id, `received "exit"`)
121
123
  process.exit(0)
122
124
  })
123
- process.on(`exit`, () => {
124
- this.logger.info(`🔥`, this.id, `exited`)
125
- process.exit(0)
125
+ process.on(`exit`, (code) => {
126
+ this.logger.info(`🔥`, this.id, `exited with code ${code}`)
126
127
  })
127
128
  process.on(`end`, () => {
128
129
  this.logger.info(`🔥`, this.id, `ended`)
@@ -62,6 +62,47 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
62
62
 
63
63
  // ../anvl/src/object/entries.ts
64
64
  var recordToEntries = (obj) => Object.entries(obj);
65
+
66
+ // __unstable__/web-effects/src/storage.ts
67
+ var persistAtom = (storage) => ({ stringify, parse }) => (key) => ({ setSelf, onSet }) => {
68
+ const savedValue = storage.getItem(key);
69
+ if (savedValue != null)
70
+ setSelf(parse(savedValue));
71
+ onSet(({ newValue }) => {
72
+ if (newValue == null) {
73
+ storage.removeItem(key);
74
+ return;
75
+ }
76
+ storage.setItem(key, stringify(newValue));
77
+ });
78
+ };
79
+ var lazyLocalStorageEffect = persistAtom(window.localStorage)(JSON);
80
+
81
+ // realtime-client/src/realtime-client-stores/client-main-store.ts
82
+ var myIdState__INTERNAL = AtomIO__namespace.atom({
83
+ key: `mySocketId__INTERNAL`,
84
+ default: void 0
85
+ });
86
+ AtomIO__namespace.selector({
87
+ key: `mySocketId`,
88
+ get: ({ get }) => get(myIdState__INTERNAL)
89
+ });
90
+ var usernameEffects = typeof window === `undefined` ? [] : [lazyLocalStorageEffect(`myUsername`)];
91
+ var myUsernameState = AtomIO__namespace.atom({
92
+ key: `myUsername`,
93
+ default: null,
94
+ effects: usernameEffects
95
+ });
96
+ AtomIO__namespace.atom({
97
+ key: `updateQueue`,
98
+ default: []
99
+ });
100
+ AtomIO__namespace.atom(
101
+ {
102
+ key: `serverConfirmedUpdateQueue`,
103
+ default: []
104
+ }
105
+ );
65
106
  var testNumber = 0;
66
107
  var setupRealtimeTestServer = (options) => {
67
108
  ++testNumber;
@@ -121,6 +162,7 @@ var setupRealtimeTestClient = (options, name, port) => {
121
162
  silo.store.valueMap.set(key, [...value]);
122
163
  }
123
164
  }
165
+ silo.setState(myUsernameState, `${name}-${testNumber}`);
124
166
  const { document } = new Happy__namespace.Window();
125
167
  document.body.innerHTML = `<div id="app"></div>`;
126
168
  const renderResult = react.render(
@@ -148,11 +190,7 @@ var setupRealtimeTestClient = (options, name, port) => {
148
190
  };
149
191
  var singleClient = (options) => {
150
192
  const server = setupRealtimeTestServer(options);
151
- const client = setupRealtimeTestClient(
152
- options,
153
- `CLIENT-${testNumber}`,
154
- server.port
155
- );
193
+ const client = setupRealtimeTestClient(options, `CLIENT`, server.port);
156
194
  return {
157
195
  client,
158
196
  server,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/setup-realtime-test.tsx","../../../anvl/src/object/entries.ts"],"names":["usersOfSockets","clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { prettyDOM, render } from \"@testing-library/react\"\nimport type { RenderResult } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tclearStore,\n\tfindInStore,\n\tgetFromStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTR from \"atom.io/realtime-react\"\nimport * as RTS from \"atom.io/realtime-server\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\n\nlet testNumber = 0\n\nexport type TestSetupOptions = {\n\tport: number\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\tsocket: ClientSocket\n}\nexport type RealtimeTestClientBuilder = {\n\tdispose: () => void\n\tinit: () => RealtimeTestClient\n}\n\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tdispose: () => void\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClientBuilder\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClientBuilder>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\t++testNumber\n\tconst silo = new AtomIO.Silo(`SERVER-${testNumber}`, IMPLICIT.STORE)\n\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen(options.port).address()\n\tconst port =\n\t\ttypeof address === `string` ? null : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\n\tconst server = new SocketIO.Server(httpServer).use((socket, next) => {\n\t\tconst { token, username } = socket.handshake.auth\n\t\tif (token === `test` && socket.id) {\n\t\t\tconst socketState = findInStore(RTS.socketAtoms, socket.id, silo.store)\n\t\t\tsetIntoStore(socketState, socket, silo.store)\n\t\t\tconst usersOfSockets = RTS.usersOfSockets.in(silo.store)\n\t\t\tusersOfSockets.relations.set(socket.id, username)\n\t\t\tsetIntoStore(RTS.userIndex, (index) => index.add(username), silo.store)\n\t\t\tsetIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store)\n\t\t\tconsole.log(`${username} connected on ${socket.id}`)\n\t\t\tnext()\n\t\t} else {\n\t\t\tnext(new Error(`Authentication error`))\n\t\t}\n\t})\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tconst roomKeys = getFromStore(RT.roomIndex, silo.store)\n\t\tfor (const roomKey of roomKeys) {\n\t\t\tconst roomState = findInStore(RTS.roomSelectors, roomKey, silo.store)\n\t\t\tconst room = getFromStore(roomState, silo.store)\n\t\t\tif (room && !(room instanceof Promise)) {\n\t\t\t\troom.process.kill()\n\t\t\t}\n\t\t}\n\t\tsilo.store.valueMap.clear()\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClientBuilder => {\n\tconst testClient = { dispose: () => {} }\n\tconst init = () => {\n\t\tconst socket: ClientSocket = io(`http://localhost:${port}/`, {\n\t\t\tauth: { token: `test`, username: `${name}-${testNumber}` },\n\t\t})\n\t\tconst silo = new AtomIO.Silo(name, IMPLICIT.STORE)\n\t\tfor (const [key, value] of silo.store.valueMap.entries()) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tsilo.store.valueMap.set(key, [...value])\n\t\t\t}\n\t\t}\n\n\t\tconst { document } = new Happy.Window()\n\t\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\t\tconst renderResult = render(\n\t\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t\t<RTR.RealtimeProvider socket={socket}>\n\t\t\t\t\t<options.client />\n\t\t\t\t</RTR.RealtimeProvider>\n\t\t\t</AR.StoreProvider>,\n\t\t\t{\n\t\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t\t},\n\t\t)\n\n\t\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\t\tconst dispose = () => {\n\t\t\trenderResult.unmount()\n\t\t\tsocket.disconnect()\n\t\t\tclearStore(silo.store)\n\t\t}\n\t\ttestClient.dispose = dispose\n\n\t\treturn {\n\t\t\tname,\n\t\t\tsilo,\n\t\t\tsocket,\n\t\t\trenderResult,\n\t\t\tprettyPrint,\n\t\t}\n\t}\n\treturn Object.assign(testClient, { init })\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(\n\t\toptions,\n\t\t`CLIENT-${testNumber}`,\n\t\tserver.port,\n\t)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tclient.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => {\n\t\t\tclients[name] = setupRealtimeTestClient(\n\t\t\t\t{ ...options, client },\n\t\t\t\tname,\n\t\t\t\tserver.port,\n\t\t\t)\n\t\t\treturn clients\n\t\t},\n\t\t{} as Record<ClientNames, RealtimeTestClientBuilder>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tfor (const [, client] of recordToEntries(clients)) {\n\t\t\t\tclient.dispose()\n\t\t\t}\n\t\t},\n\t}\n}\n","export type Entries<K extends keyof any, V> = [key: K, value: V][]\n\nexport const recordToEntries = <K extends keyof any, V>(\n\tobj: Record<K, V>,\n): Entries<K, V> => Object.entries(obj) as Entries<K, V>\n\nexport const entriesToRecord = <K extends keyof any, V>(\n\tentries: Entries<K, V>,\n): Record<K, V> => Object.fromEntries(entries) as Record<K, V>\n"]}
1
+ {"version":3,"sources":["../src/setup-realtime-test.tsx","../../../anvl/src/object/entries.ts","../../realtime-client/src/realtime-client-stores/client-main-store.ts","../../__unstable__/web-effects/src/storage.ts","../../realtime-client/src/realtime-client-stores/client-sync-store.ts"],"names":["AtomIO","usersOfSockets","clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { prettyDOM, render } from \"@testing-library/react\"\nimport type { RenderResult } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tclearStore,\n\tfindInStore,\n\tgetFromStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTR from \"atom.io/realtime-react\"\nimport * as RTS from \"atom.io/realtime-server\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\nimport { myUsernameState } from \"../../realtime-client/src/realtime-client-stores\"\n\nlet testNumber = 0\n\nexport type TestSetupOptions = {\n\tport: number\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\tsocket: ClientSocket\n}\nexport type RealtimeTestClientBuilder = {\n\tdispose: () => void\n\tinit: () => RealtimeTestClient\n}\n\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tdispose: () => void\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClientBuilder\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClientBuilder>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\t++testNumber\n\tconst silo = new AtomIO.Silo(`SERVER-${testNumber}`, IMPLICIT.STORE)\n\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen(options.port).address()\n\tconst port =\n\t\ttypeof address === `string` ? null : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\n\tconst server = new SocketIO.Server(httpServer).use((socket, next) => {\n\t\tconst { token, username } = socket.handshake.auth\n\t\tif (token === `test` && socket.id) {\n\t\t\tconst socketState = findInStore(RTS.socketAtoms, socket.id, silo.store)\n\t\t\tsetIntoStore(socketState, socket, silo.store)\n\t\t\tconst usersOfSockets = RTS.usersOfSockets.in(silo.store)\n\t\t\tusersOfSockets.relations.set(socket.id, username)\n\t\t\tsetIntoStore(RTS.userIndex, (index) => index.add(username), silo.store)\n\t\t\tsetIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store)\n\t\t\tconsole.log(`${username} connected on ${socket.id}`)\n\t\t\tnext()\n\t\t} else {\n\t\t\tnext(new Error(`Authentication error`))\n\t\t}\n\t})\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tconst roomKeys = getFromStore(RT.roomIndex, silo.store)\n\t\tfor (const roomKey of roomKeys) {\n\t\t\tconst roomState = findInStore(RTS.roomSelectors, roomKey, silo.store)\n\t\t\tconst room = getFromStore(roomState, silo.store)\n\t\t\tif (room && !(room instanceof Promise)) {\n\t\t\t\troom.process.kill()\n\t\t\t}\n\t\t}\n\t\tsilo.store.valueMap.clear()\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClientBuilder => {\n\tconst testClient = { dispose: () => {} }\n\tconst init = () => {\n\t\tconst socket: ClientSocket = io(`http://localhost:${port}/`, {\n\t\t\tauth: { token: `test`, username: `${name}-${testNumber}` },\n\t\t})\n\t\tconst silo = new AtomIO.Silo(name, IMPLICIT.STORE)\n\t\tfor (const [key, value] of silo.store.valueMap.entries()) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tsilo.store.valueMap.set(key, [...value])\n\t\t\t}\n\t\t}\n\t\tsilo.setState(myUsernameState, `${name}-${testNumber}`)\n\n\t\tconst { document } = new Happy.Window()\n\t\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\t\tconst renderResult = render(\n\t\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t\t<RTR.RealtimeProvider socket={socket}>\n\t\t\t\t\t<options.client />\n\t\t\t\t</RTR.RealtimeProvider>\n\t\t\t</AR.StoreProvider>,\n\t\t\t{\n\t\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t\t},\n\t\t)\n\n\t\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\t\tconst dispose = () => {\n\t\t\trenderResult.unmount()\n\t\t\tsocket.disconnect()\n\t\t\tclearStore(silo.store)\n\t\t}\n\t\ttestClient.dispose = dispose\n\n\t\treturn {\n\t\t\tname,\n\t\t\tsilo,\n\t\t\tsocket,\n\t\t\trenderResult,\n\t\t\tprettyPrint,\n\t\t}\n\t}\n\treturn Object.assign(testClient, { init })\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(options, `CLIENT`, server.port)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tclient.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => {\n\t\t\tclients[name] = setupRealtimeTestClient(\n\t\t\t\t{ ...options, client },\n\t\t\t\tname,\n\t\t\t\tserver.port,\n\t\t\t)\n\t\t\treturn clients\n\t\t},\n\t\t{} as Record<ClientNames, RealtimeTestClientBuilder>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tfor (const [, client] of recordToEntries(clients)) {\n\t\t\t\tclient.dispose()\n\t\t\t}\n\t\t},\n\t}\n}\n","export type Entries<K extends keyof any, V> = [key: K, value: V][]\n\nexport const recordToEntries = <K extends keyof any, V>(\n\tobj: Record<K, V>,\n): Entries<K, V> => Object.entries(obj) as Entries<K, V>\n\nexport const entriesToRecord = <K extends keyof any, V>(\n\tentries: Entries<K, V>,\n): Record<K, V> => Object.fromEntries(entries) as Record<K, V>\n","import * as AtomIO from \"atom.io\"\n\nimport { lazyLocalStorageEffect } from \"~/packages/atom.io/__unstable__/web-effects/src/storage\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | undefined>({\n\tkey: `mySocketId__INTERNAL`,\n\tdefault: undefined,\n})\nexport const myIdState = AtomIO.selector<string | undefined>({\n\tkey: `mySocketId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n\nconst usernameEffects =\n\ttypeof window === `undefined` ? [] : [lazyLocalStorageEffect(`myUsername`)]\nexport const myUsernameState = AtomIO.atom<string | null>({\n\tkey: `myUsername`,\n\tdefault: null,\n\teffects: usernameEffects,\n})\n","import type { AtomEffect } from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\n\nexport type StringInterface<T> = {\n\tstringify: (t: T) => string\n\tparse: (s: string) => T\n}\n\nexport const persistAtom =\n\t<T>(storage: Storage) =>\n\t({ stringify, parse }: StringInterface<T>) =>\n\t(key: string): AtomEffect<T> =>\n\t({ setSelf, onSet }) => {\n\t\tconst savedValue = storage.getItem(key)\n\t\tif (savedValue != null) setSelf(parse(savedValue))\n\n\t\tonSet(({ newValue }) => {\n\t\t\tif (newValue == null) {\n\t\t\t\tstorage.removeItem(key)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstorage.setItem(key, stringify(newValue))\n\t\t})\n\t}\n\nexport const lazyLocalStorageEffect: <J extends Json.Serializable>(\n\tkey: string,\n) => AtomEffect<J> = persistAtom(window.localStorage)(JSON)\n","import * as AtomIO from \"atom.io\"\n\nexport const optimisticUpdateQueue = AtomIO.atom<\n\tAtomIO.TransactionUpdate<any>[]\n>({\n\tkey: `updateQueue`,\n\tdefault: [],\n})\n\nexport const confirmedUpdateQueue = AtomIO.atom<AtomIO.TransactionUpdate<any>[]>(\n\t{\n\t\tkey: `serverConfirmedUpdateQueue`,\n\t\tdefault: [],\n\t},\n)\n"]}
@@ -1,4 +1,6 @@
1
+ import { myUsernameState } from '../../dist/chunk-3J2EGSBE.js';
1
2
  import { recordToEntries } from '../../dist/chunk-NYCVSXQB.js';
3
+ import '../../dist/chunk-A4ZCNKWQ.js';
2
4
  import { __spreadProps, __spreadValues } from '../../dist/chunk-PZLG2HP3.js';
3
5
  import * as http from 'http';
4
6
  import { render, prettyDOM } from '@testing-library/react';
@@ -72,6 +74,7 @@ var setupRealtimeTestClient = (options, name, port) => {
72
74
  silo.store.valueMap.set(key, [...value]);
73
75
  }
74
76
  }
77
+ silo.setState(myUsernameState, `${name}-${testNumber}`);
75
78
  const { document } = new Happy.Window();
76
79
  document.body.innerHTML = `<div id="app"></div>`;
77
80
  const renderResult = render(
@@ -99,11 +102,7 @@ var setupRealtimeTestClient = (options, name, port) => {
99
102
  };
100
103
  var singleClient = (options) => {
101
104
  const server = setupRealtimeTestServer(options);
102
- const client = setupRealtimeTestClient(
103
- options,
104
- `CLIENT-${testNumber}`,
105
- server.port
106
- );
105
+ const client = setupRealtimeTestClient(options, `CLIENT`, server.port);
107
106
  return {
108
107
  client,
109
108
  server,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/setup-realtime-test.tsx"],"names":["usersOfSockets","clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { prettyDOM, render } from \"@testing-library/react\"\nimport type { RenderResult } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tclearStore,\n\tfindInStore,\n\tgetFromStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTR from \"atom.io/realtime-react\"\nimport * as RTS from \"atom.io/realtime-server\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\n\nlet testNumber = 0\n\nexport type TestSetupOptions = {\n\tport: number\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\tsocket: ClientSocket\n}\nexport type RealtimeTestClientBuilder = {\n\tdispose: () => void\n\tinit: () => RealtimeTestClient\n}\n\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tdispose: () => void\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClientBuilder\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClientBuilder>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\t++testNumber\n\tconst silo = new AtomIO.Silo(`SERVER-${testNumber}`, IMPLICIT.STORE)\n\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen(options.port).address()\n\tconst port =\n\t\ttypeof address === `string` ? null : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\n\tconst server = new SocketIO.Server(httpServer).use((socket, next) => {\n\t\tconst { token, username } = socket.handshake.auth\n\t\tif (token === `test` && socket.id) {\n\t\t\tconst socketState = findInStore(RTS.socketAtoms, socket.id, silo.store)\n\t\t\tsetIntoStore(socketState, socket, silo.store)\n\t\t\tconst usersOfSockets = RTS.usersOfSockets.in(silo.store)\n\t\t\tusersOfSockets.relations.set(socket.id, username)\n\t\t\tsetIntoStore(RTS.userIndex, (index) => index.add(username), silo.store)\n\t\t\tsetIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store)\n\t\t\tconsole.log(`${username} connected on ${socket.id}`)\n\t\t\tnext()\n\t\t} else {\n\t\t\tnext(new Error(`Authentication error`))\n\t\t}\n\t})\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tconst roomKeys = getFromStore(RT.roomIndex, silo.store)\n\t\tfor (const roomKey of roomKeys) {\n\t\t\tconst roomState = findInStore(RTS.roomSelectors, roomKey, silo.store)\n\t\t\tconst room = getFromStore(roomState, silo.store)\n\t\t\tif (room && !(room instanceof Promise)) {\n\t\t\t\troom.process.kill()\n\t\t\t}\n\t\t}\n\t\tsilo.store.valueMap.clear()\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClientBuilder => {\n\tconst testClient = { dispose: () => {} }\n\tconst init = () => {\n\t\tconst socket: ClientSocket = io(`http://localhost:${port}/`, {\n\t\t\tauth: { token: `test`, username: `${name}-${testNumber}` },\n\t\t})\n\t\tconst silo = new AtomIO.Silo(name, IMPLICIT.STORE)\n\t\tfor (const [key, value] of silo.store.valueMap.entries()) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tsilo.store.valueMap.set(key, [...value])\n\t\t\t}\n\t\t}\n\n\t\tconst { document } = new Happy.Window()\n\t\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\t\tconst renderResult = render(\n\t\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t\t<RTR.RealtimeProvider socket={socket}>\n\t\t\t\t\t<options.client />\n\t\t\t\t</RTR.RealtimeProvider>\n\t\t\t</AR.StoreProvider>,\n\t\t\t{\n\t\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t\t},\n\t\t)\n\n\t\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\t\tconst dispose = () => {\n\t\t\trenderResult.unmount()\n\t\t\tsocket.disconnect()\n\t\t\tclearStore(silo.store)\n\t\t}\n\t\ttestClient.dispose = dispose\n\n\t\treturn {\n\t\t\tname,\n\t\t\tsilo,\n\t\t\tsocket,\n\t\t\trenderResult,\n\t\t\tprettyPrint,\n\t\t}\n\t}\n\treturn Object.assign(testClient, { init })\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(\n\t\toptions,\n\t\t`CLIENT-${testNumber}`,\n\t\tserver.port,\n\t)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tclient.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => {\n\t\t\tclients[name] = setupRealtimeTestClient(\n\t\t\t\t{ ...options, client },\n\t\t\t\tname,\n\t\t\t\tserver.port,\n\t\t\t)\n\t\t\treturn clients\n\t\t},\n\t\t{} as Record<ClientNames, RealtimeTestClientBuilder>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tfor (const [, client] of recordToEntries(clients)) {\n\t\t\t\tclient.dispose()\n\t\t\t}\n\t\t},\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/setup-realtime-test.tsx"],"names":["usersOfSockets","clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { prettyDOM, render } from \"@testing-library/react\"\nimport type { RenderResult } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tclearStore,\n\tfindInStore,\n\tgetFromStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTR from \"atom.io/realtime-react\"\nimport * as RTS from \"atom.io/realtime-server\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\nimport { myUsernameState } from \"../../realtime-client/src/realtime-client-stores\"\n\nlet testNumber = 0\n\nexport type TestSetupOptions = {\n\tport: number\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\tsocket: ClientSocket\n}\nexport type RealtimeTestClientBuilder = {\n\tdispose: () => void\n\tinit: () => RealtimeTestClient\n}\n\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tdispose: () => void\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClientBuilder\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClientBuilder>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\t++testNumber\n\tconst silo = new AtomIO.Silo(`SERVER-${testNumber}`, IMPLICIT.STORE)\n\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen(options.port).address()\n\tconst port =\n\t\ttypeof address === `string` ? null : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\n\tconst server = new SocketIO.Server(httpServer).use((socket, next) => {\n\t\tconst { token, username } = socket.handshake.auth\n\t\tif (token === `test` && socket.id) {\n\t\t\tconst socketState = findInStore(RTS.socketAtoms, socket.id, silo.store)\n\t\t\tsetIntoStore(socketState, socket, silo.store)\n\t\t\tconst usersOfSockets = RTS.usersOfSockets.in(silo.store)\n\t\t\tusersOfSockets.relations.set(socket.id, username)\n\t\t\tsetIntoStore(RTS.userIndex, (index) => index.add(username), silo.store)\n\t\t\tsetIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store)\n\t\t\tconsole.log(`${username} connected on ${socket.id}`)\n\t\t\tnext()\n\t\t} else {\n\t\t\tnext(new Error(`Authentication error`))\n\t\t}\n\t})\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tconst roomKeys = getFromStore(RT.roomIndex, silo.store)\n\t\tfor (const roomKey of roomKeys) {\n\t\t\tconst roomState = findInStore(RTS.roomSelectors, roomKey, silo.store)\n\t\t\tconst room = getFromStore(roomState, silo.store)\n\t\t\tif (room && !(room instanceof Promise)) {\n\t\t\t\troom.process.kill()\n\t\t\t}\n\t\t}\n\t\tsilo.store.valueMap.clear()\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClientBuilder => {\n\tconst testClient = { dispose: () => {} }\n\tconst init = () => {\n\t\tconst socket: ClientSocket = io(`http://localhost:${port}/`, {\n\t\t\tauth: { token: `test`, username: `${name}-${testNumber}` },\n\t\t})\n\t\tconst silo = new AtomIO.Silo(name, IMPLICIT.STORE)\n\t\tfor (const [key, value] of silo.store.valueMap.entries()) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tsilo.store.valueMap.set(key, [...value])\n\t\t\t}\n\t\t}\n\t\tsilo.setState(myUsernameState, `${name}-${testNumber}`)\n\n\t\tconst { document } = new Happy.Window()\n\t\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\t\tconst renderResult = render(\n\t\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t\t<RTR.RealtimeProvider socket={socket}>\n\t\t\t\t\t<options.client />\n\t\t\t\t</RTR.RealtimeProvider>\n\t\t\t</AR.StoreProvider>,\n\t\t\t{\n\t\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t\t},\n\t\t)\n\n\t\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\t\tconst dispose = () => {\n\t\t\trenderResult.unmount()\n\t\t\tsocket.disconnect()\n\t\t\tclearStore(silo.store)\n\t\t}\n\t\ttestClient.dispose = dispose\n\n\t\treturn {\n\t\t\tname,\n\t\t\tsilo,\n\t\t\tsocket,\n\t\t\trenderResult,\n\t\t\tprettyPrint,\n\t\t}\n\t}\n\treturn Object.assign(testClient, { init })\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(options, `CLIENT`, server.port)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tclient.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => {\n\t\t\tclients[name] = setupRealtimeTestClient(\n\t\t\t\t{ ...options, client },\n\t\t\t\tname,\n\t\t\t\tserver.port,\n\t\t\t)\n\t\t\treturn clients\n\t\t},\n\t\t{} as Record<ClientNames, RealtimeTestClientBuilder>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tserver.dispose()\n\t\t\tfor (const [, client] of recordToEntries(clients)) {\n\t\t\t\tclient.dispose()\n\t\t\t}\n\t\t},\n\t}\n}\n"]}
@@ -21,6 +21,7 @@ import type { Socket as ClientSocket } from "socket.io-client"
21
21
  import { io } from "socket.io-client"
22
22
 
23
23
  import { recordToEntries } from "~/packages/anvl/src/object"
24
+ import { myUsernameState } from "../../realtime-client/src/realtime-client-stores"
24
25
 
25
26
  let testNumber = 0
26
27
 
@@ -137,6 +138,7 @@ export const setupRealtimeTestClient = (
137
138
  silo.store.valueMap.set(key, [...value])
138
139
  }
139
140
  }
141
+ silo.setState(myUsernameState, `${name}-${testNumber}`)
140
142
 
141
143
  const { document } = new Happy.Window()
142
144
  document.body.innerHTML = `<div id="app"></div>`
@@ -175,11 +177,7 @@ export const singleClient = (
175
177
  options: TestSetupOptions__SingleClient,
176
178
  ): RealtimeTestAPI__SingleClient => {
177
179
  const server = setupRealtimeTestServer(options)
178
- const client = setupRealtimeTestClient(
179
- options,
180
- `CLIENT-${testNumber}`,
181
- server.port,
182
- )
180
+ const client = setupRealtimeTestClient(options, `CLIENT`, server.port)
183
181
 
184
182
  return {
185
183
  client,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../__unstable__/web-effects/src/storage.ts"],"names":[],"mappings":";AAQO,IAAM,cACZ,CAAI,YACJ,CAAC,EAAE,WAAW,MAAM,MACpB,CAAC,QACD,CAAC,EAAE,SAAS,MAAM,MAAM;AACvB,QAAM,aAAa,QAAQ,QAAQ,GAAG;AAEtC,MAAI,cAAc;AAAM,YAAQ,MAAM,UAAU,CAAC;AAEjD,QAAM,CAAC,EAAE,SAAS,MAAM;AACvB,QAAI,YAAY,MAAM;AACrB,cAAQ,WAAW,GAAG;AACtB;AAAA,IACD;AACA,YAAQ,QAAQ,KAAK,UAAU,QAAQ,CAAC;AAAA,EACzC,CAAC;AACF;AAEM,IAAM,yBAEQ,YAAY,YAAY,EAAE,IAAI","sourcesContent":["import type { AtomEffect } from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\n\nexport type StringInterface<T> = {\n\tstringify: (t: T) => string\n\tparse: (s: string) => T\n}\n\nexport const persistAtom =\n\t<T>(storage: Storage) =>\n\t({ stringify, parse }: StringInterface<T>) =>\n\t(key: string): AtomEffect<T> =>\n\t({ setSelf, onSet }) => {\n\t\tconst savedValue = storage.getItem(key)\n\n\t\tif (savedValue != null) setSelf(parse(savedValue))\n\n\t\tonSet(({ newValue }) => {\n\t\t\tif (newValue == null) {\n\t\t\t\tstorage.removeItem(key)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstorage.setItem(key, stringify(newValue))\n\t\t})\n\t}\n\nexport const lazyLocalStorageEffect: <J extends Json.Serializable>(\n\tkey: string,\n) => AtomEffect<J> = persistAtom(localStorage)(JSON)\n"]}