@vielzeug/flux 1.0.7 → 2.0.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 +22 -25
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +2 -8
- package/dist/_dev.js.map +1 -1
- package/dist/_iterator.cjs +1 -1
- package/dist/_iterator.cjs.map +1 -1
- package/dist/_iterator.d.ts +3 -1
- package/dist/_iterator.d.ts.map +1 -1
- package/dist/_iterator.js +57 -35
- package/dist/_iterator.js.map +1 -1
- package/dist/_link.cjs +2 -0
- package/dist/_link.cjs.map +1 -0
- package/dist/_link.d.ts +4 -0
- package/dist/_link.d.ts.map +1 -0
- package/dist/_link.js +8 -0
- package/dist/_link.js.map +1 -0
- package/dist/_numeric.cjs +1 -1
- package/dist/_numeric.cjs.map +1 -1
- package/dist/_numeric.d.ts +2 -1
- package/dist/_numeric.d.ts.map +1 -1
- package/dist/_numeric.js +3 -7
- package/dist/_numeric.js.map +1 -1
- package/dist/_pipe.cjs +1 -1
- package/dist/_pipe.cjs.map +1 -1
- package/dist/_pipe.d.ts +2 -1
- package/dist/_pipe.d.ts.map +1 -1
- package/dist/_pipe.js +3 -3
- package/dist/_pipe.js.map +1 -1
- package/dist/_safe.cjs +1 -1
- package/dist/_safe.cjs.map +1 -1
- package/dist/_safe.d.ts +1 -1
- package/dist/_safe.d.ts.map +1 -1
- package/dist/_safe.js +2 -2
- package/dist/_safe.js.map +1 -1
- package/dist/_scheduler.cjs +1 -1
- package/dist/_scheduler.cjs.map +1 -1
- package/dist/_scheduler.d.ts +5 -2
- package/dist/_scheduler.d.ts.map +1 -1
- package/dist/_scheduler.js +1 -1
- package/dist/_scheduler.js.map +1 -1
- package/dist/_subscription.cjs +2 -0
- package/dist/_subscription.cjs.map +1 -0
- package/dist/_subscription.d.ts +8 -0
- package/dist/_subscription.d.ts.map +1 -0
- package/dist/_subscription.js +80 -0
- package/dist/_subscription.js.map +1 -0
- package/dist/adapters/courier.cjs +1 -1
- package/dist/adapters/courier.cjs.map +1 -1
- package/dist/adapters/courier.d.ts +35 -21
- package/dist/adapters/courier.d.ts.map +1 -1
- package/dist/adapters/courier.js +25 -6
- package/dist/adapters/courier.js.map +1 -1
- package/dist/adapters/herald.cjs +1 -1
- package/dist/adapters/herald.cjs.map +1 -1
- package/dist/adapters/herald.d.ts +2 -16
- package/dist/adapters/herald.d.ts.map +1 -1
- package/dist/adapters/herald.js +12 -8
- package/dist/adapters/herald.js.map +1 -1
- package/dist/adapters/pulse.cjs +1 -1
- package/dist/adapters/pulse.cjs.map +1 -1
- package/dist/adapters/pulse.d.ts +3 -20
- package/dist/adapters/pulse.d.ts.map +1 -1
- package/dist/adapters/pulse.js +2 -6
- package/dist/adapters/pulse.js.map +1 -1
- package/dist/adapters/ripple.cjs +1 -1
- package/dist/adapters/ripple.cjs.map +1 -1
- package/dist/adapters/ripple.d.ts +3 -39
- package/dist/adapters/ripple.d.ts.map +1 -1
- package/dist/adapters/ripple.js +22 -29
- package/dist/adapters/ripple.js.map +1 -1
- package/dist/async.cjs +2 -0
- package/dist/async.cjs.map +1 -0
- package/dist/async.d.ts +4 -0
- package/dist/async.d.ts.map +1 -0
- package/dist/async.js +11 -0
- package/dist/async.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +3 -16
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +12 -81
- package/dist/core.js.map +1 -1
- package/dist/courier.cjs +1 -0
- package/dist/courier.d.ts +2 -0
- package/dist/courier.d.ts.map +1 -0
- package/dist/courier.js +2 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/flux.cjs +1 -1
- package/dist/flux.cjs.map +1 -1
- package/dist/flux.iife.js +1 -1
- package/dist/flux.iife.js.map +1 -1
- package/dist/flux.js +1 -1
- package/dist/flux.js.map +1 -1
- package/dist/herald.cjs +1 -0
- package/dist/herald.d.ts +2 -0
- package/dist/herald.d.ts.map +1 -0
- package/dist/herald.js +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +13 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -14
- package/dist/operators/combination.cjs +1 -1
- package/dist/operators/combination.cjs.map +1 -1
- package/dist/operators/combination.d.ts +9 -64
- package/dist/operators/combination.d.ts.map +1 -1
- package/dist/operators/combination.js +46 -160
- package/dist/operators/combination.js.map +1 -1
- package/dist/operators/creation.cjs +1 -1
- package/dist/operators/creation.cjs.map +1 -1
- package/dist/operators/creation.d.ts +13 -46
- package/dist/operators/creation.d.ts.map +1 -1
- package/dist/operators/creation.js +61 -65
- package/dist/operators/creation.js.map +1 -1
- package/dist/operators/filtering.cjs +1 -1
- package/dist/operators/filtering.cjs.map +1 -1
- package/dist/operators/filtering.d.ts +10 -60
- package/dist/operators/filtering.d.ts.map +1 -1
- package/dist/operators/filtering.js +62 -109
- package/dist/operators/filtering.js.map +1 -1
- package/dist/operators/transformation.cjs +1 -1
- package/dist/operators/transformation.cjs.map +1 -1
- package/dist/operators/transformation.d.ts +9 -62
- package/dist/operators/transformation.d.ts.map +1 -1
- package/dist/operators/transformation.js +91 -142
- package/dist/operators/transformation.js.map +1 -1
- package/dist/operators/utility.cjs +1 -1
- package/dist/operators/utility.cjs.map +1 -1
- package/dist/operators/utility.d.ts +16 -97
- package/dist/operators/utility.d.ts.map +1 -1
- package/dist/operators/utility.js +75 -191
- package/dist/operators/utility.js.map +1 -1
- package/dist/pipe.cjs +2 -0
- package/dist/pipe.cjs.map +1 -0
- package/dist/pipe.d.ts +15 -0
- package/dist/pipe.d.ts.map +1 -0
- package/dist/pipe.js +9 -0
- package/dist/pipe.js.map +1 -0
- package/dist/pulse.cjs +1 -0
- package/dist/pulse.d.ts +2 -0
- package/dist/pulse.d.ts.map +1 -0
- package/dist/pulse.js +2 -0
- package/dist/ripple.cjs +1 -0
- package/dist/ripple.d.ts +3 -0
- package/dist/ripple.d.ts.map +1 -0
- package/dist/ripple.js +2 -0
- package/dist/subject.cjs +1 -1
- package/dist/subject.cjs.map +1 -1
- package/dist/subject.d.ts +14 -65
- package/dist/subject.d.ts.map +1 -1
- package/dist/subject.js +31 -166
- package/dist/subject.js.map +1 -1
- package/dist/subjects.cjs +1 -0
- package/dist/subjects.d.ts +3 -0
- package/dist/subjects.d.ts.map +1 -0
- package/dist/subjects.js +2 -0
- package/dist/types.d.ts +32 -79
- package/dist/types.d.ts.map +1 -1
- package/package.json +54 -15
package/dist/pulse.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/pulse.cjs");exports.fromPresence=e.fromPresence,exports.fromPulse=e.fromPulse;
|
package/dist/pulse.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pulse.d.ts","sourceRoot":"","sources":["../src/pulse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/pulse.js
ADDED
package/dist/ripple.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/ripple.cjs");exports.fromSignal=e.fromSignal,exports.toSignal=e.toSignal;
|
package/dist/ripple.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../src/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/ripple.js
ADDED
package/dist/subject.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./
|
|
1
|
+
const e=require("./core.cjs"),t=require("./_numeric.cjs");function n(e){let n=e.replay??+(`initial`in e);return t.assertNonNegativeInteger(n,`Channel replay`),n}function r(t={}){let r=n(t),i=new AbortController,a=new Set,o=[];`initial`in t&&r>0&&o.push(t.initial);let s=e.stream(e=>{for(let t of o)e.next(t);if(i.signal.aborted){e.complete();return}return a.add(e),()=>a.delete(e)}),c=()=>{if(!i.signal.aborted){i.abort();for(let e of[...a])e.complete();a.clear()}};return{get disposalSignal(){return i.signal},dispose:c,get disposed(){return i.signal.aborted},send(e){if(!i.signal.aborted){r>0&&(o.length===r&&o.shift(),o.push(e));for(let t of[...a])t.next(e)}},stream:s,[Symbol.dispose]:c}}exports.createChannel=r;
|
|
2
2
|
//# sourceMappingURL=subject.cjs.map
|
package/dist/subject.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subject.cjs","names":[],"sources":["../src/subject.ts"],"sourcesContent":["import type { Flux, Observer, Unsubscribe } from './types';\n\nimport { error, warn } from './_dev';\nimport { makeAsyncIterator } from './_iterator';\nimport { clampPositiveInt } from './_numeric';\nimport { makePipe } from './_pipe';\n\nconst NOOP: Unsubscribe = () => {};\n\n/**\n * A `Subject` is both a `Flux` and a manual emission handle.\n * Calling `emit()` pushes a value to all active subscribers.\n *\n * A Subject is hot — all subscribers share the same emission sequence.\n * Subscribers that subscribe after an emission will NOT receive past values.\n * Use `BehaviorSubject` to replay the latest value to late subscribers.\n */\nexport interface Subject<T> extends Flux<T> {\n /** `true` after `dispose()` or `complete()` is called. */\n readonly disposed: boolean;\n /** Emit a complete signal to all subscribers and dispose the subject. */\n complete(): void;\n /** Push a value to all active subscribers. */\n emit(value: T): void;\n /** Push an error to all active subscribers and dispose the subject. */\n fail(err: unknown): void;\n}\n\n/**\n * A `BehaviorSubject` is a `Subject` that replays the latest value to\n * any new subscriber immediately on subscription.\n */\nexport interface BehaviorSubject<T> extends Subject<T> {\n /** The current (latest emitted) value. */\n readonly value: T;\n}\n\n/**\n * A `ReplaySubject` is a `Subject` that replays the last N emitted values\n * to any new subscriber immediately on subscription.\n */\nexport interface ReplaySubject<T> extends Subject<T> {\n /** Snapshot of the current replay buffer (up to `bufferSize` entries). */\n readonly buffer: readonly T[];\n}\n\n// ── Shared internals ──────────────────────────────────────────────────────────\n\ninterface SubjectCore<T> {\n ac: AbortController;\n broadcast(fn: (obs: Observer<T>) => void): void;\n doSubscribe(observerOrNext: Observer<T> | ((value: T) => void), signal?: AbortSignal): Unsubscribe;\n subscribers: Set<Observer<T>>;\n}\n\nfunction makeCore<T>(): SubjectCore<T> {\n const ac = new AbortController();\n const subscribers = new Set<Observer<T>>();\n\n function broadcast(fn: (obs: Observer<T>) => void): void {\n for (const obs of [...subscribers]) {\n try {\n fn(obs);\n } catch (err) {\n error('Subscriber threw during broadcast', err);\n }\n }\n }\n\n function doSubscribe(observerOrNext: Observer<T> | ((value: T) => void), signal?: AbortSignal): Unsubscribe {\n const observer: Observer<T> = typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n if (ac.signal.aborted || signal?.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n subscribers.add(observer);\n\n const unsub = (): void => {\n subscribers.delete(observer);\n\n if (signal) signal.removeEventListener('abort', unsub);\n };\n\n if (signal) signal.addEventListener('abort', unsub, { once: true });\n\n return unsub;\n }\n\n return { ac, broadcast, doSubscribe, subscribers };\n}\n\n// Safely emit initial replay values; re-check disposed after sync replay.\nfunction replaySubscribe<T>(\n core: SubjectCore<T>,\n replay: () => void,\n observerOrNext: Observer<T> | ((value: T) => void),\n signal?: AbortSignal,\n): Unsubscribe {\n const observer: Observer<T> = typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n if (core.ac.signal.aborted || signal?.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n replay();\n\n // Re-check: the synchronous replay may have triggered a dispose.\n if (core.ac.signal.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n return core.doSubscribe(observer, signal);\n}\n\n/**\n * Shared `dispose()` implementation for every `Subject` variant: aborts the core,\n * notifies all active subscribers with `complete()`, and clears the subscriber set.\n * Reused instead of being copy-pasted per factory.\n * @internal\n */\nfunction makeDispose<T>(core: SubjectCore<T>): () => void {\n return () => {\n if (core.ac.signal.aborted) return;\n\n core.ac.abort();\n core.broadcast((obs) => obs.complete?.());\n core.subscribers.clear();\n };\n}\n\n/**\n * Shared `fail()` implementation for every `Subject` variant: aborts the core,\n * notifies all active subscribers with `error()`, and clears the subscriber set.\n * Reused instead of being copy-pasted per factory.\n * @internal\n */\nfunction makeFail<T>(core: SubjectCore<T>): (err: unknown) => void {\n return (err) => {\n if (core.ac.signal.aborted) return;\n\n core.ac.abort();\n core.broadcast((obs) => obs.error?.(err));\n core.subscribers.clear();\n };\n}\n\n// ── createSubject ─────────────────────────────────────────────────────────────\n\n/**\n * Creates a new `Subject<T>`.\n *\n * @example\n * const events = createSubject<string>();\n * events.subscribe((s) => console.log(s));\n * events.emit('hello');\n * events.dispose();\n */\nexport function createSubject<T>(): Subject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n\n const subject: Subject<T> = {\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return core.doSubscribe(observerOrNext, signal);\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) => core.doSubscribe(obs));\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n };\n\n return subject;\n}\n\n// ── createBehaviorSubject ─────────────────────────────────────────────────────\n\n/**\n * Creates a new `BehaviorSubject<T>` with an initial value.\n * Late subscribers immediately receive the current value on subscribe.\n *\n * @example\n * const count = createBehaviorSubject(0);\n * count.subscribe((n) => console.log(n)); // logs 0 immediately\n * count.emit(1); // logs 1\n */\nexport function createBehaviorSubject<T>(initial: T): BehaviorSubject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n let current = initial;\n\n const subject: BehaviorSubject<T> = {\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n current = value;\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return replaySubscribe(\n core,\n () => {\n const observer: Observer<T> =\n typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n try {\n observer.next(current);\n } catch (err) {\n error('BehaviorSubject: subscriber threw during initial replay', err);\n }\n },\n observerOrNext,\n signal,\n );\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) =>\n replaySubscribe(\n core,\n () => {\n try {\n obs.next(current);\n } catch (err) {\n error('BehaviorSubject: subscriber threw during initial replay', err);\n }\n },\n obs,\n ),\n );\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n\n get value(): T {\n return current;\n },\n };\n\n return subject;\n}\n\n// ── createReplaySubject ───────────────────────────────────────────────────────\n\n/**\n * Creates a `ReplaySubject<T>` that buffers up to `bufferSize` values and\n * replays them in order to any new subscriber immediately on subscription.\n *\n * @example\n * const history = createReplaySubject<string>(3);\n * history.emit('a');\n * history.emit('b');\n * history.subscribe(console.log); // logs 'a', 'b' immediately\n */\nexport function createReplaySubject<T>(bufferSize: number): ReplaySubject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n const { clamped, value: max } = clampPositiveInt(bufferSize);\n const buf: T[] = [];\n\n if (clamped) {\n warn(`createReplaySubject: bufferSize must be a finite integer >= 1, got ${bufferSize} — clamped to ${max}`);\n }\n\n const subject: ReplaySubject<T> = {\n get buffer(): readonly T[] {\n return buf;\n },\n\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n if (buf.length >= max) buf.shift();\n\n buf.push(value);\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return replaySubscribe(\n core,\n () => {\n const observer: Observer<T> =\n typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n for (const v of buf) {\n try {\n observer.next(v);\n } catch (err) {\n error('ReplaySubject: subscriber threw during replay', err);\n }\n }\n },\n observerOrNext,\n signal,\n );\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) =>\n replaySubscribe(\n core,\n () => {\n for (const v of buf) {\n try {\n obs.next(v);\n } catch (err) {\n error('ReplaySubject: subscriber threw during replay', err);\n }\n }\n },\n obs,\n ),\n );\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n };\n\n return subject;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subject.cjs","names":[],"sources":["../src/subject.ts"],"sourcesContent":["import type { Sink, Stream } from './types';\n\nimport { assertNonNegativeInteger } from './_numeric';\nimport { stream } from './core';\n\nexport type ChannelOptions<T> = {\n initial?: T;\n replay?: number;\n};\n\nexport type Channel<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n send(value: T): void;\n readonly stream: Stream<T>;\n};\n\nfunction replayCapacity<T>(options: ChannelOptions<T>): number {\n const capacity = options.replay ?? ('initial' in options ? 1 : 0);\n\n assertNonNegativeInteger(capacity, 'Channel replay');\n\n return capacity;\n}\n\n/** Channels own mutable multicast state; disposal is their only terminal event. */\nexport function createChannel<T>(options: ChannelOptions<T> = {}): Channel<T> {\n const capacity = replayCapacity(options);\n const controller = new AbortController();\n const listeners = new Set<Sink<T>>();\n const replay: T[] = [];\n\n if ('initial' in options && capacity > 0) replay.push(options.initial as T);\n\n const source = stream<T>((sink) => {\n for (const value of replay) sink.next(value);\n\n if (controller.signal.aborted) {\n sink.complete();\n\n return;\n }\n\n listeners.add(sink);\n\n return () => listeners.delete(sink);\n });\n\n const dispose = (): void => {\n if (controller.signal.aborted) return;\n\n controller.abort();\n\n for (const listener of [...listeners]) listener.complete();\n\n listeners.clear();\n };\n\n return {\n get disposalSignal(): AbortSignal {\n return controller.signal;\n },\n dispose,\n get disposed(): boolean {\n return controller.signal.aborted;\n },\n send(value: T): void {\n if (controller.signal.aborted) return;\n\n if (capacity > 0) {\n if (replay.length === capacity) replay.shift();\n\n replay.push(value);\n }\n\n for (const listener of [...listeners]) listener.next(value);\n },\n stream: source,\n [Symbol.dispose]: dispose,\n };\n}\n"],"mappings":"0DAmBA,SAAS,EAAkB,EAAoC,CAC7D,IAAM,EAAW,EAAQ,QAAW,cAAa,GAIjD,OAFA,EAAA,yBAAyB,EAAU,gBAAgB,EAE5C,CACT,CAGA,SAAgB,EAAiB,EAA6B,CAAC,EAAe,CAC5E,IAAM,EAAW,EAAe,CAAO,EACjC,EAAa,IAAI,gBACjB,EAAY,IAAI,IAChB,EAAc,CAAC,EAEjB,YAAa,GAAW,EAAW,GAAG,EAAO,KAAK,EAAQ,OAAY,EAE1E,IAAM,EAAS,EAAA,OAAW,GAAS,CACjC,IAAK,IAAM,KAAS,EAAQ,EAAK,KAAK,CAAK,EAE3C,GAAI,EAAW,OAAO,QAAS,CAC7B,EAAK,SAAS,EAEd,MACF,CAIA,OAFA,EAAU,IAAI,CAAI,MAEL,EAAU,OAAO,CAAI,CACpC,CAAC,EAEK,MAAsB,CACtB,MAAW,OAAO,QAEtB,GAAW,MAAM,EAEjB,IAAK,IAAM,IAAY,CAAC,GAAG,CAAS,EAAG,EAAS,SAAS,EAEzD,EAAU,MAAM,CAJC,CAKnB,EAEA,MAAO,CACL,IAAI,gBAA8B,CAChC,OAAO,EAAW,MACpB,EACA,UACA,IAAI,UAAoB,CACtB,OAAO,EAAW,OAAO,OAC3B,EACA,KAAK,EAAgB,CACf,MAAW,OAAO,QAEtB,CAAI,EAAW,IACT,EAAO,SAAW,GAAU,EAAO,MAAM,EAE7C,EAAO,KAAK,CAAK,GAGnB,IAAK,IAAM,IAAY,CAAC,GAAG,CAAS,EAAG,EAAS,KAAK,CAAK,CAF1D,CAGF,EACA,OAAQ,GACP,OAAO,SAAU,CACpB,CACF"}
|
package/dist/subject.d.ts
CHANGED
|
@@ -1,67 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export interface Subject<T> extends Flux<T> {
|
|
11
|
-
/** `true` after `dispose()` or `complete()` is called. */
|
|
1
|
+
import type { Stream } from './types';
|
|
2
|
+
export type ChannelOptions<T> = {
|
|
3
|
+
initial?: T;
|
|
4
|
+
replay?: number;
|
|
5
|
+
};
|
|
6
|
+
export type Channel<T> = {
|
|
7
|
+
[Symbol.dispose](): void;
|
|
8
|
+
readonly disposalSignal: AbortSignal;
|
|
9
|
+
dispose(): void;
|
|
12
10
|
readonly disposed: boolean;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
fail(err: unknown): void;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* A `BehaviorSubject` is a `Subject` that replays the latest value to
|
|
22
|
-
* any new subscriber immediately on subscription.
|
|
23
|
-
*/
|
|
24
|
-
export interface BehaviorSubject<T> extends Subject<T> {
|
|
25
|
-
/** The current (latest emitted) value. */
|
|
26
|
-
readonly value: T;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* A `ReplaySubject` is a `Subject` that replays the last N emitted values
|
|
30
|
-
* to any new subscriber immediately on subscription.
|
|
31
|
-
*/
|
|
32
|
-
export interface ReplaySubject<T> extends Subject<T> {
|
|
33
|
-
/** Snapshot of the current replay buffer (up to `bufferSize` entries). */
|
|
34
|
-
readonly buffer: readonly T[];
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Creates a new `Subject<T>`.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* const events = createSubject<string>();
|
|
41
|
-
* events.subscribe((s) => console.log(s));
|
|
42
|
-
* events.emit('hello');
|
|
43
|
-
* events.dispose();
|
|
44
|
-
*/
|
|
45
|
-
export declare function createSubject<T>(): Subject<T>;
|
|
46
|
-
/**
|
|
47
|
-
* Creates a new `BehaviorSubject<T>` with an initial value.
|
|
48
|
-
* Late subscribers immediately receive the current value on subscribe.
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* const count = createBehaviorSubject(0);
|
|
52
|
-
* count.subscribe((n) => console.log(n)); // logs 0 immediately
|
|
53
|
-
* count.emit(1); // logs 1
|
|
54
|
-
*/
|
|
55
|
-
export declare function createBehaviorSubject<T>(initial: T): BehaviorSubject<T>;
|
|
56
|
-
/**
|
|
57
|
-
* Creates a `ReplaySubject<T>` that buffers up to `bufferSize` values and
|
|
58
|
-
* replays them in order to any new subscriber immediately on subscription.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* const history = createReplaySubject<string>(3);
|
|
62
|
-
* history.emit('a');
|
|
63
|
-
* history.emit('b');
|
|
64
|
-
* history.subscribe(console.log); // logs 'a', 'b' immediately
|
|
65
|
-
*/
|
|
66
|
-
export declare function createReplaySubject<T>(bufferSize: number): ReplaySubject<T>;
|
|
11
|
+
send(value: T): void;
|
|
12
|
+
readonly stream: Stream<T>;
|
|
13
|
+
};
|
|
14
|
+
/** Channels own mutable multicast state; disposal is their only terminal event. */
|
|
15
|
+
export declare function createChannel<T>(options?: ChannelOptions<T>): Channel<T>;
|
|
67
16
|
//# sourceMappingURL=subject.d.ts.map
|
package/dist/subject.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"subject.d.ts","sourceRoot":"","sources":["../src/subject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,MAAM,EAAE,MAAM,SAAS,CAAC;AAK5C,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IACvB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CAC5B,CAAC;AAUF,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAE,cAAc,CAAC,CAAC,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAsD5E"}
|
package/dist/subject.js
CHANGED
|
@@ -1,181 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { makePipe as r } from "./_pipe.js";
|
|
4
|
-
import { clampPositiveInt as i } from "./_numeric.js";
|
|
1
|
+
import { stream as e } from "./core.js";
|
|
2
|
+
import { assertNonNegativeInteger as t } from "./_numeric.js";
|
|
5
3
|
//#region src/subject.ts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function r(t) {
|
|
10
|
-
for (let r of [...n]) try {
|
|
11
|
-
t(r);
|
|
12
|
-
} catch (t) {
|
|
13
|
-
e("Subscriber threw during broadcast", t);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function i(e, r) {
|
|
17
|
-
let i = typeof e == "function" ? { next: e } : e;
|
|
18
|
-
if (t.signal.aborted || r?.aborted) {
|
|
19
|
-
try {
|
|
20
|
-
i.complete?.();
|
|
21
|
-
} catch {}
|
|
22
|
-
return a;
|
|
23
|
-
}
|
|
24
|
-
n.add(i);
|
|
25
|
-
let o = () => {
|
|
26
|
-
n.delete(i), r && r.removeEventListener("abort", o);
|
|
27
|
-
};
|
|
28
|
-
return r && r.addEventListener("abort", o, { once: !0 }), o;
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
ac: t,
|
|
32
|
-
broadcast: r,
|
|
33
|
-
doSubscribe: i,
|
|
34
|
-
subscribers: n
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
function s(e, t, n, r) {
|
|
38
|
-
let i = typeof n == "function" ? { next: n } : n;
|
|
39
|
-
if (e.ac.signal.aborted || r?.aborted) {
|
|
40
|
-
try {
|
|
41
|
-
i.complete?.();
|
|
42
|
-
} catch {}
|
|
43
|
-
return a;
|
|
44
|
-
}
|
|
45
|
-
if (t(), e.ac.signal.aborted) {
|
|
46
|
-
try {
|
|
47
|
-
i.complete?.();
|
|
48
|
-
} catch {}
|
|
49
|
-
return a;
|
|
50
|
-
}
|
|
51
|
-
return e.doSubscribe(i, r);
|
|
52
|
-
}
|
|
53
|
-
function c(e) {
|
|
54
|
-
return () => {
|
|
55
|
-
e.ac.signal.aborted || (e.ac.abort(), e.broadcast((e) => e.complete?.()), e.subscribers.clear());
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function l(e) {
|
|
59
|
-
return (t) => {
|
|
60
|
-
e.ac.signal.aborted || (e.ac.abort(), e.broadcast((e) => e.error?.(t)), e.subscribers.clear());
|
|
61
|
-
};
|
|
4
|
+
function n(e) {
|
|
5
|
+
let n = e.replay ?? +("initial" in e);
|
|
6
|
+
return t(n, "Channel replay"), n;
|
|
62
7
|
}
|
|
63
|
-
function
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return e.ac.signal.aborted;
|
|
72
|
-
},
|
|
73
|
-
emit(t) {
|
|
74
|
-
e.ac.signal.aborted || e.broadcast((e) => e.next(t));
|
|
75
|
-
},
|
|
76
|
-
fail: l(e),
|
|
77
|
-
pipe: r(() => i),
|
|
78
|
-
subscribe(t, n) {
|
|
79
|
-
return e.doSubscribe(t, n);
|
|
80
|
-
},
|
|
81
|
-
[Symbol.asyncIterator]() {
|
|
82
|
-
return n((t) => e.doSubscribe(t));
|
|
83
|
-
},
|
|
84
|
-
[Symbol.dispose]() {
|
|
85
|
-
t();
|
|
8
|
+
function r(t = {}) {
|
|
9
|
+
let r = n(t), i = new AbortController(), a = /* @__PURE__ */ new Set(), o = [];
|
|
10
|
+
"initial" in t && r > 0 && o.push(t.initial);
|
|
11
|
+
let s = e((e) => {
|
|
12
|
+
for (let t of o) e.next(t);
|
|
13
|
+
if (i.signal.aborted) {
|
|
14
|
+
e.complete();
|
|
15
|
+
return;
|
|
86
16
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
get disposalSignal() {
|
|
94
|
-
return i.ac.signal;
|
|
95
|
-
},
|
|
96
|
-
dispose: a,
|
|
97
|
-
get disposed() {
|
|
98
|
-
return i.ac.signal.aborted;
|
|
99
|
-
},
|
|
100
|
-
emit(e) {
|
|
101
|
-
i.ac.signal.aborted || (d = e, i.broadcast((t) => t.next(e)));
|
|
102
|
-
},
|
|
103
|
-
fail: u,
|
|
104
|
-
pipe: r(() => f),
|
|
105
|
-
subscribe(t, n) {
|
|
106
|
-
return s(i, () => {
|
|
107
|
-
let n = typeof t == "function" ? { next: t } : t;
|
|
108
|
-
try {
|
|
109
|
-
n.next(d);
|
|
110
|
-
} catch (t) {
|
|
111
|
-
e("BehaviorSubject: subscriber threw during initial replay", t);
|
|
112
|
-
}
|
|
113
|
-
}, t, n);
|
|
114
|
-
},
|
|
115
|
-
[Symbol.asyncIterator]() {
|
|
116
|
-
return n((t) => s(i, () => {
|
|
117
|
-
try {
|
|
118
|
-
t.next(d);
|
|
119
|
-
} catch (t) {
|
|
120
|
-
e("BehaviorSubject: subscriber threw during initial replay", t);
|
|
121
|
-
}
|
|
122
|
-
}, t));
|
|
123
|
-
},
|
|
124
|
-
[Symbol.dispose]() {
|
|
125
|
-
a();
|
|
126
|
-
},
|
|
127
|
-
get value() {
|
|
128
|
-
return d;
|
|
17
|
+
return a.add(e), () => a.delete(e);
|
|
18
|
+
}), c = () => {
|
|
19
|
+
if (!i.signal.aborted) {
|
|
20
|
+
i.abort();
|
|
21
|
+
for (let e of [...a]) e.complete();
|
|
22
|
+
a.clear();
|
|
129
23
|
}
|
|
130
24
|
};
|
|
131
|
-
return
|
|
132
|
-
}
|
|
133
|
-
function f(a) {
|
|
134
|
-
let u = o(), d = c(u), f = l(u), { clamped: p, value: m } = i(a), h = [];
|
|
135
|
-
p && t(`createReplaySubject: bufferSize must be a finite integer >= 1, got ${a} — clamped to ${m}`);
|
|
136
|
-
let g = {
|
|
137
|
-
get buffer() {
|
|
138
|
-
return h;
|
|
139
|
-
},
|
|
140
|
-
complete: d,
|
|
25
|
+
return {
|
|
141
26
|
get disposalSignal() {
|
|
142
|
-
return
|
|
27
|
+
return i.signal;
|
|
143
28
|
},
|
|
144
|
-
dispose:
|
|
29
|
+
dispose: c,
|
|
145
30
|
get disposed() {
|
|
146
|
-
return
|
|
147
|
-
},
|
|
148
|
-
emit(e) {
|
|
149
|
-
u.ac.signal.aborted || (h.length >= m && h.shift(), h.push(e), u.broadcast((t) => t.next(e)));
|
|
31
|
+
return i.signal.aborted;
|
|
150
32
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
for (let t of h) try {
|
|
157
|
-
n.next(t);
|
|
158
|
-
} catch (t) {
|
|
159
|
-
e("ReplaySubject: subscriber threw during replay", t);
|
|
160
|
-
}
|
|
161
|
-
}, t, n);
|
|
33
|
+
send(e) {
|
|
34
|
+
if (!i.signal.aborted) {
|
|
35
|
+
r > 0 && (o.length === r && o.shift(), o.push(e));
|
|
36
|
+
for (let t of [...a]) t.next(e);
|
|
37
|
+
}
|
|
162
38
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
for (let n of h) try {
|
|
166
|
-
t.next(n);
|
|
167
|
-
} catch (t) {
|
|
168
|
-
e("ReplaySubject: subscriber threw during replay", t);
|
|
169
|
-
}
|
|
170
|
-
}, t));
|
|
171
|
-
},
|
|
172
|
-
[Symbol.dispose]() {
|
|
173
|
-
d();
|
|
174
|
-
}
|
|
39
|
+
stream: s,
|
|
40
|
+
[Symbol.dispose]: c
|
|
175
41
|
};
|
|
176
|
-
return g;
|
|
177
42
|
}
|
|
178
43
|
//#endregion
|
|
179
|
-
export {
|
|
44
|
+
export { r as createChannel };
|
|
180
45
|
|
|
181
46
|
//# sourceMappingURL=subject.js.map
|
package/dist/subject.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subject.js","names":[],"sources":["../src/subject.ts"],"sourcesContent":["import type { Flux, Observer, Unsubscribe } from './types';\n\nimport { error, warn } from './_dev';\nimport { makeAsyncIterator } from './_iterator';\nimport { clampPositiveInt } from './_numeric';\nimport { makePipe } from './_pipe';\n\nconst NOOP: Unsubscribe = () => {};\n\n/**\n * A `Subject` is both a `Flux` and a manual emission handle.\n * Calling `emit()` pushes a value to all active subscribers.\n *\n * A Subject is hot — all subscribers share the same emission sequence.\n * Subscribers that subscribe after an emission will NOT receive past values.\n * Use `BehaviorSubject` to replay the latest value to late subscribers.\n */\nexport interface Subject<T> extends Flux<T> {\n /** `true` after `dispose()` or `complete()` is called. */\n readonly disposed: boolean;\n /** Emit a complete signal to all subscribers and dispose the subject. */\n complete(): void;\n /** Push a value to all active subscribers. */\n emit(value: T): void;\n /** Push an error to all active subscribers and dispose the subject. */\n fail(err: unknown): void;\n}\n\n/**\n * A `BehaviorSubject` is a `Subject` that replays the latest value to\n * any new subscriber immediately on subscription.\n */\nexport interface BehaviorSubject<T> extends Subject<T> {\n /** The current (latest emitted) value. */\n readonly value: T;\n}\n\n/**\n * A `ReplaySubject` is a `Subject` that replays the last N emitted values\n * to any new subscriber immediately on subscription.\n */\nexport interface ReplaySubject<T> extends Subject<T> {\n /** Snapshot of the current replay buffer (up to `bufferSize` entries). */\n readonly buffer: readonly T[];\n}\n\n// ── Shared internals ──────────────────────────────────────────────────────────\n\ninterface SubjectCore<T> {\n ac: AbortController;\n broadcast(fn: (obs: Observer<T>) => void): void;\n doSubscribe(observerOrNext: Observer<T> | ((value: T) => void), signal?: AbortSignal): Unsubscribe;\n subscribers: Set<Observer<T>>;\n}\n\nfunction makeCore<T>(): SubjectCore<T> {\n const ac = new AbortController();\n const subscribers = new Set<Observer<T>>();\n\n function broadcast(fn: (obs: Observer<T>) => void): void {\n for (const obs of [...subscribers]) {\n try {\n fn(obs);\n } catch (err) {\n error('Subscriber threw during broadcast', err);\n }\n }\n }\n\n function doSubscribe(observerOrNext: Observer<T> | ((value: T) => void), signal?: AbortSignal): Unsubscribe {\n const observer: Observer<T> = typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n if (ac.signal.aborted || signal?.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n subscribers.add(observer);\n\n const unsub = (): void => {\n subscribers.delete(observer);\n\n if (signal) signal.removeEventListener('abort', unsub);\n };\n\n if (signal) signal.addEventListener('abort', unsub, { once: true });\n\n return unsub;\n }\n\n return { ac, broadcast, doSubscribe, subscribers };\n}\n\n// Safely emit initial replay values; re-check disposed after sync replay.\nfunction replaySubscribe<T>(\n core: SubjectCore<T>,\n replay: () => void,\n observerOrNext: Observer<T> | ((value: T) => void),\n signal?: AbortSignal,\n): Unsubscribe {\n const observer: Observer<T> = typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n if (core.ac.signal.aborted || signal?.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n replay();\n\n // Re-check: the synchronous replay may have triggered a dispose.\n if (core.ac.signal.aborted) {\n try {\n observer.complete?.();\n } catch {\n /* empty */\n }\n\n return NOOP;\n }\n\n return core.doSubscribe(observer, signal);\n}\n\n/**\n * Shared `dispose()` implementation for every `Subject` variant: aborts the core,\n * notifies all active subscribers with `complete()`, and clears the subscriber set.\n * Reused instead of being copy-pasted per factory.\n * @internal\n */\nfunction makeDispose<T>(core: SubjectCore<T>): () => void {\n return () => {\n if (core.ac.signal.aborted) return;\n\n core.ac.abort();\n core.broadcast((obs) => obs.complete?.());\n core.subscribers.clear();\n };\n}\n\n/**\n * Shared `fail()` implementation for every `Subject` variant: aborts the core,\n * notifies all active subscribers with `error()`, and clears the subscriber set.\n * Reused instead of being copy-pasted per factory.\n * @internal\n */\nfunction makeFail<T>(core: SubjectCore<T>): (err: unknown) => void {\n return (err) => {\n if (core.ac.signal.aborted) return;\n\n core.ac.abort();\n core.broadcast((obs) => obs.error?.(err));\n core.subscribers.clear();\n };\n}\n\n// ── createSubject ─────────────────────────────────────────────────────────────\n\n/**\n * Creates a new `Subject<T>`.\n *\n * @example\n * const events = createSubject<string>();\n * events.subscribe((s) => console.log(s));\n * events.emit('hello');\n * events.dispose();\n */\nexport function createSubject<T>(): Subject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n\n const subject: Subject<T> = {\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return core.doSubscribe(observerOrNext, signal);\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) => core.doSubscribe(obs));\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n };\n\n return subject;\n}\n\n// ── createBehaviorSubject ─────────────────────────────────────────────────────\n\n/**\n * Creates a new `BehaviorSubject<T>` with an initial value.\n * Late subscribers immediately receive the current value on subscribe.\n *\n * @example\n * const count = createBehaviorSubject(0);\n * count.subscribe((n) => console.log(n)); // logs 0 immediately\n * count.emit(1); // logs 1\n */\nexport function createBehaviorSubject<T>(initial: T): BehaviorSubject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n let current = initial;\n\n const subject: BehaviorSubject<T> = {\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n current = value;\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return replaySubscribe(\n core,\n () => {\n const observer: Observer<T> =\n typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n try {\n observer.next(current);\n } catch (err) {\n error('BehaviorSubject: subscriber threw during initial replay', err);\n }\n },\n observerOrNext,\n signal,\n );\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) =>\n replaySubscribe(\n core,\n () => {\n try {\n obs.next(current);\n } catch (err) {\n error('BehaviorSubject: subscriber threw during initial replay', err);\n }\n },\n obs,\n ),\n );\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n\n get value(): T {\n return current;\n },\n };\n\n return subject;\n}\n\n// ── createReplaySubject ───────────────────────────────────────────────────────\n\n/**\n * Creates a `ReplaySubject<T>` that buffers up to `bufferSize` values and\n * replays them in order to any new subscriber immediately on subscription.\n *\n * @example\n * const history = createReplaySubject<string>(3);\n * history.emit('a');\n * history.emit('b');\n * history.subscribe(console.log); // logs 'a', 'b' immediately\n */\nexport function createReplaySubject<T>(bufferSize: number): ReplaySubject<T> {\n const core = makeCore<T>();\n const dispose = makeDispose(core);\n const fail = makeFail(core);\n const { clamped, value: max } = clampPositiveInt(bufferSize);\n const buf: T[] = [];\n\n if (clamped) {\n warn(`createReplaySubject: bufferSize must be a finite integer >= 1, got ${bufferSize} — clamped to ${max}`);\n }\n\n const subject: ReplaySubject<T> = {\n get buffer(): readonly T[] {\n return buf;\n },\n\n complete: dispose,\n\n get disposalSignal(): AbortSignal {\n return core.ac.signal;\n },\n\n dispose,\n\n get disposed(): boolean {\n return core.ac.signal.aborted;\n },\n\n emit(value: T): void {\n if (core.ac.signal.aborted) return;\n\n if (buf.length >= max) buf.shift();\n\n buf.push(value);\n core.broadcast((obs) => obs.next(value));\n },\n\n fail,\n\n pipe: makePipe(() => subject),\n\n subscribe(observerOrNext, signal) {\n return replaySubscribe(\n core,\n () => {\n const observer: Observer<T> =\n typeof observerOrNext === 'function' ? { next: observerOrNext } : observerOrNext;\n\n for (const v of buf) {\n try {\n observer.next(v);\n } catch (err) {\n error('ReplaySubject: subscriber threw during replay', err);\n }\n }\n },\n observerOrNext,\n signal,\n );\n },\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return makeAsyncIterator<T>((obs) =>\n replaySubscribe(\n core,\n () => {\n for (const v of buf) {\n try {\n obs.next(v);\n } catch (err) {\n error('ReplaySubject: subscriber threw during replay', err);\n }\n }\n },\n obs,\n ),\n );\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n };\n\n return subject;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subject.js","names":[],"sources":["../src/subject.ts"],"sourcesContent":["import type { Sink, Stream } from './types';\n\nimport { assertNonNegativeInteger } from './_numeric';\nimport { stream } from './core';\n\nexport type ChannelOptions<T> = {\n initial?: T;\n replay?: number;\n};\n\nexport type Channel<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n send(value: T): void;\n readonly stream: Stream<T>;\n};\n\nfunction replayCapacity<T>(options: ChannelOptions<T>): number {\n const capacity = options.replay ?? ('initial' in options ? 1 : 0);\n\n assertNonNegativeInteger(capacity, 'Channel replay');\n\n return capacity;\n}\n\n/** Channels own mutable multicast state; disposal is their only terminal event. */\nexport function createChannel<T>(options: ChannelOptions<T> = {}): Channel<T> {\n const capacity = replayCapacity(options);\n const controller = new AbortController();\n const listeners = new Set<Sink<T>>();\n const replay: T[] = [];\n\n if ('initial' in options && capacity > 0) replay.push(options.initial as T);\n\n const source = stream<T>((sink) => {\n for (const value of replay) sink.next(value);\n\n if (controller.signal.aborted) {\n sink.complete();\n\n return;\n }\n\n listeners.add(sink);\n\n return () => listeners.delete(sink);\n });\n\n const dispose = (): void => {\n if (controller.signal.aborted) return;\n\n controller.abort();\n\n for (const listener of [...listeners]) listener.complete();\n\n listeners.clear();\n };\n\n return {\n get disposalSignal(): AbortSignal {\n return controller.signal;\n },\n dispose,\n get disposed(): boolean {\n return controller.signal.aborted;\n },\n send(value: T): void {\n if (controller.signal.aborted) return;\n\n if (capacity > 0) {\n if (replay.length === capacity) replay.shift();\n\n replay.push(value);\n }\n\n for (const listener of [...listeners]) listener.next(value);\n },\n stream: source,\n [Symbol.dispose]: dispose,\n };\n}\n"],"mappings":";;;AAmBA,SAAS,EAAkB,GAAoC;CAC7D,IAAM,IAAW,EAAQ,UAAW,eAAa;CAIjD,OAFA,EAAyB,GAAU,gBAAgB,GAE5C;AACT;AAGA,SAAgB,EAAiB,IAA6B,CAAC,GAAe;CAC5E,IAAM,IAAW,EAAe,CAAO,GACjC,IAAa,IAAI,gBAAgB,GACjC,oBAAY,IAAI,IAAa,GAC7B,IAAc,CAAC;CAErB,AAAI,aAAa,KAAW,IAAW,KAAG,EAAO,KAAK,EAAQ,OAAY;CAE1E,IAAM,IAAS,GAAW,MAAS;EACjC,KAAK,IAAM,KAAS,GAAQ,EAAK,KAAK,CAAK;EAE3C,IAAI,EAAW,OAAO,SAAS;GAC7B,EAAK,SAAS;GAEd;EACF;EAIA,OAFA,EAAU,IAAI,CAAI,SAEL,EAAU,OAAO,CAAI;CACpC,CAAC,GAEK,UAAsB;EACtB,OAAW,OAAO,SAEtB;KAAW,MAAM;GAEjB,KAAK,IAAM,KAAY,CAAC,GAAG,CAAS,GAAG,EAAS,SAAS;GAEzD,EAAU,MAAM;EAJC;CAKnB;CAEA,OAAO;EACL,IAAI,iBAA8B;GAChC,OAAO,EAAW;EACpB;EACA;EACA,IAAI,WAAoB;GACtB,OAAO,EAAW,OAAO;EAC3B;EACA,KAAK,GAAgB;GACf,OAAW,OAAO,SAEtB;IAAI,IAAW,MACT,EAAO,WAAW,KAAU,EAAO,MAAM,GAE7C,EAAO,KAAK,CAAK;IAGnB,KAAK,IAAM,KAAY,CAAC,GAAG,CAAS,GAAG,EAAS,KAAK,CAAK;GAF1D;EAGF;EACA,QAAQ;GACP,OAAO,UAAU;CACpB;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./subject.cjs");exports.createChannel=e.createChannel;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subjects.d.ts","sourceRoot":"","sources":["../src/subjects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/subjects.js
ADDED
package/dist/types.d.ts
CHANGED
|
@@ -1,86 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* global fake-timer mechanisms (`vi.useFakeTimers()`).
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* const testScheduler: Scheduler = {
|
|
10
|
-
* delay(fn, ms) { ... },
|
|
11
|
-
* repeat(fn, ms) { ... },
|
|
12
|
-
* };
|
|
13
|
-
* debounce(300, testScheduler);
|
|
14
|
-
*/
|
|
15
|
-
export type Scheduler = {
|
|
16
|
-
/** Schedule `fn` to run once after `ms` milliseconds. Returns a cancel function. */
|
|
17
|
-
delay(fn: () => void, ms: number): () => void;
|
|
18
|
-
/** Schedule `fn` to run repeatedly every `ms` milliseconds. Returns a cancel function. */
|
|
19
|
-
repeat(fn: () => void, ms: number): () => void;
|
|
1
|
+
export type Teardown = () => void;
|
|
2
|
+
export type Subscription = {
|
|
3
|
+
[Symbol.dispose](): void;
|
|
4
|
+
readonly closed: boolean;
|
|
5
|
+
unsubscribe(): void;
|
|
20
6
|
};
|
|
21
|
-
/**
|
|
22
|
-
* Observer passed to a producer or `subscribe()`.
|
|
23
|
-
* `error` and `complete` are optional — omit them to ignore those signals.
|
|
24
|
-
*/
|
|
25
7
|
export type Observer<T> = {
|
|
26
8
|
complete?: () => void;
|
|
27
|
-
error?: (
|
|
9
|
+
error?: (reason: unknown) => void;
|
|
28
10
|
next: (value: T) => void;
|
|
29
11
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export type Operator<A = unknown, B = unknown> = (source: Flux<A>) => Flux<B>;
|
|
44
|
-
/**
|
|
45
|
-
* The core stream primitive. Lazy (cold) by default — each `subscribe()` invocation
|
|
46
|
-
* starts its own producer. Use `.pipe(share())` to multicast to many subscribers.
|
|
47
|
-
*/
|
|
48
|
-
export interface Flux<T> {
|
|
49
|
-
/** `true` after `dispose()` is called. New subscriptions receive an immediate `complete` notification. */
|
|
50
|
-
readonly disposed: boolean;
|
|
51
|
-
/** AbortSignal that aborts when `dispose()` is called. */
|
|
52
|
-
readonly disposalSignal: AbortSignal;
|
|
53
|
-
/** Permanently terminates this stream. All active subscribers receive a `complete` notification. */
|
|
54
|
-
dispose(): void;
|
|
55
|
-
/**
|
|
56
|
-
* Apply one or more operators in sequence. Each operator receives the output
|
|
57
|
-
* of the previous one as its input, forming a pipeline.
|
|
58
|
-
*/
|
|
59
|
-
pipe<B>(op1: Operator<T, B>): Flux<B>;
|
|
60
|
-
pipe<B, C>(op1: Operator<T, B>, op2: Operator<B, C>): Flux<C>;
|
|
61
|
-
pipe<B, C, D>(op1: Operator<T, B>, op2: Operator<B, C>, op3: Operator<C, D>): Flux<D>;
|
|
62
|
-
pipe<B, C, D, E>(op1: Operator<T, B>, op2: Operator<B, C>, op3: Operator<C, D>, op4: Operator<D, E>): Flux<E>;
|
|
63
|
-
pipe(...operators: Operator[]): Flux<unknown>;
|
|
64
|
-
/**
|
|
65
|
-
* Subscribe to values emitted by this stream.
|
|
66
|
-
* Accepts either a full `Observer<T>` object or a plain `next` function.
|
|
67
|
-
* Returns an unsubscribe function — call it to stop receiving values.
|
|
68
|
-
* Pass an optional `AbortSignal` to unsubscribe automatically when the signal aborts.
|
|
69
|
-
* If the stream is already disposed, the observer receives an immediate `complete` notification.
|
|
70
|
-
*/
|
|
71
|
-
subscribe(observerOrNext: Observer<T> | ((value: T) => void), signal?: AbortSignal): Unsubscribe;
|
|
72
|
-
/**
|
|
73
|
-
* Consume the stream as an async iterator.
|
|
74
|
-
* Buffers incoming values until consumed.
|
|
75
|
-
* Calling `return()` on the iterator (or exiting a `for await` loop early) unsubscribes from the source.
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* for await (const value of source$) {
|
|
79
|
-
* console.log(value);
|
|
80
|
-
* }
|
|
81
|
-
*/
|
|
82
|
-
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
|
83
|
-
/** ES2026 `using` compatible disposal. Delegates to `dispose()`. */
|
|
84
|
-
[Symbol.dispose](): void;
|
|
12
|
+
export type SubscribeOptions = {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
};
|
|
15
|
+
export type Sink<T> = {
|
|
16
|
+
complete(): void;
|
|
17
|
+
error(reason: unknown): void;
|
|
18
|
+
next(value: T): void;
|
|
19
|
+
};
|
|
20
|
+
export type Producer<T> = (sink: Sink<T>, signal: AbortSignal) => Teardown | void;
|
|
21
|
+
export type Operator<A = unknown, B = unknown> = (source: Stream<A>) => Stream<B>;
|
|
22
|
+
/** Streams describe reusable work. Subscriptions own lifetime. */
|
|
23
|
+
export interface Stream<T> {
|
|
24
|
+
subscribe(observer: Observer<T> | ((value: T) => void), options?: SubscribeOptions): Subscription;
|
|
85
25
|
}
|
|
26
|
+
export type OverflowPolicy = 'drop-newest' | 'drop-oldest' | 'error';
|
|
27
|
+
export type AsyncIterableOptions = {
|
|
28
|
+
capacity: number;
|
|
29
|
+
overflow: OverflowPolicy;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
};
|
|
32
|
+
type PipeResult<Input, Operators extends readonly unknown[]> = Operators extends readonly [
|
|
33
|
+
Operator<Input, infer Output>,
|
|
34
|
+
...infer Remaining
|
|
35
|
+
] ? PipeResult<Output, Remaining> : Stream<Input>;
|
|
36
|
+
export type ValidPipe<Input, Operators extends readonly unknown[]> = Operators extends readonly [] ? [] : Operators extends readonly [Operator<Input, infer Output>, ...infer Remaining] ? [Operator<Input, Output>, ...ValidPipe<Output, Remaining>] : never;
|
|
37
|
+
export type PipedStream<Input, Operators extends readonly unknown[]> = PipeResult<Input, Operators>;
|
|
38
|
+
export {};
|
|
86
39
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,WAAW,IAAI,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;IACpB,QAAQ,IAAI,IAAI,CAAC;IACjB,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,QAAQ,GAAG,IAAI,CAAC;AAElF,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;AAElF,kEAAkE;AAClE,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAAC;CACnG;AAED,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,aAAa,GAAG,OAAO,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,KAAK,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,SAAS,OAAO,EAAE,IAAI,SAAS,SAAS,SAAS;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,GAAG,MAAM,SAAS;CACnB,GACG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,MAAM,CAAC,KAAK,CAAC,CAAC;AAElB,MAAM,MAAM,SAAS,CAAC,KAAK,EAAE,SAAS,SAAS,SAAS,OAAO,EAAE,IAAI,SAAS,SAAS,SAAS,EAAE,GAC9F,EAAE,GACF,SAAS,SAAS,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,SAAS,CAAC,GAC5E,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,GAC1D,KAAK,CAAC;AAEZ,MAAM,MAAM,WAAW,CAAC,KAAK,EAAE,SAAS,SAAS,SAAS,OAAO,EAAE,IAAI,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC"}
|