@coherent.js/devtools 1.1.2 → 2.0.0-rc.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.
package/dist/profiler.js CHANGED
@@ -1,8 +1,32 @@
1
1
  // src/profiler.js
2
+ var hasPerformanceTimeline = () => typeof performance !== "undefined" && typeof performance.mark === "function";
3
+ function now() {
4
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
5
+ }
6
+ function clearTimelineEntries(marks, measureName) {
7
+ if (!hasPerformanceTimeline()) return;
8
+ for (const mark of marks) {
9
+ performance.clearMarks?.(mark);
10
+ }
11
+ if (measureName) {
12
+ performance.clearMeasures?.(measureName);
13
+ }
14
+ }
15
+ function recordTimelineMeasure(name, startMark, endMark) {
16
+ if (!hasPerformanceTimeline()) return;
17
+ try {
18
+ performance.mark(endMark);
19
+ performance.measure?.(name, startMark, endMark);
20
+ } catch {
21
+ } finally {
22
+ clearTimelineEntries([startMark, endMark], name);
23
+ }
24
+ }
2
25
  var PerformanceProfiler = class {
3
26
  constructor(options = {}) {
4
27
  this.options = {
5
- enabled: true,
28
+ // Opt-in: a profiler that is merely constructed must cost nothing.
29
+ enabled: false,
6
30
  sampleRate: 1,
7
31
  // 1.0 = 100% sampling
8
32
  slowThreshold: 16,
@@ -29,14 +53,14 @@ var PerformanceProfiler = class {
29
53
  const session = {
30
54
  id: this.generateId(),
31
55
  name,
32
- startTime: Date.now(),
56
+ startTime: now(),
33
57
  measurements: [],
34
58
  marks: [],
35
59
  active: true
36
60
  };
37
61
  this.sessions.set(session.id, session);
38
62
  this.currentSession = session;
39
- if (typeof performance !== "undefined" && performance.mark) {
63
+ if (hasPerformanceTimeline()) {
40
64
  performance.mark(`coherent-session-start-${session.id}`);
41
65
  }
42
66
  return session.id;
@@ -52,19 +76,18 @@ var PerformanceProfiler = class {
52
76
  if (!session) {
53
77
  return null;
54
78
  }
55
- session.endTime = Date.now();
79
+ session.endTime = now();
56
80
  session.duration = session.endTime - session.startTime;
57
81
  session.active = false;
58
- if (typeof performance !== "undefined" && performance.mark) {
59
- performance.mark(`coherent-session-end-${session.id}`);
60
- }
82
+ recordTimelineMeasure(
83
+ `coherent-session-${session.id}`,
84
+ `coherent-session-start-${session.id}`,
85
+ `coherent-session-end-${session.id}`
86
+ );
61
87
  if (this.currentSession === session) {
62
88
  this.currentSession = null;
63
89
  }
64
- this.measurements.push(session);
65
- if (this.measurements.length > this.options.maxSamples) {
66
- this.measurements.shift();
67
- }
90
+ this.addMeasurement(session);
68
91
  return this.analyzeSession(session);
69
92
  }
70
93
  /**
@@ -78,12 +101,12 @@ var PerformanceProfiler = class {
78
101
  id: measurementId,
79
102
  componentName,
80
103
  props,
81
- startTime: Date.now(),
104
+ startTime: now(),
82
105
  startMemory: this.getMemoryUsage(),
83
106
  phase: "render"
84
107
  };
85
108
  this.marks.set(measurementId, measurement);
86
- if (typeof performance !== "undefined" && performance.mark) {
109
+ if (hasPerformanceTimeline()) {
87
110
  performance.mark(`coherent-render-start-${measurementId}`);
88
111
  }
89
112
  return measurementId;
@@ -94,28 +117,21 @@ var PerformanceProfiler = class {
94
117
  endRender(measurementId, result = {}) {
95
118
  if (!measurementId || !this.marks.has(measurementId)) return null;
96
119
  const measurement = this.marks.get(measurementId);
97
- measurement.endTime = Date.now();
120
+ measurement.endTime = now();
98
121
  measurement.duration = measurement.endTime - measurement.startTime;
99
122
  measurement.endMemory = this.getMemoryUsage();
100
- measurement.memoryDelta = measurement.endMemory - measurement.startMemory;
123
+ measurement.memoryDelta = measurement.startMemory && measurement.endMemory ? measurement.endMemory.used - measurement.startMemory.used : null;
101
124
  measurement.result = result;
102
125
  measurement.slow = measurement.duration > this.options.slowThreshold;
103
- if (typeof performance !== "undefined" && performance.mark) {
104
- performance.mark(`coherent-render-end-${measurementId}`);
105
- if (performance.measure) {
106
- try {
107
- performance.measure(
108
- `coherent-render-${measurementId}`,
109
- `coherent-render-start-${measurementId}`,
110
- `coherent-render-end-${measurementId}`
111
- );
112
- } catch {
113
- }
114
- }
115
- }
116
- this.measurements.push(measurement);
126
+ recordTimelineMeasure(
127
+ `coherent-render-${measurementId}`,
128
+ `coherent-render-start-${measurementId}`,
129
+ `coherent-render-end-${measurementId}`
130
+ );
131
+ this.addMeasurement(measurement);
117
132
  if (this.currentSession) {
118
133
  this.currentSession.measurements.push(measurement);
134
+ this.trim(this.currentSession.measurements);
119
135
  }
120
136
  this.marks.delete(measurementId);
121
137
  return measurement;
@@ -126,15 +142,13 @@ var PerformanceProfiler = class {
126
142
  mark(name, data = {}) {
127
143
  const mark = {
128
144
  name,
129
- timestamp: Date.now(),
145
+ timestamp: now(),
130
146
  data,
131
147
  memory: this.getMemoryUsage()
132
148
  };
133
149
  if (this.currentSession) {
134
150
  this.currentSession.marks.push(mark);
135
- }
136
- if (typeof performance !== "undefined" && performance.mark) {
137
- performance.mark(`coherent-mark-${name}`);
151
+ this.trim(this.currentSession.marks);
138
152
  }
139
153
  return mark;
140
154
  }
@@ -153,6 +167,22 @@ var PerformanceProfiler = class {
153
167
  endMark: end.name
154
168
  };
155
169
  }
170
+ /**
171
+ * Append a measurement, dropping the oldest beyond `maxSamples`.
172
+ */
173
+ addMeasurement(measurement) {
174
+ this.measurements.push(measurement);
175
+ this.trim(this.measurements);
176
+ }
177
+ /**
178
+ * Drop the oldest entries of `list` beyond `maxSamples`.
179
+ */
180
+ trim(list) {
181
+ const max = Math.max(1, Number(this.options.maxSamples) || 1e3);
182
+ if (list.length > max) {
183
+ list.splice(0, list.length - max);
184
+ }
185
+ }
156
186
  /**
157
187
  * Get memory usage
158
188
  */
@@ -447,6 +477,10 @@ var PerformanceProfiler = class {
447
477
  * Clear all data
448
478
  */
449
479
  clear() {
480
+ clearTimelineEntries([
481
+ ...[...this.marks.keys()].map((id) => `coherent-render-start-${id}`),
482
+ ...[...this.sessions.values()].filter((session) => session.active).map((session) => `coherent-session-start-${session.id}`)
483
+ ]);
450
484
  this.measurements = [];
451
485
  this.sessions.clear();
452
486
  this.currentSession = null;
@@ -486,7 +520,7 @@ function createProfiler(options = {}) {
486
520
  return new PerformanceProfiler(options);
487
521
  }
488
522
  async function measure(name, fn, profiler = null) {
489
- const prof = profiler || new PerformanceProfiler();
523
+ const prof = profiler || new PerformanceProfiler({ enabled: true });
490
524
  const sessionId = prof.start(name);
491
525
  try {
492
526
  const value = await fn();
@@ -494,14 +528,48 @@ async function measure(name, fn, profiler = null) {
494
528
  return { value, duration: result?.duration || 0 };
495
529
  } catch (error) {
496
530
  const result = prof.stop(sessionId);
497
- throw { error, duration: result?.duration || 0 };
531
+ const failure = error instanceof Error ? error : new Error(`${name} failed: ${String(error)}`, { cause: error });
532
+ try {
533
+ failure.duration = result?.duration || 0;
534
+ } catch {
535
+ }
536
+ throw failure;
498
537
  }
499
538
  }
500
- function profile(fn) {
501
- return function(...args) {
502
- const result = fn(...args);
539
+ function profile(fn, options = {}) {
540
+ if (typeof fn !== "function") {
541
+ throw new TypeError("profile() expects a function");
542
+ }
543
+ const opts = options instanceof PerformanceProfiler ? { profiler: options } : options;
544
+ const profiler = opts.profiler || new PerformanceProfiler({ enabled: true });
545
+ const name = opts.name || fn.name || "anonymous";
546
+ function profiled(...args) {
547
+ const id = profiler.startRender(name);
548
+ let result;
549
+ try {
550
+ result = fn.apply(this, args);
551
+ } catch (error) {
552
+ profiler.endRender(id, { error: true });
553
+ throw error;
554
+ }
555
+ if (result && typeof result.then === "function") {
556
+ return Promise.resolve(result).then(
557
+ (value) => {
558
+ profiler.endRender(id);
559
+ return value;
560
+ },
561
+ (error) => {
562
+ profiler.endRender(id, { error: true });
563
+ throw error;
564
+ }
565
+ );
566
+ }
567
+ profiler.endRender(id);
503
568
  return result;
504
- };
569
+ }
570
+ Object.defineProperty(profiled, "name", { value: name });
571
+ profiled.profiler = profiler;
572
+ return profiled;
505
573
  }
506
574
  var profiler_default = {
507
575
  PerformanceProfiler,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/profiler.js"],
4
- "sourcesContent": ["/**\n * Coherent.js Performance Profiler\n * \n * Tracks and analyzes rendering performance\n * \n * @module devtools/profiler\n */\n\n/**\n * Performance Profiler\n * Measures and analyzes component rendering performance\n */\nexport class PerformanceProfiler {\n constructor(options = {}) {\n this.options = {\n enabled: true,\n sampleRate: 1.0, // 1.0 = 100% sampling\n slowThreshold: 16, // 16ms = 60fps\n trackMemory: typeof performance !== 'undefined' && performance.memory,\n maxSamples: options.maxSamples || 1000,\n ...options\n };\n \n this.measurements = [];\n this.sessions = new Map();\n this.currentSession = null;\n this.marks = new Map();\n }\n\n /**\n * Start a profiling session\n */\n start(name = 'default') {\n if (!this.options.enabled) {\n return null;\n }\n\n // Apply sampling\n if (this.options.sampleRate < 1.0 && Math.random() > this.options.sampleRate) {\n return null;\n }\n\n const session = {\n id: this.generateId(),\n name,\n startTime: Date.now(),\n measurements: [],\n marks: [],\n active: true\n };\n\n this.sessions.set(session.id, session);\n this.currentSession = session;\n\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(`coherent-session-start-${session.id}`);\n }\n\n return session.id;\n }\n\n /**\n * Stop a profiling session\n */\n stop(sessionId) {\n if (!sessionId) {\n return null;\n }\n\n const session = this.sessions.get(sessionId);\n\n if (!session) {\n return null; // Gracefully handle non-existent sessions\n }\n\n session.endTime = Date.now();\n session.duration = session.endTime - session.startTime;\n session.active = false;\n\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(`coherent-session-end-${session.id}`);\n }\n\n if (this.currentSession === session) {\n this.currentSession = null;\n }\n\n // Store measurement\n this.measurements.push(session);\n \n // Limit measurements (maxSamples)\n if (this.measurements.length > this.options.maxSamples) {\n this.measurements.shift();\n }\n\n return this.analyzeSession(session);\n }\n\n /**\n * Start measuring a render\n */\n startRender(componentName, props = {}) {\n if (!this.options.enabled) return null;\n \n // Sample rate check\n if (Math.random() > this.options.sampleRate) return null;\n\n const measurementId = this.generateId();\n const measurement = {\n id: measurementId,\n componentName,\n props,\n startTime: Date.now(),\n startMemory: this.getMemoryUsage(),\n phase: 'render'\n };\n\n this.marks.set(measurementId, measurement);\n\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(`coherent-render-start-${measurementId}`);\n }\n\n return measurementId;\n }\n\n /**\n * End measuring a render\n */\n endRender(measurementId, result = {}) {\n if (!measurementId || !this.marks.has(measurementId)) return null;\n\n const measurement = this.marks.get(measurementId);\n measurement.endTime = Date.now();\n measurement.duration = measurement.endTime - measurement.startTime;\n measurement.endMemory = this.getMemoryUsage();\n measurement.memoryDelta = measurement.endMemory - measurement.startMemory;\n measurement.result = result;\n measurement.slow = measurement.duration > this.options.slowThreshold;\n\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(`coherent-render-end-${measurementId}`);\n \n if (performance.measure) {\n try {\n performance.measure(\n `coherent-render-${measurementId}`,\n `coherent-render-start-${measurementId}`,\n `coherent-render-end-${measurementId}`\n );\n } catch {\n // Ignore measure errors\n }\n }\n }\n\n // Add to measurements\n this.measurements.push(measurement);\n \n // Add to current session\n if (this.currentSession) {\n this.currentSession.measurements.push(measurement);\n }\n\n // Clean up\n this.marks.delete(measurementId);\n\n return measurement;\n }\n\n /**\n * Mark a point in time\n */\n mark(name, data = {}) {\n const mark = {\n name,\n timestamp: Date.now(),\n data,\n memory: this.getMemoryUsage()\n };\n\n if (this.currentSession) {\n this.currentSession.marks.push(mark);\n }\n\n if (typeof performance !== 'undefined' && performance.mark) {\n performance.mark(`coherent-mark-${name}`);\n }\n\n return mark;\n }\n\n /**\n * Measure time between two marks\n */\n measure(startMark, endMark) {\n const start = this.findMark(startMark);\n const end = this.findMark(endMark);\n\n if (!start || !end) {\n throw new Error('Mark not found');\n }\n\n return {\n duration: end.timestamp - start.timestamp,\n startMark: start.name,\n endMark: end.name\n };\n }\n\n /**\n * Get memory usage\n */\n getMemoryUsage() {\n if (typeof performance !== 'undefined' && performance.memory) {\n return {\n used: performance.memory.usedJSHeapSize,\n total: performance.memory.totalJSHeapSize,\n limit: performance.memory.jsHeapSizeLimit\n };\n }\n return null;\n }\n\n /**\n * Find a mark by name\n */\n findMark(name) {\n if (!this.currentSession) return null;\n return this.currentSession.marks.find(m => m.name === name);\n }\n\n /**\n * Get all measurements\n */\n getMeasurements(filter = {}) {\n let results = [...this.measurements];\n\n if (filter.componentName) {\n results = results.filter(m => m.componentName === filter.componentName);\n }\n\n if (filter.slow) {\n results = results.filter(m => m.slow);\n }\n\n if (filter.minDuration) {\n results = results.filter(m => m.duration >= filter.minDuration);\n }\n\n if (filter.limit) {\n results = results.slice(0, filter.limit);\n }\n\n return results;\n }\n\n /**\n * Analyze a session\n */\n analyzeSession(session) {\n const measurements = session.measurements;\n\n if (measurements.length === 0) {\n return {\n session: session.id,\n duration: session.duration,\n measurements: 0,\n analysis: null\n };\n }\n\n const durations = measurements.map(m => m.duration);\n const sorted = [...durations].sort((a, b) => a - b);\n\n return {\n session: session.id,\n name: session.name,\n duration: session.duration,\n measurements: measurements.length,\n analysis: {\n total: durations.reduce((a, b) => a + b, 0),\n average: durations.reduce((a, b) => a + b, 0) / durations.length,\n median: sorted[Math.floor(sorted.length / 2)],\n min: Math.min(...durations),\n max: Math.max(...durations),\n p95: sorted[Math.floor(sorted.length * 0.95)],\n p99: sorted[Math.floor(sorted.length * 0.99)],\n slowRenders: measurements.filter(m => m.slow).length,\n slowPercentage: (measurements.filter(m => m.slow).length / measurements.length) * 100\n },\n byComponent: this.groupByComponent(measurements),\n slowest: measurements\n .sort((a, b) => b.duration - a.duration)\n .slice(0, 10)\n .map(m => ({\n component: m.componentName,\n duration: m.duration,\n timestamp: m.startTime\n }))\n };\n }\n\n /**\n * Group measurements by component\n */\n groupByComponent(measurements) {\n const groups = {};\n\n measurements.forEach(m => {\n if (!groups[m.componentName]) {\n groups[m.componentName] = {\n count: 0,\n totalDuration: 0,\n durations: []\n };\n }\n\n groups[m.componentName].count++;\n groups[m.componentName].totalDuration += m.duration;\n groups[m.componentName].durations.push(m.duration);\n });\n\n // Calculate stats for each component\n Object.keys(groups).forEach(name => {\n const group = groups[name];\n group.average = group.totalDuration / group.count;\n group.min = Math.min(...group.durations);\n group.max = Math.max(...group.durations);\n });\n\n return groups;\n }\n\n /**\n * Get performance summary\n */\n getSummary() {\n const allMeasurements = this.measurements;\n\n if (allMeasurements.length === 0) {\n return {\n totalMeasurements: 0,\n totalSessions: this.sessions.size,\n analysis: null\n };\n }\n\n const durations = allMeasurements.map(m => m.duration);\n\n return {\n totalMeasurements: allMeasurements.length,\n totalSessions: this.sessions.size,\n slowRenders: allMeasurements.filter(m => m.slow).length,\n analysis: {\n average: durations.reduce((a, b) => a + b, 0) / durations.length,\n min: Math.min(...durations),\n max: Math.max(...durations),\n slowPercentage: (allMeasurements.filter(m => m.slow).length / allMeasurements.length) * 100\n },\n byComponent: this.groupByComponent(allMeasurements),\n recentSlow: allMeasurements\n .filter(m => m.slow)\n .slice(-10)\n .map(m => ({\n component: m.componentName,\n duration: m.duration,\n timestamp: m.startTime\n }))\n };\n }\n\n /**\n * Get statistics\n */\n getStatistics() {\n if (this.measurements.length === 0) {\n return { mean: 0, median: 0, min: 0, max: 0, stdDev: 0 };\n }\n\n const durations = this.measurements.map(m => m.duration);\n const sum = durations.reduce((a, b) => a + b, 0);\n const mean = sum / durations.length;\n \n const sorted = [...durations].sort((a, b) => a - b);\n const median = sorted[Math.floor(sorted.length / 2)];\n \n const variance = durations.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / durations.length;\n const stdDev = Math.sqrt(variance);\n\n return {\n mean,\n median,\n min: Math.min(...durations),\n max: Math.max(...durations),\n stdDev\n };\n }\n\n /**\n * Get bottlenecks\n */\n getBottlenecks(threshold = null) {\n const slowThreshold = threshold || this.options.slowThreshold;\n return this.measurements\n .filter(m => m.duration > slowThreshold)\n .sort((a, b) => b.duration - a.duration)\n .map(m => ({\n name: m.name,\n duration: m.duration,\n timestamp: m.startTime\n }));\n }\n\n /**\n * Get metrics\n */\n getMetrics() {\n const operationCounts = {};\n this.measurements.forEach(m => {\n operationCounts[m.name] = (operationCounts[m.name] || 0) + 1;\n });\n\n const totalDuration = this.measurements.reduce((sum, m) => sum + m.duration, 0);\n\n return {\n totalOperations: this.measurements.length,\n totalDuration,\n operationCounts,\n averageDuration: this.measurements.length > 0 ? totalDuration / this.measurements.length : 0,\n memoryUsage: this.options.trackMemory && typeof performance !== 'undefined' && performance.memory\n ? performance.memory.usedJSHeapSize\n : null\n };\n }\n\n /**\n * Generate report\n */\n generateReport() {\n const stats = this.getStatistics();\n const metrics = this.getMetrics();\n const bottlenecks = this.getBottlenecks();\n const recommendations = this.getRecommendations();\n\n return {\n summary: {\n totalOperations: metrics.totalOperations,\n averageDuration: metrics.averageDuration,\n slowOperations: bottlenecks.length\n },\n statistics: stats,\n operations: this.measurements.map(m => ({\n name: m.name,\n duration: m.duration,\n timestamp: m.startTime\n })),\n bottlenecks: bottlenecks.slice(0, 10),\n recommendations,\n timestamp: Date.now()\n };\n }\n\n /**\n * Export profiling data\n */\n export() {\n return {\n sessions: Array.from(this.sessions.values()),\n measurements: this.measurements,\n metrics: this.getMetrics(),\n statistics: this.getStatistics(),\n exportedAt: Date.now()\n };\n }\n\n /**\n * Format metrics for display\n */\n formatMetrics() {\n const metrics = this.getMetrics();\n const stats = this.getStatistics();\n \n let output = `Performance Metrics\\n`;\n output += `==================\\n`;\n output += `Total Operations: ${metrics.totalOperations}\\n`;\n output += `Average Duration: ${metrics.averageDuration.toFixed(2)}ms\\n`;\n output += `Mean: ${stats.mean.toFixed(2)}ms\\n`;\n output += `Median: ${stats.median.toFixed(2)}ms\\n`;\n output += `Min: ${stats.min.toFixed(2)}ms\\n`;\n output += `Max: ${stats.max.toFixed(2)}ms\\n`;\n \n return output;\n }\n\n /**\n * Compare two profiles\n */\n compare(profileId1, profileId2) {\n const session1 = this.sessions.get(profileId1);\n const session2 = this.sessions.get(profileId2);\n\n if (!session1 || !session2) {\n return null;\n }\n\n return {\n difference: session2.duration - session1.duration,\n percentChange: ((session2.duration - session1.duration) / session1.duration) * 100,\n profile1: { name: session1.name, duration: session1.duration },\n profile2: { name: session2.name, duration: session2.duration }\n };\n }\n\n /**\n * Get performance recommendations\n */\n getRecommendations() {\n const recommendations = [];\n const bottlenecks = this.getBottlenecks();\n const stats = this.getStatistics();\n\n if (bottlenecks.length > 0) {\n bottlenecks.slice(0, 5).forEach(bottleneck => {\n recommendations.push({\n type: 'bottleneck',\n operation: bottleneck.name,\n suggestion: `Optimize ${bottleneck.name} - duration: ${bottleneck.duration.toFixed(2)}ms exceeds threshold`,\n severity: 'high',\n message: `Found slow operation exceeding ${this.options.slowThreshold}ms`\n });\n });\n }\n\n if (stats.max > this.options.slowThreshold * 2) {\n recommendations.push({\n type: 'performance',\n operation: 'general',\n suggestion: `Review operations with high duration`,\n message: `Maximum duration (${stats.max.toFixed(2)}ms) is significantly high`,\n severity: 'medium'\n });\n }\n\n return recommendations;\n }\n\n /**\n * Clear all data\n */\n clear() {\n this.measurements = [];\n this.sessions.clear();\n this.currentSession = null;\n this.marks.clear();\n }\n\n /**\n * Enable profiler\n */\n enable() {\n this.options.enabled = true;\n }\n\n /**\n * Disable profiler\n */\n disable() {\n this.options.enabled = false;\n }\n\n /**\n * Generate unique ID.\n *\n * Uses crypto.getRandomValues rather than Math.random: the ids key the\n * session and measurement maps, so a predictable suffix lets one caller\n * guess or collide with another's entry. getRandomValues is available in\n * Node 19+ and in browsers without requiring a secure context, unlike\n * randomUUID.\n *\n * @returns {string} A unique profiling id\n */\n generateId() {\n const bytes = new Uint8Array(8);\n globalThis.crypto.getRandomValues(bytes);\n const suffix = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');\n return `prof-${Date.now()}-${suffix}`;\n }\n}\n\n/**\n * Create a performance profiler\n */\nexport function createProfiler(options = {}) {\n return new PerformanceProfiler(options);\n}\n\n/**\n * Measure a function execution\n */\nexport async function measure(name, fn, profiler = null) {\n const prof = profiler || new PerformanceProfiler();\n const sessionId = prof.start(name);\n \n try {\n const value = await fn();\n const result = prof.stop(sessionId);\n return { value, duration: result?.duration || 0 };\n } catch (error) {\n const result = prof.stop(sessionId);\n throw { error, duration: result?.duration || 0 };\n }\n}\n\n/**\n * Create a profiling decorator\n */\nexport function profile(fn) {\n return function(...args) {\n const result = fn(...args);\n return result;\n };\n}\n\nexport default {\n PerformanceProfiler,\n createProfiler,\n measure,\n profile\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Coherent.js Performance Profiler\n *\n * Tracks and analyzes rendering performance\n *\n * Timings come from performance.now() (sub-millisecond, monotonic), so\n * `startTime` / `endTime` are relative to the time origin, not epoch\n * milliseconds. A profiler records nothing until enabled.\n *\n * @module devtools/profiler\n */\n\nconst hasPerformanceTimeline = () =>\n typeof performance !== 'undefined' && typeof performance.mark === 'function';\n\n/** Monotonic high-resolution clock in milliseconds. */\nfunction now() {\n return typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now();\n}\n\n/** Remove entries this profiler added to the global performance timeline. */\nfunction clearTimelineEntries(marks, measureName) {\n if (!hasPerformanceTimeline()) return;\n for (const mark of marks) {\n performance.clearMarks?.(mark);\n }\n if (measureName) {\n performance.clearMeasures?.(measureName);\n }\n}\n\n/**\n * Add a performance.measure() for DevTools timelines, then clear it and its\n * marks so a long-running process does not accumulate timeline entries.\n */\nfunction recordTimelineMeasure(name, startMark, endMark) {\n if (!hasPerformanceTimeline()) return;\n try {\n performance.mark(endMark);\n performance.measure?.(name, startMark, endMark);\n } catch {\n // Ignore measure errors (e.g. the start mark was already cleared)\n } finally {\n clearTimelineEntries([startMark, endMark], name);\n }\n}\n\n/**\n * Performance Profiler\n * Measures and analyzes component rendering performance\n */\nexport class PerformanceProfiler {\n constructor(options = {}) {\n this.options = {\n // Opt-in: a profiler that is merely constructed must cost nothing.\n enabled: false,\n sampleRate: 1.0, // 1.0 = 100% sampling\n slowThreshold: 16, // 16ms = 60fps\n trackMemory: typeof performance !== 'undefined' && performance.memory,\n maxSamples: options.maxSamples || 1000,\n ...options\n };\n \n this.measurements = [];\n this.sessions = new Map();\n this.currentSession = null;\n this.marks = new Map();\n }\n\n /**\n * Start a profiling session\n */\n start(name = 'default') {\n if (!this.options.enabled) {\n return null;\n }\n\n // Apply sampling\n if (this.options.sampleRate < 1.0 && Math.random() > this.options.sampleRate) {\n return null;\n }\n\n const session = {\n id: this.generateId(),\n name,\n startTime: now(),\n measurements: [],\n marks: [],\n active: true\n };\n\n this.sessions.set(session.id, session);\n this.currentSession = session;\n\n if (hasPerformanceTimeline()) {\n performance.mark(`coherent-session-start-${session.id}`);\n }\n\n return session.id;\n }\n\n /**\n * Stop a profiling session\n */\n stop(sessionId) {\n if (!sessionId) {\n return null;\n }\n\n const session = this.sessions.get(sessionId);\n\n if (!session) {\n return null; // Gracefully handle non-existent sessions\n }\n\n session.endTime = now();\n session.duration = session.endTime - session.startTime;\n session.active = false;\n\n recordTimelineMeasure(\n `coherent-session-${session.id}`,\n `coherent-session-start-${session.id}`,\n `coherent-session-end-${session.id}`\n );\n\n if (this.currentSession === session) {\n this.currentSession = null;\n }\n\n // Store measurement\n this.addMeasurement(session);\n\n return this.analyzeSession(session);\n }\n\n /**\n * Start measuring a render\n */\n startRender(componentName, props = {}) {\n if (!this.options.enabled) return null;\n \n // Sample rate check\n if (Math.random() > this.options.sampleRate) return null;\n\n const measurementId = this.generateId();\n const measurement = {\n id: measurementId,\n componentName,\n props,\n startTime: now(),\n startMemory: this.getMemoryUsage(),\n phase: 'render'\n };\n\n this.marks.set(measurementId, measurement);\n\n if (hasPerformanceTimeline()) {\n performance.mark(`coherent-render-start-${measurementId}`);\n }\n\n return measurementId;\n }\n\n /**\n * End measuring a render\n */\n endRender(measurementId, result = {}) {\n if (!measurementId || !this.marks.has(measurementId)) return null;\n\n const measurement = this.marks.get(measurementId);\n measurement.endTime = now();\n measurement.duration = measurement.endTime - measurement.startTime;\n measurement.endMemory = this.getMemoryUsage();\n measurement.memoryDelta = measurement.startMemory && measurement.endMemory\n ? measurement.endMemory.used - measurement.startMemory.used\n : null;\n measurement.result = result;\n measurement.slow = measurement.duration > this.options.slowThreshold;\n\n recordTimelineMeasure(\n `coherent-render-${measurementId}`,\n `coherent-render-start-${measurementId}`,\n `coherent-render-end-${measurementId}`\n );\n\n // Add to measurements (bounded by maxSamples)\n this.addMeasurement(measurement);\n\n // Add to current session\n if (this.currentSession) {\n this.currentSession.measurements.push(measurement);\n this.trim(this.currentSession.measurements);\n }\n\n // Clean up\n this.marks.delete(measurementId);\n\n return measurement;\n }\n\n /**\n * Mark a point in time\n */\n mark(name, data = {}) {\n const mark = {\n name,\n timestamp: now(),\n data,\n memory: this.getMemoryUsage()\n };\n\n if (this.currentSession) {\n this.currentSession.marks.push(mark);\n this.trim(this.currentSession.marks);\n }\n\n return mark;\n }\n\n /**\n * Measure time between two marks\n */\n measure(startMark, endMark) {\n const start = this.findMark(startMark);\n const end = this.findMark(endMark);\n\n if (!start || !end) {\n throw new Error('Mark not found');\n }\n\n return {\n duration: end.timestamp - start.timestamp,\n startMark: start.name,\n endMark: end.name\n };\n }\n\n /**\n * Append a measurement, dropping the oldest beyond `maxSamples`.\n */\n addMeasurement(measurement) {\n this.measurements.push(measurement);\n this.trim(this.measurements);\n }\n\n /**\n * Drop the oldest entries of `list` beyond `maxSamples`.\n */\n trim(list) {\n const max = Math.max(1, Number(this.options.maxSamples) || 1000);\n if (list.length > max) {\n list.splice(0, list.length - max);\n }\n }\n\n /**\n * Get memory usage\n */\n getMemoryUsage() {\n if (typeof performance !== 'undefined' && performance.memory) {\n return {\n used: performance.memory.usedJSHeapSize,\n total: performance.memory.totalJSHeapSize,\n limit: performance.memory.jsHeapSizeLimit\n };\n }\n return null;\n }\n\n /**\n * Find a mark by name\n */\n findMark(name) {\n if (!this.currentSession) return null;\n return this.currentSession.marks.find(m => m.name === name);\n }\n\n /**\n * Get all measurements\n */\n getMeasurements(filter = {}) {\n let results = [...this.measurements];\n\n if (filter.componentName) {\n results = results.filter(m => m.componentName === filter.componentName);\n }\n\n if (filter.slow) {\n results = results.filter(m => m.slow);\n }\n\n if (filter.minDuration) {\n results = results.filter(m => m.duration >= filter.minDuration);\n }\n\n if (filter.limit) {\n results = results.slice(0, filter.limit);\n }\n\n return results;\n }\n\n /**\n * Analyze a session\n */\n analyzeSession(session) {\n const measurements = session.measurements;\n\n if (measurements.length === 0) {\n return {\n session: session.id,\n duration: session.duration,\n measurements: 0,\n analysis: null\n };\n }\n\n const durations = measurements.map(m => m.duration);\n const sorted = [...durations].sort((a, b) => a - b);\n\n return {\n session: session.id,\n name: session.name,\n duration: session.duration,\n measurements: measurements.length,\n analysis: {\n total: durations.reduce((a, b) => a + b, 0),\n average: durations.reduce((a, b) => a + b, 0) / durations.length,\n median: sorted[Math.floor(sorted.length / 2)],\n min: Math.min(...durations),\n max: Math.max(...durations),\n p95: sorted[Math.floor(sorted.length * 0.95)],\n p99: sorted[Math.floor(sorted.length * 0.99)],\n slowRenders: measurements.filter(m => m.slow).length,\n slowPercentage: (measurements.filter(m => m.slow).length / measurements.length) * 100\n },\n byComponent: this.groupByComponent(measurements),\n slowest: measurements\n .sort((a, b) => b.duration - a.duration)\n .slice(0, 10)\n .map(m => ({\n component: m.componentName,\n duration: m.duration,\n timestamp: m.startTime\n }))\n };\n }\n\n /**\n * Group measurements by component\n */\n groupByComponent(measurements) {\n const groups = {};\n\n measurements.forEach(m => {\n if (!groups[m.componentName]) {\n groups[m.componentName] = {\n count: 0,\n totalDuration: 0,\n durations: []\n };\n }\n\n groups[m.componentName].count++;\n groups[m.componentName].totalDuration += m.duration;\n groups[m.componentName].durations.push(m.duration);\n });\n\n // Calculate stats for each component\n Object.keys(groups).forEach(name => {\n const group = groups[name];\n group.average = group.totalDuration / group.count;\n group.min = Math.min(...group.durations);\n group.max = Math.max(...group.durations);\n });\n\n return groups;\n }\n\n /**\n * Get performance summary\n */\n getSummary() {\n const allMeasurements = this.measurements;\n\n if (allMeasurements.length === 0) {\n return {\n totalMeasurements: 0,\n totalSessions: this.sessions.size,\n analysis: null\n };\n }\n\n const durations = allMeasurements.map(m => m.duration);\n\n return {\n totalMeasurements: allMeasurements.length,\n totalSessions: this.sessions.size,\n slowRenders: allMeasurements.filter(m => m.slow).length,\n analysis: {\n average: durations.reduce((a, b) => a + b, 0) / durations.length,\n min: Math.min(...durations),\n max: Math.max(...durations),\n slowPercentage: (allMeasurements.filter(m => m.slow).length / allMeasurements.length) * 100\n },\n byComponent: this.groupByComponent(allMeasurements),\n recentSlow: allMeasurements\n .filter(m => m.slow)\n .slice(-10)\n .map(m => ({\n component: m.componentName,\n duration: m.duration,\n timestamp: m.startTime\n }))\n };\n }\n\n /**\n * Get statistics\n */\n getStatistics() {\n if (this.measurements.length === 0) {\n return { mean: 0, median: 0, min: 0, max: 0, stdDev: 0 };\n }\n\n const durations = this.measurements.map(m => m.duration);\n const sum = durations.reduce((a, b) => a + b, 0);\n const mean = sum / durations.length;\n \n const sorted = [...durations].sort((a, b) => a - b);\n const median = sorted[Math.floor(sorted.length / 2)];\n \n const variance = durations.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / durations.length;\n const stdDev = Math.sqrt(variance);\n\n return {\n mean,\n median,\n min: Math.min(...durations),\n max: Math.max(...durations),\n stdDev\n };\n }\n\n /**\n * Get bottlenecks\n */\n getBottlenecks(threshold = null) {\n const slowThreshold = threshold || this.options.slowThreshold;\n return this.measurements\n .filter(m => m.duration > slowThreshold)\n .sort((a, b) => b.duration - a.duration)\n .map(m => ({\n name: m.name,\n duration: m.duration,\n timestamp: m.startTime\n }));\n }\n\n /**\n * Get metrics\n */\n getMetrics() {\n const operationCounts = {};\n this.measurements.forEach(m => {\n operationCounts[m.name] = (operationCounts[m.name] || 0) + 1;\n });\n\n const totalDuration = this.measurements.reduce((sum, m) => sum + m.duration, 0);\n\n return {\n totalOperations: this.measurements.length,\n totalDuration,\n operationCounts,\n averageDuration: this.measurements.length > 0 ? totalDuration / this.measurements.length : 0,\n memoryUsage: this.options.trackMemory && typeof performance !== 'undefined' && performance.memory\n ? performance.memory.usedJSHeapSize\n : null\n };\n }\n\n /**\n * Generate report\n */\n generateReport() {\n const stats = this.getStatistics();\n const metrics = this.getMetrics();\n const bottlenecks = this.getBottlenecks();\n const recommendations = this.getRecommendations();\n\n return {\n summary: {\n totalOperations: metrics.totalOperations,\n averageDuration: metrics.averageDuration,\n slowOperations: bottlenecks.length\n },\n statistics: stats,\n operations: this.measurements.map(m => ({\n name: m.name,\n duration: m.duration,\n timestamp: m.startTime\n })),\n bottlenecks: bottlenecks.slice(0, 10),\n recommendations,\n timestamp: Date.now()\n };\n }\n\n /**\n * Export profiling data\n */\n export() {\n return {\n sessions: Array.from(this.sessions.values()),\n measurements: this.measurements,\n metrics: this.getMetrics(),\n statistics: this.getStatistics(),\n exportedAt: Date.now()\n };\n }\n\n /**\n * Format metrics for display\n */\n formatMetrics() {\n const metrics = this.getMetrics();\n const stats = this.getStatistics();\n \n let output = `Performance Metrics\\n`;\n output += `==================\\n`;\n output += `Total Operations: ${metrics.totalOperations}\\n`;\n output += `Average Duration: ${metrics.averageDuration.toFixed(2)}ms\\n`;\n output += `Mean: ${stats.mean.toFixed(2)}ms\\n`;\n output += `Median: ${stats.median.toFixed(2)}ms\\n`;\n output += `Min: ${stats.min.toFixed(2)}ms\\n`;\n output += `Max: ${stats.max.toFixed(2)}ms\\n`;\n \n return output;\n }\n\n /**\n * Compare two profiles\n */\n compare(profileId1, profileId2) {\n const session1 = this.sessions.get(profileId1);\n const session2 = this.sessions.get(profileId2);\n\n if (!session1 || !session2) {\n return null;\n }\n\n return {\n difference: session2.duration - session1.duration,\n percentChange: ((session2.duration - session1.duration) / session1.duration) * 100,\n profile1: { name: session1.name, duration: session1.duration },\n profile2: { name: session2.name, duration: session2.duration }\n };\n }\n\n /**\n * Get performance recommendations\n */\n getRecommendations() {\n const recommendations = [];\n const bottlenecks = this.getBottlenecks();\n const stats = this.getStatistics();\n\n if (bottlenecks.length > 0) {\n bottlenecks.slice(0, 5).forEach(bottleneck => {\n recommendations.push({\n type: 'bottleneck',\n operation: bottleneck.name,\n suggestion: `Optimize ${bottleneck.name} - duration: ${bottleneck.duration.toFixed(2)}ms exceeds threshold`,\n severity: 'high',\n message: `Found slow operation exceeding ${this.options.slowThreshold}ms`\n });\n });\n }\n\n if (stats.max > this.options.slowThreshold * 2) {\n recommendations.push({\n type: 'performance',\n operation: 'general',\n suggestion: `Review operations with high duration`,\n message: `Maximum duration (${stats.max.toFixed(2)}ms) is significantly high`,\n severity: 'medium'\n });\n }\n\n return recommendations;\n }\n\n /**\n * Clear all data\n */\n clear() {\n clearTimelineEntries([\n ...[...this.marks.keys()].map((id) => `coherent-render-start-${id}`),\n ...[...this.sessions.values()]\n .filter((session) => session.active)\n .map((session) => `coherent-session-start-${session.id}`)\n ]);\n this.measurements = [];\n this.sessions.clear();\n this.currentSession = null;\n this.marks.clear();\n }\n\n /**\n * Enable profiler\n */\n enable() {\n this.options.enabled = true;\n }\n\n /**\n * Disable profiler\n */\n disable() {\n this.options.enabled = false;\n }\n\n /**\n * Generate unique ID.\n *\n * Uses crypto.getRandomValues rather than Math.random: the ids key the\n * session and measurement maps, so a predictable suffix lets one caller\n * guess or collide with another's entry. getRandomValues is available in\n * Node 19+ and in browsers without requiring a secure context, unlike\n * randomUUID.\n *\n * @returns {string} A unique profiling id\n */\n generateId() {\n const bytes = new Uint8Array(8);\n globalThis.crypto.getRandomValues(bytes);\n const suffix = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');\n return `prof-${Date.now()}-${suffix}`;\n }\n}\n\n/**\n * Create a performance profiler\n */\nexport function createProfiler(options = {}) {\n return new PerformanceProfiler(options);\n}\n\n/**\n * Measure a function execution.\n *\n * Resolves with `{ value, duration }`. When `fn` throws, rejects with that\n * error (an Error \u2014 non-Error values are wrapped, with the original as\n * `cause`) carrying a `duration` property.\n */\nexport async function measure(name, fn, profiler = null) {\n // Measuring is the whole point of the call, so an ad-hoc profiler is enabled.\n const prof = profiler || new PerformanceProfiler({ enabled: true });\n const sessionId = prof.start(name);\n\n try {\n const value = await fn();\n const result = prof.stop(sessionId);\n return { value, duration: result?.duration || 0 };\n } catch (error) {\n const result = prof.stop(sessionId);\n const failure = error instanceof Error\n ? error\n : new Error(`${name} failed: ${String(error)}`, { cause: error });\n try {\n failure.duration = result?.duration || 0;\n } catch {\n // frozen error object: rethrow it as is\n }\n throw failure;\n }\n}\n\n/**\n * Wrap a function so every call is recorded as a render measurement.\n *\n * @param {Function} fn - Function to profile (sync or async).\n * @param {PerformanceProfiler|Object} [options] - A profiler, or\n * `{ profiler, name }`. Without a profiler an enabled one is created;\n * either way it is exposed as `wrapped.profiler`.\n * @returns {Function} The wrapper; it returns what `fn` returns.\n */\nexport function profile(fn, options = {}) {\n if (typeof fn !== 'function') {\n throw new TypeError('profile() expects a function');\n }\n const opts = options instanceof PerformanceProfiler ? { profiler: options } : options;\n const profiler = opts.profiler || new PerformanceProfiler({ enabled: true });\n const name = opts.name || fn.name || 'anonymous';\n\n function profiled(...args) {\n const id = profiler.startRender(name);\n let result;\n try {\n result = fn.apply(this, args);\n } catch (error) {\n profiler.endRender(id, { error: true });\n throw error;\n }\n if (result && typeof result.then === 'function') {\n return Promise.resolve(result).then(\n (value) => {\n profiler.endRender(id);\n return value;\n },\n (error) => {\n profiler.endRender(id, { error: true });\n throw error;\n }\n );\n }\n profiler.endRender(id);\n return result;\n }\n\n Object.defineProperty(profiled, 'name', { value: name });\n profiled.profiler = profiler;\n return profiled;\n}\n\nexport default {\n PerformanceProfiler,\n createProfiler,\n measure,\n profile\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coherent.js/devtools",
3
- "version": "1.1.2",
3
+ "version": "2.0.0-rc.0",
4
4
  "description": "Developer tools for Coherent.js applications - tree-shakable modular exports",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -62,7 +62,7 @@
62
62
  "author": "Coherent.js Team",
63
63
  "license": "MIT",
64
64
  "peerDependencies": {
65
- "@coherent.js/core": "^1.1.2"
65
+ "@coherent.js/core": "^2.0.0-rc.0"
66
66
  },
67
67
  "repository": {
68
68
  "type": "git",
package/types/index.d.ts CHANGED
@@ -288,7 +288,7 @@ export function validateComponent(component: unknown): boolean;
288
288
  // ============================================================================
289
289
 
290
290
  export interface ProfilerOptions {
291
- /** Record anything at all; defaults to `true` */
291
+ /** Record anything at all; defaults to `false` (opt in) */
292
292
  enabled?: boolean;
293
293
  /** Fraction of sessions and renders to record, 0 to 1; defaults to `1.0` */
294
294
  sampleRate?: number;
@@ -307,7 +307,10 @@ export interface MemoryUsage {
307
307
  limit: number;
308
308
  }
309
309
 
310
- /** One recorded render. */
310
+ /**
311
+ * One recorded render. Times are `performance.now()` milliseconds
312
+ * (sub-millisecond, relative to the time origin), not epoch timestamps.
313
+ */
311
314
  export interface RenderMeasurement {
312
315
  id: string;
313
316
  componentName: string;
@@ -317,7 +320,8 @@ export interface RenderMeasurement {
317
320
  duration?: number;
318
321
  startMemory: MemoryUsage | null;
319
322
  endMemory?: MemoryUsage | null;
320
- memoryDelta?: number;
323
+ /** Change in used heap bytes, or `null` where heap usage is unavailable */
324
+ memoryDelta?: number | null;
321
325
  phase: string;
322
326
  result?: Record<string, unknown>;
323
327
  /** Whether `duration` exceeded `slowThreshold` */
@@ -452,6 +456,9 @@ export class PerformanceProfiler {
452
456
  /** Suggestions derived from the recorded measurements */
453
457
  getRecommendations(): unknown[];
454
458
 
459
+ /** Append a measurement, dropping the oldest beyond `maxSamples` */
460
+ addMeasurement(measurement: RenderMeasurement | Record<string, unknown>): void;
461
+
455
462
  /** Drop measurements, sessions and marks */
456
463
  clear(): void;
457
464
 
@@ -465,7 +472,9 @@ export class PerformanceProfiler {
465
472
  export function createProfiler(options?: ProfilerOptions): PerformanceProfiler;
466
473
 
467
474
  /**
468
- * Time an async function. Rejects with `{ error, duration }` when `fn` throws.
475
+ * Time a (possibly async) function with `profiler`, or an enabled ad-hoc one.
476
+ * When `fn` throws, rejects with that Error (non-Error values are wrapped,
477
+ * the original kept as `cause`) carrying a `duration` property.
469
478
  */
470
479
  export function measure<T>(
471
480
  name: string,
@@ -473,24 +482,65 @@ export function measure<T>(
473
482
  profiler?: PerformanceProfiler | null
474
483
  ): Promise<{ value: T; duration: number }>;
475
484
 
476
- /** Wrap a function so calls to it can be profiled. */
477
- export function profile<F extends (...args: never[]) => unknown>(fn: F): F;
485
+ export interface ProfileOptions {
486
+ /** Profiler to record into; an enabled one is created when omitted */
487
+ profiler?: PerformanceProfiler;
488
+ /** Measurement name; defaults to the function's name */
489
+ name?: string;
490
+ }
491
+
492
+ /**
493
+ * Wrap a function so every call (sync or async) is recorded as a render
494
+ * measurement on `wrapped.profiler`.
495
+ */
496
+ export function profile<F extends (...args: never[]) => unknown>(
497
+ fn: F,
498
+ options?: PerformanceProfiler | ProfileOptions
499
+ ): F & { profiler: PerformanceProfiler };
478
500
 
479
501
  // ============================================================================
480
502
  // DevTools
481
503
  // ============================================================================
482
504
 
505
+ export interface DevToolsOptions {
506
+ /** Force on or off; defaults to `shouldEnable()` */
507
+ enabled?: boolean;
508
+ /** Cap on retained warnings and errors each; defaults to `100` */
509
+ maxEntries?: number;
510
+ /** Record console.error calls; defaults to `true` */
511
+ captureConsoleErrors?: boolean;
512
+ /**
513
+ * Record unhandled promise rejections (Node). They still crash the process
514
+ * as they would without DevTools. Defaults to `false`.
515
+ */
516
+ trackUnhandledRejections?: boolean;
517
+ /** Browser only: hot-reload WebSocket URL; no connection is made without it */
518
+ hotReloadUrl?: string | null;
519
+ /** Expose `$inspect`, `$history`, … on `globalThis`; defaults to `true` */
520
+ globalHelpers?: boolean;
521
+ }
522
+
523
+ /** The part of a Coherent instance DevTools uses, e.g. `import * as coherent from '@coherent.js/core'`. */
524
+ export interface DevToolsTarget {
525
+ render?: (component: unknown, context?: Record<string, unknown>, options?: Record<string, unknown>) => string;
526
+ createComponent?: (config: Record<string, unknown>) => unknown;
527
+ cache?: unknown;
528
+ }
529
+
483
530
  /**
484
- * Development-only instrumentation: render interception, validation, hot
531
+ * Development-only instrumentation: render timing, validation, optional hot
485
532
  * reload and a browser panel.
486
533
  *
487
- * Enabled only when `NODE_ENV=development`, or on localhost / `?dev=true` in
488
- * a browser. `isEnabled` is a property, not a method.
534
+ * Enabled when `NODE_ENV=development`, or on a localhost page in a browser;
535
+ * anything else needs `{ enabled: true }`. It never mutates the instance it
536
+ * wraps — render through {@link DevTools.render}. `isEnabled` is a property,
537
+ * not a method.
489
538
  */
490
539
  export class DevTools {
491
- constructor(coherentInstance?: unknown);
540
+ constructor(coherentInstance?: DevToolsTarget | null, options?: DevToolsOptions);
492
541
 
493
- coherent: unknown;
542
+ coherent: DevToolsTarget | null;
543
+ options: Required<Omit<DevToolsOptions, 'enabled' | 'hotReloadUrl'>> & DevToolsOptions;
494
544
  /** Whether instrumentation is active in this environment */
495
545
  isEnabled: boolean;
496
546
  renderHistory: unknown[];
@@ -505,6 +555,18 @@ export class DevTools {
505
555
  /** Install every hook; called by the constructor when enabled */
506
556
  initialize(): void;
507
557
 
558
+ /** Remove everything `initialize()` installed */
559
+ destroy(): void;
560
+
561
+ /** Append to a bounded list (warnings, errors), dropping the oldest */
562
+ record<T>(list: T[], entry: T): T;
563
+
564
+ /** Render through the wrapped instance, recording timing and warnings */
565
+ render(component: unknown, context?: Record<string, unknown>, options?: Record<string, unknown>): string;
566
+
567
+ /** The wrapped instance's `createComponent()`, registering the result */
568
+ createComponent(config: Record<string, unknown>): unknown;
569
+
508
570
  /** Report a component's type, structure and props */
509
571
  inspectComponent(component: unknown): Record<string, unknown>;
510
572
 
@@ -537,7 +599,7 @@ export class DevTools {
537
599
  }
538
600
 
539
601
  /** Create a {@link DevTools} instance bound to a Coherent instance. */
540
- export function createDevTools(coherentInstance?: unknown): DevTools;
602
+ export function createDevTools(coherentInstance?: DevToolsTarget | null, options?: DevToolsOptions): DevTools;
541
603
 
542
604
  // ============================================================================
543
605
  // Component Visualizer