chore(deps): update dependency @napi-rs/cli to v3.10.7 (#27347)

This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Adoption](https://docs.renovatebot.com/merge-confidence/) |
[Passing](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|---|
| [@napi-rs/cli](https://napi.rs/)
([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.10.6` →
`3.10.7`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.10.6/3.10.7)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@napi-rs%2fcli/3.10.7?slim=true)
|
![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@napi-rs%2fcli/3.10.7?slim=true)
|
![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@napi-rs%2fcli/3.10.6/3.10.7?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@napi-rs%2fcli/3.10.6/3.10.7?slim=true)
|

---

### Release Notes

<details>
<summary>napi-rs/napi-rs (@&#8203;napi-rs/cli)</summary>

###
[`v3.10.7`](https://redirect.github.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.10.7)

[Compare
Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.10.6...@napi-rs/cli@3.10.7)

#### What's Changed

- feat(cli, async-runtime): preload the threaded WASI worker pool from
the loader by
[@&#8203;Brooooooklyn](https://redirect.github.com/Brooooooklyn) in
[#&#8203;3558](https://redirect.github.com/napi-rs/napi-rs/pull/3558)

#### New Contributors

- [@&#8203;colinhacks](https://redirect.github.com/colinhacks) made
their first contribution in
[#&#8203;3560](https://redirect.github.com/napi-rs/napi-rs/pull/3560)

**Full Changelog**:
<https://github.com/napi-rs/napi-rs/compare/napi-async-runtime-v0.2.4...@napi-rs/cli@3.10.7>

</details>

---

### Configuration

📅 **Schedule**: (in timezone Asia/Shanghai)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/oxc-project/oxc).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMjUuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjEzNC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Cameron Clark <cameron.clark@hey.com>
This commit is contained in:
renovate[bot]andCameron Clark authored and GitHub committed 2026-10-05 16:31:01 +00:00
1 parent f9d08677da
commit 43212aa645
8 files changed
+984 -24

No files matched your search

+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.LegalCommentsMode = __napiModule.exports.LegalCommentsMode
module.exports.minify = __napiModule.exports.minify
+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.Severity = __napiModule.exports.Severity
module.exports.ParseResult = __napiModule.exports.ParseResult
+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.Severity = __napiModule.exports.Severity
module.exports.Oxc = __napiModule.exports.Oxc
+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.Severity = __napiModule.exports.Severity
module.exports.transform = __napiModule.exports.transform
+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.Severity = __napiModule.exports.Severity
module.exports.transform = __napiModule.exports.transform
+161 -1
View File
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
}
let __wasiThreadCrashDisposePromise
// Raised by the crash disposal right before it terminates the workers. See
// `__wasiSetImmediate`.
let __wasiReentryClosed = false
/**
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
* closes, threadsafe-function finalizers), threadsafe-function dispatch
* (`async-send`) and the finalizer queue. One queued before a crash disposal
* terminates the workers still runs after it, and a worker terminated while it
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
* gives up) leaves that call spinning on this thread for good. The binding is
* unusable after a crash disposal, so those calls are dropped.
*
* Known residual, still able to enter wasm after a crash disposal because emnapi
* offers no hook for them: the `FinalizationRegistry` callbacks that free
* external memory when GC collects a value (`_free`, the shared-buffer meta
* release), threadsafe-function dispatch of `async-send` type 1 and
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
* call under emnapi 1.x, whose `createContext` ignores `features`.
*/
function __wasiSetImmediate(callback) {
return setImmediate(function () {
if (!__wasiReentryClosed) {
callback()
}
})
}
/**
* Stores the first error a pool worker reported, with the worker's id. Called
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
return __wasiThreadCrashDisposePromise
}
__releaseEmnapiWaitingRequestHandle()
// No call into wasm after this: see `__wasiSetImmediate`.
__wasiReentryClosed = true
let workerResult
try {
workerResult = __terminateWasiWorkers()
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
return [crashError]
}
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
/**
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
* terminates a pooled Worker that failed to load but (up to
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
* then.
*/
function __removeWasiPoolWorker(manager, worker) {
const index = manager.unusedWorkers.indexOf(worker)
if (index !== -1) {
manager.unusedWorkers.splice(index, 1)
}
}
/**
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
* once it has exited, not before. `terminateWorker` only starts Node's
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
* begins before the exit has to find this Worker in the set and wait for it
* like any other. A second `terminate()` settles when the Worker has exited,
* the way `__terminateWasiWorkers` waits.
*/
function __untrackWasiWorkerOnExit(worker) {
const terminated = worker.terminate()
if (__isThenable(terminated)) {
Promise.resolve(terminated).then(
() => {
__wasiWorkers.delete(worker)
},
// Left tracked: disposal terminates it again and reports the error.
() => {},
)
} else {
__wasiWorkers.delete(worker)
}
}
/**
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
* pool empty, so without this every pool thread the first async call spawns
* boots a Worker and loads the wasm into it first. Here each missing Worker is
* created and starts loading now; a spawn later pops one that is already
* booting. Idle Workers above the count are terminated, last in first out,
* the way a spawn takes them. A Worker a spawn already took is not in the pool
* and is left alone.
*
* Runs once after a successful load and, when the loader wraps it, after every
* successful `configureAsyncRuntime`. Also reachable as
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
* It never throws and never waits on a Worker: a Worker whose load fails is
* dropped from the pool when its load rejects. Nothing at all happens after a
* thread crash, once disposal started, or for an addon without the export.
*/
function __reconcileWasiThreadPool() {
try {
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
return
}
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
if (typeof read !== 'function') {
return
}
const count = read() >>> 0
const manager = __getWasiThreadManager()
if (
!manager ||
!Array.isArray(manager.unusedWorkers) ||
typeof manager.allocateUnusedWorker !== 'function' ||
typeof manager.loadWasmModuleToWorker !== 'function'
) {
return
}
// Both loops are bounded by the difference they start from, so a manager
// that does not update `unusedWorkers` the way emnapi does cannot spin.
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
manager.terminateWorker(worker)
__removeWasiPoolWorker(manager, worker)
__untrackWasiWorkerOnExit(worker)
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
// `terminateWorker` installs a reporter that logs every emnapi message
// still queued on the port, so a Worker that finished loading just
// before it was terminated prints 'received "loaded" command from
// terminated worker'. Nothing listens for that Worker any more, and a
// newer emnapi ignores the late 'loaded' itself, so this is harmless
// there. `__terminateWasiWorkers` does the same.
worker.onmessage = undefined
}
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
let worker
try {
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
// handed the crash flags like any pool Worker.
worker = manager.allocateUnusedWorker()
manager
.loadWasmModuleToWorker(worker)
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
} catch {
if (worker !== undefined) {
__removeWasiPoolWorker(manager, worker)
try {
manager.terminateWorker(worker)
__untrackWasiWorkerOnExit(worker)
} catch {}
}
return
}
}
} catch {}
}
function __publishWasiThreadPoolReconcile(exports) {
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
configurable: false,
enumerable: false,
value: __reconcileWasiThreadPool,
writable: false,
})
}
const __cwd = process.cwd()
const __rootDir = __nodePath.parse(__cwd).root
const __hostRoot =
@@ -2011,7 +2165,7 @@ try {
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
try {
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
__emnapiCreateContext({ autoDestroy: false }),
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
__prepareWasmEnvCleanup,
__isPreparingWasmEnvCleanup,
)
@@ -2108,6 +2262,7 @@ try {
},
}))
__publishWasiDispose(__napiModule.exports)
__publishWasiThreadPoolReconcile(__napiModule.exports)
// The CommonJS tail below aliases `__napiModule.exports`; a named module
// export does not travel with it, so carry the marker on the binding itself
// too. Three things pin the stamp to exactly this spot:
@@ -2136,6 +2291,11 @@ try {
__runWasiInitializationRollback(rollback)
throw rollback.error
}
// Preload the pool for the count the addon configured during registration.
// See `__reconcileWasiThreadPool`.
try {
__reconcileWasiThreadPool()
} catch {}
module.exports = __napiModule.exports
module.exports.Severity = __napiModule.exports.Severity
module.exports.HelperMode = __napiModule.exports.HelperMode
+17 -17
View File
@@ -174,8 +174,8 @@ catalogs:
specifier: 2.0.0-alpha.5
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 3.10.6
version: 3.10.6
specifier: 3.10.7
version: 3.10.7
'@napi-rs/wasm-runtime':
specifier: 1.2.4
version: 1.2.4
@@ -218,7 +218,7 @@ importers:
devDependencies:
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
emnapi:
specifier: 2.0.0-alpha.5
version: 2.0.0-alpha.5
@@ -252,7 +252,7 @@ importers:
version: 0.18.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@oxapps/shared':
specifier: workspace:*
version: link:../shared
@@ -297,7 +297,7 @@ importers:
version: 8.0.6
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@oxapps/shared':
specifier: workspace:*
version: link:../shared
@@ -411,7 +411,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@types/node':
specifier: 'catalog:'
version: 24.1.0
@@ -439,7 +439,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@napi-rs/wasm-runtime':
specifier: 'catalog:'
version: 1.2.4(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)
@@ -485,7 +485,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
publint:
specifier: 'catalog:'
version: 0.3.25
@@ -500,7 +500,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@types/node':
specifier: 'catalog:'
version: 24.1.0
@@ -521,7 +521,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@types/node':
specifier: 'catalog:'
version: 24.1.0
@@ -542,7 +542,7 @@ importers:
version: 2.0.0-alpha.5
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)
'@types/node':
specifier: 'catalog:'
version: 24.1.0
@@ -610,7 +610,7 @@ importers:
devDependencies:
'@napi-rs/cli':
specifier: 'catalog:'
version: 3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
version: 3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)
tasks/compat_data:
devDependencies:
@@ -1537,8 +1537,8 @@ packages:
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
engines: {node: '>=8'}
'@napi-rs/cli@3.10.6':
resolution: {integrity: sha512-8Vj+XgPHtHWiPjyj+RXKKdAiC/rSpSrzT7OabrS4xGKu6yEnj6sVJ2Bqzmg3xHYqopXCE6P3ylcuek7wV4zFWA==}
'@napi-rs/cli@3.10.7':
resolution: {integrity: sha512-wTocvxyQeqqvKVOzocHMUs2X27Nc2EcRnpH0ojK8uSnzUAYSehfGSYgRheZNcU1ltY2yqJ/R18Zt2YbKXqYMmw==}
engines: {node: ^20.17.0 || ^22.13.0 || >= 23.5.0}
hasBin: true
peerDependencies:
@@ -7143,7 +7143,7 @@ snapshots:
'@lukeed/csprng@1.1.0': {}
'@napi-rs/cli@3.10.6(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)':
'@napi-rs/cli@3.10.7(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)':
dependencies:
'@inquirer/prompts': 8.5.2(@types/node@24.1.0)
'@napi-rs/cross-toolchain': 1.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
@@ -7175,7 +7175,7 @@ snapshots:
- '@types/node'
- supports-color
'@napi-rs/cli@3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)':
'@napi-rs/cli@3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@24.1.0)(emnapi@2.0.0-alpha.5)':
dependencies:
'@inquirer/prompts': 8.5.2(@types/node@24.1.0)
'@napi-rs/cross-toolchain': 1.0.3(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)
@@ -7207,7 +7207,7 @@ snapshots:
- '@types/node'
- supports-color
'@napi-rs/cli@3.10.6(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)':
'@napi-rs/cli@3.10.7(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)(@types/node@25.0.2)(emnapi@2.0.0-alpha.5)':
dependencies:
'@inquirer/prompts': 8.5.2(@types/node@25.0.2)
'@napi-rs/cross-toolchain': 1.0.3(@emnapi/core@2.0.0-alpha.5)(@emnapi/runtime@2.0.0-alpha.5)
+1 -1
View File
@@ -14,7 +14,7 @@ catalog:
"@emnapi/runtime": 2.0.0-alpha.5
emnapi: 2.0.0-alpha.5
"@arethetypeswrong/core": 0.18.5
"@napi-rs/cli": 3.10.6
"@napi-rs/cli": 3.10.7
"@napi-rs/wasm-runtime": 1.2.4
"@types/node": 24.1.0
cross-env: ^10.1.0