node-addon-api 1.6.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- # Class propertry and descriptor
1
+ # Class property and descriptor
2
2
 
3
3
  Property descriptor for use with `Napi::ObjectWrap::DefineClass()`.
4
4
  This is different from the standalone `Napi::PropertyDescriptor` because it is
@@ -6,6 +6,87 @@ specific to each `Napi::ObjectWrap<T>` subclass.
6
6
  This prevents using descriptors from a different class when defining a new class
7
7
  (preventing the callbacks from having incorrect `this` pointers).
8
8
 
9
+ ## Example
10
+
11
+ ```cpp
12
+ #include <napi.h>
13
+
14
+ class Example : public Napi::ObjectWrap<Example> {
15
+ public:
16
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
17
+ Example(const Napi::CallbackInfo &info);
18
+
19
+ private:
20
+ static Napi::FunctionReference constructor;
21
+ double _value;
22
+ Napi::Value GetValue(const Napi::CallbackInfo &info);
23
+ void SetValue(const Napi::CallbackInfo &info, const Napi::Value &value);
24
+ };
25
+
26
+ Napi::Object Example::Init(Napi::Env env, Napi::Object exports) {
27
+ Napi::Function func = DefineClass(env, "Example", {
28
+ // Register a class instance accessor with getter and setter functions.
29
+ InstanceAccessor("value", &Example::GetValue, &Example::SetValue),
30
+ // We can also register a readonly accessor by passing nullptr as the setter.
31
+ InstanceAccessor("readOnlyProp", &Example::GetValue, nullptr)
32
+ });
33
+
34
+ constructor = Napi::Persistent(func);
35
+ constructor.SuppressDestruct();
36
+ exports.Set("Example", func);
37
+
38
+ return exports;
39
+ }
40
+
41
+ Example::Example(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Example>(info) {
42
+ Napi::Env env = info.Env();
43
+ // ...
44
+ Napi::Number value = info[0].As<Napi::Number>();
45
+ this->_value = value.DoubleValue();
46
+ }
47
+
48
+ Napi::FunctionReference Example::constructor;
49
+
50
+ Napi::Value Example::GetValue(const Napi::CallbackInfo &info) {
51
+ Napi::Env env = info.Env();
52
+ return Napi::Number::New(env, this->_value);
53
+ }
54
+
55
+ void Example::SetValue(const Napi::CallbackInfo &info, const Napi::Value &value) {
56
+ Napi::Env env = info.Env();
57
+ // ...
58
+ Napi::Number arg = value.As<Napi::Number>();
59
+ this->_value = arg.DoubleValue();
60
+ }
61
+
62
+ // Initialize native add-on
63
+ Napi::Object Init (Napi::Env env, Napi::Object exports) {
64
+ Example::Init(env, exports);
65
+ return exports;
66
+ }
67
+
68
+ // Register and initialize native add-on
69
+ NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
70
+ ```
71
+
72
+ The above code can be used from JavaScript as follows:
73
+
74
+ ```js
75
+ 'use strict';
76
+
77
+ const { Example } = require('bindings')('addon');
78
+
79
+ const example = new Example(11);
80
+ console.log(example.value);
81
+ // It prints 11
82
+ example.value = 19;
83
+ console.log(example.value);
84
+ // It prints 19
85
+ example.readOnlyProp = 500;
86
+ console.log(example.readOnlyProp);
87
+ // Unchanged. It prints 19
88
+ ```
89
+
9
90
  ## Methods
10
91
 
11
92
  ### Constructor
package/doc/cmake-js.md CHANGED
@@ -1,19 +1,68 @@
1
1
  # CMake.js
2
2
 
3
- **CMake.js** is a build tool that allow native addon developer to compile their
4
- C++ code into executable form. It works like **[node-gyp](node-gyp.md)** but
5
- instead of Google's **gyp** format it is base on **CMake** build system.
3
+ [**CMake.js**](https://github.com/cmake-js/cmake-js) is a build tool that allow native addon developers to compile their
4
+ C or C++ code into executable form. It works like **[node-gyp](node-gyp.md)** but
5
+ instead of Google's [**gyp**](https://gyp.gsrc.io) tool it is based on the [**CMake**](https://cmake.org) build system.
6
6
 
7
- ## **CMake** reference
7
+ ## Quick Start
8
8
 
9
- - [Installation](https://www.npmjs.com/package/cmake-js#installation)
10
- - [How to use](https://www.npmjs.com/package/cmake-js#usage)
9
+ ### Install CMake
10
+
11
+ CMake.js requires that CMake be installed. Installers for a variety of platforms can be found on the [CMake website](https://cmake.org).
12
+
13
+ ### Install CMake.js
14
+
15
+ For developers, CMake.js is typically installed as a global package:
16
+
17
+ ```bash
18
+ npm install -g cmake-js
19
+ cmake-js --help
20
+ ```
21
+
22
+ > For *users* of your native addon, CMake.js should be configured as a dependency in your `package.json` as described in the [CMake.js documentation](https://github.com/cmake-js/cmake-js).
23
+
24
+ ### CMakeLists.txt
25
+
26
+ Your project will require a `CMakeLists.txt` file. The [CMake.js README file](https://github.com/cmake-js/cmake-js#usage) shows what's necessary.
27
+
28
+ ### NAPI_VERSION
29
+
30
+ When building N-API addons, it's crucial to specify the N-API version your code is designed to work with. With CMake.js, this information is specified in the `CMakeLists.txt` file:
31
+
32
+ ```
33
+ add_definitions(-DNAPI_VERSION=3)
34
+ ```
35
+
36
+ Since N-API is ABI-stable, your N-API addon will work, without recompilation, with the N-API version you specify in `NAPI_VERSION` and all subsequent N-API versions.
37
+
38
+ In the absence of a need for features available only in a specific N-API version, version 3 is a good choice as it is the version of N-API that was active when N-API left experimental status.
39
+
40
+ ### NAPI_EXPERIMENTAL
41
+
42
+ The following line in the `CMakeLists.txt` file will enable N-API experimental features if your code requires them:
43
+
44
+ ```
45
+ add_definitions(-DNAPI_EXPERIMENTAL)
46
+ ```
47
+
48
+ ### node-addon-api
49
+
50
+ If your N-API native add-on uses the optional [**node-addon-api**](https://github.com/nodejs/node-addon-api#node-addon-api-module) C++ wrapper, the `CMakeLists.txt` file requires additional configuration information as described on the [CMake.js README file](https://github.com/cmake-js/cmake-js#n-api-and-node-addon-api).
51
+
52
+ ## Example
53
+
54
+ A working example of an N-API native addon built using CMake.js can be found on the [node-addon-examples repository](https://github.com/nodejs/node-addon-examples/tree/master/build_with_cmake#building-n-api-addons-using-cmakejs).
55
+
56
+ ## **CMake** Reference
57
+
58
+ - [Installation](https://github.com/cmake-js/cmake-js#installation)
59
+ - [How to use](https://github.com/cmake-js/cmake-js#usage)
11
60
  - [Using N-API and node-addon-api](https://github.com/cmake-js/cmake-js#n-api-and-node-addon-api)
12
- - [Tutorials](https://www.npmjs.com/package/cmake-js#tutorials)
13
- - [Use case in the works - ArrayFire.js](https://www.npmjs.com/package/cmake-js#use-case-in-the-works---arrayfirejs)
61
+ - [Tutorials](https://github.com/cmake-js/cmake-js#tutorials)
62
+ - [Use case in the works - ArrayFire.js](https://github.com/cmake-js/cmake-js#use-case-in-the-works---arrayfirejs)
14
63
 
15
64
  Sometimes finding the right settings is not easy so to accomplish at most
16
65
  complicated task please refer to:
17
66
 
18
67
  - [CMake documentation](https://cmake.org/)
19
- - [CMake.js wiki](https://github.com/cmake-js/cmake-js/wiki)
68
+ - [CMake.js wiki](https://github.com/cmake-js/cmake-js/wiki)
package/doc/date.md ADDED
@@ -0,0 +1,68 @@
1
+ # Date
2
+
3
+ `Napi::Date` class is a representation of the JavaScript `Date` object. The
4
+ `Napi::Date` class inherits its behavior from `Napi::Value` class
5
+ (for more info see [`Napi::Value`](value.md))
6
+
7
+ ## Methods
8
+
9
+ ### Constructor
10
+
11
+ Creates a new _empty_ instance of a `Napi::Date` object.
12
+
13
+ ```cpp
14
+ Napi::Date::Date();
15
+ ```
16
+
17
+ Creates a new _non-empty_ instance of a `Napi::Date` object.
18
+
19
+ ```cpp
20
+ Napi::Date::Date(napi_env env, napi_value value);
21
+ ```
22
+
23
+ - `[in] env`: The environment in which to construct the `Napi::Date` object.
24
+ - `[in] value`: The `napi_value` which is a handle for a JavaScript `Date`.
25
+
26
+ ### New
27
+
28
+ Creates a new instance of a `Napi::Date` object.
29
+
30
+ ```cpp
31
+ static Napi::Date Napi::Date::New(Napi::Env env, double value);
32
+ ```
33
+
34
+ - `[in] env`: The environment in which to construct the `Napi::Date` object.
35
+ - `[in] value`: The time value the JavaScript `Date` will contain represented
36
+ as the number of milliseconds since 1 January 1970 00:00:00 UTC.
37
+
38
+ Returns a new instance of `Napi::Date` object.
39
+
40
+ ### ValueOf
41
+
42
+ ```cpp
43
+ double Napi::Date::ValueOf() const;
44
+ ```
45
+
46
+ Returns the time value as `double` primitive represented as the number of
47
+ milliseconds since 1 January 1970 00:00:00 UTC.
48
+
49
+ ## Operators
50
+
51
+ ### operator double
52
+
53
+ Converts a `Napi::Date` value to a `double` primitive.
54
+
55
+ ```cpp
56
+ Napi::Date::operator double() const;
57
+ ```
58
+
59
+ ### Example
60
+
61
+ The following shows an example of casting a `Napi::Date` value to a `double`
62
+ primitive.
63
+
64
+ ```cpp
65
+ double operatorVal = Napi::Date::New(Env(), 0); // Napi::Date to double
66
+ // or
67
+ auto instanceVal = info[0].As<Napi::Date>().ValueOf();
68
+ ```
package/doc/object.md CHANGED
@@ -23,12 +23,12 @@ Void Init(Env env) {
23
23
 
24
24
  // Assign values to properties
25
25
  obj.Set("hello", "world");
26
- obj.Set(42, "The Answer to Life, the Universe, and Everything");
26
+ obj.Set(uint32_t(42), "The Answer to Life, the Universe, and Everything");
27
27
  obj.Set("Douglas Adams", true);
28
28
 
29
29
  // Get properties
30
30
  Value val1 = obj.Get("hello");
31
- Value val2 = obj.Get(42);
31
+ Value val2 = obj.Get(uint32_t(42));
32
32
  Value val3 = obj.Get("Douglas Adams");
33
33
 
34
34
  // Test if objects have properties.
@@ -137,6 +137,40 @@ Returns a `bool` that is true if the `Napi::Object` is an instance created by th
137
137
 
138
138
  Note: This is equivalent to the JavaScript instanceof operator.
139
139
 
140
+ ### AddFinalizer()
141
+ ```cpp
142
+ template <typename Finalizer, typename T>
143
+ inline void AddFinalizer(Finalizer finalizeCallback, T* data);
144
+ ```
145
+
146
+ - `[in] finalizeCallback`: The function to call when the object is garbage-collected.
147
+ - `[in] data`: The data to associate with the object.
148
+
149
+ Associates `data` with the object, calling `finalizeCallback` when the object is garbage-collected. `finalizeCallback`
150
+ has the signature
151
+ ```cpp
152
+ void finalizeCallback(Napi::Env env, T* data);
153
+ ```
154
+ where `data` is the pointer that was passed into the call to `AddFinalizer()`.
155
+
156
+ ### AddFinalizer()
157
+ ```cpp
158
+ template <typename Finalizer, typename T, typename Hint>
159
+ inline void AddFinalizer(Finalizer finalizeCallback,
160
+ T* data,
161
+ Hint* finalizeHint);
162
+ ```
163
+
164
+ - `[in] data`: The data to associate with the object.
165
+ - `[in] finalizeCallback`: The function to call when the object is garbage-collected.
166
+
167
+ Associates `data` with the object, calling `finalizeCallback` when the object is garbage-collected. An additional hint
168
+ may be given. It will also be passed to `finalizeCallback`, which has the signature
169
+ ```cpp
170
+ void finalizeCallback(Napi::Env env, T* data, Hint* hint);
171
+ ```
172
+ where `data` and `hint` are the pointers that were passed into the call to `AddFinalizer()`.
173
+
140
174
  ### DefineProperty()
141
175
 
142
176
  ```cpp
@@ -78,7 +78,7 @@ Napi::Object Init (Napi::Env env, Napi::Object exports) {
78
78
  return exports;
79
79
  }
80
80
 
81
- // Regisgter and initialize native add-on
81
+ // Register and initialize native add-on
82
82
  NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
83
83
  ```
84
84
 
@@ -161,7 +161,7 @@ static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env,
161
161
  JavaScript constructor function.
162
162
  * `[in] properties`: Initializer list of class property descriptor describing
163
163
  static and instance properties and methods of the class.
164
- See: [`Class propertry and descriptor`](class_property_descriptor.md).
164
+ See: [`Class property and descriptor`](class_property_descriptor.md).
165
165
  * `[in] data`: User-provided data passed to the constructor callback as `data`
166
166
  property of the `Napi::CallbackInfo`.
167
167
 
@@ -184,12 +184,23 @@ static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env,
184
184
  JavaScript constructor function.
185
185
  * `[in] properties`: Vector of class property descriptor describing static and
186
186
  instance properties and methods of the class.
187
- See: [`Class propertry and descriptor`](class_property_descriptor.md).
187
+ See: [`Class property and descriptor`](class_property_descriptor.md).
188
188
  * `[in] data`: User-provided data passed to the constructor callback as `data`
189
189
  property of the `Napi::CallbackInfo`.
190
190
 
191
191
  Returns a `Napi::Function` representing the constructor function for the class.
192
192
 
193
+ ### Finalize
194
+
195
+ Provides an opportunity to run cleanup code that requires access to the `Napi::Env`
196
+ before the wrapped native object instance is freed. Override to implement.
197
+
198
+ ```cpp
199
+ virtual void Finalize(Napi::Env env);
200
+ ```
201
+
202
+ - `[in] env`: `Napi::Env`.
203
+
193
204
  ### StaticMethod
194
205
 
195
206
  Creates property descriptor that represents a static method of a JavaScript class.
@@ -2,14 +2,14 @@
2
2
 
3
3
  The distribution of a native add-on is just as important as its implementation.
4
4
  In order to install a native add-on it's important to have all the necessary
5
- dependencies installed and well configured (see the [setup](doc/setum.md) section).
5
+ dependencies installed and well configured (see the [setup](setup.md) section).
6
6
  The end-user will need to compile the add-on when they will do an `npm install`
7
7
  and in some cases this could create problems. To avoid the compilation process it's
8
8
  possible to ditribute the native add-on in pre-built form for different platform
9
9
  and architectures. The prebuild tools help to create and distrubute the pre-built
10
10
  form of a native add-on.
11
11
 
12
- The following list report two of the tools that are compatible with **N-API**:
12
+ The following list report known tools that are compatible with **N-API**:
13
13
 
14
14
  - **[node-pre-gyp](https://www.npmjs.com/package/node-pre-gyp)**
15
15
  - **[prebuild](https://www.npmjs.com/package/prebuild)**
package/doc/string.md CHANGED
@@ -56,6 +56,8 @@ Napi::String::New(napi_env env, const std::string& value);
56
56
  Napi::String::New(napi_env env, const std::u16::string& value);
57
57
  Napi::String::New(napi_env env, const char* value);
58
58
  Napi::String::New(napi_env env, const char16_t* value);
59
+ Napi::String::New(napi_env env, const char* value, size_t length);
60
+ Napi::String::New(napi_env env, const char16_t* value, size_t length);
59
61
  ```
60
62
 
61
63
  - `[in] env`: The `napi_env` environment in which to construct the `Napi::Value` object.
@@ -64,6 +66,7 @@ Napi::String::New(napi_env env, const char16_t* value);
64
66
  - `std::u16string&` - represents a UTF16-LE string.
65
67
  - `const char*` - represents a UTF8 string.
66
68
  - `const char16_t*` - represents a UTF16-LE string.
69
+ - `[in] length`: The length of the string (not necessarily null-terminated) in code units.
67
70
 
68
71
  Returns a new `Napi::String` that represents the passed in C++ string.
69
72
 
@@ -0,0 +1,320 @@
1
+ # ThreadSafeFunction
2
+
3
+ JavaScript functions can normally only be called from a native addon's main
4
+ thread. If an addon creates additional threads, then node-addon-api functions
5
+ that require a `Napi::Env`, `Napi::Value`, or `Napi::Reference` must not be
6
+ called from those threads.
7
+
8
+ When an addon has additional threads and JavaScript functions need to be invoked
9
+ based on the processing completed by those threads, those threads must
10
+ communicate with the addon's main thread so that the main thread can invoke the
11
+ JavaScript function on their behalf. The thread-safe function APIs provide an
12
+ easy way to do this.
13
+
14
+ These APIs provide the type `Napi::ThreadSafeFunction` as well as APIs to
15
+ create, destroy, and call objects of this type.
16
+ `Napi::ThreadSafeFunction::New()` creates a persistent reference that holds a
17
+ JavaScript function which can be called from multiple threads. The calls happen
18
+ asynchronously. This means that values with which the JavaScript callback is to
19
+ be called will be placed in a queue, and, for each value in the queue, a call
20
+ will eventually be made to the JavaScript function.
21
+
22
+ `Napi::ThreadSafeFunction` objects are destroyed when every thread which uses
23
+ the object has called `Release()` or has received a return status of
24
+ `napi_closing` in response to a call to `BlockingCall()` or `NonBlockingCall()`.
25
+ The queue is emptied before the `Napi::ThreadSafeFunction` is destroyed. It is
26
+ important that `Release()` be the last API call made in conjunction with a given
27
+ `Napi::ThreadSafeFunction`, because after the call completes, there is no
28
+ guarantee that the `Napi::ThreadSafeFunction` is still allocated. For the same
29
+ reason it is also important that no more use be made of a thread-safe function
30
+ after receiving a return value of `napi_closing` in response to a call to
31
+ `BlockingCall()` or `NonBlockingCall()`. Data associated with the
32
+ `Napi::ThreadSafeFunction` can be freed in its `Finalizer` callback which was
33
+ passed to `ThreadSafeFunction::New()`.
34
+
35
+ Once the number of threads making use of a `Napi::ThreadSafeFunction` reaches
36
+ zero, no further threads can start making use of it by calling `Acquire()`. In
37
+ fact, all subsequent API calls associated with it, except `Release()`, will
38
+ return an error value of `napi_closing`.
39
+
40
+ ## Methods
41
+
42
+ ### Constructor
43
+
44
+ Creates a new empty instance of `Napi::ThreadSafeFunction`.
45
+
46
+ ```cpp
47
+ Napi::Function::ThreadSafeFunction();
48
+ ```
49
+
50
+ ### Constructor
51
+
52
+ Creates a new instance of the `Napi::ThreadSafeFunction` object.
53
+
54
+ ```cpp
55
+ Napi::ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn);
56
+ ```
57
+
58
+ - `tsfn`: The `napi_threadsafe_function` which is a handle for an existing
59
+ thread-safe function.
60
+
61
+ Returns a non-empty `Napi::ThreadSafeFunction` instance. When using this
62
+ constructor, only use the `Blocking(void*)` / `NonBlocking(void*)` overloads;
63
+ the `Callback` and templated `data*` overloads should _not_ be used. See below
64
+ for additional details.
65
+
66
+ ### New
67
+
68
+ Creates a new instance of the `Napi::ThreadSafeFunction` object. The `New`
69
+ function has several overloads for the various optional parameters: skip the
70
+ optional parameter for that specific overload.
71
+
72
+ ```cpp
73
+ New(napi_env env,
74
+ const Function& callback,
75
+ const Object& resource,
76
+ ResourceString resourceName,
77
+ size_t maxQueueSize,
78
+ size_t initialThreadCount,
79
+ ContextType* context,
80
+ Finalizer finalizeCallback,
81
+ FinalizerDataType* data);
82
+ ```
83
+
84
+ - `env`: The `napi_env` environment in which to construct the
85
+ `Napi::ThreadSafeFunction` object.
86
+ - `callback`: The `Function` to call from another thread.
87
+ - `[optional] resource`: An object associated with the async work that will be
88
+ passed to possible async_hooks init hooks.
89
+ - `resourceName`: A JavaScript string to provide an identifier for the kind of
90
+ resource that is being provided for diagnostic information exposed by the
91
+ async_hooks API.
92
+ - `maxQueueSize`: Maximum size of the queue. `0` for no limit.
93
+ - `initialThreadCount`: The initial number of threads, including the main
94
+ thread, which will be making use of this function.
95
+ - `[optional] context`: Data to attach to the resulting `ThreadSafeFunction`.
96
+ - `[optional] finalizeCallback`: Function to call when the `ThreadSafeFunction`
97
+ is being destroyed. This callback will be invoked on the main thread when the
98
+ thread-safe function is about to be destroyed. It receives the context and the
99
+ finalize data given during construction (if given), and provides an
100
+ opportunity for cleaning up after the threads e.g. by calling
101
+ `uv_thread_join()`. It is important that, aside from the main loop thread,
102
+ there be no threads left using the thread-safe function after the finalize
103
+ callback completes. Must implement `void operator()(Env env, DataType* data,
104
+ Context* hint)`, skipping `data` or `hint` if they are not provided.
105
+ Can be retreived via `GetContext()`.
106
+ - `[optional] data`: Data to be passed to `finalizeCallback`.
107
+
108
+ Returns a non-empty `Napi::ThreadSafeFunction` instance.
109
+
110
+ ### Acquire
111
+
112
+ Add a thread to this thread-safe function object, indicating that a new thread
113
+ will start making use of the thread-safe function.
114
+
115
+ ```cpp
116
+ napi_status Napi::ThreadSafeFunction::Acquire()
117
+ ```
118
+
119
+ Returns one of:
120
+ - `napi_ok`: The thread has successfully acquired the thread-safe function
121
+ for its use.
122
+ - `napi_closing`: The thread-safe function has been marked as closing via a
123
+ previous call to `Abort()`.
124
+
125
+ ### Release
126
+
127
+ Indicate that an existing thread will stop making use of the thread-safe
128
+ function. A thread should call this API when it stops making use of this
129
+ thread-safe function. Using any thread-safe APIs after having called this API
130
+ has undefined results in the current thread, as it may have been destroyed.
131
+
132
+ ```cpp
133
+ napi_status Napi::ThreadSafeFunction::Release()
134
+ ```
135
+
136
+ Returns one of:
137
+ - `napi_ok`: The thread-safe function has been successfully released.
138
+ - `napi_invalid_arg`: The thread-safe function's thread-count is zero.
139
+ - `napi_generic_failure`: A generic error occurred when attemping to release
140
+ the thread-safe function.
141
+
142
+ ### Abort
143
+
144
+ "Abort" the thread-safe function. This will cause all subsequent APIs associated
145
+ with the thread-safe function except `Release()` to return `napi_closing` even
146
+ before its reference count reaches zero. In particular, `BlockingCall` and
147
+ `NonBlockingCall()` will return `napi_closing`, thus informing the threads that
148
+ it is no longer possible to make asynchronous calls to the thread-safe function.
149
+ This can be used as a criterion for terminating the thread. Upon receiving a
150
+ return value of `napi_closing` from a thread-safe function call a thread must
151
+ make no further use of the thread-safe function because it is no longer
152
+ guaranteed to be allocated.
153
+
154
+ ```cpp
155
+ napi_status Napi::ThreadSafeFunction::Abort()
156
+ ```
157
+
158
+ Returns one of:
159
+ - `napi_ok`: The thread-safe function has been successfully aborted.
160
+ - `napi_invalid_arg`: The thread-safe function's thread-count is zero.
161
+ - `napi_generic_failure`: A generic error occurred when attemping to abort
162
+ the thread-safe function.
163
+
164
+ ### BlockingCall / NonBlockingCall
165
+
166
+ Calls the Javascript function in either a blocking or non-blocking fashion.
167
+ - `BlockingCall()`: the API blocks until space becomes available in the queue.
168
+ Will never block if the thread-safe function was created with a maximum queue
169
+ size of `0`.
170
+ - `NonBlockingCall()`: will return `napi_queue_full` if the queue was full,
171
+ preventing data from being successfully added to the queue.
172
+
173
+ There are several overloaded implementations of `BlockingCall()` and
174
+ `NonBlockingCall()` for use with optional parameters: skip the optional
175
+ parameter for that specific overload.
176
+
177
+ **These specific function overloads should only be used on a `ThreadSafeFunction`
178
+ created via `ThreadSafeFunction::New`.**
179
+
180
+ ```cpp
181
+ napi_status Napi::ThreadSafeFunction::BlockingCall(DataType* data, Callback callback) const
182
+
183
+ napi_status Napi::ThreadSafeFunction::NonBlockingCall(DataType* data, Callback callback) const
184
+ ```
185
+
186
+ - `[optional] data`: Data to pass to `callback`.
187
+ - `[optional] callback`: C++ function that is invoked on the main thread. The
188
+ callback receives the `ThreadSafeFunction`'s JavaScript callback function to
189
+ call as an `Napi::Function` in its parameters and the `DataType*` data pointer
190
+ (if provided). Must implement `void operator()(Napi::Env env, Function
191
+ jsCallback, DataType* data)`, skipping `data` if not provided. It is not
192
+ necessary to call into JavaScript via `MakeCallback()` because N-API runs
193
+ `callback` in a context appropriate for callbacks.
194
+
195
+ **These specific function overloads should only be used on a `ThreadSafeFunction`
196
+ created via `ThreadSafeFunction(napi_threadsafe_function)`.**
197
+
198
+ ```cpp
199
+ napi_status Napi::ThreadSafeFunction::BlockingCall(void* data) const
200
+
201
+ napi_status Napi::ThreadSafeFunction::NonBlockingCall(void* data) const
202
+ ```
203
+ - `data`: Data to pass to `call_js_cb` specified when creating the thread-safe
204
+ function via `napi_create_threadsafe_function`.
205
+
206
+ Returns one of:
207
+ - `napi_ok`: The call was successfully added to the queue.
208
+ - `napi_queue_full`: The queue was full when trying to call in a non-blocking
209
+ method.
210
+ - `napi_closing`: The thread-safe function is aborted and cannot accept more
211
+ calls.
212
+ - `napi_invalid_arg`: The thread-safe function is closed.
213
+ - `napi_generic_failure`: A generic error occurred when attemping to add to the
214
+ queue.
215
+
216
+ ## Example
217
+
218
+ ```cpp
219
+ #include <chrono>
220
+ #include <thread>
221
+ #include <napi.h>
222
+
223
+ using namespace Napi;
224
+
225
+ std::thread nativeThread;
226
+ ThreadSafeFunction tsfn;
227
+
228
+ Value Start( const CallbackInfo& info )
229
+ {
230
+ Napi::Env env = info.Env();
231
+
232
+ if ( info.Length() < 2 )
233
+ {
234
+ throw TypeError::New( env, "Expected two arguments" );
235
+ }
236
+ else if ( !info[0].IsFunction() )
237
+ {
238
+ throw TypeError::New( env, "Expected first arg to be function" );
239
+ }
240
+ else if ( !info[1].IsNumber() )
241
+ {
242
+ throw TypeError::New( env, "Expected second arg to be number" );
243
+ }
244
+
245
+ int count = info[1].As<Number>().Int32Value();
246
+
247
+ // Create a ThreadSafeFunction
248
+ tsfn = ThreadSafeFunction::New(
249
+ env,
250
+ info[0].As<Function>(), // JavaScript function called asynchronously
251
+ "Resource Name", // Name
252
+ 0, // Unlimited queue
253
+ 1, // Only one thread will use this initially
254
+ []( Napi::Env ) { // Finalizer used to clean threads up
255
+ nativeThread.join();
256
+ } );
257
+
258
+ // Create a native thread
259
+ nativeThread = std::thread( [count] {
260
+ auto callback = []( Napi::Env env, Function jsCallback, int* value ) {
261
+ // Transform native data into JS data, passing it to the provided
262
+ // `jsCallback` -- the TSFN's JavaScript function.
263
+ jsCallback.Call( {Number::New( env, *value )} );
264
+
265
+ // We're finished with the data.
266
+ delete value;
267
+ };
268
+
269
+ for ( int i = 0; i < count; i++ )
270
+ {
271
+ // Create new data
272
+ int* value = new int( clock() );
273
+
274
+ // Perform a blocking call
275
+ napi_status status = tsfn.BlockingCall( value, callback );
276
+ if ( status != napi_ok )
277
+ {
278
+ // Handle error
279
+ break;
280
+ }
281
+
282
+ std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
283
+ }
284
+
285
+ // Release the thread-safe function
286
+ tsfn.Release();
287
+ } );
288
+
289
+ return Boolean::New(env, true);
290
+ }
291
+
292
+ Napi::Object Init( Napi::Env env, Object exports )
293
+ {
294
+ exports.Set( "start", Function::New( env, Start ) );
295
+ return exports;
296
+ }
297
+
298
+ NODE_API_MODULE( clock, Init )
299
+ ```
300
+
301
+ The above code can be used from JavaScript as follows:
302
+
303
+ ```js
304
+ const { start } = require('bindings')('clock');
305
+
306
+ start(function () {
307
+ console.log("JavaScript callback called with arguments", Array.from(arguments));
308
+ }, 5);
309
+ ```
310
+
311
+ When executed, the output will show the value of `clock()` five times at one
312
+ second intervals:
313
+
314
+ ```
315
+ JavaScript callback called with arguments [ 84745 ]
316
+ JavaScript callback called with arguments [ 103211 ]
317
+ JavaScript callback called with arguments [ 104516 ]
318
+ JavaScript callback called with arguments [ 105104 ]
319
+ JavaScript callback called with arguments [ 105691 ]
320
+ ```