atom.io 0.27.4 → 0.28.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 (134) hide show
  1. package/data/dist/index.d.ts +31 -29
  2. package/data/dist/index.js +65 -81
  3. package/data/src/dict.ts +9 -12
  4. package/data/src/join.ts +30 -33
  5. package/data/src/struct-family.ts +17 -23
  6. package/data/src/struct.ts +9 -12
  7. package/dist/{chunk-JRENM6KL.js → chunk-BX3MTH2Z.js} +482 -385
  8. package/dist/chunk-D52JNVER.js +721 -0
  9. package/dist/chunk-EUVKUTW3.js +89 -0
  10. package/dist/index.d.ts +4 -3
  11. package/dist/index.js +35 -53
  12. package/ephemeral/dist/index.js +1 -1
  13. package/ephemeral/src/find-state.ts +1 -1
  14. package/immortal/dist/index.js +2 -2
  15. package/immortal/src/seek-state.ts +2 -2
  16. package/internal/dist/index.d.ts +141 -87
  17. package/internal/dist/index.js +1 -1
  18. package/internal/src/atom/create-regular-atom.ts +3 -3
  19. package/internal/src/atom/create-standalone-atom.ts +7 -5
  20. package/internal/src/atom/dispose-atom.ts +2 -9
  21. package/internal/src/families/create-atom-family.ts +5 -5
  22. package/internal/src/families/create-readonly-selector-family.ts +20 -9
  23. package/internal/src/families/create-regular-atom-family.ts +15 -6
  24. package/internal/src/families/create-selector-family.ts +5 -5
  25. package/internal/src/families/create-writable-selector-family.ts +20 -10
  26. package/internal/src/families/dispose-from-store.ts +43 -29
  27. package/internal/src/families/find-in-store.ts +28 -18
  28. package/internal/src/families/init-family-member.ts +9 -9
  29. package/internal/src/families/seek-in-store.ts +10 -10
  30. package/internal/src/get-state/get-from-store.ts +70 -47
  31. package/internal/src/ingest-updates/ingest-atom-update.ts +1 -1
  32. package/internal/src/ingest-updates/ingest-creation-disposal.ts +15 -6
  33. package/internal/src/molecule/create-molecule-family.ts +1 -1
  34. package/internal/src/molecule/dispose-molecule.ts +7 -18
  35. package/internal/src/molecule/grow-molecule-in-store.ts +1 -1
  36. package/internal/src/molecule/make-molecule-in-store.ts +5 -5
  37. package/internal/src/mutable/create-mutable-atom-family.ts +15 -6
  38. package/internal/src/mutable/create-mutable-atom.ts +3 -3
  39. package/internal/src/mutable/get-json-token.ts +2 -2
  40. package/internal/src/mutable/tracker-family.ts +3 -3
  41. package/internal/src/mutable/tracker.ts +14 -18
  42. package/internal/src/pretty-print.ts +1 -16
  43. package/internal/src/selector/create-readonly-selector.ts +2 -2
  44. package/internal/src/selector/create-standalone-selector.ts +5 -5
  45. package/internal/src/selector/create-writable-selector.ts +2 -2
  46. package/internal/src/selector/dispose-selector.ts +2 -9
  47. package/internal/src/selector/register-selector.ts +9 -9
  48. package/internal/src/set-state/set-into-store.ts +23 -33
  49. package/internal/src/store/circular-buffer.ts +34 -0
  50. package/internal/src/store/counterfeit.ts +109 -0
  51. package/internal/src/store/deposit.ts +67 -13
  52. package/internal/src/store/index.ts +1 -0
  53. package/internal/src/store/store.ts +4 -1
  54. package/internal/src/store/withdraw.ts +15 -10
  55. package/internal/src/subscribe/index.ts +2 -0
  56. package/internal/src/subscribe/subscribe-in-store.ts +62 -0
  57. package/internal/src/timeline/time-travel.ts +1 -1
  58. package/internal/src/transaction/build-transaction.ts +7 -6
  59. package/introspection/dist/index.d.ts +84 -4
  60. package/introspection/dist/index.js +1 -413
  61. package/introspection/src/attach-atom-index.ts +5 -8
  62. package/introspection/src/attach-introspection-states.ts +7 -4
  63. package/introspection/src/attach-selector-index.ts +6 -8
  64. package/introspection/src/attach-timeline-family.ts +25 -28
  65. package/introspection/src/attach-timeline-index.ts +5 -8
  66. package/introspection/src/attach-transaction-index.ts +5 -8
  67. package/introspection/src/attach-transaction-logs.ts +21 -27
  68. package/introspection/src/attach-type-selectors.ts +26 -0
  69. package/introspection/src/differ.ts +167 -0
  70. package/introspection/src/index.ts +2 -0
  71. package/introspection/src/refinery.ts +100 -0
  72. package/json/dist/index.d.ts +31 -30
  73. package/json/dist/index.js +2 -80
  74. package/json/src/entries.ts +6 -0
  75. package/json/src/index.ts +47 -6
  76. package/json/src/select-json-family.ts +4 -4
  77. package/json/src/select-json.ts +6 -9
  78. package/package.json +17 -8
  79. package/react/dist/index.js +7 -7
  80. package/react/src/parse-state-overloads.ts +2 -2
  81. package/react/src/use-i.ts +1 -1
  82. package/react/src/use-json.ts +2 -2
  83. package/react/src/use-o.ts +2 -2
  84. package/react-devtools/dist/index.d.ts +1 -91
  85. package/react-devtools/dist/index.js +285 -414
  86. package/react-devtools/src/AtomIODevtools.tsx +2 -2
  87. package/react-devtools/src/StateEditor.tsx +20 -12
  88. package/react-devtools/src/StateIndex.tsx +8 -26
  89. package/react-devtools/src/TimelineIndex.tsx +3 -3
  90. package/react-devtools/src/TransactionIndex.tsx +6 -6
  91. package/react-devtools/src/Updates.tsx +1 -4
  92. package/react-devtools/src/index.ts +0 -71
  93. package/react-devtools/src/store.ts +51 -0
  94. package/realtime/dist/index.d.ts +7 -7
  95. package/realtime/dist/index.js +18 -22
  96. package/realtime/src/realtime-continuity.ts +27 -35
  97. package/realtime-client/dist/index.js +59 -65
  98. package/realtime-client/src/pull-atom-family-member.ts +1 -1
  99. package/realtime-client/src/pull-atom.ts +1 -1
  100. package/realtime-client/src/pull-mutable-atom-family-member.ts +3 -3
  101. package/realtime-client/src/pull-mutable-atom.ts +3 -3
  102. package/realtime-client/src/realtime-client-stores/client-main-store.ts +6 -6
  103. package/realtime-client/src/sync-continuity.ts +55 -53
  104. package/realtime-react/dist/index.js +3 -3
  105. package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
  106. package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
  107. package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
  108. package/realtime-server/dist/index.js +72 -36
  109. package/realtime-server/src/realtime-continuity-synchronizer.ts +57 -93
  110. package/realtime-server/src/realtime-family-provider.ts +3 -3
  111. package/realtime-server/src/realtime-mutable-family-provider.ts +5 -5
  112. package/realtime-server/src/realtime-mutable-provider.ts +2 -2
  113. package/realtime-server/src/realtime-state-provider.ts +1 -1
  114. package/realtime-server/src/realtime-state-receiver.ts +1 -1
  115. package/realtime-testing/dist/index.d.ts +2 -0
  116. package/realtime-testing/dist/index.js +57 -15
  117. package/realtime-testing/src/setup-realtime-test.tsx +66 -16
  118. package/src/atom.ts +2 -2
  119. package/src/dispose-state.ts +2 -2
  120. package/src/get-state.ts +9 -13
  121. package/src/molecule.ts +1 -1
  122. package/src/selector.ts +2 -2
  123. package/src/set-state.ts +10 -7
  124. package/src/silo.ts +29 -55
  125. package/src/subscribe.ts +3 -23
  126. package/src/timeline.ts +2 -2
  127. package/web/dist/index.d.ts +9 -0
  128. package/{dist/chunk-H6EDLPKH.js → web/dist/index.js} +5 -4
  129. package/web/package.json +13 -0
  130. package/web/src/index.ts +1 -0
  131. package/web/src/persist-sync.ts +25 -0
  132. package/dist/chunk-AK23DRMD.js +0 -21
  133. package/dist/chunk-IW6WYRS7.js +0 -140
  134. package/internal/src/families/throw-in-case-of-conflicting-family.ts +0 -18
@@ -10,16 +10,15 @@ import type {
10
10
  import type { Canonical } from "atom.io/json"
11
11
  import { stringifyJson } from "atom.io/json"
12
12
 
13
- import type { RegularAtomFamily } from ".."
13
+ import { prettyPrintTokenType, type RegularAtomFamily } from ".."
14
14
  import { createRegularAtom } from "../atom"
15
15
  import { newest } from "../lineage"
16
16
  import type { Store } from "../store"
17
17
  import { Subject } from "../subject"
18
- import { throwInCaseOfConflictingFamily } from "./throw-in-case-of-conflicting-family"
19
18
 
20
19
  export function createRegularAtomFamily<T, K extends Canonical>(
21
- options: RegularAtomFamilyOptions<T, K>,
22
20
  store: Store,
21
+ options: RegularAtomFamilyOptions<T, K>,
23
22
  internalRoles?: string[],
24
23
  ): RegularAtomFamilyToken<T, K> {
25
24
  const familyToken = {
@@ -27,7 +26,17 @@ export function createRegularAtomFamily<T, K extends Canonical>(
27
26
  type: `atom_family`,
28
27
  } as const satisfies RegularAtomFamilyToken<T, K>
29
28
 
30
- throwInCaseOfConflictingFamily(familyToken, store)
29
+ const existing = store.families.get(options.key)
30
+ if (existing) {
31
+ store.logger.error(
32
+ `❗`,
33
+ `atom_family`,
34
+ options.key,
35
+ `Overwriting an existing ${prettyPrintTokenType(
36
+ existing,
37
+ )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
38
+ )
39
+ }
31
40
 
32
41
  const subject = new Subject<
33
42
  StateCreation<RegularAtomToken<T>> | StateDisposal<RegularAtomToken<T>>
@@ -48,7 +57,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
48
57
  individualOptions.effects = options.effects(key)
49
58
  }
50
59
 
51
- const token = createRegularAtom(individualOptions, family, target)
60
+ const token = createRegularAtom(target, individualOptions, family)
52
61
 
53
62
  subject.next({ type: `state_creation`, token })
54
63
  return token
@@ -56,7 +65,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
56
65
 
57
66
  const atomFamily = Object.assign(familyFunction, familyToken, {
58
67
  subject,
59
- install: (s: Store) => createRegularAtomFamily(options, s),
68
+ install: (s: Store) => createRegularAtomFamily(s, options),
60
69
  internalRoles,
61
70
  }) satisfies RegularAtomFamily<T, K>
62
71
 
@@ -12,23 +12,23 @@ import { createReadonlySelectorFamily } from "./create-readonly-selector-family"
12
12
  import { createWritableSelectorFamily } from "./create-writable-selector-family"
13
13
 
14
14
  export function createSelectorFamily<T, K extends Canonical>(
15
- options: WritableSelectorFamilyOptions<T, K>,
16
15
  store: Store,
16
+ options: WritableSelectorFamilyOptions<T, K>,
17
17
  ): WritableSelectorFamilyToken<T, K>
18
18
  export function createSelectorFamily<T, K extends Canonical>(
19
- options: ReadonlySelectorFamilyOptions<T, K>,
20
19
  store: Store,
20
+ options: ReadonlySelectorFamilyOptions<T, K>,
21
21
  ): ReadonlySelectorFamilyToken<T, K>
22
22
  export function createSelectorFamily<T, K extends Canonical>(
23
+ store: Store,
23
24
  options:
24
25
  | ReadonlySelectorFamilyOptions<T, K>
25
26
  | WritableSelectorFamilyOptions<T, K>,
26
- store: Store,
27
27
  ): SelectorFamilyToken<T, K> {
28
28
  const isWritable = `set` in options
29
29
 
30
30
  if (isWritable) {
31
- return createWritableSelectorFamily(options, store)
31
+ return createWritableSelectorFamily(store, options)
32
32
  }
33
- return createReadonlySelectorFamily(options, store)
33
+ return createReadonlySelectorFamily(store, options)
34
34
  }
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  FamilyMetadata,
3
+ getState,
3
4
  StateCreation,
4
5
  StateDisposal,
5
6
  WritableSelectorFamilyOptions,
@@ -15,6 +16,7 @@ import {
15
16
  findInStore,
16
17
  getFromStore,
17
18
  getJsonToken,
19
+ prettyPrintTokenType,
18
20
  seekInStore,
19
21
  type WritableSelectorFamily,
20
22
  } from ".."
@@ -22,11 +24,10 @@ import { newest } from "../lineage"
22
24
  import { createWritableSelector } from "../selector"
23
25
  import type { Store } from "../store"
24
26
  import { Subject } from "../subject"
25
- import { throwInCaseOfConflictingFamily } from "./throw-in-case-of-conflicting-family"
26
27
 
27
28
  export function createWritableSelectorFamily<T, K extends Canonical>(
28
- options: WritableSelectorFamilyOptions<T, K>,
29
29
  store: Store,
30
+ options: WritableSelectorFamilyOptions<T, K>,
30
31
  internalRoles?: string[],
31
32
  ): WritableSelectorFamilyToken<T, K> {
32
33
  const familyToken = {
@@ -34,8 +35,17 @@ export function createWritableSelectorFamily<T, K extends Canonical>(
34
35
  type: `selector_family`,
35
36
  } as const satisfies WritableSelectorFamilyToken<T, K>
36
37
 
37
- throwInCaseOfConflictingFamily(familyToken, store)
38
-
38
+ const existing = store.families.get(options.key)
39
+ if (existing) {
40
+ store.logger.error(
41
+ `❗`,
42
+ `selector_family`,
43
+ options.key,
44
+ `Overwriting an existing ${prettyPrintTokenType(
45
+ existing,
46
+ )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
47
+ )
48
+ }
39
49
  const subject = new Subject<
40
50
  | StateCreation<WritableSelectorToken<T>>
41
51
  | StateDisposal<WritableSelectorToken<T>>
@@ -48,13 +58,13 @@ export function createWritableSelectorFamily<T, K extends Canonical>(
48
58
  const target = newest(store)
49
59
 
50
60
  const token = createWritableSelector(
61
+ target,
51
62
  {
52
63
  key: fullKey,
53
64
  get: options.get(key),
54
65
  set: options.set(key),
55
66
  },
56
67
  family,
57
- target,
58
68
  )
59
69
 
60
70
  subject.next({ type: `state_creation`, token })
@@ -64,14 +74,14 @@ export function createWritableSelectorFamily<T, K extends Canonical>(
64
74
  const selectorFamily = Object.assign(familyFunction, familyToken, {
65
75
  internalRoles,
66
76
  subject,
67
- install: (s: Store) => createWritableSelectorFamily(options, s),
77
+ install: (s: Store) => createWritableSelectorFamily(s, options),
68
78
  default: (key: K) => {
69
79
  const getFn = options.get(key)
70
80
  return getFn({
71
- get: (...params: [any]) => getFromStore(...params, store), // TODO: make store zero-arg
72
- find: ((token, k) => findInStore(token, k, store)) as typeof findState,
73
- seek: ((token, k) => seekInStore(token, k, store)) as typeof seekState,
74
- json: (token) => getJsonToken(token, store),
81
+ get: ((...ps: [any]) => getFromStore(store, ...ps)) as typeof getState,
82
+ find: ((token, k) => findInStore(store, token, k)) as typeof findState,
83
+ seek: ((token, k) => seekInStore(store, token, k)) as typeof seekState,
84
+ json: (token) => getJsonToken(store, token),
75
85
  })
76
86
  },
77
87
  }) satisfies WritableSelectorFamily<T, K>
@@ -6,68 +6,75 @@ import type {
6
6
  ReadableFamilyToken,
7
7
  ReadableToken,
8
8
  } from "atom.io"
9
- import { type Canonical, stringifyJson } from "atom.io/json"
9
+ import type { Canonical } from "atom.io/json"
10
10
 
11
11
  import { disposeAtom } from "../atom"
12
12
  import { disposeMolecule } from "../molecule/dispose-molecule"
13
- import { NotFoundError } from "../not-found-error"
14
13
  import { disposeSelector } from "../selector"
15
- import type { Store } from "../store"
14
+ import { counterfeit, type Store, withdraw } from "../store"
16
15
  import { findInStore } from "./find-in-store"
17
16
  import { seekInStore } from "./seek-in-store"
18
17
 
19
18
  export function disposeFromStore(
20
- token: MoleculeToken<any> | ReadableToken<any>,
21
19
  store: Store,
20
+ token: MoleculeToken<any> | ReadableToken<any>,
22
21
  ): void
23
22
 
24
23
  export function disposeFromStore<K extends Canonical>(
24
+ store: Store,
25
25
  token: ReadableFamilyToken<any, K>,
26
26
  key: K,
27
- store: Store,
28
27
  ): void
29
28
 
30
29
  export function disposeFromStore<M extends MoleculeConstructor>(
30
+ store: Store,
31
31
  token: MoleculeFamilyToken<M>,
32
32
  key: MoleculeKey<M>,
33
- store: Store,
34
33
  ): void
35
34
 
36
35
  export function disposeFromStore(
36
+ store: Store,
37
37
  ...params:
38
- | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>, store: Store]
39
- | [token: MoleculeToken<any> | ReadableToken<any>, store: Store]
40
- | [token: ReadableFamilyToken<any, any>, key: Canonical, store: Store]
38
+ | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>]
39
+ | [token: MoleculeToken<any> | ReadableToken<any>]
40
+ | [token: ReadableFamilyToken<any, any>, key: Canonical]
41
41
  ): void {
42
42
  let token: MoleculeToken<any> | ReadableToken<any>
43
- let store: Store
44
- if (params.length === 2) {
43
+ let fullKey: string
44
+ if (params.length === 1) {
45
45
  token = params[0]
46
- store = params[1]
46
+ fullKey = token.key
47
47
  } else {
48
48
  const family = params[0]
49
49
  const key = params[1]
50
- store = params[2]
51
50
  const maybeToken =
52
51
  family.type === `molecule_family`
53
- ? seekInStore(family, key, store)
54
- : store.config.lifespan === `immortal`
55
- ? seekInStore(family, key, store)
56
- : findInStore(family, key, store)
57
- if (!maybeToken) {
58
- store.logger.error(
59
- `❗`,
60
- family.type,
61
- family.key,
62
- `tried to dispose of member`,
63
- stringifyJson(key),
64
- `but it was not found in store`,
65
- store.config.name,
66
- )
67
- return
68
- }
52
+ ? seekInStore(store, family, key) ?? counterfeit(family, key)
53
+ : findInStore(store, family, key)
69
54
  token = maybeToken
70
55
  }
56
+ try {
57
+ withdraw(token, store)
58
+ } catch (thrown) {
59
+ const disposal = store.disposalTraces.buffer.find(
60
+ (item) => item?.key === token.key,
61
+ )
62
+ console.log(
63
+ `seeking disposal trace for`,
64
+ token,
65
+ store.disposalTraces.buffer.filter(Boolean),
66
+ )
67
+ store.logger.error(
68
+ `❌`,
69
+ token.type,
70
+ token.key,
71
+ `could not be disposed because it was not found in the store "${store.config.name}".`,
72
+ disposal
73
+ ? `\n This state was most recently disposed\n${disposal.trace}`
74
+ : `No previous disposal trace was found.`,
75
+ )
76
+ return
77
+ }
71
78
  switch (token.type) {
72
79
  case `atom`:
73
80
  case `mutable_atom`:
@@ -81,4 +88,11 @@ export function disposeFromStore(
81
88
  disposeMolecule(token, store)
82
89
  break
83
90
  }
91
+
92
+ const { stack } = new Error()
93
+ if (stack) {
94
+ const trace = stack?.split(`\n`)?.slice(3)?.join(`\n`)
95
+ store.disposalTraces.add({ key: token.key, trace })
96
+ console.log(`added`, token)
97
+ }
84
98
  }
@@ -16,10 +16,11 @@ import type {
16
16
  WritableSelectorToken,
17
17
  WritableToken,
18
18
  } from "atom.io"
19
- import type { Canonical, Json } from "atom.io/json"
19
+ import { type Canonical, type Json, stringifyJson } from "atom.io/json"
20
20
 
21
+ import { growMoleculeInStore } from "../molecule"
21
22
  import type { Transceiver } from "../mutable"
22
- import type { Store } from "../store"
23
+ import { counterfeit, type Store } from "../store"
23
24
  import { initFamilyMemberInStore } from "./init-family-member"
24
25
  import { seekInStore } from "./seek-in-store"
25
26
 
@@ -29,67 +30,76 @@ export function findInStore<
29
30
  K extends Canonical,
30
31
  Key extends K,
31
32
  >(
33
+ store: Store,
32
34
  token: MutableAtomFamilyToken<T, J, K>,
33
35
  key: Key,
34
- store: Store,
35
36
  ): MutableAtomToken<T, J>
36
37
 
37
38
  export function findInStore<T, K extends Canonical, Key extends K>(
39
+ store: Store,
38
40
  token: RegularAtomFamilyToken<T, K>,
39
41
  key: Key,
40
- store: Store,
41
42
  ): RegularAtomToken<T>
42
43
 
43
44
  export function findInStore<T, K extends Canonical, Key extends K>(
45
+ store: Store,
44
46
  token: AtomFamilyToken<T, K>,
45
47
  key: Key,
46
- store: Store,
47
48
  ): AtomToken<T>
48
49
 
49
50
  export function findInStore<T, K extends Canonical, Key extends K>(
51
+ store: Store,
50
52
  token: WritableSelectorFamilyToken<T, K>,
51
53
  key: Key,
52
- store: Store,
53
54
  ): WritableSelectorToken<T>
54
55
 
55
56
  export function findInStore<T, K extends Canonical, Key extends K>(
57
+ store: Store,
56
58
  token: ReadonlySelectorFamilyToken<T, K>,
57
59
  key: Key,
58
- store: Store,
59
60
  ): ReadonlySelectorToken<T>
60
61
 
61
62
  export function findInStore<T, K extends Canonical, Key extends K>(
63
+ store: Store,
62
64
  token: SelectorFamilyToken<T, K>,
63
65
  key: Key,
64
- store: Store,
65
66
  ): SelectorToken<T>
66
67
 
67
68
  export function findInStore<T, K extends Canonical, Key extends K>(
69
+ store: Store,
68
70
  token: WritableFamilyToken<T, K>,
69
71
  key: Key,
70
- store: Store,
71
72
  ): WritableToken<T>
72
73
 
73
74
  export function findInStore<T, K extends Canonical, Key extends K>(
75
+ store: Store,
74
76
  token: ReadableFamilyToken<T, K>,
75
77
  key: Key,
76
- store: Store,
77
78
  ): ReadableToken<T>
78
79
 
79
80
  export function findInStore(
81
+ store: Store,
80
82
  token: ReadableFamilyToken<any, any>,
81
83
  key: Json.Serializable,
82
- store: Store,
83
84
  ): ReadableToken<any> {
84
- if (store.config.lifespan === `immortal`) {
85
- throw new Error(
86
- `Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`,
87
- )
88
- }
89
- let state = seekInStore(token, key, store)
85
+ let state = seekInStore(store, token, key)
90
86
  if (state) {
91
87
  return state
92
88
  }
93
- state = initFamilyMemberInStore(token, key, store)
89
+ const molecule = store.molecules.get(stringifyJson(key))
90
+ if (molecule) {
91
+ return growMoleculeInStore(molecule, token, store)
92
+ }
93
+ if (store.config.lifespan === `immortal`) {
94
+ const fakeToken = counterfeit(token, key)
95
+ store.logger.error(
96
+ `❌`,
97
+ fakeToken.type,
98
+ fakeToken.key,
99
+ `was not found in store "${store.config.name}"; returned a counterfeit token.`,
100
+ )
101
+ return fakeToken
102
+ }
103
+ state = initFamilyMemberInStore(store, token, key)
94
104
  return state
95
105
  }
@@ -30,57 +30,57 @@ export function initFamilyMemberInStore<
30
30
  K extends Canonical,
31
31
  Key extends K,
32
32
  >(
33
+ store: Store,
33
34
  token: MutableAtomFamilyToken<T, J, K>,
34
35
  key: Key,
35
- store: Store,
36
36
  ): MutableAtomToken<T, J>
37
37
 
38
38
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
39
+ store: Store,
39
40
  token: RegularAtomFamilyToken<T, K>,
40
41
  key: Key,
41
- store: Store,
42
42
  ): RegularAtomToken<T>
43
43
 
44
44
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
45
+ store: Store,
45
46
  token: AtomFamilyToken<T, K>,
46
47
  key: Key,
47
- store: Store,
48
48
  ): AtomToken<T>
49
49
 
50
50
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
51
+ store: Store,
51
52
  token: WritableSelectorFamilyToken<T, K>,
52
53
  key: Key,
53
- store: Store,
54
54
  ): WritableSelectorToken<T>
55
55
 
56
56
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
57
+ store: Store,
57
58
  token: ReadonlySelectorFamilyToken<T, K>,
58
59
  key: Key,
59
- store: Store,
60
60
  ): ReadonlySelectorToken<T>
61
61
 
62
62
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
63
+ store: Store,
63
64
  token: SelectorFamilyToken<T, K>,
64
65
  key: Key,
65
- store: Store,
66
66
  ): SelectorToken<T>
67
67
 
68
68
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
69
+ store: Store,
69
70
  token: WritableFamilyToken<T, K>,
70
71
  key: Key,
71
- store: Store,
72
72
  ): WritableToken<T>
73
73
 
74
74
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
75
+ store: Store,
75
76
  token: ReadableFamilyToken<T, K>,
76
77
  key: Key,
77
- store: Store,
78
78
  ): ReadableToken<T>
79
79
 
80
80
  export function initFamilyMemberInStore(
81
+ store: Store,
81
82
  token: ReadableFamilyToken<any, any>,
82
83
  key: Json.Serializable,
83
- store: Store,
84
84
  ): ReadableToken<any> {
85
85
  const familyKey = token.key
86
86
  const family = store.families.get(familyKey)
@@ -34,63 +34,63 @@ export function seekInStore<
34
34
  K extends Canonical,
35
35
  Key extends K,
36
36
  >(
37
+ store: Store,
37
38
  token: MutableAtomFamilyToken<T, J, K>,
38
39
  key: Key,
39
- store: Store,
40
40
  ): MutableAtomToken<T, J> | undefined
41
41
 
42
42
  export function seekInStore<T, K extends Canonical, Key extends K>(
43
+ store: Store,
43
44
  token: RegularAtomFamilyToken<T, K>,
44
45
  key: Key,
45
- store: Store,
46
46
  ): RegularAtomToken<T> | undefined
47
47
 
48
48
  export function seekInStore<T, K extends Canonical, Key extends K>(
49
+ store: Store,
49
50
  token: AtomFamilyToken<T, K>,
50
51
  key: Key,
51
- store: Store,
52
52
  ): AtomToken<T> | undefined
53
53
 
54
54
  export function seekInStore<T, K extends Canonical, Key extends K>(
55
+ store: Store,
55
56
  token: WritableSelectorFamilyToken<T, K>,
56
57
  key: Key,
57
- store: Store,
58
58
  ): WritableSelectorToken<T> | undefined
59
59
 
60
60
  export function seekInStore<T, K extends Canonical, Key extends K>(
61
+ store: Store,
61
62
  token: ReadonlySelectorFamilyToken<T, K>,
62
63
  key: Key,
63
- store: Store,
64
64
  ): ReadonlySelectorToken<T> | undefined
65
65
 
66
66
  export function seekInStore<T, K extends Canonical, Key extends K>(
67
+ store: Store,
67
68
  token: SelectorFamilyToken<T, K>,
68
69
  key: Key,
69
- store: Store,
70
70
  ): SelectorToken<T> | undefined
71
71
 
72
72
  export function seekInStore<T, K extends Canonical, Key extends K>(
73
+ store: Store,
73
74
  token: WritableFamilyToken<T, K>,
74
75
  key: Key,
75
- store: Store,
76
76
  ): WritableToken<T> | undefined
77
77
 
78
78
  export function seekInStore<T, K extends Canonical, Key extends K>(
79
+ store: Store,
79
80
  token: ReadableFamilyToken<T, K>,
80
81
  key: Key,
81
- store: Store,
82
82
  ): ReadableToken<T> | undefined
83
83
 
84
84
  export function seekInStore<M extends MoleculeConstructor>(
85
+ store: Store,
85
86
  token: MoleculeFamilyToken<M>,
86
87
  key: MoleculeKey<M>,
87
- store: Store,
88
88
  ): MoleculeKey<M> | undefined
89
89
 
90
90
  export function seekInStore(
91
+ store: Store,
91
92
  token: MoleculeFamilyToken<any> | ReadableFamilyToken<any, any>,
92
93
  key: Canonical,
93
- store: Store,
94
94
  ): MoleculeToken<any> | ReadableToken<any> | undefined {
95
95
  const subKey = stringifyJson(key)
96
96
  const fullKey = `${token.key}(${subKey})`
@@ -11,78 +11,101 @@ import { type Canonical, stringifyJson } from "atom.io/json"
11
11
  import { findInStore, seekInStore } from "../families"
12
12
  import { NotFoundError } from "../not-found-error"
13
13
  import type { Store } from "../store"
14
- import { withdraw } from "../store"
14
+ import { counterfeit, withdraw } from "../store"
15
15
  import { readOrComputeValue } from "./read-or-compute-value"
16
16
 
17
- export function getFromStore<T>(token: ReadableToken<T>, store: Store): T
17
+ export function getFromStore<T>(store: Store, token: ReadableToken<T>): T
18
18
 
19
19
  export function getFromStore<M extends MoleculeConstructor>(
20
- token: MoleculeToken<M>,
21
20
  store: Store,
22
- ): InstanceType<M> | undefined
21
+ token: MoleculeToken<M>,
22
+ ): InstanceType<M>
23
23
 
24
24
  export function getFromStore<T, K extends Canonical>(
25
+ store: Store,
25
26
  token: ReadableFamilyToken<T, K>,
26
27
  key: K,
27
- store: Store,
28
28
  ): T
29
29
 
30
30
  export function getFromStore<M extends MoleculeConstructor>(
31
+ store: Store,
31
32
  token: MoleculeFamilyToken<M>,
32
33
  key: MoleculeKey<M>,
33
- store: Store,
34
34
  ): InstanceType<M>
35
35
 
36
- export function getFromStore<T>(
36
+ export function getFromStore(
37
+ store: Store,
38
+ token: MoleculeToken<any> | ReadableToken<any>,
39
+ ): any
40
+
41
+ export function getFromStore(
42
+ store: Store,
43
+ token: MoleculeFamilyToken<any> | ReadableFamilyToken<any, any>,
44
+ key: Canonical,
45
+ ): any
46
+
47
+ export function getFromStore(
48
+ store: Store,
37
49
  ...params:
38
- | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>, store: Store]
39
- | [token: MoleculeToken<any>, store: Store]
40
- | [token: ReadableFamilyToken<T, any>, key: Canonical, store: Store]
41
- | [token: ReadableToken<T>, store: Store]
50
+ | [
51
+ token: MoleculeFamilyToken<any> | ReadableFamilyToken<any, any>,
52
+ key: Canonical,
53
+ ]
54
+ | [token: MoleculeFamilyToken<any>, key: MoleculeKey<any>]
55
+ | [token: MoleculeToken<any> | ReadableToken<any>]
56
+ | [token: MoleculeToken<any>]
57
+ | [token: ReadableFamilyToken<any, any>, key: Canonical]
58
+ | [token: ReadableToken<any>]
42
59
  ): any {
43
- let token: MoleculeToken<any> | ReadableToken<T>
44
- let store: Store
45
- if (params.length === 2) {
60
+ let token: MoleculeToken<any> | ReadableToken<any>
61
+ if (params.length === 1) {
46
62
  token = params[0]
47
- store = params[1]
48
63
  } else {
49
64
  const family = params[0]
50
65
  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
- store.logger.error(
60
- `❗`,
61
- family.type,
62
- family.key,
63
- `tried to get member`,
64
- stringifyJson(key),
65
- `but it was not found in store`,
66
- store.config.name,
67
- )
68
- switch (family.type) {
69
- case `atom_family`:
70
- case `mutable_atom_family`:
71
- return store.defaults.get(family.key)
72
- case `selector_family`:
73
- case `readonly_selector_family`: {
74
- if (store.defaults.has(family.key)) {
75
- return store.defaults.get(family.key)
76
- }
77
- const defaultValue = withdraw(family, store).default(key)
78
- store.defaults.set(family.key, defaultValue)
79
- return defaultValue
66
+ let maybeToken: MoleculeToken<any> | ReadableToken<any>
67
+ if (family.type === `molecule_family`) {
68
+ maybeToken = seekInStore(store, family, key) ?? counterfeit(family, key)
69
+ } else {
70
+ maybeToken = findInStore(store, family, key)
71
+ }
72
+ token = maybeToken
73
+ }
74
+ if (`counterfeit` in token && `family` in token) {
75
+ const family =
76
+ token.type === `molecule`
77
+ ? withdraw(token.family, store)
78
+ : // biome-ignore lint/style/noNonNullAssertion: family must be present
79
+ store.families.get(token.family.key)!
80
+ const subKey = token.type === `molecule` ? token.key : token.family.subKey
81
+ const disposal = store.disposalTraces.buffer.find(
82
+ (item) => item?.key === token.key,
83
+ )
84
+ store.logger.error(
85
+ `❌`,
86
+ token.type,
87
+ token.key,
88
+ `could not be retrieved because it was not found in the store "${store.config.name}".`,
89
+ disposal
90
+ ? `This state was previously disposed:\n${disposal.trace}`
91
+ : `No previous disposal trace was found.`,
92
+ )
93
+ switch (family.type) {
94
+ case `atom_family`:
95
+ case `mutable_atom_family`:
96
+ return store.defaults.get(family.key)
97
+ case `selector_family`:
98
+ case `readonly_selector_family`: {
99
+ if (store.defaults.has(family.key)) {
100
+ return store.defaults.get(token.family.key)
80
101
  }
81
- case `molecule_family`:
82
- throw new NotFoundError(family, key, store)
102
+ const defaultValue = withdraw(family, store).default(subKey)
103
+ store.defaults.set(family.key, defaultValue)
104
+ return defaultValue
83
105
  }
106
+ case `molecule_family`:
107
+ throw new NotFoundError(family, subKey, store)
84
108
  }
85
- token = maybeToken
86
109
  }
87
110
  switch (token.type) {
88
111
  case `atom`: