diff --git a/examples/napitutorials/doc/apiguide/README.md b/examples/napitutorials/doc/apiguide/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a8a90e831ac5aae76ad42bebc747f827745cdafe --- /dev/null +++ b/examples/napitutorials/doc/apiguide/README.md @@ -0,0 +1,141 @@ +# node-addon-api Documents + +* [Setup](#setup) +* [API Documentation](#api) +* [Examples](#examples) +* [ABI Stability Guideline](#abi-stability-guideline) +* [More resource and info about native Addons](#resources) + +Node-API is an ABI stable C interface provided by Node.js for building native +addons. It is independent of the underlying JavaScript runtime (e.g. or ChakraCore) +and is maintained as part of Node.js itself. It is intended to insulate +native addons from changes in the underlying JavaScript engine and allow +modules compiled for one version to run on later versions of Node.js without +recompilation. + +The `node-addon-api` module, which is not part of Node.js, preserves the benefits +of the Node-API as it consists only of inline code that depends only on the stable API +provided by Node-API. As such, modules built against one version of Node.js +using node-addon-api should run without having to be rebuilt with newer versions +of Node.js. + +## Setup + - [Installation and usage](setup.md) + - [node-gyp](node-gyp.md) + - [cmake-js](cmake-js.md) + - [Conversion tool](conversion-tool.md) + - [Checker tool](checker-tool.md) + - [Generator](generator.md) + - [Prebuild tools](prebuild_tools.md) + + + +## API Documentation + +The following is the documentation for node-addon-api. + + - [Full Class Hierarchy](hierarchy.md) + - [Addon Structure](addon.md) + - Data Types: + - [Env](env.md) + - [CallbackInfo](callbackinfo.md) + - [Reference](reference.md) + - [Value](value.md) + - [Name](name.md) + - [Symbol](symbol.md) + - [String](string.md) + - [Number](number.md) + - [Date](date.md) + - [BigInt](bigint.md) + - [Boolean](boolean.md) + - [External](external.md) + - [Object](object.md) + - [Array](array.md) + - [ObjectReference](object_reference.md) + - [PropertyDescriptor](property_descriptor.md) + - [Function](function.md) + - [FunctionReference](function_reference.md) + - [ObjectWrap](object_wrap.md) + - [ClassPropertyDescriptor](class_property_descriptor.md) + - [Buffer](buffer.md) + - [ArrayBuffer](array_buffer.md) + - [TypedArray](typed_array.md) + - [TypedArrayOf](typed_array_of.md) + - [DataView](dataview.md) + - [Error Handling](error_handling.md) + - [Error](error.md) + - [TypeError](type_error.md) + - [RangeError](range_error.md) + - [SyntaxError](syntax_error.md) + - [Object Lifetime Management](object_lifetime_management.md) + - [HandleScope](handle_scope.md) + - [EscapableHandleScope](escapable_handle_scope.md) + - [Memory Management](memory_management.md) + - [Async Operations](async_operations.md) + - [AsyncWorker](async_worker.md) + - [AsyncContext](async_context.md) + - [AsyncWorker Variants](async_worker_variants.md) + - [Thread-safe Functions](threadsafe.md) + - [ThreadSafeFunction](threadsafe_function.md) + - [TypedThreadSafeFunction](typed_threadsafe_function.md) + - [Promises](promises.md) + - [Version management](version_management.md) + + + +## Examples + +Are you new to **node-addon-api**? Take a look at our **[examples]()** + +- [Hello World](/tree/main/src/1-getting-started/1_hello_world) +- [Pass arguments to a function](/tree/main/src/1-getting-started/2_function_arguments/node-addon-api) +- [Callbacks](/tree/main/src/1-getting-started/3_callbacks/node-addon-api) +- [Object factory](/tree/main/src/1-getting-started/4_object_factory/node-addon-api) +- [Function factory](/tree/main/src/1-getting-started/5_function_factory/node-addon-api) +- [Wrapping C++ Object](/tree/main/src/1-getting-started/6_object_wrap/node-addon-api) +- [Factory of wrapped object](/tree/main/src/1-getting-started/7_factory_wrap/node-addon-api) +- [Passing wrapped object around](/tree/main/src/2-js-to-native-conversion/8_passing_wrapped/node-addon-api) + + + +## ABI Stability Guideline + +It is important to remember that *other* Node.js interfaces such as +`libuv` (included in a project via `#include `) are not ABI-stable across +Node.js major versions. Thus, an addon must use Node-API and/or `node-addon-api` +exclusively and build against a version of Node.js that includes an +implementation of Node-API (meaning an active LTS version of Node.js) in +order to benefit from ABI stability across Node.js major versions. Node.js +provides an [ABI stability guide][] containing a detailed explanation of ABI +stability in general, and the Node-API ABI stability guarantee in particular. + + + +## More resource and info about native Addons + +There are three options for implementing addons: Node-API, nan, or direct +use of internal , libuv, and Node.js libraries. Unless there is a need for +direct access to functionality that is not exposed by Node-API as outlined +in [C/C++ addons](/dist/latest/docs/api/addons.html) +in Node.js core, use Node-API. Refer to +[C/C++ addons with Node-API](/dist/latest/docs/api/n-api.html) +for more information on Node-API. + +- [C++ Addons](/dist/latest/docs/api/addons.html) +- [Node-API](/dist/latest/docs/api/n-api.html) +- [Node-API - Next Generation Node API for Native Modules]() +- [How We Migrated Realm JavaScript From NAN to Node-API](/article/realm-javascript-nan-to-n-api) + +As node-addon-api's core mission is to expose the plain C Node-API as C++ +wrappers, tools that facilitate n-api/node-addon-api providing more +convenient patterns for developing a Node.js add-on with n-api/node-addon-api +can be published to NPM as standalone packages. It is also recommended to tag +such packages with `node-addon-api` to provide more visibility to the community. + +Quick links to NPM searches: [keywords:node-addon-api](/search?q=keywords%3Anode-addon-api). + + + +## Other bindings + +[ABI stability guide]: /en/docs/guides/abi-stability/ diff --git a/examples/napitutorials/doc/apiguide/addon.md b/examples/napitutorials/doc/apiguide/addon.md new file mode 100644 index 0000000000000000000000000000000000000000..7e5ec47916e878ae4ff7865baf47236dc3bcb347 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/addon.md @@ -0,0 +1,163 @@ +# Add-on Structure + +Class `Napi::Addon` inherits from class [`Napi::InstanceWrap`][]. + +Creating add-ons that work correctly when loaded multiple times from the same +source package into multiple Node.js threads and/or multiple times into the same +Node.js thread requires that all global data they hold be associated with the +environment in which they run. It is not safe to store global data in static +variables because doing so does not take into account the fact that an add-on +may be loaded into multiple threads nor that an add-on may be loaded multiple +times into a single thread. + +The `Napi::Addon` class can be used to define an entire add-on. Instances of +`Napi::Addon` subclasses become instances of the add-on, stored safely by +Node.js on its various threads and into its various contexts. Thus, any data +stored in the instance variables of a `Napi::Addon` subclass instance are +stored safely by Node.js. Functions exposed to JavaScript using +`Napi::Addon::InstanceMethod` and/or `Napi::Addon::DefineAddon` are +instance methods of the `Napi::Addon` subclass and thus have access to data +stored inside the instance. + +`Napi::Addon::DefineProperties` may be used to attach `Napi::Addon` +subclass instance methods to objects other than the one that will be returned to +Node.js as the add-on instance. + +The `Napi::Addon` class can be used together with the `NODE_API_ADDON()` and +`NODE_API_NAMED_ADDON()` macros to define add-ons. + +## Example + +```cpp +#include + +class ExampleAddon : public Napi::Addon { + public: + ExampleAddon(Napi::Env env, Napi::Object exports) { + // In the constructor we declare the functions the add-on makes available + // to JavaScript. + DefineAddon(exports, { + InstanceMethod("increment", &ExampleAddon::Increment), + + // We can also attach plain objects to `exports`, and instance methods as + // properties of those sub-objects. + InstanceValue("subObject", DefineProperties(Napi::Object::New(env), { + InstanceMethod("decrement", &ExampleAddon::Decrement) + }), napi_enumerable) + }); + } + private: + + // This method has access to the data stored in the environment because it is + // an instance method of `ExampleAddon` and because it was listed among the + // property descriptors passed to `DefineAddon()` in the constructor. + Napi::Value Increment(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), ++value); + } + + // This method has access to the data stored in the environment because it is + // an instance method of `ExampleAddon` and because it was exposed to + // JavaScript by calling `DefineProperties()` with the object onto which it is + // attached. + Napi::Value Decrement(const Napi::CallbackInfo& info) { + return Napi::Number::New(info.Env(), --value); + } + + // Data stored in these variables is unique to each instance of the add-on. + uint32_t value = 42; +}; + +// The macro announces that instances of the class `ExampleAddon` will be +// created for each instance of the add-on that must be loaded into Node.js. +NODE_API_ADDON(ExampleAddon) +``` + +The above code can be used from JavaScript as follows: + +```js +'use strict' + +const exampleAddon = require('bindings')('example_addon'); +console.log(exampleAddon.increment()); // prints 43 +console.log(exampleAddon.increment()); // prints 44 +console.log(exampleAddon.subObject.decrement()); // prints 43 +``` + +When Node.js loads an instance of the add-on, a new instance of the class is +created. Its constructor receives the environment `Napi::Env env` and the +exports object `Napi::Object exports`. It can then use the method `DefineAddon` +to either attach methods, accessors, and/or values to the `exports` object or to +create its own `exports` object and attach methods, accessors, and/or values to +it. + +**Note:** `Napi::Addon` uses `Napi::Env::SetInstanceData()` internally. This +means that the add-on should only use `Napi::Env::GetInstanceData` explicitly to +retrieve the instance of the `Napi::Addon` class. Variables whose scope would +otherwise be global should be stored as instance variables in the +`Napi::Addon` class. + +Functions created with `Napi::Function::New()`, accessors created with +`PropertyDescriptor::Accessor()`, and values can also be attached. If their +implementation requires the `ExampleAddon` instance, it can be retrieved from +the `Napi::Env env` with `GetInstanceData()`: + +```cpp +void ExampleBinding(const Napi::CallbackInfo& info) { + ExampleAddon* addon = info.Env().GetInstanceData(); +} +``` + +## Methods + +### Constructor + +Creates a new instance of the add-on. + +```cpp +Napi::Addon(Napi::Env env, Napi::Object exports); +``` + +- `[in] env`: The environment into which the add-on is being loaded. +- `[in] exports`: The exports object received from JavaScript. + +Typically, the constructor calls `DefineAddon()` to attach methods, accessors, +and/or values to `exports`. The constructor may also create a new object and +pass it to `DefineAddon()` as its first parameter if it wishes to replace the +`exports` object as provided by Node.js. + +### DefineAddon + +Defines an add-on instance with functions, accessors, and/or values. + +```cpp +template +void Napi::Addon::DefineAddon(Napi::Object exports, + const std::initializer_list& properties); +``` + +* `[in] exports`: The object to return to Node.js as an instance of the add-on. +* `[in] properties`: Initializer list of add-on property descriptors of the +methods, property accessors, and values that define the add-on. They will be +set on `exports`. +See: [`Class property and descriptor`](class_property_descriptor.md). + +### DefineProperties + +Defines function, accessor, and/or value properties on an object using add-on +instance methods. + +```cpp +template +Napi::Object +Napi::Addon::DefineProperties(Napi::Object object, + const std::initializer_list& properties); +``` + +* `[in] object`: The object that will receive the new properties. +* `[in] properties`: Initializer list of property descriptors of the methods, +property accessors, and values to attach to `object`. +See: [`Class property and descriptor`](class_property_descriptor.md). + +Returns `object`. + +[`Napi::InstanceWrap`]: ./instance_wrap.md diff --git a/examples/napitutorials/doc/apiguide/array.md b/examples/napitutorials/doc/apiguide/array.md new file mode 100644 index 0000000000000000000000000000000000000000..0aa8143e0366e587ba6254c63b1ffb26ded56b35 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/array.md @@ -0,0 +1,81 @@ +# Array + +Class [`Napi::Array`][] inherits from class [`Napi::Object`][]. + +Arrays are native representations of JavaScript Arrays. `Napi::Array` is a wrapper +around `napi_value` representing a JavaScript Array. + +[`Napi::TypedArray`][] and [`Napi::ArrayBuffer`][] correspond to JavaScript data +types such as [`Napi::Int32Array`][] and [`Napi::ArrayBuffer`][], respectively, +that can be used for transferring large amounts of data from JavaScript to the +native side. An example illustrating the use of a JavaScript-provided +`ArrayBuffer` in native code is available [here](/tree/main/src/2-js-to-native-conversion/array_buffer_to_native/node-addon-api). + +## Constructor +```cpp +Napi::Array::Array(); +``` + +Returns an empty array. + +If an error occurs, a `Napi::Error` will be thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +```cpp +Napi::Array::Array(napi_env env, napi_value value); +``` +- `[in] env` - The environment in which to create the array. +- `[in] value` - The primitive to wrap. + +Returns a `Napi::Array` wrapping a `napi_value`. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +## Methods + +### New +```cpp +static Napi::Array Napi::Array::New(napi_env env); +``` +- `[in] env` - The environment in which to create the array. + +Returns a new `Napi::Array`. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +### New + +```cpp +static Napi::Array Napi::Array::New(napi_env env, size_t length); +``` +- `[in] env` - The environment in which to create the array. +- `[in] length` - The length of the array. + +Returns a new `Napi::Array` with the given length. + +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +### Length +```cpp +uint32_t Napi::Array::Length() const; +``` + +Returns the length of the array. + +Note: +This can execute JavaScript code implicitly according to JavaScript semantics. +If an error occurs, a `Napi::Error` will get thrown. If C++ exceptions are not +being used, callers should check the result of `Env::IsExceptionPending` before +attempting to use the returned value. + +[`Napi::ArrayBuffer`]: ./array_buffer.md +[`Napi::Int32Array`]: ./typed_array_of.md +[`Napi::Object`]: ./object.md +[`Napi::TypedArray`]: ./typed_array.md diff --git a/examples/napitutorials/doc/apiguide/array_buffer.md b/examples/napitutorials/doc/apiguide/array_buffer.md new file mode 100644 index 0000000000000000000000000000000000000000..9a7340732e6f6fa422c255a2da760c524b5d5140 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/array_buffer.md @@ -0,0 +1,165 @@ +# ArrayBuffer + +Class `Napi::ArrayBuffer` inherits from class [`Napi::Object`][]. + +The `Napi::ArrayBuffer` class corresponds to the +[JavaScript `ArrayBuffer`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) +class. + +## Methods + +### New + +Allocates a new `Napi::ArrayBuffer` instance with a given length. + +```cpp +static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env, size_t byteLength); +``` + +- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. +- `[in] byteLength`: The length to be allocated, in bytes. + +Returns a new `Napi::ArrayBuffer` instance. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::ArrayBuffer` instance. + +The `Napi::ArrayBuffer` instance does not assume ownership for the data and +expects it to be valid for the lifetime of the instance. Since the +`Napi::ArrayBuffer` is subject to garbage collection this overload is only +suitable for data which is static and never needs to be freed. +This factory method will not provide the caller with an opportunity to free the +data when the `Napi::ArrayBuffer` gets garbage-collected. If you need to free +the data retained by the `Napi::ArrayBuffer` object please use other +variants of the `Napi::ArrayBuffer::New` factory method that accept +`Napi::Finalizer`, which is a function that will be invoked when the +`Napi::ArrayBuffer` object has been destroyed. + +```cpp +static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env, void* externalData, size_t byteLength); +``` + +- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. +- `[in] externalData`: The pointer to the external data to wrap. +- `[in] byteLength`: The length of the `externalData`, in bytes. + +Returns a new `Napi::ArrayBuffer` instance. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::ArrayBuffer` instance. + +The `Napi::ArrayBuffer` instance does not assume ownership for the data and +expects it to be valid for the lifetime of the instance. The data can only be +freed once the `finalizeCallback` is invoked to indicate that the +`Napi::ArrayBuffer` has been released. + +```cpp +template +static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env, + void* externalData, + size_t byteLength, + Finalizer finalizeCallback); +``` + +- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. +- `[in] externalData`: The pointer to the external data to wrap. +- `[in] byteLength`: The length of the `externalData`, in bytes. +- `[in] finalizeCallback`: A function to be called when the `Napi::ArrayBuffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `void*` (which is the + `externalData` pointer), and return `void`. + +Returns a new `Napi::ArrayBuffer` instance. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::ArrayBuffer` instance. + +The `Napi::ArrayBuffer` instance does not assume ownership for the data and expects it +to be valid for the lifetime of the instance. The data can only be freed once +the `finalizeCallback` is invoked to indicate that the `Napi::ArrayBuffer` has been +released. + +```cpp +template +static Napi::ArrayBuffer Napi::ArrayBuffer::New(napi_env env, + void* externalData, + size_t byteLength, + Finalizer finalizeCallback, + Hint* finalizeHint); +``` + +- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. +- `[in] externalData`: The pointer to the external data to wrap. +- `[in] byteLength`: The length of the `externalData`, in bytes. +- `[in] finalizeCallback`: The function to be called when the `Napi::ArrayBuffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `void*` (which is the + `externalData` pointer) and `Hint*`, and return `void`. +- `[in] finalizeHint`: The hint to be passed as the second parameter of the + finalize callback. + +Returns a new `Napi::ArrayBuffer` instance. + +### Constructor + +Initializes an empty instance of the `Napi::ArrayBuffer` class. + +```cpp +Napi::ArrayBuffer::ArrayBuffer(); +``` + +### Constructor + +Initializes a wrapper instance of an existing `Napi::ArrayBuffer` object. + +```cpp +Napi::ArrayBuffer::ArrayBuffer(napi_env env, napi_value value); +``` + +- `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. +- `[in] value`: The `Napi::ArrayBuffer` reference to wrap. + +### ByteLength + +```cpp +size_t Napi::ArrayBuffer::ByteLength() const; +``` + +Returns the length of the wrapped data, in bytes. + +### Data + +```cpp +void* Napi::ArrayBuffer::Data() const; +``` + +Returns a pointer the wrapped data. + +### Detach + +```cpp +void Napi::ArrayBuffer::Detach(); +``` + +Invokes the `ArrayBuffer` detach operation on a detachable `ArrayBuffer`. + +### IsDetached + +```cpp +bool Napi::ArrayBuffer::IsDetached() const; +``` + +Returns `true` if this `ArrayBuffer` has been detached. + +[`Napi::Object`]: ./object.md +[External Buffer]: ./external_buffer.md diff --git a/examples/napitutorials/doc/apiguide/async_context.md b/examples/napitutorials/doc/apiguide/async_context.md new file mode 100644 index 0000000000000000000000000000000000000000..06a606cd9f0f71eeae68f1d90d4bb90c4ae85d9f --- /dev/null +++ b/examples/napitutorials/doc/apiguide/async_context.md @@ -0,0 +1,86 @@ +# AsyncContext + +The [Napi::AsyncWorker](async_worker.md) class may not be appropriate for every +scenario. When using any other async mechanism, introducing a new class +`Napi::AsyncContext` is necessary to ensure an async operation is properly +tracked by the runtime. The `Napi::AsyncContext` class can be passed to +[Napi::Function::MakeCallback()](function.md) method to properly restore the +correct async execution context. + +## Methods + +### Constructor + +Creates a new `Napi::AsyncContext`. + +```cpp +explicit Napi::AsyncContext::AsyncContext(napi_env env, const char* resource_name); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncContext`. +- `[in] resource_name`: Null-terminated strings that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the `async_hooks` API. + +### Constructor + +Creates a new `Napi::AsyncContext`. + +```cpp +explicit Napi::AsyncContext::AsyncContext(napi_env env, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncContext`. +- `[in] resource_name`: Null-terminated strings that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the `async_hooks` API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible `async_hooks`. + +### Destructor + +The `Napi::AsyncContext` to be destroyed. + +```cpp +virtual Napi::AsyncContext::~AsyncContext(); +``` + +### Env + +Requests the environment in which the async context has been initially created. + +```cpp +Napi::Env Env() const; +``` + +Returns the `Napi::Env` environment in which the async context has been created. + +## Operator + +```cpp +Napi::AsyncContext::operator napi_async_context() const; +``` + +Returns the Node-API `napi_async_context` wrapped by the `Napi::AsyncContext` +object. This can be used to mix usage of the C Node-API and node-addon-api. + +## Example + +```cpp +#include "napi.h" + +void MakeCallbackWithAsyncContext(const Napi::CallbackInfo& info) { + Napi::Function callback = info[0].As(); + Napi::Object resource = info[1].As(); + + // Create a new async context instance. + Napi::AsyncContext context(info.Env(), "async_context_test", resource); + + // Invoke the callback with the async context instance. + callback.MakeCallback(Napi::Object::New(info.Env()), + std::initializer_list{}, context); + + // The async context instance is automatically destroyed here because it's + // block-scope like `Napi::HandleScope`. +} +``` diff --git a/examples/napitutorials/doc/apiguide/async_operations.md b/examples/napitutorials/doc/apiguide/async_operations.md new file mode 100644 index 0000000000000000000000000000000000000000..30efefe45dbe1b97d59ce2b9bacb3d020a6ff2ad --- /dev/null +++ b/examples/napitutorials/doc/apiguide/async_operations.md @@ -0,0 +1,31 @@ +# Asynchronous operations + +Node.js native add-ons often need to execute long running tasks and to avoid +blocking the **event loop** they have to run them asynchronously from the +**event loop**. +In the Node.js model of execution the event loop thread represents the thread +where JavaScript code is executing. The Node.js guidance is to avoid blocking +other work queued on the event loop thread. Therefore, we need to do this work on +another thread. + +All this means that native add-ons need to leverage async helpers from libuv as +part of their implementation. This allows them to schedule work to be executed +asynchronously so that their methods can return in advance of the work being +completed. + +Node Addon API provides an interface to support functions that cover +the most common asynchronous use cases. There is an abstract classes to implement +asynchronous operations: + +- **[`Napi::AsyncWorker`](async_worker.md)** + +This class helps manage asynchronous operations through an abstraction +of the concept of moving data between the **event loop** and **worker threads**. + +Also, the above class may not be appropriate for every scenario. When using any +other asynchronous mechanism, the following API is necessary to ensure an +asynchronous operation is properly tracked by the runtime: + +- **[AsyncContext](async_context.md)** + +- **[CallbackScope](callback_scope.md)** diff --git a/examples/napitutorials/doc/apiguide/async_worker.md b/examples/napitutorials/doc/apiguide/async_worker.md new file mode 100644 index 0000000000000000000000000000000000000000..2250d541d150bcd92eba6deece16272c317eab32 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/async_worker.md @@ -0,0 +1,428 @@ +# AsyncWorker + +`Napi::AsyncWorker` is an abstract class that you can subclass to remove many of +the tedious tasks of moving data between the event loop and worker threads. This +class internally handles all the details of creating and executing an asynchronous +operation. + +Once created, execution is requested by calling `Napi::AsyncWorker::Queue`. When +a thread is available for execution the `Napi::AsyncWorker::Execute` method will +be invoked. Once `Napi::AsyncWorker::Execute` completes either +`Napi::AsyncWorker::OnOK` or `Napi::AsyncWorker::OnError` will be invoked. Once +the `Napi::AsyncWorker::OnOK` or `Napi::AsyncWorker::OnError` methods are +complete the `Napi::AsyncWorker` instance is destructed. + +For the most basic use, only the `Napi::AsyncWorker::Execute` method must be +implemented in a subclass. + +## Methods + +### Env + +Requests the environment in which the async worker has been initially created. + +```cpp +Napi::Env Napi::AsyncWorker::Env() const; +``` + +Returns the environment in which the async worker has been created. + +### Queue + +Requests that the work be queued for execution. + +```cpp +void Napi::AsyncWorker::Queue(); +``` + +### Cancel + +Cancels queued work if it has not yet been started. If it has already started +executing, it cannot be cancelled. If cancelled successfully neither +`OnOK` nor `OnError` will be called. + +```cpp +void Napi::AsyncWorker::Cancel(); +``` + +### Receiver + +```cpp +Napi::ObjectReference& Napi::AsyncWorker::Receiver(); +``` + +Returns the persistent object reference of the receiver object set when the async +worker was created. + +### Callback + +```cpp +Napi::FunctionReference& Napi::AsyncWorker::Callback(); +``` + +Returns the persistent function reference of the callback set when the async +worker was created. The returned function reference will receive the results of +the computation that happened in the `Napi::AsyncWorker::Execute` method, unless +the default implementation of `Napi::AsyncWorker::OnOK` or +`Napi::AsyncWorker::OnError` is overridden. + +### SuppressDestruct + +```cpp +void Napi::AsyncWorker::SuppressDestruct(); +``` + +Prevents the destruction of the `Napi::AsyncWorker` instance upon completion of +the `Napi::AsyncWorker::OnOK` callback. + +### SetError + +Sets the error message for the error that happened during the execution. Setting +an error message will cause the `Napi::AsyncWorker::OnError` method to be +invoked instead of `Napi::AsyncWorker::OnOK` once the +`Napi::AsyncWorker::Execute` method completes. + +```cpp +void Napi::AsyncWorker::SetError(const std::string& error); +``` + +- `[in] error`: The reference to the string that represent the message of the error. + +### Execute + +This method is used to execute some tasks outside of the **event loop** on a libuv +worker thread. Subclasses must implement this method and the method is run on +a thread other than that running the main event loop. As the method is not +running on the main event loop, it must avoid calling any methods from node-addon-api +or running any code that might invoke JavaScript. Instead, once this method is +complete any interaction through node-addon-api with JavaScript should be implemented +in the `Napi::AsyncWorker::OnOK` method and `Napi::AsyncWorker::OnError` which run +on the main thread and are invoked when the `Napi::AsyncWorker::Execute` method completes. + +```cpp +virtual void Napi::AsyncWorker::Execute() = 0; +``` + +### OnOK + +This method is invoked when the computation in the `Execute` method ends. +The default implementation runs the `Callback` optionally provided when the +`AsyncWorker` class was created. The `Callback` will by default receive no +arguments. The arguments to the `Callback` can be provided by overriding the +`GetResult()` method. + +```cpp +virtual void Napi::AsyncWorker::OnOK(); +``` +### GetResult + +This method returns the arguments passed to the `Callback` invoked by the default +`OnOK()` implementation. The default implementation returns an empty vector, +providing no arguments to the `Callback`. + +```cpp +virtual std::vector Napi::AsyncWorker::GetResult(Napi::Env env); +``` + +### OnError + +This method is invoked after `Napi::AsyncWorker::Execute` completes if an error +occurs while `Napi::AsyncWorker::Execute` is running and C++ exceptions are +enabled or if an error was set through a call to `Napi::AsyncWorker::SetError`. +The default implementation calls the `Callback` provided when the `Napi::AsyncWorker` +class was created, passing in the error as the first parameter. + +```cpp +virtual void Napi::AsyncWorker::OnError(const Napi::Error& e); +``` + +### OnWorkComplete + +This method is invoked after the work has completed on JavaScript thread. +The default implementation of this method checks the status of the work and +tries to dispatch the result to `Napi::AsyncWorker::OnOk` or `Napi::AsyncWorker::Error` +if the work has committed an error. If the work was cancelled, neither +`Napi::AsyncWorker::OnOk` nor `Napi::AsyncWorker::Error` will be invoked. +After the result is dispatched, the default implementation will call into +`Napi::AsyncWorker::Destroy` if `SuppressDestruct()` was not called. + +```cpp +virtual void OnWorkComplete(Napi::Env env, napi_status status); +``` + +### OnExecute + +This method is invoked immediately on the work thread when scheduled. +The default implementation of this method just calls the `Napi::AsyncWorker::Execute` +and handles exceptions if cpp exceptions were enabled. + +The `OnExecute` method receives an `napi_env` argument. However, the `napi_env` +must NOT be used within this method, as it does not run on the JavaScript +thread and must not run any method that would cause JavaScript to run. In +practice, this means that almost any use of `napi_env` will be incorrect. + +```cpp +virtual void OnExecute(Napi::Env env); +``` + +### Destroy + +This method is invoked when the instance must be deallocated. If +`SuppressDestruct()` was not called then this method will be called after either +`OnError()` or `OnOK()` complete. The default implementation of this method +causes the instance to delete itself using the `delete` operator. The method is +provided so as to ensure that instances allocated by means other than the `new` +operator can be deallocated upon work completion. + +```cpp +virtual void Napi::AsyncWorker::Destroy(); +``` + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Function& callback); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by calling +`Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Function& callback, const char* resource_name); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Function& callback, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Object& receiver, const Napi::Function& callback); +``` + +- `[in] receiver`: The `this` object passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Object& receiver, const Napi::Function& callback, const char* resource_name); +``` + +- `[in] receiver`: The `this` object passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncWork` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(const Napi::Object& receiver, const Napi::Function& callback, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] receiver`: The `this` object passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncWork` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(Napi::Env env); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncWorker`. + +Returns an `Napi::AsyncWorker` instance which can later be queued for execution by calling +`Napi::AsyncWorker::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(Napi::Env env, const char* resource_name); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncWorker`. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by +calling `Napi::AsyncWorker::Queue`. + +### Constructor + +Creates a new `Napi::AsyncWorker`. + +```cpp +explicit Napi::AsyncWorker(Napi::Env env, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncWorker`. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncWorker` instance which can later be queued for execution by +calling `Napi::AsyncWorker::Queue`. + +### Destructor + +Deletes the created work object that is used to execute logic asynchronously. + +```cpp +virtual Napi::AsyncWorker::~AsyncWorker(); +``` + +## Operator + +```cpp +Napi::AsyncWorker::operator napi_async_work() const; +``` + +Returns the Node-API `napi_async_work` wrapped by the `Napi::AsyncWorker` object. This +can be used to mix usage of the C Node-API and node-addon-api. + +## Example + +The first step to use the `Napi::AsyncWorker` class is to create a new class that +inherits from it and implement the `Napi::AsyncWorker::Execute` abstract method. +Typically input to your worker will be saved within class' fields generally +passed in through its constructor. + +When the `Napi::AsyncWorker::Execute` method completes without errors the +`Napi::AsyncWorker::OnOK` function callback will be invoked. In this function the +results of the computation will be reassembled and returned back to the initial +JavaScript context. + +`Napi::AsyncWorker` ensures that all the code in the `Napi::AsyncWorker::Execute` +function runs in the background out of the **event loop** thread and at the end +the `Napi::AsyncWorker::OnOK` or `Napi::AsyncWorker::OnError` function will be +called and are executed as part of the event loop. + +The code below shows a basic example of `Napi::AsyncWorker` the implementation: + +```cpp +#include + +#include +#include + +using namespace Napi; + +class EchoWorker : public AsyncWorker { + public: + EchoWorker(Function& callback, std::string& echo) + : AsyncWorker(callback), echo(echo) {} + + ~EchoWorker() {} + // This code will be executed on the worker thread + void Execute() override { + // Need to simulate cpu heavy task + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + void OnOK() override { + HandleScope scope(Env()); + Callback().Call({Env().Null(), String::New(Env(), echo)}); + } + + private: + std::string echo; +}; +``` + +The `EchoWorker`'s constructor calls the base class' constructor to pass in the +callback that the `Napi::AsyncWorker` base class will store persistently. When +the work on the `Napi::AsyncWorker::Execute` method is done the +`Napi::AsyncWorker::OnOk` method is called and the results return back to +JavaScript invoking the stored callback with its associated environment. + +The following code shows an example of how to create and use an `Napi::AsyncWorker`. + +```cpp +#include + +// Include EchoWorker class +// .. + +using namespace Napi; + +Value Echo(const CallbackInfo& info) { + // You need to validate the arguments here. + Function cb = info[1].As(); + std::string in = info[0].As(); + EchoWorker* wk = new EchoWorker(cb, in); + wk->Queue(); + return info.Env().Undefined(); +} +``` + +Using the implementation of a `Napi::AsyncWorker` is straight forward. You only +need to create a new instance and pass to its constructor the callback you want to +execute when your asynchronous task ends and other data you need for your +computation. Once created the only other action you have to do is to call the +`Napi::AsyncWorker::Queue` method that will queue the created worker for execution. diff --git a/examples/napitutorials/doc/apiguide/async_worker_variants.md b/examples/napitutorials/doc/apiguide/async_worker_variants.md new file mode 100644 index 0000000000000000000000000000000000000000..876131aa8893845bd696e3b8b7820625450cbced --- /dev/null +++ b/examples/napitutorials/doc/apiguide/async_worker_variants.md @@ -0,0 +1,578 @@ +# AsyncProgressWorker + +`Napi::AsyncProgressWorker` is an abstract class which implements `Napi::AsyncWorker` +while extending `Napi::AsyncWorker` internally with `Napi::ThreadSafeFunction` for +moving work progress reports from worker thread(s) to event loop threads. + +Like `Napi::AsyncWorker`, once created, execution is requested by calling +`Napi::AsyncProgressWorker::Queue`. When a thread is available for execution +the `Napi::AsyncProgressWorker::Execute` method will be invoked. During the +execution, `Napi::AsyncProgressWorker::ExecutionProgress::Send` can be used to +indicate execution process, which will eventually invoke `Napi::AsyncProgressWorker::OnProgress` +on the JavaScript thread to safely call into JavaScript. Once `Napi::AsyncProgressWorker::Execute` +completes either `Napi::AsyncProgressWorker::OnOK` or `Napi::AsyncProgressWorker::OnError` +will be invoked. Once the `Napi::AsyncProgressWorker::OnOK` or `Napi::AsyncProgressWorker::OnError` +methods are complete the `Napi::AsyncProgressWorker` instance is destructed. + +For the most basic use, only the `Napi::AsyncProgressWorker::Execute` and +`Napi::AsyncProgressWorker::OnProgress` method must be implemented in a subclass. + +## Methods + +[`Napi::AsyncWorker`][] provides detailed descriptions for most methods. + +### Execute + +This method is used to execute some tasks outside of the **event loop** on a libuv +worker thread. Subclasses must implement this method and the method is run on +a thread other than that running the main event loop. As the method is not +running on the main event loop, it must avoid calling any methods from node-addon-api +or running any code that might invoke JavaScript. Instead, once this method is +complete any interaction through node-addon-api with JavaScript should be implemented +in the `Napi::AsyncProgressWorker::OnOK` method and/or `Napi::AsyncProgressWorker::OnError` +which run on the main thread and are invoked when the `Napi::AsyncProgressWorker::Execute` +method completes. + +```cpp +virtual void Napi::AsyncProgressWorker::Execute(const ExecutionProgress& progress) = 0; +``` + +### OnOK + +This method is invoked when the computation in the `Execute` method ends. +The default implementation runs the `Callback` optionally provided when the +`AsyncProgressWorker` class was created. The `Callback` will by default receive no +arguments. Arguments to the callback can be provided by overriding the `GetResult()` +method. + +```cpp +virtual void Napi::AsyncProgressWorker::OnOK(); +``` + +### OnProgress + +This method is invoked when the computation in the +`Napi::AsyncProgressWorker::ExecutionProgress::Send` method was called during +worker thread execution. This method can also be triggered via a call to +`Napi::AsyncProgress[Queue]Worker::ExecutionProgress::Signal`, in which case the +`data` parameter will be `nullptr`. + +```cpp +virtual void Napi::AsyncProgressWorker::OnProgress(const T* data, size_t count) +``` + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Function& callback); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Function& callback, const char* resource_name); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Function& callback, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Object& receiver, const Napi::Function& callback); +``` + +- `[in] receiver`: The `this` object passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Object& receiver, const Napi::Function& callback, const char* resource_name); +``` + +- `[in] receiver`: The `this` object passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncWork` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(const Napi::Object& receiver, const Napi::Function& callback, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] receiver`: The `this` object to be passed to the called function. +- `[in] callback`: The function which will be called when an asynchronous +operations ends. The given function is called from the main event loop thread. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncWork` instance which can later be queued for execution by +calling `Napi::AsyncWork::Queue`. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(Napi::Env env); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncProgressWorker`. + +Returns an `Napi::AsyncProgressWorker` instance which can later be queued for execution by calling +`Napi::AsyncProgressWorker::Queue`. + +Available with `NAPI_VERSION` equal to or greater than 5. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(Napi::Env env, const char* resource_name); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncProgressWorker`. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncProgressWorker::Queue`. + +Available with `NAPI_VERSION` equal to or greater than 5. + +### Constructor + +Creates a new `Napi::AsyncProgressWorker`. + +```cpp +explicit Napi::AsyncProgressWorker(Napi::Env env, const char* resource_name, const Napi::Object& resource); +``` + +- `[in] env`: The environment in which to create the `Napi::AsyncProgressWorker`. +- `[in] resource_name`: Null-terminated string that represents the +identifier for the kind of resource that is being provided for diagnostic +information exposed by the async_hooks API. +- `[in] resource`: Object associated with the asynchronous operation that +will be passed to possible async_hooks. + +Returns a `Napi::AsyncProgressWorker` instance which can later be queued for execution by +calling `Napi::AsyncProgressWorker::Queue`. + +Available with `NAPI_VERSION` equal to or greater than 5. + +### Destructor + +Deletes the created work object that is used to execute logic asynchronously and +release the internal `Napi::ThreadSafeFunction`, which will be aborted to prevent +unexpected upcoming thread safe calls. + +```cpp +virtual Napi::AsyncProgressWorker::~AsyncProgressWorker(); +``` + +# AsyncProgressWorker::ExecutionProgress + +A bridge class created before the worker thread execution of `Napi::AsyncProgressWorker::Execute`. + +## Methods + +### Send + +`Napi::AsyncProgressWorker::ExecutionProgress::Send` takes two arguments, a pointer +to a generic type of data, and a `size_t` to indicate how many items the pointer is +pointing to. + +The data pointed to will be copied to internal slots of `Napi::AsyncProgressWorker` so +after the call to `Napi::AsyncProgressWorker::ExecutionProgress::Send` the data can +be safely released. + +Note that `Napi::AsyncProgressWorker::ExecutionProgress::Send` merely guarantees +**eventual** invocation of `Napi::AsyncProgressWorker::OnProgress`, which means +multiple send might be coalesced into single invocation of `Napi::AsyncProgressWorker::OnProgress` +with latest data. If you would like to guarantee that there is one invocation of +`OnProgress` for every `Send` call, you should use the `Napi::AsyncProgressQueueWorker` +class instead which is documented further down this page. + +```cpp +void Napi::AsyncProgressWorker::ExecutionProgress::Send(const T* data, size_t count) const; +``` + +### Signal + +`Napi::AsyncProgressWorker::ExecutionProgress::Signal` triggers an invocation of +`Napi::AsyncProgressWorker::OnProgress` with `nullptr` as the `data` parameter. + +```cpp +void Napi::AsyncProgressWorker::ExecutionProgress::Signal(); +``` + +## Example + +The first step to use the `Napi::AsyncProgressWorker` class is to create a new class that +inherits from it and implement the `Napi::AsyncProgressWorker::Execute` abstract method. +Typically input to the worker will be saved within the class' fields generally +passed in through its constructor. + +During the worker thread execution, the first argument of `Napi::AsyncProgressWorker::Execute` +can be used to report the progress of the execution. + +When the `Napi::AsyncProgressWorker::Execute` method completes without errors the +`Napi::AsyncProgressWorker::OnOK` function callback will be invoked. In this function the +results of the computation will be reassembled and returned back to the initial +JavaScript context. + +`Napi::AsyncProgressWorker` ensures that all the code in the `Napi::AsyncProgressWorker::Execute` +function runs in the background out of the **event loop** thread and at the end +the `Napi::AsyncProgressWorker::OnOK` or `Napi::AsyncProgressWorker::OnError` function will be +called and are executed as part of the event loop. + +The code below shows a basic example of the `Napi::AsyncProgressWorker` implementation along with an +example of how the counterpart in Javascript would appear: + +```cpp +#include + +#include +#include + +using namespace Napi; + +class EchoWorker : public AsyncProgressWorker { + public: + EchoWorker(Function& okCallback, std::string& echo) + : AsyncProgressWorker(okCallback), echo(echo) {} + + ~EchoWorker() {} + + // This code will be executed on the worker thread + void Execute(const ExecutionProgress& progress) { + // Need to simulate cpu heavy task + // Note: This Send() call is not guaranteed to trigger an equal + // number of OnProgress calls (read documentation above for more info) + for (uint32_t i = 0; i < 100; ++i) { + progress.Send(&i, 1) + } + } + + void OnError(const Error &e) { + HandleScope scope(Env()); + // Pass error onto JS, no data for other parameters + Callback().Call({String::New(Env(), e.Message())}); + } + + void OnOK() { + HandleScope scope(Env()); + // Pass no error, give back original data + Callback().Call({Env().Null(), String::New(Env(), echo)}); + } + + void OnProgress(const uint32_t* data, size_t /* count */) { + HandleScope scope(Env()); + // Pass no error, no echo data, but do pass on the progress data + Callback().Call({Env().Null(), Env().Null(), Number::New(Env(), *data)}); + } + + private: + std::string echo; +}; +``` + +The `EchoWorker`'s constructor calls the base class' constructor to pass in the +callback that the `Napi::AsyncProgressWorker` base class will store persistently. When +the work on the `Napi::AsyncProgressWorker::Execute` method is done the +`Napi::AsyncProgressWorker::OnOk` method is called and the results are return back to +JavaScript when the stored callback is invoked with its associated environment. + +The following code shows an example of how to create and use an `Napi::AsyncProgressWorker` + +```cpp +#include + +// Include EchoWorker class +// .. + +using namespace Napi; + +Value Echo(const CallbackInfo& info) { + // We need to validate the arguments here + std::string in = info[0].As(); + Function cb = info[1].As(); + EchoWorker* wk = new EchoWorker(cb, in); + wk->Queue(); + return info.Env().Undefined(); +} + +// Register the native method for JS to access +Object Init(Env env, Object exports) +{ + exports.Set(String::New(env, "echo"), Function::New(env, Echo)); + + return exports; +} + +// Register our native addon +NODE_API_MODULE(nativeAddon, Init) +``` + +The implementation of a `Napi::AsyncProgressWorker` can be used by creating a +new instance and passing to its constructor the callback to execute when the +asynchronous task ends and other data needed for the computation. Once created, +the only other action needed is to call the `Napi::AsyncProgressWorker::Queue` +method that will queue the created worker for execution. + +Lastly, the following Javascript (ES6+) code would be associated the above example: + +```js +const { nativeAddon } = require('binding.node'); + +const exampleCallback = (errorResponse, okResponse, progressData) => { + // Use the data accordingly + // ... +}; + +// Call our native addon with the parameters of a string and a function +nativeAddon.echo("example", exampleCallback); +``` + +# AsyncProgressQueueWorker + +`Napi::AsyncProgressQueueWorker` acts exactly like `Napi::AsyncProgressWorker` +except that each progress committed by `Napi::AsyncProgressQueueWorker::ExecutionProgress::Send` +during `Napi::AsyncProgressQueueWorker::Execute` is guaranteed to be +processed by `Napi::AsyncProgressQueueWorker::OnProgress` on the JavaScript +thread in the order it was committed. + +For the most basic use, only the `Napi::AsyncProgressQueueWorker::Execute` and +`Napi::AsyncProgressQueueWorker::OnProgress` method must be implemented in a subclass. + +# AsyncProgressQueueWorker::ExecutionProgress + +A bridge class created before the worker thread execution of `Napi::AsyncProgressQueueWorker::Execute`. + +## Methods + +### Send + +`Napi::AsyncProgressQueueWorker::ExecutionProgress::Send` takes two arguments, a pointer +to a generic type of data, and a `size_t` to indicate how many items the pointer is +pointing to. + +The data pointed to will be copied to internal slots of `Napi::AsyncProgressQueueWorker` so +after the call to `Napi::AsyncProgressQueueWorker::ExecutionProgress::Send` the data can +be safely released. + +`Napi::AsyncProgressQueueWorker::ExecutionProgress::Send` guarantees invocation +of `Napi::AsyncProgressQueueWorker::OnProgress`, which means multiple `Send` +call will result in the in-order invocation of `Napi::AsyncProgressQueueWorker::OnProgress` +with each data item. + +```cpp +void Napi::AsyncProgressQueueWorker::ExecutionProgress::Send(const T* data, size_t count) const; +``` + +### Signal + +`Napi::AsyncProgressQueueWorker::ExecutionProgress::Signal` triggers an invocation of +`Napi::AsyncProgressQueueWorker::OnProgress` with `nullptr` as the `data` parameter. + +```cpp +void Napi::AsyncProgressQueueWorker::ExecutionProgress::Signal() const; +``` + +## Example + +The code below shows an example of the `Napi::AsyncProgressQueueWorker` implementation, but +also demonstrates how to use multiple `Napi::Function`'s if you wish to provide multiple +callback functions for more object-oriented code: + +```cpp +#include + +#include +#include + +using namespace Napi; + +class EchoWorker : public AsyncProgressQueueWorker { + public: + EchoWorker(Function& okCallback, Function& errorCallback, Function& progressCallback, std::string& echo) + : AsyncProgressQueueWorker(okCallback), echo(echo) { + // Set our function references to use them below + this->errorCallback.Reset(errorCallback, 1); + this->progressCallback.Reset(progressCallback, 1); + } + + ~EchoWorker() {} + + // This code will be executed on the worker thread + void Execute(const ExecutionProgress& progress) { + // Need to simulate cpu heavy task to demonstrate that + // every call to Send() will trigger an OnProgress function call + for (uint32_t i = 0; i < 100; ++i) { + progress.Send(&i, 1); + } + } + + void OnOK() { + HandleScope scope(Env()); + // Call our onOkCallback in javascript with the data we were given originally + Callback().Call({String::New(Env(), echo)}); + } + + void OnError(const Error &e) { + HandleScope scope(Env()); + + // We call our callback provided in the constructor with 2 parameters + if (!this->errorCallback.IsEmpty()) { + // Call our onErrorCallback in javascript with the error message + this->errorCallback.Call(Receiver().Value(), {String::New(Env(), e.Message())}); + } + } + + void OnProgress(const uint32_t* data, size_t /* count */) { + HandleScope scope(Env()); + + if (!this->progressCallback.IsEmpty()) { + // Call our onProgressCallback in javascript with each integer from 0 to 99 (inclusive) + // as this function is triggered from the above Send() calls + this->progressCallback.Call(Receiver().Value(), {Number::New(Env(), *data)}); + } + } + + private: + std::string echo; + FunctionReference progressCallback; + FunctionReference errorCallback; + +}; +``` + +The `EchoWorker`'s constructor calls the base class' constructor to pass in the +callback that the `Napi::AsyncProgressQueueWorker` base class will store +persistently. When the work on the `Napi::AsyncProgressQueueWorker::Execute` +method is done the `Napi::AsyncProgressQueueWorker::OnOk` method is called and +the results are returned back to JavaScript when the stored callback is invoked +with its associated environment. + +The following code shows an example of how to create and use an +`Napi::AsyncProgressQueueWorker`. + +```cpp +#include + +// Include EchoWorker class +// .. + +using namespace Napi; + +Value Echo(const CallbackInfo& info) { + // We need to validate the arguments here. + std::string in = info[0].As(); + Function errorCb = info[1].As(); + Function okCb = info[2].As(); + Function progressCb = info[3].As(); + EchoWorker* wk = new EchoWorker(okCb, errorCb, progressCb, in); + wk->Queue(); + return info.Env().Undefined(); +} + +// Register the native method for JS to access +Object Init(Env env, Object exports) +{ + exports.Set(String::New(env, "echo"), Function::New(env, Echo)); + + return exports; +} + +// Register our native addon +NODE_API_MODULE(nativeAddon, Init) +``` + +The implementation of a `Napi::AsyncProgressQueueWorker` can be used by creating a +new instance and passing to its constructor the callback to execute when the +asynchronous task ends and other data needed for the computation. Once created, +the only other action needed is to call the `Napi::AsyncProgressQueueWorker::Queue` +method that will queue the created worker for execution. + +Lastly, the following Javascript (ES6+) code would be associated the above example: + +```js +const { nativeAddon } = require('binding.node'); + +const onErrorCallback = (msg) => { + // Use the data accordingly + // ... +}; + +const onOkCallback = (echo) => { + // Use the data accordingly + // ... +}; + +const onProgressCallback = (num) => { + // Use the data accordingly + // ... +}; + +// Call our native addon with the parameters of a string and three callback functions +nativeAddon.echo("example", onErrorCallback, onOkCallback, onProgressCallback); +``` + +[`Napi::AsyncWorker`]: ./async_worker.md diff --git a/examples/napitutorials/doc/apiguide/bigint.md b/examples/napitutorials/doc/apiguide/bigint.md new file mode 100644 index 0000000000000000000000000000000000000000..d6f2ea68ebb7daf79690cb6fcb7b276832e36be0 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/bigint.md @@ -0,0 +1,97 @@ +# BigInt + +Class `Napi::Bigint` inherits from class [`Napi::Value`][]. + +A JavaScript BigInt value. + +## Methods + +### New + +```cpp +static Napi::BigInt Napi::BigInt::New(Napi::Env env, int64_t value); +static Napi::BigInt Napi::BigInt::New(Napi::Env env, uint64_t value); +``` + + - `[in] env`: The environment in which to construct the `Napi::BigInt` object. + - `[in] value`: The value the JavaScript `BigInt` will contain + +These APIs convert the C `int64_t` and `uint64_t` types to the JavaScript +`BigInt` type. + +```cpp +static Napi::BigInt Napi::BigInt::New(Napi::Env env, + int sign_bit, + size_t word_count, + const uint64_t* words); +``` + + - `[in] env`: The environment in which to construct the `Napi::BigInt` object. + - `[in] sign_bit`: Determines if the resulting `BigInt` will be positive or negative. + - `[in] word_count`: The length of the words array. + - `[in] words`: An array of `uint64_t` little-endian 64-bit words. + +This API converts an array of unsigned 64-bit words into a single `BigInt` +value. + +The resulting `BigInt` is calculated as: (–1)`sign_bit` (`words[0]` +× (264)0 + `words[1]` × (264)1 + …) + +Returns a new JavaScript `BigInt`. + +### Constructor + +```cpp +Napi::BigInt(); +``` + +Returns a new empty JavaScript `Napi::BigInt`. + +### Int64Value + +```cpp +int64_t Napi::BigInt::Int64Value(bool* lossless) const; +``` + + - `[out] lossless`: Indicates whether the `BigInt` value was converted losslessly. + +Returns the C `int64_t` primitive equivalent of the given JavaScript +`BigInt`. If needed it will truncate the value, setting lossless to false. + +### Uint64Value + +```cpp +uint64_t Napi::BigInt::Uint64Value(bool* lossless) const; +``` + + - `[out] lossless`: Indicates whether the `BigInt` value was converted + losslessly. + +Returns the C `uint64_t` primitive equivalent of the given JavaScript +`BigInt`. If needed it will truncate the value, setting lossless to false. + +### WordCount + +```cpp +size_t Napi::BigInt::WordCount() const; +``` + +Returns the number of words needed to store this `BigInt` value. + +### ToWords + +```cpp +void Napi::BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words); +``` + + - `[out] sign_bit`: Integer representing if the JavaScript `BigInt` is positive + or negative. + - `[in/out] word_count`: Must be initialized to the length of the words array. + Upon return, it will be set to the actual number of words that would be + needed to store this `BigInt`. + - `[out] words`: Pointer to a pre-allocated 64-bit word array. + +Returns a single `BigInt` value into a sign bit, 64-bit little-endian array, +and the number of elements in the array. + +[`Napi::Value`]: ./value.md diff --git a/examples/napitutorials/doc/apiguide/boolean.md b/examples/napitutorials/doc/apiguide/boolean.md new file mode 100644 index 0000000000000000000000000000000000000000..6a8ec3f9882190d3e2d7e3b82025e2744df05a37 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/boolean.md @@ -0,0 +1,68 @@ +# Boolean + +Class `Napi::Boolean` inherits from class [`Napi::Value`][]. + +`Napi::Boolean` class is a representation of the JavaScript `Boolean` object. The +`Napi::Boolean` class inherits its behavior from the `Napi::Value` class +(for more info see: [`Napi::Value`](value.md)). + +## Methods + +### Constructor + +Creates a new empty instance of an `Napi::Boolean` object. + +```cpp +Napi::Boolean::Boolean(); +``` + +Returns a new _empty_ `Napi::Boolean` object. + +### Constructor + +Creates a new instance of the `Napi::Boolean` object. + +```cpp +Napi::Boolean(napi_env env, napi_value value); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Boolean` object. +- `[in] value`: The `napi_value` which is a handle for a JavaScript `Boolean`. + +Returns a non-empty `Napi::Boolean` object. + +### New + +Initializes a new instance of the `Napi::Boolean` object. + +```cpp +Napi::Boolean Napi::Boolean::New(napi_env env, bool value); +``` +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Boolean` object. +- `[in] value`: The primitive boolean value (`true` or `false`). + +Returns a new instance of the `Napi::Boolean` object. + +### Value + +Converts a `Napi::Boolean` value to a boolean primitive. + +```cpp +bool Napi::Boolean::Value() const; +``` + +Returns the boolean primitive type of the corresponding `Napi::Boolean` object. + +## Operators + +### operator bool + +Converts a `Napi::Boolean` value to a boolean primitive. + +```cpp +Napi::Boolean::operator bool() const; +``` + +Returns the boolean primitive type of the corresponding `Napi::Boolean` object. + +[`Napi::Value`]: ./value.md diff --git a/examples/napitutorials/doc/apiguide/buffer.md b/examples/napitutorials/doc/apiguide/buffer.md new file mode 100644 index 0000000000000000000000000000000000000000..427eeee2f8eb50b30376774b2302c99f3eace8e9 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/buffer.md @@ -0,0 +1,247 @@ +# Buffer + +Class `Napi::Buffer` inherits from class [`Napi::Uint8Array`][]. + +The `Napi::Buffer` class creates a projection of raw data that can be consumed by +script. + +## Methods + +### New + +Allocates a new `Napi::Buffer` object with a given length. + +```cpp +static Napi::Buffer Napi::Buffer::New(napi_env env, size_t length); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] length`: The number of `T` elements to allocate. + +Returns a new `Napi::Buffer` object. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::Buffer` object. + +The `Napi::Buffer` object does not assume ownership for the data and expects it to be +valid for the lifetime of the object. Since the `Napi::Buffer` is subject to garbage +collection this overload is only suitable for data which is static and never +needs to be freed. +This factory method will not provide the caller with an opportunity to free the +data when the `Napi::Buffer` gets garbage-collected. If you need to free the +data retained by the `Napi::Buffer` object please use other variants of the +`Napi::Buffer::New` factory method that accept `Napi::Finalizer`, which is a +function that will be invoked when the `Napi::Buffer` object has been +destroyed. + +```cpp +static Napi::Buffer Napi::Buffer::New(napi_env env, T* data, size_t length); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. + +Returns a new `Napi::Buffer` object. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::Buffer` object. + +The `Napi::Buffer` object does not assume ownership for the data and expects it +to be valid for the lifetime of the object. The data can only be freed once the +`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released. + +```cpp +template +static Napi::Buffer Napi::Buffer::New(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. +- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the + external data pointer), and return `void`. + +Returns a new `Napi::Buffer` object. + +### New + +> When `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` is defined, this method is not available. +> See [External Buffer][] for more information. + +Wraps the provided external data into a new `Napi::Buffer` object. + +The `Napi::Buffer` object does not assume ownership for the data and expects it to be +valid for the lifetime of the object. The data can only be freed once the +`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released. + +```cpp +template +static Napi::Buffer Napi::Buffer::New(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback, + Hint* finalizeHint); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. +- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the + external data pointer) and `Hint*`, and return `void`. +- `[in] finalizeHint`: The hint to be passed as the second parameter of the + finalize callback. + +Returns a new `Napi::Buffer` object. + +### NewOrCopy + +Wraps the provided external data into a new `Napi::Buffer` object. When the +[external buffer][] is not supported, allocates a new `Napi::Buffer` object and +copies the provided external data into it. + +The `Napi::Buffer` object does not assume ownership for the data and expects it to be +valid for the lifetime of the object. Since the `Napi::Buffer` is subject to garbage +collection this overload is only suitable for data which is static and never +needs to be freed. + +This factory method will not provide the caller with an opportunity to free the +data when the `Napi::Buffer` gets garbage-collected. If you need to free the +data retained by the `Napi::Buffer` object please use other variants of the +`Napi::Buffer::New` factory method that accept `Napi::Finalizer`, which is a +function that will be invoked when the `Napi::Buffer` object has been +destroyed. + +```cpp +static Napi::Buffer Napi::Buffer::NewOrCopy(napi_env env, T* data, size_t length); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. + +Returns a new `Napi::Buffer` object. + +### NewOrCopy + +Wraps the provided external data into a new `Napi::Buffer` object. When the +[external buffer][] is not supported, allocates a new `Napi::Buffer` object and +copies the provided external data into it and the `finalizeCallback` is invoked +immediately. + +The `Napi::Buffer` object does not assume ownership for the data and expects it +to be valid for the lifetime of the object. The data can only be freed once the +`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released. + +```cpp +template +static Napi::Buffer Napi::Buffer::NewOrCopy(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. +- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the + external data pointer), and return `void`. + +Returns a new `Napi::Buffer` object. + +### NewOrCopy + +Wraps the provided external data into a new `Napi::Buffer` object. When the +[external buffer][] is not supported, allocates a new `Napi::Buffer` object and +copies the provided external data into it and the `finalizeCallback` is invoked +immediately. + +The `Napi::Buffer` object does not assume ownership for the data and expects it to be +valid for the lifetime of the object. The data can only be freed once the +`finalizeCallback` is invoked to indicate that the `Napi::Buffer` has been released. + +```cpp +template +static Napi::Buffer Napi::Buffer::NewOrCopy(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback, + Hint* finalizeHint); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to expose. +- `[in] length`: The number of `T` elements in the external data. +- `[in] finalizeCallback`: The function to be called when the `Napi::Buffer` is + destroyed. It must implement `operator()`, accept an Napi::Env, a `T*` (which is the + external data pointer) and `Hint*`, and return `void`. +- `[in] finalizeHint`: The hint to be passed as the second parameter of the + finalize callback. + +Returns a new `Napi::Buffer` object. + +### Copy + +Allocates a new `Napi::Buffer` object and copies the provided external data into it. + +```cpp +static Napi::Buffer Napi::Buffer::Copy(napi_env env, const T* data, size_t length); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] data`: The pointer to the external data to copy. +- `[in] length`: The number of `T` elements in the external data. + +Returns a new `Napi::Buffer` object containing a copy of the data. + +### Constructor + +Initializes an empty instance of the `Napi::Buffer` class. + +```cpp +Napi::Buffer::Buffer(); +``` + +### Constructor + +Initializes the `Napi::Buffer` object using an existing Uint8Array. + +```cpp +Napi::Buffer::Buffer(napi_env env, napi_value value); +``` + +- `[in] env`: The environment in which to create the `Napi::Buffer` object. +- `[in] value`: The Uint8Array reference to wrap. + +### Data + +```cpp +T* Napi::Buffer::Data() const; +``` + +Returns a pointer the external data. + +### Length + +```cpp +size_t Napi::Buffer::Length() const; +``` + +Returns the number of `T` elements in the external data. + +[`Napi::Uint8Array`]: ./typed_array_of.md +[External Buffer]: ./external_buffer.md diff --git a/examples/napitutorials/doc/apiguide/callback_scope.md b/examples/napitutorials/doc/apiguide/callback_scope.md new file mode 100644 index 0000000000000000000000000000000000000000..39e4b58fe56be34de4628c4980498c0be328cf82 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/callback_scope.md @@ -0,0 +1,54 @@ +# CallbackScope + +There are cases (for example, resolving promises) where it is necessary to have +the equivalent of the scope associated with a callback in place when making +certain Node-API calls. + +## Methods + +### Constructor + +Creates a new callback scope on the stack. + +```cpp +Napi::CallbackScope::CallbackScope(napi_env env, napi_callback_scope scope); +``` + +- `[in] env`: The environment in which to create the `Napi::CallbackScope`. +- `[in] scope`: The pre-existing `napi_callback_scope` or `Napi::CallbackScope`. + +### Constructor + +Creates a new callback scope on the stack. + +```cpp +Napi::CallbackScope::CallbackScope(napi_env env, napi_async_context context); +``` + +- `[in] env`: The environment in which to create the `Napi::CallbackScope`. +- `[in] async_context`: The pre-existing `napi_async_context` or `Napi::AsyncContext`. + +### Destructor + +Deletes the instance of `Napi::CallbackScope` object. + +```cpp +virtual Napi::CallbackScope::~CallbackScope(); +``` + +### Env + +```cpp +Napi::Env Napi::CallbackScope::Env() const; +``` + +Returns the `Napi::Env` associated with the `Napi::CallbackScope`. + +## Operator + +```cpp +Napi::CallbackScope::operator napi_callback_scope() const; +``` + +Returns the Node-API `napi_callback_scope` wrapped by the `Napi::CallbackScope` +object. This can be used to mix usage of the C Node-API and node-addon-api. diff --git a/examples/napitutorials/doc/apiguide/callbackinfo.md b/examples/napitutorials/doc/apiguide/callbackinfo.md new file mode 100644 index 0000000000000000000000000000000000000000..0bf4e1ad144a71d4b10ded5ae4702c7d530c68f9 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/callbackinfo.md @@ -0,0 +1,97 @@ +# CallbackInfo + +The object representing the components of the JavaScript request being made. + +The `Napi::CallbackInfo` object is usually created and passed by the Node.js runtime or node-addon-api infrastructure. + +The `Napi::CallbackInfo` object contains the arguments passed by the caller. The number of arguments is returned by the `Length` method. Each individual argument can be accessed using the `operator[]` method. + +The `SetData` and `Data` methods are used to set and retrieve the data pointer contained in the `Napi::CallbackInfo` object. + +## Methods + +### Constructor + +```cpp +Napi::CallbackInfo::CallbackInfo(napi_env env, napi_callback_info info); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::CallbackInfo` object. +- `[in] info`: The `napi_callback_info` data structure from which to construct the `Napi::CallbackInfo` object. + +### Env + +```cpp +Napi::Env Napi::CallbackInfo::Env() const; +``` + +Returns the `Env` object in which the request is being made. + +### NewTarget + +```cpp +Napi::Value Napi::CallbackInfo::NewTarget() const; +``` + +Returns the `new.target` value of the constructor call. If the function that was invoked (and for which the `Napi::NCallbackInfo` was passed) is not a constructor call, a call to `IsEmpty()` on the returned value returns true. + +### IsConstructCall + +```cpp +bool Napi::CallbackInfo::IsConstructCall() const; +``` + +Returns a `bool` indicating if the function that was invoked (and for which the `Napi::CallbackInfo` was passed) is a constructor call. + +### Length + +```cpp +size_t Napi::CallbackInfo::Length() const; +``` + +Returns the number of arguments passed in the `Napi::CallbackInfo` object. + +### operator [] + +```cpp +const Napi::Value operator [](size_t index) const; +``` + +- `[in] index`: The zero-based index of the requested argument. + +Returns a `Napi::Value` object containing the requested argument. + +### This + +```cpp +Napi::Value Napi::CallbackInfo::This() const; +``` + +Returns the JavaScript `this` value for the call + +### Data + +```cpp +void* Napi::CallbackInfo::Data() const; +``` + +Returns the data pointer for the callback. + +### SetData + +```cpp +void Napi::CallbackInfo::SetData(void* data); +``` + +- `[in] data`: The new data pointer to associate with this `Napi::CallbackInfo` object. + +Returns `void`. + +### Not documented here + +```cpp +Napi::CallbackInfo::~CallbackInfo(); +// Disallow copying to prevent multiple free of _dynamicArgs +Napi::CallbackInfo::CallbackInfo(CallbackInfo const &) = delete; +void Napi::CallbackInfo::operator=(CallbackInfo const &) = delete; +``` diff --git a/examples/napitutorials/doc/apiguide/checker-tool.md b/examples/napitutorials/doc/apiguide/checker-tool.md new file mode 100644 index 0000000000000000000000000000000000000000..9d755bd3af9f1cd6e475fcab485196fe271c94a4 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/checker-tool.md @@ -0,0 +1,32 @@ +# Checker Tool + +**node-addon-api** provides a [checker tool][] that will inspect a given +directory tree, identifying all Node.js native addons therein, and further +indicating for each addon whether it is an Node-API addon. + +## To use the checker tool: + + 1. Install the application with `npm install`. + + 2. If the application does not depend on **node-addon-api**, copy the + checker tool into the application's directory. + + 3. If the application does not depend on **node-addon-api**, run the checker + tool from the application's directory: + + ```sh + node ./check-napi.js + ``` + + Otherwise, the checker tool can be run from the application's + `node_modules/` subdirectory: + + ```sh + node ./node_modules/node-addon-api/tools/check-napi.js + ``` + +The tool accepts the root directory from which to start checking for Node.js +native addons as a single optional command line parameter. If omitted it will +start checking from the current directory (`.`). + +[checker tool]: ../tools/check-napi.js diff --git a/examples/napitutorials/doc/apiguide/class_property_descriptor.md b/examples/napitutorials/doc/apiguide/class_property_descriptor.md new file mode 100644 index 0000000000000000000000000000000000000000..69fe92fa4fe7b4d635f89948a4626a8dd1bb17e5 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/class_property_descriptor.md @@ -0,0 +1,123 @@ +# Class property and descriptor + +Property descriptor for use with `Napi::ObjectWrap` and +`Napi::InstanceWrap`. This is different from the standalone +`Napi::PropertyDescriptor` because it is specific to each +`Napi::ObjectWrap` and `Napi::InstanceWrap` subclasses. +This prevents using descriptors from a different class when defining a new +class (preventing the callbacks from having incorrect `this` pointers). + +`Napi::ClassPropertyDescriptor` is a helper class created with +`Napi::ObjectWrap` and `Napi::InstanceWrap`. For more reference about it +see: + +- [InstanceWrap](./instance_wrap.md) +- [ObjectWrap](./object_wrap.md) + +## Example + +```cpp +#include + +class Example : public Napi::ObjectWrap { + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); + Example(const Napi::CallbackInfo &info); + + private: + double _value; + Napi::Value GetValue(const Napi::CallbackInfo &info); + void SetValue(const Napi::CallbackInfo &info, const Napi::Value &value); +}; + +Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { + Napi::Function func = DefineClass(env, "Example", { + // Register a class instance accessor with getter and setter functions. + InstanceAccessor<&Example::GetValue, &Example::SetValue>("value"), + // We can also register a readonly accessor by omitting the setter. + InstanceAccessor<&Example::GetValue>("readOnlyProp") + }); + + Napi::FunctionReference *constructor = new Napi::FunctionReference(); + *constructor = Napi::Persistent(func); + env.SetInstanceData(constructor); + exports.Set("Example", func); + + return exports; +} + +Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + // ... + Napi::Number value = info[0].As(); + this->_value = value.DoubleValue(); +} + +Napi::Value Example::GetValue(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + return Napi::Number::New(env, this->_value); +} + +void Example::SetValue(const Napi::CallbackInfo &info, const Napi::Value &value) { + Napi::Env env = info.Env(); + // ... + Napi::Number arg = value.As(); + this->_value = arg.DoubleValue(); +} + +// Initialize native add-on +Napi::Object Init (Napi::Env env, Napi::Object exports) { + Example::Init(env, exports); + return exports; +} + +// Register and initialize native add-on +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) +``` + +The above code can be used from JavaScript as follows: + +```js +'use strict'; + +const { Example } = require('bindings')('addon'); + +const example = new Example(11); +console.log(example.value); +// It prints 11 +example.value = 19; +console.log(example.value); +// It prints 19 +example.readOnlyProp = 500; +console.log(example.readOnlyProp); +// Unchanged. It prints 19 +``` + +## Methods + +### Constructor + +Creates new instance of `Napi::ClassPropertyDescriptor` descriptor object. + +```cpp +Napi::ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} +``` + +- `[in] desc`: The `napi_property_descriptor` + +Returns new instance of `Napi::ClassPropertyDescriptor` that is used as property descriptor +inside the `Napi::ObjectWrap` class. + +### Operator + +```cpp +operator napi_property_descriptor&() { return _desc; } +``` + +Returns the original Node-API `napi_property_descriptor` wrapped inside the `Napi::ClassPropertyDescriptor` + +```cpp +operator const napi_property_descriptor&() const { return _desc; } +``` + +Returns the original Node-API `napi_property_descriptor` wrapped inside the `Napi::ClassPropertyDescriptor` diff --git a/examples/napitutorials/doc/apiguide/cmake-js.md b/examples/napitutorials/doc/apiguide/cmake-js.md new file mode 100644 index 0000000000000000000000000000000000000000..3e78224aa406554859c6ff86daef6c2c55d06f2d --- /dev/null +++ b/examples/napitutorials/doc/apiguide/cmake-js.md @@ -0,0 +1,68 @@ +# CMake.js + +[**CMake.js**](cmake-js/cmake-js) is a build tool that allow native addon developers to compile their +C or C++ code into executable form. It works like **[node-gyp](node-gyp.md)** but +instead of 's [**gyp**]() tool it is based on the [**CMake**]() build system. + +## Quick Start + +### Install CMake + +CMake.js requires that CMake be installed. Installers for a variety of platforms can be found on the [CMake website](). + +### Install CMake.js + +For developers, CMake.js is typically installed as a global package: + +```bash +npm install -g cmake-js +cmake-js --help +``` + +> For *users* of your native addon, CMake.js should be configured as a dependency in your `package.json` as described in the [CMake.js documentation](cmake-js/cmake-js). + +### CMakeLists.txt + +Your project will require a `CMakeLists.txt` file. The [CMake.js README file](cmake-js/cmake-js#usage) shows what's necessary. + +### NAPI_VERSION + +When building Node-API addons, it's crucial to specify the Node-API version your code is designed to work with. With CMake.js, this information is specified in the `CMakeLists.txt` file: + +``` +add_definitions(-DNAPI_VERSION=3) +``` + +Since Node-API is ABI-stable, your Node-API addon will work, without recompilation, with the Node-API version you specify in `NAPI_VERSION` and all subsequent Node-API versions. + +In the absence of a need for features available only in a specific Node-API version, version 3 is a good choice as it is the version of Node-API that was active when Node-API left experimental status. + +### NAPI_EXPERIMENTAL + +The following line in the `CMakeLists.txt` file will enable Node-API experimental features if your code requires them: + +``` +add_definitions(-DNAPI_EXPERIMENTAL) +``` + +### node-addon-api + +If your Node-API native add-on uses the optional [**node-addon-api**](/node-addon-api#node-addon-api-module) C++ wrapper, the `CMakeLists.txt` file requires additional configuration information as described on the [CMake.js README file](cmake-js/cmake-js#node-api-and-node-addon-api). + +## Example + +A working example of an Node-API native addon built using CMake.js can be found on the [node-addon-examples repository](/tree/main/src/8-tooling/build_with_cmake#building-node-api-addons-using-cmakejs). + +## **CMake** Reference + + - [Installation](cmake-js/cmake-js#installation) + - [How to use](cmake-js/cmake-js#usage) + - [Using Node-API and node-addon-api](cmake-js/cmake-js#n-api-and-node-addon-api) + - [Tutorials](cmake-js/cmake-js#tutorials) + - [Use case in the works - ArrayFire.js](cmake-js/cmake-js#use-case-in-the-works---arrayfirejs) + +Sometimes finding the right settings is not easy so to accomplish at most +complicated task please refer to: + +- [CMake documentation](/) +- [CMake.js wiki](cmake-js/cmake-js/wiki) diff --git a/examples/napitutorials/doc/apiguide/conversion-tool.md b/examples/napitutorials/doc/apiguide/conversion-tool.md new file mode 100644 index 0000000000000000000000000000000000000000..3b50b9cc142fa95f4c96db8c1a8bbaa1c37a67fc --- /dev/null +++ b/examples/napitutorials/doc/apiguide/conversion-tool.md @@ -0,0 +1,28 @@ +# Conversion Tool + +To make the migration to **node-addon-api** easier, we have provided a script to +help complete some tasks. + +## To use the conversion script: + + 1. Go to your module directory + +``` +cd [module_path] +``` + + 2. Install node-addon-api module + +``` +npm install node-addon-api +``` + 3. Run node-addon-api conversion script + +``` +node ./node_modules/node-addon-api/tools/conversion.js ./ +``` + + 4. While this script makes conversion easier, it still cannot fully convert +the module. The next step is to try to build the module and complete the +remaining conversions necessary to allow it to compile and pass all of the +module's tests. \ No newline at end of file diff --git a/examples/napitutorials/doc/apiguide/dataview.md b/examples/napitutorials/doc/apiguide/dataview.md new file mode 100644 index 0000000000000000000000000000000000000000..5fe5b21728a5c057503b96902b3141c2ff95493f --- /dev/null +++ b/examples/napitutorials/doc/apiguide/dataview.md @@ -0,0 +1,248 @@ +# DataView + +Class `Napi::DataView` inherits from class [`Napi::Object`][]. + +The `Napi::DataView` class corresponds to the +[JavaScript `DataView`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) +class. + +## Methods + +### New + +Allocates a new `Napi::DataView` instance with a given `Napi::ArrayBuffer`. + +```cpp +static Napi::DataView Napi::DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer); +``` + +- `[in] env`: The environment in which to create the `Napi::DataView` instance. +- `[in] arrayBuffer` : `Napi::ArrayBuffer` underlying the `Napi::DataView`. + +Returns a new `Napi::DataView` instance. + +### New + +Allocates a new `Napi::DataView` instance with a given `Napi::ArrayBuffer`. + +```cpp +static Napi::DataView Napi::DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer, size_t byteOffset); +``` + +- `[in] env`: The environment in which to create the `Napi::DataView` instance. +- `[in] arrayBuffer` : `Napi::ArrayBuffer` underlying the `Napi::DataView`. +- `[in] byteOffset` : The byte offset within the `Napi::ArrayBuffer` from which to start projecting the `Napi::DataView`. + +Returns a new `Napi::DataView` instance. + +### New + +Allocates a new `Napi::DataView` instance with a given `Napi::ArrayBuffer`. + +```cpp +static Napi::DataView Napi::DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer, size_t byteOffset, size_t byteLength); +``` + +- `[in] env`: The environment in which to create the `Napi::DataView` instance. +- `[in] arrayBuffer` : `Napi::ArrayBuffer` underlying the `Napi::DataView`. +- `[in] byteOffset` : The byte offset within the `Napi::ArrayBuffer` from which to start projecting the `Napi::DataView`. +- `[in] byteLength` : Number of elements in the `Napi::DataView`. + +Returns a new `Napi::DataView` instance. + +### Constructor + +Initializes an empty instance of the `Napi::DataView` class. + +```cpp +Napi::DataView(); +``` + +### Constructor + +Initializes a wrapper instance of an existing `Napi::DataView` instance. + +```cpp +Napi::DataView(napi_env env, napi_value value); +``` + +- `[in] env`: The environment in which to create the `Napi::DataView` instance. +- `[in] value`: The `Napi::DataView` reference to wrap. + +### ArrayBuffer + +```cpp +Napi::ArrayBuffer Napi::DataView::ArrayBuffer() const; +``` + +Returns the backing array buffer. + +### ByteOffset + +```cpp +size_t Napi::DataView::ByteOffset() const; +``` + +Returns the offset into the `Napi::DataView` where the array starts, in bytes. + +### ByteLength + +```cpp +size_t Napi::DataView::ByteLength() const; +``` + +Returns the length of the array, in bytes. + +### GetFloat32 + +```cpp +float Napi::DataView::GetFloat32(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a signed 32-bit float (float) at the specified byte offset from the start of the `Napi::DataView`. + +### GetFloat64 + +```cpp +double Napi::DataView::GetFloat64(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a signed 64-bit float (double) at the specified byte offset from the start of the `Napi::DataView`. + +### GetInt8 + +```cpp +int8_t Napi::DataView::GetInt8(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a signed 8-bit integer (byte) at the specified byte offset from the start of the `Napi::DataView`. + +### GetInt16 + +```cpp +int16_t Napi::DataView::GetInt16(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a signed 16-bit integer (short) at the specified byte offset from the start of the `Napi::DataView`. + +### GetInt32 + +```cpp +int32_t Napi::DataView::GetInt32(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a signed 32-bit integer (long) at the specified byte offset from the start of the `Napi::DataView`. + +### GetUint8 + +```cpp +uint8_t Napi::DataView::GetUint8(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a unsigned 8-bit integer (unsigned byte) at the specified byte offset from the start of the `Napi::DataView`. + +### GetUint16 + +```cpp +uint16_t Napi::DataView::GetUint16(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a unsigned 16-bit integer (unsigned short) at the specified byte offset from the start of the `Napi::DataView`. + +### GetUint32 + +```cpp +uint32_t Napi::DataView::GetUint32(size_t byteOffset) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. + +Returns a unsigned 32-bit integer (unsigned long) at the specified byte offset from the start of the `Napi::DataView`. + +### SetFloat32 + +```cpp +void Napi::DataView::SetFloat32(size_t byteOffset, float value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetFloat64 + +```cpp +void Napi::DataView::SetFloat64(size_t byteOffset, double value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetInt8 + +```cpp +void Napi::DataView::SetInt8(size_t byteOffset, int8_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetInt16 + +```cpp +void Napi::DataView::SetInt16(size_t byteOffset, int16_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetInt32 + +```cpp +void Napi::DataView::SetInt32(size_t byteOffset, int32_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetUint8 + +```cpp +void Napi::DataView::SetUint8(size_t byteOffset, uint8_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetUint16 + +```cpp +void Napi::DataView::SetUint16(size_t byteOffset, uint16_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +### SetUint32 + +```cpp +void Napi::DataView::SetUint32(size_t byteOffset, uint32_t value) const; +``` + +- `[in] byteOffset`: The offset, in byte, from the start of the view where to read the data. +- `[in] value`: The value to set. + +[`Napi::Object`]: ./object.md diff --git a/examples/napitutorials/doc/apiguide/date.md b/examples/napitutorials/doc/apiguide/date.md new file mode 100644 index 0000000000000000000000000000000000000000..4c5fefa5ed8c0433fff3d1233b74fa1ee6a4804c --- /dev/null +++ b/examples/napitutorials/doc/apiguide/date.md @@ -0,0 +1,68 @@ +# Date + +`Napi::Date` class is a representation of the JavaScript `Date` object. The +`Napi::Date` class inherits its behavior from the `Napi::Value` class +(for more info see [`Napi::Value`](value.md)). + +## Methods + +### Constructor + +Creates a new _empty_ instance of a `Napi::Date` object. + +```cpp +Napi::Date::Date(); +``` + +Creates a new _non-empty_ instance of a `Napi::Date` object. + +```cpp +Napi::Date::Date(napi_env env, napi_value value); +``` + + - `[in] env`: The environment in which to construct the `Napi::Date` object. + - `[in] value`: The `napi_value` which is a handle for a JavaScript `Date`. + +### New + +Creates a new instance of a `Napi::Date` object. + +```cpp +static Napi::Date Napi::Date::New(Napi::Env env, double value); +``` + + - `[in] env`: The environment in which to construct the `Napi::Date` object. + - `[in] value`: The time value the JavaScript `Date` will contain represented + as the number of milliseconds since 1 January 1970 00:00:00 UTC. + +Returns a new instance of `Napi::Date` object. + +### ValueOf + +```cpp +double Napi::Date::ValueOf() const; +``` + +Returns the time value as `double` primitive represented as the number of + milliseconds since 1 January 1970 00:00:00 UTC. + +## Operators + +### operator double + +Converts a `Napi::Date` value to a `double` primitive. + +```cpp +Napi::Date::operator double() const; +``` + +### Example + +The following shows an example of casting a `Napi::Date` value to a `double` + primitive. + +```cpp +double operatorVal = Napi::Date::New(Env(), 0); // Napi::Date to double +// or +auto instanceVal = info[0].As().ValueOf(); +``` diff --git a/examples/napitutorials/doc/apiguide/env.md b/examples/napitutorials/doc/apiguide/env.md new file mode 100644 index 0000000000000000000000000000000000000000..29aa4459e77f29148c31496d70ab1ec61dfc1198 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/env.md @@ -0,0 +1,207 @@ +# Env + +The opaque data structure containing the environment in which the request is being run. + +The Env object is usually created and passed by the Node.js runtime or node-addon-api infrastructure. + +## Methods + +### Constructor + +```cpp +Napi::Env::Env(napi_env env); +``` + +- `[in] env`: The `napi_env` environment from which to construct the `Napi::Env` object. + +### napi_env + +```cpp +operator napi_env() const; +``` + +Returns the `napi_env` opaque data structure representing the environment. + +### Global + +```cpp +Napi::Object Napi::Env::Global() const; +``` + +Returns the `Napi::Object` representing the environment's JavaScript Global Object. + +### Undefined + +```cpp +Napi::Value Napi::Env::Undefined() const; +``` + +Returns the `Napi::Value` representing the environment's JavaScript Undefined Object. + +### Null + +```cpp +Napi::Value Napi::Env::Null() const; +``` + +Returns the `Napi::Value` representing the environment's JavaScript Null Object. + +### IsExceptionPending + +```cpp +bool Napi::Env::IsExceptionPending() const; +``` + +Returns a `bool` indicating if an exception is pending in the environment. + +### GetAndClearPendingException + +```cpp +Napi::Error Napi::Env::GetAndClearPendingException() const; +``` + +Returns an `Napi::Error` object representing the environment's pending exception, if any. + +### RunScript + +```cpp +Napi::Value Napi::Env::RunScript(____ script) const; +``` +- `[in] script`: A string containing JavaScript code to execute. + +Runs JavaScript code contained in a string and returns its result. + +The `script` can be any of the following types: +- [`Napi::String`](string.md) +- `const char *` +- `const std::string &` + +### GetInstanceData +```cpp +template T* GetInstanceData() const; +``` + +Returns the instance data that was previously associated with the environment, +or `nullptr` if none was associated. + +### SetInstanceData + +```cpp +template using Finalizer = void (*)(Env, T*); +template fini = Env::DefaultFini> +void SetInstanceData(T* data) const; +``` + +- `[template] fini`: A function to call when the instance data is to be deleted. +Accepts a function of the form `void CleanupData(Napi::Env env, T* data)`. If +not given, the default finalizer will be used, which simply uses the `delete` +operator to destroy `T*` when the addon instance is unloaded. +- `[in] data`: A pointer to data that will be associated with the instance of +the addon for the duration of its lifecycle. + +Associates a data item stored at `T* data` with the current instance of the +addon. The item will be passed to the function `fini` which gets called when an +instance of the addon is unloaded. + +### SetInstanceData + +```cpp +template +using FinalizerWithHint = void (*)(Env, DataType*, HintType*); +template fini = + Env::DefaultFiniWithHint> +void SetInstanceData(DataType* data, HintType* hint) const; +``` + +- `[template] fini`: A function to call when the instance data is to be deleted. +Accepts a function of the form +`void CleanupData(Napi::Env env, DataType* data, HintType* hint)`. If not given, +the default finalizer will be used, which simply uses the `delete` operator to +destroy `T*` when the addon instance is unloaded. +- `[in] data`: A pointer to data that will be associated with the instance of +the addon for the duration of its lifecycle. +- `[in] hint`: A pointer to data that will be associated with the instance of +the addon for the duration of its lifecycle and will be passed as a hint to +`fini` when the addon instance is unloaded. + +Associates a data item stored at `T* data` with the current instance of the +addon. The item will be passed to the function `fini` which gets called when an +instance of the addon is unloaded. This overload accepts an additional hint to +be passed to `fini`. + +### GetModuleFileName + +```cpp +const char* Napi::Env::GetModuleFileName() const; +``` + +Returns a A URL containing the absolute path of the location from which the +add-on was loaded. For a file on the local file system it will start with +`file://`. The string is null-terminated and owned by env and must thus not be +modified or freed. It is only valid while the add-on is loaded. + +### AddCleanupHook + +```cpp +template +CleanupHook AddCleanupHook(Hook hook); +``` + +- `[in] hook`: A function to call when the environment exits. Accepts a + function of the form `void ()`. + +Registers `hook` as a function to be run once the current Node.js environment +exits. Unlike the underlying C-based Node-API, providing the same `hook` +multiple times **is** allowed. The hooks will be called in reverse order, i.e. +the most recently added one will be called first. + +Returns an `Env::CleanupHook` object, which can be used to remove the hook via +its `Remove()` method. + +### AddCleanupHook + +```cpp +template +CleanupHook AddCleanupHook(Hook hook, Arg* arg); +``` + +- `[in] hook`: A function to call when the environment exits. Accepts a + function of the form `void (Arg* arg)`. +- `[in] arg`: A pointer to data that will be passed as the argument to `hook`. + +Registers `hook` as a function to be run with the `arg` parameter once the +current Node.js environment exits. Unlike the underlying C-based Node-API, +providing the same `hook` and `arg` pair multiple times **is** allowed. The +hooks will be called in reverse order, i.e. the most recently added one will be +called first. + +Returns an `Env::CleanupHook` object, which can be used to remove the hook via +its `Remove()` method. + +# Env::CleanupHook + +The `Env::CleanupHook` object allows removal of the hook added via +`Env::AddCleanupHook()` + +## Methods + +### IsEmpty + +```cpp +bool IsEmpty(); +``` + +Returns `true` if the cleanup hook was **not** successfully registered. + +### Remove + +```cpp +bool Remove(Env env); +``` + +Unregisters the hook from running once the current Node.js environment exits. + +Returns `true` if the hook was successfully removed from the Node.js +environment. diff --git a/examples/napitutorials/doc/apiguide/error.md b/examples/napitutorials/doc/apiguide/error.md new file mode 100644 index 0000000000000000000000000000000000000000..cfa0565c9b275b7d461b0074992803bf430e1645 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/error.md @@ -0,0 +1,120 @@ +# Error + +Class `Napi::Error` inherits from class [`Napi::ObjectReference`][] and class [`std::exception`][]. + +The `Napi::Error` class is a representation of the JavaScript `Error` object that is thrown +when runtime errors occur. The Error object can also be used as a base object for +user-defined exceptions. + +The `Napi::Error` class is a persistent reference to a JavaScript error object thus +inherits its behavior from the `Napi::ObjectReference` class (for more info see: [`Napi::ObjectReference`](object_reference.md)). + +If C++ exceptions are enabled (for more info see: [Setup](setup.md)), then the +`Napi::Error` class extends `std::exception` and enables integrated +error-handling for C++ exceptions and JavaScript exceptions. + +For more details about error handling refer to the section titled [Error handling](error_handling.md). + +## Methods + +### New + +Creates empty instance of an `Napi::Error` object for the specified environment. + +```cpp +Napi::Error::New(Napi::Env env); +``` + +- `[in] env`: The environment in which to construct the `Napi::Error` object. + +Returns an instance of `Napi::Error` object. + +### New + +Creates instance of an `Napi::Error` object. + +```cpp +Napi::Error::New(Napi::Env env, const char* message); +``` + +- `[in] env`: The environment in which to construct the `Napi::Error` object. +- `[in] message`: Null-terminated string to be used as the message for the `Napi::Error`. + +Returns instance of an `Napi::Error` object. + +### New + +Creates instance of an `Napi::Error` object + +```cpp +Napi::Error::New(Napi::Env env, const std::string& message); +``` + +- `[in] env`: The environment in which to construct the `Napi::Error` object. +- `[in] message`: Reference string to be used as the message for the `Napi::Error`. + +Returns instance of an `Napi::Error` object. + +### Fatal + +In case of an unrecoverable error in a native module, a fatal error can be thrown +to immediately terminate the process. + +```cpp +static NAPI_NO_RETURN void Napi::Error::Fatal(const char* location, const char* message); +``` + +The function call does not return, the process will be terminated. + +### Constructor + +Creates empty instance of an `Napi::Error`. + +```cpp +Napi::Error::Error(); +``` + +Returns an instance of `Napi::Error` object. + +### Constructor + +Initializes an `Napi::Error` instance from an existing JavaScript error object. + +```cpp +Napi::Error::Error(napi_env env, napi_value value); +``` + +- `[in] env`: The environment in which to construct the error object. +- `[in] value`: The `Napi::Error` reference to wrap. + +Returns instance of an `Napi::Error` object. + +### Message + +```cpp +std::string& Napi::Error::Message() const NAPI_NOEXCEPT; +``` + +Returns the reference to the string that represent the message of the error. + +### ThrowAsJavaScriptException + +Throw the error as JavaScript exception. + +```cpp +void Napi::Error::ThrowAsJavaScriptException() const; +``` + +Throws the error as a JavaScript exception. + +### what + +```cpp +const char* Napi::Error::what() const NAPI_NOEXCEPT override; +``` + +Returns a pointer to a null-terminated string that is used to identify the +exception. This method can be used only if the exception mechanism is enabled. + +[`Napi::ObjectReference`]: ./object_reference.md +[`std::exception`]: /reference/exception/exception/ diff --git a/examples/napitutorials/doc/apiguide/error_handling.md b/examples/napitutorials/doc/apiguide/error_handling.md new file mode 100644 index 0000000000000000000000000000000000000000..467b5d2e05f9a8c87c55de4de109a272389edbab --- /dev/null +++ b/examples/napitutorials/doc/apiguide/error_handling.md @@ -0,0 +1,254 @@ +# Error handling + +Error handling represents one of the most important considerations when +implementing a Node.js native add-on. When an error occurs in your C++ code you +have to handle and dispatch it correctly. **node-addon-api** uses return values and +JavaScript exceptions for error handling. You can choose return values or +exception handling based on the mechanism that works best for your add-on. + +The `Napi::Error` is a persistent reference (for more info see: [`Napi::ObjectReference`](object_reference.md)) +to a JavaScript error object. Use of this class depends on whether C++ +exceptions are enabled at compile time. + +If C++ exceptions are enabled (for more info see: [Setup](setup.md)), then the +`Napi::Error` class extends `std::exception` and enables integrated +error-handling for C++ exceptions and JavaScript exceptions. + +Note, that due to limitations of the Node-API, if one attempts to cast the error object wrapping a primitive inside a C++ addon, the wrapped object +will be received instead. (With property `4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal` containing the primitive value thrown) + +The following sections explain the approach for each case: + +- [Handling Errors With C++ Exceptions](#exceptions) +- [Handling Errors With Maybe Type and C++ Exceptions Disabled](#noexceptions-maybe) +- [Handling Errors Without C++ Exceptions](#noexceptions) + + + +In most cases when an error occurs, the addon should do whatever cleanup is possible +and then return to JavaScript so that the error can be propagated. In less frequent +cases the addon may be able to recover from the error, clear the error and then +continue. + +## Handling Errors With C++ Exceptions + +When C++ exceptions are enabled try/catch can be used to catch exceptions thrown +from calls to JavaScript and then they can either be handled or rethrown before +returning from a native method. + +If a node-addon-api call fails without executing any JavaScript code (for example due to +an invalid argument), then node-addon-api automatically converts and throws +the error as a C++ exception of type `Napi::Error`. + +If a JavaScript function called by C++ code via node-addon-api throws a JavaScript +exception, then node-addon-api automatically converts and throws it as a C++ +exception of type `Napi::Error` on return from the JavaScript code to the native +method. + +If a C++ exception of type `Napi::Error` escapes from a Node-API C++ callback, then +the Node-API wrapper automatically converts and throws it as a JavaScript exception. + +On return from a native method, node-addon-api will automatically convert a pending +`Napi::Error` C++ exception to a JavaScript exception. + +When C++ exceptions are enabled try/catch can be used to catch exceptions thrown +from calls to JavaScript and then they can either be handled or rethrown before +returning from a native method. + +## Examples with C++ exceptions enabled + +### Throwing a C++ exception + +```cpp +Env env = ... +throw Napi::Error::New(env, "Example exception"); +// other C++ statements +// ... +``` + +The statements following the throw statement will not be executed. The exception +will bubble up as a C++ exception of type `Napi::Error`, until it is either caught +while still in C++, or else automatically propagated as a JavaScript exception +when returning to JavaScript. + +### Propagating a Node-API C++ exception + +```cpp +Napi::Function jsFunctionThatThrows = someValue.As(); +Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +// other C++ statements +// ... +``` + +The C++ statements following the call to the JavaScript function will not be +executed. The exception will bubble up as a C++ exception of type `Napi::Error`, +until it is either caught while still in C++, or else automatically propagated as +a JavaScript exception when returning to JavaScript. + +### Handling a Node-API C++ exception + +```cpp +Napi::Function jsFunctionThatThrows = someValue.As(); +Napi::Value result; +try { + result = jsFunctionThatThrows({ arg1, arg2 }); +} catch (const Error& e) { + cerr << "Caught JavaScript exception: " + e.what(); +} +``` + +Since the exception was caught here, it will not be propagated as a JavaScript +exception. + + + +## Handling Errors With Maybe Type and C++ Exceptions Disabled + +If C++ exceptions are disabled (for more info see: [Setup](setup.md)), then the +`Napi::Error` class does not extend `std::exception`. This means that any calls to +node-addon-api functions do not throw a C++ exceptions. Instead, these node-api +functions that call into JavaScript are returning with `Maybe` boxed values. +In that case, the calling side should convert the `Maybe` boxed values with +checks to ensure that the call did succeed and therefore no exception is pending. +If the check fails, that is to say, the returning value is _empty_, the calling +side should determine what to do with `env.GetAndClearPendingException()` before +attempting to call another node-api (for more info see: [Env](env.md)). + +The conversion from the `Maybe` boxed value to the actual return value is +enforced by compilers so that the exceptions must be properly handled before +continuing. + +## Examples with Maybe Type and C++ exceptions disabled + +### Throwing a JS exception + +```cpp +Napi::Env env = ... +Napi::Error::New(env, "Example exception").ThrowAsJavaScriptException(); +return; +``` + +After throwing a JavaScript exception, the code should generally return +immediately from the native callback, after performing any necessary cleanup. + +### Propagating a Node-API JS exception + +```cpp +Napi::Env env = ... +Napi::Function jsFunctionThatThrows = someValue.As(); +Maybe maybeResult = jsFunctionThatThrows({ arg1, arg2 }); +Napi::Value result; +if (!maybeResult.To(&result)) { + // The Maybe is empty, calling into js failed, cleaning up... + // It is recommended to return an empty Maybe if the procedure failed. + return result; +} +``` + +If `maybeResult.To(&result)` returns false a JavaScript exception is pending. +To let the exception propagate, the code should generally return immediately +from the native callback, after performing any necessary cleanup. + +### Handling a Node-API JS exception + +```cpp +Napi::Env env = ... +Napi::Function jsFunctionThatThrows = someValue.As(); +Maybe maybeResult = jsFunctionThatThrows({ arg1, arg2 }); +if (maybeResult.IsNothing()) { + Napi::Error e = env.GetAndClearPendingException(); + cerr << "Caught JavaScript exception: " + e.Message(); +} +``` + +Since the exception was cleared here, it will not be propagated as a JavaScript +exception after the native callback returns. + + + +## Handling Errors Without C++ Exceptions + +If C++ exceptions are disabled (for more info see: [Setup](setup.md)), then the +`Napi::Error` class does not extend `std::exception`. This means that any calls to +node-addon-api function do not throw a C++ exceptions. Instead, it raises +_pending_ JavaScript exceptions and returns an _empty_ `Napi::Value`. +The calling code should check `env.IsExceptionPending()` before attempting to use a +returned value, and may use methods on the `Napi::Env` class +to check for, get, and clear a pending JavaScript exception (for more info see: [Env](env.md)). +If the pending exception is not cleared, it will be thrown when the native code +returns to JavaScript. + +## Examples with C++ exceptions disabled + +### Throwing a JS exception + +```cpp +Napi::Env env = ... +Napi::Error::New(env, "Example exception").ThrowAsJavaScriptException(); +return; +``` + +After throwing a JavaScript exception, the code should generally return +immediately from the native callback, after performing any necessary cleanup. + +### Propagating a Node-API JS exception + +```cpp +Napi::Env env = ... +Napi::Function jsFunctionThatThrows = someValue.As(); +Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +if (env.IsExceptionPending()) { + Error e = env.GetAndClearPendingException(); + return e.Value(); +} +``` + +If env.IsExceptionPending() returns true a JavaScript exception is pending. To +let the exception propagate, the code should generally return immediately from +the native callback, after performing any necessary cleanup. + +### Handling a Node-API JS exception + +```cpp +Napi::Env env = ... +Napi::Function jsFunctionThatThrows = someValue.As(); +Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +if (env.IsExceptionPending()) { + Napi::Error e = env.GetAndClearPendingException(); + cerr << "Caught JavaScript exception: " + e.Message(); +} +``` + +Since the exception was cleared here, it will not be propagated as a JavaScript +exception after the native callback returns. + +## Calling Node-API directly from a **node-addon-api** addon + +**node-addon-api** provides macros for throwing errors in response to non-OK +`napi_status` results when calling [Node-API](/docs/latest/api/n-api.html) +functions from within a native addon. These macros are defined differently +depending on whether C++ exceptions are enabled or not, but are available for +use in either case. + +### `NAPI_THROW(e, ...)` + +This macro accepts a `Napi::Error`, throws it, and returns the value given as +the last parameter. If C++ exceptions are enabled (by defining +`NAPI_CPP_EXCEPTIONS` during the build), the return value will be ignored. + +### `NAPI_THROW_IF_FAILED(env, status, ...)` + +This macro accepts a `Napi::Env` and a `napi_status`. It constructs an error +from the `napi_status`, throws it, and returns the value given as the last +parameter. If C++ exceptions are enabled (by defining `NAPI_CPP_EXCEPTIONS` +during the build), the return value will be ignored. + +### `NAPI_THROW_IF_FAILED_VOID(env, status)` + +This macro accepts a `Napi::Env` and a `napi_status`. It constructs an error +from the `napi_status`, throws it, and returns. + +### `NAPI_FATAL_IF_FAILED(status, location, message)` + +This macro accepts a `napi_status`, a C string indicating the location where the +error occurred, and a second C string for the message to display. diff --git a/examples/napitutorials/doc/apiguide/escapable_handle_scope.md b/examples/napitutorials/doc/apiguide/escapable_handle_scope.md new file mode 100644 index 0000000000000000000000000000000000000000..faf4b5b475add4c59e3e73af5c1d0071b4f8fb5b --- /dev/null +++ b/examples/napitutorials/doc/apiguide/escapable_handle_scope.md @@ -0,0 +1,80 @@ +# EscapableHandleScope + +The `Napi::EscapableHandleScope` class is used to manage the lifetime of object handles +which are created through the use of node-addon-api. These handles +keep an object alive in the heap in order to ensure that the objects +are not collected by the garbage collector while native code is using them. +A handle may be created when any new node-addon-api Value or one +of its subclasses is created or returned. + +The `Napi::EscapableHandleScope` is a special type of `Napi::HandleScope` +which allows a single handle to be "promoted" to an outer scope. + +For more details refer to the section titled +[Object lifetime management](object_lifetime_management.md). + +## Methods + +### Constructor + +Creates a new escapable handle scope. + +```cpp +Napi::EscapableHandleScope Napi::EscapableHandleScope::New(Napi::Env env); +``` + +- `[in] Env`: The environment in which to construct the `Napi::EscapableHandleScope` object. + +Returns a new `Napi::EscapableHandleScope` + +### Constructor + +Creates a new escapable handle scope. + +```cpp +Napi::EscapableHandleScope Napi::EscapableHandleScope::New(napi_env env, napi_handle_scope scope); +``` + +- `[in] env`: `napi_env` in which the scope passed in was created. +- `[in] scope`: pre-existing `napi_handle_scope`. + +Returns a new `Napi::EscapableHandleScope` instance which wraps the +`napi_escapable_handle_scope` handle passed in. This can be used +to mix usage of the C Node-API and node-addon-api. + +```cpp +operator Napi::EscapableHandleScope::napi_escapable_handle_scope() const +``` + +Returns the Node-API `napi_escapable_handle_scope` wrapped by the `Napi::EscapableHandleScope` object. +This can be used to mix usage of the C Node-API and node-addon-api by allowing +the class to be used be converted to a `napi_escapable_handle_scope`. + +### Destructor +```cpp +Napi::EscapableHandleScope::~EscapableHandleScope(); +``` + +Deletes the `Napi::EscapableHandleScope` instance and allows any objects/handles created +in the scope to be collected by the garbage collector. There is no +guarantee as to when the garbage collector will do this. + +### Escape + +```cpp +napi::Value Napi::EscapableHandleScope::Escape(napi_value escapee); +``` + +- `[in] escapee`: `Napi::Value` or `napi_env` to promote to the outer scope + +Returns `Napi::Value` which can be used in the outer scope. This method can +be called at most once on a given `Napi::EscapableHandleScope`. If it is called +more than once an exception will be thrown. + +### Env + +```cpp +Napi::Env Napi::EscapableHandleScope::Env() const; +``` + +Returns the `Napi::Env` associated with the `Napi::EscapableHandleScope`. diff --git a/examples/napitutorials/doc/apiguide/external.md b/examples/napitutorials/doc/apiguide/external.md new file mode 100644 index 0000000000000000000000000000000000000000..ce42e112a0ea0d0f285b4c893ebedfc8e5bf11d5 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/external.md @@ -0,0 +1,70 @@ +# External (template) + +Class `Napi::External` inherits from class [`Napi::TypeTaggable`][]. + +The `Napi::External` template class implements the ability to create a `Napi::Value` object with arbitrary C++ data. It is the user's responsibility to manage the memory for the arbitrary C++ data. + +`Napi::External` objects can be created with an optional Finalizer function and optional Hint value. The Finalizer function, if specified, is called when your `Napi::External` object is released by Node's garbage collector. It gives your code the opportunity to free any dynamically created data. If you specify a Hint value, it is passed to your Finalizer function. + +Note that `Napi::Value::IsExternal()` will return `true` for any external value. +It does not differentiate between the templated parameter `T` in +`Napi::External`. It is up to the addon to ensure an `Napi::External` +object holds the correct `T` when retrieving the data via +`Napi::External::Data()`. One method to ensure an object is of a specific +type is through [type tags](./object.md#TypeTag). + +## Methods + +### New + +```cpp +template +static Napi::External Napi::External::New(napi_env env, T* data); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::External` object. +- `[in] data`: The arbitrary C++ data to be held by the `Napi::External` object. + +Returns the created `Napi::External` object. + +### New + +```cpp +template +static Napi::External Napi::External::New(napi_env env, + T* data, + Finalizer finalizeCallback); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::External` object. +- `[in] data`: The arbitrary C++ data to be held by the `Napi::External` object. +- `[in] finalizeCallback`: A function called when the `Napi::External` object is released by the garbage collector accepting a T* and returning void. + +Returns the created `Napi::External` object. + +### New + +```cpp +template +static Napi::External Napi::External::New(napi_env env, + T* data, + Finalizer finalizeCallback, + Hint* finalizeHint); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::External` object. +- `[in] data`: The arbitrary C++ data to be held by the `Napi::External` object. +- `[in] finalizeCallback`: A function called when the `Napi::External` object is released by the garbage collector accepting T* and Hint* parameters and returning void. +- `[in] finalizeHint`: A hint value passed to the `finalizeCallback` function. + +Returns the created `Napi::External` object. + +### Data + +```cpp +T* Napi::External::Data() const; +``` + +Returns a pointer to the arbitrary C++ data held by the `Napi::External` object. + +[`Napi::TypeTaggable`]: ./type_taggable.md diff --git a/examples/napitutorials/doc/apiguide/external_buffer.md b/examples/napitutorials/doc/apiguide/external_buffer.md new file mode 100644 index 0000000000000000000000000000000000000000..aa87bb78b53682fcc8b50bbb80e0142ee33b28a0 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/external_buffer.md @@ -0,0 +1,18 @@ +# External Buffer + +**Some runtimes other than Node.js have dropped support for external buffers**. +On runtimes other than Node.js, node-api methods may return +`napi_no_external_buffers_allowed` to indicate that external +buffers are not supported. One such runtime is Electron as +described in this issue +[electron/issues/35801](electron/electron/issues/35801). + +In order to maintain broadest compatibility with all runtimes, +you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before +includes for the node-api and node-addon-api headers. Doing so will hide the +functions that create external buffers. This will ensure a compilation error +occurs if you accidentally use one of these methods. + +In node-addon-api, the `Napi::Buffer::NewOrCopy` provides a convenient way to +create an external buffer, or allocate a new buffer and copy the data when the +external buffer is not supported. diff --git a/examples/napitutorials/doc/apiguide/function.md b/examples/napitutorials/doc/apiguide/function.md new file mode 100644 index 0000000000000000000000000000000000000000..2b1cbfda7f67412bb99493808a6ce7013d1a6d18 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/function.md @@ -0,0 +1,402 @@ +# Function + +The `Napi::Function` class provides a set of methods for creating a function object in +native code that can later be called from JavaScript. The created function is not +automatically visible from JavaScript. Instead it needs to be part of the add-on's +module exports or be returned by one of the module's exported functions. + +In addition the `Napi::Function` class also provides methods that can be used to call +functions that were created in JavaScript and passed to the native add-on. + +The `Napi::Function` class inherits its behavior from the `Napi::Object` class (for more info +see: [`Napi::Object`](object.md)). + +> For callbacks that will be called with asynchronous events from a +> non-JavaScript thread, please refer to [`Napi::ThreadSafeFunction`][] for more +> examples. + +## Example + +```cpp +#include + +using namespace Napi; + +Value Fn(const CallbackInfo& info) { + Env env = info.Env(); + // ... + return String::New(env, "Hello World"); +} + +Object Init(Env env, Object exports) { + exports.Set(String::New(env, "fn"), Function::New(env)); + return exports; +} + +NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) +``` + +The above code can be used from JavaScript as follows: + +```js +const addon = require('./addon'); +addon.fn(); +``` + +With the `Napi::Function` class it is possible to call a JavaScript function object +from a native add-on with two different methods: `Call` and `MakeCallback`. +The API of these two methods is very similar, but they are used in different +contexts. The `MakeCallback` method is used to call from native code back into +JavaScript after returning from an [asynchronous operation](async_operations.md) +and in general in situations which don't have an existing JavaScript function on +the stack. The `Call` method is used when there is already a JavaScript function +on the stack (for example when running a native method called from JavaScript). + +## Type definitions + +### Napi::Function::VoidCallback + +This is the type describing a callback returning `void` that will be invoked +from JavaScript. + +```cpp +using VoidCallback = void (*)(const Napi::CallbackInfo& info); +``` + +### Napi::Function::Callback + +This is the type describing a callback returning a value that will be invoked +from JavaScript. + + +```cpp +using Callback = Value (*)(const Napi::CallbackInfo& info); +``` + +## Methods + +### Constructor + +Creates a new empty instance of `Napi::Function`. + +```cpp +Napi::Function::Function(); +``` + +### Constructor + +Creates a new instance of the `Napi::Function` object. + +```cpp +Napi::Function::Function(napi_env env, napi_value value); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] value`: The `napi_value` which is a handle for a JavaScript function. + +Returns a non-empty `Napi::Function` instance. + +### New + +Creates an instance of a `Napi::Function` object. + +```cpp +template +static Napi::Function New(napi_env env, + const char* utf8name = nullptr, + void* data = nullptr); +``` + +- `[template] cb`: The native function to invoke when the JavaScript function is +invoked. +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] utf8name`: Null-terminated string to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +Creates an instance of a `Napi::Function` object. + +```cpp +template +static Napi::Function New(napi_env env, + const char* utf8name = nullptr, + void* data = nullptr); +``` + +- `[template] cb`: The native function to invoke when the JavaScript function is +invoked. +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] utf8name`: Null-terminated string to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +Creates an instance of a `Napi::Function` object. + +```cpp +template +static Napi::Function New(napi_env env, + const std::string& utf8name, + void* data = nullptr); +``` + +- `[template] cb`: The native function to invoke when the JavaScript function is +invoked. +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] utf8name`: String to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +Creates an instance of a `Napi::Function` object. + +```cpp +template +static Napi::Function New(napi_env env, + const std::string& utf8name, + void* data = nullptr); +``` + +- `[template] cb`: The native function to invoke when the JavaScript function is +invoked. +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] utf8name`: String to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +Creates an instance of a `Napi::Function` object. + +```cpp +template +static Napi::Function Napi::Function::New(napi_env env, Callable cb, const char* utf8name = nullptr, void* data = nullptr); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] cb`: Object that implements `Callable`. +- `[in] utf8name`: Null-terminated string to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +```cpp +template +static Napi::Function Napi::Function::New(napi_env env, Callable cb, const std::string& utf8name, void* data = nullptr); +``` + +- `[in] env`: The `napi_env` environment in which to construct the `Napi::Function` object. +- `[in] cb`: Object that implements `Callable`. +- `[in] utf8name`: String to be used as the name of the function. +- `[in] data`: User-provided data context. This will be passed back into the +function when invoked later. + +Returns an instance of a `Napi::Function` object. + +### New + +Creates a new JavaScript value from one that represents the constructor for the +object. + +```cpp +Napi::Object Napi::Function::New(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the constructor function. + +Returns a new JavaScript object. + +### New + +Creates a new JavaScript value from one that represents the constructor for the +object. + +```cpp +Napi::Object Napi::Function::New(const std::vector& args) const; +``` + +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the constructor function. + +Returns a new JavaScript object. + +### New + +Creates a new JavaScript value from one that represents the constructor for the +object. + +```cpp +Napi::Object Napi::Function::New(size_t argc, const napi_value* args) const; +``` + +- `[in] argc`: The number of the arguments passed to the constructor function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the constructor function. + +Returns a new JavaScript object. + +### Call + +Calls a Javascript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### Call + +Calls a JavaScript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(const std::vector& args) const; +``` + +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### Call + +Calls a Javascript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(size_t argc, const napi_value* args) const; +``` + +- `[in] argc`: The number of the arguments passed to the function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### Call + +Calls a Javascript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(napi_value recv, const std::initializer_list& args) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### Call + +Calls a Javascript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(napi_value recv, const std::vector& args) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### Call + +Calls a Javascript function from a native add-on. + +```cpp +Napi::Value Napi::Function::Call(napi_value recv, size_t argc, const napi_value* args) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] argc`: The number of the arguments passed to the function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the function. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### MakeCallback + +Calls a Javascript function from a native add-on after an asynchronous operation. + +```cpp +Napi::Value Napi::Function::MakeCallback(napi_value recv, const std::initializer_list& args, napi_async_context context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### MakeCallback + +Calls a Javascript function from a native add-on after an asynchronous operation. + +```cpp +Napi::Value Napi::Function::MakeCallback(napi_value recv, const std::vector& args, napi_async_context context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] args`: List of JavaScript values as `napi_value` representing the +arguments of the function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +### MakeCallback + +Calls a Javascript function from a native add-on after an asynchronous operation. + +```cpp +Napi::Value Napi::Function::MakeCallback(napi_value recv, size_t argc, const napi_value* args, napi_async_context context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the called function. +- `[in] argc`: The number of the arguments passed to the function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +## Operator + +```cpp +Napi::Value Napi::Function::operator ()(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of JavaScript values as `napi_value`. + +Returns a `Napi::Value` representing the JavaScript value returned by the function. + +[`Napi::ThreadSafeFunction`]: ./threadsafe_function.md diff --git a/examples/napitutorials/doc/apiguide/function_reference.md b/examples/napitutorials/doc/apiguide/function_reference.md new file mode 100644 index 0000000000000000000000000000000000000000..07afc643b2274faf6935d6dd9bbd8015ae1ba008 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/function_reference.md @@ -0,0 +1,238 @@ +# FunctionReference + +`Napi::FunctionReference` is a subclass of [`Napi::Reference`](reference.md), and +is equivalent to an instance of `Napi::Reference`. This means +that a `Napi::FunctionReference` holds a [`Napi::Function`](function.md), and a +count of the number of references to that `Napi::Function`. When the count is +greater than 0, a `Napi::FunctionReference` is not eligible for garbage collection. +This ensures that the `Function` will remain accessible, even if the original +reference to it is no longer available. +`Napi::FunctionReference` allows the referenced JavaScript function object to be +called from a native add-on with two different methods: `Call` and `MakeCallback`. +See the documentation for [`Napi::Function`](function.md) for when `Call` should +be used instead of `MakeCallback` and vice-versa. + +The `Napi::FunctionReference` class inherits its behavior from the `Napi::Reference` +class (for more info see: [`Napi::Reference`](reference.md)). + +## Methods + +### Weak + +Creates a "weak" reference to the value, in that the initial reference count is +set to 0. + +```cpp +static Napi::FunctionReference Napi::Weak(const Napi::Function& value); +``` + +- `[in] value`: The value which is to be referenced. + +Returns the newly created reference. + +### Persistent + +Creates a "persistent" reference to the value, in that the initial reference +count is set to 1. + +```cpp +static Napi::FunctionReference Napi::Persistent(const Napi::Function& value); +``` + +- `[in] value`: The value which is to be referenced. + +Returns the newly created reference. + +### Constructor + +Creates a new empty instance of `Napi::FunctionReference`. + +```cpp +Napi::FunctionReference::FunctionReference(); +``` + +### Constructor + +Creates a new instance of the `Napi::FunctionReference`. + +```cpp +Napi::FunctionReference::FunctionReference(napi_env env, napi_ref ref); +``` + +- `[in] env`: The environment in which to construct the `Napi::FunctionReference` object. +- `[in] ref`: The Node-API reference to be held by the `Napi::FunctionReference`. + +Returns a newly created `Napi::FunctionReference` object. + +### New + +Constructs a new instance by calling the constructor held by this reference. + +```cpp +Napi::Object Napi::FunctionReference::New(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the constructor function. + +Returns a new JavaScript object. + +### New + +Constructs a new instance by calling the constructor held by this reference. + +```cpp +Napi::Object Napi::FunctionReference::New(const std::vector& args) const; +``` + +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the constructor function. + +Returns a new JavaScript object. + +### Call + +Calls a referenced Javascript function from a native add-on. + +```cpp +Napi::Value Napi::FunctionReference::Call(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the referenced function. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### Call + +Calls a referenced JavaScript function from a native add-on. + +```cpp +Napi::Value Napi::FunctionReference::Call(const std::vector& args) const; +``` + +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the referenced function. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### Call + +Calls a referenced JavaScript function from a native add-on. + +```cpp +Napi::Value Napi::FunctionReference::Call(napi_value recv, const std::initializer_list& args) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the referenced function. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### Call + +Calls a referenced JavaScript function from a native add-on. + +```cpp +Napi::Value Napi::FunctionReference::Call(napi_value recv, const std::vector& args) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the referenced function. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### Call + +Calls a referenced JavaScript function from a native add-on. + +```cpp +Napi::Value Napi::FunctionReference::Call(napi_value recv, size_t argc, const napi_value* args) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] argc`: The number of arguments passed to the referenced function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the referenced function. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + + +### MakeCallback + +Calls a referenced JavaScript function from a native add-on after an asynchronous +operation. + +```cpp +Napi::Value Napi::FunctionReference::MakeCallback(napi_value recv, const std::initializer_list& args, napi_async_context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] args`: Initializer list of JavaScript values as `napi_value` representing +the arguments of the referenced function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### MakeCallback + +Calls a referenced JavaScript function from a native add-on after an asynchronous +operation. + +```cpp +Napi::Value Napi::FunctionReference::MakeCallback(napi_value recv, const std::vector& args, napi_async_context context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] args`: Vector of JavaScript values as `napi_value` representing the +arguments of the referenced function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +### MakeCallback + +Calls a referenced JavaScript function from a native add-on after an asynchronous +operation. + +```cpp +Napi::Value Napi::FunctionReference::MakeCallback(napi_value recv, size_t argc, const napi_value* args, napi_async_context context = nullptr) const; +``` + +- `[in] recv`: The `this` object passed to the referenced function when it's called. +- `[in] argc`: The number of arguments passed to the referenced function. +- `[in] args`: Array of JavaScript values as `napi_value` representing the +arguments of the referenced function. +- `[in] context`: Context for the async operation that is invoking the callback. +This should normally be a value previously obtained from [Napi::AsyncContext](async_context.md). +However `nullptr` is also allowed, which indicates the current async context +(if any) is to be used for the callback. + +Returns a `Napi::Value` representing the JavaScript object returned by the referenced +function. + +## Operator + +```cpp +Napi::Value operator ()(const std::initializer_list& args) const; +``` + +- `[in] args`: Initializer list of reference to JavaScript values as `napi_value` + +Returns a `Napi::Value` representing the JavaScript value returned by the referenced +function. diff --git a/examples/napitutorials/doc/apiguide/generator.md b/examples/napitutorials/doc/apiguide/generator.md new file mode 100644 index 0000000000000000000000000000000000000000..36595f109c41500c5e5aeb520d5b81e3d7c90cac --- /dev/null +++ b/examples/napitutorials/doc/apiguide/generator.md @@ -0,0 +1,13 @@ +# Generator + +## What is generator + +**[generator-napi-module](/package/generator-napi-module)** is a module to quickly generate a skeleton module using +**Node-API**, the new API for Native addons. This module automatically sets up your +**gyp file** to use **node-addon-api**, the C++ wrappers for Node-API and generates +a wrapper JS module. Optionally, it can even configure the generated project to +use **TypeScript** instead. + +## **generator-napi-module** reference + + - [Installation and usage](/package/generator-napi-module#installation) diff --git a/examples/napitutorials/doc/apiguide/handle_scope.md b/examples/napitutorials/doc/apiguide/handle_scope.md new file mode 100644 index 0000000000000000000000000000000000000000..212344604c3dd4106d359d2012ec0af77af477e7 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/handle_scope.md @@ -0,0 +1,77 @@ +# HandleScope + +The HandleScope class is used to manage the lifetime of object handles +which are created through the use of node-addon-api. These handles +keep an object alive in the heap in order to ensure that the objects +are not collected while native code is using them. +A handle may be created when any new node-addon-api Value or one +of its subclasses is created or returned. For more details refer to +the section titled [Object lifetime management](object_lifetime_management.md). + +## Methods + +### Constructor + +Creates a new handle scope on the stack. + +```cpp +Napi::HandleScope::HandleScope(Napi::Env env); +``` + +- `[in] env`: The environment in which to construct the `Napi::HandleScope` object. + +Returns a new `Napi::HandleScope` + +### Constructor + +Creates a new handle scope on the stack. + +```cpp +Napi::HandleScope::HandleScope(Napi::Env env, Napi::HandleScope scope); +``` + +- `[in] env`: `Napi::Env` in which the scope passed in was created. +- `[in] scope`: pre-existing `Napi::HandleScope`. + +Returns a new `Napi::HandleScope` instance which wraps the `napi_handle_scope` +handle passed in. This can be used to mix usage of the C Node-API +and node-addon-api. + +```cpp +operator Napi::HandleScope::napi_handle_scope() const +``` + +Returns the Node-API `napi_handle_scope` wrapped by the `Napi::EscapableHandleScope` object. +This can be used to mix usage of the C Node-API and node-addon-api by allowing +the class to be used be converted to a `napi_handle_scope`. + +### Destructor +```cpp +Napi::HandleScope::~HandleScope(); +``` + +Deletes the `Napi::HandleScope` instance and allows any objects/handles created +in the scope to be collected by the garbage collector. There is no +guarantee as to when the garbage collector will do this. + +### Env + +```cpp +Napi::Env Napi::HandleScope::Env() const; +``` + +Returns the `Napi::Env` associated with the `Napi::HandleScope`. + +## Example + +```cpp +for (int i = 0; i < LOOP_MAX; i++) { + Napi::HandleScope scope(info.Env()); + std::string name = std::string("inner-scope") + std::to_string(i); + Napi::Value newValue = Napi::String::New(info.Env(), name.c_str()); + // do something with newValue +}; +``` + +For more details refer to the section titled [Object lifetime +management](object_lifetime_management.md). diff --git a/examples/napitutorials/doc/apiguide/hierarchy.md b/examples/napitutorials/doc/apiguide/hierarchy.md new file mode 100644 index 0000000000000000000000000000000000000000..14fc08352d4527aaca537fbc056a0524675d2716 --- /dev/null +++ b/examples/napitutorials/doc/apiguide/hierarchy.md @@ -0,0 +1,95 @@ +# Full Class Hierarchy + +| Class | Parent Class(es) | +|---|---| +| [`Napi::Addon`][] | [`Napi::InstanceWrap`][] | +| [`Napi::Array`][] | [`Napi::Object`][] | +| [`Napi::ArrayBuffer`][] | [`Napi::Object`][] | +| [`Napi::AsyncContext`][] | | +| [`Napi::AsyncProgressQueueWorker`][] | `Napi::AsyncProgressWorkerBase` | +| [`Napi::AsyncProgressWorker`][] | `Napi::AsyncProgressWorkerBase` | +| [`Napi::AsyncWorker`][] | | +| [`Napi::BigInt`][] | [`Napi::Value`][] | +| [`Napi::Boolean`][] | [`Napi::Value`][] | +| [`Napi::Buffer`][] | [`Napi::Uint8Array`][] | +| [`Napi::CallbackInfo`][] | | +| [`Napi::CallbackScope`][] | | +| [`Napi::ClassPropertyDescriptor`][] | | +| [`Napi::DataView`][] | [`Napi::Object`][] | +| [`Napi::Date`][] | [`Napi::Value`][] | +| [`Napi::Env`][] | | +| [`Napi::Error`][] | [`Napi::ObjectReference`][], [`std::exception`][] | +| [`Napi::EscapableHandleScope`][] | | +| [`Napi::External`][] | [`Napi::TypeTaggable`][] | +| [`Napi::Function`][] | [`Napi::Object`][] | +| [`Napi::FunctionReference`][] | [`Napi::Reference`][] | +| [`Napi::HandleScope`][] | | +| [`Napi::InstanceWrap`][] | | +| [`Napi::MemoryManagement`][] | | +| [`Napi::Name`][] | [`Napi::Value`][] | +| [`Napi::Number`][] | [`Napi::Value`][] | +| [`Napi::Object`][] | [`Napi::TypeTaggable`][] | +| [`Napi::ObjectReference`][] | [`Napi::Reference`][] | +| [`Napi::ObjectWrap`][] | [`Napi::InstanceWrap`][], [`Napi::Reference`][] | +| [`Napi::Promise`][] | [`Napi::Object`][] | +| [`Napi::PropertyDescriptor`][] | | +| [`Napi::RangeError`][] | [`Napi::Error`][] | +| [`Napi::Reference`] | | +| [`Napi::String`][] | [`Napi::Name`][] | +| [`Napi::Symbol`][] | [`Napi::Name`][] | +| [`Napi::SyntaxError`][] | [`Napi::Error`][] | +| [`Napi::ThreadSafeFunction`][] | | +| [`Napi::TypeTaggable`][] | [`Napi::Value][] | +| [`Napi::TypeError`][] | [`Napi::Error`][] | +| [`Napi::TypedArray`][] | [`Napi::Object`][] | +| [`Napi::TypedArrayOf`][] | [`Napi::TypedArray`][] | +| [`Napi::Value`][] | | +| [`Napi::VersionManagement`][] | | + +[`Napi::Addon`]: ./addon.md +[`Napi::Array`]: ./array.md +[`Napi::ArrayBuffer`]: ./array_buffer.md +[`Napi::AsyncContext`]: ./async_context.md +[`Napi::AsyncProgressQueueWorker`]: ./async_worker_variants.md#asyncprogressqueueworker +[`Napi::AsyncProgressWorker`]: ./async_worker_variants.md#asyncprogressworker +[`Napi::AsyncWorker`]: ./async_worker.md +[`Napi::BigInt`]: ./bigint.md +[`Napi::Boolean`]: ./boolean.md +[`Napi::Buffer`]: ./buffer.md +[`Napi::CallbackInfo`]: ./callbackinfo.md +[`Napi::CallbackScope`]: ./callback_scope.md +[`Napi::ClassPropertyDescriptor`]: ./class_property_descriptor.md +[`Napi::DataView`]: ./dataview.md +[`Napi::Date`]: ./date.md +[`Napi::Env`]: ./env.md +[`Napi::Error`]: ./error.md +[`Napi::EscapableHandleScope`]: ./escapable_handle_scope.md +[`Napi::External`]: ./external.md +[`Napi::Function`]: ./function.md +[`Napi::FunctionReference`]: ./function_reference.md +[`Napi::HandleScope`]: ./handle_scope.md +[`Napi::InstanceWrap`]: ./instance_wrap.md +[`Napi::MemoryManagement`]: ./memory_management.md +[`Napi::Name`]: ./name.md +[`Napi::Number`]: ./number.md +[`Napi::Object`]: ./object.md +[`Napi::ObjectReference`]: ./object_reference.md +[`Napi::ObjectWrap`]: ./object_wrap.md +[`Napi::Promise`]: ./promise.md +[`Napi::PropertyDescriptor`]: ./property_descriptor.md +[`Napi::RangeError`]: ./range_error.md +[`Napi::Reference`]: ./reference.md +[`Napi::Reference`]: ./reference.md +[`Napi::Reference`]: ./reference.md +[`Napi::String`]: ./string.md +[`Napi::Symbol`]: ./symbol.md +[`Napi::SyntaxError`]: ./syntax_error.md +[`Napi::ThreadSafeFunction`]: ./threadsafe_function.md +[`Napi::TypeError`]: ./type_error.md +[`Napi::TypeTaggable`]: ./type_taggable.md +[`Napi::TypedArray`]: ./typed_array.md +[`Napi::TypedArrayOf`]: ./typed_array_of.md +[`Napi::Uint8Array`]: ./typed_array_of.md +[`Napi::Value`]: ./value.md +[`Napi::VersionManagement`]: ./version_management.md +[`std::exception`]: /reference/exception/exception/ diff --git a/examples/napitutorials/doc/apiguide/instance_wrap.md b/examples/napitutorials/doc/apiguide/instance_wrap.md new file mode 100644 index 0000000000000000000000000000000000000000..1238e7e296adf6b92ec15346c1d0a4d3d54ee25a --- /dev/null +++ b/examples/napitutorials/doc/apiguide/instance_wrap.md @@ -0,0 +1,408 @@ +# InstanceWrap + +This class serves as the base class for [`Napi::ObjectWrap`][] and +[`Napi::Addon`][]. + +In the case of [`Napi::Addon`][] it provides the +methods for exposing functions to JavaScript on instances of an add-on. + +As a base class for [`Napi::ObjectWrap`][] it provides the methods for +exposing instance methods of JavaScript objects instantiated from the JavaScript +class corresponding to the subclass of [`Napi::ObjectWrap`][]. + +## Methods + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(const char* utf8name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of the method +provided by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +void MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(const char* utf8name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] utf8name`: Null-terminated string that represents the name of the method +provided by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +Napi::Value MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(Napi::Symbol name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: JavaScript symbol that represents the name of the method provided +by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +void MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +template +static Napi::ClassPropertyDescriptor +Napi::InstanceWrap::InstanceMethod(Napi::Symbol name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +``` + +- `[in] name`: JavaScript symbol that represents the name of the method provided +by instances of the class. +- `[in] method`: The native function that represents a method provided by the +add-on. +- `[in] attributes`: The attributes associated with the property. One or more of +`napi_property_attributes`. +- `[in] data`: User-provided data passed into the method when it is invoked. + +Returns a `Napi::ClassPropertyDescriptor` object that represents a method +provided by instances of the class. The method must be of the form + +```cpp +Napi::Value MethodName(const Napi::CallbackInfo& info); +``` + +### InstanceMethod + +Creates a property descriptor that represents a method exposed on JavaScript +instances of this class. + +```cpp +