reactor-core-ts 3.2.3 → 3.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/core/demand.d.ts +4 -0
  2. package/dist/core/demand.d.ts.map +1 -1
  3. package/dist/core/demand.js +12 -4
  4. package/dist/core/demand.js.map +1 -1
  5. package/dist/internal/iteration-demand.d.ts +18 -0
  6. package/dist/internal/iteration-demand.d.ts.map +1 -0
  7. package/dist/internal/iteration-demand.js +34 -0
  8. package/dist/internal/iteration-demand.js.map +1 -0
  9. package/dist/internal/publisher-terminal.d.ts +25 -0
  10. package/dist/internal/publisher-terminal.d.ts.map +1 -0
  11. package/dist/internal/publisher-terminal.js +128 -0
  12. package/dist/internal/publisher-terminal.js.map +1 -0
  13. package/dist/publisher/flux.d.ts.map +1 -1
  14. package/dist/publisher/flux.js +22 -12
  15. package/dist/publisher/flux.js.map +1 -1
  16. package/dist/publisher/mono.d.ts.map +1 -1
  17. package/dist/publisher/mono.js +2 -1
  18. package/dist/publisher/mono.js.map +1 -1
  19. package/dist/publisher/operators/aggregate.d.ts.map +1 -1
  20. package/dist/publisher/operators/aggregate.js +136 -143
  21. package/dist/publisher/operators/aggregate.js.map +1 -1
  22. package/dist/publisher/operators/buffer-lift.d.ts +5 -0
  23. package/dist/publisher/operators/buffer-lift.d.ts.map +1 -0
  24. package/dist/publisher/operators/buffer-lift.js +197 -0
  25. package/dist/publisher/operators/buffer-lift.js.map +1 -0
  26. package/dist/publisher/operators/compat/flux.d.ts.map +1 -1
  27. package/dist/publisher/operators/compat/flux.js +86 -35
  28. package/dist/publisher/operators/compat/flux.js.map +1 -1
  29. package/dist/publisher/operators/coordination.d.ts.map +1 -1
  30. package/dist/publisher/operators/coordination.js +3 -4
  31. package/dist/publisher/operators/coordination.js.map +1 -1
  32. package/dist/publisher/operators/lifecycle.d.ts.map +1 -1
  33. package/dist/publisher/operators/lifecycle.js +64 -21
  34. package/dist/publisher/operators/lifecycle.js.map +1 -1
  35. package/dist/publisher/operators/lift.d.ts +2 -0
  36. package/dist/publisher/operators/lift.d.ts.map +1 -1
  37. package/dist/publisher/operators/lift.js +173 -3
  38. package/dist/publisher/operators/lift.js.map +1 -1
  39. package/dist/publisher/operators/selection.d.ts.map +1 -1
  40. package/dist/publisher/operators/selection.js +3 -2
  41. package/dist/publisher/operators/selection.js.map +1 -1
  42. package/dist/publisher/operators/terminal-mono.d.ts +12 -0
  43. package/dist/publisher/operators/terminal-mono.d.ts.map +1 -0
  44. package/dist/publisher/operators/terminal-mono.js +244 -0
  45. package/dist/publisher/operators/terminal-mono.js.map +1 -0
  46. package/dist/publisher/operators/terminal.d.ts.map +1 -1
  47. package/dist/publisher/operators/terminal.js +12 -25
  48. package/dist/publisher/operators/terminal.js.map +1 -1
  49. package/dist/publisher/operators/time.d.ts.map +1 -1
  50. package/dist/publisher/operators/time.js +2 -0
  51. package/dist/publisher/operators/time.js.map +1 -1
  52. package/dist/subscription/iterable-subscription.d.ts.map +1 -1
  53. package/dist/subscription/iterable-subscription.js +5 -2
  54. package/dist/subscription/iterable-subscription.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/internal/iterable-terminal.d.ts +0 -12
  57. package/dist/internal/iterable-terminal.d.ts.map +0 -1
  58. package/dist/internal/iterable-terminal.js +0 -49
  59. package/dist/internal/iterable-terminal.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"lift.js","names":[],"sources":["../../../src/publisher/operators/lift.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Internal subscriber-lifting primitives for demand-preserving Flux operators.\n */\nimport {Context} from \"@/context/context.js\";\nimport {addCap} from \"@/core/demand.js\";\nimport type {SourceFactory} from \"@/publisher/types.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport type {CoreSubscriber} from \"@/subscription/core-subscriber.js\";\nimport type {Subscriber} from \"@/subscription/subscriber.js\";\nimport type {Subscription} from \"@/subscription/subscription.js\";\n\n/** Creates the subscriber that an upstream Flux sees for a downstream subscriber. */\nexport type SubscriberLifter<T, R> = (subscriber: Subscriber<R>) => Subscriber<T>;\n\n/** Hooks used by synchronous one-input/one-output operators. */\nexport interface OneToOneOperatorHooks<T, R> {\n /** Converts one upstream value into exactly one downstream value. */\n onNext(value: T): R;\n\n /** Runs before the downstream receives its subscription. */\n onSubscribe?(subscription: Subscription): void;\n\n /** Runs before an upstream error is forwarded. */\n onError?(error: unknown): void;\n\n /** Runs before downstream demand is forwarded upstream. */\n onRequest?(request: number): void;\n\n /** Runs before successful completion is forwarded. */\n onComplete?(): void;\n\n /** Runs when downstream cancellation is propagated upstream. */\n onCancel?(): void;\n\n /** Runs after the terminal signal or cancellation has been propagated. */\n onFinally?(signal: \"complete\" | \"error\" | \"cancel\"): void;\n\n /** Context exposed to the upstream subscriber. */\n currentContext?(): Context;\n}\n\n/**\n * Lifts a Flux at the Reactive Streams subscriber boundary while keeping an\n * iterable implementation for explicit async-iterator consumption.\n */\nexport function liftFlux<T, R>(\n source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n lifter: SubscriberLifter<T, R>\n): Flux<R> {\n return new LiftedFlux(source, sourceFactory, lifter);\n}\n\n/** Creates a one-to-one operator that forwards downstream demand unchanged. */\nexport function liftOneToOne<T, R>(\n source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n hooksFactory: (subscriber: Subscriber<R>) => OneToOneOperatorHooks<T, R>\n): Flux<R> {\n return liftFlux(source, sourceFactory, subscriber =>\n new OneToOneOperatorSubscriber(subscriber, hooksFactory(subscriber))\n );\n}\n\n/** Creates a filtering operator that replenishes only values dropped from finite demand. */\nexport function liftFilter<T>(\n source: Flux<T>,\n sourceFactory: SourceFactory<T>,\n predicate: (value: T) => boolean\n): Flux<T> {\n return liftFlux(source, sourceFactory, subscriber => new FilterOperatorSubscriber(subscriber, predicate));\n}\n\n/** Returns the context exposed by a subscriber, or the shared empty context. */\nexport function subscriberContext<T>(subscriber: Subscriber<T>): Context {\n return (subscriber as CoreSubscriber<T>).currentContext?.() ?? Context.empty();\n}\n\n/** Flux whose normal subscribe path is assembled through a subscriber lifter. */\nclass LiftedFlux<T, R> extends Flux<R> {\n /** Creates a lifted Flux around an upstream source. */\n public constructor(\n private readonly source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n private readonly lifter: SubscriberLifter<T, R>\n ) {\n super(sourceFactory);\n }\n\n /** Subscribes without crossing the async-iterator bridge. */\n protected override subscribeActual(subscriber: Subscriber<R>): void {\n let upstreamSubscriber: Subscriber<T>;\n try {\n upstreamSubscriber = this.lifter(subscriber);\n } catch (error) {\n signalAssemblyError(subscriber, error);\n return;\n }\n this.source.subscribe(upstreamSubscriber);\n }\n}\n\n/** Subscription/subscriber pair shared by synchronous one-to-one operators. */\nclass OneToOneOperatorSubscriber<T, R> implements CoreSubscriber<T>, Subscription {\n /** Upstream subscription received during the Reactive Streams handshake. */\n private upstream: Subscription | undefined;\n /** Prevents duplicate subscriptions from replacing the active upstream. */\n private subscribed = false;\n /** Suppresses signals and demand after cancellation or termination. */\n private terminated = false;\n\n /** Creates a one-to-one operator subscriber. */\n public constructor(\n private readonly actual: Subscriber<R>,\n private readonly hooks: OneToOneOperatorHooks<T, R>\n ) {\n }\n\n /** Installs the upstream subscription and exposes this forwarding subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n subscription.cancel();\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n\n try {\n this.hooks.onSubscribe?.(subscription);\n } catch (error) {\n this.terminated = true;\n cancelSilently(subscription);\n this.actual.onSubscribe(this);\n this.signalError(error);\n return;\n }\n\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n try {\n subscription.cancel();\n } finally {\n this.runFinally(\"cancel\");\n }\n throw error;\n }\n }\n\n /** Converts and forwards one upstream value without changing demand. */\n public onNext(value: T): void {\n if (this.terminated) {\n return;\n }\n let mapped: R;\n try {\n mapped = this.hooks.onNext(value);\n } catch (error) {\n this.terminateWithError(error, true);\n return;\n }\n this.actual.onNext(mapped);\n }\n\n /** Forwards an upstream error after running the operator callback. */\n public onError(error: unknown): void {\n this.terminateWithError(error, false);\n }\n\n /** Forwards successful completion after running the operator callback. */\n public onComplete(): void {\n if (this.terminated) {\n return;\n }\n try {\n this.hooks.onComplete?.();\n } catch (error) {\n this.terminateWithError(error, false);\n return;\n }\n this.terminated = true;\n try {\n this.actual.onComplete();\n } finally {\n this.runFinally(\"complete\");\n }\n }\n\n /** Forwards exactly the requested amount to upstream. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n try {\n this.hooks.onRequest?.(n);\n } catch (error) {\n this.terminateWithError(error, true);\n return;\n }\n this.upstream?.request(n);\n }\n\n /** Cancels upstream once and reports the cancellation lifecycle hooks. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n try {\n this.upstream?.cancel();\n } finally {\n try {\n this.hooks.onCancel?.();\n } finally {\n this.runFinally(\"cancel\");\n }\n }\n }\n\n /** Exposes downstream context to context-aware upstream publishers. */\n public currentContext(): Context {\n return this.hooks.currentContext?.() ?? subscriberContext(this.actual);\n }\n\n /** Cancels when needed and emits one downstream error signal. */\n private terminateWithError(error: unknown, cancelUpstream: boolean): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n if (cancelUpstream && this.upstream) {\n cancelSilently(this.upstream);\n }\n let failure = error;\n try {\n this.hooks.onError?.(error);\n } catch (callbackError) {\n failure = callbackError;\n }\n this.signalError(failure);\n }\n\n /** Delivers an error followed by the final error callback. */\n private signalError(error: unknown): void {\n try {\n this.actual.onError(error);\n } finally {\n this.runFinally(\"error\");\n }\n }\n\n /** Runs a final callback without letting observer code alter terminal semantics. */\n private runFinally(signal: \"complete\" | \"error\" | \"cancel\"): void {\n try {\n this.hooks.onFinally?.(signal);\n } catch {\n // Final observers run after propagation and cannot replace the terminal signal.\n }\n }\n}\n\n/** Filtering subscriber with stack-safe compensation for dropped values. */\nclass FilterOperatorSubscriber<T> implements CoreSubscriber<T>, Subscription {\n /** Upstream subscription received during the Reactive Streams handshake. */\n private upstream: Subscription | undefined;\n /** Prevents duplicate subscriptions from replacing the active upstream. */\n private subscribed = false;\n /** Suppresses signals and demand after cancellation or termination. */\n private terminated = false;\n /** Avoids compensation requests after downstream switches to unbounded demand. */\n private unbounded = false;\n /** Guards synchronous request calls against reentrant compensation. */\n private requesting = false;\n /** Compensation or downstream demand accumulated during an active request call. */\n private missedRequested = 0;\n\n /** Creates a filtering subscriber. */\n public constructor(\n private readonly actual: Subscriber<T>,\n private readonly predicate: (value: T) => boolean\n ) {\n }\n\n /** Installs upstream and exposes the demand-forwarding subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n subscription.cancel();\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n subscription.cancel();\n throw error;\n }\n }\n\n /** Tests one value, forwarding matches and replenishing finite demand for drops. */\n public onNext(value: T): void {\n if (this.terminated) {\n return;\n }\n let accepted: boolean;\n try {\n accepted = this.predicate(value);\n } catch (error) {\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onError(error);\n return;\n }\n if (accepted) {\n this.actual.onNext(value);\n } else if (!this.unbounded) {\n this.requestUpstream(1);\n }\n }\n\n /** Forwards one terminal error. */\n public onError(error: unknown): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onError(error);\n }\n\n /** Forwards successful completion once. */\n public onComplete(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onComplete();\n }\n\n /** Forwards demand and records when no further compensation is necessary. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n if (n === Number.POSITIVE_INFINITY) {\n this.unbounded = true;\n }\n this.requestUpstream(n);\n }\n\n /** Cancels the upstream once. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.upstream?.cancel();\n }\n\n /** Exposes the downstream context unchanged. */\n public currentContext(): Context {\n return subscriberContext(this.actual);\n }\n\n /** Drains demand iteratively so synchronous sources cannot recurse through dropped values. */\n private requestUpstream(n: number): void {\n if (this.requesting) {\n this.missedRequested = addCap(this.missedRequested, n);\n return;\n }\n const upstream = this.upstream;\n if (!upstream) {\n return;\n }\n this.requesting = true;\n let request = n;\n try {\n while (!this.terminated) {\n upstream.request(request);\n if (this.terminated || this.missedRequested === 0) {\n return;\n }\n request = this.missedRequested;\n this.missedRequested = 0;\n }\n } finally {\n this.requesting = false;\n }\n }\n}\n\n/** Signals a lifter assembly failure through a valid Reactive Streams handshake. */\nfunction signalAssemblyError<T>(subscriber: Subscriber<T>, error: unknown): void {\n subscriber.onSubscribe(EMPTY_SUBSCRIPTION);\n subscriber.onError(error);\n}\n\n/** Cancels an upstream while preserving the original operator failure. */\nfunction cancelSilently(subscription: Subscription): void {\n try {\n subscription.cancel();\n } catch {\n // The operator failure remains the terminal signal.\n }\n}\n\n/** Shared inert subscription used only when operator assembly fails. */\nconst EMPTY_SUBSCRIPTION: Subscription = Object.freeze({\n /** Ignores requests because the sequence has already failed. */\n request() {\n // no-op\n },\n /** Ignores cancellation because no upstream was subscribed. */\n cancel() {\n // no-op\n }\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"lift.js","names":[],"sources":["../../../src/publisher/operators/lift.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Internal subscriber-lifting primitives for demand-preserving Flux operators.\n */\nimport {Context} from \"@/context/context.js\";\nimport {addCap, normalizeRequest, UNBOUNDED_DEMAND} from \"@/core/demand.js\";\nimport {ITERATION_DEMAND_HINT, iterationDemandHint} from \"@/internal/iteration-demand.js\";\nimport type {SourceFactory} from \"@/publisher/types.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport type {CoreSubscriber} from \"@/subscription/core-subscriber.js\";\nimport type {Subscriber} from \"@/subscription/subscriber.js\";\nimport type {Subscription} from \"@/subscription/subscription.js\";\n\n/** Creates the subscriber that an upstream Flux sees for a downstream subscriber. */\nexport type SubscriberLifter<T, R> = (subscriber: Subscriber<R>) => Subscriber<T>;\n\n/** Hooks used by synchronous one-input/one-output operators. */\nexport interface OneToOneOperatorHooks<T, R> {\n /** Converts one upstream value into exactly one downstream value. */\n onNext(value: T): R;\n\n /** Runs before the downstream receives its subscription. */\n onSubscribe?(subscription: Subscription): void;\n\n /** Runs before an upstream error is forwarded. */\n onError?(error: unknown): void;\n\n /** Runs before downstream demand is forwarded upstream. */\n onRequest?(request: number): void;\n\n /** Runs before successful completion is forwarded. */\n onComplete?(): void;\n\n /** Runs when downstream cancellation is propagated upstream. */\n onCancel?(): void;\n\n /** Runs after the terminal signal or cancellation has been propagated. */\n onFinally?(signal: \"complete\" | \"error\" | \"cancel\"): void;\n\n /** Context exposed to the upstream subscriber. */\n currentContext?(): Context;\n}\n\n/**\n * Lifts a Flux at the Reactive Streams subscriber boundary while keeping an\n * iterable implementation for explicit async-iterator consumption.\n */\nexport function liftFlux<T, R>(\n source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n lifter: SubscriberLifter<T, R>\n): Flux<R> {\n return new LiftedFlux(source, sourceFactory, lifter);\n}\n\n/** Creates a one-to-one operator that forwards downstream demand unchanged. */\nexport function liftOneToOne<T, R>(\n source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n hooksFactory: (subscriber: Subscriber<R>) => OneToOneOperatorHooks<T, R>\n): Flux<R> {\n return liftFlux(source, sourceFactory, subscriber =>\n new OneToOneOperatorSubscriber(subscriber, hooksFactory(subscriber))\n );\n}\n\n/** Creates a filtering operator that replenishes only values dropped from finite demand. */\nexport function liftFilter<T>(\n source: Flux<T>,\n sourceFactory: SourceFactory<T>,\n predicate: (value: T) => boolean\n): Flux<T> {\n return liftFlux(source, sourceFactory, subscriber => new FilterOperatorSubscriber(subscriber, predicate));\n}\n\n/** Creates a limiting operator that never requests more than its remaining item count. */\nexport function liftTake<T>(source: Flux<T>, sourceFactory: SourceFactory<T>, count: number): Flux<T> {\n return liftFlux(source, sourceFactory, subscriber => new TakeOperatorSubscriber(subscriber, count));\n}\n\n/** Returns the context exposed by a subscriber, or the shared empty context. */\nexport function subscriberContext<T>(subscriber: Subscriber<T>): Context {\n return (subscriber as CoreSubscriber<T>).currentContext?.() ?? Context.empty();\n}\n\n/** Flux whose normal subscribe path is assembled through a subscriber lifter. */\nclass LiftedFlux<T, R> extends Flux<R> {\n /** Creates a lifted Flux around an upstream source. */\n public constructor(\n private readonly source: Flux<T>,\n sourceFactory: SourceFactory<R>,\n private readonly lifter: SubscriberLifter<T, R>\n ) {\n super(sourceFactory);\n }\n\n /** Subscribes without crossing the async-iterator bridge. */\n protected override subscribeActual(subscriber: Subscriber<R>): void {\n let upstreamSubscriber: Subscriber<T>;\n try {\n upstreamSubscriber = this.lifter(subscriber);\n } catch (error) {\n signalAssemblyError(subscriber, error);\n return;\n }\n this.source.subscribe(upstreamSubscriber);\n }\n}\n\n/** Subscription/subscriber pair shared by synchronous one-to-one operators. */\nclass OneToOneOperatorSubscriber<T, R> implements CoreSubscriber<T>, Subscription {\n /** Upstream subscription received during the Reactive Streams handshake. */\n private upstream: Subscription | undefined;\n /** Prevents duplicate subscriptions from replacing the active upstream. */\n private subscribed = false;\n /** Suppresses signals and demand after cancellation or termination. */\n private terminated = false;\n\n /** Creates a one-to-one operator subscriber. */\n public constructor(\n private readonly actual: Subscriber<R>,\n private readonly hooks: OneToOneOperatorHooks<T, R>\n ) {\n }\n\n /** Installs the upstream subscription and exposes this forwarding subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n subscription.cancel();\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n\n try {\n this.hooks.onSubscribe?.(subscription);\n } catch (error) {\n this.terminated = true;\n cancelSilently(subscription);\n this.actual.onSubscribe(this);\n this.signalError(error);\n return;\n }\n\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n try {\n subscription.cancel();\n } finally {\n this.runFinally(\"cancel\");\n }\n throw error;\n }\n }\n\n /** Converts and forwards one upstream value without changing demand. */\n public onNext(value: T): void {\n if (this.terminated) {\n return;\n }\n let mapped: R;\n try {\n mapped = this.hooks.onNext(value);\n } catch (error) {\n this.terminateWithError(error, true);\n return;\n }\n if (this.terminated) {\n return;\n }\n this.actual.onNext(mapped);\n }\n\n /** Forwards an upstream error after running the operator callback. */\n public onError(error: unknown): void {\n this.terminateWithError(error, false);\n }\n\n /** Forwards successful completion after running the operator callback. */\n public onComplete(): void {\n if (this.terminated) {\n return;\n }\n try {\n this.hooks.onComplete?.();\n } catch (error) {\n this.terminateWithError(error, false);\n return;\n }\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n try {\n this.actual.onComplete();\n } finally {\n this.runFinally(\"complete\");\n }\n }\n\n /** Forwards exactly the requested amount to upstream. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n try {\n this.hooks.onRequest?.(n);\n } catch (error) {\n this.terminateWithError(error, true);\n return;\n }\n if (this.terminated) {\n return;\n }\n this.upstream?.request(n);\n }\n\n /** Cancels upstream once and reports the cancellation lifecycle hooks. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n try {\n this.upstream?.cancel();\n } finally {\n try {\n this.hooks.onCancel?.();\n } finally {\n this.runFinally(\"cancel\");\n }\n }\n }\n\n /** Exposes downstream context to context-aware upstream publishers. */\n public currentContext(): Context {\n return this.hooks.currentContext?.() ?? subscriberContext(this.actual);\n }\n\n /** Propagates a known terminal demand batch through this one-to-one boundary. */\n public [ITERATION_DEMAND_HINT](): number | undefined {\n return iterationDemandHint(this.actual);\n }\n\n /** Cancels when needed and emits one downstream error signal. */\n private terminateWithError(error: unknown, cancelUpstream: boolean): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n if (cancelUpstream && this.upstream) {\n cancelSilently(this.upstream);\n }\n let failure = error;\n try {\n this.hooks.onError?.(error);\n } catch (callbackError) {\n failure = callbackError;\n }\n this.signalError(failure);\n }\n\n /** Delivers an error followed by the final error callback. */\n private signalError(error: unknown): void {\n try {\n this.actual.onError(error);\n } finally {\n this.runFinally(\"error\");\n }\n }\n\n /** Runs a final callback without letting observer code alter terminal semantics. */\n private runFinally(signal: \"complete\" | \"error\" | \"cancel\"): void {\n try {\n this.hooks.onFinally?.(signal);\n } catch {\n // Final observers run after propagation and cannot replace the terminal signal.\n }\n }\n}\n\n/** Filtering subscriber with stack-safe compensation for dropped values. */\nclass FilterOperatorSubscriber<T> implements CoreSubscriber<T>, Subscription {\n /** Upstream subscription received during the Reactive Streams handshake. */\n private upstream: Subscription | undefined;\n /** Prevents duplicate subscriptions from replacing the active upstream. */\n private subscribed = false;\n /** Suppresses signals and demand after cancellation or termination. */\n private terminated = false;\n /** Avoids compensation requests after downstream switches to unbounded demand. */\n private unbounded = false;\n /** Guards synchronous request calls against reentrant compensation. */\n private requesting = false;\n /** Compensation or downstream demand accumulated during an active request call. */\n private missedRequested = 0;\n\n /** Creates a filtering subscriber. */\n public constructor(\n private readonly actual: Subscriber<T>,\n private readonly predicate: (value: T) => boolean\n ) {\n }\n\n /** Installs upstream and exposes the demand-forwarding subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n subscription.cancel();\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n subscription.cancel();\n throw error;\n }\n }\n\n /** Tests one value, forwarding matches and replenishing finite demand for drops. */\n public onNext(value: T): void {\n if (this.terminated) {\n return;\n }\n let accepted: boolean;\n try {\n accepted = this.predicate(value);\n } catch (error) {\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onError(error);\n return;\n }\n if (accepted) {\n this.actual.onNext(value);\n } else if (!this.unbounded) {\n this.requestUpstream(1);\n }\n }\n\n /** Forwards one terminal error. */\n public onError(error: unknown): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onError(error);\n }\n\n /** Forwards successful completion once. */\n public onComplete(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onComplete();\n }\n\n /** Forwards demand and records when no further compensation is necessary. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n if (n === UNBOUNDED_DEMAND) {\n this.unbounded = true;\n }\n this.requestUpstream(n);\n }\n\n /** Cancels the upstream once. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.upstream?.cancel();\n }\n\n /** Exposes the downstream context unchanged. */\n public currentContext(): Context {\n return subscriberContext(this.actual);\n }\n\n /** Propagates a known unbounded terminal batch through this filtering boundary. */\n public [ITERATION_DEMAND_HINT](): number | undefined {\n return iterationDemandHint(this.actual);\n }\n\n /** Drains demand iteratively so synchronous sources cannot recurse through dropped values. */\n private requestUpstream(n: number): void {\n if (this.requesting) {\n this.missedRequested = addCap(this.missedRequested, n);\n return;\n }\n const upstream = this.upstream;\n if (!upstream) {\n return;\n }\n this.requesting = true;\n let request = n;\n try {\n while (!this.terminated) {\n upstream.request(request);\n if (this.terminated || this.missedRequested === 0) {\n return;\n }\n request = this.missedRequested;\n this.missedRequested = 0;\n }\n } finally {\n this.requesting = false;\n }\n }\n}\n\n/** Subscriber that caps cumulative upstream demand and completes after a fixed number of values. */\nclass TakeOperatorSubscriber<T> implements CoreSubscriber<T>, Subscription {\n /** Active upstream subscription. */\n private upstream: Subscription | undefined;\n /** Remaining values before this operator completes. */\n private remaining: number;\n /** Requested upstream values that have not arrived yet. */\n private outstanding = 0;\n /** Guards synchronous upstream request calls against recursive downstream demand. */\n private requesting = false;\n /** Downstream demand accumulated while an upstream request is active. */\n private missedRequested = 0;\n /** Prevents duplicate subscriptions from replacing the active upstream. */\n private subscribed = false;\n /** Suppresses signals after cancellation or termination. */\n private terminated = false;\n\n /** Creates a take subscriber with the provided maximum value count. */\n public constructor(private readonly actual: Subscriber<T>, count: number) {\n this.remaining = count;\n }\n\n /** Stores upstream and exposes the capped subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n cancelSilently(subscription);\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n cancelSilently(subscription);\n throw error;\n }\n }\n\n /** Forwards one value and cancels upstream exactly at the configured limit. */\n public onNext(value: T): void {\n if (this.terminated || this.remaining === 0) {\n return;\n }\n if (this.outstanding > 0) {\n this.outstanding -= 1;\n }\n this.remaining -= 1;\n try {\n this.actual.onNext(value);\n } catch (error) {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onError(error);\n return;\n }\n if (this.remaining === 0 && !this.terminated) {\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onComplete();\n }\n }\n\n /** Forwards the first upstream failure. */\n public onError(error: unknown): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onError(error);\n }\n\n /** Forwards early upstream completion. */\n public onComplete(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onComplete();\n }\n\n /** Requests only demand that still fits below the take limit. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n let demand: number;\n try {\n demand = normalizeRequest(n);\n } catch (error) {\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onError(error);\n return;\n }\n if (this.requesting) {\n this.missedRequested = addCap(this.missedRequested, demand);\n return;\n }\n this.requesting = true;\n let nextDemand = demand;\n try {\n while (!this.terminated) {\n const available = this.remaining - this.outstanding;\n if (available > 0) {\n const request = Math.min(nextDemand, available);\n this.outstanding += request;\n this.upstream?.request(request);\n }\n if (this.terminated || this.missedRequested === 0) {\n return;\n }\n nextDemand = this.missedRequested;\n this.missedRequested = 0;\n }\n } catch (error) {\n if (!this.terminated) {\n this.terminated = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n this.actual.onError(error);\n }\n } finally {\n this.requesting = false;\n }\n }\n\n /** Cancels the active upstream once. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.upstream?.cancel();\n }\n\n /** Exposes the downstream context unchanged. */\n public currentContext(): Context {\n return subscriberContext(this.actual);\n }\n\n /** Propagates downstream demand metadata while `take` still applies its own cap. */\n public [ITERATION_DEMAND_HINT](): number | undefined {\n const downstream = iterationDemandHint(this.actual);\n return downstream === undefined ? undefined : Math.min(downstream, this.remaining);\n }\n}\n\n/** Signals a lifter assembly failure through a valid Reactive Streams handshake. */\nfunction signalAssemblyError<T>(subscriber: Subscriber<T>, error: unknown): void {\n subscriber.onSubscribe(EMPTY_SUBSCRIPTION);\n subscriber.onError(error);\n}\n\n/** Cancels an upstream while preserving the original operator failure. */\nfunction cancelSilently(subscription: Subscription): void {\n try {\n subscription.cancel();\n } catch {\n // The operator failure remains the terminal signal.\n }\n}\n\n/** Shared inert subscription used only when operator assembly fails. */\nconst EMPTY_SUBSCRIPTION: Subscription = Object.freeze({\n /** Ignores requests because the sequence has already failed. */\n request() {\n // no-op\n },\n /** Ignores cancellation because no upstream was subscribed. */\n cancel() {\n // no-op\n }\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/selection.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,QAAQ,qBAAqB,CAAC;IACjC,uDAAuD;IACvD,UAAU,IAAI,CAAC,CAAC;QACZ,iDAAiD;QACjD,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,4EAA4E;QAC5E,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,mFAAmF;QACnF,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,yCAAyC;QACzC,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,2EAA2E;QAC3E,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,wDAAwD;QACxD,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAExD,6EAA6E;QAC7E,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpE;;;WAGG;QACH,wBAAwB,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAExE,qEAAqE;QACrE,cAAc,CAAC,YAAY,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzC,wEAAwE;QACxE,aAAa,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;KACxD;CACJ"}
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/selection.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,QAAQ,qBAAqB,CAAC;IACjC,uDAAuD;IACvD,UAAU,IAAI,CAAC,CAAC;QACZ,iDAAiD;QACjD,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,4EAA4E;QAC5E,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,mFAAmF;QACnF,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,yCAAyC;QACzC,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,2EAA2E;QAC3E,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErD,wDAAwD;QACxD,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAExD,6EAA6E;QAC7E,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpE;;;WAGG;QACH,wBAAwB,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAExE,qEAAqE;QACrE,cAAc,CAAC,YAAY,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzC,wEAAwE;QACxE,aAAa,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;KACxD;CACJ"}
@@ -2,6 +2,7 @@ import { isAsyncIterable, toAsyncIterator } from "../../internal/iterable.js";
2
2
  import { defaultIfEmptyIterable, distinctIterable, distinctUntilChangedIterable, skipIterable, skipWhileIterable, takeUntilIterable, takeWhileIterable } from "../../internal/iterable-transform.js";
3
3
  import { identity } from "../helpers.js";
4
4
  import { Flux } from "../flux.js";
5
+ import { liftTake } from "./lift.js";
5
6
  import { deepEqual, snapshotDeep } from "../../internal/deep-value.js";
6
7
  //#region src/publisher/operators/selection.ts
7
8
  /**
@@ -12,7 +13,7 @@ Flux.prototype.take = function take(n) {
12
13
  if (!Number.isInteger(n) || n < 0) throw new RangeError("take expects a non-negative integer");
13
14
  if (n === 0) return Flux.empty();
14
15
  const source = this;
15
- return new Flux((signal, context) => {
16
+ return liftTake(source, (signal, context) => {
16
17
  const controller = new AbortController();
17
18
  const abort = () => controller.abort(signal.reason);
18
19
  signal.addEventListener("abort", abort, { once: true });
@@ -61,7 +62,7 @@ Flux.prototype.take = function take(n) {
61
62
  if (cancelledSource || signal.aborted) await iterator.return?.();
62
63
  }
63
64
  })();
64
- });
65
+ }, n);
65
66
  };
66
67
  Flux.prototype.takeWhile = function takeWhile(predicate) {
67
68
  const source = this;
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","names":[],"sources":["../../../src/publisher/operators/selection.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Flux, Mono and operator implementation modules.\n */\nimport {deepEqual, snapshotDeep} from \"@/internal/deep-value.js\";\nimport {\n type AnyIterable,\n isAsyncIterable,\n toAsyncIterator\n} from \"@/internal/iterable.js\";\nimport {\n defaultIfEmptyIterable,\n distinctIterable,\n distinctUntilChangedIterable,\n skipIterable,\n skipWhileIterable,\n takeUntilIterable,\n takeWhileIterable\n} from \"@/internal/iterable-transform.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport {identity} from \"@/publisher/helpers.js\";\nimport type {PublisherInput} from \"@/publisher/types.js\";\n\ndeclare module \"@/publisher/flux.js\" {\n /** Selection and filtering operators added to Flux. */\n interface Flux<T> {\n /** Emits at most the first `n` source values. */\n take(n: number): Flux<T>;\n\n /** Emits values while the predicate returns true, then cancels upstream. */\n takeWhile(predicate: (value: T) => boolean): Flux<T>;\n\n /** Emits values until the predicate returns true, including the matching value. */\n takeUntil(predicate: (value: T) => boolean): Flux<T>;\n\n /** Drops the first `n` source values. */\n skip(n: number): Flux<T>;\n\n /** Drops values while the predicate returns true, then relays the rest. */\n skipWhile(predicate: (value: T) => boolean): Flux<T>;\n\n /** Emits only the first value for each selected key. */\n distinct<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /** Drops adjacent values whose selected key is equal to the previous key. */\n distinctUntilChanged<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /**\n * Drops adjacent values with equal nested state. Snapshots arrays, enumerable properties of ordinary objects,\n * and local `Date`, `RegExp`, `Map` and `Set` values; other object types retain identity comparison.\n */\n distinctUntilChangedDeep<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /** Emits `defaultValue` when the source completes without values. */\n defaultIfEmpty(defaultValue: T): Flux<T>;\n\n /** Switches to `alternate` when the source completes without values. */\n switchIfEmpty(alternate: PublisherInput<T>): Flux<T>;\n }\n}\n\nFlux.prototype.take = function take<T>(this: Flux<T>, n: number): Flux<T> {\n if (!Number.isInteger(n) || n < 0) {\n throw new RangeError(\"take expects a non-negative integer\");\n }\n if (n === 0) {\n return Flux.empty<T>();\n }\n const source = this;\n return new Flux((signal, context) => {\n const controller = new AbortController();\n const abort = () => controller.abort(signal.reason);\n signal.addEventListener(\"abort\", abort, {once: true});\n let values: AnyIterable<T>;\n try {\n values = source.iterate(controller.signal, context);\n } catch (error) {\n signal.removeEventListener(\"abort\", abort);\n throw error;\n }\n if (!isAsyncIterable<T>(values)) {\n return (function* () {\n let remaining = n;\n try {\n for (const value of values) {\n yield value;\n remaining -= 1;\n if (remaining === 0) {\n controller.abort();\n return;\n }\n }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n if (signal.aborted && !controller.signal.aborted) {\n controller.abort(signal.reason);\n }\n }\n })();\n }\n return (async function* () {\n const iterator = toAsyncIterator(values);\n let remaining = n;\n let cancelledSource = false;\n try {\n while (!signal.aborted) {\n const result = await iterator.next();\n if (result.done) {\n return;\n }\n yield result.value;\n remaining -= 1;\n if (remaining === 0) {\n cancelledSource = true;\n controller.abort();\n return;\n }\n }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n if (signal.aborted && !controller.signal.aborted) {\n controller.abort(signal.reason);\n }\n if (cancelledSource || signal.aborted) {\n await iterator.return?.();\n }\n }\n })();\n });\n};\n\nFlux.prototype.takeWhile = function takeWhile<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => takeWhileIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.takeUntil = function takeUntil<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => takeUntilIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.skip = function skip<T>(this: Flux<T>, n: number): Flux<T> {\n if (!Number.isInteger(n) || n < 0) {\n throw new RangeError(\"skip expects a non-negative integer\");\n }\n if (n === 0) {\n return this;\n }\n const source = this;\n return new Flux((signal, context) => skipIterable(source.iterate(signal, context), n));\n};\n\nFlux.prototype.skipWhile = function skipWhile<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => skipWhileIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.distinct = function distinct<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctIterable(source.iterate(signal, context), keySelector));\n};\n\nFlux.prototype.distinctUntilChanged = function distinctUntilChanged<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctUntilChangedIterable(source.iterate(signal, context), keySelector));\n};\n\nFlux.prototype.distinctUntilChangedDeep = function distinctUntilChangedDeep<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctUntilChangedIterable(source.iterate(signal, context), keySelector, {\n equals: deepEqual,\n snapshot: snapshotDeep\n }));\n};\n\nFlux.prototype.defaultIfEmpty = function defaultIfEmpty<T>(this: Flux<T>, defaultValue: T): Flux<T> {\n const source = this;\n return new Flux((signal, context) => defaultIfEmptyIterable(source.iterate(signal, context), defaultValue));\n};\n\nFlux.prototype.switchIfEmpty = function switchIfEmpty<T>(this: Flux<T>, alternate: PublisherInput<T>): Flux<T> {\n const source = this;\n return new Flux(async function* (signal, context) {\n let empty = true;\n for await (const value of source.iterate(signal, context)) {\n empty = false;\n yield value;\n }\n if (empty) {\n for await (const value of Flux.from(alternate).iterate(signal, context)) {\n yield value;\n }\n }\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"selection.js","names":[],"sources":["../../../src/publisher/operators/selection.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Flux, Mono and operator implementation modules.\n */\nimport {deepEqual, snapshotDeep} from \"@/internal/deep-value.js\";\nimport {\n type AnyIterable,\n isAsyncIterable,\n toAsyncIterator\n} from \"@/internal/iterable.js\";\nimport {\n defaultIfEmptyIterable,\n distinctIterable,\n distinctUntilChangedIterable,\n skipIterable,\n skipWhileIterable,\n takeUntilIterable,\n takeWhileIterable\n} from \"@/internal/iterable-transform.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport {identity} from \"@/publisher/helpers.js\";\nimport {liftTake} from \"@/publisher/operators/lift.js\";\nimport type {PublisherInput} from \"@/publisher/types.js\";\n\ndeclare module \"@/publisher/flux.js\" {\n /** Selection and filtering operators added to Flux. */\n interface Flux<T> {\n /** Emits at most the first `n` source values. */\n take(n: number): Flux<T>;\n\n /** Emits values while the predicate returns true, then cancels upstream. */\n takeWhile(predicate: (value: T) => boolean): Flux<T>;\n\n /** Emits values until the predicate returns true, including the matching value. */\n takeUntil(predicate: (value: T) => boolean): Flux<T>;\n\n /** Drops the first `n` source values. */\n skip(n: number): Flux<T>;\n\n /** Drops values while the predicate returns true, then relays the rest. */\n skipWhile(predicate: (value: T) => boolean): Flux<T>;\n\n /** Emits only the first value for each selected key. */\n distinct<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /** Drops adjacent values whose selected key is equal to the previous key. */\n distinctUntilChanged<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /**\n * Drops adjacent values with equal nested state. Snapshots arrays, enumerable properties of ordinary objects,\n * and local `Date`, `RegExp`, `Map` and `Set` values; other object types retain identity comparison.\n */\n distinctUntilChangedDeep<K = T>(keySelector?: (value: T) => K): Flux<T>;\n\n /** Emits `defaultValue` when the source completes without values. */\n defaultIfEmpty(defaultValue: T): Flux<T>;\n\n /** Switches to `alternate` when the source completes without values. */\n switchIfEmpty(alternate: PublisherInput<T>): Flux<T>;\n }\n}\n\nFlux.prototype.take = function take<T>(this: Flux<T>, n: number): Flux<T> {\n if (!Number.isInteger(n) || n < 0) {\n throw new RangeError(\"take expects a non-negative integer\");\n }\n if (n === 0) {\n return Flux.empty<T>();\n }\n const source = this;\n return liftTake(source, (signal, context) => {\n const controller = new AbortController();\n const abort = () => controller.abort(signal.reason);\n signal.addEventListener(\"abort\", abort, {once: true});\n let values: AnyIterable<T>;\n try {\n values = source.iterate(controller.signal, context);\n } catch (error) {\n signal.removeEventListener(\"abort\", abort);\n throw error;\n }\n if (!isAsyncIterable<T>(values)) {\n return (function* () {\n let remaining = n;\n try {\n for (const value of values) {\n yield value;\n remaining -= 1;\n if (remaining === 0) {\n controller.abort();\n return;\n }\n }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n if (signal.aborted && !controller.signal.aborted) {\n controller.abort(signal.reason);\n }\n }\n })();\n }\n return (async function* () {\n const iterator = toAsyncIterator(values);\n let remaining = n;\n let cancelledSource = false;\n try {\n while (!signal.aborted) {\n const result = await iterator.next();\n if (result.done) {\n return;\n }\n yield result.value;\n remaining -= 1;\n if (remaining === 0) {\n cancelledSource = true;\n controller.abort();\n return;\n }\n }\n } finally {\n signal.removeEventListener(\"abort\", abort);\n if (signal.aborted && !controller.signal.aborted) {\n controller.abort(signal.reason);\n }\n if (cancelledSource || signal.aborted) {\n await iterator.return?.();\n }\n }\n })();\n }, n);\n};\n\nFlux.prototype.takeWhile = function takeWhile<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => takeWhileIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.takeUntil = function takeUntil<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => takeUntilIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.skip = function skip<T>(this: Flux<T>, n: number): Flux<T> {\n if (!Number.isInteger(n) || n < 0) {\n throw new RangeError(\"skip expects a non-negative integer\");\n }\n if (n === 0) {\n return this;\n }\n const source = this;\n return new Flux((signal, context) => skipIterable(source.iterate(signal, context), n));\n};\n\nFlux.prototype.skipWhile = function skipWhile<T>(this: Flux<T>, predicate: (value: T) => boolean): Flux<T> {\n const source = this;\n return new Flux((signal, context) => skipWhileIterable(source.iterate(signal, context), predicate));\n};\n\nFlux.prototype.distinct = function distinct<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctIterable(source.iterate(signal, context), keySelector));\n};\n\nFlux.prototype.distinctUntilChanged = function distinctUntilChanged<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctUntilChangedIterable(source.iterate(signal, context), keySelector));\n};\n\nFlux.prototype.distinctUntilChangedDeep = function distinctUntilChangedDeep<T, K = T>(\n this: Flux<T>,\n keySelector: (value: T) => K = identity as (value: T) => K\n): Flux<T> {\n const source = this;\n return new Flux((signal, context) => distinctUntilChangedIterable(source.iterate(signal, context), keySelector, {\n equals: deepEqual,\n snapshot: snapshotDeep\n }));\n};\n\nFlux.prototype.defaultIfEmpty = function defaultIfEmpty<T>(this: Flux<T>, defaultValue: T): Flux<T> {\n const source = this;\n return new Flux((signal, context) => defaultIfEmptyIterable(source.iterate(signal, context), defaultValue));\n};\n\nFlux.prototype.switchIfEmpty = function switchIfEmpty<T>(this: Flux<T>, alternate: PublisherInput<T>): Flux<T> {\n const source = this;\n return new Flux(async function* (signal, context) {\n let empty = true;\n for await (const value of source.iterate(signal, context)) {\n empty = false;\n yield value;\n }\n if (empty) {\n for await (const value of Flux.from(alternate).iterate(signal, context)) {\n yield value;\n }\n }\n });\n};\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type TerminalCollector } from "../../internal/publisher-terminal.js";
2
+ import { Flux } from "../flux.js";
3
+ import { Mono } from "../mono.js";
4
+ /** Sentinel returned by a terminal collector when its Mono must complete empty. */
5
+ export declare const NO_TERMINAL_VALUE: unique symbol;
6
+ /** Result produced by a terminal collector, including empty Mono completion. */
7
+ export type TerminalValue<T> = T | typeof NO_TERMINAL_VALUE;
8
+ /** Creates fresh terminal reduction state for each subscription. */
9
+ export type TerminalCollectorFactory<T, R> = () => TerminalCollector<T, TerminalValue<R>>;
10
+ /** Creates a Mono that reduces Publisher signals on the native demand path. */
11
+ export declare function terminalMono<T, R>(source: Flux<T>, upstreamRequest: number, collectorFactory: TerminalCollectorFactory<T, R>): Mono<R>;
12
+ //# sourceMappingURL=terminal-mono.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-mono.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/terminal-mono.ts"],"names":[],"mappings":"AAOA,OAAO,EAAmB,KAAK,iBAAiB,EAAC,MAAM,kCAAkC,CAAC;AAC1F,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAKzC,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D,gFAAgF;AAChF,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,iBAAiB,CAAC;AAE5D,oEAAoE;AACpE,MAAM,MAAM,wBAAwB,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,iBAAiB,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1F,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAC7B,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EACf,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,GACjD,IAAI,CAAC,CAAC,CAAC,CAET"}
@@ -0,0 +1,244 @@
1
+ import _defineProperty from "../../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/defineProperty.js";
2
+ import { Context } from "../../context/context.js";
3
+ import { UNBOUNDED_DEMAND, normalizeRequest } from "../../core/demand.js";
4
+ import { ITERATION_DEMAND_HINT, iterationDemandHint } from "../../internal/iteration-demand.js";
5
+ import { consumePublisher } from "../../internal/publisher-terminal.js";
6
+ import { Mono } from "../mono.js";
7
+ //#region src/publisher/operators/terminal-mono.ts
8
+ /**
9
+ * @packageDocumentation
10
+ * Direct terminal Mono implementation shared by aggregating operators.
11
+ */
12
+ /** Sentinel returned by a terminal collector when its Mono must complete empty. */
13
+ var NO_TERMINAL_VALUE = Symbol("no-terminal-value");
14
+ /** Creates a Mono that reduces Publisher signals on the native demand path. */
15
+ function terminalMono(source, upstreamRequest, collectorFactory) {
16
+ return new DirectTerminalMono(source, upstreamRequest, collectorFactory);
17
+ }
18
+ /** Mono whose subscribe and iteration paths both consume the source directly. */
19
+ var DirectTerminalMono = class extends Mono {
20
+ /** Creates a direct terminal Mono around one source. */
21
+ constructor(source, upstreamRequest, collectorFactory) {
22
+ super(async function* (signal, context) {
23
+ if (signal.aborted) return;
24
+ const result = await consumePublisher(source, signal, context, upstreamRequest, collectorFactory());
25
+ if (result !== NO_TERMINAL_VALUE) yield result;
26
+ });
27
+ _defineProperty(this, "source", void 0);
28
+ _defineProperty(this, "upstreamRequest", void 0);
29
+ _defineProperty(this, "collectorFactory", void 0);
30
+ this.source = source;
31
+ this.upstreamRequest = upstreamRequest;
32
+ this.collectorFactory = collectorFactory;
33
+ }
34
+ /** Installs a subscriber that waits for downstream demand before requesting upstream. */
35
+ subscribeActual(subscriber) {
36
+ new TerminalMonoSubscriber(subscriber, this.upstreamRequest, this.collectorFactory).start(this.source);
37
+ }
38
+ };
39
+ /** Subscriber/subscription pair that reduces a Flux to at most one value. */
40
+ var TerminalMonoSubscriber = class {
41
+ /** Creates a terminal subscriber for one downstream subscriber. */
42
+ constructor(actual, upstreamRequest, collectorFactory) {
43
+ _defineProperty(this, "actual", void 0);
44
+ _defineProperty(this, "upstreamRequest", void 0);
45
+ _defineProperty(this, "collectorFactory", void 0);
46
+ _defineProperty(
47
+ this,
48
+ /** Active upstream subscription. */
49
+ "upstream",
50
+ void 0
51
+ );
52
+ _defineProperty(
53
+ this,
54
+ /** Collector created lazily on the first valid downstream request. */
55
+ "collector",
56
+ void 0
57
+ );
58
+ _defineProperty(
59
+ this,
60
+ /** Tracks the upstream Reactive Streams handshake. */
61
+ "subscribed",
62
+ false
63
+ );
64
+ _defineProperty(
65
+ this,
66
+ /** Ensures upstream is requested at most once. */
67
+ "requested",
68
+ false
69
+ );
70
+ _defineProperty(
71
+ this,
72
+ /** Records completion that arrived before downstream demand. */
73
+ "completedBeforeRequest",
74
+ false
75
+ );
76
+ _defineProperty(
77
+ this,
78
+ /** Guards the downstream result callback against reentrant upstream signals. */
79
+ "emitting",
80
+ false
81
+ );
82
+ _defineProperty(
83
+ this,
84
+ /** Ensures the active upstream is cancelled at most once. */
85
+ "upstreamCancelled",
86
+ false
87
+ );
88
+ _defineProperty(
89
+ this,
90
+ /** Suppresses signals after cancellation or termination. */
91
+ "terminated",
92
+ false
93
+ );
94
+ this.actual = actual;
95
+ this.upstreamRequest = upstreamRequest;
96
+ this.collectorFactory = collectorFactory;
97
+ }
98
+ /** Subscribes this terminal reducer to its source with handshake error recovery. */
99
+ start(source) {
100
+ try {
101
+ source.subscribe(this);
102
+ } catch (error) {
103
+ if (this.terminated) throw error;
104
+ if (!this.subscribed && !this.terminated) {
105
+ this.subscribed = true;
106
+ this.actual.onSubscribe(this);
107
+ }
108
+ this.onError(error);
109
+ }
110
+ }
111
+ /** Stores the upstream and exposes this demand-gating subscription downstream. */
112
+ onSubscribe(subscription) {
113
+ if (this.subscribed || this.terminated) {
114
+ cancelSilently(subscription);
115
+ return;
116
+ }
117
+ this.subscribed = true;
118
+ this.upstream = subscription;
119
+ try {
120
+ this.actual.onSubscribe(this);
121
+ } catch (error) {
122
+ this.terminated = true;
123
+ this.cancelUpstream();
124
+ throw error;
125
+ }
126
+ }
127
+ /** Reduces a value and emits the result immediately when it becomes final. */
128
+ onNext(value) {
129
+ if (this.terminated || this.emitting || !this.requested || !this.collector) return;
130
+ try {
131
+ if (this.collector.onNext(value)) this.emitResult(true);
132
+ } catch (error) {
133
+ this.fail(error, true);
134
+ }
135
+ }
136
+ /** Forwards the first upstream failure without waiting for demand. */
137
+ onError(error) {
138
+ if (this.emitting) return;
139
+ this.fail(error, false);
140
+ }
141
+ /** Emits the reduced result, or remembers completion until demand arrives. */
142
+ onComplete() {
143
+ if (this.terminated || this.emitting) return;
144
+ if (!this.requested) {
145
+ this.completedBeforeRequest = true;
146
+ return;
147
+ }
148
+ this.emitResult(false);
149
+ }
150
+ /** Starts the single upstream terminal batch on the first valid request. */
151
+ request(n) {
152
+ if (this.terminated) return;
153
+ try {
154
+ normalizeRequest(n);
155
+ } catch (error) {
156
+ this.fail(error, true);
157
+ return;
158
+ }
159
+ if (this.requested) return;
160
+ this.requested = true;
161
+ try {
162
+ this.collector = this.collectorFactory();
163
+ } catch (error) {
164
+ this.fail(error, true);
165
+ return;
166
+ }
167
+ if (this.completedBeforeRequest) {
168
+ this.emitResult(false);
169
+ return;
170
+ }
171
+ try {
172
+ this.upstream?.request(this.upstreamRequest);
173
+ } catch (error) {
174
+ this.fail(error, true);
175
+ }
176
+ }
177
+ /** Cancels the source and releases the collector state. */
178
+ cancel() {
179
+ if (this.terminated) return;
180
+ this.terminated = true;
181
+ this.collector = void 0;
182
+ this.cancelUpstream();
183
+ }
184
+ /** Exposes the downstream Reactor context to the source. */
185
+ currentContext() {
186
+ return this.actual.currentContext?.() ?? Context.empty();
187
+ }
188
+ /** Propagates a guaranteed downstream batch to eagerly assembled iterable sources. */
189
+ [ITERATION_DEMAND_HINT]() {
190
+ return iterationDemandHint(this.actual) === UNBOUNDED_DEMAND ? this.upstreamRequest : void 0;
191
+ }
192
+ /** Produces and emits the terminal result, cancelling upstream for early results. */
193
+ emitResult(cancelUpstream) {
194
+ if (this.terminated || !this.collector) return;
195
+ let result;
196
+ try {
197
+ result = this.collector.result();
198
+ } catch (error) {
199
+ this.fail(error, cancelUpstream);
200
+ return;
201
+ }
202
+ this.collector = void 0;
203
+ this.emitting = true;
204
+ if (cancelUpstream) this.cancelUpstream();
205
+ if (result !== NO_TERMINAL_VALUE) try {
206
+ this.actual.onNext(result);
207
+ } catch (error) {
208
+ this.emitting = false;
209
+ if (this.terminated) return;
210
+ this.terminated = true;
211
+ this.cancelUpstream();
212
+ this.actual.onError(error);
213
+ return;
214
+ }
215
+ this.emitting = false;
216
+ if (this.terminated) return;
217
+ this.terminated = true;
218
+ this.actual.onComplete();
219
+ }
220
+ /** Cancels when requested and forwards one terminal failure. */
221
+ fail(error, cancelUpstream) {
222
+ if (this.terminated) return;
223
+ this.terminated = true;
224
+ this.collector = void 0;
225
+ if (cancelUpstream) this.cancelUpstream();
226
+ this.actual.onError(error);
227
+ }
228
+ /** Cancels the active upstream at most once. */
229
+ cancelUpstream() {
230
+ if (this.upstreamCancelled) return;
231
+ this.upstreamCancelled = true;
232
+ if (this.upstream) cancelSilently(this.upstream);
233
+ }
234
+ };
235
+ /** Cancels a subscription without replacing the active terminal signal. */
236
+ function cancelSilently(subscription) {
237
+ try {
238
+ subscription.cancel();
239
+ } catch {}
240
+ }
241
+ //#endregion
242
+ export { NO_TERMINAL_VALUE, terminalMono };
243
+
244
+ //# sourceMappingURL=terminal-mono.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-mono.js","names":[],"sources":["../../../src/publisher/operators/terminal-mono.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Direct terminal Mono implementation shared by aggregating operators.\n */\nimport {Context} from \"@/context/context.js\";\nimport {normalizeRequest, UNBOUNDED_DEMAND} from \"@/core/demand.js\";\nimport {ITERATION_DEMAND_HINT, iterationDemandHint} from \"@/internal/iteration-demand.js\";\nimport {consumePublisher, type TerminalCollector} from \"@/internal/publisher-terminal.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport {Mono} from \"@/publisher/mono.js\";\nimport type {CoreSubscriber} from \"@/subscription/core-subscriber.js\";\nimport type {Subscriber} from \"@/subscription/subscriber.js\";\nimport type {Subscription} from \"@/subscription/subscription.js\";\n\n/** Sentinel returned by a terminal collector when its Mono must complete empty. */\nexport const NO_TERMINAL_VALUE = Symbol(\"no-terminal-value\");\n\n/** Result produced by a terminal collector, including empty Mono completion. */\nexport type TerminalValue<T> = T | typeof NO_TERMINAL_VALUE;\n\n/** Creates fresh terminal reduction state for each subscription. */\nexport type TerminalCollectorFactory<T, R> = () => TerminalCollector<T, TerminalValue<R>>;\n\n/** Creates a Mono that reduces Publisher signals on the native demand path. */\nexport function terminalMono<T, R>(\n source: Flux<T>,\n upstreamRequest: number,\n collectorFactory: TerminalCollectorFactory<T, R>\n): Mono<R> {\n return new DirectTerminalMono(source, upstreamRequest, collectorFactory);\n}\n\n/** Mono whose subscribe and iteration paths both consume the source directly. */\nclass DirectTerminalMono<T, R> extends Mono<R> {\n /** Creates a direct terminal Mono around one source. */\n public constructor(\n private readonly source: Flux<T>,\n private readonly upstreamRequest: number,\n private readonly collectorFactory: TerminalCollectorFactory<T, R>\n ) {\n super(async function* (signal, context) {\n if (signal.aborted) {\n return;\n }\n const result = await consumePublisher(source, signal, context, upstreamRequest, collectorFactory());\n if (result !== NO_TERMINAL_VALUE) {\n yield result as R;\n }\n });\n }\n\n /** Installs a subscriber that waits for downstream demand before requesting upstream. */\n protected override subscribeActual(subscriber: Subscriber<R>): void {\n new TerminalMonoSubscriber(subscriber, this.upstreamRequest, this.collectorFactory).start(this.source);\n }\n}\n\n/** Subscriber/subscription pair that reduces a Flux to at most one value. */\nclass TerminalMonoSubscriber<T, R> implements CoreSubscriber<T>, Subscription {\n /** Active upstream subscription. */\n private upstream: Subscription | undefined;\n /** Collector created lazily on the first valid downstream request. */\n private collector: TerminalCollector<T, TerminalValue<R>> | undefined;\n /** Tracks the upstream Reactive Streams handshake. */\n private subscribed = false;\n /** Ensures upstream is requested at most once. */\n private requested = false;\n /** Records completion that arrived before downstream demand. */\n private completedBeforeRequest = false;\n /** Guards the downstream result callback against reentrant upstream signals. */\n private emitting = false;\n /** Ensures the active upstream is cancelled at most once. */\n private upstreamCancelled = false;\n /** Suppresses signals after cancellation or termination. */\n private terminated = false;\n\n /** Creates a terminal subscriber for one downstream subscriber. */\n public constructor(\n private readonly actual: Subscriber<R>,\n private readonly upstreamRequest: number,\n private readonly collectorFactory: TerminalCollectorFactory<T, R>\n ) {\n }\n\n /** Subscribes this terminal reducer to its source with handshake error recovery. */\n public start(source: Flux<T>): void {\n try {\n source.subscribe(this);\n } catch (error) {\n if (this.terminated) {\n throw error;\n }\n if (!this.subscribed && !this.terminated) {\n this.subscribed = true;\n this.actual.onSubscribe(this);\n }\n this.onError(error);\n }\n }\n\n /** Stores the upstream and exposes this demand-gating subscription downstream. */\n public onSubscribe(subscription: Subscription): void {\n if (this.subscribed || this.terminated) {\n cancelSilently(subscription);\n return;\n }\n this.subscribed = true;\n this.upstream = subscription;\n try {\n this.actual.onSubscribe(this);\n } catch (error) {\n this.terminated = true;\n this.cancelUpstream();\n throw error;\n }\n }\n\n /** Reduces a value and emits the result immediately when it becomes final. */\n public onNext(value: T): void {\n if (this.terminated || this.emitting || !this.requested || !this.collector) {\n return;\n }\n try {\n if (this.collector.onNext(value)) {\n this.emitResult(true);\n }\n } catch (error) {\n this.fail(error, true);\n }\n }\n\n /** Forwards the first upstream failure without waiting for demand. */\n public onError(error: unknown): void {\n if (this.emitting) {\n return;\n }\n this.fail(error, false);\n }\n\n /** Emits the reduced result, or remembers completion until demand arrives. */\n public onComplete(): void {\n if (this.terminated || this.emitting) {\n return;\n }\n if (!this.requested) {\n this.completedBeforeRequest = true;\n return;\n }\n this.emitResult(false);\n }\n\n /** Starts the single upstream terminal batch on the first valid request. */\n public request(n: number): void {\n if (this.terminated) {\n return;\n }\n try {\n normalizeRequest(n);\n } catch (error) {\n this.fail(error, true);\n return;\n }\n if (this.requested) {\n return;\n }\n this.requested = true;\n try {\n this.collector = this.collectorFactory();\n } catch (error) {\n this.fail(error, true);\n return;\n }\n if (this.completedBeforeRequest) {\n this.emitResult(false);\n return;\n }\n try {\n this.upstream?.request(this.upstreamRequest);\n } catch (error) {\n this.fail(error, true);\n }\n }\n\n /** Cancels the source and releases the collector state. */\n public cancel(): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.collector = undefined;\n this.cancelUpstream();\n }\n\n /** Exposes the downstream Reactor context to the source. */\n public currentContext(): Context {\n return (this.actual as CoreSubscriber<R>).currentContext?.() ?? Context.empty();\n }\n\n /** Propagates a guaranteed downstream batch to eagerly assembled iterable sources. */\n public [ITERATION_DEMAND_HINT](): number | undefined {\n return iterationDemandHint(this.actual) === UNBOUNDED_DEMAND\n ? this.upstreamRequest\n : undefined;\n }\n\n /** Produces and emits the terminal result, cancelling upstream for early results. */\n private emitResult(cancelUpstream: boolean): void {\n if (this.terminated || !this.collector) {\n return;\n }\n let result: TerminalValue<R>;\n try {\n result = this.collector.result();\n } catch (error) {\n this.fail(error, cancelUpstream);\n return;\n }\n this.collector = undefined;\n this.emitting = true;\n if (cancelUpstream) {\n this.cancelUpstream();\n }\n if (result !== NO_TERMINAL_VALUE) {\n try {\n this.actual.onNext(result as R);\n } catch (error) {\n this.emitting = false;\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.cancelUpstream();\n this.actual.onError(error);\n return;\n }\n }\n this.emitting = false;\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.actual.onComplete();\n }\n\n /** Cancels when requested and forwards one terminal failure. */\n private fail(error: unknown, cancelUpstream: boolean): void {\n if (this.terminated) {\n return;\n }\n this.terminated = true;\n this.collector = undefined;\n if (cancelUpstream) {\n this.cancelUpstream();\n }\n this.actual.onError(error);\n }\n\n /** Cancels the active upstream at most once. */\n private cancelUpstream(): void {\n if (this.upstreamCancelled) {\n return;\n }\n this.upstreamCancelled = true;\n if (this.upstream) {\n cancelSilently(this.upstream);\n }\n }\n}\n\n/** Cancels a subscription without replacing the active terminal signal. */\nfunction cancelSilently(subscription: Subscription): void {\n try {\n subscription.cancel();\n } catch {\n // Terminal state has already been selected.\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,IAAa,oBAAoB,OAAO,mBAAmB;;AAS3D,SAAgB,aACZ,QACA,iBACA,kBACO;CACP,OAAO,IAAI,mBAAmB,QAAQ,iBAAiB,gBAAgB;AAC3E;;AAGA,IAAM,qBAAN,cAAuC,KAAQ;;CAE3C,YACI,QACA,iBACA,kBACF;EACE,MAAM,iBAAiB,QAAQ,SAAS;GACpC,IAAI,OAAO,SACP;GAEJ,MAAM,SAAS,MAAM,iBAAiB,QAAQ,QAAQ,SAAS,iBAAiB,iBAAiB,CAAC;GAClG,IAAI,WAAW,mBACX,MAAM;EAEd,CAAC;wBAZgB,UAAA,KAAA,CAAA;wBACA,mBAAA,KAAA,CAAA;wBACA,oBAAA,KAAA,CAAA;EAFA,KAAA,SAAA;EACA,KAAA,kBAAA;EACA,KAAA,mBAAA;CAWrB;;CAGA,gBAAmC,YAAiC;EAChE,IAAI,uBAAuB,YAAY,KAAK,iBAAiB,KAAK,gBAAgB,CAAC,CAAC,MAAM,KAAK,MAAM;CACzG;AACJ;;AAGA,IAAM,yBAAN,MAA8E;;CAmB1E,YACI,QACA,iBACA,kBACF;wBAHmB,UAAA,KAAA,CAAA;wBACA,mBAAA,KAAA,CAAA;wBACA,oBAAA,KAAA,CAAA;;;;GApBrB;;;;;;GAEA;;;;;;GAEA;GAAqB;;;;;GAErB;GAAoB;;;;;GAEpB;GAAiC;;;;;GAEjC;GAAmB;;;;;GAEnB;GAA4B;;;;;GAE5B;GAAqB;;EAIA,KAAA,SAAA;EACA,KAAA,kBAAA;EACA,KAAA,mBAAA;CAErB;;CAGA,MAAa,QAAuB;EAChC,IAAI;GACA,OAAO,UAAU,IAAI;EACzB,SAAS,OAAO;GACZ,IAAI,KAAK,YACL,MAAM;GAEV,IAAI,CAAC,KAAK,cAAc,CAAC,KAAK,YAAY;IACtC,KAAK,aAAa;IAClB,KAAK,OAAO,YAAY,IAAI;GAChC;GACA,KAAK,QAAQ,KAAK;EACtB;CACJ;;CAGA,YAAmB,cAAkC;EACjD,IAAI,KAAK,cAAc,KAAK,YAAY;GACpC,eAAe,YAAY;GAC3B;EACJ;EACA,KAAK,aAAa;EAClB,KAAK,WAAW;EAChB,IAAI;GACA,KAAK,OAAO,YAAY,IAAI;EAChC,SAAS,OAAO;GACZ,KAAK,aAAa;GAClB,KAAK,eAAe;GACpB,MAAM;EACV;CACJ;;CAGA,OAAc,OAAgB;EAC1B,IAAI,KAAK,cAAc,KAAK,YAAY,CAAC,KAAK,aAAa,CAAC,KAAK,WAC7D;EAEJ,IAAI;GACA,IAAI,KAAK,UAAU,OAAO,KAAK,GAC3B,KAAK,WAAW,IAAI;EAE5B,SAAS,OAAO;GACZ,KAAK,KAAK,OAAO,IAAI;EACzB;CACJ;;CAGA,QAAe,OAAsB;EACjC,IAAI,KAAK,UACL;EAEJ,KAAK,KAAK,OAAO,KAAK;CAC1B;;CAGA,aAA0B;EACtB,IAAI,KAAK,cAAc,KAAK,UACxB;EAEJ,IAAI,CAAC,KAAK,WAAW;GACjB,KAAK,yBAAyB;GAC9B;EACJ;EACA,KAAK,WAAW,KAAK;CACzB;;CAGA,QAAe,GAAiB;EAC5B,IAAI,KAAK,YACL;EAEJ,IAAI;GACA,iBAAiB,CAAC;EACtB,SAAS,OAAO;GACZ,KAAK,KAAK,OAAO,IAAI;GACrB;EACJ;EACA,IAAI,KAAK,WACL;EAEJ,KAAK,YAAY;EACjB,IAAI;GACA,KAAK,YAAY,KAAK,iBAAiB;EAC3C,SAAS,OAAO;GACZ,KAAK,KAAK,OAAO,IAAI;GACrB;EACJ;EACA,IAAI,KAAK,wBAAwB;GAC7B,KAAK,WAAW,KAAK;GACrB;EACJ;EACA,IAAI;GACA,KAAK,UAAU,QAAQ,KAAK,eAAe;EAC/C,SAAS,OAAO;GACZ,KAAK,KAAK,OAAO,IAAI;EACzB;CACJ;;CAGA,SAAsB;EAClB,IAAI,KAAK,YACL;EAEJ,KAAK,aAAa;EAClB,KAAK,YAAY;EACjB,KAAK,eAAe;CACxB;;CAGA,iBAAiC;EAC7B,OAAQ,KAAK,OAA6B,iBAAiB,KAAK,QAAQ,MAAM;CAClF;;CAGA,CAAQ,yBAA6C;EACjD,OAAO,oBAAoB,KAAK,MAAM,MAAM,mBACtC,KAAK,kBACL;CACV;;CAGA,WAAmB,gBAA+B;EAC9C,IAAI,KAAK,cAAc,CAAC,KAAK,WACzB;EAEJ,IAAI;EACJ,IAAI;GACA,SAAS,KAAK,UAAU,OAAO;EACnC,SAAS,OAAO;GACZ,KAAK,KAAK,OAAO,cAAc;GAC/B;EACJ;EACA,KAAK,YAAY;EACjB,KAAK,WAAW;EAChB,IAAI,gBACA,KAAK,eAAe;EAExB,IAAI,WAAW,mBACX,IAAI;GACA,KAAK,OAAO,OAAO,MAAW;EAClC,SAAS,OAAO;GACZ,KAAK,WAAW;GAChB,IAAI,KAAK,YACL;GAEJ,KAAK,aAAa;GAClB,KAAK,eAAe;GACpB,KAAK,OAAO,QAAQ,KAAK;GACzB;EACJ;EAEJ,KAAK,WAAW;EAChB,IAAI,KAAK,YACL;EAEJ,KAAK,aAAa;EAClB,KAAK,OAAO,WAAW;CAC3B;;CAGA,KAAa,OAAgB,gBAA+B;EACxD,IAAI,KAAK,YACL;EAEJ,KAAK,aAAa;EAClB,KAAK,YAAY;EACjB,IAAI,gBACA,KAAK,eAAe;EAExB,KAAK,OAAO,QAAQ,KAAK;CAC7B;;CAGA,iBAA+B;EAC3B,IAAI,KAAK,mBACL;EAEJ,KAAK,oBAAoB;EACzB,IAAI,KAAK,UACL,eAAe,KAAK,QAAQ;CAEpC;AACJ;;AAGA,SAAS,eAAe,cAAkC;CACtD,IAAI;EACA,aAAa,OAAO;CACxB,QAAQ,CAER;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/terminal.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAEzC,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,QAAQ,qBAAqB,CAAC;IACjC,6DAA6D;IAC7D,UAAU,IAAI,CAAC,CAAC;QACZ,+EAA+E;QAC/E,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnB,4EAA4E;QAC5E,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE/C,wEAAwE;QACxE,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEjC,wEAAwE;QACxE,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;KAC7G;CACJ"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/terminal.ts"],"names":[],"mappings":"AAOA,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAEzC,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,QAAQ,qBAAqB,CAAC;IACjC,6DAA6D;IAC7D,UAAU,IAAI,CAAC,CAAC;QACZ,+EAA+E;QAC/E,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnB,4EAA4E;QAC5E,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE/C,wEAAwE;QACxE,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEjC,wEAAwE;QACxE,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;KAC7G;CACJ"}
@@ -1,44 +1,31 @@
1
- import { isAsyncIterable } from "../../internal/iterable.js";
1
+ import { UNBOUNDED_DEMAND } from "../../core/demand.js";
2
+ import { drainPublisher } from "../../internal/publisher-terminal.js";
2
3
  import { Flux } from "../flux.js";
3
- import { Mono } from "../mono.js";
4
+ import { NO_TERMINAL_VALUE, terminalMono } from "./terminal-mono.js";
4
5
  //#region src/publisher/operators/terminal.ts
5
6
  /**
6
7
  * @packageDocumentation
7
8
  * Flux, Mono and operator implementation modules.
8
9
  */
9
10
  Flux.prototype.then = function then() {
10
- const source = this;
11
- return new Mono((signal, context) => {
12
- const values = source.iterate(signal, context);
13
- return isAsyncIterable(values) ? drainThenEmitAsync(values, void 0) : drainThenEmitSync(values, void 0);
14
- });
11
+ return terminalMono(this, UNBOUNDED_DEMAND, () => ({
12
+ onNext: () => false,
13
+ result: () => NO_TERMINAL_VALUE
14
+ }));
15
15
  };
16
16
  Flux.prototype.thenMany = function thenMany(other) {
17
17
  const source = this;
18
18
  return new Flux(async function* (signal, context) {
19
- for await (const _ of source.iterate(signal, context));
19
+ await drainPublisher(source, signal, context);
20
20
  for await (const value of Flux.from(other).iterate(signal, context)) yield value;
21
21
  });
22
22
  };
23
23
  Flux.prototype.thenReturn = function thenReturn(value) {
24
- const source = this;
25
- return new Mono((signal, context) => {
26
- const values = source.iterate(signal, context);
27
- return isAsyncIterable(values) ? drainThenEmitAsync(values, value) : drainThenEmitSync(values, value);
28
- });
24
+ return terminalMono(this, UNBOUNDED_DEMAND, () => ({
25
+ onNext: () => false,
26
+ result: () => value
27
+ }));
29
28
  };
30
- /** Drains a synchronous source and then emits one completion value. */
31
- function drainThenEmitSync(values, value) {
32
- return (function* () {
33
- for (const _ of values);
34
- yield value;
35
- })();
36
- }
37
- /** Drains an asynchronous source and then emits one completion value. */
38
- async function* drainThenEmitAsync(values, value) {
39
- for await (const _ of values);
40
- yield value;
41
- }
42
29
  Flux.prototype.zipWith = function zipWith(other, combinator) {
43
30
  return Flux.zip([this, other], (values) => combinator ? combinator(values[0], values[1]) : [values[0], values[1]]);
44
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.js","names":[],"sources":["../../../src/publisher/operators/terminal.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Flux, Mono and operator implementation modules.\n */\nimport {Flux} from \"@/publisher/flux.js\";\nimport {Mono} from \"@/publisher/mono.js\";\nimport {isAsyncIterable} from \"@/internal/iterable.js\";\nimport type {PublisherInput} from \"@/publisher/types.js\";\n\ndeclare module \"@/publisher/flux.js\" {\n /** Terminal continuation and zip operators added to Flux. */\n interface Flux<T> {\n /** Ignores all values and completes when the source completes successfully. */\n then(): Mono<void>;\n\n /** Waits for this source to complete and then emits values from `other`. */\n thenMany<R>(other: PublisherInput<R>): Flux<R>;\n\n /** Ignores all values and emits `value` after successful completion. */\n thenReturn<R>(value: R): Mono<R>;\n\n /** Zips this Flux with another publisher and combines paired values. */\n zipWith<U, R = readonly [T, U]>(other: PublisherInput<U>, combinator?: (left: T, right: U) => R): Flux<R>;\n }\n}\n\nFlux.prototype.then = function then<T>(this: Flux<T>): Mono<void> {\n const source = this;\n return new Mono((signal, context) => {\n const values = source.iterate(signal, context);\n return isAsyncIterable<T>(values) ? drainThenEmitAsync(values, undefined) : drainThenEmitSync(values, undefined);\n });\n};\n\nFlux.prototype.thenMany = function thenMany<T, R>(this: Flux<T>, other: PublisherInput<R>): Flux<R> {\n const source = this;\n return new Flux(async function* (signal, context) {\n for await (const _ of source.iterate(signal, context)) {\n // ignore values\n }\n for await (const value of Flux.from(other).iterate(signal, context)) {\n yield value;\n }\n });\n};\n\nFlux.prototype.thenReturn = function thenReturn<T, R>(this: Flux<T>, value: R): Mono<R> {\n const source = this;\n return new Mono((signal, context) => {\n const values = source.iterate(signal, context);\n return isAsyncIterable<T>(values) ? drainThenEmitAsync(values, value) : drainThenEmitSync(values, value);\n });\n};\n\n/** Drains a synchronous source and then emits one completion value. */\nfunction drainThenEmitSync<T, R>(values: Iterable<T>, value: R): Iterable<R> {\n return (function* () {\n for (const _ of values) {\n // ignore values\n }\n yield value;\n })();\n}\n\n/** Drains an asynchronous source and then emits one completion value. */\nasync function* drainThenEmitAsync<T, R>(values: AsyncIterable<T>, value: R): AsyncIterable<R> {\n for await (const _ of values) {\n // ignore values\n }\n yield value;\n}\n\nFlux.prototype.zipWith = function zipWith<T, U, R = readonly [T, U]>(\n this: Flux<T>,\n other: PublisherInput<U>,\n combinator?: (left: T, right: U) => R\n): Flux<R> {\n return Flux.zip<[T, U], R>([this, other], values =>\n combinator ? combinator(values[0], values[1]) : ([values[0], values[1]] as const as R)\n );\n};\n"],"mappings":";;;;;;;;AA0BA,KAAK,UAAU,OAAO,SAAS,OAAmC;CAC9D,MAAM,SAAS;CACf,OAAO,IAAI,MAAM,QAAQ,YAAY;EACjC,MAAM,SAAS,OAAO,QAAQ,QAAQ,OAAO;EAC7C,OAAO,gBAAmB,MAAM,IAAI,mBAAmB,QAAQ,MAAS,IAAI,kBAAkB,QAAQ,MAAS;CACnH,CAAC;AACL;AAEA,KAAK,UAAU,WAAW,SAAS,SAA8B,OAAmC;CAChG,MAAM,SAAS;CACf,OAAO,IAAI,KAAK,iBAAiB,QAAQ,SAAS;EAC9C,WAAW,MAAM,KAAK,OAAO,QAAQ,QAAQ,OAAO;EAGpD,WAAW,MAAM,SAAS,KAAK,KAAK,KAAK,CAAC,CAAC,QAAQ,QAAQ,OAAO,GAC9D,MAAM;CAEd,CAAC;AACL;AAEA,KAAK,UAAU,aAAa,SAAS,WAAgC,OAAmB;CACpF,MAAM,SAAS;CACf,OAAO,IAAI,MAAM,QAAQ,YAAY;EACjC,MAAM,SAAS,OAAO,QAAQ,QAAQ,OAAO;EAC7C,OAAO,gBAAmB,MAAM,IAAI,mBAAmB,QAAQ,KAAK,IAAI,kBAAkB,QAAQ,KAAK;CAC3G,CAAC;AACL;;AAGA,SAAS,kBAAwB,QAAqB,OAAuB;CACzE,QAAQ,aAAa;EACjB,KAAK,MAAM,KAAK;EAGhB,MAAM;CACV,EAAA,CAAG;AACP;;AAGA,gBAAgB,mBAAyB,QAA0B,OAA4B;CAC3F,WAAW,MAAM,KAAK;CAGtB,MAAM;AACV;AAEA,KAAK,UAAU,UAAU,SAAS,QAE9B,OACA,YACO;CACP,OAAO,KAAK,IAAe,CAAC,MAAM,KAAK,IAAG,WACtC,aAAa,WAAW,OAAO,IAAI,OAAO,EAAE,IAAK,CAAC,OAAO,IAAI,OAAO,EAAE,CAC1E;AACJ"}
1
+ {"version":3,"file":"terminal.js","names":[],"sources":["../../../src/publisher/operators/terminal.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Flux, Mono and operator implementation modules.\n */\nimport {UNBOUNDED_DEMAND} from \"@/core/demand.js\";\nimport {drainPublisher} from \"@/internal/publisher-terminal.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport {Mono} from \"@/publisher/mono.js\";\nimport {NO_TERMINAL_VALUE, terminalMono} from \"@/publisher/operators/terminal-mono.js\";\nimport type {PublisherInput} from \"@/publisher/types.js\";\n\ndeclare module \"@/publisher/flux.js\" {\n /** Terminal continuation and zip operators added to Flux. */\n interface Flux<T> {\n /** Ignores all values and completes when the source completes successfully. */\n then(): Mono<void>;\n\n /** Waits for this source to complete and then emits values from `other`. */\n thenMany<R>(other: PublisherInput<R>): Flux<R>;\n\n /** Ignores all values and emits `value` after successful completion. */\n thenReturn<R>(value: R): Mono<R>;\n\n /** Zips this Flux with another publisher and combines paired values. */\n zipWith<U, R = readonly [T, U]>(other: PublisherInput<U>, combinator?: (left: T, right: U) => R): Flux<R>;\n }\n}\n\nFlux.prototype.then = function then<T>(this: Flux<T>): Mono<void> {\n return terminalMono<T, void>(this, UNBOUNDED_DEMAND, () => ({\n onNext: () => false,\n result: () => NO_TERMINAL_VALUE\n }));\n};\n\nFlux.prototype.thenMany = function thenMany<T, R>(this: Flux<T>, other: PublisherInput<R>): Flux<R> {\n const source = this;\n return new Flux(async function* (signal, context) {\n await drainPublisher(source, signal, context);\n for await (const value of Flux.from(other).iterate(signal, context)) {\n yield value;\n }\n });\n};\n\nFlux.prototype.thenReturn = function thenReturn<T, R>(this: Flux<T>, value: R): Mono<R> {\n return terminalMono(this, UNBOUNDED_DEMAND, () => ({\n onNext: () => false,\n result: () => value\n }));\n};\n\nFlux.prototype.zipWith = function zipWith<T, U, R = readonly [T, U]>(\n this: Flux<T>,\n other: PublisherInput<U>,\n combinator?: (left: T, right: U) => R\n): Flux<R> {\n return Flux.zip<[T, U], R>([this, other], values =>\n combinator ? combinator(values[0], values[1]) : ([values[0], values[1]] as const as R)\n );\n};\n"],"mappings":";;;;;;;;;AA4BA,KAAK,UAAU,OAAO,SAAS,OAAmC;CAC9D,OAAO,aAAsB,MAAM,yBAAyB;EACxD,cAAc;EACd,cAAc;CAClB,EAAE;AACN;AAEA,KAAK,UAAU,WAAW,SAAS,SAA8B,OAAmC;CAChG,MAAM,SAAS;CACf,OAAO,IAAI,KAAK,iBAAiB,QAAQ,SAAS;EAC9C,MAAM,eAAe,QAAQ,QAAQ,OAAO;EAC5C,WAAW,MAAM,SAAS,KAAK,KAAK,KAAK,CAAC,CAAC,QAAQ,QAAQ,OAAO,GAC9D,MAAM;CAEd,CAAC;AACL;AAEA,KAAK,UAAU,aAAa,SAAS,WAAgC,OAAmB;CACpF,OAAO,aAAa,MAAM,yBAAyB;EAC/C,cAAc;EACd,cAAc;CAClB,EAAE;AACN;AAEA,KAAK,UAAU,UAAU,SAAS,QAE9B,OACA,YACO;CACP,OAAO,KAAK,IAAe,CAAC,MAAM,KAAK,IAAG,WACtC,aAAa,WAAW,OAAO,IAAI,OAAO,EAAE,IAAK,CAAC,OAAO,IAAI,OAAO,EAAE,CAC1E;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/time.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEpE,OAAO,QAAQ,qBAAqB,CAAC;IACjC,4DAA4D;IAC5D,UAAU,IAAI,CAAC,CAAC;QACZ,6EAA6E;QAC7E,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpE,+EAA+E;QAC/E,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9F,4DAA4D;QAC5D,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzC,6DAA6D;QAC7D,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,8DAA8D;QAC9D,SAAS,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QAE7D,sFAAsF;QACtF,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;KAC9D;CACJ"}
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/publisher/operators/time.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEpE,OAAO,QAAQ,qBAAqB,CAAC;IACjC,4DAA4D;IAC5D,UAAU,IAAI,CAAC,CAAC;QACZ,6EAA6E;QAC7E,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpE,+EAA+E;QAC/E,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9F,4DAA4D;QAC5D,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzC,6DAA6D;QAC7D,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,8DAA8D;QAC9D,SAAS,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QAE7D,sFAAsF;QACtF,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;KAC9D;CACJ"}
@@ -1,6 +1,7 @@
1
1
  import { toAsyncIterator } from "../../internal/iterable.js";
2
2
  import { TimeoutError } from "../../errors/classes.js";
3
3
  import { AsyncQueue } from "../../internal/async-queue.js";
4
+ import { inheritIterationDemand } from "../../internal/iteration-demand.js";
4
5
  import { Schedulers } from "../../schedulers/schedulers.js";
5
6
  import { TIMEOUT, raceIteratorWithTimeout, scheduleDelay } from "../helpers.js";
6
7
  import { Flux } from "../flux.js";
@@ -22,6 +23,7 @@ Flux.prototype.timeout = function timeout(timeout, fallback, scheduler = Schedul
22
23
  const source = this;
23
24
  return new Flux(async function* (signal, context) {
24
25
  const controller = new AbortController();
26
+ inheritIterationDemand(signal, controller.signal);
25
27
  const abort = () => controller.abort();
26
28
  signal.addEventListener("abort", abort, { once: true });
27
29
  const iterator = toAsyncIterator(source.iterate(controller.signal, context));