atom.io 0.36.3 → 0.37.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 (121) hide show
  1. package/dist/data/index.d.ts.map +1 -1
  2. package/dist/data/index.js.map +1 -1
  3. package/dist/eslint-plugin/index.js +1 -2
  4. package/dist/eslint-plugin/index.js.map +1 -1
  5. package/dist/internal/index.d.ts +71 -102
  6. package/dist/internal/index.d.ts.map +1 -1
  7. package/dist/internal/index.js +566 -515
  8. package/dist/internal/index.js.map +1 -1
  9. package/dist/introspection/index.d.ts +2 -2
  10. package/dist/introspection/index.d.ts.map +1 -1
  11. package/dist/introspection/index.js +1 -1
  12. package/dist/introspection/index.js.map +1 -1
  13. package/dist/json/index.d.ts +2 -1
  14. package/dist/json/index.d.ts.map +1 -1
  15. package/dist/json/index.js.map +1 -1
  16. package/dist/main/index.d.ts +154 -139
  17. package/dist/main/index.d.ts.map +1 -1
  18. package/dist/main/index.js.map +1 -1
  19. package/dist/react/index.d.ts.map +1 -1
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/react-devtools/index.d.ts.map +1 -1
  22. package/dist/react-devtools/index.js +54 -56
  23. package/dist/react-devtools/index.js.map +1 -1
  24. package/dist/realtime/index.d.ts.map +1 -1
  25. package/dist/realtime/index.js.map +1 -1
  26. package/dist/realtime-client/index.d.ts +3 -3
  27. package/dist/realtime-client/index.d.ts.map +1 -1
  28. package/dist/realtime-client/index.js +6 -6
  29. package/dist/realtime-client/index.js.map +1 -1
  30. package/dist/realtime-react/index.d.ts.map +1 -1
  31. package/dist/realtime-react/index.js.map +1 -1
  32. package/dist/realtime-server/index.d.ts +5 -5
  33. package/dist/realtime-server/index.d.ts.map +1 -1
  34. package/dist/realtime-server/index.js +10 -12
  35. package/dist/realtime-server/index.js.map +1 -1
  36. package/dist/realtime-testing/index.d.ts.map +1 -1
  37. package/dist/realtime-testing/index.js.map +1 -1
  38. package/dist/transceivers/set-rtx/index.d.ts +1 -1
  39. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  40. package/dist/transceivers/set-rtx/index.js +1 -3
  41. package/dist/transceivers/set-rtx/index.js.map +1 -1
  42. package/dist/use-o-DXPncKmZ.js.map +1 -1
  43. package/dist/web/index.d.ts +2 -2
  44. package/dist/web/index.d.ts.map +1 -1
  45. package/dist/web/index.js.map +1 -1
  46. package/package.json +6 -6
  47. package/src/internal/atom/dispose-atom.ts +16 -9
  48. package/src/internal/caching.ts +1 -1
  49. package/src/internal/families/create-readonly-held-selector-family.ts +3 -5
  50. package/src/internal/families/create-readonly-pure-selector-family.ts +3 -5
  51. package/src/internal/families/create-regular-atom-family.ts +7 -7
  52. package/src/internal/families/create-writable-held-selector-family.ts +3 -5
  53. package/src/internal/families/create-writable-pure-selector-family.ts +3 -5
  54. package/src/internal/families/find-in-store.ts +17 -34
  55. package/src/internal/families/init-family-member.ts +5 -87
  56. package/src/internal/families/mint-in-store.ts +74 -0
  57. package/src/internal/get-state/get-from-store.ts +19 -6
  58. package/src/internal/get-state/read-or-compute-value.ts +4 -2
  59. package/src/internal/index.ts +25 -36
  60. package/src/internal/ingest-updates/ingest-atom-update.ts +7 -7
  61. package/src/internal/ingest-updates/ingest-creation-disposal.ts +11 -11
  62. package/src/internal/ingest-updates/ingest-selector-update.ts +8 -4
  63. package/src/internal/ingest-updates/ingest-transaction-update.ts +5 -6
  64. package/src/internal/install-into-store.ts +2 -2
  65. package/src/internal/join/join-internal.ts +1 -1
  66. package/src/internal/molecule.ts +12 -9
  67. package/src/internal/mutable/create-mutable-atom-family.ts +4 -6
  68. package/src/internal/mutable/tracker.ts +2 -2
  69. package/src/internal/mutable/transceiver.ts +6 -4
  70. package/src/internal/operation.ts +17 -14
  71. package/src/internal/selector/create-readonly-held-selector.ts +9 -7
  72. package/src/internal/selector/create-readonly-pure-selector.ts +8 -5
  73. package/src/internal/selector/create-writable-held-selector.ts +12 -21
  74. package/src/internal/selector/create-writable-pure-selector.ts +15 -28
  75. package/src/internal/selector/dispose-selector.ts +6 -1
  76. package/src/internal/selector/get-selector-dependency-keys.ts +2 -6
  77. package/src/internal/selector/register-selector.ts +64 -74
  78. package/src/internal/selector/trace-selector-atoms.ts +2 -2
  79. package/src/internal/selector/update-selector-atoms.ts +2 -2
  80. package/src/internal/set-state/dispatch-state-update.ts +101 -0
  81. package/src/internal/set-state/operate-on-store.ts +126 -0
  82. package/src/internal/set-state/reset-atom-or-selector.ts +24 -15
  83. package/src/internal/set-state/set-atom-or-selector.ts +9 -4
  84. package/src/internal/set-state/set-atom.ts +4 -49
  85. package/src/internal/set-state/set-into-store.ts +11 -77
  86. package/src/internal/set-state/set-selector.ts +35 -0
  87. package/src/internal/store/store.ts +4 -4
  88. package/src/internal/subscribe/subscribe-in-store.ts +3 -3
  89. package/src/internal/subscribe/subscribe-to-timeline.ts +2 -2
  90. package/src/internal/timeline/create-timeline.ts +57 -101
  91. package/src/internal/timeline/time-travel.ts +1 -1
  92. package/src/internal/transaction/abort-transaction.ts +1 -1
  93. package/src/internal/transaction/apply-transaction.ts +7 -7
  94. package/src/internal/transaction/build-transaction.ts +10 -9
  95. package/src/internal/transaction/create-transaction.ts +4 -3
  96. package/src/internal/transaction/index.ts +6 -2
  97. package/src/introspection/attach-introspection-states.ts +2 -2
  98. package/src/introspection/attach-transaction-logs.ts +13 -6
  99. package/src/json/index.ts +3 -1
  100. package/src/main/atom.ts +2 -1
  101. package/src/main/events.ts +109 -0
  102. package/src/main/get-state.ts +1 -1
  103. package/src/main/index.ts +3 -0
  104. package/src/main/subscribe.ts +9 -19
  105. package/src/main/timeline.ts +3 -21
  106. package/src/main/transaction.ts +0 -65
  107. package/src/main/validators.ts +8 -2
  108. package/src/react-devtools/TimelineIndex.tsx +1 -1
  109. package/src/react-devtools/TransactionIndex.tsx +5 -3
  110. package/src/react-devtools/Updates.tsx +54 -46
  111. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +20 -10
  112. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +4 -4
  113. package/src/realtime-client/sync-continuity.ts +1 -1
  114. package/src/realtime-server/continuity/prepare-to-serve-transaction-request.ts +14 -8
  115. package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +5 -2
  116. package/src/realtime-server/continuity/subscribe-to-continuity-actions.ts +1 -1
  117. package/src/realtime-server/realtime-action-receiver.ts +6 -3
  118. package/src/realtime-server/realtime-server-stores/server-sync-store.ts +13 -16
  119. package/src/transceivers/set-rtx/set-rtx.ts +1 -3
  120. package/src/web/persist-sync.ts +2 -2
  121. package/src/internal/set-state/emit-update.ts +0 -40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.36.3",
3
+ "version": "0.37.1",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -72,9 +72,9 @@
72
72
  "@types/npmlog": "7.0.0",
73
73
  "@types/react": "19.1.10",
74
74
  "@types/tmp": "0.2.6",
75
- "@typescript-eslint/parser": "8.39.1",
76
- "@typescript-eslint/rule-tester": "8.39.1",
77
- "@typescript-eslint/utils": "8.39.1",
75
+ "@typescript-eslint/parser": "8.40.0",
76
+ "@typescript-eslint/rule-tester": "8.40.0",
77
+ "@typescript-eslint/utils": "8.40.0",
78
78
  "@vitest/coverage-v8": "3.2.4",
79
79
  "@vitest/ui": "3.2.4",
80
80
  "concurrently": "9.2.0",
@@ -87,7 +87,7 @@
87
87
  "npmlog": "7.0.1",
88
88
  "nyc": "17.1.0",
89
89
  "postgres": "3.4.7",
90
- "preact": "10.27.0",
90
+ "preact": "10.27.1",
91
91
  "react": "19.1.1",
92
92
  "react-dom": "19.1.1",
93
93
  "react-router-dom": "7.8.1",
@@ -99,7 +99,7 @@
99
99
  "tsdown": "0.14.1",
100
100
  "tsx": "4.20.4",
101
101
  "typescript": "5.9.2",
102
- "vite": "7.1.2",
102
+ "vite": "7.1.3",
103
103
  "vite-tsconfig-paths": "5.1.4",
104
104
  "vitest": "3.2.4",
105
105
  "zod": "3.25.76",
@@ -1,9 +1,10 @@
1
- import type { AtomDisposal, AtomToken } from "atom.io"
1
+ import type { AtomDisposalEvent, AtomToken, StateLifecycleEvent } from "atom.io"
2
2
 
3
- import type { Store } from ".."
3
+ import type { Store, Subject } from ".."
4
4
  import { getUpdateToken, isChildStore, newest, withdraw } from ".."
5
+ import { getFamilyOfToken } from "../families/get-family-of-token"
5
6
 
6
- export function disposeAtom(store: Store, atomToken: AtomToken<unknown>): void {
7
+ export function disposeAtom(store: Store, atomToken: AtomToken<any>): void {
7
8
  const target = newest(store)
8
9
  const { key, family } = atomToken
9
10
  const atom = withdraw(target, atomToken)
@@ -12,16 +13,22 @@ export function disposeAtom(store: Store, atomToken: AtomToken<unknown>): void {
12
13
  } else {
13
14
  atom.cleanup?.()
14
15
  const lastValue = store.valueMap.get(atom.key)
15
- const atomFamily = withdraw(store, { key: family.key, type: `atom_family` })
16
-
17
- const disposal: AtomDisposal<AtomToken<unknown>> = {
16
+ // biome-ignore lint/style/noNonNullAssertion: family has been verified
17
+ const familyToken = getFamilyOfToken(store, atomToken)!
18
+ const atomFamily = withdraw(store, familyToken)
19
+ const subject = atomFamily.subject as Subject<
20
+ StateLifecycleEvent<AtomToken<any>>
21
+ >
22
+
23
+ const disposal: AtomDisposalEvent<AtomToken<any>> = {
18
24
  type: `state_disposal`,
19
25
  subType: `atom`,
20
26
  token: atomToken,
21
27
  value: lastValue,
28
+ timestamp: Date.now(),
22
29
  }
23
30
 
24
- atomFamily.subject.next(disposal)
31
+ subject.next(disposal)
25
32
 
26
33
  const isChild = isChildStore(target)
27
34
 
@@ -39,14 +46,14 @@ export function disposeAtom(store: Store, atomToken: AtomToken<unknown>): void {
39
46
  }
40
47
  store.logger.info(`🔥`, `atom`, key, `deleted`)
41
48
  if (isChild && target.transactionMeta.phase === `building`) {
42
- const mostRecentUpdate = target.transactionMeta.update.updates.at(-1)
49
+ const mostRecentUpdate = target.transactionMeta.update.subEvents.at(-1)
43
50
  const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`
44
51
  const updateAlreadyCaptured =
45
52
  wasMoleculeDisposal &&
46
53
  mostRecentUpdate.values.some(([k]) => k === atom.family?.key)
47
54
 
48
55
  if (!updateAlreadyCaptured) {
49
- target.transactionMeta.update.updates.push(disposal)
56
+ target.transactionMeta.update.subEvents.push(disposal)
50
57
  }
51
58
  } else {
52
59
  store.on.atomDisposal.next(atomToken)
@@ -113,7 +113,7 @@ export function evictCachedValue(target: Store, key: string): void {
113
113
  const selector =
114
114
  target.writableSelectors.get(key) ?? target.readonlySelectors.get(key)
115
115
  if (selector) {
116
- selector.get()
116
+ selector.getFrom(target)
117
117
  }
118
118
  return
119
119
  }
@@ -3,8 +3,7 @@ import type {
3
3
  ReadonlyHeldSelectorFamilyOptions,
4
4
  ReadonlyHeldSelectorFamilyToken,
5
5
  ReadonlyHeldSelectorToken,
6
- StateCreation,
7
- StateDisposal,
6
+ StateLifecycleEvent,
8
7
  } from "atom.io"
9
8
  import type { Canonical } from "atom.io/json"
10
9
  import { stringifyJson } from "atom.io/json"
@@ -45,8 +44,7 @@ export function createReadonlyHeldSelectorFamily<
45
44
  }
46
45
 
47
46
  const subject = new Subject<
48
- | StateCreation<ReadonlyHeldSelectorToken<T>>
49
- | StateDisposal<ReadonlyHeldSelectorToken<T>>
47
+ StateLifecycleEvent<ReadonlyHeldSelectorToken<T>>
50
48
  >()
51
49
 
52
50
  const familyFunction = (key: K): ReadonlyHeldSelectorToken<T> => {
@@ -65,7 +63,7 @@ export function createReadonlyHeldSelectorFamily<
65
63
  family,
66
64
  )
67
65
 
68
- subject.next({ type: `state_creation`, token })
66
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
69
67
  return token
70
68
  }
71
69
 
@@ -5,8 +5,7 @@ import type {
5
5
  ReadonlyPureSelectorFamilyOptions,
6
6
  ReadonlyPureSelectorFamilyToken,
7
7
  ReadonlyPureSelectorToken,
8
- StateCreation,
9
- StateDisposal,
8
+ StateLifecycleEvent,
10
9
  } from "atom.io"
11
10
  import type { Canonical } from "atom.io/json"
12
11
  import { stringifyJson } from "atom.io/json"
@@ -49,8 +48,7 @@ export function createReadonlyPureSelectorFamily<T, K extends Canonical>(
49
48
  }
50
49
 
51
50
  const subject = new Subject<
52
- | StateCreation<ReadonlyPureSelectorToken<T>>
53
- | StateDisposal<ReadonlyPureSelectorToken<T>>
51
+ StateLifecycleEvent<ReadonlyPureSelectorToken<T>>
54
52
  >()
55
53
 
56
54
  const familyFunction = (key: K): ReadonlyPureSelectorToken<T> => {
@@ -68,7 +66,7 @@ export function createReadonlyPureSelectorFamily<T, K extends Canonical>(
68
66
  family,
69
67
  )
70
68
 
71
- subject.next({ type: `state_creation`, token })
69
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
72
70
  return token
73
71
  }
74
72
 
@@ -4,8 +4,7 @@ import type {
4
4
  RegularAtomFamilyToken,
5
5
  RegularAtomOptions,
6
6
  RegularAtomToken,
7
- StateCreation,
8
- StateDisposal,
7
+ StateLifecycleEvent,
9
8
  } from "atom.io"
10
9
  import type { Canonical } from "atom.io/json"
11
10
  import { stringifyJson } from "atom.io/json"
@@ -38,9 +37,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
38
37
  )
39
38
  }
40
39
 
41
- const subject = new Subject<
42
- StateCreation<RegularAtomToken<T>> | StateDisposal<RegularAtomToken<T>>
43
- >()
40
+ const subject = new Subject<StateLifecycleEvent<RegularAtomToken<T>>>()
44
41
 
45
42
  const familyFunction = (key: K): RegularAtomToken<any> => {
46
43
  const subKey = stringifyJson(key)
@@ -59,17 +56,20 @@ export function createRegularAtomFamily<T, K extends Canonical>(
59
56
 
60
57
  const token = createRegularAtom(target, individualOptions, family)
61
58
 
62
- subject.next({ type: `state_creation`, token })
59
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
63
60
  return token
64
61
  }
65
62
 
66
63
  const atomFamily = Object.assign(familyFunction, familyToken, {
64
+ default: options.default,
67
65
  subject,
68
66
  install: (s: Store) => createRegularAtomFamily(s, options),
69
67
  internalRoles,
70
68
  }) satisfies RegularAtomFamily<T, K>
71
69
 
72
70
  store.families.set(options.key, atomFamily)
73
- store.defaults.set(options.key, options.default)
71
+ if (options.default instanceof Function === false) {
72
+ store.defaults.set(options.key, options.default)
73
+ }
74
74
  return familyToken
75
75
  }
@@ -1,7 +1,6 @@
1
1
  import type {
2
2
  FamilyMetadata,
3
- StateCreation,
4
- StateDisposal,
3
+ StateLifecycleEvent,
5
4
  WritableHeldSelectorFamilyOptions,
6
5
  WritableHeldSelectorFamilyToken,
7
6
  WritableHeldSelectorToken,
@@ -43,8 +42,7 @@ export function createWritableHeldSelectorFamily<
43
42
  )
44
43
  }
45
44
  const subject = new Subject<
46
- | StateCreation<WritableHeldSelectorToken<T>>
47
- | StateDisposal<WritableHeldSelectorToken<T>>
45
+ StateLifecycleEvent<WritableHeldSelectorToken<T>>
48
46
  >()
49
47
 
50
48
  const familyFunction = (key: K): WritableHeldSelectorToken<T> => {
@@ -64,7 +62,7 @@ export function createWritableHeldSelectorFamily<
64
62
  family,
65
63
  )
66
64
 
67
- subject.next({ type: `state_creation`, token })
65
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
68
66
  return token
69
67
  }
70
68
 
@@ -2,8 +2,7 @@ import type {
2
2
  FamilyMetadata,
3
3
  findState,
4
4
  getState,
5
- StateCreation,
6
- StateDisposal,
5
+ StateLifecycleEvent,
7
6
  WritablePureSelectorFamilyOptions,
8
7
  WritablePureSelectorFamilyToken,
9
8
  WritablePureSelectorToken,
@@ -48,8 +47,7 @@ export function createWritablePureSelectorFamily<T, K extends Canonical>(
48
47
  )
49
48
  }
50
49
  const subject = new Subject<
51
- | StateCreation<WritablePureSelectorToken<T>>
52
- | StateDisposal<WritablePureSelectorToken<T>>
50
+ StateLifecycleEvent<WritablePureSelectorToken<T>>
53
51
  >()
54
52
 
55
53
  const familyFunction = (key: K): WritablePureSelectorToken<T> => {
@@ -68,7 +66,7 @@ export function createWritablePureSelectorFamily<T, K extends Canonical>(
68
66
  family,
69
67
  )
70
68
 
71
- subject.next({ type: `state_creation`, token })
69
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
72
70
  return token
73
71
  }
74
72
 
@@ -16,12 +16,11 @@ import type {
16
16
  WritablePureSelectorToken,
17
17
  WritableToken,
18
18
  } from "atom.io"
19
- import { type Canonical, stringifyJson } from "atom.io/json"
19
+ import type { Canonical } from "atom.io/json"
20
20
 
21
- import { newest } from "../lineage"
22
21
  import type { Transceiver } from "../mutable"
23
- import { counterfeit, type Store } from "../store"
24
- import { initFamilyMemberInStore } from "./init-family-member"
22
+ import type { Store } from "../store"
23
+ import { mintInStore } from "./mint-in-store"
25
24
  import { seekInStore } from "./seek-in-store"
26
25
 
27
26
  export function findInStore<
@@ -30,77 +29,61 @@ export function findInStore<
30
29
  Key extends K,
31
30
  >(
32
31
  store: Store,
33
- token: MutableAtomFamilyToken<T, K>,
32
+ familyToken: MutableAtomFamilyToken<T, K>,
34
33
  key: Key,
35
34
  ): MutableAtomToken<T, K>
36
35
 
37
36
  export function findInStore<T, K extends Canonical, Key extends K>(
38
37
  store: Store,
39
- token: RegularAtomFamilyToken<T, K>,
38
+ familyToken: RegularAtomFamilyToken<T, K>,
40
39
  key: Key,
41
40
  ): RegularAtomToken<T, K>
42
41
 
43
42
  export function findInStore<T, K extends Canonical, Key extends K>(
44
43
  store: Store,
45
- token: AtomFamilyToken<T, K>,
44
+ familyToken: AtomFamilyToken<T, K>,
46
45
  key: Key,
47
46
  ): AtomToken<T, K>
48
47
 
49
48
  export function findInStore<T, K extends Canonical, Key extends K>(
50
49
  store: Store,
51
- token: WritablePureSelectorFamilyToken<T, K>,
50
+ familyToken: WritablePureSelectorFamilyToken<T, K>,
52
51
  key: Key,
53
52
  ): WritablePureSelectorToken<T, K>
54
53
 
55
54
  export function findInStore<T, K extends Canonical, Key extends K>(
56
55
  store: Store,
57
- token: ReadonlyPureSelectorFamilyToken<T, K>,
56
+ familyToken: ReadonlyPureSelectorFamilyToken<T, K>,
58
57
  key: Key,
59
58
  ): ReadonlyPureSelectorToken<T, K>
60
59
 
61
60
  export function findInStore<T, K extends Canonical, Key extends K>(
62
61
  store: Store,
63
- token: SelectorFamilyToken<T, K>,
62
+ familyToken: SelectorFamilyToken<T, K>,
64
63
  key: Key,
65
64
  ): SelectorToken<T, K>
66
65
 
67
66
  export function findInStore<T, K extends Canonical, Key extends K>(
68
67
  store: Store,
69
- token: WritableFamilyToken<T, K>,
68
+ familyToken: WritableFamilyToken<T, K>,
70
69
  key: Key,
71
70
  ): WritableToken<T, K>
72
71
 
73
72
  export function findInStore<T, K extends Canonical, Key extends K>(
74
73
  store: Store,
75
- token: ReadableFamilyToken<T, K>,
74
+ familyToken: ReadableFamilyToken<T, K>,
76
75
  key: Key,
77
76
  ): ReadableToken<T, K>
78
77
 
79
78
  export function findInStore(
80
79
  store: Store,
81
- token: ReadableFamilyToken<any, any>,
80
+ familyToken: ReadableFamilyToken<any, any>,
82
81
  key: Canonical,
83
82
  ): ReadableToken<any> {
84
- let state = seekInStore(store, token, key)
85
- if (state) {
86
- return state
83
+ const existingStateToken = seekInStore(store, familyToken, key)
84
+ if (existingStateToken) {
85
+ return existingStateToken
87
86
  }
88
- const stringKey = stringifyJson(key)
89
- const molecule = store.molecules.get(stringKey)
90
- if (!molecule && store.config.lifespan === `immortal`) {
91
- const fakeToken = counterfeit(token, key)
92
- store.logger.error(
93
- `❌`,
94
- fakeToken.type,
95
- fakeToken.key,
96
- `was not found in store "${store.config.name}"; returned a counterfeit token.`,
97
- )
98
- return fakeToken
99
- }
100
- state = initFamilyMemberInStore(store, token, key)
101
- if (molecule) {
102
- const target = newest(store)
103
- target.moleculeData.set(stringKey, token.key)
104
- }
105
- return state
87
+ const newStateToken = mintInStore(store, familyToken, key)
88
+ return newStateToken
106
89
  }
@@ -1,68 +1,13 @@
1
1
  import type {
2
- AtomFamilyToken,
3
- AtomToken,
4
- MutableAtomFamilyToken,
5
- MutableAtomToken,
6
2
  ReadableFamilyToken,
7
3
  ReadableToken,
8
- ReadonlyPureSelectorFamilyToken,
9
- ReadonlyPureSelectorToken,
10
- RegularAtomFamilyToken,
11
- RegularAtomToken,
12
- SelectorFamilyToken,
13
- SelectorToken,
14
4
  WritableFamilyToken,
15
- WritablePureSelectorFamilyToken,
16
- WritablePureSelectorToken,
17
5
  WritableToken,
18
6
  } from "atom.io"
19
- import type { Canonical, Json } from "atom.io/json"
7
+ import type { Canonical } from "atom.io/json"
20
8
 
21
- import { newest } from "../lineage"
22
- import type { Transceiver } from "../mutable"
23
- import { NotFoundError } from "../not-found-error"
24
9
  import type { Store } from "../store"
25
- import { isChildStore, isRootStore } from "../transaction"
26
-
27
- export function initFamilyMemberInStore<
28
- T extends Transceiver<any, any, any>,
29
- K extends Canonical,
30
- Key extends K,
31
- >(
32
- store: Store,
33
- token: MutableAtomFamilyToken<T, K>,
34
- key: Key,
35
- ): MutableAtomToken<T, K>
36
-
37
- export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
38
- store: Store,
39
- token: RegularAtomFamilyToken<T, K>,
40
- key: Key,
41
- ): RegularAtomToken<T, K>
42
-
43
- export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
44
- store: Store,
45
- token: AtomFamilyToken<T, K>,
46
- key: Key,
47
- ): AtomToken<T, K>
48
-
49
- export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
50
- store: Store,
51
- token: WritablePureSelectorFamilyToken<T, K>,
52
- key: Key,
53
- ): WritablePureSelectorToken<T, K>
54
-
55
- export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
56
- store: Store,
57
- token: ReadonlyPureSelectorFamilyToken<T, K>,
58
- key: Key,
59
- ): ReadonlyPureSelectorToken<T, K>
60
-
61
- export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
62
- store: Store,
63
- token: SelectorFamilyToken<T, K>,
64
- key: Key,
65
- ): SelectorToken<T, K>
10
+ import { withdraw } from "../store"
66
11
 
67
12
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
68
13
  store: Store,
@@ -79,37 +24,10 @@ export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
79
24
  export function initFamilyMemberInStore(
80
25
  store: Store,
81
26
  token: ReadableFamilyToken<any, any>,
82
- key: Json.Serializable,
27
+ key: Canonical,
83
28
  ): ReadableToken<any> {
84
- const family = store.families.get(token.key)
85
- if (family === undefined) {
86
- throw new NotFoundError(token, store)
87
- }
29
+ const family = withdraw(store, token)
88
30
  const state = family(key)
89
- const target = newest(store)
90
- if (state.family) {
91
- if (isRootStore(target)) {
92
- switch (state.type) {
93
- case `atom`:
94
- case `mutable_atom`:
95
- store.on.atomCreation.next(state)
96
- break
97
- case `writable_pure_selector`:
98
- case `readonly_pure_selector`:
99
- case `writable_held_selector`:
100
- case `readonly_held_selector`:
101
- store.on.selectorCreation.next(state)
102
- break
103
- }
104
- } else if (
105
- isChildStore(target) &&
106
- target.on.transactionApplying.state === null
107
- ) {
108
- target.transactionMeta.update.updates.push({
109
- type: `state_creation`,
110
- token: state,
111
- })
112
- }
113
- }
31
+
114
32
  return state
115
33
  }
@@ -0,0 +1,74 @@
1
+ import type {
2
+ ReadableFamilyToken,
3
+ ReadableToken,
4
+ WritableFamilyToken,
5
+ WritableToken,
6
+ } from "atom.io"
7
+ import type { Canonical } from "atom.io/json"
8
+ import { stringifyJson } from "atom.io/json"
9
+
10
+ import { newest } from "../lineage"
11
+ import type { Store } from "../store"
12
+ import { counterfeit } from "../store"
13
+ import { isChildStore, isRootStore } from "../transaction"
14
+ import { initFamilyMemberInStore } from "./init-family-member"
15
+
16
+ export function mintInStore<T, K extends Canonical, Key extends K>(
17
+ store: Store,
18
+ familyToken: WritableFamilyToken<T, K>,
19
+ key: Key,
20
+ ): WritableToken<T, K>
21
+ export function mintInStore<T, K extends Canonical, Key extends K>(
22
+ store: Store,
23
+ familyToken: ReadableFamilyToken<T, K>,
24
+ key: Key,
25
+ ): ReadableToken<T, K>
26
+ export function mintInStore<T, K extends Canonical, Key extends K>(
27
+ store: Store,
28
+ familyToken: ReadableFamilyToken<T, K>,
29
+ key: Key,
30
+ ): ReadableToken<T, K> {
31
+ const stringKey = stringifyJson(key)
32
+ const molecule = store.molecules.get(stringKey)
33
+ 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.`,
40
+ )
41
+ return fakeToken
42
+ }
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
58
+ }
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
+ }
69
+ }
70
+ if (molecule) {
71
+ target.moleculeData.set(stringKey, familyToken.key)
72
+ }
73
+ return newStateToken
74
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ReadableFamilyToken, ReadableToken } from "atom.io"
2
- import type { Canonical } from "atom.io/json"
2
+ import { type Canonical, parseJson } from "atom.io/json"
3
3
 
4
4
  import { findInStore } from "../families"
5
5
  import type { Store } from "../store"
@@ -47,9 +47,23 @@ export function getFromStore(
47
47
  : `No previous disposal trace was found.`,
48
48
  )
49
49
  switch (family.type) {
50
- case `atom_family`:
51
- case `mutable_atom_family`:
52
- return store.defaults.get(family.key)
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
+ }
53
67
  case `readonly_pure_selector_family`:
54
68
  case `writable_pure_selector_family`:
55
69
  case `readonly_held_selector_family`:
@@ -57,8 +71,7 @@ export function getFromStore(
57
71
  if (store.defaults.has(family.key)) {
58
72
  return store.defaults.get(token.family.key)
59
73
  }
60
- 3
61
- const defaultValue = withdraw(store, family).default(subKey)
74
+ const defaultValue = withdraw(store, family).default(parseJson(subKey))
62
75
  store.defaults.set(family.key, defaultValue)
63
76
  return defaultValue
64
77
  }
@@ -1,4 +1,6 @@
1
- import type { ReadableState, ViewOf } from ".."
1
+ import type { ViewOf } from "atom.io"
2
+
3
+ import type { ReadableState } from ".."
2
4
  import { readFromCache, writeToCache } from "../caching"
3
5
  import type { Store } from "../store"
4
6
 
@@ -27,7 +29,7 @@ export function readOrComputeValue<T>(
27
29
  case `writable_held_selector`:
28
30
  case `writable_pure_selector`:
29
31
  target.logger.info(`🧮`, state.type, key, `computing value`)
30
- return state.get()
32
+ return state.getFrom(target)
31
33
  case `atom`: {
32
34
  let def: T
33
35
  if (state.default instanceof Function) {