Skip to content

Commit

Permalink
API 1.0 Changes (#31)
Browse files Browse the repository at this point in the history
* New factory API in object-oriented style

* Pipe util, interval source, string stream and tests

Extract pipe function into util/pipe
Fix string stream
More tests
Add Interval source

* map() conformance; first() and last() API changes

Fix map() to conform to AsyncIteratorHelp proposal
Make predicate optional in first() and last()

* Rename AsyncStream -> AsyncIterableStream

* Rename polyfill method asyncStream -> streamAsync

* Moved stream sources to source/

* Decouple sources from AsyncIteratorStream

* Clean up polyfills

* Polyfills are actually factories

* Add Scheduler abstraction to interval source

* Core-js, range tests, sources naming convention

* Polyfill Iterator Helpers for test if necessary

* Rename source to sources

* Fix editor tab size for vscode

* Add Event source

* Fix pipe.close() to notify waiting next()s

* Readable release on iterator end and back-pressure

* Rename readable APIs

* Rename readable files

* AsyncStream -> AsyncIterableStream in comments and related identifiers

* AsyncIterableStream -> AsyncIteratorStream

* ReadableSplit error handling

* Make readableSplit and fromEvent lazy (like rxjs)

* Readable.chunks

* Use Genearator types and start/next/stop pattern

* AsyncGenerator factory from {next, start, stop} functions

* readableLines2 - simpler implementation

* Introducing IteratorStream

* Add sync IteratorHelper protocol

* Move test_cli.ts from src/ to new demos/ folder (not packaged)

* Bug fixes, improvements, reorg

* Hyphenated folder names et al

* Fix comment in unit test
  • Loading branch information
nikolaybotev authored Sep 6, 2024
1 parent 753fd38 commit 53be8ed
Show file tree
Hide file tree
Showing 54 changed files with 2,184 additions and 1,085 deletions.
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "test_cli",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/test_cli.js",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/./**/*.js"]
},
{
"type": "node",
"request": "attach",
"name": "Attach by Process ID",
"processId": "${command:PickProcess}"
}
]
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.rulers": [80]
"editor.rulers": [80],
"editor.tabSize": 2
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
A lazy streams library for functional composition in JavaScript.

```javascript
import "streams/polyfill";
import "streams/factories";

process.stdin
.streamLines()
Expand Down
20 changes: 20 additions & 0 deletions demos/test_cli.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "../factories/index.js";

console.log("Start", process.stdin.readableFlowing);

process.stdin
.lines()
.stream()
.take(2)
.map((s) => s.substring(0, 2).toLocaleLowerCase())
.forEach((s) => console.log(s, process.stdin.readableFlowing))
.then(() => {
console.log("- stdin is", process.stdin.readableFlowing);
process.stdin
.lines()
.stream()
.take(1)
.map((s) => s.toUpperCase())
.forEach((s) => console.log(s, process.stdin.readableFlowing))
.then(() => console.log("End", process.stdin.readableFlowing));
});
8 changes: 8 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
// @ts-check

import eslint from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";

export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
{
linterOptions: {},
languageOptions: {
ecmaVersion: 2023,
globals: {
...globals.node,
},
},
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
Expand Down
70 changes: 63 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "index.js",
"files": [
"**/*.js",
"**/*.d.ts"
"**/*.d.ts",
"!demos/**"
],
"scripts": {
"build": "run-s format:check eslint clean tsc",
Expand Down Expand Up @@ -41,11 +42,14 @@
},
"devDependencies": {
"@eslint/js": "^9.9.1",
"@types/core-js": "^2.5.8",
"@types/eslint__js": "^8.42.3",
"@types/jest": "^29.5.12",
"@types/node": "^22.5.3",
"core-js": "^3.38.1",
"del-cli": "^5.1.0",
"eslint": "^9.9.1",
"globals": "^15.9.0",
"jest": "^29.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",
Expand Down
44 changes: 44 additions & 0 deletions src/async-iterator-stream.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import "./factories";
import { iteratorInterval } from "./sources/interval";
import { logger } from "./behavior.test";

test("some() consumes iterator", async () => {
// See https://github.com/tc39/proposal-iterator-helpers?tab=readme-ov-file#somefn
async function* naturals() {
let i = 0;
while (true) {
yield i;
i += 1;
}
}

const iter = naturals().stream().take(4);

const result1 = await iter.some((v) => v > 1); // true
const result2 = await iter.some((_) => true); // false, iterator is already consumed.

expect(result1).toBe(true);
expect(result2).toBe(false);
});

test("map() concurrent helpers - results are computed concurrently", async () => {
// See https://github.com/tc39/proposal-async-iterator-helpers?tab=readme-ov-file#concurrency
const log = logger();
const gen = [50, 10]
.values()
.streamAsync()
.map((n) =>
iteratorInterval(n)
.stream()
.map((_) => n)
.peek((v) => log(v))
.first(),
);

const result = (await Promise.all([gen.next(), gen.next()])).map(
(x) => x.value,
);

expect(result).toEqual([50, 10]);
expect(log.output).toEqual([10, 50]);
});
Loading

0 comments on commit 53be8ed

Please sign in to comment.