@ff-labs/fff-node 0.10.4-nightly.e2cad2f → 0.10.5-dev.774d6bc

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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1533 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
8
+ var __toCommonJS = (from) => {
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
+ if (entry)
11
+ return entry;
12
+ entry = __defProp({}, "__esModule", { value: true });
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ __moduleCache.set(from, entry);
22
+ return entry;
23
+ };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
29
+ var __export = (target, all) => {
30
+ for (var name in all)
31
+ __defProp(target, name, {
32
+ get: all[name],
33
+ enumerable: true,
34
+ configurable: true,
35
+ set: __exportSetter.bind(all, name)
36
+ });
37
+ };
38
+
39
+ // src/index.ts
40
+ var exports_src = {};
41
+ __export(exports_src, {
42
+ ok: () => ok,
43
+ getTriple: () => getTriple,
44
+ getNpmPackageName: () => getNpmPackageName,
45
+ getLibFilename: () => getLibFilename,
46
+ getLibExtension: () => getLibExtension,
47
+ findBinary: () => findBinary,
48
+ err: () => err,
49
+ closeLibrary: () => closeLibrary,
50
+ binaryExists: () => binaryExists,
51
+ FileFinder: () => FileFinder
52
+ });
53
+ module.exports = __toCommonJS(exports_src);
54
+
55
+ // src/binary.ts
56
+ var import_node_fs = require("node:fs");
57
+ var import_node_module = require("node:module");
58
+ var import_node_path = require("node:path");
59
+ var import_node_url = require("node:url");
60
+
61
+ // src/platform.ts
62
+ var import_node_child_process = require("node:child_process");
63
+ function getTriple() {
64
+ const platform = process.platform;
65
+ const arch = process.arch;
66
+ let osName;
67
+ if (platform === "darwin") {
68
+ osName = "apple-darwin";
69
+ } else if (platform === "android") {
70
+ osName = "linux-android";
71
+ } else if (platform === "linux") {
72
+ osName = detectLinuxLibc();
73
+ } else if (platform === "win32") {
74
+ osName = "pc-windows-msvc";
75
+ } else {
76
+ throw new Error(`Unsupported platform: ${platform}`);
77
+ }
78
+ const archName = normalizeArch(arch);
79
+ return `${archName}-${osName}`;
80
+ }
81
+ function detectLinuxLibc() {
82
+ let output = "";
83
+ try {
84
+ output = import_node_child_process.execSync("ldd --version 2>&1", {
85
+ encoding: "utf-8",
86
+ timeout: 5000
87
+ });
88
+ } catch (e) {
89
+ const err = e;
90
+ output = String(err?.stdout ?? "") + String(err?.stderr ?? "");
91
+ }
92
+ if (output.toLowerCase().includes("musl")) {
93
+ return "unknown-linux-musl";
94
+ }
95
+ return "unknown-linux-gnu";
96
+ }
97
+ function normalizeArch(arch) {
98
+ switch (arch) {
99
+ case "x64":
100
+ case "amd64":
101
+ return "x86_64";
102
+ case "arm64":
103
+ return "aarch64";
104
+ case "arm":
105
+ return "arm";
106
+ default:
107
+ throw new Error(`Unsupported architecture: ${arch}`);
108
+ }
109
+ }
110
+ function getLibExtension() {
111
+ switch (process.platform) {
112
+ case "darwin":
113
+ return "dylib";
114
+ case "win32":
115
+ return "dll";
116
+ default:
117
+ return "so";
118
+ }
119
+ }
120
+ function getLibPrefix() {
121
+ return process.platform === "win32" ? "" : "lib";
122
+ }
123
+ function getLibFilename() {
124
+ const prefix = getLibPrefix();
125
+ const ext = getLibExtension();
126
+ return `${prefix}fff_c.${ext}`;
127
+ }
128
+ var TRIPLE_TO_NPM_PACKAGE = {
129
+ "aarch64-apple-darwin": "@ff-labs/fff-bin-darwin-arm64",
130
+ "x86_64-apple-darwin": "@ff-labs/fff-bin-darwin-x64",
131
+ "x86_64-unknown-linux-gnu": "@ff-labs/fff-bin-linux-x64-gnu",
132
+ "aarch64-unknown-linux-gnu": "@ff-labs/fff-bin-linux-arm64-gnu",
133
+ "x86_64-unknown-linux-musl": "@ff-labs/fff-bin-linux-x64-musl",
134
+ "aarch64-unknown-linux-musl": "@ff-labs/fff-bin-linux-arm64-musl",
135
+ "x86_64-pc-windows-msvc": "@ff-labs/fff-bin-win32-x64",
136
+ "aarch64-pc-windows-msvc": "@ff-labs/fff-bin-win32-arm64",
137
+ "aarch64-linux-android": "@ff-labs/fff-bin-android-arm64"
138
+ };
139
+ function getNpmPackageName() {
140
+ const triple = getTriple();
141
+ const packageName = TRIPLE_TO_NPM_PACKAGE[triple];
142
+ if (!packageName) {
143
+ throw new Error(`No npm package available for platform: ${triple}`);
144
+ }
145
+ return packageName;
146
+ }
147
+
148
+ // src/binary.ts
149
+ var __dirname = "/home/runner/work/fff/fff/packages/fff-node/src";
150
+ function getCurrentDir() {
151
+ if (typeof __dirname !== "undefined")
152
+ return __dirname;
153
+ const url = "file:///home/runner/work/fff/fff/packages/fff-node/src/binary.ts";
154
+ if (url.startsWith("file://")) {
155
+ return import_node_path.dirname(import_node_url.fileURLToPath(url));
156
+ }
157
+ return import_node_path.dirname(url);
158
+ }
159
+ function getPackageDir() {
160
+ const currentDir = getCurrentDir();
161
+ let dir = currentDir;
162
+ for (let i = 0;i < 5; i++) {
163
+ if (import_node_fs.existsSync(import_node_path.join(dir, "package.json"))) {
164
+ try {
165
+ const pkg = JSON.parse(import_node_fs.readFileSync(import_node_path.join(dir, "package.json"), "utf-8"));
166
+ if (pkg.name === "@ff-labs/fff-node") {
167
+ return dir;
168
+ }
169
+ } catch {}
170
+ }
171
+ dir = import_node_path.dirname(dir);
172
+ }
173
+ return import_node_path.dirname(currentDir);
174
+ }
175
+ function binaryExists() {
176
+ return findBinary() !== null;
177
+ }
178
+ function resolveFromNpmPackage() {
179
+ const packageName = getNpmPackageName();
180
+ try {
181
+ const require2 = import_node_module.createRequire(import_node_path.join(getPackageDir(), "package.json"));
182
+ const packageJsonPath = require2.resolve(`${packageName}/package.json`);
183
+ const packageDir = import_node_path.dirname(packageJsonPath);
184
+ const binaryPath = import_node_path.join(packageDir, getLibFilename());
185
+ if (import_node_fs.existsSync(binaryPath)) {
186
+ return binaryPath;
187
+ }
188
+ } catch {}
189
+ return null;
190
+ }
191
+ function getDevBinaryPath() {
192
+ const packageDir = getPackageDir();
193
+ const workspaceRoot = import_node_path.join(packageDir, "..", "..");
194
+ const possiblePaths = [
195
+ import_node_path.join(workspaceRoot, "target", "release", getLibFilename()),
196
+ import_node_path.join(workspaceRoot, "target", "debug", getLibFilename())
197
+ ];
198
+ for (const path of possiblePaths) {
199
+ if (import_node_fs.existsSync(path)) {
200
+ return path;
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ function isDevWorkspace() {
206
+ const packageDir = getPackageDir();
207
+ const workspaceRoot = import_node_path.join(packageDir, "..", "..");
208
+ return import_node_fs.existsSync(import_node_path.join(workspaceRoot, "Cargo.toml"));
209
+ }
210
+ function findBinary() {
211
+ if (isDevWorkspace()) {
212
+ const binPath = import_node_path.join(getPackageDir(), "bin", getLibFilename());
213
+ if (import_node_fs.existsSync(binPath))
214
+ return binPath;
215
+ const devPath = getDevBinaryPath();
216
+ if (devPath)
217
+ return devPath;
218
+ const npmPath2 = resolveFromNpmPackage();
219
+ if (npmPath2)
220
+ return npmPath2;
221
+ return null;
222
+ }
223
+ const npmPath = resolveFromNpmPackage();
224
+ if (npmPath)
225
+ return npmPath;
226
+ return getDevBinaryPath();
227
+ }
228
+ // src/ffi.ts
229
+ var import_ffi_rs = require("ffi-rs");
230
+
231
+ // src/fff-api.ts
232
+ function ok(value) {
233
+ return { ok: true, value };
234
+ }
235
+ function err(error) {
236
+ return { ok: false, error };
237
+ }
238
+ function createGrepCursor(offset) {
239
+ return { __brand: "GrepCursor", _offset: offset };
240
+ }
241
+
242
+ // src/ffi.ts
243
+ var LIBRARY_KEY = "fff_c";
244
+ var FFF_CREATE_OPTIONS_STRUCT = {
245
+ version: import_ffi_rs.DataType.U32,
246
+ base_path: import_ffi_rs.DataType.String,
247
+ frecency_db_path: import_ffi_rs.DataType.String,
248
+ history_db_path: import_ffi_rs.DataType.String,
249
+ enable_mmap_cache: import_ffi_rs.DataType.U8,
250
+ enable_content_indexing: import_ffi_rs.DataType.U8,
251
+ watch: import_ffi_rs.DataType.U8,
252
+ ai_mode: import_ffi_rs.DataType.U8,
253
+ log_file_path: import_ffi_rs.DataType.String,
254
+ log_level: import_ffi_rs.DataType.String,
255
+ cache_budget_max_files: import_ffi_rs.DataType.U64,
256
+ cache_budget_max_bytes: import_ffi_rs.DataType.U64,
257
+ cache_budget_max_file_size: import_ffi_rs.DataType.U64,
258
+ enable_fs_root_scanning: import_ffi_rs.DataType.U8,
259
+ enable_home_dir_scanning: import_ffi_rs.DataType.U8,
260
+ follow_symlinks: import_ffi_rs.DataType.U8
261
+ };
262
+ var FFF_CREATE_OPTIONS_VERSION = 2;
263
+ var GREP_MODE_PLAIN = 0;
264
+ var GREP_MODE_REGEX = 1;
265
+ var GREP_MODE_FUZZY = 2;
266
+ function grepModeToU8(mode) {
267
+ switch (mode) {
268
+ case "regex":
269
+ return GREP_MODE_REGEX;
270
+ case "fuzzy":
271
+ return GREP_MODE_FUZZY;
272
+ default:
273
+ return GREP_MODE_PLAIN;
274
+ }
275
+ }
276
+ var isLoaded = false;
277
+ var FFF_RESULT_STRUCT = {
278
+ success: import_ffi_rs.DataType.U8,
279
+ error: import_ffi_rs.DataType.External,
280
+ handle: import_ffi_rs.DataType.External,
281
+ int_value: import_ffi_rs.DataType.I64
282
+ };
283
+ function loadLibrary() {
284
+ if (isLoaded)
285
+ return;
286
+ const binaryPath = findBinary();
287
+ if (!binaryPath) {
288
+ throw new Error("fff native library not found. Run `npx @ff-labs/fff-node download` or build from source with `cargo build --release -p fff-c`");
289
+ }
290
+ import_ffi_rs.open({ library: LIBRARY_KEY, path: binaryPath });
291
+ isLoaded = true;
292
+ }
293
+ function snakeToCamel(obj) {
294
+ if (obj === null || obj === undefined)
295
+ return obj;
296
+ if (typeof obj !== "object")
297
+ return obj;
298
+ if (Array.isArray(obj))
299
+ return obj.map(snakeToCamel);
300
+ const result = {};
301
+ for (const [key, value] of Object.entries(obj)) {
302
+ const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
303
+ result[camelKey] = snakeToCamel(value);
304
+ }
305
+ return result;
306
+ }
307
+ function readCString(ptr) {
308
+ if (import_ffi_rs.isNullPointer(ptr))
309
+ return null;
310
+ try {
311
+ const [str] = import_ffi_rs.restorePointer({
312
+ retType: [import_ffi_rs.DataType.String],
313
+ paramsValue: import_ffi_rs.wrapPointer([ptr])
314
+ });
315
+ return str;
316
+ } catch {
317
+ return null;
318
+ }
319
+ }
320
+ function callRaw(funcName, paramsType, paramsValue) {
321
+ const rawPtr = import_ffi_rs.load({
322
+ library: LIBRARY_KEY,
323
+ funcName,
324
+ retType: import_ffi_rs.DataType.External,
325
+ paramsType,
326
+ paramsValue,
327
+ freeResultMemory: false
328
+ });
329
+ const [structData] = import_ffi_rs.restorePointer({
330
+ retType: [FFF_RESULT_STRUCT],
331
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
332
+ });
333
+ return { rawPtr, struct: structData };
334
+ }
335
+ function freeResult(resultPtr) {
336
+ try {
337
+ import_ffi_rs.load({
338
+ library: LIBRARY_KEY,
339
+ funcName: "fff_free_result",
340
+ retType: import_ffi_rs.DataType.Void,
341
+ paramsType: [import_ffi_rs.DataType.External],
342
+ paramsValue: [resultPtr]
343
+ });
344
+ } catch {}
345
+ }
346
+ function readResultEnvelope(funcName, paramsType, paramsValue) {
347
+ loadLibrary();
348
+ const { rawPtr, struct: structData } = callRaw(funcName, paramsType, paramsValue);
349
+ if (structData.success === 0) {
350
+ const errorStr = readCString(structData.error);
351
+ freeResult(rawPtr);
352
+ return err(errorStr || "Unknown error");
353
+ }
354
+ return { rawPtr, struct: structData };
355
+ }
356
+ function callVoidResult(funcName, paramsType, paramsValue) {
357
+ const res = readResultEnvelope(funcName, paramsType, paramsValue);
358
+ if ("ok" in res)
359
+ return res;
360
+ freeResult(res.rawPtr);
361
+ return { ok: true, value: undefined };
362
+ }
363
+ function callIntResult(funcName, paramsType, paramsValue) {
364
+ const res = readResultEnvelope(funcName, paramsType, paramsValue);
365
+ if ("ok" in res)
366
+ return res;
367
+ const value = Number(res.struct.int_value);
368
+ freeResult(res.rawPtr);
369
+ return { ok: true, value };
370
+ }
371
+ function callBoolResult(funcName, paramsType, paramsValue) {
372
+ const res = readResultEnvelope(funcName, paramsType, paramsValue);
373
+ if ("ok" in res)
374
+ return res;
375
+ const value = Number(res.struct.int_value) !== 0;
376
+ freeResult(res.rawPtr);
377
+ return { ok: true, value };
378
+ }
379
+ function callStringResult(funcName, paramsType, paramsValue) {
380
+ const res = readResultEnvelope(funcName, paramsType, paramsValue);
381
+ if ("ok" in res)
382
+ return res;
383
+ const handlePtr = res.struct.handle;
384
+ freeResult(res.rawPtr);
385
+ if (import_ffi_rs.isNullPointer(handlePtr))
386
+ return { ok: true, value: null };
387
+ const str = readCString(handlePtr);
388
+ freeString(handlePtr);
389
+ return { ok: true, value: str };
390
+ }
391
+ function callJsonResult(funcName, paramsType, paramsValue) {
392
+ const res = readResultEnvelope(funcName, paramsType, paramsValue);
393
+ if ("ok" in res)
394
+ return res;
395
+ const handlePtr = res.struct.handle;
396
+ freeResult(res.rawPtr);
397
+ if (import_ffi_rs.isNullPointer(handlePtr))
398
+ return { ok: true, value: undefined };
399
+ const jsonStr = readCString(handlePtr);
400
+ freeString(handlePtr);
401
+ if (jsonStr === null || jsonStr === "")
402
+ return { ok: true, value: undefined };
403
+ try {
404
+ return { ok: true, value: snakeToCamel(JSON.parse(jsonStr)) };
405
+ } catch {
406
+ return { ok: true, value: jsonStr };
407
+ }
408
+ }
409
+ function freeString(ptr) {
410
+ try {
411
+ import_ffi_rs.load({
412
+ library: LIBRARY_KEY,
413
+ funcName: "fff_free_string",
414
+ retType: import_ffi_rs.DataType.Void,
415
+ paramsType: [import_ffi_rs.DataType.External],
416
+ paramsValue: [ptr]
417
+ });
418
+ } catch {}
419
+ }
420
+ function ffiCreate(basePath, frecencyDbPath, historyDbPath, _useUnsafeNoLock, enableMmapCache, enableContentIndexing, watch, aiMode, logFilePath, logLevel, cacheBudgetMaxFiles, cacheBudgetMaxBytes, cacheBudgetMaxFileSize, enableFsRootScanning, enableHomeDirScanning, followSymlinks) {
421
+ loadLibrary();
422
+ const optsValue = {
423
+ version: FFF_CREATE_OPTIONS_VERSION,
424
+ base_path: basePath,
425
+ frecency_db_path: frecencyDbPath,
426
+ history_db_path: historyDbPath,
427
+ enable_mmap_cache: enableMmapCache ? 1 : 0,
428
+ enable_content_indexing: enableContentIndexing ? 1 : 0,
429
+ watch: watch ? 1 : 0,
430
+ ai_mode: aiMode ? 1 : 0,
431
+ log_file_path: logFilePath,
432
+ log_level: logLevel,
433
+ cache_budget_max_files: cacheBudgetMaxFiles,
434
+ cache_budget_max_bytes: cacheBudgetMaxBytes,
435
+ cache_budget_max_file_size: cacheBudgetMaxFileSize,
436
+ enable_fs_root_scanning: enableFsRootScanning ? 1 : 0,
437
+ enable_home_dir_scanning: enableHomeDirScanning ? 1 : 0,
438
+ follow_symlinks: followSymlinks ? 1 : 0
439
+ };
440
+ const rawPtr = import_ffi_rs.load({
441
+ library: LIBRARY_KEY,
442
+ funcName: "fff_create_instance_with",
443
+ retType: import_ffi_rs.DataType.External,
444
+ paramsType: [FFF_CREATE_OPTIONS_STRUCT],
445
+ paramsValue: [optsValue],
446
+ freeResultMemory: false
447
+ });
448
+ const [structData] = import_ffi_rs.restorePointer({
449
+ retType: [FFF_RESULT_STRUCT],
450
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
451
+ });
452
+ const success = structData.success !== 0;
453
+ try {
454
+ if (success) {
455
+ const handle = structData.handle;
456
+ if (import_ffi_rs.isNullPointer(handle)) {
457
+ return err("fff_create_instance_with returned null handle");
458
+ }
459
+ return { ok: true, value: handle };
460
+ } else {
461
+ const errorStr = readCString(structData.error);
462
+ return err(errorStr || "Unknown error");
463
+ }
464
+ } finally {
465
+ freeResult(rawPtr);
466
+ }
467
+ }
468
+ function ffiDestroy(handle) {
469
+ loadLibrary();
470
+ import_ffi_rs.load({
471
+ library: LIBRARY_KEY,
472
+ funcName: "fff_destroy",
473
+ retType: import_ffi_rs.DataType.Void,
474
+ paramsType: [import_ffi_rs.DataType.External],
475
+ paramsValue: [handle]
476
+ });
477
+ }
478
+ var FFF_FILE_ITEM_STRUCT = {
479
+ relative_path: import_ffi_rs.DataType.External,
480
+ file_name: import_ffi_rs.DataType.External,
481
+ git_status: import_ffi_rs.DataType.External,
482
+ size: import_ffi_rs.DataType.U64,
483
+ modified: import_ffi_rs.DataType.U64,
484
+ access_frecency_score: import_ffi_rs.DataType.I64,
485
+ modification_frecency_score: import_ffi_rs.DataType.I64,
486
+ total_frecency_score: import_ffi_rs.DataType.I64,
487
+ is_binary: import_ffi_rs.DataType.U8
488
+ };
489
+ var FFF_SCORE_STRUCT = {
490
+ total: import_ffi_rs.DataType.I32,
491
+ base_score: import_ffi_rs.DataType.I32,
492
+ filename_bonus: import_ffi_rs.DataType.I32,
493
+ special_filename_bonus: import_ffi_rs.DataType.I32,
494
+ frecency_boost: import_ffi_rs.DataType.I32,
495
+ distance_penalty: import_ffi_rs.DataType.I32,
496
+ current_file_penalty: import_ffi_rs.DataType.I32,
497
+ combo_match_boost: import_ffi_rs.DataType.I32,
498
+ exact_match: import_ffi_rs.DataType.U8,
499
+ match_type: import_ffi_rs.DataType.External
500
+ };
501
+ var FFF_SEARCH_RESULT_STRUCT = {
502
+ items: import_ffi_rs.DataType.External,
503
+ scores: import_ffi_rs.DataType.External,
504
+ count: import_ffi_rs.DataType.U32,
505
+ total_matched: import_ffi_rs.DataType.U32,
506
+ total_files: import_ffi_rs.DataType.U32,
507
+ location_tag: import_ffi_rs.DataType.U8,
508
+ location_line: import_ffi_rs.DataType.I32,
509
+ location_col: import_ffi_rs.DataType.I32,
510
+ location_end_line: import_ffi_rs.DataType.I32,
511
+ location_end_col: import_ffi_rs.DataType.I32
512
+ };
513
+ var FFF_DIR_ITEM_STRUCT = {
514
+ relative_path: import_ffi_rs.DataType.External,
515
+ dir_name: import_ffi_rs.DataType.External,
516
+ max_access_frecency: import_ffi_rs.DataType.I32
517
+ };
518
+ var FFF_DIR_SEARCH_RESULT_STRUCT = {
519
+ items: import_ffi_rs.DataType.External,
520
+ scores: import_ffi_rs.DataType.External,
521
+ count: import_ffi_rs.DataType.U32,
522
+ total_matched: import_ffi_rs.DataType.U32,
523
+ total_dirs: import_ffi_rs.DataType.U32
524
+ };
525
+ var FFF_MIXED_ITEM_STRUCT = {
526
+ item_type: import_ffi_rs.DataType.U8,
527
+ relative_path: import_ffi_rs.DataType.External,
528
+ display_name: import_ffi_rs.DataType.External,
529
+ git_status: import_ffi_rs.DataType.External,
530
+ size: import_ffi_rs.DataType.U64,
531
+ modified: import_ffi_rs.DataType.U64,
532
+ access_frecency_score: import_ffi_rs.DataType.I64,
533
+ modification_frecency_score: import_ffi_rs.DataType.I64,
534
+ total_frecency_score: import_ffi_rs.DataType.I64,
535
+ is_binary: import_ffi_rs.DataType.U8
536
+ };
537
+ var FFF_MIXED_SEARCH_RESULT_STRUCT = {
538
+ items: import_ffi_rs.DataType.External,
539
+ scores: import_ffi_rs.DataType.External,
540
+ count: import_ffi_rs.DataType.U32,
541
+ total_matched: import_ffi_rs.DataType.U32,
542
+ total_files: import_ffi_rs.DataType.U32,
543
+ total_dirs: import_ffi_rs.DataType.U32,
544
+ location_tag: import_ffi_rs.DataType.U8,
545
+ location_line: import_ffi_rs.DataType.I32,
546
+ location_col: import_ffi_rs.DataType.I32,
547
+ location_end_line: import_ffi_rs.DataType.I32,
548
+ location_end_col: import_ffi_rs.DataType.I32
549
+ };
550
+ var FFF_GREP_MATCH_STRUCT = {
551
+ relative_path: import_ffi_rs.DataType.External,
552
+ file_name: import_ffi_rs.DataType.External,
553
+ git_status: import_ffi_rs.DataType.External,
554
+ line_content: import_ffi_rs.DataType.External,
555
+ match_ranges: import_ffi_rs.DataType.External,
556
+ context_before: import_ffi_rs.DataType.External,
557
+ context_after: import_ffi_rs.DataType.External,
558
+ size: import_ffi_rs.DataType.U64,
559
+ modified: import_ffi_rs.DataType.U64,
560
+ total_frecency_score: import_ffi_rs.DataType.I64,
561
+ access_frecency_score: import_ffi_rs.DataType.I64,
562
+ modification_frecency_score: import_ffi_rs.DataType.I64,
563
+ line_number: import_ffi_rs.DataType.U64,
564
+ byte_offset: import_ffi_rs.DataType.U64,
565
+ col: import_ffi_rs.DataType.U32,
566
+ match_ranges_count: import_ffi_rs.DataType.U32,
567
+ context_before_count: import_ffi_rs.DataType.U32,
568
+ context_after_count: import_ffi_rs.DataType.U32,
569
+ fuzzy_score: import_ffi_rs.DataType.U32,
570
+ has_fuzzy_score: import_ffi_rs.DataType.U8,
571
+ is_binary: import_ffi_rs.DataType.U8,
572
+ is_definition: import_ffi_rs.DataType.U8
573
+ };
574
+ var FFF_GREP_RESULT_STRUCT = {
575
+ items: import_ffi_rs.DataType.External,
576
+ count: import_ffi_rs.DataType.U32,
577
+ total_matched: import_ffi_rs.DataType.U32,
578
+ total_files_searched: import_ffi_rs.DataType.U32,
579
+ total_files: import_ffi_rs.DataType.U32,
580
+ filtered_file_count: import_ffi_rs.DataType.U32,
581
+ next_file_offset: import_ffi_rs.DataType.U32,
582
+ regex_fallback_error: import_ffi_rs.DataType.External
583
+ };
584
+ var FFF_MATCH_RANGE_STRUCT = {
585
+ start: import_ffi_rs.DataType.U32,
586
+ end: import_ffi_rs.DataType.U32
587
+ };
588
+ function readFileItemFromRaw(raw) {
589
+ return {
590
+ relativePath: readCString(raw.relative_path) ?? "",
591
+ fileName: readCString(raw.file_name) ?? "",
592
+ gitStatus: readCString(raw.git_status) ?? "",
593
+ size: Number(raw.size),
594
+ modified: Number(raw.modified),
595
+ accessFrecencyScore: Number(raw.access_frecency_score),
596
+ modificationFrecencyScore: Number(raw.modification_frecency_score),
597
+ totalFrecencyScore: Number(raw.total_frecency_score)
598
+ };
599
+ }
600
+ function readScoreFromRaw(raw) {
601
+ return {
602
+ total: raw.total,
603
+ baseScore: raw.base_score,
604
+ filenameBonus: raw.filename_bonus,
605
+ specialFilenameBonus: raw.special_filename_bonus,
606
+ frecencyBoost: raw.frecency_boost,
607
+ distancePenalty: raw.distance_penalty,
608
+ currentFilePenalty: raw.current_file_penalty,
609
+ comboMatchBoost: raw.combo_match_boost,
610
+ exactMatch: raw.exact_match !== 0,
611
+ matchType: readCString(raw.match_type) ?? ""
612
+ };
613
+ }
614
+ function readDirItemFromRaw(raw) {
615
+ return {
616
+ relativePath: readCString(raw.relative_path) ?? "",
617
+ dirName: readCString(raw.dir_name) ?? "",
618
+ maxAccessFrecency: raw.max_access_frecency
619
+ };
620
+ }
621
+ function readMixedItemFromRaw(raw) {
622
+ if (raw.item_type === 1) {
623
+ return {
624
+ type: "directory",
625
+ item: {
626
+ relativePath: readCString(raw.relative_path) ?? "",
627
+ dirName: readCString(raw.display_name) ?? "",
628
+ maxAccessFrecency: Number(raw.access_frecency_score)
629
+ }
630
+ };
631
+ }
632
+ return {
633
+ type: "file",
634
+ item: {
635
+ relativePath: readCString(raw.relative_path) ?? "",
636
+ fileName: readCString(raw.display_name) ?? "",
637
+ gitStatus: readCString(raw.git_status) ?? "",
638
+ size: Number(raw.size),
639
+ modified: Number(raw.modified),
640
+ accessFrecencyScore: Number(raw.access_frecency_score),
641
+ modificationFrecencyScore: Number(raw.modification_frecency_score),
642
+ totalFrecencyScore: Number(raw.total_frecency_score)
643
+ }
644
+ };
645
+ }
646
+ function callAccessor(funcName, resultPtr, index, structDef) {
647
+ loadLibrary();
648
+ const elemPtr = import_ffi_rs.load({
649
+ library: LIBRARY_KEY,
650
+ funcName,
651
+ retType: import_ffi_rs.DataType.External,
652
+ paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U32],
653
+ paramsValue: [resultPtr, index]
654
+ });
655
+ const [raw] = import_ffi_rs.restorePointer({
656
+ retType: [structDef],
657
+ paramsValue: import_ffi_rs.wrapPointer([elemPtr])
658
+ });
659
+ return raw;
660
+ }
661
+ function ptrOffset(base, bytes) {
662
+ return import_ffi_rs.load({
663
+ library: LIBRARY_KEY,
664
+ funcName: "fff_ptr_offset",
665
+ retType: import_ffi_rs.DataType.External,
666
+ paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64],
667
+ paramsValue: [base, bytes]
668
+ });
669
+ }
670
+ function readCStringArray(ptrArray, count) {
671
+ if (count === 0 || import_ffi_rs.isNullPointer(ptrArray))
672
+ return [];
673
+ const result = [];
674
+ for (let i = 0;i < count; i++) {
675
+ const elemPtr = ptrOffset(ptrArray, i * 8);
676
+ const [charPtr] = import_ffi_rs.restorePointer({
677
+ retType: [import_ffi_rs.DataType.External],
678
+ paramsValue: [elemPtr]
679
+ });
680
+ result.push(readCString(charPtr) ?? "");
681
+ }
682
+ return result;
683
+ }
684
+ function readGrepMatchFromRaw(raw) {
685
+ const matchRanges = [];
686
+ for (let i = 0;i < raw.match_ranges_count; i++) {
687
+ const rangePtr = ptrOffset(raw.match_ranges, i * 8);
688
+ const [rangeRaw] = import_ffi_rs.restorePointer({
689
+ retType: [FFF_MATCH_RANGE_STRUCT],
690
+ paramsValue: import_ffi_rs.wrapPointer([rangePtr])
691
+ });
692
+ matchRanges.push([rangeRaw.start, rangeRaw.end]);
693
+ }
694
+ const match = {
695
+ relativePath: readCString(raw.relative_path) ?? "",
696
+ fileName: readCString(raw.file_name) ?? "",
697
+ gitStatus: readCString(raw.git_status) ?? "",
698
+ lineContent: readCString(raw.line_content) ?? "",
699
+ size: Number(raw.size),
700
+ modified: Number(raw.modified),
701
+ totalFrecencyScore: Number(raw.total_frecency_score),
702
+ accessFrecencyScore: Number(raw.access_frecency_score),
703
+ modificationFrecencyScore: Number(raw.modification_frecency_score),
704
+ isBinary: raw.is_binary !== 0,
705
+ lineNumber: Number(raw.line_number),
706
+ col: raw.col,
707
+ byteOffset: Number(raw.byte_offset),
708
+ matchRanges
709
+ };
710
+ if (raw.has_fuzzy_score !== 0) {
711
+ match.fuzzyScore = raw.fuzzy_score;
712
+ }
713
+ if (raw.context_before_count > 0) {
714
+ match.contextBefore = readCStringArray(raw.context_before, raw.context_before_count);
715
+ }
716
+ if (raw.context_after_count > 0) {
717
+ match.contextAfter = readCStringArray(raw.context_after, raw.context_after_count);
718
+ }
719
+ if (raw.is_definition !== 0) {
720
+ match.isDefinition = true;
721
+ }
722
+ return match;
723
+ }
724
+ function parseGrepResult(rawPtr) {
725
+ loadLibrary();
726
+ const [envelope] = import_ffi_rs.restorePointer({
727
+ retType: [FFF_RESULT_STRUCT],
728
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
729
+ });
730
+ const success = envelope.success !== 0;
731
+ if (!success) {
732
+ const errorMsg = readCString(envelope.error) || "Unknown error";
733
+ freeResult(rawPtr);
734
+ return err(errorMsg);
735
+ }
736
+ const handlePtr = envelope.handle;
737
+ freeResult(rawPtr);
738
+ if (import_ffi_rs.isNullPointer(handlePtr)) {
739
+ return err("grep returned null result");
740
+ }
741
+ const [gr] = import_ffi_rs.restorePointer({
742
+ retType: [FFF_GREP_RESULT_STRUCT],
743
+ paramsValue: import_ffi_rs.wrapPointer([handlePtr])
744
+ });
745
+ const count = gr.count;
746
+ const regexFallbackError = readCString(gr.regex_fallback_error) ?? undefined;
747
+ const items = [];
748
+ for (let i = 0;i < count; i++) {
749
+ const rawMatch = callAccessor("fff_grep_result_get_match", handlePtr, i, FFF_GREP_MATCH_STRUCT);
750
+ items.push(readGrepMatchFromRaw(rawMatch));
751
+ }
752
+ import_ffi_rs.load({
753
+ library: LIBRARY_KEY,
754
+ funcName: "fff_free_grep_result",
755
+ retType: import_ffi_rs.DataType.Void,
756
+ paramsType: [import_ffi_rs.DataType.External],
757
+ paramsValue: [handlePtr]
758
+ });
759
+ const grepResult = {
760
+ items,
761
+ totalMatched: gr.total_matched,
762
+ totalFilesSearched: gr.total_files_searched,
763
+ totalFiles: gr.total_files,
764
+ filteredFileCount: gr.filtered_file_count,
765
+ nextCursor: gr.next_file_offset > 0 ? createGrepCursor(gr.next_file_offset) : null
766
+ };
767
+ if (regexFallbackError) {
768
+ grepResult.regexFallbackError = regexFallbackError;
769
+ }
770
+ return { ok: true, value: grepResult };
771
+ }
772
+ function parseSearchResult(rawPtr) {
773
+ loadLibrary();
774
+ const [envelope] = import_ffi_rs.restorePointer({
775
+ retType: [FFF_RESULT_STRUCT],
776
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
777
+ });
778
+ const success = envelope.success !== 0;
779
+ if (!success) {
780
+ const errorMsg = readCString(envelope.error) || "Unknown error";
781
+ freeResult(rawPtr);
782
+ return err(errorMsg);
783
+ }
784
+ const handlePtr = envelope.handle;
785
+ freeResult(rawPtr);
786
+ if (import_ffi_rs.isNullPointer(handlePtr)) {
787
+ return err("fff_search returned null search result");
788
+ }
789
+ const [sr] = import_ffi_rs.restorePointer({
790
+ retType: [FFF_SEARCH_RESULT_STRUCT],
791
+ paramsValue: import_ffi_rs.wrapPointer([handlePtr])
792
+ });
793
+ const count = sr.count;
794
+ let location;
795
+ if (sr.location_tag === 1) {
796
+ location = { type: "line", line: sr.location_line };
797
+ } else if (sr.location_tag === 2) {
798
+ location = {
799
+ type: "position",
800
+ line: sr.location_line,
801
+ col: sr.location_col
802
+ };
803
+ } else if (sr.location_tag === 3) {
804
+ location = {
805
+ type: "range",
806
+ start: { line: sr.location_line, col: sr.location_col },
807
+ end: { line: sr.location_end_line, col: sr.location_end_col }
808
+ };
809
+ }
810
+ const items = [];
811
+ const scores = [];
812
+ for (let i = 0;i < count; i++) {
813
+ const rawItem = callAccessor("fff_search_result_get_item", handlePtr, i, FFF_FILE_ITEM_STRUCT);
814
+ items.push(readFileItemFromRaw(rawItem));
815
+ const rawScore = callAccessor("fff_search_result_get_score", handlePtr, i, FFF_SCORE_STRUCT);
816
+ scores.push(readScoreFromRaw(rawScore));
817
+ }
818
+ import_ffi_rs.load({
819
+ library: LIBRARY_KEY,
820
+ funcName: "fff_free_search_result",
821
+ retType: import_ffi_rs.DataType.Void,
822
+ paramsType: [import_ffi_rs.DataType.External],
823
+ paramsValue: [handlePtr]
824
+ });
825
+ const result = {
826
+ items,
827
+ scores,
828
+ totalMatched: sr.total_matched,
829
+ totalFiles: sr.total_files
830
+ };
831
+ if (location) {
832
+ result.location = location;
833
+ }
834
+ return { ok: true, value: result };
835
+ }
836
+ function parseDirSearchResult(rawPtr) {
837
+ loadLibrary();
838
+ const [envelope] = import_ffi_rs.restorePointer({
839
+ retType: [FFF_RESULT_STRUCT],
840
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
841
+ });
842
+ const success = envelope.success !== 0;
843
+ if (!success) {
844
+ const errorMsg = readCString(envelope.error) || "Unknown error";
845
+ freeResult(rawPtr);
846
+ return err(errorMsg);
847
+ }
848
+ const handlePtr = envelope.handle;
849
+ freeResult(rawPtr);
850
+ if (import_ffi_rs.isNullPointer(handlePtr)) {
851
+ return err("fff_search_directories returned null search result");
852
+ }
853
+ const [sr] = import_ffi_rs.restorePointer({
854
+ retType: [FFF_DIR_SEARCH_RESULT_STRUCT],
855
+ paramsValue: import_ffi_rs.wrapPointer([handlePtr])
856
+ });
857
+ const count = sr.count;
858
+ const items = [];
859
+ const scores = [];
860
+ for (let i = 0;i < count; i++) {
861
+ const rawItem = callAccessor("fff_dir_search_result_get_item", handlePtr, i, FFF_DIR_ITEM_STRUCT);
862
+ items.push(readDirItemFromRaw(rawItem));
863
+ const rawScore = callAccessor("fff_dir_search_result_get_score", handlePtr, i, FFF_SCORE_STRUCT);
864
+ scores.push(readScoreFromRaw(rawScore));
865
+ }
866
+ import_ffi_rs.load({
867
+ library: LIBRARY_KEY,
868
+ funcName: "fff_free_dir_search_result",
869
+ retType: import_ffi_rs.DataType.Void,
870
+ paramsType: [import_ffi_rs.DataType.External],
871
+ paramsValue: [handlePtr]
872
+ });
873
+ return {
874
+ ok: true,
875
+ value: {
876
+ items,
877
+ scores,
878
+ totalMatched: sr.total_matched,
879
+ totalDirs: sr.total_dirs
880
+ }
881
+ };
882
+ }
883
+ function parseMixedSearchResult(rawPtr) {
884
+ loadLibrary();
885
+ const [envelope] = import_ffi_rs.restorePointer({
886
+ retType: [FFF_RESULT_STRUCT],
887
+ paramsValue: import_ffi_rs.wrapPointer([rawPtr])
888
+ });
889
+ const success = envelope.success !== 0;
890
+ if (!success) {
891
+ const errorMsg = readCString(envelope.error) || "Unknown error";
892
+ freeResult(rawPtr);
893
+ return err(errorMsg);
894
+ }
895
+ const handlePtr = envelope.handle;
896
+ freeResult(rawPtr);
897
+ if (import_ffi_rs.isNullPointer(handlePtr)) {
898
+ return err("fff_search_mixed returned null search result");
899
+ }
900
+ const [sr] = import_ffi_rs.restorePointer({
901
+ retType: [FFF_MIXED_SEARCH_RESULT_STRUCT],
902
+ paramsValue: import_ffi_rs.wrapPointer([handlePtr])
903
+ });
904
+ const count = sr.count;
905
+ let location;
906
+ if (sr.location_tag === 1) {
907
+ location = { type: "line", line: sr.location_line };
908
+ } else if (sr.location_tag === 2) {
909
+ location = {
910
+ type: "position",
911
+ line: sr.location_line,
912
+ col: sr.location_col
913
+ };
914
+ } else if (sr.location_tag === 3) {
915
+ location = {
916
+ type: "range",
917
+ start: { line: sr.location_line, col: sr.location_col },
918
+ end: { line: sr.location_end_line, col: sr.location_end_col }
919
+ };
920
+ }
921
+ const items = [];
922
+ const scores = [];
923
+ for (let i = 0;i < count; i++) {
924
+ const rawItem = callAccessor("fff_mixed_search_result_get_item", handlePtr, i, FFF_MIXED_ITEM_STRUCT);
925
+ items.push(readMixedItemFromRaw(rawItem));
926
+ const rawScore = callAccessor("fff_mixed_search_result_get_score", handlePtr, i, FFF_SCORE_STRUCT);
927
+ scores.push(readScoreFromRaw(rawScore));
928
+ }
929
+ import_ffi_rs.load({
930
+ library: LIBRARY_KEY,
931
+ funcName: "fff_free_mixed_search_result",
932
+ retType: import_ffi_rs.DataType.Void,
933
+ paramsType: [import_ffi_rs.DataType.External],
934
+ paramsValue: [handlePtr]
935
+ });
936
+ const result = {
937
+ items,
938
+ scores,
939
+ totalMatched: sr.total_matched,
940
+ totalFiles: sr.total_files,
941
+ totalDirs: sr.total_dirs
942
+ };
943
+ if (location) {
944
+ result.location = location;
945
+ }
946
+ return { ok: true, value: result };
947
+ }
948
+ function ffiSearch(handle, query, currentFile, maxThreads, pageIndex, pageSize, comboBoostMultiplier, minComboCount) {
949
+ loadLibrary();
950
+ const rawPtr = import_ffi_rs.load({
951
+ library: LIBRARY_KEY,
952
+ funcName: "fff_search",
953
+ retType: import_ffi_rs.DataType.External,
954
+ paramsType: [
955
+ import_ffi_rs.DataType.External,
956
+ import_ffi_rs.DataType.String,
957
+ import_ffi_rs.DataType.String,
958
+ import_ffi_rs.DataType.U32,
959
+ import_ffi_rs.DataType.U32,
960
+ import_ffi_rs.DataType.U32,
961
+ import_ffi_rs.DataType.I32,
962
+ import_ffi_rs.DataType.U32
963
+ ],
964
+ paramsValue: [
965
+ handle,
966
+ query,
967
+ currentFile,
968
+ maxThreads,
969
+ pageIndex,
970
+ pageSize,
971
+ comboBoostMultiplier,
972
+ minComboCount
973
+ ],
974
+ freeResultMemory: false
975
+ });
976
+ return parseSearchResult(rawPtr);
977
+ }
978
+ function ffiGlob(handle, pattern, currentFile, maxThreads, pageIndex, pageSize) {
979
+ loadLibrary();
980
+ const rawPtr = import_ffi_rs.load({
981
+ library: LIBRARY_KEY,
982
+ funcName: "fff_glob",
983
+ retType: import_ffi_rs.DataType.External,
984
+ paramsType: [
985
+ import_ffi_rs.DataType.External,
986
+ import_ffi_rs.DataType.String,
987
+ import_ffi_rs.DataType.String,
988
+ import_ffi_rs.DataType.U32,
989
+ import_ffi_rs.DataType.U32,
990
+ import_ffi_rs.DataType.U32
991
+ ],
992
+ paramsValue: [handle, pattern, currentFile, maxThreads, pageIndex, pageSize],
993
+ freeResultMemory: false
994
+ });
995
+ return parseSearchResult(rawPtr);
996
+ }
997
+ function ffiSearchDirectories(handle, query, currentFile, maxThreads, pageIndex, pageSize) {
998
+ loadLibrary();
999
+ const rawPtr = import_ffi_rs.load({
1000
+ library: LIBRARY_KEY,
1001
+ funcName: "fff_search_directories",
1002
+ retType: import_ffi_rs.DataType.External,
1003
+ paramsType: [
1004
+ import_ffi_rs.DataType.External,
1005
+ import_ffi_rs.DataType.String,
1006
+ import_ffi_rs.DataType.String,
1007
+ import_ffi_rs.DataType.U32,
1008
+ import_ffi_rs.DataType.U32,
1009
+ import_ffi_rs.DataType.U32
1010
+ ],
1011
+ paramsValue: [handle, query, currentFile ?? "", maxThreads, pageIndex, pageSize],
1012
+ freeResultMemory: false
1013
+ });
1014
+ return parseDirSearchResult(rawPtr);
1015
+ }
1016
+ function ffiSearchMixed(handle, query, currentFile, maxThreads, pageIndex, pageSize, comboBoostMultiplier, minComboCount) {
1017
+ loadLibrary();
1018
+ const rawPtr = import_ffi_rs.load({
1019
+ library: LIBRARY_KEY,
1020
+ funcName: "fff_search_mixed",
1021
+ retType: import_ffi_rs.DataType.External,
1022
+ paramsType: [
1023
+ import_ffi_rs.DataType.External,
1024
+ import_ffi_rs.DataType.String,
1025
+ import_ffi_rs.DataType.String,
1026
+ import_ffi_rs.DataType.U32,
1027
+ import_ffi_rs.DataType.U32,
1028
+ import_ffi_rs.DataType.U32,
1029
+ import_ffi_rs.DataType.I32,
1030
+ import_ffi_rs.DataType.U32
1031
+ ],
1032
+ paramsValue: [
1033
+ handle,
1034
+ query,
1035
+ currentFile,
1036
+ maxThreads,
1037
+ pageIndex,
1038
+ pageSize,
1039
+ comboBoostMultiplier,
1040
+ minComboCount
1041
+ ],
1042
+ freeResultMemory: false
1043
+ });
1044
+ return parseMixedSearchResult(rawPtr);
1045
+ }
1046
+ function ffiLiveGrep(handle, query, mode, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
1047
+ loadLibrary();
1048
+ const rawPtr = import_ffi_rs.load({
1049
+ library: LIBRARY_KEY,
1050
+ funcName: "fff_live_grep",
1051
+ retType: import_ffi_rs.DataType.External,
1052
+ paramsType: [
1053
+ import_ffi_rs.DataType.External,
1054
+ import_ffi_rs.DataType.String,
1055
+ import_ffi_rs.DataType.U8,
1056
+ import_ffi_rs.DataType.U64,
1057
+ import_ffi_rs.DataType.U32,
1058
+ import_ffi_rs.DataType.Boolean,
1059
+ import_ffi_rs.DataType.U32,
1060
+ import_ffi_rs.DataType.U32,
1061
+ import_ffi_rs.DataType.U64,
1062
+ import_ffi_rs.DataType.U32,
1063
+ import_ffi_rs.DataType.U32,
1064
+ import_ffi_rs.DataType.Boolean
1065
+ ],
1066
+ paramsValue: [
1067
+ handle,
1068
+ query,
1069
+ grepModeToU8(mode),
1070
+ maxFileSize,
1071
+ maxMatchesPerFile,
1072
+ smartCase,
1073
+ fileOffset,
1074
+ pageLimit,
1075
+ timeBudgetMs,
1076
+ beforeContext,
1077
+ afterContext,
1078
+ classifyDefinitions
1079
+ ],
1080
+ freeResultMemory: false
1081
+ });
1082
+ return parseGrepResult(rawPtr);
1083
+ }
1084
+ function ffiMultiGrep(handle, patternsJoined, constraints, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
1085
+ loadLibrary();
1086
+ const rawPtr = import_ffi_rs.load({
1087
+ library: LIBRARY_KEY,
1088
+ funcName: "fff_multi_grep",
1089
+ retType: import_ffi_rs.DataType.External,
1090
+ paramsType: [
1091
+ import_ffi_rs.DataType.External,
1092
+ import_ffi_rs.DataType.String,
1093
+ import_ffi_rs.DataType.String,
1094
+ import_ffi_rs.DataType.U64,
1095
+ import_ffi_rs.DataType.U32,
1096
+ import_ffi_rs.DataType.Boolean,
1097
+ import_ffi_rs.DataType.U32,
1098
+ import_ffi_rs.DataType.U32,
1099
+ import_ffi_rs.DataType.U64,
1100
+ import_ffi_rs.DataType.U32,
1101
+ import_ffi_rs.DataType.U32,
1102
+ import_ffi_rs.DataType.Boolean
1103
+ ],
1104
+ paramsValue: [
1105
+ handle,
1106
+ patternsJoined,
1107
+ constraints,
1108
+ maxFileSize,
1109
+ maxMatchesPerFile,
1110
+ smartCase,
1111
+ fileOffset,
1112
+ pageLimit,
1113
+ timeBudgetMs,
1114
+ beforeContext,
1115
+ afterContext,
1116
+ classifyDefinitions
1117
+ ],
1118
+ freeResultMemory: false
1119
+ });
1120
+ return parseGrepResult(rawPtr);
1121
+ }
1122
+ function ffiScanFiles(handle) {
1123
+ return callVoidResult("fff_scan_files", [import_ffi_rs.DataType.External], [handle]);
1124
+ }
1125
+ function ffiIsScanning(handle) {
1126
+ loadLibrary();
1127
+ return import_ffi_rs.load({
1128
+ library: LIBRARY_KEY,
1129
+ funcName: "fff_is_scanning",
1130
+ retType: import_ffi_rs.DataType.Boolean,
1131
+ paramsType: [import_ffi_rs.DataType.External],
1132
+ paramsValue: [handle]
1133
+ });
1134
+ }
1135
+ function ffiGetBasePath(handle) {
1136
+ return callStringResult("fff_get_base_path", [import_ffi_rs.DataType.External], [handle]);
1137
+ }
1138
+ var FFF_SCAN_PROGRESS_STRUCT = {
1139
+ scanned_files_count: import_ffi_rs.DataType.U64,
1140
+ is_scanning: import_ffi_rs.DataType.U8,
1141
+ is_watcher_ready: import_ffi_rs.DataType.U8,
1142
+ is_warmup_complete: import_ffi_rs.DataType.U8
1143
+ };
1144
+ function ffiGetScanProgress(handle) {
1145
+ loadLibrary();
1146
+ const res = readResultEnvelope("fff_get_scan_progress", [import_ffi_rs.DataType.External], [handle]);
1147
+ if ("ok" in res)
1148
+ return res;
1149
+ const handlePtr = res.struct.handle;
1150
+ freeResult(res.rawPtr);
1151
+ if (import_ffi_rs.isNullPointer(handlePtr))
1152
+ return err("scan progress returned null");
1153
+ const [sp] = import_ffi_rs.restorePointer({
1154
+ retType: [FFF_SCAN_PROGRESS_STRUCT],
1155
+ paramsValue: import_ffi_rs.wrapPointer([handlePtr])
1156
+ });
1157
+ const result = {
1158
+ scannedFilesCount: Number(sp.scanned_files_count),
1159
+ isScanning: sp.is_scanning !== 0,
1160
+ isWatcherReady: sp.is_watcher_ready !== 0,
1161
+ isWarmupComplete: sp.is_warmup_complete !== 0
1162
+ };
1163
+ import_ffi_rs.load({
1164
+ library: LIBRARY_KEY,
1165
+ funcName: "fff_free_scan_progress",
1166
+ retType: import_ffi_rs.DataType.Void,
1167
+ paramsType: [import_ffi_rs.DataType.External],
1168
+ paramsValue: [handlePtr]
1169
+ });
1170
+ return { ok: true, value: result };
1171
+ }
1172
+ function ffiWaitForScan(handle, timeoutMs) {
1173
+ return callBoolResult("fff_wait_for_scan", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64], [handle, timeoutMs]);
1174
+ }
1175
+ function ffiRestartIndex(handle, newPath) {
1176
+ return callVoidResult("fff_restart_index", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.String], [handle, newPath]);
1177
+ }
1178
+ function ffiRefreshGitStatus(handle) {
1179
+ return callIntResult("fff_refresh_git_status", [import_ffi_rs.DataType.External], [handle]);
1180
+ }
1181
+ function ffiTrackQuery(handle, query, filePath) {
1182
+ return callBoolResult("fff_track_query", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.String, import_ffi_rs.DataType.String], [handle, query, filePath]);
1183
+ }
1184
+ function ffiGetHistoricalQuery(handle, offset) {
1185
+ return callStringResult("fff_get_historical_query", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64], [handle, offset]);
1186
+ }
1187
+ function watchKindFromU8(kind) {
1188
+ switch (kind) {
1189
+ case 0:
1190
+ return "created";
1191
+ case 1:
1192
+ return "modified";
1193
+ case 2:
1194
+ return "removed";
1195
+ default:
1196
+ return "rescan";
1197
+ }
1198
+ }
1199
+ var WATCH_TRAMPOLINE_TYPE = import_ffi_rs.funcConstructor({
1200
+ paramsType: [import_ffi_rs.DataType.U64, import_ffi_rs.DataType.U64, import_ffi_rs.DataType.U64],
1201
+ retType: import_ffi_rs.DataType.Void
1202
+ });
1203
+ var watchHandlers = new Map;
1204
+ var watchInstances = new Set;
1205
+ var watchTrampoline = null;
1206
+ function addressToExternal(address) {
1207
+ return import_ffi_rs.load({
1208
+ library: LIBRARY_KEY,
1209
+ funcName: "fff_ptr_offset",
1210
+ retType: import_ffi_rs.DataType.External,
1211
+ paramsType: [import_ffi_rs.DataType.U64, import_ffi_rs.DataType.U64],
1212
+ paramsValue: [address, 0]
1213
+ });
1214
+ }
1215
+ function consumeWatchBatch(address) {
1216
+ const batchPtr = addressToExternal(address);
1217
+ const count = import_ffi_rs.load({
1218
+ library: LIBRARY_KEY,
1219
+ funcName: "fff_watch_events_count",
1220
+ retType: import_ffi_rs.DataType.U32,
1221
+ paramsType: [import_ffi_rs.DataType.External],
1222
+ paramsValue: [batchPtr]
1223
+ });
1224
+ const events = [];
1225
+ for (let i = 0;i < count; i++) {
1226
+ const path = import_ffi_rs.load({
1227
+ library: LIBRARY_KEY,
1228
+ funcName: "fff_watch_events_get_path",
1229
+ retType: import_ffi_rs.DataType.External,
1230
+ paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U32],
1231
+ paramsValue: [batchPtr, i]
1232
+ });
1233
+ const kind = import_ffi_rs.load({
1234
+ library: LIBRARY_KEY,
1235
+ funcName: "fff_watch_events_get_kind",
1236
+ retType: import_ffi_rs.DataType.U8,
1237
+ paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U32],
1238
+ paramsValue: [batchPtr, i]
1239
+ });
1240
+ events.push({
1241
+ path: readCString(path) ?? "",
1242
+ kind: watchKindFromU8(kind)
1243
+ });
1244
+ }
1245
+ import_ffi_rs.load({
1246
+ library: LIBRARY_KEY,
1247
+ funcName: "fff_free_watch_events",
1248
+ retType: import_ffi_rs.DataType.Void,
1249
+ paramsType: [import_ffi_rs.DataType.U64],
1250
+ paramsValue: [address]
1251
+ });
1252
+ return events;
1253
+ }
1254
+ function watchTrampolineImpl(watchId, batchAddress, _userData) {
1255
+ const events = consumeWatchBatch(batchAddress);
1256
+ const handler = watchHandlers.get(Number(watchId));
1257
+ if (handler === undefined || events.length === 0)
1258
+ return;
1259
+ try {
1260
+ handler(events);
1261
+ } catch {}
1262
+ }
1263
+ function ensureWatchTrampoline() {
1264
+ if (watchTrampoline === null) {
1265
+ watchTrampoline = import_ffi_rs.createPointer({
1266
+ paramsType: [WATCH_TRAMPOLINE_TYPE],
1267
+ paramsValue: [watchTrampolineImpl]
1268
+ });
1269
+ }
1270
+ return import_ffi_rs.unwrapPointer(watchTrampoline)[0];
1271
+ }
1272
+ function ensureWatchCallbackRegistered(handle) {
1273
+ if (watchInstances.has(handle))
1274
+ return { ok: true, value: undefined };
1275
+ const trampoline = ensureWatchTrampoline();
1276
+ const registered = callVoidResult("fff_set_watch_callback", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64], [handle, trampoline, 0]);
1277
+ if (registered.ok)
1278
+ watchInstances.add(handle);
1279
+ return registered;
1280
+ }
1281
+ function releaseWatchTrampolineIfIdle() {
1282
+ if (watchHandlers.size > 0 || watchInstances.size > 0 || watchTrampoline === null)
1283
+ return;
1284
+ import_ffi_rs.freePointer({
1285
+ paramsType: [WATCH_TRAMPOLINE_TYPE],
1286
+ paramsValue: watchTrampoline,
1287
+ pointerType: import_ffi_rs.PointerType.RsPointer
1288
+ });
1289
+ watchTrampoline = null;
1290
+ }
1291
+ function ffiWatch(handle, pattern, ignore, callback) {
1292
+ loadLibrary();
1293
+ const registered = ensureWatchCallbackRegistered(handle);
1294
+ if (!registered.ok)
1295
+ return registered;
1296
+ const created = callIntResult("fff_watch_args", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.String, import_ffi_rs.DataType.StringArray, import_ffi_rs.DataType.U32], [handle, pattern, ignore, ignore.length]);
1297
+ if (!created.ok)
1298
+ return created;
1299
+ watchHandlers.set(created.value, callback);
1300
+ return created;
1301
+ }
1302
+ function ffiUnwatch(handle, watchId) {
1303
+ const result = callBoolResult("fff_unwatch", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64], [handle, watchId]);
1304
+ watchHandlers.delete(watchId);
1305
+ return result;
1306
+ }
1307
+ function ffiWatchCleanupAfterDestroy(handle, watchIds) {
1308
+ for (const id of watchIds) {
1309
+ watchHandlers.delete(id);
1310
+ }
1311
+ watchInstances.delete(handle);
1312
+ releaseWatchTrampolineIfIdle();
1313
+ }
1314
+ function ffiHealthCheck(handle, testPath) {
1315
+ if (handle === null) {
1316
+ return callJsonResult("fff_health_check", [import_ffi_rs.DataType.U64, import_ffi_rs.DataType.String], [0, testPath]);
1317
+ }
1318
+ return callJsonResult("fff_health_check", [import_ffi_rs.DataType.External, import_ffi_rs.DataType.String], [handle, testPath]);
1319
+ }
1320
+ function ensureLoaded() {
1321
+ loadLibrary();
1322
+ }
1323
+ function isAvailable() {
1324
+ try {
1325
+ loadLibrary();
1326
+ return true;
1327
+ } catch {
1328
+ return false;
1329
+ }
1330
+ }
1331
+ function closeLibrary() {
1332
+ if (isLoaded) {
1333
+ import_ffi_rs.close(LIBRARY_KEY);
1334
+ isLoaded = false;
1335
+ }
1336
+ }
1337
+ // src/finder.ts
1338
+ class FileFinder {
1339
+ handle;
1340
+ watchers = new Set;
1341
+ constructor(handle) {
1342
+ this.handle = handle;
1343
+ }
1344
+ static create(options) {
1345
+ const result = ffiCreate(options.basePath, options.frecencyDbPath ?? "", options.historyDbPath ?? "", options.useUnsafeNoLock ?? false, !(options.disableMmapCache ?? false), !(options.disableContentIndexing ?? options.disableMmapCache ?? false), !(options.disableWatch ?? false), options.aiMode ?? false, options.logFilePath ?? "", options.logLevel ?? "", options.cacheBudgetMaxFiles ?? 0, options.cacheBudgetMaxBytes ?? 0, options.cacheBudgetMaxFileSize ?? 0, options.enableFsRootScanning ?? false, options.enableHomeDirScanning ?? false, options.followSymlinks ?? false);
1346
+ if (!result.ok) {
1347
+ return result;
1348
+ }
1349
+ return { ok: true, value: new FileFinder(result.value) };
1350
+ }
1351
+ destroy() {
1352
+ if (this.handle !== null) {
1353
+ const handle = this.handle;
1354
+ ffiDestroy(handle);
1355
+ this.handle = null;
1356
+ ffiWatchCleanupAfterDestroy(handle, this.watchers);
1357
+ this.watchers.clear();
1358
+ }
1359
+ }
1360
+ get isDestroyed() {
1361
+ return this.handle === null;
1362
+ }
1363
+ ensureAlive() {
1364
+ if (this.handle === null) {
1365
+ return err("FileFinder instance has been destroyed.");
1366
+ }
1367
+ return { ok: true, value: this.handle };
1368
+ }
1369
+ fileSearch(query, options) {
1370
+ const guard = this.ensureAlive();
1371
+ if (!guard.ok)
1372
+ return guard;
1373
+ return ffiSearch(guard.value, query, options?.currentFile ?? "", options?.maxThreads ?? 0, options?.pageIndex ?? 0, options?.pageSize ?? 0, options?.comboBoostMultiplier ?? 0, options?.minComboCount ?? 0);
1374
+ }
1375
+ glob(pattern, options) {
1376
+ const guard = this.ensureAlive();
1377
+ if (!guard.ok)
1378
+ return guard;
1379
+ return ffiGlob(guard.value, pattern, options?.currentFile ?? "", options?.maxThreads ?? 0, options?.pageIndex ?? 0, options?.pageSize ?? 0);
1380
+ }
1381
+ directorySearch(query, options) {
1382
+ const guard = this.ensureAlive();
1383
+ if (!guard.ok)
1384
+ return guard;
1385
+ return ffiSearchDirectories(guard.value, query, options?.currentFile ?? null, options?.maxThreads ?? 0, options?.pageIndex ?? 0, options?.pageSize ?? 0);
1386
+ }
1387
+ mixedSearch(query, options) {
1388
+ const guard = this.ensureAlive();
1389
+ if (!guard.ok)
1390
+ return guard;
1391
+ return ffiSearchMixed(guard.value, query, options?.currentFile ?? "", options?.maxThreads ?? 0, options?.pageIndex ?? 0, options?.pageSize ?? 0, options?.comboBoostMultiplier ?? 0, options?.minComboCount ?? 0);
1392
+ }
1393
+ grep(query, options) {
1394
+ const guard = this.ensureAlive();
1395
+ if (!guard.ok)
1396
+ return guard;
1397
+ return ffiLiveGrep(guard.value, query, options?.mode ?? "plain", options?.maxFileSize ?? 0, options?.maxMatchesPerFile ?? 0, options?.smartCase ?? true, options?.cursor?._offset ?? 0, options?.pageSize ?? 0, options?.timeBudgetMs ?? 0, options?.beforeContext ?? 0, options?.afterContext ?? 0, options?.classifyDefinitions ?? false);
1398
+ }
1399
+ multiGrep(options) {
1400
+ const guard = this.ensureAlive();
1401
+ if (!guard.ok)
1402
+ return guard;
1403
+ if (!options.patterns || options.patterns.length === 0) {
1404
+ return err("patterns array must have at least 1 element");
1405
+ }
1406
+ return ffiMultiGrep(guard.value, options.patterns.join(`
1407
+ `), options.constraints ?? "", options.maxFileSize ?? 0, options.maxMatchesPerFile ?? 0, options.smartCase ?? true, options.cursor?._offset ?? 0, options.pageSize ?? 0, options.timeBudgetMs ?? 0, options.beforeContext ?? 0, options.afterContext ?? 0, options.classifyDefinitions ?? false);
1408
+ }
1409
+ scanFiles() {
1410
+ const guard = this.ensureAlive();
1411
+ if (!guard.ok)
1412
+ return guard;
1413
+ return ffiScanFiles(guard.value);
1414
+ }
1415
+ isScanning() {
1416
+ if (this.handle === null)
1417
+ return false;
1418
+ return ffiIsScanning(this.handle);
1419
+ }
1420
+ getBasePath() {
1421
+ const guard = this.ensureAlive();
1422
+ if (!guard.ok)
1423
+ return guard;
1424
+ return ffiGetBasePath(guard.value);
1425
+ }
1426
+ getScanProgress() {
1427
+ const guard = this.ensureAlive();
1428
+ if (!guard.ok)
1429
+ return guard;
1430
+ return ffiGetScanProgress(guard.value);
1431
+ }
1432
+ async waitForScan(timeoutMs = 5000) {
1433
+ const guard = this.ensureAlive();
1434
+ if (!guard.ok)
1435
+ return guard;
1436
+ const deadline = Date.now() + timeoutMs;
1437
+ while (this.isScanning()) {
1438
+ if (Date.now() >= deadline) {
1439
+ return { ok: true, value: false };
1440
+ }
1441
+ await new Promise((resolve) => setTimeout(resolve, 50));
1442
+ }
1443
+ return { ok: true, value: true };
1444
+ }
1445
+ waitForScanBlocking(timeoutMs = 5000) {
1446
+ const guard = this.ensureAlive();
1447
+ if (!guard.ok)
1448
+ return guard;
1449
+ return ffiWaitForScan(guard.value, timeoutMs);
1450
+ }
1451
+ async waitForIndexReady(timeoutMs = 5000) {
1452
+ const guard = this.ensureAlive();
1453
+ if (!guard.ok)
1454
+ return guard;
1455
+ const deadline = Date.now() + timeoutMs;
1456
+ while (true) {
1457
+ const progress = this.getScanProgress();
1458
+ if (!progress.ok)
1459
+ return progress;
1460
+ if (!progress.value.isScanning && progress.value.isWarmupComplete) {
1461
+ return { ok: true, value: true };
1462
+ }
1463
+ if (Date.now() >= deadline) {
1464
+ return { ok: true, value: false };
1465
+ }
1466
+ await new Promise((resolve) => setTimeout(resolve, 50));
1467
+ }
1468
+ }
1469
+ reindex(newPath) {
1470
+ const guard = this.ensureAlive();
1471
+ if (!guard.ok)
1472
+ return guard;
1473
+ return ffiRestartIndex(guard.value, newPath);
1474
+ }
1475
+ refreshGitStatus() {
1476
+ const guard = this.ensureAlive();
1477
+ if (!guard.ok)
1478
+ return guard;
1479
+ return ffiRefreshGitStatus(guard.value);
1480
+ }
1481
+ trackQuery(query, selectedFilePath) {
1482
+ const guard = this.ensureAlive();
1483
+ if (!guard.ok)
1484
+ return guard;
1485
+ return ffiTrackQuery(guard.value, query, selectedFilePath);
1486
+ }
1487
+ getHistoricalQuery(offset) {
1488
+ const guard = this.ensureAlive();
1489
+ if (!guard.ok)
1490
+ return guard;
1491
+ return ffiGetHistoricalQuery(guard.value, offset);
1492
+ }
1493
+ watch(patternOrCallback, callbackOrOptions, maybeOptions) {
1494
+ const noPattern = typeof patternOrCallback === "function";
1495
+ const pattern = noPattern ? "" : patternOrCallback;
1496
+ const callback = noPattern ? patternOrCallback : callbackOrOptions;
1497
+ const options = noPattern ? callbackOrOptions : maybeOptions;
1498
+ if (typeof callback !== "function") {
1499
+ return err("watch callback must be a function");
1500
+ }
1501
+ const guard = this.ensureAlive();
1502
+ if (!guard.ok)
1503
+ return guard;
1504
+ const created = ffiWatch(guard.value, pattern, options?.ignore ?? [], callback);
1505
+ if (!created.ok)
1506
+ return created;
1507
+ const watchId = created.value;
1508
+ this.watchers.add(watchId);
1509
+ return {
1510
+ ok: true,
1511
+ value: () => {
1512
+ if (!this.watchers.delete(watchId))
1513
+ return;
1514
+ if (this.handle !== null)
1515
+ ffiUnwatch(this.handle, watchId);
1516
+ }
1517
+ };
1518
+ }
1519
+ healthCheck(testPath) {
1520
+ return ffiHealthCheck(this.handle, testPath || "");
1521
+ }
1522
+ static isAvailable() {
1523
+ return isAvailable();
1524
+ }
1525
+ static ensureLoaded() {
1526
+ ensureLoaded();
1527
+ }
1528
+ static healthCheckStatic(testPath) {
1529
+ return ffiHealthCheck(null, testPath || "");
1530
+ }
1531
+ }
1532
+
1533
+ //# debugId=A462FE346ED11F3D64756E2164756E21