@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,328 @@
1
+ /**
2
+ * BrowserPolyfills Test Suite
3
+ * Tests for cross-browser compatibility polyfills
4
+ */
5
+
6
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
7
+ import { BrowserPolyfills } from '../BrowserPolyfills';
8
+
9
+ describe('BrowserPolyfills', () => {
10
+ let polyfills: BrowserPolyfills;
11
+ let originalResizeObserver: any;
12
+ let originalIntersectionObserver: any;
13
+ let originalPerformance: any;
14
+ let originalCSS: any;
15
+
16
+ beforeEach(() => {
17
+ // Store original implementations
18
+ originalResizeObserver = (global as any).ResizeObserver;
19
+ originalIntersectionObserver = (global as any).IntersectionObserver;
20
+ originalPerformance = global.performance;
21
+ originalCSS = (global as any).CSS;
22
+
23
+ polyfills = BrowserPolyfills.getInstance();
24
+ });
25
+
26
+ afterEach(() => {
27
+ // Restore original implementations
28
+ (global as any).ResizeObserver = originalResizeObserver;
29
+ (global as any).IntersectionObserver = originalIntersectionObserver;
30
+ global.performance = originalPerformance;
31
+ (global as any).CSS = originalCSS;
32
+ });
33
+
34
+ describe('Singleton Pattern', () => {
35
+ it('should return the same instance', () => {
36
+ const instance1 = BrowserPolyfills.getInstance();
37
+ const instance2 = BrowserPolyfills.getInstance();
38
+
39
+ expect(instance1).toBe(instance2);
40
+ });
41
+ });
42
+
43
+ describe('Browser Support Detection', () => {
44
+ it('should detect supported features', () => {
45
+ const support = polyfills.checkBrowserSupport();
46
+
47
+ expect(support).toHaveProperty('supported');
48
+ expect(support).toHaveProperty('missing');
49
+ expect(support).toHaveProperty('warnings');
50
+ expect(Array.isArray(support.supported)).toBe(true);
51
+ expect(Array.isArray(support.missing)).toBe(true);
52
+ expect(Array.isArray(support.warnings)).toBe(true);
53
+ });
54
+
55
+ it('should detect missing ResizeObserver', () => {
56
+ delete (global as any).ResizeObserver;
57
+
58
+ const support = polyfills.checkBrowserSupport();
59
+
60
+ expect(support.missing).toContain('ResizeObserver');
61
+ });
62
+
63
+ it('should detect missing IntersectionObserver', () => {
64
+ delete (global as any).IntersectionObserver;
65
+
66
+ const support = polyfills.checkBrowserSupport();
67
+
68
+ expect(support.missing).toContain('IntersectionObserver');
69
+ });
70
+
71
+ it('should detect browser-specific warnings', () => {
72
+ // Mock IE user agent
73
+ Object.defineProperty(navigator, 'userAgent', {
74
+ value: 'Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko',
75
+ configurable: true
76
+ });
77
+
78
+ const support = polyfills.checkBrowserSupport();
79
+
80
+ expect(support.warnings.some(w => w.includes('Internet Explorer'))).toBe(true);
81
+ });
82
+ });
83
+
84
+ describe('ResizeObserver Polyfill', () => {
85
+ beforeEach(() => {
86
+ delete (global as any).ResizeObserver;
87
+ });
88
+
89
+ it('should load ResizeObserver polyfill when missing', async () => {
90
+ await polyfills.loadPolyfills({ resizeObserver: true });
91
+
92
+ expect(typeof (global as any).ResizeObserver).toBe('function');
93
+ expect(polyfills.getLoadedPolyfills()).toContain('ResizeObserver');
94
+ });
95
+
96
+ it('should create functional ResizeObserver polyfill', async () => {
97
+ await polyfills.loadPolyfills({ resizeObserver: true });
98
+
99
+ const callback = vi.fn();
100
+ const observer = new (global as any).ResizeObserver(callback);
101
+
102
+ expect(observer).toBeDefined();
103
+ expect(typeof observer.observe).toBe('function');
104
+ expect(typeof observer.unobserve).toBe('function');
105
+ expect(typeof observer.disconnect).toBe('function');
106
+ });
107
+
108
+ it('should not load polyfill when ResizeObserver exists', async () => {
109
+ (global as any).ResizeObserver = vi.fn();
110
+
111
+ await polyfills.loadPolyfills({ resizeObserver: true });
112
+
113
+ expect(polyfills.getLoadedPolyfills()).not.toContain('ResizeObserver');
114
+ });
115
+ });
116
+
117
+ describe('IntersectionObserver Polyfill', () => {
118
+ beforeEach(() => {
119
+ delete (global as any).IntersectionObserver;
120
+ });
121
+
122
+ it('should load IntersectionObserver polyfill when missing', async () => {
123
+ await polyfills.loadPolyfills({ intersectionObserver: true });
124
+
125
+ expect(typeof (global as any).IntersectionObserver).toBe('function');
126
+ expect(polyfills.getLoadedPolyfills()).toContain('IntersectionObserver');
127
+ });
128
+
129
+ it('should create functional IntersectionObserver polyfill', async () => {
130
+ await polyfills.loadPolyfills({ intersectionObserver: true });
131
+
132
+ const callback = vi.fn();
133
+ const observer = new (global as any).IntersectionObserver(callback);
134
+
135
+ expect(observer).toBeDefined();
136
+ expect(typeof observer.observe).toBe('function');
137
+ expect(typeof observer.unobserve).toBe('function');
138
+ expect(typeof observer.disconnect).toBe('function');
139
+ });
140
+ });
141
+
142
+ describe('Performance API Polyfill', () => {
143
+ it('should load performance polyfill when missing', async () => {
144
+ delete (global as any).performance;
145
+
146
+ await polyfills.loadPolyfills({ performance: true });
147
+
148
+ expect(typeof performance).toBe('object');
149
+ expect(typeof performance.now).toBe('function');
150
+ expect(polyfills.getLoadedPolyfills()).toContain('Performance');
151
+ });
152
+
153
+ it('should provide working performance.now', async () => {
154
+ delete (global as any).performance;
155
+
156
+ await polyfills.loadPolyfills({ performance: true });
157
+
158
+ const time1 = performance.now();
159
+ await new Promise(resolve => setTimeout(resolve, 10));
160
+ const time2 = performance.now();
161
+
162
+ expect(time2).toBeGreaterThan(time1);
163
+ });
164
+ });
165
+
166
+ describe('RequestAnimationFrame Polyfill', () => {
167
+ it('should load RAF polyfill when missing', async () => {
168
+ delete (global as any).requestAnimationFrame;
169
+ delete (global as any).cancelAnimationFrame;
170
+
171
+ await polyfills.loadPolyfills({ requestAnimationFrame: true });
172
+
173
+ expect(typeof requestAnimationFrame).toBe('function');
174
+ expect(typeof cancelAnimationFrame).toBe('function');
175
+ expect(polyfills.getLoadedPolyfills()).toContain('RequestAnimationFrame');
176
+ });
177
+
178
+ it('should provide working requestAnimationFrame', async () => {
179
+ delete (global as any).requestAnimationFrame;
180
+
181
+ await polyfills.loadPolyfills({ requestAnimationFrame: true });
182
+
183
+ const callback = vi.fn();
184
+ const id = requestAnimationFrame(callback);
185
+
186
+ expect(typeof id).toBe('number');
187
+
188
+ // Wait for callback
189
+ await new Promise(resolve => setTimeout(resolve, 20));
190
+
191
+ expect(callback).toHaveBeenCalled();
192
+ });
193
+ });
194
+
195
+ describe('CSS.supports Polyfill', () => {
196
+ it('should load CSS.supports polyfill when missing', async () => {
197
+ delete (global as any).CSS;
198
+
199
+ await polyfills.loadPolyfills({ cssSupports: true });
200
+
201
+ expect(typeof CSS).toBe('object');
202
+ expect(typeof CSS.supports).toBe('function');
203
+ expect(polyfills.getLoadedPolyfills()).toContain('CSS.supports');
204
+ });
205
+
206
+ it('should provide working CSS.supports', async () => {
207
+ delete (global as any).CSS;
208
+
209
+ await polyfills.loadPolyfills({ cssSupports: true });
210
+
211
+ // Test basic property support
212
+ const supportsColor = CSS.supports('color', 'red');
213
+ const supportsInvalid = CSS.supports('invalid-property', 'invalid-value');
214
+
215
+ expect(typeof supportsColor).toBe('boolean');
216
+ expect(typeof supportsInvalid).toBe('boolean');
217
+ });
218
+ });
219
+
220
+ describe('Element.classList Polyfill', () => {
221
+ it('should load classList polyfill when missing', async () => {
222
+ // Mock missing classList
223
+ const originalDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'classList');
224
+ delete (Element.prototype as any).classList;
225
+
226
+ await polyfills.loadPolyfills({ classList: true });
227
+
228
+ const element = document.createElement('div');
229
+ expect(element.classList).toBeDefined();
230
+ expect(typeof element.classList.add).toBe('function');
231
+ expect(polyfills.getLoadedPolyfills()).toContain('Element.classList');
232
+
233
+ // Restore original
234
+ if (originalDescriptor) {
235
+ Object.defineProperty(Element.prototype, 'classList', originalDescriptor);
236
+ }
237
+ });
238
+ });
239
+
240
+ describe('Element.closest Polyfill', () => {
241
+ it('should load closest polyfill when missing', async () => {
242
+ const originalClosest = Element.prototype.closest;
243
+ delete (Element.prototype as any).closest;
244
+
245
+ await polyfills.loadPolyfills({ closest: true });
246
+
247
+ const element = document.createElement('div');
248
+ expect(typeof element.closest).toBe('function');
249
+ expect(polyfills.getLoadedPolyfills()).toContain('Element.closest');
250
+
251
+ // Restore original
252
+ Element.prototype.closest = originalClosest;
253
+ });
254
+ });
255
+
256
+ describe('Auto Initialization', () => {
257
+ it('should auto-initialize based on browser support', async () => {
258
+ // Remove some features to trigger polyfills
259
+ delete (global as any).ResizeObserver;
260
+ delete (global as any).IntersectionObserver;
261
+
262
+ await BrowserPolyfills.autoInit();
263
+
264
+ expect(typeof (global as any).ResizeObserver).toBe('function');
265
+ expect(typeof (global as any).IntersectionObserver).toBe('function');
266
+ });
267
+
268
+ it('should not load unnecessary polyfills', async () => {
269
+ // Ensure features exist
270
+ (global as any).ResizeObserver = vi.fn();
271
+ (global as any).IntersectionObserver = vi.fn();
272
+
273
+ const polyfillsBefore = polyfills.getLoadedPolyfills().length;
274
+
275
+ await BrowserPolyfills.autoInit();
276
+
277
+ const polyfillsAfter = polyfills.getLoadedPolyfills().length;
278
+
279
+ // Should not have loaded additional polyfills
280
+ expect(polyfillsAfter).toBe(polyfillsBefore);
281
+ });
282
+ });
283
+
284
+ describe('Configuration', () => {
285
+ it('should respect polyfill configuration', async () => {
286
+ delete (global as any).ResizeObserver;
287
+ delete (global as any).IntersectionObserver;
288
+
289
+ await polyfills.loadPolyfills({
290
+ resizeObserver: true,
291
+ intersectionObserver: false
292
+ });
293
+
294
+ expect(typeof (global as any).ResizeObserver).toBe('function');
295
+ expect(typeof (global as any).IntersectionObserver).toBe('undefined');
296
+ });
297
+
298
+ it('should use default configuration when none provided', async () => {
299
+ delete (global as any).ResizeObserver;
300
+
301
+ await polyfills.loadPolyfills();
302
+
303
+ expect(typeof (global as any).ResizeObserver).toBe('function');
304
+ });
305
+ });
306
+
307
+ describe('Error Handling', () => {
308
+ it('should handle polyfill loading errors gracefully', async () => {
309
+ // This test ensures no errors are thrown during polyfill loading
310
+ expect(async () => {
311
+ await polyfills.loadPolyfills();
312
+ }).not.toThrow();
313
+ });
314
+
315
+ it('should handle missing DOM gracefully', async () => {
316
+ // Mock missing document
317
+ const originalDocument = global.document;
318
+ delete (global as any).document;
319
+
320
+ expect(async () => {
321
+ await polyfills.loadPolyfills();
322
+ }).not.toThrow();
323
+
324
+ // Restore document
325
+ global.document = originalDocument;
326
+ });
327
+ });
328
+ });
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Test setup file for Vitest
3
+ */
4
+
5
+ import { vi } from 'vitest';
6
+
7
+ // Mock ResizeObserver
8
+ global.ResizeObserver = vi.fn().mockImplementation(() => ({
9
+ observe: vi.fn(),
10
+ unobserve: vi.fn(),
11
+ disconnect: vi.fn()
12
+ }));
13
+
14
+ // Mock IntersectionObserver
15
+ global.IntersectionObserver = vi.fn().mockImplementation(() => ({
16
+ observe: vi.fn(),
17
+ unobserve: vi.fn(),
18
+ disconnect: vi.fn(),
19
+ root: null,
20
+ rootMargin: '',
21
+ thresholds: []
22
+ }));
23
+
24
+ // Mock requestAnimationFrame
25
+ global.requestAnimationFrame = vi.fn().mockImplementation((cb) => {
26
+ return setTimeout(cb, 16);
27
+ });
28
+
29
+ global.cancelAnimationFrame = vi.fn().mockImplementation((id) => {
30
+ clearTimeout(id);
31
+ });
32
+
33
+ // Mock CSS.supports
34
+ Object.defineProperty(global, 'CSS', {
35
+ value: {
36
+ supports: vi.fn().mockReturnValue(true)
37
+ },
38
+ writable: true
39
+ });
40
+
41
+ // Mock window.getComputedStyle
42
+ global.getComputedStyle = vi.fn().mockImplementation(() => ({
43
+ getPropertyValue: vi.fn().mockReturnValue(''),
44
+ setProperty: vi.fn(),
45
+ removeProperty: vi.fn()
46
+ }));
47
+
48
+ // Mock Element.getBoundingClientRect
49
+ Element.prototype.getBoundingClientRect = vi.fn().mockImplementation(() => ({
50
+ width: 100,
51
+ height: 100,
52
+ top: 0,
53
+ left: 0,
54
+ bottom: 100,
55
+ right: 100,
56
+ x: 0,
57
+ y: 0,
58
+ toJSON: vi.fn()
59
+ }));
60
+
61
+ // Mock window.matchMedia
62
+ Object.defineProperty(window, 'matchMedia', {
63
+ writable: true,
64
+ value: vi.fn().mockImplementation((query: string) => ({
65
+ matches: false,
66
+ media: query,
67
+ onchange: null,
68
+ addListener: vi.fn(), // deprecated
69
+ removeListener: vi.fn(), // deprecated
70
+ addEventListener: vi.fn(),
71
+ removeEventListener: vi.fn(),
72
+ dispatchEvent: vi.fn()
73
+ }))
74
+ });
75
+
76
+ // Mock performance.memory for memory monitoring tests
77
+ Object.defineProperty(performance, 'memory', {
78
+ writable: true,
79
+ value: {
80
+ usedJSHeapSize: 10000000,
81
+ totalJSHeapSize: 20000000,
82
+ jsHeapSizeLimit: 100000000
83
+ }
84
+ });
85
+
86
+ // Mock performance timing methods
87
+ Object.defineProperty(performance, 'mark', {
88
+ writable: true,
89
+ value: vi.fn()
90
+ });
91
+
92
+ Object.defineProperty(performance, 'measure', {
93
+ writable: true,
94
+ value: vi.fn()
95
+ });
96
+
97
+ Object.defineProperty(performance, 'getEntriesByType', {
98
+ writable: true,
99
+ value: vi.fn().mockReturnValue([])
100
+ });
101
+
102
+ Object.defineProperty(performance, 'getEntriesByName', {
103
+ writable: true,
104
+ value: vi.fn().mockReturnValue([])
105
+ });
106
+
107
+ // Mock console methods in test environment
108
+ if (process.env['NODE_ENV'] === 'test') {
109
+ global.console = {
110
+ ...console,
111
+ warn: vi.fn(),
112
+ error: vi.fn(),
113
+ log: vi.fn()
114
+ };
115
+ }