@oh-my-pi/pi-natives 15.12.4 → 15.13.1
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 +20 -1
- package/native/index.js +2 -1
- package/native/loader-state.d.ts +7 -0
- package/native/loader-state.js +56 -1
- package/package.json +6 -6
package/native/index.d.ts
CHANGED
|
@@ -118,6 +118,25 @@ export declare class Shell {
|
|
|
118
118
|
abort(): Promise<void>
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Install the bounded Tokio runtime napi-rs adopts for async exports.
|
|
123
|
+
*
|
|
124
|
+
* The JS loader calls this exactly once, synchronously, right *after* `dlopen`
|
|
125
|
+
* returns and *before* any async native runs — never from `#[module_init]`.
|
|
126
|
+
* Building a multi-thread runtime eagerly spawns worker threads, and doing
|
|
127
|
+
* that during module init (while the dynamic-loader lock is held) deadlocks on
|
|
128
|
+
* some hosts: a fresh worker blocks acquiring the loader lock that the init
|
|
129
|
+
* thread still owns. napi-rs only materializes its runtime on the first async
|
|
130
|
+
* call (`RT` is a `LazyLock`) and `create_custom_tokio_runtime` merely records
|
|
131
|
+
* the runtime in a `OnceLock`, so installing it post-load is still honored.
|
|
132
|
+
* Without it napi builds its own default (one worker per CPU, spawned eagerly)
|
|
133
|
+
* which aborts the process (`os error 1455`) on a memory-constrained Windows
|
|
134
|
+
* host before any JS error can surface; [`create_windows_napi_tokio_runtime`]
|
|
135
|
+
* pre-flights the spawn instead. If no runtime can be built we leave napi-rs
|
|
136
|
+
* to its default. Idempotent.
|
|
137
|
+
*/
|
|
138
|
+
export declare function __ompInstallTokioRuntime(): void
|
|
139
|
+
|
|
121
140
|
/**
|
|
122
141
|
* Version sentinel — exists solely so the JS loader can prove at load time
|
|
123
142
|
* that the `.node` file on disk is from the same package release as the
|
|
@@ -136,7 +155,7 @@ export declare class Shell {
|
|
|
136
155
|
* `packages/natives/native/index.js` (which derives the name from
|
|
137
156
|
* `package.json#version`).
|
|
138
157
|
*/
|
|
139
|
-
export declare function
|
|
158
|
+
export declare function __piNativesV15_13_1(): void
|
|
140
159
|
|
|
141
160
|
/**
|
|
142
161
|
* Apply conservative pre-execution rewrites to a bash command.
|
package/native/index.js
CHANGED
|
@@ -23,7 +23,8 @@ export const PtySession = nativeBindings.PtySession;
|
|
|
23
23
|
export const Shell = nativeBindings.Shell;
|
|
24
24
|
|
|
25
25
|
// functions
|
|
26
|
-
export const
|
|
26
|
+
export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime;
|
|
27
|
+
export const __piNativesV15_13_1 = nativeBindings.__piNativesV15_13_1;
|
|
27
28
|
export const applyBashFixups = nativeBindings.applyBashFixups;
|
|
28
29
|
export const astEdit = nativeBindings.astEdit;
|
|
29
30
|
export const astGrep = nativeBindings.astGrep;
|
package/native/loader-state.d.ts
CHANGED
|
@@ -55,6 +55,13 @@ export interface ResolveLoaderCandidatesInput {
|
|
|
55
55
|
|
|
56
56
|
export function resolveLoaderCandidates(input: ResolveLoaderCandidatesInput): string[];
|
|
57
57
|
|
|
58
|
+
export interface CleanupStaleNativeVersionsInput {
|
|
59
|
+
nativesDir: string;
|
|
60
|
+
currentVersion: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function cleanupStaleNativeVersions(input: CleanupStaleNativeVersionsInput): string[];
|
|
64
|
+
|
|
58
65
|
export interface ExtractEmbeddedAddonArchiveInput {
|
|
59
66
|
archivePath: string;
|
|
60
67
|
files: EmbeddedAddonFile[];
|
package/native/loader-state.js
CHANGED
|
@@ -177,6 +177,37 @@ export function resolveLoaderCandidates({
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
// =========================================================================
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Remove version-pinned native cache directories older than the loaded package.
|
|
183
|
+
* Best-effort by design: permission errors and concurrent processes must not
|
|
184
|
+
* abort startup after the native addon has already loaded successfully.
|
|
185
|
+
*
|
|
186
|
+
* @param {{ nativesDir: string; currentVersion: string }} input
|
|
187
|
+
* @returns {string[]}
|
|
188
|
+
*/
|
|
189
|
+
export function cleanupStaleNativeVersions({ nativesDir, currentVersion }) {
|
|
190
|
+
const removed = [];
|
|
191
|
+
let entries;
|
|
192
|
+
try {
|
|
193
|
+
entries = fs.readdirSync(nativesDir, { withFileTypes: true });
|
|
194
|
+
} catch {
|
|
195
|
+
return removed;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
if (!entry.isDirectory() || entry.name === currentVersion) continue;
|
|
200
|
+
const targetPath = path.join(nativesDir, entry.name);
|
|
201
|
+
try {
|
|
202
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
203
|
+
removed.push(targetPath);
|
|
204
|
+
} catch {
|
|
205
|
+
// Stale caches are opportunistic cleanup only.
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return removed;
|
|
209
|
+
}
|
|
210
|
+
|
|
180
211
|
// Side-effectful loader. Everything below runs only when `loadNative()` is
|
|
181
212
|
// called from `native/index.js` — tests that only import the pure helpers
|
|
182
213
|
// above pay nothing for variant detection, subprocess spawns, or fs probes.
|
|
@@ -485,6 +516,26 @@ function validateLoadedBindings(ctx, bindings, candidate) {
|
|
|
485
516
|
);
|
|
486
517
|
}
|
|
487
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Install the addon's bounded Tokio runtime now that `dlopen` has returned and
|
|
521
|
+
* the dynamic-loader lock is released. The Rust `#[module_init]` deliberately
|
|
522
|
+
* does NOT build the runtime — spawning worker threads under the loader lock
|
|
523
|
+
* deadlocks on some hosts — so it exposes `__ompInstallTokioRuntime` for the
|
|
524
|
+
* loader to call once, before any async native runs. Best-effort: older addons
|
|
525
|
+
* predating this export simply fall back to napi-rs's default runtime.
|
|
526
|
+
*/
|
|
527
|
+
function installNativeTokioRuntime(bindings) {
|
|
528
|
+
const install = bindings.__ompInstallTokioRuntime;
|
|
529
|
+
if (typeof install !== "function") return;
|
|
530
|
+
try {
|
|
531
|
+
install();
|
|
532
|
+
startupMarker("native:tokioRuntime:installed");
|
|
533
|
+
} catch (err) {
|
|
534
|
+
startupMarker(`native:tokioRuntime:failed:${err instanceof Error ? err.message : String(err)}`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
488
539
|
function buildHelpMessage(ctx) {
|
|
489
540
|
if (ctx.isCompiledBinary) {
|
|
490
541
|
const expectedPaths = ctx.addonFilenames.map(filename => ` ${path.join(ctx.versionedDir, filename)}`).join("\n");
|
|
@@ -518,7 +569,8 @@ function initLoaderContext() {
|
|
|
518
569
|
const packageVersion = packageJson.version;
|
|
519
570
|
const nativeDir = path.join(import.meta.dir, "..", "native");
|
|
520
571
|
const execDir = path.dirname(process.execPath);
|
|
521
|
-
const
|
|
572
|
+
const nativesDir = getNativesDir();
|
|
573
|
+
const versionedDir = path.join(nativesDir, packageVersion);
|
|
522
574
|
const userDataDir =
|
|
523
575
|
process.platform === "win32"
|
|
524
576
|
? path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local"), "omp")
|
|
@@ -576,6 +628,7 @@ function initLoaderContext() {
|
|
|
576
628
|
candidates,
|
|
577
629
|
versionSentinelExport,
|
|
578
630
|
isWorkspaceLoad,
|
|
631
|
+
nativesDir,
|
|
579
632
|
};
|
|
580
633
|
}
|
|
581
634
|
|
|
@@ -595,6 +648,8 @@ export function loadNative() {
|
|
|
595
648
|
startupMarker(`native:require:${path.basename(candidate)}`);
|
|
596
649
|
const bindings = require_(candidate);
|
|
597
650
|
validateLoadedBindings(ctx, bindings, candidate);
|
|
651
|
+
installNativeTokioRuntime(bindings);
|
|
652
|
+
cleanupStaleNativeVersions({ nativesDir: ctx.nativesDir, currentVersion: ctx.packageVersion });
|
|
598
653
|
startupMarker("native:loadNative:done");
|
|
599
654
|
return bindings;
|
|
600
655
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-natives",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.13.1",
|
|
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://omp.sh",
|
|
@@ -66,10 +66,10 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"optionalDependencies": {
|
|
69
|
-
"@oh-my-pi/pi-natives-linux-x64": "15.
|
|
70
|
-
"@oh-my-pi/pi-natives-linux-arm64": "15.
|
|
71
|
-
"@oh-my-pi/pi-natives-darwin-x64": "15.
|
|
72
|
-
"@oh-my-pi/pi-natives-darwin-arm64": "15.
|
|
73
|
-
"@oh-my-pi/pi-natives-win32-x64": "15.
|
|
69
|
+
"@oh-my-pi/pi-natives-linux-x64": "15.13.1",
|
|
70
|
+
"@oh-my-pi/pi-natives-linux-arm64": "15.13.1",
|
|
71
|
+
"@oh-my-pi/pi-natives-darwin-x64": "15.13.1",
|
|
72
|
+
"@oh-my-pi/pi-natives-darwin-arm64": "15.13.1",
|
|
73
|
+
"@oh-my-pi/pi-natives-win32-x64": "15.13.1"
|
|
74
74
|
}
|
|
75
75
|
}
|