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,299 +0,0 @@
1
- import {b}from'./chunk-RD5XCTW4.js';/* sparkfx v1.2.1 - Premium micro-interactions with Event Bus, Testing Kit & Devtools */
2
- var c=`
3
- /* SparkFX Devtools Panel */
4
- .sparkfx-devtools {
5
- --sparkfx-bg: #1a1a2e;
6
- --sparkfx-bg-secondary: #16213e;
7
- --sparkfx-text: #eee;
8
- --sparkfx-text-dim: #888;
9
- --sparkfx-accent: #e94560;
10
- --sparkfx-success: #4ade80;
11
- --sparkfx-warning: #fbbf24;
12
- --sparkfx-border: #333;
13
-
14
- position: fixed;
15
- z-index: 999999;
16
- font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
17
- font-size: 12px;
18
- line-height: 1.4;
19
- color: var(--sparkfx-text);
20
- background: var(--sparkfx-bg);
21
- border: 1px solid var(--sparkfx-border);
22
- border-radius: 8px;
23
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
24
- min-width: 320px;
25
- max-width: 400px;
26
- max-height: 80vh;
27
- overflow: hidden;
28
- user-select: none;
29
- backdrop-filter: blur(8px);
30
- }
31
-
32
- .sparkfx-devtools.top-right { top: 16px; right: 16px; }
33
- .sparkfx-devtools.top-left { top: 16px; left: 16px; }
34
- .sparkfx-devtools.bottom-right { bottom: 16px; right: 16px; }
35
- .sparkfx-devtools.bottom-left { bottom: 16px; left: 16px; }
36
-
37
- .sparkfx-devtools.light {
38
- --sparkfx-bg: #ffffff;
39
- --sparkfx-bg-secondary: #f5f5f5;
40
- --sparkfx-text: #1a1a1a;
41
- --sparkfx-text-dim: #666;
42
- --sparkfx-border: #ddd;
43
- }
44
-
45
- .sparkfx-devtools-header {
46
- display: flex;
47
- align-items: center;
48
- justify-content: space-between;
49
- padding: 8px 12px;
50
- background: var(--sparkfx-bg-secondary);
51
- border-bottom: 1px solid var(--sparkfx-border);
52
- cursor: move;
53
- }
54
-
55
- .sparkfx-devtools-title {
56
- display: flex;
57
- align-items: center;
58
- gap: 8px;
59
- font-weight: 600;
60
- }
61
-
62
- .sparkfx-devtools-title::before {
63
- content: '\u26A1';
64
- }
65
-
66
- .sparkfx-devtools-close {
67
- background: none;
68
- border: none;
69
- color: var(--sparkfx-text-dim);
70
- cursor: pointer;
71
- padding: 4px;
72
- font-size: 16px;
73
- line-height: 1;
74
- }
75
-
76
- .sparkfx-devtools-close:hover {
77
- color: var(--sparkfx-accent);
78
- }
79
-
80
- .sparkfx-devtools-metrics {
81
- display: flex;
82
- gap: 16px;
83
- padding: 8px 12px;
84
- background: var(--sparkfx-bg-secondary);
85
- border-bottom: 1px solid var(--sparkfx-border);
86
- }
87
-
88
- .sparkfx-metric {
89
- display: flex;
90
- flex-direction: column;
91
- align-items: center;
92
- }
93
-
94
- .sparkfx-metric-value {
95
- font-size: 18px;
96
- font-weight: bold;
97
- }
98
-
99
- .sparkfx-metric-value.good { color: var(--sparkfx-success); }
100
- .sparkfx-metric-value.warning { color: var(--sparkfx-warning); }
101
- .sparkfx-metric-value.bad { color: var(--sparkfx-accent); }
102
-
103
- .sparkfx-metric-label {
104
- font-size: 10px;
105
- color: var(--sparkfx-text-dim);
106
- text-transform: uppercase;
107
- }
108
-
109
- .sparkfx-devtools-controls {
110
- display: flex;
111
- gap: 8px;
112
- padding: 8px 12px;
113
- border-bottom: 1px solid var(--sparkfx-border);
114
- }
115
-
116
- .sparkfx-btn {
117
- background: var(--sparkfx-bg-secondary);
118
- border: 1px solid var(--sparkfx-border);
119
- color: var(--sparkfx-text);
120
- padding: 4px 12px;
121
- border-radius: 4px;
122
- cursor: pointer;
123
- font-size: 11px;
124
- font-family: inherit;
125
- transition: all 0.15s;
126
- }
127
-
128
- .sparkfx-btn:hover {
129
- background: var(--sparkfx-accent);
130
- border-color: var(--sparkfx-accent);
131
- }
132
-
133
- .sparkfx-btn.active {
134
- background: var(--sparkfx-accent);
135
- border-color: var(--sparkfx-accent);
136
- }
137
-
138
- .sparkfx-devtools-list {
139
- max-height: 300px;
140
- overflow-y: auto;
141
- padding: 8px;
142
- }
143
-
144
- .sparkfx-animation-item {
145
- display: flex;
146
- align-items: center;
147
- gap: 8px;
148
- padding: 6px 8px;
149
- margin-bottom: 4px;
150
- background: var(--sparkfx-bg-secondary);
151
- border-radius: 4px;
152
- }
153
-
154
- .sparkfx-animation-status {
155
- width: 8px;
156
- height: 8px;
157
- border-radius: 50%;
158
- }
159
-
160
- .sparkfx-animation-status.running { background: var(--sparkfx-success); }
161
- .sparkfx-animation-status.paused { background: var(--sparkfx-warning); }
162
- .sparkfx-animation-status.complete { background: var(--sparkfx-text-dim); }
163
-
164
- .sparkfx-animation-info {
165
- flex: 1;
166
- min-width: 0;
167
- }
168
-
169
- .sparkfx-animation-effect {
170
- font-weight: 500;
171
- white-space: nowrap;
172
- overflow: hidden;
173
- text-overflow: ellipsis;
174
- }
175
-
176
- .sparkfx-animation-element {
177
- font-size: 10px;
178
- color: var(--sparkfx-text-dim);
179
- white-space: nowrap;
180
- overflow: hidden;
181
- text-overflow: ellipsis;
182
- }
183
-
184
- .sparkfx-animation-progress {
185
- width: 60px;
186
- }
187
-
188
- .sparkfx-progress-bar {
189
- height: 4px;
190
- background: var(--sparkfx-border);
191
- border-radius: 2px;
192
- overflow: hidden;
193
- }
194
-
195
- .sparkfx-progress-fill {
196
- height: 100%;
197
- background: var(--sparkfx-accent);
198
- border-radius: 2px;
199
- transition: width 0.1s;
200
- }
201
-
202
- .sparkfx-progress-text {
203
- font-size: 10px;
204
- text-align: right;
205
- color: var(--sparkfx-text-dim);
206
- }
207
-
208
- .sparkfx-devtools-empty {
209
- padding: 24px;
210
- text-align: center;
211
- color: var(--sparkfx-text-dim);
212
- }
213
-
214
- .sparkfx-devtools-footer {
215
- padding: 6px 12px;
216
- font-size: 10px;
217
- color: var(--sparkfx-text-dim);
218
- border-top: 1px solid var(--sparkfx-border);
219
- display: flex;
220
- justify-content: space-between;
221
- }
222
-
223
- .sparkfx-warning-item {
224
- display: flex;
225
- align-items: center;
226
- gap: 6px;
227
- padding: 6px 12px;
228
- background: rgba(251, 191, 36, 0.1);
229
- border-bottom: 1px solid var(--sparkfx-border);
230
- font-size: 11px;
231
- color: var(--sparkfx-warning);
232
- }
233
- `,l=class{#r={shortcut:"Ctrl+Shift+S",position:"top-right",theme:"dark",showFps:true,showMemory:false,maxAnimations:20,updateInterval:100};#t=null;#s=null;#e=false;#n=false;#p=1;#a=new Map;#f=[];#o=[];#c=0;#d=null;#x=[];#i=[];constructor(){this.enable=this.enable.bind(this),this.disable=this.disable.bind(this),this.toggle=this.toggle.bind(this);}enable(){this.#e||typeof document>"u"||(this.#e=true,this.#k(),this.#w(),this.#L(),this.#M(),this.#C());}disable(){this.#e&&(this.#e=false,this.#y(),this.#b(),this.#$(),this.#S(),this.#I());}toggle(){this.#e?this.disable():this.enable();}pause(){this.#n=true,b.pause(),this.#l();}resume(){this.#n=false,b.resume(),this.#l();}slowMo(t){this.#p=Math.max(.1,Math.min(2,t)),this.#l();}exportLog(){let t={timestamp:new Date().toISOString(),version:"1.2.1",animations:Array.from(this.#a.values()),events:this.#f.slice(-100),warnings:this.#i,metrics:this.#h()},s=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),e=URL.createObjectURL(s),i=document.createElement("a");i.href=e,i.download=`sparkfx-log-${Date.now()}.json`,i.click(),URL.revokeObjectURL(e);}configure(t){this.#r={...this.#r,...t},this.#e&&this.#l();}get enabled(){return this.#e}#k(){this.#s||(this.#s=document.createElement("style"),this.#s.id="sparkfx-devtools-styles",this.#s.textContent=c,document.head.appendChild(this.#s));}#b(){this.#s&&(this.#s.remove(),this.#s=null);}#w(){if(this.#t)return;let t=document.createElement("div");t.className=`sparkfx-devtools ${this.#r.position} ${this.#r.theme}`,t.innerHTML=this.#m(),document.body.appendChild(t),this.#t=t,this.#v(),this.#E();}#y(){this.#t&&(this.#t.remove(),this.#t=null);}#m(){let t=this.#h(),s=Array.from(this.#a.values()).slice(0,this.#r.maxAnimations);return `
234
- <div class="sparkfx-devtools-header">
235
- <div class="sparkfx-devtools-title">SparkFX Devtools</div>
236
- <button class="sparkfx-devtools-close" data-action="close">\xD7</button>
237
- </div>
238
-
239
- <div class="sparkfx-devtools-metrics">
240
- <div class="sparkfx-metric">
241
- <div class="sparkfx-metric-value ${this.#T(t.fps)}">${t.fps}</div>
242
- <div class="sparkfx-metric-label">FPS</div>
243
- </div>
244
- <div class="sparkfx-metric">
245
- <div class="sparkfx-metric-value">${t.animationCount}</div>
246
- <div class="sparkfx-metric-label">Active</div>
247
- </div>
248
- <div class="sparkfx-metric">
249
- <div class="sparkfx-metric-value ${t.cpuEstimate>50?"warning":""}">${t.cpuEstimate}%</div>
250
- <div class="sparkfx-metric-label">CPU Est.</div>
251
- </div>
252
- </div>
253
-
254
- ${this.#i.length>0?`
255
- <div class="sparkfx-warning-item">
256
- \u26A0\uFE0F ${this.#i[this.#i.length-1]}
257
- </div>
258
- `:""}
259
-
260
- <div class="sparkfx-devtools-controls">
261
- <button class="sparkfx-btn ${this.#n?"":"active"}" data-action="pause">
262
- ${this.#n?"\u25B6 Resume":"\u23F8 Pause"}
263
- </button>
264
- <button class="sparkfx-btn ${this.#p<1?"active":""}" data-action="slowmo">
265
- \u{1F422} ${this.#p}x
266
- </button>
267
- <button class="sparkfx-btn" data-action="export">
268
- \u{1F4CB} Export
269
- </button>
270
- </div>
271
-
272
- <div class="sparkfx-devtools-list">
273
- ${s.length===0?`
274
- <div class="sparkfx-devtools-empty">
275
- No active animations
276
- </div>
277
- `:s.map(e=>`
278
- <div class="sparkfx-animation-item" data-id="${e.id}">
279
- <div class="sparkfx-animation-status ${e.status}"></div>
280
- <div class="sparkfx-animation-info">
281
- <div class="sparkfx-animation-effect">${e.effect}</div>
282
- <div class="sparkfx-animation-element">${e.element}</div>
283
- </div>
284
- <div class="sparkfx-animation-progress">
285
- <div class="sparkfx-progress-bar">
286
- <div class="sparkfx-progress-fill" style="width: ${e.progress*100}%"></div>
287
- </div>
288
- <div class="sparkfx-progress-text">${(e.progress*100).toFixed(0)}%</div>
289
- </div>
290
- </div>
291
- `).join("")}
292
- </div>
293
-
294
- <div class="sparkfx-devtools-footer">
295
- <span>v1.2.1</span>
296
- <span>${this.#r.shortcut} to toggle</span>
297
- </div>
298
- `}#v(){this.#t&&this.#t.addEventListener("click",t=>{switch(t.target.dataset.action){case "close":this.disable();break;case "pause":this.#n?this.resume():this.pause();break;case "slowmo":let i=[1,.5,.25,2],o=(i.indexOf(this.#p)+1)%i.length;this.slowMo(i[o]??1);break;case "export":this.exportLog();break}});}#E(){if(!this.#t)return;let t=this.#t.querySelector(".sparkfx-devtools-header");if(!t)return;let s=false,e=0,i=0,r=0,o=0;t.addEventListener("mousedown",a=>{if(a.target.classList.contains("sparkfx-devtools-close"))return;s=true,e=a.clientX,i=a.clientY;let n=this.#t.getBoundingClientRect();r=n.left,o=n.top,this.#t.classList.remove("top-right","top-left","bottom-right","bottom-left"),this.#t.style.left=`${r}px`,this.#t.style.top=`${o}px`,this.#t.style.right="auto",this.#t.style.bottom="auto";}),document.addEventListener("mousemove",a=>{if(!s)return;let n=a.clientX-e,f=a.clientY-i;this.#t.style.left=`${r+n}px`,this.#t.style.top=`${o+f}px`;}),document.addEventListener("mouseup",()=>{s=false;});}#L(){document.addEventListener("keydown",this.#u);}#$(){document.removeEventListener("keydown",this.#u);}#u=t=>{t.ctrlKey&&t.shiftKey&&t.key.toLowerCase()==="s"&&(t.preventDefault(),this.toggle());};#M(){let t=b.on("*",s=>{if(this.#f.push(s),this.#f.length>1e3&&this.#f.shift(),s.animationId){let e=this.#a.get(s.animationId);e?(s.progress!==void 0&&(e.progress=s.progress),s.progress===1&&(e.status="complete",setTimeout(()=>{this.#a.delete(s.animationId);},1e3))):this.#a.set(s.animationId,{id:s.animationId,element:this.#F(s.element),effect:s.effect??"unknown",progress:s.progress??0,status:"running",startTime:s.timestamp,duration:300});}this.#P();});this.#x.push(t);}#S(){for(let t of this.#x)t();this.#x=[];}#C(){if(this.#d)return;let t=()=>{let s=performance.now();if(this.#c){let e=Math.round(1e3/(s-this.#c));this.#o.push(e),this.#o.length>60&&this.#o.shift();}this.#c=s,this.#e&&requestAnimationFrame(t);};requestAnimationFrame(t),this.#d=window.setInterval(()=>{this.#l();},this.#r.updateInterval);}#I(){this.#d&&(clearInterval(this.#d),this.#d=null);}#l(){this.#t&&(this.#t.innerHTML=this.#m(),this.#v());}#h(){let t=this.#o.length>0?Math.round(this.#o.reduce((i,r)=>i+r,0)/this.#o.length):60,s=Array.from(this.#a.values()).filter(i=>i.status==="running").length,e=Math.min(100,s*5);return {fps:t,animationCount:s,cpuEstimate:e}}#T(t){return t>=55?"good":t>=30?"warning":"bad"}#F(t){if(!t)return "unknown";let s=t.tagName.toLowerCase(),e=t.id?`#${t.id}`:"",i=t.className&&typeof t.className=="string"?`.${t.className.split(" ").filter(Boolean).slice(0,2).join(".")}`:"";return `${s}${e}${i}`||s}#P(){let t=this.#h();t.fps<30&&this.#g("Low FPS detected! Consider reducing animation complexity."),t.animationCount>10&&this.#g("Many concurrent animations. This may impact performance.");}#g(t){this.#i.includes(t)||(this.#i.push(t),this.#i.length>5&&this.#i.shift());}},x=new l;typeof window<"u"&&new URLSearchParams(window.location.search).has("sparkfx-debug")&&setTimeout(()=>x.enable(),100);export{l as a,x as b};//# sourceMappingURL=chunk-RMXXT53J.js.map
299
- //# sourceMappingURL=chunk-RMXXT53J.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/devtools/index.ts"],"names":["DEVTOOLS_STYLES","SparkDevtools","#config","#panelElement","#styleElement","#isEnabled","#isPaused","#slowMoFactor","#animations","#eventHistory","#fpsHistory","#lastFrameTime","#updateIntervalId","#unsubscribers","#warnings","#injectStyles","#createPanel","#attachKeyboardShortcut","#subscribeToEvents","#startUpdateLoop","#removePanel","#removeStyles","#detachKeyboardShortcut","#unsubscribeFromEvents","#stopUpdateLoop","eventBus","#updateUI","factor","log","#getMetrics","blob","url","a","config","panel","#getPanelHTML","#attachPanelEvents","#makeDraggable","metrics","animations","#getFpsClass","anim","e","values","nextIndex","header","isDragging","startX","startY","startLeft","startTop","rect","dx","dy","#handleKeydown","unsub","payload","existing","#getElementDescription","#checkPerformance","measureFps","now","fps","avgFps","b","animationCount","cpuEstimate","element","tag","id","classes","#addWarning","message","devtools"],"mappings":"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","file":"chunk-RMXXT53J.js","sourcesContent":["/**\r\n * SparkFX Devtools - Browser Debugging Panel\r\n * \r\n * A floating panel that shows all active animations, performance metrics,\r\n * and provides controls for debugging animations.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { devtools } from 'sparkfx'\r\n * \r\n * // Enable devtools (also works with Ctrl+Shift+S)\r\n * devtools.enable()\r\n * \r\n * // Programmatic controls\r\n * devtools.pause() // Pause all animations\r\n * devtools.resume() // Resume animations\r\n * devtools.slowMo(0.5) // Half speed\r\n * devtools.exportLog() // Export animation log\r\n * ```\r\n * \r\n * @version 1.2.1\r\n */\r\n\r\nimport { eventBus, type SparkEventPayload } from '../core/event-bus'\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/** Animation info for display */\r\ninterface AnimationInfo {\r\n id: string\r\n element: string\r\n effect: string\r\n progress: number\r\n status: 'running' | 'paused' | 'complete'\r\n startTime: number\r\n duration: number\r\n}\r\n\r\n/** Performance metrics */\r\ninterface PerformanceMetrics {\r\n fps: number\r\n animationCount: number\r\n cpuEstimate: number\r\n memoryUsage?: number\r\n}\r\n\r\n/** Devtools configuration */\r\ninterface DevtoolsConfig {\r\n /** Keyboard shortcut to toggle panel */\r\n shortcut: string\r\n /** Panel position */\r\n position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\r\n /** Panel theme */\r\n theme: 'dark' | 'light' | 'auto'\r\n /** Show FPS counter */\r\n showFps: boolean\r\n /** Show memory usage */\r\n showMemory: boolean\r\n /** Max animations to display */\r\n maxAnimations: number\r\n /** Update interval in ms */\r\n updateInterval: number\r\n}\r\n\r\n// ============================================================================\r\n// STYLES\r\n// ============================================================================\r\n\r\nconst DEVTOOLS_STYLES = `\r\n/* SparkFX Devtools Panel */\r\n.sparkfx-devtools {\r\n --sparkfx-bg: #1a1a2e;\r\n --sparkfx-bg-secondary: #16213e;\r\n --sparkfx-text: #eee;\r\n --sparkfx-text-dim: #888;\r\n --sparkfx-accent: #e94560;\r\n --sparkfx-success: #4ade80;\r\n --sparkfx-warning: #fbbf24;\r\n --sparkfx-border: #333;\r\n \r\n position: fixed;\r\n z-index: 999999;\r\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\r\n font-size: 12px;\r\n line-height: 1.4;\r\n color: var(--sparkfx-text);\r\n background: var(--sparkfx-bg);\r\n border: 1px solid var(--sparkfx-border);\r\n border-radius: 8px;\r\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\r\n min-width: 320px;\r\n max-width: 400px;\r\n max-height: 80vh;\r\n overflow: hidden;\r\n user-select: none;\r\n backdrop-filter: blur(8px);\r\n}\r\n\r\n.sparkfx-devtools.top-right { top: 16px; right: 16px; }\r\n.sparkfx-devtools.top-left { top: 16px; left: 16px; }\r\n.sparkfx-devtools.bottom-right { bottom: 16px; right: 16px; }\r\n.sparkfx-devtools.bottom-left { bottom: 16px; left: 16px; }\r\n\r\n.sparkfx-devtools.light {\r\n --sparkfx-bg: #ffffff;\r\n --sparkfx-bg-secondary: #f5f5f5;\r\n --sparkfx-text: #1a1a1a;\r\n --sparkfx-text-dim: #666;\r\n --sparkfx-border: #ddd;\r\n}\r\n\r\n.sparkfx-devtools-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--sparkfx-bg-secondary);\r\n border-bottom: 1px solid var(--sparkfx-border);\r\n cursor: move;\r\n}\r\n\r\n.sparkfx-devtools-title {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n font-weight: 600;\r\n}\r\n\r\n.sparkfx-devtools-title::before {\r\n content: '⚡';\r\n}\r\n\r\n.sparkfx-devtools-close {\r\n background: none;\r\n border: none;\r\n color: var(--sparkfx-text-dim);\r\n cursor: pointer;\r\n padding: 4px;\r\n font-size: 16px;\r\n line-height: 1;\r\n}\r\n\r\n.sparkfx-devtools-close:hover {\r\n color: var(--sparkfx-accent);\r\n}\r\n\r\n.sparkfx-devtools-metrics {\r\n display: flex;\r\n gap: 16px;\r\n padding: 8px 12px;\r\n background: var(--sparkfx-bg-secondary);\r\n border-bottom: 1px solid var(--sparkfx-border);\r\n}\r\n\r\n.sparkfx-metric {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n}\r\n\r\n.sparkfx-metric-value {\r\n font-size: 18px;\r\n font-weight: bold;\r\n}\r\n\r\n.sparkfx-metric-value.good { color: var(--sparkfx-success); }\r\n.sparkfx-metric-value.warning { color: var(--sparkfx-warning); }\r\n.sparkfx-metric-value.bad { color: var(--sparkfx-accent); }\r\n\r\n.sparkfx-metric-label {\r\n font-size: 10px;\r\n color: var(--sparkfx-text-dim);\r\n text-transform: uppercase;\r\n}\r\n\r\n.sparkfx-devtools-controls {\r\n display: flex;\r\n gap: 8px;\r\n padding: 8px 12px;\r\n border-bottom: 1px solid var(--sparkfx-border);\r\n}\r\n\r\n.sparkfx-btn {\r\n background: var(--sparkfx-bg-secondary);\r\n border: 1px solid var(--sparkfx-border);\r\n color: var(--sparkfx-text);\r\n padding: 4px 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-size: 11px;\r\n font-family: inherit;\r\n transition: all 0.15s;\r\n}\r\n\r\n.sparkfx-btn:hover {\r\n background: var(--sparkfx-accent);\r\n border-color: var(--sparkfx-accent);\r\n}\r\n\r\n.sparkfx-btn.active {\r\n background: var(--sparkfx-accent);\r\n border-color: var(--sparkfx-accent);\r\n}\r\n\r\n.sparkfx-devtools-list {\r\n max-height: 300px;\r\n overflow-y: auto;\r\n padding: 8px;\r\n}\r\n\r\n.sparkfx-animation-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 6px 8px;\r\n margin-bottom: 4px;\r\n background: var(--sparkfx-bg-secondary);\r\n border-radius: 4px;\r\n}\r\n\r\n.sparkfx-animation-status {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n}\r\n\r\n.sparkfx-animation-status.running { background: var(--sparkfx-success); }\r\n.sparkfx-animation-status.paused { background: var(--sparkfx-warning); }\r\n.sparkfx-animation-status.complete { background: var(--sparkfx-text-dim); }\r\n\r\n.sparkfx-animation-info {\r\n flex: 1;\r\n min-width: 0;\r\n}\r\n\r\n.sparkfx-animation-effect {\r\n font-weight: 500;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.sparkfx-animation-element {\r\n font-size: 10px;\r\n color: var(--sparkfx-text-dim);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.sparkfx-animation-progress {\r\n width: 60px;\r\n}\r\n\r\n.sparkfx-progress-bar {\r\n height: 4px;\r\n background: var(--sparkfx-border);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.sparkfx-progress-fill {\r\n height: 100%;\r\n background: var(--sparkfx-accent);\r\n border-radius: 2px;\r\n transition: width 0.1s;\r\n}\r\n\r\n.sparkfx-progress-text {\r\n font-size: 10px;\r\n text-align: right;\r\n color: var(--sparkfx-text-dim);\r\n}\r\n\r\n.sparkfx-devtools-empty {\r\n padding: 24px;\r\n text-align: center;\r\n color: var(--sparkfx-text-dim);\r\n}\r\n\r\n.sparkfx-devtools-footer {\r\n padding: 6px 12px;\r\n font-size: 10px;\r\n color: var(--sparkfx-text-dim);\r\n border-top: 1px solid var(--sparkfx-border);\r\n display: flex;\r\n justify-content: space-between;\r\n}\r\n\r\n.sparkfx-warning-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 6px 12px;\r\n background: rgba(251, 191, 36, 0.1);\r\n border-bottom: 1px solid var(--sparkfx-border);\r\n font-size: 11px;\r\n color: var(--sparkfx-warning);\r\n}\r\n`\r\n\r\n// ============================================================================\r\n// DEVTOOLS CLASS\r\n// ============================================================================\r\n\r\nclass SparkDevtools {\r\n #config: DevtoolsConfig = {\r\n shortcut: 'Ctrl+Shift+S',\r\n position: 'top-right',\r\n theme: 'dark',\r\n showFps: true,\r\n showMemory: false,\r\n maxAnimations: 20,\r\n updateInterval: 100\r\n }\r\n\r\n #panelElement: HTMLElement | null = null\r\n #styleElement: HTMLStyleElement | null = null\r\n #isEnabled = false\r\n #isPaused = false\r\n #slowMoFactor = 1\r\n #animations = new Map<string, AnimationInfo>()\r\n #eventHistory: SparkEventPayload[] = []\r\n #fpsHistory: number[] = []\r\n #lastFrameTime = 0\r\n #updateIntervalId: number | null = null\r\n #unsubscribers: (() => void)[] = []\r\n #warnings: string[] = []\r\n\r\n constructor() {\r\n // Bind methods\r\n this.enable = this.enable.bind(this)\r\n this.disable = this.disable.bind(this)\r\n this.toggle = this.toggle.bind(this)\r\n }\r\n\r\n // ============================================================================\r\n // PUBLIC API\r\n // ============================================================================\r\n\r\n /** Enable devtools */\r\n enable(): void {\r\n if (this.#isEnabled || typeof document === 'undefined') return\r\n\r\n this.#isEnabled = true\r\n this.#injectStyles()\r\n this.#createPanel()\r\n this.#attachKeyboardShortcut()\r\n this.#subscribeToEvents()\r\n this.#startUpdateLoop()\r\n }\r\n\r\n /** Disable devtools */\r\n disable(): void {\r\n if (!this.#isEnabled) return\r\n\r\n this.#isEnabled = false\r\n this.#removePanel()\r\n this.#removeStyles()\r\n this.#detachKeyboardShortcut()\r\n this.#unsubscribeFromEvents()\r\n this.#stopUpdateLoop()\r\n }\r\n\r\n /** Toggle devtools visibility */\r\n toggle(): void {\r\n if (this.#isEnabled) {\r\n this.disable()\r\n } else {\r\n this.enable()\r\n }\r\n }\r\n\r\n /** Pause all animations */\r\n pause(): void {\r\n this.#isPaused = true\r\n eventBus.pause()\r\n this.#updateUI()\r\n }\r\n\r\n /** Resume all animations */\r\n resume(): void {\r\n this.#isPaused = false\r\n eventBus.resume()\r\n this.#updateUI()\r\n }\r\n\r\n /** Set slow motion factor */\r\n slowMo(factor: number): void {\r\n this.#slowMoFactor = Math.max(0.1, Math.min(2, factor))\r\n // Note: Actual slow-mo would require modifying animation durations\r\n // This is a simplified implementation\r\n this.#updateUI()\r\n }\r\n\r\n /** Export animation log */\r\n exportLog(): void {\r\n const log = {\r\n timestamp: new Date().toISOString(),\r\n version: '1.2.1',\r\n animations: Array.from(this.#animations.values()),\r\n events: this.#eventHistory.slice(-100),\r\n warnings: this.#warnings,\r\n metrics: this.#getMetrics()\r\n }\r\n\r\n const blob = new Blob([JSON.stringify(log, null, 2)], { type: 'application/json' })\r\n const url = URL.createObjectURL(blob)\r\n const a = document.createElement('a')\r\n a.href = url\r\n a.download = `sparkfx-log-${Date.now()}.json`\r\n a.click()\r\n URL.revokeObjectURL(url)\r\n }\r\n\r\n /** Configure devtools */\r\n configure(config: Partial<DevtoolsConfig>): void {\r\n this.#config = { ...this.#config, ...config }\r\n if (this.#isEnabled) {\r\n this.#updateUI()\r\n }\r\n }\r\n\r\n /** Check if devtools is enabled */\r\n get enabled(): boolean {\r\n return this.#isEnabled\r\n }\r\n\r\n // ============================================================================\r\n // PRIVATE METHODS\r\n // ============================================================================\r\n\r\n #injectStyles(): void {\r\n if (this.#styleElement) return\r\n\r\n this.#styleElement = document.createElement('style')\r\n this.#styleElement.id = 'sparkfx-devtools-styles'\r\n this.#styleElement.textContent = DEVTOOLS_STYLES\r\n document.head.appendChild(this.#styleElement)\r\n }\r\n\r\n #removeStyles(): void {\r\n if (this.#styleElement) {\r\n this.#styleElement.remove()\r\n this.#styleElement = null\r\n }\r\n }\r\n\r\n #createPanel(): void {\r\n if (this.#panelElement) return\r\n\r\n const panel = document.createElement('div')\r\n panel.className = `sparkfx-devtools ${this.#config.position} ${this.#config.theme}`\r\n panel.innerHTML = this.#getPanelHTML()\r\n\r\n document.body.appendChild(panel)\r\n this.#panelElement = panel\r\n\r\n // Attach panel event listeners\r\n this.#attachPanelEvents()\r\n\r\n // Make draggable\r\n this.#makeDraggable()\r\n }\r\n\r\n #removePanel(): void {\r\n if (this.#panelElement) {\r\n this.#panelElement.remove()\r\n this.#panelElement = null\r\n }\r\n }\r\n\r\n #getPanelHTML(): string {\r\n const metrics = this.#getMetrics()\r\n const animations = Array.from(this.#animations.values())\r\n .slice(0, this.#config.maxAnimations)\r\n\r\n return `\r\n <div class=\"sparkfx-devtools-header\">\r\n <div class=\"sparkfx-devtools-title\">SparkFX Devtools</div>\r\n <button class=\"sparkfx-devtools-close\" data-action=\"close\">×</button>\r\n </div>\r\n \r\n <div class=\"sparkfx-devtools-metrics\">\r\n <div class=\"sparkfx-metric\">\r\n <div class=\"sparkfx-metric-value ${this.#getFpsClass(metrics.fps)}\">${metrics.fps}</div>\r\n <div class=\"sparkfx-metric-label\">FPS</div>\r\n </div>\r\n <div class=\"sparkfx-metric\">\r\n <div class=\"sparkfx-metric-value\">${metrics.animationCount}</div>\r\n <div class=\"sparkfx-metric-label\">Active</div>\r\n </div>\r\n <div class=\"sparkfx-metric\">\r\n <div class=\"sparkfx-metric-value ${metrics.cpuEstimate > 50 ? 'warning' : ''}\">${metrics.cpuEstimate}%</div>\r\n <div class=\"sparkfx-metric-label\">CPU Est.</div>\r\n </div>\r\n </div>\r\n \r\n ${this.#warnings.length > 0 ? `\r\n <div class=\"sparkfx-warning-item\">\r\n ⚠️ ${this.#warnings[this.#warnings.length - 1]}\r\n </div>\r\n ` : ''}\r\n \r\n <div class=\"sparkfx-devtools-controls\">\r\n <button class=\"sparkfx-btn ${this.#isPaused ? '' : 'active'}\" data-action=\"pause\">\r\n ${this.#isPaused ? '▶ Resume' : '⏸ Pause'}\r\n </button>\r\n <button class=\"sparkfx-btn ${this.#slowMoFactor < 1 ? 'active' : ''}\" data-action=\"slowmo\">\r\n 🐢 ${this.#slowMoFactor}x\r\n </button>\r\n <button class=\"sparkfx-btn\" data-action=\"export\">\r\n 📋 Export\r\n </button>\r\n </div>\r\n \r\n <div class=\"sparkfx-devtools-list\">\r\n ${animations.length === 0 ? `\r\n <div class=\"sparkfx-devtools-empty\">\r\n No active animations\r\n </div>\r\n ` : animations.map(anim => `\r\n <div class=\"sparkfx-animation-item\" data-id=\"${anim.id}\">\r\n <div class=\"sparkfx-animation-status ${anim.status}\"></div>\r\n <div class=\"sparkfx-animation-info\">\r\n <div class=\"sparkfx-animation-effect\">${anim.effect}</div>\r\n <div class=\"sparkfx-animation-element\">${anim.element}</div>\r\n </div>\r\n <div class=\"sparkfx-animation-progress\">\r\n <div class=\"sparkfx-progress-bar\">\r\n <div class=\"sparkfx-progress-fill\" style=\"width: ${anim.progress * 100}%\"></div>\r\n </div>\r\n <div class=\"sparkfx-progress-text\">${(anim.progress * 100).toFixed(0)}%</div>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n \r\n <div class=\"sparkfx-devtools-footer\">\r\n <span>v1.2.1</span>\r\n <span>${this.#config.shortcut} to toggle</span>\r\n </div>\r\n `\r\n }\r\n\r\n #attachPanelEvents(): void {\r\n if (!this.#panelElement) return\r\n\r\n this.#panelElement.addEventListener('click', (e) => {\r\n const target = e.target as HTMLElement\r\n const action = target.dataset.action\r\n\r\n switch (action) {\r\n case 'close':\r\n this.disable()\r\n break\r\n case 'pause':\r\n if (this.#isPaused) {\r\n this.resume()\r\n } else {\r\n this.pause()\r\n }\r\n break\r\n case 'slowmo':\r\n // Cycle through slow-mo values\r\n const values = [1, 0.5, 0.25, 2]\r\n const currentIndex = values.indexOf(this.#slowMoFactor)\r\n const nextIndex = (currentIndex + 1) % values.length\r\n this.slowMo(values[nextIndex] ?? 1)\r\n break\r\n case 'export':\r\n this.exportLog()\r\n break\r\n }\r\n })\r\n }\r\n\r\n #makeDraggable(): void {\r\n if (!this.#panelElement) return\r\n\r\n const header = this.#panelElement.querySelector('.sparkfx-devtools-header') as HTMLElement\r\n if (!header) return\r\n\r\n let isDragging = false\r\n let startX = 0\r\n let startY = 0\r\n let startLeft = 0\r\n let startTop = 0\r\n\r\n header.addEventListener('mousedown', (e) => {\r\n if ((e.target as HTMLElement).classList.contains('sparkfx-devtools-close')) return\r\n\r\n isDragging = true\r\n startX = e.clientX\r\n startY = e.clientY\r\n\r\n const rect = this.#panelElement!.getBoundingClientRect()\r\n startLeft = rect.left\r\n startTop = rect.top\r\n\r\n // Remove position classes and use absolute positioning\r\n this.#panelElement!.classList.remove('top-right', 'top-left', 'bottom-right', 'bottom-left')\r\n this.#panelElement!.style.left = `${startLeft}px`\r\n this.#panelElement!.style.top = `${startTop}px`\r\n this.#panelElement!.style.right = 'auto'\r\n this.#panelElement!.style.bottom = 'auto'\r\n })\r\n\r\n document.addEventListener('mousemove', (e) => {\r\n if (!isDragging) return\r\n\r\n const dx = e.clientX - startX\r\n const dy = e.clientY - startY\r\n\r\n this.#panelElement!.style.left = `${startLeft + dx}px`\r\n this.#panelElement!.style.top = `${startTop + dy}px`\r\n })\r\n\r\n document.addEventListener('mouseup', () => {\r\n isDragging = false\r\n })\r\n }\r\n\r\n #attachKeyboardShortcut(): void {\r\n document.addEventListener('keydown', this.#handleKeydown)\r\n }\r\n\r\n #detachKeyboardShortcut(): void {\r\n document.removeEventListener('keydown', this.#handleKeydown)\r\n }\r\n\r\n #handleKeydown = (e: KeyboardEvent): void => {\r\n // Ctrl+Shift+S\r\n if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 's') {\r\n e.preventDefault()\r\n this.toggle()\r\n }\r\n }\r\n\r\n #subscribeToEvents(): void {\r\n // Subscribe to all animation events\r\n const unsub = eventBus.on('*', (payload) => {\r\n this.#eventHistory.push(payload)\r\n if (this.#eventHistory.length > 1000) {\r\n this.#eventHistory.shift()\r\n }\r\n\r\n // Update animation tracking\r\n if (payload.animationId) {\r\n const existing = this.#animations.get(payload.animationId)\r\n\r\n if (!existing) {\r\n this.#animations.set(payload.animationId, {\r\n id: payload.animationId,\r\n element: this.#getElementDescription(payload.element),\r\n effect: payload.effect ?? 'unknown',\r\n progress: payload.progress ?? 0,\r\n status: 'running',\r\n startTime: payload.timestamp,\r\n duration: 300\r\n })\r\n } else {\r\n if (payload.progress !== undefined) {\r\n existing.progress = payload.progress\r\n }\r\n\r\n // Check for completion\r\n if (payload.progress === 1) {\r\n existing.status = 'complete'\r\n // Remove after a short delay\r\n setTimeout(() => {\r\n this.#animations.delete(payload.animationId!)\r\n }, 1000)\r\n }\r\n }\r\n }\r\n\r\n // Check for performance warnings\r\n this.#checkPerformance()\r\n })\r\n\r\n this.#unsubscribers.push(unsub)\r\n }\r\n\r\n #unsubscribeFromEvents(): void {\r\n for (const unsub of this.#unsubscribers) {\r\n unsub()\r\n }\r\n this.#unsubscribers = []\r\n }\r\n\r\n #startUpdateLoop(): void {\r\n if (this.#updateIntervalId) return\r\n\r\n // FPS counter using requestAnimationFrame\r\n const measureFps = () => {\r\n const now = performance.now()\r\n if (this.#lastFrameTime) {\r\n const fps = Math.round(1000 / (now - this.#lastFrameTime))\r\n this.#fpsHistory.push(fps)\r\n if (this.#fpsHistory.length > 60) {\r\n this.#fpsHistory.shift()\r\n }\r\n }\r\n this.#lastFrameTime = now\r\n\r\n if (this.#isEnabled) {\r\n requestAnimationFrame(measureFps)\r\n }\r\n }\r\n requestAnimationFrame(measureFps)\r\n\r\n // UI update loop\r\n this.#updateIntervalId = window.setInterval(() => {\r\n this.#updateUI()\r\n }, this.#config.updateInterval)\r\n }\r\n\r\n #stopUpdateLoop(): void {\r\n if (this.#updateIntervalId) {\r\n clearInterval(this.#updateIntervalId)\r\n this.#updateIntervalId = null\r\n }\r\n }\r\n\r\n #updateUI(): void {\r\n if (!this.#panelElement) return\r\n this.#panelElement.innerHTML = this.#getPanelHTML()\r\n this.#attachPanelEvents()\r\n }\r\n\r\n #getMetrics(): PerformanceMetrics {\r\n const avgFps = this.#fpsHistory.length > 0\r\n ? Math.round(this.#fpsHistory.reduce((a, b) => a + b, 0) / this.#fpsHistory.length)\r\n : 60\r\n\r\n const animationCount = Array.from(this.#animations.values())\r\n .filter(a => a.status === 'running').length\r\n\r\n // Rough CPU estimate based on animation count\r\n const cpuEstimate = Math.min(100, animationCount * 5)\r\n\r\n return {\r\n fps: avgFps,\r\n animationCount,\r\n cpuEstimate\r\n }\r\n }\r\n\r\n #getFpsClass(fps: number): string {\r\n if (fps >= 55) return 'good'\r\n if (fps >= 30) return 'warning'\r\n return 'bad'\r\n }\r\n\r\n #getElementDescription(element: Element | null | undefined): string {\r\n if (!element) return 'unknown'\r\n\r\n const tag = element.tagName.toLowerCase()\r\n const id = element.id ? `#${element.id}` : ''\r\n const classes = element.className && typeof element.className === 'string'\r\n ? `.${element.className.split(' ').filter(Boolean).slice(0, 2).join('.')}`\r\n : ''\r\n\r\n return `${tag}${id}${classes}` || tag\r\n }\r\n\r\n #checkPerformance(): void {\r\n const metrics = this.#getMetrics()\r\n\r\n if (metrics.fps < 30) {\r\n this.#addWarning('Low FPS detected! Consider reducing animation complexity.')\r\n }\r\n\r\n if (metrics.animationCount > 10) {\r\n this.#addWarning('Many concurrent animations. This may impact performance.')\r\n }\r\n }\r\n\r\n #addWarning(message: string): void {\r\n // Avoid duplicate warnings\r\n if (!this.#warnings.includes(message)) {\r\n this.#warnings.push(message)\r\n if (this.#warnings.length > 5) {\r\n this.#warnings.shift()\r\n }\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// SINGLETON EXPORT\r\n// ============================================================================\r\n\r\n/** Global devtools instance */\r\nexport const devtools = new SparkDevtools()\r\n\r\n// Auto-enable in development mode if URL has ?sparkfx-debug\r\nif (typeof window !== 'undefined') {\r\n const params = new URLSearchParams(window.location.search)\r\n if (params.has('sparkfx-debug')) {\r\n // Defer to allow page to load\r\n setTimeout(() => devtools.enable(), 100)\r\n }\r\n}\r\n\r\n// Export class for advanced usage\r\nexport { SparkDevtools }\r\n"]}
package/dist/devtools.cjs DELETED
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkE3PKCBIJ_cjs=require('./chunk-E3PKCBIJ.cjs');require('./chunk-Y5V7MOLA.cjs');Object.defineProperty(exports,"SparkDevtools",{enumerable:true,get:function(){return chunkE3PKCBIJ_cjs.a}});Object.defineProperty(exports,"devtools",{enumerable:true,get:function(){return chunkE3PKCBIJ_cjs.b}});//# sourceMappingURL=devtools.cjs.map
2
- //# sourceMappingURL=devtools.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"devtools.cjs"}
@@ -1,65 +0,0 @@
1
- /**
2
- * SparkFX Devtools - Browser Debugging Panel
3
- *
4
- * A floating panel that shows all active animations, performance metrics,
5
- * and provides controls for debugging animations.
6
- *
7
- * @example
8
- * ```typescript
9
- * import { devtools } from 'sparkfx'
10
- *
11
- * // Enable devtools (also works with Ctrl+Shift+S)
12
- * devtools.enable()
13
- *
14
- * // Programmatic controls
15
- * devtools.pause() // Pause all animations
16
- * devtools.resume() // Resume animations
17
- * devtools.slowMo(0.5) // Half speed
18
- * devtools.exportLog() // Export animation log
19
- * ```
20
- *
21
- * @version 1.2.1
22
- */
23
- /** Devtools configuration */
24
- interface DevtoolsConfig {
25
- /** Keyboard shortcut to toggle panel */
26
- shortcut: string;
27
- /** Panel position */
28
- position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
29
- /** Panel theme */
30
- theme: 'dark' | 'light' | 'auto';
31
- /** Show FPS counter */
32
- showFps: boolean;
33
- /** Show memory usage */
34
- showMemory: boolean;
35
- /** Max animations to display */
36
- maxAnimations: number;
37
- /** Update interval in ms */
38
- updateInterval: number;
39
- }
40
- declare class SparkDevtools {
41
- #private;
42
- constructor();
43
- /** Enable devtools */
44
- enable(): void;
45
- /** Disable devtools */
46
- disable(): void;
47
- /** Toggle devtools visibility */
48
- toggle(): void;
49
- /** Pause all animations */
50
- pause(): void;
51
- /** Resume all animations */
52
- resume(): void;
53
- /** Set slow motion factor */
54
- slowMo(factor: number): void;
55
- /** Export animation log */
56
- exportLog(): void;
57
- /** Configure devtools */
58
- configure(config: Partial<DevtoolsConfig>): void;
59
- /** Check if devtools is enabled */
60
- get enabled(): boolean;
61
- }
62
- /** Global devtools instance */
63
- declare const devtools: SparkDevtools;
64
-
65
- export { SparkDevtools, devtools };
@@ -1,65 +0,0 @@
1
- /**
2
- * SparkFX Devtools - Browser Debugging Panel
3
- *
4
- * A floating panel that shows all active animations, performance metrics,
5
- * and provides controls for debugging animations.
6
- *
7
- * @example
8
- * ```typescript
9
- * import { devtools } from 'sparkfx'
10
- *
11
- * // Enable devtools (also works with Ctrl+Shift+S)
12
- * devtools.enable()
13
- *
14
- * // Programmatic controls
15
- * devtools.pause() // Pause all animations
16
- * devtools.resume() // Resume animations
17
- * devtools.slowMo(0.5) // Half speed
18
- * devtools.exportLog() // Export animation log
19
- * ```
20
- *
21
- * @version 1.2.1
22
- */
23
- /** Devtools configuration */
24
- interface DevtoolsConfig {
25
- /** Keyboard shortcut to toggle panel */
26
- shortcut: string;
27
- /** Panel position */
28
- position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
29
- /** Panel theme */
30
- theme: 'dark' | 'light' | 'auto';
31
- /** Show FPS counter */
32
- showFps: boolean;
33
- /** Show memory usage */
34
- showMemory: boolean;
35
- /** Max animations to display */
36
- maxAnimations: number;
37
- /** Update interval in ms */
38
- updateInterval: number;
39
- }
40
- declare class SparkDevtools {
41
- #private;
42
- constructor();
43
- /** Enable devtools */
44
- enable(): void;
45
- /** Disable devtools */
46
- disable(): void;
47
- /** Toggle devtools visibility */
48
- toggle(): void;
49
- /** Pause all animations */
50
- pause(): void;
51
- /** Resume all animations */
52
- resume(): void;
53
- /** Set slow motion factor */
54
- slowMo(factor: number): void;
55
- /** Export animation log */
56
- exportLog(): void;
57
- /** Configure devtools */
58
- configure(config: Partial<DevtoolsConfig>): void;
59
- /** Check if devtools is enabled */
60
- get enabled(): boolean;
61
- }
62
- /** Global devtools instance */
63
- declare const devtools: SparkDevtools;
64
-
65
- export { SparkDevtools, devtools };
package/dist/devtools.js DELETED
@@ -1,2 +0,0 @@
1
- export{a as SparkDevtools,b as devtools}from'./chunk-RMXXT53J.js';import'./chunk-RD5XCTW4.js';//# sourceMappingURL=devtools.js.map
2
- //# sourceMappingURL=devtools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"devtools.js"}