crbro-memory 1.4.0 → 1.5.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 (43) hide show
  1. package/README.md +49 -8
  2. package/bin/crbro.mjs +109 -0
  3. package/dist/engine/brain.d.ts +3 -0
  4. package/dist/engine/brain.d.ts.map +1 -1
  5. package/dist/engine/brain.js +15 -1
  6. package/dist/engine/brain.js.map +1 -1
  7. package/dist/engine/cortex.d.ts +61 -7
  8. package/dist/engine/cortex.d.ts.map +1 -1
  9. package/dist/engine/cortex.js +168 -23
  10. package/dist/engine/cortex.js.map +1 -1
  11. package/dist/engine/maintenance.d.ts +6 -1
  12. package/dist/engine/maintenance.d.ts.map +1 -1
  13. package/dist/engine/maintenance.js +19 -5
  14. package/dist/engine/maintenance.js.map +1 -1
  15. package/dist/engine/prefrontal.d.ts +13 -2
  16. package/dist/engine/prefrontal.d.ts.map +1 -1
  17. package/dist/engine/prefrontal.js +46 -10
  18. package/dist/engine/prefrontal.js.map +1 -1
  19. package/dist/miner/index.d.ts.map +1 -1
  20. package/dist/miner/index.js +35 -30
  21. package/dist/miner/index.js.map +1 -1
  22. package/dist/search/index.d.ts +46 -6
  23. package/dist/search/index.d.ts.map +1 -1
  24. package/dist/search/index.js +335 -74
  25. package/dist/search/index.js.map +1 -1
  26. package/dist/search/tokenize.d.ts +23 -0
  27. package/dist/search/tokenize.d.ts.map +1 -0
  28. package/dist/search/tokenize.js +83 -0
  29. package/dist/search/tokenize.js.map +1 -0
  30. package/dist/server.d.ts.map +1 -1
  31. package/dist/server.js +125 -14
  32. package/dist/server.js.map +1 -1
  33. package/dist/types/index.d.ts +39 -1
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/utils/fs.d.ts +3 -1
  36. package/dist/utils/fs.d.ts.map +1 -1
  37. package/dist/utils/fs.js +6 -2
  38. package/dist/utils/fs.js.map +1 -1
  39. package/dist/utils/hash.d.ts +20 -0
  40. package/dist/utils/hash.d.ts.map +1 -0
  41. package/dist/utils/hash.js +45 -0
  42. package/dist/utils/hash.js.map +1 -0
  43. package/package.json +53 -53
@@ -1,102 +1,148 @@
1
1
  "use strict";
2
2
  // ─── CRBRO Search Engine ─────────────────────────────────────────
3
- // Hybrid search powered by Orama (text + BM25 + fuzzy)
3
+ // Chunk-level retrieval powered by Orama (BM25) with late interaction.
4
+ //
5
+ // WHY CHUNKS AND NOT WHOLE NEURONS
6
+ // Until v1.4 the whole neuron was indexed as a single document, with every
7
+ // fact concatenated into one field. BM25 normalises term frequency by
8
+ // document length, so on a real brain (median neuron 90 chars, largest
9
+ // 342,302 chars) the most valuable neuron scored near zero for any single
10
+ // term while a 90-char scrap outranked it. The system punished its own best
11
+ // memories: the more you saved about a project, the less findable it became.
12
+ //
13
+ // Now every fact / decision / pattern / preference is its own document, plus
14
+ // one header document per neuron carrying name and tags (which is what keeps
15
+ // search-by-name working). Scoring runs per term and recombines, so a neuron
16
+ // wins by having ONE chunk that covers the query, not by being short.
4
17
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.SearchEngine = void 0;
18
+ exports.SearchEngine = exports.INDEX_VERSION = void 0;
6
19
  const orama_1 = require("@orama/orama");
7
20
  const fs_js_1 = require("../utils/fs.js");
8
- // Orama schema for indexing neurons
21
+ const hash_js_1 = require("../utils/hash.js");
22
+ const tokenize_js_1 = require("./tokenize.js");
23
+ /** Bump when the schema changes so old on-disk indexes are rebuilt, not loaded. */
24
+ exports.INDEX_VERSION = 2;
25
+ /** Weight given to a neuron for each *additional* chunk that matches. */
26
+ const BREADTH_BONUS = 0.05;
27
+ /** Cap on the breadth bonus — breadth is a tiebreaker, never the main signal. */
28
+ const BREADTH_CAP = 0.25;
29
+ /** Exponent on term coverage. >1 punishes chunks that only match one term. */
30
+ const COVERAGE_EXPONENT = 1.5;
31
+ /** Debounce before writing the index to disk after a learn. */
32
+ const PERSIST_DEBOUNCE_MS = 5000;
9
33
  const SCHEMA = {
10
- id: 'string',
34
+ id: 'string', // "<neuron_id>#<hash>" — must be `id` for Orama
35
+ neuron: 'string',
11
36
  name: 'string',
12
- summary: 'string',
13
- facts: 'string',
37
+ text: 'string',
38
+ kind: 'string', // header | fact | decision | pattern | preference
14
39
  domain: 'string',
15
40
  tags: 'string',
41
+ added: 'string',
16
42
  heat: 'number',
17
43
  };
18
44
  class SearchEngine {
19
45
  brain;
20
46
  db = null;
47
+ docCount = 0;
48
+ dirty = false;
49
+ persistTimer = null;
21
50
  constructor(brain) {
22
51
  this.brain = brain;
23
52
  }
53
+ // ─── Lifecycle ─────────────────────────────────────────────────
24
54
  /**
25
- * Initialize or restore the search index.
55
+ * Load the index from disk, or rebuild it if missing / stale / corrupt.
56
+ *
57
+ * Version check matters: Orama's `load()` does NOT throw when the stored
58
+ * schema differs — it silently overwrites the live schema with the old one,
59
+ * so the try/catch never fires and every later search fails with
60
+ * `Invalid property name`, permanently, on every boot. Reading the version
61
+ * ourselves is the only reliable guard.
26
62
  */
27
63
  async init() {
28
- const indexPath = this.brain.paths.searchIndex();
29
- const indexExists = await (0, fs_js_1.fileExists)(indexPath);
30
- if (indexExists) {
64
+ const indexPath = this.brain.paths.chunksIndex();
65
+ if (await (0, fs_js_1.fileExists)(indexPath)) {
31
66
  try {
32
- const savedData = await (0, fs_js_1.readJSON)(indexPath);
33
- if (savedData) {
34
- // Create a fresh db then load data into it
67
+ const stored = await (0, fs_js_1.readJSON)(indexPath);
68
+ if (stored && stored.v === exports.INDEX_VERSION && stored.data) {
35
69
  this.db = (0, orama_1.create)({ schema: SCHEMA });
36
- (0, orama_1.load)(this.db, savedData);
70
+ (0, orama_1.load)(this.db, stored.data);
71
+ this.docCount = this.countDocs(stored.data);
37
72
  return;
38
73
  }
39
74
  }
40
75
  catch {
41
- // Index corrupted — rebuild
76
+ // Corruptedfall through to rebuild.
42
77
  }
43
78
  }
44
- // Create fresh index
45
79
  await this.rebuild();
46
80
  }
47
81
  /**
48
- * Rebuild the entire search index from cortex files.
82
+ * Rebuild the whole index from the cortex.
83
+ * One bad neuron must not take the server down with it, so every neuron
84
+ * is isolated: CRBRO is published and other people's brains are not ours
85
+ * to assume well-formed.
49
86
  */
50
87
  async rebuild() {
51
88
  this.db = (0, orama_1.create)({ schema: SCHEMA });
89
+ this.docCount = 0;
52
90
  const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
53
- let indexed = 0;
54
91
  for (const id of ids) {
55
- const neuron = await (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
56
- if (!neuron)
57
- continue;
58
- await (0, orama_1.insert)(this.db, {
59
- id: neuron.id,
60
- name: neuron.name,
61
- summary: neuron.summary,
62
- facts: neuron.facts.map(f => f.text).join(' | '),
63
- domain: neuron.domain,
64
- tags: neuron.tags.join(' '),
65
- heat: neuron.heat,
66
- });
67
- indexed++;
92
+ try {
93
+ const neuron = await (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
94
+ if (!neuron)
95
+ continue;
96
+ await this.insertNeuronChunks(neuron);
97
+ }
98
+ catch {
99
+ // Skip unreadable neuron, keep going.
100
+ }
68
101
  }
69
- // Save index to disk
70
102
  await this.persist();
71
- return indexed;
103
+ await this.dropLegacyIndex();
104
+ return this.docCount;
72
105
  }
73
106
  /**
74
- * Index a single neuron (for real-time updates).
107
+ * Re-index a single neuron: drop its old chunks, insert the current ones.
75
108
  */
76
109
  async indexNeuron(neuron) {
77
110
  if (!this.db)
78
111
  await this.init();
79
112
  if (!this.db)
80
113
  return;
81
- // Remove existing entry if present (ignore errors)
82
- try {
83
- await (0, orama_1.remove)(this.db, neuron.id);
114
+ await this.removeNeuronChunks(neuron.id);
115
+ await this.insertNeuronChunks(neuron);
116
+ this.markDirty();
117
+ }
118
+ /** Write the index to disk now. */
119
+ async persist() {
120
+ if (!this.db)
121
+ return;
122
+ if (this.persistTimer) {
123
+ clearTimeout(this.persistTimer);
124
+ this.persistTimer = null;
84
125
  }
85
- catch {
86
- // Not found fine
87
- }
88
- await (0, orama_1.insert)(this.db, {
89
- id: neuron.id,
90
- name: neuron.name,
91
- summary: neuron.summary,
92
- facts: neuron.facts.map(f => f.text).join(' | '),
93
- domain: neuron.domain,
94
- tags: neuron.tags.join(' '),
95
- heat: neuron.heat,
96
- });
126
+ const payload = { v: exports.INDEX_VERSION, data: (0, orama_1.save)(this.db) };
127
+ // Not pretty-printed: this file reaches tens of MB and indentation costs
128
+ // ~25% of both size and write time for something no human reads.
129
+ await (0, fs_js_1.writeJSON)(this.brain.paths.chunksIndex(), payload, { pretty: false });
130
+ this.dirty = false;
97
131
  }
132
+ /** Flush if there are unsaved changes. Called on consolidate/shutdown. */
133
+ async flush() {
134
+ if (this.dirty)
135
+ await this.persist();
136
+ }
137
+ // ─── Search ────────────────────────────────────────────────────
98
138
  /**
99
- * Search for neurons matching a query.
139
+ * Find neurons matching a query.
140
+ *
141
+ * Late interaction: each query term is searched separately and its scores
142
+ * normalised against the best score for that term, then a chunk's score is
143
+ * the sum of its normalised hits weighted by how much of the query it
144
+ * covers. This is what stops one very common term from deciding the ranking
145
+ * and what makes a chunk matching five of six terms beat a scrap matching one.
100
146
  */
101
147
  async search(query, options) {
102
148
  if (!this.db)
@@ -104,36 +150,251 @@ class SearchEngine {
104
150
  if (!this.db)
105
151
  return [];
106
152
  const limit = options?.limit || 10;
107
- const searchParams = {
108
- term: query,
109
- properties: ['name', 'summary', 'facts', 'tags'],
110
- boost: { name: 3, summary: 2, facts: 1, tags: 1 },
111
- limit,
112
- tolerance: 2,
113
- };
114
- // Domain filter
115
- if (options?.domain) {
116
- searchParams.where = { domain: { eq: options.domain } };
117
- }
118
- const results = await (0, orama_1.search)(this.db, searchParams);
119
- return results.hits.map((hit) => ({
120
- neuron_id: hit.document.id,
121
- name: hit.document.name,
122
- domain: hit.document.domain,
123
- relevance_score: Math.round(hit.score * 1000) / 1000,
124
- matching_content: hit.document.summary || hit.document.facts?.substring(0, 200) || '',
125
- heat: hit.document.heat || 0,
126
- }));
153
+ const terms = (0, tokenize_js_1.queryTerms)(query);
154
+ if (terms.length === 0)
155
+ return [];
156
+ const perChunk = new Map();
157
+ for (const term of terms) {
158
+ const hits = await this.searchTerm(term, options?.domain);
159
+ if (hits.length === 0)
160
+ continue;
161
+ const best = hits[0].score || 1;
162
+ for (const hit of hits) {
163
+ const doc = hit.document;
164
+ const key = doc.id;
165
+ const normalised = best > 0 ? hit.score / best : 0;
166
+ const existing = perChunk.get(key);
167
+ if (existing) {
168
+ existing.score += normalised;
169
+ existing.matched += 1;
170
+ }
171
+ else {
172
+ perChunk.set(key, {
173
+ neuron: doc.neuron,
174
+ name: doc.name,
175
+ domain: doc.domain,
176
+ text: doc.text,
177
+ kind: doc.kind,
178
+ added: doc.added,
179
+ heat: doc.heat || 0,
180
+ score: normalised,
181
+ matched: 1,
182
+ });
183
+ }
184
+ }
185
+ }
186
+ if (perChunk.size === 0)
187
+ return [];
188
+ // Coverage weighting, then collapse chunks into their neurons.
189
+ const byNeuron = new Map();
190
+ for (const chunk of perChunk.values()) {
191
+ const coverage = chunk.matched / terms.length;
192
+ chunk.score = chunk.score * Math.pow(coverage, COVERAGE_EXPONENT);
193
+ const current = byNeuron.get(chunk.neuron);
194
+ if (!current) {
195
+ byNeuron.set(chunk.neuron, { best: chunk, extra: 0 });
196
+ }
197
+ else if (chunk.score > current.best.score) {
198
+ byNeuron.set(chunk.neuron, { best: chunk, extra: current.extra + 1 });
199
+ }
200
+ else {
201
+ current.extra += 1;
202
+ }
203
+ }
204
+ const results = [];
205
+ for (const { best, extra } of byNeuron.values()) {
206
+ const breadth = Math.min(extra * BREADTH_BONUS, BREADTH_CAP);
207
+ results.push({
208
+ neuron_id: best.neuron,
209
+ name: best.name,
210
+ domain: best.domain,
211
+ relevance_score: Math.round((best.score + breadth) * 1000) / 1000,
212
+ matching_content: best.text,
213
+ matched_kind: best.kind,
214
+ matched_added: best.added || '',
215
+ heat: best.heat,
216
+ });
217
+ }
218
+ results.sort((a, b) => b.relevance_score - a.relevance_score);
219
+ return results.slice(0, limit);
127
220
  }
221
+ // ─── Internals ─────────────────────────────────────────────────
128
222
  /**
129
- * Persist the search index to disk.
223
+ * Search one term. Exact first; only if a reasonably long term finds
224
+ * nothing do we allow a single edit of slack, which covers typos without
225
+ * the indiscriminate noise of the old `tolerance: 2` (measured: it matched
226
+ * 1,166 of 1,183 documents, i.e. the ranking was noise).
130
227
  */
131
- async persist() {
228
+ async searchTerm(term, domain) {
229
+ const run = async (tolerance) => {
230
+ const params = {
231
+ term,
232
+ properties: ['text', 'name', 'tags'],
233
+ boost: { name: 2, text: 1, tags: 1 },
234
+ limit: Math.max(this.docCount, 10),
235
+ tolerance,
236
+ };
237
+ if (domain)
238
+ params.where = { domain: { eq: domain } };
239
+ const res = await (0, orama_1.search)(this.db, params);
240
+ return res.hits;
241
+ };
242
+ let hits = await run(0);
243
+ if (hits.length === 0 && term.length >= 5) {
244
+ hits = await run(1);
245
+ }
246
+ return hits;
247
+ }
248
+ /** Build and insert every chunk of a neuron. */
249
+ async insertNeuronChunks(neuron) {
132
250
  if (!this.db)
133
251
  return;
134
- const data = (0, orama_1.save)(this.db);
135
- await (0, fs_js_1.writeJSON)(this.brain.paths.searchIndex(), data);
252
+ const tags = Array.isArray(neuron.tags) ? neuron.tags.join(' ') : '';
253
+ const base = {
254
+ neuron: neuron.id,
255
+ name: neuron.name || neuron.id,
256
+ domain: neuron.domain || 'general',
257
+ tags,
258
+ heat: typeof neuron.heat === 'number' ? neuron.heat : 0,
259
+ };
260
+ // Header chunk — carries name, summary and tags. This is what preserves
261
+ // search-by-name, which is the one thing that worked before.
262
+ const headerText = [neuron.name, neuron.summary, tags]
263
+ .filter(Boolean)
264
+ .join(' — ');
265
+ await this.put({
266
+ ...base,
267
+ id: (0, hash_js_1.chunkId)(neuron.id, `header:${headerText}`),
268
+ text: headerText,
269
+ kind: 'header',
270
+ added: neuron.created || '',
271
+ });
272
+ for (const fact of neuron.facts || []) {
273
+ if (!fact || !fact.text)
274
+ continue;
275
+ if (isRetired(fact))
276
+ continue;
277
+ await this.put({
278
+ ...base,
279
+ id: (0, hash_js_1.chunkId)(neuron.id, fact.text),
280
+ text: fact.text,
281
+ kind: 'fact',
282
+ added: fact.added || '',
283
+ });
284
+ }
285
+ for (const decision of neuron.decisions || []) {
286
+ if (!decision || !decision.text)
287
+ continue;
288
+ const text = decision.rationale
289
+ ? `${decision.text} — ${decision.rationale}`
290
+ : decision.text;
291
+ await this.put({
292
+ ...base,
293
+ id: (0, hash_js_1.chunkId)(neuron.id, text),
294
+ text,
295
+ kind: 'decision',
296
+ added: decision.date || '',
297
+ });
298
+ }
299
+ for (const pattern of neuron.patterns || []) {
300
+ if (!pattern)
301
+ continue;
302
+ await this.put({
303
+ ...base,
304
+ id: (0, hash_js_1.chunkId)(neuron.id, pattern),
305
+ text: pattern,
306
+ kind: 'pattern',
307
+ added: '',
308
+ });
309
+ }
310
+ for (const pref of neuron.preferences || []) {
311
+ if (!pref)
312
+ continue;
313
+ await this.put({
314
+ ...base,
315
+ id: (0, hash_js_1.chunkId)(neuron.id, pref),
316
+ text: pref,
317
+ kind: 'preference',
318
+ added: '',
319
+ });
320
+ }
321
+ }
322
+ async put(doc) {
323
+ try {
324
+ await (0, orama_1.insert)(this.db, doc);
325
+ this.docCount++;
326
+ }
327
+ catch {
328
+ // Duplicate id (identical text twice in one neuron) — nothing to add.
329
+ }
330
+ }
331
+ /** Drop every chunk belonging to a neuron. */
332
+ async removeNeuronChunks(neuronId) {
333
+ if (!this.db)
334
+ return;
335
+ try {
336
+ const res = await (0, orama_1.search)(this.db, {
337
+ term: '',
338
+ where: { neuron: { eq: neuronId } },
339
+ limit: 10000,
340
+ });
341
+ for (const hit of res.hits) {
342
+ try {
343
+ await (0, orama_1.remove)(this.db, hit.document.id);
344
+ this.docCount = Math.max(0, this.docCount - 1);
345
+ }
346
+ catch {
347
+ // Already gone.
348
+ }
349
+ }
350
+ }
351
+ catch {
352
+ // `where` on a non-filterable field, or empty index — ignore.
353
+ }
354
+ }
355
+ markDirty() {
356
+ this.dirty = true;
357
+ if (this.persistTimer)
358
+ clearTimeout(this.persistTimer);
359
+ this.persistTimer = setTimeout(() => {
360
+ this.persistTimer = null;
361
+ void this.persist().catch(() => { });
362
+ }, PERSIST_DEBOUNCE_MS);
363
+ // Never hold the process open just to flush the index.
364
+ if (typeof this.persistTimer.unref === 'function')
365
+ this.persistTimer.unref();
366
+ }
367
+ countDocs(data) {
368
+ try {
369
+ const store = data?.internalDocumentIDStore?.internalIdToId;
370
+ if (Array.isArray(store))
371
+ return store.length;
372
+ const docs = data?.docs?.docs;
373
+ if (docs)
374
+ return Object.keys(docs).length;
375
+ }
376
+ catch {
377
+ // Unknown shape — a floor of 0 only affects the per-term limit.
378
+ }
379
+ return 0;
380
+ }
381
+ /**
382
+ * Remove the pre-v2 index once a rebuild has succeeded. It is dead weight
383
+ * (25 MB on the reference brain) and nothing reads it any more. Downgrading
384
+ * to an older CRBRO simply finds no index and rebuilds its own.
385
+ */
386
+ async dropLegacyIndex() {
387
+ try {
388
+ await (0, fs_js_1.deleteJSON)(this.brain.paths.searchIndex());
389
+ }
390
+ catch {
391
+ // Best effort.
392
+ }
136
393
  }
137
394
  }
138
395
  exports.SearchEngine = SearchEngine;
396
+ /** A fact that has been superseded or retracted must not surface in recall. */
397
+ function isRetired(fact) {
398
+ return fact.status === 'superseded' || fact.status === 'retracted';
399
+ }
139
400
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Words that carry no retrieval signal. Kept short on purpose: an
3
+ * over-eager stoplist silently deletes terms the user meant.
4
+ */
5
+ declare const STOPWORDS: Set<string>;
6
+ /**
7
+ * Fold accents so "participación" and "participacion" are the same term.
8
+ * Keeps ñ as n — Spanish users type it both ways.
9
+ */
10
+ export declare function fold(text: string): string;
11
+ /**
12
+ * Split text into terms. Keeps underscores and digits together so
13
+ * identifiers survive intact ("ocultar_de_lista", "wp_wppc_entries", "6698").
14
+ */
15
+ export declare function tokenize(text: string): string[];
16
+ /**
17
+ * Tokenize a search query: drop stopwords and 1-char noise, dedupe,
18
+ * and keep the original order. If everything was a stopword, fall back
19
+ * to the raw tokens — an empty term list would return nothing at all.
20
+ */
21
+ export declare function queryTerms(query: string): string[];
22
+ export { STOPWORDS };
23
+ //# sourceMappingURL=tokenize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenize.d.ts","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,QAAA,MAAM,SAAS,aAcb,CAAC;AAEH;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAI/C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBlD;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ // ─── CRBRO Query Tokenizer ───────────────────────────────────────
3
+ // Splits a query into meaningful terms. Spanish-first, English-aware.
4
+ //
5
+ // Deliberately NO stemming. Orama applies its stemmer *before* stripping
6
+ // diacritics, so a Spanish stemmer mangles the very common "-ción" family
7
+ // (información, configuración, aplicación, integración). Measured on the
8
+ // reference brain: 24% of facts contain a "-ción" word and they retrieve
9
+ // correctly today. Ablation also showed removing the stemmer *raises* MRR.
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.STOPWORDS = void 0;
12
+ exports.fold = fold;
13
+ exports.tokenize = tokenize;
14
+ exports.queryTerms = queryTerms;
15
+ /**
16
+ * Words that carry no retrieval signal. Kept short on purpose: an
17
+ * over-eager stoplist silently deletes terms the user meant.
18
+ */
19
+ const STOPWORDS = new Set([
20
+ // Spanish
21
+ 'a', 'al', 'algo', 'ante', 'aqui', 'asi', 'con', 'como', 'cual', 'cuando',
22
+ 'de', 'del', 'desde', 'donde', 'dos', 'el', 'ella', 'ellos', 'en', 'entre',
23
+ 'era', 'es', 'esa', 'ese', 'eso', 'esta', 'este', 'esto', 'estos', 'fue',
24
+ 'ha', 'hay', 'la', 'las', 'le', 'les', 'lo', 'los', 'mas', 'me', 'mi', 'muy',
25
+ 'ni', 'no', 'nos', 'o', 'para', 'pero', 'por', 'que', 'se', 'ser', 'si',
26
+ 'sin', 'sobre', 'su', 'sus', 'tan', 'te', 'tiene', 'todo', 'tu', 'un', 'una',
27
+ 'uno', 'unos', 'unas', 'y', 'ya',
28
+ // English
29
+ 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'but', 'by', 'for', 'from', 'has',
30
+ 'have', 'how', 'in', 'is', 'it', 'its', 'of', 'on', 'or', 'that', 'the',
31
+ 'their', 'then', 'there', 'these', 'this', 'to', 'was', 'were', 'what',
32
+ 'when', 'where', 'which', 'who', 'why', 'with',
33
+ ]);
34
+ exports.STOPWORDS = STOPWORDS;
35
+ /**
36
+ * Fold accents so "participación" and "participacion" are the same term.
37
+ * Keeps ñ as n — Spanish users type it both ways.
38
+ */
39
+ function fold(text) {
40
+ return text
41
+ .normalize('NFD')
42
+ .replace(/[̀-ͯ]/g, '')
43
+ .toLowerCase();
44
+ }
45
+ /**
46
+ * Split text into terms. Keeps underscores and digits together so
47
+ * identifiers survive intact ("ocultar_de_lista", "wp_wppc_entries", "6698").
48
+ */
49
+ function tokenize(text) {
50
+ return fold(text)
51
+ .split(/[^a-z0-9_]+/)
52
+ .filter(Boolean);
53
+ }
54
+ /**
55
+ * Tokenize a search query: drop stopwords and 1-char noise, dedupe,
56
+ * and keep the original order. If everything was a stopword, fall back
57
+ * to the raw tokens — an empty term list would return nothing at all.
58
+ */
59
+ function queryTerms(query) {
60
+ const raw = tokenize(query);
61
+ const kept = [];
62
+ const seen = new Set();
63
+ for (const t of raw) {
64
+ if (t.length < 2)
65
+ continue;
66
+ if (STOPWORDS.has(t))
67
+ continue;
68
+ if (seen.has(t))
69
+ continue;
70
+ seen.add(t);
71
+ kept.push(t);
72
+ }
73
+ if (kept.length > 0)
74
+ return kept;
75
+ // Everything filtered out — use whatever we had, deduped.
76
+ const fallback = [];
77
+ for (const t of raw) {
78
+ if (!fallback.includes(t))
79
+ fallback.push(t);
80
+ }
81
+ return fallback;
82
+ }
83
+ //# sourceMappingURL=tokenize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":";AAAA,oEAAoE;AACpE,sEAAsE;AACtE,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;;;AA0B3E,oBAKC;AAMD,4BAIC;AAOD,gCAqBC;AAnED;;;GAGG;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,UAAU;IACV,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ;IACzE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO;IAC1E,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;IACxE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;IAC5E,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;IACvE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;IAC5E,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI;IAChC,UAAU;IACV,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;IAC5E,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK;IACvE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;IACtE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM;CAC/C,CAAC,CAAC;AAmDM,8BAAS;AAjDlB;;;GAGG;AACH,SAAgB,IAAI,CAAC,IAAY;IAC/B,OAAO,IAAI;SACR,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAgB,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC;SACd,KAAK,CAAC,aAAa,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,KAAa;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC3B,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAS;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAS;QAC1B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACZ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjC,0DAA0D;IAC1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,wBAAgB,YAAY,IAAI,SAAS,CA4lBxC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,wBAAgB,YAAY,IAAI,SAAS,CA2tBxC"}