atom.io 0.37.1 → 0.38.1

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 (44) hide show
  1. package/dist/internal/index.d.ts +23 -25
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +193 -138
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/json/index.d.ts +3 -1
  6. package/dist/json/index.d.ts.map +1 -1
  7. package/dist/json/index.js +3 -2
  8. package/dist/json/index.js.map +1 -1
  9. package/dist/main/index.d.ts +6 -3
  10. package/dist/main/index.d.ts.map +1 -1
  11. package/dist/main/index.js +22 -2
  12. package/dist/main/index.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/internal/atom/dispose-atom.ts +1 -2
  15. package/src/internal/families/create-readonly-held-selector-family.ts +2 -4
  16. package/src/internal/families/create-readonly-pure-selector-family.ts +2 -4
  17. package/src/internal/families/create-regular-atom-family.ts +3 -4
  18. package/src/internal/families/create-writable-held-selector-family.ts +3 -4
  19. package/src/internal/families/create-writable-pure-selector-family.ts +2 -4
  20. package/src/internal/families/find-in-store.ts +7 -1
  21. package/src/internal/families/get-family-of-token.ts +21 -24
  22. package/src/internal/families/mint-in-store.ts +59 -35
  23. package/src/internal/get-state/get-fallback.ts +57 -0
  24. package/src/internal/get-state/get-from-store.ts +11 -61
  25. package/src/internal/get-state/reduce-reference.ts +66 -0
  26. package/src/internal/index.ts +0 -1
  27. package/src/internal/ingest-updates/ingest-creation-disposal.ts +4 -3
  28. package/src/internal/molecule.ts +5 -5
  29. package/src/internal/mutable/create-mutable-atom-family.ts +3 -8
  30. package/src/internal/mutable/get-json-token.ts +2 -1
  31. package/src/internal/not-found-error.ts +2 -3
  32. package/src/internal/operation.ts +1 -1
  33. package/src/internal/selector/register-selector.ts +17 -24
  34. package/src/internal/selector/update-selector-atoms.ts +2 -2
  35. package/src/internal/set-state/operate-on-store.ts +17 -13
  36. package/src/internal/set-state/set-into-store.ts +2 -2
  37. package/src/internal/store/index.ts +1 -1
  38. package/src/internal/store/{counterfeit.ts → mint-or-counterfeit.ts} +27 -15
  39. package/src/internal/store/store.ts +1 -1
  40. package/src/internal/subscribe/subscribe-to-state.ts +2 -0
  41. package/src/internal/timeline/create-timeline.ts +2 -0
  42. package/src/json/index.ts +6 -3
  43. package/src/main/logger.ts +26 -4
  44. package/src/internal/pretty-print.ts +0 -7
@@ -9,66 +9,90 @@ import { stringifyJson } from "atom.io/json"
9
9
 
10
10
  import { newest } from "../lineage"
11
11
  import type { Store } from "../store"
12
- import { counterfeit } from "../store"
12
+ import { COUNTERFEIT, mint } from "../store"
13
13
  import { isChildStore, isRootStore } from "../transaction"
14
14
  import { initFamilyMemberInStore } from "./init-family-member"
15
15
 
16
+ export const MUST_CREATE: unique symbol = Symbol(`MUST_NOT_EXIST`)
17
+
16
18
  export function mintInStore<T, K extends Canonical, Key extends K>(
17
19
  store: Store,
18
20
  familyToken: WritableFamilyToken<T, K>,
19
21
  key: Key,
22
+ init?: typeof MUST_CREATE,
20
23
  ): WritableToken<T, K>
21
24
  export function mintInStore<T, K extends Canonical, Key extends K>(
22
25
  store: Store,
23
26
  familyToken: ReadableFamilyToken<T, K>,
24
27
  key: Key,
28
+ init?: typeof MUST_CREATE,
25
29
  ): ReadableToken<T, K>
26
30
  export function mintInStore<T, K extends Canonical, Key extends K>(
27
31
  store: Store,
28
32
  familyToken: ReadableFamilyToken<T, K>,
29
33
  key: Key,
34
+ shouldCreate?: typeof MUST_CREATE,
30
35
  ): ReadableToken<T, K> {
36
+ let stateToken: ReadableToken<T, K>
37
+
38
+ let willCreate: boolean
39
+ switch (shouldCreate) {
40
+ case MUST_CREATE:
41
+ willCreate = true
42
+ break
43
+ case undefined:
44
+ willCreate = false
45
+ break
46
+ }
47
+
31
48
  const stringKey = stringifyJson(key)
32
49
  const molecule = store.molecules.get(stringKey)
33
50
  if (!molecule && store.config.lifespan === `immortal`) {
34
- const fakeToken = counterfeit(familyToken, key)
35
- store.logger.error(
36
- `❌`,
37
- fakeToken.type,
38
- fakeToken.key,
39
- `was not found in store "${store.config.name}"; returned a counterfeit token.`,
51
+ const fakeToken = mint(familyToken, key, COUNTERFEIT)
52
+ store.logger.warn(
53
+ `💣`,
54
+ `key`,
55
+ stringKey,
56
+ `was used to mint a counterfeit token for`,
57
+ familyToken.type,
58
+ `"${familyToken.key}"`,
40
59
  )
41
60
  return fakeToken
42
61
  }
43
- const newStateToken = initFamilyMemberInStore(store, familyToken, key)
44
- const target = newest(store)
45
- if (newStateToken.family) {
46
- if (isRootStore(target)) {
47
- switch (newStateToken.type) {
48
- case `atom`:
49
- case `mutable_atom`:
50
- store.on.atomCreation.next(newStateToken)
51
- break
52
- case `writable_pure_selector`:
53
- case `readonly_pure_selector`:
54
- case `writable_held_selector`:
55
- case `readonly_held_selector`:
56
- store.on.selectorCreation.next(newStateToken)
57
- break
62
+
63
+ if (willCreate) {
64
+ stateToken = initFamilyMemberInStore(store, familyToken, key)
65
+ const target = newest(store)
66
+ if (stateToken.family) {
67
+ if (isRootStore(target)) {
68
+ switch (stateToken.type) {
69
+ case `atom`:
70
+ case `mutable_atom`:
71
+ store.on.atomCreation.next(stateToken)
72
+ break
73
+ case `writable_pure_selector`:
74
+ case `readonly_pure_selector`:
75
+ case `writable_held_selector`:
76
+ case `readonly_held_selector`:
77
+ store.on.selectorCreation.next(stateToken)
78
+ break
79
+ }
80
+ } else if (
81
+ isChildStore(target) &&
82
+ target.on.transactionApplying.state === null
83
+ ) {
84
+ target.transactionMeta.update.subEvents.push({
85
+ type: `state_creation`,
86
+ token: stateToken,
87
+ timestamp: Date.now(),
88
+ })
58
89
  }
59
- } else if (
60
- isChildStore(target) &&
61
- target.on.transactionApplying.state === null
62
- ) {
63
- target.transactionMeta.update.subEvents.push({
64
- type: `state_creation`,
65
- token: newStateToken,
66
- timestamp: Date.now(),
67
- })
68
90
  }
91
+ if (molecule) {
92
+ target.moleculeData.set(stringKey, familyToken.key)
93
+ }
94
+ } else {
95
+ stateToken = mint(familyToken, key)
69
96
  }
70
- if (molecule) {
71
- target.moleculeData.set(stringKey, familyToken.key)
72
- }
73
- return newStateToken
97
+ return stateToken
74
98
  }
@@ -0,0 +1,57 @@
1
+ import type { ReadableToken } from "atom.io"
2
+ import { type Canonical, stringifyJson } from "atom.io/json"
3
+
4
+ import type { ReadableFamily } from ".."
5
+ import type { Store } from "../store"
6
+
7
+ export function getFallback<T, K extends Canonical>(
8
+ store: Store,
9
+ token: ReadableToken<T, K>,
10
+ family: ReadableFamily<T, K>,
11
+ subKey: K,
12
+ ): T {
13
+ const disposal = store.disposalTraces.buffer.find(
14
+ (item) => item?.key === stringifyJson(subKey),
15
+ )
16
+ store.logger.error(
17
+ `❌`,
18
+ token.type,
19
+ token.key,
20
+ `gets a fallback value because key`,
21
+ subKey,
22
+ `is not allocated`,
23
+ disposal
24
+ ? `This key was previously disposed:\n${disposal.trace}`
25
+ : `(no previous disposal trace found)`,
26
+ )
27
+ switch (family.type) {
28
+ case `mutable_atom_family`: {
29
+ if (store.defaults.has(family.key)) {
30
+ return store.defaults.get(family.key)
31
+ }
32
+ const defaultValue = new family.class()
33
+ store.defaults.set(family.key, defaultValue)
34
+ return defaultValue
35
+ }
36
+ case `atom_family`: {
37
+ if (store.defaults.has(family.key)) {
38
+ return store.defaults.get(family.key)
39
+ }
40
+ const def = family.default as (key: K) => T
41
+ const defaultValue = def(subKey)
42
+ store.defaults.set(family.key, defaultValue)
43
+ return defaultValue
44
+ }
45
+ case `readonly_pure_selector_family`:
46
+ case `writable_pure_selector_family`:
47
+ case `readonly_held_selector_family`:
48
+ case `writable_held_selector_family`: {
49
+ if (store.defaults.has(family.key)) {
50
+ return store.defaults.get(family.key)
51
+ }
52
+ const defaultValue = family.default(subKey)
53
+ store.defaults.set(family.key, defaultValue)
54
+ return defaultValue
55
+ }
56
+ }
57
+ }
@@ -1,10 +1,10 @@
1
1
  import type { ReadableFamilyToken, ReadableToken } from "atom.io"
2
- import { type Canonical, parseJson } from "atom.io/json"
2
+ import type { Canonical } from "atom.io/json"
3
3
 
4
- import { findInStore } from "../families"
5
- import type { Store } from "../store"
6
- import { withdraw } from "../store"
4
+ import { type Store, withdraw } from "../store"
5
+ import { getFallback } from "./get-fallback"
7
6
  import { readOrComputeValue } from "./read-or-compute-value"
7
+ import { reduceReference } from "./reduce-reference"
8
8
 
9
9
  export function getFromStore<T>(store: Store, token: ReadableToken<T>): T
10
10
 
@@ -20,63 +20,13 @@ export function getFromStore(
20
20
  | [token: ReadableFamilyToken<any, any>, key: Canonical]
21
21
  | [token: ReadableToken<any>]
22
22
  ): any {
23
- let token: ReadableToken<any>
24
- let family: ReadableFamilyToken<any, Canonical> | null
25
- let key: Canonical | null
26
- if (params.length === 1) {
27
- token = params[0]
28
- } else {
29
- family = params[0]
30
- key = params[1]
31
- token = findInStore(store, family, key)
32
- }
33
- if (`counterfeit` in token && `family` in token) {
34
- // biome-ignore lint/style/noNonNullAssertion: family must be present
35
- family = store.families.get(token.family.key)!
36
- const subKey = token.family.subKey
37
- const disposal = store.disposalTraces.buffer.find(
38
- (item) => item?.key === subKey,
39
- )
40
- store.logger.error(
41
- `❌`,
42
- token.type,
43
- token.key,
44
- `could not be retrieved because it was not found in the store "${store.config.name}".`,
45
- disposal
46
- ? `This state was previously disposed:\n${disposal.trace}`
47
- : `No previous disposal trace was found.`,
48
- )
49
- switch (family.type) {
50
- case `mutable_atom_family`: {
51
- if (store.defaults.has(family.key)) {
52
- return store.defaults.get(family.key)
53
- }
54
- const mutableFamily = withdraw(store, family)
55
- const defaultValue = new mutableFamily.class()
56
- store.defaults.set(family.key, defaultValue)
57
- return defaultValue
58
- }
59
- case `atom_family`: {
60
- if (store.defaults.has(family.key)) {
61
- return store.defaults.get(token.family.key)
62
- }
63
- const defaultValue = withdraw(store, family).default(parseJson(subKey))
64
- store.defaults.set(family.key, defaultValue)
65
- return defaultValue
66
- }
67
- case `readonly_pure_selector_family`:
68
- case `writable_pure_selector_family`:
69
- case `readonly_held_selector_family`:
70
- case `writable_held_selector_family`: {
71
- if (store.defaults.has(family.key)) {
72
- return store.defaults.get(token.family.key)
73
- }
74
- const defaultValue = withdraw(store, family).default(parseJson(subKey))
75
- store.defaults.set(family.key, defaultValue)
76
- return defaultValue
77
- }
78
- }
23
+ const { token, familyToken, subKey } = reduceReference(store, ...params)
24
+
25
+ if (`counterfeit` in token && familyToken && subKey) {
26
+ const family = withdraw(store, familyToken)
27
+ return getFallback(store, token, family, subKey)
79
28
  }
29
+ const state = withdraw(store, token)
80
30
 
81
- return readOrComputeValue(store, withdraw(store, token))
31
+ return readOrComputeValue(store, state)
82
32
  }
@@ -0,0 +1,66 @@
1
+ import type { ReadableFamilyToken, ReadableToken } from "atom.io"
2
+ import { type Canonical, parseJson } from "atom.io/json"
3
+
4
+ import { seekInStore } from "../families"
5
+ import { getFamilyOfToken } from "../families/get-family-of-token"
6
+ import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
7
+ import type { Store } from "../store"
8
+ import { withdraw } from "../store"
9
+
10
+ export function reduceReference<T, K extends Canonical>(
11
+ store: Store,
12
+ ...params:
13
+ | [token: ReadableFamilyToken<T, K>, key: K]
14
+ | [token: ReadableToken<T>]
15
+ ): {
16
+ token: ReadableToken<T>
17
+ familyToken: ReadableFamilyToken<T, K> | undefined
18
+ subKey: K | undefined
19
+ isNew: boolean
20
+ } {
21
+ let existingToken: ReadableToken<T> | undefined
22
+ let brandNewToken: ReadableToken<T> | undefined
23
+ let familyToken: ReadableFamilyToken<T, K> | undefined
24
+ let subKey: K | undefined
25
+ let token: ReadableToken<T, K>
26
+ if (params.length === 1) {
27
+ token = params[0]
28
+ if (`family` in token) {
29
+ familyToken = getFamilyOfToken(store, token)
30
+ withdraw(store, familyToken)
31
+ subKey = parseJson(token.family.subKey)
32
+ existingToken = seekInStore(store, familyToken, subKey)
33
+ if (`counterfeit` in token) {
34
+ return {
35
+ token,
36
+ familyToken,
37
+ subKey,
38
+ isNew: false,
39
+ }
40
+ }
41
+ if (!existingToken) {
42
+ brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE)
43
+ token = brandNewToken
44
+ } else {
45
+ token = existingToken
46
+ }
47
+ }
48
+ } else {
49
+ familyToken = params[0]
50
+ subKey = params[1]
51
+ existingToken = seekInStore(store, familyToken, subKey)
52
+ if (!existingToken) {
53
+ brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE)
54
+ token = brandNewToken
55
+ } else {
56
+ token = existingToken
57
+ }
58
+ }
59
+
60
+ return {
61
+ token,
62
+ familyToken,
63
+ subKey,
64
+ isNew: Boolean(brandNewToken),
65
+ }
66
+ }
@@ -45,7 +45,6 @@ export * from "./molecule"
45
45
  export * from "./mutable"
46
46
  export * from "./not-found-error"
47
47
  export * from "./operation"
48
- export * from "./pretty-print"
49
48
  export * from "./reserved-keys"
50
49
  export * from "./selector"
51
50
  export * from "./set-state"
@@ -8,7 +8,8 @@ import type {
8
8
  } from "atom.io"
9
9
  import { parseJson, stringifyJson } from "atom.io/json"
10
10
 
11
- import { disposeFromStore, findInStore } from "../families"
11
+ import { disposeFromStore } from "../families"
12
+ import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
12
13
  import {
13
14
  allocateIntoStore,
14
15
  claimWithinStore,
@@ -61,7 +62,7 @@ function createInStore(
61
62
  if (familyMeta) {
62
63
  const family = store.families.get(familyMeta.key)
63
64
  if (family) {
64
- findInStore(store, family, parseJson(familyMeta.subKey))
65
+ mintInStore(store, family, parseJson(familyMeta.subKey), MUST_CREATE)
65
66
  }
66
67
  }
67
68
  }
@@ -98,7 +99,7 @@ export function ingestMoleculeDisposalEvent(
98
99
  for (const [familyKey, value] of update.values) {
99
100
  const family = store.families.get(familyKey)
100
101
  if (family) {
101
- findInStore(store, family, update.key)
102
+ mintInStore(store, family, update.key, MUST_CREATE)
102
103
  const memberKey = `${familyKey}(${stringifyJson(update.key)})`
103
104
  store.valueMap.set(memberKey, value)
104
105
  }
@@ -97,7 +97,7 @@ export function allocateIntoStore<
97
97
  )
98
98
  store.logger.error(
99
99
  `❌`,
100
- `molecule`,
100
+ `key`,
101
101
  key,
102
102
  `allocation failed:`,
103
103
  `Could not allocate to ${claim} in store "${store.config.name}".`,
@@ -147,7 +147,7 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
147
147
  )
148
148
  store.logger.error(
149
149
  `❌`,
150
- `molecule`,
150
+ `key`,
151
151
  claim,
152
152
  `deallocation failed:`,
153
153
  `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
@@ -244,8 +244,8 @@ export function claimWithinStore<
244
244
  )
245
245
  store.logger.error(
246
246
  `❌`,
247
- `molecule`,
248
- claim,
247
+ `key`,
248
+ stringKey,
249
249
  `claim failed:`,
250
250
  `Could not allocate to ${stringKey} in store "${store.config.name}".`,
251
251
  disposal
@@ -263,7 +263,7 @@ export function claimWithinStore<
263
263
  )
264
264
  store.logger.error(
265
265
  `❌`,
266
- `molecule`,
266
+ `key`,
267
267
  claim,
268
268
  `claim failed:`,
269
269
  `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
@@ -6,14 +6,11 @@ import type {
6
6
  MutableAtomToken,
7
7
  StateLifecycleEvent,
8
8
  } from "atom.io"
9
+ import { PRETTY_TOKEN_TYPES } from "atom.io"
9
10
  import type { Canonical } from "atom.io/json"
10
11
  import { stringifyJson } from "atom.io/json"
11
12
 
12
- import {
13
- createWritablePureSelectorFamily,
14
- type MutableAtomFamily,
15
- prettyPrintTokenType,
16
- } from ".."
13
+ import { createWritablePureSelectorFamily, type MutableAtomFamily } from ".."
17
14
  import { newest } from "../lineage"
18
15
  import { createMutableAtom } from "../mutable"
19
16
  import type { Store } from "../store"
@@ -41,9 +38,7 @@ export function createMutableAtomFamily<
41
38
  `❗`,
42
39
  `mutable_atom_family`,
43
40
  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.`,
41
+ `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
47
42
  )
48
43
  }
49
44
 
@@ -3,6 +3,7 @@ import type {
3
3
  WritablePureSelectorFamilyToken,
4
4
  WritablePureSelectorToken,
5
5
  } from "atom.io"
6
+ import { parseJson } from "atom.io/json"
6
7
 
7
8
  import { findInStore } from "../families"
8
9
  import { newest } from "../lineage"
@@ -21,7 +22,7 @@ export const getJsonToken = <T extends Transceiver<any, any, any>>(
21
22
  type: `writable_pure_selector_family`,
22
23
  }
23
24
  const family = withdraw(target, jsonFamilyToken)
24
- const subKey = JSON.parse(mutableAtomToken.family.subKey)
25
+ const subKey = parseJson(mutableAtomToken.family.subKey)
25
26
  const jsonToken = findInStore(store, family, subKey)
26
27
  return jsonToken
27
28
  }
@@ -1,13 +1,12 @@
1
- import type { AtomIOToken } from "atom.io"
1
+ import { type AtomIOToken, PRETTY_TOKEN_TYPES } from "atom.io"
2
2
  import { stringifyJson } from "atom.io/json"
3
3
 
4
- import { prettyPrintTokenType } from "./pretty-print"
5
4
  import type { Store } from "./store"
6
5
 
7
6
  export class NotFoundError extends Error {
8
7
  public constructor(token: AtomIOToken, store: Store) {
9
8
  super(
10
- `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${
9
+ `${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${
11
10
  store.config.name
12
11
  }".`,
13
12
  )
@@ -23,7 +23,7 @@ export function openOperation(
23
23
  if (store.operation.open) {
24
24
  const rejectionTime = performance.now()
25
25
  store.logger.info(
26
- `❗`,
26
+ `🚫`,
27
27
  token.type,
28
28
  token.key,
29
29
  `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`,
@@ -7,13 +7,15 @@ import type {
7
7
  WritableToken,
8
8
  WriterToolkit,
9
9
  } from "atom.io"
10
- import type { Canonical, Json } from "atom.io/json"
10
+ import type { Canonical } from "atom.io/json"
11
11
 
12
12
  import { findInStore } from "../families"
13
+ import { getFallback } from "../get-state/get-fallback"
13
14
  import { readOrComputeValue } from "../get-state/read-or-compute-value"
15
+ import { reduceReference } from "../get-state/reduce-reference"
14
16
  import { newest } from "../lineage"
15
17
  import { getJsonToken } from "../mutable"
16
- import { operateOnStore } from "../set-state/operate-on-store"
18
+ import { JOIN_OP, operateOnStore } from "../set-state/operate-on-store"
17
19
  import type { Store } from "../store"
18
20
  import { withdraw } from "../store"
19
21
  import { updateSelectorAtoms } from "./update-selector-atoms"
@@ -31,48 +33,39 @@ export function registerSelector(
31
33
  return {
32
34
  get: (
33
35
  ...params:
34
- | [ReadableFamilyToken<any, any>, Json.Serializable]
36
+ | [ReadableFamilyToken<any, any>, Canonical]
35
37
  | [ReadableToken<any>]
36
38
  ) => {
37
39
  const target = newest(store)
38
- let dependency: ReadableToken<any>
39
-
40
- if (params.length === 2) {
41
- const [family, key] = params
42
- dependency = findInStore(store, family, key)
40
+ const { token, familyToken, subKey } = reduceReference(store, ...params)
41
+ let dependencyValue: unknown
42
+ if (`counterfeit` in token && familyToken && subKey) {
43
+ const dependencyFamily = withdraw(store, familyToken)
44
+ dependencyValue = getFallback(store, token, dependencyFamily, subKey)
43
45
  } else {
44
- ;[dependency] = params
46
+ const dependency = withdraw(store, token)
47
+ dependencyValue = readOrComputeValue(store, dependency)
45
48
  }
46
49
 
47
- const dependencyState = withdraw(store, dependency)
48
- const dependencyValue = readOrComputeValue(store, dependencyState)
49
- const dependencyKey = dependency.key
50
-
51
50
  store.logger.info(
52
51
  `🔌`,
53
52
  selectorType,
54
53
  selectorKey,
55
- `registers dependency ( "${dependencyKey}" =`,
54
+ `registers dependency ( "${token.key}" =`,
56
55
  dependencyValue,
57
56
  `)`,
58
57
  )
59
58
 
60
59
  target.selectorGraph.set(
61
60
  {
62
- upstreamSelectorKey: dependencyKey,
61
+ upstreamSelectorKey: token.key,
63
62
  downstreamSelectorKey: selectorKey,
64
63
  },
65
64
  {
66
- source: dependency.key,
65
+ source: token.key,
67
66
  },
68
67
  )
69
- updateSelectorAtoms(
70
- store,
71
- selectorType,
72
- selectorKey,
73
- dependency as any,
74
- covered,
75
- )
68
+ updateSelectorAtoms(store, selectorType, selectorKey, token, covered)
76
69
  return dependencyValue
77
70
  },
78
71
  set: (<T, K extends Canonical, New extends T, Key extends K>(
@@ -85,7 +78,7 @@ export function registerSelector(
85
78
  | [token: WritableToken<T>, value: New | ((oldValue: T) => New)]
86
79
  ) => {
87
80
  const target = newest(store)
88
- operateOnStore(target, false, ...params)
81
+ operateOnStore(target, JOIN_OP, ...params)
89
82
  }) as typeof setState,
90
83
  find: ((...args: Parameters<typeof findState>) =>
91
84
  findInStore(store, ...args)) as typeof findState,
@@ -1,4 +1,4 @@
1
- import type { ReadonlyPureSelectorToken, WritableToken } from "atom.io"
1
+ import type { ReadableToken } from "atom.io"
2
2
 
3
3
  import { newest } from "../lineage"
4
4
  import type { Store } from "../store"
@@ -12,7 +12,7 @@ export function updateSelectorAtoms(
12
12
  | `writable_held_selector`
13
13
  | `writable_pure_selector`,
14
14
  selectorKey: string,
15
- dependency: ReadonlyPureSelectorToken<unknown> | WritableToken<unknown>,
15
+ dependency: ReadableToken<unknown>,
16
16
  covered: Set<string>,
17
17
  ): void {
18
18
  const target = newest(store)
@@ -3,7 +3,7 @@ import { type Canonical, parseJson } from "atom.io/json"
3
3
 
4
4
  import { seekInStore } from "../families"
5
5
  import { getFamilyOfToken } from "../families/get-family-of-token"
6
- import { mintInStore } from "../families/mint-in-store"
6
+ import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
7
7
  import type { OpenOperation } from "../operation"
8
8
  import { closeOperation, openOperation } from "../operation"
9
9
  import { type Store, withdraw } from "../store"
@@ -12,9 +12,12 @@ import { resetAtomOrSelector } from "./reset-atom-or-selector"
12
12
  import { RESET_STATE } from "./reset-in-store"
13
13
  import { setAtomOrSelector } from "./set-atom-or-selector"
14
14
 
15
+ export const OWN_OP: unique symbol = Symbol(`OWN_OP`)
16
+ export const JOIN_OP: unique symbol = Symbol(`JOIN_OP`)
17
+
15
18
  export function operateOnStore<T, New extends T>(
16
19
  store: Store,
17
- ownOp: boolean,
20
+ opMode: typeof JOIN_OP | typeof OWN_OP,
18
21
  ...params:
19
22
  | [
20
23
  token: WritableFamilyToken<T, Canonical>,
@@ -35,13 +38,12 @@ export function operateOnStore<T, New extends T>(
35
38
  if (params.length === 2) {
36
39
  token = params[0]
37
40
  value = params[1]
38
- if (token.family) {
39
- // biome-ignore lint/style/noNonNullAssertion: this token belongs to a family
40
- family = getFamilyOfToken(store, token)!
41
+ if (`family` in token) {
42
+ family = getFamilyOfToken(store, token)
41
43
  key = parseJson(token.family.subKey)
42
44
  existingToken = seekInStore(store, family, key)
43
45
  if (!existingToken) {
44
- brandNewToken = mintInStore(store, family, key)
46
+ brandNewToken = mintInStore(store, family, key, MUST_CREATE)
45
47
  token = brandNewToken
46
48
  } else {
47
49
  token = existingToken
@@ -53,7 +55,7 @@ export function operateOnStore<T, New extends T>(
53
55
  value = params[2]
54
56
  existingToken = seekInStore(store, family, key)
55
57
  if (!existingToken) {
56
- brandNewToken = mintInStore(store, family, key)
58
+ brandNewToken = mintInStore(store, family, key, MUST_CREATE)
57
59
  token = brandNewToken
58
60
  } else {
59
61
  token = existingToken
@@ -64,7 +66,7 @@ export function operateOnStore<T, New extends T>(
64
66
 
65
67
  let target: Store & { operation: OpenOperation }
66
68
 
67
- if (ownOp) {
69
+ if (opMode === OWN_OP) {
68
70
  const result = openOperation(store, token)
69
71
  const rejected = typeof result === `number`
70
72
  if (rejected) {
@@ -81,7 +83,7 @@ export function operateOnStore<T, New extends T>(
81
83
  action,
82
84
  `from T-${rejectionTime}`,
83
85
  )
84
- operateOnStore(store, ownOp, token, value)
86
+ operateOnStore(store, opMode, token, value)
85
87
  },
86
88
  )
87
89
  return
@@ -102,10 +104,12 @@ export function operateOnStore<T, New extends T>(
102
104
  token.key,
103
105
  `could not be`,
104
106
  action,
105
- `because it was not found in the store "${store.config.name}".`,
107
+ `because key`,
108
+ subKey,
109
+ `is not allocated.`,
106
110
  disposal
107
- ? `This state was previously disposed:\n${disposal.trace}`
108
- : `No previous disposal trace was found.`,
111
+ ? `this key was previously disposed:${disposal.trace}`
112
+ : `(no previous disposal trace found)`,
109
113
  )
110
114
  return
111
115
  }
@@ -120,7 +124,7 @@ export function operateOnStore<T, New extends T>(
120
124
  const isNewlyCreated = Boolean(brandNewToken)
121
125
  dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated)
122
126
 
123
- if (ownOp) {
127
+ if (opMode === OWN_OP) {
124
128
  closeOperation(target)
125
129
  }
126
130
  }