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,14 @@
1
+ export { BatchProgress } from './BatchProgress';
2
+ export type {
3
+ BatchProgressConfig,
4
+ BatchProgressState,
5
+ BatchProgressUpdate,
6
+ BatchItem,
7
+ BatchItemStatus,
8
+ BatchStartEvent,
9
+ BatchItemUpdateEvent,
10
+ BatchCompleteEvent,
11
+ BatchCancelEvent,
12
+ BatchItemCompleteEvent,
13
+ BatchItemFailedEvent,
14
+ } from './types';
@@ -0,0 +1,480 @@
1
+ export const styles = `
2
+ :host {
3
+ /* CSS variables inherit from document root with fallback defaults */
4
+ display: block;
5
+ font-family: var(--ai-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
6
+ font-size: var(--ai-font-size, 14px);
7
+ color: var(--ai-text-color, #1f2937);
8
+ }
9
+
10
+ :host([style*="cursor: progress"]) .container {
11
+ cursor: progress;
12
+ }
13
+
14
+ :host([style*="cursor: not-allowed"]) .container {
15
+ cursor: not-allowed;
16
+ }
17
+
18
+ :host([style*="cursor: default"]) .container {
19
+ cursor: default;
20
+ }
21
+
22
+ .container {
23
+ background: var(--ai-background-color, #ffffff);
24
+ border: 1px solid var(--ai-border-color, #e5e7eb);
25
+ border-radius: var(--ai-border-radius, 8px);
26
+ padding: var(--ai-spacing, 12px);
27
+ }
28
+
29
+ .header {
30
+ display: flex;
31
+ justify-content: space-between;
32
+ align-items: center;
33
+ margin-bottom: var(--ai-spacing, 12px);
34
+ }
35
+
36
+ .status-message {
37
+ font-weight: 600;
38
+ color: var(--ai-text-color, #1f2937);
39
+ font-size: 14px;
40
+ }
41
+
42
+ .status-badge {
43
+ padding: 4px 10px;
44
+ border-radius: 12px;
45
+ font-size: 12px;
46
+ font-weight: 600;
47
+ text-transform: uppercase;
48
+ }
49
+
50
+ .status-badge.processing {
51
+ background: #dbeafe;
52
+ color: #1e40af;
53
+ }
54
+
55
+ .status-badge.completed {
56
+ background: #d1fae5;
57
+ color: #065f46;
58
+ }
59
+
60
+ .status-badge.cancelled {
61
+ background: #fee2e2;
62
+ color: #991b1b;
63
+ }
64
+
65
+ .stats {
66
+ display: flex;
67
+ gap: 16px;
68
+ margin-bottom: var(--ai-spacing, 12px);
69
+ padding: 8px;
70
+ background: #f9fafb;
71
+ border-radius: 6px;
72
+ }
73
+
74
+ .stat-item {
75
+ display: flex;
76
+ flex-direction: column;
77
+ gap: 2px;
78
+ }
79
+
80
+ .stat-label {
81
+ font-size: 11px;
82
+ color: #6b7280;
83
+ text-transform: uppercase;
84
+ font-weight: 600;
85
+ letter-spacing: 0.5px;
86
+ }
87
+
88
+ .stat-value {
89
+ font-size: 18px;
90
+ font-weight: 700;
91
+ color: var(--ai-text-color, #1f2937);
92
+ }
93
+
94
+ .stat-value.success {
95
+ color: var(--ai-secondary-color, #10b981);
96
+ }
97
+
98
+ .stat-value.error {
99
+ color: #ef4444;
100
+ }
101
+
102
+ .stat-value.rate {
103
+ color: var(--ai-primary-color, #3b82f6);
104
+ }
105
+
106
+ .overall-progress {
107
+ margin-bottom: var(--ai-spacing, 12px);
108
+ }
109
+
110
+ .progress-header {
111
+ display: flex;
112
+ justify-content: space-between;
113
+ margin-bottom: 6px;
114
+ font-size: 12px;
115
+ color: #6b7280;
116
+ }
117
+
118
+ .progress-bar {
119
+ width: 100%;
120
+ height: 8px;
121
+ background: #f3f4f6;
122
+ border-radius: 4px;
123
+ overflow: hidden;
124
+ position: relative;
125
+ }
126
+
127
+ .progress-fill {
128
+ height: 100%;
129
+ background: linear-gradient(90deg, var(--ai-primary-color, #3b82f6), var(--ai-secondary-color, #10b981));
130
+ transition: width 0.3s ease;
131
+ border-radius: 4px;
132
+ }
133
+
134
+ .items-container {
135
+ max-height: 400px;
136
+ overflow-y: auto;
137
+ border: 1px solid var(--ai-border-color, #e5e7eb);
138
+ border-radius: 6px;
139
+ background: white;
140
+ }
141
+
142
+ .batch-item {
143
+ padding: 10px 12px;
144
+ border-bottom: 1px solid var(--ai-border-color, #e5e7eb);
145
+ transition: background 0.2s;
146
+ }
147
+
148
+ .batch-item:last-child {
149
+ border-bottom: none;
150
+ }
151
+
152
+ .batch-item.processing {
153
+ background: #eff6ff;
154
+ }
155
+
156
+ .batch-item.completed {
157
+ background: #f0fdf4;
158
+ }
159
+
160
+ .batch-item.failed {
161
+ background: #fef2f2;
162
+ }
163
+
164
+ .batch-item.collapsed {
165
+ opacity: 0.6;
166
+ max-height: 0;
167
+ padding: 0 12px;
168
+ overflow: hidden;
169
+ transition: max-height 0.3s, padding 0.3s, opacity 0.3s;
170
+ }
171
+
172
+ .item-header {
173
+ display: flex;
174
+ justify-content: space-between;
175
+ align-items: center;
176
+ margin-bottom: 4px;
177
+ }
178
+
179
+ .item-label {
180
+ font-size: 13px;
181
+ font-weight: 500;
182
+ color: var(--ai-text-color, #1f2937);
183
+ flex: 1;
184
+ }
185
+
186
+ .item-status {
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 6px;
190
+ font-size: 11px;
191
+ font-weight: 600;
192
+ }
193
+
194
+ .item-status.pending {
195
+ color: #6b7280;
196
+ }
197
+
198
+ .item-status.processing {
199
+ color: var(--ai-primary-color, #3b82f6);
200
+ }
201
+
202
+ .item-status.completed {
203
+ color: var(--ai-secondary-color, #10b981);
204
+ }
205
+
206
+ .item-status.failed {
207
+ color: #ef4444;
208
+ }
209
+
210
+ .item-status-icon {
211
+ font-size: 14px;
212
+ }
213
+
214
+ .item-progress-bar {
215
+ height: 4px;
216
+ background: #e5e7eb;
217
+ border-radius: 2px;
218
+ overflow: hidden;
219
+ margin-top: 4px;
220
+ }
221
+
222
+ .item-progress-fill {
223
+ height: 100%;
224
+ background: var(--ai-primary-color, #3b82f6);
225
+ transition: width 0.3s ease;
226
+ border-radius: 2px;
227
+ }
228
+
229
+ .item-error {
230
+ margin-top: 4px;
231
+ padding: 6px 8px;
232
+ background: #fee2e2;
233
+ border-left: 3px solid #ef4444;
234
+ border-radius: 4px;
235
+ font-size: 12px;
236
+ color: #991b1b;
237
+ }
238
+
239
+ .controls {
240
+ margin-top: var(--ai-spacing, 12px);
241
+ display: flex;
242
+ justify-content: flex-end;
243
+ }
244
+
245
+ .cancel-btn {
246
+ padding: 8px 16px;
247
+ background: #fee2e2;
248
+ color: #991b1b;
249
+ border: 1px solid #fecaca;
250
+ border-radius: 6px;
251
+ font-size: 13px;
252
+ font-weight: 600;
253
+ cursor: pointer;
254
+ transition: background 0.2s;
255
+ }
256
+
257
+ .cancel-btn:hover:not(:disabled) {
258
+ background: #fecaca;
259
+ }
260
+
261
+ .cancel-btn:disabled {
262
+ opacity: 0.5;
263
+ cursor: not-allowed;
264
+ }
265
+
266
+ .spinner {
267
+ display: inline-block;
268
+ width: 12px;
269
+ height: 12px;
270
+ border: 2px solid currentColor;
271
+ border-radius: 50%;
272
+ border-top-color: transparent;
273
+ animation: spin 0.6s linear infinite;
274
+ }
275
+
276
+ @keyframes spin {
277
+ to { transform: rotate(360deg); }
278
+ }
279
+
280
+ .empty-state {
281
+ text-align: center;
282
+ padding: 40px 20px;
283
+ color: #9ca3af;
284
+ }
285
+
286
+ .empty-state-icon {
287
+ font-size: 48px;
288
+ margin-bottom: 12px;
289
+ }
290
+
291
+ /* Visual Variants */
292
+
293
+ /* Minimal variant - clean, no shadows */
294
+ :host([variant="minimal"]) .container {
295
+ box-shadow: none;
296
+ border: 1px solid var(--ai-border-color, #e5e7eb);
297
+ }
298
+
299
+ :host([variant="minimal"]) .progress-bar {
300
+ background: transparent;
301
+ border: 1px solid var(--ai-border-color, #e5e7eb);
302
+ }
303
+
304
+ /* Gradient variant - colorful gradients */
305
+ :host([variant="gradient"]) .progress-fill {
306
+ background: linear-gradient(
307
+ 90deg,
308
+ var(--ai-primary-color, #3b82f6),
309
+ var(--ai-secondary-color, #10b981),
310
+ var(--ai-primary-color, #3b82f6)
311
+ );
312
+ background-size: 200% 100%;
313
+ animation: gradient-shift 3s ease-in-out infinite;
314
+ }
315
+
316
+ @keyframes gradient-shift {
317
+ 0%, 100% { background-position: 0% 50%; }
318
+ 50% { background-position: 100% 50%; }
319
+ }
320
+
321
+ /* Override default animation when animation attribute is set */
322
+ :host([animation][variant="gradient"]) .progress-fill {
323
+ animation: none !important;
324
+ }
325
+
326
+ /* Glassmorphic variant - frosted glass effect */
327
+ :host([variant="glassmorphic"]) .container {
328
+ background: rgba(255, 255, 255, 0.1);
329
+ backdrop-filter: blur(10px);
330
+ -webkit-backdrop-filter: blur(10px);
331
+ border: 1px solid rgba(255, 255, 255, 0.2);
332
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
333
+ }
334
+
335
+ :host([variant="glassmorphic"]) .progress-bar {
336
+ background: rgba(0, 0, 0, 0.1);
337
+ }
338
+
339
+ :host([variant="glassmorphic"]) .progress-fill {
340
+ background: linear-gradient(
341
+ 90deg,
342
+ rgba(59, 130, 246, 0.8),
343
+ rgba(16, 185, 129, 0.8)
344
+ );
345
+ }
346
+
347
+ /* Animation Effects */
348
+
349
+ /* Striped animation */
350
+ :host([animation="striped"]) .progress-fill {
351
+ background-image:
352
+ linear-gradient(
353
+ 45deg,
354
+ rgba(255, 255, 255, 0.2) 25%,
355
+ transparent 25%,
356
+ transparent 50%,
357
+ rgba(255, 255, 255, 0.2) 50%,
358
+ rgba(255, 255, 255, 0.2) 75%,
359
+ transparent 75%,
360
+ transparent
361
+ ),
362
+ linear-gradient(to right, var(--ai-primary-color, #3b82f6), var(--ai-primary-color, #3b82f6)) !important;
363
+ background-size: 2rem 2rem, 100% 100% !important;
364
+ animation: progress-stripes 3s linear infinite !important;
365
+ }
366
+
367
+ @keyframes progress-stripes {
368
+ 0% { background-position: 0 0, 0 0; }
369
+ 100% { background-position: 2rem 0, 0 0; }
370
+ }
371
+
372
+ /* Pulse animation */
373
+ :host([animation="pulse"]) .progress-fill {
374
+ animation: progress-pulse 4s ease-in-out infinite !important;
375
+ }
376
+
377
+ @keyframes progress-pulse {
378
+ 0%, 100% { opacity: 1; }
379
+ 50% { opacity: 0.3; }
380
+ }
381
+
382
+ /* Glow animation */
383
+ :host([animation="glow"]) .progress-fill {
384
+ animation: progress-glow 4s ease-in-out infinite !important;
385
+ }
386
+
387
+ @keyframes progress-glow {
388
+ 0%, 100% {
389
+ box-shadow: 0 0 5px var(--ai-primary-color, #3b82f6),
390
+ 0 0 10px var(--ai-primary-color, #3b82f6);
391
+ }
392
+ 50% {
393
+ box-shadow: 0 0 20px var(--ai-primary-color, #3b82f6),
394
+ 0 0 35px var(--ai-primary-color, #3b82f6),
395
+ 0 0 50px var(--ai-primary-color, #3b82f6);
396
+ }
397
+ }
398
+
399
+ /* Size variants */
400
+ :host([size="compact"]) .container {
401
+ padding: 8px;
402
+ font-size: 12px;
403
+ }
404
+
405
+ :host([size="compact"]) .progress-bar {
406
+ height: 6px;
407
+ }
408
+
409
+ :host([size="compact"]) .status-message {
410
+ font-size: 12px;
411
+ }
412
+
413
+ :host([size="compact"]) .status-badge {
414
+ padding: 3px 8px;
415
+ font-size: 10px;
416
+ }
417
+
418
+ :host([size="compact"]) .stat-value {
419
+ font-size: 16px;
420
+ }
421
+
422
+ :host([size="compact"]) .stat-label {
423
+ font-size: 10px;
424
+ }
425
+
426
+ :host([size="large"]) .container {
427
+ padding: 16px;
428
+ font-size: 16px;
429
+ }
430
+
431
+ :host([size="large"]) .progress-bar {
432
+ height: 10px;
433
+ }
434
+
435
+ :host([size="large"]) .status-message {
436
+ font-size: 16px;
437
+ }
438
+
439
+ :host([size="large"]) .status-badge {
440
+ padding: 5px 12px;
441
+ font-size: 13px;
442
+ }
443
+
444
+ :host([size="large"]) .stat-value {
445
+ font-size: 20px;
446
+ }
447
+
448
+ :host([size="large"]) .stat-label {
449
+ font-size: 12px;
450
+ }
451
+
452
+ /* Accessibility */
453
+ @media (prefers-reduced-motion: reduce) {
454
+ .progress-fill,
455
+ .item-progress-fill,
456
+ .spinner {
457
+ animation: none;
458
+ transition: none;
459
+ }
460
+ }
461
+
462
+ /* Scrollbar styling */
463
+ .items-container::-webkit-scrollbar {
464
+ width: 8px;
465
+ }
466
+
467
+ .items-container::-webkit-scrollbar-track {
468
+ background: #f3f4f6;
469
+ border-radius: 4px;
470
+ }
471
+
472
+ .items-container::-webkit-scrollbar-thumb {
473
+ background: #d1d5db;
474
+ border-radius: 4px;
475
+ }
476
+
477
+ .items-container::-webkit-scrollbar-thumb:hover {
478
+ background: #9ca3af;
479
+ }
480
+ `;
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Status of a batch item
3
+ */
4
+ export type BatchItemStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
5
+
6
+ /**
7
+ * Individual batch item
8
+ */
9
+ export interface BatchItem {
10
+ id: string;
11
+ label?: string;
12
+ status: BatchItemStatus;
13
+ progress?: number; // 0-100
14
+ error?: string;
15
+ result?: any;
16
+ startTime?: number;
17
+ endTime?: number;
18
+ }
19
+
20
+ /**
21
+ * Configuration options for BatchProgress
22
+ */
23
+ export interface BatchProgressConfig {
24
+ /** Total number of items in batch */
25
+ totalItems?: number;
26
+
27
+ /** Maximum concurrent operations */
28
+ concurrency?: number;
29
+
30
+ /** Show individual item progress */
31
+ showItems?: boolean;
32
+
33
+ /** Maximum items to display */
34
+ maxDisplayItems?: number;
35
+
36
+ /** Show overall progress bar */
37
+ showProgressBar?: boolean;
38
+
39
+ /** Show statistics (success/fail counts) */
40
+ showStats?: boolean;
41
+
42
+ /** Show elapsed time */
43
+ showTime?: boolean;
44
+
45
+ /** Show processing rate (items/sec) */
46
+ showRate?: boolean;
47
+
48
+ /** Allow cancellation */
49
+ allowCancel?: boolean;
50
+
51
+ /** Cancel button label */
52
+ cancelLabel?: string;
53
+
54
+ /** Automatically collapse completed items */
55
+ collapseCompleted?: boolean;
56
+
57
+ /** Status message */
58
+ message?: string;
59
+
60
+ /** Enable automatic cursor state changes based on component state */
61
+ cursorFeedback?: boolean;
62
+
63
+ /** Component size variant */
64
+ size?: 'compact' | 'default' | 'large';
65
+
66
+ /** Visual style variant */
67
+ variant?: 'default' | 'minimal' | 'gradient' | 'glassmorphic';
68
+
69
+ /** Animation style */
70
+ animation?: 'none' | 'striped' | 'pulse' | 'glow';
71
+
72
+ /** Disabled state */
73
+ disabled?: boolean;
74
+
75
+ /** Enable debug logging */
76
+ debug?: boolean;
77
+
78
+ /** Additional CSS class */
79
+ className?: string;
80
+
81
+ /** ARIA label for accessibility */
82
+ ariaLabel?: string;
83
+ }
84
+
85
+ /**
86
+ * Internal state of the BatchProgress
87
+ */
88
+ export interface BatchProgressState {
89
+ status: 'idle' | 'processing' | 'completed' | 'paused' | 'cancelled';
90
+ items: Map<string, BatchItem>;
91
+ totalItems: number;
92
+ completedCount: number;
93
+ failedCount: number;
94
+ successCount: number;
95
+ currentConcurrency: number;
96
+ startTime: number | null;
97
+ endTime: number | null;
98
+ message: string;
99
+ }
100
+
101
+ /**
102
+ * Update parameters for batch progress
103
+ */
104
+ export interface BatchProgressUpdate {
105
+ itemId: string;
106
+ status?: BatchItemStatus;
107
+ progress?: number;
108
+ error?: string;
109
+ result?: any;
110
+ label?: string;
111
+ }
112
+
113
+ /**
114
+ * Event detail for batch start
115
+ */
116
+ export interface BatchStartEvent {
117
+ totalItems: number;
118
+ startTime: number;
119
+ }
120
+
121
+ /**
122
+ * Event detail for batch item update
123
+ */
124
+ export interface BatchItemUpdateEvent extends BatchItem {
125
+ totalCompleted: number;
126
+ totalFailed: number;
127
+ overallProgress: number;
128
+ }
129
+
130
+ /**
131
+ * Event detail for batch complete
132
+ */
133
+ export interface BatchCompleteEvent {
134
+ totalItems: number;
135
+ successCount: number;
136
+ failedCount: number;
137
+ duration: number;
138
+ averageRate: number;
139
+ startTime: number;
140
+ endTime: number;
141
+ }
142
+
143
+ /**
144
+ * Event detail for batch cancel
145
+ */
146
+ export interface BatchCancelEvent {
147
+ completedCount: number;
148
+ failedCount: number;
149
+ cancelledCount: number;
150
+ reason?: string;
151
+ }
152
+
153
+ /**
154
+ * Event detail for batch item complete
155
+ */
156
+ export interface BatchItemCompleteEvent {
157
+ item: BatchItem;
158
+ totalCompleted: number;
159
+ remainingItems: number;
160
+ }
161
+
162
+ /**
163
+ * Event detail for batch item failed
164
+ */
165
+ export interface BatchItemFailedEvent {
166
+ item: BatchItem;
167
+ error: string;
168
+ totalFailed: number;
169
+ }