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
@@ -0,0 +1,250 @@
1
+ import { createHash } from 'node:crypto'
2
+ import fs from 'node:fs'
3
+ import { createRequire } from 'node:module'
4
+ import path from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
6
+ import type { TransformOptions } from '@babel/core'
7
+ import type { TransformResult } from 'vite'
8
+
9
+ const sootsimPluginRequire = createRequire(import.meta.url)
10
+ const sootsimRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
11
+ const workspaceRoot = path.resolve(sootsimRoot, '..', '..')
12
+
13
+ // handle files containing upstream reanimated/worklets worklet directives and
14
+ // inline updaters to auto-workletizable hooks. the babel transform lifts those
15
+ // into functions carrying `__closure`, `__workletHash`, and `__initData`.
16
+ export const REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [
17
+ 'worklet',
18
+ 'useAnimatedGestureHandler',
19
+ 'useAnimatedScrollHandler',
20
+ 'useFrameCallback',
21
+ 'useAnimatedStyle',
22
+ 'useAnimatedProps',
23
+ 'createAnimatedPropAdapter',
24
+ 'useDerivedValue',
25
+ 'useAnimatedReaction',
26
+ 'useWorkletCallback',
27
+ 'withTiming',
28
+ 'withSpring',
29
+ 'withDecay',
30
+ 'withRepeat',
31
+ 'runOnUI',
32
+ 'executeOnUIRuntimeSync',
33
+ ]
34
+
35
+ export const REANIMATED_WORKLETIZATION_REGEX = new RegExp(
36
+ REANIMATED_AUTOWORKLETIZATION_KEYWORDS.join('|'),
37
+ )
38
+ // false-positive packages: they mention the keywords in strings/comments but
39
+ // don't actually use worklets, or transforming them causes circular deps /
40
+ // breaks the build. keep this minimal; the regex above is already
41
+ // content-gated so most of node_modules skips for free.
42
+ const REANIMATED_IGNORED_PATHS_REGEX =
43
+ /node_modules\/(react|react-dom|react-native|react-native-web)\//
44
+ const SOOTSIM_ENGINE_SRC_PATH = '/packages/sootsim-engine/src/'
45
+ const SOOTSIM_ENGINE_TEST_FIXTURE_PATH = '/packages/sootsim-engine/src/test-fixtures/'
46
+ const REANIMATED_IMPORT_REGEX =
47
+ /(?:from\s+['"]react-native-reanimated(?:\/[^'"]*)?['"]|require\(\s*['"]react-native-reanimated(?:\/[^'"]*)?['"]\s*\))/
48
+
49
+ let workletsPluginPath: string | null = null
50
+ let babelCorePromise: Promise<typeof import('@babel/core')> | null = null
51
+
52
+ export function shouldApplyWorkletsPlugin(id: string, code: string): boolean {
53
+ if (!/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/.test(id)) return false
54
+ if (REANIMATED_IGNORED_PATHS_REGEX.test(id)) return false
55
+ // sootsim engine source has local helpers named like upstream reanimated
56
+ // hooks. only transform engine files that actually import upstream
57
+ // react-native-reanimated; otherwise the plugin rewrites callbacks for our
58
+ // own engine hooks and expects a `this.__closure` binding they never provide.
59
+ if (
60
+ id.includes(SOOTSIM_ENGINE_SRC_PATH) &&
61
+ !id.includes(SOOTSIM_ENGINE_TEST_FIXTURE_PATH) &&
62
+ !REANIMATED_IMPORT_REGEX.test(code)
63
+ ) {
64
+ return false
65
+ }
66
+ return REANIMATED_WORKLETIZATION_REGEX.test(code)
67
+ }
68
+
69
+ function getWorkletsPluginPath(): string {
70
+ if (!workletsPluginPath) {
71
+ workletsPluginPath = path.resolve(
72
+ workspaceRoot,
73
+ 'node_modules',
74
+ 'react-native-worklets',
75
+ 'plugin',
76
+ )
77
+ }
78
+ return workletsPluginPath
79
+ }
80
+
81
+ function isTypescriptFile(id: string): boolean {
82
+ return /\.(tsx?|mts|cts)$/.test(id)
83
+ }
84
+
85
+ // the worklets babel pass is the single most expensive plugin hook in the
86
+ // engine and tenant builds (hundreds of files, several seconds each). the
87
+ // output is a pure function of the source text, the file path, the sourcemap
88
+ // flag, and the babel toolchain, so cache it on disk keyed by all four. a
89
+ // normal dev rebuild changes a handful of files and replays the rest.
90
+ const CACHE_SCHEMA = 'v1'
91
+ const CACHE_ROOT = path.resolve(
92
+ workspaceRoot,
93
+ 'node_modules',
94
+ '.cache',
95
+ 'sootsim-worklets',
96
+ )
97
+
98
+ // null once resolved on a tree we cannot write to (a read-only install), which
99
+ // only costs speed: every caller falls through to the babel run it would have
100
+ // made anyway.
101
+ let cacheDir: string | null | undefined
102
+
103
+ function getCacheDir(): string | null {
104
+ if (cacheDir !== undefined) return cacheDir
105
+ const versions = [
106
+ '@babel/core',
107
+ '@babel/preset-typescript',
108
+ 'react-native-worklets',
109
+ ].map((pkg) => {
110
+ const manifest = sootsimPluginRequire(`${pkg}/package.json`) as { version?: string }
111
+ return `${pkg}@${manifest.version ?? '0'}`
112
+ })
113
+ const fingerprint = createHash('sha256')
114
+ .update([CACHE_SCHEMA, ...versions].join('\n'))
115
+ .digest('hex')
116
+ .slice(0, 16)
117
+ const dir = path.join(CACHE_ROOT, fingerprint)
118
+ try {
119
+ fs.mkdirSync(dir, { recursive: true })
120
+ // a toolchain bump starts a new fingerprint, so drop the previous ones
121
+ // instead of letting every upgrade leave its entries behind forever.
122
+ for (const entry of fs.readdirSync(CACHE_ROOT)) {
123
+ if (entry === fingerprint) continue
124
+ fs.rmSync(path.join(CACHE_ROOT, entry), { recursive: true, force: true })
125
+ }
126
+ cacheDir = dir
127
+ } catch {
128
+ cacheDir = null
129
+ }
130
+ return cacheDir
131
+ }
132
+
133
+ function getCacheEntryPath(
134
+ code: string,
135
+ id: string,
136
+ sourceMaps: TransformOptions['sourceMaps'],
137
+ ): string | null {
138
+ const dir = getCacheDir()
139
+ if (!dir) return null
140
+ // the worklets plugin's `isRelease` reads BABEL_ENV and NODE_ENV and emits a
141
+ // different worklet for each (release drops the embedded source and map), so
142
+ // both belong in the key. the same file is built once as a dev tenant bundle
143
+ // and once as a production engine bundle.
144
+ const key = createHash('sha256')
145
+ .update(
146
+ [
147
+ id,
148
+ String(sourceMaps),
149
+ process.env.BABEL_ENV ?? '',
150
+ process.env.NODE_ENV ?? '',
151
+ code,
152
+ ].join('\0'),
153
+ )
154
+ .digest('hex')
155
+ return path.join(dir, key.slice(0, 2), `${key.slice(2)}.json`)
156
+ }
157
+
158
+ function readCachedTransform(
159
+ entryPath: string | null,
160
+ ): Pick<TransformResult, 'code' | 'map'> | null {
161
+ if (!entryPath) return null
162
+ try {
163
+ return JSON.parse(fs.readFileSync(entryPath, 'utf8'))
164
+ } catch {
165
+ return null
166
+ }
167
+ }
168
+
169
+ function writeCachedTransform(
170
+ entryPath: string | null,
171
+ result: Pick<TransformResult, 'code' | 'map'>,
172
+ ): void {
173
+ if (!entryPath) return
174
+ try {
175
+ fs.mkdirSync(path.dirname(entryPath), { recursive: true })
176
+ // write-then-rename so a concurrent build never reads a half-written entry.
177
+ const temp = `${entryPath}.${process.pid}.${Math.random().toString(36).slice(2)}`
178
+ fs.writeFileSync(temp, JSON.stringify(result))
179
+ fs.renameSync(temp, entryPath)
180
+ } catch {}
181
+ }
182
+
183
+ function createWorkletsBabelOptions(
184
+ id: string,
185
+ sourceMaps: TransformOptions['sourceMaps'],
186
+ ): TransformOptions {
187
+ const isTSX = id.endsWith('.tsx')
188
+ const isTS = isTypescriptFile(id)
189
+ return {
190
+ filename: id,
191
+ babelrc: false,
192
+ configFile: false,
193
+ sourceMaps,
194
+ presets: isTS
195
+ ? [
196
+ [
197
+ sootsimPluginRequire.resolve('@babel/preset-typescript'),
198
+ { isTSX, allExtensions: isTSX, allowDeclareFields: true },
199
+ ],
200
+ ]
201
+ : [],
202
+ plugins: [
203
+ [sootsimPluginRequire.resolve('@babel/plugin-syntax-jsx')],
204
+ [getWorkletsPluginPath(), { processNestedWorklets: true }],
205
+ ],
206
+ }
207
+ }
208
+
209
+ export async function transformWorkletsCode(
210
+ code: string,
211
+ id: string,
212
+ sourceMaps: TransformOptions['sourceMaps'] = true,
213
+ ): Promise<Pick<TransformResult, 'code' | 'map'> | null> {
214
+ const entryPath = getCacheEntryPath(code, id, sourceMaps)
215
+ const cached = readCachedTransform(entryPath)
216
+ if (cached) return cached
217
+ if (!babelCorePromise) {
218
+ babelCorePromise = import('@babel/core') as Promise<typeof import('@babel/core')>
219
+ }
220
+ const { transformAsync } = await babelCorePromise
221
+ const result = await transformAsync(code, createWorkletsBabelOptions(id, sourceMaps))
222
+ if (!result?.code) return null
223
+ const transformed = {
224
+ code: result.code,
225
+ map: (result.map ?? null) as TransformResult['map'],
226
+ }
227
+ writeCachedTransform(entryPath, transformed)
228
+ return transformed
229
+ }
230
+
231
+ export function transformWorkletsCodeSync(
232
+ code: string,
233
+ id: string,
234
+ sourceMaps: TransformOptions['sourceMaps'] = false,
235
+ ): Pick<TransformResult, 'code' | 'map'> | null {
236
+ const entryPath = getCacheEntryPath(code, id, sourceMaps)
237
+ const cached = readCachedTransform(entryPath)
238
+ if (cached) return cached
239
+ const { transformSync } = sootsimPluginRequire(
240
+ '@babel/core',
241
+ ) as typeof import('@babel/core')
242
+ const result = transformSync(code, createWorkletsBabelOptions(id, sourceMaps))
243
+ if (!result?.code) return null
244
+ const transformed = {
245
+ code: result.code,
246
+ map: (result.map ?? null) as TransformResult['map'],
247
+ }
248
+ writeCachedTransform(entryPath, transformed)
249
+ return transformed
250
+ }