asyncro
Advanced tools
Comparing version 1.0.0 to 2.0.0
{ | ||
"name": "asyncro", | ||
"version": "1.0.0", | ||
"description": "Utilities for working with Arrays asynchronously.", | ||
"main": "lib/index.js", | ||
"version": "2.0.0", | ||
"description": "Asynchronous Array Utilities (for await)", | ||
"main": "dist/asyncro.js", | ||
"jsnext:main": "src/index.js", | ||
"minified:main": "dist/asyncro.min.js", | ||
"scripts": { | ||
"build": "babel src -d lib --minified --no-comments -s", | ||
"prepublish": "npm run -s build && npm run -s test", | ||
"test": "babel-node test", | ||
"clean": "rimraf dist/", | ||
"build": "npm-run-all --silent clean transpile minify docs size", | ||
"prepublish": "npm-run-all build test", | ||
"transpile": "rollup -c rollup.config.js -m ${npm_package_main}.map -f umd -n $npm_package_name $npm_package_jsnext_main -o $npm_package_main", | ||
"minify": "uglifyjs $npm_package_main -cm -o $npm_package_minified_main -p relative --in-source-map ${npm_package_main}.map --source-map ${npm_package_minified_main}.map", | ||
"size": "size=$(gzip-size $npm_package_minified_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", | ||
"docs": "documentation readme src/index.js --section API -q", | ||
"test": "ava --verbose", | ||
"lint": "eslint {src,test}", | ||
"release": "npm run -s build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/developit/asyncro.git" | ||
}, | ||
"repository": "developit/asyncro", | ||
"keywords": [ | ||
@@ -23,3 +27,3 @@ "async", | ||
"author": "Jason Miller <jason@developit.ca>", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -30,8 +34,18 @@ "url": "https://github.com/developit/asyncro/issues" | ||
"devDependencies": { | ||
"ava": "^0.16.0", | ||
"babel-cli": "^6.14.0", | ||
"babel-plugin-async-to-promises": "^1.0.5", | ||
"babel-plugin-transform-react-jsx": "^6.8.0", | ||
"babel-preset-es2015": "^6.14.0", | ||
"babel-preset-stage-0": "^6.5.0" | ||
"documentation": "^4.0.0-beta11", | ||
"eslint": "^3.8.1", | ||
"gzip-size-cli": "^1.0.0", | ||
"npm-run-all": "^3.1.1", | ||
"pretty-bytes-cli": "^2.0.0", | ||
"rollup": "^0.36.3", | ||
"rollup-plugin-babel": "^2.6.1", | ||
"rollup-plugin-es3": "^1.0.3", | ||
"rollup-plugin-memory": "^2.0.0", | ||
"sinon": "^1.17.6", | ||
"uglify-js": "^2.7.3" | ||
} | ||
} |
127
README.md
# `asyncro` [![NPM](https://img.shields.io/npm/v/asyncro.svg?style=flat)](https://www.npmjs.org/package/asyncro) [![travis-ci](https://travis-ci.org/developit/asyncro.svg?branch=master)](https://travis-ci.org/developit/asyncro) | ||
Converts JSX to Objects (JSON) <sub>using blood magic</sub>. | ||
It's the `map()`, `reduce()` & `filter()` you know, but with support for async callbacks! | ||
<img src="http://i.imgur.com/yiiq6Gx.png" width="275" alt="preview"> | ||
### Installation | ||
```sh | ||
@@ -9,4 +13,2 @@ npm install --save asyncro | ||
--- | ||
### Example | ||
@@ -18,3 +20,3 @@ | ||
async function example() { | ||
await map( | ||
return await map( | ||
['foo', 'bar'], | ||
@@ -25,1 +27,118 @@ async name => fetch('./'+name) | ||
``` | ||
### API | ||
<!-- Generated by documentation.js. Update this documentation by updating the source code. --> | ||
#### reduce | ||
Invoke an async reducer function on each item in the given Array, | ||
where the reducer transforms an accumulator value based on each item iterated over. | ||
**Note:** because `reduce()` is order-sensitive, iteration is sequential. | ||
> This is an asynchronous version of `Array.prototype.reduce()` | ||
**Parameters** | ||
- `array` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** The Array to reduce | ||
- `reducer` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Async function, gets passed `(accumulator, value, index, array)` and returns a new value for `accumulator` | ||
- `accumulator` **\[Any]** Optional initial accumulator value | ||
**Examples** | ||
```javascript | ||
await reduce( | ||
['/foo', '/bar', '/baz'], | ||
async (accumulator, value) => { | ||
accumulator[v] = await fetch(value); | ||
return accumulator; | ||
}, | ||
{} | ||
); | ||
``` | ||
Returns **any** final `accumulator` value | ||
#### map | ||
Invoke an async transform function on each item in the given Array **in parallel**, | ||
returning the resulting Array of mapped/transformed items. | ||
> This is an asynchronous, parallelized version of `Array.prototype.map()`. | ||
**Parameters** | ||
- `array` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** The Array to map over | ||
- `mapper` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Async function, gets passed `(value, index, array)`, returns the new value. | ||
**Examples** | ||
```javascript | ||
await map( | ||
['foo', 'baz'], | ||
async v => await fetch(v) | ||
) | ||
``` | ||
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** resulting mapped/transformed values. | ||
#### filter | ||
Invoke an async filter function on each item in the given Array **in parallel**, | ||
returning an Array of values for which the filter function returned a truthy value. | ||
> This is an asynchronous, parallelized version of `Array.prototype.filter()`. | ||
**Parameters** | ||
- `array` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** The Array to filter | ||
- `filterer` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Async function. Gets passed `(value, index, array)`, returns true to keep the value in the resulting filtered Array. | ||
**Examples** | ||
```javascript | ||
await filter( | ||
['foo', 'baz'], | ||
async v => (await fetch(v)).ok | ||
) | ||
``` | ||
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** resulting filtered values | ||
#### parallel | ||
Invoke all async functions in an Array or Object **in parallel**, returning the result. | ||
**Parameters** | ||
- `list` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)> | [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)<[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)>)** Array/Object with values that are async functions to invoke. | ||
**Examples** | ||
```javascript | ||
await parallel([ | ||
async () => await fetch('foo'), | ||
async () => await fetch('baz') | ||
]) | ||
``` | ||
Returns **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** same structure as `list` input, but with values now resolved. | ||
#### series | ||
Invoke all async functions in an Array or Object **sequentially**, returning the result. | ||
**Parameters** | ||
- `list` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)> | [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)<[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)>)** Array/Object with values that are async functions to invoke. | ||
**Examples** | ||
```javascript | ||
await series([ | ||
async () => await fetch('foo'), | ||
async () => await fetch('baz') | ||
]) | ||
``` | ||
Returns **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** same structure as `list` input, but with values now resolved. |
116
src/index.js
@@ -1,47 +0,82 @@ | ||
/** Async version of Array.prototype.reduce() | ||
* await reduce(['/foo', '/bar', '/baz'], async (acc, v) => { | ||
* acc[v] = await (await fetch(v)).json(); | ||
* return acc; | ||
* }, {}); | ||
import { resolve, pushReducer } from './util'; | ||
/** Invoke an async reducer function on each item in the given Array, | ||
* where the reducer transforms an accumulator value based on each item iterated over. | ||
* **Note:** because `reduce()` is order-sensitive, iteration is sequential. | ||
* | ||
* > This is an asynchronous version of `Array.prototype.reduce()` | ||
* | ||
* @param {Array} array The Array to reduce | ||
* @param {Function} reducer Async function, gets passed `(accumulator, value, index, array)` and returns a new value for `accumulator` | ||
* @param {Any} [accumulator] Optional initial accumulator value | ||
* @returns final `accumulator` value | ||
* | ||
* @example | ||
* await reduce( | ||
* ['/foo', '/bar', '/baz'], | ||
* async (accumulator, value) => { | ||
* accumulator[v] = await fetch(value); | ||
* return accumulator; | ||
* }, | ||
* {} | ||
* ); | ||
*/ | ||
export async function reduce(arr, fn, val, pure) { | ||
for (let i=0; i<arr.length; i++) { | ||
let v = await fn(val, arr[i], i, arr); | ||
if (pure!==false) val = v; | ||
export async function reduce(array, reducer, accumulator) { | ||
for (let i=0; i<array.length; i++) { | ||
accumulator = await reducer(accumulator, array[i], i, array); | ||
} | ||
return val; | ||
return accumulator; | ||
} | ||
/** Async version of Array.prototype.map() | ||
* await map(['foo', 'baz'], async v => await fetch(v) ) | ||
/** Invoke an async transform function on each item in the given Array **in parallel**, | ||
* returning the resulting Array of mapped/transformed items. | ||
* | ||
* > This is an asynchronous, parallelized version of `Array.prototype.map()`. | ||
* | ||
* @param {Array} array The Array to map over | ||
* @param {Function} mapper Async function, gets passed `(value, index, array)`, returns the new value. | ||
* @returns {Array} resulting mapped/transformed values. | ||
* | ||
* @example | ||
* await map( | ||
* ['foo', 'baz'], | ||
* async v => await fetch(v) | ||
* ) | ||
*/ | ||
export async function map(arr, fn) { | ||
return await reduce(arr, async (acc, value, index, arr) => { | ||
acc.push(await fn(value, index, arr)); | ||
}, [], false); | ||
export function map(array, mapper) { | ||
return Promise.all(array.map(mapper)); | ||
} | ||
/** Async version of Array.prototype.filter() | ||
* await filter(['foo', 'baz'], async v => (await fetch(v)).ok ) | ||
/** Invoke an async filter function on each item in the given Array **in parallel**, | ||
* returning an Array of values for which the filter function returned a truthy value. | ||
* | ||
* > This is an asynchronous, parallelized version of `Array.prototype.filter()`. | ||
* | ||
* @param {Array} array The Array to filter | ||
* @param {Function} filterer Async function. Gets passed `(value, index, array)`, returns true to keep the value in the resulting filtered Array. | ||
* @returns {Array} resulting filtered values | ||
* | ||
* @example | ||
* await filter( | ||
* ['foo', 'baz'], | ||
* async v => (await fetch(v)).ok | ||
* ) | ||
*/ | ||
export async function filter(arr, fn) { | ||
return await reduce(arr, async (acc, value, index, arr) => { | ||
if (await fn(value, index, arr)) acc.push(value); | ||
}, [], false); | ||
export async function filter(array, filterer) { | ||
let mapped = await map(array, filterer); | ||
return array.filter( (v, i) => mapped[i] ); | ||
} | ||
function identity(x) { | ||
return x; | ||
} | ||
function resolve(list) { | ||
let out = Array.isArray(list) ? [] : {}; | ||
for (let i in list) if (list.hasOwnProperty(i)) out[i] = list[i](); | ||
return out; | ||
} | ||
/** Provided by standard lib, replaces async.parallel() | ||
/** Invoke all async functions in an Array or Object **in parallel**, returning the result. | ||
* @param {Array<Function>|Object<Function>} list Array/Object with values that are async functions to invoke. | ||
* @returns {Array|Object} same structure as `list` input, but with values now resolved. | ||
* | ||
* @example | ||
* await parallel([ | ||
* () => fetch('foo'), | ||
* () => fetch('baz') | ||
* async () => await fetch('foo'), | ||
* async () => await fetch('baz') | ||
* ]) | ||
@@ -53,10 +88,15 @@ */ | ||
/** Replaces async.series() | ||
/** Invoke all async functions in an Array or Object **sequentially**, returning the result. | ||
* @param {Array<Function>|Object<Function>} list Array/Object with values that are async functions to invoke. | ||
* @returns {Array|Object} same structure as `list` input, but with values now resolved. | ||
* | ||
* @example | ||
* await series([ | ||
* () => fetch('foo'), | ||
* () => fetch('baz') | ||
* async () => await fetch('foo'), | ||
* async () => await fetch('baz') | ||
* ]) | ||
*/ | ||
export async function series(list) { | ||
return await map(resolve(list), identity); | ||
return await reduce(resolve(list), pushReducer, []); | ||
} |
@@ -1,16 +0,50 @@ | ||
import assert from 'assert'; | ||
import { series, parallel } from '../src'; | ||
import test from 'ava'; | ||
import { spy } from 'sinon'; | ||
import { series, parallel, map } from '..'; | ||
assert.equal(typeof series, 'function'); | ||
const get = v => Promise.resolve(v); | ||
assert.equal(typeof parallel, 'function'); | ||
const sleep = time => new Promise( r => setTimeout(r, time) ); | ||
parallel([ | ||
() => Promise.resolve('a'), | ||
() => Promise.resolve('b') | ||
]).then( out => { | ||
assert.deepEqual(out, ['a', 'b']); | ||
console.log('✅ success'); | ||
process.exit(0); | ||
test('series', async t => { | ||
t.is(typeof series, 'function'); | ||
t.deepEqual( | ||
await series([ | ||
async () => await get(1), | ||
async () => await get(2) | ||
]), | ||
[1, 2] | ||
); | ||
}); | ||
test('parallel', async t => { | ||
t.is(typeof parallel, 'function', 'should be a function'); | ||
t.deepEqual( | ||
await parallel([ | ||
async () => await get(1), | ||
async () => await get(2) | ||
]), | ||
[1, 2] | ||
); | ||
}); | ||
test('map', async t => { | ||
t.is(typeof map, 'function'); | ||
let fn = spy( async value => (await sleep(50), await get(value * 2)) ); | ||
let start = Date.now(); | ||
let out = await map([1, 2, 3], fn); | ||
t.deepEqual(out, [2, 4, 6]); | ||
let elapsed = Date.now() - start; | ||
t.true(elapsed < 100, 'Should invoke in parallel'); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
13756
10
0
163
142
15
1
1