atom.io 0.22.0 → 0.23.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 (79) hide show
  1. package/data/dist/index.cjs +17 -1
  2. package/data/dist/index.js +1 -1
  3. package/data/src/join.ts +30 -1
  4. package/dist/chunk-6MLFYN32.js +18 -0
  5. package/dist/{chunk-JA4V7TJY.js → chunk-7DT3PVS3.js} +18 -2
  6. package/dist/chunk-OAYGID5B.js +27 -0
  7. package/dist/index.cjs +2 -11
  8. package/dist/index.d.ts +51 -23
  9. package/dist/index.js +2 -11
  10. package/eslint-plugin/dist/index.cjs +0 -1
  11. package/eslint-plugin/dist/index.js +0 -1
  12. package/eslint-plugin/src/rules/lifespan.ts +0 -1
  13. package/immortal/dist/index.cjs +180 -20
  14. package/immortal/dist/index.js +134 -19
  15. package/immortal/src/index.ts +1 -0
  16. package/immortal/src/make-molecule.ts +222 -0
  17. package/immortal/src/molecule.ts +49 -16
  18. package/immortal/src/seek-state.ts +15 -2
  19. package/internal/dist/index.cjs +1119 -754
  20. package/internal/dist/index.d.ts +109 -12
  21. package/internal/dist/index.js +1098 -760
  22. package/internal/src/atom/create-regular-atom.ts +0 -2
  23. package/internal/src/atom/create-standalone-atom.ts +6 -2
  24. package/internal/src/atom/dispose-atom.ts +22 -2
  25. package/internal/src/families/create-readonly-selector-family.ts +7 -2
  26. package/internal/src/families/create-regular-atom-family.ts +6 -2
  27. package/internal/src/families/create-writable-selector-family.ts +7 -2
  28. package/internal/src/families/dispose-from-store.ts +22 -0
  29. package/internal/src/families/find-in-store.ts +0 -1
  30. package/internal/src/families/index.ts +1 -0
  31. package/internal/src/families/init-family-member.ts +22 -1
  32. package/internal/src/families/seek-in-store.ts +23 -6
  33. package/internal/src/ingest-updates/index.ts +1 -0
  34. package/internal/src/ingest-updates/ingest-creation-disposal.ts +104 -0
  35. package/internal/src/ingest-updates/ingest-transaction-update.ts +26 -4
  36. package/internal/src/mutable/create-mutable-atom-family.ts +6 -2
  37. package/internal/src/mutable/create-mutable-atom.ts +0 -2
  38. package/internal/src/mutable/get-json-token.ts +0 -1
  39. package/internal/src/mutable/tracker-family.ts +7 -7
  40. package/internal/src/not-found-error.ts +5 -0
  41. package/internal/src/selector/create-readonly-selector.ts +2 -3
  42. package/internal/src/selector/create-standalone-selector.ts +6 -2
  43. package/internal/src/selector/create-writable-selector.ts +2 -3
  44. package/internal/src/selector/dispose-selector.ts +32 -5
  45. package/internal/src/selector/register-selector.ts +2 -0
  46. package/internal/src/set-state/stow-update.ts +5 -1
  47. package/internal/src/store/deposit.ts +41 -7
  48. package/internal/src/store/store.ts +11 -0
  49. package/internal/src/store/withdraw.ts +28 -1
  50. package/internal/src/timeline/add-atom-to-timeline.ts +206 -182
  51. package/internal/src/timeline/create-timeline.ts +181 -60
  52. package/internal/src/timeline/time-travel.ts +20 -0
  53. package/internal/src/transaction/apply-transaction.ts +2 -12
  54. package/internal/src/transaction/build-transaction.ts +11 -2
  55. package/introspection/dist/index.cjs +2 -1
  56. package/introspection/dist/index.js +2 -1
  57. package/introspection/src/attach-timeline-family.ts +1 -0
  58. package/json/dist/index.cjs +3 -3
  59. package/json/dist/index.js +6 -5
  60. package/json/src/select-json-family.ts +3 -4
  61. package/package.json +5 -5
  62. package/react-devtools/dist/index.cjs +58 -47
  63. package/react-devtools/dist/index.js +60 -48
  64. package/react-devtools/src/TimelineIndex.tsx +15 -13
  65. package/react-devtools/src/Updates.tsx +41 -32
  66. package/realtime-server/dist/index.cjs +21 -10
  67. package/realtime-server/dist/index.d.ts +1 -1
  68. package/realtime-server/dist/index.js +21 -11
  69. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +21 -11
  70. package/realtime-testing/dist/index.cjs +1 -0
  71. package/realtime-testing/dist/index.js +1 -1
  72. package/src/atom.ts +9 -3
  73. package/src/dispose-state.ts +3 -12
  74. package/src/index.ts +4 -0
  75. package/src/selector.ts +3 -3
  76. package/src/subscribe.ts +8 -4
  77. package/src/timeline.ts +18 -1
  78. package/src/transaction.ts +56 -4
  79. package/dist/chunk-BF4MVQF6.js +0 -44
@@ -1,7 +1,13 @@
1
1
  import type {
2
2
  AtomFamilyToken,
3
3
  FamilyMetadata,
4
+ Flat,
4
5
  Func,
6
+ MoleculeCreation,
7
+ MoleculeDisposal,
8
+ ReadableToken,
9
+ StateCreation,
10
+ StateDisposal,
5
11
  StateUpdate,
6
12
  TimelineManageable,
7
13
  TimelineOptions,
@@ -10,6 +16,7 @@ import type {
10
16
  TokenType,
11
17
  TransactionUpdate,
12
18
  } from "atom.io"
19
+ import { type Json, stringifyJson } from "atom.io/json"
13
20
 
14
21
  import { newest } from "../lineage"
15
22
  import { getUpdateToken, isMutable } from "../mutable"
@@ -17,31 +24,46 @@ import { type Store, withdraw } from "../store"
17
24
  import { Subject } from "../subject"
18
25
  import { addAtomToTimeline } from "./add-atom-to-timeline"
19
26
 
20
- export type TimelineAtomUpdate<ManagedAtom extends TimelineManageable> =
27
+ export type TimelineAtomUpdate<ManagedAtom extends TimelineManageable> = Flat<
21
28
  StateUpdate<TokenType<ManagedAtom>> & {
22
29
  key: string
23
30
  type: `atom_update`
24
31
  timestamp: number
25
32
  family?: FamilyMetadata
26
33
  }
34
+ >
27
35
  export type TimelineSelectorUpdate<ManagedAtom extends TimelineManageable> = {
28
36
  key: string
29
37
  type: `selector_update`
30
38
  timestamp: number
31
39
  atomUpdates: Omit<TimelineAtomUpdate<ManagedAtom>, `timestamp`>[]
32
40
  }
33
- export type TimelineTransactionUpdate = TransactionUpdate<Func> & {
34
- key: string
35
- type: `transaction_update`
36
- timestamp: number
37
- }
41
+ export type TimelineTransactionUpdate = Flat<
42
+ TransactionUpdate<Func> & {
43
+ key: string
44
+ type: `transaction_update`
45
+ timestamp: number
46
+ }
47
+ >
48
+ export type TimelineStateCreation<T extends ReadableToken<any>> = Flat<
49
+ StateCreation<T> & { timestamp: number }
50
+ >
51
+ export type TimelineStateDisposal<T extends ReadableToken<any>> = Flat<
52
+ StateDisposal<T> & { timestamp: number }
53
+ >
54
+ export type TimelineMoleculeCreation<Key extends Json.Serializable> = Flat<
55
+ MoleculeCreation<Key> & { timestamp: number }
56
+ >
57
+ export type TimelineMoleculeDisposal<Key extends Json.Serializable> = Flat<
58
+ MoleculeDisposal<Key> & { timestamp: number }
59
+ >
38
60
 
39
61
  export type Timeline<ManagedAtom extends TimelineManageable> = {
40
62
  type: `timeline`
41
63
  key: string
42
64
  at: number
43
65
  shouldCapture?: (
44
- update: TimelineUpdate<TimelineManageable>,
66
+ update: TimelineUpdate<ManagedAtom>,
45
67
  timeline: Timeline<ManagedAtom>,
46
68
  ) => boolean
47
69
  timeTraveling: `into_future` | `into_past` | null
@@ -49,13 +71,8 @@ export type Timeline<ManagedAtom extends TimelineManageable> = {
49
71
  selectorTime: number | null
50
72
  transactionKey: string | null
51
73
  install: (store: Store) => void
52
- subject: Subject<
53
- | TimelineAtomUpdate<ManagedAtom>
54
- | TimelineSelectorUpdate<ManagedAtom>
55
- | TimelineTransactionUpdate
56
- | `redo`
57
- | `undo`
58
- >
74
+ subject: Subject<TimelineUpdate<ManagedAtom> | `redo` | `undo`>
75
+ subscriptions: Map<string, () => void>
59
76
  }
60
77
 
61
78
  export function createTimeline<ManagedAtom extends TimelineManageable>(
@@ -67,6 +84,7 @@ export function createTimeline<ManagedAtom extends TimelineManageable>(
67
84
  type: `timeline`,
68
85
  key: options.key,
69
86
  at: 0,
87
+
70
88
  timeTraveling: null,
71
89
  selectorTime: null,
72
90
  transactionKey: null,
@@ -74,62 +92,140 @@ export function createTimeline<ManagedAtom extends TimelineManageable>(
74
92
  history: data?.history.map((update) => ({ ...update })) ?? [],
75
93
  install: (s) => createTimeline(options, s, tl),
76
94
  subject: new Subject(),
95
+ subscriptions: new Map(),
77
96
  }
78
97
  if (options.shouldCapture) {
79
98
  tl.shouldCapture = options.shouldCapture
80
99
  }
81
100
  const timelineKey = options.key
82
101
  const target = newest(store)
83
- for (const tokenOrFamily of options.atoms) {
102
+ for (const tokenOrFamily of options.scope) {
84
103
  let atomKey = tokenOrFamily.key
85
- if (
86
- tokenOrFamily.type === `atom_family` ||
87
- tokenOrFamily.type === `mutable_atom_family`
88
- ) {
89
- const familyToken: AtomFamilyToken<any> = tokenOrFamily
90
- const family = withdraw(familyToken, store)
91
- const familyKey = family.key
92
- target.timelineAtoms.set({ atomKey: familyKey, timelineKey })
93
- family.subject.subscribe(`timeline:${options.key}`, (token) => {
94
- addAtomToTimeline(token, tl, store)
95
- })
96
- for (const atom of target.atoms.values()) {
97
- if (atom.family?.key === familyKey) {
104
+ switch (tokenOrFamily.type) {
105
+ case `atom_family`:
106
+ case `mutable_atom_family`:
107
+ {
108
+ const familyToken: AtomFamilyToken<any> = tokenOrFamily
109
+ const family = withdraw(familyToken, store)
110
+ const familyKey = family.key
111
+ target.timelineAtoms.set({ atomKey: familyKey, timelineKey })
112
+ tl.subscriptions.set(
113
+ family.key,
114
+ family.subject.subscribe(
115
+ `timeline:${options.key}`,
116
+ (creationOrDisposal) => {
117
+ handleStateLifecycleEvent(creationOrDisposal, tl, store)
118
+ },
119
+ ),
120
+ )
121
+ for (const atom of target.atoms.values()) {
122
+ if (atom.family?.key === familyKey) {
123
+ addAtomToTimeline(atom, tl, store)
124
+ }
125
+ }
126
+ }
127
+ break
128
+ case `atom`:
129
+ case `mutable_atom`:
130
+ {
131
+ let atom = withdraw(tokenOrFamily, store)
132
+ if (isMutable(atom)) {
133
+ const updateAtom = withdraw(getUpdateToken(atom), store)
134
+ atom = updateAtom
135
+ atomKey = atom.key
136
+ }
137
+ if (`family` in atom) {
138
+ const familyTimelineKey = target.timelineAtoms.getRelatedKey(
139
+ atom.family.key,
140
+ )
141
+ if (familyTimelineKey) {
142
+ store.logger.error(
143
+ `❌`,
144
+ `timeline`,
145
+ options.key,
146
+ `Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`,
147
+ )
148
+ continue
149
+ }
150
+ }
151
+ const existingTimelineKey = target.timelineAtoms.getRelatedKey(atomKey)
152
+ if (existingTimelineKey) {
153
+ store.logger.error(
154
+ `❌`,
155
+ `timeline`,
156
+ options.key,
157
+ `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`,
158
+ )
159
+ continue
160
+ }
98
161
  addAtomToTimeline(atom, tl, store)
99
162
  }
100
- }
101
- } else {
102
- let atom = withdraw(tokenOrFamily, store)
103
- if (isMutable(atom)) {
104
- const updateAtom = withdraw(getUpdateToken(atom), store)
105
- atom = updateAtom
106
- atomKey = atom.key
107
- }
108
- if (`family` in atom) {
109
- const familyTimelineKey = target.timelineAtoms.getRelatedKey(
110
- atom.family.key,
111
- )
112
- if (familyTimelineKey) {
113
- store.logger.error(
114
- `❌`,
115
- `timeline`,
116
- options.key,
117
- `Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`,
118
- )
119
- continue
163
+ break
164
+ case `molecule_family`:
165
+ {
166
+ const family = store.moleculeFamilies.get(tokenOrFamily.key)
167
+ if (family) {
168
+ tl.subscriptions.set(
169
+ tokenOrFamily.key,
170
+ family.subject.subscribe(
171
+ `timeline:${options.key}`,
172
+ (creationOrDisposal) => {
173
+ switch (creationOrDisposal.type) {
174
+ case `molecule_creation`:
175
+ {
176
+ const molecule = store.molecules.get(
177
+ stringifyJson(creationOrDisposal.token.key),
178
+ )
179
+ if (molecule) {
180
+ const event = Object.assign(creationOrDisposal, {
181
+ timestamp: Date.now(),
182
+ })
183
+ tl.history.push(event)
184
+ tl.at = tl.history.length
185
+ tl.subject.next(event)
186
+
187
+ for (const token of molecule.tokens) {
188
+ switch (token.type) {
189
+ case `atom`:
190
+ case `mutable_atom`:
191
+ addAtomToTimeline(token, tl, store)
192
+ break
193
+ }
194
+ }
195
+ tl.subscriptions.set(
196
+ molecule.key,
197
+ molecule.subject.subscribe(
198
+ `timeline:${options.key}`,
199
+ (stateCreationOrDisposal) => {
200
+ handleStateLifecycleEvent(
201
+ stateCreationOrDisposal,
202
+ tl,
203
+ store,
204
+ )
205
+ },
206
+ ),
207
+ )
208
+ }
209
+ }
210
+ break
211
+ case `molecule_disposal`:
212
+ tl.subscriptions.get(creationOrDisposal.token.key)?.()
213
+ tl.subscriptions.delete(creationOrDisposal.token.key)
214
+ for (const familyKey of creationOrDisposal.familyKeys) {
215
+ const stateKey = `${familyKey}(${stringifyJson(
216
+ creationOrDisposal.token.key,
217
+ )})`
218
+ tl.subscriptions.get(stateKey)?.()
219
+ tl.subscriptions.delete(stateKey)
220
+ }
221
+ break
222
+ }
223
+ },
224
+ ),
225
+ )
226
+ }
120
227
  }
121
- }
122
- const existingTimelineKey = target.timelineAtoms.getRelatedKey(atomKey)
123
- if (existingTimelineKey) {
124
- store.logger.error(
125
- `❌`,
126
- `timeline`,
127
- options.key,
128
- `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`,
129
- )
130
- continue
131
- }
132
- addAtomToTimeline(atom, tl, store)
228
+ break
133
229
  }
134
230
  }
135
231
 
@@ -141,3 +237,28 @@ export function createTimeline<ManagedAtom extends TimelineManageable>(
141
237
  store.on.timelineCreation.next(token)
142
238
  return token
143
239
  }
240
+
241
+ function handleStateLifecycleEvent(
242
+ event: StateCreation<any> | StateDisposal<any>,
243
+ tl: Timeline<any>,
244
+ store: Store,
245
+ ): void {
246
+ const timestamp = Date.now()
247
+ const timelineEvent = Object.assign(event, {
248
+ timestamp,
249
+ }) as TimelineUpdate<any>
250
+ if (!tl.timeTraveling) {
251
+ tl.history.push(timelineEvent)
252
+ tl.at = tl.history.length
253
+ tl.subject.next(timelineEvent)
254
+ }
255
+ switch (event.type) {
256
+ case `state_creation`:
257
+ addAtomToTimeline(event.token, tl, store)
258
+ break
259
+ case `state_disposal`:
260
+ tl.subscriptions.get(event.token.key)?.()
261
+ tl.subscriptions.delete(event.token.key)
262
+ break
263
+ }
264
+ }
@@ -2,6 +2,10 @@ import type { TimelineToken } from "atom.io"
2
2
 
3
3
  import {
4
4
  ingestAtomUpdate,
5
+ ingestCreationEvent,
6
+ ingestDisposalEvent,
7
+ ingestMoleculeCreationEvent,
8
+ ingestMoleculeDisposalEvent,
5
9
  ingestSelectorUpdate,
6
10
  ingestTransactionUpdate,
7
11
  } from "../ingest-updates"
@@ -64,6 +68,22 @@ export const timeTravel = (
64
68
  ingestTransactionUpdate(applying, update, store)
65
69
  break
66
70
  }
71
+ case `state_creation`: {
72
+ ingestCreationEvent(update, applying, store)
73
+ break
74
+ }
75
+ case `state_disposal`: {
76
+ ingestDisposalEvent(update, applying, store)
77
+ break
78
+ }
79
+ case `molecule_creation`: {
80
+ ingestMoleculeCreationEvent(update, applying, store)
81
+ break
82
+ }
83
+ case `molecule_disposal`: {
84
+ ingestMoleculeDisposalEvent(update, applying, store)
85
+ break
86
+ }
67
87
  }
68
88
 
69
89
  if (action === `redo`) {
@@ -46,19 +46,9 @@ export const applyTransaction = <F extends Func>(
46
46
  }
47
47
  tracker.dispose()
48
48
  }
49
- for (const atom of child.atoms.values()) {
50
- if (!parent.atoms.has(atom.key)) {
51
- parent.atoms.set(atom.key, atom)
52
- parent.valueMap.set(atom.key, atom.default)
53
- parent.logger.info(
54
- `🔨`,
55
- `transaction`,
56
- child.transactionMeta.update.key,
57
- `Adding atom "${atom.key}"`,
58
- )
59
- }
60
- }
49
+
61
50
  ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent)
51
+
62
52
  if (isRootStore(parent)) {
63
53
  setEpochNumberOfAction(
64
54
  child.transactionMeta.update.key,
@@ -1,15 +1,16 @@
1
1
  import type { Func } from "atom.io"
2
2
  import type { findState } from "atom.io/ephemeral"
3
- import type { seekState } from "atom.io/immortal"
3
+ import { makeMoleculeInStore, type seekState } from "atom.io/immortal"
4
4
 
5
5
  import { Junction } from "~/packages/rel8/junction/src"
6
6
 
7
7
  import { arbitrary } from "../arbitrary"
8
- import { findInStore, seekInStore } from "../families"
8
+ import { disposeFromStore, findInStore, seekInStore } from "../families"
9
9
  import { getEnvironmentData } from "../get-environment-data"
10
10
  import { getFromStore } from "../get-state"
11
11
  import { LazyMap } from "../lazy-map"
12
12
  import { newest } from "../lineage"
13
+ import { getJsonToken } from "../mutable"
13
14
  import { setIntoStore } from "../set-state"
14
15
  import type { Store } from "../store"
15
16
  import type { TransactionProgress } from "."
@@ -46,12 +47,14 @@ export const buildTransaction = (
46
47
  selectors: new LazyMap(parent.selectors),
47
48
  valueMap: new LazyMap(parent.valueMap),
48
49
  molecules: new LazyMap(parent.molecules),
50
+ moleculeFamilies: new LazyMap(parent.moleculeFamilies),
49
51
  miscResources: new LazyMap(parent.miscResources),
50
52
  }
51
53
  const epoch = getEpochNumberOfAction(key, store)
52
54
  const transactionMeta: TransactionProgress<Func> = {
53
55
  phase: `building`,
54
56
  update: {
57
+ type: `transaction_update`,
55
58
  key,
56
59
  id,
57
60
  epoch: epoch === undefined ? Number.NaN : epoch + 1,
@@ -68,6 +71,12 @@ export const buildTransaction = (
68
71
  actUponStore(token, identifier, child),
69
72
  find: ((token, k) => findInStore(token, k, child)) as typeof findState,
70
73
  seek: ((token, k) => seekInStore(token, k, child)) as typeof seekState,
74
+ json: (token) => getJsonToken(token, child),
75
+ make: (context, family, k, ...args) =>
76
+ makeMoleculeInStore(child, context, family, k, ...args),
77
+ dispose: (token) => {
78
+ disposeFromStore(token, child)
79
+ },
71
80
  env: () => getEnvironmentData(child),
72
81
  },
73
82
  }
@@ -224,7 +224,8 @@ var attachTimelineFamily = (store = Internal2.IMPLICIT.STORE) => {
224
224
  transactionKey: null,
225
225
  install: () => {
226
226
  },
227
- subject: new Internal2.Subject()
227
+ subject: new Internal2.Subject(),
228
+ subscriptions: /* @__PURE__ */ new Map()
228
229
  };
229
230
  },
230
231
  effects: (key) => [
@@ -189,7 +189,8 @@ var attachTimelineFamily = (store = IMPLICIT.STORE) => {
189
189
  transactionKey: null,
190
190
  install: () => {
191
191
  },
192
- subject: new Subject()
192
+ subject: new Subject(),
193
+ subscriptions: /* @__PURE__ */ new Map()
193
194
  };
194
195
  },
195
196
  effects: (key) => [
@@ -27,6 +27,7 @@ export const attachTimelineFamily = (
27
27
  transactionKey: null,
28
28
  install: () => {},
29
29
  subject: new Subject(),
30
+ subscriptions: new Map(),
30
31
  },
31
32
  effects: (key) => [
32
33
  ({ setSelf }) => {
@@ -62,9 +62,9 @@ function selectJsonFamily(family, transform, store = internal.IMPLICIT.STORE) {
62
62
  );
63
63
  family.subject.subscribe(
64
64
  `store=${store.config.name}::json-selector-family`,
65
- (token) => {
66
- if (token.family) {
67
- internal.seekInStore(jsonFamily, parseJson(token.family.subKey), store);
65
+ (event) => {
66
+ if (event.token.family) {
67
+ internal.seekInStore(jsonFamily, parseJson(event.token.family.subKey), store);
68
68
  }
69
69
  }
70
70
  );
@@ -1,5 +1,6 @@
1
- import { stringifyJson, parseJson } from '../../dist/chunk-BF4MVQF6.js';
2
- export { JSON_DEFAULTS, JSON_TYPE_NAMES, isBoolean, isNull, isNumber, isPrimitive, isString, parseJson, stringSetJsonInterface, stringifyJson } from '../../dist/chunk-BF4MVQF6.js';
1
+ export { isBoolean, isNull, isNumber, isPrimitive, isString } from '../../dist/chunk-6MLFYN32.js';
2
+ import { stringifyJson, parseJson } from '../../dist/chunk-OAYGID5B.js';
3
+ export { JSON_DEFAULTS, JSON_TYPE_NAMES, parseJson, stringSetJsonInterface, stringifyJson } from '../../dist/chunk-OAYGID5B.js';
3
4
  import '../../dist/chunk-F2X4B4VY.js';
4
5
  import { createStandaloneSelector, IMPLICIT, createSelectorFamily, initFamilyMember, seekInStore } from 'atom.io/internal';
5
6
 
@@ -62,9 +63,9 @@ function selectJsonFamily(family, transform, store = IMPLICIT.STORE) {
62
63
  );
63
64
  family.subject.subscribe(
64
65
  `store=${store.config.name}::json-selector-family`,
65
- (token) => {
66
- if (token.family) {
67
- seekInStore(jsonFamily, parseJson(token.family.subKey), store);
66
+ (event) => {
67
+ if (event.token.family) {
68
+ seekInStore(jsonFamily, parseJson(event.token.family.subKey), store);
68
69
  }
69
70
  }
70
71
  );
@@ -64,7 +64,6 @@ export function selectJsonFamily<
64
64
  set:
65
65
  (key) =>
66
66
  ({ seek, set }, newValue) => {
67
- // set(seek(family, key), transform.fromJson(newValue))
68
67
  const existingState = seek(family, key)
69
68
  if (existingState) {
70
69
  set(existingState, transform.fromJson(newValue))
@@ -90,9 +89,9 @@ export function selectJsonFamily<
90
89
  )
91
90
  family.subject.subscribe(
92
91
  `store=${store.config.name}::json-selector-family`,
93
- (token) => {
94
- if (token.family) {
95
- seekInStore(jsonFamily, parseJson(token.family.subKey) as K, store)
92
+ (event) => {
93
+ if (event.token.family) {
94
+ seekInStore(jsonFamily, parseJson(event.token.family.subKey) as K, store)
96
95
  }
97
96
  },
98
97
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -56,16 +56,16 @@
56
56
  "@types/npmlog": "7.0.0",
57
57
  "@types/react": "18.3.2",
58
58
  "@types/tmp": "0.2.6",
59
- "@typescript-eslint/parser": "7.9.0",
60
- "@typescript-eslint/rule-tester": "7.9.0",
59
+ "@typescript-eslint/parser": "7.10.0",
60
+ "@typescript-eslint/rule-tester": "7.10.0",
61
61
  "@vitest/coverage-v8": "1.6.0",
62
62
  "@vitest/ui": "1.6.0",
63
63
  "concurrently": "8.2.2",
64
- "drizzle-kit": "0.21.2",
64
+ "drizzle-kit": "0.21.3",
65
65
  "drizzle-orm": "0.30.10",
66
66
  "eslint": "npm:eslint@8.57.0",
67
67
  "eslint-v9": "npm:eslint@9.3.0",
68
- "framer-motion": "11.2.4",
68
+ "framer-motion": "11.2.6",
69
69
  "happy-dom": "14.11.0",
70
70
  "http-proxy": "1.18.1",
71
71
  "npmlog": "7.0.1",
@@ -1838,25 +1838,28 @@ var TransactionUpdateFC = ({ serialNumber, transactionUpdate }) => {
1838
1838
  ] }),
1839
1839
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "transaction_impact", children: [
1840
1840
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "detail", children: "impact: " }),
1841
- transactionUpdate.updates.filter((token) => !token.key.startsWith(`\u{1F441}\u200D\u{1F5E8}`)).map((update, index) => {
1842
- if (`newValue` in update) {
1843
- return /* @__PURE__ */ jsxRuntime.jsx(
1844
- article.AtomUpdate,
1845
- {
1846
- serialNumber: index,
1847
- atomUpdate: update
1848
- },
1849
- `${transactionUpdate.key}:${index}:${update.key}`
1850
- );
1841
+ transactionUpdate.updates.filter((token) => `key` in token && !token.key.startsWith(`\u{1F441}\u200D\u{1F5E8}`)).map((update, index) => {
1842
+ switch (update.type) {
1843
+ case `atom_update`:
1844
+ case `selector_update`:
1845
+ return /* @__PURE__ */ jsxRuntime.jsx(
1846
+ article.AtomUpdate,
1847
+ {
1848
+ serialNumber: index,
1849
+ atomUpdate: update
1850
+ },
1851
+ `${transactionUpdate.key}:${index}:${update.key}`
1852
+ );
1853
+ case `transaction_update`:
1854
+ return /* @__PURE__ */ jsxRuntime.jsx(
1855
+ TransactionUpdateFC,
1856
+ {
1857
+ serialNumber: index,
1858
+ transactionUpdate: update
1859
+ },
1860
+ `${transactionUpdate.key}:${index}:${update.key}`
1861
+ );
1851
1862
  }
1852
- return /* @__PURE__ */ jsxRuntime.jsx(
1853
- TransactionUpdateFC,
1854
- {
1855
- serialNumber: index,
1856
- transactionUpdate: update
1857
- },
1858
- `${transactionUpdate.key}:${index}:${update.key}`
1859
- );
1860
1863
  })
1861
1864
  ] })
1862
1865
  ] })
@@ -1865,7 +1868,7 @@ var TransactionUpdateFC = ({ serialNumber, transactionUpdate }) => {
1865
1868
  );
1866
1869
  };
1867
1870
  var TimelineUpdateFC = ({ timelineUpdate, serialNumber }) => {
1868
- return /* @__PURE__ */ jsxRuntime.jsxs(
1871
+ return `key` in timelineUpdate ? /* @__PURE__ */ jsxRuntime.jsxs(
1869
1872
  "article",
1870
1873
  {
1871
1874
  className: "node timeline_update",
@@ -1879,22 +1882,28 @@ var TimelineUpdateFC = ({ timelineUpdate, serialNumber }) => {
1879
1882
  timelineUpdate.key,
1880
1883
  ")"
1881
1884
  ] }) }),
1882
- /* @__PURE__ */ jsxRuntime.jsx("main", { children: timelineUpdate.type === `transaction_update` ? timelineUpdate.updates.filter((token) => !token.key.startsWith(`\u{1F441}\u200D\u{1F5E8}`)).map((update, index) => {
1883
- return `newValue` in update ? /* @__PURE__ */ jsxRuntime.jsx(
1884
- article.AtomUpdate,
1885
- {
1886
- serialNumber: index,
1887
- atomUpdate: update
1888
- },
1889
- `${timelineUpdate.key}:${index}:${update.key}`
1890
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1891
- TransactionUpdateFC,
1892
- {
1893
- serialNumber: index,
1894
- transactionUpdate: update
1895
- },
1896
- `${timelineUpdate.key}:${index}:${update.key}`
1897
- );
1885
+ /* @__PURE__ */ jsxRuntime.jsx("main", { children: timelineUpdate.type === `transaction_update` ? timelineUpdate.updates.filter((token) => `key` in token && !token.key.startsWith(`\u{1F441}\u200D\u{1F5E8}`)).map((update, index) => {
1886
+ switch (update.type) {
1887
+ case `atom_update`:
1888
+ case `selector_update`:
1889
+ return /* @__PURE__ */ jsxRuntime.jsx(
1890
+ article.AtomUpdate,
1891
+ {
1892
+ serialNumber: index,
1893
+ atomUpdate: update
1894
+ },
1895
+ `${timelineUpdate.key}:${index}:${update.key}`
1896
+ );
1897
+ case `transaction_update`:
1898
+ return /* @__PURE__ */ jsxRuntime.jsx(
1899
+ TransactionUpdateFC,
1900
+ {
1901
+ serialNumber: index,
1902
+ transactionUpdate: update
1903
+ },
1904
+ `${timelineUpdate.key}:${index}:${update.key}`
1905
+ );
1906
+ }
1898
1907
  }) : timelineUpdate.type === `selector_update` ? timelineUpdate.atomUpdates.filter((token) => !token.key.startsWith(`\u{1F441}\u200D\u{1F5E8}`)).map((atomUpdate, index) => {
1899
1908
  return /* @__PURE__ */ jsxRuntime.jsx(
1900
1909
  article.AtomUpdate,
@@ -1913,7 +1922,7 @@ var TimelineUpdateFC = ({ timelineUpdate, serialNumber }) => {
1913
1922
  ) : null })
1914
1923
  ]
1915
1924
  }
1916
- );
1925
+ ) : null;
1917
1926
  };
1918
1927
  var article = {
1919
1928
  AtomUpdate: AtomUpdateFC,
@@ -1973,17 +1982,19 @@ var TimelineLog = ({ token, isOpenState, timelineState }) => {
1973
1982
  ] })
1974
1983
  ] })
1975
1984
  ] }),
1976
- isOpen ? /* @__PURE__ */ jsxRuntime.jsx("main", { children: timeline.history.map((update, index) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
1977
- index === timeline.at ? /* @__PURE__ */ jsxRuntime.jsx(YouAreHere, {}) : null,
1978
- /* @__PURE__ */ jsxRuntime.jsx(
1979
- article.TimelineUpdate,
1980
- {
1981
- timelineUpdate: update,
1982
- serialNumber: index
1983
- }
1984
- ),
1985
- index === timeline.history.length - 1 && timeline.at === timeline.history.length ? /* @__PURE__ */ jsxRuntime.jsx(YouAreHere, {}) : null
1986
- ] }, update.key + index + timeline.at)) }) : null
1985
+ isOpen ? /* @__PURE__ */ jsxRuntime.jsx("main", { children: timeline.history.map(
1986
+ (update, index) => `key` in update ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
1987
+ index === timeline.at ? /* @__PURE__ */ jsxRuntime.jsx(YouAreHere, {}) : null,
1988
+ /* @__PURE__ */ jsxRuntime.jsx(
1989
+ article.TimelineUpdate,
1990
+ {
1991
+ timelineUpdate: update,
1992
+ serialNumber: index
1993
+ }
1994
+ ),
1995
+ index === timeline.history.length - 1 && timeline.at === timeline.history.length ? /* @__PURE__ */ jsxRuntime.jsx(YouAreHere, {}) : null
1996
+ ] }, update.key + index + timeline.at) : null
1997
+ ) }) : null
1987
1998
  ] });
1988
1999
  };
1989
2000
  var TimelineIndex = () => {