create-atom.io 0.0.0 → 0.0.2

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