peachsim 0.1.577 → 0.1.579
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/LICENSE +1 -1
- package/README.md +11 -9
- package/cli/app-catalog.ts +77 -0
- package/cli/app-fonts.ts +4 -20
- package/cli/app-splash.ts +2 -18
- package/cli/bridge-flow-runner.ts +505 -139
- package/cli/cloud-client.ts +1 -4
- package/cli/cloud-session.ts +1 -4
- package/cli/cloud-test-result-files.ts +3 -0
- package/cli/cloud-test-tunnel.ts +2 -5
- package/cli/command-registry.ts +2 -0
- package/cli/commands/agent.ts +149 -23
- package/cli/commands/assert.ts +1 -4
- package/cli/commands/box/peach-command.ts +62 -0
- package/cli/commands/box/plane-share.ts +0 -70
- package/cli/commands/box/rnx-command.ts +1 -60
- package/cli/commands/box/search-command.ts +14 -0
- package/cli/commands/box.ts +2 -2
- package/cli/commands/control.ts +121 -27
- package/cli/commands/cpu-profile.ts +23 -10
- package/cli/commands/daemon.ts +1 -9
- package/cli/commands/detox.ts +26 -18
- package/cli/commands/device.ts +129 -1
- package/cli/commands/film.ts +25 -16
- package/cli/commands/flow.ts +9 -2
- package/cli/commands/inspect/actions.ts +75 -1
- package/cli/commands/inspect/core.ts +81 -2
- package/cli/commands/inspect/describe.ts +2 -6
- package/cli/commands/inspect/env.ts +1 -1
- package/cli/commands/inspect/settling.ts +20 -3
- package/cli/commands/inspect/shared.ts +1 -4
- package/cli/commands/inspect/sleep.ts +1 -1
- package/cli/commands/inspect.ts +16 -49
- package/cli/commands/install-desktop.ts +8 -6
- package/cli/commands/login.ts +3 -5
- package/cli/commands/maestro-generate.ts +1 -4
- package/cli/commands/maestro.ts +38 -21
- package/cli/commands/no-bridge-hint.ts +0 -14
- package/cli/commands/permissions.ts +2 -2
- package/cli/commands/platform.ts +13 -6
- package/cli/commands/screenshot.ts +6 -1
- package/cli/commands/skills.ts +1 -1
- package/cli/commands/test.ts +6 -2
- package/cli/commands/three-mode.ts +162 -19
- package/cli/commands/upload.ts +3 -18
- package/cli/current-sim.ts +0 -1
- package/cli/desktop-companion.ts +40 -8
- package/cli/drivers/playwright-provisioning.ts +1 -4
- package/cli/flow-export.ts +1 -8
- package/cli/flow-session.ts +0 -4
- package/cli/hints.ts +1 -16
- package/cli/inspect-notice-state.ts +0 -4
- package/cli/main.ts +2 -4
- package/cli/outbound-endpoints.ts +1 -24
- package/cli/parse-args.ts +1 -2
- package/cli/rnx-in-process.ts +3 -1
- package/cli/run-rnx-core.ts +4 -2
- package/cli/run-rnx.ts +18 -10
- package/cli/send-to-box.ts +1 -4
- package/cli/telemetry.ts +1 -1
- package/cli/ws-bridge.ts +1 -5
- package/detox/gestures.ts +20 -6
- package/detox/index.ts +379 -123
- package/detox/navigation-lifecycle.ts +22 -13
- package/dist-lib/agent-daemon-client.cjs +21 -15
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +3 -17
- package/dist-lib/agent-sessions.cjs +5 -4
- package/dist-lib/attached-projects.cjs +1 -77
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +11 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +7 -5
- package/dist-lib/bridge-contract-input.mjs +7 -5
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +30 -7
- package/dist-lib/capture-contract.mjs +30 -7
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +17 -11
- package/dist-lib/cloud.mjs +17 -11
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +321 -122
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +427 -212
- package/dist-lib/host/fetch-proxy-handler.cjs +5 -28
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +315 -58
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +67 -31
- package/dist-lib/menu.mjs +64 -28
- package/dist-lib/metro-fingerprint-registry.cjs +8 -4
- package/dist-lib/metro-fingerprint-registry.mjs +6 -4
- package/dist-lib/metro-production-bundle.cjs +2 -2
- package/dist-lib/metro-production-bundle.mjs +2 -2
- package/dist-lib/metro.cjs +8 -4
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +7 -4
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +3 -13
- package/dist-lib/scripts/dev-server-scanner.cjs +5 -17
- package/dist-lib/sdk.cjs +129 -10
- package/dist-lib/sdk.mjs +127 -10
- package/dist-lib/skills.cjs +1635 -1121
- package/dist-lib/swift-compile.cjs +277 -70
- package/dist-lib/swift-compile.mjs +275 -70
- package/dist-lib/swift-package.cjs +17 -5
- package/dist-lib/swift-package.mjs +15 -4
- package/dist-lib/swift-submit.cjs +32 -8
- package/dist-lib/swift-submit.mjs +29 -7
- package/dist-lib/swift.cjs +30912 -577
- package/dist-lib/vite-kotlin.cjs +356 -0
- package/dist-lib/vite-swift.cjs +1743 -0
- package/dist-lib/vite.cjs +208 -1039
- package/kotlin/README.md +18 -0
- package/kotlin/Sources/androidx/annotation/Keep.kt +4 -0
- package/kotlin/Sources/dev/onejs/one/OneNativeSourceDispatch.kt +7 -0
- package/kotlin/Sources/dev/onejs/one/source/OneModule.kt +4 -0
- package/kotlin/Sources/org/json/JSON.kt +244 -0
- package/kotlin/toolchain.json +19 -0
- package/package.json +14 -2
- package/scripts/dev-server-scanner.ts +0 -18
- package/scripts/optional-demo-registry.ts +0 -17
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-setup/SKILL.md +16 -0
- package/src/agent-daemon-client.ts +36 -22
- package/src/agent-identity.ts +0 -15
- package/src/agent-prompt.ts +12 -0
- package/src/attached-projects.ts +0 -72
- package/src/backend-origin.ts +10 -0
- package/src/bridge-contract-input.ts +2 -5
- package/src/bridge-contract.ts +2 -0
- package/src/capture-contract.ts +53 -11
- package/src/cloud.ts +4 -9
- package/src/dev-server-open.ts +0 -99
- package/src/home-paths.ts +2 -3
- package/src/host/agent-host.ts +82 -36
- package/src/host/bridge-host.ts +5 -11
- package/src/host/fetch-proxy-handler.ts +19 -43
- package/src/is-record.ts +4 -0
- package/src/menu.ts +82 -37
- package/src/metro-fingerprint-registry.ts +1 -4
- package/src/metro-production-bundle.ts +1 -1
- package/src/plist.ts +1 -4
- package/src/public-brand.ts +5 -3
- package/src/render-mode.ts +0 -12
- package/src/runtime-assets.ts +9 -2
- package/src/screenshots/compose.ts +7 -1
- package/src/screenshots/frame-compose.ts +21 -10
- package/src/screenshots/schema.ts +1 -4
- package/src/sim-client.ts +2 -4
- package/src/skills/builtin/maestro-test.ts +1 -4
- package/src/sleep.ts +4 -0
- package/src/swift-compile.ts +209 -47
- package/src/swift-icu.ts +140 -0
- package/src/swift-package.ts +26 -2
- package/src/swift-submit.ts +84 -4
- package/src/swift.ts +2 -0
- package/src/vite-plugin-kotlin.ts +376 -0
- package/src/vite-plugin-one.ts +224 -36
- package/src/vite-plugin-swift.ts +382 -96
- package/src/vite-plugin.ts +121 -134
- package/src/vite.d.ts +10 -0
- package/cli/resolve-assets.ts +0 -63
- package/src/rolldown-plugin-swift.ts +0 -244
- package/src/team-machine-prompt.ts +0 -73
package/src/vite-plugin.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
compatStubsForBuildResolver,
|
|
23
23
|
reactNativeDeepStubsForBuildResolver,
|
|
24
24
|
} from '../../peach-compat/src/stub-manifest.ts'
|
|
25
|
+
import { isExpoHostSocketModule } from '../../peach-engine/src/guest-module-overrides.ts'
|
|
25
26
|
import { resolveSootsimBridgePort } from './bridge-constants.ts'
|
|
26
27
|
import {
|
|
27
28
|
SHELL_BRIDGE_IDENTITY_PATH,
|
|
@@ -58,6 +59,10 @@ const compatRoot = path.resolve(sootsimRoot, '..', 'peach-compat')
|
|
|
58
59
|
// renames of either package don't break things.
|
|
59
60
|
const engineRoot = path.resolve(workspaceRoot, 'packages/peach-engine')
|
|
60
61
|
const rnShimPath = path.resolve(engineRoot, 'src/react-native/index.ts')
|
|
62
|
+
const rnAssetRegistryPath = path.resolve(
|
|
63
|
+
workspaceNodeModules,
|
|
64
|
+
'react-native/src/asset-registry.js',
|
|
65
|
+
)
|
|
61
66
|
const reactBridgePath = path.resolve(
|
|
62
67
|
workspaceRoot,
|
|
63
68
|
'packages/contrast-kit/src/react-bridge.ts',
|
|
@@ -81,6 +86,14 @@ const compatStubsDir = path.resolve(compatRoot, 'src/stubs')
|
|
|
81
86
|
const nativeAutoStubPath = path.resolve(compatStubsDir, 'native-auto-stub.ts')
|
|
82
87
|
const rnDeepStubDefault = path.resolve(compatStubsDir, 'react-native-internals.ts')
|
|
83
88
|
|
|
89
|
+
function hasExactFileName(candidate: string): boolean {
|
|
90
|
+
// a differently cased native file must not shadow a directory entry on macos.
|
|
91
|
+
return (
|
|
92
|
+
fs.existsSync(candidate) &&
|
|
93
|
+
fs.readdirSync(path.dirname(candidate)).includes(path.basename(candidate))
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
function getInternalTamaguiPackages(): string[] {
|
|
85
98
|
try {
|
|
86
99
|
const scoped = fs
|
|
@@ -232,62 +245,6 @@ const expoUiJetpackComposeRealAliases = [
|
|
|
232
245
|
}
|
|
233
246
|
})
|
|
234
247
|
|
|
235
|
-
// these components are upstream pure JS and should load unchanged over the
|
|
236
|
-
// native seam. gesture handler 3 still supplies ReanimatedSwipeable but removed
|
|
237
|
-
// DrawerLayout, so the latter resolves from the explicit v2 compatibility
|
|
238
|
-
// alias. exact subpath aliases must precede the root facade alias.
|
|
239
|
-
function rnghSubpathRealPath(packageName: string, subpath: string): string | null {
|
|
240
|
-
try {
|
|
241
|
-
const packageJsonPath = sootsimPluginRequire.resolve(
|
|
242
|
-
`${packageName}/${subpath}/package.json`,
|
|
243
|
-
)
|
|
244
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
|
|
245
|
-
const moduleEntry = packageJson?.module
|
|
246
|
-
if (typeof moduleEntry !== 'string' || moduleEntry.length === 0) return null
|
|
247
|
-
const modulePath = path.resolve(path.dirname(packageJsonPath), moduleEntry)
|
|
248
|
-
if (fs.existsSync(modulePath) && fs.statSync(modulePath).isFile()) return modulePath
|
|
249
|
-
const jsPath = `${modulePath}.js`
|
|
250
|
-
if (fs.existsSync(jsPath)) return jsPath
|
|
251
|
-
const indexPath = path.join(modulePath, 'index.js')
|
|
252
|
-
return fs.existsSync(indexPath) ? indexPath : null
|
|
253
|
-
} catch {
|
|
254
|
-
return null
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const rnghReanimatedSwipeableRealPath = rnghSubpathRealPath(
|
|
259
|
-
'react-native-gesture-handler',
|
|
260
|
-
'ReanimatedSwipeable',
|
|
261
|
-
)
|
|
262
|
-
const rnghDrawerLayoutRealPath = rnghSubpathRealPath(
|
|
263
|
-
'react-native-gesture-handler-v2',
|
|
264
|
-
'DrawerLayout',
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
const rnghGestureHandlerRootViewContextRealPath = (() => {
|
|
268
|
-
try {
|
|
269
|
-
return path.join(
|
|
270
|
-
path.dirname(
|
|
271
|
-
sootsimPluginRequire.resolve('react-native-gesture-handler/package.json'),
|
|
272
|
-
),
|
|
273
|
-
'lib/module/GestureHandlerRootViewContext.js',
|
|
274
|
-
)
|
|
275
|
-
} catch {
|
|
276
|
-
return null
|
|
277
|
-
}
|
|
278
|
-
})()
|
|
279
|
-
const rnghGestureHandlerRootViewContextShimPath = path.resolve(
|
|
280
|
-
compatStubsDir,
|
|
281
|
-
'rngh-gesture-handler-root-view-context.ts',
|
|
282
|
-
)
|
|
283
|
-
const rnghRootStubPath = path.resolve(compatStubsDir, 'react-native-gesture-handler.ts')
|
|
284
|
-
const rnghLibModuleRoots = [
|
|
285
|
-
rnghGestureHandlerRootViewContextRealPath
|
|
286
|
-
? path.dirname(rnghGestureHandlerRootViewContextRealPath)
|
|
287
|
-
: null,
|
|
288
|
-
rnghDrawerLayoutRealPath ? path.dirname(path.dirname(rnghDrawerLayoutRealPath)) : null,
|
|
289
|
-
].filter((root): root is string => root !== null)
|
|
290
|
-
|
|
291
248
|
const compatWrapperRealPackageAliases: Array<{
|
|
292
249
|
find: string
|
|
293
250
|
replacement: string
|
|
@@ -324,7 +281,6 @@ const coreOwnedPackages = [
|
|
|
324
281
|
'react/jsx-dev-runtime',
|
|
325
282
|
'canvaskit-wasm',
|
|
326
283
|
'canvaskit-wasm/full',
|
|
327
|
-
'yoga-layout',
|
|
328
284
|
]
|
|
329
285
|
|
|
330
286
|
const nativePackagePatterns = [
|
|
@@ -385,7 +341,7 @@ export function sootsim(options: SootSimOptions = {}): Plugin[] {
|
|
|
385
341
|
},
|
|
386
342
|
},
|
|
387
343
|
sootsimConfigPlugin(appDir, extraSources, publishedBrowserPackages),
|
|
388
|
-
|
|
344
|
+
expoHostSocketBootstrapRedirect(),
|
|
389
345
|
fixJsxRuntimeExports(),
|
|
390
346
|
flowStripTransform(),
|
|
391
347
|
nodeModulesJsxTransform(),
|
|
@@ -408,6 +364,27 @@ export function sootsim(options: SootSimOptions = {}): Plugin[] {
|
|
|
408
364
|
]
|
|
409
365
|
}
|
|
410
366
|
|
|
367
|
+
function expoHostSocketBootstrapRedirect(): Plugin {
|
|
368
|
+
const target = '\0sootsim:expo-host-socket-bootstrap'
|
|
369
|
+
return {
|
|
370
|
+
name: 'sootsim-expo-host-socket-bootstrap',
|
|
371
|
+
enforce: 'pre',
|
|
372
|
+
resolveId(source, importer) {
|
|
373
|
+
if (isExpoHostSocketModule(stripViteQuery(source))) return target
|
|
374
|
+
if (!importer || !source.startsWith('.')) return null
|
|
375
|
+
const candidate = path.resolve(
|
|
376
|
+
path.dirname(stripViteQuery(importer)),
|
|
377
|
+
stripViteQuery(source),
|
|
378
|
+
)
|
|
379
|
+
return isExpoHostSocketModule(candidate) ? target : null
|
|
380
|
+
},
|
|
381
|
+
load(id) {
|
|
382
|
+
if (id !== target) return null
|
|
383
|
+
return 'export default function noopExpoHostSocketBootstrap() {}'
|
|
384
|
+
},
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
411
388
|
function stripViteQuery(id: string): string {
|
|
412
389
|
return id.split('?')[0]
|
|
413
390
|
}
|
|
@@ -417,41 +394,6 @@ function isPathInside(child: string, parent: string): boolean {
|
|
|
417
394
|
return rel === '' || (!!rel && !rel.startsWith('..') && !path.isAbsolute(rel))
|
|
418
395
|
}
|
|
419
396
|
|
|
420
|
-
function rnghUpstreamInternalResolvePlugin(): Plugin {
|
|
421
|
-
return {
|
|
422
|
-
name: 'sootsim-rngh-upstream-internal-resolve',
|
|
423
|
-
enforce: 'pre',
|
|
424
|
-
resolveId: {
|
|
425
|
-
filter: {
|
|
426
|
-
id: /(?:^\.\.\/\.\.(?:\.(?:js|jsx|mjs|ts|tsx))?$|GestureDetector(?:\.(?:js|jsx|mjs|ts|tsx))?$|GestureHandlerRootViewContext(?:\.(?:js|jsx|mjs|ts|tsx))?$|(?:PanGestureHandler|TapGestureHandler|State)(?:\.(?:js|jsx|mjs|ts|tsx))?$)/,
|
|
427
|
-
},
|
|
428
|
-
handler(source, importer) {
|
|
429
|
-
if (!importer || rnghLibModuleRoots.length === 0) return null
|
|
430
|
-
const importerPath = stripViteQuery(importer)
|
|
431
|
-
if (!rnghLibModuleRoots.some((root) => isPathInside(importerPath, root))) {
|
|
432
|
-
return null
|
|
433
|
-
}
|
|
434
|
-
const sourcePath = source.replace(/\.(js|jsx|mjs|ts|tsx)$/, '')
|
|
435
|
-
if (
|
|
436
|
-
sourcePath === '../..' ||
|
|
437
|
-
sourcePath.endsWith('/handlers/gestures/GestureDetector') ||
|
|
438
|
-
// upstream's DrawerLayout builds on the old-API handlers and the
|
|
439
|
-
// State enum; both come from our seam, not upstream's native modules.
|
|
440
|
-
sourcePath.endsWith('/handlers/PanGestureHandler') ||
|
|
441
|
-
sourcePath.endsWith('/handlers/TapGestureHandler') ||
|
|
442
|
-
sourcePath === '../State'
|
|
443
|
-
) {
|
|
444
|
-
return rnghRootStubPath
|
|
445
|
-
}
|
|
446
|
-
if (sourcePath.endsWith('GestureHandlerRootViewContext')) {
|
|
447
|
-
return rnghGestureHandlerRootViewContextShimPath
|
|
448
|
-
}
|
|
449
|
-
return null
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
397
|
// shared worker plugin chain for the engine's shell-host build (used by
|
|
456
398
|
// both `vite.config.ts` for dev/watch and `vite.build.config.ts` for prod).
|
|
457
399
|
// keep these here — duplicating the list inline drifts (which is exactly how
|
|
@@ -499,7 +441,6 @@ export function engineShellWorkerPlugins(): Plugin[] {
|
|
|
499
441
|
reanimatedNativeSeamRedirect(),
|
|
500
442
|
manifestNativeSeamRedirect(),
|
|
501
443
|
keyboardControllerBindingsRedirect(),
|
|
502
|
-
rnghUpstreamInternalResolvePlugin(),
|
|
503
444
|
workletsBabelTransform(() => true),
|
|
504
445
|
workerBootChunkPlugin(ENGINE_WORKER_BOOT_CLOSURES),
|
|
505
446
|
]
|
|
@@ -523,27 +464,44 @@ export type WorkerBootClosure = {
|
|
|
523
464
|
// substring of the worker entry module id this applies to
|
|
524
465
|
entry: string
|
|
525
466
|
// byte cap on the rendered worker file; fix excess boot dependencies and
|
|
526
|
-
// unneeded inclusions rather than raising the cap
|
|
467
|
+
// unneeded inclusions rather than raising the cap.
|
|
468
|
+
// a cap failure in a worktree whose node_modules is symlinked from another
|
|
469
|
+
// tree is suspect: workspace modules resolve into the other tree and bundle
|
|
470
|
+
// twice (~1MB rendered here). re-run with a real `bun install` first.
|
|
527
471
|
maxBytes: number
|
|
528
472
|
}
|
|
529
473
|
|
|
530
474
|
const ENGINE_WORKER_BOOT_CLOSURES: WorkerBootClosure[] = [
|
|
531
475
|
// these workers inline their dynamic imports, so anything reachable from the
|
|
532
476
|
// entry lands in the boot file whether or not it runs. that is why the font
|
|
533
|
-
// parser is not reachable from
|
|
477
|
+
// parser is not reachable from any of them: only the tenant reads a face's
|
|
534
478
|
// name table, and it sends the aliases and metrics it read on the wire
|
|
535
479
|
// (engine/app-font-registry.ts registerForwardedAppFonts). keep it that way
|
|
536
|
-
// when adding font work here, or
|
|
480
|
+
// when adding font work here, or every cap takes the parser again.
|
|
537
481
|
// measured 3,406,869 bytes after the shell engine config split: the shell
|
|
538
482
|
// worker installs a slim config without the list, modal, slider, swipeable,
|
|
539
483
|
// and tab components nothing shell-side reads (compat-bridge composes the
|
|
540
484
|
// full config for main, tenant, headless, and external realms on top of
|
|
541
485
|
// it), and the gesture-handler stub imports TouchableNativeFeedback
|
|
542
486
|
// statically instead of require()ing the whole react-native namespace into
|
|
543
|
-
// the boot file.
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
{ entry: 'src/render-worker/
|
|
487
|
+
// the boot file. the shell worker is one file per compositor backend, so
|
|
488
|
+
// each carries only its own CanvasKit glue: 3,263,311 graphite and
|
|
489
|
+
// 3,256,832 ganesh bytes when the split landed, down from 3,386,929 with both.
|
|
490
|
+
{ entry: 'src/render-worker/shell-worker-entry.ts', maxBytes: 3_310_000 },
|
|
491
|
+
{ entry: 'src/render-worker/shell-worker-ganesh-entry.ts', maxBytes: 3_300_000 },
|
|
492
|
+
{ entry: 'src/render-worker/compositor-worker-entry.ts', maxBytes: 1_200_000 },
|
|
493
|
+
{ entry: 'src/render-worker/compositor-worker-ganesh-entry.ts', maxBytes: 1_110_000 },
|
|
494
|
+
]
|
|
495
|
+
|
|
496
|
+
// packages whose manifests omit `sideEffects` (metro never tree-shakes, so
|
|
497
|
+
// upstream has no reason to declare it), which makes rolldown keep every module
|
|
498
|
+
// their index reaches even when the worker reads none of it.
|
|
499
|
+
// @gorhom/bottom-sheet's index reaches BottomSheetFlashList, whose top-level
|
|
500
|
+
// optional require('@shopify/flash-list') put all of flash-list, plus the
|
|
501
|
+
// sheet's unused modal, list, and text input components, in the shell worker
|
|
502
|
+
// although the shell renders only the plain sheet: 67kB of the boot file.
|
|
503
|
+
const WORKER_SIDE_EFFECT_FREE_PACKAGES = [
|
|
504
|
+
{ test: /\/node_modules\/@gorhom\/bottom-sheet\//, sideEffects: false },
|
|
547
505
|
]
|
|
548
506
|
|
|
549
507
|
export function workerBootChunkPlugin(closures: WorkerBootClosure[]): Plugin {
|
|
@@ -557,6 +515,13 @@ export function workerBootChunkPlugin(closures: WorkerBootClosure[]): Plugin {
|
|
|
557
515
|
typeof input === 'string'
|
|
558
516
|
? (closures.find((candidate) => input.includes(candidate.entry)) ?? null)
|
|
559
517
|
: null
|
|
518
|
+
if (!closure) return null
|
|
519
|
+
const treeshake =
|
|
520
|
+
typeof inputOptions.treeshake === 'object' ? inputOptions.treeshake : {}
|
|
521
|
+
return {
|
|
522
|
+
...inputOptions,
|
|
523
|
+
treeshake: { ...treeshake, moduleSideEffects: WORKER_SIDE_EFFECT_FREE_PACKAGES },
|
|
524
|
+
}
|
|
560
525
|
},
|
|
561
526
|
outputOptions(options) {
|
|
562
527
|
if (!closure) return null
|
|
@@ -572,8 +537,33 @@ export function workerBootChunkPlugin(closures: WorkerBootClosure[]): Plugin {
|
|
|
572
537
|
}
|
|
573
538
|
const bytes = Buffer.byteLength(chunks[0].code)
|
|
574
539
|
if (bytes > closure.maxBytes) {
|
|
540
|
+
const chunk = chunks[0]
|
|
541
|
+
const pkgs = new Map<string, Set<string>>()
|
|
542
|
+
for (const id of chunk.moduleIds) {
|
|
543
|
+
const nmIndex = id.lastIndexOf('/node_modules/')
|
|
544
|
+
if (nmIndex !== -1) {
|
|
545
|
+
const rest = id.slice(nmIndex + '/node_modules/'.length)
|
|
546
|
+
const pkgMatch = rest.match(/^(?:@[^/]+\/)?[^/]+/)
|
|
547
|
+
if (pkgMatch) {
|
|
548
|
+
const pkgName = pkgMatch[0]
|
|
549
|
+
if (!pkgs.has(pkgName)) pkgs.set(pkgName, new Set())
|
|
550
|
+
const baseDir = id.slice(
|
|
551
|
+
0,
|
|
552
|
+
nmIndex + '/node_modules/'.length + pkgName.length,
|
|
553
|
+
)
|
|
554
|
+
pkgs.get(pkgName)!.add(baseDir)
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
const duplicates = [...pkgs.entries()]
|
|
559
|
+
.filter(([, dirs]) => dirs.size > 1)
|
|
560
|
+
.map(([name, dirs]) => `${name} (${[...dirs].join(', ')})`)
|
|
561
|
+
const dupDetail =
|
|
562
|
+
duplicates.length > 0
|
|
563
|
+
? `\ndetected duplicate packages bundled from multiple roots (likely a symlinked or cross-tree node_modules):\n ${duplicates.join('\n ')}`
|
|
564
|
+
: ''
|
|
575
565
|
this.error(
|
|
576
|
-
`worker ${closure.entry}: ${chunks[0].fileName} is ${bytes} bytes, over the ${closure.maxBytes} byte cap; eliminate excess boot dependencies rather than raising the cap`,
|
|
566
|
+
`worker ${closure.entry}: ${chunks[0].fileName} is ${bytes} bytes, over the ${closure.maxBytes} byte cap; eliminate excess boot dependencies rather than raising the cap${dupDetail}`,
|
|
577
567
|
)
|
|
578
568
|
}
|
|
579
569
|
},
|
|
@@ -610,13 +600,13 @@ export function keyboardControllerBindingsRedirect(): Plugin {
|
|
|
610
600
|
for (const ext of nativeExts) {
|
|
611
601
|
const candidate = base + ext
|
|
612
602
|
try {
|
|
613
|
-
if (
|
|
603
|
+
if (hasExactFileName(candidate)) return candidate
|
|
614
604
|
} catch {}
|
|
615
605
|
}
|
|
616
606
|
for (const ext of nativeExts) {
|
|
617
607
|
const candidate = path.join(base, 'index' + ext)
|
|
618
608
|
try {
|
|
619
|
-
if (
|
|
609
|
+
if (hasExactFileName(candidate)) return candidate
|
|
620
610
|
} catch {}
|
|
621
611
|
}
|
|
622
612
|
return null
|
|
@@ -679,6 +669,7 @@ export function keyboardControllerBindingsRedirect(): Plugin {
|
|
|
679
669
|
// vite's worker build. redirect the validate script to a no-op stub.
|
|
680
670
|
const reanimatedNativeSeamFiles = new Set([
|
|
681
671
|
'NativeReanimatedModule',
|
|
672
|
+
'NativeWorkletsModule',
|
|
682
673
|
'scrollTo',
|
|
683
674
|
'measure',
|
|
684
675
|
'setNativeProps',
|
|
@@ -700,7 +691,7 @@ export function reanimatedNativeSeamRedirect(): Plugin {
|
|
|
700
691
|
enforce: 'pre',
|
|
701
692
|
resolveId: {
|
|
702
693
|
filter: {
|
|
703
|
-
id: /(?:^react-native-worklets\/package\.json$|^react-native-reanimated\/scripts\/validate-worklets-version(?:\.js)?$|(?:^|\/)(?:fabricUtils|NativeReanimatedModule|scrollTo|measure|setNativeProps|dispatchCommand|setGestureState)(?:\.(?:native|web|ios|android))?$)/,
|
|
694
|
+
id: /(?:^react-native-worklets\/package\.json$|^react-native-reanimated\/scripts\/validate-worklets-version(?:\.js)?$|(?:^|\/)(?:fabricUtils|NativeReanimatedModule|NativeWorkletsModule|scrollTo|measure|setNativeProps|dispatchCommand|setGestureState)(?:\.(?:native|web|ios|android))?$)/,
|
|
704
695
|
},
|
|
705
696
|
handler(source, importer) {
|
|
706
697
|
// upstream's `assertWorkletsVersion` (DEV-only) imports a build-time
|
|
@@ -738,6 +729,9 @@ export function reanimatedNativeSeamRedirect(): Plugin {
|
|
|
738
729
|
return reanimatedFabricUtilsRedirectPath
|
|
739
730
|
}
|
|
740
731
|
if (!reanimatedNativeSeamFiles.has(basename)) return null
|
|
732
|
+
if (basename === 'NativeWorkletsModule') {
|
|
733
|
+
return path.resolve(compatStubsDir, 'react-native-worklets-native.ts')
|
|
734
|
+
}
|
|
741
735
|
if (process.env.SOOTSIM_REANIMATED_REDIRECT_DEBUG) {
|
|
742
736
|
console.log(
|
|
743
737
|
'[reanimatedRedirect]',
|
|
@@ -1029,11 +1023,12 @@ function sootsimConfigPlugin(
|
|
|
1029
1023
|
// their parent package (e.g. foo) — vite processes aliases in order
|
|
1030
1024
|
.sort((a, b) => b[0].length - a[0].length)
|
|
1031
1025
|
.map(([find, file]) => ({
|
|
1032
|
-
//
|
|
1033
|
-
//
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1026
|
+
// these stubs replace only the package root; their pure-js subpaths
|
|
1027
|
+
// (core's modules, screens' experimental Split) run upstream.
|
|
1028
|
+
find:
|
|
1029
|
+
find === 'expo-modules-core' || find === 'react-native-screens'
|
|
1030
|
+
? new RegExp(`^${find}$`)
|
|
1031
|
+
: find,
|
|
1037
1032
|
replacement: path.resolve(compatStubsDir, file),
|
|
1038
1033
|
}))
|
|
1039
1034
|
|
|
@@ -1195,13 +1190,21 @@ function sootsimConfigPlugin(
|
|
|
1195
1190
|
alias: [
|
|
1196
1191
|
...sootsimBrowserSourceAliases,
|
|
1197
1192
|
...publishedBrowserEntryAliases,
|
|
1193
|
+
{
|
|
1194
|
+
find: /^@react-native\/assets-registry\/registry$/,
|
|
1195
|
+
replacement: rnAssetRegistryPath,
|
|
1196
|
+
},
|
|
1198
1197
|
...Object.entries(rnLibraryStubs).map(([find, replacement]) => ({
|
|
1199
1198
|
find,
|
|
1200
1199
|
replacement,
|
|
1201
1200
|
})),
|
|
1202
1201
|
{ find: /^react-native\/Libraries\/.*/, replacement: rnDeepStubDefault },
|
|
1203
|
-
{
|
|
1204
|
-
|
|
1202
|
+
{
|
|
1203
|
+
find: /^react-native\/asset-registry$/,
|
|
1204
|
+
replacement: rnAssetRegistryPath,
|
|
1205
|
+
},
|
|
1206
|
+
{ find: /^react-native$/, replacement: rnShimPath },
|
|
1207
|
+
{ find: /^react-native-web$/, replacement: rnShimPath },
|
|
1205
1208
|
// resolved-path alias for the synthetic specifier the
|
|
1206
1209
|
// @react-navigation/native compat wrapper imports from. terminates
|
|
1207
1210
|
// the wrapper's own real-package import without re-entering the
|
|
@@ -1233,22 +1236,6 @@ function sootsimConfigPlugin(
|
|
|
1233
1236
|
]
|
|
1234
1237
|
: []),
|
|
1235
1238
|
...expoUiJetpackComposeRealAliases,
|
|
1236
|
-
...(rnghReanimatedSwipeableRealPath
|
|
1237
|
-
? [
|
|
1238
|
-
{
|
|
1239
|
-
find: /^react-native-gesture-handler\/ReanimatedSwipeable$/,
|
|
1240
|
-
replacement: rnghReanimatedSwipeableRealPath,
|
|
1241
|
-
},
|
|
1242
|
-
]
|
|
1243
|
-
: []),
|
|
1244
|
-
...(rnghDrawerLayoutRealPath
|
|
1245
|
-
? [
|
|
1246
|
-
{
|
|
1247
|
-
find: /^(?:react-native-gesture-handler|react-native-gesture-handler-v2)\/DrawerLayout$/,
|
|
1248
|
-
replacement: rnghDrawerLayoutRealPath,
|
|
1249
|
-
},
|
|
1250
|
-
]
|
|
1251
|
-
: []),
|
|
1252
1239
|
...stubAliases,
|
|
1253
1240
|
],
|
|
1254
1241
|
},
|
|
@@ -1439,13 +1426,13 @@ function sootsimEsbuildPlugin(appDir: string) {
|
|
|
1439
1426
|
for (const ext of platformExts) {
|
|
1440
1427
|
const candidate = resolved + ext
|
|
1441
1428
|
try {
|
|
1442
|
-
if (
|
|
1429
|
+
if (hasExactFileName(candidate)) return { path: candidate }
|
|
1443
1430
|
} catch {}
|
|
1444
1431
|
}
|
|
1445
1432
|
for (const ext of platformExts) {
|
|
1446
1433
|
const candidate = path.join(resolved, 'index' + ext)
|
|
1447
1434
|
try {
|
|
1448
|
-
if (
|
|
1435
|
+
if (hasExactFileName(candidate)) return { path: candidate }
|
|
1449
1436
|
} catch {}
|
|
1450
1437
|
}
|
|
1451
1438
|
const allExts = [...platformExts, '.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs']
|
|
@@ -1455,7 +1442,7 @@ function sootsimEsbuildPlugin(appDir: string) {
|
|
|
1455
1442
|
for (const pext of platformExts) {
|
|
1456
1443
|
const candidate = base + pext
|
|
1457
1444
|
try {
|
|
1458
|
-
if (
|
|
1445
|
+
if (hasExactFileName(candidate)) return { path: candidate }
|
|
1459
1446
|
} catch {}
|
|
1460
1447
|
}
|
|
1461
1448
|
break
|
|
@@ -1614,7 +1601,7 @@ export function workletsBabelTransform(
|
|
|
1614
1601
|
// pipeline; vite/rolldown/oxc do not. detect the `@flow` pragma in node_modules and
|
|
1615
1602
|
// run @babel/plugin-transform-flow-strip-types so the wrapper-real seam can pull
|
|
1616
1603
|
// in the real upstream JS without re-implementing it locally. mirrored in
|
|
1617
|
-
// scripts/build
|
|
1604
|
+
// scripts/build/bundler-deps.ts so esbuild-based dep prebundles stay in sync.
|
|
1618
1605
|
let flowBabel: typeof import('@babel/core') | null = null
|
|
1619
1606
|
let flowStripPlugin: import('@babel/core').PluginItem | null = null
|
|
1620
1607
|
let jsxSyntaxPlugin: import('@babel/core').PluginItem | null = null
|
|
@@ -1698,13 +1685,13 @@ function metroNativeResolve(isAppSource: (p: string) => boolean): Plugin {
|
|
|
1698
1685
|
for (const ext of platformExts) {
|
|
1699
1686
|
const candidate = base + ext
|
|
1700
1687
|
try {
|
|
1701
|
-
if (
|
|
1688
|
+
if (hasExactFileName(candidate)) return candidate
|
|
1702
1689
|
} catch {}
|
|
1703
1690
|
}
|
|
1704
1691
|
for (const ext of platformExts) {
|
|
1705
1692
|
const candidate = path.join(base, 'index' + ext)
|
|
1706
1693
|
try {
|
|
1707
|
-
if (
|
|
1694
|
+
if (hasExactFileName(candidate)) return candidate
|
|
1708
1695
|
} catch {}
|
|
1709
1696
|
}
|
|
1710
1697
|
return null
|
package/src/vite.d.ts
ADDED
package/cli/resolve-assets.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// resolve peach's bundled assets (fonts, icons, sounds)
|
|
2
|
-
// regardless of how the package was installed (source checkout, npm install, bunx).
|
|
3
|
-
//
|
|
4
|
-
// uses import.meta.url to derive the package root, then checks both
|
|
5
|
-
// the source layout (public/) and npm-installed layout (public/).
|
|
6
|
-
|
|
7
|
-
import { existsSync, readFileSync } from 'fs'
|
|
8
|
-
import { dirname, resolve } from 'path'
|
|
9
|
-
import { fileURLToPath } from 'url'
|
|
10
|
-
import { rnxPublicBrand } from '../src/public-brand'
|
|
11
|
-
|
|
12
|
-
// when bundled by esbuild, this file lives at dist-cli/bin.js
|
|
13
|
-
// when running from source, this file lives at cli/resolve-assets.ts
|
|
14
|
-
const thisDir = dirname(fileURLToPath(import.meta.url))
|
|
15
|
-
|
|
16
|
-
// walk up to find package root: look for package.json with the peachsim package name
|
|
17
|
-
function findPackageRoot(): string {
|
|
18
|
-
let dir = thisDir
|
|
19
|
-
for (let i = 0; i < 5; i++) {
|
|
20
|
-
try {
|
|
21
|
-
const pkgPath = resolve(dir, 'package.json')
|
|
22
|
-
if (existsSync(pkgPath)) {
|
|
23
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
24
|
-
if (pkg.name === rnxPublicBrand.packageName) return dir
|
|
25
|
-
}
|
|
26
|
-
} catch {}
|
|
27
|
-
dir = dirname(dir)
|
|
28
|
-
}
|
|
29
|
-
// fallback: assume one level up from this file
|
|
30
|
-
return dirname(thisDir)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const packageRoot = findPackageRoot()
|
|
34
|
-
|
|
35
|
-
export interface SootSimAssets {
|
|
36
|
-
fontsDir: string
|
|
37
|
-
iconsDir: string
|
|
38
|
-
soundsDir: string
|
|
39
|
-
packageRoot: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function resolveAssets(): SootSimAssets {
|
|
43
|
-
// both source and npm-installed layouts use public/ at the package root
|
|
44
|
-
const publicDir = resolve(packageRoot, 'public')
|
|
45
|
-
|
|
46
|
-
const fontsDir = resolve(publicDir, 'fonts')
|
|
47
|
-
const iconsDir = resolve(publicDir, 'icons')
|
|
48
|
-
const soundsDir = resolve(publicDir, 'sounds')
|
|
49
|
-
|
|
50
|
-
if (!existsSync(fontsDir)) {
|
|
51
|
-
console.warn(`[peach] warning: fonts directory not found at ${fontsDir}`)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
fontsDir,
|
|
56
|
-
iconsDir,
|
|
57
|
-
soundsDir,
|
|
58
|
-
packageRoot,
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// re-export packageRoot for use in CLI commands that need SOOTSIM_ROOT
|
|
63
|
-
export { packageRoot }
|