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 🙏

© 2024 – Pkg Stats / Ryan Hefner

evo-elements

v0.0.3

Published

Evo Cloud Basic Elements

Downloads

8

Readme

evo-elements

Overview

This package includes common and basic building elements for all evo projects.

In this version, it includes:

  • Class: defining Class for object-oriented programming
  • Trace: simple console logging with predefined levels and customizable component names
  • States: a basic framework for building a state machine
  • Config: a simple configuration framework to release you from writing similar code in projects
  • DelayedJob: ensure a postponed job won't be scheduled multiple times

Install

npm install evo-elements

or pull directly from github.com and link to your project:

git clone https://github.com/evo-cloud/elements
npm link elements --prefix=node_modules

In your JavaScript code, use

var elements = require('evo-elements');

How to Use

Class

Prototype

Class(baseClass, prototype, options);

Parameters

  • baseClass: baseClass type, optional, default is Object;
  • prototype: the prototype for new class;
  • options: other options like implements and statics, see details below.

Returns

The newly defined class.

Details

A simple and quick sample:

var Class = require('evo-elements').Class;

var MyClass = Class({
  constructor: function (value) {
    // this is the constructor
    this._value = value;
  },
    
  print: function () {
    console.log(this._value);
  },
  
  // getter/setter is supported
  get value () {
    return this._value;
  },
  
  set value (value) {
    if (!isFinite(value)) {
      throw new Error('Bad Value');
    }
    this._value = value;
  }
});

var myObject = new MyClass(1);
myObject.print(); // get 1
myObject.value = myObject.value + 100;
myObject.print(); // get 101

A simple inheritance sample:

var BaseClass = Class({
  constructor: function (value) {
    this.value = value;
  },
  
  print: function () {
    console.log('BaseClass: %d', this.value);
  }
});

var SubClass = Class(BaseClass, {
  constructor: function (val1, val2) {
    BaseClass.prototype.constructor.call(this, val1 + val2);
  },
  
  print: function () {
    console.log('SubClass');
    BaseClass.prototype.print.call(this);
  }
});

var myObject = new SubClass(1, 2);
myObject instanceof SubClass;   // true
myObject instanceof BaseClass;  // true
myObject.print();
// get
// SubClass
// BaseClass: 3

Multiple inheritance with implements

var ActiveBuffer = Class(Buffer, {
  // override Clearable
  clear: function () {
    // TODO I hate to be cleared
    this.emit('cleared');
  }
}, {
  implements: [EventEmitter, Clearable]
});

var buffer = new ActiveBuffer().on('cleared', function () { console.log('CLEARED'); });
buffer.clear();

buffer instanceof Buffer; // true
buffer instanceof EventEmitter; // false
buffer instanceof Clearable;  // false

Static members

var Singleton = Class({
  constructor: function () {
    // ...
  },
  
  work: function () {
    // ...
  }
}, {
  statics: {
    get instance () {
      if (!Singleton._instance) {
        Singleton._instance = new Singleton();
      }
      return Singleton._instance;
    }
  }
});

Singleton.instance.work();

Trace

Prototype

var trace = Trace(componentName);
trace.error(...);
trace.warn(...);
trace.info(...);
trace.verbose(...);
trace.debug(...);
// aliases
trace.err(...); // same as error
trace.log(...); // same as info
trace.dbg(...); // same as debug
trace.verb(...); // same as verbose

Parameters

  • componentName: a string which will be prefixed to the logged line

Returns

The trace object. All the methods follow the same usage as console.log.

Details

The implementation is backed by debug package. You can use environment variable DEBUG to control which information should be logged. See here for details.

States

A simple state machine.

var states = new States(initialState);
states.transit(newState);
states.from(currState).transit(newState)
  • initialState: optional, initialize the state machine with the provided state.
  • newState: the next state to switch to. It can be an object or a function. If it is a function, it gets invoked when transit happens and is expected to return the new state object.
  • currState: used with from to assert current state must be currState, otherwise transit will not happen.

A state object can provides two methods: enter and leave, both are optional.

state.enter(previousState)

Expects returning a state object for next state. If it is different from current state, transition keeps runing.

state.leave(nextState)

Invoked when the state machine transits to nextState before invoking nextState.enter.

Config

A simple configuration framework to load settings from command line arguments and configuration files. It also provides a global settings object to be shared by all the modules in one project. When using this, we don't need to write logic for parsing command line and loading and configuration files.

the configuration can always be shared in modules by

var conf = require('evo-elements').Config.conf;

Usually in the main script, use

var conf = require('evo-elements').Config.parse(myArgv).conf;

to parse from specified arguments instead of process.argv.

Then, use conf.opts to access all the setting options.

Only one command line option is reserved: -c CONFIG_FILE or --config CONFIG_FILE for long option form. The CONFIG_FILE must be a YAML file, and all the keys are merged into conf.opts. For other options like --option VALUE or --option=VALUE will become: conf.opts[option] = VALUE. VALUE is automatically parsed into Number, String or Boolean, if you want to specify a JSON, use --option=json:JSON_STRING.

DelayedJob

If you know process.nextTick or setTimeout, then you know what a DelayedJob instance does. But a little differently. Each time invoking process.nextTick or setTimeout will schedule a job, the job executes as many times as you schedule. With a single instance of DelayedJob, the job is only scheduled once. The next time you schedule before the job gets run, it does nothing.

The usage is simple:

var job = new DelayedJob(function () {
  // Do what you want ...
});

job.schedule(1000); // it will be scheduled in 1 second
job.schedule();     // you want to scheduled in next tick, but actually do nothing, because already scheduled
job.schedule(200);  // still do nothing.

Why is this pattern useful? It is used to collect some small events, and perform all of them in one shot, like:

var queue = [];
var job = new DelayedJob(function () {
  console.log(queue.join(','));
  // clear queue
  queue = [];
});

queue.push('something');
job.schedule();

queue.push('something more');
job.schedule();
...

// finally, all the message are processed in one shot
// printed: something,something more

License

MIT/X11 License