### Create New napi-rs Project Source: https://napi.rs/docs/introduction/getting-started Initiates a new napi-rs project by running the `napi new` command. This command prompts the user for project details such as package name, target platforms, and whether to enable GitHub Actions. ```bash napi new ``` -------------------------------- ### Install @napi-rs/cli Source: https://napi.rs/docs/introduction/getting-started Installs the napi-rs command-line interface globally for Yarn, npm, or pnpm. This CLI tool is essential for creating new napi-rs projects. ```bash yarn global add @napi-rs/cli ``` ```bash npm install -g @napi-rs/cli ``` ```bash pnpm add -g @napi-rs/cli ``` -------------------------------- ### Dynamic Native Module Loading in Node.js Source: https://napi.rs/docs/introduction/getting-started Provides an example `index.js` file for a Node.js package that dynamically loads the correct native binary. It checks the operating system and architecture, first attempting to load a local `.node` file, then a package from `node_modules`, and handles potential loading errors. ```javascript const { existsSync, readFileSync } = require('fs') const { join } = require('path') const { platform, arch } = process let nativeBinding = null let localFileExisted = false let isMusl = false let loadError = null switch (platform) { case 'darwin': switch (arch) { case 'x64': localFileExisted = existsSync(join(__dirname, 'core.darwin-x64.node')) try { if (localFileExisted) { nativeBinding = require('./core.darwin-x64.node') } else { nativeBinding = require('@cool/core-darwin-x64') } } catch (e) { loadError = e } break case 'arm64': localFileExisted = existsSync(join(__dirname, 'core.darwin-arm64.node')) try { if (localFileExisted) { nativeBinding = require('./core.darwin-arm64.node') } else { nativeBinding = require('@cool/core-darwin-arm64') } } catch (e) { loadError = e } break default: throw new Error(`Unsupported architecture on macOS: ${arch}`) } break // ... default: throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) } if (!nativeBinding) { if (loadError) { throw loadError } throw new Error(`Failed to load native binding`) } const { plus100 } = nativeBinding module.exports.plus100 = plus100 ``` -------------------------------- ### Package.json Configuration for Native Modules Source: https://napi.rs/docs/introduction/getting-started Demonstrates how to configure `package.json` files for distributing native Node.js modules. It shows separate platform-specific packages with `os` and `cpu` fields, and a main package that lists these as `optionalDependencies`. ```json { "name": "@cool/core-darwin-x64", "version": "1.0.0", "os": ["darwin"], "cpu": ["x64"] } ``` ```json { "name": "@cool/core", "version": "1.0.0", "optionalDependencies": { "@cool/core-darwin-x64": "^1.0.0", "@cool/core-win32-x64": "^1.0.0", "@cool/core-linux-arm64": "^1.0.0" } } ``` -------------------------------- ### Install Dependencies and Build Native Package Source: https://napi.rs/docs/introduction/simple-package This snippet shows the commands to install project dependencies using yarn and then build the native package. It includes the output of the build process, demonstrating the compilation of the native addon for Node.js. ```bash cd cool yarn install ``` ```bash yarn build yarn run v1.22.17 $ napi build --platform --release Updating crates.io index Downloaded proc-macro2 v1.0.34 Downloaded once_cell v1.9.0 Downloaded napi v2.0.0-beta.7 Downloaded 3 crates (129.4 KB) in 2.35s Compiling proc-macro2 v1.0.34 Compiling unicode-xid v0.2.2 Compiling memchr v2.4.1 Compiling syn v1.0.82 Compiling regex-syntax v0.6.25 Compiling convert_case v0.4.0 Compiling once_cell v1.9.0 Compiling napi-build v1.2.0 Compiling napi-sys v2.1.0 Compiling napi-rs_cool v0.0.0 (/cool) Compiling quote v1.0.10 Compiling aho-corasick v0.7.18 Compiling regex v1.5.4 Compiling napi-derive-backend v1.0.17 Compiling ctor v0.1.21 Compiling napi-derive v2.0.0-beta.5 Compiling napi v2.0.0-beta.7 Finished release [optimized] target(s) in 37.11s ✨ Done in 37.80s. ``` -------------------------------- ### Node.js Build Tools Installation Command Source: https://napi.rs/docs/deep-dive/native-module This command installs the necessary build tools for compiling Node.js native addons on Windows. It ensures that the compiler and other required utilities are available. ```bash npm install --global --production windows-build-tools ``` -------------------------------- ### Platform-Specific Native Addon Package Configuration (JSON) Source: https://napi.rs/docs/deep-dive/release Illustrates the `package.json` configuration for individual, platform-specific native addon npm packages. Each package targets a particular operating system and CPU architecture, ensuring correct installation. ```json { "name": "@node-rs/bcrypt-darwin", "version": "0.5.0", "os": ["darwin"], "cpu": ["x64"] } ``` ```json { "name": "@node-rs/bcrypt-linux", "version": "0.5.0", "os": ["linux"], "cpu": ["x64"] } ``` ```json { "name": "@node-rs/bcrypt-win32", "version": "0.5.0", "os": ["win32"], "cpu": ["x64"] } ``` -------------------------------- ### Install WebAssembly Packages with Yarn Source: https://napi.rs/docs/concepts/webassembly Instructions for installing WebAssembly (wasm32) packages using Yarn. For Yarn v4, configure supportedArchitectures in .yarnrc.yml. For Yarn v1, use the --ignore-engines flag. ```yaml supportedArchitectures: cpu: - current - wasm32 ``` ```bash yarn install --ignore-engines ``` -------------------------------- ### Initialize New @napi-rs/cool Project with napi new Source: https://napi.rs/docs/introduction/simple-package This snippet demonstrates the initial command to create a new project using `napi new`. It prompts for the package name and directory name, guiding the user through setting up a new native Node.js addon project. ```bash napi new ? Package name: (The name field in your package.json) ? Dir name: (cool) ? Choose targets you want to support (Press to select, to toggle all, to invert selection, and to proceed) ❯ ◯ aarch64-apple-darwin ◯ aarch64-linux-android ◯ aarch64-unknown-linux-gnu ◯ aarch64-unknown-linux-musl ◯ aarch64-pc-windows-msvc ◯ armv7-unknown-linux-gnueabihf ◉ x86_64-apple-darwin (Move up and down to reveal more choices) ? Enable github actions? (Y/n) ``` ```bash napi new ? Package name: (The name field in your package.json) @napi-rs/cool ? Dir name: cool ? Choose targets you want to support aarch64-apple-darwin, aarch64-linux-android, aarch64-unknown-linux-gnu , aarch64-unknown-linux-musl, aarch64-pc-windows-msvc, armv7-unknown-linux-gnueabihf, x86_64-apple-darwin, x86_64-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, x86_64-unknown-freebsd, i686-p c-windows-msvc, armv7-linux-androideabi ? Enable github actions? Yes ``` -------------------------------- ### Install WebAssembly Packages with npm Source: https://napi.rs/docs/concepts/webassembly Manually installs WebAssembly (wasm32) packages using npm version 10.2.0 or later with the --cpu=wasm32 flag. ```bash npm install --cpu=wasm32 ``` -------------------------------- ### Parse Target Triple and Read Napi Config Source: https://napi.rs/docs/cli/programmatic-api Provides examples of using utility functions from '@napi-rs/cli' to parse a target triple string into its components and to read Napi configuration from project files. These are essential for cross-platform builds and project setup. ```typescript import { parseTriple, readNapiConfig } from '@napi-rs/cli' // Parse a target triple string const triple = parseTriple('x86_64-unknown-linux-gnu') // Result: { platform: 'linux', arch: 'x64', abi: 'gnu', ... } // Read Napi config from package.json or napi.json const config = await readNapiConfig('/path/to/project') ``` -------------------------------- ### Unsafe External Buffer Example in Rust with NAPI-RS Source: https://napi.rs/docs/concepts/typed-array Provides an example of using `BufferSlice::from_external` with manual memory management, emphasizing the critical need to `forget` the original `Vec` to prevent double-free errors and correctly reconstruct and drop the `Vec` in the finalize callback for proper deallocation. ```rust use napi::bindgen_prelude::*; use napi_derive::napi; #[napi] pub fn unsafe_external_example(env: &Env) -> Result> { let mut data = vec![1u8, 2, 3, 4, 5]; let ptr = data.as_mut_ptr(); let len = data.len(); // ⚠️ CRITICAL: Must forget the Vec to prevent double-free std::mem::forget(data); unsafe { BufferSlice::from_external(env, ptr, len, ptr, move |_, ptr| { // ✅ Properly reconstruct and drop the Vec std::mem::drop(Vec::from_raw_parts(ptr, len, len)); // Vec automatically deallocates when dropped }) } } ``` -------------------------------- ### Post-process Build Outputs with oxfmt Source: https://napi.rs/docs/cli/programmatic-api This example demonstrates how to use the @napi-rs/cli programmatic API to build project outputs and then use oxfmt to format the generated JavaScript and TypeScript files. It reads the output file, formats its content using oxfmt, and writes the formatted code back to the file. Dependencies include '@napi-rs/cli' and 'oxfmt'. ```typescript import { readFile, writeFile } from 'node:fs/promises' import { NapiCli, createBuildCommand } from '@napi-rs/cli' import { format, type FormatOptions } from 'oxfmt' import oxfmtConfig from './.oxfmtrc.json' with { type: 'json' } const buildCommand = createBuildCommand(process.argv.slice(2)) const cli = new NapiCli() const buildOptions = buildCommand.getOptions() const { task } = await cli.build(buildOptions) const outputs = await task for (const output of outputs) { if (output.kind !== 'node') { const { code } = await format(output.path, await readFile(output.path, 'utf-8'), oxfmtConfig as FormatOptions) await writeFile(output.path, code) } } ``` -------------------------------- ### NPM Package JSON with Optional Dependencies Source: https://napi.rs/docs/cli/build Example of a package.json file that includes platform-specific native modules under optionalDependencies. This structure is often used to manage native binaries for different operating systems and architectures. ```json { "name": "snappy", "version": "7.0.0", "optionalDependencies": { "@napi-rs/snappy-win32-x64-msvc": "7.0.0", "@napi-rs/snappy-darwin-x64": "7.0.0", "@napi-rs/snappy-linux-x64-gnu": "7.0.0", "@napi-rs/snappy-linux-x64-musl": "7.0.0", "@napi-rs/snappy-linux-arm64-gnu": "7.0.0", "@napi-rs/snappy-win32-ia32-msvc": "7.0.0", "@napi-rs/snappy-linux-arm-gnueabihf": "7.0.0", "@napi-rs/snappy-darwin-arm64": "7.0.0", "@napi-rs/snappy-android-arm64": "7.0.0", "@napi-rs/snappy-android-arm-eabi": "7.0.0", "@napi-rs/snappy-freebsd-x64": "7.0.0", "@napi-rs/snappy-linux-arm64-musl": "7.0.0", "@napi-rs/snappy-win32-arm64-msvc": "7.0.0" } } ``` -------------------------------- ### Programmatic Napi Pre-Publish Execution (TypeScript) Source: https://napi.rs/docs/cli/pre-publish This example demonstrates how to invoke the napi pre-publish functionality programmatically using the NapiCli class in TypeScript. This approach is useful for integrating the pre-publish logic into custom build scripts or other Node.js applications. ```typescript import { NapiCli } from '@napi-rs/cli' new NapiCli().prePublish({ // options }) ``` -------------------------------- ### Create AsyncTask with AbortSignal in Rust Source: https://napi.rs/docs/concepts/async-task Shows how to create an AsyncTask in Rust that accepts an AbortSignal, allowing the asynchronous operation to be aborted from JavaScript before it starts. ```Rust use napi::bindgen_prelude::AbortSignal; use napi::bindgen_prelude::AsyncTask; struct AsyncFib { input: u32 } #[napi] fn async_fib(input: u32, signal: AbortSignal) -> AsyncTask { AsyncTask::with_signal(AsyncFib { input }, signal) } ``` -------------------------------- ### Rust: Use napi_derive::module_init macro Source: https://napi.rs/docs/more/v2-v3-migration-guide This Rust snippet demonstrates the migration of `napi::module_init` to `napi_derive::module_init`. This change is necessary due to upstream breaking changes in the `ctor` crate and allows for modern `#[napi]` macro usage without `compat-mode`. ```rust use napi_derive::module_init; #[module_init] fn init(env: Env) { // ... initialization logic ... } ``` -------------------------------- ### NPM Package JSON with NAPI Configuration Source: https://napi.rs/docs/cli/build Example of a package.json file with a 'napi' configuration block. This block specifies the name for the native module, which is used by N-API RS during the build process. ```json { "name": "snappy", "version": "7.0.0", "napi": { "name": "snappy" } } ``` -------------------------------- ### Install WebAssembly Packages with pnpm Source: https://napi.rs/docs/concepts/webassembly Configures pnpm to install WebAssembly (wasm32) packages by setting supportedArchitectures in the pnpm-workspace.yaml file. ```yaml supportedArchitectures: cpu: - current - wasm32 ``` -------------------------------- ### Abort AsyncTask from JavaScript Source: https://napi.rs/docs/concepts/async-task Illustrates how to use an AbortController in JavaScript to abort an AsyncTask in Rust if it has not yet started, demonstrating error handling for AbortError. ```JavaScript import { asyncFib } from './index.js'; const controller = new AbortController(); asyncFib(20, controller.signal).catch((e) => { console.error(e); // Error: AbortError }); controller.abort(); ``` -------------------------------- ### Example Usage of Async fn with Automatic Reference Source: https://napi.rs/docs/concepts/async-fn This TypeScript code demonstrates how to call an `async fn` (`sleep`) on a Rust struct (`NativeClass`) that utilizes automatic reference management. The example shows creating an instance, calling the async method, and logging the result, illustrating the seamless interaction between JavaScript and Rust async operations. ```typescript const nativeClass = new NativeClass('Brooklyn') const name = await nativeClass.sleep(1) console.log(name) ``` -------------------------------- ### Abort Napi Build Process Source: https://napi.rs/docs/cli/programmatic-api Illustrates how to obtain an `abort` function from the `cli.build()` method to cancel an ongoing build process. Includes an example of handling SIGINT signals for graceful abortion. ```typescript const { task, abort } = await cli.build(options) // Handle SIGINT to abort cleanly process.on('SIGINT', () => { abort() process.exit(1) }) const outputs = await task ``` -------------------------------- ### Update NAPI Configuration: targets in package.json Source: https://napi.rs/docs/more/v2-v3-migration-guide This snippet shows the migration of the `napi.triples` configuration to `napi.targets` in `package.json` for NAPI-RS V3. The `targets` array explicitly lists the desired build targets, replacing the previous `triples` configuration. ```json { "name": "@napi-rs/package-template", "version": "1.0.0", "napi": { "targets": [ "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc", "x86_64-apple-darwin", "aarch64-apple-darwin", "x86_64-unknown-linux-musl", "aarch64-unknown-linux-musl" ] } } ``` -------------------------------- ### Get libuv Event Loop (Rust) Source: https://napi.rs/docs/concepts/env Gets a raw pointer to the underlying libuv event loop used by the Node.js runtime. This function requires the `napi2` feature. ```rust pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s> ``` -------------------------------- ### Get Instance Data (Rust) Source: https://napi.rs/docs/concepts/env Retrieves data that was previously associated with the currently running Agent using `set_instance_data`. Requires the `napi6` feature. ```rust pub fn get_instance_data(&self) -> Result> where T: 'static, ``` -------------------------------- ### Call ThreadsafeFunction with Custom Args (TypeScript) Source: https://napi.rs/docs/concepts/threadsafe-function A TypeScript example demonstrating how to call the `call_threadsafe_function` which expects custom arguments. The callback receives and logs the formatted string sent from Rust. ```typescript import { callThreadsafeFunction } from './index.js' callThreadsafeFunction((data) => { console.log(data) // Hello John }) ``` -------------------------------- ### Create JavaScript Function from Rust Callback (TypeScript) Source: https://napi.rs/docs/concepts/env Demonstrates how to import and use a JavaScript function created from a Rust callback in TypeScript. The example imports `createFunction` and then calls the created `customFunction`, logging its result. ```typescript import { createFunction } from './index.js'; const customFunction = createFunction(); console.log(customFunction(2)); // 4 ``` -------------------------------- ### Define and Instantiate NAPI-RS Engine Class in Rust and TypeScript Source: https://napi.rs/docs/concepts/understanding-lifetime Shows how to define a Rust struct `Engine` using `#[napi]` and expose it as a class to JavaScript. The example includes a constructor for creating instances and demonstrates how ownership is transferred from Rust to JavaScript. ```rust use std::sync::Arc; use napi_derive::napi; #[napi] pub struct Engine { inner: Arc<()> } #[napi] impl Engine { #[napi(constructor)] pub fn new() -> Self { Self { inner: Arc::new(()) } } } ``` ```typescript const engine = new Engine() ``` -------------------------------- ### Call Promise Finally Callback from TypeScript Source: https://napi.rs/docs/concepts/reference Shows how to invoke the Rust `promiseFinallyCallback` function from a TypeScript file. This example demonstrates the basic usage of the N-API function in a Node.js environment. ```typescript import { promiseFinallyCallback } from './index.js'; promiseFinallyCallback(Promise.resolve(), () => { console.log('finally'); }) ``` -------------------------------- ### Create JavaScript Function from Rust Closure (TypeScript) Source: https://napi.rs/docs/concepts/env Demonstrates how to import and use a JavaScript function created from a Rust closure in TypeScript. The example imports `createFunction` and then calls the created `rustClosure`, showing the result of the closure's computation. ```typescript import { createFunction } from './index.js'; const rustClosure = createFunction(); console.log(rustClosure(2)); // 44 ``` -------------------------------- ### Get N-API Version (Rust) Source: https://napi.rs/docs/concepts/env Retrieves the N-API version of the current environment, corresponding to `process.versions.napi`. The `get_napi_version` function returns the version as a `u32`. ```rust pub fn get_napi_version(&self) -> Result ``` -------------------------------- ### Example Usage of 'apply' in JavaScript Source: https://napi.rs/docs/concepts/function This JavaScript code shows how to use the `callFunctionWithApply` function, passing a `RustClass` instance as the `this` context. When the callback is executed, `this.name` correctly refers to the `name` property of the `RustClass` instance. ```typescript import { callFunctionWithApply, RustClass } from './index.js' const rustClass = new RustClass("foo") callFunctionWithApply(rustClass, function() { console.log(this.name) // foo }) ``` -------------------------------- ### Update NAPI Configuration: binaryName in package.json Source: https://napi.rs/docs/more/v2-v3-migration-guide This snippet demonstrates how to update the `package.json` configuration file to replace the `napi.name` field with `napi.binaryName` for NAPI-RS V3. This change affects how the binary name is specified. ```json { "name": "@napi-rs/package-template", "version": "1.0.0", "napi": { "binaryName": "my-package" } } ``` -------------------------------- ### Implement AsyncTask with Cleanup (finally) in Rust Source: https://napi.rs/docs/concepts/async-task Illustrates adding a `finally` method to the `Task` trait for executing cleanup actions after the task is resolved or rejected. This example ensures the buffer is dropped after the computation, regardless of success or failure. ```rust use napi::bindgen_prelude::*; use napi_derive::napi; pub struct CountBufferLength { data: Buffer, } impl CountBufferLength { pub fn new(data: Buffer) -> Self { Self { data } } } impl Task for CountBufferLength { type Output = usize; type JsValue = u32; fn compute(&mut self) -> Result { if self.data.len() == 10 { return Err(Error::new( Status::GenericFailure, "Random fatal error".to_string(), )); } Ok((&self.data).len()) } fn resolve(&mut self, _: Env, output: Self::Output) -> Result { Ok(output as u32) } fn reject(&mut self, _: Env, err: Error) -> Result { // catch the error if err.status == Status::GenericFailure { Ok(0) } else { Ok(1) } } fn finally(self, _: Env) -> Result<()> { println!("finally"); drop(self.data); Ok(()) } } #[napi] pub fn async_count_buffer_length(data: Buffer) -> AsyncTask { AsyncTask::new(CountBufferLength { data }) } ``` -------------------------------- ### Get Node.js Version (Rust) Source: https://napi.rs/docs/concepts/env Retrieves the Node.js version information. The `get_node_version` function returns a `NodeVersion` struct containing details about the Node.js runtime. ```rust pub fn get_node_version(&self) -> Result ``` -------------------------------- ### Configure MaxQueueSize for ThreadsafeFunction in Rust Source: https://napi.rs/docs/concepts/threadsafe-function Shows how to set the `MaxQueueSize` parameter for a `ThreadsafeFunction` in Rust, limiting the number of messages in the queue. This example uses `NonBlocking` mode, where exceeding the queue size results in a `QueueFull` status. ```rust use std::{sync::Arc, thread}; use napi:: bindgen_prelude::*, threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; use napi_derive::napi; #[napi] pub fn call_threadsafe_function( tsfn: Arc>, ) -> Result<()> { thread::spawn(move || { for n in 0..100 { let tsfn = tsfn.clone(); let status = tsfn.call(n, ThreadsafeFunctionCallMode::NonBlocking); println!("{}", status) } }); Ok(()) } ``` -------------------------------- ### Call ThreadsafeFunction with Return Value (TypeScript) Source: https://napi.rs/docs/concepts/threadsafe-function Provides a TypeScript example of calling the `call_threadsafe_function` and handling its return value. The callback modifies the received result before returning it. ```typescript import { callThreadsafeFunction } from './index.js' callThreadsafeFunction((err, result) => { return result + 100 }) ``` -------------------------------- ### Get JS Module File Name (Rust) Source: https://napi.rs/docs/concepts/env Retrieves the file path of the currently running JavaScript module as a URL. This function requires the `napi9` feature to be enabled. ```rust pub fn get_module_file_name(&self) -> Result ``` -------------------------------- ### Run JavaScript Script (Rust) Source: https://napi.rs/docs/concepts/env Executes a JavaScript string and returns the result. The `run_script` function takes a script string and a type parameter `V` for the expected return value. The example shows executing '2 + 2' and asserting the result is 4. ```rust pub fn run_script, V: FromNapiValue>(&self, script: S) -> Result ``` ```rust let result: i32 = env.run_script("2 + 2")?; assert_eq!(result, 4); ``` -------------------------------- ### Update CLI Build Command: manifest-path Source: https://napi.rs/docs/more/v2-v3-migration-guide This snippet illustrates the change in the NAPI CLI build command, where `--cargo-cwd` is removed and replaced by `--manifest-path`. This modification requires specifying the exact path to the `Cargo.toml` file. ```bash napi build --manifest-path ./crates/napi/Cargo.toml ``` -------------------------------- ### Implement AsyncTask with Error Handling (reject) in Rust Source: https://napi.rs/docs/concepts/async-task Shows how to implement the `reject` method in the `Task` trait to handle errors occurring during asynchronous computation. This example counts buffer length but rejects with an error if the length is 10, returning a specific value in JavaScript. ```rust use napi::bindgen_prelude::*; use napi_derive::napi; pub struct CountBufferLength { data: Buffer, } impl CountBufferLength { pub fn new(data: Buffer) -> Self { Self { data } } } impl Task for CountBufferLength { type Output = usize; type JsValue = u32; fn compute(&mut self) -> Result { if self.data.len() == 10 { return Err(Error::new( Status::GenericFailure, "Random fatal error".to_string(), )); } Ok((&self.data).len()) } fn resolve(&mut self, _: Env, output: Self::Output) -> Result { Ok(output as u32) } fn reject(&mut self, _: Env, err: Error) -> Result { // catch the error if err.status == Status::GenericFailure { Ok(0) } else { Ok(1) } } } #[napi] pub fn async_count_buffer_length(data: Buffer) -> AsyncTask { AsyncTask::new(CountBufferLength { data }) } ``` -------------------------------- ### Demonstrate MaxQueueSize Behavior with Heavy Workload in TypeScript Source: https://napi.rs/docs/concepts/threadsafe-function This TypeScript example demonstrates the effect of `MaxQueueSize` when a `ThreadsafeFunction` is called with a computationally intensive callback. Heavy work in the callback, combined with `NonBlocking` mode, leads to `QueueFull` statuses being returned when the queue reaches its limit. ```typescript import { callThreadsafeFunction } from './index.js' function fib(n) { if (n <= 1) return n return fib(n - 1) + fib(n - 2) } callThreadsafeFunction(() => { fib(40) }) ``` -------------------------------- ### Initializing Git Repository and Pushing Source: https://napi.rs/docs/introduction/simple-package Standard Git commands to initialize a new repository, add remote origin, stage all files, commit changes, and push to the remote repository. This is a prerequisite for CI/CD workflows. ```bash git init git remote add origin git@github.com/yourname/cool.git git add . git commit -m "Init" git push ``` -------------------------------- ### Call Asynchronously Resolved JavaScript Promise from Rust Source: https://napi.rs/docs/concepts/promise This JavaScript example shows how to call the Rust `async_plus_100` function, passing a standard JavaScript Promise. The Rust function will asynchronously resolve the promise and return the modified value. ```javascript import { asyncPlus100 } from './index.js' const fx = 20 const result = await asyncPlus100( new Promise((resolve) => { setTimeout(() => resolve(fx), 50) }), ) console.log(result) // 120 ``` -------------------------------- ### Create JavaScript Function from Rust Callback (Rust) Source: https://napi.rs/docs/concepts/env Creates a JavaScript function from a native Rust callback. The `create_function` method takes a name for the JavaScript function and a Rust callback function. The example shows how to create a function named 'customFunction' using a `C` callback. ```rust use napi::bindgen_prelude::*; use napi_derive::napi; #[napi] pub fn create_function(env: &Env) -> Result> { env.create_function("customFunction", custom_function_c_callback) } #[napi(no_export)] fn custom_function(input: u32) -> u32 { input * 2 } ``` -------------------------------- ### TypeScript Definition for Class Getter Source: https://napi.rs/docs/concepts/class Provides the TypeScript type definition for a JavaScript class getter. It uses the `get` keyword followed by the property name, indicating that accessing this property will invoke the associated Rust getter method. ```typescript export class QueryEngine { static withInitialCount(count: number): QueryEngine constructor() get status(): number } ``` -------------------------------- ### Package.json for Platform-Specific Native Addons (JSON) Source: https://napi.rs/docs/deep-dive/release Demonstrates the structure of a `package.json` file for a main package that utilizes optional dependencies for platform-specific native addons. It specifies operating system and CPU architecture targets. ```json { "name": "@node-rs/bcrypt", "version": "0.5.0", "os": ["linux", "win32", "darwin"], "cpu": ["x64"], "optionalDependencies": { "@node-rs/bcrypt-darwin": "^0.5.0", "@node-rs/bcrypt-linux": "^0.5.0", "@node-rs/bcrypt-win32": "^0.5.0" } } ``` -------------------------------- ### Manage External Buffers Safely in Rust with NAPI-RS Source: https://napi.rs/docs/concepts/typed-array Shows how to create `BufferSlice` instances from external data without copying, using `BufferSlice::from_external`. This method requires careful management of the data's lifetime using a `finalize` callback to prevent memory safety issues. It includes examples for both shared ownership with `Arc` and manual memory management. ```rust use std::sync::Arc; use napi::bindgen_prelude::*; use napi_derive::napi; // Safe external buffer management #[napi] pub fn create_shared_buffer(env: &Env) -> Result> { let data = Arc::new(vec![1, 2, 3, 4, 5]); let data_ptr = data.as_ptr() as *mut u8; let len = data.len(); unsafe { BufferSlice::from_external(env, data_ptr, len, data, move |_, arc_data| { drop(arc_data); }) } } #[napi] pub fn create_external_buffer(env: &Env) -> Result> { let mut data = vec![1, 2, 3, 4, 5]; let data_ptr = data.as_mut_ptr(); let len = data.len(); // make sure the data is valid until the finalize callback is called std::mem::forget(data); unsafe { BufferSlice::from_external(env, data_ptr, len, data_ptr, move |_, ptr| { // Cleanup data when JavaScript GC runs std::mem::drop(Vec::from_raw_parts(ptr, len, len)); }) } } ``` -------------------------------- ### Rust: Enable compat-mode for specific JsValues Source: https://napi.rs/docs/more/v2-v3-migration-guide This Rust code snippet shows how to enable the `compat-mode` feature flag to access certain `JsValue` types in NAPI-RS V3. These types, such as `JsObject` and `JsFunction`, are now behind this flag due to safety concerns. ```rust #[cfg(feature = "compat-mode")] use napi::JsObject; ``` -------------------------------- ### ThreadsafeFunction with CalleeHandled: true Error Strategy in TypeScript Source: https://napi.rs/docs/concepts/threadsafe-function Provides a TypeScript example for consuming a ThreadsafeFunction configured with the CalleeHandled: true error strategy. The callback function receives an error argument, which should be checked before processing the result. This aligns with standard Node.js asynchronous callback patterns. ```typescript import { callThreadsafeFunction } from './index.js' callThreadsafeFunction((err, result) => { if (err) { console.error(err) // [Error: Error with: 0] { code: 'GenericFailure' } } console.log(result) }) ``` -------------------------------- ### Rust: Use #[napi(module_exports)] macro Source: https://napi.rs/docs/more/v2-v3-migration-guide This Rust snippet shows the usage of the new `#[napi(module_exports)]` macro in NAPI-RS V3's `napi_derive` crate. This macro replaces the older `#[module_exports]` macro from `compat-mode`, enabling the use of modern `#[napi]` macros. ```rust #[napi(module_exports)] pub fn my_function() -> bool { true } ``` -------------------------------- ### Build C/C++ Dependencies with WASI SDK Source: https://napi.rs/docs/concepts/webassembly Sets up the WASI SDK environment for building C/C++ dependencies for WebAssembly. This involves downloading the SDK and setting the WASI_SDK_PATH environment variable. ```bash # on macOS aarch64 wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-arm64-macos.tar.gz tar -xvf wasi-sdk-25.0-arm64-macos.tar.gz export WASI_SDK_PATH="$(pwd)/wasi-sdk-25.0-arm64-macos" ``` -------------------------------- ### Call Rust Synchronous Promise Handler with JavaScript Source: https://napi.rs/docs/concepts/promise This TypeScript example demonstrates calling the Rust `promise_callback` function, which processes a JavaScript Promise synchronously. It passes a resolved Promise with value 100, and the Rust function returns a new Promise representing the value 200. ```typescript import { promiseCallback } from './index.js' const value = await promiseCallback(Promise.resolve(100)) console.log(value) // 200 ``` -------------------------------- ### Create Npm Dirs CLI Source: https://napi.rs/docs/cli/create-npm-dirs This section describes how to use the `create-npm-dirs` command via the command-line interface. ```APIDOC ## CLI Usage for Create Npm Dirs ### Description Creates npm package directories for different platforms using the Napi CLI. ### Method CLI Command ### Endpoint napi create-npm-dirs ### Parameters #### Query Parameters - **cwd** (string) - Optional - The working directory of where napi command will be executed in, all other paths options are relative to this path. Default: `process.cwd()` - **configPath** (string) - Optional - Path to napi config json file. - **packageJsonPath** (string) - Optional - Path to package.json. Default: `package.json` - **npmDir** (string) - Optional - Path to the folder where the npm packages put. Default: `npm` - **dryRun** (boolean) - Optional - Dry run without touching file system. Default: `false` ### Request Example ```sh napi create-npm-dirs --cwd /path/to/project --npm-dir dist/packages --dry-run ``` ### Response #### Success Response (N/A for CLI) This command typically modifies the file system or performs actions based on the provided options. Success is indicated by the absence of errors. #### Response Example (No direct JSON response, output is usually console logs or file system changes.) ``` -------------------------------- ### Create New NAPI-RS Project (CLI) Source: https://napi.rs/docs/cli/new This snippet shows the command-line interface usage for creating a new NAPI-RS project. It takes a path as an argument and accepts various options to configure the project. ```bash napi new [--options] ``` -------------------------------- ### binding.gyp Configuration for Node.js Native Addons Source: https://napi.rs/docs/deep-dive/native-module This is a sample binding.gyp file that defines multiple C++ native addon targets. It specifies the target names and the source files for each addon. The output will be .node files in the build directory. ```text { "targets": [{ "target_name": "addon1", "sources": [ "1/addon.cc", "1/myobject.cc" ] }, { "target_name": "addon2", "sources": [ "2/addon.cc", "2/myobject.cc" ] }, { "target_name": "addon3", "sources": [ "3/addon.cc", "3/myobject.cc" ] }, { "target_name": "addon4", "sources": [ "4/addon.cc", "4/myobject.cc" ] }] } ``` -------------------------------- ### node-gyp Command Line Interface Usage Source: https://napi.rs/docs/deep-dive/native-module These are common commands for interacting with node-gyp to manage the build process of Node.js native addons. They include configuring the build, compiling, cleaning, and rebuilding projects. ```bash $ node-gyp configure $ node-gyp build $ node-gyp clean $ node-gyp rebuild $ node-gyp install ``` -------------------------------- ### Run Universalize Command (CLI) Source: https://napi.rs/docs/cli/universalize This snippet demonstrates how to execute the universalize command using the command-line interface. It takes optional arguments to configure the process. ```bash # CLI napi universalize [--options] ``` -------------------------------- ### Versioning and Publishing NAPI-RS Package Source: https://napi.rs/docs/introduction/simple-package Commands to version the npm package and push tags, triggering the CI pipeline to build and publish the package. Requires NPM_TOKEN to be configured in GitHub repository secrets. ```bash npm version patch git push --follow-tags ``` -------------------------------- ### Handling External Source Map in JavaScript Source: https://napi.rs/docs/concepts/external This JavaScript code extends a native `MagicString` class to handle source map generation. The `generateMap` method calls the superclass method to get an `External`, then defines `toString` and `toUrl` functions that use the native `toSourcemapString` and `toSourcemapUrl` methods, respectively, effectively bridging the native `External` object to JavaScript functions. ```javascript module.exports.MagicString = class MagicString extends MagicStringNative { generateMap(options) { const sourcemap = super.generateMap({ file: null, source: null, sourceRoot: null, includeContent: false, ...options, }) const toString = () => super.toSourcemapString(sourcemap) const toUrl = () => super.toSourcemapUrl(sourcemap) return { toString, toUrl, } } } ``` -------------------------------- ### Implement JsRepo and JsRemote with Reference in Rust Source: https://napi.rs/docs/concepts/reference This Rust code demonstrates the implementation of `JsRepo` and `JsRemote` using napi-rs. It shows how to inject `Reference` and `Env` into a `#[napi]` function, and how to use `reference.share_with` to create a `'static` lifetime reference to the underlying `Remote` struct, overcoming lifetime limitations. ```rust use napi::bindgen_prelude::*; pub struct Repository { dir: String, } impl Repository { fn remote(&self) -> Remote { Remote { inner: self } } } pub struct Remote<'repo> { inner: &'repo Repository, } impl<'repo> Remote<'repo> { fn name(&self) -> String { "origin".to_owned() } } #[napi] pub struct JsRepo { inner: Repository, } #[napi] impl JsRepo { #[napi(constructor)] pub fn new(dir: String) -> Self { JsRepo { inner: Repository { dir }, } } #[napi] pub fn remote(&self, reference: Reference, env: Env) -> Result { Ok(JsRemote { inner: reference.share_with(env, |repo| Ok(repo.inner.remote()))?, }) } } #[napi] pub struct JsRemote { inner: SharedReference>, } #[napi] impl JsRemote { #[napi] pub fn name(&self) -> String { self.inner.name() } } ``` -------------------------------- ### Create Npm Dirs CLI Command Source: https://napi.rs/docs/cli/create-npm-dirs Demonstrates how to use the 'create-npm-dirs' command via the command-line interface. This command facilitates the creation of npm package directories for various platforms. ```bash # CLI napi create-npm-dirs [--options] ``` -------------------------------- ### Execute Napi Pre-Publish via CLI Source: https://napi.rs/docs/cli/pre-publish This snippet shows how to execute the napi pre-publish command directly from the command line interface. It accepts various options to customize its behavior, such as specifying the working directory or configuration file path. ```sh napi pre-publish [--options] ``` -------------------------------- ### N-API Module Initialization Source: https://napi.rs/docs/deep-dive/history Demonstrates the initialization of a module using N-API. This involves setting up the module's export properties, such as the 'echo' function. The `napi_define_properties` function is used to define the properties of the module. ```C++ void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_status status; // Description constructs for setting exports napi_property_descriptor desc = { "echo", 0, Echo, 0, 0, 0, napi_default, 0 }; // set "echo" into `module.exports` status = napi_define_properties(env, exports, 1, &desc); } ``` -------------------------------- ### Node.js process.dlopen() Implementation (C++) Source: https://napi.rs/docs/deep-dive/native-module This C++ code snippet demonstrates the implementation of Node.js's `process.dlopen()` function, responsible for loading native modules. It handles module initialization, linking, and execution of registration functions. Dependencies include Node.js internal C++ APIs and `uv_dlopen`. ```cpp // DLOpen is process.dlopen(module, filename, flags). void DLOpen(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); auto context = env->context(); Local module; Local exports; Local exports_v; // initialize `module`, `module.exports` values if (!args[0]->ToObject(context).ToLocal(&module) || // this line is equal to `exports = module.exports` !module->Get(context, env->exports_string()).ToLocal(&exports_v) || !exports_v->ToObject(context).ToLocal(&exports)) { return; // Exception pending. } node::Utf8Value filename(env->isolate(), args[1]); // Cast DLib dlib(*filename, flags); bool is_opened = dlib.Open(); node_module* const mp = static_cast( uv_key_get(&thread_local_modpending)); uv_key_set(&thread_local_modpending, nullptr); ... // transfer the handle in dynamic lib to the `mp` mp->nm_dso_handle = dlib.handle_; mp->nm_link = modlist_addon; modlist_addon = mp; if (mp->nm_context_register_func != nullptr) { mp->nm_context_register_func(exports, module, context, mp->nm_priv); } else if (mp->nm_register_func != nullptr) { mp->nm_register_func(exports, module, mp->nm_priv); } else { dlib.Close(); env->ThrowError("Module has no declared entry point."); return; } } ``` -------------------------------- ### Configure Rust Flags for Linux Alpine Build Source: https://napi.rs/docs/more/faq This snippet shows how to configure `rustflags` for building on Linux Alpine when targeting `*-unknown-linux-musl`. It addresses the need to pass `-C target-feature=-crt-static` to `rustc`, which can be done via the `RUSTFLAGS` environment variable or within the `.cargo/config.toml` file. ```bash export RUSTFLAGS="-C target-feature=-crt-static" ``` ```toml [target.x86_64-unknown-linux-musl] rustflags = ["-C", "target-feature=-crt-static"] ``` -------------------------------- ### Download Native Addon Artifacts with GitHub Actions Source: https://napi.rs/docs/cli/artifacts This YAML snippet demonstrates how to use the `actions/download-artifact` action in GitHub Actions to download all pre-built native addon artifacts. The artifacts are downloaded into an 'artifacts' directory, maintaining a structure that separates them by platform. ```yaml - name: Download all artifacts uses: actions/download-artifact@v2 with: path: artifacts ```