atom.io 0.37.1 → 0.38.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/internal/index.d.ts +23 -25
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +193 -138
- package/dist/internal/index.js.map +1 -1
- package/dist/json/index.d.ts +3 -1
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js +3 -2
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +6 -3
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +22 -2
- package/dist/main/index.js.map +1 -1
- package/package.json +1 -1
- package/src/internal/atom/dispose-atom.ts +1 -2
- package/src/internal/families/create-readonly-held-selector-family.ts +2 -4
- package/src/internal/families/create-readonly-pure-selector-family.ts +2 -4
- package/src/internal/families/create-regular-atom-family.ts +3 -4
- package/src/internal/families/create-writable-held-selector-family.ts +3 -4
- package/src/internal/families/create-writable-pure-selector-family.ts +2 -4
- package/src/internal/families/find-in-store.ts +7 -1
- package/src/internal/families/get-family-of-token.ts +21 -24
- package/src/internal/families/mint-in-store.ts +59 -35
- package/src/internal/get-state/get-fallback.ts +57 -0
- package/src/internal/get-state/get-from-store.ts +11 -61
- package/src/internal/get-state/reduce-reference.ts +66 -0
- package/src/internal/index.ts +0 -1
- package/src/internal/ingest-updates/ingest-creation-disposal.ts +4 -3
- package/src/internal/molecule.ts +5 -5
- package/src/internal/mutable/create-mutable-atom-family.ts +3 -8
- package/src/internal/mutable/get-json-token.ts +2 -1
- package/src/internal/not-found-error.ts +2 -3
- package/src/internal/operation.ts +1 -1
- package/src/internal/selector/register-selector.ts +17 -24
- package/src/internal/selector/update-selector-atoms.ts +2 -2
- package/src/internal/set-state/operate-on-store.ts +17 -13
- package/src/internal/set-state/set-into-store.ts +2 -2
- package/src/internal/store/index.ts +1 -1
- package/src/internal/store/{counterfeit.ts → mint-or-counterfeit.ts} +27 -15
- package/src/internal/store/store.ts +1 -1
- package/src/internal/subscribe/subscribe-to-state.ts +2 -0
- package/src/internal/timeline/create-timeline.ts +2 -0
- package/src/json/index.ts +6 -3
- package/src/main/logger.ts +26 -4
- package/src/internal/pretty-print.ts +0 -7
|
@@ -9,66 +9,90 @@ import { stringifyJson } from "atom.io/json"
|
|
|
9
9
|
|
|
10
10
|
import { newest } from "../lineage"
|
|
11
11
|
import type { Store } from "../store"
|
|
12
|
-
import {
|
|
12
|
+
import { COUNTERFEIT, mint } from "../store"
|
|
13
13
|
import { isChildStore, isRootStore } from "../transaction"
|
|
14
14
|
import { initFamilyMemberInStore } from "./init-family-member"
|
|
15
15
|
|
|
16
|
+
export const MUST_CREATE: unique symbol = Symbol(`MUST_NOT_EXIST`)
|
|
17
|
+
|
|
16
18
|
export function mintInStore<T, K extends Canonical, Key extends K>(
|
|
17
19
|
store: Store,
|
|
18
20
|
familyToken: WritableFamilyToken<T, K>,
|
|
19
21
|
key: Key,
|
|
22
|
+
init?: typeof MUST_CREATE,
|
|
20
23
|
): WritableToken<T, K>
|
|
21
24
|
export function mintInStore<T, K extends Canonical, Key extends K>(
|
|
22
25
|
store: Store,
|
|
23
26
|
familyToken: ReadableFamilyToken<T, K>,
|
|
24
27
|
key: Key,
|
|
28
|
+
init?: typeof MUST_CREATE,
|
|
25
29
|
): ReadableToken<T, K>
|
|
26
30
|
export function mintInStore<T, K extends Canonical, Key extends K>(
|
|
27
31
|
store: Store,
|
|
28
32
|
familyToken: ReadableFamilyToken<T, K>,
|
|
29
33
|
key: Key,
|
|
34
|
+
shouldCreate?: typeof MUST_CREATE,
|
|
30
35
|
): ReadableToken<T, K> {
|
|
36
|
+
let stateToken: ReadableToken<T, K>
|
|
37
|
+
|
|
38
|
+
let willCreate: boolean
|
|
39
|
+
switch (shouldCreate) {
|
|
40
|
+
case MUST_CREATE:
|
|
41
|
+
willCreate = true
|
|
42
|
+
break
|
|
43
|
+
case undefined:
|
|
44
|
+
willCreate = false
|
|
45
|
+
break
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
const stringKey = stringifyJson(key)
|
|
32
49
|
const molecule = store.molecules.get(stringKey)
|
|
33
50
|
if (!molecule && store.config.lifespan === `immortal`) {
|
|
34
|
-
const fakeToken =
|
|
35
|
-
store.logger.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`was
|
|
51
|
+
const fakeToken = mint(familyToken, key, COUNTERFEIT)
|
|
52
|
+
store.logger.warn(
|
|
53
|
+
`💣`,
|
|
54
|
+
`key`,
|
|
55
|
+
stringKey,
|
|
56
|
+
`was used to mint a counterfeit token for`,
|
|
57
|
+
familyToken.type,
|
|
58
|
+
`"${familyToken.key}"`,
|
|
40
59
|
)
|
|
41
60
|
return fakeToken
|
|
42
61
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
|
|
63
|
+
if (willCreate) {
|
|
64
|
+
stateToken = initFamilyMemberInStore(store, familyToken, key)
|
|
65
|
+
const target = newest(store)
|
|
66
|
+
if (stateToken.family) {
|
|
67
|
+
if (isRootStore(target)) {
|
|
68
|
+
switch (stateToken.type) {
|
|
69
|
+
case `atom`:
|
|
70
|
+
case `mutable_atom`:
|
|
71
|
+
store.on.atomCreation.next(stateToken)
|
|
72
|
+
break
|
|
73
|
+
case `writable_pure_selector`:
|
|
74
|
+
case `readonly_pure_selector`:
|
|
75
|
+
case `writable_held_selector`:
|
|
76
|
+
case `readonly_held_selector`:
|
|
77
|
+
store.on.selectorCreation.next(stateToken)
|
|
78
|
+
break
|
|
79
|
+
}
|
|
80
|
+
} else if (
|
|
81
|
+
isChildStore(target) &&
|
|
82
|
+
target.on.transactionApplying.state === null
|
|
83
|
+
) {
|
|
84
|
+
target.transactionMeta.update.subEvents.push({
|
|
85
|
+
type: `state_creation`,
|
|
86
|
+
token: stateToken,
|
|
87
|
+
timestamp: Date.now(),
|
|
88
|
+
})
|
|
58
89
|
}
|
|
59
|
-
} else if (
|
|
60
|
-
isChildStore(target) &&
|
|
61
|
-
target.on.transactionApplying.state === null
|
|
62
|
-
) {
|
|
63
|
-
target.transactionMeta.update.subEvents.push({
|
|
64
|
-
type: `state_creation`,
|
|
65
|
-
token: newStateToken,
|
|
66
|
-
timestamp: Date.now(),
|
|
67
|
-
})
|
|
68
90
|
}
|
|
91
|
+
if (molecule) {
|
|
92
|
+
target.moleculeData.set(stringKey, familyToken.key)
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
stateToken = mint(familyToken, key)
|
|
69
96
|
}
|
|
70
|
-
|
|
71
|
-
target.moleculeData.set(stringKey, familyToken.key)
|
|
72
|
-
}
|
|
73
|
-
return newStateToken
|
|
97
|
+
return stateToken
|
|
74
98
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ReadableToken } from "atom.io"
|
|
2
|
+
import { type Canonical, stringifyJson } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
import type { ReadableFamily } from ".."
|
|
5
|
+
import type { Store } from "../store"
|
|
6
|
+
|
|
7
|
+
export function getFallback<T, K extends Canonical>(
|
|
8
|
+
store: Store,
|
|
9
|
+
token: ReadableToken<T, K>,
|
|
10
|
+
family: ReadableFamily<T, K>,
|
|
11
|
+
subKey: K,
|
|
12
|
+
): T {
|
|
13
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
14
|
+
(item) => item?.key === stringifyJson(subKey),
|
|
15
|
+
)
|
|
16
|
+
store.logger.error(
|
|
17
|
+
`❌`,
|
|
18
|
+
token.type,
|
|
19
|
+
token.key,
|
|
20
|
+
`gets a fallback value because key`,
|
|
21
|
+
subKey,
|
|
22
|
+
`is not allocated`,
|
|
23
|
+
disposal
|
|
24
|
+
? `This key was previously disposed:\n${disposal.trace}`
|
|
25
|
+
: `(no previous disposal trace found)`,
|
|
26
|
+
)
|
|
27
|
+
switch (family.type) {
|
|
28
|
+
case `mutable_atom_family`: {
|
|
29
|
+
if (store.defaults.has(family.key)) {
|
|
30
|
+
return store.defaults.get(family.key)
|
|
31
|
+
}
|
|
32
|
+
const defaultValue = new family.class()
|
|
33
|
+
store.defaults.set(family.key, defaultValue)
|
|
34
|
+
return defaultValue
|
|
35
|
+
}
|
|
36
|
+
case `atom_family`: {
|
|
37
|
+
if (store.defaults.has(family.key)) {
|
|
38
|
+
return store.defaults.get(family.key)
|
|
39
|
+
}
|
|
40
|
+
const def = family.default as (key: K) => T
|
|
41
|
+
const defaultValue = def(subKey)
|
|
42
|
+
store.defaults.set(family.key, defaultValue)
|
|
43
|
+
return defaultValue
|
|
44
|
+
}
|
|
45
|
+
case `readonly_pure_selector_family`:
|
|
46
|
+
case `writable_pure_selector_family`:
|
|
47
|
+
case `readonly_held_selector_family`:
|
|
48
|
+
case `writable_held_selector_family`: {
|
|
49
|
+
if (store.defaults.has(family.key)) {
|
|
50
|
+
return store.defaults.get(family.key)
|
|
51
|
+
}
|
|
52
|
+
const defaultValue = family.default(subKey)
|
|
53
|
+
store.defaults.set(family.key, defaultValue)
|
|
54
|
+
return defaultValue
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ReadableFamilyToken, ReadableToken } from "atom.io"
|
|
2
|
-
import {
|
|
2
|
+
import type { Canonical } from "atom.io/json"
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import { withdraw } from "../store"
|
|
4
|
+
import { type Store, withdraw } from "../store"
|
|
5
|
+
import { getFallback } from "./get-fallback"
|
|
7
6
|
import { readOrComputeValue } from "./read-or-compute-value"
|
|
7
|
+
import { reduceReference } from "./reduce-reference"
|
|
8
8
|
|
|
9
9
|
export function getFromStore<T>(store: Store, token: ReadableToken<T>): T
|
|
10
10
|
|
|
@@ -20,63 +20,13 @@ export function getFromStore(
|
|
|
20
20
|
| [token: ReadableFamilyToken<any, any>, key: Canonical]
|
|
21
21
|
| [token: ReadableToken<any>]
|
|
22
22
|
): any {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
token
|
|
28
|
-
} else {
|
|
29
|
-
family = params[0]
|
|
30
|
-
key = params[1]
|
|
31
|
-
token = findInStore(store, family, key)
|
|
32
|
-
}
|
|
33
|
-
if (`counterfeit` in token && `family` in token) {
|
|
34
|
-
// biome-ignore lint/style/noNonNullAssertion: family must be present
|
|
35
|
-
family = store.families.get(token.family.key)!
|
|
36
|
-
const subKey = token.family.subKey
|
|
37
|
-
const disposal = store.disposalTraces.buffer.find(
|
|
38
|
-
(item) => item?.key === subKey,
|
|
39
|
-
)
|
|
40
|
-
store.logger.error(
|
|
41
|
-
`❌`,
|
|
42
|
-
token.type,
|
|
43
|
-
token.key,
|
|
44
|
-
`could not be retrieved because it was not found in the store "${store.config.name}".`,
|
|
45
|
-
disposal
|
|
46
|
-
? `This state was previously disposed:\n${disposal.trace}`
|
|
47
|
-
: `No previous disposal trace was found.`,
|
|
48
|
-
)
|
|
49
|
-
switch (family.type) {
|
|
50
|
-
case `mutable_atom_family`: {
|
|
51
|
-
if (store.defaults.has(family.key)) {
|
|
52
|
-
return store.defaults.get(family.key)
|
|
53
|
-
}
|
|
54
|
-
const mutableFamily = withdraw(store, family)
|
|
55
|
-
const defaultValue = new mutableFamily.class()
|
|
56
|
-
store.defaults.set(family.key, defaultValue)
|
|
57
|
-
return defaultValue
|
|
58
|
-
}
|
|
59
|
-
case `atom_family`: {
|
|
60
|
-
if (store.defaults.has(family.key)) {
|
|
61
|
-
return store.defaults.get(token.family.key)
|
|
62
|
-
}
|
|
63
|
-
const defaultValue = withdraw(store, family).default(parseJson(subKey))
|
|
64
|
-
store.defaults.set(family.key, defaultValue)
|
|
65
|
-
return defaultValue
|
|
66
|
-
}
|
|
67
|
-
case `readonly_pure_selector_family`:
|
|
68
|
-
case `writable_pure_selector_family`:
|
|
69
|
-
case `readonly_held_selector_family`:
|
|
70
|
-
case `writable_held_selector_family`: {
|
|
71
|
-
if (store.defaults.has(family.key)) {
|
|
72
|
-
return store.defaults.get(token.family.key)
|
|
73
|
-
}
|
|
74
|
-
const defaultValue = withdraw(store, family).default(parseJson(subKey))
|
|
75
|
-
store.defaults.set(family.key, defaultValue)
|
|
76
|
-
return defaultValue
|
|
77
|
-
}
|
|
78
|
-
}
|
|
23
|
+
const { token, familyToken, subKey } = reduceReference(store, ...params)
|
|
24
|
+
|
|
25
|
+
if (`counterfeit` in token && familyToken && subKey) {
|
|
26
|
+
const family = withdraw(store, familyToken)
|
|
27
|
+
return getFallback(store, token, family, subKey)
|
|
79
28
|
}
|
|
29
|
+
const state = withdraw(store, token)
|
|
80
30
|
|
|
81
|
-
return readOrComputeValue(store,
|
|
31
|
+
return readOrComputeValue(store, state)
|
|
82
32
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReadableFamilyToken, ReadableToken } from "atom.io"
|
|
2
|
+
import { type Canonical, parseJson } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
import { seekInStore } from "../families"
|
|
5
|
+
import { getFamilyOfToken } from "../families/get-family-of-token"
|
|
6
|
+
import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
|
|
7
|
+
import type { Store } from "../store"
|
|
8
|
+
import { withdraw } from "../store"
|
|
9
|
+
|
|
10
|
+
export function reduceReference<T, K extends Canonical>(
|
|
11
|
+
store: Store,
|
|
12
|
+
...params:
|
|
13
|
+
| [token: ReadableFamilyToken<T, K>, key: K]
|
|
14
|
+
| [token: ReadableToken<T>]
|
|
15
|
+
): {
|
|
16
|
+
token: ReadableToken<T>
|
|
17
|
+
familyToken: ReadableFamilyToken<T, K> | undefined
|
|
18
|
+
subKey: K | undefined
|
|
19
|
+
isNew: boolean
|
|
20
|
+
} {
|
|
21
|
+
let existingToken: ReadableToken<T> | undefined
|
|
22
|
+
let brandNewToken: ReadableToken<T> | undefined
|
|
23
|
+
let familyToken: ReadableFamilyToken<T, K> | undefined
|
|
24
|
+
let subKey: K | undefined
|
|
25
|
+
let token: ReadableToken<T, K>
|
|
26
|
+
if (params.length === 1) {
|
|
27
|
+
token = params[0]
|
|
28
|
+
if (`family` in token) {
|
|
29
|
+
familyToken = getFamilyOfToken(store, token)
|
|
30
|
+
withdraw(store, familyToken)
|
|
31
|
+
subKey = parseJson(token.family.subKey)
|
|
32
|
+
existingToken = seekInStore(store, familyToken, subKey)
|
|
33
|
+
if (`counterfeit` in token) {
|
|
34
|
+
return {
|
|
35
|
+
token,
|
|
36
|
+
familyToken,
|
|
37
|
+
subKey,
|
|
38
|
+
isNew: false,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!existingToken) {
|
|
42
|
+
brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE)
|
|
43
|
+
token = brandNewToken
|
|
44
|
+
} else {
|
|
45
|
+
token = existingToken
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
familyToken = params[0]
|
|
50
|
+
subKey = params[1]
|
|
51
|
+
existingToken = seekInStore(store, familyToken, subKey)
|
|
52
|
+
if (!existingToken) {
|
|
53
|
+
brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE)
|
|
54
|
+
token = brandNewToken
|
|
55
|
+
} else {
|
|
56
|
+
token = existingToken
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
token,
|
|
62
|
+
familyToken,
|
|
63
|
+
subKey,
|
|
64
|
+
isNew: Boolean(brandNewToken),
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/internal/index.ts
CHANGED
|
@@ -8,7 +8,8 @@ import type {
|
|
|
8
8
|
} from "atom.io"
|
|
9
9
|
import { parseJson, stringifyJson } from "atom.io/json"
|
|
10
10
|
|
|
11
|
-
import { disposeFromStore
|
|
11
|
+
import { disposeFromStore } from "../families"
|
|
12
|
+
import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
|
|
12
13
|
import {
|
|
13
14
|
allocateIntoStore,
|
|
14
15
|
claimWithinStore,
|
|
@@ -61,7 +62,7 @@ function createInStore(
|
|
|
61
62
|
if (familyMeta) {
|
|
62
63
|
const family = store.families.get(familyMeta.key)
|
|
63
64
|
if (family) {
|
|
64
|
-
|
|
65
|
+
mintInStore(store, family, parseJson(familyMeta.subKey), MUST_CREATE)
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -98,7 +99,7 @@ export function ingestMoleculeDisposalEvent(
|
|
|
98
99
|
for (const [familyKey, value] of update.values) {
|
|
99
100
|
const family = store.families.get(familyKey)
|
|
100
101
|
if (family) {
|
|
101
|
-
|
|
102
|
+
mintInStore(store, family, update.key, MUST_CREATE)
|
|
102
103
|
const memberKey = `${familyKey}(${stringifyJson(update.key)})`
|
|
103
104
|
store.valueMap.set(memberKey, value)
|
|
104
105
|
}
|
package/src/internal/molecule.ts
CHANGED
|
@@ -97,7 +97,7 @@ export function allocateIntoStore<
|
|
|
97
97
|
)
|
|
98
98
|
store.logger.error(
|
|
99
99
|
`❌`,
|
|
100
|
-
`
|
|
100
|
+
`key`,
|
|
101
101
|
key,
|
|
102
102
|
`allocation failed:`,
|
|
103
103
|
`Could not allocate to ${claim} in store "${store.config.name}".`,
|
|
@@ -147,7 +147,7 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
|
147
147
|
)
|
|
148
148
|
store.logger.error(
|
|
149
149
|
`❌`,
|
|
150
|
-
`
|
|
150
|
+
`key`,
|
|
151
151
|
claim,
|
|
152
152
|
`deallocation failed:`,
|
|
153
153
|
`Could not find allocation for ${stringKey} in store "${store.config.name}".`,
|
|
@@ -244,8 +244,8 @@ export function claimWithinStore<
|
|
|
244
244
|
)
|
|
245
245
|
store.logger.error(
|
|
246
246
|
`❌`,
|
|
247
|
-
`
|
|
248
|
-
|
|
247
|
+
`key`,
|
|
248
|
+
stringKey,
|
|
249
249
|
`claim failed:`,
|
|
250
250
|
`Could not allocate to ${stringKey} in store "${store.config.name}".`,
|
|
251
251
|
disposal
|
|
@@ -263,7 +263,7 @@ export function claimWithinStore<
|
|
|
263
263
|
)
|
|
264
264
|
store.logger.error(
|
|
265
265
|
`❌`,
|
|
266
|
-
`
|
|
266
|
+
`key`,
|
|
267
267
|
claim,
|
|
268
268
|
`claim failed:`,
|
|
269
269
|
`Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
|
|
@@ -6,14 +6,11 @@ import type {
|
|
|
6
6
|
MutableAtomToken,
|
|
7
7
|
StateLifecycleEvent,
|
|
8
8
|
} from "atom.io"
|
|
9
|
+
import { PRETTY_TOKEN_TYPES } from "atom.io"
|
|
9
10
|
import type { Canonical } from "atom.io/json"
|
|
10
11
|
import { stringifyJson } from "atom.io/json"
|
|
11
12
|
|
|
12
|
-
import {
|
|
13
|
-
createWritablePureSelectorFamily,
|
|
14
|
-
type MutableAtomFamily,
|
|
15
|
-
prettyPrintTokenType,
|
|
16
|
-
} from ".."
|
|
13
|
+
import { createWritablePureSelectorFamily, type MutableAtomFamily } from ".."
|
|
17
14
|
import { newest } from "../lineage"
|
|
18
15
|
import { createMutableAtom } from "../mutable"
|
|
19
16
|
import type { Store } from "../store"
|
|
@@ -41,9 +38,7 @@ export function createMutableAtomFamily<
|
|
|
41
38
|
`❗`,
|
|
42
39
|
`mutable_atom_family`,
|
|
43
40
|
options.key,
|
|
44
|
-
`Overwriting an existing ${
|
|
45
|
-
existing,
|
|
46
|
-
)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
|
|
41
|
+
`Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
|
|
47
42
|
)
|
|
48
43
|
}
|
|
49
44
|
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
WritablePureSelectorFamilyToken,
|
|
4
4
|
WritablePureSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
|
+
import { parseJson } from "atom.io/json"
|
|
6
7
|
|
|
7
8
|
import { findInStore } from "../families"
|
|
8
9
|
import { newest } from "../lineage"
|
|
@@ -21,7 +22,7 @@ export const getJsonToken = <T extends Transceiver<any, any, any>>(
|
|
|
21
22
|
type: `writable_pure_selector_family`,
|
|
22
23
|
}
|
|
23
24
|
const family = withdraw(target, jsonFamilyToken)
|
|
24
|
-
const subKey =
|
|
25
|
+
const subKey = parseJson(mutableAtomToken.family.subKey)
|
|
25
26
|
const jsonToken = findInStore(store, family, subKey)
|
|
26
27
|
return jsonToken
|
|
27
28
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AtomIOToken, PRETTY_TOKEN_TYPES } from "atom.io"
|
|
2
2
|
import { stringifyJson } from "atom.io/json"
|
|
3
3
|
|
|
4
|
-
import { prettyPrintTokenType } from "./pretty-print"
|
|
5
4
|
import type { Store } from "./store"
|
|
6
5
|
|
|
7
6
|
export class NotFoundError extends Error {
|
|
8
7
|
public constructor(token: AtomIOToken, store: Store) {
|
|
9
8
|
super(
|
|
10
|
-
`${
|
|
9
|
+
`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${
|
|
11
10
|
store.config.name
|
|
12
11
|
}".`,
|
|
13
12
|
)
|
|
@@ -23,7 +23,7 @@ export function openOperation(
|
|
|
23
23
|
if (store.operation.open) {
|
|
24
24
|
const rejectionTime = performance.now()
|
|
25
25
|
store.logger.info(
|
|
26
|
-
|
|
26
|
+
`🚫`,
|
|
27
27
|
token.type,
|
|
28
28
|
token.key,
|
|
29
29
|
`deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`,
|
|
@@ -7,13 +7,15 @@ import type {
|
|
|
7
7
|
WritableToken,
|
|
8
8
|
WriterToolkit,
|
|
9
9
|
} from "atom.io"
|
|
10
|
-
import type { Canonical
|
|
10
|
+
import type { Canonical } from "atom.io/json"
|
|
11
11
|
|
|
12
12
|
import { findInStore } from "../families"
|
|
13
|
+
import { getFallback } from "../get-state/get-fallback"
|
|
13
14
|
import { readOrComputeValue } from "../get-state/read-or-compute-value"
|
|
15
|
+
import { reduceReference } from "../get-state/reduce-reference"
|
|
14
16
|
import { newest } from "../lineage"
|
|
15
17
|
import { getJsonToken } from "../mutable"
|
|
16
|
-
import { operateOnStore } from "../set-state/operate-on-store"
|
|
18
|
+
import { JOIN_OP, operateOnStore } from "../set-state/operate-on-store"
|
|
17
19
|
import type { Store } from "../store"
|
|
18
20
|
import { withdraw } from "../store"
|
|
19
21
|
import { updateSelectorAtoms } from "./update-selector-atoms"
|
|
@@ -31,48 +33,39 @@ export function registerSelector(
|
|
|
31
33
|
return {
|
|
32
34
|
get: (
|
|
33
35
|
...params:
|
|
34
|
-
| [ReadableFamilyToken<any, any>,
|
|
36
|
+
| [ReadableFamilyToken<any, any>, Canonical]
|
|
35
37
|
| [ReadableToken<any>]
|
|
36
38
|
) => {
|
|
37
39
|
const target = newest(store)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
const
|
|
42
|
-
|
|
40
|
+
const { token, familyToken, subKey } = reduceReference(store, ...params)
|
|
41
|
+
let dependencyValue: unknown
|
|
42
|
+
if (`counterfeit` in token && familyToken && subKey) {
|
|
43
|
+
const dependencyFamily = withdraw(store, familyToken)
|
|
44
|
+
dependencyValue = getFallback(store, token, dependencyFamily, subKey)
|
|
43
45
|
} else {
|
|
44
|
-
|
|
46
|
+
const dependency = withdraw(store, token)
|
|
47
|
+
dependencyValue = readOrComputeValue(store, dependency)
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
const dependencyState = withdraw(store, dependency)
|
|
48
|
-
const dependencyValue = readOrComputeValue(store, dependencyState)
|
|
49
|
-
const dependencyKey = dependency.key
|
|
50
|
-
|
|
51
50
|
store.logger.info(
|
|
52
51
|
`🔌`,
|
|
53
52
|
selectorType,
|
|
54
53
|
selectorKey,
|
|
55
|
-
`registers dependency ( "${
|
|
54
|
+
`registers dependency ( "${token.key}" =`,
|
|
56
55
|
dependencyValue,
|
|
57
56
|
`)`,
|
|
58
57
|
)
|
|
59
58
|
|
|
60
59
|
target.selectorGraph.set(
|
|
61
60
|
{
|
|
62
|
-
upstreamSelectorKey:
|
|
61
|
+
upstreamSelectorKey: token.key,
|
|
63
62
|
downstreamSelectorKey: selectorKey,
|
|
64
63
|
},
|
|
65
64
|
{
|
|
66
|
-
source:
|
|
65
|
+
source: token.key,
|
|
67
66
|
},
|
|
68
67
|
)
|
|
69
|
-
updateSelectorAtoms(
|
|
70
|
-
store,
|
|
71
|
-
selectorType,
|
|
72
|
-
selectorKey,
|
|
73
|
-
dependency as any,
|
|
74
|
-
covered,
|
|
75
|
-
)
|
|
68
|
+
updateSelectorAtoms(store, selectorType, selectorKey, token, covered)
|
|
76
69
|
return dependencyValue
|
|
77
70
|
},
|
|
78
71
|
set: (<T, K extends Canonical, New extends T, Key extends K>(
|
|
@@ -85,7 +78,7 @@ export function registerSelector(
|
|
|
85
78
|
| [token: WritableToken<T>, value: New | ((oldValue: T) => New)]
|
|
86
79
|
) => {
|
|
87
80
|
const target = newest(store)
|
|
88
|
-
operateOnStore(target,
|
|
81
|
+
operateOnStore(target, JOIN_OP, ...params)
|
|
89
82
|
}) as typeof setState,
|
|
90
83
|
find: ((...args: Parameters<typeof findState>) =>
|
|
91
84
|
findInStore(store, ...args)) as typeof findState,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReadableToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import { newest } from "../lineage"
|
|
4
4
|
import type { Store } from "../store"
|
|
@@ -12,7 +12,7 @@ export function updateSelectorAtoms(
|
|
|
12
12
|
| `writable_held_selector`
|
|
13
13
|
| `writable_pure_selector`,
|
|
14
14
|
selectorKey: string,
|
|
15
|
-
dependency:
|
|
15
|
+
dependency: ReadableToken<unknown>,
|
|
16
16
|
covered: Set<string>,
|
|
17
17
|
): void {
|
|
18
18
|
const target = newest(store)
|
|
@@ -3,7 +3,7 @@ import { type Canonical, parseJson } from "atom.io/json"
|
|
|
3
3
|
|
|
4
4
|
import { seekInStore } from "../families"
|
|
5
5
|
import { getFamilyOfToken } from "../families/get-family-of-token"
|
|
6
|
-
import { mintInStore } from "../families/mint-in-store"
|
|
6
|
+
import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
|
|
7
7
|
import type { OpenOperation } from "../operation"
|
|
8
8
|
import { closeOperation, openOperation } from "../operation"
|
|
9
9
|
import { type Store, withdraw } from "../store"
|
|
@@ -12,9 +12,12 @@ import { resetAtomOrSelector } from "./reset-atom-or-selector"
|
|
|
12
12
|
import { RESET_STATE } from "./reset-in-store"
|
|
13
13
|
import { setAtomOrSelector } from "./set-atom-or-selector"
|
|
14
14
|
|
|
15
|
+
export const OWN_OP: unique symbol = Symbol(`OWN_OP`)
|
|
16
|
+
export const JOIN_OP: unique symbol = Symbol(`JOIN_OP`)
|
|
17
|
+
|
|
15
18
|
export function operateOnStore<T, New extends T>(
|
|
16
19
|
store: Store,
|
|
17
|
-
|
|
20
|
+
opMode: typeof JOIN_OP | typeof OWN_OP,
|
|
18
21
|
...params:
|
|
19
22
|
| [
|
|
20
23
|
token: WritableFamilyToken<T, Canonical>,
|
|
@@ -35,13 +38,12 @@ export function operateOnStore<T, New extends T>(
|
|
|
35
38
|
if (params.length === 2) {
|
|
36
39
|
token = params[0]
|
|
37
40
|
value = params[1]
|
|
38
|
-
if (token
|
|
39
|
-
|
|
40
|
-
family = getFamilyOfToken(store, token)!
|
|
41
|
+
if (`family` in token) {
|
|
42
|
+
family = getFamilyOfToken(store, token)
|
|
41
43
|
key = parseJson(token.family.subKey)
|
|
42
44
|
existingToken = seekInStore(store, family, key)
|
|
43
45
|
if (!existingToken) {
|
|
44
|
-
brandNewToken = mintInStore(store, family, key)
|
|
46
|
+
brandNewToken = mintInStore(store, family, key, MUST_CREATE)
|
|
45
47
|
token = brandNewToken
|
|
46
48
|
} else {
|
|
47
49
|
token = existingToken
|
|
@@ -53,7 +55,7 @@ export function operateOnStore<T, New extends T>(
|
|
|
53
55
|
value = params[2]
|
|
54
56
|
existingToken = seekInStore(store, family, key)
|
|
55
57
|
if (!existingToken) {
|
|
56
|
-
brandNewToken = mintInStore(store, family, key)
|
|
58
|
+
brandNewToken = mintInStore(store, family, key, MUST_CREATE)
|
|
57
59
|
token = brandNewToken
|
|
58
60
|
} else {
|
|
59
61
|
token = existingToken
|
|
@@ -64,7 +66,7 @@ export function operateOnStore<T, New extends T>(
|
|
|
64
66
|
|
|
65
67
|
let target: Store & { operation: OpenOperation }
|
|
66
68
|
|
|
67
|
-
if (
|
|
69
|
+
if (opMode === OWN_OP) {
|
|
68
70
|
const result = openOperation(store, token)
|
|
69
71
|
const rejected = typeof result === `number`
|
|
70
72
|
if (rejected) {
|
|
@@ -81,7 +83,7 @@ export function operateOnStore<T, New extends T>(
|
|
|
81
83
|
action,
|
|
82
84
|
`from T-${rejectionTime}`,
|
|
83
85
|
)
|
|
84
|
-
operateOnStore(store,
|
|
86
|
+
operateOnStore(store, opMode, token, value)
|
|
85
87
|
},
|
|
86
88
|
)
|
|
87
89
|
return
|
|
@@ -102,10 +104,12 @@ export function operateOnStore<T, New extends T>(
|
|
|
102
104
|
token.key,
|
|
103
105
|
`could not be`,
|
|
104
106
|
action,
|
|
105
|
-
`because
|
|
107
|
+
`because key`,
|
|
108
|
+
subKey,
|
|
109
|
+
`is not allocated.`,
|
|
106
110
|
disposal
|
|
107
|
-
? `
|
|
108
|
-
: `
|
|
111
|
+
? `this key was previously disposed:${disposal.trace}`
|
|
112
|
+
: `(no previous disposal trace found)`,
|
|
109
113
|
)
|
|
110
114
|
return
|
|
111
115
|
}
|
|
@@ -120,7 +124,7 @@ export function operateOnStore<T, New extends T>(
|
|
|
120
124
|
const isNewlyCreated = Boolean(brandNewToken)
|
|
121
125
|
dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated)
|
|
122
126
|
|
|
123
|
-
if (
|
|
127
|
+
if (opMode === OWN_OP) {
|
|
124
128
|
closeOperation(target)
|
|
125
129
|
}
|
|
126
130
|
}
|