atom.io 0.33.21 → 0.34.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/dist/internal/index.d.ts +5 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1252 -1247
- package/dist/internal/index.js.map +1 -1
- package/dist/realtime-client/index.js +2 -2
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js +0 -1
- package/dist/realtime-testing/index.js.map +1 -1
- package/package.json +1 -1
- package/src/internal/atom/create-regular-atom.ts +6 -7
- package/src/internal/caching.ts +9 -9
- package/src/internal/future.ts +3 -0
- package/src/internal/get-state/read-or-compute-value.ts +12 -7
- package/src/internal/mutable/create-mutable-atom.ts +2 -4
- package/src/internal/selector/create-readonly-held-selector.ts +10 -0
- package/src/internal/selector/create-readonly-pure-selector.ts +13 -4
- package/src/internal/selector/create-writable-held-selector.ts +11 -2
- package/src/internal/selector/create-writable-pure-selector.ts +11 -1
- package/src/internal/selector/trace-selector-atoms.ts +18 -40
- package/src/internal/selector/update-selector-atoms.ts +5 -5
- package/src/internal/set-state/evict-downstream.ts +2 -2
- package/src/internal/set-state/reset-atom-or-selector.ts +3 -3
- package/src/internal/store/store.ts +0 -1
- package/src/internal/subscribe/subscribe-to-root-atoms.ts +42 -38
- package/src/internal/subscribe/subscribe-to-state.ts +23 -11
- package/src/realtime-client/realtime-client-stores/client-sync-store.ts +2 -2
- package/src/realtime-testing/setup-realtime-test.tsx +0 -5
|
@@ -2,7 +2,7 @@ import type { ReadonlyPureSelectorToken, WritableToken } from "atom.io"
|
|
|
2
2
|
|
|
3
3
|
import { newest } from "../lineage"
|
|
4
4
|
import type { Store } from "../store"
|
|
5
|
-
import {
|
|
5
|
+
import { traceRootSelectorAtoms } from "./trace-selector-atoms"
|
|
6
6
|
|
|
7
7
|
export const updateSelectorAtoms = (
|
|
8
8
|
store: Store,
|
|
@@ -29,16 +29,16 @@ export const updateSelectorAtoms = (
|
|
|
29
29
|
`discovers root atom "${dependencyKey}"`,
|
|
30
30
|
)
|
|
31
31
|
} else {
|
|
32
|
-
const rootKeys =
|
|
32
|
+
const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered)
|
|
33
33
|
store.logger.info(
|
|
34
34
|
`🔍`,
|
|
35
35
|
selectorType,
|
|
36
36
|
selectorKey,
|
|
37
|
-
`discovers root atoms: [ ${rootKeys
|
|
38
|
-
.map((
|
|
37
|
+
`discovers root atoms: [ ${[...rootKeys.values()]
|
|
38
|
+
.map((root) => `"${root.key}"`)
|
|
39
39
|
.join(`, `)} ]`,
|
|
40
40
|
)
|
|
41
|
-
for (const atomKey of rootKeys) {
|
|
41
|
+
for (const { key: atomKey } of rootKeys.values()) {
|
|
42
42
|
target.selectorAtoms = target.selectorAtoms.set({
|
|
43
43
|
selectorKey,
|
|
44
44
|
atomKey,
|
|
@@ -29,7 +29,7 @@ export function evictDownStream(store: Store, atom: Atom<any>): void {
|
|
|
29
29
|
if (isDone(target, key)) {
|
|
30
30
|
continue
|
|
31
31
|
}
|
|
32
|
-
evictCachedValue(
|
|
32
|
+
evictCachedValue(target, key)
|
|
33
33
|
markDone(target, key)
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -49,7 +49,7 @@ export function evictDownStreamFromSelector(
|
|
|
49
49
|
if (isDone(target, downstreamSelectorKey)) {
|
|
50
50
|
continue
|
|
51
51
|
}
|
|
52
|
-
evictCachedValue(
|
|
52
|
+
evictCachedValue(target, downstreamSelectorKey)
|
|
53
53
|
markDone(target, downstreamSelectorKey)
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Atom, WritableState } from ".."
|
|
2
|
-
import {
|
|
2
|
+
import { traceRootSelectorAtoms } from ".."
|
|
3
3
|
import type { Store } from "../store"
|
|
4
4
|
import { setAtom } from "./set-atom"
|
|
5
5
|
|
|
@@ -23,8 +23,8 @@ export function resetAtomOrSelector(
|
|
|
23
23
|
case `writable_pure_selector`:
|
|
24
24
|
case `writable_held_selector`:
|
|
25
25
|
{
|
|
26
|
-
const atoms =
|
|
27
|
-
for (const atom of atoms) {
|
|
26
|
+
const atoms = traceRootSelectorAtoms(store, state.key)
|
|
27
|
+
for (const atom of atoms.values()) {
|
|
28
28
|
resetAtom(store, atom)
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -1,46 +1,50 @@
|
|
|
1
|
-
import type { Selector } from ".."
|
|
1
|
+
import type { Atom, Selector } from ".."
|
|
2
2
|
import { readOrComputeValue } from "../get-state/read-or-compute-value"
|
|
3
|
-
import { newest } from "../lineage"
|
|
4
|
-
import { traceAllSelectorAtoms } from "../selector"
|
|
5
3
|
import type { Store } from "../store"
|
|
6
4
|
import { recallState } from "./recall-state"
|
|
7
5
|
|
|
8
|
-
export const
|
|
9
|
-
|
|
10
|
-
selector: Selector<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
`->`,
|
|
27
|
-
atomChange.newValue,
|
|
28
|
-
)
|
|
29
|
-
const oldValue = recallState(target, selector)
|
|
30
|
-
const newValue = readOrComputeValue(target, selector)
|
|
31
|
-
store.logger.info(
|
|
32
|
-
`✨`,
|
|
33
|
-
selector.type,
|
|
34
|
-
selector.key,
|
|
35
|
-
`went`,
|
|
36
|
-
oldValue,
|
|
37
|
-
`->`,
|
|
38
|
-
newValue,
|
|
39
|
-
)
|
|
40
|
-
selector.subject.next({ newValue, oldValue })
|
|
41
|
-
},
|
|
6
|
+
export const subscribeToRootDependency = (
|
|
7
|
+
target: Store,
|
|
8
|
+
selector: Selector<any>,
|
|
9
|
+
atom: Atom<any>,
|
|
10
|
+
): (() => void) => {
|
|
11
|
+
return atom.subject.subscribe(
|
|
12
|
+
`${selector.type}:${selector.key}`,
|
|
13
|
+
(atomChange) => {
|
|
14
|
+
target.logger.info(
|
|
15
|
+
`📢`,
|
|
16
|
+
selector.type,
|
|
17
|
+
selector.key,
|
|
18
|
+
`root`,
|
|
19
|
+
atom.key,
|
|
20
|
+
`went`,
|
|
21
|
+
atomChange.oldValue,
|
|
22
|
+
`->`,
|
|
23
|
+
atomChange.newValue,
|
|
42
24
|
)
|
|
25
|
+
const oldValue = recallState(target, selector)
|
|
26
|
+
const newValue = readOrComputeValue(target, selector)
|
|
27
|
+
target.logger.info(
|
|
28
|
+
`✨`,
|
|
29
|
+
selector.type,
|
|
30
|
+
selector.key,
|
|
31
|
+
`went`,
|
|
32
|
+
oldValue,
|
|
33
|
+
`->`,
|
|
34
|
+
newValue,
|
|
35
|
+
)
|
|
36
|
+
selector.subject.next({ newValue, oldValue })
|
|
43
37
|
},
|
|
44
38
|
)
|
|
45
|
-
return dependencySubscriptions
|
|
46
39
|
}
|
|
40
|
+
|
|
41
|
+
// export const subscribeToRootAtoms = (
|
|
42
|
+
// store: Store,
|
|
43
|
+
// selector: Selector<any>,
|
|
44
|
+
// ): (() => void)[] => {
|
|
45
|
+
// const target = newest(store)
|
|
46
|
+
// const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map(
|
|
47
|
+
// (atom) => subscribeToRootDependency(target, selector, atom),
|
|
48
|
+
// )
|
|
49
|
+
// return dependencySubscriptions
|
|
50
|
+
// }
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ReadableToken, StateUpdate, UpdateHandler } from "atom.io"
|
|
2
2
|
|
|
3
|
+
import { readOrComputeValue } from "../get-state"
|
|
4
|
+
import { traceRootSelectorAtoms } from "../selector"
|
|
3
5
|
import type { Store } from "../store"
|
|
4
6
|
import { withdraw } from "../store"
|
|
5
|
-
import {
|
|
7
|
+
import { subscribeToRootDependency } from "./subscribe-to-root-atoms"
|
|
6
8
|
|
|
7
9
|
export function subscribeToState<T>(
|
|
8
10
|
store: Store,
|
|
@@ -28,14 +30,26 @@ export function subscribeToState<T>(
|
|
|
28
30
|
const isSelector =
|
|
29
31
|
state.type === `writable_pure_selector` ||
|
|
30
32
|
state.type === `readonly_pure_selector`
|
|
31
|
-
|
|
33
|
+
const rootSubs = new Map<string, () => void>()
|
|
32
34
|
let updateHandler: UpdateHandler<T> = safelyHandleUpdate
|
|
33
35
|
if (isSelector) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
readOrComputeValue(store, state)
|
|
37
|
+
for (const [atomKey, atom] of traceRootSelectorAtoms(store, state.key)) {
|
|
38
|
+
rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom))
|
|
39
|
+
}
|
|
40
|
+
updateHandler = function updateRootsBeforeHandlingUpdate(update) {
|
|
41
|
+
const dependencies = traceRootSelectorAtoms(store, state.key)
|
|
42
|
+
for (const [previousRootKey, unsub] of rootSubs) {
|
|
43
|
+
const currentRoot = dependencies.get(previousRootKey)
|
|
44
|
+
if (currentRoot) {
|
|
45
|
+
dependencies.delete(previousRootKey)
|
|
46
|
+
} else {
|
|
47
|
+
unsub()
|
|
48
|
+
rootSubs.delete(previousRootKey)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const [atomKey, atom] of dependencies) {
|
|
52
|
+
rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom))
|
|
39
53
|
}
|
|
40
54
|
safelyHandleUpdate(update)
|
|
41
55
|
}
|
|
@@ -49,10 +63,8 @@ export function subscribeToState<T>(
|
|
|
49
63
|
`Removing subscription "${key}"`,
|
|
50
64
|
)
|
|
51
65
|
mainUnsubFunction()
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
unsubFromDependency()
|
|
55
|
-
}
|
|
66
|
+
for (const unsubFromDependency of rootSubs.values()) {
|
|
67
|
+
unsubFromDependency()
|
|
56
68
|
}
|
|
57
69
|
}
|
|
58
70
|
|
|
@@ -4,12 +4,12 @@ export const optimisticUpdateQueue: AtomIO.RegularAtomToken<
|
|
|
4
4
|
AtomIO.TransactionUpdate<any>[]
|
|
5
5
|
> = AtomIO.atom<AtomIO.TransactionUpdate<any>[]>({
|
|
6
6
|
key: `updateQueue`,
|
|
7
|
-
default: [],
|
|
7
|
+
default: () => [],
|
|
8
8
|
})
|
|
9
9
|
|
|
10
10
|
export const confirmedUpdateQueue: AtomIO.RegularAtomToken<
|
|
11
11
|
AtomIO.TransactionUpdate<any>[]
|
|
12
12
|
> = AtomIO.atom<AtomIO.TransactionUpdate<any>[]>({
|
|
13
13
|
key: `serverConfirmedUpdateQueue`,
|
|
14
|
-
default: [],
|
|
14
|
+
default: () => [],
|
|
15
15
|
})
|
|
@@ -192,11 +192,6 @@ export const setupRealtimeTestClient = (
|
|
|
192
192
|
auth: { token: `test`, username: `${name}-${testNumber}` },
|
|
193
193
|
})
|
|
194
194
|
const silo = new AtomIO.Silo({ name, lifespan: `ephemeral` }, IMPLICIT.STORE)
|
|
195
|
-
for (const [key, value] of silo.store.valueMap.entries()) {
|
|
196
|
-
if (Array.isArray(value)) {
|
|
197
|
-
silo.store.valueMap.set(key, [...value])
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
195
|
silo.setState(RTC.myUsernameState, `${name}-${testNumber}`)
|
|
201
196
|
|
|
202
197
|
const { document } = new Happy.Window()
|