asyar-sdk 1.8.2 → 1.9.1

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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ExtensionBridge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExtensionBridge.test.d.ts","sourceRoot":"","sources":["../src/ExtensionBridge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ const vitest_1 = require("vitest");
36
+ // We need to reset the singleton between tests, so we import the module dynamically
37
+ // after mocking dependencies.
38
+ // Mock the MessageBroker
39
+ vitest_1.vi.mock('./ipc/MessageBroker', () => {
40
+ const handlers = new Map();
41
+ return {
42
+ MessageBroker: {
43
+ getInstance: () => ({
44
+ on: (type, handler) => handlers.set(type, handler),
45
+ send: vitest_1.vi.fn(),
46
+ }),
47
+ },
48
+ // Expose for test assertions
49
+ __handlers: handlers,
50
+ };
51
+ });
52
+ // Mock LogServiceProxy as a proper class
53
+ vitest_1.vi.mock('./services/LogServiceProxy', () => ({
54
+ LogServiceProxy: class {
55
+ constructor() {
56
+ this.debug = vitest_1.vi.fn();
57
+ this.info = vitest_1.vi.fn();
58
+ this.warn = vitest_1.vi.fn();
59
+ this.error = vitest_1.vi.fn();
60
+ }
61
+ },
62
+ }));
63
+ (0, vitest_1.describe)('ExtensionBridge search IPC', () => {
64
+ let postMessageSpy;
65
+ let messageHandler;
66
+ (0, vitest_1.beforeEach)(() => {
67
+ // Reset the singleton by clearing the module cache
68
+ vitest_1.vi.resetModules();
69
+ postMessageSpy = vitest_1.vi.fn();
70
+ // Capture the message event listener that ExtensionBridge installs
71
+ vitest_1.vi.spyOn(window, 'addEventListener').mockImplementation((type, handler) => {
72
+ if (type === 'message') {
73
+ messageHandler = handler;
74
+ }
75
+ });
76
+ // Mock window.parent.postMessage
77
+ Object.defineProperty(window, 'parent', {
78
+ value: { postMessage: postMessageSpy },
79
+ writable: true,
80
+ configurable: true,
81
+ });
82
+ });
83
+ (0, vitest_1.afterEach)(() => {
84
+ vitest_1.vi.restoreAllMocks();
85
+ messageHandler = undefined;
86
+ });
87
+ (0, vitest_1.it)('responds to asyar:search:request with results from registered extension', () => __awaiter(void 0, void 0, void 0, function* () {
88
+ // Import fresh to trigger singleton creation
89
+ const { ExtensionBridge } = yield Promise.resolve().then(() => __importStar(require('./ExtensionBridge')));
90
+ const bridge = ExtensionBridge.getInstance();
91
+ // Register a manifest and extension with a search method
92
+ bridge.registerManifest({
93
+ id: 'test-ext',
94
+ name: 'Test Extension',
95
+ version: '1.0.0',
96
+ description: 'Test',
97
+ type: 'view',
98
+ searchable: true,
99
+ commands: [],
100
+ });
101
+ bridge.registerExtensionImplementation('test-ext', {
102
+ initialize: vitest_1.vi.fn(),
103
+ activate: vitest_1.vi.fn(),
104
+ deactivate: vitest_1.vi.fn(),
105
+ onUnload: vitest_1.vi.fn(),
106
+ executeCommand: vitest_1.vi.fn(),
107
+ search: vitest_1.vi.fn().mockResolvedValue([
108
+ {
109
+ title: 'Test Result',
110
+ subtitle: 'A test doc',
111
+ score: 0.9,
112
+ type: 'view',
113
+ icon: '📖',
114
+ viewPath: 'test-ext/TestView',
115
+ action: () => { },
116
+ },
117
+ ]),
118
+ });
119
+ (0, vitest_1.expect)(messageHandler).toBeDefined();
120
+ // Simulate host sending asyar:search:request
121
+ const event = new MessageEvent('message', {
122
+ data: {
123
+ type: 'asyar:search:request',
124
+ messageId: 'search_123',
125
+ payload: { query: 'test' },
126
+ },
127
+ source: window.parent,
128
+ });
129
+ messageHandler(event);
130
+ // Wait for async search to complete
131
+ yield vitest_1.vi.waitFor(() => {
132
+ (0, vitest_1.expect)(postMessageSpy).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
133
+ type: 'asyar:search:response',
134
+ messageId: 'search_123',
135
+ result: vitest_1.expect.arrayContaining([
136
+ vitest_1.expect.objectContaining({
137
+ title: 'Test Result',
138
+ subtitle: 'A test doc',
139
+ score: 0.9,
140
+ }),
141
+ ]),
142
+ }), '*');
143
+ });
144
+ }));
145
+ (0, vitest_1.it)('responds with empty results when no extension implements search', () => __awaiter(void 0, void 0, void 0, function* () {
146
+ const { ExtensionBridge } = yield Promise.resolve().then(() => __importStar(require('./ExtensionBridge')));
147
+ const bridge = ExtensionBridge.getInstance();
148
+ // Register extension WITHOUT search method
149
+ bridge.registerManifest({
150
+ id: 'no-search-ext',
151
+ name: 'No Search',
152
+ version: '1.0.0',
153
+ description: 'Test',
154
+ type: 'view',
155
+ commands: [],
156
+ });
157
+ bridge.registerExtensionImplementation('no-search-ext', {
158
+ initialize: vitest_1.vi.fn(),
159
+ activate: vitest_1.vi.fn(),
160
+ deactivate: vitest_1.vi.fn(),
161
+ onUnload: vitest_1.vi.fn(),
162
+ executeCommand: vitest_1.vi.fn(),
163
+ });
164
+ (0, vitest_1.expect)(messageHandler).toBeDefined();
165
+ const event = new MessageEvent('message', {
166
+ data: {
167
+ type: 'asyar:search:request',
168
+ messageId: 'search_456',
169
+ payload: { query: 'test' },
170
+ },
171
+ source: window.parent,
172
+ });
173
+ messageHandler(event);
174
+ yield vitest_1.vi.waitFor(() => {
175
+ (0, vitest_1.expect)(postMessageSpy).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
176
+ type: 'asyar:search:response',
177
+ messageId: 'search_456',
178
+ result: [],
179
+ }), '*');
180
+ });
181
+ }));
182
+ (0, vitest_1.it)('strips action functions from search results (not serializable via postMessage)', () => __awaiter(void 0, void 0, void 0, function* () {
183
+ const { ExtensionBridge } = yield Promise.resolve().then(() => __importStar(require('./ExtensionBridge')));
184
+ const bridge = ExtensionBridge.getInstance();
185
+ bridge.registerManifest({
186
+ id: 'strip-ext',
187
+ name: 'Strip Test',
188
+ version: '1.0.0',
189
+ description: 'Test',
190
+ type: 'view',
191
+ commands: [],
192
+ });
193
+ bridge.registerExtensionImplementation('strip-ext', {
194
+ initialize: vitest_1.vi.fn(),
195
+ activate: vitest_1.vi.fn(),
196
+ deactivate: vitest_1.vi.fn(),
197
+ onUnload: vitest_1.vi.fn(),
198
+ executeCommand: vitest_1.vi.fn(),
199
+ search: vitest_1.vi.fn().mockResolvedValue([
200
+ {
201
+ title: 'Doc',
202
+ score: 0.5,
203
+ type: 'view',
204
+ action: () => console.log('should be stripped'),
205
+ viewPath: 'strip-ext/View',
206
+ },
207
+ ]),
208
+ });
209
+ (0, vitest_1.expect)(messageHandler).toBeDefined();
210
+ const event = new MessageEvent('message', {
211
+ data: {
212
+ type: 'asyar:search:request',
213
+ messageId: 'search_789',
214
+ payload: { query: 'doc' },
215
+ },
216
+ source: window.parent,
217
+ });
218
+ messageHandler(event);
219
+ yield vitest_1.vi.waitFor(() => {
220
+ (0, vitest_1.expect)(postMessageSpy).toHaveBeenCalled();
221
+ const call = postMessageSpy.mock.calls[0];
222
+ const result = call[0].result[0];
223
+ (0, vitest_1.expect)(result.title).toBe('Doc');
224
+ // action should NOT be present in the serialized result
225
+ (0, vitest_1.expect)(result).not.toHaveProperty('action');
226
+ });
227
+ }));
228
+ });
229
+ //# sourceMappingURL=ExtensionBridge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExtensionBridge.test.js","sourceRoot":"","sources":["../src/ExtensionBridge.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export { ActionContext, ActionCategory } from './types/ActionType';
6
6
  export type { ActionCategoryValue } from './types/ActionType';
7
7
  export * from './types';
8
8
  export * from './icons';
9
+ export * from './search';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAGL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAGL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -31,4 +31,5 @@ Object.defineProperty(exports, "ActionCategory", { enumerable: true, get: functi
31
31
  // Re-export all types for easier consumption
32
32
  __exportStar(require("./types"), exports);
33
33
  __exportStar(require("./icons"), exports);
34
+ __exportStar(require("./search"), exports);
34
35
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAezB,uCAKoB;AAJlB,4FAA4F;AAC5F,iFAAiF;AACjF,iHAAA,qBAAqB,OAAA;AACrB,iHAAA,qBAAqB,OAAA;AAGvB,qDAAqD;AACrD,iDAAmE;AAA1D,2GAAA,aAAa,OAAA;AAAE,4GAAA,cAAc,OAAA;AAGtC,6CAA6C;AAC7C,0CAAwB;AACxB,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAezB,uCAKoB;AAJlB,4FAA4F;AAC5F,iFAAiF;AACjF,iHAAA,qBAAqB,OAAA;AACrB,iHAAA,qBAAqB,OAAA;AAGvB,qDAAqD;AACrD,iDAAmE;AAA1D,2GAAA,aAAa,OAAA;AAAE,4GAAA,cAAc,OAAA;AAGtC,6CAA6C;AAC7C,0CAAwB;AACxB,0CAAwB;AACxB,2CAAyB"}
@@ -0,0 +1,20 @@
1
+ import type { SearchEngineOptions } from './types';
2
+ export declare class SearchEngine<T> {
3
+ private _items;
4
+ private _haystack;
5
+ private readonly getText;
6
+ private readonly mode;
7
+ private readonly uf;
8
+ constructor(options: SearchEngineOptions<T>);
9
+ /**
10
+ * Set the item list. Rebuilds the searchable text haystack.
11
+ * Skips rebuild if the same array reference is passed (items unchanged).
12
+ */
13
+ setItems(items: T[]): void;
14
+ /**
15
+ * Search items. Returns matching items in relevance order.
16
+ * Empty/whitespace query returns all items.
17
+ */
18
+ search(query: string): T[];
19
+ }
20
+ //# sourceMappingURL=SearchEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchEngine.d.ts","sourceRoot":"","sources":["../../src/search/SearchEngine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAUnD,qBAAa,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;gBAEhB,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAY3C;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI;IAM1B;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE;CAoD3B"}
@@ -0,0 +1,91 @@
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
+ exports.SearchEngine = void 0;
7
+ const ufuzzy_1 = __importDefault(require("@leeoniya/ufuzzy"));
8
+ function isSubsequence(search, text) {
9
+ let si = 0;
10
+ for (let ti = 0; ti < text.length && si < search.length; ti++) {
11
+ if (search[si] === text[ti])
12
+ si++;
13
+ }
14
+ return si === search.length;
15
+ }
16
+ class SearchEngine {
17
+ constructor(options) {
18
+ var _a;
19
+ this._items = [];
20
+ this._haystack = [];
21
+ this.getText = options.getText;
22
+ this.mode = (_a = options.mode) !== null && _a !== void 0 ? _a : 'fuzzy';
23
+ this.uf = new ufuzzy_1.default({
24
+ intraMode: 1,
25
+ intraIns: 12,
26
+ intraSub: 1,
27
+ intraTrn: 1,
28
+ intraDel: 1,
29
+ });
30
+ }
31
+ /**
32
+ * Set the item list. Rebuilds the searchable text haystack.
33
+ * Skips rebuild if the same array reference is passed (items unchanged).
34
+ */
35
+ setItems(items) {
36
+ if (items === this._items)
37
+ return;
38
+ this._items = items;
39
+ this._haystack = items.map(this.getText);
40
+ }
41
+ /**
42
+ * Search items. Returns matching items in relevance order.
43
+ * Empty/whitespace query returns all items.
44
+ */
45
+ search(query) {
46
+ const q = query.trim();
47
+ if (!q)
48
+ return [...this._items];
49
+ const qLower = q.toLowerCase();
50
+ const terms = qLower.split(/\s+/).filter(Boolean);
51
+ // Tier 1: Exact substring match (all terms must appear)
52
+ const exactIndices = [];
53
+ for (let i = 0; i < this._haystack.length; i++) {
54
+ const h = this._haystack[i].toLowerCase();
55
+ if (terms.every(t => h.includes(t))) {
56
+ exactIndices.push(i);
57
+ }
58
+ }
59
+ if (this.mode === 'exact') {
60
+ return exactIndices.map(i => this._items[i]);
61
+ }
62
+ // Tier 2: Subsequence match (all terms appear as ordered subsequences)
63
+ const subseqIndices = [];
64
+ for (let i = 0; i < this._haystack.length; i++) {
65
+ const h = this._haystack[i].toLowerCase();
66
+ if (terms.every(t => isSubsequence(t, h))) {
67
+ subseqIndices.push(i);
68
+ }
69
+ }
70
+ // Tier 3: uFuzzy (typo tolerance)
71
+ const idxs = this.uf.filter(this._haystack, q);
72
+ let fuzzyRankedIndices = [];
73
+ if (idxs && idxs.length > 0) {
74
+ const info = this.uf.info(idxs, this._haystack, q);
75
+ const order = this.uf.sort(info, this._haystack, q);
76
+ fuzzyRankedIndices = order.map(i => idxs[i]);
77
+ }
78
+ // Merge: exact first, then subsequence, then fuzzy (de-duplicated)
79
+ const exactItems = exactIndices.map(i => this._items[i]);
80
+ const seen = new Set(exactIndices);
81
+ const subseqOnlyItems = subseqIndices
82
+ .filter(i => !seen.has(i))
83
+ .map(i => { seen.add(i); return this._items[i]; });
84
+ const fuzzyOnlyItems = fuzzyRankedIndices
85
+ .filter(i => !seen.has(i))
86
+ .map(i => this._items[i]);
87
+ return [...exactItems, ...subseqOnlyItems, ...fuzzyOnlyItems];
88
+ }
89
+ }
90
+ exports.SearchEngine = SearchEngine;
91
+ //# sourceMappingURL=SearchEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchEngine.js","sourceRoot":"","sources":["../../src/search/SearchEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SearchEngine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchEngine.test.d.ts","sourceRoot":"","sources":["../../src/search/SearchEngine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const SearchEngine_1 = require("./SearchEngine");
5
+ function makeEngine(items, mode = 'fuzzy') {
6
+ const engine = new SearchEngine_1.SearchEngine({
7
+ getText: (item) => item.text,
8
+ mode,
9
+ });
10
+ engine.setItems(items);
11
+ return engine;
12
+ }
13
+ const sampleItems = [
14
+ { id: '1', text: 'quarterly report summary for Q3' },
15
+ { id: '2', text: 'banana smoothie recipe' },
16
+ { id: '3', text: 'record of transactions' },
17
+ { id: '4', text: 'apple pie recipe' },
18
+ { id: '5', text: 'unrelated text document' },
19
+ ];
20
+ (0, vitest_1.describe)('SearchEngine', () => {
21
+ (0, vitest_1.describe)('basic behavior', () => {
22
+ (0, vitest_1.it)('returns all items when query is empty', () => {
23
+ const engine = makeEngine(sampleItems);
24
+ (0, vitest_1.expect)(engine.search('')).toHaveLength(5);
25
+ });
26
+ (0, vitest_1.it)('returns all items when query is whitespace', () => {
27
+ const engine = makeEngine(sampleItems);
28
+ (0, vitest_1.expect)(engine.search(' ')).toHaveLength(5);
29
+ });
30
+ (0, vitest_1.it)('returns empty array when nothing matches', () => {
31
+ const engine = makeEngine(sampleItems);
32
+ (0, vitest_1.expect)(engine.search('zzzznothing')).toHaveLength(0);
33
+ });
34
+ (0, vitest_1.it)('finds exact substring matches', () => {
35
+ const engine = makeEngine(sampleItems);
36
+ const results = engine.search('banana');
37
+ (0, vitest_1.expect)(results.some(r => r.id === '2')).toBe(true);
38
+ (0, vitest_1.expect)(results.some(r => r.id === '1')).toBe(false);
39
+ });
40
+ (0, vitest_1.it)('is case-insensitive', () => {
41
+ const engine = makeEngine(sampleItems);
42
+ const results = engine.search('BANANA');
43
+ (0, vitest_1.expect)(results.some(r => r.id === '2')).toBe(true);
44
+ });
45
+ (0, vitest_1.it)('handles multi-word queries with AND logic for exact tier', () => {
46
+ const engine = makeEngine(sampleItems);
47
+ const results = engine.search('apple recipe');
48
+ (0, vitest_1.expect)(results.some(r => r.id === '4')).toBe(true);
49
+ (0, vitest_1.expect)(results.some(r => r.id === '2')).toBe(false); // has "recipe" but not "apple"
50
+ });
51
+ });
52
+ (0, vitest_1.describe)('fuzzy mode — subsequence matching', () => {
53
+ (0, vitest_1.it)('matches subsequences: "qrtly" finds "quarterly"', () => {
54
+ const engine = makeEngine(sampleItems);
55
+ const results = engine.search('qrtly');
56
+ (0, vitest_1.expect)(results.some(r => r.id === '1')).toBe(true);
57
+ });
58
+ (0, vitest_1.it)('matches across word boundaries: "qr" finds "quarterly report"', () => {
59
+ const engine = makeEngine(sampleItems);
60
+ const results = engine.search('qr');
61
+ (0, vitest_1.expect)(results.some(r => r.id === '1')).toBe(true);
62
+ });
63
+ (0, vitest_1.it)('multi-term fuzzy: "qrtly rep" finds "quarterly report summary"', () => {
64
+ const engine = makeEngine(sampleItems);
65
+ const results = engine.search('qrtly rep');
66
+ (0, vitest_1.expect)(results.some(r => r.id === '1')).toBe(true);
67
+ (0, vitest_1.expect)(results.some(r => r.id === '5')).toBe(false);
68
+ });
69
+ });
70
+ (0, vitest_1.describe)('fuzzy mode — typo tolerance', () => {
71
+ (0, vitest_1.it)('tolerates single substitution: "recort" finds "record"', () => {
72
+ const engine = makeEngine(sampleItems);
73
+ const results = engine.search('recort');
74
+ (0, vitest_1.expect)(results.some(r => r.id === '3')).toBe(true);
75
+ });
76
+ (0, vitest_1.it)('tolerates single transposition: "reocrd" finds "record"', () => {
77
+ const engine = makeEngine(sampleItems);
78
+ const results = engine.search('reocrd');
79
+ (0, vitest_1.expect)(results.some(r => r.id === '3')).toBe(true);
80
+ });
81
+ });
82
+ (0, vitest_1.describe)('ranking', () => {
83
+ (0, vitest_1.it)('ranks exact matches higher than fuzzy-only matches', () => {
84
+ const items = [
85
+ { id: 'fuzzy', text: 'approximate appple thing' },
86
+ { id: 'exact', text: 'apple pie recipe' },
87
+ ];
88
+ const engine = makeEngine(items);
89
+ const results = engine.search('apple');
90
+ (0, vitest_1.expect)(results[0].id).toBe('exact');
91
+ });
92
+ });
93
+ (0, vitest_1.describe)('exact mode', () => {
94
+ (0, vitest_1.it)('does NOT match subsequences in exact mode', () => {
95
+ const engine = makeEngine(sampleItems, 'exact');
96
+ const results = engine.search('qrtly');
97
+ (0, vitest_1.expect)(results).toHaveLength(0);
98
+ });
99
+ (0, vitest_1.it)('still finds exact substrings in exact mode', () => {
100
+ const engine = makeEngine(sampleItems, 'exact');
101
+ const results = engine.search('banana');
102
+ (0, vitest_1.expect)(results.some(r => r.id === '2')).toBe(true);
103
+ });
104
+ (0, vitest_1.it)('multi-term AND logic in exact mode', () => {
105
+ const engine = makeEngine(sampleItems, 'exact');
106
+ const results = engine.search('apple recipe');
107
+ (0, vitest_1.expect)(results.some(r => r.id === '4')).toBe(true);
108
+ (0, vitest_1.expect)(results.some(r => r.id === '2')).toBe(false);
109
+ });
110
+ });
111
+ (0, vitest_1.describe)('setItems', () => {
112
+ (0, vitest_1.it)('rebuilds haystack when items change', () => {
113
+ const engine = new SearchEngine_1.SearchEngine({
114
+ getText: (item) => item.text,
115
+ });
116
+ engine.setItems([{ id: '1', text: 'first batch' }]);
117
+ (0, vitest_1.expect)(engine.search('first')).toHaveLength(1);
118
+ engine.setItems([{ id: '2', text: 'second batch' }]);
119
+ (0, vitest_1.expect)(engine.search('first')).toHaveLength(0);
120
+ (0, vitest_1.expect)(engine.search('second')).toHaveLength(1);
121
+ });
122
+ (0, vitest_1.it)('skips rebuild if same array reference is passed', () => {
123
+ const items = [{ id: '1', text: 'hello' }];
124
+ const engine = new SearchEngine_1.SearchEngine({
125
+ getText: (item) => item.text,
126
+ });
127
+ engine.setItems(items);
128
+ // Mutate the item (bad practice, but tests the reference check)
129
+ items[0].text = 'changed';
130
+ engine.setItems(items); // same reference — should NOT rebuild
131
+ // Haystack should still contain old value
132
+ (0, vitest_1.expect)(engine.search('hello')).toHaveLength(1);
133
+ (0, vitest_1.expect)(engine.search('changed')).toHaveLength(0);
134
+ });
135
+ });
136
+ });
137
+ //# sourceMappingURL=SearchEngine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchEngine.test.js","sourceRoot":"","sources":["../../src/search/SearchEngine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { SearchEngine } from './SearchEngine';
2
+ export { stripHtml, stripRtf } from './textUtils';
3
+ export type { SearchEngineOptions } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripRtf = exports.stripHtml = exports.SearchEngine = void 0;
4
+ var SearchEngine_1 = require("./SearchEngine");
5
+ Object.defineProperty(exports, "SearchEngine", { enumerable: true, get: function () { return SearchEngine_1.SearchEngine; } });
6
+ var textUtils_1 = require("./textUtils");
7
+ Object.defineProperty(exports, "stripHtml", { enumerable: true, get: function () { return textUtils_1.stripHtml; } });
8
+ Object.defineProperty(exports, "stripRtf", { enumerable: true, get: function () { return textUtils_1.stripRtf; } });
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,yCAAkD;AAAzC,sGAAA,SAAS,OAAA;AAAE,qGAAA,QAAQ,OAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strip HTML tags, script/style blocks, and decode common entities.
3
+ * Uses regex — no DOM dependency, works in all environments.
4
+ */
5
+ export declare function stripHtml(html: string): string;
6
+ /**
7
+ * Strip RTF control words, unicode escapes, braces, and backslashes.
8
+ */
9
+ export declare function stripRtf(rtf: string): string;
10
+ //# sourceMappingURL=textUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textUtils.d.ts","sourceRoot":"","sources":["../../src/search/textUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc9C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ5C"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripHtml = stripHtml;
4
+ exports.stripRtf = stripRtf;
5
+ /**
6
+ * Strip HTML tags, script/style blocks, and decode common entities.
7
+ * Uses regex — no DOM dependency, works in all environments.
8
+ */
9
+ function stripHtml(html) {
10
+ if (!html)
11
+ return '';
12
+ return html
13
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
14
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
15
+ .replace(/<[^>]+>/g, ' ')
16
+ .replace(/&nbsp;/gi, ' ')
17
+ .replace(/&amp;/gi, '&')
18
+ .replace(/&lt;/gi, '<')
19
+ .replace(/&gt;/gi, '>')
20
+ .replace(/&quot;/gi, '"')
21
+ .replace(/&#\d+;/gi, ' ')
22
+ .replace(/\s+/g, ' ')
23
+ .trim();
24
+ }
25
+ /**
26
+ * Strip RTF control words, unicode escapes, braces, and backslashes.
27
+ */
28
+ function stripRtf(rtf) {
29
+ if (!rtf)
30
+ return '';
31
+ return rtf
32
+ .replace(/\\u-?\d+\??/g, '')
33
+ .replace(/\\[a-z]+-?\d*\s?/gi, '')
34
+ .replace(/[{}\\]/g, '')
35
+ .replace(/\s+/g, ' ')
36
+ .trim();
37
+ }
38
+ //# sourceMappingURL=textUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textUtils.js","sourceRoot":"","sources":["../../src/search/textUtils.ts"],"names":[],"mappings":";;AAIA,8BAcC;AAKD,4BAQC;AA/BD;;;GAGG;AACH,SAAgB,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI;SACR,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC;SAC9C,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC;SAChD,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAgB,QAAQ,CAAC,GAAW;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG;SACP,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;SACjC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=textUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textUtils.test.d.ts","sourceRoot":"","sources":["../../src/search/textUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const textUtils_1 = require("./textUtils");
5
+ (0, vitest_1.describe)('stripHtml', () => {
6
+ (0, vitest_1.it)('strips simple tags', () => {
7
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('<p>hello</p>')).toBe('hello');
8
+ });
9
+ (0, vitest_1.it)('strips nested tags', () => {
10
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('<div><p>hello <b>world</b></p></div>')).toBe('hello world');
11
+ });
12
+ (0, vitest_1.it)('strips full HTML documents', () => {
13
+ const html = '<html><head><meta charset="UTF-8"><style>body{color:red}</style></head><body><p>quarterly report</p></body></html>';
14
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)(html)).toContain('quarterly report');
15
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)(html)).not.toContain('<');
16
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)(html)).not.toContain('color:red');
17
+ });
18
+ (0, vitest_1.it)('strips script tags and their content', () => {
19
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('<p>safe</p><script>alert("xss")</script>')).toBe('safe');
20
+ });
21
+ (0, vitest_1.it)('strips style tags and their content', () => {
22
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('<style>.a{color:red}</style><p>text</p>')).toBe('text');
23
+ });
24
+ (0, vitest_1.it)('decodes common HTML entities', () => {
25
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('a &amp; b &lt; c &gt; d &quot;e&quot;')).toBe('a & b < c > d "e"');
26
+ });
27
+ (0, vitest_1.it)('collapses whitespace', () => {
28
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('<p> hello </p> <p> world </p>')).toBe('hello world');
29
+ });
30
+ (0, vitest_1.it)('returns empty string for empty input', () => {
31
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('')).toBe('');
32
+ });
33
+ (0, vitest_1.it)('returns plain text unchanged', () => {
34
+ (0, vitest_1.expect)((0, textUtils_1.stripHtml)('no tags here')).toBe('no tags here');
35
+ });
36
+ });
37
+ (0, vitest_1.describe)('stripRtf', () => {
38
+ (0, vitest_1.it)('strips RTF control words', () => {
39
+ const result = (0, textUtils_1.stripRtf)('{\\rtf1\\b hello\\b0 world}');
40
+ (0, vitest_1.expect)(result).toContain('hello');
41
+ (0, vitest_1.expect)(result).toContain('world');
42
+ (0, vitest_1.expect)(result).not.toContain('\\rtf');
43
+ (0, vitest_1.expect)(result).not.toContain('\\b');
44
+ });
45
+ (0, vitest_1.it)('strips unicode escape sequences', () => {
46
+ (0, vitest_1.expect)((0, textUtils_1.stripRtf)('\\u8230?')).not.toContain('\\u8230');
47
+ });
48
+ (0, vitest_1.it)('strips braces and backslashes', () => {
49
+ const result = (0, textUtils_1.stripRtf)('{\\rtf1 {\\b bold} text}');
50
+ (0, vitest_1.expect)(result).not.toContain('{');
51
+ (0, vitest_1.expect)(result).not.toContain('}');
52
+ });
53
+ (0, vitest_1.it)('collapses whitespace', () => {
54
+ const result = (0, textUtils_1.stripRtf)('{\\rtf1 hello world }');
55
+ (0, vitest_1.expect)(result).toBe('hello world');
56
+ });
57
+ (0, vitest_1.it)('returns empty string for empty input', () => {
58
+ (0, vitest_1.expect)((0, textUtils_1.stripRtf)('')).toBe('');
59
+ });
60
+ });
61
+ //# sourceMappingURL=textUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textUtils.test.js","sourceRoot":"","sources":["../../src/search/textUtils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface SearchEngineOptions<T> {
2
+ /**
3
+ * Extract searchable text from an item.
4
+ * Called once per item when setItems() is called — not on every search.
5
+ */
6
+ getText: (item: T) => string;
7
+ /**
8
+ * 'exact' — substring match only (fast, no typo tolerance)
9
+ * 'fuzzy' — two-tier: exact substring first, then uFuzzy subsequence + 1 typo per term
10
+ * Default: 'fuzzy'
11
+ */
12
+ mode?: 'exact' | 'fuzzy';
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC;;;OAGG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAE7B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asyar-sdk",
3
- "version": "1.8.2",
3
+ "version": "1.9.1",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "asyar": "./dist/cli/index.js"
@@ -47,6 +47,7 @@
47
47
  "src/styles"
48
48
  ],
49
49
  "dependencies": {
50
+ "@leeoniya/ufuzzy": "^1.0.19",
50
51
  "adm-zip": "^0.5.16",
51
52
  "chalk": "^5.6.2",
52
53
  "chokidar": "^3.6.0",