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 2.1.3 to 3.0.0

test/generator.js

89

index.js

@@ -7,2 +7,34 @@ var is = require('./is')

function wrapGenerator (gen) {
return function (ctx, callback) {
function step (err, res) {
// generator step
try {
var state = err ? iter.throw(err) : iter.next(res)
if (state.done) {
// generator done, callback middleware
callback(null, state.value)
} else if (state.value && is.function(state.value.then)) {
// thenable
state.value.then(function (res) {
step(null, res)
}, function (err) {
step(err || true)
})
}
} catch (err) {
// catch err, break generator
callback(err)
}
}
function next (err, res) {
process.nextTick(function () {
step(err, res)
})
}
var iter = gen.call(this, ctx, next)
step()
}
}
// ginga use method

@@ -42,3 +74,5 @@ function use () {

if (is.function(args[i])) {
this._hooks[name].push(args[i])
this._hooks[name].push(
is.generator(args[i]) ? wrapGenerator(args[i]) : args[i]
)
} else if (is.array(args[i])) {

@@ -54,3 +88,2 @@ // use('a', [fn1, fn2, fn3])

}
return this

@@ -77,4 +110,8 @@ }

if (!is.function(invoke)) invoke = null
else if (is.generator(invoke)) invoke = wrapGenerator(invoke)
var pre = args
var pre = args.map(function (fn) {
if (!is.function(fn)) throw new Error('Middleware must be a function')
return is.generator(fn) ? wrapGenerator(fn) : fn
})

@@ -115,11 +152,5 @@ // define scope method

function next (cb) {
if (is.function(cb)) {
return function (err, result) {
if (err) return next(err)
cb(result)
next()
}
}
if (arguments.length > 0) {
function next (err, res) {
if (err || index === size) {
// callback when err or end of pipeline
if (callback) callback.apply(self, arguments)

@@ -129,33 +160,19 @@ var args = ['end']

ctx.emit.apply(ctx, args)
return
}
if (index < size) {
} else if (index < size) {
var fn = pipe[index]
var argsLen = fn.length
index++
var val = argsLen > 2
? fn.call(self, ctx, resolve, reject)
: fn.call(self, ctx, next)
var val = fn.call(self, ctx, next)
if (val && is.function(val.then)) {
// thenable
val.then(function () {
next()
}).catch(reject)
} else if (argsLen < 2) {
// args without next()
next()
val.then(function (res) {
next(null, res)
}, function (err) {
next(err || true)
})
} else if (fn.length < 2) {
// args without next(), not thenable
next(null, val)
}
} else {
// trigger empty callback if no more pipe
next(null)
}
}
function reject (err) {
next(err || true)
}
function resolve (res) {
next(null, res)
}

@@ -162,0 +179,0 @@ if (callback) {

@@ -27,1 +27,2 @@ var is = module.exports

}
is.generator = require('is-generator-function')
{
"name": "ginga",
"version": "2.1.3",
"description": "Middleware framework for JavaScript functions",
"version": "3.0.0",
"description": "Middleware framework for async functions using callback, promise or generator",
"scripts": {

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

"dependencies": {
"pinkie-promise": "^1.0.0"
"is-generator-function": "^1.0.3",
"pinkie-promise": "^2.0.0"
},

@@ -26,0 +27,0 @@ "devDependencies": {

# Ginga.js
Ginga is a utility module that enables a middleware based (express inspired), modular architecture for creating asynchronous JavaScript function. Supports both callback and [promise](https://github.com/floatdrop/pinkie-promise).
Middleware based control flow for defining async JavaScript methods using callback, promise or generator.

@@ -28,14 +28,13 @@ [![Build Status](https://travis-ci.org/cshum/ginga.svg?branch=master)](https://travis-ci.org/cshum/ginga)

#### app.define(name, [pre...], invoke)
Creates an async `name` method that supports both callback and promise. See examples below.
#### app.use(name, [hook...])
`define()` and `use()` a method with `pre`, `hook`, `invoke` middleware functions.
`pre` middlewares initiate and batch operations where `invoke` commits result.
`hook` can be mounted for additional validations or amendments.
Inject additional middleware between `pre` and `invoke` of method `name`. See examples below.
Ginga method supports both callback and [promise](https://github.com/floatdrop/pinkie-promise).
### Middleware
Middleware turns asynchronous functions into encapsulated, reusable set of building blocks.
Upon calling a method, Ginga method goes through a sequence of middleware functions, with following arguments:
Upon calling a method, Ginga method goes through a sequence of middleware functions with following arguments:

@@ -45,7 +44,9 @@ * `ctx` - context event emitter object:

* A middleware can make changes to context object, or access changes made by previous middleware.
* Emits end event `ctx.on('end', fn)` on callback with error and result arguments.
* `next` - callback function:
* `next()` to pass control to the next middleware.
* `next(err, result)` to end the sequence and callback with error or result.
* Emits `end` event with error and result arguments.
* `next` - optional stepping function using callback, which ends the sequence if callback with error argument.
Ginga middleware can be created using callback, promise or generator, interchangeably:
#### Callback
```js

@@ -57,13 +58,15 @@ var ginga = require('ginga')

app.define('test', function (ctx, next) {
ctx.logs = ['pre']
next()
}, function (ctx, done) {
setTimeout(function () {
ctx.logs = ['pre']
next() // next middleware callback
}, 1000)
}, function (ctx) {
// not passing next argument: treated as synchronous call
ctx.logs.push('invoke')
done(null, ctx.logs)
return ctx.logs // returns value of the end of middleware sequence
})
// hook
app.use('test', function (ctx, next) {
app.use('test', function (ctx) {
ctx.logs.push('hook')
setTimeout(next, 10) // async next
})

@@ -76,26 +79,50 @@

// method call with promise
app.test().then(function (res) {
console.log(res) // ['pre', 'hook', 'invoke']
})
```
shortcuts for callback functions:
#### Promise
By returning promise, value will be resolved before passing to next middleware or returning result. Promise reject ends the middleware sequence.
```js
function (ctx, next) {
task(function (err, res) {
if (err) return next(err)
var ginga = require('ginga')
var app = ginga()
// define method
app.define('test', function (ctx) {
return fnAsync().then(function (data) {
// do stuff
next()
})
}
// equivalent to
function (ctx, next) {
task(next(function (res) {
// do stuff
}))
}
}, function (ctx) {
// returns result from last promise resolve
return fn2Async()
})
// method call with promise
app.test().then(...).catch(...)
```
#### Generator
In ES6 generators, functions can be paused and resumed using the `yield` keyword.
Both promise and callback are 'yieldable' in ginga middleware.
This enables powerful control flow while maintaining compatibility.
```js
var ginga = require('ginga')
var app = ginga()
app.define('test', function * (ctx, next) {
var foo = yield Promise.resolve('bar') // Promise is yieldable
yield setTimeout(next, 100) // callback based function is also yieldable
try {
ctx.key = yield fs.readfile('./foo/bar', next)
} catch (err) {
ctx.key = 'whatever'
}
}, function (ctx) * {
// returns result
return yield db.get(ctx.key)
})
```
#### ginga.params([param...])

@@ -102,0 +129,0 @@

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

function invoke (ctx, resolve, reject) {
return resolve(ctx.params)
function invoke (ctx) {
// returns val
return ctx.params
}

@@ -9,0 +10,0 @@ var obj = ginga()

@@ -6,3 +6,3 @@ var tape = require('tape')

tape('ginga prototype', function (t) {
t.plan(12)
t.plan(8)

@@ -18,8 +18,5 @@ function Clock () {

}
function tick (ctx, next) {
function tick (ctx) {
// no next arg
ctx.logs.push(this._tick)
// resolver function
next(function (result) {
t.equal(result, 167199, 'resolver result')
})(null, 167199)
}

@@ -26,0 +23,0 @@ function tock (ctx) {

Sorry, the diff of this file is not supported yet

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