@ff-labs/fff-bun 0.4.3-nightly.eb577ea → 0.5.0
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/package.json +9 -9
- package/src/ffi.ts +25 -6
- package/src/finder.ts +17 -0
- package/src/git-lifecycle.test.ts +15 -1
- package/src/types.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ff-labs/fff-bun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "High-performance fuzzy file finder for Bun - perfect for LLM agent tools",
|
|
6
6
|
"type": "module",
|
|
@@ -62,14 +62,14 @@
|
|
|
62
62
|
},
|
|
63
63
|
"homepage": "https://github.com/dmtrKovalenko/fff.nvim#readme",
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@ff-labs/fff-bin-darwin-arm64": "0.
|
|
66
|
-
"@ff-labs/fff-bin-darwin-x64": "0.
|
|
67
|
-
"@ff-labs/fff-bin-linux-x64-gnu": "0.
|
|
68
|
-
"@ff-labs/fff-bin-linux-arm64-gnu": "0.
|
|
69
|
-
"@ff-labs/fff-bin-linux-x64-musl": "0.
|
|
70
|
-
"@ff-labs/fff-bin-linux-arm64-musl": "0.
|
|
71
|
-
"@ff-labs/fff-bin-win32-x64": "0.
|
|
72
|
-
"@ff-labs/fff-bin-win32-arm64": "0.
|
|
65
|
+
"@ff-labs/fff-bin-darwin-arm64": "0.5.0",
|
|
66
|
+
"@ff-labs/fff-bin-darwin-x64": "0.5.0",
|
|
67
|
+
"@ff-labs/fff-bin-linux-x64-gnu": "0.5.0",
|
|
68
|
+
"@ff-labs/fff-bin-linux-arm64-gnu": "0.5.0",
|
|
69
|
+
"@ff-labs/fff-bin-linux-x64-musl": "0.5.0",
|
|
70
|
+
"@ff-labs/fff-bin-linux-arm64-musl": "0.5.0",
|
|
71
|
+
"@ff-labs/fff-bin-win32-x64": "0.5.0",
|
|
72
|
+
"@ff-labs/fff-bin-win32-arm64": "0.5.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/bun": "^1.3.8",
|
package/src/ffi.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
GrepResult,
|
|
17
17
|
Location,
|
|
18
18
|
Result,
|
|
19
|
+
ScanProgress,
|
|
19
20
|
Score,
|
|
20
21
|
SearchResult,
|
|
21
22
|
} from "./types";
|
|
@@ -125,6 +126,10 @@ const ffiDefinition = {
|
|
|
125
126
|
args: [FFIType.ptr, FFIType.u64],
|
|
126
127
|
returns: FFIType.ptr,
|
|
127
128
|
},
|
|
129
|
+
fff_wait_for_watcher: {
|
|
130
|
+
args: [FFIType.ptr, FFIType.u64],
|
|
131
|
+
returns: FFIType.ptr,
|
|
132
|
+
},
|
|
128
133
|
fff_restart_index: {
|
|
129
134
|
args: [FFIType.ptr, FFIType.cstring],
|
|
130
135
|
returns: FFIType.ptr,
|
|
@@ -817,16 +822,16 @@ export function ffiIsScanning(handle: NativeHandle): boolean {
|
|
|
817
822
|
return library.symbols.fff_is_scanning(handle) as boolean;
|
|
818
823
|
}
|
|
819
824
|
|
|
820
|
-
// FffScanProgress { scanned_files_count: u64(8), is_scanning: bool(1
|
|
825
|
+
// FffScanProgress { scanned_files_count: u64(8), is_scanning: bool(1), is_watcher_ready: bool(1), is_warmup_complete: bool(1) + pad }
|
|
821
826
|
const SP_COUNT = 0; // u64 (8)
|
|
822
|
-
const SP_SCANNING = 8; // bool (1
|
|
827
|
+
const SP_SCANNING = 8; // bool (1)
|
|
828
|
+
const SP_WATCHER_READY = 9; // bool (1)
|
|
829
|
+
const SP_WARMUP_COMPLETE = 10; // bool (1)
|
|
823
830
|
|
|
824
831
|
/**
|
|
825
832
|
* Get scan progress.
|
|
826
833
|
*/
|
|
827
|
-
export function ffiGetScanProgress(
|
|
828
|
-
handle: NativeHandle,
|
|
829
|
-
): Result<{ scannedFilesCount: number; isScanning: boolean }> {
|
|
834
|
+
export function ffiGetScanProgress(handle: NativeHandle): Result<ScanProgress> {
|
|
830
835
|
const library = loadLibrary();
|
|
831
836
|
const resultPtr = library.symbols.fff_get_scan_progress(handle);
|
|
832
837
|
const envelope = readResultEnvelope(resultPtr);
|
|
@@ -837,9 +842,11 @@ export function ffiGetScanProgress(
|
|
|
837
842
|
}
|
|
838
843
|
|
|
839
844
|
const hp = asPtr(envelope.handlePtr);
|
|
840
|
-
const result = {
|
|
845
|
+
const result: ScanProgress = {
|
|
841
846
|
scannedFilesCount: Number(read.u64(hp, SP_COUNT)),
|
|
842
847
|
isScanning: read.u8(hp, SP_SCANNING) !== 0,
|
|
848
|
+
isWatcherReady: read.u8(hp, SP_WATCHER_READY) !== 0,
|
|
849
|
+
isWarmupComplete: read.u8(hp, SP_WARMUP_COMPLETE) !== 0,
|
|
843
850
|
};
|
|
844
851
|
library.symbols.fff_free_scan_progress(hp);
|
|
845
852
|
return { ok: true, value: result };
|
|
@@ -854,6 +861,18 @@ export function ffiWaitForScan(handle: NativeHandle, timeoutMs: number): Result<
|
|
|
854
861
|
return parseBoolResult(resultPtr);
|
|
855
862
|
}
|
|
856
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Wait for the background file watcher to be ready.
|
|
866
|
+
*/
|
|
867
|
+
export function ffiWaitForWatcher(
|
|
868
|
+
handle: NativeHandle,
|
|
869
|
+
timeoutMs: number,
|
|
870
|
+
): Result<boolean> {
|
|
871
|
+
const library = loadLibrary();
|
|
872
|
+
const resultPtr = library.symbols.fff_wait_for_watcher(handle, BigInt(timeoutMs));
|
|
873
|
+
return parseBoolResult(resultPtr);
|
|
874
|
+
}
|
|
875
|
+
|
|
857
876
|
/**
|
|
858
877
|
* Restart index in new path.
|
|
859
878
|
*/
|
package/src/finder.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
ffiSearch,
|
|
25
25
|
ffiTrackQuery,
|
|
26
26
|
ffiWaitForScan,
|
|
27
|
+
ffiWaitForWatcher,
|
|
27
28
|
isAvailable,
|
|
28
29
|
type NativeHandle,
|
|
29
30
|
} from "./ffi";
|
|
@@ -345,6 +346,22 @@ export class FileFinder {
|
|
|
345
346
|
return ffiWaitForScan(guard.value, timeoutMs);
|
|
346
347
|
}
|
|
347
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Wait for the background file watcher to be ready.
|
|
351
|
+
*
|
|
352
|
+
* The watcher is created after the initial scan, git status, and optional
|
|
353
|
+
* warmup phases complete. Useful for tests that need to ensure filesystem
|
|
354
|
+
* events will be detected.
|
|
355
|
+
*
|
|
356
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (default: 10000)
|
|
357
|
+
* @returns true if watcher is ready, false if timed out
|
|
358
|
+
*/
|
|
359
|
+
waitForWatcher(timeoutMs: number = 10000): Result<boolean> {
|
|
360
|
+
const guard = this.ensureAlive();
|
|
361
|
+
if (!guard.ok) return guard;
|
|
362
|
+
return ffiWaitForWatcher(guard.value, timeoutMs);
|
|
363
|
+
}
|
|
364
|
+
|
|
348
365
|
/**
|
|
349
366
|
* Change the indexed directory to a new path.
|
|
350
367
|
*
|
|
@@ -127,7 +127,7 @@ describe.skipIf(process.platform === "win32")("Git lifecycle integration", () =>
|
|
|
127
127
|
let tmpDir: string;
|
|
128
128
|
let finder: FileFinder;
|
|
129
129
|
|
|
130
|
-
beforeAll(() => {
|
|
130
|
+
beforeAll(async () => {
|
|
131
131
|
// Create temp directory and initialise a git repo with two committed files.
|
|
132
132
|
// Use realpathSync to resolve symlinks (macOS /var -> /private/var) so
|
|
133
133
|
// that git2's resolved workdir paths match the file picker's base_path.
|
|
@@ -151,6 +151,20 @@ describe.skipIf(process.platform === "win32")("Git lifecycle integration", () =>
|
|
|
151
151
|
// Wait for the initial scan to finish
|
|
152
152
|
const scanResult = finder.waitForScan(10_000);
|
|
153
153
|
expect(scanResult.ok).toBe(true);
|
|
154
|
+
|
|
155
|
+
// Poll getScanProgress until the watcher is ready so that
|
|
156
|
+
// filesystem events (file creates, deletes) are detected.
|
|
157
|
+
const start = Date.now();
|
|
158
|
+
while (Date.now() - start < WATCHER_TIMEOUT_MS) {
|
|
159
|
+
const progress = finder.getScanProgress();
|
|
160
|
+
if (progress.ok && progress.value.isWatcherReady) break;
|
|
161
|
+
await sleep(POLL_INTERVAL_MS);
|
|
162
|
+
}
|
|
163
|
+
const progress = finder.getScanProgress();
|
|
164
|
+
expect(progress.ok).toBe(true);
|
|
165
|
+
if (progress.ok) {
|
|
166
|
+
expect(progress.value.isWatcherReady).toBe(true);
|
|
167
|
+
}
|
|
154
168
|
});
|
|
155
169
|
|
|
156
170
|
afterAll(() => {
|
package/src/types.ts
CHANGED
|
@@ -144,6 +144,10 @@ export interface ScanProgress {
|
|
|
144
144
|
scannedFilesCount: number;
|
|
145
145
|
/** Whether a scan is currently in progress */
|
|
146
146
|
isScanning: boolean;
|
|
147
|
+
/** Whether the background file watcher is ready */
|
|
148
|
+
isWatcherReady: boolean;
|
|
149
|
+
/** Whether the warmup/bigram phase has completed */
|
|
150
|
+
isWarmupComplete: boolean;
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
/**
|