react 0.0.2 → 0.2.1

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 (70) hide show
  1. package/.npmignore +6 -0
  2. package/Jakefile.js +8 -0
  3. package/README.md +226 -86
  4. package/examples/ast1.js +26 -0
  5. package/examples/chain-events1.js +34 -0
  6. package/examples/chain1.js +19 -0
  7. package/examples/default-events1.js +52 -0
  8. package/examples/default1.js +40 -0
  9. package/examples/fstr-events1.js +51 -0
  10. package/examples/fstr1.js +36 -0
  11. package/examples/pcode1.js +22 -0
  12. package/jake-tasks/jake-test.js +64 -0
  13. package/lib/base-task.js +115 -0
  14. package/lib/cb-task.js +67 -0
  15. package/lib/chain.js +148 -0
  16. package/lib/core.js +96 -0
  17. package/lib/dsl.js +122 -0
  18. package/lib/error.js +37 -0
  19. package/lib/event-manager.js +57 -0
  20. package/lib/finalcb-first-task.js +59 -0
  21. package/lib/finalcb-task.js +54 -0
  22. package/lib/fstr.js +110 -0
  23. package/lib/id.js +10 -0
  24. package/lib/input-parser.js +44 -0
  25. package/lib/parse.js +29 -0
  26. package/lib/pcode.js +164 -0
  27. package/lib/ret-task.js +67 -0
  28. package/lib/status.js +5 -0
  29. package/lib/task.js +234 -0
  30. package/lib/validate.js +102 -0
  31. package/lib/vcon.js +76 -0
  32. package/oldExamples/analyze.js +29 -0
  33. package/oldExamples/analyze2.js +29 -0
  34. package/oldExamples/example10-dsl.js +63 -0
  35. package/oldExamples/example11.js +62 -0
  36. package/oldExamples/example12.js +63 -0
  37. package/oldExamples/example13.js +63 -0
  38. package/oldExamples/example14.js +63 -0
  39. package/oldExamples/example15.js +75 -0
  40. package/{test → oldExamples}/example6-ast.js +4 -4
  41. package/{test → oldExamples}/example6-dsl.js +3 -2
  42. package/{test → oldExamples}/example8-ast.js +3 -2
  43. package/{test → oldExamples}/example8-dsl.js +3 -2
  44. package/{test → oldExamples}/example9-ast.js +3 -2
  45. package/{test → oldExamples}/example9-dsl.js +3 -2
  46. package/oldExamples/function-str-ex1.js +33 -0
  47. package/oldExamples/function-str-ex2.js +67 -0
  48. package/oldExamples/trait1.js +41 -0
  49. package/oldExamples/trait2.js +44 -0
  50. package/package.json +16 -6
  51. package/react.js +11 -1
  52. package/test/ast.test.js +69 -0
  53. package/test/cb-task.test.js +197 -0
  54. package/test/chain.test.js +239 -0
  55. package/test/core.test.js +519 -0
  56. package/test/dsl.test.js +237 -0
  57. package/test/event-manager.test.js +102 -0
  58. package/test/exec-options.test.js +32 -0
  59. package/test/finalcb-task.test.js +37 -0
  60. package/test/fstr.test.js +288 -0
  61. package/test/input-parser.test.js +62 -0
  62. package/test/module-use.test.js +317 -0
  63. package/test/pcode.test.js +321 -0
  64. package/test/ret-task.test.js +199 -0
  65. package/test/task.test.js +21 -0
  66. package/test/validate-cb-task.test.js +74 -0
  67. package/test/validate-ret-task.test.js +83 -0
  68. package/test/validate.test.js +218 -0
  69. package/test/vcon.test.js +160 -0
  70. package/lib/react.js +0 -239
package/.npmignore ADDED
@@ -0,0 +1,6 @@
1
+ node_modules
2
+ npm-debug.log
3
+ ./npmrc
4
+ todo.md
5
+ notes.md
6
+ oldExamples
package/Jakefile.js ADDED
@@ -0,0 +1,8 @@
1
+
2
+
3
+ require('./jake-tasks/jake-test.js');
4
+
5
+ desc('Default - run watch');
6
+ task('default', ['test:watch']);
7
+
8
+
package/README.md CHANGED
@@ -1,32 +1,55 @@
1
1
  # React.js
2
2
 
3
- React is a javascript module to make it easier to work with asynchronous code,
3
+ React is a javascript module to make it easier to work with asynchronous code,
4
4
  by reducing boilerplate code and improving error and exception handling while
5
- allowing variable and task dependencies when defining flow.
5
+ allowing variable and task dependencies when defining flow. This project is
6
+ applying the concepts of Reactive programming or Dataflow to controlling
7
+ application flow.
6
8
 
7
- This async flow control module is initially designed to work with Node.js but
9
+ This async flow control module is initially designed to work with Node.js but
8
10
  is planned to be extended to browser and other environments.
9
11
 
10
- It takes inspiration from several projects including:
12
+ React gets its name from similarities with how "chain reactions" work in the physical world. You start the reaction and then it cascades and continues until complete.
13
+
14
+ Also "Reactive Programming" or "Dataflow" describe defining flow which reacts to the data similar to how a spreadsheet updates cells. These are good examples of how React controls flow based on when data is available
15
+
16
+ - Reactive programming - <http://en.wikipedia.org/wiki/Reactive_programming>
17
+ - Dataflow programming - <http://en.wikipedia.org/wiki/Dataflow>
18
+ - Dataflow Programming: Handling Huge Data Loads Without Adding Complexity (Dr. Dobb's Sept 19, 2011) - <http://drdobbs.com/database/231400148>
19
+
20
+ It takes inspiration from several projects including:
11
21
 
12
22
  - Tim Caswell and Elijah Insua's [conductor](https://github.com/creationix/conductor) - [Article](http://howtonode.org/step-of-conductor)
13
23
  - Caolan McMahon's [async](https://github.com/caolan/async)
14
24
 
15
- React gets its name from similarities with how "chain reactions" work in the physical world. You start the reaction and then it cascades and continues until complete.
16
25
 
17
26
  ## Goals
18
27
 
28
+ - Minimize boilerplate code needed for working with asynchronous functions
29
+ - Minimize the need to customize your code simply to use async flow control. The use of a flow control module ideally should not affect the way you write your code, it should only help take over some of the burden.
19
30
  - Improved error and exception handling
20
31
  - Provide useful stack traces and context information for easier debugging
21
- - Minimize boilerplate code needed for working with asynchronous functions
22
32
  - Make code more readable and easier to understand which should translate to less defects
23
33
  - Provide the right level of abstraction to make it easier to refactor code, without being too magical
24
34
  - Allow the mixing of pure functions, method calls, and callback style functions in the flow
25
- - Minimize the need to customize your code simply to use async flow control. The use of a flow control module ideally should not affect the way you write your code, it should only help take over some of the burden.
35
+
36
+ ## Supports
37
+
38
+ - async node-style callback(err, arg...) functions
39
+ - sync functions which directly return value
40
+ - object instance method calls
41
+ - class method calls
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
44
+ - (planned) use of resulting flow function as callback style or promise style (if no callback provided)
45
+ - (planned) iteration on arrays, streams, sockets
46
+ - (planned) event emitter integration
47
+
48
+ The tasks can be mixed, meaning you can use async, sync, object method calls, class method calls, etc in the same flow.
26
49
 
27
50
  ## Concept
28
51
 
29
- Borrowing heavily from Tim and Elijah's ideas for conductor, this async flow control module provides a way to construct a flow from a collection of functions or methods (referred to as _tasks_ in this module). It allows dependencies to be defined between the tasks so they can run in parallel as their dependencies are satisfied. React can us both variable dependencies and task dependencies.
52
+ Borrowing heavily from Tim and Elijah's ideas for conductor, this async flow control module provides a way to construct a flow from a collection of functions or methods (referred to as _tasks_ in this module). It allows dependencies to be defined between the tasks so they can run in parallel as their dependencies are satisfied. React can us both variable dependencies and task dependencies.
30
53
 
31
54
  As tasks complete, React watches the dependencies and kicks off additional tasks that have all their dependencies met and are ready to execute. This allows the flow to run at maximum speed without needing to arbitrarily block tasks into groups of parallel and serial flow.
32
55
 
@@ -38,101 +61,217 @@ To reduce the boilerplate code needed and improve error handling, React automati
38
61
 
39
62
  ## Design
40
63
 
41
- - Optional parse step to create flow AST (TODO allow pluggable parsers to allow many interfaces)
42
- - Validate the flow AST - determine if dependencies can all be met as defined such that flow will complete (TODO)
43
- - Execute the flow AST
64
+ - Parse and validate DSL rules at module load time
65
+ - Validate the flow AST at module load time - determine if dependencies can all be met as defined
66
+ - Execute the flow AST by calling the function with arguments
44
67
 
45
68
  ## Installing
46
69
 
47
70
  npm install react
48
71
 
49
- OR
50
-
72
+ OR
73
+
51
74
  Pull from github - http://github.com/jeffbski/react
52
75
 
53
76
  ## Examples
54
77
 
55
- 1. [Direct AST](#directAST)
56
- 2. [Using Simple DSL](#simpleDSL)
78
+ 1. [Default DSL](#defaultDSL)
79
+ 2. [Direct AST](#directAST)
80
+ 3. [Using pseudocode DSL](#pcode)
81
+ 4. [Using jquery-like chaining DSL](#chain)
82
+
83
+
84
+ These live in the examples folder so they are ready to run.
85
+ Also see test/module-use.test.js for more examples as well
86
+ as the specific tests for the DSL you want to use.
87
+
88
+ <a name="defaultDSL"/>
89
+ ### Example using default DSL
90
+
91
+ ```javascript
92
+ // in your foo module
93
+ var react = require('react');
94
+
95
+ // some normal async and sync functions
96
+ function loadUser(uid, cb){ }
97
+ function loadFile(filename, cb){ }
98
+ function markdown(filedata) { }
99
+ function writeOutput(html, user, cb){ }
100
+ function loadEmailTemplate(cb) { }
101
+ function customizeEmail(user, emailHtml, cb) { }
102
+ function deliverEmail(custEmailHtml, cb) { }
103
+
104
+ // define fn, glue together with react, it will parallelize
105
+ // starts with name and in/out params, then the tasks
106
+ var loadAndSend = react('loadAndSend', 'uid, filename, cb -> err, user',
107
+ loadUser, 'uid, cb -> err, user',
108
+ loadFile, 'filename, cb -> err, filemd',
109
+ markdown, 'filemd -> html', // no cb, implies sync fn
110
+ writeOutput, 'html, user, cb -> err, htmlBytesWritten',
111
+ loadEmailTemplate, 'cb -> err, emailmd',
112
+ markdown, 'emailmd -> emailHtml', // no cb, implies sync fn
113
+ customizeEmail, 'user, emailHtml, cb -> err, custEHtml',
114
+ deliverEmail, 'custEHtml, cb -> err, custBytesWritten'
115
+ );
116
+ exports.loadAndSend = loadAndSend; // is a normal fn created by react
117
+
118
+ // in a different module far far away, use this as any other node function
119
+ var foo = require('foo');
120
+ foo.loadAndSend(100, 'bar.md', function (err, user) {
121
+ // tasks were parallelized based on their depedencies
122
+ }
123
+ ```
124
+
57
125
 
58
126
  <a name="directAST"/>
59
127
  ### Example directly using AST
60
128
 
61
- var react = require('react').react;
62
-
63
- function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
64
- function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
65
- function markdown(filedata) { return 'html'+filedata; }
66
- function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
67
- function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
68
- function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
69
- function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
70
- function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
71
-
72
- function useHtml(err, html, user, bytesWritten) {
73
- if(err) {
74
- console.log('***Error: %s', err);
75
- return;
76
- }
77
- console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
78
- }
79
-
80
- var r = react();
81
- r.ast.inputNames = ['filename', 'uid', 'outDirname', 'cb'];
82
- r.ast.taskDefs = [
83
- { f:loadUser, a:['uid'], cb:['user'] },
84
- { f:loadFile, a:['filename'], cb:['filedata'] },
85
- { f:markdown, a:['filedata'], ret:['html'] },
86
- { f:prepareDirectory, a:['outDirname'], cb:['dircreated'] },
87
- { f:writeOutput, a:['html', 'user'], cb:['bytesWritten'], after:['prepareDirectory'] },
88
- { f:loadEmailTemplate, a:[], cb:['emailmd'] },
89
- { f:markdown, a:['emailmd'], ret:['emailHtml'] },
90
- { f:customizeEmail, a:['user', 'emailHtml'], ret:['custEmailHtml'] },
91
- { f:deliverEmail, a:['custEmailHtml'], cb:['deliveredEmail'], after:['writeOutput'] }
92
- ];
93
- r.ast.finalOutputNames = ['html', 'user', 'bytesWritten'];
94
-
95
- r.exec("hello.txt", 100, 'outHello', useHtml);
96
- r.exec("small.txt", 200, 'outSmall', useHtml);
97
-
98
- <a name="simpleDSL"/>
99
- ### Example using simple DSL interface
100
-
101
- var react = require('react').react;
102
-
103
- function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
104
- function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
105
- function markdown(filedata) { return 'html'+filedata; }
106
- function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
107
- function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
108
- function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
109
- function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
110
- function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
111
-
112
- function useHtml(err, html, user, bytesWritten) {
113
- if(err) {
114
- console.log('***Error: %s', err);
115
- return;
116
- }
117
- console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
118
- }
119
-
120
- var r = react('filename, uid, outDirname, cb').define(
121
- loadUser, 'uid -> err, user',
122
- loadFile, 'filename -> err, filedata',
123
- markdown, 'filedata -> returns html',
124
- prepareDirectory, 'outDirname -> err, dircreated',
125
- writeOutput, 'html, user -> err, bytesWritten', { after:prepareDirectory },
126
- loadEmailTemplate,' -> err, emailmd',
127
- markdown, 'emailmd -> returns emailHtml',
128
- customizeEmail, 'user, emailHtml -> returns custEmailHtml',
129
- deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput }
130
- ).callbackDef('err, html, user, bytesWritten');
129
+ ```javascript
130
+ var react = require('react');
131
+
132
+ function load(res, cb) { setTimeout(cb, 100, null, res + '-loaded'); }
133
+ function prefix(prefstr, str, cb) { setTimeout(cb, 100, null, prefstr + str); }
134
+ function postfix(str, poststr, cb) { setTimeout(cb, 100, null, str + poststr); }
135
+ function upper(str) { return str.toUpperCase(); }
136
+
137
+ var fn = react();
138
+ var errors = fn.setAndValidateAST({
139
+ inParams: ['res', 'prefstr', 'poststr'],
140
+ tasks: [
141
+ { f: load, a: ['res'], out: ['lres'] },
142
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
143
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
144
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
145
+ ],
146
+ outTask: { a: ['plresp'] }
147
+ });
148
+ console.error('errors:', errors); // []
149
+
150
+ fn('foo', 'pre-', '-post', function cb(err, lres) {
151
+ console.error('err:', err); // null
152
+ console.error('lres:', lres); // pre-FOO-LOADED-post
153
+ });
154
+ ```
155
+
156
+ <a name="fstr"/>
157
+ ### Example using Function String DSL interface
158
+
159
+ ```javascript
160
+ var react = require('react');
161
+
162
+ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
163
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
164
+ function markdown(filedata) { return 'html'+filedata; }
165
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
166
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
167
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
168
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
169
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
170
+
171
+ function useHtml(err, html, user, bytesWritten) {
172
+ if(err) {
173
+ console.log('***Error: %s', err);
174
+ return;
175
+ }
176
+ console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
177
+ }
178
+
179
+ var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
180
+ loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
181
+ loadFile, 'filename -> err, filedata',
182
+ markdown, 'filedata -> returns html', // using a sync function
183
+ prepareDirectory, 'outDirname -> err, dircreated',
184
+ writeOutput, 'html, user -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
185
+ loadEmailTemplate, ' -> err, emailmd',
186
+ markdown, 'emailmd -> returns emailHtml', // using a sync function
187
+ customizeEmail, 'user, emailHtml -> returns custEmailHtml',
188
+ deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
189
+ ], 'err, html, user, bytesWritten'); // callback output params
190
+
191
+ loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
192
+ ```
193
+
194
+ <a name="pcode"/>
195
+ ### Example using pseudocode DSL interface
196
+
197
+ ```javascript
198
+ var react = require('react');
199
+
200
+ function multiply(a, b, cb) { cb(null, a * b); }
201
+ function add(a, b) { return a + b; }
202
+ var locals = { // since pcodeDefine uses strings, need references to functions passed into react
203
+ multiply: multiply,
204
+ add: add
205
+ };
206
+
207
+ var fn = react.pcodeDefine('a, b, cb', [ // input params
208
+ 'm := multiply(a, b)', // using a callback function, use :=
209
+ 's = add(m, a)', // using a sync function, use =
210
+ 'cb(err, m, s)' // output params for final callback
211
+ ], locals); // hash of functions that will be used
212
+
213
+ fn(2, 3, function (err, m, s) {
214
+ console.error('err:', err); // null
215
+ console.error('m:', m); // 2 * 3 = 6
216
+ console.error('s:', s); // 6 + 2 = 8
217
+ });
218
+ ```
219
+
220
+ <a name="chain"/>
221
+ ### Example using jquery-like chaining DSL interface
222
+
223
+ ```javascript
224
+ var react = require('react');
225
+
226
+ function multiply(a, b, cb) { cb(null, a * b); }
227
+ function add(a, b) { return a + b; }
228
+
229
+ var fn = react.chainDefine()
230
+ .in('a', 'b', 'cb') // input params
231
+ .out('err', 'm', 's') // final callback output params
232
+ .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
233
+ .sync(add).in('m', 'a').out('s') // task def - sync fn, in params, return value
234
+ .end();
235
+
236
+ fn(2, 3, function (err, m, s) {
237
+ console.error('err:', err); // null
238
+ console.error('m:', m); // 2 * 3 = 6
239
+ console.error('s:', s); // 6 + 2 = 8
240
+ });
241
+ ```
131
242
 
132
243
  ## Status
133
244
 
245
+ - 2012-01-10 - Create default DSL for react()
246
+ - 2011-12-21 - Refactor from ground up with tests, changes to the interfaces
134
247
  - 2011-10-26 - React is in active development and interface may change frequently in these early stages. Current code is functional but does not perform validation yet. Additional interfaces are planned to make it easy to define flows in a variety of ways. Documentation and examples forthcoming.
135
248
 
249
+ ## Test Results
250
+
251
+ ```bash
252
+ ok ast.test.js .................... 10/10
253
+ ok cb-task.test.js ................ 31/31
254
+ ok chain.test.js .................. 56/56
255
+ ok core.test.js ................... 98/98
256
+ ok dsl.test.js .................... 58/58
257
+ ok event-manager.test.js .......... 13/13
258
+ ok exec-options.test.js ............. 3/3
259
+ ok finalcb-task.test.js ............. 5/5
260
+ ok fstr.test.js ................... 64/64
261
+ ok input-parser.test.js ........... 15/15
262
+ ok module-use.test.js ............. 64/64
263
+ ok pcode.test.js .................. 65/65
264
+ ok ret-task.test.js ............... 31/31
265
+ ok task.test.js ..................... 1/1
266
+ ok validate-cb-task.test.js ......... 6/6
267
+ ok validate-ret-task.test.js ........ 7/7
268
+ ok validate.test.js ............... 26/26
269
+ ok vcon.test.js ................... 42/42
270
+ total ........................... 613/613
271
+
272
+ ok
273
+ ```
274
+
136
275
  ## License
137
276
 
138
277
  - [MIT license](http://github.com/jeffbski/react/raw/master/LICENSE)
@@ -145,4 +284,5 @@ Pull from github - http://github.com/jeffbski/react
145
284
 
146
285
  - Source code repository: http://github.com/jeffbski/react
147
286
  - Ideas and pull requests are encouraged - http://github.com/jeffbski/react/issues
148
- - You may contact me at @jeffbski or through github at http://github.com/jeffbski
287
+
288
+ - You may contact me at @jeffbski or through github at http://github.com/jeffbski
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var react = require('../'); // require('react');
4
+
5
+ function load(res, cb) { setTimeout(cb, 100, null, res + '-loaded'); }
6
+ function prefix(prefstr, str, cb) { setTimeout(cb, 100, null, prefstr + str); }
7
+ function postfix(str, poststr, cb) { setTimeout(cb, 100, null, str + poststr); }
8
+ function upper(str) { return str.toUpperCase(); }
9
+
10
+ var fn = react();
11
+ var errors = fn.setAndValidateAST({
12
+ inParams: ['res', 'prefstr', 'poststr'],
13
+ tasks: [
14
+ { f: load, a: ['res'], out: ['lres'] },
15
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
16
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
17
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
18
+ ],
19
+ outTask: { a: ['plresp'] }
20
+ });
21
+ console.error('errors:', errors); // []
22
+
23
+ fn('foo', 'pre-', '-post', function cb(err, lres) {
24
+ console.error('err:', err); // null
25
+ console.error('lres:', lres); // pre-FOO-LOADED-post
26
+ });
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var react = require('../'); // require('react');
4
+
5
+ //output events as tasks start and complete
6
+ react.events.on('*', function (obj) {
7
+ var time = new Date();
8
+ time.setTime(obj.time);
9
+ var eventTimeStr = time.toISOString();
10
+ var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
11
+ if (obj.event === 'task.complete') {
12
+ console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
13
+ obj.event, obj.name, obj.elapsedTime, argsNoCb, obj.results);
14
+ } else {
15
+ console.error('%s: %s \n\targs:(%s)\n', obj.event, obj.name, argsNoCb);
16
+ }
17
+ });
18
+
19
+
20
+ function multiply(a, b, cb) { cb(null, a * b); }
21
+ function add(a, b) { return a + b; }
22
+
23
+ var fn = react.chainDefine()
24
+ .in('a', 'b', 'cb') // input params
25
+ .out('err', 'm', 's') // final callback output params
26
+ .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
27
+ .sync(add).in('m', 'a').out('s') // task def - sync fn, in params, return value
28
+ .end();
29
+
30
+ fn(2, 3, function (err, m, s) {
31
+ console.error('err:', err); // null
32
+ console.error('m:', m); // 2 * 3 = 6
33
+ console.error('s:', s); // 6 + 2 = 8
34
+ });
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var react = require('../'); // require('react');
4
+
5
+ function multiply(a, b, cb) { cb(null, a * b); }
6
+ function add(a, b) { return a + b; }
7
+
8
+ var fn = react.chainDefine()
9
+ .in('a', 'b', 'cb') // input params
10
+ .out('err', 'm', 's') // final callback output params
11
+ .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
12
+ .sync(add).in('m', 'a').out('s') // task def - sync fn, in params, return value
13
+ .end();
14
+
15
+ fn(2, 3, function (err, m, s) {
16
+ console.error('err:', err); // null
17
+ console.error('m:', m); // 2 * 3 = 6
18
+ console.error('s:', s); // 6 + 2 = 8
19
+ });