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/lib/vcon.js CHANGED
@@ -71,7 +71,7 @@ VContext.create = function (args, inParams, locals, self) {
71
71
  var vContext = new VContext();
72
72
  vContext.values = args.reduce(function (vcon, x, idx) { // create vCon start with input args
73
73
  var param = inParams[idx];
74
- if (param) vcon[param] = x;
74
+ if (param) vcon[param] = (x !== undefined) ? x : null; // upgrade undefined to null
75
75
  return vcon;
76
76
  }, initValues);
77
77
  return vContext;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react",
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.3.4",
3
+ "description": "React is a javascript module implementing a lightweight rules engine 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.5.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" },
package/react.js CHANGED
@@ -2,7 +2,39 @@
2
2
 
3
3
  var core = require('./lib/core.js');
4
4
 
5
+ /**
6
+ If called, load the built-in plugin for log events and invoke
7
+
8
+ @param flowFn [function] if not provided uses global react
9
+ @param eventWildcard [string] pattern to log events for
10
+ */
11
+ function logEvents(flowFn, eventWildcard) {
12
+ var logEventsMod = require('./lib/log-events');
13
+ if (!eventWildcard && typeof(flowFn) === 'string') { // only wildcard provided
14
+ eventWildcard = flowFn;
15
+ flowFn = undefined;
16
+ }
17
+ return logEventsMod.logEvents(flowFn, eventWildcard);
18
+ }
19
+
20
+ /**
21
+ Enable detection of promises and resolution
22
+ */
23
+ function resolvePromises() {
24
+ require('./lib/promise-resolve');
25
+ }
26
+
27
+ /**
28
+ Enable tracking of tasks and flow execution, emitting events and
29
+ tracking start, end, elapsed time
30
+ */
31
+ function trackTasks() {
32
+ require('./lib/track-tasks');
33
+ }
34
+
5
35
  module.exports = require('./lib/dsl.js'); // core + default dsl
6
36
  module.exports.options = core.options; // global react options
7
37
  module.exports.events = core.events; // global react event emitter
8
-
38
+ module.exports.logEvents = logEvents; // enable event logging
39
+ module.exports.resolvePromises = resolvePromises; // enable promise resolution
40
+ module.exports.trackTasks = trackTasks; // enable tracking of tasks
package/test/ast.test.js CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  var test = require('tap').test;
4
4
 
5
- var react = require('../react');
5
+ var react = require('../'); // require('react');
6
+ var EventCollector = require('../lib/event-collector');
6
7
 
7
8
  function load(res, cb) { cb(null, res + '-loaded'); }
8
9
  function prefix(prefstr, str, cb) { cb(null, prefstr + str); }
@@ -38,6 +39,54 @@ test('mixed', function (t) {
38
39
  });
39
40
  });
40
41
 
42
+ test('ast.defined event called when ast is defined', function (t) {
43
+ var fn = react();
44
+ var collector = new EventCollector();
45
+ collector.capture(fn, 'ast.*');
46
+
47
+ var errors = fn.setAndValidateAST({
48
+ inParams: ['res', 'prefstr', 'poststr'],
49
+ tasks: [
50
+ { f: load, a: ['res'], out: ['lres'] },
51
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
52
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
53
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
54
+ ],
55
+ outTask: { a: ['plresp'] }
56
+ });
57
+
58
+ var events = collector.list();
59
+ t.equal(events.length, 1);
60
+ t.type(events[0].ast, 'object');
61
+ t.ok(events[0].ast.inParams);
62
+ t.ok(events[0].ast.tasks);
63
+ t.ok(events[0].ast.outTask);
64
+ t.end();
65
+ });
66
+
67
+ test('ast.defined event is passed to process', function (t) {
68
+ t.plan(5);
69
+ var fn = react();
70
+ process.once('ast.defined', function (ast) {
71
+ t.type(ast, 'object');
72
+ t.ok(ast.inParams);
73
+ t.ok(ast.tasks);
74
+ t.ok(ast.outTask);
75
+ t.deepEqual(ast.inParams, ['res', 'prefstr', 'poststr']);
76
+ t.end();
77
+ });
78
+ var errors = fn.setAndValidateAST({
79
+ inParams: ['res', 'prefstr', 'poststr'],
80
+ tasks: [
81
+ { f: load, a: ['res'], out: ['lres'] },
82
+ { f: upper, a: ['lres'], out: ['ulres'], type: 'ret' },
83
+ { f: prefix, a: ['prefstr', 'ulres'], out: ['plres'] },
84
+ { f: postfix, a: ['plres', 'poststr'], out: ['plresp'] }
85
+ ],
86
+ outTask: { a: ['plresp'] }
87
+ });
88
+ });
89
+
41
90
  test('cb with err', function (t) {
42
91
  t.plan(5);
43
92
 
package/test/core.test.js CHANGED
@@ -3,13 +3,14 @@
3
3
  var test = require('tap').test;
4
4
 
5
5
  var react = require('../react');
6
- var EventCollector = require('../lib/track-tasks').EventCollector; // require('react/lib/track-tasks'); // turn on tracking
6
+ var EventCollector = require('../lib/event-collector'); // require('react/lib/event-collector'); // turn on tracking and get EventCollector
7
7
 
8
8
  function multiply(x, y, cb) { cb(null, x * y); }
9
9
  function add(x, y, cb) { cb(null, x + y); }
10
10
  function badFunc(a, b, cb) { throw new Error('badFuncThrow'); }
11
11
  function badF2(a, b, cb) { cb('my-error'); }
12
12
  function fnRetsSum(a, b) { return a + b; }
13
+ var anonFn = function (a, b) { return a + b; };
13
14
 
14
15
  test('set and validate AST', function (t) {
15
16
  var fn = react();
@@ -42,16 +43,19 @@ test('unnamed tasks will be assigned unique names', function (t) {
42
43
  { f: multiply, a: ['a', 'b'], out: ['c'] },
43
44
  { f: multiply, a: ['a', 'b'], out: ['d'], name: 'multiply' },
44
45
  { f: multiply, a: ['a', 'b'], out: ['e'], name: 'times' },
46
+ { f: anonFn, a: ['a', 'b'], out: ['g'], type: 'ret' },
45
47
  { f: multiply, a: ['a', 'b'], out: ['f'] }
46
48
  ],
47
49
  outTask: { a: ['c'] }
48
50
  });
49
51
  t.deepEqual(errors, [], 'should set and validate as true');
52
+ t.equal(fn.ast.name.slice(0, 'flow_'.length), 'flow_', 'generated flow name should start with flow_');
50
53
  t.deepEqual(fn.ast.tasks, [
51
54
  { f: multiply, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'multiply_0' },
52
55
  { f: multiply, a: ['a', 'b'], out: ['d'], name: 'multiply', type: 'cb' },
53
56
  { f: multiply, a: ['a', 'b'], out: ['e'], name: 'times', type: 'cb' },
54
- { f: multiply, a: ['a', 'b'], out: ['f'], type: 'cb', name: 'multiply_3' }
57
+ { f: anonFn, a: ['a', 'b'], out: ['g'], type: 'ret', name: 'task_3' },
58
+ { f: multiply, a: ['a', 'b'], out: ['f'], type: 'cb', name: 'multiply_4' }
55
59
  ]);
56
60
  t.end();
57
61
  });
@@ -431,6 +435,27 @@ test('using "this" in a sync function', function (t) {
431
435
  }]);
432
436
  });
433
437
 
438
+ test('undefined input arguments will be upgraded from undefined to null', function (t) {
439
+ var fn = react();
440
+ function concat(a, b) {
441
+ return '' + a + b;
442
+ }
443
+ var errors = fn.setAndValidateAST({
444
+ inParams: ['a', 'b'],
445
+ tasks: [
446
+ { f: concat, a: ['a', 'b'], out: ['c'], type: 'ret' }
447
+ ],
448
+ outTask: { a: ['c'] }
449
+ });
450
+ t.deepEqual(errors, [], 'no validation errors');
451
+ fn('first', undefined, function (err, c) { // undefined second param, upgrade to null
452
+ t.equal(err, null);
453
+ t.equal(c, 'firstnull');
454
+ t.end();
455
+ });
456
+ });
457
+
458
+
434
459
 
435
460
  // Select first tests
436
461
 
package/test/dsl.test.js CHANGED
@@ -16,7 +16,7 @@ test('module exports is a fn with properties', function (t) {
16
16
 
17
17
  test('no arguments -> empty name, inParams, tasks, outTask', function (t) {
18
18
  var r = react();
19
- t.equal(r.ast.name, undefined);
19
+ t.equal(r.ast.name.slice(0, 'flow_'.length), 'flow_', 'generated flow name should start with flow_');
20
20
  t.deepEqual(r.ast.inParams, []);
21
21
  t.deepEqual(r.ast.tasks, []);
22
22
  t.deepEqual(r.ast.outTask, { a: [], type: 'finalcb' });
@@ -26,7 +26,7 @@ test('no arguments -> empty name, inParams, tasks, outTask', function (t) {
26
26
 
27
27
  test('empty first string -> empty name, inParams, tasks, outTask', function (t) {
28
28
  var r = react('');
29
- t.equal(r.ast.name, '');
29
+ t.equal(r.ast.name.slice(0, 'flow_'.length), 'flow_', 'generated flow name should start with flow_');
30
30
  t.deepEqual(r.ast.inParams, []);
31
31
  t.deepEqual(r.ast.tasks, []);
32
32
  t.deepEqual(r.ast.outTask, { a: [], type: 'finalcb' });
@@ -4,8 +4,8 @@ var test = require('tap').test;
4
4
  var BaseTask = require('../lib/base-task.js');
5
5
 
6
6
  var react = require('../'); // require('react');
7
- // turn on tracking, optionally obtain EventCollector
8
- var EventCollector = require('../lib/track-tasks').EventCollector; // require('react/lib/track-tasks');
7
+ // turn on tracking, obtain EventCollector
8
+ var EventCollector = require('../lib/event-collector'); // require('react/lib/event-collector');
9
9
 
10
10
 
11
11
  /**
@@ -39,6 +39,9 @@ test('module exports an function object with properties', function (t) {
39
39
  t.type(react, 'function', 'is a core constructor and default dsl function');
40
40
  t.type(react.options, 'object', 'has property for global react options');
41
41
  t.type(react.events, 'object', 'has global react event manager');
42
+ t.type(react.logEvents, 'function', 'has function to enable event logging');
43
+ t.type(react.trackTasks, 'function', 'has function to enable task and flow tracking');
44
+ t.type(react.resolvePromises, 'function', 'has fn to enable promise detection & resolution');
42
45
  t.end();
43
46
  });
44
47
 
@@ -8,7 +8,8 @@
8
8
  var test = require('tap').test;
9
9
  var Deferred = require('promised-io/promise').Deferred;
10
10
 
11
- var react = require('../promise-resolve'); // require('react/promise-resolve');
11
+ var react = require('../'); // require('react');
12
+ react.resolvePromises(); // enable promise resolving
12
13
 
13
14
  function multiply(x, y, cb) { cb(null, x * y); }
14
15
  function add(x, y, cb) { cb(null, x + y); }
package/Jakefile.js DELETED
@@ -1,8 +0,0 @@
1
-
2
-
3
- require('./jake-tasks/jake-test.js');
4
-
5
- desc('Default - run watch');
6
- task('default', ['test:watch']);
7
-
8
-
@@ -1,103 +0,0 @@
1
- # Alternate DSL's
2
-
3
- These DSL's are not loaded by default and thus require a separate require if you want to use one.
4
-
5
- Since React is an AST based rules system, it allows custom DSL's to be created easily, they only need to generate the AST and they are fully functional, allowing many different interfaces for the same system.
6
-
7
-
8
- ### Examples using the AST directly or alternate DSL's
9
-
10
-
11
- 1. [Using pseudocode DSL](#pcode)
12
- 2. [Using jquery-like chaining DSL](#chain)
13
- 3. [Function String DSL](#fstr) (Deprecated)
14
-
15
-
16
- <a name="pcode"/>
17
- ### Example using pseudocode DSL interface
18
-
19
- ```javascript
20
- var pcodeDefine = require('react/dsl/pcode');
21
-
22
- function multiply(a, b, cb) { cb(null, a * b); }
23
- function add(a, b) { return a + b; }
24
- var locals = { // since pcodeDefine uses strings, need references to functions passed into react
25
- multiply: multiply,
26
- add: add
27
- };
28
-
29
- var fn = pcodeDefine('a, b, cb', [ // input params
30
- 'm := multiply(a, b)', // using a callback function, use :=
31
- 's = add(m, a)', // using a sync function, use =
32
- 'cb(err, m, s)' // output params for final callback
33
- ], locals); // hash of functions that will be used
34
-
35
- fn(2, 3, function (err, m, s) {
36
- console.error('err:', err); // null
37
- console.error('m:', m); // 2 * 3 = 6
38
- console.error('s:', s); // 6 + 2 = 8
39
- });
40
- ```
41
-
42
- <a name="chain"/>
43
- ### Example using jquery-like chaining DSL interface
44
-
45
- ```javascript
46
- var chainDefine = require('react/dsl/chain');
47
-
48
- function multiply(a, b, cb) { cb(null, a * b); }
49
- function add(a, b) { return a + b; }
50
-
51
- var fn = chainDefine()
52
- .in('a', 'b', 'cb') // input params
53
- .out('err', 'm', 's') // final callback output params
54
- .async(multiply).in('a', 'b', 'cb').out('err', 'm') // task def - async fn, in params, callback out params
55
- .sync(add).in('m', 'a').out('s') // task def - sync fn, in params, return value
56
- .end();
57
-
58
- fn(2, 3, function (err, m, s) {
59
- console.error('err:', err); // null
60
- console.error('m:', m); // 2 * 3 = 6
61
- console.error('s:', s); // 6 + 2 = 8
62
- });
63
- ```
64
-
65
- <a name="fstr"/>
66
- ### Example using Function String DSL interface
67
-
68
- The Function String DSL interface is deprecated since it morphed into the default DSL which is very similar. It is recommended that you use the default DSL instead.
69
-
70
- ```javascript
71
- var fstrDefine = require('react/dsl/fstr');
72
-
73
- function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
74
- function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
75
- function markdown(filedata) { return 'html'+filedata; }
76
- function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
77
- function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
78
- function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
79
- function customizeEmail(user, emailHtml, cb) { return 'cust-'+user+emailHtml; }
80
- function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
81
-
82
- function useHtml(err, html, user, bytesWritten) {
83
- if(err) {
84
- console.log('***Error: %s', err);
85
- return;
86
- }
87
- console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
88
- }
89
-
90
- var loadAndSave = fstrDefine('filename, uid, outDirname, cb', [ // input params
91
- loadUser, 'uid -> err, user', // calling async fn loadUser with uid, callback is called with err and user
92
- loadFile, 'filename -> err, filedata',
93
- markdown, 'filedata -> returns html', // using a sync function
94
- prepareDirectory, 'outDirname -> err, dircreated',
95
- writeOutput, 'html, user -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
96
- loadEmailTemplate, ' -> err, emailmd',
97
- markdown, 'emailmd -> returns emailHtml', // using a sync function
98
- customizeEmail, 'user, emailHtml -> returns custEmailHtml',
99
- deliverEmail, 'custEmailHtml -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
100
- ], 'err, html, user, bytesWritten'); // callback output params
101
-
102
- loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
103
- ```
package/dsl/chain.js DELETED
@@ -1,150 +0,0 @@
1
- 'use strict';
2
-
3
- var sprintf = require('sprintf').sprintf;
4
- var core = require('../lib/core.js');
5
- var tutil = require('../lib/task.js');
6
-
7
- // err for task type cb is implied and thus optional, but allow for clarity.
8
- var ERROR_NAMES_RE = /^err$/i; // first out param matching this is skipped as being the err object
9
-
10
- // callback is implied for task type cb is implied and thus optional, but allow for clarity.
11
- var CALLBACK_NAMES_RE = /^cb$|^callback$/i; // last in param matching this is skipped as being the cb
12
-
13
- var FlowBuilder;
14
-
15
- /**
16
- jQuery-like chain interface for defining flow
17
-
18
- @example
19
- // normal flow
20
- var react = require('react');
21
- var fn = react.chainDefine()
22
- .in('filename', 'uid', 'outDirname', 'cb')
23
- .out('err', 'html', 'user', 'bytesWritten')
24
- .async(loadUser) .in('uid') .out('err', 'user')
25
- .async(loadFile) .in('filename') .out('err', 'filedata')
26
- .sync(markdown) .in('filedata') .out('html')
27
- .async(prepareDirectory) .in('outDirname') .out('err', 'dircreated')
28
- .async(writeOutput) .in('html', 'user') .out('err', 'bytesWritten') .after('prepareDirectory')
29
- .async(loadEmailTemplate) .in() .out('err', 'emailmd')
30
- .sync(markdown) .in('emailmd') .out('emailHtml')
31
- .sync(customizeEmail) .in('user', 'emailHtml') .out('custEmailHtml')
32
- .async(deliverEmail) .in('custEmailHtml') .out('err', 'deliveredEmail') .after('writeOutput')
33
- .end();
34
-
35
- @example
36
- // selectFirst flow
37
- var fn = chainDefine()
38
- .selectFirst()
39
- .in('a', 'b', 'cb')
40
- .out('err', 'c')
41
- .async(falpha).in('a', 'b', 'cb').out('err', 'c')
42
- .sync(fbeta).in('a', 'b').out('c')
43
- .end();
44
- */
45
- function chainDefine() {
46
- return FlowBuilder.create();
47
- }
48
-
49
- function FlowBuilder() {
50
- this.main = {
51
- name: null,
52
- options: {}
53
- };
54
- this.tasks = [];
55
- this.focus = this.main;
56
- }
57
-
58
- FlowBuilder.create = function () { return new FlowBuilder(); };
59
-
60
- FlowBuilder.prototype.selectFirst = function () {
61
- this.main.outTaskType = 'finalcbFirst';
62
- return this;
63
- };
64
-
65
- FlowBuilder.prototype.name = function (name) {
66
- this.focus.name = name;
67
- return this;
68
- };
69
-
70
- FlowBuilder.prototype.in = function (param1, param2, paramN) {
71
- var args = Array.prototype.slice.call(arguments);
72
- if (args.length && this.focus.type !== 'ret') { // has args and cb or main
73
- if (args[args.length - 1].match(CALLBACK_NAMES_RE)) args.pop(); // pop off the cb name if specified
74
- }
75
- if (this.focus === this.main) this.focus.in = args;
76
- else this.focus.a = args; // for tasks
77
- return this;
78
- };
79
-
80
- FlowBuilder.prototype.out = function (param1, param2, paramN) {
81
- var args = Array.prototype.slice.call(arguments);
82
- if (args.length && this.focus.type !== 'ret') { // has args and cb or main
83
- if (args[0].match(ERROR_NAMES_RE)) args.shift(); // shift off err if specified
84
- }
85
- this.focus.out = args;
86
- return this;
87
- };
88
-
89
- FlowBuilder.prototype.options = function (options) {
90
- var self = this;
91
- if (this.focus === this.main) {
92
- Object.keys(options).forEach(function (k) { self.focus.options[k] = options[k]; });
93
- } else { // task so set options right on task
94
- Object.keys(options).forEach(function (k) { self.focus[k] = options[k]; });
95
- }
96
- return this;
97
- };
98
-
99
- FlowBuilder.prototype.async = function (funcOrStrMethod) {
100
- var task = { f: funcOrStrMethod, type: 'cb' };
101
- this.tasks.push(task);
102
- this.focus = task;
103
- return this;
104
- };
105
-
106
- FlowBuilder.prototype.sync = function (funcOrStrMethod) {
107
- var task = { f: funcOrStrMethod, type: 'ret' };
108
- this.tasks.push(task);
109
- this.focus = task;
110
- return this;
111
- };
112
-
113
- FlowBuilder.prototype.after = function (name1, name2, nameN) {
114
- this.focus.after = Array.prototype.slice.call(arguments);
115
- return this;
116
- };
117
-
118
- /**
119
- Complete the building of a flow and perform validation
120
- which throws error if flow is not valid.
121
- */
122
- FlowBuilder.prototype.end = function end() {
123
- var reactFn = core();
124
-
125
- if (this.main.outTaskType === 'finalcbFirst') {
126
- this.tasks = tutil.serializeTasks(this.tasks);
127
- }
128
-
129
- var ast = {
130
- inParams: this.main.in || [],
131
- tasks: this.tasks,
132
- outTask: {
133
- a: this.main.out || [],
134
- type: this.main.outTaskType || 'finalcb'
135
- }
136
- };
137
- if (this.main.name) ast.name = this.main.name;
138
- var self = this;
139
- Object.keys(this.main.options).forEach(function (k) { ast[k] = self.main.options[k]; });
140
- var errors = reactFn.setAndValidateAST(ast);
141
- if (errors.length) {
142
- var errorStr = errors.join('\n');
143
- throw new Error(errorStr);
144
- }
145
- return reactFn;
146
- };
147
-
148
- module.exports = chainDefine;
149
- module.exports.options = core.options;
150
- module.exports.events = core.events;