@vielzeug/herald 26.11.12 → 26.11.13

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/bus.cjs CHANGED
@@ -1,2 +1,2 @@
1
- require("./_dev.cjs");const e=require("./errors.cjs");var noop=()=>{};function createBus(t){let n=new Map,r=new Set,i=new Set,a=new AbortController,o=t?.name,s=t?.maxListeners,c=o?` (${o})`:``;function emitTap(e){if(i.size!==0)for(let t of i)try{t(e)}catch{}}function createSubscriptionScope(e){return e?AbortSignal.any([a.signal,e]):a.signal}function registerEntry(e,t,n,{event:r,onLog:i,onRemove:a,wildcard:o}){if(n.aborted)return noop;let l=!1;function unsub(){l||(l=!0,e.delete(u),a?.(),n.removeEventListener(`abort`,unsub),r===void 0?o&&emitTap({type:`unsubscribe-any`}):emitTap({event:r,type:`unsubscribe`}))}let u=t(unsub);return e.add(u),n.addEventListener(`abort`,unsub,{once:!0}),r===void 0?o&&emitTap({type:`subscribe-any`}):emitTap({event:r,type:`subscribe`}),s!==void 0&&e.size>s&&`${i}${e.size}${s}${c}`,unsub}function onWithSignal(e,t,r,i){let a=n.get(e);a||(a=new Set,n.set(e,a));let o=a;return registerEntry(o,e=>({fn:t,unsub:e}),r,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&n.delete(e),i?.()}})}function onAnyWithSignal(e,t,n){return registerEntry(r,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:n,wildcard:!0})}function onceWithSignal(e,t,n,r){let i={unsub:noop};return i.unsub=onWithSignal(e,e=>{i.unsub(),t(e)},n,r),i.unsub}function on(e,t,n){return onWithSignal(e,t,createSubscriptionScope(n?.signal))}function once(e,t,n){return onceWithSignal(e,t,createSubscriptionScope(n?.signal))}function onAny(e,t){return onAnyWithSignal(e,createSubscriptionScope(t?.signal))}function wait(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let onAbort=()=>{r(n.reason)};onceWithSignal(e,e=>{n.removeEventListener(`abort`,onAbort),t(e)},n),n.addEventListener(`abort`,onAbort,{once:!0})})}function dispatch(e,t){let i=0,a,o=n.get(e);if(o?.size)for(let n of[...o]){try{n.fn(t)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(r.size)for(let n of[...r]){try{n.fn(e,t)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:t,type:`emit`}),a)throw a.value}function emit(e,...t){if(a.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return n.get(e)?.size??0;let t=0;for(let e of n.values())t+=e.size;return t}function wildcardCount(){return r.size}function eventNames(){return[...n.keys()]}function tap(e,t){if(a.signal.aborted)return noop;let n=createSubscriptionScope(t?.signal);if(n.aborted)return noop;i.add(e);let onAbort=()=>i.delete(e);return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{i.delete(e),n.removeEventListener(`abort`,onAbort)}}function waitAny(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=new AbortController,a=AbortSignal.any([n,i.signal]),o=[],s=!1;function cleanup(){n.removeEventListener(`abort`,onAbort),i.abort();for(let e of o)e()}function onAbort(){s||(s=!0,cleanup(),r(n.reason))}n.addEventListener(`abort`,onAbort,{once:!0});for(let n of e)o.push(onceWithSignal(n,e=>{s||(s=!0,cleanup(),t({event:n,payload:e}))},a))})}function dispose(){a.signal.aborted||(emitTap({type:`dispose`}),a.abort(new e.BusDisposedError(o)),n.clear(),r.clear(),i.clear())}return{get disposalSignal(){return a.signal},dispose,get disposed(){return a.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}exports.createBus=createBus,exports.noop=noop;
1
+ require("./_dev.cjs");const e=require("./errors.cjs");var noop=()=>{};function createBus(t){let n=new Map,r=new Set,i=new Set,a=new AbortController,o=t?.name,s=t?.maxListeners,c=o?` (${o})`:``;function emitTap(e){for(let t of i)try{t(e)}catch{}}function subscriptionSignal(e){return e?AbortSignal.any([a.signal,e]):a.signal}function register(e,t,n,r,i){if(n.aborted)return noop;let a=!1;function unsub(){a||(a=!0,e.delete(o),n.removeEventListener(`abort`,unsub),emitTap(i.unsubscribe))}let o=t(unsub);return e.add(o),n.addEventListener(`abort`,unsub,{once:!0}),emitTap(i.subscribe),s!==void 0&&e.size>s&&`${r}${e.size}${s}${c}`,unsub}function onScoped(e,t,r){let i=n.get(e);return i||(i=new Set,n.set(e,i)),register(i,e=>({fn:t,unsub:e}),r,`on("${e}")`,{subscribe:{event:e,type:`subscribe`},unsubscribe:{event:e,type:`unsubscribe`}})}function onAnyScoped(e,t){return register(r,t=>({fn:e,unsub:t}),t,`onAny`,{subscribe:{type:`subscribe-any`},unsubscribe:{type:`unsubscribe-any`}})}function onceScoped(e,t,n){let r=onScoped(e,e=>{r(),t(e)},n);return r}function on(e,t,n){return onScoped(e,t,subscriptionSignal(n?.signal))}function once(e,t,n){return onceScoped(e,t,subscriptionSignal(n?.signal))}function onAny(e,t){return onAnyScoped(e,subscriptionSignal(t?.signal))}function waitScoped(e,t){return t.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let onAbort=()=>{r(t.reason)};onceScoped(e,e=>{t.removeEventListener(`abort`,onAbort),n(e)},t),t.addEventListener(`abort`,onAbort,{once:!0})})}function wait(e,t){return waitScoped(e,subscriptionSignal(t?.signal))}function waitAny(e,t){if(e.length===0)throw TypeError(`waitAny() requires at least one event name`);let n=new AbortController,r=AbortSignal.any([subscriptionSignal(t?.signal),n.signal]),i=e.map(e=>waitScoped(e,r).then(t=>({event:e,payload:t})));for(let e of i)e.catch(noop);return Promise.race(i).then(e=>(n.abort(),e))}function dispatch(e,t){let i=0,a,o=n.get(e);if(o?.size)for(let n of[...o]){try{n.fn(t)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(r.size)for(let n of[...r]){try{n.fn(e,t)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:t,type:`emit`}),a)throw a.value}function emit(e,...t){if(a.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return n.get(e)?.size??0;let t=0;for(let e of n.values())t+=e.size;return t}function wildcardCount(){return r.size}function eventNames(){let e=[];for(let[t,r]of n)r.size>0&&e.push(t);return e}function tap(e,t){let n=subscriptionSignal(t?.signal);if(n.aborted)return noop;i.add(e);let onAbort=()=>{i.delete(e)};return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{i.delete(e),n.removeEventListener(`abort`,onAbort)}}function dispose(){a.signal.aborted||(emitTap({type:`dispose`}),a.abort(new e.BusDisposedError(o)),n.clear(),r.clear(),i.clear())}return{get disposalSignal(){return a.signal},dispose,get disposed(){return a.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}exports.createBus=createBus;
2
2
  //# sourceMappingURL=bus.cjs.map
package/dist/bus.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bus.cjs","names":["BusDisposedError","require_errors","listeners","wildcards","tappers","disposeController","busName","options","maxListeners","busTag","tapper","event","signal","called","container","entry","onRemove","wildcard","makeEntry","onLog","set","capturedSet","listener","ref","payload","opts","reject","resolve","count","firstError","err","args","total","handler","activeSignal","raceController","raceSignal","unsubs","settled","unsub","eventList"],"sources":["../src/bus.ts"],"sourcesContent":["import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\n/** @internal */\nexport const noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\ntype RegisterEntryOpts<T extends EventMap> = {\n event?: EventKey<T>;\n onLog: string;\n onRemove?: () => void;\n wildcard?: boolean;\n};\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n if (tappers.size === 0) return;\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function doWarn(msg: string): void {\n _internalWarn(msg);\n }\n\n function createSubscriptionScope(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function registerEntry<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n { event, onLog, onRemove, wildcard }: RegisterEntryOpts<T>,\n ): () => void {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub() {\n if (called) return;\n\n called = true;\n container.delete(entry);\n onRemove?.();\n signal.removeEventListener('abort', unsub);\n\n if (event !== undefined) emitTap({ event, type: 'unsubscribe' });\n else if (wildcard) emitTap({ type: 'unsubscribe-any' });\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n\n if (event !== undefined) emitTap({ event, type: 'subscribe' });\n else if (wildcard) emitTap({ type: 'subscribe-any' });\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n doWarn(\n `${onLog} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n const capturedSet = set;\n\n return registerEntry(capturedSet, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, {\n event,\n onLog: `on(\"${event}\")`,\n onRemove: () => {\n if (capturedSet.size === 0) listeners.delete(event);\n\n onRemove?.();\n },\n });\n }\n\n function onAnyWithSignal(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n return registerEntry(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n { onLog: 'onAny', onRemove, wildcard: true },\n );\n }\n\n function onceWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onWithSignal(\n event,\n (payload) => {\n ref.unsub();\n listener(payload);\n },\n signal,\n onRemove,\n );\n\n return ref.unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): () => void {\n return onWithSignal(event, listener, createSubscriptionScope(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n opts?: { signal?: AbortSignal },\n ): () => void {\n const signal = createSubscriptionScope(opts?.signal);\n\n return onceWithSignal(event, listener, signal);\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): () => void {\n return onAnyWithSignal(listener, createSubscriptionScope(opts?.signal));\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: { signal?: AbortSignal }): Promise<T[K]> {\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason);\n };\n\n onceWithSignal(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n function eventNames(): EventKey<T>[] {\n return [...listeners.keys()] as EventKey<T>[];\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: { signal?: AbortSignal }): () => void {\n if (disposeController.signal.aborted) return noop;\n\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = () => tappers.delete(handler);\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function waitAny<K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n const activeSignal = createSubscriptionScope(opts?.signal);\n\n if (activeSignal.aborted) return Promise.reject(activeSignal.reason);\n\n return new Promise<WaitAnyResult<T, K>>((resolve, reject) => {\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([activeSignal, raceController.signal]);\n const unsubs: Unsubscribe[] = [];\n let settled = false;\n\n function cleanup(): void {\n activeSignal.removeEventListener('abort', onAbort);\n raceController.abort();\n for (const unsub of unsubs) unsub();\n }\n\n function onAbort(): void {\n if (settled) return;\n\n settled = true;\n cleanup();\n reject(activeSignal.reason);\n }\n\n activeSignal.addEventListener('abort', onAbort, { once: true });\n\n for (const event of eventList) {\n unsubs.push(\n onceWithSignal(\n event as EventKey<T>,\n (payload) => {\n if (settled) return;\n\n settled = true;\n cleanup();\n resolve({ event, payload } as WaitAnyResult<T, K>);\n },\n raceSignal,\n ),\n );\n }\n });\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bus.cjs","names":["BusDisposedError","require_errors","listeners","wildcards","tappers","disposeController","busName","options","maxListeners","busTag","tapper","event","signal","called","container","entry","tapEvents","makeEntry","label","set","listener","unsub","payload","opts","reject","resolve","eventList","raceController","raceSignal","waiters","waiter","result","count","firstError","err","args","total","active","handler"],"sources":["../src/bus.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\nconst noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function subscriptionSignal(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function register<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n label: string,\n tapEvents: { readonly subscribe: HeraldEvent<T>; readonly unsubscribe: HeraldEvent<T> },\n ): Unsubscribe {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub(): void {\n if (called) return;\n\n called = true;\n container.delete(entry);\n signal.removeEventListener('abort', unsub);\n emitTap(tapEvents.unsubscribe);\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n emitTap(tapEvents.subscribe);\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n warn(\n `${label} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n return register(set, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, `on(\"${event}\")`, {\n subscribe: { event, type: 'subscribe' },\n unsubscribe: { event, type: 'unsubscribe' },\n });\n }\n\n function onAnyScoped(listener: (event: EventKey<T>, payload: unknown) => void, signal: AbortSignal): Unsubscribe {\n return register(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n 'onAny',\n {\n subscribe: { type: 'subscribe-any' },\n unsubscribe: { type: 'unsubscribe-any' },\n },\n );\n }\n\n // The wrapper calls `unsub` only when the listener runs, which is always after the\n // assignment completed; no indirection object is needed.\n function onceScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n const unsub = onScoped(\n event,\n (payload) => {\n unsub();\n listener(payload);\n },\n signal,\n );\n\n return unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onceScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe {\n return onAnyScoped(listener, subscriptionSignal(opts?.signal));\n }\n\n // `signal` must already combine bus disposal with any caller-provided signal.\n function waitScoped<K extends EventKey<T>>(event: K, signal: AbortSignal): Promise<T[K]> {\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = (): void => {\n reject(signal.reason);\n };\n\n onceScoped(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]> {\n return waitScoped(event, subscriptionSignal(opts?.signal));\n }\n\n function waitAny<const K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: SubscribeOptions,\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length === 0) {\n throw new TypeError('waitAny() requires at least one event name');\n }\n\n // One-shot `wait()` per event sharing one signal: an internal controller aborts the\n // loser subscriptions once one resolves, and `Promise.race` provides the settled-once\n // winner/loser semantics, rejection with the composite signal's reason included.\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([subscriptionSignal(opts?.signal), raceController.signal]);\n const waiters = eventList.map((event) => waitScoped(event, raceSignal).then((payload) => ({ event, payload })));\n\n // Losers reject through the cleanup abort: keep every rejection observed.\n for (const waiter of waiters) waiter.catch(noop);\n\n return Promise.race(waiters).then((result) => {\n raceController.abort();\n return result as WaitAnyResult<T, K>;\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n // Empty sets stay in `listeners` after their last listener leaves (removing them eagerly\n // on unsubscribe is what previously corrupted re-registered listeners); filter here instead.\n function eventNames(): EventKey<T>[] {\n const active: EventKey<T>[] = [];\n\n for (const [event, set] of listeners) {\n if (set.size > 0) active.push(event as EventKey<T>);\n }\n\n return active;\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: SubscribeOptions): Unsubscribe {\n const signal = subscriptionSignal(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = (): void => {\n tappers.delete(handler);\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
package/dist/bus.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../src/bus.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,GAAG,EACH,UAAU,EAEV,QAAQ,EAMT,MAAM,SAAS,CAAC;AAgBjB,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,CAuUpG"}
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../src/bus.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,GAAG,EACH,UAAU,EAEV,QAAQ,EAMT,MAAM,SAAS,CAAC;AAQjB,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,CAyRpG"}
package/dist/bus.js CHANGED
@@ -5,79 +5,84 @@ var noop = () => {};
5
5
  function createBus(t) {
6
6
  let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = new AbortController(), o = t?.name, s = t?.maxListeners, c = o ? ` (${o})` : "";
7
7
  function emitTap(e) {
8
- if (i.size !== 0) for (let t of i) try {
8
+ for (let t of i) try {
9
9
  t(e);
10
10
  } catch {}
11
11
  }
12
- function createSubscriptionScope(e) {
12
+ function subscriptionSignal(e) {
13
13
  return e ? AbortSignal.any([a.signal, e]) : a.signal;
14
14
  }
15
- function registerEntry(e, t, n, { event: r, onLog: i, onRemove: a, wildcard: o }) {
15
+ function register(e, t, n, r, i) {
16
16
  if (n.aborted) return noop;
17
- let l = !1;
17
+ let a = !1;
18
18
  function unsub() {
19
- l || (l = !0, e.delete(u), a?.(), n.removeEventListener("abort", unsub), r === void 0 ? o && emitTap({ type: "unsubscribe-any" }) : emitTap({
20
- event: r,
21
- type: "unsubscribe"
22
- }));
19
+ a || (a = !0, e.delete(o), n.removeEventListener("abort", unsub), emitTap(i.unsubscribe));
23
20
  }
24
- let u = t(unsub);
25
- return e.add(u), n.addEventListener("abort", unsub, { once: !0 }), r === void 0 ? o && emitTap({ type: "subscribe-any" }) : emitTap({
26
- event: r,
27
- type: "subscribe"
28
- }), s !== void 0 && e.size > s && `${i}${e.size}${s}${c}`, unsub;
29
- }
30
- function onWithSignal(e, t, r, i) {
31
- let a = n.get(e);
32
- a || (a = /* @__PURE__ */ new Set(), n.set(e, a));
33
- let o = a;
34
- return registerEntry(o, (e) => ({
21
+ let o = t(unsub);
22
+ return e.add(o), n.addEventListener("abort", unsub, { once: !0 }), emitTap(i.subscribe), s !== void 0 && e.size > s && `${r}${e.size}${s}${c}`, unsub;
23
+ }
24
+ function onScoped(e, t, r) {
25
+ let i = n.get(e);
26
+ return i || (i = /* @__PURE__ */ new Set(), n.set(e, i)), register(i, (e) => ({
35
27
  fn: t,
36
28
  unsub: e
37
- }), r, {
38
- event: e,
39
- onLog: `on("${e}")`,
40
- onRemove: () => {
41
- o.size === 0 && n.delete(e), i?.();
29
+ }), r, `on("${e}")`, {
30
+ subscribe: {
31
+ event: e,
32
+ type: "subscribe"
33
+ },
34
+ unsubscribe: {
35
+ event: e,
36
+ type: "unsubscribe"
42
37
  }
43
38
  });
44
39
  }
45
- function onAnyWithSignal(e, t, n) {
46
- return registerEntry(r, (t) => ({
40
+ function onAnyScoped(e, t) {
41
+ return register(r, (t) => ({
47
42
  fn: e,
48
43
  unsub: t
49
- }), t, {
50
- onLog: "onAny",
51
- onRemove: n,
52
- wildcard: !0
44
+ }), t, "onAny", {
45
+ subscribe: { type: "subscribe-any" },
46
+ unsubscribe: { type: "unsubscribe-any" }
53
47
  });
54
48
  }
55
- function onceWithSignal(e, t, n, r) {
56
- let i = { unsub: noop };
57
- return i.unsub = onWithSignal(e, (e) => {
58
- i.unsub(), t(e);
59
- }, n, r), i.unsub;
49
+ function onceScoped(e, t, n) {
50
+ let r = onScoped(e, (e) => {
51
+ r(), t(e);
52
+ }, n);
53
+ return r;
60
54
  }
61
55
  function on(e, t, n) {
62
- return onWithSignal(e, t, createSubscriptionScope(n?.signal));
56
+ return onScoped(e, t, subscriptionSignal(n?.signal));
63
57
  }
64
58
  function once(e, t, n) {
65
- return onceWithSignal(e, t, createSubscriptionScope(n?.signal));
59
+ return onceScoped(e, t, subscriptionSignal(n?.signal));
66
60
  }
67
61
  function onAny(e, t) {
68
- return onAnyWithSignal(e, createSubscriptionScope(t?.signal));
62
+ return onAnyScoped(e, subscriptionSignal(t?.signal));
69
63
  }
70
- function wait(e, t) {
71
- let n = createSubscriptionScope(t?.signal);
72
- return n.aborted ? Promise.reject(n.reason) : new Promise((t, r) => {
64
+ function waitScoped(e, t) {
65
+ return t.aborted ? Promise.reject(t.reason) : new Promise((n, r) => {
73
66
  let onAbort = () => {
74
- r(n.reason);
67
+ r(t.reason);
75
68
  };
76
- onceWithSignal(e, (e) => {
77
- n.removeEventListener("abort", onAbort), t(e);
78
- }, n), n.addEventListener("abort", onAbort, { once: !0 });
69
+ onceScoped(e, (e) => {
70
+ t.removeEventListener("abort", onAbort), n(e);
71
+ }, t), t.addEventListener("abort", onAbort, { once: !0 });
79
72
  });
80
73
  }
74
+ function wait(e, t) {
75
+ return waitScoped(e, subscriptionSignal(t?.signal));
76
+ }
77
+ function waitAny(e, t) {
78
+ if (e.length === 0) throw TypeError("waitAny() requires at least one event name");
79
+ let n = new AbortController(), r = AbortSignal.any([subscriptionSignal(t?.signal), n.signal]), i = e.map((e) => waitScoped(e, r).then((t) => ({
80
+ event: e,
81
+ payload: t
82
+ })));
83
+ for (let e of i) e.catch(noop);
84
+ return Promise.race(i).then((e) => (n.abort(), e));
85
+ }
81
86
  function dispatch(e, t) {
82
87
  let i = 0, a, o = n.get(e);
83
88
  if (o?.size) for (let n of [...o]) {
@@ -126,38 +131,21 @@ function createBus(t) {
126
131
  return r.size;
127
132
  }
128
133
  function eventNames() {
129
- return [...n.keys()];
134
+ let e = [];
135
+ for (let [t, r] of n) r.size > 0 && e.push(t);
136
+ return e;
130
137
  }
131
138
  function tap(e, t) {
132
- if (a.signal.aborted) return noop;
133
- let n = createSubscriptionScope(t?.signal);
139
+ let n = subscriptionSignal(t?.signal);
134
140
  if (n.aborted) return noop;
135
141
  i.add(e);
136
- let onAbort = () => i.delete(e);
142
+ let onAbort = () => {
143
+ i.delete(e);
144
+ };
137
145
  return n.addEventListener("abort", onAbort, { once: !0 }), () => {
138
146
  i.delete(e), n.removeEventListener("abort", onAbort);
139
147
  };
140
148
  }
141
- function waitAny(e, t) {
142
- let n = createSubscriptionScope(t?.signal);
143
- return n.aborted ? Promise.reject(n.reason) : new Promise((t, r) => {
144
- let i = new AbortController(), a = AbortSignal.any([n, i.signal]), o = [], s = !1;
145
- function cleanup() {
146
- n.removeEventListener("abort", onAbort), i.abort();
147
- for (let e of o) e();
148
- }
149
- function onAbort() {
150
- s || (s = !0, cleanup(), r(n.reason));
151
- }
152
- n.addEventListener("abort", onAbort, { once: !0 });
153
- for (let n of e) o.push(onceWithSignal(n, (e) => {
154
- s || (s = !0, cleanup(), t({
155
- event: n,
156
- payload: e
157
- }));
158
- }, a));
159
- });
160
- }
161
149
  function dispose() {
162
150
  a.signal.aborted || (emitTap({ type: "dispose" }), a.abort(new e(o)), n.clear(), r.clear(), i.clear());
163
151
  }
@@ -182,6 +170,6 @@ function createBus(t) {
182
170
  wildcardCount
183
171
  };
184
172
  }
185
- export { createBus, noop };
173
+ export { createBus };
186
174
 
187
175
  //# sourceMappingURL=bus.js.map
package/dist/bus.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bus.js","names":["listeners","wildcards","tappers","disposeController","busName","options","maxListeners","busTag","tapper","event","signal","called","container","entry","onRemove","wildcard","makeEntry","onLog","set","capturedSet","listener","ref","payload","opts","resolve","count","firstError","err","args","total","handler","activeSignal","raceController","raceSignal","unsubs","settled","unsub","reject","eventList","BusDisposedError"],"sources":["../src/bus.ts"],"sourcesContent":["import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\n/** @internal */\nexport const noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\ntype RegisterEntryOpts<T extends EventMap> = {\n event?: EventKey<T>;\n onLog: string;\n onRemove?: () => void;\n wildcard?: boolean;\n};\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n if (tappers.size === 0) return;\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function doWarn(msg: string): void {\n _internalWarn(msg);\n }\n\n function createSubscriptionScope(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function registerEntry<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n { event, onLog, onRemove, wildcard }: RegisterEntryOpts<T>,\n ): () => void {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub() {\n if (called) return;\n\n called = true;\n container.delete(entry);\n onRemove?.();\n signal.removeEventListener('abort', unsub);\n\n if (event !== undefined) emitTap({ event, type: 'unsubscribe' });\n else if (wildcard) emitTap({ type: 'unsubscribe-any' });\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n\n if (event !== undefined) emitTap({ event, type: 'subscribe' });\n else if (wildcard) emitTap({ type: 'subscribe-any' });\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n doWarn(\n `${onLog} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n const capturedSet = set;\n\n return registerEntry(capturedSet, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, {\n event,\n onLog: `on(\"${event}\")`,\n onRemove: () => {\n if (capturedSet.size === 0) listeners.delete(event);\n\n onRemove?.();\n },\n });\n }\n\n function onAnyWithSignal(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n return registerEntry(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n { onLog: 'onAny', onRemove, wildcard: true },\n );\n }\n\n function onceWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onWithSignal(\n event,\n (payload) => {\n ref.unsub();\n listener(payload);\n },\n signal,\n onRemove,\n );\n\n return ref.unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): () => void {\n return onWithSignal(event, listener, createSubscriptionScope(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n opts?: { signal?: AbortSignal },\n ): () => void {\n const signal = createSubscriptionScope(opts?.signal);\n\n return onceWithSignal(event, listener, signal);\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): () => void {\n return onAnyWithSignal(listener, createSubscriptionScope(opts?.signal));\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: { signal?: AbortSignal }): Promise<T[K]> {\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason);\n };\n\n onceWithSignal(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n function eventNames(): EventKey<T>[] {\n return [...listeners.keys()] as EventKey<T>[];\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: { signal?: AbortSignal }): () => void {\n if (disposeController.signal.aborted) return noop;\n\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = () => tappers.delete(handler);\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function waitAny<K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n const activeSignal = createSubscriptionScope(opts?.signal);\n\n if (activeSignal.aborted) return Promise.reject(activeSignal.reason);\n\n return new Promise<WaitAnyResult<T, K>>((resolve, reject) => {\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([activeSignal, raceController.signal]);\n const unsubs: Unsubscribe[] = [];\n let settled = false;\n\n function cleanup(): void {\n activeSignal.removeEventListener('abort', onAbort);\n raceController.abort();\n for (const unsub of unsubs) unsub();\n }\n\n function onAbort(): void {\n if (settled) return;\n\n settled = true;\n cleanup();\n reject(activeSignal.reason);\n }\n\n activeSignal.addEventListener('abort', onAbort, { once: true });\n\n for (const event of eventList) {\n unsubs.push(\n onceWithSignal(\n event as EventKey<T>,\n (payload) => {\n if (settled) return;\n\n settled = true;\n cleanup();\n resolve({ event, payload } as WaitAnyResult<T, K>);\n },\n raceSignal,\n ),\n );\n }\n });\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bus.js","names":["listeners","wildcards","tappers","disposeController","busName","options","maxListeners","busTag","tapper","event","signal","called","container","entry","tapEvents","makeEntry","label","set","listener","unsub","payload","opts","resolve","eventList","raceController","raceSignal","waiters","waiter","result","count","firstError","err","args","total","active","handler","BusDisposedError"],"sources":["../src/bus.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\nconst noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function subscriptionSignal(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function register<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n label: string,\n tapEvents: { readonly subscribe: HeraldEvent<T>; readonly unsubscribe: HeraldEvent<T> },\n ): Unsubscribe {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub(): void {\n if (called) return;\n\n called = true;\n container.delete(entry);\n signal.removeEventListener('abort', unsub);\n emitTap(tapEvents.unsubscribe);\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n emitTap(tapEvents.subscribe);\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n warn(\n `${label} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n return register(set, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, `on(\"${event}\")`, {\n subscribe: { event, type: 'subscribe' },\n unsubscribe: { event, type: 'unsubscribe' },\n });\n }\n\n function onAnyScoped(listener: (event: EventKey<T>, payload: unknown) => void, signal: AbortSignal): Unsubscribe {\n return register(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n 'onAny',\n {\n subscribe: { type: 'subscribe-any' },\n unsubscribe: { type: 'unsubscribe-any' },\n },\n );\n }\n\n // The wrapper calls `unsub` only when the listener runs, which is always after the\n // assignment completed; no indirection object is needed.\n function onceScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n const unsub = onScoped(\n event,\n (payload) => {\n unsub();\n listener(payload);\n },\n signal,\n );\n\n return unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onceScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe {\n return onAnyScoped(listener, subscriptionSignal(opts?.signal));\n }\n\n // `signal` must already combine bus disposal with any caller-provided signal.\n function waitScoped<K extends EventKey<T>>(event: K, signal: AbortSignal): Promise<T[K]> {\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = (): void => {\n reject(signal.reason);\n };\n\n onceScoped(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]> {\n return waitScoped(event, subscriptionSignal(opts?.signal));\n }\n\n function waitAny<const K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: SubscribeOptions,\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length === 0) {\n throw new TypeError('waitAny() requires at least one event name');\n }\n\n // One-shot `wait()` per event sharing one signal: an internal controller aborts the\n // loser subscriptions once one resolves, and `Promise.race` provides the settled-once\n // winner/loser semantics, rejection with the composite signal's reason included.\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([subscriptionSignal(opts?.signal), raceController.signal]);\n const waiters = eventList.map((event) => waitScoped(event, raceSignal).then((payload) => ({ event, payload })));\n\n // Losers reject through the cleanup abort: keep every rejection observed.\n for (const waiter of waiters) waiter.catch(noop);\n\n return Promise.race(waiters).then((result) => {\n raceController.abort();\n return result as WaitAnyResult<T, K>;\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n // Empty sets stay in `listeners` after their last listener leaves (removing them eagerly\n // on unsubscribe is what previously corrupted re-registered listeners); filter here instead.\n function eventNames(): EventKey<T>[] {\n const active: EventKey<T>[] = [];\n\n for (const [event, set] of listeners) {\n if (set.size > 0) active.push(event as EventKey<T>);\n }\n\n return active;\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: SubscribeOptions): Unsubscribe {\n const signal = subscriptionSignal(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = (): void => {\n tappers.delete(handler);\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}};exports.BusDisposedError=BusDisposedError,exports.HeraldError=HeraldError;
1
+ var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}};exports.BusDisposedError=BusDisposedError,exports.HeraldError=HeraldError;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":["message","opts","busName"],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n"],"mappings":"AACA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAMA,EAASC,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,iBAAb,cAAsC,WAAY,CAChD,YAAY,EAAkB,CAC5B,MAAMC,EAAU,QAAQA,EAAQ,eAAiB,iBAAiB,CACpE,CACF,E"}
1
+ {"version":3,"file":"errors.cjs","names":["message","opts","busName"],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n"],"mappings":"AACA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAMA,EAASC,CAAI,EACnB,KAAK,KAAO,WAAW,IACzB,CACF,EAGa,iBAAb,cAAsC,WAAY,CAChD,YAAY,EAAkB,CAC5B,MAAMC,EAAU,QAAQA,EAAQ,eAAiB,iBAAiB,CACpE,CACF,E"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAC3G,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,qEAAqE;AACrE,qBAAa,gBAAiB,SAAQ,WAAW;gBACnC,OAAO,CAAC,EAAE,MAAM;CAG7B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAC3G,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAIjD;AAED,qEAAqE;AACrE,qBAAa,gBAAiB,SAAQ,WAAW;gBACnC,OAAO,CAAC,EAAE,MAAM;CAG7B"}
package/dist/errors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/errors.ts
2
2
  var HeraldError = class extends Error {
3
3
  constructor(e, t) {
4
- super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
4
+ super(e, t), this.name = new.target.name;
5
5
  }
6
6
  }, BusDisposedError = class extends HeraldError {
7
7
  constructor(e) {
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":["message","opts","busName"],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n"],"mappings":";AACA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAMA,GAASC,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,mBAAb,cAAsC,YAAY;CAChD,YAAY,GAAkB;EAC5B,MAAMC,IAAU,QAAQA,EAAQ,iBAAiB,iBAAiB;CACpE;AACF"}
1
+ {"version":3,"file":"errors.js","names":["message","opts","busName"],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n"],"mappings":";AACA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,GAAiB,GAAqB;EAEhD,AADA,MAAMA,GAASC,CAAI,GACnB,KAAK,OAAO,WAAW;CACzB;AACF,GAGa,mBAAb,cAAsC,YAAY;CAChD,YAAY,GAAkB;EAC5B,MAAMC,IAAU,QAAQA,EAAQ,iBAAiB,iBAAiB;CACpE;AACF"}
package/dist/herald.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},noop=()=>{};function createBus(e){let t=new Map,n=new Set,r=new Set,i=new AbortController,a=e?.name,o=e?.maxListeners,s=a?` (${a})`:``;function emitTap(e){if(r.size!==0)for(let t of r)try{t(e)}catch{}}function createSubscriptionScope(e){return e?AbortSignal.any([i.signal,e]):i.signal}function registerEntry(e,t,n,{event:r,onLog:i,onRemove:a,wildcard:c}){if(n.aborted)return noop;let l=!1;function unsub(){l||(l=!0,e.delete(u),a?.(),n.removeEventListener(`abort`,unsub),r===void 0?c&&emitTap({type:`unsubscribe-any`}):emitTap({event:r,type:`unsubscribe`}))}let u=t(unsub);return e.add(u),n.addEventListener(`abort`,unsub,{once:!0}),r===void 0?c&&emitTap({type:`subscribe-any`}):emitTap({event:r,type:`subscribe`}),o!==void 0&&e.size>o&&`${i}${e.size}${o}${s}`,unsub}function onWithSignal(e,n,r,i){let a=t.get(e);a||(a=new Set,t.set(e,a));let o=a;return registerEntry(o,e=>({fn:n,unsub:e}),r,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&t.delete(e),i?.()}})}function onAnyWithSignal(e,t,r){return registerEntry(n,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:r,wildcard:!0})}function onceWithSignal(e,t,n,r){let i={unsub:noop};return i.unsub=onWithSignal(e,e=>{i.unsub(),t(e)},n,r),i.unsub}function on(e,t,n){return onWithSignal(e,t,createSubscriptionScope(n?.signal))}function once(e,t,n){return onceWithSignal(e,t,createSubscriptionScope(n?.signal))}function onAny(e,t){return onAnyWithSignal(e,createSubscriptionScope(t?.signal))}function wait(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let onAbort=()=>{r(n.reason)};onceWithSignal(e,e=>{n.removeEventListener(`abort`,onAbort),t(e)},n),n.addEventListener(`abort`,onAbort,{once:!0})})}function dispatch(e,r){let i=0,a,o=t.get(e);if(o?.size)for(let t of[...o]){try{t.fn(r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(n.size)for(let t of[...n]){try{t.fn(e,r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:r,type:`emit`}),a)throw a.value}function emit(e,...t){if(i.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return t.get(e)?.size??0;let n=0;for(let e of t.values())n+=e.size;return n}function wildcardCount(){return n.size}function eventNames(){return[...t.keys()]}function tap(e,t){if(i.signal.aborted)return noop;let n=createSubscriptionScope(t?.signal);if(n.aborted)return noop;r.add(e);let onAbort=()=>r.delete(e);return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{r.delete(e),n.removeEventListener(`abort`,onAbort)}}function waitAny(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=new AbortController,a=AbortSignal.any([n,i.signal]),o=[],s=!1;function cleanup(){n.removeEventListener(`abort`,onAbort),i.abort();for(let e of o)e()}function onAbort(){s||(s=!0,cleanup(),r(n.reason))}n.addEventListener(`abort`,onAbort,{once:!0});for(let n of e)o.push(onceWithSignal(n,e=>{s||(s=!0,cleanup(),t({event:n,payload:e}))},a))})}function dispose(){i.signal.aborted||(emitTap({type:`dispose`}),i.abort(new BusDisposedError(a)),t.clear(),n.clear(),r.clear())}return{get disposalSignal(){return i.signal},dispose,get disposed(){return i.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}exports.BusDisposedError=BusDisposedError,exports.HeraldError=HeraldError,exports.createBus=createBus;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},noop=()=>{};function createBus(e){let t=new Map,n=new Set,r=new Set,i=new AbortController,a=e?.name,o=e?.maxListeners,s=a?` (${a})`:``;function emitTap(e){for(let t of r)try{t(e)}catch{}}function subscriptionSignal(e){return e?AbortSignal.any([i.signal,e]):i.signal}function register(e,t,n,r,i){if(n.aborted)return noop;let a=!1;function unsub(){a||(a=!0,e.delete(c),n.removeEventListener(`abort`,unsub),emitTap(i.unsubscribe))}let c=t(unsub);return e.add(c),n.addEventListener(`abort`,unsub,{once:!0}),emitTap(i.subscribe),o!==void 0&&e.size>o&&`${r}${e.size}${o}${s}`,unsub}function onScoped(e,n,r){let i=t.get(e);return i||(i=new Set,t.set(e,i)),register(i,e=>({fn:n,unsub:e}),r,`on("${e}")`,{subscribe:{event:e,type:`subscribe`},unsubscribe:{event:e,type:`unsubscribe`}})}function onAnyScoped(e,t){return register(n,t=>({fn:e,unsub:t}),t,`onAny`,{subscribe:{type:`subscribe-any`},unsubscribe:{type:`unsubscribe-any`}})}function onceScoped(e,t,n){let r=onScoped(e,e=>{r(),t(e)},n);return r}function on(e,t,n){return onScoped(e,t,subscriptionSignal(n?.signal))}function once(e,t,n){return onceScoped(e,t,subscriptionSignal(n?.signal))}function onAny(e,t){return onAnyScoped(e,subscriptionSignal(t?.signal))}function waitScoped(e,t){return t.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let onAbort=()=>{r(t.reason)};onceScoped(e,e=>{t.removeEventListener(`abort`,onAbort),n(e)},t),t.addEventListener(`abort`,onAbort,{once:!0})})}function wait(e,t){return waitScoped(e,subscriptionSignal(t?.signal))}function waitAny(e,t){if(e.length===0)throw TypeError(`waitAny() requires at least one event name`);let n=new AbortController,r=AbortSignal.any([subscriptionSignal(t?.signal),n.signal]),i=e.map(e=>waitScoped(e,r).then(t=>({event:e,payload:t})));for(let e of i)e.catch(noop);return Promise.race(i).then(e=>(n.abort(),e))}function dispatch(e,r){let i=0,a,o=t.get(e);if(o?.size)for(let t of[...o]){try{t.fn(r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(n.size)for(let t of[...n]){try{t.fn(e,r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:r,type:`emit`}),a)throw a.value}function emit(e,...t){if(i.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return t.get(e)?.size??0;let n=0;for(let e of t.values())n+=e.size;return n}function wildcardCount(){return n.size}function eventNames(){let e=[];for(let[n,r]of t)r.size>0&&e.push(n);return e}function tap(e,t){let n=subscriptionSignal(t?.signal);if(n.aborted)return noop;r.add(e);let onAbort=()=>{r.delete(e)};return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{r.delete(e),n.removeEventListener(`abort`,onAbort)}}function dispose(){i.signal.aborted||(emitTap({type:`dispose`}),i.abort(new BusDisposedError(a)),t.clear(),n.clear(),r.clear())}return{get disposalSignal(){return i.signal},dispose,get disposed(){return i.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}exports.BusDisposedError=BusDisposedError,exports.HeraldError=HeraldError,exports.createBus=createBus;
2
2
  //# sourceMappingURL=herald.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"herald.cjs","names":["message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","onRemove","wildcard","makeEntry","onLog","set","capturedSet","listener","ref","payload","reject","resolve","count","firstError","err","args","total","handler","activeSignal","raceController","raceSignal","unsubs","settled","unsub","eventList"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\n/** @internal */\nexport const noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\ntype RegisterEntryOpts<T extends EventMap> = {\n event?: EventKey<T>;\n onLog: string;\n onRemove?: () => void;\n wildcard?: boolean;\n};\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n if (tappers.size === 0) return;\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function doWarn(msg: string): void {\n _internalWarn(msg);\n }\n\n function createSubscriptionScope(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function registerEntry<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n { event, onLog, onRemove, wildcard }: RegisterEntryOpts<T>,\n ): () => void {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub() {\n if (called) return;\n\n called = true;\n container.delete(entry);\n onRemove?.();\n signal.removeEventListener('abort', unsub);\n\n if (event !== undefined) emitTap({ event, type: 'unsubscribe' });\n else if (wildcard) emitTap({ type: 'unsubscribe-any' });\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n\n if (event !== undefined) emitTap({ event, type: 'subscribe' });\n else if (wildcard) emitTap({ type: 'subscribe-any' });\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n doWarn(\n `${onLog} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n const capturedSet = set;\n\n return registerEntry(capturedSet, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, {\n event,\n onLog: `on(\"${event}\")`,\n onRemove: () => {\n if (capturedSet.size === 0) listeners.delete(event);\n\n onRemove?.();\n },\n });\n }\n\n function onAnyWithSignal(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n return registerEntry(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n { onLog: 'onAny', onRemove, wildcard: true },\n );\n }\n\n function onceWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onWithSignal(\n event,\n (payload) => {\n ref.unsub();\n listener(payload);\n },\n signal,\n onRemove,\n );\n\n return ref.unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): () => void {\n return onWithSignal(event, listener, createSubscriptionScope(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n opts?: { signal?: AbortSignal },\n ): () => void {\n const signal = createSubscriptionScope(opts?.signal);\n\n return onceWithSignal(event, listener, signal);\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): () => void {\n return onAnyWithSignal(listener, createSubscriptionScope(opts?.signal));\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: { signal?: AbortSignal }): Promise<T[K]> {\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason);\n };\n\n onceWithSignal(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n function eventNames(): EventKey<T>[] {\n return [...listeners.keys()] as EventKey<T>[];\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: { signal?: AbortSignal }): () => void {\n if (disposeController.signal.aborted) return noop;\n\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = () => tappers.delete(handler);\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function waitAny<K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n const activeSignal = createSubscriptionScope(opts?.signal);\n\n if (activeSignal.aborted) return Promise.reject(activeSignal.reason);\n\n return new Promise<WaitAnyResult<T, K>>((resolve, reject) => {\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([activeSignal, raceController.signal]);\n const unsubs: Unsubscribe[] = [];\n let settled = false;\n\n function cleanup(): void {\n activeSignal.removeEventListener('abort', onAbort);\n raceController.abort();\n for (const unsub of unsubs) unsub();\n }\n\n function onAbort(): void {\n if (settled) return;\n\n settled = true;\n cleanup();\n reject(activeSignal.reason);\n }\n\n activeSignal.addEventListener('abort', onAbort, { once: true });\n\n for (const event of eventList) {\n unsubs.push(\n onceWithSignal(\n event as EventKey<T>,\n (payload) => {\n if (settled) return;\n\n settled = true;\n cleanup();\n resolve({ event, payload } as WaitAnyResult<T, K>);\n },\n raceSignal,\n ),\n );\n }\n });\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"herald.cjs","names":["message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","tapEvents","makeEntry","label","set","listener","unsub","payload","reject","resolve","eventList","raceController","raceSignal","waiters","waiter","result","count","firstError","err","args","total","active","handler"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\nconst noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function subscriptionSignal(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function register<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n label: string,\n tapEvents: { readonly subscribe: HeraldEvent<T>; readonly unsubscribe: HeraldEvent<T> },\n ): Unsubscribe {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub(): void {\n if (called) return;\n\n called = true;\n container.delete(entry);\n signal.removeEventListener('abort', unsub);\n emitTap(tapEvents.unsubscribe);\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n emitTap(tapEvents.subscribe);\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n warn(\n `${label} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n return register(set, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, `on(\"${event}\")`, {\n subscribe: { event, type: 'subscribe' },\n unsubscribe: { event, type: 'unsubscribe' },\n });\n }\n\n function onAnyScoped(listener: (event: EventKey<T>, payload: unknown) => void, signal: AbortSignal): Unsubscribe {\n return register(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n 'onAny',\n {\n subscribe: { type: 'subscribe-any' },\n unsubscribe: { type: 'unsubscribe-any' },\n },\n );\n }\n\n // The wrapper calls `unsub` only when the listener runs, which is always after the\n // assignment completed; no indirection object is needed.\n function onceScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n const unsub = onScoped(\n event,\n (payload) => {\n unsub();\n listener(payload);\n },\n signal,\n );\n\n return unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onceScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe {\n return onAnyScoped(listener, subscriptionSignal(opts?.signal));\n }\n\n // `signal` must already combine bus disposal with any caller-provided signal.\n function waitScoped<K extends EventKey<T>>(event: K, signal: AbortSignal): Promise<T[K]> {\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = (): void => {\n reject(signal.reason);\n };\n\n onceScoped(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]> {\n return waitScoped(event, subscriptionSignal(opts?.signal));\n }\n\n function waitAny<const K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: SubscribeOptions,\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length === 0) {\n throw new TypeError('waitAny() requires at least one event name');\n }\n\n // One-shot `wait()` per event sharing one signal: an internal controller aborts the\n // loser subscriptions once one resolves, and `Promise.race` provides the settled-once\n // winner/loser semantics, rejection with the composite signal's reason included.\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([subscriptionSignal(opts?.signal), raceController.signal]);\n const waiters = eventList.map((event) => waitScoped(event, raceSignal).then((payload) => ({ event, payload })));\n\n // Losers reject through the cleanup abort: keep every rejection observed.\n for (const waiter of waiters) waiter.catch(noop);\n\n return Promise.race(waiters).then((result) => {\n raceController.abort();\n return result as WaitAnyResult<T, K>;\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n // Empty sets stay in `listeners` after their last listener leaves (removing them eagerly\n // on unsubscribe is what previously corrupted re-registered listeners); filter here instead.\n function eventNames(): EventKey<T>[] {\n const active: EventKey<T>[] = [];\n\n for (const [event, set] of listeners) {\n if (set.size > 0) active.push(event as EventKey<T>);\n }\n\n return active;\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: SubscribeOptions): Unsubscribe {\n const signal = subscriptionSignal(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = (): void => {\n tappers.delete(handler);\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"A,mECCA,IAAa,YAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAMA,EAASC,CAAI,EACnB,KAAK,KAAO,WAAW,IACzB,CACF,EAGa,iBAAb,cAAsC,WAAY,CAChD,YAAY,EAAkB,CAC5B,MAAMC,EAAU,QAAQA,EAAQ,eAAiB,iBAAiB,CACpE,CACF,ECEM,SAAa,CAAC,EAKpB,SAAgB,UAAwD,EAA8B,CACpG,IAAMC,EAAY,IAAI,IAChBC,EAAY,IAAI,IAChBC,EAAU,IAAI,IACdC,EAAoB,IAAI,gBACxBJ,EAAUK,GAAS,KACnBC,EAAeD,GAAS,aACxBE,EAASP,EAAU,KAAKA,EAAQ,GAAK,GAE3C,SAAS,QAAQ,EAA6B,CAC5C,IAAK,IAAMQ,KAAUL,EACnB,GAAI,CACFK,EAAOC,CAAK,CACd,MAAQ,CAER,CAEJ,CAEA,SAAS,mBAAmB,EAAmC,CAC7D,OAAOC,EAAS,YAAY,IAAI,CAACN,EAAkB,OAAQM,CAAM,CAAC,EAAIN,EAAkB,MAC1F,CAEA,SAAS,SACP,EACA,EACA,EACA,EACA,EACa,CACb,GAAIM,EAAO,QAAS,OAAO,KAE3B,IAAIC,EAAS,GAEb,SAAS,OAAc,CACjBA,IAEJ,EAAS,GACTC,EAAU,OAAOC,CAAK,EACtBH,EAAO,oBAAoB,QAAS,KAAK,EACzC,QAAQI,EAAU,WAAW,EAC/B,CAEA,IAAMD,EAAQE,EAAU,KAAK,EAY7B,OAVAH,EAAU,IAAIC,CAAK,EACnBH,EAAO,iBAAiB,QAAS,MAAO,CAAE,KAAM,EAAK,CAAC,EACtD,QAAQI,EAAU,SAAS,EAEvBR,IAAiB,IAAA,IAAaM,EAAU,KAAON,GAE/C,GAAGU,EAAH,EAAgBJ,EAAU,KAA1B,EAAqEN,EAArE,EAA4GC,EAA5G,EAIG,KACT,CAEA,SAAS,SAAgC,EAAU,EAA0B,EAAkC,CAC7G,IAAIU,EAAMhB,EAAU,IAAIQ,CAAK,EAO7B,OALKQ,IACH,EAAM,IAAI,IACVhB,EAAU,IAAIQ,EAAOQ,CAAG,GAGnB,SAASA,EAAM,IAAW,CAAE,GAAIC,EAA+B,OAAM,GAAIR,EAAQ,OAAOD,EAAM,IAAK,CACxG,UAAW,CAAE,QAAO,KAAM,WAAY,EACtC,YAAa,CAAE,QAAO,KAAM,aAAc,CAC5C,CAAC,CACH,CAEA,SAAS,YAAY,EAA0D,EAAkC,CAC/G,OAAO,SACLP,EACC,IAAW,CAAE,GAAIgB,EAAuD,OAAM,GAC/ER,EACA,QACA,CACE,UAAW,CAAE,KAAM,eAAgB,EACnC,YAAa,CAAE,KAAM,iBAAkB,CACzC,CACF,CACF,CAIA,SAAS,WAAkC,EAAU,EAA0B,EAAkC,CAC/G,IAAMS,EAAQ,SACZV,EACC,GAAY,CACXU,EAAM,EACND,EAASE,CAAO,CAClB,EACAV,CACF,EAEA,OAAOS,CACT,CAEA,SAAS,GAA0B,EAAU,EAA0B,EAAsC,CAC3G,OAAO,SAASV,EAAOS,EAAU,mBAAmBnB,GAAM,MAAM,CAAC,CACnE,CAEA,SAAS,KAA4B,EAAU,EAA0B,EAAsC,CAC7G,OAAO,WAAWU,EAAOS,EAAU,mBAAmBnB,GAAM,MAAM,CAAC,CACrE,CAEA,SAAS,MAAM,EAA0D,EAAsC,CAC7G,OAAO,YAAYmB,EAAU,mBAAmBnB,GAAM,MAAM,CAAC,CAC/D,CAGA,SAAS,WAAkC,EAAU,EAAoC,CAGvF,OAFIW,EAAO,QAAgB,QAAQ,OAAOA,EAAO,MAAM,EAEhD,IAAI,SAAe,EAAS,IAAW,CAC5C,IAAM,YAAsB,CAC1BW,EAAOX,EAAO,MAAM,CACtB,EAEA,WACED,EACC,GAAY,CACXC,EAAO,oBAAoB,QAAS,OAAO,EAC3CY,EAAQF,CAAO,CACjB,EACAV,CACF,EAEAA,EAAO,iBAAiB,QAAS,QAAS,CAAE,KAAM,EAAK,CAAC,CAC1D,CAAC,CACH,CAEA,SAAS,KAA4B,EAAU,EAAwC,CACrF,OAAO,WAAWD,EAAO,mBAAmBV,GAAM,MAAM,CAAC,CAC3D,CAEA,SAAS,QACP,EACA,EAC8B,CAC9B,GAAIwB,EAAU,SAAW,EACvB,MAAU,UAAU,4CAA4C,EAMlE,IAAMC,EAAiB,IAAI,gBACrBC,EAAa,YAAY,IAAI,CAAC,mBAAmB1B,GAAM,MAAM,EAAGyB,EAAe,MAAM,CAAC,EACtFE,EAAUH,EAAU,IAAK,GAAU,WAAWd,EAAOgB,CAAU,CAAC,CAAC,KAAM,IAAa,CAAE,QAAO,SAAQ,EAAE,CAAC,EAG9G,IAAK,IAAME,KAAUD,EAASC,EAAO,MAAM,IAAI,EAE/C,OAAO,QAAQ,KAAKD,CAAO,CAAC,CAAC,KAAM,IACjCF,EAAe,MAAM,EACdI,EACR,CACH,CAEA,SAAS,SAAS,EAAoB,EAAwB,CAC5D,IAAIC,EAAQ,EACRC,EACEb,EAAMhB,EAAU,IAAIQ,CAAK,EAE/B,GAAIQ,GAAK,KACP,IAAK,IAAMJ,IAAS,CAAC,GAAGI,CAAG,EAAG,CAC5B,GAAI,CACFJ,EAAM,GAAGO,CAAO,CAClB,OAASW,EAAK,CACZ,IAAe,CAAE,MAAOA,CAAI,EAC5B,QAAQ,CAAE,MAAOA,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAGF,GAAI7B,EAAU,KACZ,IAAK,IAAMW,IAAS,CAAC,GAAGX,CAAS,EAAG,CAClC,GAAI,CACFW,EAAM,GAAGJ,EAAOW,CAAO,CACzB,OAASW,EAAK,CACZ,IAAe,CAAE,MAAOA,CAAI,EAC5B,QAAQ,CAAE,MAAOA,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAKF,GAFA,QAAQ,CAAE,QAAO,UAAWF,EAAO,UAAS,KAAM,MAAO,CAAC,EAEtDC,EAAY,MAAMA,EAAW,KACnC,CAEA,SAAS,KAA4B,EAAU,GAAGE,EAAsD,CACtG,GAAI5B,EAAkB,OAAO,QAAS,OAEtC,IAAMgB,EAAWY,EAAmB,GAEpC,SAASvB,EAAOW,CAAO,CACzB,CAEA,SAAS,cAAc,EAA6B,CAClD,GAAIX,IAAU,IAAA,GAAW,OAAOR,EAAU,IAAIQ,CAAK,CAAC,EAAE,MAAQ,EAE9D,IAAIwB,EAAQ,EAEZ,IAAK,IAAMhB,KAAOhB,EAAU,OAAO,EAAG,GAASgB,EAAI,KAEnD,OAAOgB,CACT,CAEA,SAAS,eAAwB,CAC/B,OAAO/B,EAAU,IACnB,CAIA,SAAS,YAA4B,CACnC,IAAMgC,EAAwB,CAAC,EAE/B,IAAK,GAAM,CAACzB,EAAOQ,KAAQhB,EACrBgB,EAAI,KAAO,GAAGiB,EAAO,KAAKzB,CAAoB,EAGpD,OAAOyB,CACT,CAEA,SAAS,IAAI,EAA0C,EAAsC,CAC3F,IAAMxB,EAAS,mBAAmBX,GAAM,MAAM,EAE9C,GAAIW,EAAO,QAAS,OAAO,KAE3BP,EAAQ,IAAIgC,CAAO,EAEnB,IAAM,YAAsB,CAC1BhC,EAAQ,OAAOgC,CAAO,CACxB,EAIA,OAFAzB,EAAO,iBAAiB,QAAS,QAAS,CAAE,KAAM,EAAK,CAAC,MAE3C,CACXP,EAAQ,OAAOgC,CAAO,EACtBzB,EAAO,oBAAoB,QAAS,OAAO,CAC7C,CACF,CAEA,SAAS,SAAgB,CACnBN,EAAkB,OAAO,UAE7B,QAAQ,CAAE,KAAM,SAAU,CAAC,EAC3BA,EAAkB,MAAM,IAAI,iBAAiBJ,CAAO,CAAC,EACrDC,EAAU,MAAM,EAChBC,EAAU,MAAM,EAChBC,EAAQ,MAAM,EAChB,CAEA,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAOC,EAAkB,MAC3B,EACA,QACA,IAAI,UAAW,CACb,OAAOA,EAAkB,OAAO,OAClC,EACA,KACA,WACA,cACA,GACA,MACA,MACC,OAAO,SAAU,QAClB,IACA,KACA,QACA,aACF,CACF,C"}
@@ -1,2 +1,2 @@
1
- var Herald=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},noop=()=>{};function createBus(e){let t=new Map,n=new Set,r=new Set,i=new AbortController,a=e?.name,o=e?.maxListeners,s=a?` (${a})`:``;function emitTap(e){if(r.size!==0)for(let t of r)try{t(e)}catch{}}function createSubscriptionScope(e){return e?AbortSignal.any([i.signal,e]):i.signal}function registerEntry(e,t,n,{event:r,onLog:i,onRemove:a,wildcard:c}){if(n.aborted)return noop;let l=!1;function unsub(){l||(l=!0,e.delete(u),a?.(),n.removeEventListener(`abort`,unsub),r===void 0?c&&emitTap({type:`unsubscribe-any`}):emitTap({event:r,type:`unsubscribe`}))}let u=t(unsub);return e.add(u),n.addEventListener(`abort`,unsub,{once:!0}),r===void 0?c&&emitTap({type:`subscribe-any`}):emitTap({event:r,type:`subscribe`}),o!==void 0&&e.size>o&&`${i}${e.size}${o}${s}`,unsub}function onWithSignal(e,n,r,i){let a=t.get(e);a||(a=new Set,t.set(e,a));let o=a;return registerEntry(o,e=>({fn:n,unsub:e}),r,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&t.delete(e),i?.()}})}function onAnyWithSignal(e,t,r){return registerEntry(n,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:r,wildcard:!0})}function onceWithSignal(e,t,n,r){let i={unsub:noop};return i.unsub=onWithSignal(e,e=>{i.unsub(),t(e)},n,r),i.unsub}function on(e,t,n){return onWithSignal(e,t,createSubscriptionScope(n?.signal))}function once(e,t,n){return onceWithSignal(e,t,createSubscriptionScope(n?.signal))}function onAny(e,t){return onAnyWithSignal(e,createSubscriptionScope(t?.signal))}function wait(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let onAbort=()=>{r(n.reason)};onceWithSignal(e,e=>{n.removeEventListener(`abort`,onAbort),t(e)},n),n.addEventListener(`abort`,onAbort,{once:!0})})}function dispatch(e,r){let i=0,a,o=t.get(e);if(o?.size)for(let t of[...o]){try{t.fn(r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(n.size)for(let t of[...n]){try{t.fn(e,r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:r,type:`emit`}),a)throw a.value}function emit(e,...t){if(i.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return t.get(e)?.size??0;let n=0;for(let e of t.values())n+=e.size;return n}function wildcardCount(){return n.size}function eventNames(){return[...t.keys()]}function tap(e,t){if(i.signal.aborted)return noop;let n=createSubscriptionScope(t?.signal);if(n.aborted)return noop;r.add(e);let onAbort=()=>r.delete(e);return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{r.delete(e),n.removeEventListener(`abort`,onAbort)}}function waitAny(e,t){let n=createSubscriptionScope(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=new AbortController,a=AbortSignal.any([n,i.signal]),o=[],s=!1;function cleanup(){n.removeEventListener(`abort`,onAbort),i.abort();for(let e of o)e()}function onAbort(){s||(s=!0,cleanup(),r(n.reason))}n.addEventListener(`abort`,onAbort,{once:!0});for(let n of e)o.push(onceWithSignal(n,e=>{s||(s=!0,cleanup(),t({event:n,payload:e}))},a))})}function dispose(){i.signal.aborted||(emitTap({type:`dispose`}),i.abort(new BusDisposedError(a)),t.clear(),n.clear(),r.clear())}return{get disposalSignal(){return i.signal},dispose,get disposed(){return i.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}return e.BusDisposedError=BusDisposedError,e.HeraldError=HeraldError,e.createBus=createBus,e})({});
1
+ var Herald=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var HeraldError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name}},BusDisposedError=class extends HeraldError{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},noop=()=>{};function createBus(e){let t=new Map,n=new Set,r=new Set,i=new AbortController,a=e?.name,o=e?.maxListeners,s=a?` (${a})`:``;function emitTap(e){for(let t of r)try{t(e)}catch{}}function subscriptionSignal(e){return e?AbortSignal.any([i.signal,e]):i.signal}function register(e,t,n,r,i){if(n.aborted)return noop;let a=!1;function unsub(){a||(a=!0,e.delete(c),n.removeEventListener(`abort`,unsub),emitTap(i.unsubscribe))}let c=t(unsub);return e.add(c),n.addEventListener(`abort`,unsub,{once:!0}),emitTap(i.subscribe),o!==void 0&&e.size>o&&`${r}${e.size}${o}${s}`,unsub}function onScoped(e,n,r){let i=t.get(e);return i||(i=new Set,t.set(e,i)),register(i,e=>({fn:n,unsub:e}),r,`on("${e}")`,{subscribe:{event:e,type:`subscribe`},unsubscribe:{event:e,type:`unsubscribe`}})}function onAnyScoped(e,t){return register(n,t=>({fn:e,unsub:t}),t,`onAny`,{subscribe:{type:`subscribe-any`},unsubscribe:{type:`unsubscribe-any`}})}function onceScoped(e,t,n){let r=onScoped(e,e=>{r(),t(e)},n);return r}function on(e,t,n){return onScoped(e,t,subscriptionSignal(n?.signal))}function once(e,t,n){return onceScoped(e,t,subscriptionSignal(n?.signal))}function onAny(e,t){return onAnyScoped(e,subscriptionSignal(t?.signal))}function waitScoped(e,t){return t.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let onAbort=()=>{r(t.reason)};onceScoped(e,e=>{t.removeEventListener(`abort`,onAbort),n(e)},t),t.addEventListener(`abort`,onAbort,{once:!0})})}function wait(e,t){return waitScoped(e,subscriptionSignal(t?.signal))}function waitAny(e,t){if(e.length===0)throw TypeError(`waitAny() requires at least one event name`);let n=new AbortController,r=AbortSignal.any([subscriptionSignal(t?.signal),n.signal]),i=e.map(e=>waitScoped(e,r).then(t=>({event:e,payload:t})));for(let e of i)e.catch(noop);return Promise.race(i).then(e=>(n.abort(),e))}function dispatch(e,r){let i=0,a,o=t.get(e);if(o?.size)for(let t of[...o]){try{t.fn(r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(n.size)for(let t of[...n]){try{t.fn(e,r)}catch(t){a??={value:t},emitTap({error:t,event:e,type:`error`})}i++}if(emitTap({event:e,listeners:i,payload:r,type:`emit`}),a)throw a.value}function emit(e,...t){if(i.signal.aborted)return;let n=t[0];dispatch(e,n)}function listenerCount(e){if(e!==void 0)return t.get(e)?.size??0;let n=0;for(let e of t.values())n+=e.size;return n}function wildcardCount(){return n.size}function eventNames(){let e=[];for(let[n,r]of t)r.size>0&&e.push(n);return e}function tap(e,t){let n=subscriptionSignal(t?.signal);if(n.aborted)return noop;r.add(e);let onAbort=()=>{r.delete(e)};return n.addEventListener(`abort`,onAbort,{once:!0}),()=>{r.delete(e),n.removeEventListener(`abort`,onAbort)}}function dispose(){i.signal.aborted||(emitTap({type:`dispose`}),i.abort(new BusDisposedError(a)),t.clear(),n.clear(),r.clear())}return{get disposalSignal(){return i.signal},dispose,get disposed(){return i.signal.aborted},emit,eventNames,listenerCount,on,onAny,once,[Symbol.dispose]:dispose,tap,wait,waitAny,wildcardCount}}return e.BusDisposedError=BusDisposedError,e.HeraldError=HeraldError,e.createBus=createBus,e})({});
2
2
  //# sourceMappingURL=herald.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"herald.iife.js","names":["exports","message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","onRemove","wildcard","makeEntry","onLog","set","capturedSet","listener","ref","payload","reject","resolve","count","firstError","err","args","total","handler","activeSignal","raceController","raceSignal","unsubs","settled","unsub","eventList"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\n/** @internal */\nexport const noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\ntype RegisterEntryOpts<T extends EventMap> = {\n event?: EventKey<T>;\n onLog: string;\n onRemove?: () => void;\n wildcard?: boolean;\n};\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n if (tappers.size === 0) return;\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function doWarn(msg: string): void {\n _internalWarn(msg);\n }\n\n function createSubscriptionScope(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function registerEntry<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n { event, onLog, onRemove, wildcard }: RegisterEntryOpts<T>,\n ): () => void {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub() {\n if (called) return;\n\n called = true;\n container.delete(entry);\n onRemove?.();\n signal.removeEventListener('abort', unsub);\n\n if (event !== undefined) emitTap({ event, type: 'unsubscribe' });\n else if (wildcard) emitTap({ type: 'unsubscribe-any' });\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n\n if (event !== undefined) emitTap({ event, type: 'subscribe' });\n else if (wildcard) emitTap({ type: 'subscribe-any' });\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n doWarn(\n `${onLog} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n const capturedSet = set;\n\n return registerEntry(capturedSet, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, {\n event,\n onLog: `on(\"${event}\")`,\n onRemove: () => {\n if (capturedSet.size === 0) listeners.delete(event);\n\n onRemove?.();\n },\n });\n }\n\n function onAnyWithSignal(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n return registerEntry(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n { onLog: 'onAny', onRemove, wildcard: true },\n );\n }\n\n function onceWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onWithSignal(\n event,\n (payload) => {\n ref.unsub();\n listener(payload);\n },\n signal,\n onRemove,\n );\n\n return ref.unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): () => void {\n return onWithSignal(event, listener, createSubscriptionScope(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n opts?: { signal?: AbortSignal },\n ): () => void {\n const signal = createSubscriptionScope(opts?.signal);\n\n return onceWithSignal(event, listener, signal);\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): () => void {\n return onAnyWithSignal(listener, createSubscriptionScope(opts?.signal));\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: { signal?: AbortSignal }): Promise<T[K]> {\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason);\n };\n\n onceWithSignal(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n function eventNames(): EventKey<T>[] {\n return [...listeners.keys()] as EventKey<T>[];\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: { signal?: AbortSignal }): () => void {\n if (disposeController.signal.aborted) return noop;\n\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = () => tappers.delete(handler);\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function waitAny<K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n const activeSignal = createSubscriptionScope(opts?.signal);\n\n if (activeSignal.aborted) return Promise.reject(activeSignal.reason);\n\n return new Promise<WaitAnyResult<T, K>>((resolve, reject) => {\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([activeSignal, raceController.signal]);\n const unsubs: Unsubscribe[] = [];\n let settled = false;\n\n function cleanup(): void {\n activeSignal.removeEventListener('abort', onAbort);\n raceController.abort();\n for (const unsub of unsubs) unsub();\n }\n\n function onAbort(): void {\n if (settled) return;\n\n settled = true;\n cleanup();\n reject(activeSignal.reason);\n }\n\n activeSignal.addEventListener('abort', onAbort, { once: true });\n\n for (const event of eventList) {\n unsubs.push(\n onceWithSignal(\n event as EventKey<T>,\n (payload) => {\n if (settled) return;\n\n settled = true;\n cleanup();\n resolve({ event, payload } as WaitAnyResult<T, K>);\n },\n raceSignal,\n ),\n );\n }\n });\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"herald.iife.js","names":["exports","message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","tapEvents","makeEntry","label","set","listener","unsub","payload","reject","resolve","eventList","raceController","raceSignal","waiters","waiter","result","count","firstError","err","args","total","active","handler"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\nconst noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function subscriptionSignal(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function register<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n label: string,\n tapEvents: { readonly subscribe: HeraldEvent<T>; readonly unsubscribe: HeraldEvent<T> },\n ): Unsubscribe {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub(): void {\n if (called) return;\n\n called = true;\n container.delete(entry);\n signal.removeEventListener('abort', unsub);\n emitTap(tapEvents.unsubscribe);\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n emitTap(tapEvents.subscribe);\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n warn(\n `${label} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n return register(set, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, `on(\"${event}\")`, {\n subscribe: { event, type: 'subscribe' },\n unsubscribe: { event, type: 'unsubscribe' },\n });\n }\n\n function onAnyScoped(listener: (event: EventKey<T>, payload: unknown) => void, signal: AbortSignal): Unsubscribe {\n return register(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n 'onAny',\n {\n subscribe: { type: 'subscribe-any' },\n unsubscribe: { type: 'unsubscribe-any' },\n },\n );\n }\n\n // The wrapper calls `unsub` only when the listener runs, which is always after the\n // assignment completed; no indirection object is needed.\n function onceScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n const unsub = onScoped(\n event,\n (payload) => {\n unsub();\n listener(payload);\n },\n signal,\n );\n\n return unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onceScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe {\n return onAnyScoped(listener, subscriptionSignal(opts?.signal));\n }\n\n // `signal` must already combine bus disposal with any caller-provided signal.\n function waitScoped<K extends EventKey<T>>(event: K, signal: AbortSignal): Promise<T[K]> {\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = (): void => {\n reject(signal.reason);\n };\n\n onceScoped(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]> {\n return waitScoped(event, subscriptionSignal(opts?.signal));\n }\n\n function waitAny<const K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: SubscribeOptions,\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length === 0) {\n throw new TypeError('waitAny() requires at least one event name');\n }\n\n // One-shot `wait()` per event sharing one signal: an internal controller aborts the\n // loser subscriptions once one resolves, and `Promise.race` provides the settled-once\n // winner/loser semantics, rejection with the composite signal's reason included.\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([subscriptionSignal(opts?.signal), raceController.signal]);\n const waiters = eventList.map((event) => waitScoped(event, raceSignal).then((payload) => ({ event, payload })));\n\n // Losers reject through the cleanup abort: keep every rejection observed.\n for (const waiter of waiters) waiter.catch(noop);\n\n return Promise.race(waiters).then((result) => {\n raceController.abort();\n return result as WaitAnyResult<T, K>;\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n // Empty sets stay in `listeners` after their last listener leaves (removing them eagerly\n // on unsubscribe is what previously corrupted re-registered listeners); filter here instead.\n function eventNames(): EventKey<T>[] {\n const active: EventKey<T>[] = [];\n\n for (const [event, set] of listeners) {\n if (set.size > 0) active.push(event as EventKey<T>);\n }\n\n return active;\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: SubscribeOptions): Unsubscribe {\n const signal = subscriptionSignal(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = (): void => {\n tappers.delete(handler);\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
package/dist/herald.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/errors.ts
2
2
  var HeraldError = class extends Error {
3
3
  constructor(e, t) {
4
- super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
4
+ super(e, t), this.name = new.target.name;
5
5
  }
6
6
  }, BusDisposedError = class extends HeraldError {
7
7
  constructor(e) {
@@ -11,79 +11,84 @@ var HeraldError = class extends Error {
11
11
  function createBus(e) {
12
12
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = new AbortController(), a = e?.name, o = e?.maxListeners, s = a ? ` (${a})` : "";
13
13
  function emitTap(e) {
14
- if (r.size !== 0) for (let t of r) try {
14
+ for (let t of r) try {
15
15
  t(e);
16
16
  } catch {}
17
17
  }
18
- function createSubscriptionScope(e) {
18
+ function subscriptionSignal(e) {
19
19
  return e ? AbortSignal.any([i.signal, e]) : i.signal;
20
20
  }
21
- function registerEntry(e, t, n, { event: r, onLog: i, onRemove: a, wildcard: c }) {
21
+ function register(e, t, n, r, i) {
22
22
  if (n.aborted) return noop;
23
- let l = !1;
23
+ let a = !1;
24
24
  function unsub() {
25
- l || (l = !0, e.delete(u), a?.(), n.removeEventListener("abort", unsub), r === void 0 ? c && emitTap({ type: "unsubscribe-any" }) : emitTap({
26
- event: r,
27
- type: "unsubscribe"
28
- }));
25
+ a || (a = !0, e.delete(c), n.removeEventListener("abort", unsub), emitTap(i.unsubscribe));
29
26
  }
30
- let u = t(unsub);
31
- return e.add(u), n.addEventListener("abort", unsub, { once: !0 }), r === void 0 ? c && emitTap({ type: "subscribe-any" }) : emitTap({
32
- event: r,
33
- type: "subscribe"
34
- }), o !== void 0 && e.size > o && `${i}${e.size}${o}${s}`, unsub;
35
- }
36
- function onWithSignal(e, n, r, i) {
37
- let a = t.get(e);
38
- a || (a = /* @__PURE__ */ new Set(), t.set(e, a));
39
- let o = a;
40
- return registerEntry(o, (e) => ({
27
+ let c = t(unsub);
28
+ return e.add(c), n.addEventListener("abort", unsub, { once: !0 }), emitTap(i.subscribe), o !== void 0 && e.size > o && `${r}${e.size}${o}${s}`, unsub;
29
+ }
30
+ function onScoped(e, n, r) {
31
+ let i = t.get(e);
32
+ return i || (i = /* @__PURE__ */ new Set(), t.set(e, i)), register(i, (e) => ({
41
33
  fn: n,
42
34
  unsub: e
43
- }), r, {
44
- event: e,
45
- onLog: `on("${e}")`,
46
- onRemove: () => {
47
- o.size === 0 && t.delete(e), i?.();
35
+ }), r, `on("${e}")`, {
36
+ subscribe: {
37
+ event: e,
38
+ type: "subscribe"
39
+ },
40
+ unsubscribe: {
41
+ event: e,
42
+ type: "unsubscribe"
48
43
  }
49
44
  });
50
45
  }
51
- function onAnyWithSignal(e, t, r) {
52
- return registerEntry(n, (t) => ({
46
+ function onAnyScoped(e, t) {
47
+ return register(n, (t) => ({
53
48
  fn: e,
54
49
  unsub: t
55
- }), t, {
56
- onLog: "onAny",
57
- onRemove: r,
58
- wildcard: !0
50
+ }), t, "onAny", {
51
+ subscribe: { type: "subscribe-any" },
52
+ unsubscribe: { type: "unsubscribe-any" }
59
53
  });
60
54
  }
61
- function onceWithSignal(e, t, n, r) {
62
- let i = { unsub: noop };
63
- return i.unsub = onWithSignal(e, (e) => {
64
- i.unsub(), t(e);
65
- }, n, r), i.unsub;
55
+ function onceScoped(e, t, n) {
56
+ let r = onScoped(e, (e) => {
57
+ r(), t(e);
58
+ }, n);
59
+ return r;
66
60
  }
67
61
  function on(e, t, n) {
68
- return onWithSignal(e, t, createSubscriptionScope(n?.signal));
62
+ return onScoped(e, t, subscriptionSignal(n?.signal));
69
63
  }
70
64
  function once(e, t, n) {
71
- return onceWithSignal(e, t, createSubscriptionScope(n?.signal));
65
+ return onceScoped(e, t, subscriptionSignal(n?.signal));
72
66
  }
73
67
  function onAny(e, t) {
74
- return onAnyWithSignal(e, createSubscriptionScope(t?.signal));
68
+ return onAnyScoped(e, subscriptionSignal(t?.signal));
75
69
  }
76
- function wait(e, t) {
77
- let n = createSubscriptionScope(t?.signal);
78
- return n.aborted ? Promise.reject(n.reason) : new Promise((t, r) => {
70
+ function waitScoped(e, t) {
71
+ return t.aborted ? Promise.reject(t.reason) : new Promise((n, r) => {
79
72
  let onAbort = () => {
80
- r(n.reason);
73
+ r(t.reason);
81
74
  };
82
- onceWithSignal(e, (e) => {
83
- n.removeEventListener("abort", onAbort), t(e);
84
- }, n), n.addEventListener("abort", onAbort, { once: !0 });
75
+ onceScoped(e, (e) => {
76
+ t.removeEventListener("abort", onAbort), n(e);
77
+ }, t), t.addEventListener("abort", onAbort, { once: !0 });
85
78
  });
86
79
  }
80
+ function wait(e, t) {
81
+ return waitScoped(e, subscriptionSignal(t?.signal));
82
+ }
83
+ function waitAny(e, t) {
84
+ if (e.length === 0) throw TypeError("waitAny() requires at least one event name");
85
+ let n = new AbortController(), r = AbortSignal.any([subscriptionSignal(t?.signal), n.signal]), i = e.map((e) => waitScoped(e, r).then((t) => ({
86
+ event: e,
87
+ payload: t
88
+ })));
89
+ for (let e of i) e.catch(noop);
90
+ return Promise.race(i).then((e) => (n.abort(), e));
91
+ }
87
92
  function dispatch(e, r) {
88
93
  let i = 0, a, o = t.get(e);
89
94
  if (o?.size) for (let t of [...o]) {
@@ -132,38 +137,21 @@ function createBus(e) {
132
137
  return n.size;
133
138
  }
134
139
  function eventNames() {
135
- return [...t.keys()];
140
+ let e = [];
141
+ for (let [n, r] of t) r.size > 0 && e.push(n);
142
+ return e;
136
143
  }
137
144
  function tap(e, t) {
138
- if (i.signal.aborted) return noop;
139
- let n = createSubscriptionScope(t?.signal);
145
+ let n = subscriptionSignal(t?.signal);
140
146
  if (n.aborted) return noop;
141
147
  r.add(e);
142
- let onAbort = () => r.delete(e);
148
+ let onAbort = () => {
149
+ r.delete(e);
150
+ };
143
151
  return n.addEventListener("abort", onAbort, { once: !0 }), () => {
144
152
  r.delete(e), n.removeEventListener("abort", onAbort);
145
153
  };
146
154
  }
147
- function waitAny(e, t) {
148
- let n = createSubscriptionScope(t?.signal);
149
- return n.aborted ? Promise.reject(n.reason) : new Promise((t, r) => {
150
- let i = new AbortController(), a = AbortSignal.any([n, i.signal]), o = [], s = !1;
151
- function cleanup() {
152
- n.removeEventListener("abort", onAbort), i.abort();
153
- for (let e of o) e();
154
- }
155
- function onAbort() {
156
- s || (s = !0, cleanup(), r(n.reason));
157
- }
158
- n.addEventListener("abort", onAbort, { once: !0 });
159
- for (let n of e) o.push(onceWithSignal(n, (e) => {
160
- s || (s = !0, cleanup(), t({
161
- event: n,
162
- payload: e
163
- }));
164
- }, a));
165
- });
166
- }
167
155
  function dispose() {
168
156
  i.signal.aborted || (emitTap({ type: "dispose" }), i.abort(new BusDisposedError(a)), t.clear(), n.clear(), r.clear());
169
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"herald.js","names":["message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","onRemove","wildcard","makeEntry","onLog","set","capturedSet","listener","ref","payload","resolve","count","firstError","err","args","total","handler","activeSignal","raceController","raceSignal","unsubs","settled","unsub","reject","eventList"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\n/** @internal */\nexport const noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\ntype RegisterEntryOpts<T extends EventMap> = {\n event?: EventKey<T>;\n onLog: string;\n onRemove?: () => void;\n wildcard?: boolean;\n};\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n if (tappers.size === 0) return;\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function doWarn(msg: string): void {\n _internalWarn(msg);\n }\n\n function createSubscriptionScope(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function registerEntry<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n { event, onLog, onRemove, wildcard }: RegisterEntryOpts<T>,\n ): () => void {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub() {\n if (called) return;\n\n called = true;\n container.delete(entry);\n onRemove?.();\n signal.removeEventListener('abort', unsub);\n\n if (event !== undefined) emitTap({ event, type: 'unsubscribe' });\n else if (wildcard) emitTap({ type: 'unsubscribe-any' });\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n\n if (event !== undefined) emitTap({ event, type: 'subscribe' });\n else if (wildcard) emitTap({ type: 'subscribe-any' });\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n doWarn(\n `${onLog} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n const capturedSet = set;\n\n return registerEntry(capturedSet, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, {\n event,\n onLog: `on(\"${event}\")`,\n onRemove: () => {\n if (capturedSet.size === 0) listeners.delete(event);\n\n onRemove?.();\n },\n });\n }\n\n function onAnyWithSignal(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n return registerEntry(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n { onLog: 'onAny', onRemove, wildcard: true },\n );\n }\n\n function onceWithSignal<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onWithSignal(\n event,\n (payload) => {\n ref.unsub();\n listener(payload);\n },\n signal,\n onRemove,\n );\n\n return ref.unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): () => void {\n return onWithSignal(event, listener, createSubscriptionScope(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(\n event: K,\n listener: Listener<T[K]>,\n opts?: { signal?: AbortSignal },\n ): () => void {\n const signal = createSubscriptionScope(opts?.signal);\n\n return onceWithSignal(event, listener, signal);\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): () => void {\n return onAnyWithSignal(listener, createSubscriptionScope(opts?.signal));\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: { signal?: AbortSignal }): Promise<T[K]> {\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason);\n };\n\n onceWithSignal(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n function eventNames(): EventKey<T>[] {\n return [...listeners.keys()] as EventKey<T>[];\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: { signal?: AbortSignal }): () => void {\n if (disposeController.signal.aborted) return noop;\n\n const signal = createSubscriptionScope(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = () => tappers.delete(handler);\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function waitAny<K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n const activeSignal = createSubscriptionScope(opts?.signal);\n\n if (activeSignal.aborted) return Promise.reject(activeSignal.reason);\n\n return new Promise<WaitAnyResult<T, K>>((resolve, reject) => {\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([activeSignal, raceController.signal]);\n const unsubs: Unsubscribe[] = [];\n let settled = false;\n\n function cleanup(): void {\n activeSignal.removeEventListener('abort', onAbort);\n raceController.abort();\n for (const unsub of unsubs) unsub();\n }\n\n function onAbort(): void {\n if (settled) return;\n\n settled = true;\n cleanup();\n reject(activeSignal.reason);\n }\n\n activeSignal.addEventListener('abort', onAbort, { once: true });\n\n for (const event of eventList) {\n unsubs.push(\n onceWithSignal(\n event as EventKey<T>,\n (payload) => {\n if (settled) return;\n\n settled = true;\n cleanup();\n resolve({ event, payload } as WaitAnyResult<T, K>);\n },\n raceSignal,\n ),\n );\n }\n });\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":";ACCA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAMA,GAASC,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,mBAAb,cAAsC,YAAY;CAChD,YAAY,GAAkB;EAC5B,MAAMC,IAAU,QAAQA,EAAQ,iBAAiB,iBAAiB;CACpE;AACF,GCEa,aAAa,CAAC;AAY3B,SAAgB,UAAwD,GAA8B;CACpG,IAAMC,oBAAY,IAAI,IAAwB,GACxCC,oBAAY,IAAI,IAAmB,GACnCC,oBAAU,IAAI,IAAqC,GACnDC,IAAoB,IAAI,gBAAgB,GACxCJ,IAAUK,GAAS,MACnBC,IAAeD,GAAS,cACxBE,IAASP,IAAU,KAAKA,EAAQ,KAAK;CAE3C,SAAS,QAAQ,GAA6B;EAC5C,IAAIG,EAAQ,SAAS,GACrB,KAAK,IAAMK,KAAUL,GACnB,IAAI;GACF,EAAOM,CAAK;EACd,QAAQ,CAER;CAEJ;CAMA,SAAS,wBAAwB,GAAmC;EAClE,OAAOC,IAAS,YAAY,IAAI,CAACN,EAAkB,QAAQM,CAAM,CAAC,IAAIN,EAAkB;CAC1F;CAEA,SAAS,cACP,GACA,GACA,GACA,EAAE,UAAO,UAAO,aAAU,eACd;EACZ,IAAIM,EAAO,SAAS,OAAO;EAE3B,IAAIC,IAAS;EAEb,SAAS,QAAQ;GACf,AAAIA,MAEJ,IAAS,IACTC,EAAU,OAAOC,CAAK,GACtBC,IAAW,GACXJ,EAAO,oBAAoB,SAAS,KAAK,GAErCD,MAAU,KAAA,IACLM,KAAU,QAAQ,EAAE,MAAM,kBAAkB,CAAC,IAD7B,QAAQ;IAAE;IAAO,MAAM;GAAc,CAAC;EAEjE;EAEA,IAAMF,IAAQG,EAAU,KAAK;EAc7B,OAZAJ,EAAU,IAAIC,CAAK,GACnBH,EAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,GAAK,CAAC,GAElDD,MAAU,KAAA,IACLM,KAAU,QAAQ,EAAE,MAAM,gBAAgB,CAAC,IAD3B,QAAQ;GAAE;GAAO,MAAM;EAAY,CAAC,GAGzDT,MAAiB,KAAA,KAAaM,EAAU,OAAON,KAE/C,GAAGW,EAAH,EAAgBL,EAAU,KAA1B,EAAqEN,EAArE,EAA4GC,EAA5G,GAIG;CACT;CAEA,SAAS,aACP,GACA,GACA,GACA,GACY;EACZ,IAAIW,IAAMjB,EAAU,IAAIQ,CAAK;EAE7B,AAAKS,MACH,oBAAM,IAAI,IAAI,GACdjB,EAAU,IAAIQ,GAAOS,CAAG;EAG1B,IAAMC,IAAcD;EAEpB,OAAO,cAAcC,IAAc,OAAW;GAAE,IAAIC;GAA+B;EAAM,IAAIV,GAAQ;GACnG;GACA,OAAO,OAAOD,EAAM;GACpB,gBAAgB;IAGd,AAFIU,EAAY,SAAS,KAAGlB,EAAU,OAAOQ,CAAK,GAElDK,IAAW;GACb;EACF,CAAC;CACH;CAEA,SAAS,gBACP,GACA,GACA,GACY;EACZ,OAAO,cACLZ,IACC,OAAW;GAAE,IAAIkB;GAAuD;EAAM,IAC/EV,GACA;GAAE,OAAO;GAAS;GAAU,UAAU;EAAK,CAC7C;CACF;CAEA,SAAS,eACP,GACA,GACA,GACA,GACY;EACZ,IAAMW,IAAM,EAAE,OAAO,KAAoB;EAYzC,OAVA,EAAI,QAAQ,aACVZ,IACC,MAAY;GAEX,AADAY,EAAI,MAAM,GACVD,EAASE,CAAO;EAClB,GACAZ,GACAI,CACF,GAEOO,EAAI;CACb;CAEA,SAAS,GAA0B,GAAU,GAA0B,GAAqC;EAC1G,OAAO,aAAaZ,GAAOW,GAAU,wBAAwBrB,GAAM,MAAM,CAAC;CAC5E;CAEA,SAAS,KACP,GACA,GACA,GACY;EAGZ,OAAO,eAAeU,GAAOW,GAFd,wBAAwBrB,GAAM,MAEN,CAAM;CAC/C;CAEA,SAAS,MAAM,GAA0D,GAAqC;EAC5G,OAAO,gBAAgBqB,GAAU,wBAAwBrB,GAAM,MAAM,CAAC;CACxE;CAEA,SAAS,KAA4B,GAAU,GAAgD;EAC7F,IAAMW,IAAS,wBAAwBX,GAAM,MAAM;EAInD,OAFIW,EAAO,UAAgB,QAAQ,OAAOA,EAAO,MAAM,IAEhD,IAAI,SAAe,GAAS,MAAW;GAC5C,IAAM,gBAAgB;IACpB,EAAOA,EAAO,MAAM;GACtB;GAWA,AATA,eACED,IACC,MAAY;IAEX,AADAC,EAAO,oBAAoB,SAAS,OAAO,GAC3Ca,EAAQD,CAAO;GACjB,GACAZ,CACF,GAEAA,EAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,GAAK,CAAC;EAC1D,CAAC;CACH;CAEA,SAAS,SAAS,GAAoB,GAAwB;EAC5D,IAAIc,IAAQ,GACRC,GACEP,IAAMjB,EAAU,IAAIQ,CAAK;EAE/B,IAAIS,GAAK,MACP,KAAK,IAAML,KAAS,CAAC,GAAGK,CAAG,GAAG;GAC5B,IAAI;IACF,EAAM,GAAGI,CAAO;GAClB,SAASI,GAAK;IAEZ,AADA,MAAe,EAAE,OAAOA,EAAI,GAC5B,QAAQ;KAAE,OAAOA;KAAK;KAAO,MAAM;IAAQ,CAAC;GAC9C;GAEA;EACF;EAGF,IAAIxB,EAAU,MACZ,KAAK,IAAMW,KAAS,CAAC,GAAGX,CAAS,GAAG;GAClC,IAAI;IACF,EAAM,GAAGO,GAAOa,CAAO;GACzB,SAASI,GAAK;IAEZ,AADA,MAAe,EAAE,OAAOA,EAAI,GAC5B,QAAQ;KAAE,OAAOA;KAAK;KAAO,MAAM;IAAQ,CAAC;GAC9C;GAEA;EACF;EAKF,IAFA,QAAQ;GAAE;GAAO,WAAWF;GAAO;GAAS,MAAM;EAAO,CAAC,GAEtDC,GAAY,MAAMA,EAAW;CACnC;CAEA,SAAS,KAA4B,GAAU,GAAGE,GAAsD;EACtG,IAAIvB,EAAkB,OAAO,SAAS;EAEtC,IAAMkB,IAAWK,EAAmB;EAEpC,SAASlB,GAAOa,CAAO;CACzB;CAEA,SAAS,cAAc,GAA6B;EAClD,IAAIb,MAAU,KAAA,GAAW,OAAOR,EAAU,IAAIQ,CAAK,CAAC,EAAE,QAAQ;EAE9D,IAAImB,IAAQ;EAEZ,KAAK,IAAMV,KAAOjB,EAAU,OAAO,GAAG,KAASiB,EAAI;EAEnD,OAAOU;CACT;CAEA,SAAS,gBAAwB;EAC/B,OAAO1B,EAAU;CACnB;CAEA,SAAS,aAA4B;EACnC,OAAO,CAAC,GAAGD,EAAU,KAAK,CAAC;CAC7B;CAEA,SAAS,IAAI,GAA0C,GAA6C;EAClG,IAAIG,EAAkB,OAAO,SAAS,OAAO;EAE7C,IAAMM,IAAS,wBAAwBX,GAAM,MAAM;EAEnD,IAAIW,EAAO,SAAS,OAAO;EAE3B,EAAQ,IAAImB,CAAO;EAEnB,IAAM,gBAAgB1B,EAAQ,OAAO0B,CAAO;EAI5C,OAFAnB,EAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,GAAK,CAAC,SAE3C;GAEX,AADAP,EAAQ,OAAO0B,CAAO,GACtBnB,EAAO,oBAAoB,SAAS,OAAO;EAC7C;CACF;CAEA,SAAS,QACP,GACA,GAC8B;EAC9B,IAAMoB,IAAe,wBAAwB/B,GAAM,MAAM;EAIzD,OAFI+B,EAAa,UAAgB,QAAQ,OAAOA,EAAa,MAAM,IAE5D,IAAI,SAA8B,GAAS,MAAW;GAC3D,IAAMC,IAAiB,IAAI,gBAAgB,GACrCC,IAAa,YAAY,IAAI,CAACF,GAAcC,EAAe,MAAM,CAAC,GAClEE,IAAwB,CAAC,GAC3BC,IAAU;GAEd,SAAS,UAAgB;IAEvB,AADAJ,EAAa,oBAAoB,SAAS,OAAO,GACjDC,EAAe,MAAM;IACrB,KAAK,IAAMI,KAASF,GAAQ,EAAM;GACpC;GAEA,SAAS,UAAgB;IACvB,AAAIC,MAEJ,IAAU,IACV,QAAQ,GACRE,EAAON,EAAa,MAAM;GAC5B;GAEA,EAAa,iBAAiB,SAAS,SAAS,EAAE,MAAM,GAAK,CAAC;GAE9D,KAAK,IAAMrB,KAAS4B,GAClB,EAAO,KACL,eACE5B,IACC,MAAY;IACX,AAAIyB,MAEJ,IAAU,IACV,QAAQ,GACRX,EAAQ;KAAE;KAAO;IAAQ,CAAwB;GACnD,GACAS,CACF,CACF;EAEJ,CAAC;CACH;CAEA,SAAS,UAAgB;EACvB,AAAI5B,EAAkB,OAAO,YAE7B,QAAQ,EAAE,MAAM,UAAU,CAAC,GAC3BA,EAAkB,MAAM,IAAI,iBAAiBJ,CAAO,CAAC,GACrDC,EAAU,MAAM,GAChBC,EAAU,MAAM,GAChBC,EAAQ,MAAM;CAChB;CAEA,OAAO;EACL,IAAI,iBAAiB;GACnB,OAAOC,EAAkB;EAC3B;EACA;EACA,IAAI,WAAW;GACb,OAAOA,EAAkB,OAAO;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;GACC,OAAO,UAAU;EAClB;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"herald.js","names":["message","opts","busName","listeners","wildcards","tappers","disposeController","options","maxListeners","busTag","tapper","event","signal","called","container","entry","tapEvents","makeEntry","label","set","listener","unsub","payload","resolve","eventList","raceController","raceSignal","waiters","waiter","result","count","firstError","err","args","total","active","handler"],"sources":["../src/_dev.ts","../src/errors.ts","../src/bus.ts"],"sourcesContent":["const isDev = !(globalThis as { __HERALD_PROD__?: boolean }).__HERALD_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/herald] ${msg}`);\n}\n","/** Base class for all herald errors. Use `instanceof HeraldError` to catch any herald-originated error. */\nexport class HeraldError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n }\n}\n\n/** Thrown when an operation is attempted on a disposed event bus. */\nexport class BusDisposedError extends HeraldError {\n constructor(busName?: string) {\n super(busName ? `Bus \"${busName}\" is disposed` : 'Bus is disposed');\n }\n}\n","import { warn } from './_dev';\nimport { BusDisposedError } from './errors';\nimport type {\n Bus,\n BusOptions,\n EventKey,\n EventMap,\n HeraldEvent,\n Listener,\n SubscribeOptions,\n Unsubscribe,\n WaitAnyResult,\n} from './types';\n\n// Module-scoped noop: shared across all bus instances to avoid per-bus allocation.\nconst noop = () => {};\n\ntype Entry = { fn: Listener<unknown>; unsub: () => void };\ntype WildcardEntry = { fn: (event: string, payload: unknown) => void; unsub: () => void };\n\nexport function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T> {\n const listeners = new Map<string, Set<Entry>>();\n const wildcards = new Set<WildcardEntry>();\n const tappers = new Set<(event: HeraldEvent<T>) => void>();\n const disposeController = new AbortController();\n const busName = options?.name;\n const maxListeners = options?.maxListeners;\n const busTag = busName ? ` (${busName})` : '';\n\n function emitTap(event: HeraldEvent<T>): void {\n for (const tapper of tappers) {\n try {\n tapper(event);\n } catch {\n // Observability must not affect bus behavior.\n }\n }\n }\n\n function subscriptionSignal(signal?: AbortSignal): AbortSignal {\n return signal ? AbortSignal.any([disposeController.signal, signal]) : disposeController.signal;\n }\n\n function register<E extends { unsub: () => void }>(\n container: Set<E>,\n makeEntry: (unsub: () => void) => E,\n signal: AbortSignal,\n label: string,\n tapEvents: { readonly subscribe: HeraldEvent<T>; readonly unsubscribe: HeraldEvent<T> },\n ): Unsubscribe {\n if (signal.aborted) return noop;\n\n let called = false;\n\n function unsub(): void {\n if (called) return;\n\n called = true;\n container.delete(entry);\n signal.removeEventListener('abort', unsub);\n emitTap(tapEvents.unsubscribe);\n }\n\n const entry = makeEntry(unsub);\n\n container.add(entry);\n signal.addEventListener('abort', unsub, { once: true });\n emitTap(tapEvents.subscribe);\n\n if (maxListeners !== undefined && container.size > maxListeners) {\n warn(\n `${label} has ${container.size} listeners, exceeding maxListeners (${maxListeners}). Possible memory leak.${busTag}`,\n );\n }\n\n return unsub;\n }\n\n function onScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n let set = listeners.get(event);\n\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n\n return register(set, (unsub) => ({ fn: listener as Listener<unknown>, unsub }), signal, `on(\"${event}\")`, {\n subscribe: { event, type: 'subscribe' },\n unsubscribe: { event, type: 'unsubscribe' },\n });\n }\n\n function onAnyScoped(listener: (event: EventKey<T>, payload: unknown) => void, signal: AbortSignal): Unsubscribe {\n return register(\n wildcards,\n (unsub) => ({ fn: listener as (event: string, payload: unknown) => void, unsub }),\n signal,\n 'onAny',\n {\n subscribe: { type: 'subscribe-any' },\n unsubscribe: { type: 'unsubscribe-any' },\n },\n );\n }\n\n // The wrapper calls `unsub` only when the listener runs, which is always after the\n // assignment completed; no indirection object is needed.\n function onceScoped<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, signal: AbortSignal): Unsubscribe {\n const unsub = onScoped(\n event,\n (payload) => {\n unsub();\n listener(payload);\n },\n signal,\n );\n\n return unsub;\n }\n\n function on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe {\n return onceScoped(event, listener, subscriptionSignal(opts?.signal));\n }\n\n function onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe {\n return onAnyScoped(listener, subscriptionSignal(opts?.signal));\n }\n\n // `signal` must already combine bus disposal with any caller-provided signal.\n function waitScoped<K extends EventKey<T>>(event: K, signal: AbortSignal): Promise<T[K]> {\n if (signal.aborted) return Promise.reject(signal.reason);\n\n return new Promise<T[K]>((resolve, reject) => {\n const onAbort = (): void => {\n reject(signal.reason);\n };\n\n onceScoped(\n event,\n (payload) => {\n signal.removeEventListener('abort', onAbort);\n resolve(payload);\n },\n signal,\n );\n\n signal.addEventListener('abort', onAbort, { once: true });\n });\n }\n\n function wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]> {\n return waitScoped(event, subscriptionSignal(opts?.signal));\n }\n\n function waitAny<const K extends readonly EventKey<T>[]>(\n eventList: K,\n opts?: SubscribeOptions,\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length === 0) {\n throw new TypeError('waitAny() requires at least one event name');\n }\n\n // One-shot `wait()` per event sharing one signal: an internal controller aborts the\n // loser subscriptions once one resolves, and `Promise.race` provides the settled-once\n // winner/loser semantics, rejection with the composite signal's reason included.\n const raceController = new AbortController();\n const raceSignal = AbortSignal.any([subscriptionSignal(opts?.signal), raceController.signal]);\n const waiters = eventList.map((event) => waitScoped(event, raceSignal).then((payload) => ({ event, payload })));\n\n // Losers reject through the cleanup abort: keep every rejection observed.\n for (const waiter of waiters) waiter.catch(noop);\n\n return Promise.race(waiters).then((result) => {\n raceController.abort();\n return result as WaitAnyResult<T, K>;\n });\n }\n\n function dispatch(event: EventKey<T>, payload: unknown): void {\n let count = 0;\n let firstError: { value: unknown } | undefined;\n const set = listeners.get(event);\n\n if (set?.size) {\n for (const entry of [...set]) {\n try {\n entry.fn(payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n if (wildcards.size) {\n for (const entry of [...wildcards]) {\n try {\n entry.fn(event, payload);\n } catch (err) {\n firstError ??= { value: err };\n emitTap({ error: err, event, type: 'error' });\n }\n\n count++;\n }\n }\n\n emitTap({ event, listeners: count, payload, type: 'emit' });\n\n if (firstError) throw firstError.value;\n }\n\n function emit<K extends EventKey<T>>(event: K, ...args: T[K] extends void ? [] : [payload: T[K]]): void {\n if (disposeController.signal.aborted) return;\n\n const payload = (args as unknown[])[0];\n\n dispatch(event, payload);\n }\n\n function listenerCount(event?: EventKey<T>): number {\n if (event !== undefined) return listeners.get(event)?.size ?? 0;\n\n let total = 0;\n\n for (const set of listeners.values()) total += set.size;\n\n return total;\n }\n\n function wildcardCount(): number {\n return wildcards.size;\n }\n\n // Empty sets stay in `listeners` after their last listener leaves (removing them eagerly\n // on unsubscribe is what previously corrupted re-registered listeners); filter here instead.\n function eventNames(): EventKey<T>[] {\n const active: EventKey<T>[] = [];\n\n for (const [event, set] of listeners) {\n if (set.size > 0) active.push(event as EventKey<T>);\n }\n\n return active;\n }\n\n function tap(handler: (event: HeraldEvent<T>) => void, opts?: SubscribeOptions): Unsubscribe {\n const signal = subscriptionSignal(opts?.signal);\n\n if (signal.aborted) return noop;\n\n tappers.add(handler);\n\n const onAbort = (): void => {\n tappers.delete(handler);\n };\n\n signal.addEventListener('abort', onAbort, { once: true });\n\n return () => {\n tappers.delete(handler);\n signal.removeEventListener('abort', onAbort);\n };\n }\n\n function dispose(): void {\n if (disposeController.signal.aborted) return;\n\n emitTap({ type: 'dispose' });\n disposeController.abort(new BusDisposedError(busName));\n listeners.clear();\n wildcards.clear();\n tappers.clear();\n }\n\n return {\n get disposalSignal() {\n return disposeController.signal;\n },\n dispose,\n get disposed() {\n return disposeController.signal.aborted;\n },\n emit,\n eventNames,\n listenerCount,\n on,\n onAny,\n once,\n [Symbol.dispose]: dispose,\n tap,\n wait,\n waitAny,\n wildcardCount,\n };\n}\n"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -3,10 +3,11 @@ export type EventKey<T extends EventMap> = Extract<keyof T, string>;
3
3
  export type Listener<T> = (payload: T) => void;
4
4
  export type Unsubscribe = () => void;
5
5
  /**
6
- * Options for a single-event subscription. Passed as the third argument to `bus.on()`.
6
+ * Options accepted by every subscription-shaped method: `on`, `once`, `onAny`,
7
+ * `tap`, `wait`, and `waitAny`.
7
8
  */
8
9
  export type SubscribeOptions = {
9
- /** Auto-remove the listener when this signal aborts. */
10
+ /** End the subscription or pending wait when this signal aborts. */
10
11
  signal?: AbortSignal;
11
12
  };
12
13
  /**
@@ -93,25 +94,20 @@ export type Bus<T extends EventMap> = {
93
94
  /**
94
95
  * Subscribe once: auto-unsubscribes after the first emit. Stops early when the signal aborts.
95
96
  */
96
- once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: {
97
- signal?: AbortSignal;
98
- }): Unsubscribe;
97
+ once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe;
99
98
  /**
100
99
  * Resolve on the next emit of the given event.
101
100
  * Rejects with `BusDisposedError` if the bus is disposed before the event fires,
102
101
  * or with the signal's reason if the signal aborts.
103
102
  */
104
- wait<K extends EventKey<T>>(event: K, opts?: {
105
- signal?: AbortSignal;
106
- }): Promise<T[K]>;
103
+ wait<K extends EventKey<T>>(event: K, opts?: SubscribeOptions): Promise<T[K]>;
107
104
  /**
108
105
  * Resolve when any of the listed events fires first. Accepts one or more event keys.
109
106
  * Returns a typed `{ event, payload }` discriminated union.
110
107
  * Rejects with `BusDisposedError` if the bus is disposed, or with the signal's reason if the signal aborts.
108
+ * Throws a synchronous `TypeError` when the list is empty.
111
109
  */
112
- waitAny<const K extends readonly EventKey<T>[]>(events: K, opts?: {
113
- signal?: AbortSignal;
114
- }): Promise<WaitAnyResult<T, K>>;
110
+ waitAny<const K extends readonly EventKey<T>[]>(events: K, opts?: SubscribeOptions): Promise<WaitAnyResult<T, K>>;
115
111
  /**
116
112
  * Number of active wildcard (`onAny`) listeners.
117
113
  */
@@ -120,8 +116,6 @@ export type Bus<T extends EventMap> = {
120
116
  * Observe runtime events (emit, subscribe, unsubscribe, error, dispose) without
121
117
  * affecting bus behavior. Handler errors are swallowed. Returns an unsubscribe function.
122
118
  */
123
- tap(handler: (event: HeraldEvent<T>) => void, options?: {
124
- signal?: AbortSignal;
125
- }): Unsubscribe;
119
+ tap(handler: (event: HeraldEvent<T>) => void, options?: SubscribeOptions): Unsubscribe;
126
120
  };
127
121
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielzeug/herald",
3
- "version": "26.11.12",
3
+ "version": "26.11.13",
4
4
  "description": "Typed synchronous event bus with wildcard subscriptions, one-shot waits, and lifecycle tracing",
5
5
  "repository": {
6
6
  "type": "git",