atom.io 0.15.4 → 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.
- package/data/dist/index.cjs +20 -16
- package/data/dist/index.cjs.map +1 -1
- package/data/dist/index.js +21 -17
- package/data/dist/index.js.map +1 -1
- package/data/src/join.ts +6 -2
- package/dist/index.cjs +21 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +69 -18
- package/dist/index.js +157 -1
- package/dist/index.js.map +1 -1
- package/internal/dist/index.cjs +82 -143
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.ts +29 -17
- package/internal/dist/index.js +73 -89
- package/internal/dist/index.js.map +1 -1
- package/internal/src/get-environment-data.ts +18 -0
- package/internal/src/index.ts +2 -0
- package/internal/src/ingest-updates/index.ts +3 -0
- package/internal/src/ingest-updates/ingest-atom-update.ts +14 -0
- package/internal/src/ingest-updates/ingest-selector-update.ts +17 -0
- package/internal/src/ingest-updates/ingest-transaction-update.ts +22 -0
- package/internal/src/mutable/tracker.ts +1 -1
- package/internal/src/not-found-error.ts +3 -8
- package/internal/src/operation.ts +3 -3
- package/internal/src/selector/create-read-write-selector.ts +5 -3
- package/internal/src/selector/create-readonly-selector.ts +2 -2
- package/internal/src/selector/register-selector.ts +6 -4
- package/internal/src/selector/update-selector-atoms.ts +2 -2
- package/internal/src/store/deposit.ts +5 -5
- package/internal/src/store/withdraw-new-family-member.ts +8 -11
- package/internal/src/store/withdraw.ts +4 -3
- package/internal/src/subscribe/subscribe-to-state.ts +2 -2
- package/internal/src/timeline/time-travel.ts +18 -44
- package/internal/src/transaction/apply-transaction.ts +3 -49
- package/internal/src/transaction/build-transaction.ts +8 -1
- package/internal/src/transaction/create-transaction.ts +3 -3
- package/internal/src/transaction/index.ts +2 -2
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.d.ts +4 -4
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-atom-index.ts +2 -2
- package/introspection/src/attach-selector-index.ts +2 -2
- package/introspection/src/index.ts +1 -1
- package/package.json +8 -8
- package/react/dist/index.cjs.map +1 -1
- package/react/dist/index.d.ts +3 -3
- package/react/dist/index.js.map +1 -1
- package/react/src/store-hooks.ts +4 -4
- package/react-devtools/dist/index.cjs.map +1 -1
- package/react-devtools/dist/index.d.ts +3 -3
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/src/StateEditor.tsx +3 -3
- package/react-devtools/src/StateIndex.tsx +3 -3
- package/realtime-client/dist/index.cjs +67 -65
- package/realtime-client/dist/index.cjs.map +1 -1
- package/realtime-client/dist/index.d.ts +6 -5
- package/realtime-client/dist/index.js +62 -61
- package/realtime-client/dist/index.js.map +1 -1
- package/realtime-client/src/pull-family-member.ts +1 -1
- package/realtime-client/src/pull.ts +1 -1
- package/realtime-client/src/push.ts +2 -3
- package/realtime-client/src/realtime-state.ts +8 -0
- package/realtime-client/src/server-action.ts +65 -65
- package/realtime-react/dist/index.cjs +88 -52
- package/realtime-react/dist/index.cjs.map +1 -1
- package/realtime-react/dist/index.d.ts +11 -6
- package/realtime-react/dist/index.js +87 -51
- package/realtime-react/dist/index.js.map +1 -1
- package/realtime-react/src/on-mount.ts +23 -0
- package/realtime-react/src/realtime-context.tsx +12 -2
- package/realtime-react/src/use-pull-family-member.ts +5 -8
- package/realtime-react/src/use-pull-mutable-family-member.ts +4 -7
- package/realtime-react/src/use-pull-mutable.ts +4 -7
- package/realtime-react/src/use-pull.ts +5 -8
- package/realtime-react/src/use-push.ts +5 -9
- package/realtime-react/src/use-realtime-service.ts +30 -0
- package/realtime-react/src/use-server-action.ts +8 -8
- package/realtime-server/dist/index.cjs +109 -40
- package/realtime-server/dist/index.cjs.map +1 -1
- package/realtime-server/dist/index.d.ts +7 -6
- package/realtime-server/dist/index.js +90 -39
- package/realtime-server/dist/index.js.map +1 -1
- package/realtime-server/src/hook-composition/expose-family.ts +2 -2
- package/realtime-server/src/hook-composition/expose-mutable-family.ts +1 -1
- package/realtime-server/src/hook-composition/expose-single.ts +1 -1
- package/realtime-server/src/hook-composition/index.ts +2 -1
- package/realtime-server/src/hook-composition/receive-state.ts +2 -2
- package/realtime-server/src/hook-composition/receive-transaction.ts +13 -32
- package/realtime-server/src/hook-composition/sync-transaction.ts +92 -0
- package/realtime-testing/dist/index.cjs +3 -3
- package/realtime-testing/dist/index.cjs.map +1 -1
- package/realtime-testing/dist/index.js +2 -2
- package/realtime-testing/dist/index.js.map +1 -1
- package/realtime-testing/src/setup-realtime-test.tsx +4 -3
- package/src/atom.ts +30 -7
- package/src/dispose.ts +2 -2
- package/src/find-state.ts +64 -0
- package/src/get-state.ts +2 -2
- package/src/index.ts +15 -2
- package/src/logger.ts +1 -0
- package/src/selector.ts +16 -0
- package/src/set-state.ts +2 -2
- package/src/silo.ts +2 -2
- package/src/timeline.ts +2 -2
- package/src/transaction.ts +31 -12
- package/dist/chunk-RLZQ6IIY.js +0 -147
- 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
|
+
}
|
package/internal/src/index.ts
CHANGED
|
@@ -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,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
|
|
7
|
+
import { createRegularAtom } from "../atom"
|
|
8
8
|
import type { Transceiver } from "./transceiver"
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import type {
|
|
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 {
|
|
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:
|
|
15
|
+
token: WritableToken<any>
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const openOperation = (
|
|
19
|
-
token:
|
|
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(
|
|
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(
|
|
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: (
|
|
47
|
-
const state = withdraw(
|
|
47
|
+
set: (WritableToken, newValue) => {
|
|
48
|
+
const state = withdraw(WritableToken, store)
|
|
48
49
|
if (state === undefined) {
|
|
49
50
|
throw new Error(
|
|
50
|
-
`State "${
|
|
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,
|
|
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> |
|
|
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>):
|
|
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
|
-
|
|
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:
|
|
24
|
+
token: WritableToken<T>,
|
|
24
25
|
store: Store,
|
|
25
26
|
): Atom<T> | Selector<T> | undefined
|
|
26
27
|
export function withdrawNewFamilyMember<T>(
|
|
27
|
-
token:
|
|
28
|
+
token: ReadableToken<T>,
|
|
28
29
|
store: Store,
|
|
29
|
-
):
|
|
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
|
-
):
|
|
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:
|
|
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
|
-
):
|
|
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 {
|
|
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:
|
|
7
|
+
token: ReadableToken<T>,
|
|
8
8
|
handleUpdate: UpdateHandler<T>,
|
|
9
9
|
key: string,
|
|
10
10
|
store: Store,
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
(
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
56
|
+
ingestAtomUpdate(applying, update, store)
|
|
77
57
|
break
|
|
78
58
|
}
|
|
79
59
|
case `selector_update`: {
|
|
80
|
-
|
|
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
|
-
|
|
64
|
+
ingestTransactionUpdate(applying, update, store)
|
|
91
65
|
break
|
|
92
66
|
}
|
|
93
67
|
}
|
|
94
68
|
|
|
95
|
-
if (
|
|
69
|
+
if (action === `redo`) {
|
|
96
70
|
++timelineData.at
|
|
97
71
|
}
|
|
98
72
|
|
|
@@ -1,56 +1,10 @@
|
|
|
1
|
-
import type {
|
|
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
|
|
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 {
|
|
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: (
|
|
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: (
|
|
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,
|
|
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:
|
|
15
|
+
transactors: TransactorsWithRunAndEnv
|
|
16
16
|
}
|