tarojs-plugin-chucker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,529 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.Chucker = void 0;
40
+ const react_1 = __importStar(require("react"));
41
+ const taro_1 = __importDefault(require("@tarojs/taro"));
42
+ const components_1 = require("@tarojs/components");
43
+ const store_1 = require("../store");
44
+ const utils_1 = require("../utils");
45
+ const useVirtual_1 = require("../hooks/useVirtual");
46
+ const icons_1 = require("./icons");
47
+ const Chucker = () => {
48
+ const [isOpen, setIsOpen] = (0, react_1.useState)(true);
49
+ const [logs, setLogs] = (0, react_1.useState)([]);
50
+ const [searchQuery, setSearchQuery] = (0, react_1.useState)("");
51
+ const [filterType, setFilterType] = (0, react_1.useState)("all");
52
+ const [selectedLogId, setSelectedLogId] = (0, react_1.useState)(null);
53
+ const [activeDetailTab, setActiveDetailTab] = (0, react_1.useState)("overview");
54
+ // Subscribe to chuckerStore updates
55
+ (0, react_1.useEffect)(() => {
56
+ const unsubscribe = store_1.chuckerStore.subscribe((updatedLogs) => {
57
+ setLogs([...updatedLogs]);
58
+ });
59
+ return unsubscribe;
60
+ }, []);
61
+ // Filter logs based on search query and tab selection
62
+ const filteredLogs = (0, react_1.useMemo)(() => {
63
+ return logs.filter((log) => {
64
+ // 1. Filter by type
65
+ if (filterType === "network" && log.type !== "network")
66
+ return false;
67
+ if (filterType === "native" && log.type !== "native")
68
+ return false;
69
+ // 2. Filter by search query (URL or native plugin name)
70
+ if (!searchQuery)
71
+ return true;
72
+ const query = searchQuery.toLowerCase();
73
+ return (log.url.toLowerCase().includes(query) ||
74
+ (log.requestHeaders && JSON.stringify(log.requestHeaders).toLowerCase().includes(query)) ||
75
+ (log.requestData && JSON.stringify(log.requestData).toLowerCase().includes(query)));
76
+ });
77
+ }, [logs, searchQuery, filterType]);
78
+ // Virtualize the logs list to support huge list data
79
+ const { vlChunks, vlStyles } = (0, useVirtual_1.useVirtualList)({
80
+ items: filteredLogs,
81
+ itemHeight: 20,
82
+ chunkSize: 10,
83
+ disabled: !isOpen,
84
+ });
85
+ const selectedLog = (0, react_1.useMemo)(() => {
86
+ return logs.find((l) => l.id === selectedLogId) || null;
87
+ }, [logs, selectedLogId]);
88
+ // Statistics
89
+ const errorCount = (0, react_1.useMemo)(() => {
90
+ return logs.filter((log) => {
91
+ if (log.status === "fail")
92
+ return true;
93
+ if (typeof log.status === "number" && log.status >= 400)
94
+ return true;
95
+ return false;
96
+ }).length;
97
+ }, [logs]);
98
+ const handleClear = () => {
99
+ taro_1.default.showModal({
100
+ title: "Clear Logs",
101
+ content: "Are you sure you want to delete all logged requests?",
102
+ success: (res) => {
103
+ if (res.confirm) {
104
+ store_1.chuckerStore.clear();
105
+ setSelectedLogId(null);
106
+ }
107
+ },
108
+ });
109
+ };
110
+ const handleClose = () => {
111
+ if (taro_1.default.getCurrentPages().length > 1) {
112
+ taro_1.default.navigateBack();
113
+ }
114
+ else {
115
+ setIsOpen(false);
116
+ }
117
+ };
118
+ const handleCopyCurl = (log) => {
119
+ const curl = (0, utils_1.generateCurl)(log.url, log.method, log.requestHeaders || {}, log.requestData);
120
+ taro_1.default.setClipboardData({
121
+ data: curl,
122
+ success: () => {
123
+ taro_1.default.showToast({
124
+ title: "cURL Copied",
125
+ icon: "success",
126
+ });
127
+ },
128
+ });
129
+ };
130
+ const handleCopyText = (text) => {
131
+ taro_1.default.setClipboardData({
132
+ data: text,
133
+ success: () => {
134
+ taro_1.default.showToast({
135
+ title: "Copied",
136
+ icon: "success",
137
+ });
138
+ },
139
+ });
140
+ };
141
+ const getStatusColor = (status) => {
142
+ if (status === undefined || status === "pending")
143
+ return "#ffd60a"; // yellow
144
+ if (status === "fail" || (typeof status === "number" && status >= 400))
145
+ return "#ff453a"; // red
146
+ return "#30d158"; // green
147
+ };
148
+ const getMethodStyle = (method) => {
149
+ const base = {
150
+ display: "inline-block",
151
+ padding: "2px 6px",
152
+ borderRadius: "4px",
153
+ fontSize: "10px",
154
+ fontWeight: "bold",
155
+ color: "#ffffff",
156
+ marginRight: "8px",
157
+ width: "50px",
158
+ textAlign: "center",
159
+ };
160
+ switch (method.toUpperCase()) {
161
+ case "GET":
162
+ return { ...base, backgroundColor: "#0a84ff" };
163
+ case "POST":
164
+ return { ...base, backgroundColor: "#bf5af2" };
165
+ case "PUT":
166
+ return { ...base, backgroundColor: "#5e5ce6" };
167
+ case "DELETE":
168
+ return { ...base, backgroundColor: "#ff453a" };
169
+ case "NATIVE":
170
+ return { ...base, backgroundColor: "#ff9f0a" };
171
+ case "UPLOAD":
172
+ case "DOWNLOAD":
173
+ return { ...base, backgroundColor: "#30d158" };
174
+ default:
175
+ return { ...base, backgroundColor: "#64d2ff" };
176
+ }
177
+ };
178
+ const formatTime = (timestamp) => {
179
+ const date = new Date(timestamp);
180
+ const h = String(date.getHours()).padStart(2, "0");
181
+ const m = String(date.getMinutes()).padStart(2, "0");
182
+ const s = String(date.getSeconds()).padStart(2, "0");
183
+ return `${h}:${m}:${s}`;
184
+ };
185
+ if (!isOpen) {
186
+ return (react_1.default.createElement(components_1.View, { onClick: () => setIsOpen(true), style: {
187
+ position: "fixed",
188
+ bottom: "100px",
189
+ right: "20px",
190
+ left: "auto",
191
+ zIndex: 99999,
192
+ width: "50px",
193
+ height: "50px",
194
+ borderRadius: "25px",
195
+ backgroundColor: "rgba(30, 30, 30, 0.85)",
196
+ border: "1px solid rgba(255, 255, 255, 0.15)",
197
+ boxShadow: "0 4px 16px rgba(0, 0, 0, 0.3)",
198
+ display: "flex",
199
+ flexDirection: "column",
200
+ alignItems: "center",
201
+ justifyContent: "center",
202
+ backdropFilter: "blur(10px)",
203
+ } },
204
+ react_1.default.createElement(icons_1.BugIcon, { size: 22, color: errorCount > 0 ? "#ff453a" : "#30d158" }),
205
+ logs.length > 0 && (react_1.default.createElement(components_1.View, { style: {
206
+ position: "absolute",
207
+ top: "-4px",
208
+ right: "-4px",
209
+ backgroundColor: errorCount > 0 ? "#ff453a" : "#30d158",
210
+ color: "#ffffff",
211
+ fontSize: "9px",
212
+ fontWeight: "bold",
213
+ borderRadius: "8px",
214
+ padding: "1px 5px",
215
+ minWidth: "12px",
216
+ textAlign: "center",
217
+ } }, logs.length))));
218
+ }
219
+ return (react_1.default.createElement(components_1.View, { style: {
220
+ position: "fixed",
221
+ top: 0,
222
+ left: 0,
223
+ right: 0,
224
+ bottom: 0,
225
+ backgroundColor: "#121212",
226
+ color: "#ffffff",
227
+ zIndex: 100000,
228
+ display: "flex",
229
+ flexDirection: "column",
230
+ fontFamily: "system-ui, -apple-system, sans-serif",
231
+ } },
232
+ selectedLog && (react_1.default.createElement(components_1.View, { style: {
233
+ position: "absolute",
234
+ top: 0,
235
+ left: 0,
236
+ right: 0,
237
+ bottom: 0,
238
+ backgroundColor: "#1c1c1e",
239
+ zIndex: 100001,
240
+ display: "flex",
241
+ flexDirection: "column",
242
+ } },
243
+ react_1.default.createElement(components_1.View, { style: {
244
+ display: "flex",
245
+ flexDirection: "row",
246
+ alignItems: "center",
247
+ padding: "12px",
248
+ borderBottom: "1px solid #2d2d2d",
249
+ backgroundColor: "#121212",
250
+ } },
251
+ react_1.default.createElement(components_1.View, { onClick: () => setSelectedLogId(null), style: { padding: "8px", marginRight: "8px" } },
252
+ react_1.default.createElement(icons_1.BackIcon, { size: 20 })),
253
+ react_1.default.createElement(components_1.View, { style: { flex: 1, overflow: "hidden" } },
254
+ react_1.default.createElement(components_1.Text, { style: {
255
+ fontSize: "14px",
256
+ fontWeight: "bold",
257
+ whiteSpace: "nowrap",
258
+ overflow: "hidden",
259
+ textOverflow: "ellipsis",
260
+ display: "block",
261
+ } }, typeof selectedLog.url === "object" ? JSON.stringify(selectedLog.url) : selectedLog.url)),
262
+ selectedLog.type === "network" && (react_1.default.createElement(components_1.Button, { onClick: () => handleCopyCurl(selectedLog), style: {
263
+ fontSize: "11px",
264
+ backgroundColor: "#30d158",
265
+ color: "#ffffff",
266
+ padding: "4px 10px",
267
+ lineHeight: "1.5",
268
+ height: "auto",
269
+ border: "none",
270
+ borderRadius: "12px",
271
+ display: "flex",
272
+ justifyContent: "center",
273
+ marginLeft: "8px",
274
+ alignItems: "center",
275
+ gap: "4px",
276
+ width: "auto",
277
+ } },
278
+ react_1.default.createElement(icons_1.CopyIcon, { size: 12, color: "#ffffff" }),
279
+ " cURL"))),
280
+ react_1.default.createElement(components_1.View, { style: {
281
+ display: "flex",
282
+ flexDirection: "row",
283
+ borderBottom: "1px solid #2d2d2d",
284
+ backgroundColor: "#121212",
285
+ } }, ["overview", "request", "response"].map((tab) => (react_1.default.createElement(components_1.View, { key: tab, onClick: () => setActiveDetailTab(tab), style: {
286
+ flex: 1,
287
+ textAlign: "center",
288
+ padding: "12px 0",
289
+ fontSize: "13px",
290
+ fontWeight: activeDetailTab === tab ? "bold" : "normal",
291
+ color: activeDetailTab === tab ? "#30d158" : "#8e8e93",
292
+ borderBottom: activeDetailTab === tab ? "2px solid #30d158" : "none",
293
+ } }, tab.toUpperCase())))),
294
+ react_1.default.createElement(components_1.ScrollView, { scrollY: true, style: { flex: 1, minHeight: 0 } },
295
+ react_1.default.createElement(components_1.View, { style: { padding: "12px" } },
296
+ activeDetailTab === "overview" && (react_1.default.createElement(components_1.View, { style: { display: "flex", flexDirection: "column", gap: "12px" } },
297
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
298
+ react_1.default.createElement(components_1.Text, { style: {
299
+ color: "#8e8e93",
300
+ fontSize: "11px",
301
+ display: "block",
302
+ marginBottom: "4px",
303
+ } }, "Type"),
304
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "14px", fontWeight: "bold" } }, selectedLog.type === "native"
305
+ ? "Native Plugin Invocation"
306
+ : "Network Request")),
307
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
308
+ react_1.default.createElement(components_1.Text, { style: {
309
+ color: "#8e8e93",
310
+ fontSize: "11px",
311
+ display: "block",
312
+ marginBottom: "4px",
313
+ } }, "Method / API Name"),
314
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "14px", fontWeight: "bold", color: "#ffd60a" } }, selectedLog.method)),
315
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
316
+ react_1.default.createElement(components_1.Text, { style: {
317
+ color: "#8e8e93",
318
+ fontSize: "11px",
319
+ display: "block",
320
+ marginBottom: "4px",
321
+ } }, "URL Path / Identifier"),
322
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "14px", wordBreak: "break-all" } }, typeof selectedLog.url === "object" ? JSON.stringify(selectedLog.url) : selectedLog.url)),
323
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
324
+ react_1.default.createElement(components_1.Text, { style: {
325
+ color: "#8e8e93",
326
+ fontSize: "11px",
327
+ display: "block",
328
+ marginBottom: "4px",
329
+ } }, "Status"),
330
+ react_1.default.createElement(components_1.Text, { style: {
331
+ fontSize: "14px",
332
+ fontWeight: "bold",
333
+ color: getStatusColor(selectedLog.status),
334
+ } }, String(selectedLog.status).toUpperCase())),
335
+ selectedLog.duration !== undefined && (react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
336
+ react_1.default.createElement(components_1.Text, { style: {
337
+ color: "#8e8e93",
338
+ fontSize: "11px",
339
+ display: "block",
340
+ marginBottom: "4px",
341
+ } }, "Latency"),
342
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "14px", fontWeight: "bold" } },
343
+ selectedLog.duration,
344
+ " ms"))),
345
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
346
+ react_1.default.createElement(components_1.Text, { style: {
347
+ color: "#8e8e93",
348
+ fontSize: "11px",
349
+ display: "block",
350
+ marginBottom: "4px",
351
+ } }, "Time Initiated"),
352
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "14px" } }, new Date(selectedLog.startTime).toLocaleString())))),
353
+ activeDetailTab === "request" && (react_1.default.createElement(components_1.View, { style: { display: "flex", flexDirection: "column", gap: "12px" } },
354
+ selectedLog.requestHeaders &&
355
+ Object.keys(selectedLog.requestHeaders).length > 0 && (react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
356
+ react_1.default.createElement(components_1.View, { style: {
357
+ display: "flex",
358
+ flexDirection: "row",
359
+ justifyContent: "space-between",
360
+ alignItems: "center",
361
+ marginBottom: "8px",
362
+ } },
363
+ react_1.default.createElement(components_1.Text, { style: { color: "#8e8e93", fontSize: "11px", fontWeight: "bold" } }, "Headers"),
364
+ react_1.default.createElement(components_1.Text, { onClick: () => handleCopyText((0, utils_1.formatJson)(selectedLog.requestHeaders)), style: { color: "#30d158", fontSize: "11px" } }, "Copy")),
365
+ react_1.default.createElement(components_1.View, { style: {
366
+ fontSize: "12px",
367
+ fontFamily: "monospace",
368
+ whiteSpace: "pre-wrap",
369
+ wordBreak: "break-all",
370
+ color: "#64d2ff",
371
+ } }, (0, utils_1.formatJson)(selectedLog.requestHeaders)))),
372
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
373
+ react_1.default.createElement(components_1.View, { style: {
374
+ display: "flex",
375
+ flexDirection: "row",
376
+ justifyContent: "space-between",
377
+ alignItems: "center",
378
+ marginBottom: "8px",
379
+ } },
380
+ react_1.default.createElement(components_1.Text, { style: { color: "#8e8e93", fontSize: "11px", fontWeight: "bold" } }, "Body Payload"),
381
+ selectedLog.requestData && (react_1.default.createElement(components_1.Text, { onClick: () => handleCopyText((0, utils_1.formatJson)(selectedLog.requestData)), style: { color: "#30d158", fontSize: "11px" } }, "Copy"))),
382
+ react_1.default.createElement(components_1.View, { style: {
383
+ fontSize: "12px",
384
+ fontFamily: "monospace",
385
+ whiteSpace: "pre-wrap",
386
+ wordBreak: "break-all",
387
+ color: "#bf5af2",
388
+ } }, selectedLog.requestData
389
+ ? (0, utils_1.formatJson)(selectedLog.requestData)
390
+ : "No request payload")))),
391
+ activeDetailTab === "response" && (react_1.default.createElement(components_1.View, { style: { display: "flex", flexDirection: "column", gap: "12px" } },
392
+ selectedLog.error && (react_1.default.createElement(components_1.View, { style: {
393
+ backgroundColor: "rgba(255, 69, 58, 0.15)",
394
+ padding: "12px",
395
+ borderRadius: "8px",
396
+ } },
397
+ react_1.default.createElement(components_1.Text, { style: {
398
+ color: "#ff453a",
399
+ fontSize: "11px",
400
+ fontWeight: "bold",
401
+ display: "block",
402
+ marginBottom: "4px",
403
+ } }, "Error Message"),
404
+ react_1.default.createElement(components_1.Text, { style: {
405
+ fontSize: "12px",
406
+ fontFamily: "monospace",
407
+ color: "#ff453a",
408
+ wordBreak: "break-all",
409
+ } }, selectedLog.error))),
410
+ selectedLog.responseHeaders &&
411
+ Object.keys(selectedLog.responseHeaders).length > 0 && (react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
412
+ react_1.default.createElement(components_1.View, { style: {
413
+ display: "flex",
414
+ flexDirection: "row",
415
+ justifyContent: "space-between",
416
+ alignItems: "center",
417
+ marginBottom: "8px",
418
+ } },
419
+ react_1.default.createElement(components_1.Text, { style: { color: "#8e8e93", fontSize: "11px", fontWeight: "bold" } }, "Headers"),
420
+ react_1.default.createElement(components_1.Text, { onClick: () => handleCopyText((0, utils_1.formatJson)(selectedLog.responseHeaders)), style: { color: "#30d158", fontSize: "11px" } }, "Copy")),
421
+ react_1.default.createElement(components_1.View, { style: {
422
+ fontSize: "12px",
423
+ fontFamily: "monospace",
424
+ whiteSpace: "pre-wrap",
425
+ wordBreak: "break-all",
426
+ color: "#64d2ff",
427
+ } }, (0, utils_1.formatJson)(selectedLog.responseHeaders)))),
428
+ react_1.default.createElement(components_1.View, { style: { backgroundColor: "#2c2c2e", padding: "12px", borderRadius: "8px" } },
429
+ react_1.default.createElement(components_1.View, { style: {
430
+ display: "flex",
431
+ flexDirection: "row",
432
+ justifyContent: "space-between",
433
+ alignItems: "center",
434
+ marginBottom: "8px",
435
+ } },
436
+ react_1.default.createElement(components_1.Text, { style: { color: "#8e8e93", fontSize: "11px", fontWeight: "bold" } }, "Body Content"),
437
+ selectedLog.responseData && (react_1.default.createElement(components_1.Text, { onClick: () => handleCopyText((0, utils_1.formatJson)(selectedLog.responseData)), style: { color: "#30d158", fontSize: "11px" } }, "Copy"))),
438
+ react_1.default.createElement(components_1.View, { style: {
439
+ fontSize: "12px",
440
+ fontFamily: "monospace",
441
+ whiteSpace: "pre-wrap",
442
+ wordBreak: "break-all",
443
+ color: "#30d158",
444
+ } }, selectedLog.responseData
445
+ ? (0, utils_1.formatJson)(selectedLog.responseData)
446
+ : "Empty response body")))),
447
+ react_1.default.createElement(components_1.View, { style: { height: "40px" } }))))),
448
+ react_1.default.createElement(components_1.View, { style: {
449
+ display: "flex",
450
+ flexDirection: "row",
451
+ alignItems: "center",
452
+ padding: "12px",
453
+ borderBottom: "1px solid #2d2d2d",
454
+ backgroundColor: "#1e1e1e",
455
+ } },
456
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "16px", fontWeight: "bold", marginRight: "12px" } }, "Chucker"),
457
+ react_1.default.createElement(components_1.View, { style: {
458
+ flex: 1,
459
+ display: "flex",
460
+ flexDirection: "row",
461
+ alignItems: "center",
462
+ backgroundColor: "#2c2c2e",
463
+ borderRadius: "8px",
464
+ padding: "4px 8px",
465
+ marginRight: "8px",
466
+ } },
467
+ react_1.default.createElement(components_1.Input, { value: searchQuery, onInput: (e) => setSearchQuery(e.detail.value), placeholder: "Search endpoint...", placeholderStyle: "color: #8e8e93", style: {
468
+ fontSize: "12px",
469
+ color: "#ffffff",
470
+ backgroundColor: "transparent",
471
+ border: "none",
472
+ width: "100%",
473
+ padding: 0,
474
+ } })),
475
+ react_1.default.createElement(components_1.View, { onClick: handleClear, style: { padding: "8px", marginRight: "6px" } },
476
+ react_1.default.createElement(icons_1.TrashIcon, { size: 18 })),
477
+ react_1.default.createElement(components_1.View, { onClick: handleClose, style: { padding: "8px" } },
478
+ react_1.default.createElement(icons_1.CloseIcon, { size: 18 }))),
479
+ react_1.default.createElement(components_1.View, { style: {
480
+ display: "flex",
481
+ flexDirection: "row",
482
+ alignItems: "center",
483
+ backgroundColor: "#1e1e1e",
484
+ padding: "8px 12px",
485
+ borderBottom: "1px solid #2d2d2d",
486
+ justifyContent: "space-between",
487
+ } },
488
+ react_1.default.createElement(components_1.View, { style: { display: "flex", flexDirection: "row", gap: "8px" } }, ["all", "network", "native"].map((type) => (react_1.default.createElement(components_1.View, { key: type, onClick: () => setFilterType(type), style: {
489
+ fontSize: "11px",
490
+ padding: "4px 12px",
491
+ borderRadius: "12px",
492
+ backgroundColor: filterType === type ? "#30d158" : "#2c2c2e",
493
+ color: filterType === type ? "#ffffff" : "#aeaeb2",
494
+ } }, type.toUpperCase()))))),
495
+ react_1.default.createElement(components_1.View, { style: { flex: 1, overflowY: "auto" } }, filteredLogs.length === 0 ? (react_1.default.createElement(components_1.View, { style: { padding: "40px 0", textAlign: "center", color: "#8e8e93" } },
496
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "13px" } }, "No transactions recorded"))) : (vlChunks.map((chunk, ci) => (react_1.default.createElement(components_1.View, { key: ci, id: `vl-chunk-${ci}`, className: "vl-chunk", style: vlStyles[ci] }, chunk.map((log) => (react_1.default.createElement(components_1.View, { key: log.id, onClick: () => {
497
+ setSelectedLogId(log.id);
498
+ setActiveDetailTab("overview");
499
+ }, style: {
500
+ display: "flex",
501
+ flexDirection: "row",
502
+ alignItems: "center",
503
+ padding: "12px",
504
+ borderBottom: "1px solid #1c1c1e",
505
+ backgroundColor: log.status === "fail" ? "rgba(255, 69, 58, 0.05)" : "transparent",
506
+ } },
507
+ react_1.default.createElement(components_1.Text, { style: getMethodStyle(log.method) }, log.method),
508
+ react_1.default.createElement(components_1.Text, { style: {
509
+ fontSize: "11px",
510
+ fontWeight: "bold",
511
+ color: getStatusColor(log.status),
512
+ width: "45px",
513
+ textAlign: "center",
514
+ marginRight: "8px",
515
+ } }, String(log.status || "pending")),
516
+ react_1.default.createElement(components_1.View, { style: { flex: 1, overflow: "hidden", marginRight: "8px" } },
517
+ react_1.default.createElement(components_1.Text, { style: {
518
+ fontSize: "13px",
519
+ color: log.status === "fail" ? "#ff453a" : "#ffffff",
520
+ whiteSpace: "nowrap",
521
+ overflow: "hidden",
522
+ textOverflow: "ellipsis",
523
+ display: "block",
524
+ } }, typeof log.url === "object" ? JSON.stringify(log.url) : log.url)),
525
+ react_1.default.createElement(components_1.View, { style: { display: "flex", flexDirection: "column", alignItems: "flex-end" } },
526
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "10px", color: "#aeaeb2", marginBottom: "2px" } }, log.duration !== undefined ? `${log.duration}ms` : "..."),
527
+ react_1.default.createElement(components_1.Text, { style: { fontSize: "9px", color: "#8e8e93" } }, formatTime(log.startTime)))))))))))));
528
+ };
529
+ exports.Chucker = Chucker;
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ interface IconProps {
3
+ size?: number;
4
+ color?: string;
5
+ style?: React.CSSProperties;
6
+ }
7
+ export declare const SearchIcon: React.FC<IconProps>;
8
+ export declare const CloseIcon: React.FC<IconProps>;
9
+ export declare const CopyIcon: React.FC<IconProps>;
10
+ export declare const BackIcon: React.FC<IconProps>;
11
+ export declare const TrashIcon: React.FC<IconProps>;
12
+ export declare const BugIcon: React.FC<IconProps>;
13
+ export {};
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BugIcon = exports.TrashIcon = exports.BackIcon = exports.CopyIcon = exports.CloseIcon = exports.SearchIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const SearchIcon = ({ size = 20, color = "#8e8e93", style }) => (react_1.default.createElement("span", { style: {
9
+ fontSize: `${size}px`,
10
+ display: "inline-flex",
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ color,
14
+ ...style,
15
+ } }, "\uD83D\uDD0D"));
16
+ exports.SearchIcon = SearchIcon;
17
+ const CloseIcon = ({ size = 20, color = "#ffffff", style }) => (react_1.default.createElement("span", { style: {
18
+ fontSize: `${size}px`,
19
+ display: "inline-flex",
20
+ alignItems: "center",
21
+ justifyContent: "center",
22
+ color,
23
+ ...style,
24
+ } }, "\u2715"));
25
+ exports.CloseIcon = CloseIcon;
26
+ const CopyIcon = ({ size = 20, color = "#34c759", style }) => (react_1.default.createElement("span", { style: {
27
+ fontSize: `${size}px`,
28
+ display: "inline-flex",
29
+ alignItems: "center",
30
+ justifyContent: "center",
31
+ color,
32
+ ...style,
33
+ } }, "\uD83D\uDCCB"));
34
+ exports.CopyIcon = CopyIcon;
35
+ const BackIcon = ({ size = 20, color = "#ffffff", style }) => (react_1.default.createElement("span", { style: {
36
+ fontSize: `${size}px`,
37
+ display: "inline-flex",
38
+ alignItems: "center",
39
+ justifyContent: "center",
40
+ color,
41
+ ...style,
42
+ } }, "\u2190"));
43
+ exports.BackIcon = BackIcon;
44
+ const TrashIcon = ({ size = 20, color = "#ff3b30", style }) => (react_1.default.createElement("span", { style: {
45
+ fontSize: `${size}px`,
46
+ display: "inline-flex",
47
+ alignItems: "center",
48
+ justifyContent: "center",
49
+ color,
50
+ ...style,
51
+ } }, "\uD83D\uDDD1\uFE0F"));
52
+ exports.TrashIcon = TrashIcon;
53
+ const BugIcon = ({ size = 20, color = "#34c759", style }) => (react_1.default.createElement("span", { style: {
54
+ fontSize: `${size}px`,
55
+ display: "inline-flex",
56
+ alignItems: "center",
57
+ justifyContent: "center",
58
+ color,
59
+ ...style,
60
+ } }, "\uD83E\uDEB2"));
61
+ exports.BugIcon = BugIcon;