reactor-core-ts 2.0.0 → 2.1.0
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 +118 -10
- package/dist/index.d.mts +799 -1
- package/dist/index.d.ts +799 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,9 @@ A TypeScript implementation of [Reactive Streams](https://www.reactive-streams.o
|
|
|
12
12
|
- [Filtering](#flux-filtering)
|
|
13
13
|
- [Aggregation](#flux-aggregation)
|
|
14
14
|
- [Combining](#flux-combining)
|
|
15
|
+
- [Backpressure](#flux-backpressure)
|
|
15
16
|
- [Side effects](#flux-side-effects)
|
|
17
|
+
- [Error handling](#flux-error-handling)
|
|
16
18
|
- [Scheduling](#flux-scheduling)
|
|
17
19
|
- [Utilities](#flux-utilities)
|
|
18
20
|
- [Subscribe](#flux-subscribe)
|
|
@@ -22,6 +24,7 @@ A TypeScript implementation of [Reactive Streams](https://www.reactive-streams.o
|
|
|
22
24
|
- [Filtering](#mono-filtering)
|
|
23
25
|
- [Combining](#mono-combining)
|
|
24
26
|
- [Side effects](#mono-side-effects)
|
|
27
|
+
- [Error handling](#mono-error-handling)
|
|
25
28
|
- [Scheduling](#mono-scheduling)
|
|
26
29
|
- [Utilities](#mono-utilities)
|
|
27
30
|
- [Subscribe](#mono-subscribe)
|
|
@@ -77,11 +80,18 @@ This library implements [Reactive Streams specification](https://www.reactive-st
|
|
|
77
80
|
| `Flux.range(start, count)` | Emit integers `[start, start+count)`. |
|
|
78
81
|
| `Flux.fromIterable(iterable)` | Emit all items from any `Iterable<T>`. |
|
|
79
82
|
| `Flux.generate(sink => …)` | Imperative generator. Call `sink.next()` / `sink.complete()` / `sink.error()`. Delivery is deferred until downstream requests. |
|
|
83
|
+
| `Flux.create(emitter => …)` | Push-based bridge via [`FluxSink`](#fluxsink) — supports `onRequest`, `onCancel`, `onDispose` callbacks. Suitable for event listeners and callback APIs. |
|
|
80
84
|
| `Flux.from(publisher)` | Wrap any `Publisher<T>` as a `Flux<T>`. |
|
|
81
85
|
| `Flux.defer(factory)` | Lazily create a new Flux per subscription via the factory function. |
|
|
82
86
|
| `Flux.empty()` | Complete immediately without emitting. |
|
|
83
87
|
| `Flux.never()` | Never emit any signal. |
|
|
84
88
|
| `Flux.error(err)` | Signal `onError` immediately. |
|
|
89
|
+
| `Flux.interval(ms)` | Emit an incrementing counter (0, 1, 2, …) at a fixed `ms` rate. Items are dropped when downstream has no demand. |
|
|
90
|
+
| `Flux.merge(...sources)` | Subscribe to all sources concurrently; items interleave as they arrive. |
|
|
91
|
+
| `Flux.zip(sources, combiner)` | Combine items from 2–4 sources positionally via `combiner`. Overloads for 2, 3, and 4 typed sources. |
|
|
92
|
+
| `Flux.combineLatest(sources, combiner)` | Emit a new value whenever any source emits, combining the **latest** values from each. Overloads for 2, 3, and 4 sources. |
|
|
93
|
+
| `Flux.firstWithValue(...sources)` | Race: emit the first value to arrive from any source, then cancel the rest. |
|
|
94
|
+
| `Flux.using(resourceSupplier, sourceFactory, cleanup)` | Manage a resource lifecycle: acquire, stream, release on termination. |
|
|
85
95
|
|
|
86
96
|
```typescript
|
|
87
97
|
import { Flux } from 'reactor-core-ts';
|
|
@@ -117,6 +127,17 @@ Flux.generate<number>(sink => {
|
|
|
117
127
|
| `.scanWith(seedFactory, reducer)` | Emit running accumulation starting from an explicit seed value. |
|
|
118
128
|
| `.cast<R>()` | Unsafe type cast — changes the declared element type without any runtime conversion. |
|
|
119
129
|
| `.indexed()` | Pair each item with its zero-based index: `Flux<[number, T]>`. |
|
|
130
|
+
| `.groupBy(keyFn)` | Route items into `GroupedFlux<K, T>` streams keyed by `keyFn(item)`. Each group is a self-contained `Flux`. |
|
|
131
|
+
| `.expand(fn)` | Breadth-first recursive expansion — each item is expanded via `fn`, which returns a `Publisher<T>` of child items. |
|
|
132
|
+
| `.sample(trigger)` | Emit the latest item seen whenever `trigger` emits. |
|
|
133
|
+
| `.bufferTimeout(maxSize, ms)` | Collect items into arrays; flush when the buffer reaches `maxSize` or `ms` elapses. |
|
|
134
|
+
| `.elapsed()` | Pair each item with the milliseconds elapsed since the previous item: `Flux<[number, T]>`. |
|
|
135
|
+
| `.timestamp()` | Pair each item with the current timestamp in ms: `Flux<[number, T]>`. |
|
|
136
|
+
| `.materialize()` | Wrap each signal (`next`, `error`, `complete`) as a `Signal<T>` item. |
|
|
137
|
+
| `.dematerialize()` | Restore a `Flux<Signal<R>>` back into a live reactive stream. |
|
|
138
|
+
| `.transformDeferred(fn)` | Apply a reusable operator function lazily per subscription. |
|
|
139
|
+
| `.delayUntil(triggerFn)` | Hold each item until the trigger publisher returned by `triggerFn(item)` emits or completes. |
|
|
140
|
+
| `.ofType(constructor)` | Keep only items that are `instanceof` the given constructor, with a typed cast to `R`. |
|
|
120
141
|
|
|
121
142
|
```typescript
|
|
122
143
|
Flux.just(1, 2, 3)
|
|
@@ -220,6 +241,10 @@ Flux.just(3, 1, 4, 1, 5)
|
|
|
220
241
|
| `.concatWith(other)` | Append `other` after `this` completes (sequential). |
|
|
221
242
|
| `.mergeWith(other)` | Merge `other` with `this` concurrently; items interleave as they arrive. |
|
|
222
243
|
| `.zipWith(other, combiner)` | Pair items from `this` and `other` one-by-one using `combiner(a, b) → V`. |
|
|
244
|
+
| `Flux.merge(...sources)` | Static N-source merge — subscribe to all and forward items as they arrive. |
|
|
245
|
+
| `Flux.zip(sources, combiner)` | Static positional combine: waits for one item from each source, then calls `combiner`. |
|
|
246
|
+
| `Flux.combineLatest(sources, combiner)` | Emit a combined value whenever any source emits; uses the latest from all others. |
|
|
247
|
+
| `Flux.firstWithValue(...sources)` | Race: emits the first value from any source, cancelling all others. |
|
|
223
248
|
|
|
224
249
|
```typescript
|
|
225
250
|
Flux.just(1, 2).concatWith(Flux.just(3, 4)).subscribe(v => console.log(v));
|
|
@@ -228,8 +253,25 @@ Flux.just(1, 2).concatWith(Flux.just(3, 4)).subscribe(v => console.log(v));
|
|
|
228
253
|
Flux.just(1, 2, 3).zipWith(Flux.just('a', 'b', 'c'), (n, s) => `${n}${s}`)
|
|
229
254
|
.subscribe(v => console.log(v));
|
|
230
255
|
// '1a' '2b' '3c'
|
|
256
|
+
|
|
257
|
+
Flux.zip([Flux.just(1, 2), Flux.just('a', 'b')], (n, s) => `${n}${s}`)
|
|
258
|
+
.subscribe(v => console.log(v));
|
|
259
|
+
// '1a' '2b'
|
|
260
|
+
|
|
261
|
+
Flux.combineLatest([Flux.just(1), Flux.just(2)], (a, b) => a + b)
|
|
262
|
+
.subscribe(v => console.log(v));
|
|
263
|
+
// 3
|
|
231
264
|
```
|
|
232
265
|
|
|
266
|
+
### Flux Backpressure
|
|
267
|
+
|
|
268
|
+
| Method | Description |
|
|
269
|
+
|---|---|
|
|
270
|
+
| `.onBackpressureBuffer(maxSize?)` | Buffer all items when downstream has no demand. Signals error when `maxSize` is exceeded. |
|
|
271
|
+
| `.onBackpressureDrop(onDrop?)` | Silently drop items when downstream has no demand. Optional `onDrop(item)` callback. |
|
|
272
|
+
| `.onBackpressureLatest()` | Keep only the latest item when downstream has no demand; older items are discarded. |
|
|
273
|
+
| `.limitRate(n)` | Prefetch items from upstream in batches of `n`, replenishing at 75% consumption. |
|
|
274
|
+
|
|
233
275
|
### Flux Side Effects
|
|
234
276
|
|
|
235
277
|
These operators observe signals without modifying the stream.
|
|
@@ -244,6 +286,22 @@ These operators observe signals without modifying the stream.
|
|
|
244
286
|
| `.doOnCancel(fn)` | Run `fn` when the subscription is cancelled. |
|
|
245
287
|
| `.doFinally(fn)` | Run `fn` after the stream terminates for any reason (complete, error, or cancel). |
|
|
246
288
|
| `.doOnSubscribe(fn)` | Run `fn` when `onSubscribe` is received, receiving the `Subscription` object. |
|
|
289
|
+
| `.doOnRequest(fn)` | Run `fn(n)` each time downstream calls `request(n)`. |
|
|
290
|
+
| `.doOnEach(fn)` | Run `fn(signal)` for every signal — next, error, and complete — as a `Signal<T>`. |
|
|
291
|
+
| `.log(label?)` | Console-log every signal with an optional label prefix. |
|
|
292
|
+
|
|
293
|
+
### Flux Error Handling
|
|
294
|
+
|
|
295
|
+
| Method | Description |
|
|
296
|
+
|---|---|
|
|
297
|
+
| `.retry(maxRetries?)` | Re-subscribe on error up to `maxRetries` times (default: unbounded). |
|
|
298
|
+
| `.retryWhen(fn)` | Controlled retry — each error is pushed to a `Flux<Error>` returned by `fn`; re-subscribe when the control emits. |
|
|
299
|
+
| `.repeatWhen(fn)` | Controlled repeat — each completion is pushed to a `Flux<void>`; re-subscribe when the control emits. |
|
|
300
|
+
| `.onErrorReturn(replacement)` | On error, switch to `replacement` publisher. |
|
|
301
|
+
| `.onErrorResume(fn)` | On error, switch to the publisher returned by `fn(error)`. |
|
|
302
|
+
| `.onErrorMap(fn)` | Transform the error without changing the stream type. |
|
|
303
|
+
| `.onErrorContinue(predicate)` | If `predicate(err)` is `true`, complete; otherwise re-throw. |
|
|
304
|
+
| `.timeout(ms, fallback?)` | Error with `TimeoutError` if no item arrives within `ms`; optionally switch to `fallback`. |
|
|
247
305
|
|
|
248
306
|
```typescript
|
|
249
307
|
Flux.just(1, 2, 3)
|
|
@@ -277,13 +335,34 @@ Flux.just('a', 'b', 'c')
|
|
|
277
335
|
|
|
278
336
|
| Method | Description |
|
|
279
337
|
|---|---|
|
|
280
|
-
| `.retry(maxRetries?)` | Re-subscribe on error up to `maxRetries` times (default: unbounded). |
|
|
281
338
|
| `.cache()` | Subscribe to the source once; replay all items to subsequent subscribers. |
|
|
282
339
|
| `.switchIfEmpty(alternative)` | Switch to `alternative` if source completes without emitting. |
|
|
283
|
-
| `.
|
|
284
|
-
| `.onErrorContinue(predicate)` | If `predicate(err)` is `true`, complete; otherwise re-throw. |
|
|
340
|
+
| `.delaySubscription(ms)` | Delay the actual subscription to the source by `ms` milliseconds. |
|
|
285
341
|
| `.pipe(producer, onRequest, onUnsubscribe)` | Low-level escape hatch for building custom downstream operators. |
|
|
286
342
|
|
|
343
|
+
### FluxSink
|
|
344
|
+
|
|
345
|
+
`Flux.create(emitter => …)` hands the `emitter` callback a `FluxSink<T>` with:
|
|
346
|
+
|
|
347
|
+
| Member | Description |
|
|
348
|
+
|---|---|
|
|
349
|
+
| `.next(value)` | Push a value. Buffered when downstream has no demand. |
|
|
350
|
+
| `.error(err)` | Terminate with an error. |
|
|
351
|
+
| `.complete()` | Complete normally. |
|
|
352
|
+
| `.requested` | Current downstream demand count. |
|
|
353
|
+
| `.onRequest(fn)` | Register a callback invoked each time downstream requests more items. |
|
|
354
|
+
| `.onCancel(fn)` | Register a cancellation callback. |
|
|
355
|
+
| `.onDispose(fn)` | Register a callback invoked on any terminal event (cancel, error, complete). |
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
Flux.create<number>(sink => {
|
|
359
|
+
const id = setInterval(() => {
|
|
360
|
+
if (sink.requested > 0) sink.next(Math.random());
|
|
361
|
+
}, 100);
|
|
362
|
+
sink.onDispose(() => clearInterval(id));
|
|
363
|
+
}).take(5).subscribe(v => console.log(v));
|
|
364
|
+
```
|
|
365
|
+
|
|
287
366
|
### Flux Subscribe
|
|
288
367
|
|
|
289
368
|
```typescript
|
|
@@ -326,10 +405,14 @@ sub.unsubscribe(); // cancel at any time
|
|
|
326
405
|
| `Mono.justOrEmpty(value)` | Emit `value` if not `null`/`undefined`, otherwise complete empty. |
|
|
327
406
|
| `Mono.fromPromise(promise)` | Wrap a `Promise<T>` — resolves to `onNext` + `onComplete`, rejects to `onError`. |
|
|
328
407
|
| `Mono.generate(sink => …)` | Imperative generator. Call `sink.next()` exactly once (or `sink.error()`/`sink.complete()`). |
|
|
408
|
+
| `Mono.create(sink => …)` | Alias for `Mono.generate`. |
|
|
409
|
+
| `Mono.fromCallable(fn)` | Lazy synchronous factory — calls `fn()` at subscribe time; propagates throws as `onError`. |
|
|
410
|
+
| `Mono.delay(ms)` | Emit `0` after `ms` milliseconds. |
|
|
329
411
|
| `Mono.from(publisher)` | Wrap any `Publisher<T>` as a `Mono<T>` (takes only the first item). |
|
|
330
412
|
| `Mono.defer(factory)` | Lazily create a new Mono per subscription via the factory function. |
|
|
331
413
|
| `Mono.empty()` | Complete immediately without emitting. |
|
|
332
414
|
| `Mono.error(err)` | Signal `onError` immediately. |
|
|
415
|
+
| `Mono.firstWithValue(...sources)` | Race: emit the first value from any of the given `Mono` sources. |
|
|
333
416
|
|
|
334
417
|
```typescript
|
|
335
418
|
import { Mono } from 'reactor-core-ts';
|
|
@@ -356,6 +439,9 @@ Mono.justOrEmpty(null).subscribe(
|
|
|
356
439
|
| `.mapNotNull(fn)` | Transform `T → R | null | undefined`; if result is null/undefined, complete empty. |
|
|
357
440
|
| `.flatMap(fn)` | Map the value to a `Mono<R>`, then subscribe to that inner Mono. |
|
|
358
441
|
| `.flatMapMany(fn)` | Map the value to a `Flux<R>` or `Mono<R>`, returning a `Flux<R>`. |
|
|
442
|
+
| `.thenReturn(value)` | Ignore the emitted value; emit `value` after source completes. |
|
|
443
|
+
| `.delayElement(ms)` | Delay the emitted value by `ms` milliseconds. |
|
|
444
|
+
| `.delayUntil(triggerFn)` | Hold the emitted value until the trigger publisher fires, then forward it. |
|
|
359
445
|
| `.cast<R>()` | Unsafe type cast. |
|
|
360
446
|
|
|
361
447
|
```typescript
|
|
@@ -396,7 +482,29 @@ Mono.just(42)
|
|
|
396
482
|
|
|
397
483
|
### Mono Side Effects
|
|
398
484
|
|
|
399
|
-
|
|
485
|
+
| Method | Description |
|
|
486
|
+
|---|---|
|
|
487
|
+
| `.doOnSuccess(fn)` | Run `fn(value)` when the Mono emits a value. Exceptions propagate as `onError`. |
|
|
488
|
+
| `.doFirst(fn)` | Run `fn` before the first item is emitted. |
|
|
489
|
+
| `.doOnNext(fn)` | Run `fn` for the emitted item. |
|
|
490
|
+
| `.doOnError(fn)` | Run `fn` when `onError` is received. |
|
|
491
|
+
| `.doOnSubscribe(fn)` | Run `fn` when `onSubscribe` is received. |
|
|
492
|
+
| `.doFinally(fn)` | Run `fn` after the stream terminates (complete or error). |
|
|
493
|
+
| `.doOnRequest(fn)` | Run `fn(n)` when downstream calls `request(n)`. |
|
|
494
|
+
| `.doOnEach(fn)` | Run `fn(signal)` for every signal as a `Signal<T>`. |
|
|
495
|
+
| `.log(label?)` | Console-log every signal. |
|
|
496
|
+
|
|
497
|
+
### Mono Error Handling
|
|
498
|
+
|
|
499
|
+
| Method | Description |
|
|
500
|
+
|---|---|
|
|
501
|
+
| `.retry(maxRetries?)` | Re-subscribe on error up to `maxRetries` times. |
|
|
502
|
+
| `.retryWhen(fn)` | Controlled retry — each error is pushed to a `Flux<Error>`; re-subscribe when the control emits. |
|
|
503
|
+
| `.onErrorReturn(replacement)` | On error, switch to `replacement` publisher. |
|
|
504
|
+
| `.onErrorResume(fn)` | On error, switch to the publisher returned by `fn(error)`. |
|
|
505
|
+
| `.onErrorMap(fn)` | Transform the error. |
|
|
506
|
+
| `.onErrorComplete(predicate?)` | Convert an error to a normal completion (optionally filtered by `predicate`). |
|
|
507
|
+
| `.timeout(ms, fallback?)` | Error with `TimeoutError` if no item arrives within `ms`. |
|
|
400
508
|
|
|
401
509
|
### Mono Scheduling
|
|
402
510
|
|
|
@@ -408,9 +516,9 @@ Same as Flux: `.publishOn(scheduler)`, `.subscribeOn(scheduler)`.
|
|
|
408
516
|
|---|---|
|
|
409
517
|
| `.hasElement()` | `Mono<boolean>` — `true` if a value is emitted, `false` if it completes empty. |
|
|
410
518
|
| `.toPromise()` | `Promise<T | null>` — resolves with the emitted value or `null` if empty. |
|
|
519
|
+
| `.toFuture()` | Alias for `.toPromise()`. |
|
|
520
|
+
| `.or(other)` | Fall back to `other` Mono if this completes empty. |
|
|
411
521
|
| `.switchIfEmpty(alternative)` | Switch to `alternative` Mono if this completes empty. |
|
|
412
|
-
| `.onErrorReturn(replacement)` | On error, switch to `replacement` publisher. |
|
|
413
|
-
| `.retry(maxRetries?)` | Re-subscribe on error. |
|
|
414
522
|
| `.pipe(producer, onRequest, onUnsubscribe)` | Low-level custom operator builder. |
|
|
415
523
|
|
|
416
524
|
### Mono Subscribe
|
|
@@ -598,10 +706,10 @@ The convenience callback overloads issue `request(Number.MAX_SAFE_INTEGER)` for
|
|
|
598
706
|
```bash
|
|
599
707
|
git clone https://github.com/CKATEPTb/reactor-core-ts.git
|
|
600
708
|
cd reactor-core-ts
|
|
601
|
-
|
|
709
|
+
npm install
|
|
602
710
|
|
|
603
|
-
|
|
604
|
-
|
|
711
|
+
npm run build # compile
|
|
712
|
+
npm run test # run all tests (Jest + TCK)
|
|
605
713
|
```
|
|
606
714
|
|
|
607
715
|
Feel free to open issues and submit pull requests.
|
|
@@ -612,4 +720,4 @@ Feel free to open issues and submit pull requests.
|
|
|
612
720
|
|
|
613
721
|
LGPL-3.0-only. See [LICENSE.md](LICENSE.md) for details.
|
|
614
722
|
|
|
615
|
-
**Author**: CKATEPTb
|
|
723
|
+
**Author**: [CKATEPTb](https://github.com/CKATEPTb)
|