Giter Club home page Giter Club logo

node-addon-api's Introduction

node-addon-api module

codecov

NPM NPM

This module contains header-only C++ wrapper classes which simplify the use of the C based Node-API provided by Node.js when using C++. It provides a C++ object model and exception handling semantics with low overhead.

API References

API references are available in the doc directory.

Current version: 8.0.0

(See CHANGELOG.md for complete Changelog)

node-addon-api is based on Node-API and supports using different Node-API versions. This allows addons built with it to run with Node.js versions which support the targeted Node-API version. However the node-addon-api support model is to support only the active LTS Node.js versions. This means that every year there will be a new major which drops support for the Node.js LTS version which has gone out of service.

The oldest Node.js version supported by the current version of node-addon-api is Node.js 18.x.

Badges

The use of badges is recommended to indicate the minimum version of Node-API required for the module. This helps to determine which Node.js major versions are supported. Addon maintainers can consult the Node-API support matrix to determine which Node.js versions provide a given Node-API version. The following badges are available:

Node-API v1 Badge Node-API v2 Badge Node-API v3 Badge Node-API v4 Badge Node-API v5 Badge Node-API v6 Badge Node-API v7 Badge Node-API v8 Badge Node-API v9 Badge Node-API Experimental Version Badge

Contributing

We love contributions from the community to node-addon-api! See CONTRIBUTING.md for more details on our philosophy around extending this module.

Team members

Active

Name GitHub Link
Anna Henningsen addaleax
Chengzhong Wu legendecas
Jack Xia JckXia
Kevin Eady KevinEady
Michael Dawson mhdawson
Nicola Del Gobbo NickNaso
Vladimir Morozov vmoroz
Emeritus

Emeritus

Name GitHub Link
Arunesh Chandra aruneshchandra
Benjamin Byholm kkoopa
Gabriel Schulhof gabrielschulhof
Hitesh Kanwathirtha digitalinfinity
Jason Ginchereau jasongin
Jim Schlight jschlight
Sampson Gao sampsongao
Taylor Woll boingoing

License

Licensed under MIT

node-addon-api's People

Contributors

addaleax avatar daaitch avatar davedoesdev avatar dependabot[bot] avatar devsnek avatar digitalinfinity avatar gabrielschulhof avatar jasongin avatar jckxia avatar joseexposito avatar jschlight avatar kevineady avatar kfarnung avatar kidneysolo avatar legendecas avatar lovell avatar mhdawson avatar mildsunrise avatar nadongguri avatar nicknaso avatar raisinten avatar rivertam avatar rolftimmermans avatar romandev avatar rubiagatra avatar seishun avatar strager avatar tniessen avatar vmoroz avatar yjaeseok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-addon-api's Issues

Documentation mismatch for napi_property_attributes

Documentation on the N-API page describes napi_property_attributes as following:

typedef enum {
  napi_default = 0,
  napi_read_only = 1 << 0,
  napi_dont_enum = 1 << 1,
  napi_dont_delete = 1 << 2,
  napi_static_property = 1 << 10,
} napi_property_attributes;

whereas src/node_api_types.h describes it as:

typedef enum {
  napi_default = 0,
  napi_writable = 1 << 0,
  napi_enumerable = 1 << 1,
  napi_configurable = 1 << 2,

  // Used with napi_define_class to distinguish static properties
  // from instance properties. Ignored by napi_define_properties.
  napi_static = 1 << 10,
} napi_property_attributes;

Basically, values of all bit flags were inverted.

Given the last commit, it seems it's the documentation that is outdated here but would be nice to confirm and sync two places to agree with each other.

markdown docs

I think documentation in markdown is more user-friendly than the autogenerated one. Given that the API in this modules would likely be very stable, we should probably put the effort.

Converting Value into TypedArrayOf

Hi guys,

Is there any way to convert Value instance received from JS into an appropriate TypedArrayOf without converting it into a TypedArray first and switching on TypedArray::TypedArrayType()?

async_work executor signalling

using the c api, how would one signal to the async work executor that an invocation of a napi_async_execute_callback has failed? so that when the corresponding napi_async_complete_callback is invoked, it has a napi_status value that indicates a failure?

i am a total c(++) greenhorn, so i'm sorry if this question is inane or a waste of your (collective) time. please let me know if this is an inappropriate place to field this kind of question. i apologise if that is the case.

could the solution be to use (parts of) the c++ api, instead?

the addon i have been developing uses the void* data parameter to pass around a pointer to a struct that i could modify to include a value indicating success or failure to be checked when napi_async_complete_callback is invoked. however, if there is already a way to do this, i'd prefer to use that approach instead.

Move repo to node-addon-api

... or change README.md to show the package.json dependency as github:nodejs/node-api rather than github:nodejs/node-addon-api.

Following instructions, depending module do not compile on Node 6.11

CXX(target) Release/obj.target/node-api/node_modules/node-addon-api/src/node_api.o
In file included from ../node_modules/node-addon-api/src/node_api.cc:20:
In file included from ../node_modules/node-addon-api/src/node_internals.h:8:
../node_modules/node-addon-api/src/util-inl.h:9:8: error: use of undeclared identifier 'Napi'
inline Napi::String OneByteString(v8::Isolate* isolate,
       ^
../node_modules/node-addon-api/src/util-inl.h:12:10: error: no viable conversion from returned value of type 'MaybeLocal<v8::String>' to function return type 'int'
  return v8::String::NewFromOneByte(isolate,
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../node_modules/node-addon-api/src/util-inl.h:18:8: error: use of undeclared identifier 'Napi'
inline Napi::String OneByteString(v8::Isolate* isolate,
       ^
../node_modules/node-addon-api/src/util-inl.h:21:10: error: no viable conversion from returned value of type 'MaybeLocal<v8::String>' to function return type 'int'
  return v8::String::NewFromOneByte(isolate,
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(and others)

Launching npm test  from this module works, so maybe there is something to be updated in the README about the instructions on how to update binding.gyp.

Here is my binding.gyp:

{
  "targets": [
    {
      "target_name": "native-hdr-histogram",
      "cflags!": [ "-fno-exceptions" ],
      "cflags_cc!": [ "-fno-exceptions" ],
      "sources": [
        "src/hdr_encoding.h",
        "src/hdr_encoding.c",
        "src/hdr_histogram.h",
        "src/hdr_histogram.c",
        "src/hdr_histogram_log.h",
        "src/hdr_histogram_log.c",
        "hdr_histogram_wrap.cc",
        "histogram.cc"
      ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include\")",
        "src/"
      ],
      "dependencies": [
        "<(module_root_dir)/zlib/zlib.gyp:zlib",
        "<!(node -p \"require('node-addon-api').gyp\")"
      ],
      'xcode_settings': {
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
        'CLANG_CXX_LIBRARY': 'libc++',
        'MACOSX_DEPLOYMENT_TARGET': '10.7',
      },
      'msvs_settings': {
        'VCCLCompilerTool': { 'ExceptionHandling': 1 },
      }
    }
  ]
}

Napi runtime flag causing include path error for node-addon-api

After I export NODE_OPTIONS=--napi-modules and invoke npm install on module including node-addon-api module. npm always complain with this error message.

gyp: Call to 'node -p "require('node-addon-api').include"' returned exit status 0
while in binding.gyp. while trying to load binding.gyp

Failure building on node v6.9.4, windows 7, for --msvs_version= 2012, 2013, and 2015

2012: https://gist.github.com/mateodelnorte/67f124196377a0ca0815c66644bf1082
2013: https://gist.github.com/mateodelnorte/5475b1d28f902e501a29686cf7c91082
2015: https://gist.github.com/mateodelnorte/8c49520a883d7fb20ef8be784ac10a9a

I'm using the a basic, unmodified project created using the yoeman generator napi module plugin.

Here's my binding.gyp:

{
  'targets': [
    {
      'target_name': 'sophis-c-client-native',
      'sources': [ 'src/sophis_c_client.cc' ],
      'include_dirs': ["<!@(node -p \"require('node-addon-api').include\")"],
      'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"],
      'cflags!': [ '-fno-exceptions' ],
      'cflags_cc!': [ '-fno-exceptions' ],
      'xcode_settings': {
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
        'CLANG_CXX_LIBRARY': 'libc++',
        'MACOSX_DEPLOYMENT_TARGET': '10.7'
      },
      'msvs_settings': {
        'VCCLCompilerTool': { 'ExceptionHandling': 1 },
      }
    }
  ]
}

Building N-API module with cmake-js.

node-gyp is really hard to use.
Since cmake-js is based on CMake build system.
It's easy for me to integrate with other c++ libraries, such as gtest rapidjson.
And right now it's work.

I think it's a good start for using cmake-js instead.

Missing assert header

In the 28fad43, the cassert header is removed. However, modules using assert now have to include this header. Should we include assert in module code or should we add that header back to napi-inl.h?

Method to get all property names?

node sqlite3 uses the object.GetPropertyNames. We have the napi_get_property_names api, but we haven't include it in the C++ API.

A Napi::Error may become invalid if it is thrown out of a handle scope

When a Napi::Error is constructed, it acquires a handle to a JS error object via napi_get_and_clear_last_exception(). Then the Napi::Error instance is intended to be thrown and caught as a C++ exception. But if any stack frame between where it is thrown and where it is caught has set up a handle scope, then the error object handle gets released as the exception propagates up the stack.

One way to resolve this is whenever using handle scopes be sure to catch any Napi::Error and escape it from the scope before re-throwing it. But this makes it difficult to use handle scopes correctly and therefore would result in bugs that only occur in exception conditions. So, not a good solution.

Instead, the Error class can be changed to acquire a persistent reference to the error object, instead of just a handle. I'm working on this.

Symbol class

There should be a Napi::Symbol class, implemented with napi_create_symbol(). And probably also a Napi::Name class that is a common base class for Symbol and String, because there are several APIs that can accept either a string or symbol.

Getting the size of a string for napi_get_value_string_utf16

Hi guys,

napi_get_value_string_utf16 expects to a buffer of fixed size to fill with the string from JS engine. I'm wondering if there is a method to get the size of the string before creating that buffer. My current workaround does the job so far, but I'm sure if it portable or correct in general:

        // where args[0] is a JS string passed into the C++ function
	size_t bufSize = sizeof(args[0]) / 2;
	char16_t value0[bufSize];
	size_t copied0;
	status = napi_get_value_string_utf16(env, args[0], value0, bufSize, &copied0);
	assert(status == napi_ok);

Buffer finish callback with c type

Probably want to wrap napi_finalize as well to avoid mixing c api types with wrapper's.

static Buffer<T> New(napi_env env, T* data,
                     size_t length,
                     napi_finalize finalizeCallback = nullptr,
                     void* finalizeHint = nullptr);

Add JSON APIs

Add JSON APIs to provide a migration path from v8::JSON / Nan::JSON.

For now, it will have to be implemented by calling into JS. Eventually N-API could add more optimized versions if there is a need.

Reference: copy-initialization miss _suppressDestruct(false)

Reference member variable _suppressDestruct is only initialized in default constructor.
It should be initialized in other constructor.
See code

If _suppressDestruct is not initialized to false, the destructor may not call napi_delete_reference, then the gc is not work as expected.

Example usage for existing napi addon binaries

Would it be possible for you to please provide some documentation explaining how to use this compatibility code to load napi modules into older node.js versions? I'm on Ubuntu 14.04 x64. I'm having a bit of trouble using the code here to add support for napi module binaries to node.js 4.X.

For example, I have built the hello world example napi module from here: https://github.com/nodejs/abi-stable-node-addon-examples/tree/2f8495dd287c3e04bf92b971c0ebe918b8ea9311/1_hello_world/napi

I built the hello world napi module using node.js 8.1.3 as follows:

cd abi-stable-node-addon-examples/1_hello_world/napi/
node-gyp configure
node-gyp build

This then gives me the hello.node binary in build/Release/ . I then move the hello.node module binary to another directory.

To test the hello.node binary I use the following script (test.js)

a=require("./hello.node");
console.log(a.hello());

I then run test.js as follows:

(trusty)ljw@localhost:~/stuff/node/example$ node --napi-modules ./test.js
world
(node:24355) Warning: N-API is an experimental feature and could change at any time.

This works fine with node.js 8.1.3. I would like to be able to load that module into node.js 4.x using the compatibility layer from this repo.

I can see that your napi compatibility code lives in src/node_api.cc, but in that directory there does not appear to be a binding.gyp file. I created the following binding.gyp file based on your node_api.gyp file:

{
  'targets': [
    {
      'target_name': 'node-api',
      'sources': [
        'node_api.cc'
      ],
      'defines': [
         'EXTERNAL_NAPI'
      ]
    }
  ]
}

I then build the node-api module with node.js 4.x using:

node-gyp configure
node-gyp build

I then copied the build/Release/node-api.node module to the same directory as my hello.node module. Next I modified my test.js file as follows:

b=require("./node-api.node");
a=require("./hello.node");
console.log(a.hello());

But when I run test.js with node.js 4.8.3 I get the following backtrace:

(trusty)ljw@localhost:~/stuff/node/example$ node ./test.js
module.js:434
  return process.dlopen(module, path._makeLong(filename));
                 ^

Error: Module did not self-register.
    at Error (native)
    at Object.Module._extensions..node (module.js:434:18)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/home/ljw/stuff/node/example/test.js:1:65)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)

The node-api.node module does not seem to load.

Is there a correct way to do this? I see that your test code statically links to node-api.a, but that would not be possible with prebuilt napi module binaries (the modules would need to be rebuilt).

More special types check

node-sqlite3 uses val.IsDate(), val.IsRegExp(), val.IsInt32(). I think we need to think about how to support these.

_NOEXCEPT or noexcept

The keyword seems to be "noexcept" on linux.

../node_modules/napi/napi.h:452:24: error: expected ‘;’ at end of member declaration
const char* what() const _NOEXCEPT override;
^
../node_modules/napi/napi.h:452:30: error: ‘_NOEXCEPT’ does not name a type
const char* what() const _NOEXCEPT override;
^

.defines instead of isNodeApiBuiltin

Would it make more sense to have a require( "node-addon-api" ).defines instead of .isNodeApiBuiltin? Conditionally adding the EXTERNAL_NAPI preprocessor directive is my only use case for examining the value of .isNodeApiBuiltin, and on Windows the define is required, otherwise there will be unresolved symbols.

Not building on node 8.2.1

In file included from /Users/matteo/Repositories/native-hdr-histogram/node_modules/node-addon-api/napi.h:1447:
/Users/matteo/Repositories/native-hdr-histogram/node_modules/node-addon-api/napi-inl.h:1461:20: error: no matching function for call to 'napi_create_type_error'
          status = napi_create_type_error(env, nullptr, message, &error);
                   ^~~~~~~~~~~~~~~~~~~~~~

I think this is due to a semver-major change happening in core for the new error codes. In case such events happen again, this module should be released to NPM after the change lands in a release.

Conflict of class name and member function?

Seeing these errors on linux. Consider changing the member function name to be Env GetEnv()/Arraybuffer GetArrayBuffer, or changing return types to be Napi::Env Env() and Napi::ArrayBuffer ArrayBuffer().

../node_modules/napi/napi.h:90:15: error: declaration of ‘Napi::Env Napi::Value::Env() const’ [-fpermissive]
Env Env() const;
^
../node_modules/napi/napi.h:58:9: error: changes meaning of ‘Env’ from ‘class Napi::Env’ [-fpermissive]
class Env {
^
../node_modules/napi/napi.h:270:31: error: declaration of ‘Napi::ArrayBuffer Napi::TypedArray::ArrayBuffer() const’ [-fpermissive]
ArrayBuffer ArrayBuffer() const;
^
../node_modules/napi/napi.h:240:9: error: changes meaning of ‘ArrayBuffer’ from ‘class Napi::ArrayBuffer’ [-fpermissive]
class ArrayBuffer : public Object {
^

ObjectWrap construction flow

In node-sqlite3, they have code call Ref() on Database in the Database::New. Similar to node-canvas port, I change the Database::New to Database::Database. So the problem is in the ConstructorCallbackWrapper, Ref() is called before the ref is set in the ObjectReference.

  T* instance;
  napi_value wrapper;
  details::WrapCallback([&] {
    CallbackInfo callbackInfo(env, info);
    instance = new T(callbackInfo);
    wrapper = callbackInfo.This();   // ==> calling db->Ref() here
    return nullptr;
  });

  napi_ref ref;
  status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
  if (status != napi_ok) return nullptr;

  Reference<Object>* instanceRef = instance;
  *instanceRef = Reference<Object>(env, ref);

So I guess better way to go is to have Database::Database() for creating napi_ref and then call a Database::New (callbackInfo) to initialize?

  T* instance = new T();
  napi_value wrapper;
  details::WrapCallback([&] {
    CallbackInfo callbackInfo(env, info);
    wrapper = callbackInfo.This();
    return nullptr;
  });

  napi_ref ref;
  status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
  if (status != napi_ok) return nullptr;

  Reference<Object>* instanceRef = instance;
  *instanceRef = Reference<Object>(env, ref);

  details::WrapCallback([&] {
    CallbackInfo callbackInfo(env, info);
    instance->New(callbackInfo);
    return nullptr;
  });

Function::New ambiguity

error: call of overloaded ‘New(Napi::Env&, Napi::Value (&)(const Napi::CallbackInfo&))’ is ambiguous
     Napi::Function::New(env, S));
                               ^

Publish new version of NPM

I've landed the outstanding PRs include the one to fix breakage due to the errors change in node core. We should publish an update npm package

@kfarnung @jasongin we might want to get this one reviewed/landed as part of that:

#77

@sampsongao how do you usually test the conversion script ?

I'm done for today but if nobody beats me to it I'll look to see if I can publish on Monday.

Compile failure after pull request #52

After the commit 09c7b71
, I see this build error when porting node-sqlite3 on linux.

../src/database.cc:24:6:   required from here
/home/sampsongao/node_api/sqlite3/node_modules/node-addon-api/napi-inl.h:51:21: error: void value not ignored as it ought to be
     return callback();

Any clue what is the fix here?

Porting FunctionTemplate to N-API

How do I port FunctionTemplate to N-API?

v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);

This is the best I could do be

Napi::FunctionReference tpl = Napi::FunctionReference(env, New);

But it still did not work.

Prebuild story on Node 8 with flag

If we do a prebuilt module using node-addon-api and Node 8.2.1, could this run without the flag?

Or do we always need a flag on Node 8 (until it's disabled)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.