atom.io 0.16.3 → 0.18.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 (162) hide show
  1. package/data/dist/index.cjs +62 -40
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.d.ts +8 -2
  4. package/data/dist/index.js +64 -42
  5. package/data/dist/index.js.map +1 -1
  6. package/data/src/dict.ts +8 -4
  7. package/data/src/join.ts +74 -33
  8. package/data/src/struct-family.ts +18 -17
  9. package/dist/chunk-OEVFAUPE.js +289 -0
  10. package/dist/chunk-OEVFAUPE.js.map +1 -0
  11. package/dist/index.cjs +36 -57
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.ts +64 -53
  14. package/dist/index.js +15 -36
  15. package/dist/index.js.map +1 -1
  16. package/internal/dist/index.cjs +211 -81
  17. package/internal/dist/index.cjs.map +1 -1
  18. package/internal/dist/index.d.ts +100 -72
  19. package/internal/dist/index.js +200 -75
  20. package/internal/dist/index.js.map +1 -1
  21. package/internal/src/arbitrary.ts +3 -0
  22. package/internal/src/atom/create-regular-atom.ts +2 -3
  23. package/internal/src/caching.ts +8 -6
  24. package/internal/src/families/find-in-store.ts +16 -0
  25. package/internal/src/get-environment-data.ts +4 -7
  26. package/internal/src/get-state/get-from-store.ts +14 -0
  27. package/internal/src/get-state/index.ts +2 -0
  28. package/internal/src/{read-or-compute-value.ts → get-state/read-or-compute-value.ts} +3 -3
  29. package/internal/src/index.ts +7 -6
  30. package/internal/src/ingest-updates/ingest-atom-update.ts +2 -2
  31. package/internal/src/ingest-updates/ingest-transaction-update.ts +0 -1
  32. package/internal/src/mutable/create-mutable-atom.ts +3 -4
  33. package/internal/src/mutable/tracker.ts +18 -13
  34. package/internal/src/selector/create-standalone-selector.ts +0 -2
  35. package/internal/src/selector/register-selector.ts +1 -1
  36. package/internal/src/set-state/index.ts +1 -0
  37. package/internal/src/set-state/set-atom.ts +15 -19
  38. package/internal/src/set-state/set-into-store.ts +24 -0
  39. package/internal/src/store/store.ts +14 -2
  40. package/internal/src/store/withdraw.ts +72 -2
  41. package/internal/src/subscribe/subscribe-to-root-atoms.ts +1 -1
  42. package/internal/src/subscribe/subscribe-to-timeline.ts +2 -2
  43. package/internal/src/subscribe/subscribe-to-transaction.ts +2 -2
  44. package/internal/src/timeline/create-timeline.ts +12 -1
  45. package/internal/src/transaction/act-upon-store.ts +19 -0
  46. package/internal/src/transaction/apply-transaction.ts +7 -1
  47. package/internal/src/transaction/assign-transaction-to-continuity.ts +18 -0
  48. package/internal/src/transaction/build-transaction.ts +11 -8
  49. package/internal/src/transaction/create-transaction.ts +1 -1
  50. package/internal/src/transaction/get-epoch-number.ts +40 -0
  51. package/internal/src/transaction/index.ts +10 -1
  52. package/internal/src/transaction/set-epoch-number.ts +31 -0
  53. package/introspection/dist/index.cjs.map +1 -1
  54. package/introspection/dist/index.d.ts +3 -3
  55. package/introspection/dist/index.js.map +1 -1
  56. package/introspection/src/attach-introspection-states.ts +6 -2
  57. package/introspection/src/attach-timeline-family.ts +5 -2
  58. package/introspection/src/attach-transaction-logs.ts +2 -2
  59. package/json/dist/index.d.ts +3 -1
  60. package/json/src/index.ts +6 -2
  61. package/package.json +24 -13
  62. package/react/dist/index.cjs +3 -3
  63. package/react/dist/index.cjs.map +1 -1
  64. package/react/dist/index.d.ts +1 -1
  65. package/react/dist/index.js +5 -5
  66. package/react/dist/index.js.map +1 -1
  67. package/react/src/use-i.ts +2 -3
  68. package/react/src/use-json.ts +1 -1
  69. package/react/src/use-o.ts +3 -4
  70. package/react-devtools/dist/index.cjs +131 -134
  71. package/react-devtools/dist/index.cjs.map +1 -1
  72. package/react-devtools/dist/index.css +2 -2
  73. package/react-devtools/dist/index.css.map +1 -1
  74. package/react-devtools/dist/index.d.ts +3 -3
  75. package/react-devtools/dist/index.js +103 -106
  76. package/react-devtools/dist/index.js.map +1 -1
  77. package/react-devtools/src/StateEditor.tsx +6 -6
  78. package/react-devtools/src/StateIndex.tsx +2 -5
  79. package/react-devtools/src/TimelineIndex.tsx +3 -3
  80. package/react-devtools/src/TransactionIndex.tsx +9 -8
  81. package/react-devtools/src/Updates.tsx +1 -1
  82. package/react-devtools/src/index.ts +4 -4
  83. package/realtime/dist/index.cjs +72 -0
  84. package/realtime/dist/index.cjs.map +1 -0
  85. package/realtime/dist/index.d.ts +39 -0
  86. package/realtime/dist/index.js +68 -0
  87. package/realtime/dist/index.js.map +1 -0
  88. package/realtime/package.json +16 -0
  89. package/realtime/src/index.ts +1 -0
  90. package/realtime/src/realtime-continuity.ts +152 -0
  91. package/realtime-client/dist/index.cjs +403 -59
  92. package/realtime-client/dist/index.cjs.map +1 -1
  93. package/realtime-client/dist/index.d.ts +16 -9
  94. package/realtime-client/dist/index.js +114 -48
  95. package/realtime-client/dist/index.js.map +1 -1
  96. package/realtime-client/src/index.ts +8 -5
  97. package/realtime-client/src/{pull-family-member.ts → pull-atom-family-member.ts} +5 -5
  98. package/realtime-client/src/{pull-state.ts → pull-atom.ts} +5 -5
  99. package/realtime-client/src/{pull-mutable-family-member.ts → pull-mutable-atom-family-member.ts} +5 -5
  100. package/realtime-client/src/{pull-mutable.ts → pull-mutable-atom.ts} +5 -5
  101. package/realtime-client/src/pull-selector-family-member.ts +42 -0
  102. package/realtime-client/src/pull-selector.ts +38 -0
  103. package/realtime-client/src/realtime-client-stores/client-main-store.ts +2 -2
  104. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +7 -7
  105. package/realtime-client/src/sync-continuity.ts +321 -0
  106. package/realtime-client/src/sync-server-action.ts +22 -21
  107. package/realtime-client/src/sync-state.ts +3 -3
  108. package/realtime-react/dist/index.cjs +330 -15
  109. package/realtime-react/dist/index.cjs.map +1 -1
  110. package/realtime-react/dist/index.d.ts +26 -6
  111. package/realtime-react/dist/index.js +43 -12
  112. package/realtime-react/dist/index.js.map +1 -1
  113. package/realtime-react/src/index.ts +6 -3
  114. package/realtime-react/src/use-pull-atom-family-member.ts +21 -0
  115. package/realtime-react/src/{use-pull.ts → use-pull-atom.ts} +6 -5
  116. package/realtime-react/src/{use-pull-mutable.ts → use-pull-mutable-atom.ts} +4 -3
  117. package/realtime-react/src/use-pull-mutable-family-member.ts +9 -4
  118. package/realtime-react/src/use-pull-selector-family-member.ts +21 -0
  119. package/realtime-react/src/{use-pull-family-member.ts → use-pull-selector.ts} +7 -5
  120. package/realtime-react/src/use-push.ts +3 -2
  121. package/realtime-react/src/use-server-action.ts +3 -2
  122. package/realtime-react/src/use-sync-continuity.ts +12 -0
  123. package/realtime-react/src/use-sync-server-action.ts +3 -2
  124. package/realtime-server/dist/index.cjs +582 -256
  125. package/realtime-server/dist/index.cjs.map +1 -1
  126. package/realtime-server/dist/index.d.ts +124 -49
  127. package/realtime-server/dist/index.js +566 -249
  128. package/realtime-server/dist/index.js.map +1 -1
  129. package/realtime-server/src/index.ts +18 -2
  130. package/realtime-server/src/ipc-socket.ts +230 -0
  131. package/realtime-server/src/realtime-action-receiver.ts +8 -5
  132. package/realtime-server/src/realtime-action-synchronizer.ts +53 -35
  133. package/realtime-server/src/realtime-continuity-synchronizer.ts +247 -0
  134. package/realtime-server/src/realtime-family-provider.ts +37 -73
  135. package/realtime-server/src/realtime-mutable-family-provider.ts +26 -87
  136. package/realtime-server/src/realtime-mutable-provider.ts +3 -2
  137. package/realtime-server/src/realtime-server-stores/index.ts +3 -1
  138. package/realtime-server/src/realtime-server-stores/realtime-continuity-store.ts +90 -0
  139. package/realtime-server/src/realtime-server-stores/server-room-store.ts +97 -0
  140. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +2 -72
  141. package/realtime-server/src/realtime-server-stores/server-user-store.ts +14 -29
  142. package/realtime-server/src/realtime-state-provider.ts +3 -3
  143. package/realtime-server/src/realtime-state-receiver.ts +2 -3
  144. package/realtime-server/src/realtime-state-synchronizer.ts +3 -3
  145. package/realtime-testing/dist/index.cjs +28 -28
  146. package/realtime-testing/dist/index.cjs.map +1 -1
  147. package/realtime-testing/dist/index.js +28 -27
  148. package/realtime-testing/dist/index.js.map +1 -1
  149. package/realtime-testing/src/setup-realtime-test.tsx +38 -28
  150. package/src/atom.ts +49 -31
  151. package/src/get-state.ts +2 -11
  152. package/src/logger.ts +10 -5
  153. package/src/selector.ts +44 -25
  154. package/src/set-state.ts +1 -13
  155. package/src/silo.ts +7 -3
  156. package/src/subscribe.ts +2 -1
  157. package/src/timeline.ts +4 -4
  158. package/src/transaction.ts +13 -17
  159. package/src/validators.ts +15 -9
  160. package/dist/chunk-H4Q5FTPZ.js +0 -11
  161. package/dist/chunk-H4Q5FTPZ.js.map +0 -1
  162. package/internal/src/set-state/copy-mutable-in-transaction.ts +0 -19
@@ -0,0 +1,3 @@
1
+ export function arbitrary(random: () => number = Math.random): string {
2
+ return random().toString(36).slice(2)
3
+ }
@@ -5,9 +5,8 @@ import type {
5
5
  RegularAtomToken,
6
6
  UpdateHandler,
7
7
  } from "atom.io"
8
- import { setState } from "atom.io"
9
8
 
10
- import type { RegularAtom } from ".."
9
+ import { type RegularAtom, setIntoStore } from ".."
11
10
  import { cacheValue } from "../caching"
12
11
  import { newest } from "../lineage"
13
12
  import type { Store } from "../store"
@@ -69,7 +68,7 @@ export function createRegularAtom<T>(
69
68
  const cleanupFunctions: (() => void)[] = []
70
69
  for (const effect of options.effects) {
71
70
  const cleanup = effect({
72
- setSelf: (next) => setState(token, next, store),
71
+ setSelf: (next) => setIntoStore(token, next, store),
73
72
  onSet: (handle: UpdateHandler<T>) =>
74
73
  subscribeToState(token, handle, `effect[${effectIndex}]`, store),
75
74
  })
@@ -1,7 +1,7 @@
1
1
  import type { StateUpdate } from "atom.io"
2
- import type { ReadableState } from "."
2
+ import { type ReadableState, isChildStore } from "."
3
3
  import { Future } from "./future"
4
- import { copyMutableIfWithinTransaction } from "./set-state/copy-mutable-in-transaction"
4
+ import { copyMutableIfNeeded } from "./set-state/copy-mutable-if-needed"
5
5
  import type { Store } from "./store"
6
6
  import type { Subject } from "./subject"
7
7
 
@@ -53,10 +53,12 @@ export const readCachedValue = <T>(
53
53
  token: ReadableState<any>,
54
54
  target: Store,
55
55
  ): T => {
56
- let value = target.valueMap.get(token.key) as T
57
- if (token.type === `atom`) {
58
- value = copyMutableIfWithinTransaction(value, token, target)
59
- }
56
+ const value = target.valueMap.get(token.key) as T
57
+ // if (token.type === `mutable_atom` && isChildStore(target)) {
58
+ // const { parent } = target
59
+ // const copiedValue = copyMutableIfNeeded(token, parent, target)
60
+ // value = copiedValue
61
+ // }
60
62
  return value
61
63
  }
62
64
 
@@ -1,6 +1,8 @@
1
1
  import type { Json } from "atom.io/json"
2
2
 
3
3
  import type {
4
+ AtomFamilyToken,
5
+ AtomToken,
4
6
  MutableAtomFamilyToken,
5
7
  MutableAtomToken,
6
8
  ReadableFamilyToken,
@@ -9,6 +11,8 @@ import type {
9
11
  ReadonlySelectorToken,
10
12
  RegularAtomFamilyToken,
11
13
  RegularAtomToken,
14
+ SelectorFamilyToken,
15
+ SelectorToken,
12
16
  WritableFamilyToken,
13
17
  WritableSelectorFamilyToken,
14
18
  WritableSelectorToken,
@@ -35,6 +39,12 @@ export function findInStore<T, K extends Json.Serializable, Key extends K>(
35
39
  store: Store,
36
40
  ): RegularAtomToken<T>
37
41
 
42
+ export function findInStore<T, K extends Json.Serializable, Key extends K>(
43
+ token: AtomFamilyToken<T, K>,
44
+ key: Key,
45
+ store: Store,
46
+ ): AtomToken<T>
47
+
38
48
  export function findInStore<T, K extends Json.Serializable, Key extends K>(
39
49
  token: WritableSelectorFamilyToken<T, K>,
40
50
  key: Key,
@@ -47,6 +57,12 @@ export function findInStore<T, K extends Json.Serializable, Key extends K>(
47
57
  store: Store,
48
58
  ): ReadonlySelectorToken<T>
49
59
 
60
+ export function findInStore<T, K extends Json.Serializable, Key extends K>(
61
+ token: SelectorFamilyToken<T, K>,
62
+ key: Key,
63
+ store: Store,
64
+ ): SelectorToken<T>
65
+
50
66
  export function findInStore<T, K extends Json.Serializable, Key extends K>(
51
67
  token: WritableFamilyToken<T, K>,
52
68
  key: Key,
@@ -1,18 +1,15 @@
1
1
  import type { Store } from "./store"
2
2
 
3
3
  export type EnvironmentData = {
4
- runtime: `browser` | `node` | `unknown`
4
+ window: typeof window | undefined
5
+ global: typeof global | undefined
5
6
  store: Store
6
7
  }
7
8
 
8
9
  export function getEnvironmentData(store: Store): EnvironmentData {
9
10
  return {
10
- runtime:
11
- typeof window === `undefined`
12
- ? typeof global === `object`
13
- ? `node`
14
- : `unknown`
15
- : `browser`,
11
+ window: typeof window === `undefined` ? undefined : window,
12
+ global: typeof global === `undefined` ? undefined : global,
16
13
  store,
17
14
  }
18
15
  }
@@ -0,0 +1,14 @@
1
+ import type { ReadableToken } from "atom.io"
2
+
3
+ import { NotFoundError } from "../not-found-error"
4
+ import type { Store } from "../store"
5
+ import { withdraw, withdrawNewFamilyMember } from "../store"
6
+ import { readOrComputeValue } from "./read-or-compute-value"
7
+
8
+ export function getFromStore<T>(token: ReadableToken<T>, store: Store): T {
9
+ const state = withdraw(token, store) ?? withdrawNewFamilyMember(token, store)
10
+ if (state === undefined) {
11
+ throw new NotFoundError(token, store)
12
+ }
13
+ return readOrComputeValue(state, store)
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./get-from-store"
2
+ export * from "./read-or-compute-value"
@@ -1,6 +1,6 @@
1
- import type { ReadableState } from "."
2
- import { readCachedValue } from "./caching"
3
- import type { Store } from "./store"
1
+ import type { ReadableState } from ".."
2
+ import { readCachedValue } from "../caching"
3
+ import type { Store } from "../store"
4
4
 
5
5
  export const readOrComputeValue = <T>(
6
6
  state: ReadableState<T>,
@@ -6,18 +6,19 @@ import type { Store } from "./store"
6
6
  import type { Subject } from "./subject"
7
7
 
8
8
  export * from "./atom"
9
+ export * from "./arbitrary"
9
10
  export * from "./caching"
10
11
  export * from "./lineage"
11
12
  export * from "./families"
12
13
  export * from "./future"
13
14
  export * from "./get-environment-data"
15
+ export * from "./get-state"
14
16
  export * from "./ingest-updates"
15
17
  export * from "./keys"
16
18
  export * from "./lazy-map"
17
19
  export * from "./mutable"
18
20
  export * from "./not-found-error"
19
21
  export * from "./operation"
20
- export * from "./read-or-compute-value"
21
22
  export * from "./selector"
22
23
  export * from "./set-state"
23
24
  export * from "./store"
@@ -26,14 +27,14 @@ export * from "./subscribe"
26
27
  export * from "./timeline"
27
28
  export * from "./transaction"
28
29
 
29
- export type BaseStateData = {
30
+ export type AtomIOState = {
30
31
  key: string
31
32
  family?: FamilyMetadata
32
33
  install: (store: Store) => void
33
34
  subject: Subject<{ newValue: any; oldValue: any }>
34
35
  }
35
36
 
36
- export type RegularAtom<T> = BaseStateData & {
37
+ export type RegularAtom<T> = AtomIOState & {
37
38
  type: `atom`
38
39
  default: T | (() => T)
39
40
  cleanup?: () => void
@@ -41,7 +42,7 @@ export type RegularAtom<T> = BaseStateData & {
41
42
  export type MutableAtom<
42
43
  T extends Transceiver<any>,
43
44
  J extends Json.Serializable,
44
- > = BaseStateData &
45
+ > = AtomIOState &
45
46
  JsonInterface<T, J> & {
46
47
  type: `mutable_atom`
47
48
  default: T | (() => T)
@@ -51,12 +52,12 @@ export type Atom<T> =
51
52
  | RegularAtom<T>
52
53
  | (T extends Transceiver<any> ? MutableAtom<T, any> : never)
53
54
 
54
- export type WritableSelector<T> = BaseStateData & {
55
+ export type WritableSelector<T> = AtomIOState & {
55
56
  type: `selector`
56
57
  get: () => T
57
58
  set: (newValue: T | ((oldValue: T) => T)) => void
58
59
  }
59
- export type ReadonlySelector<T> = BaseStateData & {
60
+ export type ReadonlySelector<T> = AtomIOState & {
60
61
  type: `readonly_selector`
61
62
  get: () => T
62
63
  }
@@ -1,6 +1,6 @@
1
1
  import type { KeyedStateUpdate } from "atom.io"
2
- import { setState } from "atom.io"
3
2
 
3
+ import { setIntoStore } from "../set-state"
4
4
  import type { Store } from "../store"
5
5
 
6
6
  export function ingestAtomUpdate(
@@ -10,5 +10,5 @@ export function ingestAtomUpdate(
10
10
  ): void {
11
11
  const { key, newValue, oldValue } = atomUpdate
12
12
  const value = applying === `newValue` ? newValue : oldValue
13
- setState({ key, type: `atom` }, value, store)
13
+ setIntoStore({ key, type: `atom` }, value, store)
14
14
  }
@@ -1,7 +1,6 @@
1
1
  import type { TransactionUpdate } from "atom.io"
2
2
 
3
3
  import type { Store } from "../store"
4
- import { isRootStore } from "../transaction/is-root-store"
5
4
  import { ingestAtomUpdate } from "./ingest-atom-update"
6
5
 
7
6
  export function ingestTransactionUpdate(
@@ -4,12 +4,11 @@ import type {
4
4
  MutableAtomOptions,
5
5
  MutableAtomToken,
6
6
  } from "atom.io"
7
- import { setState } from "atom.io"
8
7
  import type { Json } from "atom.io/json"
9
8
  import { selectJson } from "atom.io/json"
10
9
 
11
- import { type MutableAtom, cacheValue } from ".."
12
- import { createRegularAtom, markAtomAsDefault } from "../atom"
10
+ import { type MutableAtom, cacheValue, setIntoStore } from ".."
11
+ import { markAtomAsDefault } from "../atom"
13
12
  import { newest } from "../lineage"
14
13
  import { type Store, deposit } from "../store"
15
14
  import { Subject } from "../subject"
@@ -70,7 +69,7 @@ export function createMutableAtom<
70
69
  const cleanupFunctions: (() => void)[] = []
71
70
  for (const effect of options.effects) {
72
71
  const cleanup = effect({
73
- setSelf: (next) => setState(token, next, store),
72
+ setSelf: (next) => setIntoStore(token, next, store),
74
73
  onSet: (handle: UpdateHandler<T>) =>
75
74
  subscribeToState(token, handle, `effect[${effectIndex}]`, store),
76
75
  })
@@ -1,11 +1,16 @@
1
1
  import type { FamilyMetadata, MutableAtomToken, RegularAtomToken } from "atom.io"
2
- import { getState, setState } from "atom.io"
3
2
  import type { Json } from "atom.io/json"
4
3
 
5
4
  import type { Store } from ".."
6
- import { newest, subscribeToState, subscribeToTimeline } from ".."
5
+ import {
6
+ getFromStore,
7
+ newest,
8
+ setIntoStore,
9
+ subscribeToState,
10
+ subscribeToTimeline,
11
+ } from ".."
7
12
  import { createRegularAtom } from "../atom"
8
- import { isChildStore, isRootStore } from "../transaction/is-root-store"
13
+ import { isChildStore } from "../transaction/is-root-store"
9
14
  import type { Transceiver } from "./transceiver"
10
15
 
11
16
  /**
@@ -57,7 +62,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
57
62
  const subscriptionKey = `tracker:${target.config.name}:${
58
63
  isChildStore(target) ? target.transactionMeta.update.key : `main`
59
64
  }:${mutableState.key}`
60
- const originalInnerValue = getState(mutableState, target)
65
+ const originalInnerValue = getFromStore(mutableState, target)
61
66
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
62
67
  subscriptionKey,
63
68
  (update) => {
@@ -66,12 +71,12 @@ export class Tracker<Mutable extends Transceiver<any>> {
66
71
  subscriptionKey,
67
72
  () => {
68
73
  unsubscribe()
69
- setState(latestUpdateState, update, target)
74
+ setIntoStore(latestUpdateState, update, target)
70
75
  },
71
76
  )
72
77
  } else {
73
- setState(mutableState, (current) => current, target)
74
- setState(latestUpdateState, update, target)
78
+ setIntoStore(mutableState, (current) => current, target)
79
+ setIntoStore(latestUpdateState, update, target)
75
80
  }
76
81
  },
77
82
  )
@@ -88,12 +93,12 @@ export class Tracker<Mutable extends Transceiver<any>> {
88
93
  subscriptionKey,
89
94
  () => {
90
95
  unsubscribe()
91
- setState(latestUpdateState, update, target)
96
+ setIntoStore(latestUpdateState, update, target)
92
97
  },
93
98
  )
94
99
  } else {
95
- setState(mutableState, (current) => current, target)
96
- setState(latestUpdateState, update, target)
100
+ setIntoStore(mutableState, (current) => current, target)
101
+ setIntoStore(latestUpdateState, update, target)
97
102
  }
98
103
  },
99
104
  )
@@ -126,7 +131,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
126
131
  { key: timelineId, type: `timeline` },
127
132
  (update) => {
128
133
  unsubscribe()
129
- setState(
134
+ setIntoStore(
130
135
  mutableState,
131
136
  (transceiver) => {
132
137
  if (update === `redo` && newValue) {
@@ -150,12 +155,12 @@ export class Tracker<Mutable extends Transceiver<any>> {
150
155
  subscriptionKey,
151
156
  () => {
152
157
  unsubscribe()
153
- const mutable = getState(mutableState, target)
158
+ const mutable = getFromStore(mutableState, target)
154
159
  const updateNumber =
155
160
  newValue === null ? -1 : mutable.getUpdateNumber(newValue)
156
161
  const eventOffset = updateNumber - mutable.cacheUpdateNumber
157
162
  if (newValue && eventOffset === 1) {
158
- setState(
163
+ setIntoStore(
159
164
  mutableState,
160
165
  (transceiver) => (transceiver.do(newValue), transceiver),
161
166
  target,
@@ -1,5 +1,4 @@
1
1
  import type {
2
- FamilyMetadata,
3
2
  ReadonlySelectorOptions,
4
3
  ReadonlySelectorToken,
5
4
  WritableSelectorOptions,
@@ -7,7 +6,6 @@ import type {
7
6
  } from "atom.io"
8
7
 
9
8
  import type { Store } from "../store"
10
- import type { Subject } from "../subject"
11
9
  import { createReadonlySelector } from "./create-readonly-selector"
12
10
  import { createWritableSelector } from "./create-writable-selector"
13
11
 
@@ -1,8 +1,8 @@
1
1
  import type { Transactors, findState } from "atom.io"
2
2
 
3
3
  import { findInStore } from "../families"
4
+ import { readOrComputeValue } from "../get-state/read-or-compute-value"
4
5
  import { newest } from "../lineage"
5
- import { readOrComputeValue } from "../read-or-compute-value"
6
6
  import { setAtomOrSelector } from "../set-state"
7
7
  import type { Store } from "../store"
8
8
  import { withdraw, withdrawNewFamilyMember } from "../store"
@@ -1,2 +1,3 @@
1
1
  export * from "./become"
2
2
  export * from "./set-atom-or-selector"
3
+ export * from "./set-into-store"
@@ -1,13 +1,13 @@
1
1
  import type { Atom } from ".."
2
2
  import { isAtomDefault, markAtomAsNotDefault } from "../atom"
3
3
  import { cacheValue } from "../caching"
4
+ import { readOrComputeValue } from "../get-state/read-or-compute-value"
4
5
  import type { Transceiver } from "../mutable"
5
6
  import { markDone } from "../operation"
6
- import { readOrComputeValue } from "../read-or-compute-value"
7
7
  import type { Store } from "../store"
8
- import { isRootStore } from "../transaction/is-root-store"
8
+ import { isChildStore, isRootStore } from "../transaction/is-root-store"
9
9
  import { become } from "./become"
10
- import { copyMutableIfWithinTransaction } from "./copy-mutable-in-transaction"
10
+ import { copyMutableIfNeeded } from "./copy-mutable-if-needed"
11
11
  import { emitUpdate } from "./emit-update"
12
12
  import { evictDownStream } from "./evict-downstream"
13
13
  import { stowUpdate } from "./stow-update"
@@ -18,7 +18,12 @@ export const setAtom = <T>(
18
18
  target: Store,
19
19
  ): void => {
20
20
  const oldValue = readOrComputeValue(atom, target)
21
- let newValue = copyMutableIfWithinTransaction(oldValue, atom, target)
21
+ let newValue = oldValue
22
+ if (atom.type === `mutable_atom` && isChildStore(target)) {
23
+ const { parent } = target
24
+ const copiedValue = copyMutableIfNeeded(atom, parent, target)
25
+ newValue = copiedValue
26
+ }
22
27
  newValue = become(next)(newValue)
23
28
  target.logger.info(`📝`, `atom`, atom.key, `set to`, newValue)
24
29
  newValue = cacheValue(atom.key, newValue, atom.subject, target)
@@ -36,22 +41,13 @@ export const setAtom = <T>(
36
41
  } else if (atom.key.startsWith(`*`)) {
37
42
  const mutableKey = atom.key.slice(1)
38
43
  const mutableAtom = target.atoms.get(mutableKey) as Atom<any>
39
- let mutable: Transceiver<any> = target.valueMap.get(mutableKey)
40
- mutable = copyMutableIfWithinTransaction(mutable, mutableAtom, target)
41
- const output = mutable.do(update.newValue)
42
- if (output !== null) {
43
- target.logger.warn(
44
- `❌`,
45
- `mutable_atom`,
46
- mutableKey,
47
- `could not be updated.`,
48
- typeof output === `number`
49
- ? `Expected update number ${
50
- mutable.cacheUpdateNumber + 1
51
- }, but got ${output}`
52
- : output,
53
- )
44
+ let transceiver: Transceiver<any> = target.valueMap.get(mutableKey)
45
+ if (atom.type === `mutable_atom` && isChildStore(target)) {
46
+ const { parent } = target
47
+ const copiedValue = copyMutableIfNeeded(atom, parent, target)
48
+ transceiver = copiedValue
54
49
  }
50
+ transceiver.do(update.newValue)
55
51
  }
56
52
  }
57
53
  }
@@ -0,0 +1,24 @@
1
+ import type { WritableToken } from "atom.io"
2
+
3
+ import { NotFoundError } from "../not-found-error"
4
+ import { closeOperation, openOperation } from "../operation"
5
+ import type { Store } from "../store"
6
+ import { withdraw, withdrawNewFamilyMember } from "../store"
7
+ import { setAtomOrSelector } from "./set-atom-or-selector"
8
+
9
+ export function setIntoStore<T, New extends T>(
10
+ token: WritableToken<T>,
11
+ value: New | ((oldValue: T) => New),
12
+ store: Store,
13
+ ): void {
14
+ const rejection = openOperation(token, store)
15
+ if (rejection) {
16
+ return
17
+ }
18
+ const state = withdraw(token, store) ?? withdrawNewFamilyMember(token, store)
19
+ if (state === undefined) {
20
+ throw new NotFoundError(token, store)
21
+ }
22
+ setAtomOrSelector(state, value, store)
23
+ closeOperation(store)
24
+ }
@@ -32,6 +32,7 @@ import type {
32
32
  TransactionEpoch,
33
33
  TransactionProgress,
34
34
  } from "../transaction"
35
+ import { isRootStore } from "../transaction/is-root-store"
35
36
 
36
37
  export class Store implements Lineage {
37
38
  public parent: Store | null = null
@@ -93,7 +94,11 @@ export class Store implements Lineage {
93
94
  }
94
95
  public operation: OperationProgress = { open: false }
95
96
  public transactionMeta: TransactionEpoch | TransactionProgress<ƒn> = {
96
- epoch: -1,
97
+ epoch: new Map<string, number>(),
98
+ actionContinuities: new Junction({
99
+ between: [`continuity`, `action`],
100
+ cardinality: `1:n`,
101
+ }),
97
102
  }
98
103
 
99
104
  public config: {
@@ -121,7 +126,14 @@ export class Store implements Lineage {
121
126
  if (store !== null) {
122
127
  this.valueMap = new Map(store?.valueMap)
123
128
  this.operation = { ...store?.operation }
124
- this.transactionMeta = { ...store?.transactionMeta }
129
+ if (isRootStore(store)) {
130
+ this.transactionMeta = {
131
+ epoch: new Map(store?.transactionMeta.epoch),
132
+ actionContinuities: new Junction(
133
+ store?.transactionMeta.actionContinuities.toJSON(),
134
+ ),
135
+ }
136
+ }
125
137
 
126
138
  this.config = {
127
139
  ...store?.config,
@@ -1,18 +1,31 @@
1
1
  import type {
2
+ AtomFamily,
3
+ AtomFamilyToken,
2
4
  AtomToken,
5
+ MutableAtomFamily,
6
+ MutableAtomFamilyToken,
3
7
  MutableAtomToken,
4
8
  ReadableToken,
9
+ ReadonlySelectorFamily,
10
+ ReadonlySelectorFamilyToken,
5
11
  ReadonlySelectorToken,
12
+ RegularAtomFamily,
13
+ RegularAtomFamilyToken,
6
14
  RegularAtomToken,
15
+ SelectorFamily,
16
+ SelectorFamilyToken,
7
17
  SelectorToken,
8
18
  TimelineManageable,
9
19
  TimelineToken,
10
20
  TransactionToken,
21
+ WritableSelectorFamily,
22
+ WritableSelectorFamilyToken,
11
23
  WritableSelectorToken,
12
24
  WritableToken,
13
25
  ƒn,
14
26
  } from "atom.io"
15
27
 
28
+ import type { Json } from "atom.io/json"
16
29
  import type {
17
30
  Atom,
18
31
  MutableAtom,
@@ -28,7 +41,24 @@ import type { Timeline } from "../timeline"
28
41
  import type { Transaction } from "../transaction"
29
42
  import type { Store } from "./store"
30
43
 
31
- export type Withdrawable = ReadableState<any> | Timeline<any> | Transaction<any>
44
+ export type Withdrawable =
45
+ | Atom<any>
46
+ | AtomFamily<any, any>
47
+ | MutableAtom<any, any>
48
+ | MutableAtomFamily<any, any, any>
49
+ | ReadableState<any>
50
+ | ReadableState<any>
51
+ | ReadonlySelector<any>
52
+ | ReadonlySelectorFamily<any, any>
53
+ | RegularAtom<any>
54
+ | RegularAtomFamily<any, any>
55
+ | Selector<any>
56
+ | SelectorFamily<any, any>
57
+ | Timeline<any>
58
+ | Transaction<any>
59
+ | WritableSelector<any>
60
+ | WritableSelectorFamily<any, any>
61
+ | WritableState<any>
32
62
 
33
63
  export function withdraw<T>(
34
64
  token: RegularAtomToken<T>,
@@ -62,6 +92,36 @@ export function withdraw<T>(
62
92
  token: ReadableToken<T>,
63
93
  store: Store,
64
94
  ): ReadableState<T> | undefined
95
+
96
+ export function withdraw<T, K extends Json.Serializable>(
97
+ token: RegularAtomFamilyToken<T, K>,
98
+ store: Store,
99
+ ): RegularAtomFamily<T, K> | undefined
100
+ export function withdraw<
101
+ T extends Transceiver<any>,
102
+ J extends Json.Serializable,
103
+ K extends Json.Serializable,
104
+ >(
105
+ token: MutableAtomFamilyToken<T, J, K>,
106
+ store: Store,
107
+ ): MutableAtomFamily<T, J, K> | undefined
108
+ export function withdraw<T, K extends Json.Serializable>(
109
+ token: AtomFamilyToken<T>,
110
+ store: Store,
111
+ ): AtomFamily<T, any> | undefined
112
+ export function withdraw<T, K extends Json.Serializable>(
113
+ token: ReadonlySelectorFamilyToken<T, K>,
114
+ store: Store,
115
+ ): ReadonlySelectorFamily<T, any> | undefined
116
+ export function withdraw<T, K extends Json.Serializable>(
117
+ token: WritableSelectorFamilyToken<T, K>,
118
+ store: Store,
119
+ ): WritableSelectorFamily<T, any> | undefined
120
+ export function withdraw<T, K extends Json.Serializable>(
121
+ token: SelectorFamilyToken<T, K>,
122
+ store: Store,
123
+ ): SelectorFamily<T, any> | undefined
124
+
65
125
  export function withdraw<T>(
66
126
  token: TransactionToken<T>,
67
127
  store: Store,
@@ -72,11 +132,15 @@ export function withdraw<T>(
72
132
  ): Timeline<T extends TimelineManageable ? T : never> | undefined
73
133
  export function withdraw<T>(
74
134
  token:
135
+ | RegularAtomFamilyToken<T, any>
75
136
  | RegularAtomToken<T>
137
+ | SelectorFamilyToken<T, any>
76
138
  | SelectorToken<T>
77
139
  | TimelineToken<T>
78
140
  | TransactionToken<T>
79
- | (T extends Transceiver<any> ? MutableAtomToken<T, any> : never),
141
+ | (T extends Transceiver<any>
142
+ ? MutableAtomFamilyToken<T, any, any> | MutableAtomToken<T, any>
143
+ : never),
80
144
  store: Store,
81
145
  ): Withdrawable | undefined {
82
146
  let withdrawn: Withdrawable | undefined
@@ -93,6 +157,12 @@ export function withdraw<T>(
93
157
  case `readonly_selector`:
94
158
  withdrawn = target.readonlySelectors.get(token.key)
95
159
  break
160
+ case `atom_family`:
161
+ case `mutable_atom_family`:
162
+ case `selector_family`:
163
+ case `readonly_selector_family`:
164
+ withdrawn = target.families.get(token.key)
165
+ break
96
166
  case `timeline`:
97
167
  withdrawn = target.timelines.get(token.key)
98
168
  break
@@ -1,6 +1,6 @@
1
1
  import type { Selector } from ".."
2
+ import { readOrComputeValue } from "../get-state/read-or-compute-value"
2
3
  import { newest } from "../lineage"
3
- import { readOrComputeValue } from "../read-or-compute-value"
4
4
  import { traceAllSelectorAtoms } from "../selector"
5
5
  import type { Store } from "../store"
6
6
  import { recallState } from "./recall-state"
@@ -1,6 +1,6 @@
1
1
  import type { TimelineManageable, TimelineToken, TimelineUpdate } from "atom.io"
2
- import type { Store } from "atom.io/internal"
3
- import { withdraw } from "atom.io/internal"
2
+ import type { Store } from ".."
3
+ import { withdraw } from ".."
4
4
 
5
5
  export const subscribeToTimeline = <ManagedAtom extends TimelineManageable>(
6
6
  token: TimelineToken<ManagedAtom>,
@@ -1,6 +1,6 @@
1
1
  import type { TransactionToken, TransactionUpdateHandler, ƒn } from "atom.io"
2
- import type { Store } from "atom.io/internal"
3
- import { withdraw } from "atom.io/internal"
2
+ import type { Store } from ".."
3
+ import { withdraw } from ".."
4
4
 
5
5
  export const subscribeToTransaction = <ƒ extends ƒn>(
6
6
  token: TransactionToken<ƒ>,