feat(rxjs): add complete pipeable API experiment - #7628
Draft
benlesh wants to merge 7 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
This is an exploratory Draft PR. It is intentionally available for review and hands-on testing, but it is not yet proposed as the final RxJS 9 release architecture. In particular, the root-import bundle cost described below must be resolved or explicitly accepted.
What this adds
This PR explores a complete functional/pipeable API for the current RxJS Next catalog while retaining the exact-Symbol API for comparison and compatibility evidence.
rx(source, ...functions)for left-to-right composition.*Withnames for the six capabilities that have both static and source-bound forms:combineWith,combineLatestWith,concatWith,mergeWith,onErrorResumeNextWith, andraceWith.AsyncGeneratorresults.rxjs/symbolbarrel and focused paths.rxjs/pipeable,rxjs/static, and focused per-capability paths.The existing
rxjs/map-style deep paths still expose Symbols in this experiment. Moving those established paths to functions is deliberately left as a separate review decision.Basic usage
The functions are also available through the dedicated barrel:
Static functions and
*WithoperatorsStatic creation and source-bound composition use separate names:
Static functions are also available from
rxjs/static; focused forms use paths such asrxjs/static/mergeandrxjs/pipeable/merge-with.AsyncIterable terminals
Async-iteration remains a real composition boundary.
rxreturns the generator directly:iterateBufferedValues,iterateLatestValue, anditerateNextValuefollow the same rule.Why there is no private static-to-pipeable hook
A hook on a static function cannot make
rx(source, merge(other))work: JavaScript evaluatesmerge(other)beforerxreceives its arguments, sorxsees the returned Observable rather than the decorated function. Branding that result would add hidden context-sensitive behavior.The TypeScript prototypes also lost the generic source/output relationship or callback contextual inference when the branded result was threaded through fixed or recursive composition types. Separate
merge/mergeWith-style names preserve both runtime clarity and useful inference.Trying the branch
The most complete design and usage guide is packages/rxjs/docs/PIPEABLE_EXPERIMENT.md. The public overview is also reflected in packages/rxjs/README.md and packages/rxjs/docs/API.md.
Validation
rxjsbuild, declaration, package-import, migration-document, and generated-surface gates passed.Known release blocker: root bundle retention
The complete root currently re-exports facades from modules that also install exact Symbols. Consequently, importing the experimental root retains most of the catalog and the production Webpack fixture emits 64,874 bytes against the unchanged 22,000-byte release ceiling.
That failing budget is intentionally preserved and documented; this PR does not propose increasing it. Focused imports let people test bounded graphs, but the root should not ship in this form unless shared implementations are separated from Symbol installation or the retention cost is explicitly accepted.
Review questions
rxjs/map-style paths eventually switch to functions, with Symbols living underrxjs/symbol/*?rxtransformations plus anunknownfallback the right TypeScript horizon?operate, the Observable-returning terminals, and the lite subscription terminal remain internal/experimental or become public architecture?