ai-progress-controls 0.1.0

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +823 -0
  3. package/dist/ai-progress-controls.es.js +7191 -0
  4. package/dist/ai-progress-controls.es.js.map +1 -0
  5. package/dist/ai-progress-controls.umd.js +2 -0
  6. package/dist/ai-progress-controls.umd.js.map +1 -0
  7. package/dist/index.d.ts +2212 -0
  8. package/package.json +105 -0
  9. package/src/__tests__/setup.ts +93 -0
  10. package/src/core/base/AIControl.ts +230 -0
  11. package/src/core/base/index.ts +3 -0
  12. package/src/core/base/types.ts +77 -0
  13. package/src/core/base/utils.ts +168 -0
  14. package/src/core/batch-progress/BatchProgress.test.ts +458 -0
  15. package/src/core/batch-progress/BatchProgress.ts +760 -0
  16. package/src/core/batch-progress/index.ts +14 -0
  17. package/src/core/batch-progress/styles.ts +480 -0
  18. package/src/core/batch-progress/types.ts +169 -0
  19. package/src/core/model-loader/ModelLoader.test.ts +311 -0
  20. package/src/core/model-loader/ModelLoader.ts +673 -0
  21. package/src/core/model-loader/index.ts +2 -0
  22. package/src/core/model-loader/styles.ts +496 -0
  23. package/src/core/model-loader/types.ts +127 -0
  24. package/src/core/parameter-panel/ParameterPanel.test.ts +856 -0
  25. package/src/core/parameter-panel/ParameterPanel.ts +877 -0
  26. package/src/core/parameter-panel/index.ts +14 -0
  27. package/src/core/parameter-panel/styles.ts +323 -0
  28. package/src/core/parameter-panel/types.ts +278 -0
  29. package/src/core/parameter-slider/ParameterSlider.test.ts +299 -0
  30. package/src/core/parameter-slider/ParameterSlider.ts +653 -0
  31. package/src/core/parameter-slider/index.ts +8 -0
  32. package/src/core/parameter-slider/styles.ts +493 -0
  33. package/src/core/parameter-slider/types.ts +107 -0
  34. package/src/core/queue-progress/QueueProgress.test.ts +344 -0
  35. package/src/core/queue-progress/QueueProgress.ts +563 -0
  36. package/src/core/queue-progress/index.ts +5 -0
  37. package/src/core/queue-progress/styles.ts +469 -0
  38. package/src/core/queue-progress/types.ts +130 -0
  39. package/src/core/retry-progress/RetryProgress.test.ts +397 -0
  40. package/src/core/retry-progress/RetryProgress.ts +957 -0
  41. package/src/core/retry-progress/index.ts +6 -0
  42. package/src/core/retry-progress/styles.ts +530 -0
  43. package/src/core/retry-progress/types.ts +176 -0
  44. package/src/core/stream-progress/StreamProgress.test.ts +531 -0
  45. package/src/core/stream-progress/StreamProgress.ts +517 -0
  46. package/src/core/stream-progress/index.ts +2 -0
  47. package/src/core/stream-progress/styles.ts +349 -0
  48. package/src/core/stream-progress/types.ts +82 -0
  49. package/src/index.ts +19 -0
@@ -0,0 +1,469 @@
1
+ export const styles = `
2
+ :host {
3
+ /* CSS variables inherit from document root with fallback defaults */
4
+ display: block;
5
+ font-family: var(--queue-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);
6
+ font-size: var(--queue-font-size, 14px);
7
+ color: var(--queue-text, #e4e4e7);
8
+ }
9
+
10
+ :host([style*="cursor: wait"]) .queue-container {
11
+ cursor: wait;
12
+ }
13
+
14
+ :host([style*="cursor: not-allowed"]) .queue-container {
15
+ cursor: not-allowed;
16
+ }
17
+
18
+ :host([style*="cursor: default"]) .queue-container {
19
+ cursor: default;
20
+ }
21
+
22
+ .queue-container {
23
+ background: var(--queue-background, #1a1a2e);
24
+ border: 1px solid var(--queue-border, #27273a);
25
+ border-radius: var(--queue-border-radius, 12px);
26
+ padding: var(--queue-padding, 24px);
27
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
28
+ }
29
+
30
+ .queue-header {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 12px;
34
+ margin-bottom: 20px;
35
+ }
36
+
37
+ .queue-icon {
38
+ font-size: 32px;
39
+ line-height: 1;
40
+ animation: pulse 2s ease-in-out infinite;
41
+ }
42
+
43
+ @keyframes pulse {
44
+ 0%, 100% { opacity: 1; }
45
+ 50% { opacity: 0.6; }
46
+ }
47
+
48
+ .queue-title {
49
+ flex: 1;
50
+ }
51
+
52
+ .queue-status {
53
+ font-size: 16px;
54
+ font-weight: 600;
55
+ color: var(--queue-text, #e4e4e7);
56
+ margin: 0 0 4px 0;
57
+ }
58
+
59
+ .queue-message {
60
+ font-size: 13px;
61
+ color: var(--queue-text-secondary, #a1a1aa);
62
+ margin: 0;
63
+ }
64
+
65
+ .queue-badge {
66
+ padding: 4px 12px;
67
+ border-radius: 12px;
68
+ font-size: 12px;
69
+ font-weight: 600;
70
+ text-transform: uppercase;
71
+ letter-spacing: 0.5px;
72
+ }
73
+
74
+ .queue-badge.waiting {
75
+ background: rgba(251, 191, 36, 0.1);
76
+ color: #fbbf24;
77
+ }
78
+
79
+ .queue-badge.processing {
80
+ background: rgba(102, 126, 234, 0.1);
81
+ color: #667eea;
82
+ }
83
+
84
+ .queue-badge.completed {
85
+ background: rgba(16, 185, 129, 0.1);
86
+ color: #10b981;
87
+ }
88
+
89
+ .queue-badge.error {
90
+ background: rgba(239, 68, 68, 0.1);
91
+ color: #ef4444;
92
+ }
93
+
94
+ .queue-position {
95
+ text-align: center;
96
+ margin: 24px 0;
97
+ }
98
+
99
+ .position-number {
100
+ font-size: 64px;
101
+ font-weight: 700;
102
+ color: var(--queue-primary, #667eea);
103
+ line-height: 1;
104
+ margin: 0 0 8px 0;
105
+ font-variant-numeric: tabular-nums;
106
+ transition: all var(--transition-speed) ease;
107
+ }
108
+
109
+ .position-label {
110
+ font-size: 14px;
111
+ color: var(--queue-text-secondary, #a1a1aa);
112
+ text-transform: uppercase;
113
+ letter-spacing: 1px;
114
+ font-weight: 500;
115
+ }
116
+
117
+ .queue-metrics {
118
+ display: grid;
119
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
120
+ gap: 16px;
121
+ margin: 20px 0;
122
+ }
123
+
124
+ .metric {
125
+ background: var(--queue-metric-bg, #16162a);
126
+ border: 1px solid var(--queue-border, #27273a);
127
+ border-radius: 8px;
128
+ padding: 12px 16px;
129
+ }
130
+
131
+ .metric-value {
132
+ font-size: 24px;
133
+ font-weight: 700;
134
+ color: var(--queue-text, #e4e4e7);
135
+ margin: 0 0 4px 0;
136
+ font-variant-numeric: tabular-nums;
137
+ }
138
+
139
+ .metric-label {
140
+ font-size: 12px;
141
+ color: var(--queue-text-secondary, #a1a1aa);
142
+ text-transform: uppercase;
143
+ letter-spacing: 0.5px;
144
+ margin: 0;
145
+ }
146
+
147
+ .progress-container {
148
+ margin: 20px 0;
149
+ }
150
+
151
+ .progress-bar {
152
+ width: 100%;
153
+ height: 8px;
154
+ background: var(--queue-progress-bg, #27273a);
155
+ border-radius: 4px;
156
+ overflow: hidden;
157
+ position: relative;
158
+ }
159
+
160
+ .progress-fill {
161
+ height: 100%;
162
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
163
+ border-radius: 4px;
164
+ transition: width var(--transition-speed) ease;
165
+ position: relative;
166
+ overflow: hidden;
167
+ }
168
+
169
+ .progress-fill::after {
170
+ content: '';
171
+ position: absolute;
172
+ top: 0;
173
+ left: 0;
174
+ right: 0;
175
+ bottom: 0;
176
+ background: linear-gradient(
177
+ 90deg,
178
+ transparent,
179
+ rgba(255, 255, 255, 0.3),
180
+ transparent
181
+ );
182
+ animation: shimmer 2s infinite;
183
+ }
184
+
185
+ @keyframes shimmer {
186
+ 0% { transform: translateX(-100%); }
187
+ 100% { transform: translateX(100%); }
188
+ }
189
+
190
+ /* Override default animation when animation attribute is set */
191
+ :host([animation]) .progress-fill::after {
192
+ animation: none !important;
193
+ }
194
+
195
+ .info-icon {
196
+ font-size: 18px;
197
+ }
198
+
199
+ .info-text {
200
+ font-size: 13px;
201
+ color: var(--queue-text, #e4e4e7);
202
+ margin: 0;
203
+ }
204
+
205
+ .queue-actions {
206
+ display: flex;
207
+ gap: 12px;
208
+ margin-top: 20px;
209
+ }
210
+
211
+ .queue-button {
212
+ flex: 1;
213
+ padding: 10px 16px;
214
+ background: var(--queue-button-bg, #667eea);
215
+ color: var(--queue-button-text, #ffffff);
216
+ border: none;
217
+ border-radius: 8px;
218
+ font-size: 14px;
219
+ font-weight: 600;
220
+ cursor: pointer;
221
+ transition: all var(--transition-speed) ease;
222
+ }
223
+
224
+ .queue-button:hover:not(:disabled) {
225
+ background: var(--queue-button-hover, #5568d3);
226
+ transform: translateY(-1px);
227
+ box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
228
+ }
229
+
230
+ .queue-button:disabled {
231
+ opacity: 0.5;
232
+ cursor: not-allowed;
233
+ }
234
+
235
+ .queue-button.secondary {
236
+ background: var(--queue-button-secondary, #27273a);
237
+ color: var(--queue-text, #e4e4e7);
238
+ }
239
+
240
+ .queue-button.secondary:hover:not(:disabled) {
241
+ background: var(--queue-button-secondary-hover, #333348);
242
+ }
243
+
244
+ .error-message {
245
+ display: flex;
246
+ align-items: center;
247
+ gap: 8px;
248
+ padding: 12px;
249
+ background: rgba(239, 68, 68, 0.1);
250
+ border: 1px solid #ef4444;
251
+ border-radius: 8px;
252
+ color: #ef4444;
253
+ margin-top: 16px;
254
+ }
255
+
256
+ .error-icon {
257
+ font-size: 20px;
258
+ }
259
+
260
+ .error-text {
261
+ font-size: 13px;
262
+ margin: 0;
263
+ }
264
+
265
+ /* Animation for position change */
266
+ @keyframes positionChange {
267
+ 0% { transform: scale(1); }
268
+ 50% { transform: scale(1.1); color: var(--queue-success, #10b981); }
269
+ 100% { transform: scale(1); }
270
+ }
271
+
272
+ .position-number.changing {
273
+ animation: positionChange 0.5s ease;
274
+ }
275
+
276
+ /* Visual Variants */
277
+
278
+ /* Minimal variant - clean, no shadows */
279
+ :host([variant="minimal"]) .queue-container {
280
+ box-shadow: none;
281
+ border: 1px solid var(--queue-border, #27273a);
282
+ }
283
+
284
+ :host([variant="minimal"]) .progress-bar {
285
+ background: transparent;
286
+ border: 1px solid var(--queue-border, #27273a);
287
+ }
288
+
289
+ /* Gradient variant - colorful gradients */
290
+ :host([variant="gradient"]) .progress-fill {
291
+ background: linear-gradient(
292
+ 90deg,
293
+ #667eea,
294
+ #764ba2,
295
+ #667eea
296
+ );
297
+ background-size: 200% 100%;
298
+ animation: gradient-shift 3s ease-in-out infinite;
299
+ }
300
+
301
+ @keyframes gradient-shift {
302
+ 0%, 100% { background-position: 0% 50%; }
303
+ 50% { background-position: 100% 50%; }
304
+ }
305
+
306
+ /* Override default animation when animation attribute is set */
307
+ :host([animation][variant="gradient"]) .progress-fill {
308
+ animation: none !important;
309
+ }
310
+
311
+ /* Glassmorphic variant - frosted glass effect */
312
+ :host([variant="glassmorphic"]) .queue-container {
313
+ background: rgba(26, 26, 46, 0.6);
314
+ backdrop-filter: blur(10px);
315
+ -webkit-backdrop-filter: blur(10px);
316
+ border: 1px solid rgba(255, 255, 255, 0.1);
317
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
318
+ }
319
+
320
+ :host([variant="glassmorphic"]) .progress-bar {
321
+ background: rgba(0, 0, 0, 0.2);
322
+ }
323
+
324
+ :host([variant="glassmorphic"]) .progress-fill {
325
+ background: linear-gradient(
326
+ 90deg,
327
+ rgba(102, 126, 234, 0.8),
328
+ rgba(118, 75, 162, 0.8)
329
+ );
330
+ }
331
+
332
+ /* Animation Effects */
333
+
334
+ /* Striped animation */
335
+ :host([animation="striped"]) .progress-fill {
336
+ background-image:
337
+ linear-gradient(
338
+ 45deg,
339
+ rgba(255, 255, 255, 0.2) 25%,
340
+ transparent 25%,
341
+ transparent 50%,
342
+ rgba(255, 255, 255, 0.2) 50%,
343
+ rgba(255, 255, 255, 0.2) 75%,
344
+ transparent 75%,
345
+ transparent
346
+ ),
347
+ linear-gradient(to right, #667eea, #667eea) !important;
348
+ background-size: 2rem 2rem, 100% 100% !important;
349
+ animation: progress-stripes 3s linear infinite !important;
350
+ }
351
+
352
+ @keyframes progress-stripes {
353
+ 0% { background-position: 0 0, 0 0; }
354
+ 100% { background-position: 2rem 0, 0 0; }
355
+ }
356
+
357
+ /* Pulse animation */
358
+ :host([animation="pulse"]) .progress-fill {
359
+ animation: progress-pulse 4s ease-in-out infinite !important;
360
+ }
361
+
362
+ @keyframes progress-pulse {
363
+ 0%, 100% { opacity: 1; }
364
+ 50% { opacity: 0.3; }
365
+ }
366
+
367
+ /* Glow animation */
368
+ :host([animation="glow"]) .progress-fill {
369
+ animation: progress-glow 4s ease-in-out infinite !important;
370
+ }
371
+
372
+ @keyframes progress-glow {
373
+ 0%, 100% {
374
+ box-shadow: 0 0 5px #667eea,
375
+ 0 0 10px #667eea;
376
+ }
377
+ 50% {
378
+ box-shadow: 0 0 20px #667eea,
379
+ 0 0 35px #667eea,
380
+ 0 0 50px #667eea;
381
+ }
382
+ }
383
+
384
+ /* Size variants */
385
+ :host([size="compact"]) .queue-container {
386
+ padding: 8px;
387
+ font-size: 12px;
388
+ }
389
+
390
+ :host([size="compact"]) .progress-bar {
391
+ height: 6px;
392
+ }
393
+
394
+ :host([size="compact"]) .queue-status {
395
+ font-size: 14px;
396
+ }
397
+
398
+ :host([size="compact"]) .queue-message {
399
+ font-size: 11px;
400
+ }
401
+
402
+ :host([size="compact"]) .position-number {
403
+ font-size: 48px;
404
+ }
405
+
406
+ :host([size="compact"]) .metric-value {
407
+ font-size: 22px;
408
+ }
409
+
410
+ :host([size="large"]) .queue-container {
411
+ padding: 16px;
412
+ font-size: 16px;
413
+ }
414
+
415
+ :host([size="large"]) .progress-bar {
416
+ height: 10px;
417
+ }
418
+
419
+ :host([size="large"]) .queue-status {
420
+ font-size: 18px;
421
+ }
422
+
423
+ :host([size="large"]) .queue-message {
424
+ font-size: 15px;
425
+ }
426
+
427
+ :host([size="large"]) .position-number {
428
+ font-size: 72px;
429
+ }
430
+
431
+ :host([size="large"]) .metric-value {
432
+ font-size: 32px;
433
+ }
434
+
435
+ /* Responsive design */
436
+ @media (max-width: 480px) {
437
+ .queue-container {
438
+ padding: 16px;
439
+ }
440
+
441
+ .position-number {
442
+ font-size: 48px;
443
+ }
444
+
445
+ .queue-metrics {
446
+ grid-template-columns: 1fr;
447
+ }
448
+ }
449
+
450
+ /* Dark mode adjustments (default) */
451
+ :host {
452
+ color-scheme: dark;
453
+ }
454
+
455
+ /* Accessibility */
456
+ .queue-button:focus-visible {
457
+ outline: 2px solid var(--queue-primary, #667eea);
458
+ outline-offset: 2px;
459
+ }
460
+
461
+ /* Reduced motion */
462
+ @media (prefers-reduced-motion: reduce) {
463
+ * {
464
+ animation-duration: 0.01ms !important;
465
+ animation-iteration-count: 1 !important;
466
+ transition-duration: 0.01ms !important;
467
+ }
468
+ }
469
+ `;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Queue status types
3
+ */
4
+ export type QueueStatus = 'waiting' | 'processing' | 'completed' | 'cancelled' | 'error';
5
+
6
+ /**
7
+ * Configuration for QueueProgress component
8
+ */
9
+ export interface QueueProgressConfig {
10
+ /** Initial position in queue */
11
+ position?: number;
12
+
13
+ /** Total queue size */
14
+ queueSize?: number;
15
+
16
+ /** Estimated wait time in seconds */
17
+ estimatedWait?: number;
18
+
19
+ /** Processing rate (items per second) */
20
+ processingRate?: number;
21
+
22
+ /** Show position counter */
23
+ showPosition?: boolean;
24
+
25
+ /** Show estimated wait time */
26
+ showWaitTime?: boolean;
27
+
28
+ /** Show processing rate */
29
+ showRate?: boolean;
30
+
31
+ /** Show queue size */
32
+ showQueueSize?: boolean;
33
+
34
+ /** Show visual progress bar */
35
+ showProgressBar?: boolean;
36
+
37
+ /** Custom message */
38
+ message?: string;
39
+
40
+ /** Enable animations */
41
+ animate?: boolean;
42
+
43
+ /** Update throttle in milliseconds */
44
+ updateThrottle?: number;
45
+
46
+ /** Enable automatic cursor state changes based on component state */
47
+ cursorFeedback?: boolean;
48
+
49
+ /** Component size variant */
50
+ size?: 'compact' | 'default' | 'large';
51
+
52
+ /** Visual style variant */
53
+ variant?: 'default' | 'minimal' | 'gradient' | 'glassmorphic';
54
+
55
+ /** Animation style */
56
+ animation?: 'none' | 'striped' | 'pulse' | 'glow';
57
+
58
+ /** Debug mode */
59
+ debug?: boolean;
60
+
61
+ /** Custom CSS class */
62
+ className?: string;
63
+
64
+ /** Aria label */
65
+ ariaLabel?: string;
66
+ }
67
+
68
+ /**
69
+ * QueueProgress state
70
+ */
71
+ export interface QueueProgressState {
72
+ status: QueueStatus;
73
+ position: number;
74
+ queueSize: number;
75
+ estimatedWait: number;
76
+ processingRate: number;
77
+ startTime: number;
78
+ message?: string;
79
+ elapsedTime: number;
80
+ }
81
+
82
+ /**
83
+ * Update data for queue position
84
+ */
85
+ export interface QueueUpdate {
86
+ position?: number;
87
+ queueSize?: number;
88
+ estimatedWait?: number;
89
+ processingRate?: number;
90
+ message?: string;
91
+ }
92
+
93
+ /**
94
+ * Event data for position change
95
+ */
96
+ export interface PositionChangeEvent {
97
+ previousPosition: number;
98
+ currentPosition: number;
99
+ queueSize: number;
100
+ estimatedWait: number;
101
+ timestamp: number;
102
+ }
103
+
104
+ /**
105
+ * Event data for queue start
106
+ */
107
+ export interface QueueStartEvent {
108
+ position: number;
109
+ queueSize: number;
110
+ estimatedWait: number;
111
+ timestamp: number;
112
+ }
113
+
114
+ /**
115
+ * Event data for queue complete
116
+ */
117
+ export interface QueueCompleteEvent {
118
+ totalWaitTime: number;
119
+ startPosition: number;
120
+ timestamp: number;
121
+ }
122
+
123
+ /**
124
+ * Event data for queue error
125
+ */
126
+ export interface QueueErrorEvent {
127
+ message: string;
128
+ position: number;
129
+ timestamp: number;
130
+ }