@teardown/react-native 1.0.13 → 1.1.0-beta-05
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/dist/components/debugger-ui.d.ts +7 -0
- package/dist/components/debugger-ui.js +147 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +17 -0
- package/dist/components/teardown-logo.d.ts +4 -0
- package/dist/components/teardown-logo.js +33 -0
- package/dist/containers/index.d.ts +1 -0
- package/dist/containers/index.js +17 -0
- package/dist/containers/teardown.container.d.ts +11 -0
- package/dist/containers/teardown.container.js +13 -0
- package/dist/debugger.d.ts +13 -0
- package/dist/debugger.js +75 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +21 -0
- package/dist/metro/index.d.ts +2 -0
- package/dist/metro/index.js +5 -0
- package/dist/metro-plugin.d.ts +1 -0
- package/dist/metro-plugin.js +45 -0
- package/dist/plugins/http.plugin.d.ts +23 -0
- package/dist/plugins/http.plugin.js +144 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +19 -0
- package/dist/plugins/logging.plugin.d.ts +9 -0
- package/dist/plugins/logging.plugin.js +35 -0
- package/dist/plugins/websocket.plugin.d.ts +17 -0
- package/dist/plugins/websocket.plugin.js +102 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +17 -0
- package/dist/services/teardown.service.d.ts +10 -0
- package/dist/services/teardown.service.js +21 -0
- package/dist/teardown.client.d.ts +44 -0
- package/dist/teardown.client.js +65 -0
- package/package.json +35 -25
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
2
|
+
export type DebuggerUiPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center-left' | 'center-right';
|
|
3
|
+
export type DebuggerUiOptions = {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
position?: DebuggerUiPosition;
|
|
6
|
+
};
|
|
7
|
+
export declare const DebuggerUi: FunctionComponent<DebuggerUiOptions>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DebuggerUi = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
const react_native_safe_area_context_1 = require("react-native-safe-area-context");
|
|
8
|
+
const teardown_logo_1 = require("./teardown-logo");
|
|
9
|
+
const react_native_gesture_handler_1 = require("react-native-gesture-handler");
|
|
10
|
+
const react_native_ui_1 = require("@teardown/react-native-ui");
|
|
11
|
+
const teardown_service_1 = require("../services/teardown.service");
|
|
12
|
+
const DebuggerUi = props => {
|
|
13
|
+
const { enabled = true } = props;
|
|
14
|
+
return null;
|
|
15
|
+
if (!__DEV__) {
|
|
16
|
+
// never render the debugger ui in any mode apart from __DEV__ == true "development"
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const isNotEnabled = !enabled;
|
|
20
|
+
if (isNotEnabled) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return (0, jsx_runtime_1.jsx)(DebuggerUiEnabled, { ...props });
|
|
24
|
+
};
|
|
25
|
+
exports.DebuggerUi = DebuggerUi;
|
|
26
|
+
const DebuggerUiEnabled = props => {
|
|
27
|
+
const { position } = props;
|
|
28
|
+
const safeAreaInsets = (0, react_native_safe_area_context_1.useSafeAreaInsets)();
|
|
29
|
+
const bottomSheetRef = (0, react_1.useRef)(null);
|
|
30
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.container, pointerEvents: 'box-none', children: (0, jsx_runtime_1.jsx)(react_native_gesture_handler_1.GestureHandlerRootView, { children: (0, jsx_runtime_1.jsxs)(react_native_ui_1.BottomSheetModalProvider, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: () => {
|
|
31
|
+
// bottomSheetRef.current?.snapToIndex(0);
|
|
32
|
+
}, style: [
|
|
33
|
+
styles.orb,
|
|
34
|
+
getOrbPosition(safeAreaInsets, position ?? 'center-right'),
|
|
35
|
+
], children: (0, jsx_runtime_1.jsx)(teardown_logo_1.TeardownLogo, { height: 20, width: 20 }) }), (0, jsx_runtime_1.jsxs)(react_native_ui_1.BottomSheet, { sheetRef: bottomSheetRef, handleComponent: handleProps => ((0, jsx_runtime_1.jsx)(DebuggerStatusHandleComponent, { ...handleProps })), children: [(0, jsx_runtime_1.jsx)(react_native_ui_1.BottomSheetCloseIcon, {}), (0, jsx_runtime_1.jsxs)(react_native_ui_1.BottomSheetView, { style: {
|
|
36
|
+
paddingBottom: safeAreaInsets.bottom + 16,
|
|
37
|
+
}, children: [(0, jsx_runtime_1.jsx)(react_native_ui_1.BottomSheetHeader, { children: (0, jsx_runtime_1.jsx)(react_native_ui_1.BottomSheetTitle, { children: "Debugger" }) }), (0, jsx_runtime_1.jsx)(react_native_ui_1.BottomSheetContent, { children: (0, jsx_runtime_1.jsx)(react_native_ui_1.Button, { onPress: () => {
|
|
38
|
+
react_native_1.DevSettings.reload('Teardown reconnect');
|
|
39
|
+
}, children: "Reconnect debugger" }) })] })] })] }) }) }) }));
|
|
40
|
+
};
|
|
41
|
+
const DebuggerStatusHandleComponent = () => {
|
|
42
|
+
const { client } = teardown_service_1.TeardownService.useState();
|
|
43
|
+
const [debuggerStatus, setDebuggerStatus] = (0, react_1.useState)(client.debugger?.getStatus() ?? null);
|
|
44
|
+
(0, react_1.useEffect)(() => {
|
|
45
|
+
const listener = client.debugger?.emitter.on("CONNECTION_STATUS_CHANGED", (event) => {
|
|
46
|
+
const { payload } = event;
|
|
47
|
+
setDebuggerStatus(event.payload.status);
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
listener?.remove();
|
|
51
|
+
};
|
|
52
|
+
}, [client]);
|
|
53
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
|
|
54
|
+
{
|
|
55
|
+
backgroundColor: getColorForDebuggerStatus(debuggerStatus),
|
|
56
|
+
},
|
|
57
|
+
styles.debugger_status,
|
|
58
|
+
], children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.debugger_status_text, children: debuggerStatus }) }));
|
|
59
|
+
};
|
|
60
|
+
const styles = react_native_1.StyleSheet.create({
|
|
61
|
+
debugger_status: {
|
|
62
|
+
flex: 1,
|
|
63
|
+
borderTopLeftRadius: 15,
|
|
64
|
+
borderTopRightRadius: 15,
|
|
65
|
+
padding: 4,
|
|
66
|
+
},
|
|
67
|
+
debugger_status_text: {
|
|
68
|
+
color: 'white',
|
|
69
|
+
fontSize: 12,
|
|
70
|
+
textAlign: 'center',
|
|
71
|
+
fontWeight: 'bold',
|
|
72
|
+
},
|
|
73
|
+
container: {
|
|
74
|
+
...react_native_1.StyleSheet.absoluteFillObject,
|
|
75
|
+
backgroundColor: 'white',
|
|
76
|
+
},
|
|
77
|
+
orb: {
|
|
78
|
+
height: 40,
|
|
79
|
+
width: 40,
|
|
80
|
+
backgroundColor: 'hsl(240 5% 6%)',
|
|
81
|
+
borderRadius: 40,
|
|
82
|
+
position: 'absolute',
|
|
83
|
+
justifyContent: 'center',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
},
|
|
86
|
+
half_height: {
|
|
87
|
+
height: '50%',
|
|
88
|
+
backgroundColor: '#e1e1e1',
|
|
89
|
+
position: 'absolute',
|
|
90
|
+
left: 0,
|
|
91
|
+
right: 0,
|
|
92
|
+
bottom: 0,
|
|
93
|
+
},
|
|
94
|
+
logo: {
|
|
95
|
+
height: 20,
|
|
96
|
+
width: 20,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
const getColorForDebuggerStatus = (status) => {
|
|
100
|
+
switch (status) {
|
|
101
|
+
case 'CONNECTING':
|
|
102
|
+
return 'yellow';
|
|
103
|
+
case 'CONNECTED':
|
|
104
|
+
return 'green';
|
|
105
|
+
case 'DISCONNECTED':
|
|
106
|
+
return 'red';
|
|
107
|
+
case 'FAILED':
|
|
108
|
+
return 'red';
|
|
109
|
+
default:
|
|
110
|
+
return 'gray';
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const getOrbPosition = (edgeInsets, position) => {
|
|
114
|
+
const DEFAULT_PADDING = 16;
|
|
115
|
+
switch (position) {
|
|
116
|
+
case 'top-left':
|
|
117
|
+
return {
|
|
118
|
+
top: DEFAULT_PADDING + edgeInsets.top,
|
|
119
|
+
left: DEFAULT_PADDING,
|
|
120
|
+
};
|
|
121
|
+
case 'top-right':
|
|
122
|
+
return {
|
|
123
|
+
top: DEFAULT_PADDING + edgeInsets.top,
|
|
124
|
+
right: DEFAULT_PADDING,
|
|
125
|
+
};
|
|
126
|
+
case 'bottom-left':
|
|
127
|
+
return {
|
|
128
|
+
bottom: DEFAULT_PADDING + edgeInsets.bottom,
|
|
129
|
+
left: DEFAULT_PADDING,
|
|
130
|
+
};
|
|
131
|
+
case 'bottom-right':
|
|
132
|
+
return {
|
|
133
|
+
bottom: DEFAULT_PADDING + edgeInsets.bottom,
|
|
134
|
+
right: DEFAULT_PADDING,
|
|
135
|
+
};
|
|
136
|
+
case 'center-left':
|
|
137
|
+
return {
|
|
138
|
+
top: '50%',
|
|
139
|
+
left: DEFAULT_PADDING,
|
|
140
|
+
};
|
|
141
|
+
case 'center-right':
|
|
142
|
+
return {
|
|
143
|
+
top: '50%',
|
|
144
|
+
right: DEFAULT_PADDING,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './debugger-ui';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./debugger-ui"), exports);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.TeardownLogo = void 0;
|
|
27
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
28
|
+
const react_native_svg_1 = __importStar(require("react-native-svg"));
|
|
29
|
+
const TeardownLogo = (props) => {
|
|
30
|
+
const {} = props;
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(react_native_svg_1.default, { width: "350", height: "350", viewBox: "0 0 350 350", fill: "none", ...props, children: (0, jsx_runtime_1.jsx)(react_native_svg_1.Path, { fillRule: "evenodd", clipRule: "evenodd", d: "M175.09 345L300 218.574L256.859 174.909L299.821 131.426L174.91 5.00001L50 131.426L93.141 175.091L50.179 218.574L175.09 345ZM114.879 197.093L93.656 218.574L175.09 300.995L256.523 218.574L235.12 196.911L174.91 257.853L114.879 197.093ZM213.382 174.909L174.91 213.848L136.618 175.091L175.09 136.152L213.382 174.909ZM235.12 152.907L175.09 92.147L114.879 153.089L93.477 131.426L174.91 49.005L256.344 131.426L235.12 152.907Z", fill: "white" }) }));
|
|
32
|
+
};
|
|
33
|
+
exports.TeardownLogo = TeardownLogo;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './teardown.container';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./teardown.container"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FunctionComponent, PropsWithChildren } from "react";
|
|
2
|
+
import type { PluginTuple, TeardownClient } from "../teardown.client";
|
|
3
|
+
import type { DebuggerUiOptions } from "../components";
|
|
4
|
+
export type TeardownContainerOptions = {
|
|
5
|
+
debugger: DebuggerUiOptions;
|
|
6
|
+
};
|
|
7
|
+
export type TeardownContainerProps<T extends readonly PluginTuple[]> = PropsWithChildren<{
|
|
8
|
+
client: TeardownClient<T>;
|
|
9
|
+
options?: TeardownContainerOptions;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const TeardownContainer: FunctionComponent<TeardownContainerProps<any>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TeardownContainer = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const services_1 = require("../services");
|
|
6
|
+
const react_native_safe_area_context_1 = require("react-native-safe-area-context");
|
|
7
|
+
const react_native_gesture_handler_1 = require("react-native-gesture-handler");
|
|
8
|
+
const TeardownContainer = (props) => {
|
|
9
|
+
const { children, client, options } = props;
|
|
10
|
+
const providedState = services_1.TeardownService.useProvidedState(client);
|
|
11
|
+
return ((0, jsx_runtime_1.jsx)(react_native_safe_area_context_1.SafeAreaProvider, { children: (0, jsx_runtime_1.jsx)(react_native_gesture_handler_1.GestureHandlerRootView, { children: children }) }));
|
|
12
|
+
};
|
|
13
|
+
exports.TeardownContainer = TeardownContainer;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ClientWebsocketEvents, type ConnectionEstablishedWebsocketEvent, WebsocketClient, type WebsocketClientOptions, type WebsocketConnectionStatus } from "@teardown/websocket";
|
|
2
|
+
export type DebuggerStatus = WebsocketConnectionStatus;
|
|
3
|
+
export type DebuggerOptions = WebsocketClientOptions & {
|
|
4
|
+
deviceName?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class Debugger extends WebsocketClient<ClientWebsocketEvents> {
|
|
7
|
+
private readonly customDeviceName?;
|
|
8
|
+
constructor(options?: DebuggerOptions);
|
|
9
|
+
private getDeviceName;
|
|
10
|
+
onConnectionEstablished(event: ConnectionEstablishedWebsocketEvent): Promise<void>;
|
|
11
|
+
getHostFromUrl(url: string): string;
|
|
12
|
+
getHost(): string;
|
|
13
|
+
}
|
package/dist/debugger.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Debugger = void 0;
|
|
7
|
+
const logger_1 = require("@teardown/logger");
|
|
8
|
+
const websocket_1 = require("@teardown/websocket");
|
|
9
|
+
const react_native_1 = require("react-native");
|
|
10
|
+
const react_native_device_info_1 = __importDefault(require("react-native-device-info"));
|
|
11
|
+
class Debugger extends websocket_1.WebsocketClient {
|
|
12
|
+
customDeviceName;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super({
|
|
15
|
+
logger: new logger_1.Logger("Debugger"),
|
|
16
|
+
...options,
|
|
17
|
+
});
|
|
18
|
+
this.customDeviceName = options?.deviceName;
|
|
19
|
+
}
|
|
20
|
+
async getDeviceName() {
|
|
21
|
+
if (this.customDeviceName) {
|
|
22
|
+
return this.customDeviceName;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
return await react_native_device_info_1.default.getDeviceName();
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return react_native_1.Platform.select({
|
|
29
|
+
ios: "iPhone",
|
|
30
|
+
android: "Android",
|
|
31
|
+
default: "Unknown Device",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async onConnectionEstablished(event) {
|
|
36
|
+
const [deviceId, deviceName] = await Promise.all([
|
|
37
|
+
react_native_device_info_1.default.getUniqueId(),
|
|
38
|
+
this.getDeviceName(),
|
|
39
|
+
]);
|
|
40
|
+
this.send("DEVICE_CONNECTION_ESTABLISHED", {
|
|
41
|
+
deviceId,
|
|
42
|
+
deviceName,
|
|
43
|
+
platform: react_native_1.Platform.OS,
|
|
44
|
+
platformVersion: react_native_1.Platform.Version,
|
|
45
|
+
reactNativeVersion: react_native_1.Platform.constants.reactNativeVersion,
|
|
46
|
+
isDisableAnimations: react_native_1.Platform.constants.isDisableAnimations ?? false,
|
|
47
|
+
isTesting: react_native_1.Platform.constants.isTesting,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
getHostFromUrl(url) {
|
|
51
|
+
const host = url.match(/^(?:https?:\/\/)?(\[[^\]]+\]|[^/:\s]+)(?::\d+)?(?:[/?#]|$)/)?.[1];
|
|
52
|
+
if (typeof host !== "string") {
|
|
53
|
+
throw new Error("Invalid URL - host not found");
|
|
54
|
+
}
|
|
55
|
+
return host;
|
|
56
|
+
}
|
|
57
|
+
getHost() {
|
|
58
|
+
try {
|
|
59
|
+
// https://github.com/facebook/react-native/blob/2a7f969500cef73b621269299619ee1f0ee9521a/packages/react-native/src/private/specs/modules/NativeSourceCode.js#L16
|
|
60
|
+
const scriptURL = react_native_1.NativeModules?.SourceCode?.getConstants().scriptURL;
|
|
61
|
+
if (typeof scriptURL !== "string")
|
|
62
|
+
throw new Error("Invalid non-string URL");
|
|
63
|
+
return this.getHostFromUrl(scriptURL);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const superHost = super.getHost();
|
|
67
|
+
const errorMessage = typeof error === "object" && error !== null && "message" in error
|
|
68
|
+
? error.message
|
|
69
|
+
: String(error);
|
|
70
|
+
this.logger.warn(`Failed to get host: "${errorMessage}" - Falling back to ${superHost}`);
|
|
71
|
+
return superHost;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.Debugger = Debugger;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// export * from './components';
|
|
18
|
+
__exportStar(require("./containers"), exports);
|
|
19
|
+
// export * from './services';
|
|
20
|
+
__exportStar(require("./teardown.client"), exports);
|
|
21
|
+
__exportStar(require("./plugins"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
8
|
+
function getConfig() {
|
|
9
|
+
const screensDir = node_path_1.default.join(__dirname, "screens");
|
|
10
|
+
const outputFile = node_path_1.default.join(__dirname, "screens.gen.tsx");
|
|
11
|
+
return {
|
|
12
|
+
server: {
|
|
13
|
+
enhanceMiddleware: (middleware) => {
|
|
14
|
+
return (req, res, next) => {
|
|
15
|
+
console.log("Request URL:", req.url);
|
|
16
|
+
// Handle requests as usual
|
|
17
|
+
return middleware;
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// Function to generate the output file
|
|
24
|
+
function generateOutputFile() {
|
|
25
|
+
// Your code to generate the output file based on the files in the ./screens folder
|
|
26
|
+
const outputContent = "/* Generated file */";
|
|
27
|
+
console.log("Generating output file...");
|
|
28
|
+
// fs.writeFileSync(outputFile, outputContent);
|
|
29
|
+
}
|
|
30
|
+
// Initialize the watcher
|
|
31
|
+
const watcher = chokidar_1.default.watch(screensDir, {
|
|
32
|
+
ignored: /(^|[\/\\])\../, // Ignore dotfiles
|
|
33
|
+
persistent: true,
|
|
34
|
+
});
|
|
35
|
+
// Watch for changes in the ./screens folder
|
|
36
|
+
watcher
|
|
37
|
+
.on("add", generateOutputFile)
|
|
38
|
+
.on("change", generateOutputFile)
|
|
39
|
+
.on("unlink", generateOutputFile)
|
|
40
|
+
.on("ready", generateOutputFile) // Generate the initial output file
|
|
41
|
+
.on("error", (error) => console.error(`Watcher error: ${error}`));
|
|
42
|
+
console.log(`Watching ${screensDir} for changes...`);
|
|
43
|
+
module.exports = {
|
|
44
|
+
server: {},
|
|
45
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TeardownClient } from "../teardown.client";
|
|
2
|
+
import { type DefaultPluginOptions, Plugin } from "../teardown.client";
|
|
3
|
+
export type HTTPPluginOptions = DefaultPluginOptions<{
|
|
4
|
+
ignoreURLs?: RegExp[];
|
|
5
|
+
}>;
|
|
6
|
+
export declare class HTTPPlugin extends Plugin {
|
|
7
|
+
private client;
|
|
8
|
+
private requests;
|
|
9
|
+
private ignoreURLs;
|
|
10
|
+
constructor(options?: HTTPPluginOptions);
|
|
11
|
+
install(client: TeardownClient<any>): void;
|
|
12
|
+
enableXHRInterceptor(): void;
|
|
13
|
+
disableInterception(): void;
|
|
14
|
+
private shouldIgnoreURL;
|
|
15
|
+
private xhrOpenCallback;
|
|
16
|
+
private xhrRequestHeaderCallback;
|
|
17
|
+
private xhrSendCallback;
|
|
18
|
+
private serializeRequestBody;
|
|
19
|
+
private xhrResponseCallback;
|
|
20
|
+
private parseResponseHeaders;
|
|
21
|
+
private parseResponseBody;
|
|
22
|
+
private sendHTTPEvent;
|
|
23
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HTTPPlugin = void 0;
|
|
7
|
+
const util_1 = require("@teardown/util");
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const XHRInterceptor_1 = __importDefault(require("react-native/Libraries/Network/XHRInterceptor"));
|
|
10
|
+
const teardown_client_1 = require("../teardown.client");
|
|
11
|
+
class HTTPPlugin extends teardown_client_1.Plugin {
|
|
12
|
+
client = null;
|
|
13
|
+
requests = new Map();
|
|
14
|
+
ignoreURLs;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
super({
|
|
17
|
+
...options,
|
|
18
|
+
key: "HTTPPlugin",
|
|
19
|
+
});
|
|
20
|
+
this.ignoreURLs = options.ignoreURLs || [];
|
|
21
|
+
}
|
|
22
|
+
install(client) {
|
|
23
|
+
this.client = client;
|
|
24
|
+
this.enableXHRInterceptor();
|
|
25
|
+
}
|
|
26
|
+
enableXHRInterceptor() {
|
|
27
|
+
// noinspection TypeScriptUnresolvedReference
|
|
28
|
+
if (XHRInterceptor_1.default.isInterceptorEnabled()) {
|
|
29
|
+
// this.logger.info(
|
|
30
|
+
// 'XHRInterceptor is already enabled by another library. Disable it or run this plugin first when your app loads.',
|
|
31
|
+
// );
|
|
32
|
+
this.logger.info("XHRInterceptor is already enabled. Teardown overrides the existing interceptor - other plugins may not work as expected.");
|
|
33
|
+
this.disableInterception();
|
|
34
|
+
}
|
|
35
|
+
this.logger.info("Enabling XHRInterceptor");
|
|
36
|
+
// noinspection TypeScriptUnresolvedReference
|
|
37
|
+
XHRInterceptor_1.default.setOpenCallback(this.xhrOpenCallback);
|
|
38
|
+
// noinspection TypeScriptUnresolvedReference
|
|
39
|
+
XHRInterceptor_1.default.setRequestHeaderCallback(this.xhrRequestHeaderCallback);
|
|
40
|
+
// noinspection TypeScriptUnresolvedReference
|
|
41
|
+
XHRInterceptor_1.default.setSendCallback(this.xhrSendCallback);
|
|
42
|
+
// noinspection TypeScriptUnresolvedReference
|
|
43
|
+
XHRInterceptor_1.default.setResponseCallback(this.xhrResponseCallback);
|
|
44
|
+
// noinspection TypeScriptUnresolvedReference
|
|
45
|
+
XHRInterceptor_1.default.enableInterception();
|
|
46
|
+
this.logger.info("XHRInterceptor enabled");
|
|
47
|
+
}
|
|
48
|
+
disableInterception() {
|
|
49
|
+
this.logger.info("Disabling XHRInterceptor");
|
|
50
|
+
XHRInterceptor_1.default.disableInterception();
|
|
51
|
+
this.requests.clear();
|
|
52
|
+
this.logger.info("XHRInterceptor disabled");
|
|
53
|
+
}
|
|
54
|
+
shouldIgnoreURL(url) {
|
|
55
|
+
return this.ignoreURLs.some((ignoreRegex) => ignoreRegex.test(url));
|
|
56
|
+
}
|
|
57
|
+
xhrOpenCallback = (method, url, xhr) => {
|
|
58
|
+
if (this.shouldIgnoreURL(url)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const requestId = util_1.Util.generateUUID();
|
|
62
|
+
const HTTPRequestInfo = {
|
|
63
|
+
id: requestId,
|
|
64
|
+
type: "XMLHttpRequest",
|
|
65
|
+
url,
|
|
66
|
+
method: method,
|
|
67
|
+
requestHeaders: { "TD-Request-ID": requestId },
|
|
68
|
+
startTime: performance.now(),
|
|
69
|
+
updatedAt: performance.now(),
|
|
70
|
+
};
|
|
71
|
+
this.requests.set(xhr._id, HTTPRequestInfo);
|
|
72
|
+
};
|
|
73
|
+
xhrRequestHeaderCallback = (header, value, xhr) => {
|
|
74
|
+
const request = this.requests.get(xhr._id);
|
|
75
|
+
if (request) {
|
|
76
|
+
request.requestHeaders[header] = value;
|
|
77
|
+
request.updatedAt = performance.now();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
xhrSendCallback = (data, xhr) => {
|
|
81
|
+
const request = this.requests.get(xhr._id);
|
|
82
|
+
if (request) {
|
|
83
|
+
xhr.setRequestHeader("TD-Request-ID", request.id);
|
|
84
|
+
request.dataSent = this.serializeRequestBody(data);
|
|
85
|
+
request.updatedAt = performance.now();
|
|
86
|
+
this.sendHTTPEvent(request);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
serializeRequestBody(data) {
|
|
90
|
+
if (typeof data === "string") {
|
|
91
|
+
return data;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
return JSON.stringify(data);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
this.logger.warn("Failed to stringify request body", error);
|
|
98
|
+
return "[Unable to serialize request body]";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
xhrResponseCallback = (status, timeout, response, responseURL, responseType, xhr) => {
|
|
102
|
+
const request = this.requests.get(xhr._id);
|
|
103
|
+
if (request) {
|
|
104
|
+
request.status = status;
|
|
105
|
+
request.responseHeaders = this.parseResponseHeaders(xhr.getAllResponseHeaders());
|
|
106
|
+
request.response = this.parseResponseBody(response, responseType);
|
|
107
|
+
request.responseURL = responseURL;
|
|
108
|
+
request.responseType = responseType;
|
|
109
|
+
request.timeout = timeout;
|
|
110
|
+
request.endTime = performance.now();
|
|
111
|
+
request.updatedAt = performance.now();
|
|
112
|
+
this.sendHTTPEvent(request);
|
|
113
|
+
this.requests.delete(xhr._id);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
parseResponseHeaders(headersString) {
|
|
117
|
+
const headersObject = {};
|
|
118
|
+
if (headersString) {
|
|
119
|
+
const headerPairs = headersString.trim().split(/[\r\n]+/);
|
|
120
|
+
headerPairs.forEach((headerPair) => {
|
|
121
|
+
const [key, value] = headerPair.split(": ");
|
|
122
|
+
headersObject[key] = value;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return headersObject;
|
|
126
|
+
}
|
|
127
|
+
parseResponseBody(response, responseType) {
|
|
128
|
+
if (responseType === "json") {
|
|
129
|
+
try {
|
|
130
|
+
return JSON.stringify(JSON.parse(response), null, 2);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
this.logger.warn("Failed to parse JSON response", error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
138
|
+
sendHTTPEvent(httpRequestInfo) {
|
|
139
|
+
if (this.client?.debugger) {
|
|
140
|
+
this.client.debugger.send("NETWORK_HTTP_REQUEST", httpRequestInfo);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.HTTPPlugin = HTTPPlugin;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./http.plugin"), exports);
|
|
18
|
+
// export * from './websocket.plugin';
|
|
19
|
+
__exportStar(require("./logging.plugin"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IPlugin, TeardownClient } from "../teardown.client";
|
|
2
|
+
export declare class LoggingPlugin implements IPlugin {
|
|
3
|
+
private client;
|
|
4
|
+
private originalConsoleMethods;
|
|
5
|
+
private createConsoleProxy;
|
|
6
|
+
constructor();
|
|
7
|
+
install(client: TeardownClient<any>): void;
|
|
8
|
+
uninstall(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LoggingPlugin = void 0;
|
|
4
|
+
const methods = ["log", "warn", "error", "debug", "info"];
|
|
5
|
+
class LoggingPlugin {
|
|
6
|
+
client = null;
|
|
7
|
+
originalConsoleMethods = {};
|
|
8
|
+
createConsoleProxy(method) {
|
|
9
|
+
const original = console[method];
|
|
10
|
+
return new Proxy(original, {
|
|
11
|
+
apply: (target, thisArg, args) => {
|
|
12
|
+
target.apply(thisArg, args);
|
|
13
|
+
this.client?.debugger?.send("CONSOLE_LOG", {
|
|
14
|
+
type: method,
|
|
15
|
+
args,
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
constructor() {
|
|
21
|
+
methods.forEach((method) => {
|
|
22
|
+
this.originalConsoleMethods[method] = console[method];
|
|
23
|
+
console[method] = this.createConsoleProxy(method);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
install(client) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
}
|
|
29
|
+
uninstall() {
|
|
30
|
+
methods.forEach((method) => {
|
|
31
|
+
console[method] = this.originalConsoleMethods[method];
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.LoggingPlugin = LoggingPlugin;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IPlugin, TeardownClient } from "../teardown.client";
|
|
2
|
+
export declare class WebSocketPlugin implements IPlugin {
|
|
3
|
+
private logger;
|
|
4
|
+
private client;
|
|
5
|
+
private sockets;
|
|
6
|
+
constructor();
|
|
7
|
+
install(client: TeardownClient<any>): void;
|
|
8
|
+
private setupWebSocketInterceptor;
|
|
9
|
+
private wsConnectCallback;
|
|
10
|
+
private wsSendCallback;
|
|
11
|
+
private wsOnMessageCallback;
|
|
12
|
+
private wsOnCloseCallback;
|
|
13
|
+
private sendOpenEvent;
|
|
14
|
+
private sendMessageEvent;
|
|
15
|
+
private sendCloseEvent;
|
|
16
|
+
disableInterception(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WebSocketPlugin = void 0;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
const WebSocketInterceptor_1 = __importDefault(require("react-native/Libraries/WebSocket/WebSocketInterceptor"));
|
|
9
|
+
const logger_1 = require("@teardown/logger");
|
|
10
|
+
const util_1 = require("@teardown/util");
|
|
11
|
+
class WebSocketPlugin {
|
|
12
|
+
logger = new logger_1.Logger("WebSocketPlugin");
|
|
13
|
+
client = null;
|
|
14
|
+
sockets = new Map();
|
|
15
|
+
constructor() {
|
|
16
|
+
this.setupWebSocketInterceptor();
|
|
17
|
+
}
|
|
18
|
+
install(client) {
|
|
19
|
+
this.client = client;
|
|
20
|
+
}
|
|
21
|
+
setupWebSocketInterceptor() {
|
|
22
|
+
if (WebSocketInterceptor_1.default.isInterceptorEnabled()) {
|
|
23
|
+
this.logger.warn("WebSocketInterceptor is already enabled by another library, disable it or run this first when your app loads");
|
|
24
|
+
this.disableInterception();
|
|
25
|
+
}
|
|
26
|
+
WebSocketInterceptor_1.default.setConnectCallback(this.wsConnectCallback);
|
|
27
|
+
WebSocketInterceptor_1.default.setSendCallback(this.wsSendCallback);
|
|
28
|
+
WebSocketInterceptor_1.default.setOnMessageCallback(this.wsOnMessageCallback);
|
|
29
|
+
WebSocketInterceptor_1.default.setOnCloseCallback(this.wsOnCloseCallback);
|
|
30
|
+
WebSocketInterceptor_1.default.enableInterception();
|
|
31
|
+
this.logger.log("WebSocketInterceptor enabled");
|
|
32
|
+
}
|
|
33
|
+
wsConnectCallback = (url, protocols, options, socketId) => {
|
|
34
|
+
const requestId = util_1.Util.generateUUID();
|
|
35
|
+
const socketInfo = {
|
|
36
|
+
id: requestId,
|
|
37
|
+
url,
|
|
38
|
+
protocols,
|
|
39
|
+
timestamp: performance.now(),
|
|
40
|
+
};
|
|
41
|
+
this.sockets.set(socketId, socketInfo);
|
|
42
|
+
this.sendOpenEvent(socketInfo);
|
|
43
|
+
};
|
|
44
|
+
wsSendCallback = (data, socketId) => {
|
|
45
|
+
const socket = this.sockets.get(socketId);
|
|
46
|
+
if (socket) {
|
|
47
|
+
const messageInfo = {
|
|
48
|
+
id: socket.id,
|
|
49
|
+
data: "", // TODO: Currently getting array buffer length errors here when sending data
|
|
50
|
+
timestamp: performance.now(),
|
|
51
|
+
direction: "sent",
|
|
52
|
+
};
|
|
53
|
+
console.log("messageInfo", messageInfo);
|
|
54
|
+
// this.sendMessageEvent(messageInfo);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
wsOnMessageCallback = (socketId, message) => {
|
|
58
|
+
const socket = this.sockets.get(socketId);
|
|
59
|
+
if (socket) {
|
|
60
|
+
const messageInfo = {
|
|
61
|
+
id: socket.id,
|
|
62
|
+
data: "", // TODO: Currently getting array buffer length errors here when sending data
|
|
63
|
+
timestamp: performance.now(),
|
|
64
|
+
direction: "received",
|
|
65
|
+
};
|
|
66
|
+
this.sendMessageEvent(messageInfo);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
wsOnCloseCallback = (socketId, event) => {
|
|
70
|
+
const socket = this.sockets.get(socketId);
|
|
71
|
+
if (socket) {
|
|
72
|
+
const closeInfo = {
|
|
73
|
+
id: socket.id,
|
|
74
|
+
code: event.code,
|
|
75
|
+
reason: event.reason,
|
|
76
|
+
timestamp: performance.now(),
|
|
77
|
+
};
|
|
78
|
+
this.sendCloseEvent(closeInfo);
|
|
79
|
+
this.sockets.delete(socketId);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
sendOpenEvent(info) {
|
|
83
|
+
if (this.client && this.client.debugger) {
|
|
84
|
+
this.client.debugger.send("NETWORK_WEBSOCKET_OPEN", info);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
sendMessageEvent(info) {
|
|
88
|
+
if (this.client && this.client.debugger) {
|
|
89
|
+
this.client.debugger.send("NETWORK_WEBSOCKET_MESSAGE", info);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
sendCloseEvent(info) {
|
|
93
|
+
if (this.client && this.client.debugger) {
|
|
94
|
+
this.client.debugger.send("NETWORK_WEBSOCKET_CLOSE", info);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
disableInterception() {
|
|
98
|
+
WebSocketInterceptor_1.default.disableInterception();
|
|
99
|
+
this.sockets.clear();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.WebSocketPlugin = WebSocketPlugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './teardown.service';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./teardown.service"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PluginTuple, TeardownClient } from "../teardown.client";
|
|
2
|
+
export type TeardownServiceContextType<T extends readonly PluginTuple[]> = {
|
|
3
|
+
client: TeardownClient<T>;
|
|
4
|
+
};
|
|
5
|
+
export declare const TeardownService: {
|
|
6
|
+
Context: import("react").Context<TeardownServiceContextType<any> | null>;
|
|
7
|
+
Provider: import("react").Provider<TeardownServiceContextType<any> | null>;
|
|
8
|
+
useState<T extends readonly PluginTuple[]>(): TeardownServiceContextType<T>;
|
|
9
|
+
useProvidedState<T extends readonly PluginTuple[]>(client: TeardownClient<T>): TeardownServiceContextType<T>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TeardownService = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const Context = (0, react_1.createContext)(null);
|
|
6
|
+
exports.TeardownService = {
|
|
7
|
+
Context,
|
|
8
|
+
Provider: Context.Provider,
|
|
9
|
+
useState() {
|
|
10
|
+
const state = (0, react_1.useContext)(Context);
|
|
11
|
+
if (state == null) {
|
|
12
|
+
throw new Error("TeardownService not found");
|
|
13
|
+
}
|
|
14
|
+
return state;
|
|
15
|
+
},
|
|
16
|
+
useProvidedState(client) {
|
|
17
|
+
return {
|
|
18
|
+
client
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Logger } from "@teardown/logger";
|
|
2
|
+
import { Debugger, type DebuggerOptions } from "./debugger";
|
|
3
|
+
export interface IPlugin {
|
|
4
|
+
install?(client: TeardownClient<any>): void;
|
|
5
|
+
uninstall?(): void;
|
|
6
|
+
}
|
|
7
|
+
export type DefaultPluginOptions<T> = {
|
|
8
|
+
debug?: boolean;
|
|
9
|
+
} & T;
|
|
10
|
+
export type PluginOptions<T> = DefaultPluginOptions<{
|
|
11
|
+
key: string;
|
|
12
|
+
}> & T;
|
|
13
|
+
export declare abstract class Plugin<T = any> {
|
|
14
|
+
protected logger: Logger;
|
|
15
|
+
protected constructor(options: PluginOptions<T>);
|
|
16
|
+
install?(client: TeardownClient<any>): void;
|
|
17
|
+
uninstall?(): void;
|
|
18
|
+
}
|
|
19
|
+
export type PluginTuple = readonly [string, IPlugin];
|
|
20
|
+
type InferPluginFromTuple<T extends PluginTuple> = {
|
|
21
|
+
[K in T[0]]: Omit<T[1], "install" | "uninstall">;
|
|
22
|
+
};
|
|
23
|
+
type InferPluginsFromArray<T extends readonly PluginTuple[]> = UnionToIntersection<InferPluginFromTuple<T[number]>>;
|
|
24
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
25
|
+
export type TeardownClientOptions<T extends readonly PluginTuple[]> = {
|
|
26
|
+
plugins?: T;
|
|
27
|
+
debuggerEnabled?: boolean;
|
|
28
|
+
loggingEnabled?: boolean;
|
|
29
|
+
} & DebuggerOptions;
|
|
30
|
+
export declare class TeardownClient<T extends readonly PluginTuple[]> {
|
|
31
|
+
readonly options?: TeardownClientOptions<T> | undefined;
|
|
32
|
+
logger: Logger;
|
|
33
|
+
debugger: Debugger | null;
|
|
34
|
+
private readonly plugins;
|
|
35
|
+
api: InferPluginsFromArray<T>;
|
|
36
|
+
constructor(options?: TeardownClientOptions<T> | undefined);
|
|
37
|
+
private installPlugin;
|
|
38
|
+
private uninstallPlugin;
|
|
39
|
+
private uninstallAllPlugins;
|
|
40
|
+
private reinstallPlugins;
|
|
41
|
+
shutdown(): void;
|
|
42
|
+
}
|
|
43
|
+
export declare const createTeardownClient: <Plugins extends readonly PluginTuple[]>(plugins: Plugins) => TeardownClient<Plugins>;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTeardownClient = exports.TeardownClient = exports.Plugin = void 0;
|
|
4
|
+
const logger_1 = require("@teardown/logger");
|
|
5
|
+
const debugger_1 = require("./debugger");
|
|
6
|
+
class Plugin {
|
|
7
|
+
logger;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.logger = new logger_1.Logger(options.key, options.debug ?? false);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.Plugin = Plugin;
|
|
13
|
+
class TeardownClient {
|
|
14
|
+
options;
|
|
15
|
+
logger;
|
|
16
|
+
debugger;
|
|
17
|
+
plugins = new Map();
|
|
18
|
+
api = {};
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.logger = new logger_1.Logger("TeardownClient", options?.loggingEnabled ?? false);
|
|
22
|
+
const debuggerEnabled = options?.debuggerEnabled ?? __DEV__;
|
|
23
|
+
this.debugger = debuggerEnabled ? new debugger_1.Debugger(options) : null;
|
|
24
|
+
options?.plugins?.forEach(([key, plugin]) => {
|
|
25
|
+
this.plugins.set(key, plugin);
|
|
26
|
+
});
|
|
27
|
+
this.installPlugin();
|
|
28
|
+
}
|
|
29
|
+
installPlugin() {
|
|
30
|
+
this.logger.log("Installing plugins");
|
|
31
|
+
this.plugins.forEach((plugin, key) => {
|
|
32
|
+
plugin.install?.(this);
|
|
33
|
+
this.api[key] = plugin;
|
|
34
|
+
});
|
|
35
|
+
this.logger.log("Plugins installed");
|
|
36
|
+
}
|
|
37
|
+
uninstallPlugin(key) {
|
|
38
|
+
const plugin = this.plugins.get(key);
|
|
39
|
+
if (plugin) {
|
|
40
|
+
plugin.uninstall?.();
|
|
41
|
+
this.plugins.delete(key);
|
|
42
|
+
delete this.api[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
uninstallAllPlugins() {
|
|
46
|
+
this.plugins.forEach((_, key) => this.uninstallPlugin(key));
|
|
47
|
+
}
|
|
48
|
+
reinstallPlugins() {
|
|
49
|
+
this.uninstallAllPlugins();
|
|
50
|
+
this.installPlugin();
|
|
51
|
+
}
|
|
52
|
+
shutdown() {
|
|
53
|
+
this.uninstallAllPlugins();
|
|
54
|
+
this.debugger?.shutdown();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.TeardownClient = TeardownClient;
|
|
58
|
+
const createTeardownClient = (plugins) => {
|
|
59
|
+
return new TeardownClient({
|
|
60
|
+
loggingEnabled: true,
|
|
61
|
+
debuggerEnabled: true,
|
|
62
|
+
plugins,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
exports.createTeardownClient = createTeardownClient;
|
package/package.json
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
2
|
+
"name": "@teardown/react-native",
|
|
3
|
+
"version": "1.1.0-beta-05",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"dev": "tsc --declaration --watch"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"README.md",
|
|
14
|
+
"dist/**/*"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@teardown/logger": "^1.1.0-beta-04",
|
|
18
|
+
"@teardown/util": "^1.1.0-beta-04",
|
|
19
|
+
"@teardown/websocket": "^1.1.0-beta-04"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/react": "^18.3.1",
|
|
23
|
+
"@types/react-native": "^0.73.0",
|
|
24
|
+
"metro-config": "^0.81.0",
|
|
25
|
+
"react": "^18.3.1",
|
|
26
|
+
"react-native": "^0.75.4",
|
|
27
|
+
"react-native-device-info": "^14.0.0",
|
|
28
|
+
"react-native-gesture-handler": "^2.20.0",
|
|
29
|
+
"typescript": "^5.6.3"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": "^18",
|
|
33
|
+
"react-native": "^0.75",
|
|
34
|
+
"react-native-device-info": "^14",
|
|
35
|
+
"react-native-gesture-handler": "^2"
|
|
36
|
+
}
|
|
27
37
|
}
|