atom.io 0.34.2 → 0.36.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 (113) hide show
  1. package/dist/eslint-plugin/index.d.ts +2 -18
  2. package/dist/eslint-plugin/index.d.ts.map +1 -1
  3. package/dist/eslint-plugin/index.js +4 -141
  4. package/dist/eslint-plugin/index.js.map +1 -1
  5. package/dist/internal/index.d.ts +74 -77
  6. package/dist/internal/index.d.ts.map +1 -1
  7. package/dist/internal/index.js +197 -202
  8. package/dist/internal/index.js.map +1 -1
  9. package/dist/json/index.d.ts +9 -17
  10. package/dist/json/index.d.ts.map +1 -1
  11. package/dist/json/index.js +3 -33
  12. package/dist/json/index.js.map +1 -1
  13. package/dist/main/index.d.ts +689 -795
  14. package/dist/main/index.d.ts.map +1 -1
  15. package/dist/main/index.js +55 -23
  16. package/dist/main/index.js.map +1 -1
  17. package/dist/react/index.d.ts +4 -4
  18. package/dist/react/index.d.ts.map +1 -1
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/react-devtools/index.d.ts.map +1 -1
  21. package/dist/react-devtools/index.js +10 -10
  22. package/dist/react-devtools/index.js.map +1 -1
  23. package/dist/realtime/index.d.ts +4 -4
  24. package/dist/realtime/index.d.ts.map +1 -1
  25. package/dist/realtime/index.js +5 -11
  26. package/dist/realtime/index.js.map +1 -1
  27. package/dist/realtime-client/index.d.ts +2 -2
  28. package/dist/realtime-client/index.d.ts.map +1 -1
  29. package/dist/realtime-client/index.js +10 -10
  30. package/dist/realtime-client/index.js.map +1 -1
  31. package/dist/realtime-react/index.d.ts +2 -2
  32. package/dist/realtime-react/index.d.ts.map +1 -1
  33. package/dist/realtime-react/index.js.map +1 -1
  34. package/dist/realtime-server/index.d.ts +18 -18
  35. package/dist/realtime-server/index.d.ts.map +1 -1
  36. package/dist/realtime-server/index.js +13 -19
  37. package/dist/realtime-server/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.map +1 -1
  41. package/package.json +7 -7
  42. package/src/eslint-plugin/index.ts +0 -1
  43. package/src/eslint-plugin/rules/explicit-state-types.ts +8 -1
  44. package/src/eslint-plugin/rules/index.ts +0 -1
  45. package/src/internal/atom/create-regular-atom.ts +1 -0
  46. package/src/internal/atom/dispose-atom.ts +1 -0
  47. package/src/internal/atom/index.ts +0 -1
  48. package/src/internal/families/find-in-store.ts +4 -5
  49. package/src/internal/families/get-family-of-token.ts +4 -5
  50. package/src/internal/families/index.ts +0 -1
  51. package/src/internal/families/init-family-member.ts +3 -4
  52. package/src/internal/families/seek-in-store.ts +4 -5
  53. package/src/internal/get-state/read-or-compute-value.ts +14 -2
  54. package/src/internal/index.ts +116 -96
  55. package/src/internal/ingest-updates/ingest-creation-disposal.ts +18 -15
  56. package/src/internal/ingest-updates/ingest-selector-update.ts +9 -5
  57. package/src/internal/join/get-internal-relations-from-store.ts +2 -2
  58. package/src/internal/join/join-internal.ts +6 -18
  59. package/src/internal/molecule.ts +1 -0
  60. package/src/internal/mutable/create-mutable-atom-family.ts +37 -21
  61. package/src/internal/mutable/create-mutable-atom.ts +17 -13
  62. package/src/internal/mutable/get-json-family.ts +7 -6
  63. package/src/internal/mutable/get-json-token.ts +6 -13
  64. package/src/internal/mutable/get-update-family.ts +7 -8
  65. package/src/internal/mutable/get-update-token.ts +5 -9
  66. package/src/internal/mutable/tracker-family.ts +10 -13
  67. package/src/internal/mutable/tracker.ts +66 -90
  68. package/src/internal/mutable/transceiver.ts +35 -8
  69. package/src/internal/selector/dispose-selector.ts +9 -9
  70. package/src/internal/selector/register-selector.ts +2 -2
  71. package/src/internal/set-state/copy-mutable-if-needed.ts +8 -6
  72. package/src/internal/set-state/reset-atom-or-selector.ts +11 -4
  73. package/src/internal/set-state/set-atom.ts +1 -1
  74. package/src/internal/store/counterfeit.ts +3 -4
  75. package/src/internal/store/deposit.ts +7 -9
  76. package/src/internal/store/store.ts +2 -2
  77. package/src/internal/store/withdraw.ts +7 -11
  78. package/src/json/entries.ts +7 -7
  79. package/src/json/index.ts +0 -2
  80. package/src/main/atom.ts +68 -127
  81. package/src/main/dispose-state.ts +4 -6
  82. package/src/main/find-state.ts +6 -13
  83. package/src/main/get-state.ts +0 -2
  84. package/src/main/index.ts +1 -176
  85. package/src/main/join.ts +2 -9
  86. package/src/main/logger.ts +7 -7
  87. package/src/main/reset-state.ts +0 -2
  88. package/src/main/selector.ts +5 -72
  89. package/src/main/set-state.ts +1 -4
  90. package/src/main/silo.ts +14 -5
  91. package/src/main/subscribe.ts +0 -7
  92. package/src/main/timeline.ts +1 -18
  93. package/src/main/tokens.ts +245 -0
  94. package/src/main/transaction.ts +28 -60
  95. package/src/main/validators.ts +2 -2
  96. package/src/react/use-json.ts +15 -25
  97. package/src/react-devtools/store.ts +61 -45
  98. package/src/realtime/shared-room-store.ts +12 -25
  99. package/src/realtime-client/pull-mutable-atom-family-member.ts +5 -9
  100. package/src/realtime-client/pull-mutable-atom.ts +5 -9
  101. package/src/realtime-react/use-pull-mutable-atom.ts +3 -5
  102. package/src/realtime-react/use-pull-mutable-family-member.ts +3 -4
  103. package/src/realtime-server/realtime-mutable-family-provider.ts +3 -4
  104. package/src/realtime-server/realtime-mutable-provider.ts +2 -3
  105. package/src/realtime-server/realtime-server-stores/server-room-external-actions.ts +6 -5
  106. package/src/realtime-server/realtime-server-stores/server-user-store.ts +9 -18
  107. package/src/transceivers/set-rtx/set-rtx.ts +1 -1
  108. package/src/eslint-plugin/rules/synchronous-selector-dependencies.ts +0 -140
  109. package/src/eslint-plugin/walk.ts +0 -81
  110. package/src/internal/atom/create-standalone-atom.ts +0 -39
  111. package/src/internal/families/create-atom-family.ts +0 -38
  112. package/src/json/select-json-family.ts +0 -55
  113. package/src/json/select-json.ts +0 -19
@@ -1,3 +1,2 @@
1
1
  export * from "./create-regular-atom"
2
- export * from "./create-standalone-atom"
3
2
  export * from "./dispose-atom"
@@ -16,7 +16,7 @@ import type {
16
16
  WritablePureSelectorToken,
17
17
  WritableToken,
18
18
  } from "atom.io"
19
- import { type Canonical, type Json, stringifyJson } from "atom.io/json"
19
+ import { type Canonical, stringifyJson } from "atom.io/json"
20
20
 
21
21
  import { newest } from "../lineage"
22
22
  import type { Transceiver } from "../mutable"
@@ -25,15 +25,14 @@ import { initFamilyMemberInStore } from "./init-family-member"
25
25
  import { seekInStore } from "./seek-in-store"
26
26
 
27
27
  export function findInStore<
28
- T extends Transceiver<any>,
29
- J extends Json.Serializable,
28
+ T extends Transceiver<any, any>,
30
29
  K extends Canonical,
31
30
  Key extends K,
32
31
  >(
33
32
  store: Store,
34
- token: MutableAtomFamilyToken<T, J, K>,
33
+ token: MutableAtomFamilyToken<T, K>,
35
34
  key: Key,
36
- ): MutableAtomToken<T, J, K>
35
+ ): MutableAtomToken<T, K>
37
36
 
38
37
  export function findInStore<T, K extends Canonical, Key extends K>(
39
38
  store: Store,
@@ -12,19 +12,18 @@ import type {
12
12
  WritablePureSelectorToken,
13
13
  WritableToken,
14
14
  } from "atom.io"
15
- import type { Canonical, Json } from "atom.io/json"
15
+ import type { Canonical } from "atom.io/json"
16
16
 
17
17
  import type { Transceiver } from "../mutable"
18
18
  import type { Store } from "../store"
19
19
 
20
20
  export function getFamilyOfToken<
21
- T extends Transceiver<any>,
22
- J extends Json.Serializable,
21
+ T extends Transceiver<any, any>,
23
22
  K extends Canonical,
24
23
  >(
25
24
  store: Store,
26
- token: MutableAtomToken<T, J, K>,
27
- ): MutableAtomFamilyToken<T, J, K> | undefined
25
+ token: MutableAtomToken<T, K>,
26
+ ): MutableAtomFamilyToken<T, K> | undefined
28
27
 
29
28
  export function getFamilyOfToken<T, K extends Canonical>(
30
29
  store: Store,
@@ -1,4 +1,3 @@
1
- export * from "./create-atom-family"
2
1
  export * from "./create-readonly-pure-selector-family"
3
2
  export * from "./create-readonly-pure-selector-family"
4
3
  export * from "./create-regular-atom-family"
@@ -25,15 +25,14 @@ import type { Store } from "../store"
25
25
  import { isChildStore, isRootStore } from "../transaction"
26
26
 
27
27
  export function initFamilyMemberInStore<
28
- T extends Transceiver<any>,
29
- J extends Json.Serializable,
28
+ T extends Transceiver<any, any>,
30
29
  K extends Canonical,
31
30
  Key extends K,
32
31
  >(
33
32
  store: Store,
34
- token: MutableAtomFamilyToken<T, J, K>,
33
+ token: MutableAtomFamilyToken<T, K>,
35
34
  key: Key,
36
- ): MutableAtomToken<T, J, K>
35
+ ): MutableAtomToken<T, K>
37
36
 
38
37
  export function initFamilyMemberInStore<T, K extends Canonical, Key extends K>(
39
38
  store: Store,
@@ -16,7 +16,7 @@ import type {
16
16
  WritablePureSelectorToken,
17
17
  WritableToken,
18
18
  } from "atom.io"
19
- import type { Canonical, Json } from "atom.io/json"
19
+ import type { Canonical } from "atom.io/json"
20
20
  import { stringifyJson } from "atom.io/json"
21
21
 
22
22
  import type { Molecule, ReadableState } from ".."
@@ -25,15 +25,14 @@ import type { Transceiver } from "../mutable"
25
25
  import { deposit, type Store } from "../store"
26
26
 
27
27
  export function seekInStore<
28
- T extends Transceiver<any>,
29
- J extends Json.Serializable,
28
+ T extends Transceiver<any, any>,
30
29
  K extends Canonical,
31
30
  Key extends K,
32
31
  >(
33
32
  store: Store,
34
- token: MutableAtomFamilyToken<T, J, K>,
33
+ token: MutableAtomFamilyToken<T, K>,
35
34
  key: Key,
36
- ): MutableAtomToken<T, J, K> | undefined
35
+ ): MutableAtomToken<T, K> | undefined
37
36
 
38
37
  export function seekInStore<T, K extends Canonical, Key extends K>(
39
38
  store: Store,
@@ -16,8 +16,7 @@ export const readOrComputeValue = <T>(
16
16
  case `writable_pure_selector`:
17
17
  target.logger.info(`🧮`, state.type, state.key, `computing value`)
18
18
  return state.get()
19
- case `atom`:
20
- case `mutable_atom`: {
19
+ case `atom`: {
21
20
  const def = state.default
22
21
  let defaultValue: T
23
22
  if (def instanceof Function) {
@@ -40,5 +39,18 @@ export const readOrComputeValue = <T>(
40
39
  )
41
40
  return cachedValue
42
41
  }
42
+ case `mutable_atom`: {
43
+ const Ctor = state.class
44
+ const instance = new Ctor()
45
+ const cachedValue = cacheValue(target, state.key, instance, state.subject)
46
+ target.logger.info(
47
+ `💁`,
48
+ `mutable_atom`,
49
+ state.key,
50
+ `could not find cached value; using default`,
51
+ instance,
52
+ )
53
+ return cachedValue
54
+ }
43
55
  }
44
56
  }
@@ -16,13 +16,14 @@ import type {
16
16
  WritablePureSelectorFamilyToken,
17
17
  WritablePureSelectorToken,
18
18
  } from "atom.io"
19
- import type { Canonical, Json, JsonInterface } from "atom.io/json"
19
+ import type { Canonical } from "atom.io/json"
20
20
 
21
- import type { Transceiver } from "./mutable"
21
+ import type { ConstructorOf, Transceiver } from "./mutable"
22
22
  import type { Store } from "./store"
23
23
  import type { Subject } from "./subject"
24
24
  import type { Timeline } from "./timeline"
25
25
  import type { Transaction } from "./transaction"
26
+ import type { Flat } from "./utility-types"
26
27
 
27
28
  export * from "./arbitrary"
28
29
  export * from "./atom"
@@ -61,45 +62,52 @@ export type AtomIOState = {
61
62
  install: (store: Store) => void
62
63
  subject: Subject<{ newValue: any; oldValue: any }>
63
64
  }
64
-
65
- export type RegularAtom<T> = AtomIOState & {
66
- type: `atom`
67
- default: T | (() => T)
68
- cleanup?: () => void
69
- }
70
- export type MutableAtom<
71
- T extends Transceiver<any>,
72
- J extends Json.Serializable,
73
- > = AtomIOState &
74
- JsonInterface<T, J> & {
65
+ export type RegularAtom<T> = Flat<
66
+ AtomIOState & {
67
+ type: `atom`
68
+ default: T | (() => T)
69
+ cleanup?: () => void
70
+ }
71
+ >
72
+ export type MutableAtom<T extends Transceiver<any, any>> = Flat<
73
+ AtomIOState & {
75
74
  type: `mutable_atom`
76
- default: () => T
75
+ class: ConstructorOf<T>
77
76
  cleanup?: () => void
78
77
  }
78
+ >
79
79
  export type Atom<T> =
80
80
  | RegularAtom<T>
81
- | (T extends Transceiver<any> ? MutableAtom<T, any> : never)
81
+ | (T extends Transceiver<any, any> ? MutableAtom<T> : never)
82
82
 
83
- export type WritableHeldSelector<T> = AtomIOState & {
84
- type: `writable_held_selector`
85
- const: T
86
- get: () => T
87
- set: (newValue: T | ((oldValue: T) => T)) => void
88
- }
89
- export type ReadonlyHeldSelector<T> = AtomIOState & {
90
- type: `readonly_held_selector`
91
- const: T
92
- get: () => T
93
- }
94
- export type WritablePureSelector<T> = AtomIOState & {
95
- type: `writable_pure_selector`
96
- get: () => T
97
- set: (newValue: T | ((oldValue: T) => T)) => void
98
- }
99
- export type ReadonlyPureSelector<T> = AtomIOState & {
100
- type: `readonly_pure_selector`
101
- get: () => T
102
- }
83
+ export type WritableHeldSelector<T> = Flat<
84
+ AtomIOState & {
85
+ type: `writable_held_selector`
86
+ const: T
87
+ get: () => T
88
+ set: (newValue: T | ((oldValue: T) => T)) => void
89
+ }
90
+ >
91
+ export type ReadonlyHeldSelector<T> = Flat<
92
+ AtomIOState & {
93
+ type: `readonly_held_selector`
94
+ const: T
95
+ get: () => T
96
+ }
97
+ >
98
+ export type WritablePureSelector<T> = Flat<
99
+ AtomIOState & {
100
+ type: `writable_pure_selector`
101
+ get: () => T
102
+ set: (newValue: T | ((oldValue: T) => T)) => void
103
+ }
104
+ >
105
+ export type ReadonlyPureSelector<T> = Flat<
106
+ AtomIOState & {
107
+ type: `readonly_pure_selector`
108
+ get: () => T
109
+ }
110
+ >
103
111
  export type ReadonlySelector<T> =
104
112
  | ReadonlyHeldSelector<T>
105
113
  | ReadonlyPureSelector<T>
@@ -118,89 +126,101 @@ export type WritableState<T> = Atom<T> | WritableSelector<T>
118
126
  export type ReadableState<T> = Atom<T> | Selector<T>
119
127
 
120
128
  // biome-ignore format: intersection
121
- export type RegularAtomFamily<T, K extends Canonical> =
129
+ export type RegularAtomFamily<T, K extends Canonical> =
122
130
  & RegularAtomFamilyToken<T, K>
123
131
  & {
124
132
  (key: K): RegularAtomToken<T>
125
- subject: Subject<StateCreation<AtomToken<T>> | StateDisposal<AtomToken<T>>>
126
133
  install: (store: Store) => void
127
134
  internalRoles: string[] | undefined
135
+ subject: Subject<StateCreation<AtomToken<T>> | StateDisposal<AtomToken<T>>>
128
136
  }
129
137
 
130
138
  // biome-ignore format: intersection
131
139
  export type MutableAtomFamily<
132
- T extends Transceiver<any>,
133
- J extends Json.Serializable,
134
- K extends Canonical,
135
- > =
136
- & JsonInterface<T, J>
137
- & MutableAtomFamilyToken<T, J, K>
138
- & {
139
- (key: K): MutableAtomToken<T, J>
140
- subject: Subject<StateCreation<MutableAtomToken<T, J>> | StateDisposal<MutableAtomToken<T, J>>>
141
- install: (store: Store) => void
142
- internalRoles: string[] | undefined
143
- }
140
+ // C extends TransceiverConstructor<any,any>,
141
+ T extends Transceiver<any,any>,
142
+ K extends Canonical,
143
+ > =
144
+ & Flat<
145
+ & MutableAtomFamilyToken<T, K>
146
+ & {
147
+ install: (store: Store) => void
148
+ internalRoles: string[] | undefined
149
+ subject: Subject<
150
+ | StateCreation<MutableAtomToken<T>>
151
+ | StateDisposal<MutableAtomToken<T>>
152
+ >
153
+ }
154
+ >
155
+ & ((key: K) => MutableAtomToken<T>)
144
156
 
145
157
  export type AtomFamily<T, K extends Canonical = Canonical> =
146
- | MutableAtomFamily<T extends Transceiver<any> ? T : never, any, K>
158
+ | MutableAtomFamily<T extends Transceiver<any, any> ? T : never, K>
147
159
  | RegularAtomFamily<T, K>
148
160
 
149
161
  // biome-ignore format: intersection
150
- export type WritablePureSelectorFamily<T, K extends Canonical> =
151
- & WritablePureSelectorFamilyToken<T, K>
152
- & ((key: K) => WritablePureSelectorToken<T>)
153
- & {
154
- default: (key: K) => T,
155
- subject: Subject<
156
- | StateCreation<WritablePureSelectorToken<T>>
157
- | StateDisposal<WritablePureSelectorToken<T>>
158
- >
159
- install: (store: Store) => void
160
- internalRoles : string[] | undefined
161
- }
162
+ export type WritablePureSelectorFamily<T, K extends Canonical> =
163
+ & Flat<
164
+ & WritablePureSelectorFamilyToken<T, K>
165
+ & {
166
+ default: (key: K) => T,
167
+ install: (store: Store) => void
168
+ internalRoles: string[] | undefined
169
+ subject: Subject<
170
+ | StateCreation<WritablePureSelectorToken<T>>
171
+ | StateDisposal<WritablePureSelectorToken<T>>
172
+ >
173
+ }
174
+ >
175
+ & ((key: K) => WritablePureSelectorToken<T>)
162
176
 
163
177
  // biome-ignore format: intersection
164
- export type WritableHeldSelectorFamily<T , K extends Canonical> =
165
- & WritableHeldSelectorFamilyToken<T, K>
166
- & ((key: K) => WritableHeldSelectorToken<T>)
167
- & {
168
- default: (key: K) => T,
169
- subject: Subject<
170
- | StateCreation<WritableHeldSelectorToken<T>>
171
- | StateDisposal<WritableHeldSelectorToken<T>>
172
- >
173
- install: (store: Store) => void
174
- internalRoles : string[] | undefined
175
- }
178
+ export type WritableHeldSelectorFamily<T , K extends Canonical> =
179
+ & Flat<
180
+ & WritableHeldSelectorFamilyToken<T, K>
181
+ & {
182
+ default: (key: K) => T,
183
+ install: (store: Store) => void
184
+ internalRoles: string[] | undefined
185
+ subject: Subject<
186
+ | StateCreation<WritableHeldSelectorToken<T>>
187
+ | StateDisposal<WritableHeldSelectorToken<T>>
188
+ >
189
+ }
190
+ >
191
+ & ((key: K) => WritableHeldSelectorToken<T>)
176
192
 
177
193
  // biome-ignore format: intersection
178
- export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
179
- & ReadonlyPureSelectorFamilyToken<T, K>
194
+ export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
195
+ & Flat<
196
+ & ReadonlyPureSelectorFamilyToken<T, K>
197
+ & {
198
+ default: (key: K) => T,
199
+ install: (store: Store) => void
200
+ internalRoles: string[] | undefined
201
+ subject: Subject<
202
+ | StateCreation<ReadonlyPureSelectorToken<T>>
203
+ | StateDisposal<ReadonlyPureSelectorToken<T>>
204
+ >
205
+ }
206
+ >
180
207
  & ((key: K) => ReadonlyPureSelectorToken<T>)
181
- & {
182
- default: (key: K) => T,
183
- subject: Subject<
184
- | StateCreation<ReadonlyPureSelectorToken<T>>
185
- | StateDisposal<ReadonlyPureSelectorToken<T>>
186
- >
187
- install: (store: Store) => void
188
- internalRoles : string[] | undefined
189
- }
190
208
 
191
209
  // biome-ignore format: intersection
192
- export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
193
- & ReadonlyHeldSelectorFamilyToken<T, K>
210
+ export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
211
+ & Flat<
212
+ & ReadonlyHeldSelectorFamilyToken<T, K>
213
+ & {
214
+ default: (key: K) => T,
215
+ install: (store: Store) => void
216
+ internalRoles: string[] | undefined
217
+ subject: Subject<
218
+ | StateCreation<ReadonlyHeldSelectorToken<T>>
219
+ | StateDisposal<ReadonlyHeldSelectorToken<T>>
220
+ >
221
+ }
222
+ >
194
223
  & ((key: K) => ReadonlyHeldSelectorToken<T>)
195
- & {
196
- default: (key: K) => T,
197
- subject: Subject<
198
- | StateCreation<ReadonlyHeldSelectorToken<T>>
199
- | StateDisposal<ReadonlyHeldSelectorToken<T>>
200
- >
201
- install: (store: Store) => void
202
- internalRoles : string[] | undefined
203
- }
204
224
 
205
225
  export type PureSelectorFamily<T, K extends Canonical> =
206
226
  | ReadonlyPureSelectorFamily<T, K>
@@ -115,25 +115,28 @@ export function ingestMoleculeTransferEvent(
115
115
  switch (applying) {
116
116
  case `newValue`:
117
117
  {
118
- const provenance = update.to.length === 1 ? update.to[0] : update.to
119
- claimWithinStore<any, any, any>(
120
- store,
121
- provenance,
122
- update.key,
123
- `exclusive`,
124
- )
118
+ for (const newOwner of update.to) {
119
+ claimWithinStore<any, any, any>(
120
+ store,
121
+ newOwner,
122
+ update.key,
123
+ update.exclusive ? `exclusive` : undefined,
124
+ )
125
+ }
125
126
  }
126
127
  break
127
128
  case `oldValue`:
128
129
  {
129
- const provenance =
130
- update.from.length === 1 ? update.from[0] : update.from
131
- claimWithinStore<any, any, any>(
132
- store,
133
- provenance,
134
- update.key,
135
- `exclusive`,
136
- )
130
+ let exclusivity: `exclusive` | undefined = `exclusive`
131
+ for (const previousOwner of update.from) {
132
+ claimWithinStore<any, any, any>(
133
+ store,
134
+ previousOwner,
135
+ update.key,
136
+ exclusivity,
137
+ )
138
+ exclusivity = undefined
139
+ }
137
140
  }
138
141
  break
139
142
  }
@@ -1,5 +1,7 @@
1
+ import type { TimelineManageable } from "atom.io"
2
+
1
3
  import type { Store } from "../store"
2
- import type { TimelineSelectorUpdate } from "../timeline"
4
+ import type { TimelineAtomUpdate, TimelineSelectorUpdate } from "../timeline"
3
5
  import { ingestAtomUpdate } from "./ingest-atom-update"
4
6
 
5
7
  export function ingestSelectorUpdate(
@@ -7,10 +9,12 @@ export function ingestSelectorUpdate(
7
9
  selectorUpdate: TimelineSelectorUpdate<any>,
8
10
  store: Store,
9
11
  ): void {
10
- const updates =
11
- applying === `newValue`
12
- ? selectorUpdate.atomUpdates
13
- : selectorUpdate.atomUpdates.toReversed()
12
+ let updates: Omit<TimelineAtomUpdate<TimelineManageable>, `timestamp`>[]
13
+ if (applying === `newValue`) {
14
+ updates = selectorUpdate.atomUpdates
15
+ } else {
16
+ updates = selectorUpdate.atomUpdates.toReversed()
17
+ }
14
18
  for (const atomUpdate of updates) {
15
19
  ingestAtomUpdate(applying, atomUpdate, store)
16
20
  }
@@ -1,5 +1,5 @@
1
1
  import type { JoinToken, MutableAtomFamilyToken } from "atom.io"
2
- import type { SetRTX, SetRTXJson } from "atom.io/transceivers/set-rtx"
2
+ import type { SetRTX } from "atom.io/transceivers/set-rtx"
3
3
 
4
4
  import type { Store } from "../store"
5
5
  import { getJoin } from "./get-join"
@@ -7,7 +7,7 @@ import { getJoin } from "./get-join"
7
7
  export function getInternalRelationsFromStore(
8
8
  token: JoinToken<any, any, any, any, any, any>,
9
9
  store: Store,
10
- ): MutableAtomFamilyToken<SetRTX<string>, SetRTXJson<string>, string> {
10
+ ): MutableAtomFamilyToken<SetRTX<string>, string> {
11
11
  const myJoin = getJoin(token, store)
12
12
  const family = myJoin.core.relatedKeysAtoms
13
13
  return family
@@ -8,13 +8,12 @@ import type {
8
8
  ReadonlyPureSelectorFamilyToken,
9
9
  RegularAtomFamilyToken,
10
10
  setState,
11
- SetterToolkit,
12
11
  Write,
12
+ WriterToolkit,
13
13
  } from "atom.io"
14
14
  import { Anarchy } from "atom.io"
15
15
  import type { Canonical, Json, stringified } from "atom.io/json"
16
16
  import { stringifyJson } from "atom.io/json"
17
- import type { SetRTXJson } from "atom.io/transceivers/set-rtx"
18
17
  import { SetRTX } from "atom.io/transceivers/set-rtx"
19
18
 
20
19
  import { capitalize } from "../capitalize"
@@ -129,7 +128,7 @@ export class Join<
129
128
  BSide
130
129
  > = CompoundTypedKey<`content`, ASide, BSide>,
131
130
  > {
132
- private toolkit: SetterToolkit
131
+ private toolkit: WriterToolkit
133
132
  public options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>
134
133
  public defaultContent: Content | undefined
135
134
  public molecules: Map<string, Molecule<any>> = new Map()
@@ -143,14 +142,10 @@ export class Join<
143
142
  Content
144
143
  >
145
144
  public core: {
146
- relatedKeysAtoms: MutableAtomFamilyToken<
147
- SetRTX<string>,
148
- SetRTXJson<string>,
149
- string
150
- >
145
+ relatedKeysAtoms: MutableAtomFamilyToken<SetRTX<string>, string>
151
146
  }
152
147
  public transact(
153
- toolkit: SetterToolkit,
148
+ toolkit: WriterToolkit,
154
149
  run: (join: Join<ASide, AType, BSide, BType, Cardinality, Content>) => void,
155
150
  ): void {
156
151
  const originalToolkit = this.toolkit
@@ -193,18 +188,11 @@ export class Join<
193
188
 
194
189
  const aSide: ASide = options.between[0]
195
190
  const bSide: BSide = options.between[1]
196
- const relatedKeysAtoms = createMutableAtomFamily<
197
- SetRTX<string>,
198
- SetRTXJson<string>,
199
- string
200
- >(
191
+ const relatedKeysAtoms = createMutableAtomFamily<SetRTX<string>, string>(
201
192
  store,
202
193
  {
203
194
  key: `${options.key}/relatedKeys`,
204
- default: () => new SetRTX(),
205
- mutable: true,
206
- fromJson: (json) => SetRTX.fromJSON(json),
207
- toJson: (set) => set.toJSON(),
195
+ class: SetRTX,
208
196
  },
209
197
  [`join`, `relations`],
210
198
  )
@@ -293,6 +293,7 @@ export function claimWithinStore<
293
293
  const transferEvent: MoleculeTransfer = {
294
294
  type: `molecule_transfer`,
295
295
  key: molecule.key,
296
+ exclusive: Boolean(exclusive),
296
297
  from: priorProvenance,
297
298
  to: [newProvenanceMolecule.key],
298
299
  }
@@ -7,30 +7,33 @@ import type {
7
7
  StateCreation,
8
8
  StateDisposal,
9
9
  } from "atom.io"
10
- import type { Canonical, Json } from "atom.io/json"
11
- import { selectJsonFamily, stringifyJson } from "atom.io/json"
10
+ import type { Canonical } from "atom.io/json"
11
+ import { stringifyJson } from "atom.io/json"
12
12
 
13
- import { type MutableAtomFamily, prettyPrintTokenType } from ".."
13
+ import {
14
+ createWritablePureSelectorFamily,
15
+ type MutableAtomFamily,
16
+ prettyPrintTokenType,
17
+ } from ".."
14
18
  import { newest } from "../lineage"
15
19
  import { createMutableAtom } from "../mutable"
16
20
  import type { Store } from "../store"
17
21
  import { Subject } from "../subject"
18
22
  import { FamilyTracker } from "./tracker-family"
19
- import type { Transceiver } from "./transceiver"
23
+ import type { AsJSON, Transceiver } from "./transceiver"
20
24
 
21
25
  export function createMutableAtomFamily<
22
- T extends Transceiver<any>,
23
- J extends Json.Serializable,
26
+ T extends Transceiver<any, any>,
24
27
  K extends Canonical,
25
28
  >(
26
29
  store: Store,
27
- options: MutableAtomFamilyOptions<T, J, K>,
30
+ options: MutableAtomFamilyOptions<T, K>,
28
31
  internalRoles?: string[],
29
- ): MutableAtomFamilyToken<T, J, K> {
30
- const familyToken = {
32
+ ): MutableAtomFamilyToken<T, K> {
33
+ const familyToken: MutableAtomFamilyToken<T & Transceiver<any, any>, K> = {
31
34
  key: options.key,
32
35
  type: `mutable_atom_family`,
33
- } as const satisfies MutableAtomFamilyToken<T, J, K>
36
+ }
34
37
 
35
38
  const existing = store.families.get(options.key)
36
39
  if (existing) {
@@ -45,21 +48,18 @@ export function createMutableAtomFamily<
45
48
  }
46
49
 
47
50
  const subject = new Subject<
48
- StateCreation<MutableAtomToken<T, J>> | StateDisposal<MutableAtomToken<T, J>>
51
+ StateCreation<MutableAtomToken<T>> | StateDisposal<MutableAtomToken<T>>
49
52
  >()
50
53
 
51
- const familyFunction = (key: K): MutableAtomToken<T, J> => {
54
+ const familyFunction = (key: K): MutableAtomToken<T> => {
52
55
  const subKey = stringifyJson(key)
53
56
  const family: FamilyMetadata = { key: options.key, subKey }
54
57
  const fullKey = `${options.key}(${subKey})`
55
58
  const target = newest(store)
56
59
 
57
- const individualOptions: MutableAtomOptions<T, J> = {
60
+ const individualOptions: MutableAtomOptions<T> = {
58
61
  key: fullKey,
59
- default: () => options.default(key),
60
- toJson: options.toJson,
61
- fromJson: options.fromJson,
62
- mutable: true,
62
+ class: options.class,
63
63
  }
64
64
  if (options.effects) {
65
65
  individualOptions.effects = options.effects(key)
@@ -74,13 +74,29 @@ export function createMutableAtomFamily<
74
74
  const atomFamily = Object.assign(familyFunction, familyToken, {
75
75
  subject,
76
76
  install: (s: Store) => createMutableAtomFamily(s, options),
77
- toJson: options.toJson,
78
- fromJson: options.fromJson,
79
77
  internalRoles,
80
- }) satisfies MutableAtomFamily<T, J, K>
78
+ }) satisfies MutableAtomFamily<T, K>
81
79
 
82
80
  store.families.set(options.key, atomFamily)
83
- selectJsonFamily(store, atomFamily, options)
81
+
82
+ createWritablePureSelectorFamily<AsJSON<T>, K>(
83
+ store,
84
+ {
85
+ key: `${options.key}:JSON`,
86
+ get:
87
+ (key) =>
88
+ ({ get }) =>
89
+ get(familyToken, key).toJSON(),
90
+ set:
91
+ (key) =>
92
+ ({ set }, newValue) => {
93
+ set(familyToken, key, options.class.fromJSON(newValue))
94
+ },
95
+ },
96
+ [`mutable`, `json`],
97
+ )
98
+
84
99
  new FamilyTracker(atomFamily, store)
100
+
85
101
  return familyToken
86
102
  }