@nlozgachev/pipelined 0.49.0 → 0.50.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/dist/{chunk-EPT3GYGN.mjs → chunk-6N27QZFK.mjs} +1 -1
- package/dist/{chunk-IHLH2XYQ.mjs → chunk-U64ASY7P.mjs} +34 -10
- package/dist/core.d.mts +8 -0
- package/dist/core.d.ts +8 -0
- package/dist/core.js +34 -10
- package/dist/core.mjs +1 -1
- package/dist/data.mjs +2 -2
- package/dist/index.js +34 -10
- package/dist/index.mjs +2 -2
- package/package.json +36 -16
|
@@ -1737,22 +1737,35 @@ var Stream;
|
|
|
1737
1737
|
((Stream2) => {
|
|
1738
1738
|
Stream2.make = (options) => ({
|
|
1739
1739
|
options,
|
|
1740
|
-
_listeners: /* @__PURE__ */ new Set()
|
|
1740
|
+
_listeners: /* @__PURE__ */ new Set(),
|
|
1741
|
+
_queue: [],
|
|
1742
|
+
_isEmitting: false
|
|
1741
1743
|
});
|
|
1742
1744
|
Stream2.emit = (target, message) => {
|
|
1743
1745
|
const targets = Array.isArray(target) ? target : [target];
|
|
1744
1746
|
const msg = message;
|
|
1745
1747
|
for (const stream of targets) {
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
+
stream._queue.push(msg);
|
|
1749
|
+
if (!stream._isEmitting) {
|
|
1750
|
+
stream._isEmitting = true;
|
|
1748
1751
|
try {
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1752
|
+
while (stream._queue.length > 0) {
|
|
1753
|
+
const nextMsg = stream._queue.shift();
|
|
1754
|
+
const listeners = Array.from(stream._listeners);
|
|
1755
|
+
for (const listener of listeners) {
|
|
1756
|
+
try {
|
|
1757
|
+
listener(nextMsg);
|
|
1758
|
+
} catch (err2) {
|
|
1759
|
+
if (stream.options?.onError) {
|
|
1760
|
+
stream.options.onError(err2);
|
|
1761
|
+
} else {
|
|
1762
|
+
throw err2;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1755
1766
|
}
|
|
1767
|
+
} finally {
|
|
1768
|
+
stream._isEmitting = false;
|
|
1756
1769
|
}
|
|
1757
1770
|
}
|
|
1758
1771
|
}
|
|
@@ -1779,6 +1792,7 @@ var Stream;
|
|
|
1779
1792
|
const isStrict = options?.strict ?? false;
|
|
1780
1793
|
const isOnce = options?.once ?? false;
|
|
1781
1794
|
const resetKinds = options?.reset ? new Set(Array.isArray(options.reset) ? options.reset : [options.reset]) : null;
|
|
1795
|
+
const optionalKinds = options?.optional ? new Set(Array.isArray(options.optional) ? options.optional : [options.optional]) : null;
|
|
1782
1796
|
const createMatcher = (onMatch) => {
|
|
1783
1797
|
let sequenceIndex = 0;
|
|
1784
1798
|
return (msg) => {
|
|
@@ -1792,7 +1806,17 @@ var Stream;
|
|
|
1792
1806
|
}
|
|
1793
1807
|
return;
|
|
1794
1808
|
}
|
|
1795
|
-
|
|
1809
|
+
let expectedKind = eventList[sequenceIndex];
|
|
1810
|
+
if (expectedKind !== msg.kind && optionalKinds !== null) {
|
|
1811
|
+
let lookaheadIndex = sequenceIndex;
|
|
1812
|
+
while (lookaheadIndex < eventList.length && optionalKinds.has(eventList[lookaheadIndex]) && eventList[lookaheadIndex] !== msg.kind) {
|
|
1813
|
+
lookaheadIndex++;
|
|
1814
|
+
}
|
|
1815
|
+
if (lookaheadIndex < eventList.length && eventList[lookaheadIndex] === msg.kind) {
|
|
1816
|
+
sequenceIndex = lookaheadIndex;
|
|
1817
|
+
expectedKind = eventList[sequenceIndex];
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1796
1820
|
if (msg.kind === expectedKind) {
|
|
1797
1821
|
sequenceIndex++;
|
|
1798
1822
|
if (sequenceIndex === eventList.length) {
|
package/dist/core.d.mts
CHANGED
|
@@ -2490,6 +2490,10 @@ type Stream<S extends Record<string, unknown>> = {
|
|
|
2490
2490
|
readonly options?: Stream.Options;
|
|
2491
2491
|
/** @internal */
|
|
2492
2492
|
readonly _listeners: Set<(msg: Stream.Message<S>) => void>;
|
|
2493
|
+
/** @internal */
|
|
2494
|
+
readonly _queue: Array<Stream.Message<S>>;
|
|
2495
|
+
/** @internal */
|
|
2496
|
+
_isEmitting: boolean;
|
|
2493
2497
|
};
|
|
2494
2498
|
declare namespace Stream {
|
|
2495
2499
|
/**
|
|
@@ -2517,6 +2521,8 @@ declare namespace Stream {
|
|
|
2517
2521
|
readonly once?: boolean;
|
|
2518
2522
|
/** Event kind(s) that reset sequence tracking to index 0. */
|
|
2519
2523
|
readonly reset?: (keyof S & string) | ReadonlyArray<keyof S & string>;
|
|
2524
|
+
/** Event kind(s) in the sequence that may be present or skipped. */
|
|
2525
|
+
readonly optional?: (keyof S & string) | ReadonlyArray<keyof S & string>;
|
|
2520
2526
|
};
|
|
2521
2527
|
/**
|
|
2522
2528
|
* Handle for an active stateful subscription.
|
|
@@ -2558,6 +2564,8 @@ declare namespace Stream {
|
|
|
2558
2564
|
/**
|
|
2559
2565
|
* Emits a message payload to one or more target streams.
|
|
2560
2566
|
*
|
|
2567
|
+
* Uses a synchronous breadth-first trampoline queue to handle re-entrant emissions deterministically.
|
|
2568
|
+
*
|
|
2561
2569
|
* @example
|
|
2562
2570
|
* ```ts
|
|
2563
2571
|
* Stream.emit(streamA, {
|
package/dist/core.d.ts
CHANGED
|
@@ -2490,6 +2490,10 @@ type Stream<S extends Record<string, unknown>> = {
|
|
|
2490
2490
|
readonly options?: Stream.Options;
|
|
2491
2491
|
/** @internal */
|
|
2492
2492
|
readonly _listeners: Set<(msg: Stream.Message<S>) => void>;
|
|
2493
|
+
/** @internal */
|
|
2494
|
+
readonly _queue: Array<Stream.Message<S>>;
|
|
2495
|
+
/** @internal */
|
|
2496
|
+
_isEmitting: boolean;
|
|
2493
2497
|
};
|
|
2494
2498
|
declare namespace Stream {
|
|
2495
2499
|
/**
|
|
@@ -2517,6 +2521,8 @@ declare namespace Stream {
|
|
|
2517
2521
|
readonly once?: boolean;
|
|
2518
2522
|
/** Event kind(s) that reset sequence tracking to index 0. */
|
|
2519
2523
|
readonly reset?: (keyof S & string) | ReadonlyArray<keyof S & string>;
|
|
2524
|
+
/** Event kind(s) in the sequence that may be present or skipped. */
|
|
2525
|
+
readonly optional?: (keyof S & string) | ReadonlyArray<keyof S & string>;
|
|
2520
2526
|
};
|
|
2521
2527
|
/**
|
|
2522
2528
|
* Handle for an active stateful subscription.
|
|
@@ -2558,6 +2564,8 @@ declare namespace Stream {
|
|
|
2558
2564
|
/**
|
|
2559
2565
|
* Emits a message payload to one or more target streams.
|
|
2560
2566
|
*
|
|
2567
|
+
* Uses a synchronous breadth-first trampoline queue to handle re-entrant emissions deterministically.
|
|
2568
|
+
*
|
|
2561
2569
|
* @example
|
|
2562
2570
|
* ```ts
|
|
2563
2571
|
* Stream.emit(streamA, {
|
package/dist/core.js
CHANGED
|
@@ -1811,22 +1811,35 @@ var Stream;
|
|
|
1811
1811
|
((Stream2) => {
|
|
1812
1812
|
Stream2.make = (options) => ({
|
|
1813
1813
|
options,
|
|
1814
|
-
_listeners: /* @__PURE__ */ new Set()
|
|
1814
|
+
_listeners: /* @__PURE__ */ new Set(),
|
|
1815
|
+
_queue: [],
|
|
1816
|
+
_isEmitting: false
|
|
1815
1817
|
});
|
|
1816
1818
|
Stream2.emit = (target, message) => {
|
|
1817
1819
|
const targets = Array.isArray(target) ? target : [target];
|
|
1818
1820
|
const msg = message;
|
|
1819
1821
|
for (const stream of targets) {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
+
stream._queue.push(msg);
|
|
1823
|
+
if (!stream._isEmitting) {
|
|
1824
|
+
stream._isEmitting = true;
|
|
1822
1825
|
try {
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1826
|
+
while (stream._queue.length > 0) {
|
|
1827
|
+
const nextMsg = stream._queue.shift();
|
|
1828
|
+
const listeners = Array.from(stream._listeners);
|
|
1829
|
+
for (const listener of listeners) {
|
|
1830
|
+
try {
|
|
1831
|
+
listener(nextMsg);
|
|
1832
|
+
} catch (err2) {
|
|
1833
|
+
if (stream.options?.onError) {
|
|
1834
|
+
stream.options.onError(err2);
|
|
1835
|
+
} else {
|
|
1836
|
+
throw err2;
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1829
1840
|
}
|
|
1841
|
+
} finally {
|
|
1842
|
+
stream._isEmitting = false;
|
|
1830
1843
|
}
|
|
1831
1844
|
}
|
|
1832
1845
|
}
|
|
@@ -1853,6 +1866,7 @@ var Stream;
|
|
|
1853
1866
|
const isStrict = options?.strict ?? false;
|
|
1854
1867
|
const isOnce = options?.once ?? false;
|
|
1855
1868
|
const resetKinds = options?.reset ? new Set(Array.isArray(options.reset) ? options.reset : [options.reset]) : null;
|
|
1869
|
+
const optionalKinds = options?.optional ? new Set(Array.isArray(options.optional) ? options.optional : [options.optional]) : null;
|
|
1856
1870
|
const createMatcher = (onMatch) => {
|
|
1857
1871
|
let sequenceIndex = 0;
|
|
1858
1872
|
return (msg) => {
|
|
@@ -1866,7 +1880,17 @@ var Stream;
|
|
|
1866
1880
|
}
|
|
1867
1881
|
return;
|
|
1868
1882
|
}
|
|
1869
|
-
|
|
1883
|
+
let expectedKind = eventList[sequenceIndex];
|
|
1884
|
+
if (expectedKind !== msg.kind && optionalKinds !== null) {
|
|
1885
|
+
let lookaheadIndex = sequenceIndex;
|
|
1886
|
+
while (lookaheadIndex < eventList.length && optionalKinds.has(eventList[lookaheadIndex]) && eventList[lookaheadIndex] !== msg.kind) {
|
|
1887
|
+
lookaheadIndex++;
|
|
1888
|
+
}
|
|
1889
|
+
if (lookaheadIndex < eventList.length && eventList[lookaheadIndex] === msg.kind) {
|
|
1890
|
+
sequenceIndex = lookaheadIndex;
|
|
1891
|
+
expectedKind = eventList[sequenceIndex];
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1870
1894
|
if (msg.kind === expectedKind) {
|
|
1871
1895
|
sequenceIndex++;
|
|
1872
1896
|
if (sequenceIndex === eventList.length) {
|
package/dist/core.mjs
CHANGED
package/dist/data.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -2293,22 +2293,35 @@ var Stream;
|
|
|
2293
2293
|
((Stream2) => {
|
|
2294
2294
|
Stream2.make = (options) => ({
|
|
2295
2295
|
options,
|
|
2296
|
-
_listeners: /* @__PURE__ */ new Set()
|
|
2296
|
+
_listeners: /* @__PURE__ */ new Set(),
|
|
2297
|
+
_queue: [],
|
|
2298
|
+
_isEmitting: false
|
|
2297
2299
|
});
|
|
2298
2300
|
Stream2.emit = (target, message) => {
|
|
2299
2301
|
const targets = Array.isArray(target) ? target : [target];
|
|
2300
2302
|
const msg = message;
|
|
2301
2303
|
for (const stream of targets) {
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
+
stream._queue.push(msg);
|
|
2305
|
+
if (!stream._isEmitting) {
|
|
2306
|
+
stream._isEmitting = true;
|
|
2304
2307
|
try {
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2308
|
+
while (stream._queue.length > 0) {
|
|
2309
|
+
const nextMsg = stream._queue.shift();
|
|
2310
|
+
const listeners = Array.from(stream._listeners);
|
|
2311
|
+
for (const listener of listeners) {
|
|
2312
|
+
try {
|
|
2313
|
+
listener(nextMsg);
|
|
2314
|
+
} catch (err2) {
|
|
2315
|
+
if (stream.options?.onError) {
|
|
2316
|
+
stream.options.onError(err2);
|
|
2317
|
+
} else {
|
|
2318
|
+
throw err2;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2311
2322
|
}
|
|
2323
|
+
} finally {
|
|
2324
|
+
stream._isEmitting = false;
|
|
2312
2325
|
}
|
|
2313
2326
|
}
|
|
2314
2327
|
}
|
|
@@ -2335,6 +2348,7 @@ var Stream;
|
|
|
2335
2348
|
const isStrict = options?.strict ?? false;
|
|
2336
2349
|
const isOnce = options?.once ?? false;
|
|
2337
2350
|
const resetKinds = options?.reset ? new Set(Array.isArray(options.reset) ? options.reset : [options.reset]) : null;
|
|
2351
|
+
const optionalKinds = options?.optional ? new Set(Array.isArray(options.optional) ? options.optional : [options.optional]) : null;
|
|
2338
2352
|
const createMatcher = (onMatch) => {
|
|
2339
2353
|
let sequenceIndex = 0;
|
|
2340
2354
|
return (msg) => {
|
|
@@ -2348,7 +2362,17 @@ var Stream;
|
|
|
2348
2362
|
}
|
|
2349
2363
|
return;
|
|
2350
2364
|
}
|
|
2351
|
-
|
|
2365
|
+
let expectedKind = eventList[sequenceIndex];
|
|
2366
|
+
if (expectedKind !== msg.kind && optionalKinds !== null) {
|
|
2367
|
+
let lookaheadIndex = sequenceIndex;
|
|
2368
|
+
while (lookaheadIndex < eventList.length && optionalKinds.has(eventList[lookaheadIndex]) && eventList[lookaheadIndex] !== msg.kind) {
|
|
2369
|
+
lookaheadIndex++;
|
|
2370
|
+
}
|
|
2371
|
+
if (lookaheadIndex < eventList.length && eventList[lookaheadIndex] === msg.kind) {
|
|
2372
|
+
sequenceIndex = lookaheadIndex;
|
|
2373
|
+
expectedKind = eventList[sequenceIndex];
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2352
2376
|
if (msg.kind === expectedKind) {
|
|
2353
2377
|
sequenceIndex++;
|
|
2354
2378
|
if (sequenceIndex === eventList.length) {
|
package/dist/index.mjs
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
Rec,
|
|
40
40
|
Str,
|
|
41
41
|
Uniq
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-6N27QZFK.mjs";
|
|
43
43
|
import {
|
|
44
44
|
Combinable,
|
|
45
45
|
Deferred,
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
These,
|
|
67
67
|
Tuple,
|
|
68
68
|
Validation
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-U64ASY7P.mjs";
|
|
70
70
|
import {
|
|
71
71
|
Brand,
|
|
72
72
|
Duration,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nlozgachev/pipelined",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"description": "Opinionated functional abstractions for TypeScript",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"homepage": "https://pipelined.lozgachev.dev",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=24"
|
|
21
|
+
"node": ">=24.19.0"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist"
|
|
@@ -68,24 +68,44 @@
|
|
|
68
68
|
"docs:build": "pnpm --filter pipelined-docs build"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@size-limit/file": "
|
|
72
|
-
"@types/node": "
|
|
73
|
-
"@vitest/coverage-v8": "4.1.
|
|
74
|
-
"bumpp": "
|
|
75
|
-
"dprint": "0.
|
|
76
|
-
"fast-check": "4.
|
|
77
|
-
"oxlint": "1.
|
|
78
|
-
"size-limit": "
|
|
71
|
+
"@size-limit/file": "13.0.3",
|
|
72
|
+
"@types/node": "26.2.0",
|
|
73
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
74
|
+
"bumpp": "12.2.0",
|
|
75
|
+
"dprint": "0.55.2",
|
|
76
|
+
"fast-check": "4.9.0",
|
|
77
|
+
"oxlint": "1.78.0",
|
|
78
|
+
"size-limit": "13.0.3",
|
|
79
79
|
"tsup": "8.5.1",
|
|
80
80
|
"typescript": "6.0.3",
|
|
81
|
-
"vitest": "4.1.
|
|
81
|
+
"vitest": "4.1.10"
|
|
82
82
|
},
|
|
83
83
|
"size-limit": [
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
{
|
|
85
|
+
"path": "dist/index.js",
|
|
86
|
+
"limit": "25 KB",
|
|
87
|
+
"gzip": true
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"path": "dist/core.js",
|
|
91
|
+
"limit": "16 KB",
|
|
92
|
+
"gzip": true
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "dist/composition.js",
|
|
96
|
+
"limit": "4 KB",
|
|
97
|
+
"gzip": true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"path": "dist/data.js",
|
|
101
|
+
"limit": "13 KB",
|
|
102
|
+
"gzip": true
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"path": "dist/types.js",
|
|
106
|
+
"limit": "2 KB",
|
|
107
|
+
"gzip": true
|
|
108
|
+
}
|
|
89
109
|
],
|
|
90
110
|
"packageManager": "pnpm@11.6.0+sha512.9a36518224080c6fe5165afdcfe79bfa118c29be703f3f462b1e32efe1e98e47e8750b148e08286250aad4113cc7993ca413c4e2cd447752708c2ee5751bc95f"
|
|
91
111
|
}
|