@coherent.js/performance 1.0.0-beta.5 → 1.0.0-beta.6

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 (2) hide show
  1. package/package.json +2 -2
  2. package/types/index.d.ts +426 -29
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coherent.js/performance",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.6",
4
4
  "description": "Performance optimization utilities for Coherent.js",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "author": "Coherent.js Team",
21
21
  "license": "MIT",
22
22
  "peerDependencies": {
23
- "@coherent.js/core": "1.0.0-beta.5"
23
+ "@coherent.js/core": "1.0.0-beta.6"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
package/types/index.d.ts CHANGED
@@ -3,164 +3,561 @@
3
3
  * @module @coherent.js/performance
4
4
  */
5
5
 
6
- // ===== Code Splitting Types =====
6
+ import type { CoherentNode, CoherentComponent, ComponentProps } from '@coherent.js/core';
7
7
 
8
+ // ============================================================================
9
+ // Performance Metrics
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Comprehensive performance metrics
14
+ */
15
+ export interface PerformanceMetrics {
16
+ /** Total render time (ms) */
17
+ renderTime: number;
18
+ /** Number of components rendered */
19
+ componentCount: number;
20
+ /** Total number of renders */
21
+ totalRenders: number;
22
+ /** Average render time */
23
+ avgRenderTime: number;
24
+ /** Slowest render information */
25
+ slowestRender: {
26
+ component: string;
27
+ time: number;
28
+ };
29
+ /** Memory usage (if available) */
30
+ memoryUsage?: number;
31
+ /** Cache hit rate */
32
+ cacheHitRate?: number;
33
+ /** Bundle size information */
34
+ bundleSize?: {
35
+ total: number;
36
+ gzipped: number;
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Performance configuration
42
+ */
43
+ export interface PerformanceConfig {
44
+ /** Enable performance tracking */
45
+ enabled?: boolean;
46
+ /** Sample rate (0-1) for measurement */
47
+ sampleRate?: number;
48
+ /** Threshold for slow render warning (ms) */
49
+ slowThreshold?: number;
50
+ /** Callback for slow renders */
51
+ onSlowRender?: (component: string, time: number) => void;
52
+ /** Enable detailed tracing */
53
+ tracing?: boolean;
54
+ }
55
+
56
+ /**
57
+ * Profiler result for a single render
58
+ */
59
+ export interface ProfilerResult {
60
+ /** Component name */
61
+ componentName: string;
62
+ /** Total duration (ms) */
63
+ duration: number;
64
+ /** Render phase */
65
+ phase: 'mount' | 'update';
66
+ /** Actual render duration */
67
+ actualDuration: number;
68
+ /** Base duration (without memoization) */
69
+ baseDuration: number;
70
+ /** Start time (relative to page load) */
71
+ startTime: number;
72
+ /** Commit time */
73
+ commitTime: number;
74
+ }
75
+
76
+ /**
77
+ * Create a performance profiler
78
+ */
79
+ export function createProfiler(config?: PerformanceConfig): {
80
+ /** Start a measurement */
81
+ start(label: string): void;
82
+ /** End a measurement and return duration */
83
+ end(label: string): number;
84
+ /** Measure a synchronous function */
85
+ measure<T>(label: string, fn: () => T): T;
86
+ /** Measure an async function */
87
+ measureAsync<T>(label: string, fn: () => Promise<T>): Promise<T>;
88
+ /** Get current metrics */
89
+ getMetrics(): PerformanceMetrics;
90
+ /** Reset all measurements */
91
+ reset(): void;
92
+ /** Subscribe to render events */
93
+ onRender(callback: (result: ProfilerResult) => void): () => void;
94
+ };
95
+
96
+ /**
97
+ * HOC to add profiling to a component
98
+ */
99
+ export function withProfiling<P extends ComponentProps>(
100
+ component: CoherentComponent<P>,
101
+ name?: string
102
+ ): CoherentComponent<P>;
103
+
104
+ /**
105
+ * Memoize with metrics tracking
106
+ */
107
+ export function memoWithMetrics<T extends (...args: unknown[]) => unknown>(
108
+ fn: T,
109
+ options?: {
110
+ name?: string;
111
+ maxSize?: number;
112
+ }
113
+ ): T & {
114
+ hits: number;
115
+ misses: number;
116
+ hitRate: () => number;
117
+ };
118
+
119
+ // ============================================================================
120
+ // Code Splitting
121
+ // ============================================================================
122
+
123
+ /**
124
+ * Split options for lazy loading
125
+ */
8
126
  export interface SplitOptions {
9
- loading?: any;
10
- error?: any;
127
+ /** Loading component */
128
+ loading?: CoherentNode;
129
+ /** Error component */
130
+ error?: CoherentNode;
131
+ /** Delay before showing loading (ms) */
11
132
  delay?: number;
133
+ /** Timeout for loading (ms) */
12
134
  timeout?: number;
13
135
  }
14
136
 
15
- export type LazyComponent = () => Promise<any>;
137
+ /**
138
+ * Lazy component loader type
139
+ */
140
+ export type LazyComponent = () => Promise<{ default: CoherentComponent }>;
16
141
 
142
+ /**
143
+ * Code splitter class
144
+ */
17
145
  export class CodeSplitter {
18
146
  constructor();
19
- lazy(loader: LazyComponent, options?: SplitOptions): LazyComponent;
20
- split(component: any, chunkName?: string): LazyComponent;
21
- preload(loader: LazyComponent): Promise<any>;
147
+
148
+ /** Create a lazy-loaded component */
149
+ lazy(loader: LazyComponent, options?: SplitOptions): CoherentComponent;
150
+
151
+ /** Split a component into a separate chunk */
152
+ split(component: CoherentComponent, chunkName?: string): LazyComponent;
153
+
154
+ /** Preload a lazy component */
155
+ preload(loader: LazyComponent): Promise<CoherentComponent>;
156
+
157
+ /** Prefetch a lazy component (lower priority) */
22
158
  prefetch(loader: LazyComponent): void;
23
159
  }
24
160
 
161
+ /**
162
+ * Create a code splitter instance
163
+ */
25
164
  export function createCodeSplitter(): CodeSplitter;
26
- export function lazy(loader: LazyComponent, options?: SplitOptions): LazyComponent;
27
- export function splitComponent(component: any, chunkName?: string): LazyComponent;
28
165
 
166
+ /**
167
+ * Create a lazy-loaded component
168
+ */
169
+ export function lazy(loader: LazyComponent, options?: SplitOptions): CoherentComponent;
170
+
171
+ /**
172
+ * Split a component into a separate chunk
173
+ */
174
+ export function splitComponent(component: CoherentComponent, chunkName?: string): LazyComponent;
175
+
176
+ /**
177
+ * Route-based code splitting configuration
178
+ */
29
179
  export interface RouteConfig {
180
+ /** Route path */
30
181
  path: string;
182
+ /** Lazy component loader */
31
183
  component: LazyComponent;
184
+ /** Preload on route definition */
32
185
  preload?: boolean;
186
+ /** Prefetch on idle */
33
187
  prefetch?: boolean;
34
188
  }
35
189
 
190
+ /**
191
+ * Create a route-based code splitter
192
+ */
36
193
  export function createRouteSplitter(routes: RouteConfig[]): {
194
+ /** Get route configuration */
37
195
  getRoute(path: string): RouteConfig | undefined;
196
+ /** Preload a route's component */
38
197
  preloadRoute(path: string): Promise<void>;
198
+ /** Prefetch a route's component */
39
199
  prefetchRoute(path: string): void;
40
200
  };
41
201
 
42
- // ===== Cache Types =====
202
+ // ============================================================================
203
+ // Caching
204
+ // ============================================================================
43
205
 
44
- export interface CacheEntry<T = any> {
206
+ /**
207
+ * Cache entry structure
208
+ */
209
+ export interface CacheEntry<T = unknown> {
210
+ /** Cached value */
45
211
  value: T;
212
+ /** Creation timestamp */
46
213
  timestamp: number;
214
+ /** Hit count */
47
215
  hits: number;
216
+ /** Size in bytes (estimated) */
48
217
  size?: number;
49
218
  }
50
219
 
220
+ /**
221
+ * Cache options
222
+ */
51
223
  export interface CacheOptions {
224
+ /** Maximum cache size */
52
225
  maxSize?: number;
226
+ /** Maximum age in ms */
53
227
  maxAge?: number;
54
- onEvict?: (key: string, value: any) => void;
228
+ /** Callback when entry is evicted */
229
+ onEvict?: (key: string, value: unknown) => void;
55
230
  }
56
231
 
57
- export class LRUCache<K = string, V = any> {
232
+ /**
233
+ * LRU Cache class
234
+ */
235
+ export class LRUCache<K = string, V = unknown> {
58
236
  constructor(options?: CacheOptions);
237
+
238
+ /** Get a cached value */
59
239
  get(key: K): V | undefined;
240
+
241
+ /** Set a cached value */
60
242
  set(key: K, value: V): void;
243
+
244
+ /** Check if key exists */
61
245
  has(key: K): boolean;
246
+
247
+ /** Delete a key */
62
248
  delete(key: K): boolean;
249
+
250
+ /** Clear all entries */
63
251
  clear(): void;
252
+
253
+ /** Get cache size */
64
254
  size(): number;
255
+
256
+ /** Get all keys */
65
257
  keys(): K[];
258
+
259
+ /** Get all values */
66
260
  values(): V[];
261
+
262
+ /** Get all entries */
67
263
  entries(): Array<[K, V]>;
68
264
  }
69
265
 
70
- export class MemoryCache<K = string, V = any> {
266
+ /**
267
+ * Memory cache with TTL support
268
+ */
269
+ export class MemoryCache<K = string, V = unknown> {
71
270
  constructor(options?: CacheOptions);
271
+
272
+ /** Get a cached value */
72
273
  get(key: K): V | undefined;
274
+
275
+ /** Set a cached value with optional TTL */
73
276
  set(key: K, value: V, ttl?: number): void;
277
+
278
+ /** Check if key exists */
74
279
  has(key: K): boolean;
280
+
281
+ /** Delete a key */
75
282
  delete(key: K): boolean;
283
+
284
+ /** Clear all entries */
76
285
  clear(): void;
286
+
287
+ /** Get cache size */
77
288
  size(): number;
289
+
290
+ /** Clean up expired entries */
78
291
  cleanup(): void;
79
292
  }
80
293
 
294
+ /**
295
+ * Memoization options
296
+ */
81
297
  export interface MemoOptions {
298
+ /** Maximum cache size */
82
299
  maxSize?: number;
83
- keyGenerator?: (...args: any[]) => string;
300
+ /** Custom key generator */
301
+ keyGenerator?: (...args: unknown[]) => string;
302
+ /** TTL in ms */
84
303
  ttl?: number;
85
304
  }
86
305
 
306
+ /**
307
+ * Memoization cache class
308
+ */
87
309
  export class MemoCache {
88
310
  constructor(options?: MemoOptions);
89
- memoize<T extends (...args: any[]) => any>(fn: T): T;
90
- clear(fn?: Function): void;
91
- has(fn: Function, args: any[]): boolean;
92
- delete(fn: Function, args?: any[]): boolean;
311
+
312
+ /** Memoize a function */
313
+ memoize<T extends (...args: unknown[]) => unknown>(fn: T): T;
314
+
315
+ /** Clear cache for a function */
316
+ clear(fn?: (...args: unknown[]) => unknown): void;
317
+
318
+ /** Check if result is cached */
319
+ has(fn: (...args: unknown[]) => unknown, args: unknown[]): boolean;
320
+
321
+ /** Delete cached result */
322
+ delete(fn: (...args: unknown[]) => unknown, args?: unknown[]): boolean;
93
323
  }
94
324
 
325
+ /**
326
+ * Render cache options
327
+ */
95
328
  export interface RenderCacheOptions extends CacheOptions {
96
- keyGenerator?: (component: any, props: any) => string;
329
+ /** Custom key generator */
330
+ keyGenerator?: (component: CoherentComponent, props: unknown) => string;
97
331
  }
98
332
 
333
+ /**
334
+ * Render cache for component output
335
+ */
99
336
  export class RenderCache {
100
337
  constructor(options?: RenderCacheOptions);
101
- get(component: any, props: any): string | undefined;
102
- set(component: any, props: any, html: string): void;
103
- clear(component?: any): void;
338
+
339
+ /** Get cached render */
340
+ get(component: CoherentComponent, props: unknown): string | undefined;
341
+
342
+ /** Set cached render */
343
+ set(component: CoherentComponent, props: unknown, html: string): void;
344
+
345
+ /** Clear cache for a component */
346
+ clear(component?: CoherentComponent): void;
347
+
348
+ /** Get cache size */
104
349
  size(): number;
105
350
  }
106
351
 
107
- export function createCache<K = string, V = any>(type: 'lru' | 'memory' | 'memo' | 'render', options?: CacheOptions): LRUCache<K, V> | MemoryCache<K, V> | MemoCache | RenderCache;
108
- export function memoize<T extends (...args: any[]) => any>(fn: T, options?: MemoOptions): T;
352
+ /**
353
+ * Create a cache of specified type
354
+ */
355
+ export function createCache<K = string, V = unknown>(
356
+ type: 'lru' | 'memory' | 'memo' | 'render',
357
+ options?: CacheOptions
358
+ ): LRUCache<K, V> | MemoryCache<K, V> | MemoCache | RenderCache;
359
+
360
+ /**
361
+ * Memoize a function
362
+ */
363
+ export function memoize<T extends (...args: unknown[]) => unknown>(
364
+ fn: T,
365
+ options?: MemoOptions
366
+ ): T;
109
367
 
110
- // ===== Lazy Loading Types =====
368
+ // ============================================================================
369
+ // Lazy Loading
370
+ // ============================================================================
111
371
 
372
+ /**
373
+ * Lazy load options
374
+ */
112
375
  export interface LazyLoadOptions {
376
+ /** Intersection threshold (0-1) */
113
377
  threshold?: number;
378
+ /** Root margin for intersection */
114
379
  rootMargin?: string;
380
+ /** Root element for intersection */
115
381
  root?: Element | null;
382
+ /** Callback when loaded */
116
383
  onLoad?: () => void;
384
+ /** Callback on error */
117
385
  onError?: (error: Error) => void;
118
386
  }
119
387
 
388
+ /**
389
+ * Lazy loader class
390
+ */
120
391
  export class LazyLoader {
121
392
  constructor(options?: LazyLoadOptions);
122
- observe(element: Element, loader: () => Promise<any>): void;
393
+
394
+ /** Start observing an element */
395
+ observe(element: Element, loader: () => Promise<unknown>): void;
396
+
397
+ /** Stop observing an element */
123
398
  unobserve(element: Element): void;
399
+
400
+ /** Disconnect all observers */
124
401
  disconnect(): void;
402
+
403
+ /** Load all observed elements */
125
404
  loadAll(): Promise<void[]>;
126
405
  }
127
406
 
407
+ /**
408
+ * Image lazy load options
409
+ */
128
410
  export interface ImageLazyLoadOptions extends LazyLoadOptions {
411
+ /** Placeholder image URL */
129
412
  placeholder?: string;
413
+ /** Blur data URL for preview */
130
414
  blurDataURL?: string;
415
+ /** Enable fade-in animation */
131
416
  fadeIn?: boolean;
417
+ /** Fade-in duration (ms) */
132
418
  fadeInDuration?: number;
133
419
  }
134
420
 
421
+ /**
422
+ * Image lazy loader class
423
+ */
135
424
  export class ImageLazyLoader extends LazyLoader {
136
425
  constructor(options?: ImageLazyLoadOptions);
426
+
427
+ /** Lazy load an image */
137
428
  lazyImage(element: HTMLImageElement, src: string, options?: ImageLazyLoadOptions): void;
138
429
  }
139
430
 
431
+ /**
432
+ * Preload options
433
+ */
140
434
  export interface PreloadOptions {
435
+ /** Resource type */
141
436
  as?: 'script' | 'style' | 'image' | 'font' | 'fetch';
437
+ /** Cross-origin setting */
142
438
  crossOrigin?: 'anonymous' | 'use-credentials';
439
+ /** MIME type */
143
440
  type?: string;
441
+ /** Media query */
144
442
  media?: string;
145
443
  }
146
444
 
445
+ /**
446
+ * Resource preloader class
447
+ */
147
448
  export class ResourcePreloader {
148
449
  constructor();
450
+
451
+ /** Preload a resource (high priority) */
149
452
  preload(url: string, options?: PreloadOptions): void;
453
+
454
+ /** Prefetch a resource (low priority) */
150
455
  prefetch(url: string): void;
456
+
457
+ /** Preconnect to a domain */
151
458
  preconnect(url: string, crossOrigin?: boolean): void;
459
+
460
+ /** DNS prefetch for a domain */
152
461
  dnsPrefetch(url: string): void;
462
+
463
+ /** Check if resource is preloaded */
153
464
  hasPreloaded(url: string): boolean;
154
465
  }
155
466
 
467
+ /**
468
+ * Create a lazy loader
469
+ */
156
470
  export function createLazyLoader(options?: LazyLoadOptions): LazyLoader;
157
- export function lazyImage(element: HTMLImageElement | string, src: string, options?: ImageLazyLoadOptions): void;
158
471
 
472
+ /**
473
+ * Lazy load an image
474
+ */
475
+ export function lazyImage(
476
+ element: HTMLImageElement | string,
477
+ src: string,
478
+ options?: ImageLazyLoadOptions
479
+ ): void;
480
+
481
+ /**
482
+ * Progressive image loading options
483
+ */
159
484
  export interface ProgressiveImageOptions {
485
+ /** Low quality image source */
160
486
  lowQualitySrc: string;
487
+ /** High quality image source */
161
488
  highQualitySrc: string;
489
+ /** Placeholder while loading */
162
490
  placeholder?: string;
491
+ /** Fade-in duration (ms) */
163
492
  fadeInDuration?: number;
164
493
  }
165
494
 
166
- export function progressiveImage(element: HTMLImageElement | string, options: ProgressiveImageOptions): Promise<void>;
495
+ /**
496
+ * Load an image progressively (low quality first)
497
+ */
498
+ export function progressiveImage(
499
+ element: HTMLImageElement | string,
500
+ options: ProgressiveImageOptions
501
+ ): Promise<void>;
502
+
503
+ // ============================================================================
504
+ // Bundle Optimization
505
+ // ============================================================================
506
+
507
+ /**
508
+ * Bundle analysis result
509
+ */
510
+ export interface BundleAnalysis {
511
+ /** Total size in bytes */
512
+ totalSize: number;
513
+ /** Gzipped size */
514
+ gzippedSize: number;
515
+ /** Modules in bundle */
516
+ modules: Array<{
517
+ name: string;
518
+ size: number;
519
+ gzippedSize: number;
520
+ }>;
521
+ /** Duplicate modules */
522
+ duplicates: Array<{
523
+ name: string;
524
+ count: number;
525
+ totalSize: number;
526
+ }>;
527
+ }
528
+
529
+ /**
530
+ * Tree shaking result
531
+ */
532
+ export interface TreeShakeResult {
533
+ /** Original size */
534
+ originalSize: number;
535
+ /** Size after tree shaking */
536
+ shakenSize: number;
537
+ /** Removed exports */
538
+ removed: string[];
539
+ /** Kept exports */
540
+ kept: string[];
541
+ }
542
+
543
+ /**
544
+ * Bundle optimizer class
545
+ */
546
+ export class BundleOptimizer {
547
+ /** Analyze a bundle */
548
+ analyze(bundle: unknown): BundleAnalysis;
549
+
550
+ /** Optimize a bundle */
551
+ optimize(bundle: unknown): unknown;
552
+
553
+ /** Split bundle into chunks */
554
+ splitChunks(bundle: unknown): unknown[];
555
+
556
+ /** Tree shake a bundle */
557
+ treeshake(bundle: unknown): TreeShakeResult;
558
+ }
559
+
560
+ /**
561
+ * Global bundle optimizer instance
562
+ */
563
+ export const bundleOptimizer: BundleOptimizer;