@sc4rfurryx/proteusjs 1.0.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 (82) hide show
  1. package/API.md +438 -0
  2. package/FEATURES.md +286 -0
  3. package/LICENSE +21 -0
  4. package/README.md +645 -0
  5. package/dist/.tsbuildinfo +1 -0
  6. package/dist/proteus.cjs.js +16014 -0
  7. package/dist/proteus.cjs.js.map +1 -0
  8. package/dist/proteus.d.ts +3018 -0
  9. package/dist/proteus.esm.js +16005 -0
  10. package/dist/proteus.esm.js.map +1 -0
  11. package/dist/proteus.esm.min.js +8 -0
  12. package/dist/proteus.esm.min.js.map +1 -0
  13. package/dist/proteus.js +16020 -0
  14. package/dist/proteus.js.map +1 -0
  15. package/dist/proteus.min.js +8 -0
  16. package/dist/proteus.min.js.map +1 -0
  17. package/package.json +98 -0
  18. package/src/__tests__/mvp-integration.test.ts +518 -0
  19. package/src/accessibility/AccessibilityEngine.ts +2106 -0
  20. package/src/accessibility/ScreenReaderSupport.ts +444 -0
  21. package/src/accessibility/__tests__/ScreenReaderSupport.test.ts +435 -0
  22. package/src/animations/FLIPAnimationSystem.ts +491 -0
  23. package/src/compatibility/BrowserCompatibility.ts +1076 -0
  24. package/src/containers/BreakpointSystem.ts +347 -0
  25. package/src/containers/ContainerBreakpoints.ts +726 -0
  26. package/src/containers/ContainerManager.ts +370 -0
  27. package/src/containers/ContainerUnits.ts +336 -0
  28. package/src/containers/ContextIsolation.ts +394 -0
  29. package/src/containers/ElementQueries.ts +411 -0
  30. package/src/containers/SmartContainer.ts +536 -0
  31. package/src/containers/SmartContainers.ts +376 -0
  32. package/src/containers/__tests__/ContainerBreakpoints.test.ts +411 -0
  33. package/src/containers/__tests__/SmartContainers.test.ts +281 -0
  34. package/src/content/ResponsiveImages.ts +570 -0
  35. package/src/core/EventSystem.ts +147 -0
  36. package/src/core/MemoryManager.ts +321 -0
  37. package/src/core/PerformanceMonitor.ts +238 -0
  38. package/src/core/PluginSystem.ts +275 -0
  39. package/src/core/ProteusJS.test.ts +164 -0
  40. package/src/core/ProteusJS.ts +962 -0
  41. package/src/developer/PerformanceProfiler.ts +567 -0
  42. package/src/developer/VisualDebuggingTools.ts +656 -0
  43. package/src/developer/ZeroConfigSystem.ts +593 -0
  44. package/src/index.ts +35 -0
  45. package/src/integration.test.ts +227 -0
  46. package/src/layout/AdaptiveGrid.ts +429 -0
  47. package/src/layout/ContentReordering.ts +532 -0
  48. package/src/layout/FlexboxEnhancer.ts +406 -0
  49. package/src/layout/FlowLayout.ts +545 -0
  50. package/src/layout/SpacingSystem.ts +512 -0
  51. package/src/observers/IntersectionObserverPolyfill.ts +289 -0
  52. package/src/observers/ObserverManager.ts +299 -0
  53. package/src/observers/ResizeObserverPolyfill.ts +179 -0
  54. package/src/performance/BatchDOMOperations.ts +519 -0
  55. package/src/performance/CSSOptimizationEngine.ts +646 -0
  56. package/src/performance/CacheOptimizationSystem.ts +601 -0
  57. package/src/performance/EfficientEventHandler.ts +740 -0
  58. package/src/performance/LazyEvaluationSystem.ts +532 -0
  59. package/src/performance/MemoryManagementSystem.ts +497 -0
  60. package/src/performance/PerformanceMonitor.ts +931 -0
  61. package/src/performance/__tests__/BatchDOMOperations.test.ts +309 -0
  62. package/src/performance/__tests__/EfficientEventHandler.test.ts +268 -0
  63. package/src/performance/__tests__/PerformanceMonitor.test.ts +422 -0
  64. package/src/polyfills/BrowserPolyfills.ts +586 -0
  65. package/src/polyfills/__tests__/BrowserPolyfills.test.ts +328 -0
  66. package/src/test/setup.ts +115 -0
  67. package/src/theming/SmartThemeSystem.ts +591 -0
  68. package/src/types/index.ts +134 -0
  69. package/src/typography/ClampScaling.ts +356 -0
  70. package/src/typography/FluidTypography.ts +759 -0
  71. package/src/typography/LineHeightOptimization.ts +430 -0
  72. package/src/typography/LineHeightOptimizer.ts +326 -0
  73. package/src/typography/TextFitting.ts +355 -0
  74. package/src/typography/TypographicScale.ts +428 -0
  75. package/src/typography/VerticalRhythm.ts +369 -0
  76. package/src/typography/__tests__/FluidTypography.test.ts +432 -0
  77. package/src/typography/__tests__/LineHeightOptimization.test.ts +436 -0
  78. package/src/utils/Logger.ts +173 -0
  79. package/src/utils/debounce.ts +259 -0
  80. package/src/utils/performance.ts +371 -0
  81. package/src/utils/support.ts +106 -0
  82. package/src/utils/version.ts +24 -0
@@ -0,0 +1,497 @@
1
+ /**
2
+ * Memory Management System for ProteusJS
3
+ * Automatic observer cleanup, event listener lifecycle management, and memory optimization
4
+ */
5
+
6
+ export interface MemoryConfig {
7
+ autoCleanup: boolean;
8
+ cleanupInterval: number;
9
+ memoryThreshold: number;
10
+ gcOptimization: boolean;
11
+ leakDetection: boolean;
12
+ performanceMonitoring: boolean;
13
+ }
14
+
15
+ export interface MemoryMetrics {
16
+ totalObservers: number;
17
+ activeObservers: number;
18
+ totalEventListeners: number;
19
+ activeEventListeners: number;
20
+ memoryUsage: number;
21
+ gcCollections: number;
22
+ leaksDetected: number;
23
+ cleanupOperations: number;
24
+ }
25
+
26
+ export interface ManagedResource {
27
+ id: string;
28
+ type: 'observer' | 'listener' | 'timer' | 'animation' | 'cache';
29
+ element?: Element;
30
+ cleanup: () => void;
31
+ timestamp: number;
32
+ lastAccessed: number;
33
+ memorySize: number;
34
+ }
35
+
36
+ export class MemoryManagementSystem {
37
+ private config: Required<MemoryConfig>;
38
+ private resources: Map<string, ManagedResource> = new Map();
39
+ private metrics: MemoryMetrics;
40
+ private cleanupTimer: number | null = null;
41
+ private performanceObserver: PerformanceObserver | null = null;
42
+ private weakRefs: Set<WeakRef<any>> = new Set();
43
+
44
+ constructor(config: Partial<MemoryConfig> = {}) {
45
+ this.config = {
46
+ autoCleanup: true,
47
+ cleanupInterval: 30000, // 30 seconds
48
+ memoryThreshold: 50 * 1024 * 1024, // 50MB
49
+ gcOptimization: true,
50
+ leakDetection: true,
51
+ performanceMonitoring: true,
52
+ ...config
53
+ };
54
+
55
+ this.metrics = this.createInitialMetrics();
56
+ this.setupMemoryMonitoring();
57
+ this.startAutoCleanup();
58
+ }
59
+
60
+ /**
61
+ * Register a managed resource
62
+ */
63
+ public register(
64
+ type: ManagedResource['type'],
65
+ cleanup: () => void,
66
+ element?: Element,
67
+ estimatedSize: number = 1024
68
+ ): string {
69
+ const id = this.generateResourceId();
70
+ const resource: ManagedResource = {
71
+ id,
72
+ type,
73
+ ...(element && { element }),
74
+ cleanup,
75
+ timestamp: performance.now(),
76
+ lastAccessed: performance.now(),
77
+ memorySize: estimatedSize
78
+ };
79
+
80
+ this.resources.set(id, resource);
81
+ this.updateMetrics(type, 'register');
82
+
83
+ // Create weak reference for leak detection
84
+ if (element && this.config.leakDetection) {
85
+ this.weakRefs.add(new WeakRef(element));
86
+ }
87
+
88
+ return id;
89
+ }
90
+
91
+ /**
92
+ * Unregister and cleanup a resource
93
+ */
94
+ public unregister(id: string): void {
95
+ const resource = this.resources.get(id);
96
+ if (resource) {
97
+ try {
98
+ resource.cleanup();
99
+ this.updateMetrics(resource.type, 'unregister');
100
+ } catch (error) {
101
+ console.error('Error during resource cleanup:', error);
102
+ }
103
+
104
+ this.resources.delete(id);
105
+ this.metrics.cleanupOperations++;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Register ResizeObserver with automatic cleanup
111
+ */
112
+ public registerResizeObserver(
113
+ observer: ResizeObserver,
114
+ elements: Element[]
115
+ ): string {
116
+ return this.register(
117
+ 'observer',
118
+ () => {
119
+ observer.disconnect();
120
+ },
121
+ elements[0],
122
+ elements.length * 512 // Estimate memory per observed element
123
+ );
124
+ }
125
+
126
+ /**
127
+ * Register IntersectionObserver with automatic cleanup
128
+ */
129
+ public registerIntersectionObserver(
130
+ observer: IntersectionObserver,
131
+ elements: Element[]
132
+ ): string {
133
+ return this.register(
134
+ 'observer',
135
+ () => {
136
+ observer.disconnect();
137
+ },
138
+ elements[0],
139
+ elements.length * 256
140
+ );
141
+ }
142
+
143
+ /**
144
+ * Register event listener with automatic cleanup
145
+ */
146
+ public registerEventListener(
147
+ element: Element,
148
+ event: string,
149
+ listener: EventListener,
150
+ options?: AddEventListenerOptions
151
+ ): string {
152
+ return this.register(
153
+ 'listener',
154
+ () => {
155
+ element.removeEventListener(event, listener, options);
156
+ },
157
+ element,
158
+ 128 // Estimate memory per listener
159
+ );
160
+ }
161
+
162
+ /**
163
+ * Register timer with automatic cleanup
164
+ */
165
+ public registerTimer(timerId: number, type: 'timeout' | 'interval' = 'timeout'): string {
166
+ return this.register(
167
+ 'timer',
168
+ () => {
169
+ if (type === 'timeout') {
170
+ clearTimeout(timerId);
171
+ } else {
172
+ clearInterval(timerId);
173
+ }
174
+ },
175
+ undefined,
176
+ 64
177
+ );
178
+ }
179
+
180
+ /**
181
+ * Register animation with automatic cleanup
182
+ */
183
+ public registerAnimation(animation: Animation): string {
184
+ return this.register(
185
+ 'animation',
186
+ () => {
187
+ animation.cancel();
188
+ },
189
+ (animation.effect as any)?.target instanceof Element ? (animation.effect as any).target : undefined,
190
+ 256
191
+ );
192
+ }
193
+
194
+ /**
195
+ * Register cache entry with automatic cleanup
196
+ */
197
+ public registerCacheEntry(
198
+ cache: Map<any, any> | WeakMap<any, any>,
199
+ key: any,
200
+ estimatedSize: number = 1024
201
+ ): string {
202
+ return this.register(
203
+ 'cache',
204
+ () => {
205
+ cache.delete(key);
206
+ },
207
+ undefined,
208
+ estimatedSize
209
+ );
210
+ }
211
+
212
+ /**
213
+ * Force cleanup of all resources
214
+ */
215
+ public cleanup(): void {
216
+ const resourceIds = Array.from(this.resources.keys());
217
+ resourceIds.forEach(id => this.unregister(id));
218
+ }
219
+
220
+ /**
221
+ * Cleanup resources by type
222
+ */
223
+ public cleanupByType(type: ManagedResource['type']): void {
224
+ const resourceIds = Array.from(this.resources.entries())
225
+ .filter(([, resource]) => resource.type === type)
226
+ .map(([id]) => id);
227
+
228
+ resourceIds.forEach(id => this.unregister(id));
229
+ }
230
+
231
+ /**
232
+ * Cleanup stale resources
233
+ */
234
+ public cleanupStale(maxAge: number = 300000): void { // 5 minutes default
235
+ const now = performance.now();
236
+ const staleIds = Array.from(this.resources.entries())
237
+ .filter(([, resource]) => now - resource.lastAccessed > maxAge)
238
+ .map(([id]) => id);
239
+
240
+ staleIds.forEach(id => this.unregister(id));
241
+ }
242
+
243
+ /**
244
+ * Cleanup resources for removed elements
245
+ */
246
+ public cleanupOrphanedResources(): void {
247
+ const orphanedIds: string[] = [];
248
+
249
+ this.resources.forEach((resource, id) => {
250
+ if (resource.element && !document.contains(resource.element)) {
251
+ orphanedIds.push(id);
252
+ }
253
+ });
254
+
255
+ orphanedIds.forEach(id => this.unregister(id));
256
+ }
257
+
258
+ /**
259
+ * Get current memory metrics
260
+ */
261
+ public getMetrics(): MemoryMetrics {
262
+ this.updateMemoryUsage();
263
+ return { ...this.metrics };
264
+ }
265
+
266
+ /**
267
+ * Get resource count by type
268
+ */
269
+ public getResourceCount(type?: ManagedResource['type']): number {
270
+ if (!type) {
271
+ return this.resources.size;
272
+ }
273
+
274
+ return Array.from(this.resources.values())
275
+ .filter(resource => resource.type === type).length;
276
+ }
277
+
278
+ /**
279
+ * Check for memory leaks
280
+ */
281
+ public detectLeaks(): string[] {
282
+ const leaks: string[] = [];
283
+
284
+ // Check for orphaned weak references
285
+ this.weakRefs.forEach(weakRef => {
286
+ if (weakRef.deref() === undefined) {
287
+ // Element was garbage collected but we might still have resources
288
+ this.cleanupOrphanedResources();
289
+ }
290
+ });
291
+
292
+ // Check for excessive resource accumulation
293
+ const resourceCounts = new Map<string, number>();
294
+ this.resources.forEach(resource => {
295
+ const count = resourceCounts.get(resource.type) || 0;
296
+ resourceCounts.set(resource.type, count + 1);
297
+ });
298
+
299
+ resourceCounts.forEach((count, type) => {
300
+ const threshold = this.getThresholdForType(type);
301
+ if (count > threshold) {
302
+ leaks.push(`Excessive ${type} resources: ${count} (threshold: ${threshold})`);
303
+ }
304
+ });
305
+
306
+ this.metrics.leaksDetected = leaks.length;
307
+ return leaks;
308
+ }
309
+
310
+ /**
311
+ * Optimize garbage collection
312
+ */
313
+ public optimizeGC(): void {
314
+ if (!this.config.gcOptimization) return;
315
+
316
+ // Force cleanup of stale resources
317
+ this.cleanupStale();
318
+
319
+ // Clear weak references to collected objects
320
+ const validWeakRefs = new Set<WeakRef<any>>();
321
+ this.weakRefs.forEach(weakRef => {
322
+ if (weakRef.deref() !== undefined) {
323
+ validWeakRefs.add(weakRef);
324
+ }
325
+ });
326
+ this.weakRefs = validWeakRefs;
327
+
328
+ // Suggest garbage collection if available
329
+ if ('gc' in window && typeof window.gc === 'function') {
330
+ window.gc();
331
+ this.metrics.gcCollections++;
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Destroy memory management system
337
+ */
338
+ public destroy(): void {
339
+ this.stopAutoCleanup();
340
+ this.stopMemoryMonitoring();
341
+ this.cleanup();
342
+ this.weakRefs.clear();
343
+ }
344
+
345
+ /**
346
+ * Setup memory monitoring
347
+ */
348
+ private setupMemoryMonitoring(): void {
349
+ if (!this.config.performanceMonitoring) return;
350
+
351
+ // Monitor memory usage
352
+ if ('memory' in performance) {
353
+ setInterval(() => {
354
+ this.updateMemoryUsage();
355
+ this.checkMemoryThreshold();
356
+ }, 5000);
357
+ }
358
+
359
+ // Monitor performance entries
360
+ if (window.PerformanceObserver) {
361
+ try {
362
+ this.performanceObserver = new PerformanceObserver((list) => {
363
+ const entries = list.getEntries();
364
+ entries.forEach(entry => {
365
+ if (entry.entryType === 'measure' && entry.name.includes('proteus')) {
366
+ // Track ProteusJS-related performance measures
367
+ }
368
+ });
369
+ });
370
+
371
+ this.performanceObserver.observe({ entryTypes: ['measure', 'navigation'] });
372
+ } catch (error) {
373
+ console.warn('PerformanceObserver not fully supported:', error);
374
+ }
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Start automatic cleanup
380
+ */
381
+ private startAutoCleanup(): void {
382
+ if (!this.config.autoCleanup) return;
383
+
384
+ this.cleanupTimer = window.setInterval(() => {
385
+ this.cleanupStale();
386
+ this.cleanupOrphanedResources();
387
+ this.detectLeaks();
388
+
389
+ if (this.config.gcOptimization) {
390
+ this.optimizeGC();
391
+ }
392
+ }, this.config.cleanupInterval);
393
+ }
394
+
395
+ /**
396
+ * Stop automatic cleanup
397
+ */
398
+ private stopAutoCleanup(): void {
399
+ if (this.cleanupTimer) {
400
+ clearInterval(this.cleanupTimer);
401
+ this.cleanupTimer = null;
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Stop memory monitoring
407
+ */
408
+ private stopMemoryMonitoring(): void {
409
+ if (this.performanceObserver) {
410
+ this.performanceObserver.disconnect();
411
+ this.performanceObserver = null;
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Update memory usage metrics
417
+ */
418
+ private updateMemoryUsage(): void {
419
+ if ('memory' in performance) {
420
+ const memory = (performance as any).memory;
421
+ this.metrics.memoryUsage = memory.usedJSHeapSize || 0;
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Check memory threshold and trigger cleanup if needed
427
+ */
428
+ private checkMemoryThreshold(): void {
429
+ if (this.metrics.memoryUsage > this.config.memoryThreshold) {
430
+ console.warn('Memory threshold exceeded, triggering cleanup');
431
+ this.cleanupStale(60000); // Cleanup resources older than 1 minute
432
+ this.optimizeGC();
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Update metrics for resource operations
438
+ */
439
+ private updateMetrics(type: ManagedResource['type'], operation: 'register' | 'unregister'): void {
440
+ switch (type) {
441
+ case 'observer':
442
+ if (operation === 'register') {
443
+ this.metrics.totalObservers++;
444
+ this.metrics.activeObservers++;
445
+ } else {
446
+ this.metrics.activeObservers--;
447
+ }
448
+ break;
449
+ case 'listener':
450
+ if (operation === 'register') {
451
+ this.metrics.totalEventListeners++;
452
+ this.metrics.activeEventListeners++;
453
+ } else {
454
+ this.metrics.activeEventListeners--;
455
+ }
456
+ break;
457
+ }
458
+ }
459
+
460
+ /**
461
+ * Get threshold for resource type
462
+ */
463
+ private getThresholdForType(type: string): number {
464
+ const thresholds: Record<string, number> = {
465
+ observer: 100,
466
+ listener: 500,
467
+ timer: 50,
468
+ animation: 20,
469
+ cache: 1000
470
+ };
471
+
472
+ return thresholds[type] || 100;
473
+ }
474
+
475
+ /**
476
+ * Generate unique resource ID
477
+ */
478
+ private generateResourceId(): string {
479
+ return `mem-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
480
+ }
481
+
482
+ /**
483
+ * Create initial metrics
484
+ */
485
+ private createInitialMetrics(): MemoryMetrics {
486
+ return {
487
+ totalObservers: 0,
488
+ activeObservers: 0,
489
+ totalEventListeners: 0,
490
+ activeEventListeners: 0,
491
+ memoryUsage: 0,
492
+ gcCollections: 0,
493
+ leaksDetected: 0,
494
+ cleanupOperations: 0
495
+ };
496
+ }
497
+ }