atom.io 0.38.2 → 0.39.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 (91) hide show
  1. package/dist/data/index.js.map +1 -1
  2. package/dist/eslint-plugin/index.js +2 -1
  3. package/dist/eslint-plugin/index.js.map +1 -1
  4. package/dist/internal/index.d.ts +128 -85
  5. package/dist/internal/index.d.ts.map +1 -1
  6. package/dist/internal/index.js +429 -286
  7. package/dist/internal/index.js.map +1 -1
  8. package/dist/introspection/index.d.ts.map +1 -1
  9. package/dist/introspection/index.js.map +1 -1
  10. package/dist/json/index.d.ts.map +1 -1
  11. package/dist/json/index.js.map +1 -1
  12. package/dist/main/index.d.ts +45 -35
  13. package/dist/main/index.d.ts.map +1 -1
  14. package/dist/main/index.js.map +1 -1
  15. package/dist/react/index.d.ts.map +1 -1
  16. package/dist/react/index.js +43 -2
  17. package/dist/react/index.js.map +1 -1
  18. package/dist/react-devtools/index.d.ts.map +1 -1
  19. package/dist/react-devtools/index.js +4 -5
  20. package/dist/react-devtools/index.js.map +1 -1
  21. package/dist/realtime/index.d.ts.map +1 -1
  22. package/dist/realtime/index.js.map +1 -1
  23. package/dist/realtime-client/index.js +5 -5
  24. package/dist/realtime-client/index.js.map +1 -1
  25. package/dist/realtime-react/index.js.map +1 -1
  26. package/dist/realtime-server/index.d.ts.map +1 -1
  27. package/dist/realtime-server/index.js +4 -4
  28. package/dist/realtime-server/index.js.map +1 -1
  29. package/dist/realtime-testing/index.d.ts.map +1 -1
  30. package/dist/realtime-testing/index.js.map +1 -1
  31. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  32. package/dist/transceivers/set-rtx/index.js.map +1 -1
  33. package/dist/web/index.js.map +1 -1
  34. package/package.json +10 -11
  35. package/src/internal/atom/create-regular-atom.ts +2 -6
  36. package/src/internal/caching.ts +2 -4
  37. package/src/internal/{ingest-updates → events}/ingest-atom-update.ts +4 -5
  38. package/src/internal/{ingest-updates → events}/ingest-creation-disposal.ts +37 -37
  39. package/src/internal/{ingest-updates → events}/ingest-selector-update.ts +5 -5
  40. package/src/internal/events/ingest-transaction-update.ts +45 -0
  41. package/src/internal/families/create-readonly-held-selector-family.ts +1 -1
  42. package/src/internal/families/create-readonly-pure-selector-family.ts +1 -1
  43. package/src/internal/families/create-regular-atom-family.ts +4 -3
  44. package/src/internal/families/create-writable-held-selector-family.ts +1 -1
  45. package/src/internal/families/create-writable-pure-selector-family.ts +1 -1
  46. package/src/internal/families/find-in-store.ts +2 -2
  47. package/src/internal/families/get-family-of-token.ts +1 -0
  48. package/src/internal/families/index.ts +0 -1
  49. package/src/internal/families/mint-in-store.ts +30 -64
  50. package/src/internal/get-state/get-from-store.ts +2 -3
  51. package/src/internal/get-state/read-or-compute-value.ts +6 -15
  52. package/src/internal/get-state/reduce-reference.ts +52 -11
  53. package/src/internal/index.ts +2 -2
  54. package/src/internal/is-fn.ts +9 -0
  55. package/src/internal/junction.ts +177 -133
  56. package/src/internal/mutable/create-mutable-atom-family.ts +1 -1
  57. package/src/internal/overlays/index.ts +3 -0
  58. package/src/internal/overlays/map-overlay.ts +86 -0
  59. package/src/internal/{lazy-map.ts → overlays/relations-overlay.ts} +6 -6
  60. package/src/internal/overlays/set-overlay.ts +55 -0
  61. package/src/internal/selector/create-readonly-held-selector.ts +8 -11
  62. package/src/internal/selector/create-readonly-pure-selector.ts +8 -10
  63. package/src/internal/selector/create-writable-held-selector.ts +6 -6
  64. package/src/internal/selector/create-writable-pure-selector.ts +2 -2
  65. package/src/internal/selector/register-selector.ts +3 -4
  66. package/src/internal/set-state/become.ts +11 -6
  67. package/src/internal/set-state/dispatch-state-update.ts +47 -12
  68. package/src/internal/set-state/operate-on-store.ts +10 -8
  69. package/src/internal/set-state/reset-atom-or-selector.ts +7 -7
  70. package/src/internal/set-state/set-atom-or-selector.ts +3 -2
  71. package/src/internal/set-state/set-atom.ts +5 -4
  72. package/src/internal/set-state/set-selector.ts +9 -8
  73. package/src/internal/store/withdraw.ts +4 -4
  74. package/src/internal/timeline/time-travel.ts +11 -11
  75. package/src/internal/transaction/apply-transaction.ts +5 -5
  76. package/src/internal/transaction/build-transaction.ts +17 -26
  77. package/src/internal/transaction/create-transaction.ts +1 -1
  78. package/src/internal/transaction/is-root-store.ts +2 -2
  79. package/src/main/events.ts +14 -3
  80. package/src/main/logger.ts +43 -32
  81. package/src/react-devtools/json-editor/editors-by-type/array-editor.tsx +1 -1
  82. package/src/react-devtools/json-editor/editors-by-type/object-editor.tsx +2 -3
  83. package/src/react-devtools/json-editor/editors-by-type/utilities/array-elements.ts +1 -1
  84. package/src/react-devtools/json-editor/editors-by-type/utilities/object-properties.ts +1 -1
  85. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +5 -5
  86. package/src/realtime-server/continuity/subscribe-to-continuity-perpectives.ts +4 -4
  87. package/dist/use-o-DXPncKmZ.js +0 -47
  88. package/dist/use-o-DXPncKmZ.js.map +0 -1
  89. package/src/internal/families/init-family-member.ts +0 -33
  90. package/src/internal/ingest-updates/ingest-transaction-update.ts +0 -47
  91. /package/src/internal/{ingest-updates → events}/index.ts +0 -0
@@ -9,45 +9,46 @@ import type {
9
9
  import { parseJson, stringifyJson } from "atom.io/json"
10
10
 
11
11
  import { disposeFromStore } from "../families"
12
- import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
12
+ import { getFromStore } from "../get-state"
13
13
  import {
14
14
  allocateIntoStore,
15
15
  claimWithinStore,
16
16
  deallocateFromStore,
17
17
  } from "../molecule"
18
+ import { setIntoStore } from "../set-state"
18
19
  import type { Store } from "../store"
19
20
 
20
21
  export function ingestCreationEvent(
21
- update: StateCreationEvent<any>,
22
- applying: `newValue` | `oldValue`,
23
22
  store: Store,
23
+ event: StateCreationEvent<any>,
24
+ applying: `newValue` | `oldValue`,
24
25
  ): void {
25
26
  switch (applying) {
26
27
  case `newValue`: {
27
- createInStore(update, store)
28
+ createInStore(store, event)
28
29
  break
29
30
  }
30
31
  case `oldValue`: {
31
- disposeFromStore(store, update.token)
32
+ disposeFromStore(store, event.token)
32
33
  break
33
34
  }
34
35
  }
35
36
  }
36
37
 
37
38
  export function ingestDisposalEvent(
38
- update: StateDisposalEvent<ReadableToken<any>>,
39
- applying: `newValue` | `oldValue`,
40
39
  store: Store,
40
+ event: StateDisposalEvent<ReadableToken<any>>,
41
+ applying: `newValue` | `oldValue`,
41
42
  ): void {
42
43
  switch (applying) {
43
44
  case `newValue`: {
44
- disposeFromStore(store, update.token)
45
+ disposeFromStore(store, event.token)
45
46
  break
46
47
  }
47
48
  case `oldValue`: {
48
- createInStore(update, store)
49
- if (update.subType === `atom`) {
50
- store.valueMap.set(update.token.key, update.value)
49
+ createInStore(store, event)
50
+ if (event.subType === `atom`) {
51
+ store.valueMap.set(event.token.key, event.value)
51
52
  }
52
53
  break
53
54
  }
@@ -55,52 +56,51 @@ export function ingestDisposalEvent(
55
56
  }
56
57
 
57
58
  function createInStore(
58
- update: StateCreationEvent<any> | StateDisposalEvent<any>,
59
59
  store: Store,
60
+ event: StateCreationEvent<any> | StateDisposalEvent<any>,
60
61
  ): void {
61
- const { family: familyMeta } = update.token
62
- if (familyMeta) {
63
- const family = store.families.get(familyMeta.key)
64
- if (family) {
65
- mintInStore(store, family, parseJson(familyMeta.subKey), MUST_CREATE)
66
- }
62
+ const { token } = event
63
+ if (event.subType === `writable` && event.value) {
64
+ setIntoStore(store, token, event.value)
65
+ } else {
66
+ getFromStore(store, token)
67
67
  }
68
68
  }
69
69
 
70
70
  export function ingestMoleculeCreationEvent(
71
- update: MoleculeCreationEvent,
72
- applying: `newValue` | `oldValue`,
73
71
  store: Store,
72
+ event: MoleculeCreationEvent,
73
+ applying: `newValue` | `oldValue`,
74
74
  ): void {
75
75
  switch (applying) {
76
76
  case `newValue`:
77
- allocateIntoStore<any, any, any>(store, update.provenance, update.key)
77
+ allocateIntoStore<any, any, any>(store, event.provenance, event.key)
78
78
  break
79
79
 
80
80
  case `oldValue`:
81
- deallocateFromStore<any, any>(store, update.key)
81
+ deallocateFromStore<any, any>(store, event.key)
82
82
  break
83
83
  }
84
84
  }
85
85
  export function ingestMoleculeDisposalEvent(
86
- update: MoleculeDisposalEvent,
87
- applying: `newValue` | `oldValue`,
88
86
  store: Store,
87
+ event: MoleculeDisposalEvent,
88
+ applying: `newValue` | `oldValue`,
89
89
  ): void {
90
90
  switch (applying) {
91
91
  case `newValue`:
92
- deallocateFromStore<any, any>(store, update.key)
92
+ deallocateFromStore<any, any>(store, event.key)
93
93
  break
94
94
 
95
95
  case `oldValue`:
96
96
  {
97
- const provenanceJson = update.provenance.map(parseJson)
98
- allocateIntoStore<any, any, any>(store, provenanceJson, update.key)
99
- for (const [familyKey, value] of update.values) {
97
+ const provenanceJson = event.provenance.map(parseJson)
98
+ allocateIntoStore<any, any, any>(store, provenanceJson, event.key)
99
+ for (const [familyKey, value] of event.values) {
100
100
  const family = store.families.get(familyKey)
101
101
  if (family) {
102
- mintInStore(store, family, update.key, MUST_CREATE)
103
- const memberKey = `${familyKey}(${stringifyJson(update.key)})`
102
+ getFromStore(store, family, event.key)
103
+ const memberKey = `${familyKey}(${stringifyJson(event.key)})`
104
104
  store.valueMap.set(memberKey, value)
105
105
  }
106
106
  }
@@ -109,19 +109,19 @@ export function ingestMoleculeDisposalEvent(
109
109
  }
110
110
  }
111
111
  export function ingestMoleculeTransferEvent(
112
- update: MoleculeTransferEvent,
113
- applying: `newValue` | `oldValue`,
114
112
  store: Store,
113
+ event: MoleculeTransferEvent,
114
+ applying: `newValue` | `oldValue`,
115
115
  ): void {
116
116
  switch (applying) {
117
117
  case `newValue`:
118
118
  {
119
- for (const newOwner of update.to) {
119
+ for (const newOwner of event.to) {
120
120
  claimWithinStore<any, any, any>(
121
121
  store,
122
122
  newOwner,
123
- update.key,
124
- update.exclusive ? `exclusive` : undefined,
123
+ event.key,
124
+ event.exclusive ? `exclusive` : undefined,
125
125
  )
126
126
  }
127
127
  }
@@ -129,11 +129,11 @@ export function ingestMoleculeTransferEvent(
129
129
  case `oldValue`:
130
130
  {
131
131
  let exclusivity: `exclusive` | undefined = `exclusive`
132
- for (const previousOwner of update.from) {
132
+ for (const previousOwner of event.from) {
133
133
  claimWithinStore<any, any, any>(
134
134
  store,
135
135
  previousOwner,
136
- update.key,
136
+ event.key,
137
137
  exclusivity,
138
138
  )
139
139
  exclusivity = undefined
@@ -6,12 +6,12 @@ import type {
6
6
  } from "atom.io"
7
7
 
8
8
  import type { Store } from "../store"
9
- import { ingestAtomUpdate } from "./ingest-atom-update"
9
+ import { ingestAtomUpdateEvent } from "./ingest-atom-update"
10
10
 
11
- export function ingestSelectorUpdate(
12
- applying: `newValue` | `oldValue`,
13
- selectorUpdate: TimelineSelectorUpdateEvent<any>,
11
+ export function ingestSelectorUpdateEvent(
14
12
  store: Store,
13
+ selectorUpdate: TimelineSelectorUpdateEvent<any>,
14
+ applying: `newValue` | `oldValue`,
15
15
  ): void {
16
16
  let updates: AtomUpdateEvent<AtomOnly<TimelineManageable>>[]
17
17
  if (applying === `newValue`) {
@@ -20,6 +20,6 @@ export function ingestSelectorUpdate(
20
20
  updates = selectorUpdate.atomUpdates.toReversed()
21
21
  }
22
22
  for (const atomUpdate of updates) {
23
- ingestAtomUpdate(applying, atomUpdate, store)
23
+ ingestAtomUpdateEvent(store, atomUpdate, applying)
24
24
  }
25
25
  }
@@ -0,0 +1,45 @@
1
+ import type { TransactionOutcomeEvent } from "atom.io"
2
+
3
+ import type { Store } from "../store"
4
+ import { ingestAtomUpdateEvent } from "./ingest-atom-update"
5
+ import {
6
+ ingestCreationEvent,
7
+ ingestDisposalEvent,
8
+ ingestMoleculeCreationEvent,
9
+ ingestMoleculeDisposalEvent,
10
+ ingestMoleculeTransferEvent,
11
+ } from "./ingest-creation-disposal"
12
+
13
+ export function ingestTransactionOutcomeEvent(
14
+ store: Store,
15
+ event: TransactionOutcomeEvent<any>,
16
+ applying: `newValue` | `oldValue`,
17
+ ): void {
18
+ const subEvents =
19
+ applying === `newValue` ? event.subEvents : [...event.subEvents].reverse()
20
+ for (const subEvent of subEvents) {
21
+ switch (subEvent.type) {
22
+ case `atom_update`:
23
+ ingestAtomUpdateEvent(store, subEvent, applying)
24
+ break
25
+ case `state_creation`:
26
+ ingestCreationEvent(store, subEvent, applying)
27
+ break
28
+ case `state_disposal`:
29
+ ingestDisposalEvent(store, subEvent, applying)
30
+ break
31
+ case `molecule_creation`:
32
+ ingestMoleculeCreationEvent(store, subEvent, applying)
33
+ break
34
+ case `molecule_disposal`:
35
+ ingestMoleculeDisposalEvent(store, subEvent, applying)
36
+ break
37
+ case `molecule_transfer`:
38
+ ingestMoleculeTransferEvent(store, subEvent, applying)
39
+ break
40
+ case `transaction_outcome`:
41
+ ingestTransactionOutcomeEvent(store, subEvent, applying)
42
+ break
43
+ }
44
+ }
45
+ }
@@ -61,7 +61,7 @@ export function createReadonlyHeldSelectorFamily<
61
61
  family,
62
62
  )
63
63
 
64
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
64
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
65
65
  return token
66
66
  }
67
67
 
@@ -64,7 +64,7 @@ export function createReadonlyPureSelectorFamily<T, K extends Canonical>(
64
64
  family,
65
65
  )
66
66
 
67
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
67
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
68
68
  return token
69
69
  }
70
70
 
@@ -12,6 +12,7 @@ import { stringifyJson } from "atom.io/json"
12
12
 
13
13
  import type { RegularAtomFamily } from ".."
14
14
  import { createRegularAtom } from "../atom"
15
+ import { isFn } from "../is-fn"
15
16
  import { newest } from "../lineage"
16
17
  import type { Store } from "../store"
17
18
  import { Subject } from "../subject"
@@ -47,7 +48,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
47
48
  const def = options.default
48
49
  const individualOptions: RegularAtomOptions<T> = {
49
50
  key: fullKey,
50
- default: def instanceof Function ? () => def(key) : def,
51
+ default: isFn(def) ? () => def(key) : def,
51
52
  }
52
53
  if (options.effects) {
53
54
  individualOptions.effects = options.effects(key)
@@ -55,7 +56,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
55
56
 
56
57
  const token = createRegularAtom(target, individualOptions, family)
57
58
 
58
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
59
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
59
60
  return token
60
61
  }
61
62
 
@@ -67,7 +68,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
67
68
  }) satisfies RegularAtomFamily<T, K>
68
69
 
69
70
  store.families.set(options.key, atomFamily)
70
- if (options.default instanceof Function === false) {
71
+ if (isFn(options.default) === false) {
71
72
  store.defaults.set(options.key, options.default)
72
73
  }
73
74
  return familyToken
@@ -61,7 +61,7 @@ export function createWritableHeldSelectorFamily<
61
61
  family,
62
62
  )
63
63
 
64
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
64
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
65
65
  return token
66
66
  }
67
67
 
@@ -64,7 +64,7 @@ export function createWritablePureSelectorFamily<T, K extends Canonical>(
64
64
  family,
65
65
  )
66
66
 
67
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
67
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
68
68
  return token
69
69
  }
70
70
 
@@ -85,11 +85,11 @@ export function findInStore(
85
85
  familyToken: ReadableFamilyToken<any, any>,
86
86
  key: Canonical,
87
87
  ): ReadableToken<any> {
88
- withdraw(store, familyToken)
88
+ const family = withdraw(store, familyToken)
89
89
  const existingStateToken = seekInStore(store, familyToken, key)
90
90
  if (existingStateToken) {
91
91
  return existingStateToken
92
92
  }
93
- const newStateToken = mintInStore(store, familyToken, key)
93
+ const newStateToken = mintInStore(store, family, key)
94
94
  return newStateToken
95
95
  }
@@ -43,6 +43,7 @@ export function getFamilyOfToken<T, K extends Canonical>(
43
43
  store: Store,
44
44
  token: WritableToken<T, K>,
45
45
  ): WritableFamily<T, K>
46
+
46
47
  export function getFamilyOfToken<T, K extends Canonical>(
47
48
  store: Store,
48
49
  token: ReadableToken<T, K>,
@@ -5,5 +5,4 @@ export * from "./create-selector-family"
5
5
  export * from "./create-writable-pure-selector-family"
6
6
  export * from "./dispose-from-store"
7
7
  export * from "./find-in-store"
8
- export * from "./init-family-member"
9
8
  export * from "./seek-in-store"
@@ -1,98 +1,64 @@
1
- import type {
2
- ReadableFamilyToken,
3
- ReadableToken,
4
- WritableFamilyToken,
5
- WritableToken,
6
- } from "atom.io"
1
+ import type { ReadableToken, WritableToken } from "atom.io"
7
2
  import type { Canonical } from "atom.io/json"
8
3
  import { stringifyJson } from "atom.io/json"
9
4
 
10
- import { newest } from "../lineage"
5
+ import type { ReadableFamily } from ".."
11
6
  import type { Store } from "../store"
12
7
  import { COUNTERFEIT, mint } from "../store"
13
- import { isChildStore, isRootStore } from "../transaction"
14
- import { initFamilyMemberInStore } from "./init-family-member"
15
8
 
16
- export const MUST_CREATE: unique symbol = Symbol(`MUST_NOT_EXIST`)
9
+ export const MUST_CREATE: unique symbol = Symbol(`MUST_CREATE`)
17
10
 
18
11
  export function mintInStore<T, K extends Canonical, Key extends K>(
19
12
  store: Store,
20
- familyToken: WritableFamilyToken<T, K>,
13
+ family: ReadableFamily<T, K>,
21
14
  key: Key,
22
- init?: typeof MUST_CREATE,
15
+ mustCreate?: typeof MUST_CREATE,
23
16
  ): WritableToken<T, K>
24
17
  export function mintInStore<T, K extends Canonical, Key extends K>(
25
18
  store: Store,
26
- familyToken: ReadableFamilyToken<T, K>,
19
+ family: ReadableFamily<T, K>,
27
20
  key: Key,
28
- init?: typeof MUST_CREATE,
21
+ mustCreate?: typeof MUST_CREATE,
29
22
  ): ReadableToken<T, K>
30
23
  export function mintInStore<T, K extends Canonical, Key extends K>(
31
24
  store: Store,
32
- familyToken: ReadableFamilyToken<T, K>,
25
+ family: ReadableFamily<T, K>,
33
26
  key: Key,
34
- shouldCreate?: typeof MUST_CREATE,
27
+ mustCreate?: typeof MUST_CREATE,
35
28
  ): 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
-
48
29
  const stringKey = stringifyJson(key)
49
30
  const molecule = store.molecules.get(stringKey)
50
- if (!molecule && store.config.lifespan === `immortal`) {
51
- const fakeToken = mint(familyToken, key, COUNTERFEIT)
31
+
32
+ const cannotCreate = !molecule && store.config.lifespan === `immortal`
33
+
34
+ if (cannotCreate) {
52
35
  store.logger.warn(
53
36
  `💣`,
54
37
  `key`,
55
38
  stringKey,
56
39
  `was used to mint a counterfeit token for`,
57
- familyToken.type,
58
- `"${familyToken.key}"`,
40
+ family.type,
41
+ `"${family.key}"`,
59
42
  )
60
- return fakeToken
43
+ return mint(family, key, COUNTERFEIT)
61
44
  }
62
45
 
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
- })
89
- }
90
- }
46
+ let token: ReadableToken<T, K>
47
+ if (mustCreate === MUST_CREATE) {
48
+ store.logger.info(
49
+ `👪`,
50
+ family.type,
51
+ family.key,
52
+ `adds member`,
53
+ typeof key === `string` ? `\`${key}\`` : key,
54
+ )
55
+ token = family(key)
91
56
  if (molecule) {
92
- target.moleculeData.set(stringKey, familyToken.key)
57
+ store.moleculeData.set(stringKey, family.key)
93
58
  }
94
59
  } else {
95
- stateToken = mint(familyToken, key)
60
+ token = mint(family, key)
96
61
  }
97
- return stateToken
62
+
63
+ return token
98
64
  }
@@ -20,10 +20,9 @@ export function getFromStore(
20
20
  | [token: ReadableFamilyToken<any, any>, key: Canonical]
21
21
  | [token: ReadableToken<any>]
22
22
  ): any {
23
- const { token, familyToken, subKey } = reduceReference(store, ...params)
23
+ const { token, family, subKey } = reduceReference(store, ...params)
24
24
 
25
- if (`counterfeit` in token && familyToken && subKey) {
26
- const family = withdraw(store, familyToken)
25
+ if (`counterfeit` in token && family && subKey) {
27
26
  return getFallback(store, token, family, subKey)
28
27
  }
29
28
  const state = withdraw(store, token)
@@ -2,6 +2,7 @@ import type { ViewOf } from "atom.io"
2
2
 
3
3
  import type { ReadableState } from ".."
4
4
  import { readFromCache, writeToCache } from "../caching"
5
+ import { isFn } from "../is-fn"
5
6
  import type { Store } from "../store"
6
7
 
7
8
  export function readOrComputeValue<T>(
@@ -22,6 +23,7 @@ export function readOrComputeValue<T>(
22
23
  if (target.valueMap.has(state.key)) {
23
24
  return readFromCache(target, state, mut)
24
25
  }
26
+ target.logger.info(`❔`, state.type, state.key, `value not found in cache`)
25
27
  const { key } = state
26
28
  switch (state.type) {
27
29
  case `readonly_held_selector`:
@@ -32,31 +34,20 @@ export function readOrComputeValue<T>(
32
34
  return state.getFrom(target)
33
35
  case `atom`: {
34
36
  let def: T
35
- if (state.default instanceof Function) {
37
+ if (isFn(state.default)) {
36
38
  def = state.default()
39
+ target.logger.info(`✨`, state.type, key, `computed default`, def)
37
40
  } else {
38
41
  def = state.default
42
+ target.logger.info(`✨`, state.type, key, `using static default`, def)
39
43
  }
40
44
  const cachedValue = writeToCache(target, state, def)
41
- target.logger.info(
42
- `💁`,
43
- `atom`,
44
- state.key,
45
- `could not find cached value; using default`,
46
- def,
47
- )
48
45
  return cachedValue
49
46
  }
50
47
  case `mutable_atom`: {
51
48
  const instance = new state.class()
49
+ target.logger.info(`✨`, state.type, key, `created new instance`, instance)
52
50
  const cachedValue = writeToCache(target, state, instance)
53
- target.logger.info(
54
- `💁`,
55
- `mutable_atom`,
56
- state.key,
57
- `could not find cached value; using default`,
58
- instance,
59
- )
60
51
  return cachedValue
61
52
  }
62
53
  }
@@ -1,6 +1,12 @@
1
- import type { ReadableFamilyToken, ReadableToken } from "atom.io"
1
+ import type {
2
+ ReadableFamilyToken,
3
+ ReadableToken,
4
+ StateCreationEvent,
5
+ } from "atom.io"
2
6
  import { type Canonical, parseJson } from "atom.io/json"
3
7
 
8
+ import type { ReadableFamily, Subject } from ".."
9
+ import { isChildStore, isRootStore, newest } from ".."
4
10
  import { seekInStore } from "../families"
5
11
  import { getFamilyOfToken } from "../families/get-family-of-token"
6
12
  import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
@@ -13,27 +19,27 @@ export function reduceReference<T, K extends Canonical>(
13
19
  | [token: ReadableFamilyToken<T, K>, key: K]
14
20
  | [token: ReadableToken<T>]
15
21
  ): {
16
- token: ReadableToken<T>
17
- familyToken: ReadableFamilyToken<T, K> | undefined
22
+ token: ReadableToken<T, K>
23
+ family: ReadableFamily<T, K> | undefined
18
24
  subKey: K | undefined
19
25
  isNew: boolean
20
26
  } {
21
27
  let existingToken: ReadableToken<T> | undefined
22
28
  let brandNewToken: ReadableToken<T> | undefined
23
- let familyToken: ReadableFamilyToken<T, K> | undefined
29
+ let family: ReadableFamily<T, K> | undefined
24
30
  let subKey: K | undefined
25
31
  let token: ReadableToken<T, K>
26
32
  if (params.length === 1) {
27
33
  token = params[0]
28
34
  if (`family` in token) {
29
- familyToken = getFamilyOfToken(store, token)
30
- withdraw(store, familyToken)
35
+ const familyToken = getFamilyOfToken(store, token)
36
+ family = withdraw(store, familyToken) as ReadableFamily<T, K>
31
37
  subKey = parseJson(token.family.subKey)
32
38
  existingToken = seekInStore(store, familyToken, subKey)
33
39
  if (`counterfeit` in token) {
34
40
  return {
35
41
  token,
36
- familyToken,
42
+ family,
37
43
  subKey,
38
44
  isNew: false,
39
45
  }
@@ -46,20 +52,55 @@ export function reduceReference<T, K extends Canonical>(
46
52
  }
47
53
  }
48
54
  } else {
49
- familyToken = params[0]
55
+ family = withdraw(store, params[0])
50
56
  subKey = params[1]
51
- existingToken = seekInStore(store, familyToken, subKey)
57
+ existingToken = seekInStore(store, family, subKey)
52
58
  if (!existingToken) {
53
- brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE)
59
+ brandNewToken = mintInStore(store, family, subKey, MUST_CREATE)
54
60
  token = brandNewToken
55
61
  } else {
56
62
  token = existingToken
57
63
  }
58
64
  }
59
65
 
66
+ const isCounterfeit = `counterfeit` in token
67
+ const isNewlyCreated = Boolean(brandNewToken) && isCounterfeit === false
68
+ if (isNewlyCreated && family) {
69
+ const stateCreationEvent: StateCreationEvent<ReadableToken<T>> = {
70
+ type: `state_creation`,
71
+ subType: `readable`,
72
+ token,
73
+ timestamp: Date.now(),
74
+ }
75
+ const familySubject = family.subject as Subject<StateCreationEvent<any>>
76
+ familySubject.next(stateCreationEvent)
77
+ const target = newest(store)
78
+ if (token.family) {
79
+ if (isRootStore(target)) {
80
+ switch (token.type) {
81
+ case `atom`:
82
+ case `mutable_atom`:
83
+ store.on.atomCreation.next(token)
84
+ break
85
+ case `writable_pure_selector`:
86
+ case `readonly_pure_selector`:
87
+ case `writable_held_selector`:
88
+ case `readonly_held_selector`:
89
+ store.on.selectorCreation.next(token)
90
+ break
91
+ }
92
+ } else if (
93
+ isChildStore(target) &&
94
+ target.on.transactionApplying.state === null
95
+ ) {
96
+ target.transactionMeta.update.subEvents.push(stateCreationEvent)
97
+ }
98
+ }
99
+ }
100
+
60
101
  return {
61
102
  token,
62
- familyToken,
103
+ family,
63
104
  subKey,
64
105
  isNew: Boolean(brandNewToken),
65
106
  }
@@ -29,22 +29,22 @@ export * from "./arbitrary"
29
29
  export * from "./atom"
30
30
  export * from "./caching"
31
31
  export * from "./capitalize"
32
+ export * from "./events"
32
33
  export * from "./families"
33
34
  export * from "./future"
34
35
  export * from "./get-environment-data"
35
36
  export * from "./get-state"
36
37
  export * from "./get-trace"
37
- export * from "./ingest-updates"
38
38
  export * from "./install-into-store"
39
39
  export * from "./join"
40
40
  export * from "./junction"
41
41
  export * from "./keys"
42
- export * from "./lazy-map"
43
42
  export * from "./lineage"
44
43
  export * from "./molecule"
45
44
  export * from "./mutable"
46
45
  export * from "./not-found-error"
47
46
  export * from "./operation"
47
+ export * from "./overlays"
48
48
  export * from "./reserved-keys"
49
49
  export * from "./selector"
50
50
  export * from "./set-state"