capdebug 0.2.0 → 0.3.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.
Files changed (133) hide show
  1. package/README.md +30 -0
  2. package/android/build/.transforms/105231053f5053e70f17f15178bed793/results.bin +1 -0
  3. package/android/build/.transforms/7c2b02c40854250ff97be5e9e723091e/results.bin +1 -0
  4. package/android/build/.transforms/ca1c0f6bb67b5238fd83a40c3a1c0ddd/results.bin +1 -0
  5. package/android/build/.transforms/ca1c0f6bb67b5238fd83a40c3a1c0ddd/transformed/classes/classes_dex/classes.dex +0 -0
  6. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +9 -0
  7. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
  8. package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +6 -0
  9. package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
  10. package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
  11. package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
  12. package/android/build/intermediates/compile_symbol_list/debug/R.txt +0 -0
  13. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
  14. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  15. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  16. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  17. package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
  18. package/android/build/intermediates/java_res/debug/out/META-INF/capdebug_debug.kotlin_module +0 -0
  19. package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +2 -0
  20. package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +11 -0
  21. package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +9 -0
  22. package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
  23. package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
  24. package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +1 -0
  25. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  26. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  27. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  28. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  29. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  30. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  31. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  32. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  33. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  34. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  35. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  36. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  54. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  57. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  58. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  59. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  60. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  61. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  62. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  63. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  64. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  65. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  66. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  105. package/android/build/outputs/logs/manifest-merger-debug-report.txt +20 -0
  106. package/android/build/tmp/kotlin-classes/debug/META-INF/capdebug_debug.kotlin_module +0 -0
  107. package/android/build/tmp/kotlin-classes/debug/com/capdebug/plugin/CapDebugPlugin$Companion.class +0 -0
  108. package/android/build/tmp/kotlin-classes/debug/com/capdebug/plugin/CapDebugPlugin.class +0 -0
  109. package/bin/capdebug.js +8 -0
  110. package/dist/capacitor/deep-link.d.ts +4 -0
  111. package/dist/cli/index.d.ts +1 -0
  112. package/dist/cli/qr.d.ts +15 -0
  113. package/dist/cli/server.d.ts +34 -0
  114. package/dist/cli.js +1868 -0
  115. package/dist/cli.js.map +1 -0
  116. package/dist/index.d.ts +13 -0
  117. package/dist/plugin.cjs.js +866 -0
  118. package/dist/plugin.cjs.js.map +1 -1
  119. package/dist/plugin.js +866 -0
  120. package/dist/plugin.js.map +1 -1
  121. package/dist/plugin.mjs +859 -1
  122. package/dist/plugin.mjs.map +1 -1
  123. package/dist/remote/buffer.d.ts +13 -0
  124. package/dist/remote/desktop-viewer-html.d.ts +10 -0
  125. package/dist/remote/pairing-page-html.d.ts +8 -0
  126. package/dist/remote/pairing.d.ts +34 -0
  127. package/dist/remote/protocol.d.ts +14 -0
  128. package/dist/remote/remote-manager.d.ts +19 -0
  129. package/dist/remote/signaling.d.ts +27 -0
  130. package/dist/remote/transport.d.ts +15 -0
  131. package/dist/remote/types.d.ts +69 -0
  132. package/dist/remote/webrtc-transport.d.ts +47 -0
  133. package/package.json +5 -1
@@ -2377,10 +2377,861 @@ function registerCustomElement() {
2377
2377
  }
2378
2378
  }
2379
2379
 
2380
+ class HttpSseSignalingClient {
2381
+ baseUrl;
2382
+ sessionId = "";
2383
+ secret = "";
2384
+ role = "peer";
2385
+ eventSource = null;
2386
+ listeners = /* @__PURE__ */ new Set();
2387
+ isClosed = false;
2388
+ pollTimer = null;
2389
+ constructor(baseUrl) {
2390
+ this.baseUrl = baseUrl.replace(/\/+$/, "");
2391
+ }
2392
+ async createSession(ttlSeconds = 300) {
2393
+ this.role = "host";
2394
+ const res = await fetch(`${this.baseUrl}/api/pair/create`, {
2395
+ method: "POST",
2396
+ headers: { "Content-Type": "application/json" },
2397
+ body: JSON.stringify({ ttl: ttlSeconds })
2398
+ });
2399
+ if (!res.ok) {
2400
+ throw new Error(`Failed to create pairing session: ${res.statusText}`);
2401
+ }
2402
+ const data = await res.json();
2403
+ this.sessionId = data.sessionId;
2404
+ this.secret = data.secret;
2405
+ this.connectEventStream();
2406
+ return data;
2407
+ }
2408
+ async joinSession(sessionId, secret) {
2409
+ this.role = "peer";
2410
+ this.sessionId = sessionId;
2411
+ this.secret = secret;
2412
+ const res = await fetch(`${this.baseUrl}/api/pair/join`, {
2413
+ method: "POST",
2414
+ headers: { "Content-Type": "application/json" },
2415
+ body: JSON.stringify({ sessionId, secret })
2416
+ });
2417
+ if (!res.ok) {
2418
+ const err = await res.text().catch(() => "");
2419
+ throw new Error(`Failed to join pairing session: ${err || res.statusText}`);
2420
+ }
2421
+ this.connectEventStream();
2422
+ }
2423
+ async send(message) {
2424
+ if (this.isClosed) return;
2425
+ message.sessionId = this.sessionId;
2426
+ message.secret = this.secret;
2427
+ message.sender = this.role;
2428
+ message.timestamp = Date.now();
2429
+ await fetch(`${this.baseUrl}/api/pair/signal`, {
2430
+ method: "POST",
2431
+ headers: { "Content-Type": "application/json" },
2432
+ body: JSON.stringify(message)
2433
+ });
2434
+ }
2435
+ onMessage(callback) {
2436
+ this.listeners.add(callback);
2437
+ return () => {
2438
+ this.listeners.delete(callback);
2439
+ };
2440
+ }
2441
+ close() {
2442
+ this.isClosed = true;
2443
+ if (this.eventSource) {
2444
+ this.eventSource.close();
2445
+ this.eventSource = null;
2446
+ }
2447
+ if (this.pollTimer) {
2448
+ clearInterval(this.pollTimer);
2449
+ this.pollTimer = null;
2450
+ }
2451
+ this.listeners.clear();
2452
+ }
2453
+ connectEventStream() {
2454
+ if (typeof EventSource !== "undefined") {
2455
+ const sseUrl = `${this.baseUrl}/api/pair/events?session=${encodeURIComponent(this.sessionId)}&secret=${encodeURIComponent(this.secret)}&role=${this.role}`;
2456
+ this.eventSource = new EventSource(sseUrl);
2457
+ this.eventSource.onmessage = (event) => {
2458
+ if (!event.data) return;
2459
+ try {
2460
+ const msg = JSON.parse(event.data);
2461
+ this.dispatchMessage(msg);
2462
+ } catch {
2463
+ }
2464
+ };
2465
+ this.eventSource.onerror = () => {
2466
+ };
2467
+ } else {
2468
+ this.startPolling();
2469
+ }
2470
+ }
2471
+ startPolling() {
2472
+ if (this.pollTimer) return;
2473
+ this.pollTimer = setInterval(async () => {
2474
+ if (this.isClosed || !this.sessionId) return;
2475
+ try {
2476
+ const res = await fetch(
2477
+ `${this.baseUrl}/api/pair/poll?session=${encodeURIComponent(this.sessionId)}&secret=${encodeURIComponent(this.secret)}&role=${this.role}`
2478
+ );
2479
+ if (res.ok) {
2480
+ const messages = await res.json();
2481
+ if (Array.isArray(messages)) {
2482
+ for (const msg of messages) {
2483
+ this.dispatchMessage(msg);
2484
+ }
2485
+ }
2486
+ }
2487
+ } catch {
2488
+ }
2489
+ }, 1e3);
2490
+ }
2491
+ dispatchMessage(message) {
2492
+ for (const listener of this.listeners) {
2493
+ try {
2494
+ listener(message);
2495
+ } catch (err) {
2496
+ console.error("[CapDebug Signaling] Listener error:", err);
2497
+ }
2498
+ }
2499
+ }
2500
+ }
2501
+
2502
+ const PROTOCOL_VERSION = 1;
2503
+ class RemoteProtocol {
2504
+ static createHello(capdebugVersion = "0.2.0", platform = "web", deviceName) {
2505
+ return {
2506
+ v: 1,
2507
+ type: "hello",
2508
+ payload: {
2509
+ capdebugVersion,
2510
+ platform,
2511
+ deviceName: deviceName || (typeof navigator !== "undefined" ? navigator.userAgent : "Unknown Device")
2512
+ },
2513
+ timestamp: Date.now()
2514
+ };
2515
+ }
2516
+ static createHelloAck() {
2517
+ return {
2518
+ v: 1,
2519
+ type: "hello-ack",
2520
+ payload: {
2521
+ serverTime: Date.now()
2522
+ },
2523
+ timestamp: Date.now()
2524
+ };
2525
+ }
2526
+ static createEvent(event) {
2527
+ return {
2528
+ v: 1,
2529
+ type: "event",
2530
+ event,
2531
+ timestamp: Date.now()
2532
+ };
2533
+ }
2534
+ static createBatch(events) {
2535
+ return {
2536
+ v: 1,
2537
+ type: "events-batch",
2538
+ events,
2539
+ timestamp: Date.now()
2540
+ };
2541
+ }
2542
+ static createControl(command) {
2543
+ return {
2544
+ v: 1,
2545
+ type: "control",
2546
+ command,
2547
+ timestamp: Date.now()
2548
+ };
2549
+ }
2550
+ static createPing(timestamp = Date.now()) {
2551
+ return {
2552
+ v: 1,
2553
+ type: "ping",
2554
+ timestamp
2555
+ };
2556
+ }
2557
+ static createPong(pingTimestamp) {
2558
+ return {
2559
+ v: 1,
2560
+ type: "pong",
2561
+ payload: { pingTimestamp },
2562
+ timestamp: Date.now()
2563
+ };
2564
+ }
2565
+ static serialize(message) {
2566
+ return JSON.stringify(message);
2567
+ }
2568
+ static parse(raw) {
2569
+ try {
2570
+ const parsed = JSON.parse(raw);
2571
+ if (!parsed || typeof parsed !== "object") {
2572
+ return null;
2573
+ }
2574
+ if (parsed.v !== PROTOCOL_VERSION) {
2575
+ console.warn(`[CapDebug Remote] Unsupported protocol version: ${parsed.v}`);
2576
+ return null;
2577
+ }
2578
+ return parsed;
2579
+ } catch {
2580
+ return null;
2581
+ }
2582
+ }
2583
+ }
2584
+
2585
+ class RemoteEventBuffer {
2586
+ buffer = [];
2587
+ maxCapacity;
2588
+ droppedCount = 0;
2589
+ constructor(maxCapacity = 100) {
2590
+ this.maxCapacity = Math.max(1, maxCapacity);
2591
+ }
2592
+ push(event) {
2593
+ if (this.buffer.length >= this.maxCapacity) {
2594
+ this.buffer.shift();
2595
+ }
2596
+ this.buffer.push(event);
2597
+ }
2598
+ flush() {
2599
+ const items = [...this.buffer];
2600
+ this.buffer = [];
2601
+ return items;
2602
+ }
2603
+ clear() {
2604
+ this.buffer = [];
2605
+ this.droppedCount = 0;
2606
+ }
2607
+ size() {
2608
+ return this.buffer.length;
2609
+ }
2610
+ getDroppedCount() {
2611
+ return this.droppedCount;
2612
+ }
2613
+ incrementDropped() {
2614
+ this.droppedCount++;
2615
+ }
2616
+ }
2617
+
2618
+ class WebRTCTransport {
2619
+ id = "webrtc";
2620
+ pc = null;
2621
+ signaling = null;
2622
+ config = null;
2623
+ eventsChannel = null;
2624
+ controlChannel = null;
2625
+ status = "disconnected";
2626
+ buffer = new RemoteEventBuffer(100);
2627
+ eventListeners = /* @__PURE__ */ new Set();
2628
+ controlListeners = /* @__PURE__ */ new Set();
2629
+ statusListeners = /* @__PURE__ */ new Set();
2630
+ diagnosticsListeners = /* @__PURE__ */ new Set();
2631
+ pingTimer = null;
2632
+ statsTimer = null;
2633
+ rttMs = 0;
2634
+ totalEventsSent = 0;
2635
+ totalEventsReceived = 0;
2636
+ connectedAt = 0;
2637
+ remoteDeviceName = "Unknown Device";
2638
+ remotePlatform = "unknown";
2639
+ diagnostics = {
2640
+ transport: "webrtc",
2641
+ status: "disconnected",
2642
+ route: "unknown"
2643
+ };
2644
+ async connect(config) {
2645
+ this.config = config;
2646
+ this.setStatus("connecting");
2647
+ const signalingUrl = config.signalingUrl || (typeof window !== "undefined" ? window.location.origin : "http://localhost:4783");
2648
+ this.signaling = new HttpSseSignalingClient(signalingUrl);
2649
+ this.signaling.onMessage((msg) => this.handleSignalingMessage(msg));
2650
+ if (config.isHost) {
2651
+ this.setStatus("signaling");
2652
+ } else {
2653
+ this.setStatus("signaling");
2654
+ await this.signaling.joinSession(config.sessionId, config.secret);
2655
+ }
2656
+ }
2657
+ send(event) {
2658
+ if (this.eventsChannel && this.eventsChannel.readyState === "open") {
2659
+ if (this.eventsChannel.bufferedAmount > 256 * 1024) {
2660
+ if (event.level === "debug" || event.level === "info") {
2661
+ this.buffer.incrementDropped();
2662
+ return;
2663
+ }
2664
+ }
2665
+ const msg = RemoteProtocol.createEvent(event);
2666
+ try {
2667
+ this.eventsChannel.send(RemoteProtocol.serialize(msg));
2668
+ this.totalEventsSent++;
2669
+ } catch (err) {
2670
+ console.error("[CapDebug Remote] Send error:", err);
2671
+ }
2672
+ } else {
2673
+ this.buffer.push(event);
2674
+ }
2675
+ }
2676
+ sendControl(command) {
2677
+ if (this.controlChannel && this.controlChannel.readyState === "open") {
2678
+ const msg = RemoteProtocol.createControl(command);
2679
+ try {
2680
+ this.controlChannel.send(RemoteProtocol.serialize(msg));
2681
+ } catch (err) {
2682
+ console.error("[CapDebug Remote] Control send error:", err);
2683
+ }
2684
+ }
2685
+ }
2686
+ disconnect() {
2687
+ this.stopTimers();
2688
+ if (this.controlChannel) {
2689
+ try {
2690
+ this.sendControl({ type: "disconnect" });
2691
+ } catch {
2692
+ }
2693
+ }
2694
+ if (this.signaling) {
2695
+ this.signaling.close();
2696
+ this.signaling = null;
2697
+ }
2698
+ if (this.eventsChannel) {
2699
+ this.eventsChannel.close();
2700
+ this.eventsChannel = null;
2701
+ }
2702
+ if (this.controlChannel) {
2703
+ this.controlChannel.close();
2704
+ this.controlChannel = null;
2705
+ }
2706
+ if (this.pc) {
2707
+ this.pc.close();
2708
+ this.pc = null;
2709
+ }
2710
+ this.setStatus("disconnected");
2711
+ }
2712
+ getStatus() {
2713
+ return this.status;
2714
+ }
2715
+ getDiagnostics() {
2716
+ return {
2717
+ ...this.diagnostics,
2718
+ status: this.status,
2719
+ rttMs: this.rttMs,
2720
+ bufferedAmountBytes: this.eventsChannel?.bufferedAmount || 0,
2721
+ droppedEventsCount: this.buffer.getDroppedCount(),
2722
+ totalEventsSent: this.totalEventsSent,
2723
+ totalEventsReceived: this.totalEventsReceived,
2724
+ connectedAt: this.connectedAt,
2725
+ deviceName: this.remoteDeviceName,
2726
+ platform: this.remotePlatform
2727
+ };
2728
+ }
2729
+ onEvent(callback) {
2730
+ this.eventListeners.add(callback);
2731
+ return () => this.eventListeners.delete(callback);
2732
+ }
2733
+ onControl(callback) {
2734
+ this.controlListeners.add(callback);
2735
+ return () => this.controlListeners.delete(callback);
2736
+ }
2737
+ onStatusChange(callback) {
2738
+ this.statusListeners.add(callback);
2739
+ callback(this.status);
2740
+ return () => this.statusListeners.delete(callback);
2741
+ }
2742
+ onDiagnostics(callback) {
2743
+ this.diagnosticsListeners.add(callback);
2744
+ return () => this.diagnosticsListeners.delete(callback);
2745
+ }
2746
+ async handleSignalingMessage(msg) {
2747
+ switch (msg.type) {
2748
+ case "peer-joined":
2749
+ if (this.config?.isHost) {
2750
+ await this.startHandshakeAsInitiator();
2751
+ }
2752
+ break;
2753
+ case "offer":
2754
+ if (!this.config?.isHost) {
2755
+ await this.handleOffer(msg.payload);
2756
+ }
2757
+ break;
2758
+ case "answer":
2759
+ if (this.config?.isHost && this.pc) {
2760
+ await this.pc.setRemoteDescription(new RTCSessionDescription(msg.payload));
2761
+ }
2762
+ break;
2763
+ case "ice-candidate":
2764
+ if (this.pc && msg.payload) {
2765
+ try {
2766
+ await this.pc.addIceCandidate(new RTCIceCandidate(msg.payload));
2767
+ } catch (err) {
2768
+ console.warn("[CapDebug Remote] ICE Candidate error:", err);
2769
+ }
2770
+ }
2771
+ break;
2772
+ case "disconnect":
2773
+ this.disconnect();
2774
+ break;
2775
+ }
2776
+ }
2777
+ initPeerConnection() {
2778
+ const iceServers = this.config?.iceServers || [
2779
+ { urls: "stun:stun.l.google.com:19302" },
2780
+ { urls: "stun:global.stun.twilio.com:3478" }
2781
+ ];
2782
+ const pc = new RTCPeerConnection({ iceServers });
2783
+ pc.onicecandidate = (event) => {
2784
+ if (event.candidate && this.signaling) {
2785
+ this.signaling.send({
2786
+ sessionId: this.config.sessionId,
2787
+ secret: this.config.secret,
2788
+ type: "ice-candidate",
2789
+ sender: this.config.isHost ? "host" : "peer",
2790
+ payload: event.candidate.toJSON()
2791
+ });
2792
+ }
2793
+ };
2794
+ pc.onconnectionstatechange = () => {
2795
+ this.updateDiagnostics();
2796
+ if (pc.connectionState === "failed") {
2797
+ this.setStatus("failed");
2798
+ } else if (pc.connectionState === "closed" || pc.connectionState === "disconnected") {
2799
+ this.setStatus("disconnected");
2800
+ }
2801
+ };
2802
+ pc.oniceconnectionstatechange = () => {
2803
+ this.updateDiagnostics();
2804
+ };
2805
+ this.pc = pc;
2806
+ return pc;
2807
+ }
2808
+ async startHandshakeAsInitiator() {
2809
+ const pc = this.initPeerConnection();
2810
+ this.eventsChannel = pc.createDataChannel("events", { ordered: true });
2811
+ this.controlChannel = pc.createDataChannel("control", { ordered: true });
2812
+ this.setupDataChannel(this.eventsChannel, "events");
2813
+ this.setupDataChannel(this.controlChannel, "control");
2814
+ const offer = await pc.createOffer();
2815
+ await pc.setLocalDescription(offer);
2816
+ if (this.signaling) {
2817
+ await this.signaling.send({
2818
+ sessionId: this.config.sessionId,
2819
+ secret: this.config.secret,
2820
+ type: "offer",
2821
+ sender: "host",
2822
+ payload: offer
2823
+ });
2824
+ }
2825
+ }
2826
+ async handleOffer(offerSdp) {
2827
+ const pc = this.initPeerConnection();
2828
+ pc.ondatachannel = (event) => {
2829
+ const channel = event.channel;
2830
+ if (channel.label === "events") {
2831
+ this.eventsChannel = channel;
2832
+ this.setupDataChannel(channel, "events");
2833
+ } else if (channel.label === "control") {
2834
+ this.controlChannel = channel;
2835
+ this.setupDataChannel(channel, "control");
2836
+ }
2837
+ };
2838
+ await pc.setRemoteDescription(new RTCSessionDescription(offerSdp));
2839
+ const answer = await pc.createAnswer();
2840
+ await pc.setLocalDescription(answer);
2841
+ if (this.signaling) {
2842
+ await this.signaling.send({
2843
+ sessionId: this.config.sessionId,
2844
+ secret: this.config.secret,
2845
+ type: "answer",
2846
+ sender: "peer",
2847
+ payload: answer
2848
+ });
2849
+ }
2850
+ }
2851
+ setupDataChannel(channel, label) {
2852
+ channel.onopen = () => {
2853
+ if (this.eventsChannel?.readyState === "open" && this.controlChannel?.readyState === "open") {
2854
+ this.connectedAt = Date.now();
2855
+ this.setStatus("connected");
2856
+ this.startTimers();
2857
+ if (!this.config?.isHost) {
2858
+ const hello = RemoteProtocol.createHello("0.2.0", "mobile");
2859
+ channel.send(RemoteProtocol.serialize(hello));
2860
+ const buffered = this.buffer.flush();
2861
+ if (buffered.length > 0 && this.eventsChannel?.readyState === "open") {
2862
+ const batch = RemoteProtocol.createBatch(buffered);
2863
+ this.eventsChannel.send(RemoteProtocol.serialize(batch));
2864
+ this.totalEventsSent += buffered.length;
2865
+ }
2866
+ }
2867
+ }
2868
+ };
2869
+ channel.onclose = () => {
2870
+ this.setStatus("disconnected");
2871
+ };
2872
+ channel.onmessage = (e) => {
2873
+ const raw = e.data;
2874
+ if (typeof raw !== "string") return;
2875
+ const message = RemoteProtocol.parse(raw);
2876
+ if (!message) return;
2877
+ if (label === "events") {
2878
+ if (message.type === "event" && message.event) {
2879
+ this.totalEventsReceived++;
2880
+ for (const listener of this.eventListeners) {
2881
+ listener(message.event);
2882
+ }
2883
+ } else if (message.type === "events-batch" && Array.isArray(message.events)) {
2884
+ this.totalEventsReceived += message.events.length;
2885
+ for (const ev of message.events) {
2886
+ for (const listener of this.eventListeners) {
2887
+ listener(ev);
2888
+ }
2889
+ }
2890
+ }
2891
+ } else if (label === "control") {
2892
+ this.handleControlMessage(message);
2893
+ }
2894
+ };
2895
+ }
2896
+ handleControlMessage(message) {
2897
+ if (message.type === "control" && message.command) {
2898
+ for (const listener of this.controlListeners) {
2899
+ listener(message.command);
2900
+ }
2901
+ } else if (message.type === "hello") {
2902
+ this.remoteDeviceName = message.payload?.deviceName || "Mobile Device";
2903
+ this.remotePlatform = message.payload?.platform || "mobile";
2904
+ if (this.controlChannel?.readyState === "open") {
2905
+ this.controlChannel.send(RemoteProtocol.serialize(RemoteProtocol.createHelloAck()));
2906
+ }
2907
+ this.updateDiagnostics();
2908
+ } else if (message.type === "hello-ack") {
2909
+ this.updateDiagnostics();
2910
+ } else if (message.type === "ping") {
2911
+ if (this.controlChannel?.readyState === "open") {
2912
+ const pong = RemoteProtocol.createPong(message.timestamp || Date.now());
2913
+ this.controlChannel.send(RemoteProtocol.serialize(pong));
2914
+ }
2915
+ } else if (message.type === "pong") {
2916
+ const pingTime = message.payload?.pingTimestamp || message.timestamp;
2917
+ if (pingTime) {
2918
+ this.rttMs = Math.max(1, Date.now() - pingTime);
2919
+ this.updateDiagnostics();
2920
+ }
2921
+ }
2922
+ }
2923
+ startTimers() {
2924
+ this.stopTimers();
2925
+ this.pingTimer = setInterval(() => {
2926
+ if (this.controlChannel?.readyState === "open") {
2927
+ this.controlChannel.send(RemoteProtocol.serialize(RemoteProtocol.createPing(Date.now())));
2928
+ }
2929
+ }, 2e3);
2930
+ this.statsTimer = setInterval(() => {
2931
+ this.queryWebRTCStats();
2932
+ }, 3e3);
2933
+ }
2934
+ stopTimers() {
2935
+ if (this.pingTimer) {
2936
+ clearInterval(this.pingTimer);
2937
+ this.pingTimer = null;
2938
+ }
2939
+ if (this.statsTimer) {
2940
+ clearInterval(this.statsTimer);
2941
+ this.statsTimer = null;
2942
+ }
2943
+ }
2944
+ async queryWebRTCStats() {
2945
+ if (!this.pc) return;
2946
+ try {
2947
+ const stats = await this.pc.getStats();
2948
+ let candidateType = "unknown";
2949
+ let protocol = "UDP";
2950
+ let route = "unknown";
2951
+ stats.forEach((report) => {
2952
+ if (report.type === "candidate-pair" && (report.selected || report.state === "succeeded")) {
2953
+ const localCandidate = stats.get(report.localCandidateId);
2954
+ if (localCandidate) {
2955
+ candidateType = localCandidate.candidateType || "host";
2956
+ protocol = localCandidate.protocol || "UDP";
2957
+ if (candidateType === "host") {
2958
+ route = "direct / LAN";
2959
+ } else if (candidateType === "srflx" || candidateType === "prflx") {
2960
+ route = "STUN / WAN";
2961
+ } else if (candidateType === "relay") {
2962
+ route = "relay / TURN";
2963
+ }
2964
+ }
2965
+ if (report.currentRoundTripTime) {
2966
+ this.rttMs = Math.round(report.currentRoundTripTime * 1e3);
2967
+ }
2968
+ }
2969
+ });
2970
+ this.diagnostics = {
2971
+ ...this.diagnostics,
2972
+ candidateType,
2973
+ protocol,
2974
+ route
2975
+ };
2976
+ this.updateDiagnostics();
2977
+ } catch {
2978
+ }
2979
+ }
2980
+ setStatus(status) {
2981
+ this.status = status;
2982
+ this.updateDiagnostics();
2983
+ for (const listener of this.statusListeners) {
2984
+ listener(status);
2985
+ }
2986
+ }
2987
+ updateDiagnostics() {
2988
+ if (this.pc) {
2989
+ this.diagnostics.connectionState = this.pc.connectionState;
2990
+ this.diagnostics.iceConnectionState = this.pc.iceConnectionState;
2991
+ this.diagnostics.iceGatheringState = this.pc.iceGatheringState;
2992
+ this.diagnostics.signalingState = this.pc.signalingState;
2993
+ }
2994
+ const fullDiag = this.getDiagnostics();
2995
+ for (const listener of this.diagnosticsListeners) {
2996
+ listener(fullDiag);
2997
+ }
2998
+ }
2999
+ }
3000
+
3001
+ class PairingHelper {
3002
+ /**
3003
+ * Creates a new pairing session with given TTL (default 5 minutes).
3004
+ */
3005
+ static createSession(ttlMs = 5 * 60 * 1e3) {
3006
+ const now = Date.now();
3007
+ return {
3008
+ id: this.generateSessionId(),
3009
+ createdAt: now,
3010
+ expiresAt: now + ttlMs,
3011
+ status: "waiting"
3012
+ };
3013
+ }
3014
+ /**
3015
+ * Generates a short, human-readable session ID (e.g. "K7P4-M2" or "7HQ2-9X").
3016
+ */
3017
+ static generateSessionId() {
3018
+ const chars = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
3019
+ const bytes = this.getRandomBytes(4);
3020
+ let id = "";
3021
+ for (let i = 0; i < 4; i++) {
3022
+ id += chars[bytes[i] % chars.length];
3023
+ }
3024
+ const suffix = this.getRandomBytes(2);
3025
+ id += "-" + chars[suffix[0] % chars.length] + chars[suffix[1] % chars.length];
3026
+ return id;
3027
+ }
3028
+ /**
3029
+ * Generates a cryptographically strong 128-bit random secret string.
3030
+ */
3031
+ static generateSecret() {
3032
+ const bytes = this.getRandomBytes(16);
3033
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
3034
+ }
3035
+ /**
3036
+ * Formats a web pairing URL where the secret is stored strictly in the URL fragment (#SECRET).
3037
+ */
3038
+ static formatPairingUrl(baseUrl, sessionId, secret) {
3039
+ const cleanBase = baseUrl.replace(/\/+$/, "");
3040
+ return `${cleanBase}/pair?s=${encodeURIComponent(sessionId)}#${secret}`;
3041
+ }
3042
+ /**
3043
+ * Formats a Capacitor mobile deep link URL.
3044
+ */
3045
+ static formatDeepLinkUrl(sessionId, secret, signalingUrl) {
3046
+ let url = `capdebug://pair?session=${encodeURIComponent(sessionId)}&secret=${encodeURIComponent(secret)}`;
3047
+ if (signalingUrl) {
3048
+ url += `&server=${encodeURIComponent(signalingUrl)}`;
3049
+ }
3050
+ return url;
3051
+ }
3052
+ /**
3053
+ * Parses a web pairing URL or Capacitor deep-link URL into session and secret components.
3054
+ */
3055
+ static parseUrl(urlStr) {
3056
+ if (!urlStr || typeof urlStr !== "string") return null;
3057
+ try {
3058
+ if (urlStr.startsWith("capdebug://")) {
3059
+ const queryIdx = urlStr.indexOf("?");
3060
+ if (queryIdx === -1) return null;
3061
+ const search = urlStr.substring(queryIdx + 1);
3062
+ const params = new URLSearchParams(search);
3063
+ const sessionId2 = params.get("session") || params.get("s");
3064
+ const secret2 = params.get("secret") || params.get("sec") || "";
3065
+ const signalingUrl2 = params.get("server") || params.get("sig") || void 0;
3066
+ if (sessionId2 && secret2) {
3067
+ return { sessionId: sessionId2, secret: secret2, signalingUrl: signalingUrl2, rawUrl: urlStr };
3068
+ }
3069
+ return null;
3070
+ }
3071
+ const url = new URL(urlStr);
3072
+ let sessionId = url.searchParams.get("s") || url.searchParams.get("session");
3073
+ if (!sessionId && url.pathname.includes("/s/")) {
3074
+ const parts = url.pathname.split("/s/");
3075
+ if (parts[1]) {
3076
+ sessionId = decodeURIComponent(parts[1].split("/")[0]);
3077
+ }
3078
+ }
3079
+ let secret = url.hash.replace(/^#/, "");
3080
+ if (!secret) {
3081
+ secret = url.searchParams.get("secret") || url.searchParams.get("sec") || "";
3082
+ }
3083
+ const signalingUrl = url.searchParams.get("server") || `${url.protocol}//${url.host}`;
3084
+ if (sessionId && secret) {
3085
+ return {
3086
+ sessionId: sessionId.trim(),
3087
+ secret: secret.trim(),
3088
+ signalingUrl,
3089
+ rawUrl: urlStr
3090
+ };
3091
+ }
3092
+ return null;
3093
+ } catch {
3094
+ return null;
3095
+ }
3096
+ }
3097
+ static getRandomBytes(length) {
3098
+ const bytes = new Uint8Array(length);
3099
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
3100
+ crypto.getRandomValues(bytes);
3101
+ } else {
3102
+ for (let i = 0; i < length; i++) {
3103
+ bytes[i] = Math.floor(Math.random() * 256);
3104
+ }
3105
+ }
3106
+ return bytes;
3107
+ }
3108
+ }
3109
+
3110
+ class RemoteManager {
3111
+ transport;
3112
+ store;
3113
+ isListening = false;
3114
+ eventListener = null;
3115
+ constructor(store) {
3116
+ this.store = store;
3117
+ this.transport = new WebRTCTransport();
3118
+ this.setupControlHandler();
3119
+ }
3120
+ get activeTransport() {
3121
+ return this.transport;
3122
+ }
3123
+ async connect(config) {
3124
+ this.startEventListener();
3125
+ await this.transport.connect(config);
3126
+ }
3127
+ disconnect() {
3128
+ this.transport.disconnect();
3129
+ this.stopEventListener();
3130
+ }
3131
+ status() {
3132
+ return this.transport.getStatus();
3133
+ }
3134
+ getDiagnostics() {
3135
+ return this.transport.getDiagnostics();
3136
+ }
3137
+ async handlePairingUrl(url) {
3138
+ const parsed = PairingHelper.parseUrl(url);
3139
+ if (!parsed) {
3140
+ console.warn("[CapDebug Remote] Invalid pairing URL:", url);
3141
+ return false;
3142
+ }
3143
+ try {
3144
+ await this.connect({
3145
+ sessionId: parsed.sessionId,
3146
+ secret: parsed.secret,
3147
+ signalingUrl: parsed.signalingUrl,
3148
+ isHost: false
3149
+ });
3150
+ return true;
3151
+ } catch (err) {
3152
+ console.error("[CapDebug Remote] Failed to connect via pairing URL:", err);
3153
+ return false;
3154
+ }
3155
+ }
3156
+ startEventListener() {
3157
+ if (this.isListening || typeof window === "undefined") return;
3158
+ this.eventListener = (event) => {
3159
+ const customEvent = event;
3160
+ if (customEvent.detail) {
3161
+ this.transport.send(customEvent.detail);
3162
+ }
3163
+ };
3164
+ window.addEventListener("capdebug", this.eventListener);
3165
+ this.isListening = true;
3166
+ }
3167
+ stopEventListener() {
3168
+ if (!this.isListening || typeof window === "undefined") return;
3169
+ if (this.eventListener) {
3170
+ window.removeEventListener("capdebug", this.eventListener);
3171
+ this.eventListener = null;
3172
+ }
3173
+ this.isListening = false;
3174
+ }
3175
+ setupControlHandler() {
3176
+ this.transport.onControl(async (cmd) => {
3177
+ switch (cmd.type) {
3178
+ case "pause":
3179
+ this.store.pause();
3180
+ break;
3181
+ case "resume":
3182
+ this.store.resume();
3183
+ break;
3184
+ case "clear":
3185
+ this.store.clear();
3186
+ break;
3187
+ case "snapshot.request":
3188
+ try {
3189
+ const [device, memory, webView, app, network] = await Promise.allSettled([
3190
+ CapDebugNative.getDeviceInfo(),
3191
+ CapDebugNative.getMemoryInfo(),
3192
+ CapDebugNative.getWebViewInfo(),
3193
+ CapDebugNative.getAppInfo(),
3194
+ CapDebugNative.getNetworkInfo()
3195
+ ]);
3196
+ const snapshot = {
3197
+ device: device.status === "fulfilled" ? device.value : null,
3198
+ memory: memory.status === "fulfilled" ? memory.value : null,
3199
+ webView: webView.status === "fulfilled" ? webView.value : null,
3200
+ app: app.status === "fulfilled" ? app.value : null,
3201
+ network: network.status === "fulfilled" ? network.value : null
3202
+ };
3203
+ this.transport.send({
3204
+ id: "diag_" + Date.now(),
3205
+ timestamp: Date.now(),
3206
+ source: "native",
3207
+ type: "device.snapshot",
3208
+ level: "info",
3209
+ message: "Live native diagnostics snapshot",
3210
+ data: snapshot
3211
+ });
3212
+ } catch (err) {
3213
+ console.error("[CapDebug Remote] Failed snapshot:", err);
3214
+ }
3215
+ break;
3216
+ case "disconnect":
3217
+ this.disconnect();
3218
+ break;
3219
+ }
3220
+ });
3221
+ }
3222
+ }
3223
+
3224
+ class DeepLinkHandler {
3225
+ static parse(url) {
3226
+ return PairingHelper.parseUrl(url);
3227
+ }
3228
+ }
3229
+
2380
3230
  class CapDebugManager {
2381
3231
  store;
2382
3232
  viewerElement = null;
2383
3233
  isMounted = false;
3234
+ remoteManager;
2384
3235
  customEventCollector;
2385
3236
  consoleCollector;
2386
3237
  errorCollector;
@@ -2389,6 +3240,7 @@ class CapDebugManager {
2389
3240
  bridgeCollector;
2390
3241
  constructor() {
2391
3242
  this.store = new CapDebugStore();
3243
+ this.remoteManager = new RemoteManager(this.store);
2392
3244
  this.customEventCollector = new CustomEventCollector(this.store);
2393
3245
  this.consoleCollector = new ConsoleCollector();
2394
3246
  this.errorCollector = new ErrorCollector();
@@ -2396,6 +3248,12 @@ class CapDebugManager {
2396
3248
  this.browserEventCollector = new BrowserEventCollector();
2397
3249
  this.bridgeCollector = new BridgeCollector();
2398
3250
  }
3251
+ get remote() {
3252
+ return this.remoteManager;
3253
+ }
3254
+ async handlePairingUrl(url) {
3255
+ return this.remoteManager.handlePairingUrl(url);
3256
+ }
2399
3257
  get native() {
2400
3258
  return CapDebugNative;
2401
3259
  }
@@ -2637,9 +3495,17 @@ exports.CapDebugViewerElement = CapDebugViewerElement;
2637
3495
  exports.ConsoleCollector = ConsoleCollector;
2638
3496
  exports.CustomEventCollector = CustomEventCollector;
2639
3497
  exports.DataSanitizer = DataSanitizer;
3498
+ exports.DeepLinkHandler = DeepLinkHandler;
2640
3499
  exports.ErrorCollector = ErrorCollector;
3500
+ exports.HttpSseSignalingClient = HttpSseSignalingClient;
2641
3501
  exports.JsonViewer = JsonViewer;
2642
3502
  exports.NetworkCollector = NetworkCollector;
3503
+ exports.PROTOCOL_VERSION = PROTOCOL_VERSION;
3504
+ exports.PairingHelper = PairingHelper;
3505
+ exports.RemoteEventBuffer = RemoteEventBuffer;
3506
+ exports.RemoteManager = RemoteManager;
3507
+ exports.RemoteProtocol = RemoteProtocol;
3508
+ exports.WebRTCTransport = WebRTCTransport;
2643
3509
  exports.default = CapDebug;
2644
3510
  exports.defaultSanitizer = defaultSanitizer;
2645
3511
  exports.registerCustomElement = registerCustomElement;