atom.io 0.37.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/internal/index.d.ts +32 -33
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +200 -133
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/json/index.d.ts +1 -1
  6. package/dist/json/index.d.ts.map +1 -1
  7. package/dist/json/index.js.map +1 -1
  8. package/dist/main/index.d.ts +6 -3
  9. package/dist/main/index.d.ts.map +1 -1
  10. package/dist/main/index.js +22 -2
  11. package/dist/main/index.js.map +1 -1
  12. package/package.json +2 -2
  13. package/src/internal/atom/dispose-atom.ts +11 -6
  14. package/src/internal/families/create-readonly-held-selector-family.ts +2 -4
  15. package/src/internal/families/create-readonly-pure-selector-family.ts +2 -4
  16. package/src/internal/families/create-regular-atom-family.ts +7 -5
  17. package/src/internal/families/create-writable-held-selector-family.ts +3 -4
  18. package/src/internal/families/create-writable-pure-selector-family.ts +2 -4
  19. package/src/internal/families/find-in-store.ts +7 -1
  20. package/src/internal/families/get-family-of-token.ts +21 -24
  21. package/src/internal/families/mint-in-store.ts +59 -35
  22. package/src/internal/get-state/get-fallback.ts +57 -0
  23. package/src/internal/get-state/get-from-store.ts +10 -47
  24. package/src/internal/get-state/reduce-reference.ts +66 -0
  25. package/src/internal/index.ts +17 -30
  26. package/src/internal/ingest-updates/ingest-creation-disposal.ts +4 -3
  27. package/src/internal/molecule.ts +5 -5
  28. package/src/internal/mutable/create-mutable-atom-family.ts +4 -8
  29. package/src/internal/mutable/get-json-token.ts +2 -1
  30. package/src/internal/not-found-error.ts +2 -3
  31. package/src/internal/operation.ts +1 -1
  32. package/src/internal/selector/register-selector.ts +17 -24
  33. package/src/internal/selector/update-selector-atoms.ts +2 -2
  34. package/src/internal/set-state/operate-on-store.ts +17 -13
  35. package/src/internal/set-state/set-into-store.ts +2 -2
  36. package/src/internal/store/index.ts +1 -1
  37. package/src/internal/store/{counterfeit.ts → mint-or-counterfeit.ts} +27 -15
  38. package/src/internal/subscribe/subscribe-to-state.ts +2 -0
  39. package/src/internal/timeline/create-timeline.ts +2 -0
  40. package/src/json/index.ts +3 -3
  41. package/src/main/logger.ts +26 -4
  42. package/src/internal/pretty-print.ts +0 -7
@@ -1,63 +1,60 @@
1
1
  import type {
2
- MutableAtomFamilyToken,
3
2
  MutableAtomToken,
4
- ReadableFamilyToken,
5
3
  ReadableToken,
6
- ReadonlyPureSelectorFamilyToken,
7
4
  ReadonlyPureSelectorToken,
8
- RegularAtomFamilyToken,
9
5
  RegularAtomToken,
10
- WritableFamilyToken,
11
- WritablePureSelectorFamilyToken,
12
6
  WritablePureSelectorToken,
13
7
  WritableToken,
14
8
  } from "atom.io"
15
9
  import type { Canonical } from "atom.io/json"
16
10
 
11
+ import type {
12
+ MutableAtomFamily,
13
+ ReadableFamily,
14
+ ReadonlyPureSelectorFamily,
15
+ RegularAtomFamily,
16
+ WritableFamily,
17
+ WritablePureSelectorFamily,
18
+ } from ".."
17
19
  import type { Transceiver } from "../mutable"
18
- import type { Store } from "../store"
20
+ import { type Store, withdraw } from "../store"
19
21
 
20
22
  export function getFamilyOfToken<
21
23
  T extends Transceiver<any, any, any>,
22
24
  K extends Canonical,
23
- >(
24
- store: Store,
25
- token: MutableAtomToken<T, K>,
26
- ): MutableAtomFamilyToken<T, K> | undefined
25
+ >(store: Store, token: MutableAtomToken<T, K>): MutableAtomFamily<T, K>
27
26
 
28
27
  export function getFamilyOfToken<T, K extends Canonical>(
29
28
  store: Store,
30
29
  token: RegularAtomToken<T, K>,
31
- ): RegularAtomFamilyToken<T, K> | undefined
30
+ ): RegularAtomFamily<T, K>
32
31
 
33
32
  export function getFamilyOfToken<T, K extends Canonical>(
34
33
  store: Store,
35
34
  token: WritablePureSelectorToken<T, K>,
36
- ): WritablePureSelectorFamilyToken<T, K> | undefined
35
+ ): WritablePureSelectorFamily<T, K>
37
36
 
38
37
  export function getFamilyOfToken<T, K extends Canonical>(
39
38
  store: Store,
40
39
  token: ReadonlyPureSelectorToken<T, K>,
41
- ): ReadonlyPureSelectorFamilyToken<T, K> | undefined
40
+ ): ReadonlyPureSelectorFamily<T, K>
42
41
 
43
42
  export function getFamilyOfToken<T, K extends Canonical>(
44
43
  store: Store,
45
44
  token: WritableToken<T, K>,
46
- ): WritableFamilyToken<T, K> | undefined
47
-
45
+ ): WritableFamily<T, K>
48
46
  export function getFamilyOfToken<T, K extends Canonical>(
49
47
  store: Store,
50
48
  token: ReadableToken<T, K>,
51
- ): ReadableFamilyToken<T, K> | undefined
49
+ ): ReadableFamily<T, K>
52
50
 
53
51
  export function getFamilyOfToken(
54
52
  store: Store,
55
53
  token: ReadableToken<any, any>,
56
- ): ReadableFamilyToken<any, any> | undefined {
57
- if (token.family) {
58
- const family = store.families.get(token.family.key)
59
- if (family) {
60
- return family
61
- }
62
- }
54
+ ): ReadableFamily<any, any> {
55
+ return withdraw(store, {
56
+ // biome-ignore lint/style/noNonNullAssertion: family is required
57
+ key: token.family!.key,
58
+ type: `${token.type}_family`,
59
+ })
63
60
  }
@@ -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
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,50 +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 `atom_family`:
51
- case `mutable_atom_family`:
52
- return store.defaults.get(family.key)
53
- case `readonly_pure_selector_family`:
54
- case `writable_pure_selector_family`:
55
- case `readonly_held_selector_family`:
56
- case `writable_held_selector_family`: {
57
- if (store.defaults.has(family.key)) {
58
- return store.defaults.get(token.family.key)
59
- }
60
- 3
61
- const defaultValue = withdraw(store, family).default(subKey)
62
- store.defaults.set(family.key, defaultValue)
63
- return defaultValue
64
- }
65
- }
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)
66
28
  }
29
+ const state = withdraw(store, token)
67
30
 
68
- return readOrComputeValue(store, withdraw(store, token))
31
+ return readOrComputeValue(store, state)
69
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
+ }
@@ -1,5 +1,4 @@
1
1
  import type {
2
- AtomToken,
3
2
  FamilyMetadata,
4
3
  MutableAtomFamilyToken,
5
4
  MutableAtomToken,
@@ -9,8 +8,6 @@ import type {
9
8
  ReadonlyPureSelectorToken,
10
9
  RegularAtomFamilyToken,
11
10
  RegularAtomToken,
12
- StateCreationEvent,
13
- StateDisposalEvent,
14
11
  StateLifecycleEvent,
15
12
  StateUpdate,
16
13
  WritableHeldSelectorFamilyToken,
@@ -48,7 +45,6 @@ export * from "./molecule"
48
45
  export * from "./mutable"
49
46
  export * from "./not-found-error"
50
47
  export * from "./operation"
51
- export * from "./pretty-print"
52
48
  export * from "./reserved-keys"
53
49
  export * from "./selector"
54
50
  export * from "./set-state"
@@ -131,23 +127,26 @@ export type ReadableState<T> = Atom<T> | Selector<T>
131
127
 
132
128
  // biome-ignore format: intersection
133
129
  export type RegularAtomFamily<T, K extends Canonical> =
134
- & RegularAtomFamilyToken<T, K>
135
- & {
136
- (key: K): RegularAtomToken<T>
137
- install: (store: Store) => void
138
- internalRoles: string[] | undefined
139
- subject: Subject<StateCreationEvent<AtomToken<T>> | StateDisposalEvent<AtomToken<T>>>
140
- }
130
+ & Flat<
131
+ & RegularAtomFamilyToken<T, K>
132
+ & {
133
+ default: T | ((key: K) => T)
134
+ install: (store: Store) => void
135
+ internalRoles: string[] | undefined
136
+ subject: Subject<StateLifecycleEvent<RegularAtomToken<T>>>
137
+ }
138
+ >
139
+ & ((key: K) => RegularAtomToken<T>)
141
140
 
142
141
  // biome-ignore format: intersection
143
142
  export type MutableAtomFamily<
144
- // C extends TransceiverConstructor<any,any>,
145
143
  T extends Transceiver<any, any, any>,
146
144
  K extends Canonical,
147
145
  > =
148
146
  & Flat<
149
147
  & MutableAtomFamilyToken<T, K>
150
148
  & {
149
+ class: ConstructorOf<T>
151
150
  install: (store: Store) => void
152
151
  internalRoles: string[] | undefined
153
152
  subject: Subject<StateLifecycleEvent<MutableAtomToken<T>>>
@@ -167,13 +166,10 @@ export type WritablePureSelectorFamily<T, K extends Canonical> =
167
166
  default: (key: K) => T,
168
167
  install: (store: Store) => void
169
168
  internalRoles: string[] | undefined
170
- subject: Subject<
171
- | StateCreationEvent<WritablePureSelectorToken<T>>
172
- | StateDisposalEvent<WritablePureSelectorToken<T>>
173
- >
169
+ subject: Subject<StateLifecycleEvent<WritablePureSelectorToken<T>>>
174
170
  }
175
171
  >
176
- & ((key: K) => WritablePureSelectorToken<T>)
172
+ & ((key: K) => WritablePureSelectorToken<T>)
177
173
 
178
174
  // biome-ignore format: intersection
179
175
  export type WritableHeldSelectorFamily<T , K extends Canonical> =
@@ -183,13 +179,10 @@ export type WritableHeldSelectorFamily<T , K extends Canonical> =
183
179
  default: (key: K) => T,
184
180
  install: (store: Store) => void
185
181
  internalRoles: string[] | undefined
186
- subject: Subject<
187
- | StateCreationEvent<WritableHeldSelectorToken<T>>
188
- | StateDisposalEvent<WritableHeldSelectorToken<T>>
189
- >
182
+ subject: Subject<StateLifecycleEvent<WritableHeldSelectorToken<T>>>
190
183
  }
191
184
  >
192
- & ((key: K) => WritableHeldSelectorToken<T>)
185
+ & ((key: K) => WritableHeldSelectorToken<T>)
193
186
 
194
187
  // biome-ignore format: intersection
195
188
  export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
@@ -199,10 +192,7 @@ export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
199
192
  default: (key: K) => T,
200
193
  install: (store: Store) => void
201
194
  internalRoles: string[] | undefined
202
- subject: Subject<
203
- | StateCreationEvent<ReadonlyPureSelectorToken<T>>
204
- | StateDisposalEvent<ReadonlyPureSelectorToken<T>>
205
- >
195
+ subject: Subject<StateLifecycleEvent<ReadonlyPureSelectorToken<T>>>
206
196
  }
207
197
  >
208
198
  & ((key: K) => ReadonlyPureSelectorToken<T>)
@@ -215,10 +205,7 @@ export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
215
205
  default: (key: K) => T,
216
206
  install: (store: Store) => void
217
207
  internalRoles: string[] | undefined
218
- subject: Subject<
219
- | StateCreationEvent<ReadonlyHeldSelectorToken<T>>
220
- | StateDisposalEvent<ReadonlyHeldSelectorToken<T>>
221
- >
208
+ subject: Subject<StateLifecycleEvent<ReadonlyHeldSelectorToken<T>>>
222
209
  }
223
210
  >
224
211
  & ((key: K) => ReadonlyHeldSelectorToken<T>)
@@ -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
 
@@ -70,6 +65,7 @@ export function createMutableAtomFamily<
70
65
  }
71
66
 
72
67
  const atomFamily = Object.assign(familyFunction, familyToken, {
68
+ class: options.class,
73
69
  subject,
74
70
  install: (s: Store) => createMutableAtomFamily(s, options),
75
71
  internalRoles,
@@ -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`,