mindlore 0.6.2 → 0.6.3

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 (122) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +3 -3
  3. package/dist/scripts/cc-session-sync.d.ts +1 -0
  4. package/dist/scripts/cc-session-sync.d.ts.map +1 -1
  5. package/dist/scripts/cc-session-sync.js +3 -2
  6. package/dist/scripts/cc-session-sync.js.map +1 -1
  7. package/dist/scripts/fetch-raw.js +96 -7
  8. package/dist/scripts/fetch-raw.js.map +1 -1
  9. package/dist/scripts/init.js +6 -25
  10. package/dist/scripts/init.js.map +1 -1
  11. package/dist/scripts/lib/chunker.d.ts +12 -0
  12. package/dist/scripts/lib/chunker.d.ts.map +1 -0
  13. package/dist/scripts/lib/chunker.js +94 -0
  14. package/dist/scripts/lib/chunker.js.map +1 -0
  15. package/dist/scripts/lib/fuzzy.d.ts +10 -0
  16. package/dist/scripts/lib/fuzzy.d.ts.map +1 -0
  17. package/dist/scripts/lib/fuzzy.js +88 -0
  18. package/dist/scripts/lib/fuzzy.js.map +1 -0
  19. package/dist/scripts/lib/hybrid-search.d.ts +1 -0
  20. package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
  21. package/dist/scripts/lib/hybrid-search.js.map +1 -1
  22. package/dist/scripts/lib/merge-defaults.d.ts +5 -0
  23. package/dist/scripts/lib/merge-defaults.d.ts.map +1 -0
  24. package/dist/scripts/lib/merge-defaults.js +25 -0
  25. package/dist/scripts/lib/merge-defaults.js.map +1 -0
  26. package/dist/scripts/lib/migrations-v063.d.ts +7 -0
  27. package/dist/scripts/lib/migrations-v063.d.ts.map +1 -0
  28. package/dist/scripts/lib/migrations-v063.js +58 -0
  29. package/dist/scripts/lib/migrations-v063.js.map +1 -0
  30. package/dist/scripts/lib/proximity.d.ts +3 -0
  31. package/dist/scripts/lib/proximity.d.ts.map +1 -0
  32. package/dist/scripts/lib/proximity.js +53 -0
  33. package/dist/scripts/lib/proximity.js.map +1 -0
  34. package/dist/scripts/lib/rrf.d.ts +23 -0
  35. package/dist/scripts/lib/rrf.d.ts.map +1 -0
  36. package/dist/scripts/lib/rrf.js +63 -0
  37. package/dist/scripts/lib/rrf.js.map +1 -0
  38. package/dist/scripts/lib/search-cache.d.ts +20 -0
  39. package/dist/scripts/lib/search-cache.d.ts.map +1 -0
  40. package/dist/scripts/lib/search-cache.js +60 -0
  41. package/dist/scripts/lib/search-cache.js.map +1 -0
  42. package/dist/scripts/lib/search-engine.d.ts +22 -0
  43. package/dist/scripts/lib/search-engine.d.ts.map +1 -0
  44. package/dist/scripts/lib/search-engine.js +105 -0
  45. package/dist/scripts/lib/search-engine.js.map +1 -0
  46. package/dist/scripts/lib/session-payload.d.ts +2 -4
  47. package/dist/scripts/lib/session-payload.d.ts.map +1 -1
  48. package/dist/scripts/lib/session-payload.js +31 -43
  49. package/dist/scripts/lib/session-payload.js.map +1 -1
  50. package/dist/scripts/lib/snippet.d.ts +2 -0
  51. package/dist/scripts/lib/snippet.d.ts.map +1 -0
  52. package/dist/scripts/lib/snippet.js +32 -0
  53. package/dist/scripts/lib/snippet.js.map +1 -0
  54. package/dist/scripts/mindlore-fts5-index.js +44 -3
  55. package/dist/scripts/mindlore-fts5-index.js.map +1 -1
  56. package/dist/scripts/mindlore-fts5-search.d.ts +3 -5
  57. package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -1
  58. package/dist/scripts/mindlore-fts5-search.js +41 -116
  59. package/dist/scripts/mindlore-fts5-search.js.map +1 -1
  60. package/dist/tests/chunker.test.d.ts +2 -0
  61. package/dist/tests/chunker.test.d.ts.map +1 -0
  62. package/dist/tests/chunker.test.js +40 -0
  63. package/dist/tests/chunker.test.js.map +1 -0
  64. package/dist/tests/chunks-migration.test.d.ts +2 -0
  65. package/dist/tests/chunks-migration.test.d.ts.map +1 -0
  66. package/dist/tests/chunks-migration.test.js +55 -0
  67. package/dist/tests/chunks-migration.test.js.map +1 -0
  68. package/dist/tests/compaction-snapshot.test.js +47 -0
  69. package/dist/tests/compaction-snapshot.test.js.map +1 -1
  70. package/dist/tests/daemon-integration.test.js +5 -5
  71. package/dist/tests/daemon-integration.test.js.map +1 -1
  72. package/dist/tests/fuzzy.test.d.ts +2 -0
  73. package/dist/tests/fuzzy.test.d.ts.map +1 -0
  74. package/dist/tests/fuzzy.test.js +70 -0
  75. package/dist/tests/fuzzy.test.js.map +1 -0
  76. package/dist/tests/helpers/db.d.ts.map +1 -1
  77. package/dist/tests/helpers/db.js +2 -1
  78. package/dist/tests/helpers/db.js.map +1 -1
  79. package/dist/tests/merge-defaults.test.d.ts +2 -0
  80. package/dist/tests/merge-defaults.test.d.ts.map +1 -0
  81. package/dist/tests/merge-defaults.test.js +35 -0
  82. package/dist/tests/merge-defaults.test.js.map +1 -0
  83. package/dist/tests/migrations-v063.test.d.ts +2 -0
  84. package/dist/tests/migrations-v063.test.d.ts.map +1 -0
  85. package/dist/tests/migrations-v063.test.js +84 -0
  86. package/dist/tests/migrations-v063.test.js.map +1 -0
  87. package/dist/tests/proximity.test.d.ts +2 -0
  88. package/dist/tests/proximity.test.d.ts.map +1 -0
  89. package/dist/tests/proximity.test.js +31 -0
  90. package/dist/tests/proximity.test.js.map +1 -0
  91. package/dist/tests/rrf.test.d.ts +2 -0
  92. package/dist/tests/rrf.test.d.ts.map +1 -0
  93. package/dist/tests/rrf.test.js +100 -0
  94. package/dist/tests/rrf.test.js.map +1 -0
  95. package/dist/tests/search-cache.test.d.ts +2 -0
  96. package/dist/tests/search-cache.test.d.ts.map +1 -0
  97. package/dist/tests/search-cache.test.js +95 -0
  98. package/dist/tests/search-cache.test.js.map +1 -0
  99. package/dist/tests/search-engine.test.d.ts +2 -0
  100. package/dist/tests/search-engine.test.d.ts.map +1 -0
  101. package/dist/tests/search-engine.test.js +125 -0
  102. package/dist/tests/search-engine.test.js.map +1 -0
  103. package/dist/tests/search-hook.test.js +3 -3
  104. package/dist/tests/search-hook.test.js.map +1 -1
  105. package/dist/tests/session-payload.test.d.ts +1 -1
  106. package/dist/tests/session-payload.test.js +1 -14
  107. package/dist/tests/session-payload.test.js.map +1 -1
  108. package/dist/tests/session-summary.test.js +40 -4
  109. package/dist/tests/session-summary.test.js.map +1 -1
  110. package/dist/tests/snippet.test.d.ts +2 -0
  111. package/dist/tests/snippet.test.d.ts.map +1 -0
  112. package/dist/tests/snippet.test.js +30 -0
  113. package/dist/tests/snippet.test.js.map +1 -0
  114. package/hooks/lib/mindlore-common.cjs +56 -3
  115. package/hooks/mindlore-index.cjs +6 -0
  116. package/hooks/mindlore-pre-compact.cjs +61 -52
  117. package/hooks/mindlore-search.cjs +90 -214
  118. package/hooks/mindlore-session-end.cjs +9 -15
  119. package/hooks/mindlore-session-focus.cjs +11 -26
  120. package/package.json +2 -2
  121. package/plugin.json +1 -1
  122. package/templates/config.json +1 -1
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const merge_defaults_js_1 = require("../scripts/lib/merge-defaults.js");
4
+ describe('mergeDefaults', () => {
5
+ test('shallow merge — fills missing keys', () => {
6
+ const { result, changed } = (0, merge_defaults_js_1.mergeDefaults)({ a: 1 }, { a: 99, b: 2 });
7
+ expect(result).toEqual({ a: 1, b: 2 });
8
+ expect(changed).toBe(true);
9
+ });
10
+ test('deep merge — fills nested missing keys', () => {
11
+ const { result, changed } = (0, merge_defaults_js_1.mergeDefaults)({ x: { a: 1 } }, { x: { a: 99, b: 2 } });
12
+ expect(result).toEqual({ x: { a: 1, b: 2 } });
13
+ expect(changed).toBe(true);
14
+ });
15
+ test('does not overwrite existing values', () => {
16
+ const { result, changed } = (0, merge_defaults_js_1.mergeDefaults)({ a: 1, b: 2 }, { a: 99, b: 88 });
17
+ expect(result).toEqual({ a: 1, b: 2 });
18
+ expect(changed).toBe(false);
19
+ });
20
+ test('fills null/undefined with defaults', () => {
21
+ const { result, changed } = (0, merge_defaults_js_1.mergeDefaults)({ a: null, b: undefined }, { a: 1, b: 2 });
22
+ expect(result).toEqual({ a: 1, b: 2 });
23
+ expect(changed).toBe(true);
24
+ });
25
+ test('does not merge arrays — replaces', () => {
26
+ const { result } = (0, merge_defaults_js_1.mergeDefaults)({ a: [1, 2] }, { a: [3, 4] });
27
+ expect(result).toEqual({ a: [1, 2] });
28
+ });
29
+ test('no changes returns changed=false', () => {
30
+ const { result, changed } = (0, merge_defaults_js_1.mergeDefaults)({ a: 1 }, { a: 2 });
31
+ expect(result).toEqual({ a: 1 });
32
+ expect(changed).toBe(false);
33
+ });
34
+ });
35
+ //# sourceMappingURL=merge-defaults.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-defaults.test.js","sourceRoot":"","sources":["../../tests/merge-defaults.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=migrations-v063.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-v063.test.d.ts","sourceRoot":"","sources":["../../tests/migrations-v063.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const db_js_1 = require("./helpers/db.js");
10
+ const schema_version_js_1 = require("../scripts/lib/schema-version.js");
11
+ const migrations_js_1 = require("../scripts/lib/migrations.js");
12
+ const migrations_v051_js_1 = require("../scripts/lib/migrations-v051.js");
13
+ const migrations_v052_js_1 = require("../scripts/lib/migrations-v052.js");
14
+ const migrations_v053_js_1 = require("../scripts/lib/migrations-v053.js");
15
+ const migrations_v062_js_1 = require("../scripts/lib/migrations-v062.js");
16
+ const migrations_v063_js_1 = require("../scripts/lib/migrations-v063.js");
17
+ function makeTmpDir() {
18
+ return fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-mig063-'));
19
+ }
20
+ function cleanup(dir, db) {
21
+ try {
22
+ db?.close();
23
+ }
24
+ catch { }
25
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
26
+ }
27
+ /* eslint-disable @typescript-eslint/no-unsafe-type-assertion */
28
+ describe('v0.6.3 migrations', () => {
29
+ test('migration creates trigram table', () => {
30
+ const dir = makeTmpDir();
31
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
32
+ const tables = db.prepare("SELECT name FROM sqlite_master").all();
33
+ const names = tables.map(t => t.name);
34
+ expect(names).toContain('mindlore_fts_trigram');
35
+ cleanup(dir, db);
36
+ });
37
+ test('migration creates vocabulary table', () => {
38
+ const dir = makeTmpDir();
39
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
40
+ const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all();
41
+ const names = tables.map(t => t.name);
42
+ expect(names).toContain('vocabulary');
43
+ cleanup(dir, db);
44
+ });
45
+ test('trigram table copies existing porter data on migration', () => {
46
+ const dir = makeTmpDir();
47
+ const dbPath = path_1.default.join(dir, 'mindlore.db');
48
+ const db = (0, db_js_1.createTestDbWithEpisodes)(dbPath);
49
+ (0, db_js_1.insertFts)(db, {
50
+ path: '/test/doc.md',
51
+ slug: 'test-doc',
52
+ description: 'Test document',
53
+ type: 'source',
54
+ category: 'sources',
55
+ title: 'Test Doc',
56
+ content: 'Some content here',
57
+ tags: 'test',
58
+ });
59
+ const porterBefore = db.prepare('SELECT COUNT(*) as c FROM mindlore_fts').get().c;
60
+ expect(porterBefore).toBe(1);
61
+ (0, schema_version_js_1.ensureSchemaTable)(db);
62
+ (0, schema_version_js_1.runMigrations)(db, [...migrations_js_1.V050_MIGRATIONS, ...migrations_v051_js_1.V051_MIGRATIONS, ...migrations_v052_js_1.V052_MIGRATIONS, ...migrations_v053_js_1.V053_MIGRATIONS, ...migrations_v062_js_1.V062_MIGRATIONS, ...migrations_v063_js_1.V063_MIGRATIONS]);
63
+ const trigramCount = db.prepare('SELECT COUNT(*) as c FROM mindlore_fts_trigram').get().c;
64
+ expect(trigramCount).toBe(1);
65
+ cleanup(dir, db);
66
+ });
67
+ test('schema version is 12 after migration', () => {
68
+ const dir = makeTmpDir();
69
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
70
+ const row = db.prepare('SELECT MAX(version) as v FROM schema_versions').get();
71
+ expect(row.v).toBe(13);
72
+ cleanup(dir, db);
73
+ });
74
+ test('vocabulary table accepts inserts and dedup', () => {
75
+ const dir = makeTmpDir();
76
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
77
+ db.prepare('INSERT INTO vocabulary (word) VALUES (?)').run('typescript');
78
+ db.prepare('INSERT OR IGNORE INTO vocabulary (word) VALUES (?)').run('typescript');
79
+ const count = db.prepare('SELECT COUNT(*) as c FROM vocabulary').get().c;
80
+ expect(count).toBe(1);
81
+ cleanup(dir, db);
82
+ });
83
+ });
84
+ //# sourceMappingURL=migrations-v063.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-v063.test.js","sourceRoot":"","sources":["../../tests/migrations-v063.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proximity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proximity.test.d.ts","sourceRoot":"","sources":["../../tests/proximity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const proximity_js_1 = require("../scripts/lib/proximity.js");
4
+ test('boosts results where terms are adjacent', () => {
5
+ const results = [
6
+ { slug: 'a', path: '/a', title: '', description: '', category: '', tags: '', score: 1.0, content: 'TypeScript hooks are powerful tools' },
7
+ { slug: 'b', path: '/b', title: '', description: '', category: '', tags: '', score: 1.0, content: 'TypeScript is great. Much later: hooks pattern' },
8
+ ];
9
+ const reranked = (0, proximity_js_1.rerankByProximity)(results, ['typescript', 'hooks']);
10
+ expect(reranked[0].slug).toBe('a');
11
+ });
12
+ test('single term query — no reranking', () => {
13
+ const results = [
14
+ { slug: 'a', path: '/a', title: '', description: '', category: '', tags: '', score: 2.0, content: 'x' },
15
+ { slug: 'b', path: '/b', title: '', description: '', category: '', tags: '', score: 1.0, content: 'y' },
16
+ ];
17
+ const reranked = (0, proximity_js_1.rerankByProximity)(results, ['single']);
18
+ expect(reranked[0].slug).toBe('a');
19
+ });
20
+ test('empty results returns empty', () => {
21
+ expect((0, proximity_js_1.rerankByProximity)([], ['a', 'b'])).toEqual([]);
22
+ });
23
+ test('missing content treated as no match', () => {
24
+ const results = [
25
+ { slug: 'a', path: '/a', title: '', description: '', category: '', tags: '', score: 1.0 },
26
+ ];
27
+ const reranked = (0, proximity_js_1.rerankByProximity)(results, ['foo', 'bar']);
28
+ expect(reranked).toHaveLength(1);
29
+ expect(reranked[0].score).toBe(1.0);
30
+ });
31
+ //# sourceMappingURL=proximity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proximity.test.js","sourceRoot":"","sources":["../../tests/proximity.test.ts"],"names":[],"mappings":";;AAAA,8DAAgE;AAGhE,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACnD,MAAM,OAAO,GAAmB;QAC9B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,qCAAqC,EAAE;QACzI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,gDAAgD,EAAE;KACrJ,CAAC;IACF,MAAM,QAAQ,GAAG,IAAA,gCAAiB,EAAC,OAAO,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IACrE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAC5C,MAAM,OAAO,GAAmB;QAC9B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QACvG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;KACxG,CAAC;IACF,MAAM,QAAQ,GAAG,IAAA,gCAAiB,EAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACvC,MAAM,CAAC,IAAA,gCAAiB,EAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;IAC/C,MAAM,OAAO,GAAmB;QAC9B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;KAC1F,CAAC;IACF,MAAM,QAAQ,GAAG,IAAA,gCAAiB,EAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5D,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rrf.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rrf.test.d.ts","sourceRoot":"","sources":["../../tests/rrf.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const db_js_1 = require("./helpers/db.js");
10
+ const rrf_js_1 = require("../scripts/lib/rrf.js");
11
+ function makeTmpDir() {
12
+ return fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-rrf-'));
13
+ }
14
+ function cleanup(dir, db) {
15
+ try {
16
+ db?.close();
17
+ }
18
+ catch { }
19
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
20
+ }
21
+ describe('computeRRF', () => {
22
+ test('merges porter and trigram results', () => {
23
+ const porter = [
24
+ { slug: 'doc-a', rank: 1, path: '/a', score: 0 },
25
+ { slug: 'doc-b', rank: 2, path: '/b', score: 0 },
26
+ ];
27
+ const trigram = [
28
+ { slug: 'doc-b', rank: 1, path: '/b', score: 0 },
29
+ { slug: 'doc-c', rank: 2, path: '/c', score: 0 },
30
+ ];
31
+ const fused = (0, rrf_js_1.computeRRF)(porter, trigram);
32
+ expect(fused[0].slug).toBe('doc-b');
33
+ expect(fused.length).toBe(3);
34
+ });
35
+ test('RRF score formula: 1/(K+rank)', () => {
36
+ const porter = [{ slug: 'x', rank: 1, path: '/x', score: 0 }];
37
+ const trigram = [{ slug: 'x', rank: 1, path: '/x', score: 0 }];
38
+ const fused = (0, rrf_js_1.computeRRF)(porter, trigram, { k: 60 });
39
+ expect(fused[0].score).toBeCloseTo(2 / 61, 4);
40
+ });
41
+ test('chunk dedup — same path keeps highest score', () => {
42
+ const porter = [
43
+ { slug: 'doc--chunk-0', rank: 1, path: '/doc.md', score: 0 },
44
+ { slug: 'doc--chunk-3', rank: 3, path: '/doc.md', score: 0 },
45
+ ];
46
+ const trigram = [];
47
+ const fused = (0, rrf_js_1.computeRRF)(porter, trigram, { dedupByPath: true });
48
+ expect(fused.length).toBe(1);
49
+ expect(fused[0].slug).toBe('doc--chunk-0');
50
+ });
51
+ test('empty inputs return empty', () => {
52
+ expect((0, rrf_js_1.computeRRF)([], [])).toEqual([]);
53
+ });
54
+ });
55
+ describe('searchPorter + searchTrigram', () => {
56
+ test('searchPorter returns ranked results from FTS5', () => {
57
+ const dir = makeTmpDir();
58
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
59
+ (0, db_js_1.insertFts)(db, {
60
+ path: '/sources/ts.md',
61
+ slug: 'typescript-guide',
62
+ description: 'TypeScript guide',
63
+ type: 'source',
64
+ category: 'sources',
65
+ title: 'TypeScript Hooks',
66
+ content: 'TypeScript provides hooks for React applications.',
67
+ tags: 'typescript,react',
68
+ });
69
+ const results = (0, rrf_js_1.searchPorter)(db, 'TypeScript hooks', 5);
70
+ expect(results.length).toBeGreaterThan(0);
71
+ expect(results[0].rank).toBe(1);
72
+ expect(results[0].score).toBe(0);
73
+ cleanup(dir, db);
74
+ });
75
+ test('searchTrigram returns results from trigram table', () => {
76
+ const dir = makeTmpDir();
77
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
78
+ (0, db_js_1.insertFts)(db, {
79
+ path: '/sources/ts.md',
80
+ slug: 'typescript-guide',
81
+ description: 'TypeScript guide',
82
+ type: 'source',
83
+ category: 'sources',
84
+ title: 'TypeScript Hooks',
85
+ content: 'TypeScript provides hooks for React applications.',
86
+ tags: 'typescript,react',
87
+ });
88
+ const results = (0, rrf_js_1.searchTrigram)(db, 'TypeScript', 5);
89
+ expect(results.length).toBeGreaterThan(0);
90
+ cleanup(dir, db);
91
+ });
92
+ test('searchPorter returns empty for no match', () => {
93
+ const dir = makeTmpDir();
94
+ const db = (0, db_js_1.createTestDbWithMigrations)(path_1.default.join(dir, 'mindlore.db'));
95
+ const results = (0, rrf_js_1.searchPorter)(db, 'nonexistentxyz', 5);
96
+ expect(results).toEqual([]);
97
+ cleanup(dir, db);
98
+ });
99
+ });
100
+ //# sourceMappingURL=rrf.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rrf.test.js","sourceRoot":"","sources":["../../tests/rrf.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,4CAAoB;AACpB,4CAAoB;AAEpB,2CAAwE;AACxE,kDAAmG;AAEnG,SAAS,UAAU;IACjB,OAAO,YAAE,CAAC,WAAW,CAAC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,EAAsB;IAClD,IAAI,CAAC;QAAC,EAAE,EAAE,KAAK,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAC7B,YAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAmB;YAC7B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;YAChD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;SACjD,CAAC;QACF,MAAM,OAAO,GAAmB;YAC9B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;YAChD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;SACjD,CAAC;QACF,MAAM,KAAK,GAAG,IAAA,mBAAU,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAmB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAmB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,IAAA,mBAAU,EAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAmB;YAC7B,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE;YAC5D,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE;SAC7D,CAAC;QACF,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAA,mBAAU,EAAC,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,IAAA,mBAAU,EAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAA,kCAA0B,EAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;QACrE,IAAA,iBAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,mDAAmD;YAC5D,IAAI,EAAE,kBAAkB;SACzB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,qBAAY,EAAC,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAA,kCAA0B,EAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;QACrE,IAAA,iBAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,mDAAmD;YAC5D,IAAI,EAAE,kBAAkB;SACzB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,sBAAa,EAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACnD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAA,kCAA0B,EAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,IAAA,qBAAY,EAAC,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-cache.test.d.ts","sourceRoot":"","sources":["../../tests/search-cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
10
+ const search_cache_js_1 = require("../scripts/lib/search-cache.js");
11
+ const migrations_v063_js_1 = require("../scripts/lib/migrations-v063.js");
12
+ function setupCacheTables(db) {
13
+ db.exec(migrations_v063_js_1.SQL_SEARCH_CACHE_CREATE);
14
+ db.exec(migrations_v063_js_1.SQL_SEARCH_THROTTLE_CREATE);
15
+ }
16
+ describe('TTL Cache', () => {
17
+ let db;
18
+ let tmpDir;
19
+ beforeEach(() => {
20
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-cache-'));
21
+ db = new better_sqlite3_1.default(path_1.default.join(tmpDir, 'test.db'));
22
+ db.pragma('journal_mode = WAL');
23
+ setupCacheTables(db);
24
+ });
25
+ afterEach(() => {
26
+ db.close();
27
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
28
+ });
29
+ test('cache hit returns cached results', () => {
30
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
31
+ const results = [{ slug: 'a', path: '/a', title: 'A', description: '', category: '', tags: '', score: 1 }];
32
+ cache.set('query1', results);
33
+ expect(cache.get('query1')).toEqual(results);
34
+ });
35
+ test('cache miss after TTL', () => {
36
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 1 });
37
+ cache.set('query1', []);
38
+ const start = Date.now();
39
+ while (Date.now() - start < 5) { /* busy wait */ }
40
+ expect(cache.get('query1')).toBeNull();
41
+ });
42
+ test('invalidate clears all entries', () => {
43
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
44
+ cache.set('q1', []);
45
+ cache.set('q2', []);
46
+ cache.invalidate();
47
+ expect(cache.get('q1')).toBeNull();
48
+ expect(cache.get('q2')).toBeNull();
49
+ });
50
+ test('cleanup removes expired entries', () => {
51
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 1 });
52
+ cache.set('old', []);
53
+ const start = Date.now();
54
+ while (Date.now() - start < 5) { /* busy wait */ }
55
+ cache.cleanup();
56
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- test assertion
57
+ const count = db.prepare('SELECT COUNT(*) as c FROM search_cache').get().c;
58
+ expect(count).toBe(0);
59
+ });
60
+ });
61
+ describe('Progressive Throttling', () => {
62
+ let db;
63
+ let tmpDir;
64
+ beforeEach(() => {
65
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-throttle-'));
66
+ db = new better_sqlite3_1.default(path_1.default.join(tmpDir, 'test.db'));
67
+ db.pragma('journal_mode = WAL');
68
+ setupCacheTables(db);
69
+ });
70
+ afterEach(() => {
71
+ db.close();
72
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
73
+ });
74
+ test('returns 3 results for calls 1-10', () => {
75
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
76
+ expect(cache.getMaxResults(1)).toBe(3);
77
+ expect(cache.getMaxResults(10)).toBe(3);
78
+ });
79
+ test('returns 1 result for calls 11-20', () => {
80
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
81
+ expect(cache.getMaxResults(11)).toBe(1);
82
+ expect(cache.getMaxResults(20)).toBe(1);
83
+ });
84
+ test('returns 0 for calls 21+', () => {
85
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
86
+ expect(cache.getMaxResults(21)).toBe(0);
87
+ });
88
+ test('incrementCallCount tracks per session', () => {
89
+ const cache = new search_cache_js_1.SearchCache(db, { ttlMs: 5000 });
90
+ expect(cache.incrementCallCount('sess-1')).toBe(1);
91
+ expect(cache.incrementCallCount('sess-1')).toBe(2);
92
+ expect(cache.incrementCallCount('sess-2')).toBe(1);
93
+ });
94
+ });
95
+ //# sourceMappingURL=search-cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-cache.test.js","sourceRoot":"","sources":["../../tests/search-cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-engine.test.d.ts","sourceRoot":"","sources":["../../tests/search-engine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const db_js_1 = require("./helpers/db.js");
10
+ const search_engine_js_1 = require("../scripts/lib/search-engine.js");
11
+ function makeTmpDir() {
12
+ return fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-se-'));
13
+ }
14
+ function cleanup(dir, db) {
15
+ try {
16
+ db?.close();
17
+ }
18
+ catch { }
19
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
20
+ }
21
+ function seedDb(dbPath) {
22
+ const db = (0, db_js_1.createTestDbWithMigrations)(dbPath);
23
+ (0, db_js_1.insertFts)(db, {
24
+ path: '/sources/typescript.md',
25
+ slug: 'typescript',
26
+ description: 'TypeScript guide',
27
+ type: 'source',
28
+ category: 'sources',
29
+ title: 'TypeScript Hooks',
30
+ content: 'TypeScript provides hooks for React applications. Hooks are reusable.',
31
+ tags: 'typescript,react',
32
+ });
33
+ (0, db_js_1.insertFts)(db, {
34
+ path: '/sources/python.md',
35
+ slug: 'python',
36
+ description: 'Python guide',
37
+ type: 'source',
38
+ category: 'sources',
39
+ title: 'Python Basics',
40
+ content: 'Python is a dynamic programming language used for data science.',
41
+ tags: 'python',
42
+ });
43
+ (0, db_js_1.insertFts)(db, {
44
+ path: '/episodes/debug-session.md',
45
+ slug: 'debug-session',
46
+ description: 'Debug session log',
47
+ type: 'episode',
48
+ category: 'episodes',
49
+ title: 'Debug Session',
50
+ content: 'Fixed a critical TypeScript compilation error in hooks module.',
51
+ tags: 'debug,typescript',
52
+ });
53
+ return db;
54
+ }
55
+ describe('extractKeywords', () => {
56
+ test('removes stop words and short words', () => {
57
+ const kw = (0, search_engine_js_1.extractKeywords)('the TypeScript hooks are powerful');
58
+ expect(kw).toContain('typescript');
59
+ expect(kw).toContain('hooks');
60
+ expect(kw).toContain('powerful');
61
+ expect(kw).not.toContain('the');
62
+ expect(kw).not.toContain('are');
63
+ });
64
+ test('returns empty for all stop words', () => {
65
+ expect((0, search_engine_js_1.extractKeywords)('the a is are')).toEqual([]);
66
+ });
67
+ test('handles Turkish stop words', () => {
68
+ const kw = (0, search_engine_js_1.extractKeywords)('bu bir TypeScript projesi');
69
+ expect(kw).toContain('typescript');
70
+ expect(kw).toContain('projesi');
71
+ expect(kw).not.toContain('bu');
72
+ expect(kw).not.toContain('bir');
73
+ });
74
+ });
75
+ describe('search pipeline', () => {
76
+ test('basic search returns ranked results', () => {
77
+ const dir = makeTmpDir();
78
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
79
+ const results = (0, search_engine_js_1.search)(db, 'TypeScript hooks', {});
80
+ expect(results.length).toBeGreaterThan(0);
81
+ expect(results[0].slug).toBe('typescript');
82
+ cleanup(dir, db);
83
+ });
84
+ test('title match ranks higher via BM25 title boost', () => {
85
+ const dir = makeTmpDir();
86
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
87
+ const results = (0, search_engine_js_1.search)(db, 'TypeScript', { maxResults: 10 });
88
+ expect(results.length).toBeGreaterThanOrEqual(2);
89
+ expect(results[0].title).toContain('TypeScript');
90
+ cleanup(dir, db);
91
+ });
92
+ test('returns empty array for no matches', () => {
93
+ const dir = makeTmpDir();
94
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
95
+ const results = (0, search_engine_js_1.search)(db, 'nonexistentterm12345xyz', {});
96
+ expect(results).toEqual([]);
97
+ cleanup(dir, db);
98
+ });
99
+ test('respects maxResults option', () => {
100
+ const dir = makeTmpDir();
101
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
102
+ const results = (0, search_engine_js_1.search)(db, 'TypeScript', { maxResults: 1 });
103
+ expect(results.length).toBeLessThanOrEqual(1);
104
+ cleanup(dir, db);
105
+ });
106
+ test('category weight boosts sources over episodes', () => {
107
+ const dir = makeTmpDir();
108
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
109
+ const results = (0, search_engine_js_1.search)(db, 'TypeScript', { maxResults: 10 });
110
+ const sourceResults = results.filter(r => r.category === 'sources');
111
+ const episodeResults = results.filter(r => r.category === 'episodes');
112
+ if (sourceResults.length > 0 && episodeResults.length > 0) {
113
+ expect(sourceResults[0].score).toBeGreaterThanOrEqual(episodeResults[0].score);
114
+ }
115
+ cleanup(dir, db);
116
+ });
117
+ test('empty query returns empty', () => {
118
+ const dir = makeTmpDir();
119
+ const db = seedDb(path_1.default.join(dir, 'mindlore.db'));
120
+ const results = (0, search_engine_js_1.search)(db, '', {});
121
+ expect(results).toEqual([]);
122
+ cleanup(dir, db);
123
+ });
124
+ });
125
+ //# sourceMappingURL=search-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-engine.test.js","sourceRoot":"","sources":["../../tests/search-engine.test.ts"],"names":[],"mappings":"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"}
@@ -178,11 +178,11 @@ describe('Search Hook — Synonym Loader Verification', () => {
178
178
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- testing null guard
179
179
  expect(loadSynonyms(null)).toEqual({});
180
180
  });
181
- test('search hook contains inline synonym expansion logic', () => {
181
+ test('search hook delegates to search-engine module', () => {
182
182
  const hookSource = fs_1.default.readFileSync(path_1.default.join(__dirname, '..', 'hooks', 'mindlore-search.cjs'), 'utf8');
183
+ expect(hookSource).toContain('search-engine.js');
184
+ expect(hookSource).toContain('searchEngineMod.search');
183
185
  expect(hookSource).toContain('config.synonyms');
184
- expect(hookSource).toContain('synonyms[lower]');
185
- expect(hookSource).toContain('expandedTerms.push');
186
186
  });
187
187
  });
188
188
  //# sourceMappingURL=search-hook.test.js.map