react-native-debug-toolkit 2.0.0 → 2.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.
- package/README.md +72 -72
- package/README.zh-CN.md +209 -0
- package/lib/commonjs/components/ClipboardTab.js +15 -16
- package/lib/commonjs/components/ClipboardTab.js.map +1 -1
- package/lib/commonjs/components/ConsoleLogTab.js +69 -202
- package/lib/commonjs/components/ConsoleLogTab.js.map +1 -1
- package/lib/commonjs/components/DebugPanel.js +230 -0
- package/lib/commonjs/components/DebugPanel.js.map +1 -0
- package/lib/commonjs/components/DebugView.js +66 -0
- package/lib/commonjs/components/DebugView.js.map +1 -0
- package/lib/commonjs/components/EnvironmentTab.js +22 -23
- package/lib/commonjs/components/EnvironmentTab.js.map +1 -1
- package/lib/commonjs/components/FeatureTabBar.js +182 -0
- package/lib/commonjs/components/FeatureTabBar.js.map +1 -0
- package/lib/commonjs/components/FloatIcon.js +187 -0
- package/lib/commonjs/components/FloatIcon.js.map +1 -0
- package/lib/commonjs/components/FloatPanelView.js +140 -723
- package/lib/commonjs/components/FloatPanelView.js.map +1 -1
- package/lib/commonjs/components/NavigationLogTab.js +8 -8
- package/lib/commonjs/components/NavigationLogTab.js.map +1 -1
- package/lib/commonjs/components/NetworkLogTab.js +179 -350
- package/lib/commonjs/components/NetworkLogTab.js.map +1 -1
- package/lib/commonjs/components/ThirdPartyLibsTab.js +8 -8
- package/lib/commonjs/components/ThirdPartyLibsTab.js.map +1 -1
- package/lib/commonjs/components/TrackLogTab.js +106 -248
- package/lib/commonjs/components/TrackLogTab.js.map +1 -1
- package/lib/commonjs/components/ZustandLogTab.js +148 -288
- package/lib/commonjs/components/ZustandLogTab.js.map +1 -1
- package/lib/commonjs/components/shared/CollapsibleSection.js +4 -4
- package/lib/commonjs/components/shared/CollapsibleSection.js.map +1 -1
- package/lib/commonjs/components/shared/CopyButton.js +3 -3
- package/lib/commonjs/components/shared/CopyButton.js.map +1 -1
- package/lib/commonjs/components/shared/LogListScreen.js +174 -0
- package/lib/commonjs/components/shared/LogListScreen.js.map +1 -0
- package/lib/commonjs/core/DebugToolkit.js +92 -112
- package/lib/commonjs/core/DebugToolkit.js.map +1 -1
- package/lib/commonjs/core/DebugToolkitProvider.js +30 -28
- package/lib/commonjs/core/DebugToolkitProvider.js.map +1 -1
- package/lib/commonjs/features/ClipboardFeature.js +6 -2
- package/lib/commonjs/features/ClipboardFeature.js.map +1 -1
- package/lib/commonjs/features/ConsoleLogFeature.js +66 -49
- package/lib/commonjs/features/ConsoleLogFeature.js.map +1 -1
- package/lib/commonjs/features/EnvironmentFeature.js +5 -13
- package/lib/commonjs/features/EnvironmentFeature.js.map +1 -1
- package/lib/commonjs/features/NavigationLogFeature.js +17 -38
- package/lib/commonjs/features/NavigationLogFeature.js.map +1 -1
- package/lib/commonjs/features/NetworkFeature.js +35 -256
- package/lib/commonjs/features/NetworkFeature.js.map +1 -1
- package/lib/commonjs/features/TrackFeature.js +17 -38
- package/lib/commonjs/features/TrackFeature.js.map +1 -1
- package/lib/commonjs/features/ZustandLogFeature.js +21 -38
- package/lib/commonjs/features/ZustandLogFeature.js.map +1 -1
- package/lib/commonjs/hooks/useNavigationLogger.js.map +1 -1
- package/lib/commonjs/index.js +7 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/initialize.js +19 -96
- package/lib/commonjs/initialize.js.map +1 -1
- package/lib/commonjs/interceptors/networkInterceptor.js +466 -0
- package/lib/commonjs/interceptors/networkInterceptor.js.map +1 -0
- package/lib/commonjs/utils/colors.js +48 -0
- package/lib/commonjs/utils/colors.js.map +1 -0
- package/lib/commonjs/utils/createChannelFeature.js +48 -0
- package/lib/commonjs/utils/createChannelFeature.js.map +1 -0
- package/lib/commonjs/utils/layout.js +8 -0
- package/lib/commonjs/utils/layout.js.map +1 -0
- package/lib/commonjs/utils/urlRewriterRegistry.js +14 -0
- package/lib/commonjs/utils/urlRewriterRegistry.js.map +1 -0
- package/lib/module/components/ClipboardTab.js +8 -8
- package/lib/module/components/ClipboardTab.js.map +1 -1
- package/lib/module/components/ConsoleLogTab.js +66 -199
- package/lib/module/components/ConsoleLogTab.js.map +1 -1
- package/lib/module/components/DebugPanel.js +225 -0
- package/lib/module/components/DebugPanel.js.map +1 -0
- package/lib/module/components/DebugView.js +61 -0
- package/lib/module/components/DebugView.js.map +1 -0
- package/lib/module/components/EnvironmentTab.js +3 -3
- package/lib/module/components/EnvironmentTab.js.map +1 -1
- package/lib/module/components/FeatureTabBar.js +177 -0
- package/lib/module/components/FeatureTabBar.js.map +1 -0
- package/lib/module/components/FloatIcon.js +182 -0
- package/lib/module/components/FloatIcon.js.map +1 -0
- package/lib/module/components/FloatPanelView.js +141 -723
- package/lib/module/components/FloatPanelView.js.map +1 -1
- package/lib/module/components/NavigationLogTab.js +1 -1
- package/lib/module/components/NavigationLogTab.js.map +1 -1
- package/lib/module/components/NetworkLogTab.js +167 -338
- package/lib/module/components/NetworkLogTab.js.map +1 -1
- package/lib/module/components/ThirdPartyLibsTab.js +1 -1
- package/lib/module/components/ThirdPartyLibsTab.js.map +1 -1
- package/lib/module/components/TrackLogTab.js +94 -236
- package/lib/module/components/TrackLogTab.js.map +1 -1
- package/lib/module/components/ZustandLogTab.js +136 -276
- package/lib/module/components/ZustandLogTab.js.map +1 -1
- package/lib/module/components/shared/CollapsibleSection.js +1 -1
- package/lib/module/components/shared/CollapsibleSection.js.map +1 -1
- package/lib/module/components/shared/CopyButton.js +1 -1
- package/lib/module/components/shared/CopyButton.js.map +1 -1
- package/lib/module/components/shared/LogListScreen.js +169 -0
- package/lib/module/components/shared/LogListScreen.js.map +1 -0
- package/lib/module/core/DebugToolkit.js +92 -111
- package/lib/module/core/DebugToolkit.js.map +1 -1
- package/lib/module/core/DebugToolkitProvider.js +31 -29
- package/lib/module/core/DebugToolkitProvider.js.map +1 -1
- package/lib/module/features/ClipboardFeature.js +6 -2
- package/lib/module/features/ClipboardFeature.js.map +1 -1
- package/lib/module/features/ConsoleLogFeature.js +65 -49
- package/lib/module/features/ConsoleLogFeature.js.map +1 -1
- package/lib/module/features/EnvironmentFeature.js +5 -13
- package/lib/module/features/EnvironmentFeature.js.map +1 -1
- package/lib/module/features/NavigationLogFeature.js +16 -38
- package/lib/module/features/NavigationLogFeature.js.map +1 -1
- package/lib/module/features/NetworkFeature.js +34 -255
- package/lib/module/features/NetworkFeature.js.map +1 -1
- package/lib/module/features/TrackFeature.js +16 -38
- package/lib/module/features/TrackFeature.js.map +1 -1
- package/lib/module/features/ZustandLogFeature.js +22 -38
- package/lib/module/features/ZustandLogFeature.js.map +1 -1
- package/lib/module/hooks/useNavigationLogger.js.map +1 -1
- package/lib/module/index.js +2 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/initialize.js +19 -95
- package/lib/module/initialize.js.map +1 -1
- package/lib/module/interceptors/networkInterceptor.js +460 -0
- package/lib/module/interceptors/networkInterceptor.js.map +1 -0
- package/lib/module/utils/colors.js +43 -0
- package/lib/module/utils/colors.js.map +1 -0
- package/lib/module/utils/createChannelFeature.js +44 -0
- package/lib/module/utils/createChannelFeature.js.map +1 -0
- package/lib/module/utils/layout.js +4 -0
- package/lib/module/utils/layout.js.map +1 -0
- package/lib/module/utils/urlRewriterRegistry.js +10 -0
- package/lib/module/utils/urlRewriterRegistry.js.map +1 -0
- package/lib/typescript/src/components/ClipboardTab.d.ts.map +1 -1
- package/lib/typescript/src/components/ConsoleLogTab.d.ts.map +1 -1
- package/lib/typescript/src/components/DebugPanel.d.ts +9 -0
- package/lib/typescript/src/components/DebugPanel.d.ts.map +1 -0
- package/lib/typescript/src/components/DebugView.d.ts +19 -0
- package/lib/typescript/src/components/DebugView.d.ts.map +1 -0
- package/lib/typescript/src/components/EnvironmentTab.d.ts.map +1 -1
- package/lib/typescript/src/components/FeatureTabBar.d.ts +13 -0
- package/lib/typescript/src/components/FeatureTabBar.d.ts.map +1 -0
- package/lib/typescript/src/components/FloatIcon.d.ts +12 -0
- package/lib/typescript/src/components/FloatIcon.d.ts.map +1 -0
- package/lib/typescript/src/components/FloatPanelView.d.ts +4 -59
- package/lib/typescript/src/components/FloatPanelView.d.ts.map +1 -1
- package/lib/typescript/src/components/NetworkLogTab.d.ts.map +1 -1
- package/lib/typescript/src/components/ThirdPartyLibsTab.d.ts.map +1 -1
- package/lib/typescript/src/components/TrackLogTab.d.ts.map +1 -1
- package/lib/typescript/src/components/ZustandLogTab.d.ts.map +1 -1
- package/lib/typescript/src/components/shared/LogListScreen.d.ts +21 -0
- package/lib/typescript/src/components/shared/LogListScreen.d.ts.map +1 -0
- package/lib/typescript/src/core/DebugToolkit.d.ts +11 -18
- package/lib/typescript/src/core/DebugToolkit.d.ts.map +1 -1
- package/lib/typescript/src/core/DebugToolkitProvider.d.ts +2 -5
- package/lib/typescript/src/core/DebugToolkitProvider.d.ts.map +1 -1
- package/lib/typescript/src/features/ClipboardFeature.d.ts +4 -0
- package/lib/typescript/src/features/ClipboardFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/ConsoleLogFeature.d.ts +2 -0
- package/lib/typescript/src/features/ConsoleLogFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/EnvironmentFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/NavigationLogFeature.d.ts +2 -0
- package/lib/typescript/src/features/NavigationLogFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/NetworkFeature.d.ts +7 -20
- package/lib/typescript/src/features/NetworkFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/TrackFeature.d.ts +2 -0
- package/lib/typescript/src/features/TrackFeature.d.ts.map +1 -1
- package/lib/typescript/src/features/ZustandLogFeature.d.ts +2 -0
- package/lib/typescript/src/features/ZustandLogFeature.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNavigationLogger.d.ts +1 -8
- package/lib/typescript/src/hooks/useNavigationLogger.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -5
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/initialize.d.ts +3 -22
- package/lib/typescript/src/initialize.d.ts.map +1 -1
- package/lib/typescript/src/interceptors/networkInterceptor.d.ts +18 -0
- package/lib/typescript/src/interceptors/networkInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +26 -29
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/colors.d.ts +21 -0
- package/lib/typescript/src/utils/colors.d.ts.map +1 -0
- package/lib/typescript/src/utils/createChannelFeature.d.ts +18 -0
- package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -0
- package/lib/typescript/src/utils/layout.d.ts +2 -0
- package/lib/typescript/src/utils/layout.d.ts.map +1 -0
- package/lib/typescript/src/utils/urlRewriterRegistry.d.ts +7 -0
- package/lib/typescript/src/utils/urlRewriterRegistry.d.ts.map +1 -0
- package/package.json +5 -1
- package/src/components/ClipboardTab.tsx +8 -8
- package/src/components/ConsoleLogTab.tsx +49 -163
- package/src/components/DebugPanel.tsx +215 -0
- package/src/components/DebugView.tsx +80 -0
- package/src/components/EnvironmentTab.tsx +3 -3
- package/src/components/FeatureTabBar.tsx +204 -0
- package/src/components/FloatIcon.tsx +171 -0
- package/src/components/FloatPanelView.tsx +135 -647
- package/src/components/NavigationLogTab.tsx +1 -1
- package/src/components/NetworkLogTab.tsx +128 -269
- package/src/components/ThirdPartyLibsTab.tsx +3 -3
- package/src/components/TrackLogTab.tsx +53 -188
- package/src/components/ZustandLogTab.tsx +79 -181
- package/src/components/shared/CollapsibleSection.tsx +1 -1
- package/src/components/shared/CopyButton.tsx +1 -1
- package/src/components/shared/LogListScreen.tsx +164 -0
- package/src/core/DebugToolkit.tsx +114 -138
- package/src/core/DebugToolkitProvider.tsx +32 -38
- package/src/features/ClipboardFeature.ts +6 -2
- package/src/features/ConsoleLogFeature.ts +66 -68
- package/src/features/EnvironmentFeature.ts +5 -13
- package/src/features/NavigationLogFeature.ts +12 -42
- package/src/features/NetworkFeature.ts +43 -405
- package/src/features/TrackFeature.ts +14 -49
- package/src/features/ZustandLogFeature.ts +16 -42
- package/src/hooks/useNavigationLogger.ts +1 -6
- package/src/index.ts +5 -9
- package/src/initialize.ts +28 -120
- package/src/interceptors/networkInterceptor.ts +646 -0
- package/src/types/index.ts +25 -36
- package/src/utils/colors.ts +38 -0
- package/src/utils/createChannelFeature.ts +55 -0
- package/src/utils/layout.ts +1 -0
- package/src/utils/urlRewriterRegistry.ts +10 -0
- package/lib/commonjs/utils/constants.js +0 -135
- package/lib/commonjs/utils/constants.js.map +0 -1
- package/lib/module/utils/constants.js +0 -130
- package/lib/module/utils/constants.js.map +0 -1
- package/lib/typescript/src/utils/constants.d.ts +0 -96
- package/lib/typescript/src/utils/constants.d.ts.map +0 -1
- package/src/utils/constants.ts +0 -91
|
@@ -2,356 +2,18 @@ import { NetworkLogTab } from '../components/NetworkLogTab';
|
|
|
2
2
|
import type { DebugFeature, NetworkLogEntry } from '../types';
|
|
3
3
|
import { createEventChannel } from '../utils/createEventChannel';
|
|
4
4
|
import { createObservableStore } from '../utils/createObservableStore';
|
|
5
|
+
import { urlRewriter } from '../utils/urlRewriterRegistry';
|
|
6
|
+
import {
|
|
7
|
+
startFetch,
|
|
8
|
+
startXMLHttpRequest,
|
|
9
|
+
setupAxios,
|
|
10
|
+
resetInterceptors,
|
|
11
|
+
} from '../interceptors/networkInterceptor';
|
|
12
|
+
import type { AxiosInstanceLike } from '../interceptors/networkInterceptor';
|
|
5
13
|
|
|
6
14
|
type NetworkLogPayload = Omit<NetworkLogEntry, 'id'>;
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
use: (onFulfilled: unknown, onRejected?: unknown) => number | void;
|
|
10
|
-
eject?: (id: number) => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface AxiosRequestConfigLike {
|
|
14
|
-
baseURL?: string;
|
|
15
|
-
url?: string;
|
|
16
|
-
method?: string;
|
|
17
|
-
headers?: Record<string, string>;
|
|
18
|
-
data?: unknown;
|
|
19
|
-
params?: unknown;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface AxiosResponseLike {
|
|
23
|
-
status: number;
|
|
24
|
-
statusText: string;
|
|
25
|
-
headers?: Record<string, string>;
|
|
26
|
-
data?: unknown;
|
|
27
|
-
config: AxiosRequestConfigLike;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface AxiosErrorLike {
|
|
31
|
-
message: string;
|
|
32
|
-
config?: AxiosRequestConfigLike;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface AxiosInstanceLike {
|
|
36
|
-
interceptors: {
|
|
37
|
-
request: AxiosInterceptorManager;
|
|
38
|
-
response: AxiosInterceptorManager;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface AxiosRegistration {
|
|
43
|
-
refCount: number;
|
|
44
|
-
requestId?: number;
|
|
45
|
-
responseId?: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const DEFAULT_MAX_LOGS = 200;
|
|
49
|
-
const networkChannel = createEventChannel<NetworkLogPayload>();
|
|
50
|
-
const pendingAxiosRequests = new Map<string, { startTime: number; timestamp: number }>();
|
|
51
|
-
const axiosRegistrations = new WeakMap<AxiosInstanceLike, AxiosRegistration>();
|
|
52
|
-
|
|
53
|
-
let originalFetch: typeof globalThis.fetch | null = null;
|
|
54
|
-
let fetchInterceptorRefCount = 0;
|
|
55
|
-
let urlRewriter: ((url: string) => string) | null = null;
|
|
56
|
-
|
|
57
|
-
export function setUrlRewriter(rewriter: ((url: string) => string) | null): void {
|
|
58
|
-
urlRewriter = rewriter;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function rewriteUrl(url: string): string {
|
|
62
|
-
if (!urlRewriter) return url;
|
|
63
|
-
try {
|
|
64
|
-
return urlRewriter(url);
|
|
65
|
-
} catch {
|
|
66
|
-
return url;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function emitNetworkLog(entry: NetworkLogPayload): void {
|
|
71
|
-
networkChannel.emit(entry);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function headersToObject(
|
|
75
|
-
headers: Record<string, string> | Headers | undefined,
|
|
76
|
-
): Record<string, string> {
|
|
77
|
-
const result: Record<string, string> = {};
|
|
78
|
-
|
|
79
|
-
if (!headers) {
|
|
80
|
-
return result;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (typeof (headers as Headers).forEach === 'function') {
|
|
84
|
-
(headers as Headers).forEach((value: string, key: string) => {
|
|
85
|
-
result[key] = value;
|
|
86
|
-
});
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Object.keys(headers).forEach((key) => {
|
|
91
|
-
result[key] = (headers as Record<string, string>)[key]!;
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
return result;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function getRequestSnapshot(
|
|
98
|
-
input: unknown,
|
|
99
|
-
init?: RequestInit,
|
|
100
|
-
): NetworkLogEntry['request'] {
|
|
101
|
-
const request = input instanceof Request ? input : null;
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
url:
|
|
105
|
-
typeof input === 'string'
|
|
106
|
-
? input
|
|
107
|
-
: request?.url ?? String(input),
|
|
108
|
-
method: (init?.method || request?.method || 'GET').toUpperCase(),
|
|
109
|
-
headers: init?.headers
|
|
110
|
-
? headersToObject(init.headers as Record<string, string> | Headers)
|
|
111
|
-
: request?.headers
|
|
112
|
-
? headersToObject(request.headers)
|
|
113
|
-
: undefined,
|
|
114
|
-
body: init?.body,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async function parseResponseBody(response: Response): Promise<unknown> {
|
|
119
|
-
const raw = await response.clone().text();
|
|
120
|
-
|
|
121
|
-
if (!raw) {
|
|
122
|
-
return undefined;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
return JSON.parse(raw);
|
|
127
|
-
} catch {
|
|
128
|
-
return raw;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function stopFetchInterceptor(): void {
|
|
133
|
-
fetchInterceptorRefCount = Math.max(0, fetchInterceptorRefCount - 1);
|
|
134
|
-
|
|
135
|
-
if (fetchInterceptorRefCount === 0 && originalFetch) {
|
|
136
|
-
globalThis.fetch = originalFetch;
|
|
137
|
-
originalFetch = null;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function startFetchInterceptor(): () => void {
|
|
142
|
-
fetchInterceptorRefCount += 1;
|
|
143
|
-
|
|
144
|
-
if (originalFetch) {
|
|
145
|
-
return () => {
|
|
146
|
-
stopFetchInterceptor();
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
originalFetch = globalThis.fetch;
|
|
151
|
-
|
|
152
|
-
globalThis.fetch = async function interceptedFetch(
|
|
153
|
-
input: Parameters<typeof fetch>[0],
|
|
154
|
-
init?: Parameters<typeof fetch>[1],
|
|
155
|
-
) {
|
|
156
|
-
const startTime = Date.now();
|
|
157
|
-
|
|
158
|
-
let rewrittenInput: typeof input = input;
|
|
159
|
-
if (urlRewriter) {
|
|
160
|
-
if (typeof input === 'string') {
|
|
161
|
-
rewrittenInput = rewriteUrl(input);
|
|
162
|
-
} else if (input instanceof Request) {
|
|
163
|
-
rewrittenInput = new Request(rewriteUrl(input.url), input as RequestInit);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const request = getRequestSnapshot(rewrittenInput, init);
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
const response = await originalFetch!.call(globalThis, rewrittenInput, init);
|
|
171
|
-
const duration = Date.now() - startTime;
|
|
172
|
-
|
|
173
|
-
try {
|
|
174
|
-
const data = await parseResponseBody(response);
|
|
175
|
-
emitNetworkLog({
|
|
176
|
-
timestamp: startTime,
|
|
177
|
-
duration,
|
|
178
|
-
request,
|
|
179
|
-
response: {
|
|
180
|
-
status: response.status,
|
|
181
|
-
statusText: response.statusText,
|
|
182
|
-
data,
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
} catch {
|
|
186
|
-
emitNetworkLog({
|
|
187
|
-
timestamp: startTime,
|
|
188
|
-
duration,
|
|
189
|
-
request,
|
|
190
|
-
response: {
|
|
191
|
-
status: response.status,
|
|
192
|
-
statusText: response.statusText,
|
|
193
|
-
},
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return response;
|
|
198
|
-
} catch (error) {
|
|
199
|
-
emitNetworkLog({
|
|
200
|
-
timestamp: startTime,
|
|
201
|
-
duration: Date.now() - startTime,
|
|
202
|
-
request,
|
|
203
|
-
error: error instanceof Error ? error.message : String(error),
|
|
204
|
-
});
|
|
205
|
-
throw error;
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
return () => {
|
|
210
|
-
stopFetchInterceptor();
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function teardownAxiosInterceptors(axiosInstance: AxiosInstanceLike): void {
|
|
215
|
-
const registration = axiosRegistrations.get(axiosInstance);
|
|
216
|
-
|
|
217
|
-
if (!registration) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
registration.refCount -= 1;
|
|
222
|
-
|
|
223
|
-
if (registration.refCount > 0) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (typeof registration.requestId === 'number') {
|
|
228
|
-
axiosInstance.interceptors.request.eject?.(registration.requestId);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (typeof registration.responseId === 'number') {
|
|
232
|
-
axiosInstance.interceptors.response.eject?.(registration.responseId);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
axiosRegistrations.delete(axiosInstance);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function setupAxiosInterceptorsInternal(
|
|
239
|
-
axiosInstance: AxiosInstanceLike,
|
|
240
|
-
): () => void {
|
|
241
|
-
const existingRegistration = axiosRegistrations.get(axiosInstance);
|
|
242
|
-
|
|
243
|
-
if (existingRegistration) {
|
|
244
|
-
existingRegistration.refCount += 1;
|
|
245
|
-
return () => {
|
|
246
|
-
teardownAxiosInterceptors(axiosInstance);
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const requestId = axiosInstance.interceptors.request.use(
|
|
251
|
-
(config: AxiosRequestConfigLike) => {
|
|
252
|
-
// Rewrite URL if rewriter is set
|
|
253
|
-
if (urlRewriter && config.url) {
|
|
254
|
-
const fullUrl = config.baseURL
|
|
255
|
-
? `${config.baseURL}${config.url}`
|
|
256
|
-
: config.url;
|
|
257
|
-
const rewritten = rewriteUrl(fullUrl);
|
|
258
|
-
if (rewritten !== fullUrl) {
|
|
259
|
-
if (config.baseURL && rewritten.startsWith(config.baseURL)) {
|
|
260
|
-
config.url = rewritten.slice(config.baseURL.length);
|
|
261
|
-
} else {
|
|
262
|
-
config.baseURL = '';
|
|
263
|
-
config.url = rewritten;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (!config.headers) {
|
|
269
|
-
config.headers = {};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (!config.headers['X-Request-Id']) {
|
|
273
|
-
config.headers['X-Request-Id'] =
|
|
274
|
-
Date.now().toString() + Math.random().toString(36).substring(2, 10);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const trackId = config.headers['X-Request-Id'] as string;
|
|
278
|
-
|
|
279
|
-
pendingAxiosRequests.set(trackId, {
|
|
280
|
-
startTime: Date.now(),
|
|
281
|
-
timestamp: Date.now(),
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
return config;
|
|
285
|
-
},
|
|
286
|
-
(error: unknown) => Promise.reject(error),
|
|
287
|
-
);
|
|
288
|
-
|
|
289
|
-
const responseId = axiosInstance.interceptors.response.use(
|
|
290
|
-
(response: AxiosResponseLike) => {
|
|
291
|
-
const trackId = response.config?.headers?.['X-Request-Id'] as string;
|
|
292
|
-
const pending = pendingAxiosRequests.get(trackId);
|
|
293
|
-
|
|
294
|
-
if (pending) {
|
|
295
|
-
emitNetworkLog({
|
|
296
|
-
timestamp: pending.timestamp,
|
|
297
|
-
duration: Date.now() - pending.startTime,
|
|
298
|
-
request: {
|
|
299
|
-
url: `${response.config.baseURL || ''}${response.config.url}`,
|
|
300
|
-
method: (response.config.method || 'GET').toUpperCase(),
|
|
301
|
-
headers: response.config.headers,
|
|
302
|
-
body: response.config.data || response.config.params,
|
|
303
|
-
},
|
|
304
|
-
response: {
|
|
305
|
-
status: response.status,
|
|
306
|
-
statusText: response.statusText,
|
|
307
|
-
headers: response.headers,
|
|
308
|
-
data: response.data,
|
|
309
|
-
success:
|
|
310
|
-
response.data && typeof response.data === 'object'
|
|
311
|
-
? (response.data as Record<string, unknown>).success !== false
|
|
312
|
-
: response.status >= 200 && response.status < 300,
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
pendingAxiosRequests.delete(trackId);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return response;
|
|
320
|
-
},
|
|
321
|
-
(error: AxiosErrorLike) => {
|
|
322
|
-
if (error.config) {
|
|
323
|
-
const trackId = error.config.headers?.['X-Request-Id'] as string;
|
|
324
|
-
const pending = pendingAxiosRequests.get(trackId);
|
|
325
|
-
|
|
326
|
-
emitNetworkLog({
|
|
327
|
-
timestamp: pending ? pending.timestamp : Date.now(),
|
|
328
|
-
duration: pending ? Date.now() - pending.startTime : undefined,
|
|
329
|
-
request: {
|
|
330
|
-
url: `${error.config.baseURL || ''}${error.config.url}`,
|
|
331
|
-
method: (error.config.method || 'GET').toUpperCase(),
|
|
332
|
-
headers: error.config.headers,
|
|
333
|
-
body: error.config.data || error.config.params,
|
|
334
|
-
},
|
|
335
|
-
error: error.message,
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
pendingAxiosRequests.delete(trackId);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
return Promise.reject(error);
|
|
342
|
-
},
|
|
343
|
-
);
|
|
344
|
-
|
|
345
|
-
axiosRegistrations.set(axiosInstance, {
|
|
346
|
-
refCount: 1,
|
|
347
|
-
requestId: typeof requestId === 'number' ? requestId : undefined,
|
|
348
|
-
responseId: typeof responseId === 'number' ? responseId : undefined,
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
return () => {
|
|
352
|
-
teardownAxiosInterceptors(axiosInstance);
|
|
353
|
-
};
|
|
354
|
-
}
|
|
16
|
+
// ─── Utilities ────────────────────────────────────────
|
|
355
17
|
|
|
356
18
|
function isUrlBlacklisted(
|
|
357
19
|
url: string,
|
|
@@ -360,20 +22,25 @@ function isUrlBlacklisted(
|
|
|
360
22
|
if (!url) {
|
|
361
23
|
return false;
|
|
362
24
|
}
|
|
363
|
-
|
|
364
25
|
return blacklist.some((pattern) =>
|
|
365
26
|
pattern instanceof RegExp ? pattern.test(url) : url.includes(pattern),
|
|
366
27
|
);
|
|
367
28
|
}
|
|
368
29
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
30
|
+
// ─── Channel (shared pub-sub backbone) ─────────────────
|
|
31
|
+
|
|
32
|
+
let networkChannel = createEventChannel<NetworkLogPayload>();
|
|
33
|
+
|
|
34
|
+
function emitNetworkLog(entry: NetworkLogPayload): void {
|
|
35
|
+
networkChannel.emit(entry);
|
|
375
36
|
}
|
|
376
37
|
|
|
38
|
+
// ─── Feature factory ──────────────────────────────────
|
|
39
|
+
|
|
40
|
+
const DEFAULT_MAX_LOGS = 200;
|
|
41
|
+
|
|
42
|
+
export type { AxiosInstanceLike };
|
|
43
|
+
|
|
377
44
|
export interface NetworkFeatureConfig {
|
|
378
45
|
/** Maximum number of network logs to keep (default: 200) */
|
|
379
46
|
maxLogs?: number;
|
|
@@ -381,7 +48,9 @@ export interface NetworkFeatureConfig {
|
|
|
381
48
|
blacklist?: Array<string | RegExp>;
|
|
382
49
|
}
|
|
383
50
|
|
|
384
|
-
export const createNetworkFeature = (config?: NetworkFeatureConfig):
|
|
51
|
+
export const createNetworkFeature = (config?: NetworkFeatureConfig): DebugFeature<NetworkLogEntry> & {
|
|
52
|
+
setupAxiosInterceptors: (axiosInstance: AxiosInstanceLike) => () => void;
|
|
53
|
+
} => {
|
|
385
54
|
const maxLogs = config?.maxLogs ?? DEFAULT_MAX_LOGS;
|
|
386
55
|
const blacklist: Array<string | RegExp> = config?.blacklist ? [...config.blacklist] : [];
|
|
387
56
|
const logStore = createObservableStore<NetworkLogEntry>();
|
|
@@ -390,25 +59,14 @@ export const createNetworkFeature = (config?: NetworkFeatureConfig): NetworkFeat
|
|
|
390
59
|
let nextId = 0;
|
|
391
60
|
let initialized = false;
|
|
392
61
|
let unsubscribeLogs: (() => void) | null = null;
|
|
393
|
-
let
|
|
62
|
+
let stopFetchFn: (() => void) | null = null;
|
|
63
|
+
let stopXMLHttpRequestFn: (() => void) | null = null;
|
|
394
64
|
|
|
395
65
|
const handleLog = (entry: NetworkLogPayload) => {
|
|
396
66
|
if (isUrlBlacklisted(entry.request.url, blacklist)) {
|
|
397
67
|
return;
|
|
398
68
|
}
|
|
399
|
-
|
|
400
|
-
logStore.push(
|
|
401
|
-
{
|
|
402
|
-
...entry,
|
|
403
|
-
id: String(nextId++),
|
|
404
|
-
},
|
|
405
|
-
maxLogs,
|
|
406
|
-
);
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
const cleanupAxiosRegistrations = () => {
|
|
410
|
-
axiosCleanupMap.forEach((cleanup) => cleanup());
|
|
411
|
-
axiosCleanupMap.clear();
|
|
69
|
+
logStore.push({ ...entry, id: String(nextId++) }, maxLogs);
|
|
412
70
|
};
|
|
413
71
|
|
|
414
72
|
return {
|
|
@@ -419,9 +77,9 @@ export const createNetworkFeature = (config?: NetworkFeatureConfig): NetworkFeat
|
|
|
419
77
|
if (initialized) {
|
|
420
78
|
return;
|
|
421
79
|
}
|
|
422
|
-
|
|
423
80
|
unsubscribeLogs = networkChannel.subscribe(handleLog);
|
|
424
|
-
|
|
81
|
+
stopFetchFn = startFetch(emitNetworkLog);
|
|
82
|
+
stopXMLHttpRequestFn = startXMLHttpRequest(emitNetworkLog);
|
|
425
83
|
initialized = true;
|
|
426
84
|
},
|
|
427
85
|
getData: () => logStore.getData(),
|
|
@@ -432,57 +90,37 @@ export const createNetworkFeature = (config?: NetworkFeatureConfig): NetworkFeat
|
|
|
432
90
|
if (!initialized) {
|
|
433
91
|
return;
|
|
434
92
|
}
|
|
435
|
-
|
|
436
|
-
setUrlRewriter(null);
|
|
93
|
+
urlRewriter.set(null);
|
|
437
94
|
unsubscribeLogs?.();
|
|
438
95
|
unsubscribeLogs = null;
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
96
|
+
stopFetchFn?.();
|
|
97
|
+
stopFetchFn = null;
|
|
98
|
+
stopXMLHttpRequestFn?.();
|
|
99
|
+
stopXMLHttpRequestFn = null;
|
|
100
|
+
axiosCleanupMap.forEach((c) => c());
|
|
101
|
+
axiosCleanupMap.clear();
|
|
442
102
|
logStore.clear();
|
|
443
103
|
initialized = false;
|
|
444
104
|
},
|
|
445
105
|
subscribe: (listener) => logStore.subscribe(listener),
|
|
446
106
|
setupAxiosInterceptors: (axiosInstance) => {
|
|
447
107
|
const existingCleanup = axiosCleanupMap.get(axiosInstance);
|
|
448
|
-
|
|
449
108
|
if (existingCleanup) {
|
|
450
109
|
return existingCleanup;
|
|
451
110
|
}
|
|
452
|
-
|
|
453
|
-
const cleanup = setupAxiosInterceptorsInternal(axiosInstance);
|
|
111
|
+
const cleanup = setupAxios(axiosInstance, emitNetworkLog);
|
|
454
112
|
const trackedCleanup = () => {
|
|
455
113
|
cleanup();
|
|
456
114
|
axiosCleanupMap.delete(axiosInstance);
|
|
457
115
|
};
|
|
458
|
-
|
|
459
116
|
axiosCleanupMap.set(axiosInstance, trackedCleanup);
|
|
460
117
|
return trackedCleanup;
|
|
461
118
|
},
|
|
462
|
-
addUrlToBlacklist: (pattern) => {
|
|
463
|
-
const alreadyExists = blacklist.some((item) =>
|
|
464
|
-
item instanceof RegExp && pattern instanceof RegExp
|
|
465
|
-
? item.toString() === pattern.toString()
|
|
466
|
-
: item === pattern,
|
|
467
|
-
);
|
|
468
|
-
|
|
469
|
-
if (!alreadyExists) {
|
|
470
|
-
blacklist.push(pattern);
|
|
471
|
-
}
|
|
472
|
-
},
|
|
473
|
-
removeUrlFromBlacklist: (pattern) => {
|
|
474
|
-
const nextBlacklist = blacklist.filter((item) =>
|
|
475
|
-
item instanceof RegExp && pattern instanceof RegExp
|
|
476
|
-
? item.toString() !== pattern.toString()
|
|
477
|
-
: item !== pattern,
|
|
478
|
-
);
|
|
479
|
-
|
|
480
|
-
blacklist.length = 0;
|
|
481
|
-
blacklist.push(...nextBlacklist);
|
|
482
|
-
},
|
|
483
|
-
clearBlacklist: () => {
|
|
484
|
-
blacklist.length = 0;
|
|
485
|
-
},
|
|
486
|
-
getBlacklist: () => [...blacklist],
|
|
487
119
|
};
|
|
488
120
|
};
|
|
121
|
+
|
|
122
|
+
/** Reset module-level state for testing */
|
|
123
|
+
export function _resetNetworkForTesting(): void {
|
|
124
|
+
networkChannel = createEventChannel<NetworkLogPayload>();
|
|
125
|
+
resetInterceptors();
|
|
126
|
+
}
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import { TrackLogTab } from '../components/TrackLogTab';
|
|
2
2
|
import type { DebugFeature, TrackLogEntry } from '../types';
|
|
3
3
|
import { createEventChannel } from '../utils/createEventChannel';
|
|
4
|
-
import {
|
|
4
|
+
import { createChannelFeature } from '../utils/createChannelFeature';
|
|
5
5
|
|
|
6
6
|
export interface TrackEventData {
|
|
7
7
|
eventName: string;
|
|
8
8
|
[key: string]: unknown;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
type TrackLogPayload = TrackEventData & {
|
|
12
|
-
timestamp: number;
|
|
13
|
-
};
|
|
11
|
+
type TrackLogPayload = TrackEventData & { timestamp: number };
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
const trackChannel = createEventChannel<TrackLogPayload>();
|
|
13
|
+
let trackChannel = createEventChannel<TrackLogPayload>();
|
|
17
14
|
|
|
18
15
|
export const addTrackLog = (eventData: TrackEventData): void => {
|
|
19
|
-
trackChannel.emit({
|
|
20
|
-
timestamp: Date.now(),
|
|
21
|
-
...eventData,
|
|
22
|
-
});
|
|
16
|
+
trackChannel.emit({ timestamp: Date.now(), ...eventData });
|
|
23
17
|
};
|
|
24
18
|
|
|
25
19
|
export interface TrackFeatureConfig {
|
|
@@ -27,43 +21,14 @@ export interface TrackFeatureConfig {
|
|
|
27
21
|
maxLogs?: number;
|
|
28
22
|
}
|
|
29
23
|
|
|
30
|
-
export const createTrackFeature = (config?: TrackFeatureConfig): DebugFeature<TrackLogEntry> =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
name: 'track',
|
|
39
|
-
label: 'Track',
|
|
40
|
-
renderContent: TrackLogTab,
|
|
41
|
-
setup: () => {
|
|
42
|
-
if (initialized) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
24
|
+
export const createTrackFeature = (config?: TrackFeatureConfig): DebugFeature<TrackLogEntry> =>
|
|
25
|
+
createChannelFeature(
|
|
26
|
+
() => trackChannel,
|
|
27
|
+
(payload, id) => ({ ...payload, id }),
|
|
28
|
+
{ name: 'track', label: 'Track', renderContent: TrackLogTab, maxLogs: config?.maxLogs },
|
|
29
|
+
);
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
id: String(nextId++),
|
|
51
|
-
},
|
|
52
|
-
maxLogs,
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
initialized = true;
|
|
56
|
-
},
|
|
57
|
-
getData: () => logStore.getData(),
|
|
58
|
-
clear: () => {
|
|
59
|
-
logStore.clear();
|
|
60
|
-
},
|
|
61
|
-
cleanup: () => {
|
|
62
|
-
unsubscribeLogs?.();
|
|
63
|
-
unsubscribeLogs = null;
|
|
64
|
-
logStore.clear();
|
|
65
|
-
initialized = false;
|
|
66
|
-
},
|
|
67
|
-
subscribe: (listener) => logStore.subscribe(listener),
|
|
68
|
-
};
|
|
69
|
-
};
|
|
31
|
+
/** Reset module-level state for testing */
|
|
32
|
+
export function _resetTrackForTesting(): void {
|
|
33
|
+
trackChannel = createEventChannel<TrackLogPayload>();
|
|
34
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { ZustandLogTab } from '../components/ZustandLogTab';
|
|
2
2
|
import type { DebugFeature, ZustandLogEntry } from '../types';
|
|
3
3
|
import { createEventChannel } from '../utils/createEventChannel';
|
|
4
|
-
import {
|
|
4
|
+
import { createChannelFeature } from '../utils/createChannelFeature';
|
|
5
5
|
|
|
6
6
|
type ZustandLogPayload = Omit<ZustandLogEntry, 'id'>;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const zustandChannel = createEventChannel<ZustandLogPayload>();
|
|
8
|
+
let zustandChannel = createEventChannel<ZustandLogPayload>();
|
|
10
9
|
|
|
11
10
|
export const addZustandLog = (
|
|
12
11
|
action: string,
|
|
@@ -25,6 +24,8 @@ export const addZustandLog = (
|
|
|
25
24
|
});
|
|
26
25
|
};
|
|
27
26
|
|
|
27
|
+
// ─── Zustand middleware (remains here — it's user-facing API) ──────────
|
|
28
|
+
|
|
28
29
|
type ZustandSetState<T> = (
|
|
29
30
|
partial: T | Partial<T> | ((state: T) => Partial<T> | T),
|
|
30
31
|
replace?: boolean | undefined,
|
|
@@ -80,48 +81,21 @@ export const zustandLogMiddleware = <T>(config: ZustandConfig<T>) => (
|
|
|
80
81
|
api,
|
|
81
82
|
);
|
|
82
83
|
|
|
84
|
+
// ─── Feature factory ──────────────────────────────────────────────────
|
|
85
|
+
|
|
83
86
|
export interface ZustandFeatureConfig {
|
|
84
87
|
/** Maximum number of zustand state changes to keep (default: 200) */
|
|
85
88
|
maxLogs?: number;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
export const createZustandLogFeature = (config?: ZustandFeatureConfig): DebugFeature<ZustandLogEntry> =>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
name: 'zustand',
|
|
97
|
-
label: 'Zustand',
|
|
98
|
-
renderContent: ZustandLogTab,
|
|
99
|
-
setup: () => {
|
|
100
|
-
if (initialized) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
91
|
+
export const createZustandLogFeature = (config?: ZustandFeatureConfig): DebugFeature<ZustandLogEntry> =>
|
|
92
|
+
createChannelFeature(
|
|
93
|
+
() => zustandChannel,
|
|
94
|
+
(payload, id) => ({ ...payload, id }),
|
|
95
|
+
{ name: 'zustand', label: 'Zustand', renderContent: ZustandLogTab, maxLogs: config?.maxLogs },
|
|
96
|
+
);
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
id: String(nextId++),
|
|
109
|
-
},
|
|
110
|
-
maxLogs,
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
initialized = true;
|
|
114
|
-
},
|
|
115
|
-
getData: () => logStore.getData(),
|
|
116
|
-
clear: () => {
|
|
117
|
-
logStore.clear();
|
|
118
|
-
},
|
|
119
|
-
cleanup: () => {
|
|
120
|
-
unsubscribeLogs?.();
|
|
121
|
-
unsubscribeLogs = null;
|
|
122
|
-
logStore.clear();
|
|
123
|
-
initialized = false;
|
|
124
|
-
},
|
|
125
|
-
subscribe: (listener) => logStore.subscribe(listener),
|
|
126
|
-
};
|
|
127
|
-
};
|
|
98
|
+
/** Reset module-level state for testing */
|
|
99
|
+
export function _resetZustandForTesting(): void {
|
|
100
|
+
zustandChannel = createEventChannel<ZustandLogPayload>();
|
|
101
|
+
}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { addNavigationLog } from '../features/NavigationLogFeature';
|
|
3
3
|
import { safeStringify } from '../utils/safeStringify';
|
|
4
|
-
|
|
5
|
-
interface NavigationContainerRef {
|
|
6
|
-
getCurrentRoute?: () => { name?: string } | undefined;
|
|
7
|
-
getRootState?: () => unknown;
|
|
8
|
-
addListener: (event: string, callback: () => void) => () => void;
|
|
9
|
-
}
|
|
4
|
+
import type { NavigationContainerRef } from '../types';
|
|
10
5
|
|
|
11
6
|
function getActiveRouteName(state: unknown): string {
|
|
12
7
|
let currentState = state as
|