react 0.3.4 → 0.5.2

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 (42) hide show
  1. package/.npmignore +2 -1
  2. package/README.md +68 -172
  3. package/doc/advanced.md +166 -0
  4. package/doc/color-def.graffle +938 -0
  5. package/doc/color-def.png +0 -0
  6. package/doc/simple.dot +25 -0
  7. package/doc/simple.png +0 -0
  8. package/examples/{default1.js → longer-example.js} +0 -0
  9. package/examples/simple.js +45 -0
  10. package/examples/{ast1.js → using-ast-directly.js} +4 -0
  11. package/examples/{default-events1.js → using-events1.js} +0 -0
  12. package/examples/{default-log-events.js → using-log-events.js} +1 -1
  13. package/lib/core.js +13 -1
  14. package/lib/event-collector.js +68 -0
  15. package/lib/event-manager.js +4 -0
  16. package/lib/id.js +1 -0
  17. package/lib/log-events.js +30 -15
  18. package/{promise-resolve.js → lib/promise-resolve.js} +1 -1
  19. package/lib/task.js +8 -3
  20. package/lib/track-tasks.js +5 -62
  21. package/lib/vcon.js +1 -1
  22. package/package.json +2 -2
  23. package/react.js +33 -1
  24. package/test/ast.test.js +50 -1
  25. package/test/core.test.js +27 -2
  26. package/test/dsl.test.js +2 -2
  27. package/test/module-use.test.js +5 -2
  28. package/test/promise-auto-resolve.test.js +2 -1
  29. package/Jakefile.js +0 -8
  30. package/doc/alternate-dsls.md +0 -103
  31. package/dsl/chain.js +0 -150
  32. package/dsl/fstr.js +0 -121
  33. package/dsl/pcode.js +0 -175
  34. package/examples/chain-events1.js +0 -55
  35. package/examples/chain1.js +0 -19
  36. package/examples/fstr-events1.js +0 -38
  37. package/examples/fstr1.js +0 -37
  38. package/examples/pcode1.js +0 -22
  39. package/jake-tasks/jake-test.js +0 -64
  40. package/test/dsl/chain.test.js +0 -324
  41. package/test/dsl/fstr.test.js +0 -300
  42. package/test/dsl/pcode.test.js +0 -448
package/.npmignore CHANGED
@@ -3,4 +3,5 @@ npm-debug.log
3
3
  ./npmrc
4
4
  todo.md
5
5
  notes.md
6
- oldExamples
6
+ .DS_Store
7
+ externalDocs
package/README.md CHANGED
@@ -35,8 +35,8 @@ It takes inspiration from several projects including:
35
35
  - object instance method calls
36
36
  - class method calls
37
37
  - selectFirst flow where the first task that returns defined, non-null value is used
38
- - promise style functions - also automatic resolution of promise inputs (optional require('react/promise-resolve');)
39
- - use of resulting flow function as callback style or promise style (if no callback provided) (provided via plugin corresponding to the promise library used)
38
+ - promise style functions - also automatic resolution of promise inputs (optionally loaded with `react.resolvePromises();`)
39
+ - use of resulting flow function as callback style or promise style (if no callback provided) (provided via plugin corresponding to the promise library used) See https://github.com/jeffbski/react-deferred
40
40
  - (planned) iteration on arrays, streams, sockets
41
41
  - (planned) event emitter integration
42
42
 
@@ -72,222 +72,121 @@ Pull from github - http://github.com/jeffbski/react
72
72
 
73
73
  ## Examples
74
74
 
75
- 1. [Direct AST](#directAST)
76
- 2. [Default DSL](#defaultDSL)
75
+ <a name="defaultDSL"/>
76
+ ### Example using default DSL interface
77
77
 
78
- ### Example using the default DSL
78
+ - Simple example showing flow definition of two async functions feeding a
79
+ synchronous function.
79
80
 
80
- These live in the examples folder so they are ready to run.
81
- Also see test/module-use.test.js for more examples as well
82
- as the specific tests for the DSL you want to use.
81
+ - First two async functions inputs are satisfied by the flow inputs, so
82
+ they will both run immediately in parallel.
83
83
 
84
- <a name="defaultDSL"/>
85
- ### Example using default DSL
84
+ - The last function waits for the outputs of the previous ones, then
85
+ executes synchronously.
86
+
87
+ - Finally the flow calls the callback with the output values once all
88
+ the tasks have completed.
86
89
 
87
90
  ```javascript
88
- // in your foo module
91
+ // in your foobar module
89
92
  var react = require('react');
90
93
 
91
94
  // some normal async and sync functions
92
- function loadUser(uid, cb){ }
93
- function loadFile(filename, cb){ }
94
- function markdown(filedata) { }
95
- function writeOutput(html, user, cb){ }
96
- function loadEmailTemplate(cb) { }
97
- function customizeEmail(user, emailHtml, cb) { }
98
- function deliverEmail(custEmailHtml, cb) { }
95
+ function loadFoo(fooPath, cb) {
96
+ setTimeout(function () {
97
+ cb(null, [fooPath, 'data'].join(':'));
98
+ }, 10);
99
+ }
99
100
 
100
- // define fn, glue together with react, it will parallelize
101
- // starts with name and in/out params, then the tasks
102
- var loadAndSend = react('loadAndSend', 'uid, filename, cb -> err, user',
103
- loadUser, 'uid, cb -> err, user',
104
- loadFile, 'filename, cb -> err, filemd',
105
- markdown, 'filemd -> html', // no cb, implies sync fn
106
- writeOutput, 'html, user, cb -> err, htmlBytesWritten',
107
- loadEmailTemplate, 'cb -> err, emailmd',
108
- markdown, 'emailmd -> emailHtml', // no cb, implies sync fn
109
- customizeEmail, 'user, emailHtml, cb -> err, custEHtml',
110
- deliverEmail, 'custEHtml, cb -> err, custBytesWritten'
111
- );
112
- exports.loadAndSend = loadAndSend; // is a normal fn created by react
101
+ function loadBar(barPath, barP2, cb) {
102
+ setTimeout(function () {
103
+ cb(null, [barPath, barP2, 'data'].join(':'));
104
+ }, 10);
105
+ }
113
106
 
114
- // in a different module far far away, use this as any other node function
115
- var foo = require('foo');
116
- foo.loadAndSend(100, 'bar.md', function (err, user) {
117
- // tasks were parallelized based on their depedencies
107
+ function render(foo, bar) {
108
+ return ['<html>', foo, '/', bar, '</html>'].join('');
118
109
  }
119
- ```
120
110
 
111
+ // define fn, glue together with react, it will parallelize
112
+ // starts with name and in/out params, then the tasks
113
+ var loadRender = react('loadRender', 'fooPath, barPath, barP2, cb -> err, renderedOut',
114
+ loadFoo, 'fooPath, cb -> err, foo', // async cb function
115
+ loadBar, 'barPath, barP2, cb -> err, bar', // async cb function
116
+ render, 'foo, bar -> renderedOut' // sync function using outputs from first two
117
+ );
121
118
 
122
- <a name="directAST"/>
123
- ### Example directly using AST
119
+ exports.loadRender = loadRender; // is a normal fn created by react
124
120
 
125
- ```javascript
126
- var react = require('react');
127
121
 
128
- function load(res, cb) { setTimeout(cb, 100, null, res + '-loaded'); }
129
- function prefix(prefstr, str, cb) { setTimeout(cb, 100, null, prefstr + str); }
130
- function postfix(str, poststr, cb) { setTimeout(cb, 100, null, str + poststr); }
131
- function upper(str) { return str.toUpperCase(); }
132
-
133
- var fn = react();
134
- var errors = fn.setAndValidateAST({
135
- inParams: ['res', 'prefstr', 'poststr'],
136
- tasks: [
137
- { f: load, a: ['res'], out: ['lres'] },
138
- { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
139
- { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
140
- { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
141
- ],
142
- outTask: { a: ['plresp'] }
143
- });
144
- console.error('errors:', errors); // []
145
-
146
- fn('foo', 'pre-', '-post', function cb(err, lres) {
147
- console.error('err:', err); // null
148
- console.error('lres:', lres); // pre-FOO-LOADED-post
122
+ // in a different module far far away, use this as any other node function
123
+ var foobar = require('foobar');
124
+ foobar.loadRender('foo.txt', 'bar.txt', 'BBB', function (err, renderedOut) {
125
+ // tasks in loadRender were parallelized based on their input dependencies
126
+ console.error('results:', renderedOut);
149
127
  });
150
128
  ```
151
129
 
152
- ### Alternate interfaces (DSL's)
130
+ Below is a graph of how the dependencies are mapped by React which
131
+ also indicates how the tasks will be executed. This was generated by the
132
+ react plugin [react-graphviz](https://github.com/jeffbski/react-graphviz)
133
+ which you can use to also graph your flows.
153
134
 
154
- 1. [Using pseudocode DSL](http://github.com/jeffbski/react/raw/master/doc/alternate-dsls.md#pcode)
155
- 2. [Using jquery-like chaining DSL](http://github.com/jeffbski/react/raw/master/doc/alternate-dsls.md#chain)
156
- 3. [Using function string DSL](http://github.com/jeffbski/react/raw/master/doc/alternate-dsls.md#fstr)
135
+ ![simple.png](https://github.com/jeffbski/react/raw/master/doc/simple.png)
157
136
 
158
137
 
159
- ## User API
160
138
 
161
- ### Default DSL
139
+ ## User API
162
140
 
163
141
  The main function returned from require('react') can be used to define the AST used for the processing of the rules or flow.
164
142
 
165
143
  It takes the following arguments to define a flow function:
166
144
 
167
145
  ```javascript
168
- var react = require('react');
169
- var fn = react('my-flow-name', 'paramName1, paramName2, cb -> err, outParamName1, outParamName2',
170
- functionRefOrMethodStr, 'paramName1, cb -> err, outParamName2', // async cb task
171
- functionRefOrMethodStr2, 'paramName2, paramName1 -> outParamName1' // sync task
146
+ var fn = react('loadRender', 'fooPath, barPath, barP2, cb -> err, renderedOut',
147
+ loadFoo, 'fooPath, cb -> err, foo',
148
+ loadBar, 'barPath, barP2, cb -> err, bar',
149
+ render, 'foo, bar -> renderedOut'
172
150
  );
173
151
  ```
174
152
 
153
+ ![color-def](https://github.com/jeffbski/react/raw/master/doc/color-def.png)
154
+
175
155
  1. **flow/function name** - string - represents the name of the flow or function that will be created. React will use the name when generating events so you can monitor progress and performance and also when errors occur.
176
156
  2. **in/out flow parameter definition** - string - the inputs and outputs for the flow function. The parameters are specified in one single string for easy typing, separated by commas. The output follows the input after being separated by a `->`. Use the parameter name `cb` or `callback` to specify the Node style callback and `err` to represent the error parameter as the first output parameter of the callback. Literal values can also be specified directly (true, false, numbers, this, null). Literal strings can simply be quoted using single or double quotes.
177
157
  3. **optional flow options** - object - If an object is provided immediately after the in/out flow def, then these options will be provided to react to customize the flow. This is reserved for future use.
178
- 3. **function reference or method string** - Specify the function to be called for this task, or if calling a method off of an object being passed in or returned by a task, use a string to specify like `'obj.method'`. These can be asynchronous Node-style callback `cb(err, ...)` functions or synchronous functions which simply return values directly.
179
- 4. **in/out task parameter definition** - string - similar to the in/out flow parameter definition above, these are the inputs and outputs that are passed to a task function and returned from a task function. The inputs will need to match either those from the flow inputs or outputs from other tasks that will run before this task. React will use the inputs as dependencies, so it will invoke and wait for response from the tasks that provide the dependent inputs. So simply by specifying inputs and outputs for the tasks, React will prioritize and parallelize tasks to run as fast as possible. Use `cb` or `callback` along with `err` to specify asynchronous Node style `cb(err, ...)` task, or omit both to specify a synchronous task.A synchronous task can only have a single return parameter.
180
- 5. **optional task options** - object - if an object is provided this can be used to specify additional options for this task. Currently the valid options for a task are:
158
+ 4. **function reference or method string** - Specify the function to be called for this task, or if calling a method off of an object being passed in or returned by a task, use a string to specify like `'obj.method'`. These can be asynchronous Node-style callback `cb(err, ...)` functions or synchronous functions which simply return values directly.
159
+ 5. **in/out task parameter definition** - string - similar to the in/out flow parameter definition above, these are the inputs and outputs that are passed to a task function and returned from a task function. The inputs will need to match either those from the flow inputs or outputs from other tasks that will run before this task. React will use the inputs as dependencies, so it will invoke and wait for response from the tasks that provide the dependent inputs. So simply by specifying inputs and outputs for the tasks, React will prioritize and parallelize tasks to run as fast as possible. Use `cb` or `callback` along with `err` to specify asynchronous Node style `cb(err, ...)` task, or omit both to specify a synchronous task.A synchronous task can only have a single return parameter.
160
+ 6. **optional task options** - object - if an object is provided this can be used to specify additional options for this task. Currently the valid options for a task are:
181
161
  - **name** - string - specifies a name for a task, otherwise React will try to use the function name or method string if it is unique in the flow. If a name is not unique subsequent tasks will have `_index` (zero based index of the task) added to create unique name. If you specify a name, you will also want to indicate a unique name for within the flow otherwise it will get a suffix as well. Example: `{ name: 'myTaskName' }`
182
162
  - **after** - string, function reference, or array of string or function refs - specify additional preconditions that need to be complete before this task can run. In addition to the input dependencies being met, wait for these named tasks to complete before running. The preconditions are specified using the name of the task or if the task function was only used once and is a named function (not anonymous), you can just provide the function reference and it will determine name from it. Example: `{ after: 'foo' }` or `{ after: ['foo', 'bar'] }`
183
- 6. **repeat 3-5** - repeat steps 3-5 to specify additional tasks in this flow. As dependencies are met for tasks, React will invoke additional tasks that are ready to run in the order they are defined in this flow definition. So while the order does have some influence on the execution, it is primarily defined by the input dependencies and any other additonal preconditions specified with the `after` option. If you want to guarantee that something only runs after something else completes, then it will need to use an output from that task or specify the dependency with an `after`.
163
+ 7. **repeat 4-6** - repeat steps 4-6 to specify additional tasks in this flow. As dependencies are met for tasks, React will invoke additional tasks that are ready to run in the order they are defined in this flow definition. So while the order does have some influence on the execution, it is primarily defined by the input dependencies and any other additonal preconditions specified with the `after` option. If you want to guarantee that something only runs after something else completes, then it will need to use an output from that task or specify the dependency with an `after`.
184
164
 
185
165
 
186
166
  The flow function created by react from the input definition is a normal Node-style function which can be used like any other. These flow functions can be defined in a module and exported, they can be passed into other functions, used as methods on objects (the `this` context is passed in and available).
187
167
 
168
+ ### Debugging React
188
169
 
189
- ### AST
190
-
191
- The abstract syntax tree or AST provided by React represents the data necessary to define the flow. By abstracting this from the DSL, it allows new skins or interfaces to be developed without need to change the core engine.
192
-
193
- The AST is normally created at parse time when the React main function is called (or one of the alternate DSL's is called). This can be done a module load time such that after loading the React defined flow function's AST is generated and ready to process eliminating parsing and validation overhead when it is invoked in the future. This has the added advantage that since validation has also been performed that additional syntax issues or incomplete flow defintion errors can be caught quickly.
194
-
195
- After the flow function has been created, you can review the generated AST for a function by accessing the ast.
170
+ React has a built-in plugin which can be loaded that will enable logging of tasks and flow as it executes very useful for debugging. For full details see [Advanced React - LogEvents](https://github.com/jeffbski/react/blob/master/doc/advanced.md#LogEvents) along with the other plugins and an explanation of the AST React uses.
196
171
 
197
172
  ```javascript
198
173
  var react = require('react');
199
- var fn = react('my-flow-name', 'paramName1, paramName2, cb -> err, outParamName1, outParamName2',
200
- functionRefOrMethodStr, 'paramName1, cb -> err, outParamName2', // async cb task
201
- functionRefOrMethodStr2, 'paramName2, paramName1 -> outParamName1' // sync task
202
- );
203
-
204
- console.error(fn.ast); // output the generated AST
205
- ```
206
-
207
- The AST contains the following pieces:
208
-
209
- ```javascript
210
- var ast = {
211
- name: flowName,
212
- inParams: [],
213
- tasks: [],
214
- outTask: {},
215
- locals: {}
216
- };
174
+ react.logEvents(); // turn on flow and task logging for all react functions
217
175
  ```
218
- - **name** - string - represents the name of the flow or function that will be created. React will use the name when generating events so you can monitor progress and performance and also when errors occur.
219
- - **inParams** - array of strings - the flow input parameter names (excluding the callback param)
220
- - **tasks** - array of task defintion objects - each containing:
221
- - **f** - function reference or method string - async or sync function to be used for this task
222
- - **a** - array of input parameter names (excluding the callback param)
223
- - **out** - array of output parameter names (excluding the err parame)
224
- - **type** - type of function determining how function is invoked and its output style - one of: ('cb', 'ret', 'promise', 'when')
225
- - **name** - string - unique name for each task provided or generated by React
226
- - **outTask** - task definition object specifying the flow's output style and parameters containing:
227
- - **f** - will contain reference to the callback function at runtime
228
- - **a** - parameters being passed as output from the flow
229
- - **locals** - object provided which contains additional values that will become part of the React variable space like input parameters but can be defined in advance at flow definition. This can be used to provide functions and objects to React enabling string based DSL's like the pcode DSL can be utilized.
230
-
231
-
232
- ### Plugins (optional requires which turn on additional functionality)
233
176
 
234
- Additional functionality which is not enabled by default but available by requiring additional modules.
177
+ ### Advanced React
235
178
 
179
+ React has many additional plugins and features which enable logging, monitoring, promise resolution, etc.
236
180
 
237
- #### LogEvents - log react progress to stderr
238
-
239
- For convenience in debugging or in monitoring flow and performance, React has a built-in plugin for easily logging progress to stderr which is activiated by requiring it and specifying a particular flow function to log or use the main react for global logging of all react modules.
240
-
241
- ```javascript
242
- require('react/lib/log-events').logEvents(react); // turn on logging for all react functions
243
-
244
- // OR
245
-
246
- require('react/lib/log-events').logEvents(myReactFn); // turn on logging for a specific function, repeat for other functions as needed
247
- ```
248
-
249
- #### Automatic Promise Resolution for inputs
250
-
251
- If you want to automatically resolve promises in React without having to manually call `when` or `then`, React provides a plugin which will detect the existence of a `then` method (indicating a promise) at runtime from any inputs to the flow and will internally create `when` tasks to resolve them before passing the values to other tasks.
252
-
253
- ```javascript
254
- require('react/promise-resolve');
255
- ```
256
-
257
- #### Track tasks
258
-
259
- Instead of only logging events to stderr (like LogEvents), this plugin fires events that can be directly monitored. The LogEvent plugin uses this internally to get access to the metrics.
260
-
261
- It also provides a simple accumulator which can be used to accumulate events. Note that this accumulator is designed for short term debug use, as it will continue to accumulate events and does not have any size restrictions.
262
-
263
- Thus while the tracking can be used in production because it simply fires events, the accumulator should only be used for convenience in debugging and testing.
264
-
265
- ```javascript
266
- require('react/lib/track-tasks'); // enable tracking and events
267
-
268
- // if you want to use the accumulator
269
-
270
- var EventCollector = require('react/lib/track-tasks').EventCollector;
271
- var collector = new EventCollector();
272
-
273
- collector.captureGlobal('*'); // capture all react events for all flows
274
-
275
- // OR
276
-
277
- collector.capture(flowFn, 'task.'); // capture task events on a flow
278
- collector.capture(flowFn, 'flow.'); // add capture flow events on a flow
279
-
280
- var events = collector.list(); // retrieve the list of events
281
- ```
282
-
283
- #### Alternate DSL's
181
+ See the [Advanced React](https://github.com/jeffbski/react/blob/master/doc/advanced.md) for details on the AST React uses for processing and other plugins that are available.
284
182
 
285
- Additional DSL's can be loaded by requiring them. See the [Alternate DSL](http://github.com/jeffbski/react/raw/master/doc/alternate-dsls.md) page for more info.
286
183
 
287
184
 
288
185
  ## Status
289
186
 
290
- - 2012-01-17 - Additional documentation (v0.3.4)
187
+ - 2012-03-12 - Pass ast.define events to process (v0.5.2)
188
+ - 2012-01-18 - Remove old DSL interfaces, improve plugin loading, log flow name with task name, ast.defined event, test with node 0.7.0 (v0.5.1)
189
+ - 2012-01-17 - Additional documentation (v0.3.5)
291
190
  - 2012-01-16 - Refine events and create logging plugin (v0.3.3)
292
191
  - 2012-01-13 - Add promise tasks, promise resolution, refactor alternate DSL interfaces as optional requires (v0.3.0)
293
192
  - 2012-01-11 - Provide warning/error when name is skipped in default DSL, literal check in validate (v0.2.5)
@@ -298,21 +197,18 @@ Additional DSL's can be loaded by requiring them. See the [Alternate DSL](http:/
298
197
  ## Test Results
299
198
 
300
199
  ```bash
301
- ok ast.test.js .................... 10/10
200
+ ok ast.test.js .................... 20/20
302
201
  ok cb-task.test.js ................ 31/31
303
202
  ok core-deferred.test.js .......... 11/11
304
203
  ok core-promised.test.js .......... 11/11
305
204
  ok core-when.test.js ................ 6/6
306
- ok core.test.js ................. 104/104
307
- ok chain.test.js .................. 74/74
308
- ok fstr.test.js ................... 67/67
309
- ok pcode.test.js .................. 94/94
205
+ ok core.test.js ................. 108/108
310
206
  ok dsl.test.js .................... 70/70
311
207
  ok event-manager.test.js .......... 13/13
312
208
  ok exec-options.test.js ............. 3/3
313
209
  ok finalcb-task.test.js ............. 5/5
314
210
  ok input-parser.test.js ........... 15/15
315
- ok module-use.test.js ............. 21/21
211
+ ok module-use.test.js ............. 24/24
316
212
  ok promise-auto-resolve.test.js ..... 4/4
317
213
  ok ret-task.test.js ............... 31/31
318
214
  ok task.test.js ..................... 1/1
@@ -320,7 +216,7 @@ ok validate-cb-task.test.js ......... 6/6
320
216
  ok validate-ret-task.test.js ........ 7/7
321
217
  ok validate.test.js ............... 31/31
322
218
  ok vcon.test.js ................... 55/55
323
- total ........................... 692/692
219
+ total ........................... 471/471
324
220
 
325
221
  ok
326
222
  ```
@@ -0,0 +1,166 @@
1
+ # Advanced React
2
+
3
+ <a name="directAST"/>
4
+ ## Example defining directly using AST
5
+
6
+ Defining flow directly using the AST. Additional DSL interfaces can be built by simply having them build the proper AST.
7
+
8
+
9
+ ```javascript
10
+ var react = require('react');
11
+
12
+ function load(res, cb) { setTimeout(cb, 100, null, res + '-loaded'); }
13
+ function prefix(prefstr, str, cb) { setTimeout(cb, 100, null, prefstr + str); }
14
+ function postfix(str, poststr, cb) { setTimeout(cb, 100, null, str + poststr); }
15
+ function upper(str) { return str.toUpperCase(); }
16
+
17
+ var fn = react();
18
+ var errors = fn.setAndValidateAST({
19
+ inParams: ['res', 'prefstr', 'poststr'],
20
+ tasks: [
21
+ { f: load, a: ['res'], out: ['lres'] },
22
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
23
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
24
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
25
+ ],
26
+ outTask: { a: ['plresp'] }
27
+ });
28
+ console.error('errors:', errors); // []
29
+
30
+ fn('foo', 'pre-', '-post', function cb(err, lres) {
31
+ console.error('err:', err); // null
32
+ console.error('lres:', lres); // pre-FOO-LOADED-post
33
+ });
34
+ ```
35
+
36
+
37
+ ## AST Definition
38
+
39
+ The abstract syntax tree or AST provided by React represents the data necessary to define the flow. By abstracting this from the DSL, it allows new skins or interfaces to be developed without need to change the core engine.
40
+
41
+ The AST is normally created at parse time when the React main function is called (or one of the alternate DSL's is called). This can be done a module load time such that after loading the React defined flow function's AST is generated and ready to process eliminating parsing and validation overhead when it is invoked in the future. This has the added advantage that since validation has also been performed that additional syntax issues or incomplete flow defintion errors can be caught quickly.
42
+
43
+ After the flow function has been created, you can review the generated AST for a function by accessing the ast.
44
+
45
+ ```javascript
46
+ var react = require('react');
47
+ var fn = react('my-flow-name', 'paramName1, paramName2, cb -> err, outParamName1, outParamName2',
48
+ functionRefOrMethodStr, 'paramName1, cb -> err, outParamName2', // async cb task
49
+ functionRefOrMethodStr2, 'paramName2, paramName1 -> outParamName1' // sync task
50
+ );
51
+
52
+ console.error(fn.ast); // output the generated AST
53
+ ```
54
+
55
+ The AST contains the following pieces:
56
+
57
+ ```javascript
58
+ var ast = {
59
+ name: flowName,
60
+ inParams: [],
61
+ tasks: [],
62
+ outTask: {},
63
+ locals: {}
64
+ };
65
+ ```
66
+ - **name** - string - represents the name of the flow or function that will be created. React will use the name when generating events so you can monitor progress and performance and also when errors occur.
67
+ - **inParams** - array of strings - the flow input parameter names (excluding the callback param)
68
+ - **tasks** - array of task defintion objects - each containing:
69
+ - **f** - function reference or method string - async or sync function to be used for this task
70
+ - **a** - array of input parameter names (excluding the callback param)
71
+ - **out** - array of output parameter names (excluding the err parame)
72
+ - **type** - type of function determining how function is invoked and its output style - one of: ('cb', 'ret', 'promise', 'when')
73
+ - **name** - string - unique name for each task provided or generated by React
74
+ - **outTask** - task definition object specifying the flow's output style and parameters containing:
75
+ - **f** - will contain reference to the callback function at runtime
76
+ - **a** - parameters being passed as output from the flow
77
+ - **locals** - object provided which contains additional values that will become part of the React variable space like input parameters but can be defined in advance at flow definition. This can be used to provide functions and objects to React enabling string based DSL's.
78
+
79
+
80
+ ## Plugins (optional requires which turn on additional functionality)
81
+
82
+ Additional functionality which is not enabled by default but available by requiring additional modules.
83
+
84
+
85
+ <a name="LogEvents"/>
86
+ ### LogEvents - log react progress to stderr
87
+
88
+ For convenience in debugging or in monitoring flow and performance, React has a built-in plugin for easily logging progress to stderr which is loaded and activated calling the react method `logEvents`. It can be specified to log globally for all react functions or only for particular react functions. You also may optionally listen to select events rather than all flow and task events.
89
+
90
+ ```javascript
91
+ var react = require('react');
92
+ react.logEvents(); // turn on flow and task logging for all react functions
93
+
94
+ // OR
95
+
96
+ react.logEvents(myReactFn); // turn on flow and task logging for a specific function, repeat as needed
97
+ react.logEvents(myReactFn).logEvents(myReactFn2); // can also chain
98
+
99
+ // Both methods can also take an optional event wildcard to specify what you want to listen to
100
+
101
+ react.logEvents('flow.*'); // turn on flow logging for all react functions
102
+ react.logEvents(myReactFn, 'task.*'); // turn on task logging for myReactFn
103
+ ```
104
+
105
+ Available Events that can be logged:
106
+
107
+ - flow.begin - flow execution has started (receives a flow env)
108
+ - flow.complete - flow execution has successfully completed (receives a flow env)
109
+ - flow.errored - flow execution has errored (receives a flow env)
110
+ - task.begin - task has started (receives task)
111
+ - task.complete - task has successfully complted (receives task)
112
+ - task.errored - task has errored (receives task)
113
+
114
+ ### Automatic Promise Resolution for inputs
115
+
116
+ If you want to automatically resolve promises in React without having to manually call `when` or `then`, React provides a plugin which will detect the existence of a `then` method (indicating a promise) at runtime from any inputs to the flow and will internally create `when` tasks to resolve them before passing the values to other tasks. This built-in plugin is not loaded normally but is loaded by invoking the react method `resolvePromises`. External plugins like `react-deferred` also enable this but also provide additional promise integration. See https://github.com/jeffbski/react-deferred
117
+
118
+ ```javascript
119
+ var react = require('react');
120
+ react.resolvePromises(); // turn on automatic promise detection and resolution
121
+ ```
122
+
123
+ ### Track tasks - enable task tracking
124
+
125
+ Instead of only logging events to stderr (like LogEvents), this built-in plugin fires events that can be directly monitored. The LogEvent plugin uses this internally to get access to the metrics.
126
+
127
+ Enable this like the other built-in plugins using the method `trackTasks`
128
+
129
+ ```javascript
130
+ var react = require('react');
131
+ react.trackTasks(); // turn on flow and task tracking events
132
+ ```
133
+
134
+ Available Events that can be consumed
135
+
136
+ - ast.defined - ast was defined (receives the ast)
137
+ - flow.begin - flow execution has started (receives a flow env)
138
+ - flow.complete - flow execution has successfully completed (receives a flow env)
139
+ - flow.errored - flow execution has errored (receives a flow env)
140
+ - task.begin - task has started (receives task)
141
+ - task.complete - task has successfully complted (receives task)
142
+ - task.errored - task has errored (receives task)
143
+
144
+
145
+ ### EventCollector - simple event accumulator for debug use
146
+
147
+ When developing or debugging it is often useful to accumulate events and then interrogate them to verify operation, especially in testing.
148
+
149
+ To make this easier to accomplish, this plugin provides a simple event accumulator for development use. Note that this accumulator is designed for short term debug use, as it will continue to accumulate events and does not have any size restrictions, it should not be used in production since it will just continue to grow in size unless manually cleared.
150
+
151
+ ```javascript
152
+ var EventCollector = require('react/lib/event-collector);
153
+ var collector = new EventCollector();
154
+
155
+ collector.capture(); // capture all flow and task events for all react flows
156
+ collector.capture('flow.*'); // capture all flow events for all react flows
157
+ collector.capture(flowFn, 'task.*'); // capture task events on a flow
158
+ collector.capture(flowFn, 'flow.*'); // add capture flow events on a flow
159
+
160
+ var events = collector.list(); // retrieve the list of events
161
+ collector.clear(); // clear the list of events;
162
+ ```
163
+
164
+ ### External Plugins
165
+
166
+ - https://github.com/jeffbski/react-deferred - integrates jQuery style Deferred/Promises with react, providing automatic promise resolution and optional usage for react functions where by calling without a callback returns a promise.