react 0.0.0-f77c7b9d7 → 0.1.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 (81) hide show
  1. package/.npmignore +5 -0
  2. package/Jakefile.js +8 -0
  3. package/LICENSE +5 -7
  4. package/README.md +242 -7
  5. package/examples/ast1.js +26 -0
  6. package/examples/chain-events1.js +34 -0
  7. package/examples/chain1.js +19 -0
  8. package/examples/fstr-events1.js +51 -0
  9. package/examples/fstr1.js +36 -0
  10. package/examples/pcode1.js +22 -0
  11. package/jake-tasks/jake-test.js +64 -0
  12. package/lib/base-task.js +115 -0
  13. package/lib/cb-task.js +67 -0
  14. package/lib/chain.js +148 -0
  15. package/lib/core.js +95 -0
  16. package/lib/error.js +37 -0
  17. package/lib/event-manager.js +57 -0
  18. package/lib/finalcb-first-task.js +59 -0
  19. package/lib/finalcb-task.js +54 -0
  20. package/lib/fstr.js +110 -0
  21. package/lib/id.js +10 -0
  22. package/lib/input-parser.js +44 -0
  23. package/lib/parse.js +28 -0
  24. package/lib/pcode.js +164 -0
  25. package/lib/ret-task.js +67 -0
  26. package/lib/status.js +5 -0
  27. package/lib/task.js +234 -0
  28. package/lib/validate.js +102 -0
  29. package/lib/vcon.js +76 -0
  30. package/oldExamples/analyze.js +29 -0
  31. package/oldExamples/analyze2.js +29 -0
  32. package/oldExamples/example10-dsl.js +63 -0
  33. package/oldExamples/example11.js +62 -0
  34. package/oldExamples/example12.js +63 -0
  35. package/oldExamples/example13.js +63 -0
  36. package/oldExamples/example14.js +63 -0
  37. package/oldExamples/example15.js +75 -0
  38. package/oldExamples/example6-ast.js +47 -0
  39. package/oldExamples/example6-dsl.js +49 -0
  40. package/oldExamples/example8-ast.js +55 -0
  41. package/oldExamples/example8-dsl.js +53 -0
  42. package/oldExamples/example9-ast.js +58 -0
  43. package/oldExamples/example9-dsl.js +57 -0
  44. package/oldExamples/function-str-ex1.js +33 -0
  45. package/oldExamples/function-str-ex2.js +67 -0
  46. package/oldExamples/trait1.js +41 -0
  47. package/oldExamples/trait2.js +44 -0
  48. package/package.json +18 -34
  49. package/react.js +12 -0
  50. package/test/ast.test.js +69 -0
  51. package/test/cb-task.test.js +197 -0
  52. package/test/chain.test.js +239 -0
  53. package/test/core.test.js +519 -0
  54. package/test/event-manager.test.js +102 -0
  55. package/test/exec-options.test.js +32 -0
  56. package/test/finalcb-task.test.js +37 -0
  57. package/test/fstr.test.js +288 -0
  58. package/test/input-parser.test.js +62 -0
  59. package/test/module-use.test.js +271 -0
  60. package/test/pcode.test.js +321 -0
  61. package/test/ret-task.test.js +199 -0
  62. package/test/task.test.js +21 -0
  63. package/test/validate-cb-task.test.js +74 -0
  64. package/test/validate-ret-task.test.js +83 -0
  65. package/test/validate.test.js +218 -0
  66. package/test/vcon.test.js +160 -0
  67. package/build-info.json +0 -8
  68. package/cjs/react-jsx-dev-runtime.development.js +0 -1200
  69. package/cjs/react-jsx-dev-runtime.production.min.js +0 -9
  70. package/cjs/react-jsx-dev-runtime.profiling.min.js +0 -9
  71. package/cjs/react-jsx-runtime.development.js +0 -1218
  72. package/cjs/react-jsx-runtime.production.min.js +0 -10
  73. package/cjs/react-jsx-runtime.profiling.min.js +0 -10
  74. package/cjs/react.development.js +0 -2330
  75. package/cjs/react.production.min.js +0 -23
  76. package/index.js +0 -7
  77. package/jsx-dev-runtime.js +0 -7
  78. package/jsx-runtime.js +0 -7
  79. package/umd/react.development.js +0 -3562
  80. package/umd/react.production.min.js +0 -31
  81. package/umd/react.profiling.min.js +0 -38
package/.npmignore ADDED
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ npm-debug.log
3
+ ./npmrc
4
+ todo.md
5
+ notes.md
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/LICENSE CHANGED
@@ -1,6 +1,4 @@
1
- MIT License
2
-
3
- Copyright (c) Facebook, Inc. and its affiliates.
1
+ Copyright (c) 2011 Jeff Barczewski
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
4
  of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
7
  copies of the Software, and to permit persons to whom the Software is
10
8
  furnished to do so, subject to the following conditions:
11
9
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
14
12
 
15
13
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
14
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
15
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
16
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
17
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,13 +1,248 @@
1
- # `react`
1
+ # React.js
2
2
 
3
- React is a JavaScript library for creating user interfaces.
3
+ React is a javascript module to make it easier to work with asynchronous code,
4
+ by reducing boilerplate code and improving error and exception handling while
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.
4
8
 
5
- The `react` package contains only the functionality necessary to define React components. It is typically used together with a React renderer like `react-dom` for the web, or `react-native` for the native environments.
9
+ This async flow control module is initially designed to work with Node.js but
10
+ is planned to be extended to browser and other environments.
6
11
 
7
- **Note:** by default, React will be in development mode. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages. Don't forget to use the [production build](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build) when deploying your application.
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.
8
13
 
9
- ## Example Usage
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
10
15
 
11
- ```js
12
- var React = require('react');
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:
21
+
22
+ - Tim Caswell and Elijah Insua's [conductor](https://github.com/creationix/conductor) - [Article](http://howtonode.org/step-of-conductor)
23
+ - Caolan McMahon's [async](https://github.com/caolan/async)
24
+
25
+
26
+ ## Goals
27
+
28
+ - Improved error and exception handling
29
+ - Provide useful stack traces and context information for easier debugging
30
+ - Minimize boilerplate code needed for working with asynchronous functions
31
+ - Make code more readable and easier to understand which should translate to less defects
32
+ - Provide the right level of abstraction to make it easier to refactor code, without being too magical
33
+ - Allow the mixing of pure functions, method calls, and callback style functions in the flow
34
+ - 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.
49
+
50
+ ## Concept
51
+
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.
53
+
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.
55
+
56
+ To reduce the boilerplate code needed and improve error handling, React automatically provides callback functions for your asynchronous code. These React-provided callback functions perform these steps:
57
+
58
+ 1. check for error and handle by calling outer callback function with this error after augmenting it with additional context information for easier debugging
59
+ 2. save the callback variables into a context for future reference
60
+ 3. call back into React (and it will kick off additional tasks that are now ready to go)
61
+
62
+ ## Design
63
+
64
+ - Parse and validate ad 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 params
67
+
68
+ ## Installing
69
+
70
+ npm install react
71
+
72
+ OR
73
+
74
+ Pull from github - http://github.com/jeffbski/react
75
+
76
+ ## Examples
77
+
78
+ 1. [Direct AST](#directAST)
79
+ 2. [Using Function Str DSL](#fstr)
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="directAST"/>
89
+ ### Example directly using AST
90
+
91
+ ```javascript
92
+ var react = require('react');
93
+
94
+ function load(res, cb) { setTimeout(cb, 100, null, res + '-loaded'); }
95
+ function prefix(prefstr, str, cb) { setTimeout(cb, 100, null, prefstr + str); }
96
+ function postfix(str, poststr, cb) { setTimeout(cb, 100, null, str + poststr); }
97
+ function upper(str) { return str.toUpperCase(); }
98
+
99
+ var fn = react();
100
+ var errors = fn.setAndValidateAST({
101
+ inParams: ['res', 'prefstr', 'poststr'],
102
+ tasks: [
103
+ { f: load, a: ['res'], out: ['lres'] },
104
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
105
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
106
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
107
+ ],
108
+ outTask: { a: ['plresp'] }
109
+ });
110
+ console.error('errors:', errors); // []
111
+
112
+ fn('foo', 'pre-', '-post', function cb(err, lres) {
113
+ console.error('err:', err); // null
114
+ console.error('lres:', lres); // pre-FOO-LOADED-post
115
+ });
116
+ ```
117
+
118
+ <a name="fstr"/>
119
+ ### Example using Function String DSL interface
120
+
121
+ ```javascript
122
+ var react = require('react');
123
+
124
+ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
125
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
126
+ function markdown(filedata) { return 'html'+filedata; }
127
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
128
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
129
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
130
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
131
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
132
+
133
+ function useHtml(err, html, user, bytesWritten) {
134
+ if(err) {
135
+ console.log('***Error: %s', err);
136
+ return;
137
+ }
138
+ console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
139
+ }
140
+
141
+ var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
142
+ loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
143
+ loadFile, 'filename -> err, filedata',
144
+ markdown, 'filedata -> returns html', // using a sync function
145
+ prepareDirectory, 'outDirname -> err, dircreated',
146
+ writeOutput, 'html, user -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
147
+ loadEmailTemplate, ' -> err, emailmd',
148
+ markdown, 'emailmd -> returns emailHtml', // using a sync function
149
+ customizeEmail, 'user, emailHtml -> returns custEmailHtml',
150
+ deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
151
+ ], 'err, html, user, bytesWritten'); // callback output params
152
+
153
+ loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
154
+ ```
155
+
156
+ <a name="pcode"/>
157
+ ### Example using pseudocode DSL interface
158
+
159
+ ```javascript
160
+ var react = require('react');
161
+
162
+ function multiply(a, b, cb) { cb(null, a * b); }
163
+ function add(a, b) { return a + b; }
164
+ var locals = { // since pcodeDefine uses strings, need references to functions passed into react
165
+ multiply: multiply,
166
+ add: add
167
+ };
168
+
169
+ var fn = react.pcodeDefine('a, b, cb', [ // input params
170
+ 'm := multiply(a, b)', // using a callback function, use :=
171
+ 's = add(m, a)', // using a sync function, use =
172
+ 'cb(err, m, s)' // output params for final callback
173
+ ], locals); // hash of functions that will be used
174
+
175
+ fn(2, 3, function (err, m, s) {
176
+ console.error('err:', err); // null
177
+ console.error('m:', m); // 2 * 3 = 6
178
+ console.error('s:', s); // 6 + 2 = 8
179
+ });
180
+ ```
181
+
182
+ <a name="chain"/>
183
+ ### Example using jquery-like chaining DSL interface
184
+
185
+ ```javascript
186
+ var react = require('react');
187
+
188
+ function multiply(a, b, cb) { cb(null, a * b); }
189
+ function add(a, b) { return a + b; }
190
+
191
+ var fn = react.chainDefine()
192
+ .in('a', 'b', 'cb') // input params
193
+ .out('err', 'm', 's') // final callback output params
194
+ .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
195
+ .sync(add).in('m', 'a').out('s') // task def - sync fn, in params, return value
196
+ .end();
197
+
198
+ fn(2, 3, function (err, m, s) {
199
+ console.error('err:', err); // null
200
+ console.error('m:', m); // 2 * 3 = 6
201
+ console.error('s:', s); // 6 + 2 = 8
202
+ });
203
+ ```
204
+
205
+ ## Status
206
+
207
+ - 2011-12-21 - Refactor from ground up with tests, changes to the interfaces
208
+ - 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.
209
+
210
+ ## Test Results
211
+
212
+ ```bash
213
+ ok ast.test.js .................... 10/10
214
+ ok cb-task.test.js ................ 31/31
215
+ ok chain.test.js .................. 56/56
216
+ ok core.test.js ................... 98/98
217
+ ok event-manager.test.js .......... 13/13
218
+ ok exec-options.test.js ............. 3/3
219
+ ok finalcb-task.test.js ............. 5/5
220
+ ok fstr.test.js ................... 64/64
221
+ ok input-parser.test.js ........... 15/15
222
+ ok module-use.test.js ............. 55/55
223
+ ok pcode.test.js .................. 65/65
224
+ ok ret-task.test.js ............... 31/31
225
+ ok task.test.js ..................... 1/1
226
+ ok validate-cb-task.test.js ......... 6/6
227
+ ok validate-ret-task.test.js ........ 7/7
228
+ ok validate.test.js ............... 26/26
229
+ ok vcon.test.js ................... 42/42
230
+ total ........................... 545/545
231
+
232
+ ok
13
233
  ```
234
+
235
+ ## License
236
+
237
+ - [MIT license](http://github.com/jeffbski/react/raw/master/LICENSE)
238
+
239
+ ## Contributors
240
+
241
+ - Author: Jeff Barczewski (@jeffbski)
242
+
243
+ ## Contributing
244
+
245
+ - Source code repository: http://github.com/jeffbski/react
246
+ - Ideas and pull requests are encouraged - http://github.com/jeffbski/react/issues
247
+
248
+ - 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
+ });
@@ -0,0 +1,51 @@
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 loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
21
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
22
+ function markdown(filedata) { return 'html'+filedata; }
23
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
24
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
25
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
26
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
27
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
28
+
29
+ function useHtml(err, html, user, bytesWritten) {
30
+ if(err) {
31
+ console.log('***Error: %s', err);
32
+ return;
33
+ }
34
+ console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
35
+ }
36
+
37
+ var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
38
+ loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
39
+ loadFile, 'filename -> err, filedata',
40
+ markdown, 'filedata -> returns html', // using a sync function
41
+ prepareDirectory, 'outDirname -> err, dircreated',
42
+ writeOutput, 'html, user -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
43
+ loadEmailTemplate, ' -> err, emailmd',
44
+ markdown, 'emailmd -> returns emailHtml', // using a sync function
45
+ customizeEmail, 'user, emailHtml -> returns custEmailHtml',
46
+ deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
47
+ ], 'err, html, user, bytesWritten'); // callback output params
48
+
49
+ loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
50
+
51
+
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ var react = require('../'); // require('react');
4
+
5
+ function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
6
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
7
+ function markdown(filedata) { return 'html'+filedata; }
8
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
9
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
10
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
11
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
12
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
13
+
14
+ function useHtml(err, html, user, bytesWritten) {
15
+ if(err) {
16
+ console.log('***Error: %s', err);
17
+ return;
18
+ }
19
+ console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
20
+ }
21
+
22
+ var loadAndSave = react.fstrDefine('filename, uid, outDirname, cb', [ // input params
23
+ loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
24
+ loadFile, 'filename -> err, filedata',
25
+ markdown, 'filedata -> returns html', // using a sync function
26
+ prepareDirectory, 'outDirname -> err, dircreated',
27
+ writeOutput, 'html, user -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
28
+ loadEmailTemplate, ' -> err, emailmd',
29
+ markdown, 'emailmd -> returns emailHtml', // using a sync function
30
+ customizeEmail, 'user, emailHtml -> returns custEmailHtml',
31
+ deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
32
+ ], 'err, html, user, bytesWritten'); // callback output params
33
+
34
+ loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
35
+
36
+