peachsim 0.1.657 → 0.1.659
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/README.md +21 -2
- package/cli/app-config.ts +25 -9
- package/cli/bridge-flow-runner.ts +10 -23
- package/cli/commands/compat.ts +234 -10
- package/cli/commands/do-chain.ts +5 -1
- package/cli/commands/inspect/actions.ts +33 -76
- package/cli/commands/inspect/resolve-target.ts +67 -2
- package/cli/commands/inspect.ts +16 -1
- package/cli/drivers/playwright-provisioning.ts +95 -0
- package/cli/ws-bridge.ts +7 -7
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -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 +9 -1
- package/dist-lib/bridge-contract-input.mjs +9 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- 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 +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +3 -2
- package/dist-lib/detox/index.cjs +2 -2
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +78 -35
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- 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 +51 -8
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +317 -70
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +14 -4
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +300 -29
- package/dist-lib/native-app-identity.cjs +58 -25
- package/dist-lib/native-app-identity.mjs +57 -25
- package/dist-lib/plist.cjs +64 -0
- package/dist-lib/plist.mjs +29 -0
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- 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 +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +2 -2
- package/dist-lib/sdk.cjs +36 -49
- package/dist-lib/sdk.mjs +36 -49
- package/dist-lib/skills.cjs +257 -138
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +51 -8
- package/kotlin/AppSources/android/app/Activity.kt +44 -0
- package/kotlin/AppSources/android/app/UiModeManager.kt +9 -0
- package/kotlin/AppSources/android/content/Context.kt +9 -2
- package/kotlin/AppSources/android/content/res/Configuration.kt +16 -0
- package/kotlin/AppSources/android/content/res/Resources.kt +7 -0
- package/kotlin/AppSources/android/graphics/Color.kt +13 -0
- package/kotlin/AppSources/android/os/Bundle.kt +9 -3
- package/kotlin/AppSources/android/view/View.kt +2 -0
- package/kotlin/AppSources/android/view/Window.kt +99 -8
- package/kotlin/AppSources/android/view/WindowInsetsController.kt +12 -0
- package/kotlin/AppSources/android/view/WindowManager.kt +16 -0
- package/kotlin/AppSources/androidx/activity/BackEventCompat.kt +17 -0
- package/kotlin/AppSources/androidx/activity/Cancellable.kt +5 -0
- package/kotlin/AppSources/androidx/activity/ComponentActivity.kt +22 -3
- package/kotlin/AppSources/androidx/activity/EdgeToEdge.kt +71 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedCallback.kt +28 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +144 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcherOwner.kt +7 -0
- package/kotlin/AppSources/androidx/activity/compose/BackHandler.kt +55 -0
- package/kotlin/AppSources/androidx/core/view/WindowCompat.kt +32 -0
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +67 -12
- package/kotlin/AppSources/dev/peach/app/PeachWindowHost.kt +2 -1
- package/kotlin/AppSources/java/lang/Runnable.kt +6 -0
- package/kotlin/ComposeSources/PeachComposeHost.kt +11 -1
- package/package.json +8 -1
- package/skills/peach-setup/SKILL.md +27 -0
- package/src/android-theme.ts +167 -0
- package/src/android-xml.ts +70 -0
- package/src/bridge-contract-input.ts +10 -1
- package/src/bridge-contract.ts +7 -1
- package/src/config.ts +8 -0
- package/src/generated/android-framework-themes.json +6303 -0
- package/src/host/replacement-module-handler.ts +33 -0
- package/src/index.ts +1 -0
- package/src/kotlin-app.ts +86 -61
- package/src/kotlin-host.ts +13 -3
- package/src/metro-plugin.ts +46 -3
- package/src/native-app-identity.ts +75 -26
- package/src/sim-client.ts +2 -4
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -946,9 +946,6 @@ function saveCurrentSimId(simId) {
|
|
|
946
946
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
947
947
|
});
|
|
948
948
|
}
|
|
949
|
-
function clearCurrentSimId() {
|
|
950
|
-
(0, import_fs2.rmSync)(getCurrentSimPath(), { force: true });
|
|
951
|
-
}
|
|
952
949
|
|
|
953
950
|
// cli/ws-bridge.ts
|
|
954
951
|
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
@@ -1295,9 +1292,8 @@ function createBridge(wsPort, opts = {}) {
|
|
|
1295
1292
|
);
|
|
1296
1293
|
return sendOnce(successor);
|
|
1297
1294
|
}
|
|
1298
|
-
clearCurrentSimId();
|
|
1299
1295
|
throw new Error(
|
|
1300
|
-
`saved sim ${sentSimId} is
|
|
1296
|
+
`saved sim ${sentSimId} is not connected${message.slice(missingSimMessage.length)}; commands resume when it reconnects, or run \`peach list\` and \`peach use <sim>\`, or open a fresh sim`
|
|
1301
1297
|
);
|
|
1302
1298
|
}
|
|
1303
1299
|
throw error;
|
|
@@ -2121,10 +2117,20 @@ async function getShellState(bridge, readyTimeoutMs = 0) {
|
|
|
2121
2117
|
}
|
|
2122
2118
|
|
|
2123
2119
|
// cli/commands/inspect/resolve-target.ts
|
|
2120
|
+
function isScreenSize(value) {
|
|
2121
|
+
if (value === null || typeof value !== "object") return false;
|
|
2122
|
+
const width = Reflect.get(value, "width");
|
|
2123
|
+
const height = Reflect.get(value, "height");
|
|
2124
|
+
return typeof width === "number" && Number.isFinite(width) && width > 0 && typeof height === "number" && Number.isFinite(height) && height > 0;
|
|
2125
|
+
}
|
|
2126
|
+
function isOffscreen(x, y, screen) {
|
|
2127
|
+
return !(x >= 0 && y >= 0 && x <= screen.width && y <= screen.height);
|
|
2128
|
+
}
|
|
2129
|
+
var UNREPORTED_SCREEN_ERROR = "this runtime does not report the screen size a targeted gesture needs; update it with `peach runtime install`, or use coordinates";
|
|
2124
2130
|
async function resolveTargetCoords(bridge, target) {
|
|
2125
2131
|
const result = await bridge.send({
|
|
2126
2132
|
type: "resolve",
|
|
2127
|
-
selector: target.mode === "testid" ? { testID: target.value } : { text: target.value }
|
|
2133
|
+
selector: target.mode === "node" ? { nodeId: target.nodeId } : target.mode === "testid" ? { testID: target.value } : { text: target.value }
|
|
2128
2134
|
});
|
|
2129
2135
|
if (result === null) return null;
|
|
2130
2136
|
if (typeof result !== "object") throw new Error("resolve returned an invalid result");
|
|
@@ -2132,6 +2138,9 @@ async function resolveTargetCoords(bridge, target) {
|
|
|
2132
2138
|
const resolvedTarget = Reflect.get(result, "target");
|
|
2133
2139
|
const semanticNodes = [match, resolvedTarget];
|
|
2134
2140
|
const point = Reflect.get(result, "point");
|
|
2141
|
+
const viewport = Reflect.get(result, "viewport");
|
|
2142
|
+
const width = viewport !== null && typeof viewport === "object" ? Reflect.get(viewport, "width") : void 0;
|
|
2143
|
+
const height = viewport !== null && typeof viewport === "object" ? Reflect.get(viewport, "height") : void 0;
|
|
2135
2144
|
const x = point !== null && typeof point === "object" ? Reflect.get(point, "x") : void 0;
|
|
2136
2145
|
const y = point !== null && typeof point === "object" ? Reflect.get(point, "y") : void 0;
|
|
2137
2146
|
if (!isSimSemanticTree(semanticNodes) || typeof x !== "number" || !Number.isFinite(x) || typeof y !== "number" || !Number.isFinite(y)) {
|
|
@@ -2145,7 +2154,8 @@ async function resolveTargetCoords(bridge, target) {
|
|
|
2145
2154
|
nodeId: semanticMatch.nodeId,
|
|
2146
2155
|
testID: semanticMatch.testID ?? null,
|
|
2147
2156
|
text: semanticMatch.text ?? (target.mode === "text" ? target.value : semanticMatch.label),
|
|
2148
|
-
type: semanticMatch.type
|
|
2157
|
+
type: semanticMatch.type,
|
|
2158
|
+
...typeof width === "number" && typeof height === "number" ? { viewport: { width, height } } : {}
|
|
2149
2159
|
};
|
|
2150
2160
|
}
|
|
2151
2161
|
|
|
@@ -2340,30 +2350,6 @@ async function waitForSootsimIdle({
|
|
|
2340
2350
|
}
|
|
2341
2351
|
|
|
2342
2352
|
// cli/commands/inspect/actions.ts
|
|
2343
|
-
function isScreenSize(value) {
|
|
2344
|
-
if (value === null || typeof value !== "object") return false;
|
|
2345
|
-
const width = Reflect.get(value, "width");
|
|
2346
|
-
const height = Reflect.get(value, "height");
|
|
2347
|
-
return typeof width === "number" && Number.isFinite(width) && width > 0 && typeof height === "number" && Number.isFinite(height) && height > 0;
|
|
2348
|
-
}
|
|
2349
|
-
function viewportFromCapture(value) {
|
|
2350
|
-
if (value === null || typeof value !== "object") return void 0;
|
|
2351
|
-
const tree = Reflect.get(value, "tree");
|
|
2352
|
-
return tree !== null && typeof tree === "object" ? Reflect.get(tree, "viewport") : void 0;
|
|
2353
|
-
}
|
|
2354
|
-
async function readScreen(bridge) {
|
|
2355
|
-
try {
|
|
2356
|
-
const viewport = viewportFromCapture(
|
|
2357
|
-
await bridge.send({ type: "capture", includeVisual: false })
|
|
2358
|
-
);
|
|
2359
|
-
return isScreenSize(viewport) ? { width: viewport.width, height: viewport.height } : null;
|
|
2360
|
-
} catch {
|
|
2361
|
-
return null;
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2364
|
-
function isOffscreen(cx, cy, screen) {
|
|
2365
|
-
return !(cx >= 0 && cy >= 0 && cx <= screen.width && cy <= screen.height);
|
|
2366
|
-
}
|
|
2367
2353
|
var DEFAULT_AGENT_TIMING = {
|
|
2368
2354
|
initialWaitMs: 3e3,
|
|
2369
2355
|
deadlineMs: 5e3,
|
|
@@ -2425,17 +2411,24 @@ async function tapResolvedTarget(bridge, args) {
|
|
|
2425
2411
|
}
|
|
2426
2412
|
const deadline = Date.now() + timing.deadlineMs;
|
|
2427
2413
|
let lastOffscreenAt = null;
|
|
2428
|
-
const screen = bridge.plane === "cloud" ? null : await readScreen(bridge);
|
|
2429
2414
|
while (Date.now() <= deadline || attempts === 0) {
|
|
2430
2415
|
attempts++;
|
|
2431
|
-
const resolved = await args.resolve();
|
|
2432
|
-
const
|
|
2416
|
+
const { screen, ...resolved } = await args.resolve() ?? {};
|
|
2417
|
+
const checksScreen = bridge.plane !== "cloud" && typeof resolved.cx === "number";
|
|
2418
|
+
if (checksScreen && screen === void 0) {
|
|
2419
|
+
throw new Error(UNREPORTED_SCREEN_ERROR);
|
|
2420
|
+
}
|
|
2421
|
+
const unsized = checksScreen && !isScreenSize(screen);
|
|
2422
|
+
const payload = checksScreen && typeof resolved.cx === "number" && typeof resolved.cy === "number" && isScreenSize(screen) && isOffscreen(resolved.cx, resolved.cy, screen) ? { ...resolved, offscreen: true, screen } : resolved;
|
|
2433
2423
|
lastPayload = payload;
|
|
2434
2424
|
if (payload?.error === "bridge-not-ready" || payload?.ambiguous || payload?.nthOutOfRange) {
|
|
2435
2425
|
return { payload, result: null, attempts, failure: "special" };
|
|
2436
2426
|
}
|
|
2437
2427
|
if (payload && typeof payload.cx === "number" && typeof payload.cy === "number") {
|
|
2438
|
-
if (
|
|
2428
|
+
if (unsized) {
|
|
2429
|
+
lastResult = { hit: false, reason: "screen-not-laid-out" };
|
|
2430
|
+
lastOffscreenAt = null;
|
|
2431
|
+
} else if (payload.offscreen) {
|
|
2439
2432
|
lastResult = {
|
|
2440
2433
|
hit: false,
|
|
2441
2434
|
reason: "offscreen",
|
|
@@ -2508,6 +2501,7 @@ function payloadFromResolved(resolved, match, extra = {}) {
|
|
|
2508
2501
|
return {
|
|
2509
2502
|
cx: resolved.x,
|
|
2510
2503
|
cy: resolved.y,
|
|
2504
|
+
screen: resolved.viewport,
|
|
2511
2505
|
match: {
|
|
2512
2506
|
nodeId: match.nodeId ?? null,
|
|
2513
2507
|
id: match.testID ?? null,
|
|
@@ -2641,30 +2635,12 @@ async function resolveTextTapTarget(bridge, query, options = {}) {
|
|
|
2641
2635
|
const picked = candidates[idx];
|
|
2642
2636
|
if (!picked) return { matched: 0, total };
|
|
2643
2637
|
const node = picked.node;
|
|
2644
|
-
const
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
args: [node.nodeId]
|
|
2638
|
+
const resolved = await resolveTargetCoords(bridge, {
|
|
2639
|
+
mode: "node",
|
|
2640
|
+
nodeId: node.nodeId
|
|
2648
2641
|
});
|
|
2649
|
-
if (!
|
|
2650
|
-
return payloadFromResolved(
|
|
2651
|
-
{
|
|
2652
|
-
x: tap.cx,
|
|
2653
|
-
y: tap.cy,
|
|
2654
|
-
nodeId: tap.target.nodeId,
|
|
2655
|
-
testID: tap.target.testID,
|
|
2656
|
-
text: tap.target.text ?? tap.target.accessibilityLabel,
|
|
2657
|
-
type: tap.target.type
|
|
2658
|
-
},
|
|
2659
|
-
node,
|
|
2660
|
-
{ total, idx }
|
|
2661
|
-
);
|
|
2662
|
-
}
|
|
2663
|
-
function isTapNode(value) {
|
|
2664
|
-
return value !== null && typeof value === "object" && typeof Reflect.get(value, "nodeId") === "number";
|
|
2665
|
-
}
|
|
2666
|
-
function isTapTargetInfo(value) {
|
|
2667
|
-
return value !== null && typeof value === "object" && typeof Reflect.get(value, "cx") === "number" && typeof Reflect.get(value, "cy") === "number" && isTapNode(Reflect.get(value, "target"));
|
|
2642
|
+
if (!resolved) return { matched: 0, total };
|
|
2643
|
+
return payloadFromResolved(resolved, node, { total, idx });
|
|
2668
2644
|
}
|
|
2669
2645
|
async function tapBest(bridge, query, opts = {}) {
|
|
2670
2646
|
return tapResolvedTarget(bridge, {
|
|
@@ -3630,6 +3606,7 @@ function launchRnxDesktop(bundleUrl, appName) {
|
|
|
3630
3606
|
}
|
|
3631
3607
|
|
|
3632
3608
|
// src/host/replacement-module-handler.ts
|
|
3609
|
+
var import_node_fs5 = require("node:fs");
|
|
3633
3610
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
3634
3611
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
3635
3612
|
|
|
@@ -3759,12 +3736,15 @@ function transformsFor(filePath) {
|
|
|
3759
3736
|
);
|
|
3760
3737
|
}
|
|
3761
3738
|
}
|
|
3739
|
+
function isLocalSpecifier(specifier) {
|
|
3740
|
+
return specifier.startsWith("./") || specifier.startsWith("../");
|
|
3741
|
+
}
|
|
3762
3742
|
function isContrastKitSpecifier(specifier) {
|
|
3763
3743
|
return specifier === "contrast-kit" || specifier.startsWith("contrast-kit/");
|
|
3764
3744
|
}
|
|
3765
3745
|
function unsupportedSpecifier(specifier) {
|
|
3766
3746
|
return new Error(
|
|
3767
|
-
`replacement modules may only import react, react-native, contrast-kit,
|
|
3747
|
+
`replacement modules may only import react, react-native, contrast-kit, the packages rnx stubs for this app, and other project files by relative path; '${specifier}' is none of those. vendor the code into a project file, or add the package to peach.config so the simulator bridges it.`
|
|
3768
3748
|
);
|
|
3769
3749
|
}
|
|
3770
3750
|
function bridgeDeclaration(name2, specifier) {
|
|
@@ -3789,11 +3769,9 @@ function compileReplacementModule(input) {
|
|
|
3789
3769
|
const transformed = (0, import_dist.transform)(input.source, {
|
|
3790
3770
|
transforms: transformsFor(input.filePath),
|
|
3791
3771
|
filePath: input.filePath,
|
|
3792
|
-
//
|
|
3793
|
-
//
|
|
3794
|
-
jsxRuntime: "
|
|
3795
|
-
jsxPragma: "React.createElement",
|
|
3796
|
-
jsxFragmentPragma: "React.Fragment",
|
|
3772
|
+
// the automatic runtime, as @react-native/babel-preset and babel-preset-expo
|
|
3773
|
+
// compile the app's own files: jsx needs no React import.
|
|
3774
|
+
jsxRuntime: "automatic",
|
|
3797
3775
|
production: true,
|
|
3798
3776
|
sourceMapOptions: { compiledFilename: input.filePath }
|
|
3799
3777
|
});
|
|
@@ -3820,6 +3798,13 @@ function compileReplacementModule(input) {
|
|
|
3820
3798
|
return name2;
|
|
3821
3799
|
};
|
|
3822
3800
|
const edits = [];
|
|
3801
|
+
const pointAtLocalModule = (specifierToken, specifier) => {
|
|
3802
|
+
edits.push({
|
|
3803
|
+
start: specifierToken.start,
|
|
3804
|
+
end: specifierToken.end,
|
|
3805
|
+
text: JSON.stringify(input.localModuleUrl(specifier))
|
|
3806
|
+
});
|
|
3807
|
+
};
|
|
3823
3808
|
for (let index = 0; index < tokens.length; index++) {
|
|
3824
3809
|
const token = tokens[index];
|
|
3825
3810
|
if (token.type === EXPORT_KEYWORD) {
|
|
@@ -3839,6 +3824,10 @@ function compileReplacementModule(input) {
|
|
|
3839
3824
|
}
|
|
3840
3825
|
if (fromAt > 0 && tokens[fromAt] && read(tokens[fromAt]) === "from" && tokens[fromAt + 1]?.type === import_types.TokenType.string) {
|
|
3841
3826
|
const specifier2 = readSpecifier(tokens[fromAt + 1]);
|
|
3827
|
+
if (isLocalSpecifier(specifier2)) {
|
|
3828
|
+
pointAtLocalModule(tokens[fromAt + 1], specifier2);
|
|
3829
|
+
continue;
|
|
3830
|
+
}
|
|
3842
3831
|
throw new Error(
|
|
3843
3832
|
`a replacement module cannot re-export from another module, and this one re-exports from '${specifier2}'. import what you need and export the binding.`
|
|
3844
3833
|
);
|
|
@@ -3891,6 +3880,10 @@ function compileReplacementModule(input) {
|
|
|
3891
3880
|
const specifierToken = tokens[cursor];
|
|
3892
3881
|
if (!specifierToken) throw new Error("replacement module import is unterminated");
|
|
3893
3882
|
const specifier = readSpecifier(specifierToken);
|
|
3883
|
+
if (isLocalSpecifier(specifier)) {
|
|
3884
|
+
pointAtLocalModule(specifierToken, specifier);
|
|
3885
|
+
continue;
|
|
3886
|
+
}
|
|
3894
3887
|
if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !isContrastKitSpecifier(specifier) && !input.runtimePackages.has(specifier)) {
|
|
3895
3888
|
throw unsupportedSpecifier(specifier);
|
|
3896
3889
|
}
|
|
@@ -3938,6 +3931,25 @@ function sendJavaScript(req, res, source) {
|
|
|
3938
3931
|
});
|
|
3939
3932
|
res.end(req.method === "HEAD" ? void 0 : source);
|
|
3940
3933
|
}
|
|
3934
|
+
function resolveLocalImport(fromFile, specifier) {
|
|
3935
|
+
const base = import_node_path5.default.resolve(import_node_path5.default.dirname(fromFile), specifier);
|
|
3936
|
+
const candidates = [
|
|
3937
|
+
...REPLACEMENT_MODULE_EXTENSIONS.some(
|
|
3938
|
+
(ext) => ext === import_node_path5.default.extname(base).toLowerCase()
|
|
3939
|
+
) ? [base] : [],
|
|
3940
|
+
...REPLACEMENT_MODULE_EXTENSIONS.map((ext) => base + ext),
|
|
3941
|
+
...REPLACEMENT_MODULE_EXTENSIONS.map((ext) => import_node_path5.default.join(base, `index${ext}`))
|
|
3942
|
+
];
|
|
3943
|
+
const found = candidates.find(
|
|
3944
|
+
(candidate) => (0, import_node_fs5.statSync)(candidate, { throwIfNoEntry: false })?.isFile()
|
|
3945
|
+
);
|
|
3946
|
+
if (!found) {
|
|
3947
|
+
throw new Error(
|
|
3948
|
+
`'${specifier}' imported by ${fromFile} matches no ${REPLACEMENT_MODULE_EXTENSIONS.join(", ")} file`
|
|
3949
|
+
);
|
|
3950
|
+
}
|
|
3951
|
+
return found;
|
|
3952
|
+
}
|
|
3941
3953
|
function isReplacementModuleRequestUrl(rawUrl) {
|
|
3942
3954
|
if (!rawUrl) return false;
|
|
3943
3955
|
try {
|
|
@@ -4028,7 +4040,14 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
4028
4040
|
const compiled = compileReplacementModule({
|
|
4029
4041
|
filePath: resolvedTargetPath,
|
|
4030
4042
|
source: await import_promises.default.readFile(resolvedTargetPath, "utf8"),
|
|
4031
|
-
runtimePackages
|
|
4043
|
+
runtimePackages,
|
|
4044
|
+
// the imported file's url is this request's with only its path changed,
|
|
4045
|
+
// so the token, cache key and runtime packages carry over.
|
|
4046
|
+
localModuleUrl: (specifier) => {
|
|
4047
|
+
const local = new URL(url.href);
|
|
4048
|
+
local.searchParams.set("path", resolveLocalImport(targetPath, specifier));
|
|
4049
|
+
return `${local.pathname}${local.search}`;
|
|
4050
|
+
}
|
|
4032
4051
|
});
|
|
4033
4052
|
const map = Buffer.from(JSON.stringify(compiled.sourceMap), "utf8").toString("base64");
|
|
4034
4053
|
sendJavaScript(
|
|
@@ -4562,8 +4581,205 @@ var import_module2 = require("module");
|
|
|
4562
4581
|
var import_node_crypto5 = require("node:crypto");
|
|
4563
4582
|
var import_path4 = __toESM(require("path"), 1);
|
|
4564
4583
|
|
|
4584
|
+
// src/native-app-identity.ts
|
|
4585
|
+
var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
|
|
4586
|
+
var METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
|
|
4587
|
+
function isRecord2(value) {
|
|
4588
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4589
|
+
}
|
|
4590
|
+
function nonEmptyString(value) {
|
|
4591
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
4592
|
+
}
|
|
4593
|
+
function createNativeAppIdentityFooter(identity) {
|
|
4594
|
+
const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
|
|
4595
|
+
return `
|
|
4596
|
+
${NATIVE_APP_IDENTITY_PREFIX}${payload};`;
|
|
4597
|
+
}
|
|
4598
|
+
function nativeAppIdentityFooterStart(source) {
|
|
4599
|
+
return source.lastIndexOf(`
|
|
4600
|
+
${NATIVE_APP_IDENTITY_PREFIX}`);
|
|
4601
|
+
}
|
|
4602
|
+
function insertNativeAppIdentityFooter(source, identity) {
|
|
4603
|
+
const existing = nativeAppIdentityFooterStart(source);
|
|
4604
|
+
const existingEnd = existing < 0 ? -1 : source.includes("\n", existing + 1) ? source.indexOf("\n", existing + 1) : -1;
|
|
4605
|
+
const withoutExisting = existing < 0 ? source : source.slice(0, existing) + source.slice(existingEnd < 0 ? source.length : existingEnd);
|
|
4606
|
+
const moduleFooter = withoutExisting.lastIndexOf(`
|
|
4607
|
+
${METRO_MODULE_PATHS_PREFIX}`);
|
|
4608
|
+
const footer = createNativeAppIdentityFooter(identity);
|
|
4609
|
+
if (moduleFooter < 0) return withoutExisting + footer;
|
|
4610
|
+
return withoutExisting.slice(0, moduleFooter) + footer + withoutExisting.slice(moduleFooter);
|
|
4611
|
+
}
|
|
4612
|
+
function plistString(plist, key) {
|
|
4613
|
+
const match = plist.match(new RegExp(`<key>${key}</key>\\s*<string>([^<]*)</string>`));
|
|
4614
|
+
return match ? match[1].trim() : null;
|
|
4615
|
+
}
|
|
4616
|
+
function resolveBuildSetting(value, settings, depth = 0) {
|
|
4617
|
+
if (depth > 8) return null;
|
|
4618
|
+
let unresolved = false;
|
|
4619
|
+
const resolved = value.replace(/\$\(([^()]+)\)/g, (_match, reference) => {
|
|
4620
|
+
const separator = reference.indexOf(":");
|
|
4621
|
+
if (separator >= 0) {
|
|
4622
|
+
unresolved = true;
|
|
4623
|
+
return "";
|
|
4624
|
+
}
|
|
4625
|
+
const replacement = settings[reference];
|
|
4626
|
+
if (replacement === void 0) {
|
|
4627
|
+
unresolved = true;
|
|
4628
|
+
return "";
|
|
4629
|
+
}
|
|
4630
|
+
return replacement;
|
|
4631
|
+
});
|
|
4632
|
+
if (unresolved) return null;
|
|
4633
|
+
if (resolved.includes("$(")) return resolveBuildSetting(resolved, settings, depth + 1);
|
|
4634
|
+
return resolved;
|
|
4635
|
+
}
|
|
4636
|
+
function resolvedIdentityField(value) {
|
|
4637
|
+
const trimmed = value?.trim() ?? "";
|
|
4638
|
+
if (!trimmed || trimmed.includes("$(")) return null;
|
|
4639
|
+
return trimmed;
|
|
4640
|
+
}
|
|
4641
|
+
function identityFieldFrom(settings, raw, fallbackSetting) {
|
|
4642
|
+
if (raw !== null) return resolvedIdentityField(resolveBuildSetting(raw, settings));
|
|
4643
|
+
return resolvedIdentityField(nonEmptyString(fallbackSetting ?? null));
|
|
4644
|
+
}
|
|
4645
|
+
function readBuildSettingsBlock(source, start) {
|
|
4646
|
+
let depth = 0;
|
|
4647
|
+
for (let index = start; index < source.length; index++) {
|
|
4648
|
+
const character = source[index];
|
|
4649
|
+
if (character === "{") depth++;
|
|
4650
|
+
else if (character === "}") {
|
|
4651
|
+
depth--;
|
|
4652
|
+
if (depth === 0) return source.slice(start, index + 1);
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
return source.slice(start);
|
|
4656
|
+
}
|
|
4657
|
+
function parseBuildSettings(block) {
|
|
4658
|
+
const settings = {};
|
|
4659
|
+
const matchPattern = /([A-Za-z0-9_]+) = ("(?:[^"\\]|\\.)*"|[^;{}]*);/g;
|
|
4660
|
+
let match;
|
|
4661
|
+
while ((match = matchPattern.exec(block)) !== null) {
|
|
4662
|
+
const raw = match[2].trim();
|
|
4663
|
+
settings[match[1]] = raw.startsWith('"') ? raw.slice(1, -1) : raw.trim();
|
|
4664
|
+
}
|
|
4665
|
+
return settings;
|
|
4666
|
+
}
|
|
4667
|
+
function appTargetReleaseSettings(pbxproj, targetName, infoPlistRelativePath) {
|
|
4668
|
+
const configurationPattern = /\/\* (Release|Debug) \*\/ = \{/g;
|
|
4669
|
+
const candidates = [];
|
|
4670
|
+
let match;
|
|
4671
|
+
while ((match = configurationPattern.exec(pbxproj)) !== null) {
|
|
4672
|
+
const blockStart = pbxproj.indexOf("{", match.index);
|
|
4673
|
+
if (blockStart < 0) continue;
|
|
4674
|
+
const block = readBuildSettingsBlock(pbxproj, blockStart);
|
|
4675
|
+
const buildSettingsStart = block.indexOf("buildSettings = {");
|
|
4676
|
+
if (buildSettingsStart < 0) continue;
|
|
4677
|
+
const settings = parseBuildSettings(
|
|
4678
|
+
readBuildSettingsBlock(block, block.indexOf("{", buildSettingsStart))
|
|
4679
|
+
);
|
|
4680
|
+
candidates.push({ name: match[1], settings });
|
|
4681
|
+
}
|
|
4682
|
+
const plistMatch = (settings) => {
|
|
4683
|
+
const plist = settings.INFOPLIST_FILE;
|
|
4684
|
+
if (!plist) return false;
|
|
4685
|
+
const normalized = plist.replace(/^"|"$/g, "");
|
|
4686
|
+
return normalized === infoPlistRelativePath || infoPlistRelativePath.endsWith(`/${normalized}`) || normalized.endsWith(`/${infoPlistRelativePath}`);
|
|
4687
|
+
};
|
|
4688
|
+
const named = (settings) => resolveBuildSetting(settings.PRODUCT_NAME ?? "", settings) === targetName;
|
|
4689
|
+
return candidates.find(
|
|
4690
|
+
(candidate) => candidate.name === "Release" && plistMatch(candidate.settings)
|
|
4691
|
+
)?.settings ?? candidates.find(
|
|
4692
|
+
(candidate) => candidate.name === "Release" && named(candidate.settings)
|
|
4693
|
+
)?.settings ?? null;
|
|
4694
|
+
}
|
|
4695
|
+
function nativeAppIdentityFromIos(files, parseInfoPlist) {
|
|
4696
|
+
const pbxprojPath = Object.keys(files).find(
|
|
4697
|
+
(path9) => /(?:^|\/)ios\/[^/]+\.xcodeproj\/project\.pbxproj$/.test(path9)
|
|
4698
|
+
);
|
|
4699
|
+
if (!pbxprojPath) return null;
|
|
4700
|
+
const pbxproj = files[pbxprojPath];
|
|
4701
|
+
const applicationTargets = new Set(
|
|
4702
|
+
[
|
|
4703
|
+
...pbxproj.matchAll(
|
|
4704
|
+
/isa = PBXNativeTarget;[^}]*?name = "?([^";]+)"?;[^}]*?productType = "com\.apple\.product-type\.application";/g
|
|
4705
|
+
)
|
|
4706
|
+
].map((match) => match[1])
|
|
4707
|
+
);
|
|
4708
|
+
const appDelegatePattern = /(?:^|\/)ios\/([^/]+)\/AppDelegate\.(?:swift|mm|m)$/;
|
|
4709
|
+
const targetName = Object.keys(files).filter((path9) => !path9.includes("/Pods/")).map((path9) => path9.match(appDelegatePattern)?.[1]).find((name2) => name2 !== void 0 && applicationTargets.has(name2)) ?? null;
|
|
4710
|
+
if (!targetName) return null;
|
|
4711
|
+
const plist = files[`ios/${targetName}/Info.plist`];
|
|
4712
|
+
if (!plist) return null;
|
|
4713
|
+
const settings = appTargetReleaseSettings(
|
|
4714
|
+
pbxproj,
|
|
4715
|
+
targetName,
|
|
4716
|
+
`${targetName}/Info.plist`
|
|
4717
|
+
);
|
|
4718
|
+
if (!settings) return null;
|
|
4719
|
+
const bundleIdentifier = identityFieldFrom(
|
|
4720
|
+
settings,
|
|
4721
|
+
plistString(plist, "CFBundleIdentifier"),
|
|
4722
|
+
settings.PRODUCT_BUNDLE_IDENTIFIER
|
|
4723
|
+
);
|
|
4724
|
+
if (!bundleIdentifier) return null;
|
|
4725
|
+
const appVersion = identityFieldFrom(
|
|
4726
|
+
settings,
|
|
4727
|
+
plistString(plist, "CFBundleShortVersionString"),
|
|
4728
|
+
settings.MARKETING_VERSION
|
|
4729
|
+
);
|
|
4730
|
+
const buildVersion = identityFieldFrom(
|
|
4731
|
+
settings,
|
|
4732
|
+
plistString(plist, "CFBundleVersion"),
|
|
4733
|
+
settings.CURRENT_PROJECT_VERSION
|
|
4734
|
+
);
|
|
4735
|
+
if (!appVersion || !buildVersion) return null;
|
|
4736
|
+
const applicationName = identityFieldFrom(settings, plistString(plist, "CFBundleDisplayName"), void 0) ?? identityFieldFrom(
|
|
4737
|
+
settings,
|
|
4738
|
+
plistString(plist, "CFBundleName"),
|
|
4739
|
+
settings.PRODUCT_NAME
|
|
4740
|
+
) ?? resolvedIdentityField(resolveBuildSetting(settings.PRODUCT_NAME ?? "", settings)) ?? resolvedIdentityField(targetName);
|
|
4741
|
+
if (!applicationName) return null;
|
|
4742
|
+
const dictionary = parseInfoPlist(plist);
|
|
4743
|
+
if (!isRecord2(dictionary)) throw new Error("native app Info.plist is not a dictionary");
|
|
4744
|
+
const permissionUsageDescriptions = {};
|
|
4745
|
+
for (const [key, value] of Object.entries(dictionary)) {
|
|
4746
|
+
if (!/^NS.*UsageDescription$/.test(key)) continue;
|
|
4747
|
+
if (typeof value !== "string") {
|
|
4748
|
+
permissionUsageDescriptions[key] = value;
|
|
4749
|
+
continue;
|
|
4750
|
+
}
|
|
4751
|
+
const resolved = resolveBuildSetting(value, settings);
|
|
4752
|
+
if (resolved === null) throw new Error(`native app Info.plist ${key} is unresolved`);
|
|
4753
|
+
permissionUsageDescriptions[key] = resolved;
|
|
4754
|
+
}
|
|
4755
|
+
if (settings.GENERATE_INFOPLIST_FILE === "YES") {
|
|
4756
|
+
for (const [setting, value] of Object.entries(settings)) {
|
|
4757
|
+
if (!/^INFOPLIST_KEY_NS.*UsageDescription$/.test(setting)) continue;
|
|
4758
|
+
const key = setting.slice("INFOPLIST_KEY_".length);
|
|
4759
|
+
const resolved = resolveBuildSetting(value, settings);
|
|
4760
|
+
if (resolved === null)
|
|
4761
|
+
throw new Error(`native app build setting ${setting} is unresolved`);
|
|
4762
|
+
permissionUsageDescriptions[key] = resolved;
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
return {
|
|
4766
|
+
applicationName,
|
|
4767
|
+
appVersion,
|
|
4768
|
+
buildVersion,
|
|
4769
|
+
bundleIdentifier,
|
|
4770
|
+
platform: "ios",
|
|
4771
|
+
permissionUsageDescriptions
|
|
4772
|
+
};
|
|
4773
|
+
}
|
|
4774
|
+
function canExtractNativeAppIdentity(platform) {
|
|
4775
|
+
return platform === "ios";
|
|
4776
|
+
}
|
|
4777
|
+
function extractNativeAppIdentityFromFiles(files, platform, parseInfoPlist) {
|
|
4778
|
+
return canExtractNativeAppIdentity(platform) ? nativeAppIdentityFromIos(files, parseInfoPlist) : null;
|
|
4779
|
+
}
|
|
4780
|
+
|
|
4565
4781
|
// src/native-firebase-config.ts
|
|
4566
|
-
var
|
|
4782
|
+
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
4567
4783
|
var import_node_module2 = require("node:module");
|
|
4568
4784
|
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
4569
4785
|
|
|
@@ -4594,7 +4810,7 @@ function readNativeFirebaseConfig(projectRoot) {
|
|
|
4594
4810
|
"app.config.ts",
|
|
4595
4811
|
"app.config.cjs",
|
|
4596
4812
|
"app.config.mjs"
|
|
4597
|
-
].some((name2) =>
|
|
4813
|
+
].some((name2) => import_node_fs6.default.existsSync(import_node_path6.default.join(projectRoot, name2))))
|
|
4598
4814
|
return result;
|
|
4599
4815
|
const require2 = (0, import_node_module2.createRequire)(import_node_path6.default.join(projectRoot, "package.json"));
|
|
4600
4816
|
const configModule = require2("@expo/config");
|
|
@@ -4610,7 +4826,7 @@ function readNativeFirebaseConfig(projectRoot) {
|
|
|
4610
4826
|
const native = config[platform];
|
|
4611
4827
|
if (!isRecord(native) || typeof native.googleServicesFile !== "string") continue;
|
|
4612
4828
|
try {
|
|
4613
|
-
const source =
|
|
4829
|
+
const source = import_node_fs6.default.readFileSync(
|
|
4614
4830
|
import_node_path6.default.resolve(projectRoot, native.googleServicesFile),
|
|
4615
4831
|
"utf8"
|
|
4616
4832
|
);
|
|
@@ -4755,7 +4971,38 @@ function withRNX(config) {
|
|
|
4755
4971
|
customSerializer: async (entryPoint, preModules, graph, serializerOptions) => {
|
|
4756
4972
|
const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot));
|
|
4757
4973
|
const result = await serializer(entryPoint, preModules, graph, serializerOptions);
|
|
4758
|
-
|
|
4974
|
+
let annotated = appendRNXModulePaths(
|
|
4975
|
+
result,
|
|
4976
|
+
graph,
|
|
4977
|
+
serializerOptions,
|
|
4978
|
+
cfgProjectRoot
|
|
4979
|
+
);
|
|
4980
|
+
const iosRoot = import_path4.default.join(cfgProjectRoot, "ios");
|
|
4981
|
+
const bundlePlatform = graph.transformOptions?.platform;
|
|
4982
|
+
if (canExtractNativeAppIdentity(bundlePlatform) && import_fs5.default.existsSync(iosRoot)) {
|
|
4983
|
+
const files = {};
|
|
4984
|
+
for (const entry of import_fs5.default.readdirSync(iosRoot, { withFileTypes: true })) {
|
|
4985
|
+
if (!entry.isDirectory() || entry.name === "Pods") continue;
|
|
4986
|
+
const names = entry.name.endsWith(".xcodeproj") ? ["project.pbxproj"] : ["Info.plist", "AppDelegate.swift", "AppDelegate.mm", "AppDelegate.m"];
|
|
4987
|
+
for (const name2 of names) {
|
|
4988
|
+
const relative2 = `ios/${entry.name}/${name2}`;
|
|
4989
|
+
const file = import_path4.default.join(cfgProjectRoot, relative2);
|
|
4990
|
+
if (import_fs5.default.existsSync(file)) files[relative2] = import_fs5.default.readFileSync(file, "utf8");
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
const identity = extractNativeAppIdentityFromFiles(
|
|
4994
|
+
files,
|
|
4995
|
+
bundlePlatform,
|
|
4996
|
+
parsePlistSource
|
|
4997
|
+
);
|
|
4998
|
+
if (identity) {
|
|
4999
|
+
annotated = typeof annotated === "string" ? insertNativeAppIdentityFooter(annotated, identity) : {
|
|
5000
|
+
...annotated,
|
|
5001
|
+
code: insertNativeAppIdentityFooter(annotated.code, identity)
|
|
5002
|
+
};
|
|
5003
|
+
}
|
|
5004
|
+
}
|
|
5005
|
+
return annotated;
|
|
4759
5006
|
}
|
|
4760
5007
|
}
|
|
4761
5008
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/kotlin-host.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -294,17 +294,27 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
|
|
|
294
294
|
"",
|
|
295
295
|
"@JsExport",
|
|
296
296
|
"fun peachAppMount(density: Float, fontScale: Float, locale: String, backend: String, stencilBits: Int,",
|
|
297
|
-
" regular: String, medium: String, bold: String, statusBar: Int, navigationBar: Int,",
|
|
297
|
+
" regular: String, medium: String, bold: String, statusBar: Int, navigationBar: Int, night: Boolean,",
|
|
298
298
|
" invalidate: (Boolean) -> Unit): String = dev.peach.app.peachStartApp(",
|
|
299
299
|
" dev.peach.app.PeachAppSpec(",
|
|
300
300
|
` android.content.ComponentName(${kotlinString(app.packageName)}, ${kotlinString(app.launcher.name)}),`,
|
|
301
301
|
` android.content.ComponentName(${kotlinString(app.packageName)}, ${kotlinString(app.launcher.targetClass)}),`,
|
|
302
|
-
|
|
302
|
+
" android.view.WindowTheme(",
|
|
303
|
+
` ${app.window.edgeToEdgeEnforced}, 0x${app.window.statusBarColor.toString(16).padStart(8, "0")}.toInt(),`,
|
|
304
|
+
` ${app.window.statusBarContrastEnforced}, ${app.window.navigationBarContrastEnforced},`,
|
|
305
|
+
` ${app.window.lightStatusBar}, ${app.window.lightNavigationBar},`,
|
|
306
|
+
" ),",
|
|
303
307
|
` { ${app.applicationClass ?? "android.app.Application"}() },`,
|
|
304
308
|
` { ${app.launcher.targetClass}() },`,
|
|
305
309
|
" ),",
|
|
306
|
-
" density, fontScale, locale, backend, stencilBits, regular, medium, bold, statusBar, navigationBar, invalidate,",
|
|
310
|
+
" density, fontScale, locale, backend, stencilBits, regular, medium, bold, statusBar, navigationBar, night, invalidate,",
|
|
307
311
|
")",
|
|
312
|
+
"",
|
|
313
|
+
"@JsExport",
|
|
314
|
+
`fun peachAppBack(): Boolean = dev.peach.app.peachAppBack(${app.predictiveBack})`,
|
|
315
|
+
"",
|
|
316
|
+
"@JsExport",
|
|
317
|
+
"fun peachAppTask(foreground: Boolean) = dev.peach.app.peachAppTask(foreground)",
|
|
308
318
|
""
|
|
309
319
|
].join("\n")
|
|
310
320
|
};
|
package/dist-lib/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|