@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/README.md +2 -2
- package/dist/binary.d.ts.map +1 -0
- package/dist/fff-api.d.ts.map +1 -0
- package/dist/ffi.d.ts.map +1 -0
- package/dist/finder.d.ts.map +1 -0
- package/dist/index.cjs +1533 -0
- package/dist/index.cjs.map +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1504 -0
- package/dist/index.js.map +14 -0
- package/dist/platform.d.ts.map +1 -0
- package/package.json +25 -18
- package/dist/src/binary.d.ts.map +0 -1
- package/dist/src/binary.js +0 -135
- package/dist/src/binary.js.map +0 -1
- package/dist/src/fff-api.d.ts.map +0 -1
- package/dist/src/fff-api.js +0 -24
- package/dist/src/fff-api.js.map +0 -1
- package/dist/src/ffi.d.ts.map +0 -1
- package/dist/src/ffi.js +0 -1365
- package/dist/src/ffi.js.map +0 -1
- package/dist/src/finder.d.ts.map +0 -1
- package/dist/src/finder.js +0 -528
- package/dist/src/finder.js.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -47
- package/dist/src/index.js.map +0 -1
- package/dist/src/platform.d.ts.map +0 -1
- package/dist/src/platform.js +0 -124
- package/dist/src/platform.js.map +0 -1
- /package/dist/{src/binary.d.ts → binary.d.ts} +0 -0
- /package/dist/{src/fff-api.d.ts → fff-api.d.ts} +0 -0
- /package/dist/{src/ffi.d.ts → ffi.d.ts} +0 -0
- /package/dist/{src/finder.d.ts → finder.d.ts} +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
- /package/dist/{src/platform.d.ts → platform.d.ts} +0 -0
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
|