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
@@ -1,5 +1,4 @@
1
1
  import type {
2
- AtomToken,
3
2
  FamilyMetadata,
4
3
  MutableAtomFamilyToken,
5
4
  MutableAtomToken,
@@ -9,9 +8,8 @@ import type {
9
8
  ReadonlyPureSelectorToken,
10
9
  RegularAtomFamilyToken,
11
10
  RegularAtomToken,
12
- StateCreation,
13
- StateDisposal,
14
11
  StateLifecycleEvent,
12
+ StateUpdate,
15
13
  WritableHeldSelectorFamilyToken,
16
14
  WritableHeldSelectorToken,
17
15
  WritablePureSelectorFamilyToken,
@@ -62,7 +60,7 @@ export type AtomIOState = {
62
60
  key: string
63
61
  family?: FamilyMetadata
64
62
  install: (store: Store) => void
65
- subject: Subject<{ newValue: any; oldValue: any }>
63
+ subject: Subject<StateUpdate<any>>
66
64
  }
67
65
  export type RegularAtom<T> = Flat<
68
66
  AtomIOState & {
@@ -87,28 +85,28 @@ export type WritableHeldSelector<T> = Flat<
87
85
  AtomIOState & {
88
86
  type: `writable_held_selector`
89
87
  const: T
90
- get: () => T
91
- set: (newValue: T | ((oldValue: T) => T)) => void
88
+ getFrom: (target: Store) => T
89
+ setSelf: (newValue: T) => void
92
90
  }
93
91
  >
94
92
  export type ReadonlyHeldSelector<T> = Flat<
95
93
  AtomIOState & {
96
94
  type: `readonly_held_selector`
97
95
  const: T
98
- get: () => T
96
+ getFrom: (target: Store) => T
99
97
  }
100
98
  >
101
99
  export type WritablePureSelector<T> = Flat<
102
100
  AtomIOState & {
103
101
  type: `writable_pure_selector`
104
- get: () => T
105
- set: (newValue: T | ((oldValue: T) => T)) => void
102
+ getFrom: (target: Store) => T
103
+ setSelf: (newValue: T) => void
106
104
  }
107
105
  >
108
106
  export type ReadonlyPureSelector<T> = Flat<
109
107
  AtomIOState & {
110
108
  type: `readonly_pure_selector`
111
- get: () => T
109
+ getFrom: (target: Store) => T
112
110
  }
113
111
  >
114
112
  export type ReadonlySelector<T> =
@@ -130,23 +128,26 @@ export type ReadableState<T> = Atom<T> | Selector<T>
130
128
 
131
129
  // biome-ignore format: intersection
132
130
  export type RegularAtomFamily<T, K extends Canonical> =
133
- & RegularAtomFamilyToken<T, K>
134
- & {
135
- (key: K): RegularAtomToken<T>
136
- install: (store: Store) => void
137
- internalRoles: string[] | undefined
138
- subject: Subject<StateCreation<AtomToken<T>> | StateDisposal<AtomToken<T>>>
139
- }
131
+ & Flat<
132
+ & RegularAtomFamilyToken<T, K>
133
+ & {
134
+ default: T | ((key: K) => T)
135
+ install: (store: Store) => void
136
+ internalRoles: string[] | undefined
137
+ subject: Subject<StateLifecycleEvent<RegularAtomToken<T>>>
138
+ }
139
+ >
140
+ & ((key: K) => RegularAtomToken<T>)
140
141
 
141
142
  // biome-ignore format: intersection
142
143
  export type MutableAtomFamily<
143
- // C extends TransceiverConstructor<any,any>,
144
144
  T extends Transceiver<any, any, any>,
145
145
  K extends Canonical,
146
146
  > =
147
147
  & Flat<
148
148
  & MutableAtomFamilyToken<T, K>
149
149
  & {
150
+ class: ConstructorOf<T>
150
151
  install: (store: Store) => void
151
152
  internalRoles: string[] | undefined
152
153
  subject: Subject<StateLifecycleEvent<MutableAtomToken<T>>>
@@ -166,13 +167,10 @@ export type WritablePureSelectorFamily<T, K extends Canonical> =
166
167
  default: (key: K) => T,
167
168
  install: (store: Store) => void
168
169
  internalRoles: string[] | undefined
169
- subject: Subject<
170
- | StateCreation<WritablePureSelectorToken<T>>
171
- | StateDisposal<WritablePureSelectorToken<T>>
172
- >
170
+ subject: Subject<StateLifecycleEvent<WritablePureSelectorToken<T>>>
173
171
  }
174
172
  >
175
- & ((key: K) => WritablePureSelectorToken<T>)
173
+ & ((key: K) => WritablePureSelectorToken<T>)
176
174
 
177
175
  // biome-ignore format: intersection
178
176
  export type WritableHeldSelectorFamily<T , K extends Canonical> =
@@ -182,13 +180,10 @@ export type WritableHeldSelectorFamily<T , K extends Canonical> =
182
180
  default: (key: K) => T,
183
181
  install: (store: Store) => void
184
182
  internalRoles: string[] | undefined
185
- subject: Subject<
186
- | StateCreation<WritableHeldSelectorToken<T>>
187
- | StateDisposal<WritableHeldSelectorToken<T>>
188
- >
183
+ subject: Subject<StateLifecycleEvent<WritableHeldSelectorToken<T>>>
189
184
  }
190
185
  >
191
- & ((key: K) => WritableHeldSelectorToken<T>)
186
+ & ((key: K) => WritableHeldSelectorToken<T>)
192
187
 
193
188
  // biome-ignore format: intersection
194
189
  export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
@@ -198,10 +193,7 @@ export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
198
193
  default: (key: K) => T,
199
194
  install: (store: Store) => void
200
195
  internalRoles: string[] | undefined
201
- subject: Subject<
202
- | StateCreation<ReadonlyPureSelectorToken<T>>
203
- | StateDisposal<ReadonlyPureSelectorToken<T>>
204
- >
196
+ subject: Subject<StateLifecycleEvent<ReadonlyPureSelectorToken<T>>>
205
197
  }
206
198
  >
207
199
  & ((key: K) => ReadonlyPureSelectorToken<T>)
@@ -214,10 +206,7 @@ export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
214
206
  default: (key: K) => T,
215
207
  install: (store: Store) => void
216
208
  internalRoles: string[] | undefined
217
- subject: Subject<
218
- | StateCreation<ReadonlyHeldSelectorToken<T>>
219
- | StateDisposal<ReadonlyHeldSelectorToken<T>>
220
- >
209
+ subject: Subject<StateLifecycleEvent<ReadonlyHeldSelectorToken<T>>>
221
210
  }
222
211
  >
223
212
  & ((key: K) => ReadonlyHeldSelectorToken<T>)
@@ -1,18 +1,18 @@
1
- import type { KeyedStateUpdate, RegularAtomToken } from "atom.io"
1
+ import type { AtomUpdateEvent } from "atom.io"
2
2
 
3
3
  import { setIntoStore } from "../set-state"
4
4
  import type { Store } from "../store"
5
5
 
6
6
  export function ingestAtomUpdate(
7
7
  applying: `newValue` | `oldValue`,
8
- atomUpdate: KeyedStateUpdate<any>,
8
+ atomUpdate: AtomUpdateEvent<any>,
9
9
  store: Store,
10
10
  ): void {
11
- const { key, newValue, oldValue } = atomUpdate
11
+ const {
12
+ token,
13
+ update: { newValue, oldValue },
14
+ } = atomUpdate
12
15
  const value = applying === `newValue` ? newValue : oldValue
13
- const token: RegularAtomToken<unknown> = { key, type: `atom` }
14
- if (atomUpdate.family) {
15
- Object.assign(token, { family: atomUpdate.family })
16
- }
16
+
17
17
  setIntoStore(store, token, value)
18
18
  }
@@ -1,10 +1,10 @@
1
1
  import type {
2
- MoleculeCreation,
3
- MoleculeDisposal,
4
- MoleculeTransfer,
2
+ MoleculeCreationEvent,
3
+ MoleculeDisposalEvent,
4
+ MoleculeTransferEvent,
5
5
  ReadableToken,
6
- StateCreation,
7
- StateDisposal,
6
+ StateCreationEvent,
7
+ StateDisposalEvent,
8
8
  } from "atom.io"
9
9
  import { parseJson, stringifyJson } from "atom.io/json"
10
10
 
@@ -17,7 +17,7 @@ import {
17
17
  import type { Store } from "../store"
18
18
 
19
19
  export function ingestCreationEvent(
20
- update: StateCreation<any>,
20
+ update: StateCreationEvent<any>,
21
21
  applying: `newValue` | `oldValue`,
22
22
  store: Store,
23
23
  ): void {
@@ -34,7 +34,7 @@ export function ingestCreationEvent(
34
34
  }
35
35
 
36
36
  export function ingestDisposalEvent(
37
- update: StateDisposal<ReadableToken<any>>,
37
+ update: StateDisposalEvent<ReadableToken<any>>,
38
38
  applying: `newValue` | `oldValue`,
39
39
  store: Store,
40
40
  ): void {
@@ -54,7 +54,7 @@ export function ingestDisposalEvent(
54
54
  }
55
55
 
56
56
  function createInStore(
57
- update: StateCreation<any> | StateDisposal<any>,
57
+ update: StateCreationEvent<any> | StateDisposalEvent<any>,
58
58
  store: Store,
59
59
  ): void {
60
60
  const { family: familyMeta } = update.token
@@ -67,7 +67,7 @@ function createInStore(
67
67
  }
68
68
 
69
69
  export function ingestMoleculeCreationEvent(
70
- update: MoleculeCreation,
70
+ update: MoleculeCreationEvent,
71
71
  applying: `newValue` | `oldValue`,
72
72
  store: Store,
73
73
  ): void {
@@ -82,7 +82,7 @@ export function ingestMoleculeCreationEvent(
82
82
  }
83
83
  }
84
84
  export function ingestMoleculeDisposalEvent(
85
- update: MoleculeDisposal,
85
+ update: MoleculeDisposalEvent,
86
86
  applying: `newValue` | `oldValue`,
87
87
  store: Store,
88
88
  ): void {
@@ -108,7 +108,7 @@ export function ingestMoleculeDisposalEvent(
108
108
  }
109
109
  }
110
110
  export function ingestMoleculeTransferEvent(
111
- update: MoleculeTransfer,
111
+ update: MoleculeTransferEvent,
112
112
  applying: `newValue` | `oldValue`,
113
113
  store: Store,
114
114
  ): void {
@@ -1,15 +1,19 @@
1
- import type { TimelineManageable } from "atom.io"
1
+ import type {
2
+ AtomOnly,
3
+ AtomUpdateEvent,
4
+ TimelineManageable,
5
+ TimelineSelectorUpdateEvent,
6
+ } from "atom.io"
2
7
 
3
8
  import type { Store } from "../store"
4
- import type { TimelineAtomUpdate, TimelineSelectorUpdate } from "../timeline"
5
9
  import { ingestAtomUpdate } from "./ingest-atom-update"
6
10
 
7
11
  export function ingestSelectorUpdate(
8
12
  applying: `newValue` | `oldValue`,
9
- selectorUpdate: TimelineSelectorUpdate<any>,
13
+ selectorUpdate: TimelineSelectorUpdateEvent<any>,
10
14
  store: Store,
11
15
  ): void {
12
- let updates: Omit<TimelineAtomUpdate<TimelineManageable>, `timestamp`>[]
16
+ let updates: AtomUpdateEvent<AtomOnly<TimelineManageable>>[]
13
17
  if (applying === `newValue`) {
14
18
  updates = selectorUpdate.atomUpdates
15
19
  } else {
@@ -1,4 +1,4 @@
1
- import type { TransactionUpdate } from "atom.io"
1
+ import type { TransactionOutcomeEvent } from "atom.io"
2
2
 
3
3
  import type { Store } from "../store"
4
4
  import { ingestAtomUpdate } from "./ingest-atom-update"
@@ -12,17 +12,16 @@ import {
12
12
 
13
13
  export function ingestTransactionUpdate(
14
14
  applying: `newValue` | `oldValue`,
15
- transactionUpdate: TransactionUpdate<any>,
15
+ transactionUpdate: TransactionOutcomeEvent<any>,
16
16
  store: Store,
17
17
  ): void {
18
18
  const updates =
19
19
  applying === `newValue`
20
- ? transactionUpdate.updates
21
- : [...transactionUpdate.updates].reverse()
20
+ ? transactionUpdate.subEvents
21
+ : [...transactionUpdate.subEvents].reverse()
22
22
  for (const updateFromTransaction of updates) {
23
23
  switch (updateFromTransaction.type) {
24
24
  case `atom_update`:
25
- case `selector_update`:
26
25
  ingestAtomUpdate(applying, updateFromTransaction, store)
27
26
  break
28
27
  case `state_creation`:
@@ -40,7 +39,7 @@ export function ingestTransactionUpdate(
40
39
  case `molecule_transfer`:
41
40
  ingestMoleculeTransferEvent(updateFromTransaction, applying, store)
42
41
  break
43
- case `transaction_update`:
42
+ case `transaction_outcome`:
44
43
  ingestTransactionUpdate(applying, updateFromTransaction, store)
45
44
  break
46
45
  }
@@ -22,7 +22,7 @@ export function installIntoStore(
22
22
  source.logger.error(
23
23
  `❌`,
24
24
  `transaction`,
25
- sourceNewest.transactionMeta.update.key,
25
+ sourceNewest.transactionMeta.update.token.key,
26
26
  `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
27
27
  tokens,
28
28
  `${sourceNewest.config.name} is undergoing a transaction.`,
@@ -34,7 +34,7 @@ export function installIntoStore(
34
34
  target.logger.error(
35
35
  `❌`,
36
36
  `transaction`,
37
- targetNewest.transactionMeta.update.key,
37
+ targetNewest.transactionMeta.update.token.key,
38
38
  `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
39
39
  tokens,
40
40
  `${targetNewest.config.name} is undergoing a transaction.`,
@@ -8,6 +8,7 @@ import type {
8
8
  ReadonlyPureSelectorFamilyToken,
9
9
  RegularAtomFamilyToken,
10
10
  setState,
11
+ ViewOf,
11
12
  Write,
12
13
  WriterToolkit,
13
14
  } from "atom.io"
@@ -29,7 +30,6 @@ import type {
29
30
  } from "../junction"
30
31
  import { Junction } from "../junction"
31
32
  import type { Molecule } from "../molecule"
32
- import type { ViewOf } from "../mutable"
33
33
  import { createMutableAtomFamily, getJsonFamily, getJsonToken } from "../mutable"
34
34
  import { setIntoStore } from "../set-state"
35
35
  import type { Store } from "../store"
@@ -4,9 +4,9 @@ import type {
4
4
  CompoundFrom,
5
5
  CompoundTypedKey,
6
6
  Hierarchy,
7
- MoleculeCreation,
8
- MoleculeDisposal,
9
- MoleculeTransfer,
7
+ MoleculeCreationEvent,
8
+ MoleculeDisposalEvent,
9
+ MoleculeTransferEvent,
10
10
  SingularTypedKey,
11
11
  Vassal,
12
12
  } from "atom.io"
@@ -77,15 +77,16 @@ export function allocateIntoStore<
77
77
  target.molecules.set(stringKey, { key, stringKey, dependsOn })
78
78
  }
79
79
 
80
- const creationEvent: MoleculeCreation = {
80
+ const creationEvent: MoleculeCreationEvent = {
81
81
  type: `molecule_creation`,
82
82
  key,
83
83
  provenance: origin,
84
+ timestamp: Date.now(),
84
85
  }
85
86
  const isTransaction =
86
87
  isChildStore(target) && target.transactionMeta.phase === `building`
87
88
  if (isTransaction) {
88
- target.transactionMeta.update.updates.push(creationEvent)
89
+ target.transactionMeta.update.subEvents.push(creationEvent)
89
90
  } else {
90
91
  target.on.moleculeCreation.next(creationEvent)
91
92
  }
@@ -174,18 +175,19 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
174
175
  const provenance: stringified<Canonical>[] = []
175
176
 
176
177
  const values: [string, any][] = []
177
- const disposalEvent: MoleculeDisposal = {
178
+ const disposalEvent: MoleculeDisposalEvent = {
178
179
  type: `molecule_disposal`,
179
180
  key: molecule.key,
180
181
  values,
181
182
  provenance,
183
+ timestamp: Date.now(),
182
184
  }
183
185
  const target = newest(store)
184
186
  target.molecules.delete(stringKey)
185
187
  const isTransaction =
186
188
  isChildStore(target) && target.transactionMeta.phase === `building`
187
189
  if (isTransaction) {
188
- target.transactionMeta.update.updates.push(disposalEvent)
190
+ target.transactionMeta.update.subEvents.push(disposalEvent)
189
191
  }
190
192
  const relatedMolecules = store.moleculeGraph.getRelationEntries({
191
193
  downstreamMoleculeKey: molecule.stringKey,
@@ -290,17 +292,18 @@ export function claimWithinStore<
290
292
  source: newProvenanceMolecule.stringKey,
291
293
  },
292
294
  )
293
- const transferEvent: MoleculeTransfer = {
295
+ const transferEvent: MoleculeTransferEvent = {
294
296
  type: `molecule_transfer`,
295
297
  key: molecule.key,
296
298
  exclusive: Boolean(exclusive),
297
299
  from: priorProvenance,
298
300
  to: [newProvenanceMolecule.key],
301
+ timestamp: Date.now(),
299
302
  }
300
303
  const isTransaction =
301
304
  isChildStore(target) && target.transactionMeta.phase === `building`
302
305
  if (isTransaction) {
303
- target.transactionMeta.update.updates.push(transferEvent)
306
+ target.transactionMeta.update.subEvents.push(transferEvent)
304
307
  }
305
308
 
306
309
  return claim
@@ -4,8 +4,7 @@ import type {
4
4
  MutableAtomFamilyToken,
5
5
  MutableAtomOptions,
6
6
  MutableAtomToken,
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"
@@ -48,9 +47,7 @@ export function createMutableAtomFamily<
48
47
  )
49
48
  }
50
49
 
51
- const subject = new Subject<
52
- StateCreation<MutableAtomToken<T>> | StateDisposal<MutableAtomToken<T>>
53
- >()
50
+ const subject = new Subject<StateLifecycleEvent<MutableAtomToken<T>>>()
54
51
 
55
52
  const familyFunction = (key: K): MutableAtomToken<T> => {
56
53
  const subKey = stringifyJson(key)
@@ -68,11 +65,12 @@ export function createMutableAtomFamily<
68
65
 
69
66
  const token = createMutableAtom(target, individualOptions, family)
70
67
 
71
- subject.next({ type: `state_creation`, token })
68
+ subject.next({ type: `state_creation`, token, timestamp: Date.now() })
72
69
  return token
73
70
  }
74
71
 
75
72
  const atomFamily = Object.assign(familyFunction, familyToken, {
73
+ class: options.class,
76
74
  subject,
77
75
  install: (s: Store) => createMutableAtomFamily(s, options),
78
76
  internalRoles,
@@ -58,7 +58,7 @@ export class Tracker<T extends Transceiver<any, any, any>> {
58
58
  const stateKey = mutableState.key
59
59
  const storeName = target.config.name
60
60
  const storeStatus = isChildStore(target)
61
- ? target.transactionMeta.update.key
61
+ ? target.transactionMeta.update.token.key
62
62
  : `main`
63
63
  const subscriptionKey = `tracker:${storeName}:${storeStatus}:${stateKey}`
64
64
  const trackerCapturesOutboundSignal = (update: SignalFrom<T>) => {
@@ -91,7 +91,7 @@ export class Tracker<T extends Transceiver<any, any, any>> {
91
91
  target: Store,
92
92
  ): void {
93
93
  const subscriptionKey = `tracker:${target.config.name}:${
94
- isChildStore(target) ? target.transactionMeta.update.key : `main`
94
+ isChildStore(target) ? target.transactionMeta.update.token.key : `main`
95
95
  }:${mutableState.key}`
96
96
  subscribeToState(
97
97
  target,
@@ -5,12 +5,12 @@ export interface Transceiver<
5
5
  S extends Json.Serializable,
6
6
  J extends Json.Serializable,
7
7
  > {
8
+ READONLY_VIEW: V
8
9
  do: (update: S) => number | `OUT_OF_RANGE` | null
9
10
  undo: (update: S) => void
10
11
  subscribe: (key: string, fn: (update: S) => void) => () => void
11
12
  cacheUpdateNumber: number
12
13
  getUpdateNumber: (update: S) => number
13
- view: () => V
14
14
  toJSON: () => J
15
15
  }
16
16
 
@@ -30,14 +30,16 @@ export function isTransceiver(
30
30
  value !== null &&
31
31
  `do` in value &&
32
32
  `undo` in value &&
33
- `subscribe` in value
33
+ `subscribe` in value &&
34
+ `cacheUpdateNumber` in value &&
35
+ `getUpdateNumber` in value &&
36
+ `READONLY_VIEW` in value &&
37
+ `toJSON` in value
34
38
  )
35
39
  }
36
40
 
37
41
  export type TransceiverMode = `playback` | `record` | `transaction`
38
42
 
39
- export type ViewOf<T> = T extends Transceiver<infer V, any, any> ? V : T
40
-
41
43
  export type SignalFrom<T extends Transceiver<any, any, any>> =
42
44
  T extends Transceiver<any, infer S, any> ? S : never
43
45
 
@@ -4,21 +4,22 @@ import type { Store } from "./store"
4
4
  import { isChildStore } from "./transaction/is-root-store"
5
5
 
6
6
  export type OperationProgress =
7
+ | OpenOperation<any>
7
8
  | {
8
9
  open: false
9
10
  }
10
- | {
11
- open: true
12
- done: Set<string>
13
- prev: Map<string, any>
14
- time: number
15
- token: ReadableToken<any>
16
- }
11
+ export type OpenOperation<R extends ReadableToken<any> = ReadableToken<any>> = {
12
+ open: true
13
+ token: R
14
+ done: Set<string>
15
+ prev: Map<string, any>
16
+ timestamp: number
17
+ }
17
18
 
18
- export const openOperation = (
19
+ export function openOperation(
19
20
  store: Store,
20
21
  token: ReadableToken<any>,
21
- ): number | undefined => {
22
+ ): number | (Store & { operation: OpenOperation }) {
22
23
  if (store.operation.open) {
23
24
  const rejectionTime = performance.now()
24
25
  store.logger.info(
@@ -33,7 +34,7 @@ export const openOperation = (
33
34
  open: true,
34
35
  done: new Set(),
35
36
  prev: new Map(),
36
- time: Date.now(),
37
+ timestamp: Date.now(),
37
38
  token,
38
39
  }
39
40
  store.logger.info(
@@ -41,13 +42,15 @@ export const openOperation = (
41
42
  token.type,
42
43
  token.key,
43
44
  `operation start in store "${store.config.name}"${
44
- !isChildStore(store)
45
- ? ``
46
- : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`
45
+ isChildStore(store)
46
+ ? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"`
47
+ : ``
47
48
  }`,
48
49
  )
50
+ return store as Store & { operation: OpenOperation }
49
51
  }
50
- export const closeOperation = (store: Store): void => {
52
+
53
+ export function closeOperation(store: Store): void {
51
54
  if (store.operation.open) {
52
55
  store.logger.info(
53
56
  `🔴`,
@@ -11,19 +11,19 @@ import type { Store } from "../store"
11
11
  import { Subject } from "../subject"
12
12
  import { registerSelector } from "./register-selector"
13
13
 
14
- export const createReadonlyHeldSelector = <T extends object>(
14
+ export function createReadonlyHeldSelector<T extends object>(
15
15
  store: Store,
16
16
  options: ReadonlyHeldSelectorOptions<T>,
17
17
  family: FamilyMetadata | undefined,
18
- ): ReadonlyHeldSelectorToken<T> => {
18
+ ): ReadonlyHeldSelectorToken<T> {
19
19
  const target = newest(store)
20
20
  const subject = new Subject<{ newValue: T; oldValue: T }>()
21
21
  const covered = new Set<string>()
22
22
  const { key, const: constant } = options
23
23
  const type = `readonly_held_selector` as const
24
24
  const { get, find, json } = registerSelector(target, type, key, covered)
25
- const getSelf = () => {
26
- const innerTarget = newest(store)
25
+
26
+ const getFrom = (innerTarget: Store) => {
27
27
  const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
28
28
  downstreamSelectorKey: key,
29
29
  })
@@ -34,7 +34,7 @@ export const createReadonlyHeldSelector = <T extends object>(
34
34
  }
35
35
  innerTarget.selectorAtoms.delete(key)
36
36
  options.get({ get, find, json }, constant)
37
- writeToCache(newest(store), readonlySelector, constant)
37
+ writeToCache(innerTarget, readonlySelector, constant)
38
38
  covered.clear()
39
39
  return constant
40
40
  }
@@ -43,9 +43,11 @@ export const createReadonlyHeldSelector = <T extends object>(
43
43
  ...options,
44
44
  type,
45
45
  subject,
46
+ getFrom,
46
47
  install: (s: Store) => createReadonlyHeldSelector(s, options, family),
47
- get: getSelf,
48
- ...(family && { family }),
48
+ }
49
+ if (family) {
50
+ readonlySelector.family = family
49
51
  }
50
52
  target.readonlySelectors.set(key, readonlySelector)
51
53
  store.logger.info(`✨`, type, key, `=`, constant)
@@ -11,18 +11,19 @@ import type { Store } from "../store"
11
11
  import { Subject } from "../subject"
12
12
  import { registerSelector } from "./register-selector"
13
13
 
14
- export const createReadonlyPureSelector = <T>(
14
+ export function createReadonlyPureSelector<T>(
15
15
  store: Store,
16
16
  options: ReadonlyPureSelectorOptions<T>,
17
17
  family: FamilyMetadata | undefined,
18
- ): ReadonlyPureSelectorToken<T> => {
18
+ ): ReadonlyPureSelectorToken<T> {
19
19
  const target = newest(store)
20
20
  const subject = new Subject<{ newValue: T; oldValue: T }>()
21
21
  const covered = new Set<string>()
22
22
  const key = options.key
23
23
  const type = `readonly_pure_selector` as const
24
24
  const { get, find, json } = registerSelector(target, type, key, covered)
25
- const getSelf = () => {
25
+
26
+ const getFrom = () => {
26
27
  const innerTarget = newest(store)
27
28
  const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
28
29
  downstreamSelectorKey: key,
@@ -44,9 +45,11 @@ export const createReadonlyPureSelector = <T>(
44
45
  ...options,
45
46
  type,
46
47
  subject,
48
+ getFrom,
47
49
  install: (s: Store) => createReadonlyPureSelector(s, options, family),
48
- get: getSelf,
49
- ...(family && { family }),
50
+ }
51
+ if (family) {
52
+ readonlySelector.family = family
50
53
  }
51
54
  target.readonlySelectors.set(key, readonlySelector)
52
55
  const token: ReadonlyPureSelectorToken<T> = {