react 0.0.1 → 0.0.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.
package/README.md CHANGED
@@ -12,6 +12,8 @@ It takes inspiration from several projects including:
12
12
  - Tim Caswell and Elijah Insua's [conductor](https://github.com/creationix/conductor) - [Article](http://howtonode.org/step-of-conductor)
13
13
  - Caolan McMahon's [async](https://github.com/caolan/async)
14
14
 
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
+
15
17
  ## Goals
16
18
 
17
19
  - Improved error and exception handling
@@ -40,6 +42,14 @@ To reduce the boilerplate code needed and improve error handling, React automati
40
42
  - Validate the flow AST - determine if dependencies can all be met as defined such that flow will complete (TODO)
41
43
  - Execute the flow AST
42
44
 
45
+ ## Installing
46
+
47
+ npm install react
48
+
49
+ OR
50
+
51
+ Pull from github - http://github.com/jeffbski/react
52
+
43
53
  ## Examples
44
54
 
45
55
  1. [Direct AST](#directAST)
package/lib/react.js CHANGED
@@ -163,10 +163,15 @@ function react(inputDef){
163
163
  });
164
164
  tasksByName = nameTasks(tasks); //remap names to exec task copies instead of taskDefs
165
165
 
166
+ function getVar(name) { //get the name from the variable context, name might be simple or obj.prop
167
+ var nameAndProps = name.split('.');
168
+ return nameAndProps.reduce(function(accObj, prop){ return accObj[prop]; }, vCon); // vCon['foo']['bar']
169
+ }
170
+
166
171
 
167
172
  function execTask(t){
168
173
  t.status = STATUS.RUNNING;
169
- var args = t.a.map(function(k){ return vCon[k]; }); //get args from vCon
174
+ var args = t.a.map(function(k){ return getVar(k); }); //get args from vCon
170
175
  if (t.cbFun) args.push(t.cbFun); //push custom callback to back if fn uses cb
171
176
  if (reactOptions.debugOutput) console.log('starting task: %s', fName(t.f), args);
172
177
  try {
@@ -192,6 +197,17 @@ function react(inputDef){
192
197
  }
193
198
  } catch (e) { handleTaskError(t, e); } //catch and handle the task error, calling final cb
194
199
  }
200
+
201
+ function stripProp(objectWithOptionalPropertyName) { //return only object if object.property
202
+ return ( /\w+/ ).exec(objectWithOptionalPropertyName)[0];
203
+ }
204
+
205
+ function isTaskReady(t, idx, arr){
206
+ return !t.status && // filter for not started AND
207
+ t.a.every(function(k){ return (vCon[stripProp(k)] !== undefined); }) && // all dep vars defined AND
208
+ (!t.after || // (no dep tasks OR
209
+ t.after.every( function(n){ return tasksByName[n].status === STATUS.COMPLETE; })); //alldone
210
+ }
195
211
 
196
212
  contExec = function contExec(){
197
213
  if (firstError) { return; } //stop execution, we already hit an error
@@ -202,12 +218,7 @@ function react(inputDef){
202
218
  cbFinal.apply(null, finalArgs);
203
219
  return;
204
220
  }
205
- var tasksReady = tasks.filter(function(t, idx, arr){ //if we are here then we stil have tasks to run
206
- return !t.status && // filter for not started AND
207
- t.a.every(function(k){ return (vCon[k] !== undefined); }) && // all dep vars defined AND
208
- (!t.after || // (no dep tasks OR
209
- t.after.every( function(n){ return tasksByName[n].status === STATUS.COMPLETE; })); //alldone
210
- });
221
+ var tasksReady = tasks.filter(isTaskReady); //if we are here then we stil have tasks to run
211
222
  tasksReady.forEach(function(t){ t.status = STATUS.READY; }); //set ready before call, no double exec
212
223
  tasksReady.forEach(function(t){ execTask(t); });
213
224
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react",
3
3
  "description": "React is a javascript module to make it easier to work with asynchronous code, by reducing boilerplate code and improving error and exception handling while allowing variable and task dependencies when defining flow.",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "author": "Jeff Barczewski <jeff.barczewski@gmail.com>",
6
6
  "repository": { "type": "git", "url": "http://github.com/jeffbski/react.git" },
7
7
  "bugs" : { "url": "http://github.com/jeffbski/react/issues" },
@@ -4,8 +4,8 @@
4
4
  Example setting the AST directly without using define
5
5
  */
6
6
 
7
- var react = require('../react.js').react;
8
- var reactOptions = require('react').reactOptions;
7
+ var react = require(__dirname+'/../lib/react.js').react;
8
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
9
9
  reactOptions.debugOutput = true;
10
10
 
11
11
  function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
@@ -4,8 +4,8 @@
4
4
  Example using functions with the simple DSL
5
5
  */
6
6
 
7
- var react = require('../react.js').react;
8
- var reactOptions = require('react').reactOptions;
7
+ var react = require(__dirname+'/../lib/react.js').react;
8
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
9
9
  reactOptions.debugOutput = true;
10
10
  reactOptions.stackTraceLimitMin = 20;
11
11
 
@@ -4,8 +4,8 @@
4
4
  AST directly without define, using object methods in addition to functions
5
5
  */
6
6
 
7
- var react = require('../react.js').react;
8
- var reactOptions = require('react').reactOptions;
7
+ var react = require(__dirname+'/../lib/react.js').react;
8
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
9
9
  reactOptions.debugOutput = true;
10
10
 
11
11
 
@@ -4,8 +4,8 @@
4
4
  Using object methods in addition to functions with simple DSL
5
5
  */
6
6
 
7
- var react = require('../react.js').react;
8
- var reactOptions = require('react').reactOptions;
7
+ var react = require(__dirname+'/../lib/react.js').react;
8
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
9
9
  reactOptions.debugOutput = true;
10
10
  reactOptions.stackTraceLimitMin = 20;
11
11
 
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ AST directly without define, using object methods in addition to functions
5
+ also passing in an options object and referring to the properties.
6
+ The dependency is on the object existing, if it exists, it expects the values
7
+ to be there.
8
+ */
9
+
10
+ var react = require(__dirname+'/../lib/react.js').react;
11
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
12
+ reactOptions.debugOutput = true;
13
+
14
+
15
+ var UserMgr = function(){ };
16
+ UserMgr.prototype = {};
17
+ UserMgr.prototype.constructor = UserMgr;
18
+ UserMgr.prototype.loadUser = function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); };
19
+
20
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
21
+ function markdown(filedata) { return 'html'+filedata; }
22
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
23
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
24
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
25
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
26
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
27
+
28
+ function useHtml(err, html, user, bytesWritten) {
29
+ if(err) {
30
+ console.log('***Error: %s', err);
31
+ return;
32
+ }
33
+ console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
34
+ }
35
+
36
+ var r = react();
37
+ r.ast.inputNames = ['options', 'uid', 'anObj', 'cb'];
38
+ r.ast.taskDefs = [
39
+ { f:'anObj.loadUser', a:['uid'], cb:['user'] },
40
+ { f:loadFile, a:['options.filename'], cb:['filedata'] },
41
+ { f:markdown, a:['filedata'], ret:['html'] },
42
+ { f:prepareDirectory, a:['options.outDirname'],cb:['dircreated'] },
43
+ { f:writeOutput, a:['html', 'user'], cb:['bytesWritten'], after:['prepareDirectory'] },
44
+ { f:loadEmailTemplate, a:[], cb:['emailmd'] },
45
+ { f:markdown, a:['emailmd'], ret:['emailHtml'] },
46
+ { f:customizeEmail, a:['user', 'emailHtml'], ret:['custEmailHtml'] },
47
+ { f:deliverEmail, a:['custEmailHtml'], cb:['deliveredEmail'], after:['writeOutput'] }
48
+ ];
49
+ r.ast.finalOutputNames = ['html', 'user', 'bytesWritten'];
50
+
51
+ var myObj = new UserMgr();
52
+ r.exec({ filename: "hello.txt", outDirname: 'outHello' }, 100, myObj, useHtml);
53
+ r.exec({ filename: "small.txt", outDirname: 'outSmall' }, 200, myObj, useHtml);
54
+ r.exec({ filename: "world.txt", outDirname: 'outWorld' }, 300, myObj, useHtml);
55
+
56
+
57
+
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Using object methods in addition to functions with simple DSL
5
+ also passing in an options object and referring to the properties.
6
+ The dependency is on the object existing, if it exists, it expects the values
7
+ to be there.
8
+ */
9
+
10
+ var react = require(__dirname+'/../lib/react.js').react;
11
+ var reactOptions = require(__dirname+'/../lib/react.js').reactOptions;
12
+ reactOptions.debugOutput = true;
13
+ reactOptions.stackTraceLimitMin = 20;
14
+
15
+ var UserMgr = function(){ };
16
+ UserMgr.prototype = {};
17
+ UserMgr.prototype.constructor = UserMgr;
18
+ UserMgr.prototype.loadUser = function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); };
19
+
20
+ function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
21
+ function markdown(filedata) { return 'html'+filedata; }
22
+ function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
23
+ function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
24
+ function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
25
+ function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
26
+ function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
27
+
28
+ function useHtml(err, html, user, bytesWritten) {
29
+ if(err) {
30
+ console.log('***Error: %s', err);
31
+ return;
32
+ }
33
+ console.log('final result: %s, user: %s, written: %s', html, user, bytesWritten);
34
+ }
35
+
36
+ var r = react('options, uid, anObj, cb').define(
37
+ 'anObj.loadUser', 'uid -> err, user',
38
+ loadFile, 'options.filename -> err, filedata',
39
+ markdown, 'filedata -> returns html',
40
+ prepareDirectory, 'options.outDirname -> err, dircreated',
41
+ writeOutput, 'html, user -> err, bytesWritten', { after:prepareDirectory },
42
+ loadEmailTemplate,' -> err, emailmd',
43
+ markdown, 'emailmd -> returns emailHtml',
44
+ customizeEmail, 'user, emailHtml -> returns custEmailHtml',
45
+ deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput }
46
+ ).callbackDef('err, html, user, bytesWritten');
47
+
48
+
49
+ //console.log(r.ast);
50
+
51
+ var myObj = new UserMgr();
52
+ r.exec({ filename: "hello.txt", outDirname: 'outHello' }, 100, myObj, useHtml);
53
+ r.exec({ filename: "small.txt", outDirname: 'outSmall' }, 200, myObj, useHtml);
54
+ r.exec({ filename: "world.txt", outDirname: 'outWorld' }, 300, myObj, useHtml);
55
+
56
+