@rork-ai/toolkit-dev-sdk 0.2.6 → 0.2.8
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/lib/module/index.53.js +18 -0
- package/lib/module/index.53.js.map +1 -0
- package/lib/module/index.js +5 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/inspector.53.js +413 -0
- package/lib/module/inspector.53.js.map +1 -0
- package/lib/module/inspector.53.web.js +11 -0
- package/lib/module/inspector.53.web.js.map +1 -0
- package/lib/module/inspector.js +290 -0
- package/lib/module/inspector.js.map +1 -0
- package/lib/module/inspector.web.js +11 -0
- package/lib/module/inspector.web.js.map +1 -0
- package/lib/typescript/src/index.53.d.ts +4 -0
- package/lib/typescript/src/index.53.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/inspector.53.d.ts +23 -0
- package/lib/typescript/src/inspector.53.d.ts.map +1 -0
- package/lib/typescript/src/inspector.53.web.d.ts +4 -0
- package/lib/typescript/src/inspector.53.web.d.ts.map +1 -0
- package/lib/typescript/src/inspector.d.ts +23 -0
- package/lib/typescript/src/inspector.d.ts.map +1 -0
- package/lib/typescript/src/inspector.web.d.ts +4 -0
- package/lib/typescript/src/inspector.web.d.ts.map +1 -0
- package/package.json +10 -3
- package/src/index.53.tsx +13 -0
- package/src/index.tsx +4 -1
- package/src/inspector.53.tsx +467 -0
- package/src/inspector.53.web.tsx +3 -0
- package/src/inspector.tsx +345 -0
- package/src/inspector.web.tsx +3 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/*
|
|
2
|
+
The code here will is moved to our infrastructure (with ctrl+c ctrl+v)
|
|
3
|
+
where we add it in _layout.tsx as it is.
|
|
4
|
+
|
|
5
|
+
It will be added at .rork/BundleInspector.tsx (web vestoin too).
|
|
6
|
+
|
|
7
|
+
That is why:
|
|
8
|
+
1. This file should never import other files
|
|
9
|
+
2. This file should never import other modules that will not be on the device.
|
|
10
|
+
We import react-native-safe-area-context and lucide-react-native
|
|
11
|
+
but we are confident it will be there. Still not great.
|
|
12
|
+
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { BlurView } from "expo-blur";
|
|
16
|
+
import {
|
|
17
|
+
requireOptionalNativeModule,
|
|
18
|
+
type EventSubscription,
|
|
19
|
+
} from "expo-modules-core";
|
|
20
|
+
import { X } from "lucide-react-native";
|
|
21
|
+
import type { PropsWithChildren } from "react";
|
|
22
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
23
|
+
import type { ViewStyle } from "react-native";
|
|
24
|
+
import {
|
|
25
|
+
Dimensions,
|
|
26
|
+
LogBox,
|
|
27
|
+
NativeModules,
|
|
28
|
+
StyleSheet,
|
|
29
|
+
Text,
|
|
30
|
+
TouchableOpacity,
|
|
31
|
+
View,
|
|
32
|
+
} from "react-native";
|
|
33
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
import DebuggingOverlay from "react-native/Libraries/Debugging/DebuggingOverlay.js";
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
import useSubscribeToDebuggingOverlayRegistry from "react-native/Libraries/Debugging/useSubscribeToDebuggingOverlayRegistry";
|
|
38
|
+
import type {
|
|
39
|
+
InspectorData,
|
|
40
|
+
TouchedViewDataAtPoint,
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
} from "react-native/Libraries/Renderer/shims/ReactNativeTypes";
|
|
43
|
+
import ErrorUtils from "react-native/Libraries/vendor/core/ErrorUtils";
|
|
44
|
+
|
|
45
|
+
const getInspectorDataForViewAtPoint =
|
|
46
|
+
require("react-native/src/private/inspector/getInspectorDataForViewAtPoint").default;
|
|
47
|
+
const InspectorOverlay =
|
|
48
|
+
require("react-native/src/private/inspector/InspectorOverlay").default;
|
|
49
|
+
// Removed InspectorPanel import - implementing inline
|
|
50
|
+
|
|
51
|
+
type PanelPosition = "top" | "bottom";
|
|
52
|
+
|
|
53
|
+
export type InspectedElementFrame = TouchedViewDataAtPoint["frame"];
|
|
54
|
+
|
|
55
|
+
export type InspectedElement = Readonly<{
|
|
56
|
+
frame: InspectedElementFrame;
|
|
57
|
+
style?: ViewStyle;
|
|
58
|
+
}>;
|
|
59
|
+
|
|
60
|
+
export type ElementsHierarchy = InspectorData["hierarchy"];
|
|
61
|
+
|
|
62
|
+
export type BundleInspectorRef = { enableDebuggingOverlay: () => void };
|
|
63
|
+
export type BundleInspectorProps = PropsWithChildren<{}>;
|
|
64
|
+
|
|
65
|
+
const BridgeModule = requireOptionalNativeModule("Bridge");
|
|
66
|
+
|
|
67
|
+
export function isRorkSandbox() {
|
|
68
|
+
return !!NativeModules.RorkSandbox;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (BridgeModule) {
|
|
72
|
+
LogBox.ignoreAllLogs();
|
|
73
|
+
LogBox.uninstall();
|
|
74
|
+
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
ErrorUtils.setGlobalHandler((error) => {
|
|
77
|
+
sendBridgeMessage("runtime-error", {
|
|
78
|
+
stack: error.stack,
|
|
79
|
+
message: error.message,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function sendBridgeMessage(
|
|
85
|
+
type:
|
|
86
|
+
| "inspector-element"
|
|
87
|
+
| "merge-inspector-state"
|
|
88
|
+
| "runtime-ready"
|
|
89
|
+
| "runtime-error",
|
|
90
|
+
data?: Record<string, any>,
|
|
91
|
+
) {
|
|
92
|
+
if (data) {
|
|
93
|
+
return BridgeModule?.sendMessage({ type, data: JSON.stringify(data) });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return BridgeModule?.sendMessage({ type });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function addBridgeListener(
|
|
100
|
+
listener: (data: Record<string, any>) => void,
|
|
101
|
+
): EventSubscription {
|
|
102
|
+
return BridgeModule?.addListener("onMessage", (data: any) => {
|
|
103
|
+
if (typeof data !== "object") return;
|
|
104
|
+
if (data.data) {
|
|
105
|
+
listener({ ...data, data: JSON.parse(data.data) });
|
|
106
|
+
} else {
|
|
107
|
+
listener(data);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function useBridge() {
|
|
113
|
+
const [state, setState] = useState({ inspectorEnabled: false });
|
|
114
|
+
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
const subscription = addBridgeListener((data) => {
|
|
117
|
+
if (typeof data === "object" && data.type === "merge-inspector-state") {
|
|
118
|
+
setState((prev) => ({ ...prev, ...data.data }));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
sendBridgeMessage("runtime-ready");
|
|
123
|
+
|
|
124
|
+
return () => subscription?.remove();
|
|
125
|
+
}, []);
|
|
126
|
+
|
|
127
|
+
const disableInspector = useCallback(() => {
|
|
128
|
+
setState((prev) => ({ ...prev, inspectorEnabled: false }));
|
|
129
|
+
sendBridgeMessage("merge-inspector-state", { inspectorEnabled: false });
|
|
130
|
+
}, []);
|
|
131
|
+
|
|
132
|
+
return { ...state, disableInspector };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function BundleInspector(props: BundleInspectorProps) {
|
|
136
|
+
const innerViewRef = useRef(null);
|
|
137
|
+
const appContainerRootViewRef = useRef(null);
|
|
138
|
+
const debuggingOverlayRef = useRef(null);
|
|
139
|
+
const { inspectorEnabled, disableInspector } = useBridge();
|
|
140
|
+
|
|
141
|
+
const [panelPosition, setPanelPosition] = useState<PanelPosition>("bottom");
|
|
142
|
+
const [inspectedElement, setInspectedElement] =
|
|
143
|
+
useState<InspectedElement | null>(null);
|
|
144
|
+
|
|
145
|
+
const [lastPayload, setLastPayload] = useState<Record<string, any> | null>(
|
|
146
|
+
null,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (inspectorEnabled) return;
|
|
151
|
+
setInspectedElement(null);
|
|
152
|
+
setPanelPosition("bottom");
|
|
153
|
+
}, [inspectorEnabled]);
|
|
154
|
+
|
|
155
|
+
useSubscribeToDebuggingOverlayRegistry(
|
|
156
|
+
appContainerRootViewRef,
|
|
157
|
+
debuggingOverlayRef,
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const handleInspectedElementChange = useCallback(
|
|
161
|
+
(viewData: TouchedViewDataAtPoint | null) => {
|
|
162
|
+
if (viewData) {
|
|
163
|
+
const payload = {
|
|
164
|
+
style: viewData.props.style,
|
|
165
|
+
frame: viewData.frame,
|
|
166
|
+
componentStack: viewData.componentStack,
|
|
167
|
+
hierarchy: viewData.hierarchy?.map((h: any) => ({
|
|
168
|
+
name: h.name ?? null,
|
|
169
|
+
})),
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
setLastPayload(payload);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
[],
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const onTouchPoint = (locationX: number, locationY: number) => {
|
|
179
|
+
getInspectorDataForViewAtPoint(
|
|
180
|
+
innerViewRef.current,
|
|
181
|
+
locationX,
|
|
182
|
+
locationY,
|
|
183
|
+
(viewData: TouchedViewDataAtPoint) => {
|
|
184
|
+
setPanelPosition(
|
|
185
|
+
viewData.pointerY > Dimensions.get("window").height * 0.8
|
|
186
|
+
? "top"
|
|
187
|
+
: "bottom",
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
setInspectedElement({
|
|
191
|
+
frame: viewData.frame,
|
|
192
|
+
style: viewData.props.style,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
handleInspectedElementChange(viewData);
|
|
196
|
+
|
|
197
|
+
return false;
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const { top, bottom } = useSafeAreaInsets();
|
|
203
|
+
|
|
204
|
+
const panelContainerStyle =
|
|
205
|
+
panelPosition === "bottom"
|
|
206
|
+
? { bottom: 0, marginBottom: bottom }
|
|
207
|
+
: { top: 0, marginTop: top };
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<View style={styles.container} ref={appContainerRootViewRef}>
|
|
211
|
+
<View style={styles.container} ref={innerViewRef}>
|
|
212
|
+
{props.children}
|
|
213
|
+
</View>
|
|
214
|
+
|
|
215
|
+
{inspectorEnabled && (
|
|
216
|
+
<DebuggingOverlay ref={debuggingOverlayRef} style={styles.absolute} />
|
|
217
|
+
)}
|
|
218
|
+
|
|
219
|
+
{inspectorEnabled && (
|
|
220
|
+
<View style={styles.inspectorContainer} pointerEvents="box-none">
|
|
221
|
+
<InspectorOverlay
|
|
222
|
+
inspected={inspectedElement}
|
|
223
|
+
onTouchPoint={onTouchPoint}
|
|
224
|
+
/>
|
|
225
|
+
|
|
226
|
+
<BlurView
|
|
227
|
+
style={[
|
|
228
|
+
{
|
|
229
|
+
position: "absolute",
|
|
230
|
+
left: 0,
|
|
231
|
+
right: 0,
|
|
232
|
+
backgroundColor: "rgba(0, 0, 0, 0.85)",
|
|
233
|
+
borderRadius: 30,
|
|
234
|
+
marginHorizontal: 12,
|
|
235
|
+
padding: 12,
|
|
236
|
+
paddingLeft: 20,
|
|
237
|
+
overflow: "hidden",
|
|
238
|
+
},
|
|
239
|
+
panelContainerStyle,
|
|
240
|
+
]}
|
|
241
|
+
>
|
|
242
|
+
{inspectedElement ? (
|
|
243
|
+
<View style={styles.floatingIsland}>
|
|
244
|
+
<Text style={styles.islandText}>Element selected</Text>
|
|
245
|
+
<View style={styles.buttonGroup}>
|
|
246
|
+
<TouchableOpacity
|
|
247
|
+
style={styles.selectButton}
|
|
248
|
+
onPress={() => {
|
|
249
|
+
if (lastPayload) {
|
|
250
|
+
sendBridgeMessage("inspector-element", lastPayload);
|
|
251
|
+
disableInspector();
|
|
252
|
+
}
|
|
253
|
+
}}
|
|
254
|
+
>
|
|
255
|
+
<Text style={styles.buttonText}>Select</Text>
|
|
256
|
+
</TouchableOpacity>
|
|
257
|
+
<TouchableOpacity
|
|
258
|
+
activeOpacity={0.72}
|
|
259
|
+
style={styles.cancelButton}
|
|
260
|
+
onPress={disableInspector}
|
|
261
|
+
>
|
|
262
|
+
<X size={18} color="#808080" strokeWidth={2.5} />
|
|
263
|
+
</TouchableOpacity>
|
|
264
|
+
</View>
|
|
265
|
+
</View>
|
|
266
|
+
) : (
|
|
267
|
+
<View style={styles.floatingIsland}>
|
|
268
|
+
<Text style={styles.islandText}>
|
|
269
|
+
Touch any element to inspect
|
|
270
|
+
</Text>
|
|
271
|
+
<TouchableOpacity
|
|
272
|
+
activeOpacity={0.72}
|
|
273
|
+
style={styles.cancelTextButton}
|
|
274
|
+
onPress={disableInspector}
|
|
275
|
+
>
|
|
276
|
+
<Text style={styles.buttonText}>Cancel</Text>
|
|
277
|
+
</TouchableOpacity>
|
|
278
|
+
</View>
|
|
279
|
+
)}
|
|
280
|
+
</BlurView>
|
|
281
|
+
</View>
|
|
282
|
+
)}
|
|
283
|
+
</View>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const styles = StyleSheet.create({
|
|
288
|
+
container: {
|
|
289
|
+
flex: 1,
|
|
290
|
+
},
|
|
291
|
+
absolute: StyleSheet.absoluteFillObject,
|
|
292
|
+
inspectorContainer: {
|
|
293
|
+
position: "absolute",
|
|
294
|
+
backgroundColor: "transparent",
|
|
295
|
+
top: 0,
|
|
296
|
+
left: 0,
|
|
297
|
+
right: 0,
|
|
298
|
+
bottom: 0,
|
|
299
|
+
},
|
|
300
|
+
properties: {
|
|
301
|
+
flexShrink: 1,
|
|
302
|
+
},
|
|
303
|
+
elementInfo: {
|
|
304
|
+
padding: 8,
|
|
305
|
+
gap: 3,
|
|
306
|
+
},
|
|
307
|
+
section: {
|
|
308
|
+
marginBottom: 15,
|
|
309
|
+
},
|
|
310
|
+
sectionTitle: {
|
|
311
|
+
color: "white",
|
|
312
|
+
fontSize: 11,
|
|
313
|
+
fontWeight: "600",
|
|
314
|
+
marginBottom: 4,
|
|
315
|
+
textTransform: "uppercase",
|
|
316
|
+
opacity: 0.7,
|
|
317
|
+
},
|
|
318
|
+
boxModel: {
|
|
319
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
320
|
+
padding: 10,
|
|
321
|
+
borderRadius: 4,
|
|
322
|
+
alignItems: "center",
|
|
323
|
+
},
|
|
324
|
+
boxText: {
|
|
325
|
+
color: "white",
|
|
326
|
+
fontSize: 13,
|
|
327
|
+
fontWeight: "500",
|
|
328
|
+
},
|
|
329
|
+
layoutInfo: {
|
|
330
|
+
backgroundColor: "rgba(255, 255, 255, 0.05)",
|
|
331
|
+
padding: 8,
|
|
332
|
+
borderRadius: 4,
|
|
333
|
+
},
|
|
334
|
+
layoutText: {
|
|
335
|
+
color: "white",
|
|
336
|
+
fontSize: 12,
|
|
337
|
+
marginBottom: 2,
|
|
338
|
+
},
|
|
339
|
+
styleInfo: {
|
|
340
|
+
backgroundColor: "rgba(255, 255, 255, 0.05)",
|
|
341
|
+
padding: 8,
|
|
342
|
+
borderRadius: 4,
|
|
343
|
+
},
|
|
344
|
+
styleText: {
|
|
345
|
+
color: "white",
|
|
346
|
+
fontSize: 11,
|
|
347
|
+
marginBottom: 2,
|
|
348
|
+
fontFamily: "monospace",
|
|
349
|
+
},
|
|
350
|
+
waiting: {
|
|
351
|
+
height: 60,
|
|
352
|
+
justifyContent: "center",
|
|
353
|
+
alignItems: "center",
|
|
354
|
+
},
|
|
355
|
+
waitingContent: {
|
|
356
|
+
flex: 1,
|
|
357
|
+
justifyContent: "center",
|
|
358
|
+
alignItems: "center",
|
|
359
|
+
},
|
|
360
|
+
waitingText: {
|
|
361
|
+
fontSize: 14,
|
|
362
|
+
textAlign: "center",
|
|
363
|
+
color: "white",
|
|
364
|
+
opacity: 0.9,
|
|
365
|
+
fontWeight: "500",
|
|
366
|
+
},
|
|
367
|
+
waitingSubText: {
|
|
368
|
+
fontSize: 12,
|
|
369
|
+
textAlign: "center",
|
|
370
|
+
color: "white",
|
|
371
|
+
opacity: 0.6,
|
|
372
|
+
marginTop: 4,
|
|
373
|
+
},
|
|
374
|
+
floatingIsland: {
|
|
375
|
+
flexDirection: "row",
|
|
376
|
+
justifyContent: "space-between",
|
|
377
|
+
alignItems: "center",
|
|
378
|
+
gap: 16,
|
|
379
|
+
},
|
|
380
|
+
islandText: {
|
|
381
|
+
color: "white",
|
|
382
|
+
fontSize: 16,
|
|
383
|
+
fontWeight: "600",
|
|
384
|
+
flex: 1,
|
|
385
|
+
},
|
|
386
|
+
buttonGroup: {
|
|
387
|
+
flexDirection: "row",
|
|
388
|
+
gap: 8,
|
|
389
|
+
},
|
|
390
|
+
selectButton: {
|
|
391
|
+
backgroundColor: "#007AFF",
|
|
392
|
+
paddingHorizontal: 12,
|
|
393
|
+
paddingVertical: 6,
|
|
394
|
+
borderRadius: 16,
|
|
395
|
+
minWidth: 60,
|
|
396
|
+
},
|
|
397
|
+
cancelButton: {
|
|
398
|
+
backgroundColor: "rgba(255, 255, 255, 0.15)",
|
|
399
|
+
borderRadius: 16,
|
|
400
|
+
aspectRatio: 1,
|
|
401
|
+
height: 28,
|
|
402
|
+
justifyContent: "center",
|
|
403
|
+
alignItems: "center",
|
|
404
|
+
},
|
|
405
|
+
cancelTextButton: {
|
|
406
|
+
backgroundColor: "rgba(255, 255, 255, 0.15)",
|
|
407
|
+
paddingHorizontal: 12,
|
|
408
|
+
paddingVertical: 6,
|
|
409
|
+
borderRadius: 16,
|
|
410
|
+
minWidth: 60,
|
|
411
|
+
},
|
|
412
|
+
buttonText: {
|
|
413
|
+
color: "white",
|
|
414
|
+
fontSize: 14,
|
|
415
|
+
fontWeight: "600",
|
|
416
|
+
textAlign: "center",
|
|
417
|
+
},
|
|
418
|
+
panelTitle: {
|
|
419
|
+
color: "white",
|
|
420
|
+
fontSize: 14,
|
|
421
|
+
fontWeight: "600",
|
|
422
|
+
marginBottom: 8,
|
|
423
|
+
textAlign: "center",
|
|
424
|
+
},
|
|
425
|
+
editorSection: {
|
|
426
|
+
marginBottom: 10,
|
|
427
|
+
},
|
|
428
|
+
inputGrid: {
|
|
429
|
+
flexDirection: "row",
|
|
430
|
+
gap: 8,
|
|
431
|
+
},
|
|
432
|
+
inputCell: {
|
|
433
|
+
flex: 1,
|
|
434
|
+
},
|
|
435
|
+
inputLabel: {
|
|
436
|
+
color: "white",
|
|
437
|
+
fontSize: 10,
|
|
438
|
+
fontWeight: "500",
|
|
439
|
+
marginBottom: 2,
|
|
440
|
+
opacity: 0.8,
|
|
441
|
+
},
|
|
442
|
+
compactInput: {
|
|
443
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
444
|
+
paddingHorizontal: 8,
|
|
445
|
+
paddingVertical: 4,
|
|
446
|
+
borderRadius: 4,
|
|
447
|
+
color: "white",
|
|
448
|
+
fontSize: 12,
|
|
449
|
+
borderWidth: 1,
|
|
450
|
+
borderColor: "rgba(255, 255, 255, 0.15)",
|
|
451
|
+
height: 28,
|
|
452
|
+
},
|
|
453
|
+
applyButton: {
|
|
454
|
+
backgroundColor: "#007AFF",
|
|
455
|
+
paddingVertical: 10,
|
|
456
|
+
paddingHorizontal: 20,
|
|
457
|
+
borderRadius: 6,
|
|
458
|
+
alignItems: "center",
|
|
459
|
+
marginTop: 8,
|
|
460
|
+
alignSelf: "flex-end",
|
|
461
|
+
},
|
|
462
|
+
applyButtonText: {
|
|
463
|
+
color: "white",
|
|
464
|
+
fontSize: 14,
|
|
465
|
+
fontWeight: "600",
|
|
466
|
+
},
|
|
467
|
+
});
|