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/event-manager.js
CHANGED
|
@@ -3,12 +3,30 @@
|
|
|
3
3
|
var EventEmitter2 = require('eventemitter2').EventEmitter2;
|
|
4
4
|
|
|
5
5
|
var EVENT_EMITTER2_CONFIG = {
|
|
6
|
-
wildcard: true
|
|
6
|
+
wildcard: true, // should the event emitter use wildcards.
|
|
7
|
+
delimiter: '.', // the delimiter used to segment namespaces, defaults to `.`.
|
|
8
|
+
maxListeners: 30 // the max number of listeners that can be assigned to an event, defaults to 10.
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
var TYPES = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// Flow monitoring events and their params
|
|
13
|
+
FLOW_BEGIN: 'flow.begin', // env
|
|
14
|
+
TASK_BEGIN: 'task.begin', // task
|
|
15
|
+
TASK_COMPLETE: 'task.complete', // task
|
|
16
|
+
TASK_ERRORED: 'task.errored', // task
|
|
17
|
+
FLOW_COMPLETE: 'flow.complete', // env
|
|
18
|
+
FLOW_ERRORED: 'flow.errored', // env
|
|
19
|
+
|
|
20
|
+
// Internal Hooks
|
|
21
|
+
EXEC_FLOW_START: 'exec.flow.start', // env
|
|
22
|
+
EXEC_INPUT_PREPROCESS: 'exec.input.preprocess', // parsedInput
|
|
23
|
+
EXEC_TASKS_PRECREATE: 'exec.tasks.precreate', // env
|
|
24
|
+
EXEC_OUTTASK_CREATE: 'exec.outTask.create', // outTaskOptions
|
|
25
|
+
EXEC_TASK_START: 'exec.task.start', // task
|
|
26
|
+
EXEC_TASK_COMPLETE: 'exec.task.complete', // task
|
|
27
|
+
EXEC_TASK_ERRORED: 'exec.task.errored', // task
|
|
28
|
+
EXEC_FLOW_COMPLETE: 'exec.flow.complete', // env
|
|
29
|
+
EXEC_FLOW_ERRORED: 'exec.flow.errored' // env
|
|
12
30
|
};
|
|
13
31
|
|
|
14
32
|
/**
|
|
@@ -21,6 +39,9 @@ function EventManager() {
|
|
|
21
39
|
|
|
22
40
|
EventManager.create = function () { return new EventManager(); };
|
|
23
41
|
|
|
42
|
+
EventManager.TYPES = TYPES;
|
|
43
|
+
EventManager.prototype.TYPES = TYPES;
|
|
44
|
+
|
|
24
45
|
EventManager.prototype.isEnabled = function () { // if has listener or an ancestor has listener
|
|
25
46
|
return (this.emitter || (this.parent && this.parent.isEnabled()));
|
|
26
47
|
};
|
|
@@ -36,23 +57,15 @@ EventManager.prototype.on = function (event, listener) {
|
|
|
36
57
|
};
|
|
37
58
|
|
|
38
59
|
EventManager.prototype.emit = function (event, arg1, arg2, argN) {
|
|
60
|
+
if (event === undefined) throw new Error('event is undefined');
|
|
39
61
|
if (this.emitter) this.emitter.emit.apply(this.emitter, arguments);
|
|
40
62
|
if (this.parent && this.parent.isEnabled()) this.parent.emit.apply(this.parent, arguments);
|
|
41
63
|
};
|
|
42
64
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Copies object and adds standard fields:
|
|
46
|
-
event: event type
|
|
47
|
-
time: current time
|
|
48
|
-
*/
|
|
49
|
-
EventManager.prototype.emitObject = function (event, object) {
|
|
50
|
-
var evObj = Object.create(object); // create inherited copy version so origin is untouched
|
|
51
|
-
evObj.event = event; // augment with the event type
|
|
52
|
-
evObj.time = Date.now(); // augument with the time of the event
|
|
53
|
-
this.emit(event, evObj);
|
|
65
|
+
EventManager.prototype.removeListener = function (event, listener) {
|
|
66
|
+
if (this.emitter) this.emitter.removeListener.apply(this.emitter, arguments);
|
|
54
67
|
};
|
|
55
68
|
|
|
69
|
+
|
|
56
70
|
module.exports = EventManager;
|
|
57
|
-
module.exports.
|
|
58
|
-
module.exports.globalEventManager = EventManager.create(); // create one top level emitter
|
|
71
|
+
module.exports.global = EventManager.create(); // create one top level emitter
|
|
@@ -5,15 +5,22 @@ var util = require('util');
|
|
|
5
5
|
|
|
6
6
|
var STATUS = require('./status.js');
|
|
7
7
|
var VContext = require('./vcon.js');
|
|
8
|
+
var EventManager = require('./event-manager.js');
|
|
8
9
|
|
|
9
10
|
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
10
11
|
|
|
11
|
-
function FinalCbFirstSuccTask(
|
|
12
|
+
function FinalCbFirstSuccTask(outTaskOptions) {
|
|
13
|
+
var taskDef = outTaskOptions.taskDef;
|
|
14
|
+
if (typeof(outTaskOptions.cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
12
15
|
var self = this;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.
|
|
16
|
+
for (var k in taskDef) {
|
|
17
|
+
if (true) self[k] = taskDef[k]; // if to make jshint happy
|
|
18
|
+
}
|
|
19
|
+
this.f = outTaskOptions.cbFunc;
|
|
20
|
+
this.tasks = outTaskOptions.tasks;
|
|
21
|
+
this.vCon = outTaskOptions.vCon;
|
|
22
|
+
this.retValue = outTaskOptions.retValue;
|
|
23
|
+
this.env = outTaskOptions.env;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
function format_error(errmsg, obj) {
|
|
@@ -27,11 +34,6 @@ FinalCbFirstSuccTask.validate = function (taskDef) {
|
|
|
27
34
|
errors.push(format_error(OUTTASK_A_REQ, taskDef));
|
|
28
35
|
}
|
|
29
36
|
return errors;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
FinalCbFirstSuccTask.create = function (taskDef, cbFunc, tasks, vCon) {
|
|
33
|
-
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function');
|
|
34
|
-
return new FinalCbFirstSuccTask(taskDef, cbFunc, tasks, vCon);
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
/**
|
|
@@ -46,11 +48,15 @@ FinalCbFirstSuccTask.prototype.isReady = function () {
|
|
|
46
48
|
FinalCbFirstSuccTask.prototype.exec = function (err) {
|
|
47
49
|
if (!this.f) return; //must have already been called
|
|
48
50
|
if (err) {
|
|
51
|
+
this.env.error = err;
|
|
52
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_ERRORED, this.env);
|
|
49
53
|
this.f.call(null, err); //call the final callback with the first error hit
|
|
50
54
|
} else { // no error, call with args
|
|
51
55
|
var vCon = this.vCon;
|
|
52
56
|
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
53
57
|
finalArgs.unshift(null); //unshift err=null to front
|
|
58
|
+
this.env.results = finalArgs;
|
|
59
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_COMPLETE, this.env);
|
|
54
60
|
this.f.apply(null, finalArgs);
|
|
55
61
|
}
|
|
56
62
|
this.f = null; // prevent multiple calls
|
package/lib/finalcb-task.js
CHANGED
|
@@ -4,15 +4,23 @@ var sprintf = require('sprintf').sprintf;
|
|
|
4
4
|
var util = require('util');
|
|
5
5
|
|
|
6
6
|
var STATUS = require('./status.js');
|
|
7
|
+
var EventManager = require('./event-manager.js');
|
|
7
8
|
|
|
8
9
|
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
9
10
|
|
|
10
|
-
function FinalCbTask(
|
|
11
|
+
function FinalCbTask(outTaskOptions) {
|
|
12
|
+
var taskDef = outTaskOptions.taskDef;
|
|
13
|
+
if (typeof(outTaskOptions.cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
11
14
|
var self = this;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.
|
|
15
|
+
for (var k in taskDef) {
|
|
16
|
+
if (true) self[k] = taskDef[k]; // if to make jshint happy
|
|
17
|
+
}
|
|
18
|
+
this.f = outTaskOptions.cbFunc;
|
|
19
|
+
this.tasks = outTaskOptions.tasks;
|
|
20
|
+
this.vCon = outTaskOptions.vCon;
|
|
21
|
+
this.retValue = outTaskOptions.retValue;
|
|
22
|
+
this.execOptions = outTaskOptions.execOptions;
|
|
23
|
+
this.env = outTaskOptions.env;
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
function format_error(errmsg, obj) {
|
|
@@ -29,11 +37,6 @@ FinalCbTask.validate = function (taskDef) {
|
|
|
29
37
|
return errors;
|
|
30
38
|
};
|
|
31
39
|
|
|
32
|
-
FinalCbTask.create = function (taskDef, cbFunc, tasks, vCon) {
|
|
33
|
-
if (!(cbFunc && cbFunc instanceof Function)) throw new Error('callback is not a function');
|
|
34
|
-
return new FinalCbTask(taskDef, cbFunc, tasks, vCon);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
40
|
FinalCbTask.prototype.isReady = function () {
|
|
38
41
|
return (this.tasks.every(function (t) { return (t.status === STATUS.COMPLETE); }));
|
|
39
42
|
};
|
|
@@ -41,11 +44,15 @@ FinalCbTask.prototype.isReady = function () {
|
|
|
41
44
|
FinalCbTask.prototype.exec = function (err) {
|
|
42
45
|
if (!this.f) return; //must have already been called
|
|
43
46
|
if (err) {
|
|
47
|
+
this.env.error = err;
|
|
48
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_ERRORED, this.env);
|
|
44
49
|
this.f.call(null, err); //call the final callback with the first error hit
|
|
45
50
|
} else { // no error, call with args
|
|
46
51
|
var vCon = this.vCon;
|
|
47
52
|
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
48
53
|
finalArgs.unshift(null); //unshift err=null to front
|
|
54
|
+
this.env.results = finalArgs;
|
|
55
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_COMPLETE, this.env);
|
|
49
56
|
this.f.apply(null, finalArgs);
|
|
50
57
|
}
|
|
51
58
|
this.f = null; // prevent multiple calls
|
package/lib/input-parser.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var EventManager = require('./event-manager.js');
|
|
4
|
+
|
|
3
5
|
var defaultExecOptions = {
|
|
4
6
|
reactExecOptions: true,
|
|
5
|
-
outputStyle: '
|
|
7
|
+
outputStyle: 'cb',
|
|
6
8
|
};
|
|
7
9
|
|
|
8
10
|
var OUTPUT_STYLES = {
|
|
9
|
-
CALLBACK: '
|
|
11
|
+
CALLBACK: 'cb',
|
|
10
12
|
NONE: 'none'
|
|
11
13
|
};
|
|
12
14
|
|
|
@@ -36,7 +38,9 @@ function inputParser(inputArgs, ast) {
|
|
|
36
38
|
var splitResult = splitArgs(args, ast.inParams, parsedInput.options.outputStyle);
|
|
37
39
|
parsedInput.args = splitResult.args;
|
|
38
40
|
parsedInput.cb = splitResult.cb;
|
|
39
|
-
if (splitResult.
|
|
41
|
+
if (splitResult.outputStyle) parsedInput.options.outputStyle = splitResult.outputStyle;
|
|
42
|
+
if (splitResult.extra) parsedInput.extraArgs = splitResult.extra;
|
|
43
|
+
EventManager.global.emit(EventManager.TYPES.EXEC_INPUT_PREPROCESS, parsedInput); // hook
|
|
40
44
|
return parsedInput;
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Log events to console.error
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
var react = require('react');
|
|
8
|
+
react.logEvents(); // log all task and flow events on all react functions
|
|
9
|
+
react.logEvents('task.*'); // log all task events on all react functions
|
|
10
|
+
react.logEvents(flowFn); // log all task and flow events on flowFn only
|
|
11
|
+
react.logEvents(flowFn, 'flow.*'); // log all flow events on flowFn only
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
var util = require('util'); // TODO replace inspect with something portable to browser
|
|
15
|
+
|
|
16
|
+
var react = require('../'); // require('react');
|
|
17
|
+
react.trackTasks(); // enable task and flow tracking
|
|
18
|
+
|
|
19
|
+
var ALL_FLOW_EVENTS = 'flow.*';
|
|
20
|
+
var ALL_TASK_EVENTS = 'task.*';
|
|
21
|
+
var FLOW_RE = /^flow\./;
|
|
22
|
+
|
|
23
|
+
function flowLog(obj) {
|
|
24
|
+
/*jshint validthis: true */
|
|
25
|
+
var time = new Date();
|
|
26
|
+
time.setTime(obj.time);
|
|
27
|
+
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
28
|
+
var eventTimeStr = time.toISOString();
|
|
29
|
+
if (this.event === 'flow.complete') {
|
|
30
|
+
var env = obj;
|
|
31
|
+
console.error('%s: %s \tmsecs: %s \n\targs: %s \n\tresults: %s\n',
|
|
32
|
+
this.event, env.name, env.elapsedTime, util.inspect(argsNoCb), util.inspect(env.results));
|
|
33
|
+
} else {
|
|
34
|
+
var name = obj.name;
|
|
35
|
+
var args = obj.args;
|
|
36
|
+
console.error('%s: %s \n\targs: %s\n', this.event, name, util.inspect(argsNoCb));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function taskLog(obj) {
|
|
41
|
+
/*jshint validthis: true */
|
|
42
|
+
var time = new Date();
|
|
43
|
+
time.setTime(obj.time);
|
|
44
|
+
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
45
|
+
var eventTimeStr = time.toISOString();
|
|
46
|
+
if (this.event === 'task.complete') {
|
|
47
|
+
var task = obj;
|
|
48
|
+
console.error('%s: %s \tmsecs: %s \n\targs: %s \n\tresults: %s\n',
|
|
49
|
+
this.event, task.name, task.elapsedTime, util.inspect(argsNoCb), util.inspect(task.results));
|
|
50
|
+
} else {
|
|
51
|
+
var name = obj.name;
|
|
52
|
+
var args = obj.args;
|
|
53
|
+
console.error('%s: %s \n\targs: %s\n', this.event, name, util.inspect(argsNoCb));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
Log flow and task events for a flowFn or all of react.
|
|
60
|
+
If called multiple times, remove previous listener (if any) before
|
|
61
|
+
adding.
|
|
62
|
+
|
|
63
|
+
@example
|
|
64
|
+
var react = require('react');
|
|
65
|
+
react.logEvents(flowFn, eventWildcard); //log events on flowfn matching wildcard
|
|
66
|
+
|
|
67
|
+
@param flowFn Flow function or global react object
|
|
68
|
+
@param eventWildcard wildcarded event type, if not provided use flow.* and task.*
|
|
69
|
+
*/
|
|
70
|
+
function logEvents(flowFn, eventWildcard) {
|
|
71
|
+
if (!flowFn) flowFn = react; // use global
|
|
72
|
+
if (eventWildcard && eventWildcard !== '*') {
|
|
73
|
+
var logFn = (FLOW_RE.test(eventWildcard)) ? flowLog : taskLog;
|
|
74
|
+
flowFn.events.removeListener(eventWildcard, logFn);
|
|
75
|
+
flowFn.events.on(eventWildcard, logFn);
|
|
76
|
+
} else { // none provided, use flow.* and task.*
|
|
77
|
+
//output events as tasks start and complete
|
|
78
|
+
flowFn.events.removeListener(ALL_FLOW_EVENTS, flowLog);
|
|
79
|
+
flowFn.events.on(ALL_FLOW_EVENTS, flowLog);
|
|
80
|
+
flowFn.events.removeListener(ALL_TASK_EVENTS, taskLog);
|
|
81
|
+
flowFn.events.on(ALL_TASK_EVENTS, taskLog);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = react;
|
|
86
|
+
module.exports.logEvents = logEvents;
|
package/lib/parse.js
CHANGED
|
@@ -9,10 +9,13 @@ function splitTrimFilterArgs(commaSepArgs) { //parse 'one, two' into ['one', 'tw
|
|
|
9
9
|
.filter(function (s) { return (s); }); //filter out empty strings
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
@param patternFn regex + fn or splitStr + fn
|
|
14
|
+
*/
|
|
15
|
+
function parseReduce(accum, patternFn) {
|
|
13
16
|
if (typeof(accum) !== 'string') return accum; // already matched
|
|
14
|
-
var m =
|
|
15
|
-
if (m) return
|
|
17
|
+
var m = (patternFn.regex) ? patternFn.regex.exec(accum) : accum.split(patternFn.splitStr);
|
|
18
|
+
if (m) return patternFn.fn(m, accum); // pass in matches and origStr, return result obj
|
|
16
19
|
return accum; // no match, return str, will try next matcher
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Auto resolve promises passed in as arguments to the flow
|
|
5
|
+
|
|
6
|
+
- Detects promises by checking for .then()
|
|
7
|
+
- Create promise name for param (param__promise)
|
|
8
|
+
- moves existing vCon promise into the param__promise
|
|
9
|
+
- creates WhenTask which resolves param__promise into param
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var react = require('../'); // require('react');
|
|
14
|
+
|
|
15
|
+
var PROMISE_SUFFIX = '__promise'; // added to param names that are promises
|
|
16
|
+
|
|
17
|
+
react.events.on(react.events.TYPES.EXEC_TASKS_PRECREATE, function (env) {
|
|
18
|
+
var vConValues = env.vCon.values;
|
|
19
|
+
var promiseParams = env.ast.inParams.filter(function (p) {
|
|
20
|
+
var value = vConValues[p];
|
|
21
|
+
return (value && typeof(value.then) === 'function');
|
|
22
|
+
});
|
|
23
|
+
promiseParams.forEach(function (p) {
|
|
24
|
+
var promiseName = p + PROMISE_SUFFIX;
|
|
25
|
+
vConValues[promiseName] = vConValues[p];
|
|
26
|
+
vConValues[p] = undefined;
|
|
27
|
+
env.taskDefs.push({
|
|
28
|
+
type: 'when',
|
|
29
|
+
a: [promiseName],
|
|
30
|
+
out: [p]
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
module.exports = react; // return react
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
PromiseTask is a task which executes a fn that returns a promise
|
|
5
|
+
and when it completes it sets the values in vCon
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var util = require('util');
|
|
9
|
+
var sprintf = require('sprintf').sprintf;
|
|
10
|
+
|
|
11
|
+
var BaseTask = require('./base-task.js');
|
|
12
|
+
|
|
13
|
+
function format_error(errmsg, obj) {
|
|
14
|
+
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var REQ = 'promiseTask requires f, a, out';
|
|
18
|
+
var FN_REQ = 'promiseTask requires f to be a function or string';
|
|
19
|
+
var A_REQ = 'promiseTask requires a to be an array of string param names';
|
|
20
|
+
var OUT_REQ = 'promiseTask requires out to be an array[1] of string param names';
|
|
21
|
+
|
|
22
|
+
function PromiseTask(taskDef) {
|
|
23
|
+
var self = this;
|
|
24
|
+
Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
PromiseTask.prototype = new BaseTask();
|
|
28
|
+
PromiseTask.prototype.constructor = PromiseTask;
|
|
29
|
+
|
|
30
|
+
PromiseTask.validate = function (taskDef) {
|
|
31
|
+
var errors = [];
|
|
32
|
+
if (!taskDef.f || !taskDef.a || !taskDef.out) {
|
|
33
|
+
errors.push(format_error(REQ, taskDef));
|
|
34
|
+
} else {
|
|
35
|
+
var ftype = typeof(taskDef.f);
|
|
36
|
+
if (! ((taskDef.f instanceof Function) || (ftype === 'string'))) {
|
|
37
|
+
errors.push(format_error(FN_REQ, taskDef));
|
|
38
|
+
}
|
|
39
|
+
if (! (Array.isArray(taskDef.a) &&
|
|
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
|
+
PromiseTask.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
|
+
PromiseTask.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('PromiseTask.exec.args=', args);
|
|
68
|
+
//console.error('PromiseTask.exec.vCon=', vCon);
|
|
69
|
+
this.start(args); //note the start time, args
|
|
70
|
+
var func = this.f;
|
|
71
|
+
var bindObj = vCon.getVar('this'); //global space or the original this
|
|
72
|
+
if (this.isMethodCall()) { //if method call then reset func and bindObj
|
|
73
|
+
func = vCon.getVar(this.f);
|
|
74
|
+
bindObj = this.getMethodObj(vCon);
|
|
75
|
+
} else if (typeof(func) === 'string') {
|
|
76
|
+
func = vCon.getVar(func); // we want the actual fn from this string
|
|
77
|
+
}
|
|
78
|
+
var retValue = func.apply(bindObj, args);
|
|
79
|
+
if (retValue && typeof(retValue.then) === 'function') { // is a promise
|
|
80
|
+
retValue.then(this.nextFn, this.failFn);
|
|
81
|
+
} else { // just a value, proceed now
|
|
82
|
+
this.nextFn(retValue);
|
|
83
|
+
}
|
|
84
|
+
} catch (err) { //catch and handle the task error, calling final cb
|
|
85
|
+
handleError(this, err);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
module.exports = PromiseTask;
|
package/lib/ret-task.js
CHANGED
|
@@ -50,7 +50,7 @@ RetTask.prototype.exec = function exec(vCon, handleError, contExec) {
|
|
|
50
50
|
var args = this.a.map(function (k) { return vCon.getVar(k); }); //get args from vCon
|
|
51
51
|
this.start(args); //note the start time, args
|
|
52
52
|
var func = this.f;
|
|
53
|
-
var bindObj =
|
|
53
|
+
var bindObj = vCon.getVar('this'); //global space or the original this
|
|
54
54
|
if (this.isMethodCall()) { //if method call then reset func and bindObj
|
|
55
55
|
func = vCon.getVar(this.f);
|
|
56
56
|
bindObj = this.getMethodObj(vCon);
|