atom.io 0.9.10 → 0.10.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.
Files changed (55) hide show
  1. package/dist/index.d.mts +11 -4
  2. package/dist/index.d.ts +11 -4
  3. package/dist/index.js +36 -56
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +34 -55
  6. package/dist/index.mjs.map +1 -1
  7. package/internal/dist/index.d.mts +30 -19
  8. package/internal/dist/index.d.ts +30 -19
  9. package/internal/dist/index.js +158 -186
  10. package/internal/dist/index.js.map +1 -1
  11. package/internal/dist/index.mjs +159 -187
  12. package/internal/dist/index.mjs.map +1 -1
  13. package/internal/src/atom/create-atom.ts +5 -5
  14. package/internal/src/atom/delete-atom.ts +9 -2
  15. package/internal/src/caching.ts +5 -5
  16. package/internal/src/get-state-internal.ts +4 -4
  17. package/internal/src/mutable/create-mutable-atom.ts +2 -2
  18. package/internal/src/mutable/tracker.ts +1 -1
  19. package/internal/src/operation.ts +7 -7
  20. package/internal/src/selector/create-read-write-selector.ts +2 -8
  21. package/internal/src/selector/create-readonly-selector.ts +1 -1
  22. package/internal/src/selector/create-selector.ts +5 -3
  23. package/internal/src/selector/register-selector.ts +4 -11
  24. package/internal/src/selector/update-selector-atoms.ts +14 -14
  25. package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
  26. package/internal/src/set-state/copy-mutable-in-transaction.ts +1 -1
  27. package/internal/src/set-state/emit-update.ts +3 -3
  28. package/internal/src/set-state/evict-downstream.ts +5 -6
  29. package/internal/src/set-state/set-atom.ts +1 -4
  30. package/internal/src/set-state/stow-update.ts +10 -4
  31. package/internal/src/store/store.ts +27 -10
  32. package/internal/src/store/withdraw-new-family-member.ts +1 -1
  33. package/internal/src/store/withdraw.ts +1 -1
  34. package/internal/src/subscribe/recall-state.ts +2 -2
  35. package/internal/src/subscribe/subscribe-to-root-atoms.ts +3 -3
  36. package/internal/src/timeline/add-atom-to-timeline.ts +8 -8
  37. package/internal/src/timeline/time-travel-internal.ts +12 -12
  38. package/internal/src/timeline/timeline-internal.ts +2 -2
  39. package/internal/src/transaction/abort-transaction.ts +3 -3
  40. package/internal/src/transaction/apply-transaction.ts +6 -6
  41. package/internal/src/transaction/build-transaction.ts +2 -3
  42. package/internal/src/transaction/redo-transaction.ts +1 -1
  43. package/internal/src/transaction/transaction-internal.ts +2 -2
  44. package/internal/src/transaction/undo-transaction.ts +1 -1
  45. package/package.json +10 -6
  46. package/react-devtools/dist/index.d.mts +3 -3
  47. package/react-devtools/dist/index.d.ts +3 -3
  48. package/realtime-client/dist/index.js +6 -9
  49. package/realtime-client/dist/index.js.map +1 -1
  50. package/realtime-client/dist/index.mjs +6 -9
  51. package/realtime-client/dist/index.mjs.map +1 -1
  52. package/realtime-client/src/use-server-action.ts +6 -8
  53. package/src/atom.ts +3 -0
  54. package/src/logger.ts +25 -36
  55. package/src/subscribe.ts +7 -7
@@ -29,16 +29,16 @@ export function createAtom<T>(
29
29
  family?: FamilyMetadata,
30
30
  store: Store = IMPLICIT.STORE,
31
31
  ): AtomToken<T> {
32
- store.config.logger?.info?.(
32
+ store.logger.info(
33
33
  `🔨 creating atom "${options.key}" in store "${store.config.name}"`,
34
34
  )
35
35
  const core = target(store)
36
36
  const existing = core.atoms.get(options.key)
37
37
  if (existing) {
38
- store.config.logger?.error?.(
39
- `Tried to create atom "${options.key}",`,
38
+ store.logger.error(
39
+ `❓ Tried to create atom "${options.key}",`,
40
40
  `but it already exists in the store.`,
41
- `(Ignore if you are using hot module replacement.)`,
41
+ `(Ignore if you are in development using hot module replacement.)`,
42
42
  )
43
43
  return deposit(existing)
44
44
  }
@@ -47,7 +47,7 @@ export function createAtom<T>(
47
47
  ...options,
48
48
  type: `atom`,
49
49
  install: (store: Store) => {
50
- store.config.logger?.info?.(
50
+ store.logger.info(
51
51
  `đŸ› ī¸ installing atom "${options.key}" in store "${store.config.name}"`,
52
52
  )
53
53
  return `mutable` in options
@@ -1,10 +1,17 @@
1
- import type { StoreCore } from ".."
1
+ import type { AtomToken } from "~/packages/atom.io/src"
2
+ import type { Store } from ".."
2
3
  import { IMPLICIT, target } from ".."
3
4
 
4
- export function deleteAtom(key: string, core: StoreCore = IMPLICIT.STORE): void {
5
+ export function deleteAtom(
6
+ atomToken: AtomToken<unknown>,
7
+ store: Store = IMPLICIT.STORE,
8
+ ): void {
9
+ const core = target(store)
10
+ const { key } = atomToken
5
11
  core.atoms.delete(key)
6
12
  core.valueMap.delete(key)
7
13
  core.selectorAtoms.delete(key)
8
14
  core.atomsThatAreDefault.delete(key)
9
15
  core.timelineAtoms.delete(key)
16
+ store.logger.info(`đŸ”Ĩ Atom "${key}" deleted`)
10
17
  }
@@ -28,10 +28,7 @@ export const cacheValue = (
28
28
  })
29
29
  .catch((error) => {
30
30
  if (error !== `canceled`) {
31
- store.config.logger?.error(
32
- `Promised value for "${key}" rejected:`,
33
- error,
34
- )
31
+ store.logger.error(`đŸ™…â€â™‚ī¸ Promised value for "${key}" rejected:`, error)
35
32
  }
36
33
  })
37
34
  } else {
@@ -58,6 +55,9 @@ export const evictCachedValue = (
58
55
  if (currentValue instanceof Future) {
59
56
  currentValue.cancel()
60
57
  }
58
+ if (core.operation.open) {
59
+ core.operation.prev.set(key, currentValue)
60
+ }
61
61
  core.valueMap.delete(key)
62
- store.config.logger?.info(` xx evicted "${key}"`)
62
+ store.logger.info(`🗑 evicted "${key}"`)
63
63
  }
@@ -9,15 +9,15 @@ export const getState__INTERNAL = <T>(
9
9
  store: Store = IMPLICIT.STORE,
10
10
  ): T => {
11
11
  if (isValueCached(state.key, store)) {
12
- store.config.logger?.info(`>> read "${state.key}"`)
12
+ store.logger.info(`📖 reading "${state.key}"`)
13
13
  return readCachedValue(state.key, store)
14
14
  }
15
15
  if (state.type !== `atom`) {
16
- store.config.logger?.info(`-> calc "${state.key}"`)
16
+ store.logger.info(`🧮 calculating "${state.key}"`)
17
17
  return state.get()
18
18
  }
19
- store.config.logger?.error(
20
- `Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`,
19
+ store.logger.error(
20
+ `🐞 Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`,
21
21
  )
22
22
  return state.default
23
23
  }
@@ -17,7 +17,7 @@ export function createMutableAtom<
17
17
  options: MutableAtomOptions<Core, SerializableCore>,
18
18
  store: Store = IMPLICIT.STORE,
19
19
  ): MutableAtomToken<Core, SerializableCore> {
20
- store.config.logger?.info(
20
+ store.logger.info(
21
21
  `🔧 creating mutable atom "${options.key}" in store "${store.config.name}"`,
22
22
  )
23
23
  const coreState = createAtom<Core>(options, undefined, store)
@@ -26,7 +26,7 @@ export function createMutableAtom<
26
26
  subscribe(
27
27
  jsonState,
28
28
  () => {
29
- store.config.logger?.info(
29
+ store.logger.info(
30
30
  `🔍 tracker-initializer:${store?.config.name}:${
31
31
  store.transactionStatus.phase === `idle`
32
32
  ? `main`
@@ -21,7 +21,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
21
21
  store: Store = IMPLICIT.STORE,
22
22
  ): AtomToken<typeof this.Update | null> {
23
23
  const latestUpdateStateKey = `*${mutableState.key}`
24
- deleteAtom(latestUpdateStateKey, target(store))
24
+ deleteAtom({ type: `atom`, key: latestUpdateStateKey }, store)
25
25
  const familyMetaData: FamilyMetadata | undefined = mutableState.family
26
26
  ? {
27
27
  key: `*${mutableState.family.key}`,
@@ -22,7 +22,7 @@ export const openOperation = (
22
22
  ): `rejection` | undefined => {
23
23
  const core = target(store)
24
24
  if (core.operation.open) {
25
- store.config.logger?.error(
25
+ store.logger.error(
26
26
  `❌ failed to setState to "${token.key}" during a setState for "${core.operation.token.key}"`,
27
27
  )
28
28
  return `rejection`
@@ -30,11 +30,11 @@ export const openOperation = (
30
30
  core.operation = {
31
31
  open: true,
32
32
  done: new Set(),
33
- prev: new Map(store.valueMap),
33
+ prev: new Map(),
34
34
  time: Date.now(),
35
35
  token,
36
36
  }
37
- store.config.logger?.info(
37
+ store.logger.info(
38
38
  `⭕ operation start from "${token.key}" in store "${store.config.name}"${
39
39
  store.transactionStatus.phase === `idle`
40
40
  ? ``
@@ -45,14 +45,14 @@ export const openOperation = (
45
45
  export const closeOperation = (store: Store): void => {
46
46
  const core = target(store)
47
47
  core.operation = { open: false }
48
- store.config.logger?.info(`🔴 operation done`)
48
+ store.logger.info(`🔴 operation done`)
49
49
  store.subject.operationStatus.next(core.operation)
50
50
  }
51
51
 
52
52
  export const isDone = (key: string, store: Store = IMPLICIT.STORE): boolean => {
53
53
  const core = target(store)
54
54
  if (!core.operation.open) {
55
- store.config.logger?.warn(
55
+ store.logger.warn(
56
56
  `isDone called outside of an operation. This is probably a bug.`,
57
57
  )
58
58
  return true
@@ -62,8 +62,8 @@ export const isDone = (key: string, store: Store = IMPLICIT.STORE): boolean => {
62
62
  export const markDone = (key: string, store: Store = IMPLICIT.STORE): void => {
63
63
  const core = target(store)
64
64
  if (!core.operation.open) {
65
- store.config.logger?.warn(
66
- `markDone called outside of an operation. This is probably a bug.`,
65
+ store.logger.warn(
66
+ `🐞 markDone called outside of an operation. This is probably a bug.`,
67
67
  )
68
68
  return
69
69
  }
@@ -27,13 +27,7 @@ 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.config.logger?.info(
31
- ` <- "${options.key}" went (`,
32
- oldValue,
33
- `->`,
34
- newValue,
35
- `)`,
36
- )
30
+ store.logger.info(`📝 set "${options.key}" (`, oldValue, `->`, newValue, `)`)
37
31
  cacheValue(options.key, newValue, subject, store)
38
32
  markDone(options.key, store)
39
33
  if (store.transactionStatus.phase === `idle`) {
@@ -52,7 +46,7 @@ export const createReadWriteSelector = <T>(
52
46
  }
53
47
  core.selectors.set(options.key, mySelector)
54
48
  const initialValue = getSelf()
55
- store.config.logger?.info(` ✨ "${options.key}" =`, initialValue)
49
+ store.logger.info(`✨ "${options.key}" =`, initialValue)
56
50
  const token: SelectorToken<T> = {
57
51
  key: options.key,
58
52
  type: `selector`,
@@ -36,7 +36,7 @@ export const createReadonlySelector = <T>(
36
36
  }
37
37
  core.readonlySelectors.set(options.key, readonlySelector)
38
38
  const initialValue = getSelf()
39
- store.config.logger?.info(` ✨ "${options.key}" =`, initialValue)
39
+ store.logger.info(`✨ "${options.key}" =`, initialValue)
40
40
  const token: ReadonlySelectorToken<T> = {
41
41
  key: options.key,
42
42
  type: `readonly_selector`,
@@ -51,10 +51,12 @@ export function createSelector<T>(
51
51
  const existingReadonly = core.readonlySelectors.get(options.key)
52
52
 
53
53
  if (existingWritable || existingReadonly) {
54
- store.config.logger?.error?.(
55
- `Tried to create ${existingReadonly ? `readonly selector` : `selector`}`,
54
+ store.logger.error(
55
+ `❓ Tried to create ${
56
+ existingReadonly ? `readonly selector` : `selector`
57
+ }`,
56
58
  `"${options.key}", but it already exists in the store.`,
57
- `(Ignore if you are using hot module replacement.)`,
59
+ `(Ignore if you are in development using hot module replacement.)`,
58
60
  )
59
61
  }
60
62
 
@@ -25,17 +25,10 @@ export const registerSelector = (
25
25
  }
26
26
  const dependencyValue = getState__INTERNAL(dependencyState, store)
27
27
 
28
- if (alreadyRegistered) {
29
- store.config.logger?.info(
30
- ` || ${selectorKey} <- ${dependency.key} =`,
31
- dependencyValue,
32
- )
33
- } else {
34
- store.config.logger?.info(
35
- `🔌 registerSelector "${selectorKey}" <- ( "${dependency.key}" =`,
36
- dependencyValue,
37
- `)`,
38
- )
28
+ store.logger.info(
29
+ `🔌 selector "${selectorKey}" registers dependency ( "${dependency.key}" = ${dependencyValue} )`,
30
+ )
31
+ if (!alreadyRegistered) {
39
32
  core.selectorGraph = core.selectorGraph.set(
40
33
  {
41
34
  upstreamSelectorKey: dependency.key,
@@ -15,20 +15,20 @@ export const updateSelectorAtoms = (
15
15
  selectorKey,
16
16
  atomKey: dependency.key,
17
17
  })
18
- store.config.logger?.info(
19
- ` || adding root for "${selectorKey}": ${dependency.key}`,
18
+ store.logger.info(
19
+ `🔍 selector "${selectorKey}" discovers root atom "${dependency.key}"`,
20
20
  )
21
- return
22
- }
23
- const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store)
24
- store.config.logger?.info(
25
- ` || adding roots for "${selectorKey}":`,
26
- rootKeys.map((r) => r),
27
- )
28
- for (const atomKey of rootKeys) {
29
- core.selectorAtoms = core.selectorAtoms.set({
30
- selectorKey,
31
- atomKey,
32
- })
21
+ } else {
22
+ const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store)
23
+ store.logger.info(
24
+ `🔍 selector "${selectorKey}" discovers root atoms:`,
25
+ rootKeys.map((r) => r),
26
+ )
27
+ for (const atomKey of rootKeys) {
28
+ core.selectorAtoms = core.selectorAtoms.set({
29
+ selectorKey,
30
+ atomKey,
31
+ })
32
+ }
33
33
  }
34
34
  }
@@ -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.config.logger?.info(`📃 copying`, `${atom.key}`)
16
+ origin.logger.info(`📃 copying`, `${atom.key}`)
17
17
  const copiedValue = transform.fromJson(transform.toJson(originValue))
18
18
  target.valueMap.set(atom.key, copiedValue)
19
19
  new Tracker(atom, origin)
@@ -14,7 +14,7 @@ export function copyMutableIfWithinTransaction<T>(
14
14
  store.transactionStatus.phase === `applying`
15
15
  ) {
16
16
  if (`toJson` in atom && `fromJson` in atom) {
17
- store.config.logger?.info(
17
+ store.logger.info(
18
18
  `📄 copyMutableIfWithinTransaction: ${atom.key} is mutable`,
19
19
  )
20
20
  const copiedValue = copyMutableIfNeeded(
@@ -10,14 +10,14 @@ export const emitUpdate = <T>(
10
10
  store: Store,
11
11
  ): void => {
12
12
  const { key } = state
13
- const { logger } = store.config
14
- logger?.info(
13
+ const { logger } = store
14
+ logger.info(
15
15
  `đŸ“ĸ ${state.type} "${key}" went (`,
16
16
  update.oldValue,
17
17
  `->`,
18
18
  update.newValue,
19
19
  `)`,
20
20
  )
21
- logger?.info(`đŸ“ĸ notifying subscribers:`, state.subject.subscribers)
21
+ logger.info(`đŸ“ĸ notifying subscribers:`, state.subject.subscribers)
22
22
  state.subject.next(update)
23
23
  }
@@ -11,23 +11,22 @@ export const evictDownStream = <T>(
11
11
  ): void => {
12
12
  const core = target(store)
13
13
  const downstreamKeys = core.selectorAtoms.getRelatedKeys(state.key)
14
- store.config.logger?.info(
15
- ` || ${downstreamKeys?.size ?? `none`} downstream:`,
14
+ store.logger.info(
15
+ `🧹 evicting ${downstreamKeys?.size} states downstream from ${state.type} "${state.key}":`,
16
16
  downstreamKeys,
17
17
  )
18
18
  if (core.operation.open) {
19
- store.config.logger?.info(` ||`, [...core.operation.done], `already done`)
19
+ store.logger.info(`🧹`, [...core.operation.done], `already done`)
20
20
  }
21
21
  if (downstreamKeys) {
22
22
  for (const key of downstreamKeys) {
23
23
  if (isDone(key, store)) {
24
- store.config.logger?.info(` || ${key} already done`)
25
24
  continue
26
25
  }
27
26
  const state = core.selectors.get(key) ?? core.readonlySelectors.get(key)
28
27
  if (!state) {
29
- store.config.logger?.info(
30
- ` || ${key} was not found in selectors or readonlySelectors`,
28
+ store.logger.error(
29
+ `🐞 "${key}" was not found in selectors or readonlySelectors`,
31
30
  )
32
31
  return
33
32
  }
@@ -19,15 +19,12 @@ 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.config.logger?.info(`<< setting atom "${atom.key}" to`, newValue)
22
+ store.logger.info(`📝 setting atom "${atom.key}" to`, newValue)
23
23
  cacheValue(atom.key, newValue, atom.subject, store)
24
24
  if (isAtomDefault(atom.key, store)) {
25
25
  markAtomAsNotDefault(atom.key, store)
26
26
  }
27
27
  markDone(atom.key, store)
28
- store.config.logger?.info(
29
- ` || evicting caches downstream from "${atom.key}"`,
30
- )
31
28
  evictDownStream(atom, store)
32
29
  const update = { oldValue, newValue }
33
30
  if (store.transactionStatus.phase !== `building`) {
@@ -22,10 +22,10 @@ export const stowUpdate = <T>(
22
22
  store: Store,
23
23
  ): void => {
24
24
  const { key } = state
25
- const { logger } = store.config
25
+ const { logger } = store
26
26
  if (store.transactionStatus.phase !== `building`) {
27
- store.config.logger?.warn(
28
- `stowUpdate called outside of a transaction. This is probably a bug.`,
27
+ store.logger.warn(
28
+ `🐞 stowUpdate called outside of a transaction. This is probably a bug.`,
29
29
  )
30
30
  return
31
31
  }
@@ -38,5 +38,11 @@ export const stowUpdate = <T>(
38
38
  atomUpdate.family = state.family
39
39
  }
40
40
  store.transactionStatus.atomUpdates.push(atomUpdate)
41
- logger?.info(`📝 ${key} stowed (`, update.oldValue, `->`, update.newValue, `)`)
41
+ store.logger.info(
42
+ `📁 ${key} stowed (`,
43
+ update.oldValue,
44
+ `->`,
45
+ update.newValue,
46
+ `)`,
47
+ )
42
48
  }
@@ -1,3 +1,4 @@
1
+ import { AtomIOLogger } from "atom.io"
1
2
  import type {
2
3
  AtomFamily,
3
4
  AtomToken,
@@ -94,12 +95,33 @@ export class Store {
94
95
 
95
96
  public config: {
96
97
  name: string
97
- logger: Logger | null
98
- logger__INTERNAL: Logger
99
98
  } = {
100
99
  name: `IMPLICIT_STORE`,
101
- logger: { ...console, info: () => undefined },
102
- logger__INTERNAL: console,
100
+ }
101
+
102
+ public loggers: AtomIOLogger[] = [
103
+ new AtomIOLogger(
104
+ { ...console },
105
+ `warn`,
106
+ (message) => !message.includes(`👁‍🗨`),
107
+ ),
108
+ ]
109
+ public logger: Logger = {
110
+ error: (...messages: unknown[]) => {
111
+ for (const logger of this.loggers) {
112
+ logger.error(...messages)
113
+ }
114
+ },
115
+ info: (...messages: unknown[]) => {
116
+ for (const logger of this.loggers) {
117
+ logger.info(...messages)
118
+ }
119
+ },
120
+ warn: (...messages: unknown[]) => {
121
+ for (const logger of this.loggers) {
122
+ logger.warn(...messages)
123
+ }
124
+ },
103
125
  }
104
126
 
105
127
  public constructor(name: string, store: Store | null = null) {
@@ -110,14 +132,9 @@ export class Store {
110
132
  this.transactionStatus = { ...store?.transactionStatus }
111
133
  this.config = {
112
134
  ...store?.config,
113
- logger__INTERNAL: console,
114
- logger: {
115
- ...console,
116
- info: () => undefined,
117
- ...store?.config?.logger,
118
- },
119
135
  name,
120
136
  }
137
+
121
138
  for (const [, atom] of store.atoms) {
122
139
  atom.install(this)
123
140
  }
@@ -36,7 +36,7 @@ export function withdrawNewFamilyMember<T>(
36
36
  | StateToken<T>,
37
37
  store: Store,
38
38
  ): Atom<T> | ReadonlySelector<T> | Selector<T> | undefined {
39
- store.config.logger?.info(
39
+ store.logger.info(
40
40
  `đŸ‘Ē creating new family member "${token.key}" in store "${store.config.name}"`,
41
41
  )
42
42
  if (token.family) {
@@ -78,7 +78,7 @@ export function withdraw<T>(
78
78
  core.timelines.get(token.key)
79
79
 
80
80
  if (state) {
81
- store.config.logger?.info(`đŸ› ī¸ add ${token.type} "${token.key}"`)
81
+ store.logger.info(`đŸ› ī¸ add ${token.type} "${token.key}"`)
82
82
  switch (state.type) {
83
83
  case `atom`: {
84
84
  store.atoms.set(token.key, state)
@@ -10,8 +10,8 @@ export const recallState = <T>(
10
10
  ): T => {
11
11
  const core = target(store)
12
12
  if (!core.operation.open) {
13
- store.config.logger?.warn(
14
- `recall called outside of an operation. This is probably a bug.`,
13
+ store.logger.warn(
14
+ `🐞recall called outside of an operation. This is probably a bug.`,
15
15
  )
16
16
  return core.valueMap.get(state.key)
17
17
  }
@@ -21,7 +21,7 @@ export const subscribeToRootAtoms = <T>(
21
21
  return atom.subject.subscribe(
22
22
  `${state.type}:${state.key}`,
23
23
  (atomChange) => {
24
- store.config.logger?.info(
24
+ store.logger.info(
25
25
  `đŸ“ĸ selector "${state.key}" saw root "${atomKey}" go (`,
26
26
  atomChange.oldValue,
27
27
  `->`,
@@ -31,8 +31,8 @@ export const subscribeToRootAtoms = <T>(
31
31
  const oldValue = recallState(state, store)
32
32
  // ❗ this retrieves a stale cached value when applying a transaction on the server
33
33
  const newValue = getState__INTERNAL(state, store)
34
- store.config.logger?.info(
35
- ` <- "${state.key}" went (`,
34
+ store.logger.info(
35
+ `✨ "${state.key}" went (`,
36
36
  oldValue,
37
37
  `->`,
38
38
  newValue,
@@ -38,7 +38,7 @@ export const addAtomToTimeline = (
38
38
  ? store.transactionStatus.time
39
39
  : null
40
40
 
41
- store.config.logger?.info(
41
+ store.logger.info(
42
42
  `âŗ timeline "${tl.key}" saw atom "${atomToken.key}" go (`,
43
43
  update.oldValue,
44
44
  `->`,
@@ -74,8 +74,8 @@ export const addAtomToTimeline = (
74
74
  }
75
75
  if (tl.transactionKey !== currentTransactionKey) {
76
76
  if (tl.transactionKey) {
77
- store.config.logger?.error(
78
- `Timeline "${tl.key}" was unable to resolve transaction "${tl.transactionKey}. This is probably a bug.`,
77
+ store.logger.error(
78
+ `🐞 Timeline "${tl.key}" was unable to resolve transaction "${tl.transactionKey}. This is probably a bug.`,
79
79
  )
80
80
  }
81
81
  tl.transactionKey = currentTransactionKey
@@ -118,7 +118,7 @@ export const addAtomToTimeline = (
118
118
  }
119
119
  }
120
120
  tl.transactionKey = null
121
- store.config.logger?.info(
121
+ store.logger.info(
122
122
  `⌛ timeline "${tl.key}" got a transaction_update "${update.key}"`,
123
123
  )
124
124
  },
@@ -145,7 +145,7 @@ export const addAtomToTimeline = (
145
145
 
146
146
  tl.history.push(latestUpdate)
147
147
 
148
- store.config.logger?.info(
148
+ store.logger.info(
149
149
  `⌛ timeline "${tl.key}" got a selector_update "${currentSelectorKey}" with`,
150
150
  latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key),
151
151
  )
@@ -159,8 +159,8 @@ export const addAtomToTimeline = (
159
159
  type: `atom_update`,
160
160
  ...update,
161
161
  })
162
- store.config.logger?.info(
163
- ` ⌛ timeline "${tl.key}" set selector_update "${currentSelectorKey}" to`,
162
+ store.logger.info(
163
+ `⌛ timeline "${tl.key}" set selector_update "${currentSelectorKey}" to`,
164
164
  latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.key),
165
165
  )
166
166
  }
@@ -192,7 +192,7 @@ export const addAtomToTimeline = (
192
192
  atomUpdate.family = atom.family
193
193
  }
194
194
  const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true
195
- store.config.logger?.info(
195
+ store.logger.info(
196
196
  `⌛ timeline "${tl.key}" got an atom_update to "${atom.key}"`,
197
197
  )
198
198
  if (willCapture) {
@@ -8,17 +8,17 @@ export const redo__INTERNAL = (
8
8
  token: TimelineToken,
9
9
  store: Store = IMPLICIT.STORE,
10
10
  ): void => {
11
- store.config.logger?.info(`⏊ redo "${token.key}"`)
11
+ store.logger.info(`⏊ redo "${token.key}"`)
12
12
  const timelineData = store.timelines.get(token.key)
13
13
  if (!timelineData) {
14
- store.config.logger?.error(
15
- `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`,
14
+ store.logger.error(
15
+ `🐞 Failed to redo on timeline "${token.key}". This timeline has not been initialized.`,
16
16
  )
17
17
  return
18
18
  }
19
19
  if (timelineData.at === timelineData.history.length) {
20
- store.config.logger?.warn(
21
- `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`,
20
+ store.logger.warn(
21
+ `â˜ī¸ Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`,
22
22
  )
23
23
  return
24
24
  }
@@ -42,7 +42,7 @@ export const redo__INTERNAL = (
42
42
  ++timelineData.at
43
43
  timelineData.subject.next(`redo`)
44
44
  timelineData.timeTraveling = null
45
- store.config.logger?.info(
45
+ store.logger.info(
46
46
  `âšī¸ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
47
47
  )
48
48
  }
@@ -51,17 +51,17 @@ export const undo__INTERNAL = (
51
51
  token: TimelineToken,
52
52
  store: Store = IMPLICIT.STORE,
53
53
  ): void => {
54
- store.config.logger?.info(`âĒ undo "${token.key}"`)
54
+ store.logger.info(`âĒ undo "${token.key}"`)
55
55
  const timelineData = store.timelines.get(token.key)
56
56
  if (!timelineData) {
57
- store.config.logger?.error(
58
- `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`,
57
+ store.logger.error(
58
+ `🐞 Failed to undo on timeline "${token.key}". This timeline has not been initialized.`,
59
59
  )
60
60
  return
61
61
  }
62
62
  if (timelineData.at === 0) {
63
- store.config.logger?.warn(
64
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`,
63
+ store.logger.warn(
64
+ `â˜ī¸ Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`,
65
65
  )
66
66
  return
67
67
  }
@@ -85,7 +85,7 @@ export const undo__INTERNAL = (
85
85
  }
86
86
  timelineData.subject.next(`undo`)
87
87
  timelineData.timeTraveling = null
88
- store.config.logger?.info(
88
+ store.logger.info(
89
89
  `âšī¸ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
90
90
  )
91
91
  }
@@ -76,7 +76,7 @@ export function timeline__INTERNAL(
76
76
  for (const tokenOrFamily of options.atoms) {
77
77
  const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key)
78
78
  if (timelineKey) {
79
- store.config.logger?.error(
79
+ store.logger.error(
80
80
  `❌ Failed to add atom "${tokenOrFamily.key}" to timeline "${options.key}" because it belongs to timeline "${timelineKey}"`,
81
81
  )
82
82
  continue
@@ -100,7 +100,7 @@ export function timeline__INTERNAL(
100
100
  token.family.key,
101
101
  )
102
102
  if (familyTimelineKey) {
103
- store.config.logger?.error(
103
+ store.logger.error(
104
104
  `❌ Failed to add atom "${token.key}" to timeline "${options.key}" because its family "${token.family.key}" belongs to timeline "${familyTimelineKey}"`,
105
105
  )
106
106
  continue