Node-API#
Node-API (formerly N-API) is an API for building native Addons. It isindependent from the underlying JavaScript runtime (for example, V8) and ismaintained as part of Node.js itself. This API will be Application BinaryInterface (ABI) stable across versions of Node.js. It is intended to insulateaddons from changes in the underlying JavaScript engine and allow modulescompiled for one major version to run on later major versions of Node.js withoutrecompilation. TheABI Stability guide provides a more in-depth explanation.
Addons are built/packaged with the same approach/tools outlined in the sectiontitledC++ Addons. The only difference is the set of APIs that are used bythe native code. Instead of using the V8 orNative Abstractions for Node.jsAPIs, the functions available in Node-API are used.
APIs exposed by Node-API are generally used to create and manipulateJavaScript values. Concepts and operations generally map to ideas specifiedin the ECMA-262 Language Specification. The APIs have the followingproperties:
- All Node-API calls return a status code of type
napi_status
. Thisstatus indicates whether the API call succeeded or failed. - The API's return value is passed via an out parameter.
- All JavaScript values are abstracted behind an opaque type named
napi_value
. - In case of an error status code, additional information can be obtainedusing
napi_get_last_error_info
. More information can be found in the errorhandling sectionError handling.
Node-API is a C API that ensures ABI stability across Node.js versionsand different compiler levels. A C++ API can be easier to use.To support using C++, the project maintains aC++ wrapper module callednode-addon-api
.This wrapper provides an inlinable C++ API. Binaries builtwithnode-addon-api
will depend on the symbols for the Node-API C-basedfunctions exported by Node.js.node-addon-api
is a moreefficient way to write code that calls Node-API. Take, for example, thefollowingnode-addon-api
code. The first section shows thenode-addon-api
code and the second section shows what actually getsused in the addon.
Object obj = Object::New(env);obj["foo"] = String::New(env,"bar");
napi_status status;napi_value object, string;status =napi_create_object(env, &object);if (status != napi_ok) {napi_throw_error(env, ...);return;}status =napi_create_string_utf8(env,"bar", NAPI_AUTO_LENGTH, &string);if (status != napi_ok) {napi_throw_error(env, ...);return;}status =napi_set_named_property(env, object,"foo", string);if (status != napi_ok) {napi_throw_error(env, ...);return;}
The end result is that the addon only uses the exported C APIs. As a result,it still gets the benefits of the ABI stability provided by the C API.
When usingnode-addon-api
instead of the C APIs, start with the APIdocsfornode-addon-api
.
TheNode-API Resource offersan excellent orientation and tips for developers just getting started withNode-API andnode-addon-api
. Additional media resources can be found on theNode-API Media page.
Implications of ABI stability#
Although Node-API provides an ABI stability guarantee, other parts of Node.js donot, and any external libraries used from the addon may not. In particular,none of the following APIs provide an ABI stability guarantee across majorversions:
the Node.js C++ APIs available via any of
#include<node.h>#include<node_buffer.h>#include<node_version.h>#include<node_object_wrap.h>
the libuv APIs which are also included with Node.js and available via
#include<uv.h>
the V8 API available via
#include<v8.h>
Thus, for an addon to remain ABI-compatible across Node.js major versions, itmust use Node-API exclusively by restricting itself to using
#include<node_api.h>
and by checking, for all external libraries that it uses, that the externallibrary makes ABI stability guarantees similar to Node-API.
Building#
Unlike modules written in JavaScript, developing and deploying Node.jsnative addons using Node-API requires an additional set of tools. Besides thebasic tools required to develop for Node.js, the native addon developerrequires a toolchain that can compile C and C++ code into a binary. Inaddition, depending upon how the native addon is deployed, theuser ofthe native addon will also need to have a C/C++ toolchain installed.
For Linux developers, the necessary C/C++ toolchain packages are readilyavailable.GCC is widely used in the Node.js community to build andtest across a variety of platforms. For many developers, theLLVMcompiler infrastructure is also a good choice.
For Mac developers,Xcode offers all the required compiler tools.However, it is not necessary to install the entire Xcode IDE. The followingcommand installs the necessary toolchain:
xcode-select --install
For Windows developers,Visual Studio offers all the required compilertools. However, it is not necessary to install the entire Visual StudioIDE. The following command installs the necessary toolchain:
npm install --global windows-build-tools
The sections below describe the additional tools available for developingand deploying Node.js native addons.
Build tools#
Both the tools listed here require thatusers of the nativeaddon have a C/C++ toolchain installed in order to successfully installthe native addon.
node-gyp#
node-gyp is a build system based on thegyp-next fork ofGoogle'sGYP tool and comes bundled with npm. GYP, and therefore node-gyp,requires that Python be installed.
Historically, node-gyp has been the tool of choice for building nativeaddons. It has widespread adoption and documentation. However, somedevelopers have run into limitations in node-gyp.
CMake.js#
CMake.js is an alternative build system based onCMake.
CMake.js is a good choice for projects that already use CMake or fordevelopers affected by limitations in node-gyp.build_with_cmake
is anexample of a CMake-based native addon project.
Uploading precompiled binaries#
The three tools listed here permit native addon developers and maintainersto create and upload binaries to public or private servers. These tools aretypically integrated with CI/CD build systems likeTravis CI andAppVeyor to build and upload binaries for a variety of platforms andarchitectures. These binaries are then available for download by users whodo not need to have a C/C++ toolchain installed.
node-pre-gyp#
node-pre-gyp is a tool based on node-gyp that adds the ability toupload binaries to a server of the developer's choice. node-pre-gyp hasparticularly good support for uploading binaries to Amazon S3.
prebuild#
prebuild is a tool that supports builds using either node-gyp orCMake.js. Unlike node-pre-gyp which supports a variety of servers, prebuilduploads binaries only toGitHub releases. prebuild is a good choice forGitHub projects using CMake.js.
prebuildify#
prebuildify is a tool based on node-gyp. The advantage of prebuildify isthat the built binaries are bundled with the native addon when it'suploaded to npm. The binaries are downloaded from npm and are immediatelyavailable to the module user when the native addon is installed.
Usage#
In order to use the Node-API functions, include the filenode_api.h
whichis located in the src directory in the node development tree:
#include<node_api.h>
This will opt into the defaultNAPI_VERSION
for the given release of Node.js.In order to ensure compatibility with specific versions of Node-API, the versioncan be specified explicitly when including the header:
#define NAPI_VERSION 3#include<node_api.h>
This restricts the Node-API surface to just the functionality that was availablein the specified (and earlier) versions.
Some of the Node-API surface is experimental and requires explicit opt-in:
#define NAPI_EXPERIMENTAL#include<node_api.h>
In this case the entire API surface, including any experimental APIs, will beavailable to the module code.
Occasionally, experimental features are introduced that affect already-releasedand stable APIs. These features can be disabled by an opt-out:
#define NAPI_EXPERIMENTAL#define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT#include<node_api.h>
where<FEATURE_NAME>
is the name of an experimental feature that affects bothexperimental and stable APIs.
Node-API version matrix#
Up until version 9, Node-API versions were additive and versionedindependently from Node.js. This meant that any version wasan extension to the previous version in that it had all ofthe APIs from the previous version with some additions. EachNode.js version only supported a single Node-API version.For example v18.15.0 supports only Node-API version 8. ABI stability wasachieved because 8 was a strict superset of all previous versions.
As of version 9, while Node-API versions continue to be versionedindependently, an add-on that ran with Node-API version 9 may needcode updates to run with Node-API version 10. ABI stabilityis maintained, however, because Node.js versions that supportNode-API versions higher than 8 will support all versionsbetween 8 and the highest version they support and will defaultto providing the version 8 APIs unless an add-on opts into ahigher Node-API version. This approach provides the flexibilityof better optimizing existing Node-API functions whilemaintaining ABI stability. Existing add-ons can continue to run withoutrecompilation using an earlier version of Node-API. If an add-onneeds functionality from a newer Node-API version, changes to existingcode and recompilation will be needed to use those new functions anyway.
In versions of Node.js that support Node-API version 9 and later, definingNAPI_VERSION=X
and using the existing add-on initialization macroswill bake in the requested Node-API version that will be used at runtimeinto the add-on. IfNAPI_VERSION
is not set it will default to 8.
This table may not be up to date in older streams, the most up to dateinformation is in the latest API documentation in:Node-API version matrix
Node-API version | Supported In |
---|---|
10 | v22.14.0+, 23.6.0+ and all later versions |
9 | v18.17.0+, 20.3.0+, 21.0.0 and all later versions |
8 | v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 and all later versions |
7 | v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 and all later versions |
6 | v10.20.0+, v12.17.0+, 14.0.0 and all later versions |
5 | v10.17.0+, v12.11.0+, 13.0.0 and all later versions |
4 | v10.16.0+, v11.8.0+, 12.0.0 and all later versions |
3 | v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 and all later versions |
2 | v8.10.0+*, v9.3.0+*, 10.0.0 and all later versions |
1 | v8.6.0+**, v9.0.0+*, 10.0.0 and all later versions |
* Node-API was experimental.
** Node.js 8.0.0 included Node-API as experimental. It was released asNode-API version 1 but continued to evolve until Node.js 8.6.0. The API isdifferent in versions prior to Node.js 8.6.0. We recommend Node-API version 3 orlater.
Each API documented for Node-API will have a header namedadded in:
, and APIswhich are stable will have the additional headerNode-API version:
.APIs are directly usable when using a Node.js version which supportsthe Node-API version shown inNode-API version:
or higher.When using a Node.js version that does not support theNode-API version:
listed or if there is noNode-API version:
listed,then the API will only be available if#define NAPI_EXPERIMENTAL
precedes the inclusion ofnode_api.h
orjs_native_api.h
. If an API appears not to be available ona version of Node.js which is later than the one shown inadded in:
thenthis is most likely the reason for the apparent absence.
The Node-APIs associated strictly with accessing ECMAScript features from nativecode can be found separately injs_native_api.h
andjs_native_api_types.h
.The APIs defined in these headers are included innode_api.h
andnode_api_types.h
. The headers are structured in this way in order to allowimplementations of Node-API outside of Node.js. For those implementations theNode.js specific APIs may not be applicable.
The Node.js-specific parts of an addon can be separated from the code thatexposes the actual functionality to the JavaScript environment so that thelatter may be used with multiple implementations of Node-API. In the examplebelow,addon.c
andaddon.h
refer only tojs_native_api.h
. This ensuresthataddon.c
can be reused to compile against either the Node.jsimplementation of Node-API or any implementation of Node-API outside of Node.js.
addon_node.c
is a separate file that contains the Node.js specific entry pointto the addon and which instantiates the addon by calling intoaddon.c
when theaddon is loaded into a Node.js environment.
// addon.h#ifndef _ADDON_H_#define _ADDON_H_#include<js_native_api.h>napi_valuecreate_addon(napi_env env);#endif// _ADDON_H_
// addon.c#include"addon.h"#define NODE_API_CALL(env, call) \ do { \ napi_status status = (call); \if (status != napi_ok) { \ const napi_extended_error_info* error_info = NULL; \ napi_get_last_error_info((env), &error_info); \ const char* err_message = error_info->error_message; \ bool is_pending; \ napi_is_exception_pending((env), &is_pending); \/* If an exception is already pending, don't rethrow it */ \if (!is_pending) { \ const char* message = (err_message == NULL) \ ?"empty error message" \ : err_message; \ napi_throw_error((env), NULL, message); \ } \ return NULL; \ } \ } while(0)static napi_valueDoSomethingUseful(napi_env env, napi_callback_info info) {// Do something useful.returnNULL;}napi_valuecreate_addon(napi_env env) { napi_value result; NODE_API_CALL(env, napi_create_object(env, &result)); napi_value exported_function; NODE_API_CALL(env, napi_create_function(env,"doSomethingUseful", NAPI_AUTO_LENGTH, DoSomethingUseful,NULL, &exported_function)); NODE_API_CALL(env, napi_set_named_property(env, result,"doSomethingUseful", exported_function));return result;}
// addon_node.c#include<node_api.h>#include"addon.h"NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {// This function body is expected to return a `napi_value`.// The variables `napi_env env` and `napi_value exports` may be used within// the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.return create_addon(env);}
Environment life cycle APIs#
Section 8.7 of theECMAScript Language Specification defines the conceptof an "Agent" as a self-contained environment in which JavaScript code runs.Multiple such Agents may be started and terminated either concurrently or insequence by the process.
A Node.js environment corresponds to an ECMAScript Agent. In the main process,an environment is created at startup, and additional environments can be createdon separate threads to serve asworker threads. When Node.js is embedded inanother application, the main thread of the application may also construct anddestroy a Node.js environment multiple times during the life cycle of theapplication process such that each Node.js environment created by theapplication may, in turn, during its life cycle create and destroy additionalenvironments as worker threads.
From the perspective of a native addon this means that the bindings it providesmay be called multiple times, from multiple contexts, and even concurrently frommultiple threads.
Native addons may need to allocate global state which they use duringtheir life cycle of an Node.js environment such that the state can beunique to each instance of the addon.
To this end, Node-API provides a way to associate data such that its life cycleis tied to the life cycle of a Node.js environment.
napi_set_instance_data
#
napi_statusnapi_set_instance_data(node_api_basic_env env,void* data, napi_finalize finalize_cb,void* finalize_hint);
[in] env
: The environment that the Node-API call is invoked under.[in] data
: The data item to make available to bindings of this instance.[in] finalize_cb
: The function to call when the environment is being torndown. The function receivesdata
so that it might free it.napi_finalize
provides more details.[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.
Returnsnapi_ok
if the API succeeded.
This API associatesdata
with the currently running Node.js environment.data
can later be retrieved usingnapi_get_instance_data()
. Any existing dataassociated with the currently running Node.js environment which was set by meansof a previous call tonapi_set_instance_data()
will be overwritten. If afinalize_cb
was provided by the previous call, it will not be called.
napi_get_instance_data
#
napi_statusnapi_get_instance_data(node_api_basic_env env,void** data);
[in] env
: The environment that the Node-API call is invoked under.[out] data
: The data item that was previously associated with the currentlyrunning Node.js environment by a call tonapi_set_instance_data()
.
Returnsnapi_ok
if the API succeeded.
This API retrieves data that was previously associated with the currentlyrunning Node.js environment vianapi_set_instance_data()
. If no data is set,the call will succeed anddata
will be set toNULL
.
Basic Node-API data types#
Node-API exposes the following fundamental data types as abstractions that areconsumed by the various APIs. These APIs should be treated as opaque,introspectable only with other Node-API calls.
napi_status
#
Integral status code indicating the success or failure of a Node-API call.Currently, the following status codes are supported.
typedefenum { napi_ok, napi_invalid_arg, napi_object_expected, napi_string_expected, napi_name_expected, napi_function_expected, napi_number_expected, napi_boolean_expected, napi_array_expected, napi_generic_failure, napi_pending_exception, napi_cancelled, napi_escape_called_twice, napi_handle_scope_mismatch, napi_callback_scope_mismatch, napi_queue_full, napi_closing, napi_bigint_expected, napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, napi_would_deadlock,/* unused */ napi_no_external_buffers_allowed, napi_cannot_run_js} napi_status;
If additional information is required upon an API returning a failed status,it can be obtained by callingnapi_get_last_error_info
.
napi_extended_error_info
#
typedefstruct {constchar* error_message;void* engine_reserved;uint32_t engine_error_code; napi_status error_code;} napi_extended_error_info;
error_message
: UTF8-encoded string containing a VM-neutral description ofthe error.engine_reserved
: Reserved for VM-specific error details. This is currentlynot implemented for any VM.engine_error_code
: VM-specific error code. This is currentlynot implemented for any VM.error_code
: The Node-API status code that originated with the last error.
See theError handling section for additional information.
napi_env
#
napi_env
is used to represent a context that the underlying Node-APIimplementation can use to persist VM-specific state. This structure is passedto native functions when they're invoked, and it must be passed back whenmaking Node-API calls. Specifically, the samenapi_env
that was passed in whenthe initial native function was called must be passed to any subsequentnested Node-API calls. Caching thenapi_env
for the purpose of general reuse,and passing thenapi_env
between instances of the same addon running ondifferentWorker
threads is not allowed. Thenapi_env
becomes invalidwhen an instance of a native addon is unloaded. Notification of this event isdelivered through the callbacks given tonapi_add_env_cleanup_hook
andnapi_set_instance_data
.
node_api_basic_env
#
This variant ofnapi_env
is passed to synchronous finalizers(node_api_basic_finalize
). There is a subset of Node-APIs which accepta parameter of typenode_api_basic_env
as their first argument. These APIs donot access the state of the JavaScript engine and are thus safe to call fromsynchronous finalizers. Passing a parameter of typenapi_env
to these APIs isallowed, however, passing a parameter of typenode_api_basic_env
to APIs thataccess the JavaScript engine state is not allowed. Attempting to do so withouta cast will produce a compiler warning or an error when add-ons are compiledwith flags which cause them to emit warnings and/or errors when incorrectpointer types are passed into a function. Calling such APIs from a synchronousfinalizer will ultimately result in the termination of the application.
napi_value
#
This is an opaque pointer that is used to represent a JavaScript value.
napi_threadsafe_function
#
This is an opaque pointer that represents a JavaScript function which can becalled asynchronously from multiple threads vianapi_call_threadsafe_function()
.
napi_threadsafe_function_release_mode
#
A value to be given tonapi_release_threadsafe_function()
to indicate whetherthe thread-safe function is to be closed immediately (napi_tsfn_abort
) ormerely released (napi_tsfn_release
) and thus available for subsequent use vianapi_acquire_threadsafe_function()
andnapi_call_threadsafe_function()
.
typedefenum { napi_tsfn_release, napi_tsfn_abort} napi_threadsafe_function_release_mode;
napi_threadsafe_function_call_mode
#
A value to be given tonapi_call_threadsafe_function()
to indicate whetherthe call should block whenever the queue associated with the thread-safefunction is full.
typedefenum { napi_tsfn_nonblocking, napi_tsfn_blocking} napi_threadsafe_function_call_mode;
Node-API memory management types#
napi_handle_scope
#
This is an abstraction used to control and modify the lifetime of objectscreated within a particular scope. In general, Node-API values are createdwithin the context of a handle scope. When a native method is called fromJavaScript, a default handle scope will exist. If the user does not explicitlycreate a new handle scope, Node-API values will be created in the default handlescope. For any invocations of code outside the execution of a native method(for instance, during a libuv callback invocation), the module is required tocreate a scope before invoking any functions that can result in the creationof JavaScript values.
Handle scopes are created usingnapi_open_handle_scope
and are destroyedusingnapi_close_handle_scope
. Closing the scope can indicate to the GCthat allnapi_value
s created during the lifetime of the handle scope are nolonger referenced from the current stack frame.
For more details, review theObject lifetime management.
napi_escapable_handle_scope
#
Escapable handle scopes are a special type of handle scope to return valuescreated within a particular handle scope to a parent scope.
napi_ref
#
This is the abstraction to use to reference anapi_value
. This allows forusers to manage the lifetimes of JavaScript values, including defining theirminimum lifetimes explicitly.
For more details, review theObject lifetime management.
napi_type_tag
#
A 128-bit value stored as two unsigned 64-bit integers. It serves as a UUIDwith which JavaScript objects orexternals can be "tagged" in order toensure that they are of a certain type. This is a stronger check thannapi_instanceof
, because the latter can report a false positive if theobject's prototype has been manipulated. Type-tagging is most useful inconjunction withnapi_wrap
because it ensures that the pointer retrievedfrom a wrapped object can be safely cast to the native type corresponding to thetype tag that had been previously applied to the JavaScript object.
typedefstruct {uint64_t lower;uint64_t upper;} napi_type_tag;
napi_async_cleanup_hook_handle
#
An opaque value returned bynapi_add_async_cleanup_hook
. It must be passedtonapi_remove_async_cleanup_hook
when the chain of asynchronous cleanupevents completes.
Node-API callback types#
napi_callback_info
#
Opaque datatype that is passed to a callback function. It can be used forgetting additional information about the context in which the callback wasinvoked.
napi_callback
#
Function pointer type for user-provided native functions which are to beexposed to JavaScript via Node-API. Callback functions should satisfy thefollowing signature:
typedefnapi_value(*napi_callback)(napi_env, napi_callback_info);
Unless for reasons discussed inObject Lifetime Management, creating ahandle and/or callback scope inside anapi_callback
is not necessary.
node_api_basic_finalize
#
Function pointer type for add-on provided functions that allow the user to benotified when externally-owned data is ready to be cleaned up because theobject it was associated with has been garbage-collected. The user must providea function satisfying the following signature which would get called upon theobject's collection. Currently,node_api_basic_finalize
can be used forfinding out when objects that have external data are collected.
typedefvoid(*node_api_basic_finalize)(node_api_basic_env env,void* finalize_data,void* finalize_hint);
Unless for reasons discussed inObject Lifetime Management, creating ahandle and/or callback scope inside the function body is not necessary.
Since these functions may be called while the JavaScript engine is in a statewhere it cannot execute JavaScript code, only Node-APIs which accept anode_api_basic_env
as their first parameter may be called.node_api_post_finalizer
can be used to schedule Node-API calls thatrequire access to the JavaScript engine's state to run after the currentgarbage collection cycle has completed.
In the case ofnode_api_create_external_string_latin1
andnode_api_create_external_string_utf16
theenv
parameter may be null,because external strings can be collected during the latter part of environmentshutdown.
Change History:
experimental (
NAPI_EXPERIMENTAL
):Only Node-API calls that accept a
node_api_basic_env
as their firstparameter may be called, otherwise the application will be terminated with anappropriate error message. This feature can be turned off by definingNODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT
.
napi_finalize
#
Function pointer type for add-on provided function that allow the user toschedule a group of calls to Node-APIs in response to a garbage collectionevent, after the garbage collection cycle has completed. These functionpointers can be used withnode_api_post_finalizer
.
typedefvoid(*napi_finalize)(napi_env env,void* finalize_data,void* finalize_hint);
Change History:
experimental (
NAPI_EXPERIMENTAL
is defined):A function of this type may no longer be used as a finalizer, except with
node_api_post_finalizer
.node_api_basic_finalize
must be usedinstead. This feature can be turned off by definingNODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT
.
napi_async_execute_callback
#
Function pointer used with functions that support asynchronousoperations. Callback functions must satisfy the following signature:
typedefvoid(*napi_async_execute_callback)(napi_env env,void* data);
Implementations of this function must avoid making Node-API calls that executeJavaScript or interact with JavaScript objects. Node-API calls should be in thenapi_async_complete_callback
instead. Do not use thenapi_env
parameter asit will likely result in execution of JavaScript.
napi_async_complete_callback
#
Function pointer used with functions that support asynchronousoperations. Callback functions must satisfy the following signature:
typedefvoid(*napi_async_complete_callback)(napi_env env, napi_status status,void* data);
Unless for reasons discussed inObject Lifetime Management, creating ahandle and/or callback scope inside the function body is not necessary.
napi_threadsafe_function_call_js
#
Function pointer used with asynchronous thread-safe function calls. The callbackwill be called on the main thread. Its purpose is to use a data item arrivingvia the queue from one of the secondary threads to construct the parametersnecessary for a call into JavaScript, usually vianapi_call_function
, and thenmake the call into JavaScript.
The data arriving from the secondary thread via the queue is given in thedata
parameter and the JavaScript function to call is given in thejs_callback
parameter.
Node-API sets up the environment prior to calling this callback, so it issufficient to call the JavaScript function vianapi_call_function
rather thanvianapi_make_callback
.
Callback functions must satisfy the following signature:
typedefvoid(*napi_threadsafe_function_call_js)(napi_env env, napi_value js_callback,void* context,void* data);
[in] env
: The environment to use for API calls, orNULL
if the thread-safefunction is being torn down anddata
may need to be freed.[in] js_callback
: The JavaScript function to call, orNULL
if thethread-safe function is being torn down anddata
may need to be freed. Itmay also beNULL
if the thread-safe function was created withoutjs_callback
.[in] context
: The optional data with which the thread-safe function wascreated.[in] data
: Data created by the secondary thread. It is the responsibility ofthe callback to convert this native data to JavaScript values (with Node-APIfunctions) that can be passed as parameters whenjs_callback
is invoked.This pointer is managed entirely by the threads and this callback. Thus thiscallback should free the data.
Unless for reasons discussed inObject Lifetime Management, creating ahandle and/or callback scope inside the function body is not necessary.
napi_cleanup_hook
#
Function pointer used withnapi_add_env_cleanup_hook
. It will be calledwhen the environment is being torn down.
Callback functions must satisfy the following signature:
typedefvoid(*napi_cleanup_hook)(void* data);
[in] data
: The data that was passed tonapi_add_env_cleanup_hook
.
napi_async_cleanup_hook
#
Function pointer used withnapi_add_async_cleanup_hook
. It will be calledwhen the environment is being torn down.
Callback functions must satisfy the following signature:
typedefvoid(*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,void* data);
[in] handle
: The handle that must be passed tonapi_remove_async_cleanup_hook
after completion of the asynchronouscleanup.[in] data
: The data that was passed tonapi_add_async_cleanup_hook
.
The body of the function should initiate the asynchronous cleanup actions at theend of whichhandle
must be passed in a call tonapi_remove_async_cleanup_hook
.
Error handling#
Node-API uses both return values and JavaScript exceptions for error handling.The following sections explain the approach for each case.
Return values#
All of the Node-API functions share the same error handling pattern. Thereturn type of all API functions isnapi_status
.
The return value will benapi_ok
if the request was successful andno uncaught JavaScript exception was thrown. If an error occurred ANDan exception was thrown, thenapi_status
value for the errorwill be returned. If an exception was thrown, and no error occurred,napi_pending_exception
will be returned.
In cases where a return value other thannapi_ok
ornapi_pending_exception
is returned,napi_is_exception_pending
must be called to check if an exception is pending.See the section on exceptions for more details.
The full set of possiblenapi_status
values is definedinnapi_api_types.h
.
Thenapi_status
return value provides a VM-independent representation ofthe error which occurred. In some cases it is useful to be able to getmore detailed information, including a string representing the error as well asVM (engine)-specific information.
In order to retrieve this informationnapi_get_last_error_info
is provided which returns anapi_extended_error_info
structure.The format of thenapi_extended_error_info
structure is as follows:
typedefstructnapi_extended_error_info {constchar* error_message;void* engine_reserved;uint32_t engine_error_code; napi_status error_code;};
error_message
: Textual representation of the error that occurred.engine_reserved
: Opaque handle reserved for engine use only.engine_error_code
: VM specific error code.error_code
: Node-API status code for the last error.
napi_get_last_error_info
returns the information for the lastNode-API call that was made.
Do not rely on the content or format of any of the extended information as itis not subject to SemVer and may change at any time. It is intended only forlogging purposes.
napi_get_last_error_info
#
napi_statusnapi_get_last_error_info(node_api_basic_env env,const napi_extended_error_info** result);
[in] env
: The environment that the API is invoked under.[out] result
: Thenapi_extended_error_info
structure with moreinformation about the error.
Returnsnapi_ok
if the API succeeded.
This API retrieves anapi_extended_error_info
structure with informationabout the last error that occurred.
The content of thenapi_extended_error_info
returned is only valid up untila Node-API function is called on the sameenv
. This includes a call tonapi_is_exception_pending
so it may often be necessary to make a copyof the information so that it can be used later. The pointer returnedinerror_message
points to a statically-defined string so it is safe to usethat pointer if you have copied it out of theerror_message
field (which willbe overwritten) before another Node-API function was called.
Do not rely on the content or format of any of the extended information as itis not subject to SemVer and may change at any time. It is intended only forlogging purposes.
This API can be called even if there is a pending JavaScript exception.
Exceptions#
Any Node-API function call may result in a pending JavaScript exception. This isthe case for any of the API functions, even those that may not cause theexecution of JavaScript.
If thenapi_status
returned by a function isnapi_ok
then noexception is pending and no additional action is required. If thenapi_status
returned is anything other thannapi_ok
ornapi_pending_exception
, in order to try to recover and continueinstead of simply returning immediately,napi_is_exception_pending
must be called in order to determine if an exception is pending or not.
In many cases when a Node-API function is called and an exception isalready pending, the function will return immediately with anapi_status
ofnapi_pending_exception
. However, this is not the casefor all functions. Node-API allows a subset of the functions to becalled to allow for some minimal cleanup before returning to JavaScript.In that case,napi_status
will reflect the status for the function. Itwill not reflect previous pending exceptions. To avoid confusion, checkthe error status after every function call.
When an exception is pending one of two approaches can be employed.
The first approach is to do any appropriate cleanup and then return so thatexecution will return to JavaScript. As part of the transition back toJavaScript, the exception will be thrown at the point in the JavaScriptcode where the native method was invoked. The behavior of most Node-API callsis unspecified while an exception is pending, and many will simply returnnapi_pending_exception
, so do as little as possible and then return toJavaScript where the exception can be handled.
The second approach is to try to handle the exception. There will be caseswhere the native code can catch the exception, take the appropriate action,and then continue. This is only recommended in specific caseswhere it is known that the exception can be safely handled. In thesecasesnapi_get_and_clear_last_exception
can be used to get andclear the exception. On success, result will contain the handle tothe last JavaScriptObject
thrown. If it is determined, afterretrieving the exception, the exception cannot be handled after allit can be re-thrown it withnapi_throw
where error is theJavaScript value to be thrown.
The following utility functions are also available in case native codeneeds to throw an exception or determine if anapi_value
is an instanceof a JavaScriptError
object:napi_throw_error
,napi_throw_type_error
,napi_throw_range_error
,node_api_throw_syntax_error
andnapi_is_error
.
The following utility functions are also available in case nativecode needs to create anError
object:napi_create_error
,napi_create_type_error
,napi_create_range_error
andnode_api_create_syntax_error
,where result is thenapi_value
that refers to the newly createdJavaScriptError
object.
The Node.js project is adding error codes to all of the errorsgenerated internally. The goal is for applications to use theseerror codes for all error checking. The associated error messageswill remain, but will only be meant to be used for logging anddisplay with the expectation that the message can change withoutSemVer applying. In order to support this model with Node-API, bothin internal functionality and for module specific functionality(as its good practice), thethrow_
andcreate_
functionstake an optional code parameter which is the string for the codeto be added to the error object. If the optional parameter isNULL
then no code will be associated with the error. If a code is provided,the name associated with the error is also updated to be:
originalName [code]
whereoriginalName
is the original name associated with the errorandcode
is the code that was provided. For example, if the codeis'ERR_ERROR_1'
and aTypeError
is being created the name will be:
TypeError [ERR_ERROR_1]
napi_throw
#
NAPI_EXTERN napi_statusnapi_throw(napi_env env, napi_value error);
[in] env
: The environment that the API is invoked under.[in] error
: The JavaScript value to be thrown.
Returnsnapi_ok
if the API succeeded.
This API throws the JavaScript value provided.
napi_throw_error
#
NAPI_EXTERN napi_statusnapi_throw_error(napi_env env,constchar* code,constchar* msg);
[in] env
: The environment that the API is invoked under.[in] code
: Optional error code to be set on the error.[in] msg
: C string representing the text to be associated with the error.
Returnsnapi_ok
if the API succeeded.
This API throws a JavaScriptError
with the text provided.
napi_throw_type_error
#
NAPI_EXTERN napi_statusnapi_throw_type_error(napi_env env,constchar* code,constchar* msg);
[in] env
: The environment that the API is invoked under.[in] code
: Optional error code to be set on the error.[in] msg
: C string representing the text to be associated with the error.
Returnsnapi_ok
if the API succeeded.
This API throws a JavaScriptTypeError
with the text provided.
napi_throw_range_error
#
NAPI_EXTERN napi_statusnapi_throw_range_error(napi_env env,constchar* code,constchar* msg);
[in] env
: The environment that the API is invoked under.[in] code
: Optional error code to be set on the error.[in] msg
: C string representing the text to be associated with the error.
Returnsnapi_ok
if the API succeeded.
This API throws a JavaScriptRangeError
with the text provided.
node_api_throw_syntax_error
#
NAPI_EXTERN napi_statusnode_api_throw_syntax_error(napi_env env,constchar* code,constchar* msg);
[in] env
: The environment that the API is invoked under.[in] code
: Optional error code to be set on the error.[in] msg
: C string representing the text to be associated with the error.
Returnsnapi_ok
if the API succeeded.
This API throws a JavaScriptSyntaxError
with the text provided.
napi_is_error
#
NAPI_EXTERN napi_statusnapi_is_error(napi_env env, napi_value value,bool* result);
[in] env
: The environment that the API is invoked under.[in] value
: Thenapi_value
to be checked.[out] result
: Boolean value that is set to true ifnapi_value
representsan error, false otherwise.
Returnsnapi_ok
if the API succeeded.
This API queries anapi_value
to check if it represents an error object.
napi_create_error
#
NAPI_EXTERN napi_statusnapi_create_error(napi_env env, napi_value code, napi_value msg, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] code
: Optionalnapi_value
with the string for the error code to beassociated with the error.[in] msg
:napi_value
that references a JavaScriptstring
to be used asthe message for theError
.[out] result
:napi_value
representing the error created.
Returnsnapi_ok
if the API succeeded.
This API returns a JavaScriptError
with the text provided.
napi_create_type_error
#
NAPI_EXTERN napi_statusnapi_create_type_error(napi_env env, napi_value code, napi_value msg, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] code
: Optionalnapi_value
with the string for the error code to beassociated with the error.[in] msg
:napi_value
that references a JavaScriptstring
to be used asthe message for theError
.[out] result
:napi_value
representing the error created.
Returnsnapi_ok
if the API succeeded.
This API returns a JavaScriptTypeError
with the text provided.
napi_create_range_error
#
NAPI_EXTERN napi_statusnapi_create_range_error(napi_env env, napi_value code, napi_value msg, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] code
: Optionalnapi_value
with the string for the error code to beassociated with the error.[in] msg
:napi_value
that references a JavaScriptstring
to be used asthe message for theError
.[out] result
:napi_value
representing the error created.
Returnsnapi_ok
if the API succeeded.
This API returns a JavaScriptRangeError
with the text provided.
node_api_create_syntax_error
#
NAPI_EXTERN napi_statusnode_api_create_syntax_error(napi_env env, napi_value code, napi_value msg, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] code
: Optionalnapi_value
with the string for the error code to beassociated with the error.[in] msg
:napi_value
that references a JavaScriptstring
to be used asthe message for theError
.[out] result
:napi_value
representing the error created.
Returnsnapi_ok
if the API succeeded.
This API returns a JavaScriptSyntaxError
with the text provided.
napi_get_and_clear_last_exception
#
napi_statusnapi_get_and_clear_last_exception(napi_env env, napi_value* result);
[in] env
: The environment that the API is invoked under.[out] result
: The exception if one is pending,NULL
otherwise.
Returnsnapi_ok
if the API succeeded.
This API can be called even if there is a pending JavaScript exception.
napi_is_exception_pending
#
napi_statusnapi_is_exception_pending(napi_env env,bool* result);
[in] env
: The environment that the API is invoked under.[out] result
: Boolean value that is set to true if an exception is pending.
Returnsnapi_ok
if the API succeeded.
This API can be called even if there is a pending JavaScript exception.
napi_fatal_exception
#
napi_statusnapi_fatal_exception(napi_env env, napi_value err);
[in] env
: The environment that the API is invoked under.[in] err
: The error that is passed to'uncaughtException'
.
Trigger an'uncaughtException'
in JavaScript. Useful if an asynccallback throws an exception with no way to recover.
Fatal errors#
In the event of an unrecoverable error in a native addon, a fatal error can bethrown to immediately terminate the process.
napi_fatal_error
#
NAPI_NO_RETURNvoidnapi_fatal_error(constchar* location,size_t location_len,constchar* message,size_t message_len);
[in] location
: Optional location at which the error occurred.[in] location_len
: The length of the location in bytes, orNAPI_AUTO_LENGTH
if it is null-terminated.[in] message
: The message associated with the error.[in] message_len
: The length of the message in bytes, orNAPI_AUTO_LENGTH
if it is null-terminated.
The function call does not return, the process will be terminated.
This API can be called even if there is a pending JavaScript exception.
Object lifetime management#
As Node-API calls are made, handles to objects in the heap for the underlyingVM may be returned asnapi_values
. These handles must hold theobjects 'live' until they are no longer required by the native code,otherwise the objects could be collected before the native code wasfinished using them.
As object handles are returned they are associated with a'scope'. The lifespan for the default scope is tied to the lifespanof the native method call. The result is that, by default, handlesremain valid and the objects associated with these handles will beheld live for the lifespan of the native method call.
In many cases, however, it is necessary that the handles remain valid foreither a shorter or longer lifespan than that of the native method.The sections which follow describe the Node-API functions that can be usedto change the handle lifespan from the default.
Making handle lifespan shorter than that of the native method#
It is often necessary to make the lifespan of handles shorter thanthe lifespan of a native method. For example, consider a native methodthat has a loop which iterates through the elements in a large array:
for (int i =0; i <1000000; i++) { napi_value result; napi_status status = napi_get_element(env, object, i, &result);if (status != napi_ok) {break; }// do something with element}
This would result in a large number of handles being created, consumingsubstantial resources. In addition, even though the native code could onlyuse the most recent handle, all of the associated objects would also bekept alive since they all share the same scope.
To handle this case, Node-API provides the ability to establish a new 'scope' towhich newly created handles will be associated. Once those handlesare no longer required, the scope can be 'closed' and any handles associatedwith the scope are invalidated. The methods available to open/close scopes arenapi_open_handle_scope
andnapi_close_handle_scope
.
Node-API only supports a single nested hierarchy of scopes. There is only oneactive scope at any time, and all new handles will be associated with thatscope while it is active. Scopes must be closed in the reverse order fromwhich they are opened. In addition, all scopes created within a native methodmust be closed before returning from that method.
Taking the earlier example, adding calls tonapi_open_handle_scope
andnapi_close_handle_scope
would ensure that at most a single handleis valid throughout the execution of the loop:
for (int i =0; i <1000000; i++) { napi_handle_scope scope; napi_status status = napi_open_handle_scope(env, &scope);if (status != napi_ok) {break; } napi_value result; status = napi_get_element(env, object, i, &result);if (status != napi_ok) {break; }// do something with element status = napi_close_handle_scope(env, scope);if (status != napi_ok) {break; }}
When nesting scopes, there are cases where a handle from aninner scope needs to live beyond the lifespan of that scope. Node-API supportsan 'escapable scope' in order to support this case. An escapable scopeallows one handle to be 'promoted' so that it 'escapes' thecurrent scope and the lifespan of the handle changes from the currentscope to that of the outer scope.
The methods available to open/close escapable scopes arenapi_open_escapable_handle_scope
andnapi_close_escapable_handle_scope
.
The request to promote a handle is made throughnapi_escape_handle
whichcan only be called once.
napi_open_handle_scope
#
NAPI_EXTERN napi_statusnapi_open_handle_scope(napi_env env, napi_handle_scope* result);
[in] env
: The environment that the API is invoked under.[out] result
:napi_value
representing the new scope.
Returnsnapi_ok
if the API succeeded.
This API opens a new scope.
napi_close_handle_scope
#
NAPI_EXTERN napi_statusnapi_close_handle_scope(napi_env env, napi_handle_scope scope);
[in] env
: The environment that the API is invoked under.[in] scope
:napi_value
representing the scope to be closed.
Returnsnapi_ok
if the API succeeded.
This API closes the scope passed in. Scopes must be closed in thereverse order from which they were created.
This API can be called even if there is a pending JavaScript exception.
napi_open_escapable_handle_scope
#
NAPI_EXTERN napi_statusnapi_open_escapable_handle_scope(napi_env env, napi_handle_scope* result);
[in] env
: The environment that the API is invoked under.[out] result
:napi_value
representing the new scope.
Returnsnapi_ok
if the API succeeded.
This API opens a new scope from which one object can be promotedto the outer scope.
napi_close_escapable_handle_scope
#
NAPI_EXTERN napi_statusnapi_close_escapable_handle_scope(napi_env env, napi_handle_scope scope);
[in] env
: The environment that the API is invoked under.[in] scope
:napi_value
representing the scope to be closed.
Returnsnapi_ok
if the API succeeded.
This API closes the scope passed in. Scopes must be closed in thereverse order from which they were created.
This API can be called even if there is a pending JavaScript exception.
napi_escape_handle
#
napi_statusnapi_escape_handle(napi_env env, napi_escapable_handle_scope scope, napi_value escapee, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] scope
:napi_value
representing the current scope.[in] escapee
:napi_value
representing the JavaScriptObject
to beescaped.[out] result
:napi_value
representing the handle to the escapedObject
in the outer scope.
Returnsnapi_ok
if the API succeeded.
This API promotes the handle to the JavaScript object so that it is validfor the lifetime of the outer scope. It can only be called once per scope.If it is called more than once an error will be returned.
This API can be called even if there is a pending JavaScript exception.
References to values with a lifespan longer than that of the native method#
In some cases, an addon will need to be able to create and reference valueswith a lifespan longer than that of a single native method invocation. Forexample, to create a constructor and later use that constructorin a request to create instances, it must be possible to referencethe constructor object across many different instance creation requests. Thiswould not be possible with a normal handle returned as anapi_value
asdescribed in the earlier section. The lifespan of a normal handle ismanaged by scopes and all scopes must be closed before the end of a nativemethod.
Node-API provides methods for creating persistent references to values.Currently Node-API only allows references to be created for alimited set of value types, including object, external, function, and symbol.
Each reference has an associated count with a value of 0 or higher,which determines whether the reference will keep the corresponding value alive.References with a count of 0 do not prevent values from being collected.Values of object (object, function, external) and symbol types are becoming'weak' references and can still be accessed while they are not collected.Any count greater than 0 will prevent the values from being collected.
Symbol values have different flavors. The true weak reference behavior isonly supported by local symbols created with thenapi_create_symbol
functionor the JavaScriptSymbol()
constructor calls. Globally registered symbolscreated with thenode_api_symbol_for
function or JavaScriptSymbol.for()
function calls remain always strong references because the garbage collectordoes not collect them. The same is true for well-known symbols such asSymbol.iterator
. They are also never collected by the garbage collector.
References can be created with an initial reference count. The count canthen be modified throughnapi_reference_ref
andnapi_reference_unref
. If an object is collected while the countfor a reference is 0, all subsequent calls toget the object associated with the referencenapi_get_reference_value
will returnNULL
for the returnednapi_value
. An attempt to callnapi_reference_ref
for a reference whose object has been collectedresults in an error.
References must be deleted once they are no longer required by the addon. Whena reference is deleted, it will no longer prevent the corresponding object frombeing collected. Failure to delete a persistent reference results ina 'memory leak' with both the native memory for the persistent reference andthe corresponding object on the heap being retained forever.
There can be multiple persistent references created which refer to the sameobject, each of which will either keep the object live or not based on itsindividual count. Multiple persistent references to the same objectcan result in unexpectedly keeping alive native memory. The native structuresfor a persistent reference must be kept alive until finalizers for thereferenced object are executed. If a new persistent reference is createdfor the same object, the finalizers for that object will not berun and the native memory pointed by the earlier persistent referencewill not be freed. This can be avoided by callingnapi_delete_reference
in addition tonapi_reference_unref
when possible.
Change History:
Version 10 (
NAPI_VERSION
is defined as10
or higher):References can be created for all value types. The new supported valuetypes do not support weak reference semantic and the values of these typesare released when the reference count becomes 0 and cannot be accessed fromthe reference anymore.
napi_create_reference
#
NAPI_EXTERN napi_statusnapi_create_reference(napi_env env, napi_value value,uint32_t initial_refcount, napi_ref* result);
[in] env
: The environment that the API is invoked under.[in] value
: Thenapi_value
for which a reference is being created.[in] initial_refcount
: Initial reference count for the new reference.[out] result
:napi_ref
pointing to the new reference.
Returnsnapi_ok
if the API succeeded.
This API creates a new reference with the specified reference countto the value passed in.
napi_delete_reference
#
NAPI_EXTERN napi_statusnapi_delete_reference(napi_env env, napi_ref ref);
[in] env
: The environment that the API is invoked under.[in] ref
:napi_ref
to be deleted.
Returnsnapi_ok
if the API succeeded.
This API deletes the reference passed in.
This API can be called even if there is a pending JavaScript exception.
napi_reference_ref
#
NAPI_EXTERN napi_statusnapi_reference_ref(napi_env env, napi_ref ref,uint32_t* result);
[in] env
: The environment that the API is invoked under.[in] ref
:napi_ref
for which the reference count will be incremented.[out] result
: The new reference count.
Returnsnapi_ok
if the API succeeded.
This API increments the reference count for the referencepassed in and returns the resulting reference count.
napi_reference_unref
#
NAPI_EXTERN napi_statusnapi_reference_unref(napi_env env, napi_ref ref,uint32_t* result);
[in] env
: The environment that the API is invoked under.[in] ref
:napi_ref
for which the reference count will be decremented.[out] result
: The new reference count.
Returnsnapi_ok
if the API succeeded.
This API decrements the reference count for the referencepassed in and returns the resulting reference count.
napi_get_reference_value
#
NAPI_EXTERN napi_statusnapi_get_reference_value(napi_env env, napi_ref ref, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] ref
: Thenapi_ref
for which the corresponding value isbeing requested.[out] result
: Thenapi_value
referenced by thenapi_ref
.
Returnsnapi_ok
if the API succeeded.
If still valid, this API returns thenapi_value
representing theJavaScript value associated with thenapi_ref
. Otherwise, resultwill beNULL
.
Cleanup on exit of the current Node.js environment#
While a Node.js process typically releases all its resources when exiting,embedders of Node.js, or future Worker support, may require addons to registerclean-up hooks that will be run once the current Node.js environment exits.
Node-API provides functions for registering and un-registering such callbacks.When those callbacks are run, all resources that are being held by the addonshould be freed up.
napi_add_env_cleanup_hook
#
NODE_EXTERN napi_statusnapi_add_env_cleanup_hook(node_api_basic_env env, napi_cleanup_hook fun,void* arg);
Registersfun
as a function to be run with thearg
parameter once thecurrent Node.js environment exits.
A function can safely be specified multiple times with differentarg
values. In that case, it will be called multiple times as well.Providing the samefun
andarg
values multiple times is not allowedand will lead the process to abort.
The hooks will be called in reverse order, i.e. the most recently added onewill be called first.
Removing this hook can be done by usingnapi_remove_env_cleanup_hook
.Typically, that happens when the resource for which this hook was addedis being torn down anyway.
For asynchronous cleanup,napi_add_async_cleanup_hook
is available.
napi_remove_env_cleanup_hook
#
NAPI_EXTERN napi_statusnapi_remove_env_cleanup_hook(node_api_basic_env env,void (*fun)(void* arg),void* arg);
Unregistersfun
as a function to be run with thearg
parameter once thecurrent Node.js environment exits. Both the argument and the function valueneed to be exact matches.
The function must have originally been registeredwithnapi_add_env_cleanup_hook
, otherwise the process will abort.
napi_add_async_cleanup_hook
#
History
Version | Changes |
---|---|
v14.10.0, v12.19.0 | Changed signature of the |
v14.8.0, v12.19.0 | Added in: v14.8.0, v12.19.0 |
NAPI_EXTERN napi_statusnapi_add_async_cleanup_hook( node_api_basic_env env, napi_async_cleanup_hook hook,void* arg, napi_async_cleanup_hook_handle* remove_handle);
[in] env
: The environment that the API is invoked under.[in] hook
: The function pointer to call at environment teardown.[in] arg
: The pointer to pass tohook
when it gets called.[out] remove_handle
: Optional handle that refers to the asynchronous cleanuphook.
Registershook
, which is a function of typenapi_async_cleanup_hook
, asa function to be run with theremove_handle
andarg
parameters once thecurrent Node.js environment exits.
Unlikenapi_add_env_cleanup_hook
, the hook is allowed to be asynchronous.
Otherwise, behavior generally matches that ofnapi_add_env_cleanup_hook
.
Ifremove_handle
is notNULL
, an opaque value will be stored in itthat must later be passed tonapi_remove_async_cleanup_hook
,regardless of whether the hook has already been invoked.Typically, that happens when the resource for which this hook was addedis being torn down anyway.
napi_remove_async_cleanup_hook
#
History
Version | Changes |
---|---|
v14.10.0, v12.19.0 | Removed |
v14.8.0, v12.19.0 | Added in: v14.8.0, v12.19.0 |
NAPI_EXTERN napi_statusnapi_remove_async_cleanup_hook( napi_async_cleanup_hook_handle remove_handle);
[in] remove_handle
: The handle to an asynchronous cleanup hook that wascreated withnapi_add_async_cleanup_hook
.
Unregisters the cleanup hook corresponding toremove_handle
. This will preventthe hook from being executed, unless it has already started executing.This must be called on anynapi_async_cleanup_hook_handle
value obtainedfromnapi_add_async_cleanup_hook
.
Finalization on the exit of the Node.js environment#
The Node.js environment may be torn down at an arbitrary time as soon aspossible with JavaScript execution disallowed, like on the request ofworker.terminate()
. When the environment is being torn down, theregisterednapi_finalize
callbacks of JavaScript objects, thread-safefunctions and environment instance data are invoked immediately andindependently.
The invocation ofnapi_finalize
callbacks is scheduled after the manuallyregistered cleanup hooks. In order to ensure a proper order of addonfinalization during environment shutdown to avoid use-after-free in thenapi_finalize
callback, addons should register a cleanup hook withnapi_add_env_cleanup_hook
andnapi_add_async_cleanup_hook
to manuallyrelease the allocated resource in a proper order.
Module registration#
Node-API modules are registered in a manner similar to other modulesexcept that instead of using theNODE_MODULE
macro the followingis used:
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
The next difference is the signature for theInit
method. For a Node-APImodule it is as follows:
napi_valueInit(napi_env env, napi_value exports);
The return value fromInit
is treated as theexports
object for the module.TheInit
method is passed an empty object via theexports
parameter as aconvenience. IfInit
returnsNULL
, the parameter passed asexports
isexported by the module. Node-API modules cannot modify themodule
object butcan specify anything as theexports
property of the module.
To add the methodhello
as a function so that it can be called as a methodprovided by the addon:
napi_valueInit(napi_env env, napi_value exports) { napi_status status; napi_property_descriptor desc = {"hello",NULL, Method,NULL,NULL,NULL, napi_writable | napi_enumerable | napi_configurable,NULL }; status = napi_define_properties(env, exports,1, &desc);if (status != napi_ok)returnNULL;return exports;}
To set a function to be returned by therequire()
for the addon:
napi_valueInit(napi_env env, napi_value exports) { napi_value method; napi_status status; status = napi_create_function(env,"exports", NAPI_AUTO_LENGTH, Method,NULL, &method);if (status != napi_ok)returnNULL;return method;}
To define a class so that new instances can be created (often used withObject wrap):
//NOTE: partial example, not all referenced code is includednapi_valueInit(napi_env env, napi_value exports) { napi_status status; napi_property_descriptor properties[] = { {"value",NULL,NULL, GetValue, SetValue,NULL, napi_writable | napi_configurable,NULL }, DECLARE_NAPI_METHOD("plusOne", PlusOne), DECLARE_NAPI_METHOD("multiply", Multiply), }; napi_value cons; status = napi_define_class(env,"MyObject", New,NULL,3, properties, &cons);if (status != napi_ok)returnNULL; status = napi_create_reference(env, cons,1, &constructor);if (status != napi_ok)returnNULL; status = napi_set_named_property(env, exports,"MyObject", cons);if (status != napi_ok)returnNULL;return exports;}
You can also use theNAPI_MODULE_INIT
macro, which acts as a shorthandforNAPI_MODULE
and defining anInit
function:
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) { napi_value answer; napi_status result; status = napi_create_int64(env,42, &answer);if (status != napi_ok)returnNULL; status = napi_set_named_property(env, exports,"answer", answer);if (status != napi_ok)returnNULL;return exports;}
The parametersenv
andexports
are provided to the body of theNAPI_MODULE_INIT
macro.
All Node-API addons are context-aware, meaning they may be loaded multipletimes. There are a few design considerations when declaring such a module.The documentation oncontext-aware addons provides more details.
The variablesenv
andexports
will be available inside the function bodyfollowing the macro invocation.
For more details on setting properties on objects, see the section onWorking with JavaScript properties.
For more details on building addon modules in general, refer to the existingAPI.
Working with JavaScript values#
Node-API exposes a set of APIs to create all types of JavaScript values.Some of these types are documented underSection 6of theECMAScript Language Specification.
Fundamentally, these APIs are used to do one of the following:
- Create a new JavaScript object
- Convert from a primitive C type to a Node-API value
- Convert from Node-API value to a primitive C type
- Get global instances including
undefined
andnull
Node-API values are represented by the typenapi_value
.Any Node-API call that requires a JavaScript value takes in anapi_value
.In some cases, the API does check the type of thenapi_value
up-front.However, for better performance, it's better for the caller to make sure thatthenapi_value
in question is of the JavaScript type expected by the API.
Enum types#
napi_key_collection_mode
#
typedefenum { napi_key_include_prototypes, napi_key_own_only} napi_key_collection_mode;
Describes theKeys/Properties
filter enums:
napi_key_collection_mode
limits the range of collected properties.
napi_key_own_only
limits the collected properties to the givenobject only.napi_key_include_prototypes
will include all keysof the objects's prototype chain as well.
napi_key_filter
#
typedefenum { napi_key_all_properties =0, napi_key_writable =1, napi_key_enumerable =1 <<1, napi_key_configurable =1 <<2, napi_key_skip_strings =1 <<3, napi_key_skip_symbols =1 <<4} napi_key_filter;
Property filter bits. They can be or'ed to build a composite filter.
napi_key_conversion
#
typedefenum { napi_key_keep_numbers, napi_key_numbers_to_strings} napi_key_conversion;
napi_key_numbers_to_strings
will convert integer indexes tostrings.napi_key_keep_numbers
will return numbers for integerindexes.
napi_valuetype
#
typedefenum {// ES6 types (corresponds to typeof) napi_undefined, napi_null, napi_boolean, napi_number, napi_string, napi_symbol, napi_object, napi_function, napi_external, napi_bigint,} napi_valuetype;
Describes the type of anapi_value
. This generally corresponds to the typesdescribed inSection 6.1 of the ECMAScript Language Specification.In addition to types in that section,napi_valuetype
can also representFunction
s andObject
s with external data.
A JavaScript value of typenapi_external
appears in JavaScript as a plainobject such that no properties can be set on it, and no prototype.
napi_typedarray_type
#
typedefenum { napi_int8_array, napi_uint8_array, napi_uint8_clamped_array, napi_int16_array, napi_uint16_array, napi_int32_array, napi_uint32_array, napi_float32_array, napi_float64_array, napi_bigint64_array, napi_biguint64_array,} napi_typedarray_type;
This represents the underlying binary scalar datatype of theTypedArray
.Elements of this enum correspond toSection 22.2 of theECMAScript Language Specification.
Object creation functions#
napi_create_array
#
napi_statusnapi_create_array(napi_env env, napi_value* result)
[in] env
: The environment that the Node-API call is invoked under.[out] result
: Anapi_value
representing a JavaScriptArray
.
Returnsnapi_ok
if the API succeeded.
This API returns a Node-API value corresponding to a JavaScriptArray
type.JavaScript arrays are described inSection 22.1 of the ECMAScript Language Specification.
napi_create_array_with_length
#
napi_statusnapi_create_array_with_length(napi_env env,size_t length, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] length
: The initial length of theArray
.[out] result
: Anapi_value
representing a JavaScriptArray
.
Returnsnapi_ok
if the API succeeded.
This API returns a Node-API value corresponding to a JavaScriptArray
type.TheArray
's length property is set to the passed-in length parameter.However, the underlying buffer is not guaranteed to be pre-allocated by the VMwhen the array is created. That behavior is left to the underlying VMimplementation. If the buffer must be a contiguous block of memory that can bedirectly read and/or written via C, consider usingnapi_create_external_arraybuffer
.
JavaScript arrays are described inSection 22.1 of the ECMAScript Language Specification.
napi_create_arraybuffer
#
napi_statusnapi_create_arraybuffer(napi_env env,size_t byte_length,void** data, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] length
: The length in bytes of the array buffer to create.[out] data
: Pointer to the underlying byte buffer of theArrayBuffer
.data
can optionally be ignored by passingNULL
.[out] result
: Anapi_value
representing a JavaScriptArrayBuffer
.
Returnsnapi_ok
if the API succeeded.
This API returns a Node-API value corresponding to a JavaScriptArrayBuffer
.ArrayBuffer
s are used to represent fixed-length binary data buffers. They arenormally used as a backing-buffer forTypedArray
objects.TheArrayBuffer
allocated will have an underlying byte buffer whose size isdetermined by thelength
parameter that's passed in.The underlying buffer is optionally returned back to the caller in case thecaller wants to directly manipulate the buffer. This buffer can only bewritten to directly from native code. To write to this buffer from JavaScript,a typed array orDataView
object would need to be created.
JavaScriptArrayBuffer
objects are described inSection 24.1 of the ECMAScript Language Specification.
napi_create_buffer
#
napi_statusnapi_create_buffer(napi_env env,size_t size,void** data, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] size
: Size in bytes of the underlying buffer.[out] data
: Raw pointer to the underlying buffer.data
can optionally be ignored by passingNULL
.[out] result
: Anapi_value
representing anode::Buffer
.
Returnsnapi_ok
if the API succeeded.
This API allocates anode::Buffer
object. While this is still afully-supported data structure, in most cases using aTypedArray
will suffice.
napi_create_buffer_copy
#
napi_statusnapi_create_buffer_copy(napi_env env,size_t length,constvoid* data,void** result_data, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] size
: Size in bytes of the input buffer (should be the same as the sizeof the new buffer).[in] data
: Raw pointer to the underlying buffer to copy from.[out] result_data
: Pointer to the newBuffer
's underlying data buffer.result_data
can optionally be ignored by passingNULL
.[out] result
: Anapi_value
representing anode::Buffer
.
Returnsnapi_ok
if the API succeeded.
This API allocates anode::Buffer
object and initializes it with data copiedfrom the passed-in buffer. While this is still a fully-supported datastructure, in most cases using aTypedArray
will suffice.
napi_create_date
#
napi_statusnapi_create_date(napi_env env,double time, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] time
: ECMAScript time value in milliseconds since 01 January, 1970 UTC.[out] result
: Anapi_value
representing a JavaScriptDate
.
Returnsnapi_ok
if the API succeeded.
This API does not observe leap seconds; they are ignored, asECMAScript aligns with POSIX time specification.
This API allocates a JavaScriptDate
object.
JavaScriptDate
objects are described inSection 20.3 of the ECMAScript Language Specification.
napi_create_external
#
napi_statusnapi_create_external(napi_env env,void* data, napi_finalize finalize_cb,void* finalize_hint, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] data
: Raw pointer to the external data.[in] finalize_cb
: Optional callback to call when the external value is beingcollected.napi_finalize
provides more details.[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.[out] result
: Anapi_value
representing an external value.
Returnsnapi_ok
if the API succeeded.
This API allocates a JavaScript value with external data attached to it. Thisis used to pass external data through JavaScript code, so it can be retrievedlater by native code usingnapi_get_value_external
.
The API adds anapi_finalize
callback which will be called when the JavaScriptobject just created has been garbage collected.
The created value is not an object, and therefore does not support additionalproperties. It is considered a distinct value type: callingnapi_typeof()
withan external value yieldsnapi_external
.
napi_create_external_arraybuffer
#
napi_statusnapi_create_external_arraybuffer(napi_env env,void* external_data,size_t byte_length, napi_finalize finalize_cb,void* finalize_hint, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] external_data
: Pointer to the underlying byte buffer of theArrayBuffer
.[in] byte_length
: The length in bytes of the underlying buffer.[in] finalize_cb
: Optional callback to call when theArrayBuffer
is beingcollected.napi_finalize
provides more details.[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.[out] result
: Anapi_value
representing a JavaScriptArrayBuffer
.
Returnsnapi_ok
if the API succeeded.
Some runtimes other than Node.js have dropped support for external buffers.On runtimes other than Node.js this method may returnnapi_no_external_buffers_allowed
to indicate that externalbuffers are not supported. One such runtime is Electron asdescribed in this issueelectron/issues/35801.
In order to maintain broadest compatibility with all runtimesyou may defineNODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
in your addon beforeincludes for the node-api headers. Doing so will hide the 2 functionsthat create external buffers. This will ensure a compilation erroroccurs if you accidentally use one of these methods.
This API returns a Node-API value corresponding to a JavaScriptArrayBuffer
.The underlying byte buffer of theArrayBuffer
is externally allocated andmanaged. The caller must ensure that the byte buffer remains valid until thefinalize callback is called.
The API adds anapi_finalize
callback which will be called when the JavaScriptobject just created has been garbage collected.
JavaScriptArrayBuffer
s are described inSection 24.1 of the ECMAScript Language Specification.
napi_create_external_buffer
#
napi_statusnapi_create_external_buffer(napi_env env,size_t length,void* data, napi_finalize finalize_cb,void* finalize_hint, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] length
: Size in bytes of the input buffer (should be the same as thesize of the new buffer).[in] data
: Raw pointer to the underlying buffer to expose to JavaScript.[in] finalize_cb
: Optional callback to call when theArrayBuffer
is beingcollected.napi_finalize
provides more details.[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.[out] result
: Anapi_value
representing anode::Buffer
.
Returnsnapi_ok
if the API succeeded.
Some runtimes other than Node.js have dropped support for external buffers.On runtimes other than Node.js this method may returnnapi_no_external_buffers_allowed
to indicate that externalbuffers are not supported. One such runtime is Electron asdescribed in this issueelectron/issues/35801.
In order to maintain broadest compatibility with all runtimesyou may defineNODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
in your addon beforeincludes for the node-api headers. Doing so will hide the 2 functionsthat create external buffers. This will ensure a compilation erroroccurs if you accidentally use one of these methods.
This API allocates anode::Buffer
object and initializes it with databacked by the passed in buffer. While this is still a fully-supported datastructure, in most cases using aTypedArray
will suffice.
The API adds anapi_finalize
callback which will be called when the JavaScriptobject just created has been garbage collected.
For Node.js >=4Buffers
areUint8Array
s.
napi_create_object
#
napi_statusnapi_create_object(napi_env env, napi_value* result)
[in] env
: The environment that the API is invoked under.[out] result
: Anapi_value
representing a JavaScriptObject
.
Returnsnapi_ok
if the API succeeded.
This API allocates a default JavaScriptObject
.It is the equivalent of doingnew Object()
in JavaScript.
The JavaScriptObject
type is described inSection 6.1.7 of theECMAScript Language Specification.
napi_create_symbol
#
napi_statusnapi_create_symbol(napi_env env, napi_value description, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] description
: Optionalnapi_value
which refers to a JavaScriptstring
to be set as the description for the symbol.[out] result
: Anapi_value
representing a JavaScriptsymbol
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptsymbol
value from a UTF8-encoded C string.
The JavaScriptsymbol
type is described inSection 19.4of the ECMAScript Language Specification.
node_api_symbol_for
#
napi_statusnode_api_symbol_for(napi_env env,constchar* utf8description,size_t length, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] utf8description
: UTF-8 C string representing the text to be used as thedescription for the symbol.[in] length
: The length of the description string in bytes, orNAPI_AUTO_LENGTH
if it is null-terminated.[out] result
: Anapi_value
representing a JavaScriptsymbol
.
Returnsnapi_ok
if the API succeeded.
This API searches in the global registry for an existing symbol with the givendescription. If the symbol already exists it will be returned, otherwise a newsymbol will be created in the registry.
The JavaScriptsymbol
type is described inSection 19.4 of the ECMAScriptLanguage Specification.
napi_create_typedarray
#
napi_statusnapi_create_typedarray(napi_env env, napi_typedarray_type type,size_t length, napi_value arraybuffer,size_t byte_offset, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] type
: Scalar datatype of the elements within theTypedArray
.[in] length
: Number of elements in theTypedArray
.[in] arraybuffer
:ArrayBuffer
underlying the typed array.[in] byte_offset
: The byte offset within theArrayBuffer
from which tostart projecting theTypedArray
.[out] result
: Anapi_value
representing a JavaScriptTypedArray
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptTypedArray
object over an existingArrayBuffer
.TypedArray
objects provide an array-like view over anunderlying data buffer where each element has the same underlying binary scalardatatype.
It's required that(length * size_of_element) + byte_offset
shouldbe <= the size in bytes of the array passed in. If not, aRangeError
exceptionis raised.
JavaScriptTypedArray
objects are described inSection 22.2 of the ECMAScript Language Specification.
node_api_create_buffer_from_arraybuffer
#
napi_status NAPI_CDECLnode_api_create_buffer_from_arraybuffer(napi_env env, napi_value arraybuffer,size_t byte_offset,size_t byte_length, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] arraybuffer
: TheArrayBuffer
from which the buffer will be created.[in] byte_offset
: The byte offset within theArrayBuffer
from which to start creating the buffer.[in] byte_length
: The length in bytes of the buffer to be created from theArrayBuffer
.[out] result
: Anapi_value
representing the created JavaScriptBuffer
object.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptBuffer
object from an existingArrayBuffer
.TheBuffer
object is a Node.js-specific class that provides a way to work with binary data directly in JavaScript.
The byte range[byte_offset, byte_offset + byte_length)
must be within the bounds of theArrayBuffer
. Ifbyte_offset + byte_length
exceeds the size of theArrayBuffer
, aRangeError
exception is raised.
napi_create_dataview
#
napi_statusnapi_create_dataview(napi_env env,size_t byte_length, napi_value arraybuffer,size_t byte_offset, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] length
: Number of elements in theDataView
.[in] arraybuffer
:ArrayBuffer
underlying theDataView
.[in] byte_offset
: The byte offset within theArrayBuffer
from which tostart projecting theDataView
.[out] result
: Anapi_value
representing a JavaScriptDataView
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptDataView
object over an existingArrayBuffer
.DataView
objects provide an array-like view over an underlying data buffer,but one which allows items of different size and type in theArrayBuffer
.
It is required thatbyte_length + byte_offset
is less than or equal to thesize in bytes of the array passed in. If not, aRangeError
exception israised.
JavaScriptDataView
objects are described inSection 24.3 of the ECMAScript Language Specification.
Functions to convert from C types to Node-API#
napi_create_int32
#
napi_statusnapi_create_int32(napi_env env,int32_t value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: Integer value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded.
This API is used to convert from the Cint32_t
type to the JavaScriptnumber
type.
The JavaScriptnumber
type is described inSection 6.1.6 of the ECMAScript Language Specification.
napi_create_uint32
#
napi_statusnapi_create_uint32(napi_env env,uint32_t value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: Unsigned integer value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded.
This API is used to convert from the Cuint32_t
type to the JavaScriptnumber
type.
The JavaScriptnumber
type is described inSection 6.1.6 of the ECMAScript Language Specification.
napi_create_int64
#
napi_statusnapi_create_int64(napi_env env,int64_t value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: Integer value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded.
This API is used to convert from the Cint64_t
type to the JavaScriptnumber
type.
The JavaScriptnumber
type is described inSection 6.1.6of the ECMAScript Language Specification. Note the complete range ofint64_t
cannot be represented with full precision in JavaScript. Integer valuesoutside the range ofNumber.MIN_SAFE_INTEGER
-(2**53 - 1)
-Number.MAX_SAFE_INTEGER
(2**53 - 1)
will lose precision.
napi_create_double
#
napi_statusnapi_create_double(napi_env env,double value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: Double-precision value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded.
This API is used to convert from the Cdouble
type to the JavaScriptnumber
type.
The JavaScriptnumber
type is described inSection 6.1.6 of the ECMAScript Language Specification.
napi_create_bigint_int64
#
napi_statusnapi_create_bigint_int64(napi_env env,int64_t value, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] value
: Integer value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptBigInt
.
Returnsnapi_ok
if the API succeeded.
This API converts the Cint64_t
type to the JavaScriptBigInt
type.
napi_create_bigint_uint64
#
napi_statusnapi_create_bigint_uint64(napi_env env,uint64_t value, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] value
: Unsigned integer value to be represented in JavaScript.[out] result
: Anapi_value
representing a JavaScriptBigInt
.
Returnsnapi_ok
if the API succeeded.
This API converts the Cuint64_t
type to the JavaScriptBigInt
type.
napi_create_bigint_words
#
napi_statusnapi_create_bigint_words(napi_env env,int sign_bit,size_t word_count,constuint64_t* words, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] sign_bit
: Determines if the resultingBigInt
will be positive ornegative.[in] word_count
: The length of thewords
array.[in] words
: An array ofuint64_t
little-endian 64-bit words.[out] result
: Anapi_value
representing a JavaScriptBigInt
.
Returnsnapi_ok
if the API succeeded.
This API converts an array of unsigned 64-bit words into a singleBigInt
value.
The resultingBigInt
is calculated as: (–1)sign_bit
(words[0]
× (264)0 +words[1]
× (264)1 + …)
napi_create_string_latin1
#
napi_statusnapi_create_string_latin1(napi_env env,constchar* str,size_t length, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing an ISO-8859-1-encoded string.[in] length
: The length of the string in bytes, orNAPI_AUTO_LENGTH
if itis null-terminated.[out] result
: Anapi_value
representing a JavaScriptstring
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptstring
value from an ISO-8859-1-encoded Cstring. The native string is copied.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
node_api_create_external_string_latin1
#
napi_statusnode_api_create_external_string_latin1(napi_env env,char* str,size_t length, napi_finalize finalize_callback,void* finalize_hint, napi_value* result,bool* copied);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing an ISO-8859-1-encoded string.[in] length
: The length of the string in bytes, orNAPI_AUTO_LENGTH
if itis null-terminated.[in] finalize_callback
: The function to call when the string is beingcollected. The function will be called with the following parameters:[in] env
: The environment in which the add-on is running. This valuemay be null if the string is being collected as part of the terminationof the worker or the main Node.js instance.[in] data
: This is the valuestr
as avoid*
pointer.[in] finalize_hint
: This is the valuefinalize_hint
that was givento the API.napi_finalize
provides more details.This parameter is optional. Passing a null value means that the add-ondoesn't need to be notified when the corresponding JavaScript string iscollected.
[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.[out] result
: Anapi_value
representing a JavaScriptstring
.[out] copied
: Whether the string was copied. If it was, the finalizer willalready have been invoked to destroystr
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptstring
value from an ISO-8859-1-encoded Cstring. The native string may not be copied and must thus exist for the entirelife cycle of the JavaScript value.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
napi_create_string_utf16
#
napi_statusnapi_create_string_utf16(napi_env env,constchar16_t* str,size_t length, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing a UTF16-LE-encoded string.[in] length
: The length of the string in two-byte code units, orNAPI_AUTO_LENGTH
if it is null-terminated.[out] result
: Anapi_value
representing a JavaScriptstring
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptstring
value from a UTF16-LE-encoded C string.The native string is copied.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
node_api_create_external_string_utf16
#
napi_statusnode_api_create_external_string_utf16(napi_env env,char16_t* str,size_t length, napi_finalize finalize_callback,void* finalize_hint, napi_value* result,bool* copied);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing a UTF16-LE-encoded string.[in] length
: The length of the string in two-byte code units, orNAPI_AUTO_LENGTH
if it is null-terminated.[in] finalize_callback
: The function to call when the string is beingcollected. The function will be called with the following parameters:[in] env
: The environment in which the add-on is running. This valuemay be null if the string is being collected as part of the terminationof the worker or the main Node.js instance.[in] data
: This is the valuestr
as avoid*
pointer.[in] finalize_hint
: This is the valuefinalize_hint
that was givento the API.napi_finalize
provides more details.This parameter is optional. Passing a null value means that the add-ondoesn't need to be notified when the corresponding JavaScript string iscollected.
[in] finalize_hint
: Optional hint to pass to the finalize callback duringcollection.[out] result
: Anapi_value
representing a JavaScriptstring
.[out] copied
: Whether the string was copied. If it was, the finalizer willalready have been invoked to destroystr
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptstring
value from a UTF16-LE-encoded C string.The native string may not be copied and must thus exist for the entire lifecycle of the JavaScript value.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
napi_create_string_utf8
#
napi_statusnapi_create_string_utf8(napi_env env,constchar* str,size_t length, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing a UTF8-encoded string.[in] length
: The length of the string in bytes, orNAPI_AUTO_LENGTH
if itis null-terminated.[out] result
: Anapi_value
representing a JavaScriptstring
.
Returnsnapi_ok
if the API succeeded.
This API creates a JavaScriptstring
value from a UTF8-encoded C string.The native string is copied.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
Functions to create optimized property keys#
Many JavaScript engines including V8 use internalized strings as keysto set and get property values. They typically use a hash table to createand lookup such strings. While it adds some cost per key creation, it improvesthe performance after that by enabling comparison of string pointers insteadof the whole strings.
If a new JavaScript string is intended to be used as a property key, then forsome JavaScript engines it will be more efficient to use the functions in thissection. Otherwise, use thenapi_create_string_utf8
ornode_api_create_external_string_utf8
series functions as there may beadditional overhead in creating/storing strings with the property keycreation methods.
node_api_create_property_key_latin1
#
napi_status NAPI_CDECLnode_api_create_property_key_latin1(napi_env env,constchar* str,size_t length, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing an ISO-8859-1-encoded string.[in] length
: The length of the string in bytes, orNAPI_AUTO_LENGTH
if itis null-terminated.[out] result
: Anapi_value
representing an optimized JavaScriptstring
to be used as a property key for objects.
Returnsnapi_ok
if the API succeeded.
This API creates an optimized JavaScriptstring
value froman ISO-8859-1-encoded C string to be used as a property key for objects.The native string is copied. In contrast withnapi_create_string_latin1
,subsequent calls to this function with the samestr
pointer may benefit from a speedupin the creation of the requestednapi_value
, depending on the engine.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
node_api_create_property_key_utf16
#
napi_status NAPI_CDECLnode_api_create_property_key_utf16(napi_env env,constchar16_t* str,size_t length, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing a UTF16-LE-encoded string.[in] length
: The length of the string in two-byte code units, orNAPI_AUTO_LENGTH
if it is null-terminated.[out] result
: Anapi_value
representing an optimized JavaScriptstring
to be used as a property key for objects.
Returnsnapi_ok
if the API succeeded.
This API creates an optimized JavaScriptstring
value froma UTF16-LE-encoded C string to be used as a property key for objects.The native string is copied.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
node_api_create_property_key_utf8
#
napi_status NAPI_CDECLnode_api_create_property_key_utf8(napi_env env,constchar* str,size_t length, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] str
: Character buffer representing a UTF8-encoded string.[in] length
: The length of the string in two-byte code units, orNAPI_AUTO_LENGTH
if it is null-terminated.[out] result
: Anapi_value
representing an optimized JavaScriptstring
to be used as a property key for objects.
Returnsnapi_ok
if the API succeeded.
This API creates an optimized JavaScriptstring
value froma UTF8-encoded C string to be used as a property key for objects.The native string is copied.
The JavaScriptstring
type is described inSection 6.1.4 of the ECMAScript Language Specification.
Functions to convert from Node-API to C types#
napi_get_array_length
#
napi_statusnapi_get_array_length(napi_env env, napi_value value,uint32_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing the JavaScriptArray
whose length isbeing queried.[out] result
:uint32
representing length of the array.
Returnsnapi_ok
if the API succeeded.
This API returns the length of an array.
Array
length is described inSection 22.1.4.1 of the ECMAScript LanguageSpecification.
napi_get_arraybuffer_info
#
napi_statusnapi_get_arraybuffer_info(napi_env env, napi_value arraybuffer,void** data,size_t* byte_length)
[in] env
: The environment that the API is invoked under.[in] arraybuffer
:napi_value
representing theArrayBuffer
being queried.[out] data
: The underlying data buffer of theArrayBuffer
. If byte_lengthis0
, this may beNULL
or any other pointer value.[out] byte_length
: Length in bytes of the underlying data buffer.
Returnsnapi_ok
if the API succeeded.
This API is used to retrieve the underlying data buffer of anArrayBuffer
andits length.
WARNING: Use caution while using this API. The lifetime of the underlying databuffer is managed by theArrayBuffer
even after it's returned. Apossible safe way to use this API is in conjunction withnapi_create_reference
, which can be used to guarantee control over thelifetime of theArrayBuffer
. It's also safe to use the returned data bufferwithin the same callback as long as there are no calls to other APIs that mighttrigger a GC.
napi_get_buffer_info
#
napi_statusnapi_get_buffer_info(napi_env env, napi_value value,void** data,size_t* length)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing thenode::Buffer
orUint8Array
being queried.[out] data
: The underlying data buffer of thenode::Buffer
orUint8Array
. If length is0
, this may beNULL
or any other pointer value.[out] length
: Length in bytes of the underlying data buffer.
Returnsnapi_ok
if the API succeeded.
This method returns the identicaldata
andbyte_length
asnapi_get_typedarray_info
. Andnapi_get_typedarray_info
accepts anode::Buffer
(a Uint8Array) as the value too.
This API is used to retrieve the underlying data buffer of anode::Buffer
and its length.
Warning: Use caution while using this API since the underlying data buffer'slifetime is not guaranteed if it's managed by the VM.
napi_get_prototype
#
napi_statusnapi_get_prototype(napi_env env, napi_value object, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] object
:napi_value
representing JavaScriptObject
whose prototypeto return. This returns the equivalent ofObject.getPrototypeOf
(which isnot the same as the function'sprototype
property).[out] result
:napi_value
representing prototype of the given object.
Returnsnapi_ok
if the API succeeded.
napi_get_typedarray_info
#
napi_statusnapi_get_typedarray_info(napi_env env, napi_value typedarray, napi_typedarray_type* type,size_t* length,void** data, napi_value* arraybuffer,size_t* byte_offset)
[in] env
: The environment that the API is invoked under.[in] typedarray
:napi_value
representing theTypedArray
whoseproperties to query.[out] type
: Scalar datatype of the elements within theTypedArray
.[out] length
: The number of elements in theTypedArray
.[out] data
: The data buffer underlying theTypedArray
adjusted bythebyte_offset
value so that it points to the first element in theTypedArray
. If the length of the array is0
, this may beNULL
orany other pointer value.[out] arraybuffer
: TheArrayBuffer
underlying theTypedArray
.[out] byte_offset
: The byte offset within the underlying native arrayat which the first element of the arrays is located. The value for the dataparameter has already been adjusted so that data points to the first elementin the array. Therefore, the first byte of the native array would be atdata - byte_offset
.
Returnsnapi_ok
if the API succeeded.
This API returns various properties of a typed array.
Any of the out parameters may beNULL
if that property is unneeded.
Warning: Use caution while using this API since the underlying data bufferis managed by the VM.
napi_get_dataview_info
#
napi_statusnapi_get_dataview_info(napi_env env, napi_value dataview,size_t* byte_length,void** data, napi_value* arraybuffer,size_t* byte_offset)
[in] env
: The environment that the API is invoked under.[in] dataview
:napi_value
representing theDataView
whoseproperties to query.[out] byte_length
: Number of bytes in theDataView
.[out] data
: The data buffer underlying theDataView
.If byte_length is0
, this may beNULL
or any other pointer value.[out] arraybuffer
:ArrayBuffer
underlying theDataView
.[out] byte_offset
: The byte offset within the data buffer from whichto start projecting theDataView
.
Returnsnapi_ok
if the API succeeded.
Any of the out parameters may beNULL
if that property is unneeded.
This API returns various properties of aDataView
.
napi_get_date_value
#
napi_statusnapi_get_date_value(napi_env env, napi_value value,double* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing a JavaScriptDate
.[out] result
: Time value as adouble
represented as milliseconds sincemidnight at the beginning of 01 January, 1970 UTC.
This API does not observe leap seconds; they are ignored, asECMAScript aligns with POSIX time specification.
Returnsnapi_ok
if the API succeeded. If a non-datenapi_value
is passedin it returnsnapi_date_expected
.
This API returns the C double primitive of time value for the given JavaScriptDate
.
napi_get_value_bool
#
napi_statusnapi_get_value_bool(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptBoolean
.[out] result
: C boolean primitive equivalent of the given JavaScriptBoolean
.
Returnsnapi_ok
if the API succeeded. If a non-booleannapi_value
ispassed in it returnsnapi_boolean_expected
.
This API returns the C boolean primitive equivalent of the given JavaScriptBoolean
.
napi_get_value_double
#
napi_statusnapi_get_value_double(napi_env env, napi_value value,double* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptnumber
.[out] result
: C double primitive equivalent of the given JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded. If a non-numbernapi_value
is passedin it returnsnapi_number_expected
.
This API returns the C double primitive equivalent of the given JavaScriptnumber
.
napi_get_value_bigint_int64
#
napi_statusnapi_get_value_bigint_int64(napi_env env, napi_value value,int64_t* result,bool* lossless);
[in] env
: The environment that the API is invoked under[in] value
:napi_value
representing JavaScriptBigInt
.[out] result
: Cint64_t
primitive equivalent of the given JavaScriptBigInt
.[out] lossless
: Indicates whether theBigInt
value was convertedlosslessly.
Returnsnapi_ok
if the API succeeded. If a non-BigInt
is passed in itreturnsnapi_bigint_expected
.
This API returns the Cint64_t
primitive equivalent of the given JavaScriptBigInt
. If needed it will truncate the value, settinglossless
tofalse
.
napi_get_value_bigint_uint64
#
napi_statusnapi_get_value_bigint_uint64(napi_env env, napi_value value,uint64_t* result,bool* lossless);
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptBigInt
.[out] result
: Cuint64_t
primitive equivalent of the given JavaScriptBigInt
.[out] lossless
: Indicates whether theBigInt
value was convertedlosslessly.
Returnsnapi_ok
if the API succeeded. If a non-BigInt
is passed in itreturnsnapi_bigint_expected
.
This API returns the Cuint64_t
primitive equivalent of the given JavaScriptBigInt
. If needed it will truncate the value, settinglossless
tofalse
.
napi_get_value_bigint_words
#
napi_statusnapi_get_value_bigint_words(napi_env env, napi_value value,int* sign_bit,size_t* word_count,uint64_t* words);
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptBigInt
.[out] sign_bit
: Integer representing if the JavaScriptBigInt
is positiveor negative.[in/out] word_count
: Must be initialized to the length of thewords
array. Upon return, it will be set to the actual number of words thatwould be needed to store thisBigInt
.[out] words
: Pointer to a pre-allocated 64-bit word array.
Returnsnapi_ok
if the API succeeded.
This API converts a singleBigInt
value into a sign bit, 64-bit little-endianarray, and the number of elements in the array.sign_bit
andwords
may beboth set toNULL
, in order to get onlyword_count
.
napi_get_value_external
#
napi_statusnapi_get_value_external(napi_env env, napi_value value,void** result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScript external value.[out] result
: Pointer to the data wrapped by the JavaScript external value.
Returnsnapi_ok
if the API succeeded. If a non-externalnapi_value
ispassed in it returnsnapi_invalid_arg
.
This API retrieves the external data pointer that was previously passed tonapi_create_external()
.
napi_get_value_int32
#
napi_statusnapi_get_value_int32(napi_env env, napi_value value,int32_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptnumber
.[out] result
: Cint32
primitive equivalent of the given JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded. If a non-numbernapi_value
is passed innapi_number_expected
.
This API returns the Cint32
primitive equivalentof the given JavaScriptnumber
.
If the number exceeds the range of the 32 bit integer, then the result istruncated to the equivalent of the bottom 32 bits. This can result in a largepositive number becoming a negative number if the value is > 231 - 1.
Non-finite number values (NaN
,+Infinity
, or-Infinity
) set theresult to zero.
napi_get_value_int64
#
napi_statusnapi_get_value_int64(napi_env env, napi_value value,int64_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptnumber
.[out] result
: Cint64
primitive equivalent of the given JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded. If a non-numbernapi_value
is passed in it returnsnapi_number_expected
.
This API returns the Cint64
primitive equivalent of the given JavaScriptnumber
.
number
values outside the range ofNumber.MIN_SAFE_INTEGER
-(2**53 - 1)
-Number.MAX_SAFE_INTEGER
(2**53 - 1)
will loseprecision.
Non-finite number values (NaN
,+Infinity
, or-Infinity
) set theresult to zero.
napi_get_value_string_latin1
#
napi_statusnapi_get_value_string_latin1(napi_env env, napi_value value,char* buf,size_t bufsize,size_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScript string.[in] buf
: Buffer to write the ISO-8859-1-encoded string into. IfNULL
ispassed in, the length of the string in bytes and excluding the null terminatoris returned inresult
.[in] bufsize
: Size of the destination buffer. When this value isinsufficient, the returned string is truncated and null-terminated.If this value is zero, then the string is not returned and no changes are doneto the buffer.[out] result
: Number of bytes copied into the buffer, excluding the nullterminator.
Returnsnapi_ok
if the API succeeded. If a non-string
napi_value
is passed in it returnsnapi_string_expected
.
This API returns the ISO-8859-1-encoded string corresponding the value passedin.
napi_get_value_string_utf8
#
napi_statusnapi_get_value_string_utf8(napi_env env, napi_value value,char* buf,size_t bufsize,size_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScript string.[in] buf
: Buffer to write the UTF8-encoded string into. IfNULL
is passedin, the length of the string in bytes and excluding the null terminator isreturned inresult
.[in] bufsize
: Size of the destination buffer. When this value isinsufficient, the returned string is truncated and null-terminated.If this value is zero, then the string is not returned and no changes are doneto the buffer.[out] result
: Number of bytes copied into the buffer, excluding the nullterminator.
Returnsnapi_ok
if the API succeeded. If a non-string
napi_value
is passed in it returnsnapi_string_expected
.
This API returns the UTF8-encoded string corresponding the value passed in.
napi_get_value_string_utf16
#
napi_statusnapi_get_value_string_utf16(napi_env env, napi_value value,char16_t* buf,size_t bufsize,size_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScript string.[in] buf
: Buffer to write the UTF16-LE-encoded string into. IfNULL
ispassed in, the length of the string in 2-byte code units and excluding thenull terminator is returned.[in] bufsize
: Size of the destination buffer. When this value isinsufficient, the returned string is truncated and null-terminated.If this value is zero, then the string is not returned and no changes are doneto the buffer.[out] result
: Number of 2-byte code units copied into the buffer, excludingthe null terminator.
Returnsnapi_ok
if the API succeeded. If a non-string
napi_value
is passed in it returnsnapi_string_expected
.
This API returns the UTF16-encoded string corresponding the value passed in.
napi_get_value_uint32
#
napi_statusnapi_get_value_uint32(napi_env env, napi_value value,uint32_t* result)
[in] env
: The environment that the API is invoked under.[in] value
:napi_value
representing JavaScriptnumber
.[out] result
: C primitive equivalent of the givennapi_value
as auint32_t
.
Returnsnapi_ok
if the API succeeded. If a non-numbernapi_value
is passed in it returnsnapi_number_expected
.
This API returns the C primitive equivalent of the givennapi_value
as auint32_t
.
Functions to get global instances#
napi_get_boolean
#
napi_statusnapi_get_boolean(napi_env env,bool value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: The value of the boolean to retrieve.[out] result
:napi_value
representing JavaScriptBoolean
singleton toretrieve.
Returnsnapi_ok
if the API succeeded.
This API is used to return the JavaScript singleton object that is used torepresent the given boolean value.
napi_get_global
#
napi_statusnapi_get_global(napi_env env, napi_value* result)
[in] env
: The environment that the API is invoked under.[out] result
:napi_value
representing JavaScriptglobal
object.
Returnsnapi_ok
if the API succeeded.
This API returns theglobal
object.
napi_get_null
#
napi_statusnapi_get_null(napi_env env, napi_value* result)
[in] env
: The environment that the API is invoked under.[out] result
:napi_value
representing JavaScriptnull
object.
Returnsnapi_ok
if the API succeeded.
This API returns thenull
object.
napi_get_undefined
#
napi_statusnapi_get_undefined(napi_env env, napi_value* result)
[in] env
: The environment that the API is invoked under.[out] result
:napi_value
representing JavaScript Undefined value.
Returnsnapi_ok
if the API succeeded.
This API returns the Undefined object.
Working with JavaScript values and abstract operations#
Node-API exposes a set of APIs to perform some abstract operations on JavaScriptvalues. Some of these operations are documented underSection 7of theECMAScript Language Specification.
These APIs support doing one of the following:
- Coerce JavaScript values to specific JavaScript types (such as
number
orstring
). - Check the type of a JavaScript value.
- Check for equality between two JavaScript values.
napi_coerce_to_bool
#
napi_statusnapi_coerce_to_bool(napi_env env, napi_value value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to coerce.[out] result
:napi_value
representing the coerced JavaScriptBoolean
.
Returnsnapi_ok
if the API succeeded.
This API implements the abstract operationToBoolean()
as defined inSection 7.1.2 of the ECMAScript Language Specification.
napi_coerce_to_number
#
napi_statusnapi_coerce_to_number(napi_env env, napi_value value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to coerce.[out] result
:napi_value
representing the coerced JavaScriptnumber
.
Returnsnapi_ok
if the API succeeded.
This API implements the abstract operationToNumber()
as defined inSection 7.1.3 of the ECMAScript Language Specification.This function potentially runs JS code if the passed-in value is anobject.
napi_coerce_to_object
#
napi_statusnapi_coerce_to_object(napi_env env, napi_value value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to coerce.[out] result
:napi_value
representing the coerced JavaScriptObject
.
Returnsnapi_ok
if the API succeeded.
This API implements the abstract operationToObject()
as defined inSection 7.1.13 of the ECMAScript Language Specification.
napi_coerce_to_string
#
napi_statusnapi_coerce_to_string(napi_env env, napi_value value, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to coerce.[out] result
:napi_value
representing the coerced JavaScriptstring
.
Returnsnapi_ok
if the API succeeded.
This API implements the abstract operationToString()
as defined inSection 7.1.13 of the ECMAScript Language Specification.This function potentially runs JS code if the passed-in value is anobject.
napi_typeof
#
napi_statusnapi_typeof(napi_env env, napi_value value, napi_valuetype* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value whose type to query.[out] result
: The type of the JavaScript value.
Returnsnapi_ok
if the API succeeded.
napi_invalid_arg
if the type ofvalue
is not a known ECMAScript type andvalue
is not an External value.
This API represents behavior similar to invoking thetypeof
Operator onthe object as defined inSection 12.5.5 of the ECMAScript LanguageSpecification. However, there are some differences:
- It has support for detecting an External value.
- It detects
null
as a separate type, while ECMAScripttypeof
would detectobject
.
Ifvalue
has a type that is invalid, an error is returned.
napi_instanceof
#
napi_statusnapi_instanceof(napi_env env, napi_value object, napi_value constructor,bool* result)
[in] env
: The environment that the API is invoked under.[in] object
: The JavaScript value to check.[in] constructor
: The JavaScript function object of the constructor functionto check against.[out] result
: Boolean that is set to true ifobject instanceof constructor
is true.
Returnsnapi_ok
if the API succeeded.
This API represents invoking theinstanceof
Operator on the object asdefined inSection 12.10.4 of the ECMAScript Language Specification.
napi_is_array
#
napi_statusnapi_is_array(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the given object is an array.
Returnsnapi_ok
if the API succeeded.
This API represents invoking theIsArray
operation on the objectas defined inSection 7.2.2 of the ECMAScript Language Specification.
napi_is_arraybuffer
#
napi_statusnapi_is_arraybuffer(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the given object is anArrayBuffer
.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is an array buffer.
napi_is_buffer
#
napi_statusnapi_is_buffer(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the givennapi_value
represents anode::Buffer
orUint8Array
object.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is a buffer or Uint8Array.napi_is_typedarray
should be preferred if the caller needs to check if thevalue is a Uint8Array.
napi_is_date
#
napi_statusnapi_is_date(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the givennapi_value
represents a JavaScriptDate
object.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is a date.
napi_is_error
#
napi_statusnapi_is_error(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the givennapi_value
represents anError
object.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is anError
.
napi_is_typedarray
#
napi_statusnapi_is_typedarray(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the givennapi_value
represents aTypedArray
.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is a typed array.
napi_is_dataview
#
napi_statusnapi_is_dataview(napi_env env, napi_value value,bool* result)
[in] env
: The environment that the API is invoked under.[in] value
: The JavaScript value to check.[out] result
: Whether the givennapi_value
represents aDataView
.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in is aDataView
.
napi_strict_equals
#
napi_statusnapi_strict_equals(napi_env env, napi_value lhs, napi_value rhs,bool* result)
[in] env
: The environment that the API is invoked under.[in] lhs
: The JavaScript value to check.[in] rhs
: The JavaScript value to check against.[out] result
: Whether the twonapi_value
objects are equal.
Returnsnapi_ok
if the API succeeded.
This API represents the invocation of the Strict Equality algorithm asdefined inSection 7.2.14 of the ECMAScript Language Specification.
napi_detach_arraybuffer
#
napi_statusnapi_detach_arraybuffer(napi_env env, napi_value arraybuffer)
[in] env
: The environment that the API is invoked under.[in] arraybuffer
: The JavaScriptArrayBuffer
to be detached.
Returnsnapi_ok
if the API succeeded. If a non-detachableArrayBuffer
ispassed in it returnsnapi_detachable_arraybuffer_expected
.
Generally, anArrayBuffer
is non-detachable if it has been detached before.The engine may impose additional conditions on whether anArrayBuffer
isdetachable. For example, V8 requires that theArrayBuffer
be external,that is, created withnapi_create_external_arraybuffer
.
This API represents the invocation of theArrayBuffer
detach operation asdefined inSection 24.1.1.3 of the ECMAScript Language Specification.
napi_is_detached_arraybuffer
#
napi_statusnapi_is_detached_arraybuffer(napi_env env, napi_value arraybuffer,bool* result)
[in] env
: The environment that the API is invoked under.[in] arraybuffer
: The JavaScriptArrayBuffer
to be checked.[out] result
: Whether thearraybuffer
is detached.
Returnsnapi_ok
if the API succeeded.
TheArrayBuffer
is considered detached if its internal data isnull
.
This API represents the invocation of theArrayBuffer
IsDetachedBuffer
operation as defined inSection 24.1.1.2 of the ECMAScript LanguageSpecification.
Working with JavaScript properties#
Node-API exposes a set of APIs to get and set properties on JavaScriptobjects. Some of these types are documented underSection 7 of theECMAScript Language Specification.
Properties in JavaScript are represented as a tuple of a key and a value.Fundamentally, all property keys in Node-API can be represented in one of thefollowing forms:
- Named: a simple UTF8-encoded string
- Integer-Indexed: an index value represented by
uint32_t
- JavaScript value: these are represented in Node-API by
napi_value
. This canbe anapi_value
representing astring
,number
, orsymbol
.
Node-API values are represented by the typenapi_value
.Any Node-API call that requires a JavaScript value takes in anapi_value
.However, it's the caller's responsibility to make sure that thenapi_value
in question is of the JavaScript type expected by the API.
The APIs documented in this section provide a simple interface toget and set properties on arbitrary JavaScript objects represented bynapi_value
.
For instance, consider the following JavaScript code snippet:
const obj = {};obj.myProp =123;
The equivalent can be done using Node-API values with the following snippet:
napi_status status = napi_generic_failure;// const obj = {}napi_value obj, value;status = napi_create_object(env, &obj);if (status != napi_ok)return status;// Create a napi_value for 123status = napi_create_int32(env,123, &value);if (status != napi_ok)return status;// obj.myProp = 123status = napi_set_named_property(env, obj,"myProp", value);if (status != napi_ok)return status;
Indexed properties can be set in a similar manner. Consider the followingJavaScript snippet:
const arr = [];arr[123] ='hello';
The equivalent can be done using Node-API values with the following snippet:
napi_status status = napi_generic_failure;// const arr = [];napi_value arr, value;status = napi_create_array(env, &arr);if (status != napi_ok)return status;// Create a napi_value for 'hello'status = napi_create_string_utf8(env,"hello", NAPI_AUTO_LENGTH, &value);if (status != napi_ok)return status;// arr[123] = 'hello';status = napi_set_element(env, arr,123, value);if (status != napi_ok)return status;
Properties can be retrieved using the APIs described in this section.Consider the following JavaScript snippet:
const arr = [];const value = arr[123];
The following is the approximate equivalent of the Node-API counterpart:
napi_status status = napi_generic_failure;// const arr = []napi_value arr, value;status = napi_create_array(env, &arr);if (status != napi_ok)return status;// const value = arr[123]status = napi_get_element(env, arr,123, &value);if (status != napi_ok)return status;
Finally, multiple properties can also be defined on an object for performancereasons. Consider the following #"foo",NULL,NULL,NULL,NULL, fooValue, napi_writable | napi_configurable,NULL }, {"bar",NULL,NULL,NULL,NULL, barValue, napi_writable | napi_configurable,NULL }}status = napi_define_properties(env, obj,sizeof(descriptors) /sizeof(descriptors[0]), descriptors);if (status != napi_ok)return status;
Structures#
napi_property_attributes
#
History
Version | Changes |
---|---|
v14.12.0 | added |
typedefenum { napi_default =0, napi_writable =1 <<0, napi_enumerable =1 <<1, napi_configurable =1 <<2,// Used with napi_define_class to distinguish static properties// from instance properties. Ignored by napi_define_properties. napi_static =1 <<10,// Default for class methods. napi_default_method = napi_writable | napi_configurable,// Default for object properties, like in JS obj[prop]. napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable,} napi_property_attributes;
napi_property_attributes
are flags used to control the behavior of propertiesset on a JavaScript object. Other thannapi_static
they correspond to theattributes listed inSection 6.1.7.1of theECMAScript Language Specification.They can be one or more of the following bitflags:
napi_default
: No explicit attributes are set on the property. By default, aproperty is read only, not enumerable and not configurable.napi_writable
: The property is writable.napi_enumerable
: The property is enumerable.napi_configurable
: The property is configurable as defined inSection 6.1.7.1 of theECMAScript Language Specification.napi_static
: The property will be defined as a static property on a class asopposed to an instance property, which is the default. This is used only bynapi_define_class
. It is ignored bynapi_define_properties
.napi_default_method
: Like a method in a JS class, the property isconfigurable and writeable, but not enumerable.napi_default_jsproperty
: Like a property set via assignment in JavaScript,the property is writable, enumerable, and configurable.
napi_property_descriptor
#
typedefstruct {// One of utf8name or name should be NULL.constchar* utf8name; napi_value name; napi_callback method; napi_callback getter; napi_callback setter; napi_value value; napi_property_attributes attributes;void* data;} napi_property_descriptor;
utf8name
: Optional string describing the key for the property,encoded as UTF8. One ofutf8name
orname
must be provided for theproperty.name
: Optionalnapi_value
that points to a JavaScript string or symbolto be used as the key for the property. One ofutf8name
orname
mustbe provided for the property.value
: The value that's retrieved by a get access of the property if theproperty is a data property. If this is passed in, setgetter
,setter
,method
anddata
toNULL
(since these members won't be used).getter
: A function to call when a get access of the property is performed.If this is passed in, setvalue
andmethod
toNULL
(since these memberswon't be used). The given function is called implicitly by the runtime whenthe property is accessed from JavaScript code (or if a get on the property isperformed using a Node-API call).napi_callback
provides more details.setter
: A function to call when a set access of the property is performed.If this is passed in, setvalue
andmethod
toNULL
(since these memberswon't be used). The given function is called implicitly by the runtime whenthe property is set from JavaScript code (or if a set on the property isperformed using a Node-API call).napi_callback
provides more details.method
: Set this to make the property descriptor object'svalue
property to be a JavaScript function represented bymethod
. If this ispassed in, setvalue
,getter
andsetter
toNULL
(since these memberswon't be used).napi_callback
provides more details.attributes
: The attributes associated with the particular property. Seenapi_property_attributes
.data
: The callback data passed intomethod
,getter
andsetter
if thisfunction is invoked.
Functions#
napi_get_property_names
#
napi_statusnapi_get_property_names(napi_env env, napi_value object, napi_value* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the properties.[out] result
: Anapi_value
representing an array of JavaScript valuesthat represent the property names of the object. The API can be used toiterate overresult
usingnapi_get_array_length
andnapi_get_element
.
Returnsnapi_ok
if the API succeeded.
This API returns the names of the enumerable properties ofobject
as an arrayof strings. The properties ofobject
whose key is a symbol will not beincluded.
napi_get_all_property_names
#
napi_get_all_property_names(napi_env env, napi_value object, napi_key_collection_mode key_mode, napi_key_filter key_filter, napi_key_conversion key_conversion, napi_value* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the properties.[in] key_mode
: Whether to retrieve prototype properties as well.[in] key_filter
: Which properties to retrieve(enumerable/readable/writable).[in] key_conversion
: Whether to convert numbered property keys to strings.[out] result
: Anapi_value
representing an array of JavaScript valuesthat represent the property names of the object.napi_get_array_length
andnapi_get_element
can be used to iterate overresult
.
Returnsnapi_ok
if the API succeeded.
This API returns an array containing the names of the available propertiesof this object.
napi_set_property
#
napi_statusnapi_set_property(napi_env env, napi_value object, napi_value key, napi_value value);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object on which to set the property.[in] key
: The name of the property to set.[in] value
: The property value.
Returnsnapi_ok
if the API succeeded.
This API set a property on theObject
passed in.
napi_get_property
#
napi_statusnapi_get_property(napi_env env, napi_value object, napi_value key, napi_value* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the property.[in] key
: The name of the property to retrieve.[out] result
: The value of the property.
Returnsnapi_ok
if the API succeeded.
This API gets the requested property from theObject
passed in.
napi_has_property
#
napi_statusnapi_has_property(napi_env env, napi_value object, napi_value key,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] key
: The name of the property whose existence to check.[out] result
: Whether the property exists on the object or not.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in has the named property.
napi_delete_property
#
napi_statusnapi_delete_property(napi_env env, napi_value object, napi_value key,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] key
: The name of the property to delete.[out] result
: Whether the property deletion succeeded or not.result
canoptionally be ignored by passingNULL
.
Returnsnapi_ok
if the API succeeded.
This API attempts to delete thekey
own property fromobject
.
napi_has_own_property
#
napi_statusnapi_has_own_property(napi_env env, napi_value object, napi_value key,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] key
: The name of the own property whose existence to check.[out] result
: Whether the own property exists on the object or not.
Returnsnapi_ok
if the API succeeded.
This API checks if theObject
passed in has the named own property.key
mustbe astring
or asymbol
, or an error will be thrown. Node-API will notperform any conversion between data types.
napi_set_named_property
#
napi_statusnapi_set_named_property(napi_env env, napi_value object,constchar* utf8Name, napi_value value);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object on which to set the property.[in] utf8Name
: The name of the property to set.[in] value
: The property value.
Returnsnapi_ok
if the API succeeded.
This method is equivalent to callingnapi_set_property
with anapi_value
created from the string passed in asutf8Name
.
napi_get_named_property
#
napi_statusnapi_get_named_property(napi_env env, napi_value object,constchar* utf8Name, napi_value* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the property.[in] utf8Name
: The name of the property to get.[out] result
: The value of the property.
Returnsnapi_ok
if the API succeeded.
This method is equivalent to callingnapi_get_property
with anapi_value
created from the string passed in asutf8Name
.
napi_has_named_property
#
napi_statusnapi_has_named_property(napi_env env, napi_value object,constchar* utf8Name,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] utf8Name
: The name of the property whose existence to check.[out] result
: Whether the property exists on the object or not.
Returnsnapi_ok
if the API succeeded.
This method is equivalent to callingnapi_has_property
with anapi_value
created from the string passed in asutf8Name
.
napi_set_element
#
napi_statusnapi_set_element(napi_env env, napi_value object,uint32_t index, napi_value value);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to set the properties.[in] index
: The index of the property to set.[in] value
: The property value.
Returnsnapi_ok
if the API succeeded.
This API sets an element on theObject
passed in.
napi_get_element
#
napi_statusnapi_get_element(napi_env env, napi_value object,uint32_t index, napi_value* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the property.[in] index
: The index of the property to get.[out] result
: The value of the property.
Returnsnapi_ok
if the API succeeded.
This API gets the element at the requested index.
napi_has_element
#
napi_statusnapi_has_element(napi_env env, napi_value object,uint32_t index,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] index
: The index of the property whose existence to check.[out] result
: Whether the property exists on the object or not.
Returnsnapi_ok
if the API succeeded.
This API returns if theObject
passed in has an element at therequested index.
napi_delete_element
#
napi_statusnapi_delete_element(napi_env env, napi_value object,uint32_t index,bool* result);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to query.[in] index
: The index of the property to delete.[out] result
: Whether the element deletion succeeded or not.result
canoptionally be ignored by passingNULL
.
Returnsnapi_ok
if the API succeeded.
This API attempts to delete the specifiedindex
fromobject
.
napi_define_properties
#
napi_statusnapi_define_properties(napi_env env, napi_value object,size_t property_count,const napi_property_descriptor* properties);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object from which to retrieve the properties.[in] property_count
: The number of elements in theproperties
array.[in] properties
: The array of property descriptors.
Returnsnapi_ok
if the API succeeded.
This method allows the efficient definition of multiple properties on a givenobject. The properties are defined using property descriptors (seenapi_property_descriptor
). Given an array of such property descriptors,this API will set the properties on the object one at a time, as defined byDefineOwnProperty()
(described inSection 9.1.6 of the ECMA-262specification).
napi_object_freeze
#
napi_statusnapi_object_freeze(napi_env env, napi_value object);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to freeze.
Returnsnapi_ok
if the API succeeded.
This method freezes a given object. This prevents new properties frombeing added to it, existing properties from being removed, preventschanging the enumerability, configurability, or writability of existingproperties, and prevents the values of existing properties from being changed.It also prevents the object's prototype from being changed. This is describedinSection 19.1.2.6 of theECMA-262 specification.
napi_object_seal
#
napi_statusnapi_object_seal(napi_env env, napi_value object);
[in] env
: The environment that the Node-API call is invoked under.[in] object
: The object to seal.
Returnsnapi_ok
if the API succeeded.
This method seals a given object. This prevents new properties from beingadded to it, as well as marking all existing properties as non-configurable.This is described inSection 19.1.2.20of the ECMA-262 specification.
Working with JavaScript functions#
Node-API provides a set of APIs that allow JavaScript code tocall back into native code. Node-APIs that support calling backinto native code take in a callback functions represented bythenapi_callback
type. When the JavaScript VM calls back tonative code, thenapi_callback
function provided is invoked. The APIsdocumented in this section allow the callback function to do thefollowing:
- Get information about the context in which the callback was invoked.
- Get the arguments passed into the callback.
- Return a
napi_value
back from the callback.
Additionally, Node-API provides a set of functions which allow callingJavaScript functions from native code. One can either call a functionlike a regular JavaScript function call, or as a constructorfunction.
Any non-NULL
data which is passed to this API via thedata
field of thenapi_property_descriptor
items can be associated withobject
and freedwheneverobject
is garbage-collected by passing bothobject
and the data tonapi_add_finalizer
.
napi_call_function
#
NAPI_EXTERN napi_statusnapi_call_function(napi_env env, napi_value recv, napi_value func,size_t argc,const napi_value* argv, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] recv
: Thethis
value passed to the called function.[in] func
:napi_value
representing the JavaScript function to be invoked.[in] argc
: The count of elements in theargv
array.[in] argv
: Array ofnapi_values
representing JavaScript values passed inas arguments to the function.[out] result
:napi_value
representing the JavaScript object returned.
Returnsnapi_ok
if the API succeeded.
This method allows a JavaScript function object to be called from a nativeadd-on. This is the primary mechanism of calling backfrom the add-on'snative codeinto JavaScript. For the special case of calling into JavaScriptafter an async operation, seenapi_make_callback
.
A sample use case might look as follows. Consider the following JavaScriptsnippet:
functionAddTwo(num) {return num +2;}global.AddTwo =AddTwo;
Then, the above function can be invoked from a native add-on using thefollowing code:
// Get the function named "AddTwo" on the global objectnapi_value global, add_two, arg;napi_status status = napi_get_global(env, &global);if (status != napi_ok)return;status = napi_get_named_property(env, global,"AddTwo", &add_two);if (status != napi_ok)return;// const arg = 1337status = napi_create_int32(env,1337, &arg);if (status != napi_ok)return;napi_value* argv = &arg;size_t argc =1;// AddTwo(arg);napi_value return_val;status = napi_call_function(env, global, add_two, argc, argv, &return_val);if (status != napi_ok)return;// Convert the result back to a native typeint32_t result;status = napi_get_value_int32(env, return_val, &result);if (status != napi_ok)return;
napi_create_function
#
napi_statusnapi_create_function(napi_env env,constchar* utf8name,size_t length, napi_callback cb,void* data, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] utf8Name
: Optional name of the function encoded as UTF8. This isvisible within JavaScript as the new function object'sname
property.[in] length
: The length of theutf8name
in bytes, orNAPI_AUTO_LENGTH
ifit is null-terminated.[in] cb
: The native function which should be called when this functionobject is invoked.napi_callback
provides more details.[in] data
: User-provided data context. This will be passed back into thefunction when invoked later.[out] result
:napi_value
representing the JavaScript function object forthe newly created function.
Returnsnapi_ok
if the API succeeded.
This API allows an add-on author to create a function object in native code.This is the primary mechanism to allow callinginto the add-on's native codefrom JavaScript.
The newly created function is not automatically visible from script after thiscall. Instead, a property must be explicitly set on any object that is visibleto JavaScript, in order for the function to be accessible from script.
In order to expose a function as part of theadd-on's module exports, set the newly created function on the exportsobject. A sample module might look as follows:
napi_valueSayHello(napi_env env, napi_callback_info info) {printf("Hello\n");returnNULL;}napi_valueInit(napi_env env, napi_value exports) { napi_status status; napi_value fn; status = napi_create_function(env,NULL,0, SayHello,NULL, &fn);if (status != napi_ok)returnNULL; status = napi_set_named_property(env, exports,"sayHello", fn);if (status != napi_ok)returnNULL;return exports;}NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
Given the above code, the add-on can be used from JavaScript as follows:
const myaddon =require('./addon');myaddon.sayHello();
The string passed torequire()
is the name of the target inbinding.gyp
responsible for creating the.node
file.
Any non-NULL
data which is passed to this API via thedata
parameter canbe associated with the resulting JavaScript function (which is returned in theresult
parameter) and freed whenever the function is garbage-collected bypassing both the JavaScript function and the data tonapi_add_finalizer
.
JavaScriptFunction
s are described inSection 19.2 of the ECMAScriptLanguage Specification.
napi_get_cb_info
#
napi_statusnapi_get_cb_info(napi_env env, napi_callback_info cbinfo,size_t* argc, napi_value* argv, napi_value* thisArg,void** data)
[in] env
: The environment that the API is invoked under.[in] cbinfo
: The callback info passed into the callback function.[in-out] argc
: Specifies the length of the providedargv
array andreceives the actual count of arguments.argc
canoptionally be ignored by passingNULL
.[out] argv
: C array ofnapi_value
s to which the arguments will becopied. If there are more arguments than the provided count, only therequested number of arguments are copied. If there are fewer argumentsprovided than claimed, the rest ofargv
is filled withnapi_value
valuesthat representundefined
.argv
can optionally be ignored bypassingNULL
.[out] thisArg
: Receives the JavaScriptthis
argument for the call.thisArg
can optionally be ignored by passingNULL
.[out] data
: Receives the data pointer for the callback.data
canoptionally be ignored by passingNULL
.
Returnsnapi_ok
if the API succeeded.
This method is used within a callback function to retrieve details about thecall like the arguments and thethis
pointer from a given callback info.
napi_get_new_target
#
napi_statusnapi_get_new_target(napi_env env, napi_callback_info cbinfo, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] cbinfo
: The callback info passed into the callback function.[out] result
: Thenew.target
of the constructor call.
Returnsnapi_ok
if the API succeeded.
This API returns thenew.target
of the constructor call. If the currentcallback is not a constructor call, the result isNULL
.
napi_new_instance
#
napi_statusnapi_new_instance(napi_env env, napi_value cons,size_t argc, napi_value* argv, napi_value* result)
[in] env
: The environment that the API is invoked under.[in] cons
:napi_value
representing the JavaScript function to be invokedas a constructor.[in] argc
: The count of elements in theargv
array.[in] argv
: Array of JavaScript values asnapi_value
representing thearguments to the constructor. Ifargc
is zero this parameter may beomitted by passing inNULL
.[out] result
:napi_value
representing the JavaScript object returned,which in this case is the constructed object.
This method is used to instantiate a new JavaScript value using a givennapi_value
that represents the constructor for the object. For example,consider the following snippet:
functionMyObject(param) {this.param = param;}const arg ='hello';const value =newMyObject(arg);
The following can be approximated in Node-API using the following snippet:
// Get the constructor function MyObjectnapi_value global, constructor, arg, value;napi_status status = napi_get_global(env, &global);if (status != napi_ok)return;status = napi_get_named_property(env, global,"MyObject", &constructor);if (status != napi_ok)return;// const arg = "hello"status = napi_create_string_utf8(env,"hello", NAPI_AUTO_LENGTH, &arg);if (status != napi_ok)return;napi_value* argv = &arg;size_t argc =1;// const value = new MyObject(arg)status = napi_new_instance(env, constructor, argc, argv, &value);
Returnsnapi_ok
if the API succeeded.
Object wrap#
Node-API offers a way to "wrap" C++ classes and instances so that the classconstructor and methods can be called from JavaScript.
- The
napi_define_class
API defines a JavaScript class with constructor,static properties and methods, and instance properties and methods thatcorrespond to the C++ class. - When JavaScript code invokes the constructor, the constructor callbackuses
napi_wrap
to wrap a new C++ instance in a JavaScript object,then returns the wrapper object. - When JavaScript code invokes a method or property accessor on the class,the corresponding
napi_callback
C++ function is invoked. For an instancecallback,napi_unwrap
obtains the C++ instance that is the target ofthe call.
For wrapped objects it may be difficult to distinguish between a functioncalled on a class prototype and a function called on an instance of a class.A common pattern used to address this problem is to save a persistentreference to the class constructor for laterinstanceof
checks.
napi_value MyClass_constructor =NULL;status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);assert(napi_ok == status);bool is_instance =false;status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);assert(napi_ok == status);if (is_instance) {// napi_unwrap() ...}else {// otherwise...}
The reference must be freed once it is no longer needed.
There are occasions wherenapi_instanceof()
is insufficient for ensuring thata JavaScript object is a wrapper for a certain native type. This is the caseespecially when wrapped JavaScript objects are passed back into the addon viastatic methods rather than as thethis
value of prototype methods. In suchcases there is a chance that they may be unwrapped incorrectly.
const myAddon =require('./build/Release/my_addon.node');// `openDatabase()` returns a JavaScript object that wraps a native database// handle.const dbHandle = myAddon.openDatabase();// `query()` returns a JavaScript object that wraps a native query handle.const queryHandle = myAddon.query(dbHandle,'Gimme ALL the things!');// There is an accidental error in the line below. The first parameter to// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not// the query handle (`query`), so the correct condition for the while-loop// should be//// myAddon.queryHasRecords(dbHandle, queryHandle)//while (myAddon.queryHasRecords(queryHandle, dbHandle)) {// retrieve records}
In the above examplemyAddon.queryHasRecords()
is a method that accepts twoarguments. The first is a database handle and the second is a query handle.Internally, it unwraps the first argument and casts the resulting pointer to anative database handle. It then unwraps the second argument and casts theresulting pointer to a query handle. If the arguments are passed in the wrongorder, the casts will work, however, there is a good chance that the underlyingdatabase operation will fail, or will even cause an invalid memory access.
To ensure that the pointer retrieved from the first argument is indeed a pointerto a database handle and, similarly, that the pointer retrieved from the secondargument is indeed a pointer to a query handle, the implementation ofqueryHasRecords()
has to perform a type validation. Retaining the JavaScriptclass constructor from which the database handle was instantiated and theconstructor from which the query handle was instantiated innapi_ref
s canhelp, becausenapi_instanceof()
can then be used to ensure that the instancespassed intoqueryHashRecords()
are indeed of the correct type.
Unfortunately,napi_instanceof()
does not protect against prototypemanipulation. For example, the prototype of the database handle instance can beset to the prototype of the constructor for query handle instances. In thiscase, the database handle instance can appear as a query handle instance, and itwill pass thenapi_instanceof()
test for a query handle instance, while stillcontaining a pointer to a database handle.
To this end, Node-API provides type-tagging capabilities.
A type tag is a 128-bit integer unique to the addon. Node-API provides thenapi_type_tag
structure for storing a type tag. When such a value is passedalong with a JavaScript object orexternal stored in anapi_value
tonapi_type_tag_object()
, the JavaScript object will be "marked" with thetype tag. The "mark" is invisible on the JavaScript side. When a JavaScriptobject arrives into a native binding,napi_check_object_type_tag()
can be usedalong with the original type tag to determine whether the JavaScript object waspreviously "marked" with the type tag. This creates a type-checking capabilityof a higher fidelity thannapi_instanceof()
can provide, because such type-tagging survives prototype manipulation and addon unloading/reloading.
Continuing the above example, the following skeleton addon implementationillustrates the use ofnapi_type_tag_object()
andnapi_check_object_type_tag()
.
// This value is the type tag for a database handle. The command//// uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\1, 0x\2/'//// can be used to obtain the two values with which to initialize the structure.staticconst napi_type_tag DatabaseHandleTypeTag = {0x1edf75a38336451d,0xa5ed9ce2e4c00c38};// This value is the type tag for a query handle.staticconst napi_type_tag QueryHandleTypeTag = {0x9c73317f9fad44a3,0x93c3920bf3b0ad6a};static napi_valueopenDatabase(napi_env env, napi_callback_info info) { napi_status status; napi_value result;// Perform the underlying action which results in a database handle. DatabaseHandle* dbHandle = open_database();// Create a new, empty JS object. status = napi_create_object(env, &result);if (status != napi_ok)returnNULL;// Tag the object to indicate that it holds a pointer to a `DatabaseHandle`. status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);if (status != napi_ok)returnNULL;// Store the pointer to the `DatabaseHandle` structure inside the JS object. status = napi_wrap(env, result, dbHandle,NULL,NULL,NULL);if (status != napi_ok)returnNULL;return result;}// Later when we receive a JavaScript object purporting to be a database handle// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a// handle.static napi_valuequery(napi_env env, napi_callback_info info) { napi_status status;size_t argc =2; napi_value argv[2];bool is_db_handle; status = napi_get_cb_info(env, info, &argc, argv,NULL,NULL);if (status != napi_ok)returnNULL;// Check that the object passed as the first parameter has the previously// applied tag. status = napi_check_object_type_tag(env, argv[0], &DatabaseHandleTypeTag, &is_db_handle);if (status != napi_ok)returnNULL;// Throw a `TypeError` if it doesn't.if (!is_db_handle) {// Throw a TypeError.returnNULL; }}
napi_define_class
#
napi_statusnapi_define_class(napi_env env,constchar* utf8name,size_t length, napi_callback constructor,void* data,size_t property_count,const napi_property_descriptor* properties, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] utf8name
: Name of the JavaScript constructor function. For clarity,it is recommended to use the C++ class name when wrapping a C++ class.[in] length
: The length of theutf8name
in bytes, orNAPI_AUTO_LENGTH
if it is null-terminated.[in] constructor
: Callback function that handles constructing instancesof the class. When wrapping a C++ class, this method must be a static memberwith thenapi_callback
signature. A C++ class constructor cannot beused.napi_callback
provides more details.[in] data
: Optional data to be passed to the constructor callback asthedata
property of the callback info.[in] property_count
: Number of items in theproperties
array argument.[in] properties
: Array of property descriptors describing static andinstance data properties, accessors, and methods on the classSeenapi_property_descriptor
.[out] result
: Anapi_value
representing the constructor function forthe class.
Returnsnapi_ok
if the API succeeded.
Defines a JavaScript class, including:
- A JavaScript constructor function that has the class name. When wrapping acorresponding C++ class, the callback passed via
constructor
can be used toinstantiate a new C++ class instance, which can then be placed inside theJavaScript object instance being constructed usingnapi_wrap
. - Properties on the constructor function whose implementation can callcorrespondingstatic data properties, accessors, and methods of the C++class (defined by property descriptors with the
napi_static
attribute). - Properties on the constructor function's
prototype
object. When wrapping aC++ class,non-static data properties, accessors, and methods of the C++class can be called from the static functions given in the propertydescriptors without thenapi_static
attribute after retrieving the C++ classinstance placed inside the JavaScript object instance by usingnapi_unwrap
.
When wrapping a C++ class, the C++ constructor callback passed viaconstructor
should be a static method on the class that calls the actual class constructor,then wraps the new C++ instance in a JavaScript object, and returns the wrapperobject. Seenapi_wrap
for details.
The JavaScript constructor function returned fromnapi_define_class
isoften saved and used later to construct new instances of the class from nativecode, and/or to check whether provided values are instances of the class. Inthat case, to prevent the function value from being garbage-collected, astrong persistent reference to it can be created usingnapi_create_reference
, ensuring that the reference count is kept >= 1.
Any non-NULL
data which is passed to this API via thedata
parameter or viathedata
field of thenapi_property_descriptor
array items can be associatedwith the resulting JavaScript constructor (which is returned in theresult
parameter) and freed whenever the class is garbage-collected by passing boththe JavaScript function and the data tonapi_add_finalizer
.
napi_wrap
#
napi_statusnapi_wrap(napi_env env, napi_value js_object,void* native_object, napi_finalize finalize_cb,void* finalize_hint, napi_ref* result);
[in] env
: The environment that the API is invoked under.[in] js_object
: The JavaScript object that will be the wrapper for thenative object.[in] native_object
: The native instance that will be wrapped in theJavaScript object.[in] finalize_cb
: Optional native callback that can be used to free thenative instance when the JavaScript object has been garbage-collected.napi_finalize
provides more details.[in] finalize_hint
: Optional contextual hint that is passed to thefinalize callback.[out] result
: Optional reference to the wrapped object.
Returnsnapi_ok
if the API succeeded.
Wraps a native instance in a JavaScript object. The native instance can beretrieved later usingnapi_unwrap()
.
When JavaScript code invokes a constructor for a class that was defined usingnapi_define_class()
, thenapi_callback
for the constructor is invoked.After constructing an instance of the native class, the callback must then callnapi_wrap()
to wrap the newly constructed instance in the already-createdJavaScript object that is thethis
argument to the constructor callback.(Thatthis
object was created from the constructor function'sprototype
,so it already has definitions of all the instance properties and methods.)
Typically when wrapping a class instance, a finalize callback should beprovided that simply deletes the native instance that is received as thedata
argument to the finalize callback.
The optional returned reference is initially a weak reference, meaning ithas a reference count of 0. Typically this reference count would be incrementedtemporarily during async operations that require the instance to remain valid.
Caution: The optional returned reference (if obtained) should be deleted vianapi_delete_reference
ONLY in response to the finalize callbackinvocation. If it is deleted before then, then the finalize callback may neverbe invoked. Therefore, when obtaining a reference a finalize callback is alsorequired in order to enable correct disposal of the reference.
Finalizer callbacks may be deferred, leaving a window where the object hasbeen garbage collected (and the weak reference is invalid) but the finalizerhasn't been called yet. When usingnapi_get_reference_value()
on weakreferences returned bynapi_wrap()
, you should still handle an empty result.
Callingnapi_wrap()
a second time on an object will return an error. Toassociate another native instance with the object, usenapi_remove_wrap()
first.
napi_unwrap
#
napi_statusnapi_unwrap(napi_env env, napi_value js_object,void** result);
[in] env
: The environment that the API is invoked under.[in] js_object
: The object associated with the native instance.[out] result
: Pointer to the wrapped native instance.
Returnsnapi_ok
if the API succeeded.
Retrieves a native instance that was previously wrapped in a JavaScriptobject usingnapi_wrap()
.
When JavaScript code invokes a method or property accessor on the class, thecorrespondingnapi_callback
is invoked. If the callback is for an instancemethod or accessor, then thethis
argument to the callback is the wrapperobject; the wrapped C++ instance that is the target of the call can be obtainedthen by callingnapi_unwrap()
on the wrapper object.
napi_remove_wrap
#
napi_statusnapi_remove_wrap(napi_env env, napi_value js_object,void** result);
[in] env
: The environment that the API is invoked under.[in] js_object
: The object associated with the native instance.[out] result
: Pointer to the wrapped native instance.
Returnsnapi_ok
if the API succeeded.
Retrieves a native instance that was previously wrapped in the JavaScriptobjectjs_object
usingnapi_wrap()
and removes the wrapping. If a finalizecallback was associated with the wrapping, it will no longer be called when theJavaScript object becomes garbage-collected.
napi_type_tag_object
#
napi_statusnapi_type_tag_object(napi_env env, napi_value js_object,const napi_type_tag* type_tag);
[in] env
: The environment that the API is invoked under.[in] js_object
: The JavaScript object orexternal to be marked.[in] type_tag
: The tag with which the object is to be marked.
Returnsnapi_ok
if the API succeeded.
Associates the value of thetype_tag
pointer with the JavaScript object orexternal.napi_check_object_type_tag()
can then be used to compare the tagthat was attached to the object with one owned by the addon to ensure that theobject has the right type.
If the object already has an associated type tag, this API will returnnapi_invalid_arg
.
napi_check_object_type_tag
#
napi_statusnapi_check_object_type_tag(napi_env env, napi_value js_object,const napi_type_tag* type_tag,bool* result);
[in] env
: The environment that the API is invoked under.[in] js_object
: The JavaScript object orexternal whose type tag toexamine.[in] type_tag
: The tag with which to compare any tag found on the object.[out] result
: Whether the type tag given matched the type tag on theobject.false
is also returned if no type tag was found on the object.
Returnsnapi_ok
if the API succeeded.
Compares the pointer given astype_tag
with any that can be found onjs_object
. If no tag is found onjs_object
or, if a tag is found but it doesnot matchtype_tag
, thenresult
is set tofalse
. If a tag is found and itmatchestype_tag
, thenresult
is set totrue
.
napi_add_finalizer
#
napi_statusnapi_add_finalizer(napi_env env, napi_value js_object,void* finalize_data, node_api_basic_finalize finalize_cb,void* finalize_hint, napi_ref* result);
[in] env
: The environment that the API is invoked under.[in] js_object
: The JavaScript object to which the native data will beattached.[in] finalize_data
: Optional data to be passed tofinalize_cb
.[in] finalize_cb
: Native callback that will be used to free thenative data when the JavaScript object has been garbage-collected.napi_finalize
provides more details.[in] finalize_hint
: Optional contextual hint that is passed to thefinalize callback.[out] result
: Optional reference to the JavaScript object.
Returnsnapi_ok
if the API succeeded.
Adds anapi_finalize
callback which will be called when the JavaScript objectinjs_object
has been garbage-collected.
This API can be called multiple times on a single JavaScript object.
Caution: The optional returned reference (if obtained) should be deleted vianapi_delete_reference
ONLY in response to the finalize callbackinvocation. If it is deleted before then, then the finalize callback may neverbe invoked. Therefore, when obtaining a reference a finalize callback is alsorequired in order to enable correct disposal of the reference.
node_api_post_finalizer
#
napi_statusnode_api_post_finalizer(node_api_basic_env env, napi_finalize finalize_cb,void* finalize_data,void* finalize_hint);
[in] env
: The environment that the API is invoked under.[in] finalize_cb
: Native callback that will be used to free thenative data when the JavaScript object has been garbage-collected.napi_finalize
provides more details.[in] finalize_data
: Optional data to be passed tofinalize_cb
.[in] finalize_hint
: Optional contextual hint that is passed to thefinalize callback.
Returnsnapi_ok
if the API succeeded.
Schedules anapi_finalize
callback to be called asynchronously in theevent loop.
Normally, finalizers are called while the GC (garbage collector) collectsobjects. At that point calling any Node-API that may cause changes in the GCstate will be disabled and will crash Node.js.
node_api_post_finalizer
helps to work around this limitation by allowing theadd-on to defer calls to such Node-APIs to a point in time outside of the GCfinalization.
Simple asynchronous operations#
Addon modules often need to leverage async helpers from libuv as part of theirimplementation. This allows them to schedule work to be executed asynchronouslyso that their methods can return in advance of the work being completed. Thisallows them to avoid blocking overall execution of the Node.js application.
Node-API provides an ABI-stable interface for thesesupporting functions which covers the most common asynchronous use cases.
Node-API defines thenapi_async_work
structure which is used to manageasynchronous workers. Instances are created/deleted withnapi_create_async_work
andnapi_delete_async_work
.
Theexecute
andcomplete
callbacks are functions that will beinvoked when the executor is ready to execute and when it completes itstask respectively.
Theexecute
function should avoid making any Node-API callsthat could result in the execution of JavaScript or interaction withJavaScript objects. Most often, any code that needs to make Node-APIcalls should be made incomplete
callback instead.Avoid using thenapi_env
parameter in the execute callback asit will likely execute JavaScript.
These functions implement the following interfaces:
typedefvoid(*napi_async_execute_callback)(napi_env env,void* data);typedefvoid(*napi_async_complete_callback)(napi_env env, napi_status status,void* data);
When these methods are invoked, thedata
parameter passed will be theaddon-providedvoid*
data that was passed into thenapi_create_async_work
call.
Once created the async worker can be queuedfor execution using thenapi_queue_async_work
function:
napi_statusnapi_queue_async_work(node_api_basic_env env, napi_async_work work);
napi_cancel_async_work
can be used if the work needsto be cancelled before the work has started execution.
After callingnapi_cancel_async_work
, thecomplete
callbackwill be invoked with a status value ofnapi_cancelled
.The work should not be deleted before thecomplete
callback invocation, even when it was cancelled.
napi_create_async_work
#
History
Version | Changes |
---|---|
v8.6.0 | Added |
v8.0.0 | Added in: v8.0.0 |
napi_statusnapi_create_async_work(napi_env env, napi_value async_resource, napi_value async_resource_name, napi_async_execute_callback execute, napi_async_complete_callback complete,void* data, napi_async_work* result);
[in] env
: The environment that the API is invoked under.[in] async_resource
: An optional object associated with the async workthat will be passed to possibleasync_hooks
init
hooks.[in] async_resource_name
: Identifier for the kind of resource that is beingprovided for diagnostic information exposed by theasync_hooks
API.[in] execute
: The native function which should be called to execute thelogic asynchronously. The given function is called from a worker pool threadand can execute in parallel with the main event loop thread.[in] complete
: The native function which will be called when theasynchronous logic is completed or is cancelled. The given function is calledfrom the main event loop thread.napi_async_complete_callback
providesmore details.[in] data
: User-provided data context. This will be passed back into theexecute and complete functions.[out] result
:napi_async_work*
which is the handle to the newly createdasync work.
Returnsnapi_ok
if the API succeeded.
This API allocates a work object that is used to execute logic asynchronously.It should be freed usingnapi_delete_async_work
once the work is no longerrequired.
async_resource_name
should be a null-terminated, UTF-8-encoded string.
Theasync_resource_name
identifier is provided by the user and should berepresentative of the type of async work being performed. It is also recommendedto apply namespacing to the identifier, e.g. by including the module name. Seetheasync_hooks
documentation for more information.
napi_delete_async_work
#
napi_statusnapi_delete_async_work(napi_env env, napi_async_work work);
[in] env
: The environment that the API is invoked under.[in] work
: The handle returned by the call tonapi_create_async_work
.
Returnsnapi_ok
if the API succeeded.
This API frees a previously allocated work object.
This API can be called even if there is a pending JavaScript exception.
napi_queue_async_work
#
napi_statusnapi_queue_async_work(node_api_basic_env env, napi_async_work work);
[in] env
: The environment that the API is invoked under.[in] work
: The handle returned by the call tonapi_create_async_work
.
Returnsnapi_ok
if the API succeeded.
This API requests that the previously allocated work be scheduledfor execution. Once it returns successfully, this API must not be called againwith the samenapi_async_work
item or the result will be undefined.
napi_cancel_async_work
#
napi_statusnapi_cancel_async_work(node_api_basic_env env, napi_async_work work);
[in] env
: The environment that the API is invoked under.[in] work
: The handle returned by the call tonapi_create_async_work
.
Returnsnapi_ok
if the API succeeded.
This API cancels queued work if it has not yetbeen started. If it has already started executing, it cannot becancelled andnapi_generic_failure
will be returned. If successful,thecomplete
callback will be invoked with a status value ofnapi_cancelled
. The work should not be deleted before thecomplete
callback invocation, even if it has been successfully cancelled.
This API can be called even if there is a pending JavaScript exception.
Custom asynchronous operations#
The simple asynchronous work APIs above may not be appropriate for everyscenario. When using any other asynchronous mechanism, the following APIsare necessary to ensure an asynchronous operation is properly tracked bythe runtime.
napi_async_init
#
napi_statusnapi_async_init(napi_env env, napi_value async_resource, napi_value async_resource_name, napi_async_context* result)
[in] env
: The environment that the API is invoked under.[in] async_resource
: Object associated with the async workthat will be passed to possibleasync_hooks
init
hooks and can beaccessed byasync_hooks.executionAsyncResource()
.[in] async_resource_name
: Identifier for the kind of resource that is beingprovided for diagnostic information exposed by theasync_hooks
API.[out] result
: The initialized async context.
Returnsnapi_ok
if the API succeeded.
Theasync_resource
object needs to be kept alive untilnapi_async_destroy
to keepasync_hooks
related API acts correctly. Inorder to retain ABI compatibility with previous versions,napi_async_context
sare not maintaining the strong reference to theasync_resource
objects toavoid introducing causing memory leaks. However, if theasync_resource
isgarbage collected by JavaScript engine before thenapi_async_context
wasdestroyed bynapi_async_destroy
, callingnapi_async_context
related APIslikenapi_open_callback_scope
andnapi_make_callback
can causeproblems like loss of async context when using theAsyncLocalStorage
API.
In order to retain ABI compatibility with previous versions, passingNULL
forasync_resource
does not result in an error. However, this is notrecommended as this will result in undesirable behavior withasync_hooks
init
hooks andasync_hooks.executionAsyncResource()
as the resource isnow required by the underlyingasync_hooks
implementation in order to providethe linkage between async callbacks.
napi_async_destroy
#
napi_statusnapi_async_destroy(napi_env env, napi_async_context async_context);
[in] env
: The environment that the API is invoked under.[in] async_context
: The async context to be destroyed.
Returnsnapi_ok
if the API succeeded.
This API can be called even if there is a pending JavaScript exception.
napi_make_callback
#
History
Version | Changes |
---|---|
v8.6.0 | Added |
v8.0.0 | Added in: v8.0.0 |
NAPI_EXTERN napi_statusnapi_make_callback(napi_env env, napi_async_context async_context, napi_value recv, napi_value func,size_t argc,const napi_value* argv, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] async_context
: Context for the async operation that isinvoking the callback. This should normally be a value previouslyobtained fromnapi_async_init
.In order to retain ABI compatibility with previous versions, passingNULL
forasync_context
does not result in an error. However, this resultsin incorrect operation of async hooks. Potential issues include loss ofasync context when using theAsyncLocalStorage
API.[in] recv
: Thethis
value passed to the called function.[in] func
:napi_value
representing the JavaScript function to be invoked.[in] argc
: The count of elements in theargv
array.[in] argv
: Array of JavaScript values asnapi_value
representing thearguments to the function. Ifargc
is zero this parameter may beomitted by passing inNULL
.[out] result
:napi_value
representing the JavaScript object returned.
Returnsnapi_ok
if the API succeeded.
This method allows a JavaScript function object to be called from a nativeadd-on. This API is similar tonapi_call_function
. However, it is used to callfrom native code backinto JavaScriptafter returning from an asyncoperation (when there is no other script on the stack). It is a fairly simplewrapper aroundnode::MakeCallback
.
Note it isnot necessary to usenapi_make_callback
from within anapi_async_complete_callback
; in that situation the callback's asynccontext has already been set up, so a direct call tonapi_call_function
is sufficient and appropriate. Use of thenapi_make_callback
functionmay be required when implementing custom async behavior that does not usenapi_create_async_work
.
Anyprocess.nextTick
s or Promises scheduled on the microtask queue byJavaScript during the callback are ran before returning back to C/C++.
napi_open_callback_scope
#
NAPI_EXTERN napi_statusnapi_open_callback_scope(napi_env env, napi_value resource_object, napi_async_context context, napi_callback_scope* result)
[in] env
: The environment that the API is invoked under.[in] resource_object
: An object associated with the async workthat will be passed to possibleasync_hooks
init
hooks. Thisparameter has been deprecated and is ignored at runtime. Use theasync_resource
parameter innapi_async_init
instead.[in] context
: Context for the async operation that is invoking the callback.This should be a value previously obtained fromnapi_async_init
.[out] result
: The newly created scope.
There are cases (for example, resolving promises) where it isnecessary to have the equivalent of the scope associated with a callbackin place when making certain Node-API calls. If there is no other script onthe stack thenapi_open_callback_scope
andnapi_close_callback_scope
functions can be used to open/closethe required scope.
napi_close_callback_scope
#
NAPI_EXTERN napi_statusnapi_close_callback_scope(napi_env env, napi_callback_scope scope)
[in] env
: The environment that the API is invoked under.[in] scope
: The scope to be closed.
This API can be called even if there is a pending JavaScript exception.
Version management#
napi_get_node_version
#
typedefstruct {uint32_t major;uint32_t minor;uint32_t patch;constchar* release;} napi_node_version;napi_statusnapi_get_node_version(node_api_basic_env env,const napi_node_version** version);
[in] env
: The environment that the API is invoked under.[out] version
: A pointer to version information for Node.js itself.
Returnsnapi_ok
if the API succeeded.
This function fills theversion
struct with the major, minor, and patchversion of Node.js that is currently running, and therelease
field with thevalue ofprocess.release.name
.
The returned buffer is statically allocated and does not need to be freed.
napi_get_version
#
napi_statusnapi_get_version(node_api_basic_env env,uint32_t* result);
[in] env
: The environment that the API is invoked under.[out] result
: The highest version of Node-API supported.
Returnsnapi_ok
if the API succeeded.
This API returns the highest Node-API version supported by theNode.js runtime. Node-API is planned to be additive such thatnewer releases of Node.js may support additional API functions.In order to allow an addon to use a newer function when running withversions of Node.js that support it, while providingfallback behavior when running with Node.js versions that don'tsupport it:
- Call
napi_get_version()
to determine if the API is available. - If available, dynamically load a pointer to the function using
uv_dlsym()
. - Use the dynamically loaded pointer to invoke the function.
- If the function is not available, provide an alternate implementationthat does not use the function.
Memory management#
napi_adjust_external_memory
#
NAPI_EXTERN napi_statusnapi_adjust_external_memory(node_api_basic_env env,int64_t change_in_bytes,int64_t* result);
[in] env
: The environment that the API is invoked under.[in] change_in_bytes
: The change in externally allocated memory that is keptalive by JavaScript objects.[out] result
: The adjusted value. This value should reflect thetotal amount of external memory with the givenchange_in_bytes
included.The absolute value of the returned value should not be depended on.For example, implementations may use a single counter for all addons, or acounter for each addon.
Returnsnapi_ok
if the API succeeded.
This function gives the runtime an indication of the amount of externallyallocated memory that is kept alive by JavaScript objects(i.e. a JavaScript object that points to its own memory allocated by anative addon). Registering externally allocated memory may, but is notguaranteed to, trigger global garbage collections moreoften than it would otherwise.
This function is expected to be called in a manner such that anaddon does not decrease the external memory more than it hasincreased the external memory.
Promises#
Node-API provides facilities for creatingPromise
objects as described inSection 25.4 of the ECMA specification. It implements promises as a pair ofobjects. When a promise is created bynapi_create_promise()
, a "deferred"object is created and returned alongside thePromise
. The deferred object isbound to the createdPromise
and is the only means to resolve or reject thePromise
usingnapi_resolve_deferred()
ornapi_reject_deferred()
. Thedeferred object that is created bynapi_create_promise()
is freed bynapi_resolve_deferred()
ornapi_reject_deferred()
. ThePromise
object maybe returned to JavaScript where it can be used in the usual fashion.
For example, to create a promise and pass it to an asynchronous worker:
napi_deferred deferred;napi_value promise;napi_status status;// Create the promise.status = napi_create_promise(env, &deferred, &promise);if (status != napi_ok)returnNULL;// Pass the deferred to a function that performs an asynchronous action.do_something_asynchronous(deferred);// Return the promise to JSreturn promise;
The above functiondo_something_asynchronous()
would perform its asynchronousaction and then it would resolve or reject the deferred, thereby concluding thepromise and freeing the deferred:
napi_deferred deferred;napi_value undefined;napi_status status;// Create a value with which to conclude the deferred.status = napi_get_undefined(env, &undefined);if (status != napi_ok)returnNULL;// Resolve or reject the promise associated with the deferred depending on// whether the asynchronous action succeeded.if (asynchronous_action_succeeded) { status = napi_resolve_deferred(env, deferred, undefined);}else { status = napi_reject_deferred(env, deferred, undefined);}if (status != napi_ok)returnNULL;// At this point the deferred has been freed, so we should assign NULL to it.deferred =NULL;
napi_create_promise
#
napi_statusnapi_create_promise(napi_env env, napi_deferred* deferred, napi_value* promise);
[in] env
: The environment that the API is invoked under.[out] deferred
: A newly created deferred object which can later be passed tonapi_resolve_deferred()
ornapi_reject_deferred()
to resolve resp. rejectthe associated promise.[out] promise
: The JavaScript promise associated with the deferred object.
Returnsnapi_ok
if the API succeeded.
This API creates a deferred object and a JavaScript promise.
napi_resolve_deferred
#
napi_statusnapi_resolve_deferred(napi_env env, napi_deferred deferred, napi_value resolution);
[in] env
: The environment that the API is invoked under.[in] deferred
: The deferred object whose associated promise to resolve.[in] resolution
: The value with which to resolve the promise.
This API resolves a JavaScript promise by way of the deferred objectwith which it is associated. Thus, it can only be used to resolve JavaScriptpromises for which the corresponding deferred object is available. Thiseffectively means that the promise must have been created usingnapi_create_promise()
and the deferred object returned from that call musthave been retained in order to be passed to this API.
The deferred object is freed upon successful completion.
napi_reject_deferred
#
napi_statusnapi_reject_deferred(napi_env env, napi_deferred deferred, napi_value rejection);
[in] env
: The environment that the API is invoked under.[in] deferred
: The deferred object whose associated promise to resolve.[in] rejection
: The value with which to reject the promise.
This API rejects a JavaScript promise by way of the deferred objectwith which it is associated. Thus, it can only be used to reject JavaScriptpromises for which the corresponding deferred object is available. Thiseffectively means that the promise must have been created usingnapi_create_promise()
and the deferred object returned from that call musthave been retained in order to be passed to this API.
The deferred object is freed upon successful completion.
napi_is_promise
#
napi_statusnapi_is_promise(napi_env env, napi_value value,bool* is_promise);
[in] env
: The environment that the API is invoked under.[in] value
: The value to examine[out] is_promise
: Flag indicating whetherpromise
is a native promiseobject (that is, a promise object created by the underlying engine).
Script execution#
Node-API provides an API for executing a string containing JavaScript using theunderlying JavaScript engine.
napi_run_script
#
NAPI_EXTERN napi_statusnapi_run_script(napi_env env, napi_value script, napi_value* result);
[in] env
: The environment that the API is invoked under.[in] script
: A JavaScript string containing the script to execute.[out] result
: The value resulting from having executed the script.
This function executes a string of JavaScript code and returns its result withthe following caveats:
- Unlike
eval
, this function does not allow the script to access the currentlexical scope, and therefore also does not allow to access themodule scope, meaning that pseudo-globals such asrequire
will not beavailable. - The script can access theglobal scope. Function and
var
declarationsin the script will be added to theglobal
object. Variable declarationsmade usinglet
andconst
will be visible globally, but will not be addedto theglobal
object. - The value of
this
isglobal
within the script.
libuv event loop#
Node-API provides a function for getting the current event loop associated witha specificnapi_env
.
napi_get_uv_event_loop
#
NAPI_EXTERN napi_statusnapi_get_uv_event_loop(node_api_basic_env env,struct uv_loop_s** loop);
[in] env
: The environment that the API is invoked under.[out] loop
: The current libuv loop instance.
Note: While libuv has been relatively stable over time, it doesnot provide an ABI stability guarantee. Use of this function should be avoided.Its use may result in an addon that does not work across Node.js versions.asynchronous-thread-safe-function-callsare an alternative for many use cases.
Asynchronous thread-safe function calls#
JavaScript functions can normally only be called from a native addon's mainthread. If an addon creates additional threads, then Node-API functions thatrequire anapi_env
,napi_value
, ornapi_ref
must not be called from thosethreads.
When an addon has additional threads and JavaScript functions need to be invokedbased on the processing completed by those threads, those threads mustcommunicate with the addon's main thread so that the main thread can invoke theJavaScript function on their behalf. The thread-safe function APIs provide aneasy way to do this.
These APIs provide the typenapi_threadsafe_function
as well as APIs tocreate, destroy, and call objects of this type.napi_create_threadsafe_function()
creates a persistent reference to anapi_value
that holds a JavaScript function which can be called from multiplethreads. The calls happen asynchronously. This means that values with which theJavaScript callback is to be called will be placed in a queue, and, for eachvalue in the queue, a call will eventually be made to the JavaScript function.
Upon creation of anapi_threadsafe_function
anapi_finalize
callback can beprovided. This callback will be invoked on the main thread when the thread-safefunction is about to be destroyed. It receives the context and the finalize datagiven during construction, and provides an opportunity for cleaning up after thethreads e.g. by callinguv_thread_join()
.Aside from the main loop thread,no threads should be using the thread-safe function after the finalize callbackcompletes.
Thecontext
given during the call tonapi_create_threadsafe_function()
canbe retrieved from any thread with a call tonapi_get_threadsafe_function_context()
.
Calling a thread-safe function#
napi_call_threadsafe_function()
can be used for initiating a call intoJavaScript.napi_call_threadsafe_function()
accepts a parameter which controlswhether the API behaves blockingly. If set tonapi_tsfn_nonblocking
, the APIbehaves non-blockingly, returningnapi_queue_full
if the queue was full,preventing data from being successfully added to the queue. If set tonapi_tsfn_blocking
, the API blocks until space becomes available in the queue.napi_call_threadsafe_function()
never blocks if the thread-safe function wascreated with a maximum queue size of 0.
napi_call_threadsafe_function()
should not be called withnapi_tsfn_blocking
from a JavaScript thread, because, if the queue is full, it may cause theJavaScript thread to deadlock.
The actual call into JavaScript is controlled by the callback given via thecall_js_cb
parameter.call_js_cb
is invoked on the main thread once for eachvalue that was placed into the queue by a successful call tonapi_call_threadsafe_function()
. If such a callback is not given, a defaultcallback will be used, and the resulting JavaScript call will have no arguments.Thecall_js_cb
callback receives the JavaScript function to call as anapi_value
in its parameters, as well as thevoid*
context pointer used whencreating thenapi_threadsafe_function
, and the next data pointer that wascreated by one of the secondary threads. The callback can then use an API suchasnapi_call_function()
to call into JavaScript.
The callback may also be invoked withenv
andcall_js_cb
both set toNULL
to indicate that calls into JavaScript are no longer possible, while itemsremain in the queue that may need to be freed. This normally occurs when theNode.js process exits while there is a thread-safe function still active.
It is not necessary to call into JavaScript vianapi_make_callback()
becauseNode-API runscall_js_cb
in a context appropriate for callbacks.
Zero or more queued items may be invoked in each tick of the event loop.Applications should not depend on a specific behavior other than progress ininvoking callbacks will be made and events will be invokedas time moves forward.
Reference counting of thread-safe functions#
Threads can be added to and removed from anapi_threadsafe_function
objectduring its existence. Thus, in addition to specifying an initial number ofthreads upon creation,napi_acquire_threadsafe_function
can be called toindicate that a new thread will start making use of the thread-safe function.Similarly,napi_release_threadsafe_function
can be called to indicate that anexisting thread will stop making use of the thread-safe function.
napi_threadsafe_function
objects are destroyed when every thread which usesthe object has callednapi_release_threadsafe_function()
or has received areturn status ofnapi_closing
in response to a call tonapi_call_threadsafe_function
. The queue is emptied before thenapi_threadsafe_function
is destroyed.napi_release_threadsafe_function()
should be the last API call made in conjunction with a givennapi_threadsafe_function
, because after the call completes, there is noguarantee that thenapi_threadsafe_function
is still allocated. For the samereason, do not use a thread-safe functionafter receiving a return value ofnapi_closing
in response to a call tonapi_call_threadsafe_function
. Data associated with thenapi_threadsafe_function
can be freed in itsnapi_finalize
callback whichwas passed tonapi_create_threadsafe_function()
. The parameterinitial_thread_count
ofnapi_create_threadsafe_function
marks the initialnumber of acquisitions of the thread-safe functions, instead of callingnapi_acquire_threadsafe_function
multiple times at creation.
Once the number of threads making use of anapi_threadsafe_function
reacheszero, no further threads can start making use of it by callingnapi_acquire_threadsafe_function()
. In fact, all subsequent API callsassociated with it, exceptnapi_release_threadsafe_function()
, will return anerror value ofnapi_closing
.
The thread-safe function can be "aborted" by giving a value ofnapi_tsfn_abort
tonapi_release_threadsafe_function()
. This will cause all subsequent APIsassociated with the thread-safe function exceptnapi_release_threadsafe_function()
to returnnapi_closing
even before itsreference count reaches zero. In particular,napi_call_threadsafe_function()
will returnnapi_closing
, thus informing the threads that it is no longerpossible to make asynchronous calls to the thread-safe function. This can beused as a criterion for terminating the thread.Upon receiving a return valueofnapi_closing
fromnapi_call_threadsafe_function()
a thread must not usethe thread-safe function anymore because it is no longer guaranteed tobe allocated.
Deciding whether to keep the process running#
Similarly to libuv handles, thread-safe functions can be "referenced" and"unreferenced". A "referenced" thread-safe function will cause the event loop onthe thread on which it is created to remain alive until the thread-safe functionis destroyed. In contrast, an "unreferenced" thread-safe function will notprevent the event loop from exiting. The APIsnapi_ref_threadsafe_function
andnapi_unref_threadsafe_function
exist for this purpose.
Neither doesnapi_unref_threadsafe_function
mark the thread-safe functions asable to be destroyed nor doesnapi_ref_threadsafe_function
prevent it frombeing destroyed.
napi_create_threadsafe_function
#
History
Version | Changes |
---|---|
v12.6.0, v10.17.0 | Made |
v10.6.0 | Added in: v10.6.0 |
NAPI_EXTERN napi_statusnapi_create_threadsafe_function(napi_env env, napi_value func, napi_value async_resource, napi_value async_resource_name,size_t max_queue_size,size_t initial_thread_count,void* thread_finalize_data, napi_finalize thread_finalize_cb,void* context, napi_threadsafe_function_call_js call_js_cb, napi_threadsafe_function* result);
[in] env
: The environment that the API is invoked under.[in] func
: An optional JavaScript function to call from another thread. Itmust be provided ifNULL
is passed tocall_js_cb
.[in] async_resource
: An optional object associated with the async work thatwill be passed to possibleasync_hooks
init
hooks.[in] async_resource_name
: A JavaScript string to provide an identifier forthe kind of resource that is being provided for diagnostic information exposedby theasync_hooks
API.[in] max_queue_size
: Maximum size of the queue.0
for no limit.[in] initial_thread_count
: The initial number of acquisitions, i.e. theinitial number of threads, including the main thread, which will be making useof this function.[in] thread_finalize_data
: Optional data to be passed tothread_finalize_cb
.[in] thread_finalize_cb
: Optional function to call when thenapi_threadsafe_function
is being destroyed.[in] context
: Optional data to attach to the resultingnapi_threadsafe_function
.[in] call_js_cb
: Optional callback which calls the JavaScript function inresponse to a call on a different thread. This callback will be called on themain thread. If not given, the JavaScript function will be called with noparameters and withundefined
as itsthis
value.napi_threadsafe_function_call_js
provides more details.[out] result
: The asynchronous thread-safe JavaScript function.
Change History:
Version 10 (
NAPI_VERSION
is defined as10
or higher):Uncaught exceptions thrown in
call_js_cb
are handled with the'uncaughtException'
event, instead of being ignored.
napi_get_threadsafe_function_context
#
NAPI_EXTERN napi_statusnapi_get_threadsafe_function_context(napi_threadsafe_function func,void** result);
[in] func
: The thread-safe function for which to retrieve the context.[out] result
: The location where to store the context.
This API may be called from any thread which makes use offunc
.
napi_call_threadsafe_function
#
History
Version | Changes |
---|---|
v14.5.0 | Support for |
v14.1.0 | Return |
v10.6.0 | Added in: v10.6.0 |
NAPI_EXTERN napi_statusnapi_call_threadsafe_function(napi_threadsafe_function func,void* data, napi_threadsafe_function_call_mode is_blocking);
[in] func
: The asynchronous thread-safe JavaScript function to invoke.[in] data
: Data to send into JavaScript via the callbackcall_js_cb
provided during the creation of the thread-safe JavaScript function.[in] is_blocking
: Flag whose value can be eithernapi_tsfn_blocking
toindicate that the call should block if the queue is full ornapi_tsfn_nonblocking
to indicate that the call should return immediatelywith a status ofnapi_queue_full
whenever the queue is full.
This API should not be called withnapi_tsfn_blocking
from a JavaScriptthread, because, if the queue is full, it may cause the JavaScript thread todeadlock.
This API will returnnapi_closing
ifnapi_release_threadsafe_function()
wascalled withabort
set tonapi_tsfn_abort
from any thread. The value is onlyadded to the queue if the API returnsnapi_ok
.
This API may be called from any thread which makes use offunc
.
napi_acquire_threadsafe_function
#
NAPI_EXTERN napi_statusnapi_acquire_threadsafe_function(napi_threadsafe_function func);
[in] func
: The asynchronous thread-safe JavaScript function to start makinguse of.
A thread should call this API before passingfunc
to any other thread-safefunction APIs to indicate that it will be making use offunc
. This preventsfunc
from being destroyed when all other threads have stopped making use ofit.
This API may be called from any thread which will start making use offunc
.
napi_release_threadsafe_function
#
NAPI_EXTERN napi_statusnapi_release_threadsafe_function(napi_threadsafe_function func, napi_threadsafe_function_release_mode mode);
[in] func
: The asynchronous thread-safe JavaScript function whose referencecount to decrement.[in] mode
: Flag whose value can be eithernapi_tsfn_release
to indicatethat the current thread will make no further calls to the thread-safefunction, ornapi_tsfn_abort
to indicate that in addition to the currentthread, no other thread should make any further calls to the thread-safefunction. If set tonapi_tsfn_abort
, further calls tonapi_call_threadsafe_function()
will returnnapi_closing
, and no furthervalues will be placed in the queue.
A thread should call this API when it stops making use offunc
. Passingfunc
to any thread-safe APIs after having called this API has undefined results, asfunc
may have been destroyed.
This API may be called from any thread which will stop making use offunc
.
napi_ref_threadsafe_function
#
NAPI_EXTERN napi_statusnapi_ref_threadsafe_function(node_api_basic_env env, napi_threadsafe_function func);
[in] env
: The environment that the API is invoked under.[in] func
: The thread-safe function to reference.
This API is used to indicate that the event loop running on the main threadshould not exit untilfunc
has been destroyed. Similar touv_ref
it isalso idempotent.
Neither doesnapi_unref_threadsafe_function
mark the thread-safe functions asable to be destroyed nor doesnapi_ref_threadsafe_function
prevent it frombeing destroyed.napi_acquire_threadsafe_function
andnapi_release_threadsafe_function
are available for that purpose.
This API may only be called from the main thread.
napi_unref_threadsafe_function
#
NAPI_EXTERN napi_statusnapi_unref_threadsafe_function(node_api_basic_env env, napi_threadsafe_function func);
[in] env
: The environment that the API is invoked under.[in] func
: The thread-safe function to unreference.
This API is used to indicate that the event loop running on the main threadmay exit beforefunc
is destroyed. Similar touv_unref
it is alsoidempotent.
This API may only be called from the main thread.
Miscellaneous utilities#
node_api_get_module_file_name
#
NAPI_EXTERN napi_statusnode_api_get_module_file_name(node_api_basic_env env,constchar** result);
[in] env
: The environment that the API is invoked under.[out] result
: A URL containing the absolute path of thelocation from which the add-on was loaded. For a file on the localfile system it will start withfile://
. The string is null-terminated andowned byenv
and must thus not be modified or freed.
result
may be an empty string if the add-on loading process fails to establishthe add-on's file name during loading.