atom.io 0.9.9 → 0.10.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 (64) 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 +52 -25
  8. package/internal/dist/index.d.ts +52 -25
  9. package/internal/dist/index.js +352 -385
  10. package/internal/dist/index.js.map +1 -1
  11. package/internal/dist/index.mjs +349 -385
  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/atom/is-default.ts +2 -2
  16. package/internal/src/caching.ts +7 -5
  17. package/internal/src/get-state-internal.ts +4 -4
  18. package/internal/src/index.ts +1 -0
  19. package/internal/src/keys.ts +30 -0
  20. package/internal/src/mutable/create-mutable-atom.ts +2 -2
  21. package/internal/src/mutable/tracker.ts +1 -1
  22. package/internal/src/operation.ts +7 -7
  23. package/internal/src/selector/create-read-write-selector.ts +2 -8
  24. package/internal/src/selector/create-readonly-selector.ts +1 -1
  25. package/internal/src/selector/create-selector.ts +5 -3
  26. package/internal/src/selector/get-selector-dependency-keys.ts +20 -0
  27. package/internal/src/selector/index.ts +1 -1
  28. package/internal/src/selector/register-selector.ts +4 -11
  29. package/internal/src/selector/trace-selector-atoms.ts +26 -26
  30. package/internal/src/selector/update-selector-atoms.ts +14 -14
  31. package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
  32. package/internal/src/set-state/copy-mutable-in-transaction.ts +1 -1
  33. package/internal/src/set-state/emit-update.ts +1 -1
  34. package/internal/src/set-state/evict-downstream.ts +5 -6
  35. package/internal/src/set-state/set-atom.ts +1 -4
  36. package/internal/src/set-state/stow-update.ts +10 -4
  37. package/internal/src/store/index.ts +0 -1
  38. package/internal/src/store/store.ts +27 -10
  39. package/internal/src/store/withdraw-new-family-member.ts +1 -1
  40. package/internal/src/store/withdraw.ts +1 -1
  41. package/internal/src/subscribe/recall-state.ts +2 -2
  42. package/internal/src/subscribe/subscribe-to-root-atoms.ts +7 -8
  43. package/internal/src/timeline/add-atom-to-timeline.ts +8 -8
  44. package/internal/src/timeline/time-travel-internal.ts +12 -12
  45. package/internal/src/timeline/timeline-internal.ts +2 -2
  46. package/internal/src/transaction/abort-transaction.ts +3 -3
  47. package/internal/src/transaction/apply-transaction.ts +6 -6
  48. package/internal/src/transaction/build-transaction.ts +2 -3
  49. package/internal/src/transaction/redo-transaction.ts +1 -1
  50. package/internal/src/transaction/transaction-internal.ts +2 -2
  51. package/internal/src/transaction/undo-transaction.ts +1 -1
  52. package/package.json +3 -3
  53. package/react-devtools/dist/index.d.mts +3 -3
  54. package/react-devtools/dist/index.d.ts +3 -3
  55. package/realtime-client/dist/index.js +6 -9
  56. package/realtime-client/dist/index.js.map +1 -1
  57. package/realtime-client/dist/index.mjs +6 -9
  58. package/realtime-client/dist/index.mjs.map +1 -1
  59. package/realtime-client/src/use-server-action.ts +6 -8
  60. package/src/atom.ts +3 -0
  61. package/src/logger.ts +25 -36
  62. package/src/subscribe.ts +7 -7
  63. package/internal/src/selector/lookup-selector-sources.ts +0 -20
  64. package/internal/src/store/lookup.ts +0 -26
@@ -2,7 +2,6 @@ import { getState__INTERNAL } from "../get-state-internal"
2
2
  import type { ReadonlySelector, Selector } from "../selector"
3
3
  import { traceAllSelectorAtoms } from "../selector"
4
4
  import type { Store } from "../store"
5
- import { withdraw } from "../store"
6
5
  import { recallState } from "./recall-state"
7
6
 
8
7
  export const subscribeToRootAtoms = <T>(
@@ -12,18 +11,18 @@ export const subscribeToRootAtoms = <T>(
12
11
  const dependencySubscriptions =
13
12
  `default` in state
14
13
  ? null
15
- : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
16
- const atom = withdraw(atomToken, store)
14
+ : traceAllSelectorAtoms(state.key, store).map((atomKey) => {
15
+ const atom = store.atoms.get(atomKey)
17
16
  if (atom === undefined) {
18
17
  throw new Error(
19
- `Atom "${atomToken.key}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`,
18
+ `Atom "${atomKey}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`,
20
19
  )
21
20
  }
22
21
  return atom.subject.subscribe(
23
22
  `${state.type}:${state.key}`,
24
23
  (atomChange) => {
25
- store.config.logger?.info(
26
- `📢 selector "${state.key}" saw root "${atomToken.key}" go (`,
24
+ store.logger.info(
25
+ `📢 selector "${state.key}" saw root "${atomKey}" go (`,
27
26
  atomChange.oldValue,
28
27
  `->`,
29
28
  atomChange.newValue,
@@ -32,8 +31,8 @@ export const subscribeToRootAtoms = <T>(
32
31
  const oldValue = recallState(state, store)
33
32
  // ❗ this retrieves a stale cached value when applying a transaction on the server
34
33
  const newValue = getState__INTERNAL(state, store)
35
- store.config.logger?.info(
36
- ` <- "${state.key}" went (`,
34
+ store.logger.info(
35
+ `✨ "${state.key}" went (`,
37
36
  oldValue,
38
37
  `->`,
39
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
@@ -2,11 +2,11 @@ import type { Store } from "../store"
2
2
 
3
3
  export const abortTransaction = (store: Store): void => {
4
4
  if (store.transactionStatus.phase === `idle`) {
5
- store.config.logger?.warn(
6
- `abortTransaction called outside of a transaction. This is probably a bug.`,
5
+ store.logger.warn(
6
+ `🐞 abortTransaction called outside of a transaction. This is probably a bug.`,
7
7
  )
8
8
  return
9
9
  }
10
10
  store.transactionStatus = { phase: `idle` }
11
- store.config.logger?.info(`🪂`, `transaction fail`)
11
+ store.logger.info(`🪂`, `transaction fail`)
12
12
  }
@@ -9,18 +9,18 @@ export const applyTransaction = <ƒ extends ƒn>(
9
9
  store: Store,
10
10
  ): void => {
11
11
  if (store.transactionStatus.phase !== `building`) {
12
- store.config.logger?.warn(
13
- `abortTransaction called outside of a transaction. This is probably a bug.`,
12
+ store.logger.warn(
13
+ `🐞 applyTransaction called outside of a transaction. This is probably a bug.`,
14
14
  )
15
15
  return
16
16
  }
17
17
  store.transactionStatus.phase = `applying`
18
18
  store.transactionStatus.output = output
19
19
  const { atomUpdates } = store.transactionStatus
20
- store.config.logger?.info(
20
+ store.logger.info(
21
21
  `🛃 applying transaction "${store.transactionStatus.key}" with ${atomUpdates.length} updates.`,
22
22
  )
23
- store.config.logger?.info(`🛃 the updates are:`, atomUpdates)
23
+ store.logger.info(`🛃 the updates are:`, atomUpdates)
24
24
  for (const { key, newValue } of atomUpdates) {
25
25
  const token: AtomToken<unknown> = { key, type: `atom` }
26
26
  if (!store.valueMap.has(token.key)) {
@@ -38,7 +38,7 @@ export const applyTransaction = <ƒ extends ƒn>(
38
38
  }
39
39
  store.atoms.set(newAtom.key, newAtom)
40
40
  store.valueMap.set(newAtom.key, newAtom.default)
41
- store.config.logger?.info(`🔧`, `add atom "${newAtom.key}"`)
41
+ store.logger.info(`🔧 add atom "${newAtom.key}"`)
42
42
  }
43
43
  }
44
44
  // if (store.transactionStatus.key === `dealCards`) debugger
@@ -60,5 +60,5 @@ export const applyTransaction = <ƒ extends ƒn>(
60
60
  params: store.transactionStatus.params as Parameters<ƒ>,
61
61
  })
62
62
  store.transactionStatus = { phase: `idle` }
63
- store.config.logger?.info(`🛬`, `transaction "${myTransaction.key}" applied`)
63
+ store.logger.info(`🛬 transaction "${myTransaction.key}" applied`)
64
64
  }
@@ -32,8 +32,7 @@ export const buildTransaction = (
32
32
  params,
33
33
  output: undefined,
34
34
  }
35
- store.config.logger?.info(
36
- `🛫`,
37
- `transaction "${key}" building in store "${store.config.name}"`,
35
+ store.logger.info(
36
+ `🛫 transaction "${key}" building in store "${store.config.name}"`,
38
37
  )
39
38
  }
@@ -8,7 +8,7 @@ export const redoTransactionUpdate = <ƒ extends ƒn>(
8
8
  update: TransactionUpdate<ƒ>,
9
9
  store: Store,
10
10
  ): void => {
11
- store.config.logger?.info(` ⏭ redo transaction "${update.key}" (redo)`)
11
+ store.logger.info(` ⏭ redo transaction "${update.key}" (redo)`)
12
12
  for (const { key, newValue } of update.atomUpdates) {
13
13
  const token: AtomToken<unknown> = { key, type: `atom` }
14
14
  const state = withdraw(token, store)
@@ -41,8 +41,8 @@ export function transaction__INTERNAL<ƒ extends ƒn>(
41
41
  return output
42
42
  } catch (thrown) {
43
43
  abortTransaction(store)
44
- store.config.logger?.error(
45
- `Transaction "${options.key}" failed in store "${store.config.name}":`,
44
+ store.logger.error(
45
+ `❗ Transaction "${options.key}" failed in store "${store.config.name}":`,
46
46
  thrown,
47
47
  )
48
48
  throw thrown
@@ -8,7 +8,7 @@ export const undoTransactionUpdate = <ƒ extends ƒn>(
8
8
  update: TransactionUpdate<ƒ>,
9
9
  store: Store,
10
10
  ): void => {
11
- store.config.logger?.info(` ⏮ undo transaction "${update.key}" (undo)`)
11
+ store.logger.info(` ⏮ undo transaction "${update.key}" (undo)`)
12
12
  for (const { key, oldValue } of update.atomUpdates) {
13
13
  const token: AtomToken<unknown> = { key, type: `atom` }
14
14
  const state = withdraw(token, store)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.9.9",
3
+ "version": "0.10.0",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -55,7 +55,7 @@
55
55
  "@types/tmp": "0.2.6",
56
56
  "@vitest/coverage-v8": "0.34.6",
57
57
  "concurrently": "8.2.2",
58
- "eslint": "8.53.0",
58
+ "eslint": "8.54.0",
59
59
  "framer-motion": "10.16.5",
60
60
  "happy-dom": "12.10.3",
61
61
  "npmlog": "7.0.1",
@@ -66,7 +66,7 @@
66
66
  "socket.io": "4.7.2",
67
67
  "socket.io-client": "4.7.2",
68
68
  "tmp": "0.2.1",
69
- "tsup": "7.3.0",
69
+ "tsup": "8.0.0",
70
70
  "typescript": "5.2.2",
71
71
  "vite": "4.5.0",
72
72
  "vite-tsconfig-paths": "4.2.1",
@@ -1,5 +1,5 @@
1
1
  import * as atom_io from 'atom.io';
2
- import { FamilyMetadata, ƒn, TransactionUpdate, MutableAtomToken, AtomToken, StateToken, TimelineUpdate, StateUpdate, AtomFamily, ReadonlySelectorFamily, SelectorFamily, ReadonlySelectorToken, SelectorToken, TransactionToken, TimelineToken, Logger } from 'atom.io';
2
+ import { FamilyMetadata, ƒn, TransactionUpdate, MutableAtomToken, AtomToken, StateToken, TimelineUpdate, StateUpdate, AtomFamily, ReadonlySelectorFamily, SelectorFamily, ReadonlySelectorToken, SelectorToken, TransactionToken, TimelineToken, AtomIOLogger, Logger } from 'atom.io';
3
3
  import { Json } from 'atom.io/json';
4
4
 
5
5
  type ClassSignature = abstract new (...args: any) => any;
@@ -232,9 +232,9 @@ declare class Store {
232
232
  transactionStatus: TransactionStatus<ƒn>;
233
233
  config: {
234
234
  name: string;
235
- logger: Logger | null;
236
- logger__INTERNAL: Logger;
237
235
  };
236
+ loggers: AtomIOLogger[];
237
+ logger: Logger;
238
238
  constructor(name: string, store?: Store | null);
239
239
  }
240
240
 
@@ -1,5 +1,5 @@
1
1
  import * as atom_io from 'atom.io';
2
- import { FamilyMetadata, ƒn, TransactionUpdate, MutableAtomToken, AtomToken, StateToken, TimelineUpdate, StateUpdate, AtomFamily, ReadonlySelectorFamily, SelectorFamily, ReadonlySelectorToken, SelectorToken, TransactionToken, TimelineToken, Logger } from 'atom.io';
2
+ import { FamilyMetadata, ƒn, TransactionUpdate, MutableAtomToken, AtomToken, StateToken, TimelineUpdate, StateUpdate, AtomFamily, ReadonlySelectorFamily, SelectorFamily, ReadonlySelectorToken, SelectorToken, TransactionToken, TimelineToken, AtomIOLogger, Logger } from 'atom.io';
3
3
  import { Json } from 'atom.io/json';
4
4
 
5
5
  type ClassSignature = abstract new (...args: any) => any;
@@ -232,9 +232,9 @@ declare class Store {
232
232
  transactionStatus: TransactionStatus<ƒn>;
233
233
  config: {
234
234
  name: string;
235
- logger: Logger | null;
236
- logger__INTERNAL: Logger;
237
235
  };
236
+ loggers: AtomIOLogger[];
237
+ logger: Logger;
238
238
  constructor(name: string, store?: Store | null);
239
239
  }
240
240
 
@@ -131,20 +131,17 @@ function synchronizeTransactionResults(token, socket, store) {
131
131
  const clientResult = JSON.stringify(clientUpdate);
132
132
  const topic = `tx:sync:${transactionId}`;
133
133
  const sync = (serverUpdate) => {
134
- var _a2, _b, _c, _d, _e;
135
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(`Transaction ${token.key} synced`);
134
+ store.logger.info(`\u267B\uFE0F Transaction "${token.key}" synced`);
136
135
  socket.off(topic, sync);
137
136
  const serverResult = JSON.stringify(serverUpdate);
138
137
  if (clientResult !== serverResult) {
139
- (_b = store.config.logger) == null ? void 0 : _b.error(
140
- `Transaction ${token.key} produced different results on client and server`
138
+ store.logger.error(
139
+ `\u2757 Transaction "${token.key}" produced different results on client and server`
141
140
  );
142
- (_c = store.config.logger) == null ? void 0 : _c.error(`Client:`, clientResult);
143
- (_d = store.config.logger) == null ? void 0 : _d.error(`Server:`, serverResult);
141
+ store.logger.error(`\u2757 Client:`, clientResult);
142
+ store.logger.error(`\u2757 Server:`, serverResult);
144
143
  } else {
145
- (_e = store.config.logger) == null ? void 0 : _e.info(
146
- `Transaction ${token.key} results match`
147
- );
144
+ store.logger.info(`\u2705 Transaction ${token.key} results match`);
148
145
  }
149
146
  };
150
147
  socket.on(topic, sync);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":"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","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.config.logger?.info(`Transaction ${token.key} synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.config.logger?.error(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.config.logger?.info(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} results match`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":"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","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.logger.info(`♻️ Transaction \"${token.key}\" synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t\t\t`❗ Transaction \"${token.key}\" produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.logger.error(`❗ Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.logger.error(`❗ Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.logger.info(`✅ Transaction ${token.key} results match`)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
@@ -109,20 +109,17 @@ function synchronizeTransactionResults(token, socket, store) {
109
109
  const clientResult = JSON.stringify(clientUpdate);
110
110
  const topic = `tx:sync:${transactionId}`;
111
111
  const sync = (serverUpdate) => {
112
- var _a2, _b, _c, _d, _e;
113
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(`Transaction ${token.key} synced`);
112
+ store.logger.info(`\u267B\uFE0F Transaction "${token.key}" synced`);
114
113
  socket.off(topic, sync);
115
114
  const serverResult = JSON.stringify(serverUpdate);
116
115
  if (clientResult !== serverResult) {
117
- (_b = store.config.logger) == null ? void 0 : _b.error(
118
- `Transaction ${token.key} produced different results on client and server`
116
+ store.logger.error(
117
+ `\u2757 Transaction "${token.key}" produced different results on client and server`
119
118
  );
120
- (_c = store.config.logger) == null ? void 0 : _c.error(`Client:`, clientResult);
121
- (_d = store.config.logger) == null ? void 0 : _d.error(`Server:`, serverResult);
119
+ store.logger.error(`\u2757 Client:`, clientResult);
120
+ store.logger.error(`\u2757 Server:`, serverResult);
122
121
  } else {
123
- (_e = store.config.logger) == null ? void 0 : _e.info(
124
- `Transaction ${token.key} results match`
125
- );
122
+ store.logger.info(`\u2705 Transaction ${token.key} results match`);
126
123
  }
127
124
  };
128
125
  socket.on(topic, sync);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":";AAAA,YAAY,YAAY;AAEjB,IAAM,sBAA6B,YAAoB;AAAA,EAC7D,KAAK;AAAA,EACL,SAAS;AACV,CAAC;AACM,IAAM,YAAmB,gBAAwB;AAAA,EACvD,KAAK;AAAA,EACL,KAAK,CAAC,EAAE,IAAI,MAAM,IAAI,mBAAmB;AAC1C,CAAC;;;ACTD,YAAYA,aAAY;AAKjB,SAAS,UACf,OACA,QACA,OACa;AACb,SAAO,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAS;AACzC,IAAO,iBAAS,OAAO,MAAM,KAAK;AAAA,EACnC,CAAC;AACD,SAAO,KAAK,OAAO,MAAM,GAAG,EAAE;AAC9B,SAAO,MAAM;AACZ,WAAO,IAAI,SAAS,MAAM,GAAG,EAAE;AAC/B,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAAA,EACjC;AACD;;;AClBA,YAAYA,aAAY;AAGxB,SAAS,iBAAiB;AAGnB,SAAS,iBACf,OACA,QACA,OACa;AACb,MAAI,EAAE,YAAY,QAAQ;AACzB,YAAQ,MAAM,iCAAiC,KAAK;AACpD,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACA,QAAM,EAAE,KAAK,WAAW,QAAQ,iBAAiB,IAAI,MAAM;AAC3D,QAAM,SAAS,UAAU,gBAAgB;AACzC,mCAAQ,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAY;AAC7C,IAAO,iBAAS,OAAO,MAAM,KAAK;AAAA,EACnC;AACA,mCAAQ,KAAK,OAAO,SAAS,IAAI;AACjC,SAAO,MAAM;AACZ,qCAAQ,IAAI,SAAS,MAAM,GAAG;AAC9B,qCAAQ,KAAK,SAAS,MAAM,GAAG;AAAA,EAChC;AACD;;;ACzBA,YAAYA,aAAY;AAExB,SAAS,cAAc,sBAAsB;AAItC,SAAS,iBAIf,OACA,QACA,OACa;AACb,QAAM,YAAY,aAAa,KAAK;AACpC,QAAM,cAAc,eAAe,KAAK;AACxC,SAAO,GAAG,QAAQ,MAAM,GAAG,IAAI,CAAC,SAAY;AAC3C,IAAO,iBAAS,WAAW,MAAM,KAAK;AAAA,EACvC,CAAC;AACD,SAAO;AAAA,IACN,QAAQ,MAAM,GAAG;AAAA,IACjB,CAAC,SAA+D;AAC/D,MAAO,iBAAS,aAAa,MAAM,KAAK;AAAA,IACzC;AAAA,EACD;AACA,SAAO,KAAK,OAAO,MAAM,GAAG,EAAE;AAC9B,SAAO,MAAM;AACZ,WAAO,IAAI,QAAQ,MAAM,GAAG,EAAE;AAC9B,WAAO,IAAI,QAAQ,MAAM,GAAG,EAAE;AAC9B,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAAA,EACjC;AACD;;;AC/BA,YAAYA,aAAY;AACxB,SAAS,gBAAAC,eAAc,kBAAAC,uBAAsB;AAE7C,SAAS,aAAAC,kBAAiB;AAInB,SAAS,wBAIf,OACA,QACA,OACa;AACb,MAAI,EAAE,YAAY,QAAQ;AACzB,YAAQ,MAAM,iCAAiC,KAAK;AACpD,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACA,QAAM,EAAE,KAAK,WAAW,QAAQ,iBAAiB,IAAI,MAAM;AAC3D,QAAM,SAASA,WAAU,gBAAgB;AACzC,mCAAQ,GAAG,QAAQ,MAAM,GAAG,IAAI,CAAC,SAAY;AAC5C,UAAM,YAAYF,cAAa,KAAK;AACpC,IAAO,iBAAS,WAAW,MAAM,KAAK;AAAA,EACvC;AACA,mCAAQ;AAAA,IACP,QAAQ,MAAM,GAAG;AAAA,IACjB,CAAC,SAA+D;AAC/D,YAAM,eAAeC,gBAAe,KAAK;AACzC,MAAO,iBAAS,cAAc,MAAM,KAAK;AAAA,IAC1C;AAAA;AAED,mCAAQ,KAAK,OAAO,SAAS,IAAI;AACjC,SAAO,MAAM;AACZ,qCAAQ,IAAI,SAAS,MAAM,GAAG;AAC9B,qCAAQ,KAAK,SAAS,MAAM,GAAG;AAAA,EAChC;AACD;;;ACrCA,YAAYF,aAAY;AAKjB,SAAS,UACf,OACA,QACA,iBACA,OACa;AACb,SAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAChC,EAAO;AAAA,IACN;AAAA,IACA,CAAC,EAAE,SAAS,MAAM;AACjB,aAAO,KAAK,OAAO,MAAM,GAAG,IAAI,QAAQ;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,SAAO,MAAM;AACZ,WAAO,IAAI,OAAO,MAAM,GAAG,EAAE;AAC7B,WAAO,KAAK,WAAW,MAAM,GAAG,EAAE;AAAA,EACnC;AACD;;;ACxBA,YAAYA,aAAY;AAIxB,IAAM,UAAU,oBAAI,IAAoB;AACjC,SAAS,8BACf,OACA,QACA,OACa;AATd;AAUC,QAAM,SAAQ,aAAQ,IAAI,MAAM,GAAG,MAArB,YAA0B;AACxC,UAAQ,IAAI,MAAM,KAAK,QAAQ,CAAC;AAChC,QAAM,cACL,UAAU,IACA;AAAA,IACP;AAAA,IACA,CAAC,iBAAiB;AACjB,YAAM,gBAAgB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AACxD,YAAM,eAAe,KAAK,UAAU,YAAY;AAChD,YAAM,QAAQ,WAAW,aAAa;AACtC,YAAM,OAAO,CAAC,iBAAsC;AApB1D,YAAAI,KAAA;AAqBO,SAAAA,MAAA,MAAM,OAAO,WAAb,gBAAAA,IAAqB,KAAK,eAAe,MAAM,GAAG;AAClD,eAAO,IAAI,OAAO,IAAI;AACtB,cAAM,eAAe,KAAK,UAAU,YAAY;AAChD,YAAI,iBAAiB,cAAc;AAClC,sBAAM,OAAO,WAAb,mBAAqB;AAAA,YACpB,eAAe,MAAM,GAAG;AAAA;AAEzB,sBAAM,OAAO,WAAb,mBAAqB,MAAM,WAAW;AACtC,sBAAM,OAAO,WAAb,mBAAqB,MAAM,WAAW;AAAA,QACvC,OAAO;AACN,sBAAM,OAAO,WAAb,mBAAqB;AAAA,YACpB,eAAe,MAAM,GAAG;AAAA;AAAA,QAE1B;AAAA,MACD;AACA,aAAO,GAAG,OAAO,IAAI;AACrB,aAAO,KAAK,MAAM,MAAM,GAAG,IAAI,cAAc,aAAa;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,EACA,IACA,MAAM;AACV,SAAO,MAAM;AA3Cd,QAAAA;AA4CE,UAAM,YAAWA,MAAA,QAAQ,IAAI,MAAM,GAAG,MAArB,OAAAA,MAA0B;AAC3C,YAAQ,IAAI,MAAM,KAAK,WAAW,CAAC;AACnC,gBAAY;AAAA,EACb;AACD","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.config.logger?.info(`Transaction ${token.key} synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.config.logger?.error(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.config.logger?.info(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} results match`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":";AAAA,YAAY,YAAY;AAEjB,IAAM,sBAA6B,YAAoB;AAAA,EAC7D,KAAK;AAAA,EACL,SAAS;AACV,CAAC;AACM,IAAM,YAAmB,gBAAwB;AAAA,EACvD,KAAK;AAAA,EACL,KAAK,CAAC,EAAE,IAAI,MAAM,IAAI,mBAAmB;AAC1C,CAAC;;;ACTD,YAAYA,aAAY;AAKjB,SAAS,UACf,OACA,QACA,OACa;AACb,SAAO,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAS;AACzC,IAAO,iBAAS,OAAO,MAAM,KAAK;AAAA,EACnC,CAAC;AACD,SAAO,KAAK,OAAO,MAAM,GAAG,EAAE;AAC9B,SAAO,MAAM;AACZ,WAAO,IAAI,SAAS,MAAM,GAAG,EAAE;AAC/B,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAAA,EACjC;AACD;;;AClBA,YAAYA,aAAY;AAGxB,SAAS,iBAAiB;AAGnB,SAAS,iBACf,OACA,QACA,OACa;AACb,MAAI,EAAE,YAAY,QAAQ;AACzB,YAAQ,MAAM,iCAAiC,KAAK;AACpD,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACA,QAAM,EAAE,KAAK,WAAW,QAAQ,iBAAiB,IAAI,MAAM;AAC3D,QAAM,SAAS,UAAU,gBAAgB;AACzC,mCAAQ,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAY;AAC7C,IAAO,iBAAS,OAAO,MAAM,KAAK;AAAA,EACnC;AACA,mCAAQ,KAAK,OAAO,SAAS,IAAI;AACjC,SAAO,MAAM;AACZ,qCAAQ,IAAI,SAAS,MAAM,GAAG;AAC9B,qCAAQ,KAAK,SAAS,MAAM,GAAG;AAAA,EAChC;AACD;;;ACzBA,YAAYA,aAAY;AAExB,SAAS,cAAc,sBAAsB;AAItC,SAAS,iBAIf,OACA,QACA,OACa;AACb,QAAM,YAAY,aAAa,KAAK;AACpC,QAAM,cAAc,eAAe,KAAK;AACxC,SAAO,GAAG,QAAQ,MAAM,GAAG,IAAI,CAAC,SAAY;AAC3C,IAAO,iBAAS,WAAW,MAAM,KAAK;AAAA,EACvC,CAAC;AACD,SAAO;AAAA,IACN,QAAQ,MAAM,GAAG;AAAA,IACjB,CAAC,SAA+D;AAC/D,MAAO,iBAAS,aAAa,MAAM,KAAK;AAAA,IACzC;AAAA,EACD;AACA,SAAO,KAAK,OAAO,MAAM,GAAG,EAAE;AAC9B,SAAO,MAAM;AACZ,WAAO,IAAI,QAAQ,MAAM,GAAG,EAAE;AAC9B,WAAO,IAAI,QAAQ,MAAM,GAAG,EAAE;AAC9B,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAAA,EACjC;AACD;;;AC/BA,YAAYA,aAAY;AACxB,SAAS,gBAAAC,eAAc,kBAAAC,uBAAsB;AAE7C,SAAS,aAAAC,kBAAiB;AAInB,SAAS,wBAIf,OACA,QACA,OACa;AACb,MAAI,EAAE,YAAY,QAAQ;AACzB,YAAQ,MAAM,iCAAiC,KAAK;AACpD,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACA,QAAM,EAAE,KAAK,WAAW,QAAQ,iBAAiB,IAAI,MAAM;AAC3D,QAAM,SAASA,WAAU,gBAAgB;AACzC,mCAAQ,GAAG,QAAQ,MAAM,GAAG,IAAI,CAAC,SAAY;AAC5C,UAAM,YAAYF,cAAa,KAAK;AACpC,IAAO,iBAAS,WAAW,MAAM,KAAK;AAAA,EACvC;AACA,mCAAQ;AAAA,IACP,QAAQ,MAAM,GAAG;AAAA,IACjB,CAAC,SAA+D;AAC/D,YAAM,eAAeC,gBAAe,KAAK;AACzC,MAAO,iBAAS,cAAc,MAAM,KAAK;AAAA,IAC1C;AAAA;AAED,mCAAQ,KAAK,OAAO,SAAS,IAAI;AACjC,SAAO,MAAM;AACZ,qCAAQ,IAAI,SAAS,MAAM,GAAG;AAC9B,qCAAQ,KAAK,SAAS,MAAM,GAAG;AAAA,EAChC;AACD;;;ACrCA,YAAYF,aAAY;AAKjB,SAAS,UACf,OACA,QACA,iBACA,OACa;AACb,SAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAChC,EAAO;AAAA,IACN;AAAA,IACA,CAAC,EAAE,SAAS,MAAM;AACjB,aAAO,KAAK,OAAO,MAAM,GAAG,IAAI,QAAQ;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,SAAO,MAAM;AACZ,WAAO,IAAI,OAAO,MAAM,GAAG,EAAE;AAC7B,WAAO,KAAK,WAAW,MAAM,GAAG,EAAE;AAAA,EACnC;AACD;;;ACxBA,YAAYA,aAAY;AAIxB,IAAM,UAAU,oBAAI,IAAoB;AACjC,SAAS,8BACf,OACA,QACA,OACa;AATd;AAUC,QAAM,SAAQ,aAAQ,IAAI,MAAM,GAAG,MAArB,YAA0B;AACxC,UAAQ,IAAI,MAAM,KAAK,QAAQ,CAAC;AAChC,QAAM,cACL,UAAU,IACA;AAAA,IACP;AAAA,IACA,CAAC,iBAAiB;AACjB,YAAM,gBAAgB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AACxD,YAAM,eAAe,KAAK,UAAU,YAAY;AAChD,YAAM,QAAQ,WAAW,aAAa;AACtC,YAAM,OAAO,CAAC,iBAAsC;AACnD,cAAM,OAAO,KAAK,6BAAmB,MAAM,GAAG,UAAU;AACxD,eAAO,IAAI,OAAO,IAAI;AACtB,cAAM,eAAe,KAAK,UAAU,YAAY;AAChD,YAAI,iBAAiB,cAAc;AAClC,gBAAM,OAAO;AAAA,YACZ,uBAAkB,MAAM,GAAG;AAAA,UAC5B;AACA,gBAAM,OAAO,MAAM,kBAAa,YAAY;AAC5C,gBAAM,OAAO,MAAM,kBAAa,YAAY;AAAA,QAC7C,OAAO;AACN,gBAAM,OAAO,KAAK,sBAAiB,MAAM,GAAG,gBAAgB;AAAA,QAC7D;AAAA,MACD;AACA,aAAO,GAAG,OAAO,IAAI;AACrB,aAAO,KAAK,MAAM,MAAM,GAAG,IAAI,cAAc,aAAa;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,EACA,IACA,MAAM;AACV,SAAO,MAAM;AAzCd,QAAAI;AA0CE,UAAM,YAAWA,MAAA,QAAQ,IAAI,MAAM,GAAG,MAArB,OAAAA,MAA0B;AAC3C,YAAQ,IAAI,MAAM,KAAK,WAAW,CAAC;AACnC,gBAAY;AAAA,EACb;AACD","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.logger.info(`♻️ Transaction \"${token.key}\" synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.logger.error(\n\t\t\t\t\t\t\t\t\t`❗ Transaction \"${token.key}\" produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.logger.error(`❗ Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.logger.error(`❗ Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.logger.info(`✅ Transaction ${token.key} results match`)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
@@ -19,19 +19,17 @@ export function synchronizeTransactionResults(
19
19
  const clientResult = JSON.stringify(clientUpdate)
20
20
  const topic = `tx:sync:${transactionId}`
21
21
  const sync = (serverUpdate: typeof clientUpdate) => {
22
- store.config.logger?.info(`Transaction ${token.key} synced`)
22
+ store.logger.info(`♻️ Transaction "${token.key}" synced`)
23
23
  socket.off(topic, sync)
24
24
  const serverResult = JSON.stringify(serverUpdate)
25
25
  if (clientResult !== serverResult) {
26
- store.config.logger?.error(
27
- `Transaction ${token.key} produced different results on client and server`,
26
+ store.logger.error(
27
+ `❗ Transaction "${token.key}" produced different results on client and server`,
28
28
  )
29
- store.config.logger?.error(`Client:`, clientResult)
30
- store.config.logger?.error(`Server:`, serverResult)
29
+ store.logger.error(`❗ Client:`, clientResult)
30
+ store.logger.error(`❗ Server:`, serverResult)
31
31
  } else {
32
- store.config.logger?.info(
33
- `Transaction ${token.key} results match`,
34
- )
32
+ store.logger.info(`✅ Transaction ${token.key} results match`)
35
33
  }
36
34
  }
37
35
  socket.on(topic, sync)
package/src/atom.ts CHANGED
@@ -4,11 +4,14 @@ import {
4
4
  createAtomFamily,
5
5
  createMutableAtom,
6
6
  createMutableAtomFamily,
7
+ deleteAtom,
7
8
  } from "atom.io/internal"
8
9
  import type { Json, JsonInterface } from "atom.io/json"
9
10
 
10
11
  import type { AtomToken, MutableAtomToken } from "."
11
12
 
13
+ export { deleteAtom }
14
+
12
15
  export type Effectors<T> = {
13
16
  setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void
14
17
  onSet: (callback: (options: { newValue: T; oldValue: T }) => void) => void
package/src/logger.ts CHANGED
@@ -1,46 +1,35 @@
1
- import { IMPLICIT } from "atom.io/internal"
2
- import type { Store } from "atom.io/internal"
3
-
4
- export const NO_OP = (): void => undefined
5
-
6
1
  export type Logger = Pick<Console, `error` | `info` | `warn`>
2
+
7
3
  export const LOG_LEVELS: ReadonlyArray<keyof Logger> = [
8
4
  `info`,
9
5
  `warn`,
10
6
  `error`,
11
7
  ] as const
12
8
 
13
- export const setLogLevel = (
14
- preferredLevel: `error` | `info` | `warn` | null,
15
- store: Store = IMPLICIT.STORE,
16
- ): void => {
17
- const { logger__INTERNAL } = store.config
18
- if (preferredLevel === null) {
19
- store.config.logger = null
20
- } else {
21
- store.config.logger = { ...console }
22
- for (const logLevel of LOG_LEVELS) {
23
- if (LOG_LEVELS.indexOf(logLevel) < LOG_LEVELS.indexOf(preferredLevel)) {
24
- // biome-ignore lint/style/noNonNullAssertion: we just set it
25
- store.config.logger![logLevel] = NO_OP
26
- } else {
27
- // biome-ignore lint/style/noNonNullAssertion: we just set it
28
- store.config.logger![logLevel] = logger__INTERNAL[logLevel]
29
- }
9
+ export class AtomIOLogger implements Logger {
10
+ public constructor(
11
+ private readonly logger: Logger,
12
+ public logLevel: `error` | `info` | `warn` | null,
13
+ private readonly filter?: (message: string) => boolean,
14
+ ) {}
15
+
16
+ public error(...args: any[]): void {
17
+ if ((this.filter?.(args[0]) ?? true) && this.logLevel !== null) {
18
+ this.logger.error(...args)
19
+ }
20
+ }
21
+ public info(...args: any[]): void {
22
+ if ((this.filter?.(args[0]) ?? true) && this.logLevel === `info`) {
23
+ this.logger.info(...args)
24
+ }
25
+ }
26
+ public warn(...args: any[]): void {
27
+ if (
28
+ (this.filter?.(args[0]) ?? true) &&
29
+ this.logLevel !== `error` &&
30
+ this.logLevel !== null
31
+ ) {
32
+ this.logger.warn(...args)
30
33
  }
31
34
  }
32
- }
33
-
34
- export const useLogger = (
35
- logger: Logger,
36
- store: Store = IMPLICIT.STORE,
37
- ): void => {
38
- const currentLogLevel =
39
- store.config.logger === null
40
- ? null
41
- : LOG_LEVELS.find(
42
- (logLevel) => store.config.logger?.[logLevel] !== NO_OP,
43
- ) ?? null
44
- store.config.logger__INTERNAL = { ...logger }
45
- setLogLevel(currentLogLevel, store)
46
35
  }