Create an AsyncIterableIterator from anything while handling back-pressure!
Installations
npm install @n1ru4l/push-pull-async-iterable-iterator
Developer
n1ru4l
Developer Guide
Module System
CommonJS, ESM
Min. Node Version
>=12
Typescript Support
No
Node Version
14.18.2
NPM Version
6.14.15
Statistics
23 Stars
122 Commits
3 Watching
12 Branches
2 Contributors
Updated on 18 Mar 2023
Bundle Size
2.04 kB
Minified
856.00 B
Minified + Gzipped
Languages
TypeScript (97.65%)
JavaScript (1.79%)
Shell (0.55%)
Total Downloads
Cumulative downloads
Total Downloads
38,815,134
Last day
-12.1%
65,414
Compared to previous day
Last week
-6.1%
349,930
Compared to previous week
Last month
33.4%
1,550,657
Compared to previous month
Last year
6.4%
14,586,080
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
No dependencies detected.
@n1ru4l/push-pull-async-iterable-iterator
Create an AsyncIterableIterator from anything (on any modern platform) while handling back-pressure!
1yarn install -E @n1ru4l/push-pull-async-iterable-iterator
Standalone Usage
1import { makePushPullAsyncIterableIterator } from "@n1ru4l/push-pull-async-iterable-iterator"; 2 3const { 4 pushValue, 5 asyncIterableIterator 6} = makePushPullAsyncIterableIterator(); 7pushValue(1); 8pushValue(2); 9pushValue(3); 10 11// prints 1, 2, 3 12for await (const value of asyncIterableIterator) { 13 console.log(value); 14}
Check if something is an AsyncIterable
1import { isAsyncIterable } from "@n1ru4l/push-pull-async-iterable-iterator"; 2 3if (isAsyncIterable(something)) { 4 for await (const value of something) { 5 console.log(value); 6 } 7}
Note: On Safari iOS Symbol.asyncIterator
is not available, therefore all async iterators used must be build using AsyncGenerators.
If a AsyncIterable that is NO AsyncGenerator is passed to isAsyncIterable
on the Safari iOS environment, it will return the value false
.
Wrap a Sink
1import { makeAsyncIterableIteratorFromSink } from "@n1ru4l/push-pull-async-iterable-iterator";
2// let's use some GraphQL client :)
3import { createClient } from "graphql-ws/lib/use/ws";
4
5const client = createClient({
6 url: "ws://localhost:3000/graphql"
7});
8
9const asyncIterableIterator = makeAsyncIterableIteratorFromSink(sink => {
10 const dispose = client.subscribe(
11 {
12 query: "{ hello }"
13 },
14 {
15 next: sink.next,
16 error: sink.error,
17 complete: sink.complete
18 }
19 );
20 return () => dispose();
21});
22
23for await (const value of asyncIterableIterator) {
24 console.log(value);
25}
Apply an AsyncIterableIterator to a sink
1import Observable from "zen-observable"; 2import { 3 makePushPullAsyncIterableIterator, 4 applyAsyncIterableIteratorToSink 5} from "@n1ru4l/push-pull-async-iterable-iterator"; 6 7const { asyncIterableIterator } = makePushPullAsyncIterableIterator(); 8 9const observable = new Observable(sink => { 10 const dispose = applyAsyncIterableIteratorToSink(asyncIterableIterator, sink); 11 // dispose will be called when the observable subscription got destroyed 12 // the dispose call will ensure that the async iterator is completed. 13 return () => dispose(); 14}); 15 16const subscription = observable.subscribe({ 17 next: console.log, 18 complete: () => console.log("done."), 19 error: () => console.log("error.") 20}); 21 22const interval = setInterval(() => { 23 iterator.push("hi"); 24}, 1000); 25 26setTimeout(() => { 27 subscription.unsubscribe(); 28 clearInterval(interval); 29}, 5000);
Put it all together
1import { Observable, RequestParameters, Variables } from "relay-runtime"; 2import { createClient } from "graphql-ws/lib/use/ws"; 3import { 4 makeAsyncIterableFromSink, 5 applyAsyncIterableIteratorToSink 6} from "@n1ru4l/push-pull-async-iterable-iterator"; 7import { createApplyLiveQueryPatch } from "@n1ru4l/graphql-live-query-patch"; 8 9const client = createClient({ 10 url: "ws://localhost:3000/graphql" 11}); 12 13export const execute = (request: RequestParameters, variables: Variables) => { 14 if (!request.text) { 15 throw new Error("Missing document."); 16 } 17 const query = request.text; 18 19 return Observable.create<GraphQLResponse>(sink => { 20 // Create our asyncIterator from a Sink 21 const executionResultIterator = makeAsyncIterableFromSink(wsSink => { 22 const dispose = client.subscribe({ query }, wsSink); 23 return () => dispose(); 24 }); 25 26 const applyLiveQueryPatch = createApplyLiveQueryPatch(); 27 28 // apply some middleware to our asyncIterator 29 const compositeIterator = applyLiveQueryPatch(executionResultIterator); 30 31 // Apply our async iterable to the relay sink 32 // unfortunately relay cannot consume an async iterable right now. 33 const dispose = applyAsyncIterableIteratorToSink(compositeIterator, sink); 34 // dispose will be called by relay when the observable is disposed 35 // the dispose call will ensure that the async iterator is completed. 36 return () => dispose(); 37 }); 38};
Operators
This package also ships a few utilities that make your life easier!
map
Map a source
1import { map } from "@n1ru4l/push-pull-async-iterable-iterator"; 2 3async function* source() { 4 yield 1; 5 yield 2; 6 yield 3; 7} 8 9const square = map((value: number): number => value * value); 10 11for await (const value of square(source())) { 12 console.log(value); 13} 14// logs 1, 4, 9
filter
Filter a source
1import { filter } from "@n1ru4l/push-pull-async-iterable-iterator"; 2 3async function* source() { 4 yield 1; 5 yield 2; 6 yield 3; 7} 8 9const biggerThan1 = filter((value: number): number => value > 1); 10 11for await (const value of biggerThan1(source())) { 12 console.log(value); 13} 14// logs 2, 3
Other helpers
withHandlers
Attach a return and throw handler to a source.
1import { withReturn } from "@n1ru4l/push-pull-async-iterable-iterator"; 2 3async function* source() { 4 yield 1; 5 yield 2; 6 yield 3; 7} 8 9const sourceInstance = source(); 10 11const newSourceWithHandlers = withHandlers( 12 sourceInstance, 13 () => sourceInstance.return(), 14 err => sourceInstance.throw(err) 15); 16 17for await (const value of stream) { 18 // ... 19}
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 0/6 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/main.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/main.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/main.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/release.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/size.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/size.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/size.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/n1ru4l/push-pull-async-iterable-iterator/size.yml/main?enable=pin
- Info: 0 out of 5 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 3 third-party GitHubAction dependencies pinned
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/main.yml:1
- Warn: no topLevel permission defined: .github/workflows/release.yml:1
- Warn: no topLevel permission defined: .github/workflows/size.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'main'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 26 are checked with a SAST tool
Reason
29 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-434g-2637-qmqr
- Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m
- Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw
- Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p
- Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq
- Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488
- Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-84p7-fh9c-6g8h
- Warn: Project is vulnerable to: GHSA-qrpm-p2h7-hrv2
- Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
Score
2.5
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to @n1ru4l/push-pull-async-iterable-iterator
get-iterator
Get the default iterator or async iterator for an iterable or async iterable
iterate-iterator
Iterate any JS iterator. Works robustly in all environments, all versions.
tiny-async-pool
Run multiple promise-returning & async functions with limited concurrency using native ES9
p-each-series
Iterate over promises serially