Skip to content

Commit

Permalink
AsyncIterable support (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
szilanor authored Jul 27, 2024
1 parent a30886b commit 99358ce
Show file tree
Hide file tree
Showing 303 changed files with 12,529 additions and 18,253 deletions.
10 changes: 0 additions & 10 deletions .babelrc

This file was deleted.

4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
build/
docs/
node_modules/
dist/
coverage/
.github/
6 changes: 6 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
root: true,
};
3 changes: 0 additions & 3 deletions .eslintrc.json

This file was deleted.

84 changes: 0 additions & 84 deletions .github/workflows/ci.yml

This file was deleted.

33 changes: 33 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Lint and test

on:
pull_request:

permissions:
id-token: write
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: |
npm ci --ignore-scripts
- name: Lint code
run: |
npm run lint
- name: Run tests
run: |
npm test
57 changes: 57 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Publish

on:
workflow_dispatch:
inputs:
version:
type: choice
options:
- major
- minor
- patch

permissions:
contents: write

jobs:
build:
environment: npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: |
npm ci --ignore-scripts
- name: Build
run: |
npm run build
- name: Update version and docs
run: |
git reset --hard
git config --local --list
git checkout main
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
npm version ${{ inputs.version }}
npm run docs
git add . || true
git commit -m "Update package version and docs" || true
git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY" -f
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

- name: Publish
run: |
npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/.pnp
.pnp.js
/build
dist

/.idea/

Expand Down
4 changes: 0 additions & 4 deletions .husky/pre-commit

This file was deleted.

3 changes: 0 additions & 3 deletions .prettierrc.js

This file was deleted.

101 changes: 38 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,94 +4,68 @@
![CI Pipeline](https://github.com/szilanor/stream/actions/workflows/ci.yml/badge.svg)
[![donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/donate/?hosted_button_id=PRBMJHJUFYZQL)

Type-safe API for processing Iterable data (Arrays, Sets, Maps, Iterables) similarly to [Java 8 Stream API](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html),
Type-safe API for processing Iterable and AsyncIterable data (Arrays, Sets, Maps) similarly to [Java 8 Stream API](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html),
[LINQ](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/) or [Kotlin Sequences](https://kotlinlang.org/docs/sequences.html).

- [API Docs](https://szilanor.github.io/stream/)
- [Benchmarks](https://github.com/szilanor/stream/blob/main/benchmarks/)

## Classic Javascript solution

```typescript
const result = [1, 2, 3].filter(x => x % 2 === 0).map(x => x * 2);
```

## Stream API solution

Creating a Stream object

```typescript
import {Stream, of, from} from '@szilanor/stream';

let stream: Stream<number>;
stream = new Stream([1, 2, 3]); // With constructor;
stream = of(1, 2, 3); // With the 'of' creator function
stream = from([1, 2, 3]); // With the 'from' creator function
```

Operations on stream entries for the same result

## Classic JS vs Stream API solution
```typescript
import {filter, map, compound} from '@szilanor/stream';

stream = stream.pipe(
filter(x => x % 2 === 0),
map(x => x * 2)
);
```

Process the stream for the same result
// Classic
let result;
result = [1, 2, 3].filter(x => x % 2 === 0).map(x => x * 2);

```typescript
import {toArray} from '@szilanor/stream';

// With a collector
result = stream.collect(toArray());

// Using for..of
let result = [];
for (let entry of stream) {
result.push(entry);
}

// Using spread operator
result = [...stream];
// Stream API
result = stream([1, 2, 3])
.pipe(
filter(x => x % 2 === 0),
map(x => x * 2)
)
.collect(toArray());
```

## Why Stream API?

- Can achieve faster results due to sequential processing
- Can achieve faster results and lower memory usage due to sequential processing.

```typescript
let allEven: boolean;
const input = [1, 2, 3, 4, 5];
const input = [1, 2, 3, .... 10000];
let allOdd: boolean;

// Classic JS maps all the entries first then returns false
allEven = input.map(x => x + 1).every(x => x % 2 === 0);
// Classic JS
allOdd = input
.map(x => x + 1)
.every(x => x % 2 === 1);

// vs Stream API maps only the first element then returns false
allEven = from(input)
// Result: 2, 3, 4 .... 10000 false

// Stream API
allOdd = from(input)
.pipe(map(x => x + 1))
.collect(all(x => x % 2 === 0));
.collect(every(x => x % 2 === 1));

// Result: 2, false
```

- More readable code
- More readable and fewer lines of code

```typescript
import {from, distinct, collect} from '@szilanor/stream';

// Filtering duplicates and group them by whether they are even or odd
const input = [1, 1, 1, 1, 2, 3, 4, 4, 5];
let oddOrEvenWithoutDuplicates: Map<string, number[]>;

// Classic JS
const resultClassic: Map<string, number[]> = new Map<string, number[]>();
Array.from(new Set<number>(input)).forEach(x => {
oddOrEvenWithoutDuplicates = new Map<string, number[]>();
for (let x of new Set<number>(input))
const key = x % 2 === 0 ? 'even' : 'odd';
resultClassic.set(key, [...(resultClassic.get(key) || []), x]);
});
if (resultClassic.has(key)) {
resultClassic.get(key).push(x);
} else {
resultClassic.set(key, [x]);
}
}

// Stream API
const resultStreamApi: Map<string, number[]> = from(input)
oddOrEvenWithoutDuplicates = stream(input)
.pipe(distinct())
.collect(groupBy(x => (x % 2 === 0 ? 'even' : 'odd')));
```
Expand All @@ -112,3 +86,4 @@ const result = of(1, 2, 3)
.pipe(myAwesomeOperation())
.collect(myAwesomeCollector());
```

Loading

0 comments on commit 99358ce

Please sign in to comment.