How can I bind OLSRT to Node.js?



This content originally appeared on DEV Community and was authored by Javad

Hey Dev Community!
I’m glad to share a new post with you!
I’ve been working on OLSRT, a lightweight runtime written in pure C.
It brings together concepts like Actors, Channels, Promise/Futures, Event Loop, WebSocket, HTTP, Parallel, and Poller into one modular system.

Think of it as a flexible foundation for building event-driven applications, similar in spirit to Node.js or libuv, but desgined to be minimal and hackable, but powerful.

Here’s a tiny example of how a promise & future works in OLSRT (C++):

#include "olsrt.h"
#include <iostream>
#include <string>
#include <vector>

// Callback for future
void print_callback(ol_future_t* f, void* arg) {
    const char* msg = static_cast<const char*>(arg);
    std::cout << msg << std::endl;
}

int main() {
    // Making a loop
    ol_loop_t* loop = ol_loop_create();

    // Making future
    ol_future_t* f = ol_future_create(loop);

    // Some callbacks...
    ol_future_then(f, print_callback, (void*)"Async Message");
    ol_future_then(f, print_callback, (void*)"Another Async Message");
    ol_future_then(f, print_callback, (void*)"Yet another one");
    ol_future_then(f, print_callback, (void*)"Finished async chain");

    // Just a simply hello world
    std::cout << "Hello, World!" << std::endl;

    // Resolve future -> Running all callbacks
    ol_future_resolve(f, nullptr);

    // Running loop (For Async Dispatch)
    ol_loop_run(loop);

    // Cleanup the memory
    ol_loop_destroy(loop);
    return 0;
}

For binding to node.js, first you must install N-API or node-addon-api, here is an example with node-addon-api:
Project structure:

olsrt-node/
-|- binding.gyp // Settings
-|- index.js // Our node.js example
-|- core/
     -|- promise.cpp // Binding
-|- OLSRT/ // OverLab Streams Runtime Core & Includes
     -|- src/
         -|- actors.c
         -|- ...
     -|- includes
         -|- compat.h
         -|- olsrt.h

Example of binding.gyp file:

{
    "targets": [
        {
            "target_name": "olsrt",
            "sources": [ "core/promise.cpp" ],
            "include_dirs": [
                "<!(node -p \"require('node-addon-api').include\")",
                "../OLSRT/include"
            ],
            "dependencies": [
                "<!(node -p \"require('node-addon-api').gyp\")"
            ],
            "cflags": [ "-fno-exceptions" ],
            "cflags_CC!": [ "-fno-exceptions" ],
            "defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ]
        }
    ]
}

core/promise.cpp (Binding):

#include "napi.h"
#include "olsrt.h"
#include <string>
#include <iostream>

struct FutureWrapper {
    ol_future_t* future;
};

Napi::Value CreateFuture(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    ol_loop_t* loop = ol_loop_create();
    FutureWrapper* fw = new FutureWrapper();
    fw->future = ol_future_create(loop);
    return Napi::External<FutureWrapper>::New(env, fw);
}

Napi::Value ResolveFuture(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    auto fw = info[0].As<Napi::External<FutureWrapper>>().Data();
    ol_future_resolve(fw->future, nullptr);
    return env.Undefined();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set("createFuture", Napi::Function::New(env, CreateFuture));
    exports.Set("resolveFuture", Napi::Function::New(env, ResolveFuture));
    return exports;
}

NODE_API_MODULE(olsrt, Init);

Then, you must install and build:

npm install node-addon-api
node-gyp configure build

An example in Node.js (index.js):

const olsrt = require('./build/Release/olsrt');

// Making Future
const f = olsrt.createFuture();

// Emulating Promise in JS
function wrapFuture(f) {
  return new Promise((resolve) => {
    // In full version, we must define ol_future_then
    // Here, we have call resolveFuture by our self
    setTimeout(() => {
      olsrt.resolveFuture(f);
      resolve();
    }, 100);
  });
}

console.log("Hello World");

wrapFuture(f).then(() => {
  console.log("Async message");
  console.log("Another async message");
  console.log("Yet another one");
  console.log("Finished async chain");
});

The output most something like this:

Async message
Another async message
Yet another one
Finished async chain

This was just one of the smallest things that OLSRT can do! Imagine what it can do in Enterprise-grade projects!

But in this post, we want you to discuss with each other, I’d love to hear your thoughts:

  • Which features would you like to see next?
  • Would node.js bindings be useful for your projects?
  • How do you imagine using OLSRT in your own projects? I will see all of you in the next posts! Have a nice OLSRT day 🙂


This content originally appeared on DEV Community and was authored by Javad