@ff-labs/fff-node 0.10.5-dev.774d6bc → 0.10.5-nightly.f565d37
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 +729 -291
- package/dist/index.cjs.map +1 -14
- package/dist/index.js +617 -174
- package/dist/index.js.map +1 -14
- package/package.json +14 -14
package/dist/index.cjs
CHANGED
|
@@ -1,65 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
5
|
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
6
|
var __export = (target, all) => {
|
|
30
7
|
for (var name in all)
|
|
31
|
-
__defProp(target, name, {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
37
17
|
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
19
|
|
|
39
20
|
// src/index.ts
|
|
40
|
-
var
|
|
41
|
-
__export(
|
|
42
|
-
|
|
43
|
-
getTriple: () => getTriple,
|
|
44
|
-
getNpmPackageName: () => getNpmPackageName,
|
|
45
|
-
getLibFilename: () => getLibFilename,
|
|
46
|
-
getLibExtension: () => getLibExtension,
|
|
47
|
-
findBinary: () => findBinary,
|
|
48
|
-
err: () => err,
|
|
49
|
-
closeLibrary: () => closeLibrary,
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
FileFinder: () => FileFinder,
|
|
50
24
|
binaryExists: () => binaryExists,
|
|
51
|
-
|
|
25
|
+
closeLibrary: () => closeLibrary,
|
|
26
|
+
err: () => err,
|
|
27
|
+
findBinary: () => findBinary,
|
|
28
|
+
getLibExtension: () => getLibExtension,
|
|
29
|
+
getLibFilename: () => getLibFilename,
|
|
30
|
+
getNpmPackageName: () => getNpmPackageName,
|
|
31
|
+
getTriple: () => getTriple,
|
|
32
|
+
ok: () => ok
|
|
52
33
|
});
|
|
53
|
-
module.exports = __toCommonJS(
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
54
35
|
|
|
55
36
|
// src/binary.ts
|
|
56
|
-
var import_node_fs = require("
|
|
57
|
-
var import_node_module = require("
|
|
58
|
-
var import_node_path = require("
|
|
59
|
-
var import_node_url = require("
|
|
37
|
+
var import_node_fs = require("fs");
|
|
38
|
+
var import_node_module = require("module");
|
|
39
|
+
var import_node_path = require("path");
|
|
40
|
+
var import_node_url = require("url");
|
|
60
41
|
|
|
61
42
|
// src/platform.ts
|
|
62
|
-
var import_node_child_process = require("
|
|
43
|
+
var import_node_child_process = require("child_process");
|
|
63
44
|
function getTriple() {
|
|
64
45
|
const platform = process.platform;
|
|
65
46
|
const arch = process.arch;
|
|
@@ -81,13 +62,13 @@ function getTriple() {
|
|
|
81
62
|
function detectLinuxLibc() {
|
|
82
63
|
let output = "";
|
|
83
64
|
try {
|
|
84
|
-
output = import_node_child_process.execSync("ldd --version 2>&1", {
|
|
65
|
+
output = (0, import_node_child_process.execSync)("ldd --version 2>&1", {
|
|
85
66
|
encoding: "utf-8",
|
|
86
|
-
timeout:
|
|
67
|
+
timeout: 5e3
|
|
87
68
|
});
|
|
88
69
|
} catch (e) {
|
|
89
|
-
const
|
|
90
|
-
output = String(
|
|
70
|
+
const err2 = e;
|
|
71
|
+
output = String(err2?.stdout ?? "") + String(err2?.stderr ?? "");
|
|
91
72
|
}
|
|
92
73
|
if (output.toLowerCase().includes("musl")) {
|
|
93
74
|
return "unknown-linux-musl";
|
|
@@ -146,31 +127,31 @@ function getNpmPackageName() {
|
|
|
146
127
|
}
|
|
147
128
|
|
|
148
129
|
// src/binary.ts
|
|
149
|
-
var
|
|
130
|
+
var import_meta = {};
|
|
150
131
|
function getCurrentDir() {
|
|
151
|
-
if (typeof __dirname !== "undefined")
|
|
152
|
-
|
|
153
|
-
const url = "file:///home/runner/work/fff/fff/packages/fff-node/src/binary.ts";
|
|
132
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
133
|
+
const url = import_meta.url;
|
|
154
134
|
if (url.startsWith("file://")) {
|
|
155
|
-
return import_node_path.dirname(import_node_url.fileURLToPath(url));
|
|
135
|
+
return (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(url));
|
|
156
136
|
}
|
|
157
|
-
return import_node_path.dirname(url);
|
|
137
|
+
return (0, import_node_path.dirname)(url);
|
|
158
138
|
}
|
|
159
139
|
function getPackageDir() {
|
|
160
140
|
const currentDir = getCurrentDir();
|
|
161
141
|
let dir = currentDir;
|
|
162
|
-
for (let i = 0;i < 5; i++) {
|
|
163
|
-
if (import_node_fs.existsSync(import_node_path.join(dir, "package.json"))) {
|
|
142
|
+
for (let i = 0; i < 5; i++) {
|
|
143
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(dir, "package.json"))) {
|
|
164
144
|
try {
|
|
165
|
-
const pkg = JSON.parse(import_node_fs.readFileSync(import_node_path.join(dir, "package.json"), "utf-8"));
|
|
145
|
+
const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(dir, "package.json"), "utf-8"));
|
|
166
146
|
if (pkg.name === "@ff-labs/fff-node") {
|
|
167
147
|
return dir;
|
|
168
148
|
}
|
|
169
|
-
} catch {
|
|
149
|
+
} catch {
|
|
150
|
+
}
|
|
170
151
|
}
|
|
171
|
-
dir = import_node_path.dirname(dir);
|
|
152
|
+
dir = (0, import_node_path.dirname)(dir);
|
|
172
153
|
}
|
|
173
|
-
return import_node_path.dirname(currentDir);
|
|
154
|
+
return (0, import_node_path.dirname)(currentDir);
|
|
174
155
|
}
|
|
175
156
|
function binaryExists() {
|
|
176
157
|
return findBinary() !== null;
|
|
@@ -178,25 +159,26 @@ function binaryExists() {
|
|
|
178
159
|
function resolveFromNpmPackage() {
|
|
179
160
|
const packageName = getNpmPackageName();
|
|
180
161
|
try {
|
|
181
|
-
const require2 = import_node_module.createRequire(import_node_path.join(getPackageDir(), "package.json"));
|
|
162
|
+
const require2 = (0, import_node_module.createRequire)((0, import_node_path.join)(getPackageDir(), "package.json"));
|
|
182
163
|
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)) {
|
|
164
|
+
const packageDir = (0, import_node_path.dirname)(packageJsonPath);
|
|
165
|
+
const binaryPath = (0, import_node_path.join)(packageDir, getLibFilename());
|
|
166
|
+
if ((0, import_node_fs.existsSync)(binaryPath)) {
|
|
186
167
|
return binaryPath;
|
|
187
168
|
}
|
|
188
|
-
} catch {
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
189
171
|
return null;
|
|
190
172
|
}
|
|
191
173
|
function getDevBinaryPath() {
|
|
192
174
|
const packageDir = getPackageDir();
|
|
193
|
-
const workspaceRoot = import_node_path.join(packageDir, "..", "..");
|
|
175
|
+
const workspaceRoot = (0, import_node_path.join)(packageDir, "..", "..");
|
|
194
176
|
const possiblePaths = [
|
|
195
|
-
import_node_path.join(workspaceRoot, "target", "release", getLibFilename()),
|
|
196
|
-
import_node_path.join(workspaceRoot, "target", "debug", getLibFilename())
|
|
177
|
+
(0, import_node_path.join)(workspaceRoot, "target", "release", getLibFilename()),
|
|
178
|
+
(0, import_node_path.join)(workspaceRoot, "target", "debug", getLibFilename())
|
|
197
179
|
];
|
|
198
180
|
for (const path of possiblePaths) {
|
|
199
|
-
if (import_node_fs.existsSync(path)) {
|
|
181
|
+
if ((0, import_node_fs.existsSync)(path)) {
|
|
200
182
|
return path;
|
|
201
183
|
}
|
|
202
184
|
}
|
|
@@ -204,27 +186,24 @@ function getDevBinaryPath() {
|
|
|
204
186
|
}
|
|
205
187
|
function isDevWorkspace() {
|
|
206
188
|
const packageDir = getPackageDir();
|
|
207
|
-
const workspaceRoot = import_node_path.join(packageDir, "..", "..");
|
|
208
|
-
return import_node_fs.existsSync(import_node_path.join(workspaceRoot, "Cargo.toml"));
|
|
189
|
+
const workspaceRoot = (0, import_node_path.join)(packageDir, "..", "..");
|
|
190
|
+
return (0, import_node_fs.existsSync)((0, import_node_path.join)(workspaceRoot, "Cargo.toml"));
|
|
209
191
|
}
|
|
210
192
|
function findBinary() {
|
|
211
193
|
if (isDevWorkspace()) {
|
|
212
|
-
const binPath = import_node_path.join(getPackageDir(), "bin", getLibFilename());
|
|
213
|
-
if (import_node_fs.existsSync(binPath))
|
|
214
|
-
return binPath;
|
|
194
|
+
const binPath = (0, import_node_path.join)(getPackageDir(), "bin", getLibFilename());
|
|
195
|
+
if ((0, import_node_fs.existsSync)(binPath)) return binPath;
|
|
215
196
|
const devPath = getDevBinaryPath();
|
|
216
|
-
if (devPath)
|
|
217
|
-
return devPath;
|
|
197
|
+
if (devPath) return devPath;
|
|
218
198
|
const npmPath2 = resolveFromNpmPackage();
|
|
219
|
-
if (npmPath2)
|
|
220
|
-
return npmPath2;
|
|
199
|
+
if (npmPath2) return npmPath2;
|
|
221
200
|
return null;
|
|
222
201
|
}
|
|
223
202
|
const npmPath = resolveFromNpmPackage();
|
|
224
|
-
if (npmPath)
|
|
225
|
-
return npmPath;
|
|
203
|
+
if (npmPath) return npmPath;
|
|
226
204
|
return getDevBinaryPath();
|
|
227
205
|
}
|
|
206
|
+
|
|
228
207
|
// src/ffi.ts
|
|
229
208
|
var import_ffi_rs = require("ffi-rs");
|
|
230
209
|
|
|
@@ -281,36 +260,36 @@ var FFF_RESULT_STRUCT = {
|
|
|
281
260
|
int_value: import_ffi_rs.DataType.I64
|
|
282
261
|
};
|
|
283
262
|
function loadLibrary() {
|
|
284
|
-
if (isLoaded)
|
|
285
|
-
return;
|
|
263
|
+
if (isLoaded) return;
|
|
286
264
|
const binaryPath = findBinary();
|
|
287
265
|
if (!binaryPath) {
|
|
288
|
-
throw new Error(
|
|
266
|
+
throw new Error(
|
|
267
|
+
"fff native library not found. Run `npx @ff-labs/fff-node download` or build from source with `cargo build --release -p fff-c`"
|
|
268
|
+
);
|
|
289
269
|
}
|
|
290
|
-
import_ffi_rs.open({ library: LIBRARY_KEY, path: binaryPath });
|
|
270
|
+
(0, import_ffi_rs.open)({ library: LIBRARY_KEY, path: binaryPath });
|
|
291
271
|
isLoaded = true;
|
|
292
272
|
}
|
|
293
273
|
function snakeToCamel(obj) {
|
|
294
|
-
if (obj === null || obj ===
|
|
295
|
-
|
|
296
|
-
if (
|
|
297
|
-
return obj;
|
|
298
|
-
if (Array.isArray(obj))
|
|
299
|
-
return obj.map(snakeToCamel);
|
|
274
|
+
if (obj === null || obj === void 0) return obj;
|
|
275
|
+
if (typeof obj !== "object") return obj;
|
|
276
|
+
if (Array.isArray(obj)) return obj.map(snakeToCamel);
|
|
300
277
|
const result = {};
|
|
301
278
|
for (const [key, value] of Object.entries(obj)) {
|
|
302
|
-
const camelKey = key.replace(
|
|
279
|
+
const camelKey = key.replace(
|
|
280
|
+
/_([a-z])/g,
|
|
281
|
+
(_, letter) => letter.toUpperCase()
|
|
282
|
+
);
|
|
303
283
|
result[camelKey] = snakeToCamel(value);
|
|
304
284
|
}
|
|
305
285
|
return result;
|
|
306
286
|
}
|
|
307
287
|
function readCString(ptr) {
|
|
308
|
-
if (import_ffi_rs.isNullPointer(ptr))
|
|
309
|
-
return null;
|
|
288
|
+
if ((0, import_ffi_rs.isNullPointer)(ptr)) return null;
|
|
310
289
|
try {
|
|
311
|
-
const [str] = import_ffi_rs.restorePointer({
|
|
290
|
+
const [str] = (0, import_ffi_rs.restorePointer)({
|
|
312
291
|
retType: [import_ffi_rs.DataType.String],
|
|
313
|
-
paramsValue: import_ffi_rs.wrapPointer([ptr])
|
|
292
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([ptr])
|
|
314
293
|
});
|
|
315
294
|
return str;
|
|
316
295
|
} catch {
|
|
@@ -318,7 +297,7 @@ function readCString(ptr) {
|
|
|
318
297
|
}
|
|
319
298
|
}
|
|
320
299
|
function callRaw(funcName, paramsType, paramsValue) {
|
|
321
|
-
const rawPtr = import_ffi_rs.load({
|
|
300
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
322
301
|
library: LIBRARY_KEY,
|
|
323
302
|
funcName,
|
|
324
303
|
retType: import_ffi_rs.DataType.External,
|
|
@@ -326,22 +305,23 @@ function callRaw(funcName, paramsType, paramsValue) {
|
|
|
326
305
|
paramsValue,
|
|
327
306
|
freeResultMemory: false
|
|
328
307
|
});
|
|
329
|
-
const [structData] = import_ffi_rs.restorePointer({
|
|
308
|
+
const [structData] = (0, import_ffi_rs.restorePointer)({
|
|
330
309
|
retType: [FFF_RESULT_STRUCT],
|
|
331
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
310
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
332
311
|
});
|
|
333
312
|
return { rawPtr, struct: structData };
|
|
334
313
|
}
|
|
335
314
|
function freeResult(resultPtr) {
|
|
336
315
|
try {
|
|
337
|
-
import_ffi_rs.load({
|
|
316
|
+
(0, import_ffi_rs.load)({
|
|
338
317
|
library: LIBRARY_KEY,
|
|
339
318
|
funcName: "fff_free_result",
|
|
340
319
|
retType: import_ffi_rs.DataType.Void,
|
|
341
320
|
paramsType: [import_ffi_rs.DataType.External],
|
|
342
321
|
paramsValue: [resultPtr]
|
|
343
322
|
});
|
|
344
|
-
} catch {
|
|
323
|
+
} catch {
|
|
324
|
+
}
|
|
345
325
|
}
|
|
346
326
|
function readResultEnvelope(funcName, paramsType, paramsValue) {
|
|
347
327
|
loadLibrary();
|
|
@@ -355,51 +335,43 @@ function readResultEnvelope(funcName, paramsType, paramsValue) {
|
|
|
355
335
|
}
|
|
356
336
|
function callVoidResult(funcName, paramsType, paramsValue) {
|
|
357
337
|
const res = readResultEnvelope(funcName, paramsType, paramsValue);
|
|
358
|
-
if ("ok" in res)
|
|
359
|
-
return res;
|
|
338
|
+
if ("ok" in res) return res;
|
|
360
339
|
freeResult(res.rawPtr);
|
|
361
|
-
return { ok: true, value:
|
|
340
|
+
return { ok: true, value: void 0 };
|
|
362
341
|
}
|
|
363
342
|
function callIntResult(funcName, paramsType, paramsValue) {
|
|
364
343
|
const res = readResultEnvelope(funcName, paramsType, paramsValue);
|
|
365
|
-
if ("ok" in res)
|
|
366
|
-
return res;
|
|
344
|
+
if ("ok" in res) return res;
|
|
367
345
|
const value = Number(res.struct.int_value);
|
|
368
346
|
freeResult(res.rawPtr);
|
|
369
347
|
return { ok: true, value };
|
|
370
348
|
}
|
|
371
349
|
function callBoolResult(funcName, paramsType, paramsValue) {
|
|
372
350
|
const res = readResultEnvelope(funcName, paramsType, paramsValue);
|
|
373
|
-
if ("ok" in res)
|
|
374
|
-
return res;
|
|
351
|
+
if ("ok" in res) return res;
|
|
375
352
|
const value = Number(res.struct.int_value) !== 0;
|
|
376
353
|
freeResult(res.rawPtr);
|
|
377
354
|
return { ok: true, value };
|
|
378
355
|
}
|
|
379
356
|
function callStringResult(funcName, paramsType, paramsValue) {
|
|
380
357
|
const res = readResultEnvelope(funcName, paramsType, paramsValue);
|
|
381
|
-
if ("ok" in res)
|
|
382
|
-
return res;
|
|
358
|
+
if ("ok" in res) return res;
|
|
383
359
|
const handlePtr = res.struct.handle;
|
|
384
360
|
freeResult(res.rawPtr);
|
|
385
|
-
if (import_ffi_rs.isNullPointer(handlePtr))
|
|
386
|
-
return { ok: true, value: null };
|
|
361
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) return { ok: true, value: null };
|
|
387
362
|
const str = readCString(handlePtr);
|
|
388
363
|
freeString(handlePtr);
|
|
389
364
|
return { ok: true, value: str };
|
|
390
365
|
}
|
|
391
366
|
function callJsonResult(funcName, paramsType, paramsValue) {
|
|
392
367
|
const res = readResultEnvelope(funcName, paramsType, paramsValue);
|
|
393
|
-
if ("ok" in res)
|
|
394
|
-
return res;
|
|
368
|
+
if ("ok" in res) return res;
|
|
395
369
|
const handlePtr = res.struct.handle;
|
|
396
370
|
freeResult(res.rawPtr);
|
|
397
|
-
if (import_ffi_rs.isNullPointer(handlePtr))
|
|
398
|
-
return { ok: true, value: undefined };
|
|
371
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) return { ok: true, value: void 0 };
|
|
399
372
|
const jsonStr = readCString(handlePtr);
|
|
400
373
|
freeString(handlePtr);
|
|
401
|
-
if (jsonStr === null || jsonStr === "")
|
|
402
|
-
return { ok: true, value: undefined };
|
|
374
|
+
if (jsonStr === null || jsonStr === "") return { ok: true, value: void 0 };
|
|
403
375
|
try {
|
|
404
376
|
return { ok: true, value: snakeToCamel(JSON.parse(jsonStr)) };
|
|
405
377
|
} catch {
|
|
@@ -408,14 +380,15 @@ function callJsonResult(funcName, paramsType, paramsValue) {
|
|
|
408
380
|
}
|
|
409
381
|
function freeString(ptr) {
|
|
410
382
|
try {
|
|
411
|
-
import_ffi_rs.load({
|
|
383
|
+
(0, import_ffi_rs.load)({
|
|
412
384
|
library: LIBRARY_KEY,
|
|
413
385
|
funcName: "fff_free_string",
|
|
414
386
|
retType: import_ffi_rs.DataType.Void,
|
|
415
387
|
paramsType: [import_ffi_rs.DataType.External],
|
|
416
388
|
paramsValue: [ptr]
|
|
417
389
|
});
|
|
418
|
-
} catch {
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
419
392
|
}
|
|
420
393
|
function ffiCreate(basePath, frecencyDbPath, historyDbPath, _useUnsafeNoLock, enableMmapCache, enableContentIndexing, watch, aiMode, logFilePath, logLevel, cacheBudgetMaxFiles, cacheBudgetMaxBytes, cacheBudgetMaxFileSize, enableFsRootScanning, enableHomeDirScanning, followSymlinks) {
|
|
421
394
|
loadLibrary();
|
|
@@ -437,7 +410,7 @@ function ffiCreate(basePath, frecencyDbPath, historyDbPath, _useUnsafeNoLock, en
|
|
|
437
410
|
enable_home_dir_scanning: enableHomeDirScanning ? 1 : 0,
|
|
438
411
|
follow_symlinks: followSymlinks ? 1 : 0
|
|
439
412
|
};
|
|
440
|
-
const rawPtr = import_ffi_rs.load({
|
|
413
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
441
414
|
library: LIBRARY_KEY,
|
|
442
415
|
funcName: "fff_create_instance_with",
|
|
443
416
|
retType: import_ffi_rs.DataType.External,
|
|
@@ -445,15 +418,15 @@ function ffiCreate(basePath, frecencyDbPath, historyDbPath, _useUnsafeNoLock, en
|
|
|
445
418
|
paramsValue: [optsValue],
|
|
446
419
|
freeResultMemory: false
|
|
447
420
|
});
|
|
448
|
-
const [structData] = import_ffi_rs.restorePointer({
|
|
421
|
+
const [structData] = (0, import_ffi_rs.restorePointer)({
|
|
449
422
|
retType: [FFF_RESULT_STRUCT],
|
|
450
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
423
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
451
424
|
});
|
|
452
425
|
const success = structData.success !== 0;
|
|
453
426
|
try {
|
|
454
427
|
if (success) {
|
|
455
428
|
const handle = structData.handle;
|
|
456
|
-
if (import_ffi_rs.isNullPointer(handle)) {
|
|
429
|
+
if ((0, import_ffi_rs.isNullPointer)(handle)) {
|
|
457
430
|
return err("fff_create_instance_with returned null handle");
|
|
458
431
|
}
|
|
459
432
|
return { ok: true, value: handle };
|
|
@@ -467,7 +440,7 @@ function ffiCreate(basePath, frecencyDbPath, historyDbPath, _useUnsafeNoLock, en
|
|
|
467
440
|
}
|
|
468
441
|
function ffiDestroy(handle) {
|
|
469
442
|
loadLibrary();
|
|
470
|
-
import_ffi_rs.load({
|
|
443
|
+
(0, import_ffi_rs.load)({
|
|
471
444
|
library: LIBRARY_KEY,
|
|
472
445
|
funcName: "fff_destroy",
|
|
473
446
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -504,6 +477,7 @@ var FFF_SEARCH_RESULT_STRUCT = {
|
|
|
504
477
|
count: import_ffi_rs.DataType.U32,
|
|
505
478
|
total_matched: import_ffi_rs.DataType.U32,
|
|
506
479
|
total_files: import_ffi_rs.DataType.U32,
|
|
480
|
+
// FffLocation inlined (flattened)
|
|
507
481
|
location_tag: import_ffi_rs.DataType.U8,
|
|
508
482
|
location_line: import_ffi_rs.DataType.I32,
|
|
509
483
|
location_col: import_ffi_rs.DataType.I32,
|
|
@@ -541,6 +515,7 @@ var FFF_MIXED_SEARCH_RESULT_STRUCT = {
|
|
|
541
515
|
total_matched: import_ffi_rs.DataType.U32,
|
|
542
516
|
total_files: import_ffi_rs.DataType.U32,
|
|
543
517
|
total_dirs: import_ffi_rs.DataType.U32,
|
|
518
|
+
// FffLocation inlined (flattened)
|
|
544
519
|
location_tag: import_ffi_rs.DataType.U8,
|
|
545
520
|
location_line: import_ffi_rs.DataType.I32,
|
|
546
521
|
location_col: import_ffi_rs.DataType.I32,
|
|
@@ -567,6 +542,7 @@ var FFF_GREP_MATCH_STRUCT = {
|
|
|
567
542
|
context_before_count: import_ffi_rs.DataType.U32,
|
|
568
543
|
context_after_count: import_ffi_rs.DataType.U32,
|
|
569
544
|
fuzzy_score: import_ffi_rs.DataType.U32,
|
|
545
|
+
// actually u16 in C, but ffi-rs doesn't so we read it as u32 with padding
|
|
570
546
|
has_fuzzy_score: import_ffi_rs.DataType.U8,
|
|
571
547
|
is_binary: import_ffi_rs.DataType.U8,
|
|
572
548
|
is_definition: import_ffi_rs.DataType.U8
|
|
@@ -645,21 +621,21 @@ function readMixedItemFromRaw(raw) {
|
|
|
645
621
|
}
|
|
646
622
|
function callAccessor(funcName, resultPtr, index, structDef) {
|
|
647
623
|
loadLibrary();
|
|
648
|
-
const elemPtr = import_ffi_rs.load({
|
|
624
|
+
const elemPtr = (0, import_ffi_rs.load)({
|
|
649
625
|
library: LIBRARY_KEY,
|
|
650
626
|
funcName,
|
|
651
627
|
retType: import_ffi_rs.DataType.External,
|
|
652
628
|
paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U32],
|
|
653
629
|
paramsValue: [resultPtr, index]
|
|
654
630
|
});
|
|
655
|
-
const [raw] = import_ffi_rs.restorePointer({
|
|
631
|
+
const [raw] = (0, import_ffi_rs.restorePointer)({
|
|
656
632
|
retType: [structDef],
|
|
657
|
-
paramsValue: import_ffi_rs.wrapPointer([elemPtr])
|
|
633
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([elemPtr])
|
|
658
634
|
});
|
|
659
635
|
return raw;
|
|
660
636
|
}
|
|
661
637
|
function ptrOffset(base, bytes) {
|
|
662
|
-
return import_ffi_rs.load({
|
|
638
|
+
return (0, import_ffi_rs.load)({
|
|
663
639
|
library: LIBRARY_KEY,
|
|
664
640
|
funcName: "fff_ptr_offset",
|
|
665
641
|
retType: import_ffi_rs.DataType.External,
|
|
@@ -668,12 +644,11 @@ function ptrOffset(base, bytes) {
|
|
|
668
644
|
});
|
|
669
645
|
}
|
|
670
646
|
function readCStringArray(ptrArray, count) {
|
|
671
|
-
if (count === 0 || import_ffi_rs.isNullPointer(ptrArray))
|
|
672
|
-
return [];
|
|
647
|
+
if (count === 0 || (0, import_ffi_rs.isNullPointer)(ptrArray)) return [];
|
|
673
648
|
const result = [];
|
|
674
|
-
for (let i = 0;i < count; i++) {
|
|
649
|
+
for (let i = 0; i < count; i++) {
|
|
675
650
|
const elemPtr = ptrOffset(ptrArray, i * 8);
|
|
676
|
-
const [charPtr] = import_ffi_rs.restorePointer({
|
|
651
|
+
const [charPtr] = (0, import_ffi_rs.restorePointer)({
|
|
677
652
|
retType: [import_ffi_rs.DataType.External],
|
|
678
653
|
paramsValue: [elemPtr]
|
|
679
654
|
});
|
|
@@ -683,11 +658,11 @@ function readCStringArray(ptrArray, count) {
|
|
|
683
658
|
}
|
|
684
659
|
function readGrepMatchFromRaw(raw) {
|
|
685
660
|
const matchRanges = [];
|
|
686
|
-
for (let i = 0;i < raw.match_ranges_count; i++) {
|
|
661
|
+
for (let i = 0; i < raw.match_ranges_count; i++) {
|
|
687
662
|
const rangePtr = ptrOffset(raw.match_ranges, i * 8);
|
|
688
|
-
const [rangeRaw] = import_ffi_rs.restorePointer({
|
|
663
|
+
const [rangeRaw] = (0, import_ffi_rs.restorePointer)({
|
|
689
664
|
retType: [FFF_MATCH_RANGE_STRUCT],
|
|
690
|
-
paramsValue: import_ffi_rs.wrapPointer([rangePtr])
|
|
665
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rangePtr])
|
|
691
666
|
});
|
|
692
667
|
matchRanges.push([rangeRaw.start, rangeRaw.end]);
|
|
693
668
|
}
|
|
@@ -723,9 +698,9 @@ function readGrepMatchFromRaw(raw) {
|
|
|
723
698
|
}
|
|
724
699
|
function parseGrepResult(rawPtr) {
|
|
725
700
|
loadLibrary();
|
|
726
|
-
const [envelope] = import_ffi_rs.restorePointer({
|
|
701
|
+
const [envelope] = (0, import_ffi_rs.restorePointer)({
|
|
727
702
|
retType: [FFF_RESULT_STRUCT],
|
|
728
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
703
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
729
704
|
});
|
|
730
705
|
const success = envelope.success !== 0;
|
|
731
706
|
if (!success) {
|
|
@@ -735,21 +710,26 @@ function parseGrepResult(rawPtr) {
|
|
|
735
710
|
}
|
|
736
711
|
const handlePtr = envelope.handle;
|
|
737
712
|
freeResult(rawPtr);
|
|
738
|
-
if (import_ffi_rs.isNullPointer(handlePtr)) {
|
|
713
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) {
|
|
739
714
|
return err("grep returned null result");
|
|
740
715
|
}
|
|
741
|
-
const [gr] = import_ffi_rs.restorePointer({
|
|
716
|
+
const [gr] = (0, import_ffi_rs.restorePointer)({
|
|
742
717
|
retType: [FFF_GREP_RESULT_STRUCT],
|
|
743
|
-
paramsValue: import_ffi_rs.wrapPointer([handlePtr])
|
|
718
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([handlePtr])
|
|
744
719
|
});
|
|
745
720
|
const count = gr.count;
|
|
746
|
-
const regexFallbackError = readCString(gr.regex_fallback_error) ??
|
|
721
|
+
const regexFallbackError = readCString(gr.regex_fallback_error) ?? void 0;
|
|
747
722
|
const items = [];
|
|
748
|
-
for (let i = 0;i < count; i++) {
|
|
749
|
-
const rawMatch = callAccessor(
|
|
723
|
+
for (let i = 0; i < count; i++) {
|
|
724
|
+
const rawMatch = callAccessor(
|
|
725
|
+
"fff_grep_result_get_match",
|
|
726
|
+
handlePtr,
|
|
727
|
+
i,
|
|
728
|
+
FFF_GREP_MATCH_STRUCT
|
|
729
|
+
);
|
|
750
730
|
items.push(readGrepMatchFromRaw(rawMatch));
|
|
751
731
|
}
|
|
752
|
-
import_ffi_rs.load({
|
|
732
|
+
(0, import_ffi_rs.load)({
|
|
753
733
|
library: LIBRARY_KEY,
|
|
754
734
|
funcName: "fff_free_grep_result",
|
|
755
735
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -771,9 +751,9 @@ function parseGrepResult(rawPtr) {
|
|
|
771
751
|
}
|
|
772
752
|
function parseSearchResult(rawPtr) {
|
|
773
753
|
loadLibrary();
|
|
774
|
-
const [envelope] = import_ffi_rs.restorePointer({
|
|
754
|
+
const [envelope] = (0, import_ffi_rs.restorePointer)({
|
|
775
755
|
retType: [FFF_RESULT_STRUCT],
|
|
776
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
756
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
777
757
|
});
|
|
778
758
|
const success = envelope.success !== 0;
|
|
779
759
|
if (!success) {
|
|
@@ -783,12 +763,12 @@ function parseSearchResult(rawPtr) {
|
|
|
783
763
|
}
|
|
784
764
|
const handlePtr = envelope.handle;
|
|
785
765
|
freeResult(rawPtr);
|
|
786
|
-
if (import_ffi_rs.isNullPointer(handlePtr)) {
|
|
766
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) {
|
|
787
767
|
return err("fff_search returned null search result");
|
|
788
768
|
}
|
|
789
|
-
const [sr] = import_ffi_rs.restorePointer({
|
|
769
|
+
const [sr] = (0, import_ffi_rs.restorePointer)({
|
|
790
770
|
retType: [FFF_SEARCH_RESULT_STRUCT],
|
|
791
|
-
paramsValue: import_ffi_rs.wrapPointer([handlePtr])
|
|
771
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([handlePtr])
|
|
792
772
|
});
|
|
793
773
|
const count = sr.count;
|
|
794
774
|
let location;
|
|
@@ -809,13 +789,23 @@ function parseSearchResult(rawPtr) {
|
|
|
809
789
|
}
|
|
810
790
|
const items = [];
|
|
811
791
|
const scores = [];
|
|
812
|
-
for (let i = 0;i < count; i++) {
|
|
813
|
-
const rawItem = callAccessor(
|
|
792
|
+
for (let i = 0; i < count; i++) {
|
|
793
|
+
const rawItem = callAccessor(
|
|
794
|
+
"fff_search_result_get_item",
|
|
795
|
+
handlePtr,
|
|
796
|
+
i,
|
|
797
|
+
FFF_FILE_ITEM_STRUCT
|
|
798
|
+
);
|
|
814
799
|
items.push(readFileItemFromRaw(rawItem));
|
|
815
|
-
const rawScore = callAccessor(
|
|
800
|
+
const rawScore = callAccessor(
|
|
801
|
+
"fff_search_result_get_score",
|
|
802
|
+
handlePtr,
|
|
803
|
+
i,
|
|
804
|
+
FFF_SCORE_STRUCT
|
|
805
|
+
);
|
|
816
806
|
scores.push(readScoreFromRaw(rawScore));
|
|
817
807
|
}
|
|
818
|
-
import_ffi_rs.load({
|
|
808
|
+
(0, import_ffi_rs.load)({
|
|
819
809
|
library: LIBRARY_KEY,
|
|
820
810
|
funcName: "fff_free_search_result",
|
|
821
811
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -835,9 +825,9 @@ function parseSearchResult(rawPtr) {
|
|
|
835
825
|
}
|
|
836
826
|
function parseDirSearchResult(rawPtr) {
|
|
837
827
|
loadLibrary();
|
|
838
|
-
const [envelope] = import_ffi_rs.restorePointer({
|
|
828
|
+
const [envelope] = (0, import_ffi_rs.restorePointer)({
|
|
839
829
|
retType: [FFF_RESULT_STRUCT],
|
|
840
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
830
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
841
831
|
});
|
|
842
832
|
const success = envelope.success !== 0;
|
|
843
833
|
if (!success) {
|
|
@@ -847,23 +837,33 @@ function parseDirSearchResult(rawPtr) {
|
|
|
847
837
|
}
|
|
848
838
|
const handlePtr = envelope.handle;
|
|
849
839
|
freeResult(rawPtr);
|
|
850
|
-
if (import_ffi_rs.isNullPointer(handlePtr)) {
|
|
840
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) {
|
|
851
841
|
return err("fff_search_directories returned null search result");
|
|
852
842
|
}
|
|
853
|
-
const [sr] = import_ffi_rs.restorePointer({
|
|
843
|
+
const [sr] = (0, import_ffi_rs.restorePointer)({
|
|
854
844
|
retType: [FFF_DIR_SEARCH_RESULT_STRUCT],
|
|
855
|
-
paramsValue: import_ffi_rs.wrapPointer([handlePtr])
|
|
845
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([handlePtr])
|
|
856
846
|
});
|
|
857
847
|
const count = sr.count;
|
|
858
848
|
const items = [];
|
|
859
849
|
const scores = [];
|
|
860
|
-
for (let i = 0;i < count; i++) {
|
|
861
|
-
const rawItem = callAccessor(
|
|
850
|
+
for (let i = 0; i < count; i++) {
|
|
851
|
+
const rawItem = callAccessor(
|
|
852
|
+
"fff_dir_search_result_get_item",
|
|
853
|
+
handlePtr,
|
|
854
|
+
i,
|
|
855
|
+
FFF_DIR_ITEM_STRUCT
|
|
856
|
+
);
|
|
862
857
|
items.push(readDirItemFromRaw(rawItem));
|
|
863
|
-
const rawScore = callAccessor(
|
|
858
|
+
const rawScore = callAccessor(
|
|
859
|
+
"fff_dir_search_result_get_score",
|
|
860
|
+
handlePtr,
|
|
861
|
+
i,
|
|
862
|
+
FFF_SCORE_STRUCT
|
|
863
|
+
);
|
|
864
864
|
scores.push(readScoreFromRaw(rawScore));
|
|
865
865
|
}
|
|
866
|
-
import_ffi_rs.load({
|
|
866
|
+
(0, import_ffi_rs.load)({
|
|
867
867
|
library: LIBRARY_KEY,
|
|
868
868
|
funcName: "fff_free_dir_search_result",
|
|
869
869
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -882,9 +882,9 @@ function parseDirSearchResult(rawPtr) {
|
|
|
882
882
|
}
|
|
883
883
|
function parseMixedSearchResult(rawPtr) {
|
|
884
884
|
loadLibrary();
|
|
885
|
-
const [envelope] = import_ffi_rs.restorePointer({
|
|
885
|
+
const [envelope] = (0, import_ffi_rs.restorePointer)({
|
|
886
886
|
retType: [FFF_RESULT_STRUCT],
|
|
887
|
-
paramsValue: import_ffi_rs.wrapPointer([rawPtr])
|
|
887
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([rawPtr])
|
|
888
888
|
});
|
|
889
889
|
const success = envelope.success !== 0;
|
|
890
890
|
if (!success) {
|
|
@@ -894,12 +894,12 @@ function parseMixedSearchResult(rawPtr) {
|
|
|
894
894
|
}
|
|
895
895
|
const handlePtr = envelope.handle;
|
|
896
896
|
freeResult(rawPtr);
|
|
897
|
-
if (import_ffi_rs.isNullPointer(handlePtr)) {
|
|
897
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) {
|
|
898
898
|
return err("fff_search_mixed returned null search result");
|
|
899
899
|
}
|
|
900
|
-
const [sr] = import_ffi_rs.restorePointer({
|
|
900
|
+
const [sr] = (0, import_ffi_rs.restorePointer)({
|
|
901
901
|
retType: [FFF_MIXED_SEARCH_RESULT_STRUCT],
|
|
902
|
-
paramsValue: import_ffi_rs.wrapPointer([handlePtr])
|
|
902
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([handlePtr])
|
|
903
903
|
});
|
|
904
904
|
const count = sr.count;
|
|
905
905
|
let location;
|
|
@@ -920,13 +920,23 @@ function parseMixedSearchResult(rawPtr) {
|
|
|
920
920
|
}
|
|
921
921
|
const items = [];
|
|
922
922
|
const scores = [];
|
|
923
|
-
for (let i = 0;i < count; i++) {
|
|
924
|
-
const rawItem = callAccessor(
|
|
923
|
+
for (let i = 0; i < count; i++) {
|
|
924
|
+
const rawItem = callAccessor(
|
|
925
|
+
"fff_mixed_search_result_get_item",
|
|
926
|
+
handlePtr,
|
|
927
|
+
i,
|
|
928
|
+
FFF_MIXED_ITEM_STRUCT
|
|
929
|
+
);
|
|
925
930
|
items.push(readMixedItemFromRaw(rawItem));
|
|
926
|
-
const rawScore = callAccessor(
|
|
931
|
+
const rawScore = callAccessor(
|
|
932
|
+
"fff_mixed_search_result_get_score",
|
|
933
|
+
handlePtr,
|
|
934
|
+
i,
|
|
935
|
+
FFF_SCORE_STRUCT
|
|
936
|
+
);
|
|
927
937
|
scores.push(readScoreFromRaw(rawScore));
|
|
928
938
|
}
|
|
929
|
-
import_ffi_rs.load({
|
|
939
|
+
(0, import_ffi_rs.load)({
|
|
930
940
|
library: LIBRARY_KEY,
|
|
931
941
|
funcName: "fff_free_mixed_search_result",
|
|
932
942
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -947,19 +957,27 @@ function parseMixedSearchResult(rawPtr) {
|
|
|
947
957
|
}
|
|
948
958
|
function ffiSearch(handle, query, currentFile, maxThreads, pageIndex, pageSize, comboBoostMultiplier, minComboCount) {
|
|
949
959
|
loadLibrary();
|
|
950
|
-
const rawPtr = import_ffi_rs.load({
|
|
960
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
951
961
|
library: LIBRARY_KEY,
|
|
952
962
|
funcName: "fff_search",
|
|
953
963
|
retType: import_ffi_rs.DataType.External,
|
|
954
964
|
paramsType: [
|
|
955
965
|
import_ffi_rs.DataType.External,
|
|
966
|
+
// handle
|
|
956
967
|
import_ffi_rs.DataType.String,
|
|
968
|
+
// query
|
|
957
969
|
import_ffi_rs.DataType.String,
|
|
970
|
+
// current_file
|
|
958
971
|
import_ffi_rs.DataType.U32,
|
|
972
|
+
// max_threads
|
|
959
973
|
import_ffi_rs.DataType.U32,
|
|
974
|
+
// page_index
|
|
960
975
|
import_ffi_rs.DataType.U32,
|
|
976
|
+
// page_size
|
|
961
977
|
import_ffi_rs.DataType.I32,
|
|
978
|
+
// combo_boost_multiplier
|
|
962
979
|
import_ffi_rs.DataType.U32
|
|
980
|
+
// min_combo_count
|
|
963
981
|
],
|
|
964
982
|
paramsValue: [
|
|
965
983
|
handle,
|
|
@@ -977,17 +995,23 @@ function ffiSearch(handle, query, currentFile, maxThreads, pageIndex, pageSize,
|
|
|
977
995
|
}
|
|
978
996
|
function ffiGlob(handle, pattern, currentFile, maxThreads, pageIndex, pageSize) {
|
|
979
997
|
loadLibrary();
|
|
980
|
-
const rawPtr = import_ffi_rs.load({
|
|
998
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
981
999
|
library: LIBRARY_KEY,
|
|
982
1000
|
funcName: "fff_glob",
|
|
983
1001
|
retType: import_ffi_rs.DataType.External,
|
|
984
1002
|
paramsType: [
|
|
985
1003
|
import_ffi_rs.DataType.External,
|
|
1004
|
+
// handle
|
|
986
1005
|
import_ffi_rs.DataType.String,
|
|
1006
|
+
// pattern
|
|
987
1007
|
import_ffi_rs.DataType.String,
|
|
1008
|
+
// current_file
|
|
988
1009
|
import_ffi_rs.DataType.U32,
|
|
1010
|
+
// max_threads
|
|
989
1011
|
import_ffi_rs.DataType.U32,
|
|
1012
|
+
// page_index
|
|
990
1013
|
import_ffi_rs.DataType.U32
|
|
1014
|
+
// page_size
|
|
991
1015
|
],
|
|
992
1016
|
paramsValue: [handle, pattern, currentFile, maxThreads, pageIndex, pageSize],
|
|
993
1017
|
freeResultMemory: false
|
|
@@ -996,17 +1020,23 @@ function ffiGlob(handle, pattern, currentFile, maxThreads, pageIndex, pageSize)
|
|
|
996
1020
|
}
|
|
997
1021
|
function ffiSearchDirectories(handle, query, currentFile, maxThreads, pageIndex, pageSize) {
|
|
998
1022
|
loadLibrary();
|
|
999
|
-
const rawPtr = import_ffi_rs.load({
|
|
1023
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
1000
1024
|
library: LIBRARY_KEY,
|
|
1001
1025
|
funcName: "fff_search_directories",
|
|
1002
1026
|
retType: import_ffi_rs.DataType.External,
|
|
1003
1027
|
paramsType: [
|
|
1004
1028
|
import_ffi_rs.DataType.External,
|
|
1029
|
+
// handle
|
|
1005
1030
|
import_ffi_rs.DataType.String,
|
|
1031
|
+
// query
|
|
1006
1032
|
import_ffi_rs.DataType.String,
|
|
1033
|
+
// current_file
|
|
1007
1034
|
import_ffi_rs.DataType.U32,
|
|
1035
|
+
// max_threads
|
|
1008
1036
|
import_ffi_rs.DataType.U32,
|
|
1037
|
+
// page_index
|
|
1009
1038
|
import_ffi_rs.DataType.U32
|
|
1039
|
+
// page_size
|
|
1010
1040
|
],
|
|
1011
1041
|
paramsValue: [handle, query, currentFile ?? "", maxThreads, pageIndex, pageSize],
|
|
1012
1042
|
freeResultMemory: false
|
|
@@ -1015,19 +1045,27 @@ function ffiSearchDirectories(handle, query, currentFile, maxThreads, pageIndex,
|
|
|
1015
1045
|
}
|
|
1016
1046
|
function ffiSearchMixed(handle, query, currentFile, maxThreads, pageIndex, pageSize, comboBoostMultiplier, minComboCount) {
|
|
1017
1047
|
loadLibrary();
|
|
1018
|
-
const rawPtr = import_ffi_rs.load({
|
|
1048
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
1019
1049
|
library: LIBRARY_KEY,
|
|
1020
1050
|
funcName: "fff_search_mixed",
|
|
1021
1051
|
retType: import_ffi_rs.DataType.External,
|
|
1022
1052
|
paramsType: [
|
|
1023
1053
|
import_ffi_rs.DataType.External,
|
|
1054
|
+
// handle
|
|
1024
1055
|
import_ffi_rs.DataType.String,
|
|
1056
|
+
// query
|
|
1025
1057
|
import_ffi_rs.DataType.String,
|
|
1058
|
+
// current_file
|
|
1026
1059
|
import_ffi_rs.DataType.U32,
|
|
1060
|
+
// max_threads
|
|
1027
1061
|
import_ffi_rs.DataType.U32,
|
|
1062
|
+
// page_index
|
|
1028
1063
|
import_ffi_rs.DataType.U32,
|
|
1064
|
+
// page_size
|
|
1029
1065
|
import_ffi_rs.DataType.I32,
|
|
1066
|
+
// combo_boost_multiplier
|
|
1030
1067
|
import_ffi_rs.DataType.U32
|
|
1068
|
+
// min_combo_count
|
|
1031
1069
|
],
|
|
1032
1070
|
paramsValue: [
|
|
1033
1071
|
handle,
|
|
@@ -1045,23 +1083,35 @@ function ffiSearchMixed(handle, query, currentFile, maxThreads, pageIndex, pageS
|
|
|
1045
1083
|
}
|
|
1046
1084
|
function ffiLiveGrep(handle, query, mode, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
|
|
1047
1085
|
loadLibrary();
|
|
1048
|
-
const rawPtr = import_ffi_rs.load({
|
|
1086
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
1049
1087
|
library: LIBRARY_KEY,
|
|
1050
1088
|
funcName: "fff_live_grep",
|
|
1051
1089
|
retType: import_ffi_rs.DataType.External,
|
|
1052
1090
|
paramsType: [
|
|
1053
1091
|
import_ffi_rs.DataType.External,
|
|
1092
|
+
// handle
|
|
1054
1093
|
import_ffi_rs.DataType.String,
|
|
1094
|
+
// query
|
|
1055
1095
|
import_ffi_rs.DataType.U8,
|
|
1096
|
+
// mode
|
|
1056
1097
|
import_ffi_rs.DataType.U64,
|
|
1098
|
+
// max_file_size
|
|
1057
1099
|
import_ffi_rs.DataType.U32,
|
|
1100
|
+
// max_matches_per_file
|
|
1058
1101
|
import_ffi_rs.DataType.Boolean,
|
|
1102
|
+
// smart_case
|
|
1059
1103
|
import_ffi_rs.DataType.U32,
|
|
1104
|
+
// file_offset
|
|
1060
1105
|
import_ffi_rs.DataType.U32,
|
|
1106
|
+
// page_limit
|
|
1061
1107
|
import_ffi_rs.DataType.U64,
|
|
1108
|
+
// time_budget_ms
|
|
1062
1109
|
import_ffi_rs.DataType.U32,
|
|
1110
|
+
// before_context
|
|
1063
1111
|
import_ffi_rs.DataType.U32,
|
|
1112
|
+
// after_context
|
|
1064
1113
|
import_ffi_rs.DataType.Boolean
|
|
1114
|
+
// classify_definitions
|
|
1065
1115
|
],
|
|
1066
1116
|
paramsValue: [
|
|
1067
1117
|
handle,
|
|
@@ -1083,23 +1133,35 @@ function ffiLiveGrep(handle, query, mode, maxFileSize, maxMatchesPerFile, smartC
|
|
|
1083
1133
|
}
|
|
1084
1134
|
function ffiMultiGrep(handle, patternsJoined, constraints, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
|
|
1085
1135
|
loadLibrary();
|
|
1086
|
-
const rawPtr = import_ffi_rs.load({
|
|
1136
|
+
const rawPtr = (0, import_ffi_rs.load)({
|
|
1087
1137
|
library: LIBRARY_KEY,
|
|
1088
1138
|
funcName: "fff_multi_grep",
|
|
1089
1139
|
retType: import_ffi_rs.DataType.External,
|
|
1090
1140
|
paramsType: [
|
|
1091
1141
|
import_ffi_rs.DataType.External,
|
|
1142
|
+
// handle
|
|
1092
1143
|
import_ffi_rs.DataType.String,
|
|
1144
|
+
// patterns_joined
|
|
1093
1145
|
import_ffi_rs.DataType.String,
|
|
1146
|
+
// constraints
|
|
1094
1147
|
import_ffi_rs.DataType.U64,
|
|
1148
|
+
// max_file_size
|
|
1095
1149
|
import_ffi_rs.DataType.U32,
|
|
1150
|
+
// max_matches_per_file
|
|
1096
1151
|
import_ffi_rs.DataType.Boolean,
|
|
1152
|
+
// smart_case
|
|
1097
1153
|
import_ffi_rs.DataType.U32,
|
|
1154
|
+
// file_offset
|
|
1098
1155
|
import_ffi_rs.DataType.U32,
|
|
1156
|
+
// page_limit
|
|
1099
1157
|
import_ffi_rs.DataType.U64,
|
|
1158
|
+
// time_budget_ms
|
|
1100
1159
|
import_ffi_rs.DataType.U32,
|
|
1160
|
+
// before_context
|
|
1101
1161
|
import_ffi_rs.DataType.U32,
|
|
1162
|
+
// after_context
|
|
1102
1163
|
import_ffi_rs.DataType.Boolean
|
|
1164
|
+
// classify_definitions
|
|
1103
1165
|
],
|
|
1104
1166
|
paramsValue: [
|
|
1105
1167
|
handle,
|
|
@@ -1124,7 +1186,7 @@ function ffiScanFiles(handle) {
|
|
|
1124
1186
|
}
|
|
1125
1187
|
function ffiIsScanning(handle) {
|
|
1126
1188
|
loadLibrary();
|
|
1127
|
-
return import_ffi_rs.load({
|
|
1189
|
+
return (0, import_ffi_rs.load)({
|
|
1128
1190
|
library: LIBRARY_KEY,
|
|
1129
1191
|
funcName: "fff_is_scanning",
|
|
1130
1192
|
retType: import_ffi_rs.DataType.Boolean,
|
|
@@ -1144,15 +1206,13 @@ var FFF_SCAN_PROGRESS_STRUCT = {
|
|
|
1144
1206
|
function ffiGetScanProgress(handle) {
|
|
1145
1207
|
loadLibrary();
|
|
1146
1208
|
const res = readResultEnvelope("fff_get_scan_progress", [import_ffi_rs.DataType.External], [handle]);
|
|
1147
|
-
if ("ok" in res)
|
|
1148
|
-
return res;
|
|
1209
|
+
if ("ok" in res) return res;
|
|
1149
1210
|
const handlePtr = res.struct.handle;
|
|
1150
1211
|
freeResult(res.rawPtr);
|
|
1151
|
-
if (import_ffi_rs.isNullPointer(handlePtr))
|
|
1152
|
-
|
|
1153
|
-
const [sp] = import_ffi_rs.restorePointer({
|
|
1212
|
+
if ((0, import_ffi_rs.isNullPointer)(handlePtr)) return err("scan progress returned null");
|
|
1213
|
+
const [sp] = (0, import_ffi_rs.restorePointer)({
|
|
1154
1214
|
retType: [FFF_SCAN_PROGRESS_STRUCT],
|
|
1155
|
-
paramsValue: import_ffi_rs.wrapPointer([handlePtr])
|
|
1215
|
+
paramsValue: (0, import_ffi_rs.wrapPointer)([handlePtr])
|
|
1156
1216
|
});
|
|
1157
1217
|
const result = {
|
|
1158
1218
|
scannedFilesCount: Number(sp.scanned_files_count),
|
|
@@ -1160,7 +1220,7 @@ function ffiGetScanProgress(handle) {
|
|
|
1160
1220
|
isWatcherReady: sp.is_watcher_ready !== 0,
|
|
1161
1221
|
isWarmupComplete: sp.is_warmup_complete !== 0
|
|
1162
1222
|
};
|
|
1163
|
-
import_ffi_rs.load({
|
|
1223
|
+
(0, import_ffi_rs.load)({
|
|
1164
1224
|
library: LIBRARY_KEY,
|
|
1165
1225
|
funcName: "fff_free_scan_progress",
|
|
1166
1226
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -1170,19 +1230,35 @@ function ffiGetScanProgress(handle) {
|
|
|
1170
1230
|
return { ok: true, value: result };
|
|
1171
1231
|
}
|
|
1172
1232
|
function ffiWaitForScan(handle, timeoutMs) {
|
|
1173
|
-
return callBoolResult(
|
|
1233
|
+
return callBoolResult(
|
|
1234
|
+
"fff_wait_for_scan",
|
|
1235
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64],
|
|
1236
|
+
[handle, timeoutMs]
|
|
1237
|
+
);
|
|
1174
1238
|
}
|
|
1175
1239
|
function ffiRestartIndex(handle, newPath) {
|
|
1176
|
-
return callVoidResult(
|
|
1240
|
+
return callVoidResult(
|
|
1241
|
+
"fff_restart_index",
|
|
1242
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.String],
|
|
1243
|
+
[handle, newPath]
|
|
1244
|
+
);
|
|
1177
1245
|
}
|
|
1178
1246
|
function ffiRefreshGitStatus(handle) {
|
|
1179
1247
|
return callIntResult("fff_refresh_git_status", [import_ffi_rs.DataType.External], [handle]);
|
|
1180
1248
|
}
|
|
1181
1249
|
function ffiTrackQuery(handle, query, filePath) {
|
|
1182
|
-
return callBoolResult(
|
|
1250
|
+
return callBoolResult(
|
|
1251
|
+
"fff_track_query",
|
|
1252
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.String, import_ffi_rs.DataType.String],
|
|
1253
|
+
[handle, query, filePath]
|
|
1254
|
+
);
|
|
1183
1255
|
}
|
|
1184
1256
|
function ffiGetHistoricalQuery(handle, offset) {
|
|
1185
|
-
return callStringResult(
|
|
1257
|
+
return callStringResult(
|
|
1258
|
+
"fff_get_historical_query",
|
|
1259
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64],
|
|
1260
|
+
[handle, offset]
|
|
1261
|
+
);
|
|
1186
1262
|
}
|
|
1187
1263
|
function watchKindFromU8(kind) {
|
|
1188
1264
|
switch (kind) {
|
|
@@ -1196,15 +1272,15 @@ function watchKindFromU8(kind) {
|
|
|
1196
1272
|
return "rescan";
|
|
1197
1273
|
}
|
|
1198
1274
|
}
|
|
1199
|
-
var WATCH_TRAMPOLINE_TYPE = import_ffi_rs.funcConstructor({
|
|
1275
|
+
var WATCH_TRAMPOLINE_TYPE = (0, import_ffi_rs.funcConstructor)({
|
|
1200
1276
|
paramsType: [import_ffi_rs.DataType.U64, import_ffi_rs.DataType.U64, import_ffi_rs.DataType.U64],
|
|
1201
1277
|
retType: import_ffi_rs.DataType.Void
|
|
1202
1278
|
});
|
|
1203
|
-
var watchHandlers = new Map;
|
|
1204
|
-
var watchInstances = new Set;
|
|
1279
|
+
var watchHandlers = /* @__PURE__ */ new Map();
|
|
1280
|
+
var watchInstances = /* @__PURE__ */ new Set();
|
|
1205
1281
|
var watchTrampoline = null;
|
|
1206
1282
|
function addressToExternal(address) {
|
|
1207
|
-
return import_ffi_rs.load({
|
|
1283
|
+
return (0, import_ffi_rs.load)({
|
|
1208
1284
|
library: LIBRARY_KEY,
|
|
1209
1285
|
funcName: "fff_ptr_offset",
|
|
1210
1286
|
retType: import_ffi_rs.DataType.External,
|
|
@@ -1214,7 +1290,7 @@ function addressToExternal(address) {
|
|
|
1214
1290
|
}
|
|
1215
1291
|
function consumeWatchBatch(address) {
|
|
1216
1292
|
const batchPtr = addressToExternal(address);
|
|
1217
|
-
const count = import_ffi_rs.load({
|
|
1293
|
+
const count = (0, import_ffi_rs.load)({
|
|
1218
1294
|
library: LIBRARY_KEY,
|
|
1219
1295
|
funcName: "fff_watch_events_count",
|
|
1220
1296
|
retType: import_ffi_rs.DataType.U32,
|
|
@@ -1222,15 +1298,15 @@ function consumeWatchBatch(address) {
|
|
|
1222
1298
|
paramsValue: [batchPtr]
|
|
1223
1299
|
});
|
|
1224
1300
|
const events = [];
|
|
1225
|
-
for (let i = 0;i < count; i++) {
|
|
1226
|
-
const path = import_ffi_rs.load({
|
|
1301
|
+
for (let i = 0; i < count; i++) {
|
|
1302
|
+
const path = (0, import_ffi_rs.load)({
|
|
1227
1303
|
library: LIBRARY_KEY,
|
|
1228
1304
|
funcName: "fff_watch_events_get_path",
|
|
1229
1305
|
retType: import_ffi_rs.DataType.External,
|
|
1230
1306
|
paramsType: [import_ffi_rs.DataType.External, import_ffi_rs.DataType.U32],
|
|
1231
1307
|
paramsValue: [batchPtr, i]
|
|
1232
1308
|
});
|
|
1233
|
-
const kind = import_ffi_rs.load({
|
|
1309
|
+
const kind = (0, import_ffi_rs.load)({
|
|
1234
1310
|
library: LIBRARY_KEY,
|
|
1235
1311
|
funcName: "fff_watch_events_get_kind",
|
|
1236
1312
|
retType: import_ffi_rs.DataType.U8,
|
|
@@ -1242,7 +1318,7 @@ function consumeWatchBatch(address) {
|
|
|
1242
1318
|
kind: watchKindFromU8(kind)
|
|
1243
1319
|
});
|
|
1244
1320
|
}
|
|
1245
|
-
import_ffi_rs.load({
|
|
1321
|
+
(0, import_ffi_rs.load)({
|
|
1246
1322
|
library: LIBRARY_KEY,
|
|
1247
1323
|
funcName: "fff_free_watch_events",
|
|
1248
1324
|
retType: import_ffi_rs.DataType.Void,
|
|
@@ -1254,34 +1330,36 @@ function consumeWatchBatch(address) {
|
|
|
1254
1330
|
function watchTrampolineImpl(watchId, batchAddress, _userData) {
|
|
1255
1331
|
const events = consumeWatchBatch(batchAddress);
|
|
1256
1332
|
const handler = watchHandlers.get(Number(watchId));
|
|
1257
|
-
if (handler ===
|
|
1258
|
-
return;
|
|
1333
|
+
if (handler === void 0 || events.length === 0) return;
|
|
1259
1334
|
try {
|
|
1260
1335
|
handler(events);
|
|
1261
|
-
} catch {
|
|
1336
|
+
} catch {
|
|
1337
|
+
}
|
|
1262
1338
|
}
|
|
1263
1339
|
function ensureWatchTrampoline() {
|
|
1264
1340
|
if (watchTrampoline === null) {
|
|
1265
|
-
watchTrampoline = import_ffi_rs.createPointer({
|
|
1341
|
+
watchTrampoline = (0, import_ffi_rs.createPointer)({
|
|
1266
1342
|
paramsType: [WATCH_TRAMPOLINE_TYPE],
|
|
1267
1343
|
paramsValue: [watchTrampolineImpl]
|
|
1268
1344
|
});
|
|
1269
1345
|
}
|
|
1270
|
-
return import_ffi_rs.unwrapPointer(watchTrampoline)[0];
|
|
1346
|
+
return (0, import_ffi_rs.unwrapPointer)(watchTrampoline)[0];
|
|
1271
1347
|
}
|
|
1272
1348
|
function ensureWatchCallbackRegistered(handle) {
|
|
1273
|
-
if (watchInstances.has(handle))
|
|
1274
|
-
return { ok: true, value: undefined };
|
|
1349
|
+
if (watchInstances.has(handle)) return { ok: true, value: void 0 };
|
|
1275
1350
|
const trampoline = ensureWatchTrampoline();
|
|
1276
|
-
const registered = callVoidResult(
|
|
1277
|
-
|
|
1278
|
-
|
|
1351
|
+
const registered = callVoidResult(
|
|
1352
|
+
"fff_set_watch_callback",
|
|
1353
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64],
|
|
1354
|
+
[handle, trampoline, 0]
|
|
1355
|
+
);
|
|
1356
|
+
if (registered.ok) watchInstances.add(handle);
|
|
1279
1357
|
return registered;
|
|
1280
1358
|
}
|
|
1281
1359
|
function releaseWatchTrampolineIfIdle() {
|
|
1282
1360
|
if (watchHandlers.size > 0 || watchInstances.size > 0 || watchTrampoline === null)
|
|
1283
1361
|
return;
|
|
1284
|
-
import_ffi_rs.freePointer({
|
|
1362
|
+
(0, import_ffi_rs.freePointer)({
|
|
1285
1363
|
paramsType: [WATCH_TRAMPOLINE_TYPE],
|
|
1286
1364
|
paramsValue: watchTrampoline,
|
|
1287
1365
|
pointerType: import_ffi_rs.PointerType.RsPointer
|
|
@@ -1291,16 +1369,22 @@ function releaseWatchTrampolineIfIdle() {
|
|
|
1291
1369
|
function ffiWatch(handle, pattern, ignore, callback) {
|
|
1292
1370
|
loadLibrary();
|
|
1293
1371
|
const registered = ensureWatchCallbackRegistered(handle);
|
|
1294
|
-
if (!registered.ok)
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1372
|
+
if (!registered.ok) return registered;
|
|
1373
|
+
const created = callIntResult(
|
|
1374
|
+
"fff_watch_args",
|
|
1375
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.String, import_ffi_rs.DataType.StringArray, import_ffi_rs.DataType.U32],
|
|
1376
|
+
[handle, pattern, ignore, ignore.length]
|
|
1377
|
+
);
|
|
1378
|
+
if (!created.ok) return created;
|
|
1299
1379
|
watchHandlers.set(created.value, callback);
|
|
1300
1380
|
return created;
|
|
1301
1381
|
}
|
|
1302
1382
|
function ffiUnwatch(handle, watchId) {
|
|
1303
|
-
const result = callBoolResult(
|
|
1383
|
+
const result = callBoolResult(
|
|
1384
|
+
"fff_unwatch",
|
|
1385
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.U64],
|
|
1386
|
+
[handle, watchId]
|
|
1387
|
+
);
|
|
1304
1388
|
watchHandlers.delete(watchId);
|
|
1305
1389
|
return result;
|
|
1306
1390
|
}
|
|
@@ -1313,9 +1397,17 @@ function ffiWatchCleanupAfterDestroy(handle, watchIds) {
|
|
|
1313
1397
|
}
|
|
1314
1398
|
function ffiHealthCheck(handle, testPath) {
|
|
1315
1399
|
if (handle === null) {
|
|
1316
|
-
return callJsonResult(
|
|
1317
|
-
|
|
1318
|
-
|
|
1400
|
+
return callJsonResult(
|
|
1401
|
+
"fff_health_check",
|
|
1402
|
+
[import_ffi_rs.DataType.U64, import_ffi_rs.DataType.String],
|
|
1403
|
+
[0, testPath]
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
return callJsonResult(
|
|
1407
|
+
"fff_health_check",
|
|
1408
|
+
[import_ffi_rs.DataType.External, import_ffi_rs.DataType.String],
|
|
1409
|
+
[handle, testPath]
|
|
1410
|
+
);
|
|
1319
1411
|
}
|
|
1320
1412
|
function ensureLoaded() {
|
|
1321
1413
|
loadLibrary();
|
|
@@ -1330,24 +1422,69 @@ function isAvailable() {
|
|
|
1330
1422
|
}
|
|
1331
1423
|
function closeLibrary() {
|
|
1332
1424
|
if (isLoaded) {
|
|
1333
|
-
import_ffi_rs.close(LIBRARY_KEY);
|
|
1425
|
+
(0, import_ffi_rs.close)(LIBRARY_KEY);
|
|
1334
1426
|
isLoaded = false;
|
|
1335
1427
|
}
|
|
1336
1428
|
}
|
|
1429
|
+
|
|
1337
1430
|
// src/finder.ts
|
|
1338
|
-
|
|
1431
|
+
var FileFinder = class _FileFinder {
|
|
1339
1432
|
handle;
|
|
1340
|
-
|
|
1433
|
+
/** Native ids of this instance's active watch subscriptions. */
|
|
1434
|
+
watchers = /* @__PURE__ */ new Set();
|
|
1341
1435
|
constructor(handle) {
|
|
1342
1436
|
this.handle = handle;
|
|
1343
1437
|
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Create a new file finder instance.
|
|
1440
|
+
*
|
|
1441
|
+
* @param options - Initialization options
|
|
1442
|
+
* @returns Result containing the new FileFinder instance or an error
|
|
1443
|
+
*
|
|
1444
|
+
* @example
|
|
1445
|
+
* ```typescript
|
|
1446
|
+
* // Basic initialization
|
|
1447
|
+
* const finder = FileFinder.create({ basePath: "/path/to/project" });
|
|
1448
|
+
*
|
|
1449
|
+
* // With custom database paths
|
|
1450
|
+
* const finder = FileFinder.create({
|
|
1451
|
+
* basePath: "/path/to/project",
|
|
1452
|
+
* frecencyDbPath: "/custom/frecency.mdb",
|
|
1453
|
+
* historyDbPath: "/custom/history.mdb",
|
|
1454
|
+
* });
|
|
1455
|
+
* ```
|
|
1456
|
+
*/
|
|
1344
1457
|
static create(options) {
|
|
1345
|
-
const result = ffiCreate(
|
|
1458
|
+
const result = ffiCreate(
|
|
1459
|
+
options.basePath,
|
|
1460
|
+
options.frecencyDbPath ?? "",
|
|
1461
|
+
options.historyDbPath ?? "",
|
|
1462
|
+
options.useUnsafeNoLock ?? false,
|
|
1463
|
+
!(options.disableMmapCache ?? false),
|
|
1464
|
+
!(options.disableContentIndexing ?? options.disableMmapCache ?? false),
|
|
1465
|
+
!(options.disableWatch ?? false),
|
|
1466
|
+
options.aiMode ?? false,
|
|
1467
|
+
options.logFilePath ?? "",
|
|
1468
|
+
options.logLevel ?? "",
|
|
1469
|
+
options.cacheBudgetMaxFiles ?? 0,
|
|
1470
|
+
options.cacheBudgetMaxBytes ?? 0,
|
|
1471
|
+
options.cacheBudgetMaxFileSize ?? 0,
|
|
1472
|
+
options.enableFsRootScanning ?? false,
|
|
1473
|
+
options.enableHomeDirScanning ?? false,
|
|
1474
|
+
options.followSymlinks ?? false
|
|
1475
|
+
);
|
|
1346
1476
|
if (!result.ok) {
|
|
1347
1477
|
return result;
|
|
1348
1478
|
}
|
|
1349
|
-
return { ok: true, value: new
|
|
1350
|
-
}
|
|
1479
|
+
return { ok: true, value: new _FileFinder(result.value) };
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Destroy and clean up all resources.
|
|
1483
|
+
*
|
|
1484
|
+
* Call this when you're done using the file finder to free memory
|
|
1485
|
+
* and stop background file watching. After calling this, the instance
|
|
1486
|
+
* must not be used again.
|
|
1487
|
+
*/
|
|
1351
1488
|
destroy() {
|
|
1352
1489
|
if (this.handle !== null) {
|
|
1353
1490
|
const handle = this.handle;
|
|
@@ -1357,82 +1494,314 @@ class FileFinder {
|
|
|
1357
1494
|
this.watchers.clear();
|
|
1358
1495
|
}
|
|
1359
1496
|
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Check if this instance has been destroyed.
|
|
1499
|
+
*/
|
|
1360
1500
|
get isDestroyed() {
|
|
1361
1501
|
return this.handle === null;
|
|
1362
1502
|
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Guard that returns an error if the instance has been destroyed.
|
|
1505
|
+
*/
|
|
1363
1506
|
ensureAlive() {
|
|
1364
1507
|
if (this.handle === null) {
|
|
1365
1508
|
return err("FileFinder instance has been destroyed.");
|
|
1366
1509
|
}
|
|
1367
1510
|
return { ok: true, value: this.handle };
|
|
1368
1511
|
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Search for files matching the query.
|
|
1514
|
+
*
|
|
1515
|
+
* The query supports fuzzy matching and special syntax:
|
|
1516
|
+
* - `foo bar` - Match files containing "foo" and "bar"
|
|
1517
|
+
* - `src/` - Match files in src directory
|
|
1518
|
+
* - `file.ts:42` - Match file.ts with line 42
|
|
1519
|
+
* - `file.ts:42:10` - Match file.ts with line 42, column 10
|
|
1520
|
+
*
|
|
1521
|
+
* @param query - Search query string
|
|
1522
|
+
* @param options - Search options
|
|
1523
|
+
* @returns Search results with matched files and scores
|
|
1524
|
+
*
|
|
1525
|
+
* @example
|
|
1526
|
+
* ```typescript
|
|
1527
|
+
* const result = finder.search("main.ts", { pageSize: 10 });
|
|
1528
|
+
* if (result.ok) {
|
|
1529
|
+
* console.log(`Found ${result.value.totalMatched} files`);
|
|
1530
|
+
* for (const item of result.value.items) {
|
|
1531
|
+
* console.log(item.relativePath);
|
|
1532
|
+
* }
|
|
1533
|
+
* }
|
|
1534
|
+
* ```
|
|
1535
|
+
*/
|
|
1369
1536
|
fileSearch(query, options) {
|
|
1370
1537
|
const guard = this.ensureAlive();
|
|
1371
|
-
if (!guard.ok)
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1538
|
+
if (!guard.ok) return guard;
|
|
1539
|
+
return ffiSearch(
|
|
1540
|
+
guard.value,
|
|
1541
|
+
query,
|
|
1542
|
+
options?.currentFile ?? "",
|
|
1543
|
+
options?.maxThreads ?? 0,
|
|
1544
|
+
options?.pageIndex ?? 0,
|
|
1545
|
+
options?.pageSize ?? 0,
|
|
1546
|
+
options?.comboBoostMultiplier ?? 0,
|
|
1547
|
+
options?.minComboCount ?? 0
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Filters files using glob wildcard expression.
|
|
1552
|
+
*
|
|
1553
|
+
* The pattern is applied as a single pass SIMD optimized prefiltering
|
|
1554
|
+
* without any fuzzy matching involved. Faster and 100% compatible to npm `glob`.
|
|
1555
|
+
*
|
|
1556
|
+
* @param pattern - Glob pattern (required, non-empty)
|
|
1557
|
+
* @param options - Glob search options (pagination, max threads, current file)
|
|
1558
|
+
* @returns Search results with files matching the glob
|
|
1559
|
+
*
|
|
1560
|
+
* @example
|
|
1561
|
+
* ```typescript
|
|
1562
|
+
* const result = finder.glob("**\/*.rs", { pageSize: 100 });
|
|
1563
|
+
* if (result.ok) {
|
|
1564
|
+
* for (const item of result.value.items) {
|
|
1565
|
+
* console.log(item.relativePath);
|
|
1566
|
+
* }
|
|
1567
|
+
* }
|
|
1568
|
+
* ```
|
|
1569
|
+
*/
|
|
1375
1570
|
glob(pattern, options) {
|
|
1376
1571
|
const guard = this.ensureAlive();
|
|
1377
|
-
if (!guard.ok)
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1572
|
+
if (!guard.ok) return guard;
|
|
1573
|
+
return ffiGlob(
|
|
1574
|
+
guard.value,
|
|
1575
|
+
pattern,
|
|
1576
|
+
options?.currentFile ?? "",
|
|
1577
|
+
options?.maxThreads ?? 0,
|
|
1578
|
+
options?.pageIndex ?? 0,
|
|
1579
|
+
options?.pageSize ?? 0
|
|
1580
|
+
);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Search for directories matching the query.
|
|
1584
|
+
*
|
|
1585
|
+
* @param query - Search query string
|
|
1586
|
+
* @param options - Directory search options
|
|
1587
|
+
* @returns Search results with matched directories and scores
|
|
1588
|
+
*
|
|
1589
|
+
* @example
|
|
1590
|
+
* ```typescript
|
|
1591
|
+
* const result = finder.directorySearch("src/comp", { pageSize: 10 });
|
|
1592
|
+
* if (result.ok) {
|
|
1593
|
+
* console.log(`Found ${result.value.totalMatched} directories`);
|
|
1594
|
+
* for (const item of result.value.items) {
|
|
1595
|
+
* console.log(item.relativePath);
|
|
1596
|
+
* }
|
|
1597
|
+
* }
|
|
1598
|
+
* ```
|
|
1599
|
+
*/
|
|
1381
1600
|
directorySearch(query, options) {
|
|
1382
1601
|
const guard = this.ensureAlive();
|
|
1383
|
-
if (!guard.ok)
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1602
|
+
if (!guard.ok) return guard;
|
|
1603
|
+
return ffiSearchDirectories(
|
|
1604
|
+
guard.value,
|
|
1605
|
+
query,
|
|
1606
|
+
options?.currentFile ?? null,
|
|
1607
|
+
options?.maxThreads ?? 0,
|
|
1608
|
+
options?.pageIndex ?? 0,
|
|
1609
|
+
options?.pageSize ?? 0
|
|
1610
|
+
);
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Search for files and directories matching the query (mixed results).
|
|
1614
|
+
*
|
|
1615
|
+
* Results are interleaved by total score in descending order, mixing
|
|
1616
|
+
* both file and directory items.
|
|
1617
|
+
*
|
|
1618
|
+
* @param query - Search query string
|
|
1619
|
+
* @param options - Search options
|
|
1620
|
+
* @returns Mixed search results with files and directories interleaved by score
|
|
1621
|
+
*
|
|
1622
|
+
* @example
|
|
1623
|
+
* ```typescript
|
|
1624
|
+
* const result = finder.mixedSearch("main", { pageSize: 20 });
|
|
1625
|
+
* if (result.ok) {
|
|
1626
|
+
* for (const entry of result.value.items) {
|
|
1627
|
+
* if (entry.type === "file") {
|
|
1628
|
+
* console.log(`File: ${entry.item.relativePath}`);
|
|
1629
|
+
* } else {
|
|
1630
|
+
* console.log(`Dir: ${entry.item.relativePath}`);
|
|
1631
|
+
* }
|
|
1632
|
+
* }
|
|
1633
|
+
* }
|
|
1634
|
+
* ```
|
|
1635
|
+
*/
|
|
1387
1636
|
mixedSearch(query, options) {
|
|
1388
1637
|
const guard = this.ensureAlive();
|
|
1389
|
-
if (!guard.ok)
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1638
|
+
if (!guard.ok) return guard;
|
|
1639
|
+
return ffiSearchMixed(
|
|
1640
|
+
guard.value,
|
|
1641
|
+
query,
|
|
1642
|
+
options?.currentFile ?? "",
|
|
1643
|
+
options?.maxThreads ?? 0,
|
|
1644
|
+
options?.pageIndex ?? 0,
|
|
1645
|
+
options?.pageSize ?? 0,
|
|
1646
|
+
options?.comboBoostMultiplier ?? 0,
|
|
1647
|
+
options?.minComboCount ?? 0
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Search file contents (live grep).
|
|
1652
|
+
*
|
|
1653
|
+
* Searches through the contents of indexed files using the specified mode:
|
|
1654
|
+
* - `"plain"` (default): SIMD-accelerated literal text matching
|
|
1655
|
+
* - `"regex"`: Regular expression matching
|
|
1656
|
+
* - `"fuzzy"`: Smith-Waterman fuzzy matching per line
|
|
1657
|
+
*
|
|
1658
|
+
* Supports pagination for large result sets. The result includes a `nextCursor`
|
|
1659
|
+
* that can be passed back to fetch the next page.
|
|
1660
|
+
*
|
|
1661
|
+
* The query also supports constraint syntax:
|
|
1662
|
+
* - `*.ts pattern` - Only search in TypeScript files
|
|
1663
|
+
* - `src/ pattern` - Only search in the src directory
|
|
1664
|
+
*
|
|
1665
|
+
* @param query - Search query string
|
|
1666
|
+
* @param options - Grep options (mode, pagination, limits)
|
|
1667
|
+
* @returns Grep results with matched lines and file metadata
|
|
1668
|
+
*
|
|
1669
|
+
* @example
|
|
1670
|
+
* ```typescript
|
|
1671
|
+
* // First page
|
|
1672
|
+
* const result = finder.grep("TODO", { mode: "plain" });
|
|
1673
|
+
* if (result.ok) {
|
|
1674
|
+
* for (const match of result.value.items) {
|
|
1675
|
+
* console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);
|
|
1676
|
+
* }
|
|
1677
|
+
* // Fetch next page
|
|
1678
|
+
* if (result.value.nextCursor) {
|
|
1679
|
+
* const page2 = finder.grep("TODO", {
|
|
1680
|
+
* cursor: result.value.nextCursor,
|
|
1681
|
+
* });
|
|
1682
|
+
* }
|
|
1683
|
+
* }
|
|
1684
|
+
* ```
|
|
1685
|
+
*/
|
|
1393
1686
|
grep(query, options) {
|
|
1394
1687
|
const guard = this.ensureAlive();
|
|
1395
|
-
if (!guard.ok)
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1688
|
+
if (!guard.ok) return guard;
|
|
1689
|
+
return ffiLiveGrep(
|
|
1690
|
+
guard.value,
|
|
1691
|
+
query,
|
|
1692
|
+
options?.mode ?? "plain",
|
|
1693
|
+
options?.maxFileSize ?? 0,
|
|
1694
|
+
options?.maxMatchesPerFile ?? 0,
|
|
1695
|
+
options?.smartCase ?? true,
|
|
1696
|
+
options?.cursor?._offset ?? 0,
|
|
1697
|
+
options?.pageSize ?? 0,
|
|
1698
|
+
options?.timeBudgetMs ?? 0,
|
|
1699
|
+
options?.beforeContext ?? 0,
|
|
1700
|
+
options?.afterContext ?? 0,
|
|
1701
|
+
options?.classifyDefinitions ?? false
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Multi-pattern OR search using Aho-Corasick.
|
|
1706
|
+
*
|
|
1707
|
+
* Searches for lines matching ANY of the provided patterns using
|
|
1708
|
+
* SIMD-accelerated multi-needle matching. Faster than regex alternation
|
|
1709
|
+
* for literal text searches.
|
|
1710
|
+
*
|
|
1711
|
+
* Supports pagination. The result includes a `nextCursor` that can be
|
|
1712
|
+
* passed back to fetch the next page.
|
|
1713
|
+
*
|
|
1714
|
+
* @param options - Multi-grep options including patterns and optional constraints
|
|
1715
|
+
* @returns Grep results with matched lines and file metadata
|
|
1716
|
+
*
|
|
1717
|
+
* @example
|
|
1718
|
+
* ```typescript
|
|
1719
|
+
* const result = finder.multiGrep({
|
|
1720
|
+
* patterns: ["VideoFrame", "video_frame", "PreloadedImage"],
|
|
1721
|
+
* });
|
|
1722
|
+
* if (result.ok) {
|
|
1723
|
+
* for (const match of result.value.items) {
|
|
1724
|
+
* console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);
|
|
1725
|
+
* }
|
|
1726
|
+
* }
|
|
1727
|
+
* ```
|
|
1728
|
+
*/
|
|
1399
1729
|
multiGrep(options) {
|
|
1400
1730
|
const guard = this.ensureAlive();
|
|
1401
|
-
if (!guard.ok)
|
|
1402
|
-
return guard;
|
|
1731
|
+
if (!guard.ok) return guard;
|
|
1403
1732
|
if (!options.patterns || options.patterns.length === 0) {
|
|
1404
1733
|
return err("patterns array must have at least 1 element");
|
|
1405
1734
|
}
|
|
1406
|
-
return ffiMultiGrep(
|
|
1407
|
-
|
|
1408
|
-
|
|
1735
|
+
return ffiMultiGrep(
|
|
1736
|
+
guard.value,
|
|
1737
|
+
options.patterns.join("\n"),
|
|
1738
|
+
options.constraints ?? "",
|
|
1739
|
+
options.maxFileSize ?? 0,
|
|
1740
|
+
options.maxMatchesPerFile ?? 0,
|
|
1741
|
+
options.smartCase ?? true,
|
|
1742
|
+
options.cursor?._offset ?? 0,
|
|
1743
|
+
options.pageSize ?? 0,
|
|
1744
|
+
options.timeBudgetMs ?? 0,
|
|
1745
|
+
options.beforeContext ?? 0,
|
|
1746
|
+
options.afterContext ?? 0,
|
|
1747
|
+
options.classifyDefinitions ?? false
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Trigger a rescan of the indexed directory.
|
|
1752
|
+
*
|
|
1753
|
+
* This is useful after major file system changes that the
|
|
1754
|
+
* background watcher might have missed.
|
|
1755
|
+
*/
|
|
1409
1756
|
scanFiles() {
|
|
1410
1757
|
const guard = this.ensureAlive();
|
|
1411
|
-
if (!guard.ok)
|
|
1412
|
-
return guard;
|
|
1758
|
+
if (!guard.ok) return guard;
|
|
1413
1759
|
return ffiScanFiles(guard.value);
|
|
1414
1760
|
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Check if a scan is currently in progress.
|
|
1763
|
+
*/
|
|
1415
1764
|
isScanning() {
|
|
1416
|
-
if (this.handle === null)
|
|
1417
|
-
return false;
|
|
1765
|
+
if (this.handle === null) return false;
|
|
1418
1766
|
return ffiIsScanning(this.handle);
|
|
1419
1767
|
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Get the base path of the file picker (the root directory being indexed).
|
|
1770
|
+
*/
|
|
1420
1771
|
getBasePath() {
|
|
1421
1772
|
const guard = this.ensureAlive();
|
|
1422
|
-
if (!guard.ok)
|
|
1423
|
-
return guard;
|
|
1773
|
+
if (!guard.ok) return guard;
|
|
1424
1774
|
return ffiGetBasePath(guard.value);
|
|
1425
1775
|
}
|
|
1776
|
+
/**
|
|
1777
|
+
* Get the current scan progress.
|
|
1778
|
+
*/
|
|
1426
1779
|
getScanProgress() {
|
|
1427
1780
|
const guard = this.ensureAlive();
|
|
1428
|
-
if (!guard.ok)
|
|
1429
|
-
return guard;
|
|
1781
|
+
if (!guard.ok) return guard;
|
|
1430
1782
|
return ffiGetScanProgress(guard.value);
|
|
1431
1783
|
}
|
|
1432
|
-
|
|
1784
|
+
/**
|
|
1785
|
+
* Wait for the initial file scan to complete.
|
|
1786
|
+
* Non-blocking: polls `isScanning` and yields to the event loop between checks.
|
|
1787
|
+
*
|
|
1788
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)
|
|
1789
|
+
* @returns true if scan completed, false if timed out
|
|
1790
|
+
*
|
|
1791
|
+
* @example
|
|
1792
|
+
* ```typescript
|
|
1793
|
+
* const finder = FileFinder.create({ basePath: "/path/to/project" });
|
|
1794
|
+
* if (finder.ok) {
|
|
1795
|
+
* const completed = await finder.value.waitForScan(10000);
|
|
1796
|
+
* if (!completed.ok || !completed.value) {
|
|
1797
|
+
* console.warn("Scan did not complete in time");
|
|
1798
|
+
* }
|
|
1799
|
+
* }
|
|
1800
|
+
* ```
|
|
1801
|
+
*/
|
|
1802
|
+
async waitForScan(timeoutMs = 5e3) {
|
|
1433
1803
|
const guard = this.ensureAlive();
|
|
1434
|
-
if (!guard.ok)
|
|
1435
|
-
return guard;
|
|
1804
|
+
if (!guard.ok) return guard;
|
|
1436
1805
|
const deadline = Date.now() + timeoutMs;
|
|
1437
1806
|
while (this.isScanning()) {
|
|
1438
1807
|
if (Date.now() >= deadline) {
|
|
@@ -1442,21 +1811,36 @@ class FileFinder {
|
|
|
1442
1811
|
}
|
|
1443
1812
|
return { ok: true, value: true };
|
|
1444
1813
|
}
|
|
1445
|
-
|
|
1814
|
+
/**
|
|
1815
|
+
* Wait for the initial file scan to complete, blocking the calling thread.
|
|
1816
|
+
*
|
|
1817
|
+
* Backed by the native `fff_wait_for_scan` call. Prefer {@link waitForScan}
|
|
1818
|
+
* unless you specifically need synchronous blocking behaviour.
|
|
1819
|
+
*
|
|
1820
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)
|
|
1821
|
+
* @returns true if scan completed, false if timed out
|
|
1822
|
+
*/
|
|
1823
|
+
waitForScanBlocking(timeoutMs = 5e3) {
|
|
1446
1824
|
const guard = this.ensureAlive();
|
|
1447
|
-
if (!guard.ok)
|
|
1448
|
-
return guard;
|
|
1825
|
+
if (!guard.ok) return guard;
|
|
1449
1826
|
return ffiWaitForScan(guard.value, timeoutMs);
|
|
1450
1827
|
}
|
|
1451
|
-
|
|
1828
|
+
/**
|
|
1829
|
+
* Wait until the index is fully ready: the scan has finished and the warmup
|
|
1830
|
+
* (content indexing / bigram) phase has completed.
|
|
1831
|
+
*
|
|
1832
|
+
* Non-blocking: polls `getScanProgress` and yields to the event loop.
|
|
1833
|
+
*
|
|
1834
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)
|
|
1835
|
+
* @returns true if the index became ready, false if timed out
|
|
1836
|
+
*/
|
|
1837
|
+
async waitForIndexReady(timeoutMs = 5e3) {
|
|
1452
1838
|
const guard = this.ensureAlive();
|
|
1453
|
-
if (!guard.ok)
|
|
1454
|
-
return guard;
|
|
1839
|
+
if (!guard.ok) return guard;
|
|
1455
1840
|
const deadline = Date.now() + timeoutMs;
|
|
1456
1841
|
while (true) {
|
|
1457
1842
|
const progress = this.getScanProgress();
|
|
1458
|
-
if (!progress.ok)
|
|
1459
|
-
return progress;
|
|
1843
|
+
if (!progress.ok) return progress;
|
|
1460
1844
|
if (!progress.value.isScanning && progress.value.isWarmupComplete) {
|
|
1461
1845
|
return { ok: true, value: true };
|
|
1462
1846
|
}
|
|
@@ -1466,28 +1850,51 @@ class FileFinder {
|
|
|
1466
1850
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1467
1851
|
}
|
|
1468
1852
|
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Change the indexed directory to a new path.
|
|
1855
|
+
*
|
|
1856
|
+
* This stops the current file watcher and starts indexing the new directory.
|
|
1857
|
+
*
|
|
1858
|
+
* @param newPath - New directory path to index
|
|
1859
|
+
*/
|
|
1469
1860
|
reindex(newPath) {
|
|
1470
1861
|
const guard = this.ensureAlive();
|
|
1471
|
-
if (!guard.ok)
|
|
1472
|
-
return guard;
|
|
1862
|
+
if (!guard.ok) return guard;
|
|
1473
1863
|
return ffiRestartIndex(guard.value, newPath);
|
|
1474
1864
|
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Refresh the git status cache.
|
|
1867
|
+
*
|
|
1868
|
+
* @returns Number of files with updated git status
|
|
1869
|
+
*/
|
|
1475
1870
|
refreshGitStatus() {
|
|
1476
1871
|
const guard = this.ensureAlive();
|
|
1477
|
-
if (!guard.ok)
|
|
1478
|
-
return guard;
|
|
1872
|
+
if (!guard.ok) return guard;
|
|
1479
1873
|
return ffiRefreshGitStatus(guard.value);
|
|
1480
1874
|
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Track query completion for smart suggestions.
|
|
1877
|
+
*
|
|
1878
|
+
* Call this when a user selects a file from search results.
|
|
1879
|
+
* This helps improve future search rankings for similar queries.
|
|
1880
|
+
*
|
|
1881
|
+
* @param query - The search query that was used
|
|
1882
|
+
* @param selectedFilePath - The file path that was selected
|
|
1883
|
+
*/
|
|
1481
1884
|
trackQuery(query, selectedFilePath) {
|
|
1482
1885
|
const guard = this.ensureAlive();
|
|
1483
|
-
if (!guard.ok)
|
|
1484
|
-
return guard;
|
|
1886
|
+
if (!guard.ok) return guard;
|
|
1485
1887
|
return ffiTrackQuery(guard.value, query, selectedFilePath);
|
|
1486
1888
|
}
|
|
1889
|
+
/**
|
|
1890
|
+
* Get a historical query by offset.
|
|
1891
|
+
*
|
|
1892
|
+
* @param offset - Offset from most recent (0 = most recent)
|
|
1893
|
+
* @returns The historical query string, or null if not found
|
|
1894
|
+
*/
|
|
1487
1895
|
getHistoricalQuery(offset) {
|
|
1488
1896
|
const guard = this.ensureAlive();
|
|
1489
|
-
if (!guard.ok)
|
|
1490
|
-
return guard;
|
|
1897
|
+
if (!guard.ok) return guard;
|
|
1491
1898
|
return ffiGetHistoricalQuery(guard.value, offset);
|
|
1492
1899
|
}
|
|
1493
1900
|
watch(patternOrCallback, callbackOrOptions, maybeOptions) {
|
|
@@ -1499,35 +1906,66 @@ class FileFinder {
|
|
|
1499
1906
|
return err("watch callback must be a function");
|
|
1500
1907
|
}
|
|
1501
1908
|
const guard = this.ensureAlive();
|
|
1502
|
-
if (!guard.ok)
|
|
1503
|
-
return guard;
|
|
1909
|
+
if (!guard.ok) return guard;
|
|
1504
1910
|
const created = ffiWatch(guard.value, pattern, options?.ignore ?? [], callback);
|
|
1505
|
-
if (!created.ok)
|
|
1506
|
-
return created;
|
|
1911
|
+
if (!created.ok) return created;
|
|
1507
1912
|
const watchId = created.value;
|
|
1508
1913
|
this.watchers.add(watchId);
|
|
1509
1914
|
return {
|
|
1510
1915
|
ok: true,
|
|
1511
1916
|
value: () => {
|
|
1512
|
-
if (!this.watchers.delete(watchId))
|
|
1513
|
-
|
|
1514
|
-
if (this.handle !== null)
|
|
1515
|
-
ffiUnwatch(this.handle, watchId);
|
|
1917
|
+
if (!this.watchers.delete(watchId)) return;
|
|
1918
|
+
if (this.handle !== null) ffiUnwatch(this.handle, watchId);
|
|
1516
1919
|
}
|
|
1517
1920
|
};
|
|
1518
1921
|
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Get health check information.
|
|
1924
|
+
*
|
|
1925
|
+
* Useful for debugging and verifying the file finder is working correctly.
|
|
1926
|
+
*
|
|
1927
|
+
* @param testPath - Optional path to test git repository detection
|
|
1928
|
+
*/
|
|
1519
1929
|
healthCheck(testPath) {
|
|
1520
1930
|
return ffiHealthCheck(this.handle, testPath || "");
|
|
1521
1931
|
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Check if the native library is available.
|
|
1934
|
+
*/
|
|
1522
1935
|
static isAvailable() {
|
|
1523
1936
|
return isAvailable();
|
|
1524
1937
|
}
|
|
1938
|
+
/**
|
|
1939
|
+
* Ensure the native library is loaded.
|
|
1940
|
+
*
|
|
1941
|
+
* Loads the native library from the platform-specific npm package
|
|
1942
|
+
* or a local dev build. Throws if the binary is not found.
|
|
1943
|
+
*/
|
|
1525
1944
|
static ensureLoaded() {
|
|
1526
1945
|
ensureLoaded();
|
|
1527
1946
|
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Get a health check without requiring an instance.
|
|
1949
|
+
*
|
|
1950
|
+
* Returns limited info (version + git only, no picker/frecency/query data).
|
|
1951
|
+
*
|
|
1952
|
+
* @param testPath - Optional path to test git repository detection
|
|
1953
|
+
*/
|
|
1528
1954
|
static healthCheckStatic(testPath) {
|
|
1529
1955
|
return ffiHealthCheck(null, testPath || "");
|
|
1530
1956
|
}
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1957
|
+
};
|
|
1958
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1959
|
+
0 && (module.exports = {
|
|
1960
|
+
FileFinder,
|
|
1961
|
+
binaryExists,
|
|
1962
|
+
closeLibrary,
|
|
1963
|
+
err,
|
|
1964
|
+
findBinary,
|
|
1965
|
+
getLibExtension,
|
|
1966
|
+
getLibFilename,
|
|
1967
|
+
getNpmPackageName,
|
|
1968
|
+
getTriple,
|
|
1969
|
+
ok
|
|
1970
|
+
});
|
|
1971
|
+
//# sourceMappingURL=index.cjs.map
|