diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:26:46 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:43:56 -0700 |
| commit | e4fa1e69e7ebfb627c7198fd1a9881e9327ec4d4 (patch) | |
| tree | 06284a538a6008eca75051399e47db4e5d50301c /node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts | |
initial commit: scaffolding
Diffstat (limited to 'node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts')
| -rw-r--r-- | node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts b/node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts new file mode 100644 index 0000000..593b937 --- /dev/null +++ b/node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts @@ -0,0 +1,112 @@ +import { Subscriber } from '../Subscriber'; + +/** + * Creates an instance of an `OperatorSubscriber`. + * @param destination The downstream subscriber. + * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any + * error that occurs in this function is caught and sent to the `error` method of this subscriber. + * @param onError Handles errors from the subscription, any errors that occur in this handler are caught + * and send to the `destination` error handler. + * @param onComplete Handles completion notification from the subscription. Any errors that occur in + * this handler are sent to the `destination` error handler. + * @param onFinalize Additional teardown logic here. This will only be called on teardown if the + * subscriber itself is not already closed. This is called after all other teardown logic is executed. + */ +export function createOperatorSubscriber<T>( + destination: Subscriber<any>, + onNext?: (value: T) => void, + onComplete?: () => void, + onError?: (err: any) => void, + onFinalize?: () => void +): Subscriber<T> { + return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize); +} + +/** + * A generic helper for allowing operators to be created with a Subscriber and + * use closures to capture necessary state from the operator function itself. + */ +export class OperatorSubscriber<T> extends Subscriber<T> { + /** + * Creates an instance of an `OperatorSubscriber`. + * @param destination The downstream subscriber. + * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any + * error that occurs in this function is caught and sent to the `error` method of this subscriber. + * @param onError Handles errors from the subscription, any errors that occur in this handler are caught + * and send to the `destination` error handler. + * @param onComplete Handles completion notification from the subscription. Any errors that occur in + * this handler are sent to the `destination` error handler. + * @param onFinalize Additional finalization logic here. This will only be called on finalization if the + * subscriber itself is not already closed. This is called after all other finalization logic is executed. + * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe. + * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription + * to the resulting observable does not actually disconnect from the source if there are active subscriptions + * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!) + */ + constructor( + destination: Subscriber<any>, + onNext?: (value: T) => void, + onComplete?: () => void, + onError?: (err: any) => void, + private onFinalize?: () => void, + private shouldUnsubscribe?: () => boolean + ) { + // It's important - for performance reasons - that all of this class's + // members are initialized and that they are always initialized in the same + // order. This will ensure that all OperatorSubscriber instances have the + // same hidden class in V8. This, in turn, will help keep the number of + // hidden classes involved in property accesses within the base class as + // low as possible. If the number of hidden classes involved exceeds four, + // the property accesses will become megamorphic and performance penalties + // will be incurred - i.e. inline caches won't be used. + // + // The reasons for ensuring all instances have the same hidden class are + // further discussed in this blog post from Benedikt Meurer: + // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/ + super(destination); + this._next = onNext + ? function (this: OperatorSubscriber<T>, value: T) { + try { + onNext(value); + } catch (err) { + destination.error(err); + } + } + : super._next; + this._error = onError + ? function (this: OperatorSubscriber<T>, err: any) { + try { + onError(err); + } catch (err) { + // Send any errors that occur down stream. + destination.error(err); + } finally { + // Ensure finalization. + this.unsubscribe(); + } + } + : super._error; + this._complete = onComplete + ? function (this: OperatorSubscriber<T>) { + try { + onComplete(); + } catch (err) { + // Send any errors that occur down stream. + destination.error(err); + } finally { + // Ensure finalization. + this.unsubscribe(); + } + } + : super._complete; + } + + unsubscribe() { + if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) { + const { closed } = this; + super.unsubscribe(); + // Execute additional teardown if we have any and we didn't already do so. + !closed && this.onFinalize?.(); + } + } +} |
