atom.io 0.38.2 → 0.39.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.
Files changed (59) hide show
  1. package/dist/internal/index.d.ts +115 -78
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +398 -275
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/main/index.d.ts +45 -35
  6. package/dist/main/index.d.ts.map +1 -1
  7. package/dist/main/index.js.map +1 -1
  8. package/dist/realtime-client/index.js +5 -5
  9. package/dist/realtime-client/index.js.map +1 -1
  10. package/dist/realtime-server/index.js +4 -4
  11. package/dist/realtime-server/index.js.map +1 -1
  12. package/package.json +3 -4
  13. package/src/internal/atom/create-regular-atom.ts +2 -6
  14. package/src/internal/caching.ts +2 -4
  15. package/src/internal/{ingest-updates → events}/ingest-atom-update.ts +4 -5
  16. package/src/internal/{ingest-updates → events}/ingest-creation-disposal.ts +37 -37
  17. package/src/internal/{ingest-updates → events}/ingest-selector-update.ts +5 -5
  18. package/src/internal/events/ingest-transaction-update.ts +45 -0
  19. package/src/internal/families/create-readonly-held-selector-family.ts +1 -1
  20. package/src/internal/families/create-readonly-pure-selector-family.ts +1 -1
  21. package/src/internal/families/create-regular-atom-family.ts +1 -1
  22. package/src/internal/families/create-writable-held-selector-family.ts +1 -1
  23. package/src/internal/families/create-writable-pure-selector-family.ts +1 -1
  24. package/src/internal/families/find-in-store.ts +2 -2
  25. package/src/internal/families/get-family-of-token.ts +1 -0
  26. package/src/internal/families/index.ts +0 -1
  27. package/src/internal/families/mint-in-store.ts +30 -64
  28. package/src/internal/get-state/get-from-store.ts +2 -3
  29. package/src/internal/get-state/read-or-compute-value.ts +4 -14
  30. package/src/internal/get-state/reduce-reference.ts +52 -11
  31. package/src/internal/index.ts +2 -2
  32. package/src/internal/junction.ts +177 -133
  33. package/src/internal/mutable/create-mutable-atom-family.ts +1 -1
  34. package/src/internal/overlays/index.ts +3 -0
  35. package/src/internal/overlays/map-overlay.ts +86 -0
  36. package/src/internal/{lazy-map.ts → overlays/relations-overlay.ts} +6 -6
  37. package/src/internal/overlays/set-overlay.ts +55 -0
  38. package/src/internal/selector/create-readonly-held-selector.ts +8 -11
  39. package/src/internal/selector/create-readonly-pure-selector.ts +8 -10
  40. package/src/internal/selector/create-writable-held-selector.ts +6 -6
  41. package/src/internal/selector/create-writable-pure-selector.ts +2 -2
  42. package/src/internal/selector/register-selector.ts +3 -4
  43. package/src/internal/set-state/dispatch-state-update.ts +45 -11
  44. package/src/internal/set-state/operate-on-store.ts +7 -7
  45. package/src/internal/set-state/set-atom.ts +1 -1
  46. package/src/internal/set-state/set-selector.ts +1 -1
  47. package/src/internal/store/withdraw.ts +4 -4
  48. package/src/internal/timeline/time-travel.ts +11 -11
  49. package/src/internal/transaction/apply-transaction.ts +5 -5
  50. package/src/internal/transaction/build-transaction.ts +17 -26
  51. package/src/internal/transaction/create-transaction.ts +1 -1
  52. package/src/internal/transaction/is-root-store.ts +2 -2
  53. package/src/main/events.ts +14 -3
  54. package/src/main/logger.ts +43 -32
  55. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +5 -5
  56. package/src/realtime-server/continuity/subscribe-to-continuity-perpectives.ts +4 -4
  57. package/src/internal/families/init-family-member.ts +0 -33
  58. package/src/internal/ingest-updates/ingest-transaction-update.ts +0 -47
  59. /package/src/internal/{ingest-updates → events}/index.ts +0 -0
@@ -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
 
@@ -55,7 +55,7 @@ export function createRegularAtomFamily<T, K extends Canonical>(
55
55
 
56
56
  const token = createRegularAtom(target, individualOptions, family)
57
57
 
58
- subject.next({ type: `state_creation`, token, timestamp: Date.now() })
58
+ // subject.next({ type: `state_creation`, token, timestamp: Date.now() })
59
59
  return token
60
60
  }
61
61
 
@@ -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)
@@ -22,6 +22,7 @@ export function readOrComputeValue<T>(
22
22
  if (target.valueMap.has(state.key)) {
23
23
  return readFromCache(target, state, mut)
24
24
  }
25
+ target.logger.info(`❔`, state.type, state.key, `value not found in cache`)
25
26
  const { key } = state
26
27
  switch (state.type) {
27
28
  case `readonly_held_selector`:
@@ -34,29 +35,18 @@ export function readOrComputeValue<T>(
34
35
  let def: T
35
36
  if (state.default instanceof Function) {
36
37
  def = state.default()
38
+ target.logger.info(`✨`, state.type, key, `computed default`, def)
37
39
  } else {
38
40
  def = state.default
41
+ target.logger.info(`✨`, state.type, key, `using static default`, def)
39
42
  }
40
43
  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
44
  return cachedValue
49
45
  }
50
46
  case `mutable_atom`: {
51
47
  const instance = new state.class()
48
+ target.logger.info(`✨`, state.type, key, `created new instance`, instance)
52
49
  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
50
  return cachedValue
61
51
  }
62
52
  }
@@ -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"