atom.io 0.21.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.cjs +136 -63
- package/data/dist/index.d.ts +6 -0
- package/data/dist/index.js +3 -3
- package/data/src/join.ts +135 -51
- package/data/src/struct-family.ts +2 -2
- package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
- package/dist/{chunk-HITX3MO4.js → chunk-JA4V7TJY.js} +135 -62
- package/dist/index.cjs +2 -7
- package/dist/index.d.ts +29 -14
- package/dist/index.js +4 -8
- package/ephemeral/dist/index.cjs +11 -0
- package/ephemeral/dist/index.js +9 -0
- package/ephemeral/package.json +16 -0
- package/ephemeral/src/index.ts +1 -0
- package/eslint-plugin/dist/index.cjs +156 -1
- package/eslint-plugin/dist/index.js +156 -1
- package/eslint-plugin/src/rules/index.ts +1 -0
- package/eslint-plugin/src/rules/lifespan.ts +204 -0
- package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -65
- package/eslint-plugin/src/walk.ts +73 -0
- package/immortal/dist/index.cjs +100 -0
- package/immortal/dist/index.js +97 -0
- package/immortal/package.json +16 -0
- package/immortal/src/index.ts +2 -0
- package/immortal/src/molecule.ts +134 -0
- package/immortal/src/seek-state.ts +60 -0
- package/internal/dist/index.cjs +186 -146
- package/internal/dist/index.d.ts +29 -13
- package/internal/dist/index.js +185 -146
- package/internal/src/atom/dispose-atom.ts +4 -1
- package/internal/src/families/create-readonly-selector-family.ts +9 -9
- package/internal/src/families/create-regular-atom-family.ts +15 -20
- package/internal/src/families/create-writable-selector-family.ts +6 -7
- package/internal/src/families/find-in-store.ts +11 -5
- package/internal/src/families/index.ts +2 -0
- package/internal/src/families/init-family-member.ts +91 -0
- package/internal/src/families/seek-in-store.ts +106 -0
- package/internal/src/get-state/get-from-store.ts +2 -2
- package/internal/src/mutable/create-mutable-atom-family.ts +17 -23
- package/internal/src/mutable/create-mutable-atom.ts +3 -1
- package/internal/src/mutable/get-json-family.ts +2 -2
- package/internal/src/mutable/get-json-token.ts +27 -12
- package/internal/src/mutable/tracker-family.ts +14 -12
- package/internal/src/not-found-error.ts +11 -3
- package/internal/src/selector/create-readonly-selector.ts +2 -2
- package/internal/src/selector/create-writable-selector.ts +2 -2
- package/internal/src/selector/dispose-selector.ts +40 -23
- package/internal/src/selector/register-selector.ts +8 -5
- package/internal/src/set-state/set-into-store.ts +2 -2
- package/internal/src/store/index.ts +0 -1
- package/internal/src/store/store.ts +18 -5
- package/internal/src/subscribe/subscribe-to-state.ts +2 -2
- package/internal/src/transaction/build-transaction.ts +7 -2
- package/introspection/dist/index.cjs +38 -52
- package/introspection/dist/index.js +38 -52
- package/introspection/src/attach-atom-index.ts +38 -48
- package/introspection/src/attach-selector-index.ts +45 -50
- package/json/dist/index.cjs +38 -4
- package/json/dist/index.js +40 -6
- package/json/src/select-json-family.ts +46 -7
- package/package.json +30 -10
- package/react/dist/index.cjs +1 -1
- package/react/dist/index.js +1 -1
- package/react/src/use-json.ts +1 -1
- package/react-devtools/dist/index.cjs +11 -10
- package/react-devtools/dist/index.js +2 -1
- package/react-devtools/src/StateIndex.tsx +2 -1
- package/react-devtools/src/TimelineIndex.tsx +2 -1
- package/react-devtools/src/TransactionIndex.tsx +7 -7
- package/realtime-client/dist/index.cjs +3 -3
- package/realtime-client/dist/index.js +3 -3
- package/realtime-client/src/pull-mutable-atom-family-member.ts +1 -1
- package/realtime-client/src/pull-mutable-atom.ts +1 -1
- package/realtime-client/src/sync-continuity.ts +1 -2
- package/realtime-react/dist/index.cjs +1 -1
- package/realtime-react/dist/index.js +1 -1
- package/realtime-server/dist/index.cjs +18 -17
- package/realtime-server/dist/index.js +7 -6
- package/realtime-server/src/realtime-continuity-synchronizer.ts +5 -3
- package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
- package/realtime-server/src/realtime-mutable-provider.ts +1 -1
- package/realtime-testing/dist/index.cjs +6 -2
- package/realtime-testing/dist/index.js +8 -5
- package/realtime-testing/src/setup-realtime-test.tsx +5 -2
- package/src/atom.ts +10 -4
- package/src/index.ts +1 -2
- package/src/selector.ts +10 -4
- package/src/silo.ts +3 -3
- package/src/transaction.ts +5 -2
- package/internal/src/store/withdraw-new-family-member.ts +0 -69
- /package/{src → ephemeral/src}/find-state.ts +0 -0
- /package/src/{dispose.ts → dispose-state.ts} +0 -0
|
@@ -18,30 +18,26 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
18
18
|
store: Store,
|
|
19
19
|
): RegularAtomFamily<T, K> {
|
|
20
20
|
const subject = new Subject<RegularAtomToken<T>>()
|
|
21
|
+
|
|
21
22
|
const atomFamily: RegularAtomFamily<T, K> = Object.assign(
|
|
22
23
|
(key: K): RegularAtomToken<any> => {
|
|
23
24
|
const subKey = stringifyJson(key)
|
|
24
25
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
25
26
|
const fullKey = `${options.key}(${subKey})`
|
|
26
27
|
const target = newest(store)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
options.default instanceof Function
|
|
36
|
-
? options.default(key)
|
|
37
|
-
: options.default,
|
|
38
|
-
}
|
|
39
|
-
if (options.effects) {
|
|
40
|
-
individualOptions.effects = options.effects(key)
|
|
41
|
-
}
|
|
42
|
-
token = createRegularAtom(individualOptions, family, store)
|
|
43
|
-
subject.next(token)
|
|
28
|
+
|
|
29
|
+
const def = options.default
|
|
30
|
+
const individualOptions: RegularAtomOptions<T> = {
|
|
31
|
+
key: fullKey,
|
|
32
|
+
default: def instanceof Function ? def(key) : def,
|
|
33
|
+
}
|
|
34
|
+
if (options.effects) {
|
|
35
|
+
individualOptions.effects = options.effects(key)
|
|
44
36
|
}
|
|
37
|
+
|
|
38
|
+
const token = createRegularAtom(individualOptions, family, target)
|
|
39
|
+
|
|
40
|
+
subject.next(token)
|
|
45
41
|
return token
|
|
46
42
|
},
|
|
47
43
|
{
|
|
@@ -50,8 +46,7 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
50
46
|
subject,
|
|
51
47
|
install: (s: Store) => createRegularAtomFamily(options, s),
|
|
52
48
|
} as const,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
target.families.set(options.key, atomFamily)
|
|
49
|
+
) satisfies RegularAtomFamily<T, K>
|
|
50
|
+
store.families.set(options.key, atomFamily)
|
|
56
51
|
return atomFamily
|
|
57
52
|
}
|
|
@@ -7,9 +7,9 @@ import type {
|
|
|
7
7
|
import type { Json } from "atom.io/json"
|
|
8
8
|
import { stringifyJson } from "atom.io/json"
|
|
9
9
|
|
|
10
|
+
import { newest } from "../lineage"
|
|
10
11
|
import { createWritableSelector } from "../selector"
|
|
11
12
|
import type { Store } from "../store"
|
|
12
|
-
import { deposit } from "../store"
|
|
13
13
|
import { Subject } from "../subject"
|
|
14
14
|
|
|
15
15
|
export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
@@ -23,10 +23,8 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
|
23
23
|
const subKey = stringifyJson(key)
|
|
24
24
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
25
25
|
const fullKey = `${options.key}(${subKey})`
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
return deposit(existing)
|
|
29
|
-
}
|
|
26
|
+
const target = newest(store)
|
|
27
|
+
|
|
30
28
|
const token = createWritableSelector(
|
|
31
29
|
{
|
|
32
30
|
key: fullKey,
|
|
@@ -34,8 +32,9 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
|
34
32
|
set: options.set(key),
|
|
35
33
|
},
|
|
36
34
|
family,
|
|
37
|
-
|
|
35
|
+
target,
|
|
38
36
|
)
|
|
37
|
+
|
|
39
38
|
subject.next(token)
|
|
40
39
|
return token
|
|
41
40
|
},
|
|
@@ -45,7 +44,7 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
|
45
44
|
subject,
|
|
46
45
|
install: (s: Store) => createWritableSelectorFamily(options, s),
|
|
47
46
|
} as const,
|
|
48
|
-
)
|
|
47
|
+
) satisfies WritableSelectorFamily<T, K>
|
|
49
48
|
store.families.set(options.key, selectorFamily)
|
|
50
49
|
return selectorFamily
|
|
51
50
|
}
|
|
@@ -21,6 +21,8 @@ import type { Json } from "atom.io/json"
|
|
|
21
21
|
import type { Transceiver } from "../mutable"
|
|
22
22
|
import { NotFoundError } from "../not-found-error"
|
|
23
23
|
import type { Store } from "../store"
|
|
24
|
+
import { initFamilyMember } from "./init-family-member"
|
|
25
|
+
import { seekInStore } from "./seek-in-store"
|
|
24
26
|
|
|
25
27
|
export function findInStore<
|
|
26
28
|
T extends Transceiver<any>,
|
|
@@ -80,11 +82,15 @@ export function findInStore(
|
|
|
80
82
|
key: Json.Serializable,
|
|
81
83
|
store: Store,
|
|
82
84
|
): ReadableToken<any> {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if (store.config.lifespan === `immortal`) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`,
|
|
88
|
+
)
|
|
87
89
|
}
|
|
88
|
-
|
|
90
|
+
let state = seekInStore(token, key, store)
|
|
91
|
+
if (state) {
|
|
92
|
+
return state
|
|
93
|
+
}
|
|
94
|
+
state = initFamilyMember(token, key, store)
|
|
89
95
|
return state
|
|
90
96
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AtomFamilyToken,
|
|
3
|
+
AtomToken,
|
|
4
|
+
MutableAtomFamilyToken,
|
|
5
|
+
MutableAtomToken,
|
|
6
|
+
ReadableFamilyToken,
|
|
7
|
+
ReadableToken,
|
|
8
|
+
ReadonlySelectorFamilyToken,
|
|
9
|
+
ReadonlySelectorToken,
|
|
10
|
+
RegularAtomFamilyToken,
|
|
11
|
+
RegularAtomToken,
|
|
12
|
+
SelectorFamilyToken,
|
|
13
|
+
SelectorToken,
|
|
14
|
+
WritableFamilyToken,
|
|
15
|
+
WritableSelectorFamilyToken,
|
|
16
|
+
WritableSelectorToken,
|
|
17
|
+
WritableToken,
|
|
18
|
+
} from "atom.io"
|
|
19
|
+
import type { Json } from "atom.io/json"
|
|
20
|
+
|
|
21
|
+
import type { Transceiver } from "../mutable"
|
|
22
|
+
import { NotFoundError } from "../not-found-error"
|
|
23
|
+
import type { Store } from "../store"
|
|
24
|
+
import { seekInStore } from "./seek-in-store"
|
|
25
|
+
|
|
26
|
+
export function initFamilyMember<
|
|
27
|
+
T extends Transceiver<any>,
|
|
28
|
+
J extends Json.Serializable,
|
|
29
|
+
K extends Json.Serializable,
|
|
30
|
+
Key extends K,
|
|
31
|
+
>(
|
|
32
|
+
token: MutableAtomFamilyToken<T, J, K>,
|
|
33
|
+
key: Key,
|
|
34
|
+
store: Store,
|
|
35
|
+
): MutableAtomToken<T, J>
|
|
36
|
+
|
|
37
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
38
|
+
token: RegularAtomFamilyToken<T, K>,
|
|
39
|
+
key: Key,
|
|
40
|
+
store: Store,
|
|
41
|
+
): RegularAtomToken<T>
|
|
42
|
+
|
|
43
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
44
|
+
token: AtomFamilyToken<T, K>,
|
|
45
|
+
key: Key,
|
|
46
|
+
store: Store,
|
|
47
|
+
): AtomToken<T>
|
|
48
|
+
|
|
49
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
50
|
+
token: WritableSelectorFamilyToken<T, K>,
|
|
51
|
+
key: Key,
|
|
52
|
+
store: Store,
|
|
53
|
+
): WritableSelectorToken<T>
|
|
54
|
+
|
|
55
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
56
|
+
token: ReadonlySelectorFamilyToken<T, K>,
|
|
57
|
+
key: Key,
|
|
58
|
+
store: Store,
|
|
59
|
+
): ReadonlySelectorToken<T>
|
|
60
|
+
|
|
61
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
62
|
+
token: SelectorFamilyToken<T, K>,
|
|
63
|
+
key: Key,
|
|
64
|
+
store: Store,
|
|
65
|
+
): SelectorToken<T>
|
|
66
|
+
|
|
67
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
68
|
+
token: WritableFamilyToken<T, K>,
|
|
69
|
+
key: Key,
|
|
70
|
+
store: Store,
|
|
71
|
+
): WritableToken<T>
|
|
72
|
+
|
|
73
|
+
export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
|
|
74
|
+
token: ReadableFamilyToken<T, K>,
|
|
75
|
+
key: Key,
|
|
76
|
+
store: Store,
|
|
77
|
+
): ReadableToken<T>
|
|
78
|
+
|
|
79
|
+
export function initFamilyMember(
|
|
80
|
+
token: ReadableFamilyToken<any, any>,
|
|
81
|
+
key: Json.Serializable,
|
|
82
|
+
store: Store,
|
|
83
|
+
): ReadableToken<any> {
|
|
84
|
+
const familyKey = token.key
|
|
85
|
+
const family = store.families.get(familyKey)
|
|
86
|
+
if (family === undefined) {
|
|
87
|
+
throw new NotFoundError(token, store)
|
|
88
|
+
}
|
|
89
|
+
const state = family(key)
|
|
90
|
+
return state
|
|
91
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AtomFamilyToken,
|
|
3
|
+
AtomToken,
|
|
4
|
+
MutableAtomFamilyToken,
|
|
5
|
+
MutableAtomToken,
|
|
6
|
+
ReadableFamilyToken,
|
|
7
|
+
ReadableToken,
|
|
8
|
+
ReadonlySelectorFamilyToken,
|
|
9
|
+
ReadonlySelectorToken,
|
|
10
|
+
RegularAtomFamilyToken,
|
|
11
|
+
RegularAtomToken,
|
|
12
|
+
SelectorFamilyToken,
|
|
13
|
+
SelectorToken,
|
|
14
|
+
WritableFamilyToken,
|
|
15
|
+
WritableSelectorFamilyToken,
|
|
16
|
+
WritableSelectorToken,
|
|
17
|
+
WritableToken,
|
|
18
|
+
} from "atom.io"
|
|
19
|
+
import { type Json, stringifyJson } from "atom.io/json"
|
|
20
|
+
|
|
21
|
+
import type { ReadableState } from ".."
|
|
22
|
+
import { newest } from "../lineage"
|
|
23
|
+
import type { Transceiver } from "../mutable"
|
|
24
|
+
import { deposit, type Store } from "../store"
|
|
25
|
+
|
|
26
|
+
export function seekInStore<
|
|
27
|
+
T extends Transceiver<any>,
|
|
28
|
+
J extends Json.Serializable,
|
|
29
|
+
K extends Json.Serializable,
|
|
30
|
+
Key extends K,
|
|
31
|
+
>(
|
|
32
|
+
token: MutableAtomFamilyToken<T, J, K>,
|
|
33
|
+
key: Key,
|
|
34
|
+
store: Store,
|
|
35
|
+
): MutableAtomToken<T, J> | undefined
|
|
36
|
+
|
|
37
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
38
|
+
token: RegularAtomFamilyToken<T, K>,
|
|
39
|
+
key: Key,
|
|
40
|
+
store: Store,
|
|
41
|
+
): RegularAtomToken<T> | undefined
|
|
42
|
+
|
|
43
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
44
|
+
token: AtomFamilyToken<T, K>,
|
|
45
|
+
key: Key,
|
|
46
|
+
store: Store,
|
|
47
|
+
): AtomToken<T> | undefined
|
|
48
|
+
|
|
49
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
50
|
+
token: WritableSelectorFamilyToken<T, K>,
|
|
51
|
+
key: Key,
|
|
52
|
+
store: Store,
|
|
53
|
+
): WritableSelectorToken<T> | undefined
|
|
54
|
+
|
|
55
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
56
|
+
token: ReadonlySelectorFamilyToken<T, K>,
|
|
57
|
+
key: Key,
|
|
58
|
+
store: Store,
|
|
59
|
+
): ReadonlySelectorToken<T> | undefined
|
|
60
|
+
|
|
61
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
62
|
+
token: SelectorFamilyToken<T, K>,
|
|
63
|
+
key: Key,
|
|
64
|
+
store: Store,
|
|
65
|
+
): SelectorToken<T> | undefined
|
|
66
|
+
|
|
67
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
68
|
+
token: WritableFamilyToken<T, K>,
|
|
69
|
+
key: Key,
|
|
70
|
+
store: Store,
|
|
71
|
+
): WritableToken<T> | undefined
|
|
72
|
+
|
|
73
|
+
export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
74
|
+
token: ReadableFamilyToken<T, K>,
|
|
75
|
+
key: Key,
|
|
76
|
+
store: Store,
|
|
77
|
+
): ReadableToken<T> | undefined
|
|
78
|
+
|
|
79
|
+
export function seekInStore(
|
|
80
|
+
token: ReadableFamilyToken<any, any>,
|
|
81
|
+
key: Json.Serializable,
|
|
82
|
+
store: Store,
|
|
83
|
+
): ReadableToken<any> | undefined {
|
|
84
|
+
const subKey = stringifyJson(key)
|
|
85
|
+
const fullKey = `${token.key}(${subKey})`
|
|
86
|
+
const target = newest(store)
|
|
87
|
+
let state: ReadableState<any> | undefined
|
|
88
|
+
switch (token.type) {
|
|
89
|
+
case `atom_family`:
|
|
90
|
+
case `mutable_atom_family`:
|
|
91
|
+
state = target.atoms.get(fullKey)
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
case `selector_family`: {
|
|
95
|
+
state = target.selectors.get(fullKey)
|
|
96
|
+
break
|
|
97
|
+
}
|
|
98
|
+
case `readonly_selector_family`:
|
|
99
|
+
state = target.readonlySelectors.get(fullKey)
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
if (state) {
|
|
103
|
+
return deposit(state)
|
|
104
|
+
}
|
|
105
|
+
return state
|
|
106
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ReadableToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from "../store"
|
|
4
|
-
import {
|
|
4
|
+
import { withdraw } from "../store"
|
|
5
5
|
import { readOrComputeValue } from "./read-or-compute-value"
|
|
6
6
|
|
|
7
7
|
export function getFromStore<T>(token: ReadableToken<T>, store: Store): T {
|
|
8
|
-
const state =
|
|
8
|
+
const state = withdraw(token, store)
|
|
9
9
|
return readOrComputeValue(state, store)
|
|
10
10
|
}
|
|
@@ -24,32 +24,28 @@ export function createMutableAtomFamily<
|
|
|
24
24
|
store: Store,
|
|
25
25
|
): MutableAtomFamily<T, J, K> {
|
|
26
26
|
const subject = new Subject<MutableAtomToken<T, J>>()
|
|
27
|
-
|
|
27
|
+
|
|
28
|
+
const atomFamily = Object.assign(
|
|
28
29
|
(key: K): MutableAtomToken<T, J> => {
|
|
29
30
|
const subKey = stringifyJson(key)
|
|
30
31
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
31
32
|
const fullKey = `${options.key}(${subKey})`
|
|
32
33
|
const target = newest(store)
|
|
33
|
-
const atomAlreadyCreated = target.atoms.has(fullKey)
|
|
34
|
-
let token: MutableAtomToken<T, J>
|
|
35
|
-
if (atomAlreadyCreated) {
|
|
36
|
-
token = { type: `mutable_atom`, key: fullKey, family }
|
|
37
|
-
} else {
|
|
38
|
-
const individualOptions: MutableAtomOptions<T, J> = {
|
|
39
|
-
key: fullKey,
|
|
40
|
-
default: () => options.default(key),
|
|
41
|
-
toJson: options.toJson,
|
|
42
|
-
fromJson: options.fromJson,
|
|
43
|
-
mutable: true,
|
|
44
|
-
}
|
|
45
|
-
if (options.effects) {
|
|
46
|
-
individualOptions.effects = options.effects(key)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
token = createMutableAtom(individualOptions, family, store)
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
const individualOptions: MutableAtomOptions<T, J> = {
|
|
36
|
+
key: fullKey,
|
|
37
|
+
default: () => options.default(key),
|
|
38
|
+
toJson: options.toJson,
|
|
39
|
+
fromJson: options.fromJson,
|
|
40
|
+
mutable: true,
|
|
41
|
+
}
|
|
42
|
+
if (options.effects) {
|
|
43
|
+
individualOptions.effects = options.effects(key)
|
|
52
44
|
}
|
|
45
|
+
|
|
46
|
+
const token = createMutableAtom(individualOptions, family, target)
|
|
47
|
+
|
|
48
|
+
subject.next(token)
|
|
53
49
|
return token
|
|
54
50
|
},
|
|
55
51
|
{
|
|
@@ -60,10 +56,8 @@ export function createMutableAtomFamily<
|
|
|
60
56
|
toJson: options.toJson,
|
|
61
57
|
fromJson: options.fromJson,
|
|
62
58
|
} as const,
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
const target = newest(store)
|
|
66
|
-
target.families.set(options.key, atomFamily)
|
|
59
|
+
) satisfies MutableAtomFamily<T, J, K>
|
|
60
|
+
store.families.set(options.key, atomFamily)
|
|
67
61
|
selectJsonFamily(atomFamily, options, store)
|
|
68
62
|
new FamilyTracker(atomFamily, store)
|
|
69
63
|
return atomFamily
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MutableAtomFamilyToken, WritableSelectorFamily } from "atom.io"
|
|
2
2
|
import type { Json } from "atom.io/json"
|
|
3
3
|
|
|
4
4
|
import { newest } from "../lineage"
|
|
@@ -10,7 +10,7 @@ export const getJsonFamily = <
|
|
|
10
10
|
SerializableCore extends Json.Serializable,
|
|
11
11
|
Key extends string,
|
|
12
12
|
>(
|
|
13
|
-
mutableAtomFamily:
|
|
13
|
+
mutableAtomFamily: MutableAtomFamilyToken<Core, SerializableCore, Key>,
|
|
14
14
|
store: Store,
|
|
15
15
|
): WritableSelectorFamily<SerializableCore, Key> => {
|
|
16
16
|
const target = newest(store)
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MutableAtomToken,
|
|
3
|
+
WritableSelectorFamily,
|
|
4
|
+
WritableSelectorFamilyToken,
|
|
5
|
+
WritableSelectorToken,
|
|
6
|
+
} from "atom.io"
|
|
2
7
|
import type { Json } from "atom.io/json"
|
|
3
8
|
|
|
9
|
+
import { findInStore } from "../families"
|
|
10
|
+
import { newest } from "../lineage"
|
|
11
|
+
import { type Store, withdraw } from "../store"
|
|
4
12
|
import type { Transceiver } from "./transceiver"
|
|
5
13
|
|
|
6
14
|
export const getJsonToken = <
|
|
@@ -8,19 +16,26 @@ export const getJsonToken = <
|
|
|
8
16
|
SerializableCore extends Json.Serializable,
|
|
9
17
|
>(
|
|
10
18
|
mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
|
|
19
|
+
store: Store,
|
|
11
20
|
): WritableSelectorToken<SerializableCore> => {
|
|
12
|
-
const key = mutableAtomToken.family
|
|
13
|
-
? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})`
|
|
14
|
-
: `${mutableAtomToken.key}:JSON`
|
|
15
|
-
const jsonToken: WritableSelectorToken<SerializableCore> = {
|
|
16
|
-
type: `selector`,
|
|
17
|
-
key,
|
|
18
|
-
}
|
|
19
21
|
if (mutableAtomToken.family) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
const target = newest(store)
|
|
23
|
+
const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`
|
|
24
|
+
const jsonFamilyToken: WritableSelectorFamilyToken<
|
|
25
|
+
SerializableCore,
|
|
26
|
+
string
|
|
27
|
+
> = {
|
|
28
|
+
key: jsonFamilyKey,
|
|
29
|
+
type: `selector_family`,
|
|
23
30
|
}
|
|
31
|
+
const family = withdraw(jsonFamilyToken, target)
|
|
32
|
+
const subKey = JSON.parse(mutableAtomToken.family.subKey)
|
|
33
|
+
const jsonToken = findInStore(family, subKey, store)
|
|
34
|
+
return jsonToken
|
|
35
|
+
}
|
|
36
|
+
const token: WritableSelectorToken<SerializableCore> = {
|
|
37
|
+
type: `selector`,
|
|
38
|
+
key: `${mutableAtomToken.key}:JSON`,
|
|
24
39
|
}
|
|
25
|
-
return
|
|
40
|
+
return token
|
|
26
41
|
}
|
|
@@ -2,7 +2,7 @@ import type { MutableAtomFamily, RegularAtomFamily } from "atom.io"
|
|
|
2
2
|
import type { Json } from "atom.io/json"
|
|
3
3
|
import { parseJson } from "atom.io/json"
|
|
4
4
|
|
|
5
|
-
import { createRegularAtomFamily } from "../families"
|
|
5
|
+
import { createRegularAtomFamily, seekInStore } from "../families"
|
|
6
6
|
import type { Store } from "../store"
|
|
7
7
|
import { Tracker } from "./tracker"
|
|
8
8
|
import type { Transceiver } from "./transceiver"
|
|
@@ -15,44 +15,46 @@ export class FamilyTracker<
|
|
|
15
15
|
? Signal
|
|
16
16
|
: never
|
|
17
17
|
|
|
18
|
-
public readonly
|
|
18
|
+
public readonly latestUpdateAtoms: RegularAtomFamily<
|
|
19
19
|
typeof this.Update | null,
|
|
20
20
|
FamilyMemberKey
|
|
21
21
|
>
|
|
22
|
-
public readonly
|
|
22
|
+
public readonly mutableAtoms: MutableAtomFamily<Core, any, FamilyMemberKey>
|
|
23
23
|
|
|
24
24
|
public constructor(
|
|
25
|
-
|
|
25
|
+
mutableAtoms: MutableAtomFamily<Core, any, FamilyMemberKey>,
|
|
26
26
|
store: Store,
|
|
27
27
|
) {
|
|
28
|
-
this.
|
|
28
|
+
this.latestUpdateAtoms = createRegularAtomFamily<
|
|
29
29
|
typeof this.Update | null,
|
|
30
30
|
FamilyMemberKey
|
|
31
31
|
>(
|
|
32
32
|
{
|
|
33
|
-
key: `*${
|
|
33
|
+
key: `*${mutableAtoms.key}`,
|
|
34
34
|
default: null,
|
|
35
35
|
},
|
|
36
36
|
store,
|
|
37
37
|
)
|
|
38
|
-
this.
|
|
39
|
-
this.
|
|
38
|
+
this.mutableAtoms = mutableAtoms
|
|
39
|
+
this.mutableAtoms.subject.subscribe(
|
|
40
40
|
`store=${store.config.name}::tracker-atom-family`,
|
|
41
41
|
(atomToken) => {
|
|
42
42
|
if (atomToken.family) {
|
|
43
43
|
const key = parseJson(atomToken.family.subKey) as FamilyMemberKey
|
|
44
|
-
this.
|
|
44
|
+
seekInStore(this.latestUpdateAtoms, key, store)
|
|
45
45
|
new Tracker<Core>(atomToken, store)
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
)
|
|
49
|
-
this.
|
|
49
|
+
this.latestUpdateAtoms.subject.subscribe(
|
|
50
50
|
`store=${store.config.name}::tracker-atom-family`,
|
|
51
51
|
(atomToken) => {
|
|
52
52
|
if (atomToken.family) {
|
|
53
53
|
const key = parseJson(atomToken.family.subKey) as FamilyMemberKey
|
|
54
|
-
const mutableAtomToken = this.
|
|
55
|
-
|
|
54
|
+
const mutableAtomToken = seekInStore(this.mutableAtoms, key, store)
|
|
55
|
+
if (mutableAtomToken) {
|
|
56
|
+
new Tracker<Core>(mutableAtomToken, store)
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
},
|
|
58
60
|
)
|
|
@@ -16,10 +16,18 @@ type AtomIOToken =
|
|
|
16
16
|
| TransactionToken<any>
|
|
17
17
|
|
|
18
18
|
function prettyPrintTokenType(token: AtomIOToken) {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
switch (token.type) {
|
|
20
|
+
case `atom_family`:
|
|
21
|
+
return `Atom Family`
|
|
22
|
+
case `readonly_selector`:
|
|
23
|
+
return `Readonly Selector`
|
|
24
|
+
case `readonly_selector_family`:
|
|
25
|
+
return `Readonly Selector Family`
|
|
26
|
+
case `selector_family`:
|
|
27
|
+
return `Selector Family`
|
|
28
|
+
default:
|
|
29
|
+
return capitalize(token.type)
|
|
21
30
|
}
|
|
22
|
-
return capitalize(token.type)
|
|
23
31
|
}
|
|
24
32
|
|
|
25
33
|
export class NotFoundError extends Error {
|
|
@@ -19,9 +19,9 @@ export const createReadonlySelector = <T>(
|
|
|
19
19
|
const target = newest(store)
|
|
20
20
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
21
21
|
|
|
22
|
-
const { get, find } = registerSelector(options.key, target)
|
|
22
|
+
const { get, find, seek } = registerSelector(options.key, target)
|
|
23
23
|
const getSelf = () => {
|
|
24
|
-
const value = options.get({ get, find })
|
|
24
|
+
const value = options.get({ get, find, seek })
|
|
25
25
|
cacheValue(options.key, value, subject, newest(store))
|
|
26
26
|
return value
|
|
27
27
|
}
|
|
@@ -22,8 +22,8 @@ export const createWritableSelector = <T>(
|
|
|
22
22
|
const target = newest(store)
|
|
23
23
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
24
24
|
const transactors = registerSelector(options.key, target)
|
|
25
|
-
const { find, get } = transactors
|
|
26
|
-
const readonlyTransactors = { find, get }
|
|
25
|
+
const { find, get, seek } = transactors
|
|
26
|
+
const readonlyTransactors = { find, get, seek }
|
|
27
27
|
|
|
28
28
|
const getSelf = () => {
|
|
29
29
|
const value = options.get(readonlyTransactors)
|
|
@@ -9,30 +9,47 @@ export function disposeSelector(
|
|
|
9
9
|
): void {
|
|
10
10
|
const target = newest(store)
|
|
11
11
|
const { key } = selectorToken
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
([downstreamSelectorKey]) =>
|
|
27
|
-
target.selectors.get(downstreamSelectorKey) ??
|
|
28
|
-
target.readonlySelectors.get(downstreamSelectorKey),
|
|
12
|
+
const selector = target.selectors.get(key) ?? target.readonlySelectors.get(key)
|
|
13
|
+
if (!selector) {
|
|
14
|
+
store.logger.error(
|
|
15
|
+
`❌`,
|
|
16
|
+
`selector`,
|
|
17
|
+
key,
|
|
18
|
+
`Tried to dispose selector, but it does not exist in the store.`,
|
|
19
|
+
)
|
|
20
|
+
} else if (!selector.family) {
|
|
21
|
+
store.logger.error(
|
|
22
|
+
`❌`,
|
|
23
|
+
`selector`,
|
|
24
|
+
key,
|
|
25
|
+
`Standalone selectors cannot be disposed.`,
|
|
29
26
|
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
} else {
|
|
28
|
+
switch (selectorToken.type) {
|
|
29
|
+
case `selector`:
|
|
30
|
+
target.selectors.delete(key)
|
|
31
|
+
break
|
|
32
|
+
case `readonly_selector`:
|
|
33
|
+
target.readonlySelectors.delete(key)
|
|
34
|
+
break
|
|
35
|
+
}
|
|
36
|
+
target.valueMap.delete(key)
|
|
37
|
+
target.selectorAtoms.delete(key)
|
|
38
|
+
const downstreamTokens = target.selectorGraph
|
|
39
|
+
.getRelationEntries({ upstreamSelectorKey: key })
|
|
40
|
+
.filter(([_, { source }]) => source === key)
|
|
41
|
+
.map(
|
|
42
|
+
([downstreamSelectorKey]) =>
|
|
43
|
+
target.selectors.get(downstreamSelectorKey) ??
|
|
44
|
+
target.readonlySelectors.get(downstreamSelectorKey),
|
|
45
|
+
)
|
|
46
|
+
for (const downstreamToken of downstreamTokens) {
|
|
47
|
+
if (downstreamToken) {
|
|
48
|
+
disposeSelector(downstreamToken, store)
|
|
49
|
+
}
|
|
33
50
|
}
|
|
51
|
+
target.selectorGraph.delete(key)
|
|
52
|
+
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
53
|
+
store.on.selectorDisposal.next(selectorToken)
|
|
34
54
|
}
|
|
35
|
-
target.selectorGraph.delete(key)
|
|
36
|
-
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
37
|
-
store.on.selectorDisposal.next(selectorToken)
|
|
38
55
|
}
|