@korajs/store 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/adapters/better-sqlite3.cjs +1 -1
  2. package/dist/adapters/better-sqlite3.cjs.map +1 -1
  3. package/dist/adapters/better-sqlite3.d.cts +1 -1
  4. package/dist/adapters/better-sqlite3.d.ts +1 -1
  5. package/dist/adapters/better-sqlite3.js +1 -1
  6. package/dist/adapters/better-sqlite3.js.map +1 -1
  7. package/dist/adapters/indexeddb.cjs +413 -18
  8. package/dist/adapters/indexeddb.cjs.map +1 -1
  9. package/dist/adapters/indexeddb.d.cts +23 -5
  10. package/dist/adapters/indexeddb.d.ts +23 -5
  11. package/dist/adapters/indexeddb.js +166 -19
  12. package/dist/adapters/indexeddb.js.map +1 -1
  13. package/dist/adapters/sqlite-wasm-shared-host.cjs +68 -0
  14. package/dist/adapters/sqlite-wasm-shared-host.cjs.map +1 -0
  15. package/dist/adapters/sqlite-wasm-shared-host.d.cts +2 -0
  16. package/dist/adapters/sqlite-wasm-shared-host.d.ts +2 -0
  17. package/dist/adapters/sqlite-wasm-shared-host.js +66 -0
  18. package/dist/adapters/sqlite-wasm-shared-host.js.map +1 -0
  19. package/dist/adapters/sqlite-wasm-worker.cjs +34 -5
  20. package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
  21. package/dist/adapters/sqlite-wasm-worker.js +34 -5
  22. package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
  23. package/dist/adapters/sqlite-wasm.cjs +249 -2
  24. package/dist/adapters/sqlite-wasm.cjs.map +1 -1
  25. package/dist/adapters/sqlite-wasm.d.cts +15 -3
  26. package/dist/adapters/sqlite-wasm.d.ts +15 -3
  27. package/dist/adapters/sqlite-wasm.js +2 -2
  28. package/dist/audit-trace-store-AM4EWQNZ.js +15 -0
  29. package/dist/backup-JN3LB4YT.js +14 -0
  30. package/dist/backup-JN3LB4YT.js.map +1 -0
  31. package/dist/chunk-56LL4XP6.js +205 -0
  32. package/dist/chunk-56LL4XP6.js.map +1 -0
  33. package/dist/chunk-6AHYGQQT.js +425 -0
  34. package/dist/chunk-6AHYGQQT.js.map +1 -0
  35. package/dist/chunk-7BPETY5Y.js +570 -0
  36. package/dist/chunk-7BPETY5Y.js.map +1 -0
  37. package/dist/chunk-AGN3CIPB.js +188 -0
  38. package/dist/chunk-AGN3CIPB.js.map +1 -0
  39. package/dist/chunk-EZSTD2XC.js +380 -0
  40. package/dist/chunk-EZSTD2XC.js.map +1 -0
  41. package/dist/chunk-MYSJN3DF.js +117 -0
  42. package/dist/chunk-MYSJN3DF.js.map +1 -0
  43. package/dist/{chunk-DXKLAQ6P.js → chunk-XO4LMPAH.js} +1 -1
  44. package/dist/chunk-XO4LMPAH.js.map +1 -0
  45. package/dist/export-audit-5GV6VRDZ.js +15 -0
  46. package/dist/export-audit-5GV6VRDZ.js.map +1 -0
  47. package/dist/index.cjs +3351 -510
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +822 -50
  50. package/dist/index.d.ts +822 -50
  51. package/dist/index.js +1976 -558
  52. package/dist/index.js.map +1 -1
  53. package/dist/internal.cjs +789 -0
  54. package/dist/internal.cjs.map +1 -0
  55. package/dist/internal.d.cts +154 -0
  56. package/dist/internal.d.ts +154 -0
  57. package/dist/internal.js +48 -0
  58. package/dist/internal.js.map +1 -0
  59. package/dist/{sqlite-wasm-channel-46AOWNPM.js → sqlite-wasm-channel-HDDW6UBH.js} +2 -2
  60. package/dist/sqlite-wasm-channel-HDDW6UBH.js.map +1 -0
  61. package/dist/{sqlite-wasm-channel-Lakjuk2E.d.cts → sqlite-wasm-channel-I9y_jObg.d.cts} +1 -0
  62. package/dist/{sqlite-wasm-channel-Lakjuk2E.d.ts → sqlite-wasm-channel-I9y_jObg.d.ts} +1 -0
  63. package/dist/types-BMyHmwvn.d.ts +163 -0
  64. package/dist/types-CTr00g_d.d.cts +163 -0
  65. package/dist/types-DepnRDk_.d.cts +212 -0
  66. package/dist/types-DepnRDk_.d.ts +212 -0
  67. package/package.json +23 -2
  68. package/dist/chunk-DXKLAQ6P.js.map +0 -1
  69. package/dist/chunk-ZP5AXQ3Z.js +0 -179
  70. package/dist/chunk-ZP5AXQ3Z.js.map +0 -1
  71. package/dist/types-DF-KDSK1.d.cts +0 -106
  72. package/dist/types-DF-KDSK1.d.ts +0 -106
  73. /package/dist/{sqlite-wasm-channel-46AOWNPM.js.map → audit-trace-store-AM4EWQNZ.js.map} +0 -0
@@ -0,0 +1,205 @@
1
+ // src/serialization/richtext-serializer.ts
2
+ import * as Y from "yjs";
3
+ var TEXT_KEY = "content";
4
+ function encodeRichtext(value) {
5
+ if (value === null || value === void 0) {
6
+ return null;
7
+ }
8
+ if (typeof value === "string") {
9
+ const doc = new Y.Doc();
10
+ doc.getText(TEXT_KEY).insert(0, value);
11
+ return Y.encodeStateAsUpdate(doc);
12
+ }
13
+ if (value instanceof Uint8Array) {
14
+ return value;
15
+ }
16
+ if (value instanceof ArrayBuffer) {
17
+ return new Uint8Array(value);
18
+ }
19
+ throw new Error("Richtext value must be a string, Uint8Array, ArrayBuffer, null, or undefined.");
20
+ }
21
+ function decodeRichtext(value) {
22
+ if (value === null || value === void 0) {
23
+ return null;
24
+ }
25
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) {
26
+ return new Uint8Array(value);
27
+ }
28
+ if (value instanceof Uint8Array) {
29
+ return value;
30
+ }
31
+ if (value instanceof ArrayBuffer) {
32
+ return new Uint8Array(value);
33
+ }
34
+ throw new Error(
35
+ "Richtext storage value must be Uint8Array, ArrayBuffer, Buffer, null, or undefined."
36
+ );
37
+ }
38
+ function richtextToPlainText(value) {
39
+ const encoded = encodeRichtext(value);
40
+ if (!encoded) return "";
41
+ const doc = new Y.Doc();
42
+ Y.applyUpdate(doc, encoded);
43
+ return doc.getText(TEXT_KEY).toString();
44
+ }
45
+ function richtextStatesEqual(a, b) {
46
+ try {
47
+ return richtextToPlainText(a) === richtextToPlainText(b);
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ // src/serialization/serializer.ts
54
+ import { HybridLogicalClock } from "@korajs/core";
55
+ function serializeRecord(data, fields) {
56
+ const result = {};
57
+ for (const [key, value] of Object.entries(data)) {
58
+ const descriptor = fields[key];
59
+ if (!descriptor) {
60
+ result[key] = value;
61
+ continue;
62
+ }
63
+ result[key] = serializeValue(value, descriptor);
64
+ }
65
+ return result;
66
+ }
67
+ function deserializeRecord(row, fields) {
68
+ const result = {
69
+ id: row.id,
70
+ createdAt: row._created_at,
71
+ updatedAt: row._updated_at
72
+ };
73
+ for (const [key, descriptor] of Object.entries(fields)) {
74
+ const rawValue = row[key];
75
+ if (rawValue === void 0 || rawValue === null) {
76
+ result[key] = rawValue ?? null;
77
+ continue;
78
+ }
79
+ result[key] = deserializeValue(rawValue, descriptor);
80
+ }
81
+ return result;
82
+ }
83
+ var ATOMIC_OPS_KEY = "__kora_atomic_ops__";
84
+ var TX_ID_KEY = "__kora_tx_id__";
85
+ var MUTATION_NAME_KEY = "__kora_mutation__";
86
+ function serializeOperation(op) {
87
+ const hasMetadata = op.transactionId !== void 0 || op.mutationName !== void 0;
88
+ let dataPayload = null;
89
+ if (op.data) {
90
+ dataPayload = { ...op.data };
91
+ if (op.atomicOps !== void 0 && Object.keys(op.atomicOps).length > 0) {
92
+ dataPayload[ATOMIC_OPS_KEY] = op.atomicOps;
93
+ }
94
+ if (op.transactionId !== void 0) {
95
+ dataPayload[TX_ID_KEY] = op.transactionId;
96
+ }
97
+ if (op.mutationName !== void 0) {
98
+ dataPayload[MUTATION_NAME_KEY] = op.mutationName;
99
+ }
100
+ } else if (hasMetadata) {
101
+ dataPayload = {};
102
+ if (op.transactionId !== void 0) {
103
+ dataPayload[TX_ID_KEY] = op.transactionId;
104
+ }
105
+ if (op.mutationName !== void 0) {
106
+ dataPayload[MUTATION_NAME_KEY] = op.mutationName;
107
+ }
108
+ }
109
+ return {
110
+ id: op.id,
111
+ node_id: op.nodeId,
112
+ type: op.type,
113
+ record_id: op.recordId,
114
+ data: dataPayload ? JSON.stringify(dataPayload) : null,
115
+ previous_data: op.previousData ? JSON.stringify(op.previousData) : null,
116
+ timestamp: HybridLogicalClock.serialize(op.timestamp),
117
+ sequence_number: op.sequenceNumber,
118
+ causal_deps: JSON.stringify(op.causalDeps),
119
+ schema_version: op.schemaVersion
120
+ };
121
+ }
122
+ function deserializeOperation(row) {
123
+ let data = null;
124
+ let atomicOps;
125
+ let transactionId;
126
+ let mutationName;
127
+ if (row.data) {
128
+ const parsed = JSON.parse(row.data);
129
+ if (ATOMIC_OPS_KEY in parsed) {
130
+ atomicOps = parsed[ATOMIC_OPS_KEY];
131
+ }
132
+ if (TX_ID_KEY in parsed) {
133
+ transactionId = parsed[TX_ID_KEY];
134
+ }
135
+ if (MUTATION_NAME_KEY in parsed) {
136
+ mutationName = parsed[MUTATION_NAME_KEY];
137
+ }
138
+ const { [ATOMIC_OPS_KEY]: _a, [TX_ID_KEY]: _t, [MUTATION_NAME_KEY]: _m, ...rest } = parsed;
139
+ data = Object.keys(rest).length > 0 ? rest : null;
140
+ }
141
+ return {
142
+ id: row.id,
143
+ nodeId: row.node_id,
144
+ type: row.type,
145
+ collection: "",
146
+ // Collection name is derived from the table name by the caller
147
+ recordId: row.record_id,
148
+ data,
149
+ previousData: row.previous_data ? JSON.parse(row.previous_data) : null,
150
+ timestamp: HybridLogicalClock.deserialize(row.timestamp),
151
+ sequenceNumber: row.sequence_number,
152
+ causalDeps: JSON.parse(row.causal_deps),
153
+ schemaVersion: row.schema_version,
154
+ ...atomicOps !== void 0 ? { atomicOps } : {},
155
+ ...transactionId !== void 0 ? { transactionId } : {},
156
+ ...mutationName !== void 0 ? { mutationName } : {}
157
+ };
158
+ }
159
+ function deserializeOperationWithCollection(row, collection) {
160
+ const op = deserializeOperation(row);
161
+ return { ...op, collection };
162
+ }
163
+ function serializeValue(value, descriptor) {
164
+ if (value === null || value === void 0) {
165
+ return null;
166
+ }
167
+ switch (descriptor.kind) {
168
+ case "boolean":
169
+ return value ? 1 : 0;
170
+ case "array":
171
+ return JSON.stringify(value);
172
+ case "richtext":
173
+ return encodeRichtext(value);
174
+ default:
175
+ return value;
176
+ }
177
+ }
178
+ function deserializeValue(value, descriptor) {
179
+ switch (descriptor.kind) {
180
+ case "boolean":
181
+ return value === 1 || value === true;
182
+ case "array":
183
+ if (typeof value === "string") {
184
+ return JSON.parse(value);
185
+ }
186
+ return value;
187
+ case "richtext":
188
+ return decodeRichtext(value);
189
+ default:
190
+ return value;
191
+ }
192
+ }
193
+
194
+ export {
195
+ encodeRichtext,
196
+ decodeRichtext,
197
+ richtextToPlainText,
198
+ richtextStatesEqual,
199
+ serializeRecord,
200
+ deserializeRecord,
201
+ serializeOperation,
202
+ deserializeOperation,
203
+ deserializeOperationWithCollection
204
+ };
205
+ //# sourceMappingURL=chunk-56LL4XP6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/serialization/richtext-serializer.ts","../src/serialization/serializer.ts"],"sourcesContent":["import * as Y from 'yjs'\n\nconst TEXT_KEY = 'content'\n\nexport type RichtextInput = string | Uint8Array | ArrayBuffer | null | undefined\n\n/**\n * Encodes richtext values into Yjs document updates.\n */\nexport function encodeRichtext(value: RichtextInput): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof value === 'string') {\n\t\tconst doc = new Y.Doc()\n\t\tdoc.getText(TEXT_KEY).insert(0, value)\n\t\treturn Y.encodeStateAsUpdate(doc)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tthrow new Error('Richtext value must be a string, Uint8Array, ArrayBuffer, null, or undefined.')\n}\n\n/**\n * Decodes driver-provided richtext values into Uint8Array.\n */\nexport function decodeRichtext(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tif (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tif (value instanceof Uint8Array) {\n\t\treturn value\n\t}\n\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(value)\n\t}\n\n\tthrow new Error(\n\t\t'Richtext storage value must be Uint8Array, ArrayBuffer, Buffer, null, or undefined.',\n\t)\n}\n\n/**\n * Reads plain text from a richtext Yjs state update.\n */\nexport function richtextToPlainText(value: RichtextInput): string {\n\tconst encoded = encodeRichtext(value)\n\tif (!encoded) return ''\n\n\tconst doc = new Y.Doc()\n\tY.applyUpdate(doc, encoded)\n\treturn doc.getText(TEXT_KEY).toString()\n}\n\n/**\n * Compares two richtext values by decoded plain text.\n * Yjs update bytes are not stable across separate encodes of the same string.\n */\nexport function richtextStatesEqual(a: unknown, b: unknown): boolean {\n\ttry {\n\t\treturn richtextToPlainText(a as RichtextInput) === richtextToPlainText(b as RichtextInput)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import { HybridLogicalClock } from '@korajs/core'\nimport type { CollectionDefinition, FieldDescriptor, Operation } from '@korajs/core'\nimport type { CollectionRecord, OperationRow, RawCollectionRow } from '../types'\nimport { decodeRichtext, encodeRichtext } from './richtext-serializer'\n\n/**\n * Serialize a JS record to SQL-compatible values for INSERT/UPDATE.\n * Transforms: boolean → 0/1, array → JSON string, richtext → Yjs binary update.\n *\n * @param data - The record data with JS-native types\n * @param fields - The field descriptors from the schema\n * @returns An object with SQL-compatible values\n */\nexport function serializeRecord(\n\tdata: Record<string, unknown>,\n\tfields: Record<string, FieldDescriptor>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tconst descriptor = fields[key]\n\t\tif (!descriptor) {\n\t\t\tresult[key] = value\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = serializeValue(value, descriptor)\n\t}\n\treturn result\n}\n\n/**\n * Deserialize a SQL row to JS-native types for the application layer.\n * Transforms: 0/1 → boolean, JSON string → array, strips _deleted, maps _created_at/_updated_at.\n *\n * @param row - The raw SQL row\n * @param fields - The field descriptors from the schema\n * @returns A CollectionRecord with JS-native types\n */\nexport function deserializeRecord(\n\trow: RawCollectionRow,\n\tfields: Record<string, FieldDescriptor>,\n): CollectionRecord {\n\tconst result: CollectionRecord = {\n\t\tid: row.id,\n\t\tcreatedAt: row._created_at,\n\t\tupdatedAt: row._updated_at,\n\t}\n\n\tfor (const [key, descriptor] of Object.entries(fields)) {\n\t\tconst rawValue = row[key]\n\t\tif (rawValue === undefined || rawValue === null) {\n\t\t\tresult[key] = rawValue ?? null\n\t\t\tcontinue\n\t\t}\n\t\tresult[key] = deserializeValue(rawValue, descriptor)\n\t}\n\n\treturn result\n}\n\n/**\n * Internal key used to embed atomicOps metadata in the data JSON column.\n * This avoids adding a new column to the ops table (no migration needed).\n */\nconst ATOMIC_OPS_KEY = '__kora_atomic_ops__'\n\n/**\n * Internal key used to embed transactionId in the data JSON column.\n */\nconst TX_ID_KEY = '__kora_tx_id__'\n\n/**\n * Internal key used to embed mutationName in the data JSON column.\n */\nconst MUTATION_NAME_KEY = '__kora_mutation__'\n\n/**\n * Serialize an Operation to a row for the operations log table.\n *\n * @param op - The operation to serialize\n * @returns An OperationRow suitable for SQL INSERT\n */\nexport function serializeOperation(op: Operation): OperationRow {\n\tconst hasMetadata = op.transactionId !== undefined || op.mutationName !== undefined\n\tlet dataPayload: Record<string, unknown> | null = null\n\tif (op.data) {\n\t\t// Embed metadata in the data JSON when present\n\t\tdataPayload = { ...op.data }\n\t\tif (op.atomicOps !== undefined && Object.keys(op.atomicOps).length > 0) {\n\t\t\tdataPayload[ATOMIC_OPS_KEY] = op.atomicOps\n\t\t}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t} else if (hasMetadata) {\n\t\t// For delete operations (data is null), we still need to store metadata\n\t\tdataPayload = {}\n\t\tif (op.transactionId !== undefined) {\n\t\t\tdataPayload[TX_ID_KEY] = op.transactionId\n\t\t}\n\t\tif (op.mutationName !== undefined) {\n\t\t\tdataPayload[MUTATION_NAME_KEY] = op.mutationName\n\t\t}\n\t}\n\n\treturn {\n\t\tid: op.id,\n\t\tnode_id: op.nodeId,\n\t\ttype: op.type,\n\t\trecord_id: op.recordId,\n\t\tdata: dataPayload ? JSON.stringify(dataPayload) : null,\n\t\tprevious_data: op.previousData ? JSON.stringify(op.previousData) : null,\n\t\ttimestamp: HybridLogicalClock.serialize(op.timestamp),\n\t\tsequence_number: op.sequenceNumber,\n\t\tcausal_deps: JSON.stringify(op.causalDeps),\n\t\tschema_version: op.schemaVersion,\n\t}\n}\n\n/**\n * Deserialize a row from the operations log table back to an Operation.\n *\n * @param row - The raw operation row from SQL\n * @returns The deserialized Operation object\n */\nexport function deserializeOperation(row: OperationRow): Operation {\n\tlet data: Record<string, unknown> | null = null\n\tlet atomicOps: Record<string, unknown> | undefined\n\tlet transactionId: string | undefined\n\tlet mutationName: string | undefined\n\n\tif (row.data) {\n\t\tconst parsed = JSON.parse(row.data) as Record<string, unknown>\n\t\t// Extract embedded metadata keys\n\t\tif (ATOMIC_OPS_KEY in parsed) {\n\t\t\tatomicOps = parsed[ATOMIC_OPS_KEY] as Record<string, unknown>\n\t\t}\n\t\tif (TX_ID_KEY in parsed) {\n\t\t\ttransactionId = parsed[TX_ID_KEY] as string\n\t\t}\n\t\tif (MUTATION_NAME_KEY in parsed) {\n\t\t\tmutationName = parsed[MUTATION_NAME_KEY] as string\n\t\t}\n\t\t// Remove metadata keys from data\n\t\tconst { [ATOMIC_OPS_KEY]: _a, [TX_ID_KEY]: _t, [MUTATION_NAME_KEY]: _m, ...rest } = parsed\n\t\tdata = Object.keys(rest).length > 0 ? rest : null\n\t}\n\n\treturn {\n\t\tid: row.id,\n\t\tnodeId: row.node_id,\n\t\ttype: row.type as Operation['type'],\n\t\tcollection: '', // Collection name is derived from the table name by the caller\n\t\trecordId: row.record_id,\n\t\tdata,\n\t\tpreviousData: row.previous_data\n\t\t\t? (JSON.parse(row.previous_data) as Record<string, unknown>)\n\t\t\t: null,\n\t\ttimestamp: HybridLogicalClock.deserialize(row.timestamp),\n\t\tsequenceNumber: row.sequence_number,\n\t\tcausalDeps: JSON.parse(row.causal_deps) as string[],\n\t\tschemaVersion: row.schema_version,\n\t\t...(atomicOps !== undefined ? { atomicOps: atomicOps as Operation['atomicOps'] } : {}),\n\t\t...(transactionId !== undefined ? { transactionId } : {}),\n\t\t...(mutationName !== undefined ? { mutationName } : {}),\n\t}\n}\n\n/**\n * Deserialize an operation row with collection name already known.\n */\nexport function deserializeOperationWithCollection(\n\trow: OperationRow,\n\tcollection: string,\n): Operation {\n\tconst op = deserializeOperation(row)\n\treturn { ...op, collection }\n}\n\nfunction serializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tif (value === null || value === undefined) {\n\t\treturn null\n\t}\n\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value ? 1 : 0\n\t\tcase 'array':\n\t\t\treturn JSON.stringify(value)\n\t\tcase 'richtext':\n\t\t\treturn encodeRichtext(value as string | Uint8Array | ArrayBuffer)\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n\nfunction deserializeValue(value: unknown, descriptor: FieldDescriptor): unknown {\n\tswitch (descriptor.kind) {\n\t\tcase 'boolean':\n\t\t\treturn value === 1 || value === true\n\t\tcase 'array':\n\t\t\tif (typeof value === 'string') {\n\t\t\t\treturn JSON.parse(value) as unknown[]\n\t\t\t}\n\t\t\treturn value\n\t\tcase 'richtext':\n\t\t\treturn decodeRichtext(value)\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n"],"mappings":";AAAA,YAAY,OAAO;AAEnB,IAAM,WAAW;AAOV,SAAS,eAAe,OAAyC;AACvE,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,MAAM,IAAM,MAAI;AACtB,QAAI,QAAQ,QAAQ,EAAE,OAAO,GAAG,KAAK;AACrC,WAAS,sBAAoB,GAAG;AAAA,EACjC;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,aAAa;AACjC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,QAAM,IAAI,MAAM,+EAA+E;AAChG;AAKO,SAAS,eAAe,OAAmC;AACjE,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,MAAI,OAAO,WAAW,eAAe,OAAO,SAAS,KAAK,GAAG;AAC5D,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,aAAa;AACjC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC5B;AAEA,QAAM,IAAI;AAAA,IACT;AAAA,EACD;AACD;AAKO,SAAS,oBAAoB,OAA8B;AACjE,QAAM,UAAU,eAAe,KAAK;AACpC,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,MAAM,IAAM,MAAI;AACtB,EAAE,cAAY,KAAK,OAAO;AAC1B,SAAO,IAAI,QAAQ,QAAQ,EAAE,SAAS;AACvC;AAMO,SAAS,oBAAoB,GAAY,GAAqB;AACpE,MAAI;AACH,WAAO,oBAAoB,CAAkB,MAAM,oBAAoB,CAAkB;AAAA,EAC1F,QAAQ;AACP,WAAO;AAAA,EACR;AACD;;;AC9EA,SAAS,0BAA0B;AAa5B,SAAS,gBACf,MACA,QAC0B;AAC1B,QAAM,SAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,UAAM,aAAa,OAAO,GAAG;AAC7B,QAAI,CAAC,YAAY;AAChB,aAAO,GAAG,IAAI;AACd;AAAA,IACD;AACA,WAAO,GAAG,IAAI,eAAe,OAAO,UAAU;AAAA,EAC/C;AACA,SAAO;AACR;AAUO,SAAS,kBACf,KACA,QACmB;AACnB,QAAM,SAA2B;AAAA,IAChC,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EAChB;AAEA,aAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,MAAM,GAAG;AACvD,UAAM,WAAW,IAAI,GAAG;AACxB,QAAI,aAAa,UAAa,aAAa,MAAM;AAChD,aAAO,GAAG,IAAI,YAAY;AAC1B;AAAA,IACD;AACA,WAAO,GAAG,IAAI,iBAAiB,UAAU,UAAU;AAAA,EACpD;AAEA,SAAO;AACR;AAMA,IAAM,iBAAiB;AAKvB,IAAM,YAAY;AAKlB,IAAM,oBAAoB;AAQnB,SAAS,mBAAmB,IAA6B;AAC/D,QAAM,cAAc,GAAG,kBAAkB,UAAa,GAAG,iBAAiB;AAC1E,MAAI,cAA8C;AAClD,MAAI,GAAG,MAAM;AAEZ,kBAAc,EAAE,GAAG,GAAG,KAAK;AAC3B,QAAI,GAAG,cAAc,UAAa,OAAO,KAAK,GAAG,SAAS,EAAE,SAAS,GAAG;AACvE,kBAAY,cAAc,IAAI,GAAG;AAAA,IAClC;AACA,QAAI,GAAG,kBAAkB,QAAW;AACnC,kBAAY,SAAS,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,GAAG,iBAAiB,QAAW;AAClC,kBAAY,iBAAiB,IAAI,GAAG;AAAA,IACrC;AAAA,EACD,WAAW,aAAa;AAEvB,kBAAc,CAAC;AACf,QAAI,GAAG,kBAAkB,QAAW;AACnC,kBAAY,SAAS,IAAI,GAAG;AAAA,IAC7B;AACA,QAAI,GAAG,iBAAiB,QAAW;AAClC,kBAAY,iBAAiB,IAAI,GAAG;AAAA,IACrC;AAAA,EACD;AAEA,SAAO;AAAA,IACN,IAAI,GAAG;AAAA,IACP,SAAS,GAAG;AAAA,IACZ,MAAM,GAAG;AAAA,IACT,WAAW,GAAG;AAAA,IACd,MAAM,cAAc,KAAK,UAAU,WAAW,IAAI;AAAA,IAClD,eAAe,GAAG,eAAe,KAAK,UAAU,GAAG,YAAY,IAAI;AAAA,IACnE,WAAW,mBAAmB,UAAU,GAAG,SAAS;AAAA,IACpD,iBAAiB,GAAG;AAAA,IACpB,aAAa,KAAK,UAAU,GAAG,UAAU;AAAA,IACzC,gBAAgB,GAAG;AAAA,EACpB;AACD;AAQO,SAAS,qBAAqB,KAA8B;AAClE,MAAI,OAAuC;AAC3C,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,IAAI,MAAM;AACb,UAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAElC,QAAI,kBAAkB,QAAQ;AAC7B,kBAAY,OAAO,cAAc;AAAA,IAClC;AACA,QAAI,aAAa,QAAQ;AACxB,sBAAgB,OAAO,SAAS;AAAA,IACjC;AACA,QAAI,qBAAqB,QAAQ;AAChC,qBAAe,OAAO,iBAAiB;AAAA,IACxC;AAEA,UAAM,EAAE,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,iBAAiB,GAAG,IAAI,GAAG,KAAK,IAAI;AACpF,WAAO,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAAA,EAC9C;AAEA,SAAO;AAAA,IACN,IAAI,IAAI;AAAA,IACR,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,YAAY;AAAA;AAAA,IACZ,UAAU,IAAI;AAAA,IACd;AAAA,IACA,cAAc,IAAI,gBACd,KAAK,MAAM,IAAI,aAAa,IAC7B;AAAA,IACH,WAAW,mBAAmB,YAAY,IAAI,SAAS;AAAA,IACvD,gBAAgB,IAAI;AAAA,IACpB,YAAY,KAAK,MAAM,IAAI,WAAW;AAAA,IACtC,eAAe,IAAI;AAAA,IACnB,GAAI,cAAc,SAAY,EAAE,UAA+C,IAAI,CAAC;AAAA,IACpF,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,EACtD;AACD;AAKO,SAAS,mCACf,KACA,YACY;AACZ,QAAM,KAAK,qBAAqB,GAAG;AACnC,SAAO,EAAE,GAAG,IAAI,WAAW;AAC5B;AAEA,SAAS,eAAe,OAAgB,YAAsC;AAC7E,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,WAAO;AAAA,EACR;AAEA,UAAQ,WAAW,MAAM;AAAA,IACxB,KAAK;AACJ,aAAO,QAAQ,IAAI;AAAA,IACpB,KAAK;AACJ,aAAO,KAAK,UAAU,KAAK;AAAA,IAC5B,KAAK;AACJ,aAAO,eAAe,KAA0C;AAAA,IACjE;AACC,aAAO;AAAA,EACT;AACD;AAEA,SAAS,iBAAiB,OAAgB,YAAsC;AAC/E,UAAQ,WAAW,MAAM;AAAA,IACxB,KAAK;AACJ,aAAO,UAAU,KAAK,UAAU;AAAA,IACjC,KAAK;AACJ,UAAI,OAAO,UAAU,UAAU;AAC9B,eAAO,KAAK,MAAM,KAAK;AAAA,MACxB;AACA,aAAO;AAAA,IACR,KAAK;AACJ,aAAO,eAAe,KAAK;AAAA,IAC5B;AACC,aAAO;AAAA,EACT;AACD;","names":[]}
@@ -0,0 +1,425 @@
1
+ import {
2
+ Mutex
3
+ } from "./chunk-XO4LMPAH.js";
4
+ import {
5
+ AdapterError,
6
+ StoreNotOpenError,
7
+ WorkerTimeoutError
8
+ } from "./chunk-LAWV6CFH.js";
9
+
10
+ // src/adapters/sqlite-wasm-adapter.ts
11
+ import { generateFullDDL } from "@korajs/core";
12
+
13
+ // src/multi-tab/shared-worker-bridge.ts
14
+ var SW_REQUEST = "kora-sw-request";
15
+ var SW_RESPONSE = "kora-sw-response";
16
+ var SharedWorkerClientBridge = class {
17
+ constructor(sharedWorker, dbName, workerUrl, timeoutMs = 3e4) {
18
+ this.dbName = dbName;
19
+ this.workerUrl = workerUrl;
20
+ this.timeoutMs = timeoutMs;
21
+ this.port = sharedWorker.port;
22
+ this.port.start();
23
+ this.port.addEventListener("message", (event) => {
24
+ const data = event.data;
25
+ if (data?.type !== SW_RESPONSE) {
26
+ return;
27
+ }
28
+ const entry = this.pending.get(data.requestId);
29
+ if (entry) {
30
+ this.pending.delete(data.requestId);
31
+ entry.resolve(data.response);
32
+ }
33
+ });
34
+ }
35
+ dbName;
36
+ workerUrl;
37
+ port;
38
+ pending = /* @__PURE__ */ new Map();
39
+ timeoutMs;
40
+ terminated = false;
41
+ async send(request) {
42
+ if (this.terminated) {
43
+ return {
44
+ id: request.id,
45
+ type: "error",
46
+ message: "SharedWorker bridge terminated",
47
+ code: "BRIDGE_TERMINATED"
48
+ };
49
+ }
50
+ const requestId = crypto.randomUUID();
51
+ const msg = {
52
+ type: SW_REQUEST,
53
+ requestId,
54
+ dbName: this.dbName,
55
+ workerUrl: this.workerUrl,
56
+ request
57
+ };
58
+ return new Promise((resolve, reject) => {
59
+ const timer = setTimeout(() => {
60
+ this.pending.delete(requestId);
61
+ reject(new WorkerTimeoutError(`shared-worker:${request.type}`, this.timeoutMs));
62
+ }, this.timeoutMs);
63
+ this.pending.set(requestId, {
64
+ resolve: (response) => {
65
+ clearTimeout(timer);
66
+ resolve(response);
67
+ },
68
+ reject: (error) => {
69
+ clearTimeout(timer);
70
+ reject(error);
71
+ }
72
+ });
73
+ this.port.postMessage(msg);
74
+ });
75
+ }
76
+ terminate() {
77
+ if (this.terminated) {
78
+ return;
79
+ }
80
+ this.terminated = true;
81
+ this.port.close();
82
+ for (const [, entry] of this.pending) {
83
+ entry.reject(new Error("SharedWorker bridge terminated"));
84
+ }
85
+ this.pending.clear();
86
+ }
87
+ };
88
+
89
+ // src/multi-tab/tab-storage.ts
90
+ var RPC_REQUEST = "kora-worker-request";
91
+ var RPC_RESPONSE = "kora-worker-response";
92
+ function isSharedWorkerStorageSupported() {
93
+ return typeof globalThis !== "undefined" && typeof SharedWorker !== "undefined";
94
+ }
95
+ function isMultiTabStorageSupported() {
96
+ return typeof globalThis !== "undefined" && typeof BroadcastChannel !== "undefined" && typeof navigator !== "undefined" && typeof navigator.locks?.request === "function";
97
+ }
98
+ async function acquireTabStorageSession(dbName) {
99
+ const channelName = `kora-storage-${dbName}`;
100
+ if (!isMultiTabStorageSupported()) {
101
+ return { role: "leader", channelName };
102
+ }
103
+ return new Promise((resolve) => {
104
+ let releaseHeld;
105
+ void navigator.locks.request(
106
+ `kora-leader-${dbName}`,
107
+ { mode: "exclusive", ifAvailable: true },
108
+ (lock) => {
109
+ if (lock === null) {
110
+ resolve({ role: "follower", channelName });
111
+ return;
112
+ }
113
+ resolve({
114
+ role: "leader",
115
+ channelName,
116
+ releaseLock: async () => {
117
+ releaseHeld?.();
118
+ }
119
+ });
120
+ return new Promise((release) => {
121
+ releaseHeld = release;
122
+ });
123
+ }
124
+ );
125
+ });
126
+ }
127
+ function startLeaderRpcRelay(channelName, bridge) {
128
+ const channel = new BroadcastChannel(channelName);
129
+ const onMessage = (event) => {
130
+ const data = event.data;
131
+ if (data?.type !== RPC_REQUEST) {
132
+ return;
133
+ }
134
+ void bridge.send(data.request).then((response) => {
135
+ const msg = {
136
+ type: RPC_RESPONSE,
137
+ requestId: data.requestId,
138
+ response
139
+ };
140
+ channel.postMessage(msg);
141
+ }).catch((error) => {
142
+ const message = error instanceof Error ? error.message : "Worker RPC failed";
143
+ const msg = {
144
+ type: RPC_RESPONSE,
145
+ requestId: data.requestId,
146
+ response: {
147
+ id: data.request.id,
148
+ type: "error",
149
+ message,
150
+ code: "LEADER_RPC_ERROR"
151
+ }
152
+ };
153
+ channel.postMessage(msg);
154
+ });
155
+ };
156
+ channel.addEventListener("message", onMessage);
157
+ return () => {
158
+ channel.removeEventListener("message", onMessage);
159
+ channel.close();
160
+ };
161
+ }
162
+ var FollowerBroadcastBridge = class {
163
+ channel;
164
+ pending = /* @__PURE__ */ new Map();
165
+ timeoutMs;
166
+ terminated = false;
167
+ constructor(channelName, timeoutMs = 3e4) {
168
+ this.timeoutMs = timeoutMs;
169
+ this.channel = new BroadcastChannel(channelName);
170
+ this.channel.addEventListener("message", (event) => {
171
+ const data = event.data;
172
+ if (data?.type !== RPC_RESPONSE) {
173
+ return;
174
+ }
175
+ const entry = this.pending.get(data.requestId);
176
+ if (entry) {
177
+ this.pending.delete(data.requestId);
178
+ entry.resolve(data.response);
179
+ }
180
+ });
181
+ }
182
+ async send(request) {
183
+ if (this.terminated) {
184
+ return {
185
+ id: request.id,
186
+ type: "error",
187
+ message: "Follower bridge terminated",
188
+ code: "BRIDGE_TERMINATED"
189
+ };
190
+ }
191
+ const requestId = crypto.randomUUID();
192
+ const msg = { type: RPC_REQUEST, requestId, request };
193
+ return new Promise((resolve, reject) => {
194
+ const timer = setTimeout(() => {
195
+ this.pending.delete(requestId);
196
+ reject(new WorkerTimeoutError(`follower-rpc:${request.type}`, this.timeoutMs));
197
+ }, this.timeoutMs);
198
+ this.pending.set(requestId, {
199
+ resolve: (response) => {
200
+ clearTimeout(timer);
201
+ resolve(response);
202
+ },
203
+ reject: (error) => {
204
+ clearTimeout(timer);
205
+ reject(error);
206
+ }
207
+ });
208
+ this.channel.postMessage(msg);
209
+ });
210
+ }
211
+ terminate() {
212
+ if (this.terminated) {
213
+ return;
214
+ }
215
+ this.terminated = true;
216
+ this.channel.close();
217
+ for (const [, entry] of this.pending) {
218
+ entry.reject(new Error("Follower bridge terminated"));
219
+ }
220
+ this.pending.clear();
221
+ }
222
+ };
223
+
224
+ // src/adapters/sqlite-wasm-adapter.ts
225
+ var SqliteWasmAdapter = class {
226
+ bridge = null;
227
+ opened = false;
228
+ mutex = new Mutex();
229
+ injectedBridge;
230
+ workerUrl;
231
+ sharedWorkerUrl;
232
+ workerResponseTimeoutMs;
233
+ dbName;
234
+ tabSession = null;
235
+ sharedWorker = null;
236
+ constructor(options = {}) {
237
+ this.injectedBridge = options.bridge;
238
+ this.workerUrl = options.workerUrl;
239
+ this.sharedWorkerUrl = options.sharedWorkerUrl;
240
+ this.workerResponseTimeoutMs = options.workerResponseTimeoutMs ?? 3e4;
241
+ this.dbName = options.dbName ?? "kora-db";
242
+ }
243
+ async open(schema) {
244
+ if (this.opened) return;
245
+ if (this.injectedBridge) {
246
+ this.bridge = this.injectedBridge;
247
+ } else if (this.sharedWorkerUrl && this.workerUrl && isSharedWorkerStorageSupported()) {
248
+ const workerUrlString = typeof this.workerUrl === "string" ? this.workerUrl : this.workerUrl.href;
249
+ const sharedUrl = typeof this.sharedWorkerUrl === "string" ? this.sharedWorkerUrl : this.sharedWorkerUrl.href;
250
+ this.sharedWorker = new SharedWorker(sharedUrl, { name: `kora-sw-${this.dbName}` });
251
+ this.bridge = new SharedWorkerClientBridge(this.sharedWorker, this.dbName, workerUrlString);
252
+ } else if (this.workerUrl) {
253
+ this.tabSession = await acquireTabStorageSession(this.dbName);
254
+ const { WebWorkerBridge } = await import("./sqlite-wasm-channel-HDDW6UBH.js");
255
+ if (this.tabSession.role === "leader") {
256
+ const workerBridge = new WebWorkerBridge(this.workerUrl, this.workerResponseTimeoutMs);
257
+ this.tabSession.stopRelay = startLeaderRpcRelay(this.tabSession.channelName, workerBridge);
258
+ this.bridge = workerBridge;
259
+ } else {
260
+ this.bridge = new FollowerBroadcastBridge(
261
+ this.tabSession.channelName,
262
+ this.workerResponseTimeoutMs
263
+ );
264
+ }
265
+ } else {
266
+ throw new AdapterError(
267
+ 'SqliteWasmAdapter requires either a bridge (for testing) or a workerUrl (for browsers). Pass { bridge: new MockWorkerBridge() } for tests, or { workerUrl: "/worker.js" } for browsers.'
268
+ );
269
+ }
270
+ const ddlStatements = generateFullDDL(schema);
271
+ const response = await this.sendRequest({
272
+ id: 0,
273
+ type: "open",
274
+ ddlStatements,
275
+ dbName: this.dbName
276
+ });
277
+ if (response.type === "error") {
278
+ throw new AdapterError(`Failed to open database: ${response.message}`, {
279
+ code: response.code,
280
+ dbName: this.dbName
281
+ });
282
+ }
283
+ this.opened = true;
284
+ }
285
+ async close() {
286
+ if (!this.bridge) return;
287
+ try {
288
+ await this.sendRequest({ id: 0, type: "close" });
289
+ } finally {
290
+ this.tabSession?.stopRelay?.();
291
+ if (this.tabSession?.releaseLock) {
292
+ await this.tabSession.releaseLock();
293
+ }
294
+ this.tabSession = null;
295
+ this.sharedWorker = null;
296
+ this.bridge.terminate();
297
+ this.bridge = null;
298
+ this.opened = false;
299
+ }
300
+ }
301
+ async execute(sql, params) {
302
+ this.guardOpen();
303
+ const response = await this.sendRequest({ id: 0, type: "execute", sql, params });
304
+ if (response.type === "error") {
305
+ throw new AdapterError(`Execute failed: ${response.message}`, { sql, params });
306
+ }
307
+ }
308
+ async query(sql, params) {
309
+ this.guardOpen();
310
+ const response = await this.sendRequest({ id: 0, type: "query", sql, params });
311
+ if (response.type === "error") {
312
+ throw new AdapterError(`Query failed: ${response.message}`, { sql, params });
313
+ }
314
+ return response.data ?? [];
315
+ }
316
+ async transaction(fn) {
317
+ this.guardOpen();
318
+ const release = await this.mutex.acquire();
319
+ try {
320
+ await this.sendChecked({ id: 0, type: "begin" }, "BEGIN transaction");
321
+ const tx = {
322
+ execute: async (sql, params) => {
323
+ const response = await this.sendRequest({ id: 0, type: "execute", sql, params });
324
+ if (response.type === "error") {
325
+ throw new AdapterError(`Transaction execute failed: ${response.message}`, {
326
+ sql,
327
+ params
328
+ });
329
+ }
330
+ },
331
+ query: async (sql, params) => {
332
+ const response = await this.sendRequest({ id: 0, type: "query", sql, params });
333
+ if (response.type === "error") {
334
+ throw new AdapterError(`Transaction query failed: ${response.message}`, { sql, params });
335
+ }
336
+ return response.data ?? [];
337
+ }
338
+ };
339
+ await fn(tx);
340
+ await this.sendChecked({ id: 0, type: "commit" }, "COMMIT transaction");
341
+ } catch (error) {
342
+ try {
343
+ await this.sendRequest({ id: 0, type: "rollback" });
344
+ } catch {
345
+ }
346
+ throw error;
347
+ } finally {
348
+ release();
349
+ }
350
+ }
351
+ async migrate(from, to, migration) {
352
+ this.guardOpen();
353
+ const release = await this.mutex.acquire();
354
+ try {
355
+ await this.sendChecked({ id: 0, type: "begin" }, "BEGIN migration");
356
+ for (const sql of migration.statements) {
357
+ const response = await this.sendRequest({ id: 0, type: "execute", sql });
358
+ if (response.type === "error") {
359
+ throw new AdapterError(`Migration from v${from} to v${to} failed: ${response.message}`, {
360
+ from,
361
+ to
362
+ });
363
+ }
364
+ }
365
+ await this.sendChecked({ id: 0, type: "commit" }, "COMMIT migration");
366
+ } catch (error) {
367
+ try {
368
+ await this.sendRequest({ id: 0, type: "rollback" });
369
+ } catch {
370
+ }
371
+ if (error instanceof AdapterError) throw error;
372
+ throw new AdapterError(
373
+ `Migration from v${from} to v${to} failed: ${error.message}`,
374
+ { from, to }
375
+ );
376
+ } finally {
377
+ release();
378
+ }
379
+ }
380
+ /**
381
+ * Export the database as a Uint8Array (for IndexedDB persistence).
382
+ * Only available when the database is open.
383
+ */
384
+ async exportDatabase() {
385
+ this.guardOpen();
386
+ const response = await this.sendRequest({ id: 0, type: "export" });
387
+ if (response.type === "error") {
388
+ throw new AdapterError(`Export failed: ${response.message}`);
389
+ }
390
+ return response.data;
391
+ }
392
+ /**
393
+ * Import a serialized database snapshot.
394
+ */
395
+ async importDatabase(data) {
396
+ this.guardOpen();
397
+ const response = await this.sendRequest({ id: 0, type: "import", data });
398
+ if (response.type === "error") {
399
+ throw new AdapterError(`Import failed: ${response.message}`);
400
+ }
401
+ }
402
+ guardOpen() {
403
+ if (!this.opened || !this.bridge) {
404
+ throw new StoreNotOpenError();
405
+ }
406
+ }
407
+ async sendRequest(request) {
408
+ const bridge = this.bridge;
409
+ if (!bridge) {
410
+ throw new StoreNotOpenError();
411
+ }
412
+ return bridge.send(request);
413
+ }
414
+ async sendChecked(request, description) {
415
+ const response = await this.sendRequest(request);
416
+ if (response.type === "error") {
417
+ throw new AdapterError(`${description} failed: ${response.message}`);
418
+ }
419
+ }
420
+ };
421
+
422
+ export {
423
+ SqliteWasmAdapter
424
+ };
425
+ //# sourceMappingURL=chunk-6AHYGQQT.js.map