@coherent.js/core 1.0.0-beta.2

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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/dist/coherent.d.ts +472 -0
  4. package/dist/coherent.d.ts.map +1 -0
  5. package/dist/coherent.js +590 -0
  6. package/dist/coherent.js.map +1 -0
  7. package/dist/components/component-system.d.ts +1138 -0
  8. package/dist/components/component-system.d.ts.map +1 -0
  9. package/dist/components/component-system.js +2220 -0
  10. package/dist/components/component-system.js.map +1 -0
  11. package/dist/components/lifecycle.d.ts +212 -0
  12. package/dist/components/lifecycle.d.ts.map +1 -0
  13. package/dist/components/lifecycle.js +525 -0
  14. package/dist/components/lifecycle.js.map +1 -0
  15. package/dist/core/html-utils.d.ts +14 -0
  16. package/dist/core/html-utils.d.ts.map +1 -0
  17. package/dist/core/html-utils.js +166 -0
  18. package/dist/core/html-utils.js.map +1 -0
  19. package/dist/core/object-factory.d.ts +38 -0
  20. package/dist/core/object-factory.d.ts.map +1 -0
  21. package/dist/core/object-factory.js +63 -0
  22. package/dist/core/object-factory.js.map +1 -0
  23. package/dist/core/object-utils.d.ts +77 -0
  24. package/dist/core/object-utils.d.ts.map +1 -0
  25. package/dist/core/object-utils.js +502 -0
  26. package/dist/core/object-utils.js.map +1 -0
  27. package/dist/dev/dev-tools.d.ts +194 -0
  28. package/dist/dev/dev-tools.d.ts.map +1 -0
  29. package/dist/dev/dev-tools.js +846 -0
  30. package/dist/dev/dev-tools.js.map +1 -0
  31. package/dist/forms/validation.d.ts +271 -0
  32. package/dist/forms/validation.d.ts.map +1 -0
  33. package/dist/forms/validation.js +573 -0
  34. package/dist/forms/validation.js.map +1 -0
  35. package/dist/index.cjs +5281 -0
  36. package/dist/index.cjs.map +7 -0
  37. package/dist/index.js +5204 -0
  38. package/dist/index.js.map +7 -0
  39. package/dist/performance/bundle-optimizer.d.ts +95 -0
  40. package/dist/performance/bundle-optimizer.d.ts.map +1 -0
  41. package/dist/performance/bundle-optimizer.js +192 -0
  42. package/dist/performance/bundle-optimizer.js.map +1 -0
  43. package/dist/performance/cache-manager.d.ts +107 -0
  44. package/dist/performance/cache-manager.d.ts.map +1 -0
  45. package/dist/performance/cache-manager.js +314 -0
  46. package/dist/performance/cache-manager.js.map +1 -0
  47. package/dist/performance/component-cache.d.ts +120 -0
  48. package/dist/performance/component-cache.d.ts.map +1 -0
  49. package/dist/performance/component-cache.js +364 -0
  50. package/dist/performance/component-cache.js.map +1 -0
  51. package/dist/performance/monitor.d.ts +189 -0
  52. package/dist/performance/monitor.d.ts.map +1 -0
  53. package/dist/performance/monitor.js +347 -0
  54. package/dist/performance/monitor.js.map +1 -0
  55. package/dist/rendering/base-renderer.d.ts +140 -0
  56. package/dist/rendering/base-renderer.d.ts.map +1 -0
  57. package/dist/rendering/base-renderer.js +409 -0
  58. package/dist/rendering/base-renderer.js.map +1 -0
  59. package/dist/rendering/css-manager.d.ts +73 -0
  60. package/dist/rendering/css-manager.d.ts.map +1 -0
  61. package/dist/rendering/css-manager.js +176 -0
  62. package/dist/rendering/css-manager.js.map +1 -0
  63. package/dist/rendering/dom-renderer.d.ts +62 -0
  64. package/dist/rendering/dom-renderer.d.ts.map +1 -0
  65. package/dist/rendering/dom-renderer.js +252 -0
  66. package/dist/rendering/dom-renderer.js.map +1 -0
  67. package/dist/rendering/html-renderer.d.ts +67 -0
  68. package/dist/rendering/html-renderer.d.ts.map +1 -0
  69. package/dist/rendering/html-renderer.js +444 -0
  70. package/dist/rendering/html-renderer.js.map +1 -0
  71. package/dist/rendering/renderer-config.d.ts +282 -0
  72. package/dist/rendering/renderer-config.d.ts.map +1 -0
  73. package/dist/rendering/renderer-config.js +144 -0
  74. package/dist/rendering/renderer-config.js.map +1 -0
  75. package/dist/rendering/streaming-renderer.d.ts +117 -0
  76. package/dist/rendering/streaming-renderer.d.ts.map +1 -0
  77. package/dist/rendering/streaming-renderer.js +326 -0
  78. package/dist/rendering/streaming-renderer.js.map +1 -0
  79. package/dist/rendering/vdom-diff.d.ts +47 -0
  80. package/dist/rendering/vdom-diff.d.ts.map +1 -0
  81. package/dist/rendering/vdom-diff.js +416 -0
  82. package/dist/rendering/vdom-diff.js.map +1 -0
  83. package/dist/routing/router.d.ts +241 -0
  84. package/dist/routing/router.d.ts.map +1 -0
  85. package/dist/routing/router.js +648 -0
  86. package/dist/routing/router.js.map +1 -0
  87. package/dist/state/reactive-state.d.ts +166 -0
  88. package/dist/state/reactive-state.d.ts.map +1 -0
  89. package/dist/state/reactive-state.js +546 -0
  90. package/dist/state/reactive-state.js.map +1 -0
  91. package/dist/state/state-manager.d.ts +45 -0
  92. package/dist/state/state-manager.d.ts.map +1 -0
  93. package/dist/state/state-manager.js +151 -0
  94. package/dist/state/state-manager.js.map +1 -0
  95. package/dist/types/constants.d.ts +8 -0
  96. package/dist/types/constants.d.ts.map +1 -0
  97. package/dist/types/constants.js +36 -0
  98. package/dist/types/constants.js.map +1 -0
  99. package/dist/utils/dependency-utils.d.ts +43 -0
  100. package/dist/utils/dependency-utils.d.ts.map +1 -0
  101. package/dist/utils/dependency-utils.js +105 -0
  102. package/dist/utils/dependency-utils.js.map +1 -0
  103. package/dist/utils/error-handler.d.ts +148 -0
  104. package/dist/utils/error-handler.d.ts.map +1 -0
  105. package/dist/utils/error-handler.js +468 -0
  106. package/dist/utils/error-handler.js.map +1 -0
  107. package/dist/utils/normalization.d.ts +3 -0
  108. package/dist/utils/normalization.d.ts.map +1 -0
  109. package/dist/utils/normalization.js +24 -0
  110. package/dist/utils/normalization.js.map +1 -0
  111. package/dist/utils/validation.d.ts +10 -0
  112. package/dist/utils/validation.d.ts.map +1 -0
  113. package/dist/utils/validation.js +32 -0
  114. package/dist/utils/validation.js.map +1 -0
  115. package/package.json +44 -0
  116. package/types/index.d.ts +734 -0
@@ -0,0 +1,846 @@
1
+ /**
2
+ * Development Tools for Coherent.js
3
+ * Provides debugging, profiling, and development utilities
4
+ * Only active in development environment for zero production overhead
5
+ */
6
+ import { performanceMonitor } from '../performance/monitor.js';
7
+ import { validateComponent, isCoherentObject } from '../core/object-utils.js';
8
+ /**
9
+ * Main DevTools class
10
+ */
11
+ export class DevTools {
12
+ constructor(coherentInstance) {
13
+ this.coherent = coherentInstance;
14
+ this.isEnabled = this.shouldEnable();
15
+ this.renderHistory = [];
16
+ this.componentRegistry = new Map();
17
+ this.warnings = [];
18
+ this.errors = [];
19
+ this.hotReloadEnabled = false;
20
+ if (this.isEnabled) {
21
+ this.initialize();
22
+ }
23
+ }
24
+ /**
25
+ * Check if dev tools should be enabled
26
+ */
27
+ shouldEnable() {
28
+ // Only enable in development
29
+ if (typeof process !== 'undefined') {
30
+ return process.env.NODE_ENV === 'development';
31
+ }
32
+ // Browser development detection
33
+ if (typeof window !== 'undefined') {
34
+ return window.location.hostname === 'localhost' ||
35
+ window.location.hostname === '127.0.0.1' ||
36
+ window.location.search.includes('dev=true');
37
+ }
38
+ return false;
39
+ }
40
+ /**
41
+ * Initialize dev tools
42
+ */
43
+ initialize() {
44
+ console.log('🛠️ Coherent.js Dev Tools Enabled');
45
+ this.setupGlobalHelpers();
46
+ this.setupRenderInterception();
47
+ this.setupErrorHandling();
48
+ this.setupHotReload();
49
+ this.setupComponentInspector();
50
+ // Browser-specific setup
51
+ if (typeof window !== 'undefined') {
52
+ this.setupBrowserDevTools();
53
+ }
54
+ // Node.js specific setup
55
+ if (typeof process !== 'undefined') {
56
+ this.setupNodeDevTools();
57
+ }
58
+ }
59
+ /**
60
+ * Set up global helper functions
61
+ */
62
+ setupGlobalHelpers() {
63
+ const helpers = {
64
+ // Inspect any component
65
+ $inspect: (component) => this.inspectComponent(component),
66
+ // Get render history
67
+ $history: () => this.renderHistory,
68
+ // Get performance stats
69
+ $perf: () => this.getPerformanceInsights(),
70
+ // Validate component structure
71
+ $validate: (component) => this.validateComponent(component),
72
+ // Get component registry
73
+ $registry: () => Array.from(this.componentRegistry.entries()),
74
+ // Clear dev data
75
+ $clear: () => this.clearDevData(),
76
+ // Enable/disable features
77
+ $toggle: (feature) => this.toggleFeature(feature),
78
+ // Get warnings and errors
79
+ $issues: () => ({ warnings: this.warnings, errors: this.errors })
80
+ };
81
+ // Expose helpers globally
82
+ if (typeof window !== 'undefined') {
83
+ Object.assign(window, helpers);
84
+ }
85
+ else if (typeof global !== 'undefined') {
86
+ Object.assign(global, helpers);
87
+ }
88
+ }
89
+ /**
90
+ * Intercept render calls for debugging
91
+ */
92
+ setupRenderInterception() {
93
+ const originalRender = this.coherent.render;
94
+ this.coherent.render = (component, context = {}, options = {}) => {
95
+ const renderStart = performance.now();
96
+ const renderId = this.generateRenderId();
97
+ try {
98
+ // Pre-render validation and logging
99
+ this.preRenderAnalysis(component, context, renderId);
100
+ // Actual render
101
+ const result = originalRender.call(this.coherent, component, context, {
102
+ ...options,
103
+ _devRenderId: renderId
104
+ });
105
+ // Post-render analysis
106
+ const renderTime = performance.now() - renderStart;
107
+ this.postRenderAnalysis(component, result, renderTime, renderId);
108
+ return result;
109
+ }
110
+ catch (error) {
111
+ this.handleRenderError(error, component, context, renderId);
112
+ throw error;
113
+ }
114
+ };
115
+ }
116
+ /**
117
+ * Pre-render analysis and validation
118
+ */
119
+ preRenderAnalysis(component, context, renderId) {
120
+ // Component structure validation
121
+ const validation = this.deepValidateComponent(component);
122
+ if (!validation.isValid) {
123
+ this.warnings.push({
124
+ type: 'validation',
125
+ message: validation.message,
126
+ component: this.serializeComponent(component),
127
+ renderId,
128
+ timestamp: Date.now()
129
+ });
130
+ }
131
+ // Performance warnings
132
+ const complexity = this.analyzeComplexity(component);
133
+ if (complexity > 1000) {
134
+ this.warnings.push({
135
+ type: 'performance',
136
+ message: `High complexity component detected (${complexity} nodes)`,
137
+ renderId,
138
+ timestamp: Date.now()
139
+ });
140
+ }
141
+ // Context analysis
142
+ this.analyzeContext(context, renderId);
143
+ }
144
+ /**
145
+ * Post-render analysis
146
+ */
147
+ postRenderAnalysis(component, result, renderTime, renderId) {
148
+ // Store render in history
149
+ const renderRecord = {
150
+ id: renderId,
151
+ timestamp: Date.now(),
152
+ component: this.serializeComponent(component),
153
+ renderTime,
154
+ outputSize: result.length,
155
+ complexity: this.analyzeComplexity(component)
156
+ };
157
+ this.renderHistory.push(renderRecord);
158
+ // Keep only last 50 renders
159
+ if (this.renderHistory.length > 50) {
160
+ this.renderHistory.shift();
161
+ }
162
+ // Performance analysis
163
+ if (renderTime > 10) {
164
+ this.warnings.push({
165
+ type: 'performance',
166
+ message: `Slow render detected: ${renderTime.toFixed(2)}ms`,
167
+ renderId,
168
+ timestamp: Date.now()
169
+ });
170
+ }
171
+ // Log render in development
172
+ if (renderTime > 1) {
173
+ console.log(`🔄 Render ${renderId}: ${renderTime.toFixed(2)}ms`);
174
+ }
175
+ }
176
+ /**
177
+ * Deep component validation
178
+ */
179
+ deepValidateComponent(component, path = 'root', depth = 0) {
180
+ if (depth > 100) {
181
+ return {
182
+ isValid: false,
183
+ message: `Component nesting too deep at ${path}`
184
+ };
185
+ }
186
+ // Basic validation
187
+ try {
188
+ validateComponent(component);
189
+ }
190
+ catch (error) {
191
+ return {
192
+ isValid: false,
193
+ message: `Invalid component at ${path}: ${error.message}`
194
+ };
195
+ }
196
+ // Recursive validation for objects and arrays
197
+ if (Array.isArray(component)) {
198
+ for (let i = 0; i < component.length; i++) {
199
+ const childValidation = this.deepValidateComponent(component[i], `${path}[${i}]`, depth + 1);
200
+ if (!childValidation.isValid) {
201
+ return childValidation;
202
+ }
203
+ }
204
+ }
205
+ else if (isCoherentObject(component)) {
206
+ for (const [tag, props] of Object.entries(component)) {
207
+ if (props && typeof props === 'object' && props.children) {
208
+ const childValidation = this.deepValidateComponent(props.children, `${path}.${tag}.children`, depth + 1);
209
+ if (!childValidation.isValid) {
210
+ return childValidation;
211
+ }
212
+ }
213
+ }
214
+ }
215
+ return { isValid: true };
216
+ }
217
+ /**
218
+ * Analyze component complexity
219
+ */
220
+ analyzeComplexity(component, depth = 0) {
221
+ if (depth > 100)
222
+ return 1000; // Prevent infinite recursion
223
+ if (typeof component === 'string' || typeof component === 'number') {
224
+ return 1;
225
+ }
226
+ if (Array.isArray(component)) {
227
+ return component.reduce((sum, child) => sum + this.analyzeComplexity(child, depth + 1), 0);
228
+ }
229
+ if (isCoherentObject(component)) {
230
+ let complexity = 1;
231
+ for (const [, props] of Object.entries(component)) {
232
+ if (props && typeof props === 'object') {
233
+ if (props.children) {
234
+ complexity += this.analyzeComplexity(props.children, depth + 1);
235
+ }
236
+ if (typeof props.text === 'function') {
237
+ complexity += 2; // Functions add complexity
238
+ }
239
+ }
240
+ }
241
+ return complexity;
242
+ }
243
+ return 1;
244
+ }
245
+ /**
246
+ * Context analysis
247
+ */
248
+ analyzeContext(context, renderId) {
249
+ // Large context warning
250
+ const contextSize = JSON.stringify(_context).length;
251
+ if (contextSize > 10000) {
252
+ this.warnings.push({
253
+ type: 'context',
254
+ message: `Large context object: ${contextSize} characters`,
255
+ renderId,
256
+ timestamp: Date.now()
257
+ });
258
+ }
259
+ // Circular reference check
260
+ try {
261
+ JSON.stringify(_context);
262
+ }
263
+ catch (error) {
264
+ if (error.message.includes('circular')) {
265
+ this.warnings.push({
266
+ type: 'context',
267
+ message: 'Circular reference detected in context',
268
+ renderId,
269
+ timestamp: Date.now()
270
+ });
271
+ }
272
+ }
273
+ }
274
+ /**
275
+ * Component inspector
276
+ */
277
+ inspectComponent(component) {
278
+ return {
279
+ type: this.getComponentType(component),
280
+ complexity: this.analyzeComplexity(component),
281
+ validation: this.deepValidateComponent(component),
282
+ structure: this.visualizeStructure(component),
283
+ serialized: this.serializeComponent(component),
284
+ recommendations: this.getOptimizationRecommendations(component)
285
+ };
286
+ }
287
+ /**
288
+ * Get component type
289
+ */
290
+ getComponentType(component) {
291
+ if (typeof component === 'string')
292
+ return 'text';
293
+ if (typeof component === 'function')
294
+ return 'function';
295
+ if (Array.isArray(component))
296
+ return 'array';
297
+ if (isCoherentObject(component))
298
+ return 'element';
299
+ return 'unknown';
300
+ }
301
+ /**
302
+ * Visualize component structure
303
+ */
304
+ visualizeStructure(component, depth = 0, maxDepth = 5) {
305
+ if (depth > maxDepth)
306
+ return '...';
307
+ const indent = ' '.repeat(depth);
308
+ if (typeof component === 'string') {
309
+ return `${indent}"${component.substring(0, 20)}${component.length > 20 ? '...' : ''}"`;
310
+ }
311
+ if (Array.isArray(component)) {
312
+ const items = component.slice(0, 3).map(child => this.visualizeStructure(child, depth + 1, maxDepth));
313
+ const more = component.length > 3 ? `${indent} ...${component.length - 3} more` : '';
314
+ return `${indent}[\n${items.join('\n')}${more ? `\n${more}` : ''}\n${indent}]`;
315
+ }
316
+ if (isCoherentObject(component)) {
317
+ const entries = Object.entries(component).slice(0, 3);
318
+ const elements = entries.map(([tag, props]) => {
319
+ let result = `${indent}<${tag}`;
320
+ if (props && props.children) {
321
+ result += `>\n${this.visualizeStructure(props.children, depth + 1, maxDepth)}\n${indent}</${tag}>`;
322
+ }
323
+ else if (props && props.text) {
324
+ result += `>${props.text}</${tag}>`;
325
+ }
326
+ else {
327
+ result += ' />';
328
+ }
329
+ return result;
330
+ });
331
+ return elements.join('\n');
332
+ }
333
+ return `${indent}${typeof component}`;
334
+ }
335
+ /**
336
+ * Get optimization recommendations
337
+ */
338
+ getOptimizationRecommendations(component) {
339
+ const recommendations = [];
340
+ const complexity = this.analyzeComplexity(component);
341
+ if (complexity > 500) {
342
+ recommendations.push({
343
+ type: 'complexity',
344
+ message: 'Consider breaking down this component into smaller parts',
345
+ priority: 'high'
346
+ });
347
+ }
348
+ // Check for repeated patterns
349
+ const serialized = JSON.stringify(component);
350
+ const patterns = this.findRepeatedPatterns(serialized);
351
+ if (patterns.length > 0) {
352
+ recommendations.push({
353
+ type: 'caching',
354
+ message: 'Consider extracting repeated patterns into cached components',
355
+ priority: 'medium',
356
+ patterns: patterns.slice(0, 3)
357
+ });
358
+ }
359
+ return recommendations;
360
+ }
361
+ /**
362
+ * Find repeated patterns in component
363
+ */
364
+ findRepeatedPatterns(serialized) {
365
+ const patterns = [];
366
+ const minPatternLength = 20;
367
+ for (let i = 0; i < serialized.length - minPatternLength; i++) {
368
+ for (let len = minPatternLength; len <= 100 && i + len < serialized.length; len++) {
369
+ const pattern = serialized.substring(i, i + len);
370
+ const occurrences = (serialized.match(new RegExp(this.escapeRegex(pattern), 'g')) || []).length;
371
+ if (occurrences > 2) {
372
+ patterns.push({ pattern: `${pattern.substring(0, 50)}...`, occurrences });
373
+ break; // Found a pattern starting at this position
374
+ }
375
+ }
376
+ }
377
+ return patterns.sort((a, b) => b.occurrences - a.occurrences);
378
+ }
379
+ /**
380
+ * Escape regex special characters
381
+ */
382
+ escapeRegex(string) {
383
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
384
+ }
385
+ /**
386
+ * Setup error handling
387
+ */
388
+ setupErrorHandling() {
389
+ // Global error handler
390
+ const originalConsoleError = console.error;
391
+ console.error = (...args) => {
392
+ // Log to dev tools
393
+ this.errors.push({
394
+ type: 'console',
395
+ message: args.join(' '),
396
+ timestamp: Date.now(),
397
+ stack: new Error().stack
398
+ });
399
+ // Call original
400
+ originalConsoleError.apply(console, args);
401
+ };
402
+ // Unhandled rejection handler (Node.js)
403
+ if (typeof process !== 'undefined') {
404
+ process.on('unhandledRejection', (reason, promise) => {
405
+ this.errors.push({
406
+ type: 'unhandled-rejection',
407
+ message: reason.toString(),
408
+ promise: promise.toString(),
409
+ timestamp: Date.now()
410
+ });
411
+ });
412
+ }
413
+ // Browser error handler
414
+ if (typeof window !== 'undefined') {
415
+ window.addEventListener('error', (event) => {
416
+ this.errors.push({
417
+ type: 'browser-error',
418
+ message: event.message,
419
+ filename: event.filename,
420
+ lineno: event.lineno,
421
+ colno: event.colno,
422
+ timestamp: Date.now()
423
+ });
424
+ });
425
+ }
426
+ }
427
+ /**
428
+ * Handle render errors specifically
429
+ */
430
+ handleRenderError(error, component, context, renderId) {
431
+ this.errors.push({
432
+ type: 'render-error',
433
+ message: error.message,
434
+ stack: error.stack,
435
+ component: this.serializeComponent(component),
436
+ context: Object.keys(_context),
437
+ renderId,
438
+ timestamp: Date.now()
439
+ });
440
+ console.error(`🚨 Render Error in ${renderId}:`, error.message);
441
+ console.error('Component:', this.serializeComponent(component));
442
+ }
443
+ /**
444
+ * Setup hot reload capability
445
+ */
446
+ setupHotReload() {
447
+ if (typeof window !== 'undefined' && 'WebSocket' in window) {
448
+ // Browser hot reload
449
+ this.setupBrowserHotReload();
450
+ }
451
+ else if (typeof require !== 'undefined') {
452
+ // Node.js file watching
453
+ this.setupNodeHotReload();
454
+ }
455
+ }
456
+ /**
457
+ * Browser hot reload setup
458
+ */
459
+ setupBrowserHotReload() {
460
+ // Connect to development server WebSocket
461
+ try {
462
+ const ws = new WebSocket('ws://localhost:3001/coherent-dev');
463
+ ws.onmessage = (event) => {
464
+ const data = JSON.parse(event.data);
465
+ if (data.type === 'component-updated') {
466
+ console.log('🔄 Component updated:', data.componentName);
467
+ this.handleComponentUpdate(data);
468
+ }
469
+ else if (data.type === 'full-reload') {
470
+ window.location.reload();
471
+ }
472
+ };
473
+ ws.onopen = () => {
474
+ console.log('🔗 Connected to Coherent dev server');
475
+ this.hotReloadEnabled = true;
476
+ };
477
+ ws.onclose = () => {
478
+ console.log('🔌 Disconnected from dev server');
479
+ this.hotReloadEnabled = false;
480
+ };
481
+ }
482
+ catch {
483
+ // Dev server not available
484
+ }
485
+ }
486
+ /**
487
+ * Node.js hot reload setup
488
+ */
489
+ setupNodeHotReload() {
490
+ // File system watching for component changes
491
+ try {
492
+ const fs = require('fs');
493
+ const path = require('path');
494
+ const watchDir = path.join(process.cwd(), 'src');
495
+ fs.watch(watchDir, { recursive: true }, (eventType, filename) => {
496
+ if (filename && filename.endsWith('.js')) {
497
+ console.log(`🔄 File changed: ${filename}`);
498
+ this.handleFileChange(filename, eventType);
499
+ }
500
+ });
501
+ this.hotReloadEnabled = true;
502
+ }
503
+ catch {
504
+ // File watching not available
505
+ }
506
+ }
507
+ /**
508
+ * Handle component updates
509
+ */
510
+ handleComponentUpdate(updateData) {
511
+ // Clear related caches
512
+ if (this.coherent.cache) {
513
+ this.coherent.cache.invalidatePattern(updateData.componentName);
514
+ }
515
+ // Update component registry
516
+ this.componentRegistry.set(updateData.componentName, {
517
+ ...updateData,
518
+ lastUpdated: Date.now()
519
+ });
520
+ // Trigger re-render if needed
521
+ if (typeof window !== 'undefined' && window.location.search.includes('auto-reload=true')) {
522
+ window.location.reload();
523
+ }
524
+ }
525
+ /**
526
+ * Handle file changes
527
+ */
528
+ handleFileChange(filename, eventType) {
529
+ // Clear require cache for the changed file
530
+ if (typeof require !== 'undefined' && require.cache) {
531
+ const fullPath = require.resolve(path.resolve(filename));
532
+ delete require.cache[fullPath];
533
+ }
534
+ console.log(`📝 ${eventType}: ${filename}`);
535
+ }
536
+ /**
537
+ * Setup browser-specific dev tools
538
+ */
539
+ setupBrowserDevTools() {
540
+ // Add dev tools panel to page
541
+ this.createDevPanel();
542
+ // Add keyboard shortcuts
543
+ document.addEventListener('keydown', (e) => {
544
+ // Ctrl+Shift+C = Toggle dev panel
545
+ if (e.ctrlKey && e.shiftKey && e.code === 'KeyC') {
546
+ this.toggleDevPanel();
547
+ e.preventDefault();
548
+ }
549
+ // Ctrl+Shift+P = Performance report
550
+ if (e.ctrlKey && e.shiftKey && e.code === 'KeyP') {
551
+ console.table(this.getPerformanceInsights());
552
+ e.preventDefault();
553
+ }
554
+ });
555
+ }
556
+ /**
557
+ * Create development panel in browser
558
+ */
559
+ createDevPanel() {
560
+ // Create floating dev panel
561
+ const panel = document.createElement('div');
562
+ panel.id = 'coherent-dev-panel';
563
+ panel.style.cssText = `
564
+ position: fixed;
565
+ top: 10px;
566
+ right: 10px;
567
+ width: 300px;
568
+ background: #1a1a1a;
569
+ color: #fff;
570
+ font-family: monospace;
571
+ font-size: 12px;
572
+ border-radius: 8px;
573
+ box-shadow: 0 4px 20px rgba(0,0,0,0.5);
574
+ z-index: 999999;
575
+ display: none;
576
+ max-height: 80vh;
577
+ overflow-y: auto;
578
+ `;
579
+ document.body.appendChild(panel);
580
+ this.devPanel = panel;
581
+ this.updateDevPanel();
582
+ }
583
+ /**
584
+ * Toggle dev panel visibility
585
+ */
586
+ toggleDevPanel() {
587
+ if (this.devPanel) {
588
+ const isVisible = this.devPanel.style.display === 'block';
589
+ this.devPanel.style.display = isVisible ? 'none' : 'block';
590
+ if (!isVisible) {
591
+ this.updateDevPanel();
592
+ }
593
+ }
594
+ }
595
+ /**
596
+ * Update dev panel content
597
+ */
598
+ updateDevPanel() {
599
+ if (!this.devPanel)
600
+ return;
601
+ const stats = this.getPerformanceInsights();
602
+ const recentRenders = this.renderHistory.slice(-5);
603
+ const recentWarnings = this.warnings.slice(-3);
604
+ this.devPanel.innerHTML = `
605
+ <div style="padding: 15px; border-bottom: 1px solid #333;">
606
+ <strong>🛠️ Coherent.js Dev Tools</strong>
607
+ <button onclick="this.parentElement.parentElement.style.display='none'"
608
+ style="float: right; background: none; border: none; color: #fff; cursor: pointer;">×</button>
609
+ </div>
610
+
611
+ <div style="padding: 10px;">
612
+ <h4 style="margin: 0 0 10px 0; color: #4CAF50;">Performance</h4>
613
+ <div style="font-size: 11px;">
614
+ <div>Avg Render: ${stats.averageRenderTime || 0}ms</div>
615
+ <div>Cache Hit Rate: ${((stats.cacheHits || 0) / Math.max(stats.totalRenders || 1, 1) * 100).toFixed(1)}%</div>
616
+ <div>Memory Usage: ${(performance.memory?.usedJSHeapSize / 1024 / 1024 || 0).toFixed(1)}MB</div>
617
+ </div>
618
+ </div>
619
+
620
+ <div style="padding: 10px;">
621
+ <h4 style="margin: 0 0 10px 0; color: #2196F3;">Recent Renders</h4>
622
+ ${recentRenders.map(r => `
623
+ <div style="font-size: 10px; margin-bottom: 5px; padding: 3px; background: #333; border-radius: 3px;">
624
+ ${r.id}: ${r.renderTime.toFixed(1)}ms (${r.complexity} nodes)
625
+ </div>
626
+ `).join('')}
627
+ </div>
628
+
629
+ ${recentWarnings.length > 0 ? `
630
+ <div style="padding: 10px;">
631
+ <h4 style="margin: 0 0 10px 0; color: #FF9800;">Warnings</h4>
632
+ ${recentWarnings.map(w => `
633
+ <div style="font-size: 10px; margin-bottom: 5px; padding: 3px; background: #4a2c0a; border-radius: 3px; color: #FFB74D;">
634
+ ${w.type}: ${w.message}
635
+ </div>
636
+ `).join('')}
637
+ </div>
638
+ ` : ''}
639
+
640
+ <div style="padding: 10px; font-size: 10px; color: #888;">
641
+ Press Ctrl+Shift+P for performance details
642
+ </div>
643
+ `;
644
+ }
645
+ /**
646
+ * Setup Node.js specific dev tools
647
+ */
648
+ setupNodeDevTools() {
649
+ // Add process event listeners
650
+ process.on('SIGINT', () => {
651
+ this.printDevSummary();
652
+ process.exit();
653
+ });
654
+ }
655
+ /**
656
+ * Print development summary
657
+ */
658
+ printDevSummary() {
659
+ console.log('\n🛠️ Coherent.js Development Summary');
660
+ console.log('=================================');
661
+ console.log(`Total Renders: ${this.renderHistory.length}`);
662
+ console.log(`Total Warnings: ${this.warnings.length}`);
663
+ console.log(`Total Errors: ${this.errors.length}`);
664
+ if (this.renderHistory.length > 0) {
665
+ const avgTime = this.renderHistory.reduce((sum, r) => sum + r.renderTime, 0) / this.renderHistory.length;
666
+ console.log(`Average Render Time: ${avgTime.toFixed(2)}ms`);
667
+ }
668
+ console.log('=================================\n');
669
+ }
670
+ /**
671
+ * Get performance insights
672
+ */
673
+ getPerformanceInsights() {
674
+ const insights = {
675
+ totalRenders: this.renderHistory.length,
676
+ averageRenderTime: 0,
677
+ slowestRender: null,
678
+ fastestRender: null,
679
+ cacheHits: 0,
680
+ totalWarnings: this.warnings.length,
681
+ totalErrors: this.errors.length
682
+ };
683
+ if (this.renderHistory.length > 0) {
684
+ const times = this.renderHistory.map(r => r.renderTime);
685
+ insights.averageRenderTime = times.reduce((a, b) => a + b, 0) / times.length;
686
+ insights.slowestRender = Math.max(...times);
687
+ insights.fastestRender = Math.min(...times);
688
+ }
689
+ // Get cache stats if available
690
+ if (this.coherent.cache && this.coherent.cache.getStats) {
691
+ const cacheStats = this.coherent.cache.getStats();
692
+ insights.cacheHits = cacheStats.hits;
693
+ insights.cacheHitRate = cacheStats.hitRate;
694
+ }
695
+ // Add performance monitor data if available
696
+ if (performanceMonitor && performanceMonitor.getStats) {
697
+ const perfStats = performanceMonitor.getStats();
698
+ insights.performanceMonitorStats = perfStats;
699
+ }
700
+ return insights;
701
+ }
702
+ /**
703
+ * Utility methods
704
+ */
705
+ generateRenderId() {
706
+ return `render_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
707
+ }
708
+ serializeComponent(component, maxDepth = 3, currentDepth = 0) {
709
+ if (currentDepth > maxDepth)
710
+ return '...';
711
+ try {
712
+ if (typeof component === 'function') {
713
+ return `[Function: ${component.name || 'anonymous'}]`;
714
+ }
715
+ if (Array.isArray(component)) {
716
+ return component.slice(0, 3).map(c => this.serializeComponent(c, maxDepth, currentDepth + 1)).concat(component.length > 3 ? [`...(${component.length - 3} more)`] : []);
717
+ }
718
+ if (component && typeof component === 'object') {
719
+ const serialized = {};
720
+ const keys = Object.keys(component).slice(0, 10);
721
+ for (const key of keys) {
722
+ if (key === 'children' && component[key]) {
723
+ serialized[key] = this.serializeComponent(component[key], maxDepth, currentDepth + 1);
724
+ }
725
+ else if (typeof component[key] === 'function') {
726
+ serialized[key] = `[Function: ${component[key].name || 'anonymous'}]`;
727
+ }
728
+ else {
729
+ serialized[key] = component[key];
730
+ }
731
+ }
732
+ if (Object.keys(component).length > 10) {
733
+ serialized['...'] = `(${Object.keys(component).length - 10} more properties)`;
734
+ }
735
+ return serialized;
736
+ }
737
+ return component;
738
+ }
739
+ catch (error) {
740
+ return `[Serialization Error: ${error.message}]`;
741
+ }
742
+ }
743
+ clearDevData() {
744
+ this.renderHistory = [];
745
+ this.warnings = [];
746
+ this.errors = [];
747
+ this.componentRegistry.clear();
748
+ console.log('🧹 Dev data cleared');
749
+ }
750
+ toggleFeature(feature) {
751
+ switch (feature) {
752
+ case 'cache':
753
+ if (this.coherent.cache) {
754
+ this.coherent.cache.enabled = !this.coherent.cache.enabled;
755
+ console.log(`Cache ${this.coherent.cache.enabled ? 'enabled' : 'disabled'}`);
756
+ }
757
+ break;
758
+ case 'monitoring':
759
+ if (performanceMonitor) {
760
+ performanceMonitor.enabled = !performanceMonitor.enabled;
761
+ console.log(`Monitoring ${performanceMonitor.enabled ? 'enabled' : 'disabled'}`);
762
+ }
763
+ break;
764
+ case 'hot-reload':
765
+ this.hotReloadEnabled = !this.hotReloadEnabled;
766
+ console.log(`Hot reload ${this.hotReloadEnabled ? 'enabled' : 'disabled'}`);
767
+ break;
768
+ default:
769
+ console.log(`Unknown feature: ${feature}`);
770
+ }
771
+ }
772
+ validateComponent(component) {
773
+ return this.deepValidateComponent(component);
774
+ }
775
+ setupComponentInspector() {
776
+ // Register components for inspection
777
+ const originalCreateComponent = this.coherent.createComponent;
778
+ if (originalCreateComponent) {
779
+ this.coherent.createComponent = (config) => {
780
+ const component = originalCreateComponent.call(this.coherent, config);
781
+ // Register component
782
+ this.componentRegistry.set(config.name || 'anonymous', {
783
+ config,
784
+ component,
785
+ registeredAt: Date.now()
786
+ });
787
+ return component;
788
+ };
789
+ }
790
+ }
791
+ }
792
+ /**
793
+ * Create a lightweight dev tools instance
794
+ */
795
+ export function createDevTools(coherentInstance) {
796
+ return new DevTools(coherentInstance);
797
+ }
798
+ /**
799
+ * Global dev tools utilities (available even when DevTools is disabled)
800
+ */
801
+ export const devUtils = {
802
+ /**
803
+ * Quick component inspection
804
+ */
805
+ inspect: (component) => {
806
+ console.log('🔍 Component Inspection:');
807
+ console.log('Type:', typeof component);
808
+ console.log('Structure:', component);
809
+ if (isCoherentObject(component)) {
810
+ const tags = Object.keys(component);
811
+ console.log('Tags:', tags);
812
+ for (const tag of tags) {
813
+ const props = component[tag];
814
+ if (props && typeof props === 'object') {
815
+ console.log(`${tag} props:`, Object.keys(_props));
816
+ }
817
+ }
818
+ }
819
+ },
820
+ /**
821
+ * Simple validation
822
+ */
823
+ validate: (component) => {
824
+ try {
825
+ validateComponent(component);
826
+ console.log('✅ Component is valid');
827
+ return true;
828
+ }
829
+ catch (error) {
830
+ console.error('❌ Component validation failed:', error.message);
831
+ return false;
832
+ }
833
+ },
834
+ /**
835
+ * Performance timing helper
836
+ */
837
+ time: (label, fn) => {
838
+ const start = performance.now();
839
+ const result = fn();
840
+ const end = performance.now();
841
+ console.log(`⏱️ ${label}: ${(end - start).toFixed(2)}ms`);
842
+ return result;
843
+ }
844
+ };
845
+ export default DevTools;
846
+ //# sourceMappingURL=dev-tools.js.map