atom.io 0.15.4 → 0.15.6

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 (108) hide show
  1. package/data/dist/index.cjs +20 -16
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.js +21 -17
  4. package/data/dist/index.js.map +1 -1
  5. package/data/src/join.ts +6 -2
  6. package/dist/index.cjs +21 -6
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +69 -18
  9. package/dist/index.js +157 -1
  10. package/dist/index.js.map +1 -1
  11. package/internal/dist/index.cjs +88 -146
  12. package/internal/dist/index.cjs.map +1 -1
  13. package/internal/dist/index.d.ts +29 -17
  14. package/internal/dist/index.js +79 -92
  15. package/internal/dist/index.js.map +1 -1
  16. package/internal/src/get-environment-data.ts +18 -0
  17. package/internal/src/index.ts +2 -0
  18. package/internal/src/ingest-updates/index.ts +3 -0
  19. package/internal/src/ingest-updates/ingest-atom-update.ts +14 -0
  20. package/internal/src/ingest-updates/ingest-selector-update.ts +17 -0
  21. package/internal/src/ingest-updates/ingest-transaction-update.ts +22 -0
  22. package/internal/src/mutable/tracker.ts +1 -1
  23. package/internal/src/not-found-error.ts +3 -8
  24. package/internal/src/operation.ts +3 -3
  25. package/internal/src/selector/create-read-write-selector.ts +5 -3
  26. package/internal/src/selector/create-readonly-selector.ts +2 -2
  27. package/internal/src/selector/register-selector.ts +6 -4
  28. package/internal/src/selector/update-selector-atoms.ts +2 -2
  29. package/internal/src/set-state/set-atom.ts +8 -3
  30. package/internal/src/store/deposit.ts +5 -5
  31. package/internal/src/store/withdraw-new-family-member.ts +8 -11
  32. package/internal/src/store/withdraw.ts +4 -3
  33. package/internal/src/subscribe/subscribe-to-state.ts +2 -2
  34. package/internal/src/timeline/time-travel.ts +18 -44
  35. package/internal/src/transaction/apply-transaction.ts +3 -49
  36. package/internal/src/transaction/build-transaction.ts +8 -1
  37. package/internal/src/transaction/create-transaction.ts +3 -3
  38. package/internal/src/transaction/index.ts +2 -2
  39. package/introspection/dist/index.cjs.map +1 -1
  40. package/introspection/dist/index.d.ts +4 -4
  41. package/introspection/dist/index.js.map +1 -1
  42. package/introspection/src/attach-atom-index.ts +2 -2
  43. package/introspection/src/attach-selector-index.ts +2 -2
  44. package/introspection/src/index.ts +1 -1
  45. package/package.json +8 -8
  46. package/react/dist/index.cjs.map +1 -1
  47. package/react/dist/index.d.ts +3 -3
  48. package/react/dist/index.js.map +1 -1
  49. package/react/src/store-hooks.ts +4 -4
  50. package/react-devtools/dist/index.cjs.map +1 -1
  51. package/react-devtools/dist/index.d.ts +3 -3
  52. package/react-devtools/dist/index.js.map +1 -1
  53. package/react-devtools/src/StateEditor.tsx +3 -3
  54. package/react-devtools/src/StateIndex.tsx +3 -3
  55. package/realtime-client/dist/index.cjs +67 -65
  56. package/realtime-client/dist/index.cjs.map +1 -1
  57. package/realtime-client/dist/index.d.ts +6 -5
  58. package/realtime-client/dist/index.js +62 -61
  59. package/realtime-client/dist/index.js.map +1 -1
  60. package/realtime-client/src/pull-family-member.ts +1 -1
  61. package/realtime-client/src/pull.ts +1 -1
  62. package/realtime-client/src/push.ts +2 -3
  63. package/realtime-client/src/realtime-state.ts +8 -0
  64. package/realtime-client/src/server-action.ts +65 -65
  65. package/realtime-react/dist/index.cjs +88 -52
  66. package/realtime-react/dist/index.cjs.map +1 -1
  67. package/realtime-react/dist/index.d.ts +11 -6
  68. package/realtime-react/dist/index.js +87 -51
  69. package/realtime-react/dist/index.js.map +1 -1
  70. package/realtime-react/src/on-mount.ts +23 -0
  71. package/realtime-react/src/realtime-context.tsx +12 -2
  72. package/realtime-react/src/use-pull-family-member.ts +5 -8
  73. package/realtime-react/src/use-pull-mutable-family-member.ts +4 -7
  74. package/realtime-react/src/use-pull-mutable.ts +4 -7
  75. package/realtime-react/src/use-pull.ts +5 -8
  76. package/realtime-react/src/use-push.ts +5 -9
  77. package/realtime-react/src/use-realtime-service.ts +30 -0
  78. package/realtime-react/src/use-server-action.ts +8 -8
  79. package/realtime-server/dist/index.cjs +109 -40
  80. package/realtime-server/dist/index.cjs.map +1 -1
  81. package/realtime-server/dist/index.d.ts +7 -6
  82. package/realtime-server/dist/index.js +90 -39
  83. package/realtime-server/dist/index.js.map +1 -1
  84. package/realtime-server/src/hook-composition/expose-family.ts +2 -2
  85. package/realtime-server/src/hook-composition/expose-mutable-family.ts +1 -1
  86. package/realtime-server/src/hook-composition/expose-single.ts +1 -1
  87. package/realtime-server/src/hook-composition/index.ts +2 -1
  88. package/realtime-server/src/hook-composition/receive-state.ts +2 -2
  89. package/realtime-server/src/hook-composition/receive-transaction.ts +13 -32
  90. package/realtime-server/src/hook-composition/sync-transaction.ts +92 -0
  91. package/realtime-testing/dist/index.cjs +3 -3
  92. package/realtime-testing/dist/index.cjs.map +1 -1
  93. package/realtime-testing/dist/index.js +2 -2
  94. package/realtime-testing/dist/index.js.map +1 -1
  95. package/realtime-testing/src/setup-realtime-test.tsx +4 -3
  96. package/src/atom.ts +30 -7
  97. package/src/dispose.ts +2 -2
  98. package/src/find-state.ts +64 -0
  99. package/src/get-state.ts +2 -2
  100. package/src/index.ts +15 -2
  101. package/src/logger.ts +1 -0
  102. package/src/selector.ts +16 -0
  103. package/src/set-state.ts +2 -2
  104. package/src/silo.ts +2 -2
  105. package/src/timeline.ts +2 -2
  106. package/src/transaction.ts +31 -12
  107. package/dist/chunk-RLZQ6IIY.js +0 -147
  108. package/dist/chunk-RLZQ6IIY.js.map +0 -1
@@ -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
  /**
@@ -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) {
@@ -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,
@@ -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
  }
@@ -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,6 +1,8 @@
1
+ import { setState } from "atom.io"
1
2
  import type { Atom } from "../atom"
2
3
  import { isAtomDefault, markAtomAsNotDefault } from "../atom"
3
4
  import { cacheValue } from "../caching"
5
+ import type { Transceiver } from "../mutable"
4
6
  import { markDone } from "../operation"
5
7
  import { readOrComputeValue } from "../read-or-compute-value"
6
8
  import type { Store } from "../store"
@@ -28,9 +30,12 @@ export const setAtom = <T>(
28
30
  const update = { oldValue, newValue }
29
31
  if (target.transactionMeta === null) {
30
32
  emitUpdate(atom, update, target)
31
- } else if (target.transactionMeta.phase === `applying` && target.parent) {
32
- emitUpdate(atom, update, target.parent)
33
- } else {
33
+ } else if (target.on.transactionApplying && target.parent) {
34
34
  stowUpdate(atom, update, target)
35
+ if (atom.key.startsWith(`*`)) {
36
+ const mutableKey = atom.key.slice(1)
37
+ const mutable: Transceiver<any> = target.valueMap.get(mutableKey)
38
+ mutable.do(update.newValue)
39
+ }
35
40
  }
36
41
  }
@@ -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>
@@ -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
  `👪`,
@@ -3,13 +3,14 @@ import type {
3
3
  ReadableToken,
4
4
  ReadonlySelectorToken,
5
5
  SelectorToken,
6
- StateToken,
7
6
  TimelineManageable,
8
7
  TimelineToken,
9
8
  TransactionToken,
9
+ WritableToken,
10
10
  ƒn,
11
11
  } from "atom.io"
12
12
 
13
+ import type { StateNode } from ".."
13
14
  import type { Atom } from "../atom"
14
15
  import type { ReadonlySelector, Selector } from "../selector"
15
16
  import type { Timeline } from "../timeline"
@@ -32,7 +33,7 @@ export function withdraw<T>(
32
33
  store: Store,
33
34
  ): Selector<T> | undefined
34
35
  export function withdraw<T>(
35
- token: StateToken<T>,
36
+ token: WritableToken<T>,
36
37
  store: Store,
37
38
  ): Atom<T> | Selector<T> | undefined
38
39
  export function withdraw<T>(
@@ -46,7 +47,7 @@ export function withdraw<T>(
46
47
  export function withdraw<T>(
47
48
  token: ReadableToken<T>,
48
49
  store: Store,
49
- ): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined
50
+ ): StateNode<T> | undefined
50
51
  export function withdraw<T>(
51
52
  token: TimelineToken<T>,
52
53
  store: Store,
@@ -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,21 +1,23 @@
1
- import type { KeyedStateUpdate, TimelineToken, TransactionUpdate } from "atom.io"
2
- import { setState } from "atom.io"
1
+ import type { TimelineToken } from "atom.io"
3
2
 
3
+ import {
4
+ ingestAtomUpdate,
5
+ ingestSelectorUpdate,
6
+ ingestTransactionUpdate,
7
+ } from "../ingest-updates"
4
8
  import type { Store } from "../store"
5
9
 
6
10
  export const timeTravel = (
7
- direction: `backward` | `forward`,
11
+ action: `redo` | `undo`,
8
12
  token: TimelineToken<any>,
9
13
  store: Store,
10
14
  ): void => {
11
- const action = direction === `forward` ? `redo` : `undo`
12
15
  store.logger.info(
13
- direction === `forward` ? `⏩` : `⏪`,
16
+ action === `redo` ? `⏩` : `⏪`,
14
17
  `timeline`,
15
18
  token.key,
16
19
  action,
17
20
  )
18
-
19
21
  const timelineData = store.timelines.get(token.key)
20
22
  if (!timelineData) {
21
23
  store.logger.error(
@@ -26,73 +28,45 @@ export const timeTravel = (
26
28
  )
27
29
  return
28
30
  }
29
-
30
31
  if (
31
- (direction === `forward` &&
32
- timelineData.at === timelineData.history.length) ||
33
- (direction === `backward` && timelineData.at === 0)
32
+ (action === `redo` && timelineData.at === timelineData.history.length) ||
33
+ (action === `undo` && timelineData.at === 0)
34
34
  ) {
35
35
  store.logger.warn(
36
36
  `💁`,
37
37
  `timeline`,
38
38
  token.key,
39
39
  `Failed to ${action} at the ${
40
- direction === `forward` ? `end` : `beginning`
40
+ action === `redo` ? `end` : `beginning`
41
41
  } of timeline "${token.key}". There is nothing to ${action}.`,
42
42
  )
43
43
  return
44
44
  }
45
45
 
46
- timelineData.timeTraveling =
47
- direction === `forward` ? `into_future` : `into_past`
48
- if (direction === `backward`) {
46
+ timelineData.timeTraveling = action === `redo` ? `into_future` : `into_past`
47
+ if (action === `undo`) {
49
48
  --timelineData.at
50
49
  }
51
50
 
52
51
  const update = timelineData.history[timelineData.at]
53
- const updateValues = (atomUpdate: KeyedStateUpdate<any>) => {
54
- const { key, newValue, oldValue } = atomUpdate
55
- const value = direction === `forward` ? newValue : oldValue
56
- setState({ key, type: `atom` }, value, store)
57
- }
58
- const updateValuesFromTransactionUpdate = (
59
- transactionUpdate: TransactionUpdate<any>,
60
- ) => {
61
- const updates =
62
- direction === `forward`
63
- ? transactionUpdate.updates
64
- : [...transactionUpdate.updates].reverse()
65
- for (const updateFromTransaction of updates) {
66
- if (`newValue` in updateFromTransaction) {
67
- updateValues(updateFromTransaction)
68
- } else {
69
- updateValuesFromTransactionUpdate(updateFromTransaction)
70
- }
71
- }
72
- }
52
+ const applying = action === `redo` ? `newValue` : `oldValue`
73
53
 
74
54
  switch (update.type) {
75
55
  case `atom_update`: {
76
- updateValues(update)
56
+ ingestAtomUpdate(applying, update, store)
77
57
  break
78
58
  }
79
59
  case `selector_update`: {
80
- const updates =
81
- direction === `forward`
82
- ? update.atomUpdates
83
- : [...update.atomUpdates].reverse()
84
- for (const atomUpdate of updates) {
85
- updateValues(atomUpdate)
86
- }
60
+ ingestSelectorUpdate(applying, update, store)
87
61
  break
88
62
  }
89
63
  case `transaction_update`: {
90
- updateValuesFromTransactionUpdate(update)
64
+ ingestTransactionUpdate(applying, update, store)
91
65
  break
92
66
  }
93
67
  }
94
68
 
95
- if (direction === `forward`) {
69
+ if (action === `redo`) {
96
70
  ++timelineData.at
97
71
  }
98
72
 
@@ -1,56 +1,10 @@
1
- import type { AtomToken, KeyedStateUpdate, TransactionUpdate, ƒn } from "atom.io"
2
- import { setState } from "atom.io"
1
+ import type { ƒn } from "atom.io"
3
2
 
3
+ import { ingestTransactionUpdate } from "../ingest-updates"
4
4
  import { newest } from "../lineage"
5
5
  import { withdraw } from "../store"
6
6
  import type { Store } from "../store"
7
7
 
8
- function ingestAtomUpdate(
9
- update: KeyedStateUpdate<any>,
10
- parent: Store,
11
- child: Store,
12
- ): void {
13
- const { key, newValue } = update
14
- const token: AtomToken<unknown> = { key, type: `atom` }
15
- if (!parent.valueMap.has(token.key)) {
16
- if (token.family) {
17
- const family = parent.families.get(token.family.key)
18
- if (family) {
19
- family(token.family.subKey)
20
- }
21
- } else {
22
- const newAtom = child.atoms.get(token.key)
23
- if (!newAtom) {
24
- throw new Error(
25
- `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${child.transactionMeta?.update.key}" to store "${parent.config.name}"`,
26
- )
27
- }
28
- parent.atoms.set(newAtom.key, newAtom)
29
- parent.valueMap.set(newAtom.key, newAtom.default)
30
- parent.logger.info(
31
- `🔨`,
32
- `transaction`,
33
- child.transactionMeta?.update.key ?? `???`,
34
- `Adding atom "${newAtom.key}"`,
35
- )
36
- }
37
- }
38
- setState(token, newValue, parent)
39
- }
40
- function ingestTransactionUpdate(
41
- transactionUpdate: TransactionUpdate<any>,
42
- parent: Store,
43
- child: Store,
44
- ): void {
45
- for (const update of transactionUpdate.updates) {
46
- if (`newValue` in update) {
47
- ingestAtomUpdate(update, parent, child)
48
- } else {
49
- ingestTransactionUpdate(update, parent, child)
50
- }
51
- }
52
- }
53
-
54
8
  export const applyTransaction = <ƒ extends ƒn>(
55
9
  output: ReturnType<ƒ>,
56
10
  store: Store,
@@ -102,7 +56,7 @@ export const applyTransaction = <ƒ extends ƒn>(
102
56
  )
103
57
  }
104
58
  }
105
- ingestTransactionUpdate(child.transactionMeta.update, parent, child)
59
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent)
106
60
  if (parent.transactionMeta === null) {
107
61
  const myTransaction = withdraw<ƒ>(
108
62
  { key: child.transactionMeta.update.key, type: `transaction` },
@@ -1,6 +1,9 @@
1
+ import { findInStore, getState, runTransaction, setState } from "atom.io"
2
+ import type { findState } from "atom.io"
3
+
1
4
  import { Junction } from "~/packages/rel8/junction/src"
2
5
 
3
- import { getState, runTransaction, setState } from "~/packages/atom.io/src"
6
+ import { getEnvironmentData } from "../get-environment-data"
4
7
  import { LazyMap } from "../lazy-map"
5
8
  import { newest } from "../lineage"
6
9
  import type { Store } from "../store"
@@ -9,6 +12,7 @@ export const buildTransaction = (
9
12
  key: string,
10
13
  params: any[],
11
14
  store: Store,
15
+ id?: string,
12
16
  ): void => {
13
17
  const parent = newest(store)
14
18
  const child: Store = {
@@ -40,6 +44,7 @@ export const buildTransaction = (
40
44
  time: Date.now(),
41
45
  update: {
42
46
  key,
47
+ id: id ?? Math.random().toString(36).slice(2),
43
48
  updates: [],
44
49
  params,
45
50
  output: undefined,
@@ -48,6 +53,8 @@ export const buildTransaction = (
48
53
  get: (token) => getState(token, child),
49
54
  set: (token, value) => setState(token, value, child),
50
55
  run: (token) => runTransaction(token, child),
56
+ find: ((token, key) => findInStore(token, key, child)) as typeof findState,
57
+ env: () => getEnvironmentData(child),
51
58
  },
52
59
  }
53
60
  parent.child = child
@@ -18,7 +18,7 @@ export type Transaction<ƒ extends ƒn> = {
18
18
  type: `transaction`
19
19
  install: (store: Store) => void
20
20
  subject: Subject<TransactionUpdate<ƒ>>
21
- run: (...parameters: Parameters<ƒ>) => ReturnType<ƒ>
21
+ run: (parameters: Parameters<ƒ>, id?: string) => ReturnType<ƒ>
22
22
  }
23
23
 
24
24
  export function createTransaction<ƒ extends ƒn>(
@@ -28,8 +28,8 @@ export function createTransaction<ƒ extends ƒn>(
28
28
  const newTransaction: Transaction<ƒ> = {
29
29
  key: options.key,
30
30
  type: `transaction`,
31
- run: (...params: Parameters<ƒ>) => {
32
- buildTransaction(options.key, params, store)
31
+ run: (params: Parameters<ƒ>, id?: string) => {
32
+ buildTransaction(options.key, params, store, id)
33
33
  try {
34
34
  const target = newest(store)
35
35
  // biome-ignore lint/style/noNonNullAssertion: this happens right above
@@ -1,4 +1,4 @@
1
- import type { TransactionUpdate, TransactorsWithRun, ƒn } from "atom.io"
1
+ import type { TransactionUpdate, TransactorsWithRunAndEnv, ƒn } from "atom.io"
2
2
 
3
3
  export * from "./abort-transaction"
4
4
  export * from "./apply-transaction"
@@ -12,5 +12,5 @@ export type TransactionMeta<ƒ extends ƒn> = {
12
12
  phase: `applying` | `building`
13
13
  time: number
14
14
  update: TransactionUpdate<ƒ>
15
- transactors: TransactorsWithRun
15
+ transactors: TransactorsWithRunAndEnv
16
16
  }