@thi.ng/transducers
Advanced tools
Comparing version 0.11.2 to 1.0.0
@@ -12,2 +12,3 @@ export * from "./api"; | ||
export * from "./rfn/count"; | ||
export * from "./rfn/every"; | ||
export * from "./rfn/frequencies"; | ||
@@ -17,3 +18,2 @@ export * from "./rfn/group-binary"; | ||
export * from "./rfn/group-by-obj"; | ||
export * from "./rfn/join"; | ||
export * from "./rfn/last"; | ||
@@ -29,2 +29,4 @@ export * from "./rfn/max-compare"; | ||
export * from "./rfn/reductions"; | ||
export * from "./rfn/some"; | ||
export * from "./rfn/str"; | ||
export * from "./xform/base64"; | ||
@@ -50,2 +52,3 @@ export * from "./xform/benchmark"; | ||
export * from "./xform/keep"; | ||
export * from "./xform/labeled"; | ||
export * from "./xform/map-indexed"; | ||
@@ -57,2 +60,5 @@ export * from "./xform/map-keys"; | ||
export * from "./xform/moving-average"; | ||
export * from "./xform/multiplex"; | ||
export * from "./xform/multiplex-obj"; | ||
export * from "./xform/noop"; | ||
export * from "./xform/pad-last"; | ||
@@ -78,2 +84,4 @@ export * from "./xform/partition-by"; | ||
export * from "./xform/throttle"; | ||
export * from "./xform/throttle-time"; | ||
export * from "./xform/utf8"; | ||
export * from "./func/binary-search"; | ||
@@ -80,0 +88,0 @@ export * from "./func/comp"; |
10
index.js
@@ -17,2 +17,3 @@ "use strict"; | ||
__export(require("./rfn/count")); | ||
__export(require("./rfn/every")); | ||
__export(require("./rfn/frequencies")); | ||
@@ -22,3 +23,2 @@ __export(require("./rfn/group-binary")); | ||
__export(require("./rfn/group-by-obj")); | ||
__export(require("./rfn/join")); | ||
__export(require("./rfn/last")); | ||
@@ -34,2 +34,4 @@ __export(require("./rfn/max-compare")); | ||
__export(require("./rfn/reductions")); | ||
__export(require("./rfn/some")); | ||
__export(require("./rfn/str")); | ||
__export(require("./xform/base64")); | ||
@@ -55,2 +57,3 @@ __export(require("./xform/benchmark")); | ||
__export(require("./xform/keep")); | ||
__export(require("./xform/labeled")); | ||
__export(require("./xform/map-indexed")); | ||
@@ -62,2 +65,5 @@ __export(require("./xform/map-keys")); | ||
__export(require("./xform/moving-average")); | ||
__export(require("./xform/multiplex")); | ||
__export(require("./xform/multiplex-obj")); | ||
__export(require("./xform/noop")); | ||
__export(require("./xform/pad-last")); | ||
@@ -83,2 +89,4 @@ __export(require("./xform/partition-by")); | ||
__export(require("./xform/throttle")); | ||
__export(require("./xform/throttle-time")); | ||
__export(require("./xform/utf8")); | ||
__export(require("./func/binary-search")); | ||
@@ -85,0 +93,0 @@ __export(require("./func/comp")); |
@@ -10,2 +10,2 @@ /** | ||
*/ | ||
export declare function reverse<T>(input: Iterable<T>): IterableIterator<any>; | ||
export declare function reverse<T>(input: Iterable<T>): IterableIterator<T>; |
{ | ||
"name": "@thi.ng/transducers", | ||
"version": "0.11.2", | ||
"version": "1.0.0", | ||
"description": "Lightweight transducer implementations for ES6 / TypeScript", | ||
"main": "./index.js", | ||
"typings": "./index.d.ts", | ||
"repository": "https://github.com/thi-ng/transducers", | ||
"repository": "https://github.com/thi-ng/umbrella", | ||
"author": "Karsten Schmidt <k+npm@thi.ng>", | ||
@@ -14,3 +14,3 @@ "license": "Apache-2.0", | ||
"clean": "rm -rf *.js *.d.ts build doc func iter rfn xform", | ||
"pub": "yarn run build && (cd build && yarn publish --access public)" | ||
"pub": "yarn run build && yarn publish --access public" | ||
}, | ||
@@ -27,4 +27,3 @@ "devDependencies": { | ||
"dependencies": { | ||
"@thi.ng/api": "^1.2.1", | ||
"@thi.ng/checks": "^1.1.1" | ||
"@thi.ng/api": "^1.3.0" | ||
}, | ||
@@ -31,0 +30,0 @@ "keywords": [ |
152
README.md
@@ -21,4 +21,4 @@ # @thi.ng/transducers | ||
Currently, the library provides altogether 75+ transducers, reducers and | ||
sequence generators for composing data transformation pipelines. | ||
This library provides altogether ~85 transducers, reducers and sequence | ||
generators (iterators) for composing data transformation pipelines. | ||
@@ -28,16 +28,16 @@ The overall concept and many of the core functions offered here are directly | ||
implementation does differ (also in contrast to some other JS based | ||
implementations) and several less common, but generally highly useful operators | ||
implementations) and dozens of less common, but generally highly useful operators | ||
have been added, with at least a couple dozen more to come. | ||
Please see the [@thi.ng/iterators](https://github.com/thi-ng/umbrella/tree/master/packages/iterators) & | ||
[@thi.ng/csp](https://github.com/thi-ng/umbrella/tree/master/packages/csp) partner modules for related | ||
functionality, supplementing features of this library. However, this lib has no | ||
dependencies on either of them. The only dependency is | ||
[@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) for re-using common types & | ||
interfaces. | ||
Please see the | ||
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/master/packages/rstream) | ||
& [@thi.ng/csp](https://github.com/thi-ng/umbrella/tree/master/packages/csp) | ||
partner modules for related functionality, supplementing features of this | ||
library and depending on it. | ||
Having said this, since 0.8.0 this project largely supersedes the | ||
[@thi.ng/iterators](https://github.com/thi-ng/umbrella/tree/master/packages/iterators) library for most use | ||
cases and offers are more powerful API and potentially faster execution of | ||
composed transformations (due to lack of ES generator overheads). | ||
Since 0.8.0 this project largely supersedes the | ||
[@thi.ng/iterators](https://github.com/thi-ng/umbrella/tree/master/packages/iterators) | ||
library for most use cases and offers are more powerful API and potentially | ||
faster execution of composed transformations (due to lack of ES generator | ||
overheads). | ||
@@ -89,4 +89,4 @@ ## Installation | ||
// single step execution | ||
// (currently doesn't work w/ mapcat(), duplicate() and some others) | ||
// returns undefined if transducer returned no result for this input | ||
// returns array if transducer step produced multiple results | ||
f = tx.step(xform); | ||
@@ -97,10 +97,7 @@ f(1) // 3 | ||
f(4) // undefined | ||
f(5) // 15 | ||
f(4) // undefined | ||
f(3) // undefined | ||
f(2) // undefined | ||
f(1) // undefined | ||
f = tx.step(take) | ||
``` | ||
### Histogram generation | ||
### Histogram generation & result grouping | ||
@@ -116,4 +113,56 @@ ```typescript | ||
// Map { 1 => 3, 2 => 1, 3 => 1, 4 => 2 } | ||
// with optional key function, here to bin by word length | ||
tx.reduce( | ||
tx.frequencies(x => x.length), | ||
"my camel is collapsing and needs some water".split(" ") | ||
) | ||
// Map { 2 => 2, 5 => 3, 10 => 1, 3 => 1, 4 => 1 } | ||
// actual grouping | ||
tx.reduce( | ||
tx.groupByMap(x => x.length), | ||
"my camel is collapsing and needs some water".split(" ") | ||
) | ||
// Map { | ||
// 2 => [ 'my', 'is' ], | ||
// 3 => [ 'and' ], | ||
// 4 => [ 'some' ], | ||
// 5 => [ 'camel', 'needs', 'water' ], | ||
// 10 => [ 'collapsing' ] | ||
// } | ||
``` | ||
### Multiplexing / parallel transducer application | ||
`multiplex` and `multiplexObj` can be used to transform values in parallel | ||
using the provided transducers (which can be composed as usual) and results in | ||
a tuple or keyed object. | ||
```typescript | ||
tx.transduce( | ||
tx.multiplex( | ||
tx.map(x => x.charAt(0)), | ||
tx.map(x => x.toUpperCase()), | ||
tx.map(x => x.length) | ||
), | ||
tx.push(), | ||
["Alice", "Bob", "Charlie"] | ||
) | ||
// [ [ "A", "ALICE", 5 ], [ "B", "BOB", 3 ], [ "C", "CHARLIE", 7 ] ] | ||
tx.transduce( | ||
tx.multiplexObj({ | ||
initial: tx.map(x => x.charAt(0)), | ||
name: tx.map(x => x.toUpperCase()), | ||
len: tx.map(x => x.length) | ||
}), | ||
tx.push(), | ||
["Alice", "Bob", "Charlie"] | ||
) | ||
// [ { len: 5, name: 'ALICE', initial: 'A' }, | ||
// { len: 3, name: 'BOB', initial: 'B' }, | ||
// { len: 7, name: 'CHARLIE', initial: 'C' } ] | ||
``` | ||
### Moving average using sliding window | ||
@@ -123,4 +172,2 @@ | ||
// use nested reduce to compute window averages | ||
// this combined transducer is also directly | ||
// available as: `tx.movingAverage(n)` | ||
tx.transduce( | ||
@@ -135,2 +182,10 @@ tx.comp( | ||
// [ 2.6, 3.4, 4, 4.6, 5.4, 6.2, 6.8, 7.6, 8.4 ] | ||
// this combined transducer is also directly | ||
// available as: `tx.movingAverage(n)` | ||
tx.transduce( | ||
tx.movingAverage(5), | ||
[1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10] | ||
); | ||
// [ 2.6, 3.4, 4, 4.6, 5.4, 6.2, 6.8, 7.6, 8.4 ] | ||
``` | ||
@@ -182,3 +237,3 @@ | ||
The `struct` transducer is simply a composition of: `partitionOf -> partition -> rename -> mapKeys`. | ||
[See code here](https://github.com/thi-ng/transducers/blob/master/src/xform/struct.ts). | ||
[See code here](https://github.com/thi-ng/umbrella/tree/master/packages/transducers/src/xform/struct.ts). | ||
@@ -266,3 +321,3 @@ ```typescript | ||
This is a higher-order transducer, purely composed from other transducers. | ||
[See code here](https://github.com/thi-ng/transducers/blob/master/src/xform/hex-dump.ts). | ||
[See code here](https://github.com/thi-ng/umbrella/tree/master/packages/transducers/src/xform/hex-dump.ts). | ||
@@ -302,3 +357,3 @@ ```typescript | ||
### Base64 en/decoding | ||
### Base64 & UTF-8 en/decoding | ||
@@ -313,3 +368,3 @@ ```typescript | ||
), | ||
tx.join(), | ||
tx.str(), | ||
tx.range(-8, 8) | ||
@@ -328,2 +383,12 @@ ); | ||
// [ -8, -7, -6, -5, -4, -3, -2, -1 ] | ||
buf = tx.transduce( | ||
tx.comp(tx.utf8Encode(), tx.base64Encode()), | ||
tx.str(), | ||
"beer (🍺) or hot beverage (☕︎)" | ||
); | ||
// "YmVlciAo8J+Nuikgb3IgaG90IGJldmVyYWdlICjimJXvuI4p" | ||
tx.transduce(tx.comp(tx.base64Decode(), tx.utf8Decode()), tx.str(), buf) | ||
// "beer (🍺) or hot beverage (☕︎)" | ||
``` | ||
@@ -344,4 +409,4 @@ | ||
_Documentation is slowly forthcoming in the form of doc comments (incl. code | ||
examples) for a small, but growing number the functions listed below. Please | ||
see source code for now._ | ||
examples) for a growing number the functions listed below. Please see source | ||
code for now._ | ||
@@ -392,4 +457,4 @@ ### Types | ||
Currently `partition`, `partitionBy`, `streamSort`, `streamShuffle` are the only operators making | ||
use of the 1-arity completing function of their reducer. | ||
`partition`, `partitionBy`, `streamSort`, `streamShuffle` are (examples of) | ||
transducers making use of their 1-arity completing function. | ||
@@ -471,7 +536,8 @@ #### Reduced | ||
Helper function to build reducers. | ||
Helper function to compose reducers. | ||
#### `iterator<A, B>(tx: Transducer<A, B>, xs: Iterable<A>): IterableIterator<B>` | ||
Similar to `transduce()`, but emits results as ES6 iterator (and hence doesn't use a reduction function). | ||
Similar to `transduce()`, but emits results as ES6 iterator (and hence doesn't | ||
use a reduction function). | ||
@@ -531,2 +597,4 @@ #### `reduce<A, B>(rfn: Reducer<A, B>, acc: A, xs: Iterable<B>): A` | ||
#### `labeled<L, T>(id: L): Transducer<T, [L, T]>` | ||
#### `map<A, B>(fn: (x: A) => B): Transducer<A, B>` | ||
@@ -544,2 +612,8 @@ | ||
#### `multiplex<T, A, B>(a: Transducer<T, A>, b: Transducer<T, B>...): Transducer<T, [A, B...]>` | ||
#### `multiplexObj<A, B>(xforms: IObjectOf<Transducer<A, any>>, rfn?: Reducer<B, [PropertyKey, any]>): Transducer<A, B>` | ||
#### `noop<T>(): Transducer<T, T>` | ||
#### `padLast<T>(n: number, fill: T): Transducer<T, T>` | ||
@@ -585,2 +659,8 @@ | ||
#### `throttleTime<T>(delay: number): Transducer<T, T>` | ||
#### `utf8Decode(): Transducer<number, string>` | ||
#### `utf8Encode(): Transducer<string, number>` | ||
### Reducers | ||
@@ -598,4 +678,6 @@ | ||
#### `frequencies<T>(): Reducer<Map<T, number>, T>` | ||
#### `every<T>(pred?: Predicate<T>): Reducer<boolean, T>` | ||
#### `frequencies<A, B>(key: (x: A) => B): Reducer<Map<B, number>, A>` | ||
#### `groupBinary<T>(bits: number, key: (x: T) => number, branch?: () => IObjectOf<T[]>, leaf?: Reducer<any, T>, left?: PropertyKey, right?: PropertyKey): Reducer<any, T>` | ||
@@ -625,2 +707,6 @@ | ||
#### `reductions<A, B>(rfn: Reducer<A, B>): Reducer<A[], B>` | ||
#### `some<T>(pred?: Predicate<T>): Reducer<boolean, T>` | ||
### Generators / Iterators | ||
@@ -627,0 +713,0 @@ |
import { Reducer } from "../api"; | ||
export declare function frequencies<T>(): Reducer<Map<T, number>, T>; | ||
export declare function frequencies<A, B>(key?: ((x: A) => B)): Reducer<Map<B, number>, A>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function frequencies() { | ||
return [ | ||
() => new Map(), | ||
(acc) => acc, | ||
(acc, x) => acc.set(x, acc.has(x) ? acc.get(x) + 1 : 1) | ||
]; | ||
const identity_1 = require("../func/identity"); | ||
const count_1 = require("./count"); | ||
const group_by_map_1 = require("./group-by-map"); | ||
function frequencies(key = identity_1.identity) { | ||
return group_by_map_1.groupByMap(key, count_1.count()); | ||
} | ||
exports.frequencies = frequencies; |
import { IObjectOf } from "@thi.ng/api/api"; | ||
import { Reducer } from "../api"; | ||
/** | ||
* Creates a bottom-up binary tree of desired depth and choice of | ||
* data structures. Any value can be indexed, as long as a numeric | ||
* representation (key) can be obtained. This mapping is produced | ||
* Creates a bottom-up, unbalanced binary tree of desired depth and | ||
* choice of data structures. Any value can be indexed, as long as a | ||
* numeric representation (key) can be obtained. This mapping is produced | ||
* by the supplied `key` function. IMPORTANT: the returned values | ||
@@ -8,0 +8,0 @@ * MUST be unsigned and less than the provided bit length (i.e. 2^`bits`). |
@@ -9,5 +9,5 @@ "use strict"; | ||
/** | ||
* Creates a bottom-up binary tree of desired depth and choice of | ||
* data structures. Any value can be indexed, as long as a numeric | ||
* representation (key) can be obtained. This mapping is produced | ||
* Creates a bottom-up, unbalanced binary tree of desired depth and | ||
* choice of data structures. Any value can be indexed, as long as a | ||
* numeric representation (key) can be obtained. This mapping is produced | ||
* by the supplied `key` function. IMPORTANT: the returned values | ||
@@ -14,0 +14,0 @@ * MUST be unsigned and less than the provided bit length (i.e. 2^`bits`). |
import { Reducer } from "../api"; | ||
export declare function groupByMap<A, B, C>(key: (x: A) => B, rfn?: Reducer<C, A>): Reducer<Map<B, C>, A>; | ||
export declare function groupByMap<A, B, C>(key?: ((x: A) => B), rfn?: Reducer<C, A>): Reducer<Map<B, C>, A>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const identity_1 = require("../func/identity"); | ||
const push_1 = require("./push"); | ||
function groupByMap(key, rfn = push_1.push()) { | ||
function groupByMap(key = identity_1.identity, rfn = push_1.push()) { | ||
return [ | ||
@@ -6,0 +7,0 @@ () => new Map(), |
@@ -11,3 +11,3 @@ "use strict"; | ||
if (reduced_1.isReduced(res)) { | ||
acc.push(reduced_1.unreduced(res)); | ||
acc.push(res.deref()); | ||
return reduced_1.reduced(acc); | ||
@@ -14,0 +14,0 @@ } |
import { Transducer } from "./api"; | ||
export declare function step<A, B>(tx: Transducer<A, B>): (x: A) => B; | ||
/** | ||
* Single-step transducer execution wrapper. | ||
* Returns array if transducer produces multiple results | ||
* and undefined if there was no output. Else returns single | ||
* result value. | ||
* | ||
* Likewise, once a transducer has produced a final / reduced | ||
* value, all further invocations of the stepper function will | ||
* return undefined. | ||
* | ||
* ``` | ||
* // single result | ||
* step(map(x => x * 10))(1); | ||
* // 10 | ||
* | ||
* // multiple results | ||
* step(mapcat(x => [x, x + 1, x + 2]))(1) | ||
* // [ 1, 2, 3 ] | ||
* | ||
* // no result | ||
* f = step(filter(even)) | ||
* f(1); // undefined | ||
* f(2); // 2 | ||
* | ||
* // reduced value termination | ||
* f = step(take(2)); | ||
* f(1); // 1 | ||
* f(1); // 1 | ||
* f(1); // undefined | ||
* f(1); // undefined | ||
* ``` | ||
* | ||
* @param tx | ||
*/ | ||
export declare function step<A, B>(tx: Transducer<A, B>): (x: A) => B | B[]; |
56
step.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const last_1 = require("./rfn/last"); | ||
const push_1 = require("./rfn/push"); | ||
const index_1 = require("./index"); | ||
/** | ||
* Single-step transducer execution wrapper. | ||
* Returns array if transducer produces multiple results | ||
* and undefined if there was no output. Else returns single | ||
* result value. | ||
* | ||
* Likewise, once a transducer has produced a final / reduced | ||
* value, all further invocations of the stepper function will | ||
* return undefined. | ||
* | ||
* ``` | ||
* // single result | ||
* step(map(x => x * 10))(1); | ||
* // 10 | ||
* | ||
* // multiple results | ||
* step(mapcat(x => [x, x + 1, x + 2]))(1) | ||
* // [ 1, 2, 3 ] | ||
* | ||
* // no result | ||
* f = step(filter(even)) | ||
* f(1); // undefined | ||
* f(2); // 2 | ||
* | ||
* // reduced value termination | ||
* f = step(take(2)); | ||
* f(1); // 1 | ||
* f(1); // 1 | ||
* f(1); // undefined | ||
* f(1); // undefined | ||
* ``` | ||
* | ||
* @param tx | ||
*/ | ||
function step(tx) { | ||
const rfn = tx(last_1.last())[2]; | ||
return (x) => rfn(undefined, x); | ||
const [_, complete, reduce] = tx(push_1.push()); | ||
_; | ||
let done = false; | ||
return (x) => { | ||
if (!done) { | ||
let acc = reduce([], x); | ||
done = index_1.isReduced(acc); | ||
if (done) { | ||
acc = complete(acc.deref()); | ||
} | ||
return acc.length === 1 ? | ||
acc[0] : | ||
acc.length > 0 ? | ||
acc : | ||
undefined; | ||
} | ||
}; | ||
} | ||
exports.step = step; |
@@ -1,2 +0,2 @@ | ||
const tx = require("../build"); | ||
const tx = require("../"); | ||
@@ -15,3 +15,3 @@ console.log( | ||
tx.transduce(tx.bits(), tx.push(), [0xaa]) | ||
tx.reduce(tx.every(tx.even), tx.range(10)) | ||
); |
import { Transducer } from "../api"; | ||
export declare function cat<T>(): Transducer<T[], T>; | ||
export declare function cat<T>(): Transducer<Iterable<T>, T>; |
import { Transducer } from "../api"; | ||
/** | ||
* Yields transducer which wraps incoming values in promises, which | ||
* resolve after specified delay time (in ms). | ||
* | ||
* **Only to be used in async contexts and NOT with `transduce` directly.** | ||
* | ||
* @param t | ||
*/ | ||
export declare function delayed<T>(t: number): Transducer<T, Promise<T>>; |
@@ -5,2 +5,10 @@ "use strict"; | ||
const delay_1 = require("../func/delay"); | ||
/** | ||
* Yields transducer which wraps incoming values in promises, which | ||
* resolve after specified delay time (in ms). | ||
* | ||
* **Only to be used in async contexts and NOT with `transduce` directly.** | ||
* | ||
* @param t | ||
*/ | ||
function delayed(t) { | ||
@@ -7,0 +15,0 @@ return map_1.map((x) => delay_1.delay(x, t)); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const comp_1 = require("../func/comp"); | ||
const throttle_1 = require("./throttle"); | ||
function dropNth(n) { | ||
n--; | ||
return (rfn) => { | ||
const r = rfn[2]; | ||
n = Math.max(0, n - 1); | ||
return throttle_1.throttle(() => { | ||
let skip = n; | ||
return comp_1.compR(rfn, (acc, x) => skip-- > 0 ? r(acc, x) : (skip = n, acc)); | ||
}; | ||
return () => skip-- > 0 ? true : (skip = n, false); | ||
}); | ||
} | ||
exports.dropNth = dropNth; |
import { Reducer, Transducer } from "../api"; | ||
export declare function scan<A, B>(inner: Reducer<B, A>, acc?: B): Transducer<A, B>; | ||
export declare function scan<A, B>([initi, completei, reducei]: Reducer<B, A>): Transducer<A, B>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const comp_1 = require("../func/comp"); | ||
const reduced_1 = require("../reduced"); | ||
function scan(inner, acc) { | ||
return (outer) => { | ||
acc = acc || inner[0](); | ||
const ri = inner[2], ro = outer[2]; | ||
return comp_1.compR(outer, (_acc, x) => { | ||
acc = ri(acc, x); | ||
if (reduced_1.isReduced(acc)) { | ||
return reduced_1.ensureReduced(ro(_acc, acc.deref())); | ||
function scan([initi, completei, reducei]) { | ||
return ([inito, completeo, reduceo]) => { | ||
let acc = initi(); | ||
return [ | ||
inito, | ||
(_acc) => { | ||
let a = completei(acc); | ||
if (a !== acc) { | ||
_acc = reduced_1.unreduced(reduceo(_acc, a)); | ||
} | ||
acc = a; | ||
return completeo(_acc); | ||
}, | ||
(_acc, x) => { | ||
acc = reducei(acc, x); | ||
if (reduced_1.isReduced(acc)) { | ||
return reduced_1.ensureReduced(reduceo(_acc, acc.deref())); | ||
} | ||
return reduceo(_acc, acc); | ||
} | ||
return ro(_acc, acc); | ||
}); | ||
]; | ||
}; | ||
} | ||
exports.scan = scan; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const comp_1 = require("../func/comp"); | ||
const throttle_1 = require("./throttle"); | ||
function takeNth(n) { | ||
n--; | ||
return (rfn) => { | ||
const r = rfn[2]; | ||
n = Math.max(0, n - 1); | ||
return throttle_1.throttle(() => { | ||
let skip = 0; | ||
return comp_1.compR(rfn, (acc, x) => { | ||
if (skip === 0) { | ||
skip = n; | ||
return r(acc, x); | ||
} | ||
skip--; | ||
return acc; | ||
}); | ||
}; | ||
return () => (skip === 0 ? (skip = n, true) : (skip--, false)); | ||
}); | ||
} | ||
exports.takeNth = takeNth; |
@@ -0,2 +1,18 @@ | ||
import { StatefulPredicate } from "@thi.ng/api/api"; | ||
import { Transducer } from "../api"; | ||
export declare function throttle<T>(delay: number): Transducer<T, T>; | ||
/** | ||
* Similar to `filter`, but works with possibly stateful predicates | ||
* to achieve rate limiting capabilities. Emits only values when | ||
* predicate returns a truthy value. | ||
* | ||
* To support multiple instances of stateful predicates, the predicate | ||
* itself must be wrapped in a no-arg function, which is called when | ||
* the transducer initializes. Any stateful initialization of the | ||
* predicate MUST be done in this function and the function MUST | ||
* return a 1-arg function, the actual predicate applied to each value. | ||
* | ||
* Also see: `throttleTime()`. | ||
* | ||
* @param pred | ||
*/ | ||
export declare function throttle<T>(pred: StatefulPredicate<T>): Transducer<T, T>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const comp_1 = require("../func/comp"); | ||
function throttle(delay) { | ||
/** | ||
* Similar to `filter`, but works with possibly stateful predicates | ||
* to achieve rate limiting capabilities. Emits only values when | ||
* predicate returns a truthy value. | ||
* | ||
* To support multiple instances of stateful predicates, the predicate | ||
* itself must be wrapped in a no-arg function, which is called when | ||
* the transducer initializes. Any stateful initialization of the | ||
* predicate MUST be done in this function and the function MUST | ||
* return a 1-arg function, the actual predicate applied to each value. | ||
* | ||
* Also see: `throttleTime()`. | ||
* | ||
* @param pred | ||
*/ | ||
function throttle(pred) { | ||
return (rfn) => { | ||
const r = rfn[2]; | ||
let last = 0; | ||
return comp_1.compR(rfn, (acc, x) => { | ||
const t = Date.now(); | ||
if (t - last >= delay) { | ||
last = t; | ||
acc = r(acc, x); | ||
} | ||
return acc; | ||
}); | ||
const _pred = pred(); | ||
return comp_1.compR(rfn, (acc, x) => _pred(x) ? r(acc, x) : acc); | ||
}; | ||
} | ||
exports.throttle = throttle; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
135832
1
217
2913
1
719
- Removed@thi.ng/checks@^1.1.1
Updated@thi.ng/api@^1.3.0