@ff-labs/fff-bun 0.1.0-nightly.fcdf4a9 → 0.2.4-dev.233679d
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 +18 -18
- package/examples/grep.ts +1 -1
- package/package.json +9 -14
- package/src/download.ts +20 -143
- package/src/ffi.ts +341 -60
- package/src/finder.ts +72 -53
- package/src/git-lifecycle.test.ts +7 -7
- package/src/index.test.ts +13 -21
- package/src/index.ts +2 -6
- package/src/platform.ts +9 -9
- package/src/types.ts +0 -131
- package/bin/libfff_c.dylib +0 -0
- package/scripts/cli.ts +0 -116
- package/scripts/postinstall.ts +0 -49
|
@@ -51,7 +51,7 @@ function sleep(ms: number) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function findFile(finder: FileFinder, name: string): FileItem | undefined {
|
|
54
|
-
const result = finder.
|
|
54
|
+
const result = finder.fileSearch(name, { pageSize: 200 });
|
|
55
55
|
if (!result.ok) throw new Error(`search failed: ${result.error}`);
|
|
56
56
|
return result.value.items.find((item) => item.fileName === name);
|
|
57
57
|
}
|
|
@@ -99,15 +99,15 @@ async function waitForFileGone(finder: FileFinder, name: string): Promise<boolea
|
|
|
99
99
|
async function waitForFileCount(finder: FileFinder, count: number): Promise<number> {
|
|
100
100
|
const start = Date.now();
|
|
101
101
|
while (Date.now() - start < WATCHER_TIMEOUT_MS) {
|
|
102
|
-
const result = finder.
|
|
102
|
+
const result = finder.fileSearch("", { pageSize: 200 });
|
|
103
103
|
if (result.ok && result.value.totalFiles === count) return count;
|
|
104
104
|
await sleep(POLL_INTERVAL_MS);
|
|
105
105
|
}
|
|
106
|
-
const result = finder.
|
|
106
|
+
const result = finder.fileSearch("", { pageSize: 200 });
|
|
107
107
|
return result.ok ? result.value.totalFiles : -1;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/** Poll
|
|
110
|
+
/** Poll grep until predicate on totalMatched is satisfied, or the timeout is exceeded. */
|
|
111
111
|
async function waitForGrep(
|
|
112
112
|
finder: FileFinder,
|
|
113
113
|
pattern: string,
|
|
@@ -116,11 +116,11 @@ async function waitForGrep(
|
|
|
116
116
|
) {
|
|
117
117
|
const start = Date.now();
|
|
118
118
|
while (Date.now() - start < WATCHER_TIMEOUT_MS) {
|
|
119
|
-
const result = finder.
|
|
119
|
+
const result = finder.grep(pattern, options);
|
|
120
120
|
if (result.ok && predicate(result.value.totalMatched)) return result;
|
|
121
121
|
await sleep(POLL_INTERVAL_MS);
|
|
122
122
|
}
|
|
123
|
-
return finder.
|
|
123
|
+
return finder.grep(pattern, options);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
describe.skipIf(process.platform === "win32")("Git lifecycle integration", () => {
|
|
@@ -161,7 +161,7 @@ describe.skipIf(process.platform === "win32")("Git lifecycle integration", () =>
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
test("initial scan indexes all committed files", () => {
|
|
164
|
-
const result = finder.
|
|
164
|
+
const result = finder.fileSearch("", { pageSize: 200 });
|
|
165
165
|
expect(result.ok).toBe(true);
|
|
166
166
|
if (!result.ok) return;
|
|
167
167
|
|
package/src/index.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
2
|
-
import { findBinary
|
|
2
|
+
import { findBinary } from "./download";
|
|
3
3
|
import { FileFinder } from "./index";
|
|
4
4
|
import { getLibExtension, getLibFilename, getTriple } from "./platform";
|
|
5
5
|
|
|
@@ -46,14 +46,6 @@ describe("Platform Detection", () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
describe("Binary Detection", () => {
|
|
49
|
-
test("getDevBinaryPath finds local build", () => {
|
|
50
|
-
const devPath = getDevBinaryPath();
|
|
51
|
-
expect(devPath).not.toBeNull();
|
|
52
|
-
// Normalize path for cross-platform comparison (Windows uses backslashes)
|
|
53
|
-
const normalizedPath = normalizePath(devPath);
|
|
54
|
-
expect(normalizedPath).toContain("target/release");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
49
|
test("findBinary returns a path", () => {
|
|
58
50
|
const path = findBinary();
|
|
59
51
|
expect(path).not.toBeNull();
|
|
@@ -120,7 +112,7 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
120
112
|
if (progress.ok) {
|
|
121
113
|
}
|
|
122
114
|
|
|
123
|
-
const result = finder.
|
|
115
|
+
const result = finder.fileSearch("");
|
|
124
116
|
expect(result.ok).toBe(true);
|
|
125
117
|
|
|
126
118
|
if (result.ok) {
|
|
@@ -140,7 +132,7 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
140
132
|
});
|
|
141
133
|
|
|
142
134
|
test("search returns a valid result structure", () => {
|
|
143
|
-
const result = finder.
|
|
135
|
+
const result = finder.fileSearch("Cargo.toml");
|
|
144
136
|
expect(result.ok).toBe(true);
|
|
145
137
|
|
|
146
138
|
if (result.ok) {
|
|
@@ -152,7 +144,7 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
152
144
|
});
|
|
153
145
|
|
|
154
146
|
test("search returns empty for non-matching query", () => {
|
|
155
|
-
const result = finder.
|
|
147
|
+
const result = finder.fileSearch("xyznonexistentfilenamexyz123456");
|
|
156
148
|
expect(result.ok).toBe(true);
|
|
157
149
|
|
|
158
150
|
if (result.ok) {
|
|
@@ -162,7 +154,7 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
162
154
|
});
|
|
163
155
|
|
|
164
156
|
test("search respects pageSize option", () => {
|
|
165
|
-
const result = finder.
|
|
157
|
+
const result = finder.fileSearch("ts", { pageSize: 3 });
|
|
166
158
|
expect(result.ok).toBe(true);
|
|
167
159
|
|
|
168
160
|
if (result.ok) {
|
|
@@ -170,8 +162,8 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
170
162
|
}
|
|
171
163
|
});
|
|
172
164
|
|
|
173
|
-
test("
|
|
174
|
-
const result = finder.
|
|
165
|
+
test("grep plain text returns matching lines", () => {
|
|
166
|
+
const result = finder.grep("fff-core", {
|
|
175
167
|
mode: "plain",
|
|
176
168
|
});
|
|
177
169
|
expect(result.ok).toBe(true);
|
|
@@ -205,9 +197,9 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
205
197
|
}
|
|
206
198
|
});
|
|
207
199
|
|
|
208
|
-
test("
|
|
200
|
+
test("grep fuzzy mode returns results with scores", () => {
|
|
209
201
|
// Intentional typo: "depdnency" instead of "dependency" to exercise fuzzy matching
|
|
210
|
-
const result = finder.
|
|
202
|
+
const result = finder.grep("depdnency", {
|
|
211
203
|
mode: "fuzzy",
|
|
212
204
|
});
|
|
213
205
|
expect(result.ok).toBe(true);
|
|
@@ -273,8 +265,8 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
273
265
|
const finder2 = result2.value;
|
|
274
266
|
|
|
275
267
|
// Both should work independently
|
|
276
|
-
const search1 = finder.
|
|
277
|
-
const search2 = finder2.
|
|
268
|
+
const search1 = finder.fileSearch("Cargo");
|
|
269
|
+
const search2 = finder2.fileSearch("Cargo");
|
|
278
270
|
|
|
279
271
|
expect(search1.ok).toBe(true);
|
|
280
272
|
expect(search2.ok).toBe(true);
|
|
@@ -282,7 +274,7 @@ describe("FileFinder - Full Lifecycle", () => {
|
|
|
282
274
|
// Destroying one should not affect the other
|
|
283
275
|
finder2.destroy();
|
|
284
276
|
|
|
285
|
-
const search3 = finder.
|
|
277
|
+
const search3 = finder.fileSearch("Cargo");
|
|
286
278
|
expect(search3.ok).toBe(true);
|
|
287
279
|
}
|
|
288
280
|
});
|
|
@@ -297,7 +289,7 @@ describe("FileFinder - Error Handling", () => {
|
|
|
297
289
|
const f = createResult.value;
|
|
298
290
|
f.destroy();
|
|
299
291
|
|
|
300
|
-
const result = f.
|
|
292
|
+
const result = f.fileSearch("test");
|
|
301
293
|
expect(result.ok).toBe(false);
|
|
302
294
|
if (!result.ok) {
|
|
303
295
|
expect(result.error).toContain("destroyed");
|
package/src/index.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* finder.waitForScan(5000);
|
|
24
24
|
*
|
|
25
25
|
* // Search for files
|
|
26
|
-
* const search = finder.
|
|
26
|
+
* const search = finder.fileSearch("main.ts");
|
|
27
27
|
* if (search.ok) {
|
|
28
28
|
* for (const item of search.value.items) {
|
|
29
29
|
* console.log(item.relativePath);
|
|
@@ -37,15 +37,11 @@
|
|
|
37
37
|
* @packageDocumentation
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
-
export { FileFinder } from "./finder";
|
|
41
|
-
|
|
42
40
|
export {
|
|
43
41
|
binaryExists,
|
|
44
|
-
downloadBinary,
|
|
45
|
-
ensureBinary,
|
|
46
42
|
findBinary,
|
|
47
|
-
getBinaryPath,
|
|
48
43
|
} from "./download";
|
|
44
|
+
export { FileFinder } from "./finder";
|
|
49
45
|
|
|
50
46
|
export {
|
|
51
47
|
getLibExtension,
|
package/src/platform.ts
CHANGED
|
@@ -95,20 +95,20 @@ export function getLibFilename(): string {
|
|
|
95
95
|
* Map from Rust target triple to npm platform package name
|
|
96
96
|
*/
|
|
97
97
|
const TRIPLE_TO_NPM_PACKAGE: Record<string, string> = {
|
|
98
|
-
"aarch64-apple-darwin": "@ff-labs/fff-
|
|
99
|
-
"x86_64-apple-darwin": "@ff-labs/fff-
|
|
100
|
-
"x86_64-unknown-linux-gnu": "@ff-labs/fff-
|
|
101
|
-
"aarch64-unknown-linux-gnu": "@ff-labs/fff-
|
|
102
|
-
"x86_64-unknown-linux-musl": "@ff-labs/fff-
|
|
103
|
-
"aarch64-unknown-linux-musl": "@ff-labs/fff-
|
|
104
|
-
"x86_64-pc-windows-msvc": "@ff-labs/fff-
|
|
105
|
-
"aarch64-pc-windows-msvc": "@ff-labs/fff-
|
|
98
|
+
"aarch64-apple-darwin": "@ff-labs/fff-bin-darwin-arm64",
|
|
99
|
+
"x86_64-apple-darwin": "@ff-labs/fff-bin-darwin-x64",
|
|
100
|
+
"x86_64-unknown-linux-gnu": "@ff-labs/fff-bin-linux-x64-gnu",
|
|
101
|
+
"aarch64-unknown-linux-gnu": "@ff-labs/fff-bin-linux-arm64-gnu",
|
|
102
|
+
"x86_64-unknown-linux-musl": "@ff-labs/fff-bin-linux-x64-musl",
|
|
103
|
+
"aarch64-unknown-linux-musl": "@ff-labs/fff-bin-linux-arm64-musl",
|
|
104
|
+
"x86_64-pc-windows-msvc": "@ff-labs/fff-bin-win32-x64",
|
|
105
|
+
"aarch64-pc-windows-msvc": "@ff-labs/fff-bin-win32-arm64",
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
109
|
* Get the npm package name for the current platform's native binary.
|
|
110
110
|
*
|
|
111
|
-
* @returns Package name like "@ff-labs/fff-
|
|
111
|
+
* @returns Package name like "@ff-labs/fff-bin-darwin-arm64"
|
|
112
112
|
* @throws If the current platform is not supported
|
|
113
113
|
*/
|
|
114
114
|
export function getNpmPackageName(): string {
|
package/src/types.ts
CHANGED
|
@@ -208,62 +208,6 @@ export interface HealthCheck {
|
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
/**
|
|
212
|
-
* Internal: Options format sent to Rust FFI
|
|
213
|
-
* @internal
|
|
214
|
-
*/
|
|
215
|
-
export interface InitOptionsInternal {
|
|
216
|
-
base_path: string;
|
|
217
|
-
frecency_db_path?: string;
|
|
218
|
-
history_db_path?: string;
|
|
219
|
-
use_unsafe_no_lock: boolean;
|
|
220
|
-
warmup_mmap_cache: boolean;
|
|
221
|
-
ai_mode: boolean;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Internal: Search options format sent to Rust FFI
|
|
226
|
-
* @internal
|
|
227
|
-
*/
|
|
228
|
-
export interface SearchOptionsInternal {
|
|
229
|
-
max_threads?: number;
|
|
230
|
-
current_file?: string;
|
|
231
|
-
combo_boost_multiplier?: number;
|
|
232
|
-
min_combo_count?: number;
|
|
233
|
-
page_index?: number;
|
|
234
|
-
page_size?: number;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Convert public InitOptions to internal format
|
|
239
|
-
* @internal
|
|
240
|
-
*/
|
|
241
|
-
export function toInternalInitOptions(opts: InitOptions): InitOptionsInternal {
|
|
242
|
-
return {
|
|
243
|
-
base_path: opts.basePath,
|
|
244
|
-
frecency_db_path: opts.frecencyDbPath,
|
|
245
|
-
history_db_path: opts.historyDbPath,
|
|
246
|
-
use_unsafe_no_lock: opts.useUnsafeNoLock ?? false,
|
|
247
|
-
warmup_mmap_cache: opts.warmupMmapCache ?? false,
|
|
248
|
-
ai_mode: opts.aiMode ?? false,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Convert public SearchOptions to internal format
|
|
254
|
-
* @internal
|
|
255
|
-
*/
|
|
256
|
-
export function toInternalSearchOptions(opts?: SearchOptions): SearchOptionsInternal {
|
|
257
|
-
return {
|
|
258
|
-
max_threads: opts?.maxThreads,
|
|
259
|
-
current_file: opts?.currentFile,
|
|
260
|
-
combo_boost_multiplier: opts?.comboBoostMultiplier,
|
|
261
|
-
min_combo_count: opts?.minComboCount,
|
|
262
|
-
page_index: opts?.pageIndex,
|
|
263
|
-
page_size: opts?.pageSize,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
211
|
/**
|
|
268
212
|
* Grep search mode
|
|
269
213
|
*/
|
|
@@ -417,78 +361,3 @@ export interface MultiGrepOptions {
|
|
|
417
361
|
afterContext?: number;
|
|
418
362
|
}
|
|
419
363
|
|
|
420
|
-
/**
|
|
421
|
-
* Internal: Multi-grep options format sent to Rust FFI
|
|
422
|
-
* @internal
|
|
423
|
-
*/
|
|
424
|
-
export interface MultiGrepOptionsInternal {
|
|
425
|
-
patterns: string[];
|
|
426
|
-
constraints?: string;
|
|
427
|
-
max_file_size?: number;
|
|
428
|
-
max_matches_per_file?: number;
|
|
429
|
-
smart_case?: boolean;
|
|
430
|
-
file_offset?: number;
|
|
431
|
-
page_limit?: number;
|
|
432
|
-
time_budget_ms?: number;
|
|
433
|
-
before_context?: number;
|
|
434
|
-
after_context?: number;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Convert public MultiGrepOptions to internal format
|
|
439
|
-
* @internal
|
|
440
|
-
*/
|
|
441
|
-
export function toInternalMultiGrepOptions(
|
|
442
|
-
opts: MultiGrepOptions,
|
|
443
|
-
pageLimit?: number,
|
|
444
|
-
): MultiGrepOptionsInternal {
|
|
445
|
-
return {
|
|
446
|
-
patterns: opts.patterns,
|
|
447
|
-
constraints: opts.constraints,
|
|
448
|
-
max_file_size: opts.maxFileSize,
|
|
449
|
-
max_matches_per_file: opts.maxMatchesPerFile,
|
|
450
|
-
smart_case: opts.smartCase,
|
|
451
|
-
file_offset: opts.cursor?._offset ?? 0,
|
|
452
|
-
page_limit: pageLimit,
|
|
453
|
-
time_budget_ms: opts.timeBudgetMs,
|
|
454
|
-
before_context: opts.beforeContext,
|
|
455
|
-
after_context: opts.afterContext,
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Internal: Grep options format sent to Rust FFI
|
|
461
|
-
* @internal
|
|
462
|
-
*/
|
|
463
|
-
export interface GrepOptionsInternal {
|
|
464
|
-
max_file_size?: number;
|
|
465
|
-
max_matches_per_file?: number;
|
|
466
|
-
smart_case?: boolean;
|
|
467
|
-
file_offset?: number;
|
|
468
|
-
page_limit?: number;
|
|
469
|
-
mode?: string;
|
|
470
|
-
time_budget_ms?: number;
|
|
471
|
-
before_context?: number;
|
|
472
|
-
after_context?: number;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Convert public GrepOptions to internal format
|
|
477
|
-
* @internal
|
|
478
|
-
*/
|
|
479
|
-
export function toInternalGrepOptions(
|
|
480
|
-
opts?: GrepOptions,
|
|
481
|
-
pageLimit?: number,
|
|
482
|
-
): GrepOptionsInternal {
|
|
483
|
-
return {
|
|
484
|
-
max_file_size: opts?.maxFileSize,
|
|
485
|
-
max_matches_per_file: opts?.maxMatchesPerFile,
|
|
486
|
-
smart_case: opts?.smartCase,
|
|
487
|
-
file_offset: opts?.cursor?._offset ?? 0,
|
|
488
|
-
page_limit: pageLimit,
|
|
489
|
-
mode: opts?.mode,
|
|
490
|
-
time_budget_ms: opts?.timeBudgetMs,
|
|
491
|
-
before_context: opts?.beforeContext,
|
|
492
|
-
after_context: opts?.afterContext,
|
|
493
|
-
};
|
|
494
|
-
}
|
package/bin/libfff_c.dylib
DELETED
|
Binary file
|
package/scripts/cli.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* CLI tool for fff package management
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* bunx fff download [tag] - Download native binary from GitHub
|
|
7
|
-
* bunx fff info - Show platform and binary info
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { downloadBinary, getBinaryPath, findBinary } from "../src/download";
|
|
11
|
-
import {
|
|
12
|
-
getTriple,
|
|
13
|
-
getLibExtension,
|
|
14
|
-
getLibFilename,
|
|
15
|
-
getNpmPackageName,
|
|
16
|
-
} from "../src/platform";
|
|
17
|
-
import { dirname, join } from "node:path";
|
|
18
|
-
import { fileURLToPath } from "node:url";
|
|
19
|
-
|
|
20
|
-
const args = process.argv.slice(2);
|
|
21
|
-
const command = args[0];
|
|
22
|
-
|
|
23
|
-
interface PackageJson {
|
|
24
|
-
version: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function getPackageInfo(): Promise<PackageJson> {
|
|
28
|
-
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
29
|
-
const packageJsonPath = join(currentDir, "..", "package.json");
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
return await Bun.file(packageJsonPath).json();
|
|
33
|
-
} catch {
|
|
34
|
-
return { version: "unknown" };
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function main() {
|
|
39
|
-
switch (command) {
|
|
40
|
-
case "download": {
|
|
41
|
-
const tag = args[1];
|
|
42
|
-
console.log("fff: Downloading native library from GitHub...");
|
|
43
|
-
try {
|
|
44
|
-
const resolvedTag = await downloadBinary(tag);
|
|
45
|
-
console.log(`fff: Download complete! (${resolvedTag})`);
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error("fff: Download failed:", error);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
case "info": {
|
|
54
|
-
const pkg = await getPackageInfo();
|
|
55
|
-
let npmPackage: string;
|
|
56
|
-
try {
|
|
57
|
-
npmPackage = getNpmPackageName();
|
|
58
|
-
} catch {
|
|
59
|
-
npmPackage = "unsupported";
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
console.log("fff - Fast File Finder");
|
|
63
|
-
console.log(`Package version: ${pkg.version}`);
|
|
64
|
-
console.log("");
|
|
65
|
-
console.log("Platform Information:");
|
|
66
|
-
console.log(` Triple: ${getTriple()}`);
|
|
67
|
-
console.log(` Extension: ${getLibExtension()}`);
|
|
68
|
-
console.log(` Library name: ${getLibFilename()}`);
|
|
69
|
-
console.log(` npm package: ${npmPackage}`);
|
|
70
|
-
console.log("");
|
|
71
|
-
console.log("Binary Status:");
|
|
72
|
-
const existing = findBinary();
|
|
73
|
-
if (existing) {
|
|
74
|
-
console.log(` Found: ${existing}`);
|
|
75
|
-
} else {
|
|
76
|
-
console.log(` Not found`);
|
|
77
|
-
console.log(` Expected path: ${getBinaryPath()}`);
|
|
78
|
-
console.log(` Try: bun add ${npmPackage}`);
|
|
79
|
-
}
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
case "version":
|
|
84
|
-
case "--version":
|
|
85
|
-
case "-v": {
|
|
86
|
-
const pkg = await getPackageInfo();
|
|
87
|
-
console.log(pkg.version);
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
default: {
|
|
92
|
-
const pkg = await getPackageInfo();
|
|
93
|
-
console.log(`fff - Fast File Finder CLI v${pkg.version}`);
|
|
94
|
-
console.log("");
|
|
95
|
-
console.log("Usage:");
|
|
96
|
-
console.log(
|
|
97
|
-
" bunx fff download [tag] Download native binary from GitHub (fallback)",
|
|
98
|
-
);
|
|
99
|
-
console.log(" bunx fff info Show platform and binary info");
|
|
100
|
-
console.log(" bunx fff version Show version");
|
|
101
|
-
console.log(" bunx fff help Show this help message");
|
|
102
|
-
console.log("");
|
|
103
|
-
console.log("Examples:");
|
|
104
|
-
console.log(" bunx fff download Download latest binary from GitHub");
|
|
105
|
-
console.log(" bunx fff download abc1234 Download specific release tag");
|
|
106
|
-
console.log("");
|
|
107
|
-
console.log(
|
|
108
|
-
"Note: Binaries are normally provided via platform-specific npm packages.",
|
|
109
|
-
);
|
|
110
|
-
console.log("The download command is a fallback for when those aren't available.");
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
main();
|
package/scripts/postinstall.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* Postinstall script - ensures the native binary is available
|
|
4
|
-
*
|
|
5
|
-
* Resolution order:
|
|
6
|
-
* 1. Platform-specific npm package (installed via optionalDependencies)
|
|
7
|
-
* 2. Local dev build (target/release or target/debug)
|
|
8
|
-
* 3. Fallback: download from GitHub releases
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { findBinary, downloadBinary } from "../src/download";
|
|
12
|
-
import { getNpmPackageName } from "../src/platform";
|
|
13
|
-
|
|
14
|
-
async function main() {
|
|
15
|
-
// Check if binary is already available (npm package or dev build)
|
|
16
|
-
const existing = findBinary();
|
|
17
|
-
if (existing) {
|
|
18
|
-
console.log(`fff: Native library found at ${existing}`);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Binary not found via npm package - try downloading from GitHub as fallback
|
|
23
|
-
let packageName: string;
|
|
24
|
-
try {
|
|
25
|
-
packageName = getNpmPackageName();
|
|
26
|
-
} catch {
|
|
27
|
-
packageName = "unknown";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log(
|
|
31
|
-
`fff: Platform package ${packageName} not found, falling back to GitHub download...`,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const tag = await downloadBinary();
|
|
36
|
-
console.log(`fff: Native library installed successfully! (${tag})`);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
console.error("fff: Failed to download native library:", error);
|
|
39
|
-
console.error("");
|
|
40
|
-
console.error("fff: You can build from source instead:");
|
|
41
|
-
console.error(" cargo build --release -p fff-c");
|
|
42
|
-
console.error("");
|
|
43
|
-
console.error("fff: Or run `bunx fff download` after fixing network issues.");
|
|
44
|
-
// Don't exit with error - allow install to complete
|
|
45
|
-
// The error will surface when the user tries to use the library
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
main();
|