react-native-grab 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +92 -0
  2. package/dist/cjs/metro/index.js +6 -0
  3. package/dist/cjs/metro/index.js.map +1 -0
  4. package/dist/cjs/metro/withReactNativeGrab.js +180 -0
  5. package/dist/cjs/metro/withReactNativeGrab.js.map +1 -0
  6. package/dist/cjs/react-native/copy-payload.js +340 -0
  7. package/dist/cjs/react-native/copy-payload.js.map +1 -0
  8. package/dist/cjs/react-native/dom-traversal.js +210 -0
  9. package/dist/cjs/react-native/dom-traversal.js.map +1 -0
  10. package/dist/cjs/react-native/fiber.js +142 -0
  11. package/dist/cjs/react-native/fiber.js.map +1 -0
  12. package/dist/cjs/react-native/index.js +452 -0
  13. package/dist/cjs/react-native/index.js.map +1 -0
  14. package/dist/cjs/react-native/pointer-events.js +117 -0
  15. package/dist/cjs/react-native/pointer-events.js.map +1 -0
  16. package/dist/cjs/react-native/selection-trigger.js +19 -0
  17. package/dist/cjs/react-native/selection-trigger.js.map +1 -0
  18. package/dist/cjs/react-native/settings.js +101 -0
  19. package/dist/cjs/react-native/settings.js.map +1 -0
  20. package/dist/cjs/react-native/symbolicate.js +15 -0
  21. package/dist/cjs/react-native/symbolicate.js.map +1 -0
  22. package/dist/cjs/react-native/types.js +7 -0
  23. package/dist/cjs/react-native/types.js.map +1 -0
  24. package/dist/cjs/react-native/z-index.js +47 -0
  25. package/dist/cjs/react-native/z-index.js.map +1 -0
  26. package/dist/esm/metro/index.js +2 -0
  27. package/dist/esm/metro/index.js.map +1 -0
  28. package/dist/esm/metro/withReactNativeGrab.js +177 -0
  29. package/dist/esm/metro/withReactNativeGrab.js.map +1 -0
  30. package/dist/esm/react-native/copy-payload.js +333 -0
  31. package/dist/esm/react-native/copy-payload.js.map +1 -0
  32. package/dist/esm/react-native/dom-traversal.js +201 -0
  33. package/dist/esm/react-native/dom-traversal.js.map +1 -0
  34. package/dist/esm/react-native/fiber.js +133 -0
  35. package/dist/esm/react-native/fiber.js.map +1 -0
  36. package/dist/esm/react-native/index.js +445 -0
  37. package/dist/esm/react-native/index.js.map +1 -0
  38. package/dist/esm/react-native/pointer-events.js +109 -0
  39. package/dist/esm/react-native/pointer-events.js.map +1 -0
  40. package/dist/esm/react-native/selection-trigger.js +14 -0
  41. package/dist/esm/react-native/selection-trigger.js.map +1 -0
  42. package/dist/esm/react-native/settings.js +91 -0
  43. package/dist/esm/react-native/settings.js.map +1 -0
  44. package/dist/esm/react-native/symbolicate.js +8 -0
  45. package/dist/esm/react-native/symbolicate.js.map +1 -0
  46. package/dist/esm/react-native/types.js +6 -0
  47. package/dist/esm/react-native/types.js.map +1 -0
  48. package/dist/esm/react-native/z-index.js +43 -0
  49. package/dist/esm/react-native/z-index.js.map +1 -0
  50. package/dist/types/metro/index.d.ts +2 -0
  51. package/dist/types/metro/index.d.ts.map +1 -0
  52. package/dist/types/metro/withReactNativeGrab.d.ts +2 -0
  53. package/dist/types/metro/withReactNativeGrab.d.ts.map +1 -0
  54. package/dist/types/react-native/copy-payload.d.ts +22 -0
  55. package/dist/types/react-native/copy-payload.d.ts.map +1 -0
  56. package/dist/types/react-native/dom-traversal.d.ts +8 -0
  57. package/dist/types/react-native/dom-traversal.d.ts.map +1 -0
  58. package/dist/types/react-native/fiber.d.ts +22 -0
  59. package/dist/types/react-native/fiber.d.ts.map +1 -0
  60. package/dist/types/react-native/index.d.ts +2 -0
  61. package/dist/types/react-native/index.d.ts.map +1 -0
  62. package/dist/types/react-native/pointer-events.d.ts +13 -0
  63. package/dist/types/react-native/pointer-events.d.ts.map +1 -0
  64. package/dist/types/react-native/selection-trigger.d.ts +3 -0
  65. package/dist/types/react-native/selection-trigger.d.ts.map +1 -0
  66. package/dist/types/react-native/settings.d.ts +8 -0
  67. package/dist/types/react-native/settings.d.ts.map +1 -0
  68. package/dist/types/react-native/symbolicate.d.ts +3 -0
  69. package/dist/types/react-native/symbolicate.d.ts.map +1 -0
  70. package/dist/types/react-native/types.d.ts +53 -0
  71. package/dist/types/react-native/types.d.ts.map +1 -0
  72. package/dist/types/react-native/z-index.d.ts +3 -0
  73. package/dist/types/react-native/z-index.d.ts.map +1 -0
  74. package/package.json +62 -8
@@ -0,0 +1,101 @@
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.updateInspectorSettings = exports.initializeInspectorSettings = exports.subscribeInspectorSettings = exports.getInspectorSettings = void 0;
7
+ const getDevServer_1 = __importDefault(require("react-native/Libraries/Core/Devtools/getDevServer"));
8
+ const INSPECTOR_SETTINGS_ENDPOINT = '/__react-native-grab/settings';
9
+ const DEFAULT_INSPECTOR_SETTINGS = {
10
+ selectionPillVisible: true,
11
+ };
12
+ let settings = { ...DEFAULT_INSPECTOR_SETTINGS };
13
+ let initPromise = null;
14
+ const listeners = new Set();
15
+ const getMetroBaseUrl = () => {
16
+ const devServer = (0, getDevServer_1.default)();
17
+ if (!devServer?.url)
18
+ return null;
19
+ return devServer.url.replace(/\/$/, '');
20
+ };
21
+ const emitChange = () => {
22
+ for (const listener of listeners) {
23
+ listener();
24
+ }
25
+ };
26
+ const mergeSettings = (nextSettings) => {
27
+ if (!nextSettings)
28
+ return;
29
+ const nextSelectionPillVisible = nextSettings.selectionPillVisible;
30
+ if (typeof nextSelectionPillVisible !== 'boolean')
31
+ return;
32
+ if (nextSelectionPillVisible === settings.selectionPillVisible)
33
+ return;
34
+ settings = {
35
+ ...settings,
36
+ selectionPillVisible: nextSelectionPillVisible,
37
+ };
38
+ emitChange();
39
+ };
40
+ const getInspectorSettings = () => settings;
41
+ exports.getInspectorSettings = getInspectorSettings;
42
+ const subscribeInspectorSettings = (listener) => {
43
+ listeners.add(listener);
44
+ return () => {
45
+ listeners.delete(listener);
46
+ };
47
+ };
48
+ exports.subscribeInspectorSettings = subscribeInspectorSettings;
49
+ const initializeInspectorSettings = async () => {
50
+ if (initPromise) {
51
+ await initPromise;
52
+ return settings;
53
+ }
54
+ initPromise = (async () => {
55
+ const baseUrl = getMetroBaseUrl();
56
+ if (!baseUrl)
57
+ return;
58
+ try {
59
+ const response = await fetch(`${baseUrl}${INSPECTOR_SETTINGS_ENDPOINT}`);
60
+ if (!response.ok)
61
+ return;
62
+ const payload = (await response.json());
63
+ mergeSettings(payload?.settings);
64
+ }
65
+ catch {
66
+ // Keep defaults if Metro settings endpoint is unavailable.
67
+ }
68
+ })();
69
+ try {
70
+ await initPromise;
71
+ }
72
+ finally {
73
+ initPromise = null;
74
+ }
75
+ return settings;
76
+ };
77
+ exports.initializeInspectorSettings = initializeInspectorSettings;
78
+ const updateInspectorSettings = async (patch) => {
79
+ const baseUrl = getMetroBaseUrl();
80
+ if (!baseUrl)
81
+ return settings;
82
+ try {
83
+ const response = await fetch(`${baseUrl}${INSPECTOR_SETTINGS_ENDPOINT}`, {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ },
88
+ body: JSON.stringify(patch),
89
+ });
90
+ if (!response.ok)
91
+ return settings;
92
+ const payload = (await response.json());
93
+ mergeSettings(payload?.settings);
94
+ }
95
+ catch {
96
+ // Keep existing state if persistence is unavailable.
97
+ }
98
+ return settings;
99
+ };
100
+ exports.updateInspectorSettings = updateInspectorSettings;
101
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/react-native/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
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.symbolicate = void 0;
7
+ const parseErrorStack_1 = __importDefault(require("react-native/Libraries/Core/Devtools/parseErrorStack"));
8
+ const symbolicateStackTrace_1 = __importDefault(require("react-native/Libraries/Core/Devtools/symbolicateStackTrace"));
9
+ const symbolicate = async (error) => {
10
+ const parsedStack = (0, parseErrorStack_1.default)(error.stack);
11
+ const symbolicatedStack = await (0, symbolicateStackTrace_1.default)(parsedStack);
12
+ return symbolicatedStack;
13
+ };
14
+ exports.symbolicate = symbolicate;
15
+ //# sourceMappingURL=symbolicate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbolicate.js","sourceRoot":"","sources":["../../../src/react-native/symbolicate.ts"],"names":[],"mappings":";;;;;;AAAA,2GAAmF;AACnF,uHAA2H;AAGpH,MAAM,WAAW,GAAG,KAAK,EAAE,KAAY,EAAmC,EAAE;IAClF,MAAM,WAAW,GAAG,IAAA,yBAAe,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,MAAM,IAAA,+BAAqB,EAAC,WAAW,CAAC,CAAC;IACnE,OAAO,iBAAiB,CAAC;AAC1B,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Types for the Touch-to-Find Element Inspector.
4
+ * Uses React Native's public Nodes API (see https://reactnative.dev/docs/nodes).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/react-native/types.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getChildrenInHitTestOrder = void 0;
4
+ const fiber_1 = require("./fiber");
5
+ const toNumber = (value) => {
6
+ if (typeof value === 'number' && Number.isFinite(value)) {
7
+ return value;
8
+ }
9
+ if (typeof value === 'string') {
10
+ const parsed = Number(value);
11
+ if (Number.isFinite(parsed)) {
12
+ return parsed;
13
+ }
14
+ }
15
+ return undefined;
16
+ };
17
+ const getNodeZIndex = (node) => {
18
+ const props = (0, fiber_1.getMemoizedProps)(node);
19
+ const zIndexFromProps = toNumber(props?.zIndex);
20
+ if (zIndexFromProps != null) {
21
+ return zIndexFromProps;
22
+ }
23
+ const style = (0, fiber_1.getNormalizedStyle)(node);
24
+ const zIndexFromStyle = toNumber(style?.zIndex);
25
+ if (zIndexFromStyle != null) {
26
+ return zIndexFromStyle;
27
+ }
28
+ return 0;
29
+ };
30
+ const getChildrenInHitTestOrder = (node) => {
31
+ const children = Array.from(node.children ?? []);
32
+ return children
33
+ .map((child, index) => ({
34
+ child,
35
+ index,
36
+ zIndex: getNodeZIndex(child),
37
+ }))
38
+ .sort((a, b) => {
39
+ if (a.zIndex !== b.zIndex) {
40
+ return a.zIndex - b.zIndex;
41
+ }
42
+ return a.index - b.index;
43
+ })
44
+ .map(({ child }) => child);
45
+ };
46
+ exports.getChildrenInHitTestOrder = getChildrenInHitTestOrder;
47
+ //# sourceMappingURL=z-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"z-index.js","sourceRoot":"","sources":["../../../src/react-native/z-index.ts"],"names":[],"mappings":";;;AAAA,mCAA+D;AAG/D,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAsB,EAAE;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAgB,EAAU,EAAE;IACjD,MAAM,KAAK,GAAG,IAAA,wBAAgB,EAAC,IAAI,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;QAC5B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,KAAK,GAAG,IAAA,0BAAkB,EAAC,IAAI,CAAC,CAAC;IACvC,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;QAC5B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEK,MAAM,yBAAyB,GAAG,CAAC,IAAgB,EAAgB,EAAE;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IACjD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACtB,KAAK;QACL,KAAK;QACL,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC;KAC7B,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC;AAfW,QAAA,yBAAyB,6BAepC"}
@@ -0,0 +1,2 @@
1
+ export { withReactNativeGrab } from './withReactNativeGrab';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/metro/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,177 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { createMetroConfigTransformer } from 'metro-config-transformers';
3
+ const MAX_BODY_BYTES = 1024 * 512;
4
+ const JSON_HEADERS = { 'Content-Type': 'application/json' };
5
+ const SETTINGS_ROUTE = '/__react-native-grab/settings';
6
+ const COPY_ROUTE = '/__react-native-grab/copy';
7
+ const DEFAULT_SETTINGS = Object.freeze({
8
+ selectionPillVisible: false,
9
+ });
10
+ let persistedSettings = { ...DEFAULT_SETTINGS };
11
+ const tryCopy = (command, args, text) => {
12
+ try {
13
+ execFileSync(command, args, { input: text });
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ };
20
+ const copyToHostClipboard = (text) => {
21
+ if (process.platform === 'darwin') {
22
+ return tryCopy('pbcopy', [], text);
23
+ }
24
+ if (process.platform === 'win32') {
25
+ return tryCopy('clip', [], text);
26
+ }
27
+ return (tryCopy('xclip', ['-selection', 'clipboard'], text) ||
28
+ tryCopy('xsel', ['--clipboard', '--input'], text));
29
+ };
30
+ const sendJson = (res, statusCode, payload) => {
31
+ res.writeHead(statusCode, JSON_HEADERS);
32
+ res.end(JSON.stringify(payload));
33
+ };
34
+ const getPathname = (req) => {
35
+ if (typeof req.url !== 'string')
36
+ return '';
37
+ try {
38
+ return new URL(req.url, 'http://localhost').pathname;
39
+ }
40
+ catch {
41
+ return req.url.split('?')[0];
42
+ }
43
+ };
44
+ const parseJsonObject = (value) => {
45
+ if (!value)
46
+ return {};
47
+ const parsed = JSON.parse(value);
48
+ if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
49
+ return null;
50
+ }
51
+ return parsed;
52
+ };
53
+ const readJsonBody = (req, res, onSuccess) => {
54
+ let body = '';
55
+ let byteLength = 0;
56
+ let resolved = false;
57
+ req.on('data', (chunk) => {
58
+ if (resolved)
59
+ return;
60
+ const asString = chunk.toString();
61
+ byteLength += Buffer.byteLength(asString);
62
+ if (byteLength > MAX_BODY_BYTES) {
63
+ resolved = true;
64
+ sendJson(res, 413, { ok: false, error: 'Payload too large' });
65
+ req.destroy();
66
+ return;
67
+ }
68
+ body += asString;
69
+ });
70
+ req.on('end', () => {
71
+ if (resolved)
72
+ return;
73
+ try {
74
+ const payload = parseJsonObject(body);
75
+ if (payload === null) {
76
+ sendJson(res, 400, { ok: false, error: 'Invalid JSON payload shape' });
77
+ return;
78
+ }
79
+ resolved = true;
80
+ onSuccess(payload);
81
+ }
82
+ catch {
83
+ resolved = true;
84
+ sendJson(res, 400, { ok: false, error: 'Invalid JSON' });
85
+ }
86
+ });
87
+ };
88
+ const hasOwn = (payload, key) => {
89
+ return Object.prototype.hasOwnProperty.call(payload, key);
90
+ };
91
+ const validateSettingsPatch = (payload) => {
92
+ const patch = {};
93
+ if (hasOwn(payload, 'selectionPillVisible')) {
94
+ const value = payload.selectionPillVisible;
95
+ if (typeof value !== 'boolean') {
96
+ return {
97
+ ok: false,
98
+ error: 'selectionPillVisible must be a boolean',
99
+ };
100
+ }
101
+ patch.selectionPillVisible = value;
102
+ }
103
+ return { ok: true, patch };
104
+ };
105
+ const handleCopyRequest = (req, res) => {
106
+ if (req.method !== 'POST') {
107
+ sendJson(res, 405, { ok: false, error: 'Method not allowed' });
108
+ return;
109
+ }
110
+ readJsonBody(req, res, (payload) => {
111
+ const text = typeof payload.text === 'string' ? payload.text : '';
112
+ if (!text.trim()) {
113
+ sendJson(res, 400, { ok: false, error: 'Missing text' });
114
+ return;
115
+ }
116
+ const copied = copyToHostClipboard(text);
117
+ if (!copied) {
118
+ sendJson(res, 500, { ok: false, error: 'Clipboard write failed on host' });
119
+ return;
120
+ }
121
+ sendJson(res, 200, { ok: true });
122
+ });
123
+ };
124
+ const handleSettingsRequest = (req, res) => {
125
+ if (req.method === 'GET') {
126
+ sendJson(res, 200, { ok: true, settings: persistedSettings });
127
+ return;
128
+ }
129
+ if (req.method !== 'POST') {
130
+ sendJson(res, 405, { ok: false, error: 'Method not allowed' });
131
+ return;
132
+ }
133
+ readJsonBody(req, res, (payload) => {
134
+ const validation = validateSettingsPatch(payload);
135
+ if (!validation.ok) {
136
+ sendJson(res, 400, { ok: false, error: validation.error });
137
+ return;
138
+ }
139
+ persistedSettings = {
140
+ ...persistedSettings,
141
+ ...validation.patch,
142
+ };
143
+ sendJson(res, 200, { ok: true, settings: persistedSettings });
144
+ });
145
+ };
146
+ const handleReactNativeGrabRequest = (req, res, next) => {
147
+ const pathname = getPathname(req);
148
+ if (pathname === COPY_ROUTE) {
149
+ handleCopyRequest(req, res);
150
+ return;
151
+ }
152
+ if (pathname === SETTINGS_ROUTE) {
153
+ handleSettingsRequest(req, res);
154
+ return;
155
+ }
156
+ next();
157
+ };
158
+ export const withReactNativeGrab = createMetroConfigTransformer((config) => {
159
+ const previousEnhanceMiddleware = config.server?.enhanceMiddleware;
160
+ return {
161
+ ...config,
162
+ server: {
163
+ ...config.server,
164
+ enhanceMiddleware: (middleware, metroServer) => {
165
+ const baseMiddleware = previousEnhanceMiddleware
166
+ ? previousEnhanceMiddleware(middleware, metroServer)
167
+ : middleware;
168
+ return (req, res, next) => {
169
+ handleReactNativeGrabRequest(req, res, () => {
170
+ baseMiddleware(req, res, next);
171
+ });
172
+ };
173
+ },
174
+ },
175
+ };
176
+ });
177
+ //# sourceMappingURL=withReactNativeGrab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withReactNativeGrab.js","sourceRoot":"","sources":["../../../src/metro/withReactNativeGrab.ts"],"names":[],"mappings":"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"}