@ 260528.1

231103.1 · 7f4a9ed91bbecb84e39f4bc8030247ce5116ddf8

Reorganize examples into categorized folders (#341)

* refactor: create directory structure to organize exmaples
* test: update test_all to work with new directory structure
* fix: bug in test_all if no package.json scripts
* test: cleanup output of test_all
* fix: remove default test script that throws from thread_safe_function_with_object_wrap
* fix: remove build_with_cmake from .gitignore
* fix: swith to ' from " and remove subdir from getAllTests call
* test: add extra test cases for npm start and just running the pkgJson.main with node
* refactor: move all examples to src directory
* refactor: add numbers to categories so they are ordered in the src folder
* refactor: simplify getAllExamples in test_all.js
* docs: add directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure example in readme
* add back build_with_cmake --------- Co-authored-by: legendecas <legendecas@gmail.com>

reading declarations

Changes to src/5-async-work/call-js-from-async-worker-execute/. All files

src/5-async-work/call-js-from-async-worker-execute/node-addon-api/binding.gyp

new file mode 100644@@ -0,0 +1,28 @@+{+  "targets": [+    {+      "target_name": "dispatcher",+      "sources": [ "src/binding.cc" ],+      'cflags!': [ '-fno-exceptions' ],+      'cflags_cc!': [ '-fno-exceptions' ],+      'include_dirs': ["<!@(node -p \"require('node-addon-api').include\")"],+      'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"],+      'conditions': [+        ['OS=="win"', {+          "msvs_settings": {+            "VCCLCompilerTool": {+              "ExceptionHandling": 1+            }+          }+        }],+        ['OS=="mac"', {+          "xcode_settings": {+            "CLANG_CXX_LIBRARY": "libc++",+            'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',+            'MACOSX_DEPLOYMENT_TARGET': '10.7'+          }+        }]+      ]+    }+  ]+}

src/5-async-work/call-js-from-async-worker-execute/node-addon-api/index.js

new file mode 100644@@ -0,0 +1,25 @@+'use strict'++const { EventEmitter } = require('node:events');+const { dispatch } = require('bindings')('dispatcher');++class Socket extends EventEmitter {+  constructor () {+    super();+    dispatch(this.emit.bind(this));+  }+}++const socket = new Socket();++socket.on('open', () => {+  console.log('opened');+});++socket.on('message', (message) => {+  console.log(`message: ${message}`);+});++socket.on('close', () => {+  console.log('closed');+});

src/5-async-work/call-js-from-async-worker-execute/node-addon-api/package.json

new file mode 100644@@ -0,0 +1,15 @@+{+  "name": "call-js-from-async-worker-execute",+  "version": "0.0.0",+  "description": "Node.js Addons - calls JS from AsyncWorker::Execute",+  "main": "index.js",+  "private": true,+  "gypfile": true,+  "scripts": {+    "start": "node index.js"+  },+  "dependencies": {+    "node-addon-api": "*",+    "bindings": "*"+  }+}

src/5-async-work/call-js-from-async-worker-execute/node-addon-api/src/binding.cc

new file mode 100644@@ -0,0 +1,101 @@+#include <napi.h>++#include <chrono>+#include <thread>++class Dispatcher : public Napi::AsyncWorker {+ public:+  Dispatcher(Napi::Env env, Napi::Function& callback)+      : Napi::AsyncWorker(env),+        callback_(callback),+        tsfn_{+            Napi::ThreadSafeFunction::New(env, callback, "Dispatcher", 0, 1)} {}++  virtual ~Dispatcher() override { tsfn_.Release(); }++  void Execute() override {+    // Since this method executes on a thread that is different from the main+    // thread, we can't directly call into JavaScript. To trigger a call into+    // JavaScript from this thread, ThreadSafeFunction needs to be used to+    // communicate with the main thread, so that the main thread can invoke the+    // JavaScript function.++    napi_status status =+        tsfn_.BlockingCall([](Napi::Env env, Napi::Function js_callback) {+          js_callback.Call({Napi::String::New(env, "open")});+        });+    if (status != napi_ok) {+      SetError("Napi::ThreadSafeNapi::Function.BlockingCall() failed");+      return;+    }++    std::this_thread::sleep_for(std::chrono::seconds(1));+    status = tsfn_.BlockingCall([](Napi::Env env, Napi::Function js_callback) {+      js_callback.Call(+          {Napi::String::New(env, "message"), Napi::String::New(env, "data1")});+    });+    if (status != napi_ok) {+      SetError("Napi::ThreadSafeNapi::Function.BlockingCall() failed");+      return;+    }++    std::this_thread::sleep_for(std::chrono::seconds(1));+    status = tsfn_.BlockingCall([](Napi::Env env, Napi::Function js_callback) {+      js_callback.Call(+          {Napi::String::New(env, "message"), Napi::String::New(env, "data2")});+    });+    if (status != napi_ok) {+      SetError("Napi::ThreadSafeNapi::Function.BlockingCall() failed");+      return;+    }++    std::this_thread::sleep_for(std::chrono::seconds(1));+    status = tsfn_.BlockingCall([](Napi::Env env, Napi::Function js_callback) {+      js_callback.Call(+          {Napi::String::New(env, "message"), Napi::String::New(env, "data3")});+    });+    if (status != napi_ok) {+      SetError("Napi::ThreadSafeNapi::Function.BlockingCall() failed");+      return;+    }++    status = tsfn_.BlockingCall([](Napi::Env env, Napi::Function js_callback) {+      js_callback.Call({Napi::String::New(env, "close")});+    });+    if (status != napi_ok) {+      SetError("Napi::ThreadSafeNapi::Function.BlockingCall() failed");+      return;+    }+  }++  void OnError(Napi::Error const& error) override {+    callback_.Call({Napi::String::New(Env(), "error"), error.Value()});+  }++ private:+  Napi::Function callback_;+  Napi::ThreadSafeFunction tsfn_;+};++void Dispatch(const Napi::CallbackInfo& info) {+  Napi::Env env = info.Env();++  if (info.Length() < 1 || !info[0].IsFunction()) {+    Napi::TypeError::New(+        env, "The first argument needs to be the callback function.")+        .ThrowAsJavaScriptException();+    return;+  }++  Napi::Function callback = info[0].As<Napi::Function>();++  Dispatcher* dispatcher = new Dispatcher(env, callback);+  dispatcher->Queue();+}++Napi::Object Init(Napi::Env env, Napi::Object exports) {+  exports.Set("dispatch", Napi::Function::New(env, Dispatch));+  return exports;+}++NODE_API_MODULE(dispatcher, Init)