@gajae-code/natives 0.14.2 → 0.15.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/native/index.d.ts CHANGED
@@ -524,7 +524,7 @@ export declare function __piNativesPublishOutcomeV1(): void
524
524
  * `packages/natives/native/index.js` (which derives the name from
525
525
  * `package.json#version`).
526
526
  */
527
- export declare function __piNativesV0_14_2(): void
527
+ export declare function __piNativesV0_15_0(): void
528
528
 
529
529
  /**
530
530
  * Apply conservative pre-execution rewrites to a bash command.
package/native/index.js CHANGED
@@ -30,7 +30,7 @@ export const Shell = nativeBindings.Shell;
30
30
 
31
31
  // functions
32
32
  export const __piNativesPublishOutcomeV1 = nativeBindings.__piNativesPublishOutcomeV1;
33
- export const __piNativesV0_14_2 = nativeBindings.__piNativesV0_14_2;
33
+ export const __piNativesV0_15_0 = nativeBindings.__piNativesV0_15_0;
34
34
  export const applyBashFixups = nativeBindings.applyBashFixups;
35
35
  export const applyOwnerOnlyFdSecurity = nativeBindings.applyOwnerOnlyFdSecurity;
36
36
  export const applyOwnerOnlyPathSecurity = nativeBindings.applyOwnerOnlyPathSecurity;
@@ -18,9 +18,16 @@ export interface DetectCompiledBinaryInput {
18
18
 
19
19
  export function detectCompiledBinary(input: DetectCompiledBinaryInput): boolean;
20
20
 
21
+ export type Win32Avx2ProbeDiagnostic = "timeout" | "spawn_error" | "nonzero_exit" | "non_decisive_output";
22
+
21
23
  export function detectWin32Avx2Support(
22
24
  probe?: () => boolean | undefined,
23
- command?: (file: string, args: string[]) => string | null,
25
+ command?: (
26
+ file: string,
27
+ args: string[],
28
+ report?: (diagnostic: Win32Avx2ProbeDiagnostic) => void,
29
+ ) => string | null,
30
+ report?: (diagnostic: Win32Avx2ProbeDiagnostic) => void,
24
31
  ): boolean;
25
32
 
26
33
  export interface GetAddonFilenamesInput {
@@ -246,17 +246,46 @@ export function cachedEmbeddedExtractionIsFresh({ targetPath, embeddedPath, size
246
246
  // above pay nothing for variant detection, subprocess spawns, or fs probes.
247
247
  // =========================================================================
248
248
 
249
- function runCommand(command, args) {
249
+ // Keep the synchronous fallback below Bun's default 5 s test budget. The
250
+ // remaining margin covers spawnSync's return path after the kill is delivered
251
+ // and prevents a wedged PowerShell process from starving native loading.
252
+ const WIN32_AVX2_PROBE_TIMEOUT_MS = 4_000;
253
+ const WIN32_AVX2_PROBE_MAX_BUFFER = 4 * 1024;
254
+ const WIN32_AVX2_PROBE_WARNING_CODE = "GJC_WIN32_AVX2_PROBE";
255
+
256
+ function emitWin32Avx2ProbeDiagnostic(kind) {
257
+ process.emitWarning(`Windows AVX2 probe inconclusive (${kind}); using baseline variant.`, {
258
+ code: WIN32_AVX2_PROBE_WARNING_CODE,
259
+ });
260
+ }
261
+
262
+ function spawnFailureDiagnostic(result) {
263
+ if (result.error?.code === "ETIMEDOUT" || result.signal === "SIGKILL") return "timeout";
264
+ if (result.error) return "spawn_error";
265
+ if (result.status !== 0) return "nonzero_exit";
266
+ return "non_decisive_output";
267
+ }
268
+
269
+ function runCommand(command, args, report) {
250
270
  try {
251
271
  // `windowsHide` keeps probes console-less: from a detached, console-less
252
272
  // parent (e.g. the SDK broker) spawning a console app like powershell.exe
253
273
  // would otherwise allocate and flash a visible console window per call
254
274
  // (#4652). It is ignored on POSIX.
255
- const result = childProcess.spawnSync(command, args, { encoding: "utf-8", windowsHide: true });
256
- if (result.error) return null;
257
- if (result.status !== 0) return null;
275
+ const result = childProcess.spawnSync(command, args, {
276
+ encoding: "utf-8",
277
+ windowsHide: true,
278
+ timeout: WIN32_AVX2_PROBE_TIMEOUT_MS,
279
+ killSignal: "SIGKILL",
280
+ maxBuffer: WIN32_AVX2_PROBE_MAX_BUFFER,
281
+ });
282
+ if (result.error || result.status !== 0) {
283
+ report?.(spawnFailureDiagnostic(result));
284
+ return null;
285
+ }
258
286
  return (result.stdout || "").trim();
259
287
  } catch {
288
+ report?.("spawn_error");
260
289
  return null;
261
290
  }
262
291
  }
@@ -287,21 +316,30 @@ function probeWin32Avx2InProcess() {
287
316
  // Hidden PowerShell fallback. `Add-Type` P/Invoke works on both stock Windows
288
317
  // PowerShell 5.1 (.NET Framework, which has no System.Runtime.Intrinsics) and
289
318
  // pwsh 7+. Any probe failure fails safe to `false` (baseline variant).
290
- function probeWin32Avx2ViaPowerShell(run = runCommand) {
319
+ function probeWin32Avx2ViaPowerShell(run = runCommand, report = emitWin32Avx2ProbeDiagnostic) {
291
320
  const output = run("powershell.exe", [
292
321
  "-NoProfile",
293
322
  "-NonInteractive",
294
323
  "-Command",
295
324
  "Add-Type -Namespace GjcNative -Name Cpu -MemberDefinition '[DllImport(\"kernel32.dll\")] public static extern bool IsProcessorFeaturePresent(int feature);'; " +
296
325
  `[GjcNative.Cpu]::IsProcessorFeaturePresent(${WIN32_PF_AVX2_INSTRUCTIONS_AVAILABLE})`,
297
- ]);
298
- return output !== null && output.toLowerCase() === "true";
326
+ ], report);
327
+ if (output === null) return false;
328
+ const normalized = output.toLowerCase();
329
+ if (normalized === "true") return true;
330
+ if (normalized === "false") return false;
331
+ report("non_decisive_output");
332
+ return false;
299
333
  }
300
334
 
301
- export function detectWin32Avx2Support(probe = probeWin32Avx2InProcess, run = runCommand) {
335
+ export function detectWin32Avx2Support(
336
+ probe = probeWin32Avx2InProcess,
337
+ run = runCommand,
338
+ report = emitWin32Avx2ProbeDiagnostic,
339
+ ) {
302
340
  const probed = probe();
303
341
  if (probed !== undefined) return probed;
304
- return probeWin32Avx2ViaPowerShell(run);
342
+ return probeWin32Avx2ViaPowerShell(run, report);
305
343
  }
306
344
 
307
345
  function getVariantOverride() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gajae-code/natives",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "description": "Native Rust bindings for grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
5
5
  "type": "module",
6
6
  "homepage": "https://gajae-code.com",
@@ -46,7 +46,7 @@
46
46
  "@types/ws": "^8.5.13"
47
47
  },
48
48
  "engines": {
49
- "bun": ">=1.3.14"
49
+ "bun": ">=1.4.0"
50
50
  },
51
51
  "napi": {
52
52
  "binaryName": "pi_natives",
@@ -61,11 +61,11 @@
61
61
  "README.md"
62
62
  ],
63
63
  "optionalDependencies": {
64
- "@gajae-code/natives-darwin-arm64": "0.14.2",
65
- "@gajae-code/natives-darwin-x64": "0.14.2",
66
- "@gajae-code/natives-linux-arm64": "0.14.2",
67
- "@gajae-code/natives-linux-x64": "0.14.2",
68
- "@gajae-code/natives-win32-x64": "0.14.2"
64
+ "@gajae-code/natives-darwin-arm64": "0.15.0",
65
+ "@gajae-code/natives-darwin-x64": "0.15.0",
66
+ "@gajae-code/natives-linux-arm64": "0.15.0",
67
+ "@gajae-code/natives-linux-x64": "0.15.0",
68
+ "@gajae-code/natives-win32-x64": "0.15.0"
69
69
  },
70
70
  "exports": {
71
71
  ".": {