atom.io 0.15.6 → 0.16.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 (141) hide show
  1. package/data/dist/index.cjs +49 -37
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.d.ts +6 -6
  4. package/data/dist/index.js +50 -38
  5. package/data/dist/index.js.map +1 -1
  6. package/data/src/dict.ts +6 -7
  7. package/data/src/join.ts +52 -38
  8. package/data/src/struct-family.ts +2 -2
  9. package/data/src/struct.ts +4 -5
  10. package/dist/index.cjs +12 -5
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.ts +67 -60
  13. package/dist/index.js +13 -6
  14. package/dist/index.js.map +1 -1
  15. package/internal/dist/index.cjs +911 -888
  16. package/internal/dist/index.cjs.map +1 -1
  17. package/internal/dist/index.d.ts +157 -162
  18. package/internal/dist/index.js +486 -462
  19. package/internal/dist/index.js.map +1 -1
  20. package/internal/src/atom/create-regular-atom.ts +9 -12
  21. package/internal/src/atom/create-standalone-atom.ts +33 -0
  22. package/internal/src/atom/delete-atom.ts +5 -2
  23. package/internal/src/atom/index.ts +1 -16
  24. package/internal/src/atom/is-default.ts +0 -1
  25. package/internal/src/caching.ts +6 -3
  26. package/internal/src/families/create-atom-family.ts +11 -7
  27. package/internal/src/families/create-readonly-selector-family.ts +4 -3
  28. package/internal/src/families/create-regular-atom-family.ts +12 -27
  29. package/internal/src/families/create-selector-family.ts +13 -49
  30. package/internal/src/families/create-writable-selector-family.ts +51 -0
  31. package/internal/src/index.ts +44 -3
  32. package/internal/src/lineage.ts +0 -7
  33. package/internal/src/mutable/create-mutable-atom-family.ts +61 -15
  34. package/internal/src/mutable/create-mutable-atom.ts +70 -25
  35. package/internal/src/mutable/get-json-family.ts +4 -5
  36. package/internal/src/mutable/get-json-token.ts +6 -3
  37. package/internal/src/mutable/get-update-token.ts +3 -3
  38. package/internal/src/mutable/index.ts +1 -7
  39. package/internal/src/mutable/is-mutable.ts +6 -7
  40. package/internal/src/mutable/tracker-family.ts +4 -4
  41. package/internal/src/mutable/tracker.ts +6 -6
  42. package/internal/src/read-or-compute-value.ts +6 -3
  43. package/internal/src/selector/create-readonly-selector.ts +4 -5
  44. package/internal/src/selector/create-standalone-selector.ts +32 -0
  45. package/internal/src/selector/{create-read-write-selector.ts → create-writable-selector.ts} +13 -10
  46. package/internal/src/selector/delete-selector.ts +2 -2
  47. package/internal/src/selector/index.ts +3 -1
  48. package/internal/src/selector/trace-selector-atoms.ts +3 -2
  49. package/internal/src/selector/update-selector-atoms.ts +1 -1
  50. package/internal/src/set-state/copy-mutable-if-needed.ts +5 -8
  51. package/internal/src/set-state/copy-mutable-in-transaction.ts +4 -36
  52. package/internal/src/set-state/emit-update.ts +2 -3
  53. package/internal/src/set-state/evict-downstream.ts +1 -1
  54. package/internal/src/set-state/set-atom-or-selector.ts +3 -3
  55. package/internal/src/set-state/set-atom.ts +1 -2
  56. package/internal/src/set-state/stow-update.ts +1 -1
  57. package/internal/src/store/deposit.ts +25 -13
  58. package/internal/src/store/store.ts +20 -21
  59. package/internal/src/store/withdraw-new-family-member.ts +16 -9
  60. package/internal/src/store/withdraw.ts +43 -19
  61. package/internal/src/subscribe/recall-state.ts +2 -6
  62. package/internal/src/subscribe/subscribe-to-root-atoms.ts +39 -41
  63. package/internal/src/subscribe/subscribe-to-state.ts +3 -1
  64. package/internal/src/timeline/add-atom-to-timeline.ts +5 -5
  65. package/internal/src/timeline/create-timeline.ts +19 -22
  66. package/introspection/dist/index.cjs +4 -8
  67. package/introspection/dist/index.cjs.map +1 -1
  68. package/introspection/dist/index.d.ts +5 -5
  69. package/introspection/dist/index.js +5 -9
  70. package/introspection/dist/index.js.map +1 -1
  71. package/introspection/src/attach-atom-index.ts +4 -5
  72. package/introspection/src/attach-selector-index.ts +4 -5
  73. package/introspection/src/attach-timeline-index.ts +6 -3
  74. package/introspection/src/attach-transaction-index.ts +6 -3
  75. package/introspection/src/index.ts +9 -5
  76. package/json/dist/index.cjs +3 -4
  77. package/json/dist/index.cjs.map +1 -1
  78. package/json/dist/index.d.ts +4 -3
  79. package/json/dist/index.js +4 -5
  80. package/json/dist/index.js.map +1 -1
  81. package/json/src/select-json-family.ts +24 -4
  82. package/json/src/select-json.ts +3 -4
  83. package/package.json +11 -11
  84. package/react-devtools/dist/index.cjs +0 -2
  85. package/react-devtools/dist/index.cjs.map +1 -1
  86. package/react-devtools/dist/index.d.ts +9 -9
  87. package/react-devtools/dist/index.js +0 -2
  88. package/react-devtools/dist/index.js.map +1 -1
  89. package/react-devtools/src/StateIndex.tsx +18 -10
  90. package/react-devtools/src/TimelineIndex.tsx +6 -2
  91. package/react-devtools/src/TransactionIndex.tsx +2 -2
  92. package/realtime-client/dist/index.cjs +27 -13
  93. package/realtime-client/dist/index.cjs.map +1 -1
  94. package/realtime-client/dist/index.d.ts +6 -4
  95. package/realtime-client/dist/index.js +20 -7
  96. package/realtime-client/dist/index.js.map +1 -1
  97. package/realtime-client/src/index.ts +4 -3
  98. package/realtime-client/src/server-action.ts +2 -55
  99. package/realtime-client/src/sync-server-action.ts +75 -0
  100. package/realtime-react/dist/index.cjs +22 -13
  101. package/realtime-react/dist/index.cjs.map +1 -1
  102. package/realtime-react/dist/index.d.ts +3 -1
  103. package/realtime-react/dist/index.js +20 -12
  104. package/realtime-react/dist/index.js.map +1 -1
  105. package/realtime-react/src/index.ts +1 -0
  106. package/realtime-react/src/use-server-action.ts +2 -4
  107. package/realtime-react/src/use-sync-server-action.ts +19 -0
  108. package/realtime-server/dist/index.cjs +83 -81
  109. package/realtime-server/dist/index.cjs.map +1 -1
  110. package/realtime-server/dist/index.d.ts +8 -8
  111. package/realtime-server/dist/index.js +58 -56
  112. package/realtime-server/dist/index.js.map +1 -1
  113. package/realtime-server/src/index.ts +15 -1
  114. package/realtime-server/src/{hook-composition/receive-transaction.ts → realtime-action-receiver.ts} +6 -2
  115. package/realtime-server/src/{hook-composition/sync-transaction.ts → realtime-action-synchronizer.ts} +10 -43
  116. package/realtime-server/src/{hook-composition/expose-family.ts → realtime-family-provider.ts} +9 -23
  117. package/realtime-server/src/{hook-composition/expose-mutable-family.ts → realtime-mutable-family-provider.ts} +4 -4
  118. package/realtime-server/src/{hook-composition/expose-mutable.ts → realtime-mutable-provider.ts} +4 -5
  119. package/realtime-server/src/realtime-server-store.ts +39 -0
  120. package/realtime-server/src/{hook-composition/expose-single.ts → realtime-state-provider.ts} +7 -8
  121. package/realtime-server/src/{hook-composition/receive-state.ts → realtime-state-receiver.ts} +7 -4
  122. package/src/atom.ts +39 -24
  123. package/src/find-state.ts +20 -19
  124. package/src/index.ts +41 -28
  125. package/src/logger.ts +1 -0
  126. package/src/selector.ts +31 -16
  127. package/src/silo.ts +45 -6
  128. package/src/subscribe.ts +1 -0
  129. package/src/validators.ts +35 -25
  130. package/transceivers/set-rtx/dist/index.cjs +2 -2
  131. package/transceivers/set-rtx/dist/index.cjs.map +1 -1
  132. package/transceivers/set-rtx/dist/index.js +2 -2
  133. package/transceivers/set-rtx/dist/index.js.map +1 -1
  134. package/transceivers/set-rtx/src/set-rtx.ts +2 -2
  135. package/internal/src/atom/create-atom.ts +0 -21
  136. package/internal/src/mutable/get-update-family.ts +0 -23
  137. package/internal/src/selector/create-selector.ts +0 -65
  138. package/realtime-server/src/hook-composition/index.ts +0 -15
  139. /package/realtime-client/src/{pull.ts → pull-state.ts} +0 -0
  140. /package/realtime-client/src/{push.ts → push-state.ts} +0 -0
  141. /package/realtime-client/src/{realtime-state.ts → realtime-client-store.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/set-rtx.ts"],"names":["update","value"],"mappings":"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","sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, Stringified, primitive } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdate =\n\t| `add:${string}`\n\t| `clear:${string}`\n\t| `del:${string}`\n\t| `tx:${string}`\nexport type NumberedSetUpdate = `${number}=${SetUpdate}`\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdate | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements Transceiver<NumberedSetUpdate>, Lineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject = new Subject<SetUpdate>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdate | null)[] = []\n\tpublic cacheIdx = -1\n\tpublic cacheUpdateNumber = -1\n\n\tpublic constructor(values?: Iterable<P>, cacheLimit = 0) {\n\t\tsuper(values)\n\t\tif (values instanceof SetRTX) {\n\t\t\tthis.parent = values\n\t\t\tthis.cacheUpdateNumber = values.cacheUpdateNumber\n\t\t}\n\t\tif (cacheLimit) {\n\t\t\tthis.cacheLimit = cacheLimit\n\t\t\tthis.cache = new Array(cacheLimit)\n\t\t\tthis.subscribe(`auto cache`, (update) => {\n\t\t\t\tthis.cacheIdx++\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tthis.cache[this.cacheIdx] = update\n\t\t\t})\n\t\t}\n\t}\n\n\tpublic toJSON(): SetRTXJson<P> {\n\t\treturn {\n\t\t\tmembers: [...this],\n\t\t\tcache: this.cache,\n\t\t\tcacheLimit: this.cacheLimit,\n\t\t\tcacheIdx: this.cacheIdx,\n\t\t\tcacheUpdateNumber: this.cacheUpdateNumber,\n\t\t}\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: SetRTXJson<P>): SetRTX<P> {\n\t\tconst set = new SetRTX<P>(json.members, json.cacheLimit)\n\t\tset.cache = json.cache\n\t\tset.cacheIdx = json.cacheIdx\n\t\tset.cacheUpdateNumber = json.cacheUpdateNumber\n\t\treturn set\n\t}\n\n\tpublic add(value: P): this {\n\t\tconst result = super.add(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`add:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic clear(): void {\n\t\tconst capturedContents = this.mode === `record` ? [...this] : null\n\t\tsuper.clear()\n\t\tif (capturedContents) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`clear:${JSON.stringify(capturedContents)}`)\n\t\t}\n\t}\n\n\tpublic delete(value: P): boolean {\n\t\tconst result = super.delete(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`del:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic readonly parent: SetRTX<P> | null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdate[] | null = null\n\tpublic transaction(run: (child: SetRTX<P>) => boolean): void {\n\t\tthis.mode = `transaction`\n\t\tthis.transactionUpdates = []\n\t\tthis.child = new SetRTX(this)\n\t\tconst unsubscribe = this.child._subscribe(`transaction`, (update) => {\n\t\t\tthis.transactionUpdates?.push(update)\n\t\t})\n\t\ttry {\n\t\t\tconst shouldCommit = run(this.child)\n\t\t\tif (shouldCommit) {\n\t\t\t\tthis.cacheUpdateNumber++\n\t\t\t\tthis.emit(`tx:${this.transactionUpdates.join(`;`)}`)\n\t\t\t\tfor (const update of this.transactionUpdates) {\n\t\t\t\t\tthis.doStep(update)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (thrown) {\n\t\t\tconsole.error(`Failed to apply transaction to SetRTX: ${thrown}`)\n\t\t\tthrow thrown\n\t\t} finally {\n\t\t\tunsubscribe()\n\t\t\tthis.child = null\n\t\t\tthis.transactionUpdates = null\n\t\t\tthis.mode = `record`\n\t\t}\n\t}\n\n\tprotected _subscribe(\n\t\tkey: string,\n\t\tfn: (update: SetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: NumberedSetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, (update) =>\n\t\t\tfn(`${this.cacheUpdateNumber}=${update}`),\n\t\t)\n\t}\n\n\tpublic emit(update: SetUpdate): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdate): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak)\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const update of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(update as SetUpdate)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdate): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdate): number | `OUT_OF_RANGE` | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tconst eventOffset = updateNumber - this.cacheUpdateNumber\n\t\tconst isFuture = eventOffset > 0\n\t\tif (isFuture) {\n\t\t\tif (eventOffset === 1) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\t\tthis.doStep(innerUpdate)\n\t\t\t\tthis.mode = `record`\n\t\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.cacheUpdateNumber + 1\n\t\t}\n\t\tif (Math.abs(eventOffset) < this.cacheLimit) {\n\t\t\tconst eventIdx = this.cacheIdx + eventOffset\n\t\t\tconst cachedUpdate = this.cache[eventIdx]\n\t\t\tif (cachedUpdate === update) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthis.mode = `playback`\n\t\t\tlet done = false\n\t\t\twhile (!done) {\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tconst update = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!update) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(update)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.doStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\treturn null\n\t\t}\n\t\treturn `OUT_OF_RANGE`\n\t}\n\n\tpublic undoStep(update: SetUpdate): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint)\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = JSON.parse(value) as P[]\n\t\t\t\tfor (const value of values) this.add(value)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdate[]\n\t\t\t\tfor (let i = updates.length - 1; i >= 0; i--) {\n\t\t\t\t\tthis.undoStep(updates[i])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic undo(update: NumberedSetUpdate): number | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tif (updateNumber === this.cacheUpdateNumber) {\n\t\t\tthis.mode = `playback`\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.undoStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber--\n\t\t\treturn null\n\t\t}\n\t\treturn this.cacheUpdateNumber\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/set-rtx.ts"],"names":["update","value"],"mappings":"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","sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, Stringified, primitive } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdate =\n\t| `add:${string}`\n\t| `clear:${string}`\n\t| `del:${string}`\n\t| `tx:${string}`\nexport type NumberedSetUpdate = `${number}=${SetUpdate}`\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdate | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements Transceiver<NumberedSetUpdate>, Lineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject = new Subject<SetUpdate>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdate | null)[] = []\n\tpublic cacheIdx = -1\n\tpublic cacheUpdateNumber = -1\n\n\tpublic constructor(values?: Iterable<P>, cacheLimit = 0) {\n\t\tsuper(values)\n\t\tif (values instanceof SetRTX) {\n\t\t\tthis.parent = values\n\t\t\tthis.cacheUpdateNumber = values.cacheUpdateNumber\n\t\t}\n\t\tif (cacheLimit) {\n\t\t\tthis.cacheLimit = cacheLimit\n\t\t\tthis.cache = new Array(cacheLimit)\n\t\t\tthis.subscribe(`auto cache`, (update) => {\n\t\t\t\tthis.cacheIdx++\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tthis.cache[this.cacheIdx] = update\n\t\t\t})\n\t\t}\n\t}\n\n\tpublic toJSON(): SetRTXJson<P> {\n\t\treturn {\n\t\t\tmembers: [...this],\n\t\t\tcache: this.cache,\n\t\t\tcacheLimit: this.cacheLimit,\n\t\t\tcacheIdx: this.cacheIdx,\n\t\t\tcacheUpdateNumber: this.cacheUpdateNumber,\n\t\t}\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: SetRTXJson<P>): SetRTX<P> {\n\t\tconst set = new SetRTX<P>(json.members, json.cacheLimit)\n\t\tset.cache = json.cache\n\t\tset.cacheIdx = json.cacheIdx\n\t\tset.cacheUpdateNumber = json.cacheUpdateNumber\n\t\treturn set\n\t}\n\n\tpublic add(value: P): this {\n\t\tconst result = super.add(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`add:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic clear(): void {\n\t\tconst capturedContents = this.mode === `record` ? [...this] : null\n\t\tsuper.clear()\n\t\tif (capturedContents) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`clear:${JSON.stringify(capturedContents)}`)\n\t\t}\n\t}\n\n\tpublic delete(value: P): boolean {\n\t\tconst result = super.delete(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`del:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic readonly parent: SetRTX<P> | null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdate[] | null = null\n\tpublic transaction(run: (child: SetRTX<P>) => boolean): void {\n\t\tthis.mode = `transaction`\n\t\tthis.transactionUpdates = []\n\t\tthis.child = new SetRTX(this)\n\t\tconst unsubscribe = this.child._subscribe(`transaction`, (update) => {\n\t\t\tthis.transactionUpdates?.push(update)\n\t\t})\n\t\ttry {\n\t\t\tconst shouldCommit = run(this.child)\n\t\t\tif (shouldCommit) {\n\t\t\t\tfor (const update of this.transactionUpdates) {\n\t\t\t\t\tthis.doStep(update)\n\t\t\t\t}\n\t\t\t\tthis.cacheUpdateNumber++\n\t\t\t\tthis.emit(`tx:${this.transactionUpdates.join(`;`)}`)\n\t\t\t}\n\t\t} catch (thrown) {\n\t\t\tconsole.error(`Failed to apply transaction to SetRTX: ${thrown}`)\n\t\t\tthrow thrown\n\t\t} finally {\n\t\t\tunsubscribe()\n\t\t\tthis.child = null\n\t\t\tthis.transactionUpdates = null\n\t\t\tthis.mode = `record`\n\t\t}\n\t}\n\n\tprotected _subscribe(\n\t\tkey: string,\n\t\tfn: (update: SetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: NumberedSetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, (update) =>\n\t\t\tfn(`${this.cacheUpdateNumber}=${update}`),\n\t\t)\n\t}\n\n\tpublic emit(update: SetUpdate): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdate): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak)\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const update of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(update as SetUpdate)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdate): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdate): number | `OUT_OF_RANGE` | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tconst eventOffset = updateNumber - this.cacheUpdateNumber\n\t\tconst isFuture = eventOffset > 0\n\t\tif (isFuture) {\n\t\t\tif (eventOffset === 1) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\t\tthis.doStep(innerUpdate)\n\t\t\t\tthis.mode = `record`\n\t\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.cacheUpdateNumber + 1\n\t\t}\n\t\tif (Math.abs(eventOffset) < this.cacheLimit) {\n\t\t\tconst eventIdx = this.cacheIdx + eventOffset\n\t\t\tconst cachedUpdate = this.cache[eventIdx]\n\t\t\tif (cachedUpdate === update) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthis.mode = `playback`\n\t\t\tlet done = false\n\t\t\twhile (!done) {\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tconst update = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!update) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(update)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.doStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\treturn null\n\t\t}\n\t\treturn `OUT_OF_RANGE`\n\t}\n\n\tpublic undoStep(update: SetUpdate): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint)\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = JSON.parse(value) as P[]\n\t\t\t\tfor (const value of values) this.add(value)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdate[]\n\t\t\t\tfor (let i = updates.length - 1; i >= 0; i--) {\n\t\t\t\t\tthis.undoStep(updates[i])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic undo(update: NumberedSetUpdate): number | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tif (updateNumber === this.cacheUpdateNumber) {\n\t\t\tthis.mode = `playback`\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.undoStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber--\n\t\t\treturn null\n\t\t}\n\t\treturn this.cacheUpdateNumber\n\t}\n}\n"]}
@@ -78,11 +78,11 @@ var SetRTX = class _SetRTX extends Set {
78
78
  try {
79
79
  const shouldCommit = run(this.child);
80
80
  if (shouldCommit) {
81
- this.cacheUpdateNumber++;
82
- this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
83
81
  for (const update of this.transactionUpdates) {
84
82
  this.doStep(update);
85
83
  }
84
+ this.cacheUpdateNumber++;
85
+ this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
86
86
  }
87
87
  } catch (thrown) {
88
88
  console.error(`Failed to apply transaction to SetRTX: ${thrown}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/set-rtx.ts"],"names":["update","value"],"mappings":";;;AACA,SAAS,eAAe;AAExB,SAAS,WAAW,qBAAqB;AAgBlC,IAAM,SAAN,MAAM,gBACJ,IAET;AAAA,EAQQ,YAAY,QAAsB,aAAa,GAAG;AACxD,UAAM,MAAM;AARb,SAAO,OAAwB;AAC/B,SAAgB,UAAU,IAAI,QAAmB;AACjD,SAAO,aAAa;AACpB,SAAO,QAAsC,CAAC;AAC9C,SAAO,WAAW;AAClB,SAAO,oBAAoB;AAiE3B,SAAO,QAA0B;AACjC,SAAO,qBAAyC;AA9D/C,QAAI,kBAAkB,SAAQ;AAC7B,WAAK,SAAS;AACd,WAAK,oBAAoB,OAAO;AAAA,IACjC;AACA,QAAI,YAAY;AACf,WAAK,aAAa;AAClB,WAAK,QAAQ,IAAI,MAAM,UAAU;AACjC,WAAK,UAAU,cAAc,CAAC,WAAW;AACxC,aAAK;AACL,aAAK,YAAY,KAAK;AACtB,aAAK,MAAM,KAAK,QAAQ,IAAI;AAAA,MAC7B,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEO,SAAwB;AAC9B,WAAO;AAAA,MACN,SAAS,CAAC,GAAG,IAAI;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK;AAAA,MACf,mBAAmB,KAAK;AAAA,IACzB;AAAA,EACD;AAAA,EAEA,OAAc,SAA8B,MAAgC;AAC3E,UAAM,MAAM,IAAI,QAAU,KAAK,SAAS,KAAK,UAAU;AACvD,QAAI,QAAQ,KAAK;AACjB,QAAI,WAAW,KAAK;AACpB,QAAI,oBAAoB,KAAK;AAC7B,WAAO;AAAA,EACR;AAAA,EAEO,IAAI,OAAgB;AAC1B,UAAM,SAAS,MAAM,IAAI,KAAK;AAC9B,QAAI,KAAK,SAAS,UAAU;AAC3B,WAAK;AACL,WAAK,KAAK,OAAO,cAAiB,KAAK,CAAC,EAAE;AAAA,IAC3C;AACA,WAAO;AAAA,EACR;AAAA,EAEO,QAAc;AACpB,UAAM,mBAAmB,KAAK,SAAS,WAAW,CAAC,GAAG,IAAI,IAAI;AAC9D,UAAM,MAAM;AACZ,QAAI,kBAAkB;AACrB,WAAK;AACL,WAAK,KAAK,SAAS,KAAK,UAAU,gBAAgB,CAAC,EAAE;AAAA,IACtD;AAAA,EACD;AAAA,EAEO,OAAO,OAAmB;AAChC,UAAM,SAAS,MAAM,OAAO,KAAK;AACjC,QAAI,KAAK,SAAS,UAAU;AAC3B,WAAK;AACL,WAAK,KAAK,OAAO,cAAiB,KAAK,CAAC,EAAE;AAAA,IAC3C;AACA,WAAO;AAAA,EACR;AAAA,EAKO,YAAY,KAA0C;AAC5D,SAAK,OAAO;AACZ,SAAK,qBAAqB,CAAC;AAC3B,SAAK,QAAQ,IAAI,QAAO,IAAI;AAC5B,UAAM,cAAc,KAAK,MAAM,WAAW,eAAe,CAAC,WAAW;AAnGvE;AAoGG,iBAAK,uBAAL,mBAAyB,KAAK;AAAA,IAC/B,CAAC;AACD,QAAI;AACH,YAAM,eAAe,IAAI,KAAK,KAAK;AACnC,UAAI,cAAc;AACjB,aAAK;AACL,aAAK,KAAK,MAAM,KAAK,mBAAmB,KAAK,GAAG,CAAC,EAAE;AACnD,mBAAW,UAAU,KAAK,oBAAoB;AAC7C,eAAK,OAAO,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,IACD,SAAS,QAAQ;AAChB,cAAQ,MAAM,0CAA0C,MAAM,EAAE;AAChE,YAAM;AAAA,IACP,UAAE;AACD,kBAAY;AACZ,WAAK,QAAQ;AACb,WAAK,qBAAqB;AAC1B,WAAK,OAAO;AAAA,IACb;AAAA,EACD;AAAA,EAEU,WACT,KACA,IACa;AACb,WAAO,KAAK,QAAQ,UAAU,KAAK,EAAE;AAAA,EACtC;AAAA,EACO,UACN,KACA,IACa;AACb,WAAO,KAAK,QAAQ;AAAA,MAAU;AAAA,MAAK,CAAC,WACnC,GAAG,GAAG,KAAK,iBAAiB,IAAI,MAAM,EAAE;AAAA,IACzC;AAAA,EACD;AAAA,EAEO,KAAK,QAAyB;AACpC,SAAK,QAAQ,KAAK,MAAM;AAAA,EACzB;AAAA,EAEQ,OAAO,QAAyB;AACvC,UAAM,iBAAiB,OAAO,QAAQ,GAAG;AACzC,UAAM,OAAO,OAAO,UAAU,GAAG,cAAc;AAC/C,UAAM,QAAQ,OAAO,UAAU,iBAAiB,CAAC;AACjD,YAAQ,MAAM;AAAA,MACb,KAAK;AACJ,aAAK,IAAI,UAAU,KAAuB,CAAC;AAC3C;AAAA,MACD,KAAK;AACJ,aAAK,MAAM;AACX;AAAA,MACD,KAAK;AACJ,aAAK,OAAO,UAAU,KAAuB,CAAC;AAC9C;AAAA,MACD,KAAK;AACJ,mBAAWA,WAAU,MAAM,MAAM,GAAG,GAAG;AACtC,eAAK,OAAOA,OAAmB;AAAA,QAChC;AAAA,IACF;AAAA,EACD;AAAA,EAEO,gBAAgB,QAAmC;AACzD,UAAM,aAAa,OAAO,QAAQ,GAAG;AACrC,WAAO,OAAO,OAAO,UAAU,GAAG,UAAU,CAAC;AAAA,EAC9C;AAAA,EAEO,GAAG,QAA2D;AACpE,UAAM,aAAa,OAAO,QAAQ,GAAG;AACrC,UAAM,eAAe,OAAO,OAAO,UAAU,GAAG,UAAU,CAAC;AAC3D,UAAM,cAAc,eAAe,KAAK;AACxC,UAAM,WAAW,cAAc;AAC/B,QAAI,UAAU;AACb,UAAI,gBAAgB,GAAG;AACtB,aAAK,OAAO;AACZ,cAAM,cAAc,OAAO,UAAU,aAAa,CAAC;AACnD,aAAK,OAAO,WAAW;AACvB,aAAK,OAAO;AACZ,aAAK,oBAAoB;AACzB,eAAO;AAAA,MACR;AACA,aAAO,KAAK,oBAAoB;AAAA,IACjC;AACA,QAAI,KAAK,IAAI,WAAW,IAAI,KAAK,YAAY;AAC5C,YAAM,WAAW,KAAK,WAAW;AACjC,YAAM,eAAe,KAAK,MAAM,QAAQ;AACxC,UAAI,iBAAiB,QAAQ;AAC5B,eAAO;AAAA,MACR;AACA,WAAK,OAAO;AACZ,UAAI,OAAO;AACX,aAAO,CAAC,MAAM;AACb,aAAK,YAAY,KAAK;AACtB,cAAMA,UAAS,KAAK,MAAM,KAAK,QAAQ;AACvC,aAAK;AACL,YAAI,CAACA,SAAQ;AACZ,iBAAO;AAAA,QACR;AACA,aAAK,KAAKA,OAAM;AAChB,eAAO,KAAK,aAAa,WAAW;AAAA,MACrC;AACA,YAAM,cAAc,OAAO,UAAU,aAAa,CAAC;AACnD,WAAK,OAAO,WAAW;AACvB,WAAK,OAAO;AACZ,WAAK,oBAAoB;AACzB,aAAO;AAAA,IACR;AACA,WAAO;AAAA,EACR;AAAA,EAEO,SAAS,QAAyB;AACxC,UAAM,aAAa,OAAO,QAAQ,GAAG;AACrC,UAAM,OAAO,OAAO,UAAU,GAAG,UAAU;AAC3C,UAAM,QAAQ,OAAO,UAAU,aAAa,CAAC;AAC7C,YAAQ,MAAM;AAAA,MACb,KAAK;AACJ,aAAK,OAAO,UAAU,KAAuB,CAAC;AAC9C;AAAA,MACD,KAAK;AACJ,aAAK,IAAI,UAAU,KAAuB,CAAC;AAC3C;AAAA,MACD,KAAK,SAAS;AACb,cAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,mBAAWC,UAAS;AAAQ,eAAK,IAAIA,MAAK;AAC1C;AAAA,MACD;AAAA,MACA,KAAK,MAAM;AACV,cAAM,UAAU,MAAM,MAAM,GAAG;AAC/B,iBAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,eAAK,SAAS,QAAQ,CAAC,CAAC;AAAA,QACzB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEO,KAAK,QAA0C;AACrD,UAAM,aAAa,OAAO,QAAQ,GAAG;AACrC,UAAM,eAAe,OAAO,OAAO,UAAU,GAAG,UAAU,CAAC;AAC3D,QAAI,iBAAiB,KAAK,mBAAmB;AAC5C,WAAK,OAAO;AACZ,YAAM,cAAc,OAAO,UAAU,aAAa,CAAC;AACnD,WAAK,SAAS,WAAW;AACzB,WAAK,OAAO;AACZ,WAAK;AACL,aAAO;AAAA,IACR;AACA,WAAO,KAAK;AAAA,EACb;AACD","sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, Stringified, primitive } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdate =\n\t| `add:${string}`\n\t| `clear:${string}`\n\t| `del:${string}`\n\t| `tx:${string}`\nexport type NumberedSetUpdate = `${number}=${SetUpdate}`\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdate | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements Transceiver<NumberedSetUpdate>, Lineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject = new Subject<SetUpdate>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdate | null)[] = []\n\tpublic cacheIdx = -1\n\tpublic cacheUpdateNumber = -1\n\n\tpublic constructor(values?: Iterable<P>, cacheLimit = 0) {\n\t\tsuper(values)\n\t\tif (values instanceof SetRTX) {\n\t\t\tthis.parent = values\n\t\t\tthis.cacheUpdateNumber = values.cacheUpdateNumber\n\t\t}\n\t\tif (cacheLimit) {\n\t\t\tthis.cacheLimit = cacheLimit\n\t\t\tthis.cache = new Array(cacheLimit)\n\t\t\tthis.subscribe(`auto cache`, (update) => {\n\t\t\t\tthis.cacheIdx++\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tthis.cache[this.cacheIdx] = update\n\t\t\t})\n\t\t}\n\t}\n\n\tpublic toJSON(): SetRTXJson<P> {\n\t\treturn {\n\t\t\tmembers: [...this],\n\t\t\tcache: this.cache,\n\t\t\tcacheLimit: this.cacheLimit,\n\t\t\tcacheIdx: this.cacheIdx,\n\t\t\tcacheUpdateNumber: this.cacheUpdateNumber,\n\t\t}\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: SetRTXJson<P>): SetRTX<P> {\n\t\tconst set = new SetRTX<P>(json.members, json.cacheLimit)\n\t\tset.cache = json.cache\n\t\tset.cacheIdx = json.cacheIdx\n\t\tset.cacheUpdateNumber = json.cacheUpdateNumber\n\t\treturn set\n\t}\n\n\tpublic add(value: P): this {\n\t\tconst result = super.add(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`add:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic clear(): void {\n\t\tconst capturedContents = this.mode === `record` ? [...this] : null\n\t\tsuper.clear()\n\t\tif (capturedContents) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`clear:${JSON.stringify(capturedContents)}`)\n\t\t}\n\t}\n\n\tpublic delete(value: P): boolean {\n\t\tconst result = super.delete(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`del:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic readonly parent: SetRTX<P> | null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdate[] | null = null\n\tpublic transaction(run: (child: SetRTX<P>) => boolean): void {\n\t\tthis.mode = `transaction`\n\t\tthis.transactionUpdates = []\n\t\tthis.child = new SetRTX(this)\n\t\tconst unsubscribe = this.child._subscribe(`transaction`, (update) => {\n\t\t\tthis.transactionUpdates?.push(update)\n\t\t})\n\t\ttry {\n\t\t\tconst shouldCommit = run(this.child)\n\t\t\tif (shouldCommit) {\n\t\t\t\tthis.cacheUpdateNumber++\n\t\t\t\tthis.emit(`tx:${this.transactionUpdates.join(`;`)}`)\n\t\t\t\tfor (const update of this.transactionUpdates) {\n\t\t\t\t\tthis.doStep(update)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (thrown) {\n\t\t\tconsole.error(`Failed to apply transaction to SetRTX: ${thrown}`)\n\t\t\tthrow thrown\n\t\t} finally {\n\t\t\tunsubscribe()\n\t\t\tthis.child = null\n\t\t\tthis.transactionUpdates = null\n\t\t\tthis.mode = `record`\n\t\t}\n\t}\n\n\tprotected _subscribe(\n\t\tkey: string,\n\t\tfn: (update: SetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: NumberedSetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, (update) =>\n\t\t\tfn(`${this.cacheUpdateNumber}=${update}`),\n\t\t)\n\t}\n\n\tpublic emit(update: SetUpdate): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdate): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak)\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const update of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(update as SetUpdate)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdate): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdate): number | `OUT_OF_RANGE` | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tconst eventOffset = updateNumber - this.cacheUpdateNumber\n\t\tconst isFuture = eventOffset > 0\n\t\tif (isFuture) {\n\t\t\tif (eventOffset === 1) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\t\tthis.doStep(innerUpdate)\n\t\t\t\tthis.mode = `record`\n\t\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.cacheUpdateNumber + 1\n\t\t}\n\t\tif (Math.abs(eventOffset) < this.cacheLimit) {\n\t\t\tconst eventIdx = this.cacheIdx + eventOffset\n\t\t\tconst cachedUpdate = this.cache[eventIdx]\n\t\t\tif (cachedUpdate === update) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthis.mode = `playback`\n\t\t\tlet done = false\n\t\t\twhile (!done) {\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tconst update = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!update) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(update)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.doStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\treturn null\n\t\t}\n\t\treturn `OUT_OF_RANGE`\n\t}\n\n\tpublic undoStep(update: SetUpdate): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint)\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = JSON.parse(value) as P[]\n\t\t\t\tfor (const value of values) this.add(value)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdate[]\n\t\t\t\tfor (let i = updates.length - 1; i >= 0; i--) {\n\t\t\t\t\tthis.undoStep(updates[i])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic undo(update: NumberedSetUpdate): number | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tif (updateNumber === this.cacheUpdateNumber) {\n\t\t\tthis.mode = `playback`\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.undoStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber--\n\t\t\treturn null\n\t\t}\n\t\treturn this.cacheUpdateNumber\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../src/set-rtx.ts"],"names":["update","value"],"mappings":"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","sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, Stringified, primitive } from \"atom.io/json\"\nimport { parseJson, stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdate =\n\t| `add:${string}`\n\t| `clear:${string}`\n\t| `del:${string}`\n\t| `tx:${string}`\nexport type NumberedSetUpdate = `${number}=${SetUpdate}`\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdate | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements Transceiver<NumberedSetUpdate>, Lineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject = new Subject<SetUpdate>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdate | null)[] = []\n\tpublic cacheIdx = -1\n\tpublic cacheUpdateNumber = -1\n\n\tpublic constructor(values?: Iterable<P>, cacheLimit = 0) {\n\t\tsuper(values)\n\t\tif (values instanceof SetRTX) {\n\t\t\tthis.parent = values\n\t\t\tthis.cacheUpdateNumber = values.cacheUpdateNumber\n\t\t}\n\t\tif (cacheLimit) {\n\t\t\tthis.cacheLimit = cacheLimit\n\t\t\tthis.cache = new Array(cacheLimit)\n\t\t\tthis.subscribe(`auto cache`, (update) => {\n\t\t\t\tthis.cacheIdx++\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tthis.cache[this.cacheIdx] = update\n\t\t\t})\n\t\t}\n\t}\n\n\tpublic toJSON(): SetRTXJson<P> {\n\t\treturn {\n\t\t\tmembers: [...this],\n\t\t\tcache: this.cache,\n\t\t\tcacheLimit: this.cacheLimit,\n\t\t\tcacheIdx: this.cacheIdx,\n\t\t\tcacheUpdateNumber: this.cacheUpdateNumber,\n\t\t}\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: SetRTXJson<P>): SetRTX<P> {\n\t\tconst set = new SetRTX<P>(json.members, json.cacheLimit)\n\t\tset.cache = json.cache\n\t\tset.cacheIdx = json.cacheIdx\n\t\tset.cacheUpdateNumber = json.cacheUpdateNumber\n\t\treturn set\n\t}\n\n\tpublic add(value: P): this {\n\t\tconst result = super.add(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`add:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic clear(): void {\n\t\tconst capturedContents = this.mode === `record` ? [...this] : null\n\t\tsuper.clear()\n\t\tif (capturedContents) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`clear:${JSON.stringify(capturedContents)}`)\n\t\t}\n\t}\n\n\tpublic delete(value: P): boolean {\n\t\tconst result = super.delete(value)\n\t\tif (this.mode === `record`) {\n\t\t\tthis.cacheUpdateNumber++\n\t\t\tthis.emit(`del:${stringifyJson<P>(value)}`)\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic readonly parent: SetRTX<P> | null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdate[] | null = null\n\tpublic transaction(run: (child: SetRTX<P>) => boolean): void {\n\t\tthis.mode = `transaction`\n\t\tthis.transactionUpdates = []\n\t\tthis.child = new SetRTX(this)\n\t\tconst unsubscribe = this.child._subscribe(`transaction`, (update) => {\n\t\t\tthis.transactionUpdates?.push(update)\n\t\t})\n\t\ttry {\n\t\t\tconst shouldCommit = run(this.child)\n\t\t\tif (shouldCommit) {\n\t\t\t\tfor (const update of this.transactionUpdates) {\n\t\t\t\t\tthis.doStep(update)\n\t\t\t\t}\n\t\t\t\tthis.cacheUpdateNumber++\n\t\t\t\tthis.emit(`tx:${this.transactionUpdates.join(`;`)}`)\n\t\t\t}\n\t\t} catch (thrown) {\n\t\t\tconsole.error(`Failed to apply transaction to SetRTX: ${thrown}`)\n\t\t\tthrow thrown\n\t\t} finally {\n\t\t\tunsubscribe()\n\t\t\tthis.child = null\n\t\t\tthis.transactionUpdates = null\n\t\t\tthis.mode = `record`\n\t\t}\n\t}\n\n\tprotected _subscribe(\n\t\tkey: string,\n\t\tfn: (update: SetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: NumberedSetUpdate) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, (update) =>\n\t\t\tfn(`${this.cacheUpdateNumber}=${update}`),\n\t\t)\n\t}\n\n\tpublic emit(update: SetUpdate): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdate): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak)\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const update of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(update as SetUpdate)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdate): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdate): number | `OUT_OF_RANGE` | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tconst eventOffset = updateNumber - this.cacheUpdateNumber\n\t\tconst isFuture = eventOffset > 0\n\t\tif (isFuture) {\n\t\t\tif (eventOffset === 1) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\t\tthis.doStep(innerUpdate)\n\t\t\t\tthis.mode = `record`\n\t\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.cacheUpdateNumber + 1\n\t\t}\n\t\tif (Math.abs(eventOffset) < this.cacheLimit) {\n\t\t\tconst eventIdx = this.cacheIdx + eventOffset\n\t\t\tconst cachedUpdate = this.cache[eventIdx]\n\t\t\tif (cachedUpdate === update) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthis.mode = `playback`\n\t\t\tlet done = false\n\t\t\twhile (!done) {\n\t\t\t\tthis.cacheIdx %= this.cacheLimit\n\t\t\t\tconst update = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!update) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(update)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.doStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber = updateNumber\n\t\t\treturn null\n\t\t}\n\t\treturn `OUT_OF_RANGE`\n\t}\n\n\tpublic undoStep(update: SetUpdate): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint)\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(parseJson(value as Stringified<P>))\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = JSON.parse(value) as P[]\n\t\t\t\tfor (const value of values) this.add(value)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdate[]\n\t\t\t\tfor (let i = updates.length - 1; i >= 0; i--) {\n\t\t\t\t\tthis.undoStep(updates[i])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic undo(update: NumberedSetUpdate): number | null {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\tconst updateNumber = Number(update.substring(0, breakpoint))\n\t\tif (updateNumber === this.cacheUpdateNumber) {\n\t\t\tthis.mode = `playback`\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdate\n\t\t\tthis.undoStep(innerUpdate)\n\t\t\tthis.mode = `record`\n\t\t\tthis.cacheUpdateNumber--\n\t\t\treturn null\n\t\t}\n\t\treturn this.cacheUpdateNumber\n\t}\n}\n"]}
@@ -103,11 +103,11 @@ export class SetRTX<P extends primitive>
103
103
  try {
104
104
  const shouldCommit = run(this.child)
105
105
  if (shouldCommit) {
106
- this.cacheUpdateNumber++
107
- this.emit(`tx:${this.transactionUpdates.join(`;`)}`)
108
106
  for (const update of this.transactionUpdates) {
109
107
  this.doStep(update)
110
108
  }
109
+ this.cacheUpdateNumber++
110
+ this.emit(`tx:${this.transactionUpdates.join(`;`)}`)
111
111
  }
112
112
  } catch (thrown) {
113
113
  console.error(`Failed to apply transaction to SetRTX: ${thrown}`)
@@ -1,21 +0,0 @@
1
- import type {
2
- AtomOptions,
3
- AtomToken,
4
- FamilyMetadata,
5
- MutableAtomOptions,
6
- } from "atom.io"
7
-
8
- import { createMutableAtom } from "../mutable"
9
- import type { Store } from "../store"
10
- import { createRegularAtom } from "./create-regular-atom"
11
-
12
- export function createAtom<T>(
13
- options: AtomOptions<T> | MutableAtomOptions<any, any>,
14
- family: FamilyMetadata | undefined,
15
- store: Store,
16
- ): AtomToken<T> {
17
- if (`mutable` in options) {
18
- return createMutableAtom(options, family, store)
19
- }
20
- return createRegularAtom<T>(options, family, store)
21
- }
@@ -1,23 +0,0 @@
1
- import type { AtomFamily, MutableAtomFamily } from "atom.io"
2
- import type { Json } from "atom.io/json"
3
-
4
- import { newest } from "../lineage"
5
- import type { Store } from "../store"
6
- import type { Signal, Transceiver } from "./transceiver"
7
-
8
- export const getUpdateFamily = <
9
- Core extends Transceiver<Json.Serializable>,
10
- SerializableCore extends Json.Serializable,
11
- Key extends string,
12
- >(
13
- mutableAtomFamily: MutableAtomFamily<Core, SerializableCore, Key>,
14
- store: Store,
15
- ): AtomFamily<Signal<Core> | null, Key> => {
16
- const target = newest(store)
17
- const key = `*${mutableAtomFamily.key}`
18
- const updateFamily = target.families.get(key) as AtomFamily<
19
- Signal<Core> | null,
20
- Key
21
- >
22
- return updateFamily
23
- }
@@ -1,65 +0,0 @@
1
- import type {
2
- FamilyMetadata,
3
- ReadonlySelectorOptions,
4
- ReadonlySelectorToken,
5
- SelectorOptions,
6
- SelectorToken,
7
- } from "atom.io"
8
-
9
- import { newest } from "../lineage"
10
- import type { Store } from "../store"
11
- import type { Subject } from "../subject"
12
- import { createReadWriteSelector } from "./create-read-write-selector"
13
- import { createReadonlySelector } from "./create-readonly-selector"
14
-
15
- export type Selector<T> = {
16
- key: string
17
- type: `selector`
18
- family?: FamilyMetadata
19
- install: (store: Store) => void
20
- subject: Subject<{ newValue: T; oldValue: T }>
21
- get: () => T
22
- set: (newValue: T | ((oldValue: T) => T)) => void
23
- }
24
- export type ReadonlySelector<T> = {
25
- key: string
26
- type: `readonly_selector`
27
- family?: FamilyMetadata
28
- install: (store: Store) => void
29
- subject: Subject<{ newValue: T; oldValue: T }>
30
- get: () => T
31
- }
32
-
33
- export function createSelector<T>(
34
- options: SelectorOptions<T>,
35
- family: FamilyMetadata | undefined,
36
- store: Store,
37
- ): SelectorToken<T>
38
- export function createSelector<T>(
39
- options: ReadonlySelectorOptions<T>,
40
- family: FamilyMetadata | undefined,
41
- store: Store,
42
- ): ReadonlySelectorToken<T>
43
- export function createSelector<T>(
44
- options: ReadonlySelectorOptions<T> | SelectorOptions<T>,
45
- family: FamilyMetadata | undefined,
46
- store: Store,
47
- ): ReadonlySelectorToken<T> | SelectorToken<T> {
48
- const target = newest(store)
49
- const existingWritable = target.selectors.get(options.key)
50
- const existingReadonly = target.readonlySelectors.get(options.key)
51
-
52
- if (existingWritable || existingReadonly) {
53
- store.logger.error(
54
- `❌`,
55
- existingReadonly ? `readonly_selector` : `selector`,
56
- options.key,
57
- `Tried to create selector, but it already exists in the store.`,
58
- )
59
- }
60
-
61
- if (`set` in options) {
62
- return createReadWriteSelector(options, family, store)
63
- }
64
- return createReadonlySelector(options, family, store)
65
- }
@@ -1,15 +0,0 @@
1
- import type { Store } from "atom.io/internal"
2
- import type * as SocketIO from "socket.io"
3
-
4
- export * from "./expose-single"
5
- export * from "./expose-family"
6
- export * from "./expose-mutable"
7
- export * from "./expose-mutable-family"
8
- export * from "./receive-state"
9
- export * from "./receive-transaction"
10
- export * from "./sync-transaction"
11
-
12
- export type ServerConfig = {
13
- socket: SocketIO.Socket
14
- store?: Store
15
- }
File without changes
File without changes