capdebug 0.1.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,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapDebug'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = 'https://github.com/capdebug/capdebug'
11
+ s.author = package['author']
12
+ s.source = { :git => 'https://github.com/capdebug/capdebug.git', :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '13.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # CapDebug
2
+
3
+ > Lightweight, embedded debug viewer and live diagnostics plugin for Capacitor applications.
4
+
5
+ `capdebug` runs entirely inside your Capacitor WebView as an isolated Web Component with Shadow DOM. It displays a draggable floating debug pill on the screen that opens a mobile-first developer drawer with real-time logs, errors, network traffic, custom events, and native system diagnostics for iOS (Swift) and Android (Kotlin).
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - 🚀 **Zero UI Framework Dependencies**: Built purely with Web Components, Shadow DOM, and Vanilla CSS. Works seamlessly with React, Vue, Svelte, Angular, Solid, or Vanilla JS.
12
+ - 🛡️ **Complete CSS Isolation**: Shadow DOM guarantees that the debug UI never conflicts with or inherits host application styles.
13
+ - 📱 **Mobile-First Floating Trigger**: Draggable floating pill that automatically snaps to the left/right screen edge, persists coordinates in `localStorage`, and supports safe-area insets.
14
+ - 📑 **Developer Drawer & Tabs**:
15
+ - **All**: Unified chronological event stream.
16
+ - **Console**: Intercepts `console.log`, `info`, `warn`, `error`, `debug`.
17
+ - **Errors**: Intercepts `window.onerror` and `unhandledrejection` with stack traces.
18
+ - **Events**: Custom app events dispatched via `CapDebug.emit()` or `CustomEvent('capdebug')`.
19
+ - **Native**: Native plugin events and bridge telemetry.
20
+ - **Device**: Live lazy-loaded diagnostics card for Device, Memory/Heap, App, WebView, and Network status.
21
+ - **Network**: Intercepts `fetch` requests with latency, status codes, and sanitized headers.
22
+ - **Bridge**: Capacitor plugin bridge activity collector.
23
+ - 🔍 **Search & Level Filters**: Real-time filtering by search query (`type`, `message`, `data`) and severity levels (`ALL`, `DEBUG`, `INFO`, `WARN`, `ERROR`).
24
+ - 🌳 **Interactive JSON Tree Viewer**: Collapsible nested objects/arrays, syntax coloring, individual value copying, and full payload JSON export.
25
+ - 🔒 **Privacy & Sanitization by Default**: Recursively sanitizes data and masks sensitive keys (`authorization`, `cookie`, `password`, `token`, `secret`, `api_key`, `jwt`, `credit_card`, etc.) while safely handling circular references, BigInt, Symbols, and DOM nodes.
26
+ - ⚡ **High Performance**: Circular FIFO ring buffer (default 500 events), incremental rendering, and `requestAnimationFrame` UI updates ensure zero lag in the host application.
27
+
28
+ ---
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install -D capdebug
34
+ npx cap sync
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Quick Start
40
+
41
+ Initialize CapDebug in your app's entry point:
42
+
43
+ ```ts
44
+ import { CapDebug } from 'capdebug';
45
+
46
+ // Mount the debug viewer
47
+ CapDebug.mount();
48
+
49
+ // Emit a test event
50
+ CapDebug.emit({
51
+ type: 'app.booted',
52
+ message: 'Application started successfully',
53
+ data: { version: '1.0.0' }
54
+ });
55
+ ```
56
+
57
+ ### Disabling in Production Builds (Recommended)
58
+
59
+ To ensure zero bundle size overhead in production builds, dynamically import CapDebug only in development mode:
60
+
61
+ ```ts
62
+ if (import.meta.env.DEV) {
63
+ const { CapDebug } = await import('capdebug');
64
+
65
+ CapDebug.mount({
66
+ console: true,
67
+ errors: true,
68
+ network: true,
69
+ native: true,
70
+ });
71
+ }
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Configuration Options
77
+
78
+ Pass options to `CapDebug.mount(options)`:
79
+
80
+ ```ts
81
+ CapDebug.mount({
82
+ button: true, // Show floating trigger button (default: true)
83
+ position: 'right', // Initial placement: 'right' | 'left' | { x, y } (default: 'right')
84
+ maxEvents: 500, // Max events retained in ring buffer (default: 500)
85
+ console: true, // Auto-capture console.log/info/warn/error/debug (default: true)
86
+ errors: true, // Auto-capture window errors & unhandled promise rejections (default: true)
87
+ network: false, // Auto-capture fetch API requests (default: false)
88
+ native: true, // Enable iOS/Android native diagnostics bridge (default: true)
89
+ bridge: false, // Enable bridge telemetry collector (default: false)
90
+ persistPosition: true, // Save button screen position in localStorage (default: true)
91
+ defaultTab: 'all', // Initial active tab: 'all' | 'console' | 'errors' | 'events' | 'device' | 'network' (default: 'all')
92
+ customMaskKeys: ['pin'] // Additional sensitive property keys to mask
93
+ });
94
+ ```
95
+
96
+ ---
97
+
98
+ ## CustomEvent Event Bus
99
+
100
+ CapDebug uses a standardized `CustomEvent('capdebug')` architecture as its core event bus. You can emit events from anywhere in your codebase without importing `capdebug`:
101
+
102
+ ```ts
103
+ window.dispatchEvent(
104
+ new CustomEvent('capdebug', {
105
+ detail: {
106
+ source: 'web',
107
+ type: 'user.login',
108
+ level: 'info',
109
+ message: 'User logged in',
110
+ data: {
111
+ userId: 'usr_102',
112
+ role: 'admin',
113
+ token: 'secret_jwt_token' // Auto-masked as '********'
114
+ }
115
+ }
116
+ })
117
+ );
118
+ ```
119
+
120
+ Or use the convenient public helper:
121
+
122
+ ```ts
123
+ import { CapDebug } from 'capdebug';
124
+
125
+ CapDebug.emit({
126
+ type: 'cart.checkout',
127
+ level: 'info',
128
+ message: 'Checkout started',
129
+ duration: 180,
130
+ data: { total: 49.99, itemsCount: 3 }
131
+ });
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Public API Reference
137
+
138
+ ```ts
139
+ // Lifecycle
140
+ CapDebug.mount(options?: CapDebugOptions);
141
+ CapDebug.unmount();
142
+
143
+ // Visibility
144
+ CapDebug.show(); // Open drawer
145
+ CapDebug.hide(); // Close drawer
146
+ CapDebug.toggle(); // Toggle drawer
147
+
148
+ // Event & Buffer Control
149
+ CapDebug.emit(event: CapDebugEventInput);
150
+ CapDebug.clear(); // Clear all recorded events
151
+ CapDebug.pause(); // Pause recording
152
+ CapDebug.resume(); // Resume recording
153
+
154
+ // Interception Collectors
155
+ CapDebug.captureConsole();
156
+ CapDebug.releaseConsole();
157
+
158
+ CapDebug.captureErrors();
159
+ CapDebug.releaseErrors();
160
+
161
+ CapDebug.captureFetch({ body?: boolean });
162
+ CapDebug.releaseFetch();
163
+
164
+ CapDebug.observeEvent('online');
165
+ CapDebug.observeEvent('visibilitychange');
166
+ CapDebug.unobserveEvent('online');
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Native Device Diagnostics
172
+
173
+ When running in Capacitor iOS or Android (or web fallback), diagnostics are fetched on-demand when opening the **Device** tab or via programmatic calls:
174
+
175
+ ```ts
176
+ import { CapDebug } from 'capdebug';
177
+
178
+ // Device Info (manufacturer, model, OS version, architecture, emulator flag)
179
+ const device = await CapDebug.native.getDeviceInfo();
180
+
181
+ // Memory Info (app heap usage, total/max heap, system available memory)
182
+ const memory = await CapDebug.native.getMemoryInfo();
183
+
184
+ // WebView Info (user agent, webview version, debug mode)
185
+ const webView = await CapDebug.native.getWebViewInfo();
186
+
187
+ // App Info (bundle ID / package name, version, build number)
188
+ const app = await CapDebug.native.getAppInfo();
189
+
190
+ // Network Info (connection type: wifi/cellular/ethernet, metered status)
191
+ const network = await CapDebug.native.getNetworkInfo();
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Privacy & Security
197
+
198
+ CapDebug is designed with privacy-first defaults:
199
+ 1. **Recursive Masking**: Passwords, tokens, cookies, auth headers, and API keys are automatically replaced with `'********'` in all data payloads and event views.
200
+ 2. **No Payload Leaks in Network Capture**: Network body capturing is disabled by default. If enabled via `{ network: { body: true } }`, sensitive fields inside JSON bodies are masked.
201
+ 3. **Permission Safety**: Native plugins only use standard, non-invasive system metrics (e.g. `NetworkCapabilities`, `ProcessInfo`, `mach_task_basic_info`). No fine location or private telephony permissions are requested.
202
+
203
+ ---
204
+
205
+ ## Running the Demo App
206
+
207
+ The repository includes a complete Capacitor example app in the `example/` directory:
208
+
209
+ ```bash
210
+ # Build capdebug package
211
+ npm run build
212
+
213
+ # Enter example directory and install
214
+ cd example
215
+ npm install
216
+ npm run build
217
+
218
+ # Run in browser
219
+ npm run dev
220
+
221
+ # Or sync to native mobile platforms
222
+ npx cap add ios
223
+ npx cap add android
224
+ npx cap sync
225
+ ```
226
+
227
+ ---
228
+
229
+ ## License
230
+
231
+ MIT
@@ -0,0 +1,63 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
4
+ androidxCoreVersion = project.hasProperty('androidxCoreVersion') ? rootProject.ext.androidxCoreVersion : '1.12.0'
5
+ androidxWebkitVersion = project.hasProperty('androidxWebkitVersion') ? rootProject.ext.androidxWebkitVersion : '1.10.0'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.2.1'
15
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22"
16
+ }
17
+ }
18
+
19
+ apply plugin: 'com.android.library'
20
+ apply plugin: 'kotlin-android'
21
+
22
+ android {
23
+ namespace "com.capdebug.plugin"
24
+ compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
25
+ defaultConfig {
26
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
27
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
28
+ versionCode 1
29
+ versionName "0.1.0"
30
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
31
+ }
32
+ buildTypes {
33
+ release {
34
+ minifyEnabled false
35
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
36
+ }
37
+ }
38
+ lintOptions {
39
+ abortOnError false
40
+ }
41
+ compileOptions {
42
+ sourceCompatibility JavaVersion.VERSION_17
43
+ targetCompatibility JavaVersion.VERSION_17
44
+ }
45
+ kotlinOptions {
46
+ jvmTarget = '17'
47
+ }
48
+ }
49
+
50
+ repositories {
51
+ google()
52
+ mavenCentral()
53
+ }
54
+
55
+ dependencies {
56
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
57
+ implementation project(':capacitor-android')
58
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
59
+ implementation "androidx.core:core-ktx:$androidxCoreVersion"
60
+ implementation "androidx.webkit:webkit:$androidxWebkitVersion"
61
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.22"
62
+ testImplementation "junit:junit:$junitVersion"
63
+ }
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
3
+ </manifest>
@@ -0,0 +1,241 @@
1
+ package com.capdebug.plugin
2
+
3
+ import android.app.ActivityManager
4
+ import android.content.Context
5
+ import android.content.pm.ApplicationInfo
6
+ import android.content.pm.PackageInfo
7
+ import android.content.pm.PackageManager
8
+ import android.net.ConnectivityManager
9
+ import android.net.NetworkCapabilities
10
+ import android.os.Build
11
+ import android.webkit.WebView
12
+ import androidx.webkit.WebViewCompat
13
+ import com.getcapacitor.JSObject
14
+ import com.getcapacitor.Plugin
15
+ import com.getcapacitor.PluginCall
16
+ import com.getcapacitor.PluginMethod
17
+ import com.getcapacitor.annotation.CapacitorPlugin
18
+ import java.util.Locale
19
+
20
+ @CapacitorPlugin(name = "CapDebug")
21
+ class CapDebugPlugin : Plugin() {
22
+
23
+ @PluginMethod
24
+ fun getDeviceInfo(call: PluginCall) {
25
+ try {
26
+ val ret = JSObject()
27
+ ret.put("manufacturer", Build.MANUFACTURER)
28
+ ret.put("model", Build.MODEL)
29
+ ret.put("device", Build.DEVICE)
30
+ ret.put("androidVersion", Build.VERSION.RELEASE)
31
+ ret.put("sdkVersion", Build.VERSION.SDK_INT)
32
+ ret.put("isEmulator", isEmulator())
33
+ ret.put("architecture", Build.SUPPORTED_ABIS.joinToString(", "))
34
+ ret.put("availableProcessors", Runtime.getRuntime().availableProcessors())
35
+ ret.put("platform", "android")
36
+ call.resolve(ret)
37
+ } catch (e: Exception) {
38
+ call.reject("Failed to get device info: ${e.message}", e)
39
+ }
40
+ }
41
+
42
+ @PluginMethod
43
+ fun getMemoryInfo(call: PluginCall) {
44
+ try {
45
+ val ret = JSObject()
46
+ val runtime = Runtime.getRuntime()
47
+ val totalHeap = runtime.totalMemory()
48
+ val freeHeap = runtime.freeMemory()
49
+ val maxHeap = runtime.maxMemory()
50
+ val usedHeap = totalHeap - freeHeap
51
+
52
+ ret.put("appMemoryUsage", usedHeap)
53
+ ret.put("appMemoryUsageFormatted", formatBytes(usedHeap))
54
+ ret.put("totalHeap", totalHeap)
55
+ ret.put("totalHeapFormatted", formatBytes(totalHeap))
56
+ ret.put("freeHeap", freeHeap)
57
+ ret.put("freeHeapFormatted", formatBytes(freeHeap))
58
+ ret.put("maxHeap", maxHeap)
59
+ ret.put("maxHeapFormatted", formatBytes(maxHeap))
60
+
61
+ val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
62
+ if (activityManager != null) {
63
+ val memInfo = ActivityManager.MemoryInfo()
64
+ activityManager.getMemoryInfo(memInfo)
65
+
66
+ ret.put("systemAvailableMemory", memInfo.availMem)
67
+ ret.put("systemAvailableMemoryFormatted", formatBytes(memInfo.availMem))
68
+ ret.put("systemTotalMemory", memInfo.totalMem)
69
+ ret.put("systemTotalMemoryFormatted", formatBytes(memInfo.totalMem))
70
+ ret.put("lowMemory", memInfo.lowMemory)
71
+ }
72
+
73
+ call.resolve(ret)
74
+ } catch (e: Exception) {
75
+ call.reject("Failed to get memory info: ${e.message}", e)
76
+ }
77
+ }
78
+
79
+ @PluginMethod
80
+ fun getWebViewInfo(call: PluginCall) {
81
+ try {
82
+ val ret = JSObject()
83
+
84
+ var webViewVersion = "Unknown"
85
+ var webViewPackage = "Unknown"
86
+
87
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
88
+ val pkg = WebView.getCurrentWebViewPackage()
89
+ if (pkg != null) {
90
+ webViewVersion = pkg.versionName ?: "Unknown"
91
+ webViewPackage = pkg.packageName ?: "Unknown"
92
+ }
93
+ } else {
94
+ val pkg = WebViewCompat.getCurrentWebViewPackage(context)
95
+ if (pkg != null) {
96
+ webViewVersion = pkg.versionName ?: "Unknown"
97
+ webViewPackage = pkg.packageName ?: "Unknown"
98
+ }
99
+ }
100
+
101
+ val userAgent = try {
102
+ bridge?.webView?.settings?.userAgentString ?: "Unknown"
103
+ } catch (e: Exception) {
104
+ "Unknown"
105
+ }
106
+
107
+ val isDebuggable = (context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
108
+
109
+ ret.put("version", webViewVersion)
110
+ ret.put("packageName", webViewPackage)
111
+ ret.put("userAgent", userAgent)
112
+ ret.put("debugEnabled", isDebuggable)
113
+
114
+ call.resolve(ret)
115
+ } catch (e: Exception) {
116
+ call.reject("Failed to get webview info: ${e.message}", e)
117
+ }
118
+ }
119
+
120
+ @PluginMethod
121
+ fun getAppInfo(call: PluginCall) {
122
+ try {
123
+ val ret = JSObject()
124
+ val packageName = context.packageName
125
+ val packageManager = context.packageManager
126
+
127
+ var versionName = "Unknown"
128
+ var versionCode: Long = -1
129
+
130
+ try {
131
+ val packageInfo: PackageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
132
+ packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
133
+ } else {
134
+ @Suppress("DEPRECATION")
135
+ packageManager.getPackageInfo(packageName, 0)
136
+ }
137
+ versionName = packageInfo.versionName ?: "Unknown"
138
+ versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
139
+ packageInfo.longVersionCode
140
+ } else {
141
+ @Suppress("DEPRECATION")
142
+ packageInfo.versionCode.toLong()
143
+ }
144
+ } catch (e: Exception) {
145
+ // ignore
146
+ }
147
+
148
+ val isDebuggable = (context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
149
+
150
+ ret.put("applicationId", packageName)
151
+ ret.put("versionName", versionName)
152
+ ret.put("version", versionName)
153
+ ret.put("versionCode", versionCode)
154
+ ret.put("buildType", if (isDebuggable) "debug" else "release")
155
+
156
+ call.resolve(ret)
157
+ } catch (e: Exception) {
158
+ call.reject("Failed to get app info: ${e.message}", e)
159
+ }
160
+ }
161
+
162
+ @PluginMethod
163
+ fun getNetworkInfo(call: PluginCall) {
164
+ try {
165
+ val ret = JSObject()
166
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
167
+
168
+ if (connectivityManager == null) {
169
+ ret.put("connected", false)
170
+ ret.put("connectionType", "none")
171
+ ret.put("metered", false)
172
+ call.resolve(ret)
173
+ return
174
+ }
175
+
176
+ val activeNetwork = connectivityManager.activeNetwork
177
+ val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
178
+
179
+ if (capabilities == null) {
180
+ ret.put("connected", false)
181
+ ret.put("connectionType", "none")
182
+ ret.put("metered", false)
183
+ call.resolve(ret)
184
+ return
185
+ }
186
+
187
+ val isConnected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
188
+ val connectionType = when {
189
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> "wifi"
190
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "cellular"
191
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> "ethernet"
192
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> "vpn"
193
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> "bluetooth"
194
+ else -> "other"
195
+ }
196
+
197
+ val isMetered = connectivityManager.isActiveNetworkMetered
198
+
199
+ ret.put("connected", isConnected)
200
+ ret.put("connectionType", connectionType)
201
+ ret.put("metered", isMetered)
202
+
203
+ call.resolve(ret)
204
+ } catch (e: Exception) {
205
+ call.reject("Failed to get network info: ${e.message}", e)
206
+ }
207
+ }
208
+
209
+ private fun isEmulator(): Boolean {
210
+ val finger = Build.FINGERPRINT.lowercase(Locale.ROOT)
211
+ val model = Build.MODEL.lowercase(Locale.ROOT)
212
+ val manufacturer = Build.MANUFACTURER.lowercase(Locale.ROOT)
213
+ val product = Build.PRODUCT.lowercase(Locale.ROOT)
214
+ val hardware = Build.HARDWARE.lowercase(Locale.ROOT)
215
+
216
+ return finger.startsWith("generic") ||
217
+ finger.startsWith("unknown") ||
218
+ model.contains("google_sdk") ||
219
+ model.contains("emulator") ||
220
+ model.contains("android sdk built for x86") ||
221
+ manufacturer.contains("genymotion") ||
222
+ hardware == "goldfish" ||
223
+ hardware == "ranchu" ||
224
+ product.contains("sdk_gphone") ||
225
+ product.contains("sdk") ||
226
+ product.contains("emulator")
227
+ }
228
+
229
+ private fun formatBytes(bytes: Long): String {
230
+ if (bytes <= 0) return "0 B"
231
+ val units = arrayOf("B", "KB", "MB", "GB", "TB")
232
+ val digitGroups = (Math.log10(bytes.toDouble()) / Math.log10(1024.0)).toInt()
233
+ val formatted = String.format(
234
+ Locale.US,
235
+ "%.2f %s",
236
+ bytes / Math.pow(1024.0, digitGroups.toDouble()),
237
+ units[digitGroups]
238
+ )
239
+ return formatted
240
+ }
241
+ }
@@ -0,0 +1,8 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ export declare class BridgeCollector implements CapDebugCollector {
3
+ readonly id = "bridge";
4
+ private running;
5
+ start(): void;
6
+ stop(): void;
7
+ emitBridgeCall(pluginName: string, methodName: string, options?: unknown, duration?: number): void;
8
+ }
@@ -0,0 +1,10 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ export declare class BrowserEventCollector implements CapDebugCollector {
3
+ readonly id = "browser-event";
4
+ private running;
5
+ private observedEvents;
6
+ start(): void;
7
+ observe(eventName: string): void;
8
+ unobserve(eventName: string): void;
9
+ stop(): void;
10
+ }
@@ -0,0 +1,2 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ export type { CapDebugCollector };
@@ -0,0 +1,9 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ export declare class ConsoleCollector implements CapDebugCollector {
3
+ readonly id = "console";
4
+ private running;
5
+ private originalMethods;
6
+ start(): void;
7
+ stop(): void;
8
+ private emitConsoleEvent;
9
+ }
@@ -0,0 +1,11 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ import type { CapDebugStore } from '../store';
3
+ export declare class CustomEventCollector implements CapDebugCollector {
4
+ readonly id = "custom-event";
5
+ private store;
6
+ private running;
7
+ private handler;
8
+ constructor(store: CapDebugStore);
9
+ start(): void;
10
+ stop(): void;
11
+ }
@@ -0,0 +1,9 @@
1
+ import type { CapDebugCollector } from '../types';
2
+ export declare class ErrorCollector implements CapDebugCollector {
3
+ readonly id = "error";
4
+ private running;
5
+ private errorHandler;
6
+ private rejectionHandler;
7
+ start(): void;
8
+ stop(): void;
9
+ }
@@ -0,0 +1,12 @@
1
+ import type { CapDebugCollector, NetworkCaptureOptions } from '../types';
2
+ export declare class NetworkCollector implements CapDebugCollector {
3
+ readonly id = "network";
4
+ private running;
5
+ private originalFetch;
6
+ private options;
7
+ constructor(options?: NetworkCaptureOptions);
8
+ setOptions(options: NetworkCaptureOptions): void;
9
+ start(): void;
10
+ stop(): void;
11
+ private emitNetworkEvent;
12
+ }
@@ -0,0 +1,9 @@
1
+ import type { DeviceInfo, MemoryInfo, WebViewInfo, AppInfo, NetworkInfo } from './types';
2
+ export interface CapDebugNativePlugin {
3
+ getDeviceInfo(): Promise<DeviceInfo>;
4
+ getMemoryInfo(): Promise<MemoryInfo>;
5
+ getWebViewInfo(): Promise<WebViewInfo>;
6
+ getAppInfo(): Promise<AppInfo>;
7
+ getNetworkInfo(): Promise<NetworkInfo>;
8
+ }
9
+ export declare const CapDebugNative: CapDebugNativePlugin;