-
Notifications
You must be signed in to change notification settings - Fork 6
Enable multiple Node-API hosting JS engines / runtimes to share the global Node-API functions #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: kh/weak-node-api-refactored-generator-3
Are you sure you want to change the base?
Enable multiple Node-API hosting JS engines / runtimes to share the global Node-API functions #329
Conversation
6f9356d to
f79a30b
Compare
|
Wow, I really need this capability. And I like the "wrap" mechanisms; they're very elegant for this scenario.
From my perspective, using
I agree that releasing the corresponding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds multi-host support to weak-node-api, enabling multiple Node-API implementations to coexist in a single process. The implementation wraps opaque Node-API pointers (napi_env, napi_threadsafe_function, napi_async_cleanup_hook_handle) with metadata tracking which host owns them, allowing proper delegation of API calls to the correct implementation.
Key changes:
- Introduces
WeakNodeApiMultiHostclass with wrapper mechanism for opaque Node-API types - Generates multi-host header and source files alongside existing weak-node-api files
- Adds comprehensive test coverage for multi-host scenarios including host lifecycle and wrapped pointer handling
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
packages/weak-node-api/tests/test_multi_host.cpp |
Comprehensive test suite validating multi-host injection, call routing, host lifecycle, and wrapped opaque pointer handling |
packages/weak-node-api/tests/CMakeLists.txt |
Adds new multi-host test file to the build configuration |
packages/weak-node-api/scripts/generators/multi-host.ts |
Code generator for multi-host header and implementation, including wrapper creation and call delegation logic |
packages/weak-node-api/scripts/generate-weak-node-api.ts |
Updates generator to produce multi-host files with documentation headers |
packages/weak-node-api/CMakeLists.txt |
Includes generated multi-host source and header files in the build |
packages/weak-node-api/.gitignore |
Simplifies ignore pattern to cover all generated files |
f79a30b to
4d78b71
Compare
4d78b71 to
5ff0a5e
Compare
5ff0a5e to
daf6686
Compare
cf5e056 to
bd952a6
Compare
This is my suggestion for adding "multi-host" support to
weak-node-api, enabling multiple engines implementing Node-API to co-exist and share the Node-API function namespace. While not needed specifically for bringing Node-API to React Native adding this could makeweak-node-apimore applicable in other scenarios where multiple engines implementing Node-API share a single process.I'm proposing adding mechanisms to "wrap" the opaque pointers of specific Node-API implementors with references to the
NodeApiHostobject to enable deferring implementation of Node-API functions based on thenapi_env,node_api_basic_env,napi_threadsafe_functionornapi_async_cleanup_hook_handlepassed.classDiagram class NodeApiHost { <<interface>> } class NodeApiMultiHost { -vector~unique_ptr~WrappedEnv~~ envs +wrap(napi_env, weak_ptr~NodeApiHost~) napi_env +static napi_* methods... } class WrappedEnv { +napi_env value +weak_ptr~NodeApiHost~ host -vector~unique_ptr~WrappedThreadsafeFunction~~ threadsafe_functions -vector~unique_ptr~WrappedAsyncCleanupHookHandle~~ async_cleanup_hook_handles +wrap(napi_threadsafe_function, WrappedEnv*, weak_ptr~NodeApiHost~) napi_threadsafe_function +wrap(napi_async_cleanup_hook_handle, WrappedEnv*, weak_ptr~NodeApiHost~) napi_async_cleanup_hook_handle } class WrappedThreadsafeFunction { +napi_threadsafe_function value +WrappedEnv* env +weak_ptr~NodeApiHost~ host } class WrappedAsyncCleanupHookHandle { +napi_async_cleanup_hook_handle value +WrappedEnv* env +weak_ptr~NodeApiHost~ host } NodeApiMultiHost --|> NodeApiHost : inherits NodeApiMultiHost *-- "0..*" WrappedEnv : owns WrappedEnv *-- "0..*" WrappedThreadsafeFunction : owns WrappedEnv *-- "0..*" WrappedAsyncCleanupHookHandle : owns WrappedThreadsafeFunction --> WrappedEnv : references WrappedAsyncCleanupHookHandle --> WrappedEnv : references WrappedEnv --> NodeApiHost : weak reference WrappedThreadsafeFunction --> NodeApiHost : weak reference WrappedAsyncCleanupHookHandle --> NodeApiHost : weak reference WrappedEnv ..|> enable_shared_from_this : implements note for NodeApiMultiHost "Manages multiple Node-API host implementations" note for WrappedEnv "Wraps napi_env with ownership tracking for threadsafe functions and async cleanup hook handles"WrappedEnv,WrappedThreadsafeFunctionandWrappedAsyncCleanupHookHandleobjects can then be passed around like their respective opaque pointers and are "unwrapped" in the internal implementation of the "multi host" implementation of Node-API functions.Wrappedobjects are created calling one of thewrapinstance methods onNodeApiMultiHostorWrappedEnv, which are called internally innapi_create_threadsafe_functionandnapi_add_async_cleanup_hooktoo.Usage
NodeApiMultiHost(providing functions to register modules and handling a fatal error)NodeApiMultiHost(callingmulti_host.wrap(original_env, host);)react-native-node-api/packages/weak-node-api/tests/test_multi_host.cpp
Lines 18 to 52 in f79a30b
TODO
WrappedEnv(besides deleting the entireNodeApiMultiHost)WrappedThreadsafeFunction(in somenapi_*_threadsafe_functionfunction?) andWrappedAsyncCleanupHookHandle(innapi_remove_async_cleanup_hook).Open questions
std::functioninstead of raw function pointers for all (or some) of theWeakNodeApiHostmembers? This would allow capturing lambdas, making it much easier to provide a meaningful implementation of for examplenapi_module_register.Generated code
Below are samples from the generated code:
napi_create_objectimplementationnapi_create_threadsafe_functionandnapi_add_async_cleanup_hookimplementationsNotice the calls to
wrap, wrapping their opaque "out" pointers.