atom.io 0.22.0 → 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 +17 -1
- package/data/dist/index.js +1 -1
- package/data/src/join.ts +30 -1
- package/dist/chunk-6MLFYN32.js +18 -0
- package/dist/{chunk-JA4V7TJY.js → chunk-7DT3PVS3.js} +18 -2
- package/dist/chunk-OAYGID5B.js +27 -0
- package/dist/index.cjs +2 -11
- package/dist/index.d.ts +51 -23
- package/dist/index.js +2 -11
- package/eslint-plugin/dist/index.cjs +0 -1
- package/eslint-plugin/dist/index.js +0 -1
- package/eslint-plugin/src/rules/lifespan.ts +0 -1
- package/immortal/dist/index.cjs +180 -20
- package/immortal/dist/index.js +134 -19
- package/immortal/src/index.ts +1 -0
- package/immortal/src/make-molecule.ts +222 -0
- package/immortal/src/molecule.ts +49 -16
- package/immortal/src/seek-state.ts +15 -2
- package/internal/dist/index.cjs +1119 -754
- package/internal/dist/index.d.ts +109 -12
- package/internal/dist/index.js +1098 -760
- 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 +22 -2
- package/internal/src/families/create-readonly-selector-family.ts +7 -2
- package/internal/src/families/create-regular-atom-family.ts +6 -2
- package/internal/src/families/create-writable-selector-family.ts +7 -2
- package/internal/src/families/dispose-from-store.ts +22 -0
- package/internal/src/families/find-in-store.ts +0 -1
- package/internal/src/families/index.ts +1 -0
- package/internal/src/families/init-family-member.ts +22 -1
- package/internal/src/families/seek-in-store.ts +23 -6
- 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 +6 -2
- package/internal/src/mutable/create-mutable-atom.ts +0 -2
- package/internal/src/mutable/get-json-token.ts +0 -1
- package/internal/src/mutable/tracker-family.ts +7 -7
- package/internal/src/not-found-error.ts +5 -0
- 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 +32 -5
- package/internal/src/selector/register-selector.ts +2 -0
- package/internal/src/set-state/stow-update.ts +5 -1
- package/internal/src/store/deposit.ts +41 -7
- package/internal/src/store/store.ts +11 -0
- package/internal/src/store/withdraw.ts +28 -1
- 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 +11 -2
- package/introspection/dist/index.cjs +2 -1
- package/introspection/dist/index.js +2 -1
- package/introspection/src/attach-timeline-family.ts +1 -0
- package/json/dist/index.cjs +3 -3
- package/json/dist/index.js +6 -5
- package/json/src/select-json-family.ts +3 -4
- package/package.json +5 -5
- package/react-devtools/dist/index.cjs +58 -47
- package/react-devtools/dist/index.js +60 -48
- package/react-devtools/src/TimelineIndex.tsx +15 -13
- package/react-devtools/src/Updates.tsx +41 -32
- package/realtime-server/dist/index.cjs +21 -10
- package/realtime-server/dist/index.d.ts +1 -1
- package/realtime-server/dist/index.js +21 -11
- package/realtime-server/src/realtime-server-stores/server-sync-store.ts +21 -11
- package/realtime-testing/dist/index.cjs +1 -0
- package/realtime-testing/dist/index.js +1 -1
- package/src/atom.ts +9 -3
- package/src/dispose-state.ts +3 -12
- package/src/index.ts +4 -0
- package/src/selector.ts +3 -3
- package/src/subscribe.ts +8 -4
- package/src/timeline.ts +18 -1
- package/src/transaction.ts +56 -4
- package/dist/chunk-BF4MVQF6.js +0 -44
|
@@ -27,7 +27,11 @@ export function createStandaloneAtom<T>(
|
|
|
27
27
|
const isMutable = `mutable` in options
|
|
28
28
|
|
|
29
29
|
if (isMutable) {
|
|
30
|
-
|
|
30
|
+
const state = createMutableAtom(options, undefined, store)
|
|
31
|
+
store.on.atomCreation.next(state)
|
|
32
|
+
return state
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
const state = createRegularAtom(options, undefined, store)
|
|
35
|
+
store.on.atomCreation.next(state)
|
|
36
|
+
return state
|
|
33
37
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { AtomToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
disposeSelector,
|
|
6
|
+
getUpdateToken,
|
|
7
|
+
isChildStore,
|
|
8
|
+
newest,
|
|
9
|
+
withdraw,
|
|
10
|
+
} from ".."
|
|
5
11
|
|
|
6
12
|
export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
7
13
|
const target = newest(store)
|
|
@@ -18,6 +24,13 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
|
18
24
|
store.logger.error(`❌`, `atom`, key, `Standalone atoms cannot be disposed.`)
|
|
19
25
|
} else {
|
|
20
26
|
atom.cleanup?.()
|
|
27
|
+
const lastValue = store.valueMap.get(atom.key)
|
|
28
|
+
const family = withdraw({ key: atom.family.key, type: `atom_family` }, store)
|
|
29
|
+
family.subject.next({
|
|
30
|
+
type: `state_disposal`,
|
|
31
|
+
token: atomToken,
|
|
32
|
+
value: lastValue,
|
|
33
|
+
})
|
|
21
34
|
target.atoms.delete(key)
|
|
22
35
|
target.valueMap.delete(key)
|
|
23
36
|
const selectorKeys = target.selectorAtoms.getRelatedKeys(key)
|
|
@@ -40,6 +53,13 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
|
40
53
|
store.trackers.delete(key)
|
|
41
54
|
}
|
|
42
55
|
store.logger.info(`🔥`, `atom`, key, `deleted`)
|
|
43
|
-
|
|
56
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
57
|
+
target.transactionMeta.update.updates.push({
|
|
58
|
+
type: `state_disposal`,
|
|
59
|
+
token: atomToken,
|
|
60
|
+
})
|
|
61
|
+
} else {
|
|
62
|
+
store.on.atomDisposal.next(atomToken)
|
|
63
|
+
}
|
|
44
64
|
}
|
|
45
65
|
}
|
|
@@ -3,6 +3,8 @@ import type {
|
|
|
3
3
|
ReadonlySelectorFamily,
|
|
4
4
|
ReadonlySelectorFamilyOptions,
|
|
5
5
|
ReadonlySelectorToken,
|
|
6
|
+
StateCreation,
|
|
7
|
+
StateDisposal,
|
|
6
8
|
} from "atom.io"
|
|
7
9
|
import type { Json } from "atom.io/json"
|
|
8
10
|
import { stringifyJson } from "atom.io/json"
|
|
@@ -16,7 +18,10 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
|
16
18
|
options: ReadonlySelectorFamilyOptions<T, K>,
|
|
17
19
|
store: Store,
|
|
18
20
|
): ReadonlySelectorFamily<T, K> {
|
|
19
|
-
const subject = new Subject<
|
|
21
|
+
const subject = new Subject<
|
|
22
|
+
| StateCreation<ReadonlySelectorToken<T>>
|
|
23
|
+
| StateDisposal<ReadonlySelectorToken<T>>
|
|
24
|
+
>()
|
|
20
25
|
|
|
21
26
|
const readonlySelectorFamily = Object.assign(
|
|
22
27
|
(key: K): ReadonlySelectorToken<T> => {
|
|
@@ -34,7 +39,7 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
|
34
39
|
target,
|
|
35
40
|
)
|
|
36
41
|
|
|
37
|
-
subject.next(token)
|
|
42
|
+
subject.next({ type: `state_creation`, token })
|
|
38
43
|
return token
|
|
39
44
|
},
|
|
40
45
|
{
|
|
@@ -4,6 +4,8 @@ import type {
|
|
|
4
4
|
RegularAtomFamilyOptions,
|
|
5
5
|
RegularAtomOptions,
|
|
6
6
|
RegularAtomToken,
|
|
7
|
+
StateCreation,
|
|
8
|
+
StateDisposal,
|
|
7
9
|
} from "atom.io"
|
|
8
10
|
import type { Json } from "atom.io/json"
|
|
9
11
|
import { stringifyJson } from "atom.io/json"
|
|
@@ -17,7 +19,9 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
17
19
|
options: RegularAtomFamilyOptions<T, K>,
|
|
18
20
|
store: Store,
|
|
19
21
|
): RegularAtomFamily<T, K> {
|
|
20
|
-
const subject = new Subject<
|
|
22
|
+
const subject = new Subject<
|
|
23
|
+
StateCreation<RegularAtomToken<T>> | StateDisposal<RegularAtomToken<T>>
|
|
24
|
+
>()
|
|
21
25
|
|
|
22
26
|
const atomFamily: RegularAtomFamily<T, K> = Object.assign(
|
|
23
27
|
(key: K): RegularAtomToken<any> => {
|
|
@@ -37,7 +41,7 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
37
41
|
|
|
38
42
|
const token = createRegularAtom(individualOptions, family, target)
|
|
39
43
|
|
|
40
|
-
subject.next(token)
|
|
44
|
+
subject.next({ type: `state_creation`, token })
|
|
41
45
|
return token
|
|
42
46
|
},
|
|
43
47
|
{
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
FamilyMetadata,
|
|
3
|
+
StateCreation,
|
|
4
|
+
StateDisposal,
|
|
3
5
|
WritableSelectorFamily,
|
|
4
6
|
WritableSelectorFamilyOptions,
|
|
5
7
|
WritableSelectorToken,
|
|
@@ -16,7 +18,10 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
|
16
18
|
options: WritableSelectorFamilyOptions<T, K>,
|
|
17
19
|
store: Store,
|
|
18
20
|
): WritableSelectorFamily<T, K> {
|
|
19
|
-
const subject = new Subject<
|
|
21
|
+
const subject = new Subject<
|
|
22
|
+
| StateCreation<WritableSelectorToken<T>>
|
|
23
|
+
| StateDisposal<WritableSelectorToken<T>>
|
|
24
|
+
>()
|
|
20
25
|
|
|
21
26
|
const selectorFamily = Object.assign(
|
|
22
27
|
(key: K): WritableSelectorToken<T> => {
|
|
@@ -35,7 +40,7 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
|
35
40
|
target,
|
|
36
41
|
)
|
|
37
42
|
|
|
38
|
-
subject.next(token)
|
|
43
|
+
subject.next({ type: `state_creation`, token })
|
|
39
44
|
return token
|
|
40
45
|
},
|
|
41
46
|
{
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReadableToken } from "atom.io"
|
|
2
|
+
import { disposeMolecule, type MoleculeToken } from "atom.io/immortal"
|
|
3
|
+
import * as Internal from "atom.io/internal"
|
|
4
|
+
|
|
5
|
+
export function disposeFromStore(
|
|
6
|
+
token: MoleculeToken<any, any, any> | ReadableToken<any>,
|
|
7
|
+
store: Internal.Store = Internal.IMPLICIT.STORE,
|
|
8
|
+
): void {
|
|
9
|
+
switch (token.type) {
|
|
10
|
+
case `atom`:
|
|
11
|
+
case `mutable_atom`:
|
|
12
|
+
Internal.disposeAtom(token, store)
|
|
13
|
+
break
|
|
14
|
+
case `selector`:
|
|
15
|
+
case `readonly_selector`:
|
|
16
|
+
Internal.disposeSelector(token, store)
|
|
17
|
+
break
|
|
18
|
+
case `molecule`:
|
|
19
|
+
disposeMolecule(token, store)
|
|
20
|
+
break
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -19,7 +19,6 @@ import type {
|
|
|
19
19
|
import type { Json } from "atom.io/json"
|
|
20
20
|
|
|
21
21
|
import type { Transceiver } from "../mutable"
|
|
22
|
-
import { NotFoundError } from "../not-found-error"
|
|
23
22
|
import type { Store } from "../store"
|
|
24
23
|
import { initFamilyMember } from "./init-family-member"
|
|
25
24
|
import { seekInStore } from "./seek-in-store"
|
|
@@ -2,6 +2,7 @@ export * from "./create-atom-family"
|
|
|
2
2
|
export * from "./create-readonly-selector-family"
|
|
3
3
|
export * from "./create-regular-atom-family"
|
|
4
4
|
export * from "./create-selector-family"
|
|
5
|
+
export * from "./dispose-from-store"
|
|
5
6
|
export * from "./find-in-store"
|
|
6
7
|
export * from "./init-family-member"
|
|
7
8
|
export * from "./seek-in-store"
|
|
@@ -18,10 +18,11 @@ import type {
|
|
|
18
18
|
} from "atom.io"
|
|
19
19
|
import type { Json } from "atom.io/json"
|
|
20
20
|
|
|
21
|
+
import { newest } from "../lineage"
|
|
21
22
|
import type { Transceiver } from "../mutable"
|
|
22
23
|
import { NotFoundError } from "../not-found-error"
|
|
23
24
|
import type { Store } from "../store"
|
|
24
|
-
import {
|
|
25
|
+
import { isChildStore } from "../transaction"
|
|
25
26
|
|
|
26
27
|
export function initFamilyMember<
|
|
27
28
|
T extends Transceiver<any>,
|
|
@@ -87,5 +88,25 @@ export function initFamilyMember(
|
|
|
87
88
|
throw new NotFoundError(token, store)
|
|
88
89
|
}
|
|
89
90
|
const state = family(key)
|
|
91
|
+
const target = newest(store)
|
|
92
|
+
if (state.family) {
|
|
93
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
94
|
+
target.transactionMeta.update.updates.push({
|
|
95
|
+
type: `state_creation`,
|
|
96
|
+
token: state,
|
|
97
|
+
})
|
|
98
|
+
} else {
|
|
99
|
+
switch (state.type) {
|
|
100
|
+
case `atom`:
|
|
101
|
+
case `mutable_atom`:
|
|
102
|
+
store.on.atomCreation.next(state)
|
|
103
|
+
break
|
|
104
|
+
case `selector`:
|
|
105
|
+
case `readonly_selector`:
|
|
106
|
+
store.on.selectorCreation.next(state)
|
|
107
|
+
break
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
90
111
|
return state
|
|
91
112
|
}
|
|
@@ -16,6 +16,11 @@ import type {
|
|
|
16
16
|
WritableSelectorToken,
|
|
17
17
|
WritableToken,
|
|
18
18
|
} from "atom.io"
|
|
19
|
+
import type {
|
|
20
|
+
Molecule,
|
|
21
|
+
MoleculeFamilyToken,
|
|
22
|
+
MoleculeToken,
|
|
23
|
+
} from "atom.io/immortal"
|
|
19
24
|
import { type Json, stringifyJson } from "atom.io/json"
|
|
20
25
|
|
|
21
26
|
import type { ReadableState } from ".."
|
|
@@ -76,28 +81,40 @@ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
|
|
|
76
81
|
store: Store,
|
|
77
82
|
): ReadableToken<T> | undefined
|
|
78
83
|
|
|
84
|
+
export function seekInStore<
|
|
85
|
+
K extends Json.Serializable,
|
|
86
|
+
S extends { [key: string]: any },
|
|
87
|
+
>(
|
|
88
|
+
token: MoleculeFamilyToken<K, S, any[]>,
|
|
89
|
+
key: K,
|
|
90
|
+
store: Store,
|
|
91
|
+
): MoleculeToken<K, S, any[]> | undefined
|
|
92
|
+
|
|
79
93
|
export function seekInStore(
|
|
80
|
-
token: ReadableFamilyToken<any, any>,
|
|
94
|
+
token: MoleculeFamilyToken<any, any, any> | ReadableFamilyToken<any, any>,
|
|
81
95
|
key: Json.Serializable,
|
|
82
96
|
store: Store,
|
|
83
|
-
): ReadableToken<any> | undefined {
|
|
97
|
+
): MoleculeToken<any, any, any> | ReadableToken<any> | undefined {
|
|
84
98
|
const subKey = stringifyJson(key)
|
|
85
99
|
const fullKey = `${token.key}(${subKey})`
|
|
86
100
|
const target = newest(store)
|
|
87
|
-
let state: ReadableState<any> | undefined
|
|
101
|
+
let state: Molecule<any> | ReadableState<any> | undefined
|
|
88
102
|
switch (token.type) {
|
|
89
103
|
case `atom_family`:
|
|
90
104
|
case `mutable_atom_family`:
|
|
91
105
|
state = target.atoms.get(fullKey)
|
|
92
106
|
break
|
|
93
|
-
|
|
94
|
-
case `selector_family`: {
|
|
107
|
+
case `selector_family`:
|
|
95
108
|
state = target.selectors.get(fullKey)
|
|
96
109
|
break
|
|
97
|
-
}
|
|
98
110
|
case `readonly_selector_family`:
|
|
99
111
|
state = target.readonlySelectors.get(fullKey)
|
|
100
112
|
break
|
|
113
|
+
case `molecule_family`:
|
|
114
|
+
state = target.molecules.get(stringifyJson(key))
|
|
115
|
+
if (state) {
|
|
116
|
+
return deposit(state)
|
|
117
|
+
}
|
|
101
118
|
}
|
|
102
119
|
if (state) {
|
|
103
120
|
return deposit(state)
|
|
@@ -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,7 +25,9 @@ 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<
|
|
28
|
+
const subject = new Subject<
|
|
29
|
+
StateCreation<MutableAtomToken<T, J>> | StateDisposal<MutableAtomToken<T, J>>
|
|
30
|
+
>()
|
|
27
31
|
|
|
28
32
|
const atomFamily = Object.assign(
|
|
29
33
|
(key: K): MutableAtomToken<T, J> => {
|
|
@@ -45,7 +49,7 @@ export function createMutableAtomFamily<
|
|
|
45
49
|
|
|
46
50
|
const token = createMutableAtom(individualOptions, family, target)
|
|
47
51
|
|
|
48
|
-
subject.next(token)
|
|
52
|
+
subject.next({ type: `state_creation`, token })
|
|
49
53
|
return token
|
|
50
54
|
},
|
|
51
55
|
{
|
|
@@ -38,19 +38,19 @@ export class FamilyTracker<
|
|
|
38
38
|
this.mutableAtoms = mutableAtoms
|
|
39
39
|
this.mutableAtoms.subject.subscribe(
|
|
40
40
|
`store=${store.config.name}::tracker-atom-family`,
|
|
41
|
-
(
|
|
42
|
-
if (
|
|
43
|
-
const key = parseJson(
|
|
41
|
+
(event) => {
|
|
42
|
+
if (event.token.family) {
|
|
43
|
+
const key = parseJson(event.token.family.subKey) as FamilyMemberKey
|
|
44
44
|
seekInStore(this.latestUpdateAtoms, key, store)
|
|
45
|
-
new Tracker<Core>(
|
|
45
|
+
new Tracker<Core>(event.token, store)
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
)
|
|
49
49
|
this.latestUpdateAtoms.subject.subscribe(
|
|
50
50
|
`store=${store.config.name}::tracker-atom-family`,
|
|
51
|
-
(
|
|
52
|
-
if (
|
|
53
|
-
const key = parseJson(
|
|
51
|
+
(event) => {
|
|
52
|
+
if (event.token.family) {
|
|
53
|
+
const key = parseJson(event.token.family.subKey) as FamilyMemberKey
|
|
54
54
|
const mutableAtomToken = seekInStore(this.mutableAtoms, key, store)
|
|
55
55
|
if (mutableAtomToken) {
|
|
56
56
|
new Tracker<Core>(mutableAtomToken, store)
|
|
@@ -4,12 +4,15 @@ 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>
|
|
@@ -19,6 +22,8 @@ function prettyPrintTokenType(token: AtomIOToken) {
|
|
|
19
22
|
switch (token.type) {
|
|
20
23
|
case `atom_family`:
|
|
21
24
|
return `Atom Family`
|
|
25
|
+
case `molecule_family`:
|
|
26
|
+
return `Molecule Family`
|
|
22
27
|
case `readonly_selector`:
|
|
23
28
|
return `Readonly Selector`
|
|
24
29
|
case `readonly_selector_family`:
|
|
@@ -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, seek } = 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, seek })
|
|
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, seek } = transactors
|
|
26
|
-
const readonlyTransactors = { find, get, seek }
|
|
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>,
|
|
@@ -11,7 +11,7 @@ export function disposeSelector(
|
|
|
11
11
|
const { key } = selectorToken
|
|
12
12
|
const selector = target.selectors.get(key) ?? target.readonlySelectors.get(key)
|
|
13
13
|
if (!selector) {
|
|
14
|
-
store.logger.
|
|
14
|
+
store.logger.info(
|
|
15
15
|
`❌`,
|
|
16
16
|
`selector`,
|
|
17
17
|
key,
|
|
@@ -27,10 +27,30 @@ export function disposeSelector(
|
|
|
27
27
|
} else {
|
|
28
28
|
switch (selectorToken.type) {
|
|
29
29
|
case `selector`:
|
|
30
|
-
|
|
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
|
+
}
|
|
31
41
|
break
|
|
32
42
|
case `readonly_selector`:
|
|
33
|
-
|
|
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
|
+
}
|
|
34
54
|
break
|
|
35
55
|
}
|
|
36
56
|
target.valueMap.delete(key)
|
|
@@ -50,6 +70,13 @@ export function disposeSelector(
|
|
|
50
70
|
}
|
|
51
71
|
target.selectorGraph.delete(key)
|
|
52
72
|
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
53
|
-
|
|
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)
|
|
80
|
+
}
|
|
54
81
|
}
|
|
55
82
|
}
|