@tontoko/fast-playwright-mcp 0.0.4
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/LICENSE +202 -0
- package/README.md +1047 -0
- package/cli.js +18 -0
- package/config.d.ts +124 -0
- package/index.d.ts +25 -0
- package/index.js +18 -0
- package/lib/actions.d.js +0 -0
- package/lib/batch/batch-executor.js +137 -0
- package/lib/browser-context-factory.js +252 -0
- package/lib/browser-server-backend.js +139 -0
- package/lib/config/constants.js +80 -0
- package/lib/config.js +405 -0
- package/lib/context.js +274 -0
- package/lib/diagnostics/common/diagnostic-base.js +63 -0
- package/lib/diagnostics/common/error-enrichment-utils.js +212 -0
- package/lib/diagnostics/common/index.js +56 -0
- package/lib/diagnostics/common/initialization-manager.js +210 -0
- package/lib/diagnostics/common/performance-tracker.js +132 -0
- package/lib/diagnostics/diagnostic-error.js +140 -0
- package/lib/diagnostics/diagnostic-level.js +123 -0
- package/lib/diagnostics/diagnostic-thresholds.js +347 -0
- package/lib/diagnostics/element-discovery.js +441 -0
- package/lib/diagnostics/enhanced-error-handler.js +376 -0
- package/lib/diagnostics/error-enrichment.js +157 -0
- package/lib/diagnostics/frame-reference-manager.js +179 -0
- package/lib/diagnostics/page-analyzer.js +639 -0
- package/lib/diagnostics/parallel-page-analyzer.js +129 -0
- package/lib/diagnostics/resource-manager.js +134 -0
- package/lib/diagnostics/smart-config.js +482 -0
- package/lib/diagnostics/smart-handle.js +118 -0
- package/lib/diagnostics/unified-system.js +717 -0
- package/lib/extension/cdp-relay.js +486 -0
- package/lib/extension/extension-context-factory.js +74 -0
- package/lib/extension/main.js +41 -0
- package/lib/file-utils.js +42 -0
- package/lib/generate-keys.js +75 -0
- package/lib/http-server.js +50 -0
- package/lib/in-process-client.js +64 -0
- package/lib/index.js +48 -0
- package/lib/javascript.js +90 -0
- package/lib/log.js +33 -0
- package/lib/loop/loop-claude.js +247 -0
- package/lib/loop/loop-open-ai.js +222 -0
- package/lib/loop/loop.js +174 -0
- package/lib/loop/main.js +46 -0
- package/lib/loopTools/context.js +76 -0
- package/lib/loopTools/main.js +65 -0
- package/lib/loopTools/perform.js +40 -0
- package/lib/loopTools/snapshot.js +37 -0
- package/lib/loopTools/tool.js +26 -0
- package/lib/manual-promise.js +125 -0
- package/lib/mcp/in-process-transport.js +91 -0
- package/lib/mcp/proxy-backend.js +127 -0
- package/lib/mcp/server.js +123 -0
- package/lib/mcp/transport.js +159 -0
- package/lib/package.js +28 -0
- package/lib/program.js +82 -0
- package/lib/response.js +493 -0
- package/lib/schemas/expectation.js +152 -0
- package/lib/session-log.js +210 -0
- package/lib/tab.js +417 -0
- package/lib/tools/base-tool-handler.js +141 -0
- package/lib/tools/batch-execute.js +150 -0
- package/lib/tools/common.js +65 -0
- package/lib/tools/console.js +60 -0
- package/lib/tools/diagnose/diagnose-analysis-runner.js +101 -0
- package/lib/tools/diagnose/diagnose-config-handler.js +130 -0
- package/lib/tools/diagnose/diagnose-report-builder.js +394 -0
- package/lib/tools/diagnose.js +147 -0
- package/lib/tools/dialogs.js +57 -0
- package/lib/tools/evaluate.js +67 -0
- package/lib/tools/files.js +53 -0
- package/lib/tools/find-elements.js +307 -0
- package/lib/tools/install.js +60 -0
- package/lib/tools/keyboard.js +93 -0
- package/lib/tools/mouse.js +110 -0
- package/lib/tools/navigate.js +82 -0
- package/lib/tools/network.js +50 -0
- package/lib/tools/pdf.js +46 -0
- package/lib/tools/screenshot.js +113 -0
- package/lib/tools/snapshot.js +158 -0
- package/lib/tools/tabs.js +97 -0
- package/lib/tools/tool.js +47 -0
- package/lib/tools/utils.js +131 -0
- package/lib/tools/wait.js +64 -0
- package/lib/tools.js +65 -0
- package/lib/types/batch.js +47 -0
- package/lib/types/diff.js +0 -0
- package/lib/types/performance.js +0 -0
- package/lib/types/threshold-base.js +0 -0
- package/lib/utils/array-utils.js +44 -0
- package/lib/utils/code-deduplication-utils.js +141 -0
- package/lib/utils/common-formatters.js +252 -0
- package/lib/utils/console-filter.js +64 -0
- package/lib/utils/diagnostic-report-utils.js +178 -0
- package/lib/utils/diff-formatter.js +126 -0
- package/lib/utils/disposable-manager.js +135 -0
- package/lib/utils/error-handler-middleware.js +77 -0
- package/lib/utils/image-processor.js +137 -0
- package/lib/utils/index.js +92 -0
- package/lib/utils/report-builder.js +189 -0
- package/lib/utils/request-logger.js +82 -0
- package/lib/utils/response-diff-detector.js +150 -0
- package/lib/utils/section-builder.js +62 -0
- package/lib/utils/tool-patterns.js +153 -0
- package/lib/utils.js +46 -0
- package/package.json +77 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/common/initialization-manager.ts
|
|
21
|
+
import { DiagnosticError } from "../diagnostic-error.js";
|
|
22
|
+
|
|
23
|
+
class InitializationManager {
|
|
24
|
+
isInitialized = false;
|
|
25
|
+
initializationPromise;
|
|
26
|
+
initializationError;
|
|
27
|
+
performanceTracker;
|
|
28
|
+
partiallyInitialized = [];
|
|
29
|
+
context;
|
|
30
|
+
constructor(context) {
|
|
31
|
+
this.context = context;
|
|
32
|
+
this.performanceTracker = context.performanceTracker;
|
|
33
|
+
}
|
|
34
|
+
async initialize(stages) {
|
|
35
|
+
if (this.isInitialized) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (this.initializationPromise) {
|
|
39
|
+
return this.initializationPromise;
|
|
40
|
+
}
|
|
41
|
+
if (this.initializationError) {
|
|
42
|
+
throw this.initializationError;
|
|
43
|
+
}
|
|
44
|
+
this.initializationPromise = this.performInitialization(stages);
|
|
45
|
+
try {
|
|
46
|
+
await this.initializationPromise;
|
|
47
|
+
this.isInitialized = true;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof DiagnosticError) {
|
|
50
|
+
this.initializationError = error;
|
|
51
|
+
} else {
|
|
52
|
+
const baseError = error instanceof Error ? error : new Error(String(error));
|
|
53
|
+
this.initializationError = new DiagnosticError(`Initialization failed: ${baseError.message}`, {
|
|
54
|
+
timestamp: Date.now(),
|
|
55
|
+
component: "InitializationManager",
|
|
56
|
+
operation: "initialize",
|
|
57
|
+
suggestions: [
|
|
58
|
+
"Check component dependencies",
|
|
59
|
+
"Verify all required services are available",
|
|
60
|
+
"Review initialization order"
|
|
61
|
+
],
|
|
62
|
+
context: {
|
|
63
|
+
componentName: this.context.componentName,
|
|
64
|
+
errorStage: "initialization"
|
|
65
|
+
}
|
|
66
|
+
}, baseError);
|
|
67
|
+
}
|
|
68
|
+
throw this.initializationError;
|
|
69
|
+
} finally {
|
|
70
|
+
this.initializationPromise = undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async performInitialization(stages) {
|
|
74
|
+
const completedStages = new Set;
|
|
75
|
+
try {
|
|
76
|
+
const executeStagesSequentially = async (index) => {
|
|
77
|
+
if (index >= stages.length) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const stage = stages[index];
|
|
81
|
+
await this.executeStage(stage, completedStages);
|
|
82
|
+
completedStages.add(stage.name);
|
|
83
|
+
await executeStagesSequentially(index + 1);
|
|
84
|
+
};
|
|
85
|
+
await executeStagesSequentially(0);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
await this.cleanupPartialInitialization();
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async executeStage(stage, completedStages) {
|
|
92
|
+
if (stage.dependencies) {
|
|
93
|
+
for (const dependency of stage.dependencies) {
|
|
94
|
+
if (!completedStages.has(dependency)) {
|
|
95
|
+
throw new Error(`Dependency '${dependency}' not satisfied for stage '${stage.name}'`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const executeWithTracking = async () => {
|
|
100
|
+
const executeComponentsSequentially = async (index) => {
|
|
101
|
+
if (index >= stage.components.length) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const componentInit = stage.components[index];
|
|
105
|
+
await this.executeWithRetry(componentInit, stage.retryCount ?? 1, stage.timeout);
|
|
106
|
+
await executeComponentsSequentially(index + 1);
|
|
107
|
+
};
|
|
108
|
+
await executeComponentsSequentially(0);
|
|
109
|
+
};
|
|
110
|
+
if (this.performanceTracker) {
|
|
111
|
+
await this.performanceTracker.trackOperation(`init-stage-${stage.name}`, this.context.componentName, executeWithTracking);
|
|
112
|
+
} else {
|
|
113
|
+
await executeWithTracking();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async executeWithRetry(operation, retryCount, timeout) {
|
|
117
|
+
const attemptOperation = async (attempt) => {
|
|
118
|
+
try {
|
|
119
|
+
if (timeout) {
|
|
120
|
+
await Promise.race([
|
|
121
|
+
operation(),
|
|
122
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Operation timeout after ${timeout}ms`)), timeout))
|
|
123
|
+
]);
|
|
124
|
+
} else {
|
|
125
|
+
await operation();
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
const lastError = error instanceof Error ? error : new Error(String(error));
|
|
130
|
+
if (attempt < retryCount) {
|
|
131
|
+
await this.delay(1000 * attempt);
|
|
132
|
+
return attemptOperation(attempt + 1);
|
|
133
|
+
}
|
|
134
|
+
throw lastError;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
await attemptOperation(1);
|
|
138
|
+
}
|
|
139
|
+
delay(ms) {
|
|
140
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
141
|
+
}
|
|
142
|
+
trackPartialInitialization(component) {
|
|
143
|
+
this.partiallyInitialized.push(component);
|
|
144
|
+
}
|
|
145
|
+
async cleanupPartialInitialization() {
|
|
146
|
+
const cleanupPromises = this.partiallyInitialized.map(async (component) => {
|
|
147
|
+
try {
|
|
148
|
+
await component.dispose();
|
|
149
|
+
} catch {}
|
|
150
|
+
});
|
|
151
|
+
await Promise.allSettled(cleanupPromises);
|
|
152
|
+
this.partiallyInitialized.length = 0;
|
|
153
|
+
}
|
|
154
|
+
getIsInitialized() {
|
|
155
|
+
return this.isInitialized;
|
|
156
|
+
}
|
|
157
|
+
getInitializationError() {
|
|
158
|
+
return this.initializationError;
|
|
159
|
+
}
|
|
160
|
+
reset() {
|
|
161
|
+
this.isInitialized = false;
|
|
162
|
+
this.initializationPromise = undefined;
|
|
163
|
+
this.initializationError = undefined;
|
|
164
|
+
this.partiallyInitialized.length = 0;
|
|
165
|
+
}
|
|
166
|
+
async dispose() {
|
|
167
|
+
if (this.initializationPromise) {
|
|
168
|
+
try {
|
|
169
|
+
await this.initializationPromise;
|
|
170
|
+
} catch {}
|
|
171
|
+
}
|
|
172
|
+
await this.cleanupPartialInitialization();
|
|
173
|
+
this.reset();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function createCoreStage(name, components) {
|
|
177
|
+
return {
|
|
178
|
+
name,
|
|
179
|
+
components,
|
|
180
|
+
timeout: 5000
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function createDependentStage(name, dependencies, components) {
|
|
184
|
+
return {
|
|
185
|
+
name,
|
|
186
|
+
dependencies,
|
|
187
|
+
components,
|
|
188
|
+
timeout: 1e4,
|
|
189
|
+
retryCount: 2
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function createAdvancedStage(name, components, additionalDependencies = []) {
|
|
193
|
+
return {
|
|
194
|
+
name,
|
|
195
|
+
dependencies: [
|
|
196
|
+
"core-infrastructure",
|
|
197
|
+
"page-dependent",
|
|
198
|
+
...additionalDependencies
|
|
199
|
+
],
|
|
200
|
+
components,
|
|
201
|
+
timeout: 15000,
|
|
202
|
+
retryCount: 1
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
createDependentStage,
|
|
207
|
+
createCoreStage,
|
|
208
|
+
createAdvancedStage,
|
|
209
|
+
InitializationManager
|
|
210
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/common/performance-tracker.ts
|
|
21
|
+
class PerformanceTracker {
|
|
22
|
+
metrics = [];
|
|
23
|
+
maxHistorySize;
|
|
24
|
+
constructor(maxHistorySize = 1000) {
|
|
25
|
+
this.maxHistorySize = maxHistorySize;
|
|
26
|
+
}
|
|
27
|
+
async trackOperation(operation, component, fn, metadata) {
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
const startMemory = process.memoryUsage().heapUsed;
|
|
30
|
+
let success = false;
|
|
31
|
+
let result;
|
|
32
|
+
try {
|
|
33
|
+
result = await fn();
|
|
34
|
+
success = true;
|
|
35
|
+
return {
|
|
36
|
+
result,
|
|
37
|
+
metric: this.recordMetric(operation, component, startTime, success, startMemory, metadata)
|
|
38
|
+
};
|
|
39
|
+
} catch (error) {
|
|
40
|
+
this.recordMetric(operation, component, startTime, success, startMemory, metadata);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
recordMetric(operation, component, startTime, success, startMemory, metadata) {
|
|
45
|
+
const executionTime = Date.now() - startTime;
|
|
46
|
+
const currentMemory = process.memoryUsage().heapUsed;
|
|
47
|
+
const metric = {
|
|
48
|
+
operation,
|
|
49
|
+
component,
|
|
50
|
+
executionTime,
|
|
51
|
+
timestamp: startTime,
|
|
52
|
+
success,
|
|
53
|
+
memoryUsage: currentMemory - startMemory,
|
|
54
|
+
metadata
|
|
55
|
+
};
|
|
56
|
+
this.addMetric(metric);
|
|
57
|
+
return metric;
|
|
58
|
+
}
|
|
59
|
+
addMetric(metric) {
|
|
60
|
+
this.metrics.push(metric);
|
|
61
|
+
if (this.metrics.length > this.maxHistorySize) {
|
|
62
|
+
const excessCount = this.metrics.length - this.maxHistorySize;
|
|
63
|
+
this.metrics.splice(0, excessCount);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
getOperationStats(operation, component) {
|
|
67
|
+
const relevantMetrics = this.metrics.filter((m) => m.operation === operation && (!component || m.component === component));
|
|
68
|
+
if (relevantMetrics.length === 0) {
|
|
69
|
+
return {
|
|
70
|
+
averageExecutionTime: 0,
|
|
71
|
+
minExecutionTime: 0,
|
|
72
|
+
maxExecutionTime: 0,
|
|
73
|
+
totalOperations: 0,
|
|
74
|
+
successRate: 1,
|
|
75
|
+
recentFailures: 0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const executionTimes = relevantMetrics.map((m) => m.executionTime);
|
|
79
|
+
const successCount = relevantMetrics.filter((m) => m.success).length;
|
|
80
|
+
const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
|
|
81
|
+
const recentFailures = relevantMetrics.filter((m) => !m.success && m.timestamp > fiveMinutesAgo).length;
|
|
82
|
+
return {
|
|
83
|
+
averageExecutionTime: executionTimes.reduce((sum, time) => sum + time, 0) / executionTimes.length,
|
|
84
|
+
minExecutionTime: Math.min(...executionTimes),
|
|
85
|
+
maxExecutionTime: Math.max(...executionTimes),
|
|
86
|
+
totalOperations: relevantMetrics.length,
|
|
87
|
+
successRate: successCount / relevantMetrics.length,
|
|
88
|
+
recentFailures
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
getAllStats() {
|
|
92
|
+
const operations = [...new Set(this.metrics.map((m) => m.operation))];
|
|
93
|
+
const stats = {};
|
|
94
|
+
for (const operation of operations) {
|
|
95
|
+
stats[operation] = this.getOperationStats(operation);
|
|
96
|
+
}
|
|
97
|
+
return stats;
|
|
98
|
+
}
|
|
99
|
+
getMetricsInRange(startTime, endTime, operation, component) {
|
|
100
|
+
return this.metrics.filter((m) => m.timestamp >= startTime && m.timestamp <= endTime && (!operation || m.operation === operation) && (!component || m.component === component));
|
|
101
|
+
}
|
|
102
|
+
clearMetrics() {
|
|
103
|
+
this.metrics.splice(0, this.metrics.length);
|
|
104
|
+
}
|
|
105
|
+
getRecentMetrics(limit = 50) {
|
|
106
|
+
return this.metrics.slice(-limit);
|
|
107
|
+
}
|
|
108
|
+
detectAnomalies(operation, threshold = 2) {
|
|
109
|
+
const stats = this.getOperationStats(operation);
|
|
110
|
+
const recentMetrics = this.getMetricsInRange(Date.now() - 10 * 60 * 1000, Date.now(), operation);
|
|
111
|
+
const slowOperations = recentMetrics.filter((m) => m.executionTime > stats.averageExecutionTime * threshold);
|
|
112
|
+
const recommendations = [];
|
|
113
|
+
if (slowOperations.length > 0) {
|
|
114
|
+
recommendations.push(`${slowOperations.length} slow operations detected for ${operation}`);
|
|
115
|
+
}
|
|
116
|
+
if (stats.successRate < 0.9) {
|
|
117
|
+
recommendations.push(`Low success rate (${(stats.successRate * 100).toFixed(1)}%) for ${operation}`);
|
|
118
|
+
}
|
|
119
|
+
if (stats.recentFailures > 3) {
|
|
120
|
+
recommendations.push(`${stats.recentFailures} recent failures detected for ${operation}`);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
slowOperations,
|
|
124
|
+
recommendations
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
var globalPerformanceTracker = new PerformanceTracker;
|
|
129
|
+
export {
|
|
130
|
+
globalPerformanceTracker,
|
|
131
|
+
PerformanceTracker
|
|
132
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/diagnostic-error.ts
|
|
21
|
+
var PERFORMANCE_IMPACT_LEVELS = ["low", "medium", "high"];
|
|
22
|
+
|
|
23
|
+
class DiagnosticError extends Error {
|
|
24
|
+
timestamp;
|
|
25
|
+
component;
|
|
26
|
+
operation;
|
|
27
|
+
originalError;
|
|
28
|
+
executionTime;
|
|
29
|
+
memoryUsage;
|
|
30
|
+
performanceImpact;
|
|
31
|
+
suggestions;
|
|
32
|
+
context;
|
|
33
|
+
constructor(message, context, originalError) {
|
|
34
|
+
const enhancedMessage = `[${context.component}:${context.operation}] ${message}`;
|
|
35
|
+
super(enhancedMessage);
|
|
36
|
+
this.name = "DiagnosticError";
|
|
37
|
+
this.timestamp = context.timestamp;
|
|
38
|
+
this.component = context.component;
|
|
39
|
+
this.operation = context.operation;
|
|
40
|
+
this.originalError = originalError;
|
|
41
|
+
this.executionTime = context.executionTime;
|
|
42
|
+
this.memoryUsage = context.memoryUsage;
|
|
43
|
+
this.performanceImpact = context.performanceImpact ?? "low";
|
|
44
|
+
this.suggestions = context.suggestions ?? [];
|
|
45
|
+
this.context = context.context;
|
|
46
|
+
if (Error.captureStackTrace) {
|
|
47
|
+
Error.captureStackTrace(this, DiagnosticError);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
static from(error, component, operation, additionalContext) {
|
|
51
|
+
return new DiagnosticError(error.message, {
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
component,
|
|
54
|
+
operation,
|
|
55
|
+
...additionalContext
|
|
56
|
+
}, error);
|
|
57
|
+
}
|
|
58
|
+
static performance(message, component, operation, executionTime, threshold) {
|
|
59
|
+
let impact;
|
|
60
|
+
if (executionTime > threshold * 3) {
|
|
61
|
+
impact = "high";
|
|
62
|
+
} else if (executionTime > threshold * 2) {
|
|
63
|
+
impact = "medium";
|
|
64
|
+
} else {
|
|
65
|
+
impact = "low";
|
|
66
|
+
}
|
|
67
|
+
return new DiagnosticError(`Performance issue: ${message} (${executionTime}ms > ${threshold}ms)`, {
|
|
68
|
+
timestamp: Date.now(),
|
|
69
|
+
component,
|
|
70
|
+
operation,
|
|
71
|
+
executionTime,
|
|
72
|
+
performanceImpact: impact,
|
|
73
|
+
suggestions: [
|
|
74
|
+
`Operation took longer than expected (${executionTime}ms vs ${threshold}ms threshold)`,
|
|
75
|
+
"Consider optimizing this operation or increasing timeout thresholds"
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
static resource(message, component, operation, memoryUsage, memoryLimit) {
|
|
80
|
+
let impact;
|
|
81
|
+
if (memoryUsage > memoryLimit * 2) {
|
|
82
|
+
impact = "high";
|
|
83
|
+
} else if (memoryUsage > memoryLimit * 1.5) {
|
|
84
|
+
impact = "medium";
|
|
85
|
+
} else {
|
|
86
|
+
impact = "low";
|
|
87
|
+
}
|
|
88
|
+
return new DiagnosticError(`Resource issue: ${message} (${(memoryUsage / 1024 / 1024).toFixed(2)}MB)`, {
|
|
89
|
+
timestamp: Date.now(),
|
|
90
|
+
component,
|
|
91
|
+
operation,
|
|
92
|
+
memoryUsage,
|
|
93
|
+
performanceImpact: impact,
|
|
94
|
+
suggestions: [
|
|
95
|
+
`Memory usage exceeded expectations (${(memoryUsage / 1024 / 1024).toFixed(2)}MB vs ${(memoryLimit / 1024 / 1024).toFixed(2)}MB limit)`,
|
|
96
|
+
"Consider enabling resource cleanup or reducing analysis scope"
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
toJSON() {
|
|
101
|
+
return {
|
|
102
|
+
name: this.name,
|
|
103
|
+
message: this.message,
|
|
104
|
+
timestamp: this.timestamp,
|
|
105
|
+
component: this.component,
|
|
106
|
+
operation: this.operation,
|
|
107
|
+
executionTime: this.executionTime,
|
|
108
|
+
memoryUsage: this.memoryUsage,
|
|
109
|
+
performanceImpact: this.performanceImpact,
|
|
110
|
+
suggestions: this.suggestions,
|
|
111
|
+
stack: this.stack,
|
|
112
|
+
originalError: this.originalError ? {
|
|
113
|
+
name: this.originalError.name,
|
|
114
|
+
message: this.originalError.message,
|
|
115
|
+
stack: this.originalError.stack
|
|
116
|
+
} : undefined
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
toString() {
|
|
120
|
+
const parts = [this.message];
|
|
121
|
+
if (this.executionTime !== undefined) {
|
|
122
|
+
parts.push(`Execution Time: ${this.executionTime}ms`);
|
|
123
|
+
}
|
|
124
|
+
if (this.memoryUsage !== undefined) {
|
|
125
|
+
parts.push(`Memory Usage: ${(this.memoryUsage / 1024 / 1024).toFixed(2)}MB`);
|
|
126
|
+
}
|
|
127
|
+
if (this.suggestions.length > 0) {
|
|
128
|
+
parts.push("Suggestions:");
|
|
129
|
+
for (const suggestion of this.suggestions) {
|
|
130
|
+
parts.push(` - ${suggestion}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return parts.join(`
|
|
134
|
+
`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
PERFORMANCE_IMPACT_LEVELS,
|
|
139
|
+
DiagnosticError
|
|
140
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/diagnostic-level.ts
|
|
21
|
+
var DiagnosticLevel = {
|
|
22
|
+
NONE: "none",
|
|
23
|
+
BASIC: "basic",
|
|
24
|
+
STANDARD: "standard",
|
|
25
|
+
DETAILED: "detailed",
|
|
26
|
+
FULL: "full"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
class DiagnosticLevelManager {
|
|
30
|
+
static defaultConfig = {
|
|
31
|
+
level: DiagnosticLevel.STANDARD,
|
|
32
|
+
features: undefined,
|
|
33
|
+
thresholds: {
|
|
34
|
+
maxDiagnosticTime: 300
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
config;
|
|
38
|
+
constructor(config) {
|
|
39
|
+
this.config = this.mergeConfig(config);
|
|
40
|
+
}
|
|
41
|
+
mergeConfig(partial) {
|
|
42
|
+
if (!partial) {
|
|
43
|
+
return { ...DiagnosticLevelManager.defaultConfig };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
level: partial.level ?? DiagnosticLevelManager.defaultConfig.level,
|
|
47
|
+
features: partial.features ? { ...partial.features } : undefined,
|
|
48
|
+
thresholds: {
|
|
49
|
+
...DiagnosticLevelManager.defaultConfig.thresholds,
|
|
50
|
+
...partial.thresholds
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
getMaxAlternatives() {
|
|
55
|
+
if (this.config.maxAlternatives !== undefined) {
|
|
56
|
+
return this.config.maxAlternatives;
|
|
57
|
+
}
|
|
58
|
+
if (this.config.thresholds?.maxAlternatives !== undefined) {
|
|
59
|
+
return this.config.thresholds.maxAlternatives;
|
|
60
|
+
}
|
|
61
|
+
switch (this.config.level) {
|
|
62
|
+
case DiagnosticLevel.NONE:
|
|
63
|
+
return 0;
|
|
64
|
+
case DiagnosticLevel.BASIC:
|
|
65
|
+
return 1;
|
|
66
|
+
case DiagnosticLevel.STANDARD:
|
|
67
|
+
return 5;
|
|
68
|
+
case DiagnosticLevel.DETAILED:
|
|
69
|
+
case DiagnosticLevel.FULL:
|
|
70
|
+
return 10;
|
|
71
|
+
default:
|
|
72
|
+
return 5;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
shouldSkipDiagnostics() {
|
|
76
|
+
return this.config.level === DiagnosticLevel.NONE;
|
|
77
|
+
}
|
|
78
|
+
getConfig() {
|
|
79
|
+
return { ...this.config };
|
|
80
|
+
}
|
|
81
|
+
updateConfig(partial) {
|
|
82
|
+
const updatedConfig = this.mergeConfig({ ...this.config, ...partial });
|
|
83
|
+
this.config = updatedConfig;
|
|
84
|
+
}
|
|
85
|
+
shouldEnableFeature(feature) {
|
|
86
|
+
if (feature === "alternativeSuggestions" && this.config.enableAlternativeSuggestions !== undefined) {
|
|
87
|
+
return this.config.enableAlternativeSuggestions;
|
|
88
|
+
}
|
|
89
|
+
if (feature === "pageAnalysis" && this.config.enablePageAnalysis !== undefined) {
|
|
90
|
+
return this.config.enablePageAnalysis;
|
|
91
|
+
}
|
|
92
|
+
if (feature === "performanceMetrics" && this.config.enablePerformanceMetrics !== undefined) {
|
|
93
|
+
return this.config.enablePerformanceMetrics;
|
|
94
|
+
}
|
|
95
|
+
if (this.config.features?.[feature] !== undefined) {
|
|
96
|
+
const featureValue = this.config.features[feature];
|
|
97
|
+
return featureValue ?? false;
|
|
98
|
+
}
|
|
99
|
+
switch (this.config.level) {
|
|
100
|
+
case DiagnosticLevel.NONE:
|
|
101
|
+
return false;
|
|
102
|
+
case DiagnosticLevel.BASIC:
|
|
103
|
+
return feature === "iframeDetection" || feature === "modalDetection";
|
|
104
|
+
case DiagnosticLevel.STANDARD:
|
|
105
|
+
return feature !== "performanceTracking" && feature !== "accessibilityAnalysis";
|
|
106
|
+
case DiagnosticLevel.DETAILED:
|
|
107
|
+
return feature !== "accessibilityAnalysis";
|
|
108
|
+
case DiagnosticLevel.FULL:
|
|
109
|
+
return true;
|
|
110
|
+
default:
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
getMaxDiagnosticTime() {
|
|
115
|
+
return this.config.thresholds?.maxDiagnosticTime ?? 300;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
var globalDiagnosticConfig = new DiagnosticLevelManager;
|
|
119
|
+
export {
|
|
120
|
+
globalDiagnosticConfig,
|
|
121
|
+
DiagnosticLevelManager,
|
|
122
|
+
DiagnosticLevel
|
|
123
|
+
};
|