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