dsh-locator 0.8.2 → 0.10.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.
- package/CHANGELOG.md +47 -0
- package/README-es.md +30 -5
- package/README-hi.md +31 -5
- package/README-pt.md +31 -5
- package/README.en.md +31 -5
- package/README.md +31 -5
- package/bin/darwin-arm64/indexd +0 -0
- package/bin/darwin-x64/indexd +0 -0
- package/bin/linux-arm64/indexd +0 -0
- package/bin/linux-x64/indexd +0 -0
- package/bin/win32-arm64/indexd.exe +0 -0
- package/bin/win32-x64/indexd.exe +0 -0
- package/client.js +1198 -117
- package/lib/combined.d.ts +20 -3
- package/lib/combined.d.ts.map +1 -1
- package/lib/combined.js +85 -15
- package/lib/combined.js.map +1 -1
- package/lib/content-search-worker.d.ts +8 -3
- package/lib/content-search-worker.d.ts.map +1 -1
- package/lib/content-search-worker.js +54 -27
- package/lib/content-search-worker.js.map +1 -1
- package/lib/content-search.d.ts +127 -7
- package/lib/content-search.d.ts.map +1 -1
- package/lib/content-search.js +571 -36
- package/lib/content-search.js.map +1 -1
- package/lib/content.d.ts +83 -5
- package/lib/content.d.ts.map +1 -1
- package/lib/content.js +351 -87
- package/lib/content.js.map +1 -1
- package/lib/export.d.ts +61 -0
- package/lib/export.d.ts.map +1 -1
- package/lib/export.js +217 -52
- package/lib/export.js.map +1 -1
- package/lib/find.d.ts.map +1 -1
- package/lib/find.js +73 -16
- package/lib/find.js.map +1 -1
- package/lib/http.d.ts +38 -2
- package/lib/http.d.ts.map +1 -1
- package/lib/http.js +279 -82
- package/lib/http.js.map +1 -1
- package/lib/reveal.d.ts +69 -3
- package/lib/reveal.d.ts.map +1 -1
- package/lib/reveal.js +140 -11
- package/lib/reveal.js.map +1 -1
- package/lib/tools.d.ts +30 -0
- package/lib/tools.d.ts.map +1 -1
- package/lib/tools.js +65 -3
- package/lib/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/combined.ts +107 -17
- package/src/content-search-worker.ts +52 -24
- package/src/content-search.ts +710 -36
- package/src/content.ts +349 -73
- package/src/export.ts +240 -50
- package/src/find.ts +83 -16
- package/src/http.ts +271 -83
- package/src/reveal.ts +148 -10
- package/src/tools.ts +83 -6
package/lib/content-search.js
CHANGED
|
@@ -1,47 +1,582 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Content FTS5 query
|
|
2
|
+
* Content FTS5 query engine: normal substring search, Notepad++-style extended
|
|
3
|
+
* escaping, case-sensitive GLOB matching and whole-word post-filtering, with
|
|
4
|
+
* exact or bounded counts.
|
|
5
|
+
*
|
|
6
|
+
* Shared by the host thread, the search worker and the combined panel search.
|
|
7
|
+
* The page path is deliberately two-phase: rank the rowids first, then read the
|
|
8
|
+
* few bodies and build the snippet in JS. Putting `snippet()` in the same
|
|
9
|
+
* `ORDER BY rank` statement made a SQLite sorter evaluate it for every match
|
|
10
|
+
* (measured 2.7 s for "the" on a 1 GB corpus; 60 ms with this split).
|
|
11
|
+
*
|
|
12
|
+
* Every unbounded-looking path has an explicit budget: queries shorter than a
|
|
13
|
+
* trigram are rejected instead of degrading into a full-table LIKE/GLOB scan,
|
|
14
|
+
* and the whole-word post-filter stops after a fixed number of rows, body bytes
|
|
15
|
+
* or milliseconds and reports a bounded count.
|
|
3
16
|
* @module dsh-locator/content-search
|
|
4
17
|
*/
|
|
18
|
+
import { sep } from 'node:path';
|
|
19
|
+
/** Shortest text a trigram tokenizer can index. */
|
|
20
|
+
const TRIGRAM_MIN = 3;
|
|
21
|
+
/** Query entry limits: no unbounded parsing, no unbounded SQL. */
|
|
22
|
+
const MAX_QUERY_CODEPOINTS = 256;
|
|
23
|
+
const MAX_QUERY_TERMS = 32;
|
|
24
|
+
const MAX_LIMIT = 100;
|
|
25
|
+
const DEFAULT_COUNT_LIMIT = 1000;
|
|
26
|
+
const MAX_COUNT_LIMIT = 5000;
|
|
27
|
+
const SNIPPET_BEFORE = 60;
|
|
28
|
+
const SNIPPET_AFTER = 120;
|
|
29
|
+
const SNIPPET_MAX = 400;
|
|
30
|
+
/** Whole-word post-filter defaults (rows, body bytes, wall clock). */
|
|
31
|
+
const SCAN_MAX_ROWS = 5_000;
|
|
32
|
+
const SCAN_MAX_BYTES = 64 * 1024 * 1024;
|
|
33
|
+
const SCAN_MAX_MS = 800;
|
|
34
|
+
/** Bytes that count as "inside a word", matching the name engine. */
|
|
35
|
+
const WORD_BYTE = /[A-Za-z0-9_]/;
|
|
36
|
+
/** Control bytes: file names cannot contain them, so name patterns drop them. */
|
|
37
|
+
const CONTROL_CHARS = /[\u0000-\u001f]/;
|
|
5
38
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @param limit - maximum hits.
|
|
10
|
-
* @returns hits, ordered by relevance.
|
|
39
|
+
* Control bytes rejected in a content query. Tab/LF/CR stay allowed: they are
|
|
40
|
+
* ordinary term separators in normal mode and explicit escapes in extended
|
|
41
|
+
* mode. NUL and the other C0 bytes must never reach SQLite.
|
|
11
42
|
*/
|
|
12
|
-
|
|
43
|
+
const QUERY_CONTROL_CHARS = /[\u0000-\u0008\u000b\u000c\u000e-\u001f]/;
|
|
44
|
+
/** Text escaped for an FTS5 quoted phrase (`"` doubled). */
|
|
45
|
+
export function quoteFts(text) {
|
|
46
|
+
return '"' + text.replace(/"/g, '""') + '"';
|
|
47
|
+
}
|
|
48
|
+
/** Escape a literal for SQLite GLOB (`*`, `?`, `[`, `]`). */
|
|
49
|
+
export function escapeGlob(text) {
|
|
50
|
+
return text.replace(/[*?[\]]/g, ch => (ch === ']' ? '[]]' : '[' + ch + ']'));
|
|
51
|
+
}
|
|
52
|
+
/** Escape a literal for SQL LIKE with `ESCAPE '\'`. */
|
|
53
|
+
export function escapeLike(text) {
|
|
54
|
+
return text.replace(/[\\%_]/g, ch => '\\' + ch);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Decode Notepad++-style extended escapes: `\n`, `\r`, `\t`, `\0`, `\\`,
|
|
58
|
+
* `\xNN`. Unknown escapes are kept literally with a warning.
|
|
59
|
+
*/
|
|
60
|
+
export function decodeExtended(input) {
|
|
61
|
+
const warnings = new Set();
|
|
62
|
+
let text = '';
|
|
63
|
+
for (let i = 0; i < input.length; i++) {
|
|
64
|
+
const ch = input[i];
|
|
65
|
+
if (ch !== '\\') {
|
|
66
|
+
text += ch;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const next = input[i + 1];
|
|
70
|
+
if (next === undefined) {
|
|
71
|
+
warnings.add('extended-trailing-backslash');
|
|
72
|
+
text += '\\';
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
switch (next) {
|
|
76
|
+
case 'n':
|
|
77
|
+
text += '\n';
|
|
78
|
+
i++;
|
|
79
|
+
continue;
|
|
80
|
+
case 'r':
|
|
81
|
+
text += '\r';
|
|
82
|
+
i++;
|
|
83
|
+
continue;
|
|
84
|
+
case 't':
|
|
85
|
+
text += '\t';
|
|
86
|
+
i++;
|
|
87
|
+
continue;
|
|
88
|
+
case '0':
|
|
89
|
+
text += '\0';
|
|
90
|
+
warnings.add('extended-control-char');
|
|
91
|
+
i++;
|
|
92
|
+
continue;
|
|
93
|
+
case '\\':
|
|
94
|
+
text += '\\';
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
case 'x': {
|
|
98
|
+
const hex = input.slice(i + 2, i + 4);
|
|
99
|
+
if (!/^[0-9a-fA-F]{2}$/.test(hex)) {
|
|
100
|
+
return { ok: false, text: '', warnings: [...warnings], error: 'invalid-escape' };
|
|
101
|
+
}
|
|
102
|
+
const code = Number.parseInt(hex, 16);
|
|
103
|
+
text += String.fromCharCode(code);
|
|
104
|
+
if (code < 0x20 && code !== 0x09 && code !== 0x0a && code !== 0x0d)
|
|
105
|
+
warnings.add('extended-control-char');
|
|
106
|
+
i += 3;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
default:
|
|
110
|
+
warnings.add('extended-unknown-escape');
|
|
111
|
+
text += '\\' + next;
|
|
112
|
+
i++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { ok: true, text, warnings: [...warnings] };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Extended decoding for file names: names cannot contain control characters, so
|
|
119
|
+
* they are dropped from the pattern and reported instead of silently matching
|
|
120
|
+
* nothing.
|
|
121
|
+
*/
|
|
122
|
+
export function decodeExtendedForNames(input) {
|
|
123
|
+
const decoded = decodeExtended(input);
|
|
124
|
+
if (!decoded.ok)
|
|
125
|
+
return decoded;
|
|
126
|
+
const kept = decoded.text.replace(CONTROL_CHARS, '');
|
|
127
|
+
if (kept !== decoded.text)
|
|
128
|
+
decoded.warnings.push('name-extended-control-char');
|
|
129
|
+
return { ...decoded, text: kept };
|
|
130
|
+
}
|
|
131
|
+
/** Length in Unicode code points, so emoji count as one character. */
|
|
132
|
+
function codePointCount(text) {
|
|
133
|
+
return Array.from(text).length;
|
|
134
|
+
}
|
|
135
|
+
/** Whether text still contains a byte the content query must reject. */
|
|
136
|
+
function hasControlChars(text) {
|
|
137
|
+
return QUERY_CONTROL_CHARS.test(text);
|
|
138
|
+
}
|
|
139
|
+
/** Split a normal-mode query on whitespace, dropping empty terms. */
|
|
140
|
+
function splitTerms(text) {
|
|
141
|
+
return text.split(/\s+/).map(part => part.replace(/^"|"$/g, '')).filter(part => part !== '');
|
|
142
|
+
}
|
|
143
|
+
/** Split decoded extended text into words for the entry checks. */
|
|
144
|
+
function splitWords(text) {
|
|
145
|
+
return text.split(/\s+/).filter(part => part !== '');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate a content query before it reaches SQL.
|
|
149
|
+
*
|
|
150
|
+
* Content search only supports substrings the FTS5 trigram tokenizer can
|
|
151
|
+
* serve. A 1–2 character term used to fall back to a whole-corpus `LIKE` scan,
|
|
152
|
+
* which is both slow and unbounded; it is now a hard, visible error instead.
|
|
153
|
+
* The same limits apply after extended-mode escapes are decoded, and lengths
|
|
154
|
+
* are measured in Unicode code points so emoji are not mistaken for long text.
|
|
155
|
+
* @param query - raw query text.
|
|
156
|
+
* @param matchMode - `normal` (whitespace-separated terms) or `extended`.
|
|
157
|
+
* @returns normalized terms, or the first entry error.
|
|
158
|
+
*/
|
|
159
|
+
export function checkContentQuery(query, matchMode) {
|
|
160
|
+
const warnings = [];
|
|
13
161
|
const text = query.trim();
|
|
14
162
|
if (text === '')
|
|
15
|
-
return [];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
163
|
+
return { ok: true, terms: [], phrase: false, warnings };
|
|
164
|
+
if (codePointCount(text) > MAX_QUERY_CODEPOINTS) {
|
|
165
|
+
return { ok: false, terms: [], phrase: false, warnings, error: 'content-query-too-long' };
|
|
166
|
+
}
|
|
167
|
+
if (hasControlChars(text)) {
|
|
168
|
+
// A NUL (or other C0 byte) in the query must never be passed to SQLite:
|
|
169
|
+
// some string paths would stop at it and turn the query into "match
|
|
170
|
+
// everything". Reject it explicitly instead.
|
|
171
|
+
return { ok: false, terms: [], phrase: false, warnings, error: 'invalid-control-char' };
|
|
172
|
+
}
|
|
173
|
+
if (matchMode === 'extended') {
|
|
174
|
+
const decoded = decodeExtended(text);
|
|
175
|
+
warnings.push(...decoded.warnings);
|
|
176
|
+
if (!decoded.ok) {
|
|
177
|
+
return { ok: false, terms: [], phrase: false, warnings, error: decoded.error ?? 'invalid-escape' };
|
|
178
|
+
}
|
|
179
|
+
if (hasControlChars(decoded.text)) {
|
|
180
|
+
return { ok: false, terms: [], phrase: false, warnings, error: 'invalid-control-char' };
|
|
181
|
+
}
|
|
182
|
+
const words = splitWords(decoded.text);
|
|
183
|
+
if (words.length === 0)
|
|
184
|
+
return { ok: true, terms: [], phrase: true, warnings };
|
|
185
|
+
if (words.length > MAX_QUERY_TERMS) {
|
|
186
|
+
return { ok: false, terms: [], phrase: true, warnings, error: 'content-query-too-many-terms' };
|
|
187
|
+
}
|
|
188
|
+
if (words.some(word => codePointCount(word) < TRIGRAM_MIN)) {
|
|
189
|
+
return { ok: false, terms: [], phrase: true, warnings, error: 'content-query-too-short' };
|
|
190
|
+
}
|
|
191
|
+
return { ok: true, terms: [decoded.text], phrase: true, warnings };
|
|
192
|
+
}
|
|
193
|
+
const terms = splitTerms(text);
|
|
194
|
+
if (terms.length > MAX_QUERY_TERMS) {
|
|
195
|
+
return { ok: false, terms: [], phrase: false, warnings, error: 'content-query-too-many-terms' };
|
|
196
|
+
}
|
|
197
|
+
if (terms.some(term => codePointCount(term) < TRIGRAM_MIN)) {
|
|
198
|
+
return { ok: false, terms: [], phrase: false, warnings, error: 'content-query-too-short' };
|
|
199
|
+
}
|
|
200
|
+
return { ok: true, terms, phrase: false, warnings };
|
|
201
|
+
}
|
|
202
|
+
/** Whether `index` starts a whole-word occurrence of `length` bytes. */
|
|
203
|
+
export function isWholeWord(hay, index, length) {
|
|
204
|
+
const left = index === 0 || !WORD_BYTE.test(hay[index - 1] ?? '');
|
|
205
|
+
const end = index + length;
|
|
206
|
+
const right = end >= hay.length || !WORD_BYTE.test(hay[end] ?? '');
|
|
207
|
+
return left && right;
|
|
208
|
+
}
|
|
209
|
+
/** First whole-word (or plain) occurrence of any term, or null. */
|
|
210
|
+
export function locateMatch(body, terms, caseSensitive, wholeWord) {
|
|
211
|
+
const hay = caseSensitive ? body : body.toLowerCase();
|
|
212
|
+
let best = null;
|
|
213
|
+
for (const term of terms) {
|
|
214
|
+
if (term === '')
|
|
215
|
+
continue;
|
|
216
|
+
const needle = caseSensitive ? term : term.toLowerCase();
|
|
217
|
+
let from = 0;
|
|
218
|
+
while (from <= hay.length) {
|
|
219
|
+
const index = hay.indexOf(needle, from);
|
|
220
|
+
if (index < 0)
|
|
221
|
+
break;
|
|
222
|
+
if (!wholeWord || isWholeWord(hay, index, needle.length)) {
|
|
223
|
+
if (best === null || index < best.index)
|
|
224
|
+
best = { index, length: needle.length };
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
from = index + 1;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return best;
|
|
231
|
+
}
|
|
232
|
+
/** Every term must appear as a whole word (normal mode) or the literal must
|
|
233
|
+
* have non-word edges (extended mode is a single "term"). */
|
|
234
|
+
function matchesWholeWord(body, terms, caseSensitive) {
|
|
235
|
+
for (const term of terms) {
|
|
236
|
+
if (term === '')
|
|
237
|
+
continue;
|
|
238
|
+
if (locateMatch(body, [term], caseSensitive, true) === null)
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
/** 1-based line number of a byte offset. */
|
|
244
|
+
export function lineOf(body, index) {
|
|
245
|
+
let line = 1;
|
|
246
|
+
let from = 0;
|
|
247
|
+
for (;;) {
|
|
248
|
+
const next = body.indexOf('\n', from);
|
|
249
|
+
if (next < 0 || next >= index)
|
|
250
|
+
return line;
|
|
251
|
+
line++;
|
|
252
|
+
from = next + 1;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/** Bounded, single-line snippet around the first match. */
|
|
256
|
+
function makeSnippet(body, located) {
|
|
257
|
+
if (located === null) {
|
|
258
|
+
const flat = body.replace(/\s+/g, ' ').trim();
|
|
259
|
+
return flat.length > SNIPPET_MAX ? flat.slice(0, SNIPPET_MAX - 1) + '…' : flat;
|
|
260
|
+
}
|
|
261
|
+
const start = Math.max(0, located.index - SNIPPET_BEFORE);
|
|
262
|
+
const end = Math.min(body.length, located.index + located.length + SNIPPET_AFTER);
|
|
263
|
+
const flat = body.slice(start, end).replace(/\s+/g, ' ');
|
|
264
|
+
const text = (start > 0 ? '…' : '') + flat + (end < body.length ? '…' : '');
|
|
265
|
+
return text.length > SNIPPET_MAX ? text.slice(0, SNIPPET_MAX - 1) + '…' : text;
|
|
266
|
+
}
|
|
267
|
+
function emptyCount(mode) {
|
|
268
|
+
if (mode === 'none')
|
|
269
|
+
return { value: 0, kind: 'unknown' };
|
|
270
|
+
return { value: 0, kind: 'exact' };
|
|
271
|
+
}
|
|
272
|
+
function clampLimit(limit) {
|
|
273
|
+
return Math.max(1, Math.min(MAX_LIMIT, Number.isFinite(limit) ? Math.trunc(limit) : MAX_LIMIT));
|
|
274
|
+
}
|
|
275
|
+
function clampCountLimit(limit) {
|
|
276
|
+
if (limit === undefined || !Number.isFinite(limit))
|
|
277
|
+
return DEFAULT_COUNT_LIMIT;
|
|
278
|
+
return Math.max(1, Math.min(MAX_COUNT_LIMIT, Math.trunc(limit)));
|
|
279
|
+
}
|
|
280
|
+
/** A positive integer override, or the default when unset/invalid. */
|
|
281
|
+
function budgetValue(value, fallback) {
|
|
282
|
+
if (value === undefined || !Number.isFinite(value) || value < 0)
|
|
283
|
+
return fallback;
|
|
284
|
+
return Math.trunc(value);
|
|
285
|
+
}
|
|
286
|
+
function resolveScanBudget(budget) {
|
|
287
|
+
return {
|
|
288
|
+
maxRows: budgetValue(budget?.maxRows, SCAN_MAX_ROWS),
|
|
289
|
+
maxBytes: budgetValue(budget?.maxBytes, SCAN_MAX_BYTES),
|
|
290
|
+
maxMs: budgetValue(budget?.maxMs, SCAN_MAX_MS),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/** Normalize the optional path-prefix filter; keep the platform separator. */
|
|
294
|
+
function normalizePathPrefix(prefix) {
|
|
295
|
+
if (typeof prefix !== 'string')
|
|
296
|
+
return null;
|
|
297
|
+
const trimmed = prefix.trim();
|
|
298
|
+
if (trimmed === '')
|
|
299
|
+
return null;
|
|
300
|
+
if (trimmed.endsWith('/') || trimmed.endsWith('\\'))
|
|
301
|
+
return trimmed;
|
|
302
|
+
return trimmed + sep;
|
|
303
|
+
}
|
|
304
|
+
function buildPlan(terms, options) {
|
|
305
|
+
const { caseSensitive, wholeWord, phrase, sessionPath, pathPrefix } = options;
|
|
306
|
+
if (terms.length === 0)
|
|
307
|
+
return null;
|
|
308
|
+
// Only files live inside the workspace prefix. Session rows belong to the
|
|
309
|
+
// session scope and are filtered by sessionPath/sessionId instead.
|
|
310
|
+
const suffix = [];
|
|
311
|
+
const suffixParams = [];
|
|
312
|
+
if (sessionPath !== null) {
|
|
313
|
+
suffix.push(' AND rowid IN (SELECT rowid FROM docs_meta WHERE path = ?)');
|
|
314
|
+
suffixParams.push(sessionPath);
|
|
315
|
+
}
|
|
316
|
+
if (pathPrefix !== null) {
|
|
317
|
+
suffix.push(" AND (kind = 'session' OR rowid IN (SELECT rowid FROM docs_meta WHERE path LIKE ? ESCAPE '\\'))");
|
|
318
|
+
suffixParams.push(escapeLike(pathPrefix) + '%');
|
|
319
|
+
}
|
|
320
|
+
const sessionClause = suffix.join('');
|
|
321
|
+
if (phrase) {
|
|
322
|
+
const literal = terms[0];
|
|
323
|
+
if (caseSensitive) {
|
|
324
|
+
return {
|
|
325
|
+
where: 'body GLOB ?' + sessionClause,
|
|
326
|
+
params: ['*' + escapeGlob(literal) + '*', ...suffixParams],
|
|
327
|
+
terms: [literal],
|
|
328
|
+
caseSensitive,
|
|
329
|
+
wholeWord,
|
|
330
|
+
phrase,
|
|
331
|
+
rankOrder: false,
|
|
332
|
+
exactCount: true,
|
|
333
|
+
boundedCount: true,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
where: 'docs MATCH ?' + sessionClause,
|
|
338
|
+
params: [quoteFts(literal), ...suffixParams],
|
|
339
|
+
terms: [literal],
|
|
340
|
+
caseSensitive,
|
|
341
|
+
wholeWord,
|
|
342
|
+
phrase,
|
|
343
|
+
rankOrder: true,
|
|
344
|
+
exactCount: true,
|
|
345
|
+
boundedCount: false,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (caseSensitive) {
|
|
349
|
+
return {
|
|
350
|
+
where: terms.map(() => 'body GLOB ?').join(' AND ') + sessionClause,
|
|
351
|
+
params: [...terms.map(term => '*' + escapeGlob(term) + '*'), ...suffixParams],
|
|
352
|
+
terms: [...terms],
|
|
353
|
+
caseSensitive,
|
|
354
|
+
wholeWord,
|
|
355
|
+
phrase,
|
|
356
|
+
rankOrder: false,
|
|
357
|
+
exactCount: true,
|
|
358
|
+
boundedCount: true,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
where: 'docs MATCH ?' + sessionClause,
|
|
363
|
+
params: [terms.map(quoteFts).join(' AND '), ...suffixParams],
|
|
364
|
+
terms: [...terms],
|
|
365
|
+
caseSensitive,
|
|
366
|
+
wholeWord,
|
|
367
|
+
phrase,
|
|
368
|
+
rankOrder: true,
|
|
369
|
+
exactCount: true,
|
|
370
|
+
boundedCount: false,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const DOC_SQL = `SELECT d.kind AS kind, d.path AS path, d.title AS title,
|
|
374
|
+
d.session_id AS session_id, d.message_id AS message_id, d.body AS body,
|
|
375
|
+
m.node_key AS node_key
|
|
376
|
+
FROM docs d LEFT JOIN docs_meta m ON m.rowid = d.rowid
|
|
377
|
+
WHERE d.rowid = ?`;
|
|
378
|
+
/** Build hits from rowids: metadata, snippet, first-match line and score. */
|
|
379
|
+
function buildHits(db, plan, rowids, scores) {
|
|
380
|
+
const statement = db.prepare(DOC_SQL);
|
|
381
|
+
const hits = [];
|
|
382
|
+
for (const rowid of rowids) {
|
|
383
|
+
const row = statement.get(rowid);
|
|
384
|
+
if (row === undefined || typeof row.body !== 'string')
|
|
385
|
+
continue;
|
|
386
|
+
const located = locateMatch(row.body, plan.terms, plan.caseSensitive, plan.wholeWord);
|
|
387
|
+
const line = located === null ? undefined : lineOf(row.body, located.index);
|
|
388
|
+
const score = scores.get(rowid);
|
|
389
|
+
const hit = {
|
|
390
|
+
kind: row.kind === 'session' ? 'session' : 'file',
|
|
391
|
+
path: typeof row.path === 'string' ? row.path : '',
|
|
392
|
+
title: typeof row.title === 'string' ? row.title : '',
|
|
393
|
+
snippet: makeSnippet(row.body, located),
|
|
394
|
+
score: score === undefined ? 0 : score,
|
|
395
|
+
...(typeof row.session_id === 'string' && row.session_id !== '' ? { sessionId: row.session_id } : {}),
|
|
396
|
+
...(typeof row.message_id === 'string' && row.message_id !== '' ? { messageId: row.message_id } : {}),
|
|
397
|
+
...(typeof row.node_key === 'string' && row.node_key !== '' ? { nodeKey: row.node_key } : {}),
|
|
398
|
+
...(line === undefined ? {} : { line }),
|
|
399
|
+
};
|
|
400
|
+
hits.push(hit);
|
|
401
|
+
}
|
|
402
|
+
return hits;
|
|
403
|
+
}
|
|
404
|
+
/** Candidate rowids for one page (no post-filter). */
|
|
405
|
+
function pageRowids(db, plan, limit) {
|
|
406
|
+
const scores = new Map();
|
|
407
|
+
const sql = plan.rankOrder
|
|
408
|
+
? `SELECT rowid AS rowid, rank AS score FROM docs WHERE ${plan.where} ORDER BY rank LIMIT ?`
|
|
409
|
+
: `SELECT rowid AS rowid FROM docs WHERE ${plan.where} LIMIT ?`;
|
|
410
|
+
const rows = db.prepare(sql).all(...plan.params, limit);
|
|
411
|
+
const rowids = [];
|
|
412
|
+
for (const row of rows) {
|
|
413
|
+
if (typeof row.rowid !== 'number')
|
|
414
|
+
continue;
|
|
415
|
+
rowids.push(row.rowid);
|
|
416
|
+
if (typeof row.score === 'number')
|
|
417
|
+
scores.set(row.rowid, row.score);
|
|
418
|
+
}
|
|
419
|
+
return { rowids, scores };
|
|
420
|
+
}
|
|
421
|
+
/** Exact COUNT over the plan's WHERE fragment. */
|
|
422
|
+
function exactCount(db, plan) {
|
|
423
|
+
const row = db.prepare(`SELECT count(*) AS n FROM docs WHERE ${plan.where}`).get(...plan.params);
|
|
424
|
+
return Number(row?.n ?? 0);
|
|
425
|
+
}
|
|
426
|
+
/** Count up to `limit + 1` rows: exact below the cap, bounded at the cap. */
|
|
427
|
+
function boundedCount(db, plan, limit) {
|
|
428
|
+
const row = db
|
|
429
|
+
.prepare(`SELECT count(*) AS n FROM (SELECT rowid FROM docs WHERE ${plan.where} LIMIT ?)`)
|
|
430
|
+
.get(...plan.params, limit + 1);
|
|
431
|
+
const value = Number(row?.n ?? 0);
|
|
432
|
+
if (value > limit)
|
|
433
|
+
return { value: limit, kind: 'bounded', limit };
|
|
434
|
+
return { value, kind: 'exact' };
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Scan candidates for whole-word matches under a hard budget.
|
|
438
|
+
*
|
|
439
|
+
* Reading every candidate body in JS is the only correct way to apply the
|
|
440
|
+
* ASCII word-boundary rule, but a common word in a multi-GB corpus would keep
|
|
441
|
+
* the worker (and the query) busy for minutes. Rows, body bytes and wall clock
|
|
442
|
+
* are all capped: on any cap the scan stops, keeps the rowids found so far and
|
|
443
|
+
* reports a bounded count plus a `scan-capped` warning. Session-scoped scans go
|
|
444
|
+
* through the same budget, so a huge session cannot run unbounded either.
|
|
445
|
+
*/
|
|
446
|
+
function scanWholeWord(db, plan, limit, countMode, countLimit, sessionScoped, budget) {
|
|
447
|
+
const warnings = new Set();
|
|
448
|
+
const rowids = [];
|
|
449
|
+
const sql = plan.rankOrder
|
|
450
|
+
? `SELECT rowid AS rowid FROM docs WHERE ${plan.where} ORDER BY rank`
|
|
451
|
+
: `SELECT rowid AS rowid FROM docs WHERE ${plan.where}`;
|
|
452
|
+
const iterator = db.prepare(sql).iterate(...plan.params);
|
|
453
|
+
const bodyStatement = db.prepare('SELECT body FROM docs WHERE rowid = ?');
|
|
454
|
+
const deadline = performance.now() + budget.maxMs;
|
|
455
|
+
let count = 0;
|
|
456
|
+
let scannedRows = 0;
|
|
457
|
+
let scannedBytes = 0;
|
|
458
|
+
let capped = false;
|
|
459
|
+
let exhausted = true;
|
|
460
|
+
for (const raw of iterator) {
|
|
461
|
+
scannedRows++;
|
|
462
|
+
if (scannedRows > budget.maxRows || scannedBytes >= budget.maxBytes || performance.now() > deadline) {
|
|
463
|
+
capped = true;
|
|
464
|
+
exhausted = false;
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
const rowid = raw.rowid;
|
|
468
|
+
if (typeof rowid !== 'number')
|
|
469
|
+
continue;
|
|
470
|
+
const row = bodyStatement.get(rowid);
|
|
471
|
+
if (row === undefined || typeof row.body !== 'string')
|
|
472
|
+
continue;
|
|
473
|
+
scannedBytes += row.body.length;
|
|
474
|
+
if (!matchesWholeWord(row.body, plan.terms, plan.caseSensitive))
|
|
475
|
+
continue;
|
|
476
|
+
count++;
|
|
477
|
+
if (rowids.length < limit)
|
|
478
|
+
rowids.push(rowid);
|
|
479
|
+
if (countMode === 'none') {
|
|
480
|
+
if (rowids.length >= limit) {
|
|
481
|
+
// The page is full; no count was requested, so stopping is safe.
|
|
482
|
+
exhausted = false;
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else if (!sessionScoped && count > countLimit) {
|
|
487
|
+
exhausted = false;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (capped)
|
|
492
|
+
warnings.add('scan-capped');
|
|
493
|
+
let result;
|
|
494
|
+
if (countMode === 'none') {
|
|
495
|
+
result = { value: 0, kind: 'unknown' };
|
|
496
|
+
}
|
|
497
|
+
else if (count > countLimit) {
|
|
498
|
+
// Above the cap: report the known floor, never an exact count we did not
|
|
499
|
+
// finish. Global whole-word counts are deliberately bounded.
|
|
500
|
+
warnings.add('bounded-count');
|
|
501
|
+
result = { value: countLimit, kind: 'bounded', limit: countLimit };
|
|
502
|
+
}
|
|
503
|
+
else if (capped || !exhausted) {
|
|
504
|
+
result = { value: count, kind: 'bounded', limit: countLimit };
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
result = { value: count, kind: 'exact' };
|
|
508
|
+
}
|
|
509
|
+
return { rowids, count: result, warnings: [...warnings] };
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Run one content query.
|
|
513
|
+
*
|
|
514
|
+
* Modes: `normal` (whitespace-separated substring terms), `extended`
|
|
515
|
+
* (Notepad++ escapes, one literal phrase), `regex` (not executed server-side in
|
|
516
|
+
* 0.9.0: returns `content-regex-not-supported`).
|
|
517
|
+
*/
|
|
518
|
+
export function searchContent(db, query, limit, options = {}) {
|
|
519
|
+
const capped = clampLimit(limit);
|
|
520
|
+
const matchMode = options.matchMode ?? 'normal';
|
|
521
|
+
const countMode = options.count ?? 'exact';
|
|
522
|
+
const countLimit = clampCountLimit(options.countLimit);
|
|
523
|
+
if (matchMode === 'regex') {
|
|
524
|
+
return {
|
|
525
|
+
hits: [],
|
|
526
|
+
count: { value: 0, kind: 'unknown' },
|
|
527
|
+
warnings: ['content-regex-paused'],
|
|
528
|
+
error: 'content-regex-not-supported',
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
const check = checkContentQuery(query, matchMode);
|
|
532
|
+
const warnings = [...check.warnings];
|
|
533
|
+
if (!check.ok) {
|
|
534
|
+
return {
|
|
535
|
+
hits: [],
|
|
536
|
+
count: { value: 0, kind: 'unknown' },
|
|
537
|
+
warnings,
|
|
538
|
+
error: check.error ?? 'content-query-invalid',
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (check.terms.length === 0)
|
|
542
|
+
return { hits: [], count: emptyCount(countMode), warnings };
|
|
543
|
+
const plan = buildPlan(check.terms, {
|
|
544
|
+
caseSensitive: options.caseSensitive === true,
|
|
545
|
+
wholeWord: options.wholeWord === true,
|
|
546
|
+
phrase: check.phrase,
|
|
547
|
+
sessionPath: options.sessionPath ?? null,
|
|
548
|
+
pathPrefix: normalizePathPrefix(options.pathPrefix),
|
|
549
|
+
});
|
|
550
|
+
if (plan === null)
|
|
551
|
+
return { hits: [], count: emptyCount(countMode), warnings };
|
|
552
|
+
if (plan.wholeWord) {
|
|
553
|
+
const scanned = scanWholeWord(db, plan, capped, countMode, countLimit, options.sessionPath != null, resolveScanBudget(options.scanBudget));
|
|
554
|
+
for (const warning of scanned.warnings)
|
|
555
|
+
warnings.push(warning);
|
|
556
|
+
const hits = buildHits(db, plan, scanned.rowids, new Map());
|
|
557
|
+
return { hits, count: scanned.count, warnings: [...new Set(warnings)] };
|
|
558
|
+
}
|
|
559
|
+
let count;
|
|
560
|
+
if (countMode === 'none') {
|
|
561
|
+
count = { value: 0, kind: 'unknown' };
|
|
562
|
+
}
|
|
563
|
+
else if (countMode === 'bounded') {
|
|
564
|
+
count = boundedCount(db, plan, countLimit);
|
|
565
|
+
if (count.kind === 'bounded')
|
|
566
|
+
warnings.push('bounded-count');
|
|
567
|
+
}
|
|
568
|
+
else if (plan.exactCount && !plan.boundedCount) {
|
|
569
|
+
count = { value: exactCount(db, plan), kind: 'exact' };
|
|
25
570
|
}
|
|
26
571
|
else {
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
return rows.map(row => ({
|
|
37
|
-
kind: row.kind === 'session' ? 'session' : 'file',
|
|
38
|
-
path: String(row.path ?? ''),
|
|
39
|
-
title: String(row.title ?? ''),
|
|
40
|
-
snippet: String(row.snippet ?? row.body ?? '').replace(/[\u0001\u0002]/g, ''),
|
|
41
|
-
...(row.session_id ? { sessionId: String(row.session_id) } : {}),
|
|
42
|
-
...(row.message_id ? { messageId: String(row.message_id) } : {}),
|
|
43
|
-
...(row.node_key ? { nodeKey: String(row.node_key) } : {}),
|
|
44
|
-
score: Number(row.score ?? 0),
|
|
45
|
-
}));
|
|
572
|
+
// GLOB patterns cannot count cheaply: cap the work and report the known
|
|
573
|
+
// floor plus a warning.
|
|
574
|
+
count = boundedCount(db, plan, countLimit);
|
|
575
|
+
if (count.kind === 'bounded')
|
|
576
|
+
warnings.push('bounded-count');
|
|
577
|
+
}
|
|
578
|
+
const page = pageRowids(db, plan, capped);
|
|
579
|
+
const hits = buildHits(db, plan, page.rowids, page.scores);
|
|
580
|
+
return { hits, count, warnings: [...new Set(warnings)] };
|
|
46
581
|
}
|
|
47
582
|
//# sourceMappingURL=content-search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-search.js","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,EAAgB,EAAE,KAAa,EAAE,KAAa;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAChD,IAAI,IAAoC,CAAA;IACxC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;wDAGkC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAmC,CAAA;IAC3G,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7G,2EAA2E;QAC3E,yEAAyE;QACzE,0EAA0E;QAC1E,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;0DAGoC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAmC,CAAA;IAC9G,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;QACjD,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7E,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;KAC9B,CAAC,CAAC,CAAA;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"content-search.js","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"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"}
|