Add stream support with generators for functional reactive programming - #7
Conversation
Co-authored-by: irony <395843+irony@users.noreply.github.com>
Co-authored-by: irony <395843+irony@users.noreply.github.com>
|
@copilot resolve the conflicts |
- Kept both composable pipes example (from main) and stream processing examples - Reorganized examples as D, E, F sections in README - Updated section numbering (7-11 instead of 8-12) - All 40 tests pass including new composable pipes tests from main
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive stream support to aspipes, enabling functional reactive programming (FRP) patterns with async generators. The implementation allows processing endless event streams and waiting for particular events using composable pipeline operations, successfully merging with existing composable pipes functionality from the main branch.
Key changes:
- Added five new generator-based aspipe functions (
map,filter,take,scan,reduce) for stream processing - Implemented comprehensive testing suite with 15 new tests covering stream operations and FRP patterns
- Created extensive documentation and examples demonstrating mouse event tracking, double-click detection, and system monitoring patterns
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| stream.js | Core stream processing functions with async generator support for FRP |
| stream.test.js | Comprehensive test suite covering all stream functionality and reactive patterns |
| package.json | Updated exports, scripts, and keywords to include stream module support |
| frp-demo.js | Comprehensive FRP demonstration with practical examples |
| examples.js | Five practical examples showing stream capabilities |
| README.md | Enhanced documentation with stream processing sections E and F |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| let result; | ||
| (result = pipe(numbers())) | map(x => x * 2); |
There was a problem hiding this comment.
[nitpick] The assignment within parentheses pattern (result = pipe(...)) is used consistently throughout the test file but creates unnecessary complexity. Consider separating the assignment from the pipe operation for better readability: result = pipe(numbers()); result | map(x => x * 2);
| let result; | ||
| (result = pipe(numbers())) | filter(x => x > 2); |
There was a problem hiding this comment.
[nitpick] Same assignment-in-parentheses pattern as previous comment. This pattern is repeated throughout the entire test file and reduces code clarity.
| if (isFirst && accumulator === undefined) { | ||
| accumulator = item; | ||
| isFirst = false; | ||
| } else { | ||
| accumulator = await Promise.resolve(reducer(accumulator, item)); | ||
| } |
There was a problem hiding this comment.
The logic for handling the first item when initialValue is undefined is duplicated between scan and reduce functions. Consider extracting this into a shared helper function to reduce code duplication.
| if (isFirst && accumulator === undefined) { | ||
| accumulator = item; | ||
| isFirst = false; | ||
| } else { | ||
| accumulator = await Promise.resolve(reducer(accumulator, item)); | ||
| } |
There was a problem hiding this comment.
This is the exact same logic as in the scan function above. The duplication should be addressed by extracting the common pattern.
Overview
This PR adds comprehensive stream support to aspipes, enabling functional reactive programming (FRP) patterns with async generators. Now you can process endless event streams and wait for particular events using composable pipeline operations.
Note: This PR has been merged with the main branch, which includes composable pipes functionality. The merge combines both feature sets seamlessly.
What's New
Stream Processing Functions
Added five new generator-based aspipe functions in
stream.js:map(iterable, fn)- Transform each item in an async generatorfilter(iterable, predicate)- Filter items based on a conditiontake(iterable, n)- Take first n items (essential for endless streams)scan(iterable, reducer, initial)- Accumulate values, yielding intermediate resultsreduce(iterable, reducer, initial)- Reduce stream to a single valueKey Capabilities
Processing Endless Streams:
Mouse Event Tracking:
Double-Click Detection:
Files Added
stream.js- Core stream processing functions and helpersstream.test.js- 15 comprehensive tests covering all stream functionalityexamples.js- 5 practical examples demonstrating stream capabilitiesfrp-demo.js- Comprehensive FRP demonstration with mouse events, double-clicks, and system monitoringFiles Modified
README.md- Merged documentation for both stream processing (sections E, F) and composable pipes (section D from main)index.js- Includes composable pipes support from main branchtest.js- Includes 3 new composable pipes tests from main branchpackage.json- Updated to include stream tests and exportsDocumentation
Updated
README.mdwith extensive documentation including:Testing
All tests pass (40 total):
take()scan()Merge Notes
This PR has been successfully merged with the main branch. The merge resolved conflicts in
README.mdby:index.jswith composable pipes supportCompatibility
pipeandasPipefunctionsaspipes/streamexportThis implementation enables aspipes to be used as a functional reactive programming library, perfect for processing event streams, mouse/keyboard interactions, and any scenario requiring stateful stream transformations. The composable pipes feature from main further enhances reusability and abstraction.
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.