react 0.2.6 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +2 -1
- package/README.md +94 -149
- package/doc/advanced.md +161 -0
- package/doc/color-def.graffle +938 -0
- package/doc/color-def.png +0 -0
- package/doc/default-simple.dot +19 -0
- package/doc/default-simple.dot.png +0 -0
- package/examples/default-events1.js +33 -6
- package/examples/{fstr1.js → default-log-events.js} +20 -13
- package/examples/default-simple.js +45 -0
- package/lib/base-task.js +8 -6
- package/lib/cb-task.js +14 -1
- package/lib/core.js +43 -12
- package/lib/dsl.js +14 -6
- package/lib/event-collector.js +65 -0
- package/lib/event-manager.js +29 -16
- package/lib/finalcb-first-task.js +16 -10
- package/lib/finalcb-task.js +17 -10
- package/lib/input-parser.js +7 -3
- package/lib/log-events.js +86 -0
- package/lib/parse.js +6 -3
- package/lib/promise-resolve.js +35 -0
- package/lib/promise-task.js +89 -0
- package/lib/ret-task.js +1 -1
- package/lib/task.js +32 -23
- package/lib/track-tasks.js +60 -0
- package/lib/validate.js +3 -3
- package/lib/vcon.js +6 -3
- package/lib/when-task.js +81 -0
- package/package.json +5 -3
- package/react.js +33 -5
- package/test/core-deferred.test.js +134 -0
- package/test/core-promised.test.js +132 -0
- package/test/core-when.test.js +84 -0
- package/test/core.test.js +108 -60
- package/test/dsl.test.js +58 -6
- package/test/exec-options.test.js +2 -1
- package/test/finalcb-task.test.js +6 -5
- package/test/input-parser.test.js +10 -6
- package/test/module-use.test.js +16 -199
- package/test/promise-auto-resolve.test.js +52 -0
- package/test/validate.test.js +4 -2
- package/test/vcon.test.js +13 -0
- package/Jakefile.js +0 -8
- package/examples/chain-events1.js +0 -34
- package/examples/chain1.js +0 -19
- package/examples/fstr-events1.js +0 -51
- package/examples/pcode1.js +0 -22
- package/jake-tasks/jake-test.js +0 -64
- package/lib/chain.js +0 -148
- package/lib/fstr.js +0 -119
- package/lib/pcode.js +0 -173
- package/oldExamples/analyze.js +0 -29
- package/oldExamples/analyze2.js +0 -29
- package/oldExamples/example10-dsl.js +0 -63
- package/oldExamples/example11.js +0 -62
- package/oldExamples/example12.js +0 -63
- package/oldExamples/example13.js +0 -63
- package/oldExamples/example14.js +0 -63
- package/oldExamples/example15.js +0 -75
- package/oldExamples/example6-ast.js +0 -47
- package/oldExamples/example6-dsl.js +0 -49
- package/oldExamples/example8-ast.js +0 -55
- package/oldExamples/example8-dsl.js +0 -53
- package/oldExamples/example9-ast.js +0 -58
- package/oldExamples/example9-dsl.js +0 -57
- package/oldExamples/function-str-ex1.js +0 -33
- package/oldExamples/function-str-ex2.js +0 -67
- package/oldExamples/trait1.js +0 -41
- package/oldExamples/trait2.js +0 -44
- package/test/chain.test.js +0 -253
- package/test/fstr.test.js +0 -300
- package/test/pcode.test.js +0 -335
package/lib/task.js
CHANGED
|
@@ -4,16 +4,21 @@ var util = require('util');
|
|
|
4
4
|
var sprintf = require('sprintf').sprintf;
|
|
5
5
|
var array = require('ensure-array');
|
|
6
6
|
var CbTask = require('./cb-task.js');
|
|
7
|
+
var PromiseTask = require('./promise-task.js');
|
|
7
8
|
var RetTask = require('./ret-task.js');
|
|
9
|
+
var WhenTask = require('./when-task.js');
|
|
8
10
|
var FinalCbTask = require('./finalcb-task.js');
|
|
9
11
|
var FinalCbFirstSuccTask = require('./finalcb-first-task.js');
|
|
10
12
|
var STATUS = require('./status.js');
|
|
11
13
|
var error = require('./error.js');
|
|
12
14
|
var VContext = require('./vcon.js');
|
|
15
|
+
var EventManager = require('./event-manager.js');
|
|
13
16
|
|
|
14
17
|
var TASK_TYPES = {
|
|
15
18
|
cb: CbTask,
|
|
16
|
-
ret: RetTask
|
|
19
|
+
ret: RetTask,
|
|
20
|
+
promise: PromiseTask,
|
|
21
|
+
when: WhenTask
|
|
17
22
|
};
|
|
18
23
|
function taskTypeKeys() { return Object.keys(TASK_TYPES); }
|
|
19
24
|
|
|
@@ -106,7 +111,8 @@ function validateLocalFunctions(inParams, taskDefs, locals) {
|
|
|
106
111
|
var mock_args = inParams.map(function (p) { return foo; }); //mock args with fns
|
|
107
112
|
var vCon = VContext.create(mock_args, inParams, locals);
|
|
108
113
|
var tasks = taskDefs.map(create);
|
|
109
|
-
tasks.
|
|
114
|
+
var tasksWFunctions = tasks.filter(function (t) { return (t.type !== 'when'); }); // non-when tasks need f
|
|
115
|
+
tasksWFunctions.forEach(function (t, idx) {
|
|
110
116
|
if (!t.functionExists(vCon)) { // error if function doesnt exist AND
|
|
111
117
|
if (!t.isMethodCall()) errors.push(sprintf(LOCAL_FN_MISSING, t.f, idx)); // not method OR
|
|
112
118
|
else {
|
|
@@ -121,7 +127,9 @@ function validateLocalFunctions(inParams, taskDefs, locals) {
|
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
function fName(fn) {
|
|
124
|
-
return (
|
|
130
|
+
return (fn) ?
|
|
131
|
+
((fn.name) ? fn.name : fn) : // if defined, try name, otherwise toString()
|
|
132
|
+
'undefined'; // not defined, use undefined
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
/**
|
|
@@ -155,27 +163,28 @@ function create(taskDef) {
|
|
|
155
163
|
return new TaskConstructor(taskDef);
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
function createOutTask(taskDef,
|
|
166
|
+
function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions, env) {
|
|
159
167
|
setMissingOutTaskType(taskDef);
|
|
160
|
-
var
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
//no error, save callback args to vCon context, then continue execution
|
|
170
|
-
vCon.saveResults(task.out, args);
|
|
171
|
-
task.complete(args);
|
|
172
|
-
contExec();
|
|
168
|
+
var outTaskOptions = {
|
|
169
|
+
taskDef: taskDef,
|
|
170
|
+
cbFunc: cbFunc,
|
|
171
|
+
tasks: tasks,
|
|
172
|
+
vCon: vCon,
|
|
173
|
+
execOptions: execOptions,
|
|
174
|
+
env: env,
|
|
175
|
+
TaskConstructor: OUT_TASK_TYPES[taskDef.type]
|
|
173
176
|
};
|
|
177
|
+
EventManager.global.emit(EventManager.TYPES.EXEC_OUTTASK_CREATE, outTaskOptions); // hook
|
|
178
|
+
var TaskConstructor = outTaskOptions.TaskConstructor; // hook could have changed
|
|
179
|
+
return new TaskConstructor(outTaskOptions);
|
|
174
180
|
}
|
|
175
|
-
|
|
181
|
+
|
|
176
182
|
function createErrorHandler(vCon, outTask) {
|
|
177
183
|
return function handleError(task, err) {
|
|
178
184
|
task.status = STATUS.ERRORED;
|
|
185
|
+
task.error = err;
|
|
186
|
+
outTask.env.currentTask = task;
|
|
187
|
+
outTask.env.flowEmitter.emit(EventManager.TYPES.EXEC_TASK_ERRORED, task);
|
|
179
188
|
var errWithMeta = error.augmentError(err, {task: task, vcon: vCon});
|
|
180
189
|
outTask.exec(errWithMeta); //call the final callback with the first error hit
|
|
181
190
|
};
|
|
@@ -197,7 +206,7 @@ function execTasks(tasksReady, vCon, handleError, contExec) {
|
|
|
197
206
|
case everything is fine. If no tasks are running then
|
|
198
207
|
call handleError since this will never complete.
|
|
199
208
|
*/
|
|
200
|
-
function checkIfTasksRunning(vCon, tasks, handleError) {
|
|
209
|
+
function checkIfTasksRunning(vCon, tasks, handleError, env) {
|
|
201
210
|
var tasksRunning = tasks.filter(function (t) {
|
|
202
211
|
return (t.status === STATUS.RUNNING || t.status === STATUS.READY);
|
|
203
212
|
});
|
|
@@ -205,13 +214,14 @@ function checkIfTasksRunning(vCon, tasks, handleError) {
|
|
|
205
214
|
var remainingTasks = tasks.filter(function (t) { return (!t.status); });
|
|
206
215
|
var remainingTNames = remainingTasks.map(function (t) { return t.name; });
|
|
207
216
|
var errMsg = sprintf(NO_TASKS_RUNNING_WONT_COMPLETE, remainingTNames.join(', '));
|
|
208
|
-
|
|
217
|
+
var emptyTask = { env: env };
|
|
218
|
+
handleError(emptyTask, new Error(errMsg));
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
|
|
212
|
-
function findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec) {
|
|
222
|
+
function findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec, env) {
|
|
213
223
|
var tasksReady = findTasksReady(vCon, tasks, tasksByName);
|
|
214
|
-
if (!tasksReady.length) checkIfTasksRunning(vCon, tasks, handleError); // no tasks to run, check if ok
|
|
224
|
+
if (!tasksReady.length) checkIfTasksRunning(vCon, tasks, handleError, env); // no tasks to run, check if ok
|
|
215
225
|
execTasks(tasksReady, vCon, handleError, contExec);
|
|
216
226
|
}
|
|
217
227
|
|
|
@@ -234,6 +244,5 @@ exports.validateLocalFunctions = validateLocalFunctions;
|
|
|
234
244
|
exports.nameTasks = nameTasks;
|
|
235
245
|
exports.create = create;
|
|
236
246
|
exports.createOutTask = createOutTask;
|
|
237
|
-
exports.createCallback = createCallback;
|
|
238
247
|
exports.createErrorHandler = createErrorHandler;
|
|
239
248
|
exports.findReadyAndExec = findReadyAndExec;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Track the tasks, start, complete, args, results, elapsed time
|
|
5
|
+
Emits events that can be monitored
|
|
6
|
+
|
|
7
|
+
- track start and complete
|
|
8
|
+
- record args each task was called with
|
|
9
|
+
- record results at completion
|
|
10
|
+
- record start, end, and calc elapsed time
|
|
11
|
+
- emits flow.begin with flowEnv
|
|
12
|
+
- emits task.begin with task
|
|
13
|
+
- emits task.complete with task
|
|
14
|
+
- emits flow complete with flowEnv
|
|
15
|
+
- emits flow errored with flowEnv
|
|
16
|
+
|
|
17
|
+
@example
|
|
18
|
+
var react = require('react');
|
|
19
|
+
react.trackTasks(); // enable task and flow tracking
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
var react = require('../'); // require('react');
|
|
24
|
+
|
|
25
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_START, function (env){
|
|
26
|
+
env.startTime = Date.now();
|
|
27
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_BEGIN, env); //fire public ev
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
react.events.on(react.events.TYPES.EXEC_TASK_START, function (task) {
|
|
31
|
+
task.startTime = Date.now();
|
|
32
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_BEGIN, task); //fire public ev
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
react.events.on(react.events.TYPES.EXEC_TASK_COMPLETE, function (task) {
|
|
36
|
+
task.endTime = Date.now();
|
|
37
|
+
task.elapsedTime = task.endTime - task.startTime;
|
|
38
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_COMPLETE, task); // fire public ev
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
react.events.on(react.events.TYPES.EXEC_TASK_ERRORED, function (task) {
|
|
42
|
+
task.endTime = Date.now();
|
|
43
|
+
task.elapsedTime = task.endTime - task.startTime;
|
|
44
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_ERRORED, task); // fire public ev
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_COMPLETE, function (env) {
|
|
48
|
+
env.endTime = Date.now();
|
|
49
|
+
env.elapsedTime = env.endTime - env.startTime;
|
|
50
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_COMPLETE, env); //fire public ev
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_ERRORED, function (env) {
|
|
54
|
+
env.endTime = Date.now();
|
|
55
|
+
env.elapsedTime = env.endTime - env.startTime;
|
|
56
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_ERRORED, env); //fire public ev
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
module.exports = react; // return react
|
package/lib/validate.js
CHANGED
|
@@ -13,8 +13,8 @@ var LOCALS_NOTNULL = 'ast.locals should not be null';
|
|
|
13
13
|
var DUP_OUTPUTS = 'multiple tasks output the same param, must be unique. param';
|
|
14
14
|
var MISSING_INPUTS = 'missing or mispelled variable referenced in flow definition: %s';
|
|
15
15
|
|
|
16
|
-
// match any of our literals true, false, int, float, quoted strings, or is property (has dot)
|
|
17
|
-
var LITERAL_OR_PROP_RE = /^(true|false|\-?[0-9\.]+)$|'|"|\./i;
|
|
16
|
+
// match any of our literals true, false, int, float, quoted strings, or is property (has dot), match vcon.js
|
|
17
|
+
var LITERAL_OR_PROP_RE = /^(true|false|this|null|\-?[0-9\.]+)$|'|"|\./i;
|
|
18
18
|
|
|
19
19
|
var validateInParams, validateTasks, validateOutTask, validateTaskNamesUnique;
|
|
20
20
|
var validateLocals, validateOuputsUnique, validateNoMissingNames;
|
|
@@ -153,7 +153,7 @@ function validateNoMissingNames(ast) {
|
|
|
153
153
|
if (!isLiteralOrProp(p) && !names[p]) accum.push(sprintf(MISSING_INPUTS, p)); // add error if missing
|
|
154
154
|
return accum;
|
|
155
155
|
}, errors);
|
|
156
|
-
return errors;
|
|
156
|
+
return errors;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
module.exports = validate;
|
package/lib/vcon.js
CHANGED
|
@@ -16,6 +16,7 @@ VContext.prototype.getVar = function (name) { //name might be simple or obj.prop
|
|
|
16
16
|
// literal checks need to match what is in validate.js
|
|
17
17
|
if (name === 'true') return true;
|
|
18
18
|
if (name === 'false') return false;
|
|
19
|
+
if (name === 'null') return null;
|
|
19
20
|
if (/^-?[0-9]+$/.test(name)) return parseInt(name, 10); //int
|
|
20
21
|
if (/^-?[0-9.]+$/.test(name)) return parseFloat(name); //float
|
|
21
22
|
var m = /^("|')([^\1]*)\1$/.exec(name); //check for quoted string " or '
|
|
@@ -32,13 +33,13 @@ VContext.prototype.getVar = function (name) { //name might be simple or obj.prop
|
|
|
32
33
|
variable :LAST_RESULTS which keeps an array of the last values
|
|
33
34
|
which can be used for chaining and testing last results, etc.
|
|
34
35
|
*/
|
|
35
|
-
VContext.prototype.saveResults = function(paramArr, valuesArr) { // set values for params
|
|
36
|
+
VContext.prototype.saveResults = function (paramArr, valuesArr) { // set values for params
|
|
36
37
|
var self = this;
|
|
37
38
|
paramArr.forEach(function (k, idx) { //save values to v context
|
|
38
39
|
self.setVar(k, (valuesArr[idx] !== undefined) ? valuesArr[idx] : null); //upgrade any undefined to null
|
|
39
40
|
});
|
|
40
41
|
this.setLastResults(valuesArr);
|
|
41
|
-
}
|
|
42
|
+
};
|
|
42
43
|
|
|
43
44
|
VContext.prototype.setVar = function (name, value) { //name might be simple or obj.prop
|
|
44
45
|
if (!name) return; // if name is undefined or null, then discard
|
|
@@ -61,9 +62,11 @@ VContext.prototype.setVar = function (name, value) { //name might be simple or o
|
|
|
61
62
|
Ignore extra arguments passed in. Locals can be
|
|
62
63
|
passed into seed the VContext otherwise empty {}
|
|
63
64
|
will be used
|
|
65
|
+
@param self used to pass 'this' context in
|
|
64
66
|
*/
|
|
65
|
-
VContext.create = function (args, inParams, locals) {
|
|
67
|
+
VContext.create = function (args, inParams, locals, self) {
|
|
66
68
|
var initValues = {};
|
|
69
|
+
if (self) initValues['this'] = self;
|
|
67
70
|
if (locals) Object.keys(locals).forEach(function (k) { initValues[k] = locals[k]; }); // copy over keys
|
|
68
71
|
var vContext = new VContext();
|
|
69
72
|
vContext.values = args.reduce(function (vcon, x, idx) { // create vCon start with input args
|
package/lib/when-task.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
When task which checks if is a promise (has a then method)
|
|
5
|
+
and waits for it to resolve.
|
|
6
|
+
|
|
7
|
+
If argument does not have a then method, it resolves immediately
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var util = require('util');
|
|
11
|
+
var sprintf = require('sprintf').sprintf;
|
|
12
|
+
|
|
13
|
+
var BaseTask = require('./base-task.js');
|
|
14
|
+
|
|
15
|
+
function format_error(errmsg, obj) {
|
|
16
|
+
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var REQ = 'whenTask requires a, out';
|
|
20
|
+
var A_REQ = 'whenTask requires a to be an array[1] of string param names';
|
|
21
|
+
var OUT_REQ = 'whenTask requires out to be an array[1] of string param names';
|
|
22
|
+
|
|
23
|
+
function WhenTask(taskDef) {
|
|
24
|
+
var self = this;
|
|
25
|
+
Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
WhenTask.prototype = new BaseTask();
|
|
29
|
+
WhenTask.prototype.constructor = WhenTask;
|
|
30
|
+
|
|
31
|
+
WhenTask.prototype.f = function when() { // just here to keep validations happy
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
WhenTask.validate = function (taskDef) {
|
|
35
|
+
var errors = [];
|
|
36
|
+
if (!taskDef.a || !taskDef.out) {
|
|
37
|
+
errors.push(format_error(REQ, taskDef));
|
|
38
|
+
} else {
|
|
39
|
+
if (! (Array.isArray(taskDef.a) && taskDef.a.length === 1 &&
|
|
40
|
+
taskDef.a.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
41
|
+
errors.push(format_error(A_REQ, taskDef));
|
|
42
|
+
}
|
|
43
|
+
if (! (Array.isArray(taskDef.out) && taskDef.out.length <= 1 &&
|
|
44
|
+
taskDef.out.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
45
|
+
errors.push(format_error(OUT_REQ, taskDef));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return errors;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
WhenTask.prototype.prepare = function prepare(handleTaskError, vCon, contExec) {
|
|
52
|
+
var self = this;
|
|
53
|
+
this.nextFn = function (arg) {
|
|
54
|
+
var args = Array.prototype.slice.call(arguments);
|
|
55
|
+
vCon.saveResults(self.out, args);
|
|
56
|
+
self.complete(args);
|
|
57
|
+
contExec();
|
|
58
|
+
};
|
|
59
|
+
this.failFn = function (err) {
|
|
60
|
+
handleTaskError(self, err);
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
WhenTask.prototype.exec = function exec(vCon, handleError, contExec) {
|
|
65
|
+
try {
|
|
66
|
+
var args = this.a.map(function (k) { return vCon.getVar(k); }); //get args from vCon
|
|
67
|
+
//console.error('WhenTask.exec.args=', args);
|
|
68
|
+
//console.error('WhenTask.exec.vCon=', vCon);
|
|
69
|
+
this.start(args); //note the start time, args
|
|
70
|
+
var arg = args[0]; // one value allowed
|
|
71
|
+
if (arg && typeof(arg.then) === 'function') { // is a promise
|
|
72
|
+
arg.then(this.nextFn, this.failFn);
|
|
73
|
+
} else { // not a promise continue immediately
|
|
74
|
+
this.nextFn(arg);
|
|
75
|
+
}
|
|
76
|
+
} catch (err) { //catch and handle the task error, calling final cb
|
|
77
|
+
handleError(this, err);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
module.exports = WhenTask;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react",
|
|
3
|
-
"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.",
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "React is a javascript module implementing a lightweight rules engine 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.",
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"author": "Jeff Barczewski <jeff.barczewski@gmail.com>",
|
|
6
6
|
"repository": { "type": "git", "url": "http://github.com/jeffbski/react.git" },
|
|
7
7
|
"bugs" : { "url": "http://github.com/jeffbski/react/issues" },
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"tap" : "~0.1.0",
|
|
18
|
-
"tapr" : "~0.1.0"
|
|
18
|
+
"tapr" : "~0.1.0",
|
|
19
|
+
"promised-io" : "~0.3.0",
|
|
20
|
+
"Deferred" : "~0.1.1"
|
|
19
21
|
},
|
|
20
22
|
"scripts": {
|
|
21
23
|
"test": "node_modules/.bin/tapr test"
|
package/react.js
CHANGED
|
@@ -2,11 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
var core = require('./lib/core.js');
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
If called, load the built-in plugin for log events and invoke
|
|
7
|
+
|
|
8
|
+
@param flowFn [function] if not provided uses global react
|
|
9
|
+
@param eventWildcard [string] pattern to log events for
|
|
10
|
+
*/
|
|
11
|
+
function logEvents(flowFn, eventWildcard) {
|
|
12
|
+
var logEventsMod = require('./lib/log-events');
|
|
13
|
+
if (!eventWildcard && typeof(flowFn) === 'string') { // only wildcard provided
|
|
14
|
+
eventWildcard = flowFn;
|
|
15
|
+
flowFn = undefined;
|
|
16
|
+
}
|
|
17
|
+
return logEventsMod.logEvents(flowFn, eventWildcard);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
Enable detection of promises and resolution
|
|
22
|
+
*/
|
|
23
|
+
function resolvePromises() {
|
|
24
|
+
require('./lib/promise-resolve');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
Enable tracking of tasks and flow execution, emitting events and
|
|
29
|
+
tracking start, end, elapsed time
|
|
30
|
+
*/
|
|
31
|
+
function trackTasks() {
|
|
32
|
+
require('./lib/track-tasks');
|
|
33
|
+
}
|
|
34
|
+
|
|
5
35
|
module.exports = require('./lib/dsl.js'); // core + default dsl
|
|
6
36
|
module.exports.options = core.options; // global react options
|
|
7
37
|
module.exports.events = core.events; // global react event emitter
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
module.exports.
|
|
11
|
-
module.exports.pcodeDefine = require('./lib/pcode.js');
|
|
12
|
-
module.exports.chainDefine = require('./lib/chain.js');
|
|
38
|
+
module.exports.logEvents = logEvents; // enable event logging
|
|
39
|
+
module.exports.resolvePromises = resolvePromises; // enable promise resolution
|
|
40
|
+
module.exports.trackTasks = trackTasks; // enable tracking of tasks
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Test core PromiseTasks using Deferred - jquery style promises
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var test = require('tap').test;
|
|
9
|
+
var Deferred = require('Deferred');
|
|
10
|
+
//var when = Deferred.when;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var react = require('../'); //require('react');
|
|
14
|
+
|
|
15
|
+
function multiply(x, y) {
|
|
16
|
+
var deferred = new Deferred();
|
|
17
|
+
setTimeout(function () {
|
|
18
|
+
deferred.resolve(x * y);
|
|
19
|
+
}, 10);
|
|
20
|
+
return deferred.promise();
|
|
21
|
+
}
|
|
22
|
+
function add(x, y) {
|
|
23
|
+
var deferred = new Deferred();
|
|
24
|
+
setTimeout(function () {
|
|
25
|
+
deferred.resolve(x + y);
|
|
26
|
+
}, 10);
|
|
27
|
+
return deferred.promise();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function badFunc(a, b) {
|
|
31
|
+
throw new Error('badFuncThrow');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function badF2(a, b) {
|
|
35
|
+
var deferred = new Deferred();
|
|
36
|
+
setTimeout(function () {
|
|
37
|
+
deferred.reject(new Error('my-error'));
|
|
38
|
+
}, 10);
|
|
39
|
+
return deferred.promise();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
test('multi-step', function (t) {
|
|
44
|
+
t.plan(4);
|
|
45
|
+
var fn = react();
|
|
46
|
+
var errors = fn.setAndValidateAST({
|
|
47
|
+
inParams: ['a', 'b'],
|
|
48
|
+
tasks: [
|
|
49
|
+
{ f: multiply, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
50
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
51
|
+
],
|
|
52
|
+
outTask: { a: ['c', 'd'] }
|
|
53
|
+
});
|
|
54
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
55
|
+
|
|
56
|
+
fn(2, 3, function (err, c, d) {
|
|
57
|
+
t.equal(err, null);
|
|
58
|
+
t.equal(c, 6);
|
|
59
|
+
t.equal(d, 9);
|
|
60
|
+
t.end();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('using "this" in a cb function', function (t) {
|
|
65
|
+
t.plan(3);
|
|
66
|
+
function getA(cb) {
|
|
67
|
+
/*jshint validthis: true */
|
|
68
|
+
var deferred = new Deferred();
|
|
69
|
+
var self = this;
|
|
70
|
+
setTimeout(function () {
|
|
71
|
+
deferred.resolve(self.a);
|
|
72
|
+
}, 10);
|
|
73
|
+
return deferred.promise();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var fn = react();
|
|
77
|
+
var errors = fn.setAndValidateAST({
|
|
78
|
+
inParams: [],
|
|
79
|
+
tasks: [
|
|
80
|
+
{ f: getA, a: [], out: ['a'], type: 'promise' }
|
|
81
|
+
],
|
|
82
|
+
outTask: { a: ['a'] }
|
|
83
|
+
});
|
|
84
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
85
|
+
|
|
86
|
+
var obj = {
|
|
87
|
+
a: 100
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
fn.apply(obj, [function (err, a) {
|
|
91
|
+
t.equal(err, null);
|
|
92
|
+
t.equal(a, 100);
|
|
93
|
+
t.end();
|
|
94
|
+
}]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
test('throws error', function (t) {
|
|
99
|
+
t.plan(2);
|
|
100
|
+
var fn = react();
|
|
101
|
+
var errors = fn.setAndValidateAST({
|
|
102
|
+
inParams: ['a', 'b'],
|
|
103
|
+
tasks: [
|
|
104
|
+
{ f: badFunc, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
105
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
106
|
+
],
|
|
107
|
+
outTask: { a: ['c', 'd'] }
|
|
108
|
+
});
|
|
109
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
110
|
+
|
|
111
|
+
fn(2, 3, function (err, c, d) {
|
|
112
|
+
t.equal(err.message, 'badFuncThrow');
|
|
113
|
+
t.end();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('rejects with error', function (t) {
|
|
118
|
+
t.plan(2);
|
|
119
|
+
var fn = react();
|
|
120
|
+
var errors = fn.setAndValidateAST({
|
|
121
|
+
inParams: ['a', 'b'],
|
|
122
|
+
tasks: [
|
|
123
|
+
{ f: badF2, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
124
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
125
|
+
],
|
|
126
|
+
outTask: { a: ['c', 'd'] }
|
|
127
|
+
});
|
|
128
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
129
|
+
|
|
130
|
+
fn(2, 3, function (err, c, d) {
|
|
131
|
+
t.equal(err.message, 'my-error');
|
|
132
|
+
t.end();
|
|
133
|
+
});
|
|
134
|
+
});
|