atom.io 0.24.8 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/data/dist/index.cjs +40 -62
  2. package/data/dist/index.d.ts +3 -3
  3. package/data/dist/index.js +41 -63
  4. package/data/src/join.ts +47 -64
  5. package/dist/index.cjs +26 -8
  6. package/dist/index.d.ts +37 -15
  7. package/dist/index.js +27 -9
  8. package/internal/dist/index.cjs +204 -104
  9. package/internal/dist/index.d.ts +10 -5
  10. package/internal/dist/index.js +205 -105
  11. package/internal/src/families/dispose-from-store.ts +56 -3
  12. package/internal/src/get-state/get-from-store.ts +58 -25
  13. package/internal/src/molecule/make-molecule-in-store.ts +59 -23
  14. package/internal/src/not-found-error.ts +29 -6
  15. package/internal/src/selector/create-writable-selector.ts +5 -5
  16. package/internal/src/selector/register-selector.ts +58 -9
  17. package/internal/src/set-state/set-into-store.ts +48 -1
  18. package/internal/src/store/store.ts +4 -4
  19. package/internal/src/transaction/build-transaction.ts +10 -9
  20. package/internal/src/transaction/create-transaction.ts +2 -2
  21. package/internal/src/transaction/index.ts +2 -2
  22. package/package.json +5 -5
  23. package/react/dist/index.cjs +4 -1
  24. package/react/dist/index.js +5 -2
  25. package/react/src/use-o.ts +11 -3
  26. package/realtime/dist/index.cjs +0 -1
  27. package/realtime/dist/index.js +0 -1
  28. package/realtime/src/realtime-continuity.ts +0 -1
  29. package/realtime-server/dist/index.cjs +7 -7
  30. package/realtime-server/dist/index.js +7 -7
  31. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +7 -7
  32. package/src/dispose-state.ts +32 -3
  33. package/src/get-state.ts +37 -4
  34. package/src/molecule.ts +20 -7
  35. package/src/set-state.ts +19 -2
  36. package/src/silo.ts +11 -4
  37. package/src/transaction.ts +9 -17
@@ -2,7 +2,7 @@ import { Junction } from '../../dist/chunk-HYXKCFVY.js';
2
2
  import { __spreadValues, __spreadProps } from '../../dist/chunk-S4N6XNPH.js';
3
3
  import { stringifyJson, parseJson, selectJson, selectJsonFamily } from 'atom.io/json';
4
4
  import { AtomIOLogger } from 'atom.io';
5
- import { getJoin } from 'atom.io/data';
5
+ import { getJoin, findRelations } from 'atom.io/data';
6
6
 
7
7
  // internal/src/arbitrary.ts
8
8
  function arbitrary(random = Math.random) {
@@ -132,8 +132,6 @@ var abortTransaction = (store) => {
132
132
  );
133
133
  target.parent.child = null;
134
134
  };
135
-
136
- // internal/src/not-found-error.ts
137
135
  var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
138
136
  function prettyPrintTokenType(token) {
139
137
  switch (token.type) {
@@ -152,10 +150,19 @@ function prettyPrintTokenType(token) {
152
150
  }
153
151
  }
154
152
  var NotFoundError = class extends Error {
155
- constructor(token, store) {
156
- super(
157
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
158
- );
153
+ constructor(...params) {
154
+ const token = params[0];
155
+ const store = params.length === 2 ? params[1] : params[2];
156
+ if (params.length === 2) {
157
+ super(
158
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
159
+ );
160
+ } else {
161
+ const key = params[1];
162
+ super(
163
+ `${prettyPrintTokenType(token)} "${token.key}" member ${stringifyJson(key)} not found in store "${store.config.name}".`
164
+ );
165
+ }
159
166
  }
160
167
  };
161
168
 
@@ -415,41 +422,6 @@ var setAtomOrSelector = (state, value, store) => {
415
422
  break;
416
423
  }
417
424
  };
418
-
419
- // internal/src/set-state/set-into-store.ts
420
- function setIntoStore(token, value, store) {
421
- const rejectionTime = openOperation(token, store);
422
- if (rejectionTime) {
423
- const unsubscribe = store.on.operationClose.subscribe(
424
- `waiting to set "${token.key}" at T-${rejectionTime}`,
425
- () => {
426
- unsubscribe();
427
- store.logger.info(
428
- `\u{1F7E2}`,
429
- token.type,
430
- token.key,
431
- `resuming deferred setState from T-${rejectionTime}`
432
- );
433
- setIntoStore(token, value, store);
434
- }
435
- );
436
- return;
437
- }
438
- const state = withdraw(token, store);
439
- setAtomOrSelector(state, value, store);
440
- closeOperation(store);
441
- }
442
-
443
- // internal/src/ingest-updates/ingest-atom-update.ts
444
- function ingestAtomUpdate(applying, atomUpdate, store) {
445
- const { key, newValue, oldValue } = atomUpdate;
446
- const value = applying === `newValue` ? newValue : oldValue;
447
- const token = { key, type: `atom` };
448
- if (atomUpdate.family) {
449
- Object.assign(token, { family: atomUpdate.family });
450
- }
451
- setIntoStore(token, value, store);
452
- }
453
425
  function createRegularAtomFamily(options, store) {
454
426
  const subject = new Subject();
455
427
  const atomFamily = Object.assign(
@@ -491,17 +463,31 @@ function createAtomFamily(options, store) {
491
463
  }
492
464
 
493
465
  // internal/src/get-state/get-from-store.ts
494
- function getFromStore(token, store) {
495
- if (token.type === `molecule`) {
496
- try {
497
- const molecule = withdraw(token, store);
498
- return molecule.instance;
499
- } catch (_) {
500
- return void 0;
466
+ function getFromStore(...params) {
467
+ let token;
468
+ let store;
469
+ if (params.length === 2) {
470
+ token = params[0];
471
+ store = params[1];
472
+ } else {
473
+ const family = params[0];
474
+ const key = params[1];
475
+ store = params[2];
476
+ const maybeToken = family.type === `molecule_family` ? seekInStore(family, key, store) : store.config.lifespan === `immortal` ? seekInStore(family, key, store) : findInStore(family, key, store);
477
+ if (!maybeToken) {
478
+ throw new NotFoundError(family, key, store);
501
479
  }
480
+ token = maybeToken;
481
+ }
482
+ switch (token.type) {
483
+ case `atom`:
484
+ case `mutable_atom`:
485
+ case `selector`:
486
+ case `readonly_selector`:
487
+ return readOrComputeValue(withdraw(token, store), store);
488
+ case `molecule`:
489
+ return withdraw(token, store).instance;
502
490
  }
503
- const state = withdraw(token, store);
504
- return readOrComputeValue(state, store);
505
491
  }
506
492
 
507
493
  // internal/src/keys.ts
@@ -582,8 +568,16 @@ var updateSelectorAtoms = (selectorKey, dependency, covered, store) => {
582
568
 
583
569
  // internal/src/selector/register-selector.ts
584
570
  var registerSelector = (selectorKey, covered, store) => ({
585
- get: (dependency) => {
571
+ get: (dependency, key) => {
586
572
  const target = newest(store);
573
+ if (key) {
574
+ switch (dependency.type) {
575
+ case `molecule_family`:
576
+ return getFromStore(dependency, key, store);
577
+ case `atom_family`:
578
+ dependency = seekInStore(dependency, key, store);
579
+ }
580
+ }
587
581
  if (dependency.type === `molecule`) {
588
582
  return getFromStore(dependency, store);
589
583
  }
@@ -609,10 +603,25 @@ var registerSelector = (selectorKey, covered, store) => ({
609
603
  updateSelectorAtoms(selectorKey, dependency, covered, store);
610
604
  return dependencyValue;
611
605
  },
612
- set: (WritableToken, newValue) => {
606
+ set: (...params) => {
607
+ let token;
608
+ let value;
609
+ if (params.length === 2) {
610
+ token = params[0];
611
+ value = params[1];
612
+ } else {
613
+ const family = params[0];
614
+ const key = params[1];
615
+ value = params[2];
616
+ const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(family, key, store) : seekInStore(family, key, store);
617
+ if (!maybeToken) {
618
+ throw new NotFoundError(family, key, store);
619
+ }
620
+ token = maybeToken;
621
+ }
613
622
  const target = newest(store);
614
- const state = withdraw(WritableToken, target);
615
- setAtomOrSelector(state, newValue, target);
623
+ const state = withdraw(token, target);
624
+ setAtomOrSelector(state, value, target);
616
625
  },
617
626
  find: (token, key) => findInStore(token, key, store),
618
627
  seek: (token, key) => seekInStore(token, key, store),
@@ -665,11 +674,11 @@ var createWritableSelector = (options, family, store) => {
665
674
  const target = newest(store);
666
675
  const subject = new Subject();
667
676
  const covered = /* @__PURE__ */ new Set();
668
- const transactors = registerSelector(options.key, covered, target);
669
- const { find, get, seek, json } = transactors;
670
- const readonlyTransactors = { find, get, seek, json };
677
+ const toolkit = registerSelector(options.key, covered, target);
678
+ const { find, get, seek, json } = toolkit;
679
+ const getterToolkit = { find, get, seek, json };
671
680
  const getSelf = (innerTarget = newest(store)) => {
672
- const value = options.get(readonlyTransactors);
681
+ const value = options.get(getterToolkit);
673
682
  cacheValue(options.key, value, subject, innerTarget);
674
683
  covered.clear();
675
684
  return value;
@@ -693,7 +702,7 @@ var createWritableSelector = (options, family, store) => {
693
702
  if (isRootStore(innerTarget)) {
694
703
  subject.next({ newValue, oldValue });
695
704
  }
696
- options.set(transactors, newValue);
705
+ options.set(toolkit, newValue);
697
706
  };
698
707
  const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
699
708
  subject,
@@ -947,23 +956,6 @@ function disposeMolecule(token, store) {
947
956
  }
948
957
  }
949
958
 
950
- // internal/src/families/dispose-from-store.ts
951
- function disposeFromStore(token, store = IMPLICIT.STORE) {
952
- switch (token.type) {
953
- case `atom`:
954
- case `mutable_atom`:
955
- disposeAtom(token, store);
956
- break;
957
- case `selector`:
958
- case `readonly_selector`:
959
- disposeSelector(token, store);
960
- break;
961
- case `molecule`:
962
- disposeMolecule(token, store);
963
- break;
964
- }
965
- }
966
-
967
959
  // internal/src/families/init-family-member.ts
968
960
  function initFamilyMemberInStore(token, key, store) {
969
961
  const familyKey = token.key;
@@ -1037,6 +1029,91 @@ function findInStore(token, key, store) {
1037
1029
  return state;
1038
1030
  }
1039
1031
 
1032
+ // internal/src/families/dispose-from-store.ts
1033
+ function disposeFromStore(...params) {
1034
+ let token;
1035
+ let store;
1036
+ if (params.length === 2) {
1037
+ token = params[0];
1038
+ store = params[1];
1039
+ } else {
1040
+ const family = params[0];
1041
+ const key = params[1];
1042
+ store = params[2];
1043
+ const maybeToken = family.type === `molecule_family` ? seekInStore(family, key, store) : store.config.lifespan === `immortal` ? seekInStore(family, key, store) : findInStore(family, key, store);
1044
+ if (!maybeToken) {
1045
+ throw new NotFoundError(family, key, store);
1046
+ }
1047
+ token = maybeToken;
1048
+ }
1049
+ switch (token.type) {
1050
+ case `atom`:
1051
+ case `mutable_atom`:
1052
+ disposeAtom(token, store);
1053
+ break;
1054
+ case `selector`:
1055
+ case `readonly_selector`:
1056
+ disposeSelector(token, store);
1057
+ break;
1058
+ case `molecule`:
1059
+ disposeMolecule(token, store);
1060
+ break;
1061
+ }
1062
+ }
1063
+
1064
+ // internal/src/set-state/set-into-store.ts
1065
+ function setIntoStore(...params) {
1066
+ let token;
1067
+ let value;
1068
+ let store;
1069
+ if (params.length === 3) {
1070
+ token = params[0];
1071
+ value = params[1];
1072
+ store = params[2];
1073
+ } else {
1074
+ const family = params[0];
1075
+ const key = params[1];
1076
+ value = params[2];
1077
+ store = params[3];
1078
+ const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(family, key, store) : seekInStore(family, key, store);
1079
+ if (!maybeToken) {
1080
+ throw new NotFoundError(family, key, store);
1081
+ }
1082
+ token = maybeToken;
1083
+ }
1084
+ const rejectionTime = openOperation(token, store);
1085
+ if (rejectionTime) {
1086
+ const unsubscribe = store.on.operationClose.subscribe(
1087
+ `waiting to set "${token.key}" at T-${rejectionTime}`,
1088
+ () => {
1089
+ unsubscribe();
1090
+ store.logger.info(
1091
+ `\u{1F7E2}`,
1092
+ token.type,
1093
+ token.key,
1094
+ `resuming deferred setState from T-${rejectionTime}`
1095
+ );
1096
+ setIntoStore(token, value, store);
1097
+ }
1098
+ );
1099
+ return;
1100
+ }
1101
+ const state = withdraw(token, store);
1102
+ setAtomOrSelector(state, value, store);
1103
+ closeOperation(store);
1104
+ }
1105
+
1106
+ // internal/src/ingest-updates/ingest-atom-update.ts
1107
+ function ingestAtomUpdate(applying, atomUpdate, store) {
1108
+ const { key, newValue, oldValue } = atomUpdate;
1109
+ const value = applying === `newValue` ? newValue : oldValue;
1110
+ const token = { key, type: `atom` };
1111
+ if (atomUpdate.family) {
1112
+ Object.assign(token, { family: atomUpdate.family });
1113
+ }
1114
+ setIntoStore(token, value, store);
1115
+ }
1116
+
1040
1117
  // internal/src/molecule/create-molecule-family.ts
1041
1118
  function createMoleculeFamily(options, store) {
1042
1119
  var _a;
@@ -1098,30 +1175,34 @@ var Molecule = class {
1098
1175
  };
1099
1176
 
1100
1177
  // internal/src/molecule/make-molecule-in-store.ts
1178
+ function capitalize2(string) {
1179
+ return string[0].toUpperCase() + string.slice(1);
1180
+ }
1101
1181
  function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1102
1182
  const target = newest(store);
1103
- target.moleculeInProgress = key;
1183
+ const stringKey = stringifyJson(key);
1184
+ target.moleculeInProgress = stringKey;
1104
1185
  const contextArray = Array.isArray(context) ? context : [context];
1105
1186
  const owners = contextArray.map((ctx) => {
1106
1187
  if (ctx instanceof Molecule) {
1107
1188
  return ctx;
1108
1189
  }
1109
- const stringKey = stringifyJson(ctx.key);
1110
- const molecule2 = store.molecules.get(stringKey);
1190
+ const ctxStringKey = stringifyJson(ctx.key);
1191
+ const molecule2 = store.molecules.get(ctxStringKey);
1111
1192
  if (!molecule2) {
1112
1193
  throw new Error(
1113
- `Molecule ${stringKey} not found in store "${store.config.name}"`
1194
+ `Molecule ${ctxStringKey} not found in store "${store.config.name}"`
1114
1195
  );
1115
1196
  }
1116
1197
  return molecule2;
1117
1198
  });
1118
1199
  const molecule = new Molecule(owners, key, familyToken);
1119
- target.molecules.set(stringifyJson(key), molecule);
1200
+ target.molecules.set(stringKey, molecule);
1120
1201
  for (const owner of owners) {
1121
1202
  owner.below.set(molecule.stringKey, molecule);
1122
1203
  }
1123
- const transactors = {
1124
- get: (t) => getFromStore(t, newest(store)),
1204
+ const toolkit = {
1205
+ get: (t) => getFromStore(t, void 0, newest(store)),
1125
1206
  set: (t, newValue) => {
1126
1207
  setIntoStore(t, newValue, newest(store));
1127
1208
  },
@@ -1133,11 +1214,36 @@ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1133
1214
  disposeFromStore(t, newest(store));
1134
1215
  },
1135
1216
  env: () => getEnvironmentData(newest(store)),
1136
- bond: (f) => growMoleculeInStore(
1137
- molecule,
1138
- withdraw(f, store),
1139
- newest(store)
1140
- ),
1217
+ bond: (token2, maybeRole) => {
1218
+ if (token2.type === `join`) {
1219
+ const { as: role } = maybeRole;
1220
+ const join = getJoin(token2, store);
1221
+ join.molecules.set(stringKey, molecule);
1222
+ molecule.joins.set(token2.key, join);
1223
+ const unsubFromFamily = family.subject.subscribe(
1224
+ `join:${token2.key}-${stringKey}`,
1225
+ (event) => {
1226
+ if (event.type === `molecule_disposal` && stringifyJson(event.token.key) === stringKey) {
1227
+ unsubFromFamily();
1228
+ join.molecules.delete(stringKey);
1229
+ }
1230
+ }
1231
+ );
1232
+ if (role === null) {
1233
+ return;
1234
+ }
1235
+ const otherRole = token2.a === role ? token2.b : token2.a;
1236
+ const relations = findRelations(token2, key);
1237
+ const relatedKeys = relations[`${otherRole}KeysOf${capitalize2(role)}`];
1238
+ const relatedEntries = relations[`${otherRole}EntriesOf${capitalize2(role)}`];
1239
+ let tokens = { relatedKeys };
1240
+ if (relatedEntries) {
1241
+ tokens = Object.assign(tokens, { relatedEntries });
1242
+ }
1243
+ return tokens;
1244
+ }
1245
+ return growMoleculeInStore(molecule, withdraw(token2, store), newest(store));
1246
+ },
1141
1247
  claim: (below, options) => {
1142
1248
  const { exclusive } = options;
1143
1249
  const belowMolecule = newest(store).molecules.get(stringifyJson(below.key));
@@ -1155,12 +1261,6 @@ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1155
1261
  }
1156
1262
  }
1157
1263
  },
1158
- join: (joinToken) => {
1159
- const join = getJoin(joinToken, store);
1160
- join.molecules.set(stringifyJson(key), molecule);
1161
- molecule.joins.set(joinToken.key, join);
1162
- return joinToken;
1163
- },
1164
1264
  spawn: (f, k, ...p) => makeMoleculeInStore(
1165
1265
  newest(store),
1166
1266
  [molecule],
@@ -1171,7 +1271,7 @@ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1171
1271
  };
1172
1272
  const family = withdraw(familyToken, store);
1173
1273
  const Constructor = family.new;
1174
- molecule.instance = new Constructor(transactors, key, ...params);
1274
+ molecule.instance = new Constructor(toolkit, key, ...params);
1175
1275
  const token = {
1176
1276
  type: `molecule`,
1177
1277
  key,
@@ -1472,18 +1572,18 @@ var buildTransaction = (key, params, store, id) => {
1472
1572
  params,
1473
1573
  output: void 0
1474
1574
  },
1475
- transactors: {
1476
- get: (token) => getFromStore(token, child),
1477
- set: (token, value) => {
1478
- setIntoStore(token, value, child);
1575
+ toolkit: {
1576
+ get: (...ps) => getFromStore(...ps, child),
1577
+ set: (...ps) => {
1578
+ setIntoStore(...ps, child);
1479
1579
  },
1480
1580
  run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1481
1581
  find: (token, k) => findInStore(token, k, child),
1482
1582
  seek: (token, k) => seekInStore(token, k, child),
1483
1583
  json: (token) => getJsonToken(token, child),
1484
1584
  make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
1485
- dispose: (token) => {
1486
- disposeFromStore(token, child);
1585
+ dispose: (...ps) => {
1586
+ disposeFromStore(...ps, child);
1487
1587
  },
1488
1588
  env: () => getEnvironmentData(child)
1489
1589
  }
@@ -1511,8 +1611,8 @@ function createTransaction(options, store) {
1511
1611
  const childStore = buildTransaction(options.key, params, store, id);
1512
1612
  try {
1513
1613
  const target2 = newest(store);
1514
- const { transactors } = childStore.transactionMeta;
1515
- const output = options.do(transactors, ...params);
1614
+ const { toolkit } = childStore.transactionMeta;
1615
+ const output = options.do(toolkit, ...params);
1516
1616
  applyTransaction(output, target2);
1517
1617
  return output;
1518
1618
  } catch (thrown) {
@@ -1628,6 +1728,7 @@ var Store = class {
1628
1728
  for (const logger of this.loggers) logger.warn(...messages);
1629
1729
  }
1630
1730
  };
1731
+ this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
1631
1732
  if (store !== null) {
1632
1733
  this.valueMap = new Map(store == null ? void 0 : store.valueMap);
1633
1734
  this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
@@ -1639,7 +1740,6 @@ var Store = class {
1639
1740
  )
1640
1741
  };
1641
1742
  }
1642
- this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
1643
1743
  for (const [, family] of store.families) {
1644
1744
  family.install(this);
1645
1745
  }
@@ -1,15 +1,68 @@
1
- import type { MoleculeToken, ReadableToken } from "atom.io"
1
+ import type {
2
+ MoleculeConstructor,
3
+ MoleculeFamilyToken,
4
+ MoleculeKey,
5
+ MoleculeToken,
6
+ ReadableFamilyToken,
7
+ ReadableToken,
8
+ } from "atom.io"
9
+ import type { Json } from "atom.io/json"
2
10
 
3
11
  import { disposeAtom } from "../atom"
4
12
  import { disposeMolecule } from "../molecule/dispose-molecule"
13
+ import { NotFoundError } from "../not-found-error"
5
14
  import { disposeSelector } from "../selector"
6
15
  import type { Store } from "../store"
7
- import { IMPLICIT } from "../store"
16
+ import { findInStore } from "./find-in-store"
17
+ import { seekInStore } from "./seek-in-store"
8
18
 
9
19
  export function disposeFromStore(
10
20
  token: MoleculeToken<any> | ReadableToken<any>,
11
- store: Store = IMPLICIT.STORE,
21
+ store: Store,
22
+ ): void
23
+
24
+ export function disposeFromStore<K extends Json.Serializable>(
25
+ token: ReadableFamilyToken<any, K>,
26
+ key: K,
27
+ store: Store,
28
+ ): void
29
+
30
+ export function disposeFromStore<M extends MoleculeConstructor>(
31
+ token: MoleculeFamilyToken<M>,
32
+ key: MoleculeKey<M>,
33
+ store: Store,
34
+ ): void
35
+
36
+ export function disposeFromStore(
37
+ ...params:
38
+ | [
39
+ token: ReadableFamilyToken<any, any>,
40
+ key: Json.Serializable,
41
+ store: Store,
42
+ ]
43
+ | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>, store: Store]
44
+ | [token: MoleculeToken<any> | ReadableToken<any>, store: Store]
12
45
  ): void {
46
+ let token: MoleculeToken<any> | ReadableToken<any>
47
+ let store: Store
48
+ if (params.length === 2) {
49
+ token = params[0]
50
+ store = params[1]
51
+ } else {
52
+ const family = params[0]
53
+ const key = params[1]
54
+ store = params[2]
55
+ const maybeToken =
56
+ family.type === `molecule_family`
57
+ ? seekInStore(family, key, store)
58
+ : store.config.lifespan === `immortal`
59
+ ? seekInStore(family, key, store)
60
+ : findInStore(family, key, store)
61
+ if (!maybeToken) {
62
+ throw new NotFoundError(family, key, store)
63
+ }
64
+ token = maybeToken
65
+ }
13
66
  switch (token.type) {
14
67
  case `atom`:
15
68
  case `mutable_atom`:
@@ -1,39 +1,72 @@
1
- import type { MoleculeConstructor, MoleculeToken, ReadableToken } from "atom.io"
1
+ import type {
2
+ MoleculeConstructor,
3
+ MoleculeFamilyToken,
4
+ MoleculeKey,
5
+ MoleculeToken,
6
+ ReadableFamilyToken,
7
+ ReadableToken,
8
+ } from "atom.io"
9
+ import type { Json } from "atom.io/json"
2
10
 
11
+ import { findInStore, seekInStore } from "../families"
12
+ import { NotFoundError } from "../not-found-error"
3
13
  import type { Store } from "../store"
4
14
  import { withdraw } from "../store"
5
15
  import { readOrComputeValue } from "./read-or-compute-value"
6
16
 
7
17
  export function getFromStore<T>(token: ReadableToken<T>, store: Store): T
18
+
8
19
  export function getFromStore<M extends MoleculeConstructor>(
9
20
  token: MoleculeToken<M>,
10
21
  store: Store,
11
22
  ): InstanceType<M> | undefined
12
- export function getFromStore<
13
- T,
14
- M extends MoleculeConstructor,
15
- Token extends MoleculeToken<M> | ReadableToken<T>,
16
- >(token: Token, store: Store): InstanceType<M> | T | undefined
17
- export function getFromStore<
18
- Token extends MoleculeToken<any> | ReadableToken<any>,
19
- >(
20
- token: Token,
23
+
24
+ export function getFromStore<T, K extends Json.Serializable>(
25
+ token: ReadableFamilyToken<T, K>,
26
+ key: K,
21
27
  store: Store,
22
- ):
23
- | (Token extends MoleculeToken<infer M>
24
- ? InstanceType<M>
25
- : Token extends ReadableToken<infer T>
26
- ? T
27
- : never)
28
- | undefined {
29
- if (token.type === `molecule`) {
30
- try {
31
- const molecule = withdraw(token, store)
32
- return molecule.instance
33
- } catch (_) {
34
- return undefined
28
+ ): T
29
+
30
+ export function getFromStore<M extends MoleculeConstructor>(
31
+ token: MoleculeFamilyToken<M>,
32
+ key: MoleculeKey<M>,
33
+ store: Store,
34
+ ): InstanceType<M>
35
+
36
+ export function getFromStore<T>(
37
+ ...params:
38
+ | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>, store: Store]
39
+ | [token: MoleculeToken<any>, store: Store]
40
+ | [token: ReadableFamilyToken<T, any>, key: Json.Serializable, store: Store]
41
+ | [token: ReadableToken<T>, store: Store]
42
+ ): any {
43
+ let token: MoleculeToken<any> | ReadableToken<T>
44
+ let store: Store
45
+ if (params.length === 2) {
46
+ token = params[0]
47
+ store = params[1]
48
+ } else {
49
+ const family = params[0]
50
+ const key = params[1]
51
+ store = params[2]
52
+ const maybeToken =
53
+ family.type === `molecule_family`
54
+ ? seekInStore(family, key, store)
55
+ : store.config.lifespan === `immortal`
56
+ ? seekInStore(family, key, store)
57
+ : findInStore(family, key, store)
58
+ if (!maybeToken) {
59
+ throw new NotFoundError(family, key, store)
35
60
  }
61
+ token = maybeToken
62
+ }
63
+ switch (token.type) {
64
+ case `atom`:
65
+ case `mutable_atom`:
66
+ case `selector`:
67
+ case `readonly_selector`:
68
+ return readOrComputeValue(withdraw(token, store), store)
69
+ case `molecule`:
70
+ return withdraw(token, store).instance
36
71
  }
37
- const state = withdraw(token, store)
38
- return readOrComputeValue(state, store)
39
72
  }