atom.io 0.44.15 → 0.45.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.
- package/dist/eslint-plugin/index.js +1 -1
- package/dist/introspection/index.d.ts +3 -2
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/dist/json/index.d.ts +34 -20
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js +40 -2
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +1 -1
- package/dist/main/index.d.ts.map +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +13 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.d.ts.map +1 -1
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +1 -1
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-testing/index.js +1 -1
- package/dist/transceivers/o-list/index.d.ts +1 -2
- package/dist/transceivers/o-list/index.d.ts.map +1 -1
- package/dist/transceivers/o-list/index.js +23 -24
- package/dist/transceivers/o-list/index.js.map +1 -1
- package/dist/transceivers/u-list/index.d.ts +1 -2
- package/dist/transceivers/u-list/index.d.ts.map +1 -1
- package/dist/transceivers/u-list/index.js +5 -6
- package/dist/transceivers/u-list/index.js.map +1 -1
- package/package.json +4 -12
- package/src/introspection/attach-introspection-states.ts +1 -1
- package/src/introspection/attach-transaction-logs.ts +2 -2
- package/src/introspection/index.ts +3 -0
- package/src/json/canonical.ts +42 -0
- package/src/json/enumeration.ts +36 -0
- package/src/json/index.ts +3 -132
- package/src/json/json.ts +128 -0
- package/src/main/index.ts +9 -2
- package/src/react/use-loadable.ts +10 -5
- package/src/react/use-o.ts +33 -1
- package/src/react-devtools/TransactionIndex.tsx +1 -1
- package/src/react-devtools/store.ts +3 -3
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +2 -2
- package/src/realtime-react/use-pull-selector-family-member.ts +0 -1
- package/src/transceivers/o-list/o-list.ts +27 -28
- package/src/transceivers/u-list/u-list.ts +7 -8
- package/dist/data/index.d.ts +0 -23
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js +0 -63
- package/dist/data/index.js.map +0 -1
- package/dist/struct/index.d.ts +0 -14
- package/dist/struct/index.d.ts.map +0 -1
- package/dist/struct/index.js +0 -37
- package/dist/struct/index.js.map +0 -1
- package/src/data/dict.ts +0 -31
- package/src/data/index.ts +0 -3
- package/src/data/struct-family.ts +0 -53
- package/src/data/struct.ts +0 -54
- package/src/struct/index.ts +0 -1
- package/src/struct/micro.ts +0 -72
- /package/dist/{chunk-D8lmAICg.js → chunk-CKcAJnC7.js} +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
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
|
+
import { enumeration, packCanonical, stringifyJson, unpackCanonical } from "atom.io/json";
|
|
4
3
|
|
|
5
4
|
//#region src/transceivers/u-list/u-list.ts
|
|
6
5
|
const SET_UPDATE_ENUM = enumeration([
|
|
@@ -87,19 +86,19 @@ var UList = class UList extends Set {
|
|
|
87
86
|
}
|
|
88
87
|
static packUpdate(update) {
|
|
89
88
|
const head = SET_UPDATE_ENUM[update.type] + `\u001F`;
|
|
90
|
-
if (update.type === `clear`) return head + update.values.map(
|
|
91
|
-
return head +
|
|
89
|
+
if (update.type === `clear`) return head + update.values.map(packCanonical).join(`\u001E`);
|
|
90
|
+
return head + packCanonical(update.value);
|
|
92
91
|
}
|
|
93
92
|
static unpackUpdate(packed) {
|
|
94
93
|
const [type, tail] = packed.split(`\u001F`);
|
|
95
94
|
const head = SET_UPDATE_ENUM[type];
|
|
96
95
|
if (head === `clear`) return {
|
|
97
96
|
type: `clear`,
|
|
98
|
-
values: tail.split(`\u001E`).map(
|
|
97
|
+
values: tail.split(`\u001E`).map(unpackCanonical)
|
|
99
98
|
};
|
|
100
99
|
return {
|
|
101
100
|
type: head,
|
|
102
|
-
value:
|
|
101
|
+
value: unpackCanonical(tail)
|
|
103
102
|
};
|
|
104
103
|
}
|
|
105
104
|
};
|
|
@@ -1 +1 @@
|
|
|
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
|
|
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 { Enumeration, packed, primitive } from \"atom.io/json\"\nimport { enumeration, packCanonical, unpackCanonical } 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 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(packCanonical).join(`\\u001E`)\n\t\t}\n\t\treturn head + packCanonical(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, packed<P>]\n\t\tconst head = SET_UPDATE_ENUM[type]\n\t\tif (head === `clear`) {\n\t\t\tconst values = tail.split(`\\u001E`).map<P>(unpackCanonical)\n\t\t\treturn { type: `clear`, values }\n\t\t}\n\t\treturn { type: head, value: unpackCanonical(tail) }\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":";;;;AA2BA,MAAaA,kBACZ,YAAY;CAAC;CAAO;CAAU;CAAQ,CAAU;AAWjD,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,gBAA8B;CAE9C,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,cAAc,CAAC,KAAK,SAAS;AAE9D,SAAO,OAAO,cAAc,OAAO,MAAM;;CAE1C,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,IAAO,gBAAgB;GAC3B;AAEjC,SAAO;GAAE,MAAM;GAAM,OAAO,gBAAgB,KAAK;GAAE;;;;;;ACnJrD,MAAaC,iCAA+D,EAC3E,OACA,SACA,YACK;CACL,MAAM,wCAAwB,IAAI,KAA4B;AAE9D,kBACC,OAFmB,eAAe,MAAM,EAIxC,SAAS,wBAAwB,EAAE,YAAY;EAC9C,MAAM,WAAW,MAAM,aAAa,SAAS;AAC7C,UAAQ,SAAS,MAAjB;GACC,KAAK;IACJ;KACC,MAAM,WAAW,MAAM,UAAU,IAAI,cAAc,SAAS,MAAM,CAAC;AACnE,SAAI,SACH,uBAAsB,IACrB,SAAS,OACT,SAAS,QAAQ,UAAU,MAAM,WAAW;AAC3C,eAAS,SAAS;AACjB,YAAK,OAAO,SAAS,MAAM;AAC3B,cAAO;QACN;OACD,CACF;;AAGH;GACD,KAAK;AACJ,0BAAsB,IAAI,SAAS,MAAM,IAAI;AAC7C,0BAAsB,OAAO,SAAS,MAAM;AAC5C;GACD,KAAK;AACJ,SAAK,MAAM,SAAS,sBAAsB,QAAQ,CAAE,QAAO;AAC3D,0BAAsB,OAAO;;IAGhC,6BACA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.1",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@typescript-eslint/parser": "8.47.0",
|
|
73
73
|
"@typescript-eslint/rule-tester": "8.47.0",
|
|
74
74
|
"@typescript-eslint/utils": "8.47.0",
|
|
75
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
75
|
+
"@typescript/native-preview": "7.0.0-dev.20251130.1",
|
|
76
76
|
"@vitest/coverage-v8": "4.0.14",
|
|
77
77
|
"@vitest/ui": "4.0.14",
|
|
78
78
|
"arktype": "2.1.27",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
"vite": "7.2.4",
|
|
98
98
|
"vite-tsconfig-paths": "5.1.4",
|
|
99
99
|
"vitest": "4.0.14",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
100
|
+
"takua": "0.1.1",
|
|
101
|
+
"break-check": "0.6.24"
|
|
102
102
|
},
|
|
103
103
|
"main": "./dist/main/index.js",
|
|
104
104
|
"files": [
|
|
@@ -111,10 +111,6 @@
|
|
|
111
111
|
"import": "./dist/main/index.js",
|
|
112
112
|
"types": "./dist/main/index.d.ts"
|
|
113
113
|
},
|
|
114
|
-
"./data": {
|
|
115
|
-
"import": "./dist/data/index.js",
|
|
116
|
-
"types": "./dist/data/index.d.ts"
|
|
117
|
-
},
|
|
118
114
|
"./eslint-plugin": {
|
|
119
115
|
"import": "./dist/eslint-plugin/index.js",
|
|
120
116
|
"types": "./dist/eslint-plugin/index.d.ts"
|
|
@@ -162,10 +158,6 @@
|
|
|
162
158
|
"import": "./dist/realtime-testing/index.js",
|
|
163
159
|
"types": "./dist/realtime-testing/index.d.ts"
|
|
164
160
|
},
|
|
165
|
-
"./struct": {
|
|
166
|
-
"import": "./dist/struct/index.js",
|
|
167
|
-
"types": "./dist/struct/index.d.ts"
|
|
168
|
-
},
|
|
169
161
|
"./transceivers/o-list": {
|
|
170
162
|
"import": "./dist/transceivers/o-list/index.js",
|
|
171
163
|
"types": "./dist/transceivers/o-list/index.d.ts"
|
|
@@ -22,7 +22,7 @@ export type IntrospectionStates = {
|
|
|
22
22
|
selectorIndex: AtomToken<SelectorTokenIndex>
|
|
23
23
|
transactionIndex: AtomToken<TransactionToken<Fn>[]>
|
|
24
24
|
transactionLogSelectors: ReadonlyPureSelectorFamilyToken<
|
|
25
|
-
TransactionOutcomeEvent<TransactionToken<Fn>>[],
|
|
25
|
+
readonly TransactionOutcomeEvent<TransactionToken<Fn>>[],
|
|
26
26
|
string
|
|
27
27
|
>
|
|
28
28
|
timelineIndex: AtomToken<TimelineToken<any>[]>
|
|
@@ -9,7 +9,7 @@ import { createRegularAtomFamily, createSelectorFamily } from "atom.io/internal"
|
|
|
9
9
|
export const attachTransactionLogs = (
|
|
10
10
|
store: RootStore,
|
|
11
11
|
): ReadonlyPureSelectorFamilyToken<
|
|
12
|
-
TransactionOutcomeEvent<TransactionToken<any>>[],
|
|
12
|
+
readonly TransactionOutcomeEvent<TransactionToken<any>>[],
|
|
13
13
|
string
|
|
14
14
|
> => {
|
|
15
15
|
const transactionUpdateLogAtoms = createRegularAtomFamily<
|
|
@@ -31,7 +31,7 @@ export const attachTransactionLogs = (
|
|
|
31
31
|
],
|
|
32
32
|
})
|
|
33
33
|
const findTransactionUpdateLogState = createSelectorFamily<
|
|
34
|
-
TransactionOutcomeEvent<TransactionToken<any>>[],
|
|
34
|
+
readonly TransactionOutcomeEvent<TransactionToken<any>>[],
|
|
35
35
|
string,
|
|
36
36
|
never
|
|
37
37
|
>(store, {
|
|
@@ -11,5 +11,8 @@ export type FamilyNode<Token extends ReadableToken<unknown, any, any>> = {
|
|
|
11
11
|
familyMembers: Map<string, Token>
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export type ReadonlyTokenIndex<Token extends ReadableToken<unknown, any, any>> =
|
|
15
|
+
ReadonlyMap<string, FamilyNode<Token> | Token>
|
|
16
|
+
|
|
14
17
|
export type WritableTokenIndex<Token extends ReadableToken<unknown, any, any>> =
|
|
15
18
|
Map<string, FamilyNode<Token> | Token>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { primitive } from "./json"
|
|
2
|
+
|
|
3
|
+
/** Only Canonical values should be used for keys because they always serialize to the same string */
|
|
4
|
+
export type Canonical = primitive | ReadonlyArray<Canonical>
|
|
5
|
+
|
|
6
|
+
export type packed<C extends Canonical> = string & { __canonical?: C }
|
|
7
|
+
|
|
8
|
+
const BOOL = `\u0001`
|
|
9
|
+
const NULL = `\u0002`
|
|
10
|
+
const STRING = `\u0003`
|
|
11
|
+
const NUMBER = `\u0004`
|
|
12
|
+
export const packCanonical = <C extends Canonical>(
|
|
13
|
+
value: Canonical,
|
|
14
|
+
): packed<C> => {
|
|
15
|
+
if (value === null) return NULL
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
17
|
+
switch (typeof value) {
|
|
18
|
+
case `string`:
|
|
19
|
+
return STRING + value
|
|
20
|
+
case `number`:
|
|
21
|
+
return NUMBER + value
|
|
22
|
+
case `boolean`:
|
|
23
|
+
return BOOL + +value
|
|
24
|
+
case `object`: // array
|
|
25
|
+
return JSON.stringify(value)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export const unpackCanonical = <C extends Canonical>(value: packed<C>): C => {
|
|
29
|
+
const type = value[0] as `[` | `\u0001` | `\u0002` | `\u0003` | `\u0004`
|
|
30
|
+
switch (type) {
|
|
31
|
+
case STRING:
|
|
32
|
+
return value.slice(1) as C
|
|
33
|
+
case NUMBER:
|
|
34
|
+
return +value.slice(1) as C
|
|
35
|
+
case BOOL:
|
|
36
|
+
return (value.slice(1) === `1`) as C
|
|
37
|
+
case NULL:
|
|
38
|
+
return null as C
|
|
39
|
+
case `[`:
|
|
40
|
+
return JSON.parse(value)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Flat } from "atom.io/internal"
|
|
2
|
+
|
|
3
|
+
export type IndexOf<
|
|
4
|
+
T extends readonly unknown[],
|
|
5
|
+
E,
|
|
6
|
+
A extends unknown[] = [],
|
|
7
|
+
> = T extends readonly [infer Head, ...infer Tail]
|
|
8
|
+
? (<U>() => U extends Head ? 1 : 2) extends <U>() => U extends E ? 1 : 2
|
|
9
|
+
? A[`length`]
|
|
10
|
+
: IndexOf<Tail, E, [...A, unknown]>
|
|
11
|
+
: never
|
|
12
|
+
|
|
13
|
+
export type Flip<T extends Record<string, number | string>> = {
|
|
14
|
+
[K in keyof T as T[K]]: K
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type TwoWay<T extends Record<string, number | string>> = Flip<T> & T
|
|
18
|
+
|
|
19
|
+
export type Enumeration<T extends readonly string[]> = Flat<
|
|
20
|
+
TwoWay<{
|
|
21
|
+
[K in T[number]]: IndexOf<T, K>
|
|
22
|
+
}>
|
|
23
|
+
>
|
|
24
|
+
|
|
25
|
+
export function enumeration<T extends readonly string[]>(
|
|
26
|
+
values: T,
|
|
27
|
+
): Enumeration<T> {
|
|
28
|
+
const result: Record<any, any> = {}
|
|
29
|
+
let i = 0
|
|
30
|
+
for (const value of values) {
|
|
31
|
+
result[value] = i
|
|
32
|
+
result[i] = value
|
|
33
|
+
++i
|
|
34
|
+
}
|
|
35
|
+
return result as Enumeration<T>
|
|
36
|
+
}
|
package/src/json/index.ts
CHANGED
|
@@ -1,133 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from "./canonical"
|
|
3
2
|
export * from "./entries"
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export namespace Json {
|
|
8
|
-
export namespace Tree {
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
10
|
-
export type Array<Element = unknown> = ReadonlyArray<Element>
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
12
|
-
export type Object<K extends string = string, V = unknown> = Record<K, V>
|
|
13
|
-
export type Fork = Array | Object
|
|
14
|
-
export type Leaf = primitive
|
|
15
|
-
export type Node = Fork | Leaf
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** A value can survive being {@link JSON.stringify}-ed and {@link JSON.parse}-d fully intact */
|
|
19
|
-
export type Serializable =
|
|
20
|
-
| primitive
|
|
21
|
-
| Readonly<{ [key: string]: Serializable }>
|
|
22
|
-
| ReadonlyArray<Serializable>
|
|
23
|
-
|
|
24
|
-
export type Object<
|
|
25
|
-
Key extends string = string,
|
|
26
|
-
Value extends Serializable = Serializable,
|
|
27
|
-
> = Record<Key, Value>
|
|
28
|
-
|
|
29
|
-
export type Array<Element extends Serializable = Serializable> =
|
|
30
|
-
ReadonlyArray<Element>
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** A generic that retains the type information of a {@link Json.Serializable} value while in string form */
|
|
34
|
-
// biome-ignore format: long silly ternary
|
|
35
|
-
export type stringified<J extends Json.Serializable> = (
|
|
36
|
-
J extends string
|
|
37
|
-
? `"${J}"`
|
|
38
|
-
: J extends number
|
|
39
|
-
? `${J}`
|
|
40
|
-
: J extends true
|
|
41
|
-
? `true`
|
|
42
|
-
: J extends false
|
|
43
|
-
? `false`
|
|
44
|
-
: J extends boolean
|
|
45
|
-
? `false` | `true`
|
|
46
|
-
: J extends null
|
|
47
|
-
? `null`
|
|
48
|
-
: J extends []
|
|
49
|
-
? `[]`
|
|
50
|
-
: J extends [infer Element extends Json.Serializable]
|
|
51
|
-
? `[${stringified<Element>}]`
|
|
52
|
-
: J extends [
|
|
53
|
-
infer Element1 extends Json.Serializable,
|
|
54
|
-
infer Element2 extends Json.Serializable,
|
|
55
|
-
]
|
|
56
|
-
? `[${stringified<Element1>}, ${stringified<Element2>}]`
|
|
57
|
-
: J extends [
|
|
58
|
-
infer Element1 extends Json.Serializable,
|
|
59
|
-
infer Element2 extends Json.Serializable,
|
|
60
|
-
infer Element3 extends Json.Serializable,
|
|
61
|
-
]
|
|
62
|
-
? `[${stringified<Element1>}, ${stringified<Element2>}, ${stringified<Element3>}]`
|
|
63
|
-
: J extends any[]
|
|
64
|
-
? `[${string}]` & { __json?: J }
|
|
65
|
-
: string & { __json?: J }
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
/** Type-safe wrapper for {@link JSON.parse} */
|
|
69
|
-
export function parseJson<J extends Json.Serializable>(str: stringified<J>): J
|
|
70
|
-
/** Type-safe wrapper for {@link JSON.parse} */
|
|
71
|
-
export function parseJson(str: string): Json.Serializable
|
|
72
|
-
export function parseJson(str: string): Json.Serializable {
|
|
73
|
-
return JSON.parse(str)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Type-safe wrapper for {@link JSON.stringify} */
|
|
77
|
-
export const stringifyJson = <J extends Json.Serializable>(
|
|
78
|
-
json: J,
|
|
79
|
-
): stringified<J> => JSON.stringify(json) as stringified<J>
|
|
80
|
-
|
|
81
|
-
/** Only Canonical values should be used for keys because they always serialize to the same string */
|
|
82
|
-
export type Canonical = primitive | ReadonlyArray<Canonical>
|
|
83
|
-
|
|
84
|
-
/** A function whose parameters and return value are {@link Json.Serializable} */
|
|
85
|
-
export type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void
|
|
86
|
-
|
|
87
|
-
export type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
88
|
-
toJson: (t: ViewOf<T>) => J
|
|
89
|
-
fromJson: (json: J) => T
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const JSON_PROTOTYPES = [
|
|
93
|
-
Array.prototype,
|
|
94
|
-
Boolean.prototype,
|
|
95
|
-
Number.prototype,
|
|
96
|
-
Object.prototype,
|
|
97
|
-
String.prototype,
|
|
98
|
-
] as const
|
|
99
|
-
export const isJson = (input: unknown): input is Json.Tree.Node => {
|
|
100
|
-
if (input === null) return true
|
|
101
|
-
if (input === undefined) return false
|
|
102
|
-
const prototype = Object.getPrototypeOf(input)
|
|
103
|
-
return JSON_PROTOTYPES.includes(prototype)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export const JSON_TYPE_NAMES = [
|
|
107
|
-
`array`,
|
|
108
|
-
`boolean`,
|
|
109
|
-
`null`,
|
|
110
|
-
`number`,
|
|
111
|
-
`object`,
|
|
112
|
-
`string`,
|
|
113
|
-
] as const
|
|
114
|
-
|
|
115
|
-
export type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]
|
|
116
|
-
|
|
117
|
-
export interface JsonTypes extends Record<JsonTypeName, Json.Serializable> {
|
|
118
|
-
array: Json.Array
|
|
119
|
-
boolean: boolean
|
|
120
|
-
null: null
|
|
121
|
-
number: number
|
|
122
|
-
object: Json.Object
|
|
123
|
-
string: string
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export const JSON_DEFAULTS: JsonTypes = {
|
|
127
|
-
array: [],
|
|
128
|
-
boolean: false,
|
|
129
|
-
null: null,
|
|
130
|
-
number: 0,
|
|
131
|
-
object: {},
|
|
132
|
-
string: ``,
|
|
133
|
-
}
|
|
3
|
+
export * from "./enumeration"
|
|
4
|
+
export * from "./json"
|
package/src/json/json.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { ViewOf } from "atom.io"
|
|
2
|
+
|
|
3
|
+
export type primitive = boolean | number | string | null
|
|
4
|
+
|
|
5
|
+
export namespace Json {
|
|
6
|
+
export namespace Tree {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
8
|
+
export type Array<Element = unknown> = ReadonlyArray<Element>
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
10
|
+
export type Object<K extends string = string, V = unknown> = Record<K, V>
|
|
11
|
+
export type Fork = Array | Object
|
|
12
|
+
export type Leaf = primitive
|
|
13
|
+
export type Node = Fork | Leaf
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** A value can survive being {@link JSON.stringify}-ed and {@link JSON.parse}-d fully intact */
|
|
17
|
+
export type Serializable =
|
|
18
|
+
| primitive
|
|
19
|
+
| Readonly<{ [key: string]: Serializable }>
|
|
20
|
+
| ReadonlyArray<Serializable>
|
|
21
|
+
|
|
22
|
+
export type Object<
|
|
23
|
+
Key extends string = string,
|
|
24
|
+
Value extends Serializable = Serializable,
|
|
25
|
+
> = Record<Key, Value>
|
|
26
|
+
|
|
27
|
+
export type Array<Element extends Serializable = Serializable> =
|
|
28
|
+
ReadonlyArray<Element>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A generic that retains the type information of a {@link Json.Serializable} value while in string form */
|
|
32
|
+
// biome-ignore format: long silly ternary
|
|
33
|
+
export type stringified<J extends Json.Serializable> = (
|
|
34
|
+
J extends string
|
|
35
|
+
? `"${J}"`
|
|
36
|
+
: J extends number
|
|
37
|
+
? `${J}`
|
|
38
|
+
: J extends true
|
|
39
|
+
? `true`
|
|
40
|
+
: J extends false
|
|
41
|
+
? `false`
|
|
42
|
+
: J extends boolean
|
|
43
|
+
? `false` | `true`
|
|
44
|
+
: J extends null
|
|
45
|
+
? `null`
|
|
46
|
+
: J extends []
|
|
47
|
+
? `[]`
|
|
48
|
+
: J extends [infer Element extends Json.Serializable]
|
|
49
|
+
? `[${stringified<Element>}]`
|
|
50
|
+
: J extends [
|
|
51
|
+
infer Element1 extends Json.Serializable,
|
|
52
|
+
infer Element2 extends Json.Serializable,
|
|
53
|
+
]
|
|
54
|
+
? `[${stringified<Element1>}, ${stringified<Element2>}]`
|
|
55
|
+
: J extends [
|
|
56
|
+
infer Element1 extends Json.Serializable,
|
|
57
|
+
infer Element2 extends Json.Serializable,
|
|
58
|
+
infer Element3 extends Json.Serializable,
|
|
59
|
+
]
|
|
60
|
+
? `[${stringified<Element1>}, ${stringified<Element2>}, ${stringified<Element3>}]`
|
|
61
|
+
: J extends any[]
|
|
62
|
+
? `[${string}]` & { __json?: J }
|
|
63
|
+
: string & { __json?: J }
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
/** Type-safe wrapper for {@link JSON.parse} */
|
|
67
|
+
export function parseJson<J extends Json.Serializable>(str: stringified<J>): J
|
|
68
|
+
/** Type-safe wrapper for {@link JSON.parse} */
|
|
69
|
+
export function parseJson(str: string): Json.Serializable
|
|
70
|
+
export function parseJson(str: string): Json.Serializable {
|
|
71
|
+
return JSON.parse(str)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Type-safe wrapper for {@link JSON.stringify} */
|
|
75
|
+
export const stringifyJson = <J extends Json.Serializable>(
|
|
76
|
+
json: J,
|
|
77
|
+
): stringified<J> => JSON.stringify(json) as stringified<J>
|
|
78
|
+
|
|
79
|
+
/** A function whose parameters and return value are {@link Json.Serializable} */
|
|
80
|
+
export type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void
|
|
81
|
+
|
|
82
|
+
export type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
83
|
+
toJson: (t: ViewOf<T>) => J
|
|
84
|
+
fromJson: (json: J) => T
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const JSON_PROTOTYPES = [
|
|
88
|
+
Array.prototype,
|
|
89
|
+
Boolean.prototype,
|
|
90
|
+
Number.prototype,
|
|
91
|
+
Object.prototype,
|
|
92
|
+
String.prototype,
|
|
93
|
+
] as const
|
|
94
|
+
export const isJson = (input: unknown): input is Json.Tree.Node => {
|
|
95
|
+
if (input === null) return true
|
|
96
|
+
if (input === undefined) return false
|
|
97
|
+
const prototype = Object.getPrototypeOf(input)
|
|
98
|
+
return JSON_PROTOTYPES.includes(prototype)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const JSON_TYPE_NAMES = [
|
|
102
|
+
`array`,
|
|
103
|
+
`boolean`,
|
|
104
|
+
`null`,
|
|
105
|
+
`number`,
|
|
106
|
+
`object`,
|
|
107
|
+
`string`,
|
|
108
|
+
] as const
|
|
109
|
+
|
|
110
|
+
export type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]
|
|
111
|
+
|
|
112
|
+
export interface JsonTypes extends Record<JsonTypeName, Json.Serializable> {
|
|
113
|
+
array: Json.Array
|
|
114
|
+
boolean: boolean
|
|
115
|
+
null: null
|
|
116
|
+
number: number
|
|
117
|
+
object: Json.Object
|
|
118
|
+
string: string
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const JSON_DEFAULTS: JsonTypes = {
|
|
122
|
+
array: [],
|
|
123
|
+
boolean: false,
|
|
124
|
+
null: null,
|
|
125
|
+
number: 0,
|
|
126
|
+
object: {},
|
|
127
|
+
string: ``,
|
|
128
|
+
}
|
package/src/main/index.ts
CHANGED
|
@@ -15,7 +15,6 @@ export * from "./timeline"
|
|
|
15
15
|
export type * from "./tokens"
|
|
16
16
|
export * from "./transaction"
|
|
17
17
|
export * from "./validators"
|
|
18
|
-
|
|
19
18
|
/**
|
|
20
19
|
* Loadable is used to type atoms or selectors that may at some point be initialized to or set to a {@link Promise}.
|
|
21
20
|
*
|
|
@@ -25,4 +24,12 @@ export * from "./validators"
|
|
|
25
24
|
*/
|
|
26
25
|
export type Loadable<T> = Promise<T> | T
|
|
27
26
|
|
|
28
|
-
export type ViewOf<T> = T extends { READONLY_VIEW: infer View }
|
|
27
|
+
export type ViewOf<T> = T extends { READONLY_VIEW: infer View }
|
|
28
|
+
? View
|
|
29
|
+
: T extends Array<any>
|
|
30
|
+
? readonly [...T]
|
|
31
|
+
: T extends Set<infer U>
|
|
32
|
+
? ReadonlySet<ViewOf<U>>
|
|
33
|
+
: T extends Map<infer K, infer V>
|
|
34
|
+
? ReadonlyMap<ViewOf<K>, ViewOf<V>>
|
|
35
|
+
: T
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** biome-ignore-all lint/correctness/useHookAtTopLevel: params are used in an invariant way */
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
Loadable,
|
|
4
|
+
ReadableFamilyToken,
|
|
5
|
+
ReadableToken,
|
|
6
|
+
ViewOf,
|
|
7
|
+
} from "atom.io"
|
|
3
8
|
import { findInStore, type ReadableState, withdraw } from "atom.io/internal"
|
|
4
9
|
import type { Canonical } from "atom.io/json"
|
|
5
10
|
import { StoreContext, useO } from "atom.io/react"
|
|
@@ -7,23 +12,23 @@ import { useContext, useRef } from "react"
|
|
|
7
12
|
|
|
8
13
|
export function useLoadable<T, E>(
|
|
9
14
|
token: ReadableToken<Loadable<T>, any, E>,
|
|
10
|
-
): `LOADING` | { loading: boolean; value: E | T }
|
|
15
|
+
): `LOADING` | { loading: boolean; value: ViewOf<E | T> }
|
|
11
16
|
|
|
12
17
|
export function useLoadable<T, K extends Canonical, E>(
|
|
13
18
|
token: ReadableFamilyToken<Loadable<T>, K, E>,
|
|
14
19
|
key: NoInfer<K>,
|
|
15
|
-
): `LOADING` | { loading: boolean; value: E | T }
|
|
20
|
+
): `LOADING` | { loading: boolean; value: ViewOf<E | T> }
|
|
16
21
|
|
|
17
22
|
export function useLoadable<T, F extends T, E>(
|
|
18
23
|
token: ReadableToken<Loadable<T>, any, E>,
|
|
19
24
|
fallback: F,
|
|
20
|
-
): { loading: boolean; value: T
|
|
25
|
+
): { loading: boolean; value: ViewOf<T>; error?: E }
|
|
21
26
|
|
|
22
27
|
export function useLoadable<T, K extends Canonical, F extends T, E>(
|
|
23
28
|
token: ReadableFamilyToken<Loadable<T>, K, E>,
|
|
24
29
|
key: NoInfer<K>,
|
|
25
30
|
fallback: F,
|
|
26
|
-
): { loading: boolean; value: T
|
|
31
|
+
): { loading: boolean; value: ViewOf<T>; error?: E }
|
|
27
32
|
|
|
28
33
|
export function useLoadable(
|
|
29
34
|
...params:
|
package/src/react/use-o.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
/** biome-ignore-all lint/correctness/useHookAtTopLevel: depends on the type of atom, which shouldn't change */
|
|
1
2
|
import type { ReadableFamilyToken, ReadableToken, ViewOf } from "atom.io"
|
|
2
3
|
import { getFromStore, subscribeToState } from "atom.io/internal"
|
|
3
4
|
import type { Canonical } from "atom.io/json"
|
|
4
|
-
import {
|
|
5
|
+
import { useSingleEffect } from "atom.io/realtime-react"
|
|
6
|
+
import {
|
|
7
|
+
useCallback,
|
|
8
|
+
useContext,
|
|
9
|
+
useId,
|
|
10
|
+
useRef,
|
|
11
|
+
useState,
|
|
12
|
+
useSyncExternalStore,
|
|
13
|
+
} from "react"
|
|
5
14
|
|
|
6
15
|
import { parseStateOverloads } from "./parse-state-overloads"
|
|
7
16
|
import { StoreContext } from "./store-context"
|
|
@@ -23,6 +32,29 @@ export function useO<T, K extends Canonical, E = never>(
|
|
|
23
32
|
const store = useContext(StoreContext)
|
|
24
33
|
const token = parseStateOverloads(store, ...params)
|
|
25
34
|
const id = useId()
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
token.type === `mutable_atom` ||
|
|
38
|
+
token.type === `readonly_held_selector` ||
|
|
39
|
+
token.type === `writable_held_selector`
|
|
40
|
+
) {
|
|
41
|
+
const [, dispatch] = useState<number>(0)
|
|
42
|
+
const valueRef = useRef<ViewOf<E | T>>(getFromStore(store, token))
|
|
43
|
+
useSingleEffect(() => {
|
|
44
|
+
const unsub = subscribeToState<T, E>(
|
|
45
|
+
store,
|
|
46
|
+
token,
|
|
47
|
+
`use-o:${id}`,
|
|
48
|
+
({ newValue }) => {
|
|
49
|
+
valueRef.current = newValue
|
|
50
|
+
dispatch((c) => c + 1)
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
return unsub
|
|
54
|
+
}, [token.key])
|
|
55
|
+
return valueRef.current
|
|
56
|
+
}
|
|
57
|
+
|
|
26
58
|
const sub = useCallback(
|
|
27
59
|
(dispatch: () => void) =>
|
|
28
60
|
subscribeToState<T, E>(store, token, `use-o:${id}`, dispatch),
|
|
@@ -16,7 +16,7 @@ export const TransactionLog: FC<{
|
|
|
16
16
|
token: TransactionToken<Fn>
|
|
17
17
|
isOpenState: RegularAtomToken<boolean>
|
|
18
18
|
logState: ReadonlyPureSelectorToken<
|
|
19
|
-
TransactionOutcomeEvent<TransactionToken<Fn>>[]
|
|
19
|
+
readonly TransactionOutcomeEvent<TransactionToken<Fn>>[]
|
|
20
20
|
>
|
|
21
21
|
}> = ({ token, isOpenState, logState }) => {
|
|
22
22
|
const log = useO(logState)
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "atom.io/internal"
|
|
14
14
|
import type {
|
|
15
15
|
IntrospectionStates,
|
|
16
|
-
|
|
16
|
+
ReadonlyTokenIndex,
|
|
17
17
|
} from "atom.io/introspection"
|
|
18
18
|
import { attachIntrospectionStates, isPlainObject } from "atom.io/introspection"
|
|
19
19
|
import { storageSync } from "atom.io/web"
|
|
@@ -131,8 +131,8 @@ export function attachDevtoolsStates(
|
|
|
131
131
|
do: ({ get, set }, path, current) => {
|
|
132
132
|
const currentView = get(devtoolsViewSelectionAtom)
|
|
133
133
|
let states:
|
|
134
|
-
|
|
|
135
|
-
|
|
|
134
|
+
| ReadonlyTokenIndex<AtomToken<unknown, any, any>>
|
|
135
|
+
| ReadonlyTokenIndex<SelectorToken<unknown, any, any>>
|
|
136
136
|
switch (currentView) {
|
|
137
137
|
case `atoms`:
|
|
138
138
|
states = get(introspectionStates.atomIndex)
|
|
@@ -18,10 +18,10 @@ export const useRegisterAndAttemptConfirmedUpdate =
|
|
|
18
18
|
store: RootStore,
|
|
19
19
|
continuityKey: string,
|
|
20
20
|
socket: Socket,
|
|
21
|
-
optimisticUpdates: AtomIO.TransactionOutcomeEvent<
|
|
21
|
+
optimisticUpdates: readonly AtomIO.TransactionOutcomeEvent<
|
|
22
22
|
AtomIO.TransactionToken<Fn>
|
|
23
23
|
>[],
|
|
24
|
-
confirmedUpdates: AtomIO.TransactionOutcomeEvent<
|
|
24
|
+
confirmedUpdates: readonly AtomIO.TransactionOutcomeEvent<
|
|
25
25
|
AtomIO.TransactionToken<Fn>
|
|
26
26
|
>[],
|
|
27
27
|
) =>
|