diff --git a/Promise.js b/Promise.js index 3551373..5bca12e 100644 --- a/Promise.js +++ b/Promise.js @@ -174,6 +174,8 @@ object.Constructor('IterablePromise', Promise, { // the value they can wait for it... // // + // Spectial cases usefull for extending this constructor... + // // Clone the iterator... // Promise.iter([ .. ], false) // -> iterable-promise diff --git a/README.md b/README.md index 34e8b6d..1731669 100644 --- a/README.md +++ b/README.md @@ -5,29 +5,28 @@ A library of JavaScript type extensions, types and type utilities. - [types.js](#typesjs) - [Installation](#installation) - [Basic usage](#basic-usage) - - [Built-in type extensions](#built-in-type-extensions) - - [`Object`](#object) - - [`Object.deepKeys(..)`](#objectdeepkeys) - - [`Object.copy(..)` (EXPERIMENTAL)](#objectcopy-experimental) - - [`Object.flatCopy(..)`](#objectflatcopy) - - [`Object.match(..)`](#objectmatch) - - [`Object.matchPartial(..)`](#objectmatchpartial) - - [`.run(..)`](#objectrun) - - [`Object.sort(..)`](#objectsort) - - [`Array`](#array) - - [`.first(..)` / `.last(..)`](#arrayfirst--arraylast) - - [`.rol(..)`](#arrayrol) - - [`.compact()`](#arraycompact) - - [`.len`](#arraylen) - - [`.unique(..)` / `.tailUnique(..)`](#arrayunique--arraytailunique) - - [`.cmp(..)`](#arraycmp) - - [`.setCmp(..)`](#arraysetcmp) - - [`.sortAs(..)`](#arraysortas) - - [`.inplaceSortAs(..)`](#arrayinplacesortas) - - [`.toKeys(..)`](#arraytokeys) - - [`.toMap(..)`](#arraytomap) - - [`Array.zip(..)` / `.zip(..)`](#arrayzip--arrayzip) - - [`.iter()`](#arrayiter) + - [`Object`](#object) + - [`Object.deepKeys(..)`](#objectdeepkeys) + - [`Object.copy(..)` (EXPERIMENTAL)](#objectcopy-experimental) + - [`Object.flatCopy(..)`](#objectflatcopy) + - [`Object.match(..)`](#objectmatch) + - [`Object.matchPartial(..)`](#objectmatchpartial) + - [`.run(..)`](#objectrun) + - [`Object.sort(..)`](#objectsort) + - [`Array`](#array) + - [`.first(..)` / `.last(..)`](#arrayfirst--arraylast) + - [`.rol(..)`](#arrayrol) + - [`.compact()`](#arraycompact) + - [`.len`](#arraylen) + - [`.unique(..)` / `.tailUnique(..)`](#arrayunique--arraytailunique) + - [`.cmp(..)`](#arraycmp) + - [`.setCmp(..)`](#arraysetcmp) + - [`.sortAs(..)`](#arraysortas) + - [`.inplaceSortAs(..)`](#arrayinplacesortas) + - [`.toKeys(..)`](#arraytokeys) + - [`.toMap(..)`](#arraytomap) + - [`Array.zip(..)` / `.zip(..)`](#arrayzip--arrayzip) + - [`.iter()`](#arrayiter) - [Abortable `Array` iteration](#abortable-array-iteration) - [`array.StopIteration`](#arraystopiteration) - [`.smap(..)` / `.sfilter(..)` / `.sreduce(..)` / `.sforEach(..)`](#arraysmap--arraysfilter--arraysreduce--arraysforeach) @@ -40,26 +39,35 @@ A library of JavaScript type extensions, types and type utilities. - [`Array` (polyfill)](#array-polyfill) - [`.flat()`](#arrayflat) - [`.includes()`](#arrayincludes) - - [`Map`](#map) - - [`.sort(..)`](#mapsort) - - [`Set`](#set) - - [`.unite(..)`](#setunite) - - [`.intersect(..)`](#setintersect) - - [`.subtract(..)`](#setsubtract) - - [`.sort(..)`](#setsort) - - [`Date`](#date) - - [`Date.timeStamp(..)`](#datetimestamp) - - [`Date.fromTimeStamp(..)`](#datefromtimestamp) - - [`Date.str2ms(..)`](#datestr2ms) - - [`.toShortDate(..)`](#datetoshortdate) - - [`.getTimeStamp(..)`](#dategettimestamp) - - [`.setTimeStamp(..)`](#datesettimestamp) - - [`String`](#string) - - [`.capitalize()`](#stringcapitalize) - - [`RegExp`](#regexp) - - [`RegExp.quoteRegExp(..)`](#regexpquoteregexp) - - ['Promise'](#promise) + - [`Map`](#map) + - [`.sort(..)`](#mapsort) + - [`Set`](#set) + - [`.unite(..)`](#setunite) + - [`.intersect(..)`](#setintersect) + - [`.subtract(..)`](#setsubtract) + - [`.sort(..)`](#setsort) + - [`Date`](#date) + - [`Date.timeStamp(..)`](#datetimestamp) + - [`Date.fromTimeStamp(..)`](#datefromtimestamp) + - [`Date.str2ms(..)`](#datestr2ms) + - [`.toShortDate(..)`](#datetoshortdate) + - [`.getTimeStamp(..)`](#dategettimestamp) + - [`.setTimeStamp(..)`](#datesettimestamp) + - [`String`](#string) + - [`.capitalize()`](#stringcapitalize) + - [`RegExp`](#regexp) + - [`RegExp.quoteRegExp(..)`](#regexpquoteregexp) + - [`Promise`](#promise) + - [Cooperative promises](#cooperative-promises) - [`Promise.cooperative(..)`](#promisecooperative) + - [`.set(..)`](#promise-coopset) + - [`.isSet`](#promise-coopisset) + - [Promise iteration](#promise-iteration) + - [`Promise.iter(..)` / `promise.IterablePromise(..)`](#promiseiter--promiseiterablepromise) + - [`.map(..)` / `.filter(..)` / `.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce) + - [`.flat(..)`](#promise-iterflat) + - [`.then(..)` / `.catch(..)` / `.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally) + - [Advanced handler](#advanced-handler) - [Generator extensions and utilities](#generator-extensions-and-utilities) - [The basics](#the-basics) - [`Generator`](#generator) @@ -149,11 +157,13 @@ var containers = require('ig-types/containers') ``` -## Built-in type extensions +## `Object` -### `Object` +```javascript +require('ig-types/Object') +``` -#### `Object.deepKeys(..)` +### `Object.deepKeys(..)` ``` Object.deepKeys() @@ -178,7 +188,7 @@ Object.keys(b) // -> ['y'] Object.deepKeys(b) // -> ['x', 'y'] ``` -#### `Object.copy(..)` (EXPERIMENTAL) +### `Object.copy(..)` (EXPERIMENTAL) ``` Object.copy() @@ -197,7 +207,7 @@ Note that this will make no attempt to clone object type. _XXX not yet sure how useful this is._ -#### `Object.flatCopy(..)` +### `Object.flatCopy(..)` ``` Object.flatCopy() @@ -207,11 +217,11 @@ Object.flatCopy() Copy all attributes from the prototype chain of `` into ``. -#### `Object.match(..)` +### `Object.match(..)` -#### `Object.matchPartial(..)` +### `Object.matchPartial(..)` -#### `.run(..)` +### `.run(..)` ``` .run() @@ -248,7 +258,7 @@ For more info see: https://github.com/flynx/object-run.js -#### `Object.sort(..)` +### `Object.sort(..)` Sort `` attributes (same as `Array`'s `.sort(..)`) ``` @@ -290,9 +300,17 @@ Object.keys(Object.sort(o, ['x', 'a', '100'])) -### `Array` +## `Array` -#### `.first(..)` / `.last(..)` +```javascript +require('ig-types/Array') +``` +or +```javascript +var array = require('ig-types/Array') +``` + +### `.first(..)` / `.last(..)` Get the first/last items of ``. ``` @@ -316,7 +334,7 @@ Note that these do not affect `` length unless setting items on an empty ``. -#### `.rol(..)` +### `.rol(..)` Roll `` in-place left. ``` @@ -331,7 +349,7 @@ Roll `` in-place left. To roll right pass a negative `n` to `.rol(..)`. -#### `.compact()` +### `.compact()` ``` .compact() @@ -342,7 +360,7 @@ Generate a compact `` from a sparse ``, i.e. removing all the empty slots. -#### `.len` +### `.len` Number of non-empty slots/elements in ``. @@ -357,12 +375,12 @@ L.compact().length Note that this is different from `.length` in that writing to `.len` has no effect. -#### `.unique(..)` / `.tailUnique(..)` +### `.unique(..)` / `.tailUnique(..)` Generate an array with all duplicate elements removed. -#### `.cmp(..)` +### `.cmp(..)` ``` .cmp() @@ -377,19 +395,19 @@ This will return `true` if: - values on the same positions are equal. -#### `.setCmp(..)` +### `.setCmp(..)` -#### `.sortAs(..)` +### `.sortAs(..)` -#### `.inplaceSortAs(..)` +### `.inplaceSortAs(..)` -#### `.toKeys(..)` +### `.toKeys(..)` -#### `.toMap(..)` +### `.toMap(..)` -#### `Array.zip(..)` / `.zip(..)` +### `Array.zip(..)` / `.zip(..)` -#### `.iter()` +### `.iter()` Return an iterator/generator from the current array. @@ -551,51 +569,193 @@ Default value: `50` #### `.includes()` -### `Map` +## `Map` -#### `.sort(..)` +```javascript +require('ig-types/Map') +``` + +### `.sort(..)` -### `Set` +## `Set` -#### `.unite(..)` - -#### `.intersect(..)` - -#### `.subtract(..)` - -#### `.sort(..)` +```javascript +require('ig-types/Set') +``` -### `Date` +### `.unite(..)` -#### `Date.timeStamp(..)` +### `.intersect(..)` -#### `Date.fromTimeStamp(..)` +### `.subtract(..)` -#### `Date.str2ms(..)` - -#### `.toShortDate(..)` - -#### `.getTimeStamp(..)` - -#### `.setTimeStamp(..)` +### `.sort(..)` -### `String` +## `Date` -#### `.capitalize()` +```javascript +require('ig-types/Date') +``` + +### `Date.timeStamp(..)` + +### `Date.fromTimeStamp(..)` + +### `Date.str2ms(..)` + +### `.toShortDate(..)` + +### `.getTimeStamp(..)` + +### `.setTimeStamp(..)` -### `RegExp` +## `String` -#### `RegExp.quoteRegExp(..)` +```javascript +require('ig-types/String') +``` + +### `.capitalize()` -### 'Promise' +## `RegExp` + +```javascript +require('ig-types/RegExp') +``` + +### `RegExp.quoteRegExp(..)` + + +## `Promise` + +```javascript +require('ig-types/Promise') +``` +or +```javascript +var promise = require('ig-types/Promise') +``` + + + +### Cooperative promises #### `Promise.cooperative(..)` +#### `.set(..)` + +#### `.isSet` + + +### Promise iteration + +An _iterable promise_ is on one hand very similar to `Promise.all(..)` in that it +generally takes a list of values each could be either an explicit value or a +promise, and it is similar to a _generator_ in that allows iteration over the +contained values and chaining of operations but unlike `Promise.all(..)` this +iteration occurs depth first instead of breadth first. + +Here is a traditional example using `Promise.all(..)`: +```javascript +var p = Promise.all([ .. ]) + // this will not execute until ALL the inputs resolve... + .then(function(lst){ + return lst + .filter(function(e){ + + }) + // this will not run until ALL of lst is filtered... + .map(function(e){ + + }) }) +``` + +```javascript +var p = Promise.iter([ .. ]) + // each element is processed as soon as it is ready disregarding of its order + // in the input array... + .filter(function(e){ + + }) + // items reach here as soon as they are returned by the filter stage... + // NOTE: the filter handler may return promises, those will not be processed + // until they are resolved... + .map(function(e){ + + }) + // .then(..) explicitly waits for the whole list of inputs to resolve... + .then(function(lst){ + + }) +``` + +This approach has a number of advantages: +- items are processed as soon as they are available without waiting for the + slowest promise on each level to resolve +- simpler and more intuitive code + +And some disadvantages: +- item indexes are unknowable until all the promises resolve. + + + +#### `Promise.iter(..)` / `promise.IterablePromise(..)` + +Create an _iterable promise_ +``` +Promise.iter() + -> +``` +#### `.map(..)` / `.filter(..)` / `.reduce(..)` + +#### `.flat(..)` + + +#### `.then(..)` / `.catch(..)` / `.finally(..)` + +#### Advanced handler + +``` +Promise.iter(, ) + -> + +() + -> [ ] +``` + +```bnf + ::= + [] + | [ , .. ] + + ::= + [] + | [ , .. ] + | + | +``` + +Example: +```javascript +var p = Promise.iter( + // NOTE: if you want an element to explicitly be an array wrap it in + // an array -- like the last element here... + [[1, 2], 3, Promise.resolve(4), [[5, 6]]], + function(elem){ + return elem % 2 == 0 ? + [elem, elem] + : elem instanceof Array ? + [elem] + : [] }) + .then(function(lst){ + console.log(lst) // -> [2, 2, 4, 4, [5, 6]] + }) +``` ## Generator extensions and utilities @@ -808,6 +968,11 @@ otherwise [`.unorderedRename(..)`](#unique-key-mapunorderedrename) is called. ## Event +```javascript +var event = require('ig-types/event') +``` + + ### `event.Eventfull(..)` ### `event.Event(..)` @@ -837,6 +1002,11 @@ to trigger event if the first argument was a function. ## Runner +```javascript +var runner = require('ig-types/runner') +``` + + ### `runner.Queue(..)` / `runner.Queue.run(..)` #### `.state`