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.
Files changed (58) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README-es.md +30 -5
  3. package/README-hi.md +31 -5
  4. package/README-pt.md +31 -5
  5. package/README.en.md +31 -5
  6. package/README.md +31 -5
  7. package/bin/darwin-arm64/indexd +0 -0
  8. package/bin/darwin-x64/indexd +0 -0
  9. package/bin/linux-arm64/indexd +0 -0
  10. package/bin/linux-x64/indexd +0 -0
  11. package/bin/win32-arm64/indexd.exe +0 -0
  12. package/bin/win32-x64/indexd.exe +0 -0
  13. package/client.js +1198 -117
  14. package/lib/combined.d.ts +20 -3
  15. package/lib/combined.d.ts.map +1 -1
  16. package/lib/combined.js +85 -15
  17. package/lib/combined.js.map +1 -1
  18. package/lib/content-search-worker.d.ts +8 -3
  19. package/lib/content-search-worker.d.ts.map +1 -1
  20. package/lib/content-search-worker.js +54 -27
  21. package/lib/content-search-worker.js.map +1 -1
  22. package/lib/content-search.d.ts +127 -7
  23. package/lib/content-search.d.ts.map +1 -1
  24. package/lib/content-search.js +571 -36
  25. package/lib/content-search.js.map +1 -1
  26. package/lib/content.d.ts +83 -5
  27. package/lib/content.d.ts.map +1 -1
  28. package/lib/content.js +351 -87
  29. package/lib/content.js.map +1 -1
  30. package/lib/export.d.ts +61 -0
  31. package/lib/export.d.ts.map +1 -1
  32. package/lib/export.js +217 -52
  33. package/lib/export.js.map +1 -1
  34. package/lib/find.d.ts.map +1 -1
  35. package/lib/find.js +73 -16
  36. package/lib/find.js.map +1 -1
  37. package/lib/http.d.ts +38 -2
  38. package/lib/http.d.ts.map +1 -1
  39. package/lib/http.js +279 -82
  40. package/lib/http.js.map +1 -1
  41. package/lib/reveal.d.ts +69 -3
  42. package/lib/reveal.d.ts.map +1 -1
  43. package/lib/reveal.js +140 -11
  44. package/lib/reveal.js.map +1 -1
  45. package/lib/tools.d.ts +30 -0
  46. package/lib/tools.d.ts.map +1 -1
  47. package/lib/tools.js +65 -3
  48. package/lib/tools.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/combined.ts +107 -17
  51. package/src/content-search-worker.ts +52 -24
  52. package/src/content-search.ts +710 -36
  53. package/src/content.ts +349 -73
  54. package/src/export.ts +240 -50
  55. package/src/find.ts +83 -16
  56. package/src/http.ts +271 -83
  57. package/src/reveal.ts +148 -10
  58. package/src/tools.ts +83 -6
package/lib/combined.d.ts CHANGED
@@ -4,11 +4,13 @@
4
4
  *
5
5
  * The name index and the content index live in different stores, so this module
6
6
  * owns the orchestration and the merge rules as pure, injectable functions:
7
- * scope gating, the lazy-build guard for empty queries, per-group degradation
8
- * and de-duplication of a path that appears both as a body hit and a name hit.
7
+ * scope gating, the lazy-build guard for empty queries, per-group degradation,
8
+ * match-option routing (content vs name engine), page counts and de-duplication
9
+ * of a path that appears both as a body hit and a name hit.
9
10
  * @module dsh-locator/combined
10
11
  */
11
12
  import type { ContentHit, ContentState } from './content.ts';
13
+ import type { ContentCount, ContentCountMode, ContentMatchMode, ContentSearchOptions, ContentSearchResult } from './content-search.ts';
12
14
  import type { SearchArgs, SearchHit, SearchResult } from './runtime.ts';
13
15
  /** Which groups a combined request asked for; every scope is on by default. */
14
16
  export interface CombinedScopes {
@@ -24,6 +26,15 @@ export interface CombinedRequest {
24
26
  sort: string;
25
27
  desc: boolean;
26
28
  scopes: CombinedScopes;
29
+ /** How the query text is interpreted (`normal` by default). */
30
+ matchMode: ContentMatchMode;
31
+ caseSensitive: boolean;
32
+ wholeWord: boolean;
33
+ /** Restrict the content group to one session (null means every document). */
34
+ sessionId: string | null;
35
+ /** How much counting work the groups may spend. */
36
+ count: ContentCountMode;
37
+ countLimit: number;
27
38
  }
28
39
  /** One name-index group: files or directories. */
29
40
  export interface NameGroup {
@@ -33,7 +44,10 @@ export interface NameGroup {
33
44
  truncated: boolean;
34
45
  /** Rows dropped because the same path already appears in the content group. */
35
46
  deduped: number;
47
+ /** The name engine always returns an exact total. */
48
+ count: ContentCount;
36
49
  tookMs: number;
50
+ warnings?: string[];
37
51
  error?: string;
38
52
  }
39
53
  /** The content group: body/session hits plus the index state at query time. */
@@ -42,6 +56,9 @@ export interface ContentGroup {
42
56
  returned: number;
43
57
  /** True when the group was cut off by its page limit. */
44
58
  capped: boolean;
59
+ /** Exact or bounded match count; `unknown` when counting was skipped. */
60
+ count: ContentCount;
61
+ warnings: string[];
45
62
  building: boolean;
46
63
  files: number;
47
64
  sessions: number;
@@ -64,7 +81,7 @@ export interface CombinedResponse {
64
81
  /** Dependencies required to run a combined search; the HTTP layer supplies them. */
65
82
  export interface CombinedDeps {
66
83
  search(args: SearchArgs): Promise<SearchResult>;
67
- contentSearch?: (query: string, limit: number) => Promise<ContentHit[]>;
84
+ contentSearch?: (query: string, limit: number, options: ContentSearchOptions) => Promise<ContentSearchResult>;
68
85
  contentStatus?: () => ContentState;
69
86
  ensure?: () => void;
70
87
  maxResults: number;
@@ -1 +1 @@
1
- {"version":3,"file":"combined.d.ts","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combined.d.ts","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"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"}
package/lib/combined.js CHANGED
@@ -4,10 +4,12 @@
4
4
  *
5
5
  * The name index and the content index live in different stores, so this module
6
6
  * owns the orchestration and the merge rules as pure, injectable functions:
7
- * scope gating, the lazy-build guard for empty queries, per-group degradation
8
- * and de-duplication of a path that appears both as a body hit and a name hit.
7
+ * scope gating, the lazy-build guard for empty queries, per-group degradation,
8
+ * match-option routing (content vs name engine), page counts and de-duplication
9
+ * of a path that appears both as a body hit and a name hit.
9
10
  * @module dsh-locator/combined
10
11
  */
12
+ import { checkContentQuery, decodeExtendedForNames } from "./content-search.js";
11
13
  /**
12
14
  * Read the three scope flags from a request body. Anything that is not an
13
15
  * explicit `false` counts as enabled, so a panel that only sends `{ content:
@@ -39,6 +41,12 @@ export function readCombinedRequest(body, maxResults) {
39
41
  sort: sortKey(body.sort),
40
42
  desc: body.desc === true,
41
43
  scopes: readScopes(body),
44
+ matchMode: matchMode(body.matchMode),
45
+ caseSensitive: body.caseSensitive === true,
46
+ wholeWord: body.wholeWord === true,
47
+ sessionId: typeof body.sessionId === 'string' && body.sessionId.trim() !== '' ? body.sessionId : null,
48
+ count: countMode(body.count),
49
+ countLimit: clamp(body.countLimit, 1, 5000, 1000),
42
50
  };
43
51
  }
44
52
  /**
@@ -80,9 +88,10 @@ export async function runCombinedSearch(deps, request) {
80
88
  const { scopes, query } = request;
81
89
  const contentEnabled = deps.contentSearch !== undefined;
82
90
  const wantsContent = scopes.content && contentEnabled;
83
- // Two characters are the floor for the content store: one-character queries
84
- // fall back to an unindexed LIKE scan and are not worth a build or a query.
85
- const askContent = wantsContent && query.trim().length >= 2;
91
+ // Any non-empty query is evaluated against the content store; short or
92
+ // over-limit queries are rejected by the same validator the store uses, so
93
+ // the panel can show `content-query-too-short` without starting a build.
94
+ const askContent = wantsContent && query.trim() !== '';
86
95
  const contentPromise = wantsContent ? contentGroup(deps, request, askContent) : Promise.resolve(undefined);
87
96
  const filesPromise = scopes.files ? nameGroup(deps, request, true) : Promise.resolve(undefined);
88
97
  const dirsPromise = scopes.dirs ? nameGroup(deps, request, false) : Promise.resolve(undefined);
@@ -111,16 +120,42 @@ export async function runCombinedSearch(deps, request) {
111
120
  /** Page through a directory-shaped name query. */
112
121
  async function nameGroup(deps, request, files) {
113
122
  const started = Date.now();
123
+ const empty = (error, warnings) => ({
124
+ hits: [],
125
+ returned: 0,
126
+ total: 0,
127
+ truncated: false,
128
+ deduped: 0,
129
+ count: { value: 0, kind: 'exact' },
130
+ tookMs: Date.now() - started,
131
+ ...(warnings === undefined || warnings.length === 0 ? {} : { warnings }),
132
+ ...(error === undefined ? {} : { error }),
133
+ });
134
+ // The name engine understands everything except Notepad++-style escapes:
135
+ // decode them here and drop control characters (file names cannot contain
136
+ // them) instead of searching for a literal backslash sequence.
137
+ let nameQuery = request.query;
138
+ let warnings = [];
139
+ if (request.matchMode === 'extended') {
140
+ const decoded = decodeExtendedForNames(request.query);
141
+ warnings = decoded.warnings;
142
+ if (!decoded.ok)
143
+ return empty(decoded.error ?? 'invalid-escape', warnings);
144
+ nameQuery = decoded.text;
145
+ // An all-control-escape query must not degrade into "match everything".
146
+ if (nameQuery.trim() === '')
147
+ return empty(undefined, [...new Set([...warnings, 'name-extended-empty'])]);
148
+ }
114
149
  try {
115
150
  const result = await deps.search({
116
- query: request.query,
151
+ query: nameQuery,
117
152
  limit: request.limit,
118
153
  offset: 0,
119
154
  sort: request.sort,
120
155
  desc: request.desc,
121
- regex: false,
122
- caseSensitive: false,
123
- wholeWord: false,
156
+ regex: request.matchMode === 'regex',
157
+ caseSensitive: request.caseSensitive,
158
+ wholeWord: request.wholeWord,
124
159
  filesOnly: files,
125
160
  dirsOnly: !files,
126
161
  });
@@ -130,17 +165,19 @@ async function nameGroup(deps, request, files) {
130
165
  total: result.total,
131
166
  truncated: result.truncated,
132
167
  deduped: 0,
168
+ count: { value: result.total, kind: 'exact' },
133
169
  tookMs: result.tookNs / 1e6,
170
+ ...(warnings.length === 0 ? {} : { warnings: [...new Set(warnings)] }),
134
171
  };
135
172
  }
136
173
  catch (error) {
137
- return { hits: [], returned: 0, total: 0, truncated: false, deduped: 0, tookMs: Date.now() - started, error: messageOf(error) };
174
+ return { ...empty(messageOf(error)), tookMs: Date.now() - started };
138
175
  }
139
176
  }
140
177
  /** Query the content store, or report its state without starting a build. */
141
178
  async function contentGroup(deps, request, ask) {
142
179
  const started = Date.now();
143
- const empty = () => {
180
+ const empty = (warnings = []) => {
144
181
  let state;
145
182
  try {
146
183
  state = deps.contentStatus?.();
@@ -152,6 +189,8 @@ async function contentGroup(deps, request, ask) {
152
189
  hits: [],
153
190
  returned: 0,
154
191
  capped: false,
192
+ count: { value: 0, kind: 'unknown' },
193
+ warnings,
155
194
  building: state?.building ?? false,
156
195
  files: state?.files ?? 0,
157
196
  sessions: state?.sessions ?? 0,
@@ -160,22 +199,47 @@ async function contentGroup(deps, request, ask) {
160
199
  tookMs: 0,
161
200
  };
162
201
  };
202
+ // 0.9.0 never scans the whole corpus from a panel keystroke: the content
203
+ // group pauses itself in regex mode while the name groups still run.
204
+ if (request.matchMode === 'regex') {
205
+ return { ...empty(['content-regex-paused']), error: 'content-regex-not-supported' };
206
+ }
163
207
  if (!ask || deps.contentSearch === undefined)
164
208
  return empty();
209
+ // Reject sub-trigram / over-limit / control-character queries here, before
210
+ // deps.ensure() can start a lazy content build the store cannot answer. The
211
+ // store performs the same check; sharing it keeps the error codes identical.
212
+ const check = checkContentQuery(request.query, request.matchMode);
213
+ if (!check.ok) {
214
+ return { ...empty(check.warnings), error: check.error ?? 'content-query-invalid', tookMs: Date.now() - started };
215
+ }
216
+ if (check.terms.length === 0)
217
+ return empty();
218
+ const options = {
219
+ matchMode: request.matchMode,
220
+ caseSensitive: request.caseSensitive,
221
+ wholeWord: request.wholeWord,
222
+ count: request.count,
223
+ countLimit: request.countLimit,
224
+ ...(request.sessionId === null ? {} : { sessionId: request.sessionId }),
225
+ };
165
226
  try {
166
227
  deps.ensure?.();
167
- const hits = await deps.contentSearch(request.query, request.contentLimit);
228
+ const result = await deps.contentSearch(request.query, request.contentLimit, options);
168
229
  const state = deps.contentStatus?.();
169
230
  return {
170
- hits,
171
- returned: hits.length,
172
- capped: hits.length >= request.contentLimit,
231
+ hits: result.hits,
232
+ returned: result.hits.length,
233
+ capped: result.hits.length >= request.contentLimit,
234
+ count: result.count,
235
+ warnings: result.warnings,
173
236
  building: state?.building ?? false,
174
237
  files: state?.files ?? 0,
175
238
  sessions: state?.sessions ?? 0,
176
239
  messages: state?.messages ?? 0,
177
240
  truncated: state?.truncated ?? false,
178
241
  tookMs: Date.now() - started,
242
+ ...(result.error === undefined ? {} : { error: result.error }),
179
243
  };
180
244
  }
181
245
  catch (error) {
@@ -187,6 +251,12 @@ function clamp(value, min, max, fallback) {
187
251
  return fallback;
188
252
  return Math.min(max, Math.max(min, Math.trunc(value)));
189
253
  }
254
+ function matchMode(value) {
255
+ return value === 'extended' || value === 'regex' ? value : 'normal';
256
+ }
257
+ function countMode(value) {
258
+ return value === 'bounded' || value === 'none' ? value : 'exact';
259
+ }
190
260
  function sortKey(value) {
191
261
  return value === 'name' || value === 'path' || value === 'size' || value === 'mtime' || value === 'ext' ? value : 'mtime';
192
262
  }
@@ -1 +1 @@
1
- {"version":3,"file":"combined.js","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combined.js","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AA0F/E;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,KAAK;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,KAAK;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B,EAAE,UAAkB;IACnF,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;IACnE,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IACzD,OAAO;QACL,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACvD,KAAK,EAAE,SAAS;QAChB,YAAY;QACZ,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI;QACxB,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;QACxB,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;QACpC,aAAa,EAAE,IAAI,CAAC,aAAa,KAAK,IAAI;QAC1C,SAAS,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI;QAClC,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACrG,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAkC,EAClC,QAA8B;IAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,KAAK,MAAM,GAAG,IAAI,WAAW;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;IAC/D,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,CAAA;YACT,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAkB,EAAE,OAAwB;IAClF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IACjC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAA;IACvD,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,IAAI,cAAc,CAAA;IACrD,uEAAuE;IACvE,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM,UAAU,GAAG,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;IAEtD,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC1G,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/F,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9F,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,CAAA;IAE7F,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;QACtC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YAC9D,OAAO;gBACL,GAAG,KAAK;gBACR,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;gBAC5B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;aACjD,CAAA;QACH,CAAC,CAAC,EAAE,CAAA;IAER,OAAO;QACL,MAAM;QACN,cAAc;QACd,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;KAC7B,CAAA;AACH,CAAC;AAED,kDAAkD;AAClD,KAAK,UAAU,SAAS,CAAC,IAAkB,EAAE,OAAwB,EAAE,KAAc;IACnF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,CAAC,KAAc,EAAE,QAAmB,EAAa,EAAE,CAAC,CAAC;QACjE,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;QAClC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;QAC5B,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QACxE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAC1C,CAAC,CAAA;IACF,yEAAyE;IACzE,0EAA0E;IAC1E,+DAA+D;IAC/D,IAAI,SAAS,GAAG,OAAO,CAAC,KAAK,CAAA;IAC7B,IAAI,QAAQ,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACrD,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAC3B,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,gBAAgB,EAAE,QAAQ,CAAC,CAAA;QAC1E,SAAS,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,wEAAwE;QACxE,IAAI,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1G,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;YAC/B,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,OAAO;YACpC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,CAAC,KAAK;SACjB,CAAC,CAAA;QACF,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;YAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,GAAG;YAC3B,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;SACvE,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;IACrE,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,KAAK,UAAU,YAAY,CAAC,IAAkB,EAAE,OAAwB,EAAE,GAAY;IACpF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,CAAC,WAAqB,EAAE,EAAgB,EAAE;QACtD,IAAI,KAA+B,CAAA;QACnC,IAAI,CAAC;YAAC,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,KAAK,GAAG,SAAS,CAAA;QAAC,CAAC;QAClE,OAAO;YACL,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;YACpC,QAAQ;YACR,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;YAClC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;YACxB,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK;YACpC,MAAM,EAAE,CAAC;SACV,CAAA;IACH,CAAC,CAAA;IACD,yEAAyE;IACzE,qEAAqE;IACrE,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;IACrF,CAAC;IACD,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,EAAE,CAAA;IAC5D,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IACjE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,uBAAuB,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;IAClH,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,EAAE,CAAA;IAC5C,MAAM,OAAO,GAAyB;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;KACxE,CAAA;IACD,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,EAAE,CAAA;QACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QACrF,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAA;QACpC,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC5B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,YAAY;YAClD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;YAClC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;YACxB,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK;YACpC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;YAC5B,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;SAC/D,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;IAC9E,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,KAAc,EAAE,GAAW,EAAE,GAAW,EAAE,QAAgB;IACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACzE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;AACrE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;AAClE,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;AAC3H,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC"}
@@ -1,7 +1,12 @@
1
1
  /**
2
- * Search worker: the FTS5 query runs here so a slow content query can never
3
- * stall the DSH host's event loop. A read-only connection makes the build's
4
- * writes in the main thread safe to observe concurrently (WAL).
2
+ * Search worker: content queries run here so a slow query can never stall the
3
+ * DSH host's event loop. A read-only connection makes the build's writes in the
4
+ * main thread safe to observe concurrently (WAL).
5
+ *
6
+ * Every request is answered with a complete {@link ContentSearchResult}; the
7
+ * worker never throws into the channel, because the host treats a timeout or a
8
+ * malformed reply as a hard error rather than re-running the query on the main
9
+ * thread.
5
10
  * @module dsh-locator/content-search-worker
6
11
  */
7
12
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"content-search-worker.d.ts","sourceRoot":"","sources":["../src/content-search-worker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
1
+ {"version":3,"file":"content-search-worker.d.ts","sourceRoot":"","sources":["../src/content-search-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -1,12 +1,21 @@
1
1
  /**
2
- * Search worker: the FTS5 query runs here so a slow content query can never
3
- * stall the DSH host's event loop. A read-only connection makes the build's
4
- * writes in the main thread safe to observe concurrently (WAL).
2
+ * Search worker: content queries run here so a slow query can never stall the
3
+ * DSH host's event loop. A read-only connection makes the build's writes in the
4
+ * main thread safe to observe concurrently (WAL).
5
+ *
6
+ * Every request is answered with a complete {@link ContentSearchResult}; the
7
+ * worker never throws into the channel, because the host treats a timeout or a
8
+ * malformed reply as a hard error rather than re-running the query on the main
9
+ * thread.
5
10
  * @module dsh-locator/content-search-worker
6
11
  */
7
12
  import { parentPort, workerData } from 'node:worker_threads';
8
13
  import { DatabaseSync } from 'node:sqlite';
9
14
  import { searchContent } from "./content-search.js";
15
+ /** A result shape every failure path can share. */
16
+ function failure(error, warnings = [error]) {
17
+ return { hits: [], count: { value: 0, kind: 'unknown' }, warnings, error };
18
+ }
10
19
  let db = null;
11
20
  function open(path) {
12
21
  try {
@@ -21,34 +30,52 @@ function open(path) {
21
30
  db = null;
22
31
  }
23
32
  }
24
- const initial = workerData?.dbPath;
25
- if (initial !== undefined)
26
- open(initial);
27
- parentPort?.on('message', (request) => {
28
- if (request.open !== undefined) {
29
- open(request.open);
30
- parentPort?.postMessage({ id: request.id, ok: true });
31
- return;
33
+ function post(message) {
34
+ try {
35
+ parentPort?.postMessage(message);
32
36
  }
33
- if (request.close === true) {
34
- try {
35
- db?.close();
37
+ catch { /* the host is gone; nothing to do */ }
38
+ }
39
+ /** Handle one request; never throws. */
40
+ function handle(request) {
41
+ try {
42
+ if (request.open !== undefined) {
43
+ open(request.open);
44
+ post({ id: request.id, ok: true });
45
+ return;
36
46
  }
37
- catch { /* ignore */ }
38
- db = null;
39
- parentPort?.postMessage({ id: request.id, ok: true });
40
- return;
41
- }
42
- let hits = [];
43
- let error = '';
44
- if (db !== null) {
45
- try {
46
- hits = searchContent(db, request.query ?? '', request.limit ?? 30);
47
+ if (request.close === true) {
48
+ try {
49
+ db?.close();
50
+ }
51
+ catch { /* ignore */ }
52
+ db = null;
53
+ post({ id: request.id, ok: true });
54
+ return;
55
+ }
56
+ if (typeof request.query !== 'string') {
57
+ post({ id: request.id, result: failure('content-search-worker-protocol-error') });
58
+ return;
47
59
  }
48
- catch (cause) {
49
- error = cause instanceof Error ? cause.message : String(cause);
60
+ if (db === null) {
61
+ post({ id: request.id, result: failure('content-index-unavailable') });
62
+ return;
50
63
  }
64
+ const result = searchContent(db, request.query, request.limit ?? 30, request.options ?? {});
65
+ post({ id: request.id, result });
51
66
  }
52
- parentPort?.postMessage({ id: request.id, hits, error });
67
+ catch {
68
+ // A thrown SQLite/JS error is reported as a result so the host can show a
69
+ // clear error code instead of silently re-running the query in-process.
70
+ post({ id: request.id, result: failure('content-search-worker-error') });
71
+ }
72
+ }
73
+ const initial = workerData?.dbPath;
74
+ if (initial !== undefined)
75
+ open(initial);
76
+ parentPort?.on('message', (request) => {
77
+ if (typeof request !== 'object' || request === null || typeof request.id !== 'number')
78
+ return;
79
+ handle(request);
53
80
  });
54
81
  //# sourceMappingURL=content-search-worker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-search-worker.js","sourceRoot":"","sources":["../src/content-search-worker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAWnD,IAAI,EAAE,GAAwB,IAAI,CAAA;AAElC,SAAS,IAAI,CAAC,IAAY;IACxB,IAAI,CAAC;QAAC,EAAE,EAAE,KAAK,EAAE,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC1C,EAAE,GAAG,IAAI,CAAA;IACT,IAAI,CAAC;QAAC,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,EAAE,GAAG,IAAI,CAAA;IAAC,CAAC;AAC7E,CAAC;AAED,MAAM,OAAO,GAAI,UAA8C,EAAE,MAAM,CAAA;AACvE,IAAI,OAAO,KAAK,SAAS;IAAE,IAAI,CAAC,OAAO,CAAC,CAAA;AAExC,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,OAAgB,EAAE,EAAE;IAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAClB,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,OAAM;IACR,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC;YAAC,EAAE,EAAE,KAAK,EAAE,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1C,EAAE,GAAG,IAAI,CAAA;QACT,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,OAAM;IACR,CAAC;IACD,IAAI,IAAI,GAAiB,EAAE,CAAA;IAC3B,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,IAAI,CAAC;YAAC,IAAI,GAAG,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACxF,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAChE,CAAC;IACH,CAAC;IACD,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;AAC1D,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"content-search-worker.js","sourceRoot":"","sources":["../src/content-search-worker.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,135 @@
1
1
  /**
2
- * Content FTS5 query shared by the host thread and the search worker.
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
  */
5
18
  import type { DatabaseSync } from 'node:sqlite';
6
19
  import type { ContentHit } from './content.ts';
20
+ /** How the query text is interpreted. */
21
+ export type ContentMatchMode = 'normal' | 'extended' | 'regex';
22
+ /** How much work the caller wants the count to spend. */
23
+ export type ContentCountMode = 'exact' | 'bounded' | 'none';
24
+ /** A match count, with its confidence. `bounded` means "at least value". */
25
+ export interface ContentCount {
26
+ value: number;
27
+ kind: 'exact' | 'bounded' | 'unknown';
28
+ limit?: number;
29
+ }
7
30
  /**
8
- * Run one content query against an open SQLite handle.
9
- * @param db - open database (read-only in the worker).
10
- * @param query - user query; shorter than three characters falls back to LIKE.
11
- * @param limit - maximum hits.
12
- * @returns hits, ordered by relevance.
31
+ * Hard budget for the whole-word post-filter, which has to read candidate
32
+ * bodies in JS. Exceeding any cap stops the scan and keeps the hits found so
33
+ * far; the count then becomes bounded. Exposed mainly so embedders and tests
34
+ * can shrink the caps.
13
35
  */
14
- export declare function searchContent(db: DatabaseSync, query: string, limit: number): ContentHit[];
36
+ export interface ContentScanBudget {
37
+ maxRows?: number;
38
+ maxBytes?: number;
39
+ maxMs?: number;
40
+ }
41
+ /** Options accepted by {@link searchContent} and the content search worker. */
42
+ export interface ContentSearchOptions {
43
+ matchMode?: ContentMatchMode;
44
+ caseSensitive?: boolean;
45
+ wholeWord?: boolean;
46
+ /** Resolved by ContentIndex from the request's sessionId. */
47
+ sessionId?: string;
48
+ /** Session log path; set by ContentIndex after resolving sessionId. */
49
+ sessionPath?: string | null;
50
+ count?: ContentCountMode;
51
+ countLimit?: number;
52
+ /**
53
+ * Keep only file/session documents whose stored path lives under this
54
+ * directory prefix (the locator_find `scope: workspace` filter). Session
55
+ * documents are unaffected: they are scoped by `sessionPath`/`sessionId`.
56
+ */
57
+ pathPrefix?: string | null;
58
+ /** Override for the whole-word scan caps; production uses the defaults. */
59
+ scanBudget?: ContentScanBudget;
60
+ }
61
+ /** Result of one content query. */
62
+ export interface ContentSearchResult {
63
+ hits: ContentHit[];
64
+ count: ContentCount;
65
+ warnings: string[];
66
+ error?: string;
67
+ }
68
+ /** Text escaped for an FTS5 quoted phrase (`"` doubled). */
69
+ export declare function quoteFts(text: string): string;
70
+ /** Escape a literal for SQLite GLOB (`*`, `?`, `[`, `]`). */
71
+ export declare function escapeGlob(text: string): string;
72
+ /** Escape a literal for SQL LIKE with `ESCAPE '\'`. */
73
+ export declare function escapeLike(text: string): string;
74
+ /** Decoded extended-mode query text. */
75
+ export interface DecodedExtended {
76
+ ok: boolean;
77
+ text: string;
78
+ warnings: string[];
79
+ /** `invalid-escape` when `\\xNN` is malformed. */
80
+ error?: string;
81
+ }
82
+ /**
83
+ * Decode Notepad++-style extended escapes: `\n`, `\r`, `\t`, `\0`, `\\`,
84
+ * `\xNN`. Unknown escapes are kept literally with a warning.
85
+ */
86
+ export declare function decodeExtended(input: string): DecodedExtended;
87
+ /**
88
+ * Extended decoding for file names: names cannot contain control characters, so
89
+ * they are dropped from the pattern and reported instead of silently matching
90
+ * nothing.
91
+ */
92
+ export declare function decodeExtendedForNames(input: string): DecodedExtended;
93
+ /** Result of the query-entry checks shared by searchContent and the panel. */
94
+ export interface ContentQueryCheck {
95
+ ok: boolean;
96
+ /** Literal terms for normal mode; one phrase for extended mode. */
97
+ terms: string[];
98
+ phrase: boolean;
99
+ warnings: string[];
100
+ error?: string;
101
+ }
102
+ /**
103
+ * Validate a content query before it reaches SQL.
104
+ *
105
+ * Content search only supports substrings the FTS5 trigram tokenizer can
106
+ * serve. A 1–2 character term used to fall back to a whole-corpus `LIKE` scan,
107
+ * which is both slow and unbounded; it is now a hard, visible error instead.
108
+ * The same limits apply after extended-mode escapes are decoded, and lengths
109
+ * are measured in Unicode code points so emoji are not mistaken for long text.
110
+ * @param query - raw query text.
111
+ * @param matchMode - `normal` (whitespace-separated terms) or `extended`.
112
+ * @returns normalized terms, or the first entry error.
113
+ */
114
+ export declare function checkContentQuery(query: string, matchMode: ContentMatchMode): ContentQueryCheck;
115
+ /** Whether `index` starts a whole-word occurrence of `length` bytes. */
116
+ export declare function isWholeWord(hay: string, index: number, length: number): boolean;
117
+ /** One located match: byte offset and length. */
118
+ interface Located {
119
+ index: number;
120
+ length: number;
121
+ }
122
+ /** First whole-word (or plain) occurrence of any term, or null. */
123
+ export declare function locateMatch(body: string, terms: readonly string[], caseSensitive: boolean, wholeWord: boolean): Located | null;
124
+ /** 1-based line number of a byte offset. */
125
+ export declare function lineOf(body: string, index: number): number;
126
+ /**
127
+ * Run one content query.
128
+ *
129
+ * Modes: `normal` (whitespace-separated substring terms), `extended`
130
+ * (Notepad++ escapes, one literal phrase), `regex` (not executed server-side in
131
+ * 0.9.0: returns `content-regex-not-supported`).
132
+ */
133
+ export declare function searchContent(db: DatabaseSync, query: string, limit: number, options?: ContentSearchOptions): ContentSearchResult;
134
+ export {};
15
135
  //# sourceMappingURL=content-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-search.d.ts","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAgC1F"}
1
+ {"version":3,"file":"content-search.d.ts","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"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"}