$
This commit is contained in:
37
node_modules/erre/CHANGELOG.md
generated
vendored
Normal file
37
node_modules/erre/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# erre
|
||||
|
||||
## 2.2.0
|
||||
- added: unsubscription methods https://github.com/GianlucaGuarini/erre/issues/2
|
||||
|
||||
## 2.1.4
|
||||
- updated: simplify the stream end event using the native `generator.return()` method
|
||||
|
||||
## 2.1.2
|
||||
|
||||
- updated: eslint config and the other dev dependencies
|
||||
- fixed: all the `npm audit` issues
|
||||
|
||||
## 2.1.1
|
||||
|
||||
- added: `ruit` into the `erre` dependencies
|
||||
|
||||
## 2.1.0
|
||||
|
||||
- added: the `erre.install` method
|
||||
|
||||
## 2.0.1
|
||||
|
||||
- fixed: typos in the doc
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- changed: all the `on*` API methods were linked to the `on` object for example: `onValue` => `on.value`
|
||||
- added: the `next` method to run raw stream events without dispatching them to the listeners
|
||||
|
||||
## 1.2.0
|
||||
|
||||
- updated: return the stream generator extended with erre API methods
|
||||
|
||||
## 1.1.0
|
||||
|
||||
- added: `onEnd` method
|
21
node_modules/erre/LICENSE
generated
vendored
Normal file
21
node_modules/erre/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Gianluca Guarini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
353
node_modules/erre/README.md
generated
vendored
Normal file
353
node_modules/erre/README.md
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
<img alt="erre.js" src="https://cdn.rawgit.com/GianlucaGuarini/erre/master/erre-logo.svg" width="50%"/>
|
||||
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
|
||||
[![NPM version][npm-version-image]][npm-url]
|
||||
[![NPM downloads][npm-downloads-image]][npm-url]
|
||||
[![MIT License][license-image]][license-url]
|
||||
|
||||
## Description
|
||||
|
||||
Erre is a modern, performant and tiny (~0.5kb minified) streams script using generators that runs on modern browsers and node.
|
||||
It can be used to manage any kind of sync and async event series and it's inspired to bigger libraries like:
|
||||
- [baconjs](https://baconjs.github.io/)
|
||||
- [RxJS](http://reactivex.io/rxjs/)
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm i erre -S
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
You can use it to create and manipulate simple event streams
|
||||
|
||||
```js
|
||||
import erre from 'erre'
|
||||
|
||||
const stream = erre(
|
||||
string => string.toUpperCase(),
|
||||
string => [...string].reverse().join('')
|
||||
)
|
||||
|
||||
stream.on.value(console.log) // EVOL, ETAH
|
||||
|
||||
stream.push('love')
|
||||
stream.push(async () => await 'hate') // async values
|
||||
```
|
||||
|
||||
It supports async and sync event chains thanks to [ruit](https://github.com/GianlucaGuarini/ruit)
|
||||
|
||||
```js
|
||||
const userNamesStream = erre(
|
||||
async user => await patchUsers(user), // async function returning a users collection
|
||||
users => users.map(user => user.name)
|
||||
)
|
||||
|
||||
userNamesStream.on.value(console.log) // ['John'...]
|
||||
|
||||
userNamesStream.push({
|
||||
name: 'John',
|
||||
role: 'Doctor',
|
||||
age: 24
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### erre(...functions)
|
||||
##### @returns [`stream`](#stream)
|
||||
|
||||
Create an `erre` stream object.
|
||||
The initial `functions` list is optional and it represents the chain of async or sync events needed to generate the final stream output received via [`on.value`](#streamonvaluecallback) callbacks
|
||||
|
||||
### stream
|
||||
|
||||
It's an enhanced [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator) object having additional API methods
|
||||
|
||||
#### stream.push(value)
|
||||
##### @returns `stream`
|
||||
|
||||
Push a new value into the stream that will be asynchronously modified and returned as argument to [`stream.on.value`](#streamonvaluecallback) method
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre()
|
||||
stream.on.value(console.log) // 1
|
||||
stream.push(1)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.on.value(callback)
|
||||
##### @returns `stream`
|
||||
|
||||
Add a callback that will be called receiving the output of the stream asynchronously
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(console.log) // 2
|
||||
stream.on.value(val => console.log(val * 2)) // 4
|
||||
|
||||
stream.push(1)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.on.error(callback)
|
||||
##### @returns `stream`
|
||||
|
||||
Add a callback that will be called in case of errors or promise rejections during the output generation
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => {
|
||||
throw 'error'
|
||||
})
|
||||
|
||||
stream.on.value(console.log) // never called!!
|
||||
stream.on.error(console.log) // 'error'
|
||||
|
||||
stream.push(1)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.on.end(callback)
|
||||
##### @returns `stream`
|
||||
|
||||
Add a callback that will be called when the stream will be ended
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre()
|
||||
|
||||
stream.on.end(() => console.log('ended!')) // ended!
|
||||
|
||||
stream.end()
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.off.value(callback)
|
||||
##### @returns `stream`
|
||||
##### @throws `Error` if `callback` isn't registered
|
||||
|
||||
Removes a previously-registered callback
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre()
|
||||
|
||||
const handler = (value) => console.log('handling', value)
|
||||
stream.on.value(handler)
|
||||
stream.push(1) // handler called, logs: handling 1
|
||||
|
||||
stream.off.value(handler)
|
||||
stream.push(2) // handler is not called
|
||||
|
||||
// throws, because the handler is not registered
|
||||
const someOtherHandler = () => console.log(`don't register me`)
|
||||
stream.off.value(someOtherHandler)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.off.error(callback)
|
||||
##### @returns `stream`
|
||||
##### @throws `Error` if `callback` isn't registered
|
||||
|
||||
#### stream.off.end(callback)
|
||||
##### @returns `stream`
|
||||
##### @throws `Error` if `callback` isn't registered
|
||||
|
||||
#### stream.connect(function)
|
||||
##### @returns `stream`
|
||||
|
||||
Enhance the stream adding a new operation to the functions chain to generate its output
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(console.log) // 2, 4
|
||||
stream.push(1)
|
||||
|
||||
// enhance the stream
|
||||
stream.connect(val => val * 2)
|
||||
stream.push(1)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.end()
|
||||
##### @returns `stream`
|
||||
|
||||
End the stream
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(console.log) // 2
|
||||
stream.push(1)
|
||||
|
||||
// end the stream
|
||||
stream.end()
|
||||
|
||||
// no more events
|
||||
stream.push(1)
|
||||
stream.push(1)
|
||||
stream.push(1)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.fork()
|
||||
##### @returns new `stream` object
|
||||
|
||||
Create a new stream object inheriting the function chain from its parent
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(console.log) // 2, 3
|
||||
stream.push(1)
|
||||
|
||||
const fork = stream.fork()
|
||||
fork.on.value(console.log)
|
||||
fork.connect(val => val * 10) // 20, 60
|
||||
|
||||
// 2 independent streams
|
||||
fork.push(1)
|
||||
stream.push(2)
|
||||
fork.push(5)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### stream.next(value)
|
||||
##### @returns { done: true|false, value: Promise|undefined }
|
||||
|
||||
Run a single stream sequence (**without dispatching any event**) returning as `value` a promise result of the stream computation.
|
||||
If the stream was ended the `done` value will be `true` and the `value` will be `undefined`.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(console.log) // never called
|
||||
|
||||
const { value } = stream.next(1)
|
||||
|
||||
value.then(console.log) // 2
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### erre.cancel()
|
||||
|
||||
Static function that if returned by any of the stream functions chain can be used to filter or stop the computation
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => {
|
||||
if (typeof val !== 'number') return erre.cancel()
|
||||
return val + 1
|
||||
})
|
||||
|
||||
stream.on.value(console.log) // 2, 3
|
||||
stream.push(1)
|
||||
stream.push('foo') // filtered
|
||||
stream.push('1') // filtered
|
||||
stream.push(2)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### erre.off()
|
||||
|
||||
Static function that if returned by any of the subscribed callbacks can be used to unsubscribe it
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(val => {
|
||||
// if this condition will be matched, this callback will be unsubscribed
|
||||
if (typeof val !== 'number') return erre.off()
|
||||
console.log(val)
|
||||
}) // 2
|
||||
stream.push(1)
|
||||
// this value will let the previous listener unsubscribe itself
|
||||
stream.push('foo')
|
||||
stream.push('1')
|
||||
// this value will not be logged because the stream.on.value was unsubscribed
|
||||
stream.push(2)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### erre.install(name, fn)
|
||||
##### @returns [`erre`](#errefunctions)
|
||||
|
||||
Extend erre adding custom API methods. Any plugin must have at lease a `name` (as string) and a `function`
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```js
|
||||
// alias the `console.log` with `erre.log`
|
||||
erre.install('log', console.log)
|
||||
|
||||
const stream = erre(val => val + 1)
|
||||
|
||||
stream.on.value(erre.log) // 2, 3
|
||||
stream.push(1)
|
||||
stream.push(2)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
# TODO List
|
||||
|
||||
- [x] [erre.fromDOM](https://github.com/GianlucaGuarini/erre.fromDOM) - to stream DOM nodes events
|
||||
- [x] [erre.merge](https://github.com/GianlucaGuarini/erre.merge) - to merge multiple stream results into one
|
||||
|
||||
[travis-image]:https://img.shields.io/travis/GianlucaGuarini/erre.svg?style=flat-square
|
||||
[travis-url]:https://travis-ci.org/GianlucaGuarini/erre
|
||||
|
||||
[license-image]:http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
|
||||
[license-url]:LICENSE
|
||||
|
||||
[npm-version-image]:http://img.shields.io/npm/v/erre.svg?style=flat-square
|
||||
[npm-downloads-image]:http://img.shields.io/npm/dm/erre.svg?style=flat-square
|
||||
[npm-url]:https://npmjs.org/package/erre
|
||||
|
243
node_modules/erre/erre.js
generated
vendored
Normal file
243
node_modules/erre/erre.js
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = global || self, global.erre = factory());
|
||||
}(this, function () { 'use strict';
|
||||
|
||||
/**
|
||||
* Cancel token
|
||||
* @private
|
||||
* @type { Symbol }
|
||||
*/
|
||||
const CANCEL = Symbol();
|
||||
|
||||
/**
|
||||
* Helper that can be returned by ruit function to cancel the tasks chain
|
||||
* @returns { Symbol } internal private constant
|
||||
* @example
|
||||
*
|
||||
* ruit(
|
||||
* 100,
|
||||
* num => Math.random() * num
|
||||
* num => num > 50 ? ruit.cancel() : num
|
||||
* num => num - 2
|
||||
* ).then(result => {
|
||||
* console.log(result) // here we will get only number lower than 50
|
||||
* })
|
||||
*
|
||||
*/
|
||||
ruit.cancel = () => CANCEL;
|
||||
|
||||
/**
|
||||
* The same as ruit() but with the arguments inverted from right to left
|
||||
* @param { * } tasks - list of tasks to process sequentially
|
||||
* @returns { Promise } a promise containing the result of the whole chain
|
||||
* @example
|
||||
*
|
||||
* const curry = f => a => b => f(a, b)
|
||||
* const add = (a, b) => a + b
|
||||
*
|
||||
* const addOne = curry(add)(1)
|
||||
*
|
||||
* const squareAsync = (num) => {
|
||||
* return new Promise(r => {
|
||||
* setTimeout(r, 500, num * 2)
|
||||
* })
|
||||
* }
|
||||
*
|
||||
* // a -> a + a -> a * 2
|
||||
* // basically from right to left: 1 => 1 + 1 => 2 * 2
|
||||
* ruit.compose(squareAsync, addOne, 1).then(result => console.log(result)) // 4
|
||||
*/
|
||||
ruit.compose = (...tasks) => ruit(...tasks.reverse());
|
||||
|
||||
/**
|
||||
* Serialize a list of sync and async tasks from left to right
|
||||
* @param { * } tasks - list of tasks to process sequentially
|
||||
* @returns { Promise } a promise containing the result of the whole chain
|
||||
* @example
|
||||
*
|
||||
* const curry = f => a => b => f(a, b)
|
||||
* const add = (a, b) => a + b
|
||||
*
|
||||
* const addOne = curry(add)(1)
|
||||
*
|
||||
* const squareAsync = (num) => {
|
||||
* return new Promise(r => {
|
||||
* setTimeout(r, 500, num * 2)
|
||||
* })
|
||||
* }
|
||||
*
|
||||
* // a -> a + a -> a * 2
|
||||
* // basically from left to right: 1 => 1 + 1 => 2 * 2
|
||||
* ruit(1, addOne, squareAsync).then(result => console.log(result)) // 4
|
||||
*/
|
||||
function ruit(...tasks) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return (function run(queue, result) {
|
||||
if (!queue.length) return resolve(result)
|
||||
|
||||
const [task, ...rest] = queue;
|
||||
const value = typeof task === 'function' ? task(result) : task;
|
||||
const done = v => run(rest, v);
|
||||
|
||||
// check against nil values
|
||||
if (value != null) {
|
||||
if (value === CANCEL) return
|
||||
if (value.then) return value.then(done, reject)
|
||||
}
|
||||
|
||||
return Promise.resolve(done(value))
|
||||
})(tasks)
|
||||
})
|
||||
}
|
||||
|
||||
// Store the erre the API methods to handle the plugins installation
|
||||
const API_METHODS = new Set();
|
||||
const UNSUBSCRIBE_SYMBOL = Symbol();
|
||||
const UNSUBSCRIBE_METHOD = 'off';
|
||||
const CANCEL_METHOD = 'cancel';
|
||||
|
||||
/**
|
||||
* Factory function to create the stream generator
|
||||
* @private
|
||||
* @param {Set} modifiers - stream input modifiers
|
||||
* @returns {Generator} the stream generator
|
||||
*/
|
||||
function createStream(modifiers) {
|
||||
const stream = (function *stream() {
|
||||
while (true) {
|
||||
// get the initial stream value
|
||||
const input = yield;
|
||||
|
||||
// run the input sequence
|
||||
yield ruit(input, ...modifiers);
|
||||
}
|
||||
})();
|
||||
|
||||
// start the stream
|
||||
stream.next();
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a value to several listeners
|
||||
* @private
|
||||
* @param {Set} callbacks - callbacks collection
|
||||
* @param {*} value - anything
|
||||
* @returns {Set} the callbacks received
|
||||
*/
|
||||
function dispatch(callbacks, value) {
|
||||
callbacks.forEach(f => {
|
||||
// unsubscribe the callback if erre.unsubscribe() will be returned
|
||||
if (f(value) === UNSUBSCRIBE_SYMBOL) callbacks.delete(f);
|
||||
});
|
||||
|
||||
return callbacks
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a panic error
|
||||
* @param {string} message - error message
|
||||
* @returns {Error} an error object
|
||||
*/
|
||||
function panic(message) {
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Install an erre plugin adding it to the API
|
||||
* @param {string} name - plugin name
|
||||
* @param {Function} fn - new erre API method
|
||||
* @returns {Function} return the erre function
|
||||
*/
|
||||
erre.install = function(name, fn) {
|
||||
if (!name || typeof name !== 'string')
|
||||
panic('Please provide a name (as string) for your erre plugin');
|
||||
if (!fn || typeof fn !== 'function')
|
||||
panic('Please provide a function for your erre plugin');
|
||||
|
||||
if (API_METHODS.has(name)) {
|
||||
panic(`The ${name} is already part of the erre API, please provide a different name`);
|
||||
} else {
|
||||
erre[name] = fn;
|
||||
API_METHODS.add(name);
|
||||
}
|
||||
|
||||
return erre
|
||||
};
|
||||
|
||||
// alias for ruit canel to stop a stream chain
|
||||
erre.install(CANCEL_METHOD, ruit.cancel);
|
||||
|
||||
// unsubscribe helper
|
||||
erre.install(UNSUBSCRIBE_METHOD, () => UNSUBSCRIBE_SYMBOL);
|
||||
|
||||
/**
|
||||
* Stream constuction function
|
||||
* @param {...Function} fns - stream modifiers
|
||||
* @returns {Object} erre instance
|
||||
*/
|
||||
function erre(...fns) {
|
||||
const
|
||||
[success, error, end, modifiers] = [new Set(), new Set(), new Set(), new Set(fns)],
|
||||
generator = createStream(modifiers),
|
||||
stream = Object.create(generator),
|
||||
addToCollection = (collection) => (fn) => collection.add(fn) && stream,
|
||||
deleteFromCollection = (collection) => (fn) => collection.delete(fn) ? stream
|
||||
: panic('Couldn\'t remove handler passed by reference');
|
||||
|
||||
return Object.assign(stream, {
|
||||
on: Object.freeze({
|
||||
value: addToCollection(success),
|
||||
error: addToCollection(error),
|
||||
end: addToCollection(end)
|
||||
}),
|
||||
off: Object.freeze({
|
||||
value: deleteFromCollection(success),
|
||||
error: deleteFromCollection(error),
|
||||
end: deleteFromCollection(end)
|
||||
}),
|
||||
connect: addToCollection(modifiers),
|
||||
push(input) {
|
||||
const { value, done } = stream.next(input);
|
||||
|
||||
// dispatch the stream events
|
||||
if (!done) {
|
||||
value.then(
|
||||
res => dispatch(success, res),
|
||||
err => dispatch(error, err)
|
||||
);
|
||||
}
|
||||
|
||||
return stream
|
||||
},
|
||||
end() {
|
||||
// kill the stream
|
||||
generator.return();
|
||||
// dispatch the end event
|
||||
dispatch(end)
|
||||
// clean up all the collections
|
||||
;[success, error, end, modifiers].forEach(el => el.clear());
|
||||
|
||||
return stream
|
||||
},
|
||||
fork() {
|
||||
return erre(...modifiers)
|
||||
},
|
||||
next(input) {
|
||||
// get the input and run eventually the promise
|
||||
const result = generator.next(input);
|
||||
|
||||
// pause to the next iteration
|
||||
generator.next();
|
||||
|
||||
return result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return erre;
|
||||
|
||||
}));
|
147
node_modules/erre/index.next.js
generated
vendored
Normal file
147
node_modules/erre/index.next.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
import ruit from 'ruit'
|
||||
|
||||
// Store the erre the API methods to handle the plugins installation
|
||||
const API_METHODS = new Set()
|
||||
const UNSUBSCRIBE_SYMBOL = Symbol()
|
||||
const UNSUBSCRIBE_METHOD = 'off'
|
||||
const CANCEL_METHOD = 'cancel'
|
||||
|
||||
/**
|
||||
* Factory function to create the stream generator
|
||||
* @private
|
||||
* @param {Set} modifiers - stream input modifiers
|
||||
* @returns {Generator} the stream generator
|
||||
*/
|
||||
function createStream(modifiers) {
|
||||
const stream = (function *stream() {
|
||||
while (true) {
|
||||
// get the initial stream value
|
||||
const input = yield
|
||||
|
||||
// run the input sequence
|
||||
yield ruit(input, ...modifiers)
|
||||
}
|
||||
})()
|
||||
|
||||
// start the stream
|
||||
stream.next()
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a value to several listeners
|
||||
* @private
|
||||
* @param {Set} callbacks - callbacks collection
|
||||
* @param {*} value - anything
|
||||
* @returns {Set} the callbacks received
|
||||
*/
|
||||
function dispatch(callbacks, value) {
|
||||
callbacks.forEach(f => {
|
||||
// unsubscribe the callback if erre.unsubscribe() will be returned
|
||||
if (f(value) === UNSUBSCRIBE_SYMBOL) callbacks.delete(f)
|
||||
})
|
||||
|
||||
return callbacks
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a panic error
|
||||
* @param {string} message - error message
|
||||
* @returns {Error} an error object
|
||||
*/
|
||||
function panic(message) {
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Install an erre plugin adding it to the API
|
||||
* @param {string} name - plugin name
|
||||
* @param {Function} fn - new erre API method
|
||||
* @returns {Function} return the erre function
|
||||
*/
|
||||
erre.install = function(name, fn) {
|
||||
if (!name || typeof name !== 'string')
|
||||
panic('Please provide a name (as string) for your erre plugin')
|
||||
if (!fn || typeof fn !== 'function')
|
||||
panic('Please provide a function for your erre plugin')
|
||||
|
||||
if (API_METHODS.has(name)) {
|
||||
panic(`The ${name} is already part of the erre API, please provide a different name`)
|
||||
} else {
|
||||
erre[name] = fn
|
||||
API_METHODS.add(name)
|
||||
}
|
||||
|
||||
return erre
|
||||
}
|
||||
|
||||
// alias for ruit canel to stop a stream chain
|
||||
erre.install(CANCEL_METHOD, ruit.cancel)
|
||||
|
||||
// unsubscribe helper
|
||||
erre.install(UNSUBSCRIBE_METHOD, () => UNSUBSCRIBE_SYMBOL)
|
||||
|
||||
/**
|
||||
* Stream constuction function
|
||||
* @param {...Function} fns - stream modifiers
|
||||
* @returns {Object} erre instance
|
||||
*/
|
||||
export default function erre(...fns) {
|
||||
const
|
||||
[success, error, end, modifiers] = [new Set(), new Set(), new Set(), new Set(fns)],
|
||||
generator = createStream(modifiers),
|
||||
stream = Object.create(generator),
|
||||
addToCollection = (collection) => (fn) => collection.add(fn) && stream,
|
||||
deleteFromCollection = (collection) => (fn) => collection.delete(fn) ? stream
|
||||
: panic('Couldn\'t remove handler passed by reference')
|
||||
|
||||
return Object.assign(stream, {
|
||||
on: Object.freeze({
|
||||
value: addToCollection(success),
|
||||
error: addToCollection(error),
|
||||
end: addToCollection(end)
|
||||
}),
|
||||
off: Object.freeze({
|
||||
value: deleteFromCollection(success),
|
||||
error: deleteFromCollection(error),
|
||||
end: deleteFromCollection(end)
|
||||
}),
|
||||
connect: addToCollection(modifiers),
|
||||
push(input) {
|
||||
const { value, done } = stream.next(input)
|
||||
|
||||
// dispatch the stream events
|
||||
if (!done) {
|
||||
value.then(
|
||||
res => dispatch(success, res),
|
||||
err => dispatch(error, err)
|
||||
)
|
||||
}
|
||||
|
||||
return stream
|
||||
},
|
||||
end() {
|
||||
// kill the stream
|
||||
generator.return()
|
||||
// dispatch the end event
|
||||
dispatch(end)
|
||||
// clean up all the collections
|
||||
;[success, error, end, modifiers].forEach(el => el.clear())
|
||||
|
||||
return stream
|
||||
},
|
||||
fork() {
|
||||
return erre(...modifiers)
|
||||
},
|
||||
next(input) {
|
||||
// get the input and run eventually the promise
|
||||
const result = generator.next(input)
|
||||
|
||||
// pause to the next iteration
|
||||
generator.next()
|
||||
|
||||
return result
|
||||
}
|
||||
})
|
||||
}
|
47
node_modules/erre/package.json
generated
vendored
Normal file
47
node_modules/erre/package.json
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "erre",
|
||||
"version": "2.2.0",
|
||||
"description": "Modern, performant and tiny streams script using generators",
|
||||
"main": "erre.js",
|
||||
"jsnext:main": "index.next.js",
|
||||
"module": "index.next.js",
|
||||
"scripts": {
|
||||
"prepare": "npm run build && npm test",
|
||||
"lint": "eslint index.next.js test.js rollup.config.js",
|
||||
"build": "rollup -c",
|
||||
"bench": "node bench",
|
||||
"test": "npm run lint && mocha test.js"
|
||||
},
|
||||
"files": [
|
||||
"index.next.js"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/gianlucaguarini/erre.git"
|
||||
},
|
||||
"keywords": [
|
||||
"es6",
|
||||
"es2015",
|
||||
"streams",
|
||||
"generator",
|
||||
"functional",
|
||||
"reactive"
|
||||
],
|
||||
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (http://gianlucaguarini.com)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/gianlucaguarini/erre/issues"
|
||||
},
|
||||
"homepage": "https://github.com/gianlucaguarini/erre#readme",
|
||||
"devDependencies": {
|
||||
"@gianlucaguarini/eslint-config": "^2.0.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"eslint": "^5.16.0",
|
||||
"mocha": "^6.1.4",
|
||||
"rollup": "^1.15.5",
|
||||
"rollup-plugin-node-resolve": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ruit": "^1.0.4"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user