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
@@ -4,9 +4,20 @@ export interface Lineage {
4
4
  child: typeof this | null
5
5
  }
6
6
 
7
- export function newest<T extends Lineage>(scion: T): T {
7
+ export function newest<T extends Lineage>(
8
+ scion: T,
9
+ ): Exclude<T[`child`], null> | T {
8
10
  while (scion.child !== null) {
9
11
  scion = scion.child
10
12
  }
11
13
  return scion
12
14
  }
15
+
16
+ export function eldest<T extends Lineage>(
17
+ scion: T,
18
+ ): Exclude<T[`parent`], T[`child`] | null> {
19
+ while (scion.parent !== null) {
20
+ scion = scion.parent
21
+ }
22
+ return scion as Exclude<T[`parent`], T[`child`] | null>
23
+ }
@@ -8,18 +8,20 @@ import type {
8
8
  MoleculeDisposalEvent,
9
9
  MoleculeTransferEvent,
10
10
  SingularTypedKey,
11
+ TransactionToken,
11
12
  Vassal,
12
13
  } from "atom.io"
13
14
  import type { Canonical, stringified } from "atom.io/json"
14
15
  import { parseJson, stringifyJson } from "atom.io/json"
15
16
 
16
- import { disposeFromStore, findInStore } from "./families"
17
+ import { disposeFromStore } from "./families"
17
18
  import { getFromStore } from "./get-state"
18
19
  import { getTrace } from "./get-trace"
19
20
  import { newest } from "./lineage"
20
21
  import type { Store } from "./store"
21
22
  import { IMPLICIT } from "./store"
22
- import { isChildStore } from "./transaction"
23
+ import type { RootStore } from "./transaction"
24
+ import { createTransaction, isChildStore } from "./transaction"
23
25
 
24
26
  export type Molecule<K extends Canonical> = {
25
27
  readonly key: K
@@ -135,23 +137,35 @@ export function fuseWithinStore<
135
137
  return compoundKey
136
138
  }
137
139
 
140
+ export function createDeallocateTX<
141
+ H extends Hierarchy,
142
+ V extends Exclude<Vassal<H>, CompoundTypedKey>,
143
+ >(store: RootStore): TransactionToken<(claim: Claim<V>) => void> {
144
+ return createTransaction(store, {
145
+ key: `[Internal] deallocate`,
146
+ do: (_, claim: Claim<V>): void => {
147
+ deallocateFromStore<H, V>(newest(store), claim)
148
+ },
149
+ })
150
+ }
151
+
138
152
  export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
139
- store: Store,
153
+ target: Store,
140
154
  claim: Claim<V>,
141
155
  ): void {
142
156
  const stringKey = stringifyJson(claim)
143
157
 
144
- const molecule = store.molecules.get(stringKey)
158
+ const molecule = target.molecules.get(stringKey)
145
159
  if (!molecule) {
146
- const disposal = store.disposalTraces.buffer.find(
160
+ const disposal = target.disposalTraces.buffer.find(
147
161
  (item) => item?.key === stringKey,
148
162
  )
149
- store.logger.error(
163
+ target.logger.error(
150
164
  `❌`,
151
165
  `key`,
152
166
  claim,
153
167
  `deallocation failed:`,
154
- `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
168
+ `Could not find allocation for ${stringKey} in store "${target.config.name}".`,
155
169
  disposal
156
170
  ? `\n This state was most recently deallocated\n${disposal.trace}`
157
171
  : `No previous disposal trace for ${stringKey} was found.`,
@@ -159,45 +173,29 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
159
173
  return
160
174
  }
161
175
 
162
- const joinKeys = store.moleculeJoins.getRelatedKeys(
163
- molecule.key as string /* 💥 RECONCILE */,
164
- )
176
+ const joinKeys = target.moleculeJoins.getRelatedKeys(stringKey)
165
177
  if (joinKeys) {
166
178
  for (const joinKey of joinKeys) {
167
- const join = store.joins.get(joinKey)
179
+ const join = target.joins.get(joinKey)
168
180
  if (join) {
169
- join.relations.delete(molecule.key)
170
- join.molecules.delete(molecule.stringKey) // get rid of
181
+ join.relations.delete(claim)
171
182
  }
172
183
  }
173
184
  }
174
- store.moleculeJoins.delete(molecule.stringKey)
185
+ target.moleculeJoins.delete(stringKey)
175
186
 
176
187
  const provenance: stringified<Canonical>[] = []
177
188
 
178
189
  const values: [string, any][] = []
179
- const disposalEvent: MoleculeDisposalEvent = {
180
- type: `molecule_disposal`,
181
- key: molecule.key,
182
- values,
183
- provenance,
184
- timestamp: Date.now(),
185
- }
186
- const target = newest(store)
187
- target.molecules.delete(stringKey)
188
- const isTransaction =
189
- isChildStore(target) && target.transactionMeta.phase === `building`
190
- if (isTransaction) {
191
- target.transactionMeta.update.subEvents.push(disposalEvent)
192
- }
193
- const relatedMolecules = store.moleculeGraph.getRelationEntries({
194
- downstreamMoleculeKey: molecule.stringKey,
190
+
191
+ const relatedMolecules = target.moleculeGraph.getRelationEntries({
192
+ downstreamMoleculeKey: stringKey,
195
193
  })
196
194
  if (relatedMolecules) {
197
195
  for (const [relatedStringKey, { source }] of relatedMolecules) {
198
- if (source === molecule.stringKey) {
196
+ if (source === stringKey) {
199
197
  const relatedKey = parseJson(relatedStringKey)
200
- deallocateFromStore<any, any>(store, relatedKey)
198
+ deallocateFromStore<any, any>(target, relatedKey)
201
199
  } else {
202
200
  provenance.push(source)
203
201
  }
@@ -208,12 +206,24 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
208
206
  for (const familyKey of familyKeys) {
209
207
  // biome-ignore lint/style/noNonNullAssertion: tokens of molecules must have a family
210
208
  const family = target.families.get(familyKey)!
211
- const token = findInStore(store, family, molecule.key)
212
- const value = getFromStore(store, token)
209
+ const value = getFromStore(target, family, claim)
213
210
  values.push([family.key, value])
214
- disposeFromStore(store, token)
211
+ disposeFromStore(target, family, claim)
215
212
  }
216
213
  }
214
+ const disposalEvent: MoleculeDisposalEvent = {
215
+ type: `molecule_disposal`,
216
+ key: molecule.key,
217
+ values,
218
+ provenance,
219
+ timestamp: Date.now(),
220
+ }
221
+ target.molecules.delete(stringKey)
222
+ const isTransaction =
223
+ isChildStore(target) && target.transactionMeta.phase === `building`
224
+ if (isTransaction) {
225
+ target.transactionMeta.update.subEvents.push(disposalEvent)
226
+ }
217
227
 
218
228
  target.moleculeGraph.delete(molecule.stringKey)
219
229
  target.moleculeJoins.delete(molecule.stringKey)
@@ -225,8 +235,26 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
225
235
  target.molecules.delete(molecule.stringKey)
226
236
 
227
237
  const trace = getTrace(new Error())
228
- store.disposalTraces.add({ key: stringKey, trace })
238
+ target.disposalTraces.add({ key: stringKey, trace })
239
+ }
240
+
241
+ export function createClaimTX<
242
+ H extends Hierarchy,
243
+ V extends Exclude<Vassal<H>, CompoundTypedKey>,
244
+ A extends Above<V, H>,
245
+ >(
246
+ store: RootStore,
247
+ ): TransactionToken<
248
+ (newProvenance: A, claim: Claim<V>, exclusive?: `exclusive`) => void
249
+ > {
250
+ return createTransaction(store, {
251
+ key: `[Internal] claim`,
252
+ do: (_, newProvenance, claim, exclusive) => {
253
+ claimWithinStore<H, V, A>(store, newProvenance, claim, exclusive)
254
+ },
255
+ })
229
256
  }
257
+
230
258
  export function claimWithinStore<
231
259
  H extends Hierarchy,
232
260
  V extends Exclude<Vassal<H>, CompoundTypedKey>,
@@ -10,10 +10,10 @@ import { PRETTY_TOKEN_TYPES } from "atom.io"
10
10
  import type { Canonical } from "atom.io/json"
11
11
  import { stringifyJson } from "atom.io/json"
12
12
 
13
- import { createWritablePureSelectorFamily, type MutableAtomFamily } from ".."
13
+ import type { MutableAtomFamily, RootStore } from ".."
14
+ import { createWritablePureSelectorFamily } from ".."
14
15
  import { newest } from "../lineage"
15
16
  import { createMutableAtom } from "../mutable"
16
- import type { Store } from "../store"
17
17
  import { Subject } from "../subject"
18
18
  import { FamilyTracker } from "./tracker-family"
19
19
  import type { AsJSON, Transceiver } from "./transceiver"
@@ -22,7 +22,7 @@ export function createMutableAtomFamily<
22
22
  T extends Transceiver<any, any, any>,
23
23
  K extends Canonical,
24
24
  >(
25
- store: Store,
25
+ store: RootStore,
26
26
  options: MutableAtomFamilyOptions<T, K>,
27
27
  internalRoles?: string[],
28
28
  ): MutableAtomFamilyToken<T, K> {
@@ -67,13 +67,13 @@ export function createMutableAtomFamily<
67
67
  const atomFamily = Object.assign(familyFunction, familyToken, {
68
68
  class: options.class,
69
69
  subject,
70
- install: (s: Store) => createMutableAtomFamily(s, options),
70
+ install: (s: RootStore) => createMutableAtomFamily(s, options),
71
71
  internalRoles,
72
72
  }) satisfies MutableAtomFamily<T, K>
73
73
 
74
74
  store.families.set(options.key, atomFamily)
75
75
 
76
- createWritablePureSelectorFamily<AsJSON<T>, K>(
76
+ createWritablePureSelectorFamily<AsJSON<T>, K, never>(
77
77
  store,
78
78
  {
79
79
  key: `${options.key}:JSON`,
@@ -5,7 +5,7 @@ import type {
5
5
  UpdateHandler,
6
6
  } from "atom.io"
7
7
 
8
- import type { MutableAtom } from ".."
8
+ import type { MutableAtom, RootStore } from ".."
9
9
  import { createStandaloneSelector, resetInStore, setIntoStore } from ".."
10
10
  import { newest } from "../lineage"
11
11
  import { deposit, type Store } from "../store"
@@ -45,7 +45,7 @@ export function createMutableAtom<T extends Transceiver<any, any, any>>(
45
45
  const newAtom: MutableAtom<T> = {
46
46
  ...options,
47
47
  type,
48
- install: (s: Store) => {
48
+ install: (s: RootStore) => {
49
49
  s.logger.info(`🛠️`, `atom`, key, `installing in store "${s.config.name}"`)
50
50
  return createMutableAtom(s, options, family)
51
51
  },
@@ -12,12 +12,13 @@ export const getJsonFamily = <
12
12
  >(
13
13
  mutableAtomFamily: MutableAtomFamilyToken<Core, Key>,
14
14
  store: Store,
15
- ): WritablePureSelectorFamily<ReturnType<Core[`toJSON`]>, Key> => {
15
+ ): WritablePureSelectorFamily<ReturnType<Core[`toJSON`]>, Key, never> => {
16
16
  const target = newest(store)
17
17
  const key = `${mutableAtomFamily.key}:JSON`
18
18
  const jsonFamily = target.families.get(key) as WritablePureSelectorFamily<
19
19
  ReturnType<Core[`toJSON`]>,
20
- Key
20
+ Key,
21
+ never
21
22
  >
22
23
  return jsonFamily
23
24
  }
@@ -1,7 +1,7 @@
1
1
  import type { MutableAtomFamilyToken } from "atom.io"
2
2
  import type { Json } from "atom.io/json"
3
3
 
4
- import type { AtomFamily } from ".."
4
+ import type { RegularAtomFamily } from ".."
5
5
  import { newest } from "../lineage"
6
6
  import type { Store } from "../store"
7
7
  import type { SignalFrom, Transceiver } from "./transceiver"
@@ -12,11 +12,13 @@ export const getUpdateFamily = <
12
12
  >(
13
13
  mutableAtomFamily: MutableAtomFamilyToken<T, K>,
14
14
  store: Store,
15
- ): AtomFamily<SignalFrom<T>, K> => {
15
+ ): RegularAtomFamily<SignalFrom<T>, K, never> => {
16
16
  const target = newest(store)
17
17
  const key = `*${mutableAtomFamily.key}`
18
- const updateFamily: AtomFamily<SignalFrom<T>, K> = target.families.get(
19
- key,
20
- ) as AtomFamily<SignalFrom<T>, K>
18
+ const updateFamily = target.families.get(key) as RegularAtomFamily<
19
+ SignalFrom<T>,
20
+ K,
21
+ never
22
+ >
21
23
  return updateFamily
22
24
  }
@@ -2,9 +2,9 @@ import type { MutableAtomToken, StateLifecycleEvent } from "atom.io"
2
2
  import type { Canonical } from "atom.io/json"
3
3
  import { parseJson } from "atom.io/json"
4
4
 
5
- import type { MutableAtomFamily, RegularAtomFamily } from ".."
5
+ import type { MutableAtomFamily, RegularAtomFamily, RootStore } from ".."
6
6
  import { createRegularAtomFamily } from "../families"
7
- import { type Store, withdraw } from "../store"
7
+ import { withdraw } from "../store"
8
8
  import { Tracker } from "./tracker"
9
9
  import type { SignalFrom, Transceiver } from "./transceiver"
10
10
 
@@ -17,8 +17,12 @@ export class FamilyTracker<
17
17
  public readonly latestSignalAtoms: RegularAtomFamily<SignalFrom<T> | null, K>
18
18
  public readonly mutableAtoms: MutableAtomFamily<T, K>
19
19
 
20
- public constructor(mutableAtoms: MutableAtomFamily<T, K>, store: Store) {
21
- const latestSignalAtoms = createRegularAtomFamily<SignalFrom<T> | null, K>(
20
+ public constructor(mutableAtoms: MutableAtomFamily<T, K>, store: RootStore) {
21
+ const latestSignalAtoms = createRegularAtomFamily<
22
+ SignalFrom<T> | null,
23
+ K,
24
+ never
25
+ >(
22
26
  store,
23
27
  {
24
28
  key: `*${mutableAtoms.key}`,
@@ -31,7 +31,11 @@ export class Tracker<T extends Transceiver<any, any, any>> {
31
31
  subKey: mutableState.family.subKey,
32
32
  }
33
33
  : undefined
34
- const latestSignalState = createRegularAtom<SignalFrom<T> | null>(
34
+ const latestSignalState = createRegularAtom<
35
+ SignalFrom<T> | null,
36
+ any,
37
+ never
38
+ >(
35
39
  store,
36
40
  {
37
41
  key: latestSignalStateKey,
@@ -8,7 +8,9 @@ export type OperationProgress =
8
8
  | {
9
9
  open: false
10
10
  }
11
- export type OpenOperation<R extends ReadableToken<any> = ReadableToken<any>> = {
11
+ export type OpenOperation<
12
+ R extends ReadableToken<any, any> = ReadableToken<any, any>,
13
+ > = {
12
14
  open: true
13
15
  token: R
14
16
  done: Set<string>
@@ -19,7 +21,7 @@ export type OpenOperation<R extends ReadableToken<any> = ReadableToken<any>> = {
19
21
 
20
22
  export function openOperation(
21
23
  store: Store,
22
- token: ReadableToken<any>,
24
+ token: ReadableToken<any, any, any>,
23
25
  ): number | (Store & { operation: OpenOperation }) {
24
26
  if (store.operation.open) {
25
27
  const rejectionTime = performance.now()
@@ -4,7 +4,7 @@ import type {
4
4
  ReadonlyHeldSelectorToken,
5
5
  } from "atom.io"
6
6
 
7
- import type { ReadonlyHeldSelector } from ".."
7
+ import type { ReadonlyHeldSelector, RootStore } from ".."
8
8
  import { writeToCache } from "../caching"
9
9
  import { newest } from "../lineage"
10
10
  import type { Store } from "../store"
@@ -47,7 +47,7 @@ export function createReadonlyHeldSelector<T extends object>(
47
47
  type,
48
48
  subject,
49
49
  getFrom,
50
- install: (s: Store) => createReadonlyHeldSelector(s, options, family),
50
+ install: (s: RootStore) => createReadonlyHeldSelector(s, options, family),
51
51
  }
52
52
  if (family) readonlySelector.family = family
53
53
 
@@ -2,22 +2,24 @@ import type {
2
2
  FamilyMetadata,
3
3
  ReadonlyPureSelectorOptions,
4
4
  ReadonlyPureSelectorToken,
5
+ StateUpdate,
5
6
  } from "atom.io"
7
+ import type { Canonical } from "atom.io/json"
6
8
 
7
- import type { ReadonlyPureSelector } from ".."
9
+ import type { ReadonlyPureSelector, RootStore } from ".."
8
10
  import { writeToCache } from "../caching"
9
11
  import { newest } from "../lineage"
10
12
  import type { Store } from "../store"
11
13
  import { Subject } from "../subject"
12
14
  import { registerSelector } from "./register-selector"
13
15
 
14
- export function createReadonlyPureSelector<T>(
16
+ export function createReadonlyPureSelector<T, K extends Canonical, E>(
15
17
  store: Store,
16
- options: ReadonlyPureSelectorOptions<T>,
17
- family: FamilyMetadata | undefined,
18
- ): ReadonlyPureSelectorToken<T> {
18
+ options: ReadonlyPureSelectorOptions<T, E>,
19
+ family: FamilyMetadata<K> | undefined,
20
+ ): ReadonlyPureSelectorToken<T, K, E> {
19
21
  const target = newest(store)
20
- const subject = new Subject<{ newValue: T; oldValue: T }>()
22
+ const subject = new Subject<StateUpdate<E | T>>()
21
23
  const covered = new Set<string>()
22
24
  const key = options.key
23
25
  const type = `readonly_pure_selector` as const
@@ -43,12 +45,12 @@ export function createReadonlyPureSelector<T>(
43
45
  return cached
44
46
  }
45
47
 
46
- const readonlySelector: ReadonlyPureSelector<T> = {
48
+ const readonlySelector: ReadonlyPureSelector<T, E> = {
47
49
  ...options,
48
50
  type,
49
51
  subject,
50
52
  getFrom,
51
- install: (s: Store) => createReadonlyPureSelector(s, options, family),
53
+ install: (s: RootStore) => createReadonlyPureSelector(s, options, family),
52
54
  }
53
55
  if (family) readonlySelector.family = family
54
56
 
@@ -23,26 +23,26 @@ export function createStandaloneSelector<T extends object>(
23
23
  store: Store,
24
24
  options: ReadonlyHeldSelectorOptions<T>,
25
25
  ): ReadonlyHeldSelectorToken<T>
26
- export function createStandaloneSelector<T>(
26
+ export function createStandaloneSelector<T, E>(
27
27
  store: Store,
28
- options: WritablePureSelectorOptions<T>,
29
- ): WritablePureSelectorToken<T>
30
- export function createStandaloneSelector<T>(
28
+ options: WritablePureSelectorOptions<T, E>,
29
+ ): WritablePureSelectorToken<T, any, E>
30
+ export function createStandaloneSelector<T, E>(
31
31
  store: Store,
32
- options: ReadonlyPureSelectorOptions<T>,
33
- ): ReadonlyPureSelectorToken<T>
32
+ options: ReadonlyPureSelectorOptions<T, E>,
33
+ ): ReadonlyPureSelectorToken<T, any, E>
34
34
  export function createStandaloneSelector(
35
35
  store: Store,
36
36
  options:
37
37
  | ReadonlyHeldSelectorOptions<any>
38
- | ReadonlyPureSelectorOptions<any>
38
+ | ReadonlyPureSelectorOptions<any, any>
39
39
  | WritableHeldSelectorOptions<any>
40
- | WritablePureSelectorOptions<any>,
40
+ | WritablePureSelectorOptions<any, any>,
41
41
  ):
42
42
  | ReadonlyHeldSelectorToken<any>
43
- | ReadonlyPureSelectorToken<any>
43
+ | ReadonlyPureSelectorToken<any, any, any>
44
44
  | WritableHeldSelectorToken<any>
45
- | WritablePureSelectorToken<any> {
45
+ | WritablePureSelectorToken<any, any, any> {
46
46
  const isWritable = `set` in options
47
47
  const isHeld = `const` in options
48
48
 
@@ -4,7 +4,7 @@ import type {
4
4
  WritableHeldSelectorToken,
5
5
  } from "atom.io"
6
6
 
7
- import type { WritableHeldSelector } from ".."
7
+ import type { RootStore, WritableHeldSelector } from ".."
8
8
  import { writeToCache } from "../caching"
9
9
  import { newest } from "../lineage"
10
10
  import type { Store } from "../store"
@@ -54,7 +54,7 @@ export function createWritableHeldSelector<T extends object>(
54
54
  subject,
55
55
  getFrom,
56
56
  setSelf,
57
- install: (s: Store) => createWritableHeldSelector(s, options, family),
57
+ install: (s: RootStore) => createWritableHeldSelector(s, options, family),
58
58
  }
59
59
  if (family) mySelector.family = family
60
60
 
@@ -1,23 +1,25 @@
1
1
  import type {
2
2
  FamilyMetadata,
3
+ StateUpdate,
3
4
  WritablePureSelectorOptions,
4
5
  WritablePureSelectorToken,
5
6
  } from "atom.io"
7
+ import type { Canonical } from "atom.io/json"
6
8
 
7
- import type { WritablePureSelector } from ".."
9
+ import type { RootStore, WritablePureSelector } from ".."
8
10
  import { writeToCache } from "../caching"
9
11
  import { newest } from "../lineage"
10
12
  import type { Store } from "../store"
11
13
  import { Subject } from "../subject"
12
14
  import { registerSelector } from "./register-selector"
13
15
 
14
- export function createWritablePureSelector<T>(
16
+ export function createWritablePureSelector<T, K extends Canonical, E>(
15
17
  store: Store,
16
- options: WritablePureSelectorOptions<T>,
17
- family: FamilyMetadata | undefined,
18
- ): WritablePureSelectorToken<T> {
18
+ options: WritablePureSelectorOptions<T, E>,
19
+ family: FamilyMetadata<K> | undefined,
20
+ ): WritablePureSelectorToken<T, K, E> {
19
21
  const target = newest(store)
20
- const subject = new Subject<{ newValue: T; oldValue: T }>()
22
+ const subject = new Subject<StateUpdate<E | T>>()
21
23
  const covered = new Set<string>()
22
24
  const key = options.key
23
25
  const type = `writable_pure_selector` as const
@@ -27,7 +29,7 @@ export function createWritablePureSelector<T>(
27
29
  const { find, get, json } = setterToolkit
28
30
  const getterToolkit = { find, get, json }
29
31
 
30
- const getFrom = (innerTarget: Store): T => {
32
+ const getFrom = (innerTarget: Store): E | T => {
31
33
  const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
32
34
  downstreamSelectorKey: key,
33
35
  })
@@ -48,13 +50,13 @@ export function createWritablePureSelector<T>(
48
50
  options.set(setterToolkit, newValue)
49
51
  }
50
52
 
51
- const mySelector: WritablePureSelector<T> = {
53
+ const mySelector: WritablePureSelector<T, E> = {
52
54
  ...options,
53
55
  type,
54
56
  subject,
55
57
  getFrom,
56
58
  setSelf,
57
- install: (s: Store) => createWritablePureSelector(s, options, family),
59
+ install: (s: RootStore) => createWritablePureSelector(s, options, family),
58
60
  }
59
61
  if (family) mySelector.family = family
60
62
 
@@ -5,7 +5,7 @@ import { isChildStore, newest, withdraw } from ".."
5
5
 
6
6
  export function disposeSelector(
7
7
  store: Store,
8
- selectorToken: SelectorToken<unknown>,
8
+ selectorToken: SelectorToken<unknown, any, any>,
9
9
  ): void {
10
10
  const target = newest(store)
11
11
  const { key, type, family: familyMeta } = selectorToken
@@ -21,7 +21,7 @@ export function disposeSelector(
21
21
  if (molecule) {
22
22
  target.moleculeData.delete(familyMeta.subKey, familyMeta.key)
23
23
  }
24
- let familyToken: SelectorFamilyToken<any, any>
24
+ let familyToken: SelectorFamilyToken<any, any, any>
25
25
  switch (selectorToken.type) {
26
26
  case `writable_held_selector`:
27
27
  {
@@ -33,8 +33,8 @@ export function registerSelector(
33
33
  return {
34
34
  get: (
35
35
  ...params:
36
- | [ReadableFamilyToken<any, any>, Canonical]
37
- | [ReadableToken<any>]
36
+ | [ReadableFamilyToken<any, any, any>, Canonical]
37
+ | [ReadableToken<any, any, any>]
38
38
  ) => {
39
39
  const target = newest(store)
40
40
  const { token, family, subKey } = reduceReference(store, ...params)
@@ -6,10 +6,10 @@ export function traceRootSelectorAtoms(
6
6
  store: Store,
7
7
  selectorKey: string,
8
8
  covered: Set<string> = new Set<string>(),
9
- ): Map<string, Atom<unknown>> {
9
+ ): Map<string, Atom<any, any>> {
10
10
  const dependencies = getSelectorDependencyKeys(store, selectorKey)
11
11
 
12
- const roots = new Map<string, Atom<unknown>>()
12
+ const roots = new Map<string, Atom<unknown, unknown>>()
13
13
 
14
14
  while (dependencies.length > 0) {
15
15
  // biome-ignore lint/style/noNonNullAssertion: just checked length ^^^
@@ -19,7 +19,7 @@ export function traceRootSelectorAtoms(
19
19
  }
20
20
  covered.add(dependencyKey)
21
21
  if (isAtomKey(store, dependencyKey)) {
22
- const atom = store.atoms.get(dependencyKey) as Atom<unknown>
22
+ const atom = store.atoms.get(dependencyKey) as Atom<unknown, unknown>
23
23
  roots.set(atom.key, atom)
24
24
  } else {
25
25
  dependencies.push(...getSelectorDependencyKeys(store, dependencyKey))
@@ -12,7 +12,7 @@ export function updateSelectorAtoms(
12
12
  | `writable_held_selector`
13
13
  | `writable_pure_selector`,
14
14
  selectorKey: string,
15
- dependency: ReadableToken<unknown>,
15
+ dependency: ReadableToken<unknown, any, unknown>,
16
16
  covered: Set<string>,
17
17
  ): void {
18
18
  const target = newest(store)
@@ -1,9 +1,7 @@
1
1
  import { isFn } from "../is-fn"
2
2
 
3
- export type Modify<T> = (thing: T) => T
4
-
5
3
  export function become<T>(
6
- nextVersionOfThing: Modify<T> | T,
4
+ nextVersionOfThing: T | ((prev: T) => T),
7
5
  originalThing: T,
8
6
  ): T {
9
7
  if (isFn(nextVersionOfThing)) {
@@ -17,18 +17,18 @@ import { isChildStore, isRootStore } from "../transaction"
17
17
  import { evictDownstreamFromAtom } from "./evict-downstream"
18
18
  import type { ProtoUpdate } from "./operate-on-store"
19
19
 
20
- export function dispatchOrDeferStateUpdate<T>(
20
+ export function dispatchOrDeferStateUpdate<T, E>(
21
21
  target: Store & { operation: OpenOperation<any> },
22
- state: WritableState<T>,
23
- { oldValue, newValue }: ProtoUpdate<T>,
22
+ state: WritableState<T, E>,
23
+ { oldValue, newValue }: ProtoUpdate<E | T>,
24
24
  stateIsNewlyCreated: boolean,
25
- family?: WritableFamily<T, any>,
25
+ family?: WritableFamily<T, any, E>,
26
26
  ): void {
27
27
  const token = deposit(state)
28
28
  if (stateIsNewlyCreated && family) {
29
29
  state.subject.next({ newValue })
30
30
  const stateCreationEvent: StateCreationEvent<any> & TimelineEvent<any> = {
31
- write: true,
31
+ checkpoint: true,
32
32
  type: `state_creation`,
33
33
  subType: `writable`,
34
34
  token,
@@ -128,7 +128,11 @@ export function dispatchOrDeferStateUpdate<T>(
128
128
  const mutable = target.atoms.get(keyOfMutable) as MutableAtom<
129
129
  Transceiver<unknown, any, any>
130
130
  >
131
- const transceiver = readOrComputeValue(target, mutable, `mut`)
131
+ const transceiver = readOrComputeValue<Transceiver<any, any, any>, never>(
132
+ target,
133
+ mutable,
134
+ `mut`,
135
+ )
132
136
  const accepted = transceiver.do(update.newValue) === null
133
137
  if (accepted === true) {
134
138
  evictDownstreamFromAtom(target, mutable)
@@ -4,7 +4,10 @@ import { newest } from "../lineage"
4
4
  import { isDone, markDone } from "../operation"
5
5
  import type { Store } from "../store"
6
6
 
7
- export function evictDownstreamFromAtom(store: Store, atom: Atom<any>): void {
7
+ export function evictDownstreamFromAtom(
8
+ store: Store,
9
+ atom: Atom<any, any>,
10
+ ): void {
8
11
  const target = newest(store)
9
12
  const { key, type } = atom
10
13
  const downstreamKeys = target.selectorAtoms.getRelatedKeys(key)