atom.io 0.41.1 → 0.42.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 (59) hide show
  1. package/dist/internal/index.d.ts +30 -47
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +116 -287
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/main/index.d.ts +52 -56
  6. package/dist/main/index.d.ts.map +1 -1
  7. package/dist/main/index.js +45 -8
  8. package/dist/main/index.js.map +1 -1
  9. package/dist/realtime/index.d.ts +2 -3
  10. package/dist/realtime/index.d.ts.map +1 -1
  11. package/dist/realtime/index.js +1 -1
  12. package/dist/realtime/index.js.map +1 -1
  13. package/dist/realtime-server/index.js +1 -1
  14. package/dist/realtime-server/index.js.map +1 -1
  15. package/dist/realtime-testing/index.js +1 -1
  16. package/dist/struct/index.d.ts +14 -0
  17. package/dist/struct/index.d.ts.map +1 -0
  18. package/dist/struct/index.js +35 -0
  19. package/dist/struct/index.js.map +1 -0
  20. package/dist/transceivers/o-list/index.d.ts +8 -4
  21. package/dist/transceivers/o-list/index.d.ts.map +1 -1
  22. package/dist/transceivers/o-list/index.js +2 -1
  23. package/dist/transceivers/o-list/index.js.map +1 -1
  24. package/dist/transceivers/set-rtx/index.d.ts +1 -0
  25. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  26. package/dist/transceivers/set-rtx/index.js.map +1 -1
  27. package/dist/transceivers/u-list/index.d.ts +12 -4
  28. package/dist/transceivers/u-list/index.d.ts.map +1 -1
  29. package/dist/transceivers/u-list/index.js +34 -2
  30. package/dist/transceivers/u-list/index.js.map +1 -1
  31. package/dist/utility-types-aZkJVERa.d.ts +10 -0
  32. package/dist/utility-types-aZkJVERa.d.ts.map +1 -0
  33. package/package.json +20 -16
  34. package/src/internal/atom/create-regular-atom.ts +3 -1
  35. package/src/internal/index.ts +0 -1
  36. package/src/internal/join/create-join.ts +8 -11
  37. package/src/internal/join/edit-relations-in-store.ts +6 -8
  38. package/src/internal/join/find-relations-in-store.ts +11 -67
  39. package/src/internal/join/get-internal-relations-from-store.ts +11 -5
  40. package/src/internal/join/get-join.ts +7 -9
  41. package/src/internal/join/join-internal.ts +143 -412
  42. package/src/internal/molecule.ts +44 -25
  43. package/src/internal/mutable/create-mutable-atom.ts +15 -11
  44. package/src/internal/mutable/transceiver.ts +1 -5
  45. package/src/internal/set-state/dispatch-state-update.ts +1 -1
  46. package/src/internal/store/store.ts +16 -15
  47. package/src/internal/transaction/build-transaction.ts +1 -1
  48. package/src/main/atom.ts +15 -6
  49. package/src/main/join.ts +68 -151
  50. package/src/main/realm.ts +58 -17
  51. package/src/realtime/shared-room-store.ts +5 -15
  52. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +1 -1
  53. package/src/struct/index.ts +1 -0
  54. package/src/{internal → struct}/micro.ts +1 -1
  55. package/src/transceivers/o-list/o-list.ts +13 -9
  56. package/src/transceivers/set-rtx/set-rtx.ts +4 -0
  57. package/src/transceivers/u-list/index.ts +1 -0
  58. package/src/transceivers/u-list/u-list-disposed-key-cleanup-effect.ts +47 -0
  59. package/src/transceivers/u-list/u-list.ts +13 -9
@@ -10,6 +10,7 @@ interface SetRTXView<P extends primitive> extends ReadonlySet<P> {
10
10
  readonly cacheLimit: number;
11
11
  readonly cacheIdx: number;
12
12
  readonly cacheUpdateNumber: number;
13
+ readonly subscribe: (key: string, fn: (update: NumberedSetUpdateString) => void) => () => void;
13
14
  }
14
15
  interface SetRTXJson<P extends primitive> extends Json.Object {
15
16
  members: P[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/transceivers/set-rtx/set-rtx.ts"],"sourcesContent":[],"mappings":";;;;KAKY,aAAA;AAAA,KACA,eAAA,GADA,GACqB,aADrB,IAAA,MAAA,EAAA;AACA,KACA,uBAAA,GADqB,GAAA,MAAA,GAAA,GAAA,IACwB,eADxB,EAAA;AACrB,UAEK,UAFL,CAAA,UAE0B,SAFmB,CAAA,SAEA,WAFA,CAEY,CAFZ,CAAA,CAAA;EAEzD,SAAiB,KAAA,EACA,aADA,CACc,uBADd,GAAA,IAAA,CAAA;EAAA,SAAA,UAAA,EAAA,MAAA;WAAqB,QAAA,EAAA,MAAA;WAA+B,iBAAA,EAAA,MAAA;;AACpD,UAMA,UANA,CAAA,UAMqB,SANrB,CAAA,SAMwC,IAAA,CAAK,MAN7C,CAAA;SADwC,EAQ/C,CAR+C,EAAA;EAAA,KAAA,EAAA,CAShD,uBATgD,GAAA,IAAA,CAAA,EAAA;EAOzD,UAAiB,EAAA,MAAA;EAAA,QAAA,EAAA,MAAA;mBAAqB,EAAA,MAAA;;AAE7B,cAKI,MALJ,CAAA,UAKqB,SALrB,CAAA,SAMA,GANA,CAMI,CANJ,CAAA,YAQP,WARO,CAQK,UARL,CAQgB,CARhB,CAAA,EAQoB,uBARpB,EAQ6C,UAR7C,CAQwD,CARxD,CAAA,CAAA,EASP,OATO,CAAA;QAWK,eAbgD;EAAA,SAAA,OAAA,EAcpC,OAdoC,CAc5B,eAd4B,CAAA;EAO9D,UAAa,EAAA,MAAA;EAAA,KAAA,EAAA,CAUG,uBAVH,GAAA,IAAA,CAAA,EAAA;UAAiB,EAAA,MAAA;mBACjB,EAAA,MAAA;aAEY,CAAA,MAAA,CAAA,EAWI,QAXJ,CAWa,CAXb,CAAA,EAAA,UAAA,CAAA,EAAA,MAAA;WAAX,aAAA,EA4BkB,UA5BlB,CA4B6B,CA5B7B,CAAA;QAAe,CAAA,CAAA,EA8BX,UA9BW,CA8BA,CA9BA,CAAA;SAAoC,QAAA,CAAA,UAwC/B,SAxC+B,CAAA,CAAA,IAAA,EAwCd,UAxCc,CAwCH,CAxCG,CAAA,CAAA,EAwCE,MAxCF,CAwCS,CAxCT,CAAA;WAAX,EAgDnC,CAhDmC,CAAA,EAAA,IAAA;SAGxC,EAAA,IAAA;QACoB,CAAA,KAAA,EA8DZ,CA9DY,CAAA,EAAA,OAAA;WAAR,MAAA,EAuED,MAvEC,CAuEM,CAvEN,CAAA,GAAA,IAAA;SAwEX,MArEC,CAqEM,CArEN,CAAA,GAAA,IAAA;oBAIsB,EAkEV,eAlEU,EAAA,GAAA,IAAA;aAAT,CAAA,GAAA,EAAA,CAAA,KAAA,EAmEI,MAnEJ,CAmEW,CAnEX,CAAA,EAAA,GAAA,OAAA,CAAA,EAAA,IAAA;YAiBc,UAAA,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAmF5B,eAnF4B,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;WAAX,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAyFjB,uBAzFiB,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;aAEH,EA8FR,eA9FQ,CAAA,EAAA,IAAA;UAAX,MAAA;iBAUgB,CAAA,MAAA,EA6GF,uBA7GE,CAAA,EAAA,MAAA;WAA4B,EAkH3C,uBAlH2C,CAAA,EAAA,MAAA,GAAA,cAAA,GAAA,IAAA;UAAX,CAAA,MAAA,EA6J1B,eA7J0B,CAAA,EAAA,IAAA;aAAuB,EAsLrD,uBAtLqD,CAAA,EAAA,MAAA,GAAA,IAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/transceivers/set-rtx/set-rtx.ts"],"sourcesContent":[],"mappings":";;;;KAKY,aAAA;AAAA,KACA,eAAA,GADA,GACqB,aADrB,IAAA,MAAA,EAAA;AACA,KACA,uBAAA,GADqB,GAAA,MAAA,GAAA,GAAA,IACwB,eADxB,EAAA;AACrB,UAEK,UAFL,CAAA,UAE0B,SAFmB,CAAA,SAEA,WAFA,CAEY,CAFZ,CAAA,CAAA;EAEzD,SAAiB,KAAA,EACA,aADA,CACc,uBADd,GAAA,IAAA,CAAA;EAAA,SAAA,UAAA,EAAA,MAAA;WAAqB,QAAA,EAAA,MAAA;WAA+B,iBAAA,EAAA,MAAA;WACtC,SAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAMhB,uBANgB,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,GAAA,IAAA;;AAMhB,UAIE,UAJF,CAAA,UAIuB,SAJvB,CAAA,SAI0C,IAAA,CAAK,MAJ/C,CAAA;SAP0C,EAY/C,CAZ+C,EAAA;EAAA,KAAA,EAAA,CAahD,uBAbgD,GAAA,IAAA,CAAA,EAAA;EAWzD,UAAiB,EAAA,MAAA;EAAA,QAAA,EAAA,MAAA;mBAAqB,EAAA,MAAA;;AAE7B,cAKI,MALJ,CAAA,UAKqB,SALrB,CAAA,SAMA,GANA,CAMI,CANJ,CAAA,YAQP,WARO,CAQK,UARL,CAQgB,CARhB,CAAA,EAQoB,uBARpB,EAQ6C,UAR7C,CAQwD,CARxD,CAAA,CAAA,EASP,OATO,CAAA;QAWK,eAbgD;EAAA,SAAA,OAAA,EAcpC,OAdoC,CAc5B,eAd4B,CAAA;EAO9D,UAAa,EAAA,MAAA;EAAA,KAAA,EAAA,CAUG,uBAVH,GAAA,IAAA,CAAA,EAAA;UAAiB,EAAA,MAAA;mBACjB,EAAA,MAAA;aAEY,CAAA,MAAA,CAAA,EAWI,QAXJ,CAWa,CAXb,CAAA,EAAA,UAAA,CAAA,EAAA,MAAA;WAAX,aAAA,EA4BkB,UA5BlB,CA4B6B,CA5B7B,CAAA;QAAe,CAAA,CAAA,EA8BX,UA9BW,CA8BA,CA9BA,CAAA;SAAoC,QAAA,CAAA,UAwC/B,SAxC+B,CAAA,CAAA,IAAA,EAwCd,UAxCc,CAwCH,CAxCG,CAAA,CAAA,EAwCE,MAxCF,CAwCS,CAxCT,CAAA;WAAX,EAgDnC,CAhDmC,CAAA,EAAA,IAAA;SAGxC,EAAA,IAAA;QACoB,CAAA,KAAA,EA8DZ,CA9DY,CAAA,EAAA,OAAA;WAAR,MAAA,EAuED,MAvEC,CAuEM,CAvEN,CAAA,GAAA,IAAA;SAwEX,MArEC,CAqEM,CArEN,CAAA,GAAA,IAAA;oBAIsB,EAkEV,eAlEU,EAAA,GAAA,IAAA;aAAT,CAAA,GAAA,EAAA,CAAA,KAAA,EAmEI,MAnEJ,CAmEW,CAnEX,CAAA,EAAA,GAAA,OAAA,CAAA,EAAA,IAAA;YAiBc,UAAA,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAmF5B,eAnF4B,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;WAAX,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAyFjB,uBAzFiB,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;aAEH,EA8FR,eA9FQ,CAAA,EAAA,IAAA;UAAX,MAAA;iBAUgB,CAAA,MAAA,EA6GF,uBA7GE,CAAA,EAAA,MAAA;WAA4B,EAkH3C,uBAlH2C,CAAA,EAAA,MAAA,GAAA,cAAA,GAAA,IAAA;UAAX,CAAA,MAAA,EA6J1B,eA7J0B,CAAA,EAAA,IAAA;aAAuB,EAsLrD,uBAtLqD,CAAA,EAAA,MAAA,GAAA,IAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/transceivers/set-rtx/set-rtx.ts"],"sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, primitive } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdateType = `add` | `clear` | `del` | `tx`\nexport type SetUpdateString = `${SetUpdateType}:${string}`\nexport type NumberedSetUpdateString = `${number | `*`}=${SetUpdateString}`\n\nexport interface SetRTXView<P extends primitive> extends ReadonlySet<P> {\n\treadonly cache: ReadonlyArray<NumberedSetUpdateString | null>\n\treadonly cacheLimit: number\n\treadonly cacheIdx: number\n\treadonly cacheUpdateNumber: number\n}\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdateString | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements\n\t\tTransceiver<SetRTXView<P>, NumberedSetUpdateString, SetRTXJson<P>>,\n\t\tLineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject: Subject<SetUpdateString> =\n\t\tnew Subject<SetUpdateString>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdateString | 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 readonly READONLY_VIEW: SetRTXView<P> = this\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 = null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdateString[] | 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\t/* eslint-disable-next-line no-console */\n\t\t\tconsole.warn(\n\t\t\t\t`Did not apply transaction to SetRTX; this error was thrown:`,\n\t\t\t\tthrown,\n\t\t\t)\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: SetUpdateString) => 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: NumberedSetUpdateString) => 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: SetUpdateString): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdateString): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak) as SetUpdateType\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(JSON.parse(value))\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(JSON.parse(value))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const subUpdate of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(subUpdate as SetUpdateString)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdateString): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdateString): 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 || Number.isNaN(eventOffset)) {\n\t\t\tif (eventOffset === 1 || Number.isNaN(eventOffset)) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdateString\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 u = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!u) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(u)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdateString\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: SetUpdateString): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint) as SetUpdateType\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(JSON.parse(value))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(JSON.parse(value))\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 v of values) this.add(v)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdateString[]\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: NumberedSetUpdateString): 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 SetUpdateString\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"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/transceivers/set-rtx/set-rtx.ts"],"sourcesContent":["import type { Lineage, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { Json, primitive } from \"atom.io/json\"\nimport { stringifyJson } from \"atom.io/json\"\n\nexport type SetUpdateType = `add` | `clear` | `del` | `tx`\nexport type SetUpdateString = `${SetUpdateType}:${string}`\nexport type NumberedSetUpdateString = `${number | `*`}=${SetUpdateString}`\n\nexport interface SetRTXView<P extends primitive> extends ReadonlySet<P> {\n\treadonly cache: ReadonlyArray<NumberedSetUpdateString | null>\n\treadonly cacheLimit: number\n\treadonly cacheIdx: number\n\treadonly cacheUpdateNumber: number\n\treadonly subscribe: (\n\t\tkey: string,\n\t\tfn: (update: NumberedSetUpdateString) => void,\n\t) => () => void\n}\n\nexport interface SetRTXJson<P extends primitive> extends Json.Object {\n\tmembers: P[]\n\tcache: (NumberedSetUpdateString | null)[]\n\tcacheLimit: number\n\tcacheIdx: number\n\tcacheUpdateNumber: number\n}\nexport class SetRTX<P extends primitive>\n\textends Set<P>\n\timplements\n\t\tTransceiver<SetRTXView<P>, NumberedSetUpdateString, SetRTXJson<P>>,\n\t\tLineage\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject: Subject<SetUpdateString> =\n\t\tnew Subject<SetUpdateString>()\n\tpublic cacheLimit = 0\n\tpublic cache: (NumberedSetUpdateString | 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 readonly READONLY_VIEW: SetRTXView<P> = this\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 = null\n\tpublic child: SetRTX<P> | null = null\n\tpublic transactionUpdates: SetUpdateString[] | 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\t/* eslint-disable-next-line no-console */\n\t\t\tconsole.warn(\n\t\t\t\t`Did not apply transaction to SetRTX; this error was thrown:`,\n\t\t\t\tthrown,\n\t\t\t)\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: SetUpdateString) => 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: NumberedSetUpdateString) => 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: SetUpdateString): void {\n\t\tthis.subject.next(update)\n\t}\n\n\tprivate doStep(update: SetUpdateString): void {\n\t\tconst typeValueBreak = update.indexOf(`:`)\n\t\tconst type = update.substring(0, typeValueBreak) as SetUpdateType\n\t\tconst value = update.substring(typeValueBreak + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(JSON.parse(value))\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(JSON.parse(value))\n\t\t\t\tbreak\n\t\t\tcase `tx`:\n\t\t\t\tfor (const subUpdate of value.split(`;`)) {\n\t\t\t\t\tthis.doStep(subUpdate as SetUpdateString)\n\t\t\t\t}\n\t\t}\n\t}\n\n\tpublic getUpdateNumber(update: NumberedSetUpdateString): number {\n\t\tconst breakpoint = update.indexOf(`=`)\n\t\treturn Number(update.substring(0, breakpoint))\n\t}\n\n\tpublic do(update: NumberedSetUpdateString): 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 || Number.isNaN(eventOffset)) {\n\t\t\tif (eventOffset === 1 || Number.isNaN(eventOffset)) {\n\t\t\t\tthis.mode = `playback`\n\t\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdateString\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 u = this.cache[this.cacheIdx]\n\t\t\t\tthis.cacheIdx--\n\t\t\t\tif (!u) {\n\t\t\t\t\treturn `OUT_OF_RANGE`\n\t\t\t\t}\n\t\t\t\tthis.undo(u)\n\t\t\t\tdone = this.cacheIdx === eventIdx - 1\n\t\t\t}\n\t\t\tconst innerUpdate = update.substring(breakpoint + 1) as SetUpdateString\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: SetUpdateString): void {\n\t\tconst breakpoint = update.indexOf(`:`)\n\t\tconst type = update.substring(0, breakpoint) as SetUpdateType\n\t\tconst value = update.substring(breakpoint + 1)\n\t\tswitch (type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(JSON.parse(value))\n\t\t\t\tbreak\n\t\t\tcase `del`:\n\t\t\t\tthis.add(JSON.parse(value))\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 v of values) this.add(v)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase `tx`: {\n\t\t\t\tconst updates = value.split(`;`) as SetUpdateString[]\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: NumberedSetUpdateString): 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 SetUpdateString\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"],"mappings":";;;;AA2BA,IAAa,SAAb,MAAa,eACJ,IAIT;CACC,AAAO,OAAwB;CAC/B,AAAgB,UACf,IAAI,SAA0B;CAC/B,AAAO,aAAa;CACpB,AAAO,QAA4C,EAAE;CACrD,AAAO,WAAW;CAClB,AAAO,oBAAoB;CAE3B,AAAO,YAAY,QAAsB,aAAa,GAAG;AACxD,QAAM,OAAO;AACb,MAAI,kBAAkB,QAAQ;AAC7B,QAAK,SAAS;AACd,QAAK,oBAAoB,OAAO;;AAEjC,MAAI,YAAY;AACf,QAAK,aAAa;AAClB,QAAK,QAAQ,IAAI,MAAM,WAAW;AAClC,QAAK,UAAU,eAAe,WAAW;AACxC,SAAK;AACL,SAAK,YAAY,KAAK;AACtB,SAAK,MAAM,KAAK,YAAY;KAC3B;;;CAIJ,AAAgB,gBAA+B;CAE/C,AAAO,SAAwB;AAC9B,SAAO;GACN,SAAS,CAAC,GAAG,KAAK;GAClB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU,KAAK;GACf,mBAAmB,KAAK;GACxB;;CAGF,OAAc,SAA8B,MAAgC;EAC3E,MAAM,MAAM,IAAI,OAAU,KAAK,SAAS,KAAK,WAAW;AACxD,MAAI,QAAQ,KAAK;AACjB,MAAI,WAAW,KAAK;AACpB,MAAI,oBAAoB,KAAK;AAC7B,SAAO;;CAGR,AAAO,IAAI,OAAgB;EAC1B,MAAM,SAAS,MAAM,IAAI,MAAM;AAC/B,MAAI,KAAK,SAAS,UAAU;AAC3B,QAAK;AACL,QAAK,KAAK,OAAO,cAAiB,MAAM,GAAG;;AAE5C,SAAO;;CAGR,AAAO,QAAc;EACpB,MAAM,mBAAmB,KAAK,SAAS,WAAW,CAAC,GAAG,KAAK,GAAG;AAC9D,QAAM,OAAO;AACb,MAAI,kBAAkB;AACrB,QAAK;AACL,QAAK,KAAK,SAAS,KAAK,UAAU,iBAAiB,GAAG;;;CAIxD,AAAO,OAAO,OAAmB;EAChC,MAAM,SAAS,MAAM,OAAO,MAAM;AAClC,MAAI,KAAK,SAAS,UAAU;AAC3B,QAAK;AACL,QAAK,KAAK,OAAO,cAAiB,MAAM,GAAG;;AAE5C,SAAO;;CAGR,AAAgB,SAA2B;CAC3C,AAAO,QAA0B;CACjC,AAAO,qBAA+C;CACtD,AAAO,YAAY,KAA0C;AAC5D,OAAK,OAAO;AACZ,OAAK,qBAAqB,EAAE;AAC5B,OAAK,QAAQ,IAAI,OAAO,KAAK;EAC7B,MAAM,cAAc,KAAK,MAAM,WAAW,gBAAgB,WAAW;AACpE,QAAK,oBAAoB,KAAK,OAAO;IACpC;AACF,MAAI;AAEH,OADqB,IAAI,KAAK,MAAM,EAClB;AACjB,SAAK,MAAM,UAAU,KAAK,mBACzB,MAAK,OAAO,OAAO;AAEpB,SAAK;AACL,SAAK,KAAK,MAAM,KAAK,mBAAmB,KAAK,IAAI,GAAG;;WAE7C,QAAQ;AAEhB,WAAQ,KACP,+DACA,OACA;AACD,SAAM;YACG;AACT,gBAAa;AACb,QAAK,QAAQ;AACb,QAAK,qBAAqB;AAC1B,QAAK,OAAO;;;CAId,AAAU,WACT,KACA,IACa;AACb,SAAO,KAAK,QAAQ,UAAU,KAAK,GAAG;;CAEvC,AAAO,UACN,KACA,IACa;AACb,SAAO,KAAK,QAAQ,UAAU,MAAM,WAAW;AAC9C,MAAG,GAAG,KAAK,kBAAkB,GAAG,SAAS;IACxC;;CAGH,AAAO,KAAK,QAA+B;AAC1C,OAAK,QAAQ,KAAK,OAAO;;CAG1B,AAAQ,OAAO,QAA+B;EAC7C,MAAM,iBAAiB,OAAO,QAAQ,IAAI;EAC1C,MAAM,OAAO,OAAO,UAAU,GAAG,eAAe;EAChD,MAAM,QAAQ,OAAO,UAAU,iBAAiB,EAAE;AAClD,UAAQ,MAAR;GACC,KAAK;AACJ,SAAK,IAAI,KAAK,MAAM,MAAM,CAAC;AAC3B;GACD,KAAK;AACJ,SAAK,OAAO;AACZ;GACD,KAAK;AACJ,SAAK,OAAO,KAAK,MAAM,MAAM,CAAC;AAC9B;GACD,KAAK,KACJ,MAAK,MAAM,aAAa,MAAM,MAAM,IAAI,CACvC,MAAK,OAAO,UAA6B;;;CAK7C,AAAO,gBAAgB,QAAyC;EAC/D,MAAM,aAAa,OAAO,QAAQ,IAAI;AACtC,SAAO,OAAO,OAAO,UAAU,GAAG,WAAW,CAAC;;CAG/C,AAAO,GAAG,QAAiE;EAC1E,MAAM,aAAa,OAAO,QAAQ,IAAI;EACtC,MAAM,eAAe,OAAO,OAAO,UAAU,GAAG,WAAW,CAAC;EAC5D,MAAM,cAAc,eAAe,KAAK;AAExC,MADiB,cAAc,KACf,OAAO,MAAM,YAAY,EAAE;AAC1C,OAAI,gBAAgB,KAAK,OAAO,MAAM,YAAY,EAAE;AACnD,SAAK,OAAO;IACZ,MAAM,cAAc,OAAO,UAAU,aAAa,EAAE;AACpD,SAAK,OAAO,YAAY;AACxB,SAAK,OAAO;AACZ,SAAK,oBAAoB;AACzB,WAAO;;AAER,UAAO,KAAK,oBAAoB;;AAEjC,MAAI,KAAK,IAAI,YAAY,GAAG,KAAK,YAAY;GAC5C,MAAM,WAAW,KAAK,WAAW;AAEjC,OADqB,KAAK,MAAM,cACX,OACpB,QAAO;AAER,QAAK,OAAO;GACZ,IAAI,OAAO;AACX,UAAO,CAAC,MAAM;AACb,SAAK,YAAY,KAAK;IACtB,MAAM,IAAI,KAAK,MAAM,KAAK;AAC1B,SAAK;AACL,QAAI,CAAC,EACJ,QAAO;AAER,SAAK,KAAK,EAAE;AACZ,WAAO,KAAK,aAAa,WAAW;;GAErC,MAAM,cAAc,OAAO,UAAU,aAAa,EAAE;AACpD,QAAK,OAAO,YAAY;AACxB,QAAK,OAAO;AACZ,QAAK,oBAAoB;AACzB,UAAO;;AAER,SAAO;;CAGR,AAAO,SAAS,QAA+B;EAC9C,MAAM,aAAa,OAAO,QAAQ,IAAI;EACtC,MAAM,OAAO,OAAO,UAAU,GAAG,WAAW;EAC5C,MAAM,QAAQ,OAAO,UAAU,aAAa,EAAE;AAC9C,UAAQ,MAAR;GACC,KAAK;AACJ,SAAK,OAAO,KAAK,MAAM,MAAM,CAAC;AAC9B;GACD,KAAK;AACJ,SAAK,IAAI,KAAK,MAAM,MAAM,CAAC;AAC3B;GACD,KAAK,SAAS;IACb,MAAM,SAAS,KAAK,MAAM,MAAM;AAChC,SAAK,MAAM,KAAK,OAAQ,MAAK,IAAI,EAAE;AACnC;;GAED,KAAK,MAAM;IACV,MAAM,UAAU,MAAM,MAAM,IAAI;AAChC,SAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,IACxC,MAAK,SAAS,QAAQ,GAAG;;;;CAM7B,AAAO,KAAK,QAAgD;EAC3D,MAAM,aAAa,OAAO,QAAQ,IAAI;AAEtC,MADqB,OAAO,OAAO,UAAU,GAAG,WAAW,CAAC,KACvC,KAAK,mBAAmB;AAC5C,QAAK,OAAO;GACZ,MAAM,cAAc,OAAO,UAAU,aAAa,EAAE;AACpD,QAAK,SAAS,YAAY;AAC1B,QAAK,OAAO;AACZ,QAAK;AACL,UAAO;;AAER,SAAO,KAAK"}
@@ -1,5 +1,7 @@
1
- import { Enumeration, Fn, Subject, Transceiver, TransceiverMode } from "atom.io/internal";
1
+ import { Fn, Subject, Transceiver, TransceiverMode } from "atom.io/internal";
2
+ import { AtomEffect } from "atom.io";
2
3
  import { primitive } from "atom.io/json";
4
+ import { Enumeration } from "atom.io/struct";
3
5
 
4
6
  //#region src/transceivers/u-list/u-list.d.ts
5
7
  type SetMutations = Exclude<keyof Set<any>, symbol | keyof ReadonlySet<any>>;
@@ -16,11 +18,14 @@ type PackedSetUpdate<P extends primitive> = string & {
16
18
  };
17
19
  declare const SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]>;
18
20
  type SetMutationHandler = { [K in UListUpdateType]: Fn };
19
- declare class UList<P extends primitive> extends Set<P> implements Transceiver<ReadonlySet<P>, PackedSetUpdate<P>, ReadonlyArray<P>>, SetMutationHandler {
21
+ type UListView<P extends primitive> = ReadonlySet<P> & {
22
+ subscribe: (key: string, fn: (update: PackedSetUpdate<P>) => void) => () => void;
23
+ };
24
+ declare class UList<P extends primitive> extends Set<P> implements Transceiver<UListView<P>, PackedSetUpdate<P>, ReadonlyArray<P>>, SetMutationHandler {
20
25
  mode: TransceiverMode;
21
26
  readonly subject: Subject<PackedSetUpdate<P>>;
22
27
  constructor(values?: Iterable<P>);
23
- readonly READONLY_VIEW: ReadonlySet<P>;
28
+ readonly READONLY_VIEW: UListView<P>;
24
29
  toJSON(): ReadonlyArray<P>;
25
30
  static fromJSON<P extends primitive>(json: ReadonlyArray<P>): UList<P>;
26
31
  add(value: P): this;
@@ -34,5 +39,8 @@ declare class UList<P extends primitive> extends Set<P> implements Transceiver<R
34
39
  static unpackUpdate<P extends primitive>(packed: PackedSetUpdate<P>): SetUpdate<P>;
35
40
  }
36
41
  //#endregion
37
- export { PackedSetUpdate, SET_UPDATE_ENUM, SetMutationHandler, SetMutations, SetUpdate, UList, UListUpdateType };
42
+ //#region src/transceivers/u-list/u-list-disposed-key-cleanup-effect.d.ts
43
+ declare const uListDisposedKeyCleanupEffect: AtomEffect<UList<primitive>>;
44
+ //#endregion
45
+ export { PackedSetUpdate, SET_UPDATE_ENUM, SetMutationHandler, SetMutations, SetUpdate, UList, UListUpdateType, UListView, uListDisposedKeyCleanupEffect };
38
46
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]>"],"sources":["../../../src/transceivers/u-list/u-list.ts"],"sourcesContent":[],"mappings":";;;;KASY,YAAA,GAAe,cACpB,yBACS;AAFJ,KAIA,SAJA,CAAA,UAIoB,SAJpB,CAAA,GAAA;EAAA,IAAA,EAAA,KAAA,GAAA,QAAA;SAOF,CANH;;QADoB,OAAA;EAAA,MAAA,EAWhB,CAXgB,EAAA;AAI3B,CAAA;AAAY,KASA,eAAA,GAAkB,SATlB,CAAA,GAAA,CAAA,CAAA,MAAA,CAAA;AAAoB,KAcpB,eAdoB,CAAA,UAcM,SAdN,CAAA,GAAA,MAAA,GAAA;QAGtB,CAAA,EAYA,SAZA,CAYU,CAZV,CAAA;;AAIC,cAWEA,eAXF,EAWmB,WAXnB,CAAA,CAAA,KAAA,EAAA,QAAA,EAAA,OAAA,CAAA,CAAA;AAEC,KAYA,kBAAA,GAZkB,QAYW,eAZX,GAY6B,EAZ7B,EAAA;AAKlB,cASC,KATD,CAAA,UASiB,SATjB,CAAA,SAUH,GAVG,CAUC,CAVD,CAAA,YAYV,WAZU,CAYE,WAZF,CAYc,CAZd,CAAA,EAYkB,eAZlB,CAYkC,CAZlC,CAAA,EAYsC,aAZtC,CAYoD,CAZpD,CAAA,CAAA,EAaV,kBAbU,CAAA;EAAA,IAAA,EAeE,eAfF;WAA0B,OAAA,EAgBZ,OAhBY,CAgBJ,eAhBI,CAgBY,CAhBZ,CAAA,CAAA;aAClB,CAAA,MAAA,CAAA,EAiBS,QAjBT,CAiBkB,CAjBlB,CAAA;WAAV,aAAA,EAuBsB,WAvBtB,CAuBkC,CAvBlC,CAAA;EAAA,MAAA,CAAA,CAAA,EAyBQ,aAzBR,CAyBsB,CAzBtB,CAAA;EAGV,OAAaA,QAAAA,CAAAA,UA0BqB,SA1BJ,CAAA,CAAA,IAAA,EA0BqB,aA1BrB,CA0BmC,CA1BnC,CAAA,CAAA,EA0BwC,KA1BxC,CA0B8C,CA1B9C,CAAA;EAG9B,GAAY,CAAA,KAAA,EA2BO,CA3BP,CAAA,EAAA,IAAA;EAAA,KAAA,CAAA,CAAA,EAAA,IAAA;QAA6B,CAAA,KAAA,EA2CnB,CA3CmB,CAAA,EAAA,OAAA;WAAkB,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAqD5C,eArD4C,CAqD5B,CArD4B,CAAA,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,IAAA,CAAA,MAAA,EA0DtC,SA1DsC,CA0D5B,CA1D4B,CAAA,CAAA,EAAA,IAAA;EAE3D,EAAA,CAAa,MAAA,EA4DM,eA5DN,CA4DsB,CA5DtB,CAAA,CAAA,EAAA,IAAA;EAAA,IAAA,CAAA,MAAA,EA6EQ,eA7ER,CA6EwB,CA7ExB,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;SAAgB,UAAA,CAAA,UAgGO,SAhGP,CAAA,CAAA,MAAA,EAiGnB,SAjGmB,CAiGT,CAjGS,CAAA,CAAA,EAkGzB,eAlGyB,CAkGT,CAlGS,CAAA;SAChB,YAAA,CAAA,UAwGyB,SAxGzB,CAAA,CAAA,MAAA,EAyGH,eAzGG,CAyGa,CAzGb,CAAA,CAAA,EA0GT,SA1GS,CA0GC,CA1GD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":["SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]>","uListDisposedKeyCleanupEffect: AtomEffect<UList<primitive>>"],"sources":["../../../src/transceivers/u-list/u-list.ts","../../../src/transceivers/u-list/u-list-disposed-key-cleanup-effect.ts"],"sourcesContent":[],"mappings":";;;;;;KAMY,YAAA,GAAe,cACpB,yBACS;KAEJ,oBAAoB;EAJhC,IAAY,EAAA,KAAA,GAAA,QAAA;EAAA,KAAA,EAOF,CAPE;;QAEI,OAAA;QAFW,EAWhB,CAXgB,EAAA;CAAA;AAIf,KASA,eAAA,GAAkB,SATlB,CAAA,GAAA,CAAA,CAAA,MAAA,CAAA;AAAA,KAcA,eAdA,CAAA,UAc0B,SAd1B,CAAA,GAAA,MAAA,GAAA;QAAoB,CAAA,EAetB,SAfsB,CAeZ,CAfY,CAAA;;AAOrB,cAWEA,eAXF,EAWmB,WAXnB,CAAA,CAAA,KAAA,EAAA,QAAA,EAAA,OAAA,CAAA,CAAA;AAAA,KAcC,kBAAA,GAdD,QAc8B,eAd9B,GAcgD,EAdhD,EAAA;AAEC,KAcA,SAdA,CAAA,UAcoB,SAdF,CAAA,GAce,WAdf,CAc2B,CAd3B,CAAA,GAAA;EAK9B,SAAY,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EAYG,eAZH,CAYmB,CAZnB,CAAA,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,GAAA,IAAA;CAAA;AAA0B,cAgBzB,KAhByB,CAAA,UAgBT,SAhBS,CAAA,SAiB7B,GAjB6B,CAiBzB,CAjByB,CAAA,YAmBpC,WAnBoC,CAmBxB,SAnBwB,CAmBd,CAnBc,CAAA,EAmBV,eAnBU,CAmBM,CAnBN,CAAA,EAmBU,aAnBV,CAmBwB,CAnBxB,CAAA,CAAA,EAoBpC,kBApBoC,CAAA;QAsBxB,eArBM;WAAV,OAAA,EAsBgB,OAtBhB,CAsBwB,eAtBxB,CAsBwC,CAtBxC,CAAA,CAAA;EAAA,WAAA,CAAA,MAAA,CAAA,EAwBmB,QAxBnB,CAwB4B,CAxB5B,CAAA;EAGV,SAAaA,aAA+C,EA2B5B,SA3BF,CA2BY,CA3BZ,CAAA;EAG9B,MAAY,CAAA,CAAA,EA0BM,aA1BN,CA0BoB,CA1BpB,CAAA;EAAA,OAAA,QAAA,CAAA,UA8BsB,SA9BtB,CAAA,CAAA,IAAA,EA8BuC,aA9BvC,CA8BqD,CA9BrD,CAAA,CAAA,EA8B0D,KA9B1D,CA8BgE,CA9BhE,CAAA;WAA6B,EAkCtB,CAlCsB,CAAA,EAAA,IAAA;SAAkB,EAAA,IAAA;EAAA,MAAA,CAAA,KAAA,EAkDrC,CAlDqC,CAAA,EAAA,OAAA;EAE3D,SAAY,CAAA,GAAA,EAAA,MAAA,EAAA,EAAA,EAAA,CAAA,MAAA,EA0DG,eA1DH,CA0DmB,CA1DnB,CAAA,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,IAAA,CAAA,MAAA,EA+DS,SA/DT,CA+DmB,CA/DnB,CAAA,CAAA,EAAA,IAAA;WAAoB,EAmEb,eAnEa,CAmEG,CAnEH,CAAA,CAAA,EAAA,IAAA;aAAyB,EAoFpC,eApFoC,CAoFpB,CApFoB,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;SAAZ,UAAA,CAAA,UAuGT,SAvGS,CAAA,CAAA,MAAA,EAwGnC,SAxGmC,CAwGzB,CAxGyB,CAAA,CAAA,EAyGzC,eAzGyC,CAyGzB,CAzGyB,CAAA;SAGd,YAAA,CAAA,UA6GO,SA7GP,CAAA,CAAA,MAAA,EA8GrB,eA9GqB,CA8GL,CA9GK,CAAA,CAAA,EA+G3B,SA/G2B,CA+GjB,CA/GiB,CAAA;;;;cC9BlBC,+BAA+B,WAAW,MAAM"}
@@ -1,4 +1,6 @@
1
- import { Subject, enumeration, packValue, unpackValue } from "atom.io/internal";
1
+ import { Subject, getUpdateToken, subscribeInStore } from "atom.io/internal";
2
+ import { stringifyJson } from "atom.io/json";
3
+ import { enumeration, packValue, unpackValue } from "atom.io/struct";
2
4
 
3
5
  //#region src/transceivers/u-list/u-list.ts
4
6
  const SET_UPDATE_ENUM = enumeration([
@@ -103,5 +105,35 @@ var UList = class UList extends Set {
103
105
  };
104
106
 
105
107
  //#endregion
106
- export { SET_UPDATE_ENUM, UList };
108
+ //#region src/transceivers/u-list/u-list-disposed-key-cleanup-effect.ts
109
+ const uListDisposedKeyCleanupEffect = ({ token, setSelf, store }) => {
110
+ const disposalSubscriptions = /* @__PURE__ */ new Map();
111
+ const updateToken = getUpdateToken(token);
112
+ subscribeInStore(store, updateToken, function setAutoDeletionTriggers({ newValue }) {
113
+ const unpacked = UList.unpackUpdate(newValue);
114
+ switch (unpacked.type) {
115
+ case `add`:
116
+ {
117
+ const molecule = store.molecules.get(stringifyJson(unpacked.value));
118
+ if (molecule) disposalSubscriptions.set(unpacked.value, molecule.subject.subscribe(token.key, () => {
119
+ setSelf((self) => {
120
+ self.delete(unpacked.value);
121
+ return self;
122
+ });
123
+ }));
124
+ }
125
+ break;
126
+ case `delete`:
127
+ disposalSubscriptions.get(unpacked.value)?.();
128
+ disposalSubscriptions.delete(unpacked.value);
129
+ break;
130
+ case `clear`:
131
+ for (const unsub of disposalSubscriptions.values()) unsub();
132
+ disposalSubscriptions.clear();
133
+ }
134
+ }, `set-auto-deletion-triggers`);
135
+ };
136
+
137
+ //#endregion
138
+ export { SET_UPDATE_ENUM, UList, uListDisposedKeyCleanupEffect };
107
139
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]>"],"sources":["../../../src/transceivers/u-list/u-list.ts"],"sourcesContent":["import type {\n\tEnumeration,\n\tFn,\n\tTransceiver,\n\tTransceiverMode,\n} from \"atom.io/internal\"\nimport { enumeration, packValue, Subject, unpackValue } from \"atom.io/internal\"\nimport type { primitive } from \"atom.io/json\"\n\nexport type SetMutations = Exclude<\n\tkeyof Set<any>,\n\tsymbol | keyof ReadonlySet<any>\n>\nexport type SetUpdate<P extends primitive> =\n\t| {\n\t\t\ttype: `add` | `delete`\n\t\t\tvalue: P\n\t }\n\t| {\n\t\t\ttype: `clear`\n\t\t\tvalues: P[]\n\t }\nexport type UListUpdateType = SetUpdate<any>[`type`]\ntrue satisfies SetMutations extends UListUpdateType\n\t? true\n\t: Exclude<SetMutations, UListUpdateType>\n\nexport type PackedSetUpdate<P extends primitive> = string & {\n\tupdate?: SetUpdate<P>\n}\n\nexport const SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]> =\n\tenumeration([`add`, `delete`, `clear`] as const)\n\nexport type SetMutationHandler = { [K in UListUpdateType]: Fn }\n\nexport class UList<P extends primitive>\n\textends Set<P>\n\timplements\n\t\tTransceiver<ReadonlySet<P>, PackedSetUpdate<P>, ReadonlyArray<P>>,\n\t\tSetMutationHandler\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject: Subject<PackedSetUpdate<P>> = new Subject()\n\n\tpublic constructor(values?: Iterable<P>) {\n\t\tsuper(values)\n\t\tif (values instanceof UList) {\n\t\t}\n\t}\n\n\tpublic readonly READONLY_VIEW: ReadonlySet<P> = this\n\n\tpublic toJSON(): ReadonlyArray<P> {\n\t\treturn [...this]\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: ReadonlyArray<P>): UList<P> {\n\t\treturn new UList<P>(json)\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.emit({ type: `add`, 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.emit({ type: `clear`, values: 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.emit({ type: `delete`, value })\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: PackedSetUpdate<P>) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\n\tpublic emit(update: SetUpdate<P>): void {\n\t\tthis.subject.next(UList.packUpdate(update))\n\t}\n\n\tpublic do(packed: PackedSetUpdate<P>): null {\n\t\tthis.mode = `playback`\n\t\tconst update = UList.unpackUpdate(packed)\n\t\tswitch (update.type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(update.value)\n\t\t\t\tbreak\n\t\t\tcase `delete`:\n\t\t\t\tthis.delete(update.value)\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t}\n\t\tthis.mode = `record`\n\t\treturn null\n\t}\n\n\tpublic undo(packed: PackedSetUpdate<P>): number | null {\n\t\tconst update = UList.unpackUpdate(packed)\n\t\tthis.mode = `playback`\n\t\tswitch (update.type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(update.value)\n\t\t\t\tbreak\n\t\t\tcase `delete`:\n\t\t\t\tthis.add(update.value)\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = update.values\n\t\t\t\tfor (const v of values) this.add(v)\n\t\t\t}\n\t\t}\n\t\tthis.mode = `record`\n\t\treturn null\n\t}\n\n\tpublic static packUpdate<P extends primitive>(\n\t\tupdate: SetUpdate<P>,\n\t): PackedSetUpdate<P> {\n\t\tconst head = SET_UPDATE_ENUM[update.type] + `\\u001F`\n\t\tif (update.type === `clear`) {\n\t\t\treturn head + update.values.map(packValue).join(`\\u001E`)\n\t\t}\n\t\treturn head + packValue(update.value)\n\t}\n\tpublic static unpackUpdate<P extends primitive>(\n\t\tpacked: PackedSetUpdate<P>,\n\t): SetUpdate<P> {\n\t\tconst [type, tail] = packed.split(`\\u001F`) as [0 | 1 | 2, string]\n\t\tconst head = SET_UPDATE_ENUM[type]\n\t\tif (head === `clear`) {\n\t\t\tconst values = tail.split(`\\u001E`).map(unpackValue) as P[]\n\t\t\treturn { type: `clear`, values }\n\t\t}\n\t\treturn { type: head, value: unpackValue(tail) as P }\n\t}\n}\n"],"mappings":";;;AA+BA,MAAaA,kBACZ,YAAY;CAAC;CAAO;CAAU;CAAQ,CAAU;AAIjD,IAAa,QAAb,MAAa,cACJ,IAIT;CACC,AAAO,OAAwB;CAC/B,AAAgB,UAAuC,IAAI,SAAS;CAEpE,AAAO,YAAY,QAAsB;AACxC,QAAM,OAAO;AACb,MAAI,kBAAkB,OAAO;;CAI9B,AAAgB,gBAAgC;CAEhD,AAAO,SAA2B;AACjC,SAAO,CAAC,GAAG,KAAK;;CAGjB,OAAc,SAA8B,MAAkC;AAC7E,SAAO,IAAI,MAAS,KAAK;;CAG1B,AAAO,IAAI,OAAgB;EAC1B,MAAM,SAAS,MAAM,IAAI,MAAM;AAC/B,MAAI,KAAK,SAAS,SACjB,MAAK,KAAK;GAAE,MAAM;GAAO;GAAO,CAAC;AAElC,SAAO;;CAGR,AAAO,QAAc;EACpB,MAAM,mBAAmB,KAAK,SAAS,WAAW,CAAC,GAAG,KAAK,GAAG;AAC9D,QAAM,OAAO;AACb,MAAI,iBACH,MAAK,KAAK;GAAE,MAAM;GAAS,QAAQ;GAAkB,CAAC;;CAIxD,AAAO,OAAO,OAAmB;EAChC,MAAM,SAAS,MAAM,OAAO,MAAM;AAClC,MAAI,KAAK,SAAS,SACjB,MAAK,KAAK;GAAE,MAAM;GAAU;GAAO,CAAC;AAErC,SAAO;;CAGR,AAAO,UACN,KACA,IACa;AACb,SAAO,KAAK,QAAQ,UAAU,KAAK,GAAG;;CAGvC,AAAO,KAAK,QAA4B;AACvC,OAAK,QAAQ,KAAK,MAAM,WAAW,OAAO,CAAC;;CAG5C,AAAO,GAAG,QAAkC;AAC3C,OAAK,OAAO;EACZ,MAAM,SAAS,MAAM,aAAa,OAAO;AACzC,UAAQ,OAAO,MAAf;GACC,KAAK;AACJ,SAAK,IAAI,OAAO,MAAM;AACtB;GACD,KAAK;AACJ,SAAK,OAAO,OAAO,MAAM;AACzB;GACD,KAAK,QACJ,MAAK,OAAO;;AAEd,OAAK,OAAO;AACZ,SAAO;;CAGR,AAAO,KAAK,QAA2C;EACtD,MAAM,SAAS,MAAM,aAAa,OAAO;AACzC,OAAK,OAAO;AACZ,UAAQ,OAAO,MAAf;GACC,KAAK;AACJ,SAAK,OAAO,OAAO,MAAM;AACzB;GACD,KAAK;AACJ,SAAK,IAAI,OAAO,MAAM;AACtB;GACD,KAAK,SAAS;IACb,MAAM,SAAS,OAAO;AACtB,SAAK,MAAM,KAAK,OAAQ,MAAK,IAAI,EAAE;;;AAGrC,OAAK,OAAO;AACZ,SAAO;;CAGR,OAAc,WACb,QACqB;EACrB,MAAM,OAAO,gBAAgB,OAAO,QAAQ;AAC5C,MAAI,OAAO,SAAS,QACnB,QAAO,OAAO,OAAO,OAAO,IAAI,UAAU,CAAC,KAAK,SAAS;AAE1D,SAAO,OAAO,UAAU,OAAO,MAAM;;CAEtC,OAAc,aACb,QACe;EACf,MAAM,CAAC,MAAM,QAAQ,OAAO,MAAM,SAAS;EAC3C,MAAM,OAAO,gBAAgB;AAC7B,MAAI,SAAS,QAEZ,QAAO;GAAE,MAAM;GAAS,QADT,KAAK,MAAM,SAAS,CAAC,IAAI,YAAY;GACpB;AAEjC,SAAO;GAAE,MAAM;GAAM,OAAO,YAAY,KAAK;GAAO"}
1
+ {"version":3,"file":"index.js","names":["SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]>","uListDisposedKeyCleanupEffect: AtomEffect<UList<primitive>>"],"sources":["../../../src/transceivers/u-list/u-list.ts","../../../src/transceivers/u-list/u-list-disposed-key-cleanup-effect.ts"],"sourcesContent":["import type { Fn, Transceiver, TransceiverMode } from \"atom.io/internal\"\nimport { Subject } from \"atom.io/internal\"\nimport type { primitive } from \"atom.io/json\"\nimport type { Enumeration } from \"atom.io/struct\"\nimport { enumeration, packValue, unpackValue } from \"atom.io/struct\"\n\nexport type SetMutations = Exclude<\n\tkeyof Set<any>,\n\tsymbol | keyof ReadonlySet<any>\n>\nexport type SetUpdate<P extends primitive> =\n\t| {\n\t\t\ttype: `add` | `delete`\n\t\t\tvalue: P\n\t }\n\t| {\n\t\t\ttype: `clear`\n\t\t\tvalues: P[]\n\t }\nexport type UListUpdateType = SetUpdate<any>[`type`]\ntrue satisfies SetMutations extends UListUpdateType\n\t? true\n\t: Exclude<SetMutations, UListUpdateType>\n\nexport type PackedSetUpdate<P extends primitive> = string & {\n\tupdate?: SetUpdate<P>\n}\n\nexport const SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]> =\n\tenumeration([`add`, `delete`, `clear`] as const)\n\nexport type SetMutationHandler = { [K in UListUpdateType]: Fn }\n\nexport type UListView<P extends primitive> = ReadonlySet<P> & {\n\tsubscribe: (\n\t\tkey: string,\n\t\tfn: (update: PackedSetUpdate<P>) => void,\n\t) => () => void\n}\n\nexport class UList<P extends primitive>\n\textends Set<P>\n\timplements\n\t\tTransceiver<UListView<P>, PackedSetUpdate<P>, ReadonlyArray<P>>,\n\t\tSetMutationHandler\n{\n\tpublic mode: TransceiverMode = `record`\n\tpublic readonly subject: Subject<PackedSetUpdate<P>> = new Subject()\n\n\tpublic constructor(values?: Iterable<P>) {\n\t\tsuper(values)\n\t\tif (values instanceof UList) {\n\t\t}\n\t}\n\n\tpublic readonly READONLY_VIEW: UListView<P> = this\n\n\tpublic toJSON(): ReadonlyArray<P> {\n\t\treturn [...this]\n\t}\n\n\tpublic static fromJSON<P extends primitive>(json: ReadonlyArray<P>): UList<P> {\n\t\treturn new UList<P>(json)\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.emit({ type: `add`, 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.emit({ type: `clear`, values: 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.emit({ type: `delete`, value })\n\t\t}\n\t\treturn result\n\t}\n\n\tpublic subscribe(\n\t\tkey: string,\n\t\tfn: (update: PackedSetUpdate<P>) => void,\n\t): () => void {\n\t\treturn this.subject.subscribe(key, fn)\n\t}\n\n\tpublic emit(update: SetUpdate<P>): void {\n\t\tthis.subject.next(UList.packUpdate(update))\n\t}\n\n\tpublic do(packed: PackedSetUpdate<P>): null {\n\t\tthis.mode = `playback`\n\t\tconst update = UList.unpackUpdate(packed)\n\t\tswitch (update.type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.add(update.value)\n\t\t\t\tbreak\n\t\t\tcase `delete`:\n\t\t\t\tthis.delete(update.value)\n\t\t\t\tbreak\n\t\t\tcase `clear`:\n\t\t\t\tthis.clear()\n\t\t}\n\t\tthis.mode = `record`\n\t\treturn null\n\t}\n\n\tpublic undo(packed: PackedSetUpdate<P>): number | null {\n\t\tconst update = UList.unpackUpdate(packed)\n\t\tthis.mode = `playback`\n\t\tswitch (update.type) {\n\t\t\tcase `add`:\n\t\t\t\tthis.delete(update.value)\n\t\t\t\tbreak\n\t\t\tcase `delete`:\n\t\t\t\tthis.add(update.value)\n\t\t\t\tbreak\n\t\t\tcase `clear`: {\n\t\t\t\tconst values = update.values\n\t\t\t\tfor (const v of values) this.add(v)\n\t\t\t}\n\t\t}\n\t\tthis.mode = `record`\n\t\treturn null\n\t}\n\n\tpublic static packUpdate<P extends primitive>(\n\t\tupdate: SetUpdate<P>,\n\t): PackedSetUpdate<P> {\n\t\tconst head = SET_UPDATE_ENUM[update.type] + `\\u001F`\n\t\tif (update.type === `clear`) {\n\t\t\treturn head + update.values.map(packValue).join(`\\u001E`)\n\t\t}\n\t\treturn head + packValue(update.value)\n\t}\n\tpublic static unpackUpdate<P extends primitive>(\n\t\tpacked: PackedSetUpdate<P>,\n\t): SetUpdate<P> {\n\t\tconst [type, tail] = packed.split(`\\u001F`) as [0 | 1 | 2, string]\n\t\tconst head = SET_UPDATE_ENUM[type]\n\t\tif (head === `clear`) {\n\t\t\tconst values = tail.split(`\\u001E`).map(unpackValue) as P[]\n\t\t\treturn { type: `clear`, values }\n\t\t}\n\t\treturn { type: head, value: unpackValue(tail) as P }\n\t}\n}\n","import type { AtomEffect } from \"atom.io\"\nimport { getUpdateToken, subscribeInStore } from \"atom.io/internal\"\nimport { type primitive, stringifyJson } from \"atom.io/json\"\n\nimport { UList } from \"./u-list\"\n\nexport const uListDisposedKeyCleanupEffect: AtomEffect<UList<primitive>> = ({\n\ttoken,\n\tsetSelf,\n\tstore,\n}) => {\n\tconst disposalSubscriptions = new Map<primitive, () => void>()\n\tconst updateToken = getUpdateToken(token)\n\tsubscribeInStore(\n\t\tstore,\n\t\tupdateToken,\n\t\tfunction setAutoDeletionTriggers({ newValue }) {\n\t\t\tconst unpacked = UList.unpackUpdate(newValue)\n\t\t\tswitch (unpacked.type) {\n\t\t\t\tcase `add`:\n\t\t\t\t\t{\n\t\t\t\t\t\tconst molecule = store.molecules.get(stringifyJson(unpacked.value))\n\t\t\t\t\t\tif (molecule) {\n\t\t\t\t\t\t\tdisposalSubscriptions.set(\n\t\t\t\t\t\t\t\tunpacked.value,\n\t\t\t\t\t\t\t\tmolecule.subject.subscribe(token.key, () => {\n\t\t\t\t\t\t\t\t\tsetSelf((self) => {\n\t\t\t\t\t\t\t\t\t\tself.delete(unpacked.value)\n\t\t\t\t\t\t\t\t\t\treturn self\n\t\t\t\t\t\t\t\t\t})\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}\n\t\t\t\t\tbreak\n\t\t\t\tcase `delete`:\n\t\t\t\t\tdisposalSubscriptions.get(unpacked.value)?.()\n\t\t\t\t\tdisposalSubscriptions.delete(unpacked.value)\n\t\t\t\t\tbreak\n\t\t\t\tcase `clear`:\n\t\t\t\t\tfor (const unsub of disposalSubscriptions.values()) unsub()\n\t\t\t\t\tdisposalSubscriptions.clear()\n\t\t\t}\n\t\t},\n\t\t`set-auto-deletion-triggers`,\n\t)\n}\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ //#region src/internal/utility-types.d.ts
2
+ type Fn = (...parameters: any[]) => any;
3
+ type Ctor<T> = new (...args: any[]) => T;
4
+ type Flat<R extends { [K in PropertyKey]: any }> = { [K in keyof R]: R[K] };
5
+ type Count<N extends number, A extends any[] = []> = [...A, any][`length`] extends N ? A[`length`] : A[`length`] | Count<N, [...A, any]>;
6
+ type Each<E extends any[]> = { [P in Count<E[`length`]>]: E[P] };
7
+ type Refinement<A, B extends A> = (a: A) => a is B;
8
+ //#endregion
9
+ export { Count, Ctor, Each, Flat, Fn, Refinement };
10
+ //# sourceMappingURL=utility-types-aZkJVERa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utility-types-aZkJVERa.d.ts","names":[],"sources":["../src/internal/utility-types.ts"],"sourcesContent":[],"mappings":";KAAY,EAAA;AAAA,KAEA,IAFA,CAAA,CAAA,CAAA,GAAA,KAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAEkC,CAFlC;AAEA,KAEA,IAFA,CAAA,UAAkC,QAEX,WAFW,GAAA,GAAA,EAAA,CAAA,GAAA,QAAA,MAGjC,CAHiC,GAG7B,CAH6B,CAG3B,CAH2B,CAAA,EAAA;AAElC,KAIA,KAJA,CAAA,UAAA,MAAA,YAAuB,GAAA,EAAA,GAAA,EAAA,QAK/B,CAJS,EAAA,GAAA,CAAA,CAAA,QAAA,CAAA,SAMO,CANP,GAOV,CAPU,CAAA,QAAA,CAAA,GAQV,CARU,CAAA,QAAA,CAAA,GAQI,KARJ,CAQU,CARV,EAAA,CAAA,GAQiB,CARjB,EAAA,GAAA,CAAA,CAAA;AAAI,KAUL,IAVK,CAAA,UAAA,GAAA,EAAA,CAAA,GAAA,QAWV,KAXU,CAWJ,CAXI,CAAA,QAAA,CAAA,CAAA,GAWW,CAXX,CAWa,CAXb,CAAA,EAAA;AAAE,KAcP,UAdO,CAAA,CAAA,EAGnB,UAWoC,CAXxB,CAAA,GAAA,CAAA,CAAA,EAWiC,CAXjC,EAAA,GAAA,CAAA,IAW4C,CAX5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.41.1",
3
+ "version": "0.42.1",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -60,45 +60,45 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@eslint/core": "0.15.2",
64
- "@storybook/addon-docs": "9.1.6",
65
- "@storybook/addon-onboarding": "9.1.6",
66
- "@storybook/react-vite": "9.1.6",
63
+ "@eslint/core": "0.16.0",
64
+ "@storybook/addon-docs": "9.1.8",
65
+ "@storybook/addon-onboarding": "9.1.8",
66
+ "@storybook/react-vite": "9.1.8",
67
67
  "@testing-library/react": "16.3.0",
68
68
  "@types/bun": "npm:bun-types@1.2.22",
69
69
  "@types/eslint": "9.6.1",
70
70
  "@types/estree": "1.0.8",
71
71
  "@types/http-proxy": "1.17.16",
72
72
  "@types/npmlog": "7.0.0",
73
- "@types/react": "19.1.13",
73
+ "@types/react": "19.1.14",
74
74
  "@types/tmp": "0.2.6",
75
- "@typescript-eslint/parser": "8.44.0",
76
- "@typescript-eslint/rule-tester": "8.44.0",
77
- "@typescript-eslint/utils": "8.44.0",
75
+ "@typescript-eslint/parser": "8.44.1",
76
+ "@typescript-eslint/rule-tester": "8.44.1",
77
+ "@typescript-eslint/utils": "8.44.1",
78
78
  "@vitest/coverage-v8": "3.2.4",
79
79
  "@vitest/ui": "3.2.4",
80
80
  "concurrently": "9.2.1",
81
- "drizzle-kit": "0.31.4",
81
+ "drizzle-kit": "0.31.5",
82
82
  "drizzle-orm": "0.44.5",
83
- "eslint": "9.35.0",
83
+ "eslint": "9.36.0",
84
84
  "happy-dom": "18.0.1",
85
85
  "http-proxy": "1.18.1",
86
- "motion": "12.23.14",
86
+ "motion": "12.23.22",
87
87
  "npmlog": "7.0.1",
88
88
  "nyc": "17.1.0",
89
89
  "postgres": "3.4.7",
90
90
  "preact": "10.27.2",
91
91
  "react": "19.1.1",
92
92
  "react-dom": "19.1.1",
93
- "react-router-dom": "7.9.1",
93
+ "react-router-dom": "7.9.3",
94
94
  "recoverage": "0.1.11",
95
95
  "socket.io": "4.8.1",
96
96
  "socket.io-client": "4.8.1",
97
- "storybook": "9.1.6",
97
+ "storybook": "9.1.8",
98
98
  "tmp": "0.2.5",
99
- "tsdown": "0.15.2",
99
+ "tsdown": "0.15.5",
100
100
  "typescript": "5.9.2",
101
- "vite": "7.1.5",
101
+ "vite": "7.1.7",
102
102
  "vite-tsconfig-paths": "5.1.4",
103
103
  "vitest": "3.2.4",
104
104
  "zod": "3.25.76",
@@ -166,6 +166,10 @@
166
166
  "import": "./dist/realtime-testing/index.js",
167
167
  "types": "./dist/realtime-testing/index.d.ts"
168
168
  },
169
+ "./struct": {
170
+ "import": "./dist/struct/index.js",
171
+ "types": "./dist/struct/index.d.ts"
172
+ },
169
173
  "./transceivers/o-list": {
170
174
  "import": "./dist/transceivers/o-list/index.js",
171
175
  "types": "./dist/transceivers/o-list/index.d.ts"
@@ -6,7 +6,7 @@ import type {
6
6
  } from "atom.io"
7
7
  import type { Canonical } from "atom.io/json"
8
8
 
9
- import { newest } from "../lineage"
9
+ import { eldest, newest } from "../lineage"
10
10
  import { resetInStore, setIntoStore } from "../set-state"
11
11
  import type { RegularAtom } from "../state-types"
12
12
  import type { Store } from "../store"
@@ -68,6 +68,8 @@ export function createRegularAtom<T, K extends Canonical, E>(
68
68
  },
69
69
  onSet: (handle: UpdateHandler<T>) =>
70
70
  subscribeToState(store, token, `effect[${effectIndex}]`, handle),
71
+ token: token as any,
72
+ store: eldest(store),
71
73
  })
72
74
  if (cleanup) {
73
75
  cleanupFunctions.push(cleanup)
@@ -14,7 +14,6 @@ export * from "./join"
14
14
  export * from "./junction"
15
15
  export * from "./keys"
16
16
  export * from "./lineage"
17
- export * from "./micro"
18
17
  export * from "./molecule"
19
18
  export * from "./mutable"
20
19
  export * from "./not-found-error"
@@ -1,23 +1,20 @@
1
1
  import type { JoinOptions, JoinToken } from "atom.io"
2
- import type { Json } from "atom.io/json"
3
2
 
4
3
  import type { RootStore } from "../transaction"
5
4
  import { Join } from "./join-internal"
6
5
 
7
6
  export function createJoin<
8
- ASide extends string,
9
- AType extends string,
10
- BSide extends string,
11
- BType extends string,
7
+ AName extends string,
8
+ A extends string,
9
+ BName extends string,
10
+ B extends string,
12
11
  Cardinality extends `1:1` | `1:n` | `n:n`,
13
- Content extends Json.Object,
14
12
  >(
15
13
  store: RootStore,
16
- options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>,
17
- defaultContent: Content | undefined,
18
- ): JoinToken<ASide, AType, BSide, BType, Cardinality, Content> {
19
- store.joins.set(options.key, new Join(options, defaultContent, store))
20
- const token: JoinToken<ASide, AType, BSide, BType, Cardinality, Content> = {
14
+ options: JoinOptions<AName, A, BName, B, Cardinality>,
15
+ ): JoinToken<AName, A, BName, B, Cardinality> {
16
+ store.joins.set(options.key, new Join(options))
17
+ const token: JoinToken<AName, A, BName, B, Cardinality> = {
21
18
  key: options.key,
22
19
  type: `join`,
23
20
  a: options.between[0],
@@ -1,5 +1,4 @@
1
1
  import type { JoinToken } from "atom.io"
2
- import type { Json } from "atom.io/json"
3
2
 
4
3
  import type { Junction } from "../junction"
5
4
  import { newest } from "../lineage"
@@ -8,15 +7,14 @@ import { isChildStore } from "../transaction"
8
7
  import { getJoin } from "./get-join"
9
8
 
10
9
  export function editRelationsInStore<
11
- ASide extends string,
12
- AType extends string,
13
- BSide extends string,
14
- BType extends string,
10
+ AName extends string,
11
+ A extends string,
12
+ BName extends string,
13
+ B extends string,
15
14
  Cardinality extends `1:1` | `1:n` | `n:n`,
16
- Content extends Json.Object | null,
17
15
  >(
18
- token: JoinToken<ASide, AType, BSide, BType, Cardinality, Content>,
19
- change: (relations: Junction<ASide, AType, BSide, BType, Content>) => void,
16
+ token: JoinToken<AName, A, BName, B, Cardinality>,
17
+ change: (relations: Junction<AName, A, BName, B>) => void,
20
18
  store: Store,
21
19
  ): void {
22
20
  const myJoin = getJoin(token, store)
@@ -1,5 +1,4 @@
1
1
  import type { JoinStates, JoinToken } from "atom.io"
2
- import type { Json } from "atom.io/json"
3
2
 
4
3
  import { capitalize } from "../capitalize"
5
4
  import { findInStore } from "../families"
@@ -7,19 +6,18 @@ import type { RootStore } from "../transaction"
7
6
  import { getJoin } from "./get-join"
8
7
 
9
8
  export function findRelationsInStore<
10
- ASide extends string,
11
- AType extends string,
12
- BSide extends string,
13
- BType extends string,
9
+ AName extends string,
10
+ A extends string,
11
+ BName extends string,
12
+ B extends string,
14
13
  Cardinality extends `1:1` | `1:n` | `n:n`,
15
- Content extends Json.Object | null,
16
14
  >(
17
- token: JoinToken<ASide, AType, BSide, BType, Cardinality, Content>,
18
- key: AType | BType,
15
+ token: JoinToken<AName, A, BName, B, Cardinality>,
16
+ key: A | B,
19
17
  store: RootStore,
20
- ): JoinStates<ASide, AType, BSide, BType, Cardinality, Content> {
18
+ ): JoinStates<AName, A, BName, B, Cardinality> {
21
19
  const myJoin = getJoin(token, store)
22
- let relations: JoinStates<ASide, AType, BSide, BType, Cardinality, Content>
20
+ let relations: JoinStates<AName, A, BName, B, Cardinality>
23
21
  switch (token.cardinality satisfies `1:1` | `1:n` | `n:n`) {
24
22
  case `1:1`: {
25
23
  const keyAB = `${token.a}KeyOf${capitalize(token.b)}`
@@ -37,25 +35,7 @@ export function findRelationsInStore<
37
35
  const state = findInStore(store, familyBA, key)
38
36
  return state
39
37
  },
40
- } as JoinStates<ASide, AType, BSide, BType, Cardinality, Content>
41
- const entryAB = `${token.a}EntryOf${capitalize(token.b)}`
42
- if (entryAB in myJoin.states) {
43
- const entryBA = `${token.b}EntryOf${capitalize(token.a)}`
44
- Object.assign(relations, {
45
- get [entryAB]() {
46
- // @ts-expect-error way too complicated to represent
47
- const familyAB = myJoin.states[entryAB as any]
48
- const state = findInStore(store, familyAB, key)
49
- return state
50
- },
51
- get [entryBA]() {
52
- // @ts-expect-error way too complicated to represent
53
- const familyBA = myJoin.states[entryBA as any]
54
- const state = findInStore(store, familyBA, key)
55
- return state
56
- },
57
- })
58
- }
38
+ } as JoinStates<AName, A, BName, B, Cardinality>
59
39
  break
60
40
  }
61
41
  case `1:n`: {
@@ -74,25 +54,7 @@ export function findRelationsInStore<
74
54
  const state = findInStore(store, familyBA, key)
75
55
  return state
76
56
  },
77
- } as JoinStates<ASide, AType, BSide, BType, Cardinality, Content>
78
- const entryAB = `${token.a}EntryOf${capitalize(token.b)}`
79
- if (entryAB in myJoin.states) {
80
- const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`
81
- Object.assign(relations, {
82
- get [entryAB]() {
83
- // @ts-expect-error way too complicated to represent
84
- const familyAB = myJoin.states[entryAB as any]
85
- const state = findInStore(store, familyAB, key)
86
- return state
87
- },
88
- get [entriesBA]() {
89
- // @ts-expect-error way too complicated to represent
90
- const familyBA = myJoin.states[entriesBA as any]
91
- const state = findInStore(store, familyBA, key)
92
- return state
93
- },
94
- })
95
- }
57
+ } as JoinStates<AName, A, BName, B, Cardinality>
96
58
  break
97
59
  }
98
60
  case `n:n`: {
@@ -111,25 +73,7 @@ export function findRelationsInStore<
111
73
  const state = findInStore(store, familyBA, key)
112
74
  return state
113
75
  },
114
- } as JoinStates<ASide, AType, BSide, BType, Cardinality, Content>
115
- const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`
116
- if (entriesAB in myJoin.states) {
117
- const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`
118
- Object.assign(relations, {
119
- get [entriesAB]() {
120
- // @ts-expect-error way too complicated to represent
121
- const familyAB = myJoin.states[entriesAB as any]
122
- const state = findInStore(store, familyAB, key)
123
- return state
124
- },
125
- get [entriesBA]() {
126
- // @ts-expect-error way too complicated to represent
127
- const familyBA = myJoin.states[entriesBA as any]
128
- const state = findInStore(store, familyBA, key)
129
- return state
130
- },
131
- })
132
- }
76
+ } as JoinStates<AName, A, BName, B, Cardinality>
133
77
  }
134
78
  }
135
79
  return relations
@@ -1,14 +1,20 @@
1
1
  import type { JoinToken, MutableAtomFamilyToken } from "atom.io"
2
- import type { SetRTX } from "atom.io/transceivers/set-rtx"
2
+ import type { UList } from "atom.io/transceivers/u-list"
3
3
 
4
4
  import type { RootStore } from "../transaction"
5
5
  import { getJoin } from "./get-join"
6
6
 
7
- export function getInternalRelationsFromStore(
8
- token: JoinToken<any, any, any, any, any, any>,
7
+ export function getInternalRelationsFromStore<
8
+ AName extends string,
9
+ BName extends string,
10
+ >(
11
+ token: JoinToken<any, AName, any, BName, any>,
9
12
  store: RootStore,
10
- ): MutableAtomFamilyToken<SetRTX<string>, string> {
13
+ ): MutableAtomFamilyToken<UList<AName> | UList<BName>, string> {
11
14
  const myJoin = getJoin(token, store)
12
- const family = myJoin.core.relatedKeysAtoms
15
+ const family = myJoin.relatedKeysAtoms as MutableAtomFamilyToken<
16
+ UList<AName> | UList<BName>,
17
+ string
18
+ >
13
19
  return family
14
20
  }
@@ -1,5 +1,4 @@
1
1
  import type { JoinToken } from "atom.io"
2
- import type { Json } from "atom.io/json"
3
2
 
4
3
  import { eldest } from "../lineage"
5
4
  import type { Store } from "../store"
@@ -7,16 +6,15 @@ import { IMPLICIT } from "../store"
7
6
  import { Join } from "./join-internal"
8
7
 
9
8
  export function getJoin<
10
- ASide extends string,
11
- AType extends string,
12
- BSide extends string,
13
- BType extends string,
9
+ AName extends string,
10
+ A extends string,
11
+ BName extends string,
12
+ B extends string,
14
13
  Cardinality extends `1:1` | `1:n` | `n:n`,
15
- Content extends Json.Object | null,
16
14
  >(
17
- token: JoinToken<ASide, AType, BSide, BType, Cardinality, Content>,
15
+ token: JoinToken<AName, A, BName, B, Cardinality>,
18
16
  store: Store,
19
- ): Join<ASide, AType, BSide, BType, Cardinality, Content> {
17
+ ): Join<AName, A, BName, B, Cardinality> {
20
18
  let myJoin = store.joins.get(token.key)
21
19
  if (myJoin === undefined) {
22
20
  const rootJoinMap = IMPLICIT.STORE.joins
@@ -27,7 +25,7 @@ export function getJoin<
27
25
  )
28
26
  }
29
27
  const root = eldest(store)
30
- myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root)
28
+ myJoin = new Join(rootJoin.options, root)
31
29
  store.joins.set(token.key, myJoin)
32
30
  }
33
31
  return myJoin