atom.io 0.31.1 → 0.32.1

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 (162) hide show
  1. package/data/dist/index.d.ts +3 -154
  2. package/data/dist/index.js +11 -559
  3. package/data/src/index.ts +0 -2
  4. package/data/src/struct-family.ts +1 -1
  5. package/data/src/struct.ts +1 -2
  6. package/dist/chunk-3PQTWLQQ.js +83 -0
  7. package/dist/chunk-3ZFTRSNG.js +523 -0
  8. package/dist/chunk-4LWKCEW3.js +14 -0
  9. package/dist/chunk-KVI5OBF2.js +153 -0
  10. package/dist/{chunk-Y5MBNTVU.js → chunk-UQEYZ3OI.js} +1814 -721
  11. package/dist/chunk-UYYKOGZQ.js +1034 -0
  12. package/dist/chunk-VRJP2PCU.js +631 -0
  13. package/dist/chunk-X7SD2NXU.js +108 -0
  14. package/dist/index.d.ts +137 -12
  15. package/dist/index.js +1 -228
  16. package/eslint-plugin/dist/index.d.ts +1 -30
  17. package/eslint-plugin/dist/index.js +3 -149
  18. package/eslint-plugin/src/index.ts +0 -1
  19. package/eslint-plugin/src/rules/explicit-state-types.ts +1 -0
  20. package/eslint-plugin/src/rules/index.ts +0 -1
  21. package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -0
  22. package/eslint-plugin/src/walk.ts +1 -0
  23. package/internal/dist/index.d.ts +129 -58
  24. package/internal/dist/index.js +1 -1
  25. package/internal/src/atom/create-regular-atom.ts +3 -3
  26. package/internal/src/atom/dispose-atom.ts +4 -13
  27. package/internal/src/atom/is-default.ts +3 -3
  28. package/internal/src/caching.ts +5 -5
  29. package/internal/src/capitalize.ts +3 -0
  30. package/internal/src/families/create-readonly-selector-family.ts +5 -6
  31. package/internal/src/families/create-writable-selector-family.ts +1 -4
  32. package/internal/src/families/dispose-from-store.ts +3 -13
  33. package/internal/src/get-state/get-from-store.ts +2 -2
  34. package/internal/src/get-state/read-or-compute-value.ts +1 -1
  35. package/internal/src/index.ts +2 -0
  36. package/internal/src/install-into-store.ts +1 -1
  37. package/internal/src/join/edit-relations-in-store.ts +32 -0
  38. package/internal/src/join/find-relations-in-store.ts +124 -0
  39. package/internal/src/join/get-internal-relations-from-store.ts +14 -0
  40. package/internal/src/join/get-join.ts +31 -0
  41. package/internal/src/join/index.ts +5 -0
  42. package/{data/src/join.ts → internal/src/join/join-internal.ts} +21 -430
  43. package/internal/src/junction.ts +7 -4
  44. package/internal/src/keys.ts +7 -7
  45. package/internal/src/mutable/create-mutable-atom-family.ts +1 -1
  46. package/internal/src/mutable/create-mutable-atom.ts +3 -3
  47. package/internal/src/mutable/get-json-token.ts +1 -1
  48. package/internal/src/mutable/tracker-family.ts +19 -17
  49. package/internal/src/mutable/tracker.ts +8 -8
  50. package/internal/src/pretty-print.ts +1 -1
  51. package/internal/src/selector/create-readonly-selector.ts +3 -7
  52. package/internal/src/selector/create-writable-selector.ts +4 -4
  53. package/internal/src/selector/dispose-selector.ts +20 -11
  54. package/internal/src/selector/get-selector-dependency-keys.ts +1 -1
  55. package/internal/src/selector/register-selector.ts +6 -9
  56. package/internal/src/selector/trace-selector-atoms.ts +2 -2
  57. package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
  58. package/internal/src/set-state/emit-update.ts +4 -2
  59. package/internal/src/set-state/evict-downstream.ts +1 -1
  60. package/internal/src/set-state/set-atom-or-selector.ts +1 -1
  61. package/internal/src/set-state/set-atom.ts +10 -10
  62. package/internal/src/set-state/set-into-store.ts +2 -2
  63. package/internal/src/set-state/stow-update.ts +1 -1
  64. package/internal/src/store/store.ts +1 -1
  65. package/internal/src/store/withdraw.ts +22 -22
  66. package/internal/src/subscribe/recall-state.ts +1 -1
  67. package/internal/src/subscribe/subscribe-in-store.ts +3 -3
  68. package/internal/src/subscribe/subscribe-to-root-atoms.ts +3 -3
  69. package/internal/src/subscribe/subscribe-to-state.ts +5 -5
  70. package/internal/src/subscribe/subscribe-to-timeline.ts +3 -3
  71. package/internal/src/subscribe/subscribe-to-transaction.ts +3 -3
  72. package/internal/src/timeline/create-timeline.ts +19 -38
  73. package/internal/src/timeline/time-travel.ts +2 -1
  74. package/internal/src/transaction/act-upon-store.ts +2 -2
  75. package/internal/src/transaction/apply-transaction.ts +5 -5
  76. package/internal/src/transaction/assign-transaction-to-continuity.ts +1 -1
  77. package/internal/src/transaction/build-transaction.ts +5 -8
  78. package/internal/src/transaction/create-transaction.ts +3 -3
  79. package/internal/src/transaction/get-epoch-number.ts +3 -3
  80. package/internal/src/transaction/set-epoch-number.ts +2 -2
  81. package/introspection/dist/index.js +2 -620
  82. package/json/dist/index.d.ts +2 -2
  83. package/json/dist/index.js +1 -80
  84. package/json/src/select-json-family.ts +3 -14
  85. package/package.json +31 -49
  86. package/react/dist/index.js +2 -82
  87. package/react/src/use-o.ts +1 -1
  88. package/react/src/use-tl.ts +2 -2
  89. package/react-devtools/dist/index.css +16 -14
  90. package/react-devtools/dist/index.js +31 -18
  91. package/react-devtools/src/Updates.tsx +12 -0
  92. package/react-devtools/src/devtools.scss +16 -14
  93. package/react-devtools/src/json-editor/editors-by-type/utilities/cast-to-json.ts +2 -1
  94. package/realtime/dist/index.d.ts +1 -2
  95. package/realtime/dist/index.js +2 -107
  96. package/realtime/src/realtime-continuity.ts +3 -2
  97. package/realtime/src/shared-room-store.ts +1 -2
  98. package/realtime-client/dist/index.d.ts +9 -9
  99. package/realtime-client/dist/index.js +3 -509
  100. package/realtime-client/src/continuity/register-and-attempt-confirmed-update.ts +3 -3
  101. package/realtime-client/src/continuity/use-conceal-state.ts +1 -1
  102. package/realtime-client/src/pull-atom-family-member.ts +2 -2
  103. package/realtime-client/src/pull-atom.ts +2 -2
  104. package/realtime-client/src/pull-mutable-atom-family-member.ts +2 -2
  105. package/realtime-client/src/pull-mutable-atom.ts +2 -2
  106. package/realtime-client/src/pull-selector-family-member.ts +4 -4
  107. package/realtime-client/src/pull-selector.ts +4 -4
  108. package/realtime-client/src/push-state.ts +5 -10
  109. package/realtime-client/src/server-action.ts +4 -4
  110. package/realtime-client/src/sync-continuity.ts +6 -6
  111. package/realtime-react/dist/index.js +5 -154
  112. package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
  113. package/realtime-react/src/use-pull-atom.ts +1 -1
  114. package/realtime-react/src/use-pull-mutable-atom.ts +1 -1
  115. package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
  116. package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
  117. package/realtime-react/src/use-pull-selector.ts +1 -1
  118. package/realtime-react/src/use-push.ts +1 -1
  119. package/realtime-react/src/use-server-action.ts +2 -2
  120. package/realtime-react/src/use-sync-continuity.ts +1 -1
  121. package/realtime-server/dist/index.d.ts +2 -4
  122. package/realtime-server/dist/index.js +3 -1001
  123. package/realtime-server/src/continuity/prepare-to-serve-transaction-request.ts +1 -1
  124. package/realtime-server/src/continuity/prepare-to-sync-realtime-continuity.ts +3 -3
  125. package/realtime-server/src/continuity/subscribe-to-continuity-actions.ts +2 -2
  126. package/realtime-server/src/continuity/subscribe-to-continuity-perpectives.ts +2 -2
  127. package/realtime-server/src/ipc-sockets/child-socket.ts +2 -0
  128. package/realtime-server/src/realtime-action-receiver.ts +1 -1
  129. package/realtime-server/src/realtime-family-provider.ts +2 -2
  130. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -2
  131. package/realtime-server/src/realtime-mutable-provider.ts +2 -2
  132. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +2 -1
  133. package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +1 -1
  134. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +10 -2
  135. package/realtime-server/src/realtime-server-stores/server-user-store.ts +1 -2
  136. package/realtime-server/src/realtime-state-provider.ts +2 -2
  137. package/realtime-testing/dist/index.js +20 -22
  138. package/realtime-testing/src/setup-realtime-test.tsx +2 -1
  139. package/src/index.ts +4 -0
  140. package/src/join.ts +218 -0
  141. package/src/silo.ts +4 -4
  142. package/src/timeline.ts +1 -1
  143. package/src/transaction.ts +4 -8
  144. package/transceivers/set-rtx/dist/index.d.ts +4 -3
  145. package/transceivers/set-rtx/dist/index.js +1 -215
  146. package/transceivers/set-rtx/src/set-rtx.ts +4 -7
  147. package/web/dist/index.js +1 -15
  148. package/data/src/until.ts +0 -15
  149. package/ephemeral/dist/index.d.ts +0 -67
  150. package/ephemeral/dist/index.js +0 -9
  151. package/ephemeral/package.json +0 -13
  152. package/ephemeral/src/index.ts +0 -1
  153. package/eslint-plugin/src/rules/lifespan.ts +0 -203
  154. package/immortal/dist/index.d.ts +0 -12
  155. package/immortal/dist/index.js +0 -9
  156. package/immortal/package.json +0 -13
  157. package/immortal/src/index.ts +0 -1
  158. package/immortal/src/seek-state.ts +0 -60
  159. package/react-devtools/src/json-editor/assets/Untitled-1.ai +2 -1436
  160. package/react-devtools/src/json-editor/assets/data-vis.ai +1 -1548
  161. package/react-devtools/src/json-editor/comp/json-editor-sketches.ai +5 -1449
  162. /package/{ephemeral/src → src}/find-state.ts +0 -0
@@ -0,0 +1,1034 @@
1
+ import { roomIndex, usersInRooms } from './chunk-X7SD2NXU.js';
2
+ import { atomFamily, selectorFamily, transaction, editRelationsInStore, atom, SetRTX, join, parseJson, Subject, stringifyJson, findRelationsInStore, IMPLICIT, getFromStore, subscribeToState, findInStore, getJsonToken, getUpdateToken, actUponStore, setIntoStore, subscribeToTransaction, isRootStore } from './chunk-UQEYZ3OI.js';
3
+ import { spawn } from 'node:child_process';
4
+
5
+ // realtime-server/src/ipc-sockets/custom-socket.ts
6
+ var CustomSocket = class {
7
+ constructor(emit) {
8
+ this.emit = emit;
9
+ this.listeners = /* @__PURE__ */ new Map();
10
+ this.globalListeners = /* @__PURE__ */ new Set();
11
+ }
12
+ listeners;
13
+ globalListeners;
14
+ handleEvent(event, ...args) {
15
+ for (const listener of this.globalListeners) {
16
+ listener(event, ...args);
17
+ }
18
+ const listeners = this.listeners.get(event);
19
+ if (listeners) {
20
+ for (const listener of listeners) {
21
+ listener(...args);
22
+ }
23
+ }
24
+ }
25
+ id = `no_id_retrieved`;
26
+ on(event, listener) {
27
+ const listeners = this.listeners.get(event);
28
+ if (listeners) {
29
+ listeners.add(listener);
30
+ } else {
31
+ this.listeners.set(event, /* @__PURE__ */ new Set([listener]));
32
+ }
33
+ return this;
34
+ }
35
+ onAny(listener) {
36
+ this.globalListeners.add(listener);
37
+ return this;
38
+ }
39
+ off(event, listener) {
40
+ const listeners = this.listeners.get(event);
41
+ if (listeners) {
42
+ if (listener) {
43
+ listeners.delete(listener);
44
+ } else {
45
+ this.listeners.delete(event);
46
+ }
47
+ }
48
+ return this;
49
+ }
50
+ offAny(listener) {
51
+ this.globalListeners.delete(listener);
52
+ return this;
53
+ }
54
+ };
55
+
56
+ // realtime-server/src/ipc-sockets/child-socket.ts
57
+ var ChildSocket = class extends CustomSocket {
58
+ incompleteData = ``;
59
+ unprocessedEvents = [];
60
+ incompleteLog = ``;
61
+ unprocessedLogs = [];
62
+ id = `#####`;
63
+ process;
64
+ key;
65
+ logger;
66
+ handleLog(arg) {
67
+ if (Array.isArray(arg)) {
68
+ const [level, ...rest] = arg;
69
+ switch (level) {
70
+ case `i`:
71
+ this.logger.info(...rest);
72
+ break;
73
+ case `w`:
74
+ this.logger.warn(...rest);
75
+ break;
76
+ case `e`:
77
+ this.logger.error(...rest);
78
+ break;
79
+ default:
80
+ return;
81
+ }
82
+ }
83
+ }
84
+ constructor(process2, key, logger) {
85
+ super((event, ...args) => {
86
+ const stringifiedEvent = JSON.stringify([event, ...args]) + ``;
87
+ const errorHandler = (err) => {
88
+ if (err.code === `EPIPE`) {
89
+ console.error(`EPIPE error during write`, this.process.stdin);
90
+ }
91
+ this.process.stdin.removeListener(`error`, errorHandler);
92
+ };
93
+ this.process.stdin.once(`error`, errorHandler);
94
+ this.process.stdin.write(stringifiedEvent);
95
+ return this;
96
+ });
97
+ this.process = process2;
98
+ this.key = key;
99
+ this.logger = logger ?? {
100
+ info: (...args) => {
101
+ console.info(this.id, this.key, ...args);
102
+ },
103
+ warn: (...args) => {
104
+ console.warn(this.id, this.key, ...args);
105
+ },
106
+ error: (...args) => {
107
+ console.error(this.id, this.key, ...args);
108
+ }
109
+ };
110
+ this.process.stdout.on(
111
+ `data`,
112
+ (buffer) => {
113
+ const chunk = buffer.toString();
114
+ if (chunk === `ALIVE`) {
115
+ return;
116
+ }
117
+ this.unprocessedEvents.push(...chunk.split(``));
118
+ const newInput = this.unprocessedEvents.shift();
119
+ this.incompleteData += newInput ?? ``;
120
+ try {
121
+ if (this.incompleteData.startsWith(`error`)) {
122
+ console.log(`\u2757`, this.incompleteData);
123
+ }
124
+ let parsedEvent = parseJson(this.incompleteData);
125
+ this.handleEvent(...parsedEvent);
126
+ while (this.unprocessedEvents.length > 0) {
127
+ const event = this.unprocessedEvents.shift();
128
+ if (event) {
129
+ if (this.unprocessedEvents.length === 0) {
130
+ this.incompleteData = event;
131
+ }
132
+ parsedEvent = parseJson(event);
133
+ this.handleEvent(...parsedEvent);
134
+ }
135
+ }
136
+ this.incompleteData = ``;
137
+ } catch (error) {
138
+ console.warn(`\u26A0\uFE0F----------------\u26A0\uFE0F`);
139
+ console.warn(this.incompleteData);
140
+ console.warn(`\u26A0\uFE0F----------------\u26A0\uFE0F`);
141
+ console.error(error);
142
+ }
143
+ }
144
+ );
145
+ this.process.stderr.on(`data`, (buf) => {
146
+ const chunk = buf.toString();
147
+ this.unprocessedLogs.push(...chunk.split(``));
148
+ const newInput = this.unprocessedLogs.shift();
149
+ this.incompleteLog += newInput ?? ``;
150
+ try {
151
+ let parsedLog = parseJson(this.incompleteLog);
152
+ this.handleLog(parsedLog);
153
+ while (this.unprocessedLogs.length > 0) {
154
+ this.incompleteLog = this.unprocessedLogs.shift() ?? ``;
155
+ if (this.incompleteLog) {
156
+ parsedLog = parseJson(this.incompleteLog);
157
+ this.handleLog(parsedLog);
158
+ }
159
+ }
160
+ } catch (error) {
161
+ console.error(`\u274C\u274C\u274C`);
162
+ console.error(this.incompleteLog);
163
+ console.error(error);
164
+ console.error(`\u274C\u274C\u274C\uFE0F`);
165
+ }
166
+ });
167
+ if (process2.pid) {
168
+ this.id = process2.pid.toString();
169
+ }
170
+ }
171
+ };
172
+
173
+ // realtime-server/src/ipc-sockets/parent-socket.ts
174
+ var SubjectSocket = class extends CustomSocket {
175
+ in;
176
+ out;
177
+ id = `no_id_retrieved`;
178
+ disposalFunctions = [];
179
+ constructor(id) {
180
+ super((...args) => {
181
+ this.out.next(args);
182
+ return this;
183
+ });
184
+ this.id = id;
185
+ this.in = new Subject();
186
+ this.out = new Subject();
187
+ this.in.subscribe(`socket`, (event) => {
188
+ this.handleEvent(...event);
189
+ });
190
+ }
191
+ dispose() {
192
+ for (const dispose of this.disposalFunctions) {
193
+ dispose();
194
+ }
195
+ }
196
+ };
197
+ var ParentSocket = class extends CustomSocket {
198
+ incompleteData = ``;
199
+ unprocessedEvents = [];
200
+ relays;
201
+ relayServices;
202
+ process;
203
+ id = `#####`;
204
+ log(...args) {
205
+ this.process.stderr.write(
206
+ stringifyJson(
207
+ args.map(
208
+ (arg) => arg instanceof SetRTX ? `{ ${arg.toJSON().members.join(` | `)} }` : arg
209
+ )
210
+ ) + ``
211
+ );
212
+ }
213
+ logger = {
214
+ info: (...args) => {
215
+ this.log(`i`, ...args);
216
+ },
217
+ warn: (...args) => {
218
+ this.log(`w`, ...args);
219
+ },
220
+ error: (...args) => {
221
+ this.log(`e`, ...args);
222
+ }
223
+ };
224
+ constructor() {
225
+ super((event, ...args) => {
226
+ const stringifiedEvent = JSON.stringify([event, ...args]);
227
+ this.process.stdout.write(stringifiedEvent + ``);
228
+ return this;
229
+ });
230
+ this.process = process;
231
+ this.process.stdin.resume();
232
+ this.relays = /* @__PURE__ */ new Map();
233
+ this.relayServices = [];
234
+ this.process.stdin.on(
235
+ `data`,
236
+ (buffer) => {
237
+ const chunk = buffer.toString();
238
+ this.unprocessedEvents.push(...chunk.split(``));
239
+ const newInput = this.unprocessedEvents.shift();
240
+ this.incompleteData += newInput ?? ``;
241
+ try {
242
+ const parsedData = parseJson(this.incompleteData);
243
+ this.logger.info(`\u{1F3B0}`, `received`, parsedData);
244
+ this.handleEvent(...parsedData);
245
+ while (this.unprocessedEvents.length > 0) {
246
+ const event = this.unprocessedEvents.shift();
247
+ if (event) {
248
+ if (this.unprocessedEvents.length === 0) {
249
+ this.incompleteData = event;
250
+ }
251
+ const parsedEvent = parseJson(event);
252
+ this.handleEvent(...parsedEvent);
253
+ }
254
+ }
255
+ this.incompleteData = ``;
256
+ } catch (thrown) {
257
+ if (thrown instanceof Error) {
258
+ this.logger.error(`\u2757`, thrown.message, thrown.cause, thrown.stack);
259
+ }
260
+ }
261
+ }
262
+ );
263
+ this.on(`exit`, () => {
264
+ this.logger.info(`\u{1F525}`, this.id, `received "exit"`);
265
+ process.exit(0);
266
+ });
267
+ process.on(`exit`, (code) => {
268
+ this.logger.info(`\u{1F525}`, this.id, `exited with code ${code}`);
269
+ });
270
+ process.on(`end`, () => {
271
+ this.logger.info(`\u{1F525}`, this.id, `ended`);
272
+ process.exit(0);
273
+ });
274
+ process.on(`SIGTERM`, () => {
275
+ this.logger.error(`\u{1F525}`, this.id, `terminated`);
276
+ process.exit(0);
277
+ });
278
+ process.on(`SIGINT`, () => {
279
+ this.logger.error(`\u{1F525}`, this.id, `interrupted`);
280
+ process.exit(0);
281
+ });
282
+ if (process.pid) {
283
+ this.id = process.pid?.toString();
284
+ }
285
+ this.on(`user-joins`, (username) => {
286
+ this.logger.info(`\u{1F464}`, `user`, username, `joined`);
287
+ const relay = new SubjectSocket(`user:${username}`);
288
+ this.relays.set(username, relay);
289
+ this.logger.info(
290
+ `\u{1F517}`,
291
+ `attaching services:`,
292
+ `[${[...this.relayServices.keys()].join(`, `)}]`
293
+ );
294
+ for (const attachServices of this.relayServices) {
295
+ const cleanup = attachServices(relay);
296
+ if (cleanup) {
297
+ relay.disposalFunctions.push(cleanup);
298
+ }
299
+ }
300
+ this.on(`user:${username}`, (...data) => {
301
+ relay.in.next(data);
302
+ });
303
+ relay.out.subscribe(`socket`, (data) => {
304
+ this.emit(...data);
305
+ });
306
+ });
307
+ this.on(`user-leaves`, (username) => {
308
+ const relay = this.relays.get(username);
309
+ this.off(`relay:${username}`);
310
+ if (relay) {
311
+ relay.dispose();
312
+ this.relays.delete(username);
313
+ }
314
+ });
315
+ process.stdout.write(`ALIVE`);
316
+ }
317
+ relay(attachServices) {
318
+ this.logger.info(`\u{1F517}`, `running relay method`);
319
+ this.relayServices.push(attachServices);
320
+ }
321
+ };
322
+
323
+ // realtime-server/src/realtime-server-stores/server-room-external-store.ts
324
+ var roomArgumentsAtoms = atomFamily({
325
+ key: `roomArguments`,
326
+ default: [`echo`, [`Hello World!`]]
327
+ });
328
+ var roomSelectors = selectorFamily({
329
+ key: `room`,
330
+ get: (roomId) => async ({ get, find }) => {
331
+ const argumentsState = find(roomArgumentsAtoms, roomId);
332
+ const args = get(argumentsState);
333
+ const [script, options] = args;
334
+ const child = await new Promise(
335
+ (resolve) => {
336
+ const room = spawn(script, options, { env: process.env });
337
+ const resolver = (data) => {
338
+ if (data.toString() === `ALIVE`) {
339
+ room.stdout.off(`data`, resolver);
340
+ resolve(room);
341
+ }
342
+ };
343
+ room.stdout.on(`data`, resolver);
344
+ }
345
+ );
346
+ return new ChildSocket(child, roomId);
347
+ }
348
+ });
349
+
350
+ // realtime-server/src/realtime-server-stores/server-room-external-actions.ts
351
+ var createRoomTX = transaction({
352
+ key: `createRoom`,
353
+ do: ({ get, set, find }, roomId, script, options) => {
354
+ const args = options ? [script, options] : [script];
355
+ const roomArgumentsState = find(roomArgumentsAtoms, roomId);
356
+ set(roomArgumentsState, args);
357
+ set(roomIndex, (s) => s.add(roomId));
358
+ const roomState = find(roomSelectors, roomId);
359
+ const room = get(roomState);
360
+ return room;
361
+ }
362
+ });
363
+ var joinRoomTX = transaction({
364
+ key: `joinRoom`,
365
+ do: (tools, roomId, userId, enteredAtEpoch) => {
366
+ const meta = { enteredAtEpoch };
367
+ editRelationsInStore(
368
+ usersInRooms,
369
+ (relations) => {
370
+ relations.set({ room: roomId, user: userId }, meta);
371
+ },
372
+ tools.env().store
373
+ );
374
+ return meta;
375
+ }
376
+ });
377
+ var leaveRoomTX = transaction({
378
+ key: `leaveRoom`,
379
+ do: (tools, roomId, userId) => {
380
+ editRelationsInStore(
381
+ usersInRooms,
382
+ (relations) => {
383
+ relations.delete({ room: roomId, user: userId });
384
+ },
385
+ tools.env().store
386
+ );
387
+ }
388
+ });
389
+ var destroyRoomTX = transaction({
390
+ key: `destroyRoom`,
391
+ do: (tools, roomId) => {
392
+ editRelationsInStore(
393
+ usersInRooms,
394
+ (relations) => {
395
+ relations.delete({ room: roomId });
396
+ },
397
+ tools.env().store
398
+ );
399
+ tools.set(roomIndex, (s) => (s.delete(roomId), s));
400
+ }
401
+ });
402
+
403
+ // realtime-server/src/realtime-server-stores/server-sync-store.ts
404
+ function redactTransactionUpdateContent(visibleStateKeys, updates) {
405
+ return updates.map((update) => {
406
+ switch (update.type) {
407
+ case `transaction_update`: {
408
+ const redacted = redactTransactionUpdateContent(
409
+ visibleStateKeys,
410
+ update.updates
411
+ );
412
+ return { ...update, updates: redacted };
413
+ }
414
+ case `atom_update`:
415
+ case `selector_update`:
416
+ case `molecule_creation`:
417
+ case `molecule_disposal`:
418
+ case `molecule_transfer`:
419
+ case `state_creation`:
420
+ case `state_disposal`:
421
+ return update;
422
+ }
423
+ }).filter((update) => {
424
+ switch (update.type) {
425
+ case `atom_update`:
426
+ case `selector_update`:
427
+ return visibleStateKeys.includes(update.key);
428
+ case `state_creation`:
429
+ case `state_disposal`:
430
+ return visibleStateKeys.includes(update.token.key);
431
+ case `molecule_creation`:
432
+ case `transaction_update`:
433
+ case `molecule_disposal`:
434
+ case `molecule_transfer`:
435
+ return true;
436
+ }
437
+ });
438
+ }
439
+ var redactorAtoms = atomFamily({
440
+ key: `redactor`,
441
+ default: { occlude: (updates) => updates }
442
+ });
443
+ var userUnacknowledgedQueues = atomFamily({
444
+ key: `unacknowledgedUpdates`,
445
+ default: () => []
446
+ });
447
+
448
+ // realtime-server/src/realtime-server-stores/server-user-store.ts
449
+ var socketAtoms = atomFamily({
450
+ key: `sockets`,
451
+ default: null
452
+ });
453
+ var socketIndex = atom({
454
+ key: `socketsIndex`,
455
+ mutable: true,
456
+ default: () => new SetRTX(),
457
+ toJson: (set) => set.toJSON(),
458
+ fromJson: (json) => SetRTX.fromJSON(json)
459
+ });
460
+ var userIndex = atom({
461
+ key: `usersIndex`,
462
+ mutable: true,
463
+ default: () => new SetRTX(),
464
+ toJson: (set) => set.toJSON(),
465
+ fromJson: (json) => SetRTX.fromJSON(json)
466
+ });
467
+ var usersOfSockets = join({
468
+ key: `usersOfSockets`,
469
+ between: [`user`, `socket`],
470
+ cardinality: `1:1`,
471
+ isAType: (s) => s.startsWith(`user::`),
472
+ isBType: (s) => s.startsWith(`socket::`)
473
+ });
474
+
475
+ // realtime-server/src/continuity/prepare-to-send-initial-payload.ts
476
+ function prepareToSendInitialPayload(store, continuity, userKey, socket) {
477
+ const continuityKey = continuity.key;
478
+ return function sendInitialPayload() {
479
+ const initialPayload = [];
480
+ for (const atom2 of continuity.globals) {
481
+ const resourceToken = atom2.type === `mutable_atom` ? getJsonToken(store, atom2) : atom2;
482
+ const resource = getFromStore(store, resourceToken);
483
+ initialPayload.push(resourceToken, resource);
484
+ }
485
+ for (const perspective of continuity.perspectives) {
486
+ const { viewAtoms, resourceAtoms } = perspective;
487
+ const userViewState = findInStore(store, viewAtoms, userKey);
488
+ const userView = getFromStore(store, userViewState);
489
+ store.logger.info(`\u{1F441}`, `atom`, resourceAtoms.key, `${userKey} can see`, {
490
+ viewAtoms,
491
+ resourceAtoms,
492
+ userView
493
+ });
494
+ for (const visibleToken of userView) {
495
+ const resourceToken = visibleToken.type === `mutable_atom` ? getJsonToken(store, visibleToken) : visibleToken;
496
+ const resource = getFromStore(store, resourceToken);
497
+ initialPayload.push(resourceToken, resource);
498
+ }
499
+ }
500
+ const epoch = isRootStore(store) ? store.transactionMeta.epoch.get(continuityKey) ?? null : null;
501
+ socket?.emit(`continuity-init:${continuityKey}`, epoch, initialPayload);
502
+ };
503
+ }
504
+
505
+ // realtime-server/src/continuity/prepare-to-serve-transaction-request.ts
506
+ function prepareToServeTransactionRequest(store, continuity, userKey) {
507
+ const continuityKey = continuity.key;
508
+ return function serveTransactionRequest(update) {
509
+ store.logger.info(`\u{1F6CE}\uFE0F`, `continuity`, continuityKey, `received`, update);
510
+ const transactionKey = update.key;
511
+ const updateId = update.id;
512
+ const performanceKey = `tx-run:${transactionKey}:${updateId}`;
513
+ const performanceKeyStart = `${performanceKey}:start`;
514
+ const performanceKeyEnd = `${performanceKey}:end`;
515
+ performance.mark(performanceKeyStart);
516
+ try {
517
+ actUponStore(
518
+ store,
519
+ { type: `transaction`, key: transactionKey },
520
+ updateId
521
+ )(...update.params);
522
+ } catch (thrown) {
523
+ if (thrown instanceof Error) {
524
+ store.logger.error(
525
+ `\u274C`,
526
+ `continuity`,
527
+ continuityKey,
528
+ `failed to run transaction ${transactionKey} from ${userKey} with update ${updateId}`,
529
+ thrown.message
530
+ );
531
+ }
532
+ }
533
+ performance.mark(performanceKeyEnd);
534
+ const metric = performance.measure(
535
+ performanceKey,
536
+ performanceKeyStart,
537
+ performanceKeyEnd
538
+ );
539
+ store?.logger.info(
540
+ `\u{1F680}`,
541
+ `transaction`,
542
+ transactionKey,
543
+ updateId,
544
+ userKey,
545
+ metric.duration
546
+ );
547
+ };
548
+ }
549
+
550
+ // realtime-server/src/continuity/prepare-to-track-client-acknowledgement.ts
551
+ function prepareToTrackClientAcknowledgement(store, continuity, userKey, userUnacknowledgedUpdates) {
552
+ const continuityKey = continuity.key;
553
+ return function trackClientAcknowledgement(epoch) {
554
+ store.logger.info(
555
+ `\u{1F44D}`,
556
+ `continuity`,
557
+ continuityKey,
558
+ `${userKey} acknowledged epoch ${epoch}`
559
+ );
560
+ const isUnacknowledged = userUnacknowledgedUpdates[0]?.epoch === epoch;
561
+ if (isUnacknowledged) {
562
+ setIntoStore(store, userUnacknowledgedQueues, userKey, (updates) => {
563
+ updates.shift();
564
+ store.logger.info(
565
+ `\u{1F44D}`,
566
+ `continuity`,
567
+ continuityKey,
568
+ `${userKey} unacknowledged update queue now has`,
569
+ updates.length,
570
+ `items`
571
+ );
572
+ return updates;
573
+ });
574
+ }
575
+ };
576
+ }
577
+
578
+ // realtime-server/src/continuity/subscribe-to-continuity-actions.ts
579
+ function subscribeToContinuityActions(store, continuity, userKey, socket) {
580
+ const continuityKey = continuity.key;
581
+ const unsubscribeFunctions = [];
582
+ for (const transaction2 of continuity.actions) {
583
+ const unsubscribeFromTransaction = subscribeToTransaction(
584
+ store,
585
+ transaction2,
586
+ `sync-continuity:${continuityKey}:${userKey}`,
587
+ (update) => {
588
+ try {
589
+ const visibleKeys = continuity.globals.map((atom2) => {
590
+ if (atom2.type === `atom`) {
591
+ return atom2.key;
592
+ }
593
+ return getUpdateToken(atom2).key;
594
+ }).concat(
595
+ continuity.perspectives.flatMap((perspective) => {
596
+ const { viewAtoms } = perspective;
597
+ const userPerspectiveTokenState = findInStore(
598
+ store,
599
+ viewAtoms,
600
+ userKey
601
+ );
602
+ const visibleTokens = getFromStore(
603
+ store,
604
+ userPerspectiveTokenState
605
+ );
606
+ return visibleTokens.map((token) => {
607
+ const key = token.type === `mutable_atom` ? `*` + token.key : token.key;
608
+ return key;
609
+ });
610
+ })
611
+ );
612
+ const redactedUpdates = redactTransactionUpdateContent(
613
+ visibleKeys,
614
+ update.updates
615
+ );
616
+ const redactedUpdate = {
617
+ ...update,
618
+ updates: redactedUpdates
619
+ };
620
+ setIntoStore(store, userUnacknowledgedQueues, userKey, (updates) => {
621
+ if (redactedUpdate) {
622
+ updates.push(redactedUpdate);
623
+ updates.sort((a, b) => a.epoch - b.epoch);
624
+ store.logger.info(
625
+ `\u{1F44D}`,
626
+ `continuity`,
627
+ continuityKey,
628
+ `${userKey} unacknowledged update queue now has`,
629
+ updates.length,
630
+ `items`
631
+ );
632
+ }
633
+ return updates;
634
+ });
635
+ socket?.emit(
636
+ `tx-new:${continuityKey}`,
637
+ redactedUpdate
638
+ );
639
+ } catch (thrown) {
640
+ if (thrown instanceof Error) {
641
+ store.logger.error(
642
+ `\u274C`,
643
+ `continuity`,
644
+ continuityKey,
645
+ `${userKey} failed to send update from transaction ${transaction2.key} to ${userKey}`,
646
+ thrown.message
647
+ );
648
+ }
649
+ }
650
+ }
651
+ );
652
+ unsubscribeFunctions.push(unsubscribeFromTransaction);
653
+ }
654
+ return unsubscribeFunctions;
655
+ }
656
+
657
+ // realtime-server/src/continuity/subscribe-to-continuity-perpectives.ts
658
+ function subscribeToContinuityPerspectives(store, continuity, userKey, socket) {
659
+ const continuityKey = continuity.key;
660
+ const unsubFns = [];
661
+ for (const perspective of continuity.perspectives) {
662
+ const { viewAtoms } = perspective;
663
+ const userViewState = findInStore(store, viewAtoms, userKey);
664
+ const unsubscribeFromUserView = subscribeToState(
665
+ store,
666
+ userViewState,
667
+ `sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,
668
+ ({ oldValue, newValue }) => {
669
+ const oldKeys = oldValue.map((token) => token.key);
670
+ const newKeys = newValue.map((token) => token.key);
671
+ const concealed = oldValue.filter(
672
+ (token) => !newKeys.includes(token.key)
673
+ );
674
+ const revealed = newValue.filter((token) => !oldKeys.includes(token.key)).flatMap((token) => {
675
+ const resourceToken = token.type === `mutable_atom` ? getJsonToken(store, token) : token;
676
+ const resource = getFromStore(store, resourceToken);
677
+ return [resourceToken, resource];
678
+ });
679
+ store.logger.info(
680
+ `\u{1F441}`,
681
+ `atom`,
682
+ perspective.resourceAtoms.key,
683
+ `${userKey} has a new perspective`,
684
+ { oldKeys, newKeys, revealed, concealed }
685
+ );
686
+ if (revealed.length > 0) {
687
+ socket?.emit(`reveal:${continuityKey}`, revealed);
688
+ }
689
+ if (concealed.length > 0) {
690
+ socket?.emit(`conceal:${continuityKey}`, concealed);
691
+ }
692
+ }
693
+ );
694
+ unsubFns.push(unsubscribeFromUserView);
695
+ }
696
+ return unsubFns;
697
+ }
698
+
699
+ // realtime-server/src/continuity/prepare-to-sync-realtime-continuity.ts
700
+ function prepareToExposeRealtimeContinuity({
701
+ socket: initialSocket,
702
+ store = IMPLICIT.STORE
703
+ }) {
704
+ return function syncRealtimeContinuity(continuity) {
705
+ let socket = initialSocket;
706
+ const continuityKey = continuity.key;
707
+ const userKeyState = findRelationsInStore(
708
+ usersOfSockets,
709
+ `socket::${socket.id}`,
710
+ store
711
+ ).userKeyOfSocket;
712
+ const userKey = getFromStore(store, userKeyState);
713
+ if (!userKey) {
714
+ store.logger.error(
715
+ `\u274C`,
716
+ `continuity`,
717
+ continuityKey,
718
+ `Tried to create a synchronizer for a socket (${socket.id}) that is not connected to a user.`
719
+ );
720
+ return () => {
721
+ };
722
+ }
723
+ const socketKeyState = findRelationsInStore(
724
+ usersOfSockets,
725
+ userKey,
726
+ store
727
+ ).socketKeyOfUser;
728
+ subscribeToState(
729
+ store,
730
+ socketKeyState,
731
+ `sync-continuity:${continuityKey}:${userKey}`,
732
+ ({ newValue: newSocketKey }) => {
733
+ store.logger.info(
734
+ `\u{1F44B}`,
735
+ `continuity`,
736
+ continuityKey,
737
+ `seeing ${userKey} on new socket ${newSocketKey}`
738
+ );
739
+ if (newSocketKey === null) {
740
+ store.logger.warn(
741
+ `\u274C`,
742
+ `continuity`,
743
+ continuityKey,
744
+ `User (${userKey}) is not connected to a socket, waiting for them to reappear.`
745
+ );
746
+ return;
747
+ }
748
+ const newSocketState = findInStore(store, socketAtoms, newSocketKey);
749
+ const newSocket = getFromStore(store, newSocketState);
750
+ socket = newSocket;
751
+ for (const unacknowledgedUpdate of userUnacknowledgedUpdates) {
752
+ socket?.emit(
753
+ `tx-new:${continuityKey}`,
754
+ unacknowledgedUpdate
755
+ );
756
+ }
757
+ }
758
+ );
759
+ const userUnacknowledgedUpdates = getFromStore(
760
+ store,
761
+ userUnacknowledgedQueues,
762
+ userKey
763
+ );
764
+ const unsubscribeFunctions = [];
765
+ const unsubscribeFromPerspectives = subscribeToContinuityPerspectives(
766
+ store,
767
+ continuity,
768
+ userKey,
769
+ socket
770
+ );
771
+ const unsubscribeFromTransactions = subscribeToContinuityActions(
772
+ store,
773
+ continuity,
774
+ userKey,
775
+ socket
776
+ );
777
+ unsubscribeFunctions.push(
778
+ ...unsubscribeFromPerspectives,
779
+ ...unsubscribeFromTransactions
780
+ );
781
+ const sendInitialPayload = prepareToSendInitialPayload(
782
+ store,
783
+ continuity,
784
+ userKey,
785
+ initialSocket
786
+ );
787
+ socket.off(`get:${continuityKey}`, sendInitialPayload);
788
+ socket.on(`get:${continuityKey}`, sendInitialPayload);
789
+ const fillTransactionRequest = prepareToServeTransactionRequest(
790
+ store,
791
+ continuity,
792
+ userKey
793
+ );
794
+ socket.off(`tx-run:${continuityKey}`, fillTransactionRequest);
795
+ socket.on(`tx-run:${continuityKey}`, fillTransactionRequest);
796
+ const trackClientAcknowledgement = prepareToTrackClientAcknowledgement(
797
+ store,
798
+ continuity,
799
+ userKey,
800
+ userUnacknowledgedUpdates
801
+ );
802
+ socket?.on(`ack:${continuityKey}`, trackClientAcknowledgement);
803
+ return () => {
804
+ for (const unsubscribe of unsubscribeFunctions) unsubscribe();
805
+ socket?.off(`ack:${continuityKey}`, trackClientAcknowledgement);
806
+ socket?.off(`get:${continuityKey}`, sendInitialPayload);
807
+ socket?.off(`tx-run:${continuityKey}`, fillTransactionRequest);
808
+ };
809
+ };
810
+ }
811
+
812
+ // realtime-server/src/realtime-action-receiver.ts
813
+ function realtimeActionReceiver({
814
+ socket,
815
+ store = IMPLICIT.STORE
816
+ }) {
817
+ return function actionReceiver(tx) {
818
+ const fillTransactionRequest = (update) => {
819
+ const performanceKey = `tx-run:${tx.key}:${update.id}`;
820
+ const performanceKeyStart = `${performanceKey}:start`;
821
+ const performanceKeyEnd = `${performanceKey}:end`;
822
+ performance.mark(performanceKeyStart);
823
+ actUponStore(store, tx, update.id)(...update.params);
824
+ performance.mark(performanceKeyEnd);
825
+ const metric = performance.measure(
826
+ performanceKey,
827
+ performanceKeyStart,
828
+ performanceKeyEnd
829
+ );
830
+ store?.logger.info(`\u{1F680}`, `transaction`, tx.key, update.id, metric.duration);
831
+ };
832
+ socket.on(`tx-run:${tx.key}`, fillTransactionRequest);
833
+ return () => {
834
+ socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
835
+ };
836
+ };
837
+ }
838
+
839
+ // realtime-server/src/realtime-family-provider.ts
840
+ function realtimeAtomFamilyProvider({
841
+ socket,
842
+ store = IMPLICIT.STORE
843
+ }) {
844
+ return function familyProvider(family, index) {
845
+ const unsubCallbacksByKey = /* @__PURE__ */ new Map();
846
+ const fillUnsubRequest = (key) => {
847
+ socket.off(`unsub:${key}`, fillUnsubRequest);
848
+ const unsub = unsubCallbacksByKey.get(key);
849
+ if (unsub) {
850
+ unsub();
851
+ unsubCallbacksByKey.delete(key);
852
+ }
853
+ };
854
+ const fillSubRequest = (subKey) => {
855
+ const exposedSubKeys = getFromStore(store, index);
856
+ for (const exposedSubKey of exposedSubKeys) {
857
+ if (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {
858
+ const token = findInStore(store, family, subKey);
859
+ socket.emit(`serve:${token.key}`, getFromStore(store, token));
860
+ const unsubscribe = subscribeToState(
861
+ store,
862
+ token,
863
+ `expose-family:${family.key}:${socket.id}`,
864
+ ({ newValue }) => {
865
+ socket.emit(`serve:${token.key}`, newValue);
866
+ }
867
+ );
868
+ unsubCallbacksByKey.set(token.key, unsubscribe);
869
+ socket.on(`unsub:${token.key}`, () => {
870
+ fillUnsubRequest(token.key);
871
+ });
872
+ break;
873
+ }
874
+ }
875
+ };
876
+ socket.on(`sub:${family.key}`, fillSubRequest);
877
+ return () => {
878
+ socket.off(`sub:${family.key}`, fillSubRequest);
879
+ for (const [, unsub] of unsubCallbacksByKey) {
880
+ unsub();
881
+ }
882
+ unsubCallbacksByKey.clear();
883
+ };
884
+ };
885
+ }
886
+
887
+ // realtime-server/src/realtime-mutable-family-provider.ts
888
+ function realtimeMutableFamilyProvider({
889
+ socket,
890
+ store = IMPLICIT.STORE
891
+ }) {
892
+ return function mutableFamilyProvider(family, index) {
893
+ const unsubCallbacksByKey = /* @__PURE__ */ new Map();
894
+ const fillUnsubRequest = (key) => {
895
+ socket.off(`unsub:${key}`, fillUnsubRequest);
896
+ const unsub = unsubCallbacksByKey.get(key);
897
+ if (unsub) {
898
+ unsub();
899
+ unsubCallbacksByKey.delete(key);
900
+ }
901
+ };
902
+ const fillSubRequest = (subKey) => {
903
+ const exposedSubKeys = getFromStore(store, index);
904
+ for (const exposedSubKey of exposedSubKeys) {
905
+ if (stringifyJson(exposedSubKey) === stringifyJson(subKey)) {
906
+ const token = findInStore(store, family, subKey);
907
+ getFromStore(store, token);
908
+ const jsonToken = getJsonToken(store, token);
909
+ const updateToken = getUpdateToken(token);
910
+ socket.emit(`init:${token.key}`, getFromStore(store, jsonToken));
911
+ const unsubscribe = subscribeToState(
912
+ store,
913
+ updateToken,
914
+ `expose-family:${family.key}:${socket.id}`,
915
+ ({ newValue }) => {
916
+ socket.emit(`next:${token.key}`, newValue);
917
+ }
918
+ );
919
+ unsubCallbacksByKey.set(token.key, unsubscribe);
920
+ socket.on(`unsub:${token.key}`, () => {
921
+ fillUnsubRequest(token.key);
922
+ });
923
+ break;
924
+ }
925
+ }
926
+ };
927
+ socket.on(`sub:${family.key}`, fillSubRequest);
928
+ return () => {
929
+ socket.off(`sub:${family.key}`, fillSubRequest);
930
+ for (const [, unsub] of unsubCallbacksByKey) {
931
+ unsub();
932
+ }
933
+ unsubCallbacksByKey.clear();
934
+ };
935
+ };
936
+ }
937
+
938
+ // realtime-server/src/realtime-mutable-provider.ts
939
+ function realtimeMutableProvider({
940
+ socket,
941
+ store = IMPLICIT.STORE
942
+ }) {
943
+ return function mutableProvider(token) {
944
+ let unsubscribeFromStateUpdates = null;
945
+ const jsonToken = getJsonToken(store, token);
946
+ const trackerToken = getUpdateToken(token);
947
+ const fillUnsubRequest = () => {
948
+ socket.off(`unsub:${token.key}`, fillUnsubRequest);
949
+ unsubscribeFromStateUpdates?.();
950
+ unsubscribeFromStateUpdates = null;
951
+ };
952
+ const fillSubRequest = () => {
953
+ socket.emit(`init:${token.key}`, getFromStore(store, jsonToken));
954
+ unsubscribeFromStateUpdates = subscribeToState(
955
+ store,
956
+ trackerToken,
957
+ `expose-single:${socket.id}`,
958
+ ({ newValue }) => {
959
+ socket.emit(`next:${token.key}`, newValue);
960
+ }
961
+ );
962
+ socket.on(`unsub:${token.key}`, fillUnsubRequest);
963
+ };
964
+ socket.on(`sub:${token.key}`, fillSubRequest);
965
+ return () => {
966
+ socket.off(`sub:${token.key}`, fillSubRequest);
967
+ unsubscribeFromStateUpdates?.();
968
+ };
969
+ };
970
+ }
971
+
972
+ // realtime-server/src/realtime-state-provider.ts
973
+ function realtimeStateProvider({
974
+ socket,
975
+ store = IMPLICIT.STORE
976
+ }) {
977
+ return function stateProvider(token) {
978
+ let unsubscribeFromStateUpdates;
979
+ const fillSubRequest = () => {
980
+ socket.emit(`serve:${token.key}`, getFromStore(store, token));
981
+ unsubscribeFromStateUpdates = subscribeToState(
982
+ store,
983
+ token,
984
+ `expose-single:${socket.id}`,
985
+ ({ newValue }) => {
986
+ socket.emit(`serve:${token.key}`, newValue);
987
+ }
988
+ );
989
+ const fillUnsubRequest = () => {
990
+ socket.off(`unsub:${token.key}`, fillUnsubRequest);
991
+ if (unsubscribeFromStateUpdates) {
992
+ unsubscribeFromStateUpdates();
993
+ unsubscribeFromStateUpdates = void 0;
994
+ }
995
+ };
996
+ socket.on(`unsub:${token.key}`, fillUnsubRequest);
997
+ };
998
+ socket.on(`sub:${token.key}`, fillSubRequest);
999
+ return () => {
1000
+ socket.off(`sub:${token.key}`, fillSubRequest);
1001
+ if (unsubscribeFromStateUpdates) {
1002
+ unsubscribeFromStateUpdates();
1003
+ unsubscribeFromStateUpdates = void 0;
1004
+ }
1005
+ };
1006
+ };
1007
+ }
1008
+
1009
+ // realtime-server/src/realtime-state-receiver.ts
1010
+ function realtimeStateReceiver({
1011
+ socket,
1012
+ store = IMPLICIT.STORE
1013
+ }) {
1014
+ return function stateReceiver(token) {
1015
+ const publish = (newValue) => {
1016
+ setIntoStore(store, token, newValue);
1017
+ };
1018
+ const fillPubUnclaim = () => {
1019
+ socket.off(`pub:${token.key}`, publish);
1020
+ socket.off(`unclaim:${token.key}`, fillPubUnclaim);
1021
+ };
1022
+ const fillPubClaim = () => {
1023
+ socket.on(`pub:${token.key}`, publish);
1024
+ socket.on(`unclaim:${token.key}`, fillPubUnclaim);
1025
+ };
1026
+ socket.on(`claim:${token.key}`, fillPubClaim);
1027
+ return () => {
1028
+ socket.off(`claim:${token.key}`, fillPubClaim);
1029
+ socket.off(`pub:${token.key}`, publish);
1030
+ };
1031
+ };
1032
+ }
1033
+
1034
+ export { ChildSocket, CustomSocket, ParentSocket, SubjectSocket, createRoomTX, destroyRoomTX, joinRoomTX, leaveRoomTX, prepareToExposeRealtimeContinuity, realtimeActionReceiver, realtimeAtomFamilyProvider, realtimeMutableFamilyProvider, realtimeMutableProvider, realtimeStateProvider, realtimeStateReceiver, redactTransactionUpdateContent, redactorAtoms, roomArgumentsAtoms, roomSelectors, socketAtoms, socketIndex, userIndex, userUnacknowledgedQueues, usersOfSockets };