atom.io 0.17.0 → 0.18.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 (153) hide show
  1. package/data/dist/index.cjs +62 -40
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.d.ts +8 -2
  4. package/data/dist/index.js +64 -42
  5. package/data/dist/index.js.map +1 -1
  6. package/data/src/dict.ts +8 -4
  7. package/data/src/join.ts +74 -33
  8. package/data/src/struct-family.ts +18 -17
  9. package/dist/chunk-IZHOMSXA.js +331 -0
  10. package/dist/chunk-IZHOMSXA.js.map +1 -0
  11. package/dist/chunk-JDUNWJFB.js +18 -0
  12. package/dist/chunk-JDUNWJFB.js.map +1 -0
  13. package/dist/index.cjs +4 -10
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +66 -51
  16. package/dist/index.js +5 -11
  17. package/dist/index.js.map +1 -1
  18. package/internal/dist/index.cjs +187 -58
  19. package/internal/dist/index.cjs.map +1 -1
  20. package/internal/dist/index.d.ts +95 -71
  21. package/internal/dist/index.js +179 -53
  22. package/internal/dist/index.js.map +1 -1
  23. package/internal/src/arbitrary.ts +3 -0
  24. package/internal/src/atom/delete-atom.ts +7 -6
  25. package/internal/src/caching.ts +6 -4
  26. package/internal/src/families/find-in-store.ts +16 -0
  27. package/internal/src/get-environment-data.ts +4 -7
  28. package/internal/src/index.ts +6 -5
  29. package/internal/src/ingest-updates/ingest-atom-update.ts +6 -2
  30. package/internal/src/ingest-updates/ingest-transaction-update.ts +0 -1
  31. package/internal/src/selector/create-standalone-selector.ts +0 -2
  32. package/internal/src/set-state/copy-mutable-if-needed.ts +5 -0
  33. package/internal/src/set-state/emit-update.ts +25 -11
  34. package/internal/src/set-state/set-atom.ts +15 -18
  35. package/internal/src/store/store.ts +14 -2
  36. package/internal/src/store/withdraw.ts +72 -2
  37. package/internal/src/subscribe/subscribe-to-timeline.ts +2 -2
  38. package/internal/src/subscribe/subscribe-to-transaction.ts +2 -2
  39. package/internal/src/timeline/create-timeline.ts +12 -1
  40. package/internal/src/transaction/act-upon-store.ts +19 -0
  41. package/internal/src/transaction/apply-transaction.ts +6 -1
  42. package/internal/src/transaction/assign-transaction-to-continuity.ts +18 -0
  43. package/internal/src/transaction/build-transaction.ts +7 -6
  44. package/internal/src/transaction/create-transaction.ts +1 -1
  45. package/internal/src/transaction/get-epoch-number.ts +40 -0
  46. package/internal/src/transaction/index.ts +10 -1
  47. package/internal/src/transaction/set-epoch-number.ts +30 -0
  48. package/introspection/dist/index.cjs.map +1 -1
  49. package/introspection/dist/index.d.ts +3 -3
  50. package/introspection/dist/index.js.map +1 -1
  51. package/introspection/src/attach-introspection-states.ts +6 -2
  52. package/introspection/src/attach-timeline-family.ts +5 -2
  53. package/introspection/src/attach-transaction-logs.ts +2 -2
  54. package/json/dist/index.d.ts +3 -1
  55. package/json/src/index.ts +4 -0
  56. package/package.json +241 -230
  57. package/react/dist/index.cjs.map +1 -1
  58. package/react/dist/index.d.ts +1 -1
  59. package/react/dist/index.js.map +1 -1
  60. package/react/src/use-json.ts +1 -1
  61. package/react-devtools/dist/index.cjs +131 -134
  62. package/react-devtools/dist/index.cjs.map +1 -1
  63. package/react-devtools/dist/index.css +2 -2
  64. package/react-devtools/dist/index.css.map +1 -1
  65. package/react-devtools/dist/index.d.ts +3 -3
  66. package/react-devtools/dist/index.js +91 -108
  67. package/react-devtools/dist/index.js.map +1 -1
  68. package/react-devtools/src/StateEditor.tsx +4 -4
  69. package/react-devtools/src/StateIndex.tsx +1 -4
  70. package/react-devtools/src/TimelineIndex.tsx +3 -3
  71. package/react-devtools/src/TransactionIndex.tsx +9 -8
  72. package/react-devtools/src/index.ts +2 -2
  73. package/realtime/dist/index.cjs +120 -0
  74. package/realtime/dist/index.cjs.map +1 -0
  75. package/realtime/dist/index.d.ts +146 -0
  76. package/realtime/dist/index.js +111 -0
  77. package/realtime/dist/index.js.map +1 -0
  78. package/realtime/package.json +16 -0
  79. package/realtime/src/index.ts +2 -0
  80. package/realtime/src/realtime-continuity.ts +162 -0
  81. package/realtime/src/shared-room-store.ts +48 -0
  82. package/realtime-client/dist/index.cjs +424 -170
  83. package/realtime-client/dist/index.cjs.map +1 -1
  84. package/realtime-client/dist/index.d.ts +15 -11
  85. package/realtime-client/dist/index.js +96 -177
  86. package/realtime-client/dist/index.js.map +1 -1
  87. package/realtime-client/src/index.ts +8 -7
  88. package/realtime-client/src/{pull-family-member.ts → pull-atom-family-member.ts} +2 -2
  89. package/realtime-client/src/{pull-state.ts → pull-atom.ts} +2 -2
  90. package/realtime-client/src/{pull-mutable-family-member.ts → pull-mutable-atom-family-member.ts} +6 -6
  91. package/realtime-client/src/{pull-mutable.ts → pull-mutable-atom.ts} +1 -1
  92. package/realtime-client/src/pull-selector-family-member.ts +42 -0
  93. package/realtime-client/src/pull-selector.ts +38 -0
  94. package/realtime-client/src/realtime-client-stores/client-main-store.ts +12 -2
  95. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +7 -7
  96. package/realtime-client/src/sync-continuity.ts +368 -0
  97. package/realtime-react/dist/index.cjs +367 -27
  98. package/realtime-react/dist/index.cjs.map +1 -1
  99. package/realtime-react/dist/index.d.ts +24 -8
  100. package/realtime-react/dist/index.js +38 -22
  101. package/realtime-react/dist/index.js.map +1 -1
  102. package/realtime-react/src/index.ts +6 -5
  103. package/realtime-react/src/use-pull-atom-family-member.ts +21 -0
  104. package/realtime-react/src/{use-sync.ts → use-pull-atom.ts} +4 -4
  105. package/realtime-react/src/{use-pull-mutable.ts → use-pull-mutable-atom.ts} +4 -3
  106. package/realtime-react/src/use-pull-mutable-family-member.ts +9 -4
  107. package/realtime-react/src/use-pull-selector-family-member.ts +21 -0
  108. package/realtime-react/src/{use-pull.ts → use-pull-selector.ts} +7 -5
  109. package/realtime-react/src/use-push.ts +3 -2
  110. package/realtime-react/src/use-server-action.ts +3 -2
  111. package/realtime-react/src/use-sync-continuity.ts +12 -0
  112. package/realtime-server/dist/index.cjs +769 -371
  113. package/realtime-server/dist/index.cjs.map +1 -1
  114. package/realtime-server/dist/index.d.ts +130 -60
  115. package/realtime-server/dist/index.js +753 -361
  116. package/realtime-server/dist/index.js.map +1 -1
  117. package/realtime-server/src/index.ts +17 -3
  118. package/realtime-server/src/ipc-sockets/child-socket.ts +135 -0
  119. package/realtime-server/src/ipc-sockets/custom-socket.ts +90 -0
  120. package/realtime-server/src/ipc-sockets/index.ts +3 -0
  121. package/realtime-server/src/ipc-sockets/parent-socket.ts +185 -0
  122. package/realtime-server/src/realtime-action-receiver.ts +8 -5
  123. package/realtime-server/src/realtime-continuity-synchronizer.ts +376 -0
  124. package/realtime-server/src/realtime-family-provider.ts +30 -71
  125. package/realtime-server/src/realtime-mutable-family-provider.ts +24 -86
  126. package/realtime-server/src/realtime-server-stores/index.ts +4 -1
  127. package/realtime-server/src/realtime-server-stores/realtime-continuity-store.ts +109 -0
  128. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +64 -0
  129. package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +42 -0
  130. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +51 -98
  131. package/realtime-server/src/realtime-server-stores/server-user-store.ts +14 -29
  132. package/realtime-server/src/realtime-state-receiver.ts +0 -1
  133. package/realtime-testing/dist/index.cjs +34 -32
  134. package/realtime-testing/dist/index.cjs.map +1 -1
  135. package/realtime-testing/dist/index.d.ts +1 -0
  136. package/realtime-testing/dist/index.js +33 -31
  137. package/realtime-testing/dist/index.js.map +1 -1
  138. package/realtime-testing/src/setup-realtime-test.tsx +44 -32
  139. package/src/atom.ts +49 -31
  140. package/src/logger.ts +14 -5
  141. package/src/selector.ts +44 -25
  142. package/src/subscribe.ts +2 -1
  143. package/src/timeline.ts +4 -4
  144. package/src/transaction.ts +13 -17
  145. package/src/validators.ts +15 -9
  146. package/dist/chunk-H4Q5FTPZ.js +0 -11
  147. package/dist/chunk-H4Q5FTPZ.js.map +0 -1
  148. package/internal/src/set-state/copy-mutable-in-transaction.ts +0 -19
  149. package/realtime-client/src/sync-server-action.ts +0 -170
  150. package/realtime-client/src/sync-state.ts +0 -19
  151. package/realtime-react/src/use-pull-family-member.ts +0 -16
  152. package/realtime-react/src/use-sync-server-action.ts +0 -16
  153. package/realtime-server/src/realtime-action-synchronizer.ts +0 -152
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ var json = require('atom.io/json');
4
+ var internal = require('atom.io/internal');
5
+ var setRtx = require('atom.io/transceivers/set-rtx');
3
6
  var AtomIO = require('atom.io');
7
+ var realtime = require('atom.io/realtime');
8
+ var child_process = require('child_process');
4
9
  var data = require('atom.io/data');
5
- var setRtx = require('atom.io/transceivers/set-rtx');
6
- var internal = require('atom.io/internal');
7
- var json = require('atom.io/json');
8
10
 
9
11
  function _interopNamespace(e) {
10
12
  if (e && e.__esModule) return e;
@@ -45,113 +47,722 @@ var __spreadValues = (a, b) => {
45
47
  return a;
46
48
  };
47
49
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
48
- var userIndex = AtomIO.atom({
49
- key: `usersIndex`,
50
- mutable: true,
51
- default: () => new setRtx.SetRTX(),
52
- toJson: (set) => set.toJSON(),
53
- fromJson: (json) => setRtx.SetRTX.fromJSON(json)
50
+
51
+ // realtime-server/src/ipc-sockets/custom-socket.ts
52
+ var CustomSocket = class {
53
+ constructor(emit) {
54
+ this.emit = emit;
55
+ this.id = `no_id_retrieved`;
56
+ this.listeners = /* @__PURE__ */ new Map();
57
+ this.globalListeners = /* @__PURE__ */ new Set();
58
+ }
59
+ handleEvent(event, ...args) {
60
+ for (const listener of this.globalListeners) {
61
+ listener(event, ...args);
62
+ }
63
+ const listeners = this.listeners.get(event);
64
+ if (listeners) {
65
+ for (const listener of listeners) {
66
+ listener(...args);
67
+ }
68
+ }
69
+ }
70
+ on(event, listener) {
71
+ const listeners = this.listeners.get(event);
72
+ if (listeners) {
73
+ listeners.add(listener);
74
+ } else {
75
+ this.listeners.set(event, /* @__PURE__ */ new Set([listener]));
76
+ }
77
+ return this;
78
+ }
79
+ onAny(listener) {
80
+ this.globalListeners.add(listener);
81
+ return this;
82
+ }
83
+ off(event, listener) {
84
+ const listeners = this.listeners.get(event);
85
+ if (listeners) {
86
+ if (listener) {
87
+ listeners.delete(listener);
88
+ } else {
89
+ this.listeners.delete(event);
90
+ }
91
+ }
92
+ return this;
93
+ }
94
+ offAny(listener) {
95
+ this.globalListeners.delete(listener);
96
+ return this;
97
+ }
98
+ };
99
+
100
+ // realtime-server/src/ipc-sockets/child-socket.ts
101
+ var ChildSocket = class extends CustomSocket {
102
+ constructor(process2, key, logger = console) {
103
+ super((event, ...args) => {
104
+ const stringifiedEvent = JSON.stringify([event, ...args]) + ``;
105
+ const errorHandler = (err) => {
106
+ if (err.code === `EPIPE`) {
107
+ console.error(`EPIPE error during write`, this.process.stdin);
108
+ }
109
+ this.process.stdin.removeListener(`error`, errorHandler);
110
+ };
111
+ this.process.stdin.once(`error`, errorHandler);
112
+ this.process.stdin.write(stringifiedEvent);
113
+ return this;
114
+ });
115
+ this.process = process2;
116
+ this.key = key;
117
+ this.logger = logger;
118
+ this.incompleteData = ``;
119
+ this.unprocessedEvents = [];
120
+ this.incompleteLog = ``;
121
+ this.unprocessedLogs = [];
122
+ this.id = `#####`;
123
+ this.process = process2;
124
+ this.process.stdout.on(
125
+ `data`,
126
+ (buffer) => {
127
+ const chunk = buffer.toString();
128
+ if (chunk === `\u2728`) {
129
+ return;
130
+ }
131
+ this.unprocessedEvents.push(...chunk.split(``));
132
+ const newInput = this.unprocessedEvents.shift();
133
+ this.incompleteData += newInput || ``;
134
+ try {
135
+ if (this.incompleteData.startsWith(`error`)) {
136
+ console.log(`\u2757`, this.incompleteData);
137
+ }
138
+ const parsedEvent = json.parseJson(this.incompleteData);
139
+ this.handleEvent(...parsedEvent);
140
+ while (this.unprocessedEvents.length > 0) {
141
+ const event = this.unprocessedEvents.shift();
142
+ if (event) {
143
+ if (this.unprocessedEvents.length === 0) {
144
+ this.incompleteData = event;
145
+ }
146
+ const parsedEvent2 = json.parseJson(event);
147
+ this.handleEvent(...parsedEvent2);
148
+ }
149
+ }
150
+ this.incompleteData = ``;
151
+ } catch (error) {
152
+ console.warn(`\u26A0\uFE0F----------------\u26A0\uFE0F`);
153
+ console.warn(this.incompleteData);
154
+ console.warn(`\u26A0\uFE0F----------------\u26A0\uFE0F`);
155
+ console.error(error);
156
+ }
157
+ }
158
+ );
159
+ this.process.stderr.on(`data`, (buf) => {
160
+ var _a;
161
+ const chunk = buf.toString();
162
+ this.unprocessedLogs.push(...chunk.split(``));
163
+ const newInput = this.unprocessedLogs.shift();
164
+ this.incompleteLog += newInput || ``;
165
+ try {
166
+ const parsedLog = json.parseJson(this.incompleteLog);
167
+ this.handleLog(parsedLog);
168
+ while (this.unprocessedLogs.length > 0) {
169
+ this.incompleteLog = (_a = this.unprocessedLogs.shift()) != null ? _a : ``;
170
+ if (this.incompleteLog) {
171
+ const parsedLog2 = json.parseJson(this.incompleteLog);
172
+ this.handleLog(parsedLog2);
173
+ }
174
+ }
175
+ } catch (error) {
176
+ console.error(`\u274C\u274C\u274C`);
177
+ console.error(this.incompleteLog);
178
+ console.error(error);
179
+ console.error(`\u274C\u274C\u274C\uFE0F`);
180
+ }
181
+ });
182
+ if (process2.pid) {
183
+ this.id = process2.pid.toString();
184
+ }
185
+ }
186
+ handleLog(arg) {
187
+ if (Array.isArray(arg)) {
188
+ const [level, ...rest] = arg;
189
+ switch (level) {
190
+ case `i`:
191
+ this.logger.info(this.id, this.key, ...rest);
192
+ break;
193
+ case `w`:
194
+ this.logger.warn(this.id, this.key, ...rest);
195
+ break;
196
+ case `e`:
197
+ this.logger.error(this.id, this.key, ...rest);
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ };
203
+ var SubjectSocket = class extends CustomSocket {
204
+ constructor(id) {
205
+ super((...args) => {
206
+ this.out.next(args);
207
+ return this;
208
+ });
209
+ this.id = `no_id_retrieved`;
210
+ this.disposalFunctions = [];
211
+ this.id = id;
212
+ this.in = new internal.Subject();
213
+ this.out = new internal.Subject();
214
+ this.in.subscribe(`socket`, (event) => {
215
+ this.handleEvent(...event);
216
+ });
217
+ }
218
+ dispose() {
219
+ for (const dispose of this.disposalFunctions) {
220
+ dispose();
221
+ }
222
+ }
223
+ };
224
+ var ParentSocket = class extends CustomSocket {
225
+ constructor() {
226
+ var _a;
227
+ super((event, ...args) => {
228
+ const stringifiedEvent = JSON.stringify([event, ...args]);
229
+ this.process.stdout.write(stringifiedEvent + ``);
230
+ return this;
231
+ });
232
+ this.incompleteData = ``;
233
+ this.unprocessedEvents = [];
234
+ this.id = `#####`;
235
+ this.logger = {
236
+ info: (...args) => this.log(`i`, ...args),
237
+ warn: (...args) => this.log(`w`, ...args),
238
+ error: (...args) => this.log(`e`, ...args)
239
+ };
240
+ this.process = process;
241
+ this.process.stdin.resume();
242
+ this.relays = /* @__PURE__ */ new Map();
243
+ this.relayServices = [];
244
+ this.process.stdin.on(
245
+ `data`,
246
+ (buffer) => {
247
+ const chunk = buffer.toString();
248
+ this.unprocessedEvents.push(...chunk.split(``));
249
+ const newInput = this.unprocessedEvents.shift();
250
+ this.incompleteData += newInput || ``;
251
+ try {
252
+ const parsedEvent = json.parseJson(this.incompleteData);
253
+ this.logger.info(`\u{1F3B0}`, `received`, parsedEvent);
254
+ this.handleEvent(...parsedEvent);
255
+ while (this.unprocessedEvents.length > 0) {
256
+ const event = this.unprocessedEvents.shift();
257
+ if (event) {
258
+ if (this.unprocessedEvents.length === 0) {
259
+ this.incompleteData = event;
260
+ }
261
+ const parsedEvent2 = json.parseJson(event);
262
+ this.handleEvent(...parsedEvent2);
263
+ }
264
+ }
265
+ this.incompleteData = ``;
266
+ } catch (thrown) {
267
+ if (thrown instanceof Error) {
268
+ this.logger.error(`\u2757`, thrown.message, thrown.cause, thrown.stack);
269
+ }
270
+ }
271
+ }
272
+ );
273
+ this.on(`exit`, () => {
274
+ process.exit(0);
275
+ });
276
+ process.on(`exit`, () => {
277
+ this.logger.info(`\u{1F525}`, this.id, `exited`);
278
+ process.exit(0);
279
+ });
280
+ process.on(`end`, () => {
281
+ this.logger.info(`\u{1F525}`, this.id, `ended`);
282
+ process.exit(0);
283
+ });
284
+ process.on(`SIGTERM`, () => {
285
+ this.logger.error(`\u{1F525}`, this.id, `terminated`);
286
+ process.exit(0);
287
+ });
288
+ process.on(`SIGINT`, () => {
289
+ this.logger.error(`\u{1F525}`, this.id, `interrupted`);
290
+ process.exit(0);
291
+ });
292
+ if (process.pid) {
293
+ this.id = (_a = process.pid) == null ? void 0 : _a.toString();
294
+ }
295
+ this.on(`user-joins`, (username) => {
296
+ this.logger.info(`\u{1F464}`, `user`, username, `joined`);
297
+ const relay = new SubjectSocket(`user:${username}`);
298
+ this.relays.set(username, relay);
299
+ this.logger.info(
300
+ `\u{1F517}`,
301
+ `attaching services:`,
302
+ `[${[...this.relayServices.keys()].join(`, `)}]`
303
+ );
304
+ for (const attachServices of this.relayServices) {
305
+ const cleanup = attachServices(relay);
306
+ if (cleanup) {
307
+ relay.disposalFunctions.push(cleanup);
308
+ }
309
+ }
310
+ this.on(`user:${username}`, (...data) => {
311
+ relay.in.next(data);
312
+ });
313
+ relay.out.subscribe(`socket`, (data) => {
314
+ this.emit(...data);
315
+ });
316
+ });
317
+ this.on(`user-leaves`, (username) => {
318
+ const relay = this.relays.get(username);
319
+ this.off(`relay:${username}`);
320
+ if (relay) {
321
+ relay.dispose();
322
+ this.relays.delete(username);
323
+ }
324
+ });
325
+ process.stdout.write(`\u2728`);
326
+ }
327
+ log(...args) {
328
+ this.process.stderr.write(
329
+ json.stringifyJson(
330
+ args.map(
331
+ (arg) => arg instanceof setRtx.SetRTX ? `{ ${arg.toJSON().members.join(` | `)} }` : arg
332
+ )
333
+ ) + ``
334
+ );
335
+ }
336
+ relay(attachServices) {
337
+ this.logger.info(`\u{1F517}`, `running relay method`);
338
+ this.relayServices.push(attachServices);
339
+ }
340
+ };
341
+ AtomIO.selectorFamily({
342
+ key: `perspectiveRedactor`,
343
+ get: ({ userId, syncGroupKey }) => ({ get, find }) => {
344
+ const syncGroup = realtime.SyncGroup.existing.get(syncGroupKey);
345
+ if (!syncGroup) {
346
+ throw new Error(
347
+ `Tried to create a synchronizer for a sync group that does not exist.`
348
+ );
349
+ }
350
+ const userPerspectiveTokens = syncGroup.perspectives.flatMap(
351
+ ({ viewAtoms }) => {
352
+ const userPerspectiveToken = find(viewAtoms, userId);
353
+ const userPerspective = get(userPerspectiveToken);
354
+ const visibleTokens = [...userPerspective].map((token) => {
355
+ return token.type === `mutable_atom` ? internal.getUpdateToken(token).key : token.key;
356
+ });
357
+ internal.IMPLICIT.STORE.logger.info(
358
+ `\u{1F52D}`,
359
+ `continuity`,
360
+ syncGroupKey,
361
+ `${userId} can see ${visibleTokens.length} tokens in ${viewAtoms.key}`,
362
+ visibleTokens
363
+ );
364
+ return visibleTokens;
365
+ }
366
+ );
367
+ const filterTransactionUpdate = (visible, transactionUpdate) => {
368
+ internal.IMPLICIT.STORE.logger.info(
369
+ `\u{1F58C}`,
370
+ `continuity`,
371
+ syncGroupKey,
372
+ `redacting updates from ${transactionUpdate.epoch}:${transactionUpdate.key}:${transactionUpdate.id}`,
373
+ visible,
374
+ transactionUpdate.updates
375
+ );
376
+ const updates = transactionUpdate.updates.filter((update) => {
377
+ if (`newValue` in update) {
378
+ return visible.includes(update.key);
379
+ }
380
+ return true;
381
+ }).map((update) => {
382
+ if (`updates` in update) {
383
+ return filterTransactionUpdate(visible, update);
384
+ }
385
+ return update;
386
+ });
387
+ const filtered = __spreadProps(__spreadValues({}, transactionUpdate), {
388
+ updates
389
+ });
390
+ return filtered;
391
+ };
392
+ const filter = (update) => {
393
+ const visibleKeys = syncGroup.globals.map(
394
+ (atomToken) => atomToken.type === `mutable_atom` ? internal.getUpdateToken(atomToken).key : atomToken.key
395
+ );
396
+ visibleKeys.push(...userPerspectiveTokens);
397
+ return filterTransactionUpdate(visibleKeys, update);
398
+ };
399
+ return filter;
400
+ }
54
401
  });
55
- var usersOfSockets = data.join({
56
- key: `usersOfSockets`,
57
- between: [`user`, `socket`],
58
- cardinality: `1:1`
402
+ var roomArgumentsAtoms = AtomIO.atomFamily({
403
+ key: `roomArguments`,
404
+ default: [`echo`, [`Hello World!`]]
59
405
  });
60
- var roomIndex = AtomIO.atom({
61
- key: `conclaveIndex`,
62
- default: () => new setRtx.SetRTX(),
63
- mutable: true,
64
- toJson: (set) => set.toJSON(),
65
- fromJson: (json) => setRtx.SetRTX.fromJSON(json)
406
+ var roomSelectors = AtomIO.selectorFamily({
407
+ key: `room`,
408
+ get: (roomId) => async ({ get, find }) => {
409
+ const argumentsState = find(roomArgumentsAtoms, roomId);
410
+ const args = get(argumentsState);
411
+ const [script, options] = args;
412
+ const child = await new Promise(
413
+ (resolve) => {
414
+ const room = child_process.spawn(script, options, { env: process.env });
415
+ const resolver = (data) => {
416
+ if (data.toString() === `\u2728`) {
417
+ room.stdout.off(`data`, resolver);
418
+ resolve(room);
419
+ }
420
+ };
421
+ room.stdout.on(`data`, resolver);
422
+ }
423
+ );
424
+ return new ChildSocket(child, roomId);
425
+ }
66
426
  });
67
- var DEFAULT_USER_IN_ROOM_META = {
68
- enteredAtEpoch: 0
69
- };
70
- var usersInRooms = data.join(
71
- {
72
- key: `usersInRooms`,
73
- between: [`room`, `user`],
74
- cardinality: `1:n`
75
- },
76
- DEFAULT_USER_IN_ROOM_META
77
- );
78
- var completeUpdateAtoms = AtomIO.atomFamily({
79
- key: `completeUpdate`,
80
- default: null
427
+
428
+ // realtime-server/src/realtime-server-stores/server-room-external-actions.ts
429
+ var createRoomTX = AtomIO__namespace.transaction({
430
+ key: `createRoom`,
431
+ do: ({ get, set, find }, roomId, script, options) => {
432
+ const args = options ? [script, options] : [script];
433
+ const roomArgumentsState = find(roomArgumentsAtoms, roomId);
434
+ set(roomArgumentsState, args);
435
+ set(realtime.roomIndex, (s) => s.add(roomId));
436
+ const roomState = find(roomSelectors, roomId);
437
+ const room = get(roomState);
438
+ return room;
439
+ }
81
440
  });
82
- var transactionRedactorAtoms = AtomIO.atomFamily({
83
- key: `transactionRedactor`,
84
- default: { filter: (updates) => updates }
441
+ var joinRoomTX = AtomIO__namespace.transaction({
442
+ key: `joinRoom`,
443
+ do: (transactors, roomId, userId, enteredAtEpoch) => {
444
+ const meta = { enteredAtEpoch };
445
+ realtime.usersInRooms.transact(transactors, ({ relations }) => {
446
+ relations.set(roomId, userId, meta);
447
+ });
448
+ return meta;
449
+ }
85
450
  });
86
- var redactedUpdateSelectors = AtomIO.selectorFamily({
87
- key: `redactedUpdate`,
88
- get: ([transactionKey, updateId]) => ({ get, find }) => {
89
- const update = get(find(completeUpdateAtoms, updateId));
90
- const { filter } = get(find(transactionRedactorAtoms, transactionKey));
91
- if (update && filter) {
92
- return __spreadProps(__spreadValues({}, update), { updates: filter(update.updates) });
93
- }
94
- return null;
451
+ var leaveRoomTX = AtomIO__namespace.transaction({
452
+ key: `leaveRoom`,
453
+ do: (transactors, roomId, userId) => {
454
+ realtime.usersInRooms.transact(transactors, ({ relations }) => {
455
+ relations.delete({ room: roomId, user: userId });
456
+ });
95
457
  }
96
458
  });
97
- var userUnacknowledgedUpdatesAtoms = AtomIO.atomFamily({
98
- key: `unacknowledgedUpdates`,
99
- default: () => []
459
+ var destroyRoomTX = AtomIO__namespace.transaction({
460
+ key: `destroyRoom`,
461
+ do: (transactors, roomId) => {
462
+ realtime.usersInRooms.transact(transactors, ({ relations }) => {
463
+ relations.delete({ room: roomId });
464
+ });
465
+ transactors.set(realtime.roomIndex, (s) => (s.delete(roomId), s));
466
+ }
100
467
  });
101
- var socketUnacknowledgedUpdatesSelectors = AtomIO.selectorFamily({
102
- key: `socketUnacknowledgedUpdates`,
103
- get: (socketId) => ({ get, find }) => {
104
- const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
105
- const userKey = get(userKeyState);
106
- if (!userKey) {
107
- return [];
468
+ function redactTransactionUpdateContent(visibleStateKeys, updates) {
469
+ return updates.map((update) => {
470
+ if (`newValue` in update) {
471
+ return update;
108
472
  }
109
- const unacknowledgedUpdatesState = find(
110
- userUnacknowledgedUpdatesAtoms,
111
- userKey
473
+ const redacted = redactTransactionUpdateContent(
474
+ visibleStateKeys,
475
+ update.updates
112
476
  );
113
- const unacknowledgedUpdates = get(unacknowledgedUpdatesState);
114
- return unacknowledgedUpdates;
115
- },
116
- set: (socketId) => ({ set, get, find }, newUpdates) => {
117
- const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
118
- const userKey = get(userKeyState);
119
- if (!userKey) {
120
- return;
477
+ return __spreadProps(__spreadValues({}, update), { updates: redacted });
478
+ }).filter((update) => {
479
+ if (`newValue` in update) {
480
+ return visibleStateKeys.includes(update.key);
121
481
  }
122
- const unacknowledgedUpdatesState = find(
123
- userUnacknowledgedUpdatesAtoms,
124
- userKey
125
- );
126
- set(unacknowledgedUpdatesState, newUpdates);
127
- }
482
+ return true;
483
+ });
484
+ }
485
+ var actionOcclusionAtoms = AtomIO.atomFamily({
486
+ key: `transactionRedactor`,
487
+ default: { occlude: (updates) => updates }
128
488
  });
129
- var userEpochAtoms = AtomIO.atomFamily({
130
- key: `clientEpoch`,
489
+ var userUnacknowledgedQueues = AtomIO.atomFamily({
490
+ key: `unacknowledgedUpdates`,
491
+ default: () => []
492
+ });
493
+ var socketAtoms = AtomIO.atomFamily({
494
+ key: `sockets`,
131
495
  default: null
132
496
  });
133
- var socketEpochSelectors = AtomIO.selectorFamily({
134
- key: `socketEpoch`,
135
- get: (socketId) => ({ get, find }) => {
136
- const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
137
- const userKey = get(userKeyState);
138
- if (!userKey) {
139
- return null;
140
- }
141
- const userEpochState = find(userEpochAtoms, userKey);
142
- const userEpoch = get(userEpochState);
143
- return userEpoch;
144
- },
145
- set: (socketId) => ({ set, get, find }, newEpoch) => {
146
- const userKeyState = find(usersOfSockets.states.userKeyOfSocket, socketId);
147
- const userKey = get(userKeyState);
497
+ var socketIndex = AtomIO.atom({
498
+ key: `socketsIndex`,
499
+ mutable: true,
500
+ default: () => new setRtx.SetRTX(),
501
+ toJson: (set) => set.toJSON(),
502
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
503
+ });
504
+ var userIndex = AtomIO.atom({
505
+ key: `usersIndex`,
506
+ mutable: true,
507
+ default: () => new setRtx.SetRTX(),
508
+ toJson: (set) => set.toJSON(),
509
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
510
+ });
511
+ var usersOfSockets = data.join({
512
+ key: `usersOfSockets`,
513
+ between: [`user`, `socket`],
514
+ cardinality: `1:1`
515
+ });
516
+
517
+ // realtime-server/src/realtime-continuity-synchronizer.ts
518
+ function realtimeContinuitySynchronizer({
519
+ socket: initialSocket,
520
+ store = internal.IMPLICIT.STORE
521
+ }) {
522
+ return function synchronizer(continuity) {
523
+ let socket = initialSocket;
524
+ const continuityKey = continuity.key;
525
+ const userKeyState = internal.findInStore(
526
+ usersOfSockets.states.userKeyOfSocket,
527
+ socket.id,
528
+ store
529
+ );
530
+ const userKey = internal.getFromStore(userKeyState, store);
148
531
  if (!userKey) {
149
- return;
532
+ store.logger.error(
533
+ `\u274C`,
534
+ `continuity`,
535
+ continuityKey,
536
+ `Tried to create a synchronizer for a socket (${socket.id}) that is not connected to a user.`
537
+ );
538
+ return () => {
539
+ };
150
540
  }
151
- const userEpochState = find(userEpochAtoms, userKey);
152
- set(userEpochState, newEpoch);
153
- }
154
- });
541
+ const socketKeyState = internal.findInStore(
542
+ usersOfSockets.states.socketKeyOfUser,
543
+ userKey,
544
+ store
545
+ );
546
+ internal.subscribeToState(
547
+ socketKeyState,
548
+ ({ newValue: newSocketKey }) => {
549
+ store.logger.info(
550
+ `\u{1F44B}`,
551
+ `continuity`,
552
+ continuityKey,
553
+ `seeing ${userKey} on new socket ${newSocketKey}`
554
+ );
555
+ if (newSocketKey === null) {
556
+ store.logger.error(
557
+ `\u274C`,
558
+ `continuity`,
559
+ continuityKey,
560
+ `Tried to create a synchronizer for a user (${userKey}) that is not connected to a socket.`
561
+ );
562
+ return;
563
+ }
564
+ const newSocketState = internal.findInStore(socketAtoms, newSocketKey, store);
565
+ const newSocket = internal.getFromStore(newSocketState, store);
566
+ socket = newSocket;
567
+ },
568
+ `sync-continuity:${continuityKey}:${userKey}`,
569
+ store
570
+ );
571
+ const userUnacknowledgedQueue = internal.findInStore(
572
+ userUnacknowledgedQueues,
573
+ userKey,
574
+ store
575
+ );
576
+ internal.getFromStore(
577
+ userUnacknowledgedQueue,
578
+ store
579
+ );
580
+ const unsubscribeFunctions = [];
581
+ const revealPerspectives = () => {
582
+ const unsubscribeFunctions2 = [];
583
+ for (const perspective of continuity.perspectives) {
584
+ const { viewAtoms } = perspective;
585
+ const userViewState = internal.findInStore(viewAtoms, userKey, store);
586
+ const unsubscribe = internal.subscribeToState(
587
+ userViewState,
588
+ ({ oldValue, newValue }) => {
589
+ const oldKeys = oldValue.map((token) => token.key);
590
+ const newKeys = newValue.map((token) => token.key);
591
+ const concealed = oldValue.filter(
592
+ (token) => !newKeys.includes(token.key)
593
+ );
594
+ const revealed = newValue.filter((token) => !oldKeys.includes(token.key)).flatMap((token) => {
595
+ const resourceToken = token.type === `mutable_atom` ? internal.getJsonToken(token) : token;
596
+ const resource = internal.getFromStore(resourceToken, store);
597
+ return [resourceToken, resource];
598
+ });
599
+ store.logger.info(
600
+ `\u{1F441}`,
601
+ `atom`,
602
+ perspective.resourceAtoms.key,
603
+ `${userKey} has a new perspective`,
604
+ { oldKeys, newKeys, revealed, concealed }
605
+ );
606
+ if (revealed.length > 0) {
607
+ socket == null ? void 0 : socket.emit(`reveal:${continuityKey}`, revealed);
608
+ }
609
+ if (concealed.length > 0) {
610
+ socket == null ? void 0 : socket.emit(`conceal:${continuityKey}`, concealed);
611
+ }
612
+ },
613
+ `sync-continuity:${continuityKey}:${userKey}:perspective:${perspective.resourceAtoms.key}`,
614
+ store
615
+ );
616
+ unsubscribeFunctions2.push(unsubscribe);
617
+ }
618
+ return () => {
619
+ for (const unsubscribe of unsubscribeFunctions2)
620
+ unsubscribe();
621
+ };
622
+ };
623
+ const unsubscribeFromPerspectives = revealPerspectives();
624
+ const sendInitialPayload = () => {
625
+ var _a;
626
+ const initialPayload = [];
627
+ for (const atom2 of continuity.globals) {
628
+ const resourceToken = atom2.type === `mutable_atom` ? internal.getJsonToken(atom2) : atom2;
629
+ initialPayload.push(resourceToken, internal.getFromStore(atom2, store));
630
+ }
631
+ for (const perspective of continuity.perspectives) {
632
+ const { viewAtoms, resourceAtoms } = perspective;
633
+ const userViewState = internal.findInStore(viewAtoms, userKey, store);
634
+ const userView = internal.getFromStore(userViewState, store);
635
+ store.logger.info(`\u{1F441}`, `atom`, resourceAtoms.key, `${userKey} can see`, {
636
+ viewAtoms,
637
+ resourceAtoms,
638
+ userView
639
+ });
640
+ for (const visibleToken of userView) {
641
+ const resourceToken = visibleToken.type === `mutable_atom` ? internal.getJsonToken(visibleToken) : visibleToken;
642
+ const resource = internal.getFromStore(resourceToken, store);
643
+ initialPayload.push(resourceToken, resource);
644
+ }
645
+ }
646
+ const epoch = internal.isRootStore(store) ? (_a = store.transactionMeta.epoch.get(continuityKey)) != null ? _a : null : null;
647
+ socket == null ? void 0 : socket.emit(`continuity-init:${continuityKey}`, epoch, initialPayload);
648
+ for (const transaction2 of continuity.actions) {
649
+ const unsubscribeFromTransaction = internal.subscribeToTransaction(
650
+ transaction2,
651
+ (update) => {
652
+ try {
653
+ const visibleKeys = continuity.globals.map((atom2) => atom2.key).concat(
654
+ continuity.perspectives.flatMap((perspective) => {
655
+ const { viewAtoms } = perspective;
656
+ const userPerspectiveTokenState = internal.findInStore(
657
+ viewAtoms,
658
+ userKey,
659
+ store
660
+ );
661
+ const visibleTokens = internal.getFromStore(
662
+ userPerspectiveTokenState,
663
+ store
664
+ );
665
+ return visibleTokens.map((token) => {
666
+ const key = token.type === `mutable_atom` ? `*` + token.key : token.key;
667
+ return key;
668
+ });
669
+ })
670
+ );
671
+ const redactedUpdates = redactTransactionUpdateContent(
672
+ visibleKeys,
673
+ update.updates
674
+ );
675
+ const redactedUpdate = __spreadProps(__spreadValues({}, update), {
676
+ updates: redactedUpdates
677
+ });
678
+ socket == null ? void 0 : socket.emit(
679
+ `tx-new:${continuityKey}`,
680
+ redactedUpdate
681
+ );
682
+ } catch (thrown) {
683
+ if (thrown instanceof Error) {
684
+ store.logger.error(
685
+ `\u274C`,
686
+ `continuity`,
687
+ continuityKey,
688
+ `failed to send update from transaction ${transaction2.key} to ${userKey}`,
689
+ thrown.message
690
+ );
691
+ }
692
+ }
693
+ },
694
+ `sync-continuity:${continuityKey}:${userKey}`,
695
+ store
696
+ );
697
+ unsubscribeFunctions.push(unsubscribeFromTransaction);
698
+ }
699
+ };
700
+ socket.off(`get:${continuityKey}`, sendInitialPayload);
701
+ socket.on(`get:${continuityKey}`, sendInitialPayload);
702
+ const fillTransactionRequest = (update) => {
703
+ store.logger.info(`\u{1F6CE}\uFE0F`, `continuity`, continuityKey, `received`, update);
704
+ const transactionKey = update.key;
705
+ const updateId = update.id;
706
+ const performanceKey = `tx-run:${transactionKey}:${updateId}`;
707
+ const performanceKeyStart = `${performanceKey}:start`;
708
+ const performanceKeyEnd = `${performanceKey}:end`;
709
+ performance.mark(performanceKeyStart);
710
+ try {
711
+ internal.actUponStore(
712
+ { type: `transaction`, key: transactionKey },
713
+ updateId,
714
+ store
715
+ )(...update.params);
716
+ } catch (thrown) {
717
+ if (thrown instanceof Error) {
718
+ store.logger.error(
719
+ `\u274C`,
720
+ `continuity`,
721
+ continuityKey,
722
+ `failed to run transaction ${transactionKey} with update ${updateId}`,
723
+ thrown.message
724
+ );
725
+ }
726
+ }
727
+ performance.mark(performanceKeyEnd);
728
+ const metric = performance.measure(
729
+ performanceKey,
730
+ performanceKeyStart,
731
+ performanceKeyEnd
732
+ );
733
+ store == null ? void 0 : store.logger.info(
734
+ `\u{1F680}`,
735
+ `transaction`,
736
+ transactionKey,
737
+ updateId,
738
+ metric.duration
739
+ );
740
+ const valuesOfCardsViewKey = `valuesOfCardsView("${userKey}")`;
741
+ const rootsOfCardValueView = store.selectorAtoms.getRelatedKeys(valuesOfCardsViewKey);
742
+ const myCardValueView = store.valueMap.get(valuesOfCardsViewKey);
743
+ store.logger.info(
744
+ `\u{1F441}`,
745
+ `continuity`,
746
+ continuityKey,
747
+ `seeing ${userKey} card values`,
748
+ {
749
+ valuesOfCardsViewKey,
750
+ rootsOfCardValueView,
751
+ myCardValueView
752
+ }
753
+ );
754
+ };
755
+ socket.off(`tx-run:${continuityKey}`, fillTransactionRequest);
756
+ socket.on(`tx-run:${continuityKey}`, fillTransactionRequest);
757
+ return () => {
758
+ for (const unsubscribe of unsubscribeFunctions)
759
+ unsubscribe();
760
+ unsubscribeFromPerspectives();
761
+ socket == null ? void 0 : socket.off(`get:${continuityKey}`, sendInitialPayload);
762
+ socket == null ? void 0 : socket.off(`tx-run:${continuityKey}`, fillTransactionRequest);
763
+ };
764
+ };
765
+ }
155
766
  function realtimeStateProvider({
156
767
  socket,
157
768
  store = internal.IMPLICIT.STORE
@@ -201,89 +812,49 @@ function realtimeStateSynchronizer({
201
812
  };
202
813
  };
203
814
  }
204
- function realtimeFamilyProvider({
815
+ function realtimeAtomFamilyProvider({
205
816
  socket,
206
817
  store = internal.IMPLICIT.STORE
207
818
  }) {
208
819
  return function familyProvider(family, index) {
209
- const unsubSingleCallbacksByKey = /* @__PURE__ */ new Map();
210
- const unsubFamilyCallbacksByKey = /* @__PURE__ */ new Map();
211
- const fillFamilyUnsubRequest = () => {
212
- for (const [, unsub] of unsubFamilyCallbacksByKey) {
213
- unsub();
214
- }
215
- unsubFamilyCallbacksByKey.clear();
216
- socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest);
217
- };
218
- const fillSingleUnsubRequest = (key) => {
219
- socket.off(`unsub:${key}`, fillSingleUnsubRequest);
220
- const unsub = unsubSingleCallbacksByKey.get(key);
820
+ const unsubCallbacksByKey = /* @__PURE__ */ new Map();
821
+ const fillUnsubRequest = (key) => {
822
+ socket.off(`unsub:${key}`, fillUnsubRequest);
823
+ const unsub = unsubCallbacksByKey.get(key);
221
824
  if (unsub) {
222
825
  unsub();
223
- unsubSingleCallbacksByKey.delete(key);
826
+ unsubCallbacksByKey.delete(key);
224
827
  }
225
828
  };
226
829
  const fillSubRequest = (subKey) => {
227
- var _a;
228
- if (subKey === void 0) {
229
- const keys = internal.getFromStore(index, store);
230
- for (const key of keys) {
231
- const token = internal.findInStore(family, key, store);
232
- socket.emit(
233
- `serve:${family.key}`,
234
- json.parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
235
- internal.getFromStore(token, store)
830
+ const exposedSubKeys = internal.getFromStore(index, store);
831
+ for (const exposedSubKey of exposedSubKeys) {
832
+ if (json.stringifyJson(exposedSubKey) === json.stringifyJson(subKey)) {
833
+ const token = internal.findInStore(family, subKey, store);
834
+ socket.emit(`serve:${token.key}`, internal.getFromStore(token, store));
835
+ const unsubscribe = internal.subscribeToState(
836
+ token,
837
+ ({ newValue }) => {
838
+ socket.emit(`serve:${token.key}`, newValue);
839
+ },
840
+ `expose-family:${family.key}:${socket.id}`,
841
+ store
236
842
  );
843
+ unsubCallbacksByKey.set(token.key, unsubscribe);
844
+ socket.on(`unsub:${token.key}`, () => {
845
+ fillUnsubRequest(token.key);
846
+ });
847
+ break;
237
848
  }
238
- const unsubscribeFromTokenCreation = family.subject.subscribe(
239
- `expose-family:${socket.id}`,
240
- (token) => {
241
- const unsub = internal.subscribeToState(
242
- token,
243
- ({ newValue }) => {
244
- var _a2;
245
- socket.emit(
246
- `serve:${family.key}`,
247
- json.parseJson(((_a2 = token.family) == null ? void 0 : _a2.subKey) || `null`),
248
- newValue
249
- );
250
- },
251
- `expose-family:${family.key}:${socket.id}`,
252
- store
253
- );
254
- unsubFamilyCallbacksByKey.set(token.key, unsub);
255
- }
256
- );
257
- unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation);
258
- socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest);
259
- } else {
260
- const token = family(subKey);
261
- socket.emit(`serve:${token.key}`, internal.getFromStore(token, store));
262
- const unsubscribe = internal.subscribeToState(
263
- token,
264
- ({ newValue }) => {
265
- socket.emit(`serve:${token.key}`, newValue);
266
- },
267
- `expose-family:${family.key}:${socket.id}`,
268
- store
269
- );
270
- unsubSingleCallbacksByKey.set(token.key, unsubscribe);
271
- socket.on(`unsub:${token.key}`, () => {
272
- fillSingleUnsubRequest(token.key);
273
- });
274
849
  }
275
850
  };
276
851
  socket.on(`sub:${family.key}`, fillSubRequest);
277
852
  return () => {
278
853
  socket.off(`sub:${family.key}`, fillSubRequest);
279
- for (const [, unsub] of unsubFamilyCallbacksByKey) {
280
- unsub();
281
- }
282
- for (const [, unsub] of unsubSingleCallbacksByKey) {
854
+ for (const [, unsub] of unsubCallbacksByKey) {
283
855
  unsub();
284
856
  }
285
- unsubFamilyCallbacksByKey.clear();
286
- unsubSingleCallbacksByKey.clear();
857
+ unsubCallbacksByKey.clear();
287
858
  };
288
859
  };
289
860
  }
@@ -324,110 +895,46 @@ function realtimeMutableFamilyProvider({
324
895
  store = internal.IMPLICIT.STORE
325
896
  }) {
326
897
  return function mutableFamilyProvider(family, index) {
327
- const unsubSingleCallbacksByKey = /* @__PURE__ */ new Map();
328
- const unsubFamilyCallbacksByKey = /* @__PURE__ */ new Map();
329
- const fillFamilyUnsubRequest = () => {
330
- for (const [, unsub] of unsubFamilyCallbacksByKey) {
331
- unsub();
332
- }
333
- unsubFamilyCallbacksByKey.clear();
334
- socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest);
335
- };
336
- const fillSingleUnsubRequest = (key) => {
337
- socket.off(`unsub:${key}`, fillSingleUnsubRequest);
338
- const unsub = unsubSingleCallbacksByKey.get(key);
898
+ const unsubCallbacksByKey = /* @__PURE__ */ new Map();
899
+ const fillUnsubRequest = (key) => {
900
+ socket.off(`unsub:${key}`, fillUnsubRequest);
901
+ const unsub = unsubCallbacksByKey.get(key);
339
902
  if (unsub) {
340
903
  unsub();
341
- unsubSingleCallbacksByKey.delete(key);
904
+ unsubCallbacksByKey.delete(key);
342
905
  }
343
906
  };
344
907
  const fillSubRequest = (subKey) => {
345
- var _a;
346
- if (subKey === void 0) {
347
- const keys = internal.getFromStore(index, store);
348
- for (const key of keys) {
349
- const token = internal.findInStore(family, key, store);
908
+ const exposedSubKeys = internal.getFromStore(index, store);
909
+ for (const exposedSubKey of exposedSubKeys) {
910
+ if (json.stringifyJson(exposedSubKey) === json.stringifyJson(subKey)) {
911
+ const token = internal.findInStore(family, subKey, store);
350
912
  const jsonToken = internal.getJsonToken(token);
351
- const trackerToken = internal.getUpdateToken(token);
352
- socket.emit(
353
- `init:${family.key}`,
354
- json.parseJson(((_a = jsonToken.family) == null ? void 0 : _a.subKey) || `null`),
355
- internal.getFromStore(jsonToken, store)
356
- );
357
- const unsubFromUpdates = internal.subscribeToState(
358
- trackerToken,
913
+ const updateToken = internal.getUpdateToken(token);
914
+ socket.emit(`init:${token.key}`, internal.getFromStore(jsonToken, store));
915
+ const unsubscribe = internal.subscribeToState(
916
+ updateToken,
359
917
  ({ newValue }) => {
360
- var _a2;
361
- socket.emit(
362
- `next:${token.key}`,
363
- json.parseJson(((_a2 = jsonToken.family) == null ? void 0 : _a2.subKey) || `null`),
364
- newValue
365
- );
918
+ socket.emit(`next:${token.key}`, newValue);
366
919
  },
367
920
  `expose-family:${family.key}:${socket.id}`,
368
921
  store
369
922
  );
370
- unsubFamilyCallbacksByKey.set(token.key, unsubFromUpdates);
923
+ unsubCallbacksByKey.set(token.key, unsubscribe);
924
+ socket.on(`unsub:${token.key}`, () => {
925
+ fillUnsubRequest(token.key);
926
+ });
927
+ break;
371
928
  }
372
- const unsubscribeFromTokenCreation = family.subject.subscribe(
373
- `expose-family:${socket.id}`,
374
- (token) => {
375
- var _a2;
376
- const jsonToken = internal.getJsonToken(token);
377
- const trackerToken = internal.getUpdateToken(token);
378
- socket.emit(
379
- `init:${family.key}`,
380
- json.parseJson(((_a2 = jsonToken.family) == null ? void 0 : _a2.subKey) || `null`),
381
- internal.getFromStore(jsonToken, store)
382
- );
383
- const unsubFromUpdates = internal.subscribeToState(
384
- trackerToken,
385
- ({ newValue }) => {
386
- var _a3;
387
- socket.emit(
388
- `next:${token.key}`,
389
- json.parseJson(((_a3 = jsonToken.family) == null ? void 0 : _a3.subKey) || `null`),
390
- newValue
391
- );
392
- },
393
- `expose-family:${family.key}:${socket.id}`,
394
- store
395
- );
396
- unsubFamilyCallbacksByKey.set(token.key, unsubFromUpdates);
397
- }
398
- );
399
- unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation);
400
- socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest);
401
- } else {
402
- const token = family(subKey);
403
- const jsonToken = internal.getJsonToken(token);
404
- const updateToken = internal.getUpdateToken(token);
405
- socket.emit(`init:${token.key}`, internal.getFromStore(jsonToken, store));
406
- const unsubscribe = internal.subscribeToState(
407
- updateToken,
408
- ({ newValue }) => {
409
- socket.emit(`next:${token.key}`, newValue);
410
- },
411
- `expose-family:${family.key}:${socket.id}`,
412
- store
413
- );
414
- unsubSingleCallbacksByKey.set(token.key, unsubscribe);
415
- socket.on(`unsub:${token.key}`, () => {
416
- fillSingleUnsubRequest(token.key);
417
- });
418
929
  }
419
930
  };
420
931
  socket.on(`sub:${family.key}`, fillSubRequest);
421
932
  return () => {
422
933
  socket.off(`sub:${family.key}`, fillSubRequest);
423
- for (const [, unsub] of unsubFamilyCallbacksByKey) {
424
- unsub();
425
- }
426
- for (const [, unsub] of unsubSingleCallbacksByKey) {
934
+ for (const [, unsub] of unsubCallbacksByKey) {
427
935
  unsub();
428
936
  }
429
- unsubFamilyCallbacksByKey.clear();
430
- unsubSingleCallbacksByKey.clear();
937
+ unsubCallbacksByKey.clear();
431
938
  };
432
939
  };
433
940
  }
@@ -462,7 +969,7 @@ function realtimeActionReceiver({
462
969
  const performanceKeyStart = `${performanceKey}:start`;
463
970
  const performanceKeyEnd = `${performanceKey}:end`;
464
971
  performance.mark(performanceKeyStart);
465
- AtomIO__namespace.runTransaction(tx, update.id, store)(...update.params);
972
+ internal.actUponStore(tx, update.id, store)(...update.params);
466
973
  performance.mark(performanceKeyEnd);
467
974
  const metric = performance.measure(
468
975
  performanceKey,
@@ -475,140 +982,31 @@ function realtimeActionReceiver({
475
982
  return () => socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
476
983
  };
477
984
  }
478
- function realtimeActionSynchronizer({
479
- socket,
480
- store = internal.IMPLICIT.STORE
481
- }) {
482
- return function actionSynchronizer(tx, filter) {
483
- const userKeyState = internal.findInStore(
484
- usersOfSockets.states.userKeyOfSocket,
485
- socket.id,
486
- store
487
- );
488
- const userKey = internal.getFromStore(userKeyState, store);
489
- const socketUnacknowledgedUpdatesState = internal.findInStore(
490
- socketUnacknowledgedUpdatesSelectors,
491
- socket.id,
492
- store
493
- );
494
- const socketUnacknowledgedUpdates = internal.getFromStore(
495
- socketUnacknowledgedUpdatesState,
496
- store
497
- );
498
- if (filter) {
499
- const redactorState = internal.findInStore(transactionRedactorAtoms, tx.key, store);
500
- internal.setIntoStore(redactorState, { filter }, store);
501
- }
502
- const fillTransactionRequest = (update) => {
503
- const performanceKey = `tx-run:${tx.key}:${update.id}`;
504
- const performanceKeyStart = `${performanceKey}:start`;
505
- const performanceKeyEnd = `${performanceKey}:end`;
506
- performance.mark(performanceKeyStart);
507
- AtomIO__namespace.runTransaction(tx, update.id, store)(...update.params);
508
- performance.mark(performanceKeyEnd);
509
- const metric = performance.measure(
510
- performanceKey,
511
- performanceKeyStart,
512
- performanceKeyEnd
513
- );
514
- store == null ? void 0 : store.logger.info(`\u{1F680}`, `transaction`, tx.key, update.id, metric.duration);
515
- };
516
- socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
517
- socket.on(`tx-run:${tx.key}`, fillTransactionRequest);
518
- let unsubscribeFromTransaction;
519
- const fillTransactionSubscriptionRequest = () => {
520
- unsubscribeFromTransaction = internal.subscribeToTransaction(
521
- tx,
522
- (update) => {
523
- const updateState = internal.findInStore(completeUpdateAtoms, update.id, store);
524
- internal.setIntoStore(updateState, update, store);
525
- const toEmit = filter ? internal.getFromStore(
526
- internal.findInStore(redactedUpdateSelectors, [tx.key, update.id], store),
527
- store
528
- ) : update;
529
- internal.setIntoStore(
530
- socketUnacknowledgedUpdatesState,
531
- (updates) => {
532
- if (toEmit) {
533
- updates.push(toEmit);
534
- updates.sort((a, b) => a.epoch - b.epoch);
535
- }
536
- return updates;
537
- },
538
- store
539
- );
540
- socket.emit(`tx-new:${tx.key}`, toEmit);
541
- },
542
- `tx-sub:${tx.key}:${socket.id}`,
543
- store
544
- );
545
- socket.on(`tx-unsub:${tx.key}`, unsubscribeFromTransaction);
546
- };
547
- socket.on(`tx-sub:${tx.key}`, fillTransactionSubscriptionRequest);
548
- let i = 1;
549
- let next = 1;
550
- const retry = setInterval(() => {
551
- const toEmit = socketUnacknowledgedUpdates[0];
552
- console.log(userKey, socketUnacknowledgedUpdates);
553
- if (toEmit && i === next) {
554
- socket.emit(`tx-new:${tx.key}`, toEmit);
555
- next *= 2;
556
- }
557
- i++;
558
- }, 250);
559
- const trackClientAcknowledgement = (epoch) => {
560
- var _a;
561
- i = 1;
562
- next = 1;
563
- const socketEpochState = internal.findInStore(
564
- socketEpochSelectors,
565
- socket.id,
566
- store
567
- );
568
- internal.setIntoStore(socketEpochState, epoch, store);
569
- if (((_a = socketUnacknowledgedUpdates[0]) == null ? void 0 : _a.epoch) === epoch) {
570
- internal.setIntoStore(
571
- socketUnacknowledgedUpdatesState,
572
- (updates) => {
573
- updates.shift();
574
- return updates;
575
- },
576
- store
577
- );
578
- }
579
- };
580
- socket.on(`tx-ack:${tx.key}`, trackClientAcknowledgement);
581
- return () => {
582
- if (unsubscribeFromTransaction) {
583
- unsubscribeFromTransaction();
584
- unsubscribeFromTransaction = void 0;
585
- }
586
- clearInterval(retry);
587
- socket.off(`tx-run:${tx.key}`, fillTransactionRequest);
588
- socket.off(`tx-sub:${tx.key}`, fillTransactionSubscriptionRequest);
589
- };
590
- };
591
- }
592
985
 
593
- exports.DEFAULT_USER_IN_ROOM_META = DEFAULT_USER_IN_ROOM_META;
594
- exports.completeUpdateAtoms = completeUpdateAtoms;
986
+ exports.ChildSocket = ChildSocket;
987
+ exports.CustomSocket = CustomSocket;
988
+ exports.ParentSocket = ParentSocket;
989
+ exports.SubjectSocket = SubjectSocket;
990
+ exports.actionOcclusionAtoms = actionOcclusionAtoms;
991
+ exports.createRoomTX = createRoomTX;
992
+ exports.destroyRoomTX = destroyRoomTX;
993
+ exports.joinRoomTX = joinRoomTX;
994
+ exports.leaveRoomTX = leaveRoomTX;
595
995
  exports.realtimeActionReceiver = realtimeActionReceiver;
596
- exports.realtimeActionSynchronizer = realtimeActionSynchronizer;
597
- exports.realtimeFamilyProvider = realtimeFamilyProvider;
996
+ exports.realtimeAtomFamilyProvider = realtimeAtomFamilyProvider;
997
+ exports.realtimeContinuitySynchronizer = realtimeContinuitySynchronizer;
598
998
  exports.realtimeMutableFamilyProvider = realtimeMutableFamilyProvider;
599
999
  exports.realtimeMutableProvider = realtimeMutableProvider;
600
1000
  exports.realtimeStateProvider = realtimeStateProvider;
601
1001
  exports.realtimeStateReceiver = realtimeStateReceiver;
602
1002
  exports.realtimeStateSynchronizer = realtimeStateSynchronizer;
603
- exports.redactedUpdateSelectors = redactedUpdateSelectors;
604
- exports.roomIndex = roomIndex;
605
- exports.socketEpochSelectors = socketEpochSelectors;
606
- exports.socketUnacknowledgedUpdatesSelectors = socketUnacknowledgedUpdatesSelectors;
607
- exports.transactionRedactorAtoms = transactionRedactorAtoms;
608
- exports.userEpochAtoms = userEpochAtoms;
1003
+ exports.redactTransactionUpdateContent = redactTransactionUpdateContent;
1004
+ exports.roomArgumentsAtoms = roomArgumentsAtoms;
1005
+ exports.roomSelectors = roomSelectors;
1006
+ exports.socketAtoms = socketAtoms;
1007
+ exports.socketIndex = socketIndex;
609
1008
  exports.userIndex = userIndex;
610
- exports.userUnacknowledgedUpdatesAtoms = userUnacknowledgedUpdatesAtoms;
611
- exports.usersInRooms = usersInRooms;
1009
+ exports.userUnacknowledgedQueues = userUnacknowledgedQueues;
612
1010
  exports.usersOfSockets = usersOfSockets;
613
1011
  //# sourceMappingURL=out.js.map
614
1012
  //# sourceMappingURL=index.cjs.map