react 0.2.6 → 0.3.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.
Files changed (61) hide show
  1. package/README.md +8 -7
  2. package/{lib → dsl}/chain.js +5 -3
  3. package/{lib → dsl}/fstr.js +7 -5
  4. package/{lib → dsl}/pcode.js +8 -6
  5. package/examples/chain-events1.js +3 -3
  6. package/examples/chain1.js +2 -2
  7. package/examples/default-events1.js +2 -2
  8. package/examples/fstr-events1.js +4 -3
  9. package/examples/fstr1.js +3 -2
  10. package/examples/pcode1.js +2 -2
  11. package/lib/base-task.js +1 -0
  12. package/lib/cb-task.js +14 -1
  13. package/lib/core.js +33 -9
  14. package/lib/dsl.js +14 -6
  15. package/lib/event-manager.js +16 -5
  16. package/lib/finalcb-first-task.js +9 -6
  17. package/lib/finalcb-task.js +9 -6
  18. package/lib/input-parser.js +7 -3
  19. package/lib/parse.js +6 -3
  20. package/lib/promise-task.js +89 -0
  21. package/lib/ret-task.js +1 -1
  22. package/lib/task.js +23 -19
  23. package/lib/validate.js +3 -3
  24. package/lib/vcon.js +6 -3
  25. package/lib/when-task.js +81 -0
  26. package/package.json +4 -2
  27. package/promise-resolve.js +35 -0
  28. package/react.js +0 -4
  29. package/test/core-deferred.test.js +134 -0
  30. package/test/core-promised.test.js +132 -0
  31. package/test/core-when.test.js +84 -0
  32. package/test/core.test.js +63 -4
  33. package/test/dsl.test.js +58 -6
  34. package/test/{chain.test.js → dsl/chain.test.js} +71 -1
  35. package/test/{fstr.test.js → dsl/fstr.test.js} +1 -1
  36. package/test/{pcode.test.js → dsl/pcode.test.js} +122 -1
  37. package/test/exec-options.test.js +2 -1
  38. package/test/finalcb-task.test.js +6 -5
  39. package/test/input-parser.test.js +10 -6
  40. package/test/module-use.test.js +2 -190
  41. package/test/promise-auto-resolve.test.js +51 -0
  42. package/test/validate.test.js +4 -2
  43. package/test/vcon.test.js +13 -0
  44. package/oldExamples/analyze.js +0 -29
  45. package/oldExamples/analyze2.js +0 -29
  46. package/oldExamples/example10-dsl.js +0 -63
  47. package/oldExamples/example11.js +0 -62
  48. package/oldExamples/example12.js +0 -63
  49. package/oldExamples/example13.js +0 -63
  50. package/oldExamples/example14.js +0 -63
  51. package/oldExamples/example15.js +0 -75
  52. package/oldExamples/example6-ast.js +0 -47
  53. package/oldExamples/example6-dsl.js +0 -49
  54. package/oldExamples/example8-ast.js +0 -55
  55. package/oldExamples/example8-dsl.js +0 -53
  56. package/oldExamples/example9-ast.js +0 -58
  57. package/oldExamples/example9-dsl.js +0 -57
  58. package/oldExamples/function-str-ex1.js +0 -33
  59. package/oldExamples/function-str-ex2.js +0 -67
  60. package/oldExamples/trait1.js +0 -41
  61. package/oldExamples/trait2.js +0 -44
package/README.md CHANGED
@@ -40,7 +40,7 @@ It takes inspiration from several projects including:
40
40
  - object instance method calls
41
41
  - class method calls
42
42
  - selectFirst flow where the first task that returns defined, non-null value is used
43
- - (planned) promise style functions - also automatic resolution of promise inputs
43
+ - promise style functions - also automatic resolution of promise inputs (optional require('react/promise-resolve');)
44
44
  - (planned) use of resulting flow function as callback style or promise style (if no callback provided)
45
45
  - (planned) iteration on arrays, streams, sockets
46
46
  - (planned) event emitter integration
@@ -157,7 +157,7 @@ fn('foo', 'pre-', '-post', function cb(err, lres) {
157
157
  ### Example using Function String DSL interface
158
158
 
159
159
  ```javascript
160
- var react = require('react');
160
+ var fstrDefine = require('react/dsl/fstr');
161
161
 
162
162
  function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
163
163
  function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
@@ -176,7 +176,7 @@ function useHtml(err, html, user, bytesWritten) {
176
176
  console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
177
177
  }
178
178
 
179
- var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
179
+ var loadAndSave = fstrDefine('filename, uid, outDirname, cb', [ // input params
180
180
  loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
181
181
  loadFile, 'filename -> err, filedata',
182
182
  markdown, 'filedata -> returns html', // using a sync function
@@ -195,7 +195,7 @@ loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
195
195
  ### Example using pseudocode DSL interface
196
196
 
197
197
  ```javascript
198
- var react = require('react');
198
+ var pcodeDefine = require('react/dsl/pcode');
199
199
 
200
200
  function multiply(a, b, cb) { cb(null, a * b); }
201
201
  function add(a, b) { return a + b; }
@@ -204,7 +204,7 @@ var locals = { // since pcodeDefine uses strings, need references to functions
204
204
  add: add
205
205
  };
206
206
 
207
- var fn = react.pcodeDefine('a, b, cb', [ // input params
207
+ var fn = pcodeDefine('a, b, cb', [ // input params
208
208
  'm := multiply(a, b)', // using a callback function, use :=
209
209
  's = add(m, a)', // using a sync function, use =
210
210
  'cb(err, m, s)' // output params for final callback
@@ -221,12 +221,12 @@ fn(2, 3, function (err, m, s) {
221
221
  ### Example using jquery-like chaining DSL interface
222
222
 
223
223
  ```javascript
224
- var react = require('react');
224
+ var chainDefine = require('react/dsl/chain');
225
225
 
226
226
  function multiply(a, b, cb) { cb(null, a * b); }
227
227
  function add(a, b) { return a + b; }
228
228
 
229
- var fn = react.chainDefine()
229
+ var fn = chainDefine()
230
230
  .in('a', 'b', 'cb') // input params
231
231
  .out('err', 'm', 's') // final callback output params
232
232
  .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
@@ -242,6 +242,7 @@ fn(2, 3, function (err, m, s) {
242
242
 
243
243
  ## Status
244
244
 
245
+ - 2012-01-13 - Add promise tasks, promise resolution, refactor alternate DSL interfaces as optional requires (v0.3.0)
245
246
  - 2012-01-11 - Provide warning/error when name is skipped in default DSL, literal check in validate (v0.2.5)
246
247
  - 2012-01-10 - Create default DSL for react(), create error for missing variables, list remaining tasks when flow won't complete
247
248
  - 2011-12-21 - Refactor from ground up with tests, changes to the interfaces
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var sprintf = require('sprintf').sprintf;
4
- var core = require('./core.js');
5
- var tutil = require('./task.js');
4
+ var core = require('../lib/core.js');
5
+ var tutil = require('../lib/task.js');
6
6
 
7
7
  // err for task type cb is implied and thus optional, but allow for clarity.
8
8
  var ERROR_NAMES_RE = /^err$/i; // first out param matching this is skipped as being the err object
@@ -145,4 +145,6 @@ FlowBuilder.prototype.end = function end() {
145
145
  return reactFn;
146
146
  };
147
147
 
148
- module.exports = chainDefine;
148
+ module.exports = chainDefine;
149
+ module.exports.options = core.options;
150
+ module.exports.events = core.events;
@@ -2,9 +2,9 @@
2
2
  /*jshint regexp: false */
3
3
 
4
4
  var sprintf = require('sprintf').sprintf;
5
- var core = require('./core.js');
6
- var parse = require('./parse.js');
7
- var tutil = require('./task.js');
5
+ var core = require('../lib/core.js');
6
+ var parse = require('../lib/parse.js');
7
+ var tutil = require('../lib/task.js');
8
8
 
9
9
  var INPARAMS_NO_MATCH = 'input params in wrong format, wanted "foo, bar" - found: %s';
10
10
  var OUTPARAMS_NO_MATCH = 'output params in wrong format, wanted "foo, bar" - found: %s';
@@ -20,7 +20,7 @@ function filterOutLeadingErrParam(args) { // if leading err param, filter it out
20
20
 
21
21
 
22
22
  var inOutDefParse = {
23
- regex: /^([^\-]*)(->)?\s*(returns?\s+)?(.*)$/i,
23
+ regex: /^([^\-]*)(->)?\s*(returns?\s+)?(.*)$/i, //TODO this will not work if literal has dash
24
24
  fn: function (m) {
25
25
  var reMatchReturns = /returns?/i;
26
26
  return {
@@ -116,4 +116,6 @@ function selectFirst(inParamStr, taskDefArr, outParamStr, options) {
116
116
  }
117
117
 
118
118
  module.exports = fstrDefine;
119
- module.exports.selectFirst = selectFirst;
119
+ module.exports.selectFirst = selectFirst;
120
+ module.exports.options = core.options;
121
+ module.exports.events = core.events;
@@ -2,9 +2,9 @@
2
2
  /*jshint regexp: false */
3
3
 
4
4
  var sprintf = require('sprintf').sprintf;
5
- var core = require('./core.js');
6
- var parse = require('./parse.js');
7
- var tutil = require('./task.js');
5
+ var core = require('../lib/core.js');
6
+ var parse = require('../lib/parse.js');
7
+ var tutil = require('../lib/task.js');
8
8
 
9
9
  var INPARAMS_NO_MATCH = 'input params in wrong format, wanted "foo, bar, cb" - found: %s';
10
10
  var OUTPARAMS_NO_MATCH = 'output params in wrong format, wanted "cb(err, foo)" - found: %s';
@@ -63,7 +63,7 @@ var inParse = {
63
63
  };
64
64
 
65
65
  var cbParse = {
66
- regex: /^\s*(var\s+)?([^:]*)\s*:=\s*([a-zA-Z0-9_\.-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
66
+ regex: /^\s*(var\s+)?([^:]*)\s*:=\s*([a-zA-Z0-9_\.\-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
67
67
  fn: function (m) {
68
68
  var taskDef = {
69
69
  type: 'cb',
@@ -77,7 +77,7 @@ var cbParse = {
77
77
  };
78
78
 
79
79
  var retParse = {
80
- regex: /^\s*(var\s+)?([^:]*)\s*=\s*([a-zA-Z0-9_\.-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
80
+ regex: /^\s*(var\s+)?([^:]*)\s*=\s*([a-zA-Z0-9_\.\-]+)\s*\(\s*([^)]*)\)\s*(when\s+([^;]+))?;?\s*$/,
81
81
  fn: function (m) {
82
82
  var taskDef = {
83
83
  type: 'ret',
@@ -170,4 +170,6 @@ function selectFirst(inParamStr, taskStrArr, locals, options) {
170
170
  }
171
171
 
172
172
  module.exports = pcodeDefine;
173
- module.exports.selectFirst = selectFirst;
173
+ module.exports.selectFirst = selectFirst;
174
+ module.exports.options = core.options;
175
+ module.exports.events = core.events;
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var react = require('../'); // require('react');
3
+ var chainDefine = require('../dsl/chain'); // require('react/dsl/chain');
4
4
 
5
5
  //output events as tasks start and complete
6
- react.events.on('*', function (obj) {
6
+ chainDefine.events.on('task.*', function (obj) {
7
7
  var time = new Date();
8
8
  time.setTime(obj.time);
9
9
  var eventTimeStr = time.toISOString();
@@ -20,7 +20,7 @@ react.events.on('*', function (obj) {
20
20
  function multiply(a, b, cb) { cb(null, a * b); }
21
21
  function add(a, b) { return a + b; }
22
22
 
23
- var fn = react.chainDefine()
23
+ var fn = chainDefine()
24
24
  .in('a', 'b', 'cb') // input params
25
25
  .out('err', 'm', 's') // final callback output params
26
26
  .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var react = require('../'); // require('react');
3
+ var chainDefine = require('../dsl/chain'); // require('react/dsl/chain');
4
4
 
5
5
  function multiply(a, b, cb) { cb(null, a * b); }
6
6
  function add(a, b) { return a + b; }
7
7
 
8
- var fn = react.chainDefine()
8
+ var fn = chainDefine()
9
9
  .in('a', 'b', 'cb') // input params
10
10
  .out('err', 'm', 's') // final callback output params
11
11
  .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
@@ -4,7 +4,7 @@
4
4
  var react = require('../'); // require('react');
5
5
 
6
6
  //output events as tasks start and complete
7
- react.events.on('*', function (obj) {
7
+ react.events.on('task.*', function (obj) {
8
8
  var time = new Date();
9
9
  time.setTime(obj.time);
10
10
  var eventTimeStr = time.toISOString();
@@ -43,7 +43,7 @@ var loadAndSave = react('loadAndSave', 'filename, uid, outDirname, cb -> err, ht
43
43
  writeOutput, 'html, user, cb -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
44
44
  loadEmailTemplate, 'cb -> err, emailmd',
45
45
  markdown, 'emailmd -> emailHtml', // using a sync function
46
- customizeEmail, 'user, emailHtml -> err, custEmailHtml', // sync fn
46
+ customizeEmail, 'user, emailHtml -> custEmailHtml', // sync fn
47
47
  deliverEmail, 'custEmailHtml, cb -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
48
48
  );
49
49
 
@@ -1,9 +1,10 @@
1
1
  'use strict';
2
+ /*jshint white: false */
2
3
 
3
- var react = require('../'); // require('react');
4
+ var fstr = require('../dsl/fstr'); // require('react/dsl/fstr');
4
5
 
5
6
  //output events as tasks start and complete
6
- react.events.on('*', function (obj) {
7
+ fstr.events.on('task.*', function (obj) {
7
8
  var time = new Date();
8
9
  time.setTime(obj.time);
9
10
  var eventTimeStr = time.toISOString();
@@ -34,7 +35,7 @@ function useHtml(err, html, user, bytesWritten) {
34
35
  console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
35
36
  }
36
37
 
37
- var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
38
+ var loadAndSave = fstr('filename, uid, outDirname, cb', [ // input params
38
39
  loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
39
40
  loadFile, 'filename -> err, filedata',
40
41
  markdown, 'filedata -> returns html', // using a sync function
package/examples/fstr1.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
+ /*jshint white: false */
2
3
 
3
- var react = require('../'); // require('react');
4
+ var fstr = require('../dsl/fstr'); // require('react/dsl/fstr');
4
5
 
5
6
  function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
6
7
  function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
@@ -19,7 +20,7 @@ function useHtml(err, html, user, bytesWritten) {
19
20
  console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
20
21
  }
21
22
 
22
- var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
23
+ var loadAndSave = fstr('filename, uid, outDirname, cb', [ // input params
23
24
  loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
24
25
  loadFile, 'filename -> err, filedata',
25
26
  markdown, 'filedata -> returns html', // using a sync function
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var react = require('../'); // require('react');
3
+ var pcodeDefine = require('../dsl/pcode'); // require('react/dsl/pcode');
4
4
 
5
5
  function multiply(a, b, cb) { cb(null, a * b); }
6
6
  function add(a, b) { return a + b; }
@@ -9,7 +9,7 @@ var locals = { // since pcodeDefine uses strings, need references to functions
9
9
  add: add
10
10
  };
11
11
 
12
- var fn = react.pcodeDefine('a, b, cb', [ // input params
12
+ var fn = pcodeDefine('a, b, cb', [ // input params
13
13
  'm := multiply(a, b)', // using a callback function, use :=
14
14
  's = add(m, a)', // using a sync function, use =
15
15
  'cb(err, m, s)' // output params for final callback
package/lib/base-task.js CHANGED
@@ -96,6 +96,7 @@ BaseTask.prototype.isReady = function (vCon, tasksByName) {
96
96
  };
97
97
 
98
98
  BaseTask.prototype.isMethodCall = function () {
99
+ /*jshint regexp: false */
99
100
  return (typeof(this.f) === 'string' && /^.*\..*$/.test(this.f)); //str contains .
100
101
  };
101
102
 
package/lib/cb-task.js CHANGED
@@ -43,6 +43,19 @@ CbTask.validate = function (taskDef) {
43
43
  return errors;
44
44
  };
45
45
 
46
+ CbTask.prototype.prepare = function prepare(handleTaskError, vCon, contExec) {
47
+ var self = this;
48
+ this.cbFun = function (err, arg0, arg1, argn) {
49
+ var args = Array.prototype.slice.call(arguments, 1);
50
+ if (err) { handleTaskError(self, err); return; } //handle error and return, we are done
51
+
52
+ //no error, save callback args to vCon context, then continue execution
53
+ vCon.saveResults(self.out, args);
54
+ self.complete(args);
55
+ contExec();
56
+ };
57
+ };
58
+
46
59
  CbTask.prototype.exec = function exec(vCon, handleError, contExec) {
47
60
  try {
48
61
  var args = this.a.map(function (k) { return vCon.getVar(k); }); //get args from vCon
@@ -51,7 +64,7 @@ CbTask.prototype.exec = function exec(vCon, handleError, contExec) {
51
64
  this.start(args); //note the start time, args
52
65
  args.push(this.cbFun); // push callback fn on end
53
66
  var func = this.f;
54
- var bindObj = null; //global space
67
+ var bindObj = vCon.getVar('this'); //global space or the original this
55
68
  if (this.isMethodCall()) { //if method call then reset func and bindObj
56
69
  func = vCon.getVar(this.f);
57
70
  bindObj = this.getMethodObj(vCon);
package/lib/core.js CHANGED
@@ -7,7 +7,6 @@ var validate = require('./validate.js');
7
7
  var tskutil = require('./task.js');
8
8
  var STATUS = require('./status.js');
9
9
  var VContext = require('./vcon.js');
10
- var FinalCbTask = require('./finalcb-task.js');
11
10
  var EventManager = require('./event-manager.js');
12
11
  var inputParser = require('./input-parser.js');
13
12
  var idGenerator = require('./id.js');
@@ -16,7 +15,17 @@ var reactOptions = {
16
15
  stackTraceLimitMin: 30
17
16
  };
18
17
 
19
- var reactEmitter = EventManager.globalEventManager; // the top emitter
18
+ var reactEmitter = EventManager.global; // the top emitter
19
+
20
+ /**
21
+ merge global react options with parsed options
22
+ */
23
+ function mergeOptions(parsedOptions) {
24
+ return Object.keys(reactOptions).reduce(function (accum, k) {
25
+ if (!accum[k]) accum[k] = reactOptions[k];
26
+ return accum;
27
+ }, parsedOptions);
28
+ }
20
29
 
21
30
  /**
22
31
  Creates react function which the AST can be manipulated and then
@@ -56,18 +65,32 @@ function reactFactory() {
56
65
  Object.keys(newAST).forEach(function (k) { ast[k] = newAST[k]; }); // copy all properties
57
66
  var errors = validate(ast);
58
67
  if (!errors.length) tskutil.nameTasks(ast.tasks); //run this so names can be checked in ast
68
+ if (Object.freeze) { //lets freeze the AST so plugin writers don't accidentally manip the ast
69
+ Object.keys(newAST).forEach(function (k) {
70
+ if (typeof(newAST[k]) === 'object') Object.freeze(newAST[k]);
71
+ });
72
+ Object.freeze(newAST);
73
+ }
59
74
  return errors;
60
75
  }
61
76
 
62
77
  function exec(arg1, arg2, argN, cb) { // called to execute the flow
78
+ /*jshint validthis: true */
63
79
  var parsedInput = inputParser(Array.prototype.slice.call(arguments), ast);
64
- var args = parsedInput.args;
65
- var cbFinal = parsedInput.cb;
66
- var extraArgs = parsedInput.extraArgs; // we'll have these if we need them
67
- var vCon = VContext.create(args, ast.inParams, ast.locals); // create var ctx with in args & locals
68
- var tasks = ast.tasks.map(tskutil.create);
80
+ var vCon = VContext.create(parsedInput.args, ast.inParams, ast.locals, this); // create var ctx with in args & locals
81
+
82
+ var taskEnv = { // collect taskEnv for hook
83
+ parsedInput: parsedInput,
84
+ vCon: vCon,
85
+ ast: ast, // for reference, will not be used further
86
+ taskDefs: ast.tasks.slice(), // create copy
87
+ outTaskDef: ast.outTask
88
+ };
89
+ reactEmitter.emit(EventManager.TYPES.EXEC_TASKS_PRECREATE, taskEnv); // hook
90
+
91
+ var tasks = taskEnv.taskDefs.map(tskutil.create);
69
92
  var tasksByName = tskutil.nameTasks(tasks); // map names to working tasks
70
- var outTask = tskutil.createOutTask(ast.outTask, cbFinal, tasks, vCon);
93
+ var outTask = tskutil.createOutTask(taskEnv.outTaskDef, parsedInput.cb, tasks, vCon, mergeOptions(parsedInput.options));
71
94
  var handleError = tskutil.createErrorHandler(vCon, outTask);
72
95
 
73
96
  function contExec() {
@@ -79,9 +102,10 @@ function reactFactory() {
79
102
  tasks.forEach(function (t) {
80
103
  t.id = idGenerator.createUniqueId();
81
104
  t.flowEmitter = flowEmitter;
82
- if (t.type === 'cb') t.cbFun = tskutil.createCallback(t, handleError, vCon, contExec, flowEmitter);
105
+ if (t.prepare) t.prepare(handleError, vCon, contExec, flowEmitter);
83
106
  }); // create callbacks
84
107
  contExec(); // start things off
108
+ return outTask.retValue; // could return promise
85
109
  }
86
110
 
87
111
  var reactFn = exec; // make the exec() the function returned
package/lib/dsl.js CHANGED
@@ -6,8 +6,10 @@ var core = require('./core.js');
6
6
  var parse = require('./parse.js');
7
7
  var tutil = require('./task.js');
8
8
 
9
- var MISSING_NAME = 'param[0] should be the flow name, instead found in/out def: %s';
10
- var INOUT_PARAMS_NO_MATCH = 'params in wrong format, wanted "foo, bar cb -> err, baz" - found: %s';
9
+ var MISSING_NAME = 'first flow parameter should be the flow name, but found in/out def: %s';
10
+ var INOUT_PARAMS_NO_MATCH = 'params in wrong format, wanted "foo, bar, cb -> err, baz" - found: %s';
11
+ var MISSING_ERR = 'callback specified, but first out param was not "err", use for clarity. Found in/out def: %s';
12
+ 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';
11
13
  var EXTRA_TASKARG = 'extra unmatched task arg: %s';
12
14
 
13
15
  var INOUT_RE = /\->/; // used to detect missing name, in/out as first arg
@@ -25,12 +27,18 @@ function filterOutLeadingErrParam(args) { // if leading err param, filter it out
25
27
  }
26
28
 
27
29
  var inOutDefParse = {
28
- regex: /^([^\-]*)(->\s*(.*))?$/i,
29
- fn: function (m) {
30
- var inParams = parse.splitTrimFilterArgs(m[1]);
30
+ splitStr: '->',
31
+ fn: function (m, origStr) {
32
+ var inParams = parse.splitTrimFilterArgs(m[0]);
31
33
  var lastParam = inParams[inParams.length - 1];
32
34
  var type = (lastParam && CB_NAMES_RE.test(lastParam)) ? 'cb' : 'ret';
33
- var outParams = parse.splitTrimFilterArgs(m[3]);
35
+ var outParams = parse.splitTrimFilterArgs(m[1]);
36
+ var firstOutParam = outParams[0];
37
+ if (type === 'cb' && (!firstOutParam || !ERR_NAMES_RE.test(firstOutParam))) {
38
+ throw new Error(sprintf(MISSING_ERR, origStr)); // found cb, but no err param
39
+ } else if (type === 'ret' && firstOutParam && ERR_NAMES_RE.test(firstOutParam)) {
40
+ throw new Error(sprintf(MISSING_CB, origStr)); // found err but not cb param
41
+ }
34
42
  return {
35
43
  type: type,
36
44
  inDef: filterOutTrailingCbParam(inParams),
@@ -3,12 +3,20 @@
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
- TASK_BEGIN: 'task.begin',
11
- TASK_COMPLETE: 'task.complete'
12
+ // Flow monitoring events and their params
13
+ TASK_BEGIN: 'task.begin', // task
14
+ TASK_COMPLETE: 'task.complete', // task
15
+
16
+ // Internal Hooks
17
+ EXEC_INPUT_PREPROCESS: 'exec.input.preprocess', // parsedInput
18
+ EXEC_TASKS_PRECREATE: 'exec.tasks.precreate', // taskEnv
19
+ EXEC_OUTTASK_CREATE: 'exec.outTask.create' // outTaskOptions
12
20
  };
13
21
 
14
22
  /**
@@ -21,6 +29,9 @@ function EventManager() {
21
29
 
22
30
  EventManager.create = function () { return new EventManager(); };
23
31
 
32
+ EventManager.TYPES = TYPES;
33
+ EventManager.prototype.TYPES = TYPES;
34
+
24
35
  EventManager.prototype.isEnabled = function () { // if has listener or an ancestor has listener
25
36
  return (this.emitter || (this.parent && this.parent.isEnabled()));
26
37
  };
@@ -36,6 +47,7 @@ EventManager.prototype.on = function (event, listener) {
36
47
  };
37
48
 
38
49
  EventManager.prototype.emit = function (event, arg1, arg2, argN) {
50
+ if (event === undefined) throw new Error('event is undefined');
39
51
  if (this.emitter) this.emitter.emit.apply(this.emitter, arguments);
40
52
  if (this.parent && this.parent.isEnabled()) this.parent.emit.apply(this.parent, arguments);
41
53
  };
@@ -54,5 +66,4 @@ EventManager.prototype.emitObject = function (event, object) {
54
66
  };
55
67
 
56
68
  module.exports = EventManager;
57
- module.exports.TYPES = TYPES;
58
- module.exports.globalEventManager = EventManager.create(); // create one top level emitter
69
+ module.exports.global = EventManager.create(); // create one top level emitter