Skip to content
Browse files

reviewed API documentation

  • Loading branch information...
1 parent 509757b commit ae31fe92f867640592d47344f322c5405f1a621c @bjouhier bjouhier committed Apr 4, 2012
View
6 index.js
@@ -4,10 +4,10 @@
///
/// `var streamline = require('streamline');`
///
-/// * `streamline.run()`
-/// runs `_node` command line analyzer / dispatcher
-exports.run = require("./lib/compiler/command").run;
/// * `streamline.register(options)`
/// Registers `require` handlers for streamline.
/// `options` is a set of default options passed to the transformation.
exports.register = require("./lib/compiler/register").register;
+/// * `streamline.run()`
+/// runs `_node` command line analyzer / dispatcher
+exports.run = require("./lib/compiler/command").run;
View
4 index.md
@@ -3,8 +3,8 @@
`var streamline = require('streamline');`
-* `streamline.run()`
- runs `_node` command line analyzer / dispatcher
* `streamline.register(options)`
Registers `require` handlers for streamline.
`options` is a set of default options passed to the transformation.
+* `streamline.run()`
+ runs `_node` command line analyzer / dispatcher
View
34 lib/callbacks/builtins.js
@@ -97,7 +97,9 @@
- Array.prototype.forEach_ = function Array_prototype_forEach___1(_, options, fn, thisObj) { var par, len, i, __this = this; var __frame = { name: "Array_prototype_forEach___1", line: 100 }; return __func(_, this, arguments, Array_prototype_forEach___1, 0, __frame, function __$Array_prototype_forEach___1() {
+
+
+ Array.prototype.forEach_ = function Array_prototype_forEach___1(_, options, fn, thisObj) { var par, len, i, __this = this; var __frame = { name: "Array_prototype_forEach___1", line: 102 }; return __func(_, this, arguments, Array_prototype_forEach___1, 0, __frame, function __$Array_prototype_forEach___1() {
if ((typeof options === "function")) { thisObj = fn, fn = options, options = 1; } ;
par = _parallel(options);
thisObj = ((thisObj !== undefined) ? thisObj : __this);
@@ -112,7 +114,7 @@
- Array.prototype.map_ = function Array_prototype_map___2(_, options, fn, thisObj) { var par, len, result, i, fun, __this = this; var __frame = { name: "Array_prototype_map___2", line: 115 }; return __func(_, this, arguments, Array_prototype_map___2, 0, __frame, function __$Array_prototype_map___2() {
+ Array.prototype.map_ = function Array_prototype_map___2(_, options, fn, thisObj) { var par, len, result, i, fun, __this = this; var __frame = { name: "Array_prototype_map___2", line: 117 }; return __func(_, this, arguments, Array_prototype_map___2, 0, __frame, function __$Array_prototype_map___2() {
if ((typeof options === "function")) { thisObj = fn, fn = options, options = 1; } ;
par = _parallel(options);
thisObj = ((thisObj !== undefined) ? thisObj : __this);
@@ -125,7 +127,7 @@
fun = funnel(par);
result = __this.map(function(elt, i) {
- return fun(null, function __1(_) { var __frame = { name: "__1", line: 128 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
+ return fun(null, function __1(_) { var __frame = { name: "__1", line: 130 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
return fn.call(thisObj, __cb(_, __frame, 1, 12, _, true), elt, i); }); }); });
@@ -135,7 +137,7 @@
- Array.prototype.filter_ = function Array_prototype_filter___3(_, options, fn, thisObj) { var par, result, len, i, elt, __this = this; var __frame = { name: "Array_prototype_filter___3", line: 138 }; return __func(_, this, arguments, Array_prototype_filter___3, 0, __frame, function __$Array_prototype_filter___3() {
+ Array.prototype.filter_ = function Array_prototype_filter___3(_, options, fn, thisObj) { var par, result, len, i, elt, __this = this; var __frame = { name: "Array_prototype_filter___3", line: 140 }; return __func(_, this, arguments, Array_prototype_filter___3, 0, __frame, function __$Array_prototype_filter___3() {
if ((typeof options === "function")) { thisObj = fn, fn = options, options = 1; } ;
par = _parallel(options);
thisObj = ((thisObj !== undefined) ? thisObj : __this);
@@ -147,15 +149,15 @@
return fn.call(thisObj, __cb(_, __frame, 9, 8, function ___(__0, __2) { return (function __$Array_prototype_filter___3(__then) { if (__2) { result.push(elt); __then(); } else { __then(); } ; })(function __$Array_prototype_filter___3() { while (__more) { __loop(); }; __more = true; }); }, true), elt); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(__then); } else {
- return __this.map_(__cb(_, __frame, 12, 3, __then, true), par, function __1(_, elt) { var __frame = { name: "__1", line: 150 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
+ return __this.map_(__cb(_, __frame, 12, 3, __then, true), par, function __1(_, elt) { var __frame = { name: "__1", line: 152 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
return fn.call(thisObj, __cb(_, __frame, 1, 8, function ___(__0, __1) { return (function __$__1(__then) { if (__1) { result.push(elt); __then(); } else { __then(); } ; })(_); }, true), elt); });
}, thisObj); } ; })(function __$Array_prototype_filter___3() {
return _(null, result); }); }); };
- Array.prototype.every_ = function Array_prototype_every___4(_, options, fn, thisObj) { var par, len, i, fun, futures, __this = this; var __frame = { name: "Array_prototype_every___4", line: 158 }; return __func(_, this, arguments, Array_prototype_every___4, 0, __frame, function __$Array_prototype_every___4() {
+ Array.prototype.every_ = function Array_prototype_every___4(_, options, fn, thisObj) { var par, len, i, fun, futures, __this = this; var __frame = { name: "Array_prototype_every___4", line: 160 }; return __func(_, this, arguments, Array_prototype_every___4, 0, __frame, function __$Array_prototype_every___4() {
if ((typeof options === "function")) { thisObj = fn, fn = options, options = 1; } ;
par = _parallel(options);
thisObj = ((thisObj !== undefined) ? thisObj : __this);
@@ -167,7 +169,7 @@
fun = funnel(par);
futures = __this.map(function(elt) {
- return fun(null, function __1(_) { var __frame = { name: "__1", line: 170 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
+ return fun(null, function __1(_) { var __frame = { name: "__1", line: 172 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
return fn.call(thisObj, __cb(_, __frame, 1, 12, _, true), elt); }); }); });
@@ -182,7 +184,7 @@
- Array.prototype.some_ = function Array_prototype_some___5(_, options, fn, thisObj) { var par, len, i, fun, futures, __this = this; var __frame = { name: "Array_prototype_some___5", line: 185 }; return __func(_, this, arguments, Array_prototype_some___5, 0, __frame, function __$Array_prototype_some___5() {
+ Array.prototype.some_ = function Array_prototype_some___5(_, options, fn, thisObj) { var par, len, i, fun, futures, __this = this; var __frame = { name: "Array_prototype_some___5", line: 187 }; return __func(_, this, arguments, Array_prototype_some___5, 0, __frame, function __$Array_prototype_some___5() {
if ((typeof options === "function")) { thisObj = fn, fn = options, options = 1; } ;
par = _parallel(options);
thisObj = ((thisObj !== undefined) ? thisObj : __this);
@@ -194,7 +196,7 @@
fun = funnel(par);
futures = __this.map(function(elt) {
- return fun(null, function __1(_) { var __frame = { name: "__1", line: 197 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
+ return fun(null, function __1(_) { var __frame = { name: "__1", line: 199 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
return fn.call(thisObj, __cb(_, __frame, 1, 12, _, true), elt); }); }); });
@@ -209,7 +211,7 @@
- Array.prototype.reduce_ = function Array_prototype_reduce___6(_, fn, v, thisObj) { var len, i, __this = this; var __frame = { name: "Array_prototype_reduce___6", line: 212 }; return __func(_, this, arguments, Array_prototype_reduce___6, 0, __frame, function __$Array_prototype_reduce___6() {
+ Array.prototype.reduce_ = function Array_prototype_reduce___6(_, fn, v, thisObj) { var len, i, __this = this; var __frame = { name: "Array_prototype_reduce___6", line: 214 }; return __func(_, this, arguments, Array_prototype_reduce___6, 0, __frame, function __$Array_prototype_reduce___6() {
thisObj = ((thisObj !== undefined) ? thisObj : __this);
len = __this.length;
i = 0; var __3 = false; return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$Array_prototype_reduce___6() { __more = false; if (__3) { i++; } else { __3 = true; } ; var __2 = (i < len); if (__2) {
@@ -219,8 +221,7 @@
-
- Array.prototype.reduceRight_ = function Array_prototype_reduceRight___7(_, fn, v, thisObj) { var len, i, __this = this; var __frame = { name: "Array_prototype_reduceRight___7", line: 223 }; return __func(_, this, arguments, Array_prototype_reduceRight___7, 0, __frame, function __$Array_prototype_reduceRight___7() {
+ Array.prototype.reduceRight_ = function Array_prototype_reduceRight___7(_, fn, v, thisObj) { var len, i, __this = this; var __frame = { name: "Array_prototype_reduceRight___7", line: 224 }; return __func(_, this, arguments, Array_prototype_reduceRight___7, 0, __frame, function __$Array_prototype_reduceRight___7() {
thisObj = ((thisObj !== undefined) ? thisObj : __this);
len = __this.length;
i = (len - 1); var __3 = false; return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$Array_prototype_reduceRight___7() { __more = false; if (__3) { i--; } else { __3 = true; } ; var __2 = (i >= 0); if (__2) {
@@ -237,7 +238,7 @@
- function _qsort(_, beg, end) { var tmp, mid, o, nbeg, nend; var __frame = { name: "_qsort", line: 240 }; return __func(_, this, arguments, _qsort, 0, __frame, function __$_qsort() {
+ function _qsort(_, beg, end) { var tmp, mid, o, nbeg, nend; var __frame = { name: "_qsort", line: 241 }; return __func(_, this, arguments, _qsort, 0, __frame, function __$_qsort() {
if ((beg >= end)) { return _(null); } ; return (function __$_qsort(__then) {
if ((end == (beg + 1))) {
@@ -255,8 +256,8 @@
nend = end; return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$_qsort() { __more = false;
var __4 = (nbeg <= nend); if (__4) { return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$_qsort() { __more = false; return (function __$_qsort(_) { return (function __$_qsort(_) {
- var __1 = (nbeg < end); if (!__1) { return _(null, __1); } ; return compare(__cb(_, __frame, 18, 25, function ___(__0, __3) { var __2 = (__3 < 0); return _(null, __2); }, true), array[nbeg], o); })(__cb(_, __frame, -239, 17, _, true)); })(__cb(_, __frame, -239, 17, function ___(__0, __5) { if (__5) { nbeg++; while (__more) { __loop(); }; __more = true; } else { __break(); } ; }, true)); }); do { __loop(); } while (__more); __more = true; })(function __$_qsort() { return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$_qsort() { __more = false; return (function __$_qsort(_) { return (function __$_qsort(_) {
- var __1 = (beg < nend); if (!__1) { return _(null, __1); } ; return compare(__cb(_, __frame, 19, 25, function ___(__0, __3) { var __2 = (__3 < 0); return _(null, __2); }, true), o, array[nend]); })(__cb(_, __frame, -239, 17, _, true)); })(__cb(_, __frame, -239, 17, function ___(__0, __7) { if (__7) { nend--; while (__more) { __loop(); }; __more = true; } else { __break(); } ; }, true)); }); do { __loop(); } while (__more); __more = true; })(function __$_qsort() {
+ var __1 = (nbeg < end); if (!__1) { return _(null, __1); } ; return compare(__cb(_, __frame, 18, 25, function ___(__0, __3) { var __2 = (__3 < 0); return _(null, __2); }, true), array[nbeg], o); })(__cb(_, __frame, -240, 17, _, true)); })(__cb(_, __frame, -240, 17, function ___(__0, __5) { if (__5) { nbeg++; while (__more) { __loop(); }; __more = true; } else { __break(); } ; }, true)); }); do { __loop(); } while (__more); __more = true; })(function __$_qsort() { return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$_qsort() { __more = false; return (function __$_qsort(_) { return (function __$_qsort(_) {
+ var __1 = (beg < nend); if (!__1) { return _(null, __1); } ; return compare(__cb(_, __frame, 19, 25, function ___(__0, __3) { var __2 = (__3 < 0); return _(null, __2); }, true), o, array[nend]); })(__cb(_, __frame, -240, 17, _, true)); })(__cb(_, __frame, -240, 17, function ___(__0, __7) { if (__7) { nend--; while (__more) { __loop(); }; __more = true; } else { __break(); } ; }, true)); }); do { __loop(); } while (__more); __more = true; })(function __$_qsort() {
if ((nbeg <= nend)) {
tmp = array[nbeg];
@@ -268,7 +269,7 @@
if ((nbeg < end)) { return _qsort(__cb(_, __frame, 30, 19, __then, true), nbeg, end); } else { __then(); } ; })(function __$_qsort() { return (function __$_qsort(__then) {
- if ((beg < nend)) { return _qsort(__cb(_, __frame, 31, 19, __then, true), beg, nend); } else { __then(); } ; })(_); }); }); }); }); }; var __frame = { name: "Array_prototype_sort___8", line: 235 }; return __func(_, this, arguments, Array_prototype_sort___8, 0, __frame, function __$Array_prototype_sort___8() { array = __this; beg = (beg || 0); end = ((end == null) ? (array.length - 1) : end);
+ if ((beg < nend)) { return _qsort(__cb(_, __frame, 31, 19, __then, true), beg, nend); } else { __then(); } ; })(_); }); }); }); }); }; var __frame = { name: "Array_prototype_sort___8", line: 236 }; return __func(_, this, arguments, Array_prototype_sort___8, 0, __frame, function __$Array_prototype_sort___8() { array = __this; beg = (beg || 0); end = ((end == null) ? (array.length - 1) : end);
return _qsort(__cb(_, __frame, 38, 2, function __$Array_prototype_sort___8() {
return _(null, array); }, true), beg, end); }); };
@@ -281,6 +282,7 @@
+
Function.prototype.apply_ = function(callback, thisObj, args, index) {
Array.prototype.splice.call(args, ((index != null) ? index : args.length), 0, callback);
return this.apply(thisObj, args); };
View
14 lib/callbacks/transform.js
@@ -26,6 +26,8 @@
///
/// # Transformation engine (callback mode)
///
+/// `var transform = require('streamline/lib/callbacks/transform')`
+///
if (typeof exports !== 'undefined') {
var Narcissus = require('../../deps/narcissus');
var format = require('./format').format;
@@ -1354,10 +1356,12 @@ if (typeof exports !== 'undefined') {
/// * `transformed = transform.transform(source, options)`
/// Transforms streamline source.
/// The following `options` may be specified:
- /// * `tryCatch` controls exception handling
+ /// * `sourceName` identifies source (stack traces, transformation errors)
/// * `lines` controls line mapping
- /// * `callback` alternative identifier if `_` is already used.
- /// * `noHelpers` disables generation of helper functions (`__cb`, etc.)
+ // Undocumented options:
+ // * (obsolete) `callback` alternative identifier if `_` is already used
+ // * (internal) `noHelpers` disables generation of helper functions (`__cb`, etc.)
+ // * (internal) `optimize` optimizes transform (but misses stack frames)
exports.transform = function(source, options) {
try {
options = options ? _extend({}, options) : {}; // clone to isolate options set at file level
@@ -1414,6 +1418,7 @@ if (typeof exports !== 'undefined') {
return fn.toString().replace(/\s+/g, " ");
}
+ // Undocumented (internal)
exports.helpersSource = function(options, used, strict) {
var srcName = "" + options.sourceName; // + "_.js";
var i = srcName.indexOf('node_modules/');
@@ -1435,5 +1440,8 @@ if (typeof exports !== 'undefined') {
s += ";" + sep;
return s;
}
+
+ /// * `version = transform.version`
+ /// current version of the transformation algorithm.
exports.version = "0.2.5";
})(typeof exports !== 'undefined' ? exports : (window.Streamline = window.Streamline || {}));
View
8 lib/callbacks/transform.md
@@ -1,10 +1,12 @@
# Transformation engine (callback mode)
+`var transform = require('streamline/lib/callbacks/transform')`
+
* `transformed = transform.transform(source, options)`
Transforms streamline source.
The following `options` may be specified:
- * `tryCatch` controls exception handling
+ * `sourceName` identifies source (stack traces, transformation errors)
* `lines` controls line mapping
- * `callback` alternative identifier if `_` is already used.
- * `noHelpers` disables generation of helper functions (`__cb`, etc.)
+* `version = transform.version`
+ current version of the transformation algorithm.
View
32 lib/compiler/builtins._js
@@ -75,25 +75,27 @@
if (typeof options.parallel === "number") return options.parallel;
return options.parallel ? -1 : 1;
}
- /// ## Asychronous versions of ES5 Array functions.
+ /// ## Array functions.
+ ///
+ /// These functions are asynchronous variants of the EcmaScript 5 Array functions.
///
/// Common Rules:
///
/// These variants are postfixed by an underscore.
/// They take the `_` callback as first parameter.
- /// They pass the `_` callback as first arguement to their `fn` callback.
+ /// They pass the `_` callback as first argument to their `fn` callback.
/// Most of them have an optional `options` second parameter which controls the level of
- /// parallelism. This `options` parameter may be specified as `{ parallel: par }`
- /// where par is an integer, or directly as a `par` integer value.
+ /// parallelism. This `options` parameter may be specified either as `{ parallel: par }`
+ /// where `par` is an integer, or directly as a `par` integer value.
/// The `par` values are interpreted as follows:
///
/// * If absent or equal to 1, execution is sequential.
/// * If > 1, at most `par` operations are parallelized.
/// * if 0, a default number of operations are parallelized.
- /// This default can be read and set with funnel.defaultSize (4 by default)
+ /// This default is defined by `flows.funnel.defaultSize` (4 by default - see `flows` module).
/// * If < 0 or Infinity, operations are fully parallelized (no limit).
///
- /// API:
+ /// Functions:
///
/// * `array.forEach_(_[, options], fn[, thisObj])`
/// `fn` is called as `fn(_, elt, i)`.
@@ -207,7 +209,7 @@
}
return false;
}
- /// * `result = array.reduce_(_, array, fn, val)`
+ /// * `result = array.reduce_(_, fn, val[, thisObj])`
/// `fn` is called as `val = fn(_, val, elt, i, array)`.
Array.prototype.reduce_ = function(_, fn, v, thisObj) {
thisObj = thisObj !== undefined ? thisObj : this;
@@ -217,8 +219,7 @@
}
return v;
}
- /// * `result = flows.reduceRight(_, array, fn, val, [thisObj])`
- /// reduces from end to start by applying `fn` to each element.
+ /// * `result = array.reduceRight_(_, fn, val[, thisObj])`
/// `fn` is called as `val = fn(_, val, elt, i, array)`.
Array.prototype.reduceRight_ = function(_, fn, v, thisObj) {
thisObj = thisObj !== undefined ? thisObj : this;
@@ -229,7 +230,7 @@
return v;
}
- /// * `array = flows.sort(_, array, compare, [beg], [end])`
+ /// * `array = array.sort_(_, compare [, beg [, end]])`
/// `compare` is called as `cmp = compare(_, elt1, elt2)`
/// Note: this function _changes_ the original array (and returns it)
Array.prototype.sort_ = function(_, compare, beg, end) {
@@ -274,13 +275,14 @@
return array;
}
- /// ## Asychronous versions of ES5 Function functions.
///
- /// * `result = fn.apply_(_, thisObj, args, [index])`
- /// Helper to use `Function.prototype.apply` with streamline functions.
+ /// ## Function functions.
+ ///
+ /// * `result = fn.apply_(_, thisObj, args[, index])`
+ /// Helper to use `Function.prototype.apply` inside streamlined functions.
/// Equivalent to `result = fn.apply(thisObj, argsWith_)` where `argsWith_` is
- /// a modified argument list in which the callback has been inserted at `index`
- /// (at the end of the argument list if `index` is not specified).
+ /// a modified `args` in which the callback has been inserted at `index`
+ /// (at the end of the argument list if `index` is omitted).
Function.prototype.apply_ = function(callback, thisObj, args, index) {
Array.prototype.splice.call(args, index != null ? index : args.length, 0, callback);
return this.apply(thisObj, args);
View
32 lib/compiler/builtins.md
@@ -1,25 +1,27 @@
# Streamline built-ins
-## Asychronous versions of ES5 Array functions.
+## Array functions.
+
+These functions are asynchronous variants of the EcmaScript 5 Array functions.
Common Rules:
These variants are postfixed by an underscore.
They take the `_` callback as first parameter.
-They pass the `_` callback as first arguement to their `fn` callback.
+They pass the `_` callback as first argument to their `fn` callback.
Most of them have an optional `options` second parameter which controls the level of
-parallelism. This `options` parameter may be specified as `{ parallel: par }`
-where par is an integer, or directly as a `par` integer value.
+parallelism. This `options` parameter may be specified either as `{ parallel: par }`
+where `par` is an integer, or directly as a `par` integer value.
The `par` values are interpreted as follows:
* If absent or equal to 1, execution is sequential.
* If > 1, at most `par` operations are parallelized.
* if 0, a default number of operations are parallelized.
- This default can be read and set with funnel.defaultSize (4 by default)
+ This default is defined by `flows.funnel.defaultSize` (4 by default - see `flows` module).
* If < 0 or Infinity, operations are fully parallelized (no limit).
-API:
+Functions:
* `array.forEach_(_[, options], fn[, thisObj])`
`fn` is called as `fn(_, elt, i)`.
@@ -31,18 +33,18 @@ API:
`fn` is called as `fn(_, elt)`.
* `bool = array.some_(_[, options], fn[, thisObj])`
`fn` is called as `fn(_, elt)`.
-* `result = array.reduce_(_, array, fn, val)`
+* `result = array.reduce_(_, fn, val[, thisObj])`
`fn` is called as `val = fn(_, val, elt, i, array)`.
-* `result = flows.reduceRight(_, array, fn, val, [thisObj])`
- reduces from end to start by applying `fn` to each element.
+* `result = array.reduceRight_(_, fn, val[, thisObj])`
`fn` is called as `val = fn(_, val, elt, i, array)`.
-* `array = flows.sort(_, array, compare, [beg], [end])`
+* `array = array.sort_(_, compare [, beg [, end]])`
`compare` is called as `cmp = compare(_, elt1, elt2)`
Note: this function _changes_ the original array (and returns it)
-## Asychronous versions of ES5 Function functions.
-* `result = fn.apply_(_, thisObj, args, [index])`
- Helper to use `Function.prototype.apply` with streamline functions.
+## Function functions.
+
+* `result = fn.apply_(_, thisObj, args[, index])`
+ Helper to use `Function.prototype.apply` inside streamlined functions.
Equivalent to `result = fn.apply(thisObj, argsWith_)` where `argsWith_` is
- a modified argument list in which the callback has been inserted at `index`
- (at the end of the argument list if `index` is not specified).
+ a modified `args` in which the callback has been inserted at `index`
+ (at the end of the argument list if `index` is omitted).
View
27 lib/compiler/compile._js
@@ -112,18 +112,18 @@ exports.compileFile = function(_, js_, options) {
}
var streamlineRE = /require\s*\(\s*['"]streamline\/module['"]\s*\)\s*\(\s*module\s*,?\s*([^)]*)?\s*\)/;
-/// * `script = compiler.loadFile(_, path, options)`
-/// Loads Javascript file and transforms it if necessary.
-/// Returns the transformed source.
-/// If `path` is `foo_.js`, the source is transformed and the result
-/// is *not* saved to disk.
-/// If `path` is `foo.js` and if a `foo_.js` file exists,
-/// `foo_.js` is transformed if necessary and saved as `foo.js`.
-/// If `path` is `foo.js` and `foo_.js` does not exist, the contents
-/// of `foo.js` is returned.
-/// `options` is a set of options passed to the transformation engine.
-/// If `options.force` is set, `foo_.js` is transformed even if
-/// `foo.js` is more recent.
+// * `script = compiler.loadFile(_, path, options)`
+// Loads Javascript file and transforms it if necessary.
+// Returns the transformed source.
+// If `path` is `foo_.js`, the source is transformed and the result
+// is *not* saved to disk.
+// If `path` is `foo.js` and if a `foo_.js` file exists,
+// `foo_.js` is transformed if necessary and saved as `foo.js`.
+// If `path` is `foo.js` and `foo_.js` does not exist, the contents
+// of `foo.js` is returned.
+// `options` is a set of options passed to the transformation engine.
+// If `options.force` is set, `foo_.js` is transformed even if
+// `foo.js` is more recent.
exports.loadFile = function(_, path, options) {
options = _extend({}, options || {});
@@ -205,9 +205,6 @@ function mtimeSync(fname) {
}
}
-/// * `script = compiler.transformModule(path, options)`
-/// Synchronous version of `compiler.loadFile`.
-/// Used by `require` logic.
exports.transformModule = function(content, path, options) {
options = _extend({}, options || {});
View
17 lib/compiler/compile.js
@@ -205,9 +205,6 @@ function mtimeSync(fname) {
-
-
-
exports.transformModule = function(content, path, options) {
options = _extend({ }, (options || { }));
@@ -280,18 +277,18 @@ var root = (((process.env.HOME || ((process.env.HOMEDRIVE + process.env.HOMEPATH
var dirMode = parseInt("777", 8);
-function mkdirs(_, path) { var p, i, segs, seg; var __frame = { name: "mkdirs", line: 283 }; return __func(_, this, arguments, mkdirs, 0, __frame, function __$mkdirs() {
+function mkdirs(_, path) { var p, i, segs, seg; var __frame = { name: "mkdirs", line: 280 }; return __func(_, this, arguments, mkdirs, 0, __frame, function __$mkdirs() {
p = "";
i = 0;
segs = path.split("/").slice(0, -1); return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$mkdirs() { __more = false;
var __3 = (i < segs.length); if (__3) {
seg = segs[i];
p += (((i++ ? "/" : "")) + seg); return (function __$mkdirs(_) {
- var __1 = (i > 1); if (!__1) { return _(null, __1); } ; return _exists(__cb(_, __frame, 7, 16, function ___(__0, __3) { var __2 = !__3; return _(null, __2); }, true), p); })(__cb(_, __frame, -282, 6, function ___(__0, __2) { return (function __$mkdirs(__then) { if (__2) { return fs.mkdir(p, dirMode, __cb(_, __frame, 7, 31, __then, true)); } else { __then(); } ; })(function __$mkdirs() { while (__more) { __loop(); }; __more = true; }); }, true)); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(_); });};
+ var __1 = (i > 1); if (!__1) { return _(null, __1); } ; return _exists(__cb(_, __frame, 7, 16, function ___(__0, __3) { var __2 = !__3; return _(null, __2); }, true), p); })(__cb(_, __frame, -279, 6, function ___(__0, __2) { return (function __$mkdirs(__then) { if (__2) { return fs.mkdir(p, dirMode, __cb(_, __frame, 7, 31, __then, true)); } else { __then(); } ; })(function __$mkdirs() { while (__more) { __loop(); }; __more = true; }); }, true)); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(_); });};
-function cachedTransform(_, content, path, transform, banner, options) { var i, dir, f, transformed; var __frame = { name: "cachedTransform", line: 294 }; return __func(_, this, arguments, cachedTransform, 0, __frame, function __$cachedTransform() {
+function cachedTransform(_, content, path, transform, banner, options) { var i, dir, f, transformed; var __frame = { name: "cachedTransform", line: 291 }; return __func(_, this, arguments, cachedTransform, 0, __frame, function __$cachedTransform() {
path = path.replace(/\\/g, "/");
i = path.indexOf("node_modules/");
if ((i < 0)) { i = path.lastIndexOf("/"); } else {
@@ -361,10 +358,10 @@ exports.compile = function exports_compile__3(_, paths, options) { var flows, fa
- function _compile(_, path, options) { var stat, ext; var __frame = { name: "_compile", line: 364 }; return __func(_, this, arguments, _compile, 0, __frame, function __$_compile() {
+ function _compile(_, path, options) { var stat, ext; var __frame = { name: "_compile", line: 361 }; return __func(_, this, arguments, _compile, 0, __frame, function __$_compile() {
return fs.stat(path, __cb(_, __frame, 1, 13, function ___(__0, __2) { stat = __2; return (function __$_compile(__then) {
if (stat.isDirectory()) {
- return fs.readdir(path, __cb(_, __frame, 3, 17, function ___(__0, __3) { return flows.each(__cb(_, __frame, 3, 3, __then, true), __3, function __1(_, f) { var __frame = { name: "__1", line: 367 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
+ return fs.readdir(path, __cb(_, __frame, 3, 17, function ___(__0, __3) { return flows.each(__cb(_, __frame, 3, 3, __then, true), __3, function __1(_, f) { var __frame = { name: "__1", line: 364 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() {
return _compile(__cb(_, __frame, 1, 4, _, true), ((path + "/") + f), options); }); }); }, true)); } else { return (function __$_compile(__then) {
if (stat.isFile()) { return (function ___(__then) { (function ___(_) { __tryCatch(_, function __$_compile() {
@@ -378,7 +375,7 @@ exports.compile = function exports_compile__3(_, paths, options) { var flows, fa
console.error(ex.stack);
- failed++; __then(); } else { _(null, __result); } ; }); }); })(function ___() { __tryCatch(_, __then); }); } else { __then(); } ; })(__then); } ; })(_); }, true)); }); }; var __frame = { name: "exports_compile__3", line: 360 }; return __func(_, this, arguments, exports_compile__3, 0, __frame, function __$exports_compile__3() { flows = require("../util/flows");
+ failed++; __then(); } else { _(null, __result); } ; }); }); })(function ___() { __tryCatch(_, __then); }); } else { __then(); } ; })(__then); } ; })(_); }, true)); }); }; var __frame = { name: "exports_compile__3", line: 357 }; return __func(_, this, arguments, exports_compile__3, 0, __frame, function __$exports_compile__3() { flows = require("../util/flows");
@@ -393,4 +390,4 @@ exports.compile = function exports_compile__3(_, paths, options) { var flows, fa
return flows.each(__cb(_, __frame, 33, 1, function __$exports_compile__3() {
- if (failed) { return _(new Error((("errors found in " + failed) + " files"))); } ; _(); }, true), paths, function __1(_, path) { var __frame = { name: "__1", line: 393 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() { return _compile(__cb(_, __frame, 1, 2, _, true), fspath.resolve(cwd, path), options); }); }); });};
+ if (failed) { return _(new Error((("errors found in " + failed) + " files"))); } ; _(); }, true), paths, function __1(_, path) { var __frame = { name: "__1", line: 390 }; return __func(_, this, arguments, __1, 0, __frame, function __$__1() { return _compile(__cb(_, __frame, 1, 2, _, true), fspath.resolve(cwd, path), options); }); }); });};
View
15 lib/compiler/compile.md
@@ -3,21 +3,6 @@
`var compiler = require('streamline/lib/compiler/compile')`
-* `script = compiler.loadFile(_, path, options)`
- Loads Javascript file and transforms it if necessary.
- Returns the transformed source.
- If `path` is `foo_.js`, the source is transformed and the result
- is *not* saved to disk.
- If `path` is `foo.js` and if a `foo_.js` file exists,
- `foo_.js` is transformed if necessary and saved as `foo.js`.
- If `path` is `foo.js` and `foo_.js` does not exist, the contents
- of `foo.js` is returned.
- `options` is a set of options passed to the transformation engine.
- If `options.force` is set, `foo_.js` is transformed even if
- `foo.js` is more recent.
-* `script = compiler.transformModule(path, options)`
- Synchronous version of `compiler.loadFile`.
- Used by `require` logic.
* `compiler.compile(_, paths, options)`
Compiles streamline source files in `paths`.
Generates a `foo.js` file for each `foo._js` file found in `paths`.
View
32 lib/fibers/builtins.js
@@ -75,25 +75,27 @@
if (typeof options.parallel === "number") return options.parallel;
return options.parallel ? -1 : 1;
}
- /// ## Asychronous versions of ES5 Array functions.
+ /// ## Array functions.
+ ///
+ /// These functions are asynchronous variants of the EcmaScript 5 Array functions.
///
/// Common Rules:
///
/// These variants are postfixed by an underscore.
/// They take the `_` callback as first parameter.
- /// They pass the `_` callback as first arguement to their `fn` callback.
+ /// They pass the `_` callback as first argument to their `fn` callback.
/// Most of them have an optional `options` second parameter which controls the level of
- /// parallelism. This `options` parameter may be specified as `{ parallel: par }`
- /// where par is an integer, or directly as a `par` integer value.
+ /// parallelism. This `options` parameter may be specified either as `{ parallel: par }`
+ /// where `par` is an integer, or directly as a `par` integer value.
/// The `par` values are interpreted as follows:
///
/// * If absent or equal to 1, execution is sequential.
/// * If > 1, at most `par` operations are parallelized.
/// * if 0, a default number of operations are parallelized.
- /// This default can be read and set with funnel.defaultSize (4 by default)
+ /// This default is defined by `flows.funnel.defaultSize` (4 by default - see `flows` module).
/// * If < 0 or Infinity, operations are fully parallelized (no limit).
///
- /// API:
+ /// Functions:
///
/// * `array.forEach_(_[, options], fn[, thisObj])`
/// `fn` is called as `fn(_, elt, i)`.
@@ -207,7 +209,7 @@
}
return false;
}, 0)
- /// * `result = array.reduce_(_, array, fn, val)`
+ /// * `result = array.reduce_(_, fn, val[, thisObj])`
/// `fn` is called as `val = fn(_, val, elt, i, array)`.
Array.prototype.reduce_ = fstreamline__.create(function(_, fn, v, thisObj) {
thisObj = thisObj !== undefined ? thisObj : this;
@@ -217,8 +219,7 @@
}
return v;
}, 0)
- /// * `result = flows.reduceRight(_, array, fn, val, [thisObj])`
- /// reduces from end to start by applying `fn` to each element.
+ /// * `result = array.reduceRight_(_, fn, val[, thisObj])`
/// `fn` is called as `val = fn(_, val, elt, i, array)`.
Array.prototype.reduceRight_ = fstreamline__.create(function(_, fn, v, thisObj) {
thisObj = thisObj !== undefined ? thisObj : this;
@@ -229,7 +230,7 @@
return v;
}, 0)
- /// * `array = flows.sort(_, array, compare, [beg], [end])`
+ /// * `array = array.sort_(_, compare [, beg [, end]])`
/// `compare` is called as `cmp = compare(_, elt1, elt2)`
/// Note: this function _changes_ the original array (and returns it)
Array.prototype.sort_ = fstreamline__.create(function(_, compare, beg, end) {var _qsort_ = fstreamline__.create(_qsort);
@@ -274,13 +275,14 @@
return array;
}, 0)
- /// ## Asychronous versions of ES5 Function functions.
///
- /// * `result = fn.apply_(_, thisObj, args, [index])`
- /// Helper to use `Function.prototype.apply` with streamline functions.
+ /// ## Function functions.
+ ///
+ /// * `result = fn.apply_(_, thisObj, args[, index])`
+ /// Helper to use `Function.prototype.apply` inside streamlined functions.
/// Equivalent to `result = fn.apply(thisObj, argsWith_)` where `argsWith_` is
- /// a modified argument list in which the callback has been inserted at `index`
- /// (at the end of the argument list if `index` is not specified).
+ /// a modified `args` in which the callback has been inserted at `index`
+ /// (at the end of the argument list if `index` is omitted).
Function.prototype.apply_ = function(callback, thisObj, args, index) {
Array.prototype.splice.call(args, index != null ? index : args.length, 0, callback);
return this.apply(thisObj, args);
View
9 lib/globals.js
@@ -2,21 +2,24 @@
///
/// # Container for global context
///
-/// The `streamline.lib.globals` is a container for the global `context` object which is maintained across
+/// The `globals` module is a container for the global `context` object which is maintained across
/// asynchronous calls.
///
/// This context is very handy to store information that all calls should be able to access
/// but that you don't want to pass explicitly via function parameters. The most obvious example is
/// the `locale` that each request may set differently and that your low level libraries should
/// be able to retrieve to format messages.
///
+/// `var globals = require('streamline/lib/globals')`
+///
/// * `globals.context = ctx`
/// * `ctx = globals.context`
/// sets and gets the context
///
+/// Note: an empty context (`{}`) is automatically set by the server wrappers of the `streams` module,
+/// before they dispatch a request. So, with these wrappers, each request starts with a fresh empty context.
// This module may be loaded several times so we need a true global (with a secret name!).
+// This implementation also allows us to share the context between modules compiled in callback and fibers mode.
var glob = typeof global === "object" ? global : window;
var secret = "_20c7abceb95c4eb88b7ca1895b1170d1";
module.exports = (glob[secret] = (glob[secret] || {}));
-// Note: this module may also look like overkill but it makes it easy to share the context in
-// programs that mix modules compiled in callback and fibers modes.
View
6 lib/globals.md
@@ -1,15 +1,19 @@
# Container for global context
-The `streamline.lib.globals` is a container for the global `context` object which is maintained across
+The `globals` module is a container for the global `context` object which is maintained across
asynchronous calls.
This context is very handy to store information that all calls should be able to access
but that you don't want to pass explicitly via function parameters. The most obvious example is
the `locale` that each request may set differently and that your low level libraries should
be able to retrieve to format messages.
+`var globals = require('streamline/lib/globals')`
+
* `globals.context = ctx`
* `ctx = globals.context`
sets and gets the context
+Note: an empty context (`{}`) is automatically set by the server wrappers of the `streams` module,
+before they dispatch a request. So, with these wrappers, each request starts with a fresh empty context.
View
79 lib/streams/server/streams._js
@@ -11,14 +11,18 @@
/// The `streams` module contains _pull mode_ wrappers around node streams.
///
/// These wrappers implement a _pull style_ API.
-/// Instead of having the stream _push_ the data to its consumer by emitting `data` and `end` events,
-/// these wrappers let the consumer _pull_ the data from the stream by calling asynchronous `read` methods.
+/// For readable streams, instead of having the stream _push_ the data to its consumer by emitting `data` and `end` events,
+/// the wrapper lets the consumer _pull_ the data from the stream by calling asynchronous `read` methods.
+/// The wrapper takes care of the low level `pause`/`resume` logic.
///
-/// For a bit more background on this design,
-/// you can read [this blog post](http://bjouhier.wordpress.com/2011/04/25/asynchronous-episode-3-adventures-in-event-land/)
+/// Similarly, for writable streams, the wrapper provides a simple asynchronous `write` method and takes
+/// care of the low level `drain` logic.
+///
+/// For more information on this design,
+/// see [this blog post](http://bjouhier.wordpress.com/2011/04/25/asynchronous-episode-3-adventures-in-event-land/)
///
/// For a simple example of this API in action,
-/// see the [google client example](./examples/googleClient_.js)
+/// see the [google client example](../../../examples/streams/googleClient_.js)
var parseUrl = require("url").parse;
var globals = require('streamline/lib/globals');
@@ -57,16 +61,16 @@ function wrapEvents(constr, events) {
}
///
-/// ## Emitter
+/// ## Wrapper
///
/// Base wrapper for all objects that emit an `end` or `close` event.
/// All stream wrappers derive from this wrapper.
///
-/// * `wrapper = new streams.Emitter(stream)`
+/// * `wrapper = new streams.Wrapper(stream)`
/// creates a wrapper.
-function Emitter(emitter) {
+function Wrapper(emitter) {
var self = this;
var closed = false;
emitter.on('close', function() {
@@ -129,13 +133,13 @@ function Emitter(emitter) {
///
/// All readable stream wrappers derive from this wrapper.
///
-/// * `stream = new streams.ReadableStream(stream, [options])`
+/// * `stream = new streams.ReadableStream(stream[, options])`
/// creates a readable stream wrapper.
function ReadableStream(emitter, options) {
var self = this;
- Emitter.call(self, emitter);
+ Wrapper.call(self, emitter);
options = options || {}
var _low = Math.max(options.lowMark || 0, 0);
var _high = Math.max(options.highMark || 0, _low);
@@ -220,10 +224,12 @@ function ReadableStream(emitter, options) {
if (enc) emitter.setEncoding(enc);
return self;
}
- /// * `data = stream.read(_, [len])`
+ /// * `data = stream.read(_[, len])`
/// reads asynchronously from the stream and returns a `string` or a `Buffer` depending on the encoding.
/// If a `len` argument is passed, the `read` call returns when `len` characters or bytes
- /// (depending on encoding) have been read, or when the underlying stream has emitted its `end` event.
+ /// (depending on encoding) have been read, or when the underlying stream has emitted its `end` event
+ /// (so it may return less than `len` bytes or chars).
+ /// Reads till the end if `len` is negative.
/// Without `len`, the read calls returns the data chunks as they have been emitted by the underlying stream.
/// Once the end of stream has been reached, the `read` call returns `null`.
self.read = function(_, len) {
@@ -273,13 +279,13 @@ wrapEvents(ReadableStream, ["error", "data", "end", "close"]);
///
/// All writable stream wrappers derive from this wrapper.
///
-/// * `stream = new streams.WritableStream(stream, [options])`
+/// * `stream = new streams.WritableStream(stream[, options])`
/// creates a writable stream wrapper.
function WritableStream(emitter, options) {
var self = this;
- Emitter.call(self, emitter);
+ Wrapper.call(self, emitter);
options = options || {}
var _error;
var _onDrain;
@@ -309,12 +315,9 @@ function WritableStream(emitter, options) {
}
}
- /// * `stream.write(_, data, [enc])`
+ /// * `stream.write(_, data[, enc])`
/// Writes the data.
/// This operation is asynchronous because it _drains_ the stream if necessary.
- /// If you have a lot of small write operations to perform and you don't want the overhead of draining at every step,
- /// you can write to the underlying stream with `stream.emitter.write(data)` most of the time
- /// and call `stream.write(_, data)` once in a while to drain.
/// Returns `this` for chaining.
self.write = function(_, data, enc) {
if (_error) throw new Error(_error.message);
@@ -353,9 +356,9 @@ function _getEncoding(headers) {
/// ## HttpServerRequest
///
/// This is a wrapper around node's `http.ServerRequest`:
-/// This stream is readable (see Readable Stream above).
+/// This stream is readable (see ReadableStream above).
///
-/// * `request = new streams.HttpServerRequest(req, [options])`
+/// * `request = new streams.HttpServerRequest(req[, options])`
/// returns a wrapper around `req`, an `http.ServerRequest` object.
/// The `options` parameter can be used to pass `lowMark` and `highMark` values.
@@ -385,9 +388,9 @@ wrapProperties(HttpServerRequest, true, ["method", "url", "headers", "trailers",
/// ## HttpServerResponse
///
/// This is a wrapper around node's `http.ServerResponse`.
-/// This stream is writable (see Writable Stream above).
+/// This stream is writable (see WritableStream above).
///
-/// * `response = new streams.HttpServerResponse(resp, [options])`
+/// * `response = new streams.HttpServerResponse(resp[, options])`
/// returns a wrapper around `resp`, an `http.ServerResponse` object.
@@ -425,7 +428,7 @@ function _fixHttpServerOptions(options) {
// Abstract class shared by HttpServer and NetServer
function Server(emitter) {
var self = this;
- Emitter.call(self, emitter);
+ Wrapper.call(self, emitter);
self.listen = function(_, args) {
if (self.closed) throw new Error("cannot listen: server is closed");
@@ -454,11 +457,12 @@ function Server(emitter) {
///
/// This is a wrapper around node's `http.Server` object:
///
-/// * `server = streams.createHttpServer(requestListener, [options])`
+/// * `server = streams.createHttpServer(requestListener[, options])`
/// creates the wrapper.
/// `requestListener` is called as `requestListener(request, response, _)`
-/// where `request` and `response` are wrappers around `http.ServerRequest` and `http.ServerResponse`.
-/// * `server.listen(_, port, [host])`
+/// where `request` and `response` are wrappers around `http.ServerRequest` and `http.ServerResponse`.
+/// A fresh empty global context is set before every call to `requestListener` (see [`streamline/lib.globals](../globals.md)).
+/// * `server.listen(_, port[, host])`
/// * `server.listen(_, path)`
/// (same as `http.Server`)
@@ -491,7 +495,7 @@ exports.HttpServer = HttpServer;
///
/// This is a wrapper around node's `http.ClientResponse`
///
-/// This stream is readable (see Readable Stream above).
+/// This stream is readable (see ReadableStream above).
///
/// * `response = request.response(_)`
/// returns the response stream.
@@ -571,7 +575,7 @@ function _fixHttpClientOptions(options) {
///
/// This is a wrapper around node's `http.ClientRequest`.
///
-/// This stream is writable (see Writable Stream above).
+/// This stream is writable (see WritableStream above).
///
/// * `request = streams.httpRequest(options)`
/// creates the wrapper.
@@ -637,9 +641,9 @@ exports.httpRequest = function(options) {
///
/// This is a wrapper around streams returned by TCP and socket clients:
///
-/// These streams are both readable and writable (see Readable Stream and Writable Stream above).
+/// These streams are both readable and writable (see ReadableStream and WritableStream above).
///
-/// * `stream = new streams.NetStream(stream, [options])`
+/// * `stream = new streams.NetStream(stream[, options])`
/// creates a network stream wrapper.
function NetStream(emitter, options) {
@@ -656,9 +660,9 @@ var net; // lazy require
///
/// These are wrappers around node's `net.createConnection`:
///
-/// * `client = streams.tcpClient(port, host, [options])`
+/// * `client = streams.tcpClient(port, host[, options])`
/// returns a TCP connection client.
-/// * `client = streams.socketClient(path, [options])`
+/// * `client = streams.socketClient(path[, options])`
/// returns a socket client.
/// The `options` parameter of the constructor provide options for the stream (`lowMark` and `highMark`).
/// If you want different options for `read` and `write` operations, you can specify them by creating `options.read` and `options.write` sub-objects inside `options`.
@@ -717,7 +721,8 @@ function NetClient(options, args) {
/// creates the wrapper.
/// `connectionListener` is called as `connectionListener(stream, _)`
/// where `stream` is a `NetStream` wrapper around the native connection.
-/// * `server.listen(_, port, [host])`
+/// A fresh empty global context is set before every call to `connectionListener` (see [`streamline/lib.globals](../globals.md)).
+/// * `server.listen(_, port[, host])`
/// * `server.listen(_, path)`
/// (same as `net.Server`)
@@ -743,9 +748,9 @@ function NetServer(serverOptions, connectionListener, streamOptions) {
///
/// ## try/finally wrappers and pump
///
-/// * `result = streams.using(_, constructor, stream, [options,] fn)`
+/// * `result = streams.using(_, constructor, stream[, options], fn)`
/// wraps `stream` with an instance of `constructor`;
-/// passes the wrapper to `fn(_, wrapped)` and closes the stream after `fn` returns.
+/// passes the wrapper to `fn(_, wrapper)` and closes the stream after `fn` returns.
/// `fn` is called inside a `try/finally` block to guarantee that the stream is closed in all cases.
/// Returns the value returned by `fn`.
exports.using = function(_, constructor, emitter, options, fn) {
@@ -758,14 +763,14 @@ exports.using = function(_, constructor, emitter, options, fn) {
}
}
-/// * `result = streams.usingReadable(_, stream, [options,] fn)`
+/// * `result = streams.usingReadable(_, stream[, options], fn)`
/// shortcut for `streams.using(_, streams.ReadableStream, stream, options, fn)`
exports.usingReadable = function(_, emitter, options, fn) {
return exports.using.call(this, _, exports.ReadableStream, emitter, options, fn);
}
-/// * `result = streams.usingWritable(_, stream, [options,] fn)`
+/// * `result = streams.usingWritable(_, stream[, options], fn)`
/// shortcut for `streams.using(_, streams.WritableStream, stream, options, fn)`
exports.usingWritable = function(_, emitter, options, fn) {
return exports.using.call(this, _, exports.WritableStream, emitter, options, fn);
View
71 lib/streams/server/streams.md
@@ -4,21 +4,25 @@
The `streams` module contains _pull mode_ wrappers around node streams.
These wrappers implement a _pull style_ API.
-Instead of having the stream _push_ the data to its consumer by emitting `data` and `end` events,
-these wrappers let the consumer _pull_ the data from the stream by calling asynchronous `read` methods.
+For readable streams, instead of having the stream _push_ the data to its consumer by emitting `data` and `end` events,
+the wrapper lets the consumer _pull_ the data from the stream by calling asynchronous `read` methods.
+The wrapper takes care of the low level `pause`/`resume` logic.
-For a bit more background on this design,
-you can read [this blog post](http://bjouhier.wordpress.com/2011/04/25/asynchronous-episode-3-adventures-in-event-land/)
+Similarly, for writable streams, the wrapper provides a simple asynchronous `write` method and takes
+care of the low level `drain` logic.
+
+For more information on this design,
+see [this blog post](http://bjouhier.wordpress.com/2011/04/25/asynchronous-episode-3-adventures-in-event-land/)
For a simple example of this API in action,
-see the [google client example](./examples/googleClient_.js)
+see the [google client example](../../../examples/streams/googleClient_.js)
-## Emitter
+## Wrapper
Base wrapper for all objects that emit an `end` or `close` event.
All stream wrappers derive from this wrapper.
-* `wrapper = new streams.Emitter(stream)`
+* `wrapper = new streams.Wrapper(stream)`
creates a wrapper.
* `emitter = wrapper.emitter`
returns the underlying emitter. The emitter stream can be used to attach additional observers.
@@ -32,15 +36,17 @@ All stream wrappers derive from this wrapper.
All readable stream wrappers derive from this wrapper.
-* `stream = new streams.ReadableStream(stream, [options])`
+* `stream = new streams.ReadableStream(stream[, options])`
creates a readable stream wrapper.
* `stream.setEncoding(enc)`
sets the encoding.
returns `this` for chaining.
-* `data = stream.read(_, [len])`
+* `data = stream.read(_[, len])`
reads asynchronously from the stream and returns a `string` or a `Buffer` depending on the encoding.
If a `len` argument is passed, the `read` call returns when `len` characters or bytes
- (depending on encoding) have been read, or when the underlying stream has emitted its `end` event.
+ (depending on encoding) have been read, or when the underlying stream has emitted its `end` event
+ (so it may return less than `len` bytes or chars).
+ Reads till the end if `len` is negative.
Without `len`, the read calls returns the data chunks as they have been emitted by the underlying stream.
Once the end of stream has been reached, the `read` call returns `null`.
* `data = stream.readAll(_)`
@@ -54,14 +60,11 @@ All readable stream wrappers derive from this wrapper.
All writable stream wrappers derive from this wrapper.
-* `stream = new streams.WritableStream(stream, [options])`
+* `stream = new streams.WritableStream(stream[, options])`
creates a writable stream wrapper.
-* `stream.write(_, data, [enc])`
+* `stream.write(_, data[, enc])`
Writes the data.
This operation is asynchronous because it _drains_ the stream if necessary.
- If you have a lot of small write operations to perform and you don't want the overhead of draining at every step,
- you can write to the underlying stream with `stream.emitter.write(data)` most of the time
- and call `stream.write(_, data)` once in a while to drain.
Returns `this` for chaining.
* `stream.end()`
signals the end of the send operation.
@@ -70,9 +73,9 @@ All writable stream wrappers derive from this wrapper.
## HttpServerRequest
This is a wrapper around node's `http.ServerRequest`:
-This stream is readable (see Readable Stream above).
+This stream is readable (see ReadableStream above).
-* `request = new streams.HttpServerRequest(req, [options])`
+* `request = new streams.HttpServerRequest(req[, options])`
returns a wrapper around `req`, an `http.ServerRequest` object.
The `options` parameter can be used to pass `lowMark` and `highMark` values.
* `method = request.method`
@@ -87,9 +90,9 @@ This stream is readable (see Readable Stream above).
## HttpServerResponse
This is a wrapper around node's `http.ServerResponse`.
-This stream is writable (see Writable Stream above).
+This stream is writable (see WritableStream above).
-* `response = new streams.HttpServerResponse(resp, [options])`
+* `response = new streams.HttpServerResponse(resp[, options])`
returns a wrapper around `resp`, an `http.ServerResponse` object.
* `response.writeContinue()`
* `response.writeHead(head)`
@@ -104,19 +107,20 @@ This stream is writable (see Writable Stream above).
This is a wrapper around node's `http.Server` object:
-* `server = streams.createHttpServer(requestListener, [options])`
+* `server = streams.createHttpServer(requestListener[, options])`
creates the wrapper.
`requestListener` is called as `requestListener(request, response, _)`
- where `request` and `response` are wrappers around `http.ServerRequest` and `http.ServerResponse`.
-* `server.listen(_, port, [host])`
+ where `request` and `response` are wrappers around `http.ServerRequest` and `http.ServerResponse`.
+ A fresh empty global context is set before every call to `requestListener` (see [`streamline/lib.globals](../globals.md)).
+* `server.listen(_, port[, host])`
* `server.listen(_, path)`
(same as `http.Server`)
## HttpClientResponse
This is a wrapper around node's `http.ClientResponse`
-This stream is readable (see Readable Stream above).
+This stream is readable (see ReadableStream above).
* `response = request.response(_)`
returns the response stream.
@@ -137,7 +141,7 @@ This stream is readable (see Readable Stream above).
This is a wrapper around node's `http.ClientRequest`.
-This stream is writable (see Writable Stream above).
+This stream is writable (see WritableStream above).
* `request = streams.httpRequest(options)`
creates the wrapper.
@@ -158,18 +162,18 @@ This stream is writable (see Writable Stream above).
This is a wrapper around streams returned by TCP and socket clients:
-These streams are both readable and writable (see Readable Stream and Writable Stream above).
+These streams are both readable and writable (see ReadableStream and WritableStream above).
-* `stream = new streams.NetStream(stream, [options])`
+* `stream = new streams.NetStream(stream[, options])`
creates a network stream wrapper.
## TCP and Socket clients
These are wrappers around node's `net.createConnection`:
-* `client = streams.tcpClient(port, host, [options])`
+* `client = streams.tcpClient(port, host[, options])`
returns a TCP connection client.
-* `client = streams.socketClient(path, [options])`
+* `client = streams.socketClient(path[, options])`
returns a socket client.
The `options` parameter of the constructor provide options for the stream (`lowMark` and `highMark`).
If you want different options for `read` and `write` operations, you can specify them by creating `options.read` and `options.write` sub-objects inside `options`.
@@ -184,20 +188,21 @@ This is a wrapper around node's `net.Server` object:
creates the wrapper.
`connectionListener` is called as `connectionListener(stream, _)`
where `stream` is a `NetStream` wrapper around the native connection.
-* `server.listen(_, port, [host])`
+ A fresh empty global context is set before every call to `connectionListener` (see [`streamline/lib.globals](../globals.md)).
+* `server.listen(_, port[, host])`
* `server.listen(_, path)`
(same as `net.Server`)
## try/finally wrappers and pump
-* `result = streams.using(_, constructor, stream, [options,] fn)`
+* `result = streams.using(_, constructor, stream[, options], fn)`
wraps `stream` with an instance of `constructor`;
- passes the wrapper to `fn(_, wrapped)` and closes the stream after `fn` returns.
+ passes the wrapper to `fn(_, wrapper)` and closes the stream after `fn` returns.
`fn` is called inside a `try/finally` block to guarantee that the stream is closed in all cases.
Returns the value returned by `fn`.
-* `result = streams.usingReadable(_, stream, [options,] fn)`
+* `result = streams.usingReadable(_, stream[, options], fn)`
shortcut for `streams.using(_, streams.ReadableStream, stream, options, fn)`
-* `result = streams.usingWritable(_, stream, [options,] fn)`
+* `result = streams.usingWritable(_, stream[, options], fn)`
shortcut for `streams.using(_, streams.WritableStream, stream, options, fn)`
* `streams.pump(_, inStream, outStream)`
Pumps from `inStream` to `outStream`.
View
9 lib/tools/docTool._js
@@ -10,15 +10,18 @@
///
/// Usage:
///
-/// node streamline/lib/tools/docTool [path]
+/// _node streamline/lib/tools/docTool [path]
///
-/// Extracts documentation comments from `.js` files and generates `API.md` file
+/// Extracts documentation comments from `.js` and `._js` files and generates `API.md` file
/// under package root.
///
/// Top of source file must contain `/// !doc` marker to enable doc extraction.
/// Documentation comments must start with `/// ` (with 1 trailing space).
/// Extraction can be turned off with `/// !nodoc` and turned back on with `/// !doc`.
///
+/// `/// !doc` can be replaced by `/// !example`.
+/// In this case, the source code will be transformed to source blocks in the generated `.md` file.
+///
/// The tool can also be invoked programatically with:
///
/// `var docTool = require('streamline/lib/tools/docTool')`
@@ -131,7 +134,7 @@ exports.generate = function(_, path, options) {
return toc;
} else return null;
}
- //options.verbose = true;
+ // options.verbose = true;
_generate(_, path);
}
if (process.argv[1] && process.argv[1].indexOf("/docTool") >= 0) exports.generate(_, fsp.join(process.cwd(), process.argv[2] || '.'), {
View
7 lib/tools/docTool.md
@@ -3,15 +3,18 @@
Usage:
- node streamline/lib/tools/docTool [path]
+ _node streamline/lib/tools/docTool [path]
-Extracts documentation comments from `.js` files and generates `API.md` file
+Extracts documentation comments from `.js` and `._js` files and generates `API.md` file
under package root.
Top of source file must contain `/// !doc` marker to enable doc extraction.
Documentation comments must start with `/// ` (with 1 trailing space).
Extraction can be turned off with `/// !nodoc` and turned back on with `/// !doc`.
+`/// !doc` can be replaced by `/// !example`.
+In this case, the source code will be transformed to source blocks in the generated `.md` file.
+
The tool can also be invoked programatically with:
`var docTool = require('streamline/lib/tools/docTool')`
View
7 lib/util/flows.js
@@ -27,8 +27,7 @@
///
/// # Flow control utilities
///
-/// `var flows = require('streamline/lib/util/flows');
-///
+/// `var flows = require('streamline/lib/util/flows')`
///
(function(exports) {
"use strict";
@@ -159,6 +158,10 @@
///
/// The `funnel` function can also be used to implement critical sections. Just set funnel's `max` parameter to 1.
///
+ /// If `max` is set to 0, a default number of parallel executions is allowed.
+ /// This default number can be read and set via `flows.funnel.defaultSize`.
+ /// If `max` is negative, the funnel does not limit the level of parallelism.
+ ///
/// The funnel can be closed with `fun.close()`.
/// When a funnel is closed, the operations that are still in the funnel will continue but their callbacks
/// won't be called, and no other operation will enter the funnel.
View
7 lib/util/flows.md
@@ -1,8 +1,7 @@
# Flow control utilities
-`var flows = require('streamline/lib/util/flows');
-
+`var flows = require('streamline/lib/util/flows')`
* `fun = flows.funnel(max)`
limits the number of concurrent executions of a given code block.
@@ -21,6 +20,10 @@ The `diskUsage2.js` example demonstrates how these calls can be combined to cont
The `funnel` function can also be used to implement critical sections. Just set funnel's `max` parameter to 1.
+If `max` is set to 0, a default number of parallel executions is allowed.
+This default number can be read and set via `flows.funnel.defaultSize`.
+If `max` is negative, the funnel does not limit the level of parallelism.
+
The funnel can be closed with `fun.close()`.
When a funnel is closed, the operations that are still in the funnel will continue but their callbacks
won't be called, and no other operation will enter the funnel.

0 comments on commit ae31fe9

Please sign in to comment.
Something went wrong with that request. Please try again.