mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
fix(desktop): don't fail startup on inconclusive native probe (#2114)
This commit is contained in:
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -7,6 +7,11 @@ const {spawnSync} = require('node:child_process');
|
||||
const NATIVE_LOAD_ERROR_MARKER = Symbol.for('fluxer.nativeLoadError');
|
||||
const MAX_TEXT_LENGTH = 6000;
|
||||
const MAX_DIRECTORY_ENTRIES = 80;
|
||||
const PREFLIGHT_CHILD_ENV = 'FLUXER_NATIVE_MODULE_PREFLIGHT_CHILD';
|
||||
const PROBE_TIMEOUT_ENV = 'FLUXER_NATIVE_PROBE_TIMEOUT_MS';
|
||||
const DEFAULT_PROBE_TIMEOUT_MS = 30000;
|
||||
const PROBE_REACHED_REQUIRE_MARKER = '__fluxer_native_probe_reached_require__';
|
||||
const PROBE_SOURCE = `require('node:fs').writeSync(1, ${JSON.stringify(PROBE_REACHED_REQUIRE_MARKER)});require(process.argv[1]);`;
|
||||
|
||||
function trimText(value, limit = MAX_TEXT_LENGTH) {
|
||||
const text = Buffer.isBuffer(value) ? value.toString('utf8') : String(value ?? '');
|
||||
@@ -446,22 +451,41 @@ function createNativeLoadError({
|
||||
return error;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs = 5000}) {
|
||||
function resolveProbeTimeoutMs(explicitTimeoutMs) {
|
||||
const configured = Number.parseInt(process.env[PROBE_TIMEOUT_ENV] ?? '', 10);
|
||||
if (Number.isFinite(configured) && configured > 0) return configured;
|
||||
return explicitTimeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function probeReachedRequire(result) {
|
||||
return typeof result.stdout === 'string' && result.stdout.includes(PROBE_REACHED_REQUIRE_MARKER);
|
||||
}
|
||||
|
||||
function stripProbeMarker(value) {
|
||||
return typeof value === 'string' ? value.split(PROBE_REACHED_REQUIRE_MARKER).join('') : value;
|
||||
}
|
||||
|
||||
function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skipNativeProbeEnv, timeoutMs}) {
|
||||
if (!skipNativeProbeEnv || process.env[skipNativeProbeEnv] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', 'require(process.argv[1])', nativePath], {
|
||||
if (process.env[PREFLIGHT_CHILD_ENV] === '1') {
|
||||
return null;
|
||||
}
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SOURCE, nativePath], {
|
||||
env: {...process.env, ELECTRON_RUN_AS_NODE: '1', [skipNativeProbeEnv]: '1'},
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
timeout: timeoutMs,
|
||||
timeout: resolveProbeTimeoutMs(timeoutMs),
|
||||
});
|
||||
if (result.status === 0) return null;
|
||||
if (!probeReachedRequire(result)) return null;
|
||||
const reason = result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `safety probe terminated by signal ${result.signal}`
|
||||
: `safety probe exited with code ${result.status}`;
|
||||
const probeStdout = trimText(stripProbeMarker(result.stdout));
|
||||
return createNativeLoadError({
|
||||
moduleName,
|
||||
nativePath,
|
||||
@@ -470,7 +494,7 @@ function probeNativeBinary({moduleName, nativePath, nativeRoot, packageDir, skip
|
||||
reason,
|
||||
skipNativeProbeEnv,
|
||||
extraDiagnostics: [
|
||||
result.stdout ? {name: 'probeStdout', text: trimText(result.stdout)} : null,
|
||||
probeStdout ? {name: 'probeStdout', text: probeStdout} : null,
|
||||
result.stderr ? {name: 'probeStderr', text: trimText(result.stderr)} : null,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -255,8 +255,13 @@ function resolveSpecs(): {resolved: Array<ResolvedSpec>; failures: Array<NativeM
|
||||
return {resolved, failures};
|
||||
}
|
||||
|
||||
function probeAllModules(resolved: Array<ResolvedSpec>): Array<NativeModulePreflightFailure> {
|
||||
if (resolved.length === 0) return [];
|
||||
interface ProbeOutcome {
|
||||
readonly inconclusive: string | null;
|
||||
readonly failures: Array<NativeModulePreflightFailure>;
|
||||
}
|
||||
|
||||
function probeAllModules(resolved: Array<ResolvedSpec>): ProbeOutcome {
|
||||
if (resolved.length === 0) return {inconclusive: null, failures: []};
|
||||
const result = spawnSync(process.execPath, ['-e', PROBE_SCRIPT, ...resolved.map((entry) => entry.modulePath)], {
|
||||
env: {
|
||||
...process.env,
|
||||
@@ -267,9 +272,20 @@ function probeAllModules(resolved: Array<ResolvedSpec>): Array<NativeModulePrefl
|
||||
timeout: PREFLIGHT_TIMEOUT_MS,
|
||||
maxBuffer: 32 * 1024 * 1024,
|
||||
});
|
||||
if (result.error) {
|
||||
return {inconclusive: result.error.message, failures: []};
|
||||
}
|
||||
const stdout = result.stdout ?? '';
|
||||
const stderr = result.stderr ?? '';
|
||||
const records = parseProbeRecords(stdout);
|
||||
if (records.length === 0 && result.status !== 0) {
|
||||
return {
|
||||
inconclusive: result.signal
|
||||
? `preflight child terminated by signal ${result.signal} without running any probe`
|
||||
: `preflight child exited with code ${result.status} without running any probe`,
|
||||
failures: [],
|
||||
};
|
||||
}
|
||||
const byIndex = new Map<number, Array<ProbeRecord>>();
|
||||
for (const record of records) {
|
||||
const list = byIndex.get(record.i) ?? [];
|
||||
@@ -292,13 +308,11 @@ function probeAllModules(resolved: Array<ResolvedSpec>): Array<NativeModulePrefl
|
||||
failures.push({
|
||||
name: spec.name,
|
||||
modulePath,
|
||||
reason: result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `child process terminated by signal ${result.signal} before this probe ran`
|
||||
: result.status !== null && result.status !== 0
|
||||
? `child process exited with code ${result.status} before this probe ran`
|
||||
: 'child process did not start probe',
|
||||
reason: result.signal
|
||||
? `child process terminated by signal ${result.signal} before this probe ran`
|
||||
: result.status !== null && result.status !== 0
|
||||
? `child process exited with code ${result.status} before this probe ran`
|
||||
: 'child process did not start probe',
|
||||
stdout: trimOutput(stdout),
|
||||
stderr: trimOutput(stderr),
|
||||
});
|
||||
@@ -326,19 +340,7 @@ function probeAllModules(resolved: Array<ResolvedSpec>): Array<NativeModulePrefl
|
||||
});
|
||||
}
|
||||
}
|
||||
if (records.length === 0 && (result.error || result.status !== 0)) {
|
||||
failures.push({
|
||||
name: '<preflight host>',
|
||||
reason: result.error
|
||||
? result.error.message
|
||||
: result.signal
|
||||
? `child terminated by signal ${result.signal}`
|
||||
: `child exited with code ${result.status}`,
|
||||
stdout: trimOutput(stdout),
|
||||
stderr: trimOutput(stderr),
|
||||
});
|
||||
}
|
||||
return failures;
|
||||
return {inconclusive: null, failures};
|
||||
}
|
||||
|
||||
function formatNativeModulePreflightFailure(failure: NativeModulePreflightFailure): string {
|
||||
@@ -367,8 +369,14 @@ export function runNativeModulePreflight(): void {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const probeFailures = probeAllModules(resolved);
|
||||
const failures = [...resolveFailures, ...probeFailures];
|
||||
const outcome = probeAllModules(resolved);
|
||||
if (outcome.inconclusive !== null && resolveFailures.length === 0) {
|
||||
log.warn('[NativeModulePreflight] Skipped: preflight could not be completed on this machine', {
|
||||
reason: outcome.inconclusive,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const failures = [...resolveFailures, ...outcome.failures];
|
||||
if (failures.length === 0) {
|
||||
writePreflightMarker(fingerprint);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user