peachsim 0.1.527

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 (324) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +640 -0
  3. package/cli/app-config.ts +82 -0
  4. package/cli/app-fonts.ts +388 -0
  5. package/cli/app-project.ts +59 -0
  6. package/cli/app-splash.ts +171 -0
  7. package/cli/app-state-reset.ts +26 -0
  8. package/cli/auth.ts +184 -0
  9. package/cli/bin.ts +59 -0
  10. package/cli/bridge-diagnostics.ts +226 -0
  11. package/cli/bridge-flow-runner.ts +2806 -0
  12. package/cli/browser-backend.ts +44 -0
  13. package/cli/browser-evals.ts +96 -0
  14. package/cli/cli-update.ts +261 -0
  15. package/cli/cloud-client.ts +1530 -0
  16. package/cli/cloud-dispatch.ts +206 -0
  17. package/cli/cloud-session.ts +227 -0
  18. package/cli/command-contract.ts +221 -0
  19. package/cli/command-registry.ts +304 -0
  20. package/cli/commands/agent-wrapper.ts +1048 -0
  21. package/cli/commands/agent.ts +439 -0
  22. package/cli/commands/app-fonts.ts +99 -0
  23. package/cli/commands/assert.ts +542 -0
  24. package/cli/commands/auth.ts +71 -0
  25. package/cli/commands/box/bundle-plane.ts +71 -0
  26. package/cli/commands/box/checkout-plane.ts +256 -0
  27. package/cli/commands/box/plane-share.ts +208 -0
  28. package/cli/commands/box/rnx-command.ts +60 -0
  29. package/cli/commands/box/search-command.ts +157 -0
  30. package/cli/commands/box.ts +925 -0
  31. package/cli/commands/camera.ts +266 -0
  32. package/cli/commands/cleanup.ts +169 -0
  33. package/cli/commands/compat.ts +176 -0
  34. package/cli/commands/config.ts +34 -0
  35. package/cli/commands/control.ts +2154 -0
  36. package/cli/commands/cpu-profile.ts +941 -0
  37. package/cli/commands/daemon-mac-app.ts +165 -0
  38. package/cli/commands/daemon.ts +800 -0
  39. package/cli/commands/debug.ts +751 -0
  40. package/cli/commands/desktop.ts +39 -0
  41. package/cli/commands/detect.ts +201 -0
  42. package/cli/commands/detox.ts +481 -0
  43. package/cli/commands/device.ts +134 -0
  44. package/cli/commands/diagnose.ts +589 -0
  45. package/cli/commands/do-chain.ts +408 -0
  46. package/cli/commands/electron.ts +94 -0
  47. package/cli/commands/film.ts +379 -0
  48. package/cli/commands/flow.ts +1240 -0
  49. package/cli/commands/inspect/actions.ts +516 -0
  50. package/cli/commands/inspect/core.ts +2086 -0
  51. package/cli/commands/inspect/count.ts +17 -0
  52. package/cli/commands/inspect/describe.ts +119 -0
  53. package/cli/commands/inspect/env.ts +25 -0
  54. package/cli/commands/inspect/find.ts +169 -0
  55. package/cli/commands/inspect/get-layout.ts +53 -0
  56. package/cli/commands/inspect/keyboard.ts +54 -0
  57. package/cli/commands/inspect/list.ts +175 -0
  58. package/cli/commands/inspect/memory.ts +215 -0
  59. package/cli/commands/inspect/redaction.ts +39 -0
  60. package/cli/commands/inspect/resolve-target.ts +77 -0
  61. package/cli/commands/inspect/screens.ts +78 -0
  62. package/cli/commands/inspect/settle.ts +32 -0
  63. package/cli/commands/inspect/settling.ts +197 -0
  64. package/cli/commands/inspect/shared.ts +259 -0
  65. package/cli/commands/inspect/sleep.ts +15 -0
  66. package/cli/commands/inspect/tree.ts +23 -0
  67. package/cli/commands/inspect/url.ts +17 -0
  68. package/cli/commands/inspect/wait-event.ts +211 -0
  69. package/cli/commands/inspect/wait-idle.ts +25 -0
  70. package/cli/commands/inspect/wait-ready.ts +87 -0
  71. package/cli/commands/inspect/wait-selector.ts +59 -0
  72. package/cli/commands/inspect/wait.ts +32 -0
  73. package/cli/commands/inspect.ts +4738 -0
  74. package/cli/commands/install-cli.ts +275 -0
  75. package/cli/commands/install-desktop.ts +385 -0
  76. package/cli/commands/login.ts +357 -0
  77. package/cli/commands/logout.ts +24 -0
  78. package/cli/commands/maestro-generate.ts +375 -0
  79. package/cli/commands/maestro.ts +536 -0
  80. package/cli/commands/mode.ts +58 -0
  81. package/cli/commands/no-bridge-hint.ts +80 -0
  82. package/cli/commands/perf.ts +67 -0
  83. package/cli/commands/permissions.ts +203 -0
  84. package/cli/commands/platform.ts +410 -0
  85. package/cli/commands/preview.ts +103 -0
  86. package/cli/commands/profile.ts +106 -0
  87. package/cli/commands/react.ts +353 -0
  88. package/cli/commands/record.ts +1435 -0
  89. package/cli/commands/report-issue.ts +305 -0
  90. package/cli/commands/reset.ts +89 -0
  91. package/cli/commands/runtime.ts +348 -0
  92. package/cli/commands/screenshot-command.ts +106 -0
  93. package/cli/commands/screenshot-layers.ts +144 -0
  94. package/cli/commands/screenshot-mode.ts +38 -0
  95. package/cli/commands/screenshot.ts +492 -0
  96. package/cli/commands/screenshots-capture.ts +608 -0
  97. package/cli/commands/screenshots.ts +127 -0
  98. package/cli/commands/serve.ts +139 -0
  99. package/cli/commands/setup.ts +416 -0
  100. package/cli/commands/shell-boolean-mode.ts +82 -0
  101. package/cli/commands/skills.ts +468 -0
  102. package/cli/commands/slides.ts +357 -0
  103. package/cli/commands/state.ts +94 -0
  104. package/cli/commands/storage.ts +58 -0
  105. package/cli/commands/telemetry.ts +55 -0
  106. package/cli/commands/test.ts +535 -0
  107. package/cli/commands/three-mode.ts +771 -0
  108. package/cli/commands/timeline.ts +121 -0
  109. package/cli/commands/upgrade.ts +167 -0
  110. package/cli/commands/upload.ts +1203 -0
  111. package/cli/commands/version.ts +63 -0
  112. package/cli/commands/welcome.ts +17 -0
  113. package/cli/commands/what-happened.ts +328 -0
  114. package/cli/current-sim.ts +217 -0
  115. package/cli/desktop-companion.ts +315 -0
  116. package/cli/drivers/electron.ts +70 -0
  117. package/cli/drivers/index.ts +20 -0
  118. package/cli/drivers/playwright-provisioning.ts +184 -0
  119. package/cli/drivers/playwright-sim-host.ts +537 -0
  120. package/cli/drivers/playwright.ts +209 -0
  121. package/cli/drivers/registry.ts +65 -0
  122. package/cli/drivers/types.ts +102 -0
  123. package/cli/flow-export.ts +55 -0
  124. package/cli/flow-file.ts +142 -0
  125. package/cli/flow-live-status.ts +126 -0
  126. package/cli/flow-session.ts +140 -0
  127. package/cli/help-core.ts +143 -0
  128. package/cli/help.ts +44 -0
  129. package/cli/hidden-runtime-alias.ts +19 -0
  130. package/cli/hints.ts +214 -0
  131. package/cli/inspect-notice-state.ts +114 -0
  132. package/cli/internal-child.ts +176 -0
  133. package/cli/maestro-js.ts +323 -0
  134. package/cli/main.ts +704 -0
  135. package/cli/open-url.ts +8 -0
  136. package/cli/outbound-endpoints.ts +830 -0
  137. package/cli/parent-pid.ts +204 -0
  138. package/cli/parse-args.ts +189 -0
  139. package/cli/privacy.ts +53 -0
  140. package/cli/prompt.ts +56 -0
  141. package/cli/recording-access.ts +108 -0
  142. package/cli/registry.ts +2 -0
  143. package/cli/resolve-assets.ts +63 -0
  144. package/cli/rnx-in-process.ts +98 -0
  145. package/cli/run-registry.ts +226 -0
  146. package/cli/run-rnx-core.ts +148 -0
  147. package/cli/run-rnx.ts +137 -0
  148. package/cli/runtime-notes.ts +66 -0
  149. package/cli/runtime-summary.ts +25 -0
  150. package/cli/secure-file.ts +31 -0
  151. package/cli/self-invocation.ts +58 -0
  152. package/cli/send-to-box.ts +109 -0
  153. package/cli/setup-repository.ts +191 -0
  154. package/cli/shell-init.ts +98 -0
  155. package/cli/standalone.ts +4 -0
  156. package/cli/telemetry.ts +84 -0
  157. package/cli/ui.ts +68 -0
  158. package/cli/ws-bridge.ts +1020 -0
  159. package/detox/attempt-events.cjs +23 -0
  160. package/detox/colors.ts +54 -0
  161. package/detox/config-loader.ts +135 -0
  162. package/detox/element-types.ts +48 -0
  163. package/detox/expectations.ts +534 -0
  164. package/detox/gestures.ts +501 -0
  165. package/detox/index.ts +2694 -0
  166. package/detox/jest-preset.cjs +29 -0
  167. package/detox/jest-setup-after-env.cjs +22 -0
  168. package/detox/matchers.ts +30 -0
  169. package/detox/motion-change.cjs +109 -0
  170. package/detox/motion-change.d.cts +35 -0
  171. package/detox/navigation-lifecycle.ts +290 -0
  172. package/detox/navigation.ts +43 -0
  173. package/detox/proof-frame.cjs +114 -0
  174. package/detox/record-block-execution.cjs +78 -0
  175. package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
  176. package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
  177. package/detox/screenshots/color-test-rest-norngh.png +0 -0
  178. package/detox/screenshots/theme-blue-toggle.png +0 -0
  179. package/detox/screenshots/theme-blue.png +0 -0
  180. package/detox/screenshots/theme-red-toggle.png +0 -0
  181. package/detox/screenshots/theme-red.png +0 -0
  182. package/dist-lib/agent-daemon-client.cjs +502 -0
  183. package/dist-lib/agent-events.cjs +48 -0
  184. package/dist-lib/agent-identity.cjs +53 -0
  185. package/dist-lib/agent-sessions.cjs +759 -0
  186. package/dist-lib/attached-projects.cjs +526 -0
  187. package/dist-lib/auth/shared-session.cjs +208 -0
  188. package/dist-lib/backend-origin.cjs +88 -0
  189. package/dist-lib/beta.cjs +41 -0
  190. package/dist-lib/beta.mjs +13 -0
  191. package/dist-lib/bridge-constants.cjs +161 -0
  192. package/dist-lib/bridge-contract-input.cjs +451 -0
  193. package/dist-lib/bridge-contract-input.mjs +414 -0
  194. package/dist-lib/bridge-contract.cjs +130 -0
  195. package/dist-lib/bridge-contract.mjs +94 -0
  196. package/dist-lib/capture-contract.cjs +220 -0
  197. package/dist-lib/capture-contract.mjs +190 -0
  198. package/dist-lib/cli-constants.cjs +32 -0
  199. package/dist-lib/cloud-contract.cjs +194 -0
  200. package/dist-lib/cloud-contract.mjs +145 -0
  201. package/dist-lib/cloud.cjs +670 -0
  202. package/dist-lib/cloud.mjs +639 -0
  203. package/dist-lib/config.cjs +96 -0
  204. package/dist-lib/detox/index.cjs +3789 -0
  205. package/dist-lib/detox/jest-preset.cjs +29 -0
  206. package/dist-lib/dev-bundle-resolution.cjs +290 -0
  207. package/dist-lib/home-paths.cjs +638 -0
  208. package/dist-lib/host/bridge-host.cjs +10903 -0
  209. package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
  210. package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
  211. package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
  212. package/dist-lib/host/replacement-module-handler.cjs +469 -0
  213. package/dist-lib/host/websocket-proxy.cjs +298 -0
  214. package/dist-lib/index.cjs +4268 -0
  215. package/dist-lib/jump-to-source-babel.cjs +93 -0
  216. package/dist-lib/jump-to-source-native.cjs +112 -0
  217. package/dist-lib/menu.cjs +646 -0
  218. package/dist-lib/menu.mjs +604 -0
  219. package/dist-lib/metro-fingerprint-registry.cjs +186 -0
  220. package/dist-lib/metro-fingerprint-registry.mjs +156 -0
  221. package/dist-lib/metro-production-bundle.cjs +329 -0
  222. package/dist-lib/metro-production-bundle.mjs +295 -0
  223. package/dist-lib/metro.cjs +904 -0
  224. package/dist-lib/profiles.cjs +246 -0
  225. package/dist-lib/public-brand.cjs +39 -0
  226. package/dist-lib/react-native-host-modules.cjs +51 -0
  227. package/dist-lib/react-native-host-modules.mjs +25 -0
  228. package/dist-lib/render-mode.cjs +54 -0
  229. package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
  230. package/dist-lib/sdk.cjs +2433 -0
  231. package/dist-lib/sdk.mjs +2336 -0
  232. package/dist-lib/skills.cjs +39132 -0
  233. package/dist-lib/swift-submit.cjs +92 -0
  234. package/dist-lib/swift-submit.mjs +65 -0
  235. package/dist-lib/swift.cjs +1646 -0
  236. package/dist-lib/vite.cjs +1591 -0
  237. package/package.json +290 -0
  238. package/scripts/dev-server-scanner.ts +1291 -0
  239. package/scripts/optional-demo-registry.ts +113 -0
  240. package/skills/contrast/SKILL.md +165 -0
  241. package/skills/rnx-debug/SKILL.md +433 -0
  242. package/skills/rnx-perf/SKILL.md +399 -0
  243. package/skills/rnx-setup/SKILL.md +172 -0
  244. package/skills/rnx-test/SKILL.md +321 -0
  245. package/skills/rnx-visual/SKILL.md +126 -0
  246. package/src/agent-daemon-client.ts +410 -0
  247. package/src/agent-events.ts +71 -0
  248. package/src/agent-identity.ts +23 -0
  249. package/src/agent-prompt.ts +71 -0
  250. package/src/agent-sessions.ts +580 -0
  251. package/src/app-url.ts +39 -0
  252. package/src/attached-projects.ts +539 -0
  253. package/src/auth/shared-session.ts +235 -0
  254. package/src/backend-origin.ts +70 -0
  255. package/src/beta.ts +19 -0
  256. package/src/bridge-constants.ts +175 -0
  257. package/src/bridge-contract-input.ts +502 -0
  258. package/src/bridge-contract.ts +558 -0
  259. package/src/browser-cache.ts +16 -0
  260. package/src/capture-contract.ts +587 -0
  261. package/src/cli-constants.ts +1 -0
  262. package/src/cli-version.ts +40 -0
  263. package/src/cloud-contract.ts +274 -0
  264. package/src/cloud.ts +762 -0
  265. package/src/codex-client.ts +234 -0
  266. package/src/config.ts +132 -0
  267. package/src/connect.ts +101 -0
  268. package/src/dev-bundle-resolution.ts +346 -0
  269. package/src/dev-server-open.ts +198 -0
  270. package/src/disk-cleanup.ts +540 -0
  271. package/src/flow-timeout-scale.ts +15 -0
  272. package/src/home-paths.ts +806 -0
  273. package/src/host/agent-host.ts +666 -0
  274. package/src/host/bridge-host.ts +2788 -0
  275. package/src/host/fetch-proxy-handler.ts +449 -0
  276. package/src/host/fetch-proxy-overrides.ts +51 -0
  277. package/src/host/open-url.ts +89 -0
  278. package/src/host/plane-host.ts +203 -0
  279. package/src/host/replacement-module-handler.ts +158 -0
  280. package/src/host/websocket-proxy.ts +315 -0
  281. package/src/index.ts +71 -0
  282. package/src/jump-to-source-babel.ts +135 -0
  283. package/src/jump-to-source-native.ts +102 -0
  284. package/src/menu.ts +777 -0
  285. package/src/metro-fingerprint-registry.ts +302 -0
  286. package/src/metro-plugin.ts +341 -0
  287. package/src/metro-production-bundle.ts +471 -0
  288. package/src/native-dev-bundle-url.ts +118 -0
  289. package/src/native-seam-manifest.ts +341 -0
  290. package/src/playwright-host-log.ts +16 -0
  291. package/src/plist.ts +27 -0
  292. package/src/poll-until.ts +123 -0
  293. package/src/profiles.ts +179 -0
  294. package/src/public-brand.ts +9 -0
  295. package/src/react-native-host-modules.ts +26 -0
  296. package/src/render-mode.ts +27 -0
  297. package/src/rolldown-plugin-swift.ts +240 -0
  298. package/src/runtime-assets.ts +233 -0
  299. package/src/runtime-delivery.ts +54 -0
  300. package/src/screenshots/compose.ts +422 -0
  301. package/src/screenshots/frame-compose.ts +514 -0
  302. package/src/screenshots/orchestrate.ts +256 -0
  303. package/src/screenshots/org-deck.ts +91 -0
  304. package/src/screenshots/registry.ts +58 -0
  305. package/src/screenshots/schema.ts +364 -0
  306. package/src/sdk.ts +15 -0
  307. package/src/settings-bundle.ts +418 -0
  308. package/src/shell-bridge-identity.ts +15 -0
  309. package/src/sim-client.ts +697 -0
  310. package/src/skills/builtin/a11y-review.ts +132 -0
  311. package/src/skills/builtin/compat-check.ts +71 -0
  312. package/src/skills/builtin/maestro-test.ts +121 -0
  313. package/src/skills/builtin/perf-profile.ts +90 -0
  314. package/src/skills/builtin/screenshot-all.ts +52 -0
  315. package/src/skills/builtin/visual-diff.ts +100 -0
  316. package/src/skills/registry.ts +107 -0
  317. package/src/skills/types.ts +41 -0
  318. package/src/swift-submit.ts +185 -0
  319. package/src/swift.ts +7 -0
  320. package/src/team-machine-prompt.ts +73 -0
  321. package/src/vite-plugin-one.ts +264 -0
  322. package/src/vite-plugin-swift.ts +620 -0
  323. package/src/vite-plugin.ts +1946 -0
  324. package/src/worklets-babel.ts +250 -0
package/src/index.ts ADDED
@@ -0,0 +1,71 @@
1
+ // sootsim public package — SDK client, CLI + framework integrations.
2
+ //
3
+ // the bridge client and plugins live here. the canvas rendering engine lives
4
+ // in the private `sootsim-engine` workspace package.
5
+
6
+ export { connect, type ConnectOptions } from './connect'
7
+ export {
8
+ SimClient,
9
+ SimClientError,
10
+ SimConnectError,
11
+ SimKeyboardError,
12
+ SimPerformError,
13
+ SimReadyTimeoutError,
14
+ SimResetError,
15
+ SimTapError,
16
+ type SimClientOptions,
17
+ type SimFindOptions,
18
+ type SimPerformStep,
19
+ type SimScreenshot,
20
+ type SimTapTarget,
21
+ } from './sim-client'
22
+ export type {
23
+ PerformOptions,
24
+ PerformResult,
25
+ PerformStep,
26
+ ResetOptions,
27
+ ResetResult,
28
+ SimStateOptions,
29
+ SimStateResult,
30
+ SimSemanticGeometry,
31
+ SimSemanticNode,
32
+ SimSemanticQuery,
33
+ SimSemanticQueryResult,
34
+ SimSemanticResolveResult,
35
+ SimSemanticResolveSelector,
36
+ SimSemanticSelector,
37
+ } from './bridge-contract'
38
+ export {
39
+ isRnxCaptureRegionAtlas,
40
+ isRnxScreenCapture,
41
+ rnxCaptureRasterRegions,
42
+ rnxRasterFrames,
43
+ RNX_SCREEN_CAPTURE_VERSION,
44
+ selectRnxRasterNodeIds,
45
+ type RnxCaptureAccessibility,
46
+ type RnxCaptureAccessibilityState,
47
+ type RnxCaptureAccessibilityValue,
48
+ type RnxCaptureAtlasRegion,
49
+ type RnxCaptureInteractionState,
50
+ type RnxCaptureNode,
51
+ type RnxCaptureRect,
52
+ type RnxCaptureRegionAtlas,
53
+ type RnxCaptureRegionRequest,
54
+ type RnxCaptureSource,
55
+ type RnxCaptureStyleTokenBinding,
56
+ type RnxCaptureTextLine,
57
+ type RnxCaptureTextSegment,
58
+ type RnxCaptureTree,
59
+ type RnxCaptureVisualEvidence,
60
+ type RnxRasterRegionTree,
61
+ type RnxScreenCapture,
62
+ } from './capture-contract'
63
+
64
+ export { rnxPlugin } from './vite-plugin-one'
65
+ export { default as metroPlugin } from './metro-plugin'
66
+ export { default as jumpToSourceBabelPlugin } from './jump-to-source-babel'
67
+ export {
68
+ DEFAULT_SOOTSIM_BRIDGE_PORT,
69
+ DEFAULT_SOOTSIM_BRIDGE_URL,
70
+ } from './bridge-constants'
71
+ export { DEFAULT_SOOTSIM_SHELL_URL } from './cli-constants'
@@ -0,0 +1,135 @@
1
+ export interface SootsimJumpToSourceBabelOptions {
2
+ enabled?: boolean
3
+ attrName?: string
4
+ include?: readonly SourcePathMatcher[]
5
+ exclude?: readonly SourcePathMatcher[]
6
+ }
7
+
8
+ type SourcePathMatcher = string | RegExp
9
+
10
+ interface BabelApi {
11
+ types: {
12
+ jsxAttribute(name: unknown, value: unknown): JSXAttributeNode
13
+ jsxIdentifier(name: string): unknown
14
+ stringLiteral(value: string): unknown
15
+ }
16
+ }
17
+
18
+ interface BabelPluginState {
19
+ file?: {
20
+ opts?: {
21
+ filename?: string
22
+ }
23
+ }
24
+ }
25
+
26
+ interface SourceLocation {
27
+ line: number
28
+ column: number
29
+ }
30
+
31
+ interface JSXNameNode {
32
+ type: string
33
+ name?: string
34
+ object?: JSXNameNode
35
+ property?: JSXNameNode
36
+ }
37
+
38
+ interface JSXAttributeNode {
39
+ type: string
40
+ name?: JSXNameNode
41
+ }
42
+
43
+ interface JSXOpeningElementNode {
44
+ name?: JSXNameNode
45
+ attributes?: JSXAttributeNode[]
46
+ loc?: {
47
+ start?: SourceLocation
48
+ }
49
+ }
50
+
51
+ interface JSXOpeningElementPath {
52
+ node: JSXOpeningElementNode
53
+ }
54
+
55
+ function normalizeSourcePath(path: string): string {
56
+ const queryStart = path.indexOf('?')
57
+ const clean = queryStart >= 0 ? path.slice(0, queryStart) : path
58
+ return clean.replace(/\\/g, '/')
59
+ }
60
+
61
+ function matchesPath(path: string, matcher: SourcePathMatcher): boolean {
62
+ return typeof matcher === 'string' ? path.includes(matcher) : matcher.test(path)
63
+ }
64
+
65
+ function shouldStampFile(
66
+ filename: string,
67
+ options: SootsimJumpToSourceBabelOptions,
68
+ ): boolean {
69
+ const normalized = normalizeSourcePath(filename)
70
+ if (normalized.includes('/node_modules/')) return false
71
+ if (normalized.includes('/dist/') || normalized.includes('/build/')) return false
72
+ if (options.exclude?.some((matcher) => matchesPath(normalized, matcher))) return false
73
+ if (options.include?.length) {
74
+ return options.include.some((matcher) => matchesPath(normalized, matcher))
75
+ }
76
+ return true
77
+ }
78
+
79
+ function getJSXName(node: JSXNameNode | undefined): string | null {
80
+ if (!node) return null
81
+ if (node.type === 'JSXIdentifier' && node.name) return node.name
82
+ if (node.type === 'JSXMemberExpression') {
83
+ const object = getJSXName(node.object)
84
+ const property = getJSXName(node.property)
85
+ return object && property ? `${object}.${property}` : null
86
+ }
87
+ return null
88
+ }
89
+
90
+ function hasAttribute(node: JSXOpeningElementNode, attrName: string): boolean {
91
+ return (
92
+ node.attributes?.some((attr) => {
93
+ if (attr.type !== 'JSXAttribute') return false
94
+ return attr.name?.type === 'JSXIdentifier' && attr.name.name === attrName
95
+ }) ?? false
96
+ )
97
+ }
98
+
99
+ export default function sootsimJumpToSourceBabelPlugin(
100
+ api: BabelApi,
101
+ options: SootsimJumpToSourceBabelOptions = {},
102
+ ) {
103
+ const attrName = options.attrName || 'srcloc'
104
+
105
+ return {
106
+ name: 'sootsim-jump-to-source',
107
+ visitor: {
108
+ JSXOpeningElement(path: JSXOpeningElementPath, state: BabelPluginState) {
109
+ if (options.enabled === false) return
110
+
111
+ const filename = state.file?.opts?.filename
112
+ if (!filename || !shouldStampFile(filename, options)) return
113
+
114
+ const node = path.node
115
+ const tagName = getJSXName(node.name)
116
+ if (!tagName || tagName === 'Fragment' || tagName.endsWith('.Fragment')) return
117
+ if (hasAttribute(node, attrName)) return
118
+
119
+ const loc = node.loc?.start
120
+ if (!loc) return
121
+
122
+ const source = `${normalizeSourcePath(filename)}:${loc.line}:${loc.column + 1}`
123
+ node.attributes ??= []
124
+ node.attributes.push(
125
+ api.types.jsxAttribute(
126
+ api.types.jsxIdentifier(attrName),
127
+ api.types.stringLiteral(source),
128
+ ),
129
+ )
130
+ },
131
+ },
132
+ }
133
+ }
134
+
135
+ export { sootsimJumpToSourceBabelPlugin }
@@ -0,0 +1,102 @@
1
+ import MagicString from 'magic-string'
2
+ import { parseSync, Visitor } from 'oxc-parser'
3
+ import type { SootsimJumpToSourceBabelOptions } from './jump-to-source-babel.ts'
4
+
5
+ export type JumpToSourceNativeOptions = SootsimJumpToSourceBabelOptions
6
+
7
+ function matchesPath(path: string, matcher: string | RegExp): boolean {
8
+ return typeof matcher === 'string' ? path.includes(matcher) : matcher.test(path)
9
+ }
10
+
11
+ // stamp the same one-based source locations as the babel plugin before native
12
+ // jsx compilation, without running babel in the native bundle pipeline.
13
+ export function stampJsxSourceLocations(
14
+ code: string,
15
+ filename: string,
16
+ options: JumpToSourceNativeOptions = {},
17
+ ): string | null {
18
+ if (options.enabled === false || !filename || !code.includes('<')) return null
19
+ const source = filename.split('?')[0].replace(/\\/g, '/')
20
+ if (
21
+ source.includes('/node_modules/') ||
22
+ source.includes('/dist/') ||
23
+ source.includes('/build/')
24
+ )
25
+ return null
26
+ if (options.exclude?.some((matcher) => matchesPath(source, matcher))) return null
27
+ if (
28
+ options.include?.length &&
29
+ !options.include.some((matcher) => matchesPath(source, matcher))
30
+ )
31
+ return null
32
+
33
+ const { program, errors } = parseSync(source, code, {
34
+ lang: source.endsWith('.tsx') ? 'tsx' : source.endsWith('.ts') ? 'ts' : 'jsx',
35
+ })
36
+ if (errors.length) return null
37
+
38
+ const attrName = options.attrName || 'srcloc'
39
+ const lineStarts = [0]
40
+ for (let i = 0; i < code.length; i++) {
41
+ if (code.charCodeAt(i) === 10) lineStarts.push(i + 1)
42
+ }
43
+ const magic = new MagicString(code)
44
+ let stamped = false
45
+ new Visitor({
46
+ JSXOpeningElement(node) {
47
+ const name = node.name
48
+ if (name.type === 'JSXNamespacedName') return
49
+ if (name.type === 'JSXIdentifier' && name.name === 'Fragment') return
50
+ if (name.type === 'JSXMemberExpression' && name.property.name === 'Fragment') return
51
+ if (
52
+ node.attributes.some(
53
+ (attr) =>
54
+ attr.type === 'JSXAttribute' &&
55
+ attr.name.type === 'JSXIdentifier' &&
56
+ attr.name.name === attrName,
57
+ )
58
+ )
59
+ return
60
+
61
+ // binary search keeps location lookup logarithmic for large source files.
62
+ let lo = 0
63
+ let hi = lineStarts.length - 1
64
+ while (lo < hi) {
65
+ const mid = (lo + hi + 1) >> 1
66
+ if (lineStarts[mid] <= node.start) lo = mid
67
+ else hi = mid - 1
68
+ }
69
+ const location = `${source}:${lo + 1}:${node.start - lineStarts[lo] + 1}`
70
+ // append after spreads, matching babel's precedence. a jsx expression
71
+ // preserves path characters that a quoted jsx attribute would decode.
72
+ magic.appendLeft(
73
+ node.end - (node.selfClosing ? 2 : 1),
74
+ ` ${attrName}={${JSON.stringify(location)}}`,
75
+ )
76
+ stamped = true
77
+ },
78
+ }).visit(program)
79
+ return stamped ? magic.toString() : null
80
+ }
81
+
82
+ // metro's nativeTransformModules accepts module ids; consumers can export an
83
+ // instance of this transform from a module to supply their include filters.
84
+ export function createJumpToSourceNativeTransform(
85
+ options: JumpToSourceNativeOptions = {},
86
+ ) {
87
+ return function jumpToSourceNativeTransform(code: string, ctx: { filename: string }) {
88
+ return stampJsxSourceLocations(code, ctx.filename, options)
89
+ }
90
+ }
91
+
92
+ export function jumpToSourceNativePlugin(options: JumpToSourceNativeOptions = {}) {
93
+ return {
94
+ name: 'sootsim-jump-to-source',
95
+ transform(code: string, id: string) {
96
+ const stamped = stampJsxSourceLocations(code, id, options)
97
+ return stamped == null ? null : { code: stamped, map: null }
98
+ },
99
+ }
100
+ }
101
+
102
+ export default createJumpToSourceNativeTransform()