sparkfx 1.2.1 → 1.2.2

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.
Files changed (44) hide show
  1. package/README.md +7 -12
  2. package/dist/{chunk-YLY5N62U.cjs → chunk-3AVUTKJ5.cjs} +8 -8
  3. package/dist/{chunk-YLY5N62U.cjs.map → chunk-3AVUTKJ5.cjs.map} +1 -1
  4. package/dist/{chunk-RD5XCTW4.js → chunk-FPJZKZGF.js} +3 -3
  5. package/dist/{chunk-RD5XCTW4.js.map → chunk-FPJZKZGF.js.map} +1 -1
  6. package/dist/{chunk-KXPTBR5B.cjs → chunk-GHLFOSXQ.cjs} +3 -3
  7. package/dist/{chunk-KXPTBR5B.cjs.map → chunk-GHLFOSXQ.cjs.map} +1 -1
  8. package/dist/{chunk-Y5V7MOLA.cjs → chunk-HB6NE443.cjs} +3 -3
  9. package/dist/{chunk-Y5V7MOLA.cjs.map → chunk-HB6NE443.cjs.map} +1 -1
  10. package/dist/{chunk-5YDUWTOY.js → chunk-LPB7JTCR.js} +3 -3
  11. package/dist/{chunk-5YDUWTOY.js.map → chunk-LPB7JTCR.js.map} +1 -1
  12. package/dist/{chunk-4BGOBPG6.js → chunk-SJKJ2GZW.js} +8 -8
  13. package/dist/{chunk-4BGOBPG6.js.map → chunk-SJKJ2GZW.js.map} +1 -1
  14. package/dist/headless.cjs +1 -1
  15. package/dist/headless.js +1 -1
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.d.cts +4 -5
  18. package/dist/index.d.ts +4 -5
  19. package/dist/index.js +1 -1
  20. package/dist/next.cjs +2 -2
  21. package/dist/next.js +1 -1
  22. package/dist/react.cjs +1 -1
  23. package/dist/react.js +1 -1
  24. package/dist/shadcn.cjs +2 -2
  25. package/dist/shadcn.js +1 -1
  26. package/dist/svelte.cjs +2 -2
  27. package/dist/svelte.js +1 -1
  28. package/dist/tailwind.cjs +1 -1
  29. package/dist/tailwind.js +1 -1
  30. package/dist/testing.cjs +2 -2
  31. package/dist/testing.js +1 -1
  32. package/dist/vue.cjs +2 -2
  33. package/dist/vue.js +1 -1
  34. package/package.json +2 -7
  35. package/dist/chunk-E3PKCBIJ.cjs +0 -299
  36. package/dist/chunk-E3PKCBIJ.cjs.map +0 -1
  37. package/dist/chunk-RMXXT53J.js +0 -299
  38. package/dist/chunk-RMXXT53J.js.map +0 -1
  39. package/dist/devtools.cjs +0 -2
  40. package/dist/devtools.cjs.map +0 -1
  41. package/dist/devtools.d.cts +0 -65
  42. package/dist/devtools.d.ts +0 -65
  43. package/dist/devtools.js +0 -2
  44. package/dist/devtools.js.map +0 -1
@@ -1,3 +1,3 @@
1
- /* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
2
- var d=class{subscriptions=new Map;triggerRules=new Map;eventHistory=[];maxHistorySize=100;subscriptionCounter=0;isEnabledFlag=true;isPausedFlag=false;generateSubscriptionId(){return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`}matchesSelector(t,e){if(!t)return false;try{return t.matches(e)}catch{return false}}getElement(t){return typeof t=="string"?typeof document<"u"?document.querySelector(t):null:t}recordEvent(t){this.eventHistory.push(t),this.eventHistory.length>this.maxHistorySize&&this.eventHistory.shift();}on(t,e,s={}){let r={handler:e,options:s,id:this.generateSubscriptionId()};return this.subscriptions.has(t)||this.subscriptions.set(t,new Set),this.subscriptions.get(t).add(r),()=>{let o=this.subscriptions.get(t);if(o){for(let u of o)if(u.id===r.id){o.delete(u);break}}}}once(t,e){return this.on(t,e,{once:true})}off(t){this.subscriptions.delete(t);}emit(t,e={}){if(!this.isEnabledFlag||this.isPausedFlag)return;let s={timestamp:Date.now(),...e};this.recordEvent(s);let r=this.subscriptions.get(t)??new Set,o=this.subscriptions.get("*")??new Set,u=[...r,...o].sort((i,n)=>(n.options.priority??0)-(i.options.priority??0)),l=[];for(let i of u)if(!(i.options.filter&&!this.matchesSelector(s.element,i.options.filter))){try{i.handler(s);}catch(n){console.error("[SparkFX EventBus] Handler error:",n),this.emit("animation:error",{data:{error:n,originalEvent:t}});}i.options.once&&l.push({event:t,sub:i});}for(let{event:i,sub:n}of l){let p=this.subscriptions.get(i);p&&p.delete(n);let c=this.subscriptions.get("*");c&&c.delete(n);}}when(t,e="complete"){let s=`animation:${e}`,r=this;return {trigger(o,u,l){let i=r.on(s,n=>{if(r.matchesSelector(n.element,t)){let p=r.getElement(o);p&&r.emit("animation:start",{element:p,effect:u,data:{triggeredBy:n,options:l,source:t,target:o}});}});return {and(n,p,c){return r.when(t,e).trigger(n,p,c)},unsubscribe:i}}}}clear(){this.subscriptions.clear(),this.triggerRules.clear(),this.eventHistory.length=0;}enable(){this.isEnabledFlag=true;}disable(){this.isEnabledFlag=false;}pause(){this.isPausedFlag=true;}resume(){this.isPausedFlag=false;}getHistory(){return [...this.eventHistory]}getSubscriptionCount(t){if(t)return this.subscriptions.get(t)?.size??0;let e=0;for(let s of this.subscriptions.values())e+=s.size;return e}get enabled(){return this.isEnabledFlag}get paused(){return this.isPausedFlag}},a=new d;var b=a.on.bind(a),v=a.once.bind(a),m=a.emit.bind(a),h=a.when.bind(a);export{d as a,a as b,b as c,v as d,m as e,h as f};//# sourceMappingURL=chunk-RD5XCTW4.js.map
3
- //# sourceMappingURL=chunk-RD5XCTW4.js.map
1
+ /* sparkfx v1.2.2 - Premium micro-interactions with Event Bus & Testing Kit */
2
+ var d=class{subscriptions=new Map;triggerRules=new Map;eventHistory=[];maxHistorySize=100;subscriptionCounter=0;isEnabledFlag=true;isPausedFlag=false;generateSubscriptionId(){return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`}matchesSelector(t,e){if(!t)return false;try{return t.matches(e)}catch{return false}}getElement(t){return typeof t=="string"?typeof document<"u"?document.querySelector(t):null:t}recordEvent(t){this.eventHistory.push(t),this.eventHistory.length>this.maxHistorySize&&this.eventHistory.shift();}on(t,e,s={}){let r={handler:e,options:s,id:this.generateSubscriptionId()};return this.subscriptions.has(t)||this.subscriptions.set(t,new Set),this.subscriptions.get(t).add(r),()=>{let o=this.subscriptions.get(t);if(o){for(let u of o)if(u.id===r.id){o.delete(u);break}}}}once(t,e){return this.on(t,e,{once:true})}off(t){this.subscriptions.delete(t);}emit(t,e={}){if(!this.isEnabledFlag||this.isPausedFlag)return;let s={timestamp:Date.now(),...e};this.recordEvent(s);let r=this.subscriptions.get(t)??new Set,o=this.subscriptions.get("*")??new Set,u=[...r,...o].sort((i,n)=>(n.options.priority??0)-(i.options.priority??0)),l=[];for(let i of u)if(!(i.options.filter&&!this.matchesSelector(s.element,i.options.filter))){try{i.handler(s);}catch(n){console.error("[SparkFX EventBus] Handler error:",n),this.emit("animation:error",{data:{error:n,originalEvent:t}});}i.options.once&&l.push({event:t,sub:i});}for(let{event:i,sub:n}of l){let p=this.subscriptions.get(i);p&&p.delete(n);let c=this.subscriptions.get("*");c&&c.delete(n);}}when(t,e="complete"){let s=`animation:${e}`,r=this;return {trigger(o,u,l){let i=r.on(s,n=>{if(r.matchesSelector(n.element,t)){let p=r.getElement(o);p&&r.emit("animation:start",{element:p,effect:u,data:{triggeredBy:n,options:l,source:t,target:o}});}});return {and(n,p,c){return r.when(t,e).trigger(n,p,c)},unsubscribe:i}}}}clear(){this.subscriptions.clear(),this.triggerRules.clear(),this.eventHistory.length=0;}enable(){this.isEnabledFlag=true;}disable(){this.isEnabledFlag=false;}pause(){this.isPausedFlag=true;}resume(){this.isPausedFlag=false;}getHistory(){return [...this.eventHistory]}getSubscriptionCount(t){if(t)return this.subscriptions.get(t)?.size??0;let e=0;for(let s of this.subscriptions.values())e+=s.size;return e}get enabled(){return this.isEnabledFlag}get paused(){return this.isPausedFlag}},a=new d;var b=a.on.bind(a),v=a.once.bind(a),m=a.emit.bind(a),h=a.when.bind(a);export{d as a,a as b,b as c,v as d,m as e,h as f};//# sourceMappingURL=chunk-FPJZKZGF.js.map
3
+ //# sourceMappingURL=chunk-FPJZKZGF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/event-bus.ts"],"names":["SparkEventBus","element","selector","selectorOrElement","event","eventType","handler","options","subscription","subs","sub","payload","fullPayload","specificHandlers","wildcardHandlers","allHandlers","a","b","toRemove","error","wildcards","sourceSelector","eventSuffix","self","targetSelector","effectName","unsubscribe","target","nextTarget","nextEffect","nextOptions","total","eventBus","on","once","emit","when"],"mappings":"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","file":"chunk-RD5XCTW4.js","sourcesContent":["/**\r\n * SparkFX Event Bus - Animation Event System\r\n * \r\n * Enables communication between animations on different elements.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { eventBus } from 'sparkfx'\r\n * \r\n * // Listen to animation events\r\n * eventBus.on('animation:start', ({ element, effect }) => {\r\n * console.log(`${effect} started on`, element)\r\n * })\r\n * \r\n * // Trigger animations based on other animations\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * \r\n * // Chain animations\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n * \r\n * @version 1.2.1\r\n */\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/** Animation lifecycle events */\r\nexport type AnimationEventType =\r\n | 'animation:start'\r\n | 'animation:progress'\r\n | 'animation:complete'\r\n | 'animation:cancel'\r\n | 'animation:pause'\r\n | 'animation:resume'\r\n | 'animation:error'\r\n\r\n/** Custom event types */\r\nexport type CustomEventType = `custom:${string}`\r\n\r\n/** All event types */\r\nexport type SparkEventType = AnimationEventType | CustomEventType | '*'\r\n\r\n/** Event payload structure */\r\nexport interface SparkEventPayload {\r\n /** Target element (if applicable) */\r\n element?: Element | null\r\n /** Effect name (if applicable) */\r\n effect?: string\r\n /** Animation progress (0-1) */\r\n progress?: number\r\n /** Animation ID */\r\n animationId?: string\r\n /** Timestamp when event occurred */\r\n timestamp: number\r\n /** Additional custom data */\r\n data?: Record<string, unknown>\r\n}\r\n\r\n/** Event handler function type */\r\nexport type SparkEventHandler = (payload: SparkEventPayload) => void\r\n\r\n/** Subscription options */\r\nexport interface SubscriptionOptions {\r\n /** Only trigger once */\r\n once?: boolean\r\n /** Priority (higher = earlier execution) */\r\n priority?: number\r\n /** Filter by element selector */\r\n filter?: string\r\n}\r\n\r\n/** Subscription record */\r\ninterface Subscription {\r\n handler: SparkEventHandler\r\n options: SubscriptionOptions\r\n id: string\r\n}\r\n\r\n// ============================================================================\r\n// SPARK EVENT BUS CLASS\r\n// ============================================================================\r\n\r\n/**\r\n * SparkFX Event Bus Class\r\n * Singleton pattern with proper encapsulation\r\n */\r\nclass SparkEventBus {\r\n private readonly subscriptions = new Map<SparkEventType, Set<Subscription>>()\r\n private readonly triggerRules = new Map<string, { targetSelector: string; effectName: string; options?: Record<string, unknown> }[]>()\r\n private readonly eventHistory: SparkEventPayload[] = []\r\n private readonly maxHistorySize = 100\r\n\r\n private subscriptionCounter = 0\r\n private isEnabledFlag = true\r\n private isPausedFlag = false\r\n\r\n // ============================================================================\r\n // UTILITY METHODS\r\n // ============================================================================\r\n\r\n private generateSubscriptionId(): string {\r\n return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`\r\n }\r\n\r\n private matchesSelector(element: Element | null | undefined, selector: string): boolean {\r\n if (!element) return false\r\n try {\r\n return element.matches(selector)\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n private getElement(selectorOrElement: string | Element): Element | null {\r\n if (typeof selectorOrElement === 'string') {\r\n return typeof document !== 'undefined'\r\n ? document.querySelector(selectorOrElement)\r\n : null\r\n }\r\n return selectorOrElement\r\n }\r\n\r\n private recordEvent(event: SparkEventPayload): void {\r\n this.eventHistory.push(event)\r\n if (this.eventHistory.length > this.maxHistorySize) {\r\n this.eventHistory.shift()\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // CORE API\r\n // ============================================================================\r\n\r\n /**\r\n * Subscribe to an event\r\n * @returns Unsubscribe function\r\n */\r\n on(\r\n eventType: SparkEventType,\r\n handler: SparkEventHandler,\r\n options: SubscriptionOptions = {}\r\n ): () => void {\r\n const subscription: Subscription = {\r\n handler,\r\n options,\r\n id: this.generateSubscriptionId()\r\n }\r\n\r\n if (!this.subscriptions.has(eventType)) {\r\n this.subscriptions.set(eventType, new Set())\r\n }\r\n this.subscriptions.get(eventType)!.add(subscription)\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n const subs = this.subscriptions.get(eventType)\r\n if (subs) {\r\n for (const sub of subs) {\r\n if (sub.id === subscription.id) {\r\n subs.delete(sub)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to an event (one-time only)\r\n */\r\n once(eventType: SparkEventType, handler: SparkEventHandler): () => void {\r\n return this.on(eventType, handler, { once: true })\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event type\r\n */\r\n off(eventType: SparkEventType): void {\r\n this.subscriptions.delete(eventType)\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n emit(eventType: SparkEventType, payload: Partial<SparkEventPayload> = {}): void {\r\n if (!this.isEnabledFlag || this.isPausedFlag) return\r\n\r\n const fullPayload: SparkEventPayload = {\r\n timestamp: Date.now(),\r\n ...payload\r\n }\r\n\r\n this.recordEvent(fullPayload)\r\n\r\n // Get handlers for specific event type\r\n const specificHandlers = this.subscriptions.get(eventType) ?? new Set()\r\n\r\n // Get handlers for wildcard\r\n const wildcardHandlers = this.subscriptions.get('*') ?? new Set()\r\n\r\n // Combine and sort by priority\r\n const allHandlers = [...specificHandlers, ...wildcardHandlers]\r\n .sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))\r\n\r\n // Execute handlers\r\n const toRemove: { event: SparkEventType; sub: Subscription }[] = []\r\n\r\n for (const subscription of allHandlers) {\r\n // Check filter\r\n if (subscription.options.filter) {\r\n if (!this.matchesSelector(fullPayload.element, subscription.options.filter)) {\r\n continue\r\n }\r\n }\r\n\r\n try {\r\n subscription.handler(fullPayload)\r\n } catch (error) {\r\n console.error('[SparkFX EventBus] Handler error:', error)\r\n this.emit('animation:error', {\r\n data: { error, originalEvent: eventType }\r\n })\r\n }\r\n\r\n // Mark for removal if once\r\n if (subscription.options.once) {\r\n toRemove.push({ event: eventType, sub: subscription })\r\n }\r\n }\r\n\r\n // Remove one-time handlers\r\n for (const { event, sub } of toRemove) {\r\n const subs = this.subscriptions.get(event)\r\n if (subs) subs.delete(sub)\r\n const wildcards = this.subscriptions.get('*')\r\n if (wildcards) wildcards.delete(sub)\r\n }\r\n }\r\n\r\n /**\r\n * Create a trigger rule: when element animates, trigger another animation\r\n * \r\n * @example\r\n * ```typescript\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n */\r\n when(\r\n sourceSelector: string,\r\n eventSuffix: 'start' | 'complete' | 'pause' | 'resume' = 'complete'\r\n ) {\r\n const eventType: AnimationEventType = `animation:${eventSuffix}`\r\n const self = this\r\n\r\n return {\r\n trigger(\r\n targetSelector: string,\r\n effectName: string,\r\n options?: Record<string, unknown>\r\n ) {\r\n // Set up listener for source element\r\n const unsubscribe = self.on(eventType, (payload) => {\r\n if (self.matchesSelector(payload.element, sourceSelector)) {\r\n const target = self.getElement(targetSelector)\r\n if (target) {\r\n self.emit('animation:start', {\r\n element: target,\r\n effect: effectName,\r\n data: {\r\n triggeredBy: payload,\r\n options,\r\n source: sourceSelector,\r\n target: targetSelector\r\n }\r\n })\r\n }\r\n }\r\n })\r\n\r\n // Return chainable object\r\n return {\r\n and(nextTarget: string, nextEffect: string, nextOptions?: Record<string, unknown>) {\r\n return self.when(sourceSelector, eventSuffix).trigger(nextTarget, nextEffect, nextOptions)\r\n },\r\n unsubscribe\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners and rules\r\n */\r\n clear(): void {\r\n this.subscriptions.clear()\r\n this.triggerRules.clear()\r\n this.eventHistory.length = 0\r\n }\r\n\r\n // ============================================================================\r\n // CONTROL API\r\n // ============================================================================\r\n\r\n /** Enable the event bus */\r\n enable(): void {\r\n this.isEnabledFlag = true\r\n }\r\n\r\n /** Disable the event bus (events will be ignored) */\r\n disable(): void {\r\n this.isEnabledFlag = false\r\n }\r\n\r\n /** Pause event processing */\r\n pause(): void {\r\n this.isPausedFlag = true\r\n }\r\n\r\n /** Resume event processing */\r\n resume(): void {\r\n this.isPausedFlag = false\r\n }\r\n\r\n // ============================================================================\r\n // INSPECTION API\r\n // ============================================================================\r\n\r\n /** Get event history */\r\n getHistory(): readonly SparkEventPayload[] {\r\n return [...this.eventHistory]\r\n }\r\n\r\n /** Get subscription count */\r\n getSubscriptionCount(eventType?: SparkEventType): number {\r\n if (eventType) {\r\n return this.subscriptions.get(eventType)?.size ?? 0\r\n }\r\n let total = 0\r\n for (const subs of this.subscriptions.values()) {\r\n total += subs.size\r\n }\r\n return total\r\n }\r\n\r\n /** Check if event bus is enabled */\r\n get enabled(): boolean {\r\n return this.isEnabledFlag\r\n }\r\n\r\n /** Check if event bus is paused */\r\n get paused(): boolean {\r\n return this.isPausedFlag\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// SINGLETON EXPORT\r\n// ============================================================================\r\n\r\n/** Global event bus instance */\r\nexport const eventBus = new SparkEventBus()\r\n\r\n/** Export class for testing purposes */\r\nexport { SparkEventBus }\r\n\r\n// ============================================================================\r\n// CONVENIENCE FUNCTIONS\r\n// ============================================================================\r\n\r\n/** Shorthand for eventBus.on */\r\nexport const on = eventBus.on.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.once */\r\nexport const once = eventBus.once.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.emit */\r\nexport const emit = eventBus.emit.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.when */\r\nexport const when = eventBus.when.bind(eventBus)\r\n"]}
1
+ {"version":3,"sources":["../src/core/event-bus.ts"],"names":["SparkEventBus","element","selector","selectorOrElement","event","eventType","handler","options","subscription","subs","sub","payload","fullPayload","specificHandlers","wildcardHandlers","allHandlers","a","b","toRemove","error","wildcards","sourceSelector","eventSuffix","self","targetSelector","effectName","unsubscribe","target","nextTarget","nextEffect","nextOptions","total","eventBus","on","once","emit","when"],"mappings":"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","file":"chunk-FPJZKZGF.js","sourcesContent":["/**\r\n * SparkFX Event Bus - Animation Event System\r\n * \r\n * Enables communication between animations on different elements.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { eventBus } from 'sparkfx'\r\n * \r\n * // Listen to animation events\r\n * eventBus.on('animation:start', ({ element, effect }) => {\r\n * console.log(`${effect} started on`, element)\r\n * })\r\n * \r\n * // Trigger animations based on other animations\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * \r\n * // Chain animations\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n * \r\n * @version 1.2.1\r\n */\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/** Animation lifecycle events */\r\nexport type AnimationEventType =\r\n | 'animation:start'\r\n | 'animation:progress'\r\n | 'animation:complete'\r\n | 'animation:cancel'\r\n | 'animation:pause'\r\n | 'animation:resume'\r\n | 'animation:error'\r\n\r\n/** Custom event types */\r\nexport type CustomEventType = `custom:${string}`\r\n\r\n/** All event types */\r\nexport type SparkEventType = AnimationEventType | CustomEventType | '*'\r\n\r\n/** Event payload structure */\r\nexport interface SparkEventPayload {\r\n /** Target element (if applicable) */\r\n element?: Element | null\r\n /** Effect name (if applicable) */\r\n effect?: string\r\n /** Animation progress (0-1) */\r\n progress?: number\r\n /** Animation ID */\r\n animationId?: string\r\n /** Timestamp when event occurred */\r\n timestamp: number\r\n /** Additional custom data */\r\n data?: Record<string, unknown>\r\n}\r\n\r\n/** Event handler function type */\r\nexport type SparkEventHandler = (payload: SparkEventPayload) => void\r\n\r\n/** Subscription options */\r\nexport interface SubscriptionOptions {\r\n /** Only trigger once */\r\n once?: boolean\r\n /** Priority (higher = earlier execution) */\r\n priority?: number\r\n /** Filter by element selector */\r\n filter?: string\r\n}\r\n\r\n/** Subscription record */\r\ninterface Subscription {\r\n handler: SparkEventHandler\r\n options: SubscriptionOptions\r\n id: string\r\n}\r\n\r\n// ============================================================================\r\n// SPARK EVENT BUS CLASS\r\n// ============================================================================\r\n\r\n/**\r\n * SparkFX Event Bus Class\r\n * Singleton pattern with proper encapsulation\r\n */\r\nclass SparkEventBus {\r\n private readonly subscriptions = new Map<SparkEventType, Set<Subscription>>()\r\n private readonly triggerRules = new Map<string, { targetSelector: string; effectName: string; options?: Record<string, unknown> }[]>()\r\n private readonly eventHistory: SparkEventPayload[] = []\r\n private readonly maxHistorySize = 100\r\n\r\n private subscriptionCounter = 0\r\n private isEnabledFlag = true\r\n private isPausedFlag = false\r\n\r\n // ============================================================================\r\n // UTILITY METHODS\r\n // ============================================================================\r\n\r\n private generateSubscriptionId(): string {\r\n return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`\r\n }\r\n\r\n private matchesSelector(element: Element | null | undefined, selector: string): boolean {\r\n if (!element) return false\r\n try {\r\n return element.matches(selector)\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n private getElement(selectorOrElement: string | Element): Element | null {\r\n if (typeof selectorOrElement === 'string') {\r\n return typeof document !== 'undefined'\r\n ? document.querySelector(selectorOrElement)\r\n : null\r\n }\r\n return selectorOrElement\r\n }\r\n\r\n private recordEvent(event: SparkEventPayload): void {\r\n this.eventHistory.push(event)\r\n if (this.eventHistory.length > this.maxHistorySize) {\r\n this.eventHistory.shift()\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // CORE API\r\n // ============================================================================\r\n\r\n /**\r\n * Subscribe to an event\r\n * @returns Unsubscribe function\r\n */\r\n on(\r\n eventType: SparkEventType,\r\n handler: SparkEventHandler,\r\n options: SubscriptionOptions = {}\r\n ): () => void {\r\n const subscription: Subscription = {\r\n handler,\r\n options,\r\n id: this.generateSubscriptionId()\r\n }\r\n\r\n if (!this.subscriptions.has(eventType)) {\r\n this.subscriptions.set(eventType, new Set())\r\n }\r\n this.subscriptions.get(eventType)!.add(subscription)\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n const subs = this.subscriptions.get(eventType)\r\n if (subs) {\r\n for (const sub of subs) {\r\n if (sub.id === subscription.id) {\r\n subs.delete(sub)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to an event (one-time only)\r\n */\r\n once(eventType: SparkEventType, handler: SparkEventHandler): () => void {\r\n return this.on(eventType, handler, { once: true })\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event type\r\n */\r\n off(eventType: SparkEventType): void {\r\n this.subscriptions.delete(eventType)\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n emit(eventType: SparkEventType, payload: Partial<SparkEventPayload> = {}): void {\r\n if (!this.isEnabledFlag || this.isPausedFlag) return\r\n\r\n const fullPayload: SparkEventPayload = {\r\n timestamp: Date.now(),\r\n ...payload\r\n }\r\n\r\n this.recordEvent(fullPayload)\r\n\r\n // Get handlers for specific event type\r\n const specificHandlers = this.subscriptions.get(eventType) ?? new Set()\r\n\r\n // Get handlers for wildcard\r\n const wildcardHandlers = this.subscriptions.get('*') ?? new Set()\r\n\r\n // Combine and sort by priority\r\n const allHandlers = [...specificHandlers, ...wildcardHandlers]\r\n .sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))\r\n\r\n // Execute handlers\r\n const toRemove: { event: SparkEventType; sub: Subscription }[] = []\r\n\r\n for (const subscription of allHandlers) {\r\n // Check filter\r\n if (subscription.options.filter) {\r\n if (!this.matchesSelector(fullPayload.element, subscription.options.filter)) {\r\n continue\r\n }\r\n }\r\n\r\n try {\r\n subscription.handler(fullPayload)\r\n } catch (error) {\r\n console.error('[SparkFX EventBus] Handler error:', error)\r\n this.emit('animation:error', {\r\n data: { error, originalEvent: eventType }\r\n })\r\n }\r\n\r\n // Mark for removal if once\r\n if (subscription.options.once) {\r\n toRemove.push({ event: eventType, sub: subscription })\r\n }\r\n }\r\n\r\n // Remove one-time handlers\r\n for (const { event, sub } of toRemove) {\r\n const subs = this.subscriptions.get(event)\r\n if (subs) subs.delete(sub)\r\n const wildcards = this.subscriptions.get('*')\r\n if (wildcards) wildcards.delete(sub)\r\n }\r\n }\r\n\r\n /**\r\n * Create a trigger rule: when element animates, trigger another animation\r\n * \r\n * @example\r\n * ```typescript\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n */\r\n when(\r\n sourceSelector: string,\r\n eventSuffix: 'start' | 'complete' | 'pause' | 'resume' = 'complete'\r\n ) {\r\n const eventType: AnimationEventType = `animation:${eventSuffix}`\r\n const self = this\r\n\r\n return {\r\n trigger(\r\n targetSelector: string,\r\n effectName: string,\r\n options?: Record<string, unknown>\r\n ) {\r\n // Set up listener for source element\r\n const unsubscribe = self.on(eventType, (payload) => {\r\n if (self.matchesSelector(payload.element, sourceSelector)) {\r\n const target = self.getElement(targetSelector)\r\n if (target) {\r\n self.emit('animation:start', {\r\n element: target,\r\n effect: effectName,\r\n data: {\r\n triggeredBy: payload,\r\n options,\r\n source: sourceSelector,\r\n target: targetSelector\r\n }\r\n })\r\n }\r\n }\r\n })\r\n\r\n // Return chainable object\r\n return {\r\n and(nextTarget: string, nextEffect: string, nextOptions?: Record<string, unknown>) {\r\n return self.when(sourceSelector, eventSuffix).trigger(nextTarget, nextEffect, nextOptions)\r\n },\r\n unsubscribe\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners and rules\r\n */\r\n clear(): void {\r\n this.subscriptions.clear()\r\n this.triggerRules.clear()\r\n this.eventHistory.length = 0\r\n }\r\n\r\n // ============================================================================\r\n // CONTROL API\r\n // ============================================================================\r\n\r\n /** Enable the event bus */\r\n enable(): void {\r\n this.isEnabledFlag = true\r\n }\r\n\r\n /** Disable the event bus (events will be ignored) */\r\n disable(): void {\r\n this.isEnabledFlag = false\r\n }\r\n\r\n /** Pause event processing */\r\n pause(): void {\r\n this.isPausedFlag = true\r\n }\r\n\r\n /** Resume event processing */\r\n resume(): void {\r\n this.isPausedFlag = false\r\n }\r\n\r\n // ============================================================================\r\n // INSPECTION API\r\n // ============================================================================\r\n\r\n /** Get event history */\r\n getHistory(): readonly SparkEventPayload[] {\r\n return [...this.eventHistory]\r\n }\r\n\r\n /** Get subscription count */\r\n getSubscriptionCount(eventType?: SparkEventType): number {\r\n if (eventType) {\r\n return this.subscriptions.get(eventType)?.size ?? 0\r\n }\r\n let total = 0\r\n for (const subs of this.subscriptions.values()) {\r\n total += subs.size\r\n }\r\n return total\r\n }\r\n\r\n /** Check if event bus is enabled */\r\n get enabled(): boolean {\r\n return this.isEnabledFlag\r\n }\r\n\r\n /** Check if event bus is paused */\r\n get paused(): boolean {\r\n return this.isPausedFlag\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// SINGLETON EXPORT\r\n// ============================================================================\r\n\r\n/** Global event bus instance */\r\nexport const eventBus = new SparkEventBus()\r\n\r\n/** Export class for testing purposes */\r\nexport { SparkEventBus }\r\n\r\n// ============================================================================\r\n// CONVENIENCE FUNCTIONS\r\n// ============================================================================\r\n\r\n/** Shorthand for eventBus.on */\r\nexport const on = eventBus.on.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.once */\r\nexport const once = eventBus.once.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.emit */\r\nexport const emit = eventBus.emit.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.when */\r\nexport const when = eventBus.when.bind(eventBus)\r\n"]}
@@ -1,3 +1,3 @@
1
- 'use strict';var chunkYLY5N62U_cjs=require('./chunk-YLY5N62U.cjs'),react=require('react');/* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
2
- function k(l,c){let n=react.useRef(null);return react.useEffect(()=>{if(!n.current)return;let i=chunkYLY5N62U_cjs.qa[l];if(typeof i!="function")return;let s=i(c),a=n.current;if(s.className){let t=s.className.split(" ");a.classList.add(...t);}s.style&&Object.entries(s.style).forEach(([t,r])=>{a.style.setProperty(t,String(r));});let u=[],e=(t,r)=>{if(!r)return;let o=t.replace(/^on/,"").toLowerCase();a.addEventListener(o,r),u.push(()=>a.removeEventListener(o,r));};return e("mouseenter",s.onMouseEnter),e("mouseleave",s.onMouseLeave),e("mousemove",s.onMouseMove),e("click",s.onClick),e("focus",s.onFocus),e("blur",s.onBlur),()=>{u.forEach(t=>t()),s.destroy&&s.destroy(),s.className&&a.classList.remove(...s.className.split(" "));}},[l,JSON.stringify(c)]),n}function L(l){let c=react.useRef(null);return react.useEffect(()=>{if(!c.current)return;let n=c.current,i=[];return l.forEach(({name:s,options:a})=>{let u=chunkYLY5N62U_cjs.qa[s];if(typeof u!="function")return;let e=u(a);e.className&&n.classList.add(...e.className.split(" ")),e.style&&Object.entries(e.style).forEach(([r,o])=>{n.style.setProperty(r,String(o));});let t=(r,o)=>{if(!o)return;let m=r.replace(/^on/,"").toLowerCase();n.addEventListener(m,o),i.push(()=>n.removeEventListener(m,o));};t("mouseenter",e.onMouseEnter),t("mouseleave",e.onMouseLeave),t("mousemove",e.onMouseMove),t("click",e.onClick),i.push(()=>{e.destroy&&e.destroy(),e.className&&n.classList.remove(...e.className.split(" "));});}),()=>i.forEach(s=>s())},[JSON.stringify(l)]),c}exports.a=k;exports.b=L;//# sourceMappingURL=chunk-KXPTBR5B.cjs.map
3
- //# sourceMappingURL=chunk-KXPTBR5B.cjs.map
1
+ 'use strict';var chunk3AVUTKJ5_cjs=require('./chunk-3AVUTKJ5.cjs'),react=require('react');/* sparkfx v1.2.2 - Premium micro-interactions with Event Bus & Testing Kit */
2
+ function k(l,c){let n=react.useRef(null);return react.useEffect(()=>{if(!n.current)return;let i=chunk3AVUTKJ5_cjs.qa[l];if(typeof i!="function")return;let s=i(c),a=n.current;if(s.className){let t=s.className.split(" ");a.classList.add(...t);}s.style&&Object.entries(s.style).forEach(([t,r])=>{a.style.setProperty(t,String(r));});let u=[],e=(t,r)=>{if(!r)return;let o=t.replace(/^on/,"").toLowerCase();a.addEventListener(o,r),u.push(()=>a.removeEventListener(o,r));};return e("mouseenter",s.onMouseEnter),e("mouseleave",s.onMouseLeave),e("mousemove",s.onMouseMove),e("click",s.onClick),e("focus",s.onFocus),e("blur",s.onBlur),()=>{u.forEach(t=>t()),s.destroy&&s.destroy(),s.className&&a.classList.remove(...s.className.split(" "));}},[l,JSON.stringify(c)]),n}function L(l){let c=react.useRef(null);return react.useEffect(()=>{if(!c.current)return;let n=c.current,i=[];return l.forEach(({name:s,options:a})=>{let u=chunk3AVUTKJ5_cjs.qa[s];if(typeof u!="function")return;let e=u(a);e.className&&n.classList.add(...e.className.split(" ")),e.style&&Object.entries(e.style).forEach(([r,o])=>{n.style.setProperty(r,String(o));});let t=(r,o)=>{if(!o)return;let m=r.replace(/^on/,"").toLowerCase();n.addEventListener(m,o),i.push(()=>n.removeEventListener(m,o));};t("mouseenter",e.onMouseEnter),t("mouseleave",e.onMouseLeave),t("mousemove",e.onMouseMove),t("click",e.onClick),i.push(()=>{e.destroy&&e.destroy(),e.className&&n.classList.remove(...e.className.split(" "));});}),()=>i.forEach(s=>s())},[JSON.stringify(l)]),c}exports.a=k;exports.b=L;//# sourceMappingURL=chunk-GHLFOSXQ.cjs.map
3
+ //# sourceMappingURL=chunk-GHLFOSXQ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/react.ts"],"names":["useSpark","effectName","options","ref","useRef","useEffect","effectFn","spark","result","element","classes","key","value","cleanups","addEvent","name","handler","eventName","c","useSparkMultiple","effects","allCleanups","n","h","ev"],"mappings":"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","file":"chunk-KXPTBR5B.cjs","sourcesContent":["/**\r\n * sparkfx - React Adapter\r\n * Hooks and components for React integration\r\n */\r\n\r\nimport { useEffect, useRef, useMemo } from 'react'\r\nimport { spark } from '../index'\r\nimport type { SparkEffectName, SparkBaseOptions, SparkResult } from '../core/types'\r\nimport clsx from 'clsx'\r\n\r\n/**\r\n * Hook to apply a single spark effect to a ref\r\n * @param effectName Name of the effect to apply\r\n * @param options Effect options\r\n * @returns React ref to attach to the target element\r\n */\r\nexport function useSpark<T extends HTMLElement = HTMLElement>(\r\n effectName: SparkEffectName,\r\n options?: SparkBaseOptions\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n\r\n // Apply the effect\r\n const effectFn = (spark as any)[effectName]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n const element = ref.current\r\n\r\n // Apply class\r\n if (result.className) {\r\n const classes = result.className.split(' ')\r\n element.classList.add(...classes)\r\n }\r\n\r\n // Apply styles\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n // Apply events\r\n const cleanups: (() => void)[] = []\r\n\r\n const addEvent = (name: string, handler?: (e: any) => void) => {\r\n if (!handler) return\r\n const eventName = name.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(eventName, handler)\r\n cleanups.push(() => element.removeEventListener(eventName, handler))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n addEvent('focus', result.onFocus)\r\n addEvent('blur', result.onBlur)\r\n\r\n return () => {\r\n cleanups.forEach(c => c())\r\n if (result.destroy) result.destroy()\r\n if (result.className) {\r\n element.classList.remove(...result.className.split(' '))\r\n }\r\n }\r\n }, [effectName, JSON.stringify(options)])\r\n\r\n return ref\r\n}\r\n\r\n/**\r\n * Hook for multiple effects\r\n */\r\nexport function useSparkMultiple<T extends HTMLElement = HTMLElement>(\r\n effects: { name: SparkEffectName; options?: SparkBaseOptions }[]\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n const element = ref.current\r\n const allCleanups: (() => void)[] = []\r\n\r\n effects.forEach(({ name, options }) => {\r\n const effectFn = (spark as any)[name]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n\r\n if (result.className) {\r\n element.classList.add(...result.className.split(' '))\r\n }\r\n\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n const addEvent = (n: string, h?: (e: any) => void) => {\r\n if (!h) return\r\n const ev = n.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(ev, h)\r\n allCleanups.push(() => element.removeEventListener(ev, h))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n\r\n allCleanups.push(() => {\r\n if (result.destroy) result.destroy()\r\n if (result.className) element.classList.remove(...result.className.split(' '))\r\n })\r\n })\r\n\r\n return () => allCleanups.forEach(c => c())\r\n }, [JSON.stringify(effects)])\r\n\r\n return ref\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/adapters/react.ts"],"names":["useSpark","effectName","options","ref","useRef","useEffect","effectFn","spark","result","element","classes","key","value","cleanups","addEvent","name","handler","eventName","c","useSparkMultiple","effects","allCleanups","n","h","ev"],"mappings":"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","file":"chunk-GHLFOSXQ.cjs","sourcesContent":["/**\r\n * sparkfx - React Adapter\r\n * Hooks and components for React integration\r\n */\r\n\r\nimport { useEffect, useRef, useMemo } from 'react'\r\nimport { spark } from '../index'\r\nimport type { SparkEffectName, SparkBaseOptions, SparkResult } from '../core/types'\r\nimport clsx from 'clsx'\r\n\r\n/**\r\n * Hook to apply a single spark effect to a ref\r\n * @param effectName Name of the effect to apply\r\n * @param options Effect options\r\n * @returns React ref to attach to the target element\r\n */\r\nexport function useSpark<T extends HTMLElement = HTMLElement>(\r\n effectName: SparkEffectName,\r\n options?: SparkBaseOptions\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n\r\n // Apply the effect\r\n const effectFn = (spark as any)[effectName]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n const element = ref.current\r\n\r\n // Apply class\r\n if (result.className) {\r\n const classes = result.className.split(' ')\r\n element.classList.add(...classes)\r\n }\r\n\r\n // Apply styles\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n // Apply events\r\n const cleanups: (() => void)[] = []\r\n\r\n const addEvent = (name: string, handler?: (e: any) => void) => {\r\n if (!handler) return\r\n const eventName = name.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(eventName, handler)\r\n cleanups.push(() => element.removeEventListener(eventName, handler))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n addEvent('focus', result.onFocus)\r\n addEvent('blur', result.onBlur)\r\n\r\n return () => {\r\n cleanups.forEach(c => c())\r\n if (result.destroy) result.destroy()\r\n if (result.className) {\r\n element.classList.remove(...result.className.split(' '))\r\n }\r\n }\r\n }, [effectName, JSON.stringify(options)])\r\n\r\n return ref\r\n}\r\n\r\n/**\r\n * Hook for multiple effects\r\n */\r\nexport function useSparkMultiple<T extends HTMLElement = HTMLElement>(\r\n effects: { name: SparkEffectName; options?: SparkBaseOptions }[]\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n const element = ref.current\r\n const allCleanups: (() => void)[] = []\r\n\r\n effects.forEach(({ name, options }) => {\r\n const effectFn = (spark as any)[name]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n\r\n if (result.className) {\r\n element.classList.add(...result.className.split(' '))\r\n }\r\n\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n const addEvent = (n: string, h?: (e: any) => void) => {\r\n if (!h) return\r\n const ev = n.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(ev, h)\r\n allCleanups.push(() => element.removeEventListener(ev, h))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n\r\n allCleanups.push(() => {\r\n if (result.destroy) result.destroy()\r\n if (result.className) element.classList.remove(...result.className.split(' '))\r\n })\r\n })\r\n\r\n return () => allCleanups.forEach(c => c())\r\n }, [JSON.stringify(effects)])\r\n\r\n return ref\r\n}\r\n"]}
@@ -1,3 +1,3 @@
1
- 'use strict';/* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
2
- var d=class{subscriptions=new Map;triggerRules=new Map;eventHistory=[];maxHistorySize=100;subscriptionCounter=0;isEnabledFlag=true;isPausedFlag=false;generateSubscriptionId(){return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`}matchesSelector(t,e){if(!t)return false;try{return t.matches(e)}catch{return false}}getElement(t){return typeof t=="string"?typeof document<"u"?document.querySelector(t):null:t}recordEvent(t){this.eventHistory.push(t),this.eventHistory.length>this.maxHistorySize&&this.eventHistory.shift();}on(t,e,s={}){let r={handler:e,options:s,id:this.generateSubscriptionId()};return this.subscriptions.has(t)||this.subscriptions.set(t,new Set),this.subscriptions.get(t).add(r),()=>{let o=this.subscriptions.get(t);if(o){for(let u of o)if(u.id===r.id){o.delete(u);break}}}}once(t,e){return this.on(t,e,{once:true})}off(t){this.subscriptions.delete(t);}emit(t,e={}){if(!this.isEnabledFlag||this.isPausedFlag)return;let s={timestamp:Date.now(),...e};this.recordEvent(s);let r=this.subscriptions.get(t)??new Set,o=this.subscriptions.get("*")??new Set,u=[...r,...o].sort((i,n)=>(n.options.priority??0)-(i.options.priority??0)),l=[];for(let i of u)if(!(i.options.filter&&!this.matchesSelector(s.element,i.options.filter))){try{i.handler(s);}catch(n){console.error("[SparkFX EventBus] Handler error:",n),this.emit("animation:error",{data:{error:n,originalEvent:t}});}i.options.once&&l.push({event:t,sub:i});}for(let{event:i,sub:n}of l){let p=this.subscriptions.get(i);p&&p.delete(n);let c=this.subscriptions.get("*");c&&c.delete(n);}}when(t,e="complete"){let s=`animation:${e}`,r=this;return {trigger(o,u,l){let i=r.on(s,n=>{if(r.matchesSelector(n.element,t)){let p=r.getElement(o);p&&r.emit("animation:start",{element:p,effect:u,data:{triggeredBy:n,options:l,source:t,target:o}});}});return {and(n,p,c){return r.when(t,e).trigger(n,p,c)},unsubscribe:i}}}}clear(){this.subscriptions.clear(),this.triggerRules.clear(),this.eventHistory.length=0;}enable(){this.isEnabledFlag=true;}disable(){this.isEnabledFlag=false;}pause(){this.isPausedFlag=true;}resume(){this.isPausedFlag=false;}getHistory(){return [...this.eventHistory]}getSubscriptionCount(t){if(t)return this.subscriptions.get(t)?.size??0;let e=0;for(let s of this.subscriptions.values())e+=s.size;return e}get enabled(){return this.isEnabledFlag}get paused(){return this.isPausedFlag}},a=new d;var b=a.on.bind(a),v=a.once.bind(a),m=a.emit.bind(a),h=a.when.bind(a);exports.a=d;exports.b=a;exports.c=b;exports.d=v;exports.e=m;exports.f=h;//# sourceMappingURL=chunk-Y5V7MOLA.cjs.map
3
- //# sourceMappingURL=chunk-Y5V7MOLA.cjs.map
1
+ 'use strict';/* sparkfx v1.2.2 - Premium micro-interactions with Event Bus & Testing Kit */
2
+ var d=class{subscriptions=new Map;triggerRules=new Map;eventHistory=[];maxHistorySize=100;subscriptionCounter=0;isEnabledFlag=true;isPausedFlag=false;generateSubscriptionId(){return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`}matchesSelector(t,e){if(!t)return false;try{return t.matches(e)}catch{return false}}getElement(t){return typeof t=="string"?typeof document<"u"?document.querySelector(t):null:t}recordEvent(t){this.eventHistory.push(t),this.eventHistory.length>this.maxHistorySize&&this.eventHistory.shift();}on(t,e,s={}){let r={handler:e,options:s,id:this.generateSubscriptionId()};return this.subscriptions.has(t)||this.subscriptions.set(t,new Set),this.subscriptions.get(t).add(r),()=>{let o=this.subscriptions.get(t);if(o){for(let u of o)if(u.id===r.id){o.delete(u);break}}}}once(t,e){return this.on(t,e,{once:true})}off(t){this.subscriptions.delete(t);}emit(t,e={}){if(!this.isEnabledFlag||this.isPausedFlag)return;let s={timestamp:Date.now(),...e};this.recordEvent(s);let r=this.subscriptions.get(t)??new Set,o=this.subscriptions.get("*")??new Set,u=[...r,...o].sort((i,n)=>(n.options.priority??0)-(i.options.priority??0)),l=[];for(let i of u)if(!(i.options.filter&&!this.matchesSelector(s.element,i.options.filter))){try{i.handler(s);}catch(n){console.error("[SparkFX EventBus] Handler error:",n),this.emit("animation:error",{data:{error:n,originalEvent:t}});}i.options.once&&l.push({event:t,sub:i});}for(let{event:i,sub:n}of l){let p=this.subscriptions.get(i);p&&p.delete(n);let c=this.subscriptions.get("*");c&&c.delete(n);}}when(t,e="complete"){let s=`animation:${e}`,r=this;return {trigger(o,u,l){let i=r.on(s,n=>{if(r.matchesSelector(n.element,t)){let p=r.getElement(o);p&&r.emit("animation:start",{element:p,effect:u,data:{triggeredBy:n,options:l,source:t,target:o}});}});return {and(n,p,c){return r.when(t,e).trigger(n,p,c)},unsubscribe:i}}}}clear(){this.subscriptions.clear(),this.triggerRules.clear(),this.eventHistory.length=0;}enable(){this.isEnabledFlag=true;}disable(){this.isEnabledFlag=false;}pause(){this.isPausedFlag=true;}resume(){this.isPausedFlag=false;}getHistory(){return [...this.eventHistory]}getSubscriptionCount(t){if(t)return this.subscriptions.get(t)?.size??0;let e=0;for(let s of this.subscriptions.values())e+=s.size;return e}get enabled(){return this.isEnabledFlag}get paused(){return this.isPausedFlag}},a=new d;var b=a.on.bind(a),v=a.once.bind(a),m=a.emit.bind(a),h=a.when.bind(a);exports.a=d;exports.b=a;exports.c=b;exports.d=v;exports.e=m;exports.f=h;//# sourceMappingURL=chunk-HB6NE443.cjs.map
3
+ //# sourceMappingURL=chunk-HB6NE443.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/event-bus.ts"],"names":["SparkEventBus","element","selector","selectorOrElement","event","eventType","handler","options","subscription","subs","sub","payload","fullPayload","specificHandlers","wildcardHandlers","allHandlers","a","b","toRemove","error","wildcards","sourceSelector","eventSuffix","self","targetSelector","effectName","unsubscribe","target","nextTarget","nextEffect","nextOptions","total","eventBus","on","once","emit","when"],"mappings":"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","file":"chunk-Y5V7MOLA.cjs","sourcesContent":["/**\r\n * SparkFX Event Bus - Animation Event System\r\n * \r\n * Enables communication between animations on different elements.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { eventBus } from 'sparkfx'\r\n * \r\n * // Listen to animation events\r\n * eventBus.on('animation:start', ({ element, effect }) => {\r\n * console.log(`${effect} started on`, element)\r\n * })\r\n * \r\n * // Trigger animations based on other animations\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * \r\n * // Chain animations\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n * \r\n * @version 1.2.1\r\n */\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/** Animation lifecycle events */\r\nexport type AnimationEventType =\r\n | 'animation:start'\r\n | 'animation:progress'\r\n | 'animation:complete'\r\n | 'animation:cancel'\r\n | 'animation:pause'\r\n | 'animation:resume'\r\n | 'animation:error'\r\n\r\n/** Custom event types */\r\nexport type CustomEventType = `custom:${string}`\r\n\r\n/** All event types */\r\nexport type SparkEventType = AnimationEventType | CustomEventType | '*'\r\n\r\n/** Event payload structure */\r\nexport interface SparkEventPayload {\r\n /** Target element (if applicable) */\r\n element?: Element | null\r\n /** Effect name (if applicable) */\r\n effect?: string\r\n /** Animation progress (0-1) */\r\n progress?: number\r\n /** Animation ID */\r\n animationId?: string\r\n /** Timestamp when event occurred */\r\n timestamp: number\r\n /** Additional custom data */\r\n data?: Record<string, unknown>\r\n}\r\n\r\n/** Event handler function type */\r\nexport type SparkEventHandler = (payload: SparkEventPayload) => void\r\n\r\n/** Subscription options */\r\nexport interface SubscriptionOptions {\r\n /** Only trigger once */\r\n once?: boolean\r\n /** Priority (higher = earlier execution) */\r\n priority?: number\r\n /** Filter by element selector */\r\n filter?: string\r\n}\r\n\r\n/** Subscription record */\r\ninterface Subscription {\r\n handler: SparkEventHandler\r\n options: SubscriptionOptions\r\n id: string\r\n}\r\n\r\n// ============================================================================\r\n// SPARK EVENT BUS CLASS\r\n// ============================================================================\r\n\r\n/**\r\n * SparkFX Event Bus Class\r\n * Singleton pattern with proper encapsulation\r\n */\r\nclass SparkEventBus {\r\n private readonly subscriptions = new Map<SparkEventType, Set<Subscription>>()\r\n private readonly triggerRules = new Map<string, { targetSelector: string; effectName: string; options?: Record<string, unknown> }[]>()\r\n private readonly eventHistory: SparkEventPayload[] = []\r\n private readonly maxHistorySize = 100\r\n\r\n private subscriptionCounter = 0\r\n private isEnabledFlag = true\r\n private isPausedFlag = false\r\n\r\n // ============================================================================\r\n // UTILITY METHODS\r\n // ============================================================================\r\n\r\n private generateSubscriptionId(): string {\r\n return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`\r\n }\r\n\r\n private matchesSelector(element: Element | null | undefined, selector: string): boolean {\r\n if (!element) return false\r\n try {\r\n return element.matches(selector)\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n private getElement(selectorOrElement: string | Element): Element | null {\r\n if (typeof selectorOrElement === 'string') {\r\n return typeof document !== 'undefined'\r\n ? document.querySelector(selectorOrElement)\r\n : null\r\n }\r\n return selectorOrElement\r\n }\r\n\r\n private recordEvent(event: SparkEventPayload): void {\r\n this.eventHistory.push(event)\r\n if (this.eventHistory.length > this.maxHistorySize) {\r\n this.eventHistory.shift()\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // CORE API\r\n // ============================================================================\r\n\r\n /**\r\n * Subscribe to an event\r\n * @returns Unsubscribe function\r\n */\r\n on(\r\n eventType: SparkEventType,\r\n handler: SparkEventHandler,\r\n options: SubscriptionOptions = {}\r\n ): () => void {\r\n const subscription: Subscription = {\r\n handler,\r\n options,\r\n id: this.generateSubscriptionId()\r\n }\r\n\r\n if (!this.subscriptions.has(eventType)) {\r\n this.subscriptions.set(eventType, new Set())\r\n }\r\n this.subscriptions.get(eventType)!.add(subscription)\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n const subs = this.subscriptions.get(eventType)\r\n if (subs) {\r\n for (const sub of subs) {\r\n if (sub.id === subscription.id) {\r\n subs.delete(sub)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to an event (one-time only)\r\n */\r\n once(eventType: SparkEventType, handler: SparkEventHandler): () => void {\r\n return this.on(eventType, handler, { once: true })\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event type\r\n */\r\n off(eventType: SparkEventType): void {\r\n this.subscriptions.delete(eventType)\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n emit(eventType: SparkEventType, payload: Partial<SparkEventPayload> = {}): void {\r\n if (!this.isEnabledFlag || this.isPausedFlag) return\r\n\r\n const fullPayload: SparkEventPayload = {\r\n timestamp: Date.now(),\r\n ...payload\r\n }\r\n\r\n this.recordEvent(fullPayload)\r\n\r\n // Get handlers for specific event type\r\n const specificHandlers = this.subscriptions.get(eventType) ?? new Set()\r\n\r\n // Get handlers for wildcard\r\n const wildcardHandlers = this.subscriptions.get('*') ?? new Set()\r\n\r\n // Combine and sort by priority\r\n const allHandlers = [...specificHandlers, ...wildcardHandlers]\r\n .sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))\r\n\r\n // Execute handlers\r\n const toRemove: { event: SparkEventType; sub: Subscription }[] = []\r\n\r\n for (const subscription of allHandlers) {\r\n // Check filter\r\n if (subscription.options.filter) {\r\n if (!this.matchesSelector(fullPayload.element, subscription.options.filter)) {\r\n continue\r\n }\r\n }\r\n\r\n try {\r\n subscription.handler(fullPayload)\r\n } catch (error) {\r\n console.error('[SparkFX EventBus] Handler error:', error)\r\n this.emit('animation:error', {\r\n data: { error, originalEvent: eventType }\r\n })\r\n }\r\n\r\n // Mark for removal if once\r\n if (subscription.options.once) {\r\n toRemove.push({ event: eventType, sub: subscription })\r\n }\r\n }\r\n\r\n // Remove one-time handlers\r\n for (const { event, sub } of toRemove) {\r\n const subs = this.subscriptions.get(event)\r\n if (subs) subs.delete(sub)\r\n const wildcards = this.subscriptions.get('*')\r\n if (wildcards) wildcards.delete(sub)\r\n }\r\n }\r\n\r\n /**\r\n * Create a trigger rule: when element animates, trigger another animation\r\n * \r\n * @example\r\n * ```typescript\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n */\r\n when(\r\n sourceSelector: string,\r\n eventSuffix: 'start' | 'complete' | 'pause' | 'resume' = 'complete'\r\n ) {\r\n const eventType: AnimationEventType = `animation:${eventSuffix}`\r\n const self = this\r\n\r\n return {\r\n trigger(\r\n targetSelector: string,\r\n effectName: string,\r\n options?: Record<string, unknown>\r\n ) {\r\n // Set up listener for source element\r\n const unsubscribe = self.on(eventType, (payload) => {\r\n if (self.matchesSelector(payload.element, sourceSelector)) {\r\n const target = self.getElement(targetSelector)\r\n if (target) {\r\n self.emit('animation:start', {\r\n element: target,\r\n effect: effectName,\r\n data: {\r\n triggeredBy: payload,\r\n options,\r\n source: sourceSelector,\r\n target: targetSelector\r\n }\r\n })\r\n }\r\n }\r\n })\r\n\r\n // Return chainable object\r\n return {\r\n and(nextTarget: string, nextEffect: string, nextOptions?: Record<string, unknown>) {\r\n return self.when(sourceSelector, eventSuffix).trigger(nextTarget, nextEffect, nextOptions)\r\n },\r\n unsubscribe\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners and rules\r\n */\r\n clear(): void {\r\n this.subscriptions.clear()\r\n this.triggerRules.clear()\r\n this.eventHistory.length = 0\r\n }\r\n\r\n // ============================================================================\r\n // CONTROL API\r\n // ============================================================================\r\n\r\n /** Enable the event bus */\r\n enable(): void {\r\n this.isEnabledFlag = true\r\n }\r\n\r\n /** Disable the event bus (events will be ignored) */\r\n disable(): void {\r\n this.isEnabledFlag = false\r\n }\r\n\r\n /** Pause event processing */\r\n pause(): void {\r\n this.isPausedFlag = true\r\n }\r\n\r\n /** Resume event processing */\r\n resume(): void {\r\n this.isPausedFlag = false\r\n }\r\n\r\n // ============================================================================\r\n // INSPECTION API\r\n // ============================================================================\r\n\r\n /** Get event history */\r\n getHistory(): readonly SparkEventPayload[] {\r\n return [...this.eventHistory]\r\n }\r\n\r\n /** Get subscription count */\r\n getSubscriptionCount(eventType?: SparkEventType): number {\r\n if (eventType) {\r\n return this.subscriptions.get(eventType)?.size ?? 0\r\n }\r\n let total = 0\r\n for (const subs of this.subscriptions.values()) {\r\n total += subs.size\r\n }\r\n return total\r\n }\r\n\r\n /** Check if event bus is enabled */\r\n get enabled(): boolean {\r\n return this.isEnabledFlag\r\n }\r\n\r\n /** Check if event bus is paused */\r\n get paused(): boolean {\r\n return this.isPausedFlag\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// SINGLETON EXPORT\r\n// ============================================================================\r\n\r\n/** Global event bus instance */\r\nexport const eventBus = new SparkEventBus()\r\n\r\n/** Export class for testing purposes */\r\nexport { SparkEventBus }\r\n\r\n// ============================================================================\r\n// CONVENIENCE FUNCTIONS\r\n// ============================================================================\r\n\r\n/** Shorthand for eventBus.on */\r\nexport const on = eventBus.on.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.once */\r\nexport const once = eventBus.once.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.emit */\r\nexport const emit = eventBus.emit.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.when */\r\nexport const when = eventBus.when.bind(eventBus)\r\n"]}
1
+ {"version":3,"sources":["../src/core/event-bus.ts"],"names":["SparkEventBus","element","selector","selectorOrElement","event","eventType","handler","options","subscription","subs","sub","payload","fullPayload","specificHandlers","wildcardHandlers","allHandlers","a","b","toRemove","error","wildcards","sourceSelector","eventSuffix","self","targetSelector","effectName","unsubscribe","target","nextTarget","nextEffect","nextOptions","total","eventBus","on","once","emit","when"],"mappings":"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","file":"chunk-HB6NE443.cjs","sourcesContent":["/**\r\n * SparkFX Event Bus - Animation Event System\r\n * \r\n * Enables communication between animations on different elements.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { eventBus } from 'sparkfx'\r\n * \r\n * // Listen to animation events\r\n * eventBus.on('animation:start', ({ element, effect }) => {\r\n * console.log(`${effect} started on`, element)\r\n * })\r\n * \r\n * // Trigger animations based on other animations\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * \r\n * // Chain animations\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n * \r\n * @version 1.2.1\r\n */\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/** Animation lifecycle events */\r\nexport type AnimationEventType =\r\n | 'animation:start'\r\n | 'animation:progress'\r\n | 'animation:complete'\r\n | 'animation:cancel'\r\n | 'animation:pause'\r\n | 'animation:resume'\r\n | 'animation:error'\r\n\r\n/** Custom event types */\r\nexport type CustomEventType = `custom:${string}`\r\n\r\n/** All event types */\r\nexport type SparkEventType = AnimationEventType | CustomEventType | '*'\r\n\r\n/** Event payload structure */\r\nexport interface SparkEventPayload {\r\n /** Target element (if applicable) */\r\n element?: Element | null\r\n /** Effect name (if applicable) */\r\n effect?: string\r\n /** Animation progress (0-1) */\r\n progress?: number\r\n /** Animation ID */\r\n animationId?: string\r\n /** Timestamp when event occurred */\r\n timestamp: number\r\n /** Additional custom data */\r\n data?: Record<string, unknown>\r\n}\r\n\r\n/** Event handler function type */\r\nexport type SparkEventHandler = (payload: SparkEventPayload) => void\r\n\r\n/** Subscription options */\r\nexport interface SubscriptionOptions {\r\n /** Only trigger once */\r\n once?: boolean\r\n /** Priority (higher = earlier execution) */\r\n priority?: number\r\n /** Filter by element selector */\r\n filter?: string\r\n}\r\n\r\n/** Subscription record */\r\ninterface Subscription {\r\n handler: SparkEventHandler\r\n options: SubscriptionOptions\r\n id: string\r\n}\r\n\r\n// ============================================================================\r\n// SPARK EVENT BUS CLASS\r\n// ============================================================================\r\n\r\n/**\r\n * SparkFX Event Bus Class\r\n * Singleton pattern with proper encapsulation\r\n */\r\nclass SparkEventBus {\r\n private readonly subscriptions = new Map<SparkEventType, Set<Subscription>>()\r\n private readonly triggerRules = new Map<string, { targetSelector: string; effectName: string; options?: Record<string, unknown> }[]>()\r\n private readonly eventHistory: SparkEventPayload[] = []\r\n private readonly maxHistorySize = 100\r\n\r\n private subscriptionCounter = 0\r\n private isEnabledFlag = true\r\n private isPausedFlag = false\r\n\r\n // ============================================================================\r\n // UTILITY METHODS\r\n // ============================================================================\r\n\r\n private generateSubscriptionId(): string {\r\n return `sub_${++this.subscriptionCounter}_${Date.now().toString(36)}`\r\n }\r\n\r\n private matchesSelector(element: Element | null | undefined, selector: string): boolean {\r\n if (!element) return false\r\n try {\r\n return element.matches(selector)\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n private getElement(selectorOrElement: string | Element): Element | null {\r\n if (typeof selectorOrElement === 'string') {\r\n return typeof document !== 'undefined'\r\n ? document.querySelector(selectorOrElement)\r\n : null\r\n }\r\n return selectorOrElement\r\n }\r\n\r\n private recordEvent(event: SparkEventPayload): void {\r\n this.eventHistory.push(event)\r\n if (this.eventHistory.length > this.maxHistorySize) {\r\n this.eventHistory.shift()\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // CORE API\r\n // ============================================================================\r\n\r\n /**\r\n * Subscribe to an event\r\n * @returns Unsubscribe function\r\n */\r\n on(\r\n eventType: SparkEventType,\r\n handler: SparkEventHandler,\r\n options: SubscriptionOptions = {}\r\n ): () => void {\r\n const subscription: Subscription = {\r\n handler,\r\n options,\r\n id: this.generateSubscriptionId()\r\n }\r\n\r\n if (!this.subscriptions.has(eventType)) {\r\n this.subscriptions.set(eventType, new Set())\r\n }\r\n this.subscriptions.get(eventType)!.add(subscription)\r\n\r\n // Return unsubscribe function\r\n return () => {\r\n const subs = this.subscriptions.get(eventType)\r\n if (subs) {\r\n for (const sub of subs) {\r\n if (sub.id === subscription.id) {\r\n subs.delete(sub)\r\n break\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to an event (one-time only)\r\n */\r\n once(eventType: SparkEventType, handler: SparkEventHandler): () => void {\r\n return this.on(eventType, handler, { once: true })\r\n }\r\n\r\n /**\r\n * Remove all listeners for an event type\r\n */\r\n off(eventType: SparkEventType): void {\r\n this.subscriptions.delete(eventType)\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n emit(eventType: SparkEventType, payload: Partial<SparkEventPayload> = {}): void {\r\n if (!this.isEnabledFlag || this.isPausedFlag) return\r\n\r\n const fullPayload: SparkEventPayload = {\r\n timestamp: Date.now(),\r\n ...payload\r\n }\r\n\r\n this.recordEvent(fullPayload)\r\n\r\n // Get handlers for specific event type\r\n const specificHandlers = this.subscriptions.get(eventType) ?? new Set()\r\n\r\n // Get handlers for wildcard\r\n const wildcardHandlers = this.subscriptions.get('*') ?? new Set()\r\n\r\n // Combine and sort by priority\r\n const allHandlers = [...specificHandlers, ...wildcardHandlers]\r\n .sort((a, b) => (b.options.priority ?? 0) - (a.options.priority ?? 0))\r\n\r\n // Execute handlers\r\n const toRemove: { event: SparkEventType; sub: Subscription }[] = []\r\n\r\n for (const subscription of allHandlers) {\r\n // Check filter\r\n if (subscription.options.filter) {\r\n if (!this.matchesSelector(fullPayload.element, subscription.options.filter)) {\r\n continue\r\n }\r\n }\r\n\r\n try {\r\n subscription.handler(fullPayload)\r\n } catch (error) {\r\n console.error('[SparkFX EventBus] Handler error:', error)\r\n this.emit('animation:error', {\r\n data: { error, originalEvent: eventType }\r\n })\r\n }\r\n\r\n // Mark for removal if once\r\n if (subscription.options.once) {\r\n toRemove.push({ event: eventType, sub: subscription })\r\n }\r\n }\r\n\r\n // Remove one-time handlers\r\n for (const { event, sub } of toRemove) {\r\n const subs = this.subscriptions.get(event)\r\n if (subs) subs.delete(sub)\r\n const wildcards = this.subscriptions.get('*')\r\n if (wildcards) wildcards.delete(sub)\r\n }\r\n }\r\n\r\n /**\r\n * Create a trigger rule: when element animates, trigger another animation\r\n * \r\n * @example\r\n * ```typescript\r\n * eventBus.when('#modal', 'start').trigger('#overlay', 'blur')\r\n * eventBus.when('.card', 'complete').trigger('.next-card', 'fadeIn')\r\n * ```\r\n */\r\n when(\r\n sourceSelector: string,\r\n eventSuffix: 'start' | 'complete' | 'pause' | 'resume' = 'complete'\r\n ) {\r\n const eventType: AnimationEventType = `animation:${eventSuffix}`\r\n const self = this\r\n\r\n return {\r\n trigger(\r\n targetSelector: string,\r\n effectName: string,\r\n options?: Record<string, unknown>\r\n ) {\r\n // Set up listener for source element\r\n const unsubscribe = self.on(eventType, (payload) => {\r\n if (self.matchesSelector(payload.element, sourceSelector)) {\r\n const target = self.getElement(targetSelector)\r\n if (target) {\r\n self.emit('animation:start', {\r\n element: target,\r\n effect: effectName,\r\n data: {\r\n triggeredBy: payload,\r\n options,\r\n source: sourceSelector,\r\n target: targetSelector\r\n }\r\n })\r\n }\r\n }\r\n })\r\n\r\n // Return chainable object\r\n return {\r\n and(nextTarget: string, nextEffect: string, nextOptions?: Record<string, unknown>) {\r\n return self.when(sourceSelector, eventSuffix).trigger(nextTarget, nextEffect, nextOptions)\r\n },\r\n unsubscribe\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners and rules\r\n */\r\n clear(): void {\r\n this.subscriptions.clear()\r\n this.triggerRules.clear()\r\n this.eventHistory.length = 0\r\n }\r\n\r\n // ============================================================================\r\n // CONTROL API\r\n // ============================================================================\r\n\r\n /** Enable the event bus */\r\n enable(): void {\r\n this.isEnabledFlag = true\r\n }\r\n\r\n /** Disable the event bus (events will be ignored) */\r\n disable(): void {\r\n this.isEnabledFlag = false\r\n }\r\n\r\n /** Pause event processing */\r\n pause(): void {\r\n this.isPausedFlag = true\r\n }\r\n\r\n /** Resume event processing */\r\n resume(): void {\r\n this.isPausedFlag = false\r\n }\r\n\r\n // ============================================================================\r\n // INSPECTION API\r\n // ============================================================================\r\n\r\n /** Get event history */\r\n getHistory(): readonly SparkEventPayload[] {\r\n return [...this.eventHistory]\r\n }\r\n\r\n /** Get subscription count */\r\n getSubscriptionCount(eventType?: SparkEventType): number {\r\n if (eventType) {\r\n return this.subscriptions.get(eventType)?.size ?? 0\r\n }\r\n let total = 0\r\n for (const subs of this.subscriptions.values()) {\r\n total += subs.size\r\n }\r\n return total\r\n }\r\n\r\n /** Check if event bus is enabled */\r\n get enabled(): boolean {\r\n return this.isEnabledFlag\r\n }\r\n\r\n /** Check if event bus is paused */\r\n get paused(): boolean {\r\n return this.isPausedFlag\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// SINGLETON EXPORT\r\n// ============================================================================\r\n\r\n/** Global event bus instance */\r\nexport const eventBus = new SparkEventBus()\r\n\r\n/** Export class for testing purposes */\r\nexport { SparkEventBus }\r\n\r\n// ============================================================================\r\n// CONVENIENCE FUNCTIONS\r\n// ============================================================================\r\n\r\n/** Shorthand for eventBus.on */\r\nexport const on = eventBus.on.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.once */\r\nexport const once = eventBus.once.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.emit */\r\nexport const emit = eventBus.emit.bind(eventBus)\r\n\r\n/** Shorthand for eventBus.when */\r\nexport const when = eventBus.when.bind(eventBus)\r\n"]}
@@ -1,3 +1,3 @@
1
- import {qa}from'./chunk-4BGOBPG6.js';import {useRef,useEffect}from'react';/* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
2
- function k(l,c){let n=useRef(null);return useEffect(()=>{if(!n.current)return;let i=qa[l];if(typeof i!="function")return;let s=i(c),a=n.current;if(s.className){let t=s.className.split(" ");a.classList.add(...t);}s.style&&Object.entries(s.style).forEach(([t,r])=>{a.style.setProperty(t,String(r));});let u=[],e=(t,r)=>{if(!r)return;let o=t.replace(/^on/,"").toLowerCase();a.addEventListener(o,r),u.push(()=>a.removeEventListener(o,r));};return e("mouseenter",s.onMouseEnter),e("mouseleave",s.onMouseLeave),e("mousemove",s.onMouseMove),e("click",s.onClick),e("focus",s.onFocus),e("blur",s.onBlur),()=>{u.forEach(t=>t()),s.destroy&&s.destroy(),s.className&&a.classList.remove(...s.className.split(" "));}},[l,JSON.stringify(c)]),n}function L(l){let c=useRef(null);return useEffect(()=>{if(!c.current)return;let n=c.current,i=[];return l.forEach(({name:s,options:a})=>{let u=qa[s];if(typeof u!="function")return;let e=u(a);e.className&&n.classList.add(...e.className.split(" ")),e.style&&Object.entries(e.style).forEach(([r,o])=>{n.style.setProperty(r,String(o));});let t=(r,o)=>{if(!o)return;let m=r.replace(/^on/,"").toLowerCase();n.addEventListener(m,o),i.push(()=>n.removeEventListener(m,o));};t("mouseenter",e.onMouseEnter),t("mouseleave",e.onMouseLeave),t("mousemove",e.onMouseMove),t("click",e.onClick),i.push(()=>{e.destroy&&e.destroy(),e.className&&n.classList.remove(...e.className.split(" "));});}),()=>i.forEach(s=>s())},[JSON.stringify(l)]),c}export{k as a,L as b};//# sourceMappingURL=chunk-5YDUWTOY.js.map
3
- //# sourceMappingURL=chunk-5YDUWTOY.js.map
1
+ import {qa}from'./chunk-SJKJ2GZW.js';import {useRef,useEffect}from'react';/* sparkfx v1.2.2 - Premium micro-interactions with Event Bus & Testing Kit */
2
+ function k(l,c){let n=useRef(null);return useEffect(()=>{if(!n.current)return;let i=qa[l];if(typeof i!="function")return;let s=i(c),a=n.current;if(s.className){let t=s.className.split(" ");a.classList.add(...t);}s.style&&Object.entries(s.style).forEach(([t,r])=>{a.style.setProperty(t,String(r));});let u=[],e=(t,r)=>{if(!r)return;let o=t.replace(/^on/,"").toLowerCase();a.addEventListener(o,r),u.push(()=>a.removeEventListener(o,r));};return e("mouseenter",s.onMouseEnter),e("mouseleave",s.onMouseLeave),e("mousemove",s.onMouseMove),e("click",s.onClick),e("focus",s.onFocus),e("blur",s.onBlur),()=>{u.forEach(t=>t()),s.destroy&&s.destroy(),s.className&&a.classList.remove(...s.className.split(" "));}},[l,JSON.stringify(c)]),n}function L(l){let c=useRef(null);return useEffect(()=>{if(!c.current)return;let n=c.current,i=[];return l.forEach(({name:s,options:a})=>{let u=qa[s];if(typeof u!="function")return;let e=u(a);e.className&&n.classList.add(...e.className.split(" ")),e.style&&Object.entries(e.style).forEach(([r,o])=>{n.style.setProperty(r,String(o));});let t=(r,o)=>{if(!o)return;let m=r.replace(/^on/,"").toLowerCase();n.addEventListener(m,o),i.push(()=>n.removeEventListener(m,o));};t("mouseenter",e.onMouseEnter),t("mouseleave",e.onMouseLeave),t("mousemove",e.onMouseMove),t("click",e.onClick),i.push(()=>{e.destroy&&e.destroy(),e.className&&n.classList.remove(...e.className.split(" "));});}),()=>i.forEach(s=>s())},[JSON.stringify(l)]),c}export{k as a,L as b};//# sourceMappingURL=chunk-LPB7JTCR.js.map
3
+ //# sourceMappingURL=chunk-LPB7JTCR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/react.ts"],"names":["useSpark","effectName","options","ref","useRef","useEffect","effectFn","spark","result","element","classes","key","value","cleanups","addEvent","name","handler","eventName","c","useSparkMultiple","effects","allCleanups","n","h","ev"],"mappings":"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","file":"chunk-5YDUWTOY.js","sourcesContent":["/**\r\n * sparkfx - React Adapter\r\n * Hooks and components for React integration\r\n */\r\n\r\nimport { useEffect, useRef, useMemo } from 'react'\r\nimport { spark } from '../index'\r\nimport type { SparkEffectName, SparkBaseOptions, SparkResult } from '../core/types'\r\nimport clsx from 'clsx'\r\n\r\n/**\r\n * Hook to apply a single spark effect to a ref\r\n * @param effectName Name of the effect to apply\r\n * @param options Effect options\r\n * @returns React ref to attach to the target element\r\n */\r\nexport function useSpark<T extends HTMLElement = HTMLElement>(\r\n effectName: SparkEffectName,\r\n options?: SparkBaseOptions\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n\r\n // Apply the effect\r\n const effectFn = (spark as any)[effectName]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n const element = ref.current\r\n\r\n // Apply class\r\n if (result.className) {\r\n const classes = result.className.split(' ')\r\n element.classList.add(...classes)\r\n }\r\n\r\n // Apply styles\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n // Apply events\r\n const cleanups: (() => void)[] = []\r\n\r\n const addEvent = (name: string, handler?: (e: any) => void) => {\r\n if (!handler) return\r\n const eventName = name.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(eventName, handler)\r\n cleanups.push(() => element.removeEventListener(eventName, handler))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n addEvent('focus', result.onFocus)\r\n addEvent('blur', result.onBlur)\r\n\r\n return () => {\r\n cleanups.forEach(c => c())\r\n if (result.destroy) result.destroy()\r\n if (result.className) {\r\n element.classList.remove(...result.className.split(' '))\r\n }\r\n }\r\n }, [effectName, JSON.stringify(options)])\r\n\r\n return ref\r\n}\r\n\r\n/**\r\n * Hook for multiple effects\r\n */\r\nexport function useSparkMultiple<T extends HTMLElement = HTMLElement>(\r\n effects: { name: SparkEffectName; options?: SparkBaseOptions }[]\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n const element = ref.current\r\n const allCleanups: (() => void)[] = []\r\n\r\n effects.forEach(({ name, options }) => {\r\n const effectFn = (spark as any)[name]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n\r\n if (result.className) {\r\n element.classList.add(...result.className.split(' '))\r\n }\r\n\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n const addEvent = (n: string, h?: (e: any) => void) => {\r\n if (!h) return\r\n const ev = n.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(ev, h)\r\n allCleanups.push(() => element.removeEventListener(ev, h))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n\r\n allCleanups.push(() => {\r\n if (result.destroy) result.destroy()\r\n if (result.className) element.classList.remove(...result.className.split(' '))\r\n })\r\n })\r\n\r\n return () => allCleanups.forEach(c => c())\r\n }, [JSON.stringify(effects)])\r\n\r\n return ref\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/adapters/react.ts"],"names":["useSpark","effectName","options","ref","useRef","useEffect","effectFn","spark","result","element","classes","key","value","cleanups","addEvent","name","handler","eventName","c","useSparkMultiple","effects","allCleanups","n","h","ev"],"mappings":"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","file":"chunk-LPB7JTCR.js","sourcesContent":["/**\r\n * sparkfx - React Adapter\r\n * Hooks and components for React integration\r\n */\r\n\r\nimport { useEffect, useRef, useMemo } from 'react'\r\nimport { spark } from '../index'\r\nimport type { SparkEffectName, SparkBaseOptions, SparkResult } from '../core/types'\r\nimport clsx from 'clsx'\r\n\r\n/**\r\n * Hook to apply a single spark effect to a ref\r\n * @param effectName Name of the effect to apply\r\n * @param options Effect options\r\n * @returns React ref to attach to the target element\r\n */\r\nexport function useSpark<T extends HTMLElement = HTMLElement>(\r\n effectName: SparkEffectName,\r\n options?: SparkBaseOptions\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n\r\n // Apply the effect\r\n const effectFn = (spark as any)[effectName]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n const element = ref.current\r\n\r\n // Apply class\r\n if (result.className) {\r\n const classes = result.className.split(' ')\r\n element.classList.add(...classes)\r\n }\r\n\r\n // Apply styles\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n // Apply events\r\n const cleanups: (() => void)[] = []\r\n\r\n const addEvent = (name: string, handler?: (e: any) => void) => {\r\n if (!handler) return\r\n const eventName = name.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(eventName, handler)\r\n cleanups.push(() => element.removeEventListener(eventName, handler))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n addEvent('focus', result.onFocus)\r\n addEvent('blur', result.onBlur)\r\n\r\n return () => {\r\n cleanups.forEach(c => c())\r\n if (result.destroy) result.destroy()\r\n if (result.className) {\r\n element.classList.remove(...result.className.split(' '))\r\n }\r\n }\r\n }, [effectName, JSON.stringify(options)])\r\n\r\n return ref\r\n}\r\n\r\n/**\r\n * Hook for multiple effects\r\n */\r\nexport function useSparkMultiple<T extends HTMLElement = HTMLElement>(\r\n effects: { name: SparkEffectName; options?: SparkBaseOptions }[]\r\n) {\r\n const ref = useRef<T>(null)\r\n\r\n useEffect(() => {\r\n if (!ref.current) return\r\n const element = ref.current\r\n const allCleanups: (() => void)[] = []\r\n\r\n effects.forEach(({ name, options }) => {\r\n const effectFn = (spark as any)[name]\r\n if (typeof effectFn !== 'function') return\r\n\r\n const result = effectFn(options) as SparkResult\r\n\r\n if (result.className) {\r\n element.classList.add(...result.className.split(' '))\r\n }\r\n\r\n if (result.style) {\r\n Object.entries(result.style).forEach(([key, value]) => {\r\n element.style.setProperty(key, String(value))\r\n })\r\n }\r\n\r\n const addEvent = (n: string, h?: (e: any) => void) => {\r\n if (!h) return\r\n const ev = n.replace(/^on/, '').toLowerCase()\r\n element.addEventListener(ev, h)\r\n allCleanups.push(() => element.removeEventListener(ev, h))\r\n }\r\n\r\n addEvent('mouseenter', result.onMouseEnter)\r\n addEvent('mouseleave', result.onMouseLeave)\r\n addEvent('mousemove', result.onMouseMove)\r\n addEvent('click', result.onClick)\r\n\r\n allCleanups.push(() => {\r\n if (result.destroy) result.destroy()\r\n if (result.className) element.classList.remove(...result.className.split(' '))\r\n })\r\n })\r\n\r\n return () => allCleanups.forEach(c => c())\r\n }, [JSON.stringify(effects)])\r\n\r\n return ref\r\n}\r\n"]}
@@ -1,4 +1,4 @@
1
- import $t from'clsx';/* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
1
+ import $t from'clsx';/* sparkfx v1.2.2 - Premium micro-interactions with Event Bus & Testing Kit */
2
2
  var Ie="sparkfx-styles",je=false,Fe=new Set,_e=`
3
3
  /* @lynch/spark base styles */
4
4
  .spark-effect {
@@ -768,16 +768,16 @@ ${e.trigger==="hover"?`
768
768
  .sparkfx-highlight-active::after {
769
769
  width: 100%;
770
770
  }
771
- `,document.head.appendChild(t);}function Ne(t){let e=l(t,fn);if(f(),mn(),!u(e))return {className:"sparkfx-effect sparkfx-reduced-motion"};let r=o=>{o.currentTarget.classList.add("sparkfx-highlight-active");},n=o=>{o.currentTarget.classList.remove("sparkfx-highlight-active");};return {className:$t("sparkfx-effect","sparkfx-highlight"),style:{...g(e),"--highlight-color":e.color,"--highlight-height":e.height},onMouseEnter:e.trigger==="hover"?r:void 0,onMouseLeave:e.trigger==="hover"?n:void 0}}var dn={bounce:_,pulse:J,lift:Z,scale:ee,shake:te,fade:re,slide:ne,rotate:oe,glow:ae,ripple:se,magnetic:ie,tilt:ce,elastic:le,jelly:pe,rubber:ue,morph:fe,glitch:me,blur:de,neon:ge,glass:ke,shimmer:he,gradient:ye,spotlight:xe,hologram:be,aurora:Se,matrix:ve,rainbow:we,parallax:Oe,float:Ee,flip3d:$e,swing:Me,orbit:Ce,reveal:Re,counter:Te,confetti:I,sparkle:q,firework:Ae,celebrate:Be,typewriter:Le,scramble:Pe,wave:He,highlight:Ne},Ki=dn;/**
772
- * SparkFX v1.2.1 - Micro-interactions for modern web applications
771
+ `,document.head.appendChild(t);}function Ne(t){let e=l(t,fn);if(f(),mn(),!u(e))return {className:"sparkfx-effect sparkfx-reduced-motion"};let r=o=>{o.currentTarget.classList.add("sparkfx-highlight-active");},n=o=>{o.currentTarget.classList.remove("sparkfx-highlight-active");};return {className:$t("sparkfx-effect","sparkfx-highlight"),style:{...g(e),"--highlight-color":e.color,"--highlight-height":e.height},onMouseEnter:e.trigger==="hover"?r:void 0,onMouseLeave:e.trigger==="hover"?n:void 0}}var dn={bounce:_,pulse:J,lift:Z,scale:ee,shake:te,fade:re,slide:ne,rotate:oe,glow:ae,ripple:se,magnetic:ie,tilt:ce,elastic:le,jelly:pe,rubber:ue,morph:fe,glitch:me,blur:de,neon:ge,glass:ke,shimmer:he,gradient:ye,spotlight:xe,hologram:be,aurora:Se,matrix:ve,rainbow:we,parallax:Oe,float:Ee,flip3d:$e,swing:Me,orbit:Ce,reveal:Re,counter:Te,confetti:I,sparkle:q,firework:Ae,celebrate:Be,typewriter:Le,scramble:Pe,wave:He,highlight:Ne},Gi=dn;/**
772
+ * SparkFX v1.2.2 - Micro-interactions for modern web applications
773
773
  * All effects are free and open source
774
774
  *
775
- * NEW in v1.2.1:
775
+ * Features:
776
+ * - 45+ Effects: Motion, scroll, visual, text animations
776
777
  * - Event Bus: Animation communication system
777
778
  * - Testing Kit: Jest/Vitest animation testing utilities
778
- * - Devtools: Browser debugging panel (Ctrl+Shift+S)
779
779
  *
780
- * @version 1.2.1
780
+ * @version 1.2.2
781
781
  * @license MIT
782
- */export{ve as $,bt as A,St as B,_ as C,J as D,Z as E,ee as F,te as G,re as H,ne as I,oe as J,ae as K,se as L,ie as M,ce as N,le as O,pe as P,ue as Q,fe as R,me as S,de as T,ge as U,ke as V,he as W,ye as X,xe as Y,be as Z,Se as _,f as a,we as aa,V as b,Oe as ba,Ze as c,Ee as ca,et as d,$e as da,tt as e,Me as ea,rt as f,Ce as fa,nt as g,Re as ga,ot as h,Te as ha,at as i,I as ia,st as j,q as ja,Q as k,Ae as ka,lt as l,Be as la,wn as m,Le as ma,w as n,Pe as na,ut as o,He as oa,ft as p,Ne as pa,dt as q,dn as qa,gt as r,Ki as ra,kt as s,On as t,En as u,ht as v,$n as w,yt as x,Mn as y,xt as z};//# sourceMappingURL=chunk-4BGOBPG6.js.map
783
- //# sourceMappingURL=chunk-4BGOBPG6.js.map
782
+ */export{ve as $,bt as A,St as B,_ as C,J as D,Z as E,ee as F,te as G,re as H,ne as I,oe as J,ae as K,se as L,ie as M,ce as N,le as O,pe as P,ue as Q,fe as R,me as S,de as T,ge as U,ke as V,he as W,ye as X,xe as Y,be as Z,Se as _,f as a,we as aa,V as b,Oe as ba,Ze as c,Ee as ca,et as d,$e as da,tt as e,Me as ea,rt as f,Ce as fa,nt as g,Re as ga,ot as h,Te as ha,at as i,I as ia,st as j,q as ja,Q as k,Ae as ka,lt as l,Be as la,wn as m,Le as ma,w as n,Pe as na,ut as o,He as oa,ft as p,Ne as pa,dt as q,dn as qa,gt as r,Gi as ra,kt as s,On as t,En as u,ht as v,$n as w,yt as x,Mn as y,xt as z};//# sourceMappingURL=chunk-SJKJ2GZW.js.map
783
+ //# sourceMappingURL=chunk-SJKJ2GZW.js.map