wicked-crew 0.14.1 → 0.14.2

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.
@@ -0,0 +1,578 @@
1
+ /**
2
+ * `GET /search` (api-types 0.127.0): one query over runs, projects, repos, transcripts (chat
3
+ * transcripts and unit outputs), rules, memories and documents.
4
+ *
5
+ * The index ({@link SearchIndex}) is built LAZILY: nothing is read until the first search, and that
6
+ * read runs off the request path — the first request waits a short while for it and answers with
7
+ * the sources still reading marked `indexing`. After that the index follows the daemon:
8
+ * - engine frames: a run's lifecycle re-reads the run list (debounced), a finished unit's output is
9
+ * read once, a chat reply re-reads that chat's transcript, a closed chat leaves;
10
+ * - the daemon's own writes: a successful mutating request re-reads the sources its path can change
11
+ * (`noteWrite`), debounced;
12
+ * - sources written outside the daemon (memories, rules a worker lands, documents) are also re-read
13
+ * when a search finds them older than their TTL — in the background, never on the request.
14
+ * A source that fails to read is `unavailable` with its reason; the others still answer.
15
+ */
16
+ import { open, readdir, stat } from 'node:fs/promises';
17
+ import { join } from 'node:path';
18
+ import { API_PREFIX } from './api-prefix.js';
19
+ import { coreUnitId } from './evidence.js';
20
+ import { jobTitle } from './job-title.js';
21
+ import { MAX_QUERY_CHARS, MIN_QUERY_CHARS, SEARCH_TYPES, SearchIndex, parseQuery, } from './search-index.js';
22
+ const SOURCES_OF = {
23
+ run: ['run'],
24
+ project: ['project'],
25
+ repo: ['repo'],
26
+ transcript: ['chat', 'run'],
27
+ rule: ['rule'],
28
+ memory: ['memory'],
29
+ doc: ['doc'],
30
+ };
31
+ /** How stale a source may get before a search re-reads it in the background (ms). */
32
+ const DEFAULT_TTL = {
33
+ run: 5 * 60_000,
34
+ project: 60_000,
35
+ repo: 60_000,
36
+ chat: 60_000,
37
+ rule: 60_000,
38
+ memory: 5 * 60_000,
39
+ doc: 2 * 60_000,
40
+ };
41
+ /** Engine frames that change the run list. */
42
+ const RUN_FRAMES = new Set([
43
+ 'sessionStarted', 'unitPlanned', 'unitDistributed', 'unitDispatched', 'unitExecuting', 'gateDecided', 'unitDone',
44
+ 'unitDenied', 'awaitingHuman', 'resumed', 'runCancelled', 'sessionFailed', 'sessionCompleted', 'unitReassigned',
45
+ ]);
46
+ /** The largest slice of a chat transcript file read (its head and tail). */
47
+ const CHAT_READ_BYTES = 2 * 1024 * 1024;
48
+ /** Unit outputs read per run-list load that the index has not tried yet (newest runs first). */
49
+ const UNIT_BACKFILL_MAX = 300;
50
+ /** Unit outputs read at once. */
51
+ const UNIT_CONCURRENCY = 2;
52
+ const message = (err) => (err instanceof Error ? err.message : String(err));
53
+ const secondsToMs = (s) => (s === undefined ? null : s * 1000);
54
+ const firstLine = (s, max) => {
55
+ const line = s.trim().split('\n')[0] ?? '';
56
+ return line.length > max ? `${line.slice(0, max - 1)}…` : line;
57
+ };
58
+ export class SearchService {
59
+ index;
60
+ deps;
61
+ states = new Map();
62
+ /** Off until the first search: before it, frames and writes cost nothing. */
63
+ active = false;
64
+ closed = false;
65
+ /** The last run list, for titling unit transcripts. */
66
+ runsById = new Map();
67
+ /** Unit outputs read (or found empty) — a backfill does not read them again; a `unitDone` does. */
68
+ unitsTried = new Set();
69
+ unitQueue = [];
70
+ unitWorkers = 0;
71
+ chatTimers = new Map();
72
+ constructor(deps) {
73
+ this.deps = deps;
74
+ this.index = new SearchIndex(deps.index);
75
+ for (const s of ['run', 'project', 'repo', 'chat', 'rule', 'memory', 'doc']) {
76
+ this.states.set(s, { loadedAt: null, loading: null, again: false, error: null, timer: null });
77
+ }
78
+ }
79
+ state(s) {
80
+ return this.states.get(s);
81
+ }
82
+ ttl(s) {
83
+ return this.deps.ttlMs?.[s] ?? DEFAULT_TTL[s];
84
+ }
85
+ /** Whether the source exists on this daemon. */
86
+ available(s) {
87
+ if (s === 'chat')
88
+ return this.deps.chatsDir !== undefined;
89
+ if (s === 'memory')
90
+ return this.deps.memories !== undefined;
91
+ if (s === 'doc')
92
+ return this.deps.docs !== undefined;
93
+ return true;
94
+ }
95
+ close() {
96
+ this.closed = true;
97
+ for (const st of this.states.values())
98
+ if (st.timer !== null)
99
+ clearTimeout(st.timer);
100
+ for (const t of this.chatTimers.values())
101
+ clearTimeout(t);
102
+ this.chatTimers.clear();
103
+ this.unitQueue.length = 0;
104
+ }
105
+ // ── Keeping current ──────────────────────────────────────────────────────────────────────────
106
+ /** One engine frame (the daemon's fan-in calls this for every frame; cheap until the first search). */
107
+ ingest(event) {
108
+ if (!this.active || this.closed)
109
+ return;
110
+ const f = event;
111
+ if (RUN_FRAMES.has(event.type))
112
+ this.markDirty('run');
113
+ if ((event.type === 'unitDone' || event.type === 'unitDenied') && typeof f['session'] === 'string' && typeof f['ord'] === 'number') {
114
+ this.enqueueUnit(f['session'], f['ord'], true);
115
+ }
116
+ if (event.type === 'chatReply' && typeof f['chat'] === 'string')
117
+ this.markChat(f['chat']);
118
+ if (event.type === 'chatClosed' && typeof f['chat'] === 'string') {
119
+ const t = this.chatTimers.get(f['chat']);
120
+ if (t !== undefined)
121
+ clearTimeout(t);
122
+ this.chatTimers.delete(f['chat']);
123
+ this.index.remove('transcript', `chat:${f['chat']}`);
124
+ }
125
+ }
126
+ /** A mutating request answered 2xx/3xx: re-read what its path can change. */
127
+ noteWrite(method, url) {
128
+ if (!this.active || this.closed || method === 'GET' || method === 'HEAD' || method === 'OPTIONS')
129
+ return;
130
+ const path = (url.split('?')[0] ?? '').replace(API_PREFIX, '');
131
+ const chat = /^\/chats\/([^/]+)\/messages$/.exec(path);
132
+ if (chat !== null && chat[1] !== undefined) {
133
+ this.markChat(decodeURIComponent(chat[1]));
134
+ return;
135
+ }
136
+ const touched = new Set();
137
+ if (path.startsWith('/projects')) {
138
+ touched.add('project');
139
+ touched.add('run');
140
+ if (path.includes('/interactive'))
141
+ touched.add('doc');
142
+ }
143
+ if (path.startsWith('/repos'))
144
+ touched.add('repo');
145
+ if (path.startsWith('/runs'))
146
+ touched.add('run');
147
+ if (path.startsWith('/interactive'))
148
+ touched.add('doc');
149
+ if (path.startsWith('/memory'))
150
+ touched.add('memory');
151
+ if (/^\/(proposals|decisions)/.test(path)) {
152
+ touched.add('memory');
153
+ touched.add('rule');
154
+ }
155
+ if (/^\/(governance|steering|policies|rules|editors)/.test(path))
156
+ touched.add('rule');
157
+ for (const s of touched)
158
+ this.markDirty(s);
159
+ }
160
+ markDirty(s) {
161
+ const st = this.state(s);
162
+ if (st.loadedAt === null && st.loading === null)
163
+ return; // never read: the first search reads it
164
+ // Already scheduled: that re-read will see this change too. (Never pushed back, so a steady stream
165
+ // of frames cannot starve it: a change waits at most one debounce.)
166
+ if (st.timer !== null)
167
+ return;
168
+ st.timer = setTimeout(() => { st.timer = null; void this.refresh(s); }, this.deps.debounceMs ?? 400);
169
+ st.timer.unref?.();
170
+ }
171
+ markChat(chatId) {
172
+ if (!this.available('chat'))
173
+ return;
174
+ if (this.chatTimers.has(chatId))
175
+ return; // the scheduled read will see this reply too
176
+ const t = setTimeout(() => {
177
+ this.chatTimers.delete(chatId);
178
+ void this.readChat(chatId).catch((err) => this.deps.log?.(`[search] chat ${chatId} transcript unread: ${message(err)}`));
179
+ }, this.deps.debounceMs ?? 400);
180
+ t.unref?.();
181
+ this.chatTimers.set(chatId, t);
182
+ }
183
+ /** Re-read one source (coalesced: a refresh asked for mid-read runs once more after it). */
184
+ refresh(s) {
185
+ const st = this.state(s);
186
+ if (this.closed || !this.available(s))
187
+ return Promise.resolve();
188
+ if (st.loading !== null) {
189
+ st.again = true;
190
+ return st.loading;
191
+ }
192
+ st.loading = (async () => {
193
+ try {
194
+ await this.load(s);
195
+ st.error = null;
196
+ }
197
+ catch (err) {
198
+ st.error = message(err);
199
+ this.deps.log?.(`[search] ${s} not readable: ${st.error}`);
200
+ }
201
+ finally {
202
+ st.loadedAt = Date.now();
203
+ st.loading = null;
204
+ }
205
+ if (st.again && !this.closed) {
206
+ st.again = false;
207
+ await this.refresh(s);
208
+ }
209
+ })();
210
+ return st.loading;
211
+ }
212
+ /** Before a query: read what was never read, re-read what is past its TTL (both off the request). */
213
+ ensure(types) {
214
+ this.active = true;
215
+ const first = [];
216
+ const seen = new Set();
217
+ for (const t of types) {
218
+ for (const s of SOURCES_OF[t]) {
219
+ if (seen.has(s) || !this.available(s))
220
+ continue;
221
+ seen.add(s);
222
+ const st = this.state(s);
223
+ if (st.loadedAt === null)
224
+ first.push(st.loading ?? this.refresh(s));
225
+ else if (st.loading === null && Date.now() - st.loadedAt > this.ttl(s))
226
+ void this.refresh(s);
227
+ }
228
+ }
229
+ return first;
230
+ }
231
+ // ── The sources ──────────────────────────────────────────────────────────────────────────────
232
+ async load(s) {
233
+ switch (s) {
234
+ case 'run': return this.loadRuns();
235
+ case 'project': {
236
+ const projects = await this.deps.projectList();
237
+ this.index.replaceType('project', projects.filter((p) => p.id !== 'default').map((p) => ({
238
+ type: 'project', id: p.id, title: p.name, body: p.description ?? '',
239
+ updatedAt: p.updated_at, projectId: p.id, status: p.status,
240
+ target: { kind: 'project', project_id: p.id }, boost: p.status === 'active' ? 0 : -3,
241
+ })));
242
+ return;
243
+ }
244
+ case 'repo': {
245
+ const repos = await this.deps.listRepos();
246
+ this.index.replaceType('repo', repos.map((r) => ({
247
+ type: 'repo', id: r.id, title: r.name,
248
+ body: [r.root_path, r.git_url ?? '', r.default_branch].filter((x) => x !== '').join('\n'),
249
+ updatedAt: r.registered_at > 1e12 ? r.registered_at : r.registered_at * 1000, projectId: null, status: null,
250
+ target: { kind: 'repo', repo_id: r.id },
251
+ })));
252
+ return;
253
+ }
254
+ case 'rule': {
255
+ const rules = await this.deps.listRules();
256
+ this.index.replaceType('rule', rules.map((r) => ({
257
+ type: 'rule', id: r.id, title: firstLine(r.statement, 140) || r.id,
258
+ body: [r.statement, r.criteria ?? '', ...(r.obligations ?? []), r.id, r.steering_type ?? '', r.rule_type].filter((x) => x !== '').join('\n'),
259
+ updatedAt: r.created_at !== undefined ? r.created_at * 1000 : null,
260
+ projectId: r.targets.project ?? null,
261
+ status: r.retired === true ? 'retired' : r.severity,
262
+ target: { kind: 'rule', rule_id: r.id, steering_type: r.steering_type ?? null },
263
+ boost: r.retired === true ? -4 : 0,
264
+ })));
265
+ return;
266
+ }
267
+ case 'memory': {
268
+ const items = await this.deps.memories();
269
+ this.index.replaceType('memory', items.map((m) => ({
270
+ type: 'memory', id: m.id, title: firstLine(m.content, 140) || m.id,
271
+ body: [m.content, ...Object.entries(m.facets).map(([k, v]) => `${k}:${v}`), m.tier].join('\n'),
272
+ updatedAt: m.created_at !== undefined && m.created_at !== null ? m.created_at * 1000 : null,
273
+ projectId: /(?:^|\/)project:([^/]+)/.exec(m.scope)?.[1] ?? null,
274
+ status: m.tier,
275
+ target: { kind: 'memory', memory_id: m.id, scope: m.scope },
276
+ })));
277
+ return;
278
+ }
279
+ case 'doc': {
280
+ const rows = await this.deps.docs();
281
+ this.index.replaceType('doc', rows.filter((d) => d.retired !== true).map((d) => {
282
+ const at = d.updatedAt !== null ? Date.parse(d.updatedAt) : NaN;
283
+ return {
284
+ type: 'doc', id: `${d.projectId}/${d.name}`, title: d.name,
285
+ body: [d.name.replace(/[-_.]+/g, ' '), d.kind].join('\n'),
286
+ updatedAt: Number.isFinite(at) ? at : null, projectId: d.projectId === 'default' ? null : d.projectId,
287
+ status: d.kind, target: { kind: 'doc', project_id: d.projectId, doc: d.name },
288
+ };
289
+ }));
290
+ return;
291
+ }
292
+ case 'chat': return this.loadChats();
293
+ }
294
+ }
295
+ runUpdatedAt(id) {
296
+ return secondsToMs(this.deps.runFacts?.endedAtFor(id) ?? this.deps.runFacts?.createdAtFor(id));
297
+ }
298
+ async loadRuns() {
299
+ const views = await this.deps.sessionsDetail();
300
+ this.runsById = new Map(views.map((v) => [v.session.id, v]));
301
+ this.index.replaceType('run', views.map((v) => {
302
+ const s = v.session;
303
+ const archived = s.archived_at !== null && s.archived_at !== undefined;
304
+ const unitText = v.units.flatMap((u) => [u.description, u.denial_reason ?? '']).filter((x) => x !== '');
305
+ return {
306
+ type: 'run', id: s.id, title: jobTitle(s.problem) || s.id,
307
+ body: [s.problem, ...unitText, s.workflow_id ?? '', s.repo_ref ?? '', s.id].filter((x) => x !== '').join('\n'),
308
+ updatedAt: this.runUpdatedAt(s.id), projectId: this.deps.projectOf(s.id) ?? null,
309
+ status: archived ? 'archived' : s.status,
310
+ target: { kind: 'run', run_id: s.id, chat_id: this.deps.runFacts?.chatIdFor(s.id) ?? null },
311
+ boost: archived ? -3 : 0,
312
+ };
313
+ }));
314
+ // A run that left the list takes its unit transcripts with it.
315
+ this.index.removeWhere('transcript', (id) => id.startsWith('unit:') && !this.runsById.has(id.slice(5, id.lastIndexOf(':'))));
316
+ // Backfill: outputs of finished units not read yet, newest runs first, bounded per load.
317
+ const newest = [...views].sort((a, b) => (this.runUpdatedAt(b.session.id) ?? 0) - (this.runUpdatedAt(a.session.id) ?? 0));
318
+ let queued = 0;
319
+ for (const v of newest) {
320
+ for (const u of v.units) {
321
+ if (queued >= UNIT_BACKFILL_MAX)
322
+ break;
323
+ if (u.status !== 'done' && u.status !== 'rejected')
324
+ continue;
325
+ if (this.unitsTried.has(`${v.session.id}:${u.ord}`))
326
+ continue;
327
+ this.enqueueUnit(v.session.id, u.ord, false);
328
+ queued += 1;
329
+ }
330
+ }
331
+ }
332
+ enqueueUnit(runId, ord, again) {
333
+ const key = `${runId}:${ord}`;
334
+ if (again)
335
+ this.unitsTried.delete(key);
336
+ if (this.unitsTried.has(key) || this.unitQueue.some((q) => q.runId === runId && q.ord === ord))
337
+ return;
338
+ this.unitQueue.push({ runId, ord });
339
+ this.drainUnits();
340
+ }
341
+ drainUnits() {
342
+ while (this.unitWorkers < UNIT_CONCURRENCY && this.unitQueue.length > 0 && !this.closed) {
343
+ const next = this.unitQueue.shift();
344
+ this.unitWorkers += 1;
345
+ void this.readUnit(next.runId, next.ord)
346
+ .catch((err) => this.deps.log?.(`[search] unit ${next.runId}:${next.ord} output unread: ${message(err)}`))
347
+ .finally(() => { this.unitWorkers -= 1; this.drainUnits(); });
348
+ }
349
+ }
350
+ async readUnit(runId, ord) {
351
+ this.unitsTried.add(`${runId}:${ord}`);
352
+ const view = this.runsById.get(runId);
353
+ const unit = view?.units.find((u) => u.ord === ord);
354
+ const unitId = unit !== undefined ? coreUnitId(runId, unit) : `${runId}:u${ord}`;
355
+ const output = await this.deps.workOutput(unitId);
356
+ const id = `unit:${runId}:${ord}`;
357
+ if (output === null || output.trim() === '') {
358
+ this.index.remove('transcript', id);
359
+ return;
360
+ }
361
+ const runTitle = view !== undefined ? jobTitle(view.session.problem) || runId : runId;
362
+ this.index.upsert({
363
+ type: 'transcript', id,
364
+ title: `${runTitle} · ${unit?.description.trim() || `step ${ord + 1}`}`,
365
+ body: output,
366
+ updatedAt: this.runUpdatedAt(runId), projectId: this.deps.projectOf(runId) ?? null,
367
+ status: unit?.status ?? null,
368
+ target: { kind: 'unit', run_id: runId, ord, chat_id: this.deps.runFacts?.chatIdFor(runId) ?? null },
369
+ });
370
+ }
371
+ async loadChats() {
372
+ const dir = this.deps.chatsDir();
373
+ let files;
374
+ try {
375
+ files = (await readdir(dir)).filter((f) => f.endsWith('.jsonl'));
376
+ }
377
+ catch (err) {
378
+ if (err.code === 'ENOENT')
379
+ files = [];
380
+ else
381
+ throw err;
382
+ }
383
+ const live = new Set(files.map((f) => f.slice(0, -6)));
384
+ this.index.removeWhere('transcript', (id) => id.startsWith('chat:') && !live.has(id.slice(5)));
385
+ for (const chatId of live)
386
+ await this.readChat(chatId);
387
+ }
388
+ /** One chat's transcript file: its head and tail (bounded), as one entity. */
389
+ async readChat(chatId) {
390
+ if (this.closed || !/^[A-Za-z0-9._-]+$/.test(chatId))
391
+ return;
392
+ const file = join(this.deps.chatsDir(), `${chatId}.jsonl`);
393
+ let text;
394
+ try {
395
+ const size = (await stat(file)).size;
396
+ const fh = await open(file, 'r');
397
+ try {
398
+ if (size <= CHAT_READ_BYTES) {
399
+ text = (await fh.readFile('utf8'));
400
+ }
401
+ else {
402
+ const half = CHAT_READ_BYTES / 2;
403
+ const head = Buffer.alloc(half);
404
+ const tail = Buffer.alloc(half);
405
+ await fh.read(head, 0, half, 0);
406
+ await fh.read(tail, 0, half, size - half);
407
+ // Cut lines are dropped: the head's last and the tail's first.
408
+ const h = head.toString('utf8');
409
+ const t = tail.toString('utf8');
410
+ text = `${h.slice(0, h.lastIndexOf('\n'))}\n${t.slice(t.indexOf('\n') + 1)}`;
411
+ }
412
+ }
413
+ finally {
414
+ await fh.close();
415
+ }
416
+ }
417
+ catch (err) {
418
+ if (err.code === 'ENOENT') {
419
+ this.index.remove('transcript', `chat:${chatId}`);
420
+ return;
421
+ }
422
+ throw err;
423
+ }
424
+ let title = '';
425
+ let last = null;
426
+ const parts = [];
427
+ for (const line of text.split('\n')) {
428
+ if (line.trim() === '')
429
+ continue;
430
+ let rec;
431
+ try {
432
+ rec = JSON.parse(line);
433
+ }
434
+ catch {
435
+ continue;
436
+ }
437
+ if (typeof rec['at'] === 'number')
438
+ last = rec['at'];
439
+ const said = typeof rec['text'] === 'string' ? rec['text'] : '';
440
+ if (said === '')
441
+ continue;
442
+ if (rec['kind'] === 'user') {
443
+ if (title === '')
444
+ title = jobTitle(said);
445
+ parts.push(said);
446
+ }
447
+ else if (rec['kind'] === 'seat') {
448
+ parts.push(`${typeof rec['cliKey'] === 'string' ? rec['cliKey'] : 'agent'}: ${said}`);
449
+ }
450
+ }
451
+ if (parts.length === 0) {
452
+ this.index.remove('transcript', `chat:${chatId}`);
453
+ return;
454
+ }
455
+ this.index.upsert({
456
+ type: 'transcript', id: `chat:${chatId}`, title: title || 'A chat', body: parts.join('\n'),
457
+ updatedAt: last, projectId: this.deps.projectOf(chatId) ?? null, status: 'chat',
458
+ target: { kind: 'chat', chat_id: chatId },
459
+ });
460
+ }
461
+ // ── The query ────────────────────────────────────────────────────────────────────────────────
462
+ async search(q, opts) {
463
+ const started = performance.now();
464
+ const budget = this.deps.budgetMs ?? 300;
465
+ const first = this.ensure(opts.types);
466
+ if (first.length > 0) {
467
+ // The first read is off the request path: wait for it a little, then answer with what is in.
468
+ let timer;
469
+ await Promise.race([
470
+ Promise.allSettled(first),
471
+ new Promise((r) => { timer = setTimeout(r, Math.min(this.deps.firstReadWaitMs ?? 1500, budget * 5)); }),
472
+ ]);
473
+ if (timer !== undefined)
474
+ clearTimeout(timer);
475
+ opts.signal?.throwIfAborted();
476
+ }
477
+ const parsed = parseQuery(q);
478
+ // The scan's budget starts now: the wait for a first read above is not the scan's time.
479
+ const scanStart = performance.now();
480
+ const searchable = opts.types.filter((t) => SOURCES_OF[t].some((s) => this.available(s) && this.state(s).loadedAt !== null));
481
+ const { groups, partial } = await this.index.query(parsed, {
482
+ types: searchable, limit: opts.limit, offset: opts.offset,
483
+ budgetMs: Math.max(1, budget - (performance.now() - scanStart)),
484
+ ...(opts.signal !== undefined ? { signal: opts.signal } : {}),
485
+ });
486
+ const sources = opts.types.map((type) => this.sourceState(type));
487
+ return { query: parsed.text, groups, sources, partial, took_ms: Math.round(performance.now() - started) };
488
+ }
489
+ sourceState(type) {
490
+ const srcs = SOURCES_OF[type].filter((s) => this.available(s));
491
+ if (srcs.length === 0)
492
+ return { type, state: 'unavailable', indexed: 0, note: 'This daemon has no source for it.' };
493
+ const sts = srcs.map((s) => this.state(s));
494
+ const indexed = this.index.count(type);
495
+ if (sts.some((st) => st.loadedAt === null))
496
+ return { type, state: 'indexing', indexed, note: null };
497
+ // Unit outputs are read after the run list, a few at a time: until the queue drains, more may come.
498
+ if (type === 'transcript' && (this.unitQueue.length > 0 || this.unitWorkers > 0))
499
+ return { type, state: 'indexing', indexed, note: null };
500
+ const failed = sts.find((st) => st.error !== null);
501
+ // A source that failed but still holds an earlier read answers from it, and says so.
502
+ if (failed !== undefined && indexed === 0)
503
+ return { type, state: 'unavailable', indexed, note: failed.error };
504
+ if (failed !== undefined)
505
+ return { type, state: 'ready', indexed, note: `Showing the last read: ${failed.error}` };
506
+ const left = this.index.leftOutOf(type);
507
+ return { type, state: 'ready', indexed, note: left > 0 ? `The ${left} oldest were left out to keep the index in memory.` : null };
508
+ }
509
+ }
510
+ /** Parse `types`: comma-separated; unknown → `null`. */
511
+ export function parseTypes(raw) {
512
+ if (raw === undefined || raw.trim() === '')
513
+ return [...SEARCH_TYPES];
514
+ const out = [];
515
+ for (const t of raw.split(',').map((x) => x.trim()).filter((x) => x !== '')) {
516
+ if (!SEARCH_TYPES.includes(t))
517
+ return null;
518
+ if (!out.includes(t))
519
+ out.push(t);
520
+ }
521
+ return out.length > 0 ? out : null;
522
+ }
523
+ const one = (v) => (Array.isArray(v) ? v[0] : v);
524
+ export function registerSearchRoutes(app, service) {
525
+ // Writes keep the index current: a successful mutating request re-reads what its path can change.
526
+ app.addHook('onResponse', (req, reply, done) => {
527
+ if (reply.statusCode < 400)
528
+ service.noteWrite(req.method, req.url);
529
+ done();
530
+ });
531
+ app.addHook('onClose', async () => { service.close(); });
532
+ app.get(`${API_PREFIX}/search`, { config: { manifest: { responseType: 'SearchResponse', statusCodes: [200, 400] } } }, async (req, reply) => {
533
+ const qs = req.query;
534
+ const q = (one(qs['q']) ?? '').trim();
535
+ if (q.length < MIN_QUERY_CHARS)
536
+ return reply.code(400).send({ error: `\`q\` needs at least ${MIN_QUERY_CHARS} characters` });
537
+ if (q.length > MAX_QUERY_CHARS)
538
+ return reply.code(400).send({ error: `\`q\` is longer than ${MAX_QUERY_CHARS} characters` });
539
+ if (parseQuery(q).terms.join('').length < MIN_QUERY_CHARS)
540
+ return reply.code(400).send({ error: `\`q\` needs at least ${MIN_QUERY_CHARS} characters of words` });
541
+ const types = parseTypes(one(qs['types']));
542
+ if (types === null)
543
+ return reply.code(400).send({ error: `\`types\` must be a comma-separated list of: ${SEARCH_TYPES.join(', ')}` });
544
+ const rawLimit = one(qs['limit']);
545
+ const limit = rawLimit === undefined || rawLimit === '' ? 5 : Number(rawLimit);
546
+ if (!Number.isInteger(limit) || limit < 1 || limit > 50)
547
+ return reply.code(400).send({ error: '`limit` must be an integer from 1 to 50' });
548
+ const cursor = one(qs['cursor']);
549
+ let offset = 0;
550
+ if (cursor !== undefined && cursor !== '') {
551
+ if (types.length !== 1)
552
+ return reply.code(400).send({ error: '`cursor` pages one type: pass exactly one in `types`' });
553
+ offset = Number(cursor);
554
+ if (!Number.isInteger(offset) || offset < 0 || offset > 100_000)
555
+ return reply.code(400).send({ error: '`cursor` is not a cursor this endpoint gave' });
556
+ }
557
+ // A client that goes away (a superseded query) stops the scan.
558
+ const ac = new AbortController();
559
+ const onClose = () => { if (!reply.raw.writableEnded)
560
+ ac.abort(new Error('client closed')); };
561
+ reply.raw.once('close', onClose);
562
+ try {
563
+ return await service.search(q, { types, limit, offset, signal: ac.signal });
564
+ }
565
+ catch (err) {
566
+ // Nobody is listening: hand the (closed) socket back instead of answering it.
567
+ if (ac.signal.aborted) {
568
+ reply.hijack();
569
+ return undefined;
570
+ }
571
+ throw err;
572
+ }
573
+ finally {
574
+ reply.raw.off('close', onClose);
575
+ }
576
+ });
577
+ }
578
+ //# sourceMappingURL=search-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-routes.js","sourceRoot":"","sources":["../../src/api/search-routes.ts"],"names":[],"mappings":"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"}