@napi-rs/cli 3.10.3 → 3.10.5
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 +1310 -55
- package/dist/index.cjs +1313 -58
- package/dist/index.d.cts +19 -7
- package/dist/index.d.ts +19 -7
- package/dist/index.js +1310 -55
- package/docs/build.md +1 -0
- package/docs/wasi.md +149 -8
- package/package.json +2 -2
- package/src/api/__tests__/__snapshots__/templates.spec.ts.md +2498 -132
- package/src/api/__tests__/__snapshots__/templates.spec.ts.snap +0 -0
- package/src/api/__tests__/build.spec.ts +257 -0
- package/src/api/__tests__/templates.spec.ts +266 -6
- package/src/api/build.ts +57 -6
- package/src/api/templates/load-wasi-template.ts +807 -24
- package/src/commands/__tests__/build.spec.ts +6 -0
- package/src/def/build.ts +13 -0
- package/src/utils/__tests__/ohos-selfsign.spec.ts +285 -0
- package/src/utils/__tests__/reconciliation.spec.ts +19 -0
- package/src/utils/config.ts +10 -6
- package/src/utils/index.ts +1 -0
- package/src/utils/misc.ts +5 -4
- package/src/utils/ohos-selfsign.ts +646 -0
- package/src/utils/typegen.ts +221 -2
package/docs/build.md
CHANGED
|
@@ -58,3 +58,4 @@ new NapiCli().build({
|
|
|
58
58
|
| features | --features,-F | string[] | false | | Space-separated list of features to activate |
|
|
59
59
|
| allFeatures | --all-features | boolean | false | | Activate all available features |
|
|
60
60
|
| noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the `default` feature |
|
|
61
|
+
| ohosSign | --ohos-sign | boolean | false | true | Whether to self-sign the built binary for OpenHarmony targets by injecting a `.codesign` fs-verity section, so the `.so` can be loaded on HarmonyOS devices. Only works with `*-unknown-linux-ohos` targets |
|
package/docs/wasi.md
CHANGED
|
@@ -390,12 +390,16 @@ override the default in either direction:
|
|
|
390
390
|
|
|
391
391
|
## Shared async runtime hosts
|
|
392
392
|
|
|
393
|
-
`CurrentThread` is the
|
|
394
|
-
|
|
395
|
-
`
|
|
396
|
-
host
|
|
397
|
-
|
|
398
|
-
|
|
393
|
+
`CurrentThread` is the default async-runtime flavor on every WebAssembly
|
|
394
|
+
target, and the only flavor on threadless `wasm32-wasip1`. On
|
|
395
|
+
`wasm32-wasip1-threads` an addon may select `MultiThread` instead — always an
|
|
396
|
+
explicit host act, never a default (see the crate's "Running MultiThread on
|
|
397
|
+
`wasm32-wasip1-threads`" section).
|
|
398
|
+
|
|
399
|
+
A `CurrentThread` addon built with the `napi-async-runtime` crate makes no
|
|
400
|
+
progress until a JavaScript task host publishes its runnable turns, and its
|
|
401
|
+
timers never fire until a timer host relays them. Set `napi.wasm.asyncRuntime`
|
|
402
|
+
and the generated loaders install both for you:
|
|
399
403
|
|
|
400
404
|
```json
|
|
401
405
|
{
|
|
@@ -407,8 +411,16 @@ both for you:
|
|
|
407
411
|
}
|
|
408
412
|
```
|
|
409
413
|
|
|
410
|
-
This affects WASI output only. Native `.node` bindings
|
|
411
|
-
flavor on real threads and need no JavaScript host.
|
|
414
|
+
This affects WASI output only. Native `.node` bindings default to the
|
|
415
|
+
`MultiThread` flavor on real threads and need no JavaScript host.
|
|
416
|
+
|
|
417
|
+
Keep the flag on even for a `wasm32-wasip1-threads` addon that configures
|
|
418
|
+
`MultiThread`. The loaders cannot see the flavor, so they install both hosts
|
|
419
|
+
unconditionally — and a `MultiThread` runtime never uses either: its futures
|
|
420
|
+
run on the Rayon pool instead of published host turns, and its timers come from
|
|
421
|
+
the executor-owned heap plus a timekeeper thread. The installed task host is an
|
|
422
|
+
unref'd threadsafe function, so it does not hold the event loop open. That is
|
|
423
|
+
what lets one artifact choose its flavor at runtime.
|
|
412
424
|
|
|
413
425
|
With the flag on:
|
|
414
426
|
|
|
@@ -526,3 +538,132 @@ would never boot and the caller would deadlock waiting for it. With a
|
|
|
526
538
|
pre-created pool, spawning is only a message to an already-running worker,
|
|
527
539
|
and if the pool is exhausted the fallback allocates a fresh worker that
|
|
528
540
|
boots once the spawning parent returns to its event loop.
|
|
541
|
+
|
|
542
|
+
## Detecting the threaded target from Rust
|
|
543
|
+
|
|
544
|
+
rustc gives you nothing to tell the two WASI targets apart. `rustc --print
|
|
545
|
+
cfg` emits an _identical_ set for `wasm32-wasip1` and
|
|
546
|
+
`wasm32-wasip1-threads` — same `target_arch`, same `target_os`, same
|
|
547
|
+
`target_env = "p1"` — and `target_feature = "atomics"` is set for neither,
|
|
548
|
+
because the wasm `atomics` feature is still unstable and the stable channel
|
|
549
|
+
keeps unstable target features out of the cfg set
|
|
550
|
+
([rust-lang/rust#77839](https://github.com/rust-lang/rust/issues/77839)).
|
|
551
|
+
Passing `-C target-feature=+atomics` does not change that: rustc warns that
|
|
552
|
+
the feature is unstable and the cfg still does not appear. Only the exact
|
|
553
|
+
cargo `TARGET` answers the question, and only a build script can read it.
|
|
554
|
+
|
|
555
|
+
An addon crate gets the answer for free. `napi_build::setup()` emits
|
|
556
|
+
`cfg(napi_wasi_threads)` when — and only when — the crate is being compiled
|
|
557
|
+
for `wasm32-wasip1-threads`, so the addon can write:
|
|
558
|
+
|
|
559
|
+
```rust
|
|
560
|
+
#[cfg(napi_wasi_threads)]
|
|
561
|
+
const WORKERS: usize = 4;
|
|
562
|
+
#[cfg(not(napi_wasi_threads))]
|
|
563
|
+
const WORKERS: usize = 1;
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
`setup()` also prints the matching `cargo::rustc-check-cfg` line on _every_
|
|
567
|
+
target, so `#[cfg(napi_wasi_threads)]` is a known cfg everywhere and never
|
|
568
|
+
trips the `unexpected_cfgs` lint on the targets where it is not set.
|
|
569
|
+
|
|
570
|
+
A build-script cfg is crate-local: it reaches the crate whose `build.rs`
|
|
571
|
+
printed it and nothing else. Another crate in the same graph that needs the
|
|
572
|
+
distinction therefore needs its own build script — which is why `napi` and
|
|
573
|
+
`napi-async-runtime` each carry one:
|
|
574
|
+
|
|
575
|
+
```rust
|
|
576
|
+
// build.rs
|
|
577
|
+
fn main() {
|
|
578
|
+
println!("cargo::rustc-check-cfg=cfg(my_wasi_threads)");
|
|
579
|
+
if std::env::var("TARGET").as_deref() == Ok("wasm32-wasip1-threads") {
|
|
580
|
+
println!("cargo::rustc-cfg=my_wasi_threads");
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
Use the older single-colon `cargo:` form if the crate's `rust-version` is
|
|
586
|
+
below 1.77.
|
|
587
|
+
|
|
588
|
+
Absence has to be the conservative branch. The cfg is permission to use
|
|
589
|
+
shared memory and real threads, never a requirement that something be
|
|
590
|
+
configured: a plain `cargo build`, `cargo test`, or rust-analyzer run — no
|
|
591
|
+
`napi build`, no CLI, no `RUSTFLAGS` — must still compile a correct crate on
|
|
592
|
+
the `not(...)` side. Nothing outside the build script can set it, so a
|
|
593
|
+
mistake there is silent.
|
|
594
|
+
|
|
595
|
+
### Third-party locks
|
|
596
|
+
|
|
597
|
+
`parking_lot_core`, the lock core under `parking_lot` and `dashmap`, does not
|
|
598
|
+
follow this rule, and an addon can pull it in without ever naming it. Its
|
|
599
|
+
only threaded-wasm parker is gated on the crate's `nightly` feature _and_
|
|
600
|
+
`target_feature = "atomics"` (0.9.12, `src/thread_parker/mod.rs:69`), so on
|
|
601
|
+
stable the cascade falls through to the wasm stub, whose `prepare_park` is
|
|
602
|
+
`panic!("Parking not supported on this platform")`
|
|
603
|
+
(`src/thread_parker/wasm.rs:26`). The build succeeds and the addon dies at the
|
|
604
|
+
first _contended_ lock, on a target whose `std` has fully working threads.
|
|
605
|
+
|
|
606
|
+
Upstream
|
|
607
|
+
[Amanieu/parking_lot#529](https://github.com/Amanieu/parking_lot/pull/529)
|
|
608
|
+
adds a `std::sync::Mutex` and `Condvar` parker for WASI, but its selection arm
|
|
609
|
+
keys on `target_feature = "atomics"` as well, so it cannot be reached on
|
|
610
|
+
stable either. Until that is resolved there are two options:
|
|
611
|
+
|
|
612
|
+
- Keep `parking_lot` and `dashmap` out of the `wasm32-wasip1-threads`
|
|
613
|
+
dependency graph, or
|
|
614
|
+
- route the whole graph through a `parking_lot_core` that detects the triple
|
|
615
|
+
in its own `build.rs`, exactly as above. napi-rs maintains that fork and
|
|
616
|
+
publishes it as `lock_api-napi` 0.4.15, `parking_lot_core-napi` 0.9.13 and
|
|
617
|
+
`parking_lot-napi` 0.12.6; each keeps the upstream `[lib] name`, so
|
|
618
|
+
`use parking_lot::Mutex` still compiles. A transitive user such as
|
|
619
|
+
`dashmap` is only reachable through `[patch.crates-io]`, and the only
|
|
620
|
+
form cargo accepts is a git pin on the fork's `wasi-threads-parker`
|
|
621
|
+
branch, which still carries the _upstream_ package names. Pin the exact
|
|
622
|
+
revision rather than the branch, so the lock stays reproducible:
|
|
623
|
+
|
|
624
|
+
```toml
|
|
625
|
+
[patch.crates-io.parking_lot_core]
|
|
626
|
+
git = "https://github.com/napi-rs/parking_lot"
|
|
627
|
+
rev = "ac046ba44e72159e90e36b7323b1058ba1d48ad2"
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
The published `*-napi` crates cannot be named in such an entry. Cargo
|
|
631
|
+
rejects a crates.io package replacing another crates.io package, because
|
|
632
|
+
a patch must point to a different source:
|
|
633
|
+
|
|
634
|
+
```toml
|
|
635
|
+
[patch.crates-io]
|
|
636
|
+
parking_lot_core = { package = "parking_lot_core-napi", version = "0.9.13" }
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
```text
|
|
640
|
+
error: patch for `parking_lot_core-napi` points to the same source, but
|
|
641
|
+
patches must point to different sources
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
Over a path or git source the entry resolves, and is then dropped. Cargo
|
|
645
|
+
does honour `package =` — it selects that package from the replacement
|
|
646
|
+
source — but the selected package keeps its own name, and a dependency on
|
|
647
|
+
`parking_lot_core` is satisfied only by a package named
|
|
648
|
+
`parking_lot_core`. The fork's `master` carries the renamed manifests
|
|
649
|
+
(`name = "parking_lot_core-napi"`), so pointing the rename at it gives:
|
|
650
|
+
|
|
651
|
+
```toml
|
|
652
|
+
[patch.crates-io.parking_lot_core]
|
|
653
|
+
git = "https://github.com/napi-rs/parking_lot"
|
|
654
|
+
rev = "e243c6c43832c151bce2887fcb209b5b8b72ac61" # master
|
|
655
|
+
package = "parking_lot_core-napi"
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
```text
|
|
659
|
+
warning: patch `parking_lot_core-napi v0.9.13 (…?rev=e243c6c4…)` was not
|
|
660
|
+
used in the crate graph
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
The lock then records it under `[[patch.unused]]` and `dashmap` keeps
|
|
664
|
+
building against stock `parking_lot_core` 0.9.12 — the panicking parker.
|
|
665
|
+
|
|
666
|
+
Verified on the patched core: a contended probe under `wasmtime run -S
|
|
667
|
+
threads` — `Mutex`, `Condvar`, `RwLock`, `park_until`, `notify_all`, `DashMap`
|
|
668
|
+
— reports `ALL OK` with zero parking stubs left in the module, and rolldown's
|
|
669
|
+
threaded WASI artifact passed its stability lane 3 of 3.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napi-rs/cli",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.5",
|
|
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.151.0",
|
|
91
91
|
"tsdown": "^0.23.0",
|
|
92
92
|
"tslib": "^2.8.1"
|
|
93
93
|
},
|