@jasonshimmy/custom-elements-runtime 3.2.0 → 3.2.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/dist/{css-utils-Cg4o1MqY.js → css-utils-CC43BbEy.js} +20 -21
- package/dist/css-utils-CC43BbEy.js.map +1 -0
- package/dist/{css-utils-RqkyBWft.cjs → css-utils-mgjmH8qX.cjs} +5 -4
- package/dist/css-utils-mgjmH8qX.cjs.map +1 -0
- package/dist/custom-elements-runtime.cjs.js +4 -3
- package/dist/custom-elements-runtime.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.colors.cjs.js +3 -2
- package/dist/custom-elements-runtime.colors.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.colors.es.js +3 -2
- package/dist/custom-elements-runtime.colors.es.js.map +1 -1
- package/dist/custom-elements-runtime.directive-enhancements.cjs.js +3 -2
- package/dist/custom-elements-runtime.directive-enhancements.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.directive-enhancements.es.js +86 -100
- package/dist/custom-elements-runtime.directive-enhancements.es.js.map +1 -1
- package/dist/custom-elements-runtime.directives.cjs.js +3 -2
- package/dist/custom-elements-runtime.directives.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.directives.es.js +40 -43
- package/dist/custom-elements-runtime.directives.es.js.map +1 -1
- package/dist/custom-elements-runtime.dom-jit-css.cjs.js +7 -6
- package/dist/custom-elements-runtime.dom-jit-css.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.dom-jit-css.es.js +58 -76
- package/dist/custom-elements-runtime.dom-jit-css.es.js.map +1 -1
- package/dist/custom-elements-runtime.es.js +162 -186
- package/dist/custom-elements-runtime.es.js.map +1 -1
- package/dist/custom-elements-runtime.event-bus.cjs.js +3 -2
- package/dist/custom-elements-runtime.event-bus.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.event-bus.es.js +48 -103
- package/dist/custom-elements-runtime.event-bus.es.js.map +1 -1
- package/dist/custom-elements-runtime.jit-css.cjs.js +3 -2
- package/dist/custom-elements-runtime.jit-css.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.jit-css.es.js +29 -30
- package/dist/custom-elements-runtime.jit-css.es.js.map +1 -1
- package/dist/custom-elements-runtime.router.cjs.js +20 -19
- package/dist/custom-elements-runtime.router.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.router.es.js +585 -603
- package/dist/custom-elements-runtime.router.es.js.map +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js +5 -4
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.es.js +44 -37
- package/dist/custom-elements-runtime.ssr-middleware.es.js.map +1 -1
- package/dist/custom-elements-runtime.ssr.cjs.js +1 -4
- package/dist/custom-elements-runtime.ssr.es.js +11 -176
- package/dist/custom-elements-runtime.store.cjs.js +3 -2
- package/dist/custom-elements-runtime.store.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.store.es.js +17 -11
- package/dist/custom-elements-runtime.store.es.js.map +1 -1
- package/dist/custom-elements-runtime.transitions.cjs.js +3 -2
- package/dist/custom-elements-runtime.transitions.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.transitions.es.js +55 -120
- package/dist/custom-elements-runtime.transitions.es.js.map +1 -1
- package/dist/custom-elements-runtime.vite-plugin.cjs.js +3 -2
- package/dist/custom-elements-runtime.vite-plugin.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.vite-plugin.es.js +54 -75
- package/dist/custom-elements-runtime.vite-plugin.es.js.map +1 -1
- package/dist/hooks-_3xP4G2N.js +1189 -0
- package/dist/hooks-_3xP4G2N.js.map +1 -0
- package/dist/hooks-fYQgZk2g.cjs +7 -0
- package/dist/hooks-fYQgZk2g.cjs.map +1 -0
- package/dist/logger-BYIN7ysT.cjs +3 -0
- package/dist/logger-BYIN7ysT.cjs.map +1 -0
- package/dist/logger-L25axmB-.js +41 -0
- package/dist/logger-L25axmB-.js.map +1 -0
- package/dist/namespace-helpers-Bf7rm9JV.cjs +3 -0
- package/dist/namespace-helpers-Bf7rm9JV.cjs.map +1 -0
- package/dist/namespace-helpers-BucDdgz_.js +61 -0
- package/dist/namespace-helpers-BucDdgz_.js.map +1 -0
- package/dist/reset.css +1 -1
- package/dist/ssr-B3lxl1vr.js +165 -0
- package/dist/ssr-B3lxl1vr.js.map +1 -0
- package/dist/ssr-DtD9e5iA.cjs +5 -0
- package/dist/ssr-DtD9e5iA.cjs.map +1 -0
- package/dist/style-Bjn8zDiZ.cjs +56 -0
- package/dist/style-Bjn8zDiZ.cjs.map +1 -0
- package/dist/{style-BmyOIMcU.js → style-DuDoj_xK.js} +724 -876
- package/dist/style-DuDoj_xK.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/template-compiler-BB4JJdqk.cjs +23 -0
- package/dist/template-compiler-BB4JJdqk.cjs.map +1 -0
- package/dist/template-compiler-Cs5axmn4.js +3236 -0
- package/dist/template-compiler-Cs5axmn4.js.map +1 -0
- package/dist/variables.css +1 -1
- package/package.json +7 -7
- package/dist/css-utils-Cg4o1MqY.js.map +0 -1
- package/dist/css-utils-RqkyBWft.cjs.map +0 -1
- package/dist/custom-elements-runtime.ssr.cjs.js.map +0 -1
- package/dist/custom-elements-runtime.ssr.es.js.map +0 -1
- package/dist/hooks-BH-CpUun.js +0 -1474
- package/dist/hooks-BH-CpUun.js.map +0 -1
- package/dist/hooks-NOFG9QRQ.cjs +0 -6
- package/dist/hooks-NOFG9QRQ.cjs.map +0 -1
- package/dist/logger-BvkEbVM4.js +0 -48
- package/dist/logger-BvkEbVM4.js.map +0 -1
- package/dist/logger-CSALKaYm.cjs +0 -2
- package/dist/logger-CSALKaYm.cjs.map +0 -1
- package/dist/namespace-helpers-D4wC2-qA.js +0 -61
- package/dist/namespace-helpers-D4wC2-qA.js.map +0 -1
- package/dist/namespace-helpers-ckeEOxpR.cjs +0 -2
- package/dist/namespace-helpers-ckeEOxpR.cjs.map +0 -1
- package/dist/style-BmyOIMcU.js.map +0 -1
- package/dist/style-D40DsIqJ.cjs +0 -55
- package/dist/style-D40DsIqJ.cjs.map +0 -1
- package/dist/template-compiler-CDvhsHia.cjs +0 -22
- package/dist/template-compiler-CDvhsHia.cjs.map +0 -1
- package/dist/template-compiler-DiE69FLO.js +0 -3724
- package/dist/template-compiler-DiE69FLO.js.map +0 -1
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./logger-BYIN7ysT.cjs");var l=class o extends EventTarget{handlers={};static instance;eventCounters=new Map;nativeUnsubscribers=new Map;MAX_EVENT_COUNTERS=1e3;static getInstance(){return o.instance||(o.instance=new o),o.instance}emit(e,t){const n=Date.now(),s=this.eventCounters.get(e);if(!s||n-s.window>1e3){if(!s&&this.eventCounters.size>=this.MAX_EVENT_COUNTERS){const c=this.eventCounters.keys().next().value;c!==void 0&&this.eventCounters.delete(c)}this.eventCounters.set(e,{count:1,window:n})}else if(s.count++,s.count===51&&a.devError(`[EventBus] Event "${e}" is firing too frequently (>${s.count-1}/s). Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. Consider debouncing the emitter.`),s.count>100)return;this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!1,cancelable:!0}));const u=this.handlers[e];u&&u.forEach(c=>{try{c(t)}catch(h){a.devError(`Error in global event handler for "${e}":`,h)}})}on(e,t){return this.handlers[e]||(this.handlers[e]=new Set),this.handlers[e].add(t),()=>this.off(e,t)}off(e,t){const n=this.handlers[e];n&&(n.delete(t),n.size===0&&delete this.handlers[e])}offAll(e){delete this.handlers[e]}listen(e,t,n){this.addEventListener(e,t,n);const s=()=>{this.removeEventListener(e,t),this.nativeUnsubscribers.delete(s)};return this.nativeUnsubscribers.set(s,!0),s}once(e,t){if(t!==void 0){const n=this.on(e,s=>{n(),t(s)})}else return new Promise(n=>{const s=this.on(e,u=>{s(),n(u)})})}getActiveEvents(){return Object.keys(this.handlers).filter(e=>this.handlers[e]&&this.handlers[e].size>0)}clear(){this.handlers={};const e=Array.from(this.nativeUnsubscribers.keys());this.nativeUnsubscribers.clear();for(const t of e)t()}getHandlerCount(e){return this.handlers[e]?.size||0}getEventStats(){const e={};for(const[t,n]of this.eventCounters.entries())e[t]={count:n.count,handlersCount:this.getHandlerCount(t)};return e}resetEventCounters(){this.eventCounters.clear()}},i=new Proxy({},{get(r,e){const t=l.getInstance(),n=t[e];return typeof n=="function"?n.bind(t):n},apply(){throw new TypeError("eventBus is not a callable function")}}),d=(r,e)=>i.emit(r,e),f=(r,e)=>i.on(r,e),v=(r,e)=>i.off(r,e);function b(r,e){return e!==void 0?i.once(r,e):i.once(r)}var E=(r,e,t)=>i.listen(r,e,t);exports.GlobalEventBus=l;exports.emit=d;exports.eventBus=i;exports.listen=E;exports.off=v;exports.on=f;exports.once=b;
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=custom-elements-runtime.event-bus.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.event-bus.cjs.js","sources":["../src/lib/event-bus.ts"],"sourcesContent":["/**\n * Event handler type for global event bus\n */\nexport type EventHandler<T> = (data: T) => void;\n\nimport { devError } from './runtime/logger';\n\n/**\n * Event map type using Set for efficient handler management\n */\ntype EventMap<Events extends Record<string, unknown>> = {\n [K in keyof Events]: Set<EventHandler<Events[K]>>;\n};\n\n/**\n * GlobalEventBus provides a singleton event bus for cross-component communication.\n * Uses Set for handler storage to optimize add/remove operations and prevent duplicates.\n */\nexport class GlobalEventBus extends EventTarget {\n private handlers: EventMap<Record<string, unknown>> = {};\n private static instance: GlobalEventBus;\n private eventCounters: Map<string, { count: number; window: number }> =\n new Map();\n private nativeUnsubscribers: Map<() => void, true> = new Map();\n private readonly MAX_EVENT_COUNTERS = 1000;\n\n /**\n * Returns the singleton instance of GlobalEventBus\n */\n static getInstance(): GlobalEventBus {\n if (!GlobalEventBus.instance) {\n GlobalEventBus.instance = new GlobalEventBus();\n }\n return GlobalEventBus.instance;\n }\n\n /**\n * Emit a global event with optional data. Includes event storm protection.\n * @param eventName - Name of the event\n * @param data - Optional event payload\n */\n emit<T = unknown>(eventName: string, data?: T): void {\n // Event storm protection\n const now = Date.now();\n const counter = this.eventCounters.get(eventName);\n\n if (!counter || now - counter.window > 1000) {\n // Evict oldest entry if the map is at capacity to prevent unbounded growth.\n if (!counter && this.eventCounters.size >= this.MAX_EVENT_COUNTERS) {\n const firstKey = this.eventCounters.keys().next().value;\n if (firstKey !== undefined) this.eventCounters.delete(firstKey);\n }\n // Reset counter every second\n this.eventCounters.set(eventName, { count: 1, window: now });\n } else {\n counter.count++;\n\n if (counter.count === 51) {\n // Warn once at the throttle threshold so developers know emissions are being dropped.\n devError(\n `[EventBus] Event \"${eventName}\" is firing too frequently (>${counter.count - 1}/s). ` +\n 'Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. ' +\n 'Consider debouncing the emitter.',\n );\n }\n if (counter.count > 100) {\n // Drop the event to protect against runaway event storms.\n return;\n }\n }\n\n // Use native CustomEvent for better browser integration\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: data,\n bubbles: false, // Global events don't need to bubble\n cancelable: true,\n }),\n );\n\n // Also trigger registered handlers\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n devError(`Error in global event handler for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Register a handler for a global event. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n on<T = unknown>(eventName: string, handler: EventHandler<T>): () => void {\n if (!this.handlers[eventName]) {\n this.handlers[eventName] = new Set<EventHandler<unknown>>();\n }\n this.handlers[eventName].add(handler as EventHandler<unknown>);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Remove a specific handler for a global event.\n * @param eventName - Name of the event\n * @param handler - Handler function to remove\n */\n off<T = unknown>(eventName: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n // Remove the entry entirely once it is empty so stale keys don't\n // accumulate indefinitely in long-lived apps.\n if (eventHandlers.size === 0) {\n delete this.handlers[eventName];\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event.\n * @param eventName - Name of the event\n */\n offAll(eventName: string): void {\n delete this.handlers[eventName];\n }\n\n /**\n * Listen for a native CustomEvent. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - CustomEvent handler\n * @param options - AddEventListener options\n */\n listen<T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n ): () => void {\n this.addEventListener(eventName, handler as EventListener, options);\n // Use a wrapper so calling unsubscribe also removes it from nativeUnsubscribers,\n // preventing indefinite accumulation in long-lived apps.\n const unsubscribe: () => void = () => {\n this.removeEventListener(eventName, handler as EventListener);\n this.nativeUnsubscribers.delete(unsubscribe);\n };\n this.nativeUnsubscribers.set(unsubscribe, true);\n return unsubscribe;\n }\n\n /**\n * Register a one-time event handler (callback form).\n * The handler is invoked exactly once, then automatically unsubscribed.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n once<T = unknown>(eventName: string, handler: EventHandler<T>): void;\n /**\n * Returns a Promise that resolves with the first emission of the event\n * (Promise form — no handler argument).\n * @param eventName - Name of the event\n */\n once<T = unknown>(eventName: string): Promise<T>;\n once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n ): void | Promise<T> {\n if (handler !== undefined) {\n // Callback form: fire-and-forget, returns void\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n handler(data);\n });\n } else {\n // Promise form: resolves on first emission\n return new Promise<T>((resolve) => {\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n resolve(data);\n });\n });\n }\n }\n\n /**\n * Get a list of all active event names with registered handlers.\n */\n getActiveEvents(): string[] {\n return Object.keys(this.handlers).filter(\n (eventName) =>\n this.handlers[eventName] && this.handlers[eventName].size > 0,\n );\n }\n\n /**\n * Clear all event handlers and native EventTarget listeners (useful for testing or cleanup).\n */\n clear(): void {\n this.handlers = {};\n const toCleanup = Array.from(this.nativeUnsubscribers.keys());\n this.nativeUnsubscribers.clear();\n for (const unsubscribe of toCleanup) {\n unsubscribe();\n }\n }\n\n /**\n * Get the number of handlers registered for a specific event.\n * @param eventName - Name of the event\n */\n getHandlerCount(eventName: string): number {\n return this.handlers[eventName]?.size || 0;\n }\n\n /**\n * Get event statistics for debugging.\n */\n getEventStats(): Record<string, { count: number; handlersCount: number }> {\n const stats: Record<string, { count: number; handlersCount: number }> = {};\n for (const [eventName, counter] of this.eventCounters.entries()) {\n stats[eventName] = {\n count: counter.count,\n handlersCount: this.getHandlerCount(eventName),\n };\n }\n return stats;\n }\n\n /**\n * Reset event counters (useful for testing or after resolving issues).\n */\n resetEventCounters(): void {\n this.eventCounters.clear();\n }\n}\n\n/**\n * Singleton instance of the global event bus\n */\n/**\n * Lazily-instantiated event bus.\n *\n * We preserve the `eventBus` export for backward compatibility but avoid\n * creating the underlying GlobalEventBus instance at module import time.\n * A small proxy defers the call to `GlobalEventBus.getInstance()` until a\n * property is accessed. This reduces import-time side-effects and helps\n * bundlers tree-shake unused entrypoints.\n */\nexport const eventBus = new Proxy(\n {},\n {\n get(_target, prop: PropertyKey) {\n const inst = GlobalEventBus.getInstance();\n const val = (inst as unknown as Record<PropertyKey, unknown>)[prop];\n // If the property is a function (method), bind it to the instance\n // so callers using `eventBus.method(...)` get the correct `this`.\n if (typeof val === 'function')\n return (val as (...args: unknown[]) => unknown).bind(inst);\n return val;\n },\n apply() {\n throw new TypeError('eventBus is not a callable function');\n },\n },\n) as unknown as GlobalEventBus;\n\n/**\n * Emit a global event\n */\nexport const emit = <T = unknown>(eventName: string, data?: T) =>\n eventBus.emit(eventName, data);\n\n/**\n * Register a handler for a global event\n */\nexport const on = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.on(eventName, handler);\n\n/**\n * Remove a handler for a global event\n */\nexport const off = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.off(eventName, handler);\n\n/**\n * Register a one-time handler for a global event (callback form).\n * The handler fires once then auto-unsubscribes.\n */\nexport function once<T = unknown>(\n eventName: string,\n handler: EventHandler<T>,\n): void;\n/**\n * Returns a Promise that resolves with the next emission of the event\n * (Promise form — no handler argument needed).\n */\nexport function once<T = unknown>(eventName: string): Promise<T>;\nexport function once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n): void | Promise<T> {\n if (handler !== undefined) {\n return eventBus.once(eventName, handler);\n }\n return eventBus.once<T>(eventName);\n}\n\n/**\n * Listen for a native CustomEvent\n */\nexport const listen = <T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n) => eventBus.listen(eventName, handler, options);\n"],"names":["GlobalEventBus","eventName","data","now","counter","firstKey","devError","eventHandlers","handler","error","options","unsubscribe","resolve","toCleanup","stats","eventBus","_target","prop","inst","val","emit","on","off","once","listen"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.event-bus.cjs.js","names":[],"sources":["../src/lib/event-bus.ts"],"sourcesContent":["/**\n * Event handler type for global event bus\n */\nexport type EventHandler<T> = (data: T) => void;\n\nimport { devError } from './runtime/logger';\n\n/**\n * Event map type using Set for efficient handler management\n */\ntype EventMap<Events extends Record<string, unknown>> = {\n [K in keyof Events]: Set<EventHandler<Events[K]>>;\n};\n\n/**\n * GlobalEventBus provides a singleton event bus for cross-component communication.\n * Uses Set for handler storage to optimize add/remove operations and prevent duplicates.\n */\nexport class GlobalEventBus extends EventTarget {\n private handlers: EventMap<Record<string, unknown>> = {};\n private static instance: GlobalEventBus;\n private eventCounters: Map<string, { count: number; window: number }> =\n new Map();\n private nativeUnsubscribers: Map<() => void, true> = new Map();\n private readonly MAX_EVENT_COUNTERS = 1000;\n\n /**\n * Returns the singleton instance of GlobalEventBus\n */\n static getInstance(): GlobalEventBus {\n if (!GlobalEventBus.instance) {\n GlobalEventBus.instance = new GlobalEventBus();\n }\n return GlobalEventBus.instance;\n }\n\n /**\n * Emit a global event with optional data. Includes event storm protection.\n * @param eventName - Name of the event\n * @param data - Optional event payload\n */\n emit<T = unknown>(eventName: string, data?: T): void {\n // Event storm protection\n const now = Date.now();\n const counter = this.eventCounters.get(eventName);\n\n if (!counter || now - counter.window > 1000) {\n // Evict oldest entry if the map is at capacity to prevent unbounded growth.\n if (!counter && this.eventCounters.size >= this.MAX_EVENT_COUNTERS) {\n const firstKey = this.eventCounters.keys().next().value;\n if (firstKey !== undefined) this.eventCounters.delete(firstKey);\n }\n // Reset counter every second\n this.eventCounters.set(eventName, { count: 1, window: now });\n } else {\n counter.count++;\n\n if (counter.count === 51) {\n // Warn once at the throttle threshold so developers know emissions are being dropped.\n devError(\n `[EventBus] Event \"${eventName}\" is firing too frequently (>${counter.count - 1}/s). ` +\n 'Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. ' +\n 'Consider debouncing the emitter.',\n );\n }\n if (counter.count > 100) {\n // Drop the event to protect against runaway event storms.\n return;\n }\n }\n\n // Use native CustomEvent for better browser integration\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: data,\n bubbles: false, // Global events don't need to bubble\n cancelable: true,\n }),\n );\n\n // Also trigger registered handlers\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n devError(`Error in global event handler for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Register a handler for a global event. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n on<T = unknown>(eventName: string, handler: EventHandler<T>): () => void {\n if (!this.handlers[eventName]) {\n this.handlers[eventName] = new Set<EventHandler<unknown>>();\n }\n this.handlers[eventName].add(handler as EventHandler<unknown>);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Remove a specific handler for a global event.\n * @param eventName - Name of the event\n * @param handler - Handler function to remove\n */\n off<T = unknown>(eventName: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n // Remove the entry entirely once it is empty so stale keys don't\n // accumulate indefinitely in long-lived apps.\n if (eventHandlers.size === 0) {\n delete this.handlers[eventName];\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event.\n * @param eventName - Name of the event\n */\n offAll(eventName: string): void {\n delete this.handlers[eventName];\n }\n\n /**\n * Listen for a native CustomEvent. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - CustomEvent handler\n * @param options - AddEventListener options\n */\n listen<T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n ): () => void {\n this.addEventListener(eventName, handler as EventListener, options);\n // Use a wrapper so calling unsubscribe also removes it from nativeUnsubscribers,\n // preventing indefinite accumulation in long-lived apps.\n const unsubscribe: () => void = () => {\n this.removeEventListener(eventName, handler as EventListener);\n this.nativeUnsubscribers.delete(unsubscribe);\n };\n this.nativeUnsubscribers.set(unsubscribe, true);\n return unsubscribe;\n }\n\n /**\n * Register a one-time event handler (callback form).\n * The handler is invoked exactly once, then automatically unsubscribed.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n once<T = unknown>(eventName: string, handler: EventHandler<T>): void;\n /**\n * Returns a Promise that resolves with the first emission of the event\n * (Promise form — no handler argument).\n * @param eventName - Name of the event\n */\n once<T = unknown>(eventName: string): Promise<T>;\n once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n ): void | Promise<T> {\n if (handler !== undefined) {\n // Callback form: fire-and-forget, returns void\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n handler(data);\n });\n } else {\n // Promise form: resolves on first emission\n return new Promise<T>((resolve) => {\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n resolve(data);\n });\n });\n }\n }\n\n /**\n * Get a list of all active event names with registered handlers.\n */\n getActiveEvents(): string[] {\n return Object.keys(this.handlers).filter(\n (eventName) =>\n this.handlers[eventName] && this.handlers[eventName].size > 0,\n );\n }\n\n /**\n * Clear all event handlers and native EventTarget listeners (useful for testing or cleanup).\n */\n clear(): void {\n this.handlers = {};\n const toCleanup = Array.from(this.nativeUnsubscribers.keys());\n this.nativeUnsubscribers.clear();\n for (const unsubscribe of toCleanup) {\n unsubscribe();\n }\n }\n\n /**\n * Get the number of handlers registered for a specific event.\n * @param eventName - Name of the event\n */\n getHandlerCount(eventName: string): number {\n return this.handlers[eventName]?.size || 0;\n }\n\n /**\n * Get event statistics for debugging.\n */\n getEventStats(): Record<string, { count: number; handlersCount: number }> {\n const stats: Record<string, { count: number; handlersCount: number }> = {};\n for (const [eventName, counter] of this.eventCounters.entries()) {\n stats[eventName] = {\n count: counter.count,\n handlersCount: this.getHandlerCount(eventName),\n };\n }\n return stats;\n }\n\n /**\n * Reset event counters (useful for testing or after resolving issues).\n */\n resetEventCounters(): void {\n this.eventCounters.clear();\n }\n}\n\n/**\n * Singleton instance of the global event bus\n */\n/**\n * Lazily-instantiated event bus.\n *\n * We preserve the `eventBus` export for backward compatibility but avoid\n * creating the underlying GlobalEventBus instance at module import time.\n * A small proxy defers the call to `GlobalEventBus.getInstance()` until a\n * property is accessed. This reduces import-time side-effects and helps\n * bundlers tree-shake unused entrypoints.\n */\nexport const eventBus = new Proxy(\n {},\n {\n get(_target, prop: PropertyKey) {\n const inst = GlobalEventBus.getInstance();\n const val = (inst as unknown as Record<PropertyKey, unknown>)[prop];\n // If the property is a function (method), bind it to the instance\n // so callers using `eventBus.method(...)` get the correct `this`.\n if (typeof val === 'function')\n return (val as (...args: unknown[]) => unknown).bind(inst);\n return val;\n },\n apply() {\n throw new TypeError('eventBus is not a callable function');\n },\n },\n) as unknown as GlobalEventBus;\n\n/**\n * Emit a global event\n */\nexport const emit = <T = unknown>(eventName: string, data?: T) =>\n eventBus.emit(eventName, data);\n\n/**\n * Register a handler for a global event\n */\nexport const on = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.on(eventName, handler);\n\n/**\n * Remove a handler for a global event\n */\nexport const off = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.off(eventName, handler);\n\n/**\n * Register a one-time handler for a global event (callback form).\n * The handler fires once then auto-unsubscribes.\n */\nexport function once<T = unknown>(\n eventName: string,\n handler: EventHandler<T>,\n): void;\n/**\n * Returns a Promise that resolves with the next emission of the event\n * (Promise form — no handler argument needed).\n */\nexport function once<T = unknown>(eventName: string): Promise<T>;\nexport function once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n): void | Promise<T> {\n if (handler !== undefined) {\n return eventBus.once(eventName, handler);\n }\n return eventBus.once<T>(eventName);\n}\n\n/**\n * Listen for a native CustomEvent\n */\nexport const listen = <T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n) => eventBus.listen(eventName, handler, options);\n"],"mappings":"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"}
|
|
@@ -1,80 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
class
|
|
1
|
+
import { t as a } from "./logger-L25axmB-.js";
|
|
2
|
+
var h = class o extends EventTarget {
|
|
3
3
|
handlers = {};
|
|
4
4
|
static instance;
|
|
5
5
|
eventCounters = /* @__PURE__ */ new Map();
|
|
6
6
|
nativeUnsubscribers = /* @__PURE__ */ new Map();
|
|
7
7
|
MAX_EVENT_COUNTERS = 1e3;
|
|
8
|
-
/**
|
|
9
|
-
* Returns the singleton instance of GlobalEventBus
|
|
10
|
-
*/
|
|
11
8
|
static getInstance() {
|
|
12
|
-
return
|
|
9
|
+
return o.instance || (o.instance = new o()), o.instance;
|
|
13
10
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Emit a global event with optional data. Includes event storm protection.
|
|
16
|
-
* @param eventName - Name of the event
|
|
17
|
-
* @param data - Optional event payload
|
|
18
|
-
*/
|
|
19
11
|
emit(t, e) {
|
|
20
12
|
const n = Date.now(), s = this.eventCounters.get(t);
|
|
21
13
|
if (!s || n - s.window > 1e3) {
|
|
22
14
|
if (!s && this.eventCounters.size >= this.MAX_EVENT_COUNTERS) {
|
|
23
|
-
const
|
|
24
|
-
|
|
15
|
+
const c = this.eventCounters.keys().next().value;
|
|
16
|
+
c !== void 0 && this.eventCounters.delete(c);
|
|
25
17
|
}
|
|
26
|
-
this.eventCounters.set(t, {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.dispatchEvent(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
const c = this.handlers[t];
|
|
40
|
-
c && c.forEach((u) => {
|
|
18
|
+
this.eventCounters.set(t, {
|
|
19
|
+
count: 1,
|
|
20
|
+
window: n
|
|
21
|
+
});
|
|
22
|
+
} else if (s.count++, s.count === 51 && a(`[EventBus] Event "${t}" is firing too frequently (>${s.count - 1}/s). Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. Consider debouncing the emitter.`), s.count > 100) return;
|
|
23
|
+
this.dispatchEvent(new CustomEvent(t, {
|
|
24
|
+
detail: e,
|
|
25
|
+
bubbles: !1,
|
|
26
|
+
cancelable: !0
|
|
27
|
+
}));
|
|
28
|
+
const u = this.handlers[t];
|
|
29
|
+
u && u.forEach((c) => {
|
|
41
30
|
try {
|
|
42
|
-
|
|
43
|
-
} catch (
|
|
44
|
-
|
|
31
|
+
c(e);
|
|
32
|
+
} catch (l) {
|
|
33
|
+
a(`Error in global event handler for "${t}":`, l);
|
|
45
34
|
}
|
|
46
35
|
});
|
|
47
36
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Register a handler for a global event. Returns an unsubscribe function.
|
|
50
|
-
* @param eventName - Name of the event
|
|
51
|
-
* @param handler - Handler function
|
|
52
|
-
*/
|
|
53
37
|
on(t, e) {
|
|
54
38
|
return this.handlers[t] || (this.handlers[t] = /* @__PURE__ */ new Set()), this.handlers[t].add(e), () => this.off(t, e);
|
|
55
39
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Remove a specific handler for a global event.
|
|
58
|
-
* @param eventName - Name of the event
|
|
59
|
-
* @param handler - Handler function to remove
|
|
60
|
-
*/
|
|
61
40
|
off(t, e) {
|
|
62
41
|
const n = this.handlers[t];
|
|
63
42
|
n && (n.delete(e), n.size === 0 && delete this.handlers[t]);
|
|
64
43
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Remove all handlers for a specific event.
|
|
67
|
-
* @param eventName - Name of the event
|
|
68
|
-
*/
|
|
69
44
|
offAll(t) {
|
|
70
45
|
delete this.handlers[t];
|
|
71
46
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Listen for a native CustomEvent. Returns an unsubscribe function.
|
|
74
|
-
* @param eventName - Name of the event
|
|
75
|
-
* @param handler - CustomEvent handler
|
|
76
|
-
* @param options - AddEventListener options
|
|
77
|
-
*/
|
|
78
47
|
listen(t, e, n) {
|
|
79
48
|
this.addEventListener(t, e, n);
|
|
80
49
|
const s = () => {
|
|
@@ -87,80 +56,56 @@ class i extends EventTarget {
|
|
|
87
56
|
const n = this.on(t, (s) => {
|
|
88
57
|
n(), e(s);
|
|
89
58
|
});
|
|
90
|
-
} else
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
s(), n(c);
|
|
94
|
-
});
|
|
59
|
+
} else return new Promise((n) => {
|
|
60
|
+
const s = this.on(t, (u) => {
|
|
61
|
+
s(), n(u);
|
|
95
62
|
});
|
|
63
|
+
});
|
|
96
64
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Get a list of all active event names with registered handlers.
|
|
99
|
-
*/
|
|
100
65
|
getActiveEvents() {
|
|
101
|
-
return Object.keys(this.handlers).filter(
|
|
102
|
-
(t) => this.handlers[t] && this.handlers[t].size > 0
|
|
103
|
-
);
|
|
66
|
+
return Object.keys(this.handlers).filter((t) => this.handlers[t] && this.handlers[t].size > 0);
|
|
104
67
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Clear all event handlers and native EventTarget listeners (useful for testing or cleanup).
|
|
107
|
-
*/
|
|
108
68
|
clear() {
|
|
109
69
|
this.handlers = {};
|
|
110
70
|
const t = Array.from(this.nativeUnsubscribers.keys());
|
|
111
71
|
this.nativeUnsubscribers.clear();
|
|
112
|
-
for (const e of t)
|
|
113
|
-
e();
|
|
72
|
+
for (const e of t) e();
|
|
114
73
|
}
|
|
115
|
-
/**
|
|
116
|
-
* Get the number of handlers registered for a specific event.
|
|
117
|
-
* @param eventName - Name of the event
|
|
118
|
-
*/
|
|
119
74
|
getHandlerCount(t) {
|
|
120
75
|
return this.handlers[t]?.size || 0;
|
|
121
76
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Get event statistics for debugging.
|
|
124
|
-
*/
|
|
125
77
|
getEventStats() {
|
|
126
78
|
const t = {};
|
|
127
|
-
for (const [e, n] of this.eventCounters.entries())
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
};
|
|
79
|
+
for (const [e, n] of this.eventCounters.entries()) t[e] = {
|
|
80
|
+
count: n.count,
|
|
81
|
+
handlersCount: this.getHandlerCount(e)
|
|
82
|
+
};
|
|
132
83
|
return t;
|
|
133
84
|
}
|
|
134
|
-
/**
|
|
135
|
-
* Reset event counters (useful for testing or after resolving issues).
|
|
136
|
-
*/
|
|
137
85
|
resetEventCounters() {
|
|
138
86
|
this.eventCounters.clear();
|
|
139
87
|
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
},
|
|
148
|
-
apply() {
|
|
149
|
-
throw new TypeError("eventBus is not a callable function");
|
|
150
|
-
}
|
|
88
|
+
}, i = new Proxy({}, {
|
|
89
|
+
get(r, t) {
|
|
90
|
+
const e = h.getInstance(), n = e[t];
|
|
91
|
+
return typeof n == "function" ? n.bind(e) : n;
|
|
92
|
+
},
|
|
93
|
+
apply() {
|
|
94
|
+
throw new TypeError("eventBus is not a callable function");
|
|
151
95
|
}
|
|
152
|
-
), d = (r, t) =>
|
|
153
|
-
function
|
|
154
|
-
return t !== void 0 ?
|
|
96
|
+
}), d = (r, t) => i.emit(r, t), v = (r, t) => i.on(r, t), b = (r, t) => i.off(r, t);
|
|
97
|
+
function E(r, t) {
|
|
98
|
+
return t !== void 0 ? i.once(r, t) : i.once(r);
|
|
155
99
|
}
|
|
156
|
-
|
|
100
|
+
var C = (r, t, e) => i.listen(r, t, e);
|
|
157
101
|
export {
|
|
158
|
-
|
|
102
|
+
h as GlobalEventBus,
|
|
159
103
|
d as emit,
|
|
160
|
-
|
|
161
|
-
|
|
104
|
+
i as eventBus,
|
|
105
|
+
C as listen,
|
|
162
106
|
b as off,
|
|
163
|
-
|
|
164
|
-
|
|
107
|
+
v as on,
|
|
108
|
+
E as once
|
|
165
109
|
};
|
|
166
|
-
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=custom-elements-runtime.event-bus.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.event-bus.es.js","sources":["../src/lib/event-bus.ts"],"sourcesContent":["/**\n * Event handler type for global event bus\n */\nexport type EventHandler<T> = (data: T) => void;\n\nimport { devError } from './runtime/logger';\n\n/**\n * Event map type using Set for efficient handler management\n */\ntype EventMap<Events extends Record<string, unknown>> = {\n [K in keyof Events]: Set<EventHandler<Events[K]>>;\n};\n\n/**\n * GlobalEventBus provides a singleton event bus for cross-component communication.\n * Uses Set for handler storage to optimize add/remove operations and prevent duplicates.\n */\nexport class GlobalEventBus extends EventTarget {\n private handlers: EventMap<Record<string, unknown>> = {};\n private static instance: GlobalEventBus;\n private eventCounters: Map<string, { count: number; window: number }> =\n new Map();\n private nativeUnsubscribers: Map<() => void, true> = new Map();\n private readonly MAX_EVENT_COUNTERS = 1000;\n\n /**\n * Returns the singleton instance of GlobalEventBus\n */\n static getInstance(): GlobalEventBus {\n if (!GlobalEventBus.instance) {\n GlobalEventBus.instance = new GlobalEventBus();\n }\n return GlobalEventBus.instance;\n }\n\n /**\n * Emit a global event with optional data. Includes event storm protection.\n * @param eventName - Name of the event\n * @param data - Optional event payload\n */\n emit<T = unknown>(eventName: string, data?: T): void {\n // Event storm protection\n const now = Date.now();\n const counter = this.eventCounters.get(eventName);\n\n if (!counter || now - counter.window > 1000) {\n // Evict oldest entry if the map is at capacity to prevent unbounded growth.\n if (!counter && this.eventCounters.size >= this.MAX_EVENT_COUNTERS) {\n const firstKey = this.eventCounters.keys().next().value;\n if (firstKey !== undefined) this.eventCounters.delete(firstKey);\n }\n // Reset counter every second\n this.eventCounters.set(eventName, { count: 1, window: now });\n } else {\n counter.count++;\n\n if (counter.count === 51) {\n // Warn once at the throttle threshold so developers know emissions are being dropped.\n devError(\n `[EventBus] Event \"${eventName}\" is firing too frequently (>${counter.count - 1}/s). ` +\n 'Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. ' +\n 'Consider debouncing the emitter.',\n );\n }\n if (counter.count > 100) {\n // Drop the event to protect against runaway event storms.\n return;\n }\n }\n\n // Use native CustomEvent for better browser integration\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: data,\n bubbles: false, // Global events don't need to bubble\n cancelable: true,\n }),\n );\n\n // Also trigger registered handlers\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n devError(`Error in global event handler for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Register a handler for a global event. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n on<T = unknown>(eventName: string, handler: EventHandler<T>): () => void {\n if (!this.handlers[eventName]) {\n this.handlers[eventName] = new Set<EventHandler<unknown>>();\n }\n this.handlers[eventName].add(handler as EventHandler<unknown>);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Remove a specific handler for a global event.\n * @param eventName - Name of the event\n * @param handler - Handler function to remove\n */\n off<T = unknown>(eventName: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n // Remove the entry entirely once it is empty so stale keys don't\n // accumulate indefinitely in long-lived apps.\n if (eventHandlers.size === 0) {\n delete this.handlers[eventName];\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event.\n * @param eventName - Name of the event\n */\n offAll(eventName: string): void {\n delete this.handlers[eventName];\n }\n\n /**\n * Listen for a native CustomEvent. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - CustomEvent handler\n * @param options - AddEventListener options\n */\n listen<T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n ): () => void {\n this.addEventListener(eventName, handler as EventListener, options);\n // Use a wrapper so calling unsubscribe also removes it from nativeUnsubscribers,\n // preventing indefinite accumulation in long-lived apps.\n const unsubscribe: () => void = () => {\n this.removeEventListener(eventName, handler as EventListener);\n this.nativeUnsubscribers.delete(unsubscribe);\n };\n this.nativeUnsubscribers.set(unsubscribe, true);\n return unsubscribe;\n }\n\n /**\n * Register a one-time event handler (callback form).\n * The handler is invoked exactly once, then automatically unsubscribed.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n once<T = unknown>(eventName: string, handler: EventHandler<T>): void;\n /**\n * Returns a Promise that resolves with the first emission of the event\n * (Promise form — no handler argument).\n * @param eventName - Name of the event\n */\n once<T = unknown>(eventName: string): Promise<T>;\n once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n ): void | Promise<T> {\n if (handler !== undefined) {\n // Callback form: fire-and-forget, returns void\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n handler(data);\n });\n } else {\n // Promise form: resolves on first emission\n return new Promise<T>((resolve) => {\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n resolve(data);\n });\n });\n }\n }\n\n /**\n * Get a list of all active event names with registered handlers.\n */\n getActiveEvents(): string[] {\n return Object.keys(this.handlers).filter(\n (eventName) =>\n this.handlers[eventName] && this.handlers[eventName].size > 0,\n );\n }\n\n /**\n * Clear all event handlers and native EventTarget listeners (useful for testing or cleanup).\n */\n clear(): void {\n this.handlers = {};\n const toCleanup = Array.from(this.nativeUnsubscribers.keys());\n this.nativeUnsubscribers.clear();\n for (const unsubscribe of toCleanup) {\n unsubscribe();\n }\n }\n\n /**\n * Get the number of handlers registered for a specific event.\n * @param eventName - Name of the event\n */\n getHandlerCount(eventName: string): number {\n return this.handlers[eventName]?.size || 0;\n }\n\n /**\n * Get event statistics for debugging.\n */\n getEventStats(): Record<string, { count: number; handlersCount: number }> {\n const stats: Record<string, { count: number; handlersCount: number }> = {};\n for (const [eventName, counter] of this.eventCounters.entries()) {\n stats[eventName] = {\n count: counter.count,\n handlersCount: this.getHandlerCount(eventName),\n };\n }\n return stats;\n }\n\n /**\n * Reset event counters (useful for testing or after resolving issues).\n */\n resetEventCounters(): void {\n this.eventCounters.clear();\n }\n}\n\n/**\n * Singleton instance of the global event bus\n */\n/**\n * Lazily-instantiated event bus.\n *\n * We preserve the `eventBus` export for backward compatibility but avoid\n * creating the underlying GlobalEventBus instance at module import time.\n * A small proxy defers the call to `GlobalEventBus.getInstance()` until a\n * property is accessed. This reduces import-time side-effects and helps\n * bundlers tree-shake unused entrypoints.\n */\nexport const eventBus = new Proxy(\n {},\n {\n get(_target, prop: PropertyKey) {\n const inst = GlobalEventBus.getInstance();\n const val = (inst as unknown as Record<PropertyKey, unknown>)[prop];\n // If the property is a function (method), bind it to the instance\n // so callers using `eventBus.method(...)` get the correct `this`.\n if (typeof val === 'function')\n return (val as (...args: unknown[]) => unknown).bind(inst);\n return val;\n },\n apply() {\n throw new TypeError('eventBus is not a callable function');\n },\n },\n) as unknown as GlobalEventBus;\n\n/**\n * Emit a global event\n */\nexport const emit = <T = unknown>(eventName: string, data?: T) =>\n eventBus.emit(eventName, data);\n\n/**\n * Register a handler for a global event\n */\nexport const on = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.on(eventName, handler);\n\n/**\n * Remove a handler for a global event\n */\nexport const off = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.off(eventName, handler);\n\n/**\n * Register a one-time handler for a global event (callback form).\n * The handler fires once then auto-unsubscribes.\n */\nexport function once<T = unknown>(\n eventName: string,\n handler: EventHandler<T>,\n): void;\n/**\n * Returns a Promise that resolves with the next emission of the event\n * (Promise form — no handler argument needed).\n */\nexport function once<T = unknown>(eventName: string): Promise<T>;\nexport function once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n): void | Promise<T> {\n if (handler !== undefined) {\n return eventBus.once(eventName, handler);\n }\n return eventBus.once<T>(eventName);\n}\n\n/**\n * Listen for a native CustomEvent\n */\nexport const listen = <T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n) => eventBus.listen(eventName, handler, options);\n"],"names":["GlobalEventBus","eventName","data","now","counter","firstKey","devError","eventHandlers","handler","error","options","unsubscribe","resolve","toCleanup","stats","eventBus","_target","prop","inst","val","emit","on","off","once","listen"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.event-bus.es.js","names":[],"sources":["../src/lib/event-bus.ts"],"sourcesContent":["/**\n * Event handler type for global event bus\n */\nexport type EventHandler<T> = (data: T) => void;\n\nimport { devError } from './runtime/logger';\n\n/**\n * Event map type using Set for efficient handler management\n */\ntype EventMap<Events extends Record<string, unknown>> = {\n [K in keyof Events]: Set<EventHandler<Events[K]>>;\n};\n\n/**\n * GlobalEventBus provides a singleton event bus for cross-component communication.\n * Uses Set for handler storage to optimize add/remove operations and prevent duplicates.\n */\nexport class GlobalEventBus extends EventTarget {\n private handlers: EventMap<Record<string, unknown>> = {};\n private static instance: GlobalEventBus;\n private eventCounters: Map<string, { count: number; window: number }> =\n new Map();\n private nativeUnsubscribers: Map<() => void, true> = new Map();\n private readonly MAX_EVENT_COUNTERS = 1000;\n\n /**\n * Returns the singleton instance of GlobalEventBus\n */\n static getInstance(): GlobalEventBus {\n if (!GlobalEventBus.instance) {\n GlobalEventBus.instance = new GlobalEventBus();\n }\n return GlobalEventBus.instance;\n }\n\n /**\n * Emit a global event with optional data. Includes event storm protection.\n * @param eventName - Name of the event\n * @param data - Optional event payload\n */\n emit<T = unknown>(eventName: string, data?: T): void {\n // Event storm protection\n const now = Date.now();\n const counter = this.eventCounters.get(eventName);\n\n if (!counter || now - counter.window > 1000) {\n // Evict oldest entry if the map is at capacity to prevent unbounded growth.\n if (!counter && this.eventCounters.size >= this.MAX_EVENT_COUNTERS) {\n const firstKey = this.eventCounters.keys().next().value;\n if (firstKey !== undefined) this.eventCounters.delete(firstKey);\n }\n // Reset counter every second\n this.eventCounters.set(eventName, { count: 1, window: now });\n } else {\n counter.count++;\n\n if (counter.count === 51) {\n // Warn once at the throttle threshold so developers know emissions are being dropped.\n devError(\n `[EventBus] Event \"${eventName}\" is firing too frequently (>${counter.count - 1}/s). ` +\n 'Emissions above 50/s are throttled and above 100/s are dropped to prevent event storms. ' +\n 'Consider debouncing the emitter.',\n );\n }\n if (counter.count > 100) {\n // Drop the event to protect against runaway event storms.\n return;\n }\n }\n\n // Use native CustomEvent for better browser integration\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: data,\n bubbles: false, // Global events don't need to bubble\n cancelable: true,\n }),\n );\n\n // Also trigger registered handlers\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n devError(`Error in global event handler for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Register a handler for a global event. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n on<T = unknown>(eventName: string, handler: EventHandler<T>): () => void {\n if (!this.handlers[eventName]) {\n this.handlers[eventName] = new Set<EventHandler<unknown>>();\n }\n this.handlers[eventName].add(handler as EventHandler<unknown>);\n return () => this.off(eventName, handler);\n }\n\n /**\n * Remove a specific handler for a global event.\n * @param eventName - Name of the event\n * @param handler - Handler function to remove\n */\n off<T = unknown>(eventName: string, handler: EventHandler<T>): void {\n const eventHandlers = this.handlers[eventName];\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n // Remove the entry entirely once it is empty so stale keys don't\n // accumulate indefinitely in long-lived apps.\n if (eventHandlers.size === 0) {\n delete this.handlers[eventName];\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event.\n * @param eventName - Name of the event\n */\n offAll(eventName: string): void {\n delete this.handlers[eventName];\n }\n\n /**\n * Listen for a native CustomEvent. Returns an unsubscribe function.\n * @param eventName - Name of the event\n * @param handler - CustomEvent handler\n * @param options - AddEventListener options\n */\n listen<T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n ): () => void {\n this.addEventListener(eventName, handler as EventListener, options);\n // Use a wrapper so calling unsubscribe also removes it from nativeUnsubscribers,\n // preventing indefinite accumulation in long-lived apps.\n const unsubscribe: () => void = () => {\n this.removeEventListener(eventName, handler as EventListener);\n this.nativeUnsubscribers.delete(unsubscribe);\n };\n this.nativeUnsubscribers.set(unsubscribe, true);\n return unsubscribe;\n }\n\n /**\n * Register a one-time event handler (callback form).\n * The handler is invoked exactly once, then automatically unsubscribed.\n * @param eventName - Name of the event\n * @param handler - Handler function\n */\n once<T = unknown>(eventName: string, handler: EventHandler<T>): void;\n /**\n * Returns a Promise that resolves with the first emission of the event\n * (Promise form — no handler argument).\n * @param eventName - Name of the event\n */\n once<T = unknown>(eventName: string): Promise<T>;\n once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n ): void | Promise<T> {\n if (handler !== undefined) {\n // Callback form: fire-and-forget, returns void\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n handler(data);\n });\n } else {\n // Promise form: resolves on first emission\n return new Promise<T>((resolve) => {\n const unsubscribe = this.on(eventName, (data: T) => {\n unsubscribe();\n resolve(data);\n });\n });\n }\n }\n\n /**\n * Get a list of all active event names with registered handlers.\n */\n getActiveEvents(): string[] {\n return Object.keys(this.handlers).filter(\n (eventName) =>\n this.handlers[eventName] && this.handlers[eventName].size > 0,\n );\n }\n\n /**\n * Clear all event handlers and native EventTarget listeners (useful for testing or cleanup).\n */\n clear(): void {\n this.handlers = {};\n const toCleanup = Array.from(this.nativeUnsubscribers.keys());\n this.nativeUnsubscribers.clear();\n for (const unsubscribe of toCleanup) {\n unsubscribe();\n }\n }\n\n /**\n * Get the number of handlers registered for a specific event.\n * @param eventName - Name of the event\n */\n getHandlerCount(eventName: string): number {\n return this.handlers[eventName]?.size || 0;\n }\n\n /**\n * Get event statistics for debugging.\n */\n getEventStats(): Record<string, { count: number; handlersCount: number }> {\n const stats: Record<string, { count: number; handlersCount: number }> = {};\n for (const [eventName, counter] of this.eventCounters.entries()) {\n stats[eventName] = {\n count: counter.count,\n handlersCount: this.getHandlerCount(eventName),\n };\n }\n return stats;\n }\n\n /**\n * Reset event counters (useful for testing or after resolving issues).\n */\n resetEventCounters(): void {\n this.eventCounters.clear();\n }\n}\n\n/**\n * Singleton instance of the global event bus\n */\n/**\n * Lazily-instantiated event bus.\n *\n * We preserve the `eventBus` export for backward compatibility but avoid\n * creating the underlying GlobalEventBus instance at module import time.\n * A small proxy defers the call to `GlobalEventBus.getInstance()` until a\n * property is accessed. This reduces import-time side-effects and helps\n * bundlers tree-shake unused entrypoints.\n */\nexport const eventBus = new Proxy(\n {},\n {\n get(_target, prop: PropertyKey) {\n const inst = GlobalEventBus.getInstance();\n const val = (inst as unknown as Record<PropertyKey, unknown>)[prop];\n // If the property is a function (method), bind it to the instance\n // so callers using `eventBus.method(...)` get the correct `this`.\n if (typeof val === 'function')\n return (val as (...args: unknown[]) => unknown).bind(inst);\n return val;\n },\n apply() {\n throw new TypeError('eventBus is not a callable function');\n },\n },\n) as unknown as GlobalEventBus;\n\n/**\n * Emit a global event\n */\nexport const emit = <T = unknown>(eventName: string, data?: T) =>\n eventBus.emit(eventName, data);\n\n/**\n * Register a handler for a global event\n */\nexport const on = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.on(eventName, handler);\n\n/**\n * Remove a handler for a global event\n */\nexport const off = <T = unknown>(eventName: string, handler: EventHandler<T>) =>\n eventBus.off(eventName, handler);\n\n/**\n * Register a one-time handler for a global event (callback form).\n * The handler fires once then auto-unsubscribes.\n */\nexport function once<T = unknown>(\n eventName: string,\n handler: EventHandler<T>,\n): void;\n/**\n * Returns a Promise that resolves with the next emission of the event\n * (Promise form — no handler argument needed).\n */\nexport function once<T = unknown>(eventName: string): Promise<T>;\nexport function once<T = unknown>(\n eventName: string,\n handler?: EventHandler<T>,\n): void | Promise<T> {\n if (handler !== undefined) {\n return eventBus.once(eventName, handler);\n }\n return eventBus.once<T>(eventName);\n}\n\n/**\n * Listen for a native CustomEvent\n */\nexport const listen = <T = unknown>(\n eventName: string,\n handler: (event: CustomEvent<T>) => void,\n options?: AddEventListenerOptions,\n) => eventBus.listen(eventName, handler, options);\n"],"mappings":"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"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./hooks-fYQgZk2g.cjs"),e=require("./style-Bjn8zDiZ.cjs");function o(r){if(s.isDiscoveryRender$1())return;const t=s.getCurrentComponentContext()?._host?.shadowRoot??null;t?e.registerJITCSSComponent(t,r):e.enableJITCSS(r)}function a(r){return r}exports.cls=a;exports.colors=e.colors;exports.containerVariants=e.containerVariants;exports.disableJITCSS=e.disableJITCSS;exports.enableJITCSS=e.enableJITCSS;exports.extractClassesFromHTML=e.extractClassesFromHTML;exports.getJITCSSOptions=e.getJITCSSOptions;exports.isJITCSSEnabled=e.isJITCSSEnabled;exports.isJITCSSEnabledFor=e.isJITCSSEnabledFor;exports.jitCSS=e.jitCSS;exports.mediaVariants=e.mediaVariants;exports.parseArbitrary=e.parseArbitrary;exports.parseColorClass=e.parseColorClass;exports.parseColorWithOpacity=e.parseColorWithOpacity;exports.parseGradientColorStop=e.parseGradientColorStop;exports.parseSpacing=e.parseSpacing;exports.registerJITCSSComponent=e.registerJITCSSComponent;exports.selectorVariants=e.selectorVariants;exports.useDesignTokens=s.useDesignTokens;exports.useGlobalStyle=s.useGlobalStyle;exports.useJITCSS=o;exports.utilityMap=e.utilityMap;
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=custom-elements-runtime.jit-css.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.jit-css.cjs.js","sources":["../src/lib/runtime/jit-hooks.ts","../src/lib/jit-css.ts"],"sourcesContent":["/**\n * JIT CSS hooks — lives in a separate module so that hooks.ts does not\n * statically import style.ts. Consumers who never call `useJITCSS` will\n * have the entire JIT engine tree-shaken out of their bundle.\n */\n\nimport { isDiscoveryRender as _isDiscoveryRenderFn } from './discovery-state';\nimport { getCurrentComponentContext } from './hooks';\nimport {\n enableJITCSS,\n registerJITCSSComponent,\n type JITCSSOptions,\n} from './style';\n\n/**\n * Configure the JIT CSS engine for the current session.\n * This is a convenience wrapper around `enableJITCSS()` that can be called\n * inside a component render function or at module initialisation time.\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * // Enable extended Tailwind colors so bg-blue-500, text-violet-700, etc. generate CSS\n * useJITCSS({ extendedColors: true });\n * return html`<div class=\"bg-blue-500 text-white\">Hello</div>`;\n * });\n * ```\n *\n * @example\n * ```ts\n * // At app entry – enable once for all components\n * useJITCSS({ extendedColors: true, customColors: { brand: { '500': '#e63946' } } });\n * ```\n */\nexport function useJITCSS(options?: JITCSSOptions): void {\n // During discovery renders (component registration phase) there is no real\n // shadow root. Without this guard, useJITCSS() falls through to\n // enableJITCSS() and globally enables JIT CSS for every component — exactly\n // the opt-in behaviour we are trying to prevent.\n if (_isDiscoveryRenderFn()) return;\n\n // When called inside a component render function, register this component's\n // shadow root for per-component JIT CSS opt-in. Context is always set during\n // a real render; it may be absent (null) or missing _host when called at app\n // startup level (outside any component context).\n const host = (getCurrentComponentContext() as { _host?: Element } | null)\n ?._host;\n const shadowRoot = host?.shadowRoot ?? null;\n\n if (shadowRoot) {\n // Per-component opt-in: register this shadow root only.\n registerJITCSSComponent(shadowRoot, options);\n } else {\n // App-level call (outside component context) — enable for all components\n // globally, preserving v2 behaviour when called at the entry point.\n enableJITCSS(options);\n }\n}\n\nexport type { JITCSSOptions };\n","/**\n * JIT CSS entry point — opt-in import for the full JIT CSS engine.\n *\n * @example\n * ```ts\n * import {\n * useJITCSS,\n * enableJITCSS,\n * } from '@jasonshimmy/custom-elements-runtime/jit-css';\n * ```\n */\n\n// Hooks\nexport { useJITCSS } from './runtime/jit-hooks';\nexport { useDesignTokens, useGlobalStyle } from './runtime/hooks';\nexport type { JITCSSOptions, DesignTokens } from './runtime/hooks';\n\n// Global configuration\nexport {\n enableJITCSS,\n disableJITCSS,\n isJITCSSEnabled,\n isJITCSSEnabledFor,\n registerJITCSSComponent,\n getJITCSSOptions,\n jitCSS,\n extractClassesFromHTML,\n parseColorClass,\n parseColorWithOpacity,\n parseGradientColorStop,\n parseSpacing,\n parseArbitrary,\n utilityMap,\n selectorVariants,\n mediaVariants,\n containerVariants,\n colors,\n} from './runtime/style';\n\n/**\n * A no-op identity function that signals to development tools (IDE\n * autocomplete, linters, PurgeCSS-style scanners) that the string contains\n * JIT CSS utility class names.\n *\n * At runtime this is simply `return className` — zero overhead.\n *\n * @example\n * ```ts\n * import { cls } from '@jasonshimmy/custom-elements-runtime/jit-css';\n *\n * const containerClasses = cls('flex items-center gap-4 bg-primary-500 text-white');\n * ```\n */\nexport function cls(className: string): string {\n return className;\n}\n"],"
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.jit-css.cjs.js","names":[],"sources":["../src/lib/runtime/jit-hooks.ts","../src/lib/jit-css.ts"],"sourcesContent":["/**\n * JIT CSS hooks — lives in a separate module so that hooks.ts does not\n * statically import style.ts. Consumers who never call `useJITCSS` will\n * have the entire JIT engine tree-shaken out of their bundle.\n */\n\nimport { isDiscoveryRender as _isDiscoveryRenderFn } from './discovery-state';\nimport { getCurrentComponentContext } from './hooks';\nimport {\n enableJITCSS,\n registerJITCSSComponent,\n type JITCSSOptions,\n} from './style';\n\n/**\n * Configure the JIT CSS engine for the current session.\n * This is a convenience wrapper around `enableJITCSS()` that can be called\n * inside a component render function or at module initialisation time.\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * // Enable extended Tailwind colors so bg-blue-500, text-violet-700, etc. generate CSS\n * useJITCSS({ extendedColors: true });\n * return html`<div class=\"bg-blue-500 text-white\">Hello</div>`;\n * });\n * ```\n *\n * @example\n * ```ts\n * // At app entry – enable once for all components\n * useJITCSS({ extendedColors: true, customColors: { brand: { '500': '#e63946' } } });\n * ```\n */\nexport function useJITCSS(options?: JITCSSOptions): void {\n // During discovery renders (component registration phase) there is no real\n // shadow root. Without this guard, useJITCSS() falls through to\n // enableJITCSS() and globally enables JIT CSS for every component — exactly\n // the opt-in behaviour we are trying to prevent.\n if (_isDiscoveryRenderFn()) return;\n\n // When called inside a component render function, register this component's\n // shadow root for per-component JIT CSS opt-in. Context is always set during\n // a real render; it may be absent (null) or missing _host when called at app\n // startup level (outside any component context).\n const host = (getCurrentComponentContext() as { _host?: Element } | null)\n ?._host;\n const shadowRoot = host?.shadowRoot ?? null;\n\n if (shadowRoot) {\n // Per-component opt-in: register this shadow root only.\n registerJITCSSComponent(shadowRoot, options);\n } else {\n // App-level call (outside component context) — enable for all components\n // globally, preserving v2 behaviour when called at the entry point.\n enableJITCSS(options);\n }\n}\n\nexport type { JITCSSOptions };\n","/**\n * JIT CSS entry point — opt-in import for the full JIT CSS engine.\n *\n * @example\n * ```ts\n * import {\n * useJITCSS,\n * enableJITCSS,\n * } from '@jasonshimmy/custom-elements-runtime/jit-css';\n * ```\n */\n\n// Hooks\nexport { useJITCSS } from './runtime/jit-hooks';\nexport { useDesignTokens, useGlobalStyle } from './runtime/hooks';\nexport type { JITCSSOptions, DesignTokens } from './runtime/hooks';\n\n// Global configuration\nexport {\n enableJITCSS,\n disableJITCSS,\n isJITCSSEnabled,\n isJITCSSEnabledFor,\n registerJITCSSComponent,\n getJITCSSOptions,\n jitCSS,\n extractClassesFromHTML,\n parseColorClass,\n parseColorWithOpacity,\n parseGradientColorStop,\n parseSpacing,\n parseArbitrary,\n utilityMap,\n selectorVariants,\n mediaVariants,\n containerVariants,\n colors,\n} from './runtime/style';\n\n/**\n * A no-op identity function that signals to development tools (IDE\n * autocomplete, linters, PurgeCSS-style scanners) that the string contains\n * JIT CSS utility class names.\n *\n * At runtime this is simply `return className` — zero overhead.\n *\n * @example\n * ```ts\n * import { cls } from '@jasonshimmy/custom-elements-runtime/jit-css';\n *\n * const containerClasses = cls('flex items-center gap-4 bg-primary-500 text-white');\n * ```\n */\nexport function cls(className: string): string {\n return className;\n}\n"],"mappings":"6IAkCA,SAAgB,EAAU,EAA+B,CAKvD,GAAI,EAAA,oBAAA,EAAwB,OAQ5B,MAAM,EAFQ,EAAA,2BAAA,GACV,OACqB,YAAc,KAEnC,EAEF,EAAA,wBAAwB,EAAY,CAAA,EAIpC,EAAA,aAAa,CAAA,ECFjB,SAAgB,EAAI,EAA2B,CAC7C,OAAO"}
|
|
@@ -1,37 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { o as m, t as u } from "./
|
|
3
|
-
|
|
4
|
-
import { c as f, a as T, d as b, b as g, g as h, i as I, f as J, j as x, m as y, p as R, h as V, k as j, l as k, n as w, s as D, u as E } from "./style-BmyOIMcU.js";
|
|
5
|
-
function S(s) {
|
|
1
|
+
import { K as e, f as n, i as r, l } from "./hooks-_3xP4G2N.js";
|
|
2
|
+
import { _ as C, a as p, c, d as u, f as d, g as o, h as m, i as t, l as T, m as f, n as I, o as J, p as b, r as g, s as h, t as y, u as x, v as R } from "./style-DuDoj_xK.js";
|
|
3
|
+
function V(s) {
|
|
6
4
|
if (e()) return;
|
|
7
|
-
const a =
|
|
8
|
-
a ?
|
|
5
|
+
const a = r()?._host?.shadowRoot ?? null;
|
|
6
|
+
a ? o(a, s) : t(s);
|
|
9
7
|
}
|
|
10
|
-
function
|
|
8
|
+
function v(s) {
|
|
11
9
|
return s;
|
|
12
10
|
}
|
|
13
11
|
export {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
v as cls,
|
|
13
|
+
y as colors,
|
|
14
|
+
I as containerVariants,
|
|
15
|
+
g as disableJITCSS,
|
|
18
16
|
t as enableJITCSS,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
p as extractClassesFromHTML,
|
|
18
|
+
J as getJITCSSOptions,
|
|
19
|
+
h as isJITCSSEnabled,
|
|
20
|
+
c as isJITCSSEnabledFor,
|
|
21
|
+
T as jitCSS,
|
|
22
|
+
x as mediaVariants,
|
|
23
|
+
u as parseArbitrary,
|
|
24
|
+
d as parseColorClass,
|
|
25
|
+
b as parseColorWithOpacity,
|
|
26
|
+
f as parseGradientColorStop,
|
|
27
|
+
m as parseSpacing,
|
|
28
|
+
o as registerJITCSSComponent,
|
|
29
|
+
C as selectorVariants,
|
|
30
|
+
l as useDesignTokens,
|
|
31
|
+
n as useGlobalStyle,
|
|
32
|
+
V as useJITCSS,
|
|
33
|
+
R as utilityMap
|
|
36
34
|
};
|
|
37
|
-
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=custom-elements-runtime.jit-css.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-elements-runtime.jit-css.es.js","sources":["../src/lib/runtime/jit-hooks.ts","../src/lib/jit-css.ts"],"sourcesContent":["/**\n * JIT CSS hooks — lives in a separate module so that hooks.ts does not\n * statically import style.ts. Consumers who never call `useJITCSS` will\n * have the entire JIT engine tree-shaken out of their bundle.\n */\n\nimport { isDiscoveryRender as _isDiscoveryRenderFn } from './discovery-state';\nimport { getCurrentComponentContext } from './hooks';\nimport {\n enableJITCSS,\n registerJITCSSComponent,\n type JITCSSOptions,\n} from './style';\n\n/**\n * Configure the JIT CSS engine for the current session.\n * This is a convenience wrapper around `enableJITCSS()` that can be called\n * inside a component render function or at module initialisation time.\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * // Enable extended Tailwind colors so bg-blue-500, text-violet-700, etc. generate CSS\n * useJITCSS({ extendedColors: true });\n * return html`<div class=\"bg-blue-500 text-white\">Hello</div>`;\n * });\n * ```\n *\n * @example\n * ```ts\n * // At app entry – enable once for all components\n * useJITCSS({ extendedColors: true, customColors: { brand: { '500': '#e63946' } } });\n * ```\n */\nexport function useJITCSS(options?: JITCSSOptions): void {\n // During discovery renders (component registration phase) there is no real\n // shadow root. Without this guard, useJITCSS() falls through to\n // enableJITCSS() and globally enables JIT CSS for every component — exactly\n // the opt-in behaviour we are trying to prevent.\n if (_isDiscoveryRenderFn()) return;\n\n // When called inside a component render function, register this component's\n // shadow root for per-component JIT CSS opt-in. Context is always set during\n // a real render; it may be absent (null) or missing _host when called at app\n // startup level (outside any component context).\n const host = (getCurrentComponentContext() as { _host?: Element } | null)\n ?._host;\n const shadowRoot = host?.shadowRoot ?? null;\n\n if (shadowRoot) {\n // Per-component opt-in: register this shadow root only.\n registerJITCSSComponent(shadowRoot, options);\n } else {\n // App-level call (outside component context) — enable for all components\n // globally, preserving v2 behaviour when called at the entry point.\n enableJITCSS(options);\n }\n}\n\nexport type { JITCSSOptions };\n","/**\n * JIT CSS entry point — opt-in import for the full JIT CSS engine.\n *\n * @example\n * ```ts\n * import {\n * useJITCSS,\n * enableJITCSS,\n * } from '@jasonshimmy/custom-elements-runtime/jit-css';\n * ```\n */\n\n// Hooks\nexport { useJITCSS } from './runtime/jit-hooks';\nexport { useDesignTokens, useGlobalStyle } from './runtime/hooks';\nexport type { JITCSSOptions, DesignTokens } from './runtime/hooks';\n\n// Global configuration\nexport {\n enableJITCSS,\n disableJITCSS,\n isJITCSSEnabled,\n isJITCSSEnabledFor,\n registerJITCSSComponent,\n getJITCSSOptions,\n jitCSS,\n extractClassesFromHTML,\n parseColorClass,\n parseColorWithOpacity,\n parseGradientColorStop,\n parseSpacing,\n parseArbitrary,\n utilityMap,\n selectorVariants,\n mediaVariants,\n containerVariants,\n colors,\n} from './runtime/style';\n\n/**\n * A no-op identity function that signals to development tools (IDE\n * autocomplete, linters, PurgeCSS-style scanners) that the string contains\n * JIT CSS utility class names.\n *\n * At runtime this is simply `return className` — zero overhead.\n *\n * @example\n * ```ts\n * import { cls } from '@jasonshimmy/custom-elements-runtime/jit-css';\n *\n * const containerClasses = cls('flex items-center gap-4 bg-primary-500 text-white');\n * ```\n */\nexport function cls(className: string): string {\n return className;\n}\n"],"
|
|
1
|
+
{"version":3,"file":"custom-elements-runtime.jit-css.es.js","names":[],"sources":["../src/lib/runtime/jit-hooks.ts","../src/lib/jit-css.ts"],"sourcesContent":["/**\n * JIT CSS hooks — lives in a separate module so that hooks.ts does not\n * statically import style.ts. Consumers who never call `useJITCSS` will\n * have the entire JIT engine tree-shaken out of their bundle.\n */\n\nimport { isDiscoveryRender as _isDiscoveryRenderFn } from './discovery-state';\nimport { getCurrentComponentContext } from './hooks';\nimport {\n enableJITCSS,\n registerJITCSSComponent,\n type JITCSSOptions,\n} from './style';\n\n/**\n * Configure the JIT CSS engine for the current session.\n * This is a convenience wrapper around `enableJITCSS()` that can be called\n * inside a component render function or at module initialisation time.\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * // Enable extended Tailwind colors so bg-blue-500, text-violet-700, etc. generate CSS\n * useJITCSS({ extendedColors: true });\n * return html`<div class=\"bg-blue-500 text-white\">Hello</div>`;\n * });\n * ```\n *\n * @example\n * ```ts\n * // At app entry – enable once for all components\n * useJITCSS({ extendedColors: true, customColors: { brand: { '500': '#e63946' } } });\n * ```\n */\nexport function useJITCSS(options?: JITCSSOptions): void {\n // During discovery renders (component registration phase) there is no real\n // shadow root. Without this guard, useJITCSS() falls through to\n // enableJITCSS() and globally enables JIT CSS for every component — exactly\n // the opt-in behaviour we are trying to prevent.\n if (_isDiscoveryRenderFn()) return;\n\n // When called inside a component render function, register this component's\n // shadow root for per-component JIT CSS opt-in. Context is always set during\n // a real render; it may be absent (null) or missing _host when called at app\n // startup level (outside any component context).\n const host = (getCurrentComponentContext() as { _host?: Element } | null)\n ?._host;\n const shadowRoot = host?.shadowRoot ?? null;\n\n if (shadowRoot) {\n // Per-component opt-in: register this shadow root only.\n registerJITCSSComponent(shadowRoot, options);\n } else {\n // App-level call (outside component context) — enable for all components\n // globally, preserving v2 behaviour when called at the entry point.\n enableJITCSS(options);\n }\n}\n\nexport type { JITCSSOptions };\n","/**\n * JIT CSS entry point — opt-in import for the full JIT CSS engine.\n *\n * @example\n * ```ts\n * import {\n * useJITCSS,\n * enableJITCSS,\n * } from '@jasonshimmy/custom-elements-runtime/jit-css';\n * ```\n */\n\n// Hooks\nexport { useJITCSS } from './runtime/jit-hooks';\nexport { useDesignTokens, useGlobalStyle } from './runtime/hooks';\nexport type { JITCSSOptions, DesignTokens } from './runtime/hooks';\n\n// Global configuration\nexport {\n enableJITCSS,\n disableJITCSS,\n isJITCSSEnabled,\n isJITCSSEnabledFor,\n registerJITCSSComponent,\n getJITCSSOptions,\n jitCSS,\n extractClassesFromHTML,\n parseColorClass,\n parseColorWithOpacity,\n parseGradientColorStop,\n parseSpacing,\n parseArbitrary,\n utilityMap,\n selectorVariants,\n mediaVariants,\n containerVariants,\n colors,\n} from './runtime/style';\n\n/**\n * A no-op identity function that signals to development tools (IDE\n * autocomplete, linters, PurgeCSS-style scanners) that the string contains\n * JIT CSS utility class names.\n *\n * At runtime this is simply `return className` — zero overhead.\n *\n * @example\n * ```ts\n * import { cls } from '@jasonshimmy/custom-elements-runtime/jit-css';\n *\n * const containerClasses = cls('flex items-center gap-4 bg-primary-500 text-white');\n * ```\n */\nexport function cls(className: string): string {\n return className;\n}\n"],"mappings":";;AAkCA,SAAgB,EAAU,GAA+B;AAKvD,MAAI,EAAA,EAAwB;AAQ5B,QAAM,IAFQ,EAAA,GACV,OACqB,cAAc;AAEvC,EAAI,IAEF,EAAwB,GAAY,CAAA,IAIpC,EAAa,CAAA;;ACFjB,SAAgB,EAAI,GAA2B;AAC7C,SAAO"}
|