rquickjs-napi 0.0.4

Node-API (N-API) support and native addon loading for rquickjs
Documentation
# rquickjs-napi

Node-API (N-API) support for loading native `.node` addons in
[rquickjs](https://github.com/DelSkayn/rquickjs).

`rquickjs-napi` provides an `rquickjs` module loader that loads a native addon
and exposes its `module.exports` to JavaScript. It is intended for embedding
Node-API addons in an `rquickjs` runtime; it does not run Node.js.

## Status and platform support

- Native addon loading is currently supported on Unix platforms.
- Addons must be built for the host platform and architecture and use Node-API
  functions supported by this crate.
- The host executable must export the N-API symbols so that the addon can
  resolve them at load time. On Linux, this commonly requires linking the
  executable with `-rdynamic`; the equivalent linker option may differ on
  other platforms.
- Compatibility depends on the APIs used by each addon; compatibility with
  every Node.js native addon is not guaranteed.
- Synchronous environment cleanup hooks run in reverse registration order when
  their QuickJS context is destroyed. Asynchronous cleanup hooks remain
  unsupported because QuickJS context destruction cannot be paused while they
  are pending; valid calls return `napi_generic_failure`.

See [NAPI.md](NAPI.md) for the implemented API areas and known limitations.

## Usage

Add `rquickjs` with its module loader feature and this crate to your
application:

```toml
[dependencies]
rquickjs = { version = "0.14", features = ["loader"] }
rquickjs-napi = { version = "0.0.4" }
```

Register `NapiLoader` before general-purpose loaders, and add the `.node`
pattern to `FileResolver` so it can resolve addon paths:

```rust
use rquickjs::{
    loader::{FileResolver, ScriptLoader},
    Context, Module, Runtime,
};
use rquickjs_napi::NapiLoader;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = Runtime::new()?;
    runtime.set_loader(
        FileResolver::default().with_pattern("{}.node"),
        (NapiLoader::default(), ScriptLoader::default()),
    );

    let context = Context::full(&runtime)?;
    context.with(|ctx| {
        Module::evaluate(
            ctx,
            "main.js",
            r#"
                import addon from "./addon.node";
                import { hello } from "./addon.node";
                globalThis.addon = addon;
                globalThis.hello = hello;
            "#,
        )?
        .finish::<()>()?;
        Ok::<(), rquickjs::Error>(())
    })?;

    Ok(())
}
```

Replace `hello` with an export provided by the addon. The addon's default
export is its `module.exports`. If `module.exports` is an object, enumerable
string keys that are valid JavaScript identifiers are also available as named
exports.

## Development

The Makefile provides common build and validation targets. Run `make help` to
list them. `make lint` checks formatting and runs Clippy; `make build` builds
all targets; and `make test` runs Rust unit tests. `make ci` runs these checks
and the N-API integration test. Run `make test-napi` to run just that
integration test; it builds the C addon fixture under `tests/fixtures/napi` and
requires a C compiler. `make check` checks all targets without producing
artifacts, while `make fix` applies Cargo and Clippy suggestions and formats
Rust sources. JavaScript test scripts are kept in `tests/`. To cross-compile,
pass an installed Rust target, for example
`make build TARGET=aarch64-unknown-linux-gnu`.

## License

Licensed under either of

- [MIT]LICENSE-MIT, or
- [Apache License, Version 2.0]LICENSE-APACHE,

at your option.