atom.io 0.15.3 → 0.15.5

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 (125) hide show
  1. package/data/dist/index.cjs +29 -16
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.js +30 -17
  4. package/data/dist/index.js.map +1 -1
  5. package/data/src/join.ts +15 -2
  6. package/dist/index.cjs +32 -6
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +153 -85
  9. package/dist/index.js +157 -1
  10. package/dist/index.js.map +1 -1
  11. package/internal/dist/index.cjs +98 -159
  12. package/internal/dist/index.cjs.map +1 -1
  13. package/internal/dist/index.d.ts +44 -32
  14. package/internal/dist/index.js +89 -105
  15. package/internal/dist/index.js.map +1 -1
  16. package/internal/src/atom/create-regular-atom.ts +1 -1
  17. package/internal/src/get-environment-data.ts +18 -0
  18. package/internal/src/index.ts +2 -0
  19. package/internal/src/ingest-updates/index.ts +3 -0
  20. package/internal/src/ingest-updates/ingest-atom-update.ts +14 -0
  21. package/internal/src/ingest-updates/ingest-selector-update.ts +17 -0
  22. package/internal/src/ingest-updates/ingest-transaction-update.ts +22 -0
  23. package/internal/src/mutable/tracker.ts +4 -4
  24. package/internal/src/not-found-error.ts +3 -8
  25. package/internal/src/operation.ts +4 -4
  26. package/internal/src/selector/create-read-write-selector.ts +6 -4
  27. package/internal/src/selector/create-readonly-selector.ts +3 -3
  28. package/internal/src/selector/register-selector.ts +6 -4
  29. package/internal/src/selector/update-selector-atoms.ts +2 -2
  30. package/internal/src/store/deposit.ts +5 -5
  31. package/internal/src/store/store.ts +4 -4
  32. package/internal/src/store/withdraw-new-family-member.ts +8 -11
  33. package/internal/src/store/withdraw.ts +11 -12
  34. package/internal/src/subscribe/subscribe-to-state.ts +2 -2
  35. package/internal/src/subscribe/subscribe-to-timeline.ts +4 -4
  36. package/internal/src/timeline/add-atom-to-timeline.ts +7 -7
  37. package/internal/src/timeline/create-timeline.ts +29 -21
  38. package/internal/src/timeline/time-travel.ts +19 -45
  39. package/internal/src/transaction/apply-transaction.ts +5 -51
  40. package/internal/src/transaction/build-transaction.ts +9 -2
  41. package/internal/src/transaction/create-transaction.ts +4 -4
  42. package/internal/src/transaction/index.ts +2 -2
  43. package/introspection/dist/index.cjs +9 -9
  44. package/introspection/dist/index.cjs.map +1 -1
  45. package/introspection/dist/index.d.ts +6 -6
  46. package/introspection/dist/index.js +9 -9
  47. package/introspection/dist/index.js.map +1 -1
  48. package/introspection/src/attach-atom-index.ts +4 -4
  49. package/introspection/src/attach-introspection-states.ts +2 -2
  50. package/introspection/src/attach-selector-index.ts +4 -4
  51. package/introspection/src/attach-timeline-family.ts +6 -6
  52. package/introspection/src/attach-timeline-index.ts +6 -4
  53. package/introspection/src/attach-transaction-index.ts +1 -1
  54. package/introspection/src/index.ts +1 -1
  55. package/package.json +11 -12
  56. package/react/dist/index.cjs.map +1 -1
  57. package/react/dist/index.d.ts +4 -4
  58. package/react/dist/index.js.map +1 -1
  59. package/react/src/store-hooks.ts +5 -5
  60. package/react-devtools/dist/index.cjs +7 -9
  61. package/react-devtools/dist/index.cjs.map +1 -1
  62. package/react-devtools/dist/index.d.ts +10 -265
  63. package/react-devtools/dist/index.js +7 -9
  64. package/react-devtools/dist/index.js.map +1 -1
  65. package/react-devtools/src/StateEditor.tsx +3 -3
  66. package/react-devtools/src/StateIndex.tsx +3 -3
  67. package/react-devtools/src/TimelineIndex.tsx +2 -2
  68. package/react-devtools/src/Updates.tsx +1 -1
  69. package/realtime-client/dist/index.cjs +68 -66
  70. package/realtime-client/dist/index.cjs.map +1 -1
  71. package/realtime-client/dist/index.d.ts +8 -7
  72. package/realtime-client/dist/index.js +63 -62
  73. package/realtime-client/dist/index.js.map +1 -1
  74. package/realtime-client/src/pull-family-member.ts +1 -1
  75. package/realtime-client/src/pull.ts +1 -1
  76. package/realtime-client/src/push.ts +2 -3
  77. package/realtime-client/src/realtime-state.ts +11 -3
  78. package/realtime-client/src/server-action.ts +65 -65
  79. package/realtime-react/dist/index.cjs +90 -56
  80. package/realtime-react/dist/index.cjs.map +1 -1
  81. package/realtime-react/dist/index.d.ts +11 -6
  82. package/realtime-react/dist/index.js +89 -55
  83. package/realtime-react/dist/index.js.map +1 -1
  84. package/realtime-react/src/on-mount.ts +23 -0
  85. package/realtime-react/src/realtime-context.tsx +14 -6
  86. package/realtime-react/src/use-pull-family-member.ts +5 -8
  87. package/realtime-react/src/use-pull-mutable-family-member.ts +4 -7
  88. package/realtime-react/src/use-pull-mutable.ts +4 -7
  89. package/realtime-react/src/use-pull.ts +5 -8
  90. package/realtime-react/src/use-push.ts +5 -9
  91. package/realtime-react/src/use-realtime-service.ts +30 -0
  92. package/realtime-react/src/use-server-action.ts +8 -8
  93. package/realtime-server/dist/index.cjs +109 -40
  94. package/realtime-server/dist/index.cjs.map +1 -1
  95. package/realtime-server/dist/index.d.ts +7 -6
  96. package/realtime-server/dist/index.js +90 -39
  97. package/realtime-server/dist/index.js.map +1 -1
  98. package/realtime-server/src/hook-composition/expose-family.ts +2 -2
  99. package/realtime-server/src/hook-composition/expose-mutable-family.ts +1 -1
  100. package/realtime-server/src/hook-composition/expose-single.ts +1 -1
  101. package/realtime-server/src/hook-composition/index.ts +2 -1
  102. package/realtime-server/src/hook-composition/receive-state.ts +2 -2
  103. package/realtime-server/src/hook-composition/receive-transaction.ts +13 -32
  104. package/realtime-server/src/hook-composition/sync-transaction.ts +92 -0
  105. package/realtime-testing/dist/index.cjs +3 -3
  106. package/realtime-testing/dist/index.cjs.map +1 -1
  107. package/realtime-testing/dist/index.js +2 -2
  108. package/realtime-testing/dist/index.js.map +1 -1
  109. package/realtime-testing/src/setup-realtime-test.tsx +4 -3
  110. package/src/atom.ts +30 -7
  111. package/src/dispose.ts +2 -2
  112. package/src/find-state.ts +64 -0
  113. package/src/get-state.ts +2 -2
  114. package/src/index.ts +23 -0
  115. package/src/logger.ts +1 -0
  116. package/src/selector.ts +16 -0
  117. package/src/set-state.ts +2 -2
  118. package/src/silo.ts +2 -2
  119. package/src/subscribe.ts +7 -11
  120. package/src/timeline.ts +20 -12
  121. package/src/transaction.ts +31 -12
  122. package/src/validators.ts +74 -0
  123. package/dist/chunk-K22LR3V6.js +0 -138
  124. package/dist/chunk-K22LR3V6.js.map +0 -1
  125. package/internal/src/set-state/copy-mutable-into-new-store.ts +0 -34
@@ -87,6 +87,6 @@ export function createRegularAtom<T>(
87
87
  }
88
88
  }
89
89
  }
90
- store.subject.atomCreation.next(token)
90
+ store.on.atomCreation.next(token)
91
91
  return token as AtomToken<T>
92
92
  }
@@ -0,0 +1,18 @@
1
+ import type { Store } from "./store"
2
+
3
+ export type EnvironmentData = {
4
+ runtime: `browser` | `node` | `unknown`
5
+ store: Store
6
+ }
7
+
8
+ export function getEnvironmentData(store: Store): EnvironmentData {
9
+ return {
10
+ runtime:
11
+ typeof window === `undefined`
12
+ ? typeof global === `object`
13
+ ? `node`
14
+ : `unknown`
15
+ : `browser`,
16
+ store,
17
+ }
18
+ }
@@ -6,6 +6,8 @@ export * from "./caching"
6
6
  export * from "./lineage"
7
7
  export * from "./families"
8
8
  export * from "./future"
9
+ export * from "./get-environment-data"
10
+ export * from "./ingest-updates"
9
11
  export * from "./keys"
10
12
  export * from "./lazy-map"
11
13
  export * from "./mutable"
@@ -0,0 +1,3 @@
1
+ export * from "./ingest-atom-update"
2
+ export * from "./ingest-selector-update"
3
+ export * from "./ingest-transaction-update"
@@ -0,0 +1,14 @@
1
+ import type { KeyedStateUpdate } from "atom.io"
2
+ import { setState } from "atom.io"
3
+
4
+ import type { Store } from "../store"
5
+
6
+ export function ingestAtomUpdate(
7
+ applying: `newValue` | `oldValue`,
8
+ atomUpdate: KeyedStateUpdate<any>,
9
+ store: Store,
10
+ ): void {
11
+ const { key, newValue, oldValue } = atomUpdate
12
+ const value = applying === `newValue` ? newValue : oldValue
13
+ setState({ key, type: `atom` }, value, store)
14
+ }
@@ -0,0 +1,17 @@
1
+ import type { Store } from "../store"
2
+ import type { TimelineSelectorUpdate } from "../timeline"
3
+ import { ingestAtomUpdate } from "./ingest-atom-update"
4
+
5
+ export function ingestSelectorUpdate(
6
+ applying: `newValue` | `oldValue`,
7
+ selectorUpdate: TimelineSelectorUpdate<any>,
8
+ store: Store,
9
+ ): void {
10
+ const updates =
11
+ applying === `newValue`
12
+ ? selectorUpdate.atomUpdates
13
+ : [...selectorUpdate.atomUpdates].reverse()
14
+ for (const atomUpdate of updates) {
15
+ ingestAtomUpdate(applying, atomUpdate, store)
16
+ }
17
+ }
@@ -0,0 +1,22 @@
1
+ import type { TransactionUpdate } from "atom.io"
2
+
3
+ import type { Store } from "../store"
4
+ import { ingestAtomUpdate } from "./ingest-atom-update"
5
+
6
+ export function ingestTransactionUpdate(
7
+ applying: `newValue` | `oldValue`,
8
+ transactionUpdate: TransactionUpdate<any>,
9
+ store: Store,
10
+ ): void {
11
+ const updates =
12
+ applying === `newValue`
13
+ ? transactionUpdate.updates
14
+ : [...transactionUpdate.updates].reverse()
15
+ for (const updateFromTransaction of updates) {
16
+ if (`newValue` in updateFromTransaction) {
17
+ ingestAtomUpdate(applying, updateFromTransaction, store)
18
+ } else {
19
+ ingestTransactionUpdate(applying, updateFromTransaction, store)
20
+ }
21
+ }
22
+ }
@@ -4,7 +4,7 @@ import type { Json } from "atom.io/json"
4
4
 
5
5
  import type { Store } from ".."
6
6
  import { newest, subscribeToState, subscribeToTimeline } from ".."
7
- import { createRegularAtom, deleteAtom } from "../atom"
7
+ import { createRegularAtom } from "../atom"
8
8
  import type { Transceiver } from "./transceiver"
9
9
 
10
10
  /**
@@ -63,7 +63,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
63
63
  }`,
64
64
  (update) => {
65
65
  if (target.operation.open) {
66
- const unsubscribe = target.subject.operationStatus.subscribe(
66
+ const unsubscribe = target.on.operationClose.subscribe(
67
67
  mutableState.key,
68
68
  () => {
69
69
  unsubscribe()
@@ -90,7 +90,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
90
90
  }`,
91
91
  (update) => {
92
92
  if (target.operation.open) {
93
- const unsubscribe = target.subject.operationStatus.subscribe(
93
+ const unsubscribe = target.on.operationClose.subscribe(
94
94
  mutableState.key,
95
95
  () => {
96
96
  unsubscribe()
@@ -148,7 +148,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
148
148
  }
149
149
  }
150
150
 
151
- const unsubscribe = store.subject.operationStatus.subscribe(
151
+ const unsubscribe = store.on.operationClose.subscribe(
152
152
  latestUpdateState.key,
153
153
  () => {
154
154
  unsubscribe()
@@ -1,12 +1,10 @@
1
- import type { ReadonlySelectorToken, StateToken } from "atom.io"
1
+ import type { ReadableToken } from "atom.io"
2
2
 
3
3
  import type { Store } from "./store"
4
4
 
5
5
  const capitalize = (str: string) => str[0].toUpperCase() + str.slice(1)
6
6
 
7
- function prettyPrintTokenType(
8
- token: ReadonlySelectorToken<any> | StateToken<any>,
9
- ) {
7
+ function prettyPrintTokenType(token: ReadableToken<any>) {
10
8
  if (token.type === `readonly_selector`) {
11
9
  return `Readonly Selector`
12
10
  }
@@ -14,10 +12,7 @@ function prettyPrintTokenType(
14
12
  }
15
13
 
16
14
  export class NotFoundError extends Error {
17
- public constructor(
18
- token: ReadonlySelectorToken<any> | StateToken<any>,
19
- store: Store,
20
- ) {
15
+ public constructor(token: ReadableToken<any>, store: Store) {
21
16
  super(
22
17
  `${prettyPrintTokenType(token)} "${token.key}" not found in store "${
23
18
  store.config.name
@@ -1,4 +1,4 @@
1
- import type { StateToken } from "atom.io"
1
+ import type { WritableToken } from "atom.io"
2
2
 
3
3
  import { newest } from "./lineage"
4
4
  import type { Store } from "./store"
@@ -12,11 +12,11 @@ export type OperationProgress =
12
12
  done: Set<string>
13
13
  prev: Map<string, any>
14
14
  time: number
15
- token: StateToken<any>
15
+ token: WritableToken<any>
16
16
  }
17
17
 
18
18
  export const openOperation = (
19
- token: StateToken<any>,
19
+ token: WritableToken<any>,
20
20
  store: Store,
21
21
  ): `rejection` | undefined => {
22
22
  if (store.operation.open) {
@@ -56,7 +56,7 @@ export const closeOperation = (store: Store): void => {
56
56
  )
57
57
  }
58
58
  store.operation = { open: false }
59
- store.subject.operationStatus.next(store.operation)
59
+ store.on.operationClose.next(store.operation)
60
60
  }
61
61
 
62
62
  export const isDone = (key: string, store: Store): boolean => {
@@ -17,10 +17,12 @@ export const createReadWriteSelector = <T>(
17
17
  ): SelectorToken<T> => {
18
18
  const target = newest(store)
19
19
  const subject = new Subject<{ newValue: T; oldValue: T }>()
20
+ const transactors = registerSelector(options.key, store)
21
+ const { find, get } = transactors
22
+ const readonlyTransactors = { find, get }
20
23
 
21
- const { get, set } = registerSelector(options.key, store)
22
24
  const getSelf = () => {
23
- const value = options.get({ get })
25
+ const value = options.get(readonlyTransactors)
24
26
  cacheValue(options.key, value, subject, newest(store))
25
27
  return value
26
28
  }
@@ -43,7 +45,7 @@ export const createReadWriteSelector = <T>(
43
45
  if (target.transactionMeta === null) {
44
46
  subject.next({ newValue, oldValue })
45
47
  }
46
- options.set({ get, set }, newValue)
48
+ options.set(transactors, newValue)
47
49
  }
48
50
  const mySelector: Selector<T> = {
49
51
  ...options,
@@ -64,6 +66,6 @@ export const createReadWriteSelector = <T>(
64
66
  if (family) {
65
67
  token.family = family
66
68
  }
67
- store.subject.selectorCreation.next(token)
69
+ store.on.selectorCreation.next(token)
68
70
  return token
69
71
  }
@@ -20,9 +20,9 @@ export const createReadonlySelector = <T>(
20
20
  const target = newest(store)
21
21
  const subject = new Subject<{ newValue: T; oldValue: T }>()
22
22
 
23
- const { get } = registerSelector(options.key, store)
23
+ const { get, find } = registerSelector(options.key, store)
24
24
  const getSelf = () => {
25
- const value = options.get({ get })
25
+ const value = options.get({ get, find })
26
26
  cacheValue(options.key, value, subject, store)
27
27
  return value
28
28
  }
@@ -51,6 +51,6 @@ export const createReadonlySelector = <T>(
51
51
  if (family) {
52
52
  token.family = family
53
53
  }
54
- store.subject.selectorCreation.next(token)
54
+ store.on.selectorCreation.next(token)
55
55
  return token
56
56
  }
@@ -1,4 +1,5 @@
1
- import type { Transactors } from "atom.io"
1
+ import type { Transactors, findState } from "atom.io"
2
+ import { findInStore } from "atom.io"
2
3
 
3
4
  import { newest } from "../lineage"
4
5
  import { readOrComputeValue } from "../read-or-compute-value"
@@ -43,13 +44,14 @@ export const registerSelector = (
43
44
  updateSelectorAtoms(selectorKey, dependency, store)
44
45
  return dependencyValue
45
46
  },
46
- set: (stateToken, newValue) => {
47
- const state = withdraw(stateToken, store)
47
+ set: (WritableToken, newValue) => {
48
+ const state = withdraw(WritableToken, store)
48
49
  if (state === undefined) {
49
50
  throw new Error(
50
- `State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`,
51
+ `State "${WritableToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`,
51
52
  )
52
53
  }
53
54
  setAtomOrSelector(state, newValue, store)
54
55
  },
56
+ find: ((token, key) => findInStore(token, key, store)) as typeof findState,
55
57
  })
@@ -1,4 +1,4 @@
1
- import type { ReadonlySelectorToken, StateToken } from "atom.io"
1
+ import type { ReadonlySelectorToken, WritableToken } from "atom.io"
2
2
 
3
3
  import { newest } from "../lineage"
4
4
  import type { Store } from "../store"
@@ -6,7 +6,7 @@ import { traceSelectorAtoms } from "./trace-selector-atoms"
6
6
 
7
7
  export const updateSelectorAtoms = (
8
8
  selectorKey: string,
9
- dependency: ReadonlySelectorToken<unknown> | StateToken<unknown>,
9
+ dependency: ReadonlySelectorToken<unknown> | WritableToken<unknown>,
10
10
  store: Store,
11
11
  ): void => {
12
12
  const target = newest(store)
@@ -1,26 +1,26 @@
1
1
  import type {
2
2
  AtomToken,
3
+ ReadableToken,
3
4
  ReadonlySelectorToken,
4
5
  SelectorToken,
5
- StateToken,
6
6
  TransactionToken,
7
+ WritableToken,
7
8
  ƒn,
8
9
  } from "atom.io"
9
10
 
11
+ import type { StateNode } from ".."
10
12
  import type { Atom } from "../atom"
11
13
  import type { ReadonlySelector, Selector } from "../selector"
12
14
  import type { Transaction } from "../transaction"
13
15
 
14
16
  export function deposit<T>(state: Atom<T>): AtomToken<T>
15
17
  export function deposit<T>(state: Selector<T>): SelectorToken<T>
16
- export function deposit<T>(state: Atom<T> | Selector<T>): StateToken<T>
18
+ export function deposit<T>(state: Atom<T> | Selector<T>): WritableToken<T>
17
19
  export function deposit<T>(state: ReadonlySelector<T>): ReadonlySelectorToken<T>
18
20
  export function deposit<T>(
19
21
  state: Transaction<T extends ƒn ? T : never>,
20
22
  ): TransactionToken<T>
21
- export function deposit<T>(
22
- state: Atom<T> | ReadonlySelector<T> | Selector<T>,
23
- ): ReadonlySelectorToken<T> | StateToken<T>
23
+ export function deposit<T>(state: StateNode<T>): ReadableToken<T>
24
24
  export function deposit<T>(
25
25
  state:
26
26
  | Atom<T>
@@ -47,7 +47,7 @@ export class Store implements Lineage {
47
47
  | SelectorFamily<any, any>
48
48
  >()
49
49
 
50
- public timelines = new Map<string, Timeline>()
50
+ public timelines = new Map<string, Timeline<any>>()
51
51
  public transactions = new Map<string, Transaction<ƒn>>()
52
52
 
53
53
  public atomsThatAreDefault = new Set<string>()
@@ -74,15 +74,15 @@ export class Store implements Lineage {
74
74
  },
75
75
  )
76
76
 
77
- public subject = {
77
+ public on = {
78
78
  atomCreation: new Subject<AtomToken<unknown>>(),
79
79
  selectorCreation: new Subject<
80
80
  ReadonlySelectorToken<unknown> | SelectorToken<unknown>
81
81
  >(),
82
82
  transactionCreation: new Subject<TransactionToken<ƒn>>(),
83
- timelineCreation: new Subject<TimelineToken>(),
83
+ timelineCreation: new Subject<TimelineToken<unknown>>(),
84
84
  transactionApplying: new StatefulSubject<TransactionMeta<ƒn> | null>(null),
85
- operationStatus: new Subject<OperationProgress>(),
85
+ operationClose: new Subject<OperationProgress>(),
86
86
  }
87
87
  public operation: OperationProgress = { open: false }
88
88
  public transactionMeta: TransactionMeta<ƒn> | null = null
@@ -1,10 +1,11 @@
1
1
  import type {
2
2
  AtomToken,
3
+ ReadableToken,
3
4
  ReadonlySelectorToken,
4
5
  SelectorToken,
5
- StateToken,
6
+ WritableToken,
6
7
  } from "atom.io"
7
- import type { Atom, ReadonlySelector, Selector, Store } from ".."
8
+ import type { Atom, ReadonlySelector, Selector, StateNode, Store } from ".."
8
9
  import { newest, withdraw } from ".."
9
10
 
10
11
  export function withdrawNewFamilyMember<T>(
@@ -20,21 +21,17 @@ export function withdrawNewFamilyMember<T>(
20
21
  store: Store,
21
22
  ): ReadonlySelector<T> | undefined
22
23
  export function withdrawNewFamilyMember<T>(
23
- token: StateToken<T>,
24
+ token: WritableToken<T>,
24
25
  store: Store,
25
26
  ): Atom<T> | Selector<T> | undefined
26
27
  export function withdrawNewFamilyMember<T>(
27
- token: ReadonlySelectorToken<T> | StateToken<T>,
28
+ token: ReadableToken<T>,
28
29
  store: Store,
29
- ): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined
30
+ ): StateNode<T> | undefined
30
31
  export function withdrawNewFamilyMember<T>(
31
- token:
32
- | AtomToken<T>
33
- | ReadonlySelectorToken<T>
34
- | SelectorToken<T>
35
- | StateToken<T>,
32
+ token: ReadableToken<T>,
36
33
  store: Store,
37
- ): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined {
34
+ ): StateNode<T> | undefined {
38
35
  if (token.family) {
39
36
  store.logger.info(
40
37
  `👪`,
@@ -1,13 +1,16 @@
1
1
  import type {
2
2
  AtomToken,
3
+ ReadableToken,
3
4
  ReadonlySelectorToken,
4
5
  SelectorToken,
5
- StateToken,
6
+ TimelineManageable,
6
7
  TimelineToken,
7
8
  TransactionToken,
9
+ WritableToken,
8
10
  ƒn,
9
11
  } from "atom.io"
10
12
 
13
+ import type { StateNode } from ".."
11
14
  import type { Atom } from "../atom"
12
15
  import type { ReadonlySelector, Selector } from "../selector"
13
16
  import type { Timeline } from "../timeline"
@@ -18,7 +21,7 @@ type Withdrawable<T> =
18
21
  | Atom<T>
19
22
  | ReadonlySelector<T>
20
23
  | Selector<T>
21
- | Timeline
24
+ | Timeline<T extends TimelineManageable ? T : never>
22
25
  | Transaction<T extends ƒn ? T : never>
23
26
 
24
27
  export function withdraw<T>(
@@ -30,7 +33,7 @@ export function withdraw<T>(
30
33
  store: Store,
31
34
  ): Selector<T> | undefined
32
35
  export function withdraw<T>(
33
- token: StateToken<T>,
36
+ token: WritableToken<T>,
34
37
  store: Store,
35
38
  ): Atom<T> | Selector<T> | undefined
36
39
  export function withdraw<T>(
@@ -42,19 +45,15 @@ export function withdraw<T>(
42
45
  store: Store,
43
46
  ): Transaction<T extends ƒn ? T : never> | undefined
44
47
  export function withdraw<T>(
45
- token: ReadonlySelectorToken<T> | StateToken<T>,
48
+ token: ReadableToken<T>,
46
49
  store: Store,
47
- ): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined
50
+ ): StateNode<T> | undefined
48
51
  export function withdraw<T>(
49
- token: TimelineToken,
52
+ token: TimelineToken<T>,
50
53
  store: Store,
51
- ): Timeline | undefined
54
+ ): Timeline<T extends TimelineManageable ? T : never> | undefined
52
55
  export function withdraw<T>(
53
- token:
54
- | ReadonlySelectorToken<T>
55
- | StateToken<T>
56
- | TimelineToken
57
- | TransactionToken<T>,
56
+ token: ReadableToken<T> | TimelineToken<T> | TransactionToken<T>,
58
57
  store: Store,
59
58
  ): Withdrawable<T> | undefined {
60
59
  let withdrawn: Withdrawable<T> | undefined
@@ -1,10 +1,10 @@
1
- import type { ReadonlySelectorToken, StateToken, UpdateHandler } from "atom.io"
1
+ import type { ReadableToken, UpdateHandler } from "atom.io"
2
2
  import type { Store } from "../store"
3
3
  import { withdraw, withdrawNewFamilyMember } from "../store"
4
4
  import { subscribeToRootAtoms } from "./subscribe-to-root-atoms"
5
5
 
6
6
  export function subscribeToState<T>(
7
- token: ReadonlySelectorToken<T> | StateToken<T>,
7
+ token: ReadableToken<T>,
8
8
  handleUpdate: UpdateHandler<T>,
9
9
  key: string,
10
10
  store: Store,
@@ -1,10 +1,10 @@
1
- import type { TimelineToken, TimelineUpdate } from "atom.io"
1
+ import type { TimelineManageable, TimelineToken, TimelineUpdate } from "atom.io"
2
2
  import type { Store } from "atom.io/internal"
3
3
  import { withdraw } from "atom.io/internal"
4
4
 
5
- export const subscribeToTimeline = (
6
- token: TimelineToken,
7
- handleUpdate: (update: TimelineUpdate | `redo` | `undo`) => void,
5
+ export const subscribeToTimeline = <ManagedAtom extends TimelineManageable>(
6
+ token: TimelineToken<ManagedAtom>,
7
+ handleUpdate: (update: TimelineUpdate<any> | `redo` | `undo`) => void,
8
8
  key: string,
9
9
  store: Store,
10
10
  ): (() => void) => {
@@ -13,7 +13,7 @@ import type {
13
13
 
14
14
  export const addAtomToTimeline = (
15
15
  atomToken: AtomToken<any>,
16
- tl: Timeline,
16
+ tl: Timeline<any>,
17
17
  store: Store,
18
18
  ): void => {
19
19
  let maybeAtom = withdraw(atomToken, store)
@@ -40,9 +40,8 @@ export const addAtomToTimeline = (
40
40
  store.operation.open && store.operation.token.type === `selector`
41
41
  ? store.operation.time
42
42
  : null
43
- const currentTransactionKey =
44
- target.subject.transactionApplying.state?.update.key
45
- const currentTransactionTime = target.subject.transactionApplying.state?.time
43
+ const currentTransactionKey = target.on.transactionApplying.state?.update.key
44
+ const currentTransactionTime = target.on.transactionApplying.state?.time
46
45
 
47
46
  store.logger.info(
48
47
  `⏳`,
@@ -62,7 +61,8 @@ export const addAtomToTimeline = (
62
61
  )
63
62
  if (tl.timeTraveling === null) {
64
63
  if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
65
- const mostRecentUpdate: TimelineUpdate | undefined = tl.history.at(-1)
64
+ const mostRecentUpdate: TimelineUpdate<any> | undefined =
65
+ tl.history.at(-1)
66
66
  if (mostRecentUpdate === undefined) {
67
67
  throw new Error(
68
68
  `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`,
@@ -155,7 +155,7 @@ export const addAtomToTimeline = (
155
155
  )
156
156
  }
157
157
  } else if (currentSelectorKey && currentSelectorTime) {
158
- let latestUpdate: TimelineUpdate | undefined = tl.history.at(-1)
158
+ let latestUpdate: TimelineUpdate<any> | undefined = tl.history.at(-1)
159
159
 
160
160
  if (currentSelectorTime !== tl.selectorTime) {
161
161
  latestUpdate = {
@@ -217,7 +217,7 @@ export const addAtomToTimeline = (
217
217
  if (tl.at !== tl.history.length) {
218
218
  tl.history.splice(tl.at)
219
219
  }
220
- const atomUpdate: TimelineAtomUpdate = {
220
+ const atomUpdate: TimelineAtomUpdate<any> = {
221
221
  type: `atom_update`,
222
222
  timestamp,
223
223
  key: atom.key,
@@ -1,9 +1,13 @@
1
1
  import type {
2
+ AtomFamily,
3
+ AtomToken,
2
4
  FamilyMetadata,
3
5
  StateUpdate,
6
+ TimelineManageable,
4
7
  TimelineOptions,
5
8
  TimelineToken,
6
9
  TimelineUpdate,
10
+ TokenType,
7
11
  TransactionUpdate,
8
12
  ƒn,
9
13
  } from "atom.io"
@@ -16,17 +20,18 @@ import { type Store, withdraw } from "../store"
16
20
  import { Subject } from "../subject"
17
21
  import { addAtomToTimeline } from "./add-atom-to-timeline"
18
22
 
19
- export type TimelineAtomUpdate = StateUpdate<unknown> & {
20
- key: string
21
- type: `atom_update`
22
- timestamp: number
23
- family?: FamilyMetadata
24
- }
25
- export type TimelineSelectorUpdate = {
23
+ export type TimelineAtomUpdate<ManagedAtom extends TimelineManageable> =
24
+ StateUpdate<TokenType<ManagedAtom>> & {
25
+ key: string
26
+ type: `atom_update`
27
+ timestamp: number
28
+ family?: FamilyMetadata
29
+ }
30
+ export type TimelineSelectorUpdate<ManagedAtom extends TimelineManageable> = {
26
31
  key: string
27
32
  type: `selector_update`
28
33
  timestamp: number
29
- atomUpdates: Omit<TimelineAtomUpdate, `timestamp`>[]
34
+ atomUpdates: Omit<TimelineAtomUpdate<ManagedAtom>, `timestamp`>[]
30
35
  }
31
36
  export type TimelineTransactionUpdate = TransactionUpdate<ƒn> & {
32
37
  key: string
@@ -34,31 +39,34 @@ export type TimelineTransactionUpdate = TransactionUpdate<ƒn> & {
34
39
  timestamp: number
35
40
  }
36
41
 
37
- export type Timeline = {
42
+ export type Timeline<ManagedAtom extends TimelineManageable> = {
38
43
  type: `timeline`
39
44
  key: string
40
45
  at: number
41
- shouldCapture?: (update: TimelineUpdate, timeline: Timeline) => boolean
46
+ shouldCapture?: (
47
+ update: TimelineUpdate<TimelineManageable>,
48
+ timeline: Timeline<ManagedAtom>,
49
+ ) => boolean
42
50
  timeTraveling: `into_future` | `into_past` | null
43
- history: TimelineUpdate[]
51
+ history: TimelineUpdate<ManagedAtom>[]
44
52
  selectorTime: number | null
45
53
  transactionKey: string | null
46
54
  install: (store: Store) => void
47
55
  subject: Subject<
48
- | TimelineAtomUpdate
49
- | TimelineSelectorUpdate
56
+ | TimelineAtomUpdate<ManagedAtom>
57
+ | TimelineSelectorUpdate<ManagedAtom>
50
58
  | TimelineTransactionUpdate
51
59
  | `redo`
52
60
  | `undo`
53
61
  >
54
62
  }
55
63
 
56
- export function createTimeline(
57
- options: TimelineOptions,
64
+ export function createTimeline<ManagedAtom extends TimelineManageable>(
65
+ options: TimelineOptions<ManagedAtom>,
58
66
  store: Store,
59
- data?: Timeline,
60
- ): TimelineToken {
61
- const tl: Timeline = {
67
+ data?: Timeline<ManagedAtom>,
68
+ ): TimelineToken<ManagedAtom> {
69
+ const tl: Timeline<ManagedAtom> = {
62
70
  type: `timeline`,
63
71
  key: options.key,
64
72
  at: 0,
@@ -88,7 +96,7 @@ export function createTimeline(
88
96
  continue
89
97
  }
90
98
  if (tokenOrFamily.type === `atom_family`) {
91
- let family = tokenOrFamily
99
+ let family: AtomFamily<any> = tokenOrFamily
92
100
  if (isMutable(family)) {
93
101
  family = getUpdateFamily(family, store)
94
102
  atomKey = family.key
@@ -146,10 +154,10 @@ export function createTimeline(
146
154
  }
147
155
 
148
156
  store.timelines.set(options.key, tl)
149
- const token: TimelineToken = {
157
+ const token: TimelineToken<ManagedAtom> = {
150
158
  key: timelineKey,
151
159
  type: `timeline`,
152
160
  }
153
- store.subject.timelineCreation.next(token)
161
+ store.on.timelineCreation.next(token)
154
162
  return token
155
163
  }