Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ginga

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ginga - npm Package Compare versions

Comparing version 0.1.7 to 1.0.0

flatten.js

378

index.js

@@ -1,284 +0,160 @@

(function (name, context, definition) {
if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
module.exports = definition();
} else if (typeof define === 'function' && typeof define.amd === 'object') {
define(function () {
return definition();
});
} else {
var old = context[name];
context[name] = definition();
context[name].noConflict = function(){
context[name] = old;
return this;
};
}
})('ginga', this, function() {
var is = require('./is'),
flatten = require('./flatten'),
params = require('./params');
//util: type checking
var is = {
'string': function(val){
return typeof val === 'string';
},
'boolean': function(val){
return typeof val === 'boolean';
},
'function': function(val){
return typeof val === 'function';
},
'number': function(val){
return typeof val === 'number';
},
'date': function(val){
return Object.prototype.toString.call(val) === '[object Date]';
},
'regexp': function(val){
return Object.prototype.toString.call(val) === '[object RegExp]';
},
'object': function(val){
return typeof val === 'object' && !!val;
},
'array': Array.isArray || function(val){
return Object.prototype.toString.call(val) === '[object Array]';
}
};
var prototypeOf = Object.getPrototypeOf || function(obj){
return obj.__proto__;
};
var prototypeOf = Object.getPrototypeOf || function(obj){
return obj.__proto__;
};
function dummy(){
return true;
//ginga use method
function use(){
//init hooks
if(!this.hasOwnProperty('_hooks')){
this._hooks = {};
}
//util: flatten array
function flatten(arr, res){
if(!res){
res = [];
}
for(var i = 0, l = arr.length; i < l; i++){
if(arr[i] && is.array(arr[i])){
flatten(arr[i], res);
}else{
res.push(arr[i]);
}
}
return res;
}
var args = Array.prototype.slice.call(arguments);
var name = null, i, j, l, m;
//params parsing middleware
function params(){
var args = Array.prototype.slice.call(arguments);
var spec = [];
var specLen = args.length;
var min = 0;
var i, l;
for(i = 0; i<specLen; i++){
var obj = {};
var str = args[i];
var ch = str.slice(-1);
obj.required = '?'.indexOf(ch) === -1;
if(obj.required)
min++;
if( '?'.indexOf(ch) > -1)
str = str.slice(0,-1);
var arg = str.split(':');
obj.name = arg[0];
if(arg.length > 1){
//defined type
var check = is[arg[1].toLowerCase()];
if(typeof check !== 'function')
throw new Error('Parameter `'+arg[0]+'`: type `'+arg[1]+'` not exist');
obj.check = check;
}else
obj.check = dummy;
spec.push(obj);
}
return function(ctx, next){
var i, l;
var args = ctx.args;
var len = args.length;
var params = {};
var index = 0;
var offset = 0;
ctx.params = params;
if(len < min)
return next(new Error('Too few arguments. Expected at least '+min));
while(offset < len && index < specLen){
while(
!spec[index].check(args[offset]) &&
!spec[index].required
){
index++;
if(args[offset] === null || args[offset] === undefined)
offset++;
if(index >= specLen || offset >= len)
return next();
}
if( !spec[index].check(args[offset]) )
return next(new Error('Invalid type on argument `'+args[offset]+'`.'));
params[spec[index].name] = args[offset];
index++;
offset++;
}
next();
};
if(is.array(args[0])){
//use(['a','b','c'], ...)
var arr = args.shift();
for(i = 0, l = arr.length; i<l; i++)
use.apply(this, [arr[i]].concat(args));
return this;
}else if(is.object(args[0]) && args[0]._hooks){
//use(ginga)
var key;
//concat hooks
for(key in args[0]._hooks)
use.call(this, key, args[0]._hooks[key]);
return this;
}
//ginga use method
function use(){
//init hooks
if(!this.hasOwnProperty('_hooks')){
this._hooks = {};
}
//method name
if(is.string(args[0]))
name = args.shift();
if(!name)
throw new Error('Method name is not defined.');
if(!this._hooks[name])
this._hooks[name] = [];
var args = Array.prototype.slice.call(arguments);
var name = null, i, j, l, m;
if(is.array(args[0])){
//use(['a','b','c'], ...)
var arr = args.shift();
for(i = 0, l = arr.length; i<l; i++)
use.apply(this, [arr[i]].concat(args));
for(i = 0, l = args.length; i<l; i++){
if(is.function(args[i])){
this._hooks[name].push(args[i]);
}else if(is.array(args[i])){
//use('a', [fn1, fn2, fn3])
for(j = 0, m = args[i].length; j<m; j++)
use.call(this, name, args[i][j]);
return this;
}else if(is.object(args[0]) && args[0]._hooks){
//use(ginga)
var key;
//concat hooks
for(key in args[0]._hooks)
use.call(this, key, args[0]._hooks[key]);
return this;
}
}else
throw new Error('Middleware must be a function');
}
//method name
if(is.string(args[0]))
name = args.shift();
if(!name)
throw new Error('Method name is not defined.');
if(!this._hooks[name])
this._hooks[name] = [];
return this;
}
for(i = 0, l = args.length; i<l; i++){
if(is.function(args[i])){
this._hooks[name].push(args[i]);
}else if(is.array(args[i])){
//use('a', [fn1, fn2, fn3])
for(j = 0, m = args[i].length; j<m; j++)
use.call(this, name, args[i][j]);
return this;
}else
throw new Error('Middleware must be a function');
}
//ginga define method
function define(){
var args = Array.prototype.slice.call(arguments);
var i, l;
var name = args.shift();
if(is.array(name)) {
name = args.shift();
for(i = 0, l = name.length; i<l; i++)
define.apply(this, [name[i]].concat(args));
return this;
}
//ginga define method
function define(){
var args = Array.prototype.slice.call(arguments);
var i, l;
if(!is.string(name))
throw new Error('method name is not defined');
var name = args.shift();
if(is.array(name)) {
name = args.shift();
for(i = 0, l = name.length; i<l; i++)
define.apply(this, [name[i]].concat(args));
return this;
}
var invoke = args.pop();
if (!is.function(invoke))
invoke = null;
if(!is.string(name))
throw new Error('method name is not defined');
var pre = args;
var invoke = args.pop();
if (!is.function(invoke))
invoke = null;
//define scope method
this[name] = function(){
var args = Array.prototype.slice.call(arguments);
var self = this;
var pre = args;
var callbacks = [];
if (is.function(args[args.length - 1]))
callbacks.push(args.pop());
//define scope method
this[name] = function(){
var args = Array.prototype.slice.call(arguments);
var self = this;
//init pipeline;
var pipe = [];
var obj = this;
var callbacks = [];
if (is.function(args[args.length - 1]))
callbacks.push(args.pop());
//prototype chain
while(obj){
if(obj.hasOwnProperty('_hooks') && obj._hooks[name])
pipe.unshift(obj._hooks[name]);
obj = prototypeOf(obj);
}
//pre middlewares
pipe.unshift(pre);
//init pipeline;
var pipe = [];
var obj = this;
//invoke middleware
if(invoke)
pipe.push(invoke);
//prototype chain
while(obj){
if(obj.hasOwnProperty('_hooks') && obj._hooks[name])
pipe.unshift(obj._hooks[name]);
obj = prototypeOf(obj);
}
//pre middlewares
pipe.unshift(pre);
pipe = flatten(pipe);
//invoke middleware
if(invoke)
pipe.push(invoke);
//context object and next triggerer
var ctx = {
method: name,
args: args
};
var index = 0;
var size = pipe.length;
var cbArgs = null;
pipe = flatten(pipe);
//context object and next triggerer
var ctx = {
method: name,
args: args
};
var index = 0;
var size = pipe.length;
var cbArgs = null;
function end(fn){
if(cbArgs)
fn.apply(self, cbArgs);
else if(is.function(fn))
callbacks.push(fn);
function end(fn){
if(cbArgs)
fn.apply(self, cbArgs);
else if(is.function(fn))
callbacks.push(fn);
}
function next(){
if(arguments.length > 0){
for(var i = 0, l = callbacks.length; i<l; i++)
callbacks[i].apply(self, arguments);
cbArgs = Array.prototype.slice.call(arguments);
return;
}
function next(){
if(arguments.length > 0){
for(var i = 0, l = callbacks.length; i<l; i++)
callbacks[i].apply(self, arguments);
cbArgs = Array.prototype.slice.call(arguments);
return;
}
if(index < size){
var fn = pipe[index];
var len = fn.length;
index++;
if(index < size){
var fn = pipe[index];
var len = fn.length;
index++;
fn.call(self, ctx, next, end);
}else{
//trigger empty callback if no more pipe
next(null);
}
fn.call(self, ctx, next, end);
//args without next()
if(fn.length < 2) next();
}else{
//trigger empty callback if no more pipe
next(null);
}
next();
}
next();
return this;
};
return this;
}
};
return this;
}
function Ginga(scope){
scope = scope || {};
scope.use = use;
scope.define = define;
function Ginga(scope){
scope = scope || {};
scope.use = use;
scope.define = define;
return scope;
}
Ginga.use = use;
Ginga.define = define;
Ginga.params = params;
return scope;
}
Ginga.use = use;
Ginga.define = define;
Ginga.params = params;
return Ginga;
});
module.exports = Ginga;
{
"name": "ginga",
"version": "0.1.7",
"description": "Ginga modularises asynchronous control flow of Javascript functions.",
"version": "1.0.0",
"description": "Middleware framework for JavaScript functions",
"scripts": {

@@ -18,3 +18,3 @@ "test": "set -e; for t in test/*.js; do node $t; done"

],
"author": "Adrian C Shum <me@cshum.com>",
"author": "Adrian C Shum <adrian@cshum.com>",
"license": "MIT",

@@ -21,0 +21,0 @@ "dependencies": {},

@@ -5,4 +5,2 @@ # Ginga.js

This has been thoroughly used in several of my Node.js projects. While it works, may not be in the best optimised form. Any feedback would be greatly appreciated.
[![Build Status](https://travis-ci.org/cshum/ginga.svg?branch=master)](https://travis-ci.org/cshum/ginga)

@@ -64,2 +62,4 @@

Middleware turns asynchronous function into encapsulated, reusable set of building blocks.
Upon calling a method, Ginga goes through a sequence of functions `middleware`. A middleware consists of arguments:

@@ -66,0 +66,0 @@ * `ctx` - context object, shared across middleware functions

@@ -13,5 +13,5 @@ var tape = require('tape');

}
function tick(ctx, next){
function tick(ctx){
//no callback
ctx.logs.push(this._tick);
next();
}

@@ -18,0 +18,0 @@ function tock(ctx, next){

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc