Comparing version 0.2.6 to 0.3.0
'use strict'; | ||
var react = require('../'); // require('react'); | ||
var chainDefine = require('../dsl/chain'); // require('react/dsl/chain'); | ||
//output events as tasks start and complete | ||
react.events.on('*', function (obj) { | ||
chainDefine.events.on('task.*', function (obj) { | ||
var time = new Date(); | ||
@@ -23,3 +23,3 @@ time.setTime(obj.time); | ||
var fn = react.chainDefine() | ||
var fn = chainDefine() | ||
.in('a', 'b', 'cb') // input params | ||
@@ -26,0 +26,0 @@ .out('err', 'm', 's') // final callback output params |
'use strict'; | ||
var react = require('../'); // require('react'); | ||
var chainDefine = require('../dsl/chain'); // require('react/dsl/chain'); | ||
@@ -8,3 +8,3 @@ function multiply(a, b, cb) { cb(null, a * b); } | ||
var fn = react.chainDefine() | ||
var fn = chainDefine() | ||
.in('a', 'b', 'cb') // input params | ||
@@ -11,0 +11,0 @@ .out('err', 'm', 's') // final callback output params |
@@ -7,3 +7,3 @@ 'use strict'; | ||
//output events as tasks start and complete | ||
react.events.on('*', function (obj) { | ||
react.events.on('task.*', function (obj) { | ||
var time = new Date(); | ||
@@ -47,3 +47,3 @@ time.setTime(obj.time); | ||
markdown, 'emailmd -> emailHtml', // using a sync function | ||
customizeEmail, 'user, emailHtml -> err, custEmailHtml', // sync fn | ||
customizeEmail, 'user, emailHtml -> custEmailHtml', // sync fn | ||
deliverEmail, 'custEmailHtml, cb -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done | ||
@@ -50,0 +50,0 @@ ); |
'use strict'; | ||
/*jshint white: false */ | ||
var react = require('../'); // require('react'); | ||
var fstr = require('../dsl/fstr'); // require('react/dsl/fstr'); | ||
//output events as tasks start and complete | ||
react.events.on('*', function (obj) { | ||
fstr.events.on('task.*', function (obj) { | ||
var time = new Date(); | ||
@@ -37,3 +38,3 @@ time.setTime(obj.time); | ||
var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params | ||
var loadAndSave = fstr('filename, uid, outDirname, cb', [ // input params | ||
loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user | ||
@@ -40,0 +41,0 @@ loadFile, 'filename -> err, filedata', |
'use strict'; | ||
/*jshint white: false */ | ||
var react = require('../'); // require('react'); | ||
var fstr = require('../dsl/fstr'); // require('react/dsl/fstr'); | ||
@@ -22,3 +23,3 @@ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); } | ||
var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params | ||
var loadAndSave = fstr('filename, uid, outDirname, cb', [ // input params | ||
loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user | ||
@@ -25,0 +26,0 @@ loadFile, 'filename -> err, filedata', |
'use strict'; | ||
var react = require('../'); // require('react'); | ||
var pcodeDefine = require('../dsl/pcode'); // require('react/dsl/pcode'); | ||
@@ -12,3 +12,3 @@ function multiply(a, b, cb) { cb(null, a * b); } | ||
var fn = react.pcodeDefine('a, b, cb', [ // input params | ||
var fn = pcodeDefine('a, b, cb', [ // input params | ||
'm := multiply(a, b)', // using a callback function, use := | ||
@@ -15,0 +15,0 @@ 's = add(m, a)', // using a sync function, use = |
@@ -99,2 +99,3 @@ 'use strict'; | ||
BaseTask.prototype.isMethodCall = function () { | ||
/*jshint regexp: false */ | ||
return (typeof(this.f) === 'string' && /^.*\..*$/.test(this.f)); //str contains . | ||
@@ -101,0 +102,0 @@ }; |
@@ -46,2 +46,15 @@ 'use strict'; | ||
CbTask.prototype.prepare = function prepare(handleTaskError, vCon, contExec) { | ||
var self = this; | ||
this.cbFun = function (err, arg0, arg1, argn) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
if (err) { handleTaskError(self, err); return; } //handle error and return, we are done | ||
//no error, save callback args to vCon context, then continue execution | ||
vCon.saveResults(self.out, args); | ||
self.complete(args); | ||
contExec(); | ||
}; | ||
}; | ||
CbTask.prototype.exec = function exec(vCon, handleError, contExec) { | ||
@@ -55,3 +68,3 @@ try { | ||
var func = this.f; | ||
var bindObj = null; //global space | ||
var bindObj = vCon.getVar('this'); //global space or the original this | ||
if (this.isMethodCall()) { //if method call then reset func and bindObj | ||
@@ -58,0 +71,0 @@ func = vCon.getVar(this.f); |
@@ -10,3 +10,2 @@ 'use strict'; | ||
var VContext = require('./vcon.js'); | ||
var FinalCbTask = require('./finalcb-task.js'); | ||
var EventManager = require('./event-manager.js'); | ||
@@ -20,5 +19,15 @@ var inputParser = require('./input-parser.js'); | ||
var reactEmitter = EventManager.globalEventManager; // the top emitter | ||
var reactEmitter = EventManager.global; // the top emitter | ||
/** | ||
merge global react options with parsed options | ||
*/ | ||
function mergeOptions(parsedOptions) { | ||
return Object.keys(reactOptions).reduce(function (accum, k) { | ||
if (!accum[k]) accum[k] = reactOptions[k]; | ||
return accum; | ||
}, parsedOptions); | ||
} | ||
/** | ||
Creates react function which the AST can be manipulated and then | ||
@@ -61,2 +70,8 @@ is ready to be executed. Can be used directly or a DSL can wrap this | ||
if (!errors.length) tskutil.nameTasks(ast.tasks); //run this so names can be checked in ast | ||
if (Object.freeze) { //lets freeze the AST so plugin writers don't accidentally manip the ast | ||
Object.keys(newAST).forEach(function (k) { | ||
if (typeof(newAST[k]) === 'object') Object.freeze(newAST[k]); | ||
}); | ||
Object.freeze(newAST); | ||
} | ||
return errors; | ||
@@ -66,10 +81,18 @@ } | ||
function exec(arg1, arg2, argN, cb) { // called to execute the flow | ||
/*jshint validthis: true */ | ||
var parsedInput = inputParser(Array.prototype.slice.call(arguments), ast); | ||
var args = parsedInput.args; | ||
var cbFinal = parsedInput.cb; | ||
var extraArgs = parsedInput.extraArgs; // we'll have these if we need them | ||
var vCon = VContext.create(args, ast.inParams, ast.locals); // create var ctx with in args & locals | ||
var tasks = ast.tasks.map(tskutil.create); | ||
var vCon = VContext.create(parsedInput.args, ast.inParams, ast.locals, this); // create var ctx with in args & locals | ||
var taskEnv = { // collect taskEnv for hook | ||
parsedInput: parsedInput, | ||
vCon: vCon, | ||
ast: ast, // for reference, will not be used further | ||
taskDefs: ast.tasks.slice(), // create copy | ||
outTaskDef: ast.outTask | ||
}; | ||
reactEmitter.emit(EventManager.TYPES.EXEC_TASKS_PRECREATE, taskEnv); // hook | ||
var tasks = taskEnv.taskDefs.map(tskutil.create); | ||
var tasksByName = tskutil.nameTasks(tasks); // map names to working tasks | ||
var outTask = tskutil.createOutTask(ast.outTask, cbFinal, tasks, vCon); | ||
var outTask = tskutil.createOutTask(taskEnv.outTaskDef, parsedInput.cb, tasks, vCon, mergeOptions(parsedInput.options)); | ||
var handleError = tskutil.createErrorHandler(vCon, outTask); | ||
@@ -86,5 +109,6 @@ | ||
t.flowEmitter = flowEmitter; | ||
if (t.type === 'cb') t.cbFun = tskutil.createCallback(t, handleError, vCon, contExec, flowEmitter); | ||
if (t.prepare) t.prepare(handleError, vCon, contExec, flowEmitter); | ||
}); // create callbacks | ||
contExec(); // start things off | ||
return outTask.retValue; // could return promise | ||
} | ||
@@ -91,0 +115,0 @@ |
@@ -9,4 +9,6 @@ 'use strict'; | ||
var MISSING_NAME = 'param[0] should be the flow name, instead found in/out def: %s'; | ||
var INOUT_PARAMS_NO_MATCH = 'params in wrong format, wanted "foo, bar cb -> err, baz" - found: %s'; | ||
var MISSING_NAME = 'first flow parameter should be the flow name, but found in/out def: %s'; | ||
var INOUT_PARAMS_NO_MATCH = 'params in wrong format, wanted "foo, bar, cb -> err, baz" - found: %s'; | ||
var MISSING_ERR = 'callback specified, but first out param was not "err", use for clarity. Found in/out def: %s'; | ||
var MISSING_CB = 'found err param, but cb/callback is not specified, is this cb-style async or sync function? Found in/out def: %s'; | ||
var EXTRA_TASKARG = 'extra unmatched task arg: %s'; | ||
@@ -29,8 +31,14 @@ | ||
var inOutDefParse = { | ||
regex: /^([^\-]*)(->\s*(.*))?$/i, | ||
fn: function (m) { | ||
var inParams = parse.splitTrimFilterArgs(m[1]); | ||
splitStr: '->', | ||
fn: function (m, origStr) { | ||
var inParams = parse.splitTrimFilterArgs(m[0]); | ||
var lastParam = inParams[inParams.length - 1]; | ||
var type = (lastParam && CB_NAMES_RE.test(lastParam)) ? 'cb' : 'ret'; | ||
var outParams = parse.splitTrimFilterArgs(m[3]); | ||
var outParams = parse.splitTrimFilterArgs(m[1]); | ||
var firstOutParam = outParams[0]; | ||
if (type === 'cb' && (!firstOutParam || !ERR_NAMES_RE.test(firstOutParam))) { | ||
throw new Error(sprintf(MISSING_ERR, origStr)); // found cb, but no err param | ||
} else if (type === 'ret' && firstOutParam && ERR_NAMES_RE.test(firstOutParam)) { | ||
throw new Error(sprintf(MISSING_CB, origStr)); // found err but not cb param | ||
} | ||
return { | ||
@@ -37,0 +45,0 @@ type: type, |
@@ -6,8 +6,16 @@ 'use strict'; | ||
var EVENT_EMITTER2_CONFIG = { | ||
wildcard: true | ||
wildcard: true, // should the event emitter use wildcards. | ||
delimiter: '.', // the delimiter used to segment namespaces, defaults to `.`. | ||
maxListeners: 30 // the max number of listeners that can be assigned to an event, defaults to 10. | ||
}; | ||
var TYPES = { | ||
TASK_BEGIN: 'task.begin', | ||
TASK_COMPLETE: 'task.complete' | ||
// Flow monitoring events and their params | ||
TASK_BEGIN: 'task.begin', // task | ||
TASK_COMPLETE: 'task.complete', // task | ||
// Internal Hooks | ||
EXEC_INPUT_PREPROCESS: 'exec.input.preprocess', // parsedInput | ||
EXEC_TASKS_PRECREATE: 'exec.tasks.precreate', // taskEnv | ||
EXEC_OUTTASK_CREATE: 'exec.outTask.create' // outTaskOptions | ||
}; | ||
@@ -25,2 +33,5 @@ | ||
EventManager.TYPES = TYPES; | ||
EventManager.prototype.TYPES = TYPES; | ||
EventManager.prototype.isEnabled = function () { // if has listener or an ancestor has listener | ||
@@ -41,2 +52,3 @@ return (this.emitter || (this.parent && this.parent.isEnabled())); | ||
EventManager.prototype.emit = function (event, arg1, arg2, argN) { | ||
if (event === undefined) throw new Error('event is undefined'); | ||
if (this.emitter) this.emitter.emit.apply(this.emitter, arguments); | ||
@@ -60,3 +72,2 @@ if (this.parent && this.parent.isEnabled()) this.parent.emit.apply(this.parent, arguments); | ||
module.exports = EventManager; | ||
module.exports.TYPES = TYPES; | ||
module.exports.globalEventManager = EventManager.create(); // create one top level emitter | ||
module.exports.global = EventManager.create(); // create one top level emitter |
@@ -11,3 +11,10 @@ 'use strict'; | ||
function FinalCbFirstSuccTask(taskDef, cbFunc, tasks, vCon) { | ||
function FinalCbFirstSuccTask(outTaskOptions) { | ||
var taskDef = outTaskOptions.taskDef; | ||
var cbFunc = outTaskOptions.cbFunc; | ||
var tasks = outTaskOptions.tasks; | ||
var vCon = outTaskOptions.vCon; | ||
var execOptions = outTaskOptions.execOptions; | ||
var retValue = outTaskOptions.retValue; | ||
if (typeof(cbFunc) !== 'function') throw new Error('callback is not a function'); | ||
var self = this; | ||
@@ -18,2 +25,3 @@ Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; }); | ||
this.vCon = vCon; | ||
this.retValue = retValue; | ||
} | ||
@@ -32,7 +40,2 @@ | ||
return errors; | ||
} | ||
FinalCbFirstSuccTask.create = function (taskDef, cbFunc, tasks, vCon) { | ||
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function'); | ||
return new FinalCbFirstSuccTask(taskDef, cbFunc, tasks, vCon); | ||
}; | ||
@@ -39,0 +42,0 @@ |
@@ -10,3 +10,10 @@ 'use strict'; | ||
function FinalCbTask(taskDef, cbFunc, tasks, vCon) { | ||
function FinalCbTask(outTaskOptions) { | ||
var taskDef = outTaskOptions.taskDef; | ||
var cbFunc = outTaskOptions.cbFunc; | ||
var tasks = outTaskOptions.tasks; | ||
var vCon = outTaskOptions.vCon; | ||
var execOptions = outTaskOptions.execOptions; | ||
var retValue = outTaskOptions.retValue; | ||
if (typeof(cbFunc) !== 'function') throw new Error('callback is not a function'); | ||
var self = this; | ||
@@ -17,2 +24,3 @@ Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; }); | ||
this.vCon = vCon; | ||
this.retValue = retValue; | ||
} | ||
@@ -34,7 +42,2 @@ | ||
FinalCbTask.create = function (taskDef, cbFunc, tasks, vCon) { | ||
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function'); | ||
return new FinalCbTask(taskDef, cbFunc, tasks, vCon); | ||
}; | ||
FinalCbTask.prototype.isReady = function () { | ||
@@ -41,0 +44,0 @@ return (this.tasks.every(function (t) { return (t.status === STATUS.COMPLETE); })); |
'use strict'; | ||
var EventManager = require('./event-manager.js'); | ||
var defaultExecOptions = { | ||
reactExecOptions: true, | ||
outputStyle: 'callback', | ||
outputStyle: 'cb', | ||
}; | ||
var OUTPUT_STYLES = { | ||
CALLBACK: 'callback', | ||
CALLBACK: 'cb', | ||
NONE: 'none' | ||
@@ -39,3 +41,5 @@ }; | ||
parsedInput.cb = splitResult.cb; | ||
if (splitResult.extra) parsedInput.extraArgs = splitResult.extra; | ||
if (splitResult.outputStyle) parsedInput.options.outputStyle = splitResult.outputStyle; | ||
if (splitResult.extra) parsedInput.extraArgs = splitResult.extra; | ||
EventManager.global.emit(EventManager.TYPES.EXEC_INPUT_PREPROCESS, parsedInput); // hook | ||
return parsedInput; | ||
@@ -42,0 +46,0 @@ } |
@@ -12,6 +12,9 @@ 'use strict'; | ||
function parseReduce(accum, regexFn) { | ||
/** | ||
@param patternFn regex + fn or splitStr + fn | ||
*/ | ||
function parseReduce(accum, patternFn) { | ||
if (typeof(accum) !== 'string') return accum; // already matched | ||
var m = regexFn.regex.exec(accum); | ||
if (m) return regexFn.fn(m); // return result obj | ||
var m = (patternFn.regex) ? patternFn.regex.exec(accum) : accum.split(patternFn.splitStr); | ||
if (m) return patternFn.fn(m, accum); // pass in matches and origStr, return result obj | ||
return accum; // no match, return str, will try next matcher | ||
@@ -18,0 +21,0 @@ } |
@@ -53,3 +53,3 @@ 'use strict'; | ||
var func = this.f; | ||
var bindObj = null; //global space | ||
var bindObj = vCon.getVar('this'); //global space or the original this | ||
if (this.isMethodCall()) { //if method call then reset func and bindObj | ||
@@ -56,0 +56,0 @@ func = vCon.getVar(this.f); |
@@ -7,3 +7,5 @@ 'use strict'; | ||
var CbTask = require('./cb-task.js'); | ||
var PromiseTask = require('./promise-task.js'); | ||
var RetTask = require('./ret-task.js'); | ||
var WhenTask = require('./when-task.js'); | ||
var FinalCbTask = require('./finalcb-task.js'); | ||
@@ -14,6 +16,9 @@ var FinalCbFirstSuccTask = require('./finalcb-first-task.js'); | ||
var VContext = require('./vcon.js'); | ||
var EventManager = require('./event-manager.js'); | ||
var TASK_TYPES = { | ||
cb: CbTask, | ||
ret: RetTask | ||
ret: RetTask, | ||
promise: PromiseTask, | ||
when: WhenTask | ||
}; | ||
@@ -111,3 +116,4 @@ function taskTypeKeys() { return Object.keys(TASK_TYPES); } | ||
var tasks = taskDefs.map(create); | ||
tasks.forEach(function (t, idx) { | ||
var tasksWFunctions = tasks.filter(function (t) { return (t.type !== 'when'); }); // non-when tasks need f | ||
tasksWFunctions.forEach(function (t, idx) { | ||
if (!t.functionExists(vCon)) { // error if function doesnt exist AND | ||
@@ -127,3 +133,5 @@ if (!t.isMethodCall()) errors.push(sprintf(LOCAL_FN_MISSING, t.f, idx)); // not method OR | ||
function fName(fn) { | ||
return (typeof(fn) === 'string') ? fn : fn.name; | ||
return (fn) ? | ||
((fn.name) ? fn.name : fn) : // if defined, try name, otherwise toString() | ||
'undefined'; // not defined, use undefined | ||
} | ||
@@ -162,20 +170,17 @@ | ||
function createOutTask(taskDef, cbFinal, tasks, vCon) { | ||
function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions) { | ||
setMissingOutTaskType(taskDef); | ||
var TaskConstructor = OUT_TASK_TYPES[taskDef.type]; | ||
return new TaskConstructor(taskDef, cbFinal, tasks, vCon); | ||
var outTaskOptions = { | ||
taskDef: taskDef, | ||
cbFunc: cbFunc, | ||
tasks: tasks, | ||
vCon: vCon, | ||
execOptions: execOptions, | ||
TaskConstructor: OUT_TASK_TYPES[taskDef.type] | ||
}; | ||
EventManager.global.emit(EventManager.TYPES.EXEC_OUTTASK_CREATE, outTaskOptions); // hook | ||
var TaskConstructor = outTaskOptions.TaskConstructor; // hook could have changed | ||
return new TaskConstructor(outTaskOptions); | ||
} | ||
function createCallback(task, handleTaskError, vCon, contExec) { | ||
return function (err, arg0, arg1, argn) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
if (err) { handleTaskError(task, err); return; } //handle error and return, we are done | ||
//no error, save callback args to vCon context, then continue execution | ||
vCon.saveResults(task.out, args); | ||
task.complete(args); | ||
contExec(); | ||
}; | ||
} | ||
function createErrorHandler(vCon, outTask) { | ||
@@ -242,4 +247,3 @@ return function handleError(task, err) { | ||
exports.createOutTask = createOutTask; | ||
exports.createCallback = createCallback; | ||
exports.createErrorHandler = createErrorHandler; | ||
exports.findReadyAndExec = findReadyAndExec; |
@@ -16,4 +16,4 @@ 'use strict'; | ||
// match any of our literals true, false, int, float, quoted strings, or is property (has dot) | ||
var LITERAL_OR_PROP_RE = /^(true|false|\-?[0-9\.]+)$|'|"|\./i; | ||
// match any of our literals true, false, int, float, quoted strings, or is property (has dot), match vcon.js | ||
var LITERAL_OR_PROP_RE = /^(true|false|this|null|\-?[0-9\.]+)$|'|"|\./i; | ||
@@ -157,5 +157,5 @@ var validateInParams, validateTasks, validateOutTask, validateTaskNamesUnique; | ||
}, errors); | ||
return errors; //TODO reenable | ||
return errors; | ||
} | ||
module.exports = validate; |
@@ -19,2 +19,3 @@ 'use strict'; | ||
if (name === 'false') return false; | ||
if (name === 'null') return null; | ||
if (/^-?[0-9]+$/.test(name)) return parseInt(name, 10); //int | ||
@@ -36,3 +37,3 @@ if (/^-?[0-9.]+$/.test(name)) return parseFloat(name); //float | ||
*/ | ||
VContext.prototype.saveResults = function(paramArr, valuesArr) { // set values for params | ||
VContext.prototype.saveResults = function (paramArr, valuesArr) { // set values for params | ||
var self = this; | ||
@@ -43,3 +44,3 @@ paramArr.forEach(function (k, idx) { //save values to v context | ||
this.setLastResults(valuesArr); | ||
} | ||
}; | ||
@@ -67,5 +68,7 @@ VContext.prototype.setVar = function (name, value) { //name might be simple or obj.prop | ||
will be used | ||
@param self used to pass 'this' context in | ||
*/ | ||
VContext.create = function (args, inParams, locals) { | ||
VContext.create = function (args, inParams, locals, self) { | ||
var initValues = {}; | ||
if (self) initValues['this'] = self; | ||
if (locals) Object.keys(locals).forEach(function (k) { initValues[k] = locals[k]; }); // copy over keys | ||
@@ -72,0 +75,0 @@ var vContext = new VContext(); |
{ | ||
"name": "react", | ||
"description": "React is a javascript module to make it easier to work with asynchronous code, by reducing boilerplate code and improving error and exception handling while allowing variable and task dependencies when defining flow.", | ||
"version": "0.2.6", | ||
"version": "0.3.0", | ||
"author": "Jeff Barczewski <jeff.barczewski@gmail.com>", | ||
@@ -18,3 +18,5 @@ "repository": { "type": "git", "url": "http://github.com/jeffbski/react.git" }, | ||
"tap" : "~0.1.0", | ||
"tapr" : "~0.1.0" | ||
"tapr" : "~0.1.0", | ||
"promised-io" : "~0.3.0", | ||
"Deferred" : "~0.1.1" | ||
}, | ||
@@ -21,0 +23,0 @@ "scripts": { |
@@ -9,5 +9,1 @@ 'use strict'; | ||
// additional interfaces | ||
module.exports.fstrDefine = require('./lib/fstr.js'); | ||
module.exports.pcodeDefine = require('./lib/pcode.js'); | ||
module.exports.chainDefine = require('./lib/chain.js'); |
@@ -43,3 +43,3 @@ # React.js | ||
- selectFirst flow where the first task that returns defined, non-null value is used | ||
- (planned) promise style functions - also automatic resolution of promise inputs | ||
- promise style functions - also automatic resolution of promise inputs (optional require('react/promise-resolve');) | ||
- (planned) use of resulting flow function as callback style or promise style (if no callback provided) | ||
@@ -161,3 +161,3 @@ - (planned) iteration on arrays, streams, sockets | ||
```javascript | ||
var react = require('react'); | ||
var fstrDefine = require('react/dsl/fstr'); | ||
@@ -181,3 +181,3 @@ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); } | ||
var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params | ||
var loadAndSave = fstrDefine('filename, uid, outDirname, cb', [ // input params | ||
loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user | ||
@@ -201,3 +201,3 @@ loadFile, 'filename -> err, filedata', | ||
```javascript | ||
var react = require('react'); | ||
var pcodeDefine = require('react/dsl/pcode'); | ||
@@ -211,3 +211,3 @@ function multiply(a, b, cb) { cb(null, a * b); } | ||
var fn = react.pcodeDefine('a, b, cb', [ // input params | ||
var fn = pcodeDefine('a, b, cb', [ // input params | ||
'm := multiply(a, b)', // using a callback function, use := | ||
@@ -229,3 +229,3 @@ 's = add(m, a)', // using a sync function, use = | ||
```javascript | ||
var react = require('react'); | ||
var chainDefine = require('react/dsl/chain'); | ||
@@ -235,3 +235,3 @@ function multiply(a, b, cb) { cb(null, a * b); } | ||
var fn = react.chainDefine() | ||
var fn = chainDefine() | ||
.in('a', 'b', 'cb') // input params | ||
@@ -252,2 +252,3 @@ .out('err', 'm', 's') // final callback output params | ||
- 2012-01-13 - Add promise tasks, promise resolution, refactor alternate DSL interfaces as optional requires (v0.3.0) | ||
- 2012-01-11 - Provide warning/error when name is skipped in default DSL, literal check in validate (v0.2.5) | ||
@@ -254,0 +255,0 @@ - 2012-01-10 - Create default DSL for react(), create error for missing variables, list remaining tasks when flow won't complete |
@@ -380,4 +380,63 @@ 'use strict'; | ||
}); | ||
test('using "this" in a cb function', function (t) { | ||
t.plan(3); | ||
function getA(cb) { | ||
/*jshint validthis: true */ | ||
cb(null, this.a); | ||
} | ||
var fn = react(); | ||
var errors = fn.setAndValidateAST({ | ||
inParams: [], | ||
tasks: [ | ||
{ f: getA, a: [], out: ['a'] } | ||
], | ||
outTask: { a: ['a'] } | ||
}); | ||
t.deepEqual(errors, [], 'no validation errors'); | ||
var obj = { | ||
a: 100 | ||
}; | ||
fn.apply(obj, [function (err, a) { | ||
t.equal(err, null); | ||
t.equal(a, 100); | ||
t.end(); | ||
}]); | ||
}); | ||
test('using "this" in a sync function', function (t) { | ||
t.plan(3); | ||
function getA(cb) { | ||
/*jshint validthis: true */ | ||
return this.a; | ||
} | ||
var fn = react(); | ||
var errors = fn.setAndValidateAST({ | ||
inParams: [], | ||
tasks: [ | ||
{ f: getA, a: [], out: ['a'], type: 'ret' } | ||
], | ||
outTask: { a: ['a'] } | ||
}); | ||
t.deepEqual(errors, [], 'no validation errors'); | ||
var obj = { | ||
a: 100 | ||
}; | ||
fn.apply(obj, [function (err, a) { | ||
t.equal(err, null); | ||
t.equal(a, 100); | ||
t.end(); | ||
}]); | ||
}); | ||
// Select first tests | ||
test('selectFirst with first succeeding', function (t) { | ||
@@ -402,3 +461,3 @@ t.plan(6); | ||
fn(2, 3, function (err, c, d) { | ||
fn(2, 3, function (err, c) { | ||
t.equal(err, null); | ||
@@ -436,3 +495,3 @@ t.equal(c, 6); | ||
fn(2, 3, function (err, c, d) { | ||
fn(2, 3, function (err, c) { | ||
t.equal(err, null); | ||
@@ -474,3 +533,3 @@ t.equal(c, 5); | ||
fn(2, 3, function (err, c, d) { | ||
fn(2, 3, function (err, c) { | ||
t.equal(err, null); | ||
@@ -514,3 +573,3 @@ t.equal(c, 5); | ||
fn(2, 3, function (err, c, d) { | ||
fn(2, 3, function (err, c) { | ||
t.equal(err, null); | ||
@@ -517,0 +576,0 @@ t.equal(c, 5); |
@@ -80,2 +80,14 @@ 'use strict'; | ||
test('using - with literal string', function (t) { | ||
var r = react('myName', '"hello-world", cb -> err, c', | ||
falpha, '"another-string", cb -> err, c' | ||
); | ||
t.deepEqual(r.ast.inParams, ['"hello-world"']); | ||
t.deepEqual(r.ast.tasks, [ | ||
{ f: falpha, a: ['"another-string"'], out: ['c'], type: 'cb', name: 'falpha'} | ||
]); | ||
t.deepEqual(r.ast.outTask, { a: ['c'], type: 'finalcb' }); | ||
t.end(); | ||
}); | ||
test('single task, ERR and out params', function (t) { | ||
@@ -203,11 +215,50 @@ var r = react('myName', 'cb -> ERR, c', | ||
}; | ||
t.throws(fn, new Error('param[0] should be the flow name, instead found in/out def: cb -> err, c')); | ||
t.throws(fn, new Error('first flow parameter should be the flow name, but found in/out def: cb -> err, c')); | ||
t.end(); | ||
}); | ||
test('missing err in flow in/out - force for consistency, throw error', function (t) { | ||
var fn = function () { | ||
var r = react('myname', 'cb -> c', // missing err | ||
falpha, 'cb -> err, c' | ||
); | ||
}; | ||
t.throws(fn, new Error('callback specified, but first out param was not "err", use for clarity. Found in/out def: cb -> c')); | ||
t.end(); | ||
}); | ||
test('missing err in task in/out - force for consistency, throw error', function (t) { | ||
var fn = function () { | ||
var r = react('myname', 'cb -> err, c', | ||
falpha, 'cb -> c' // missing err | ||
); | ||
}; | ||
t.throws(fn, new Error('callback specified, but first out param was not "err", use for clarity. Found in/out def: cb -> c')); | ||
t.end(); | ||
}); | ||
test('found err, but missing cb/callback in flow in/out - force for consistency, throw error', function (t) { | ||
var fn = function () { | ||
var r = react('myname', 'a -> err, c', // missing cb | ||
falpha, 'cb -> err, c' | ||
); | ||
}; | ||
t.throws(fn, new Error('found err param, but cb/callback is not specified, is this cb-style async or sync function? Found in/out def: a -> err, c')); | ||
t.end(); | ||
}); | ||
test('found err, but missing cb/callback in task in/out - force for consistency, throw error', function (t) { | ||
var fn = function () { | ||
var r = react('myname', 'cb -> err, c', | ||
falpha, 'a -> err, c' // missing cb | ||
); | ||
}; | ||
t.throws(fn, new Error('found err param, but cb/callback is not specified, is this cb-style async or sync function? Found in/out def: a -> err, c')); | ||
t.end(); | ||
}); | ||
test('extra arg throws error', function (t) { | ||
var fn = function () { | ||
var r = react('myName', 'a, b, cb -> err, c, d', | ||
falpha, 'a -> err, c', { after: fbeta }, | ||
falpha, 'a, cb -> err, c', { after: fbeta }, | ||
fbeta, 'a, b -> returns d', | ||
@@ -223,4 +274,4 @@ 'extraBadArg' | ||
var fn = function () { | ||
var r = react('myName', 'a, b, cb -> c, d', | ||
falpha, 'a -> err, c', { after: fbeta }, | ||
var r = react('myName', 'a, b, cb -> err, c, d', | ||
falpha, 'a, cb -> err, c', { after: fbeta }, | ||
fbeta | ||
@@ -234,2 +285,3 @@ ); | ||
test('long example', function (t) { | ||
/*jshint white: false */ | ||
t.plan(4); | ||
@@ -267,3 +319,3 @@ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); } | ||
test('selectFirst', function (t) { | ||
var r = react.selectFirst('myName', 'a, b, cb -> c', | ||
var r = react.selectFirst('myName', 'a, b, cb -> err, c', | ||
{ otherOptFoo: 'foo'}, // main options | ||
@@ -283,2 +335,2 @@ falpha, 'a, b, cb -> err, c', | ||
t.end(); | ||
}); | ||
}); |
@@ -23,3 +23,3 @@ 'use strict'; | ||
reactExecOptions: true, | ||
outputStyle: 'callback' | ||
outputStyle: 'cb' | ||
}; | ||
@@ -34,1 +34,2 @@ | ||
@@ -5,7 +5,8 @@ 'use strict'; | ||
var FinalCbTask = require('../lib/finalcb-task.js'); | ||
var tskutil = require('../lib/task.js'); | ||
test('undefined cb throws exception', function (t) { | ||
var fn = function () { | ||
var finalTask = FinalCbTask.create({}, undefined); | ||
var finalTask = tskutil.createOutTask({}, undefined); | ||
}; | ||
@@ -18,3 +19,3 @@ t.throws(fn, new Error('callback is not a function')); | ||
var fn = function () { | ||
var finalTask = FinalCbTask.create({}, null); | ||
var finalTask = tskutil.createOutTask({}, null); | ||
}; | ||
@@ -27,3 +28,3 @@ t.throws(fn, new Error('callback is not a function')); | ||
var fn = function () { | ||
var finalTask = FinalCbTask.create({}, 'foo'); | ||
var finalTask = tskutil.createOutTask({}, 'foo'); | ||
}; | ||
@@ -36,3 +37,3 @@ t.throws(fn, new Error('callback is not a function')); | ||
function foo() { } | ||
var finalTask = FinalCbTask.create({ a: ['bar', 'baz']}, foo); | ||
var finalTask = tskutil.createOutTask({ a: ['bar', 'baz']}, foo); | ||
t.equal(finalTask.f, foo); | ||
@@ -39,0 +40,0 @@ t.deepEqual(finalTask.a, ['bar', 'baz']); |
@@ -8,4 +8,5 @@ 'use strict'; | ||
test('parser parses input args', function (t) { | ||
function myCb() { } | ||
var ast = { inParams: ['a', 'b'] }; | ||
var parsedInput = inputParser([10, 20], ast); | ||
var parsedInput = inputParser([10, 20, myCb], ast); | ||
t.deepEqual(parsedInput.args, [10, 20]); | ||
@@ -47,7 +48,8 @@ t.deepEqual(parsedInput.options, inputParser.defaultExecOptions); | ||
test('parser pulls react exec option off arg list', function (t) { | ||
function myCb() { } | ||
var ast = { inParams: ['a', 'b'] }; | ||
var execOptions = { reactExecOptions: true, foo: 10 }; | ||
var parsedInput = inputParser([execOptions, 10, 20], ast); | ||
var parsedInput = inputParser([execOptions, 10, 20, myCb], ast); | ||
t.deepEqual(parsedInput.args, [10, 20]); | ||
t.deepEqual(parsedInput.options, { reactExecOptions: true, outputStyle: 'callback', foo: 10 }); | ||
t.deepEqual(parsedInput.options, { reactExecOptions: true, outputStyle: 'cb', foo: 10 }); | ||
t.end(); | ||
@@ -57,9 +59,11 @@ }); | ||
test('parser pulls react exec options off arg list and merges from left to right', function (t) { | ||
function myCb() { } | ||
var ast = { inParams: ['a', 'b'] }; | ||
var execOptions = { reactExecOptions: true, foo: 12, bar: 24 }; | ||
var execOptions2 = { reactExecOptions: true, bar: 36, baz: 'hello' }; | ||
var parsedInput = inputParser([execOptions, execOptions2, 10, 20], ast); | ||
var parsedInput = inputParser([execOptions, execOptions2, 10, 20, myCb], ast); | ||
t.deepEqual(parsedInput.args, [10, 20]); | ||
t.deepEqual(parsedInput.options, { reactExecOptions: true, outputStyle: 'callback', foo: 12, bar: 36, baz: 'hello' }); | ||
t.deepEqual(parsedInput.options, { reactExecOptions: true, outputStyle: 'cb', foo: 12, bar: 36, baz: 'hello' }); | ||
t.end(); | ||
}); | ||
}); | ||
@@ -6,3 +6,3 @@ 'use strict'; | ||
var react = require('../react'); | ||
var react = require('../'); // require('react'); | ||
@@ -39,5 +39,3 @@ /** | ||
t.type(react.options, 'object', 'has property for global react options'); | ||
t.type(react.fstrDefine, 'function', 'has fn property for using fstr dsl'); | ||
t.type(react.pcodeDefine, 'function', 'has fn property for using pcode dsl'); | ||
t.type(react.chainDefine, 'function', 'has fn property for chain define'); | ||
t.type(react.events, 'object', 'has global react event manager'); | ||
t.end(); | ||
@@ -130,191 +128,5 @@ }); | ||
test('use pcodeDefine from module', function (t) { | ||
t.plan(3); | ||
function multiply(a, b, cb) { cb(null, a * b); } | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var locals = { multiply: multiply, add: add }; | ||
var fn = react.pcodeDefine('a, b, cb', [ | ||
'm := multiply(a, b)', | ||
's := add(m, a)', | ||
'cb(err, m, s)' | ||
], locals); | ||
fn(2, 3, function (err, m, s) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(m, 6); | ||
t.equal(s, 8); | ||
t.end(); | ||
}); | ||
}); | ||
test('use pcodeDefine with events', function (t) { | ||
t.plan(8); | ||
function multiply(a, b, cb) { cb(null, a * b); } | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var events = []; | ||
function accumEvents(task) { | ||
events.push(task); | ||
} | ||
var locals = { multiply: multiply, add: add }; | ||
var fn = react.pcodeDefine('a, b, cb', [ | ||
'm := multiply(a, b)', | ||
's := add(m, a)', | ||
'cb(err, m, s)' | ||
], locals); | ||
fn.events.on('task.complete', accumEvents); | ||
fn(2, 3, function (err, m, s) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(m, 6); | ||
t.equal(s, 8); | ||
t.equal(events.length, 2, 'should have seen two task compl events'); | ||
t.equal(events[0].name, 'multiply', 'name matches'); | ||
t.deepEqual(events[0].results, [6], 'results match'); | ||
t.equal(events[1].name, 'add', 'name matches'); | ||
t.deepEqual(events[1].results, [8], 'results match'); | ||
t.end(); | ||
}); | ||
}); | ||
test('use pcodeDefine.selectFirst with events', function (t) { | ||
t.plan(7); | ||
function noSuccess(a, b, cb) { | ||
setTimeout(function () { cb(null); }, 100); // returns undefined result | ||
} | ||
function noSuccessNull(a, b, cb) { cb(null, null); } // returns null result | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var events = []; | ||
function accumEvents(task) { | ||
events.push(task); | ||
} | ||
var locals = { noSuccess: noSuccess, noSuccessNull: noSuccessNull, add: add }; | ||
var fn = react.pcodeDefine.selectFirst('a, b, cb', [ | ||
'c := noSuccess(a, b)', | ||
'c := noSuccessNull(a, b)', | ||
'c := add(a, b)', | ||
'c := noSuccess(a, b)', | ||
'cb(err, c)' | ||
], locals); | ||
fn.events.on('task.complete', accumEvents); | ||
fn(2, 3, function (err, c) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(c, 5); | ||
t.equal(events.length, 3, 'should have seen two task compl events'); | ||
t.equal(events[0].name, 'noSuccess', 'name matches'); | ||
t.equal(events[1].name, 'noSuccessNull', 'name matches'); | ||
t.equal(events[2].name, 'add', 'name matches'); | ||
t.deepEqual(events[2].results, [5], 'results match'); | ||
t.end(); | ||
}); | ||
}); | ||
test('use pcodeDefine events emit to global emitter', function (t) { | ||
t.plan(8); | ||
function multiply(a, b, cb) { cb(null, a * b); } | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var events = []; | ||
function accumEvents(task) { | ||
events.push(task); | ||
} | ||
var locals = { multiply: multiply, add: add }; | ||
var fn = react.pcodeDefine('a, b, cb', [ | ||
'm := multiply(a, b)', | ||
's := add(m, a)', | ||
'cb(err, m, s)' | ||
], locals); | ||
react.events.on('task.complete', accumEvents); // the global react emitter | ||
fn(2, 3, function (err, m, s) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(m, 6); | ||
t.equal(s, 8); | ||
t.equal(events.length, 2, 'should have seen two task compl events'); | ||
t.equal(events[0].name, 'multiply', 'name matches'); | ||
t.deepEqual(events[0].results, [6], 'results match'); | ||
t.equal(events[1].name, 'add', 'name matches'); | ||
t.deepEqual(events[1].results, [8], 'results match'); | ||
t.end(); | ||
}); | ||
}); | ||
test('chainDefine use', function (t) { | ||
t.plan(8); | ||
function multiply(a, b, cb) { cb(null, a * b); } | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var events = []; | ||
function accumEvents(task) { | ||
events.push(task); | ||
} | ||
var fn = react.chainDefine() | ||
.in('a', 'b', 'cb') | ||
.out('err', 'm', 's') | ||
.async(multiply).in('a', 'b', 'cb').out('err', 'm') | ||
.async(add).in('m', 'a', 'cb').out('err', 's') | ||
.end(); | ||
fn.events.on('task.complete', accumEvents); | ||
fn(2, 3, function (err, m, s) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(m, 6); | ||
t.equal(s, 8); | ||
t.equal(events.length, 2, 'should have seen two task compl events'); | ||
t.equal(events[0].name, 'multiply', 'name matches'); | ||
t.deepEqual(events[0].results, [6], 'results match'); | ||
t.equal(events[1].name, 'add', 'name matches'); | ||
t.deepEqual(events[1].results, [8], 'results match'); | ||
t.end(); | ||
}); | ||
}); | ||
test('use chainDefine selectFirst with events', function (t) { | ||
t.plan(7); | ||
function noSuccess(a, b, cb) { | ||
setTimeout(function () { cb(null); }, 100); // returns undefined result | ||
} | ||
function noSuccessNull(a, b, cb) { cb(null, null); } // returns null result | ||
function add(a, b, cb) { cb(null, a + b); } | ||
var events = []; | ||
function accumEvents(task) { | ||
events.push(task); | ||
} | ||
var fn = react.chainDefine() | ||
.selectFirst() | ||
.in('a', 'b', 'cb') | ||
.out('err', 'c') | ||
.async(noSuccess).in('a', 'b', 'cb').out('err', 'c') | ||
.async(noSuccessNull).in('a', 'b', 'cb').out('err', 'c') | ||
.async(add).in('a', 'b', 'cb').out('err', 'c') | ||
.async(noSuccess).in('a', 'b', 'cb').out('err', 'c') | ||
.end(); | ||
fn.events.on('task.complete', accumEvents); | ||
fn(2, 3, function (err, c) { | ||
t.deepEqual(err, null, 'should not be any error'); | ||
t.equal(c, 5); | ||
t.equal(events.length, 3, 'should have seen two task compl events'); | ||
t.equal(events[0].name, 'noSuccess', 'name matches'); | ||
t.equal(events[1].name, 'noSuccessNull', 'name matches'); | ||
t.equal(events[2].name, 'add', 'name matches'); | ||
t.deepEqual(events[2].results, [5], 'results match'); | ||
t.end(); | ||
}); | ||
}); | ||
@@ -285,4 +285,6 @@ 'use strict'; | ||
tasks: [ | ||
{ f: foo, a: ['true', 'false', '123', '123.1'], out: [] }, | ||
{ f: bar, a: ['-123', '-123.4', '"wow"', "'hey'"], out: [] } | ||
{ f: foo, a: ['true', 'false', '123', '123.1', 'null'], out: [] }, | ||
{ f: bar, a: ['-123', '-123.4', '"wow"', "'hey'"], out: [] }, | ||
{ f: foo, a: ['"two-words"', "'also-two'", '"two.words"', "'also.two'"], out: [] }, | ||
{ f: foo, a: ['this'], out: [] } | ||
], | ||
@@ -289,0 +291,0 @@ outTask: { a: [] } |
@@ -70,2 +70,6 @@ 'use strict'; | ||
t.equal(VContext.create([], []).getVar(false), false); | ||
t.equal(VContext.create([], []).getVar(null), null); | ||
t.equal(VContext.create([], []).getVar('true'), true); | ||
t.equal(VContext.create([], []).getVar('false'), false); | ||
t.equal(VContext.create([], []).getVar('null'), null); | ||
t.equal(VContext.create([], []).getVar(-100), -100); | ||
@@ -75,4 +79,13 @@ t.equal(VContext.create([], []).getVar(100), 100); | ||
t.equal(VContext.create([], []).getVar(-987.6), -987.6); | ||
t.equal(VContext.create([], []).getVar('-100'), -100); | ||
t.equal(VContext.create([], []).getVar('100'), 100); | ||
t.equal(VContext.create([], []).getVar('123.4'), 123.4); | ||
t.equal(VContext.create([], []).getVar('-987.6'), -987.6); | ||
t.equal(VContext.create([], []).getVar('"foo"'), 'foo'); | ||
t.equal(VContext.create([], []).getVar("'foo'"), 'foo'); | ||
t.equal(VContext.create([], []).getVar("'foo.bar'"), 'foo.bar'); | ||
t.equal(VContext.create([], []).getVar("'foo-bar'"), 'foo-bar'); | ||
t.equal(VContext.create([], []).getVar("'foo-bar.json'"), 'foo-bar.json'); | ||
t.equal(VContext.create([], []).getVar('"foo-bar.json"'), 'foo-bar.json'); | ||
t.deepEqual(VContext.create([], [], null, { a: 1}).getVar('this'), { a: 1}); | ||
t.end(); | ||
@@ -79,0 +92,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
291
0
212909
4
59
5328