You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					158 lines
				
				3.9 KiB
			
		
		
			
		
	
	
					158 lines
				
				3.9 KiB
			| 
											2 years ago
										 | Chainsaw | ||
|  | ======== | ||
|  | 
 | ||
|  | Build chainable fluent interfaces the easy way in node.js. | ||
|  | 
 | ||
|  | With this meta-module you can write modules with chainable interfaces. | ||
|  | Chainsaw takes care of all of the boring details and makes nested flow control | ||
|  | super simple too. | ||
|  | 
 | ||
|  | Just call `Chainsaw` with a constructor function like in the examples below. | ||
|  | In your methods, just do `saw.next()` to move along to the next event and | ||
|  | `saw.nest()` to create a nested chain. | ||
|  | 
 | ||
|  | Examples | ||
|  | ======== | ||
|  | 
 | ||
|  | add_do.js | ||
|  | --------- | ||
|  | 
 | ||
|  | This silly example adds values with a chainsaw. | ||
|  | 
 | ||
|  |     var Chainsaw = require('chainsaw'); | ||
|  |      | ||
|  |     function AddDo (sum) { | ||
|  |         return Chainsaw(function (saw) { | ||
|  |             this.add = function (n) { | ||
|  |                 sum += n; | ||
|  |                 saw.next(); | ||
|  |             }; | ||
|  |               | ||
|  |             this.do = function (cb) { | ||
|  |                 saw.nest(cb, sum); | ||
|  |             }; | ||
|  |         }); | ||
|  |     } | ||
|  |      | ||
|  |     AddDo(0) | ||
|  |         .add(5) | ||
|  |         .add(10) | ||
|  |         .do(function (sum) { | ||
|  |             if (sum > 12) this.add(-10); | ||
|  |         }) | ||
|  |         .do(function (sum) { | ||
|  |             console.log('Sum: ' + sum); | ||
|  |         }) | ||
|  |     ; | ||
|  | 
 | ||
|  | Output: | ||
|  |     Sum: 5 | ||
|  | 
 | ||
|  | prompt.js | ||
|  | --------- | ||
|  | 
 | ||
|  | This example provides a wrapper on top of stdin with the help of | ||
|  | [node-lazy](https://github.com/pkrumins/node-lazy) for line-processing. | ||
|  | 
 | ||
|  |     var Chainsaw = require('chainsaw'); | ||
|  |     var Lazy = require('lazy'); | ||
|  |      | ||
|  |     module.exports = Prompt; | ||
|  |     function Prompt (stream) { | ||
|  |         var waiting = []; | ||
|  |         var lines = []; | ||
|  |         var lazy = Lazy(stream).lines.map(String) | ||
|  |             .forEach(function (line) { | ||
|  |                 if (waiting.length) { | ||
|  |                     var w = waiting.shift(); | ||
|  |                     w(line); | ||
|  |                 } | ||
|  |                 else lines.push(line); | ||
|  |             }) | ||
|  |         ; | ||
|  |          | ||
|  |         var vars = {}; | ||
|  |         return Chainsaw(function (saw) { | ||
|  |             this.getline = function (f) { | ||
|  |                 var g = function (line) { | ||
|  |                     saw.nest(f, line, vars); | ||
|  |                 }; | ||
|  |                  | ||
|  |                 if (lines.length) g(lines.shift()); | ||
|  |                 else waiting.push(g); | ||
|  |             }; | ||
|  |              | ||
|  |             this.do = function (cb) { | ||
|  |                 saw.nest(cb, vars); | ||
|  |             }; | ||
|  |         }); | ||
|  |     } | ||
|  | 
 | ||
|  | And now for the new Prompt() module in action: | ||
|  | 
 | ||
|  |     var util = require('util'); | ||
|  |     var stdin = process.openStdin(); | ||
|  |       | ||
|  |     Prompt(stdin) | ||
|  |         .do(function () { | ||
|  |             util.print('x = '); | ||
|  |         }) | ||
|  |         .getline(function (line, vars) { | ||
|  |             vars.x = parseInt(line, 10); | ||
|  |         }) | ||
|  |         .do(function () { | ||
|  |             util.print('y = '); | ||
|  |         }) | ||
|  |         .getline(function (line, vars) { | ||
|  |             vars.y = parseInt(line, 10); | ||
|  |         }) | ||
|  |         .do(function (vars) { | ||
|  |             if (vars.x + vars.y < 10) { | ||
|  |                 util.print('z = '); | ||
|  |                 this.getline(function (line) { | ||
|  |                     vars.z = parseInt(line, 10); | ||
|  |                 }) | ||
|  |             } | ||
|  |             else { | ||
|  |                 vars.z = 0; | ||
|  |             } | ||
|  |         }) | ||
|  |         .do(function (vars) { | ||
|  |             console.log('x + y + z = ' + (vars.x + vars.y + vars.z)); | ||
|  |             process.exit(); | ||
|  |         }) | ||
|  |     ; | ||
|  | 
 | ||
|  | Installation | ||
|  | ============ | ||
|  | 
 | ||
|  | With [npm](http://github.com/isaacs/npm), just do: | ||
|  |     npm install chainsaw | ||
|  | 
 | ||
|  | or clone this project on github: | ||
|  | 
 | ||
|  |     git clone http://github.com/substack/node-chainsaw.git | ||
|  | 
 | ||
|  | To run the tests with [expresso](http://github.com/visionmedia/expresso), | ||
|  | just do: | ||
|  | 
 | ||
|  |     expresso | ||
|  | 
 | ||
|  | 
 | ||
|  | Light Mode vs Full Mode | ||
|  | ======================= | ||
|  | 
 | ||
|  | `node-chainsaw` supports two different modes. In full mode, every | ||
|  | action is recorded, which allows you to replay actions using the | ||
|  | `jump()`, `trap()` and `down()` methods. | ||
|  | 
 | ||
|  | However, if your chainsaws are long-lived, recording every action can | ||
|  | consume a tremendous amount of memory, so we also offer a "light" mode | ||
|  | where actions are not recorded and the aforementioned methods are | ||
|  | disabled. | ||
|  | 
 | ||
|  | To enable light mode simply use `Chainsaw.light()` to construct your | ||
|  | saw, instead of `Chainsaw()`. | ||
|  | 
 | ||
|  | 
 |