@concavejs/devtools 0.0.1-alpha.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.
Potentially problematic release.
This version of @concavejs/devtools might be problematic. Click here for more details.
- package/README.md +263 -0
- package/dist/client-D6NyDOCN.js +2781 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +5 -0
- package/dist/extension/page-agent.d.ts +8 -0
- package/dist/extension/panel.d.ts +14 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +380 -0
- package/dist/interceptor/index.d.ts +5 -0
- package/dist/interceptor/websocket-interceptor.d.ts +67 -0
- package/dist/overlay/ActivityPanel.d.ts +10 -0
- package/dist/overlay/ContextMenu.d.ts +23 -0
- package/dist/overlay/DataInspector.d.ts +12 -0
- package/dist/overlay/DevToolbar.d.ts +11 -0
- package/dist/overlay/LogsPanel.d.ts +10 -0
- package/dist/overlay/NetworkPanel.d.ts +9 -0
- package/dist/overlay/PerformancePanel.d.ts +10 -0
- package/dist/overlay/SearchField.d.ts +9 -0
- package/dist/overlay/SettingsPanel.d.ts +9 -0
- package/dist/overlay/SubscriptionsPanel.d.ts +9 -0
- package/dist/overlay/TimelinePanel.d.ts +9 -0
- package/dist/overlay/utils.d.ts +16 -0
- package/dist/standalone.d.ts +11 -0
- package/dist/store/event-store.d.ts +165 -0
- package/dist/store/safe-storage.d.ts +7 -0
- package/dist/types.d.ts +146 -0
- package/dist/version.d.ts +10 -0
- package/dist/vite-plugin/index.d.ts +16 -0
- package/dist/vite-plugin.js +544 -0
- package/package.json +62 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
import s from "path";
|
|
2
|
+
import { fileURLToPath as m } from "url";
|
|
3
|
+
const g = s.dirname(m(import.meta.url));
|
|
4
|
+
function p(i = {}) {
|
|
5
|
+
const { enabled: a = !0, position: r = "bottom-right" } = i;
|
|
6
|
+
let t = !1;
|
|
7
|
+
return {
|
|
8
|
+
name: "concave-devtools",
|
|
9
|
+
configResolved(e) {
|
|
10
|
+
t = e.mode === "development";
|
|
11
|
+
},
|
|
12
|
+
transformIndexHtml: {
|
|
13
|
+
order: "pre",
|
|
14
|
+
handler(e) {
|
|
15
|
+
if (!t || !a)
|
|
16
|
+
return e;
|
|
17
|
+
const n = `
|
|
18
|
+
<script>
|
|
19
|
+
// Initialize event store immediately
|
|
20
|
+
(function() {
|
|
21
|
+
if (window.__concaveDevTools) return;
|
|
22
|
+
|
|
23
|
+
console.log('[DevTools] Installing WebSocket interceptor...');
|
|
24
|
+
|
|
25
|
+
// Minimal event store for capturing events
|
|
26
|
+
window.__concaveDevToolsEvents = [];
|
|
27
|
+
window.__concaveDevToolsPendingQueries = new Map();
|
|
28
|
+
window.__concaveDevToolsPendingMutations = new Map();
|
|
29
|
+
window.__concaveDevToolsPendingActions = new Map();
|
|
30
|
+
window.__concaveDevToolsPendingAuthTokenType = null;
|
|
31
|
+
|
|
32
|
+
const OriginalWebSocket = window.WebSocket;
|
|
33
|
+
|
|
34
|
+
const emitAuthEvent = (direction, messageType, status, details, error, tokenType) => {
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
window.__concaveDevToolsEvents.push({
|
|
37
|
+
id: 'auth-' + direction + '-' + messageType + '-' + now + '-' + Math.random().toString(36).slice(2, 8),
|
|
38
|
+
timestamp: now,
|
|
39
|
+
type: 'auth',
|
|
40
|
+
direction,
|
|
41
|
+
messageType,
|
|
42
|
+
status,
|
|
43
|
+
tokenType,
|
|
44
|
+
error,
|
|
45
|
+
details,
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const decodeJwtClaims = (token) => {
|
|
50
|
+
const parts = token.split('.');
|
|
51
|
+
if (parts.length < 2) return null;
|
|
52
|
+
try {
|
|
53
|
+
const normalized = parts[1].replace(/-/g, '+').replace(/_/g, '/');
|
|
54
|
+
const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);
|
|
55
|
+
const payload = JSON.parse(atob(padded));
|
|
56
|
+
const keys = ['iss', 'sub', 'aud', 'exp', 'iat', 'nbf'];
|
|
57
|
+
const claims = {};
|
|
58
|
+
keys.forEach((key) => {
|
|
59
|
+
if (payload[key] !== undefined) claims[key] = payload[key];
|
|
60
|
+
});
|
|
61
|
+
if (typeof claims.exp === 'number') claims.expIso = new Date(claims.exp * 1000).toISOString();
|
|
62
|
+
if (typeof claims.iat === 'number') claims.iatIso = new Date(claims.iat * 1000).toISOString();
|
|
63
|
+
return Object.keys(claims).length > 0 ? claims : null;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Create intercepted WebSocket constructor
|
|
70
|
+
window.WebSocket = function(url, protocols) {
|
|
71
|
+
const ws = new OriginalWebSocket(url, protocols);
|
|
72
|
+
|
|
73
|
+
// Intercept send
|
|
74
|
+
const originalSend = ws.send.bind(ws);
|
|
75
|
+
ws.send = function(data) {
|
|
76
|
+
if (typeof data === 'string') {
|
|
77
|
+
try {
|
|
78
|
+
const msg = JSON.parse(data);
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
|
|
81
|
+
if (msg.type === 'Connect') {
|
|
82
|
+
const connectDetails = {};
|
|
83
|
+
if (typeof msg.connectionCount === 'number') connectDetails.connectionCount = msg.connectionCount;
|
|
84
|
+
if (typeof msg.lastCloseReason === 'string') connectDetails.lastCloseReason = msg.lastCloseReason;
|
|
85
|
+
if (typeof msg.clientTs === 'number') connectDetails.clientTs = msg.clientTs;
|
|
86
|
+
if (typeof msg.sessionId === 'string') connectDetails.sessionId = msg.sessionId;
|
|
87
|
+
emitAuthEvent('client', 'Connect', 'success', connectDetails, undefined, undefined);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (msg.type === 'Authenticate') {
|
|
91
|
+
const authDetails = {};
|
|
92
|
+
if (typeof msg.baseVersion === 'number') authDetails.baseVersion = msg.baseVersion;
|
|
93
|
+
if (typeof msg.tokenType === 'string') authDetails.tokenType = msg.tokenType;
|
|
94
|
+
if (typeof msg.value === 'string' && msg.value.length > 0) {
|
|
95
|
+
authDetails.tokenLength = msg.value.length;
|
|
96
|
+
authDetails.tokenPreview = msg.value.length > 24
|
|
97
|
+
? msg.value.slice(0, 12) + '…' + msg.value.slice(-10)
|
|
98
|
+
: msg.value;
|
|
99
|
+
const claims = decodeJwtClaims(msg.value);
|
|
100
|
+
if (claims) authDetails.jwtClaims = claims;
|
|
101
|
+
}
|
|
102
|
+
window.__concaveDevToolsPendingAuthTokenType = msg.tokenType || 'Unknown';
|
|
103
|
+
emitAuthEvent('client', 'Authenticate', 'success', authDetails, undefined, msg.tokenType);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Track queries
|
|
107
|
+
if (msg.type === 'ModifyQuerySet' && msg.modifications) {
|
|
108
|
+
msg.modifications.forEach(mod => {
|
|
109
|
+
if (mod.type === 'Add') {
|
|
110
|
+
window.__concaveDevToolsPendingQueries.set(mod.queryId, {
|
|
111
|
+
queryId: mod.queryId,
|
|
112
|
+
udfPath: mod.udfPath,
|
|
113
|
+
args: mod.args,
|
|
114
|
+
componentPath: mod.componentPath,
|
|
115
|
+
startTime: now
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
window.__concaveDevToolsEvents.push({
|
|
119
|
+
id: 'sub-' + mod.queryId + '-' + now,
|
|
120
|
+
timestamp: now,
|
|
121
|
+
type: 'subscription',
|
|
122
|
+
queryId: mod.queryId,
|
|
123
|
+
udfPath: mod.udfPath,
|
|
124
|
+
args: mod.args,
|
|
125
|
+
componentPath: mod.componentPath,
|
|
126
|
+
status: 'added'
|
|
127
|
+
});
|
|
128
|
+
} else if (mod.type === 'Remove') {
|
|
129
|
+
const pending = window.__concaveDevToolsPendingQueries.get(mod.queryId);
|
|
130
|
+
window.__concaveDevToolsPendingQueries.delete(mod.queryId);
|
|
131
|
+
// Emit removed subscription if we have context
|
|
132
|
+
window.__concaveDevToolsEvents.push({
|
|
133
|
+
id: 'sub-' + mod.queryId + '-' + now,
|
|
134
|
+
timestamp: now,
|
|
135
|
+
type: 'subscription',
|
|
136
|
+
queryId: mod.queryId,
|
|
137
|
+
udfPath: pending ? pending.udfPath : 'unknown',
|
|
138
|
+
args: pending ? pending.args : [],
|
|
139
|
+
componentPath: pending ? pending.componentPath : undefined,
|
|
140
|
+
status: 'removed'
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Track mutations
|
|
147
|
+
if (msg.type === 'Mutation') {
|
|
148
|
+
window.__concaveDevToolsPendingMutations.set(msg.requestId, {
|
|
149
|
+
requestId: msg.requestId,
|
|
150
|
+
udfPath: msg.udfPath,
|
|
151
|
+
args: msg.args,
|
|
152
|
+
componentPath: msg.componentPath,
|
|
153
|
+
startTime: now
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Track actions
|
|
158
|
+
if (msg.type === 'Action') {
|
|
159
|
+
window.__concaveDevToolsPendingActions.set(msg.requestId, {
|
|
160
|
+
requestId: msg.requestId,
|
|
161
|
+
udfPath: msg.udfPath,
|
|
162
|
+
args: msg.args,
|
|
163
|
+
componentPath: msg.componentPath,
|
|
164
|
+
startTime: now
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.warn('[DevTools] Error parsing client message:', e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return originalSend(data);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Intercept message handler
|
|
175
|
+
const originalAddEventListener = ws.addEventListener.bind(ws);
|
|
176
|
+
ws.addEventListener = function(type, listener, options) {
|
|
177
|
+
if (type === 'message' && typeof listener === 'function') {
|
|
178
|
+
const wrappedListener = function(event) {
|
|
179
|
+
try {
|
|
180
|
+
const msg = JSON.parse(event.data);
|
|
181
|
+
const now = Date.now();
|
|
182
|
+
|
|
183
|
+
if (msg.type === 'AuthError') {
|
|
184
|
+
const errorDetails = {};
|
|
185
|
+
if (typeof msg.baseVersion === 'number') errorDetails.baseVersion = msg.baseVersion;
|
|
186
|
+
if (typeof msg.authUpdateAttempted === 'boolean') errorDetails.authUpdateAttempted = msg.authUpdateAttempted;
|
|
187
|
+
emitAuthEvent('server', 'AuthError', 'error', errorDetails, msg.error || 'Authentication failed', window.__concaveDevToolsPendingAuthTokenType || undefined);
|
|
188
|
+
window.__concaveDevToolsPendingAuthTokenType = null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Handle transitions (query updates)
|
|
192
|
+
if (msg.type === 'Transition' && msg.modifications) {
|
|
193
|
+
if (window.__concaveDevToolsPendingAuthTokenType) {
|
|
194
|
+
emitAuthEvent(
|
|
195
|
+
'server',
|
|
196
|
+
'Authenticated',
|
|
197
|
+
'success',
|
|
198
|
+
{ modificationCount: msg.modifications.length },
|
|
199
|
+
undefined,
|
|
200
|
+
window.__concaveDevToolsPendingAuthTokenType
|
|
201
|
+
);
|
|
202
|
+
window.__concaveDevToolsPendingAuthTokenType = null;
|
|
203
|
+
}
|
|
204
|
+
msg.modifications.forEach(mod => {
|
|
205
|
+
if (mod.type === 'QueryUpdated' || mod.type === 'QueryFailed') {
|
|
206
|
+
const pending = window.__concaveDevToolsPendingQueries.get(mod.queryId);
|
|
207
|
+
if (pending) {
|
|
208
|
+
const duration = now - pending.startTime;
|
|
209
|
+
window.__concaveDevToolsEvents.push({
|
|
210
|
+
id: 'query-' + mod.queryId + '-' + now,
|
|
211
|
+
timestamp: now,
|
|
212
|
+
type: 'query',
|
|
213
|
+
queryId: mod.queryId,
|
|
214
|
+
udfPath: pending.udfPath,
|
|
215
|
+
args: pending.args,
|
|
216
|
+
componentPath: pending.componentPath,
|
|
217
|
+
status: mod.type === 'QueryUpdated' ? 'success' : 'error',
|
|
218
|
+
result: mod.type === 'QueryUpdated' ? mod.value : undefined,
|
|
219
|
+
error: mod.type === 'QueryFailed' ? mod.errorMessage : undefined,
|
|
220
|
+
logLines: mod.logLines,
|
|
221
|
+
duration: duration
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Extract log events
|
|
225
|
+
if (mod.logLines && mod.logLines.length > 0) {
|
|
226
|
+
mod.logLines.forEach(logLine => {
|
|
227
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
228
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
229
|
+
const message = match ? match[2] : logLine;
|
|
230
|
+
window.__concaveDevToolsEvents.push({
|
|
231
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
232
|
+
timestamp: now,
|
|
233
|
+
type: 'log',
|
|
234
|
+
level: level,
|
|
235
|
+
message: message,
|
|
236
|
+
relatedEventId: 'query-' + mod.queryId + '-' + now
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Handle mutation responses
|
|
246
|
+
if (msg.type === 'MutationResponse') {
|
|
247
|
+
const pending = window.__concaveDevToolsPendingMutations.get(msg.requestId);
|
|
248
|
+
if (pending) {
|
|
249
|
+
const duration = now - pending.startTime;
|
|
250
|
+
window.__concaveDevToolsEvents.push({
|
|
251
|
+
id: 'mutation-' + msg.requestId + '-' + now,
|
|
252
|
+
timestamp: now,
|
|
253
|
+
type: 'mutation',
|
|
254
|
+
requestId: msg.requestId,
|
|
255
|
+
udfPath: pending.udfPath,
|
|
256
|
+
args: pending.args,
|
|
257
|
+
componentPath: pending.componentPath,
|
|
258
|
+
status: msg.success ? 'success' : 'error',
|
|
259
|
+
result: msg.success ? msg.result : undefined,
|
|
260
|
+
error: !msg.success ? msg.result : undefined,
|
|
261
|
+
logLines: msg.logLines,
|
|
262
|
+
duration: duration
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Extract log events
|
|
266
|
+
if (msg.logLines && msg.logLines.length > 0) {
|
|
267
|
+
msg.logLines.forEach(logLine => {
|
|
268
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
269
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
270
|
+
const message = match ? match[2] : logLine;
|
|
271
|
+
window.__concaveDevToolsEvents.push({
|
|
272
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
273
|
+
timestamp: now,
|
|
274
|
+
type: 'log',
|
|
275
|
+
level: level,
|
|
276
|
+
message: message,
|
|
277
|
+
relatedEventId: 'mutation-' + msg.requestId + '-' + now
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
window.__concaveDevToolsPendingMutations.delete(msg.requestId);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Handle action responses
|
|
287
|
+
if (msg.type === 'ActionResponse') {
|
|
288
|
+
const pending = window.__concaveDevToolsPendingActions.get(msg.requestId);
|
|
289
|
+
if (pending) {
|
|
290
|
+
const duration = now - pending.startTime;
|
|
291
|
+
window.__concaveDevToolsEvents.push({
|
|
292
|
+
id: 'action-' + msg.requestId + '-' + now,
|
|
293
|
+
timestamp: now,
|
|
294
|
+
type: 'action',
|
|
295
|
+
requestId: msg.requestId,
|
|
296
|
+
udfPath: pending.udfPath,
|
|
297
|
+
args: pending.args,
|
|
298
|
+
componentPath: pending.componentPath,
|
|
299
|
+
status: msg.success ? 'success' : 'error',
|
|
300
|
+
result: msg.success ? msg.result : undefined,
|
|
301
|
+
error: !msg.success ? msg.result : undefined,
|
|
302
|
+
logLines: msg.logLines,
|
|
303
|
+
duration: duration
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Extract log events
|
|
307
|
+
if (msg.logLines && msg.logLines.length > 0) {
|
|
308
|
+
msg.logLines.forEach(logLine => {
|
|
309
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
310
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
311
|
+
const message = match ? match[2] : logLine;
|
|
312
|
+
window.__concaveDevToolsEvents.push({
|
|
313
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
314
|
+
timestamp: now,
|
|
315
|
+
type: 'log',
|
|
316
|
+
level: level,
|
|
317
|
+
message: message,
|
|
318
|
+
relatedEventId: 'action-' + msg.requestId + '-' + now
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
window.__concaveDevToolsPendingActions.delete(msg.requestId);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
} catch (e) {
|
|
327
|
+
console.warn('[DevTools] Error parsing server message:', e);
|
|
328
|
+
}
|
|
329
|
+
return listener(event);
|
|
330
|
+
};
|
|
331
|
+
return originalAddEventListener('message', wrappedListener, options);
|
|
332
|
+
}
|
|
333
|
+
return originalAddEventListener(type, listener, options);
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// Intercept onmessage assignment as well
|
|
337
|
+
(function(){
|
|
338
|
+
let currentHandler = null;
|
|
339
|
+
Object.defineProperty(ws, 'onmessage', {
|
|
340
|
+
configurable: true,
|
|
341
|
+
enumerable: true,
|
|
342
|
+
get() {
|
|
343
|
+
return currentHandler;
|
|
344
|
+
},
|
|
345
|
+
set(handler) {
|
|
346
|
+
// Remove previous wrapper if present
|
|
347
|
+
if ((ws).__concaveOnMessageWrapper) {
|
|
348
|
+
ws.removeEventListener('message', (ws).__concaveOnMessageWrapper);
|
|
349
|
+
}
|
|
350
|
+
currentHandler = handler;
|
|
351
|
+
if (typeof handler === 'function') {
|
|
352
|
+
const wrapper = function(event) {
|
|
353
|
+
try {
|
|
354
|
+
const msg = JSON.parse(event.data);
|
|
355
|
+
const now = Date.now();
|
|
356
|
+
|
|
357
|
+
if (msg.type === 'AuthError') {
|
|
358
|
+
const errorDetails = {};
|
|
359
|
+
if (typeof msg.baseVersion === 'number') errorDetails.baseVersion = msg.baseVersion;
|
|
360
|
+
if (typeof msg.authUpdateAttempted === 'boolean') errorDetails.authUpdateAttempted = msg.authUpdateAttempted;
|
|
361
|
+
emitAuthEvent('server', 'AuthError', 'error', errorDetails, msg.error || 'Authentication failed', window.__concaveDevToolsPendingAuthTokenType || undefined);
|
|
362
|
+
window.__concaveDevToolsPendingAuthTokenType = null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Mirror the same processing as in addEventListener wrapper
|
|
366
|
+
if (msg.type === 'Transition' && msg.modifications) {
|
|
367
|
+
if (window.__concaveDevToolsPendingAuthTokenType) {
|
|
368
|
+
emitAuthEvent(
|
|
369
|
+
'server',
|
|
370
|
+
'Authenticated',
|
|
371
|
+
'success',
|
|
372
|
+
{ modificationCount: msg.modifications.length },
|
|
373
|
+
undefined,
|
|
374
|
+
window.__concaveDevToolsPendingAuthTokenType
|
|
375
|
+
);
|
|
376
|
+
window.__concaveDevToolsPendingAuthTokenType = null;
|
|
377
|
+
}
|
|
378
|
+
msg.modifications.forEach(mod => {
|
|
379
|
+
if (mod.type === 'QueryUpdated' || mod.type === 'QueryFailed') {
|
|
380
|
+
const pending = window.__concaveDevToolsPendingQueries.get(mod.queryId);
|
|
381
|
+
if (pending) {
|
|
382
|
+
const duration = now - pending.startTime;
|
|
383
|
+
window.__concaveDevToolsEvents.push({
|
|
384
|
+
id: 'query-' + mod.queryId + '-' + now,
|
|
385
|
+
timestamp: now,
|
|
386
|
+
type: 'query',
|
|
387
|
+
queryId: mod.queryId,
|
|
388
|
+
udfPath: pending.udfPath,
|
|
389
|
+
args: pending.args,
|
|
390
|
+
componentPath: pending.componentPath,
|
|
391
|
+
status: mod.type === 'QueryUpdated' ? 'success' : 'error',
|
|
392
|
+
result: mod.type === 'QueryUpdated' ? mod.value : undefined,
|
|
393
|
+
error: mod.type === 'QueryFailed' ? mod.errorMessage : undefined,
|
|
394
|
+
logLines: mod.logLines,
|
|
395
|
+
duration: duration
|
|
396
|
+
});
|
|
397
|
+
if (mod.logLines && mod.logLines.length > 0) {
|
|
398
|
+
mod.logLines.forEach(logLine => {
|
|
399
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
400
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
401
|
+
const message = match ? match[2] : logLine;
|
|
402
|
+
window.__concaveDevToolsEvents.push({
|
|
403
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
404
|
+
timestamp: now,
|
|
405
|
+
type: 'log',
|
|
406
|
+
level: level,
|
|
407
|
+
message: message,
|
|
408
|
+
relatedEventId: 'query-' + mod.queryId + '-' + now
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
if (msg.type === 'MutationResponse') {
|
|
417
|
+
const pending = window.__concaveDevToolsPendingMutations.get(msg.requestId);
|
|
418
|
+
if (pending) {
|
|
419
|
+
const duration = now - pending.startTime;
|
|
420
|
+
window.__concaveDevToolsEvents.push({
|
|
421
|
+
id: 'mutation-' + msg.requestId + '-' + now,
|
|
422
|
+
timestamp: now,
|
|
423
|
+
type: 'mutation',
|
|
424
|
+
requestId: msg.requestId,
|
|
425
|
+
udfPath: pending.udfPath,
|
|
426
|
+
args: pending.args,
|
|
427
|
+
componentPath: pending.componentPath,
|
|
428
|
+
status: msg.success ? 'success' : 'error',
|
|
429
|
+
result: msg.success ? msg.result : undefined,
|
|
430
|
+
error: !msg.success ? msg.result : undefined,
|
|
431
|
+
logLines: msg.logLines,
|
|
432
|
+
duration: duration
|
|
433
|
+
});
|
|
434
|
+
if (msg.logLines && msg.logLines.length > 0) {
|
|
435
|
+
msg.logLines.forEach(logLine => {
|
|
436
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
437
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
438
|
+
const message = match ? match[2] : logLine;
|
|
439
|
+
window.__concaveDevToolsEvents.push({
|
|
440
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
441
|
+
timestamp: now,
|
|
442
|
+
type: 'log',
|
|
443
|
+
level: level,
|
|
444
|
+
message: message,
|
|
445
|
+
relatedEventId: 'mutation-' + msg.requestId + '-' + now
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
window.__concaveDevToolsPendingMutations.delete(msg.requestId);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (msg.type === 'ActionResponse') {
|
|
453
|
+
const pending = window.__concaveDevToolsPendingActions.get(msg.requestId);
|
|
454
|
+
if (pending) {
|
|
455
|
+
const duration = now - pending.startTime;
|
|
456
|
+
window.__concaveDevToolsEvents.push({
|
|
457
|
+
id: 'action-' + msg.requestId + '-' + now,
|
|
458
|
+
timestamp: now,
|
|
459
|
+
type: 'action',
|
|
460
|
+
requestId: msg.requestId,
|
|
461
|
+
udfPath: pending.udfPath,
|
|
462
|
+
args: pending.args,
|
|
463
|
+
componentPath: pending.componentPath,
|
|
464
|
+
status: msg.success ? 'success' : 'error',
|
|
465
|
+
result: msg.success ? msg.result : undefined,
|
|
466
|
+
error: !msg.success ? msg.result : undefined,
|
|
467
|
+
logLines: msg.logLines,
|
|
468
|
+
duration: duration
|
|
469
|
+
});
|
|
470
|
+
if (msg.logLines && msg.logLines.length > 0) {
|
|
471
|
+
msg.logLines.forEach(logLine => {
|
|
472
|
+
const match = logLine.match(/^\\[(log|info|warn|error)\\]\\s+(.+)$/i);
|
|
473
|
+
const level = match ? match[1].toLowerCase() : 'log';
|
|
474
|
+
const message = match ? match[2] : logLine;
|
|
475
|
+
window.__concaveDevToolsEvents.push({
|
|
476
|
+
id: 'log-' + now + '-' + Math.random(),
|
|
477
|
+
timestamp: now,
|
|
478
|
+
type: 'log',
|
|
479
|
+
level: level,
|
|
480
|
+
message: message,
|
|
481
|
+
relatedEventId: 'action-' + msg.requestId + '-' + now
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
window.__concaveDevToolsPendingActions.delete(msg.requestId);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
} catch (e) {
|
|
489
|
+
console.warn('[DevTools] Error parsing server message (onmessage):', e);
|
|
490
|
+
}
|
|
491
|
+
if (typeof handler === 'function') {
|
|
492
|
+
handler.call(ws, event);
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
(ws).__concaveOnMessageWrapper = wrapper;
|
|
496
|
+
ws.addEventListener('message', wrapper);
|
|
497
|
+
} else {
|
|
498
|
+
(ws).__concaveOnMessageWrapper = null;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
})();
|
|
503
|
+
|
|
504
|
+
return ws;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
// Preserve prototype chain
|
|
508
|
+
Object.setPrototypeOf(window.WebSocket, OriginalWebSocket);
|
|
509
|
+
Object.defineProperty(window.WebSocket, 'prototype', {
|
|
510
|
+
value: OriginalWebSocket.prototype,
|
|
511
|
+
writable: false,
|
|
512
|
+
configurable: false
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
console.log('[DevTools] WebSocket interceptor installed');
|
|
516
|
+
})();
|
|
517
|
+
<\/script>
|
|
518
|
+
`, d = `
|
|
519
|
+
<script>
|
|
520
|
+
window.__concaveDevToolsConfig = ${JSON.stringify({ position: r, autoInit: !0 })};
|
|
521
|
+
<\/script>
|
|
522
|
+
`, c = `
|
|
523
|
+
<script type="module">
|
|
524
|
+
import { initDevTools } from '/@fs${s.resolve(g, "../client.tsx").replace(/\\/g, "/")}';
|
|
525
|
+
<\/script>
|
|
526
|
+
`, o = n + d + c;
|
|
527
|
+
return e.includes("</head>") ? e.replace("</head>", `${o}</head>`) : e.includes("</body>") ? e.replace("</body>", `${o}</body>`) : e + o;
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
// Ensure devtools dependencies are optimized
|
|
531
|
+
config(e) {
|
|
532
|
+
var n;
|
|
533
|
+
return {
|
|
534
|
+
optimizeDeps: {
|
|
535
|
+
include: [...((n = e.optimizeDeps) == null ? void 0 : n.include) || [], "react", "react-dom"]
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
export {
|
|
542
|
+
p as concaveDevTools,
|
|
543
|
+
p as default
|
|
544
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@concavejs/devtools",
|
|
3
|
+
"version": "0.0.1-alpha.4",
|
|
4
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./vite": {
|
|
17
|
+
"types": "./dist/vite-plugin/index.d.ts",
|
|
18
|
+
"default": "./dist/vite-plugin.js"
|
|
19
|
+
},
|
|
20
|
+
"./client": {
|
|
21
|
+
"types": "./dist/client.d.ts",
|
|
22
|
+
"default": "./dist/client.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"sync:version": "node scripts/sync-extension-version.mjs",
|
|
30
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
31
|
+
"build:standalone": "vite build --config vite.config.standalone.ts",
|
|
32
|
+
"build:page-agent": "vite build --config vite.config.page-agent.ts",
|
|
33
|
+
"build:panel": "vite build --config vite.config.panel.ts",
|
|
34
|
+
"build:extension": "bun run sync:version && bun run build:standalone && cp dist-standalone/devtools.js extension/devtools.js && bun run build:panel",
|
|
35
|
+
"build:all": "bun run build && bun run build:extension",
|
|
36
|
+
"sync:icons": "cp ../brand/assets/icon-16.png extension/icons/icon16.png && cp ../brand/assets/icon-48.png extension/icons/icon48.png && cp ../brand/assets/icon-128.png extension/icons/icon128.png",
|
|
37
|
+
"dev": "tsc --watch",
|
|
38
|
+
"type-check": "tsc --noEmit"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@concavejs/brand": "0.0.1-alpha.4",
|
|
42
|
+
"@concavejs/core": "0.0.1-alpha.4"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": "^18.0.0",
|
|
46
|
+
"react-dom": "^18.0.0",
|
|
47
|
+
"vite": "^5.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"@types/react": "^18.2.0",
|
|
53
|
+
"@types/react-dom": "^18.2.0",
|
|
54
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
55
|
+
"react": "^18.2.0",
|
|
56
|
+
"react-dom": "^18.2.0",
|
|
57
|
+
"tailwindcss": "^4.1.18",
|
|
58
|
+
"terser": "^5.46.0",
|
|
59
|
+
"typescript": "^5.3.0",
|
|
60
|
+
"vite": "^5.0.0"
|
|
61
|
+
}
|
|
62
|
+
}
|