atom.io 0.21.1 → 0.23.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 +152 -63
- package/data/dist/index.d.ts +6 -0
- package/data/dist/index.js +3 -3
- package/data/src/join.ts +164 -51
- package/data/src/struct-family.ts +2 -2
- package/dist/chunk-6MLFYN32.js +18 -0
- package/dist/{chunk-HITX3MO4.js → chunk-7DT3PVS3.js} +151 -62
- package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
- package/dist/chunk-OAYGID5B.js +27 -0
- package/dist/index.cjs +4 -18
- package/dist/index.d.ts +71 -28
- package/dist/index.js +6 -19
- 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 +155 -1
- package/eslint-plugin/dist/index.js +155 -1
- package/eslint-plugin/src/rules/index.ts +1 -0
- package/eslint-plugin/src/rules/lifespan.ts +203 -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 +260 -0
- package/immortal/dist/index.js +212 -0
- package/immortal/package.json +16 -0
- package/immortal/src/index.ts +3 -0
- package/immortal/src/make-molecule.ts +222 -0
- package/immortal/src/molecule.ts +167 -0
- package/immortal/src/seek-state.ts +73 -0
- package/internal/dist/index.cjs +1242 -837
- package/internal/dist/index.d.ts +135 -22
- package/internal/dist/index.js +1215 -838
- package/internal/src/atom/create-regular-atom.ts +0 -2
- package/internal/src/atom/create-standalone-atom.ts +6 -2
- package/internal/src/atom/dispose-atom.ts +26 -3
- package/internal/src/families/create-readonly-selector-family.ts +15 -10
- package/internal/src/families/create-regular-atom-family.ts +20 -21
- package/internal/src/families/create-writable-selector-family.ts +13 -9
- package/{src/dispose.ts → internal/src/families/dispose-from-store.ts} +7 -4
- package/internal/src/families/find-in-store.ts +11 -6
- package/internal/src/families/index.ts +3 -0
- package/internal/src/families/init-family-member.ts +112 -0
- package/internal/src/families/seek-in-store.ts +123 -0
- package/internal/src/get-state/get-from-store.ts +2 -2
- package/internal/src/ingest-updates/index.ts +1 -0
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +104 -0
- package/internal/src/ingest-updates/ingest-transaction-update.ts +26 -4
- package/internal/src/mutable/create-mutable-atom-family.ts +22 -24
- package/internal/src/mutable/create-mutable-atom.ts +3 -3
- package/internal/src/mutable/get-json-family.ts +2 -2
- package/internal/src/mutable/get-json-token.ts +26 -12
- package/internal/src/mutable/tracker-family.ts +21 -19
- package/internal/src/not-found-error.ts +16 -3
- package/internal/src/selector/create-readonly-selector.ts +2 -3
- package/internal/src/selector/create-standalone-selector.ts +6 -2
- package/internal/src/selector/create-writable-selector.ts +2 -3
- package/internal/src/selector/dispose-selector.ts +68 -24
- package/internal/src/selector/register-selector.ts +10 -5
- package/internal/src/set-state/set-into-store.ts +2 -2
- package/internal/src/set-state/stow-update.ts +5 -1
- package/internal/src/store/deposit.ts +41 -7
- package/internal/src/store/index.ts +0 -1
- package/internal/src/store/store.ts +29 -5
- package/internal/src/store/withdraw.ts +28 -1
- package/internal/src/subscribe/subscribe-to-state.ts +2 -2
- package/internal/src/timeline/add-atom-to-timeline.ts +206 -182
- package/internal/src/timeline/create-timeline.ts +181 -60
- package/internal/src/timeline/time-travel.ts +20 -0
- package/internal/src/transaction/apply-transaction.ts +2 -12
- package/internal/src/transaction/build-transaction.ts +16 -2
- package/introspection/dist/index.cjs +40 -53
- package/introspection/dist/index.js +40 -53
- package/introspection/src/attach-atom-index.ts +38 -48
- package/introspection/src/attach-selector-index.ts +45 -50
- package/introspection/src/attach-timeline-family.ts +1 -0
- package/json/dist/index.cjs +40 -6
- package/json/dist/index.js +44 -9
- package/json/src/select-json-family.ts +47 -9
- 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 +69 -57
- package/react-devtools/dist/index.js +62 -49
- package/react-devtools/src/StateIndex.tsx +2 -1
- package/react-devtools/src/TimelineIndex.tsx +17 -14
- package/react-devtools/src/TransactionIndex.tsx +7 -7
- package/react-devtools/src/Updates.tsx +41 -32
- 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 +39 -27
- package/realtime-server/dist/index.d.ts +1 -1
- package/realtime-server/dist/index.js +27 -16
- 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-server/src/realtime-server-stores/server-sync-store.ts +21 -11
- package/realtime-testing/dist/index.cjs +7 -2
- package/realtime-testing/dist/index.js +8 -5
- package/realtime-testing/src/setup-realtime-test.tsx +5 -2
- package/src/atom.ts +19 -7
- package/src/dispose-state.ts +10 -0
- package/src/index.ts +5 -2
- package/src/selector.ts +13 -7
- package/src/silo.ts +3 -3
- package/src/subscribe.ts +8 -4
- package/src/timeline.ts +18 -1
- package/src/transaction.ts +59 -4
- package/dist/chunk-BF4MVQF6.js +0 -44
- package/internal/src/store/withdraw-new-family-member.ts +0 -69
- /package/{src → ephemeral/src}/find-state.ts +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { parseJson } from "anvl/json"
|
|
2
|
+
import type {
|
|
3
|
+
MoleculeCreation,
|
|
4
|
+
MoleculeDisposal,
|
|
5
|
+
ReadableToken,
|
|
6
|
+
StateCreation,
|
|
7
|
+
StateDisposal,
|
|
8
|
+
} from "atom.io"
|
|
9
|
+
import { disposeMolecule, makeMoleculeInStore } from "atom.io/immortal"
|
|
10
|
+
|
|
11
|
+
import { disposeFromStore, initFamilyMember } from "../families"
|
|
12
|
+
import type { Store } from "../store"
|
|
13
|
+
|
|
14
|
+
export function ingestCreationEvent(
|
|
15
|
+
update: StateCreation<any>,
|
|
16
|
+
applying: `newValue` | `oldValue`,
|
|
17
|
+
store: Store,
|
|
18
|
+
): void {
|
|
19
|
+
switch (applying) {
|
|
20
|
+
case `newValue`: {
|
|
21
|
+
createInStore(update.token, store)
|
|
22
|
+
break
|
|
23
|
+
}
|
|
24
|
+
case `oldValue`: {
|
|
25
|
+
disposeFromStore(update.token, store)
|
|
26
|
+
break
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function ingestDisposalEvent(
|
|
32
|
+
update: StateDisposal<any>,
|
|
33
|
+
applying: `newValue` | `oldValue`,
|
|
34
|
+
store: Store,
|
|
35
|
+
): void {
|
|
36
|
+
switch (applying) {
|
|
37
|
+
case `newValue`: {
|
|
38
|
+
disposeFromStore(update.token, store)
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
case `oldValue`: {
|
|
42
|
+
createInStore(update.token, store)
|
|
43
|
+
store.valueMap.set(update.token.key, update.value)
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createInStore(token: ReadableToken<any>, store: Store): void {
|
|
50
|
+
if (token.family) {
|
|
51
|
+
const family = store.families.get(token.family.key)
|
|
52
|
+
if (family) {
|
|
53
|
+
const molecule = store.molecules.get(token.family.subKey)
|
|
54
|
+
if (molecule) {
|
|
55
|
+
molecule.bond(family)
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
if (store.config.lifespan === `immortal`) {
|
|
59
|
+
throw new Error(`No molecule found for key "${token.family.subKey}"`)
|
|
60
|
+
}
|
|
61
|
+
initFamilyMember(family, parseJson(token.family.subKey), store)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function ingestMoleculeCreationEvent(
|
|
67
|
+
update: MoleculeCreation<any>,
|
|
68
|
+
applying: `newValue` | `oldValue`,
|
|
69
|
+
store: Store,
|
|
70
|
+
): void {
|
|
71
|
+
switch (applying) {
|
|
72
|
+
case `newValue`:
|
|
73
|
+
makeMoleculeInStore(
|
|
74
|
+
store,
|
|
75
|
+
update.context[0],
|
|
76
|
+
update.family,
|
|
77
|
+
update.token.key,
|
|
78
|
+
...update.params,
|
|
79
|
+
)
|
|
80
|
+
break
|
|
81
|
+
case `oldValue`:
|
|
82
|
+
disposeMolecule(update.token, store)
|
|
83
|
+
break
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function ingestMoleculeDisposalEvent(
|
|
87
|
+
update: MoleculeDisposal<any>,
|
|
88
|
+
applying: `newValue` | `oldValue`,
|
|
89
|
+
store: Store,
|
|
90
|
+
): void {
|
|
91
|
+
switch (applying) {
|
|
92
|
+
case `newValue`:
|
|
93
|
+
disposeMolecule(update.token, store)
|
|
94
|
+
break
|
|
95
|
+
case `oldValue`:
|
|
96
|
+
makeMoleculeInStore(
|
|
97
|
+
store,
|
|
98
|
+
update.context[0],
|
|
99
|
+
update.family,
|
|
100
|
+
update.token.key,
|
|
101
|
+
)
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -2,6 +2,12 @@ import type { TransactionUpdate } from "atom.io"
|
|
|
2
2
|
|
|
3
3
|
import type { Store } from "../store"
|
|
4
4
|
import { ingestAtomUpdate } from "./ingest-atom-update"
|
|
5
|
+
import {
|
|
6
|
+
ingestCreationEvent,
|
|
7
|
+
ingestDisposalEvent,
|
|
8
|
+
ingestMoleculeCreationEvent,
|
|
9
|
+
ingestMoleculeDisposalEvent,
|
|
10
|
+
} from "./ingest-creation-disposal"
|
|
5
11
|
|
|
6
12
|
export function ingestTransactionUpdate(
|
|
7
13
|
applying: `newValue` | `oldValue`,
|
|
@@ -13,10 +19,26 @@ export function ingestTransactionUpdate(
|
|
|
13
19
|
? transactionUpdate.updates
|
|
14
20
|
: [...transactionUpdate.updates].reverse()
|
|
15
21
|
for (const updateFromTransaction of updates) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
switch (updateFromTransaction.type) {
|
|
23
|
+
case `atom_update`:
|
|
24
|
+
case `selector_update`:
|
|
25
|
+
ingestAtomUpdate(applying, updateFromTransaction, store)
|
|
26
|
+
break
|
|
27
|
+
case `state_creation`:
|
|
28
|
+
ingestCreationEvent(updateFromTransaction, applying, store)
|
|
29
|
+
break
|
|
30
|
+
case `state_disposal`:
|
|
31
|
+
ingestDisposalEvent(updateFromTransaction, applying, store)
|
|
32
|
+
break
|
|
33
|
+
case `molecule_creation`:
|
|
34
|
+
ingestMoleculeCreationEvent(updateFromTransaction, applying, store)
|
|
35
|
+
break
|
|
36
|
+
case `molecule_disposal`:
|
|
37
|
+
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store)
|
|
38
|
+
break
|
|
39
|
+
case `transaction_update`:
|
|
40
|
+
ingestTransactionUpdate(applying, updateFromTransaction, store)
|
|
41
|
+
break
|
|
20
42
|
}
|
|
21
43
|
}
|
|
22
44
|
}
|
|
@@ -4,6 +4,8 @@ import type {
|
|
|
4
4
|
MutableAtomFamilyOptions,
|
|
5
5
|
MutableAtomOptions,
|
|
6
6
|
MutableAtomToken,
|
|
7
|
+
StateCreation,
|
|
8
|
+
StateDisposal,
|
|
7
9
|
} from "atom.io"
|
|
8
10
|
import type { Json } from "atom.io/json"
|
|
9
11
|
import { selectJsonFamily, stringifyJson } from "atom.io/json"
|
|
@@ -23,33 +25,31 @@ export function createMutableAtomFamily<
|
|
|
23
25
|
options: MutableAtomFamilyOptions<T, J, K>,
|
|
24
26
|
store: Store,
|
|
25
27
|
): MutableAtomFamily<T, J, K> {
|
|
26
|
-
const subject = new Subject<
|
|
27
|
-
|
|
28
|
+
const subject = new Subject<
|
|
29
|
+
StateCreation<MutableAtomToken<T, J>> | StateDisposal<MutableAtomToken<T, J>>
|
|
30
|
+
>()
|
|
31
|
+
|
|
32
|
+
const atomFamily = Object.assign(
|
|
28
33
|
(key: K): MutableAtomToken<T, J> => {
|
|
29
34
|
const subKey = stringifyJson(key)
|
|
30
35
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
31
36
|
const fullKey = `${options.key}(${subKey})`
|
|
32
37
|
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
38
|
|
|
51
|
-
|
|
39
|
+
const individualOptions: MutableAtomOptions<T, J> = {
|
|
40
|
+
key: fullKey,
|
|
41
|
+
default: () => options.default(key),
|
|
42
|
+
toJson: options.toJson,
|
|
43
|
+
fromJson: options.fromJson,
|
|
44
|
+
mutable: true,
|
|
45
|
+
}
|
|
46
|
+
if (options.effects) {
|
|
47
|
+
individualOptions.effects = options.effects(key)
|
|
52
48
|
}
|
|
49
|
+
|
|
50
|
+
const token = createMutableAtom(individualOptions, family, target)
|
|
51
|
+
|
|
52
|
+
subject.next({ type: `state_creation`, token })
|
|
53
53
|
return token
|
|
54
54
|
},
|
|
55
55
|
{
|
|
@@ -60,10 +60,8 @@ export function createMutableAtomFamily<
|
|
|
60
60
|
toJson: options.toJson,
|
|
61
61
|
fromJson: options.fromJson,
|
|
62
62
|
} as const,
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
const target = newest(store)
|
|
66
|
-
target.families.set(options.key, atomFamily)
|
|
63
|
+
) satisfies MutableAtomFamily<T, J, K>
|
|
64
|
+
store.families.set(options.key, atomFamily)
|
|
67
65
|
selectJsonFamily(atomFamily, options, store)
|
|
68
66
|
new FamilyTracker(atomFamily, store)
|
|
69
67
|
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,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MutableAtomToken,
|
|
3
|
+
WritableSelectorFamilyToken,
|
|
4
|
+
WritableSelectorToken,
|
|
5
|
+
} from "atom.io"
|
|
2
6
|
import type { Json } from "atom.io/json"
|
|
3
7
|
|
|
8
|
+
import { findInStore } from "../families"
|
|
9
|
+
import { newest } from "../lineage"
|
|
10
|
+
import { type Store, withdraw } from "../store"
|
|
4
11
|
import type { Transceiver } from "./transceiver"
|
|
5
12
|
|
|
6
13
|
export const getJsonToken = <
|
|
@@ -8,19 +15,26 @@ export const getJsonToken = <
|
|
|
8
15
|
SerializableCore extends Json.Serializable,
|
|
9
16
|
>(
|
|
10
17
|
mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
|
|
18
|
+
store: Store,
|
|
11
19
|
): 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
20
|
if (mutableAtomToken.family) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const target = newest(store)
|
|
22
|
+
const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`
|
|
23
|
+
const jsonFamilyToken: WritableSelectorFamilyToken<
|
|
24
|
+
SerializableCore,
|
|
25
|
+
string
|
|
26
|
+
> = {
|
|
27
|
+
key: jsonFamilyKey,
|
|
28
|
+
type: `selector_family`,
|
|
23
29
|
}
|
|
30
|
+
const family = withdraw(jsonFamilyToken, target)
|
|
31
|
+
const subKey = JSON.parse(mutableAtomToken.family.subKey)
|
|
32
|
+
const jsonToken = findInStore(family, subKey, store)
|
|
33
|
+
return jsonToken
|
|
34
|
+
}
|
|
35
|
+
const token: WritableSelectorToken<SerializableCore> = {
|
|
36
|
+
type: `selector`,
|
|
37
|
+
key: `${mutableAtomToken.key}:JSON`,
|
|
24
38
|
}
|
|
25
|
-
return
|
|
39
|
+
return token
|
|
26
40
|
}
|
|
@@ -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
|
-
(
|
|
42
|
-
if (
|
|
43
|
-
const key = parseJson(
|
|
44
|
-
this.
|
|
45
|
-
new Tracker<Core>(
|
|
41
|
+
(event) => {
|
|
42
|
+
if (event.token.family) {
|
|
43
|
+
const key = parseJson(event.token.family.subKey) as FamilyMemberKey
|
|
44
|
+
seekInStore(this.latestUpdateAtoms, key, store)
|
|
45
|
+
new Tracker<Core>(event.token, store)
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
)
|
|
49
|
-
this.
|
|
49
|
+
this.latestUpdateAtoms.subject.subscribe(
|
|
50
50
|
`store=${store.config.name}::tracker-atom-family`,
|
|
51
|
-
(
|
|
52
|
-
if (
|
|
53
|
-
const key = parseJson(
|
|
54
|
-
const mutableAtomToken = this.
|
|
55
|
-
|
|
51
|
+
(event) => {
|
|
52
|
+
if (event.token.family) {
|
|
53
|
+
const key = parseJson(event.token.family.subKey) as FamilyMemberKey
|
|
54
|
+
const mutableAtomToken = seekInStore(this.mutableAtoms, key, store)
|
|
55
|
+
if (mutableAtomToken) {
|
|
56
|
+
new Tracker<Core>(mutableAtomToken, store)
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
},
|
|
58
60
|
)
|
|
@@ -4,22 +4,35 @@ import type {
|
|
|
4
4
|
TimelineToken,
|
|
5
5
|
TransactionToken,
|
|
6
6
|
} from "atom.io"
|
|
7
|
+
import type { MoleculeFamilyToken, MoleculeToken } from "atom.io/immortal"
|
|
7
8
|
|
|
8
9
|
import type { Store } from "./store"
|
|
9
10
|
|
|
10
11
|
const capitalize = (str: string) => str[0].toUpperCase() + str.slice(1)
|
|
11
12
|
|
|
12
13
|
type AtomIOToken =
|
|
14
|
+
| MoleculeFamilyToken<any, any, any>
|
|
15
|
+
| MoleculeToken<any, any, any>
|
|
13
16
|
| ReadableFamilyToken<any, any>
|
|
14
17
|
| ReadableToken<any>
|
|
15
18
|
| TimelineToken<any>
|
|
16
19
|
| TransactionToken<any>
|
|
17
20
|
|
|
18
21
|
function prettyPrintTokenType(token: AtomIOToken) {
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
switch (token.type) {
|
|
23
|
+
case `atom_family`:
|
|
24
|
+
return `Atom Family`
|
|
25
|
+
case `molecule_family`:
|
|
26
|
+
return `Molecule Family`
|
|
27
|
+
case `readonly_selector`:
|
|
28
|
+
return `Readonly Selector`
|
|
29
|
+
case `readonly_selector_family`:
|
|
30
|
+
return `Readonly Selector Family`
|
|
31
|
+
case `selector_family`:
|
|
32
|
+
return `Selector Family`
|
|
33
|
+
default:
|
|
34
|
+
return capitalize(token.type)
|
|
21
35
|
}
|
|
22
|
-
return capitalize(token.type)
|
|
23
36
|
}
|
|
24
37
|
|
|
25
38
|
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, json } = registerSelector(options.key, target)
|
|
23
23
|
const getSelf = () => {
|
|
24
|
-
const value = options.get({ get, find })
|
|
24
|
+
const value = options.get({ get, find, seek, json })
|
|
25
25
|
cacheValue(options.key, value, subject, newest(store))
|
|
26
26
|
return value
|
|
27
27
|
}
|
|
@@ -50,6 +50,5 @@ export const createReadonlySelector = <T>(
|
|
|
50
50
|
if (family) {
|
|
51
51
|
token.family = family
|
|
52
52
|
}
|
|
53
|
-
store.on.selectorCreation.next(token)
|
|
54
53
|
return token
|
|
55
54
|
}
|
|
@@ -24,7 +24,11 @@ export function createStandaloneSelector<T>(
|
|
|
24
24
|
const isWritable = `set` in options
|
|
25
25
|
|
|
26
26
|
if (isWritable) {
|
|
27
|
-
|
|
27
|
+
const state = createWritableSelector(options, undefined, store)
|
|
28
|
+
store.on.selectorCreation.next(state)
|
|
29
|
+
return state
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
const state = createReadonlySelector(options, undefined, store)
|
|
32
|
+
store.on.selectorCreation.next(state)
|
|
33
|
+
return state
|
|
30
34
|
}
|
|
@@ -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, json } = transactors
|
|
26
|
+
const readonlyTransactors = { find, get, seek, json }
|
|
27
27
|
|
|
28
28
|
const getSelf = () => {
|
|
29
29
|
const value = options.get(readonlyTransactors)
|
|
@@ -70,6 +70,5 @@ export const createWritableSelector = <T>(
|
|
|
70
70
|
if (family) {
|
|
71
71
|
token.family = family
|
|
72
72
|
}
|
|
73
|
-
store.on.selectorCreation.next(token)
|
|
74
73
|
return token
|
|
75
74
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReadonlySelectorToken, WritableSelectorToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
|
-
import { newest } from ".."
|
|
4
|
+
import { isChildStore, newest, withdraw } from ".."
|
|
5
5
|
|
|
6
6
|
export function disposeSelector(
|
|
7
7
|
selectorToken: ReadonlySelectorToken<unknown> | WritableSelectorToken<unknown>,
|
|
@@ -9,30 +9,74 @@ 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.info(
|
|
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
|
+
{
|
|
31
|
+
target.selectors.delete(key)
|
|
32
|
+
const family = withdraw(
|
|
33
|
+
{ key: selector.family.key, type: `selector_family` },
|
|
34
|
+
store,
|
|
35
|
+
)
|
|
36
|
+
family.subject.next({
|
|
37
|
+
type: `state_disposal`,
|
|
38
|
+
token: selectorToken,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
break
|
|
42
|
+
case `readonly_selector`:
|
|
43
|
+
{
|
|
44
|
+
target.readonlySelectors.delete(key)
|
|
45
|
+
const family = withdraw(
|
|
46
|
+
{ key: selector.family.key, type: `readonly_selector_family` },
|
|
47
|
+
store,
|
|
48
|
+
)
|
|
49
|
+
family.subject.next({
|
|
50
|
+
type: `state_disposal`,
|
|
51
|
+
token: selectorToken,
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
target.valueMap.delete(key)
|
|
57
|
+
target.selectorAtoms.delete(key)
|
|
58
|
+
const downstreamTokens = target.selectorGraph
|
|
59
|
+
.getRelationEntries({ upstreamSelectorKey: key })
|
|
60
|
+
.filter(([_, { source }]) => source === key)
|
|
61
|
+
.map(
|
|
62
|
+
([downstreamSelectorKey]) =>
|
|
63
|
+
target.selectors.get(downstreamSelectorKey) ??
|
|
64
|
+
target.readonlySelectors.get(downstreamSelectorKey),
|
|
65
|
+
)
|
|
66
|
+
for (const downstreamToken of downstreamTokens) {
|
|
67
|
+
if (downstreamToken) {
|
|
68
|
+
disposeSelector(downstreamToken, store)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
target.selectorGraph.delete(key)
|
|
72
|
+
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
73
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
74
|
+
target.transactionMeta.update.updates.push({
|
|
75
|
+
type: `state_disposal`,
|
|
76
|
+
token: selectorToken,
|
|
77
|
+
})
|
|
78
|
+
} else {
|
|
79
|
+
store.on.selectorDisposal.next(selectorToken)
|
|
33
80
|
}
|
|
34
81
|
}
|
|
35
|
-
target.selectorGraph.delete(key)
|
|
36
|
-
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
37
|
-
store.on.selectorDisposal.next(selectorToken)
|
|
38
82
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Transactors } from "atom.io"
|
|
2
|
+
import type { findState } from "atom.io/ephemeral"
|
|
3
|
+
import type { seekState } from "atom.io/immortal"
|
|
2
4
|
|
|
3
|
-
import { findInStore } from "../families"
|
|
5
|
+
import { findInStore, seekInStore } from "../families"
|
|
4
6
|
import { readOrComputeValue } from "../get-state/read-or-compute-value"
|
|
5
7
|
import { newest } from "../lineage"
|
|
8
|
+
import { getJsonToken } from "../mutable"
|
|
6
9
|
import { setAtomOrSelector } from "../set-state"
|
|
7
10
|
import type { Store } from "../store"
|
|
8
|
-
import {
|
|
11
|
+
import { withdraw } from "../store"
|
|
9
12
|
import { updateSelectorAtoms } from "./update-selector-atoms"
|
|
10
13
|
|
|
11
14
|
export const registerSelector = (
|
|
@@ -15,7 +18,7 @@ export const registerSelector = (
|
|
|
15
18
|
get: (dependency) => {
|
|
16
19
|
const target = newest(store)
|
|
17
20
|
|
|
18
|
-
const dependencyState =
|
|
21
|
+
const dependencyState = withdraw(dependency, store)
|
|
19
22
|
const dependencyValue = readOrComputeValue(dependencyState, store)
|
|
20
23
|
|
|
21
24
|
store.logger.info(
|
|
@@ -40,8 +43,10 @@ export const registerSelector = (
|
|
|
40
43
|
return dependencyValue
|
|
41
44
|
},
|
|
42
45
|
set: (WritableToken, newValue) => {
|
|
43
|
-
const state =
|
|
46
|
+
const state = withdraw(WritableToken, store)
|
|
44
47
|
setAtomOrSelector(state, newValue, store)
|
|
45
48
|
},
|
|
46
49
|
find: ((token, key) => findInStore(token, key, store)) as typeof findState,
|
|
50
|
+
seek: ((token, key) => seekInStore(token, key, store)) as typeof seekState,
|
|
51
|
+
json: (token) => getJsonToken(token, store),
|
|
47
52
|
})
|
|
@@ -2,7 +2,7 @@ import type { WritableToken } from "atom.io"
|
|
|
2
2
|
|
|
3
3
|
import { closeOperation, openOperation } from "../operation"
|
|
4
4
|
import type { Store } from "../store"
|
|
5
|
-
import {
|
|
5
|
+
import { withdraw } from "../store"
|
|
6
6
|
import { setAtomOrSelector } from "./set-atom-or-selector"
|
|
7
7
|
|
|
8
8
|
export function setIntoStore<T, New extends T>(
|
|
@@ -27,7 +27,7 @@ export function setIntoStore<T, New extends T>(
|
|
|
27
27
|
)
|
|
28
28
|
return
|
|
29
29
|
}
|
|
30
|
-
const state =
|
|
30
|
+
const state = withdraw(token, store)
|
|
31
31
|
setAtomOrSelector(state, value, store)
|
|
32
32
|
closeOperation(store)
|
|
33
33
|
}
|
|
@@ -38,7 +38,11 @@ export const stowUpdate = <T>(
|
|
|
38
38
|
if (!shouldStow) {
|
|
39
39
|
return
|
|
40
40
|
}
|
|
41
|
-
const atomUpdate: KeyedStateUpdate<T> = {
|
|
41
|
+
const atomUpdate: KeyedStateUpdate<T> = {
|
|
42
|
+
type: `atom_update`,
|
|
43
|
+
key,
|
|
44
|
+
...update,
|
|
45
|
+
}
|
|
42
46
|
if (state.family) {
|
|
43
47
|
atomUpdate.family = state.family
|
|
44
48
|
}
|