react-native-debug-toolkit 2.3.0 → 3.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.
- package/bin/debug-toolkit.js +114 -0
- package/lib/commonjs/features/network/index.js +28 -2
- package/lib/commonjs/features/network/index.js.map +1 -1
- package/lib/commonjs/features/network/networkInterceptor.js +14 -6
- package/lib/commonjs/features/network/networkInterceptor.js.map +1 -1
- package/lib/commonjs/index.js +59 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/panel/DebugPanel.js +25 -0
- package/lib/commonjs/ui/panel/DebugPanel.js.map +1 -1
- package/lib/commonjs/ui/panel/FloatPanelView.js +15 -62
- package/lib/commonjs/ui/panel/FloatPanelView.js.map +1 -1
- package/lib/commonjs/ui/panel/StreamingSettingsModal.js +529 -0
- package/lib/commonjs/ui/panel/StreamingSettingsModal.js.map +1 -0
- package/lib/commonjs/ui/panel/useTabAnimation.js +71 -0
- package/lib/commonjs/ui/panel/useTabAnimation.js.map +1 -0
- package/lib/commonjs/utils/autoDetectDaemon.js +141 -0
- package/lib/commonjs/utils/autoDetectDaemon.js.map +1 -0
- package/lib/commonjs/utils/createPersistedObservableStore.js +23 -3
- package/lib/commonjs/utils/createPersistedObservableStore.js.map +1 -1
- package/lib/commonjs/utils/daemonConnection.js +81 -0
- package/lib/commonjs/utils/daemonConnection.js.map +1 -0
- package/lib/commonjs/utils/daemonSettings.js +110 -0
- package/lib/commonjs/utils/daemonSettings.js.map +1 -0
- package/lib/commonjs/utils/reportToDaemon.js +112 -0
- package/lib/commonjs/utils/reportToDaemon.js.map +1 -0
- package/lib/commonjs/utils/sessionReport.js +132 -0
- package/lib/commonjs/utils/sessionReport.js.map +1 -0
- package/lib/commonjs/utils/streamToDaemon.js +334 -0
- package/lib/commonjs/utils/streamToDaemon.js.map +1 -0
- package/lib/module/features/network/index.js +25 -1
- package/lib/module/features/network/index.js.map +1 -1
- package/lib/module/features/network/networkInterceptor.js +14 -6
- package/lib/module/features/network/networkInterceptor.js.map +1 -1
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/panel/DebugPanel.js +26 -1
- package/lib/module/ui/panel/DebugPanel.js.map +1 -1
- package/lib/module/ui/panel/FloatPanelView.js +16 -63
- package/lib/module/ui/panel/FloatPanelView.js.map +1 -1
- package/lib/module/ui/panel/StreamingSettingsModal.js +524 -0
- package/lib/module/ui/panel/StreamingSettingsModal.js.map +1 -0
- package/lib/module/ui/panel/useTabAnimation.js +67 -0
- package/lib/module/ui/panel/useTabAnimation.js.map +1 -0
- package/lib/module/utils/autoDetectDaemon.js +136 -0
- package/lib/module/utils/autoDetectDaemon.js.map +1 -0
- package/lib/module/utils/createPersistedObservableStore.js +23 -3
- package/lib/module/utils/createPersistedObservableStore.js.map +1 -1
- package/lib/module/utils/daemonConnection.js +77 -0
- package/lib/module/utils/daemonConnection.js.map +1 -0
- package/lib/module/utils/daemonSettings.js +102 -0
- package/lib/module/utils/daemonSettings.js.map +1 -0
- package/lib/module/utils/reportToDaemon.js +105 -0
- package/lib/module/utils/reportToDaemon.js.map +1 -0
- package/lib/module/utils/sessionReport.js +128 -0
- package/lib/module/utils/sessionReport.js.map +1 -0
- package/lib/module/utils/streamToDaemon.js +328 -0
- package/lib/module/utils/streamToDaemon.js.map +1 -0
- package/lib/typescript/src/features/network/index.d.ts +2 -0
- package/lib/typescript/src/features/network/index.d.ts.map +1 -1
- package/lib/typescript/src/features/network/networkInterceptor.d.ts +1 -1
- package/lib/typescript/src/features/network/networkInterceptor.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +10 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/ui/panel/DebugPanel.d.ts.map +1 -1
- package/lib/typescript/src/ui/panel/FloatPanelView.d.ts.map +1 -1
- package/lib/typescript/src/ui/panel/StreamingSettingsModal.d.ts +8 -0
- package/lib/typescript/src/ui/panel/StreamingSettingsModal.d.ts.map +1 -0
- package/lib/typescript/src/ui/panel/useTabAnimation.d.ts +14 -0
- package/lib/typescript/src/ui/panel/useTabAnimation.d.ts.map +1 -0
- package/lib/typescript/src/utils/autoDetectDaemon.d.ts +15 -0
- package/lib/typescript/src/utils/autoDetectDaemon.d.ts.map +1 -0
- package/lib/typescript/src/utils/createPersistedObservableStore.d.ts +2 -1
- package/lib/typescript/src/utils/createPersistedObservableStore.d.ts.map +1 -1
- package/lib/typescript/src/utils/daemonConnection.d.ts +18 -0
- package/lib/typescript/src/utils/daemonConnection.d.ts.map +1 -0
- package/lib/typescript/src/utils/daemonSettings.d.ts +19 -0
- package/lib/typescript/src/utils/daemonSettings.d.ts.map +1 -0
- package/lib/typescript/src/utils/reportToDaemon.d.ts +34 -0
- package/lib/typescript/src/utils/reportToDaemon.d.ts.map +1 -0
- package/lib/typescript/src/utils/sessionReport.d.ts +18 -0
- package/lib/typescript/src/utils/sessionReport.d.ts.map +1 -0
- package/lib/typescript/src/utils/streamToDaemon.d.ts +23 -0
- package/lib/typescript/src/utils/streamToDaemon.d.ts.map +1 -0
- package/node/daemon/src/cli.js +75 -0
- package/node/daemon/src/console/console.html +936 -0
- package/node/daemon/src/console/index.js +47 -0
- package/node/daemon/src/constants.js +32 -0
- package/node/daemon/src/index.js +11 -0
- package/node/daemon/src/server.js +365 -0
- package/node/daemon/src/store.js +110 -0
- package/node/mcp/src/cli.js +31 -0
- package/node/mcp/src/constants.js +13 -0
- package/node/mcp/src/daemonClient.js +132 -0
- package/node/mcp/src/httpClient.js +49 -0
- package/node/mcp/src/index.js +15 -0
- package/node/mcp/src/logs.js +95 -0
- package/node/mcp/src/server.js +144 -0
- package/node/mcp/src/tools.js +84 -0
- package/package.json +7 -2
- package/src/features/network/index.ts +30 -3
- package/src/features/network/networkInterceptor.ts +19 -6
- package/src/index.ts +14 -0
- package/src/ui/panel/DebugPanel.tsx +23 -1
- package/src/ui/panel/FloatPanelView.tsx +10 -68
- package/src/ui/panel/StreamingSettingsModal.tsx +566 -0
- package/src/ui/panel/useTabAnimation.ts +77 -0
- package/src/utils/autoDetectDaemon.ts +175 -0
- package/src/utils/createPersistedObservableStore.ts +16 -3
- package/src/utils/daemonConnection.ts +133 -0
- package/src/utils/daemonSettings.ts +134 -0
- package/src/utils/reportToDaemon.ts +172 -0
- package/src/utils/sessionReport.ts +203 -0
- package/src/utils/streamToDaemon.ts +419 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NativeModules } from 'react-native';
|
|
4
|
+
const DEFAULT_PORT = 3799;
|
|
5
|
+
const PROBE_TIMEOUT_MS = 1500;
|
|
6
|
+
const DEFAULT_BATCH_SIZE = 20;
|
|
7
|
+
const COMMON_SUBNETS = ['192.168.0', '192.168.1', '192.168.2', '192.168.3', '192.168.4', '192.168.31', '192.168.43', '192.168.50', '192.168.68', '192.168.100', '10.0.0', '10.0.1', '10.0.2', '172.16.0'];
|
|
8
|
+
const SIMULATOR_HOSTS = ['localhost', '127.0.0.1', '10.0.2.2'];
|
|
9
|
+
export function getMetroHost() {
|
|
10
|
+
try {
|
|
11
|
+
const scriptURL = NativeModules?.SourceCode?.scriptURL;
|
|
12
|
+
if (typeof scriptURL !== 'string') return null;
|
|
13
|
+
const url = new URL(scriptURL);
|
|
14
|
+
if (SIMULATOR_HOSTS.includes(url.hostname)) return null;
|
|
15
|
+
return url.hostname;
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function getNetworkInfo() {
|
|
21
|
+
try {
|
|
22
|
+
const mod = require('react-native-network-info');
|
|
23
|
+
return mod.default || mod;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getSubnetPrefix(ip) {
|
|
29
|
+
const parts = ip.split('.');
|
|
30
|
+
if (parts.length !== 4) return null;
|
|
31
|
+
return parts.slice(0, 3).join('.');
|
|
32
|
+
}
|
|
33
|
+
function buildCandidates(prefix) {
|
|
34
|
+
const candidates = [];
|
|
35
|
+
for (let i = 1; i <= 255; i++) {
|
|
36
|
+
candidates.push(`${prefix}.${i}`);
|
|
37
|
+
}
|
|
38
|
+
return candidates;
|
|
39
|
+
}
|
|
40
|
+
async function probeIp(ip, port, timeoutMs, signal) {
|
|
41
|
+
if (signal?.aborted) return false;
|
|
42
|
+
const fetchImpl = globalThis.fetch;
|
|
43
|
+
if (!fetchImpl) return false;
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
46
|
+
const onAbort = () => controller.abort();
|
|
47
|
+
signal?.addEventListener('abort', onAbort, {
|
|
48
|
+
once: true
|
|
49
|
+
});
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetchImpl(`http://${ip}:${port}/health`, {
|
|
52
|
+
method: 'GET',
|
|
53
|
+
signal: controller.signal
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) return false;
|
|
56
|
+
try {
|
|
57
|
+
const body = await response.json();
|
|
58
|
+
return body != null && typeof body === 'object' && body.ok === true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
} finally {
|
|
65
|
+
clearTimeout(timeout);
|
|
66
|
+
signal?.removeEventListener('abort', onAbort);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function probeBatch(candidates, port, timeoutMs, batchSize, signal) {
|
|
70
|
+
for (let i = 0; i < candidates.length; i += batchSize) {
|
|
71
|
+
if (signal?.aborted) return null;
|
|
72
|
+
const batch = candidates.slice(i, i + batchSize);
|
|
73
|
+
const results = await Promise.all(batch.map(ip => probeIp(ip, port, timeoutMs, signal)));
|
|
74
|
+
const idx = results.findIndex(Boolean);
|
|
75
|
+
if (idx !== -1) return batch[idx] ?? null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
export async function autoDetectDaemonIp(options = {}) {
|
|
80
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
81
|
+
const timeoutMs = options.timeoutMs ?? PROBE_TIMEOUT_MS;
|
|
82
|
+
const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
83
|
+
const scanSubnets = options.scanSubnets ?? true;
|
|
84
|
+
const {
|
|
85
|
+
signal
|
|
86
|
+
} = options;
|
|
87
|
+
|
|
88
|
+
// Strategy 0: extract Mac IP from Metro bundle URL (zero-dep, instant)
|
|
89
|
+
const metroHost = getMetroHost();
|
|
90
|
+
if (metroHost) {
|
|
91
|
+
const alive = await probeIp(metroHost, port, timeoutMs, signal);
|
|
92
|
+
if (alive) return {
|
|
93
|
+
ip: metroHost,
|
|
94
|
+
method: 'metro-bundle'
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (!scanSubnets) {
|
|
98
|
+
return {
|
|
99
|
+
ip: null,
|
|
100
|
+
method: 'none'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Strategy 1: react-native-network-info → device IP → subnet scan
|
|
105
|
+
const networkInfo = getNetworkInfo();
|
|
106
|
+
if (networkInfo?.getIPAddress) {
|
|
107
|
+
try {
|
|
108
|
+
const deviceIp = await networkInfo.getIPAddress();
|
|
109
|
+
const prefix = getSubnetPrefix(deviceIp);
|
|
110
|
+
if (prefix) {
|
|
111
|
+
const found = await probeBatch(buildCandidates(prefix), port, timeoutMs, batchSize, signal);
|
|
112
|
+
if (found) return {
|
|
113
|
+
ip: found,
|
|
114
|
+
method: 'network-info'
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
} catch {
|
|
118
|
+
// fall through
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Strategy 2: common subnet probe
|
|
123
|
+
for (const prefix of COMMON_SUBNETS) {
|
|
124
|
+
if (signal?.aborted) break;
|
|
125
|
+
const found = await probeBatch(buildCandidates(prefix), port, timeoutMs, batchSize, signal);
|
|
126
|
+
if (found) return {
|
|
127
|
+
ip: found,
|
|
128
|
+
method: 'subnet-common'
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
ip: null,
|
|
133
|
+
method: 'none'
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=autoDetectDaemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeModules","DEFAULT_PORT","PROBE_TIMEOUT_MS","DEFAULT_BATCH_SIZE","COMMON_SUBNETS","SIMULATOR_HOSTS","getMetroHost","scriptURL","SourceCode","url","URL","includes","hostname","getNetworkInfo","mod","require","default","getSubnetPrefix","ip","parts","split","length","slice","join","buildCandidates","prefix","candidates","i","push","probeIp","port","timeoutMs","signal","aborted","fetchImpl","globalThis","fetch","controller","AbortController","timeout","setTimeout","abort","onAbort","addEventListener","once","response","method","ok","body","json","clearTimeout","removeEventListener","probeBatch","batchSize","batch","results","Promise","all","map","idx","findIndex","Boolean","autoDetectDaemonIp","options","scanSubnets","metroHost","alive","networkInfo","getIPAddress","deviceIp","found"],"sourceRoot":"../../../src","sources":["utils/autoDetectDaemon.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -12,13 +12,23 @@ export function createPersistedObservableStore(options) {
|
|
|
12
12
|
const store = createObservableStore();
|
|
13
13
|
let writeTimer = null;
|
|
14
14
|
let idCounter = 0;
|
|
15
|
+
let resolveReady;
|
|
16
|
+
const ready = new Promise(resolve => {
|
|
17
|
+
resolveReady = resolve;
|
|
18
|
+
});
|
|
15
19
|
|
|
16
20
|
// Restore from storage (single notify via pushBatch)
|
|
17
21
|
getPreference(storageKey).then(raw => {
|
|
18
|
-
if (!raw)
|
|
22
|
+
if (!raw) {
|
|
23
|
+
resolveReady();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
19
26
|
try {
|
|
20
27
|
const entries = JSON.parse(raw);
|
|
21
|
-
if (!Array.isArray(entries))
|
|
28
|
+
if (!Array.isArray(entries)) {
|
|
29
|
+
resolveReady();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
22
32
|
const restored = entries.slice(-maxPersist);
|
|
23
33
|
store.pushBatch(restored);
|
|
24
34
|
// Fix ID counter to avoid collision with restored entries
|
|
@@ -31,6 +41,7 @@ export function createPersistedObservableStore(options) {
|
|
|
31
41
|
} catch {
|
|
32
42
|
// ignore corrupt data
|
|
33
43
|
}
|
|
44
|
+
resolveReady();
|
|
34
45
|
});
|
|
35
46
|
function scheduleWrite() {
|
|
36
47
|
if (writeTimer !== null) clearTimeout(writeTimer);
|
|
@@ -61,7 +72,16 @@ export function createPersistedObservableStore(options) {
|
|
|
61
72
|
setPreference(storageKey, '[]');
|
|
62
73
|
},
|
|
63
74
|
subscribe: store.subscribe,
|
|
64
|
-
nextId: () => String(idCounter++)
|
|
75
|
+
nextId: () => String(idCounter++),
|
|
76
|
+
ready,
|
|
77
|
+
destroy: () => {
|
|
78
|
+
if (writeTimer !== null) {
|
|
79
|
+
clearTimeout(writeTimer);
|
|
80
|
+
writeTimer = null;
|
|
81
|
+
}
|
|
82
|
+
store.clear();
|
|
83
|
+
setPreference(storageKey, '[]');
|
|
84
|
+
}
|
|
65
85
|
};
|
|
66
86
|
}
|
|
67
87
|
//# sourceMappingURL=createPersistedObservableStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createObservableStore","getPreference","setPreference","createPersistedObservableStore","options","storageKey","maxPersist","debounceMs","serialize","store","writeTimer","idCounter","then","raw","entries","JSON","parse","Array","isArray","restored","slice","pushBatch","max","e","n","parseInt","id","isNaN","scheduleWrite","clearTimeout","setTimeout","data","getData","toStore","map","stringify","push","item","maxEntries","clear","subscribe","nextId","String"],"sourceRoot":"../../../src","sources":["utils/createPersistedObservableStore.ts"],"mappings":";;AAAA,SAASA,qBAAqB,QAA8B,yBAAyB;AACrF,SAASC,aAAa,EAAEC,aAAa,QAAQ,oBAAoB;
|
|
1
|
+
{"version":3,"names":["createObservableStore","getPreference","setPreference","createPersistedObservableStore","options","storageKey","maxPersist","debounceMs","serialize","store","writeTimer","idCounter","resolveReady","ready","Promise","resolve","then","raw","entries","JSON","parse","Array","isArray","restored","slice","pushBatch","max","e","n","parseInt","id","isNaN","scheduleWrite","clearTimeout","setTimeout","data","getData","toStore","map","stringify","push","item","maxEntries","clear","subscribe","nextId","String","destroy"],"sourceRoot":"../../../src","sources":["utils/createPersistedObservableStore.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { buildDaemonUrl, getDefaultDaemonEndpoint, getGlobalFetch } from './reportToDaemon';
|
|
4
|
+
const DEFAULT_HEALTH_TIMEOUT_MS = 2000;
|
|
5
|
+
function createAbortController() {
|
|
6
|
+
const AbortControllerCtor = globalThis.AbortController;
|
|
7
|
+
return AbortControllerCtor ? new AbortControllerCtor() : undefined;
|
|
8
|
+
}
|
|
9
|
+
async function readHealthBody(response) {
|
|
10
|
+
try {
|
|
11
|
+
const body = response.json ? await response.json() : null;
|
|
12
|
+
return body && typeof body === 'object' && !Array.isArray(body) ? body : null;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export async function checkDaemonConnection(options = {}) {
|
|
18
|
+
const endpoint = options.endpoint ?? getDefaultDaemonEndpoint();
|
|
19
|
+
const healthUrl = buildDaemonUrl(endpoint, '/health');
|
|
20
|
+
const fetchImpl = getGlobalFetch();
|
|
21
|
+
if (!fetchImpl) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
endpoint,
|
|
25
|
+
reason: 'fetch_unavailable',
|
|
26
|
+
error: 'global fetch is not available'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const timeoutMs = Math.max(0, options.timeoutMs ?? DEFAULT_HEALTH_TIMEOUT_MS);
|
|
30
|
+
const controller = createAbortController();
|
|
31
|
+
let timedOut = false;
|
|
32
|
+
const timeout = controller && timeoutMs > 0 ? setTimeout(() => {
|
|
33
|
+
timedOut = true;
|
|
34
|
+
controller.abort();
|
|
35
|
+
}, timeoutMs) : undefined;
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetchImpl(healthUrl, {
|
|
38
|
+
method: 'GET',
|
|
39
|
+
headers: {},
|
|
40
|
+
signal: controller?.signal
|
|
41
|
+
});
|
|
42
|
+
const body = await readHealthBody(response);
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
endpoint,
|
|
47
|
+
reason: 'http',
|
|
48
|
+
status: response.status
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (body?.ok !== true) {
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
endpoint,
|
|
55
|
+
reason: 'invalid_response',
|
|
56
|
+
status: response.status
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
ok: true,
|
|
61
|
+
endpoint,
|
|
62
|
+
status: response.status
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
endpoint,
|
|
68
|
+
reason: timedOut ? 'timeout' : 'network',
|
|
69
|
+
error: error instanceof Error ? error.message : String(error)
|
|
70
|
+
};
|
|
71
|
+
} finally {
|
|
72
|
+
if (timeout) {
|
|
73
|
+
clearTimeout(timeout);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=daemonConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["buildDaemonUrl","getDefaultDaemonEndpoint","getGlobalFetch","DEFAULT_HEALTH_TIMEOUT_MS","createAbortController","AbortControllerCtor","globalThis","AbortController","undefined","readHealthBody","response","body","json","Array","isArray","checkDaemonConnection","options","endpoint","healthUrl","fetchImpl","ok","reason","error","timeoutMs","Math","max","controller","timedOut","timeout","setTimeout","abort","method","headers","signal","status","Error","message","String","clearTimeout"],"sourceRoot":"../../../src","sources":["utils/daemonConnection.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export const DAEMON_ENDPOINT_STORAGE_KEY = 'debugToolkit_streamEndpoint';
|
|
4
|
+
export const DAEMON_TOKEN_STORAGE_KEY = 'debugToolkit_streamToken';
|
|
5
|
+
export const DAEMON_CONNECTION_MODE_STORAGE_KEY = 'debugToolkit_connectionMode';
|
|
6
|
+
export const DAEMON_DEVICE_HOST_STORAGE_KEY = 'debugToolkit_deviceHost';
|
|
7
|
+
function getAsyncStorage() {
|
|
8
|
+
try {
|
|
9
|
+
const asyncStorageModule = require('@react-native-async-storage/async-storage');
|
|
10
|
+
return asyncStorageModule.default || asyncStorageModule;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function loadDaemonSettings() {
|
|
16
|
+
const AsyncStorage = getAsyncStorage();
|
|
17
|
+
if (!AsyncStorage) {
|
|
18
|
+
return {
|
|
19
|
+
mode: 'simulator',
|
|
20
|
+
endpoint: '',
|
|
21
|
+
deviceHost: '',
|
|
22
|
+
token: ''
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const [mode, endpoint, deviceHost, token] = await Promise.all([AsyncStorage.getItem(DAEMON_CONNECTION_MODE_STORAGE_KEY), AsyncStorage.getItem(DAEMON_ENDPOINT_STORAGE_KEY), AsyncStorage.getItem(DAEMON_DEVICE_HOST_STORAGE_KEY), AsyncStorage.getItem(DAEMON_TOKEN_STORAGE_KEY)]);
|
|
27
|
+
const inferredMode = readMode(mode, endpoint || '');
|
|
28
|
+
const inferredHost = deviceHost || extractDeviceHost(endpoint || '');
|
|
29
|
+
return {
|
|
30
|
+
mode: inferredMode,
|
|
31
|
+
endpoint: endpoint || '',
|
|
32
|
+
deviceHost: inferredMode === 'device' ? inferredHost : '',
|
|
33
|
+
token: token || ''
|
|
34
|
+
};
|
|
35
|
+
} catch {
|
|
36
|
+
return {
|
|
37
|
+
mode: 'simulator',
|
|
38
|
+
endpoint: '',
|
|
39
|
+
deviceHost: '',
|
|
40
|
+
token: ''
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export async function saveDaemonSettings(settings) {
|
|
45
|
+
const AsyncStorage = getAsyncStorage();
|
|
46
|
+
if (!AsyncStorage) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const normalized = normalizeDaemonSettings(settings);
|
|
50
|
+
try {
|
|
51
|
+
await Promise.all([AsyncStorage.setItem(DAEMON_CONNECTION_MODE_STORAGE_KEY, settings.mode), AsyncStorage.setItem(DAEMON_DEVICE_HOST_STORAGE_KEY, settings.deviceHost.trim()), AsyncStorage.setItem(DAEMON_ENDPOINT_STORAGE_KEY, normalized.endpoint || ''), AsyncStorage.setItem(DAEMON_TOKEN_STORAGE_KEY, settings.token.trim())]);
|
|
52
|
+
} catch {
|
|
53
|
+
// AsyncStorage unavailable or rejected: keep runtime behavior unchanged.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function readMode(value, endpoint) {
|
|
57
|
+
if (value === 'device' || value === 'simulator') {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
return endpoint && !isSimulatorEndpoint(endpoint) ? 'device' : 'simulator';
|
|
61
|
+
}
|
|
62
|
+
function isSimulatorEndpoint(endpoint) {
|
|
63
|
+
try {
|
|
64
|
+
const url = new URL(endpoint);
|
|
65
|
+
return ['localhost', '127.0.0.1', '10.0.2.2'].includes(url.hostname);
|
|
66
|
+
} catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function extractDeviceHost(endpoint) {
|
|
71
|
+
try {
|
|
72
|
+
const url = new URL(endpoint);
|
|
73
|
+
return url.port && url.port !== '3799' ? `${url.hostname}:${url.port}` : url.hostname;
|
|
74
|
+
} catch {
|
|
75
|
+
return '';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function buildDeviceDaemonEndpoint(host) {
|
|
79
|
+
const trimmed = host.trim().replace(/\/+$/, '');
|
|
80
|
+
if (!trimmed) {
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
const withProtocol = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//.test(trimmed) ? trimmed : `http://${trimmed}`;
|
|
84
|
+
try {
|
|
85
|
+
const url = new URL(withProtocol);
|
|
86
|
+
if (!url.port) {
|
|
87
|
+
url.port = '3799';
|
|
88
|
+
}
|
|
89
|
+
return url.toString().replace(/\/$/, '');
|
|
90
|
+
} catch {
|
|
91
|
+
return withProtocol;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function normalizeDaemonSettings(settings) {
|
|
95
|
+
const endpoint = settings.mode === 'device' ? buildDeviceDaemonEndpoint(settings.deviceHost) : '';
|
|
96
|
+
const token = settings.token.trim();
|
|
97
|
+
return {
|
|
98
|
+
endpoint: endpoint || undefined,
|
|
99
|
+
token: token || undefined
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=daemonSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DAEMON_ENDPOINT_STORAGE_KEY","DAEMON_TOKEN_STORAGE_KEY","DAEMON_CONNECTION_MODE_STORAGE_KEY","DAEMON_DEVICE_HOST_STORAGE_KEY","getAsyncStorage","asyncStorageModule","require","default","loadDaemonSettings","AsyncStorage","mode","endpoint","deviceHost","token","Promise","all","getItem","inferredMode","readMode","inferredHost","extractDeviceHost","saveDaemonSettings","settings","normalized","normalizeDaemonSettings","setItem","trim","value","isSimulatorEndpoint","url","URL","includes","hostname","port","buildDeviceDaemonEndpoint","host","trimmed","replace","withProtocol","test","toString","undefined"],"sourceRoot":"../../../src","sources":["utils/daemonSettings.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import { _addDaemonEndpointToNetworkBlacklist } from '../features/network';
|
|
5
|
+
import { createDebugSessionReport } from './sessionReport';
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 3000;
|
|
7
|
+
export function getGlobalFetch() {
|
|
8
|
+
return globalThis.fetch;
|
|
9
|
+
}
|
|
10
|
+
function createAbortController() {
|
|
11
|
+
const AbortControllerCtor = globalThis.AbortController;
|
|
12
|
+
return AbortControllerCtor ? new AbortControllerCtor() : undefined;
|
|
13
|
+
}
|
|
14
|
+
export function getDefaultDaemonEndpoint() {
|
|
15
|
+
if (Platform.OS === 'android') {
|
|
16
|
+
return 'http://10.0.2.2:3799';
|
|
17
|
+
}
|
|
18
|
+
return 'http://localhost:3799';
|
|
19
|
+
}
|
|
20
|
+
export function buildDaemonUrl(endpoint, path) {
|
|
21
|
+
const trimmed = endpoint.replace(/\/+$/, '');
|
|
22
|
+
return trimmed.endsWith(path) ? trimmed : `${trimmed}${path}`;
|
|
23
|
+
}
|
|
24
|
+
async function readResponseBody(response) {
|
|
25
|
+
try {
|
|
26
|
+
if (response.json) {
|
|
27
|
+
return await response.json();
|
|
28
|
+
}
|
|
29
|
+
if (response.text) {
|
|
30
|
+
const text = await response.text();
|
|
31
|
+
return text ? JSON.parse(text) : null;
|
|
32
|
+
}
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function readLogCount(value) {
|
|
39
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return Object.entries(value).reduce((acc, [key, count]) => {
|
|
43
|
+
if (typeof count === 'number') {
|
|
44
|
+
acc[key] = count;
|
|
45
|
+
}
|
|
46
|
+
return acc;
|
|
47
|
+
}, {});
|
|
48
|
+
}
|
|
49
|
+
export async function reportDebugSessionToDaemon(options = {}) {
|
|
50
|
+
const endpoint = options.endpoint ?? getDefaultDaemonEndpoint();
|
|
51
|
+
const reportUrl = buildDaemonUrl(endpoint, '/report');
|
|
52
|
+
const report = createDebugSessionReport(options);
|
|
53
|
+
const fetchImpl = getGlobalFetch();
|
|
54
|
+
_addDaemonEndpointToNetworkBlacklist(endpoint);
|
|
55
|
+
_addDaemonEndpointToNetworkBlacklist(reportUrl);
|
|
56
|
+
if (!fetchImpl) {
|
|
57
|
+
return {
|
|
58
|
+
ok: false,
|
|
59
|
+
endpoint,
|
|
60
|
+
report,
|
|
61
|
+
error: 'global fetch is not available'
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const timeoutMs = Math.max(0, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
65
|
+
const controller = createAbortController();
|
|
66
|
+
const timeout = controller && timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : undefined;
|
|
67
|
+
try {
|
|
68
|
+
const headers = {
|
|
69
|
+
'Content-Type': 'application/json'
|
|
70
|
+
};
|
|
71
|
+
if (options.token) {
|
|
72
|
+
headers.Authorization = `Bearer ${options.token}`;
|
|
73
|
+
}
|
|
74
|
+
const response = await fetchImpl(reportUrl, {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers,
|
|
77
|
+
body: JSON.stringify(report),
|
|
78
|
+
signal: controller?.signal
|
|
79
|
+
});
|
|
80
|
+
const responseBody = await readResponseBody(response);
|
|
81
|
+
const bodyObject = responseBody && typeof responseBody === 'object' ? responseBody : {};
|
|
82
|
+
return {
|
|
83
|
+
ok: response.ok && bodyObject.ok === true,
|
|
84
|
+
endpoint,
|
|
85
|
+
report,
|
|
86
|
+
status: response.status,
|
|
87
|
+
sessionId: typeof bodyObject.sessionId === 'string' ? bodyObject.sessionId : undefined,
|
|
88
|
+
receivedAt: typeof bodyObject.receivedAt === 'string' ? bodyObject.receivedAt : undefined,
|
|
89
|
+
logCount: readLogCount(bodyObject.logCount),
|
|
90
|
+
error: response.ok ? undefined : typeof bodyObject.error === 'string' ? bodyObject.error : 'Report failed'
|
|
91
|
+
};
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
endpoint,
|
|
96
|
+
report,
|
|
97
|
+
error: error instanceof Error ? error.message : String(error)
|
|
98
|
+
};
|
|
99
|
+
} finally {
|
|
100
|
+
if (timeout) {
|
|
101
|
+
clearTimeout(timeout);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=reportToDaemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Platform","_addDaemonEndpointToNetworkBlacklist","createDebugSessionReport","DEFAULT_TIMEOUT_MS","getGlobalFetch","globalThis","fetch","createAbortController","AbortControllerCtor","AbortController","undefined","getDefaultDaemonEndpoint","OS","buildDaemonUrl","endpoint","path","trimmed","replace","endsWith","readResponseBody","response","json","text","JSON","parse","readLogCount","value","Array","isArray","Object","entries","reduce","acc","key","count","reportDebugSessionToDaemon","options","reportUrl","report","fetchImpl","ok","error","timeoutMs","Math","max","controller","timeout","setTimeout","abort","headers","token","Authorization","method","body","stringify","signal","responseBody","bodyObject","status","sessionId","receivedAt","logCount","Error","message","String","clearTimeout"],"sourceRoot":"../../../src","sources":["utils/reportToDaemon.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import { DebugToolkit } from '../core/DebugToolkit';
|
|
5
|
+
import { safeStringify } from './safeStringify';
|
|
6
|
+
const DEFAULT_MAX_PER_TYPE = 50;
|
|
7
|
+
const DEFAULT_MAX_BODY_BYTES = 16 * 1024;
|
|
8
|
+
const MAX_DEPTH = 8;
|
|
9
|
+
function utf8ByteLength(value) {
|
|
10
|
+
let bytes = 0;
|
|
11
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
12
|
+
const code = value.charCodeAt(index);
|
|
13
|
+
if (code <= 0x7f) {
|
|
14
|
+
bytes += 1;
|
|
15
|
+
} else if (code <= 0x7ff) {
|
|
16
|
+
bytes += 2;
|
|
17
|
+
} else if (code >= 0xd800 && code <= 0xdbff) {
|
|
18
|
+
bytes += 4;
|
|
19
|
+
index += 1;
|
|
20
|
+
} else {
|
|
21
|
+
bytes += 3;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return bytes;
|
|
25
|
+
}
|
|
26
|
+
function truncateUtf8(value, maxBytes) {
|
|
27
|
+
if (utf8ByteLength(value) <= maxBytes) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
let bytes = 0;
|
|
31
|
+
let result = '';
|
|
32
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
33
|
+
const code = value.charCodeAt(index);
|
|
34
|
+
const char = value[index];
|
|
35
|
+
const charBytes = code <= 0x7f ? 1 : code <= 0x7ff ? 2 : code >= 0xd800 && code <= 0xdbff ? 4 : 3;
|
|
36
|
+
if (bytes + charBytes > maxBytes) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
result += char;
|
|
40
|
+
bytes += charBytes;
|
|
41
|
+
if (charBytes === 4) {
|
|
42
|
+
index += 1;
|
|
43
|
+
result += value[index] ?? '';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return `${result}...[truncated]`;
|
|
47
|
+
}
|
|
48
|
+
function truncateLargeValue(value, maxBytes) {
|
|
49
|
+
const serialized = safeStringify(value);
|
|
50
|
+
const originalBytes = utf8ByteLength(serialized);
|
|
51
|
+
if (originalBytes <= maxBytes) {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
__debugToolkitTruncated: true,
|
|
56
|
+
originalBytes,
|
|
57
|
+
preview: truncateUtf8(serialized, maxBytes)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function sanitizeValue(value, maxBodyBytes, depth = 0, seen = new WeakSet(), key = '') {
|
|
61
|
+
if (typeof value === 'string') {
|
|
62
|
+
return truncateUtf8(value, maxBodyBytes);
|
|
63
|
+
}
|
|
64
|
+
if (value === null || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'undefined') {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
if (typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
|
|
68
|
+
return String(value);
|
|
69
|
+
}
|
|
70
|
+
if (value instanceof Date) {
|
|
71
|
+
return value.toISOString();
|
|
72
|
+
}
|
|
73
|
+
if (typeof value !== 'object') {
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
const normalizedKey = key.toLowerCase();
|
|
77
|
+
if (normalizedKey === 'body' || normalizedKey === 'data') {
|
|
78
|
+
const normalized = sanitizeValue(value, maxBodyBytes, depth + 1, seen);
|
|
79
|
+
return truncateLargeValue(normalized, maxBodyBytes);
|
|
80
|
+
}
|
|
81
|
+
if (seen.has(value)) {
|
|
82
|
+
return '[Circular]';
|
|
83
|
+
}
|
|
84
|
+
if (depth >= MAX_DEPTH) {
|
|
85
|
+
return '[MaxDepth]';
|
|
86
|
+
}
|
|
87
|
+
seen.add(value);
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
return value.map(item => sanitizeValue(item, maxBodyBytes, depth + 1, seen));
|
|
90
|
+
}
|
|
91
|
+
return Object.entries(value).reduce((acc, [entryKey, entryValue]) => {
|
|
92
|
+
acc[entryKey] = sanitizeValue(entryValue, maxBodyBytes, depth + 1, seen, entryKey);
|
|
93
|
+
return acc;
|
|
94
|
+
}, {});
|
|
95
|
+
}
|
|
96
|
+
export function createDebugSessionReport(options = {}) {
|
|
97
|
+
const maxPerType = Math.max(1, Math.floor(options.maxPerType ?? DEFAULT_MAX_PER_TYPE));
|
|
98
|
+
const maxBodyBytes = Math.max(256, Math.floor(options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES));
|
|
99
|
+
const includeTypes = options.includeTypes?.length ? new Set(options.includeTypes) : null;
|
|
100
|
+
const logs = {};
|
|
101
|
+
DebugToolkit.features.forEach(feature => {
|
|
102
|
+
if (includeTypes && !includeTypes.has(feature.name)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let snapshot;
|
|
106
|
+
try {
|
|
107
|
+
snapshot = feature.getSnapshot();
|
|
108
|
+
} catch {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!Array.isArray(snapshot)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
logs[feature.name] = snapshot.slice(-maxPerType).map(entry => sanitizeValue(entry, maxBodyBytes));
|
|
115
|
+
});
|
|
116
|
+
const constants = Platform.constants;
|
|
117
|
+
return {
|
|
118
|
+
version: 2,
|
|
119
|
+
device: {
|
|
120
|
+
platform: Platform.OS,
|
|
121
|
+
model: constants?.model || 'unknown',
|
|
122
|
+
osVersion: Platform.Version == null ? 'unknown' : String(Platform.Version),
|
|
123
|
+
appVersion: constants?.appVersion || 'unknown'
|
|
124
|
+
},
|
|
125
|
+
logs
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=sessionReport.js.map
|