reactor-core-ts 2.1.6 → 3.2.2
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.
- package/README.md +927 -658
- package/dist/_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/defineProperty.js +12 -0
- package/dist/_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/toPrimitive.js +14 -0
- package/dist/_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/toPropertyKey.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/typeof.js +11 -0
- package/dist/context/context-view.d.ts +31 -0
- package/dist/context/context-view.d.ts.map +1 -0
- package/dist/context/context-view.js +58 -0
- package/dist/context/context-view.js.map +1 -0
- package/dist/context/context.d.ts +46 -0
- package/dist/context/context.d.ts.map +1 -0
- package/dist/context/context.js +125 -0
- package/dist/context/context.js.map +1 -0
- package/dist/context/types.d.ts +7 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/core/boolean-disposable.d.ts +19 -0
- package/dist/core/boolean-disposable.d.ts.map +1 -0
- package/dist/core/boolean-disposable.js +37 -0
- package/dist/core/boolean-disposable.js.map +1 -0
- package/dist/core/composite-disposable.d.ts +21 -0
- package/dist/core/composite-disposable.d.ts.map +1 -0
- package/dist/core/composite-disposable.js +64 -0
- package/dist/core/composite-disposable.js.map +1 -0
- package/dist/core/demand.d.ts +9 -0
- package/dist/core/demand.d.ts.map +1 -0
- package/dist/core/demand.js +21 -0
- package/dist/core/demand.js.map +1 -0
- package/dist/core/disposables.d.ts +12 -0
- package/dist/core/disposables.d.ts.map +1 -0
- package/dist/core/disposables.js +37 -0
- package/dist/core/disposables.js.map +1 -0
- package/dist/core/teardown.d.ts +4 -0
- package/dist/core/teardown.d.ts.map +1 -0
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/errors/classes.d.ts +37 -0
- package/dist/errors/classes.d.ts.map +1 -0
- package/dist/errors/classes.js +53 -0
- package/dist/errors/classes.js.map +1 -0
- package/dist/errors/exceptions.d.ts +15 -0
- package/dist/errors/exceptions.d.ts.map +1 -0
- package/dist/errors/helpers.d.ts +9 -0
- package/dist/errors/helpers.d.ts.map +1 -0
- package/dist/errors/helpers.js +18 -0
- package/dist/errors/helpers.js.map +1 -0
- package/dist/index.d.ts +17 -2556
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -2
- package/dist/internal/abort.d.ts +5 -0
- package/dist/internal/abort.d.ts.map +1 -0
- package/dist/internal/abort.js +36 -0
- package/dist/internal/abort.js.map +1 -0
- package/dist/internal/async-queue.d.ts +48 -0
- package/dist/internal/async-queue.d.ts.map +1 -0
- package/dist/internal/async-queue.js +187 -0
- package/dist/internal/async-queue.js.map +1 -0
- package/dist/internal/iterable-terminal.d.ts +12 -0
- package/dist/internal/iterable-terminal.d.ts.map +1 -0
- package/dist/internal/iterable-terminal.js +49 -0
- package/dist/internal/iterable-terminal.js.map +1 -0
- package/dist/internal/iterable-transform.d.ts +24 -0
- package/dist/internal/iterable-transform.d.ts.map +1 -0
- package/dist/internal/iterable-transform.js +159 -0
- package/dist/internal/iterable-transform.js.map +1 -0
- package/dist/internal/iterable.d.ts +23 -0
- package/dist/internal/iterable.d.ts.map +1 -0
- package/dist/internal/iterable.js +81 -0
- package/dist/internal/iterable.js.map +1 -0
- package/dist/internal/microtask.d.ts +7 -0
- package/dist/internal/microtask.d.ts.map +1 -0
- package/dist/internal/microtask.js +19 -0
- package/dist/internal/microtask.js.map +1 -0
- package/dist/publisher/browser-sources.d.ts +15 -0
- package/dist/publisher/browser-sources.d.ts.map +1 -0
- package/dist/publisher/browser-sources.js +92 -0
- package/dist/publisher/browser-sources.js.map +1 -0
- package/dist/publisher/flux-entrypoint.d.ts +7 -0
- package/dist/publisher/flux-entrypoint.d.ts.map +1 -0
- package/dist/publisher/flux-entrypoint.js +11 -0
- package/dist/publisher/flux-entrypoint.js.map +1 -0
- package/dist/publisher/flux.d.ts +121 -0
- package/dist/publisher/flux.d.ts.map +1 -0
- package/dist/publisher/flux.js +767 -0
- package/dist/publisher/flux.js.map +1 -0
- package/dist/publisher/helpers.d.ts +19 -0
- package/dist/publisher/helpers.d.ts.map +1 -0
- package/dist/publisher/helpers.js +84 -0
- package/dist/publisher/helpers.js.map +1 -0
- package/dist/publisher/mono-entrypoint.d.ts +7 -0
- package/dist/publisher/mono-entrypoint.d.ts.map +1 -0
- package/dist/publisher/mono-entrypoint.js +11 -0
- package/dist/publisher/mono-entrypoint.js.map +1 -0
- package/dist/publisher/mono.d.ts +72 -0
- package/dist/publisher/mono.d.ts.map +1 -0
- package/dist/publisher/mono.js +373 -0
- package/dist/publisher/mono.js.map +1 -0
- package/dist/publisher/operators/aggregate.d.ts +35 -0
- package/dist/publisher/operators/aggregate.d.ts.map +1 -0
- package/dist/publisher/operators/aggregate.js +217 -0
- package/dist/publisher/operators/aggregate.js.map +1 -0
- package/dist/publisher/operators/compat/flux.d.ts +56 -0
- package/dist/publisher/operators/compat/flux.d.ts.map +1 -0
- package/dist/publisher/operators/compat/flux.js +156 -0
- package/dist/publisher/operators/compat/flux.js.map +1 -0
- package/dist/publisher/operators/compat/mono.d.ts +82 -0
- package/dist/publisher/operators/compat/mono.d.ts.map +1 -0
- package/dist/publisher/operators/compat/mono.js +125 -0
- package/dist/publisher/operators/compat/mono.js.map +1 -0
- package/dist/publisher/operators/coordination.d.ts +82 -0
- package/dist/publisher/operators/coordination.d.ts.map +1 -0
- package/dist/publisher/operators/coordination.js +345 -0
- package/dist/publisher/operators/coordination.js.map +1 -0
- package/dist/publisher/operators/error.d.ts +17 -0
- package/dist/publisher/operators/error.d.ts.map +1 -0
- package/dist/publisher/operators/error.js +48 -0
- package/dist/publisher/operators/error.js.map +1 -0
- package/dist/publisher/operators/flatten.d.ts +19 -0
- package/dist/publisher/operators/flatten.d.ts.map +1 -0
- package/dist/publisher/operators/flatten.js +127 -0
- package/dist/publisher/operators/flatten.js.map +1 -0
- package/dist/publisher/operators/lifecycle.d.ts +103 -0
- package/dist/publisher/operators/lifecycle.d.ts.map +1 -0
- package/dist/publisher/operators/lifecycle.js +263 -0
- package/dist/publisher/operators/lifecycle.js.map +1 -0
- package/dist/publisher/operators/lift.d.ts +42 -0
- package/dist/publisher/operators/lift.d.ts.map +1 -0
- package/dist/publisher/operators/lift.js +343 -0
- package/dist/publisher/operators/lift.js.map +1 -0
- package/dist/publisher/operators/mono-parity.d.ts +109 -0
- package/dist/publisher/operators/mono-parity.d.ts.map +1 -0
- package/dist/publisher/operators/mono-parity.js +144 -0
- package/dist/publisher/operators/mono-parity.js.map +1 -0
- package/dist/publisher/operators/mono.d.ts +30 -0
- package/dist/publisher/operators/mono.d.ts.map +1 -0
- package/dist/publisher/operators/mono.js +37 -0
- package/dist/publisher/operators/mono.js.map +1 -0
- package/dist/publisher/operators/register.d.ts +20 -0
- package/dist/publisher/operators/register.d.ts.map +1 -0
- package/dist/publisher/operators/register.js +23 -0
- package/dist/publisher/operators/register.js.map +1 -0
- package/dist/publisher/operators/selection.d.ts +25 -0
- package/dist/publisher/operators/selection.d.ts.map +1 -0
- package/dist/publisher/operators/selection.js +108 -0
- package/dist/publisher/operators/selection.js.map +1 -0
- package/dist/publisher/operators/side-effect.d.ts +15 -0
- package/dist/publisher/operators/side-effect.d.ts.map +1 -0
- package/dist/publisher/operators/side-effect.js +81 -0
- package/dist/publisher/operators/side-effect.js.map +1 -0
- package/dist/publisher/operators/terminal.d.ts +16 -0
- package/dist/publisher/operators/terminal.d.ts.map +1 -0
- package/dist/publisher/operators/terminal.js +47 -0
- package/dist/publisher/operators/terminal.js.map +1 -0
- package/dist/publisher/operators/time.d.ts +20 -0
- package/dist/publisher/operators/time.d.ts.map +1 -0
- package/dist/publisher/operators/time.js +92 -0
- package/dist/publisher/operators/time.js.map +1 -0
- package/dist/publisher/operators/transform.d.ts +31 -0
- package/dist/publisher/operators/transform.d.ts.map +1 -0
- package/dist/publisher/operators/transform.js +75 -0
- package/dist/publisher/operators/transform.js.map +1 -0
- package/dist/publisher/operators/windowing.d.ts +28 -0
- package/dist/publisher/operators/windowing.d.ts.map +1 -0
- package/dist/publisher/operators/windowing.js +148 -0
- package/dist/publisher/operators/windowing.js.map +1 -0
- package/dist/publisher/publisher.d.ts +11 -0
- package/dist/publisher/publisher.d.ts.map +1 -0
- package/dist/publisher/types.d.ts +51 -0
- package/dist/publisher/types.d.ts.map +1 -0
- package/dist/schedulers/animation-frame-scheduler.d.ts +11 -0
- package/dist/schedulers/animation-frame-scheduler.d.ts.map +1 -0
- package/dist/schedulers/animation-frame-scheduler.js +30 -0
- package/dist/schedulers/animation-frame-scheduler.js.map +1 -0
- package/dist/schedulers/base-scheduler.d.ts +28 -0
- package/dist/schedulers/base-scheduler.d.ts.map +1 -0
- package/dist/schedulers/base-scheduler.js +77 -0
- package/dist/schedulers/base-scheduler.js.map +1 -0
- package/dist/schedulers/basic-worker.d.ts +22 -0
- package/dist/schedulers/basic-worker.d.ts.map +1 -0
- package/dist/schedulers/basic-worker.js +71 -0
- package/dist/schedulers/basic-worker.js.map +1 -0
- package/dist/schedulers/delay-scheduler.d.ts +12 -0
- package/dist/schedulers/delay-scheduler.d.ts.map +1 -0
- package/dist/schedulers/delay-scheduler.js +17 -0
- package/dist/schedulers/delay-scheduler.js.map +1 -0
- package/dist/schedulers/disposed.d.ts +4 -0
- package/dist/schedulers/disposed.d.ts.map +1 -0
- package/dist/schedulers/disposed.js +14 -0
- package/dist/schedulers/disposed.js.map +1 -0
- package/dist/schedulers/duration.d.ts +8 -0
- package/dist/schedulers/duration.d.ts.map +1 -0
- package/dist/schedulers/duration.js +11 -0
- package/dist/schedulers/duration.js.map +1 -0
- package/dist/schedulers/executor-scheduler.d.ts +13 -0
- package/dist/schedulers/executor-scheduler.d.ts.map +1 -0
- package/dist/schedulers/executor-scheduler.js +43 -0
- package/dist/schedulers/executor-scheduler.js.map +1 -0
- package/dist/schedulers/immediate-scheduler.d.ts +15 -0
- package/dist/schedulers/immediate-scheduler.d.ts.map +1 -0
- package/dist/schedulers/immediate-scheduler.js +24 -0
- package/dist/schedulers/immediate-scheduler.js.map +1 -0
- package/dist/schedulers/index.d.ts +7 -0
- package/dist/schedulers/index.d.ts.map +1 -0
- package/dist/schedulers/index.js +2 -0
- package/dist/schedulers/interval-scheduler.d.ts +12 -0
- package/dist/schedulers/interval-scheduler.d.ts.map +1 -0
- package/dist/schedulers/interval-scheduler.js +17 -0
- package/dist/schedulers/interval-scheduler.js.map +1 -0
- package/dist/schedulers/macro-scheduler.d.ts +19 -0
- package/dist/schedulers/macro-scheduler.d.ts.map +1 -0
- package/dist/schedulers/macro-scheduler.js +30 -0
- package/dist/schedulers/macro-scheduler.js.map +1 -0
- package/dist/schedulers/microtask-scheduler.d.ts +11 -0
- package/dist/schedulers/microtask-scheduler.d.ts.map +1 -0
- package/dist/schedulers/microtask-scheduler.js +34 -0
- package/dist/schedulers/microtask-scheduler.js.map +1 -0
- package/dist/schedulers/schedulers.d.ts +39 -0
- package/dist/schedulers/schedulers.d.ts.map +1 -0
- package/dist/schedulers/schedulers.js +83 -0
- package/dist/schedulers/schedulers.js.map +1 -0
- package/dist/schedulers/timeout-scheduler.d.ts +11 -0
- package/dist/schedulers/timeout-scheduler.d.ts.map +1 -0
- package/dist/schedulers/types.d.ts +35 -0
- package/dist/schedulers/types.d.ts.map +1 -0
- package/dist/signal/signal-type.d.ts +26 -0
- package/dist/signal/signal-type.d.ts.map +1 -0
- package/dist/signal/signal-type.js +31 -0
- package/dist/signal/signal-type.js.map +1 -0
- package/dist/signal/signal.d.ts +33 -0
- package/dist/signal/signal.d.ts.map +1 -0
- package/dist/signal/signal.js +70 -0
- package/dist/signal/signal.js.map +1 -0
- package/dist/sinks/index.d.ts +7 -0
- package/dist/sinks/index.d.ts.map +1 -0
- package/dist/sinks/index.js +2 -0
- package/dist/sinks/many.d.ts +66 -0
- package/dist/sinks/many.d.ts.map +1 -0
- package/dist/sinks/many.js +193 -0
- package/dist/sinks/many.js.map +1 -0
- package/dist/sinks/one.d.ts +41 -0
- package/dist/sinks/one.d.ts.map +1 -0
- package/dist/sinks/one.js +144 -0
- package/dist/sinks/one.js.map +1 -0
- package/dist/sinks/specs.d.ts +25 -0
- package/dist/sinks/specs.d.ts.map +1 -0
- package/dist/sinks/specs.js +126 -0
- package/dist/sinks/specs.js.map +1 -0
- package/dist/sinks/subscribers.d.ts +16 -0
- package/dist/sinks/subscribers.d.ts.map +1 -0
- package/dist/sinks/subscribers.js +32 -0
- package/dist/sinks/subscribers.js.map +1 -0
- package/dist/sinks/types.d.ts +137 -0
- package/dist/sinks/types.d.ts.map +1 -0
- package/dist/sinks/types.js +58 -0
- package/dist/sinks/types.js.map +1 -0
- package/dist/subscription/core-subscriber.d.ts +12 -0
- package/dist/subscription/core-subscriber.d.ts.map +1 -0
- package/dist/subscription/iterable-subscription.d.ts +64 -0
- package/dist/subscription/iterable-subscription.d.ts.map +1 -0
- package/dist/subscription/iterable-subscription.js +281 -0
- package/dist/subscription/iterable-subscription.js.map +1 -0
- package/dist/subscription/reactive-streams.d.ts +8 -0
- package/dist/subscription/reactive-streams.d.ts.map +1 -0
- package/dist/subscription/reactive-streams.js +0 -0
- package/dist/subscription/subscriber.d.ts +17 -0
- package/dist/subscription/subscriber.d.ts.map +1 -0
- package/dist/subscription/subscription.d.ts +12 -0
- package/dist/subscription/subscription.d.ts.map +1 -0
- package/package.json +100 -33
- package/dist/index.d.mts +0 -2557
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -2
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/defineProperty.js";
|
|
2
|
+
import { AsyncQueue } from "../internal/async-queue.js";
|
|
3
|
+
import { Flux } from "../publisher/flux.js";
|
|
4
|
+
import { SignalType } from "../signal/signal-type.js";
|
|
5
|
+
import { addSinkSubscriber, clearSinkSubscribers, removeSinkSubscriber, sinkSubscriberCount } from "./subscribers.js";
|
|
6
|
+
import { EmitFailureHandlers, EmitResult, emitOrThrow } from "./types.js";
|
|
7
|
+
//#region src/sinks/many.ts
|
|
8
|
+
/**
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
* Sink specifications and default browser-oriented sink implementations.
|
|
11
|
+
*/
|
|
12
|
+
/** Default implementation for unicast, multicast and replay many-valued sinks. */
|
|
13
|
+
var DefaultManySink = class {
|
|
14
|
+
/** Creates a many-valued sink with the provided delivery mode. */
|
|
15
|
+
constructor(options) {
|
|
16
|
+
_defineProperty(
|
|
17
|
+
this,
|
|
18
|
+
/** Active subscriber queues currently receiving live values. */
|
|
19
|
+
"subscribers",
|
|
20
|
+
void 0
|
|
21
|
+
);
|
|
22
|
+
_defineProperty(
|
|
23
|
+
this,
|
|
24
|
+
/** Values buffered before a non-replay sink receives its first subscriber. */
|
|
25
|
+
"pending",
|
|
26
|
+
void 0
|
|
27
|
+
);
|
|
28
|
+
_defineProperty(
|
|
29
|
+
this,
|
|
30
|
+
/** Values retained for replay subscribers. */
|
|
31
|
+
"history",
|
|
32
|
+
void 0
|
|
33
|
+
);
|
|
34
|
+
_defineProperty(
|
|
35
|
+
this,
|
|
36
|
+
/** Ring-buffer index of the oldest replay value. */
|
|
37
|
+
"historyHead",
|
|
38
|
+
0
|
|
39
|
+
);
|
|
40
|
+
_defineProperty(
|
|
41
|
+
this,
|
|
42
|
+
/** Terminal state when the sink has completed or failed. */
|
|
43
|
+
"terminated",
|
|
44
|
+
void 0
|
|
45
|
+
);
|
|
46
|
+
_defineProperty(
|
|
47
|
+
this,
|
|
48
|
+
/** Error retained for late subscribers after failure. */
|
|
49
|
+
"errorValue",
|
|
50
|
+
void 0
|
|
51
|
+
);
|
|
52
|
+
_defineProperty(
|
|
53
|
+
this,
|
|
54
|
+
/** Tracks whether a unicast sink already accepted its single subscriber. */
|
|
55
|
+
"unicastAttached",
|
|
56
|
+
false
|
|
57
|
+
);
|
|
58
|
+
_defineProperty(
|
|
59
|
+
this,
|
|
60
|
+
/** Construction options controlling delivery and replay behavior. */
|
|
61
|
+
"options",
|
|
62
|
+
void 0
|
|
63
|
+
);
|
|
64
|
+
this.options = options;
|
|
65
|
+
if (options.latestDefault !== void 0) this.rememberHistory(options.latestDefault);
|
|
66
|
+
}
|
|
67
|
+
/** Returns the Flux view of this sink. */
|
|
68
|
+
asFlux() {
|
|
69
|
+
return new Flux((signal) => {
|
|
70
|
+
const queue = new AsyncQueue(signal);
|
|
71
|
+
if (isUnicast(this.options.mode) && this.unicastAttached) {
|
|
72
|
+
queue.error(/* @__PURE__ */ new Error("Unicast sink allows only one subscriber"));
|
|
73
|
+
return queue;
|
|
74
|
+
}
|
|
75
|
+
if (isUnicast(this.options.mode)) this.unicastAttached = true;
|
|
76
|
+
const history = this.history;
|
|
77
|
+
if (history) for (let index = 0; index < history.length; index += 1) queue.push(historyValue(history, this.historyHead, index));
|
|
78
|
+
if (this.pending && this.pending.length > 0) {
|
|
79
|
+
const pending = this.pending;
|
|
80
|
+
this.pending = void 0;
|
|
81
|
+
for (const value of pending) queue.push(value);
|
|
82
|
+
}
|
|
83
|
+
if (this.terminated === "complete") queue.complete();
|
|
84
|
+
else if (this.terminated === "error") queue.error(this.errorValue);
|
|
85
|
+
else this.addSubscriber(queue, signal);
|
|
86
|
+
return queue;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Attempts to emit a value to current subscribers. */
|
|
90
|
+
tryEmitNext(value) {
|
|
91
|
+
if (this.terminated) return EmitResult.FAIL_TERMINATED;
|
|
92
|
+
if (this.options.mode === "replay") this.rememberHistory(value);
|
|
93
|
+
const subscribers = this.subscribers;
|
|
94
|
+
if (!subscribers) {
|
|
95
|
+
if (this.options.mode === "multicast-direct" || this.options.mode === "unicast-error") return EmitResult.FAIL_ZERO_SUBSCRIBER;
|
|
96
|
+
if (this.options.mode !== "replay") (this.pending ?? (this.pending = [])).push(value);
|
|
97
|
+
return EmitResult.OK;
|
|
98
|
+
}
|
|
99
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) subscriber.push(value);
|
|
100
|
+
else subscribers.push(value);
|
|
101
|
+
return EmitResult.OK;
|
|
102
|
+
}
|
|
103
|
+
/** Attempts to complete this sink. */
|
|
104
|
+
tryEmitComplete() {
|
|
105
|
+
if (this.terminated) return EmitResult.FAIL_TERMINATED;
|
|
106
|
+
const subscribers = this.subscribers;
|
|
107
|
+
if (this.options.mode === "unicast-error" && !subscribers) return EmitResult.FAIL_ZERO_SUBSCRIBER;
|
|
108
|
+
this.terminated = "complete";
|
|
109
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) subscriber.complete();
|
|
110
|
+
else if (subscribers) subscribers.complete();
|
|
111
|
+
this.clearSubscribers();
|
|
112
|
+
return EmitResult.OK;
|
|
113
|
+
}
|
|
114
|
+
/** Attempts to fail this sink. */
|
|
115
|
+
tryEmitError(error) {
|
|
116
|
+
if (this.terminated) return EmitResult.FAIL_TERMINATED;
|
|
117
|
+
const subscribers = this.subscribers;
|
|
118
|
+
if (this.options.mode === "unicast-error" && !subscribers) return EmitResult.FAIL_ZERO_SUBSCRIBER;
|
|
119
|
+
this.terminated = "error";
|
|
120
|
+
this.errorValue = error;
|
|
121
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) subscriber.error(error);
|
|
122
|
+
else if (subscribers) subscribers.error(error);
|
|
123
|
+
this.clearSubscribers();
|
|
124
|
+
return EmitResult.OK;
|
|
125
|
+
}
|
|
126
|
+
/** Emits a value or delegates failure handling to the provided handler. */
|
|
127
|
+
emitNext(value, handler = EmitFailureHandlers.FAIL_FAST) {
|
|
128
|
+
emitOrThrow(SignalType.NEXT, () => this.tryEmitNext(value), handler);
|
|
129
|
+
}
|
|
130
|
+
/** Completes this sink or delegates failure handling to the provided handler. */
|
|
131
|
+
emitComplete(handler = EmitFailureHandlers.FAIL_FAST) {
|
|
132
|
+
emitOrThrow(SignalType.COMPLETE, () => this.tryEmitComplete(), handler);
|
|
133
|
+
}
|
|
134
|
+
/** Fails this sink or delegates failure handling to the provided handler. */
|
|
135
|
+
emitError(error, handler = EmitFailureHandlers.FAIL_FAST) {
|
|
136
|
+
emitOrThrow(SignalType.ERROR, () => this.tryEmitError(error), handler, error);
|
|
137
|
+
}
|
|
138
|
+
/** Returns the current number of active subscribers. */
|
|
139
|
+
currentSubscriberCount() {
|
|
140
|
+
return sinkSubscriberCount(this.subscribers);
|
|
141
|
+
}
|
|
142
|
+
/** Subscribes this sink to an upstream publisher and relays its signals. */
|
|
143
|
+
subscribeTo(source) {
|
|
144
|
+
Flux.from(source).subscribe((value) => this.emitNext(value), (error) => this.emitError(error), () => this.emitComplete());
|
|
145
|
+
}
|
|
146
|
+
/** Handles an emission failure and returns false to fail fast by default. */
|
|
147
|
+
onEmitFailure(_signalType, _emitResult) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
/** Adds a subscriber queue and removes it again when its subscription is cancelled. */
|
|
151
|
+
addSubscriber(queue, signal) {
|
|
152
|
+
this.subscribers = addSinkSubscriber(this.subscribers, queue);
|
|
153
|
+
signal.addEventListener("abort", () => this.removeSubscriber(queue), { once: true });
|
|
154
|
+
}
|
|
155
|
+
/** Removes a subscriber queue and releases the set when it becomes empty. */
|
|
156
|
+
removeSubscriber(queue) {
|
|
157
|
+
this.subscribers = removeSinkSubscriber(this.subscribers, queue);
|
|
158
|
+
}
|
|
159
|
+
/** Clears and releases all active subscriber queues. */
|
|
160
|
+
clearSubscribers() {
|
|
161
|
+
clearSinkSubscribers(this.subscribers);
|
|
162
|
+
this.subscribers = void 0;
|
|
163
|
+
}
|
|
164
|
+
/** Records one value into replay history, allocating history only for replay sinks. */
|
|
165
|
+
rememberHistory(value) {
|
|
166
|
+
const limit = this.options.replayLimit ?? Number.POSITIVE_INFINITY;
|
|
167
|
+
if (limit <= 0) return;
|
|
168
|
+
const history = this.history;
|
|
169
|
+
if (!history) {
|
|
170
|
+
this.history = [value];
|
|
171
|
+
this.historyHead = 0;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (history.length < limit) {
|
|
175
|
+
history.push(value);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
history[this.historyHead] = value;
|
|
179
|
+
this.historyHead = (this.historyHead + 1) % history.length;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
/** Returns true for sink modes that allow exactly one subscriber. */
|
|
183
|
+
function isUnicast(mode) {
|
|
184
|
+
return mode === "unicast" || mode === "unicast-error";
|
|
185
|
+
}
|
|
186
|
+
/** Returns a replay history value in oldest-to-newest order. */
|
|
187
|
+
function historyValue(history, head, index) {
|
|
188
|
+
return history[(head + index) % history.length];
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
export { DefaultManySink };
|
|
192
|
+
|
|
193
|
+
//# sourceMappingURL=many.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"many.js","names":[],"sources":["../../src/sinks/many.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Sink specifications and default browser-oriented sink implementations.\n */\nimport {AsyncQueue} from \"@/internal/async-queue.js\";\nimport {Flux} from \"@/publisher/flux.js\";\nimport type {PublisherInput} from \"@/publisher/types.js\";\nimport {SignalType} from \"@/signal/signal-type.js\";\nimport {\n addSinkSubscriber,\n clearSinkSubscribers,\n removeSinkSubscriber,\n sinkSubscriberCount,\n type SinkSubscribers\n} from \"@/sinks/subscribers.js\";\nimport {type EmitFailureHandler, EmitFailureHandlers, emitOrThrow, EmitResult, type ManySink} from \"@/sinks/types.js\";\n\n/** Delivery mode supported by the default many-valued sink. */\ntype ManyMode = \"unicast\" | \"unicast-error\" | \"multicast-buffer\" | \"multicast-direct\" | \"replay\";\n\n/** Configuration for a many-valued sink implementation. */\nexport interface ManyOptions<T> {\n /** Delivery mode used by the sink. */\n mode: ManyMode;\n /** Maximum number of replayed values retained in history. */\n replayLimit?: number;\n /** Initial value replayed by latest-or-default sinks. */\n latestDefault?: T;\n}\n\n/** Default implementation for unicast, multicast and replay many-valued sinks. */\nexport class DefaultManySink<T> implements ManySink<T> {\n /** Active subscriber queues currently receiving live values. */\n private subscribers: SinkSubscribers<T> | undefined;\n /** Values buffered before a non-replay sink receives its first subscriber. */\n private pending: T[] | undefined;\n /** Values retained for replay subscribers. */\n private history: T[] | undefined;\n /** Ring-buffer index of the oldest replay value. */\n private historyHead = 0;\n /** Terminal state when the sink has completed or failed. */\n private terminated: \"complete\" | \"error\" | undefined;\n /** Error retained for late subscribers after failure. */\n private errorValue: unknown;\n /** Tracks whether a unicast sink already accepted its single subscriber. */\n private unicastAttached = false;\n /** Construction options controlling delivery and replay behavior. */\n private readonly options: ManyOptions<T>;\n\n /** Creates a many-valued sink with the provided delivery mode. */\n public constructor(options: ManyOptions<T>) {\n this.options = options;\n if (options.latestDefault !== undefined) {\n this.rememberHistory(options.latestDefault);\n }\n }\n\n /** Returns the Flux view of this sink. */\n public asFlux(): Flux<T> {\n return new Flux(signal => {\n const queue = new AsyncQueue<T>(signal);\n if (isUnicast(this.options.mode) && this.unicastAttached) {\n queue.error(new Error(\"Unicast sink allows only one subscriber\"));\n return queue;\n }\n if (isUnicast(this.options.mode)) {\n this.unicastAttached = true;\n }\n const history = this.history;\n if (history) {\n for (let index = 0; index < history.length; index += 1) {\n queue.push(historyValue(history, this.historyHead, index));\n }\n }\n if (this.pending && this.pending.length > 0) {\n const pending = this.pending;\n this.pending = undefined;\n for (const value of pending) {\n queue.push(value);\n }\n }\n if (this.terminated === \"complete\") {\n queue.complete();\n } else if (this.terminated === \"error\") {\n queue.error(this.errorValue);\n } else {\n this.addSubscriber(queue, signal);\n }\n return queue;\n });\n }\n\n /** Attempts to emit a value to current subscribers. */\n public tryEmitNext(value: T): EmitResult {\n if (this.terminated) {\n return EmitResult.FAIL_TERMINATED;\n }\n if (this.options.mode === \"replay\") {\n this.rememberHistory(value);\n }\n const subscribers = this.subscribers;\n if (!subscribers) {\n if (this.options.mode === \"multicast-direct\" || this.options.mode === \"unicast-error\") {\n return EmitResult.FAIL_ZERO_SUBSCRIBER;\n }\n if (this.options.mode !== \"replay\") {\n (this.pending ??= []).push(value);\n }\n return EmitResult.OK;\n }\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.push(value);\n }\n } else {\n subscribers.push(value);\n }\n return EmitResult.OK;\n }\n\n /** Attempts to complete this sink. */\n public tryEmitComplete(): EmitResult {\n if (this.terminated) {\n return EmitResult.FAIL_TERMINATED;\n }\n const subscribers = this.subscribers;\n if (this.options.mode === \"unicast-error\" && !subscribers) {\n return EmitResult.FAIL_ZERO_SUBSCRIBER;\n }\n this.terminated = \"complete\";\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.complete();\n }\n } else if (subscribers) {\n subscribers.complete();\n }\n this.clearSubscribers();\n return EmitResult.OK;\n }\n\n /** Attempts to fail this sink. */\n public tryEmitError(error: unknown): EmitResult {\n if (this.terminated) {\n return EmitResult.FAIL_TERMINATED;\n }\n const subscribers = this.subscribers;\n if (this.options.mode === \"unicast-error\" && !subscribers) {\n return EmitResult.FAIL_ZERO_SUBSCRIBER;\n }\n this.terminated = \"error\";\n this.errorValue = error;\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.error(error);\n }\n } else if (subscribers) {\n subscribers.error(error);\n }\n this.clearSubscribers();\n return EmitResult.OK;\n }\n\n /** Emits a value or delegates failure handling to the provided handler. */\n public emitNext(value: T, handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n emitOrThrow(SignalType.NEXT, () => this.tryEmitNext(value), handler);\n }\n\n /** Completes this sink or delegates failure handling to the provided handler. */\n public emitComplete(handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n emitOrThrow(SignalType.COMPLETE, () => this.tryEmitComplete(), handler);\n }\n\n /** Fails this sink or delegates failure handling to the provided handler. */\n public emitError(error: unknown, handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n emitOrThrow(SignalType.ERROR, () => this.tryEmitError(error), handler, error);\n }\n\n /** Returns the current number of active subscribers. */\n public currentSubscriberCount(): number {\n return sinkSubscriberCount(this.subscribers);\n }\n\n /** Subscribes this sink to an upstream publisher and relays its signals. */\n public subscribeTo(source: PublisherInput<T>): void {\n Flux.from(source).subscribe(\n value => this.emitNext(value),\n error => this.emitError(error),\n () => this.emitComplete()\n );\n }\n\n /** Handles an emission failure and returns false to fail fast by default. */\n public onEmitFailure(_signalType: SignalType, _emitResult: EmitResult): boolean {\n return false;\n }\n\n /** Adds a subscriber queue and removes it again when its subscription is cancelled. */\n private addSubscriber(queue: AsyncQueue<T>, signal: AbortSignal): void {\n this.subscribers = addSinkSubscriber(this.subscribers, queue);\n signal.addEventListener(\"abort\", () => this.removeSubscriber(queue), {once: true});\n }\n\n /** Removes a subscriber queue and releases the set when it becomes empty. */\n private removeSubscriber(queue: AsyncQueue<T>): void {\n this.subscribers = removeSinkSubscriber(this.subscribers, queue);\n }\n\n /** Clears and releases all active subscriber queues. */\n private clearSubscribers(): void {\n clearSinkSubscribers(this.subscribers);\n this.subscribers = undefined;\n }\n\n /** Records one value into replay history, allocating history only for replay sinks. */\n private rememberHistory(value: T): void {\n const limit = this.options.replayLimit ?? Number.POSITIVE_INFINITY;\n if (limit <= 0) {\n return;\n }\n const history = this.history;\n if (!history) {\n this.history = [value];\n this.historyHead = 0;\n return;\n }\n if (history.length < limit) {\n history.push(value);\n return;\n }\n history[this.historyHead] = value;\n this.historyHead = (this.historyHead + 1) % history.length;\n }\n}\n\n/** Returns true for sink modes that allow exactly one subscriber. */\nfunction isUnicast(mode: ManyMode): boolean {\n return mode === \"unicast\" || mode === \"unicast-error\";\n}\n\n/** Returns a replay history value in oldest-to-newest order. */\nfunction historyValue<T>(history: T[], head: number, index: number): T {\n return history[(head + index) % history.length] as T;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Mono } from "../publisher/mono.js";
|
|
2
|
+
import { SignalType } from "../signal/signal-type.js";
|
|
3
|
+
import { type EmitFailureHandler, EmitResult, type OneSink } from "./types.js";
|
|
4
|
+
/** Default replaying implementation for `Sinks.one()` and `Sinks.empty()`. */
|
|
5
|
+
export declare class DefaultOneSink<T> implements OneSink<T> {
|
|
6
|
+
/** Current terminal or pending state of the sink. */
|
|
7
|
+
private state;
|
|
8
|
+
/** Stored value replayed to late subscribers after successful termination. */
|
|
9
|
+
private value;
|
|
10
|
+
/** Stored error replayed to late subscribers after failed termination. */
|
|
11
|
+
private errorValue;
|
|
12
|
+
/** Active subscriber queues waiting for the terminal result, created only when needed. */
|
|
13
|
+
private subscribers;
|
|
14
|
+
/** Returns the Mono view of this sink. */
|
|
15
|
+
asMono(): Mono<T>;
|
|
16
|
+
/** Attempts to emit a value and complete this sink. */
|
|
17
|
+
tryEmitValue(value: T): EmitResult;
|
|
18
|
+
/** Attempts to complete this sink without a value. */
|
|
19
|
+
tryEmitEmpty(): EmitResult;
|
|
20
|
+
/** Attempts to fail this sink. */
|
|
21
|
+
tryEmitError(error: unknown): EmitResult;
|
|
22
|
+
/** Emits a value or delegates failure handling to the provided handler. */
|
|
23
|
+
emitValue(value: T, handler?: EmitFailureHandler): void;
|
|
24
|
+
/** Completes this sink or delegates failure handling to the provided handler. */
|
|
25
|
+
emitEmpty(handler?: EmitFailureHandler): void;
|
|
26
|
+
/** Fails this sink or delegates failure handling to the provided handler. */
|
|
27
|
+
emitError(error: unknown, handler?: EmitFailureHandler): void;
|
|
28
|
+
/** Returns the current number of active subscribers. */
|
|
29
|
+
currentSubscriberCount(): number;
|
|
30
|
+
/** Handles an emission failure and returns false to fail fast by default. */
|
|
31
|
+
onEmitFailure(_signalType: SignalType, _emitResult: EmitResult): boolean;
|
|
32
|
+
/** Adds a subscriber queue and removes it again when its subscription is cancelled. */
|
|
33
|
+
private addSubscriber;
|
|
34
|
+
/** Removes a subscriber queue and releases the set when it becomes empty. */
|
|
35
|
+
private removeSubscriber;
|
|
36
|
+
/** Clears and releases all active subscriber queues. */
|
|
37
|
+
private clearSubscribers;
|
|
38
|
+
/** Replays the current state into a newly subscribed queue. */
|
|
39
|
+
private replay;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=one.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one.d.ts","sourceRoot":"","sources":["../../src/sinks/one.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAQnD,OAAO,EAAC,KAAK,kBAAkB,EAAoC,UAAU,EAAE,KAAK,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAKrH,8EAA8E;AAC9E,qBAAa,cAAc,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAChD,qDAAqD;IACrD,OAAO,CAAC,KAAK,CAAuB;IACpC,8EAA8E;IAC9E,OAAO,CAAC,KAAK,CAAgB;IAC7B,0EAA0E;IAC1E,OAAO,CAAC,UAAU,CAAU;IAC5B,0FAA0F;IAC1F,OAAO,CAAC,WAAW,CAAiC;IAEpD,0CAA0C;IACnC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CASvB;IAED,uDAAuD;IAChD,YAAY,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,CAkBxC;IAED,sDAAsD;IAC/C,YAAY,IAAI,UAAU,CAehC;IAED,kCAAkC;IAC3B,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAgB9C;IAED,2EAA2E;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,kBAAkD,GAAG,IAAI,CAK5F;IAED,iFAAiF;IAC1E,SAAS,CAAC,OAAO,GAAE,kBAAkD,GAAG,IAAI,CAKlF;IAED,6EAA6E;IACtE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAkD,GAAG,IAAI,CAKlG;IAED,wDAAwD;IACjD,sBAAsB,IAAI,MAAM,CAEtC;IAED,6EAA6E;IACtE,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,GAAG,OAAO,CAE9E;IAED,uFAAuF;IACvF,OAAO,CAAC,aAAa;IAKrB,6EAA6E;IAC7E,OAAO,CAAC,gBAAgB;IAIxB,wDAAwD;IACxD,OAAO,CAAC,gBAAgB;IAKxB,+DAA+D;IAC/D,OAAO,CAAC,MAAM;CAgBjB"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.139.0/helpers/esm/defineProperty.js";
|
|
2
|
+
import { AsyncQueue } from "../internal/async-queue.js";
|
|
3
|
+
import { SignalType } from "../signal/signal-type.js";
|
|
4
|
+
import { Mono } from "../publisher/mono.js";
|
|
5
|
+
import { addSinkSubscriber, clearSinkSubscribers, removeSinkSubscriber, sinkSubscriberCount } from "./subscribers.js";
|
|
6
|
+
import { EmitFailureHandlers, EmitResult, emitOrThrow } from "./types.js";
|
|
7
|
+
//#region src/sinks/one.ts
|
|
8
|
+
/**
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
* Sink specifications and default browser-oriented sink implementations.
|
|
11
|
+
*/
|
|
12
|
+
/** Default replaying implementation for `Sinks.one()` and `Sinks.empty()`. */
|
|
13
|
+
var DefaultOneSink = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
_defineProperty(
|
|
16
|
+
this,
|
|
17
|
+
/** Current terminal or pending state of the sink. */
|
|
18
|
+
"state",
|
|
19
|
+
"pending"
|
|
20
|
+
);
|
|
21
|
+
_defineProperty(
|
|
22
|
+
this,
|
|
23
|
+
/** Stored value replayed to late subscribers after successful termination. */
|
|
24
|
+
"value",
|
|
25
|
+
void 0
|
|
26
|
+
);
|
|
27
|
+
_defineProperty(
|
|
28
|
+
this,
|
|
29
|
+
/** Stored error replayed to late subscribers after failed termination. */
|
|
30
|
+
"errorValue",
|
|
31
|
+
void 0
|
|
32
|
+
);
|
|
33
|
+
_defineProperty(
|
|
34
|
+
this,
|
|
35
|
+
/** Active subscriber queues waiting for the terminal result, created only when needed. */
|
|
36
|
+
"subscribers",
|
|
37
|
+
void 0
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
/** Returns the Mono view of this sink. */
|
|
41
|
+
asMono() {
|
|
42
|
+
return new Mono((signal) => {
|
|
43
|
+
const queue = new AsyncQueue(signal);
|
|
44
|
+
this.replay(queue);
|
|
45
|
+
if (this.state === "pending") this.addSubscriber(queue, signal);
|
|
46
|
+
return queue;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Attempts to emit a value and complete this sink. */
|
|
50
|
+
tryEmitValue(value) {
|
|
51
|
+
if (this.state !== "pending") return EmitResult.FAIL_TERMINATED;
|
|
52
|
+
this.state = "value";
|
|
53
|
+
this.value = value;
|
|
54
|
+
const subscribers = this.subscribers;
|
|
55
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) {
|
|
56
|
+
subscriber.push(value);
|
|
57
|
+
subscriber.complete();
|
|
58
|
+
}
|
|
59
|
+
else if (subscribers) {
|
|
60
|
+
subscribers.push(value);
|
|
61
|
+
subscribers.complete();
|
|
62
|
+
}
|
|
63
|
+
this.clearSubscribers();
|
|
64
|
+
return EmitResult.OK;
|
|
65
|
+
}
|
|
66
|
+
/** Attempts to complete this sink without a value. */
|
|
67
|
+
tryEmitEmpty() {
|
|
68
|
+
if (this.state !== "pending") return EmitResult.FAIL_TERMINATED;
|
|
69
|
+
this.state = "empty";
|
|
70
|
+
const subscribers = this.subscribers;
|
|
71
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) subscriber.complete();
|
|
72
|
+
else if (subscribers) subscribers.complete();
|
|
73
|
+
this.clearSubscribers();
|
|
74
|
+
return EmitResult.OK;
|
|
75
|
+
}
|
|
76
|
+
/** Attempts to fail this sink. */
|
|
77
|
+
tryEmitError(error) {
|
|
78
|
+
if (this.state !== "pending") return EmitResult.FAIL_TERMINATED;
|
|
79
|
+
this.state = "error";
|
|
80
|
+
this.errorValue = error;
|
|
81
|
+
const subscribers = this.subscribers;
|
|
82
|
+
if (subscribers instanceof Set) for (const subscriber of subscribers) subscriber.error(error);
|
|
83
|
+
else if (subscribers) subscribers.error(error);
|
|
84
|
+
this.clearSubscribers();
|
|
85
|
+
return EmitResult.OK;
|
|
86
|
+
}
|
|
87
|
+
/** Emits a value or delegates failure handling to the provided handler. */
|
|
88
|
+
emitValue(value, handler = EmitFailureHandlers.FAIL_FAST) {
|
|
89
|
+
const result = this.tryEmitValue(value);
|
|
90
|
+
if (result !== EmitResult.FAIL_TERMINATED) emitOrThrow(SignalType.NEXT, () => result, handler);
|
|
91
|
+
}
|
|
92
|
+
/** Completes this sink or delegates failure handling to the provided handler. */
|
|
93
|
+
emitEmpty(handler = EmitFailureHandlers.FAIL_FAST) {
|
|
94
|
+
const result = this.tryEmitEmpty();
|
|
95
|
+
if (result !== EmitResult.FAIL_TERMINATED) emitOrThrow(SignalType.COMPLETE, () => result, handler);
|
|
96
|
+
}
|
|
97
|
+
/** Fails this sink or delegates failure handling to the provided handler. */
|
|
98
|
+
emitError(error, handler = EmitFailureHandlers.FAIL_FAST) {
|
|
99
|
+
const result = this.tryEmitError(error);
|
|
100
|
+
if (result !== EmitResult.FAIL_TERMINATED) emitOrThrow(SignalType.ERROR, () => result, handler, error);
|
|
101
|
+
}
|
|
102
|
+
/** Returns the current number of active subscribers. */
|
|
103
|
+
currentSubscriberCount() {
|
|
104
|
+
return sinkSubscriberCount(this.subscribers);
|
|
105
|
+
}
|
|
106
|
+
/** Handles an emission failure and returns false to fail fast by default. */
|
|
107
|
+
onEmitFailure(_signalType, _emitResult) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/** Adds a subscriber queue and removes it again when its subscription is cancelled. */
|
|
111
|
+
addSubscriber(queue, signal) {
|
|
112
|
+
this.subscribers = addSinkSubscriber(this.subscribers, queue);
|
|
113
|
+
signal.addEventListener("abort", () => this.removeSubscriber(queue), { once: true });
|
|
114
|
+
}
|
|
115
|
+
/** Removes a subscriber queue and releases the set when it becomes empty. */
|
|
116
|
+
removeSubscriber(queue) {
|
|
117
|
+
this.subscribers = removeSinkSubscriber(this.subscribers, queue);
|
|
118
|
+
}
|
|
119
|
+
/** Clears and releases all active subscriber queues. */
|
|
120
|
+
clearSubscribers() {
|
|
121
|
+
clearSinkSubscribers(this.subscribers);
|
|
122
|
+
this.subscribers = void 0;
|
|
123
|
+
}
|
|
124
|
+
/** Replays the current state into a newly subscribed queue. */
|
|
125
|
+
replay(queue) {
|
|
126
|
+
switch (this.state) {
|
|
127
|
+
case "value":
|
|
128
|
+
queue.push(this.value);
|
|
129
|
+
queue.complete();
|
|
130
|
+
break;
|
|
131
|
+
case "empty":
|
|
132
|
+
queue.complete();
|
|
133
|
+
break;
|
|
134
|
+
case "error":
|
|
135
|
+
queue.error(this.errorValue);
|
|
136
|
+
break;
|
|
137
|
+
case "pending": break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
//#endregion
|
|
142
|
+
export { DefaultOneSink };
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=one.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one.js","names":[],"sources":["../../src/sinks/one.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Sink specifications and default browser-oriented sink implementations.\n */\nimport {AsyncQueue} from \"@/internal/async-queue.js\";\nimport {Mono} from \"@/publisher/mono.js\";\nimport {SignalType} from \"@/signal/signal-type.js\";\nimport {\n addSinkSubscriber,\n clearSinkSubscribers,\n removeSinkSubscriber,\n sinkSubscriberCount,\n type SinkSubscribers\n} from \"@/sinks/subscribers.js\";\nimport {type EmitFailureHandler, EmitFailureHandlers, emitOrThrow, EmitResult, type OneSink} from \"@/sinks/types.js\";\n\n/** Terminal or pending state held by a one-valued sink. */\ntype OneState = \"pending\" | \"empty\" | \"value\" | \"error\";\n\n/** Default replaying implementation for `Sinks.one()` and `Sinks.empty()`. */\nexport class DefaultOneSink<T> implements OneSink<T> {\n /** Current terminal or pending state of the sink. */\n private state: OneState = \"pending\";\n /** Stored value replayed to late subscribers after successful termination. */\n private value: T | undefined;\n /** Stored error replayed to late subscribers after failed termination. */\n private errorValue: unknown;\n /** Active subscriber queues waiting for the terminal result, created only when needed. */\n private subscribers: SinkSubscribers<T> | undefined;\n\n /** Returns the Mono view of this sink. */\n public asMono(): Mono<T> {\n return new Mono(signal => {\n const queue = new AsyncQueue<T>(signal);\n this.replay(queue);\n if (this.state === \"pending\") {\n this.addSubscriber(queue, signal);\n }\n return queue;\n });\n }\n\n /** Attempts to emit a value and complete this sink. */\n public tryEmitValue(value: T): EmitResult {\n if (this.state !== \"pending\") {\n return EmitResult.FAIL_TERMINATED;\n }\n this.state = \"value\";\n this.value = value;\n const subscribers = this.subscribers;\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.push(value);\n subscriber.complete();\n }\n } else if (subscribers) {\n subscribers.push(value);\n subscribers.complete();\n }\n this.clearSubscribers();\n return EmitResult.OK;\n }\n\n /** Attempts to complete this sink without a value. */\n public tryEmitEmpty(): EmitResult {\n if (this.state !== \"pending\") {\n return EmitResult.FAIL_TERMINATED;\n }\n this.state = \"empty\";\n const subscribers = this.subscribers;\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.complete();\n }\n } else if (subscribers) {\n subscribers.complete();\n }\n this.clearSubscribers();\n return EmitResult.OK;\n }\n\n /** Attempts to fail this sink. */\n public tryEmitError(error: unknown): EmitResult {\n if (this.state !== \"pending\") {\n return EmitResult.FAIL_TERMINATED;\n }\n this.state = \"error\";\n this.errorValue = error;\n const subscribers = this.subscribers;\n if (subscribers instanceof Set) {\n for (const subscriber of subscribers) {\n subscriber.error(error);\n }\n } else if (subscribers) {\n subscribers.error(error);\n }\n this.clearSubscribers();\n return EmitResult.OK;\n }\n\n /** Emits a value or delegates failure handling to the provided handler. */\n public emitValue(value: T, handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n const result = this.tryEmitValue(value);\n if (result !== EmitResult.FAIL_TERMINATED) {\n emitOrThrow(SignalType.NEXT, () => result, handler);\n }\n }\n\n /** Completes this sink or delegates failure handling to the provided handler. */\n public emitEmpty(handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n const result = this.tryEmitEmpty();\n if (result !== EmitResult.FAIL_TERMINATED) {\n emitOrThrow(SignalType.COMPLETE, () => result, handler);\n }\n }\n\n /** Fails this sink or delegates failure handling to the provided handler. */\n public emitError(error: unknown, handler: EmitFailureHandler = EmitFailureHandlers.FAIL_FAST): void {\n const result = this.tryEmitError(error);\n if (result !== EmitResult.FAIL_TERMINATED) {\n emitOrThrow(SignalType.ERROR, () => result, handler, error);\n }\n }\n\n /** Returns the current number of active subscribers. */\n public currentSubscriberCount(): number {\n return sinkSubscriberCount(this.subscribers);\n }\n\n /** Handles an emission failure and returns false to fail fast by default. */\n public onEmitFailure(_signalType: SignalType, _emitResult: EmitResult): boolean {\n return false;\n }\n\n /** Adds a subscriber queue and removes it again when its subscription is cancelled. */\n private addSubscriber(queue: AsyncQueue<T>, signal: AbortSignal): void {\n this.subscribers = addSinkSubscriber(this.subscribers, queue);\n signal.addEventListener(\"abort\", () => this.removeSubscriber(queue), {once: true});\n }\n\n /** Removes a subscriber queue and releases the set when it becomes empty. */\n private removeSubscriber(queue: AsyncQueue<T>): void {\n this.subscribers = removeSinkSubscriber(this.subscribers, queue);\n }\n\n /** Clears and releases all active subscriber queues. */\n private clearSubscribers(): void {\n clearSinkSubscribers(this.subscribers);\n this.subscribers = undefined;\n }\n\n /** Replays the current state into a newly subscribed queue. */\n private replay(queue: AsyncQueue<T>): void {\n switch (this.state) {\n case \"value\":\n queue.push(this.value as T);\n queue.complete();\n break;\n case \"empty\":\n queue.complete();\n break;\n case \"error\":\n queue.error(this.errorValue);\n break;\n case \"pending\":\n break;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAa,iBAAb,MAAqD;;;;;GAEjD;GAA0B;;;;;GAE1B;;;;;;GAEA;;;;;;GAEA;;;;;CAGA,SAAyB;EACrB,OAAO,IAAI,MAAK,WAAU;GACtB,MAAM,QAAQ,IAAI,WAAc,MAAM;GACtC,KAAK,OAAO,KAAK;GACjB,IAAI,KAAK,UAAU,WACf,KAAK,cAAc,OAAO,MAAM;GAEpC,OAAO;EACX,CAAC;CACL;;CAGA,aAAoB,OAAsB;EACtC,IAAI,KAAK,UAAU,WACf,OAAO,WAAW;EAEtB,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,MAAM,cAAc,KAAK;EACzB,IAAI,uBAAuB,KACvB,KAAK,MAAM,cAAc,aAAa;GAClC,WAAW,KAAK,KAAK;GACrB,WAAW,SAAS;EACxB;OACG,IAAI,aAAa;GACpB,YAAY,KAAK,KAAK;GACtB,YAAY,SAAS;EACzB;EACA,KAAK,iBAAiB;EACtB,OAAO,WAAW;CACtB;;CAGA,eAAkC;EAC9B,IAAI,KAAK,UAAU,WACf,OAAO,WAAW;EAEtB,KAAK,QAAQ;EACb,MAAM,cAAc,KAAK;EACzB,IAAI,uBAAuB,KACvB,KAAK,MAAM,cAAc,aACrB,WAAW,SAAS;OAErB,IAAI,aACP,YAAY,SAAS;EAEzB,KAAK,iBAAiB;EACtB,OAAO,WAAW;CACtB;;CAGA,aAAoB,OAA4B;EAC5C,IAAI,KAAK,UAAU,WACf,OAAO,WAAW;EAEtB,KAAK,QAAQ;EACb,KAAK,aAAa;EAClB,MAAM,cAAc,KAAK;EACzB,IAAI,uBAAuB,KACvB,KAAK,MAAM,cAAc,aACrB,WAAW,MAAM,KAAK;OAEvB,IAAI,aACP,YAAY,MAAM,KAAK;EAE3B,KAAK,iBAAiB;EACtB,OAAO,WAAW;CACtB;;CAGA,UAAiB,OAAU,UAA8B,oBAAoB,WAAiB;EAC1F,MAAM,SAAS,KAAK,aAAa,KAAK;EACtC,IAAI,WAAW,WAAW,iBACtB,YAAY,WAAW,YAAY,QAAQ,OAAO;CAE1D;;CAGA,UAAiB,UAA8B,oBAAoB,WAAiB;EAChF,MAAM,SAAS,KAAK,aAAa;EACjC,IAAI,WAAW,WAAW,iBACtB,YAAY,WAAW,gBAAgB,QAAQ,OAAO;CAE9D;;CAGA,UAAiB,OAAgB,UAA8B,oBAAoB,WAAiB;EAChG,MAAM,SAAS,KAAK,aAAa,KAAK;EACtC,IAAI,WAAW,WAAW,iBACtB,YAAY,WAAW,aAAa,QAAQ,SAAS,KAAK;CAElE;;CAGA,yBAAwC;EACpC,OAAO,oBAAoB,KAAK,WAAW;CAC/C;;CAGA,cAAqB,aAAyB,aAAkC;EAC5E,OAAO;CACX;;CAGA,cAAsB,OAAsB,QAA2B;EACnE,KAAK,cAAc,kBAAkB,KAAK,aAAa,KAAK;EAC5D,OAAO,iBAAiB,eAAe,KAAK,iBAAiB,KAAK,GAAG,EAAC,MAAM,KAAI,CAAC;CACrF;;CAGA,iBAAyB,OAA4B;EACjD,KAAK,cAAc,qBAAqB,KAAK,aAAa,KAAK;CACnE;;CAGA,mBAAiC;EAC7B,qBAAqB,KAAK,WAAW;EACrC,KAAK,cAAc;CACvB;;CAGA,OAAe,OAA4B;EACvC,QAAQ,KAAK,OAAb;GACI,KAAK;IACD,MAAM,KAAK,KAAK,KAAU;IAC1B,MAAM,SAAS;IACf;GACJ,KAAK;IACD,MAAM,SAAS;IACf;GACJ,KAAK;IACD,MAAM,MAAM,KAAK,UAAU;IAC3B;GACJ,KAAK,WACD;EACR;CACJ;AACJ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EmptySink, ManySink, ManySpec, ManyWithUpstreamSpec, OneSink } from "./types.js";
|
|
2
|
+
/** Builder tree for unsafe sinks that can subscribe to upstream publishers. */
|
|
3
|
+
declare const unsafeSpec: {
|
|
4
|
+
/** Creates an empty sink that can only terminate. */
|
|
5
|
+
empty<T>(): EmptySink<T>;
|
|
6
|
+
/** Creates a one-valued sink that replays its terminal result. */
|
|
7
|
+
one<T>(): OneSink<T>;
|
|
8
|
+
/** Returns builders for many-valued sinks. */
|
|
9
|
+
many(): ManySpec;
|
|
10
|
+
/** Returns builders for many-valued sinks that can subscribe to one upstream publisher. */
|
|
11
|
+
manyWithUpstream(): ManyWithUpstreamSpec;
|
|
12
|
+
};
|
|
13
|
+
/** Public Sinks factory facade. */
|
|
14
|
+
export declare const Sinks: Readonly<{
|
|
15
|
+
/** Creates an empty sink that can only terminate. */
|
|
16
|
+
empty<T>(): EmptySink<T>;
|
|
17
|
+
/** Creates a one-valued sink that replays its terminal result. */
|
|
18
|
+
one<T>(): OneSink<T>;
|
|
19
|
+
/** Returns builders for many-valued sinks. */
|
|
20
|
+
many(): ManySpec;
|
|
21
|
+
/** Returns unsafe sink builders. */
|
|
22
|
+
unsafe(): typeof unsafeSpec;
|
|
23
|
+
}>;
|
|
24
|
+
export type { ManySink };
|
|
25
|
+
//# sourceMappingURL=specs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specs.d.ts","sourceRoot":"","sources":["../../src/sinks/specs.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,oBAAoB,EAEpB,OAAO,EAGR,MAAM,kBAAkB,CAAC;AAqF1B,+EAA+E;AAC/E,QAAA,MAAM,UAAU,EAAE;IACd,qDAAqD;IACrD,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IACzB,kEAAkE;IAClE,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,8CAA8C;IAC9C,IAAI,IAAI,QAAQ,CAAC;IACjB,2FAA2F;IAC3F,gBAAgB,IAAI,oBAAoB,CAAC;CAqB3C,CAAC;AAEH,mCAAmC;AACnC,eAAO,MAAM,KAAK;IACd,qDAAqD;UAC/C,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IAIxB,kEAAkE;QAC9D,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IAIpB,8CAA8C;YACtC,QAAQ;IAIhB,oCAAoC;cAC1B,OAAO,UAAU;EAG7B,CAAC;AAEH,YAAY,EAAC,QAAQ,EAAC,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { DefaultManySink } from "./many.js";
|
|
2
|
+
import { DefaultOneSink } from "./one.js";
|
|
3
|
+
//#region src/sinks/specs.ts
|
|
4
|
+
/**
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
* Sink specifications and default browser-oriented sink implementations.
|
|
7
|
+
*/
|
|
8
|
+
/** Shared builders for unicast many-valued sinks. */
|
|
9
|
+
var unicastSpec = Object.freeze({
|
|
10
|
+
/** Creates a unicast sink with backpressure buffering. */
|
|
11
|
+
onBackpressureBuffer() {
|
|
12
|
+
return new DefaultManySink({ mode: "unicast" });
|
|
13
|
+
},
|
|
14
|
+
/** Creates a unicast sink that fails emission when demand cannot be honored. */
|
|
15
|
+
onBackpressureError() {
|
|
16
|
+
return new DefaultManySink({ mode: "unicast-error" });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
/** Shared builders for multicast many-valued sinks. */
|
|
20
|
+
var multicastSpec = Object.freeze({
|
|
21
|
+
/** Creates a multicast sink that buffers when subscribers are temporarily absent. */
|
|
22
|
+
onBackpressureBuffer() {
|
|
23
|
+
return new DefaultManySink({ mode: "multicast-buffer" });
|
|
24
|
+
},
|
|
25
|
+
/** Creates a multicast sink that fails emission when no subscriber can receive it. */
|
|
26
|
+
directAllOrNothing() {
|
|
27
|
+
return new DefaultManySink({ mode: "multicast-direct" });
|
|
28
|
+
},
|
|
29
|
+
/** Creates a multicast sink that emits to currently available subscribers. */
|
|
30
|
+
directBestEffort() {
|
|
31
|
+
return new DefaultManySink({ mode: "multicast-direct" });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
/** Shared builders for replaying many-valued sinks. */
|
|
35
|
+
var replaySpec = Object.freeze({
|
|
36
|
+
/** Creates a replay sink retaining every emitted value. */
|
|
37
|
+
all() {
|
|
38
|
+
return new DefaultManySink({ mode: "replay" });
|
|
39
|
+
},
|
|
40
|
+
/** Creates a replay sink retaining at most `historySize` values. */
|
|
41
|
+
limit(historySize) {
|
|
42
|
+
if (!Number.isInteger(historySize) || historySize <= 0) throw new RangeError("historySize must be a strictly positive integer");
|
|
43
|
+
return new DefaultManySink({
|
|
44
|
+
mode: "replay",
|
|
45
|
+
replayLimit: historySize
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
/** Creates a replay sink retaining only the latest emitted value. */
|
|
49
|
+
latest() {
|
|
50
|
+
return new DefaultManySink({
|
|
51
|
+
mode: "replay",
|
|
52
|
+
replayLimit: 1
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
/** Creates a replay sink with an initial default latest value. */
|
|
56
|
+
latestOrDefault(value) {
|
|
57
|
+
return new DefaultManySink({
|
|
58
|
+
mode: "replay",
|
|
59
|
+
replayLimit: 1,
|
|
60
|
+
latestDefault: value
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
/** Shared builder tree for many-valued sink variants. */
|
|
65
|
+
var manySpec = Object.freeze({
|
|
66
|
+
/** Returns builders for unicast many-valued sinks. */
|
|
67
|
+
unicast() {
|
|
68
|
+
return unicastSpec;
|
|
69
|
+
},
|
|
70
|
+
/** Returns builders for multicast many-valued sinks. */
|
|
71
|
+
multicast() {
|
|
72
|
+
return multicastSpec;
|
|
73
|
+
},
|
|
74
|
+
/** Returns builders for replaying many-valued sinks. */
|
|
75
|
+
replay() {
|
|
76
|
+
return replaySpec;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
/** Shared unsafe builders for many-valued sinks that subscribe to upstream publishers. */
|
|
80
|
+
var manyWithUpstreamSpec = Object.freeze({
|
|
81
|
+
/** Creates a multicast sink that buffers and can subscribe to one upstream publisher. */
|
|
82
|
+
multicastOnBackpressureBuffer() {
|
|
83
|
+
return new DefaultManySink({ mode: "multicast-buffer" });
|
|
84
|
+
} });
|
|
85
|
+
/** Builder tree for unsafe sinks that can subscribe to upstream publishers. */
|
|
86
|
+
var unsafeSpec = Object.freeze({
|
|
87
|
+
/** Creates an empty sink that can only terminate. */
|
|
88
|
+
empty() {
|
|
89
|
+
return new DefaultOneSink();
|
|
90
|
+
},
|
|
91
|
+
/** Creates a one-valued sink that replays its terminal result. */
|
|
92
|
+
one() {
|
|
93
|
+
return new DefaultOneSink();
|
|
94
|
+
},
|
|
95
|
+
/** Returns builders for many-valued sinks. */
|
|
96
|
+
many() {
|
|
97
|
+
return manySpec;
|
|
98
|
+
},
|
|
99
|
+
/** Returns builders for many-valued sinks that can subscribe to one upstream publisher. */
|
|
100
|
+
manyWithUpstream() {
|
|
101
|
+
return manyWithUpstreamSpec;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
/** Public Sinks factory facade. */
|
|
105
|
+
var Sinks = Object.freeze({
|
|
106
|
+
/** Creates an empty sink that can only terminate. */
|
|
107
|
+
empty() {
|
|
108
|
+
return new DefaultOneSink();
|
|
109
|
+
},
|
|
110
|
+
/** Creates a one-valued sink that replays its terminal result. */
|
|
111
|
+
one() {
|
|
112
|
+
return new DefaultOneSink();
|
|
113
|
+
},
|
|
114
|
+
/** Returns builders for many-valued sinks. */
|
|
115
|
+
many() {
|
|
116
|
+
return manySpec;
|
|
117
|
+
},
|
|
118
|
+
/** Returns unsafe sink builders. */
|
|
119
|
+
unsafe() {
|
|
120
|
+
return unsafeSpec;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
//#endregion
|
|
124
|
+
export { Sinks };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specs.js","names":[],"sources":["../../src/sinks/specs.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Sink specifications and default browser-oriented sink implementations.\n */\nimport {DefaultManySink} from \"@/sinks/many.js\";\nimport {DefaultOneSink} from \"@/sinks/one.js\";\nimport type {\n EmptySink,\n ManySink,\n ManySpec,\n ManyWithUpstreamSpec,\n MulticastSpec,\n OneSink,\n ReplaySpec,\n UnicastSpec\n} from \"@/sinks/types.js\";\n\n/** Shared builders for unicast many-valued sinks. */\nconst unicastSpec: UnicastSpec = Object.freeze({\n /** Creates a unicast sink with backpressure buffering. */\n onBackpressureBuffer<T>() {\n return new DefaultManySink<T>({mode: \"unicast\"});\n },\n\n /** Creates a unicast sink that fails emission when demand cannot be honored. */\n onBackpressureError<T>() {\n return new DefaultManySink<T>({mode: \"unicast-error\"});\n }\n});\n\n/** Shared builders for multicast many-valued sinks. */\nconst multicastSpec: MulticastSpec = Object.freeze({\n /** Creates a multicast sink that buffers when subscribers are temporarily absent. */\n onBackpressureBuffer<T>() {\n return new DefaultManySink<T>({mode: \"multicast-buffer\"});\n },\n\n /** Creates a multicast sink that fails emission when no subscriber can receive it. */\n directAllOrNothing<T>() {\n return new DefaultManySink<T>({mode: \"multicast-direct\"});\n },\n\n /** Creates a multicast sink that emits to currently available subscribers. */\n directBestEffort<T>() {\n return new DefaultManySink<T>({mode: \"multicast-direct\"});\n }\n});\n\n/** Shared builders for replaying many-valued sinks. */\nconst replaySpec: ReplaySpec = Object.freeze({\n /** Creates a replay sink retaining every emitted value. */\n all<T>() {\n return new DefaultManySink<T>({mode: \"replay\"});\n },\n\n /** Creates a replay sink retaining at most `historySize` values. */\n limit<T>(historySize: number) {\n if (!Number.isInteger(historySize) || historySize <= 0) {\n throw new RangeError(\"historySize must be a strictly positive integer\");\n }\n return new DefaultManySink<T>({mode: \"replay\", replayLimit: historySize});\n },\n\n /** Creates a replay sink retaining only the latest emitted value. */\n latest<T>() {\n return new DefaultManySink<T>({mode: \"replay\", replayLimit: 1});\n },\n\n /** Creates a replay sink with an initial default latest value. */\n latestOrDefault<T>(value: T) {\n return new DefaultManySink<T>({mode: \"replay\", replayLimit: 1, latestDefault: value});\n }\n});\n\n/** Shared builder tree for many-valued sink variants. */\nconst manySpec: ManySpec = Object.freeze({\n /** Returns builders for unicast many-valued sinks. */\n unicast(): UnicastSpec {\n return unicastSpec;\n },\n\n /** Returns builders for multicast many-valued sinks. */\n multicast(): MulticastSpec {\n return multicastSpec;\n },\n\n /** Returns builders for replaying many-valued sinks. */\n replay(): ReplaySpec {\n return replaySpec;\n }\n});\n\n/** Shared unsafe builders for many-valued sinks that subscribe to upstream publishers. */\nconst manyWithUpstreamSpec: ManyWithUpstreamSpec = Object.freeze({\n /** Creates a multicast sink that buffers and can subscribe to one upstream publisher. */\n multicastOnBackpressureBuffer<T>() {\n return new DefaultManySink<T>({mode: \"multicast-buffer\"});\n }\n});\n\n/** Builder tree for unsafe sinks that can subscribe to upstream publishers. */\nconst unsafeSpec: {\n /** Creates an empty sink that can only terminate. */\n empty<T>(): EmptySink<T>;\n /** Creates a one-valued sink that replays its terminal result. */\n one<T>(): OneSink<T>;\n /** Returns builders for many-valued sinks. */\n many(): ManySpec;\n /** Returns builders for many-valued sinks that can subscribe to one upstream publisher. */\n manyWithUpstream(): ManyWithUpstreamSpec;\n} = Object.freeze({\n /** Creates an empty sink that can only terminate. */\n empty<T>(): EmptySink<T> {\n return new DefaultOneSink<T>();\n },\n\n /** Creates a one-valued sink that replays its terminal result. */\n one<T>(): OneSink<T> {\n return new DefaultOneSink<T>();\n },\n\n /** Returns builders for many-valued sinks. */\n many(): ManySpec {\n return manySpec;\n },\n\n /** Returns builders for many-valued sinks that can subscribe to one upstream publisher. */\n manyWithUpstream(): ManyWithUpstreamSpec {\n return manyWithUpstreamSpec;\n }\n});\n\n/** Public Sinks factory facade. */\nexport const Sinks = Object.freeze({\n /** Creates an empty sink that can only terminate. */\n empty<T>(): EmptySink<T> {\n return new DefaultOneSink<T>();\n },\n\n /** Creates a one-valued sink that replays its terminal result. */\n one<T>(): OneSink<T> {\n return new DefaultOneSink<T>();\n },\n\n /** Returns builders for many-valued sinks. */\n many(): ManySpec {\n return manySpec;\n },\n\n /** Returns unsafe sink builders. */\n unsafe(): typeof unsafeSpec {\n return unsafeSpec;\n }\n});\n\nexport type {ManySink};\n"],"mappings":";;;;;;;;AAkBA,IAAM,cAA2B,OAAO,OAAO;;CAE3C,uBAA0B;EACtB,OAAO,IAAI,gBAAmB,EAAC,MAAM,UAAS,CAAC;CACnD;;CAGA,sBAAyB;EACrB,OAAO,IAAI,gBAAmB,EAAC,MAAM,gBAAe,CAAC;CACzD;AACJ,CAAC;;AAGD,IAAM,gBAA+B,OAAO,OAAO;;CAE/C,uBAA0B;EACtB,OAAO,IAAI,gBAAmB,EAAC,MAAM,mBAAkB,CAAC;CAC5D;;CAGA,qBAAwB;EACpB,OAAO,IAAI,gBAAmB,EAAC,MAAM,mBAAkB,CAAC;CAC5D;;CAGA,mBAAsB;EAClB,OAAO,IAAI,gBAAmB,EAAC,MAAM,mBAAkB,CAAC;CAC5D;AACJ,CAAC;;AAGD,IAAM,aAAyB,OAAO,OAAO;;CAEzC,MAAS;EACL,OAAO,IAAI,gBAAmB,EAAC,MAAM,SAAQ,CAAC;CAClD;;CAGA,MAAS,aAAqB;EAC1B,IAAI,CAAC,OAAO,UAAU,WAAW,KAAK,eAAe,GACjD,MAAM,IAAI,WAAW,iDAAiD;EAE1E,OAAO,IAAI,gBAAmB;GAAC,MAAM;GAAU,aAAa;EAAW,CAAC;CAC5E;;CAGA,SAAY;EACR,OAAO,IAAI,gBAAmB;GAAC,MAAM;GAAU,aAAa;EAAC,CAAC;CAClE;;CAGA,gBAAmB,OAAU;EACzB,OAAO,IAAI,gBAAmB;GAAC,MAAM;GAAU,aAAa;GAAG,eAAe;EAAK,CAAC;CACxF;AACJ,CAAC;;AAGD,IAAM,WAAqB,OAAO,OAAO;;CAErC,UAAuB;EACnB,OAAO;CACX;;CAGA,YAA2B;EACvB,OAAO;CACX;;CAGA,SAAqB;EACjB,OAAO;CACX;AACJ,CAAC;;AAGD,IAAM,uBAA6C,OAAO,OAAO;;AAE7D,gCAAmC;CAC/B,OAAO,IAAI,gBAAmB,EAAC,MAAM,mBAAkB,CAAC;AAC5D,EACJ,CAAC;;AAGD,IAAM,aASF,OAAO,OAAO;;CAEd,QAAyB;EACrB,OAAO,IAAI,eAAkB;CACjC;;CAGA,MAAqB;EACjB,OAAO,IAAI,eAAkB;CACjC;;CAGA,OAAiB;EACb,OAAO;CACX;;CAGA,mBAAyC;EACrC,OAAO;CACX;AACJ,CAAC;;AAGD,IAAa,QAAQ,OAAO,OAAO;;CAE/B,QAAyB;EACrB,OAAO,IAAI,eAAkB;CACjC;;CAGA,MAAqB;EACjB,OAAO,IAAI,eAAkB;CACjC;;CAGA,OAAiB;EACb,OAAO;CACX;;CAGA,SAA4B;EACxB,OAAO;CACX;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Compact subscriber storage shared by sink implementations.
|
|
4
|
+
*/
|
|
5
|
+
import type { AsyncQueue } from "../internal/async-queue.js";
|
|
6
|
+
/** Compact storage for one or many active sink subscriber queues. */
|
|
7
|
+
export type SinkSubscribers<T> = AsyncQueue<T> | Set<AsyncQueue<T>>;
|
|
8
|
+
/** Adds a queue without allocating a Set for the common single-subscriber case. */
|
|
9
|
+
export declare function addSinkSubscriber<T>(subscribers: SinkSubscribers<T> | undefined, queue: AsyncQueue<T>): SinkSubscribers<T>;
|
|
10
|
+
/** Removes a queue and releases multi-subscriber storage when it becomes empty. */
|
|
11
|
+
export declare function removeSinkSubscriber<T>(subscribers: SinkSubscribers<T> | undefined, queue: AsyncQueue<T>): SinkSubscribers<T> | undefined;
|
|
12
|
+
/** Clears multi-subscriber storage before the owner drops its reference. */
|
|
13
|
+
export declare function clearSinkSubscribers<T>(subscribers: SinkSubscribers<T> | undefined): void;
|
|
14
|
+
/** Returns the number of active queues in compact subscriber storage. */
|
|
15
|
+
export declare function sinkSubscriberCount<T>(subscribers: SinkSubscribers<T> | undefined): number;
|
|
16
|
+
//# sourceMappingURL=subscribers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../src/sinks/subscribers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAE1D,qEAAqE;AACrE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,CAAC,EAC/B,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,EAC3C,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GACrB,eAAe,CAAC,CAAC,CAAC,CASpB;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,CAAC,EAClC,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,EAC3C,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GACrB,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAShC;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAIzF;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,CAK1F"}
|