Skip to content

Split multicast, publish, et al into static functions and operators? #3833

@benlesh

Description

@benlesh

Given that composition of ConnectableObservable isn't something TypeScript is capable of, and given that ConnectableObservable is just a little different, it's probably worth discussing having the functions that return ConnectableObservable be static, and their projected counterparts stay as operators.

This is likely something we could not do until the next major version.

Problems

  • ConnectableObservable doesn't compose through pipe very well in typed languages.
  • It's not readily obvious that you're doing something different with these operators, and people don't know you need to connect them at times.
  • Two very different results between publish and publish(fn), for example.

Static Functions

function multicast<T>(source: Observable<T>, subject: Subject<T>): ConnectableObservable<T>;
function multicast<T>(source: Observable<T>, subjectFactory: () => Subject<T>): ConnectableObservable<T>;

function publish<T>(source: Observable<T>): ConnectableObservable<T>;
function publishLast<T>(source: Observable<T>): ConnectableObservable<T>;
function publishBehavior<T>(source: Observable<T>, initialValue: T): ConnectableObservable<T>;
function publishReplay<T>(source: Observable<T>, bufferSize?: number, bufferTime?: number): ConnectableObservable<T>;

Operator Functions

(bike shed names later)

function multicastWith<T, R>(subject: Subject<T>, project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;
function multicastWith<T, R>(subjectFactory: () => Subject<T>, project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;

function publishWith<T, R>(project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;
function publishLastWith<T, R>(project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;
function publishBehaviorWith<T, R>(initialValue: T, project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;
function publishReplayWith<T, R>(bufferSize: number, bufferTime: number, project: (source: Observable<T>) => Observable<R>): OperatorFunction<T, R>;

Risks

  • Larger API surface area
  • We'll need to support refactoring for these cases in the migration process for the next version

Benefits

  • Easier to understand than the current variadic operators, who behave very differently given different arguments.
  • Easier to read (subjective, I suppose)

Other things

I don't think all variations shown above actually exist. We can probably get away with just the multicastWith and publishWith variants of the operators.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions