@vielzeug/herald 3.0.0 → 26.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,4 +38,4 @@ stop();
38
38
 
39
39
  ## License
40
40
 
41
- MIT © [Helmuth Saatkamp](https://github.com/helmuthdu) — part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
41
+ MIT © [Helmuth Saatkamp](https://github.com/helmuthdu): part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
package/dist/_dev.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function e(e){}exports.warn=e;
1
+ function warn(e){}exports.warn=warn;
2
2
  //# sourceMappingURL=_dev.cjs.map
package/dist/_dev.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.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"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.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"],"mappings":"AAGA,SAAgB,KAAK,EAAmB,CAExC"}
package/dist/_dev.js CHANGED
@@ -1,6 +1,2 @@
1
- //#region src/_dev.ts
2
- function e(e) {}
3
- //#endregion
4
- export { e as warn };
5
-
1
+ function warn(e){}export{warn};
6
2
  //# sourceMappingURL=_dev.js.map
package/dist/_dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.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"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC"}
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.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"],"mappings":"AAGA,SAAgB,KAAK,EAAmB,CAExC"}
package/dist/bus.cjs CHANGED
@@ -1,2 +1,2 @@
1
- require("./_dev.cjs");const e=require("./errors.cjs");var t=()=>{};function n(n){let r=new Map,i=new Set,a=new Set,o=new AbortController,s=n?.name,c=n?.maxListeners,l=s?` (${s})`:``;function u(e){if(a.size!==0)for(let t of a)try{t(e)}catch{}}function d(e){return e?AbortSignal.any([o.signal,e]):o.signal}function f(e,n,r,{event:i,onLog:a,onRemove:o,wildcard:s}){if(r.aborted)return t;let d=!1;function f(){d||(d=!0,e.delete(p),o?.(),r.removeEventListener(`abort`,f),i===void 0?s&&u({type:`unsubscribe-any`}):u({event:i,type:`unsubscribe`}))}let p=n(f);return e.add(p),r.addEventListener(`abort`,f,{once:!0}),i===void 0?s&&u({type:`subscribe-any`}):u({event:i,type:`subscribe`}),c!==void 0&&e.size>c&&`${a}${e.size}${c}${l}`,f}function p(e,t,n,i){let a=r.get(e);a||(a=new Set,r.set(e,a));let o=a;return f(o,e=>({fn:t,unsub:e}),n,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&r.delete(e),i?.()}})}function m(e,t,n){return f(i,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:n,wildcard:!0})}function h(e,n,r,i){let a={unsub:t};return a.unsub=p(e,e=>{a.unsub(),n(e)},r,i),a.unsub}function g(e,n,r){let i={unsub:t};return i.unsub=m((t,n)=>{i.unsub(),e(t,n)},n,r),i.unsub}function _(e,t,n){let r=d(n?.signal);return n?.once?h(e,t,r):p(e,t,r)}function v(e,t,n){return h(e,t,d(n?.signal))}function y(e,t){let n=d(t?.signal);return t?.once?g(e,n):m(e,n)}function b(e,t){let n=d(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=()=>{r(n.reason)};h(e,e=>{n.removeEventListener(`abort`,i),t(e)},n),n.addEventListener(`abort`,i,{once:!0})})}function x(e,t){n?._onDispatch?.(e,t);let a=0,o,s=r.get(e);if(s?.size)for(let n of[...s]){try{n.fn(t)}catch(t){o??={value:t},u({error:t,event:e,type:`error`})}a++}if(i.size)for(let n of[...i]){try{n.fn(e,t)}catch(t){o??={value:t},u({error:t,event:e,type:`error`})}a++}if(u({event:e,listeners:a,payload:t,type:`emit`}),o)throw o.value}function S(e,...t){if(o.signal.aborted)return;let n=t[0];x(e,n)}function C(e){if(e!==void 0)return r.get(e)?.size??0;let t=0;for(let e of r.values())t+=e.size;return t}function w(){return i.size}function T(){return[...r.keys()]}function E(e,n){if(o.signal.aborted)return t;let r=d(n?.signal);if(r.aborted)return t;a.add(e);let i=()=>a.delete(e);return r.addEventListener(`abort`,i,{once:!0}),()=>{a.delete(e),r.removeEventListener(`abort`,i)}}function D(t,n){if(t.length<2)throw new e.HeraldConfigError(`waitAny() requires at least 2 event keys`);let r=d(n?.signal);return r.aborted?Promise.reject(r.reason):new Promise((e,n)=>{let i=new AbortController,a=AbortSignal.any([r,i.signal]),o=[],s=!1;function c(){r.removeEventListener(`abort`,l),i.abort();for(let e of o)e()}function l(){s||(s=!0,c(),n(r.reason))}r.addEventListener(`abort`,l,{once:!0});for(let n of t)o.push(h(n,t=>{s||(s=!0,c(),e({event:n,payload:t}))},a))})}function O(){o.signal.aborted||(u({type:`dispose`}),o.abort(new e.BusDisposedError(s)),r.clear(),i.clear(),a.clear())}return{get disposalSignal(){return o.signal},dispose:O,get disposed(){return o.signal.aborted},emit:S,eventNames:T,listenerCount:C,on:_,onAny:y,once:v,[Symbol.dispose]:O,tap:E,wait:b,waitAny:D,wildcardCount:w}}exports.createBus=n,exports.noop=t;
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;
2
2
  //# sourceMappingURL=bus.cjs.map
package/dist/bus.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bus.cjs","names":[],"sources":["../src/bus.ts"],"sourcesContent":["import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError, HeraldConfigError } 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<T>): 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 onAnyWithOnce(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onAnyWithSignal(\n (event, payload) => {\n ref.unsub();\n listener(event, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onceWithSignal(event, listener, signal);\n\n return onWithSignal(event, listener, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onAnyWithOnce(listener, signal);\n\n return onAnyWithSignal(listener, 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 options?._onDispatch?.(event, payload);\n\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>, EventKey<T>, ...EventKey<T>[]]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length < 2) throw new HeraldConfigError('waitAny() requires at least 2 event keys');\n\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":[],"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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"}
package/dist/bus.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import type { Bus, BusOptions, EventMap } from './types';
2
- export declare function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions<T>): Bus<T>;
2
+ export declare function createBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): Bus<T>;
3
3
  //# sourceMappingURL=bus.d.ts.map
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,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAsWvG"}
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"}
package/dist/bus.js CHANGED
@@ -1,198 +1,2 @@
1
- import "./_dev.js";
2
- import { BusDisposedError as e, HeraldConfigError as t } from "./errors.js";
3
- //#region src/bus.ts
4
- var n = () => {};
5
- function r(r) {
6
- let i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), s = new AbortController(), c = r?.name, l = r?.maxListeners, u = c ? ` (${c})` : "";
7
- function d(e) {
8
- if (o.size !== 0) for (let t of o) try {
9
- t(e);
10
- } catch {}
11
- }
12
- function f(e) {
13
- return e ? AbortSignal.any([s.signal, e]) : s.signal;
14
- }
15
- function p(e, t, r, { event: i, onLog: a, onRemove: o, wildcard: s }) {
16
- if (r.aborted) return n;
17
- let c = !1;
18
- function f() {
19
- c || (c = !0, e.delete(p), o?.(), r.removeEventListener("abort", f), i === void 0 ? s && d({ type: "unsubscribe-any" }) : d({
20
- event: i,
21
- type: "unsubscribe"
22
- }));
23
- }
24
- let p = t(f);
25
- return e.add(p), r.addEventListener("abort", f, { once: !0 }), i === void 0 ? s && d({ type: "subscribe-any" }) : d({
26
- event: i,
27
- type: "subscribe"
28
- }), l !== void 0 && e.size > l && `${a}${e.size}${l}${u}`, f;
29
- }
30
- function m(e, t, n, r) {
31
- let a = i.get(e);
32
- a || (a = /* @__PURE__ */ new Set(), i.set(e, a));
33
- let o = a;
34
- return p(o, (e) => ({
35
- fn: t,
36
- unsub: e
37
- }), n, {
38
- event: e,
39
- onLog: `on("${e}")`,
40
- onRemove: () => {
41
- o.size === 0 && i.delete(e), r?.();
42
- }
43
- });
44
- }
45
- function h(e, t, n) {
46
- return p(a, (t) => ({
47
- fn: e,
48
- unsub: t
49
- }), t, {
50
- onLog: "onAny",
51
- onRemove: n,
52
- wildcard: !0
53
- });
54
- }
55
- function g(e, t, r, i) {
56
- let a = { unsub: n };
57
- return a.unsub = m(e, (e) => {
58
- a.unsub(), t(e);
59
- }, r, i), a.unsub;
60
- }
61
- function _(e, t, r) {
62
- let i = { unsub: n };
63
- return i.unsub = h((t, n) => {
64
- i.unsub(), e(t, n);
65
- }, t, r), i.unsub;
66
- }
67
- function v(e, t, n) {
68
- let r = f(n?.signal);
69
- return n?.once ? g(e, t, r) : m(e, t, r);
70
- }
71
- function y(e, t, n) {
72
- return g(e, t, f(n?.signal));
73
- }
74
- function b(e, t) {
75
- let n = f(t?.signal);
76
- return t?.once ? _(e, n) : h(e, n);
77
- }
78
- function x(e, t) {
79
- let n = f(t?.signal);
80
- return n.aborted ? Promise.reject(n.reason) : new Promise((t, r) => {
81
- let i = () => {
82
- r(n.reason);
83
- };
84
- g(e, (e) => {
85
- n.removeEventListener("abort", i), t(e);
86
- }, n), n.addEventListener("abort", i, { once: !0 });
87
- });
88
- }
89
- function S(e, t) {
90
- r?._onDispatch?.(e, t);
91
- let n = 0, o, s = i.get(e);
92
- if (s?.size) for (let r of [...s]) {
93
- try {
94
- r.fn(t);
95
- } catch (t) {
96
- o ??= { value: t }, d({
97
- error: t,
98
- event: e,
99
- type: "error"
100
- });
101
- }
102
- n++;
103
- }
104
- if (a.size) for (let r of [...a]) {
105
- try {
106
- r.fn(e, t);
107
- } catch (t) {
108
- o ??= { value: t }, d({
109
- error: t,
110
- event: e,
111
- type: "error"
112
- });
113
- }
114
- n++;
115
- }
116
- if (d({
117
- event: e,
118
- listeners: n,
119
- payload: t,
120
- type: "emit"
121
- }), o) throw o.value;
122
- }
123
- function C(e, ...t) {
124
- if (s.signal.aborted) return;
125
- let n = t[0];
126
- S(e, n);
127
- }
128
- function w(e) {
129
- if (e !== void 0) return i.get(e)?.size ?? 0;
130
- let t = 0;
131
- for (let e of i.values()) t += e.size;
132
- return t;
133
- }
134
- function T() {
135
- return a.size;
136
- }
137
- function E() {
138
- return [...i.keys()];
139
- }
140
- function D(e, t) {
141
- if (s.signal.aborted) return n;
142
- let r = f(t?.signal);
143
- if (r.aborted) return n;
144
- o.add(e);
145
- let i = () => o.delete(e);
146
- return r.addEventListener("abort", i, { once: !0 }), () => {
147
- o.delete(e), r.removeEventListener("abort", i);
148
- };
149
- }
150
- function O(e, n) {
151
- if (e.length < 2) throw new t("waitAny() requires at least 2 event keys");
152
- let r = f(n?.signal);
153
- return r.aborted ? Promise.reject(r.reason) : new Promise((t, n) => {
154
- let i = new AbortController(), a = AbortSignal.any([r, i.signal]), o = [], s = !1;
155
- function c() {
156
- r.removeEventListener("abort", l), i.abort();
157
- for (let e of o) e();
158
- }
159
- function l() {
160
- s || (s = !0, c(), n(r.reason));
161
- }
162
- r.addEventListener("abort", l, { once: !0 });
163
- for (let n of e) o.push(g(n, (e) => {
164
- s || (s = !0, c(), t({
165
- event: n,
166
- payload: e
167
- }));
168
- }, a));
169
- });
170
- }
171
- function k() {
172
- s.signal.aborted || (d({ type: "dispose" }), s.abort(new e(c)), i.clear(), a.clear(), o.clear());
173
- }
174
- return {
175
- get disposalSignal() {
176
- return s.signal;
177
- },
178
- dispose: k,
179
- get disposed() {
180
- return s.signal.aborted;
181
- },
182
- emit: C,
183
- eventNames: E,
184
- listenerCount: w,
185
- on: v,
186
- onAny: b,
187
- once: y,
188
- [Symbol.dispose]: k,
189
- tap: D,
190
- wait: x,
191
- waitAny: O,
192
- wildcardCount: T
193
- };
194
- }
195
- //#endregion
196
- export { r as createBus, n as noop };
197
-
1
+ import"./_dev.js";import{BusDisposedError as e}from"./errors.js";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(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}}export{createBus,noop};
198
2
  //# sourceMappingURL=bus.js.map
package/dist/bus.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bus.js","names":[],"sources":["../src/bus.ts"],"sourcesContent":["import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError, HeraldConfigError } 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<T>): 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 onAnyWithOnce(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onAnyWithSignal(\n (event, payload) => {\n ref.unsub();\n listener(event, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onceWithSignal(event, listener, signal);\n\n return onWithSignal(event, listener, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onAnyWithOnce(listener, signal);\n\n return onAnyWithSignal(listener, 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 options?._onDispatch?.(event, payload);\n\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>, EventKey<T>, ...EventKey<T>[]]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length < 2) throw new HeraldConfigError('waitAny() requires at least 2 event keys');\n\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":";;;AAgBA,IAAa,UAAa,CAAC;AAY3B,SAAgB,EAAwD,GAAiC;CACvG,IAAM,oBAAY,IAAI,IAAwB,GACxC,oBAAY,IAAI,IAAmB,GACnC,oBAAU,IAAI,IAAqC,GACnD,IAAoB,IAAI,gBAAgB,GACxC,IAAU,GAAS,MACnB,IAAe,GAAS,cACxB,IAAS,IAAU,KAAK,EAAQ,KAAK;CAE3C,SAAS,EAAQ,GAA6B;EACxC,MAAQ,SAAS,GACrB,KAAK,IAAM,KAAU,GACnB,IAAI;GACF,EAAO,CAAK;EACd,QAAQ,CAER;CAEJ;CAMA,SAAS,EAAwB,GAAmC;EAClE,OAAO,IAAS,YAAY,IAAI,CAAC,EAAkB,QAAQ,CAAM,CAAC,IAAI,EAAkB;CAC1F;CAEA,SAAS,EACP,GACA,GACA,GACA,EAAE,UAAO,UAAO,aAAU,eACd;EACZ,IAAI,EAAO,SAAS,OAAO;EAE3B,IAAI,IAAS;EAEb,SAAS,IAAQ;GACX,MAEJ,IAAS,IACT,EAAU,OAAO,CAAK,GACtB,IAAW,GACX,EAAO,oBAAoB,SAAS,CAAK,GAErC,MAAU,KAAA,IACL,KAAU,EAAQ,EAAE,MAAM,kBAAkB,CAAC,IAD7B,EAAQ;IAAE;IAAO,MAAM;GAAc,CAAC;EAEjE;EAEA,IAAM,IAAQ,EAAU,CAAK;EAc7B,OAZA,EAAU,IAAI,CAAK,GACnB,EAAO,iBAAiB,SAAS,GAAO,EAAE,MAAM,GAAK,CAAC,GAElD,MAAU,KAAA,IACL,KAAU,EAAQ,EAAE,MAAM,gBAAgB,CAAC,IAD3B,EAAQ;GAAE;GAAO,MAAM;EAAY,CAAC,GAGzD,MAAiB,KAAA,KAAa,EAAU,OAAO,KAE/C,GAAG,EAAH,EAAgB,EAAU,KAA1B,EAAqE,EAArE,EAA4G,EAA5G,GAIG;CACT;CAEA,SAAS,EACP,GACA,GACA,GACA,GACY;EACZ,IAAI,IAAM,EAAU,IAAI,CAAK;EAE7B,AAAK,MACH,oBAAM,IAAI,IAAI,GACd,EAAU,IAAI,GAAO,CAAG;EAG1B,IAAM,IAAc;EAEpB,OAAO,EAAc,IAAc,OAAW;GAAE,IAAI;GAA+B;EAAM,IAAI,GAAQ;GACnG;GACA,OAAO,OAAO,EAAM;GACpB,gBAAgB;IAGd,AAFI,EAAY,SAAS,KAAG,EAAU,OAAO,CAAK,GAElD,IAAW;GACb;EACF,CAAC;CACH;CAEA,SAAS,EACP,GACA,GACA,GACY;EACZ,OAAO,EACL,IACC,OAAW;GAAE,IAAI;GAAuD;EAAM,IAC/E,GACA;GAAE,OAAO;GAAS;GAAU,UAAU;EAAK,CAC7C;CACF;CAEA,SAAS,EACP,GACA,GACA,GACA,GACY;EACZ,IAAM,IAAM,EAAE,OAAO,EAAoB;EAYzC,OAVA,EAAI,QAAQ,EACV,IACC,MAAY;GAEX,AADA,EAAI,MAAM,GACV,EAAS,CAAO;EAClB,GACA,GACA,CACF,GAEO,EAAI;CACb;CAEA,SAAS,EACP,GACA,GACA,GACY;EACZ,IAAM,IAAM,EAAE,OAAO,EAAoB;EAWzC,OATA,EAAI,QAAQ,GACT,GAAO,MAAY;GAElB,AADA,EAAI,MAAM,GACV,EAAS,GAAO,CAAO;EACzB,GACA,GACA,CACF,GAEO,EAAI;CACb;CAEA,SAAS,EAA0B,GAAU,GAA0B,GAAqC;EAC1G,IAAM,IAAS,EAAwB,GAAM,MAAM;EAInD,OAFI,GAAM,OAAa,EAAe,GAAO,GAAU,CAAM,IAEtD,EAAa,GAAO,GAAU,CAAM;CAC7C;CAEA,SAAS,EACP,GACA,GACA,GACY;EAGZ,OAAO,EAAe,GAAO,GAFd,EAAwB,GAAM,MAEN,CAAM;CAC/C;CAEA,SAAS,EAAM,GAA0D,GAAqC;EAC5G,IAAM,IAAS,EAAwB,GAAM,MAAM;EAInD,OAFI,GAAM,OAAa,EAAc,GAAU,CAAM,IAE9C,EAAgB,GAAU,CAAM;CACzC;CAEA,SAAS,EAA4B,GAAU,GAAgD;EAC7F,IAAM,IAAS,EAAwB,GAAM,MAAM;EAInD,OAFI,EAAO,UAAgB,QAAQ,OAAO,EAAO,MAAM,IAEhD,IAAI,SAAe,GAAS,MAAW;GAC5C,IAAM,UAAgB;IACpB,EAAO,EAAO,MAAM;GACtB;GAWA,AATA,EACE,IACC,MAAY;IAEX,AADA,EAAO,oBAAoB,SAAS,CAAO,GAC3C,EAAQ,CAAO;GACjB,GACA,CACF,GAEA,EAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC;EAC1D,CAAC;CACH;CAEA,SAAS,EAAS,GAAoB,GAAwB;EAC5D,GAAS,cAAc,GAAO,CAAO;EAErC,IAAI,IAAQ,GACR,GACE,IAAM,EAAU,IAAI,CAAK;EAE/B,IAAI,GAAK,MACP,KAAK,IAAM,KAAS,CAAC,GAAG,CAAG,GAAG;GAC5B,IAAI;IACF,EAAM,GAAG,CAAO;GAClB,SAAS,GAAK;IAEZ,AADA,MAAe,EAAE,OAAO,EAAI,GAC5B,EAAQ;KAAE,OAAO;KAAK;KAAO,MAAM;IAAQ,CAAC;GAC9C;GAEA;EACF;EAGF,IAAI,EAAU,MACZ,KAAK,IAAM,KAAS,CAAC,GAAG,CAAS,GAAG;GAClC,IAAI;IACF,EAAM,GAAG,GAAO,CAAO;GACzB,SAAS,GAAK;IAEZ,AADA,MAAe,EAAE,OAAO,EAAI,GAC5B,EAAQ;KAAE,OAAO;KAAK;KAAO,MAAM;IAAQ,CAAC;GAC9C;GAEA;EACF;EAKF,IAFA,EAAQ;GAAE;GAAO,WAAW;GAAO;GAAS,MAAM;EAAO,CAAC,GAEtD,GAAY,MAAM,EAAW;CACnC;CAEA,SAAS,EAA4B,GAAU,GAAG,GAAsD;EACtG,IAAI,EAAkB,OAAO,SAAS;EAEtC,IAAM,IAAW,EAAmB;EAEpC,EAAS,GAAO,CAAO;CACzB;CAEA,SAAS,EAAc,GAA6B;EAClD,IAAI,MAAU,KAAA,GAAW,OAAO,EAAU,IAAI,CAAK,CAAC,EAAE,QAAQ;EAE9D,IAAI,IAAQ;EAEZ,KAAK,IAAM,KAAO,EAAU,OAAO,GAAG,KAAS,EAAI;EAEnD,OAAO;CACT;CAEA,SAAS,IAAwB;EAC/B,OAAO,EAAU;CACnB;CAEA,SAAS,IAA4B;EACnC,OAAO,CAAC,GAAG,EAAU,KAAK,CAAC;CAC7B;CAEA,SAAS,EAAI,GAA0C,GAA6C;EAClG,IAAI,EAAkB,OAAO,SAAS,OAAO;EAE7C,IAAM,IAAS,EAAwB,GAAM,MAAM;EAEnD,IAAI,EAAO,SAAS,OAAO;EAE3B,EAAQ,IAAI,CAAO;EAEnB,IAAM,UAAgB,EAAQ,OAAO,CAAO;EAI5C,OAFA,EAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,SAE3C;GAEX,AADA,EAAQ,OAAO,CAAO,GACtB,EAAO,oBAAoB,SAAS,CAAO;EAC7C;CACF;CAEA,SAAS,EACP,GACA,GAC8B;EAC9B,IAAI,EAAU,SAAS,GAAG,MAAM,IAAI,EAAkB,0CAA0C;EAEhG,IAAM,IAAe,EAAwB,GAAM,MAAM;EAIzD,OAFI,EAAa,UAAgB,QAAQ,OAAO,EAAa,MAAM,IAE5D,IAAI,SAA8B,GAAS,MAAW;GAC3D,IAAM,IAAiB,IAAI,gBAAgB,GACrC,IAAa,YAAY,IAAI,CAAC,GAAc,EAAe,MAAM,CAAC,GAClE,IAAwB,CAAC,GAC3B,IAAU;GAEd,SAAS,IAAgB;IAEvB,AADA,EAAa,oBAAoB,SAAS,CAAO,GACjD,EAAe,MAAM;IACrB,KAAK,IAAM,KAAS,GAAQ,EAAM;GACpC;GAEA,SAAS,IAAgB;IACnB,MAEJ,IAAU,IACV,EAAQ,GACR,EAAO,EAAa,MAAM;GAC5B;GAEA,EAAa,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC;GAE9D,KAAK,IAAM,KAAS,GAClB,EAAO,KACL,EACE,IACC,MAAY;IACP,MAEJ,IAAU,IACV,EAAQ,GACR,EAAQ;KAAE;KAAO;IAAQ,CAAwB;GACnD,GACA,CACF,CACF;EAEJ,CAAC;CACH;CAEA,SAAS,IAAgB;EACnB,EAAkB,OAAO,YAE7B,EAAQ,EAAE,MAAM,UAAU,CAAC,GAC3B,EAAkB,MAAM,IAAI,EAAiB,CAAO,CAAC,GACrD,EAAU,MAAM,GAChB,EAAU,MAAM,GAChB,EAAQ,MAAM;CAChB;CAEA,OAAO;EACL,IAAI,iBAAiB;GACnB,OAAO,EAAkB;EAC3B;EACA;EACA,IAAI,WAAW;GACb,OAAO,EAAkB,OAAO;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;GACC,OAAO,UAAU;EAClB;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"bus.js","names":[],"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":"iEAgBA,IAAa,SAAa,CAAC,EAY3B,SAAgB,UAAwD,EAA8B,CACpG,IAAM,EAAY,IAAI,IAChB,EAAY,IAAI,IAChB,EAAU,IAAI,IACd,EAAoB,IAAI,gBACxB,EAAU,GAAS,KACnB,EAAe,GAAS,aACxB,EAAS,EAAU,KAAK,EAAQ,GAAK,GAE3C,SAAS,QAAQ,EAA6B,CACxC,KAAQ,OAAS,EACrB,IAAK,IAAM,KAAU,EACnB,GAAI,CACF,EAAO,CAAK,CACd,MAAQ,CAER,CAEJ,CAMA,SAAS,wBAAwB,EAAmC,CAClE,OAAO,EAAS,YAAY,IAAI,CAAC,EAAkB,OAAQ,CAAM,CAAC,EAAI,EAAkB,MAC1F,CAEA,SAAS,cACP,EACA,EACA,EACA,CAAE,QAAO,QAAO,WAAU,YACd,CACZ,GAAI,EAAO,QAAS,OAAO,KAE3B,IAAI,EAAS,GAEb,SAAS,OAAQ,CACX,IAEJ,EAAS,GACT,EAAU,OAAO,CAAK,EACtB,IAAW,EACX,EAAO,oBAAoB,QAAS,KAAK,EAErC,IAAU,IAAA,GACL,GAAU,QAAQ,CAAE,KAAM,iBAAkB,CAAC,EAD7B,QAAQ,CAAE,QAAO,KAAM,aAAc,CAAC,EAEjE,CAEA,IAAM,EAAQ,EAAU,KAAK,EAc7B,OAZA,EAAU,IAAI,CAAK,EACnB,EAAO,iBAAiB,QAAS,MAAO,CAAE,KAAM,EAAK,CAAC,EAElD,IAAU,IAAA,GACL,GAAU,QAAQ,CAAE,KAAM,eAAgB,CAAC,EAD3B,QAAQ,CAAE,QAAO,KAAM,WAAY,CAAC,EAGzD,IAAiB,IAAA,IAAa,EAAU,KAAO,GAE/C,GAAG,EAAH,EAAgB,EAAU,KAA1B,EAAqE,EAArE,EAA4G,EAA5G,EAIG,KACT,CAEA,SAAS,aACP,EACA,EACA,EACA,EACY,CACZ,IAAI,EAAM,EAAU,IAAI,CAAK,EAExB,IACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,GAG1B,IAAM,EAAc,EAEpB,OAAO,cAAc,EAAc,IAAW,CAAE,GAAI,EAA+B,OAAM,GAAI,EAAQ,CACnG,QACA,MAAO,OAAO,EAAM,IACpB,aAAgB,CACV,EAAY,OAAS,GAAG,EAAU,OAAO,CAAK,EAElD,IAAW,CACb,CACF,CAAC,CACH,CAEA,SAAS,gBACP,EACA,EACA,EACY,CACZ,OAAO,cACL,EACC,IAAW,CAAE,GAAI,EAAuD,OAAM,GAC/E,EACA,CAAE,MAAO,QAAS,WAAU,SAAU,EAAK,CAC7C,CACF,CAEA,SAAS,eACP,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAM,CAAE,MAAO,IAAoB,EAYzC,MAVA,GAAI,MAAQ,aACV,EACC,GAAY,CACX,EAAI,MAAM,EACV,EAAS,CAAO,CAClB,EACA,EACA,CACF,EAEO,EAAI,KACb,CAEA,SAAS,GAA0B,EAAU,EAA0B,EAAqC,CAC1G,OAAO,aAAa,EAAO,EAAU,wBAAwB,GAAM,MAAM,CAAC,CAC5E,CAEA,SAAS,KACP,EACA,EACA,EACY,CAGZ,OAAO,eAAe,EAAO,EAFd,wBAAwB,GAAM,MAEN,CAAM,CAC/C,CAEA,SAAS,MAAM,EAA0D,EAAqC,CAC5G,OAAO,gBAAgB,EAAU,wBAAwB,GAAM,MAAM,CAAC,CACxE,CAEA,SAAS,KAA4B,EAAU,EAAgD,CAC7F,IAAM,EAAS,wBAAwB,GAAM,MAAM,EAInD,OAFI,EAAO,QAAgB,QAAQ,OAAO,EAAO,MAAM,EAEhD,IAAI,SAAe,EAAS,IAAW,CAC5C,IAAM,YAAgB,CACpB,EAAO,EAAO,MAAM,CACtB,EAEA,eACE,EACC,GAAY,CACX,EAAO,oBAAoB,QAAS,OAAO,EAC3C,EAAQ,CAAO,CACjB,EACA,CACF,EAEA,EAAO,iBAAiB,QAAS,QAAS,CAAE,KAAM,EAAK,CAAC,CAC1D,CAAC,CACH,CAEA,SAAS,SAAS,EAAoB,EAAwB,CAC5D,IAAI,EAAQ,EACR,EACE,EAAM,EAAU,IAAI,CAAK,EAE/B,GAAI,GAAK,KACP,IAAK,IAAM,IAAS,CAAC,GAAG,CAAG,EAAG,CAC5B,GAAI,CACF,EAAM,GAAG,CAAO,CAClB,OAAS,EAAK,CACZ,IAAe,CAAE,MAAO,CAAI,EAC5B,QAAQ,CAAE,MAAO,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAGF,GAAI,EAAU,KACZ,IAAK,IAAM,IAAS,CAAC,GAAG,CAAS,EAAG,CAClC,GAAI,CACF,EAAM,GAAG,EAAO,CAAO,CACzB,OAAS,EAAK,CACZ,IAAe,CAAE,MAAO,CAAI,EAC5B,QAAQ,CAAE,MAAO,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAKF,GAFA,QAAQ,CAAE,QAAO,UAAW,EAAO,UAAS,KAAM,MAAO,CAAC,EAEtD,EAAY,MAAM,EAAW,KACnC,CAEA,SAAS,KAA4B,EAAU,GAAG,EAAsD,CACtG,GAAI,EAAkB,OAAO,QAAS,OAEtC,IAAM,EAAW,EAAmB,GAEpC,SAAS,EAAO,CAAO,CACzB,CAEA,SAAS,cAAc,EAA6B,CAClD,GAAI,IAAU,IAAA,GAAW,OAAO,EAAU,IAAI,CAAK,CAAC,EAAE,MAAQ,EAE9D,IAAI,EAAQ,EAEZ,IAAK,IAAM,KAAO,EAAU,OAAO,EAAG,GAAS,EAAI,KAEnD,OAAO,CACT,CAEA,SAAS,eAAwB,CAC/B,OAAO,EAAU,IACnB,CAEA,SAAS,YAA4B,CACnC,MAAO,CAAC,GAAG,EAAU,KAAK,CAAC,CAC7B,CAEA,SAAS,IAAI,EAA0C,EAA6C,CAClG,GAAI,EAAkB,OAAO,QAAS,OAAO,KAE7C,IAAM,EAAS,wBAAwB,GAAM,MAAM,EAEnD,GAAI,EAAO,QAAS,OAAO,KAE3B,EAAQ,IAAI,CAAO,EAEnB,IAAM,YAAgB,EAAQ,OAAO,CAAO,EAI5C,OAFA,EAAO,iBAAiB,QAAS,QAAS,CAAE,KAAM,EAAK,CAAC,MAE3C,CACX,EAAQ,OAAO,CAAO,EACtB,EAAO,oBAAoB,QAAS,OAAO,CAC7C,CACF,CAEA,SAAS,QACP,EACA,EAC8B,CAC9B,IAAM,EAAe,wBAAwB,GAAM,MAAM,EAIzD,OAFI,EAAa,QAAgB,QAAQ,OAAO,EAAa,MAAM,EAE5D,IAAI,SAA8B,EAAS,IAAW,CAC3D,IAAM,EAAiB,IAAI,gBACrB,EAAa,YAAY,IAAI,CAAC,EAAc,EAAe,MAAM,CAAC,EAClE,EAAwB,CAAC,EAC3B,EAAU,GAEd,SAAS,SAAgB,CACvB,EAAa,oBAAoB,QAAS,OAAO,EACjD,EAAe,MAAM,EACrB,IAAK,IAAM,KAAS,EAAQ,EAAM,CACpC,CAEA,SAAS,SAAgB,CACnB,IAEJ,EAAU,GACV,QAAQ,EACR,EAAO,EAAa,MAAM,EAC5B,CAEA,EAAa,iBAAiB,QAAS,QAAS,CAAE,KAAM,EAAK,CAAC,EAE9D,IAAK,IAAM,KAAS,EAClB,EAAO,KACL,eACE,EACC,GAAY,CACP,IAEJ,EAAU,GACV,QAAQ,EACR,EAAQ,CAAE,QAAO,SAAQ,CAAwB,EACnD,EACA,CACF,CACF,CAEJ,CAAC,CACH,CAEA,SAAS,SAAgB,CACnB,EAAkB,OAAO,UAE7B,QAAQ,CAAE,KAAM,SAAU,CAAC,EAC3B,EAAkB,MAAM,IAAI,EAAiB,CAAO,CAAC,EACrD,EAAU,MAAM,EAChB,EAAU,MAAM,EAChB,EAAQ,MAAM,EAChB,CAEA,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAkB,MAC3B,EACA,QACA,IAAI,UAAW,CACb,OAAO,EAAkB,OAAO,OAClC,EACA,KACA,WACA,cACA,GACA,MACA,MACC,OAAO,SAAU,QAClB,IACA,KACA,QACA,aACF,CACF"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},n=class extends e{};exports.BusDisposedError=t,exports.HeraldConfigError=n,exports.HeraldError=e;
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;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"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\n/** Thrown when a herald API is called with invalid arguments or configuration. */\nexport class HeraldConfigError extends HeraldError {}\n"],"mappings":"AACA,IAAa,EAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAAsC,CAAY,CAChD,YAAY,EAAkB,CAC5B,MAAM,EAAU,QAAQ,EAAQ,eAAiB,iBAAiB,CACpE,CACF,EAGa,EAAb,cAAuC,CAAY,CAAC"}
1
+ {"version":3,"file":"errors.cjs","names":[],"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,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,iBAAb,cAAsC,WAAY,CAChD,YAAY,EAAkB,CAC5B,MAAM,EAAU,QAAQ,EAAQ,eAAiB,iBAAiB,CACpE,CACF"}
package/dist/errors.d.ts CHANGED
@@ -6,7 +6,4 @@ export declare class HeraldError extends Error {
6
6
  export declare class BusDisposedError extends HeraldError {
7
7
  constructor(busName?: string);
8
8
  }
9
- /** Thrown when a herald API is called with invalid arguments or configuration. */
10
- export declare class HeraldConfigError extends HeraldError {
11
- }
12
9
  //# sourceMappingURL=errors.d.ts.map
@@ -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;AAED,kFAAkF;AAClF,qBAAa,iBAAkB,SAAQ,WAAW;CAAG"}
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"}
package/dist/errors.js CHANGED
@@ -1,14 +1,2 @@
1
- //#region src/errors.ts
2
- var e = class extends Error {
3
- constructor(e, t) {
4
- super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
- }
6
- }, t = class extends e {
7
- constructor(e) {
8
- super(e ? `Bus "${e}" is disposed` : "Bus is disposed");
9
- }
10
- }, n = class extends e {};
11
- //#endregion
12
- export { t as BusDisposedError, n as HeraldConfigError, e as HeraldError };
13
-
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`)}};export{BusDisposedError,HeraldError};
14
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"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\n/** Thrown when a herald API is called with invalid arguments or configuration. */\nexport class HeraldConfigError extends HeraldError {}\n"],"mappings":";AACA,IAAa,IAAb,cAAiC,MAAM;CACrC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,IAAb,cAAsC,EAAY;CAChD,YAAY,GAAkB;EAC5B,MAAM,IAAU,QAAQ,EAAQ,iBAAiB,iBAAiB;CACpE;AACF,GAGa,IAAb,cAAuC,EAAY,CAAC"}
1
+ {"version":3,"file":"errors.js","names":[],"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,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,iBAAb,cAAsC,WAAY,CAChD,YAAY,EAAkB,CAC5B,MAAM,EAAU,QAAQ,EAAQ,eAAiB,iBAAiB,CACpE,CACF"}
package/dist/herald.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},n=class extends e{},r=()=>{};function i(e){let i=new Map,a=new Set,o=new Set,s=new AbortController,c=e?.name,l=e?.maxListeners,u=c?` (${c})`:``;function d(e){if(o.size!==0)for(let t of o)try{t(e)}catch{}}function f(e){return e?AbortSignal.any([s.signal,e]):s.signal}function p(e,t,n,{event:i,onLog:a,onRemove:o,wildcard:s}){if(n.aborted)return r;let c=!1;function f(){c||(c=!0,e.delete(p),o?.(),n.removeEventListener(`abort`,f),i===void 0?s&&d({type:`unsubscribe-any`}):d({event:i,type:`unsubscribe`}))}let p=t(f);return e.add(p),n.addEventListener(`abort`,f,{once:!0}),i===void 0?s&&d({type:`subscribe-any`}):d({event:i,type:`subscribe`}),l!==void 0&&e.size>l&&`${a}${e.size}${l}${u}`,f}function m(e,t,n,r){let a=i.get(e);a||(a=new Set,i.set(e,a));let o=a;return p(o,e=>({fn:t,unsub:e}),n,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&i.delete(e),r?.()}})}function h(e,t,n){return p(a,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:n,wildcard:!0})}function g(e,t,n,i){let a={unsub:r};return a.unsub=m(e,e=>{a.unsub(),t(e)},n,i),a.unsub}function _(e,t,n){let i={unsub:r};return i.unsub=h((t,n)=>{i.unsub(),e(t,n)},t,n),i.unsub}function v(e,t,n){let r=f(n?.signal);return n?.once?g(e,t,r):m(e,t,r)}function y(e,t,n){return g(e,t,f(n?.signal))}function b(e,t){let n=f(t?.signal);return t?.once?_(e,n):h(e,n)}function x(e,t){let n=f(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=()=>{r(n.reason)};g(e,e=>{n.removeEventListener(`abort`,i),t(e)},n),n.addEventListener(`abort`,i,{once:!0})})}function S(t,n){e?._onDispatch?.(t,n);let r=0,o,s=i.get(t);if(s?.size)for(let e of[...s]){try{e.fn(n)}catch(e){o??={value:e},d({error:e,event:t,type:`error`})}r++}if(a.size)for(let e of[...a]){try{e.fn(t,n)}catch(e){o??={value:e},d({error:e,event:t,type:`error`})}r++}if(d({event:t,listeners:r,payload:n,type:`emit`}),o)throw o.value}function C(e,...t){if(s.signal.aborted)return;let n=t[0];S(e,n)}function w(e){if(e!==void 0)return i.get(e)?.size??0;let t=0;for(let e of i.values())t+=e.size;return t}function T(){return a.size}function E(){return[...i.keys()]}function D(e,t){if(s.signal.aborted)return r;let n=f(t?.signal);if(n.aborted)return r;o.add(e);let i=()=>o.delete(e);return n.addEventListener(`abort`,i,{once:!0}),()=>{o.delete(e),n.removeEventListener(`abort`,i)}}function O(e,t){if(e.length<2)throw new n(`waitAny() requires at least 2 event keys`);let r=f(t?.signal);return r.aborted?Promise.reject(r.reason):new Promise((t,n)=>{let i=new AbortController,a=AbortSignal.any([r,i.signal]),o=[],s=!1;function c(){r.removeEventListener(`abort`,l),i.abort();for(let e of o)e()}function l(){s||(s=!0,c(),n(r.reason))}r.addEventListener(`abort`,l,{once:!0});for(let n of e)o.push(g(n,e=>{s||(s=!0,c(),t({event:n,payload:e}))},a))})}function k(){s.signal.aborted||(d({type:`dispose`}),s.abort(new t(c)),i.clear(),a.clear(),o.clear())}return{get disposalSignal(){return s.signal},dispose:k,get disposed(){return s.signal.aborted},emit:C,eventNames:E,listenerCount:w,on:v,onAny:b,once:y,[Symbol.dispose]:k,tap:D,wait:x,waitAny:O,wildcardCount:T}}exports.BusDisposedError=t,exports.HeraldConfigError=n,exports.HeraldError=e,exports.createBus=i;
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;
2
2
  //# sourceMappingURL=herald.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"herald.cjs","names":[],"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\n/** Thrown when a herald API is called with invalid arguments or configuration. */\nexport class HeraldConfigError extends HeraldError {}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError, HeraldConfigError } 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<T>): 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 onAnyWithOnce(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onAnyWithSignal(\n (event, payload) => {\n ref.unsub();\n listener(event, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onceWithSignal(event, listener, signal);\n\n return onWithSignal(event, listener, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onAnyWithOnce(listener, signal);\n\n return onAnyWithSignal(listener, 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 options?._onDispatch?.(event, payload);\n\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>, EventKey<T>, ...EventKey<T>[]]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length < 2) throw new HeraldConfigError('waitAny() requires at least 2 event keys');\n\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":"mECCA,IAAa,EAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAAsC,CAAY,CAChD,YAAY,EAAkB,CAC5B,MAAM,EAAU,QAAQ,EAAQ,eAAiB,iBAAiB,CACpE,CACF,EAGa,EAAb,cAAuC,CAAY,CAAC,ECDvC,MAAa,CAAC,EAY3B,SAAgB,EAAwD,EAAiC,CACvG,IAAM,EAAY,IAAI,IAChB,EAAY,IAAI,IAChB,EAAU,IAAI,IACd,EAAoB,IAAI,gBACxB,EAAU,GAAS,KACnB,EAAe,GAAS,aACxB,EAAS,EAAU,KAAK,EAAQ,GAAK,GAE3C,SAAS,EAAQ,EAA6B,CACxC,KAAQ,OAAS,EACrB,IAAK,IAAM,KAAU,EACnB,GAAI,CACF,EAAO,CAAK,CACd,MAAQ,CAER,CAEJ,CAMA,SAAS,EAAwB,EAAmC,CAClE,OAAO,EAAS,YAAY,IAAI,CAAC,EAAkB,OAAQ,CAAM,CAAC,EAAI,EAAkB,MAC1F,CAEA,SAAS,EACP,EACA,EACA,EACA,CAAE,QAAO,QAAO,WAAU,YACd,CACZ,GAAI,EAAO,QAAS,OAAO,EAE3B,IAAI,EAAS,GAEb,SAAS,GAAQ,CACX,IAEJ,EAAS,GACT,EAAU,OAAO,CAAK,EACtB,IAAW,EACX,EAAO,oBAAoB,QAAS,CAAK,EAErC,IAAU,IAAA,GACL,GAAU,EAAQ,CAAE,KAAM,iBAAkB,CAAC,EAD7B,EAAQ,CAAE,QAAO,KAAM,aAAc,CAAC,EAEjE,CAEA,IAAM,EAAQ,EAAU,CAAK,EAc7B,OAZA,EAAU,IAAI,CAAK,EACnB,EAAO,iBAAiB,QAAS,EAAO,CAAE,KAAM,EAAK,CAAC,EAElD,IAAU,IAAA,GACL,GAAU,EAAQ,CAAE,KAAM,eAAgB,CAAC,EAD3B,EAAQ,CAAE,QAAO,KAAM,WAAY,CAAC,EAGzD,IAAiB,IAAA,IAAa,EAAU,KAAO,GAE/C,GAAG,EAAH,EAAgB,EAAU,KAA1B,EAAqE,EAArE,EAA4G,EAA5G,EAIG,CACT,CAEA,SAAS,EACP,EACA,EACA,EACA,EACY,CACZ,IAAI,EAAM,EAAU,IAAI,CAAK,EAExB,IACH,EAAM,IAAI,IACV,EAAU,IAAI,EAAO,CAAG,GAG1B,IAAM,EAAc,EAEpB,OAAO,EAAc,EAAc,IAAW,CAAE,GAAI,EAA+B,OAAM,GAAI,EAAQ,CACnG,QACA,MAAO,OAAO,EAAM,IACpB,aAAgB,CACV,EAAY,OAAS,GAAG,EAAU,OAAO,CAAK,EAElD,IAAW,CACb,CACF,CAAC,CACH,CAEA,SAAS,EACP,EACA,EACA,EACY,CACZ,OAAO,EACL,EACC,IAAW,CAAE,GAAI,EAAuD,OAAM,GAC/E,EACA,CAAE,MAAO,QAAS,WAAU,SAAU,EAAK,CAC7C,CACF,CAEA,SAAS,EACP,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAM,CAAE,MAAO,CAAoB,EAYzC,MAVA,GAAI,MAAQ,EACV,EACC,GAAY,CACX,EAAI,MAAM,EACV,EAAS,CAAO,CAClB,EACA,EACA,CACF,EAEO,EAAI,KACb,CAEA,SAAS,EACP,EACA,EACA,EACY,CACZ,IAAM,EAAM,CAAE,MAAO,CAAoB,EAWzC,MATA,GAAI,MAAQ,GACT,EAAO,IAAY,CAClB,EAAI,MAAM,EACV,EAAS,EAAO,CAAO,CACzB,EACA,EACA,CACF,EAEO,EAAI,KACb,CAEA,SAAS,EAA0B,EAAU,EAA0B,EAAqC,CAC1G,IAAM,EAAS,EAAwB,GAAM,MAAM,EAInD,OAFI,GAAM,KAAa,EAAe,EAAO,EAAU,CAAM,EAEtD,EAAa,EAAO,EAAU,CAAM,CAC7C,CAEA,SAAS,EACP,EACA,EACA,EACY,CAGZ,OAAO,EAAe,EAAO,EAFd,EAAwB,GAAM,MAEN,CAAM,CAC/C,CAEA,SAAS,EAAM,EAA0D,EAAqC,CAC5G,IAAM,EAAS,EAAwB,GAAM,MAAM,EAInD,OAFI,GAAM,KAAa,EAAc,EAAU,CAAM,EAE9C,EAAgB,EAAU,CAAM,CACzC,CAEA,SAAS,EAA4B,EAAU,EAAgD,CAC7F,IAAM,EAAS,EAAwB,GAAM,MAAM,EAInD,OAFI,EAAO,QAAgB,QAAQ,OAAO,EAAO,MAAM,EAEhD,IAAI,SAAe,EAAS,IAAW,CAC5C,IAAM,MAAgB,CACpB,EAAO,EAAO,MAAM,CACtB,EAEA,EACE,EACC,GAAY,CACX,EAAO,oBAAoB,QAAS,CAAO,EAC3C,EAAQ,CAAO,CACjB,EACA,CACF,EAEA,EAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,CAC1D,CAAC,CACH,CAEA,SAAS,EAAS,EAAoB,EAAwB,CAC5D,GAAS,cAAc,EAAO,CAAO,EAErC,IAAI,EAAQ,EACR,EACE,EAAM,EAAU,IAAI,CAAK,EAE/B,GAAI,GAAK,KACP,IAAK,IAAM,IAAS,CAAC,GAAG,CAAG,EAAG,CAC5B,GAAI,CACF,EAAM,GAAG,CAAO,CAClB,OAAS,EAAK,CACZ,IAAe,CAAE,MAAO,CAAI,EAC5B,EAAQ,CAAE,MAAO,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAGF,GAAI,EAAU,KACZ,IAAK,IAAM,IAAS,CAAC,GAAG,CAAS,EAAG,CAClC,GAAI,CACF,EAAM,GAAG,EAAO,CAAO,CACzB,OAAS,EAAK,CACZ,IAAe,CAAE,MAAO,CAAI,EAC5B,EAAQ,CAAE,MAAO,EAAK,QAAO,KAAM,OAAQ,CAAC,CAC9C,CAEA,GACF,CAKF,GAFA,EAAQ,CAAE,QAAO,UAAW,EAAO,UAAS,KAAM,MAAO,CAAC,EAEtD,EAAY,MAAM,EAAW,KACnC,CAEA,SAAS,EAA4B,EAAU,GAAG,EAAsD,CACtG,GAAI,EAAkB,OAAO,QAAS,OAEtC,IAAM,EAAW,EAAmB,GAEpC,EAAS,EAAO,CAAO,CACzB,CAEA,SAAS,EAAc,EAA6B,CAClD,GAAI,IAAU,IAAA,GAAW,OAAO,EAAU,IAAI,CAAK,CAAC,EAAE,MAAQ,EAE9D,IAAI,EAAQ,EAEZ,IAAK,IAAM,KAAO,EAAU,OAAO,EAAG,GAAS,EAAI,KAEnD,OAAO,CACT,CAEA,SAAS,GAAwB,CAC/B,OAAO,EAAU,IACnB,CAEA,SAAS,GAA4B,CACnC,MAAO,CAAC,GAAG,EAAU,KAAK,CAAC,CAC7B,CAEA,SAAS,EAAI,EAA0C,EAA6C,CAClG,GAAI,EAAkB,OAAO,QAAS,OAAO,EAE7C,IAAM,EAAS,EAAwB,GAAM,MAAM,EAEnD,GAAI,EAAO,QAAS,OAAO,EAE3B,EAAQ,IAAI,CAAO,EAEnB,IAAM,MAAgB,EAAQ,OAAO,CAAO,EAI5C,OAFA,EAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,MAE3C,CACX,EAAQ,OAAO,CAAO,EACtB,EAAO,oBAAoB,QAAS,CAAO,CAC7C,CACF,CAEA,SAAS,EACP,EACA,EAC8B,CAC9B,GAAI,EAAU,OAAS,EAAG,MAAM,IAAI,EAAkB,0CAA0C,EAEhG,IAAM,EAAe,EAAwB,GAAM,MAAM,EAIzD,OAFI,EAAa,QAAgB,QAAQ,OAAO,EAAa,MAAM,EAE5D,IAAI,SAA8B,EAAS,IAAW,CAC3D,IAAM,EAAiB,IAAI,gBACrB,EAAa,YAAY,IAAI,CAAC,EAAc,EAAe,MAAM,CAAC,EAClE,EAAwB,CAAC,EAC3B,EAAU,GAEd,SAAS,GAAgB,CACvB,EAAa,oBAAoB,QAAS,CAAO,EACjD,EAAe,MAAM,EACrB,IAAK,IAAM,KAAS,EAAQ,EAAM,CACpC,CAEA,SAAS,GAAgB,CACnB,IAEJ,EAAU,GACV,EAAQ,EACR,EAAO,EAAa,MAAM,EAC5B,CAEA,EAAa,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAE9D,IAAK,IAAM,KAAS,EAClB,EAAO,KACL,EACE,EACC,GAAY,CACP,IAEJ,EAAU,GACV,EAAQ,EACR,EAAQ,CAAE,QAAO,SAAQ,CAAwB,EACnD,EACA,CACF,CACF,CAEJ,CAAC,CACH,CAEA,SAAS,GAAgB,CACnB,EAAkB,OAAO,UAE7B,EAAQ,CAAE,KAAM,SAAU,CAAC,EAC3B,EAAkB,MAAM,IAAI,EAAiB,CAAO,CAAC,EACrD,EAAU,MAAM,EAChB,EAAU,MAAM,EAChB,EAAQ,MAAM,EAChB,CAEA,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAkB,MAC3B,EACA,UACA,IAAI,UAAW,CACb,OAAO,EAAkB,OAAO,OAClC,EACA,OACA,aACA,gBACA,KACA,QACA,QACC,OAAO,SAAU,EAClB,MACA,OACA,UACA,eACF,CACF"}
1
+ {"version":3,"file":"herald.cjs","names":[],"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,2 +1,2 @@
1
- var Herald=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},r=class extends t{},i=()=>{};function a(e){let t=new Map,a=new Set,o=new Set,s=new AbortController,c=e?.name,l=e?.maxListeners,u=c?` (${c})`:``;function d(e){if(o.size!==0)for(let t of o)try{t(e)}catch{}}function f(e){return e?AbortSignal.any([s.signal,e]):s.signal}function p(e,t,n,{event:r,onLog:a,onRemove:o,wildcard:s}){if(n.aborted)return i;let c=!1;function f(){c||(c=!0,e.delete(p),o?.(),n.removeEventListener(`abort`,f),r===void 0?s&&d({type:`unsubscribe-any`}):d({event:r,type:`unsubscribe`}))}let p=t(f);return e.add(p),n.addEventListener(`abort`,f,{once:!0}),r===void 0?s&&d({type:`subscribe-any`}):d({event:r,type:`subscribe`}),l!==void 0&&e.size>l&&`${a}${e.size}${l}${u}`,f}function m(e,n,r,i){let a=t.get(e);a||(a=new Set,t.set(e,a));let o=a;return p(o,e=>({fn:n,unsub:e}),r,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&t.delete(e),i?.()}})}function h(e,t,n){return p(a,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:n,wildcard:!0})}function g(e,t,n,r){let a={unsub:i};return a.unsub=m(e,e=>{a.unsub(),t(e)},n,r),a.unsub}function _(e,t,n){let r={unsub:i};return r.unsub=h((t,n)=>{r.unsub(),e(t,n)},t,n),r.unsub}function v(e,t,n){let r=f(n?.signal);return n?.once?g(e,t,r):m(e,t,r)}function y(e,t,n){return g(e,t,f(n?.signal))}function b(e,t){let n=f(t?.signal);return t?.once?_(e,n):h(e,n)}function x(e,t){let n=f(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=()=>{r(n.reason)};g(e,e=>{n.removeEventListener(`abort`,i),t(e)},n),n.addEventListener(`abort`,i,{once:!0})})}function S(n,r){e?._onDispatch?.(n,r);let i=0,o,s=t.get(n);if(s?.size)for(let e of[...s]){try{e.fn(r)}catch(e){o??={value:e},d({error:e,event:n,type:`error`})}i++}if(a.size)for(let e of[...a]){try{e.fn(n,r)}catch(e){o??={value:e},d({error:e,event:n,type:`error`})}i++}if(d({event:n,listeners:i,payload:r,type:`emit`}),o)throw o.value}function C(e,...t){if(s.signal.aborted)return;let n=t[0];S(e,n)}function w(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 T(){return a.size}function E(){return[...t.keys()]}function D(e,t){if(s.signal.aborted)return i;let n=f(t?.signal);if(n.aborted)return i;o.add(e);let r=()=>o.delete(e);return n.addEventListener(`abort`,r,{once:!0}),()=>{o.delete(e),n.removeEventListener(`abort`,r)}}function O(e,t){if(e.length<2)throw new r(`waitAny() requires at least 2 event keys`);let n=f(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 c(){n.removeEventListener(`abort`,l),i.abort();for(let e of o)e()}function l(){s||(s=!0,c(),r(n.reason))}n.addEventListener(`abort`,l,{once:!0});for(let n of e)o.push(g(n,e=>{s||(s=!0,c(),t({event:n,payload:e}))},a))})}function k(){s.signal.aborted||(d({type:`dispose`}),s.abort(new n(c)),t.clear(),a.clear(),o.clear())}return{get disposalSignal(){return s.signal},dispose:k,get disposed(){return s.signal.aborted},emit:C,eventNames:E,listenerCount:w,on:v,onAny:b,once:y,[Symbol.dispose]:k,tap:D,wait:x,waitAny:O,wildcardCount:T}}return e.BusDisposedError=n,e.HeraldConfigError=r,e.HeraldError=t,e.createBus=a,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,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})({});
2
2
  //# sourceMappingURL=herald.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"herald.iife.js","names":[],"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\n/** Thrown when a herald API is called with invalid arguments or configuration. */\nexport class HeraldConfigError extends HeraldError {}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError, HeraldConfigError } 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<T>): 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 onAnyWithOnce(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onAnyWithSignal(\n (event, payload) => {\n ref.unsub();\n listener(event, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onceWithSignal(event, listener, signal);\n\n return onWithSignal(event, listener, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onAnyWithOnce(listener, signal);\n\n return onAnyWithSignal(listener, 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 options?._onDispatch?.(event, payload);\n\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>, EventKey<T>, ...EventKey<T>[]]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length < 2) throw new HeraldConfigError('waitAny() requires at least 2 event keys');\n\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":[],"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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"}
package/dist/herald.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{constructor(e){super(e?`Bus "${e}" is disposed`:`Bus is disposed`)}},n=class extends e{},r=()=>{};function i(e){let i=new Map,a=new Set,o=new Set,s=new AbortController,c=e?.name,l=e?.maxListeners,u=c?` (${c})`:``;function d(e){if(o.size!==0)for(let t of o)try{t(e)}catch{}}function f(e){return e?AbortSignal.any([s.signal,e]):s.signal}function p(e,t,n,{event:i,onLog:a,onRemove:o,wildcard:s}){if(n.aborted)return r;let c=!1;function f(){c||(c=!0,e.delete(p),o?.(),n.removeEventListener(`abort`,f),i===void 0?s&&d({type:`unsubscribe-any`}):d({event:i,type:`unsubscribe`}))}let p=t(f);return e.add(p),n.addEventListener(`abort`,f,{once:!0}),i===void 0?s&&d({type:`subscribe-any`}):d({event:i,type:`subscribe`}),l!==void 0&&e.size>l&&`${a}${e.size}${l}${u}`,f}function m(e,t,n,r){let a=i.get(e);a||(a=new Set,i.set(e,a));let o=a;return p(o,e=>({fn:t,unsub:e}),n,{event:e,onLog:`on("${e}")`,onRemove:()=>{o.size===0&&i.delete(e),r?.()}})}function h(e,t,n){return p(a,t=>({fn:e,unsub:t}),t,{onLog:`onAny`,onRemove:n,wildcard:!0})}function g(e,t,n,i){let a={unsub:r};return a.unsub=m(e,e=>{a.unsub(),t(e)},n,i),a.unsub}function _(e,t,n){let i={unsub:r};return i.unsub=h((t,n)=>{i.unsub(),e(t,n)},t,n),i.unsub}function v(e,t,n){let r=f(n?.signal);return n?.once?g(e,t,r):m(e,t,r)}function y(e,t,n){return g(e,t,f(n?.signal))}function b(e,t){let n=f(t?.signal);return t?.once?_(e,n):h(e,n)}function x(e,t){let n=f(t?.signal);return n.aborted?Promise.reject(n.reason):new Promise((t,r)=>{let i=()=>{r(n.reason)};g(e,e=>{n.removeEventListener(`abort`,i),t(e)},n),n.addEventListener(`abort`,i,{once:!0})})}function S(t,n){e?._onDispatch?.(t,n);let r=0,o,s=i.get(t);if(s?.size)for(let e of[...s]){try{e.fn(n)}catch(e){o??={value:e},d({error:e,event:t,type:`error`})}r++}if(a.size)for(let e of[...a]){try{e.fn(t,n)}catch(e){o??={value:e},d({error:e,event:t,type:`error`})}r++}if(d({event:t,listeners:r,payload:n,type:`emit`}),o)throw o.value}function C(e,...t){if(s.signal.aborted)return;let n=t[0];S(e,n)}function w(e){if(e!==void 0)return i.get(e)?.size??0;let t=0;for(let e of i.values())t+=e.size;return t}function T(){return a.size}function E(){return[...i.keys()]}function D(e,t){if(s.signal.aborted)return r;let n=f(t?.signal);if(n.aborted)return r;o.add(e);let i=()=>o.delete(e);return n.addEventListener(`abort`,i,{once:!0}),()=>{o.delete(e),n.removeEventListener(`abort`,i)}}function O(e,t){if(e.length<2)throw new n(`waitAny() requires at least 2 event keys`);let r=f(t?.signal);return r.aborted?Promise.reject(r.reason):new Promise((t,n)=>{let i=new AbortController,a=AbortSignal.any([r,i.signal]),o=[],s=!1;function c(){r.removeEventListener(`abort`,l),i.abort();for(let e of o)e()}function l(){s||(s=!0,c(),n(r.reason))}r.addEventListener(`abort`,l,{once:!0});for(let n of e)o.push(g(n,e=>{s||(s=!0,c(),t({event:n,payload:e}))},a))})}function k(){s.signal.aborted||(d({type:`dispose`}),s.abort(new t(c)),i.clear(),a.clear(),o.clear())}return{get disposalSignal(){return s.signal},dispose:k,get disposed(){return s.signal.aborted},emit:C,eventNames:E,listenerCount:w,on:v,onAny:b,once:y,[Symbol.dispose]:k,tap:D,wait:x,waitAny:O,wildcardCount:T}}export{t as BusDisposedError,n as HeraldConfigError,e as HeraldError,i as createBus};
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`)}},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}}export{BusDisposedError,HeraldError,createBus};
2
2
  //# sourceMappingURL=herald.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"herald.js","names":[],"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\n/** Thrown when a herald API is called with invalid arguments or configuration. */\nexport class HeraldConfigError extends HeraldError {}\n","import { warn as _internalWarn } from './_dev';\nimport { BusDisposedError, HeraldConfigError } 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<T>): 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 onAnyWithOnce(\n listener: (event: EventKey<T>, payload: unknown) => void,\n signal: AbortSignal,\n onRemove?: () => void,\n ): () => void {\n const ref = { unsub: noop as Unsubscribe };\n\n ref.unsub = onAnyWithSignal(\n (event, payload) => {\n ref.unsub();\n listener(event, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onceWithSignal(event, listener, signal);\n\n return onWithSignal(event, listener, 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 const signal = createSubscriptionScope(opts?.signal);\n\n if (opts?.once) return onAnyWithOnce(listener, signal);\n\n return onAnyWithSignal(listener, 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 options?._onDispatch?.(event, payload);\n\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>, EventKey<T>, ...EventKey<T>[]]>(\n eventList: K,\n opts?: { signal?: AbortSignal },\n ): Promise<WaitAnyResult<T, K>> {\n if (eventList.length < 2) throw new HeraldConfigError('waitAny() requires at least 2 event keys');\n\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.js","names":[],"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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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./bus.cjs");exports.BusDisposedError=e.BusDisposedError,exports.HeraldConfigError=e.HeraldConfigError,exports.HeraldError=e.HeraldError,exports.createBus=t.createBus;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./bus.cjs");exports.BusDisposedError=e.BusDisposedError,exports.HeraldError=e.HeraldError,exports.createBus=t.createBus;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createBus } from './bus';
2
- export { BusDisposedError, HeraldConfigError, HeraldError } from './errors';
2
+ export { BusDisposedError, HeraldError } from './errors';
3
3
  export type { Bus, BusOptions, EventKey, EventMap, HeraldEvent, Listener, SubscribeOptions, Unsubscribe, WaitAnyResult, } from './types';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACzD,YAAY,EACV,GAAG,EACH,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1 @@
1
- import { BusDisposedError as e, HeraldConfigError as t, HeraldError as n } from "./errors.js";
2
- import { createBus as r } from "./bus.js";
3
- export { e as BusDisposedError, t as HeraldConfigError, n as HeraldError, r as createBus };
1
+ import{BusDisposedError as e,HeraldError as t}from"./errors.js";import{createBus as n}from"./bus.js";export{e as BusDisposedError,t as HeraldError,n as createBus};
@@ -1,2 +1,2 @@
1
- const e=require("../bus.cjs");var t=new Set([`__proto__`,`constructor`,`prototype`]);function n(n){let r=new Map,i=e.createBus({...n,_onDispatch:(e,t)=>{let n=r.get(e);n?n.push(t):r.set(e,[t])}}),a=i.dispose;function o(){let e={};for(let[n,i]of r)t.has(n)||(e[n]=[...i]);return e}function s(e){return[...r.get(e)??[]]}function c(e){return r.get(e)?.length??0}function l(){a(),r.clear()}return Object.assign(i,{allEmitted:o,dispose:l,emitted:s,emittedCount:c,reset:()=>r.clear(),[Symbol.dispose]:l})}exports.createTestBus=n;
1
+ const e=require("../bus.cjs");var t=new Set([`__proto__`,`constructor`,`prototype`]);function createTestBus(n){let r=new Map,i=e.createBus(n),a=i.dispose;i.tap(e=>{if(e.type!==`emit`)return;let t=r.get(e.event);t?t.push(e.payload):r.set(e.event,[e.payload])});function allEmitted(){let e={};for(let[n,i]of r)t.has(n)||(e[n]=[...i]);return e}function emitted(e){return[...r.get(e)??[]]}function emittedCount(e){return r.get(e)?.length??0}function dispose(){a(),r.clear()}return Object.assign(i,{allEmitted,dispose,emitted,emittedCount,reset:()=>r.clear(),[Symbol.dispose]:dispose})}exports.createTestBus=createTestBus;
2
2
  //# sourceMappingURL=testing.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.cjs","names":[],"sources":["../../src/testing/testing.ts"],"sourcesContent":["import type { Bus, BusOptions, EventKey, EventMap } from '..';\nimport { createBus } from '../bus';\n\n// Property names that must never be used as a bracket-assignment key on a plain object literal —\n// `obj[key] = value` for `key === '__proto__'` invokes `Object.prototype`'s `__proto__` accessor\n// and reassigns `obj`'s own prototype instead of setting an own property. `constructor` and\n// `prototype` are excluded defensively for the same class of risk.\n// Event names come from a caller-supplied `EventMap` type, but nothing prevents a caller from\n// wiring in a dynamically-determined (e.g. user-supplied) event name at runtime.\nconst UNSAFE_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A test bus is a regular bus with typed emission recording on top. */\nexport type TestBus<T extends EventMap> = Bus<T> & {\n /** Returns a snapshot of all payloads dispatched across every recorded event, keyed by event name. */\n allEmitted(): { [K in EventKey<T>]?: T[K][] };\n /** Snapshot of all payloads that were successfully dispatched for the given event key, in order. */\n emitted<K extends EventKey<T>>(event: K): T[K][];\n /** Number of times the given event was successfully dispatched. Shorthand for `emitted(event).length`. */\n emittedCount<K extends EventKey<T>>(event: K): number;\n /** Clear emitted records without disposing the bus. */\n reset(): void;\n};\n\nexport function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions<T>): TestBus<T> {\n const records = new Map<string, unknown[]>();\n const bus = createBus<T>({\n ...options,\n _onDispatch: (event: EventKey<T>, payload: unknown) => {\n const list = records.get(event);\n\n if (list) list.push(payload);\n else records.set(event, [payload]);\n },\n });\n const disposeBus = bus.dispose;\n\n function allEmitted(): { [K in EventKey<T>]?: T[K][] } {\n const result: { [K in EventKey<T>]?: T[K][] } = {};\n\n for (const [key, list] of records) {\n if (UNSAFE_OBJECT_KEYS.has(key)) continue;\n\n (result as Record<string, unknown[]>)[key] = [...list];\n }\n\n return result;\n }\n\n function emitted<K extends EventKey<T>>(event: K): T[K][] {\n return [...(records.get(event) ?? [])] as T[K][];\n }\n\n function emittedCount<K extends EventKey<T>>(event: K): number {\n return records.get(event)?.length ?? 0;\n }\n\n function dispose(): void {\n disposeBus();\n records.clear();\n }\n\n return Object.assign(bus, {\n allEmitted,\n dispose,\n emitted,\n emittedCount,\n reset: () => records.clear(),\n [Symbol.dispose]: dispose,\n }) as TestBus<T>;\n}\n"],"mappings":"8BASA,IAAM,EAAqB,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAc5E,SAAgB,EAA4D,EAAqC,CAC/G,IAAM,EAAU,IAAI,IACd,EAAM,EAAA,UAAa,CACvB,GAAG,EACH,aAAc,EAAoB,IAAqB,CACrD,IAAM,EAAO,EAAQ,IAAI,CAAK,EAE1B,EAAM,EAAK,KAAK,CAAO,EACtB,EAAQ,IAAI,EAAO,CAAC,CAAO,CAAC,CACnC,CACF,CAAC,EACK,EAAa,EAAI,QAEvB,SAAS,GAA8C,CACrD,IAAM,EAA0C,CAAC,EAEjD,IAAK,GAAM,CAAC,EAAK,KAAS,EACpB,EAAmB,IAAI,CAAG,IAE9B,EAAsC,GAAO,CAAC,GAAG,CAAI,GAGvD,OAAO,CACT,CAEA,SAAS,EAA+B,EAAkB,CACxD,MAAO,CAAC,GAAI,EAAQ,IAAI,CAAK,GAAK,CAAC,CAAE,CACvC,CAEA,SAAS,EAAoC,EAAkB,CAC7D,OAAO,EAAQ,IAAI,CAAK,CAAC,EAAE,QAAU,CACvC,CAEA,SAAS,GAAgB,CACvB,EAAW,EACX,EAAQ,MAAM,CAChB,CAEA,OAAO,OAAO,OAAO,EAAK,CACxB,aACA,UACA,UACA,eACA,UAAa,EAAQ,MAAM,GAC1B,OAAO,SAAU,CACpB,CAAC,CACH"}
1
+ {"version":3,"file":"testing.cjs","names":[],"sources":["../../src/testing/testing.ts"],"sourcesContent":["import type { Bus, BusOptions, EventKey, EventMap, HeraldEvent } from '..';\nimport { createBus } from '../bus';\n\n// Property names that must never be used as a bracket-assignment key on a plain object literal :\n// `obj[key] = value` for `key === '__proto__'` invokes `Object.prototype`'s `__proto__` accessor\n// and reassigns `obj`'s own prototype instead of setting an own property. `constructor` and\n// `prototype` are excluded defensively for the same class of risk.\n// Event names come from a caller-supplied `EventMap` type, but nothing prevents a caller from\n// wiring in a dynamically-determined (e.g. user-supplied) event name at runtime.\nconst UNSAFE_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A test bus is a regular bus with typed emission recording on top. */\nexport type TestBus<T extends EventMap> = Bus<T> & {\n /** Returns a snapshot of all payloads dispatched across every recorded event, keyed by event name. */\n allEmitted(): { [K in EventKey<T>]?: T[K][] };\n /** Snapshot of all payloads that were successfully dispatched for the given event key, in order. */\n emitted<K extends EventKey<T>>(event: K): T[K][];\n /** Number of times the given event was successfully dispatched. Shorthand for `emitted(event).length`. */\n emittedCount<K extends EventKey<T>>(event: K): number;\n /** Clear emitted records without disposing the bus. */\n reset(): void;\n};\n\nexport function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): TestBus<T> {\n const records = new Map<string, unknown[]>();\n const bus = createBus<T>(options);\n const disposeBus = bus.dispose;\n\n // Pure observer over the public tap channel: the `emit` event is traced after every\n // listener has run, so a dispatch whose listener throws still records its payload.\n bus.tap((event: HeraldEvent<T>) => {\n if (event.type !== 'emit') return;\n\n const list = records.get(event.event);\n\n if (list) list.push(event.payload);\n else records.set(event.event, [event.payload]);\n });\n\n function allEmitted(): { [K in EventKey<T>]?: T[K][] } {\n const result: { [K in EventKey<T>]?: T[K][] } = {};\n\n for (const [key, list] of records) {\n if (UNSAFE_OBJECT_KEYS.has(key)) continue;\n\n (result as Record<string, unknown[]>)[key] = [...list];\n }\n\n return result;\n }\n\n function emitted<K extends EventKey<T>>(event: K): T[K][] {\n return [...(records.get(event) ?? [])] as T[K][];\n }\n\n function emittedCount<K extends EventKey<T>>(event: K): number {\n return records.get(event)?.length ?? 0;\n }\n\n function dispose(): void {\n disposeBus();\n records.clear();\n }\n\n return Object.assign(bus, {\n allEmitted,\n dispose,\n emitted,\n emittedCount,\n reset: () => records.clear(),\n [Symbol.dispose]: dispose,\n }) as TestBus<T>;\n}\n"],"mappings":"8BASA,IAAM,EAAqB,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAc5E,SAAgB,cAA4D,EAAkC,CAC5G,IAAM,EAAU,IAAI,IACd,EAAM,EAAA,UAAa,CAAO,EAC1B,EAAa,EAAI,QAIvB,EAAI,IAAK,GAA0B,CACjC,GAAI,EAAM,OAAS,OAAQ,OAE3B,IAAM,EAAO,EAAQ,IAAI,EAAM,KAAK,EAEhC,EAAM,EAAK,KAAK,EAAM,OAAO,EAC5B,EAAQ,IAAI,EAAM,MAAO,CAAC,EAAM,OAAO,CAAC,CAC/C,CAAC,EAED,SAAS,YAA8C,CACrD,IAAM,EAA0C,CAAC,EAEjD,IAAK,GAAM,CAAC,EAAK,KAAS,EACpB,EAAmB,IAAI,CAAG,IAE9B,EAAsC,GAAO,CAAC,GAAG,CAAI,GAGvD,OAAO,CACT,CAEA,SAAS,QAA+B,EAAkB,CACxD,MAAO,CAAC,GAAI,EAAQ,IAAI,CAAK,GAAK,CAAC,CAAE,CACvC,CAEA,SAAS,aAAoC,EAAkB,CAC7D,OAAO,EAAQ,IAAI,CAAK,CAAC,EAAE,QAAU,CACvC,CAEA,SAAS,SAAgB,CACvB,EAAW,EACX,EAAQ,MAAM,CAChB,CAEA,OAAO,OAAO,OAAO,EAAK,CACxB,WACA,QACA,QACA,aACA,UAAa,EAAQ,MAAM,GAC1B,OAAO,SAAU,OACpB,CAAC,CACH"}
@@ -12,5 +12,5 @@ export type TestBus<T extends EventMap> = Bus<T> & {
12
12
  /** Clear emitted records without disposing the bus. */
13
13
  reset(): void;
14
14
  };
15
- export declare function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions<T>): TestBus<T>;
15
+ export declare function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): TestBus<T>;
16
16
  //# sourceMappingURL=testing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAW9D,wEAAwE;AACxE,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG;IACjD,sGAAsG;IACtG,UAAU,IAAI;SAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;KAAE,CAAC;IAC9C,oGAAoG;IACpG,OAAO,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,0GAA0G;IAC1G,YAAY,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC;IACtD,uDAAuD;IACvD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA8C/G"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAe,MAAM,IAAI,CAAC;AAW3E,wEAAwE;AACxE,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG;IACjD,sGAAsG;IACtG,UAAU,IAAI;SAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;KAAE,CAAC;IAC9C,oGAAoG;IACpG,OAAO,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,0GAA0G;IAC1G,YAAY,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC;IACtD,uDAAuD;IACvD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAiD5G"}
@@ -1,42 +1,2 @@
1
- import { createBus as e } from "../bus.js";
2
- //#region src/testing/testing.ts
3
- var t = /* @__PURE__ */ new Set([
4
- "__proto__",
5
- "constructor",
6
- "prototype"
7
- ]);
8
- function n(n) {
9
- let r = /* @__PURE__ */ new Map(), i = e({
10
- ...n,
11
- _onDispatch: (e, t) => {
12
- let n = r.get(e);
13
- n ? n.push(t) : r.set(e, [t]);
14
- }
15
- }), a = i.dispose;
16
- function o() {
17
- let e = {};
18
- for (let [n, i] of r) t.has(n) || (e[n] = [...i]);
19
- return e;
20
- }
21
- function s(e) {
22
- return [...r.get(e) ?? []];
23
- }
24
- function c(e) {
25
- return r.get(e)?.length ?? 0;
26
- }
27
- function l() {
28
- a(), r.clear();
29
- }
30
- return Object.assign(i, {
31
- allEmitted: o,
32
- dispose: l,
33
- emitted: s,
34
- emittedCount: c,
35
- reset: () => r.clear(),
36
- [Symbol.dispose]: l
37
- });
38
- }
39
- //#endregion
40
- export { n as createTestBus };
41
-
1
+ import{createBus as e}from"../bus.js";var t=new Set([`__proto__`,`constructor`,`prototype`]);function createTestBus(n){let r=new Map,i=e(n),a=i.dispose;i.tap(e=>{if(e.type!==`emit`)return;let t=r.get(e.event);t?t.push(e.payload):r.set(e.event,[e.payload])});function allEmitted(){let e={};for(let[n,i]of r)t.has(n)||(e[n]=[...i]);return e}function emitted(e){return[...r.get(e)??[]]}function emittedCount(e){return r.get(e)?.length??0}function dispose(){a(),r.clear()}return Object.assign(i,{allEmitted,dispose,emitted,emittedCount,reset:()=>r.clear(),[Symbol.dispose]:dispose})}export{createTestBus};
42
2
  //# sourceMappingURL=testing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":[],"sources":["../../src/testing/testing.ts"],"sourcesContent":["import type { Bus, BusOptions, EventKey, EventMap } from '..';\nimport { createBus } from '../bus';\n\n// Property names that must never be used as a bracket-assignment key on a plain object literal —\n// `obj[key] = value` for `key === '__proto__'` invokes `Object.prototype`'s `__proto__` accessor\n// and reassigns `obj`'s own prototype instead of setting an own property. `constructor` and\n// `prototype` are excluded defensively for the same class of risk.\n// Event names come from a caller-supplied `EventMap` type, but nothing prevents a caller from\n// wiring in a dynamically-determined (e.g. user-supplied) event name at runtime.\nconst UNSAFE_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A test bus is a regular bus with typed emission recording on top. */\nexport type TestBus<T extends EventMap> = Bus<T> & {\n /** Returns a snapshot of all payloads dispatched across every recorded event, keyed by event name. */\n allEmitted(): { [K in EventKey<T>]?: T[K][] };\n /** Snapshot of all payloads that were successfully dispatched for the given event key, in order. */\n emitted<K extends EventKey<T>>(event: K): T[K][];\n /** Number of times the given event was successfully dispatched. Shorthand for `emitted(event).length`. */\n emittedCount<K extends EventKey<T>>(event: K): number;\n /** Clear emitted records without disposing the bus. */\n reset(): void;\n};\n\nexport function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions<T>): TestBus<T> {\n const records = new Map<string, unknown[]>();\n const bus = createBus<T>({\n ...options,\n _onDispatch: (event: EventKey<T>, payload: unknown) => {\n const list = records.get(event);\n\n if (list) list.push(payload);\n else records.set(event, [payload]);\n },\n });\n const disposeBus = bus.dispose;\n\n function allEmitted(): { [K in EventKey<T>]?: T[K][] } {\n const result: { [K in EventKey<T>]?: T[K][] } = {};\n\n for (const [key, list] of records) {\n if (UNSAFE_OBJECT_KEYS.has(key)) continue;\n\n (result as Record<string, unknown[]>)[key] = [...list];\n }\n\n return result;\n }\n\n function emitted<K extends EventKey<T>>(event: K): T[K][] {\n return [...(records.get(event) ?? [])] as T[K][];\n }\n\n function emittedCount<K extends EventKey<T>>(event: K): number {\n return records.get(event)?.length ?? 0;\n }\n\n function dispose(): void {\n disposeBus();\n records.clear();\n }\n\n return Object.assign(bus, {\n allEmitted,\n dispose,\n emitted,\n emittedCount,\n reset: () => records.clear(),\n [Symbol.dispose]: dispose,\n }) as TestBus<T>;\n}\n"],"mappings":";;AASA,IAAM,oBAAqB,IAAI,IAAI;CAAC;CAAa;CAAe;AAAW,CAAC;AAc5E,SAAgB,EAA4D,GAAqC;CAC/G,IAAM,oBAAU,IAAI,IAAuB,GACrC,IAAM,EAAa;EACvB,GAAG;EACH,cAAc,GAAoB,MAAqB;GACrD,IAAM,IAAO,EAAQ,IAAI,CAAK;GAE9B,AAAI,IAAM,EAAK,KAAK,CAAO,IACtB,EAAQ,IAAI,GAAO,CAAC,CAAO,CAAC;EACnC;CACF,CAAC,GACK,IAAa,EAAI;CAEvB,SAAS,IAA8C;EACrD,IAAM,IAA0C,CAAC;EAEjD,KAAK,IAAM,CAAC,GAAK,MAAS,GACpB,EAAmB,IAAI,CAAG,MAE9B,EAAsC,KAAO,CAAC,GAAG,CAAI;EAGvD,OAAO;CACT;CAEA,SAAS,EAA+B,GAAkB;EACxD,OAAO,CAAC,GAAI,EAAQ,IAAI,CAAK,KAAK,CAAC,CAAE;CACvC;CAEA,SAAS,EAAoC,GAAkB;EAC7D,OAAO,EAAQ,IAAI,CAAK,CAAC,EAAE,UAAU;CACvC;CAEA,SAAS,IAAgB;EAEvB,AADA,EAAW,GACX,EAAQ,MAAM;CAChB;CAEA,OAAO,OAAO,OAAO,GAAK;EACxB;EACA;EACA;EACA;EACA,aAAa,EAAQ,MAAM;GAC1B,OAAO,UAAU;CACpB,CAAC;AACH"}
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../../src/testing/testing.ts"],"sourcesContent":["import type { Bus, BusOptions, EventKey, EventMap, HeraldEvent } from '..';\nimport { createBus } from '../bus';\n\n// Property names that must never be used as a bracket-assignment key on a plain object literal :\n// `obj[key] = value` for `key === '__proto__'` invokes `Object.prototype`'s `__proto__` accessor\n// and reassigns `obj`'s own prototype instead of setting an own property. `constructor` and\n// `prototype` are excluded defensively for the same class of risk.\n// Event names come from a caller-supplied `EventMap` type, but nothing prevents a caller from\n// wiring in a dynamically-determined (e.g. user-supplied) event name at runtime.\nconst UNSAFE_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A test bus is a regular bus with typed emission recording on top. */\nexport type TestBus<T extends EventMap> = Bus<T> & {\n /** Returns a snapshot of all payloads dispatched across every recorded event, keyed by event name. */\n allEmitted(): { [K in EventKey<T>]?: T[K][] };\n /** Snapshot of all payloads that were successfully dispatched for the given event key, in order. */\n emitted<K extends EventKey<T>>(event: K): T[K][];\n /** Number of times the given event was successfully dispatched. Shorthand for `emitted(event).length`. */\n emittedCount<K extends EventKey<T>>(event: K): number;\n /** Clear emitted records without disposing the bus. */\n reset(): void;\n};\n\nexport function createTestBus<T extends EventMap = Record<string, unknown>>(options?: BusOptions): TestBus<T> {\n const records = new Map<string, unknown[]>();\n const bus = createBus<T>(options);\n const disposeBus = bus.dispose;\n\n // Pure observer over the public tap channel: the `emit` event is traced after every\n // listener has run, so a dispatch whose listener throws still records its payload.\n bus.tap((event: HeraldEvent<T>) => {\n if (event.type !== 'emit') return;\n\n const list = records.get(event.event);\n\n if (list) list.push(event.payload);\n else records.set(event.event, [event.payload]);\n });\n\n function allEmitted(): { [K in EventKey<T>]?: T[K][] } {\n const result: { [K in EventKey<T>]?: T[K][] } = {};\n\n for (const [key, list] of records) {\n if (UNSAFE_OBJECT_KEYS.has(key)) continue;\n\n (result as Record<string, unknown[]>)[key] = [...list];\n }\n\n return result;\n }\n\n function emitted<K extends EventKey<T>>(event: K): T[K][] {\n return [...(records.get(event) ?? [])] as T[K][];\n }\n\n function emittedCount<K extends EventKey<T>>(event: K): number {\n return records.get(event)?.length ?? 0;\n }\n\n function dispose(): void {\n disposeBus();\n records.clear();\n }\n\n return Object.assign(bus, {\n allEmitted,\n dispose,\n emitted,\n emittedCount,\n reset: () => records.clear(),\n [Symbol.dispose]: dispose,\n }) as TestBus<T>;\n}\n"],"mappings":"sCASA,IAAM,EAAqB,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAc5E,SAAgB,cAA4D,EAAkC,CAC5G,IAAM,EAAU,IAAI,IACd,EAAM,EAAa,CAAO,EAC1B,EAAa,EAAI,QAIvB,EAAI,IAAK,GAA0B,CACjC,GAAI,EAAM,OAAS,OAAQ,OAE3B,IAAM,EAAO,EAAQ,IAAI,EAAM,KAAK,EAEhC,EAAM,EAAK,KAAK,EAAM,OAAO,EAC5B,EAAQ,IAAI,EAAM,MAAO,CAAC,EAAM,OAAO,CAAC,CAC/C,CAAC,EAED,SAAS,YAA8C,CACrD,IAAM,EAA0C,CAAC,EAEjD,IAAK,GAAM,CAAC,EAAK,KAAS,EACpB,EAAmB,IAAI,CAAG,IAE9B,EAAsC,GAAO,CAAC,GAAG,CAAI,GAGvD,OAAO,CACT,CAEA,SAAS,QAA+B,EAAkB,CACxD,MAAO,CAAC,GAAI,EAAQ,IAAI,CAAK,GAAK,CAAC,CAAE,CACvC,CAEA,SAAS,aAAoC,EAAkB,CAC7D,OAAO,EAAQ,IAAI,CAAK,CAAC,EAAE,QAAU,CACvC,CAEA,SAAS,SAAgB,CACvB,EAAW,EACX,EAAQ,MAAM,CAChB,CAEA,OAAO,OAAO,OAAO,EAAK,CACxB,WACA,QACA,QACA,aACA,UAAa,EAAQ,MAAM,GAC1B,OAAO,SAAU,OACpB,CAAC,CACH"}
package/dist/testing.js CHANGED
@@ -1,2 +1 @@
1
- import { createTestBus as e } from "./testing/testing.js";
2
- export { e as createTestBus };
1
+ import{createTestBus as e}from"./testing/testing.js";export{e as createTestBus};
package/dist/types.d.ts CHANGED
@@ -4,17 +4,14 @@ export type Listener<T> = (payload: T) => void;
4
4
  export type Unsubscribe = () => void;
5
5
  /**
6
6
  * Options for a single-event subscription. Passed as the third argument to `bus.on()`.
7
- * Both fields are optional and can be combined freely.
8
7
  */
9
8
  export type SubscribeOptions = {
10
- /** Auto-remove the listener after its first invocation. Equivalent to calling `bus.once()`. */
11
- once?: boolean;
12
9
  /** Auto-remove the listener when this signal aborts. */
13
10
  signal?: AbortSignal;
14
11
  };
15
12
  /**
16
13
  * Runtime events emitted by {@link Bus.tap}.
17
- * Subscribe via `bus.tap(handler)` — handler errors are swallowed.
14
+ * Subscribe via `bus.tap(handler)`: handler errors are swallowed.
18
15
  */
19
16
  export type HeraldEvent<T extends EventMap = EventMap> = {
20
17
  readonly event: EventKey<T>;
@@ -38,7 +35,7 @@ export type HeraldEvent<T extends EventMap = EventMap> = {
38
35
  } | {
39
36
  readonly type: 'dispose';
40
37
  };
41
- export type BusOptions<T extends EventMap = EventMap> = {
38
+ export type BusOptions = {
42
39
  /**
43
40
  * Warn when a single event's active listener count exceeds this threshold.
44
41
  * Useful for detecting listener leaks during development. Default: no check.
@@ -58,14 +55,14 @@ export type WaitAnyResult<T extends EventMap, K extends readonly EventKey<T>[]>
58
55
  } : never;
59
56
  }[number];
60
57
  export type Bus<T extends EventMap> = {
61
- /** Alias for dispose() — enables the `using` keyword for automatic cleanup. */
58
+ /** Alias for dispose(): enables the `using` keyword for automatic cleanup. */
62
59
  [Symbol.dispose](): void;
63
60
  /**
64
61
  * Signal that fires when the bus is disposed.
65
62
  * Use to tie other lifecycles (subscriptions, pipes, timers) to this bus's lifetime.
66
63
  */
67
64
  readonly disposalSignal: AbortSignal;
68
- /** Permanently dispose the bus — clears all listeners; pending waits are rejected. Idempotent. */
65
+ /** Permanently dispose the bus: clears all listeners; pending waits are rejected. Idempotent. */
69
66
  dispose(): void;
70
67
  /** Whether the bus has been permanently disposed. */
71
68
  readonly disposed: boolean;
@@ -79,15 +76,13 @@ export type Bus<T extends EventMap> = {
79
76
  eventNames(): EventKey<T>[];
80
77
  /**
81
78
  * Number of active specific-event listeners for a given event key.
82
- * Does not include wildcard (`onAny`) listeners — use `wildcardCount()` for those.
79
+ * Does not include wildcard (`onAny`) listeners: use `wildcardCount()` for those.
83
80
  * When called without an argument, returns the total across all specific-event listeners.
84
81
  */
85
82
  listenerCount(event?: EventKey<T>): number;
86
83
  /**
87
84
  * Subscribe to an event. Returns an unsubscribe function.
88
- *
89
- * - `opts.signal` — auto-unsubscribe when the signal aborts.
90
- * - `opts.once` — auto-unsubscribe after the first invocation (equivalent to `bus.once()`).
85
+ * `opts.signal` auto-unsubscribes when the signal aborts.
91
86
  */
92
87
  on<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: SubscribeOptions): Unsubscribe;
93
88
  /**
@@ -96,7 +91,7 @@ export type Bus<T extends EventMap> = {
96
91
  */
97
92
  onAny(listener: (event: EventKey<T>, payload: unknown) => void, opts?: SubscribeOptions): Unsubscribe;
98
93
  /**
99
- * Subscribe once — auto-unsubscribes after the first emit. Stops early when the signal aborts.
94
+ * Subscribe once: auto-unsubscribes after the first emit. Stops early when the signal aborts.
100
95
  */
101
96
  once<K extends EventKey<T>>(event: K, listener: Listener<T[K]>, opts?: {
102
97
  signal?: AbortSignal;
@@ -110,11 +105,11 @@ export type Bus<T extends EventMap> = {
110
105
  signal?: AbortSignal;
111
106
  }): Promise<T[K]>;
112
107
  /**
113
- * Resolve when any of the listed events (minimum 2) fires first.
108
+ * Resolve when any of the listed events fires first. Accepts one or more event keys.
114
109
  * Returns a typed `{ event, payload }` discriminated union.
115
110
  * Rejects with `BusDisposedError` if the bus is disposed, or with the signal's reason if the signal aborts.
116
111
  */
117
- waitAny<const K extends readonly [EventKey<T>, EventKey<T>, ...EventKey<T>[]]>(events: K, opts?: {
112
+ waitAny<const K extends readonly EventKey<T>[]>(events: K, opts?: {
118
113
  signal?: AbortSignal;
119
114
  }): Promise<WaitAnyResult<T, K>>;
120
115
  /**
@@ -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,7 +1,7 @@
1
1
  {
2
2
  "name": "@vielzeug/herald",
3
- "version": "3.0.0",
4
- "description": "Typed event bus — pub/sub with namespaces, wildcards, and once-listeners",
3
+ "version": "26.10.1",
4
+ "description": "Typed synchronous event bus with wildcard subscriptions, one-shot waits, and lifecycle tracing",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/helmuthdu/vielzeug",
@@ -53,9 +53,9 @@
53
53
  "test": "vitest"
54
54
  },
55
55
  "devDependencies": {
56
- "@types/node": "^26.4.1",
56
+ "@types/node": "^26.6.2",
57
57
  "typescript": "^6.0.3",
58
- "vite": "^8.2.2",
59
- "vitest": "^5.0.0"
58
+ "vite": "^8.3.0",
59
+ "vitest": "^5.0.1"
60
60
  }
61
61
  }