@napi-rs/cli 3.10.6 → 3.10.8
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/dist/cli.js +432 -22
- package/dist/index.cjs +432 -22
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +432 -22
- package/docs/wasi.md +68 -0
- package/package.json +2 -2
- package/src/api/__tests__/artifacts.spec.ts +1644 -1
- package/src/api/__tests__/templates.spec.ts +692 -5
- package/src/api/artifacts.ts +547 -21
- package/src/api/templates/load-wasi-template.ts +213 -1
- package/src/utils/__tests__/__snapshots__/target.spec.ts.md +7 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
- package/src/utils/misc.ts +2 -2
- package/src/utils/target.ts +1 -0
package/docs/wasi.md
CHANGED
|
@@ -539,6 +539,67 @@ pre-created pool, spawning is only a message to an already-running worker,
|
|
|
539
539
|
and if the pool is exhausted the fallback allocates a fresh worker that
|
|
540
540
|
boots once the spawning parent returns to its event loop.
|
|
541
541
|
|
|
542
|
+
## Thread pool preload
|
|
543
|
+
|
|
544
|
+
The threaded Node loader (`<binary>.wasi.cjs`) creates its emnapi worker pool
|
|
545
|
+
empty (`reuseWorker: true`): emnapi's own preload (`reuseWorker.size > 0`)
|
|
546
|
+
cannot run on a synchronous CommonJS load. Without help, every pool thread a
|
|
547
|
+
`MultiThread` runtime spawns on its first async call would first boot a Worker
|
|
548
|
+
and load the wasm into it.
|
|
549
|
+
|
|
550
|
+
An addon built with `napi-async-runtime` exports
|
|
551
|
+
`napi_wasm_runtime_pool_workers() -> u32` on `wasm32-wasip1-threads`: the pool
|
|
552
|
+
threads the runtime will still spawn. That is the configured `MultiThread`
|
|
553
|
+
`worker_threads`, or 0 under `CurrentThread` (also the wasm default before any
|
|
554
|
+
configure), and 0 once the runtime has started (its first async call, or a
|
|
555
|
+
runtime-backed call during module registration): the started runtime already
|
|
556
|
+
spawned all its pool threads and never adds more. So a reconcile after first
|
|
557
|
+
use only releases idle Workers; a thread that starts later (a timer thread, a
|
|
558
|
+
uv thread, a restarted runtime) creates its Worker on demand. It reads an
|
|
559
|
+
atomic and takes no lock, and it comes with the scheduler, so
|
|
560
|
+
`default-features = false` builds have it too. The loader keeps that many
|
|
561
|
+
Workers idle in the pool:
|
|
562
|
+
|
|
563
|
+
- once, right after a successful load (after `#[module_init]` configured the
|
|
564
|
+
runtime);
|
|
565
|
+
- after every successful `configureAsyncRuntime`, when `napi.wasm.asyncRuntime`
|
|
566
|
+
is on. The loader replaces that export with a wrapper (same name, `this`,
|
|
567
|
+
arguments and return value) that calls the original and then reconciles. It
|
|
568
|
+
is matched by name, like the host install above. A configure that throws
|
|
569
|
+
(for example because the runtime already started) propagates and leaves the
|
|
570
|
+
pool alone;
|
|
571
|
+
- whenever you call
|
|
572
|
+
`binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]()`, published
|
|
573
|
+
non-enumerable and read-only next to the dispose symbol. Use it after
|
|
574
|
+
changing the configuration some other way. Like `napi.rs.wasi.dispose`, the
|
|
575
|
+
symbol lives on the CommonJS loader object. The generated ESM entry
|
|
576
|
+
re-exports named exports only, so an ESM consumer reaches it through
|
|
577
|
+
`createRequire(import.meta.url)('<pkg>-wasm32-wasi')` or the local
|
|
578
|
+
`./<name>.wasi.cjs`.
|
|
579
|
+
|
|
580
|
+
A reconcile creates each missing Worker through `onCreateWorker` (so it is
|
|
581
|
+
tracked, unref'd and gets the crash flags) and starts its load without waiting
|
|
582
|
+
for it; a thread spawn later pops a Worker that is already booting. It
|
|
583
|
+
terminates the idle Workers above the count, newest first, the way a spawn
|
|
584
|
+
takes them. Workers a spawn already took are not in the pool and are left
|
|
585
|
+
alone, so the count only covers idle Workers. A reconcile never throws and
|
|
586
|
+
never waits. It does nothing after a thread crash, once disposal started, or
|
|
587
|
+
for an addon without the export.
|
|
588
|
+
|
|
589
|
+
Two things to know:
|
|
590
|
+
|
|
591
|
+
- A preloaded Worker that fails to load still latches the binding as crashed,
|
|
592
|
+
like any pool Worker: the worker cannot tell a preload from a thread spawn,
|
|
593
|
+
so `dispose()` rejects afterwards. This is by design. The failed Worker is
|
|
594
|
+
taken out of the pool, so a later spawn creates a fresh one.
|
|
595
|
+
- `NAPI_RS_ASYNC_WORK_POOL_SIZE` (or `UV_THREADPOOL_SIZE`, default 4) sizes the
|
|
596
|
+
uv async-work threads, which take their Workers from the same reuse pool. A
|
|
597
|
+
preloaded Worker can therefore end up running a uv thread instead of a
|
|
598
|
+
runtime thread; the runtime thread then creates its own.
|
|
599
|
+
|
|
600
|
+
The browser loaders keep their fixed pre-created pool (see above), and the
|
|
601
|
+
threadless and deferred loaders have no pool.
|
|
602
|
+
|
|
542
603
|
## Detecting the threaded target from Rust
|
|
543
604
|
|
|
544
605
|
rustc gives you nothing to tell the two WASI targets apart. `rustc --print
|
|
@@ -869,3 +930,10 @@ only through the worker's `'error'` or `'exit'` event, which needs a turn of
|
|
|
869
930
|
its event loop, so a cleanup wait already in progress keeps waiting. The same
|
|
870
931
|
holds before `beforeInit`: a thread spawned while the wasm initializes gets a
|
|
871
932
|
worker with no view.
|
|
933
|
+
|
|
934
|
+
After a crash, the threaded Node loader's `dispose()` only terminates the pool
|
|
935
|
+
workers and rejects, and from then on it drops the calls into wasm that emnapi
|
|
936
|
+
deferred through the context's `setImmediate` (threadsafe-function finalizers,
|
|
937
|
+
handle closes, the finalizer queue). A worker terminated while it held napi's
|
|
938
|
+
heap-sync lock leaves that lock set, so such a call would free memory on the
|
|
939
|
+
JavaScript thread and spin on the lock for good.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napi-rs/cli",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.8",
|
|
4
4
|
"description": "Cli tools for napi-rs",
|
|
5
5
|
"author": "LongYinan <lynweklm@gmail.com>",
|
|
6
6
|
"homepage": "https://napi.rs/",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"emnapi": "^2.0.0-alpha.4",
|
|
88
88
|
"empathic": "^2.0.1",
|
|
89
89
|
"env-paths": "^4.0.0",
|
|
90
|
-
"oxc-parser": "^0.
|
|
90
|
+
"oxc-parser": "^0.153.0",
|
|
91
91
|
"tsdown": "^0.23.0",
|
|
92
92
|
"tslib": "^2.8.1"
|
|
93
93
|
},
|