tempest.games 0.2.105 → 0.3.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/CHANGELOG.md +12 -0
- package/app/assets/index-92RdVh_1.css +1 -0
- package/app/assets/index-CHjZDDSa.js +4123 -0
- package/app/index.html +8 -3
- package/bin/backend.bun.js +66754 -63903
- package/bin/backend.worker.bug-rangers.bun.js +28827 -0
- package/bin/backend.worker.tribunal.bun.js +44184 -41668
- package/bin/frontend.bun.js +16232 -13716
- package/bin/setup-db.bun.js +3 -1
- package/index.html +6 -1
- package/package.json +13 -6
- package/app/assets/index-BuI4xz01.js +0 -66
- package/app/assets/index-DZ_4vJcE.css +0 -1
- package/bin/backend.worker.game.bun.js +0 -3393
|
@@ -1,3393 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
// @bun
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
-
var __defProp = Object.defineProperty;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
-
for (let key of __getOwnPropNames(mod))
|
|
12
|
-
if (!__hasOwnProp.call(to, key))
|
|
13
|
-
__defProp(to, key, {
|
|
14
|
-
get: () => mod[key],
|
|
15
|
-
enumerable: true
|
|
16
|
-
});
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, {
|
|
23
|
-
get: all[name],
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
set: (newValue) => all[name] = () => newValue
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
|
-
var __require = import.meta.require;
|
|
31
|
-
|
|
32
|
-
// ../../packages/atom.io/dist/main/index.js
|
|
33
|
-
function mutableAtom(options) {
|
|
34
|
-
return createMutableAtom(IMPLICIT.STORE, options, undefined);
|
|
35
|
-
}
|
|
36
|
-
function atomFamily(options) {
|
|
37
|
-
return createRegularAtomFamily(IMPLICIT.STORE, options);
|
|
38
|
-
}
|
|
39
|
-
function getState(...params) {
|
|
40
|
-
return getFromStore(IMPLICIT.STORE, ...params);
|
|
41
|
-
}
|
|
42
|
-
function join(options) {
|
|
43
|
-
return createJoin(IMPLICIT.STORE, options);
|
|
44
|
-
}
|
|
45
|
-
function getInternalRelations(token, split) {
|
|
46
|
-
return getInternalRelationsFromStore(IMPLICIT.STORE, token, split);
|
|
47
|
-
}
|
|
48
|
-
var PRETTY_ENTITY_NAMES = {
|
|
49
|
-
atom_family: `atom family`,
|
|
50
|
-
atom: `atom`,
|
|
51
|
-
continuity: `continuity`,
|
|
52
|
-
key: `key`,
|
|
53
|
-
mutable_atom_family: `atom family [m]`,
|
|
54
|
-
mutable_atom: `atom [m]`,
|
|
55
|
-
readonly_held_selector_family: `selector family [h]`,
|
|
56
|
-
readonly_held_selector: `selector [h]`,
|
|
57
|
-
readonly_pure_selector_family: `selector family`,
|
|
58
|
-
readonly_pure_selector: `selector`,
|
|
59
|
-
socket: `socket`,
|
|
60
|
-
state: `state`,
|
|
61
|
-
timeline: `timeline`,
|
|
62
|
-
transaction: `transaction`,
|
|
63
|
-
unknown: `unknown`,
|
|
64
|
-
user: `\uD83D\uDC64`,
|
|
65
|
-
writable_held_selector_family: `selector family [wh]`,
|
|
66
|
-
writable_held_selector: `selector [wh]`,
|
|
67
|
-
writable_pure_selector_family: `selector family [w]`,
|
|
68
|
-
writable_pure_selector: `selector [w]`
|
|
69
|
-
};
|
|
70
|
-
var simpleLog = (logLevel, prefix) => (icon, denomination, tokenKey, message, ...rest) => {
|
|
71
|
-
console[logLevel](`${prefix ? `${prefix} ` : ``}${icon} ${PRETTY_ENTITY_NAMES[denomination]} \`${tokenKey}\` ${message}`, ...rest);
|
|
72
|
-
};
|
|
73
|
-
var simpleLogger = {
|
|
74
|
-
error: simpleLog(`error`),
|
|
75
|
-
info: simpleLog(`info`),
|
|
76
|
-
warn: simpleLog(`warn`)
|
|
77
|
-
};
|
|
78
|
-
var AtomIOLogger = class {
|
|
79
|
-
logLevel;
|
|
80
|
-
filter;
|
|
81
|
-
logger;
|
|
82
|
-
constructor(logLevel, filter, logger = simpleLogger) {
|
|
83
|
-
this.logLevel = logLevel;
|
|
84
|
-
this.filter = filter;
|
|
85
|
-
this.logger = logger;
|
|
86
|
-
}
|
|
87
|
-
error = (...args) => {
|
|
88
|
-
if (this.logLevel !== null) {
|
|
89
|
-
const filterResult = this.filter?.(...args) ?? true;
|
|
90
|
-
if (filterResult === true)
|
|
91
|
-
this.logger.error(...args);
|
|
92
|
-
else if (filterResult)
|
|
93
|
-
this.logger.error(...filterResult);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
info = (...args) => {
|
|
97
|
-
if (this.logLevel === `info`) {
|
|
98
|
-
const filterResult = this.filter?.(...args) ?? true;
|
|
99
|
-
if (filterResult === true)
|
|
100
|
-
this.logger.info(...args);
|
|
101
|
-
else if (filterResult)
|
|
102
|
-
this.logger.info(...filterResult);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
warn = (...args) => {
|
|
106
|
-
if (this.logLevel !== `error` && this.logLevel !== null) {
|
|
107
|
-
const filterResult = this.filter?.(...args) ?? true;
|
|
108
|
-
if (filterResult === true)
|
|
109
|
-
this.logger.warn(...args);
|
|
110
|
-
else if (filterResult)
|
|
111
|
-
this.logger.warn(...filterResult);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
var $validatedKey = Symbol.for(`claim`);
|
|
116
|
-
function simpleCompound(a, b) {
|
|
117
|
-
return [a, b].sort().join(`\x1F`);
|
|
118
|
-
}
|
|
119
|
-
function selectorFamily(options) {
|
|
120
|
-
return createSelectorFamily(IMPLICIT.STORE, options);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ../../packages/atom.io/dist/json/index.js
|
|
124
|
-
var BOOL = `\x01`;
|
|
125
|
-
var NULL = `\x02`;
|
|
126
|
-
var STRING = `\x03`;
|
|
127
|
-
var NUMBER = `\x04`;
|
|
128
|
-
var packCanonical = (value) => {
|
|
129
|
-
if (value === null)
|
|
130
|
-
return NULL;
|
|
131
|
-
switch (typeof value) {
|
|
132
|
-
case `string`:
|
|
133
|
-
return STRING + value;
|
|
134
|
-
case `number`:
|
|
135
|
-
return NUMBER + value;
|
|
136
|
-
case `boolean`:
|
|
137
|
-
return BOOL + +value;
|
|
138
|
-
case `object`:
|
|
139
|
-
return JSON.stringify(value);
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
var unpackCanonical = (value) => {
|
|
143
|
-
switch (value[0]) {
|
|
144
|
-
case STRING:
|
|
145
|
-
return value.slice(1);
|
|
146
|
-
case NUMBER:
|
|
147
|
-
return +value.slice(1);
|
|
148
|
-
case BOOL:
|
|
149
|
-
return value.slice(1) === `1`;
|
|
150
|
-
case NULL:
|
|
151
|
-
return null;
|
|
152
|
-
case `[`:
|
|
153
|
-
return JSON.parse(value);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
function enumeration(values) {
|
|
157
|
-
const result = {};
|
|
158
|
-
let i = 0;
|
|
159
|
-
for (const value of values) {
|
|
160
|
-
result[value] = i;
|
|
161
|
-
result[i] = value;
|
|
162
|
-
++i;
|
|
163
|
-
}
|
|
164
|
-
return result;
|
|
165
|
-
}
|
|
166
|
-
function parseJson(str) {
|
|
167
|
-
return JSON.parse(str);
|
|
168
|
-
}
|
|
169
|
-
var stringifyJson = (json) => JSON.stringify(json);
|
|
170
|
-
var JSON_PROTOTYPES = [
|
|
171
|
-
Array.prototype,
|
|
172
|
-
Boolean.prototype,
|
|
173
|
-
Number.prototype,
|
|
174
|
-
Object.prototype,
|
|
175
|
-
String.prototype
|
|
176
|
-
];
|
|
177
|
-
|
|
178
|
-
// ../../packages/atom.io/dist/transceivers/u-list/index.js
|
|
179
|
-
var SET_UPDATE_ENUM = enumeration([
|
|
180
|
-
`add`,
|
|
181
|
-
`delete`,
|
|
182
|
-
`clear`
|
|
183
|
-
]);
|
|
184
|
-
var UList = class UList2 extends Set {
|
|
185
|
-
mode = `record`;
|
|
186
|
-
subject = new Subject;
|
|
187
|
-
constructor(values) {
|
|
188
|
-
super(values);
|
|
189
|
-
if (values instanceof UList2) {}
|
|
190
|
-
}
|
|
191
|
-
READONLY_VIEW = this;
|
|
192
|
-
toJSON() {
|
|
193
|
-
return [...this];
|
|
194
|
-
}
|
|
195
|
-
static fromJSON(json) {
|
|
196
|
-
return new UList2(json);
|
|
197
|
-
}
|
|
198
|
-
add(value) {
|
|
199
|
-
const result = super.add(value);
|
|
200
|
-
if (this.mode === `record`)
|
|
201
|
-
this.emit({
|
|
202
|
-
type: `add`,
|
|
203
|
-
value
|
|
204
|
-
});
|
|
205
|
-
return result;
|
|
206
|
-
}
|
|
207
|
-
clear() {
|
|
208
|
-
const capturedContents = this.mode === `record` ? [...this] : null;
|
|
209
|
-
super.clear();
|
|
210
|
-
if (capturedContents)
|
|
211
|
-
this.emit({
|
|
212
|
-
type: `clear`,
|
|
213
|
-
values: capturedContents
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
delete(value) {
|
|
217
|
-
const result = super.delete(value);
|
|
218
|
-
if (this.mode === `record`)
|
|
219
|
-
this.emit({
|
|
220
|
-
type: `delete`,
|
|
221
|
-
value
|
|
222
|
-
});
|
|
223
|
-
return result;
|
|
224
|
-
}
|
|
225
|
-
subscribe(key, fn) {
|
|
226
|
-
return this.subject.subscribe(key, fn);
|
|
227
|
-
}
|
|
228
|
-
emit(update) {
|
|
229
|
-
this.subject.next(UList2.packUpdate(update));
|
|
230
|
-
}
|
|
231
|
-
do(packed) {
|
|
232
|
-
this.mode = `playback`;
|
|
233
|
-
const update = UList2.unpackUpdate(packed);
|
|
234
|
-
switch (update.type) {
|
|
235
|
-
case `add`:
|
|
236
|
-
this.add(update.value);
|
|
237
|
-
break;
|
|
238
|
-
case `delete`:
|
|
239
|
-
this.delete(update.value);
|
|
240
|
-
break;
|
|
241
|
-
case `clear`:
|
|
242
|
-
this.clear();
|
|
243
|
-
}
|
|
244
|
-
this.mode = `record`;
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
undo(packed) {
|
|
248
|
-
const update = UList2.unpackUpdate(packed);
|
|
249
|
-
this.mode = `playback`;
|
|
250
|
-
switch (update.type) {
|
|
251
|
-
case `add`:
|
|
252
|
-
this.delete(update.value);
|
|
253
|
-
break;
|
|
254
|
-
case `delete`:
|
|
255
|
-
this.add(update.value);
|
|
256
|
-
break;
|
|
257
|
-
case `clear`: {
|
|
258
|
-
const values = update.values;
|
|
259
|
-
for (const v of values)
|
|
260
|
-
this.add(v);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
this.mode = `record`;
|
|
264
|
-
return null;
|
|
265
|
-
}
|
|
266
|
-
static packUpdate(update) {
|
|
267
|
-
const head = SET_UPDATE_ENUM[update.type] + `\x1F`;
|
|
268
|
-
if (update.type === `clear`)
|
|
269
|
-
return head + update.values.map(packCanonical).join(`\x1E`);
|
|
270
|
-
return head + packCanonical(update.value);
|
|
271
|
-
}
|
|
272
|
-
static unpackUpdate(packed) {
|
|
273
|
-
const [type, tail] = packed.split(`\x1F`);
|
|
274
|
-
const head = SET_UPDATE_ENUM[type];
|
|
275
|
-
if (head === `clear`)
|
|
276
|
-
return {
|
|
277
|
-
type: `clear`,
|
|
278
|
-
values: tail.split(`\x1E`).map(unpackCanonical)
|
|
279
|
-
};
|
|
280
|
-
return {
|
|
281
|
-
type: head,
|
|
282
|
-
value: unpackCanonical(tail)
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
// ../../packages/atom.io/dist/internal/index.js
|
|
288
|
-
function newest(scion) {
|
|
289
|
-
while (scion.child !== null)
|
|
290
|
-
scion = scion.child;
|
|
291
|
-
return scion;
|
|
292
|
-
}
|
|
293
|
-
function eldest(scion) {
|
|
294
|
-
while (scion.parent !== null)
|
|
295
|
-
scion = scion.parent;
|
|
296
|
-
return scion;
|
|
297
|
-
}
|
|
298
|
-
var NON_CTOR_FN_REGEX = /^\[object (?:Async|Generator|AsyncGenerator)?Function\]$/;
|
|
299
|
-
function isFn(input) {
|
|
300
|
-
const protoString = Object.prototype.toString.call(input);
|
|
301
|
-
return NON_CTOR_FN_REGEX.test(protoString);
|
|
302
|
-
}
|
|
303
|
-
function become(nextVersionOfThing, originalThing) {
|
|
304
|
-
if (isFn(nextVersionOfThing))
|
|
305
|
-
return nextVersionOfThing(originalThing);
|
|
306
|
-
return nextVersionOfThing;
|
|
307
|
-
}
|
|
308
|
-
var Future = class extends Promise {
|
|
309
|
-
fate;
|
|
310
|
-
resolve;
|
|
311
|
-
reject;
|
|
312
|
-
done = false;
|
|
313
|
-
constructor(executor) {
|
|
314
|
-
let superResolve;
|
|
315
|
-
let superReject;
|
|
316
|
-
super((resolve, reject) => {
|
|
317
|
-
superResolve = resolve;
|
|
318
|
-
superReject = reject;
|
|
319
|
-
});
|
|
320
|
-
this.resolve = superResolve;
|
|
321
|
-
this.reject = superReject;
|
|
322
|
-
this.use(executor instanceof Promise ? executor : new Promise(executor));
|
|
323
|
-
}
|
|
324
|
-
pass(promise, value) {
|
|
325
|
-
if (promise === this.fate) {
|
|
326
|
-
this.resolve(value);
|
|
327
|
-
this.done = true;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
fail(promise, reason) {
|
|
331
|
-
if (promise === this.fate) {
|
|
332
|
-
this.reject(reason);
|
|
333
|
-
this.done = true;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
use(value) {
|
|
337
|
-
if (this === value)
|
|
338
|
-
return;
|
|
339
|
-
if (value instanceof Promise) {
|
|
340
|
-
const promise = value;
|
|
341
|
-
this.fate = promise;
|
|
342
|
-
promise.then((resolved) => {
|
|
343
|
-
this.pass(promise, resolved);
|
|
344
|
-
}, (reason) => {
|
|
345
|
-
this.fail(promise, reason);
|
|
346
|
-
});
|
|
347
|
-
} else {
|
|
348
|
-
this.resolve(value);
|
|
349
|
-
this.fate = undefined;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
var Subject = class {
|
|
354
|
-
Subscriber;
|
|
355
|
-
subscribers = /* @__PURE__ */ new Map;
|
|
356
|
-
subscribe(key, subscriber) {
|
|
357
|
-
this.subscribers.set(key, subscriber);
|
|
358
|
-
const unsubscribe = () => {
|
|
359
|
-
this.unsubscribe(key);
|
|
360
|
-
};
|
|
361
|
-
return unsubscribe;
|
|
362
|
-
}
|
|
363
|
-
unsubscribe(key) {
|
|
364
|
-
this.subscribers.delete(key);
|
|
365
|
-
}
|
|
366
|
-
next(value) {
|
|
367
|
-
const subscribers = this.subscribers.values();
|
|
368
|
-
for (const subscriber of subscribers)
|
|
369
|
-
subscriber(value);
|
|
370
|
-
}
|
|
371
|
-
};
|
|
372
|
-
var StatefulSubject = class extends Subject {
|
|
373
|
-
state;
|
|
374
|
-
constructor(initialState) {
|
|
375
|
-
super();
|
|
376
|
-
this.state = initialState;
|
|
377
|
-
}
|
|
378
|
-
next(value) {
|
|
379
|
-
this.state = value;
|
|
380
|
-
super.next(value);
|
|
381
|
-
}
|
|
382
|
-
};
|
|
383
|
-
var CircularBuffer = class CircularBuffer2 {
|
|
384
|
-
_buffer;
|
|
385
|
-
_index = 0;
|
|
386
|
-
constructor(lengthOrArray) {
|
|
387
|
-
let length;
|
|
388
|
-
if (typeof lengthOrArray === `number`)
|
|
389
|
-
length = lengthOrArray;
|
|
390
|
-
else
|
|
391
|
-
length = lengthOrArray.length;
|
|
392
|
-
this._buffer = Array.from({ length });
|
|
393
|
-
}
|
|
394
|
-
get buffer() {
|
|
395
|
-
return this._buffer;
|
|
396
|
-
}
|
|
397
|
-
get index() {
|
|
398
|
-
return this._index;
|
|
399
|
-
}
|
|
400
|
-
add(item) {
|
|
401
|
-
this._buffer[this._index] = item;
|
|
402
|
-
this._index = (this._index + 1) % this._buffer.length;
|
|
403
|
-
}
|
|
404
|
-
copy() {
|
|
405
|
-
const copy = new CircularBuffer2([...this._buffer]);
|
|
406
|
-
copy._index = this._index;
|
|
407
|
-
return copy;
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
function deposit(state) {
|
|
411
|
-
const token = {
|
|
412
|
-
key: state.key,
|
|
413
|
-
type: state.type
|
|
414
|
-
};
|
|
415
|
-
if (`family` in state)
|
|
416
|
-
token.family = state.family;
|
|
417
|
-
return token;
|
|
418
|
-
}
|
|
419
|
-
var MapOverlay = class extends Map {
|
|
420
|
-
deleted = /* @__PURE__ */ new Set;
|
|
421
|
-
changed = /* @__PURE__ */ new Set;
|
|
422
|
-
source;
|
|
423
|
-
constructor(source) {
|
|
424
|
-
super();
|
|
425
|
-
this.source = source;
|
|
426
|
-
}
|
|
427
|
-
get(key) {
|
|
428
|
-
if (super.has(key))
|
|
429
|
-
return super.get(key);
|
|
430
|
-
if (!this.deleted.has(key) && this.source.has(key))
|
|
431
|
-
return this.source.get(key);
|
|
432
|
-
}
|
|
433
|
-
set(key, value) {
|
|
434
|
-
this.deleted.delete(key);
|
|
435
|
-
if (this.source.has(key))
|
|
436
|
-
this.changed.add(key);
|
|
437
|
-
return super.set(key, value);
|
|
438
|
-
}
|
|
439
|
-
hasOwn(key) {
|
|
440
|
-
return super.has(key);
|
|
441
|
-
}
|
|
442
|
-
has(key) {
|
|
443
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
444
|
-
}
|
|
445
|
-
delete(key) {
|
|
446
|
-
if (this.source.has(key)) {
|
|
447
|
-
this.deleted.add(key);
|
|
448
|
-
this.changed.delete(key);
|
|
449
|
-
}
|
|
450
|
-
return super.delete(key);
|
|
451
|
-
}
|
|
452
|
-
clear() {
|
|
453
|
-
this.deleted = new Set(this.source.keys());
|
|
454
|
-
this.changed.clear();
|
|
455
|
-
super.clear();
|
|
456
|
-
}
|
|
457
|
-
*[Symbol.iterator]() {
|
|
458
|
-
yield* super[Symbol.iterator]();
|
|
459
|
-
for (const [key, value] of this.source)
|
|
460
|
-
if (!this.deleted.has(key) && !this.changed.has(key))
|
|
461
|
-
yield [key, value];
|
|
462
|
-
}
|
|
463
|
-
*entries() {
|
|
464
|
-
yield* this[Symbol.iterator]();
|
|
465
|
-
}
|
|
466
|
-
*keys() {
|
|
467
|
-
yield* super.keys();
|
|
468
|
-
for (const key of this.source.keys())
|
|
469
|
-
if (!this.deleted.has(key) && !this.changed.has(key))
|
|
470
|
-
yield key;
|
|
471
|
-
}
|
|
472
|
-
*values() {
|
|
473
|
-
for (const [, value] of this[Symbol.iterator]())
|
|
474
|
-
yield value;
|
|
475
|
-
}
|
|
476
|
-
forEach(callbackfn) {
|
|
477
|
-
for (const [key, value] of this[Symbol.iterator]())
|
|
478
|
-
callbackfn(value, key, this);
|
|
479
|
-
}
|
|
480
|
-
get size() {
|
|
481
|
-
return super.size + this.source.size - this.changed.size - this.deleted.size;
|
|
482
|
-
}
|
|
483
|
-
};
|
|
484
|
-
var SetOverlay = class extends Set {
|
|
485
|
-
deleted = /* @__PURE__ */ new Set;
|
|
486
|
-
source;
|
|
487
|
-
constructor(source) {
|
|
488
|
-
super();
|
|
489
|
-
this.source = source;
|
|
490
|
-
}
|
|
491
|
-
add(value) {
|
|
492
|
-
if (this.source.has(value)) {
|
|
493
|
-
this.deleted.delete(value);
|
|
494
|
-
return this;
|
|
495
|
-
}
|
|
496
|
-
return super.add(value);
|
|
497
|
-
}
|
|
498
|
-
hasOwn(member) {
|
|
499
|
-
return super.has(member);
|
|
500
|
-
}
|
|
501
|
-
has(key) {
|
|
502
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
503
|
-
}
|
|
504
|
-
delete(key) {
|
|
505
|
-
if (this.source.has(key)) {
|
|
506
|
-
this.deleted.add(key);
|
|
507
|
-
return true;
|
|
508
|
-
}
|
|
509
|
-
return super.delete(key);
|
|
510
|
-
}
|
|
511
|
-
clear() {
|
|
512
|
-
this.deleted = new Set(this.source);
|
|
513
|
-
super.clear();
|
|
514
|
-
}
|
|
515
|
-
*[Symbol.iterator]() {
|
|
516
|
-
yield* super[Symbol.iterator]();
|
|
517
|
-
for (const value of this.source)
|
|
518
|
-
if (!this.deleted.has(value))
|
|
519
|
-
yield value;
|
|
520
|
-
}
|
|
521
|
-
*iterateOwn() {
|
|
522
|
-
yield* super[Symbol.iterator]();
|
|
523
|
-
}
|
|
524
|
-
get size() {
|
|
525
|
-
return super.size + this.source.size - this.deleted.size;
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
var RelationsOverlay = class extends Map {
|
|
529
|
-
deleted = /* @__PURE__ */ new Set;
|
|
530
|
-
source;
|
|
531
|
-
constructor(source) {
|
|
532
|
-
super();
|
|
533
|
-
this.source = source;
|
|
534
|
-
}
|
|
535
|
-
get(key) {
|
|
536
|
-
if (super.has(key))
|
|
537
|
-
return super.get(key);
|
|
538
|
-
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
539
|
-
const valueOverlay = new SetOverlay(this.source.get(key));
|
|
540
|
-
super.set(key, valueOverlay);
|
|
541
|
-
return valueOverlay;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
set(key, value) {
|
|
545
|
-
this.deleted.delete(key);
|
|
546
|
-
return super.set(key, value);
|
|
547
|
-
}
|
|
548
|
-
has(key) {
|
|
549
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
550
|
-
}
|
|
551
|
-
delete(key) {
|
|
552
|
-
this.deleted.add(key);
|
|
553
|
-
return super.delete(key);
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
var Junction = class Junction2 {
|
|
557
|
-
a;
|
|
558
|
-
b;
|
|
559
|
-
cardinality;
|
|
560
|
-
relations = /* @__PURE__ */ new Map;
|
|
561
|
-
contents = /* @__PURE__ */ new Map;
|
|
562
|
-
isAType;
|
|
563
|
-
isBType;
|
|
564
|
-
isContent;
|
|
565
|
-
makeContentKey = (a, b) => `${a}:${b}`;
|
|
566
|
-
warn;
|
|
567
|
-
getRelatedKeys(key) {
|
|
568
|
-
return this.relations.get(key);
|
|
569
|
-
}
|
|
570
|
-
addRelation(a, b) {
|
|
571
|
-
let aRelations = this.relations.get(a);
|
|
572
|
-
let bRelations = this.relations.get(b);
|
|
573
|
-
if (aRelations)
|
|
574
|
-
aRelations.add(b);
|
|
575
|
-
else {
|
|
576
|
-
aRelations = new Set([b]);
|
|
577
|
-
this.relations.set(a, aRelations);
|
|
578
|
-
}
|
|
579
|
-
if (bRelations)
|
|
580
|
-
bRelations.add(a);
|
|
581
|
-
else {
|
|
582
|
-
bRelations = new Set([a]);
|
|
583
|
-
this.relations.set(b, bRelations);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
deleteRelation(a, b) {
|
|
587
|
-
const aRelations = this.relations.get(a);
|
|
588
|
-
if (aRelations) {
|
|
589
|
-
aRelations.delete(b);
|
|
590
|
-
if (aRelations.size === 0)
|
|
591
|
-
this.relations.delete(a);
|
|
592
|
-
const bRelations = this.relations.get(b);
|
|
593
|
-
if (bRelations) {
|
|
594
|
-
bRelations.delete(a);
|
|
595
|
-
if (bRelations.size === 0)
|
|
596
|
-
this.relations.delete(b);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
replaceRelationsUnsafely(x, ys) {
|
|
601
|
-
this.relations.set(x, new Set(ys));
|
|
602
|
-
for (const y of ys) {
|
|
603
|
-
const yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
604
|
-
this.relations.set(y, yRelations);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
replaceRelationsSafely(x, ys) {
|
|
608
|
-
const xRelationsPrev = this.relations.get(x);
|
|
609
|
-
let a = this.isAType?.(x) ? x : undefined;
|
|
610
|
-
let b = a === undefined ? x : undefined;
|
|
611
|
-
if (xRelationsPrev)
|
|
612
|
-
for (const y of xRelationsPrev) {
|
|
613
|
-
a ??= y;
|
|
614
|
-
b ??= y;
|
|
615
|
-
const yRelations = this.relations.get(y);
|
|
616
|
-
if (yRelations) {
|
|
617
|
-
if (yRelations.size === 1)
|
|
618
|
-
this.relations.delete(y);
|
|
619
|
-
else
|
|
620
|
-
yRelations.delete(x);
|
|
621
|
-
this.contents.delete(this.makeContentKey(a, b));
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
this.relations.set(x, new Set(ys));
|
|
625
|
-
for (const y of ys) {
|
|
626
|
-
let yRelations = this.relations.get(y);
|
|
627
|
-
if (yRelations)
|
|
628
|
-
yRelations.add(x);
|
|
629
|
-
else {
|
|
630
|
-
yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
631
|
-
this.relations.set(y, yRelations);
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
getContentInternal(contentKey) {
|
|
636
|
-
return this.contents.get(contentKey);
|
|
637
|
-
}
|
|
638
|
-
setContent(contentKey, content) {
|
|
639
|
-
this.contents.set(contentKey, content);
|
|
640
|
-
}
|
|
641
|
-
deleteContent(contentKey) {
|
|
642
|
-
this.contents.delete(contentKey);
|
|
643
|
-
}
|
|
644
|
-
constructor(data, config) {
|
|
645
|
-
this.a = data.between[0];
|
|
646
|
-
this.b = data.between[1];
|
|
647
|
-
this.cardinality = data.cardinality;
|
|
648
|
-
this.isAType = config?.isAType ?? null;
|
|
649
|
-
this.isBType = config?.isBType ?? null;
|
|
650
|
-
this.isContent = config?.isContent ?? null;
|
|
651
|
-
if (config?.makeContentKey)
|
|
652
|
-
this.makeContentKey = config.makeContentKey;
|
|
653
|
-
if (!config?.externalStore) {
|
|
654
|
-
const source = config?.source;
|
|
655
|
-
if (source === undefined) {
|
|
656
|
-
this.relations = new Map(data.relations?.map(([x, ys]) => [x, new Set(ys)]));
|
|
657
|
-
this.contents = new Map(data.contents);
|
|
658
|
-
}
|
|
659
|
-
if (source) {
|
|
660
|
-
this.relations = new RelationsOverlay(source.relations);
|
|
661
|
-
this.contents = new MapOverlay(source.contents);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
if (config?.externalStore) {
|
|
665
|
-
const externalStore = config.externalStore;
|
|
666
|
-
this.has = (a, b) => externalStore.has(a, b);
|
|
667
|
-
this.addRelation = (a, b) => {
|
|
668
|
-
externalStore.addRelation(a, b);
|
|
669
|
-
};
|
|
670
|
-
this.deleteRelation = (a, b) => {
|
|
671
|
-
externalStore.deleteRelation(a, b);
|
|
672
|
-
};
|
|
673
|
-
this.replaceRelationsSafely = (a, bs) => {
|
|
674
|
-
externalStore.replaceRelationsSafely(a, bs);
|
|
675
|
-
};
|
|
676
|
-
this.replaceRelationsUnsafely = (a, bs) => {
|
|
677
|
-
externalStore.replaceRelationsUnsafely(a, bs);
|
|
678
|
-
};
|
|
679
|
-
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
|
|
680
|
-
if (externalStore.getContent) {
|
|
681
|
-
this.getContentInternal = (contentKey) => {
|
|
682
|
-
return externalStore.getContent(contentKey);
|
|
683
|
-
};
|
|
684
|
-
this.setContent = (contentKey, content) => {
|
|
685
|
-
externalStore.setContent(contentKey, content);
|
|
686
|
-
};
|
|
687
|
-
this.deleteContent = (contentKey) => {
|
|
688
|
-
externalStore.deleteContent(contentKey);
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
for (const [x, ys] of data.relations ?? []) {
|
|
692
|
-
let a = this.isAType?.(x) ? x : undefined;
|
|
693
|
-
let b = a === undefined ? x : undefined;
|
|
694
|
-
for (const y of ys) {
|
|
695
|
-
a ??= y;
|
|
696
|
-
b ??= y;
|
|
697
|
-
this.addRelation(a, b);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
for (const [contentKey, content] of data.contents ?? [])
|
|
701
|
-
this.setContent(contentKey, content);
|
|
702
|
-
}
|
|
703
|
-
if (config?.warn)
|
|
704
|
-
this.warn = config.warn;
|
|
705
|
-
}
|
|
706
|
-
toJSON() {
|
|
707
|
-
return {
|
|
708
|
-
between: [this.a, this.b],
|
|
709
|
-
cardinality: this.cardinality,
|
|
710
|
-
relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
|
|
711
|
-
contents: [...this.contents.entries()]
|
|
712
|
-
};
|
|
713
|
-
}
|
|
714
|
-
set(...params) {
|
|
715
|
-
let a;
|
|
716
|
-
let b;
|
|
717
|
-
let content;
|
|
718
|
-
switch (params.length) {
|
|
719
|
-
case 1: {
|
|
720
|
-
const relation = params[0];
|
|
721
|
-
a = relation[this.a];
|
|
722
|
-
b = relation[this.b];
|
|
723
|
-
content = undefined;
|
|
724
|
-
break;
|
|
725
|
-
}
|
|
726
|
-
case 2: {
|
|
727
|
-
const zeroth = params[0];
|
|
728
|
-
if (typeof zeroth === `string`)
|
|
729
|
-
[a, b] = params;
|
|
730
|
-
else {
|
|
731
|
-
a = zeroth[this.a];
|
|
732
|
-
b = zeroth[this.b];
|
|
733
|
-
content = params[1];
|
|
734
|
-
}
|
|
735
|
-
break;
|
|
736
|
-
}
|
|
737
|
-
default:
|
|
738
|
-
a = params[0];
|
|
739
|
-
b = params[1];
|
|
740
|
-
content = params[2];
|
|
741
|
-
break;
|
|
742
|
-
}
|
|
743
|
-
switch (this.cardinality) {
|
|
744
|
-
case `1:1`: {
|
|
745
|
-
const bPrev = this.getRelatedKey(a);
|
|
746
|
-
if (bPrev && bPrev !== b)
|
|
747
|
-
this.delete(a, bPrev);
|
|
748
|
-
}
|
|
749
|
-
case `1:n`:
|
|
750
|
-
{
|
|
751
|
-
const aPrev = this.getRelatedKey(b);
|
|
752
|
-
if (aPrev && aPrev !== a)
|
|
753
|
-
this.delete(aPrev, b);
|
|
754
|
-
}
|
|
755
|
-
break;
|
|
756
|
-
case `n:n`:
|
|
757
|
-
}
|
|
758
|
-
if (content) {
|
|
759
|
-
const contentKey = this.makeContentKey(a, b);
|
|
760
|
-
this.setContent(contentKey, content);
|
|
761
|
-
}
|
|
762
|
-
this.addRelation(a, b);
|
|
763
|
-
return this;
|
|
764
|
-
}
|
|
765
|
-
delete(x, b) {
|
|
766
|
-
b = typeof b === `string` ? b : x[this.b];
|
|
767
|
-
const a = typeof x === `string` ? x : x[this.a];
|
|
768
|
-
if (a === undefined && typeof b === `string`) {
|
|
769
|
-
const bRelations = this.getRelatedKeys(b);
|
|
770
|
-
if (bRelations)
|
|
771
|
-
for (const bRelation of bRelations)
|
|
772
|
-
this.delete(bRelation, b);
|
|
773
|
-
} else if (typeof a === `string` && b === undefined) {
|
|
774
|
-
const aRelations = this.getRelatedKeys(a);
|
|
775
|
-
if (aRelations)
|
|
776
|
-
for (const aRelation of aRelations)
|
|
777
|
-
this.delete(a, aRelation);
|
|
778
|
-
} else if (typeof a === `string` && typeof b === `string`) {
|
|
779
|
-
this.deleteRelation(a, b);
|
|
780
|
-
const contentKey = this.makeContentKey(a, b);
|
|
781
|
-
this.deleteContent(contentKey);
|
|
782
|
-
}
|
|
783
|
-
return this;
|
|
784
|
-
}
|
|
785
|
-
getRelatedKey(key) {
|
|
786
|
-
const relations = this.getRelatedKeys(key);
|
|
787
|
-
if (relations) {
|
|
788
|
-
if (relations.size > 1)
|
|
789
|
-
this.warn?.(`${relations.size} related keys were found for key "${key}": (${[...relations].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`);
|
|
790
|
-
let singleRelation;
|
|
791
|
-
for (const relation of relations) {
|
|
792
|
-
singleRelation = relation;
|
|
793
|
-
break;
|
|
794
|
-
}
|
|
795
|
-
return singleRelation;
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
replaceRelations(x, relations, config) {
|
|
799
|
-
const hasContent = !Array.isArray(relations);
|
|
800
|
-
const ys = hasContent ? Object.keys(relations) : relations;
|
|
801
|
-
if (config?.reckless)
|
|
802
|
-
this.replaceRelationsUnsafely(x, ys);
|
|
803
|
-
else
|
|
804
|
-
this.replaceRelationsSafely(x, ys);
|
|
805
|
-
if (hasContent)
|
|
806
|
-
for (const y of ys) {
|
|
807
|
-
const contentKey = this.makeContentKey(x, y);
|
|
808
|
-
const content = relations[y];
|
|
809
|
-
this.setContent(contentKey, content);
|
|
810
|
-
}
|
|
811
|
-
return this;
|
|
812
|
-
}
|
|
813
|
-
getContent(a, b) {
|
|
814
|
-
const contentKey = this.makeContentKey(a, b);
|
|
815
|
-
return this.getContentInternal(contentKey);
|
|
816
|
-
}
|
|
817
|
-
getRelationEntries(input) {
|
|
818
|
-
const a = input[this.a];
|
|
819
|
-
const b = input[this.b];
|
|
820
|
-
if (a !== undefined && b === undefined) {
|
|
821
|
-
const aRelations = this.getRelatedKeys(a);
|
|
822
|
-
if (aRelations)
|
|
823
|
-
return [...aRelations].map((aRelation) => {
|
|
824
|
-
return [aRelation, this.getContent(a, aRelation)];
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
if (a === undefined && b !== undefined) {
|
|
828
|
-
const bRelations = this.getRelatedKeys(b);
|
|
829
|
-
if (bRelations)
|
|
830
|
-
return [...bRelations].map((bRelation) => {
|
|
831
|
-
return [bRelation, this.getContent(bRelation, b)];
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
|
-
return [];
|
|
835
|
-
}
|
|
836
|
-
has(a, b) {
|
|
837
|
-
if (b)
|
|
838
|
-
return this.getRelatedKeys(a)?.has(b) ?? false;
|
|
839
|
-
return this.relations.has(a);
|
|
840
|
-
}
|
|
841
|
-
overlay() {
|
|
842
|
-
const config = {
|
|
843
|
-
source: this,
|
|
844
|
-
makeContentKey: this.makeContentKey
|
|
845
|
-
};
|
|
846
|
-
if (this.isAType)
|
|
847
|
-
config.isAType = this.isAType;
|
|
848
|
-
if (this.isBType)
|
|
849
|
-
config.isBType = this.isBType;
|
|
850
|
-
if (this.isContent)
|
|
851
|
-
config.isContent = this.isContent;
|
|
852
|
-
if (this.warn)
|
|
853
|
-
config.warn = this.warn;
|
|
854
|
-
return new Junction2({
|
|
855
|
-
between: [this.a, this.b],
|
|
856
|
-
cardinality: this.cardinality
|
|
857
|
-
}, config);
|
|
858
|
-
}
|
|
859
|
-
incorporate(overlay) {
|
|
860
|
-
const { relations, contents } = overlay;
|
|
861
|
-
for (const [key, value] of relations)
|
|
862
|
-
if (value instanceof SetOverlay) {
|
|
863
|
-
const { source } = value;
|
|
864
|
-
for (const keyAdded of value.iterateOwn())
|
|
865
|
-
source.add(keyAdded);
|
|
866
|
-
} else
|
|
867
|
-
this.relations.set(key, value);
|
|
868
|
-
for (const key of relations.deleted)
|
|
869
|
-
this.relations.delete(key);
|
|
870
|
-
for (const [key, value] of contents)
|
|
871
|
-
this.contents.set(key, value);
|
|
872
|
-
for (const key of contents.deleted)
|
|
873
|
-
this.contents.delete(key);
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
function isReservedIntrospectionKey(value) {
|
|
877
|
-
return value.startsWith(`\uD83D\uDD0D `);
|
|
878
|
-
}
|
|
879
|
-
function isRootStore(store) {
|
|
880
|
-
return `epoch` in store.transactionMeta;
|
|
881
|
-
}
|
|
882
|
-
function isChildStore(store) {
|
|
883
|
-
return `phase` in store.transactionMeta;
|
|
884
|
-
}
|
|
885
|
-
var Store = class {
|
|
886
|
-
parent = null;
|
|
887
|
-
child = null;
|
|
888
|
-
valueMap = /* @__PURE__ */ new Map;
|
|
889
|
-
defaults = /* @__PURE__ */ new Map;
|
|
890
|
-
atoms = /* @__PURE__ */ new Map;
|
|
891
|
-
writableSelectors = /* @__PURE__ */ new Map;
|
|
892
|
-
readonlySelectors = /* @__PURE__ */ new Map;
|
|
893
|
-
atomsThatAreDefault = /* @__PURE__ */ new Set;
|
|
894
|
-
selectorAtoms = new Junction({
|
|
895
|
-
between: [`selectorKey`, `atomKey`],
|
|
896
|
-
cardinality: `n:n`
|
|
897
|
-
});
|
|
898
|
-
selectorGraph = new Junction({
|
|
899
|
-
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
900
|
-
cardinality: `n:n`
|
|
901
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
902
|
-
trackers = /* @__PURE__ */ new Map;
|
|
903
|
-
families = /* @__PURE__ */ new Map;
|
|
904
|
-
joins = /* @__PURE__ */ new Map;
|
|
905
|
-
transactions = /* @__PURE__ */ new Map;
|
|
906
|
-
transactionMeta = {
|
|
907
|
-
epoch: /* @__PURE__ */ new Map,
|
|
908
|
-
actionContinuities: new Junction({
|
|
909
|
-
between: [`continuity`, `action`],
|
|
910
|
-
cardinality: `1:n`
|
|
911
|
-
})
|
|
912
|
-
};
|
|
913
|
-
timelines = /* @__PURE__ */ new Map;
|
|
914
|
-
timelineTopics = new Junction({
|
|
915
|
-
between: [`timelineKey`, `topicKey`],
|
|
916
|
-
cardinality: `1:n`
|
|
917
|
-
});
|
|
918
|
-
disposalTraces = new CircularBuffer(100);
|
|
919
|
-
molecules = /* @__PURE__ */ new Map;
|
|
920
|
-
moleculeGraph = new Junction({
|
|
921
|
-
between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
|
|
922
|
-
cardinality: `n:n`
|
|
923
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
924
|
-
moleculeData = new Junction({
|
|
925
|
-
between: [`moleculeKey`, `stateFamilyKey`],
|
|
926
|
-
cardinality: `n:n`
|
|
927
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
928
|
-
keyRefsInJoins = new Junction({
|
|
929
|
-
between: [`moleculeKey`, `joinKey`],
|
|
930
|
-
cardinality: `n:n`
|
|
931
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
932
|
-
miscResources = /* @__PURE__ */ new Map;
|
|
933
|
-
on = {
|
|
934
|
-
atomCreation: new Subject,
|
|
935
|
-
atomDisposal: new Subject,
|
|
936
|
-
selectorCreation: new Subject,
|
|
937
|
-
selectorDisposal: new Subject,
|
|
938
|
-
timelineCreation: new Subject,
|
|
939
|
-
transactionCreation: new Subject,
|
|
940
|
-
transactionApplying: new StatefulSubject(null),
|
|
941
|
-
operationClose: new Subject,
|
|
942
|
-
moleculeCreation: new Subject,
|
|
943
|
-
moleculeDisposal: new Subject
|
|
944
|
-
};
|
|
945
|
-
operation = { open: false };
|
|
946
|
-
config = {
|
|
947
|
-
name: `IMPLICIT_STORE`,
|
|
948
|
-
lifespan: `ephemeral`,
|
|
949
|
-
isProduction: globalThis.process?.env?.[`NODE_ENV`] === `production`
|
|
950
|
-
};
|
|
951
|
-
loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
|
|
952
|
-
logger = {
|
|
953
|
-
error: (...messages) => {
|
|
954
|
-
for (const logger of this.loggers)
|
|
955
|
-
logger.error(...messages);
|
|
956
|
-
},
|
|
957
|
-
info: (...messages) => {
|
|
958
|
-
for (const logger of this.loggers)
|
|
959
|
-
logger.info(...messages);
|
|
960
|
-
},
|
|
961
|
-
warn: (...messages) => {
|
|
962
|
-
for (const logger of this.loggers)
|
|
963
|
-
logger.warn(...messages);
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
constructor(config, store = null) {
|
|
967
|
-
this.config = {
|
|
968
|
-
...store?.config,
|
|
969
|
-
...config
|
|
970
|
-
};
|
|
971
|
-
if (store !== null) {
|
|
972
|
-
this.operation = { ...store?.operation };
|
|
973
|
-
if (isRootStore(store))
|
|
974
|
-
this.transactionMeta = {
|
|
975
|
-
epoch: new Map(store?.transactionMeta.epoch),
|
|
976
|
-
actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
|
|
977
|
-
};
|
|
978
|
-
for (const [, family] of store.families) {
|
|
979
|
-
if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`))
|
|
980
|
-
continue;
|
|
981
|
-
family.install(this);
|
|
982
|
-
}
|
|
983
|
-
const mutableHelpers = /* @__PURE__ */ new Set;
|
|
984
|
-
for (const [, atom$1] of store.atoms) {
|
|
985
|
-
if (mutableHelpers.has(atom$1.key))
|
|
986
|
-
continue;
|
|
987
|
-
atom$1.install(this);
|
|
988
|
-
if (atom$1.type === `mutable_atom`) {
|
|
989
|
-
const originalJsonToken = getJsonToken(store, atom$1);
|
|
990
|
-
const originalUpdateToken = getUpdateToken(atom$1);
|
|
991
|
-
mutableHelpers.add(originalJsonToken.key);
|
|
992
|
-
mutableHelpers.add(originalUpdateToken.key);
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
for (const [, selector$1] of store.readonlySelectors)
|
|
996
|
-
selector$1.install(this);
|
|
997
|
-
for (const [, selector$1] of store.writableSelectors) {
|
|
998
|
-
if (mutableHelpers.has(selector$1.key))
|
|
999
|
-
continue;
|
|
1000
|
-
selector$1.install(this);
|
|
1001
|
-
}
|
|
1002
|
-
for (const [, tx] of store.transactions)
|
|
1003
|
-
tx.install(this);
|
|
1004
|
-
for (const [, timeline] of store.timelines)
|
|
1005
|
-
timeline.install(this);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
};
|
|
1009
|
-
var IMPLICIT = { get STORE() {
|
|
1010
|
-
globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
|
|
1011
|
-
name: `IMPLICIT_STORE`,
|
|
1012
|
-
lifespan: `ephemeral`,
|
|
1013
|
-
isProduction: globalThis.process?.env?.[`NODE_ENV`] === `production`
|
|
1014
|
-
});
|
|
1015
|
-
return globalThis.ATOM_IO_IMPLICIT_STORE;
|
|
1016
|
-
} };
|
|
1017
|
-
var NotFoundError = class extends Error {
|
|
1018
|
-
constructor(token, store) {
|
|
1019
|
-
super(`${PRETTY_ENTITY_NAMES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
function withdraw(store, token) {
|
|
1023
|
-
let withdrawn;
|
|
1024
|
-
let target = store;
|
|
1025
|
-
while (target !== null) {
|
|
1026
|
-
switch (token.type) {
|
|
1027
|
-
case `atom`:
|
|
1028
|
-
case `mutable_atom`:
|
|
1029
|
-
withdrawn = target.atoms.get(token.key);
|
|
1030
|
-
break;
|
|
1031
|
-
case `writable_pure_selector`:
|
|
1032
|
-
case `writable_held_selector`:
|
|
1033
|
-
withdrawn = target.writableSelectors.get(token.key);
|
|
1034
|
-
break;
|
|
1035
|
-
case `readonly_pure_selector`:
|
|
1036
|
-
case `readonly_held_selector`:
|
|
1037
|
-
withdrawn = target.readonlySelectors.get(token.key);
|
|
1038
|
-
break;
|
|
1039
|
-
case `atom_family`:
|
|
1040
|
-
case `mutable_atom_family`:
|
|
1041
|
-
case `writable_pure_selector_family`:
|
|
1042
|
-
case `readonly_pure_selector_family`:
|
|
1043
|
-
case `writable_held_selector_family`:
|
|
1044
|
-
case `readonly_held_selector_family`:
|
|
1045
|
-
withdrawn = target.families.get(token.key);
|
|
1046
|
-
break;
|
|
1047
|
-
case `timeline`:
|
|
1048
|
-
withdrawn = target.timelines.get(token.key);
|
|
1049
|
-
break;
|
|
1050
|
-
case `transaction`:
|
|
1051
|
-
withdrawn = target.transactions.get(token.key);
|
|
1052
|
-
break;
|
|
1053
|
-
}
|
|
1054
|
-
if (withdrawn)
|
|
1055
|
-
return withdrawn;
|
|
1056
|
-
target = target.child;
|
|
1057
|
-
}
|
|
1058
|
-
throw new NotFoundError(token, store);
|
|
1059
|
-
}
|
|
1060
|
-
function getFallback(store, token, family, subKey) {
|
|
1061
|
-
const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringifyJson(subKey));
|
|
1062
|
-
store.logger.error(`\u274C`, token.type, token.key, `gets a fallback value because key`, subKey, `is not allocated`, disposal ? `This key was previously disposed:
|
|
1063
|
-
${disposal.trace}` : `(no previous disposal trace found)`);
|
|
1064
|
-
switch (family.type) {
|
|
1065
|
-
case `mutable_atom_family`: {
|
|
1066
|
-
if (store.defaults.has(family.key))
|
|
1067
|
-
return store.defaults.get(family.key);
|
|
1068
|
-
const defaultValue = new family.class;
|
|
1069
|
-
store.defaults.set(family.key, defaultValue);
|
|
1070
|
-
return defaultValue.READONLY_VIEW;
|
|
1071
|
-
}
|
|
1072
|
-
case `atom_family`: {
|
|
1073
|
-
if (store.defaults.has(family.key))
|
|
1074
|
-
return store.defaults.get(family.key);
|
|
1075
|
-
const def = family.default;
|
|
1076
|
-
const defaultValue = def(subKey);
|
|
1077
|
-
store.defaults.set(family.key, defaultValue);
|
|
1078
|
-
return defaultValue;
|
|
1079
|
-
}
|
|
1080
|
-
case `readonly_pure_selector_family`:
|
|
1081
|
-
case `writable_pure_selector_family`:
|
|
1082
|
-
case `readonly_held_selector_family`:
|
|
1083
|
-
case `writable_held_selector_family`: {
|
|
1084
|
-
if (store.defaults.has(family.key))
|
|
1085
|
-
return store.defaults.get(family.key);
|
|
1086
|
-
const defaultValue = family.default(subKey);
|
|
1087
|
-
store.defaults.set(family.key, defaultValue);
|
|
1088
|
-
return defaultValue;
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
function safeCompute(target, state) {
|
|
1093
|
-
const { type, key, catch: canCatch } = state;
|
|
1094
|
-
switch (type) {
|
|
1095
|
-
case `readonly_pure_selector`:
|
|
1096
|
-
case `writable_pure_selector`: {
|
|
1097
|
-
let val;
|
|
1098
|
-
target.logger.info(`\uD83E\uDDEE`, type, key, `computing value`);
|
|
1099
|
-
try {
|
|
1100
|
-
val = state.getFrom(target);
|
|
1101
|
-
if (val instanceof Promise)
|
|
1102
|
-
val = val.catch((thrown) => {
|
|
1103
|
-
target.logger.error(`\uD83D\uDCA5`, type, key, `rejected:`, thrown);
|
|
1104
|
-
if (canCatch) {
|
|
1105
|
-
for (const Class of canCatch)
|
|
1106
|
-
if (thrown instanceof Class)
|
|
1107
|
-
return thrown;
|
|
1108
|
-
}
|
|
1109
|
-
throw thrown;
|
|
1110
|
-
});
|
|
1111
|
-
} catch (e) {
|
|
1112
|
-
target.logger.error(`\uD83D\uDCA5`, type, key, `rejected:`, e);
|
|
1113
|
-
if (canCatch) {
|
|
1114
|
-
for (const Class of canCatch)
|
|
1115
|
-
if (e instanceof Class)
|
|
1116
|
-
return writeToCache(target, state, e);
|
|
1117
|
-
}
|
|
1118
|
-
throw e;
|
|
1119
|
-
}
|
|
1120
|
-
return writeToCache(target, state, val);
|
|
1121
|
-
}
|
|
1122
|
-
case `atom`: {
|
|
1123
|
-
let def;
|
|
1124
|
-
if (isFn(state.default))
|
|
1125
|
-
try {
|
|
1126
|
-
def = state.default();
|
|
1127
|
-
if (def instanceof Promise)
|
|
1128
|
-
def = def.catch((thrown) => {
|
|
1129
|
-
target.logger.error(`\uD83D\uDCA5`, type, key, `rejected:`, thrown);
|
|
1130
|
-
if (canCatch) {
|
|
1131
|
-
for (const Class of canCatch)
|
|
1132
|
-
if (thrown instanceof Class)
|
|
1133
|
-
return thrown;
|
|
1134
|
-
}
|
|
1135
|
-
throw thrown;
|
|
1136
|
-
});
|
|
1137
|
-
} catch (e) {
|
|
1138
|
-
target.logger.error(`\uD83D\uDCA5`, type, key, `rejected:`, e);
|
|
1139
|
-
if (canCatch) {
|
|
1140
|
-
for (const Class of canCatch)
|
|
1141
|
-
if (e instanceof Class) {
|
|
1142
|
-
def = writeToCache(target, state, e);
|
|
1143
|
-
target.logger.info(`\u2728`, state.type, key, `computed default`, def);
|
|
1144
|
-
return def;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
throw e;
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
def = state.default;
|
|
1151
|
-
target.logger.info(`\u2728`, state.type, key, `using static default`, def);
|
|
1152
|
-
}
|
|
1153
|
-
return writeToCache(target, state, def);
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
function readOrComputeValue(target, state, mut) {
|
|
1158
|
-
if (target.valueMap.has(state.key))
|
|
1159
|
-
return readFromCache(target, state, mut);
|
|
1160
|
-
target.logger.info(`\u2754`, state.type, state.key, `value not found in cache`);
|
|
1161
|
-
const { key } = state;
|
|
1162
|
-
switch (state.type) {
|
|
1163
|
-
case `readonly_held_selector`:
|
|
1164
|
-
case `writable_held_selector`:
|
|
1165
|
-
target.logger.info(`\uD83E\uDDEE`, state.type, key, `computing value`);
|
|
1166
|
-
return state.getFrom(target);
|
|
1167
|
-
case `writable_pure_selector`:
|
|
1168
|
-
case `readonly_pure_selector`:
|
|
1169
|
-
case `atom`:
|
|
1170
|
-
return safeCompute(target, state);
|
|
1171
|
-
case `mutable_atom`: {
|
|
1172
|
-
const instance = new state.class;
|
|
1173
|
-
target.logger.info(`\u2728`, state.type, key, `created new instance`, instance);
|
|
1174
|
-
return writeToCache(target, state, instance);
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
function getFamilyOfToken(store, token) {
|
|
1179
|
-
return withdraw(store, {
|
|
1180
|
-
key: token.family.key,
|
|
1181
|
-
type: `${token.type}_family`
|
|
1182
|
-
});
|
|
1183
|
-
}
|
|
1184
|
-
var FAMILY_MEMBER_TOKEN_TYPES = {
|
|
1185
|
-
atom_family: `atom`,
|
|
1186
|
-
molecule_family: `molecule`,
|
|
1187
|
-
mutable_atom_family: `mutable_atom`,
|
|
1188
|
-
readonly_held_selector_family: `readonly_held_selector`,
|
|
1189
|
-
readonly_pure_selector_family: `readonly_pure_selector`,
|
|
1190
|
-
writable_held_selector_family: `writable_held_selector`,
|
|
1191
|
-
writable_pure_selector_family: `writable_pure_selector`
|
|
1192
|
-
};
|
|
1193
|
-
var MUST_CREATE = Symbol(`MUST_CREATE`);
|
|
1194
|
-
var DO_NOT_CREATE = Symbol(`DO_NOT_CREATE`);
|
|
1195
|
-
function mintInStore(mustCreate, store, family, key) {
|
|
1196
|
-
const stringKey = stringifyJson(key);
|
|
1197
|
-
const molecule = store.molecules.get(stringKey);
|
|
1198
|
-
if (!molecule && store.config.lifespan === `immortal`) {
|
|
1199
|
-
const { type: familyType, key: familyKey } = family;
|
|
1200
|
-
store.logger.warn(`\uD83D\uDCA3`, `key`, stringKey, `was used to mint a counterfeit token for`, familyType, `"${familyKey}"`);
|
|
1201
|
-
return {
|
|
1202
|
-
counterfeit: true,
|
|
1203
|
-
key: `${familyKey}(${stringKey})`,
|
|
1204
|
-
type: FAMILY_MEMBER_TOKEN_TYPES[familyType],
|
|
1205
|
-
family: {
|
|
1206
|
-
key: familyKey,
|
|
1207
|
-
subKey: stringKey
|
|
1208
|
-
}
|
|
1209
|
-
};
|
|
1210
|
-
}
|
|
1211
|
-
let token;
|
|
1212
|
-
if (mustCreate === MUST_CREATE) {
|
|
1213
|
-
store.logger.info(`\uD83D\uDC6A`, family.type, family.key, `adds member`, typeof key === `string` ? `\`${key}\`` : key);
|
|
1214
|
-
token = family.create(key);
|
|
1215
|
-
if (molecule)
|
|
1216
|
-
store.moleculeData.set(stringKey, family.key);
|
|
1217
|
-
} else {
|
|
1218
|
-
const { type: familyType, key: familyKey } = family;
|
|
1219
|
-
return {
|
|
1220
|
-
key: `${familyKey}(${stringKey})`,
|
|
1221
|
-
type: FAMILY_MEMBER_TOKEN_TYPES[familyType],
|
|
1222
|
-
family: {
|
|
1223
|
-
key: familyKey,
|
|
1224
|
-
subKey: stringKey
|
|
1225
|
-
}
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
return token;
|
|
1229
|
-
}
|
|
1230
|
-
function reduceReference(store, ...params) {
|
|
1231
|
-
let existingToken;
|
|
1232
|
-
let brandNewToken;
|
|
1233
|
-
let family;
|
|
1234
|
-
let subKey;
|
|
1235
|
-
let token;
|
|
1236
|
-
if (params.length === 1) {
|
|
1237
|
-
token = params[0];
|
|
1238
|
-
if (`family` in token) {
|
|
1239
|
-
const familyToken = getFamilyOfToken(store, token);
|
|
1240
|
-
family = withdraw(store, familyToken);
|
|
1241
|
-
subKey = parseJson(token.family.subKey);
|
|
1242
|
-
existingToken = seekInStore(store, familyToken, subKey);
|
|
1243
|
-
if (`counterfeit` in token)
|
|
1244
|
-
return {
|
|
1245
|
-
token,
|
|
1246
|
-
family,
|
|
1247
|
-
subKey,
|
|
1248
|
-
isNew: false
|
|
1249
|
-
};
|
|
1250
|
-
if (!existingToken) {
|
|
1251
|
-
brandNewToken = mintInStore(MUST_CREATE, store, familyToken, subKey);
|
|
1252
|
-
token = brandNewToken;
|
|
1253
|
-
} else
|
|
1254
|
-
token = existingToken;
|
|
1255
|
-
}
|
|
1256
|
-
} else {
|
|
1257
|
-
family = withdraw(store, params[0]);
|
|
1258
|
-
subKey = params[1];
|
|
1259
|
-
existingToken = seekInStore(store, family, subKey);
|
|
1260
|
-
if (!existingToken) {
|
|
1261
|
-
brandNewToken = mintInStore(MUST_CREATE, store, family, subKey);
|
|
1262
|
-
token = brandNewToken;
|
|
1263
|
-
} else
|
|
1264
|
-
token = existingToken;
|
|
1265
|
-
}
|
|
1266
|
-
const isCounterfeit = `counterfeit` in token;
|
|
1267
|
-
if (Boolean(brandNewToken) && isCounterfeit === false && family) {
|
|
1268
|
-
let subType;
|
|
1269
|
-
switch (token.type) {
|
|
1270
|
-
case `readonly_pure_selector`:
|
|
1271
|
-
case `readonly_held_selector`:
|
|
1272
|
-
subType = `readable`;
|
|
1273
|
-
break;
|
|
1274
|
-
case `atom`:
|
|
1275
|
-
case `mutable_atom`:
|
|
1276
|
-
case `writable_pure_selector`:
|
|
1277
|
-
case `writable_held_selector`:
|
|
1278
|
-
subType = `writable`;
|
|
1279
|
-
break;
|
|
1280
|
-
}
|
|
1281
|
-
const stateCreationEvent = {
|
|
1282
|
-
type: `state_creation`,
|
|
1283
|
-
subType,
|
|
1284
|
-
token,
|
|
1285
|
-
timestamp: Date.now()
|
|
1286
|
-
};
|
|
1287
|
-
family.subject.next(stateCreationEvent);
|
|
1288
|
-
const target = newest(store);
|
|
1289
|
-
if (token.family) {
|
|
1290
|
-
if (isRootStore(target))
|
|
1291
|
-
switch (token.type) {
|
|
1292
|
-
case `atom`:
|
|
1293
|
-
case `mutable_atom`:
|
|
1294
|
-
store.on.atomCreation.next(token);
|
|
1295
|
-
break;
|
|
1296
|
-
case `writable_pure_selector`:
|
|
1297
|
-
case `readonly_pure_selector`:
|
|
1298
|
-
case `writable_held_selector`:
|
|
1299
|
-
case `readonly_held_selector`:
|
|
1300
|
-
store.on.selectorCreation.next(token);
|
|
1301
|
-
break;
|
|
1302
|
-
}
|
|
1303
|
-
else if (isChildStore(target) && target.on.transactionApplying.state === null)
|
|
1304
|
-
target.transactionMeta.update.subEvents.push(stateCreationEvent);
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
return {
|
|
1308
|
-
token,
|
|
1309
|
-
family,
|
|
1310
|
-
subKey,
|
|
1311
|
-
isNew: Boolean(brandNewToken)
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
|
-
function getFromStore(store, ...params) {
|
|
1315
|
-
const { token, family, subKey } = reduceReference(store, ...params);
|
|
1316
|
-
if (`counterfeit` in token && family && subKey)
|
|
1317
|
-
return getFallback(store, token, family, subKey);
|
|
1318
|
-
return readOrComputeValue(store, withdraw(store, token));
|
|
1319
|
-
}
|
|
1320
|
-
function seekInStore(store, token, key) {
|
|
1321
|
-
const subKey = stringifyJson(key);
|
|
1322
|
-
const fullKey = `${token.key}(${subKey})`;
|
|
1323
|
-
const target = newest(store);
|
|
1324
|
-
let state;
|
|
1325
|
-
switch (token.type) {
|
|
1326
|
-
case `atom_family`:
|
|
1327
|
-
case `mutable_atom_family`:
|
|
1328
|
-
state = target.atoms.get(fullKey);
|
|
1329
|
-
break;
|
|
1330
|
-
case `writable_held_selector_family`:
|
|
1331
|
-
case `writable_pure_selector_family`:
|
|
1332
|
-
state = target.writableSelectors.get(fullKey);
|
|
1333
|
-
break;
|
|
1334
|
-
case `readonly_held_selector_family`:
|
|
1335
|
-
case `readonly_pure_selector_family`:
|
|
1336
|
-
state = target.readonlySelectors.get(fullKey);
|
|
1337
|
-
break;
|
|
1338
|
-
}
|
|
1339
|
-
if (state)
|
|
1340
|
-
return deposit(state);
|
|
1341
|
-
return state;
|
|
1342
|
-
}
|
|
1343
|
-
function findInStore(store, familyToken, key) {
|
|
1344
|
-
const family = withdraw(store, familyToken);
|
|
1345
|
-
const existingStateToken = seekInStore(store, familyToken, key);
|
|
1346
|
-
if (existingStateToken)
|
|
1347
|
-
return existingStateToken;
|
|
1348
|
-
return mintInStore(DO_NOT_CREATE, store, family, key);
|
|
1349
|
-
}
|
|
1350
|
-
function createReadonlyPureSelectorFamily(store, options, internalRoles) {
|
|
1351
|
-
const familyKey = options.key;
|
|
1352
|
-
const type = `readonly_pure_selector_family`;
|
|
1353
|
-
const familyToken = {
|
|
1354
|
-
key: familyKey,
|
|
1355
|
-
type
|
|
1356
|
-
};
|
|
1357
|
-
const existing = store.families.get(familyKey);
|
|
1358
|
-
if (existing && store.config.isProduction === true)
|
|
1359
|
-
store.logger.error(`\u2757`, type, familyKey, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1360
|
-
const subject = new Subject;
|
|
1361
|
-
const create = (key) => {
|
|
1362
|
-
const subKey = stringifyJson(key);
|
|
1363
|
-
const family = {
|
|
1364
|
-
key: familyKey,
|
|
1365
|
-
subKey
|
|
1366
|
-
};
|
|
1367
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1368
|
-
const target = newest(store);
|
|
1369
|
-
const individualOptions = {
|
|
1370
|
-
key: fullKey,
|
|
1371
|
-
get: options.get(key)
|
|
1372
|
-
};
|
|
1373
|
-
if (options.catch)
|
|
1374
|
-
individualOptions.catch = options.catch;
|
|
1375
|
-
return createReadonlyPureSelector(target, individualOptions, family);
|
|
1376
|
-
};
|
|
1377
|
-
const readonlySelectorFamily = {
|
|
1378
|
-
...familyToken,
|
|
1379
|
-
create,
|
|
1380
|
-
internalRoles,
|
|
1381
|
-
subject,
|
|
1382
|
-
install: (s) => createReadonlyPureSelectorFamily(s, options),
|
|
1383
|
-
default: (key) => {
|
|
1384
|
-
return options.get(key)({
|
|
1385
|
-
get: (...args) => getFromStore(store, ...args),
|
|
1386
|
-
find: (...args) => findInStore(store, ...args),
|
|
1387
|
-
json: (token) => getJsonToken(store, token)
|
|
1388
|
-
});
|
|
1389
|
-
}
|
|
1390
|
-
};
|
|
1391
|
-
store.families.set(familyKey, readonlySelectorFamily);
|
|
1392
|
-
return familyToken;
|
|
1393
|
-
}
|
|
1394
|
-
function createRegularAtomFamily(store, options, internalRoles) {
|
|
1395
|
-
const familyToken = {
|
|
1396
|
-
key: options.key,
|
|
1397
|
-
type: `atom_family`
|
|
1398
|
-
};
|
|
1399
|
-
const existing = store.families.get(options.key);
|
|
1400
|
-
if (existing && store.config.isProduction === true)
|
|
1401
|
-
store.logger.error(`\u2757`, `atom_family`, options.key, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1402
|
-
const subject = new Subject;
|
|
1403
|
-
const create = (key) => {
|
|
1404
|
-
const subKey = stringifyJson(key);
|
|
1405
|
-
const family = {
|
|
1406
|
-
key: options.key,
|
|
1407
|
-
subKey
|
|
1408
|
-
};
|
|
1409
|
-
const fullKey = `${options.key}(${subKey})`;
|
|
1410
|
-
const target = newest(store);
|
|
1411
|
-
const def = options.default;
|
|
1412
|
-
const individualOptions = {
|
|
1413
|
-
key: fullKey,
|
|
1414
|
-
default: isFn(def) ? () => def(key) : def
|
|
1415
|
-
};
|
|
1416
|
-
if (options.effects)
|
|
1417
|
-
individualOptions.effects = options.effects(key);
|
|
1418
|
-
if (options.catch)
|
|
1419
|
-
individualOptions.catch = options.catch;
|
|
1420
|
-
return createRegularAtom(target, individualOptions, family);
|
|
1421
|
-
};
|
|
1422
|
-
const atomFamily$1 = {
|
|
1423
|
-
...familyToken,
|
|
1424
|
-
create,
|
|
1425
|
-
default: options.default,
|
|
1426
|
-
subject,
|
|
1427
|
-
install: (s) => createRegularAtomFamily(s, options),
|
|
1428
|
-
internalRoles
|
|
1429
|
-
};
|
|
1430
|
-
store.families.set(options.key, atomFamily$1);
|
|
1431
|
-
if (isFn(options.default) === false)
|
|
1432
|
-
store.defaults.set(options.key, options.default);
|
|
1433
|
-
return familyToken;
|
|
1434
|
-
}
|
|
1435
|
-
function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
|
|
1436
|
-
const familyKey = options.key;
|
|
1437
|
-
const type = `readonly_held_selector_family`;
|
|
1438
|
-
const familyToken = {
|
|
1439
|
-
key: familyKey,
|
|
1440
|
-
type
|
|
1441
|
-
};
|
|
1442
|
-
const existing = store.families.get(familyKey);
|
|
1443
|
-
if (existing && store.config.isProduction === true)
|
|
1444
|
-
store.logger.error(`\u2757`, type, familyKey, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1445
|
-
const subject = new Subject;
|
|
1446
|
-
const create = (key) => {
|
|
1447
|
-
const subKey = stringifyJson(key);
|
|
1448
|
-
const family = {
|
|
1449
|
-
key: familyKey,
|
|
1450
|
-
subKey
|
|
1451
|
-
};
|
|
1452
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1453
|
-
return createReadonlyHeldSelector(newest(store), {
|
|
1454
|
-
key: fullKey,
|
|
1455
|
-
const: options.const(key),
|
|
1456
|
-
get: options.get(key)
|
|
1457
|
-
}, family);
|
|
1458
|
-
};
|
|
1459
|
-
const readonlySelectorFamily = {
|
|
1460
|
-
...familyToken,
|
|
1461
|
-
create,
|
|
1462
|
-
internalRoles,
|
|
1463
|
-
subject,
|
|
1464
|
-
install: (s) => createReadonlyHeldSelectorFamily(s, options),
|
|
1465
|
-
default: options.const
|
|
1466
|
-
};
|
|
1467
|
-
store.families.set(familyKey, readonlySelectorFamily);
|
|
1468
|
-
return familyToken;
|
|
1469
|
-
}
|
|
1470
|
-
function createWritableHeldSelectorFamily(store, options, internalRoles) {
|
|
1471
|
-
const familyKey = options.key;
|
|
1472
|
-
const type = `writable_held_selector_family`;
|
|
1473
|
-
const familyToken = {
|
|
1474
|
-
key: familyKey,
|
|
1475
|
-
type
|
|
1476
|
-
};
|
|
1477
|
-
const existing = store.families.get(familyKey);
|
|
1478
|
-
if (existing && store.config.isProduction === true)
|
|
1479
|
-
store.logger.error(`\u2757`, type, familyKey, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1480
|
-
const subject = new Subject;
|
|
1481
|
-
const create = (key) => {
|
|
1482
|
-
const subKey = stringifyJson(key);
|
|
1483
|
-
const family = {
|
|
1484
|
-
key: familyKey,
|
|
1485
|
-
subKey
|
|
1486
|
-
};
|
|
1487
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1488
|
-
return createWritableHeldSelector(newest(store), {
|
|
1489
|
-
key: fullKey,
|
|
1490
|
-
const: options.const(key),
|
|
1491
|
-
get: options.get(key),
|
|
1492
|
-
set: options.set(key)
|
|
1493
|
-
}, family);
|
|
1494
|
-
};
|
|
1495
|
-
const selectorFamily$1 = {
|
|
1496
|
-
...familyToken,
|
|
1497
|
-
create,
|
|
1498
|
-
internalRoles,
|
|
1499
|
-
subject,
|
|
1500
|
-
install: (s) => createWritableHeldSelectorFamily(s, options),
|
|
1501
|
-
default: options.const
|
|
1502
|
-
};
|
|
1503
|
-
store.families.set(familyKey, selectorFamily$1);
|
|
1504
|
-
return familyToken;
|
|
1505
|
-
}
|
|
1506
|
-
function createWritablePureSelectorFamily(store, options, internalRoles) {
|
|
1507
|
-
const familyKey = options.key;
|
|
1508
|
-
const type = `writable_pure_selector_family`;
|
|
1509
|
-
const familyToken = {
|
|
1510
|
-
key: familyKey,
|
|
1511
|
-
type
|
|
1512
|
-
};
|
|
1513
|
-
const existing = store.families.get(familyKey);
|
|
1514
|
-
if (existing && store.config.isProduction === true)
|
|
1515
|
-
store.logger.error(`\u2757`, type, familyKey, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1516
|
-
const subject = new Subject;
|
|
1517
|
-
const create = (key) => {
|
|
1518
|
-
const subKey = stringifyJson(key);
|
|
1519
|
-
const family = {
|
|
1520
|
-
key: familyKey,
|
|
1521
|
-
subKey
|
|
1522
|
-
};
|
|
1523
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1524
|
-
const target = newest(store);
|
|
1525
|
-
const individualOptions = {
|
|
1526
|
-
key: fullKey,
|
|
1527
|
-
get: options.get(key),
|
|
1528
|
-
set: options.set(key)
|
|
1529
|
-
};
|
|
1530
|
-
if (options.catch)
|
|
1531
|
-
individualOptions.catch = options.catch;
|
|
1532
|
-
return createWritablePureSelector(target, individualOptions, family);
|
|
1533
|
-
};
|
|
1534
|
-
const selectorFamily$1 = {
|
|
1535
|
-
...familyToken,
|
|
1536
|
-
create,
|
|
1537
|
-
internalRoles,
|
|
1538
|
-
subject,
|
|
1539
|
-
install: (s) => createWritablePureSelectorFamily(s, options),
|
|
1540
|
-
default: (key) => {
|
|
1541
|
-
return options.get(key)({
|
|
1542
|
-
get: (...args) => getFromStore(store, ...args),
|
|
1543
|
-
find: (...args) => findInStore(store, ...args),
|
|
1544
|
-
json: (token) => getJsonToken(store, token)
|
|
1545
|
-
});
|
|
1546
|
-
}
|
|
1547
|
-
};
|
|
1548
|
-
store.families.set(familyKey, selectorFamily$1);
|
|
1549
|
-
return familyToken;
|
|
1550
|
-
}
|
|
1551
|
-
function createSelectorFamily(store, options) {
|
|
1552
|
-
const isWritable = `set` in options;
|
|
1553
|
-
const isHeld = `const` in options;
|
|
1554
|
-
if (isHeld && isWritable)
|
|
1555
|
-
return createWritableHeldSelectorFamily(store, options, undefined);
|
|
1556
|
-
if (isHeld)
|
|
1557
|
-
return createReadonlyHeldSelectorFamily(store, options, undefined);
|
|
1558
|
-
if (isWritable)
|
|
1559
|
-
return createWritablePureSelectorFamily(store, options);
|
|
1560
|
-
return createReadonlyPureSelectorFamily(store, options);
|
|
1561
|
-
}
|
|
1562
|
-
function openOperation(store, token) {
|
|
1563
|
-
if (store.operation.open) {
|
|
1564
|
-
const rejectionTime = performance.now();
|
|
1565
|
-
store.logger.info(`\uD83D\uDEAB`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
|
|
1566
|
-
return rejectionTime;
|
|
1567
|
-
}
|
|
1568
|
-
store.operation = {
|
|
1569
|
-
open: true,
|
|
1570
|
-
done: /* @__PURE__ */ new Set,
|
|
1571
|
-
prev: /* @__PURE__ */ new Map,
|
|
1572
|
-
timestamp: Date.now(),
|
|
1573
|
-
token,
|
|
1574
|
-
subEvents: []
|
|
1575
|
-
};
|
|
1576
|
-
store.logger.info(`\u2B55`, token.type, token.key, `operation start in store "${store.config.name}"${isChildStore(store) ? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"` : ``}`);
|
|
1577
|
-
return store;
|
|
1578
|
-
}
|
|
1579
|
-
function closeOperation(store) {
|
|
1580
|
-
if (store.operation.open)
|
|
1581
|
-
store.logger.info(`\uD83D\uDD34`, store.operation.token.type, store.operation.token.key, `operation done in store "${store.config.name}"`);
|
|
1582
|
-
store.operation = { open: false };
|
|
1583
|
-
store.on.operationClose.next(store.operation);
|
|
1584
|
-
}
|
|
1585
|
-
var isDone = (store, key) => {
|
|
1586
|
-
if (!store.operation.open) {
|
|
1587
|
-
store.logger.error(`\uD83D\uDC1E`, `unknown`, key, `isDone called outside of an operation. This is probably a bug in AtomIO.`);
|
|
1588
|
-
return true;
|
|
1589
|
-
}
|
|
1590
|
-
return store.operation.done.has(key);
|
|
1591
|
-
};
|
|
1592
|
-
var markDone = (store, key) => {
|
|
1593
|
-
if (!store.operation.open) {
|
|
1594
|
-
store.logger.error(`\uD83D\uDC1E`, `unknown`, key, `markDone called outside of an operation. This is probably a bug in AtomIO.`);
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
store.operation.done.add(key);
|
|
1598
|
-
};
|
|
1599
|
-
function dispatchOrDeferStateUpdate(target, state, proto, stateIsNewlyCreated, family) {
|
|
1600
|
-
const { oldValue, newValue } = proto;
|
|
1601
|
-
const hasOldValue = `oldValue` in proto;
|
|
1602
|
-
const token = deposit(state);
|
|
1603
|
-
if (stateIsNewlyCreated && family) {
|
|
1604
|
-
state.subject.next({ newValue });
|
|
1605
|
-
const stateCreationEvent = {
|
|
1606
|
-
checkpoint: true,
|
|
1607
|
-
type: `state_creation`,
|
|
1608
|
-
subType: `writable`,
|
|
1609
|
-
token,
|
|
1610
|
-
timestamp: Date.now(),
|
|
1611
|
-
value: newValue
|
|
1612
|
-
};
|
|
1613
|
-
target.operation.subEvents.push(stateCreationEvent);
|
|
1614
|
-
family.subject.next(stateCreationEvent);
|
|
1615
|
-
const innerTarget = newest(target);
|
|
1616
|
-
if (token.family) {
|
|
1617
|
-
if (isRootStore(innerTarget))
|
|
1618
|
-
switch (token.type) {
|
|
1619
|
-
case `atom`:
|
|
1620
|
-
case `mutable_atom`:
|
|
1621
|
-
target.on.atomCreation.next(token);
|
|
1622
|
-
break;
|
|
1623
|
-
case `writable_pure_selector`:
|
|
1624
|
-
case `writable_held_selector`:
|
|
1625
|
-
target.on.selectorCreation.next(token);
|
|
1626
|
-
break;
|
|
1627
|
-
}
|
|
1628
|
-
else if (isChildStore(innerTarget) && innerTarget.on.transactionApplying.state === null)
|
|
1629
|
-
innerTarget.transactionMeta.update.subEvents.push(stateCreationEvent);
|
|
1630
|
-
}
|
|
1631
|
-
return;
|
|
1632
|
-
}
|
|
1633
|
-
const { key, subject, type } = state;
|
|
1634
|
-
let update;
|
|
1635
|
-
if (hasOldValue)
|
|
1636
|
-
update = {
|
|
1637
|
-
oldValue: isTransceiver(oldValue) ? oldValue.READONLY_VIEW : oldValue,
|
|
1638
|
-
newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue
|
|
1639
|
-
};
|
|
1640
|
-
else
|
|
1641
|
-
update = { newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue };
|
|
1642
|
-
if (isRootStore(target)) {
|
|
1643
|
-
switch (type) {
|
|
1644
|
-
case `mutable_atom`:
|
|
1645
|
-
target.logger.info(`\uD83D\uDCE2`, type, key, `is now (`, newValue, `) subscribers:`, subject.subscribers.keys());
|
|
1646
|
-
break;
|
|
1647
|
-
case `atom`:
|
|
1648
|
-
case `writable_pure_selector`:
|
|
1649
|
-
case `writable_held_selector`:
|
|
1650
|
-
target.logger.info(`\uD83D\uDCE2`, type, key, `went (`, oldValue, `->`, newValue, `) subscribers:`, subject.subscribers.keys());
|
|
1651
|
-
}
|
|
1652
|
-
subject.next(update);
|
|
1653
|
-
}
|
|
1654
|
-
if (isChildStore(target) && (type === `mutable_atom` || type === `atom`)) {
|
|
1655
|
-
if (target.on.transactionApplying.state === null) {
|
|
1656
|
-
if (isTransceiver(newValue))
|
|
1657
|
-
return;
|
|
1658
|
-
const { timestamp } = target.operation;
|
|
1659
|
-
const atomUpdate = {
|
|
1660
|
-
type: `atom_update`,
|
|
1661
|
-
token,
|
|
1662
|
-
timestamp,
|
|
1663
|
-
update
|
|
1664
|
-
};
|
|
1665
|
-
target.transactionMeta.update.subEvents.push(atomUpdate);
|
|
1666
|
-
target.logger.info(`\uD83D\uDCC1`, `atom`, key, `stowed (`, oldValue, `->`, newValue, `)`);
|
|
1667
|
-
return;
|
|
1668
|
-
}
|
|
1669
|
-
if (hasRole(state, `tracker:signal`)) {
|
|
1670
|
-
const keyOfMutable = key.slice(1);
|
|
1671
|
-
const mutable = target.atoms.get(keyOfMutable);
|
|
1672
|
-
if (readOrComputeValue(target, mutable, `mut`).do(update.newValue) === null === true)
|
|
1673
|
-
evictDownstreamFromAtom(target, mutable);
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
var UNSET = Symbol(`UNSET`);
|
|
1678
|
-
var setAtom = (target, atom$1, next) => {
|
|
1679
|
-
let oldValue;
|
|
1680
|
-
let newValue;
|
|
1681
|
-
if (isFn(next)) {
|
|
1682
|
-
const prev = readOrComputeValue(target, atom$1, `mut`);
|
|
1683
|
-
oldValue = prev;
|
|
1684
|
-
newValue = next(prev);
|
|
1685
|
-
} else {
|
|
1686
|
-
if (target.valueMap.has(atom$1.key))
|
|
1687
|
-
oldValue = readFromCache(target, atom$1, `mut`);
|
|
1688
|
-
else if (atom$1.type === `atom` && !isFn(atom$1.default))
|
|
1689
|
-
oldValue = atom$1.default;
|
|
1690
|
-
else
|
|
1691
|
-
oldValue = UNSET;
|
|
1692
|
-
newValue = next;
|
|
1693
|
-
}
|
|
1694
|
-
target.logger.info(`\u2B50`, `atom`, atom$1.key, `setting value`, newValue);
|
|
1695
|
-
newValue = writeToCache(target, atom$1, newValue);
|
|
1696
|
-
markDone(target, atom$1.key);
|
|
1697
|
-
evictDownstreamFromAtom(target, atom$1);
|
|
1698
|
-
if (oldValue === UNSET)
|
|
1699
|
-
return { newValue };
|
|
1700
|
-
return {
|
|
1701
|
-
oldValue,
|
|
1702
|
-
newValue
|
|
1703
|
-
};
|
|
1704
|
-
};
|
|
1705
|
-
function resetAtom(target, atom$1) {
|
|
1706
|
-
switch (atom$1.type) {
|
|
1707
|
-
case `mutable_atom`:
|
|
1708
|
-
return setAtom(target, atom$1, new atom$1.class);
|
|
1709
|
-
case `atom`: {
|
|
1710
|
-
let def;
|
|
1711
|
-
if (isFn(atom$1.default))
|
|
1712
|
-
def = safeCompute(target, atom$1);
|
|
1713
|
-
else
|
|
1714
|
-
def = atom$1.default;
|
|
1715
|
-
return setAtom(target, atom$1, def);
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
function resetAtomOrSelector(target, state) {
|
|
1720
|
-
let protoUpdate;
|
|
1721
|
-
switch (state.type) {
|
|
1722
|
-
case `atom`:
|
|
1723
|
-
case `mutable_atom`:
|
|
1724
|
-
protoUpdate = resetAtom(target, state);
|
|
1725
|
-
break;
|
|
1726
|
-
case `writable_held_selector`:
|
|
1727
|
-
{
|
|
1728
|
-
const atoms = traceRootSelectorAtoms(target, state.key);
|
|
1729
|
-
for (const atom$1 of atoms.values())
|
|
1730
|
-
dispatchOrDeferStateUpdate(target, state, resetAtom(target, atom$1), false);
|
|
1731
|
-
const value = state.getFrom(target);
|
|
1732
|
-
protoUpdate = {
|
|
1733
|
-
oldValue: value,
|
|
1734
|
-
newValue: value
|
|
1735
|
-
};
|
|
1736
|
-
}
|
|
1737
|
-
break;
|
|
1738
|
-
case `writable_pure_selector`:
|
|
1739
|
-
{
|
|
1740
|
-
const oldValue = safeCompute(target, state);
|
|
1741
|
-
const atoms = traceRootSelectorAtoms(target, state.key);
|
|
1742
|
-
for (const atom$1 of atoms.values())
|
|
1743
|
-
dispatchOrDeferStateUpdate(target, state, resetAtom(target, atom$1), false);
|
|
1744
|
-
protoUpdate = {
|
|
1745
|
-
oldValue,
|
|
1746
|
-
newValue: safeCompute(target, state)
|
|
1747
|
-
};
|
|
1748
|
-
}
|
|
1749
|
-
break;
|
|
1750
|
-
}
|
|
1751
|
-
return protoUpdate;
|
|
1752
|
-
}
|
|
1753
|
-
function setIntoStore(store, ...params) {
|
|
1754
|
-
operateOnStore(OWN_OP, store, ...params);
|
|
1755
|
-
}
|
|
1756
|
-
var RESET_STATE = Symbol(`RESET`);
|
|
1757
|
-
function resetInStore(store, ...params) {
|
|
1758
|
-
setIntoStore(store, ...[...params, RESET_STATE]);
|
|
1759
|
-
}
|
|
1760
|
-
function setSelector(target, selector$1, next) {
|
|
1761
|
-
let oldValue;
|
|
1762
|
-
let newValue;
|
|
1763
|
-
let constant;
|
|
1764
|
-
const { type, key } = selector$1;
|
|
1765
|
-
switch (selector$1.type) {
|
|
1766
|
-
case `writable_pure_selector`:
|
|
1767
|
-
oldValue = readOrComputeValue(target, selector$1, `mut`);
|
|
1768
|
-
newValue = become(next, oldValue);
|
|
1769
|
-
newValue = writeToCache(target, selector$1, newValue);
|
|
1770
|
-
break;
|
|
1771
|
-
case `writable_held_selector`:
|
|
1772
|
-
constant = selector$1.const;
|
|
1773
|
-
become(next, constant);
|
|
1774
|
-
oldValue = constant;
|
|
1775
|
-
newValue = constant;
|
|
1776
|
-
}
|
|
1777
|
-
target.logger.info(`\u2B50`, type, key, `setting to`, newValue);
|
|
1778
|
-
markDone(target, key);
|
|
1779
|
-
selector$1.setSelf(newValue);
|
|
1780
|
-
return {
|
|
1781
|
-
oldValue,
|
|
1782
|
-
newValue
|
|
1783
|
-
};
|
|
1784
|
-
}
|
|
1785
|
-
var setAtomOrSelector = (target, state, value) => {
|
|
1786
|
-
let protoUpdate;
|
|
1787
|
-
switch (state.type) {
|
|
1788
|
-
case `atom`:
|
|
1789
|
-
case `mutable_atom`:
|
|
1790
|
-
protoUpdate = setAtom(target, state, value);
|
|
1791
|
-
break;
|
|
1792
|
-
case `writable_pure_selector`:
|
|
1793
|
-
case `writable_held_selector`:
|
|
1794
|
-
protoUpdate = setSelector(target, state, value);
|
|
1795
|
-
break;
|
|
1796
|
-
}
|
|
1797
|
-
return protoUpdate;
|
|
1798
|
-
};
|
|
1799
|
-
var OWN_OP = Symbol(`OWN_OP`);
|
|
1800
|
-
var JOIN_OP = Symbol(`JOIN_OP`);
|
|
1801
|
-
function operateOnStore(opMode, store, ...params) {
|
|
1802
|
-
let existingToken;
|
|
1803
|
-
let brandNewToken;
|
|
1804
|
-
let token;
|
|
1805
|
-
let family;
|
|
1806
|
-
let key;
|
|
1807
|
-
let value;
|
|
1808
|
-
if (params.length === 2) {
|
|
1809
|
-
token = params[0];
|
|
1810
|
-
value = params[1];
|
|
1811
|
-
if (`family` in token) {
|
|
1812
|
-
family = getFamilyOfToken(store, token);
|
|
1813
|
-
key = parseJson(token.family.subKey);
|
|
1814
|
-
existingToken = seekInStore(store, family, key);
|
|
1815
|
-
if (!existingToken)
|
|
1816
|
-
token = brandNewToken = mintInStore(MUST_CREATE, store, family, key);
|
|
1817
|
-
else
|
|
1818
|
-
token = existingToken;
|
|
1819
|
-
}
|
|
1820
|
-
} else {
|
|
1821
|
-
family = withdraw(store, params[0]);
|
|
1822
|
-
key = params[1];
|
|
1823
|
-
value = params[2];
|
|
1824
|
-
existingToken = seekInStore(store, family, key);
|
|
1825
|
-
if (!existingToken)
|
|
1826
|
-
token = brandNewToken = mintInStore(MUST_CREATE, store, family, key);
|
|
1827
|
-
else
|
|
1828
|
-
token = existingToken;
|
|
1829
|
-
}
|
|
1830
|
-
const action = value === RESET_STATE ? `reset` : `set`;
|
|
1831
|
-
let target;
|
|
1832
|
-
if (opMode === OWN_OP) {
|
|
1833
|
-
const result = openOperation(store, token);
|
|
1834
|
-
if (typeof result === `number`) {
|
|
1835
|
-
const rejectionTime = result;
|
|
1836
|
-
const unsubscribe = store.on.operationClose.subscribe(`waiting to ${action} "${token.key}" at T-${rejectionTime}`, function waitUntilOperationCloseToSetState() {
|
|
1837
|
-
unsubscribe();
|
|
1838
|
-
store.logger.info(`\uD83D\uDFE2`, token.type, token.key, `resuming deferred`, action, `from T-${rejectionTime}`);
|
|
1839
|
-
operateOnStore(opMode, store, token, value);
|
|
1840
|
-
});
|
|
1841
|
-
return;
|
|
1842
|
-
}
|
|
1843
|
-
target = result;
|
|
1844
|
-
} else
|
|
1845
|
-
target = store;
|
|
1846
|
-
if (`counterfeit` in token && `family` in token) {
|
|
1847
|
-
const subKey = token.family.subKey;
|
|
1848
|
-
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
1849
|
-
store.logger.error(`\u274C`, token.type, token.key, `could not be`, action, `because key`, subKey, `is not allocated.`, disposal ? `this key was previously disposed:${disposal.trace}` : `(no previous disposal trace found)`);
|
|
1850
|
-
return;
|
|
1851
|
-
}
|
|
1852
|
-
const state = withdraw(target, token);
|
|
1853
|
-
let protoUpdate;
|
|
1854
|
-
if (value === RESET_STATE)
|
|
1855
|
-
protoUpdate = resetAtomOrSelector(target, state);
|
|
1856
|
-
else
|
|
1857
|
-
protoUpdate = setAtomOrSelector(target, state, value);
|
|
1858
|
-
dispatchOrDeferStateUpdate(target, state, protoUpdate, Boolean(brandNewToken), family);
|
|
1859
|
-
if (opMode === OWN_OP)
|
|
1860
|
-
closeOperation(target);
|
|
1861
|
-
}
|
|
1862
|
-
var isAtomKey = (store, key) => newest(store).atoms.has(key);
|
|
1863
|
-
var isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
|
|
1864
|
-
var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
|
|
1865
|
-
var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
|
|
1866
|
-
function getSelectorDependencyKeys(store, key) {
|
|
1867
|
-
return newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
|
|
1868
|
-
}
|
|
1869
|
-
function traceRootSelectorAtoms(store, selectorKey, covered = /* @__PURE__ */ new Set) {
|
|
1870
|
-
const dependencies = getSelectorDependencyKeys(store, selectorKey);
|
|
1871
|
-
const roots = /* @__PURE__ */ new Map;
|
|
1872
|
-
while (dependencies.length > 0) {
|
|
1873
|
-
const dependencyKey = dependencies.pop();
|
|
1874
|
-
if (covered.has(dependencyKey))
|
|
1875
|
-
continue;
|
|
1876
|
-
covered.add(dependencyKey);
|
|
1877
|
-
if (isAtomKey(store, dependencyKey)) {
|
|
1878
|
-
const atom$1 = store.atoms.get(dependencyKey);
|
|
1879
|
-
roots.set(atom$1.key, atom$1);
|
|
1880
|
-
} else
|
|
1881
|
-
dependencies.push(...getSelectorDependencyKeys(store, dependencyKey));
|
|
1882
|
-
}
|
|
1883
|
-
return roots;
|
|
1884
|
-
}
|
|
1885
|
-
function updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered) {
|
|
1886
|
-
const target = newest(store);
|
|
1887
|
-
const { type: dependencyType, key: dependencyKey } = dependency;
|
|
1888
|
-
if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
|
|
1889
|
-
target.selectorAtoms.set({
|
|
1890
|
-
selectorKey,
|
|
1891
|
-
atomKey: dependencyKey
|
|
1892
|
-
});
|
|
1893
|
-
store.logger.info(`\uD83D\uDD0D`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
|
|
1894
|
-
} else {
|
|
1895
|
-
const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
|
|
1896
|
-
store.logger.info(`\uD83D\uDD0D`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
|
|
1897
|
-
for (const { key: atomKey } of rootKeys.values())
|
|
1898
|
-
target.selectorAtoms = target.selectorAtoms.set({
|
|
1899
|
-
selectorKey,
|
|
1900
|
-
atomKey
|
|
1901
|
-
});
|
|
1902
|
-
}
|
|
1903
|
-
covered.add(dependencyKey);
|
|
1904
|
-
}
|
|
1905
|
-
function registerSelector(store, selectorType, selectorKey, covered) {
|
|
1906
|
-
return {
|
|
1907
|
-
get: (...params) => {
|
|
1908
|
-
const target = newest(store);
|
|
1909
|
-
const { token, family, subKey } = reduceReference(store, ...params);
|
|
1910
|
-
let dependencyValue;
|
|
1911
|
-
if (`counterfeit` in token && family && subKey)
|
|
1912
|
-
dependencyValue = getFallback(store, token, family, subKey);
|
|
1913
|
-
else
|
|
1914
|
-
dependencyValue = readOrComputeValue(store, withdraw(store, token));
|
|
1915
|
-
store.logger.info(`\uD83D\uDD0C`, selectorType, selectorKey, `registers dependency ( "${token.key}" =`, dependencyValue, `)`);
|
|
1916
|
-
target.selectorGraph.set({
|
|
1917
|
-
upstreamSelectorKey: token.key,
|
|
1918
|
-
downstreamSelectorKey: selectorKey
|
|
1919
|
-
}, { source: token.key });
|
|
1920
|
-
updateSelectorAtoms(store, selectorType, selectorKey, token, covered);
|
|
1921
|
-
return dependencyValue;
|
|
1922
|
-
},
|
|
1923
|
-
set: (...params) => {
|
|
1924
|
-
operateOnStore(JOIN_OP, newest(store), ...params);
|
|
1925
|
-
},
|
|
1926
|
-
find: (...args) => findInStore(store, ...args),
|
|
1927
|
-
json: (token) => getJsonToken(store, token)
|
|
1928
|
-
};
|
|
1929
|
-
}
|
|
1930
|
-
function createReadonlyHeldSelector(store, options, family) {
|
|
1931
|
-
const target = newest(store);
|
|
1932
|
-
const subject = new Subject;
|
|
1933
|
-
const covered = /* @__PURE__ */ new Set;
|
|
1934
|
-
const { key, const: constant } = options;
|
|
1935
|
-
const type = `readonly_held_selector`;
|
|
1936
|
-
store.logger.info(`\uD83D\uDD28`, type, key, `is being created`);
|
|
1937
|
-
const { get, find, json } = registerSelector(target, type, key, covered);
|
|
1938
|
-
const getFrom = (innerTarget) => {
|
|
1939
|
-
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
1940
|
-
for (const [downstreamSelectorKey, { source }] of upstreamStates)
|
|
1941
|
-
if (source !== key)
|
|
1942
|
-
innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1943
|
-
innerTarget.selectorAtoms.delete(key);
|
|
1944
|
-
options.get({
|
|
1945
|
-
get,
|
|
1946
|
-
find,
|
|
1947
|
-
json
|
|
1948
|
-
}, constant);
|
|
1949
|
-
writeToCache(innerTarget, readonlySelector, constant);
|
|
1950
|
-
store.logger.info(`\u2728`, type, key, `=`, constant);
|
|
1951
|
-
covered.clear();
|
|
1952
|
-
return constant;
|
|
1953
|
-
};
|
|
1954
|
-
const readonlySelector = {
|
|
1955
|
-
...options,
|
|
1956
|
-
type,
|
|
1957
|
-
subject,
|
|
1958
|
-
getFrom,
|
|
1959
|
-
install: (s) => createReadonlyHeldSelector(s, options, family)
|
|
1960
|
-
};
|
|
1961
|
-
if (family)
|
|
1962
|
-
readonlySelector.family = family;
|
|
1963
|
-
target.readonlySelectors.set(key, readonlySelector);
|
|
1964
|
-
const token = {
|
|
1965
|
-
key,
|
|
1966
|
-
type
|
|
1967
|
-
};
|
|
1968
|
-
if (family)
|
|
1969
|
-
token.family = family;
|
|
1970
|
-
return token;
|
|
1971
|
-
}
|
|
1972
|
-
function createReadonlyPureSelector(store, options, family) {
|
|
1973
|
-
const target = newest(store);
|
|
1974
|
-
const subject = new Subject;
|
|
1975
|
-
const covered = /* @__PURE__ */ new Set;
|
|
1976
|
-
const key = options.key;
|
|
1977
|
-
const type = `readonly_pure_selector`;
|
|
1978
|
-
store.logger.info(`\uD83D\uDD28`, type, key, `is being created`);
|
|
1979
|
-
const { get, find, json } = registerSelector(target, type, key, covered);
|
|
1980
|
-
const getFrom = () => {
|
|
1981
|
-
const innerTarget = newest(store);
|
|
1982
|
-
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
1983
|
-
for (const [downstreamSelectorKey, { source }] of upstreamStates)
|
|
1984
|
-
if (source !== key)
|
|
1985
|
-
innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1986
|
-
innerTarget.selectorAtoms.delete(key);
|
|
1987
|
-
const value = options.get({
|
|
1988
|
-
get,
|
|
1989
|
-
find,
|
|
1990
|
-
json
|
|
1991
|
-
});
|
|
1992
|
-
store.logger.info(`\u2728`, type, key, `=`, value);
|
|
1993
|
-
covered.clear();
|
|
1994
|
-
return value;
|
|
1995
|
-
};
|
|
1996
|
-
const readonlySelector = {
|
|
1997
|
-
...options,
|
|
1998
|
-
type,
|
|
1999
|
-
subject,
|
|
2000
|
-
getFrom,
|
|
2001
|
-
install: (s) => createReadonlyPureSelector(s, options, family)
|
|
2002
|
-
};
|
|
2003
|
-
if (family)
|
|
2004
|
-
readonlySelector.family = family;
|
|
2005
|
-
target.readonlySelectors.set(key, readonlySelector);
|
|
2006
|
-
const token = {
|
|
2007
|
-
key,
|
|
2008
|
-
type
|
|
2009
|
-
};
|
|
2010
|
-
if (family)
|
|
2011
|
-
token.family = family;
|
|
2012
|
-
return token;
|
|
2013
|
-
}
|
|
2014
|
-
function createWritableHeldSelector(store, options, family) {
|
|
2015
|
-
const target = newest(store);
|
|
2016
|
-
const subject = new Subject;
|
|
2017
|
-
const covered = /* @__PURE__ */ new Set;
|
|
2018
|
-
const { key, const: constant } = options;
|
|
2019
|
-
const type = `writable_held_selector`;
|
|
2020
|
-
store.logger.info(`\uD83D\uDD28`, type, key, `is being created`);
|
|
2021
|
-
const setterToolkit = registerSelector(target, type, key, covered);
|
|
2022
|
-
const { find, get, json } = setterToolkit;
|
|
2023
|
-
const getterToolkit = {
|
|
2024
|
-
find,
|
|
2025
|
-
get,
|
|
2026
|
-
json
|
|
2027
|
-
};
|
|
2028
|
-
const getFrom = (innerTarget) => {
|
|
2029
|
-
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
2030
|
-
for (const [downstreamSelectorKey, { source }] of upstreamStates)
|
|
2031
|
-
if (source !== key)
|
|
2032
|
-
innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
2033
|
-
innerTarget.selectorAtoms.delete(key);
|
|
2034
|
-
options.get(getterToolkit, constant);
|
|
2035
|
-
writeToCache(innerTarget, mySelector, constant);
|
|
2036
|
-
store.logger.info(`\u2728`, type, key, `=`, constant);
|
|
2037
|
-
covered.clear();
|
|
2038
|
-
return constant;
|
|
2039
|
-
};
|
|
2040
|
-
const setSelf = () => {
|
|
2041
|
-
options.set(setterToolkit, constant);
|
|
2042
|
-
};
|
|
2043
|
-
const mySelector = {
|
|
2044
|
-
...options,
|
|
2045
|
-
type,
|
|
2046
|
-
subject,
|
|
2047
|
-
getFrom,
|
|
2048
|
-
setSelf,
|
|
2049
|
-
install: (s) => createWritableHeldSelector(s, options, family)
|
|
2050
|
-
};
|
|
2051
|
-
if (family)
|
|
2052
|
-
mySelector.family = family;
|
|
2053
|
-
target.writableSelectors.set(key, mySelector);
|
|
2054
|
-
const token = {
|
|
2055
|
-
key,
|
|
2056
|
-
type
|
|
2057
|
-
};
|
|
2058
|
-
if (family)
|
|
2059
|
-
token.family = family;
|
|
2060
|
-
return token;
|
|
2061
|
-
}
|
|
2062
|
-
function createWritablePureSelector(store, options, family) {
|
|
2063
|
-
const target = newest(store);
|
|
2064
|
-
const subject = new Subject;
|
|
2065
|
-
const covered = /* @__PURE__ */ new Set;
|
|
2066
|
-
const key = options.key;
|
|
2067
|
-
const type = `writable_pure_selector`;
|
|
2068
|
-
store.logger.info(`\uD83D\uDD28`, type, key, `is being created`);
|
|
2069
|
-
const setterToolkit = registerSelector(target, type, key, covered);
|
|
2070
|
-
const { find, get, json } = setterToolkit;
|
|
2071
|
-
const getterToolkit = {
|
|
2072
|
-
find,
|
|
2073
|
-
get,
|
|
2074
|
-
json
|
|
2075
|
-
};
|
|
2076
|
-
const getFrom = (innerTarget) => {
|
|
2077
|
-
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
2078
|
-
for (const [downstreamSelectorKey, { source }] of upstreamStates)
|
|
2079
|
-
if (source !== key)
|
|
2080
|
-
innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
2081
|
-
innerTarget.selectorAtoms.delete(key);
|
|
2082
|
-
const value = options.get(getterToolkit);
|
|
2083
|
-
store.logger.info(`\u2728`, type, key, `=`, value);
|
|
2084
|
-
covered.clear();
|
|
2085
|
-
return value;
|
|
2086
|
-
};
|
|
2087
|
-
const setSelf = (newValue) => {
|
|
2088
|
-
options.set(setterToolkit, newValue);
|
|
2089
|
-
};
|
|
2090
|
-
const mySelector = {
|
|
2091
|
-
...options,
|
|
2092
|
-
type,
|
|
2093
|
-
subject,
|
|
2094
|
-
getFrom,
|
|
2095
|
-
setSelf,
|
|
2096
|
-
install: (s) => createWritablePureSelector(s, options, family)
|
|
2097
|
-
};
|
|
2098
|
-
if (family)
|
|
2099
|
-
mySelector.family = family;
|
|
2100
|
-
target.writableSelectors.set(key, mySelector);
|
|
2101
|
-
const token = {
|
|
2102
|
-
key,
|
|
2103
|
-
type
|
|
2104
|
-
};
|
|
2105
|
-
if (family)
|
|
2106
|
-
token.family = family;
|
|
2107
|
-
return token;
|
|
2108
|
-
}
|
|
2109
|
-
function createStandaloneSelector(store, options) {
|
|
2110
|
-
const isWritable = `set` in options;
|
|
2111
|
-
const isHeld = `const` in options;
|
|
2112
|
-
if (isHeld && isWritable) {
|
|
2113
|
-
const state$1 = createWritableHeldSelector(store, options, undefined);
|
|
2114
|
-
store.on.selectorCreation.next(state$1);
|
|
2115
|
-
return state$1;
|
|
2116
|
-
}
|
|
2117
|
-
if (isHeld) {
|
|
2118
|
-
const state$1 = createReadonlyHeldSelector(store, options, undefined);
|
|
2119
|
-
store.on.selectorCreation.next(state$1);
|
|
2120
|
-
return state$1;
|
|
2121
|
-
}
|
|
2122
|
-
if (isWritable) {
|
|
2123
|
-
const state$1 = createWritablePureSelector(store, options, undefined);
|
|
2124
|
-
store.on.selectorCreation.next(state$1);
|
|
2125
|
-
return state$1;
|
|
2126
|
-
}
|
|
2127
|
-
const state = createReadonlyPureSelector(store, options, undefined);
|
|
2128
|
-
store.on.selectorCreation.next(state);
|
|
2129
|
-
return state;
|
|
2130
|
-
}
|
|
2131
|
-
var recallState = (store, state) => {
|
|
2132
|
-
const target = newest(store);
|
|
2133
|
-
if (target.operation.open)
|
|
2134
|
-
return target.operation.prev.get(state.key);
|
|
2135
|
-
return target.valueMap.get(state.key);
|
|
2136
|
-
};
|
|
2137
|
-
var subscribeToRootDependency = (target, selector$1, atom$1) => {
|
|
2138
|
-
return atom$1.subject.subscribe(`${selector$1.type}:${selector$1.key}`, (atomChange) => {
|
|
2139
|
-
target.logger.info(`\uD83D\uDCE2`, selector$1.type, selector$1.key, `root`, atom$1.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
|
|
2140
|
-
const oldValue = recallState(target, selector$1);
|
|
2141
|
-
const newValue = readOrComputeValue(target, selector$1);
|
|
2142
|
-
target.logger.info(`\u2728`, selector$1.type, selector$1.key, `went`, oldValue, `->`, newValue);
|
|
2143
|
-
selector$1.subject.next({
|
|
2144
|
-
newValue,
|
|
2145
|
-
oldValue
|
|
2146
|
-
});
|
|
2147
|
-
});
|
|
2148
|
-
};
|
|
2149
|
-
function subscribeToState(store, token, key, handleUpdate) {
|
|
2150
|
-
function safelyHandleUpdate(update) {
|
|
2151
|
-
if (store.operation.open && state?.type === `atom` && hasRole(state, `tracker:signal`) && `*` + store.operation.token.key === token.key && `inboundTracker` in handleUpdate)
|
|
2152
|
-
return;
|
|
2153
|
-
handleUpdate(update);
|
|
2154
|
-
}
|
|
2155
|
-
reduceReference(store, token);
|
|
2156
|
-
const state = withdraw(store, token);
|
|
2157
|
-
store.logger.info(`\uD83D\uDC40`, state.type, state.key, `Adding subscription "${key}"`);
|
|
2158
|
-
const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
|
|
2159
|
-
const rootSubs = /* @__PURE__ */ new Map;
|
|
2160
|
-
let updateHandler = safelyHandleUpdate;
|
|
2161
|
-
if (isSelector) {
|
|
2162
|
-
readOrComputeValue(store, state);
|
|
2163
|
-
for (const [atomKey, atom$1] of traceRootSelectorAtoms(store, state.key))
|
|
2164
|
-
rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
|
|
2165
|
-
updateHandler = function updateRootsBeforeHandlingUpdate(update) {
|
|
2166
|
-
const dependencies = traceRootSelectorAtoms(store, state.key);
|
|
2167
|
-
for (const [previousRootKey, unsub] of rootSubs)
|
|
2168
|
-
if (dependencies.get(previousRootKey))
|
|
2169
|
-
dependencies.delete(previousRootKey);
|
|
2170
|
-
else {
|
|
2171
|
-
unsub();
|
|
2172
|
-
rootSubs.delete(previousRootKey);
|
|
2173
|
-
}
|
|
2174
|
-
for (const [atomKey, atom$1] of dependencies)
|
|
2175
|
-
rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
|
|
2176
|
-
safelyHandleUpdate(update);
|
|
2177
|
-
};
|
|
2178
|
-
}
|
|
2179
|
-
const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
|
|
2180
|
-
const unsubscribe = () => {
|
|
2181
|
-
store.logger.info(`\uD83D\uDE48`, state.type, state.key, `Removing subscription "${key}"`);
|
|
2182
|
-
mainUnsubFunction();
|
|
2183
|
-
for (const unsubFromDependency of rootSubs.values())
|
|
2184
|
-
unsubFromDependency();
|
|
2185
|
-
};
|
|
2186
|
-
return unsubscribe;
|
|
2187
|
-
}
|
|
2188
|
-
var subscribeToTimeline = (store, token, key, handleUpdate) => {
|
|
2189
|
-
const tl = withdraw(store, token);
|
|
2190
|
-
store.logger.info(`\uD83D\uDC40`, `timeline`, token.key, `Adding subscription "${key}"`);
|
|
2191
|
-
const unsubscribe = tl.subject.subscribe(key, handleUpdate);
|
|
2192
|
-
return () => {
|
|
2193
|
-
store.logger.info(`\uD83D\uDE48`, `timeline`, token.key, `Removing subscription "${key}" from timeline`);
|
|
2194
|
-
unsubscribe();
|
|
2195
|
-
};
|
|
2196
|
-
};
|
|
2197
|
-
var Tracker = class {
|
|
2198
|
-
initializeSignalAtom(mutableState, store) {
|
|
2199
|
-
const latestSignalStateKey = `*${mutableState.key}`;
|
|
2200
|
-
store.atoms.delete(latestSignalStateKey);
|
|
2201
|
-
store.valueMap.delete(latestSignalStateKey);
|
|
2202
|
-
const familyMetaData = mutableState.family ? {
|
|
2203
|
-
key: `*${mutableState.family.key}`,
|
|
2204
|
-
subKey: mutableState.family.subKey
|
|
2205
|
-
} : undefined;
|
|
2206
|
-
const latestSignalState = createRegularAtom(store, {
|
|
2207
|
-
key: latestSignalStateKey,
|
|
2208
|
-
default: null
|
|
2209
|
-
}, familyMetaData, [`tracker:signal`]);
|
|
2210
|
-
if (store.parent?.valueMap.has(latestSignalStateKey)) {
|
|
2211
|
-
const parentValue = store.parent.valueMap.get(latestSignalStateKey);
|
|
2212
|
-
store.valueMap.set(latestSignalStateKey, parentValue);
|
|
2213
|
-
}
|
|
2214
|
-
return latestSignalState;
|
|
2215
|
-
}
|
|
2216
|
-
unsubscribeFromInnerValue;
|
|
2217
|
-
unsubscribeFromState;
|
|
2218
|
-
captureSignalsFromCore(mutableState, latestSignalState, target) {
|
|
2219
|
-
const stateKey = mutableState.key;
|
|
2220
|
-
const subscriptionKey = `tracker-from-core:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.token.key : `main`}:${stateKey}`;
|
|
2221
|
-
const trackerCapturesOutboundSignal = (update) => {
|
|
2222
|
-
operateOnStore(JOIN_OP, target, latestSignalState, update);
|
|
2223
|
-
};
|
|
2224
|
-
this.unsubscribeFromInnerValue = getFromStore(target, mutableState).subscribe(subscriptionKey, trackerCapturesOutboundSignal);
|
|
2225
|
-
this.unsubscribeFromState = subscribeToState(target, mutableState, subscriptionKey, function trackerLooksForNewReference(update) {
|
|
2226
|
-
if (update.newValue !== update.oldValue) {
|
|
2227
|
-
this.unsubscribeFromInnerValue();
|
|
2228
|
-
this.unsubscribeFromInnerValue = update.newValue.subscribe(subscriptionKey, trackerCapturesOutboundSignal);
|
|
2229
|
-
}
|
|
2230
|
-
}.bind(this));
|
|
2231
|
-
}
|
|
2232
|
-
supplySignalsToCore(mutableState, latestSignalState, target) {
|
|
2233
|
-
const stateKey = mutableState.key;
|
|
2234
|
-
const subscriptionKey = `tracker-to-core:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.token.key : `main`}:${stateKey}`;
|
|
2235
|
-
subscribeToState(target, latestSignalState, subscriptionKey, Object.assign(function trackerCapturesInboundSignal({ newValue, oldValue }) {
|
|
2236
|
-
const timelineId = target.timelineTopics.getRelatedKey(latestSignalState.key);
|
|
2237
|
-
if (timelineId && target.timelines.get(timelineId)?.timeTraveling) {
|
|
2238
|
-
const unsubscribe = subscribeToTimeline(target, {
|
|
2239
|
-
key: timelineId,
|
|
2240
|
-
type: `timeline`
|
|
2241
|
-
}, subscriptionKey, function trackerWaitsForTimeTravelToFinish(update) {
|
|
2242
|
-
unsubscribe();
|
|
2243
|
-
setIntoStore(target, mutableState, (transceiver) => {
|
|
2244
|
-
if (update === `redo` && newValue)
|
|
2245
|
-
transceiver.do(newValue);
|
|
2246
|
-
else if (update === `undo` && oldValue)
|
|
2247
|
-
transceiver.undo(oldValue);
|
|
2248
|
-
return transceiver;
|
|
2249
|
-
});
|
|
2250
|
-
});
|
|
2251
|
-
return;
|
|
2252
|
-
}
|
|
2253
|
-
setIntoStore(target, mutableState, (transceiver) => (transceiver.do(newValue), transceiver));
|
|
2254
|
-
}, { inboundTracker: true }));
|
|
2255
|
-
}
|
|
2256
|
-
mutableAtomToken;
|
|
2257
|
-
latestSignalToken;
|
|
2258
|
-
[Symbol.dispose];
|
|
2259
|
-
constructor(mutableAtomToken, store) {
|
|
2260
|
-
const target = newest(store);
|
|
2261
|
-
const latestSignalToken = this.initializeSignalAtom(mutableAtomToken, target);
|
|
2262
|
-
this.mutableAtomToken = mutableAtomToken;
|
|
2263
|
-
this.latestSignalToken = latestSignalToken;
|
|
2264
|
-
this.captureSignalsFromCore(mutableAtomToken, latestSignalToken, target);
|
|
2265
|
-
this.supplySignalsToCore(mutableAtomToken, latestSignalToken, target);
|
|
2266
|
-
target.trackers.set(mutableAtomToken.key, this);
|
|
2267
|
-
this[Symbol.dispose] = () => {
|
|
2268
|
-
this.unsubscribeFromInnerValue();
|
|
2269
|
-
this.unsubscribeFromState();
|
|
2270
|
-
target.trackers.delete(mutableAtomToken.key);
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
};
|
|
2274
|
-
function createMutableAtom(store, options, family) {
|
|
2275
|
-
store.logger.info(`\uD83D\uDD28`, `atom`, options.key, `creating in store "${store.config.name}"`);
|
|
2276
|
-
const target = newest(store);
|
|
2277
|
-
const { key } = options;
|
|
2278
|
-
const existing = target.atoms.get(key);
|
|
2279
|
-
const type = `mutable_atom`;
|
|
2280
|
-
if (existing?.type === type && store.config.isProduction === true) {
|
|
2281
|
-
store.logger.error(`\u274C`, type, key, `Tried to create atom, but it already exists in the store.`);
|
|
2282
|
-
return deposit(existing);
|
|
2283
|
-
}
|
|
2284
|
-
const subject = new Subject;
|
|
2285
|
-
const newAtom = {
|
|
2286
|
-
...options,
|
|
2287
|
-
type,
|
|
2288
|
-
install: (s) => {
|
|
2289
|
-
s.logger.info(`\uD83D\uDEE0\uFE0F`, `atom`, key, `installing in store "${s.config.name}"`);
|
|
2290
|
-
return createMutableAtom(s, options, family);
|
|
2291
|
-
},
|
|
2292
|
-
subject
|
|
2293
|
-
};
|
|
2294
|
-
if (family)
|
|
2295
|
-
newAtom.family = family;
|
|
2296
|
-
target.atoms.set(newAtom.key, newAtom);
|
|
2297
|
-
const token = deposit(newAtom);
|
|
2298
|
-
new Tracker(token, store);
|
|
2299
|
-
if (!family)
|
|
2300
|
-
createStandaloneSelector(store, {
|
|
2301
|
-
key: `${key}:JSON`,
|
|
2302
|
-
get: ({ get }) => get(token).toJSON(),
|
|
2303
|
-
set: ({ set }, newValue) => {
|
|
2304
|
-
set(token, options.class.fromJSON(newValue));
|
|
2305
|
-
}
|
|
2306
|
-
});
|
|
2307
|
-
if (options.effects) {
|
|
2308
|
-
let effectIndex = 0;
|
|
2309
|
-
const cleanupFunctions = [];
|
|
2310
|
-
for (const effect of options.effects) {
|
|
2311
|
-
const cleanup = effect({
|
|
2312
|
-
resetSelf: () => {
|
|
2313
|
-
resetInStore(store, token);
|
|
2314
|
-
},
|
|
2315
|
-
setSelf: (next) => {
|
|
2316
|
-
setIntoStore(store, token, next);
|
|
2317
|
-
},
|
|
2318
|
-
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle),
|
|
2319
|
-
token,
|
|
2320
|
-
store: eldest(store)
|
|
2321
|
-
});
|
|
2322
|
-
if (cleanup)
|
|
2323
|
-
cleanupFunctions.push(cleanup);
|
|
2324
|
-
++effectIndex;
|
|
2325
|
-
}
|
|
2326
|
-
newAtom.cleanup = () => {
|
|
2327
|
-
for (const cleanup of cleanupFunctions)
|
|
2328
|
-
cleanup();
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
|
-
store.on.atomCreation.next(token);
|
|
2332
|
-
return token;
|
|
2333
|
-
}
|
|
2334
|
-
var FamilyTracker = class {
|
|
2335
|
-
trackers = /* @__PURE__ */ new Map;
|
|
2336
|
-
latestSignalAtoms;
|
|
2337
|
-
mutableAtoms;
|
|
2338
|
-
constructor(mutableAtoms, store) {
|
|
2339
|
-
this.latestSignalAtoms = withdraw(store, createRegularAtomFamily(store, {
|
|
2340
|
-
key: `*${mutableAtoms.key}`,
|
|
2341
|
-
default: null
|
|
2342
|
-
}, [`mutable`, `updates`]));
|
|
2343
|
-
this.mutableAtoms = mutableAtoms;
|
|
2344
|
-
const trackerFamilyWatchesForCreationAndDisposalEvents = (event) => {
|
|
2345
|
-
const { type, token } = event;
|
|
2346
|
-
if (token.family) {
|
|
2347
|
-
const key = parseJson(token.family.subKey);
|
|
2348
|
-
switch (type) {
|
|
2349
|
-
case `state_creation`:
|
|
2350
|
-
this.trackers.set(key, new Tracker(token, store));
|
|
2351
|
-
break;
|
|
2352
|
-
case `state_disposal`: {
|
|
2353
|
-
const tracker = this.trackers.get(key);
|
|
2354
|
-
if (tracker) {
|
|
2355
|
-
tracker[Symbol.dispose]();
|
|
2356
|
-
this.trackers.delete(key);
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
}
|
|
2361
|
-
};
|
|
2362
|
-
this.mutableAtoms.subject.subscribe(`store=${store.config.name}::tracker-atom-family`, trackerFamilyWatchesForCreationAndDisposalEvents);
|
|
2363
|
-
}
|
|
2364
|
-
};
|
|
2365
|
-
function createMutableAtomFamily(store, options, internalRoles) {
|
|
2366
|
-
const familyToken = {
|
|
2367
|
-
key: options.key,
|
|
2368
|
-
type: `mutable_atom_family`
|
|
2369
|
-
};
|
|
2370
|
-
const existing = store.families.get(options.key);
|
|
2371
|
-
if (existing && store.config.isProduction === true)
|
|
2372
|
-
store.logger.error(`\u2757`, `mutable_atom_family`, options.key, `Overwriting an existing ${PRETTY_ENTITY_NAMES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
2373
|
-
const subject = new Subject;
|
|
2374
|
-
const create = (key) => {
|
|
2375
|
-
const subKey = stringifyJson(key);
|
|
2376
|
-
const family = {
|
|
2377
|
-
key: options.key,
|
|
2378
|
-
subKey
|
|
2379
|
-
};
|
|
2380
|
-
const fullKey = `${options.key}(${subKey})`;
|
|
2381
|
-
const target = newest(store);
|
|
2382
|
-
const individualOptions = {
|
|
2383
|
-
key: fullKey,
|
|
2384
|
-
class: options.class
|
|
2385
|
-
};
|
|
2386
|
-
if (options.effects)
|
|
2387
|
-
individualOptions.effects = options.effects(key);
|
|
2388
|
-
return createMutableAtom(target, individualOptions, family);
|
|
2389
|
-
};
|
|
2390
|
-
const atomFamily$1 = {
|
|
2391
|
-
...familyToken,
|
|
2392
|
-
create,
|
|
2393
|
-
class: options.class,
|
|
2394
|
-
subject,
|
|
2395
|
-
install: (s) => createMutableAtomFamily(s, options),
|
|
2396
|
-
internalRoles
|
|
2397
|
-
};
|
|
2398
|
-
store.families.set(options.key, atomFamily$1);
|
|
2399
|
-
createWritablePureSelectorFamily(store, {
|
|
2400
|
-
key: `${options.key}:JSON`,
|
|
2401
|
-
get: (key) => ({ get }) => get(familyToken, key).toJSON(),
|
|
2402
|
-
set: (key) => ({ set }, newValue) => {
|
|
2403
|
-
set(familyToken, key, options.class.fromJSON(newValue));
|
|
2404
|
-
}
|
|
2405
|
-
}, [`mutable`, `json`]);
|
|
2406
|
-
new FamilyTracker(atomFamily$1, store);
|
|
2407
|
-
return familyToken;
|
|
2408
|
-
}
|
|
2409
|
-
var getJsonFamily = (mutableAtomFamily, store) => {
|
|
2410
|
-
const target = newest(store);
|
|
2411
|
-
const key = `${mutableAtomFamily.key}:JSON`;
|
|
2412
|
-
return target.families.get(key);
|
|
2413
|
-
};
|
|
2414
|
-
var getJsonToken = (store, mutableAtomToken) => {
|
|
2415
|
-
if (mutableAtomToken.family)
|
|
2416
|
-
return findInStore(store, withdraw(newest(store), {
|
|
2417
|
-
key: `${mutableAtomToken.family.key}:JSON`,
|
|
2418
|
-
type: `writable_pure_selector_family`
|
|
2419
|
-
}), parseJson(mutableAtomToken.family.subKey));
|
|
2420
|
-
return {
|
|
2421
|
-
type: `writable_pure_selector`,
|
|
2422
|
-
key: `${mutableAtomToken.key}:JSON`
|
|
2423
|
-
};
|
|
2424
|
-
};
|
|
2425
|
-
var getUpdateToken = (mutableAtomToken) => {
|
|
2426
|
-
const updateToken = {
|
|
2427
|
-
type: `atom`,
|
|
2428
|
-
key: `*${mutableAtomToken.key}`
|
|
2429
|
-
};
|
|
2430
|
-
if (mutableAtomToken.family)
|
|
2431
|
-
updateToken.family = {
|
|
2432
|
-
key: `*${mutableAtomToken.family.key}`,
|
|
2433
|
-
subKey: mutableAtomToken.family.subKey
|
|
2434
|
-
};
|
|
2435
|
-
return updateToken;
|
|
2436
|
-
};
|
|
2437
|
-
function isTransceiver(value) {
|
|
2438
|
-
return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value && `READONLY_VIEW` in value && `toJSON` in value;
|
|
2439
|
-
}
|
|
2440
|
-
function writeToCache(target, state, value) {
|
|
2441
|
-
const { key, subject, type } = state;
|
|
2442
|
-
const currentValue = target.valueMap.get(key);
|
|
2443
|
-
if (currentValue instanceof Future && !currentValue.done) {
|
|
2444
|
-
const future = currentValue;
|
|
2445
|
-
if (value instanceof Promise) {
|
|
2446
|
-
future.use(value);
|
|
2447
|
-
return future;
|
|
2448
|
-
}
|
|
2449
|
-
target.valueMap.set(key, value);
|
|
2450
|
-
return value;
|
|
2451
|
-
}
|
|
2452
|
-
if (value instanceof Promise) {
|
|
2453
|
-
const future = new Future(value);
|
|
2454
|
-
target.valueMap.set(key, future);
|
|
2455
|
-
future.then(function handleResolvedFuture(resolved) {
|
|
2456
|
-
if (target.valueMap.get(key) === future) {
|
|
2457
|
-
openOperation(target, state);
|
|
2458
|
-
writeToCache(target, state, resolved);
|
|
2459
|
-
switch (type) {
|
|
2460
|
-
case `atom`:
|
|
2461
|
-
evictDownstreamFromAtom(target, state);
|
|
2462
|
-
break;
|
|
2463
|
-
case `readonly_pure_selector`:
|
|
2464
|
-
case `writable_pure_selector`:
|
|
2465
|
-
evictDownstreamFromSelector(target, key);
|
|
2466
|
-
break;
|
|
2467
|
-
}
|
|
2468
|
-
closeOperation(target);
|
|
2469
|
-
subject.next({
|
|
2470
|
-
newValue: resolved,
|
|
2471
|
-
oldValue: future
|
|
2472
|
-
});
|
|
2473
|
-
}
|
|
2474
|
-
}).catch((thrown) => {
|
|
2475
|
-
target.logger.error(`\uD83D\uDCA5`, state.type, key, `rejected:`, thrown);
|
|
2476
|
-
});
|
|
2477
|
-
return future;
|
|
2478
|
-
}
|
|
2479
|
-
target.logger.info(`\uD83D\uDCDD`, state.type, state.key, `writing to cache`, value);
|
|
2480
|
-
target.valueMap.set(key, value);
|
|
2481
|
-
return value;
|
|
2482
|
-
}
|
|
2483
|
-
function readFromCache(target, state, mut) {
|
|
2484
|
-
target.logger.info(`\uD83D\uDCD6`, state.type, state.key, `reading cached value`);
|
|
2485
|
-
let value = target.valueMap.get(state.key);
|
|
2486
|
-
if (mut === `mut` && state.type === `mutable_atom` && isChildStore(target)) {
|
|
2487
|
-
const mutableAtom$1 = state;
|
|
2488
|
-
const { parent } = target;
|
|
2489
|
-
if (target.valueMap.hasOwn(mutableAtom$1.key))
|
|
2490
|
-
return value;
|
|
2491
|
-
const parentValue = parent.valueMap.get(mutableAtom$1.key);
|
|
2492
|
-
target.logger.info(`\uD83D\uDCC3`, `atom`, mutableAtom$1.key, `copying`);
|
|
2493
|
-
const jsonValue = parentValue.toJSON();
|
|
2494
|
-
const copiedValue = mutableAtom$1.class.fromJSON(jsonValue);
|
|
2495
|
-
target.valueMap.set(mutableAtom$1.key, copiedValue);
|
|
2496
|
-
new Tracker(mutableAtom$1, parent);
|
|
2497
|
-
value = copiedValue;
|
|
2498
|
-
}
|
|
2499
|
-
return value;
|
|
2500
|
-
}
|
|
2501
|
-
function evictCachedValue(target, key) {
|
|
2502
|
-
const currentValue = target.valueMap.get(key);
|
|
2503
|
-
if (currentValue instanceof Future)
|
|
2504
|
-
return;
|
|
2505
|
-
if (target.operation.open)
|
|
2506
|
-
target.operation.prev.set(key, currentValue);
|
|
2507
|
-
target.valueMap.delete(key);
|
|
2508
|
-
target.logger.info(`\uD83D\uDDD1`, `state`, key, `evicted`);
|
|
2509
|
-
}
|
|
2510
|
-
function evictDownstreamFromAtom(store, atom$1) {
|
|
2511
|
-
const target = newest(store);
|
|
2512
|
-
const { key, type } = atom$1;
|
|
2513
|
-
const downstreamKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
2514
|
-
target.logger.info(`\uD83E\uDDF9`, type, key, downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`, downstreamKeys ?? `to evict`);
|
|
2515
|
-
if (downstreamKeys) {
|
|
2516
|
-
if (target.operation.open)
|
|
2517
|
-
target.logger.info(`\uD83E\uDDF9`, type, key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
|
|
2518
|
-
for (const downstreamKey of downstreamKeys) {
|
|
2519
|
-
if (isDone(target, downstreamKey))
|
|
2520
|
-
continue;
|
|
2521
|
-
evictCachedValue(target, downstreamKey);
|
|
2522
|
-
markDone(target, downstreamKey);
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
}
|
|
2526
|
-
function evictDownstreamFromSelector(store, selectorKey) {
|
|
2527
|
-
const target = newest(store);
|
|
2528
|
-
const relationEntries = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: selectorKey }).filter(([_, { source }]) => source === selectorKey);
|
|
2529
|
-
for (const [downstreamSelectorKey] of relationEntries) {
|
|
2530
|
-
if (isDone(target, downstreamSelectorKey))
|
|
2531
|
-
continue;
|
|
2532
|
-
evictCachedValue(target, downstreamSelectorKey);
|
|
2533
|
-
markDone(target, downstreamSelectorKey);
|
|
2534
|
-
evictDownstreamFromSelector(store, downstreamSelectorKey);
|
|
2535
|
-
}
|
|
2536
|
-
}
|
|
2537
|
-
function createRegularAtom(store, options, family, internalRoles) {
|
|
2538
|
-
const type = `atom`;
|
|
2539
|
-
const { key } = options;
|
|
2540
|
-
store.logger.info(`\uD83D\uDD28`, type, key, `is being created`);
|
|
2541
|
-
const target = newest(store);
|
|
2542
|
-
const existing = target.atoms.get(key);
|
|
2543
|
-
if (existing?.type === type && store.config.isProduction === true) {
|
|
2544
|
-
store.logger.error(`\u274C`, `atom`, key, `Tried to create atom, but it already exists in the store.`);
|
|
2545
|
-
return deposit(existing);
|
|
2546
|
-
}
|
|
2547
|
-
const subject = new Subject;
|
|
2548
|
-
const newAtom = {
|
|
2549
|
-
...options,
|
|
2550
|
-
type,
|
|
2551
|
-
install: (s) => {
|
|
2552
|
-
s.logger.info(`\uD83D\uDEE0\uFE0F`, type, key, `installing in store "${s.config.name}"`);
|
|
2553
|
-
return createRegularAtom(s, options, family);
|
|
2554
|
-
},
|
|
2555
|
-
subject
|
|
2556
|
-
};
|
|
2557
|
-
if (family)
|
|
2558
|
-
newAtom.family = family;
|
|
2559
|
-
if (internalRoles)
|
|
2560
|
-
newAtom.internalRoles = internalRoles;
|
|
2561
|
-
target.atoms.set(key, newAtom);
|
|
2562
|
-
const token = deposit(newAtom);
|
|
2563
|
-
if (options.effects) {
|
|
2564
|
-
let effectIndex = 0;
|
|
2565
|
-
const cleanupFunctions = [];
|
|
2566
|
-
for (const effect of options.effects) {
|
|
2567
|
-
const cleanup = effect({
|
|
2568
|
-
resetSelf: () => {
|
|
2569
|
-
resetInStore(store, token);
|
|
2570
|
-
},
|
|
2571
|
-
setSelf: (next) => {
|
|
2572
|
-
setIntoStore(store, token, next);
|
|
2573
|
-
},
|
|
2574
|
-
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle),
|
|
2575
|
-
token,
|
|
2576
|
-
store: eldest(store)
|
|
2577
|
-
});
|
|
2578
|
-
if (cleanup)
|
|
2579
|
-
cleanupFunctions.push(cleanup);
|
|
2580
|
-
++effectIndex;
|
|
2581
|
-
}
|
|
2582
|
-
newAtom.cleanup = () => {
|
|
2583
|
-
for (const cleanup of cleanupFunctions)
|
|
2584
|
-
cleanup();
|
|
2585
|
-
};
|
|
2586
|
-
}
|
|
2587
|
-
store.on.atomCreation.next(token);
|
|
2588
|
-
return token;
|
|
2589
|
-
}
|
|
2590
|
-
function hasRole(atom$1, role) {
|
|
2591
|
-
if (`internalRoles` in atom$1 === false)
|
|
2592
|
-
return false;
|
|
2593
|
-
return atom$1.internalRoles.includes(role);
|
|
2594
|
-
}
|
|
2595
|
-
function capitalize(string) {
|
|
2596
|
-
return string[0].toUpperCase() + string.slice(1);
|
|
2597
|
-
}
|
|
2598
|
-
var Join = class {
|
|
2599
|
-
toolkit;
|
|
2600
|
-
options;
|
|
2601
|
-
relations;
|
|
2602
|
-
states;
|
|
2603
|
-
relatedKeysAtoms;
|
|
2604
|
-
transact(toolkit, run) {
|
|
2605
|
-
const originalToolkit = this.toolkit;
|
|
2606
|
-
this.toolkit = toolkit;
|
|
2607
|
-
run(this);
|
|
2608
|
-
this.toolkit = originalToolkit;
|
|
2609
|
-
}
|
|
2610
|
-
store;
|
|
2611
|
-
[Symbol.dispose]() {}
|
|
2612
|
-
constructor(store, options) {
|
|
2613
|
-
this.store = store;
|
|
2614
|
-
this.options = options;
|
|
2615
|
-
this.store.miscResources.set(`join:${options.key}`, this);
|
|
2616
|
-
this.toolkit = {
|
|
2617
|
-
get: (...ps) => getFromStore(store, ...ps),
|
|
2618
|
-
set: (...ps) => {
|
|
2619
|
-
setIntoStore(store, ...ps);
|
|
2620
|
-
},
|
|
2621
|
-
find: (...ps) => findInStore(store, ...ps),
|
|
2622
|
-
json: (token) => getJsonToken(store, token)
|
|
2623
|
-
};
|
|
2624
|
-
const aSide = options.between[0];
|
|
2625
|
-
const bSide = options.between[1];
|
|
2626
|
-
const relatedKeysAtoms = createMutableAtomFamily(store, {
|
|
2627
|
-
key: `${options.key}/relatedKeys`,
|
|
2628
|
-
class: UList
|
|
2629
|
-
}, [`join`, `relations`]);
|
|
2630
|
-
this.relatedKeysAtoms = relatedKeysAtoms;
|
|
2631
|
-
const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
|
|
2632
|
-
const { find, get, set } = toolkit;
|
|
2633
|
-
const relationsOfAState = find(relatedKeysAtoms, a);
|
|
2634
|
-
const currentRelationsOfA = get(relationsOfAState);
|
|
2635
|
-
for (const currentRelationB of currentRelationsOfA) {
|
|
2636
|
-
if (newRelationsOfA.includes(currentRelationB))
|
|
2637
|
-
continue;
|
|
2638
|
-
set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
|
|
2639
|
-
relationsOfB.delete(a);
|
|
2640
|
-
return relationsOfB;
|
|
2641
|
-
});
|
|
2642
|
-
}
|
|
2643
|
-
set(relationsOfAState, (relationsOfA) => {
|
|
2644
|
-
relationsOfA.clear();
|
|
2645
|
-
for (const newRelationB of newRelationsOfA) {
|
|
2646
|
-
const relationsOfBAtom = find(relatedKeysAtoms, newRelationB);
|
|
2647
|
-
const relationsOfB = get(relationsOfBAtom);
|
|
2648
|
-
const newRelationBIsAlreadyRelated = relationsOfB.has(a);
|
|
2649
|
-
if (this.relations.cardinality === `1:n`) {
|
|
2650
|
-
const previousOwnersToDispose = [];
|
|
2651
|
-
for (const previousOwner of relationsOfB) {
|
|
2652
|
-
if (previousOwner === a)
|
|
2653
|
-
continue;
|
|
2654
|
-
let previousOwnerSize;
|
|
2655
|
-
operateOnStore(JOIN_OP, this.store, relatedKeysAtoms, previousOwner, (relations$1) => {
|
|
2656
|
-
relations$1.delete(newRelationB);
|
|
2657
|
-
previousOwnerSize = relations$1.size;
|
|
2658
|
-
return relations$1;
|
|
2659
|
-
});
|
|
2660
|
-
if (previousOwnerSize === 0)
|
|
2661
|
-
previousOwnersToDispose.push(previousOwner);
|
|
2662
|
-
}
|
|
2663
|
-
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0)
|
|
2664
|
-
set(relationsOfBAtom, (relations$1) => {
|
|
2665
|
-
relations$1.clear();
|
|
2666
|
-
return relations$1;
|
|
2667
|
-
});
|
|
2668
|
-
for (const previousOwner of previousOwnersToDispose)
|
|
2669
|
-
store.keyRefsInJoins.delete(simpleCompound(newRelationB, previousOwner));
|
|
2670
|
-
}
|
|
2671
|
-
if (!newRelationBIsAlreadyRelated)
|
|
2672
|
-
set(relationsOfBAtom, (relations$1) => {
|
|
2673
|
-
relations$1.add(a);
|
|
2674
|
-
return relations$1;
|
|
2675
|
-
});
|
|
2676
|
-
relationsOfA.add(newRelationB);
|
|
2677
|
-
}
|
|
2678
|
-
return relationsOfA;
|
|
2679
|
-
});
|
|
2680
|
-
};
|
|
2681
|
-
const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
|
|
2682
|
-
const { set } = toolkit;
|
|
2683
|
-
set(relatedKeysAtoms, a, (relationsOfA) => {
|
|
2684
|
-
for (const newRelationB of newRelationsOfA)
|
|
2685
|
-
relationsOfA.add(newRelationB);
|
|
2686
|
-
return relationsOfA;
|
|
2687
|
-
});
|
|
2688
|
-
for (const newRelationB of newRelationsOfA)
|
|
2689
|
-
set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
|
|
2690
|
-
newRelationsB.add(a);
|
|
2691
|
-
return newRelationsB;
|
|
2692
|
-
});
|
|
2693
|
-
return true;
|
|
2694
|
-
};
|
|
2695
|
-
const relations = new Junction(options, {
|
|
2696
|
-
externalStore: {
|
|
2697
|
-
getRelatedKeys: (key) => this.toolkit.get(relatedKeysAtoms, key),
|
|
2698
|
-
addRelation: (a, b) => {
|
|
2699
|
-
this.store.keyRefsInJoins.set(`"${a}"`, options.key);
|
|
2700
|
-
this.store.keyRefsInJoins.set(`"${b}"`, options.key);
|
|
2701
|
-
this.store.keyRefsInJoins.set(simpleCompound(a, b), options.key);
|
|
2702
|
-
this.toolkit.set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
|
|
2703
|
-
this.toolkit.set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
|
|
2704
|
-
},
|
|
2705
|
-
deleteRelation: (a, b) => {
|
|
2706
|
-
this.toolkit.set(relatedKeysAtoms, a, (aKeys) => {
|
|
2707
|
-
aKeys.delete(b);
|
|
2708
|
-
return aKeys;
|
|
2709
|
-
});
|
|
2710
|
-
this.toolkit.set(relatedKeysAtoms, b, (bKeys) => {
|
|
2711
|
-
bKeys.delete(a);
|
|
2712
|
-
return bKeys;
|
|
2713
|
-
});
|
|
2714
|
-
const compositeKey = simpleCompound(a, b);
|
|
2715
|
-
this.store.keyRefsInJoins.delete(compositeKey);
|
|
2716
|
-
},
|
|
2717
|
-
replaceRelationsSafely: (a, bs) => {
|
|
2718
|
-
replaceRelationsSafely(this.toolkit, a, bs);
|
|
2719
|
-
},
|
|
2720
|
-
replaceRelationsUnsafely: (a, bs) => {
|
|
2721
|
-
replaceRelationsUnsafely(this.toolkit, a, bs);
|
|
2722
|
-
},
|
|
2723
|
-
has: (a, b) => {
|
|
2724
|
-
const aKeys = this.toolkit.get(relatedKeysAtoms, a);
|
|
2725
|
-
return b ? aKeys.has(b) : aKeys.size > 0;
|
|
2726
|
-
}
|
|
2727
|
-
},
|
|
2728
|
-
isAType: options.isAType,
|
|
2729
|
-
isBType: options.isBType
|
|
2730
|
-
});
|
|
2731
|
-
const createSingleKeySelectorFamily = () => createReadonlyPureSelectorFamily(store, {
|
|
2732
|
-
key: `${options.key}/singleRelatedKey`,
|
|
2733
|
-
get: (key) => ({ get }) => {
|
|
2734
|
-
const relatedKeys = get(relatedKeysAtoms, key);
|
|
2735
|
-
for (const relatedKey of relatedKeys)
|
|
2736
|
-
return relatedKey;
|
|
2737
|
-
return null;
|
|
2738
|
-
}
|
|
2739
|
-
}, [`join`, `keys`]);
|
|
2740
|
-
const getMultipleKeySelectorFamily = () => {
|
|
2741
|
-
return createReadonlyPureSelectorFamily(store, {
|
|
2742
|
-
key: `${options.key}/multipleRelatedKeys`,
|
|
2743
|
-
get: (key) => ({ get }) => {
|
|
2744
|
-
return get(getJsonFamily(relatedKeysAtoms, store), key);
|
|
2745
|
-
}
|
|
2746
|
-
}, [`join`, `keys`]);
|
|
2747
|
-
};
|
|
2748
|
-
switch (options.cardinality) {
|
|
2749
|
-
case `1:1`: {
|
|
2750
|
-
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
2751
|
-
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
2752
|
-
const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
|
|
2753
|
-
this.relations = relations;
|
|
2754
|
-
this.states = {
|
|
2755
|
-
[stateKeyA]: singleRelatedKeySelectors,
|
|
2756
|
-
[stateKeyB]: singleRelatedKeySelectors
|
|
2757
|
-
};
|
|
2758
|
-
break;
|
|
2759
|
-
}
|
|
2760
|
-
case `1:n`: {
|
|
2761
|
-
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
2762
|
-
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
2763
|
-
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
2764
|
-
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
2765
|
-
const baseStates = {
|
|
2766
|
-
[stateKeyA]: singleRelatedKeySelectors,
|
|
2767
|
-
[stateKeyB]: multipleRelatedKeysSelectors
|
|
2768
|
-
};
|
|
2769
|
-
this.relations = relations;
|
|
2770
|
-
this.states = baseStates;
|
|
2771
|
-
break;
|
|
2772
|
-
}
|
|
2773
|
-
case `n:n`: {
|
|
2774
|
-
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
2775
|
-
const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
|
|
2776
|
-
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
2777
|
-
this.relations = relations;
|
|
2778
|
-
this.states = {
|
|
2779
|
-
[stateKeyA]: multipleRelatedKeysSelectors,
|
|
2780
|
-
[stateKeyB]: multipleRelatedKeysSelectors
|
|
2781
|
-
};
|
|
2782
|
-
}
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
};
|
|
2786
|
-
function createJoin(store, options) {
|
|
2787
|
-
store.joins.set(options.key, new Join(store, options));
|
|
2788
|
-
return {
|
|
2789
|
-
key: options.key,
|
|
2790
|
-
type: `join`,
|
|
2791
|
-
a: options.between[0],
|
|
2792
|
-
b: options.between[1],
|
|
2793
|
-
cardinality: options.cardinality
|
|
2794
|
-
};
|
|
2795
|
-
}
|
|
2796
|
-
function getJoin(store, token) {
|
|
2797
|
-
let myJoin = store.joins.get(token.key);
|
|
2798
|
-
if (myJoin === undefined) {
|
|
2799
|
-
const rootJoin = IMPLICIT.STORE.joins.get(token.key);
|
|
2800
|
-
if (rootJoin === undefined)
|
|
2801
|
-
throw new Error(`Join "${token.key}" not found in store "${store.config.name}"`);
|
|
2802
|
-
myJoin = new Join(eldest(store), rootJoin.options);
|
|
2803
|
-
store.joins.set(token.key, myJoin);
|
|
2804
|
-
}
|
|
2805
|
-
return myJoin;
|
|
2806
|
-
}
|
|
2807
|
-
function editRelationsInStore(store, token, change) {
|
|
2808
|
-
const myJoin = getJoin(store, token);
|
|
2809
|
-
const target = newest(store);
|
|
2810
|
-
if (isChildStore(target)) {
|
|
2811
|
-
const { toolkit } = target.transactionMeta;
|
|
2812
|
-
myJoin.transact(toolkit, ({ relations }) => {
|
|
2813
|
-
change(relations);
|
|
2814
|
-
});
|
|
2815
|
-
} else
|
|
2816
|
-
change(myJoin.relations);
|
|
2817
|
-
}
|
|
2818
|
-
function findRelationsInStore(store, token, key) {
|
|
2819
|
-
const myJoin = getJoin(store, token);
|
|
2820
|
-
let relations;
|
|
2821
|
-
switch (token.cardinality) {
|
|
2822
|
-
case `1:1`: {
|
|
2823
|
-
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
2824
|
-
const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
|
|
2825
|
-
relations = {
|
|
2826
|
-
get [keyAB]() {
|
|
2827
|
-
const familyAB = myJoin.states[keyAB];
|
|
2828
|
-
return findInStore(store, familyAB, key);
|
|
2829
|
-
},
|
|
2830
|
-
get [keyBA]() {
|
|
2831
|
-
const familyBA = myJoin.states[keyBA];
|
|
2832
|
-
return findInStore(store, familyBA, key);
|
|
2833
|
-
}
|
|
2834
|
-
};
|
|
2835
|
-
break;
|
|
2836
|
-
}
|
|
2837
|
-
case `1:n`: {
|
|
2838
|
-
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
2839
|
-
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
2840
|
-
relations = {
|
|
2841
|
-
get [keyAB]() {
|
|
2842
|
-
const familyAB = myJoin.states[keyAB];
|
|
2843
|
-
return findInStore(store, familyAB, key);
|
|
2844
|
-
},
|
|
2845
|
-
get [keysBA]() {
|
|
2846
|
-
const familyBA = myJoin.states[keysBA];
|
|
2847
|
-
return findInStore(store, familyBA, key);
|
|
2848
|
-
}
|
|
2849
|
-
};
|
|
2850
|
-
break;
|
|
2851
|
-
}
|
|
2852
|
-
case `n:n`: {
|
|
2853
|
-
const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
|
|
2854
|
-
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
2855
|
-
relations = {
|
|
2856
|
-
get [keysAB]() {
|
|
2857
|
-
const familyAB = myJoin.states[keysAB];
|
|
2858
|
-
return findInStore(store, familyAB, key);
|
|
2859
|
-
},
|
|
2860
|
-
get [keysBA]() {
|
|
2861
|
-
const familyBA = myJoin.states[keysBA];
|
|
2862
|
-
return findInStore(store, familyBA, key);
|
|
2863
|
-
}
|
|
2864
|
-
};
|
|
2865
|
-
}
|
|
2866
|
-
}
|
|
2867
|
-
return relations;
|
|
2868
|
-
}
|
|
2869
|
-
function getInternalRelationsFromStore(store, token, split) {
|
|
2870
|
-
const myJoin = getJoin(store, token);
|
|
2871
|
-
if (split === `split`)
|
|
2872
|
-
return [myJoin.relatedKeysAtoms, myJoin.relatedKeysAtoms];
|
|
2873
|
-
return myJoin.relatedKeysAtoms;
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
|
-
// ../../packages/atom.io/dist/realtime/index.js
|
|
2877
|
-
var mutexAtoms = atomFamily({
|
|
2878
|
-
key: `mutex`,
|
|
2879
|
-
default: false
|
|
2880
|
-
});
|
|
2881
|
-
var InvariantMap = class extends Map {
|
|
2882
|
-
set(key, value) {
|
|
2883
|
-
if (this.has(key)) {
|
|
2884
|
-
console.warn(`Tried to set a key that already exists in an InvariantMap`, {
|
|
2885
|
-
key,
|
|
2886
|
-
value
|
|
2887
|
-
});
|
|
2888
|
-
return this;
|
|
2889
|
-
}
|
|
2890
|
-
return super.set(key, value);
|
|
2891
|
-
}
|
|
2892
|
-
};
|
|
2893
|
-
var SyncGroup = class SyncGroup2 {
|
|
2894
|
-
type = `continuity`;
|
|
2895
|
-
globals = [];
|
|
2896
|
-
actions = [];
|
|
2897
|
-
perspectives = [];
|
|
2898
|
-
key;
|
|
2899
|
-
constructor(key) {
|
|
2900
|
-
this.key = key;
|
|
2901
|
-
}
|
|
2902
|
-
static existing = new InvariantMap;
|
|
2903
|
-
static create(key, builder) {
|
|
2904
|
-
const { type, globals, actions, perspectives } = builder(new SyncGroup2(key));
|
|
2905
|
-
const token = {
|
|
2906
|
-
type,
|
|
2907
|
-
key,
|
|
2908
|
-
globals,
|
|
2909
|
-
actions,
|
|
2910
|
-
perspectives
|
|
2911
|
-
};
|
|
2912
|
-
SyncGroup2.existing.set(key, token);
|
|
2913
|
-
return token;
|
|
2914
|
-
}
|
|
2915
|
-
add(...args) {
|
|
2916
|
-
switch (args[0].type) {
|
|
2917
|
-
case `atom`:
|
|
2918
|
-
case `mutable_atom`:
|
|
2919
|
-
this.globals.push(...args);
|
|
2920
|
-
break;
|
|
2921
|
-
case `transaction`:
|
|
2922
|
-
this.actions.push(...args);
|
|
2923
|
-
break;
|
|
2924
|
-
case `atom_family`:
|
|
2925
|
-
case `mutable_atom_family`:
|
|
2926
|
-
{
|
|
2927
|
-
const [family, index] = args;
|
|
2928
|
-
this.perspectives.push({
|
|
2929
|
-
type: `realtime_perspective`,
|
|
2930
|
-
resourceAtoms: family,
|
|
2931
|
-
viewAtoms: index
|
|
2932
|
-
});
|
|
2933
|
-
}
|
|
2934
|
-
break;
|
|
2935
|
-
}
|
|
2936
|
-
return this;
|
|
2937
|
-
}
|
|
2938
|
-
};
|
|
2939
|
-
var isSocketKey = (key) => key.startsWith(`socket::`);
|
|
2940
|
-
var isUserKey = (key) => key.startsWith(`user::`);
|
|
2941
|
-
var isRoomKey = (key) => key.startsWith(`room::`);
|
|
2942
|
-
var roomKeysAtom = mutableAtom({
|
|
2943
|
-
key: `roomKeys`,
|
|
2944
|
-
class: UList
|
|
2945
|
-
});
|
|
2946
|
-
var usersInRooms = join({
|
|
2947
|
-
key: `usersInRooms`,
|
|
2948
|
-
between: [`room`, `user`],
|
|
2949
|
-
cardinality: `1:n`,
|
|
2950
|
-
isAType: isRoomKey,
|
|
2951
|
-
isBType: isUserKey
|
|
2952
|
-
});
|
|
2953
|
-
var visibleUsersInRoomsSelector = selectorFamily({
|
|
2954
|
-
key: `visibleUsersInRooms`,
|
|
2955
|
-
get: (userKey) => ({ get }) => {
|
|
2956
|
-
const [, roomsOfUsersAtoms] = getInternalRelations(usersInRooms, `split`);
|
|
2957
|
-
return [userKey, ...get(roomsOfUsersAtoms, userKey)];
|
|
2958
|
-
}
|
|
2959
|
-
});
|
|
2960
|
-
var visibilityFromRoomSelector = selectorFamily({
|
|
2961
|
-
key: `visibilityFromRoom`,
|
|
2962
|
-
get: (roomKey) => ({ get }) => {
|
|
2963
|
-
const [usersOfRoomsAtoms] = getInternalRelations(usersInRooms, `split`);
|
|
2964
|
-
return [roomKey, ...get(usersOfRoomsAtoms, roomKey)];
|
|
2965
|
-
}
|
|
2966
|
-
});
|
|
2967
|
-
var mutualUsersSelector = selectorFamily({
|
|
2968
|
-
key: `mutualUsers`,
|
|
2969
|
-
get: (userKey) => ({ get }) => {
|
|
2970
|
-
const [usersOfRoomsAtoms, roomsOfUsersAtoms] = getInternalRelations(usersInRooms, `split`);
|
|
2971
|
-
const rooms = get(roomsOfUsersAtoms, userKey);
|
|
2972
|
-
for (const room of rooms)
|
|
2973
|
-
return [...get(usersOfRoomsAtoms, room)];
|
|
2974
|
-
return [userKey];
|
|
2975
|
-
}
|
|
2976
|
-
});
|
|
2977
|
-
var ownersOfRooms = join({
|
|
2978
|
-
key: `ownersOfRooms`,
|
|
2979
|
-
between: [`user`, `room`],
|
|
2980
|
-
cardinality: `1:n`,
|
|
2981
|
-
isAType: isUserKey,
|
|
2982
|
-
isBType: isRoomKey
|
|
2983
|
-
});
|
|
2984
|
-
|
|
2985
|
-
// ../../packages/atom.io/dist/realtime-server/index.js
|
|
2986
|
-
var redactorAtoms = atomFamily({
|
|
2987
|
-
key: `redactor`,
|
|
2988
|
-
default: { occlude: (updates) => updates }
|
|
2989
|
-
});
|
|
2990
|
-
var unacknowledgedUpdatesAtoms = atomFamily({
|
|
2991
|
-
key: `unacknowledgedUpdates`,
|
|
2992
|
-
default: () => []
|
|
2993
|
-
});
|
|
2994
|
-
var CustomSocket = class {
|
|
2995
|
-
listeners;
|
|
2996
|
-
globalListeners;
|
|
2997
|
-
globalListenersOutgoing;
|
|
2998
|
-
handleEvent(...args) {
|
|
2999
|
-
const [event, ...rest] = args;
|
|
3000
|
-
for (const listener of this.globalListeners)
|
|
3001
|
-
listener(event, ...rest);
|
|
3002
|
-
const listeners = this.listeners.get(event);
|
|
3003
|
-
if (listeners)
|
|
3004
|
-
for (const listener of listeners)
|
|
3005
|
-
listener(...rest);
|
|
3006
|
-
}
|
|
3007
|
-
id = `no_id_retrieved`;
|
|
3008
|
-
emit;
|
|
3009
|
-
constructor(emit) {
|
|
3010
|
-
this.emit = (...args) => {
|
|
3011
|
-
for (const listener of this.globalListenersOutgoing)
|
|
3012
|
-
listener(...args);
|
|
3013
|
-
return emit(...args);
|
|
3014
|
-
};
|
|
3015
|
-
this.listeners = /* @__PURE__ */ new Map;
|
|
3016
|
-
this.globalListeners = /* @__PURE__ */ new Set;
|
|
3017
|
-
this.globalListenersOutgoing = /* @__PURE__ */ new Set;
|
|
3018
|
-
}
|
|
3019
|
-
on(event, listener) {
|
|
3020
|
-
const listeners = this.listeners.get(event);
|
|
3021
|
-
if (listeners)
|
|
3022
|
-
listeners.add(listener);
|
|
3023
|
-
else
|
|
3024
|
-
this.listeners.set(event, new Set([listener]));
|
|
3025
|
-
return this;
|
|
3026
|
-
}
|
|
3027
|
-
onAny(listener) {
|
|
3028
|
-
this.globalListeners.add(listener);
|
|
3029
|
-
return this;
|
|
3030
|
-
}
|
|
3031
|
-
onAnyOutgoing(listener) {
|
|
3032
|
-
this.globalListenersOutgoing.add(listener);
|
|
3033
|
-
return this;
|
|
3034
|
-
}
|
|
3035
|
-
off(event, listener) {
|
|
3036
|
-
const listeners = this.listeners.get(event);
|
|
3037
|
-
if (listeners)
|
|
3038
|
-
if (listener)
|
|
3039
|
-
listeners.delete(listener);
|
|
3040
|
-
else
|
|
3041
|
-
this.listeners.delete(event);
|
|
3042
|
-
return this;
|
|
3043
|
-
}
|
|
3044
|
-
offAny(listener) {
|
|
3045
|
-
this.globalListeners.delete(listener);
|
|
3046
|
-
return this;
|
|
3047
|
-
}
|
|
3048
|
-
};
|
|
3049
|
-
var PROOF_OF_LIFE_SIGNAL = `ALIVE`;
|
|
3050
|
-
var SubjectSocket = class extends CustomSocket {
|
|
3051
|
-
in;
|
|
3052
|
-
out;
|
|
3053
|
-
id = `no_id_retrieved`;
|
|
3054
|
-
disposalEffects = [];
|
|
3055
|
-
constructor(id) {
|
|
3056
|
-
super((...args) => {
|
|
3057
|
-
this.out.next(args);
|
|
3058
|
-
return this;
|
|
3059
|
-
});
|
|
3060
|
-
this.id = id;
|
|
3061
|
-
this.in = new Subject;
|
|
3062
|
-
this.out = new Subject;
|
|
3063
|
-
this.in.subscribe(`socket`, (event) => {
|
|
3064
|
-
this.handleEvent(...event);
|
|
3065
|
-
});
|
|
3066
|
-
}
|
|
3067
|
-
dispose() {
|
|
3068
|
-
for (const dispose of this.disposalEffects)
|
|
3069
|
-
dispose();
|
|
3070
|
-
}
|
|
3071
|
-
};
|
|
3072
|
-
var ParentSocket = class extends CustomSocket {
|
|
3073
|
-
incompleteData = ``;
|
|
3074
|
-
unprocessedEvents = [];
|
|
3075
|
-
relays;
|
|
3076
|
-
initRelay;
|
|
3077
|
-
proc;
|
|
3078
|
-
id = `#####`;
|
|
3079
|
-
log(...args) {
|
|
3080
|
-
this.proc.stderr.write(stringifyJson(args.map((arg) => arg instanceof UList ? `{ ${arg.toJSON().join(` | `)} }` : arg)) + `\x03`);
|
|
3081
|
-
}
|
|
3082
|
-
logger = {
|
|
3083
|
-
info: (...args) => {
|
|
3084
|
-
this.log(`i`, ...args);
|
|
3085
|
-
},
|
|
3086
|
-
warn: (...args) => {
|
|
3087
|
-
this.log(`w`, ...args);
|
|
3088
|
-
},
|
|
3089
|
-
error: (...args) => {
|
|
3090
|
-
this.log(`e`, ...args);
|
|
3091
|
-
}
|
|
3092
|
-
};
|
|
3093
|
-
constructor(proc) {
|
|
3094
|
-
super((event, ...args) => {
|
|
3095
|
-
const stringifiedEvent = JSON.stringify([event, ...args]);
|
|
3096
|
-
this.proc.stdout.write(stringifiedEvent + `\x03`);
|
|
3097
|
-
return this;
|
|
3098
|
-
});
|
|
3099
|
-
this.proc = proc;
|
|
3100
|
-
this.proc.stdin.resume();
|
|
3101
|
-
this.relays = /* @__PURE__ */ new Map;
|
|
3102
|
-
this.initRelay = () => {
|
|
3103
|
-
this.logger.info(`\uD83D\uDD17`, `nothing to relay`);
|
|
3104
|
-
};
|
|
3105
|
-
this.proc.stdin.on(`data`, (buffer) => {
|
|
3106
|
-
const pieces = buffer.toString().split(`\x03`);
|
|
3107
|
-
const initialMaybeWellFormed = pieces[0];
|
|
3108
|
-
pieces[0] = this.incompleteData + initialMaybeWellFormed;
|
|
3109
|
-
let idx = 0;
|
|
3110
|
-
for (const piece of pieces) {
|
|
3111
|
-
if (piece === ``)
|
|
3112
|
-
continue;
|
|
3113
|
-
try {
|
|
3114
|
-
const jsonPiece = parseJson(piece);
|
|
3115
|
-
this.logger.info(`\uD83C\uDFB0`, `received`, jsonPiece);
|
|
3116
|
-
this.handleEvent(...jsonPiece);
|
|
3117
|
-
this.incompleteData = ``;
|
|
3118
|
-
} catch (thrown0) {
|
|
3119
|
-
if (thrown0 instanceof Error)
|
|
3120
|
-
this.logger.error([
|
|
3121
|
-
`received malformed data from parent process:`,
|
|
3122
|
-
``,
|
|
3123
|
-
piece,
|
|
3124
|
-
``,
|
|
3125
|
-
thrown0.message
|
|
3126
|
-
].join(`
|
|
3127
|
-
\u274C `));
|
|
3128
|
-
try {
|
|
3129
|
-
if (idx === 0) {
|
|
3130
|
-
this.incompleteData = piece;
|
|
3131
|
-
const maybeActualJsonPiece = parseJson(initialMaybeWellFormed);
|
|
3132
|
-
this.logger.info(`\uD83C\uDFB0`, `received`, maybeActualJsonPiece);
|
|
3133
|
-
this.handleEvent(...maybeActualJsonPiece);
|
|
3134
|
-
this.incompleteData = ``;
|
|
3135
|
-
} else
|
|
3136
|
-
this.incompleteData += piece;
|
|
3137
|
-
} catch (thrown1) {
|
|
3138
|
-
if (thrown1 instanceof Error)
|
|
3139
|
-
this.logger.error([
|
|
3140
|
-
`received malformed data from parent process:`,
|
|
3141
|
-
``,
|
|
3142
|
-
initialMaybeWellFormed,
|
|
3143
|
-
``,
|
|
3144
|
-
thrown1.message
|
|
3145
|
-
].join(`
|
|
3146
|
-
\u274C `));
|
|
3147
|
-
}
|
|
3148
|
-
}
|
|
3149
|
-
++idx;
|
|
3150
|
-
}
|
|
3151
|
-
});
|
|
3152
|
-
this.on(`exit`, () => {
|
|
3153
|
-
this.logger.info(`\uD83D\uDD25`, this.id, `received "exit"`);
|
|
3154
|
-
this.proc.exit(0);
|
|
3155
|
-
});
|
|
3156
|
-
if (this.proc.pid)
|
|
3157
|
-
this.id = this.proc.pid?.toString();
|
|
3158
|
-
this.on(`user-joins`, (userKey) => {
|
|
3159
|
-
this.logger.info(`\uD83D\uDC64`, userKey, `joined`);
|
|
3160
|
-
const existingRelay = this.relays.get(userKey);
|
|
3161
|
-
if (existingRelay) {
|
|
3162
|
-
this.logger.info(`\uD83D\uDD17`, `reattaching relay services for`, userKey);
|
|
3163
|
-
const cleanupRelay$1 = this.initRelay(existingRelay, userKey);
|
|
3164
|
-
if (cleanupRelay$1)
|
|
3165
|
-
existingRelay.disposalEffects.push(cleanupRelay$1);
|
|
3166
|
-
this.on(userKey, (...data) => {
|
|
3167
|
-
relay.in.next(data);
|
|
3168
|
-
});
|
|
3169
|
-
existingRelay.disposalEffects.push(existingRelay.out.subscribe(`socket`, (data) => {
|
|
3170
|
-
this.emit(userKey, ...data);
|
|
3171
|
-
}));
|
|
3172
|
-
return;
|
|
3173
|
-
}
|
|
3174
|
-
const relay = new SubjectSocket(userKey);
|
|
3175
|
-
this.relays.set(userKey, relay);
|
|
3176
|
-
this.logger.info(`\uD83D\uDD17`, `attaching relay services for`, userKey);
|
|
3177
|
-
const cleanupRelay = this.initRelay(relay, userKey);
|
|
3178
|
-
if (cleanupRelay)
|
|
3179
|
-
relay.disposalEffects.push(cleanupRelay);
|
|
3180
|
-
this.on(userKey, (...data) => {
|
|
3181
|
-
relay.in.next(data);
|
|
3182
|
-
});
|
|
3183
|
-
relay.disposalEffects.push(relay.out.subscribe(`socket`, (data) => {
|
|
3184
|
-
this.emit(userKey, ...data);
|
|
3185
|
-
}));
|
|
3186
|
-
});
|
|
3187
|
-
this.on(`user-leaves`, (userKey) => {
|
|
3188
|
-
const relay = this.relays.get(userKey);
|
|
3189
|
-
this.off(userKey);
|
|
3190
|
-
if (relay) {
|
|
3191
|
-
relay.dispose();
|
|
3192
|
-
this.relays.delete(userKey);
|
|
3193
|
-
}
|
|
3194
|
-
});
|
|
3195
|
-
this.proc.stdout.write(PROOF_OF_LIFE_SIGNAL);
|
|
3196
|
-
}
|
|
3197
|
-
receiveRelay(attachServices) {
|
|
3198
|
-
this.initRelay = attachServices;
|
|
3199
|
-
this.logger.info(`\uD83D\uDD17`, `ready to relay`);
|
|
3200
|
-
}
|
|
3201
|
-
};
|
|
3202
|
-
var ChildSocket = class extends CustomSocket {
|
|
3203
|
-
incompleteData = ``;
|
|
3204
|
-
unprocessedEvents = [];
|
|
3205
|
-
incompleteLog = ``;
|
|
3206
|
-
unprocessedLogs = [];
|
|
3207
|
-
id = `#####`;
|
|
3208
|
-
proc;
|
|
3209
|
-
key;
|
|
3210
|
-
logger;
|
|
3211
|
-
handleLog(log) {
|
|
3212
|
-
if (Array.isArray(log)) {
|
|
3213
|
-
const [level, ...rest] = log;
|
|
3214
|
-
switch (level) {
|
|
3215
|
-
case `i`:
|
|
3216
|
-
this.logger.info(...rest);
|
|
3217
|
-
break;
|
|
3218
|
-
case `w`:
|
|
3219
|
-
this.logger.warn(...rest);
|
|
3220
|
-
break;
|
|
3221
|
-
case `e`:
|
|
3222
|
-
this.logger.error(...rest);
|
|
3223
|
-
break;
|
|
3224
|
-
}
|
|
3225
|
-
}
|
|
3226
|
-
}
|
|
3227
|
-
constructor(proc, key, logger) {
|
|
3228
|
-
super((event, ...args) => {
|
|
3229
|
-
const stringifiedEvent = JSON.stringify([event, ...args]) + `\x03`;
|
|
3230
|
-
this.proc.stdin.write(stringifiedEvent);
|
|
3231
|
-
return this;
|
|
3232
|
-
});
|
|
3233
|
-
this.proc = proc;
|
|
3234
|
-
this.key = key;
|
|
3235
|
-
this.logger = logger ?? {
|
|
3236
|
-
info: (...args) => {
|
|
3237
|
-
console.info(this.id, this.key, ...args);
|
|
3238
|
-
},
|
|
3239
|
-
warn: (...args) => {
|
|
3240
|
-
console.warn(this.id, this.key, ...args);
|
|
3241
|
-
},
|
|
3242
|
-
error: (...args) => {
|
|
3243
|
-
console.error(this.id, this.key, ...args);
|
|
3244
|
-
}
|
|
3245
|
-
};
|
|
3246
|
-
this.proc.stdout.on(`data`, (buffer) => {
|
|
3247
|
-
if (buffer[0] === 27 && buffer[1] === 91 && buffer[2] === 50) {
|
|
3248
|
-
this.logger.info(`STDOUT TERMINAL CLEAR`, buffer);
|
|
3249
|
-
return;
|
|
3250
|
-
}
|
|
3251
|
-
const chunk = buffer.toString();
|
|
3252
|
-
if (chunk === PROOF_OF_LIFE_SIGNAL)
|
|
3253
|
-
return;
|
|
3254
|
-
const pieces = chunk.split(`\x03`);
|
|
3255
|
-
const initialMaybeWellFormed = pieces[0];
|
|
3256
|
-
pieces[0] = this.incompleteData + initialMaybeWellFormed;
|
|
3257
|
-
let idx = 0;
|
|
3258
|
-
for (const piece of pieces) {
|
|
3259
|
-
if (piece === ``)
|
|
3260
|
-
continue;
|
|
3261
|
-
try {
|
|
3262
|
-
const jsonPiece = parseJson(piece);
|
|
3263
|
-
this.logger.info(`\uD83D\uDCB8`, `emitted`, jsonPiece);
|
|
3264
|
-
this.handleEvent(...jsonPiece);
|
|
3265
|
-
this.incompleteData = ``;
|
|
3266
|
-
} catch (thrown0) {
|
|
3267
|
-
if (thrown0 instanceof Error)
|
|
3268
|
-
console.error([
|
|
3269
|
-
`\u274C Malformed data received from child process:`,
|
|
3270
|
-
``,
|
|
3271
|
-
...piece.split(`
|
|
3272
|
-
`),
|
|
3273
|
-
``,
|
|
3274
|
-
thrown0.message
|
|
3275
|
-
].join(`
|
|
3276
|
-
\u274C `) + `
|
|
3277
|
-
`);
|
|
3278
|
-
try {
|
|
3279
|
-
if (idx === 0) {
|
|
3280
|
-
this.incompleteData = piece;
|
|
3281
|
-
const maybeActualJsonPiece = parseJson(initialMaybeWellFormed);
|
|
3282
|
-
this.logger.info(`\uD83D\uDCB8`, `emitted`, maybeActualJsonPiece);
|
|
3283
|
-
this.handleEvent(...maybeActualJsonPiece);
|
|
3284
|
-
this.incompleteData = ``;
|
|
3285
|
-
} else
|
|
3286
|
-
this.incompleteData += piece;
|
|
3287
|
-
} catch (thrown1) {
|
|
3288
|
-
if (thrown1 instanceof Error)
|
|
3289
|
-
console.error([
|
|
3290
|
-
`\u274C Malformed data received from child process:`,
|
|
3291
|
-
``,
|
|
3292
|
-
...initialMaybeWellFormed.split(`
|
|
3293
|
-
`),
|
|
3294
|
-
``,
|
|
3295
|
-
thrown1.message
|
|
3296
|
-
].join(`
|
|
3297
|
-
\u274C `) + `
|
|
3298
|
-
`);
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
++idx;
|
|
3302
|
-
}
|
|
3303
|
-
});
|
|
3304
|
-
this.proc.stderr.on(`data`, (buffer) => {
|
|
3305
|
-
if (buffer[0] === 27 && buffer[1] === 91 && buffer[2] === 50) {
|
|
3306
|
-
this.logger.info(`STDERR TERMINAL CLEAR`, buffer);
|
|
3307
|
-
return;
|
|
3308
|
-
}
|
|
3309
|
-
const pieces = buffer.toString().split(`\x03`);
|
|
3310
|
-
const initialMaybeWellFormed = pieces[0];
|
|
3311
|
-
pieces[0] = this.incompleteData + initialMaybeWellFormed;
|
|
3312
|
-
let idx = 0;
|
|
3313
|
-
for (const piece of pieces) {
|
|
3314
|
-
if (piece === ``)
|
|
3315
|
-
continue;
|
|
3316
|
-
try {
|
|
3317
|
-
const jsonPiece = parseJson(piece);
|
|
3318
|
-
this.handleLog(jsonPiece);
|
|
3319
|
-
this.incompleteData = ``;
|
|
3320
|
-
} catch (thrown0) {
|
|
3321
|
-
if (thrown0 instanceof Error)
|
|
3322
|
-
this.logger.error([
|
|
3323
|
-
`\u274C Malformed log received from child process:`,
|
|
3324
|
-
``,
|
|
3325
|
-
...piece.split(`
|
|
3326
|
-
`),
|
|
3327
|
-
``,
|
|
3328
|
-
thrown0.message
|
|
3329
|
-
].join(`
|
|
3330
|
-
\u274C `) + `
|
|
3331
|
-
`);
|
|
3332
|
-
try {
|
|
3333
|
-
if (idx === 0) {
|
|
3334
|
-
this.incompleteData = piece;
|
|
3335
|
-
const maybeActualJsonPiece = parseJson(initialMaybeWellFormed);
|
|
3336
|
-
this.handleLog(maybeActualJsonPiece);
|
|
3337
|
-
this.incompleteData = ``;
|
|
3338
|
-
} else
|
|
3339
|
-
this.incompleteData += piece;
|
|
3340
|
-
} catch (thrown1) {
|
|
3341
|
-
if (thrown1 instanceof Error)
|
|
3342
|
-
this.logger.error([
|
|
3343
|
-
`\u274C Malformed log received from child process:`,
|
|
3344
|
-
``,
|
|
3345
|
-
...initialMaybeWellFormed.split(`
|
|
3346
|
-
`),
|
|
3347
|
-
``,
|
|
3348
|
-
thrown1.message
|
|
3349
|
-
].join(`
|
|
3350
|
-
\u274C `) + `
|
|
3351
|
-
`);
|
|
3352
|
-
}
|
|
3353
|
-
}
|
|
3354
|
-
++idx;
|
|
3355
|
-
}
|
|
3356
|
-
});
|
|
3357
|
-
this.proc.stdin.once(`error`, (err) => {
|
|
3358
|
-
if (err.code === `EPIPE`)
|
|
3359
|
-
console.error(`EPIPE error during write`, this.proc.stdin);
|
|
3360
|
-
});
|
|
3361
|
-
if (proc.pid)
|
|
3362
|
-
this.id = proc.pid.toString();
|
|
3363
|
-
}
|
|
3364
|
-
};
|
|
3365
|
-
var ROOMS = globalThis.ATOM_IO_REALTIME_SERVER_ROOMS ?? (globalThis.ATOM_IO_REALTIME_SERVER_ROOMS = /* @__PURE__ */ new Map);
|
|
3366
|
-
var socketAtoms = atomFamily({
|
|
3367
|
-
key: `sockets`,
|
|
3368
|
-
default: null
|
|
3369
|
-
});
|
|
3370
|
-
var socketKeysAtom = mutableAtom({
|
|
3371
|
-
key: `socketKeys`,
|
|
3372
|
-
class: UList
|
|
3373
|
-
});
|
|
3374
|
-
var onlineUsersAtom = mutableAtom({
|
|
3375
|
-
key: `onlineUsers`,
|
|
3376
|
-
class: UList
|
|
3377
|
-
});
|
|
3378
|
-
var usersOfSockets = join({
|
|
3379
|
-
key: `usersOfSockets`,
|
|
3380
|
-
between: [`user`, `socket`],
|
|
3381
|
-
cardinality: `1:1`,
|
|
3382
|
-
isAType: isUserKey,
|
|
3383
|
-
isBType: isSocketKey
|
|
3384
|
-
});
|
|
3385
|
-
|
|
3386
|
-
// src/backend.worker.game.bun.ts
|
|
3387
|
-
var parent = new ParentSocket(process);
|
|
3388
|
-
Object.assign(console, parent.logger, { log: parent.logger.info });
|
|
3389
|
-
parent.on(`timeToStop`, function gracefulExit() {
|
|
3390
|
-
parent.logger.info(`\uD83D\uDEEC game worker exiting`);
|
|
3391
|
-
process.exit(0);
|
|
3392
|
-
});
|
|
3393
|
-
parent.logger.info(`\uD83D\uDEEB game worker ready`);
|