npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

nactor

v0.2.0

Published

Event based actor model framework for game

Readme

NActor - Node.js actor model framework for game

Description

The implementation is inspired by drama

It is an implementation of event-based actor model for node.js. It is designed for game backend service and may work with socket.io for sequential process of game events.

Of course it can be used for non-game service.

Features

  • Easy to declare actor (Interface is similar to drama)
    • Automated binding of proxy interface
  • Sequential order of message execution
    • All the message sent to actor model is processed in sequential order
    • Actor's reply can work in async mode (e.g reply after database read/write)
    • Prevent the race condition of high concurrent write/read to a resource
    • Example usage: Judgement of game event sent from multiple players
  • Event based actor model
    • Running on main event loop
    • High performance
    • Non-restricted access to other resource
  • Support event emission from actor
  • Customizable error handling of uncaught exception in actor.

Hello World


var nactor = require("nactor");

var actor = nactor.actor({
    // Declare your actor model through a object

    hello : function(message) {
        // Actor method
        console.log(message);
        return "Done";
    }
});

// Intialize the actor
actor.init(); 

// Ask to execute the hello() method. It will be called in next tick
actor.ask("hello","Node.js!");

The nactor.actor() constructs an actor model according to the declaration passed through argument. The return is a proxy of the actor which provides interface same as the declaration but the method will not be executed immediately. Instead, it is scheduled to run by the main event loop. The call is async.

The ask() is the standard method to invoke actor's method from proxy. Alternative method is "automated interface binding".

Automated interface binding

Instead of calling the ask() , you may execute the declared method by its name directly.

actor.hello("Node.js!");

Remarks: You must call "init()" before execute any actor method. The interface will not be binded without "init()"

Reply

actor.hello("Node.js!",function(reply){
    console.log(reply); // "Done"
});

Async Reply and Constructor

In the previous example shows that the return from actor method will be passed to sender's callback. It is simple but not suitable for calls that depend on I/O resource. In this case , it should enable the async reply mechanism.


var nactor = require("nactor");

var actor = nactor.actor(function(options) {

   // Alternative method of actor declaration

   // It is the constructor and will be executed by
   // init() immediately

   // Remarks: It is not suggested to put async method here.

   this.seq = 0; // Variables that can be shared for all methods.
   this.timeout = options.timeout;

   return {
      // Declare the method 
      ping : function(data,async){
          async.enable(); // Enable async interface
          setTimeout(function(){
              async.reply("Done!");
          },this.timeout); // Using "this" to access the variable declared
      }
   };

});

// Intialize the actor
actor.init({
   timeout : 200
}); 

actor.ping(function(message){
   console.log(message); // Done!
});

Event Emission

Beside ask() and reply(), actor may send information to sender through event emission.


var nactor = require("nactor");

var actor = nactor.actor(function(options){
    var self = this;

    this.handle = setInterval(function(){
         self.emit("pong","Pong!");
    },300);

    return {
        stop : function(){
            clearInterval(this.handle);
        }
    }
});

actor.init();

actor.on("pong",function(msg){
   console.log(msg);
});

Uncaught Exception Handling

As the actor method is not called directly, you can not catch the exception from actor in sender. Instead, you may call onUncaughtException() to add a listener for uncaught exception.

actor.onUncaughtException(function(err,action){
    console.log(err);
});

If an exception is uncaught , NActor will skip the processing message and handle the next. If you don't like the behaviour. You may stop the message execuation by calling ''action.stop()''

actor.onUncaughtException(function(err,action){
    console.log(err);
    action.stop();
});

Remarks : The actor will no longer be usable after called ''action.stop()''

Licence

New BSD