atom.io 0.36.2 → 0.37.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 (120) 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 +66 -98
  6. package/dist/internal/index.d.ts.map +1 -1
  7. package/dist/internal/index.js +544 -507
  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 +14 -14
  47. package/src/internal/atom/dispose-atom.ts +5 -4
  48. package/src/internal/caching.ts +3 -3
  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 +3 -6
  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/read-or-compute-value.ts +4 -2
  58. package/src/internal/index.ts +19 -18
  59. package/src/internal/ingest-updates/ingest-atom-update.ts +7 -7
  60. package/src/internal/ingest-updates/ingest-creation-disposal.ts +11 -11
  61. package/src/internal/ingest-updates/ingest-selector-update.ts +8 -4
  62. package/src/internal/ingest-updates/ingest-transaction-update.ts +5 -6
  63. package/src/internal/install-into-store.ts +2 -2
  64. package/src/internal/join/join-internal.ts +1 -1
  65. package/src/internal/molecule.ts +12 -9
  66. package/src/internal/mutable/create-mutable-atom-family.ts +3 -6
  67. package/src/internal/mutable/tracker.ts +2 -2
  68. package/src/internal/mutable/transceiver.ts +6 -4
  69. package/src/internal/operation.ts +17 -14
  70. package/src/internal/selector/create-readonly-held-selector.ts +9 -7
  71. package/src/internal/selector/create-readonly-pure-selector.ts +8 -5
  72. package/src/internal/selector/create-writable-held-selector.ts +12 -21
  73. package/src/internal/selector/create-writable-pure-selector.ts +16 -29
  74. package/src/internal/selector/dispose-selector.ts +6 -1
  75. package/src/internal/selector/get-selector-dependency-keys.ts +2 -6
  76. package/src/internal/selector/register-selector.ts +64 -74
  77. package/src/internal/selector/trace-selector-atoms.ts +2 -2
  78. package/src/internal/selector/update-selector-atoms.ts +2 -2
  79. package/src/internal/set-state/dispatch-state-update.ts +101 -0
  80. package/src/internal/set-state/operate-on-store.ts +126 -0
  81. package/src/internal/set-state/reset-atom-or-selector.ts +24 -15
  82. package/src/internal/set-state/set-atom-or-selector.ts +9 -4
  83. package/src/internal/set-state/set-atom.ts +4 -49
  84. package/src/internal/set-state/set-into-store.ts +11 -77
  85. package/src/internal/set-state/set-selector.ts +35 -0
  86. package/src/internal/store/store.ts +4 -4
  87. package/src/internal/subscribe/subscribe-in-store.ts +3 -3
  88. package/src/internal/subscribe/subscribe-to-timeline.ts +2 -2
  89. package/src/internal/timeline/create-timeline.ts +57 -101
  90. package/src/internal/timeline/time-travel.ts +1 -1
  91. package/src/internal/transaction/abort-transaction.ts +1 -1
  92. package/src/internal/transaction/apply-transaction.ts +7 -7
  93. package/src/internal/transaction/build-transaction.ts +10 -9
  94. package/src/internal/transaction/create-transaction.ts +4 -3
  95. package/src/internal/transaction/index.ts +6 -2
  96. package/src/introspection/attach-introspection-states.ts +2 -2
  97. package/src/introspection/attach-transaction-logs.ts +13 -6
  98. package/src/json/index.ts +3 -1
  99. package/src/main/atom.ts +2 -1
  100. package/src/main/events.ts +109 -0
  101. package/src/main/get-state.ts +1 -1
  102. package/src/main/index.ts +3 -0
  103. package/src/main/subscribe.ts +9 -19
  104. package/src/main/timeline.ts +3 -21
  105. package/src/main/transaction.ts +0 -65
  106. package/src/main/validators.ts +8 -2
  107. package/src/react-devtools/TimelineIndex.tsx +1 -1
  108. package/src/react-devtools/TransactionIndex.tsx +5 -3
  109. package/src/react-devtools/Updates.tsx +54 -46
  110. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +20 -10
  111. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +4 -4
  112. package/src/realtime-client/sync-continuity.ts +1 -1
  113. package/src/realtime-server/continuity/prepare-to-serve-transaction-request.ts +14 -8
  114. package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +5 -2
  115. package/src/realtime-server/continuity/subscribe-to-continuity-actions.ts +1 -1
  116. package/src/realtime-server/realtime-action-receiver.ts +6 -3
  117. package/src/realtime-server/realtime-server-stores/server-sync-store.ts +13 -16
  118. package/src/transceivers/set-rtx/set-rtx.ts +1 -3
  119. package/src/web/persist-sync.ts +2 -2
  120. 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.2",
3
+ "version": "0.37.0",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -61,20 +61,20 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@eslint/core": "0.15.2",
64
- "@storybook/addon-docs": "9.1.1",
65
- "@storybook/addon-onboarding": "9.1.1",
66
- "@storybook/react-vite": "9.1.1",
64
+ "@storybook/addon-docs": "9.1.2",
65
+ "@storybook/addon-onboarding": "9.1.2",
66
+ "@storybook/react-vite": "9.1.2",
67
67
  "@testing-library/react": "16.3.0",
68
68
  "@types/bun": "npm:bun-types@1.2.20",
69
69
  "@types/eslint": "9.6.1",
70
70
  "@types/estree": "1.0.8",
71
71
  "@types/http-proxy": "1.17.16",
72
72
  "@types/npmlog": "7.0.0",
73
- "@types/react": "19.1.9",
73
+ "@types/react": "19.1.10",
74
74
  "@types/tmp": "0.2.6",
75
- "@typescript-eslint/parser": "8.39.0",
76
- "@typescript-eslint/rule-tester": "8.39.0",
77
- "@typescript-eslint/utils": "8.39.0",
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,19 +87,19 @@
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
- "react-router-dom": "7.8.0",
93
+ "react-router-dom": "7.8.1",
94
94
  "recoverage": "0.1.11",
95
95
  "socket.io": "4.8.1",
96
96
  "socket.io-client": "4.8.1",
97
- "storybook": "9.1.1",
97
+ "storybook": "9.1.2",
98
98
  "tmp": "0.2.5",
99
- "tsdown": "0.14.0",
100
- "tsx": "4.20.3",
99
+ "tsdown": "0.14.1",
100
+ "tsx": "4.20.4",
101
101
  "typescript": "5.9.2",
102
- "vite": "7.1.1",
102
+ "vite": "7.1.2",
103
103
  "vite-tsconfig-paths": "5.1.4",
104
104
  "vitest": "3.2.4",
105
105
  "zod": "3.25.76",
@@ -1,4 +1,4 @@
1
- import type { AtomDisposal, AtomToken } from "atom.io"
1
+ import type { AtomDisposalEvent, AtomToken } from "atom.io"
2
2
 
3
3
  import type { Store } from ".."
4
4
  import { getUpdateToken, isChildStore, newest, withdraw } from ".."
@@ -14,11 +14,12 @@ export function disposeAtom(store: Store, atomToken: AtomToken<unknown>): void {
14
14
  const lastValue = store.valueMap.get(atom.key)
15
15
  const atomFamily = withdraw(store, { key: family.key, type: `atom_family` })
16
16
 
17
- const disposal: AtomDisposal<AtomToken<unknown>> = {
17
+ const disposal: AtomDisposalEvent<AtomToken<unknown>> = {
18
18
  type: `state_disposal`,
19
19
  subType: `atom`,
20
20
  token: atomToken,
21
21
  value: lastValue,
22
+ timestamp: Date.now(),
22
23
  }
23
24
 
24
25
  atomFamily.subject.next(disposal)
@@ -39,14 +40,14 @@ export function disposeAtom(store: Store, atomToken: AtomToken<unknown>): void {
39
40
  }
40
41
  store.logger.info(`🔥`, `atom`, key, `deleted`)
41
42
  if (isChild && target.transactionMeta.phase === `building`) {
42
- const mostRecentUpdate = target.transactionMeta.update.updates.at(-1)
43
+ const mostRecentUpdate = target.transactionMeta.update.subEvents.at(-1)
43
44
  const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`
44
45
  const updateAlreadyCaptured =
45
46
  wasMoleculeDisposal &&
46
47
  mostRecentUpdate.values.some(([k]) => k === atom.family?.key)
47
48
 
48
49
  if (!updateAlreadyCaptured) {
49
- target.transactionMeta.update.updates.push(disposal)
50
+ target.transactionMeta.update.subEvents.push(disposal)
50
51
  }
51
52
  } else {
52
53
  store.on.atomDisposal.next(atomToken)
@@ -45,17 +45,17 @@ export function writeToCache<T>(
45
45
  if (current === future) {
46
46
  openOperation(target, state)
47
47
  writeToCache(target, state, resolved)
48
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
48
49
  switch (type) {
49
50
  case `atom`:
50
51
  case `mutable_atom`:
51
52
  evictDownstreamFromAtom(target, state)
52
53
  break
53
- case `readonly_held_selector`:
54
54
  case `readonly_pure_selector`:
55
- case `writable_held_selector`:
56
55
  case `writable_pure_selector`:
57
56
  evictDownstreamFromSelector(target, key)
58
57
  break
58
+ // held selectors, by definitions, don't become promises
59
59
  }
60
60
  closeOperation(target)
61
61
  subject.next({ newValue: resolved, oldValue: future })
@@ -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,7 +56,7 @@ 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
 
@@ -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,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) {