tempest.games 0.2.105 → 0.3.0

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.
@@ -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`);