@gmickel/gno 0.7.0 → 0.8.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/LICENSE +21 -0
- package/README.md +90 -50
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/assets/screenshots/webui-ask-answer.png +0 -0
- package/assets/screenshots/webui-collections.png +0 -0
- package/assets/screenshots/webui-editor.png +0 -0
- package/assets/screenshots/webui-home.png +0 -0
- package/assets/skill/SKILL.md +12 -12
- package/assets/skill/cli-reference.md +59 -57
- package/assets/skill/examples.md +8 -7
- package/assets/skill/mcp-reference.md +8 -4
- package/package.json +31 -24
- package/src/app/constants.ts +43 -42
- package/src/cli/colors.ts +1 -1
- package/src/cli/commands/ask.ts +44 -43
- package/src/cli/commands/cleanup.ts +9 -8
- package/src/cli/commands/collection/add.ts +12 -12
- package/src/cli/commands/collection/index.ts +4 -4
- package/src/cli/commands/collection/list.ts +26 -25
- package/src/cli/commands/collection/remove.ts +10 -10
- package/src/cli/commands/collection/rename.ts +10 -10
- package/src/cli/commands/context/add.ts +1 -1
- package/src/cli/commands/context/check.ts +17 -17
- package/src/cli/commands/context/index.ts +4 -4
- package/src/cli/commands/context/list.ts +11 -11
- package/src/cli/commands/context/rm.ts +1 -1
- package/src/cli/commands/doctor.ts +86 -84
- package/src/cli/commands/embed.ts +30 -28
- package/src/cli/commands/get.ts +27 -26
- package/src/cli/commands/index-cmd.ts +9 -9
- package/src/cli/commands/index.ts +16 -16
- package/src/cli/commands/init.ts +13 -12
- package/src/cli/commands/ls.ts +20 -19
- package/src/cli/commands/mcp/config.ts +30 -28
- package/src/cli/commands/mcp/index.ts +4 -4
- package/src/cli/commands/mcp/install.ts +17 -17
- package/src/cli/commands/mcp/paths.ts +133 -133
- package/src/cli/commands/mcp/status.ts +21 -21
- package/src/cli/commands/mcp/uninstall.ts +13 -13
- package/src/cli/commands/mcp.ts +2 -2
- package/src/cli/commands/models/clear.ts +12 -11
- package/src/cli/commands/models/index.ts +5 -5
- package/src/cli/commands/models/list.ts +31 -30
- package/src/cli/commands/models/path.ts +1 -1
- package/src/cli/commands/models/pull.ts +19 -18
- package/src/cli/commands/models/use.ts +4 -4
- package/src/cli/commands/multi-get.ts +38 -36
- package/src/cli/commands/query.ts +21 -20
- package/src/cli/commands/ref-parser.ts +10 -10
- package/src/cli/commands/reset.ts +40 -39
- package/src/cli/commands/search.ts +14 -13
- package/src/cli/commands/serve.ts +4 -4
- package/src/cli/commands/shared.ts +11 -10
- package/src/cli/commands/skill/index.ts +5 -5
- package/src/cli/commands/skill/install.ts +18 -17
- package/src/cli/commands/skill/paths-cmd.ts +11 -10
- package/src/cli/commands/skill/paths.ts +23 -23
- package/src/cli/commands/skill/show.ts +13 -12
- package/src/cli/commands/skill/uninstall.ts +16 -15
- package/src/cli/commands/status.ts +25 -24
- package/src/cli/commands/update.ts +3 -3
- package/src/cli/commands/vsearch.ts +17 -16
- package/src/cli/context.ts +5 -5
- package/src/cli/errors.ts +3 -3
- package/src/cli/format/search-results.ts +37 -37
- package/src/cli/options.ts +43 -43
- package/src/cli/program.ts +455 -459
- package/src/cli/progress.ts +1 -1
- package/src/cli/run.ts +24 -23
- package/src/collection/add.ts +9 -8
- package/src/collection/index.ts +3 -3
- package/src/collection/remove.ts +7 -6
- package/src/collection/types.ts +6 -6
- package/src/config/defaults.ts +1 -1
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +19 -18
- package/src/config/paths.ts +9 -8
- package/src/config/saver.ts +14 -13
- package/src/config/types.ts +53 -52
- package/src/converters/adapters/markitdownTs/adapter.ts +21 -19
- package/src/converters/adapters/officeparser/adapter.ts +18 -16
- package/src/converters/canonicalize.ts +12 -12
- package/src/converters/errors.ts +26 -22
- package/src/converters/index.ts +8 -8
- package/src/converters/mime.ts +25 -25
- package/src/converters/native/markdown.ts +10 -9
- package/src/converters/native/plaintext.ts +8 -7
- package/src/converters/path.ts +2 -2
- package/src/converters/pipeline.ts +11 -10
- package/src/converters/registry.ts +8 -8
- package/src/converters/types.ts +14 -14
- package/src/converters/versions.ts +4 -4
- package/src/index.ts +4 -4
- package/src/ingestion/chunker.ts +10 -9
- package/src/ingestion/index.ts +6 -6
- package/src/ingestion/language.ts +62 -62
- package/src/ingestion/sync.ts +50 -49
- package/src/ingestion/types.ts +10 -10
- package/src/ingestion/walker.ts +14 -13
- package/src/llm/cache.ts +51 -49
- package/src/llm/errors.ts +40 -36
- package/src/llm/index.ts +9 -9
- package/src/llm/lockfile.ts +6 -6
- package/src/llm/nodeLlamaCpp/adapter.ts +13 -12
- package/src/llm/nodeLlamaCpp/embedding.ts +9 -8
- package/src/llm/nodeLlamaCpp/generation.ts +7 -6
- package/src/llm/nodeLlamaCpp/lifecycle.ts +11 -10
- package/src/llm/nodeLlamaCpp/rerank.ts +6 -5
- package/src/llm/policy.ts +5 -5
- package/src/llm/registry.ts +6 -5
- package/src/llm/types.ts +2 -2
- package/src/mcp/resources/index.ts +15 -13
- package/src/mcp/server.ts +25 -23
- package/src/mcp/tools/get.ts +25 -23
- package/src/mcp/tools/index.ts +32 -29
- package/src/mcp/tools/multi-get.ts +34 -32
- package/src/mcp/tools/query.ts +29 -27
- package/src/mcp/tools/search.ts +14 -12
- package/src/mcp/tools/status.ts +12 -11
- package/src/mcp/tools/vsearch.ts +26 -24
- package/src/pipeline/answer.ts +9 -9
- package/src/pipeline/chunk-lookup.ts +1 -1
- package/src/pipeline/contextual.ts +4 -4
- package/src/pipeline/expansion.ts +23 -21
- package/src/pipeline/explain.ts +21 -21
- package/src/pipeline/fusion.ts +9 -9
- package/src/pipeline/hybrid.ts +41 -42
- package/src/pipeline/index.ts +10 -10
- package/src/pipeline/query-language.ts +39 -39
- package/src/pipeline/rerank.ts +8 -7
- package/src/pipeline/search.ts +22 -22
- package/src/pipeline/types.ts +8 -8
- package/src/pipeline/vsearch.ts +21 -24
- package/src/serve/CLAUDE.md +21 -15
- package/src/serve/config-sync.ts +9 -8
- package/src/serve/context.ts +19 -18
- package/src/serve/index.ts +1 -1
- package/src/serve/jobs.ts +7 -7
- package/src/serve/public/app.tsx +79 -25
- package/src/serve/public/components/AddCollectionDialog.tsx +382 -0
- package/src/serve/public/components/CaptureButton.tsx +60 -0
- package/src/serve/public/components/CaptureModal.tsx +365 -0
- package/src/serve/public/components/IndexingProgress.tsx +333 -0
- package/src/serve/public/components/ShortcutHelpModal.tsx +106 -0
- package/src/serve/public/components/ai-elements/code-block.tsx +42 -32
- package/src/serve/public/components/ai-elements/conversation.tsx +16 -14
- package/src/serve/public/components/ai-elements/inline-citation.tsx +33 -32
- package/src/serve/public/components/ai-elements/loader.tsx +5 -4
- package/src/serve/public/components/ai-elements/message.tsx +39 -37
- package/src/serve/public/components/ai-elements/prompt-input.tsx +97 -95
- package/src/serve/public/components/ai-elements/sources.tsx +12 -10
- package/src/serve/public/components/ai-elements/suggestion.tsx +10 -9
- package/src/serve/public/components/editor/CodeMirrorEditor.tsx +142 -0
- package/src/serve/public/components/editor/MarkdownPreview.tsx +311 -0
- package/src/serve/public/components/editor/index.ts +6 -0
- package/src/serve/public/components/preset-selector.tsx +29 -28
- package/src/serve/public/components/ui/badge.tsx +13 -12
- package/src/serve/public/components/ui/button-group.tsx +13 -12
- package/src/serve/public/components/ui/button.tsx +23 -22
- package/src/serve/public/components/ui/card.tsx +16 -16
- package/src/serve/public/components/ui/carousel.tsx +36 -35
- package/src/serve/public/components/ui/collapsible.tsx +1 -1
- package/src/serve/public/components/ui/command.tsx +17 -15
- package/src/serve/public/components/ui/dialog.tsx +13 -12
- package/src/serve/public/components/ui/dropdown-menu.tsx +13 -12
- package/src/serve/public/components/ui/hover-card.tsx +6 -5
- package/src/serve/public/components/ui/input-group.tsx +45 -43
- package/src/serve/public/components/ui/input.tsx +6 -6
- package/src/serve/public/components/ui/progress.tsx +5 -4
- package/src/serve/public/components/ui/scroll-area.tsx +11 -10
- package/src/serve/public/components/ui/select.tsx +19 -18
- package/src/serve/public/components/ui/separator.tsx +6 -5
- package/src/serve/public/components/ui/table.tsx +18 -18
- package/src/serve/public/components/ui/textarea.tsx +4 -4
- package/src/serve/public/components/ui/tooltip.tsx +5 -4
- package/src/serve/public/globals.css +27 -4
- package/src/serve/public/hooks/use-api.ts +8 -8
- package/src/serve/public/hooks/useCaptureModal.tsx +83 -0
- package/src/serve/public/hooks/useKeyboardShortcuts.ts +85 -0
- package/src/serve/public/index.html +4 -4
- package/src/serve/public/lib/utils.ts +6 -0
- package/src/serve/public/pages/Ask.tsx +27 -26
- package/src/serve/public/pages/Browse.tsx +28 -27
- package/src/serve/public/pages/Collections.tsx +439 -0
- package/src/serve/public/pages/Dashboard.tsx +166 -40
- package/src/serve/public/pages/DocView.tsx +258 -73
- package/src/serve/public/pages/DocumentEditor.tsx +510 -0
- package/src/serve/public/pages/Search.tsx +80 -58
- package/src/serve/routes/api.ts +272 -155
- package/src/serve/security.ts +4 -4
- package/src/serve/server.ts +66 -48
- package/src/store/index.ts +5 -5
- package/src/store/migrations/001-initial.ts +24 -23
- package/src/store/migrations/002-documents-fts.ts +7 -6
- package/src/store/migrations/index.ts +4 -4
- package/src/store/migrations/runner.ts +17 -15
- package/src/store/sqlite/adapter.ts +123 -121
- package/src/store/sqlite/fts5-snowball.ts +24 -23
- package/src/store/sqlite/index.ts +1 -1
- package/src/store/sqlite/setup.ts +12 -12
- package/src/store/sqlite/types.ts +4 -4
- package/src/store/types.ts +19 -19
- package/src/store/vector/index.ts +3 -3
- package/src/store/vector/sqlite-vec.ts +23 -20
- package/src/store/vector/stats.ts +10 -8
- package/src/store/vector/types.ts +2 -2
- package/vendor/fts5-snowball/README.md +6 -6
- package/assets/screenshots/webui-ask-answer.jpg +0 -0
- package/assets/screenshots/webui-home.jpg +0 -0
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// CRITICAL: Import setup FIRST to configure custom SQLite before any Database use
|
|
11
|
-
import
|
|
12
|
-
import { Database } from
|
|
13
|
-
|
|
14
|
-
import type { Collection, Context, FtsTokenizer } from
|
|
15
|
-
import { migrations, runMigrations } from '../migrations';
|
|
11
|
+
import "./setup";
|
|
12
|
+
import { Database } from "bun:sqlite";
|
|
13
|
+
|
|
14
|
+
import type { Collection, Context, FtsTokenizer } from "../../config/types";
|
|
16
15
|
import type {
|
|
17
16
|
ChunkInput,
|
|
18
17
|
ChunkRow,
|
|
@@ -29,10 +28,13 @@ import type {
|
|
|
29
28
|
MigrationResult,
|
|
30
29
|
StorePort,
|
|
31
30
|
StoreResult,
|
|
32
|
-
} from
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
import
|
|
31
|
+
} from "../types";
|
|
32
|
+
import type { SqliteDbProvider } from "./types";
|
|
33
|
+
|
|
34
|
+
import { buildUri, deriveDocid } from "../../app/constants";
|
|
35
|
+
import { migrations, runMigrations } from "../migrations";
|
|
36
|
+
import { err, ok } from "../types";
|
|
37
|
+
import { loadFts5Snowball } from "./fts5-snowball";
|
|
36
38
|
|
|
37
39
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
40
|
// FTS5 Query Escaping
|
|
@@ -56,7 +58,7 @@ function escapeFts5Query(query: string): string {
|
|
|
56
58
|
const escaped = token.replace(/"/g, '""');
|
|
57
59
|
return `"${escaped}"`;
|
|
58
60
|
})
|
|
59
|
-
.join(
|
|
61
|
+
.join(" ");
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -71,9 +73,9 @@ const INDEX_PREFIX_REGEX = /^index-/;
|
|
|
71
73
|
|
|
72
74
|
export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
73
75
|
private db: Database | null = null;
|
|
74
|
-
private dbPath =
|
|
75
|
-
private ftsTokenizer: FtsTokenizer =
|
|
76
|
-
private configPath =
|
|
76
|
+
private dbPath = "";
|
|
77
|
+
private ftsTokenizer: FtsTokenizer = "unicode61";
|
|
78
|
+
private configPath = ""; // Set by CLI layer for status output
|
|
77
79
|
private txDepth = 0; // Transaction nesting depth
|
|
78
80
|
private txCounter = 0; // Savepoint counter for unique names
|
|
79
81
|
|
|
@@ -91,27 +93,27 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
91
93
|
this.ftsTokenizer = ftsTokenizer;
|
|
92
94
|
|
|
93
95
|
// Enable pragmas for performance and safety
|
|
94
|
-
this.db.exec(
|
|
95
|
-
this.db.exec(
|
|
96
|
+
this.db.exec("PRAGMA foreign_keys = ON");
|
|
97
|
+
this.db.exec("PRAGMA busy_timeout = 5000");
|
|
96
98
|
|
|
97
99
|
// CI mode: trade durability for speed (no fsync, memory journal)
|
|
98
100
|
// Safe for tests since we don't need crash recovery
|
|
99
101
|
if (process.env.CI) {
|
|
100
|
-
this.db.exec(
|
|
101
|
-
this.db.exec(
|
|
102
|
-
this.db.exec(
|
|
102
|
+
this.db.exec("PRAGMA journal_mode = MEMORY");
|
|
103
|
+
this.db.exec("PRAGMA synchronous = OFF");
|
|
104
|
+
this.db.exec("PRAGMA temp_store = MEMORY");
|
|
103
105
|
} else {
|
|
104
|
-
this.db.exec(
|
|
106
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
// Load fts5-snowball extension if using snowball tokenizer
|
|
108
|
-
if (ftsTokenizer.startsWith(
|
|
110
|
+
if (ftsTokenizer.startsWith("snowball")) {
|
|
109
111
|
const snowballResult = loadFts5Snowball(this.db);
|
|
110
112
|
if (!snowballResult.loaded) {
|
|
111
113
|
this.db.close();
|
|
112
114
|
this.db = null;
|
|
113
115
|
return err(
|
|
114
|
-
|
|
116
|
+
"EXTENSION_LOAD_FAILED",
|
|
115
117
|
`Failed to load fts5-snowball: ${snowballResult.error}`
|
|
116
118
|
);
|
|
117
119
|
}
|
|
@@ -128,8 +130,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
128
130
|
return result;
|
|
129
131
|
} catch (cause) {
|
|
130
132
|
const message =
|
|
131
|
-
cause instanceof Error ? cause.message :
|
|
132
|
-
return err(
|
|
133
|
+
cause instanceof Error ? cause.message : "Failed to open database";
|
|
134
|
+
return err("CONNECTION_FAILED", message, cause);
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -160,7 +162,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
160
162
|
try {
|
|
161
163
|
if (isOuter) {
|
|
162
164
|
// IMMEDIATE reduces lock churn for bulk writes
|
|
163
|
-
db.exec(
|
|
165
|
+
db.exec("BEGIN IMMEDIATE");
|
|
164
166
|
} else {
|
|
165
167
|
db.exec(`SAVEPOINT ${savepoint}`);
|
|
166
168
|
}
|
|
@@ -170,7 +172,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
170
172
|
this.txDepth -= 1;
|
|
171
173
|
|
|
172
174
|
if (isOuter) {
|
|
173
|
-
db.exec(
|
|
175
|
+
db.exec("COMMIT");
|
|
174
176
|
} else {
|
|
175
177
|
db.exec(`RELEASE ${savepoint}`);
|
|
176
178
|
}
|
|
@@ -181,7 +183,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
181
183
|
|
|
182
184
|
try {
|
|
183
185
|
if (isOuter) {
|
|
184
|
-
db.exec(
|
|
186
|
+
db.exec("ROLLBACK");
|
|
185
187
|
} else {
|
|
186
188
|
db.exec(`ROLLBACK TO ${savepoint}`);
|
|
187
189
|
db.exec(`RELEASE ${savepoint}`);
|
|
@@ -191,8 +193,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
const message =
|
|
194
|
-
cause instanceof Error ? cause.message :
|
|
195
|
-
return err(
|
|
196
|
+
cause instanceof Error ? cause.message : "Transaction failed";
|
|
197
|
+
return err("TRANSACTION_FAILED", message, cause);
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
|
|
@@ -213,7 +215,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
213
215
|
|
|
214
216
|
private ensureOpen(): Database {
|
|
215
217
|
if (!this.db) {
|
|
216
|
-
throw new Error(
|
|
218
|
+
throw new Error("Database not open");
|
|
217
219
|
}
|
|
218
220
|
return this.db;
|
|
219
221
|
}
|
|
@@ -230,7 +232,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
230
232
|
// Get existing collection names
|
|
231
233
|
const existing = new Set(
|
|
232
234
|
db
|
|
233
|
-
.query<{ name: string }, []>(
|
|
235
|
+
.query<{ name: string }, []>("SELECT name FROM collections")
|
|
234
236
|
.all()
|
|
235
237
|
.map((r) => r.name)
|
|
236
238
|
);
|
|
@@ -240,7 +242,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
240
242
|
// Delete removed collections
|
|
241
243
|
for (const name of existing) {
|
|
242
244
|
if (!incoming.has(name)) {
|
|
243
|
-
db.run(
|
|
245
|
+
db.run("DELETE FROM collections WHERE name = ?", [name]);
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
|
|
@@ -275,8 +277,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
275
277
|
return ok(undefined);
|
|
276
278
|
} catch (cause) {
|
|
277
279
|
return err(
|
|
278
|
-
|
|
279
|
-
cause instanceof Error ? cause.message :
|
|
280
|
+
"QUERY_FAILED",
|
|
281
|
+
cause instanceof Error ? cause.message : "Failed to sync collections",
|
|
280
282
|
cause
|
|
281
283
|
);
|
|
282
284
|
}
|
|
@@ -288,7 +290,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
288
290
|
|
|
289
291
|
const transaction = db.transaction(() => {
|
|
290
292
|
// Delete all and re-insert (contexts are small)
|
|
291
|
-
db.run(
|
|
293
|
+
db.run("DELETE FROM contexts");
|
|
292
294
|
|
|
293
295
|
const stmt = db.prepare(`
|
|
294
296
|
INSERT INTO contexts (scope_type, scope_key, text, synced_at)
|
|
@@ -304,8 +306,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
304
306
|
return ok(undefined);
|
|
305
307
|
} catch (cause) {
|
|
306
308
|
return err(
|
|
307
|
-
|
|
308
|
-
cause instanceof Error ? cause.message :
|
|
309
|
+
"QUERY_FAILED",
|
|
310
|
+
cause instanceof Error ? cause.message : "Failed to sync contexts",
|
|
309
311
|
cause
|
|
310
312
|
);
|
|
311
313
|
}
|
|
@@ -315,14 +317,14 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
315
317
|
try {
|
|
316
318
|
const db = this.ensureOpen();
|
|
317
319
|
const rows = db
|
|
318
|
-
.query<DbCollectionRow, []>(
|
|
320
|
+
.query<DbCollectionRow, []>("SELECT * FROM collections")
|
|
319
321
|
.all();
|
|
320
322
|
|
|
321
323
|
return ok(rows.map(mapCollectionRow));
|
|
322
324
|
} catch (cause) {
|
|
323
325
|
return err(
|
|
324
|
-
|
|
325
|
-
cause instanceof Error ? cause.message :
|
|
326
|
+
"QUERY_FAILED",
|
|
327
|
+
cause instanceof Error ? cause.message : "Failed to get collections",
|
|
326
328
|
cause
|
|
327
329
|
);
|
|
328
330
|
}
|
|
@@ -331,13 +333,13 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
331
333
|
async getContexts(): Promise<StoreResult<ContextRow[]>> {
|
|
332
334
|
try {
|
|
333
335
|
const db = this.ensureOpen();
|
|
334
|
-
const rows = db.query<DbContextRow, []>(
|
|
336
|
+
const rows = db.query<DbContextRow, []>("SELECT * FROM contexts").all();
|
|
335
337
|
|
|
336
338
|
return ok(rows.map(mapContextRow));
|
|
337
339
|
} catch (cause) {
|
|
338
340
|
return err(
|
|
339
|
-
|
|
340
|
-
cause instanceof Error ? cause.message :
|
|
341
|
+
"QUERY_FAILED",
|
|
342
|
+
cause instanceof Error ? cause.message : "Failed to get contexts",
|
|
341
343
|
cause
|
|
342
344
|
);
|
|
343
345
|
}
|
|
@@ -404,8 +406,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
404
406
|
return ok(docid);
|
|
405
407
|
} catch (cause) {
|
|
406
408
|
return err(
|
|
407
|
-
|
|
408
|
-
cause instanceof Error ? cause.message :
|
|
409
|
+
"QUERY_FAILED",
|
|
410
|
+
cause instanceof Error ? cause.message : "Failed to upsert document",
|
|
409
411
|
cause
|
|
410
412
|
);
|
|
411
413
|
}
|
|
@@ -419,15 +421,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
419
421
|
const db = this.ensureOpen();
|
|
420
422
|
const row = db
|
|
421
423
|
.query<DbDocumentRow, [string, string]>(
|
|
422
|
-
|
|
424
|
+
"SELECT * FROM documents WHERE collection = ? AND rel_path = ?"
|
|
423
425
|
)
|
|
424
426
|
.get(collection, relPath);
|
|
425
427
|
|
|
426
428
|
return ok(row ? mapDocumentRow(row) : null);
|
|
427
429
|
} catch (cause) {
|
|
428
430
|
return err(
|
|
429
|
-
|
|
430
|
-
cause instanceof Error ? cause.message :
|
|
431
|
+
"QUERY_FAILED",
|
|
432
|
+
cause instanceof Error ? cause.message : "Failed to get document",
|
|
431
433
|
cause
|
|
432
434
|
);
|
|
433
435
|
}
|
|
@@ -440,17 +442,17 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
440
442
|
const db = this.ensureOpen();
|
|
441
443
|
const row = db
|
|
442
444
|
.query<DbDocumentRow, [string]>(
|
|
443
|
-
|
|
445
|
+
"SELECT * FROM documents WHERE docid = ?"
|
|
444
446
|
)
|
|
445
447
|
.get(docid);
|
|
446
448
|
|
|
447
449
|
return ok(row ? mapDocumentRow(row) : null);
|
|
448
450
|
} catch (cause) {
|
|
449
451
|
return err(
|
|
450
|
-
|
|
452
|
+
"QUERY_FAILED",
|
|
451
453
|
cause instanceof Error
|
|
452
454
|
? cause.message
|
|
453
|
-
:
|
|
455
|
+
: "Failed to get document by docid",
|
|
454
456
|
cause
|
|
455
457
|
);
|
|
456
458
|
}
|
|
@@ -462,16 +464,16 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
462
464
|
try {
|
|
463
465
|
const db = this.ensureOpen();
|
|
464
466
|
const row = db
|
|
465
|
-
.query<DbDocumentRow, [string]>(
|
|
467
|
+
.query<DbDocumentRow, [string]>("SELECT * FROM documents WHERE uri = ?")
|
|
466
468
|
.get(uri);
|
|
467
469
|
|
|
468
470
|
return ok(row ? mapDocumentRow(row) : null);
|
|
469
471
|
} catch (cause) {
|
|
470
472
|
return err(
|
|
471
|
-
|
|
473
|
+
"QUERY_FAILED",
|
|
472
474
|
cause instanceof Error
|
|
473
475
|
? cause.message
|
|
474
|
-
:
|
|
476
|
+
: "Failed to get document by uri",
|
|
475
477
|
cause
|
|
476
478
|
);
|
|
477
479
|
}
|
|
@@ -486,16 +488,16 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
486
488
|
const rows = collection
|
|
487
489
|
? db
|
|
488
490
|
.query<DbDocumentRow, [string]>(
|
|
489
|
-
|
|
491
|
+
"SELECT * FROM documents WHERE collection = ?"
|
|
490
492
|
)
|
|
491
493
|
.all(collection)
|
|
492
|
-
: db.query<DbDocumentRow, []>(
|
|
494
|
+
: db.query<DbDocumentRow, []>("SELECT * FROM documents").all();
|
|
493
495
|
|
|
494
496
|
return ok(rows.map(mapDocumentRow));
|
|
495
497
|
} catch (cause) {
|
|
496
498
|
return err(
|
|
497
|
-
|
|
498
|
-
cause instanceof Error ? cause.message :
|
|
499
|
+
"QUERY_FAILED",
|
|
500
|
+
cause instanceof Error ? cause.message : "Failed to list documents",
|
|
499
501
|
cause
|
|
500
502
|
);
|
|
501
503
|
}
|
|
@@ -514,12 +516,12 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
514
516
|
const countRow = collection
|
|
515
517
|
? db
|
|
516
518
|
.query<{ count: number }, [string]>(
|
|
517
|
-
|
|
519
|
+
"SELECT COUNT(*) as count FROM documents WHERE collection = ?"
|
|
518
520
|
)
|
|
519
521
|
.get(collection)
|
|
520
522
|
: db
|
|
521
523
|
.query<{ count: number }, []>(
|
|
522
|
-
|
|
524
|
+
"SELECT COUNT(*) as count FROM documents"
|
|
523
525
|
)
|
|
524
526
|
.get();
|
|
525
527
|
|
|
@@ -529,20 +531,20 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
529
531
|
const rows = collection
|
|
530
532
|
? db
|
|
531
533
|
.query<DbDocumentRow, [string, number, number]>(
|
|
532
|
-
|
|
534
|
+
"SELECT * FROM documents WHERE collection = ? ORDER BY updated_at DESC LIMIT ? OFFSET ?"
|
|
533
535
|
)
|
|
534
536
|
.all(collection, limit, offset)
|
|
535
537
|
: db
|
|
536
538
|
.query<DbDocumentRow, [number, number]>(
|
|
537
|
-
|
|
539
|
+
"SELECT * FROM documents ORDER BY updated_at DESC LIMIT ? OFFSET ?"
|
|
538
540
|
)
|
|
539
541
|
.all(limit, offset);
|
|
540
542
|
|
|
541
543
|
return ok({ documents: rows.map(mapDocumentRow), total });
|
|
542
544
|
} catch (cause) {
|
|
543
545
|
return err(
|
|
544
|
-
|
|
545
|
-
cause instanceof Error ? cause.message :
|
|
546
|
+
"QUERY_FAILED",
|
|
547
|
+
cause instanceof Error ? cause.message : "Failed to list documents",
|
|
546
548
|
cause
|
|
547
549
|
);
|
|
548
550
|
}
|
|
@@ -559,7 +561,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
559
561
|
return ok(0);
|
|
560
562
|
}
|
|
561
563
|
|
|
562
|
-
const placeholders = relPaths.map(() =>
|
|
564
|
+
const placeholders = relPaths.map(() => "?").join(",");
|
|
563
565
|
const result = db.run(
|
|
564
566
|
`UPDATE documents SET active = 0, updated_at = datetime('now')
|
|
565
567
|
WHERE collection = ? AND rel_path IN (${placeholders})`,
|
|
@@ -569,10 +571,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
569
571
|
return ok(result.changes);
|
|
570
572
|
} catch (cause) {
|
|
571
573
|
return err(
|
|
572
|
-
|
|
574
|
+
"QUERY_FAILED",
|
|
573
575
|
cause instanceof Error
|
|
574
576
|
? cause.message
|
|
575
|
-
:
|
|
577
|
+
: "Failed to mark documents inactive",
|
|
576
578
|
cause
|
|
577
579
|
);
|
|
578
580
|
}
|
|
@@ -599,8 +601,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
599
601
|
return ok(undefined);
|
|
600
602
|
} catch (cause) {
|
|
601
603
|
return err(
|
|
602
|
-
|
|
603
|
-
cause instanceof Error ? cause.message :
|
|
604
|
+
"QUERY_FAILED",
|
|
605
|
+
cause instanceof Error ? cause.message : "Failed to upsert content",
|
|
604
606
|
cause
|
|
605
607
|
);
|
|
606
608
|
}
|
|
@@ -612,15 +614,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
612
614
|
|
|
613
615
|
const row = db
|
|
614
616
|
.query<{ markdown: string }, [string]>(
|
|
615
|
-
|
|
617
|
+
"SELECT markdown FROM content WHERE mirror_hash = ?"
|
|
616
618
|
)
|
|
617
619
|
.get(mirrorHash);
|
|
618
620
|
|
|
619
621
|
return ok(row?.markdown ?? null);
|
|
620
622
|
} catch (cause) {
|
|
621
623
|
return err(
|
|
622
|
-
|
|
623
|
-
cause instanceof Error ? cause.message :
|
|
624
|
+
"QUERY_FAILED",
|
|
625
|
+
cause instanceof Error ? cause.message : "Failed to get content",
|
|
624
626
|
cause
|
|
625
627
|
);
|
|
626
628
|
}
|
|
@@ -639,7 +641,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
639
641
|
|
|
640
642
|
const transaction = db.transaction(() => {
|
|
641
643
|
// Delete existing chunks for this hash
|
|
642
|
-
db.run(
|
|
644
|
+
db.run("DELETE FROM content_chunks WHERE mirror_hash = ?", [
|
|
643
645
|
mirrorHash,
|
|
644
646
|
]);
|
|
645
647
|
|
|
@@ -667,8 +669,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
667
669
|
return ok(undefined);
|
|
668
670
|
} catch (cause) {
|
|
669
671
|
return err(
|
|
670
|
-
|
|
671
|
-
cause instanceof Error ? cause.message :
|
|
672
|
+
"QUERY_FAILED",
|
|
673
|
+
cause instanceof Error ? cause.message : "Failed to upsert chunks",
|
|
672
674
|
cause
|
|
673
675
|
);
|
|
674
676
|
}
|
|
@@ -680,15 +682,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
680
682
|
|
|
681
683
|
const rows = db
|
|
682
684
|
.query<DbChunkRow, [string]>(
|
|
683
|
-
|
|
685
|
+
"SELECT * FROM content_chunks WHERE mirror_hash = ? ORDER BY seq"
|
|
684
686
|
)
|
|
685
687
|
.all(mirrorHash);
|
|
686
688
|
|
|
687
689
|
return ok(rows.map(mapChunkRow));
|
|
688
690
|
} catch (cause) {
|
|
689
691
|
return err(
|
|
690
|
-
|
|
691
|
-
cause instanceof Error ? cause.message :
|
|
692
|
+
"QUERY_FAILED",
|
|
693
|
+
cause instanceof Error ? cause.message : "Failed to get chunks",
|
|
692
694
|
cause
|
|
693
695
|
);
|
|
694
696
|
}
|
|
@@ -721,7 +723,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
721
723
|
// Batch queries to respect SQLite parameter limit
|
|
722
724
|
for (let i = 0; i < uniqueHashes.length; i += SQLITE_MAX_PARAMS) {
|
|
723
725
|
const batch = uniqueHashes.slice(i, i + SQLITE_MAX_PARAMS);
|
|
724
|
-
const placeholders = batch.map(() =>
|
|
726
|
+
const placeholders = batch.map(() => "?").join(",");
|
|
725
727
|
const sql = `SELECT * FROM content_chunks
|
|
726
728
|
WHERE mirror_hash IN (${placeholders})
|
|
727
729
|
ORDER BY mirror_hash, seq`;
|
|
@@ -739,8 +741,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
739
741
|
return ok(result);
|
|
740
742
|
} catch (cause) {
|
|
741
743
|
return err(
|
|
742
|
-
|
|
743
|
-
cause instanceof Error ? cause.message :
|
|
744
|
+
"QUERY_FAILED",
|
|
745
|
+
cause instanceof Error ? cause.message : "Failed to get chunks batch",
|
|
744
746
|
cause
|
|
745
747
|
);
|
|
746
748
|
}
|
|
@@ -766,7 +768,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
766
768
|
d.mirror_hash,
|
|
767
769
|
0 as seq,
|
|
768
770
|
bm25(documents_fts) as score,
|
|
769
|
-
${options.snippet ? "snippet(documents_fts, 2, '<mark>', '</mark>', '...', 32) as snippet," :
|
|
771
|
+
${options.snippet ? "snippet(documents_fts, 2, '<mark>', '</mark>', '...', 32) as snippet," : ""}
|
|
770
772
|
d.docid,
|
|
771
773
|
d.uri,
|
|
772
774
|
d.title,
|
|
@@ -780,7 +782,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
780
782
|
FROM documents_fts fts
|
|
781
783
|
JOIN documents d ON d.id = fts.rowid AND d.active = 1
|
|
782
784
|
WHERE documents_fts MATCH ?
|
|
783
|
-
${options.collection ?
|
|
785
|
+
${options.collection ? "AND d.collection = ?" : ""}
|
|
784
786
|
ORDER BY bm25(documents_fts)
|
|
785
787
|
LIMIT ?
|
|
786
788
|
`;
|
|
@@ -829,15 +831,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
829
831
|
}))
|
|
830
832
|
);
|
|
831
833
|
} catch (cause) {
|
|
832
|
-
const message = cause instanceof Error ? cause.message :
|
|
834
|
+
const message = cause instanceof Error ? cause.message : "";
|
|
833
835
|
// Detect FTS5 syntax errors and return INVALID_INPUT for consistent handling
|
|
834
836
|
const isSyntaxError =
|
|
835
|
-
message.includes(
|
|
836
|
-
message.includes(
|
|
837
|
-
message.includes(
|
|
837
|
+
message.includes("malformed MATCH") ||
|
|
838
|
+
message.includes("fts5: syntax error") ||
|
|
839
|
+
message.includes("fts5:");
|
|
838
840
|
return err(
|
|
839
|
-
isSyntaxError ?
|
|
840
|
-
message ||
|
|
841
|
+
isSyntaxError ? "INVALID_INPUT" : "QUERY_FAILED",
|
|
842
|
+
message || "Failed to search FTS",
|
|
841
843
|
cause
|
|
842
844
|
);
|
|
843
845
|
}
|
|
@@ -878,13 +880,13 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
878
880
|
}
|
|
879
881
|
|
|
880
882
|
// Delete existing FTS entry for this doc
|
|
881
|
-
db.run(
|
|
883
|
+
db.run("DELETE FROM documents_fts WHERE rowid = ?", [doc.id]);
|
|
882
884
|
|
|
883
885
|
// Insert new FTS entry if we have content
|
|
884
886
|
if (doc.markdown) {
|
|
885
887
|
db.run(
|
|
886
|
-
|
|
887
|
-
[doc.id, doc.rel_path, doc.title ??
|
|
888
|
+
"INSERT INTO documents_fts (rowid, filepath, title, body) VALUES (?, ?, ?, ?)",
|
|
889
|
+
[doc.id, doc.rel_path, doc.title ?? "", doc.markdown]
|
|
888
890
|
);
|
|
889
891
|
}
|
|
890
892
|
});
|
|
@@ -893,8 +895,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
893
895
|
return ok(undefined);
|
|
894
896
|
} catch (cause) {
|
|
895
897
|
return err(
|
|
896
|
-
|
|
897
|
-
cause instanceof Error ? cause.message :
|
|
898
|
+
"QUERY_FAILED",
|
|
899
|
+
cause instanceof Error ? cause.message : "Failed to sync document FTS",
|
|
898
900
|
cause
|
|
899
901
|
);
|
|
900
902
|
}
|
|
@@ -911,7 +913,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
911
913
|
|
|
912
914
|
const transaction = db.transaction(() => {
|
|
913
915
|
// Clear FTS table
|
|
914
|
-
db.run(
|
|
916
|
+
db.run("DELETE FROM documents_fts");
|
|
915
917
|
|
|
916
918
|
// Get all active documents with content
|
|
917
919
|
interface DocWithContent {
|
|
@@ -932,11 +934,11 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
932
934
|
|
|
933
935
|
// Insert FTS entries
|
|
934
936
|
const stmt = db.prepare(
|
|
935
|
-
|
|
937
|
+
"INSERT INTO documents_fts (rowid, filepath, title, body) VALUES (?, ?, ?, ?)"
|
|
936
938
|
);
|
|
937
939
|
|
|
938
940
|
for (const doc of docs) {
|
|
939
|
-
stmt.run(doc.id, doc.rel_path, doc.title ??
|
|
941
|
+
stmt.run(doc.id, doc.rel_path, doc.title ?? "", doc.markdown);
|
|
940
942
|
count++;
|
|
941
943
|
}
|
|
942
944
|
});
|
|
@@ -945,10 +947,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
945
947
|
return ok(count);
|
|
946
948
|
} catch (cause) {
|
|
947
949
|
return err(
|
|
948
|
-
|
|
950
|
+
"QUERY_FAILED",
|
|
949
951
|
cause instanceof Error
|
|
950
952
|
? cause.message
|
|
951
|
-
:
|
|
953
|
+
: "Failed to rebuild documents FTS",
|
|
952
954
|
cause
|
|
953
955
|
);
|
|
954
956
|
}
|
|
@@ -972,14 +974,14 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
972
974
|
|
|
973
975
|
const docs = db
|
|
974
976
|
.query<DocInfo, [string]>(
|
|
975
|
-
|
|
977
|
+
"SELECT id, rel_path, title FROM documents WHERE mirror_hash = ? AND active = 1"
|
|
976
978
|
)
|
|
977
979
|
.all(mirrorHash);
|
|
978
980
|
|
|
979
981
|
// Get content
|
|
980
982
|
const content = db
|
|
981
983
|
.query<{ markdown: string }, [string]>(
|
|
982
|
-
|
|
984
|
+
"SELECT markdown FROM content WHERE mirror_hash = ?"
|
|
983
985
|
)
|
|
984
986
|
.get(mirrorHash);
|
|
985
987
|
|
|
@@ -989,10 +991,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
989
991
|
|
|
990
992
|
// Update FTS for each document using this hash
|
|
991
993
|
for (const doc of docs) {
|
|
992
|
-
db.run(
|
|
994
|
+
db.run("DELETE FROM documents_fts WHERE rowid = ?", [doc.id]);
|
|
993
995
|
db.run(
|
|
994
|
-
|
|
995
|
-
[doc.id, doc.rel_path, doc.title ??
|
|
996
|
+
"INSERT INTO documents_fts (rowid, filepath, title, body) VALUES (?, ?, ?, ?)",
|
|
997
|
+
[doc.id, doc.rel_path, doc.title ?? "", content.markdown]
|
|
996
998
|
);
|
|
997
999
|
}
|
|
998
1000
|
});
|
|
@@ -1001,8 +1003,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1001
1003
|
return ok(undefined);
|
|
1002
1004
|
} catch (cause) {
|
|
1003
1005
|
return err(
|
|
1004
|
-
|
|
1005
|
-
cause instanceof Error ? cause.message :
|
|
1006
|
+
"QUERY_FAILED",
|
|
1007
|
+
cause instanceof Error ? cause.message : "Failed to rebuild FTS",
|
|
1006
1008
|
cause
|
|
1007
1009
|
);
|
|
1008
1010
|
}
|
|
@@ -1022,15 +1024,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1022
1024
|
"SELECT value FROM schema_meta WHERE key = 'version'"
|
|
1023
1025
|
)
|
|
1024
1026
|
.get();
|
|
1025
|
-
const version = versionRow?.value ??
|
|
1027
|
+
const version = versionRow?.value ?? "0";
|
|
1026
1028
|
|
|
1027
1029
|
// Derive indexName from dbPath (basename without extension)
|
|
1028
1030
|
const indexName =
|
|
1029
1031
|
this.dbPath
|
|
1030
|
-
.split(
|
|
1032
|
+
.split("/")
|
|
1031
1033
|
.pop()
|
|
1032
|
-
?.replace(SQLITE_EXT_REGEX,
|
|
1033
|
-
?.replace(INDEX_PREFIX_REGEX,
|
|
1034
|
+
?.replace(SQLITE_EXT_REGEX, "")
|
|
1035
|
+
?.replace(INDEX_PREFIX_REGEX, "") || "default";
|
|
1034
1036
|
|
|
1035
1037
|
// Get collection stats with chunk counts
|
|
1036
1038
|
interface CollectionStat {
|
|
@@ -1082,7 +1084,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1082
1084
|
const chunkCount =
|
|
1083
1085
|
db
|
|
1084
1086
|
.query<{ count: number }, []>(
|
|
1085
|
-
|
|
1087
|
+
"SELECT COUNT(*) as count FROM content_chunks"
|
|
1086
1088
|
)
|
|
1087
1089
|
.get()?.count ?? 0;
|
|
1088
1090
|
|
|
@@ -1117,7 +1119,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1117
1119
|
// Last updated (max updated_at from documents)
|
|
1118
1120
|
const lastUpdatedRow = db
|
|
1119
1121
|
.query<{ last_updated: string | null }, []>(
|
|
1120
|
-
|
|
1122
|
+
"SELECT MAX(updated_at) as last_updated FROM documents"
|
|
1121
1123
|
)
|
|
1122
1124
|
.get();
|
|
1123
1125
|
|
|
@@ -1151,8 +1153,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1151
1153
|
});
|
|
1152
1154
|
} catch (cause) {
|
|
1153
1155
|
return err(
|
|
1154
|
-
|
|
1155
|
-
cause instanceof Error ? cause.message :
|
|
1156
|
+
"QUERY_FAILED",
|
|
1157
|
+
cause instanceof Error ? cause.message : "Failed to get status",
|
|
1156
1158
|
cause
|
|
1157
1159
|
);
|
|
1158
1160
|
}
|
|
@@ -1181,8 +1183,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1181
1183
|
return ok(undefined);
|
|
1182
1184
|
} catch (cause) {
|
|
1183
1185
|
return err(
|
|
1184
|
-
|
|
1185
|
-
cause instanceof Error ? cause.message :
|
|
1186
|
+
"QUERY_FAILED",
|
|
1187
|
+
cause instanceof Error ? cause.message : "Failed to record error",
|
|
1186
1188
|
cause
|
|
1187
1189
|
);
|
|
1188
1190
|
}
|
|
@@ -1194,15 +1196,15 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1194
1196
|
|
|
1195
1197
|
const rows = db
|
|
1196
1198
|
.query<DbIngestErrorRow, [number]>(
|
|
1197
|
-
|
|
1199
|
+
"SELECT * FROM ingest_errors ORDER BY occurred_at DESC LIMIT ?"
|
|
1198
1200
|
)
|
|
1199
1201
|
.all(limit);
|
|
1200
1202
|
|
|
1201
1203
|
return ok(rows.map(mapIngestErrorRow));
|
|
1202
1204
|
} catch (cause) {
|
|
1203
1205
|
return err(
|
|
1204
|
-
|
|
1205
|
-
cause instanceof Error ? cause.message :
|
|
1206
|
+
"QUERY_FAILED",
|
|
1207
|
+
cause instanceof Error ? cause.message : "Failed to get recent errors",
|
|
1206
1208
|
cause
|
|
1207
1209
|
);
|
|
1208
1210
|
}
|
|
@@ -1270,8 +1272,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
1270
1272
|
});
|
|
1271
1273
|
} catch (cause) {
|
|
1272
1274
|
return err(
|
|
1273
|
-
|
|
1274
|
-
cause instanceof Error ? cause.message :
|
|
1275
|
+
"QUERY_FAILED",
|
|
1276
|
+
cause instanceof Error ? cause.message : "Failed to cleanup orphans",
|
|
1275
1277
|
cause
|
|
1276
1278
|
);
|
|
1277
1279
|
}
|
|
@@ -1294,7 +1296,7 @@ interface DbCollectionRow {
|
|
|
1294
1296
|
}
|
|
1295
1297
|
|
|
1296
1298
|
interface DbContextRow {
|
|
1297
|
-
scope_type:
|
|
1299
|
+
scope_type: "global" | "collection" | "prefix";
|
|
1298
1300
|
scope_key: string;
|
|
1299
1301
|
text: string;
|
|
1300
1302
|
synced_at: string;
|