UNPKG

ngx-signal-hub

Version:

[![npm version](https://badge.fury.io/js/ngx-signal-hub.svg)](https://badge.fury.io/js/ngx-signal-hub) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

1 lines 21.1 kB
{"version":3,"file":"ngx-signal-hub.mjs","sources":["../../../projects/ngx-signal-hub/src/lib/signal-hub.service.ts","../../../projects/ngx-signal-hub/src/public-api.ts","../../../projects/ngx-signal-hub/src/ngx-signal-hub.ts"],"sourcesContent":["import {\n Injectable,\n Injector,\n effect,\n signal,\n computed,\n Signal,\n untracked,\n DestroyRef,\n} from '@angular/core';\n\n/** Represents an event in the signal hub with a key, data, and timestamp. */\nexport interface HubEvent<T = unknown> {\n key: string;\n data: T;\n timestamp: number;\n}\n\n/** Represents the options for subscribing to a single signal hub event. */\nexport interface HubEventOptions<T> {\n /** The key to match events against (e.g., 'user:login'). */\n key: string;\n /** The callback function to execute when an event matches the key. */\n callback: (event: HubEvent<T>) => void | Promise<void>;\n /** Optional DestroyRef for auto-cleaning subscriptions. */\n destroyRef?: DestroyRef;\n /** If true, replays the latest event for the key on subscription. */\n replayLatest?: boolean;\n /** Optional error handler for callback errors. */\n onError?: (error: unknown, event: HubEvent<T>) => void;\n /** Optional condition(s) to unsubscribe when true (signal) or when event is received (key). */\n until?: (string | Signal<boolean>) | (string | Signal<boolean>)[];\n}\n\n/** Represents the options for subscribing to multiple signal hub events with combineLatest behavior. */\nexport interface HubCombineLatestOptions<T> {\n /** Array of keys to match events against (e.g., ['user:login', 'user:logout']). */\n keys: string[];\n /** The callback function to execute with the latest events for all keys. */\n callback: (events: HubEvent<T>[]) => void | Promise<void>;\n /** Optional DestroyRef for auto-cleaning subscriptions. */\n destroyRef?: DestroyRef;\n /** If true, replays the latest events for the keys on subscription. */\n replayLatest?: boolean;\n /** Optional error handler for callback errors. */\n onError?: (error: unknown, events: HubEvent<T>[]) => void;\n /** Optional sorting for combined events (e.g., 'timestamp' or 'key'). */\n sortBy?: 'timestamp' | 'key';\n}\n\n/** Represents a subscription to the signal hub. */\nexport interface HubSubscription {\n unsubscribe: () => void;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class SignalHubService {\n private readonly eventRegistry = signal<Map<string, HubEvent>>(new Map(), {\n equal: (a, b) => a === b,\n });\n\n private readonly subscribers = new Map<\n string,\n Set<{\n callback: (event: HubEvent) => void | Promise<void>;\n onError?: (error: unknown, event: HubEvent) => void;\n }>\n >();\n\n constructor(private readonly injector: Injector) {}\n\n publish<T = unknown>(key: string, data?: T): void {\n if (!key) throw new Error('Key cannot be empty');\n\n const event: HubEvent<T> = { key, data: data as T, timestamp: Date.now() };\n this.eventRegistry.update((registry) => new Map(registry).set(key, event));\n this.notifySubscribers(event);\n }\n\n on<T>(options: HubEventOptions<T>): HubSubscription {\n const { key, callback, destroyRef, replayLatest, onError, until } = options;\n if (!key) throw new Error('Key cannot be empty');\n if (typeof callback !== 'function') throw new Error('Callback must be a function');\n\n const unsubscribers: (() => void)[] = [];\n let mainSubscription: HubSubscription | null = null;\n\n // Handle unsubscription conditions (from takeUntil)\n const unsubscribeAll = () => {\n unsubscribers.forEach((unsub) => unsub());\n mainSubscription?.unsubscribe();\n };\n\n if (until) {\n const conditions = Array.isArray(until) ? until : [until];\n // Check signals immediately\n const signals = conditions.filter((c): c is Signal<boolean> => typeof c !== 'string');\n if (signals.some((signal) => signal())) {\n return { unsubscribe: () => {} };\n }\n\n for (const condition of conditions) {\n if (typeof condition === 'string') {\n const sub = this.internalSubscribe(condition, unsubscribeAll, undefined, undefined, true);\n unsubscribers.push(sub.unsubscribe);\n } else {\n const signal = condition;\n const effectRef = effect(\n () => {\n if (signal()) unsubscribeAll();\n },\n { injector: this.injector }\n );\n unsubscribers.push(() => effectRef.destroy());\n }\n }\n }\n\n // Replay latest event if requested\n if (replayLatest) {\n untracked(() => {\n const latestEvent = this.findLatestEventForKey(key) as HubEvent<T> | undefined;\n if (latestEvent) {\n try {\n callback(latestEvent);\n } catch (error) {\n this.handleError(error, latestEvent, onError, key);\n }\n }\n });\n }\n\n mainSubscription = this.internalSubscribe(key, callback, destroyRef, onError);\n return { unsubscribe: unsubscribeAll };\n }\n\n subscribe = this.on;\n\n once<T>({ key, callback, replayLatest, onError, until }: HubEventOptions<T>): HubSubscription {\n let subscription: HubSubscription | null = null;\n const onceCallback = (event: HubEvent<T>) => {\n subscription?.unsubscribe();\n try {\n callback(event);\n } catch (error) {\n this.handleError(error, event, onError, key);\n }\n };\n subscription = this.on({ key, callback: onceCallback, replayLatest, onError, until });\n return subscription;\n }\n\n onCombineLatest<T>(options: HubCombineLatestOptions<T>): HubSubscription {\n const { keys, callback, destroyRef, replayLatest, onError, sortBy } = options;\n if (!keys?.length) throw new Error('Keys array cannot be empty');\n\n const sourceSignals = keys.map((key) => this.toSignal<T>(key));\n const combinedSignal = computed(() => {\n const events = sourceSignals.map((s) => s()).filter((e): e is HubEvent<T> => e !== null);\n if (events.length === keys.length) {\n return sortBy === 'timestamp'\n ? events.sort((a, b) => b.timestamp - a.timestamp)\n : sortBy === 'key'\n ? events.sort((a, b) => a.key.localeCompare(b.key))\n : events;\n }\n return null;\n });\n\n const effectRef = effect(\n () => {\n const combinedEvents = combinedSignal();\n if (!combinedEvents) return;\n if (!replayLatest && !this.eventRegistry().size) return;\n\n try {\n callback(combinedEvents);\n } catch (error) {\n onError\n ? onError(error, combinedEvents)\n : console.warn(`onCombineLatest error for keys [${keys.join(', ')}]:`, error);\n }\n },\n { injector: this.injector }\n );\n\n const unsubscribe = () => effectRef.destroy();\n if (destroyRef) {\n destroyRef.onDestroy(unsubscribe);\n }\n\n return { unsubscribe };\n }\n\n toSignal<T>(key: string): Signal<HubEvent<T> | null> {\n if (!key) throw new Error('Key cannot be empty');\n if (key.includes('*'))\n throw new Error('toSignal does not support wildcards. Use toSignalMultiple instead.');\n\n return computed(() => (this.eventRegistry().get(key) as HubEvent<T>) ?? null);\n }\n\n toSignalMultiple<T>(\n keys: string[],\n options: { sortBy?: 'timestamp' | 'key' } = {}\n ): Signal<HubEvent<T>[]> {\n if (!keys?.length) throw new Error('Keys array cannot be empty');\n\n return computed(() => {\n const registry = this.eventRegistry();\n const matchingEvents = new Map<string, HubEvent<T>>();\n\n for (const query of keys) {\n if (!query) continue;\n const isWildcard = query.includes('*');\n if (!isWildcard) {\n const event = registry.get(query) as HubEvent<T> | undefined;\n if (event) {\n matchingEvents.set(event.key, event);\n }\n } else {\n const regex = this.buildWildcardRegex(query);\n for (const [eventKey, event] of registry.entries()) {\n if (regex.test(eventKey)) {\n matchingEvents.set(eventKey, event as HubEvent<T>);\n }\n }\n }\n }\n\n const eventsArray = Array.from(matchingEvents.values());\n if (options.sortBy === 'timestamp') {\n return eventsArray.sort((a, b) => b.timestamp - a.timestamp);\n }\n if (options.sortBy === 'key') {\n return eventsArray.sort((a, b) => a.key.localeCompare(b.key));\n }\n return eventsArray;\n });\n }\n\n clearEvent(key: string): void {\n if (!key) throw new Error('Key cannot be empty');\n this.eventRegistry.update((registry) => {\n const updated = new Map(registry);\n updated.delete(key);\n return updated;\n });\n }\n\n reset(options: { clearSubscribers?: boolean } = {}): void {\n this.eventRegistry.set(new Map());\n if (options.clearSubscribers) {\n this.subscribers.clear();\n }\n }\n\n private internalSubscribe<T>(\n query: string,\n callback: (event: HubEvent<T>) => void | Promise<void>,\n destroyRef?: DestroyRef,\n onError?: (error: unknown, event: HubEvent<T>) => void,\n once = false\n ): HubSubscription {\n const subscriber = {\n callback: callback as (event: HubEvent) => void | Promise<void>,\n onError: onError as ((error: unknown, event: HubEvent) => void) | undefined,\n };\n\n const subscriberSet = this.subscribers.get(query) ?? new Set();\n subscriberSet.add(subscriber);\n this.subscribers.set(query, subscriberSet);\n\n const unsubscribe = () => {\n const currentSubscribers = this.subscribers.get(query);\n currentSubscribers?.delete(subscriber);\n if (currentSubscribers?.size === 0) {\n this.subscribers.delete(query);\n }\n };\n\n if (once) {\n const originalCallback = subscriber.callback;\n subscriber.callback = (event: HubEvent) => {\n unsubscribe();\n return originalCallback(event);\n };\n }\n\n if (destroyRef) {\n destroyRef.onDestroy(unsubscribe);\n }\n\n return { unsubscribe };\n }\n\n private notifySubscribers(event: HubEvent): void {\n this.subscribers.forEach((subscribers, query) => {\n if (this.matchQuery(event.key, query)) {\n subscribers.forEach(({ callback, onError }) => {\n try {\n Promise.resolve(callback(event)).catch((error) => {\n this.handleError(error, event, onError, query);\n });\n } catch (error) {\n this.handleError(error, event, onError, query);\n }\n });\n }\n });\n }\n\n private findLatestEventForKey(key: string): HubEvent | undefined {\n if (!key.includes('*')) {\n return this.eventRegistry().get(key);\n }\n const regex = this.buildWildcardRegex(key);\n let latestEvent: HubEvent | undefined;\n for (const [eventKey, event] of this.eventRegistry().entries()) {\n if (regex.test(eventKey)) {\n if (!latestEvent || event.timestamp > latestEvent.timestamp) {\n latestEvent = event;\n }\n }\n }\n return latestEvent;\n }\n\n private handleError(error: unknown, event: HubEvent, handler?: Function, query?: string): void {\n if (handler) {\n handler(error, event);\n } else {\n console.warn(`SignalHub error for query \"${query}\" on event \"${event.key}\":`, error);\n }\n }\n\n private matchQuery(key: string, query: string): boolean {\n if (query === '*' || key === query) return true;\n if (!query.includes('*')) return false;\n return this.buildWildcardRegex(query).test(key);\n }\n\n private buildWildcardRegex(query: string): RegExp {\n const pattern = query.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '[^:]+');\n return new RegExp(`^${pattern}$`);\n }\n}\n","/*\n * Public API Surface of ngx-signal-hub\n */\n\nexport * from './lib/signal-hub.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}