atom.io 0.10.2 → 0.10.4
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/index.d.mts +53 -8
- package/dist/index.d.ts +53 -8
- package/dist/index.js +53 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -33
- package/dist/index.mjs.map +1 -1
- package/internal/dist/index.js +239 -113
- package/internal/dist/index.js.map +1 -1
- package/internal/dist/index.mjs +239 -113
- package/internal/dist/index.mjs.map +1 -1
- package/internal/src/atom/create-atom.ts +15 -4
- package/internal/src/atom/delete-atom.ts +1 -1
- package/internal/src/caching.ts +4 -4
- package/internal/src/get-state-internal.ts +3 -5
- package/internal/src/mutable/create-mutable-atom.ts +4 -10
- package/internal/src/operation.ts +20 -7
- package/internal/src/selector/create-read-write-selector.ts +12 -2
- package/internal/src/selector/create-readonly-selector.ts +7 -1
- package/internal/src/selector/create-selector.ts +4 -5
- package/internal/src/selector/register-selector.ts +7 -1
- package/internal/src/selector/update-selector-atoms.ts +10 -3
- package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
- package/internal/src/set-state/copy-mutable-in-transaction.ts +0 -3
- package/internal/src/set-state/emit-update.ts +5 -5
- package/internal/src/set-state/evict-downstream.ts +10 -13
- package/internal/src/set-state/set-atom.ts +1 -1
- package/internal/src/set-state/stow-update.ts +9 -3
- package/internal/src/store/store.ts +8 -19
- package/internal/src/store/withdraw-new-family-member.ts +4 -1
- package/internal/src/store/withdraw.ts +6 -1
- package/internal/src/subscribe/recall-state.ts +4 -1
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +11 -5
- package/internal/src/timeline/add-atom-to-timeline.ts +40 -9
- package/internal/src/timeline/time-travel-internal.ts +26 -8
- package/internal/src/timeline/timeline-internal.ts +8 -2
- package/internal/src/transaction/abort-transaction.ts +7 -2
- package/internal/src/transaction/apply-transaction.ts +21 -7
- package/internal/src/transaction/build-transaction.ts +5 -1
- package/internal/src/transaction/redo-transaction.ts +1 -1
- package/internal/src/transaction/transaction-internal.ts +1 -4
- package/internal/src/transaction/undo-transaction.ts +7 -1
- package/package.json +4 -4
- package/realtime-client/dist/index.js +24 -5
- package/realtime-client/dist/index.js.map +1 -1
- package/realtime-client/dist/index.mjs +24 -5
- package/realtime-client/dist/index.mjs.map +1 -1
- package/realtime-client/src/use-server-action.ts +24 -5
- package/src/logger.ts +79 -14
- package/src/subscribe.ts +22 -7
|
@@ -30,14 +30,19 @@ export function createAtom<T>(
|
|
|
30
30
|
store: Store = IMPLICIT.STORE,
|
|
31
31
|
): AtomToken<T> {
|
|
32
32
|
store.logger.info(
|
|
33
|
-
|
|
33
|
+
`🔨`,
|
|
34
|
+
`atom`,
|
|
35
|
+
options.key,
|
|
36
|
+
`creating in store "${store.config.name}"`,
|
|
34
37
|
)
|
|
35
38
|
const core = target(store)
|
|
36
39
|
const existing = core.atoms.get(options.key)
|
|
37
40
|
if (existing) {
|
|
38
41
|
store.logger.error(
|
|
39
|
-
|
|
40
|
-
`
|
|
42
|
+
`❌`,
|
|
43
|
+
`atom`,
|
|
44
|
+
options.key,
|
|
45
|
+
`Tried to create atom, but it already exists in the store.`,
|
|
41
46
|
`(Ignore if you are in development using hot module replacement.)`,
|
|
42
47
|
)
|
|
43
48
|
return deposit(existing)
|
|
@@ -47,8 +52,14 @@ export function createAtom<T>(
|
|
|
47
52
|
...options,
|
|
48
53
|
type: `atom`,
|
|
49
54
|
install: (store: Store) => {
|
|
55
|
+
// store.logger.info(
|
|
56
|
+
// `🛠️ installing atom "${options.key}" in store "${store.config.name}"`,
|
|
57
|
+
// )
|
|
50
58
|
store.logger.info(
|
|
51
|
-
|
|
59
|
+
`🛠️`,
|
|
60
|
+
`atom`,
|
|
61
|
+
options.key,
|
|
62
|
+
`installing in store "${store.config.name}"`,
|
|
52
63
|
)
|
|
53
64
|
return `mutable` in options
|
|
54
65
|
? createMutableAtom(options, store)
|
package/internal/src/caching.ts
CHANGED
|
@@ -26,9 +26,9 @@ export const cacheValue = (
|
|
|
26
26
|
cacheValue(key, value, subject, store)
|
|
27
27
|
subject.next({ newValue: value, oldValue: value })
|
|
28
28
|
})
|
|
29
|
-
.catch((
|
|
30
|
-
if (
|
|
31
|
-
store.logger.error(
|
|
29
|
+
.catch((thrown) => {
|
|
30
|
+
if (thrown !== `canceled`) {
|
|
31
|
+
store.logger.error(`💥`, `state`, key, `rejected:`, thrown)
|
|
32
32
|
}
|
|
33
33
|
})
|
|
34
34
|
} else {
|
|
@@ -59,5 +59,5 @@ export const evictCachedValue = (
|
|
|
59
59
|
core.operation.prev.set(key, currentValue)
|
|
60
60
|
}
|
|
61
61
|
core.valueMap.delete(key)
|
|
62
|
-
store.logger.info(
|
|
62
|
+
store.logger.info(`🗑`, `state`, key, `evicted`)
|
|
63
63
|
}
|
|
@@ -9,15 +9,13 @@ export const getState__INTERNAL = <T>(
|
|
|
9
9
|
store: Store = IMPLICIT.STORE,
|
|
10
10
|
): T => {
|
|
11
11
|
if (isValueCached(state.key, store)) {
|
|
12
|
-
store.logger.info(
|
|
12
|
+
store.logger.info(`📖`, state.type, state.key, `reading cached value`)
|
|
13
13
|
return readCachedValue(state.key, store)
|
|
14
14
|
}
|
|
15
15
|
if (state.type !== `atom`) {
|
|
16
|
-
store.logger.info(
|
|
16
|
+
store.logger.info(`🧮`, state.type, state.key, `calculating value`)
|
|
17
17
|
return state.get()
|
|
18
18
|
}
|
|
19
|
-
store.logger.error(
|
|
20
|
-
`🐞 Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`,
|
|
21
|
-
)
|
|
19
|
+
store.logger.error(`🐞`, `atom`, state.key, `could not find cached value`)
|
|
22
20
|
return state.default
|
|
23
21
|
}
|
|
@@ -18,7 +18,10 @@ export function createMutableAtom<
|
|
|
18
18
|
store: Store = IMPLICIT.STORE,
|
|
19
19
|
): MutableAtomToken<Core, SerializableCore> {
|
|
20
20
|
store.logger.info(
|
|
21
|
-
|
|
21
|
+
`🔧`,
|
|
22
|
+
`atom`,
|
|
23
|
+
options.key,
|
|
24
|
+
`creating in store "${store.config.name}"`,
|
|
22
25
|
)
|
|
23
26
|
const coreState = createAtom<Core>(options, undefined, store)
|
|
24
27
|
new Tracker(coreState, store)
|
|
@@ -26,15 +29,6 @@ export function createMutableAtom<
|
|
|
26
29
|
subscribe(
|
|
27
30
|
jsonState,
|
|
28
31
|
() => {
|
|
29
|
-
store.logger.info(
|
|
30
|
-
`🔍 tracker-initializer:${store?.config.name}:${
|
|
31
|
-
store.transactionStatus.phase === `idle`
|
|
32
|
-
? `main`
|
|
33
|
-
: store.transactionStatus.key
|
|
34
|
-
}`,
|
|
35
|
-
`Initializing tracker for ${coreState.key}`,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
32
|
const trackerHasBeenInitialized = target(store).trackers.has(coreState.key)
|
|
39
33
|
if (!trackerHasBeenInitialized) {
|
|
40
34
|
new Tracker(coreState, store)
|
|
@@ -23,7 +23,10 @@ export const openOperation = (
|
|
|
23
23
|
const core = target(store)
|
|
24
24
|
if (core.operation.open) {
|
|
25
25
|
store.logger.error(
|
|
26
|
-
|
|
26
|
+
`❌`,
|
|
27
|
+
token.type,
|
|
28
|
+
token.key,
|
|
29
|
+
`failed to setState during a setState for "${core.operation.token.key}"`,
|
|
27
30
|
)
|
|
28
31
|
return `rejection`
|
|
29
32
|
}
|
|
@@ -35,9 +38,10 @@ export const openOperation = (
|
|
|
35
38
|
token,
|
|
36
39
|
}
|
|
37
40
|
store.logger.info(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
`⭕`,
|
|
42
|
+
token.type,
|
|
43
|
+
token.key,
|
|
44
|
+
`operation start in store "${store.config.name}"${
|
|
41
45
|
store.transactionStatus.phase === `idle`
|
|
42
46
|
? ``
|
|
43
47
|
: ` ${store.transactionStatus.phase} "${store.transactionStatus.key}"`
|
|
@@ -48,7 +52,10 @@ export const closeOperation = (store: Store): void => {
|
|
|
48
52
|
const core = target(store)
|
|
49
53
|
if (core.operation.open) {
|
|
50
54
|
store.logger.info(
|
|
51
|
-
|
|
55
|
+
`🔴`,
|
|
56
|
+
core.operation.token.type,
|
|
57
|
+
core.operation.token.key,
|
|
58
|
+
`operation done in store "${store.config.name}"`,
|
|
52
59
|
)
|
|
53
60
|
}
|
|
54
61
|
core.operation = { open: false }
|
|
@@ -59,7 +66,10 @@ export const isDone = (key: string, store: Store = IMPLICIT.STORE): boolean => {
|
|
|
59
66
|
const core = target(store)
|
|
60
67
|
if (!core.operation.open) {
|
|
61
68
|
store.logger.warn(
|
|
62
|
-
|
|
69
|
+
`🐞`,
|
|
70
|
+
`unknown`,
|
|
71
|
+
key,
|
|
72
|
+
`isDone called outside of an operation. This is probably a bug.`,
|
|
63
73
|
)
|
|
64
74
|
return true
|
|
65
75
|
}
|
|
@@ -69,7 +79,10 @@ export const markDone = (key: string, store: Store = IMPLICIT.STORE): void => {
|
|
|
69
79
|
const core = target(store)
|
|
70
80
|
if (!core.operation.open) {
|
|
71
81
|
store.logger.warn(
|
|
72
|
-
|
|
82
|
+
`🐞`,
|
|
83
|
+
`unknown`,
|
|
84
|
+
key,
|
|
85
|
+
`markDone called outside of an operation. This is probably a bug.`,
|
|
73
86
|
)
|
|
74
87
|
return
|
|
75
88
|
}
|
|
@@ -27,7 +27,17 @@ export const createReadWriteSelector = <T>(
|
|
|
27
27
|
const setSelf = (next: T | ((oldValue: T) => T)): void => {
|
|
28
28
|
const oldValue = getSelf()
|
|
29
29
|
const newValue = become(next)(oldValue)
|
|
30
|
-
store.logger.info(`📝 set "${options.key}" (`, oldValue, `->`, newValue, `)`)
|
|
30
|
+
// store.logger.info(`📝 set "${options.key}" (`, oldValue, `->`, newValue, `)`)
|
|
31
|
+
store.logger.info(
|
|
32
|
+
`📝`,
|
|
33
|
+
`selector`,
|
|
34
|
+
options.key,
|
|
35
|
+
`set (`,
|
|
36
|
+
oldValue,
|
|
37
|
+
`->`,
|
|
38
|
+
newValue,
|
|
39
|
+
`)`,
|
|
40
|
+
)
|
|
31
41
|
cacheValue(options.key, newValue, subject, store)
|
|
32
42
|
markDone(options.key, store)
|
|
33
43
|
if (store.transactionStatus.phase === `idle`) {
|
|
@@ -46,7 +56,7 @@ export const createReadWriteSelector = <T>(
|
|
|
46
56
|
}
|
|
47
57
|
core.selectors.set(options.key, mySelector)
|
|
48
58
|
const initialValue = getSelf()
|
|
49
|
-
store.logger.info(
|
|
59
|
+
store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue)
|
|
50
60
|
const token: SelectorToken<T> = {
|
|
51
61
|
key: options.key,
|
|
52
62
|
type: `selector`,
|
|
@@ -36,7 +36,13 @@ export const createReadonlySelector = <T>(
|
|
|
36
36
|
}
|
|
37
37
|
core.readonlySelectors.set(options.key, readonlySelector)
|
|
38
38
|
const initialValue = getSelf()
|
|
39
|
-
store.logger.info(
|
|
39
|
+
store.logger.info(
|
|
40
|
+
`✨`,
|
|
41
|
+
readonlySelector.type,
|
|
42
|
+
readonlySelector.key,
|
|
43
|
+
`=`,
|
|
44
|
+
initialValue,
|
|
45
|
+
)
|
|
40
46
|
const token: ReadonlySelectorToken<T> = {
|
|
41
47
|
key: options.key,
|
|
42
48
|
type: `readonly_selector`,
|
|
@@ -52,11 +52,10 @@ export function createSelector<T>(
|
|
|
52
52
|
|
|
53
53
|
if (existingWritable || existingReadonly) {
|
|
54
54
|
store.logger.error(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
`
|
|
59
|
-
`(Ignore if you are in development using hot module replacement.)`,
|
|
55
|
+
`❌`,
|
|
56
|
+
existingReadonly ? `readonly_selector` : `selector`,
|
|
57
|
+
options.key,
|
|
58
|
+
`Tried to create selector, but it already exists in the store. (Ignore if you are in development using hot module replacement.)`,
|
|
60
59
|
)
|
|
61
60
|
}
|
|
62
61
|
|
|
@@ -26,8 +26,14 @@ export const registerSelector = (
|
|
|
26
26
|
const dependencyValue = getState__INTERNAL(dependencyState, store)
|
|
27
27
|
|
|
28
28
|
store.logger.info(
|
|
29
|
-
|
|
29
|
+
`🔌`,
|
|
30
|
+
`selector`,
|
|
31
|
+
selectorKey,
|
|
32
|
+
`registers dependency ( "${dependency.key}" =`,
|
|
33
|
+
dependencyValue,
|
|
34
|
+
`)`,
|
|
30
35
|
)
|
|
36
|
+
|
|
31
37
|
if (!alreadyRegistered) {
|
|
32
38
|
core.selectorGraph = core.selectorGraph.set(
|
|
33
39
|
{
|
|
@@ -16,13 +16,20 @@ export const updateSelectorAtoms = (
|
|
|
16
16
|
atomKey: dependency.key,
|
|
17
17
|
})
|
|
18
18
|
store.logger.info(
|
|
19
|
-
|
|
19
|
+
`🔍`,
|
|
20
|
+
`selector`,
|
|
21
|
+
selectorKey,
|
|
22
|
+
`discovers root atom "${dependency.key}"`,
|
|
20
23
|
)
|
|
21
24
|
} else {
|
|
22
25
|
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store)
|
|
23
26
|
store.logger.info(
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
`🔍`,
|
|
28
|
+
`selector`,
|
|
29
|
+
selectorKey,
|
|
30
|
+
`discovers root atoms: [ ${rootKeys
|
|
31
|
+
.map((key) => `"${key}"`)
|
|
32
|
+
.join(`, `)} ]`,
|
|
26
33
|
)
|
|
27
34
|
for (const atomKey of rootKeys) {
|
|
28
35
|
core.selectorAtoms = core.selectorAtoms.set({
|
|
@@ -13,7 +13,7 @@ export function copyMutableIfNeeded<T>(
|
|
|
13
13
|
const originValue = origin.valueMap.get(atom.key)
|
|
14
14
|
const targetValue = target.valueMap.get(atom.key)
|
|
15
15
|
if (originValue === targetValue) {
|
|
16
|
-
origin.logger.info(
|
|
16
|
+
origin.logger.info(`📃`, `atom`, `${atom.key}`, `copying`)
|
|
17
17
|
const copiedValue = transform.fromJson(transform.toJson(originValue))
|
|
18
18
|
target.valueMap.set(atom.key, copiedValue)
|
|
19
19
|
new Tracker(atom, origin)
|
|
@@ -14,9 +14,6 @@ export function copyMutableIfWithinTransaction<T>(
|
|
|
14
14
|
store.transactionStatus.phase === `applying`
|
|
15
15
|
) {
|
|
16
16
|
if (`toJson` in atom && `fromJson` in atom) {
|
|
17
|
-
store.logger.info(
|
|
18
|
-
`📄 copyMutableIfWithinTransaction: ${atom.key} is mutable`,
|
|
19
|
-
)
|
|
20
17
|
const copiedValue = copyMutableIfNeeded(
|
|
21
18
|
atom,
|
|
22
19
|
atom,
|
|
@@ -12,14 +12,14 @@ export const emitUpdate = <T>(
|
|
|
12
12
|
const { key } = state
|
|
13
13
|
const { logger } = store
|
|
14
14
|
logger.info(
|
|
15
|
-
|
|
15
|
+
`📢`,
|
|
16
|
+
state.type,
|
|
17
|
+
state.key,
|
|
18
|
+
`went (`,
|
|
16
19
|
update.oldValue,
|
|
17
20
|
`->`,
|
|
18
21
|
update.newValue,
|
|
19
|
-
`)
|
|
20
|
-
)
|
|
21
|
-
logger.info(
|
|
22
|
-
`📢 notifying subscribers to "${state.key}"`,
|
|
22
|
+
`) subscribers:`,
|
|
23
23
|
state.subject.subscribers,
|
|
24
24
|
)
|
|
25
25
|
state.subject.next(update)
|
|
@@ -6,34 +6,31 @@ import { IMPLICIT } from "../store"
|
|
|
6
6
|
import { target } from "../transaction"
|
|
7
7
|
|
|
8
8
|
export const evictDownStream = <T>(
|
|
9
|
-
|
|
9
|
+
atom: Atom<T>,
|
|
10
10
|
store: Store = IMPLICIT.STORE,
|
|
11
11
|
): void => {
|
|
12
12
|
const core = target(store)
|
|
13
|
-
const downstreamKeys = core.selectorAtoms.getRelatedKeys(
|
|
13
|
+
const downstreamKeys = core.selectorAtoms.getRelatedKeys(atom.key)
|
|
14
14
|
store.logger.info(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
`🧹`,
|
|
16
|
+
atom.type,
|
|
17
|
+
atom.key,
|
|
18
|
+
`evicting ${downstreamKeys?.size ?? 0} states downstream:`,
|
|
18
19
|
downstreamKeys,
|
|
19
20
|
)
|
|
20
21
|
if (downstreamKeys !== undefined) {
|
|
21
22
|
if (core.operation.open) {
|
|
22
23
|
store.logger.info(
|
|
23
|
-
|
|
24
|
+
`🧹`,
|
|
25
|
+
atom.type,
|
|
26
|
+
atom.key,
|
|
27
|
+
`[ ${[...core.operation.done].join(`, `)} ] already done`,
|
|
24
28
|
)
|
|
25
29
|
}
|
|
26
30
|
for (const key of downstreamKeys) {
|
|
27
31
|
if (isDone(key, store)) {
|
|
28
32
|
continue
|
|
29
33
|
}
|
|
30
|
-
const state = core.selectors.get(key) ?? core.readonlySelectors.get(key)
|
|
31
|
-
if (!state) {
|
|
32
|
-
store.logger.error(
|
|
33
|
-
`🐞 "${key}" was not found in selectors or readonlySelectors`,
|
|
34
|
-
)
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
34
|
evictCachedValue(key, store)
|
|
38
35
|
markDone(key, store)
|
|
39
36
|
}
|
|
@@ -19,7 +19,7 @@ export const setAtom = <T>(
|
|
|
19
19
|
const oldValue = getState__INTERNAL(atom, store)
|
|
20
20
|
let newValue = copyMutableIfWithinTransaction(atom, store)
|
|
21
21
|
newValue = become(next)(newValue)
|
|
22
|
-
store.logger.info(
|
|
22
|
+
store.logger.info(`📝`, `atom`, atom.key, `set to`, newValue)
|
|
23
23
|
cacheValue(atom.key, newValue, atom.subject, store)
|
|
24
24
|
if (isAtomDefault(atom.key, store)) {
|
|
25
25
|
markAtomAsNotDefault(atom.key, store)
|
|
@@ -23,8 +23,11 @@ export const stowUpdate = <T>(
|
|
|
23
23
|
): void => {
|
|
24
24
|
const { key } = state
|
|
25
25
|
if (store.transactionStatus.phase !== `building`) {
|
|
26
|
-
store.logger.
|
|
27
|
-
|
|
26
|
+
store.logger.error(
|
|
27
|
+
`🐞`,
|
|
28
|
+
`atom`,
|
|
29
|
+
key,
|
|
30
|
+
`stowUpdate called outside of a transaction. This is probably a bug.`,
|
|
28
31
|
)
|
|
29
32
|
return
|
|
30
33
|
}
|
|
@@ -38,7 +41,10 @@ export const stowUpdate = <T>(
|
|
|
38
41
|
}
|
|
39
42
|
store.transactionStatus.atomUpdates.push(atomUpdate)
|
|
40
43
|
store.logger.info(
|
|
41
|
-
|
|
44
|
+
`📁`,
|
|
45
|
+
`atom`,
|
|
46
|
+
key,
|
|
47
|
+
`stowed (`,
|
|
42
48
|
update.oldValue,
|
|
43
49
|
`->`,
|
|
44
50
|
update.newValue,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AtomIOLogger } from "atom.io"
|
|
1
|
+
import { AtomIOLogger, simpleLogger } from "atom.io"
|
|
2
2
|
import type {
|
|
3
3
|
AtomFamily,
|
|
4
4
|
AtomToken,
|
|
@@ -100,34 +100,23 @@ export class Store {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
public loggers: AtomIOLogger[] = [
|
|
103
|
-
new AtomIOLogger(
|
|
104
|
-
{ ...console },
|
|
105
|
-
`warn`,
|
|
106
|
-
(message) => !message.includes(`👁🗨`),
|
|
107
|
-
),
|
|
103
|
+
new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`👁🗨`)),
|
|
108
104
|
]
|
|
109
105
|
public logger: Logger = {
|
|
110
|
-
error: (...messages
|
|
111
|
-
for (const logger of this.loggers)
|
|
112
|
-
logger.error(...messages)
|
|
113
|
-
}
|
|
106
|
+
error: (...messages) => {
|
|
107
|
+
for (const logger of this.loggers) logger.error(...messages)
|
|
114
108
|
},
|
|
115
|
-
info: (...messages
|
|
116
|
-
for (const logger of this.loggers)
|
|
117
|
-
logger.info(...messages)
|
|
118
|
-
}
|
|
109
|
+
info: (...messages) => {
|
|
110
|
+
for (const logger of this.loggers) logger.info(...messages)
|
|
119
111
|
},
|
|
120
|
-
warn: (...messages
|
|
121
|
-
for (const logger of this.loggers)
|
|
122
|
-
logger.warn(...messages)
|
|
123
|
-
}
|
|
112
|
+
warn: (...messages) => {
|
|
113
|
+
for (const logger of this.loggers) logger.warn(...messages)
|
|
124
114
|
},
|
|
125
115
|
}
|
|
126
116
|
|
|
127
117
|
public constructor(name: string, store: Store | null = null) {
|
|
128
118
|
if (store !== null) {
|
|
129
119
|
this.valueMap = new Map(store?.valueMap)
|
|
130
|
-
|
|
131
120
|
this.operation = { ...store?.operation }
|
|
132
121
|
this.transactionStatus = { ...store?.transactionStatus }
|
|
133
122
|
this.config = {
|
|
@@ -37,7 +37,10 @@ export function withdrawNewFamilyMember<T>(
|
|
|
37
37
|
store: Store,
|
|
38
38
|
): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined {
|
|
39
39
|
store.logger.info(
|
|
40
|
-
|
|
40
|
+
`👪`,
|
|
41
|
+
token.type,
|
|
42
|
+
token.key,
|
|
43
|
+
`creating new family member in store "${store.config.name}"`,
|
|
41
44
|
)
|
|
42
45
|
if (token.family) {
|
|
43
46
|
const core = target(store)
|
|
@@ -78,7 +78,12 @@ export function withdraw<T>(
|
|
|
78
78
|
core.timelines.get(token.key)
|
|
79
79
|
|
|
80
80
|
if (state) {
|
|
81
|
-
store.logger.info(
|
|
81
|
+
store.logger.info(
|
|
82
|
+
`🛠️`,
|
|
83
|
+
token.type,
|
|
84
|
+
token.key,
|
|
85
|
+
`add ${token.type} "${token.key}"`,
|
|
86
|
+
)
|
|
82
87
|
switch (state.type) {
|
|
83
88
|
case `atom`: {
|
|
84
89
|
store.atoms.set(token.key, state)
|
|
@@ -11,7 +11,10 @@ export const recallState = <T>(
|
|
|
11
11
|
const core = target(store)
|
|
12
12
|
if (!core.operation.open) {
|
|
13
13
|
store.logger.warn(
|
|
14
|
-
|
|
14
|
+
`🐞`,
|
|
15
|
+
state.type,
|
|
16
|
+
state.key,
|
|
17
|
+
`recall called outside of an operation. This is probably a bug.`,
|
|
15
18
|
)
|
|
16
19
|
return core.valueMap.get(state.key)
|
|
17
20
|
}
|
|
@@ -22,21 +22,27 @@ export const subscribeToRootAtoms = <T>(
|
|
|
22
22
|
`${state.type}:${state.key}`,
|
|
23
23
|
(atomChange) => {
|
|
24
24
|
store.logger.info(
|
|
25
|
-
|
|
25
|
+
`📢`,
|
|
26
|
+
state.type,
|
|
27
|
+
state.key,
|
|
28
|
+
`root`,
|
|
29
|
+
atomKey,
|
|
30
|
+
`went`,
|
|
26
31
|
atomChange.oldValue,
|
|
27
32
|
`->`,
|
|
28
33
|
atomChange.newValue,
|
|
29
|
-
`)`,
|
|
30
34
|
)
|
|
31
35
|
const oldValue = recallState(state, store)
|
|
32
|
-
//
|
|
36
|
+
// ❌ this retrieves a stale cached value when applying a transaction on the server
|
|
33
37
|
const newValue = getState__INTERNAL(state, store)
|
|
34
38
|
store.logger.info(
|
|
35
|
-
|
|
39
|
+
`✨`,
|
|
40
|
+
state.type,
|
|
41
|
+
state.key,
|
|
42
|
+
`went`,
|
|
36
43
|
oldValue,
|
|
37
44
|
`->`,
|
|
38
45
|
newValue,
|
|
39
|
-
`)`,
|
|
40
46
|
)
|
|
41
47
|
state.subject.next({ newValue, oldValue })
|
|
42
48
|
},
|
|
@@ -38,16 +38,32 @@ export const addAtomToTimeline = (
|
|
|
38
38
|
? store.transactionStatus.time
|
|
39
39
|
: null
|
|
40
40
|
|
|
41
|
+
// store.logger.info(
|
|
42
|
+
// `⏳ timeline "${tl.key}" saw atom "${atomToken.key}" go (`,
|
|
43
|
+
// update.oldValue,
|
|
44
|
+
// `->`,
|
|
45
|
+
// update.newValue,
|
|
46
|
+
// currentTransactionKey
|
|
47
|
+
// ? `) in transaction "${currentTransactionKey}"`
|
|
48
|
+
// : currentSelectorKey
|
|
49
|
+
// ? `) in selector "${currentSelectorKey}"`
|
|
50
|
+
// : `)`,
|
|
51
|
+
// )
|
|
41
52
|
store.logger.info(
|
|
42
|
-
|
|
53
|
+
`⏳`,
|
|
54
|
+
`timeline`,
|
|
55
|
+
tl.key,
|
|
56
|
+
`atom`,
|
|
57
|
+
atomToken.key,
|
|
58
|
+
`went`,
|
|
43
59
|
update.oldValue,
|
|
44
60
|
`->`,
|
|
45
61
|
update.newValue,
|
|
46
62
|
currentTransactionKey
|
|
47
|
-
? `
|
|
63
|
+
? `in transaction "${currentTransactionKey}"`
|
|
48
64
|
: currentSelectorKey
|
|
49
|
-
? `
|
|
50
|
-
:
|
|
65
|
+
? `in selector "${currentSelectorKey}"`
|
|
66
|
+
: ``,
|
|
51
67
|
)
|
|
52
68
|
|
|
53
69
|
if (tl.timeTraveling === null) {
|
|
@@ -75,7 +91,10 @@ export const addAtomToTimeline = (
|
|
|
75
91
|
if (tl.transactionKey !== currentTransactionKey) {
|
|
76
92
|
if (tl.transactionKey) {
|
|
77
93
|
store.logger.error(
|
|
78
|
-
|
|
94
|
+
`🐞`,
|
|
95
|
+
`timeline`,
|
|
96
|
+
tl.key,
|
|
97
|
+
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`,
|
|
79
98
|
)
|
|
80
99
|
}
|
|
81
100
|
tl.transactionKey = currentTransactionKey
|
|
@@ -119,7 +138,10 @@ export const addAtomToTimeline = (
|
|
|
119
138
|
}
|
|
120
139
|
tl.transactionKey = null
|
|
121
140
|
store.logger.info(
|
|
122
|
-
|
|
141
|
+
`⌛`,
|
|
142
|
+
`timeline`,
|
|
143
|
+
tl.key,
|
|
144
|
+
`got a transaction_update "${update.key}"`,
|
|
123
145
|
)
|
|
124
146
|
},
|
|
125
147
|
)
|
|
@@ -146,7 +168,10 @@ export const addAtomToTimeline = (
|
|
|
146
168
|
tl.history.push(latestUpdate)
|
|
147
169
|
|
|
148
170
|
store.logger.info(
|
|
149
|
-
|
|
171
|
+
`⌛`,
|
|
172
|
+
`timeline`,
|
|
173
|
+
tl.key,
|
|
174
|
+
`got a selector_update "${currentSelectorKey}" with`,
|
|
150
175
|
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key),
|
|
151
176
|
)
|
|
152
177
|
|
|
@@ -160,7 +185,10 @@ export const addAtomToTimeline = (
|
|
|
160
185
|
...update,
|
|
161
186
|
})
|
|
162
187
|
store.logger.info(
|
|
163
|
-
|
|
188
|
+
`⌛`,
|
|
189
|
+
`timeline`,
|
|
190
|
+
tl.key,
|
|
191
|
+
`set selector_update "${currentSelectorKey}" to`,
|
|
164
192
|
latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.key),
|
|
165
193
|
)
|
|
166
194
|
}
|
|
@@ -193,7 +221,10 @@ export const addAtomToTimeline = (
|
|
|
193
221
|
}
|
|
194
222
|
const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true
|
|
195
223
|
store.logger.info(
|
|
196
|
-
|
|
224
|
+
`⌛`,
|
|
225
|
+
`timeline`,
|
|
226
|
+
tl.key,
|
|
227
|
+
`got an atom_update to "${atom.key}"`,
|
|
197
228
|
)
|
|
198
229
|
if (willCapture) {
|
|
199
230
|
tl.history.push(atomUpdate)
|