atom.io 0.40.0 → 0.40.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/data/index.d.ts +1 -1
  2. package/dist/data/index.d.ts.map +1 -1
  3. package/dist/data/index.js.map +1 -1
  4. package/dist/internal/index.d.ts +205 -196
  5. package/dist/internal/index.d.ts.map +1 -1
  6. package/dist/internal/index.js +145 -107
  7. package/dist/internal/index.js.map +1 -1
  8. package/dist/introspection/index.d.ts +6 -6
  9. package/dist/introspection/index.d.ts.map +1 -1
  10. package/dist/introspection/index.js.map +1 -1
  11. package/dist/main/index.d.ts +93 -66
  12. package/dist/main/index.d.ts.map +1 -1
  13. package/dist/main/index.js +16 -13
  14. package/dist/main/index.js.map +1 -1
  15. package/dist/react/index.d.ts +14 -14
  16. package/dist/react/index.d.ts.map +1 -1
  17. package/dist/react/index.js.map +1 -1
  18. package/dist/react-devtools/index.js +1 -1
  19. package/dist/react-devtools/index.js.map +1 -1
  20. package/dist/realtime-client/index.d.ts +3 -3
  21. package/dist/realtime-client/index.d.ts.map +1 -1
  22. package/dist/realtime-client/index.js +3 -4
  23. package/dist/realtime-client/index.js.map +1 -1
  24. package/dist/realtime-server/index.d.ts +2 -2
  25. package/dist/realtime-server/index.d.ts.map +1 -1
  26. package/package.json +2 -2
  27. package/src/data/struct.ts +2 -2
  28. package/src/internal/atom/create-regular-atom.ts +11 -9
  29. package/src/internal/atom/dispose-atom.ts +11 -8
  30. package/src/internal/atom/has-role.ts +1 -1
  31. package/src/internal/caching.ts +15 -15
  32. package/src/internal/events/ingest-creation-disposal.ts +1 -1
  33. package/src/internal/families/create-readonly-held-selector-family.ts +3 -4
  34. package/src/internal/families/create-readonly-pure-selector-family.ts +25 -23
  35. package/src/internal/families/create-regular-atom-family.ts +21 -15
  36. package/src/internal/families/create-selector-family.ts +15 -15
  37. package/src/internal/families/create-writable-held-selector-family.ts +2 -2
  38. package/src/internal/families/create-writable-pure-selector-family.ts +25 -21
  39. package/src/internal/families/dispose-from-store.ts +17 -7
  40. package/src/internal/families/find-in-store.ts +23 -23
  41. package/src/internal/families/get-family-of-token.ts +17 -17
  42. package/src/internal/families/mint-in-store.ts +10 -10
  43. package/src/internal/families/seek-in-store.ts +26 -26
  44. package/src/internal/get-state/get-fallback.ts +8 -8
  45. package/src/internal/get-state/get-from-store.ts +20 -8
  46. package/src/internal/get-state/read-or-compute-value.ts +78 -14
  47. package/src/internal/get-state/reduce-reference.ts +10 -10
  48. package/src/internal/index.ts +65 -60
  49. package/src/internal/install-into-store.ts +2 -1
  50. package/src/internal/join/create-join.ts +2 -2
  51. package/src/internal/join/find-relations-in-store.ts +2 -2
  52. package/src/internal/join/get-internal-relations-from-store.ts +2 -2
  53. package/src/internal/join/get-join.ts +5 -2
  54. package/src/internal/join/join-internal.ts +30 -26
  55. package/src/internal/lineage.ts +12 -1
  56. package/src/internal/molecule.ts +64 -36
  57. package/src/internal/mutable/create-mutable-atom-family.ts +5 -5
  58. package/src/internal/mutable/create-mutable-atom.ts +2 -2
  59. package/src/internal/mutable/get-json-family.ts +3 -2
  60. package/src/internal/mutable/get-update-family.ts +7 -5
  61. package/src/internal/mutable/tracker-family.ts +8 -4
  62. package/src/internal/mutable/tracker.ts +5 -1
  63. package/src/internal/operation.ts +4 -2
  64. package/src/internal/selector/create-readonly-held-selector.ts +2 -2
  65. package/src/internal/selector/create-readonly-pure-selector.ts +10 -8
  66. package/src/internal/selector/create-standalone-selector.ts +10 -10
  67. package/src/internal/selector/create-writable-held-selector.ts +2 -2
  68. package/src/internal/selector/create-writable-pure-selector.ts +11 -9
  69. package/src/internal/selector/dispose-selector.ts +2 -2
  70. package/src/internal/selector/register-selector.ts +2 -2
  71. package/src/internal/selector/trace-selector-atoms.ts +3 -3
  72. package/src/internal/selector/update-selector-atoms.ts +1 -1
  73. package/src/internal/set-state/become.ts +1 -3
  74. package/src/internal/set-state/dispatch-state-update.ts +10 -6
  75. package/src/internal/set-state/evict-downstream.ts +4 -1
  76. package/src/internal/set-state/operate-on-store.ts +16 -10
  77. package/src/internal/set-state/reset-atom-or-selector.ts +7 -7
  78. package/src/internal/set-state/reset-in-store.ts +17 -16
  79. package/src/internal/set-state/set-atom-or-selector.ts +1 -1
  80. package/src/internal/set-state/set-atom.ts +1 -1
  81. package/src/internal/set-state/set-into-store.ts +34 -7
  82. package/src/internal/set-state/set-selector.ts +1 -1
  83. package/src/internal/store/deposit.ts +38 -30
  84. package/src/internal/store/mint-or-counterfeit.ts +23 -23
  85. package/src/internal/store/store.ts +23 -21
  86. package/src/internal/store/withdraw.ts +68 -62
  87. package/src/internal/subscribe/recall-state.ts +4 -1
  88. package/src/internal/subscribe/subscribe-to-root-atoms.ts +2 -2
  89. package/src/internal/subscribe/subscribe-to-state.ts +4 -4
  90. package/src/internal/timeline/create-timeline.ts +11 -10
  91. package/src/internal/timeline/time-travel.ts +4 -3
  92. package/src/internal/transaction/abort-transaction.ts +3 -15
  93. package/src/internal/transaction/act-upon-store.ts +1 -5
  94. package/src/internal/transaction/apply-transaction.ts +3 -15
  95. package/src/internal/transaction/assign-transaction-to-continuity.ts +2 -7
  96. package/src/internal/transaction/build-transaction.ts +2 -3
  97. package/src/internal/transaction/create-transaction.ts +5 -6
  98. package/src/internal/transaction/get-epoch-number.ts +1 -7
  99. package/src/internal/transaction/set-epoch-number.ts +4 -12
  100. package/src/introspection/attach-atom-index.ts +2 -2
  101. package/src/introspection/attach-introspection-states.ts +4 -2
  102. package/src/introspection/attach-selector-index.ts +4 -2
  103. package/src/introspection/attach-timeline-family.ts +15 -13
  104. package/src/introspection/attach-timeline-index.ts +1 -1
  105. package/src/introspection/attach-transaction-index.ts +1 -1
  106. package/src/introspection/attach-transaction-logs.ts +6 -4
  107. package/src/introspection/attach-type-selectors.ts +4 -3
  108. package/src/introspection/index.ts +3 -5
  109. package/src/main/atom.ts +14 -8
  110. package/src/main/dispose-state.ts +1 -5
  111. package/src/main/events.ts +26 -26
  112. package/src/main/get-state.ts +10 -11
  113. package/src/main/realm.ts +36 -12
  114. package/src/main/reset-state.ts +5 -9
  115. package/src/main/selector.ts +40 -24
  116. package/src/main/set-state.ts +8 -11
  117. package/src/main/silo.ts +4 -3
  118. package/src/main/timeline.ts +5 -3
  119. package/src/main/tokens.ts +72 -44
  120. package/src/main/validators.ts +4 -4
  121. package/src/react/parse-state-overloads.ts +10 -10
  122. package/src/react/store-context.tsx +3 -3
  123. package/src/react/use-i.ts +6 -6
  124. package/src/react/use-loadable.ts +15 -15
  125. package/src/react/use-o.ts +9 -9
  126. package/src/react-devtools/Button.tsx +3 -2
  127. package/src/react-devtools/StateEditor.tsx +5 -3
  128. package/src/react-devtools/StateIndex.tsx +6 -4
  129. package/src/react-devtools/TimelineIndex.tsx +0 -2
  130. package/src/react-devtools/Updates.tsx +1 -1
  131. package/src/react-devtools/store.ts +18 -9
  132. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +4 -8
  133. package/src/realtime-client/sync-continuity.ts +2 -2
  134. package/src/realtime-server/index.ts +2 -2
@@ -5,21 +5,21 @@ import { readFromCache, writeToCache } from "../caching"
5
5
  import { isFn } from "../is-fn"
6
6
  import type { Store } from "../store"
7
7
 
8
- export function readOrComputeValue<T>(
8
+ export function readOrComputeValue<T, E>(
9
9
  target: Store,
10
- state: ReadableState<T>,
10
+ state: ReadableState<T, E>,
11
11
  mut?: undefined,
12
- ): ViewOf<T>
13
- export function readOrComputeValue<T>(
12
+ ): ViewOf<E | T>
13
+ export function readOrComputeValue<T, E>(
14
14
  target: Store,
15
- state: ReadableState<T>,
15
+ state: ReadableState<T, E>,
16
16
  mut: `mut`,
17
- ): T
18
- export function readOrComputeValue<T>(
17
+ ): E | T
18
+ export function readOrComputeValue<T, E>(
19
19
  target: Store,
20
- state: ReadableState<T>,
20
+ state: ReadableState<T, E>,
21
21
  mut: `mut` | undefined,
22
- ): T {
22
+ ): E | T {
23
23
  if (target.valueMap.has(state.key)) {
24
24
  return readFromCache(target, state, mut)
25
25
  }
@@ -27,16 +27,80 @@ export function readOrComputeValue<T>(
27
27
  const { key } = state
28
28
  switch (state.type) {
29
29
  case `readonly_held_selector`:
30
- case `readonly_pure_selector`:
31
30
  case `writable_held_selector`:
32
- case `writable_pure_selector`:
33
31
  target.logger.info(`🧮`, state.type, key, `computing value`)
34
32
  return state.getFrom(target)
33
+ case `readonly_pure_selector`:
34
+ case `writable_pure_selector`: {
35
+ let val: E | T
36
+ target.logger.info(`🧮`, state.type, key, `computing value`)
37
+ try {
38
+ val = state.getFrom(target)
39
+ if (val instanceof Promise) {
40
+ return (val as Promise<E & T>).catch((e) => {
41
+ target.logger.error(`💥`, state.type, key, `rejected:`, e)
42
+ if (state.catch) {
43
+ for (const Class of state.catch) {
44
+ if (e instanceof Class) {
45
+ return writeToCache(target, state, e)
46
+ }
47
+ }
48
+ }
49
+ throw e
50
+ }) as E | T
51
+ }
52
+ } catch (e) {
53
+ target.logger.error(`💥`, state.type, key, `rejected:`, e)
54
+ if (state.catch) {
55
+ for (const Class of state.catch) {
56
+ if (e instanceof Class) {
57
+ return writeToCache(target, state, e)
58
+ }
59
+ }
60
+ }
61
+ throw e
62
+ }
63
+ const cachedValue = writeToCache(target, state, val)
64
+ return cachedValue
65
+ }
35
66
  case `atom`: {
36
- let def: T
67
+ let def: E | T
37
68
  if (isFn(state.default)) {
38
- def = state.default()
39
- target.logger.info(`✨`, state.type, key, `computed default`, def)
69
+ try {
70
+ def = state.default()
71
+ if (def instanceof Promise) {
72
+ def = (def as Promise<T> & T).catch<E | T>((e) => {
73
+ target.logger.error(`💥`, state.type, key, `rejected:`, e)
74
+ if (state.catch) {
75
+ for (const Class of state.catch) {
76
+ if (e instanceof Class) {
77
+ def = writeToCache(target, state, e)
78
+ return def
79
+ }
80
+ }
81
+ }
82
+ throw e
83
+ }) as E | T
84
+ }
85
+ } catch (e) {
86
+ target.logger.error(`💥`, state.type, key, `rejected:`, e)
87
+ if (state.catch) {
88
+ for (const Class of state.catch) {
89
+ if (e instanceof Class) {
90
+ def = writeToCache(target, state, e)
91
+ target.logger.info(
92
+ `✨`,
93
+ state.type,
94
+ key,
95
+ `computed default`,
96
+ def,
97
+ )
98
+ return def
99
+ }
100
+ }
101
+ }
102
+ throw e
103
+ }
40
104
  } else {
41
105
  def = state.default
42
106
  target.logger.info(`✨`, state.type, key, `using static default`, def)
@@ -13,27 +13,27 @@ import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
13
13
  import type { Store } from "../store"
14
14
  import { withdraw } from "../store"
15
15
 
16
- export function reduceReference<T, K extends Canonical>(
16
+ export function reduceReference<T, K extends Canonical, E>(
17
17
  store: Store,
18
18
  ...params:
19
- | [token: ReadableFamilyToken<T, K>, key: K]
20
- | [token: ReadableToken<T>]
19
+ | [token: ReadableFamilyToken<T, K, E>, key: K]
20
+ | [token: ReadableToken<T, K, E>]
21
21
  ): {
22
- token: ReadableToken<T, K>
23
- family: ReadableFamily<T, K> | undefined
22
+ token: ReadableToken<T, K, E>
23
+ family: ReadableFamily<T, K, E> | undefined
24
24
  subKey: K | undefined
25
25
  isNew: boolean
26
26
  } {
27
- let existingToken: ReadableToken<T> | undefined
28
- let brandNewToken: ReadableToken<T> | undefined
29
- let family: ReadableFamily<T, K> | undefined
27
+ let existingToken: ReadableToken<T, K, E> | undefined
28
+ let brandNewToken: ReadableToken<T, K, E> | undefined
29
+ let family: ReadableFamily<T, K, E> | undefined
30
30
  let subKey: K | undefined
31
- let token: ReadableToken<T, K>
31
+ let token: ReadableToken<T, K, E>
32
32
  if (params.length === 1) {
33
33
  token = params[0]
34
34
  if (`family` in token) {
35
35
  const familyToken = getFamilyOfToken(store, token)
36
- family = withdraw(store, familyToken) as ReadableFamily<T, K>
36
+ family = withdraw(store, familyToken) as ReadableFamily<T, K, E>
37
37
  subKey = parseJson(token.family.subKey)
38
38
  existingToken = seekInStore(store, familyToken, subKey)
39
39
  if (`counterfeit` in token) {
@@ -22,7 +22,7 @@ import type { ConstructorOf, Transceiver } from "./mutable"
22
22
  import type { Store } from "./store"
23
23
  import type { Subject } from "./subject"
24
24
  import type { Timeline } from "./timeline"
25
- import type { Transaction } from "./transaction"
25
+ import type { RootStore, Transaction } from "./transaction"
26
26
  import type { Flat } from "./utility-types"
27
27
 
28
28
  export * from "./arbitrary"
@@ -58,15 +58,16 @@ export type * from "./utility-types"
58
58
  export type AtomIOState = {
59
59
  key: string
60
60
  family?: FamilyMetadata
61
- install: (store: Store) => void
61
+ install: (store: RootStore) => void
62
62
  subject: Subject<StateUpdate<any>>
63
63
  }
64
- export type RegularAtom<T> = Flat<
64
+ export type RegularAtom<T, E> = Flat<
65
65
  AtomIOState & {
66
66
  type: `atom`
67
67
  default: T | (() => T)
68
68
  cleanup?: () => void
69
69
  internalRoles?: internalRole[]
70
+ catch?: readonly (new () => E)[]
70
71
  }
71
72
  >
72
73
  export type MutableAtom<T extends Transceiver<any, any, any>> = Flat<
@@ -76,8 +77,8 @@ export type MutableAtom<T extends Transceiver<any, any, any>> = Flat<
76
77
  cleanup?: () => void
77
78
  }
78
79
  >
79
- export type Atom<T> =
80
- | RegularAtom<T>
80
+ export type Atom<T, E> =
81
+ | RegularAtom<T, E>
81
82
  | (T extends Transceiver<any, any, any> ? MutableAtom<T> : never)
82
83
 
83
84
  export type WritableHeldSelector<T> = Flat<
@@ -95,48 +96,52 @@ export type ReadonlyHeldSelector<T> = Flat<
95
96
  getFrom: (target: Store) => T
96
97
  }
97
98
  >
98
- export type WritablePureSelector<T> = Flat<
99
+ export type WritablePureSelector<T, E> = Flat<
99
100
  AtomIOState & {
100
101
  type: `writable_pure_selector`
101
- getFrom: (target: Store) => T
102
+ getFrom: (target: Store) => E | T
102
103
  setSelf: (newValue: T) => void
104
+ catch?: readonly (new () => E)[]
103
105
  }
104
106
  >
105
- export type ReadonlyPureSelector<T> = Flat<
107
+ export type ReadonlyPureSelector<T, E> = Flat<
106
108
  AtomIOState & {
107
109
  type: `readonly_pure_selector`
108
- getFrom: (target: Store) => T
110
+ getFrom: (target: Store) => E | T
111
+ catch?: readonly (new () => E)[]
109
112
  }
110
113
  >
111
- export type ReadonlySelector<T> =
114
+ export type ReadonlySelector<T, E> =
112
115
  | ReadonlyHeldSelector<T>
113
- | ReadonlyPureSelector<T>
114
- export type WritableSelector<T> =
116
+ | ReadonlyPureSelector<T, E>
117
+ export type WritableSelector<T, E> =
115
118
  | WritableHeldSelector<T>
116
- | WritablePureSelector<T>
119
+ | WritablePureSelector<T, E>
117
120
  export type HeldSelector<T> = ReadonlyHeldSelector<T> | WritableHeldSelector<T>
118
- export type PureSelector<T> = ReadonlyPureSelector<T> | WritablePureSelector<T>
119
- export type Selector<T> =
121
+ export type PureSelector<T, E> =
122
+ | ReadonlyPureSelector<T, E>
123
+ | WritablePureSelector<T, E>
124
+ export type Selector<T, E> =
120
125
  | ReadonlyHeldSelector<T>
121
- | ReadonlyPureSelector<T>
126
+ | ReadonlyPureSelector<T, E>
122
127
  | WritableHeldSelector<T>
123
- | WritablePureSelector<T>
128
+ | WritablePureSelector<T, E>
124
129
 
125
- export type WritableState<T> = Atom<T> | WritableSelector<T>
126
- export type ReadableState<T> = Atom<T> | Selector<T>
130
+ export type WritableState<T, E> = Atom<T, E> | WritableSelector<T, E>
131
+ export type ReadableState<T, E> = Atom<T, E> | Selector<T, E>
127
132
 
128
133
  // biome-ignore format: intersection
129
- export type RegularAtomFamily<T, K extends Canonical> =
134
+ export type RegularAtomFamily<T, K extends Canonical, E = never> =
130
135
  & Flat<
131
- & RegularAtomFamilyToken<T, K>
136
+ & RegularAtomFamilyToken<T, K, E>
132
137
  & {
133
138
  default: T | ((key: K) => T)
134
- install: (store: Store) => void
139
+ install: (store: RootStore) => void
135
140
  internalRoles: string[] | undefined
136
- subject: Subject<StateLifecycleEvent<RegularAtomToken<T>>>
141
+ subject: Subject<StateLifecycleEvent<RegularAtomToken<T, K, E>>>
137
142
  }
138
143
  >
139
- & ((key: K) => RegularAtomToken<T>)
144
+ & (<Key extends K>(key: Key) => RegularAtomToken<T, Key, E>)
140
145
 
141
146
  // biome-ignore format: intersection
142
147
  export type MutableAtomFamily<
@@ -147,29 +152,29 @@ export type MutableAtomFamily<
147
152
  & MutableAtomFamilyToken<T, K>
148
153
  & {
149
154
  class: ConstructorOf<T>
150
- install: (store: Store) => void
155
+ install: (store: RootStore) => void
151
156
  internalRoles: string[] | undefined
152
157
  subject: Subject<StateLifecycleEvent<MutableAtomToken<T>>>
153
158
  }
154
159
  >
155
- & ((key: K) => MutableAtomToken<T>)
160
+ & (<Key extends K>(key: Key) => MutableAtomToken<T, Key>)
156
161
 
157
- export type AtomFamily<T, K extends Canonical = Canonical> =
162
+ export type AtomFamily<T, K extends Canonical, E> =
158
163
  | MutableAtomFamily<T extends Transceiver<any, any, any> ? T : never, K>
159
- | RegularAtomFamily<T, K>
164
+ | RegularAtomFamily<T, K, E>
160
165
 
161
166
  // biome-ignore format: intersection
162
- export type WritablePureSelectorFamily<T, K extends Canonical> =
167
+ export type WritablePureSelectorFamily<T, K extends Canonical, E> =
163
168
  & Flat<
164
- & WritablePureSelectorFamilyToken<T, K>
169
+ & WritablePureSelectorFamilyToken<T, K, E>
165
170
  & {
166
171
  default: (key: K) => T,
167
- install: (store: Store) => void
172
+ install: (store: RootStore) => void
168
173
  internalRoles: string[] | undefined
169
- subject: Subject<StateLifecycleEvent<WritablePureSelectorToken<T>>>
174
+ subject: Subject<StateLifecycleEvent<WritablePureSelectorToken<T, K, E>>>
170
175
  }
171
176
  >
172
- & ((key: K) => WritablePureSelectorToken<T>)
177
+ & (<Key extends K>(key: Key) => WritablePureSelectorToken<T, Key, E>)
173
178
 
174
179
  // biome-ignore format: intersection
175
180
  export type WritableHeldSelectorFamily<T , K extends Canonical> =
@@ -177,25 +182,25 @@ export type WritableHeldSelectorFamily<T , K extends Canonical> =
177
182
  & WritableHeldSelectorFamilyToken<T, K>
178
183
  & {
179
184
  default: (key: K) => T,
180
- install: (store: Store) => void
185
+ install: (store: RootStore) => void
181
186
  internalRoles: string[] | undefined
182
- subject: Subject<StateLifecycleEvent<WritableHeldSelectorToken<T>>>
187
+ subject: Subject<StateLifecycleEvent<WritableHeldSelectorToken<T, K>>>
183
188
  }
184
189
  >
185
- & ((key: K) => WritableHeldSelectorToken<T>)
190
+ & (<Key extends K>(key: Key) => WritableHeldSelectorToken<T, Key>)
186
191
 
187
192
  // biome-ignore format: intersection
188
- export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
193
+ export type ReadonlyPureSelectorFamily<T, K extends Canonical, E> =
189
194
  & Flat<
190
- & ReadonlyPureSelectorFamilyToken<T, K>
195
+ & ReadonlyPureSelectorFamilyToken<T, K, E>
191
196
  & {
192
197
  default: (key: K) => T,
193
- install: (store: Store) => void
198
+ install: (store: RootStore) => void
194
199
  internalRoles: string[] | undefined
195
- subject: Subject<StateLifecycleEvent<ReadonlyPureSelectorToken<T>>>
200
+ subject: Subject<StateLifecycleEvent<ReadonlyPureSelectorToken<T, K, E>>>
196
201
  }
197
202
  >
198
- & ((key: K) => ReadonlyPureSelectorToken<T>)
203
+ & (<Key extends K>(key: Key) => ReadonlyPureSelectorToken<T, Key, E>)
199
204
 
200
205
  // biome-ignore format: intersection
201
206
  export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
@@ -203,42 +208,42 @@ export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
203
208
  & ReadonlyHeldSelectorFamilyToken<T, K>
204
209
  & {
205
210
  default: (key: K) => T,
206
- install: (store: Store) => void
211
+ install: (store: RootStore) => void
207
212
  internalRoles: string[] | undefined
208
213
  subject: Subject<StateLifecycleEvent<ReadonlyHeldSelectorToken<T>>>
209
214
  }
210
215
  >
211
- & ((key: K) => ReadonlyHeldSelectorToken<T>)
216
+ & (<Key extends K>(key: Key) => ReadonlyHeldSelectorToken<T, Key>)
212
217
 
213
- export type PureSelectorFamily<T, K extends Canonical> =
214
- | ReadonlyPureSelectorFamily<T, K>
215
- | WritablePureSelectorFamily<T, K>
218
+ export type PureSelectorFamily<T, K extends Canonical, E> =
219
+ | ReadonlyPureSelectorFamily<T, K, E>
220
+ | WritablePureSelectorFamily<T, K, E>
216
221
 
217
222
  export type HeldSelectorFamily<T, K extends Canonical> =
218
223
  | ReadonlyHeldSelectorFamily<T, K>
219
224
  | WritableHeldSelectorFamily<T, K>
220
225
 
221
- export type ReadonlySelectorFamily<T, K extends Canonical> =
226
+ export type ReadonlySelectorFamily<T, K extends Canonical, E> =
222
227
  | ReadonlyHeldSelectorFamily<T, K>
223
- | ReadonlyPureSelectorFamily<T, K>
228
+ | ReadonlyPureSelectorFamily<T, K, E>
224
229
 
225
- export type WritableSelectorFamily<T, K extends Canonical> =
230
+ export type WritableSelectorFamily<T, K extends Canonical, E> =
226
231
  | WritableHeldSelectorFamily<T, K>
227
- | WritablePureSelectorFamily<T, K>
232
+ | WritablePureSelectorFamily<T, K, E>
228
233
 
229
- export type SelectorFamily<T, K extends Canonical> =
234
+ export type SelectorFamily<T, K extends Canonical, E> =
230
235
  | HeldSelectorFamily<T, K>
231
- | PureSelectorFamily<T, K>
236
+ | PureSelectorFamily<T, K, E>
232
237
 
233
- export type WritableFamily<T, K extends Canonical> =
234
- | AtomFamily<T, K>
235
- | WritablePureSelectorFamily<T, K>
236
- export type ReadableFamily<T, K extends Canonical> =
237
- | AtomFamily<T, K>
238
- | SelectorFamily<T, K>
238
+ export type WritableFamily<T, K extends Canonical, E> =
239
+ | AtomFamily<T, K, E>
240
+ | WritableSelectorFamily<T, K, E>
241
+ export type ReadableFamily<T, K extends Canonical, E> =
242
+ | AtomFamily<T, K, E>
243
+ | SelectorFamily<T, K, E>
239
244
 
240
245
  export type AtomIOInternalResource =
241
- | ReadableFamily<any, any>
242
- | ReadableState<any>
246
+ | ReadableFamily<any, any, any>
247
+ | ReadableState<any, any>
243
248
  | Timeline<any>
244
249
  | Transaction<any>
@@ -2,6 +2,7 @@ import type { AtomIOToken } from "atom.io"
2
2
 
3
3
  import { newest } from "./lineage"
4
4
  import { type Store, withdraw } from "./store"
5
+ import type { RootStore } from "./transaction"
5
6
  import { isChildStore } from "./transaction"
6
7
 
7
8
  /**
@@ -14,7 +15,7 @@ import { isChildStore } from "./transaction"
14
15
  */
15
16
  export function installIntoStore(
16
17
  tokens: AtomIOToken[],
17
- target: Store,
18
+ target: RootStore,
18
19
  source: Store,
19
20
  ): void {
20
21
  const sourceNewest = newest(source)
@@ -1,7 +1,7 @@
1
1
  import type { JoinOptions, JoinToken } from "atom.io"
2
2
  import type { Json } from "atom.io/json"
3
3
 
4
- import type { Store } from "../store"
4
+ import type { RootStore } from "../transaction"
5
5
  import { Join } from "./join-internal"
6
6
 
7
7
  export function createJoin<
@@ -12,7 +12,7 @@ export function createJoin<
12
12
  Cardinality extends `1:1` | `1:n` | `n:n`,
13
13
  Content extends Json.Object,
14
14
  >(
15
- store: Store,
15
+ store: RootStore,
16
16
  options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>,
17
17
  defaultContent: Content | undefined,
18
18
  ): JoinToken<ASide, AType, BSide, BType, Cardinality, Content> {
@@ -3,7 +3,7 @@ import type { Json } from "atom.io/json"
3
3
 
4
4
  import { capitalize } from "../capitalize"
5
5
  import { findInStore } from "../families"
6
- import type { Store } from "../store"
6
+ import type { RootStore } from "../transaction"
7
7
  import { getJoin } from "./get-join"
8
8
 
9
9
  export function findRelationsInStore<
@@ -16,7 +16,7 @@ export function findRelationsInStore<
16
16
  >(
17
17
  token: JoinToken<ASide, AType, BSide, BType, Cardinality, Content>,
18
18
  key: AType | BType,
19
- store: Store,
19
+ store: RootStore,
20
20
  ): JoinStates<ASide, AType, BSide, BType, Cardinality, Content> {
21
21
  const myJoin = getJoin(token, store)
22
22
  let relations: JoinStates<ASide, AType, BSide, BType, Cardinality, Content>
@@ -1,12 +1,12 @@
1
1
  import type { JoinToken, MutableAtomFamilyToken } from "atom.io"
2
2
  import type { SetRTX } from "atom.io/transceivers/set-rtx"
3
3
 
4
- import type { Store } from "../store"
4
+ import type { RootStore } from "../transaction"
5
5
  import { getJoin } from "./get-join"
6
6
 
7
7
  export function getInternalRelationsFromStore(
8
8
  token: JoinToken<any, any, any, any, any, any>,
9
- store: Store,
9
+ store: RootStore,
10
10
  ): MutableAtomFamilyToken<SetRTX<string>, string> {
11
11
  const myJoin = getJoin(token, store)
12
12
  const family = myJoin.core.relatedKeysAtoms
@@ -1,7 +1,9 @@
1
1
  import type { JoinToken } from "atom.io"
2
2
  import type { Json } from "atom.io/json"
3
3
 
4
- import { IMPLICIT, type Store } from "../store"
4
+ import { eldest } from "../lineage"
5
+ import type { Store } from "../store"
6
+ import { IMPLICIT } from "../store"
5
7
  import { Join } from "./join-internal"
6
8
 
7
9
  export function getJoin<
@@ -24,7 +26,8 @@ export function getJoin<
24
26
  `Join "${token.key}" not found in store "${store.config.name}"`,
25
27
  )
26
28
  }
27
- myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store)
29
+ const root = eldest(store)
30
+ myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root)
28
31
  store.joins.set(token.key, myJoin)
29
32
  }
30
33
  return myJoin
@@ -13,7 +13,7 @@ import type {
13
13
  WriterToolkit,
14
14
  } from "atom.io"
15
15
  import { Anarchy } from "atom.io"
16
- import type { Canonical, Json, stringified } from "atom.io/json"
16
+ import type { Json } from "atom.io/json"
17
17
  import { stringifyJson } from "atom.io/json"
18
18
  import { SetRTX } from "atom.io/transceivers/set-rtx"
19
19
 
@@ -29,11 +29,11 @@ import type {
29
29
  ExternalStoreConfiguration,
30
30
  } from "../junction"
31
31
  import { Junction } from "../junction"
32
- import type { Molecule } from "../molecule"
33
32
  import { createMutableAtomFamily, getJsonFamily, getJsonToken } from "../mutable"
34
33
  import { setIntoStore } from "../set-state"
35
34
  import type { Store } from "../store"
36
35
  import { IMPLICIT } from "../store"
36
+ import type { RootStore } from "../transaction"
37
37
 
38
38
  export type JoinStateFamilies<
39
39
  ASide extends string,
@@ -132,7 +132,6 @@ export class Join<
132
132
  private toolkit: WriterToolkit
133
133
  public options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>
134
134
  public defaultContent: Content | undefined
135
- public molecules: Map<string, Molecule<any>> = new Map()
136
135
  public relations: Junction<ASide, AType, BSide, BType, Content>
137
136
  public states: JoinStateFamilies<
138
137
  ASide,
@@ -163,7 +162,7 @@ export class Join<
163
162
  public constructor(
164
163
  options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>,
165
164
  defaultContent: Content | undefined,
166
- store: Store = IMPLICIT.STORE,
165
+ store: RootStore = IMPLICIT.STORE,
167
166
  ) {
168
167
  type AnyKey = AType & BType
169
168
 
@@ -200,7 +199,8 @@ export class Join<
200
199
  this.core = { relatedKeysAtoms }
201
200
  const getRelatedKeys: Read<
202
201
  (key: string) => SetRTX<AType> | SetRTX<BType>
203
- > = ({ get }, key) => get(relatedKeysAtoms, key) as any
202
+ > = ({ get }, key) =>
203
+ get(relatedKeysAtoms, key) as SetRTX<AType> | SetRTX<BType>
204
204
  const addRelation: Write<(a: string, b: string) => void> = (
205
205
  { set },
206
206
  a,
@@ -225,6 +225,9 @@ export class Join<
225
225
  bKeys.delete(a)
226
226
  return bKeys
227
227
  })
228
+ const [x, y] = [a, b].sort()
229
+ const compositeKey = `${x}:${y}`
230
+ this.store.moleculeJoins.delete(compositeKey)
228
231
  }
229
232
  const replaceRelationsSafely: Write<
230
233
  (a: string, newRelationsOfA: string[]) => void
@@ -267,9 +270,9 @@ export class Join<
267
270
  relationsOfB.clear()
268
271
  }
269
272
  for (const previousOwner of previousOwnersToDispose) {
270
- const sorted = [newRelationB, previousOwner].sort()
271
- const compositeKey = `"${sorted[0]}:${sorted[1]}"`
272
- this.molecules.delete(compositeKey)
273
+ const [x, y] = [newRelationB, previousOwner].sort()
274
+ const compositeKey = `${x}:${y}`
275
+ store.moleculeJoins.delete(compositeKey)
273
276
  }
274
277
  }
275
278
  if (!newRelationBIsAlreadyRelated) {
@@ -310,14 +313,8 @@ export class Join<
310
313
  const baseExternalStoreConfiguration: BaseExternalStoreConfiguration = {
311
314
  getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
312
315
  addRelation: (a, b) => {
313
- this.store.moleculeJoins.set(
314
- a as stringified<Canonical> /* 💥 RECONCILE */,
315
- options.key,
316
- )
317
- this.store.moleculeJoins.set(
318
- b as stringified<Canonical> /* 💥 RECONCILE */,
319
- options.key,
320
- )
316
+ this.store.moleculeJoins.set(`"${a}"`, options.key)
317
+ this.store.moleculeJoins.set(`"${b}"`, options.key)
321
318
  addRelation(this.toolkit, a, b)
322
319
  },
323
320
  deleteRelation: (a, b) => {
@@ -335,7 +332,7 @@ export class Join<
335
332
  let contentAtoms: RegularAtomFamilyToken<Content, string>
336
333
 
337
334
  if (defaultContent) {
338
- contentAtoms = createRegularAtomFamily<Content, ContentKey>(
335
+ contentAtoms = createRegularAtomFamily<Content, ContentKey, never>(
339
336
  store,
340
337
  {
341
338
  key: `${options.key}/content`,
@@ -364,9 +361,7 @@ export class Join<
364
361
  setContent: (contentKey: ContentKey, content: Content) => {
365
362
  setContent(this.toolkit, contentKey, content)
366
363
  },
367
- deleteContent: (contentKey: ContentKey) => {
368
- this.realm.deallocate(contentKey)
369
- },
364
+ deleteContent: (_: ContentKey) => {},
370
365
  }
371
366
  externalStore = Object.assign(
372
367
  baseExternalStoreConfiguration,
@@ -384,8 +379,8 @@ export class Join<
384
379
  isBType: options.isBType,
385
380
  makeContentKey: (...args) => {
386
381
  const [a, b] = args
387
- const sorted = args.sort()
388
- const compositeKey = `${sorted[0]}:${sorted[1]}`
382
+ const [x, y] = args.sort()
383
+ const compositeKey = `${x}:${y}`
389
384
  const aMolecule = store.molecules.get(stringifyJson(a))
390
385
  const bMolecule = store.molecules.get(stringifyJson(b))
391
386
  if (!aMolecule) {
@@ -394,6 +389,7 @@ export class Join<
394
389
  if (!bMolecule) {
395
390
  this.realm.allocate(options.key, b)
396
391
  }
392
+
397
393
  this.realm.allocate(a, compositeKey, `all`)
398
394
  this.realm.claim(b, compositeKey)
399
395
  this.store.moleculeJoins.set(compositeKey, options.key)
@@ -403,7 +399,7 @@ export class Join<
403
399
  )
404
400
 
405
401
  const createSingleKeySelectorFamily = () =>
406
- createReadonlyPureSelectorFamily<string | null, string>(
402
+ createReadonlyPureSelectorFamily<string | null, string, never>(
407
403
  store,
408
404
  {
409
405
  key: `${options.key}/singleRelatedKey`,
@@ -420,7 +416,7 @@ export class Join<
420
416
  [`join`, `keys`],
421
417
  )
422
418
  const getMultipleKeySelectorFamily = () => {
423
- return createReadonlyPureSelectorFamily<string[], string>(
419
+ return createReadonlyPureSelectorFamily<string[], string, never>(
424
420
  store,
425
421
  {
426
422
  key: `${options.key}/multipleRelatedKeys`,
@@ -436,7 +432,11 @@ export class Join<
436
432
  )
437
433
  }
438
434
  const createSingleEntrySelectorFamily = () =>
439
- createReadonlyPureSelectorFamily<[string, ViewOf<Content>] | null, string>(
435
+ createReadonlyPureSelectorFamily<
436
+ [string, ViewOf<Content>] | null,
437
+ string,
438
+ never
439
+ >(
440
440
  store,
441
441
  {
442
442
  key: `${options.key}/singleRelatedEntry`,
@@ -459,7 +459,11 @@ export class Join<
459
459
  [`join`, `entries`],
460
460
  )
461
461
  const getMultipleEntrySelectorFamily = () =>
462
- createReadonlyPureSelectorFamily<[string, ViewOf<Content>][], string>(
462
+ createReadonlyPureSelectorFamily<
463
+ [string, ViewOf<Content>][],
464
+ string,
465
+ never
466
+ >(
463
467
  store,
464
468
  {
465
469
  key: `${options.key}/multipleRelatedEntries`,