2020-10-07 03:53:10 +03:00
# types.js
A library of JavaScript type extensions, types and type utilities.
- [types.js ](#typesjs )
2020-10-07 07:33:58 +03:00
- [Installation ](#installation )
- [Basic usage ](#basic-usage )
2020-11-18 06:09:43 +03:00
- [`Object` ](#object )
- [`Object.deepKeys(..)` ](#objectdeepkeys )
- [`Object.copy(..)` (EXPERIMENTAL) ](#objectcopy-experimental )
- [`Object.flatCopy(..)` ](#objectflatcopy )
- [`Object.match(..)` ](#objectmatch )
- [`Object.matchPartial(..)` ](#objectmatchpartial )
- [`<object>.run(..)` ](#objectrun )
- [`Object.sort(..)` ](#objectsort )
- [`Array` ](#array )
- [`<array>.first(..)` / `<array>.last(..)` ](#arrayfirst--arraylast )
- [`<array>.rol(..)` ](#arrayrol )
- [`<array>.compact()` ](#arraycompact )
- [`<array>.len` ](#arraylen )
2020-12-08 01:53:40 +03:00
- [`<array>.unique()` / `<array>.tailUnique()` ](#arrayunique--arraytailunique )
- [`<array>.trim()` / `<array>.trimStart()` / `<array>.trimEnd()` ](#arraytrim--arraytrimstart--arraytrimend )
2020-11-18 06:09:43 +03:00
- [`<array>.cmp(..)` ](#arraycmp )
- [`<array>.setCmp(..)` ](#arraysetcmp )
- [`<array>.sortAs(..)` ](#arraysortas )
- [`<array>.inplaceSortAs(..)` ](#arrayinplacesortas )
- [`<array>.toKeys(..)` ](#arraytokeys )
- [`<array>.toMap(..)` ](#arraytomap )
- [`Array.zip(..)` / `<array>.zip(..)` ](#arrayzip--arrayzip )
2020-11-18 06:59:56 +03:00
- [`Array.iter(..)` / `<array>.iter()` ](#arrayiter--arrayiter )
2020-11-07 03:19:52 +03:00
- [Abortable `Array` iteration ](#abortable-array-iteration )
2020-11-23 22:27:30 +03:00
- [`array.STOP` / `array.STOP(..)` ](#arraystop--arraystop )
2020-11-07 03:19:52 +03:00
- [`<array>.smap(..)` / `<array>.sfilter(..)` / `<array>.sreduce(..)` / `<array>.sforEach(..)` ](#arraysmap--arraysfilter--arraysreduce--arraysforeach )
2020-10-11 03:09:48 +03:00
- [Large `Array` iteration (chunked) ](#large-array-iteration-chunked )
2020-11-23 22:27:30 +03:00
- [`array.STOP` / `array.STOP(..)` ](#arraystop--arraystop-1 )
2020-10-11 03:09:48 +03:00
- [`<array>.CHUNK_SIZE` ](#arraychunk_size )
2020-12-08 01:53:40 +03:00
- [`<array>.mapChunks(..)` / `<array>.filterChunks(..)` / `<array>.reduceChunks(..)` ](#arraymapchunks--arrayfilterchunks--arrayreducechunks )
2020-11-18 06:09:43 +03:00
- [`Map` ](#map )
- [`<map>.sort(..)` ](#mapsort )
- [`Set` ](#set )
- [`<set>.unite(..)` ](#setunite )
- [`<set>.intersect(..)` ](#setintersect )
- [`<set>.subtract(..)` ](#setsubtract )
- [`<set>.sort(..)` ](#setsort )
- [`Date` ](#date )
- [`Date.timeStamp(..)` ](#datetimestamp )
- [`Date.fromTimeStamp(..)` ](#datefromtimestamp )
- [`Date.str2ms(..)` ](#datestr2ms )
- [`<date>.toShortDate(..)` ](#datetoshortdate )
- [`<date>.getTimeStamp(..)` ](#dategettimestamp )
- [`<date>.setTimeStamp(..)` ](#datesettimestamp )
- [`String` ](#string )
- [`<string>.capitalize()` ](#stringcapitalize )
2020-12-17 18:55:28 +03:00
- [`<string>.indent(..)` ](#stringindent )
2020-11-18 06:09:43 +03:00
- [`RegExp` ](#regexp )
- [`RegExp.quoteRegExp(..)` ](#regexpquoteregexp )
- [`Promise` ](#promise )
2021-04-06 14:27:48 +03:00
- [Interactive promises ](#interactive-promises )
- [`Promise.interactive(..)` ](#promiseinteractive )
- [`<promise-inter>.send(..)` ](#promise-intersend )
2021-04-07 14:47:25 +03:00
- [`<promise-inter>.then(..)` ](#promise-interthen )
2020-11-18 06:09:43 +03:00
- [Cooperative promises ](#cooperative-promises )
2021-04-07 14:47:25 +03:00
- [`Promise.cooperative()` ](#promisecooperative )
2020-11-18 06:09:43 +03:00
- [`<promise-coop>.set(..)` ](#promise-coopset )
- [`<promise-coop>.isSet` ](#promise-coopisset )
2021-04-07 14:47:25 +03:00
- [`<promise-coop>.then(..)` ](#promise-coopthen )
2020-11-18 06:09:43 +03:00
- [Promise iteration ](#promise-iteration )
- [`Promise.iter(..)` / `promise.IterablePromise(..)` ](#promiseiter--promiseiterablepromise )
- [`<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)` ](#promise-itermap--promise-iterfilter--promise-iterreduce )
- [`<promise-iter>.flat(..)` ](#promise-iterflat )
- [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)` ](#promise-iterthen--promise-itercatch--promise-iterfinally )
- [Advanced handler ](#advanced-handler )
2020-11-10 03:25:00 +03:00
- [Generator extensions and utilities ](#generator-extensions-and-utilities )
- [The basics ](#the-basics )
2021-03-24 18:57:02 +03:00
- [`generator.Generator` ](#generatorgenerator )
2020-11-10 03:25:00 +03:00
- [`generator.iter(..)` ](#generatoriter )
2020-11-10 03:04:04 +03:00
- [Generator instance iteration ](#generator-instance-iteration )
2021-03-25 02:59:15 +03:00
- [`<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)` ](#generatormap--generatorfilter--generatorreduce )
- [`<generator>.slice(..)` ](#generatorslice )
- [`<generator>.at(..)` ](#generatorat )
- [`<generator>.flat(..)` ](#generatorflat )
- [`<generator>.shift()` / `<generator>.pop()` ](#generatorshift--generatorpop )
2020-11-10 03:04:04 +03:00
- [`<generator>.promise()` ](#generatorpromise )
- [`<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)` ](#generatorthen--generatorcatch--generatorfinally )
- [`<generator>.toArray()` ](#generatortoarray )
2020-11-18 06:59:56 +03:00
- [Generator constructor iteration ](#generator-constructor-iteration )
2021-03-25 02:59:15 +03:00
- [`<Generator>.at(..)` ](#generatorat-1 )
- [`<Generator>.shift()` / `<Generator>.pop()` ](#generatorshift--generatorpop-1 )
- [`<Generator>.slice(..)` ](#generatorslice-1 )
- [`<Generator>.map(..)` / `<Generator>.filter(..)` / `<Generator>.reduce(..)` / `<Generator>.flat()` ](#generatormap--generatorfilter--generatorreduce--generatorflat )
2021-03-24 18:57:02 +03:00
- [`<Generator>.toArray()` ](#generatortoarray-1 )
- [`<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)` ](#generatorthen--generatorcatch--generatorfinally-1 )
2020-10-07 03:53:10 +03:00
- [Containers ](#containers )
2020-10-07 07:33:58 +03:00
- [`containers.UniqueKeyMap()` (`Map`) ](#containersuniquekeymap-map )
2020-10-07 14:48:47 +03:00
- [`<unique-key-map>.set(..)` ](#unique-key-mapset )
2020-10-07 03:53:10 +03:00
- [`<unique-key-map>.reset(..)` ](#unique-key-mapreset )
- [`<unique-key-map>.rename(..)` ](#unique-key-maprename )
2020-10-07 15:09:36 +03:00
- [`<unique-key-map>.orderedRename(..)` ](#unique-key-maporderedrename )
2020-10-07 14:48:47 +03:00
- [`<unique-key-map>.unorderedRename(..)` ](#unique-key-mapunorderedrename )
2020-10-07 03:53:10 +03:00
- [`<unique-key-map>.keysOf(..)` ](#unique-key-mapkeysof )
2020-10-07 14:48:47 +03:00
- [`<unique-key-map>.originalKey(..)` ](#unique-key-maporiginalkey )
- [`<unique-key-map>.uniqueKey(..)` ](#unique-key-mapuniquekey )
2020-10-07 07:33:58 +03:00
- [`<unique-key-map>.__key_pattern__` ](#unique-key-map__key_pattern__ )
2020-10-07 15:09:36 +03:00
- [`<unique-key-map>.__unordered_rename__` ](#unique-key-map__unordered_rename__ )
2020-11-15 05:13:35 +03:00
- [Event ](#event )
- [`event.Eventfull(..)` ](#eventeventfull )
- [`event.Event(..)` ](#eventevent )
2020-11-16 02:38:19 +03:00
- [`event.TRIGGER` ](#eventtrigger )
2020-11-15 05:13:35 +03:00
- [`event.EventHandlerMixin` ](#eventeventhandlermixin )
- [`<obj>.on(..)` ](#objon )
- [`<obj>.one(..)` ](#objone )
- [`<obj>.off(..)` ](#objoff )
- [`<obj>.trigger(..)` ](#objtrigger )
- [`event.EventDocMixin` ](#eventeventdocmixin )
- [`<obj>.eventfull` ](#objeventfull )
- [`<obj>.events` ](#objevents )
- [`event.EventMixin` ](#eventeventmixin )
2020-11-07 03:19:52 +03:00
- [Runner ](#runner )
2020-11-28 03:47:31 +03:00
- [Micro task queue ](#micro-task-queue )
2020-12-17 18:55:28 +03:00
- [`STOP` ](#stop )
- [`SKIP` ](#skip )
2020-12-08 01:53:40 +03:00
- [`Queue(..)` / `Queue.runTasks(..)` ](#queue--queueruntasks )
- [`Queue.handle(..)` ](#queuehandle )
2020-11-07 03:19:52 +03:00
- [`<queue>.state` ](#queuestate )
- [`<queue>.start(..)` ](#queuestart )
2020-12-08 01:53:40 +03:00
- [`<queue>.stop(..)` ](#queuestop )
- [`<queue>.runTask(..)` ](#queueruntask )
- [`<queue>.tasksAdded(..)` (event) ](#queuetasksadded-event )
- [`<queue>.taskStarting(..)` (event) ](#queuetaskstarting-event )
- [`<queue>.taskFailed(..)` (event) ](#queuetaskfailed-event )
2020-11-07 03:19:52 +03:00
- [`<queue>.taskCompleted(..)` (event) ](#queuetaskcompleted-event )
2020-12-08 01:53:40 +03:00
- [`<queue>.queueEmpty(..)` (event) ](#queuequeueempty-event )
2020-12-17 18:55:28 +03:00
- [`<queue>.prioritize(..)` ](#queueprioritize )
- [`<queue>.delay(..)` ](#queuedelay )
- [`<queue>.add(..)` ](#queueadd )
- [`<queue>.clear(..)` ](#queueclear )
- [`FinalizableQueue(..)` / `FinalizableQueue.runTasks(..)` (Queue) ](#finalizablequeue--finalizablequeueruntasks-queue )
- [`<finalizable-queue>.done(..)` (event/method) ](#finalizable-queuedone-eventmethod )
- [`<finalizable-queue>.abort(..)` (event/method) ](#finalizable-queueabort-eventmethod )
- [`<finalizable-queue>.promise(..)` ](#finalizable-queuepromise )
- [`<finalizable-queue>.then(..)` ](#finalizable-queuethen )
- [`<finalizable-queue>.catch(..)` ](#finalizable-queuecatch )
2020-11-28 03:47:31 +03:00
- [Large task management ](#large-task-management )
- [`runner.TaskManager(..)` ](#runnertaskmanager )
- [`<task-manager>.Task(..)` ](#task-managertask )
- [`<task-manager>.sync_start` ](#task-managersync_start )
- [`<task-manager>.record_times` ](#task-managerrecord_times )
- [`<task-manager>.titled(..)` ](#task-managertitled )
- [`<task-manager>.send(..)` ](#task-managersend )
- [`<task-manager>.stop(..)` ](#task-managerstop )
- [`<task-manager>.done(..)` (event) ](#task-managerdone-event )
- [`<task-manager>.error(..)` (event) ](#task-managererror-event )
- [`<task-manager>.tasksDone(..)` (event) ](#task-managertasksdone-event )
- [`runner.TaskTicket(..)` ](#runnertaskticket )
- [`runner.TaskMixin(..)` ](#runnertaskmixin )
2020-10-07 07:33:58 +03:00
- [License ](#license )
2020-10-07 03:53:10 +03:00
2020-10-07 07:33:58 +03:00
## Installation
```shell
$ npm install -s 'ig-types'
```
## Basic usage
To extend everything:
```javascript
require('ig-types')
```
2020-10-09 23:20:00 +03:00
To have access to additional library types and utilities:
2020-10-07 07:33:58 +03:00
```javascript
var types = require('ig-types')
```
`types.js` is organized so as to be able to import/extend only specific
sub-modules mostly independently so...
2020-10-09 23:20:00 +03:00
In case there is a need to only extend a specific constructor just import
the module dealing with that constructor (`Array` in this case):
2020-10-07 07:33:58 +03:00
```javascript
// require `ig-types/<constructor-name>` ...
require('ig-types/Array')
```
2021-03-24 02:10:55 +03:00
Note that type patching modules are _mostly_ independent.
2020-10-07 07:33:58 +03:00
And to import specific library modules only:
```javascript
var containers = require('ig-types/containers')
```
2020-11-18 06:09:43 +03:00
## `Object`
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
```javascript
require('ig-types/Object')
```
2020-10-07 03:53:10 +03:00
2021-03-24 02:10:55 +03:00
Note that this module imports from
[`object.js` ](https://github.com/flynx/object.js ) and
[`object-run.js` ](https://github.com/flynx/object-run.js ),
see those modules for more details.
2020-11-18 06:09:43 +03:00
### `Object.deepKeys(..)`
2020-10-07 03:53:10 +03:00
2021-03-24 02:10:55 +03:00
Get list of keys from all objects in the prototype chain.
2020-12-08 01:53:40 +03:00
```bnf
2020-10-09 23:20:00 +03:00
Object.deepKeys(< obj > )
2020-12-08 01:53:40 +03:00
-> < keys >
2020-10-09 23:20:00 +03:00
```
2020-10-07 03:53:10 +03:00
2020-10-09 23:20:00 +03:00
This is different from `Object.keys(..)` which only gets _own_ keys from the
current object.
Example:
```javascript
var a = { x: 123 }
var b = Object.create(a)
b.y = 321
// get own keys of b...
Object.keys(b) // -> ['y']
// get all keys accessible from b...
Object.deepKeys(b) // -> ['x', 'y']
```
2021-03-24 02:10:55 +03:00
For more details see:
https://github.com/flynx/object.js#deepkeys
2020-11-18 06:09:43 +03:00
### `Object.copy(..)` (EXPERIMENTAL)
2020-10-10 06:27:51 +03:00
2021-03-24 02:10:55 +03:00
Create a copy of `<obj>`
2020-12-08 01:53:40 +03:00
```bnf
2020-10-10 06:27:51 +03:00
Object.copy(< obj > )
2020-12-08 01:53:40 +03:00
-> < obj-copy >
2020-10-10 06:27:51 +03:00
2021-03-24 02:10:55 +03:00
Object.copy(< obj > , < constructor > )
-> < obj-copy >
```
2020-10-10 06:27:51 +03:00
This will:
- create a blank `<obj-copy>`
- link `<obj-copy>` to the same prototype chain
2021-03-24 02:10:55 +03:00
- assign all _own_ keys from `<obj>` to `<obj-copy>`
This is similar to `Object.clone(..)` but instead of creating a new descendant of
the input object with no data this will instead create a new sibling with a copy
of the instance data.
`<constructor>` if given is called to create the instance to be populated,
otherwise `Object.create(<obj>)` is used.
2020-10-10 06:27:51 +03:00
2021-03-24 02:10:55 +03:00
Note that `.assign(..)` is used to copy data, thus properties will be copied as values, to copy instance properties use `object.js` 's
[`.mixinFlat(..)` ](https://github.com/flynx/object.js#mixinflat ).
2020-10-10 06:27:51 +03:00
2021-03-24 02:10:55 +03:00
Note that this will make no attempt to clone object type, a `<constructor>`
should be passed manually if any instance type other that `Object` is required.
2020-10-10 06:27:51 +03:00
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
### `Object.flatCopy(..)`
2020-10-07 03:53:10 +03:00
2021-03-24 02:10:55 +03:00
Copy all attributes from the prototype chain of `<obj>` into `<new-obj>` .
2020-12-08 01:53:40 +03:00
```bnf
2020-10-10 06:27:51 +03:00
Object.flatCopy(< obj > )
2020-12-08 01:53:40 +03:00
-> < new-obj >
2021-03-24 02:10:55 +03:00
Object.flatCopy(< obj > , < constructor > )
-> < new-obj >
2020-10-10 06:27:51 +03:00
```
2021-03-24 02:10:55 +03:00
This is different to [`.copy(..)` ](#objectcopy-experimental ) in that if
no `<constructor>` is given `<new-obj>` will _not_ be linked into the
prototype chain of `<obj>` , if this behavior is desired use `o => Object.create(o)`
as the `<constructor>` .
2020-10-10 06:27:51 +03:00
2020-11-18 06:09:43 +03:00
### `Object.match(..)`
2020-10-09 23:20:00 +03:00
2021-03-24 02:10:55 +03:00
Attribute/value match two objects (non-recursive).
```bnf
Object.match(< object > , < other > )
-> < bool >
```
Objects `A` and `B` match iff:
- `A` and `B` are _identical_ , i.e. `A === B`
or
- `typeof A == typeof B` _and_ ,
- `A` and `B` have the same number of attributes _and_ ,
- attribute names match _and_ ,
- attribute values are _identical_ .
And for a less strict match:
```bnf
Object.match(< object > , < other > , true)
-> < bool >
```
Like the default case but uses _equality_ instead of _identity_ to match values.
For more details see:
https://github.com/flynx/object.js#match
<!--
XXX should this test based on equality or on identity by default???
...see: Array.cmp(..)
-->
2020-11-18 06:09:43 +03:00
### `Object.matchPartial(..)`
2020-10-09 23:20:00 +03:00
2021-03-24 02:10:55 +03:00
```bnf
Object.matchPartial(< object > , < other > )
-> < bool >
Object.matchPartial(< object > , < other > , true)
-> < bool >
```
Like `.match(..)` but will check for a _partial_ match, i.e. when `<other>` is a non-strict subset of `<object>` .
For more details see:
https://github.com/flynx/object.js#matchpartial
<!--
XXX should this test based on equality or on identity by default???
...see: Array.cmp(..)
-->
2020-11-18 06:09:43 +03:00
### `<object>.run(..)`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 07:33:58 +03:00
< object > .run(< func > )
-> < object >
-> < other >
```
Run a function in the context of `<object>` returning either `<object>`
itself (if returning `undefined` ) or the result.
Note that this is accessible from all JavaScript non-primitive objects,
i.e. everything that inherits from `Object` .
Example:
```javascript
var L = [1, 2, 3]
.map(function(e){
return e * 2 })
// see if the first element is 1 and prepend 1 if it is not...
.run(function(){
if(this[0] != 1){
this.unshift(1) } })
console.log(L) // -> [1, 2, 6, 8]
```
`.run(..)` is also available standalone via:
```shell
$ npm install -s object-run
```
2021-03-24 02:10:55 +03:00
For more details see:
2020-10-07 07:33:58 +03:00
https://github.com/flynx/object-run.js
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
### `Object.sort(..)`
2020-10-07 16:46:59 +03:00
2021-03-24 02:10:55 +03:00
Sort `<obj>` attributes (similar to `Array` 's `.sort(..)` )
2020-12-08 01:53:40 +03:00
```bnf
2020-10-10 06:27:51 +03:00
Object.sort(< obj > )
2020-12-08 01:53:40 +03:00
-> < obj >
2020-10-10 06:27:51 +03:00
```
Sort `<obj>` attributes via `<cmp>` function.
```
Object.sort(< obj > , < cmp > )
2020-12-08 01:53:40 +03:00
-> < obj >
2020-10-10 06:27:51 +03:00
```
Sort `<obj>` attributes to the same order of `<order-list>` .
2020-12-08 01:53:40 +03:00
```bnf
2020-10-10 06:27:51 +03:00
Object.sort(< obj > , < order-list > )
2020-12-08 01:53:40 +03:00
-> < obj >
2020-10-10 06:27:51 +03:00
```
Note that this rewrites all the keys of `<obj>` thus for very large
sets of keys/attributes this may be quite expensive.
Note that some keys of `Object` may misbehave in JavaScript, currently keys
that are string values of numbers are sorted automatically by _number value_
and are not affected by `.sort(..)` , this affects both _Chrome_ and _Firefox_ .
Example:
```javascript
var o = {x: 0, a: 1, '100':2, '0':3, ' 27 ':4, b:5}
// notice that the order is already different to the order of attributes above...
Object.keys(o)
// -> ['0', '100', 'x', 'a', ' 27 ', 'b']
// '0' and '100' are not affected by .sort(..) while ' 27 ' is...
Object.keys(Object.sort(o, ['x', 'a', '100']))
// -> [ '0', '100', 'x', 'a', ' 27 ', 'b' ]
```
2021-04-03 02:11:02 +03:00
This is similar to [`<map>.sort(..)` ](#mapsort ) and [`<ser>.sort(..)` ](#setsort ).
2020-10-07 16:46:59 +03:00
2020-11-18 06:09:43 +03:00
## `Array`
```javascript
require('ig-types/Array')
```
or
```javascript
var array = require('ig-types/Array')
```
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
### `<array>.first(..)` / `<array>.last(..)`
2020-10-07 03:53:10 +03:00
2020-10-07 16:46:59 +03:00
Get the first/last items of `<array>` .
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 16:46:59 +03:00
< array > .first()
2020-12-08 01:53:40 +03:00
-> < item >
2020-10-07 16:46:59 +03:00
< array > .last()
2020-12-08 01:53:40 +03:00
-> < item >
2020-10-07 16:46:59 +03:00
```
Set the first/last items of `<array>` .
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 16:46:59 +03:00
< array > .first(< item > )
-> < array >
< array > .last(< item > )
-> < array >
```
Note that these do not affect `<array>` length unless setting items on
an empty `<array>` .
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
### `<array>.rol(..)`
2020-11-16 18:55:31 +03:00
Roll `<array>` in-place left.
2020-12-08 01:53:40 +03:00
```bnf
2020-11-16 18:55:31 +03:00
< array > .rol()
< array > .rol(1)
2020-12-08 01:53:40 +03:00
-> < array >
2020-11-16 18:55:31 +03:00
< array > .rol(n)
2020-12-08 01:53:40 +03:00
-> < array >
2020-11-16 18:55:31 +03:00
```
2021-03-24 02:10:55 +03:00
To roll _right_ pass a negative `n` to `.rol(..)` .
2020-11-16 18:55:31 +03:00
2020-11-18 06:09:43 +03:00
### `<array>.compact()`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 16:46:59 +03:00
< array > .compact()
2020-12-08 01:53:40 +03:00
-> < compact-array >
2020-10-07 16:46:59 +03:00
```
2020-10-07 03:53:10 +03:00
Generate a compact `<array>` from a sparse `<array>` , i.e. removing all
the empty slots.
2020-11-18 06:09:43 +03:00
### `<array>.len`
2020-10-07 03:53:10 +03:00
Number of non-empty slots/elements in `<array>` .
2020-10-07 16:46:59 +03:00
This is similar to:
```javascript
var L = [,,, 1,, 2, 3,,]
2020-10-07 03:53:10 +03:00
2020-10-07 16:46:59 +03:00
// this is the same as L.len...
L.compact().length
```
2020-10-07 03:53:10 +03:00
2020-10-07 16:46:59 +03:00
Note that this is different from `.length` in that writing to `.len` has
no effect.
2020-10-07 03:53:10 +03:00
2021-03-24 02:10:55 +03:00
2020-12-08 01:53:40 +03:00
### `<array>.unique()` / `<array>.tailUnique()`
2020-10-07 03:53:10 +03:00
Generate an array with all duplicate elements removed.
2020-12-08 01:53:40 +03:00
```bnf
< array > .unique()
-> < array >
2021-03-24 02:10:55 +03:00
< array > .tailUnique()
-> < array >
2020-12-08 01:53:40 +03:00
```
2020-11-16 18:55:31 +03:00
2021-03-24 02:10:55 +03:00
The difference between the two versions is in that `.unique(..)` keeps the
first occurrence of a value while `.tailUnique(..)` keeps the last.
2020-12-08 01:53:40 +03:00
### `<array>.trim()` / `<array>.trimStart()` / `<array>.trimEnd()`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
Copy array removing empty slots from array start, end or both.
```bnf
< array > .trim()
-> < array >
< array > .trimStart()
-> < array >
< array > .trimEnd()
-> < array >
2020-10-07 16:46:59 +03:00
```
2020-12-08 01:53:40 +03:00
2021-03-24 02:10:55 +03:00
This is similar to `String` 's equivalent methods but removing _empty_ slots
instead of spaces.
2020-12-08 01:53:40 +03:00
### `<array>.cmp(..)`
Compare two arrays.
```bnf
2020-10-07 16:46:59 +03:00
< array > .cmp(< other > )
2020-12-08 01:53:40 +03:00
-> < bool >
2020-10-07 16:46:59 +03:00
```
This will return `true` if:
2021-03-24 02:10:55 +03:00
- `<array> === <other>`
or
2020-10-07 16:46:59 +03:00
- lengths are the same and,
- values on the same positions are equal.
2021-03-24 02:10:55 +03:00
<!--
XXX should this test based on equality or on identity by default???
...see: Object.match(..)
-->
2020-10-07 16:46:59 +03:00
2020-11-18 06:09:43 +03:00
### `<array>.setCmp(..)`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
Compare to arrays ignoring element order and count.
```bnf
< array > .setCmp(< other > )
-> < bool >
```
2021-03-24 02:10:55 +03:00
2020-11-18 06:09:43 +03:00
### `<array>.sortAs(..)`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
Sort array as a different array.
```bnf
< array > .sortAs(< other > )
-> < array >
```
Elements not present in `<other>` retain their relative order and are
placed after the sorted elements.
Example:
```javascript
var L = [1, 2, 3, 4, 5, 6]
var O = [5, 3, 1, 0]
L.sortAs(O) // -> [5, 3, 1, 2, 4, 6]
```
2020-11-18 06:09:43 +03:00
### `<array>.inplaceSortAs(..)`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
Sort array as a different array keeping positions of unsorted elements.
```bnf
< array > .inplaceSortAs(< other > )
-> < array >
```
Example:
```javascript
var L = [1, 2, 3, 4, 5, 6]
var O = [5, 3, 1, 0]
L.inplaceSortAs(O) // -> [5, 2, 3, 4, 1, 6]
```
2020-11-18 06:09:43 +03:00
### `<array>.toKeys(..)`
2020-10-10 17:27:00 +03:00
2020-12-08 01:53:40 +03:00
Create an object with array values as keys and index as value.
```bnf
< array > .toKeys()
-> < object >
```
Normalize resulting `<object>` keys:
```bnf
< array > .toKeys(< normalize > )
-> < object >
< normalize > (< elem > , < index > )
-> < key >
```
If `<array>` contains the same value multiple times it will be written
to `<object>` only once with the last occurrences' index.
Since `object` keys can only be `string` s array items that are not
strings will be converted to strings. If this is not desired use `.toMap(..)`
instead.
2020-11-18 06:09:43 +03:00
### `<array>.toMap(..)`
2020-10-10 17:27:00 +03:00
2020-12-08 01:53:40 +03:00
Create a map with array values as keys and index as value.
```bnf
< array > .toMap()
-> < map >
```
Normalize resulting `<map>` keys:
```bnf
< array > .toMap(< normalize > )
-> < map >
< normalize > (< elem > , < index > )
-> < key >
```
Note that if `<array>` contains the same value multiple times it will be used
as key only once and retain the last occurrences' index.
2020-11-18 06:09:43 +03:00
### `Array.zip(..)` / `<array>.zip(..)`
2020-10-15 03:12:42 +03:00
2020-12-08 01:53:40 +03:00
_Zip_ input array items.
```bnf
Array.zip(< array > , < array > , ..)
-> < array >
< array > .zip(< array > , < array > , ..)
-> < array >
```
Example:
```javascript
var A = [1, 2, 3]
var B = ['a', 'b', 'c', 'd']
Array.zip(A, B) // -> [[1, 'a'], [2, 'b'], [3, 'c'], [, 'd']]
```
Array _sparseness_ is retained -- if one of the arrays has an empty slot, or is
not long enough, the corresponding spot in the result will be empty.
Resulting array length is strictly equal to the longest input array length.
2020-11-18 06:59:56 +03:00
### `Array.iter(..)` / `<array>.iter()`
2020-11-10 03:04:04 +03:00
Return an iterator/generator from the current array.
2020-11-10 03:25:00 +03:00
This is mostly useful in combination with the [Generator extensions and utilities ](#generator-extensions-and-utilities )
2020-11-10 03:04:04 +03:00
2020-10-10 17:27:00 +03:00
2020-11-07 03:19:52 +03:00
### Abortable `Array` iteration
2020-11-16 18:55:31 +03:00
A an alternative to `Array` 's `.map(..)` / `.filter(..)` / .. methods with ability to
2020-11-23 22:27:30 +03:00
stop the iteration process by `throw` ing `STOP` or `STOP(<value>)` .
2020-11-07 03:19:52 +03:00
```javascript
2020-11-23 22:27:30 +03:00
var {STOP} = require('ig-types/Array')
2020-11-07 03:19:52 +03:00
```
This can be used in two ways:
1) `throw` as-is to simply stop...
```javascript
;[1,2,3,4,5]
.smap(function(e){
// simply abort here and now...
2020-11-23 22:27:30 +03:00
throw STOP })
2020-11-07 03:19:52 +03:00
```
2020-11-23 22:27:30 +03:00
Since we aborted the iteration without passing any arguments to `STOP` ,
2020-11-07 03:19:52 +03:00
`.smap(..)` will return `undefined` .
2) `throw` an instance and return the argument...
```javascript
2020-11-23 22:27:30 +03:00
// this will print "4" -- the value passed to STOP...
2020-11-07 03:19:52 +03:00
console.log([1,2,3,4,5]
.smap(function(e){
if(e > 3){
// NOTE: new is optional here...
// ...StopIteratiom is an object.js constructor.
2020-11-23 22:27:30 +03:00
throw new STOP(e) } }))
2020-11-07 03:19:52 +03:00
```
2020-11-23 22:27:30 +03:00
Note that no partial result is returned unless passed through `STOP(..)` .
2020-11-16 18:55:31 +03:00
2020-11-23 22:27:30 +03:00
#### `array.STOP` / `array.STOP(..)`
2020-11-16 18:55:31 +03:00
2020-11-23 22:27:30 +03:00
An _object/constructor_ that if raised (as an exception) while iterating via
a supporting iterator method will abort further execution and correctly exit.
2020-11-07 03:19:52 +03:00
#### `<array>.smap(..)` / `<array>.sfilter(..)` / `<array>.sreduce(..)` / `<array>.sforEach(..)`
Like `Array` 's `.map(..)` , `.filter(..)` , `.reduce(..)` and `.forEach(..)` but
2020-11-23 22:27:30 +03:00
with added support for aborting iteration by throwing `STOP` or `STOP(<value>)` .
2020-11-07 03:19:52 +03:00
2020-10-10 17:27:00 +03:00
### Large `Array` iteration (chunked)
Iterating over very large `Array` instances in JavaScript can block execution,
to avoid this `types.js` implements `.map(..)` /`.filter(..)` /`.reduce(..)`
2020-10-11 03:09:48 +03:00
equivalent methods that iterate the array in chunks and do it asynchronously
giving the runtime a chance to run in between.
In the simplest cases these are almost a drop-in replacements for the equivalent
methods but return a promise.
```javascript
var a = [1,2,3,4,5]
.map(function(e){
return e*2 })
var b
;[1,2,3,4,5]
.mapChunks(function(e){
return e*2 })
.then(function(res){
b = res })
// or with await...
var c = await [1,2,3,4,5]
.mapChunks(function(e){
return e*2 })
```
These support setting the chunk size (default: `50` ) as the first argument:
```javascript
2020-11-07 03:19:52 +03:00
var c = await [1,2,3,4,5]
.mapChunks(2, function(e){
return e*2 })
2020-10-11 03:09:48 +03:00
```
2020-11-23 22:27:30 +03:00
#### `array.STOP` / `array.STOP(..)`
2020-11-06 16:57:51 +03:00
2020-11-07 03:19:52 +03:00
Like for [`<array>.smap(..)` and friends ](#abortable-array-iteration ) iteration
2020-11-23 22:27:30 +03:00
can be stopped by throwing a `array.STOP` / `array.STOP(<value>)` and as before
there are two ways to go:
2020-11-06 16:57:51 +03:00
1) `throw` as-is to simply stop
```javascript
;[1,2,3,4,5]
.mapChunks(function(e){
// simply abort here and now...
2020-11-23 22:27:30 +03:00
throw STOP })
2020-11-06 16:57:51 +03:00
.catch(function(){
console.log('done.') })
```
2) `Throw` an instance and pass a value to `.catch(..)`
```javascript
;[1,2,3,4,5]
.mapChunks(function(e){
if(e > 3){
// NOTE: new is optional here...
// ...StopIteratiom is an object.js constructor.
2020-11-23 22:27:30 +03:00
throw new STOP(e) } })
2020-11-06 16:57:51 +03:00
.catch(function(e){
2020-11-07 03:19:52 +03:00
console.log('first value greater than 3:', e) })
2020-11-06 16:57:51 +03:00
```
2020-10-11 03:09:48 +03:00
#### `<array>.CHUNK_SIZE`
2020-11-06 16:57:51 +03:00
The default iteration chunk size.
Note that the smaller this is the more _responsive_ the code is, especially
in UI applications but there is a small overhead added per chunk.
Default value: `50`
2020-10-10 17:27:00 +03:00
2020-12-08 01:53:40 +03:00
#### `<array>.mapChunks(..)` / `<array>.filterChunks(..)` / `<array>.reduceChunks(..)`
2020-10-07 03:53:10 +03:00
2020-12-08 01:53:40 +03:00
The `.map(..)` , `.filter(..)` and `.reduce(..)` alternatives respectively:
```bnf
2020-10-11 03:09:48 +03:00
< array > .mapChunks(< func > )
< array > .mapChunks(< chunk-size > , < func > )
-> < promise >
< func > (< item > , < index > , < array > )
-> < new-item >
```
2020-12-08 01:53:40 +03:00
```bnf
< array > .filterChunks(< func > )
< array > .filterChunks(< chunk-size > , < func > )
-> < promise >
< func > (< item > , < index > , < array > )
-> < bool >
2020-10-11 03:09:48 +03:00
```
2020-12-08 01:53:40 +03:00
```bnf
< array > .reduceChunks(< func > , < state > )
< array > .mreduceChunks(< chunk-size > , < func > , < state > )
-> < promise >
< func > (< state > , < item > , < index > , < array > )
-> < state >
```
2021-04-02 11:25:42 +03:00
<!-- XXX Example -->
2020-12-08 01:53:40 +03:00
All three support chunk handlers in the same way (illustrated on `.mapChunks(..)` ):
```bnf
2020-10-11 03:09:48 +03:00
< array > .mapChunks([< func > , < chunk-handler > ])
< array > .mapChunks(< chunk-size > , [< func > , < chunk-handler > ])
-> < promise >
< func > (< item > , < index > , < array > )
-> < new-item >
< chunk-handler > (< chunk > , < result > , < offset > )
```
2020-12-08 01:53:40 +03:00
The `<chunk-handler>` gets the completed chunk of data after it is computed
but before the timeout.
2020-10-11 03:09:48 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX Example -->
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
## `Map`
```javascript
require('ig-types/Map')
```
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `<map>.sort(..)`
2021-04-03 02:11:02 +03:00
Sort `<map>` keys in-place
```bnf
< map > .sort()
-> < map >
2021-04-02 11:25:42 +03:00
2021-04-03 02:11:02 +03:00
< map > .sort(< cmp > )
-> < map >
```
2021-04-02 11:25:42 +03:00
2021-04-03 02:11:02 +03:00
In the general case this is similar to
[`<array>.sort(..)` ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort )
with the addition of the [`<array>.sortAs(..)` ](#arraysortas )'s ability to sort
as a list
```bnf
< map > .sort(< sorted-keys > )
-> < map >
```
This is similar to [`<set>.sort(..)` ](#setsort ) and [`Object.sort(..)` ](#objectsort ),
see the later for more info.
2020-11-18 06:09:43 +03:00
2020-12-08 01:53:40 +03:00
2020-11-18 06:09:43 +03:00
## `Set`
```javascript
require('ig-types/Set')
```
### `<set>.unite(..)`
2021-04-05 14:07:01 +03:00
Unite two sets and return the resulting set
```bnf
< set > .unite(< other > )
-> < union-set >
```
This is a shorthand for `new Set([...<set>, ...<other>])`
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `<set>.intersect(..)`
2020-10-07 16:46:59 +03:00
2021-04-05 14:07:01 +03:00
Intersect two sets and return the intersection set
```bnf
< set > .untersect(< other > )
-> < intersection-set >
```
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `<set>.subtract(..)`
2020-10-07 16:46:59 +03:00
2021-04-05 14:07:01 +03:00
Subtract `<other>` from set and return resulting set
```bnf
< set > .subtract(< other > )
-> < sub-set >
```
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `<set>.sort(..)`
2020-10-07 16:46:59 +03:00
2021-04-03 02:11:02 +03:00
Sort `<set>` keys in-place
```bnf
< set > .sort()
-> < set >
< set > .sort(< cmp > )
-> < set >
```
In the general case this is similar to
[`<array>.sort(..)` ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort )
with the addition of the [`<array>.sortAs(..)` ](#arraysortas )'s ability to sort
as a list
```bnf
< set > .sort(< sorted-values > )
-> < set >
```
2021-04-02 11:25:42 +03:00
2021-04-03 02:11:02 +03:00
This is similar to [`<map>.sort(..)` ](#mapsort ) and [`Object.sort(..)` ](#objectsort ),
see the later for more info.
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
## `Date`
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
```javascript
require('ig-types/Date')
```
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `Date.timeStamp(..)`
2020-10-07 03:53:10 +03:00
2021-04-03 02:11:02 +03:00
Generate a timestamp (format: `'YYYYMMDDHHMMSS'` )
```bnf
Date.timeStamp()
-> < timestamp >
```
Generate a full timestamp, including milliseconds (format: `'YYYYMMDDHHMMSSmmm'` )
```bnf
Date.timeStamp(true)
-> < timestamp >
```
This is a shorthand to: [`(new Date()).getTimeStamp(..)` ](#dategettimestamp )
The timestamp is generated from the time of call, for generating timestamps form specific `<date>` objects see:
[`<date>.getTimeStamp(..)` ](#dategettimestamp )
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `Date.fromTimeStamp(..)`
2020-10-07 03:53:10 +03:00
2021-04-03 02:11:02 +03:00
Create a `<date>` from a timestamp
```bnf
Date.fromTimeStamp(< timestamp > )
-> < date >
```
This is a shorthand to: [`(new Date()).setTimeStamp(<timestamp>)` ](#datesettimestamp )
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `Date.str2ms(..)`
2020-10-07 16:46:59 +03:00
2021-04-02 11:25:42 +03:00
Convert a string describing a time period into milliseconds.
```bnf
Date.str2ms(< str > )
-> < number >
```
Examples:
```javascript
// time units (d/h/m/s/ms) and their variants...
var a = Date.str2ms('3 seconds') // -> 3000
var b = Date.str2ms('0.1h') // -> 360000
// time period (DD:HH:MM:SS:mmm)...
var c = Date.str2ms('00:20:001') // -> 20001
var d = Date.str2ms('1:3') // -> 63000
```
Note that time periods are seconds-based by default unless it contains three
digits then it defaults to milliseconds:
```javascript
// least significant unit is seconds by default...
var e = Date.str2ms(':3') // -> 3000
// when the least significant unit contains 3 digits it is read as ms...
var f = Date.str2ms(':030') // -> 30
```
Supported formats:
```bnf
< str > ::=
< milliseconds >
| < seconds >
| < minutes >
| < hours >
| < days >
| < period >
< milliseconds > ::=
< number >
| < number > ms
| < number > m[illi][-]s[ec[ond[s]]]
< seconds > ::=
< number > s
| < number > s[ec[ond[s]]]
< seconds > ::=
< number > m
| < number > m[in[ute[s]]]
< seconds > ::=
< number > h
| < number > h[our[s]]
< seconds > ::=
< number > d
| < number > d[ay[s]]
< period > ::=
[[[DD:]HH:]MM]:SS[:mmm]
| [[[[DD:]HH:]MM]:SS]:mmm
```
2020-11-18 06:09:43 +03:00
### `<date>.toShortDate(..)`
2020-10-07 03:53:10 +03:00
2021-04-03 02:11:02 +03:00
Generate a short date string from `<date>`
(format: `'YYYY-MM-DD HH:MM:SS'` )
```bnf
< date > .toShortDate()
-> < short-date >
```
Generate a short date string including milliseconds from `<date>`
(format: `'YYYY-MM-DD HH:MM:SS:mmm'` )
```bnf
< date > .toShortDate(true)
-> < short-date >
```
Note that `<short-date>` is directly parseable by `new Date(..)`
```javascript
var a = (new Date()).toShortDate(true)
// parse the < short-date > and generate a new short date from it...
var b = (new Date(a)).toShortDate(true)
a == b // -> true
```
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `<date>.getTimeStamp(..)`
2020-10-07 03:53:10 +03:00
2021-04-03 02:11:02 +03:00
Generate a timestamp from `<date>`
(format `'YYYYMMDDHHMMSS'` )
```bnf
< date > .getTimeStamp()
-> < timestamp >
```
2021-04-02 11:25:42 +03:00
2021-04-03 02:11:02 +03:00
Generate a timestamp from `<date>` including milliseconds
(format `'YYYYMMDDHHMMSSmmm'` )
```bnf
< date > .getTimeStamp(true)
-> < timestamp >
```
2021-04-02 11:25:42 +03:00
2020-10-07 03:53:10 +03:00
2021-04-03 02:11:02 +03:00
### `<date>.setTimeStamp(..)`
2021-04-02 11:25:42 +03:00
2021-04-03 02:11:02 +03:00
Update a `<date>` from a timestamp
```bnf
< date > .setTimeStamp(< timestamp > )
-> < date >
```
2021-04-02 11:25:42 +03:00
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
## `String`
```javascript
require('ig-types/String')
```
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
### `<string>.capitalize()`
2020-10-07 03:53:10 +03:00
2021-04-05 14:07:01 +03:00
Capitalize the first character of a string
```bnf
< string > .capitalize()
-> < string >
```
2021-04-02 11:25:42 +03:00
2020-12-17 18:55:28 +03:00
### `<string>.indent(..)`
2021-04-05 14:07:01 +03:00
Indent each line in `<string>` by `<size>` spaces
```bnf
< string > .indent(< size > )
-> < string >
```
2021-04-02 11:25:42 +03:00
2021-04-05 14:07:01 +03:00
Indent/prepend each line in `<string>` by the `<prefix>` string
```bnf
< string > .indent(< prefix > )
-> < string >
```
2021-04-02 11:25:42 +03:00
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
## `RegExp`
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
```javascript
require('ig-types/RegExp')
```
2020-10-07 03:53:10 +03:00
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
### `RegExp.quoteRegExp(..)`
2020-10-07 03:53:10 +03:00
2021-04-05 14:07:01 +03:00
Quote regexp reserved characters in a string
```bnf
RegExp.quoteRegExp(< str > )
-> < str >
```
This is mainly used to quote strings to be matched as-is within a regular expression.
2021-04-02 11:25:42 +03:00
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
## `Promise`
2020-10-07 03:53:10 +03:00
2020-11-18 06:09:43 +03:00
```javascript
require('ig-types/Promise')
```
or
```javascript
var promise = require('ig-types/Promise')
```
2020-10-07 03:53:10 +03:00
2020-11-10 03:04:04 +03:00
2021-04-06 14:27:48 +03:00
### Interactive promises
_Interactive promises_ can be sent messages and then handle them.
```javascript
var printer = Promise.interactive(function(resolve, reject, onmessage){
var buf = []
var state = 'pending'
onmessage(function(type, ...args){
type == 'flush' ?
(buf = buf
.filter(function([type, state, ...args]){
console[type ](`(${ state } ):`, ...args) }))
: type == 'close' ?
(resolve(...args),
state = 'resolved')
: buf.push([type, state, ...args]) }) })
printer
.send('log', 'some message...')
.send('warn', 'some warning...')
.send('flush')
.send('close')
```
Note that message handling is independent of promise state, so in the above case
2021-04-07 03:17:02 +03:00
we can still populate the buffer and _flush_ it even if the promise is resolved
2021-04-06 14:27:48 +03:00
```javascript
printer
.send('log', 'some other message...')
.send('flush')
```
If the user wants to reject messages after the promise is finalized it is their
responsibility.
2021-04-07 03:17:02 +03:00
<!--
2021-04-10 14:25:06 +03:00
XXX add example of clearing handlers...
2021-04-07 03:17:02 +03:00
-->
2021-04-06 14:27:48 +03:00
#### `Promise.interactive(..)`
Create and interactive promise
```bnf
Promise.interactive(< handler > )
-> < promise-inter >
```
The `<handler>` accepts one additional argument, compared to the `Promise(..)`
handler, `<onmessage>` , used to register message handlers.
```bnf
< handler > (< resolve > , < reject > , < onmessage > )
< onmessage > (< message-handler > )
```
2021-04-07 03:32:23 +03:00
Remove `<message-handler>`
```bnf
< onmessage > (< message-handler > , false)
```
Remove all handlers
```bnf
< onmessage > (false)
```
2021-04-06 14:27:48 +03:00
`<message-handler>` is called when a message is sent via
[`<promise-inter>.send()` ](#promise-intersend ).
#### `<promise-inter>.send(..)`
Send a message to an interactive promise
```bnf
< promise-inter > .send()
< promise-inter > .send(...)
-> < promise-inter >
```
Sending a message triggers message handlers registered via `<onmessage>(..)`
2021-04-07 03:17:02 +03:00
passing each handler the arguments.
2021-04-06 14:27:48 +03:00
2021-04-07 14:47:25 +03:00
#### `<promise-inter>.then(..)`
<!-- XXX -->
See [`<promise-iter>.then(..)` ](#promise-iterthen--promise-itercatch--promise-iterfinally ) for details.
2021-04-06 14:27:48 +03:00
2020-11-18 06:09:43 +03:00
### Cooperative promises
2020-11-03 05:22:29 +03:00
2021-04-07 14:47:25 +03:00
A _cooperative promise_ is one that can be finalized externally/cooperatively.
This can be useful when breaking recursive dependencies between promises or when
it is simpler to thread the result receiver promise down the stack than building
a promise stack and manually threading the result up.
<!-- XXX Example: show a clear use - case - - ping - pong?... -->
```javascript
```
Note that functionally this can be considered a special-case of an
[interactive promise ](#interactive-promises ), but in reality they are two
different implementations, the main differences are:
- _Cooperative promise_ constructor does not need a resolver function,
- _Cooperative promises_ do not the implement `.send(..)` API.
2021-04-06 14:27:48 +03:00
2021-04-07 14:47:25 +03:00
Note that implementing _Cooperative promises_ on top of _Interactive promises_
cleanly, though feeling more _"beautiful"_ , would be more complex than the
current standalone implementation, as it would require both implementing
the `.set(..)` API/logic _and_ active encapsulation of the message API.
2021-04-02 11:25:42 +03:00
2021-04-07 14:47:25 +03:00
#### `Promise.cooperative()`
2021-04-09 02:26:34 +03:00
Create a cooperative promise
2021-04-07 14:47:25 +03:00
```bnf
Promise.cooperative()
-> < promise-coop >
```
2020-11-03 05:22:29 +03:00
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
#### `<promise-coop>.set(..)`
2021-04-09 02:26:34 +03:00
Resolve `<promise-coop>` with `<value>`
2021-04-08 22:04:29 +03:00
```bnf
< promise-coop > .set(< value > )
2021-04-09 02:26:34 +03:00
< promise-coop > .set(< value > , true)
2021-04-08 22:04:29 +03:00
-> < promise-coop >
```
2021-04-09 02:26:34 +03:00
If `<value>` is a promise, then `<promise-coop>` will be bound to its state, i.e.
resolved if `<value>` is resolved and rejected if it is rejected with the same
values.
Reject `<promise-coop>` with `<value>`
```bnf
< promise-coop > .set(< value > , false)
-> < promise-coop >
```
Calling `.set(..)` will set `.isSet` to `true` .
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
#### `<promise-coop>.isSet`
2021-04-09 02:26:34 +03:00
Property representing if the cooperative promise was _set_ / `.set(..)` was
called (value is `true` ) or no (`false` ).
This property is read-only.
2021-04-02 11:25:42 +03:00
2021-04-07 14:47:25 +03:00
#### `<promise-coop>.then(..)`
<!-- XXX -->
See [`<promise-iter>.then(..)` ](#promise-iterthen--promise-itercatch--promise-iterfinally ) for details.
2020-11-18 06:09:43 +03:00
### 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.
2020-11-18 06:59:56 +03:00
Essentially one can think about _promise iterators_ vs. _generators_ as the former
being internally controlled and asynchronous while the later being externally
controlled and synchronous.
2020-11-18 06:09:43 +03:00
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(< array > )
-> < iterable-promise >
```
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-18 06:09:43 +03:00
#### `<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-18 06:09:43 +03:00
#### `<promise-iter>.flat(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-18 06:09:43 +03:00
#### `<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-04-07 14:47:25 +03:00
Note that `.then(..)` here can be called without arguments returning a generic
promise wrapper. This can be useful to hide the extended promise API from further
code.
2021-04-02 11:25:42 +03:00
2020-11-18 06:09:43 +03:00
#### Advanced handler
2020-12-08 01:53:40 +03:00
```bnf
2020-11-18 06:09:43 +03:00
Promise.iter(< block-array > , < handler > )
-> < iterable-promise >
< handler > (< elem > )
-> [ < elems > ]
```
```bnf
< block-array > ::=
[]
| [ < block-elem > , .. ]
< block-elem > ::=
[]
| [ < value > , .. ]
| < promise >
| < non-array >
```
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]]
})
```
2020-11-03 05:22:29 +03:00
2020-10-07 03:53:10 +03:00
2020-11-10 03:25:00 +03:00
## Generator extensions and utilities
```javascript
var generator = require('ig-types/generator')
```
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-10 03:25:00 +03:00
### The basics
2021-03-24 18:57:02 +03:00
The _generator_ hierarchy in JavaScript is a bit complicated.
Consider the following:
```javascript
// generator constructor function...
var Iter = function*(L){
for(var e of L){
yield e }}
// generator instance...
var iter = Iter([1, 2, 3])
```
We can test that `iter` is an instance of `Iter` :
```javascript
iter instanceof Iter // -> true
```
2021-04-01 02:30:36 +03:00
Due to the three level structure of generators we use a slightly different
terminology to reference different levels of API's:
- `Generator` - the generator meta-constructor.
This is a constructor that is used to create/inherit `<Generator>` 's, i.e.
generator constructors.
`Generator` is mainly used for `instanceof` checks, but can be used as a
prototype for extending generators.
- `<Generator>` - the generator constructor.
This is the product of either a `Generator` meta-constructor or a
`function*(..){ .. }` statement.
In the above example `Iter` is a generator constructor.
- `<generator>` - the generator instance.
Generator instances are created by calling a `<Generator>` / generator
constructor.
In the above example `iter` is a generator instance.
2021-03-24 18:57:02 +03:00
#### `generator.Generator`
2021-04-01 02:30:36 +03:00
Exposes the _hidden_ JavaScript generator meta-constructor.
2021-03-24 18:57:02 +03:00
```javascript
Iter instanceof generator.Generator // -> true
```
Note that currently in JavaScript there is no built-in way to test if a
constructor, `Iter` in this case, is a _generator_ constructor.
2020-11-10 03:25:00 +03:00
#### `generator.iter(..)`
2020-11-10 03:04:04 +03:00
2021-03-24 18:57:02 +03:00
Generic generator wrapper
```bnf
generator.iter()
-> < generator >
generator.iter(< iterable > )
-> < generator >
```
Example:
```javascript
for(var i of generator.iter([1, 2, 3])){
console.log(i) }
```
The following are equivalent:
```javascript
2021-03-31 16:01:52 +03:00
var a = generator.iter()
2021-03-24 18:57:02 +03:00
2021-03-31 16:01:52 +03:00
var b = new generator.Generator()
2021-03-24 18:57:02 +03:00
```
2021-03-31 16:01:52 +03:00
But `Generator()` takes no arguments and thus can not be used as a wrapper while `.iter(..)` is designed to accept an iterable value like an array object.
2021-03-24 18:57:02 +03:00
2020-11-10 03:04:04 +03:00
### Generator instance iteration
2021-03-25 02:59:15 +03:00
This is a set of `Array` -like iterator methods that enable chaining of
2021-03-25 14:40:51 +03:00
generators and `Promise` -like API to handle the generated results.
2021-03-25 02:59:15 +03:00
Chained generators handle items depth-first, i.e. the items are passed as they are yielded down the generator chain.
#### `<generator>.map(..)` / `<generator>.filter(..)` / `<generator>.reduce(..)`
Equivalents to `Array` 's `.map(..)` , `.filter(..)` and `.reduce(..)` but return
generators that yield the handler return values.
2021-03-25 14:40:51 +03:00
<!--
XXX .reduce(..) can return a non-iterable -- test and document this case...
-->
2021-03-25 02:59:15 +03:00
#### `<generator>.slice(..)`
2021-03-25 14:40:51 +03:00
```bnf
< generator > .slice()
< generator > .slice(< from > )
< generator > .slice(< from > , < to > )
-> < generator >
```
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-03-28 15:21:41 +03:00
<!-- XXX check this
This does not support negative indexes.
-->
2021-03-26 02:12:55 +03:00
Equivalent to `Array` 's `.slice(..)` but will return a generator instead of an
array, for more info see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
2021-03-25 14:40:51 +03:00
2021-03-25 02:59:15 +03:00
#### `<generator>.at(..)`
2021-03-25 14:40:51 +03:00
```bnf
< generator > .at(< index > )
-> < generator >
```
Returns a generator that will yield an item at a specific position when it is
available.
2021-03-25 02:59:15 +03:00
#### `<generator>.flat(..)`
2021-03-25 14:40:51 +03:00
```bnf
< generator > .flat()
< generator > .flat(< depth > )
-> < generator >
```
2021-03-26 02:12:55 +03:00
Equivalent to `Array` 's `.flat(..)` but will return a generator instead of an
array, for more info see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
2021-03-25 14:40:51 +03:00
2021-03-25 02:59:15 +03:00
#### `<generator>.shift()` / `<generator>.pop()`
2021-03-26 02:12:55 +03:00
Return the first/last item in generator.
```bnf
< generator > .pop()
-> < value >
-> undefined
< generator > .shift()
-> < value >
-> undefined
```
Note that there are no equivalents to `.push(..)` and `.unshift(..)` as they
would require breaking item processing order.
2021-03-25 02:59:15 +03:00
2021-03-26 02:12:55 +03:00
Note that `.shift()` may not yield the actual first item if the generator is
partially depleted at time of call.
2021-03-25 02:59:15 +03:00
2020-11-10 03:04:04 +03:00
#### `<generator>.promise()`
2021-03-25 14:40:51 +03:00
```bnf
< generator > .promise()
-> < promise >
```
Return a promise and resolve it with the generator value.
Note that this will deplete the generator.
2020-11-10 03:04:04 +03:00
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
2021-03-25 14:40:51 +03:00
```bnf
< generator > .then(< resolve > , < reject > )
-> < promise >
< generator > .then(< reject > )
-> < promise >
< generator > .finally(< handler > )
-> < promise >
```
Shorthands to `<generator>.promise().then(..)` / `<generator>.promise().catch(..)` / `<generator>.promise().finally(..)`
2021-03-26 02:12:55 +03:00
These are the same as equivalent `Promise` methods, for more info see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
2021-03-25 14:40:51 +03:00
2020-11-10 03:04:04 +03:00
#### `<generator>.toArray()`
2021-03-26 02:12:55 +03:00
Unwind a generator into an array
2021-03-25 14:40:51 +03:00
```bnf
< generator > .toArray()
-> < array >
```
2021-03-26 02:12:55 +03:00
This is equivalent to `[...<generator>]` but more suited for the concatenative style.
2021-03-25 14:40:51 +03:00
2020-11-10 03:04:04 +03:00
2020-11-18 06:59:56 +03:00
### Generator constructor iteration
2020-11-10 03:04:04 +03:00
2021-03-26 02:12:55 +03:00
This API is essentially the same as [generator iteration ](#generator-instance-iteration )
2021-03-28 15:21:41 +03:00
with some minor omissions, but will return a reusable generator _pipeline_
instead of a generator.
2021-03-26 02:12:55 +03:00
2020-11-10 03:04:04 +03:00
```javascript
2020-11-10 03:25:00 +03:00
var sumOdds = generator.iter
2020-11-10 03:04:04 +03:00
.filter(function(e){
return e % 2 == 1 })
.reduce(function(r, e){
return r + e }, 0)
.pop()
2021-03-28 15:21:41 +03:00
// sumOdds(..) is essentially a function that can be reused...
2020-11-10 03:25:00 +03:00
console.log(sumOdds([1, 2, 3])) // -> 4
2020-11-10 03:04:04 +03:00
console.log(sumOdds([1, 2, 3, 4, 5, 6, 7])) // -> 16
2020-11-10 03:25:00 +03:00
```
2020-11-10 03:04:04 +03:00
2020-11-10 03:25:00 +03:00
The above code is the same in function to:
```javascript
var sumOdds = function(lst){
return generator.iter(lst)
.filter(function(e){
return e % 2 == 1 })
.reduce(function(r, e){
return r + e }, 0)
.pop() }
console.log(sumOdds([1, 2, 3])) // -> 4
console.log(sumOdds([1, 2, 3, 4, 5, 6, 7])) // -> 16
2020-11-10 03:04:04 +03:00
```
2021-03-28 15:21:41 +03:00
<!--
XXX only list the differences + reference to the above...
-->
2021-03-24 18:57:02 +03:00
#### `<Generator>.at(..)`
2020-11-10 03:25:00 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-03-24 18:57:02 +03:00
#### `<Generator>.shift()` / `<Generator>.pop()`
2020-11-10 03:04:04 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-03-24 18:57:02 +03:00
#### `<Generator>.slice(..)`
2020-11-10 03:04:04 +03:00
This is like `Array` 's `.slice(..)` but does not support negative indexes.
2021-03-24 18:57:02 +03:00
#### `<Generator>.map(..)` / `<Generator>.filter(..)` / `<Generator>.reduce(..)` / `<Generator>.flat()`
2020-11-10 03:04:04 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-03-24 18:57:02 +03:00
#### `<Generator>.toArray()`
2020-11-10 03:04:04 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2021-03-24 18:57:02 +03:00
#### `<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)`
2020-11-10 03:04:04 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-10 03:04:04 +03:00
2020-10-07 03:53:10 +03:00
## Containers
2020-10-07 07:33:58 +03:00
```javascript
var containers = require('ig-types').containers
```
or, to only import containers:
```javascript
var containers = require('ig-types/containers')
```
2020-10-07 03:53:10 +03:00
2020-10-10 06:31:29 +03:00
Note that this will also import `ig-types/Map` .
2020-10-07 16:46:59 +03:00
2020-10-07 07:33:58 +03:00
### `containers.UniqueKeyMap()` (`Map`)
`UniqueKeyMap` implements a key-value container (i.e. `Map` ) that supports
and maintains _duplicate_ keys by appending an index to them.
The original keys are stored internally thus the renaming mechanics are
stable.
`UniqueKeyMap` extends the `Map` constructor, so all the usual `Map`
methods and properties apply here.
To construct an instance:
```javascript
var x = new UniqueKeyMap()
```
or:
```javascript
// new is optional...
var y = UniqueKeyMap()
```
`UniqueKeyMap` supports the same initialization signature as `Map` but
treats repeating keys differently.
```javascript
var z = UniqueKeyMap([['a', 1], ['a', 2], ['b', 1]])
```
The second `"a"` item will automatically get re-keyed as `"a (1)"` :
```javascript
console.log([...z.keys()]) // -> ['a', 'a (1)', 'b']
```
Note that `.set(..)` will never rewrite an element:
```javascript
z.set('a', 3)
console.log([...z.keys()]) // -> ['a', 'a (1)', 'b', 'a (2)']
z.get('a') // -> 1
z.get('a (1)') // -> 2
```
To get the generated key:
```javascript
var k = z.set('a', 4, true)
console.log(k) // -> 'a (3)'
```
To explicitly rewrite an item:
```javascript
z.reset('a (1)', 4)
z.get('a (1)') // -> 4
```
And we can _rename_ items, i.e. change their key:
```javascript
z.rename('a (2)', 'c')
console.log([...z.keys()]) // -> ['a', 'a (1)', 'b', 'a (3)', 'c']
```
2020-10-07 03:53:10 +03:00
For more info on `Map` see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
2020-10-07 07:33:58 +03:00
2020-10-07 14:48:47 +03:00
#### `<unique-key-map>.set(..)`
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 14:48:47 +03:00
< unique-key-map > .reset(< key > , < item > )
-> < unique-key-map >
< unique-key-map > .reset(< key > , < item > , true)
-> < new-key >
```
Add an `<item>` to `<unique-key-map>` .
If `<key>` already exists then add an index to it to make it unique.
Key updating is done via [`<unique-key-map>.__key_pattern__` ](#unique-key-map__key_pattern__ ).
2020-10-07 03:53:10 +03:00
#### `<unique-key-map>.reset(..)`
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 14:48:47 +03:00
< unique-key-map > .reset(< key > , < item > )
-> < unique-key-map >
```
Explicitly write an `<item>` under `<key>` as-is, this is like `Map` 's `.set(..)` .
2020-10-07 03:53:10 +03:00
#### `<unique-key-map>.rename(..)`
2020-12-08 01:53:40 +03:00
```bnf
2020-10-07 15:09:36 +03:00
< unique-key-map > .rename(< from-key > , < to-key > )
-> < unique-key-map >
< unique-key-map > .rename(< from-key > , < to-key > , true)
-> < new-key >
```
Rename item key from `<from-key>` to `<to-key>` .
Same mechanics apply as for [`.set(..)` ](#unique-key-mapset ) for key uniqueness.
Note, if [`.__unordered_rename__` ](#unique-key-map__unordered_rename__ ) is
`false` (default) this calls [`.orderedRename(..)` ](#unique-key-maporderedrename )
otherwise [`.unorderedRename(..)` ](#unique-key-mapunorderedrename ) is called.
#### `<unique-key-map>.orderedRename(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 14:48:47 +03:00
#### `<unique-key-map>.unorderedRename(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 03:53:10 +03:00
#### `<unique-key-map>.keysOf(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 14:48:47 +03:00
#### `<unique-key-map>.originalKey(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 14:48:47 +03:00
#### `<unique-key-map>.uniqueKey(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 07:33:58 +03:00
#### `<unique-key-map>.__key_pattern__`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 15:09:36 +03:00
#### `<unique-key-map>.__unordered_rename__`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-10-07 07:33:58 +03:00
2020-11-15 05:13:35 +03:00
## Event
2020-11-18 06:09:43 +03:00
```javascript
var event = require('ig-types/event')
```
2020-11-15 05:13:35 +03:00
### `event.Eventfull(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
### `event.Event(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-16 02:38:19 +03:00
### `event.TRIGGER`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-16 02:38:19 +03:00
Special value when passed to an event method as first argument will force it
to trigger event if the first argument was a function.
2020-11-15 05:13:35 +03:00
### `event.EventHandlerMixin`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.on(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.one(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.off(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.trigger(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
### `event.EventDocMixin`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.eventfull`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
#### `<obj>.events`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-15 05:13:35 +03:00
### `event.EventMixin`
2020-11-28 03:47:31 +03:00
Combines [`event.EventHandlerMixin` ](#eventeventhandlermixin ) and
[`event.EventDocMixin` ](#eventeventdocmixin ).
2020-11-07 03:19:52 +03:00
## Runner
2020-11-18 06:09:43 +03:00
```javascript
var runner = require('ig-types/runner')
```
2020-11-28 03:47:31 +03:00
### Micro task queue
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
This includes [`event.EventMixin` ](#eventeventmixin ).
2020-11-18 06:09:43 +03:00
2020-12-17 18:55:28 +03:00
#### `STOP`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `SKIP`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
2020-12-08 01:53:40 +03:00
#### `Queue(..)` / `Queue.runTasks(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
#### `Queue.handle(..)`
Create a handler queue object.
```bnf
Queue.handle(< func > , ...< data > )
Queue.handle(< options > , < func > , ...< data > )
-> < queue >
```
A handler queue is a queue that has a single handler function (`.handle(..)` )
that handles the queue data.
This is a shorthand for:
```javascript
var handler_queue = Queue({
handler: function(item){ .. },
..
},
.. )
```
2020-11-07 03:19:52 +03:00
2020-12-17 18:55:28 +03:00
<!-- XXX settings... -->
2020-11-07 03:19:52 +03:00
#### `<queue>.state`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
2020-11-07 03:19:52 +03:00
#### `<queue>.start(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
#### `<queue>.stop(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-07 03:19:52 +03:00
2020-12-08 01:53:40 +03:00
#### `<queue>.runTask(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
#### `<queue>.tasksAdded(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
#### `<queue>.taskStarting(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
#### `<queue>.taskFailed(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<queue>.taskCompleted(..)` (event)
2020-11-07 03:19:52 +03:00
2020-11-28 03:47:31 +03:00
Event, triggered when a task is completed passing in its result.
2020-11-07 03:19:52 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-07 03:19:52 +03:00
2020-12-08 01:53:40 +03:00
#### `<queue>.queueEmpty(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-08 01:53:40 +03:00
2020-12-17 18:55:28 +03:00
#### `<queue>.prioritize(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<queue>.delay(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<queue>.add(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<queue>.clear(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `FinalizableQueue(..)` / `FinalizableQueue.runTasks(..)` (Queue)
This is the similar as `Queue(..)` but adds two terminal states (`"done"`
and `"aborted"` ) and a `promise` -mapping.
```bnf
FinalizableQueue.handle(< func > , ...< data > )
FinalizableQueue.handle(< options > , < func > , ...< data > )
-> < finalizable-queue >
```
When a `<finalizable-queue>` reaches a terminal state it is frozen.
#### `<finalizable-queue>.done(..)` (event/method)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<finalizable-queue>.abort(..)` (event/method)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<finalizable-queue>.promise(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<finalizable-queue>.then(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
#### `<finalizable-queue>.catch(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-12-17 18:55:28 +03:00
2020-12-08 01:53:40 +03:00
2020-11-28 03:47:31 +03:00
### Large task management
2020-11-07 03:19:52 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `runner.TaskManager(..)`
2020-11-07 03:19:52 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-07 03:19:52 +03:00
2020-11-28 03:47:31 +03:00
This includes [`event.EventMixin` ](#eventeventmixin ).
#### `<task-manager>.Task(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.sync_start`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.record_times`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.titled(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.send(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.stop(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.done(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.error(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `<task-manager>.tasksDone(..)` (event)
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `runner.TaskTicket(..)`
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-28 03:47:31 +03:00
#### `runner.TaskMixin(..)`
2020-11-07 03:19:52 +03:00
2021-04-02 11:25:42 +03:00
<!-- XXX -->
2020-11-07 03:19:52 +03:00
2020-10-07 07:33:58 +03:00
## License
[BSD 3-Clause License ](./LICENSE )
2020-10-07 03:53:10 +03:00
2020-10-07 07:33:58 +03:00
Copyright (c) 2020, Alex A. Naanou,
All rights reserved.
2020-10-07 03:53:10 +03:00
2020-12-17 18:55:28 +03:00
<!-- vim:set ts=4 sw=4 spell : -->