mcard-js 2.1.49 → 2.1.51

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 (109) hide show
  1. package/dist/CardCollection-EMSBVZP3.js +10 -0
  2. package/dist/CardCollection-KQWR4PCV.js +10 -0
  3. package/dist/CardCollection-ORGE2XBG.js +10 -0
  4. package/dist/EngineRegistry-ABZXHZWO.js +17 -0
  5. package/dist/EngineRegistry-EIOT4MUZ.js +17 -0
  6. package/dist/EngineRegistry-IQ6EVO72.js +17 -0
  7. package/dist/EngineRegistry-PHRFXEOE.js +17 -0
  8. package/dist/IndexedDBEngine-EWA3SLAO.js +12 -0
  9. package/dist/IndexedDBEngine-FXAD42F3.js +12 -0
  10. package/dist/IndexedDBEngine-RD4447IS.js +12 -0
  11. package/dist/LLMRuntime-ARUWOX52.js +17 -0
  12. package/dist/LLMRuntime-C3XCO7WF.js +17 -0
  13. package/dist/LLMRuntime-CQ7X43QR.js +17 -0
  14. package/dist/LLMRuntime-PD45COKE.js +17 -0
  15. package/dist/LLMRuntime-QOUMLT33.js +17 -0
  16. package/dist/LLMRuntime-SZNLTHD7.js +17 -0
  17. package/dist/LLMRuntime-TVJGK2BG.js +17 -0
  18. package/dist/LambdaRuntime-25GMEJCU.js +19 -0
  19. package/dist/LambdaRuntime-7KQUMHPI.js +19 -0
  20. package/dist/LambdaRuntime-DRT7ODPC.js +19 -0
  21. package/dist/LambdaRuntime-HSREEYQG.js +19 -0
  22. package/dist/LambdaRuntime-IH7NVG6Z.js +19 -0
  23. package/dist/LambdaRuntime-MPG27FM2.js +19 -0
  24. package/dist/LambdaRuntime-ODSWIMNM.js +19 -0
  25. package/dist/LambdaRuntime-PHGRZYAW.js +19 -0
  26. package/dist/LambdaRuntime-QOEYR37L.js +19 -0
  27. package/dist/LambdaRuntime-RT33TFN2.js +19 -0
  28. package/dist/LambdaRuntime-W6TQBP5O.js +19 -0
  29. package/dist/Loader-35WSUC53.js +14 -0
  30. package/dist/Loader-STS3G4OQ.js +16 -0
  31. package/dist/Loader-W22AEM6F.js +12 -0
  32. package/dist/Loader-YBPWP43S.js +12 -0
  33. package/dist/Loader-ZYSS7B4D.js +12 -0
  34. package/dist/NetworkRuntime-KR2QITXV.js +987 -0
  35. package/dist/NetworkRuntime-S6V2CMZV.js +1575 -0
  36. package/dist/OllamaProvider-2ANW6EB2.js +9 -0
  37. package/dist/OllamaProvider-5QFJKYAC.js +9 -0
  38. package/dist/OllamaProvider-6QXJGR7V.js +9 -0
  39. package/dist/OllamaProvider-ABEEFX7M.js +9 -0
  40. package/dist/OllamaProvider-Z2CGY5LY.js +9 -0
  41. package/dist/VCard-225X42W7.js +25 -0
  42. package/dist/chunk-2APJYBH4.js +368 -0
  43. package/dist/chunk-4DFTWDRB.js +497 -0
  44. package/dist/chunk-4PBRTFSY.js +112 -0
  45. package/dist/chunk-4T3H25AP.js +299 -0
  46. package/dist/chunk-5DFXPIRL.js +42 -0
  47. package/dist/chunk-5HRZV4R3.js +217 -0
  48. package/dist/chunk-6ZRJXVJ3.js +529 -0
  49. package/dist/chunk-7N7JYGN2.js +364 -0
  50. package/dist/chunk-7QTJUGYQ.js +74 -0
  51. package/dist/chunk-7TXIPJI2.js +2360 -0
  52. package/dist/chunk-BFJUD527.js +2369 -0
  53. package/dist/chunk-CHXIVTQV.js +364 -0
  54. package/dist/chunk-DM2ABCA4.js +497 -0
  55. package/dist/chunk-DTPHGTBQ.js +275 -0
  56. package/dist/chunk-EDAJ5FO6.js +405 -0
  57. package/dist/chunk-ETJWXHKZ.js +246 -0
  58. package/dist/chunk-FLYGNPUC.js +2369 -0
  59. package/dist/chunk-FSDRDWOP.js +34 -0
  60. package/dist/chunk-GIKMCG4D.js +497 -0
  61. package/dist/chunk-IJKS3LGK.js +428 -0
  62. package/dist/chunk-JUQ2VQZA.js +428 -0
  63. package/dist/chunk-JVW4J7BY.js +2369 -0
  64. package/dist/chunk-JWTRVEC3.js +2369 -0
  65. package/dist/chunk-KJM4C65U.js +299 -0
  66. package/dist/chunk-KMC566CN.js +591 -0
  67. package/dist/chunk-KMNP6DBL.js +455 -0
  68. package/dist/chunk-LVU7O5IY.js +597 -0
  69. package/dist/chunk-M4C6RWLA.js +373 -0
  70. package/dist/chunk-NAAAKSEO.js +541 -0
  71. package/dist/chunk-NKIXLPHL.js +373 -0
  72. package/dist/chunk-NOEDMK7I.js +428 -0
  73. package/dist/chunk-NOPYSBOQ.js +2360 -0
  74. package/dist/chunk-P4G42QCY.js +2369 -0
  75. package/dist/chunk-PKLONZCF.js +253 -0
  76. package/dist/chunk-PNGECWPN.js +597 -0
  77. package/dist/chunk-PYP6T64W.js +217 -0
  78. package/dist/chunk-QFT3COE2.js +217 -0
  79. package/dist/chunk-QFZFXMNX.js +275 -0
  80. package/dist/chunk-QZGRQRJP.js +2369 -0
  81. package/dist/chunk-R3XRBAM7.js +253 -0
  82. package/dist/chunk-RYP66UMH.js +74 -0
  83. package/dist/chunk-RZIZYRLF.js +112 -0
  84. package/dist/chunk-T43V44RS.js +2369 -0
  85. package/dist/chunk-UCNVX5BZ.js +74 -0
  86. package/dist/chunk-UDF7HS4V.js +368 -0
  87. package/dist/chunk-VJPXJVEH.js +299 -0
  88. package/dist/chunk-VW3KBDK5.js +74 -0
  89. package/dist/chunk-X72XIYSN.js +364 -0
  90. package/dist/chunk-XETU7TV4.js +112 -0
  91. package/dist/chunk-Y4BT6LHA.js +368 -0
  92. package/dist/chunk-YQGB6BIA.js +2369 -0
  93. package/dist/chunk-ZEQPO3XV.js +217 -0
  94. package/dist/chunk-ZKRKWXEQ.js +2369 -0
  95. package/dist/chunk-ZMK2HTZ5.js +275 -0
  96. package/dist/constants-CLB7B6MN.js +101 -0
  97. package/dist/constants-O343SMHL.js +103 -0
  98. package/dist/constants-YPGDEX5X.js +103 -0
  99. package/dist/index.browser.cjs +11 -5
  100. package/dist/index.browser.js +12 -12
  101. package/dist/index.cjs +2358 -1896
  102. package/dist/index.d.cts +934 -776
  103. package/dist/index.d.ts +934 -776
  104. package/dist/index.js +1353 -1271
  105. package/dist/storage/SqliteNodeEngine.cjs +12 -6
  106. package/dist/storage/SqliteNodeEngine.js +4 -4
  107. package/dist/storage/SqliteWasmEngine.cjs +11 -5
  108. package/dist/storage/SqliteWasmEngine.js +4 -4
  109. package/package.json +5 -3
@@ -0,0 +1,497 @@
1
+ import {
2
+ createPage
3
+ } from "./chunk-3EIBJPNF.js";
4
+ import {
5
+ init_Handle,
6
+ validateHandle
7
+ } from "./chunk-ADV52544.js";
8
+ import {
9
+ DEFAULT_PAGE_SIZE
10
+ } from "./chunk-PKLONZCF.js";
11
+
12
+ // src/storage/schema.ts
13
+ import { get_core_schema, get_vector_schema } from "mcard-wasm";
14
+ var TABLE_LAYERS = {
15
+ // Layer 1: Core
16
+ "card": "core",
17
+ // Layer 2: Handle System
18
+ "handle_registry": "handle",
19
+ "handle_history": "handle",
20
+ // Layer 3: Vector Storage
21
+ "mcard_vector_metadata": "vector",
22
+ "mcard_embeddings": "vector",
23
+ "mcard_fts": "vector",
24
+ // Layer 4: Semantic Versioning
25
+ "handle_version_vectors": "semantic",
26
+ "version_similarity_cache": "semantic",
27
+ // Layer 5: Knowledge Graph
28
+ "graph_entities": "graph",
29
+ "graph_relationships": "graph",
30
+ "graph_communities": "graph",
31
+ "graph_extractions": "graph",
32
+ // Metadata
33
+ "schema_version": "metadata"
34
+ };
35
+ var MCardSchema = class _MCardSchema {
36
+ static instance = null;
37
+ schemaPath = "";
38
+ rawSql = "";
39
+ statements = [];
40
+ tables = /* @__PURE__ */ new Map();
41
+ indexes = /* @__PURE__ */ new Map();
42
+ loaded = false;
43
+ constructor() {
44
+ }
45
+ /**
46
+ * Get the singleton instance.
47
+ */
48
+ static getInstance() {
49
+ if (!_MCardSchema.instance) {
50
+ _MCardSchema.instance = new _MCardSchema();
51
+ _MCardSchema.instance.load();
52
+ }
53
+ return _MCardSchema.instance;
54
+ }
55
+ /**
56
+ * Reset the singleton (for testing).
57
+ */
58
+ static resetInstance() {
59
+ _MCardSchema.instance = null;
60
+ }
61
+ load() {
62
+ if (this.loaded) return;
63
+ this.schemaPath = "WASM_MEMORY_SPACE";
64
+ this.rawSql = get_core_schema();
65
+ const vectorSql = get_vector_schema();
66
+ if (vectorSql) {
67
+ this.rawSql += "\n\n" + vectorSql;
68
+ }
69
+ this.statements = this.parseStatements(this.rawSql);
70
+ for (const stmt of this.statements) {
71
+ const name = this.extractName(stmt);
72
+ if (name) {
73
+ const upper = stmt.toUpperCase();
74
+ if (upper.includes("CREATE TABLE") || upper.includes("CREATE VIRTUAL TABLE")) {
75
+ this.tables.set(name.toLowerCase(), stmt);
76
+ } else if (upper.includes("CREATE INDEX")) {
77
+ this.indexes.set(name.toLowerCase(), stmt);
78
+ }
79
+ }
80
+ }
81
+ this.loaded = true;
82
+ }
83
+ parseStatements(sql) {
84
+ sql = sql.replace(/\/\*[\s\S]*?\*\//g, "");
85
+ const statements = [];
86
+ let current = [];
87
+ for (const line of sql.split("\n")) {
88
+ const stripped = line.split("--")[0].trim();
89
+ if (!stripped) continue;
90
+ current.push(stripped);
91
+ if (stripped.endsWith(";")) {
92
+ const statement = current.join(" ");
93
+ if (!statement.trim().toUpperCase().startsWith("INSERT")) {
94
+ statements.push(statement);
95
+ }
96
+ current = [];
97
+ }
98
+ }
99
+ return statements.filter((s) => s.trim());
100
+ }
101
+ extractName(statement) {
102
+ let match = statement.match(/CREATE\s+(?:VIRTUAL\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)/i);
103
+ if (match) return match[1];
104
+ match = statement.match(/CREATE\s+INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)/i);
105
+ if (match) return match[1];
106
+ return null;
107
+ }
108
+ // ─────────────────────────────────────────────────────────────────────────
109
+ // Schema Access
110
+ // ─────────────────────────────────────────────────────────────────────────
111
+ getSchemaPath() {
112
+ return this.schemaPath;
113
+ }
114
+ getTable(tableName) {
115
+ return this.tables.get(tableName.toLowerCase());
116
+ }
117
+ getIndex(indexName) {
118
+ return this.indexes.get(indexName.toLowerCase());
119
+ }
120
+ getAllTables() {
121
+ return new Map(this.tables);
122
+ }
123
+ getAllIndexes() {
124
+ return new Map(this.indexes);
125
+ }
126
+ getAllStatements() {
127
+ return [...this.statements];
128
+ }
129
+ getTablesByLayer(layer) {
130
+ return Object.entries(TABLE_LAYERS).filter(([_, l]) => l === layer).map(([name, _]) => name);
131
+ }
132
+ getLayerStatements(layer) {
133
+ const statements = [];
134
+ const tables = this.getTablesByLayer(layer);
135
+ for (const table of tables) {
136
+ const stmt = this.getTable(table);
137
+ if (stmt) statements.push(stmt);
138
+ }
139
+ for (const [_, stmt] of this.indexes) {
140
+ const match = stmt.match(/ON\s+(\w+)/i);
141
+ if (match && tables.includes(match[1].toLowerCase())) {
142
+ statements.push(stmt);
143
+ }
144
+ }
145
+ return statements;
146
+ }
147
+ // ─────────────────────────────────────────────────────────────────────────
148
+ // Database Initialization
149
+ // ─────────────────────────────────────────────────────────────────────────
150
+ execStatements(db, statements) {
151
+ for (const stmt of statements) {
152
+ db.exec(stmt);
153
+ }
154
+ return statements.length;
155
+ }
156
+ initLayer(db, layer) {
157
+ return this.execStatements(db, this.getLayerStatements(layer));
158
+ }
159
+ initCoreTables(db) {
160
+ return this.initLayer(db, "core");
161
+ }
162
+ initHandleTables(db) {
163
+ return this.initLayer(db, "handle");
164
+ }
165
+ initVectorTables(db, enableFts = true) {
166
+ const statements = this.getLayerStatements("vector").filter((s) => enableFts || !s.toLowerCase().includes("fts"));
167
+ return this.execStatements(db, statements);
168
+ }
169
+ initSemanticTables(db) {
170
+ return this.initLayer(db, "semantic");
171
+ }
172
+ initGraphTables(db) {
173
+ return this.initLayer(db, "graph");
174
+ }
175
+ initAllTables(db, options = {}) {
176
+ const { enableFts = true, enableGraph = true, enableSemantic = true } = options;
177
+ let count = 0;
178
+ count += this.initCoreTables(db);
179
+ count += this.initHandleTables(db);
180
+ count += this.initVectorTables(db, enableFts);
181
+ if (enableSemantic) {
182
+ count += this.initSemanticTables(db);
183
+ }
184
+ if (enableGraph) {
185
+ count += this.initGraphTables(db);
186
+ }
187
+ return count;
188
+ }
189
+ initVec0Table(db, dimensions) {
190
+ db.exec(`
191
+ CREATE VIRTUAL TABLE IF NOT EXISTS mcard_vec USING vec0(
192
+ metadata_id INTEGER PRIMARY KEY,
193
+ embedding float[${dimensions}]
194
+ )
195
+ `);
196
+ }
197
+ };
198
+ function getSchemaInstance() {
199
+ return MCardSchema.getInstance();
200
+ }
201
+ var CARD_TABLE_SCHEMA = getSchemaInstance().getTable("card") || "";
202
+ var HANDLE_REGISTRY_SCHEMA = getSchemaInstance().getTable("handle_registry") || "";
203
+ var HANDLE_HISTORY_SCHEMA = getSchemaInstance().getTable("handle_history") || "";
204
+ var HANDLE_INDEX_SCHEMA = getSchemaInstance().getIndex("idx_handle_current_hash") || "";
205
+ var VECTOR_METADATA_SCHEMA = getSchemaInstance().getTable("mcard_vector_metadata") || "";
206
+ var VECTOR_METADATA_INDEX = getSchemaInstance().getIndex("idx_vector_metadata_hash") || "";
207
+ var VECTOR_EMBEDDINGS_SCHEMA = getSchemaInstance().getTable("mcard_embeddings") || "";
208
+ var VECTOR_FTS_SCHEMA = getSchemaInstance().getTable("mcard_fts") || "";
209
+ var HANDLE_VERSION_VECTORS_SCHEMA = getSchemaInstance().getTable("handle_version_vectors") || "";
210
+ var HANDLE_VERSION_VECTORS_INDEXES = [
211
+ getSchemaInstance().getIndex("idx_hvv_handle"),
212
+ getSchemaInstance().getIndex("idx_hvv_hash"),
213
+ getSchemaInstance().getIndex("idx_hvv_current"),
214
+ getSchemaInstance().getIndex("idx_hvv_parent")
215
+ ].filter(Boolean).join("; ");
216
+ var VERSION_SIMILARITY_CACHE_SCHEMA = getSchemaInstance().getTable("version_similarity_cache") || "";
217
+ var VERSION_SIMILARITY_CACHE_INDEX = getSchemaInstance().getIndex("idx_vsc_handle") || "";
218
+ var GRAPH_ENTITY_SCHEMA = getSchemaInstance().getTable("graph_entities") || "";
219
+ var GRAPH_ENTITY_INDEX_NAME = getSchemaInstance().getIndex("idx_entity_name") || "";
220
+ var GRAPH_ENTITY_INDEX_TYPE = getSchemaInstance().getIndex("idx_entity_type") || "";
221
+ var GRAPH_ENTITY_INDEX_SOURCE = getSchemaInstance().getIndex("idx_entity_source") || "";
222
+ var GRAPH_RELATIONSHIP_SCHEMA = getSchemaInstance().getTable("graph_relationships") || "";
223
+ var GRAPH_RELATIONSHIP_INDEX_SOURCE = getSchemaInstance().getIndex("idx_rel_source") || "";
224
+ var GRAPH_RELATIONSHIP_INDEX_TARGET = getSchemaInstance().getIndex("idx_rel_target") || "";
225
+ var GRAPH_COMMUNITY_SCHEMA = getSchemaInstance().getTable("graph_communities") || "";
226
+ var GRAPH_COMMUNITY_INDEX_LEVEL = getSchemaInstance().getIndex("idx_community_level") || "";
227
+ var GRAPH_EXTRACTION_SCHEMA = getSchemaInstance().getTable("graph_extractions") || "";
228
+ var CORE_SCHEMAS = {
229
+ card: CARD_TABLE_SCHEMA,
230
+ handleRegistry: HANDLE_REGISTRY_SCHEMA,
231
+ handleHistory: HANDLE_HISTORY_SCHEMA,
232
+ handleIndex: HANDLE_INDEX_SCHEMA
233
+ };
234
+ function initCoreSchemas(db) {
235
+ const schema = MCardSchema.getInstance();
236
+ schema.initCoreTables(db);
237
+ schema.initHandleTables(db);
238
+ }
239
+
240
+ // src/storage/engines/AbstractSqlEngine.ts
241
+ init_Handle();
242
+ var AbstractSqlEngine = class {
243
+ /**
244
+ * SQL expression for casting content to text in search queries.
245
+ * Override in subclasses: SQLite uses 'TEXT', DuckDB uses 'VARCHAR'.
246
+ */
247
+ get castContentAs() {
248
+ return "TEXT";
249
+ }
250
+ // ======================================================================
251
+ // Concrete: Card Operations (shared across all SQL engines)
252
+ // ======================================================================
253
+ /**
254
+ * Add a card. Default uses INSERT OR REPLACE (SQLite).
255
+ * DuckDB overrides with DELETE + INSERT.
256
+ */
257
+ async add(card) {
258
+ const contentBytes = card.content instanceof Uint8Array ? card.content : new TextEncoder().encode(String(card.content));
259
+ await this.execSql(
260
+ "INSERT OR REPLACE INTO card (hash, content, g_time) VALUES (?, ?, ?)",
261
+ card.hash,
262
+ contentBytes,
263
+ card.g_time
264
+ );
265
+ return card.hash;
266
+ }
267
+ async get(hash) {
268
+ const rows = await this.queryRows(
269
+ "SELECT hash, content, g_time FROM card WHERE hash = ?",
270
+ hash
271
+ );
272
+ if (rows.length === 0) return null;
273
+ return this.rowToCard(rows[0]);
274
+ }
275
+ async delete(hash) {
276
+ await this.execSql("DELETE FROM card WHERE hash = ?", hash);
277
+ }
278
+ async getPage(pageNumber = 1, pageSize = DEFAULT_PAGE_SIZE) {
279
+ if (pageNumber < 1) throw new Error("Page number must be >= 1");
280
+ if (pageSize < 1) throw new Error("Page size must be >= 1");
281
+ const totalItems = await this.count();
282
+ const offset = (pageNumber - 1) * pageSize;
283
+ const rows = await this.queryRows(
284
+ "SELECT hash, content, g_time FROM card ORDER BY g_time DESC LIMIT ? OFFSET ?",
285
+ pageSize,
286
+ offset
287
+ );
288
+ const items = rows.map((r) => this.rowToCard(r));
289
+ return createPage(items, totalItems, pageNumber, pageSize);
290
+ }
291
+ async count() {
292
+ const rows = await this.queryRows("SELECT COUNT(*) as cnt FROM card");
293
+ return Number(rows[0]?.cnt ?? 0);
294
+ }
295
+ async searchByHash(hashPrefix) {
296
+ const rows = await this.queryRows(
297
+ "SELECT hash, content, g_time FROM card WHERE hash LIKE ?",
298
+ `${hashPrefix}%`
299
+ );
300
+ return rows.map((r) => this.rowToCard(r));
301
+ }
302
+ async search(queryStr, pageNumber = 1, pageSize = DEFAULT_PAGE_SIZE) {
303
+ if (pageNumber < 1) throw new Error("Page number must be >= 1");
304
+ if (pageSize < 1) throw new Error("Page size must be >= 1");
305
+ const offset = (pageNumber - 1) * pageSize;
306
+ const pattern = `%${queryStr}%`;
307
+ const cast = this.castContentAs;
308
+ const countRows = await this.queryRows(
309
+ `SELECT COUNT(*) as cnt FROM card WHERE CAST(content AS ${cast}) LIKE ?`,
310
+ pattern
311
+ );
312
+ const totalItems = Number(countRows[0]?.cnt ?? 0);
313
+ const rows = await this.queryRows(
314
+ `SELECT hash, content, g_time FROM card WHERE CAST(content AS ${cast}) LIKE ? ORDER BY g_time DESC LIMIT ? OFFSET ?`,
315
+ pattern,
316
+ pageSize,
317
+ offset
318
+ );
319
+ const items = rows.map((r) => this.rowToCard(r));
320
+ return createPage(items, totalItems, pageNumber, pageSize);
321
+ }
322
+ async getAll() {
323
+ const rows = await this.queryRows("SELECT hash, content, g_time FROM card ORDER BY g_time DESC");
324
+ return rows.map((r) => this.rowToCard(r));
325
+ }
326
+ // ======================================================================
327
+ // Concrete: clear (FK-safe delete order)
328
+ // ======================================================================
329
+ async clear() {
330
+ await this.execSql("DELETE FROM handle_history");
331
+ await this.execSql("DELETE FROM handle_registry");
332
+ await this.execSql("DELETE FROM card");
333
+ }
334
+ // ======================================================================
335
+ // Concrete: Handle Operations
336
+ // ======================================================================
337
+ async registerHandle(handle, hash) {
338
+ const normalized = validateHandle(handle);
339
+ const now = (/* @__PURE__ */ new Date()).toISOString();
340
+ const existing = await this.queryRows(
341
+ "SELECT handle FROM handle_registry WHERE handle = ?",
342
+ normalized
343
+ );
344
+ if (existing.length > 0) {
345
+ throw new Error(`Handle '${handle}' already exists.`);
346
+ }
347
+ await this.execSql(
348
+ "INSERT INTO handle_registry (handle, current_hash, created_at, updated_at) VALUES (?, ?, ?, ?)",
349
+ normalized,
350
+ hash,
351
+ now,
352
+ now
353
+ );
354
+ }
355
+ async resolveHandle(handle) {
356
+ const normalized = validateHandle(handle);
357
+ const rows = await this.queryRows(
358
+ "SELECT current_hash FROM handle_registry WHERE handle = ?",
359
+ normalized
360
+ );
361
+ if (rows.length === 0) return null;
362
+ return String(rows[0].current_hash);
363
+ }
364
+ async getByHandle(handle) {
365
+ const hash = await this.resolveHandle(handle);
366
+ if (!hash) return null;
367
+ return this.get(hash);
368
+ }
369
+ async updateHandle(handle, newHash) {
370
+ const normalized = validateHandle(handle);
371
+ const now = (/* @__PURE__ */ new Date()).toISOString();
372
+ const rows = await this.queryRows(
373
+ "SELECT current_hash FROM handle_registry WHERE handle = ?",
374
+ normalized
375
+ );
376
+ if (rows.length === 0) {
377
+ throw new Error(`Handle '${handle}' not found.`);
378
+ }
379
+ const previousHash = String(rows[0].current_hash);
380
+ await this.execSql(
381
+ "INSERT INTO handle_history (handle, previous_hash, changed_at) VALUES (?, ?, ?)",
382
+ normalized,
383
+ previousHash,
384
+ now
385
+ );
386
+ await this.execSql(
387
+ "UPDATE handle_registry SET current_hash = ?, updated_at = ? WHERE handle = ?",
388
+ newHash,
389
+ now,
390
+ normalized
391
+ );
392
+ return previousHash;
393
+ }
394
+ async getHandleHistory(handle) {
395
+ const normalized = validateHandle(handle);
396
+ const rows = await this.queryRows(
397
+ "SELECT previous_hash, changed_at FROM handle_history WHERE handle = ? ORDER BY id DESC",
398
+ normalized
399
+ );
400
+ return rows.map((r) => ({
401
+ previousHash: String(r.previous_hash),
402
+ changedAt: String(r.changed_at)
403
+ }));
404
+ }
405
+ async pruneHandleHistory(handle, options = {}) {
406
+ const normalized = validateHandle(handle);
407
+ if (options.deleteAll) {
408
+ return this.execSql("DELETE FROM handle_history WHERE handle = ?", normalized);
409
+ } else if (options.olderThan) {
410
+ return this.execSql(
411
+ "DELETE FROM handle_history WHERE handle = ? AND changed_at < ?",
412
+ normalized,
413
+ options.olderThan
414
+ );
415
+ }
416
+ return 0;
417
+ }
418
+ // ======================================================================
419
+ // Concrete: Handle Management Operations
420
+ // ======================================================================
421
+ async getAllHandles() {
422
+ const rows = await this.queryRows("SELECT handle, current_hash FROM handle_registry");
423
+ return rows.map((r) => ({
424
+ handle: String(r.handle),
425
+ hash: String(r.current_hash)
426
+ }));
427
+ }
428
+ async removeHandle(handle) {
429
+ const normalized = validateHandle(handle);
430
+ await this.execSql("DELETE FROM handle_history WHERE handle = ?", normalized);
431
+ await this.execSql("DELETE FROM handle_registry WHERE handle = ?", normalized);
432
+ }
433
+ async renameHandle(oldHandle, newHandle) {
434
+ const normalizedOld = validateHandle(oldHandle);
435
+ const normalizedNew = validateHandle(newHandle);
436
+ if (normalizedOld === normalizedNew) return;
437
+ const existsOld = await this.queryRows(
438
+ "SELECT handle FROM handle_registry WHERE handle = ?",
439
+ normalizedOld
440
+ );
441
+ if (existsOld.length === 0) throw new Error(`Handle '${oldHandle}' not found.`);
442
+ const existsNew = await this.queryRows(
443
+ "SELECT handle FROM handle_registry WHERE handle = ?",
444
+ normalizedNew
445
+ );
446
+ if (existsNew.length > 0) throw new Error(`Handle '${newHandle}' already exists.`);
447
+ const oldRow = await this.queryRows(
448
+ "SELECT current_hash, created_at, updated_at FROM handle_registry WHERE handle = ?",
449
+ normalizedOld
450
+ );
451
+ await this.execSql(
452
+ "INSERT INTO handle_registry (handle, current_hash, created_at, updated_at) VALUES (?, ?, ?, ?)",
453
+ normalizedNew,
454
+ String(oldRow[0].current_hash),
455
+ String(oldRow[0].created_at),
456
+ String(oldRow[0].updated_at)
457
+ );
458
+ await this.execSql(
459
+ "UPDATE handle_history SET handle = ? WHERE handle = ?",
460
+ normalizedNew,
461
+ normalizedOld
462
+ );
463
+ await this.execSql(
464
+ "DELETE FROM handle_registry WHERE handle = ?",
465
+ normalizedOld
466
+ );
467
+ }
468
+ async deleteHistoryEntry(handle, previousHash) {
469
+ const normalized = validateHandle(handle);
470
+ const rOutRows = await this.queryRows(
471
+ "SELECT id, previous_hash FROM handle_history WHERE handle = ? AND previous_hash = ? ORDER BY id DESC LIMIT 1",
472
+ normalized,
473
+ previousHash
474
+ );
475
+ if (rOutRows.length === 0) return;
476
+ const rOutId = Number(rOutRows[0].id);
477
+ const rInRows = await this.queryRows(
478
+ "SELECT id, previous_hash FROM handle_history WHERE handle = ? AND id < ? ORDER BY id DESC LIMIT 1",
479
+ normalized,
480
+ rOutId
481
+ );
482
+ if (rInRows.length > 0) {
483
+ const rInId = Number(rInRows[0].id);
484
+ const rInPrevHash = String(rInRows[0].previous_hash);
485
+ await this.execSql("UPDATE handle_history SET previous_hash = ? WHERE id = ?", rInPrevHash, rOutId);
486
+ await this.execSql("DELETE FROM handle_history WHERE id = ?", rInId);
487
+ } else {
488
+ await this.execSql("DELETE FROM handle_history WHERE id = ?", rOutId);
489
+ }
490
+ }
491
+ };
492
+
493
+ export {
494
+ CORE_SCHEMAS,
495
+ initCoreSchemas,
496
+ AbstractSqlEngine
497
+ };
@@ -0,0 +1,112 @@
1
+ import {
2
+ AbstractSqlEngine,
3
+ CORE_SCHEMAS
4
+ } from "./chunk-DM2ABCA4.js";
5
+ import {
6
+ MCard
7
+ } from "./chunk-GGQCF7ZK.js";
8
+ import {
9
+ DEFAULT_SQLJS_WASM_URL
10
+ } from "./chunk-R3XRBAM7.js";
11
+
12
+ // src/storage/engines/SqliteWasmEngine.ts
13
+ var SqliteWasmEngine = class extends AbstractSqlEngine {
14
+ db = null;
15
+ SQL = null;
16
+ /**
17
+ * Initialize the database
18
+ * @param wasmUrl URL to sql-wasm.wasm file (optional, defaults to CDN)
19
+ * @param existingData Optional existing database as Uint8Array
20
+ */
21
+ async init(wasmUrl, existingData) {
22
+ const initSqlJs = (await import("sql.js")).default;
23
+ const SQL = await initSqlJs({
24
+ locateFile: (file) => wasmUrl || `${DEFAULT_SQLJS_WASM_URL}${file}`
25
+ });
26
+ this.SQL = SQL;
27
+ this.db = existingData ? new SQL.Database(existingData) : new SQL.Database();
28
+ this.db.run(CORE_SCHEMAS.card);
29
+ this.db.run(CORE_SCHEMAS.handleRegistry);
30
+ this.db.run(CORE_SCHEMAS.handleHistory);
31
+ this.db.run(CORE_SCHEMAS.handleIndex);
32
+ }
33
+ ensureDb() {
34
+ if (!this.db) throw new Error("Database not initialized. Call init() first.");
35
+ return this.db;
36
+ }
37
+ // ======================================================================
38
+ // AbstractSqlEngine primitives
39
+ // ======================================================================
40
+ async queryRows(sql, ...params) {
41
+ const db = this.ensureDb();
42
+ const stmt = db.prepare(sql);
43
+ if (params.length > 0) stmt.bind(params);
44
+ const results = [];
45
+ while (stmt.step()) {
46
+ const row = stmt.getAsObject();
47
+ results.push(row);
48
+ }
49
+ stmt.free();
50
+ return results;
51
+ }
52
+ async execSql(sql, ...params) {
53
+ const db = this.ensureDb();
54
+ if (params.length === 0) {
55
+ db.run(sql);
56
+ } else {
57
+ db.run(sql, params);
58
+ }
59
+ return 0;
60
+ }
61
+ // ======================================================================
62
+ // Row → MCard conversion (sql.js returns Uint8Array for BLOBs)
63
+ // ======================================================================
64
+ rowToCard(row) {
65
+ const rawContent = row.content;
66
+ const content = rawContent instanceof Uint8Array ? rawContent : typeof rawContent === "string" ? new TextEncoder().encode(rawContent) : new Uint8Array(0);
67
+ return MCard.fromData(content, String(row.hash), String(row.g_time));
68
+ }
69
+ // ======================================================================
70
+ // sql.js-specific helpers
71
+ // ======================================================================
72
+ /**
73
+ * Export database as Uint8Array (for persistence)
74
+ */
75
+ export() {
76
+ return this.ensureDb().export();
77
+ }
78
+ /**
79
+ * Get raw sql.js Database for use with VectorStore adapter.
80
+ */
81
+ getRawDb() {
82
+ return this.ensureDb();
83
+ }
84
+ // =========== pruneHandleHistory override (needs count before delete) ===========
85
+ async pruneHandleHistory(handle, options = {}) {
86
+ const { validateHandle } = await import("./Handle-3N4QOA3U.js");
87
+ const db = this.ensureDb();
88
+ const normalized = validateHandle(handle);
89
+ if (options.deleteAll) {
90
+ const stmt = db.prepare("SELECT COUNT(*) FROM handle_history WHERE handle = ?");
91
+ stmt.bind([normalized]);
92
+ stmt.step();
93
+ const count = stmt.get()[0];
94
+ stmt.free();
95
+ db.run("DELETE FROM handle_history WHERE handle = ?", [normalized]);
96
+ return count;
97
+ } else if (options.olderThan) {
98
+ const stmt = db.prepare("SELECT COUNT(*) FROM handle_history WHERE handle = ? AND changed_at < ?");
99
+ stmt.bind([normalized, options.olderThan]);
100
+ stmt.step();
101
+ const count = stmt.get()[0];
102
+ stmt.free();
103
+ db.run("DELETE FROM handle_history WHERE handle = ? AND changed_at < ?", [normalized, options.olderThan]);
104
+ return count;
105
+ }
106
+ return 0;
107
+ }
108
+ };
109
+
110
+ export {
111
+ SqliteWasmEngine
112
+ };