atom.io 0.35.0 → 0.36.1
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/dist/eslint-plugin/index.d.ts +2 -18
- package/dist/eslint-plugin/index.d.ts.map +1 -1
- package/dist/eslint-plugin/index.js +4 -141
- package/dist/eslint-plugin/index.js.map +1 -1
- package/dist/internal/index.d.ts +100 -78
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +180 -163
- package/dist/internal/index.js.map +1 -1
- package/dist/introspection/index.d.ts +5 -6
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js +2 -3
- package/dist/introspection/index.js.map +1 -1
- package/dist/json/index.d.ts +2 -10
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js +1 -31
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +38 -39
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +15 -16
- package/dist/main/index.js.map +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime/index.d.ts +4 -4
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +2 -6
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +7 -8
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js +3 -4
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts +4 -4
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +18 -18
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +5 -9
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/transceivers/set-rtx/index.d.ts +9 -2
- package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
- package/dist/transceivers/set-rtx/index.js +3 -0
- package/dist/transceivers/set-rtx/index.js.map +1 -1
- package/package.json +6 -6
- package/src/eslint-plugin/index.ts +0 -1
- package/src/eslint-plugin/rules/explicit-state-types.ts +8 -1
- package/src/eslint-plugin/rules/index.ts +0 -1
- package/src/internal/atom/create-regular-atom.ts +5 -5
- package/src/internal/atom/dispose-atom.ts +1 -0
- package/src/internal/atom/has-role.ts +12 -0
- package/src/internal/atom/index.ts +1 -0
- package/src/internal/caching.ts +38 -16
- package/src/internal/families/find-in-store.ts +4 -5
- package/src/internal/families/get-family-of-token.ts +4 -5
- package/src/internal/families/init-family-member.ts +3 -4
- package/src/internal/families/seek-in-store.ts +4 -5
- package/src/internal/get-state/read-or-compute-value.ts +37 -16
- package/src/internal/index.ts +19 -21
- package/src/internal/ingest-updates/ingest-creation-disposal.ts +18 -15
- package/src/internal/ingest-updates/ingest-selector-update.ts +9 -5
- package/src/internal/join/get-internal-relations-from-store.ts +2 -2
- package/src/internal/join/join-internal.ts +10 -18
- package/src/internal/molecule.ts +1 -0
- package/src/internal/mutable/create-mutable-atom-family.ts +40 -22
- package/src/internal/mutable/create-mutable-atom.ts +16 -12
- package/src/internal/mutable/get-json-family.ts +7 -6
- package/src/internal/mutable/get-json-token.ts +6 -13
- package/src/internal/mutable/get-update-family.ts +7 -8
- package/src/internal/mutable/get-update-token.ts +5 -9
- package/src/internal/mutable/tracker-family.ts +31 -38
- package/src/internal/mutable/tracker.ts +86 -104
- package/src/internal/mutable/transceiver.ts +37 -9
- package/src/internal/selector/create-readonly-held-selector.ts +2 -2
- package/src/internal/selector/create-readonly-pure-selector.ts +2 -2
- package/src/internal/selector/create-writable-held-selector.ts +3 -3
- package/src/internal/selector/create-writable-pure-selector.ts +3 -3
- package/src/internal/selector/dispose-selector.ts +9 -9
- package/src/internal/set-state/reset-atom-or-selector.ts +11 -4
- package/src/internal/set-state/set-atom.ts +15 -22
- package/src/internal/set-state/set-into-store.ts +5 -4
- package/src/internal/store/counterfeit.ts +3 -4
- package/src/internal/store/deposit.ts +8 -11
- package/src/internal/store/store.ts +7 -7
- package/src/internal/store/withdraw.ts +8 -12
- package/src/internal/subscribe/subscribe-in-store.ts +2 -2
- package/src/internal/subscribe/subscribe-to-transaction.ts +2 -2
- package/src/internal/timeline/create-timeline.ts +3 -3
- package/src/internal/transaction/act-upon-store.ts +2 -2
- package/src/internal/transaction/apply-transaction.ts +2 -2
- package/src/internal/transaction/build-transaction.ts +2 -2
- package/src/internal/transaction/create-transaction.ts +3 -3
- package/src/internal/transaction/index.ts +2 -2
- package/src/internal/transaction/is-root-store.ts +4 -2
- package/src/internal/utility-types.ts +1 -1
- package/src/introspection/attach-introspection-states.ts +3 -3
- package/src/introspection/attach-transaction-index.ts +4 -4
- package/src/introspection/attach-transaction-logs.ts +4 -4
- package/src/introspection/auditor.ts +3 -3
- package/src/json/index.ts +0 -2
- package/src/main/atom.ts +24 -36
- package/src/main/dispose-state.ts +6 -5
- package/src/main/find-state.ts +3 -4
- package/src/main/get-state.ts +6 -5
- package/src/main/join.ts +2 -2
- package/src/main/logger.ts +7 -7
- package/src/main/reset-state.ts +3 -3
- package/src/main/set-state.ts +3 -3
- package/src/main/subscribe.ts +3 -3
- package/src/main/tokens.ts +8 -14
- package/src/main/transaction.ts +17 -13
- package/src/main/validators.ts +1 -1
- package/src/react/use-json.ts +14 -24
- package/src/react-devtools/TransactionIndex.tsx +3 -3
- package/src/react-devtools/Updates.tsx +2 -2
- package/src/realtime/shared-room-store.ts +11 -22
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +2 -2
- package/src/realtime-client/pull-mutable-atom-family-member.ts +8 -17
- package/src/realtime-client/pull-mutable-atom.ts +7 -14
- package/src/realtime-client/push-state.ts +6 -5
- package/src/realtime-client/server-action.ts +5 -4
- package/src/realtime-react/use-pull-mutable-atom.ts +3 -5
- package/src/realtime-react/use-pull-mutable-family-member.ts +3 -4
- package/src/realtime-react/use-server-action.ts +2 -2
- package/src/realtime-server/realtime-mutable-family-provider.ts +3 -4
- package/src/realtime-server/realtime-mutable-provider.ts +2 -3
- package/src/realtime-server/realtime-server-stores/server-room-external-actions.ts +6 -5
- package/src/realtime-server/realtime-server-stores/server-user-store.ts +8 -15
- package/src/transceivers/set-rtx/set-rtx.ts +14 -1
- package/src/eslint-plugin/rules/synchronous-selector-dependencies.ts +0 -140
- package/src/eslint-plugin/walk.ts +0 -81
- package/src/internal/set-state/copy-mutable-if-needed.ts +0 -27
- package/src/json/select-json-family.ts +0 -55
- package/src/json/select-json.ts +0 -19
|
@@ -7,30 +7,34 @@ import type {
|
|
|
7
7
|
StateCreation,
|
|
8
8
|
StateDisposal,
|
|
9
9
|
} from "atom.io"
|
|
10
|
-
import type { Canonical
|
|
11
|
-
import {
|
|
10
|
+
import type { Canonical } from "atom.io/json"
|
|
11
|
+
import { stringifyJson } from "atom.io/json"
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
createWritablePureSelectorFamily,
|
|
15
|
+
type MutableAtomFamily,
|
|
16
|
+
prettyPrintTokenType,
|
|
17
|
+
} from ".."
|
|
14
18
|
import { newest } from "../lineage"
|
|
15
19
|
import { createMutableAtom } from "../mutable"
|
|
16
20
|
import type { Store } from "../store"
|
|
17
21
|
import { Subject } from "../subject"
|
|
18
22
|
import { FamilyTracker } from "./tracker-family"
|
|
19
|
-
import type { Transceiver } from "./transceiver"
|
|
23
|
+
import type { AsJSON, Transceiver } from "./transceiver"
|
|
20
24
|
|
|
21
25
|
export function createMutableAtomFamily<
|
|
22
|
-
T extends Transceiver<any>,
|
|
23
|
-
J extends Json.Serializable,
|
|
26
|
+
T extends Transceiver<any, any, any>,
|
|
24
27
|
K extends Canonical,
|
|
25
28
|
>(
|
|
26
29
|
store: Store,
|
|
27
|
-
options: MutableAtomFamilyOptions<T,
|
|
30
|
+
options: MutableAtomFamilyOptions<T, K>,
|
|
28
31
|
internalRoles?: string[],
|
|
29
|
-
): MutableAtomFamilyToken<T,
|
|
30
|
-
const familyToken =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
): MutableAtomFamilyToken<T, K> {
|
|
33
|
+
const familyToken: MutableAtomFamilyToken<T & Transceiver<any, any, any>, K> =
|
|
34
|
+
{
|
|
35
|
+
key: options.key,
|
|
36
|
+
type: `mutable_atom_family`,
|
|
37
|
+
}
|
|
34
38
|
|
|
35
39
|
const existing = store.families.get(options.key)
|
|
36
40
|
if (existing) {
|
|
@@ -45,20 +49,18 @@ export function createMutableAtomFamily<
|
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
const subject = new Subject<
|
|
48
|
-
StateCreation<MutableAtomToken<T
|
|
52
|
+
StateCreation<MutableAtomToken<T>> | StateDisposal<MutableAtomToken<T>>
|
|
49
53
|
>()
|
|
50
54
|
|
|
51
|
-
const familyFunction = (key: K): MutableAtomToken<T
|
|
55
|
+
const familyFunction = (key: K): MutableAtomToken<T> => {
|
|
52
56
|
const subKey = stringifyJson(key)
|
|
53
57
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
54
58
|
const fullKey = `${options.key}(${subKey})`
|
|
55
59
|
const target = newest(store)
|
|
56
60
|
|
|
57
|
-
const individualOptions: MutableAtomOptions<T
|
|
61
|
+
const individualOptions: MutableAtomOptions<T> = {
|
|
58
62
|
key: fullKey,
|
|
59
|
-
|
|
60
|
-
toJson: options.toJson,
|
|
61
|
-
fromJson: options.fromJson,
|
|
63
|
+
class: options.class,
|
|
62
64
|
}
|
|
63
65
|
if (options.effects) {
|
|
64
66
|
individualOptions.effects = options.effects(key)
|
|
@@ -73,13 +75,29 @@ export function createMutableAtomFamily<
|
|
|
73
75
|
const atomFamily = Object.assign(familyFunction, familyToken, {
|
|
74
76
|
subject,
|
|
75
77
|
install: (s: Store) => createMutableAtomFamily(s, options),
|
|
76
|
-
toJson: options.toJson,
|
|
77
|
-
fromJson: options.fromJson,
|
|
78
78
|
internalRoles,
|
|
79
|
-
}) satisfies MutableAtomFamily<T,
|
|
79
|
+
}) satisfies MutableAtomFamily<T, K>
|
|
80
80
|
|
|
81
81
|
store.families.set(options.key, atomFamily)
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
createWritablePureSelectorFamily<AsJSON<T>, K>(
|
|
84
|
+
store,
|
|
85
|
+
{
|
|
86
|
+
key: `${options.key}:JSON`,
|
|
87
|
+
get:
|
|
88
|
+
(key) =>
|
|
89
|
+
({ get }) =>
|
|
90
|
+
get(familyToken, key).toJSON(),
|
|
91
|
+
set:
|
|
92
|
+
(key) =>
|
|
93
|
+
({ set }, newValue) => {
|
|
94
|
+
set(familyToken, key, options.class.fromJSON(newValue))
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
[`mutable`, `json`],
|
|
98
|
+
)
|
|
99
|
+
|
|
83
100
|
new FamilyTracker(atomFamily, store)
|
|
101
|
+
|
|
84
102
|
return familyToken
|
|
85
103
|
}
|
|
@@ -4,11 +4,9 @@ import type {
|
|
|
4
4
|
MutableAtomToken,
|
|
5
5
|
UpdateHandler,
|
|
6
6
|
} from "atom.io"
|
|
7
|
-
import type { Json } from "atom.io/json"
|
|
8
|
-
import { selectJson } from "atom.io/json"
|
|
9
7
|
|
|
10
8
|
import type { MutableAtom } from ".."
|
|
11
|
-
import { resetInStore, setIntoStore } from ".."
|
|
9
|
+
import { createStandaloneSelector, resetInStore, setIntoStore } from ".."
|
|
12
10
|
import { newest } from "../lineage"
|
|
13
11
|
import { deposit, type Store } from "../store"
|
|
14
12
|
import { Subject } from "../subject"
|
|
@@ -16,14 +14,11 @@ import { subscribeToState } from "../subscribe"
|
|
|
16
14
|
import { Tracker } from "./tracker"
|
|
17
15
|
import type { Transceiver } from "./transceiver"
|
|
18
16
|
|
|
19
|
-
export function createMutableAtom<
|
|
20
|
-
T extends Transceiver<any>,
|
|
21
|
-
J extends Json.Serializable,
|
|
22
|
-
>(
|
|
17
|
+
export function createMutableAtom<T extends Transceiver<any, any, any>>(
|
|
23
18
|
store: Store,
|
|
24
|
-
options: MutableAtomOptions<T
|
|
19
|
+
options: MutableAtomOptions<T>,
|
|
25
20
|
family: FamilyMetadata | undefined,
|
|
26
|
-
): MutableAtomToken<T
|
|
21
|
+
): MutableAtomToken<T> {
|
|
27
22
|
store.logger.info(
|
|
28
23
|
`🔨`,
|
|
29
24
|
`atom`,
|
|
@@ -43,8 +38,11 @@ export function createMutableAtom<
|
|
|
43
38
|
)
|
|
44
39
|
return deposit(existing)
|
|
45
40
|
}
|
|
46
|
-
const subject = new Subject<{
|
|
47
|
-
|
|
41
|
+
const subject = new Subject<{
|
|
42
|
+
newValue: T
|
|
43
|
+
oldValue: T
|
|
44
|
+
}>()
|
|
45
|
+
const newAtom: MutableAtom<T> = {
|
|
48
46
|
...options,
|
|
49
47
|
type,
|
|
50
48
|
install: (s: Store) => {
|
|
@@ -86,7 +84,13 @@ export function createMutableAtom<
|
|
|
86
84
|
|
|
87
85
|
new Tracker(token, store)
|
|
88
86
|
if (!family) {
|
|
89
|
-
|
|
87
|
+
createStandaloneSelector(store, {
|
|
88
|
+
key: `${key}:JSON`,
|
|
89
|
+
get: ({ get }) => get(token).toJSON(),
|
|
90
|
+
set: ({ set }, newValue) => {
|
|
91
|
+
set(token, options.class.fromJSON(newValue))
|
|
92
|
+
},
|
|
93
|
+
})
|
|
90
94
|
}
|
|
91
95
|
store.on.atomCreation.next(token)
|
|
92
96
|
return token
|
|
@@ -7,16 +7,17 @@ import type { Store } from "../store"
|
|
|
7
7
|
import type { Transceiver } from "./transceiver"
|
|
8
8
|
|
|
9
9
|
export const getJsonFamily = <
|
|
10
|
-
Core extends Transceiver<Json.Serializable>,
|
|
11
|
-
SerializableCore extends Json.Serializable,
|
|
10
|
+
Core extends Transceiver<any, Json.Serializable, Json.Serializable>,
|
|
12
11
|
Key extends Canonical,
|
|
13
12
|
>(
|
|
14
|
-
mutableAtomFamily: MutableAtomFamilyToken<Core,
|
|
13
|
+
mutableAtomFamily: MutableAtomFamilyToken<Core, Key>,
|
|
15
14
|
store: Store,
|
|
16
|
-
): WritablePureSelectorFamily<
|
|
15
|
+
): WritablePureSelectorFamily<ReturnType<Core[`toJSON`]>, Key> => {
|
|
17
16
|
const target = newest(store)
|
|
18
17
|
const key = `${mutableAtomFamily.key}:JSON`
|
|
19
|
-
const jsonFamily
|
|
20
|
-
|
|
18
|
+
const jsonFamily = target.families.get(key) as WritablePureSelectorFamily<
|
|
19
|
+
ReturnType<Core[`toJSON`]>,
|
|
20
|
+
Key
|
|
21
|
+
>
|
|
21
22
|
return jsonFamily
|
|
22
23
|
}
|
|
@@ -3,27 +3,20 @@ import type {
|
|
|
3
3
|
WritablePureSelectorFamilyToken,
|
|
4
4
|
WritablePureSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
|
-
import type { Json } from "atom.io/json"
|
|
7
6
|
|
|
8
7
|
import { findInStore } from "../families"
|
|
9
8
|
import { newest } from "../lineage"
|
|
10
9
|
import { type Store, withdraw } from "../store"
|
|
11
|
-
import type { Transceiver } from "./transceiver"
|
|
10
|
+
import type { AsJSON, Transceiver } from "./transceiver"
|
|
12
11
|
|
|
13
|
-
export const getJsonToken = <
|
|
14
|
-
Core extends Transceiver<any>,
|
|
15
|
-
SerializableCore extends Json.Serializable,
|
|
16
|
-
>(
|
|
12
|
+
export const getJsonToken = <T extends Transceiver<any, any, any>>(
|
|
17
13
|
store: Store,
|
|
18
|
-
mutableAtomToken: MutableAtomToken<
|
|
19
|
-
): WritablePureSelectorToken<
|
|
14
|
+
mutableAtomToken: MutableAtomToken<T>,
|
|
15
|
+
): WritablePureSelectorToken<AsJSON<T>> => {
|
|
20
16
|
if (mutableAtomToken.family) {
|
|
21
17
|
const target = newest(store)
|
|
22
18
|
const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`
|
|
23
|
-
const jsonFamilyToken: WritablePureSelectorFamilyToken<
|
|
24
|
-
SerializableCore,
|
|
25
|
-
string
|
|
26
|
-
> = {
|
|
19
|
+
const jsonFamilyToken: WritablePureSelectorFamilyToken<AsJSON<T>, string> = {
|
|
27
20
|
key: jsonFamilyKey,
|
|
28
21
|
type: `writable_pure_selector_family`,
|
|
29
22
|
}
|
|
@@ -32,7 +25,7 @@ export const getJsonToken = <
|
|
|
32
25
|
const jsonToken = findInStore(store, family, subKey)
|
|
33
26
|
return jsonToken
|
|
34
27
|
}
|
|
35
|
-
const token: WritablePureSelectorToken<
|
|
28
|
+
const token: WritablePureSelectorToken<AsJSON<T>> = {
|
|
36
29
|
type: `writable_pure_selector`,
|
|
37
30
|
key: `${mutableAtomToken.key}:JSON`,
|
|
38
31
|
}
|
|
@@ -4,20 +4,19 @@ import type { Json } from "atom.io/json"
|
|
|
4
4
|
import type { AtomFamily } from ".."
|
|
5
5
|
import { newest } from "../lineage"
|
|
6
6
|
import type { Store } from "../store"
|
|
7
|
-
import type {
|
|
7
|
+
import type { SignalFrom, Transceiver } from "./transceiver"
|
|
8
8
|
|
|
9
9
|
export const getUpdateFamily = <
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Key extends string,
|
|
10
|
+
T extends Transceiver<any, Json.Serializable, Json.Serializable>,
|
|
11
|
+
K extends string,
|
|
13
12
|
>(
|
|
14
|
-
mutableAtomFamily: MutableAtomFamilyToken<
|
|
13
|
+
mutableAtomFamily: MutableAtomFamilyToken<T, K>,
|
|
15
14
|
store: Store,
|
|
16
|
-
): AtomFamily<
|
|
15
|
+
): AtomFamily<SignalFrom<T>, K> => {
|
|
17
16
|
const target = newest(store)
|
|
18
17
|
const key = `*${mutableAtomFamily.key}`
|
|
19
|
-
const updateFamily: AtomFamily<
|
|
18
|
+
const updateFamily: AtomFamily<SignalFrom<T>, K> = target.families.get(
|
|
20
19
|
key,
|
|
21
|
-
) as AtomFamily<
|
|
20
|
+
) as AtomFamily<SignalFrom<T>, K>
|
|
22
21
|
return updateFamily
|
|
23
22
|
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { MutableAtomToken, RegularAtomToken } from "atom.io"
|
|
2
|
-
import type { Json } from "atom.io/json"
|
|
3
2
|
|
|
4
|
-
import type {
|
|
3
|
+
import type { SignalFrom, Transceiver } from "./transceiver"
|
|
5
4
|
|
|
6
|
-
export const getUpdateToken = <
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
>(
|
|
10
|
-
mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
|
|
11
|
-
): RegularAtomToken<Signal<Core>> => {
|
|
5
|
+
export const getUpdateToken = <T extends Transceiver<any, any, any>>(
|
|
6
|
+
mutableAtomToken: MutableAtomToken<T>,
|
|
7
|
+
): RegularAtomToken<SignalFrom<T>> => {
|
|
12
8
|
const key = `*${mutableAtomToken.key}`
|
|
13
|
-
const updateToken: RegularAtomToken<
|
|
9
|
+
const updateToken: RegularAtomToken<SignalFrom<T>> = { type: `atom`, key }
|
|
14
10
|
if (mutableAtomToken.family) {
|
|
15
11
|
updateToken.family = {
|
|
16
12
|
key: `*${mutableAtomToken.family.key}`,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MutableAtomToken, StateLifecycleEvent } from "atom.io"
|
|
1
2
|
import type { Canonical } from "atom.io/json"
|
|
2
3
|
import { parseJson } from "atom.io/json"
|
|
3
4
|
|
|
@@ -5,28 +6,19 @@ import type { MutableAtomFamily, RegularAtomFamily } from ".."
|
|
|
5
6
|
import { createRegularAtomFamily } from "../families"
|
|
6
7
|
import { type Store, withdraw } from "../store"
|
|
7
8
|
import { Tracker } from "./tracker"
|
|
8
|
-
import type { Transceiver } from "./transceiver"
|
|
9
|
+
import type { SignalFrom, Transceiver } from "./transceiver"
|
|
9
10
|
|
|
10
11
|
export class FamilyTracker<
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
T extends Transceiver<any, any, any>,
|
|
13
|
+
K extends Canonical,
|
|
13
14
|
> {
|
|
14
|
-
private trackers: Map<
|
|
15
|
+
private trackers: Map<K, Tracker<T>> = new Map()
|
|
15
16
|
|
|
16
|
-
public readonly
|
|
17
|
-
|
|
18
|
-
FamilyMemberKey
|
|
19
|
-
>
|
|
20
|
-
public readonly mutableAtoms: MutableAtomFamily<Core, any, FamilyMemberKey>
|
|
17
|
+
public readonly latestSignalAtoms: RegularAtomFamily<SignalFrom<T> | null, K>
|
|
18
|
+
public readonly mutableAtoms: MutableAtomFamily<T, K>
|
|
21
19
|
|
|
22
|
-
public constructor(
|
|
23
|
-
|
|
24
|
-
store: Store,
|
|
25
|
-
) {
|
|
26
|
-
const updateAtoms = createRegularAtomFamily<
|
|
27
|
-
(Core extends Transceiver<infer Signal> ? Signal : never) | null,
|
|
28
|
-
FamilyMemberKey
|
|
29
|
-
>(
|
|
20
|
+
public constructor(mutableAtoms: MutableAtomFamily<T, K>, store: Store) {
|
|
21
|
+
const latestSignalAtoms = createRegularAtomFamily<SignalFrom<T> | null, K>(
|
|
30
22
|
store,
|
|
31
23
|
{
|
|
32
24
|
key: `*${mutableAtoms.key}`,
|
|
@@ -34,30 +26,31 @@ export class FamilyTracker<
|
|
|
34
26
|
},
|
|
35
27
|
[`mutable`, `updates`],
|
|
36
28
|
)
|
|
37
|
-
this.
|
|
29
|
+
this.latestSignalAtoms = withdraw(store, latestSignalAtoms)
|
|
38
30
|
this.mutableAtoms = mutableAtoms
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
break
|
|
31
|
+
const trackerFamilyWatchesForCreationAndDisposalEvents = (
|
|
32
|
+
event: StateLifecycleEvent<MutableAtomToken<T>>,
|
|
33
|
+
) => {
|
|
34
|
+
const { type, token } = event
|
|
35
|
+
if (token.family) {
|
|
36
|
+
const key = parseJson(token.family.subKey)
|
|
37
|
+
switch (type) {
|
|
38
|
+
case `state_creation`:
|
|
39
|
+
this.trackers.set(key, new Tracker<T>(token, store))
|
|
40
|
+
break
|
|
41
|
+
case `state_disposal`: {
|
|
42
|
+
const tracker = this.trackers.get(key)
|
|
43
|
+
if (tracker) {
|
|
44
|
+
tracker[Symbol.dispose]()
|
|
45
|
+
this.trackers.delete(key)
|
|
46
|
+
}
|
|
58
47
|
}
|
|
59
48
|
}
|
|
60
|
-
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.mutableAtoms.subject.subscribe(
|
|
52
|
+
`store=${store.config.name}::tracker-atom-family`,
|
|
53
|
+
trackerFamilyWatchesForCreationAndDisposalEvents,
|
|
61
54
|
)
|
|
62
55
|
}
|
|
63
56
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { FamilyMetadata, MutableAtomToken, RegularAtomToken } from "atom.io"
|
|
2
|
-
import type { Json } from "atom.io/json"
|
|
3
2
|
|
|
4
3
|
import type { Store } from ".."
|
|
5
4
|
import {
|
|
@@ -11,89 +10,84 @@ import {
|
|
|
11
10
|
} from ".."
|
|
12
11
|
import { createRegularAtom } from "../atom"
|
|
13
12
|
import { isChildStore } from "../transaction/is-root-store"
|
|
14
|
-
import type { Transceiver } from "./transceiver"
|
|
13
|
+
import type { SignalFrom, Transceiver } from "./transceiver"
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* @internal Give the tracker a transceiver state and a store, and it will
|
|
18
17
|
* subscribe to the transceiver's inner value. When the inner value changes,
|
|
19
18
|
* the tracker will update its own state to reflect the change.
|
|
20
19
|
*/
|
|
21
|
-
export class Tracker<
|
|
22
|
-
private
|
|
23
|
-
mutableState: MutableAtomToken<
|
|
20
|
+
export class Tracker<T extends Transceiver<any, any, any>> {
|
|
21
|
+
private initializeSignalAtom(
|
|
22
|
+
mutableState: MutableAtomToken<T>,
|
|
24
23
|
store: Store,
|
|
25
|
-
): RegularAtomToken<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
store.atoms.delete(latestUpdateStateKey)
|
|
30
|
-
store.valueMap.delete(latestUpdateStateKey)
|
|
24
|
+
): RegularAtomToken<SignalFrom<T> | null> {
|
|
25
|
+
const latestSignalStateKey = `*${mutableState.key}`
|
|
26
|
+
store.atoms.delete(latestSignalStateKey)
|
|
27
|
+
store.valueMap.delete(latestSignalStateKey)
|
|
31
28
|
const familyMetaData: FamilyMetadata | undefined = mutableState.family
|
|
32
29
|
? {
|
|
33
30
|
key: `*${mutableState.family.key}`,
|
|
34
31
|
subKey: mutableState.family.subKey,
|
|
35
32
|
}
|
|
36
33
|
: undefined
|
|
37
|
-
const
|
|
38
|
-
(Mutable extends Transceiver<infer Signal> ? Signal : never) | null
|
|
39
|
-
>(
|
|
34
|
+
const latestSignalState = createRegularAtom<SignalFrom<T> | null>(
|
|
40
35
|
store,
|
|
41
36
|
{
|
|
42
|
-
key:
|
|
37
|
+
key: latestSignalStateKey,
|
|
43
38
|
default: null,
|
|
44
39
|
},
|
|
45
40
|
familyMetaData,
|
|
41
|
+
[`tracker:signal`],
|
|
46
42
|
)
|
|
47
|
-
if (store.parent?.valueMap.has(
|
|
48
|
-
const parentValue = store.parent.valueMap.get(
|
|
49
|
-
store.valueMap.set(
|
|
43
|
+
if (store.parent?.valueMap.has(latestSignalStateKey)) {
|
|
44
|
+
const parentValue = store.parent.valueMap.get(latestSignalStateKey)
|
|
45
|
+
store.valueMap.set(latestSignalStateKey, parentValue)
|
|
50
46
|
}
|
|
51
47
|
|
|
52
|
-
return
|
|
48
|
+
return latestSignalState
|
|
53
49
|
}
|
|
54
50
|
|
|
55
51
|
private unsubscribeFromInnerValue!: () => void
|
|
56
52
|
private unsubscribeFromState!: () => void
|
|
57
|
-
private
|
|
58
|
-
mutableState: MutableAtomToken<
|
|
59
|
-
|
|
60
|
-
(Mutable extends Transceiver<infer Signal> ? Signal : never) | null
|
|
61
|
-
>,
|
|
53
|
+
private captureSignalsFromCore(
|
|
54
|
+
mutableState: MutableAtomToken<T, any>,
|
|
55
|
+
latestSignalState: RegularAtomToken<SignalFrom<T> | null>,
|
|
62
56
|
target: Store,
|
|
63
57
|
): void {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
const stateKey = mutableState.key
|
|
59
|
+
const storeName = target.config.name
|
|
60
|
+
const storeStatus = isChildStore(target)
|
|
61
|
+
? target.transactionMeta.update.key
|
|
62
|
+
: `main`
|
|
63
|
+
const subscriptionKey = `tracker:${storeName}:${storeStatus}:${stateKey}`
|
|
64
|
+
const trackerCapturesOutboundSignal = (update: SignalFrom<T>) => {
|
|
65
|
+
setIntoStore(target, latestSignalState, update)
|
|
66
|
+
}
|
|
67
67
|
const originalInnerValue = getFromStore(target, mutableState)
|
|
68
68
|
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
69
69
|
subscriptionKey,
|
|
70
|
-
|
|
71
|
-
setIntoStore(target, latestUpdateState, update)
|
|
72
|
-
},
|
|
70
|
+
trackerCapturesOutboundSignal,
|
|
73
71
|
)
|
|
74
72
|
this.unsubscribeFromState = subscribeToState(
|
|
75
73
|
target,
|
|
76
74
|
mutableState,
|
|
77
75
|
subscriptionKey,
|
|
78
|
-
(update)
|
|
76
|
+
function trackerLooksForNewReference(update: SignalFrom<T>) {
|
|
79
77
|
if (update.newValue !== update.oldValue) {
|
|
80
78
|
this.unsubscribeFromInnerValue()
|
|
81
79
|
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
82
80
|
subscriptionKey,
|
|
83
|
-
|
|
84
|
-
setIntoStore(target, latestUpdateState, transceiverUpdate)
|
|
85
|
-
},
|
|
81
|
+
trackerCapturesOutboundSignal,
|
|
86
82
|
)
|
|
87
83
|
}
|
|
88
|
-
},
|
|
84
|
+
}.bind(this),
|
|
89
85
|
)
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
private
|
|
93
|
-
mutableState: MutableAtomToken<
|
|
94
|
-
|
|
95
|
-
(Mutable extends Transceiver<infer Signal> ? Signal : never) | null
|
|
96
|
-
>,
|
|
88
|
+
private supplySignalsToCore(
|
|
89
|
+
mutableState: MutableAtomToken<T>,
|
|
90
|
+
latestSignalState: RegularAtomToken<SignalFrom<T> | null>,
|
|
97
91
|
target: Store,
|
|
98
92
|
): void {
|
|
99
93
|
const subscriptionKey = `tracker:${target.config.name}:${
|
|
@@ -101,87 +95,75 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
101
95
|
}:${mutableState.key}`
|
|
102
96
|
subscribeToState(
|
|
103
97
|
target,
|
|
104
|
-
|
|
98
|
+
latestSignalState,
|
|
105
99
|
subscriptionKey,
|
|
106
|
-
({ newValue, oldValue })
|
|
100
|
+
function trackerCapturesInboundSignal({ newValue, oldValue }) {
|
|
107
101
|
const timelineId = target.timelineTopics.getRelatedKey(
|
|
108
|
-
|
|
102
|
+
latestSignalState.key,
|
|
109
103
|
)
|
|
110
104
|
|
|
111
|
-
if (timelineId) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
return
|
|
131
|
-
}
|
|
105
|
+
if (timelineId && target.timelines.get(timelineId)?.timeTraveling) {
|
|
106
|
+
const unsubscribe = subscribeToTimeline(
|
|
107
|
+
target,
|
|
108
|
+
{ key: timelineId, type: `timeline` },
|
|
109
|
+
subscriptionKey,
|
|
110
|
+
function trackerWaitsForTimeTravelToFinish(update) {
|
|
111
|
+
unsubscribe()
|
|
112
|
+
setIntoStore(target, mutableState, (transceiver) => {
|
|
113
|
+
if (update === `redo` && newValue) {
|
|
114
|
+
transceiver.do(newValue)
|
|
115
|
+
} else if (update === `undo` && oldValue) {
|
|
116
|
+
transceiver.undo(oldValue)
|
|
117
|
+
}
|
|
118
|
+
return transceiver
|
|
119
|
+
})
|
|
120
|
+
},
|
|
121
|
+
)
|
|
122
|
+
return
|
|
132
123
|
}
|
|
133
124
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}, but got ${updateNumber}`,
|
|
156
|
-
)
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
)
|
|
125
|
+
const mutable = getFromStore(target, mutableState)
|
|
126
|
+
const updateNumber = mutable.getUpdateNumber(newValue)
|
|
127
|
+
const eventOffset = updateNumber - mutable.cacheUpdateNumber
|
|
128
|
+
if (newValue && eventOffset === 1) {
|
|
129
|
+
setIntoStore(
|
|
130
|
+
target,
|
|
131
|
+
mutableState,
|
|
132
|
+
(transceiver) => (transceiver.do(newValue), transceiver),
|
|
133
|
+
)
|
|
134
|
+
} else {
|
|
135
|
+
const expected = mutable.cacheUpdateNumber + 1
|
|
136
|
+
target.logger.info(
|
|
137
|
+
`❌`,
|
|
138
|
+
`mutable_atom`,
|
|
139
|
+
mutableState.key,
|
|
140
|
+
`could not be updated. Expected update number`,
|
|
141
|
+
expected,
|
|
142
|
+
`but got`,
|
|
143
|
+
updateNumber,
|
|
144
|
+
)
|
|
145
|
+
}
|
|
160
146
|
},
|
|
161
147
|
)
|
|
162
148
|
}
|
|
163
149
|
|
|
164
|
-
public
|
|
165
|
-
public
|
|
166
|
-
(Mutable extends Transceiver<infer Signal> ? Signal : never) | null
|
|
167
|
-
>
|
|
150
|
+
public mutableAtomToken: MutableAtomToken<T>
|
|
151
|
+
public latestSignalToken: RegularAtomToken<SignalFrom<T> | null>
|
|
168
152
|
|
|
169
153
|
public [Symbol.dispose]!: () => void
|
|
170
154
|
|
|
171
|
-
public constructor(
|
|
172
|
-
mutableState: MutableAtomToken<Mutable, Json.Serializable>,
|
|
173
|
-
store: Store,
|
|
174
|
-
) {
|
|
175
|
-
this.mutableState = mutableState
|
|
155
|
+
public constructor(mutableAtomToken: MutableAtomToken<T>, store: Store) {
|
|
176
156
|
const target = newest(store)
|
|
177
|
-
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
|
|
157
|
+
const latestSignalToken = this.initializeSignalAtom(mutableAtomToken, target)
|
|
158
|
+
this.mutableAtomToken = mutableAtomToken
|
|
159
|
+
this.latestSignalToken = latestSignalToken
|
|
160
|
+
this.captureSignalsFromCore(mutableAtomToken, latestSignalToken, target)
|
|
161
|
+
this.supplySignalsToCore(mutableAtomToken, latestSignalToken, target)
|
|
162
|
+
target.trackers.set(mutableAtomToken.key, this)
|
|
181
163
|
this[Symbol.dispose] = () => {
|
|
182
164
|
this.unsubscribeFromInnerValue()
|
|
183
165
|
this.unsubscribeFromState()
|
|
184
|
-
target.trackers.delete(
|
|
166
|
+
target.trackers.delete(mutableAtomToken.key)
|
|
185
167
|
}
|
|
186
168
|
}
|
|
187
169
|
}
|