flightdeck 0.2.15 → 0.2.17

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.
@@ -218,9 +218,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
218
218
  default: (key) => {
219
219
  const getFn = options.get(key);
220
220
  return getFn({
221
- get: (...ps) => getFromStore(store, ...ps),
222
- find: (token, k) => findInStore(store, token, k),
223
- seek: (token, k) => seekInStore(store, token, k),
221
+ get: (...args) => getFromStore(store, ...args),
222
+ find: (...args) => findInStore(store, ...args),
224
223
  json: (token) => getJsonToken(store, token)
225
224
  });
226
225
  }
@@ -306,976 +305,938 @@ function deposit(state) {
306
305
  return token;
307
306
  }
308
307
 
309
- // ../atom.io/src/molecule.ts
310
- function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
311
- const molecule = {
312
- key,
313
- stringKey: stringifyJson(key),
314
- dependsOn: `any`
308
+ // ../atom.io/src/atom.ts
309
+ function atom(options) {
310
+ return createStandaloneAtom(IMPLICIT.STORE, options);
311
+ }
312
+ function atomFamily(options) {
313
+ return createAtomFamily(IMPLICIT.STORE, options);
314
+ }
315
+
316
+ // ../atom.io/src/join.ts
317
+ function join(options, defaultContent, store = IMPLICIT.STORE) {
318
+ store.joins.set(options.key, new Join(options, defaultContent, store));
319
+ const token = {
320
+ key: options.key,
321
+ type: `join`,
322
+ a: options.between[0],
323
+ b: options.between[1],
324
+ cardinality: options.cardinality
315
325
  };
316
- store.molecules.set(stringifyJson(key), molecule);
317
- return key;
326
+ return token;
318
327
  }
319
- function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
320
- const origin = provenance;
321
- const stringKey = stringifyJson(key);
322
- const invalidKeys = [];
323
- const target = newest(store);
324
- if (Array.isArray(origin)) {
325
- for (const formerClaim of origin) {
326
- const claimString = stringifyJson(formerClaim);
327
- const claim = target.molecules.get(claimString);
328
- if (claim) {
329
- store.moleculeGraph.set(claimString, stringKey, { source: claimString });
330
- } else {
331
- invalidKeys.push(claimString);
332
- }
328
+ function getInternalRelations(token) {
329
+ return getInternalRelationsFromStore(token, IMPLICIT.STORE);
330
+ }
331
+
332
+ // ../atom.io/src/logger.ts
333
+ var simpleLog = (logLevel) => (icon, denomination, tokenKey, message, ...rest) => {
334
+ console[logLevel](
335
+ `${icon} ${denomination} "${tokenKey}" ${message}`,
336
+ ...rest
337
+ );
338
+ };
339
+ var simpleLogger = {
340
+ error: simpleLog(`error`),
341
+ info: simpleLog(`info`),
342
+ warn: simpleLog(`warn`)
343
+ };
344
+ var AtomIOLogger = class {
345
+ constructor(logLevel, filter, logger = simpleLogger) {
346
+ this.logLevel = logLevel;
347
+ this.filter = filter;
348
+ this.logger = logger;
349
+ }
350
+ error = (...args) => {
351
+ if ((this.filter?.(...args) ?? true) && this.logLevel !== null) {
352
+ this.logger.error(...args);
333
353
  }
334
- } else {
335
- const claimString = stringifyJson(origin);
336
- const claim = target.molecules.get(claimString);
337
- if (claim) {
338
- store.moleculeGraph.set(claimString, stringKey, { source: claimString });
339
- } else {
340
- invalidKeys.push(claimString);
354
+ };
355
+ info = (...args) => {
356
+ if ((this.filter?.(...args) ?? true) && this.logLevel === `info`) {
357
+ this.logger.info(...args);
341
358
  }
342
- }
343
- if (invalidKeys.length === 0) {
344
- target.molecules.set(stringKey, { key, stringKey, dependsOn });
345
- }
346
- const creationEvent = {
347
- type: `molecule_creation`,
348
- key,
349
- provenance: origin
350
359
  };
351
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
352
- if (isTransaction) {
353
- target.transactionMeta.update.updates.push(creationEvent);
354
- } else {
355
- target.on.moleculeCreation.next(creationEvent);
360
+ warn = (...args) => {
361
+ if ((this.filter?.(...args) ?? true) && this.logLevel !== `error` && this.logLevel !== null) {
362
+ this.logger.warn(...args);
363
+ }
364
+ };
365
+ };
366
+ var Realm = class {
367
+ store;
368
+ constructor(store = IMPLICIT.STORE) {
369
+ this.store = store;
370
+ makeRootMoleculeInStore(`root`, store);
356
371
  }
357
- for (const claim of invalidKeys) {
358
- const disposal = store.disposalTraces.buffer.find(
359
- (item) => item?.key === claim
372
+ allocate(provenance, key, attachmentStyle) {
373
+ return allocateIntoStore(
374
+ this.store,
375
+ provenance,
376
+ key,
377
+ attachmentStyle
360
378
  );
361
- store.logger.error(
362
- `\u274C`,
363
- `molecule`,
379
+ }
380
+ fuse(type, reagentA, reagentB) {
381
+ return fuseWithinStore(this.store, type, reagentA, reagentB);
382
+ }
383
+ deallocate(claim) {
384
+ deallocateFromStore(this.store, claim);
385
+ }
386
+ claim(newProvenance, claim, exclusive) {
387
+ return claimWithinStore(this.store, newProvenance, claim, exclusive);
388
+ }
389
+ };
390
+ var Anarchy = class {
391
+ store;
392
+ realm;
393
+ constructor(store = IMPLICIT.STORE) {
394
+ this.store = store;
395
+ this.realm = new Realm(store);
396
+ }
397
+ allocate(provenance, key, attachmentStyle) {
398
+ allocateIntoStore(
399
+ this.store,
400
+ provenance,
364
401
  key,
365
- `allocation failed:`,
366
- `Could not allocate to ${claim} in store "${store.config.name}".`,
367
- disposal ? `
368
- ${claim} was most recently disposed
369
- ${disposal.trace}` : `No previous disposal trace for ${claim} was found.`
402
+ attachmentStyle
370
403
  );
371
404
  }
372
- return key;
405
+ deallocate(key) {
406
+ deallocateFromStore(this.store, key);
407
+ }
408
+ claim(newProvenance, key, exclusive) {
409
+ claimWithinStore(this.store, newProvenance, key, exclusive);
410
+ }
411
+ };
412
+
413
+ // ../atom.io/src/selector.ts
414
+ function selectorFamily(options) {
415
+ return createSelectorFamily(IMPLICIT.STORE, options);
373
416
  }
374
- function fuseWithinStore(store, type, sideA, sideB) {
375
- const compoundKey = `T$--${type}==${sideA}++${sideB}`;
376
- const above = [sideA, sideB];
377
- allocateIntoStore(
378
- store,
379
- above,
380
- compoundKey,
381
- `all`
382
- );
383
- return compoundKey;
417
+
418
+ // ../atom.io/internal/src/transaction/is-root-store.ts
419
+ function isRootStore(store) {
420
+ return `epoch` in store.transactionMeta;
384
421
  }
385
- function deallocateFromStore(store, claim) {
386
- const stringKey = stringifyJson(claim);
387
- const molecule = store.molecules.get(stringKey);
388
- if (!molecule) {
389
- const disposal = store.disposalTraces.buffer.find(
390
- (item) => item?.key === stringKey
391
- );
392
- store.logger.error(
393
- `\u274C`,
394
- `molecule`,
395
- claim,
396
- `deallocation failed:`,
397
- `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
398
- disposal ? `
399
- This state was most recently deallocated
400
- ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
422
+ function isChildStore(store) {
423
+ return `phase` in store.transactionMeta;
424
+ }
425
+
426
+ // ../atom.io/internal/src/transaction/abort-transaction.ts
427
+ var abortTransaction = (store) => {
428
+ const target = newest(store);
429
+ if (!isChildStore(target)) {
430
+ store.logger.warn(
431
+ `\u{1F41E}`,
432
+ `transaction`,
433
+ `???`,
434
+ `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
401
435
  );
402
436
  return;
403
437
  }
404
- const joinKeys = store.moleculeJoins.getRelatedKeys(
405
- molecule.key
438
+ store.logger.info(
439
+ `\u{1FA82}`,
440
+ `transaction`,
441
+ target.transactionMeta.update.key,
442
+ `Aborting transaction`
406
443
  );
407
- if (joinKeys) {
408
- for (const joinKey of joinKeys) {
409
- const join2 = store.joins.get(joinKey);
410
- if (join2) {
411
- join2.relations.delete(molecule.key);
412
- join2.molecules.delete(molecule.stringKey);
413
- }
414
- }
444
+ target.parent.child = null;
445
+ };
446
+
447
+ // ../atom.io/internal/src/capitalize.ts
448
+ function capitalize(string) {
449
+ return string[0].toUpperCase() + string.slice(1);
450
+ }
451
+
452
+ // ../atom.io/internal/src/pretty-print.ts
453
+ function prettyPrintTokenType(token) {
454
+ return token.type.split(`_`).map(capitalize).join(` `);
455
+ }
456
+
457
+ // ../atom.io/internal/src/not-found-error.ts
458
+ var NotFoundError = class extends Error {
459
+ constructor(token, store) {
460
+ super(
461
+ `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`
462
+ );
415
463
  }
416
- store.moleculeJoins.delete(molecule.stringKey);
417
- const provenance = [];
418
- const values = [];
419
- const disposalEvent = {
420
- type: `molecule_disposal`,
421
- key: molecule.key,
422
- values,
423
- provenance
464
+ };
465
+
466
+ // ../atom.io/internal/src/transaction/act-upon-store.ts
467
+ function actUponStore(store, token, id) {
468
+ return (...parameters) => {
469
+ const tx = withdraw(store, token);
470
+ if (tx) {
471
+ return tx.run(parameters, id);
472
+ }
473
+ throw new NotFoundError(token, store);
424
474
  };
425
- const target = newest(store);
426
- target.molecules.delete(stringKey);
427
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
428
- if (isTransaction) {
429
- target.transactionMeta.update.updates.push(disposalEvent);
475
+ }
476
+
477
+ // ../atom.io/internal/src/set-state/become.ts
478
+ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
479
+
480
+ // ../atom.io/internal/src/get-state/read-or-compute-value.ts
481
+ var readOrComputeValue = (target, state) => {
482
+ if (target.valueMap.has(state.key)) {
483
+ target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
484
+ return readCachedValue(state, target);
430
485
  }
431
- const relatedMolecules = store.moleculeGraph.getRelationEntries({
432
- downstreamMoleculeKey: molecule.stringKey
433
- });
434
- if (relatedMolecules) {
435
- for (const [relatedStringKey, { source }] of relatedMolecules) {
436
- if (source === molecule.stringKey) {
437
- const relatedKey = parseJson(relatedStringKey);
438
- deallocateFromStore(store, relatedKey);
439
- } else {
440
- provenance.push(source);
441
- }
442
- }
443
- }
444
- const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
445
- if (familyKeys) {
446
- for (const familyKey of familyKeys) {
447
- const family = target.families.get(familyKey);
448
- const token = findInStore(store, family, molecule.key);
449
- values.push([family.key, token]);
450
- disposeFromStore(store, token);
451
- }
486
+ if (state.type === `selector` || state.type === `readonly_selector`) {
487
+ target.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
488
+ return state.get();
452
489
  }
453
- target.moleculeGraph.delete(molecule.stringKey);
454
- target.moleculeJoins.delete(molecule.stringKey);
455
- target.moleculeData.delete(molecule.stringKey);
456
- if (!isTransaction) {
457
- target.on.moleculeDisposal.next(disposalEvent);
490
+ const fallback = state.default instanceof Function ? state.default() : state.default;
491
+ target.logger.info(
492
+ `\u{1F481}`,
493
+ `atom`,
494
+ state.key,
495
+ `could not find cached value; using default`,
496
+ fallback
497
+ );
498
+ return state.default instanceof Function ? state.default() : state.default;
499
+ };
500
+
501
+ // ../atom.io/internal/src/operation.ts
502
+ var openOperation = (store, token) => {
503
+ if (store.operation.open) {
504
+ const rejectionTime = performance.now();
505
+ store.logger.info(
506
+ `\u2757`,
507
+ token.type,
508
+ token.key,
509
+ `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`
510
+ );
511
+ return rejectionTime;
458
512
  }
459
- target.molecules.delete(molecule.stringKey);
460
- const trace = getTrace(new Error());
461
- store.disposalTraces.add({ key: stringKey, trace });
462
- }
463
- function claimWithinStore(store, newProvenance, claim, exclusive) {
464
- const stringKey = stringifyJson(claim);
465
- const target = newest(store);
466
- const molecule = target.molecules.get(stringKey);
467
- if (!molecule) {
468
- const disposal = store.disposalTraces.buffer.find(
469
- (item) => item?.key === stringKey
513
+ store.operation = {
514
+ open: true,
515
+ done: /* @__PURE__ */ new Set(),
516
+ prev: /* @__PURE__ */ new Map(),
517
+ time: Date.now(),
518
+ token
519
+ };
520
+ store.logger.info(
521
+ `\u2B55`,
522
+ token.type,
523
+ token.key,
524
+ `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
525
+ );
526
+ };
527
+ var closeOperation = (store) => {
528
+ if (store.operation.open) {
529
+ store.logger.info(
530
+ `\u{1F534}`,
531
+ store.operation.token.type,
532
+ store.operation.token.key,
533
+ `operation done in store "${store.config.name}"`
470
534
  );
535
+ }
536
+ store.operation = { open: false };
537
+ store.on.operationClose.next(store.operation);
538
+ };
539
+ var isDone = (store, key) => {
540
+ if (!store.operation.open) {
471
541
  store.logger.error(
472
- `\u274C`,
473
- `molecule`,
474
- claim,
475
- `claim failed:`,
476
- `Could not allocate to ${stringKey} in store "${store.config.name}".`,
477
- disposal ? `
478
- ${stringKey} was most recently disposed
479
- ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
542
+ `\u{1F41E}`,
543
+ `unknown`,
544
+ key,
545
+ `isDone called outside of an operation. This is probably a bug in AtomIO.`
480
546
  );
481
- return claim;
547
+ return true;
482
548
  }
483
- const newProvenanceKey = stringifyJson(newProvenance);
484
- const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
485
- if (!newProvenanceMolecule) {
486
- const disposal = store.disposalTraces.buffer.find(
487
- (item) => item?.key === newProvenanceKey
488
- );
549
+ return store.operation.done.has(key);
550
+ };
551
+ var markDone = (store, key) => {
552
+ if (!store.operation.open) {
489
553
  store.logger.error(
490
- `\u274C`,
491
- `molecule`,
492
- claim,
493
- `claim failed:`,
494
- `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
495
- disposal ? `
496
- ${newProvenanceKey} was most recently disposed
497
- ${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`
554
+ `\u{1F41E}`,
555
+ `unknown`,
556
+ key,
557
+ `markDone called outside of an operation. This is probably a bug in AtomIO.`
498
558
  );
499
- return claim;
559
+ return;
500
560
  }
501
- const priorProvenance = store.moleculeGraph.getRelationEntries({
502
- downstreamMoleculeKey: molecule.stringKey
503
- }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
504
- if (exclusive) {
505
- target.moleculeGraph.delete(stringKey);
561
+ store.operation.done.add(key);
562
+ };
563
+
564
+ // ../atom.io/internal/src/set-state/emit-update.ts
565
+ var emitUpdate = (store, state, update) => {
566
+ switch (state.type) {
567
+ case `mutable_atom`:
568
+ store.logger.info(
569
+ `\u{1F4E2}`,
570
+ state.type,
571
+ state.key,
572
+ `is now (`,
573
+ update.newValue,
574
+ `) subscribers:`,
575
+ state.subject.subscribers
576
+ );
577
+ break;
578
+ default:
579
+ store.logger.info(
580
+ `\u{1F4E2}`,
581
+ state.type,
582
+ state.key,
583
+ `went (`,
584
+ update.oldValue,
585
+ `->`,
586
+ update.newValue,
587
+ `) subscribers:`,
588
+ state.subject.subscribers
589
+ );
506
590
  }
507
- target.moleculeGraph.set(
508
- {
509
- upstreamMoleculeKey: newProvenanceMolecule.stringKey,
510
- downstreamMoleculeKey: molecule.stringKey
511
- },
512
- {
513
- source: newProvenanceMolecule.stringKey
514
- }
591
+ state.subject.next(update);
592
+ };
593
+
594
+ // ../atom.io/internal/src/set-state/evict-downstream.ts
595
+ var evictDownStream = (store, atom2) => {
596
+ const target = newest(store);
597
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
598
+ target.logger.info(
599
+ `\u{1F9F9}`,
600
+ atom2.type,
601
+ atom2.key,
602
+ downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
603
+ downstreamKeys ?? `to evict`
515
604
  );
516
- const transferEvent = {
517
- type: `molecule_transfer`,
518
- key: molecule.key,
519
- from: priorProvenance,
520
- to: [newProvenanceMolecule.key]
521
- };
522
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
523
- if (isTransaction) {
524
- target.transactionMeta.update.updates.push(transferEvent);
605
+ if (downstreamKeys) {
606
+ if (target.operation.open) {
607
+ target.logger.info(
608
+ `\u{1F9F9}`,
609
+ atom2.type,
610
+ atom2.key,
611
+ `[ ${[...target.operation.done].join(`, `)} ] already done`
612
+ );
613
+ }
614
+ for (const key of downstreamKeys) {
615
+ if (isDone(target, key)) {
616
+ continue;
617
+ }
618
+ evictCachedValue(key, target);
619
+ markDone(target, key);
620
+ }
525
621
  }
526
- return claim;
527
- }
528
- var Realm = class {
529
- store;
530
- constructor(store = IMPLICIT.STORE) {
531
- this.store = store;
532
- makeRootMoleculeInStore(`root`, store);
622
+ };
623
+
624
+ // ../atom.io/internal/src/set-state/stow-update.ts
625
+ function shouldUpdateBeStowed(key, update) {
626
+ if (isTransceiver(update.newValue)) {
627
+ return false;
533
628
  }
534
- allocate(provenance, key, attachmentStyle) {
535
- return allocateIntoStore(
536
- this.store,
537
- provenance,
629
+ if (key.includes(`\u{1F50D}`)) {
630
+ return false;
631
+ }
632
+ return true;
633
+ }
634
+ var stowUpdate = (store, state, update) => {
635
+ const { key } = state;
636
+ const target = newest(store);
637
+ if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
638
+ store.logger.error(
639
+ `\u{1F41E}`,
640
+ `atom`,
538
641
  key,
539
- attachmentStyle
642
+ `stowUpdate called outside of a transaction. This is probably a bug.`
540
643
  );
644
+ return;
541
645
  }
542
- fuse(type, reagentA, reagentB) {
543
- return fuseWithinStore(this.store, type, reagentA, reagentB);
544
- }
545
- deallocate(claim) {
546
- deallocateFromStore(this.store, claim);
646
+ const shouldStow = shouldUpdateBeStowed(key, update);
647
+ if (!shouldStow) {
648
+ return;
547
649
  }
548
- claim(newProvenance, claim, exclusive) {
549
- return claimWithinStore(this.store, newProvenance, claim, exclusive);
650
+ const atomUpdate = {
651
+ type: `atom_update`,
652
+ key,
653
+ ...update
654
+ };
655
+ if (state.family) {
656
+ atomUpdate.family = state.family;
550
657
  }
551
- };
552
- var Anarchy = class {
553
- store;
554
- realm;
555
- constructor(store = IMPLICIT.STORE) {
556
- this.store = store;
557
- this.realm = new Realm(store);
658
+ target.transactionMeta.update.updates.push(atomUpdate);
659
+ store.logger.info(
660
+ `\u{1F4C1}`,
661
+ `atom`,
662
+ key,
663
+ `stowed (`,
664
+ update.oldValue,
665
+ `->`,
666
+ update.newValue,
667
+ `)`
668
+ );
669
+ };
670
+
671
+ // ../atom.io/internal/src/set-state/set-atom.ts
672
+ var setAtom = (atom2, next, target) => {
673
+ const oldValue = readOrComputeValue(target, atom2);
674
+ let newValue = oldValue;
675
+ if (atom2.type === `mutable_atom` && isChildStore(target)) {
676
+ const { parent } = target;
677
+ const copiedValue = copyMutableIfNeeded(target, atom2, parent);
678
+ newValue = copiedValue;
558
679
  }
559
- allocate(provenance, key, attachmentStyle) {
560
- allocateIntoStore(
561
- this.store,
562
- provenance,
563
- key,
564
- attachmentStyle
565
- );
680
+ newValue = become(next)(newValue);
681
+ target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
682
+ newValue = cacheValue(target, atom2.key, newValue, atom2.subject);
683
+ if (isAtomDefault(target, atom2.key)) {
684
+ markAtomAsNotDefault(target, atom2.key);
566
685
  }
567
- deallocate(key) {
568
- deallocateFromStore(this.store, key);
686
+ markDone(target, atom2.key);
687
+ evictDownStream(target, atom2);
688
+ const update = { oldValue, newValue };
689
+ if (isRootStore(target)) {
690
+ emitUpdate(target, atom2, update);
691
+ } else if (target.parent) {
692
+ if (target.on.transactionApplying.state === null) {
693
+ stowUpdate(target, atom2, update);
694
+ } else if (atom2.key.startsWith(`*`)) {
695
+ const mutableKey = atom2.key.slice(1);
696
+ const mutableAtom = target.atoms.get(mutableKey);
697
+ let transceiver = target.valueMap.get(mutableKey);
698
+ if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
699
+ const { parent } = target;
700
+ const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
701
+ transceiver = copiedValue;
702
+ }
703
+ const accepted = transceiver.do(update.newValue) === null;
704
+ if (accepted) evictDownStream(target, mutableAtom);
705
+ }
569
706
  }
570
- claim(newProvenance, key, exclusive) {
571
- claimWithinStore(this.store, newProvenance, key, exclusive);
707
+ };
708
+
709
+ // ../atom.io/internal/src/set-state/set-atom-or-selector.ts
710
+ var setAtomOrSelector = (store, state, value) => {
711
+ switch (state.type) {
712
+ case `atom`:
713
+ case `mutable_atom`:
714
+ setAtom(state, value, store);
715
+ break;
716
+ case `selector`:
717
+ state.set(value);
718
+ break;
572
719
  }
573
720
  };
574
721
 
575
- // ../atom.io/src/atom.ts
576
- function atom(options) {
577
- return createStandaloneAtom(IMPLICIT.STORE, options);
578
- }
579
- function atomFamily(options) {
580
- return createAtomFamily(IMPLICIT.STORE, options);
722
+ // ../atom.io/internal/src/families/get-family-of-token.ts
723
+ function getFamilyOfToken(store, token) {
724
+ if (token.family) {
725
+ const family = store.families.get(token.family.key);
726
+ if (family) {
727
+ return family;
728
+ }
729
+ }
581
730
  }
582
731
 
583
- // ../atom.io/src/logger.ts
584
- var simpleLog = (logLevel) => (icon, denomination, tokenKey, message, ...rest) => {
585
- console[logLevel](
586
- `${icon} ${denomination} "${tokenKey}" ${message}`,
587
- ...rest
588
- );
589
- };
590
- var simpleLogger = {
591
- error: simpleLog(`error`),
592
- info: simpleLog(`info`),
593
- warn: simpleLog(`warn`)
594
- };
595
- var AtomIOLogger = class {
596
- constructor(logLevel, filter, logger = simpleLogger) {
597
- this.logLevel = logLevel;
598
- this.filter = filter;
599
- this.logger = logger;
600
- }
601
- error = (...args) => {
602
- if ((this.filter?.(...args) ?? true) && this.logLevel !== null) {
603
- this.logger.error(...args);
604
- }
605
- };
606
- info = (...args) => {
607
- if ((this.filter?.(...args) ?? true) && this.logLevel === `info`) {
608
- this.logger.info(...args);
609
- }
610
- };
611
- warn = (...args) => {
612
- if ((this.filter?.(...args) ?? true) && this.logLevel !== `error` && this.logLevel !== null) {
613
- this.logger.warn(...args);
732
+ // ../atom.io/internal/src/set-state/set-into-store.ts
733
+ function setIntoStore(store, ...params) {
734
+ let token;
735
+ let family;
736
+ let key;
737
+ let value;
738
+ if (params.length === 2) {
739
+ token = params[0];
740
+ value = params[1];
741
+ family = getFamilyOfToken(store, token) ?? null;
742
+ if (family) {
743
+ key = token.family ? parseJson(token.family.subKey) : null;
744
+ token = findInStore(store, family, key);
614
745
  }
615
- };
616
- };
617
-
618
- // ../atom.io/src/selector.ts
619
- function selectorFamily(options) {
620
- return createSelectorFamily(IMPLICIT.STORE, options);
746
+ } else {
747
+ family = params[0];
748
+ key = params[1];
749
+ value = params[2];
750
+ token = findInStore(store, family, key);
751
+ }
752
+ if (`counterfeit` in token && `family` in token) {
753
+ const subKey = token.family.subKey;
754
+ const disposal = store.disposalTraces.buffer.find(
755
+ (item) => item?.key === subKey
756
+ );
757
+ store.logger.error(
758
+ `\u274C`,
759
+ token.type,
760
+ token.key,
761
+ `could not be set because it was not found in the store "${store.config.name}".`,
762
+ disposal ? `This state was previously disposed:
763
+ ${disposal.trace}` : `No previous disposal trace was found.`
764
+ );
765
+ return;
766
+ }
767
+ const rejectionTime = openOperation(store, token);
768
+ if (rejectionTime) {
769
+ const unsubscribe = store.on.operationClose.subscribe(
770
+ `waiting to set "${token.key}" at T-${rejectionTime}`,
771
+ () => {
772
+ unsubscribe();
773
+ store.logger.info(
774
+ `\u{1F7E2}`,
775
+ token.type,
776
+ token.key,
777
+ `resuming deferred setState from T-${rejectionTime}`
778
+ );
779
+ setIntoStore(store, token, value);
780
+ }
781
+ );
782
+ return;
783
+ }
784
+ const state = withdraw(store, token);
785
+ setAtomOrSelector(store, state, value);
786
+ closeOperation(store);
621
787
  }
622
788
 
623
- // ../atom.io/src/transaction.ts
624
- function transaction(options) {
625
- return createTransaction(options, IMPLICIT.STORE);
789
+ // ../atom.io/internal/src/ingest-updates/ingest-atom-update.ts
790
+ function ingestAtomUpdate(applying, atomUpdate, store) {
791
+ const { key, newValue, oldValue } = atomUpdate;
792
+ const value = newValue ;
793
+ const token = { key, type: `atom` };
794
+ if (atomUpdate.family) {
795
+ Object.assign(token, { family: atomUpdate.family });
796
+ }
797
+ setIntoStore(store, token, value);
626
798
  }
627
799
 
628
- // ../atom.io/internal/src/junction.ts
629
- var Junction = class {
630
- a;
631
- b;
632
- cardinality;
633
- relations = /* @__PURE__ */ new Map();
634
- contents = /* @__PURE__ */ new Map();
635
- isAType;
636
- isBType;
637
- isContent;
638
- makeContentKey = (a, b) => `${a}:${b}`;
639
- warn;
640
- getRelatedKeys(key) {
641
- return this.relations.get(key);
800
+ // ../atom.io/internal/src/get-trace.ts
801
+ function getTrace(error) {
802
+ const { stack } = error;
803
+ if (stack) {
804
+ return `
805
+ ` + stack.split(`
806
+ `)?.slice(1)?.join(`
807
+ `);
642
808
  }
643
- addRelation(a, b) {
644
- let aRelations = this.relations.get(a);
645
- let bRelations = this.relations.get(b);
646
- if (aRelations) {
647
- aRelations.add(b);
648
- } else {
649
- aRelations = /* @__PURE__ */ new Set([b]);
650
- this.relations.set(a, aRelations);
809
+ return ``;
810
+ }
811
+
812
+ // ../atom.io/internal/src/molecule.ts
813
+ function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
814
+ const molecule = {
815
+ key,
816
+ stringKey: stringifyJson(key),
817
+ dependsOn: `any`
818
+ };
819
+ store.molecules.set(stringifyJson(key), molecule);
820
+ return key;
821
+ }
822
+ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
823
+ const origin = provenance;
824
+ const stringKey = stringifyJson(key);
825
+ const invalidKeys = [];
826
+ const target = newest(store);
827
+ if (Array.isArray(origin)) {
828
+ for (const formerClaim of origin) {
829
+ const claimString = stringifyJson(formerClaim);
830
+ const claim = target.molecules.get(claimString);
831
+ if (claim) {
832
+ store.moleculeGraph.set(claimString, stringKey, { source: claimString });
833
+ } else {
834
+ invalidKeys.push(claimString);
835
+ }
651
836
  }
652
- if (bRelations) {
653
- bRelations.add(a);
837
+ } else {
838
+ const claimString = stringifyJson(origin);
839
+ const claim = target.molecules.get(claimString);
840
+ if (claim) {
841
+ store.moleculeGraph.set(claimString, stringKey, { source: claimString });
654
842
  } else {
655
- bRelations = /* @__PURE__ */ new Set([a]);
656
- this.relations.set(b, bRelations);
657
- }
658
- }
659
- deleteRelation(a, b) {
660
- const aRelations = this.relations.get(a);
661
- if (aRelations) {
662
- aRelations.delete(b);
663
- if (aRelations.size === 0) {
664
- this.relations.delete(a);
665
- }
666
- const bRelations = this.relations.get(b);
667
- if (bRelations) {
668
- bRelations.delete(a);
669
- if (bRelations.size === 0) {
670
- this.relations.delete(b);
671
- }
672
- }
843
+ invalidKeys.push(claimString);
673
844
  }
674
845
  }
675
- replaceRelationsUnsafely(x, ys) {
676
- this.relations.set(x, new Set(ys));
677
- for (const y of ys) {
678
- const yRelations = (/* @__PURE__ */ new Set()).add(x);
679
- this.relations.set(y, yRelations);
680
- }
681
- }
682
- replaceRelationsSafely(x, ys) {
683
- const xRelationsPrev = this.relations.get(x);
684
- let a = this.isAType?.(x) ? x : undefined;
685
- let b = a === undefined ? x : undefined;
686
- if (xRelationsPrev) {
687
- for (const y of xRelationsPrev) {
688
- a ??= y;
689
- b ??= y;
690
- const yRelations = this.relations.get(y);
691
- if (yRelations) {
692
- if (yRelations.size === 1) {
693
- this.relations.delete(y);
694
- } else {
695
- yRelations.delete(x);
696
- }
697
- this.contents.delete(this.makeContentKey(a, b));
698
- }
699
- }
700
- }
701
- this.relations.set(x, new Set(ys));
702
- for (const y of ys) {
703
- let yRelations = this.relations.get(y);
704
- if (yRelations) {
705
- yRelations.add(x);
706
- } else {
707
- yRelations = (/* @__PURE__ */ new Set()).add(x);
708
- this.relations.set(y, yRelations);
709
- }
710
- }
846
+ if (invalidKeys.length === 0) {
847
+ target.molecules.set(stringKey, { key, stringKey, dependsOn });
711
848
  }
712
- getContentInternal(contentKey) {
713
- return this.contents.get(contentKey);
849
+ const creationEvent = {
850
+ type: `molecule_creation`,
851
+ key,
852
+ provenance: origin
853
+ };
854
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
855
+ if (isTransaction) {
856
+ target.transactionMeta.update.updates.push(creationEvent);
857
+ } else {
858
+ target.on.moleculeCreation.next(creationEvent);
714
859
  }
715
- setContent(contentKey, content) {
716
- this.contents.set(contentKey, content);
860
+ for (const claim of invalidKeys) {
861
+ const disposal = store.disposalTraces.buffer.find(
862
+ (item) => item?.key === claim
863
+ );
864
+ store.logger.error(
865
+ `\u274C`,
866
+ `molecule`,
867
+ key,
868
+ `allocation failed:`,
869
+ `Could not allocate to ${claim} in store "${store.config.name}".`,
870
+ disposal ? `
871
+ ${claim} was most recently disposed
872
+ ${disposal.trace}` : `No previous disposal trace for ${claim} was found.`
873
+ );
717
874
  }
718
- deleteContent(contentKey) {
719
- this.contents.delete(contentKey);
875
+ return key;
876
+ }
877
+ function fuseWithinStore(store, type, sideA, sideB) {
878
+ const compoundKey = `T$--${type}==${sideA}++${sideB}`;
879
+ const above = [sideA, sideB];
880
+ allocateIntoStore(
881
+ store,
882
+ above,
883
+ compoundKey,
884
+ `all`
885
+ );
886
+ return compoundKey;
887
+ }
888
+ function deallocateFromStore(store, claim) {
889
+ const stringKey = stringifyJson(claim);
890
+ const molecule = store.molecules.get(stringKey);
891
+ if (!molecule) {
892
+ const disposal = store.disposalTraces.buffer.find(
893
+ (item) => item?.key === stringKey
894
+ );
895
+ store.logger.error(
896
+ `\u274C`,
897
+ `molecule`,
898
+ claim,
899
+ `deallocation failed:`,
900
+ `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
901
+ disposal ? `
902
+ This state was most recently deallocated
903
+ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
904
+ );
905
+ return;
720
906
  }
721
- constructor(data, config) {
722
- this.a = data.between[0];
723
- this.b = data.between[1];
724
- this.cardinality = data.cardinality;
725
- if (!config?.externalStore) {
726
- this.relations = new Map(
727
- data.relations?.map(([x, ys]) => [x, new Set(ys)])
728
- );
729
- this.contents = new Map(data.contents);
730
- }
731
- this.isAType = config?.isAType ?? null;
732
- this.isBType = config?.isBType ?? null;
733
- this.isContent = config?.isContent ?? null;
734
- if (config?.makeContentKey) {
735
- this.makeContentKey = config.makeContentKey;
736
- }
737
- if (config?.externalStore) {
738
- const externalStore = config.externalStore;
739
- this.has = (a, b) => externalStore.has(a, b);
740
- this.addRelation = (a, b) => {
741
- externalStore.addRelation(a, b);
742
- };
743
- this.deleteRelation = (a, b) => {
744
- externalStore.deleteRelation(a, b);
745
- };
746
- this.replaceRelationsSafely = (a, bs) => {
747
- externalStore.replaceRelationsSafely(a, bs);
748
- };
749
- this.replaceRelationsUnsafely = (a, bs) => {
750
- externalStore.replaceRelationsUnsafely(a, bs);
751
- };
752
- this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
753
- key
754
- );
755
- if (externalStore.getContent) {
756
- this.getContentInternal = (contentKey) => {
757
- return externalStore.getContent(contentKey);
758
- };
759
- this.setContent = (contentKey, content) => {
760
- externalStore.setContent(contentKey, content);
761
- };
762
- this.deleteContent = (contentKey) => {
763
- externalStore.deleteContent(contentKey);
764
- };
765
- }
766
- for (const [x, ys] of data.relations ?? []) {
767
- let a = this.isAType?.(x) ? x : undefined;
768
- let b = a === undefined ? x : undefined;
769
- for (const y of ys) {
770
- a ??= y;
771
- b ??= y;
772
- this.addRelation(a, b);
773
- }
774
- }
775
- for (const [contentKey, content] of data.contents ?? []) {
776
- this.setContent(contentKey, content);
907
+ const joinKeys = store.moleculeJoins.getRelatedKeys(
908
+ molecule.key
909
+ );
910
+ if (joinKeys) {
911
+ for (const joinKey of joinKeys) {
912
+ const join2 = store.joins.get(joinKey);
913
+ if (join2) {
914
+ join2.relations.delete(molecule.key);
915
+ join2.molecules.delete(molecule.stringKey);
777
916
  }
778
917
  }
779
- if (config?.warn) {
780
- this.warn = config.warn;
781
- }
782
918
  }
783
- toJSON() {
784
- return {
785
- between: [this.a, this.b],
786
- cardinality: this.cardinality,
787
- relations: [...this.relations.entries()].map(
788
- ([a, b]) => [a, [...b]]
789
- ),
790
- contents: [...this.contents.entries()]
791
- };
919
+ store.moleculeJoins.delete(molecule.stringKey);
920
+ const provenance = [];
921
+ const values = [];
922
+ const disposalEvent = {
923
+ type: `molecule_disposal`,
924
+ key: molecule.key,
925
+ values,
926
+ provenance
927
+ };
928
+ const target = newest(store);
929
+ target.molecules.delete(stringKey);
930
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
931
+ if (isTransaction) {
932
+ target.transactionMeta.update.updates.push(disposalEvent);
792
933
  }
793
- set(...params) {
794
- let a;
795
- let b;
796
- let content;
797
- switch (params.length) {
798
- case 1: {
799
- const relation = params[0];
800
- a = relation[this.a];
801
- b = relation[this.b];
802
- content = undefined;
803
- break;
804
- }
805
- case 2: {
806
- const zeroth = params[0];
807
- if (typeof zeroth === `string`) {
808
- [a, b] = params;
809
- } else {
810
- a = zeroth[this.a];
811
- b = zeroth[this.b];
812
- content = params[1];
813
- }
814
- break;
815
- }
816
- default: {
817
- a = params[0];
818
- b = params[1];
819
- content = params[2];
820
- break;
821
- }
822
- }
823
- switch (this.cardinality) {
824
- // biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
825
- case `1:1`: {
826
- const bPrev = this.getRelatedKey(a);
827
- if (bPrev && bPrev !== b) this.delete(a, bPrev);
828
- }
829
- case `1:n`: {
830
- const aPrev = this.getRelatedKey(b);
831
- if (aPrev && aPrev !== a) this.delete(aPrev, b);
934
+ const relatedMolecules = store.moleculeGraph.getRelationEntries({
935
+ downstreamMoleculeKey: molecule.stringKey
936
+ });
937
+ if (relatedMolecules) {
938
+ for (const [relatedStringKey, { source }] of relatedMolecules) {
939
+ if (source === molecule.stringKey) {
940
+ const relatedKey = parseJson(relatedStringKey);
941
+ deallocateFromStore(store, relatedKey);
942
+ } else {
943
+ provenance.push(source);
832
944
  }
833
945
  }
834
- if (content) {
835
- const contentKey = this.makeContentKey(a, b);
836
- this.setContent(contentKey, content);
946
+ }
947
+ const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
948
+ if (familyKeys) {
949
+ for (const familyKey of familyKeys) {
950
+ const family = target.families.get(familyKey);
951
+ const token = findInStore(store, family, molecule.key);
952
+ values.push([family.key, token]);
953
+ disposeFromStore(store, token);
837
954
  }
838
- this.addRelation(a, b);
839
- return this;
840
955
  }
841
- delete(x, b) {
842
- b = typeof b === `string` ? b : x[this.b];
843
- const a = (
844
- // @ts-expect-error we deduce that this.a may index x
845
- typeof x === `string` ? x : x[this.a]
956
+ target.moleculeGraph.delete(molecule.stringKey);
957
+ target.moleculeJoins.delete(molecule.stringKey);
958
+ target.moleculeData.delete(molecule.stringKey);
959
+ if (!isTransaction) {
960
+ target.on.moleculeDisposal.next(disposalEvent);
961
+ }
962
+ target.molecules.delete(molecule.stringKey);
963
+ const trace = getTrace(new Error());
964
+ store.disposalTraces.add({ key: stringKey, trace });
965
+ }
966
+ function claimWithinStore(store, newProvenance, claim, exclusive) {
967
+ const stringKey = stringifyJson(claim);
968
+ const target = newest(store);
969
+ const molecule = target.molecules.get(stringKey);
970
+ if (!molecule) {
971
+ const disposal = store.disposalTraces.buffer.find(
972
+ (item) => item?.key === stringKey
846
973
  );
847
- if (a === undefined && typeof b === `string`) {
848
- const bRelations = this.getRelatedKeys(b);
849
- if (bRelations) {
850
- for (const bRelation of bRelations) {
851
- this.delete(bRelation, b);
852
- }
853
- }
854
- }
855
- if (typeof a === `string` && b === undefined) {
856
- const aRelations = this.getRelatedKeys(a);
857
- if (aRelations) {
858
- for (const aRelation of aRelations) {
859
- this.delete(a, aRelation);
860
- }
861
- }
862
- }
863
- if (typeof a === `string` && typeof b === `string`) {
864
- this.deleteRelation(a, b);
865
- const contentKey = this.makeContentKey(a, b);
866
- this.deleteContent(contentKey);
867
- }
868
- return this;
974
+ store.logger.error(
975
+ `\u274C`,
976
+ `molecule`,
977
+ claim,
978
+ `claim failed:`,
979
+ `Could not allocate to ${stringKey} in store "${store.config.name}".`,
980
+ disposal ? `
981
+ ${stringKey} was most recently disposed
982
+ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
983
+ );
984
+ return claim;
869
985
  }
870
- getRelatedKey(key) {
871
- const relations = this.getRelatedKeys(key);
872
- if (relations) {
873
- if (relations.size > 1) {
874
- this.warn?.(
875
- `${relations.size} related keys were found for key "${key}": (${[
876
- ...relations
877
- ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
878
- );
879
- }
880
- let singleRelation;
881
- for (const relation of relations) {
882
- singleRelation = relation;
883
- break;
884
- }
885
- return singleRelation;
986
+ const newProvenanceKey = stringifyJson(newProvenance);
987
+ const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
988
+ if (!newProvenanceMolecule) {
989
+ const disposal = store.disposalTraces.buffer.find(
990
+ (item) => item?.key === newProvenanceKey
991
+ );
992
+ store.logger.error(
993
+ `\u274C`,
994
+ `molecule`,
995
+ claim,
996
+ `claim failed:`,
997
+ `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
998
+ disposal ? `
999
+ ${newProvenanceKey} was most recently disposed
1000
+ ${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`
1001
+ );
1002
+ return claim;
1003
+ }
1004
+ const priorProvenance = store.moleculeGraph.getRelationEntries({
1005
+ downstreamMoleculeKey: molecule.stringKey
1006
+ }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
1007
+ if (exclusive) {
1008
+ target.moleculeGraph.delete(stringKey);
1009
+ }
1010
+ target.moleculeGraph.set(
1011
+ {
1012
+ upstreamMoleculeKey: newProvenanceMolecule.stringKey,
1013
+ downstreamMoleculeKey: molecule.stringKey
1014
+ },
1015
+ {
1016
+ source: newProvenanceMolecule.stringKey
886
1017
  }
1018
+ );
1019
+ const transferEvent = {
1020
+ type: `molecule_transfer`,
1021
+ key: molecule.key,
1022
+ from: priorProvenance,
1023
+ to: [newProvenanceMolecule.key]
1024
+ };
1025
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1026
+ if (isTransaction) {
1027
+ target.transactionMeta.update.updates.push(transferEvent);
887
1028
  }
888
- replaceRelations(x, relations, config) {
889
- const hasContent = !Array.isArray(relations);
890
- const ys = hasContent ? Object.keys(relations) : relations;
891
- if (config?.reckless) {
892
- this.replaceRelationsUnsafely(x, ys);
893
- } else {
894
- this.replaceRelationsSafely(x, ys);
1029
+ return claim;
1030
+ }
1031
+
1032
+ // ../atom.io/internal/src/ingest-updates/ingest-creation-disposal.ts
1033
+ function ingestCreationEvent(update, applying, store) {
1034
+ switch (applying) {
1035
+ case `newValue`: {
1036
+ createInStore(update, store);
1037
+ break;
895
1038
  }
896
- if (hasContent) {
897
- for (const y of ys) {
898
- const contentKey = this.makeContentKey(x, y);
899
- const content = relations[y];
900
- this.setContent(contentKey, content);
901
- }
1039
+ case `oldValue`: {
1040
+ disposeFromStore(store, update.token);
1041
+ break;
902
1042
  }
903
- return this;
904
- }
905
- getContent(a, b) {
906
- const contentKey = this.makeContentKey(a, b);
907
- return this.getContentInternal(contentKey);
908
1043
  }
909
- getRelationEntries(input) {
910
- const a = input[this.a];
911
- const b = input[this.b];
912
- if (a !== undefined && b === undefined) {
913
- const aRelations = this.getRelatedKeys(a);
914
- if (aRelations) {
915
- return [...aRelations].map((aRelation) => {
916
- return [aRelation, this.getContent(a, aRelation)];
917
- });
918
- }
1044
+ }
1045
+ function ingestDisposalEvent(update, applying, store) {
1046
+ switch (applying) {
1047
+ case `newValue`: {
1048
+ disposeFromStore(store, update.token);
1049
+ break;
919
1050
  }
920
- if (a === undefined && b !== undefined) {
921
- const bRelations = this.getRelatedKeys(b);
922
- if (bRelations) {
923
- return [...bRelations].map((bRelation) => {
924
- return [bRelation, this.getContent(bRelation, b)];
925
- });
1051
+ case `oldValue`: {
1052
+ createInStore(update, store);
1053
+ if (update.subType === `atom`) {
1054
+ store.valueMap.set(update.token.key, update.value);
926
1055
  }
1056
+ break;
927
1057
  }
928
- return [];
929
1058
  }
930
- has(a, b) {
931
- if (b) {
932
- const setA = this.getRelatedKeys(a);
933
- return setA?.has(b) ?? false;
1059
+ }
1060
+ function createInStore(update, store) {
1061
+ const { family: familyMeta } = update.token;
1062
+ if (familyMeta) {
1063
+ const family = store.families.get(familyMeta.key);
1064
+ if (family) {
1065
+ findInStore(store, family, parseJson(familyMeta.subKey));
934
1066
  }
935
- return this.relations.has(a);
936
1067
  }
937
- };
938
-
939
- // ../atom.io/internal/src/transaction/is-root-store.ts
940
- function isRootStore(store) {
941
- return `epoch` in store.transactionMeta;
942
- }
943
- function isChildStore(store) {
944
- return `phase` in store.transactionMeta;
945
1068
  }
946
-
947
- // ../atom.io/internal/src/transaction/abort-transaction.ts
948
- var abortTransaction = (store) => {
949
- const target = newest(store);
950
- if (!isChildStore(target)) {
951
- store.logger.warn(
952
- `\u{1F41E}`,
953
- `transaction`,
954
- `???`,
955
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
956
- );
957
- return;
1069
+ function ingestMoleculeCreationEvent(update, applying, store) {
1070
+ switch (applying) {
1071
+ case `newValue`:
1072
+ allocateIntoStore(store, update.provenance, update.key);
1073
+ break;
1074
+ case `oldValue`:
1075
+ deallocateFromStore(store, update.key);
1076
+ break;
958
1077
  }
959
- store.logger.info(
960
- `\u{1FA82}`,
961
- `transaction`,
962
- target.transactionMeta.update.key,
963
- `Aborting transaction`
964
- );
965
- target.parent.child = null;
966
- };
967
-
968
- // ../atom.io/internal/src/pretty-print.ts
969
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
970
- function prettyPrintTokenType(token) {
971
- return token.type.split(`_`).map(capitalize).join(` `);
972
1078
  }
973
-
974
- // ../atom.io/internal/src/not-found-error.ts
975
- var NotFoundError = class extends Error {
976
- constructor(...params) {
977
- const token = params[0];
978
- const store = params.length === 2 ? params[1] : params[2];
979
- if (params.length === 2) {
980
- super(
981
- `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`
982
- );
983
- } else {
984
- const key = params[1];
985
- super(
986
- `${prettyPrintTokenType(token)} "${token.key}" member ${stringifyJson(key)} not found in store "${store.config.name}".`
987
- );
988
- }
1079
+ function ingestMoleculeDisposalEvent(update, applying, store) {
1080
+ switch (applying) {
1081
+ case `newValue`:
1082
+ deallocateFromStore(store, update.key);
1083
+ break;
1084
+ case `oldValue`:
1085
+ {
1086
+ const provenanceJson = update.provenance.map(parseJson);
1087
+ allocateIntoStore(store, provenanceJson, update.key);
1088
+ for (const [familyKey, value] of update.values) {
1089
+ const family = store.families.get(familyKey);
1090
+ if (family) {
1091
+ findInStore(store, family, update.key);
1092
+ const memberKey = `${familyKey}(${stringifyJson(update.key)})`;
1093
+ store.valueMap.set(memberKey, value);
1094
+ }
1095
+ }
1096
+ }
1097
+ break;
989
1098
  }
990
- };
991
-
992
- // ../atom.io/internal/src/transaction/act-upon-store.ts
993
- function actUponStore(token, id, store) {
994
- return (...parameters) => {
995
- const tx = withdraw(token, store);
996
- if (tx) {
997
- return tx.run(parameters, id);
998
- }
999
- throw new NotFoundError(token, store);
1000
- };
1001
1099
  }
1002
-
1003
- // ../atom.io/internal/src/set-state/become.ts
1004
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
1005
-
1006
- // ../atom.io/internal/src/get-state/read-or-compute-value.ts
1007
- var readOrComputeValue = (state, target) => {
1008
- if (target.valueMap.has(state.key)) {
1009
- target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
1010
- return readCachedValue(state, target);
1011
- }
1012
- if (state.type === `selector` || state.type === `readonly_selector`) {
1013
- target.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
1014
- return state.get();
1015
- }
1016
- const fallback = state.default instanceof Function ? state.default() : state.default;
1017
- target.logger.info(
1018
- `\u{1F481}`,
1019
- `atom`,
1020
- state.key,
1021
- `could not find cached value; using default`,
1022
- fallback
1023
- );
1024
- return state.default instanceof Function ? state.default() : state.default;
1025
- };
1026
-
1027
- // ../atom.io/internal/src/operation.ts
1028
- var openOperation = (store, token) => {
1029
- if (store.operation.open) {
1030
- const rejectionTime = performance.now();
1031
- store.logger.info(
1032
- `\u2757`,
1033
- token.type,
1034
- token.key,
1035
- `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`
1036
- );
1037
- return rejectionTime;
1038
- }
1039
- store.operation = {
1040
- open: true,
1041
- done: /* @__PURE__ */ new Set(),
1042
- prev: /* @__PURE__ */ new Map(),
1043
- time: Date.now(),
1044
- token
1045
- };
1046
- store.logger.info(
1047
- `\u2B55`,
1048
- token.type,
1049
- token.key,
1050
- `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
1051
- );
1052
- };
1053
- var closeOperation = (store) => {
1054
- if (store.operation.open) {
1055
- store.logger.info(
1056
- `\u{1F534}`,
1057
- store.operation.token.type,
1058
- store.operation.token.key,
1059
- `operation done in store "${store.config.name}"`
1060
- );
1061
- }
1062
- store.operation = { open: false };
1063
- store.on.operationClose.next(store.operation);
1064
- };
1065
- var isDone = (store, key) => {
1066
- if (!store.operation.open) {
1067
- store.logger.error(
1068
- `\u{1F41E}`,
1069
- `unknown`,
1070
- key,
1071
- `isDone called outside of an operation. This is probably a bug in AtomIO.`
1072
- );
1073
- return true;
1074
- }
1075
- return store.operation.done.has(key);
1076
- };
1077
- var markDone = (store, key) => {
1078
- if (!store.operation.open) {
1079
- store.logger.error(
1080
- `\u{1F41E}`,
1081
- `unknown`,
1082
- key,
1083
- `markDone called outside of an operation. This is probably a bug in AtomIO.`
1084
- );
1085
- return;
1086
- }
1087
- store.operation.done.add(key);
1088
- };
1089
-
1090
- // ../atom.io/internal/src/set-state/emit-update.ts
1091
- var emitUpdate = (state, update, store) => {
1092
- switch (state.type) {
1093
- case `mutable_atom`:
1094
- store.logger.info(
1095
- `\u{1F4E2}`,
1096
- state.type,
1097
- state.key,
1098
- `is now (`,
1099
- update.newValue,
1100
- `) subscribers:`,
1101
- state.subject.subscribers
1102
- );
1100
+ function ingestMoleculeTransferEvent(update, applying, store) {
1101
+ switch (applying) {
1102
+ case `newValue`:
1103
+ {
1104
+ const provenance = update.to.length === 1 ? update.to[0] : update.to;
1105
+ claimWithinStore(
1106
+ store,
1107
+ provenance,
1108
+ update.key,
1109
+ `exclusive`
1110
+ );
1111
+ }
1112
+ break;
1113
+ case `oldValue`:
1114
+ {
1115
+ const provenance = update.from.length === 1 ? update.from[0] : update.from;
1116
+ claimWithinStore(
1117
+ store,
1118
+ provenance,
1119
+ update.key,
1120
+ `exclusive`
1121
+ );
1122
+ }
1103
1123
  break;
1104
- default:
1105
- store.logger.info(
1106
- `\u{1F4E2}`,
1107
- state.type,
1108
- state.key,
1109
- `went (`,
1110
- update.oldValue,
1111
- `->`,
1112
- update.newValue,
1113
- `) subscribers:`,
1114
- state.subject.subscribers
1115
- );
1116
1124
  }
1117
- state.subject.next(update);
1118
- };
1125
+ }
1119
1126
 
1120
- // ../atom.io/internal/src/set-state/evict-downstream.ts
1121
- var evictDownStream = (atom2, store) => {
1122
- const target = newest(store);
1123
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
1124
- target.logger.info(
1125
- `\u{1F9F9}`,
1126
- atom2.type,
1127
- atom2.key,
1128
- downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
1129
- downstreamKeys ?? `to evict`
1130
- );
1131
- if (downstreamKeys) {
1132
- if (target.operation.open) {
1133
- target.logger.info(
1134
- `\u{1F9F9}`,
1135
- atom2.type,
1136
- atom2.key,
1137
- `[ ${[...target.operation.done].join(`, `)} ] already done`
1138
- );
1139
- }
1140
- for (const key of downstreamKeys) {
1141
- if (isDone(target, key)) {
1142
- continue;
1143
- }
1144
- evictCachedValue(key, target);
1145
- markDone(target, key);
1127
+ // ../atom.io/internal/src/ingest-updates/ingest-transaction-update.ts
1128
+ function ingestTransactionUpdate(applying, transactionUpdate, store) {
1129
+ const updates = transactionUpdate.updates ;
1130
+ for (const updateFromTransaction of updates) {
1131
+ switch (updateFromTransaction.type) {
1132
+ case `atom_update`:
1133
+ case `selector_update`:
1134
+ ingestAtomUpdate(applying, updateFromTransaction, store);
1135
+ break;
1136
+ case `state_creation`:
1137
+ ingestCreationEvent(updateFromTransaction, applying, store);
1138
+ break;
1139
+ case `state_disposal`:
1140
+ ingestDisposalEvent(updateFromTransaction, applying, store);
1141
+ break;
1142
+ case `molecule_creation`:
1143
+ ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1144
+ break;
1145
+ case `molecule_disposal`:
1146
+ ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1147
+ break;
1148
+ case `molecule_transfer`:
1149
+ ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
1150
+ break;
1151
+ case `transaction_update`:
1152
+ ingestTransactionUpdate(applying, updateFromTransaction, store);
1153
+ break;
1146
1154
  }
1147
1155
  }
1148
- };
1156
+ }
1149
1157
 
1150
- // ../atom.io/internal/src/set-state/stow-update.ts
1151
- function shouldUpdateBeStowed(key, update) {
1152
- if (isTransceiver(update.newValue)) {
1153
- return false;
1158
+ // ../atom.io/internal/src/transaction/set-epoch-number.ts
1159
+ function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1160
+ const isRoot = isRootStore(store);
1161
+ if (!isRoot) {
1162
+ return;
1154
1163
  }
1155
- if (key.includes(`\u{1F50D}`)) {
1156
- return false;
1164
+ const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1165
+ if (continuityKey !== undefined) {
1166
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1157
1167
  }
1158
- return true;
1159
1168
  }
1160
- var stowUpdate = (state, update, store) => {
1161
- const { key } = state;
1162
- const target = newest(store);
1163
- if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
1164
- store.logger.error(
1169
+
1170
+ // ../atom.io/internal/src/transaction/apply-transaction.ts
1171
+ var applyTransaction = (output, store) => {
1172
+ const child = newest(store);
1173
+ const { parent } = child;
1174
+ if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1175
+ store.logger.warn(
1165
1176
  `\u{1F41E}`,
1166
- `atom`,
1167
- key,
1168
- `stowUpdate called outside of a transaction. This is probably a bug.`
1177
+ `transaction`,
1178
+ `???`,
1179
+ `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1169
1180
  );
1170
1181
  return;
1171
1182
  }
1172
- const shouldStow = shouldUpdateBeStowed(key, update);
1173
- if (!shouldStow) {
1174
- return;
1175
- }
1176
- const atomUpdate = {
1177
- type: `atom_update`,
1178
- key,
1179
- ...update
1180
- };
1181
- if (state.family) {
1182
- atomUpdate.family = state.family;
1183
- }
1184
- target.transactionMeta.update.updates.push(atomUpdate);
1183
+ child.transactionMeta.phase = `applying`;
1184
+ child.transactionMeta.update.output = output;
1185
+ parent.child = null;
1186
+ parent.on.transactionApplying.next(child.transactionMeta);
1187
+ const { updates } = child.transactionMeta.update;
1185
1188
  store.logger.info(
1186
- `\u{1F4C1}`,
1187
- `atom`,
1188
- key,
1189
- `stowed (`,
1190
- update.oldValue,
1191
- `->`,
1192
- update.newValue,
1193
- `)`
1189
+ `\u{1F6C4}`,
1190
+ `transaction`,
1191
+ child.transactionMeta.update.key,
1192
+ `Applying transaction with ${updates.length} updates:`,
1193
+ updates
1194
1194
  );
1195
- };
1196
-
1197
- // ../atom.io/internal/src/set-state/set-atom.ts
1198
- var setAtom = (atom2, next, target) => {
1199
- const oldValue = readOrComputeValue(atom2, target);
1200
- let newValue = oldValue;
1201
- if (atom2.type === `mutable_atom` && isChildStore(target)) {
1202
- const { parent } = target;
1203
- const copiedValue = copyMutableIfNeeded(atom2, parent, target);
1204
- newValue = copiedValue;
1205
- }
1206
- newValue = become(next)(newValue);
1207
- target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
1208
- newValue = cacheValue(atom2.key, newValue, atom2.subject, target);
1209
- if (isAtomDefault(atom2.key, target)) {
1210
- markAtomAsNotDefault(atom2.key, target);
1211
- }
1212
- markDone(target, atom2.key);
1213
- evictDownStream(atom2, target);
1214
- const update = { oldValue, newValue };
1215
- if (isRootStore(target)) {
1216
- emitUpdate(atom2, update, target);
1217
- } else if (target.parent) {
1218
- if (target.on.transactionApplying.state === null) {
1219
- stowUpdate(atom2, update, target);
1220
- } else if (atom2.key.startsWith(`*`)) {
1221
- const mutableKey = atom2.key.slice(1);
1222
- const mutableAtom = target.atoms.get(mutableKey);
1223
- let transceiver = target.valueMap.get(mutableKey);
1224
- if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
1225
- const { parent } = target;
1226
- const copiedValue = copyMutableIfNeeded(mutableAtom, parent, target);
1227
- transceiver = copiedValue;
1228
- }
1229
- const accepted = transceiver.do(update.newValue) === null;
1230
- if (accepted) evictDownStream(mutableAtom, target);
1231
- }
1232
- }
1233
- };
1234
-
1235
- // ../atom.io/internal/src/set-state/set-atom-or-selector.ts
1236
- var setAtomOrSelector = (state, value, store) => {
1237
- switch (state.type) {
1238
- case `atom`:
1239
- case `mutable_atom`:
1240
- setAtom(state, value, store);
1241
- break;
1242
- case `selector`:
1243
- state.set(value);
1244
- break;
1195
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1196
+ if (isRootStore(parent)) {
1197
+ setEpochNumberOfAction(
1198
+ parent,
1199
+ child.transactionMeta.update.key,
1200
+ child.transactionMeta.update.epoch
1201
+ );
1202
+ const myTransaction = withdraw(store, {
1203
+ key: child.transactionMeta.update.key,
1204
+ type: `transaction`
1205
+ });
1206
+ myTransaction?.subject.next(child.transactionMeta.update);
1207
+ store.logger.info(
1208
+ `\u{1F6EC}`,
1209
+ `transaction`,
1210
+ child.transactionMeta.update.key,
1211
+ `Finished applying transaction.`
1212
+ );
1213
+ } else if (isChildStore(parent)) {
1214
+ parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1245
1215
  }
1216
+ parent.on.transactionApplying.next(null);
1246
1217
  };
1247
1218
 
1248
- // ../atom.io/internal/src/families/get-family-of-token.ts
1249
- function getFamilyOfToken(store, token) {
1250
- if (token.family) {
1251
- const family = store.families.get(token.family.key);
1252
- if (family) {
1253
- return family;
1254
- }
1255
- }
1219
+ // ../atom.io/internal/src/get-environment-data.ts
1220
+ function getEnvironmentData(store) {
1221
+ return {
1222
+ store
1223
+ };
1256
1224
  }
1257
1225
 
1258
- // ../atom.io/internal/src/set-state/set-into-store.ts
1259
- function setIntoStore(store, ...params) {
1226
+ // ../atom.io/internal/src/get-state/get-from-store.ts
1227
+ function getFromStore(store, ...params) {
1260
1228
  let token;
1261
1229
  let family;
1262
1230
  let key;
1263
- let value;
1264
- if (params.length === 2) {
1231
+ if (params.length === 1) {
1265
1232
  token = params[0];
1266
- value = params[1];
1267
- family = getFamilyOfToken(store, token) ?? null;
1268
- if (family) {
1269
- key = token.family ? parseJson(token.family.subKey) : null;
1270
- token = findInStore(store, family, key);
1271
- }
1272
1233
  } else {
1273
1234
  family = params[0];
1274
1235
  key = params[1];
1275
- value = params[2];
1276
1236
  token = findInStore(store, family, key);
1277
1237
  }
1278
1238
  if (`counterfeit` in token && `family` in token) {
1239
+ family = store.families.get(token.family.key);
1279
1240
  const subKey = token.family.subKey;
1280
1241
  const disposal = store.disposalTraces.buffer.find(
1281
1242
  (item) => item?.key === subKey
@@ -1284,282 +1245,338 @@ function setIntoStore(store, ...params) {
1284
1245
  `\u274C`,
1285
1246
  token.type,
1286
1247
  token.key,
1287
- `could not be set because it was not found in the store "${store.config.name}".`,
1248
+ `could not be retrieved because it was not found in the store "${store.config.name}".`,
1288
1249
  disposal ? `This state was previously disposed:
1289
1250
  ${disposal.trace}` : `No previous disposal trace was found.`
1290
1251
  );
1291
- return;
1292
- }
1293
- const rejectionTime = openOperation(store, token);
1294
- if (rejectionTime) {
1295
- const unsubscribe = store.on.operationClose.subscribe(
1296
- `waiting to set "${token.key}" at T-${rejectionTime}`,
1297
- () => {
1298
- unsubscribe();
1299
- store.logger.info(
1300
- `\u{1F7E2}`,
1301
- token.type,
1302
- token.key,
1303
- `resuming deferred setState from T-${rejectionTime}`
1304
- );
1305
- setIntoStore(store, token, value);
1252
+ switch (family.type) {
1253
+ case `atom_family`:
1254
+ case `mutable_atom_family`:
1255
+ return store.defaults.get(family.key);
1256
+ case `selector_family`:
1257
+ case `readonly_selector_family`: {
1258
+ if (store.defaults.has(family.key)) {
1259
+ return store.defaults.get(token.family.key);
1260
+ }
1261
+ const defaultValue = withdraw(store, family).default(subKey);
1262
+ store.defaults.set(family.key, defaultValue);
1263
+ return defaultValue;
1306
1264
  }
1307
- );
1308
- return;
1265
+ }
1309
1266
  }
1310
- const state = withdraw(token, store);
1311
- setAtomOrSelector(state, value, store);
1312
- closeOperation(store);
1267
+ return readOrComputeValue(store, withdraw(store, token));
1313
1268
  }
1314
1269
 
1315
- // ../atom.io/internal/src/ingest-updates/ingest-atom-update.ts
1316
- function ingestAtomUpdate(applying, atomUpdate, store) {
1317
- const { key, newValue, oldValue } = atomUpdate;
1318
- const value = newValue ;
1319
- const token = { key, type: `atom` };
1320
- if (atomUpdate.family) {
1321
- Object.assign(token, { family: atomUpdate.family });
1270
+ // ../atom.io/internal/src/junction.ts
1271
+ var Junction = class {
1272
+ a;
1273
+ b;
1274
+ cardinality;
1275
+ relations = /* @__PURE__ */ new Map();
1276
+ contents = /* @__PURE__ */ new Map();
1277
+ isAType;
1278
+ isBType;
1279
+ isContent;
1280
+ makeContentKey = (a, b) => `${a}:${b}`;
1281
+ warn;
1282
+ getRelatedKeys(key) {
1283
+ return this.relations.get(key);
1322
1284
  }
1323
- setIntoStore(store, token, value);
1324
- }
1325
-
1326
- // ../atom.io/internal/src/ingest-updates/ingest-creation-disposal.ts
1327
- function ingestCreationEvent(update, applying, store) {
1328
- switch (applying) {
1329
- case `newValue`: {
1330
- createInStore(update, store);
1331
- break;
1285
+ addRelation(a, b) {
1286
+ let aRelations = this.relations.get(a);
1287
+ let bRelations = this.relations.get(b);
1288
+ if (aRelations) {
1289
+ aRelations.add(b);
1290
+ } else {
1291
+ aRelations = /* @__PURE__ */ new Set([b]);
1292
+ this.relations.set(a, aRelations);
1332
1293
  }
1333
- case `oldValue`: {
1334
- disposeFromStore(store, update.token);
1335
- break;
1294
+ if (bRelations) {
1295
+ bRelations.add(a);
1296
+ } else {
1297
+ bRelations = /* @__PURE__ */ new Set([a]);
1298
+ this.relations.set(b, bRelations);
1336
1299
  }
1337
1300
  }
1338
- }
1339
- function ingestDisposalEvent(update, applying, store) {
1340
- switch (applying) {
1341
- case `newValue`: {
1342
- disposeFromStore(store, update.token);
1343
- break;
1301
+ deleteRelation(a, b) {
1302
+ const aRelations = this.relations.get(a);
1303
+ if (aRelations) {
1304
+ aRelations.delete(b);
1305
+ if (aRelations.size === 0) {
1306
+ this.relations.delete(a);
1307
+ }
1308
+ const bRelations = this.relations.get(b);
1309
+ if (bRelations) {
1310
+ bRelations.delete(a);
1311
+ if (bRelations.size === 0) {
1312
+ this.relations.delete(b);
1313
+ }
1314
+ }
1344
1315
  }
1345
- case `oldValue`: {
1346
- createInStore(update, store);
1347
- if (update.subType === `atom`) {
1348
- store.valueMap.set(update.token.key, update.value);
1316
+ }
1317
+ replaceRelationsUnsafely(x, ys) {
1318
+ this.relations.set(x, new Set(ys));
1319
+ for (const y of ys) {
1320
+ const yRelations = (/* @__PURE__ */ new Set()).add(x);
1321
+ this.relations.set(y, yRelations);
1322
+ }
1323
+ }
1324
+ replaceRelationsSafely(x, ys) {
1325
+ const xRelationsPrev = this.relations.get(x);
1326
+ let a = this.isAType?.(x) ? x : undefined;
1327
+ let b = a === undefined ? x : undefined;
1328
+ if (xRelationsPrev) {
1329
+ for (const y of xRelationsPrev) {
1330
+ a ??= y;
1331
+ b ??= y;
1332
+ const yRelations = this.relations.get(y);
1333
+ if (yRelations) {
1334
+ if (yRelations.size === 1) {
1335
+ this.relations.delete(y);
1336
+ } else {
1337
+ yRelations.delete(x);
1338
+ }
1339
+ this.contents.delete(this.makeContentKey(a, b));
1340
+ }
1341
+ }
1342
+ }
1343
+ this.relations.set(x, new Set(ys));
1344
+ for (const y of ys) {
1345
+ let yRelations = this.relations.get(y);
1346
+ if (yRelations) {
1347
+ yRelations.add(x);
1348
+ } else {
1349
+ yRelations = (/* @__PURE__ */ new Set()).add(x);
1350
+ this.relations.set(y, yRelations);
1349
1351
  }
1350
- break;
1351
1352
  }
1352
1353
  }
1353
- }
1354
- function createInStore(update, store) {
1355
- const { family: familyMeta } = update.token;
1356
- if (familyMeta) {
1357
- const family = store.families.get(familyMeta.key);
1358
- if (family) {
1359
- findInStore(store, family, parseJson(familyMeta.subKey));
1354
+ getContentInternal(contentKey) {
1355
+ return this.contents.get(contentKey);
1356
+ }
1357
+ setContent(contentKey, content) {
1358
+ this.contents.set(contentKey, content);
1359
+ }
1360
+ deleteContent(contentKey) {
1361
+ this.contents.delete(contentKey);
1362
+ }
1363
+ constructor(data, config) {
1364
+ this.a = data.between[0];
1365
+ this.b = data.between[1];
1366
+ this.cardinality = data.cardinality;
1367
+ if (!config?.externalStore) {
1368
+ this.relations = new Map(
1369
+ data.relations?.map(([x, ys]) => [x, new Set(ys)])
1370
+ );
1371
+ this.contents = new Map(data.contents);
1372
+ }
1373
+ this.isAType = config?.isAType ?? null;
1374
+ this.isBType = config?.isBType ?? null;
1375
+ this.isContent = config?.isContent ?? null;
1376
+ if (config?.makeContentKey) {
1377
+ this.makeContentKey = config.makeContentKey;
1378
+ }
1379
+ if (config?.externalStore) {
1380
+ const externalStore = config.externalStore;
1381
+ this.has = (a, b) => externalStore.has(a, b);
1382
+ this.addRelation = (a, b) => {
1383
+ externalStore.addRelation(a, b);
1384
+ };
1385
+ this.deleteRelation = (a, b) => {
1386
+ externalStore.deleteRelation(a, b);
1387
+ };
1388
+ this.replaceRelationsSafely = (a, bs) => {
1389
+ externalStore.replaceRelationsSafely(a, bs);
1390
+ };
1391
+ this.replaceRelationsUnsafely = (a, bs) => {
1392
+ externalStore.replaceRelationsUnsafely(a, bs);
1393
+ };
1394
+ this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
1395
+ key
1396
+ );
1397
+ if (externalStore.getContent) {
1398
+ this.getContentInternal = (contentKey) => {
1399
+ return externalStore.getContent(contentKey);
1400
+ };
1401
+ this.setContent = (contentKey, content) => {
1402
+ externalStore.setContent(contentKey, content);
1403
+ };
1404
+ this.deleteContent = (contentKey) => {
1405
+ externalStore.deleteContent(contentKey);
1406
+ };
1407
+ }
1408
+ for (const [x, ys] of data.relations ?? []) {
1409
+ let a = this.isAType?.(x) ? x : undefined;
1410
+ let b = a === undefined ? x : undefined;
1411
+ for (const y of ys) {
1412
+ a ??= y;
1413
+ b ??= y;
1414
+ this.addRelation(a, b);
1415
+ }
1416
+ }
1417
+ for (const [contentKey, content] of data.contents ?? []) {
1418
+ this.setContent(contentKey, content);
1419
+ }
1420
+ }
1421
+ if (config?.warn) {
1422
+ this.warn = config.warn;
1360
1423
  }
1361
1424
  }
1362
- }
1363
- function ingestMoleculeCreationEvent(update, applying, store) {
1364
- switch (applying) {
1365
- case `newValue`:
1366
- allocateIntoStore(store, update.provenance, update.key);
1367
- break;
1368
- case `oldValue`:
1369
- deallocateFromStore(store, update.key);
1370
- break;
1425
+ toJSON() {
1426
+ return {
1427
+ between: [this.a, this.b],
1428
+ cardinality: this.cardinality,
1429
+ relations: [...this.relations.entries()].map(
1430
+ ([a, b]) => [a, [...b]]
1431
+ ),
1432
+ contents: [...this.contents.entries()]
1433
+ };
1434
+ }
1435
+ set(...params) {
1436
+ let a;
1437
+ let b;
1438
+ let content;
1439
+ switch (params.length) {
1440
+ case 1: {
1441
+ const relation = params[0];
1442
+ a = relation[this.a];
1443
+ b = relation[this.b];
1444
+ content = undefined;
1445
+ break;
1446
+ }
1447
+ case 2: {
1448
+ const zeroth = params[0];
1449
+ if (typeof zeroth === `string`) {
1450
+ [a, b] = params;
1451
+ } else {
1452
+ a = zeroth[this.a];
1453
+ b = zeroth[this.b];
1454
+ content = params[1];
1455
+ }
1456
+ break;
1457
+ }
1458
+ default: {
1459
+ a = params[0];
1460
+ b = params[1];
1461
+ content = params[2];
1462
+ break;
1463
+ }
1464
+ }
1465
+ switch (this.cardinality) {
1466
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
1467
+ case `1:1`: {
1468
+ const bPrev = this.getRelatedKey(a);
1469
+ if (bPrev && bPrev !== b) this.delete(a, bPrev);
1470
+ }
1471
+ case `1:n`: {
1472
+ const aPrev = this.getRelatedKey(b);
1473
+ if (aPrev && aPrev !== a) this.delete(aPrev, b);
1474
+ }
1475
+ }
1476
+ if (content) {
1477
+ const contentKey = this.makeContentKey(a, b);
1478
+ this.setContent(contentKey, content);
1479
+ }
1480
+ this.addRelation(a, b);
1481
+ return this;
1371
1482
  }
1372
- }
1373
- function ingestMoleculeDisposalEvent(update, applying, store) {
1374
- switch (applying) {
1375
- case `newValue`:
1376
- deallocateFromStore(store, update.key);
1377
- break;
1378
- case `oldValue`:
1379
- {
1380
- const provenanceJson = update.provenance.map(parseJson);
1381
- allocateIntoStore(store, provenanceJson, update.key);
1382
- for (const [familyKey, value] of update.values) {
1383
- const family = store.families.get(familyKey);
1384
- if (family) {
1385
- findInStore(store, family, update.key);
1386
- const memberKey = `${familyKey}(${stringifyJson(update.key)})`;
1387
- store.valueMap.set(memberKey, value);
1388
- }
1483
+ delete(x, b) {
1484
+ b = typeof b === `string` ? b : x[this.b];
1485
+ const a = (
1486
+ // @ts-expect-error we deduce that this.a may index x
1487
+ typeof x === `string` ? x : x[this.a]
1488
+ );
1489
+ if (a === undefined && typeof b === `string`) {
1490
+ const bRelations = this.getRelatedKeys(b);
1491
+ if (bRelations) {
1492
+ for (const bRelation of bRelations) {
1493
+ this.delete(bRelation, b);
1389
1494
  }
1390
1495
  }
1391
- break;
1392
- }
1393
- }
1394
- function ingestMoleculeTransferEvent(update, applying, store) {
1395
- switch (applying) {
1396
- case `newValue`:
1397
- {
1398
- const provenance = update.to.length === 1 ? update.to[0] : update.to;
1399
- claimWithinStore(
1400
- store,
1401
- provenance,
1402
- update.key,
1403
- `exclusive`
1404
- );
1496
+ }
1497
+ if (typeof a === `string` && b === undefined) {
1498
+ const aRelations = this.getRelatedKeys(a);
1499
+ if (aRelations) {
1500
+ for (const aRelation of aRelations) {
1501
+ this.delete(a, aRelation);
1502
+ }
1405
1503
  }
1406
- break;
1407
- case `oldValue`:
1408
- {
1409
- const provenance = update.from.length === 1 ? update.from[0] : update.from;
1410
- claimWithinStore(
1411
- store,
1412
- provenance,
1413
- update.key,
1414
- `exclusive`
1504
+ }
1505
+ if (typeof a === `string` && typeof b === `string`) {
1506
+ this.deleteRelation(a, b);
1507
+ const contentKey = this.makeContentKey(a, b);
1508
+ this.deleteContent(contentKey);
1509
+ }
1510
+ return this;
1511
+ }
1512
+ getRelatedKey(key) {
1513
+ const relations = this.getRelatedKeys(key);
1514
+ if (relations) {
1515
+ if (relations.size > 1) {
1516
+ this.warn?.(
1517
+ `${relations.size} related keys were found for key "${key}": (${[
1518
+ ...relations
1519
+ ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
1415
1520
  );
1416
1521
  }
1417
- break;
1418
- }
1419
- }
1420
-
1421
- // ../atom.io/internal/src/ingest-updates/ingest-transaction-update.ts
1422
- function ingestTransactionUpdate(applying, transactionUpdate, store) {
1423
- const updates = transactionUpdate.updates ;
1424
- for (const updateFromTransaction of updates) {
1425
- switch (updateFromTransaction.type) {
1426
- case `atom_update`:
1427
- case `selector_update`:
1428
- ingestAtomUpdate(applying, updateFromTransaction, store);
1429
- break;
1430
- case `state_creation`:
1431
- ingestCreationEvent(updateFromTransaction, applying, store);
1432
- break;
1433
- case `state_disposal`:
1434
- ingestDisposalEvent(updateFromTransaction, applying, store);
1435
- break;
1436
- case `molecule_creation`:
1437
- ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1438
- break;
1439
- case `molecule_disposal`:
1440
- ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1441
- break;
1442
- case `molecule_transfer`:
1443
- ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
1444
- break;
1445
- case `transaction_update`:
1446
- ingestTransactionUpdate(applying, updateFromTransaction, store);
1522
+ let singleRelation;
1523
+ for (const relation of relations) {
1524
+ singleRelation = relation;
1447
1525
  break;
1526
+ }
1527
+ return singleRelation;
1448
1528
  }
1449
1529
  }
1450
- }
1451
-
1452
- // ../atom.io/internal/src/transaction/set-epoch-number.ts
1453
- function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1454
- const isRoot = isRootStore(store);
1455
- if (!isRoot) {
1456
- return;
1457
- }
1458
- const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1459
- if (continuityKey !== undefined) {
1460
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1461
- }
1462
- }
1463
-
1464
- // ../atom.io/internal/src/transaction/apply-transaction.ts
1465
- var applyTransaction = (output, store) => {
1466
- const child = newest(store);
1467
- const { parent } = child;
1468
- if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1469
- store.logger.warn(
1470
- `\u{1F41E}`,
1471
- `transaction`,
1472
- `???`,
1473
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1474
- );
1475
- return;
1476
- }
1477
- child.transactionMeta.phase = `applying`;
1478
- child.transactionMeta.update.output = output;
1479
- parent.child = null;
1480
- parent.on.transactionApplying.next(child.transactionMeta);
1481
- const { updates } = child.transactionMeta.update;
1482
- store.logger.info(
1483
- `\u{1F6C4}`,
1484
- `transaction`,
1485
- child.transactionMeta.update.key,
1486
- `Applying transaction with ${updates.length} updates:`,
1487
- updates
1488
- );
1489
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1490
- if (isRootStore(parent)) {
1491
- setEpochNumberOfAction(
1492
- child.transactionMeta.update.key,
1493
- child.transactionMeta.update.epoch,
1494
- parent
1495
- );
1496
- const myTransaction = withdraw(
1497
- { key: child.transactionMeta.update.key, type: `transaction` },
1498
- store
1499
- );
1500
- myTransaction?.subject.next(child.transactionMeta.update);
1501
- store.logger.info(
1502
- `\u{1F6EC}`,
1503
- `transaction`,
1504
- child.transactionMeta.update.key,
1505
- `Finished applying transaction.`
1506
- );
1507
- } else if (isChildStore(parent)) {
1508
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1530
+ replaceRelations(x, relations, config) {
1531
+ const hasContent = !Array.isArray(relations);
1532
+ const ys = hasContent ? Object.keys(relations) : relations;
1533
+ if (config?.reckless) {
1534
+ this.replaceRelationsUnsafely(x, ys);
1535
+ } else {
1536
+ this.replaceRelationsSafely(x, ys);
1537
+ }
1538
+ if (hasContent) {
1539
+ for (const y of ys) {
1540
+ const contentKey = this.makeContentKey(x, y);
1541
+ const content = relations[y];
1542
+ this.setContent(contentKey, content);
1543
+ }
1544
+ }
1545
+ return this;
1509
1546
  }
1510
- parent.on.transactionApplying.next(null);
1511
- };
1512
-
1513
- // ../atom.io/internal/src/get-environment-data.ts
1514
- function getEnvironmentData(store) {
1515
- return {
1516
- store
1517
- };
1518
- }
1519
-
1520
- // ../atom.io/internal/src/get-state/get-from-store.ts
1521
- function getFromStore(store, ...params) {
1522
- let token;
1523
- let family;
1524
- let key;
1525
- if (params.length === 1) {
1526
- token = params[0];
1527
- } else {
1528
- family = params[0];
1529
- key = params[1];
1530
- token = findInStore(store, family, key);
1547
+ getContent(a, b) {
1548
+ const contentKey = this.makeContentKey(a, b);
1549
+ return this.getContentInternal(contentKey);
1531
1550
  }
1532
- if (`counterfeit` in token && `family` in token) {
1533
- family = store.families.get(token.family.key);
1534
- const subKey = token.family.subKey;
1535
- const disposal = store.disposalTraces.buffer.find(
1536
- (item) => item?.key === subKey
1537
- );
1538
- store.logger.error(
1539
- `\u274C`,
1540
- token.type,
1541
- token.key,
1542
- `could not be retrieved because it was not found in the store "${store.config.name}".`,
1543
- disposal ? `This state was previously disposed:
1544
- ${disposal.trace}` : `No previous disposal trace was found.`
1545
- );
1546
- switch (family.type) {
1547
- case `atom_family`:
1548
- case `mutable_atom_family`:
1549
- return store.defaults.get(family.key);
1550
- case `selector_family`:
1551
- case `readonly_selector_family`: {
1552
- if (store.defaults.has(family.key)) {
1553
- return store.defaults.get(token.family.key);
1554
- }
1555
- const defaultValue = withdraw(family, store).default(subKey);
1556
- store.defaults.set(family.key, defaultValue);
1557
- return defaultValue;
1551
+ getRelationEntries(input) {
1552
+ const a = input[this.a];
1553
+ const b = input[this.b];
1554
+ if (a !== undefined && b === undefined) {
1555
+ const aRelations = this.getRelatedKeys(a);
1556
+ if (aRelations) {
1557
+ return [...aRelations].map((aRelation) => {
1558
+ return [aRelation, this.getContent(a, aRelation)];
1559
+ });
1560
+ }
1561
+ }
1562
+ if (a === undefined && b !== undefined) {
1563
+ const bRelations = this.getRelatedKeys(b);
1564
+ if (bRelations) {
1565
+ return [...bRelations].map((bRelation) => {
1566
+ return [bRelation, this.getContent(bRelation, b)];
1567
+ });
1558
1568
  }
1559
1569
  }
1570
+ return [];
1571
+ }
1572
+ has(a, b) {
1573
+ if (b) {
1574
+ const setA = this.getRelatedKeys(a);
1575
+ return setA?.has(b) ?? false;
1576
+ }
1577
+ return this.relations.has(a);
1560
1578
  }
1561
- return readOrComputeValue(withdraw(token, store), store);
1562
- }
1579
+ };
1563
1580
 
1564
1581
  // ../atom.io/internal/src/lazy-map.ts
1565
1582
  var LazyMap = class extends Map {
@@ -1596,7 +1613,7 @@ var LazyMap = class extends Map {
1596
1613
  };
1597
1614
 
1598
1615
  // ../atom.io/internal/src/transaction/build-transaction.ts
1599
- var buildTransaction = (key, params, store, id) => {
1616
+ var buildTransaction = (store, key, params, id) => {
1600
1617
  const parent = newest(store);
1601
1618
  const childBase = {
1602
1619
  parent,
@@ -1635,7 +1652,7 @@ var buildTransaction = (key, params, store, id) => {
1635
1652
  }),
1636
1653
  miscResources: new LazyMap(parent.miscResources)
1637
1654
  };
1638
- const epoch = getEpochNumberOfAction(key, store);
1655
+ const epoch = getEpochNumberOfAction(store, key);
1639
1656
  const transactionMeta = {
1640
1657
  phase: `building`,
1641
1658
  update: {
@@ -1652,9 +1669,8 @@ var buildTransaction = (key, params, store, id) => {
1652
1669
  set: (...ps) => {
1653
1670
  setIntoStore(child, ...ps);
1654
1671
  },
1655
- run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1672
+ run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
1656
1673
  find: (token, k) => findInStore(child, token, k),
1657
- seek: (token, k) => seekInStore(child, token, k),
1658
1674
  json: (token) => getJsonToken(child, token),
1659
1675
  dispose: (...ps) => {
1660
1676
  disposeFromStore(child, ...ps);
@@ -1677,12 +1693,12 @@ var buildTransaction = (key, params, store, id) => {
1677
1693
  };
1678
1694
 
1679
1695
  // ../atom.io/internal/src/transaction/create-transaction.ts
1680
- function createTransaction(options, store) {
1696
+ function createTransaction(store, options) {
1681
1697
  const newTransaction = {
1682
1698
  key: options.key,
1683
1699
  type: `transaction`,
1684
1700
  run: (params, id) => {
1685
- const childStore = buildTransaction(options.key, params, store, id);
1701
+ const childStore = buildTransaction(store, options.key, params, id);
1686
1702
  try {
1687
1703
  const target2 = newest(store);
1688
1704
  const { toolkit } = childStore.transactionMeta;
@@ -1695,7 +1711,7 @@ function createTransaction(options, store) {
1695
1711
  throw thrown;
1696
1712
  }
1697
1713
  },
1698
- install: (s) => createTransaction(options, s),
1714
+ install: (s) => createTransaction(s, options),
1699
1715
  subject: new Subject()
1700
1716
  };
1701
1717
  const target = newest(store);
@@ -1706,13 +1722,18 @@ function createTransaction(options, store) {
1706
1722
  }
1707
1723
 
1708
1724
  // ../atom.io/internal/src/transaction/get-epoch-number.ts
1709
- function getEpochNumberOfAction(transactionKey, store) {
1725
+ function getEpochNumberOfAction(store, transactionKey) {
1710
1726
  const isRoot = isRootStore(store);
1711
1727
  const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
1712
1728
  const epoch = isRoot && continuity !== undefined ? store.transactionMeta.epoch.get(continuity) : undefined;
1713
1729
  return epoch;
1714
1730
  }
1715
1731
 
1732
+ // ../atom.io/src/transaction.ts
1733
+ function transaction(options) {
1734
+ return createTransaction(IMPLICIT.STORE, options);
1735
+ }
1736
+
1716
1737
  // ../atom.io/internal/src/store/store.ts
1717
1738
  var Store = class {
1718
1739
  parent = null;
@@ -1881,7 +1902,7 @@ var IMPLICIT = {
1881
1902
  };
1882
1903
 
1883
1904
  // ../atom.io/internal/src/store/withdraw.ts
1884
- function withdraw(token, store) {
1905
+ function withdraw(store, token) {
1885
1906
  let withdrawn;
1886
1907
  let target = store;
1887
1908
  while (target !== null) {
@@ -2009,40 +2030,37 @@ function disposeFromStore(store, ...params) {
2009
2030
  token = maybeToken;
2010
2031
  }
2011
2032
  try {
2012
- withdraw(token, store);
2033
+ withdraw(store, token);
2013
2034
  } catch (thrown) {
2014
2035
  store.logger.error(
2015
2036
  `\u274C`,
2016
2037
  token.type,
2017
2038
  token.key,
2018
2039
  `could not be disposed because it was not found in the store "${store.config.name}".`
2019
- // disposal
2020
- // ? `\n This state was most recently disposed\n${disposal.trace}`
2021
- // : `No previous disposal trace was found.`,
2022
2040
  );
2023
2041
  return;
2024
2042
  }
2025
2043
  switch (token.type) {
2026
2044
  case `atom`:
2027
2045
  case `mutable_atom`:
2028
- disposeAtom(token, store);
2046
+ disposeAtom(store, token);
2029
2047
  break;
2030
2048
  case `selector`:
2031
2049
  case `readonly_selector`:
2032
- disposeSelector(token, store);
2050
+ disposeSelector(store, token);
2033
2051
  break;
2034
2052
  }
2035
2053
  }
2036
2054
 
2037
2055
  // ../atom.io/internal/src/keys.ts
2038
- var isAtomKey = (key, store) => newest(store).atoms.has(key);
2039
- var isSelectorKey = (key, store) => newest(store).selectors.has(key);
2040
- var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
2041
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
2056
+ var isAtomKey = (store, key) => newest(store).atoms.has(key);
2057
+ var isSelectorKey = (store, key) => newest(store).selectors.has(key);
2058
+ var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
2059
+ var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
2042
2060
 
2043
2061
  // ../atom.io/internal/src/selector/get-selector-dependency-keys.ts
2044
2062
  var getSelectorDependencyKeys = (key, store) => {
2045
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
2063
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
2046
2064
  return sources;
2047
2065
  };
2048
2066
 
@@ -2059,7 +2077,7 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
2059
2077
  continue;
2060
2078
  }
2061
2079
  covered.add(indirectDependencyKey);
2062
- if (!isAtomKey(indirectDependencyKey, store)) {
2080
+ if (!isAtomKey(store, indirectDependencyKey)) {
2063
2081
  indirectDependencyKeys.push(
2064
2082
  ...getSelectorDependencyKeys(indirectDependencyKey, store)
2065
2083
  );
@@ -2074,7 +2092,7 @@ var traceAllSelectorAtoms = (selector, store) => {
2074
2092
  const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
2075
2093
  const covered = /* @__PURE__ */ new Set();
2076
2094
  return directDependencyKeys.flatMap(
2077
- (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(depKey, covered, store)
2095
+ (depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store)
2078
2096
  );
2079
2097
  };
2080
2098
 
@@ -2121,8 +2139,8 @@ var registerSelector = (selectorKey, covered, store) => ({
2121
2139
  } else {
2122
2140
  [dependency] = params;
2123
2141
  }
2124
- const dependencyState = withdraw(dependency, store);
2125
- const dependencyValue = readOrComputeValue(dependencyState, store);
2142
+ const dependencyState = withdraw(store, dependency);
2143
+ const dependencyValue = readOrComputeValue(store, dependencyState);
2126
2144
  store.logger.info(
2127
2145
  `\u{1F50C}`,
2128
2146
  `selector`,
@@ -2153,18 +2171,13 @@ var registerSelector = (selectorKey, covered, store) => ({
2153
2171
  const family = params[0];
2154
2172
  const key = params[1];
2155
2173
  value = params[2];
2156
- const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(store, family, key) : seekInStore(store, family, key);
2157
- if (!maybeToken) {
2158
- throw new NotFoundError(family, key, store);
2159
- }
2160
- token = maybeToken;
2174
+ token = findInStore(store, family, key);
2161
2175
  }
2162
2176
  const target = newest(store);
2163
- const state = withdraw(token, target);
2164
- setAtomOrSelector(state, value, target);
2177
+ const state = withdraw(target, token);
2178
+ setAtomOrSelector(target, state, value);
2165
2179
  },
2166
2180
  find: (token, key) => findInStore(store, token, key),
2167
- seek: (token, key) => seekInStore(store, token, key),
2168
2181
  json: (token) => getJsonToken(store, token)
2169
2182
  });
2170
2183
 
@@ -2173,14 +2186,10 @@ var createReadonlySelector = (store, options, family) => {
2173
2186
  const target = newest(store);
2174
2187
  const subject = new Subject();
2175
2188
  const covered = /* @__PURE__ */ new Set();
2176
- const { get, find, seek, json } = registerSelector(
2177
- options.key,
2178
- covered,
2179
- target
2180
- );
2189
+ const { get, find, json } = registerSelector(options.key, covered, target);
2181
2190
  const getSelf = () => {
2182
- const value = options.get({ get, find, seek, json });
2183
- cacheValue(options.key, value, subject, newest(store));
2191
+ const value = options.get({ get, find, json });
2192
+ cacheValue(newest(store), options.key, value, subject);
2184
2193
  covered.clear();
2185
2194
  return value;
2186
2195
  };
@@ -2217,11 +2226,11 @@ var createWritableSelector = (store, options, family) => {
2217
2226
  const subject = new Subject();
2218
2227
  const covered = /* @__PURE__ */ new Set();
2219
2228
  const setterToolkit = registerSelector(options.key, covered, target);
2220
- const { find, get, seek, json } = setterToolkit;
2221
- const getterToolkit = { find, get, seek, json };
2229
+ const { find, get, json } = setterToolkit;
2230
+ const getterToolkit = { find, get, json };
2222
2231
  const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
2223
2232
  const value = getFn(getterToolkit);
2224
- cacheValue(options.key, value, subject, innerTarget);
2233
+ cacheValue(innerTarget, options.key, value, subject);
2225
2234
  covered.clear();
2226
2235
  return value;
2227
2236
  };
@@ -2239,7 +2248,7 @@ var createWritableSelector = (store, options, family) => {
2239
2248
  newValue,
2240
2249
  `)`
2241
2250
  );
2242
- cacheValue(options.key, newValue, subject, innerTarget);
2251
+ cacheValue(innerTarget, options.key, newValue, subject);
2243
2252
  markDone(innerTarget, options.key);
2244
2253
  if (isRootStore(innerTarget)) {
2245
2254
  subject.next({ newValue, oldValue });
@@ -2282,10 +2291,10 @@ function createStandaloneSelector(store, options) {
2282
2291
  }
2283
2292
 
2284
2293
  // ../atom.io/internal/src/selector/dispose-selector.ts
2285
- function disposeSelector(selectorToken, store) {
2294
+ function disposeSelector(store, selectorToken) {
2286
2295
  const target = newest(store);
2287
2296
  const { key } = selectorToken;
2288
- const selector = withdraw(selectorToken, target);
2297
+ const selector = withdraw(target, selectorToken);
2289
2298
  if (!selector.family) {
2290
2299
  store.logger.error(
2291
2300
  `\u274C`,
@@ -2298,23 +2307,31 @@ function disposeSelector(selectorToken, store) {
2298
2307
  if (molecule) {
2299
2308
  target.moleculeData.delete(selector.family.subKey, selector.family.key);
2300
2309
  }
2310
+ let familyToken;
2301
2311
  switch (selectorToken.type) {
2302
2312
  case `selector`:
2303
2313
  {
2304
2314
  target.selectors.delete(key);
2305
- withdraw(
2306
- { key: selector.family.key, type: `selector_family` },
2307
- store
2308
- );
2315
+ familyToken = {
2316
+ key: selector.family.key,
2317
+ type: `selector_family`
2318
+ };
2319
+ const family = withdraw(store, familyToken);
2320
+ family.subject.next({
2321
+ type: `state_disposal`,
2322
+ subType: `selector`,
2323
+ token: selectorToken
2324
+ });
2309
2325
  }
2310
2326
  break;
2311
2327
  case `readonly_selector`:
2312
2328
  {
2313
2329
  target.readonlySelectors.delete(key);
2314
- const family = withdraw(
2315
- { key: selector.family.key, type: `readonly_selector_family` },
2316
- store
2317
- );
2330
+ familyToken = {
2331
+ key: selector.family.key,
2332
+ type: `readonly_selector_family`
2333
+ };
2334
+ const family = withdraw(store, familyToken);
2318
2335
  family.subject.next({
2319
2336
  type: `state_disposal`,
2320
2337
  subType: `selector`,
@@ -2383,7 +2400,6 @@ function createWritableSelectorFamily(store, options, internalRoles) {
2383
2400
  return getFn({
2384
2401
  get: (...ps) => getFromStore(store, ...ps),
2385
2402
  find: (token, k) => findInStore(store, token, k),
2386
- seek: (token, k) => seekInStore(store, token, k),
2387
2403
  json: (token) => getJsonToken(store, token)
2388
2404
  });
2389
2405
  }
@@ -2393,7 +2409,7 @@ function createWritableSelectorFamily(store, options, internalRoles) {
2393
2409
  }
2394
2410
 
2395
2411
  // ../atom.io/json/src/select-json-family.ts
2396
- function selectJsonFamily(atomFamilyToken, transform, store = IMPLICIT.STORE) {
2412
+ function selectJsonFamily(store, atomFamilyToken, transform) {
2397
2413
  const jsonFamily = createWritableSelectorFamily(
2398
2414
  store,
2399
2415
  {
@@ -2408,15 +2424,6 @@ function selectJsonFamily(atomFamilyToken, transform, store = IMPLICIT.STORE) {
2408
2424
  },
2409
2425
  [`mutable`, `json`]
2410
2426
  );
2411
- const atomFamily2 = withdraw(atomFamilyToken, store);
2412
- atomFamily2.subject.subscribe(
2413
- `store=${store.config.name}::json-selector-family`,
2414
- (event) => {
2415
- if (event.token.family) {
2416
- seekInStore(store, jsonFamily, parseJson(event.token.family.subKey));
2417
- }
2418
- }
2419
- );
2420
2427
  return jsonFamily;
2421
2428
  }
2422
2429
 
@@ -2425,7 +2432,7 @@ var parseJson = (str) => JSON.parse(str);
2425
2432
  var stringifyJson = (json) => JSON.stringify(json);
2426
2433
 
2427
2434
  // ../atom.io/internal/src/subscribe/recall-state.ts
2428
- var recallState = (state, store) => {
2435
+ var recallState = (store, state) => {
2429
2436
  const target = newest(store);
2430
2437
  if (target.operation.open) {
2431
2438
  return target.operation.prev.get(state.key);
@@ -2434,7 +2441,7 @@ var recallState = (state, store) => {
2434
2441
  };
2435
2442
 
2436
2443
  // ../atom.io/internal/src/subscribe/subscribe-to-root-atoms.ts
2437
- var subscribeToRootAtoms = (selector, store) => {
2444
+ var subscribeToRootAtoms = (store, selector) => {
2438
2445
  const target = newest(store);
2439
2446
  const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map(
2440
2447
  (atomKey) => {
@@ -2458,8 +2465,8 @@ var subscribeToRootAtoms = (selector, store) => {
2458
2465
  `->`,
2459
2466
  atomChange.newValue
2460
2467
  );
2461
- const oldValue = recallState(selector, target);
2462
- const newValue = readOrComputeValue(selector, target);
2468
+ const oldValue = recallState(target, selector);
2469
+ const newValue = readOrComputeValue(target, selector);
2463
2470
  store.logger.info(
2464
2471
  `\u2728`,
2465
2472
  selector.type,
@@ -2478,7 +2485,7 @@ var subscribeToRootAtoms = (selector, store) => {
2478
2485
  };
2479
2486
 
2480
2487
  // ../atom.io/internal/src/subscribe/subscribe-to-state.ts
2481
- function subscribeToState(token, handleUpdate, key, store) {
2488
+ function subscribeToState(store, token, key, handleUpdate) {
2482
2489
  function safelyHandleUpdate(update) {
2483
2490
  if (store.operation.open) {
2484
2491
  const unsubscribe2 = store.on.operationClose.subscribe(
@@ -2492,17 +2499,17 @@ function subscribeToState(token, handleUpdate, key, store) {
2492
2499
  handleUpdate(update);
2493
2500
  }
2494
2501
  }
2495
- const state = withdraw(token, store);
2502
+ const state = withdraw(store, token);
2496
2503
  store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
2497
2504
  const isSelector = state.type === `selector` || state.type === `readonly_selector`;
2498
2505
  let dependencyUnsubFunctions = null;
2499
2506
  let updateHandler = safelyHandleUpdate;
2500
2507
  if (isSelector) {
2501
- dependencyUnsubFunctions = subscribeToRootAtoms(state, store);
2508
+ dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
2502
2509
  updateHandler = (update) => {
2503
2510
  if (dependencyUnsubFunctions) {
2504
2511
  dependencyUnsubFunctions.length = 0;
2505
- dependencyUnsubFunctions.push(...subscribeToRootAtoms(state, store));
2512
+ dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
2506
2513
  }
2507
2514
  safelyHandleUpdate(update);
2508
2515
  };
@@ -2526,8 +2533,8 @@ function subscribeToState(token, handleUpdate, key, store) {
2526
2533
  }
2527
2534
 
2528
2535
  // ../atom.io/internal/src/subscribe/subscribe-to-timeline.ts
2529
- var subscribeToTimeline = (token, handleUpdate, key, store) => {
2530
- const tl = withdraw(token, store);
2536
+ var subscribeToTimeline = (store, token, key, handleUpdate) => {
2537
+ const tl = withdraw(store, token);
2531
2538
  store.logger.info(`\u{1F440}`, `timeline`, token.key, `Adding subscription "${key}"`);
2532
2539
  const unsubscribe = tl.subject.subscribe(key, handleUpdate);
2533
2540
  return () => {
@@ -2578,7 +2585,9 @@ var Tracker = class {
2578
2585
  }
2579
2586
  );
2580
2587
  this.unsubscribeFromState = subscribeToState(
2588
+ target,
2581
2589
  mutableState,
2590
+ subscriptionKey,
2582
2591
  (update) => {
2583
2592
  if (update.newValue !== update.oldValue) {
2584
2593
  this.unsubscribeFromInnerValue();
@@ -2589,15 +2598,15 @@ var Tracker = class {
2589
2598
  }
2590
2599
  );
2591
2600
  }
2592
- },
2593
- subscriptionKey,
2594
- target
2601
+ }
2595
2602
  );
2596
2603
  }
2597
2604
  updateCore(mutableState, latestUpdateState, target) {
2598
2605
  const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2599
2606
  subscribeToState(
2607
+ target,
2600
2608
  latestUpdateState,
2609
+ subscriptionKey,
2601
2610
  ({ newValue, oldValue }) => {
2602
2611
  const timelineId = target.timelineTopics.getRelatedKey(
2603
2612
  latestUpdateState.key
@@ -2606,7 +2615,9 @@ var Tracker = class {
2606
2615
  const timelineData = target.timelines.get(timelineId);
2607
2616
  if (timelineData?.timeTraveling) {
2608
2617
  const unsubscribe2 = subscribeToTimeline(
2618
+ target,
2609
2619
  { key: timelineId, type: `timeline` },
2620
+ subscriptionKey,
2610
2621
  (update) => {
2611
2622
  unsubscribe2();
2612
2623
  setIntoStore(target, mutableState, (transceiver) => {
@@ -2617,9 +2628,7 @@ var Tracker = class {
2617
2628
  }
2618
2629
  return transceiver;
2619
2630
  });
2620
- },
2621
- subscriptionKey,
2622
- target
2631
+ }
2623
2632
  );
2624
2633
  return;
2625
2634
  }
@@ -2647,14 +2656,12 @@ var Tracker = class {
2647
2656
  }
2648
2657
  }
2649
2658
  );
2650
- },
2651
- subscriptionKey,
2652
- target
2659
+ }
2653
2660
  );
2654
2661
  }
2655
2662
  mutableState;
2656
2663
  latestUpdateState;
2657
- dispose;
2664
+ [Symbol.dispose];
2658
2665
  constructor(mutableState, store) {
2659
2666
  this.mutableState = mutableState;
2660
2667
  const target = newest(store);
@@ -2662,7 +2669,7 @@ var Tracker = class {
2662
2669
  this.observeCore(mutableState, this.latestUpdateState, target);
2663
2670
  this.updateCore(mutableState, this.latestUpdateState, target);
2664
2671
  target.trackers.set(mutableState.key, this);
2665
- this.dispose = () => {
2672
+ this[Symbol.dispose] = () => {
2666
2673
  this.unsubscribeFromInnerValue();
2667
2674
  this.unsubscribeFromState();
2668
2675
  target.trackers.delete(mutableState.key);
@@ -2709,8 +2716,8 @@ function createMutableAtom(store, options, family) {
2709
2716
  }
2710
2717
  const initialValue = options.default();
2711
2718
  target.atoms.set(newAtom.key, newAtom);
2712
- markAtomAsDefault(options.key, store);
2713
- cacheValue(options.key, initialValue, subject, target);
2719
+ markAtomAsDefault(store, options.key);
2720
+ cacheValue(target, options.key, initialValue, subject);
2714
2721
  const token = deposit(newAtom);
2715
2722
  if (options.effects) {
2716
2723
  let effectIndex = 0;
@@ -2720,7 +2727,7 @@ function createMutableAtom(store, options, family) {
2720
2727
  setSelf: (next) => {
2721
2728
  setIntoStore(store, token, next);
2722
2729
  },
2723
- onSet: (handle) => subscribeToState(token, handle, `effect[${effectIndex}]`, store)
2730
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2724
2731
  });
2725
2732
  if (cleanup) {
2726
2733
  cleanupFunctions.push(cleanup);
@@ -2742,6 +2749,7 @@ function createMutableAtom(store, options, family) {
2742
2749
 
2743
2750
  // ../atom.io/internal/src/mutable/tracker-family.ts
2744
2751
  var FamilyTracker = class {
2752
+ trackers = /* @__PURE__ */ new Map();
2745
2753
  Update;
2746
2754
  latestUpdateAtoms;
2747
2755
  mutableAtoms;
@@ -2754,26 +2762,27 @@ var FamilyTracker = class {
2754
2762
  },
2755
2763
  [`mutable`, `updates`]
2756
2764
  );
2757
- this.latestUpdateAtoms = withdraw(updateAtoms, store);
2765
+ this.latestUpdateAtoms = withdraw(store, updateAtoms);
2758
2766
  this.mutableAtoms = mutableAtoms;
2759
2767
  this.mutableAtoms.subject.subscribe(
2760
2768
  `store=${store.config.name}::tracker-atom-family`,
2761
2769
  (event) => {
2762
- if (event.token.family) {
2763
- const key = parseJson(event.token.family.subKey);
2764
- seekInStore(store, this.latestUpdateAtoms, key);
2765
- new Tracker(event.token, store);
2766
- }
2767
- }
2768
- );
2769
- this.latestUpdateAtoms.subject.subscribe(
2770
- `store=${store.config.name}::tracker-atom-family`,
2771
- (event) => {
2772
- if (event.token.family) {
2773
- const key = parseJson(event.token.family.subKey);
2774
- const mutableAtomToken = seekInStore(store, this.mutableAtoms, key);
2775
- if (mutableAtomToken) {
2776
- new Tracker(mutableAtomToken, store);
2770
+ const { type, token } = event;
2771
+ if (token.family) {
2772
+ const key = parseJson(token.family.subKey);
2773
+ switch (type) {
2774
+ case `state_creation`:
2775
+ this.trackers.set(key, new Tracker(token, store));
2776
+ break;
2777
+ case `state_disposal`:
2778
+ {
2779
+ const tracker = this.trackers.get(key);
2780
+ if (tracker) {
2781
+ tracker[Symbol.dispose]();
2782
+ this.trackers.delete(key);
2783
+ }
2784
+ }
2785
+ break;
2777
2786
  }
2778
2787
  }
2779
2788
  }
@@ -2826,7 +2835,7 @@ function createMutableAtomFamily(store, options, internalRoles) {
2826
2835
  internalRoles
2827
2836
  });
2828
2837
  store.families.set(options.key, atomFamily2);
2829
- selectJsonFamily(atomFamily2, options, store);
2838
+ selectJsonFamily(store, atomFamily2, options);
2830
2839
  new FamilyTracker(atomFamily2, store);
2831
2840
  return familyToken;
2832
2841
  }
@@ -2848,7 +2857,7 @@ var getJsonToken = (store, mutableAtomToken) => {
2848
2857
  key: jsonFamilyKey,
2849
2858
  type: `selector_family`
2850
2859
  };
2851
- const family = withdraw(jsonFamilyToken, target);
2860
+ const family = withdraw(target, jsonFamilyToken);
2852
2861
  const subKey = JSON.parse(mutableAtomToken.family.subKey);
2853
2862
  const jsonToken = findInStore(store, family, subKey);
2854
2863
  return jsonToken;
@@ -2879,7 +2888,7 @@ function isTransceiver(value) {
2879
2888
  }
2880
2889
 
2881
2890
  // ../atom.io/internal/src/set-state/copy-mutable-if-needed.ts
2882
- function copyMutableIfNeeded(atom2, origin, target) {
2891
+ function copyMutableIfNeeded(target, atom2, origin) {
2883
2892
  const originValue = origin.valueMap.get(atom2.key);
2884
2893
  const targetValue = target.valueMap.get(atom2.key);
2885
2894
  if (originValue === targetValue) {
@@ -2897,7 +2906,7 @@ function copyMutableIfNeeded(atom2, origin, target) {
2897
2906
  }
2898
2907
 
2899
2908
  // ../atom.io/internal/src/caching.ts
2900
- function cacheValue(key, value, subject, target) {
2909
+ function cacheValue(target, key, value, subject) {
2901
2910
  const currentValue = target.valueMap.get(key);
2902
2911
  if (currentValue instanceof Future) {
2903
2912
  const future = currentValue;
@@ -2907,7 +2916,7 @@ function cacheValue(key, value, subject, target) {
2907
2916
  const future = new Future(value);
2908
2917
  target.valueMap.set(key, future);
2909
2918
  future.then((resolved) => {
2910
- cacheValue(key, resolved, subject, target);
2919
+ cacheValue(target, key, resolved, subject);
2911
2920
  subject.next({ newValue: resolved, oldValue: future });
2912
2921
  }).catch((thrown) => {
2913
2922
  target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
@@ -2921,7 +2930,7 @@ var readCachedValue = (token, target) => {
2921
2930
  let value = target.valueMap.get(token.key);
2922
2931
  if (token.type === `mutable_atom` && isChildStore(target)) {
2923
2932
  const { parent } = target;
2924
- const copiedValue = copyMutableIfNeeded(token, parent, target);
2933
+ const copiedValue = copyMutableIfNeeded(target, token, parent);
2925
2934
  value = copiedValue;
2926
2935
  }
2927
2936
  return value;
@@ -2944,15 +2953,15 @@ var evictCachedValue = (key, target) => {
2944
2953
  };
2945
2954
 
2946
2955
  // ../atom.io/internal/src/atom/is-default.ts
2947
- var isAtomDefault = (key, store) => {
2956
+ var isAtomDefault = (store, key) => {
2948
2957
  const core = newest(store);
2949
2958
  return core.atomsThatAreDefault.has(key);
2950
2959
  };
2951
- var markAtomAsDefault = (key, store) => {
2960
+ var markAtomAsDefault = (store, key) => {
2952
2961
  const core = newest(store);
2953
2962
  core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
2954
2963
  };
2955
- var markAtomAsNotDefault = (key, store) => {
2964
+ var markAtomAsNotDefault = (store, key) => {
2956
2965
  const core = newest(store);
2957
2966
  core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
2958
2967
  core.atomsThatAreDefault.delete(key);
@@ -3000,8 +3009,8 @@ function createRegularAtom(store, options, family) {
3000
3009
  initialValue = options.default();
3001
3010
  }
3002
3011
  target.atoms.set(newAtom.key, newAtom);
3003
- markAtomAsDefault(options.key, store);
3004
- cacheValue(options.key, initialValue, subject, target);
3012
+ markAtomAsDefault(store, options.key);
3013
+ cacheValue(target, options.key, initialValue, subject);
3005
3014
  const token = deposit(newAtom);
3006
3015
  if (options.effects) {
3007
3016
  let effectIndex = 0;
@@ -3011,7 +3020,7 @@ function createRegularAtom(store, options, family) {
3011
3020
  setSelf: (next) => {
3012
3021
  setIntoStore(store, token, next);
3013
3022
  },
3014
- onSet: (handle) => subscribeToState(token, handle, `effect[${effectIndex}]`, store)
3023
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
3015
3024
  });
3016
3025
  if (cleanup) {
3017
3026
  cleanupFunctions.push(cleanup);
@@ -3041,16 +3050,16 @@ function createStandaloneAtom(store, options) {
3041
3050
  }
3042
3051
 
3043
3052
  // ../atom.io/internal/src/atom/dispose-atom.ts
3044
- function disposeAtom(atomToken, store) {
3053
+ function disposeAtom(store, atomToken) {
3045
3054
  const target = newest(store);
3046
3055
  const { key, family } = atomToken;
3047
- const atom2 = withdraw(atomToken, target);
3056
+ const atom2 = withdraw(target, atomToken);
3048
3057
  if (!family) {
3049
3058
  store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
3050
3059
  } else {
3051
3060
  atom2.cleanup?.();
3052
3061
  const lastValue = store.valueMap.get(atom2.key);
3053
- const atomFamily2 = withdraw({ key: family.key, type: `atom_family` }, store);
3062
+ const atomFamily2 = withdraw(store, { key: family.key, type: `atom_family` });
3054
3063
  const disposal = {
3055
3064
  type: `state_disposal`,
3056
3065
  subType: `atom`,
@@ -3063,242 +3072,25 @@ function disposeAtom(atomToken, store) {
3063
3072
  target.valueMap.delete(key);
3064
3073
  target.selectorAtoms.delete(key);
3065
3074
  target.atomsThatAreDefault.delete(key);
3066
- store.timelineTopics.delete(key);
3067
- if (atomToken.type === `mutable_atom`) {
3068
- const updateToken = getUpdateToken(atomToken);
3069
- disposeAtom(updateToken, store);
3070
- store.trackers.delete(key);
3071
- }
3072
- store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
3073
- if (isChild && target.transactionMeta.phase === `building`) {
3074
- const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
3075
- const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
3076
- const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
3077
- if (!updateAlreadyCaptured) {
3078
- target.transactionMeta.update.updates.push(disposal);
3079
- }
3080
- } else {
3081
- store.on.atomDisposal.next(atomToken);
3082
- }
3083
- }
3084
- }
3085
-
3086
- // ../atom.io/internal/src/get-trace.ts
3087
- function getTrace(error) {
3088
- const { stack } = error;
3089
- if (stack) {
3090
- return `
3091
- ` + stack.split(`
3092
- `)?.slice(1)?.join(`
3093
- `);
3094
- }
3095
- return ``;
3096
- }
3097
-
3098
- // ../atom.io/introspection/src/refinery.ts
3099
- var Refinery = class {
3100
- supported;
3101
- constructor(supported) {
3102
- this.supported = supported;
3103
- }
3104
- refine(input) {
3105
- for (const [key, refiner] of Object.entries(this.supported)) {
3106
- try {
3107
- if (
3108
- // @ts-expect-error that's the point
3109
- refiner(input) === true && refiner !== Boolean
3110
- ) {
3111
- return { type: key, data: input };
3112
- }
3113
- } catch (_) {
3114
- try {
3115
- if (input instanceof refiner) {
3116
- return { type: key, data: input };
3117
- }
3118
- } catch (__) {
3119
- }
3120
- }
3121
- }
3122
- return null;
3123
- }
3124
- };
3125
- var primitiveRefinery = new Refinery({
3126
- number: (input) => typeof input === `number`,
3127
- string: (input) => typeof input === `string`,
3128
- boolean: (input) => typeof input === `boolean`,
3129
- null: (input) => input === null
3130
- });
3131
- function isPlainObject(input) {
3132
- if (!input) {
3133
- return false;
3134
- }
3135
- const prototype = Object.getPrototypeOf(input);
3136
- return prototype === Object.prototype;
3137
- }
3138
- var jsonTreeRefinery = new Refinery({
3139
- object: isPlainObject,
3140
- array: (input) => Array.isArray(input)
3141
- });
3142
- var jsonRefinery = new Refinery({
3143
- ...primitiveRefinery.supported,
3144
- ...jsonTreeRefinery.supported
3145
- });
3146
- var discoverType = (input) => {
3147
- if (input === undefined) {
3148
- return `undefined`;
3149
- }
3150
- const refined = jsonRefinery.refine(input);
3151
- if (refined) {
3152
- return refined.type;
3153
- }
3154
- return Object.getPrototypeOf(input).constructor.name;
3155
- };
3156
-
3157
- // ../atom.io/introspection/src/sprawl.ts
3158
- var sprawl = (tree, inspector) => {
3159
- const walk = (path, node) => {
3160
- const inspect2 = (p, n) => {
3161
- const result2 = inspector(p, n);
3162
- if (result2) return result2;
3163
- return null;
3164
- };
3165
- const result = inspect2(path, node);
3166
- if (result?.jobComplete ?? result?.pathComplete) {
3167
- return result;
3168
- }
3169
- const childEntries = Array.isArray(node) ? node.map((v, i) => [i, v]) : isPlainObject(node) ? Object.entries(node) : [];
3170
- for (const [k, v] of childEntries) {
3171
- const subResult = walk([...path, k], v);
3172
- if (subResult?.jobComplete) {
3173
- return subResult;
3174
- }
3175
- }
3176
- return {};
3177
- };
3178
- walk([], tree);
3179
- };
3180
-
3181
- // ../atom.io/introspection/src/differ.ts
3182
- function diffNumber(a, b) {
3183
- const sign = a < b ? `+` : `-`;
3184
- return {
3185
- summary: `${sign}${Math.abs(a - b)} (${a} \u2192 ${b})`
3186
- };
3187
- }
3188
- function diffString(a, b) {
3189
- const sign = a.length < b.length ? `+` : `-`;
3190
- return {
3191
- summary: `${sign}${Math.abs(a.length - b.length)} ("${a}" \u2192 "${b}")`
3192
- };
3193
- }
3194
- function diffBoolean(a, b) {
3195
- return {
3196
- summary: `${a} \u2192 ${b}`
3197
- };
3198
- }
3199
- function diffObject(a, b, recurse) {
3200
- let summary = ``;
3201
- const added = [];
3202
- const removed = [];
3203
- const changed = [];
3204
- sprawl(a, (path, nodeA) => {
3205
- let key;
3206
- for (key of path) {
3207
- const nodeB = b[key];
3208
- if (nodeB === undefined) {
3209
- removed.push([key, JSON.stringify(nodeA)]);
3210
- } else {
3211
- const delta = recurse(nodeA, nodeB);
3212
- if (delta.summary !== `No Change`) {
3213
- changed.push([key, delta]);
3214
- }
3215
- }
3216
- }
3217
- });
3218
- sprawl(b, (path, nodeB) => {
3219
- let key;
3220
- for (key of path) {
3221
- const nodeA = a[key];
3222
- if (nodeA === undefined) {
3223
- added.push([key, JSON.stringify(nodeB)]);
3224
- }
3225
- }
3226
- });
3227
- summary = `\uFF5E${changed.length} \uFF0B${added.length} \uFF0D${removed.length}`;
3228
- return {
3229
- summary,
3230
- added,
3231
- removed,
3232
- changed
3233
- };
3234
- }
3235
- function diffArray(a, b, recurse) {
3236
- return diffObject(a, b, recurse);
3237
- }
3238
- var Differ = class {
3239
- leafRefinery;
3240
- treeRefinery;
3241
- leafDiffers;
3242
- treeDiffers;
3243
- constructor(leafRefinery, treeRefinery, diffFunctions) {
3244
- this.leafRefinery = leafRefinery;
3245
- this.treeRefinery = treeRefinery;
3246
- this.leafDiffers = {};
3247
- this.treeDiffers = {};
3248
- for (const key of Object.keys(leafRefinery.supported)) {
3249
- const diffFunction = diffFunctions[key];
3250
- this.leafDiffers[key] = diffFunction;
3251
- }
3252
- for (const key of Object.keys(treeRefinery.supported)) {
3253
- const diffFunction = diffFunctions[key];
3254
- this.treeDiffers[key] = diffFunction;
3255
- }
3256
- }
3257
- diff(a, b) {
3258
- if (a === b) {
3259
- return { summary: `No Change` };
3260
- }
3261
- const aRefined = this.leafRefinery.refine(a) ?? this.treeRefinery.refine(a);
3262
- const bRefined = this.leafRefinery.refine(b) ?? this.treeRefinery.refine(b);
3263
- if (aRefined !== null && bRefined !== null) {
3264
- if (aRefined.type === bRefined.type) {
3265
- if (aRefined.type in this.leafDiffers) {
3266
- const delta = this.leafDiffers[aRefined.type](
3267
- aRefined.data,
3268
- bRefined.data
3269
- );
3270
- return delta;
3271
- }
3272
- if (aRefined.type in this.treeDiffers) {
3273
- const delta = this.treeDiffers[aRefined.type](
3274
- aRefined.data,
3275
- bRefined.data,
3276
- (x, y) => this.diff(x, y)
3277
- );
3278
- return delta;
3279
- }
3280
- }
3075
+ store.timelineTopics.delete(key);
3076
+ if (atomToken.type === `mutable_atom`) {
3077
+ const updateToken = getUpdateToken(atomToken);
3078
+ disposeAtom(store, updateToken);
3079
+ store.trackers.delete(key);
3281
3080
  }
3282
- const typeA = discoverType(a);
3283
- const typeB = discoverType(b);
3284
- if (typeA === typeB) {
3285
- return {
3286
- summary: `${typeA} \u2192 ${typeB}`
3287
- };
3081
+ store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
3082
+ if (isChild && target.transactionMeta.phase === `building`) {
3083
+ const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
3084
+ const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
3085
+ const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
3086
+ if (!updateAlreadyCaptured) {
3087
+ target.transactionMeta.update.updates.push(disposal);
3088
+ }
3089
+ } else {
3090
+ store.on.atomDisposal.next(atomToken);
3288
3091
  }
3289
- return {
3290
- summary: `Type change: ${typeA} \u2192 ${typeB}`
3291
- };
3292
3092
  }
3293
- };
3294
- new Differ(primitiveRefinery, jsonTreeRefinery, {
3295
- number: diffNumber,
3296
- string: diffString,
3297
- boolean: diffBoolean,
3298
- null: () => ({ summary: `No Change` }),
3299
- object: diffObject,
3300
- array: diffArray
3301
- });
3093
+ }
3302
3094
 
3303
3095
  // ../atom.io/transceivers/set-rtx/src/set-rtx.ts
3304
3096
  var SetRTX = class _SetRTX extends Set {
@@ -3384,7 +3176,10 @@ var SetRTX = class _SetRTX extends Set {
3384
3176
  this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
3385
3177
  }
3386
3178
  } catch (thrown) {
3387
- console.error(`Failed to apply transaction to SetRTX:`, thrown);
3179
+ console.warn(
3180
+ `Did not apply transaction to SetRTX; this error was thrown:`,
3181
+ thrown
3182
+ );
3388
3183
  throw thrown;
3389
3184
  } finally {
3390
3185
  unsubscribe();
@@ -3509,10 +3304,7 @@ var SetRTX = class _SetRTX extends Set {
3509
3304
  }
3510
3305
  };
3511
3306
 
3512
- // ../atom.io/data/src/join.ts
3513
- function capitalize2(string) {
3514
- return string[0].toUpperCase() + string.slice(1);
3515
- }
3307
+ // ../atom.io/internal/src/join/join-internal.ts
3516
3308
  var Join = class {
3517
3309
  toolkit;
3518
3310
  options;
@@ -3544,7 +3336,6 @@ var Join = class {
3544
3336
  setIntoStore(store, ...ps);
3545
3337
  },
3546
3338
  find: (...ps) => findInStore(store, ...ps),
3547
- seek: (...ps) => seekInStore(store, ...ps),
3548
3339
  json: (token) => getJsonToken(store, token)
3549
3340
  };
3550
3341
  const aSide = options.between[0];
@@ -3810,8 +3601,8 @@ var Join = class {
3810
3601
  switch (options.cardinality) {
3811
3602
  case `1:1`: {
3812
3603
  const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3813
- const stateKeyA = `${aSide}KeyOf${capitalize2(bSide)}`;
3814
- const stateKeyB = `${bSide}KeyOf${capitalize2(aSide)}`;
3604
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3605
+ const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
3815
3606
  const baseStates = {
3816
3607
  [stateKeyA]: singleRelatedKeySelectors,
3817
3608
  [stateKeyB]: singleRelatedKeySelectors
@@ -3819,8 +3610,8 @@ var Join = class {
3819
3610
  let states;
3820
3611
  if (defaultContent) {
3821
3612
  const singleEntrySelectors = createSingleEntrySelectorFamily();
3822
- const entriesStateKeyA = `${aSide}EntryOf${capitalize2(bSide)}`;
3823
- const entriesStateKeyB = `${bSide}EntryOf${capitalize2(aSide)}`;
3613
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3614
+ const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
3824
3615
  const contentStates = {
3825
3616
  [entriesStateKeyA]: singleEntrySelectors,
3826
3617
  [entriesStateKeyB]: singleEntrySelectors
@@ -3836,8 +3627,8 @@ var Join = class {
3836
3627
  case `1:n`: {
3837
3628
  const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3838
3629
  const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3839
- const stateKeyA = `${aSide}KeyOf${capitalize2(bSide)}`;
3840
- const stateKeyB = `${bSide}KeysOf${capitalize2(aSide)}`;
3630
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3631
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3841
3632
  const baseStates = {
3842
3633
  [stateKeyA]: singleRelatedKeySelectors,
3843
3634
  [stateKeyB]: multipleRelatedKeysSelectors
@@ -3846,8 +3637,8 @@ var Join = class {
3846
3637
  if (defaultContent) {
3847
3638
  const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
3848
3639
  const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3849
- const entriesStateKeyA = `${aSide}EntryOf${capitalize2(bSide)}`;
3850
- const entriesStateKeyB = `${bSide}EntriesOf${capitalize2(
3640
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3641
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3851
3642
  aSide
3852
3643
  )}`;
3853
3644
  const contentStates = {
@@ -3864,8 +3655,8 @@ var Join = class {
3864
3655
  }
3865
3656
  default: {
3866
3657
  const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3867
- const stateKeyA = `${aSide}KeysOf${capitalize2(bSide)}`;
3868
- const stateKeyB = `${bSide}KeysOf${capitalize2(aSide)}`;
3658
+ const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
3659
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3869
3660
  const baseStates = {
3870
3661
  [stateKeyA]: multipleRelatedKeysSelectors,
3871
3662
  [stateKeyB]: multipleRelatedKeysSelectors
@@ -3873,10 +3664,10 @@ var Join = class {
3873
3664
  let states;
3874
3665
  if (defaultContent) {
3875
3666
  const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3876
- const entriesStateKeyA = `${aSide}EntriesOf${capitalize2(
3667
+ const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
3877
3668
  bSide
3878
3669
  )}`;
3879
- const entriesStateKeyB = `${bSide}EntriesOf${capitalize2(
3670
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3880
3671
  aSide
3881
3672
  )}`;
3882
3673
  const contentStates = {
@@ -3893,17 +3684,8 @@ var Join = class {
3893
3684
  }
3894
3685
  }
3895
3686
  };
3896
- function join(options, defaultContent, store = IMPLICIT.STORE) {
3897
- store.joins.set(options.key, new Join(options, defaultContent, store));
3898
- const token = {
3899
- key: options.key,
3900
- type: `join`,
3901
- a: options.between[0],
3902
- b: options.between[1],
3903
- cardinality: options.cardinality
3904
- };
3905
- return token;
3906
- }
3687
+
3688
+ // ../atom.io/internal/src/join/get-join.ts
3907
3689
  function getJoin(token, store) {
3908
3690
  let myJoin = store.joins.get(token.key);
3909
3691
  if (myJoin === undefined) {
@@ -3919,6 +3701,8 @@ function getJoin(token, store) {
3919
3701
  }
3920
3702
  return myJoin;
3921
3703
  }
3704
+
3705
+ // ../atom.io/internal/src/join/edit-relations-in-store.ts
3922
3706
  function editRelationsInStore(token, change, store) {
3923
3707
  const myJoin = getJoin(token, store);
3924
3708
  const target = newest(store);
@@ -3931,14 +3715,218 @@ function editRelationsInStore(token, change, store) {
3931
3715
  change(myJoin.relations);
3932
3716
  }
3933
3717
  }
3718
+
3719
+ // ../atom.io/internal/src/join/get-internal-relations-from-store.ts
3934
3720
  function getInternalRelationsFromStore(token, store) {
3935
3721
  const myJoin = getJoin(token, store);
3936
3722
  const family = myJoin.core.relatedKeysAtoms;
3937
3723
  return family;
3938
3724
  }
3939
- function getInternalRelations(token) {
3940
- return getInternalRelationsFromStore(token, IMPLICIT.STORE);
3725
+
3726
+ // ../atom.io/introspection/src/refinery.ts
3727
+ var Refinery = class {
3728
+ supported;
3729
+ constructor(supported) {
3730
+ this.supported = supported;
3731
+ }
3732
+ refine(input) {
3733
+ for (const [key, refiner] of Object.entries(this.supported)) {
3734
+ try {
3735
+ if (
3736
+ // @ts-expect-error that's the point
3737
+ refiner(input) === true && refiner !== Boolean
3738
+ ) {
3739
+ return { type: key, data: input };
3740
+ }
3741
+ } catch (_) {
3742
+ try {
3743
+ if (input instanceof refiner) {
3744
+ return { type: key, data: input };
3745
+ }
3746
+ } catch (__) {
3747
+ }
3748
+ }
3749
+ }
3750
+ return null;
3751
+ }
3752
+ };
3753
+ var primitiveRefinery = new Refinery({
3754
+ number: (input) => typeof input === `number`,
3755
+ string: (input) => typeof input === `string`,
3756
+ boolean: (input) => typeof input === `boolean`,
3757
+ null: (input) => input === null
3758
+ });
3759
+ function isPlainObject(input) {
3760
+ if (!input) {
3761
+ return false;
3762
+ }
3763
+ const prototype = Object.getPrototypeOf(input);
3764
+ return prototype === Object.prototype;
3765
+ }
3766
+ var jsonTreeRefinery = new Refinery({
3767
+ object: isPlainObject,
3768
+ array: (input) => Array.isArray(input)
3769
+ });
3770
+ var jsonRefinery = new Refinery({
3771
+ ...primitiveRefinery.supported,
3772
+ ...jsonTreeRefinery.supported
3773
+ });
3774
+ var discoverType = (input) => {
3775
+ if (input === undefined) {
3776
+ return `undefined`;
3777
+ }
3778
+ const refined = jsonRefinery.refine(input);
3779
+ if (refined) {
3780
+ return refined.type;
3781
+ }
3782
+ return Object.getPrototypeOf(input).constructor.name;
3783
+ };
3784
+
3785
+ // ../atom.io/introspection/src/sprawl.ts
3786
+ var sprawl = (tree, inspector) => {
3787
+ const walk = (path, node) => {
3788
+ const inspect2 = (p, n) => {
3789
+ const result2 = inspector(p, n);
3790
+ if (result2) return result2;
3791
+ return null;
3792
+ };
3793
+ const result = inspect2(path, node);
3794
+ if (result?.jobComplete ?? result?.pathComplete) {
3795
+ return result;
3796
+ }
3797
+ const childEntries = Array.isArray(node) ? node.map((v, i) => [i, v]) : isPlainObject(node) ? Object.entries(node) : [];
3798
+ for (const [k, v] of childEntries) {
3799
+ const subResult = walk([...path, k], v);
3800
+ if (subResult?.jobComplete) {
3801
+ return subResult;
3802
+ }
3803
+ }
3804
+ return {};
3805
+ };
3806
+ walk([], tree);
3807
+ };
3808
+
3809
+ // ../atom.io/introspection/src/differ.ts
3810
+ function diffNumber(a, b) {
3811
+ const sign = a < b ? `+` : `-`;
3812
+ return {
3813
+ summary: `${sign}${Math.abs(a - b)} (${a} \u2192 ${b})`
3814
+ };
3815
+ }
3816
+ function diffString(a, b) {
3817
+ const sign = a.length < b.length ? `+` : `-`;
3818
+ return {
3819
+ summary: `${sign}${Math.abs(a.length - b.length)} ("${a}" \u2192 "${b}")`
3820
+ };
3821
+ }
3822
+ function diffBoolean(a, b) {
3823
+ return {
3824
+ summary: `${a} \u2192 ${b}`
3825
+ };
3826
+ }
3827
+ function diffObject(a, b, recurse) {
3828
+ let summary = ``;
3829
+ const added = [];
3830
+ const removed = [];
3831
+ const changed = [];
3832
+ sprawl(a, (path, nodeA) => {
3833
+ let key;
3834
+ for (key of path) {
3835
+ const nodeB = b[key];
3836
+ if (nodeB === undefined) {
3837
+ removed.push([key, JSON.stringify(nodeA)]);
3838
+ } else {
3839
+ const delta = recurse(nodeA, nodeB);
3840
+ if (delta.summary !== `No Change`) {
3841
+ changed.push([key, delta]);
3842
+ }
3843
+ }
3844
+ }
3845
+ });
3846
+ sprawl(b, (path, nodeB) => {
3847
+ let key;
3848
+ for (key of path) {
3849
+ const nodeA = a[key];
3850
+ if (nodeA === undefined) {
3851
+ added.push([key, JSON.stringify(nodeB)]);
3852
+ }
3853
+ }
3854
+ });
3855
+ summary = `\uFF5E${changed.length} \uFF0B${added.length} \uFF0D${removed.length}`;
3856
+ return {
3857
+ summary,
3858
+ added,
3859
+ removed,
3860
+ changed
3861
+ };
3862
+ }
3863
+ function diffArray(a, b, recurse) {
3864
+ return diffObject(a, b, recurse);
3941
3865
  }
3866
+ var Differ = class {
3867
+ leafRefinery;
3868
+ treeRefinery;
3869
+ leafDiffers;
3870
+ treeDiffers;
3871
+ constructor(leafRefinery, treeRefinery, diffFunctions) {
3872
+ this.leafRefinery = leafRefinery;
3873
+ this.treeRefinery = treeRefinery;
3874
+ this.leafDiffers = {};
3875
+ this.treeDiffers = {};
3876
+ for (const key of Object.keys(leafRefinery.supported)) {
3877
+ const diffFunction = diffFunctions[key];
3878
+ this.leafDiffers[key] = diffFunction;
3879
+ }
3880
+ for (const key of Object.keys(treeRefinery.supported)) {
3881
+ const diffFunction = diffFunctions[key];
3882
+ this.treeDiffers[key] = diffFunction;
3883
+ }
3884
+ }
3885
+ diff(a, b) {
3886
+ if (a === b) {
3887
+ return { summary: `No Change` };
3888
+ }
3889
+ const aRefined = this.leafRefinery.refine(a) ?? this.treeRefinery.refine(a);
3890
+ const bRefined = this.leafRefinery.refine(b) ?? this.treeRefinery.refine(b);
3891
+ if (aRefined !== null && bRefined !== null) {
3892
+ if (aRefined.type === bRefined.type) {
3893
+ if (aRefined.type in this.leafDiffers) {
3894
+ const delta = this.leafDiffers[aRefined.type](
3895
+ aRefined.data,
3896
+ bRefined.data
3897
+ );
3898
+ return delta;
3899
+ }
3900
+ if (aRefined.type in this.treeDiffers) {
3901
+ const delta = this.treeDiffers[aRefined.type](
3902
+ aRefined.data,
3903
+ bRefined.data,
3904
+ (x, y) => this.diff(x, y)
3905
+ );
3906
+ return delta;
3907
+ }
3908
+ }
3909
+ }
3910
+ const typeA = discoverType(a);
3911
+ const typeB = discoverType(b);
3912
+ if (typeA === typeB) {
3913
+ return {
3914
+ summary: `${typeA} \u2192 ${typeB}`
3915
+ };
3916
+ }
3917
+ return {
3918
+ summary: `Type change: ${typeA} \u2192 ${typeB}`
3919
+ };
3920
+ }
3921
+ };
3922
+ new Differ(primitiveRefinery, jsonTreeRefinery, {
3923
+ number: diffNumber,
3924
+ string: diffString,
3925
+ boolean: diffBoolean,
3926
+ null: () => ({ summary: `No Change` }),
3927
+ object: diffObject,
3928
+ array: diffArray
3929
+ });
3942
3930
 
3943
3931
  // ../atom.io/realtime/src/shared-room-store.ts
3944
3932
  atom({
@@ -4774,5 +4762,5 @@ var FlightDeckLogger = class {
4774
4762
  };
4775
4763
 
4776
4764
  export { FLIGHTDECK_ERROR, FLIGHTDECK_INFO, FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FLIGHTDECK_WARN, FlightDeck, FlightDeckLogger, flightDeckLogSchema, isVersionNumber };
4777
- //# sourceMappingURL=chunk-XIZZKICH.js.map
4778
- //# sourceMappingURL=chunk-XIZZKICH.js.map
4765
+ //# sourceMappingURL=chunk-7KMVUPT3.js.map
4766
+ //# sourceMappingURL=chunk-7KMVUPT3.js.map