2026-03-13 12:21:09 -06:00
|
|
|
/**
|
|
|
|
|
* Native addon loader.
|
|
|
|
|
*
|
|
|
|
|
* Locates and loads the compiled Rust N-API addon (`.node` file).
|
|
|
|
|
* Tries platform-tagged release builds first, then falls back to dev builds.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { createRequire } from "node:module";
|
|
|
|
|
import * as path from "node:path";
|
|
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
|
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
|
|
|
|
|
|
const addonDir = path.resolve(__dirname, "..", "..", "..", "native", "addon");
|
|
|
|
|
const platformTag = `${process.platform}-${process.arch}`;
|
|
|
|
|
|
|
|
|
|
const candidates = [
|
|
|
|
|
path.join(addonDir, `gsd_engine.${platformTag}.node`),
|
|
|
|
|
path.join(addonDir, "gsd_engine.dev.node"),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function loadNative(): Record<string, unknown> {
|
|
|
|
|
const errors: string[] = [];
|
|
|
|
|
|
|
|
|
|
for (const candidate of candidates) {
|
|
|
|
|
try {
|
|
|
|
|
return require(candidate) as Record<string, unknown>;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const message = err instanceof Error ? err.message : String(err);
|
|
|
|
|
errors.push(`${candidate}: ${message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const details = errors.map((e) => ` - ${e}`).join("\n");
|
|
|
|
|
throw new Error(
|
|
|
|
|
`Failed to load gsd_engine native addon for ${platformTag}.\n\n` +
|
|
|
|
|
`Tried:\n${details}\n\n` +
|
|
|
|
|
`Build with: npm run build:native -w @gsd/native`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const native = loadNative() as {
|
|
|
|
|
search: (content: Buffer | Uint8Array, options: unknown) => unknown;
|
|
|
|
|
grep: (options: unknown) => unknown;
|
2026-03-13 12:43:50 -06:00
|
|
|
killTree: (pid: number, signal: number) => number;
|
|
|
|
|
listDescendants: (pid: number) => number[];
|
|
|
|
|
processGroupId: (pid: number) => number | null;
|
|
|
|
|
killProcessGroup: (pgid: number, signal: number) => boolean;
|
feat: add native glob and fs_cache modules with gitignore-aware discovery (#226)
Port glob, glob_util, and fs_cache modules from Oh My Pi's pi-natives crate,
adapted for napi-rs v2. Provides gitignore-respecting filesystem discovery
with a TTL-based scan cache, mtime sorting, file-type filtering, and
node_modules exclusion.
Includes a task module for async N-API work scheduling with cooperative
cancellation (timeout-based), TypeScript type declarations and wrapper,
and 12 integration tests covering pattern matching, recursion, gitignore,
maxResults, sortByMtime, fileType filtering, and cache invalidation.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 12:45:56 -06:00
|
|
|
glob: (
|
|
|
|
|
options: unknown,
|
|
|
|
|
onMatch?: ((match: unknown) => void) | undefined | null,
|
|
|
|
|
) => Promise<unknown>;
|
|
|
|
|
invalidateFsScanCache: (path?: string) => void;
|
2026-03-13 12:21:09 -06:00
|
|
|
};
|