source: trip-planner-front/node_modules/node-addon-api/napi.h@ e29cc2e

Last change on this file since e29cc2e was e29cc2e, checked in by Ema <ema_spirova@…>, 3 years ago

primeNG components

  • Property mode set to 100644
File size: 108.6 KB
Line 
1#ifndef SRC_NAPI_H_
2#define SRC_NAPI_H_
3
4#include <node_api.h>
5#include <functional>
6#include <initializer_list>
7#include <memory>
8#include <mutex>
9#include <string>
10#include <vector>
11
12// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known good version)
13#if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
14#define NAPI_HAS_CONSTEXPR 1
15#endif
16
17// VS2013 does not support char16_t literal strings, so we'll work around it using wchar_t strings
18// and casting them. This is safe as long as the character sizes are the same.
19#if defined(_MSC_VER) && _MSC_VER <= 1800
20static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16_t and wchar_t");
21#define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L ## x)
22#else
23#define NAPI_WIDE_TEXT(x) u ## x
24#endif
25
26// If C++ exceptions are not explicitly enabled or disabled, enable them
27// if exceptions were enabled in the compiler settings.
28#if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
29 #if defined(_CPPUNWIND) || defined (__EXCEPTIONS)
30 #define NAPI_CPP_EXCEPTIONS
31 #else
32 #error Exception support not detected. \
33 Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
34 #endif
35#endif
36
37#ifdef _NOEXCEPT
38 #define NAPI_NOEXCEPT _NOEXCEPT
39#else
40 #define NAPI_NOEXCEPT noexcept
41#endif
42
43#ifdef NAPI_CPP_EXCEPTIONS
44
45// When C++ exceptions are enabled, Errors are thrown directly. There is no need
46// to return anything after the throw statements. The variadic parameter is an
47// optional return value that is ignored.
48// We need _VOID versions of the macros to avoid warnings resulting from
49// leaving the NAPI_THROW_* `...` argument empty.
50
51#define NAPI_THROW(e, ...) throw e
52#define NAPI_THROW_VOID(e) throw e
53
54#define NAPI_THROW_IF_FAILED(env, status, ...) \
55 if ((status) != napi_ok) throw Napi::Error::New(env);
56
57#define NAPI_THROW_IF_FAILED_VOID(env, status) \
58 if ((status) != napi_ok) throw Napi::Error::New(env);
59
60#else // NAPI_CPP_EXCEPTIONS
61
62// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
63// which are pending until the callback returns to JS. The variadic parameter
64// is an optional return value; usually it is an empty result.
65// We need _VOID versions of the macros to avoid warnings resulting from
66// leaving the NAPI_THROW_* `...` argument empty.
67
68#define NAPI_THROW(e, ...) \
69 do { \
70 (e).ThrowAsJavaScriptException(); \
71 return __VA_ARGS__; \
72 } while (0)
73
74#define NAPI_THROW_VOID(e) \
75 do { \
76 (e).ThrowAsJavaScriptException(); \
77 return; \
78 } while (0)
79
80#define NAPI_THROW_IF_FAILED(env, status, ...) \
81 if ((status) != napi_ok) { \
82 Napi::Error::New(env).ThrowAsJavaScriptException(); \
83 return __VA_ARGS__; \
84 }
85
86#define NAPI_THROW_IF_FAILED_VOID(env, status) \
87 if ((status) != napi_ok) { \
88 Napi::Error::New(env).ThrowAsJavaScriptException(); \
89 return; \
90 }
91
92#endif // NAPI_CPP_EXCEPTIONS
93
94# define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
95# define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
96
97#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \
98 NAPI_DISALLOW_ASSIGN(CLASS) \
99 NAPI_DISALLOW_COPY(CLASS)
100
101#define NAPI_FATAL_IF_FAILED(status, location, message) \
102 do { \
103 if ((status) != napi_ok) { \
104 Napi::Error::Fatal((location), (message)); \
105 } \
106 } while (0)
107
108////////////////////////////////////////////////////////////////////////////////
109/// Node-API C++ Wrapper Classes
110///
111/// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a
112/// C++ object model and C++ exception-handling semantics with low overhead.
113/// The wrappers are all header-only so that they do not affect the ABI.
114////////////////////////////////////////////////////////////////////////////////
115namespace Napi {
116
117 // Forward declarations
118 class Env;
119 class Value;
120 class Boolean;
121 class Number;
122#if NAPI_VERSION > 5
123 class BigInt;
124#endif // NAPI_VERSION > 5
125#if (NAPI_VERSION > 4)
126 class Date;
127#endif
128 class String;
129 class Object;
130 class Array;
131 class ArrayBuffer;
132 class Function;
133 class Error;
134 class PropertyDescriptor;
135 class CallbackInfo;
136 class TypedArray;
137 template <typename T> class TypedArrayOf;
138
139 using Int8Array =
140 TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers
141 using Uint8Array =
142 TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers
143 using Int16Array =
144 TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers
145 using Uint16Array =
146 TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers
147 using Int32Array =
148 TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers
149 using Uint32Array =
150 TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers
151 using Float32Array =
152 TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values
153 using Float64Array =
154 TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values
155#if NAPI_VERSION > 5
156 using BigInt64Array =
157 TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers
158 using BigUint64Array =
159 TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers
160#endif // NAPI_VERSION > 5
161
162 /// Defines the signature of a Node-API C++ module's registration callback
163 /// (init) function.
164 using ModuleRegisterCallback = Object (*)(Env env, Object exports);
165
166 class MemoryManagement;
167
168 /// Environment for Node-API values and operations.
169 ///
170 /// All Node-API values and operations must be associated with an environment.
171 /// An environment instance is always provided to callback functions; that
172 /// environment must then be used for any creation of Node-API values or other
173 /// Node-API operations within the callback. (Many methods infer the
174 /// environment from the `this` instance that the method is called on.)
175 ///
176 /// In the future, multiple environments per process may be supported,
177 /// although current implementations only support one environment per process.
178 ///
179 /// In the V8 JavaScript engine, a Node-API environment approximately
180 /// corresponds to an Isolate.
181 class Env {
182#if NAPI_VERSION > 5
183 private:
184 template <typename T> static void DefaultFini(Env, T* data);
185 template <typename DataType, typename HintType>
186 static void DefaultFiniWithHint(Env, DataType* data, HintType* hint);
187#endif // NAPI_VERSION > 5
188 public:
189 Env(napi_env env);
190
191 operator napi_env() const;
192
193 Object Global() const;
194 Value Undefined() const;
195 Value Null() const;
196
197 bool IsExceptionPending() const;
198 Error GetAndClearPendingException();
199
200 Value RunScript(const char* utf8script);
201 Value RunScript(const std::string& utf8script);
202 Value RunScript(String script);
203
204#if NAPI_VERSION > 5
205 template <typename T> T* GetInstanceData();
206
207 template <typename T> using Finalizer = void (*)(Env, T*);
208 template <typename T, Finalizer<T> fini = Env::DefaultFini<T>>
209 void SetInstanceData(T* data);
210
211 template <typename DataType, typename HintType>
212 using FinalizerWithHint = void (*)(Env, DataType*, HintType*);
213 template <typename DataType,
214 typename HintType,
215 FinalizerWithHint<DataType, HintType> fini =
216 Env::DefaultFiniWithHint<DataType, HintType>>
217 void SetInstanceData(DataType* data, HintType* hint);
218#endif // NAPI_VERSION > 5
219
220 private:
221 napi_env _env;
222 };
223
224 /// A JavaScript value of unknown type.
225 ///
226 /// For type-specific operations, convert to one of the Value subclasses using a `To*` or `As()`
227 /// method. The `To*` methods do type coercion; the `As()` method does not.
228 ///
229 /// Napi::Value value = ...
230 /// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid arg...");
231 /// Napi::String str = value.As<Napi::String>(); // Cast to a string value
232 ///
233 /// Napi::Value anotherValue = ...
234 /// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value
235 class Value {
236 public:
237 Value(); ///< Creates a new _empty_ Value instance.
238 Value(napi_env env,
239 napi_value value); ///< Wraps a Node-API value primitive.
240
241 /// Creates a JS value from a C++ primitive.
242 ///
243 /// `value` may be any of:
244 /// - bool
245 /// - Any integer type
246 /// - Any floating point type
247 /// - const char* (encoded using UTF-8, null-terminated)
248 /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
249 /// - std::string (encoded using UTF-8)
250 /// - std::u16string
251 /// - napi::Value
252 /// - napi_value
253 template <typename T>
254 static Value From(napi_env env, const T& value);
255
256 /// Converts to a Node-API value primitive.
257 ///
258 /// If the instance is _empty_, this returns `nullptr`.
259 operator napi_value() const;
260
261 /// Tests if this value strictly equals another value.
262 bool operator ==(const Value& other) const;
263
264 /// Tests if this value does not strictly equal another value.
265 bool operator !=(const Value& other) const;
266
267 /// Tests if this value strictly equals another value.
268 bool StrictEquals(const Value& other) const;
269
270 /// Gets the environment the value is associated with.
271 Napi::Env Env() const;
272
273 /// Checks if the value is empty (uninitialized).
274 ///
275 /// An empty value is invalid, and most attempts to perform an operation on an empty value
276 /// will result in an exception. Note an empty value is distinct from JavaScript `null` or
277 /// `undefined`, which are valid values.
278 ///
279 /// When C++ exceptions are disabled at compile time, a method with a `Value` return type may
280 /// return an empty value to indicate a pending exception. So when not using C++ exceptions,
281 /// callers should check whether the value is empty before attempting to use it.
282 bool IsEmpty() const;
283
284 napi_valuetype Type() const; ///< Gets the type of the value.
285
286 bool IsUndefined() const; ///< Tests if a value is an undefined JavaScript value.
287 bool IsNull() const; ///< Tests if a value is a null JavaScript value.
288 bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
289 bool IsNumber() const; ///< Tests if a value is a JavaScript number.
290#if NAPI_VERSION > 5
291 bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
292#endif // NAPI_VERSION > 5
293#if (NAPI_VERSION > 4)
294 bool IsDate() const; ///< Tests if a value is a JavaScript date.
295#endif
296 bool IsString() const; ///< Tests if a value is a JavaScript string.
297 bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
298 bool IsArray() const; ///< Tests if a value is a JavaScript array.
299 bool IsArrayBuffer() const; ///< Tests if a value is a JavaScript array buffer.
300 bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array.
301 bool IsObject() const; ///< Tests if a value is a JavaScript object.
302 bool IsFunction() const; ///< Tests if a value is a JavaScript function.
303 bool IsPromise() const; ///< Tests if a value is a JavaScript promise.
304 bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
305 bool IsBuffer() const; ///< Tests if a value is a Node buffer.
306 bool IsExternal() const; ///< Tests if a value is a pointer to external data.
307
308 /// Casts to another type of `Napi::Value`, when the actual type is known or assumed.
309 ///
310 /// This conversion does NOT coerce the type. Calling any methods inappropriate for the actual
311 /// value type will throw `Napi::Error`.
312 template <typename T> T As() const;
313
314 Boolean ToBoolean() const; ///< Coerces a value to a JavaScript boolean.
315 Number ToNumber() const; ///< Coerces a value to a JavaScript number.
316 String ToString() const; ///< Coerces a value to a JavaScript string.
317 Object ToObject() const; ///< Coerces a value to a JavaScript object.
318
319 protected:
320 /// !cond INTERNAL
321 napi_env _env;
322 napi_value _value;
323 /// !endcond
324 };
325
326 /// A JavaScript boolean value.
327 class Boolean : public Value {
328 public:
329 static Boolean New(napi_env env, ///< Node-API environment
330 bool value ///< Boolean value
331 );
332
333 Boolean(); ///< Creates a new _empty_ Boolean instance.
334 Boolean(napi_env env,
335 napi_value value); ///< Wraps a Node-API value primitive.
336
337 operator bool() const; ///< Converts a Boolean value to a boolean primitive.
338 bool Value() const; ///< Converts a Boolean value to a boolean primitive.
339 };
340
341 /// A JavaScript number value.
342 class Number : public Value {
343 public:
344 static Number New(napi_env env, ///< Node-API environment
345 double value ///< Number value
346 );
347
348 Number(); ///< Creates a new _empty_ Number instance.
349 Number(napi_env env,
350 napi_value value); ///< Wraps a Node-API value primitive.
351
352 operator int32_t()
353 const; ///< Converts a Number value to a 32-bit signed integer value.
354 operator uint32_t()
355 const; ///< Converts a Number value to a 32-bit unsigned integer value.
356 operator int64_t()
357 const; ///< Converts a Number value to a 64-bit signed integer value.
358 operator float()
359 const; ///< Converts a Number value to a 32-bit floating-point value.
360 operator double()
361 const; ///< Converts a Number value to a 64-bit floating-point value.
362
363 int32_t Int32Value()
364 const; ///< Converts a Number value to a 32-bit signed integer value.
365 uint32_t Uint32Value()
366 const; ///< Converts a Number value to a 32-bit unsigned integer value.
367 int64_t Int64Value()
368 const; ///< Converts a Number value to a 64-bit signed integer value.
369 float FloatValue()
370 const; ///< Converts a Number value to a 32-bit floating-point value.
371 double DoubleValue()
372 const; ///< Converts a Number value to a 64-bit floating-point value.
373 };
374
375#if NAPI_VERSION > 5
376 /// A JavaScript bigint value.
377 class BigInt : public Value {
378 public:
379 static BigInt New(napi_env env, ///< Node-API environment
380 int64_t value ///< Number value
381 );
382 static BigInt New(napi_env env, ///< Node-API environment
383 uint64_t value ///< Number value
384 );
385
386 /// Creates a new BigInt object using a specified sign bit and a
387 /// specified list of digits/words.
388 /// The resulting number is calculated as:
389 /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
390 static BigInt New(napi_env env, ///< Node-API environment
391 int sign_bit, ///< Sign bit. 1 if negative.
392 size_t word_count, ///< Number of words in array
393 const uint64_t* words ///< Array of words
394 );
395
396 BigInt(); ///< Creates a new _empty_ BigInt instance.
397 BigInt(napi_env env,
398 napi_value value); ///< Wraps a Node-API value primitive.
399
400 int64_t Int64Value(bool* lossless)
401 const; ///< Converts a BigInt value to a 64-bit signed integer value.
402 uint64_t Uint64Value(bool* lossless)
403 const; ///< Converts a BigInt value to a 64-bit unsigned integer value.
404
405 size_t WordCount() const; ///< The number of 64-bit words needed to store
406 ///< the result of ToWords().
407
408 /// Writes the contents of this BigInt to a specified memory location.
409 /// `sign_bit` must be provided and will be set to 1 if this BigInt is
410 /// negative.
411 /// `*word_count` has to be initialized to the length of the `words` array.
412 /// Upon return, it will be set to the actual number of words that would
413 /// be needed to store this BigInt (i.e. the return value of `WordCount()`).
414 void ToWords(int* sign_bit, size_t* word_count, uint64_t* words);
415 };
416#endif // NAPI_VERSION > 5
417
418#if (NAPI_VERSION > 4)
419 /// A JavaScript date value.
420 class Date : public Value {
421 public:
422 /// Creates a new Date value from a double primitive.
423 static Date New(napi_env env, ///< Node-API environment
424 double value ///< Number value
425 );
426
427 Date(); ///< Creates a new _empty_ Date instance.
428 Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive.
429 operator double() const; ///< Converts a Date value to double primitive
430
431 double ValueOf() const; ///< Converts a Date value to a double primitive.
432 };
433 #endif
434
435 /// A JavaScript string or symbol value (that can be used as a property name).
436 class Name : public Value {
437 public:
438 Name(); ///< Creates a new _empty_ Name instance.
439 Name(napi_env env,
440 napi_value value); ///< Wraps a Node-API value primitive.
441 };
442
443 /// A JavaScript string value.
444 class String : public Name {
445 public:
446 /// Creates a new String value from a UTF-8 encoded C++ string.
447 static String New(napi_env env, ///< Node-API environment
448 const std::string& value ///< UTF-8 encoded C++ string
449 );
450
451 /// Creates a new String value from a UTF-16 encoded C++ string.
452 static String New(napi_env env, ///< Node-API environment
453 const std::u16string& value ///< UTF-16 encoded C++ string
454 );
455
456 /// Creates a new String value from a UTF-8 encoded C string.
457 static String New(
458 napi_env env, ///< Node-API environment
459 const char* value ///< UTF-8 encoded null-terminated C string
460 );
461
462 /// Creates a new String value from a UTF-16 encoded C string.
463 static String New(
464 napi_env env, ///< Node-API environment
465 const char16_t* value ///< UTF-16 encoded null-terminated C string
466 );
467
468 /// Creates a new String value from a UTF-8 encoded C string with specified
469 /// length.
470 static String New(napi_env env, ///< Node-API environment
471 const char* value, ///< UTF-8 encoded C string (not
472 ///< necessarily null-terminated)
473 size_t length ///< length of the string in bytes
474 );
475
476 /// Creates a new String value from a UTF-16 encoded C string with specified
477 /// length.
478 static String New(
479 napi_env env, ///< Node-API environment
480 const char16_t* value, ///< UTF-16 encoded C string (not necessarily
481 ///< null-terminated)
482 size_t length ///< Length of the string in 2-byte code units
483 );
484
485 /// Creates a new String based on the original object's type.
486 ///
487 /// `value` may be any of:
488 /// - const char* (encoded using UTF-8, null-terminated)
489 /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
490 /// - std::string (encoded using UTF-8)
491 /// - std::u16string
492 template <typename T>
493 static String From(napi_env env, const T& value);
494
495 String(); ///< Creates a new _empty_ String instance.
496 String(napi_env env,
497 napi_value value); ///< Wraps a Node-API value primitive.
498
499 operator std::string()
500 const; ///< Converts a String value to a UTF-8 encoded C++ string.
501 operator std::u16string()
502 const; ///< Converts a String value to a UTF-16 encoded C++ string.
503 std::string Utf8Value()
504 const; ///< Converts a String value to a UTF-8 encoded C++ string.
505 std::u16string Utf16Value()
506 const; ///< Converts a String value to a UTF-16 encoded C++ string.
507 };
508
509 /// A JavaScript symbol value.
510 class Symbol : public Name {
511 public:
512 /// Creates a new Symbol value with an optional description.
513 static Symbol New(
514 napi_env env, ///< Node-API environment
515 const char* description =
516 nullptr ///< Optional UTF-8 encoded null-terminated C string
517 /// describing the symbol
518 );
519
520 /// Creates a new Symbol value with a description.
521 static Symbol New(
522 napi_env env, ///< Node-API environment
523 const std::string&
524 description ///< UTF-8 encoded C++ string describing the symbol
525 );
526
527 /// Creates a new Symbol value with a description.
528 static Symbol New(napi_env env, ///< Node-API environment
529 String description ///< String value describing the symbol
530 );
531
532 /// Creates a new Symbol value with a description.
533 static Symbol New(
534 napi_env env, ///< Node-API environment
535 napi_value description ///< String value describing the symbol
536 );
537
538 /// Get a public Symbol (e.g. Symbol.iterator).
539 static Symbol WellKnown(napi_env, const std::string& name);
540
541 Symbol(); ///< Creates a new _empty_ Symbol instance.
542 Symbol(napi_env env,
543 napi_value value); ///< Wraps a Node-API value primitive.
544 };
545
546 /// A JavaScript object value.
547 class Object : public Value {
548 public:
549 /// Enables property and element assignments using indexing syntax.
550 ///
551 /// Example:
552 ///
553 /// Napi::Value propertyValue = object1['A'];
554 /// object2['A'] = propertyValue;
555 /// Napi::Value elementValue = array[0];
556 /// array[1] = elementValue;
557 template <typename Key>
558 class PropertyLValue {
559 public:
560 /// Converts an L-value to a value.
561 operator Value() const;
562
563 /// Assigns a value to the property. The type of value can be
564 /// anything supported by `Object::Set`.
565 template <typename ValueType>
566 PropertyLValue& operator =(ValueType value);
567
568 private:
569 PropertyLValue() = delete;
570 PropertyLValue(Object object, Key key);
571 napi_env _env;
572 napi_value _object;
573 Key _key;
574
575 friend class Napi::Object;
576 };
577
578 /// Creates a new Object value.
579 static Object New(napi_env env ///< Node-API environment
580 );
581
582 Object(); ///< Creates a new _empty_ Object instance.
583 Object(napi_env env,
584 napi_value value); ///< Wraps a Node-API value primitive.
585
586 /// Gets or sets a named property.
587 PropertyLValue<std::string> operator [](
588 const char* utf8name ///< UTF-8 encoded null-terminated property name
589 );
590
591 /// Gets or sets a named property.
592 PropertyLValue<std::string> operator [](
593 const std::string& utf8name ///< UTF-8 encoded property name
594 );
595
596 /// Gets or sets an indexed property or array element.
597 PropertyLValue<uint32_t> operator [](
598 uint32_t index /// Property / element index
599 );
600
601 /// Gets a named property.
602 Value operator [](
603 const char* utf8name ///< UTF-8 encoded null-terminated property name
604 ) const;
605
606 /// Gets a named property.
607 Value operator [](
608 const std::string& utf8name ///< UTF-8 encoded property name
609 ) const;
610
611 /// Gets an indexed property or array element.
612 Value operator [](
613 uint32_t index ///< Property / element index
614 ) const;
615
616 /// Checks whether a property is present.
617 bool Has(
618 napi_value key ///< Property key primitive
619 ) const;
620
621 /// Checks whether a property is present.
622 bool Has(
623 Value key ///< Property key
624 ) const;
625
626 /// Checks whether a named property is present.
627 bool Has(
628 const char* utf8name ///< UTF-8 encoded null-terminated property name
629 ) const;
630
631 /// Checks whether a named property is present.
632 bool Has(
633 const std::string& utf8name ///< UTF-8 encoded property name
634 ) const;
635
636 /// Checks whether a own property is present.
637 bool HasOwnProperty(
638 napi_value key ///< Property key primitive
639 ) const;
640
641 /// Checks whether a own property is present.
642 bool HasOwnProperty(
643 Value key ///< Property key
644 ) const;
645
646 /// Checks whether a own property is present.
647 bool HasOwnProperty(
648 const char* utf8name ///< UTF-8 encoded null-terminated property name
649 ) const;
650
651 /// Checks whether a own property is present.
652 bool HasOwnProperty(
653 const std::string& utf8name ///< UTF-8 encoded property name
654 ) const;
655
656 /// Gets a property.
657 Value Get(
658 napi_value key ///< Property key primitive
659 ) const;
660
661 /// Gets a property.
662 Value Get(
663 Value key ///< Property key
664 ) const;
665
666 /// Gets a named property.
667 Value Get(
668 const char* utf8name ///< UTF-8 encoded null-terminated property name
669 ) const;
670
671 /// Gets a named property.
672 Value Get(
673 const std::string& utf8name ///< UTF-8 encoded property name
674 ) const;
675
676 /// Sets a property.
677 template <typename ValueType>
678 bool Set(napi_value key, ///< Property key primitive
679 const ValueType& value ///< Property value primitive
680 );
681
682 /// Sets a property.
683 template <typename ValueType>
684 bool Set(Value key, ///< Property key
685 const ValueType& value ///< Property value
686 );
687
688 /// Sets a named property.
689 template <typename ValueType>
690 bool Set(
691 const char* utf8name, ///< UTF-8 encoded null-terminated property name
692 const ValueType& value);
693
694 /// Sets a named property.
695 template <typename ValueType>
696 bool Set(const std::string& utf8name, ///< UTF-8 encoded property name
697 const ValueType& value ///< Property value primitive
698 );
699
700 /// Delete property.
701 bool Delete(
702 napi_value key ///< Property key primitive
703 );
704
705 /// Delete property.
706 bool Delete(
707 Value key ///< Property key
708 );
709
710 /// Delete property.
711 bool Delete(
712 const char* utf8name ///< UTF-8 encoded null-terminated property name
713 );
714
715 /// Delete property.
716 bool Delete(
717 const std::string& utf8name ///< UTF-8 encoded property name
718 );
719
720 /// Checks whether an indexed property is present.
721 bool Has(
722 uint32_t index ///< Property / element index
723 ) const;
724
725 /// Gets an indexed property or array element.
726 Value Get(
727 uint32_t index ///< Property / element index
728 ) const;
729
730 /// Sets an indexed property or array element.
731 template <typename ValueType>
732 bool Set(uint32_t index, ///< Property / element index
733 const ValueType& value ///< Property value primitive
734 );
735
736 /// Deletes an indexed property or array element.
737 bool Delete(
738 uint32_t index ///< Property / element index
739 );
740
741 Array GetPropertyNames() const; ///< Get all property names
742
743 /// Defines a property on the object.
744 bool DefineProperty(
745 const PropertyDescriptor&
746 property ///< Descriptor for the property to be defined
747 );
748
749 /// Defines properties on the object.
750 bool DefineProperties(
751 const std::initializer_list<PropertyDescriptor>& properties
752 ///< List of descriptors for the properties to be defined
753 );
754
755 /// Defines properties on the object.
756 bool DefineProperties(
757 const std::vector<PropertyDescriptor>& properties
758 ///< Vector of descriptors for the properties to be defined
759 );
760
761 /// Checks if an object is an instance created by a constructor function.
762 ///
763 /// This is equivalent to the JavaScript `instanceof` operator.
764 bool InstanceOf(
765 const Function& constructor ///< Constructor function
766 ) const;
767
768 template <typename Finalizer, typename T>
769 inline void AddFinalizer(Finalizer finalizeCallback, T* data);
770
771 template <typename Finalizer, typename T, typename Hint>
772 inline void AddFinalizer(Finalizer finalizeCallback,
773 T* data,
774 Hint* finalizeHint);
775#if NAPI_VERSION >= 8
776 bool Freeze();
777 bool Seal();
778#endif // NAPI_VERSION >= 8
779 };
780
781 template <typename T>
782 class External : public Value {
783 public:
784 static External New(napi_env env, T* data);
785
786 // Finalizer must implement `void operator()(Env env, T* data)`.
787 template <typename Finalizer>
788 static External New(napi_env env,
789 T* data,
790 Finalizer finalizeCallback);
791 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
792 template <typename Finalizer, typename Hint>
793 static External New(napi_env env,
794 T* data,
795 Finalizer finalizeCallback,
796 Hint* finalizeHint);
797
798 External();
799 External(napi_env env, napi_value value);
800
801 T* Data() const;
802 };
803
804 class Array : public Object {
805 public:
806 static Array New(napi_env env);
807 static Array New(napi_env env, size_t length);
808
809 Array();
810 Array(napi_env env, napi_value value);
811
812 uint32_t Length() const;
813 };
814
815 /// A JavaScript array buffer value.
816 class ArrayBuffer : public Object {
817 public:
818 /// Creates a new ArrayBuffer instance over a new automatically-allocated buffer.
819 static ArrayBuffer New(
820 napi_env env, ///< Node-API environment
821 size_t byteLength ///< Length of the buffer to be allocated, in bytes
822 );
823
824 /// Creates a new ArrayBuffer instance, using an external buffer with
825 /// specified byte length.
826 static ArrayBuffer New(
827 napi_env env, ///< Node-API environment
828 void* externalData, ///< Pointer to the external buffer to be used by
829 ///< the array
830 size_t byteLength ///< Length of the external buffer to be used by the
831 ///< array, in bytes
832 );
833
834 /// Creates a new ArrayBuffer instance, using an external buffer with
835 /// specified byte length.
836 template <typename Finalizer>
837 static ArrayBuffer New(
838 napi_env env, ///< Node-API environment
839 void* externalData, ///< Pointer to the external buffer to be used by
840 ///< the array
841 size_t byteLength, ///< Length of the external buffer to be used by the
842 ///< array,
843 /// in bytes
844 Finalizer finalizeCallback ///< Function to be called when the array
845 ///< buffer is destroyed;
846 /// must implement `void operator()(Env env,
847 /// void* externalData)`
848 );
849
850 /// Creates a new ArrayBuffer instance, using an external buffer with
851 /// specified byte length.
852 template <typename Finalizer, typename Hint>
853 static ArrayBuffer New(
854 napi_env env, ///< Node-API environment
855 void* externalData, ///< Pointer to the external buffer to be used by
856 ///< the array
857 size_t byteLength, ///< Length of the external buffer to be used by the
858 ///< array,
859 /// in bytes
860 Finalizer finalizeCallback, ///< Function to be called when the array
861 ///< buffer is destroyed;
862 /// must implement `void operator()(Env
863 /// env, void* externalData, Hint* hint)`
864 Hint* finalizeHint ///< Hint (second parameter) to be passed to the
865 ///< finalize callback
866 );
867
868 ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance.
869 ArrayBuffer(napi_env env,
870 napi_value value); ///< Wraps a Node-API value primitive.
871
872 void* Data(); ///< Gets a pointer to the data buffer.
873 size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
874
875#if NAPI_VERSION >= 7
876 bool IsDetached() const;
877 void Detach();
878#endif // NAPI_VERSION >= 7
879 };
880
881 /// A JavaScript typed-array value with unknown array type.
882 ///
883 /// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the `As()`
884 /// method:
885 ///
886 /// Napi::TypedArray array = ...
887 /// if (t.TypedArrayType() == napi_int32_array) {
888 /// Napi::Int32Array int32Array = t.As<Napi::Int32Array>();
889 /// }
890 class TypedArray : public Object {
891 public:
892 TypedArray(); ///< Creates a new _empty_ TypedArray instance.
893 TypedArray(napi_env env,
894 napi_value value); ///< Wraps a Node-API value primitive.
895
896 napi_typedarray_type TypedArrayType() const; ///< Gets the type of this typed-array.
897 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
898
899 uint8_t ElementSize() const; ///< Gets the size in bytes of one element in the array.
900 size_t ElementLength() const; ///< Gets the number of elements in the array.
901 size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts.
902 size_t ByteLength() const; ///< Gets the length of the array in bytes.
903
904 protected:
905 /// !cond INTERNAL
906 napi_typedarray_type _type;
907 size_t _length;
908
909 TypedArray(napi_env env, napi_value value, napi_typedarray_type type, size_t length);
910
911 static const napi_typedarray_type unknown_array_type = static_cast<napi_typedarray_type>(-1);
912
913 template <typename T>
914 static
915#if defined(NAPI_HAS_CONSTEXPR)
916 constexpr
917#endif
918 napi_typedarray_type TypedArrayTypeForPrimitiveType() {
919 return std::is_same<T, int8_t>::value ? napi_int8_array
920 : std::is_same<T, uint8_t>::value ? napi_uint8_array
921 : std::is_same<T, int16_t>::value ? napi_int16_array
922 : std::is_same<T, uint16_t>::value ? napi_uint16_array
923 : std::is_same<T, int32_t>::value ? napi_int32_array
924 : std::is_same<T, uint32_t>::value ? napi_uint32_array
925 : std::is_same<T, float>::value ? napi_float32_array
926 : std::is_same<T, double>::value ? napi_float64_array
927#if NAPI_VERSION > 5
928 : std::is_same<T, int64_t>::value ? napi_bigint64_array
929 : std::is_same<T, uint64_t>::value ? napi_biguint64_array
930#endif // NAPI_VERSION > 5
931 : unknown_array_type;
932 }
933 /// !endcond
934 };
935
936 /// A JavaScript typed-array value with known array type.
937 ///
938 /// Note while it is possible to create and access Uint8 "clamped" arrays using this class,
939 /// the _clamping_ behavior is only applied in JavaScript.
940 template <typename T>
941 class TypedArrayOf : public TypedArray {
942 public:
943 /// Creates a new TypedArray instance over a new automatically-allocated array buffer.
944 ///
945 /// The array type parameter can normally be omitted (because it is inferred from the template
946 /// parameter T), except when creating a "clamped" array:
947 ///
948 /// Uint8Array::New(env, length, napi_uint8_clamped_array)
949 static TypedArrayOf New(
950 napi_env env, ///< Node-API environment
951 size_t elementLength, ///< Length of the created array, as a number of
952 ///< elements
953#if defined(NAPI_HAS_CONSTEXPR)
954 napi_typedarray_type type =
955 TypedArray::TypedArrayTypeForPrimitiveType<T>()
956#else
957 napi_typedarray_type type
958#endif
959 ///< Type of array, if different from the default array type for the
960 ///< template parameter T.
961 );
962
963 /// Creates a new TypedArray instance over a provided array buffer.
964 ///
965 /// The array type parameter can normally be omitted (because it is inferred from the template
966 /// parameter T), except when creating a "clamped" array:
967 ///
968 /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array)
969 static TypedArrayOf New(
970 napi_env env, ///< Node-API environment
971 size_t elementLength, ///< Length of the created array, as a number of
972 ///< elements
973 Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use
974 size_t bufferOffset, ///< Offset into the array buffer where the
975 ///< typed-array starts
976#if defined(NAPI_HAS_CONSTEXPR)
977 napi_typedarray_type type =
978 TypedArray::TypedArrayTypeForPrimitiveType<T>()
979#else
980 napi_typedarray_type type
981#endif
982 ///< Type of array, if different from the default array type for the
983 ///< template parameter T.
984 );
985
986 TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance.
987 TypedArrayOf(napi_env env,
988 napi_value value); ///< Wraps a Node-API value primitive.
989
990 T& operator [](size_t index); ///< Gets or sets an element in the array.
991 const T& operator [](size_t index) const; ///< Gets an element in the array.
992
993 /// Gets a pointer to the array's backing buffer.
994 ///
995 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the
996 /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`.
997 T* Data();
998
999 /// Gets a pointer to the array's backing buffer.
1000 ///
1001 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the
1002 /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`.
1003 const T* Data() const;
1004
1005 private:
1006 T* _data;
1007
1008 TypedArrayOf(napi_env env,
1009 napi_value value,
1010 napi_typedarray_type type,
1011 size_t length,
1012 T* data);
1013 };
1014
1015 /// The DataView provides a low-level interface for reading/writing multiple
1016 /// number types in an ArrayBuffer irrespective of the platform's endianness.
1017 class DataView : public Object {
1018 public:
1019 static DataView New(napi_env env,
1020 Napi::ArrayBuffer arrayBuffer);
1021 static DataView New(napi_env env,
1022 Napi::ArrayBuffer arrayBuffer,
1023 size_t byteOffset);
1024 static DataView New(napi_env env,
1025 Napi::ArrayBuffer arrayBuffer,
1026 size_t byteOffset,
1027 size_t byteLength);
1028
1029 DataView(); ///< Creates a new _empty_ DataView instance.
1030 DataView(napi_env env,
1031 napi_value value); ///< Wraps a Node-API value primitive.
1032
1033 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1034 size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts.
1035 size_t ByteLength() const; ///< Gets the length of the array in bytes.
1036
1037 void* Data() const;
1038
1039 float GetFloat32(size_t byteOffset) const;
1040 double GetFloat64(size_t byteOffset) const;
1041 int8_t GetInt8(size_t byteOffset) const;
1042 int16_t GetInt16(size_t byteOffset) const;
1043 int32_t GetInt32(size_t byteOffset) const;
1044 uint8_t GetUint8(size_t byteOffset) const;
1045 uint16_t GetUint16(size_t byteOffset) const;
1046 uint32_t GetUint32(size_t byteOffset) const;
1047
1048 void SetFloat32(size_t byteOffset, float value) const;
1049 void SetFloat64(size_t byteOffset, double value) const;
1050 void SetInt8(size_t byteOffset, int8_t value) const;
1051 void SetInt16(size_t byteOffset, int16_t value) const;
1052 void SetInt32(size_t byteOffset, int32_t value) const;
1053 void SetUint8(size_t byteOffset, uint8_t value) const;
1054 void SetUint16(size_t byteOffset, uint16_t value) const;
1055 void SetUint32(size_t byteOffset, uint32_t value) const;
1056
1057 private:
1058 template <typename T>
1059 T ReadData(size_t byteOffset) const;
1060
1061 template <typename T>
1062 void WriteData(size_t byteOffset, T value) const;
1063
1064 void* _data;
1065 size_t _length;
1066 };
1067
1068 class Function : public Object {
1069 public:
1070 using VoidCallback = void (*)(const CallbackInfo& info);
1071 using Callback = Value (*)(const CallbackInfo& info);
1072
1073 template <VoidCallback cb>
1074 static Function New(napi_env env,
1075 const char* utf8name = nullptr,
1076 void* data = nullptr);
1077
1078 template <Callback cb>
1079 static Function New(napi_env env,
1080 const char* utf8name = nullptr,
1081 void* data = nullptr);
1082
1083 template <VoidCallback cb>
1084 static Function New(napi_env env,
1085 const std::string& utf8name,
1086 void* data = nullptr);
1087
1088 template <Callback cb>
1089 static Function New(napi_env env,
1090 const std::string& utf8name,
1091 void* data = nullptr);
1092
1093 /// Callable must implement operator() accepting a const CallbackInfo&
1094 /// and return either void or Value.
1095 template <typename Callable>
1096 static Function New(napi_env env,
1097 Callable cb,
1098 const char* utf8name = nullptr,
1099 void* data = nullptr);
1100 /// Callable must implement operator() accepting a const CallbackInfo&
1101 /// and return either void or Value.
1102 template <typename Callable>
1103 static Function New(napi_env env,
1104 Callable cb,
1105 const std::string& utf8name,
1106 void* data = nullptr);
1107
1108 Function();
1109 Function(napi_env env, napi_value value);
1110
1111 Value operator()(const std::initializer_list<napi_value>& args) const;
1112
1113 Value Call(const std::initializer_list<napi_value>& args) const;
1114 Value Call(const std::vector<napi_value>& args) const;
1115 Value Call(size_t argc, const napi_value* args) const;
1116 Value Call(napi_value recv,
1117 const std::initializer_list<napi_value>& args) const;
1118 Value Call(napi_value recv, const std::vector<napi_value>& args) const;
1119 Value Call(napi_value recv, size_t argc, const napi_value* args) const;
1120
1121 Value MakeCallback(napi_value recv,
1122 const std::initializer_list<napi_value>& args,
1123 napi_async_context context = nullptr) const;
1124 Value MakeCallback(napi_value recv,
1125 const std::vector<napi_value>& args,
1126 napi_async_context context = nullptr) const;
1127 Value MakeCallback(napi_value recv,
1128 size_t argc,
1129 const napi_value* args,
1130 napi_async_context context = nullptr) const;
1131
1132 Object New(const std::initializer_list<napi_value>& args) const;
1133 Object New(const std::vector<napi_value>& args) const;
1134 Object New(size_t argc, const napi_value* args) const;
1135 };
1136
1137 class Promise : public Object {
1138 public:
1139 class Deferred {
1140 public:
1141 static Deferred New(napi_env env);
1142 Deferred(napi_env env);
1143
1144 Napi::Promise Promise() const;
1145 Napi::Env Env() const;
1146
1147 void Resolve(napi_value value) const;
1148 void Reject(napi_value value) const;
1149
1150 private:
1151 napi_env _env;
1152 napi_deferred _deferred;
1153 napi_value _promise;
1154 };
1155
1156 Promise(napi_env env, napi_value value);
1157 };
1158
1159 template <typename T>
1160 class Buffer : public Uint8Array {
1161 public:
1162 static Buffer<T> New(napi_env env, size_t length);
1163 static Buffer<T> New(napi_env env, T* data, size_t length);
1164
1165 // Finalizer must implement `void operator()(Env env, T* data)`.
1166 template <typename Finalizer>
1167 static Buffer<T> New(napi_env env, T* data,
1168 size_t length,
1169 Finalizer finalizeCallback);
1170 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1171 template <typename Finalizer, typename Hint>
1172 static Buffer<T> New(napi_env env, T* data,
1173 size_t length,
1174 Finalizer finalizeCallback,
1175 Hint* finalizeHint);
1176
1177 static Buffer<T> Copy(napi_env env, const T* data, size_t length);
1178
1179 Buffer();
1180 Buffer(napi_env env, napi_value value);
1181 size_t Length() const;
1182 T* Data() const;
1183
1184 private:
1185 mutable size_t _length;
1186 mutable T* _data;
1187
1188 Buffer(napi_env env, napi_value value, size_t length, T* data);
1189 void EnsureInfo() const;
1190 };
1191
1192 /// Holds a counted reference to a value; initially a weak reference unless otherwise specified,
1193 /// may be changed to/from a strong reference by adjusting the refcount.
1194 ///
1195 /// The referenced value is not immediately destroyed when the reference count is zero; it is
1196 /// merely then eligible for garbage-collection if there are no other references to the value.
1197 template <typename T>
1198 class Reference {
1199 public:
1200 static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
1201
1202 Reference();
1203 Reference(napi_env env, napi_ref ref);
1204 ~Reference();
1205
1206 // A reference can be moved but cannot be copied.
1207 Reference(Reference<T>&& other);
1208 Reference<T>& operator =(Reference<T>&& other);
1209 NAPI_DISALLOW_ASSIGN(Reference<T>)
1210
1211 operator napi_ref() const;
1212 bool operator ==(const Reference<T> &other) const;
1213 bool operator !=(const Reference<T> &other) const;
1214
1215 Napi::Env Env() const;
1216 bool IsEmpty() const;
1217
1218 // Note when getting the value of a Reference it is usually correct to do so
1219 // within a HandleScope so that the value handle gets cleaned up efficiently.
1220 T Value() const;
1221
1222 uint32_t Ref();
1223 uint32_t Unref();
1224 void Reset();
1225 void Reset(const T& value, uint32_t refcount = 0);
1226
1227 // Call this on a reference that is declared as static data, to prevent its
1228 // destructor from running at program shutdown time, which would attempt to
1229 // reset the reference when the environment is no longer valid. Avoid using
1230 // this if at all possible. If you do need to use static data, MAKE SURE to
1231 // warn your users that your addon is NOT threadsafe.
1232 void SuppressDestruct();
1233
1234 protected:
1235 Reference(const Reference<T>&);
1236
1237 /// !cond INTERNAL
1238 napi_env _env;
1239 napi_ref _ref;
1240 /// !endcond
1241
1242 private:
1243 bool _suppressDestruct;
1244 };
1245
1246 class ObjectReference: public Reference<Object> {
1247 public:
1248 ObjectReference();
1249 ObjectReference(napi_env env, napi_ref ref);
1250
1251 // A reference can be moved but cannot be copied.
1252 ObjectReference(Reference<Object>&& other);
1253 ObjectReference& operator =(Reference<Object>&& other);
1254 ObjectReference(ObjectReference&& other);
1255 ObjectReference& operator =(ObjectReference&& other);
1256 NAPI_DISALLOW_ASSIGN(ObjectReference)
1257
1258 Napi::Value Get(const char* utf8name) const;
1259 Napi::Value Get(const std::string& utf8name) const;
1260 bool Set(const char* utf8name, napi_value value);
1261 bool Set(const char* utf8name, Napi::Value value);
1262 bool Set(const char* utf8name, const char* utf8value);
1263 bool Set(const char* utf8name, bool boolValue);
1264 bool Set(const char* utf8name, double numberValue);
1265 bool Set(const std::string& utf8name, napi_value value);
1266 bool Set(const std::string& utf8name, Napi::Value value);
1267 bool Set(const std::string& utf8name, std::string& utf8value);
1268 bool Set(const std::string& utf8name, bool boolValue);
1269 bool Set(const std::string& utf8name, double numberValue);
1270
1271 Napi::Value Get(uint32_t index) const;
1272 bool Set(uint32_t index, const napi_value value);
1273 bool Set(uint32_t index, const Napi::Value value);
1274 bool Set(uint32_t index, const char* utf8value);
1275 bool Set(uint32_t index, const std::string& utf8value);
1276 bool Set(uint32_t index, bool boolValue);
1277 bool Set(uint32_t index, double numberValue);
1278
1279 protected:
1280 ObjectReference(const ObjectReference&);
1281 };
1282
1283 class FunctionReference: public Reference<Function> {
1284 public:
1285 FunctionReference();
1286 FunctionReference(napi_env env, napi_ref ref);
1287
1288 // A reference can be moved but cannot be copied.
1289 FunctionReference(Reference<Function>&& other);
1290 FunctionReference& operator =(Reference<Function>&& other);
1291 FunctionReference(FunctionReference&& other);
1292 FunctionReference& operator =(FunctionReference&& other);
1293 NAPI_DISALLOW_ASSIGN_COPY(FunctionReference)
1294
1295 Napi::Value operator ()(const std::initializer_list<napi_value>& args) const;
1296
1297 Napi::Value Call(const std::initializer_list<napi_value>& args) const;
1298 Napi::Value Call(const std::vector<napi_value>& args) const;
1299 Napi::Value Call(napi_value recv, const std::initializer_list<napi_value>& args) const;
1300 Napi::Value Call(napi_value recv, const std::vector<napi_value>& args) const;
1301 Napi::Value Call(napi_value recv, size_t argc, const napi_value* args) const;
1302
1303 Napi::Value MakeCallback(napi_value recv,
1304 const std::initializer_list<napi_value>& args,
1305 napi_async_context context = nullptr) const;
1306 Napi::Value MakeCallback(napi_value recv,
1307 const std::vector<napi_value>& args,
1308 napi_async_context context = nullptr) const;
1309 Napi::Value MakeCallback(napi_value recv,
1310 size_t argc,
1311 const napi_value* args,
1312 napi_async_context context = nullptr) const;
1313
1314 Object New(const std::initializer_list<napi_value>& args) const;
1315 Object New(const std::vector<napi_value>& args) const;
1316 };
1317
1318 // Shortcuts to creating a new reference with inferred type and refcount = 0.
1319 template <typename T> Reference<T> Weak(T value);
1320 ObjectReference Weak(Object value);
1321 FunctionReference Weak(Function value);
1322
1323 // Shortcuts to creating a new reference with inferred type and refcount = 1.
1324 template <typename T> Reference<T> Persistent(T value);
1325 ObjectReference Persistent(Object value);
1326 FunctionReference Persistent(Function value);
1327
1328 /// A persistent reference to a JavaScript error object. Use of this class
1329 /// depends somewhat on whether C++ exceptions are enabled at compile time.
1330 ///
1331 /// ### Handling Errors With C++ Exceptions
1332 ///
1333 /// If C++ exceptions are enabled, then the `Error` class extends
1334 /// `std::exception` and enables integrated error-handling for C++ exceptions
1335 /// and JavaScript exceptions.
1336 ///
1337 /// If a Node-API call fails without executing any JavaScript code (for
1338 /// example due to an invalid argument), then the Node-API wrapper
1339 /// automatically converts and throws the error as a C++ exception of type
1340 /// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API
1341 /// throws a JavaScript exception, then the Node-API wrapper automatically
1342 /// converts and throws it as a C++ exception of type `Napi::Error`.
1343 ///
1344 /// If a C++ exception of type `Napi::Error` escapes from a Node-API C++
1345 /// callback, then the Node-API wrapper automatically converts and throws it
1346 /// as a JavaScript exception. Therefore, catching a C++ exception of type
1347 /// `Napi::Error` prevents a JavaScript exception from being thrown.
1348 ///
1349 /// #### Example 1A - Throwing a C++ exception:
1350 ///
1351 /// Napi::Env env = ...
1352 /// throw Napi::Error::New(env, "Example exception");
1353 ///
1354 /// Following C++ statements will not be executed. The exception will bubble
1355 /// up as a C++ exception of type `Napi::Error`, until it is either caught
1356 /// while still in C++, or else automatically propataged as a JavaScript
1357 /// exception when the callback returns to JavaScript.
1358 ///
1359 /// #### Example 2A - Propagating a Node-API C++ exception:
1360 ///
1361 /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1362 /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1363 ///
1364 /// Following C++ statements will not be executed. The exception will bubble
1365 /// up as a C++ exception of type `Napi::Error`, until it is either caught
1366 /// while still in C++, or else automatically propagated as a JavaScript
1367 /// exception when the callback returns to JavaScript.
1368 ///
1369 /// #### Example 3A - Handling a Node-API C++ exception:
1370 ///
1371 /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1372 /// Napi::Value result;
1373 /// try {
1374 /// result = jsFunctionThatThrows({ arg1, arg2 });
1375 /// } catch (const Napi::Error& e) {
1376 /// cerr << "Caught JavaScript exception: " + e.what();
1377 /// }
1378 ///
1379 /// Since the exception was caught here, it will not be propagated as a
1380 /// JavaScript exception.
1381 ///
1382 /// ### Handling Errors Without C++ Exceptions
1383 ///
1384 /// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`)
1385 /// then this class does not extend `std::exception`, and APIs in the `Napi`
1386 /// namespace do not throw C++ exceptions when they fail. Instead, they raise
1387 /// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code
1388 /// should check `Value::IsEmpty()` before attempting to use a returned value,
1389 /// and may use methods on the `Env` class to check for, get, and clear a
1390 /// pending JavaScript exception. If the pending exception is not cleared, it
1391 /// will be thrown when the native callback returns to JavaScript.
1392 ///
1393 /// #### Example 1B - Throwing a JS exception
1394 ///
1395 /// Napi::Env env = ...
1396 /// Napi::Error::New(env, "Example
1397 /// exception").ThrowAsJavaScriptException(); return;
1398 ///
1399 /// After throwing a JS exception, the code should generally return
1400 /// immediately from the native callback, after performing any necessary
1401 /// cleanup.
1402 ///
1403 /// #### Example 2B - Propagating a Node-API JS exception:
1404 ///
1405 /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1406 /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1407 /// if (result.IsEmpty()) return;
1408 ///
1409 /// An empty value result from a Node-API call indicates an error occurred,
1410 /// and a JavaScript exception is pending. To let the exception propagate, the
1411 /// code should generally return immediately from the native callback, after
1412 /// performing any necessary cleanup.
1413 ///
1414 /// #### Example 3B - Handling a Node-API JS exception:
1415 ///
1416 /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1417 /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1418 /// if (result.IsEmpty()) {
1419 /// Napi::Error e = env.GetAndClearPendingException();
1420 /// cerr << "Caught JavaScript exception: " + e.Message();
1421 /// }
1422 ///
1423 /// Since the exception was cleared here, it will not be propagated as a
1424 /// JavaScript exception after the native callback returns.
1425 class Error : public ObjectReference
1426#ifdef NAPI_CPP_EXCEPTIONS
1427 , public std::exception
1428#endif // NAPI_CPP_EXCEPTIONS
1429 {
1430 public:
1431 static Error New(napi_env env);
1432 static Error New(napi_env env, const char* message);
1433 static Error New(napi_env env, const std::string& message);
1434
1435 static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
1436
1437 Error();
1438 Error(napi_env env, napi_value value);
1439
1440 // An error can be moved or copied.
1441 Error(Error&& other);
1442 Error& operator =(Error&& other);
1443 Error(const Error&);
1444 Error& operator =(const Error&);
1445
1446 const std::string& Message() const NAPI_NOEXCEPT;
1447 void ThrowAsJavaScriptException() const;
1448
1449#ifdef NAPI_CPP_EXCEPTIONS
1450 const char* what() const NAPI_NOEXCEPT override;
1451#endif // NAPI_CPP_EXCEPTIONS
1452
1453 protected:
1454 /// !cond INTERNAL
1455 using create_error_fn = napi_status (*)(napi_env envb,
1456 napi_value code,
1457 napi_value msg,
1458 napi_value* result);
1459
1460 template <typename TError>
1461 static TError New(napi_env env,
1462 const char* message,
1463 size_t length,
1464 create_error_fn create_error);
1465 /// !endcond
1466
1467 private:
1468 mutable std::string _message;
1469 };
1470
1471 class TypeError : public Error {
1472 public:
1473 static TypeError New(napi_env env, const char* message);
1474 static TypeError New(napi_env env, const std::string& message);
1475
1476 TypeError();
1477 TypeError(napi_env env, napi_value value);
1478 };
1479
1480 class RangeError : public Error {
1481 public:
1482 static RangeError New(napi_env env, const char* message);
1483 static RangeError New(napi_env env, const std::string& message);
1484
1485 RangeError();
1486 RangeError(napi_env env, napi_value value);
1487 };
1488
1489 class CallbackInfo {
1490 public:
1491 CallbackInfo(napi_env env, napi_callback_info info);
1492 ~CallbackInfo();
1493
1494 // Disallow copying to prevent multiple free of _dynamicArgs
1495 NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo)
1496
1497 Napi::Env Env() const;
1498 Value NewTarget() const;
1499 bool IsConstructCall() const;
1500 size_t Length() const;
1501 const Value operator [](size_t index) const;
1502 Value This() const;
1503 void* Data() const;
1504 void SetData(void* data);
1505
1506 private:
1507 const size_t _staticArgCount = 6;
1508 napi_env _env;
1509 napi_callback_info _info;
1510 napi_value _this;
1511 size_t _argc;
1512 napi_value* _argv;
1513 napi_value _staticArgs[6];
1514 napi_value* _dynamicArgs;
1515 void* _data;
1516 };
1517
1518 class PropertyDescriptor {
1519 public:
1520 using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info);
1521 using SetterCallback = void (*)(const Napi::CallbackInfo& info);
1522
1523#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
1524 template <typename Getter>
1525 static PropertyDescriptor Accessor(const char* utf8name,
1526 Getter getter,
1527 napi_property_attributes attributes = napi_default,
1528 void* data = nullptr);
1529 template <typename Getter>
1530 static PropertyDescriptor Accessor(const std::string& utf8name,
1531 Getter getter,
1532 napi_property_attributes attributes = napi_default,
1533 void* data = nullptr);
1534 template <typename Getter>
1535 static PropertyDescriptor Accessor(napi_value name,
1536 Getter getter,
1537 napi_property_attributes attributes = napi_default,
1538 void* data = nullptr);
1539 template <typename Getter>
1540 static PropertyDescriptor Accessor(Name name,
1541 Getter getter,
1542 napi_property_attributes attributes = napi_default,
1543 void* data = nullptr);
1544 template <typename Getter, typename Setter>
1545 static PropertyDescriptor Accessor(const char* utf8name,
1546 Getter getter,
1547 Setter setter,
1548 napi_property_attributes attributes = napi_default,
1549 void* data = nullptr);
1550 template <typename Getter, typename Setter>
1551 static PropertyDescriptor Accessor(const std::string& utf8name,
1552 Getter getter,
1553 Setter setter,
1554 napi_property_attributes attributes = napi_default,
1555 void* data = nullptr);
1556 template <typename Getter, typename Setter>
1557 static PropertyDescriptor Accessor(napi_value name,
1558 Getter getter,
1559 Setter setter,
1560 napi_property_attributes attributes = napi_default,
1561 void* data = nullptr);
1562 template <typename Getter, typename Setter>
1563 static PropertyDescriptor Accessor(Name name,
1564 Getter getter,
1565 Setter setter,
1566 napi_property_attributes attributes = napi_default,
1567 void* data = nullptr);
1568 template <typename Callable>
1569 static PropertyDescriptor Function(const char* utf8name,
1570 Callable cb,
1571 napi_property_attributes attributes = napi_default,
1572 void* data = nullptr);
1573 template <typename Callable>
1574 static PropertyDescriptor Function(const std::string& utf8name,
1575 Callable cb,
1576 napi_property_attributes attributes = napi_default,
1577 void* data = nullptr);
1578 template <typename Callable>
1579 static PropertyDescriptor Function(napi_value name,
1580 Callable cb,
1581 napi_property_attributes attributes = napi_default,
1582 void* data = nullptr);
1583 template <typename Callable>
1584 static PropertyDescriptor Function(Name name,
1585 Callable cb,
1586 napi_property_attributes attributes = napi_default,
1587 void* data = nullptr);
1588#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
1589
1590 template <GetterCallback Getter>
1591 static PropertyDescriptor Accessor(const char* utf8name,
1592 napi_property_attributes attributes = napi_default,
1593 void* data = nullptr);
1594
1595 template <GetterCallback Getter>
1596 static PropertyDescriptor Accessor(const std::string& utf8name,
1597 napi_property_attributes attributes = napi_default,
1598 void* data = nullptr);
1599
1600 template <GetterCallback Getter>
1601 static PropertyDescriptor Accessor(Name name,
1602 napi_property_attributes attributes = napi_default,
1603 void* data = nullptr);
1604
1605 template <GetterCallback Getter, SetterCallback Setter>
1606 static PropertyDescriptor Accessor(const char* utf8name,
1607 napi_property_attributes attributes = napi_default,
1608 void* data = nullptr);
1609
1610 template <GetterCallback Getter, SetterCallback Setter>
1611 static PropertyDescriptor Accessor(const std::string& utf8name,
1612 napi_property_attributes attributes = napi_default,
1613 void* data = nullptr);
1614
1615 template <GetterCallback Getter, SetterCallback Setter>
1616 static PropertyDescriptor Accessor(Name name,
1617 napi_property_attributes attributes = napi_default,
1618 void* data = nullptr);
1619
1620 template <typename Getter>
1621 static PropertyDescriptor Accessor(Napi::Env env,
1622 Napi::Object object,
1623 const char* utf8name,
1624 Getter getter,
1625 napi_property_attributes attributes = napi_default,
1626 void* data = nullptr);
1627 template <typename Getter>
1628 static PropertyDescriptor Accessor(Napi::Env env,
1629 Napi::Object object,
1630 const std::string& utf8name,
1631 Getter getter,
1632 napi_property_attributes attributes = napi_default,
1633 void* data = nullptr);
1634 template <typename Getter>
1635 static PropertyDescriptor Accessor(Napi::Env env,
1636 Napi::Object object,
1637 Name name,
1638 Getter getter,
1639 napi_property_attributes attributes = napi_default,
1640 void* data = nullptr);
1641 template <typename Getter, typename Setter>
1642 static PropertyDescriptor Accessor(Napi::Env env,
1643 Napi::Object object,
1644 const char* utf8name,
1645 Getter getter,
1646 Setter setter,
1647 napi_property_attributes attributes = napi_default,
1648 void* data = nullptr);
1649 template <typename Getter, typename Setter>
1650 static PropertyDescriptor Accessor(Napi::Env env,
1651 Napi::Object object,
1652 const std::string& utf8name,
1653 Getter getter,
1654 Setter setter,
1655 napi_property_attributes attributes = napi_default,
1656 void* data = nullptr);
1657 template <typename Getter, typename Setter>
1658 static PropertyDescriptor Accessor(Napi::Env env,
1659 Napi::Object object,
1660 Name name,
1661 Getter getter,
1662 Setter setter,
1663 napi_property_attributes attributes = napi_default,
1664 void* data = nullptr);
1665 template <typename Callable>
1666 static PropertyDescriptor Function(Napi::Env env,
1667 Napi::Object object,
1668 const char* utf8name,
1669 Callable cb,
1670 napi_property_attributes attributes = napi_default,
1671 void* data = nullptr);
1672 template <typename Callable>
1673 static PropertyDescriptor Function(Napi::Env env,
1674 Napi::Object object,
1675 const std::string& utf8name,
1676 Callable cb,
1677 napi_property_attributes attributes = napi_default,
1678 void* data = nullptr);
1679 template <typename Callable>
1680 static PropertyDescriptor Function(Napi::Env env,
1681 Napi::Object object,
1682 Name name,
1683 Callable cb,
1684 napi_property_attributes attributes = napi_default,
1685 void* data = nullptr);
1686 static PropertyDescriptor Value(const char* utf8name,
1687 napi_value value,
1688 napi_property_attributes attributes = napi_default);
1689 static PropertyDescriptor Value(const std::string& utf8name,
1690 napi_value value,
1691 napi_property_attributes attributes = napi_default);
1692 static PropertyDescriptor Value(napi_value name,
1693 napi_value value,
1694 napi_property_attributes attributes = napi_default);
1695 static PropertyDescriptor Value(Name name,
1696 Napi::Value value,
1697 napi_property_attributes attributes = napi_default);
1698
1699 PropertyDescriptor(napi_property_descriptor desc);
1700
1701 operator napi_property_descriptor&();
1702 operator const napi_property_descriptor&() const;
1703
1704 private:
1705 napi_property_descriptor _desc;
1706 };
1707
1708 /// Property descriptor for use with `ObjectWrap::DefineClass()`.
1709 ///
1710 /// This is different from the standalone `PropertyDescriptor` because it is specific to each
1711 /// `ObjectWrap<T>` subclass. This prevents using descriptors from a different class when
1712 /// defining a new class (preventing the callbacks from having incorrect `this` pointers).
1713 template <typename T>
1714 class ClassPropertyDescriptor {
1715 public:
1716 ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
1717
1718 operator napi_property_descriptor&() { return _desc; }
1719 operator const napi_property_descriptor&() const { return _desc; }
1720
1721 private:
1722 napi_property_descriptor _desc;
1723 };
1724
1725 template <typename T, typename TCallback>
1726 struct MethodCallbackData {
1727 TCallback callback;
1728 void* data;
1729 };
1730
1731 template <typename T, typename TGetterCallback, typename TSetterCallback>
1732 struct AccessorCallbackData {
1733 TGetterCallback getterCallback;
1734 TSetterCallback setterCallback;
1735 void* data;
1736 };
1737
1738 template <typename T>
1739 class InstanceWrap {
1740 public:
1741 using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info);
1742 using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info);
1743 using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info);
1744 using InstanceSetterCallback = void (T::*)(const CallbackInfo& info,
1745 const Napi::Value& value);
1746
1747 using PropertyDescriptor = ClassPropertyDescriptor<T>;
1748
1749 static PropertyDescriptor InstanceMethod(const char* utf8name,
1750 InstanceVoidMethodCallback method,
1751 napi_property_attributes attributes = napi_default,
1752 void* data = nullptr);
1753 static PropertyDescriptor InstanceMethod(const char* utf8name,
1754 InstanceMethodCallback method,
1755 napi_property_attributes attributes = napi_default,
1756 void* data = nullptr);
1757 static PropertyDescriptor InstanceMethod(Symbol name,
1758 InstanceVoidMethodCallback method,
1759 napi_property_attributes attributes = napi_default,
1760 void* data = nullptr);
1761 static PropertyDescriptor InstanceMethod(Symbol name,
1762 InstanceMethodCallback method,
1763 napi_property_attributes attributes = napi_default,
1764 void* data = nullptr);
1765 template <InstanceVoidMethodCallback method>
1766 static PropertyDescriptor InstanceMethod(const char* utf8name,
1767 napi_property_attributes attributes = napi_default,
1768 void* data = nullptr);
1769 template <InstanceMethodCallback method>
1770 static PropertyDescriptor InstanceMethod(const char* utf8name,
1771 napi_property_attributes attributes = napi_default,
1772 void* data = nullptr);
1773 template <InstanceVoidMethodCallback method>
1774 static PropertyDescriptor InstanceMethod(Symbol name,
1775 napi_property_attributes attributes = napi_default,
1776 void* data = nullptr);
1777 template <InstanceMethodCallback method>
1778 static PropertyDescriptor InstanceMethod(Symbol name,
1779 napi_property_attributes attributes = napi_default,
1780 void* data = nullptr);
1781 static PropertyDescriptor InstanceAccessor(const char* utf8name,
1782 InstanceGetterCallback getter,
1783 InstanceSetterCallback setter,
1784 napi_property_attributes attributes = napi_default,
1785 void* data = nullptr);
1786 static PropertyDescriptor InstanceAccessor(Symbol name,
1787 InstanceGetterCallback getter,
1788 InstanceSetterCallback setter,
1789 napi_property_attributes attributes = napi_default,
1790 void* data = nullptr);
1791 template <InstanceGetterCallback getter, InstanceSetterCallback setter=nullptr>
1792 static PropertyDescriptor InstanceAccessor(const char* utf8name,
1793 napi_property_attributes attributes = napi_default,
1794 void* data = nullptr);
1795 template <InstanceGetterCallback getter, InstanceSetterCallback setter=nullptr>
1796 static PropertyDescriptor InstanceAccessor(Symbol name,
1797 napi_property_attributes attributes = napi_default,
1798 void* data = nullptr);
1799 static PropertyDescriptor InstanceValue(const char* utf8name,
1800 Napi::Value value,
1801 napi_property_attributes attributes = napi_default);
1802 static PropertyDescriptor InstanceValue(Symbol name,
1803 Napi::Value value,
1804 napi_property_attributes attributes = napi_default);
1805
1806 protected:
1807 static void AttachPropData(napi_env env, napi_value value, const napi_property_descriptor* prop);
1808
1809 private:
1810 using This = InstanceWrap<T>;
1811
1812 using InstanceVoidMethodCallbackData =
1813 MethodCallbackData<T, InstanceVoidMethodCallback>;
1814 using InstanceMethodCallbackData =
1815 MethodCallbackData<T, InstanceMethodCallback>;
1816 using InstanceAccessorCallbackData =
1817 AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>;
1818
1819 static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, napi_callback_info info);
1820 static napi_value InstanceMethodCallbackWrapper(napi_env env, napi_callback_info info);
1821 static napi_value InstanceGetterCallbackWrapper(napi_env env, napi_callback_info info);
1822 static napi_value InstanceSetterCallbackWrapper(napi_env env, napi_callback_info info);
1823
1824 template <InstanceSetterCallback method>
1825 static napi_value WrappedMethod(napi_env env,
1826 napi_callback_info info) NAPI_NOEXCEPT;
1827
1828 template <InstanceSetterCallback setter> struct SetterTag {};
1829
1830 template <InstanceSetterCallback setter>
1831 static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT {
1832 return &This::WrappedMethod<setter>;
1833 }
1834 static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT {
1835 return nullptr;
1836 }
1837 };
1838
1839 /// Base class to be extended by C++ classes exposed to JavaScript; each C++ class instance gets
1840 /// "wrapped" by a JavaScript object that is managed by this class.
1841 ///
1842 /// At initialization time, the `DefineClass()` method must be used to
1843 /// hook up the accessor and method callbacks. It takes a list of
1844 /// property descriptors, which can be constructed via the various
1845 /// static methods on the base class.
1846 ///
1847 /// #### Example:
1848 ///
1849 /// class Example: public Napi::ObjectWrap<Example> {
1850 /// public:
1851 /// static void Initialize(Napi::Env& env, Napi::Object& target) {
1852 /// Napi::Function constructor = DefineClass(env, "Example", {
1853 /// InstanceAccessor<&Example::GetSomething, &Example::SetSomething>("value"),
1854 /// InstanceMethod<&Example::DoSomething>("doSomething"),
1855 /// });
1856 /// target.Set("Example", constructor);
1857 /// }
1858 ///
1859 /// Example(const Napi::CallbackInfo& info); // Constructor
1860 /// Napi::Value GetSomething(const Napi::CallbackInfo& info);
1861 /// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& value);
1862 /// Napi::Value DoSomething(const Napi::CallbackInfo& info);
1863 /// }
1864 template <typename T>
1865 class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
1866 public:
1867 ObjectWrap(const CallbackInfo& callbackInfo);
1868 virtual ~ObjectWrap();
1869
1870 static T* Unwrap(Object wrapper);
1871
1872 // Methods exposed to JavaScript must conform to one of these callback signatures.
1873 using StaticVoidMethodCallback = void (*)(const CallbackInfo& info);
1874 using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info);
1875 using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info);
1876 using StaticSetterCallback = void (*)(const CallbackInfo& info,
1877 const Napi::Value& value);
1878
1879 using PropertyDescriptor = ClassPropertyDescriptor<T>;
1880
1881 static Function DefineClass(Napi::Env env,
1882 const char* utf8name,
1883 const std::initializer_list<PropertyDescriptor>& properties,
1884 void* data = nullptr);
1885 static Function DefineClass(Napi::Env env,
1886 const char* utf8name,
1887 const std::vector<PropertyDescriptor>& properties,
1888 void* data = nullptr);
1889 static PropertyDescriptor StaticMethod(const char* utf8name,
1890 StaticVoidMethodCallback method,
1891 napi_property_attributes attributes = napi_default,
1892 void* data = nullptr);
1893 static PropertyDescriptor StaticMethod(const char* utf8name,
1894 StaticMethodCallback method,
1895 napi_property_attributes attributes = napi_default,
1896 void* data = nullptr);
1897 static PropertyDescriptor StaticMethod(Symbol name,
1898 StaticVoidMethodCallback method,
1899 napi_property_attributes attributes = napi_default,
1900 void* data = nullptr);
1901 static PropertyDescriptor StaticMethod(Symbol name,
1902 StaticMethodCallback method,
1903 napi_property_attributes attributes = napi_default,
1904 void* data = nullptr);
1905 template <StaticVoidMethodCallback method>
1906 static PropertyDescriptor StaticMethod(const char* utf8name,
1907 napi_property_attributes attributes = napi_default,
1908 void* data = nullptr);
1909 template <StaticVoidMethodCallback method>
1910 static PropertyDescriptor StaticMethod(Symbol name,
1911 napi_property_attributes attributes = napi_default,
1912 void* data = nullptr);
1913 template <StaticMethodCallback method>
1914 static PropertyDescriptor StaticMethod(const char* utf8name,
1915 napi_property_attributes attributes = napi_default,
1916 void* data = nullptr);
1917 template <StaticMethodCallback method>
1918 static PropertyDescriptor StaticMethod(Symbol name,
1919 napi_property_attributes attributes = napi_default,
1920 void* data = nullptr);
1921 static PropertyDescriptor StaticAccessor(const char* utf8name,
1922 StaticGetterCallback getter,
1923 StaticSetterCallback setter,
1924 napi_property_attributes attributes = napi_default,
1925 void* data = nullptr);
1926 static PropertyDescriptor StaticAccessor(Symbol name,
1927 StaticGetterCallback getter,
1928 StaticSetterCallback setter,
1929 napi_property_attributes attributes = napi_default,
1930 void* data = nullptr);
1931 template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr>
1932 static PropertyDescriptor StaticAccessor(const char* utf8name,
1933 napi_property_attributes attributes = napi_default,
1934 void* data = nullptr);
1935 template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr>
1936 static PropertyDescriptor StaticAccessor(Symbol name,
1937 napi_property_attributes attributes = napi_default,
1938 void* data = nullptr);
1939 static PropertyDescriptor StaticValue(const char* utf8name,
1940 Napi::Value value,
1941 napi_property_attributes attributes = napi_default);
1942 static PropertyDescriptor StaticValue(Symbol name,
1943 Napi::Value value,
1944 napi_property_attributes attributes = napi_default);
1945 virtual void Finalize(Napi::Env env);
1946
1947 private:
1948 using This = ObjectWrap<T>;
1949
1950 static napi_value ConstructorCallbackWrapper(napi_env env, napi_callback_info info);
1951 static napi_value StaticVoidMethodCallbackWrapper(napi_env env, napi_callback_info info);
1952 static napi_value StaticMethodCallbackWrapper(napi_env env, napi_callback_info info);
1953 static napi_value StaticGetterCallbackWrapper(napi_env env, napi_callback_info info);
1954 static napi_value StaticSetterCallbackWrapper(napi_env env, napi_callback_info info);
1955 static void FinalizeCallback(napi_env env, void* data, void* hint);
1956 static Function DefineClass(Napi::Env env,
1957 const char* utf8name,
1958 const size_t props_count,
1959 const napi_property_descriptor* props,
1960 void* data = nullptr);
1961
1962 using StaticVoidMethodCallbackData =
1963 MethodCallbackData<T, StaticVoidMethodCallback>;
1964 using StaticMethodCallbackData =
1965 MethodCallbackData<T, StaticMethodCallback>;
1966
1967 using StaticAccessorCallbackData =
1968 AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>;
1969
1970 template <StaticSetterCallback method>
1971 static napi_value WrappedMethod(napi_env env,
1972 napi_callback_info info) NAPI_NOEXCEPT;
1973
1974 template <StaticSetterCallback setter> struct StaticSetterTag {};
1975
1976 template <StaticSetterCallback setter>
1977 static napi_callback WrapStaticSetter(StaticSetterTag<setter>)
1978 NAPI_NOEXCEPT {
1979 return &This::WrappedMethod<setter>;
1980 }
1981 static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>)
1982 NAPI_NOEXCEPT {
1983 return nullptr;
1984 }
1985
1986 bool _construction_failed = true;
1987 };
1988
1989 class HandleScope {
1990 public:
1991 HandleScope(napi_env env, napi_handle_scope scope);
1992 explicit HandleScope(Napi::Env env);
1993 ~HandleScope();
1994
1995 // Disallow copying to prevent double close of napi_handle_scope
1996 NAPI_DISALLOW_ASSIGN_COPY(HandleScope)
1997
1998 operator napi_handle_scope() const;
1999
2000 Napi::Env Env() const;
2001
2002 private:
2003 napi_env _env;
2004 napi_handle_scope _scope;
2005 };
2006
2007 class EscapableHandleScope {
2008 public:
2009 EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope);
2010 explicit EscapableHandleScope(Napi::Env env);
2011 ~EscapableHandleScope();
2012
2013 // Disallow copying to prevent double close of napi_escapable_handle_scope
2014 NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope)
2015
2016 operator napi_escapable_handle_scope() const;
2017
2018 Napi::Env Env() const;
2019 Value Escape(napi_value escapee);
2020
2021 private:
2022 napi_env _env;
2023 napi_escapable_handle_scope _scope;
2024 };
2025
2026#if (NAPI_VERSION > 2)
2027 class CallbackScope {
2028 public:
2029 CallbackScope(napi_env env, napi_callback_scope scope);
2030 CallbackScope(napi_env env, napi_async_context context);
2031 virtual ~CallbackScope();
2032
2033 // Disallow copying to prevent double close of napi_callback_scope
2034 NAPI_DISALLOW_ASSIGN_COPY(CallbackScope)
2035
2036 operator napi_callback_scope() const;
2037
2038 Napi::Env Env() const;
2039
2040 private:
2041 napi_env _env;
2042 napi_callback_scope _scope;
2043 };
2044#endif
2045
2046 class AsyncContext {
2047 public:
2048 explicit AsyncContext(napi_env env, const char* resource_name);
2049 explicit AsyncContext(napi_env env, const char* resource_name, const Object& resource);
2050 virtual ~AsyncContext();
2051
2052 AsyncContext(AsyncContext&& other);
2053 AsyncContext& operator =(AsyncContext&& other);
2054 NAPI_DISALLOW_ASSIGN_COPY(AsyncContext)
2055
2056 operator napi_async_context() const;
2057
2058 Napi::Env Env() const;
2059
2060 private:
2061 napi_env _env;
2062 napi_async_context _context;
2063 };
2064
2065 class AsyncWorker {
2066 public:
2067 virtual ~AsyncWorker();
2068
2069 // An async worker can be moved but cannot be copied.
2070 AsyncWorker(AsyncWorker&& other);
2071 AsyncWorker& operator =(AsyncWorker&& other);
2072 NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker)
2073
2074 operator napi_async_work() const;
2075
2076 Napi::Env Env() const;
2077
2078 void Queue();
2079 void Cancel();
2080 void SuppressDestruct();
2081
2082 ObjectReference& Receiver();
2083 FunctionReference& Callback();
2084
2085 virtual void OnExecute(Napi::Env env);
2086 virtual void OnWorkComplete(Napi::Env env,
2087 napi_status status);
2088
2089 protected:
2090 explicit AsyncWorker(const Function& callback);
2091 explicit AsyncWorker(const Function& callback,
2092 const char* resource_name);
2093 explicit AsyncWorker(const Function& callback,
2094 const char* resource_name,
2095 const Object& resource);
2096 explicit AsyncWorker(const Object& receiver,
2097 const Function& callback);
2098 explicit AsyncWorker(const Object& receiver,
2099 const Function& callback,
2100 const char* resource_name);
2101 explicit AsyncWorker(const Object& receiver,
2102 const Function& callback,
2103 const char* resource_name,
2104 const Object& resource);
2105
2106 explicit AsyncWorker(Napi::Env env);
2107 explicit AsyncWorker(Napi::Env env,
2108 const char* resource_name);
2109 explicit AsyncWorker(Napi::Env env,
2110 const char* resource_name,
2111 const Object& resource);
2112
2113 virtual void Execute() = 0;
2114 virtual void OnOK();
2115 virtual void OnError(const Error& e);
2116 virtual void Destroy();
2117 virtual std::vector<napi_value> GetResult(Napi::Env env);
2118
2119 void SetError(const std::string& error);
2120
2121 private:
2122 static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker);
2123 static inline void OnAsyncWorkComplete(napi_env env,
2124 napi_status status,
2125 void* asyncworker);
2126
2127 napi_env _env;
2128 napi_async_work _work;
2129 ObjectReference _receiver;
2130 FunctionReference _callback;
2131 std::string _error;
2132 bool _suppress_destruct;
2133 };
2134
2135 #if (NAPI_VERSION > 3 && !defined(__wasm32__))
2136 class ThreadSafeFunction {
2137 public:
2138 // This API may only be called from the main thread.
2139 template <typename ResourceString>
2140 static ThreadSafeFunction New(napi_env env,
2141 const Function& callback,
2142 ResourceString resourceName,
2143 size_t maxQueueSize,
2144 size_t initialThreadCount);
2145
2146 // This API may only be called from the main thread.
2147 template <typename ResourceString, typename ContextType>
2148 static ThreadSafeFunction New(napi_env env,
2149 const Function& callback,
2150 ResourceString resourceName,
2151 size_t maxQueueSize,
2152 size_t initialThreadCount,
2153 ContextType* context);
2154
2155 // This API may only be called from the main thread.
2156 template <typename ResourceString, typename Finalizer>
2157 static ThreadSafeFunction New(napi_env env,
2158 const Function& callback,
2159 ResourceString resourceName,
2160 size_t maxQueueSize,
2161 size_t initialThreadCount,
2162 Finalizer finalizeCallback);
2163
2164 // This API may only be called from the main thread.
2165 template <typename ResourceString, typename Finalizer,
2166 typename FinalizerDataType>
2167 static ThreadSafeFunction New(napi_env env,
2168 const Function& callback,
2169 ResourceString resourceName,
2170 size_t maxQueueSize,
2171 size_t initialThreadCount,
2172 Finalizer finalizeCallback,
2173 FinalizerDataType* data);
2174
2175 // This API may only be called from the main thread.
2176 template <typename ResourceString, typename ContextType, typename Finalizer>
2177 static ThreadSafeFunction New(napi_env env,
2178 const Function& callback,
2179 ResourceString resourceName,
2180 size_t maxQueueSize,
2181 size_t initialThreadCount,
2182 ContextType* context,
2183 Finalizer finalizeCallback);
2184
2185 // This API may only be called from the main thread.
2186 template <typename ResourceString, typename ContextType,
2187 typename Finalizer, typename FinalizerDataType>
2188 static ThreadSafeFunction New(napi_env env,
2189 const Function& callback,
2190 ResourceString resourceName,
2191 size_t maxQueueSize,
2192 size_t initialThreadCount,
2193 ContextType* context,
2194 Finalizer finalizeCallback,
2195 FinalizerDataType* data);
2196
2197 // This API may only be called from the main thread.
2198 template <typename ResourceString>
2199 static ThreadSafeFunction New(napi_env env,
2200 const Function& callback,
2201 const Object& resource,
2202 ResourceString resourceName,
2203 size_t maxQueueSize,
2204 size_t initialThreadCount);
2205
2206 // This API may only be called from the main thread.
2207 template <typename ResourceString, typename ContextType>
2208 static ThreadSafeFunction New(napi_env env,
2209 const Function& callback,
2210 const Object& resource,
2211 ResourceString resourceName,
2212 size_t maxQueueSize,
2213 size_t initialThreadCount,
2214 ContextType* context);
2215
2216 // This API may only be called from the main thread.
2217 template <typename ResourceString, typename Finalizer>
2218 static ThreadSafeFunction New(napi_env env,
2219 const Function& callback,
2220 const Object& resource,
2221 ResourceString resourceName,
2222 size_t maxQueueSize,
2223 size_t initialThreadCount,
2224 Finalizer finalizeCallback);
2225
2226 // This API may only be called from the main thread.
2227 template <typename ResourceString, typename Finalizer,
2228 typename FinalizerDataType>
2229 static ThreadSafeFunction New(napi_env env,
2230 const Function& callback,
2231 const Object& resource,
2232 ResourceString resourceName,
2233 size_t maxQueueSize,
2234 size_t initialThreadCount,
2235 Finalizer finalizeCallback,
2236 FinalizerDataType* data);
2237
2238 // This API may only be called from the main thread.
2239 template <typename ResourceString, typename ContextType, typename Finalizer>
2240 static ThreadSafeFunction New(napi_env env,
2241 const Function& callback,
2242 const Object& resource,
2243 ResourceString resourceName,
2244 size_t maxQueueSize,
2245 size_t initialThreadCount,
2246 ContextType* context,
2247 Finalizer finalizeCallback);
2248
2249 // This API may only be called from the main thread.
2250 template <typename ResourceString, typename ContextType,
2251 typename Finalizer, typename FinalizerDataType>
2252 static ThreadSafeFunction New(napi_env env,
2253 const Function& callback,
2254 const Object& resource,
2255 ResourceString resourceName,
2256 size_t maxQueueSize,
2257 size_t initialThreadCount,
2258 ContextType* context,
2259 Finalizer finalizeCallback,
2260 FinalizerDataType* data);
2261
2262 ThreadSafeFunction();
2263 ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2264
2265 operator napi_threadsafe_function() const;
2266
2267 // This API may be called from any thread.
2268 napi_status BlockingCall() const;
2269
2270 // This API may be called from any thread.
2271 template <typename Callback>
2272 napi_status BlockingCall(Callback callback) const;
2273
2274 // This API may be called from any thread.
2275 template <typename DataType, typename Callback>
2276 napi_status BlockingCall(DataType* data, Callback callback) const;
2277
2278 // This API may be called from any thread.
2279 napi_status NonBlockingCall() const;
2280
2281 // This API may be called from any thread.
2282 template <typename Callback>
2283 napi_status NonBlockingCall(Callback callback) const;
2284
2285 // This API may be called from any thread.
2286 template <typename DataType, typename Callback>
2287 napi_status NonBlockingCall(DataType* data, Callback callback) const;
2288
2289 // This API may only be called from the main thread.
2290 void Ref(napi_env env) const;
2291
2292 // This API may only be called from the main thread.
2293 void Unref(napi_env env) const;
2294
2295 // This API may be called from any thread.
2296 napi_status Acquire() const;
2297
2298 // This API may be called from any thread.
2299 napi_status Release();
2300
2301 // This API may be called from any thread.
2302 napi_status Abort();
2303
2304 struct ConvertibleContext
2305 {
2306 template <class T>
2307 operator T*() { return static_cast<T*>(context); }
2308 void* context;
2309 };
2310
2311 // This API may be called from any thread.
2312 ConvertibleContext GetContext() const;
2313
2314 private:
2315 using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>;
2316
2317 template <typename ResourceString, typename ContextType,
2318 typename Finalizer, typename FinalizerDataType>
2319 static ThreadSafeFunction New(napi_env env,
2320 const Function& callback,
2321 const Object& resource,
2322 ResourceString resourceName,
2323 size_t maxQueueSize,
2324 size_t initialThreadCount,
2325 ContextType* context,
2326 Finalizer finalizeCallback,
2327 FinalizerDataType* data,
2328 napi_finalize wrapper);
2329
2330 napi_status CallInternal(CallbackWrapper* callbackWrapper,
2331 napi_threadsafe_function_call_mode mode) const;
2332
2333 static void CallJS(napi_env env,
2334 napi_value jsCallback,
2335 void* context,
2336 void* data);
2337
2338 napi_threadsafe_function _tsfn;
2339 };
2340
2341 // A TypedThreadSafeFunction by default has no context (nullptr) and can
2342 // accept any type (void) to its CallJs.
2343 template <typename ContextType = std::nullptr_t,
2344 typename DataType = void,
2345 void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) =
2346 nullptr>
2347 class TypedThreadSafeFunction {
2348 public:
2349 // This API may only be called from the main thread.
2350 // Helper function that returns nullptr if running Node-API 5+, otherwise a
2351 // non-empty, no-op Function. This provides the ability to specify at
2352 // compile-time a callback parameter to `New` that safely does no action
2353 // when targeting _any_ Node-API version.
2354#if NAPI_VERSION > 4
2355 static std::nullptr_t EmptyFunctionFactory(Napi::Env env);
2356#else
2357 static Napi::Function EmptyFunctionFactory(Napi::Env env);
2358#endif
2359 static Napi::Function FunctionOrEmpty(Napi::Env env,
2360 Napi::Function& callback);
2361
2362#if NAPI_VERSION > 4
2363 // This API may only be called from the main thread.
2364 // Creates a new threadsafe function with:
2365 // Callback [missing] Resource [missing] Finalizer [missing]
2366 template <typename ResourceString>
2367 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2368 napi_env env,
2369 ResourceString resourceName,
2370 size_t maxQueueSize,
2371 size_t initialThreadCount,
2372 ContextType* context = nullptr);
2373
2374 // This API may only be called from the main thread.
2375 // Creates a new threadsafe function with:
2376 // Callback [missing] Resource [passed] Finalizer [missing]
2377 template <typename ResourceString>
2378 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2379 napi_env env,
2380 const Object& resource,
2381 ResourceString resourceName,
2382 size_t maxQueueSize,
2383 size_t initialThreadCount,
2384 ContextType* context = nullptr);
2385
2386 // This API may only be called from the main thread.
2387 // Creates a new threadsafe function with:
2388 // Callback [missing] Resource [missing] Finalizer [passed]
2389 template <typename ResourceString,
2390 typename Finalizer,
2391 typename FinalizerDataType = void>
2392 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2393 napi_env env,
2394 ResourceString resourceName,
2395 size_t maxQueueSize,
2396 size_t initialThreadCount,
2397 ContextType* context,
2398 Finalizer finalizeCallback,
2399 FinalizerDataType* data = nullptr);
2400
2401 // This API may only be called from the main thread.
2402 // Creates a new threadsafe function with:
2403 // Callback [missing] Resource [passed] Finalizer [passed]
2404 template <typename ResourceString,
2405 typename Finalizer,
2406 typename FinalizerDataType = void>
2407 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2408 napi_env env,
2409 const Object& resource,
2410 ResourceString resourceName,
2411 size_t maxQueueSize,
2412 size_t initialThreadCount,
2413 ContextType* context,
2414 Finalizer finalizeCallback,
2415 FinalizerDataType* data = nullptr);
2416#endif
2417
2418 // This API may only be called from the main thread.
2419 // Creates a new threadsafe function with:
2420 // Callback [passed] Resource [missing] Finalizer [missing]
2421 template <typename ResourceString>
2422 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2423 napi_env env,
2424 const Function& callback,
2425 ResourceString resourceName,
2426 size_t maxQueueSize,
2427 size_t initialThreadCount,
2428 ContextType* context = nullptr);
2429
2430 // This API may only be called from the main thread.
2431 // Creates a new threadsafe function with:
2432 // Callback [passed] Resource [passed] Finalizer [missing]
2433 template <typename ResourceString>
2434 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2435 napi_env env,
2436 const Function& callback,
2437 const Object& resource,
2438 ResourceString resourceName,
2439 size_t maxQueueSize,
2440 size_t initialThreadCount,
2441 ContextType* context = nullptr);
2442
2443 // This API may only be called from the main thread.
2444 // Creates a new threadsafe function with:
2445 // Callback [passed] Resource [missing] Finalizer [passed]
2446 template <typename ResourceString,
2447 typename Finalizer,
2448 typename FinalizerDataType = void>
2449 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2450 napi_env env,
2451 const Function& callback,
2452 ResourceString resourceName,
2453 size_t maxQueueSize,
2454 size_t initialThreadCount,
2455 ContextType* context,
2456 Finalizer finalizeCallback,
2457 FinalizerDataType* data = nullptr);
2458
2459 // This API may only be called from the main thread.
2460 // Creates a new threadsafe function with:
2461 // Callback [passed] Resource [passed] Finalizer [passed]
2462 template <typename CallbackType,
2463 typename ResourceString,
2464 typename Finalizer,
2465 typename FinalizerDataType>
2466 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2467 napi_env env,
2468 CallbackType callback,
2469 const Object& resource,
2470 ResourceString resourceName,
2471 size_t maxQueueSize,
2472 size_t initialThreadCount,
2473 ContextType* context,
2474 Finalizer finalizeCallback,
2475 FinalizerDataType* data = nullptr);
2476
2477 TypedThreadSafeFunction<ContextType, DataType, CallJs>();
2478 TypedThreadSafeFunction<ContextType, DataType, CallJs>(
2479 napi_threadsafe_function tsFunctionValue);
2480
2481 operator napi_threadsafe_function() const;
2482
2483 // This API may be called from any thread.
2484 napi_status BlockingCall(DataType* data = nullptr) const;
2485
2486 // This API may be called from any thread.
2487 napi_status NonBlockingCall(DataType* data = nullptr) const;
2488
2489 // This API may only be called from the main thread.
2490 void Ref(napi_env env) const;
2491
2492 // This API may only be called from the main thread.
2493 void Unref(napi_env env) const;
2494
2495 // This API may be called from any thread.
2496 napi_status Acquire() const;
2497
2498 // This API may be called from any thread.
2499 napi_status Release();
2500
2501 // This API may be called from any thread.
2502 napi_status Abort();
2503
2504 // This API may be called from any thread.
2505 ContextType* GetContext() const;
2506
2507 private:
2508 template <typename ResourceString,
2509 typename Finalizer,
2510 typename FinalizerDataType>
2511 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2512 napi_env env,
2513 const Function& callback,
2514 const Object& resource,
2515 ResourceString resourceName,
2516 size_t maxQueueSize,
2517 size_t initialThreadCount,
2518 ContextType* context,
2519 Finalizer finalizeCallback,
2520 FinalizerDataType* data,
2521 napi_finalize wrapper);
2522
2523 static void CallJsInternal(napi_env env,
2524 napi_value jsCallback,
2525 void* context,
2526 void* data);
2527
2528 protected:
2529 napi_threadsafe_function _tsfn;
2530 };
2531 template <typename DataType>
2532 class AsyncProgressWorkerBase : public AsyncWorker {
2533 public:
2534 virtual void OnWorkProgress(DataType* data) = 0;
2535 class ThreadSafeData {
2536 public:
2537 ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data)
2538 : _asyncprogressworker(asyncprogressworker), _data(data) {}
2539
2540 AsyncProgressWorkerBase* asyncprogressworker() { return _asyncprogressworker; };
2541 DataType* data() { return _data; };
2542
2543 private:
2544 AsyncProgressWorkerBase* _asyncprogressworker;
2545 DataType* _data;
2546 };
2547 void OnWorkComplete(Napi::Env env, napi_status status) override;
2548 protected:
2549 explicit AsyncProgressWorkerBase(const Object& receiver,
2550 const Function& callback,
2551 const char* resource_name,
2552 const Object& resource,
2553 size_t queue_size = 1);
2554 virtual ~AsyncProgressWorkerBase();
2555
2556// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4.
2557// Refs: https://github.com/nodejs/node/pull/27791
2558#if NAPI_VERSION > 4
2559 explicit AsyncProgressWorkerBase(Napi::Env env,
2560 const char* resource_name,
2561 const Object& resource,
2562 size_t queue_size = 1);
2563#endif
2564
2565 static inline void OnAsyncWorkProgress(Napi::Env env,
2566 Napi::Function jsCallback,
2567 void* data);
2568
2569 napi_status NonBlockingCall(DataType* data);
2570
2571 private:
2572 ThreadSafeFunction _tsfn;
2573 bool _work_completed = false;
2574 napi_status _complete_status;
2575 static inline void OnThreadSafeFunctionFinalize(Napi::Env env, void* data, AsyncProgressWorkerBase* context);
2576 };
2577
2578 template<class T>
2579 class AsyncProgressWorker : public AsyncProgressWorkerBase<void> {
2580 public:
2581 virtual ~AsyncProgressWorker();
2582
2583 class ExecutionProgress {
2584 friend class AsyncProgressWorker;
2585 public:
2586 void Signal() const;
2587 void Send(const T* data, size_t count) const;
2588 private:
2589 explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {}
2590 AsyncProgressWorker* const _worker;
2591 };
2592
2593 void OnWorkProgress(void*) override;
2594
2595 protected:
2596 explicit AsyncProgressWorker(const Function& callback);
2597 explicit AsyncProgressWorker(const Function& callback,
2598 const char* resource_name);
2599 explicit AsyncProgressWorker(const Function& callback,
2600 const char* resource_name,
2601 const Object& resource);
2602 explicit AsyncProgressWorker(const Object& receiver,
2603 const Function& callback);
2604 explicit AsyncProgressWorker(const Object& receiver,
2605 const Function& callback,
2606 const char* resource_name);
2607 explicit AsyncProgressWorker(const Object& receiver,
2608 const Function& callback,
2609 const char* resource_name,
2610 const Object& resource);
2611
2612// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4.
2613// Refs: https://github.com/nodejs/node/pull/27791
2614#if NAPI_VERSION > 4
2615 explicit AsyncProgressWorker(Napi::Env env);
2616 explicit AsyncProgressWorker(Napi::Env env,
2617 const char* resource_name);
2618 explicit AsyncProgressWorker(Napi::Env env,
2619 const char* resource_name,
2620 const Object& resource);
2621#endif
2622 virtual void Execute(const ExecutionProgress& progress) = 0;
2623 virtual void OnProgress(const T* data, size_t count) = 0;
2624
2625 private:
2626 void Execute() override;
2627 void Signal() const;
2628 void SendProgress_(const T* data, size_t count);
2629
2630 std::mutex _mutex;
2631 T* _asyncdata;
2632 size_t _asyncsize;
2633 };
2634
2635 template<class T>
2636 class AsyncProgressQueueWorker : public AsyncProgressWorkerBase<std::pair<T*, size_t>> {
2637 public:
2638 virtual ~AsyncProgressQueueWorker() {};
2639
2640 class ExecutionProgress {
2641 friend class AsyncProgressQueueWorker;
2642 public:
2643 void Signal() const;
2644 void Send(const T* data, size_t count) const;
2645 private:
2646 explicit ExecutionProgress(AsyncProgressQueueWorker* worker) : _worker(worker) {}
2647 AsyncProgressQueueWorker* const _worker;
2648 };
2649
2650 void OnWorkComplete(Napi::Env env, napi_status status) override;
2651 void OnWorkProgress(std::pair<T*, size_t>*) override;
2652
2653 protected:
2654 explicit AsyncProgressQueueWorker(const Function& callback);
2655 explicit AsyncProgressQueueWorker(const Function& callback,
2656 const char* resource_name);
2657 explicit AsyncProgressQueueWorker(const Function& callback,
2658 const char* resource_name,
2659 const Object& resource);
2660 explicit AsyncProgressQueueWorker(const Object& receiver,
2661 const Function& callback);
2662 explicit AsyncProgressQueueWorker(const Object& receiver,
2663 const Function& callback,
2664 const char* resource_name);
2665 explicit AsyncProgressQueueWorker(const Object& receiver,
2666 const Function& callback,
2667 const char* resource_name,
2668 const Object& resource);
2669
2670// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4.
2671// Refs: https://github.com/nodejs/node/pull/27791
2672#if NAPI_VERSION > 4
2673 explicit AsyncProgressQueueWorker(Napi::Env env);
2674 explicit AsyncProgressQueueWorker(Napi::Env env,
2675 const char* resource_name);
2676 explicit AsyncProgressQueueWorker(Napi::Env env,
2677 const char* resource_name,
2678 const Object& resource);
2679#endif
2680 virtual void Execute(const ExecutionProgress& progress) = 0;
2681 virtual void OnProgress(const T* data, size_t count) = 0;
2682
2683 private:
2684 void Execute() override;
2685 void Signal() const;
2686 void SendProgress_(const T* data, size_t count);
2687 };
2688 #endif // NAPI_VERSION > 3 && !defined(__wasm32__)
2689
2690 // Memory management.
2691 class MemoryManagement {
2692 public:
2693 static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
2694 };
2695
2696 // Version management
2697 class VersionManagement {
2698 public:
2699 static uint32_t GetNapiVersion(Env env);
2700 static const napi_node_version* GetNodeVersion(Env env);
2701 };
2702
2703#if NAPI_VERSION > 5
2704 template <typename T>
2705 class Addon : public InstanceWrap<T> {
2706 public:
2707 static inline Object Init(Env env, Object exports);
2708 static T* Unwrap(Object wrapper);
2709
2710 protected:
2711 using AddonProp = ClassPropertyDescriptor<T>;
2712 void DefineAddon(Object exports,
2713 const std::initializer_list<AddonProp>& props);
2714 Napi::Object DefineProperties(Object object,
2715 const std::initializer_list<AddonProp>& props);
2716
2717 private:
2718 Object entry_point_;
2719 };
2720#endif // NAPI_VERSION > 5
2721
2722} // namespace Napi
2723
2724// Inline implementations of all the above class methods are included here.
2725#include "napi-inl.h"
2726
2727#endif // SRC_NAPI_H_
Note: See TracBrowser for help on using the repository browser.