peachsim 0.1.1406 → 0.1.1463
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 +8 -4
- package/README.md +22 -2
- package/cli/app-fonts.ts +50 -44
- package/cli/bin.ts +5 -4
- package/cli/bridge-diagnostics.ts +5 -0
- package/cli/bridge-flow-runner.ts +21 -13
- package/cli/cloud-client.ts +4 -3
- package/cli/commands/control.ts +155 -123
- package/cli/commands/daemon-mac-app.ts +3 -3
- package/cli/commands/daemon.ts +2 -2
- package/cli/commands/do-chain.ts +9 -2
- package/cli/commands/electron.ts +4 -1
- package/cli/commands/inspect/core.ts +1 -1
- package/cli/commands/inspect/settle.ts +19 -7
- package/cli/commands/inspect/settling.ts +92 -56
- package/cli/commands/inspect/wait-idle.ts +21 -9
- package/cli/commands/inspect/wait-ready.ts +22 -8
- package/cli/commands/inspect.ts +101 -134
- package/cli/commands/setup.ts +26 -16
- package/cli/commands/upgrade.ts +53 -9
- package/cli/desktop-companion.ts +1 -1
- package/cli/drivers/playwright-sim-host.ts +22 -13
- package/cli/drivers/playwright.ts +3 -3
- package/cli/main.ts +14 -5
- package/cli/outbound-endpoints.ts +1 -9
- package/detox/index.ts +6 -1
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.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 +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +3 -3
- package/dist-lib/bridge-contract.mjs +3 -3
- package/dist-lib/bundle-channel.cjs +322 -274
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +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 +1 -1
- package/dist-lib/config.mjs +1 -1
- package/dist-lib/detox/index.cjs +322 -45
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +69 -33
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +3650 -3528
- 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 +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +327 -123
- 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 +10 -5
- 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 +49 -47
- package/dist-lib/native-app-identity-project.cjs +1 -1
- package/dist-lib/native-app-identity-project.mjs +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- 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/scripts/dev-server-scanner.cjs +23 -17
- package/dist-lib/sdk.cjs +99 -61
- package/dist-lib/sdk.mjs +97 -61
- package/dist-lib/skills.cjs +2959 -2780
- package/dist-lib/swift-compile.cjs +26 -12
- package/dist-lib/swift-compile.mjs +26 -12
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +2 -2
- package/dist-lib/swift-submit.mjs +2 -2
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +66 -31
- package/dist-lib/vite.cjs +1 -1
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/kotlin/AppSources/android/view/Window.kt +2 -0
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +1 -1
- package/kotlin/ComposeSources/PeachComposeHost.kt +35 -9
- package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +2 -2
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +9 -6
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +4 -4
- package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +2 -2
- package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +22 -8
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +0 -3
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +10 -9
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +6 -5
- package/kotlin/fixtures/import-drawing/Drawing.d.kt.ts +7 -0
- package/kotlin/fixtures/import-drawing/Drawing.kt +101 -0
- package/kotlin/fixtures/import-drawing/ImportDrawing.native.tsx +18 -0
- package/kotlin/fixtures/import-drawing/README.md +34 -0
- package/kotlin/fixtures/import-drawing/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-drawing/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-drawing/package.json +23 -0
- package/kotlin/fixtures/import-drawing/tsconfig.json +20 -0
- package/kotlin/fixtures/import-drawing/vite.config.ts +20 -0
- package/kotlin/fixtures/import-scroll/ImportNested.native.tsx +10 -0
- package/kotlin/fixtures/import-scroll/Nested.d.kt.ts +4 -0
- package/kotlin/fixtures/import-scroll/README.md +15 -0
- package/kotlin/fixtures/import-scroll/app/nested+spa.tsx +1 -0
- package/kotlin/fixtures/import-values/ImportValues.native.tsx +26 -0
- package/kotlin/fixtures/import-values/README.md +6 -1
- package/kotlin/fixtures/import-values/Values.d.kt.ts +4 -0
- package/kotlin/fixtures/import-values/Values.kt +18 -0
- package/kotlin/tools/expo-types.main.kts +17 -5
- package/package.json +2 -1
- package/scripts/dev-server-scanner.ts +33 -23
- package/src/assetCatalogContract.ts +7 -0
- package/src/bridge-contract.ts +21 -3
- package/src/connect.ts +18 -5
- package/src/desktop-host-delivery.ts +33 -3
- package/src/expo-swift-host.ts +6 -3
- package/src/host/bridge-host.ts +2 -0
- package/src/host/fetch-proxy-transport.ts +8 -0
- package/src/kotlin-host.ts +11 -5
- package/src/native-firebase-config.ts +95 -54
- package/src/process-output.ts +16 -0
- package/src/sdk.ts +6 -1
- package/src/sim-client.ts +6 -1
- package/src/swift-compile.ts +36 -15
- package/src/swift-distribution.lock.json +8 -8
- package/src/swift-standin-emit.ts +10 -1
- package/src/swift-standins.ts +21 -7
- package/src/swift-submit.ts +6 -1
- /package/kotlin/fixtures/{kotlin-app-variants → import-scroll}/Nested.kt +0 -0
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1463 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -2273,7 +2273,7 @@ var init_configured_bundle_producer = __esm({
|
|
|
2273
2273
|
// src/index.ts
|
|
2274
2274
|
var src_exports = {};
|
|
2275
2275
|
__export(src_exports, {
|
|
2276
|
-
DEFAULT_SOOTSIM_BRIDGE_PORT: () =>
|
|
2276
|
+
DEFAULT_SOOTSIM_BRIDGE_PORT: () => DEFAULT_SOOTSIM_BRIDGE_PORT2,
|
|
2277
2277
|
DEFAULT_SOOTSIM_BRIDGE_URL: () => DEFAULT_SOOTSIM_BRIDGE_URL,
|
|
2278
2278
|
DEFAULT_SOOTSIM_SHELL_URL: () => DEFAULT_SOOTSIM_SHELL_URL,
|
|
2279
2279
|
RNX_SCREEN_CAPTURE_VERSION: () => RNX_SCREEN_CAPTURE_VERSION,
|
|
@@ -2302,11 +2302,31 @@ module.exports = __toCommonJS(src_exports);
|
|
|
2302
2302
|
// cli/cloud-client.ts
|
|
2303
2303
|
var import_node_crypto = require("node:crypto");
|
|
2304
2304
|
|
|
2305
|
+
// ../peach-engine/src/tenant-bundle-mode.ts
|
|
2306
|
+
var import_metro_production_bundle = require("peachsim/metro-production-bundle");
|
|
2307
|
+
|
|
2308
|
+
// ../peach-engine/src/development-mode.ts
|
|
2309
|
+
var bridgeConstants = __toESM(require("peachsim/bridge-constants"), 1);
|
|
2310
|
+
|
|
2311
|
+
// ../peach-engine/src/tenant-runtime-environment.ts
|
|
2312
|
+
function readBrowserLocation() {
|
|
2313
|
+
try {
|
|
2314
|
+
return typeof location === "undefined" ? null : location;
|
|
2315
|
+
} catch {
|
|
2316
|
+
return null;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
var nativeRuntimeLocation = readBrowserLocation();
|
|
2320
|
+
|
|
2321
|
+
// ../peach-engine/src/development-mode.ts
|
|
2322
|
+
var { DEFAULT_SOOTSIM_BRIDGE_PORT } = bridgeConstants;
|
|
2323
|
+
var DAEMON_RUNTIME_PORT_MAX = DEFAULT_SOOTSIM_BRIDGE_PORT + 10;
|
|
2324
|
+
|
|
2305
2325
|
// ../peach-engine/src/metro-fingerprint-registry-client.ts
|
|
2306
2326
|
var import_metro_fingerprint_registry = require("peachsim/metro-fingerprint-registry");
|
|
2307
2327
|
|
|
2308
2328
|
// ../peach-engine/src/metro-fingerprint.ts
|
|
2309
|
-
var
|
|
2329
|
+
var import_metro_production_bundle2 = require("peachsim/metro-production-bundle");
|
|
2310
2330
|
var import_react_native_host_modules = require("peachsim/react-native-host-modules");
|
|
2311
2331
|
|
|
2312
2332
|
// cli/cloud-client.ts
|
|
@@ -5528,8 +5548,8 @@ var import_node_path3 = __toESM(require("node:path"), 1);
|
|
|
5528
5548
|
var import_ws = require("ws");
|
|
5529
5549
|
|
|
5530
5550
|
// src/bridge-constants.ts
|
|
5531
|
-
var
|
|
5532
|
-
var DEFAULT_SOOTSIM_BRIDGE_URL = `http://localhost:${
|
|
5551
|
+
var DEFAULT_SOOTSIM_BRIDGE_PORT2 = 7668;
|
|
5552
|
+
var DEFAULT_SOOTSIM_BRIDGE_URL = `http://localhost:${DEFAULT_SOOTSIM_BRIDGE_PORT2}/`;
|
|
5533
5553
|
function parsePort(value) {
|
|
5534
5554
|
if (typeof value === "number") {
|
|
5535
5555
|
return Number.isInteger(value) && value > 0 ? value : null;
|
|
@@ -5547,7 +5567,7 @@ function parsePortOffset(value) {
|
|
|
5547
5567
|
function resolveSootsimBridgePort(input = {}) {
|
|
5548
5568
|
const explicitPort = parsePort(input.explicitPort);
|
|
5549
5569
|
if (explicitPort !== null) return explicitPort;
|
|
5550
|
-
return
|
|
5570
|
+
return DEFAULT_SOOTSIM_BRIDGE_PORT2 + parsePortOffset(input.portOffset);
|
|
5551
5571
|
}
|
|
5552
5572
|
var HOSTED_SHELL_PATH = new RegExp(`^(?:${PEACH_SIMULATOR_PATH}|/sootsim)(?:/|$)`);
|
|
5553
5573
|
var AUTOMATION_SIM_IDLE_REAP_TTL_MS = 5 * 6e4;
|
|
@@ -5600,11 +5620,11 @@ function resolveDefaultDevBridgeLockfile() {
|
|
|
5600
5620
|
});
|
|
5601
5621
|
if (sameCheckout.length > 0) {
|
|
5602
5622
|
return sameCheckout.find(
|
|
5603
|
-
(lockfile) => lockfile.bridgePort ===
|
|
5623
|
+
(lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT2
|
|
5604
5624
|
) ?? sameCheckout[0];
|
|
5605
5625
|
}
|
|
5606
5626
|
}
|
|
5607
|
-
return lockfiles.find((lockfile) => lockfile.bridgePort ===
|
|
5627
|
+
return lockfiles.find((lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT2) ?? null;
|
|
5608
5628
|
}
|
|
5609
5629
|
function resolveBridgeWorld() {
|
|
5610
5630
|
const homeDir = rnxHomeDir();
|
|
@@ -5643,6 +5663,33 @@ function resolveBridgeWorldFresh() {
|
|
|
5643
5663
|
shellBaseUrl: DEFAULT_SOOTSIM_SHELL_URL
|
|
5644
5664
|
};
|
|
5645
5665
|
}
|
|
5666
|
+
function worldForBridgePort(port) {
|
|
5667
|
+
const dev = liveDevBridgeLockfiles().find((lockfile) => lockfile.bridgePort === port);
|
|
5668
|
+
if (dev) {
|
|
5669
|
+
return {
|
|
5670
|
+
source: "dev-bridge",
|
|
5671
|
+
shellBaseUrl: dev.shellPort ? `http://localhost:${dev.shellPort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
5672
|
+
};
|
|
5673
|
+
}
|
|
5674
|
+
const lock = readDaemonLockfile();
|
|
5675
|
+
if (lock && isDaemonLockfileFresh(lock) && lock.bridgePort === port) {
|
|
5676
|
+
return {
|
|
5677
|
+
source: "daemon",
|
|
5678
|
+
shellBaseUrl: lock.runtimePort > 0 ? `http://localhost:${lock.runtimePort}/` : DEFAULT_SOOTSIM_SHELL_URL
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5681
|
+
return null;
|
|
5682
|
+
}
|
|
5683
|
+
function printBridgeWorldNotice(bridgePort, shellBaseUrl) {
|
|
5684
|
+
const world = worldForBridgePort(bridgePort);
|
|
5685
|
+
const kind = world?.source === "dev-bridge" ? "dev bridge" : world?.source === "daemon" ? "daemon bridge" : "bridge";
|
|
5686
|
+
const origin = world?.source === "dev-bridge" ? `dev-bridges/${bridgePort}.json` : world?.source === "daemon" ? "daemon.json" : "no lockfile";
|
|
5687
|
+
const shell = shellBaseUrl ?? world?.shellBaseUrl;
|
|
5688
|
+
process.stderr.write(
|
|
5689
|
+
` \u2192 ${kind} :${bridgePort} (${shell ? `shell ${shell}, ` : ""}${origin})
|
|
5690
|
+
`
|
|
5691
|
+
);
|
|
5692
|
+
}
|
|
5646
5693
|
var BridgeSimLockedError = class extends Error {
|
|
5647
5694
|
lock;
|
|
5648
5695
|
constructor(message, lock) {
|
|
@@ -5936,6 +5983,120 @@ function createBridge(wsPort, opts = {}) {
|
|
|
5936
5983
|
}
|
|
5937
5984
|
};
|
|
5938
5985
|
}
|
|
5986
|
+
function createBridgeFromParsed(parsed) {
|
|
5987
|
+
const cloudBridge = createCloudBridgeForParsed(parsed);
|
|
5988
|
+
if (cloudBridge) return cloudBridge;
|
|
5989
|
+
const options = {
|
|
5990
|
+
commandTimeoutMs: parsed.commandTimeoutMs,
|
|
5991
|
+
simId: parsed.simId,
|
|
5992
|
+
simIdSource: parsed.simIdSource
|
|
5993
|
+
};
|
|
5994
|
+
if (!parsed.simId || parsed.simIdSource !== "flag") {
|
|
5995
|
+
return createBridge(parsed.wsPort, options);
|
|
5996
|
+
}
|
|
5997
|
+
let selected;
|
|
5998
|
+
let closed = false;
|
|
5999
|
+
const getBridge = () => {
|
|
6000
|
+
selected ??= resolveBridgePortForSim(parsed).then((port) => {
|
|
6001
|
+
if (closed) throw new Error("bridge closed during sim world resolution");
|
|
6002
|
+
parsed.wsPort = port;
|
|
6003
|
+
printBridgeWorldNotice(port);
|
|
6004
|
+
return createBridge(port, options);
|
|
6005
|
+
});
|
|
6006
|
+
return selected;
|
|
6007
|
+
};
|
|
6008
|
+
return {
|
|
6009
|
+
plane: "local",
|
|
6010
|
+
async send(cmd, opts) {
|
|
6011
|
+
return (await getBridge()).send(cmd, opts);
|
|
6012
|
+
},
|
|
6013
|
+
async listSims() {
|
|
6014
|
+
return (await getBridge()).listSims();
|
|
6015
|
+
},
|
|
6016
|
+
async resolveReloadedSim(id) {
|
|
6017
|
+
return (await getBridge()).resolveReloadedSim(id);
|
|
6018
|
+
},
|
|
6019
|
+
async focusSim(id) {
|
|
6020
|
+
return (await getBridge()).focusSim(id);
|
|
6021
|
+
},
|
|
6022
|
+
async closeSim(id) {
|
|
6023
|
+
return (await getBridge()).closeSim(id);
|
|
6024
|
+
},
|
|
6025
|
+
async claim(id, opts) {
|
|
6026
|
+
return (await getBridge()).claim(id, opts);
|
|
6027
|
+
},
|
|
6028
|
+
close() {
|
|
6029
|
+
closed = true;
|
|
6030
|
+
void selected?.then(
|
|
6031
|
+
(bridge) => bridge.close(),
|
|
6032
|
+
() => {
|
|
6033
|
+
}
|
|
6034
|
+
);
|
|
6035
|
+
}
|
|
6036
|
+
};
|
|
6037
|
+
}
|
|
6038
|
+
async function resolveBridgePortForSim(parsed) {
|
|
6039
|
+
const worlds = liveDevBridgeLockfiles().map((lock) => ({
|
|
6040
|
+
port: lock.bridgePort,
|
|
6041
|
+
record: `dev-bridges/${lock.bridgePort}.json`
|
|
6042
|
+
}));
|
|
6043
|
+
const daemon = readDaemonLockfile();
|
|
6044
|
+
if (daemon && isDaemonLockfileFresh(daemon)) {
|
|
6045
|
+
worlds.push({ port: daemon.bridgePort, record: "daemon.json" });
|
|
6046
|
+
}
|
|
6047
|
+
if (parsed.explicitPort && !worlds.some((world) => world.port === parsed.wsPort)) {
|
|
6048
|
+
worlds.push({ port: parsed.wsPort, record: "--port" });
|
|
6049
|
+
}
|
|
6050
|
+
const checked = await Promise.all(
|
|
6051
|
+
worlds.map(async (world) => {
|
|
6052
|
+
const probe = createBridge(world.port, {
|
|
6053
|
+
connectTimeoutMs: 2e3,
|
|
6054
|
+
commandTimeoutMs: 2e3
|
|
6055
|
+
});
|
|
6056
|
+
try {
|
|
6057
|
+
const sims = await probe.listSims();
|
|
6058
|
+
return {
|
|
6059
|
+
...world,
|
|
6060
|
+
ownsSim: sims.some(
|
|
6061
|
+
(sim) => sim.id === parsed.simId && sim.readyState === "open"
|
|
6062
|
+
)
|
|
6063
|
+
};
|
|
6064
|
+
} catch (error) {
|
|
6065
|
+
return {
|
|
6066
|
+
...world,
|
|
6067
|
+
ownsSim: false,
|
|
6068
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6069
|
+
};
|
|
6070
|
+
} finally {
|
|
6071
|
+
probe.close();
|
|
6072
|
+
}
|
|
6073
|
+
})
|
|
6074
|
+
);
|
|
6075
|
+
const owners = checked.filter((world) => world.ownsSim);
|
|
6076
|
+
if (parsed.explicitPort) {
|
|
6077
|
+
if (owners.some((world) => world.port === parsed.wsPort)) return parsed.wsPort;
|
|
6078
|
+
if (owners.length > 0) {
|
|
6079
|
+
throw new Error(
|
|
6080
|
+
`--sim ${parsed.simId} belongs to bridge port ${owners[0].port}, but --port ${parsed.wsPort} names another world`
|
|
6081
|
+
);
|
|
6082
|
+
}
|
|
6083
|
+
}
|
|
6084
|
+
if (owners.length === 0) {
|
|
6085
|
+
const names = checked.map(
|
|
6086
|
+
(world) => `${world.record} (bridge :${world.port}${"error" in world ? `, ${world.error}` : ""})`
|
|
6087
|
+
);
|
|
6088
|
+
throw new Error(
|
|
6089
|
+
`no live peach world holds sim ${parsed.simId}; worlds checked: ${names.join(", ") || "none (no fresh dev-bridge or daemon lockfiles)"}`
|
|
6090
|
+
);
|
|
6091
|
+
}
|
|
6092
|
+
if (owners.length > 1) {
|
|
6093
|
+
const candidates = owners.map((w) => `${w.record} (:${w.port})`).join(", ");
|
|
6094
|
+
throw new Error(
|
|
6095
|
+
`sim ${parsed.simId} exists in multiple worlds (${candidates}); pin one with --port`
|
|
6096
|
+
);
|
|
6097
|
+
}
|
|
6098
|
+
return owners[0].port;
|
|
6099
|
+
}
|
|
5939
6100
|
|
|
5940
6101
|
// src/bridge-contract.ts
|
|
5941
6102
|
var HEADLESS_TENANT_FETCH_HUNG_MARKER = "headless tenant fetch hung";
|
|
@@ -6765,6 +6926,18 @@ var RuntimeReadinessUnsupportedError = class extends Error {
|
|
|
6765
6926
|
}
|
|
6766
6927
|
code = "runtime_readiness_unsupported";
|
|
6767
6928
|
};
|
|
6929
|
+
var IdleObservationError = class extends Error {
|
|
6930
|
+
constructor(elapsedMs, failure) {
|
|
6931
|
+
const detail = failure instanceof Error ? failure.message : String(failure);
|
|
6932
|
+
super(`idle observation failed after ${elapsedMs}ms: ${detail}`, {
|
|
6933
|
+
cause: failure
|
|
6934
|
+
});
|
|
6935
|
+
this.elapsedMs = elapsedMs;
|
|
6936
|
+
this.failure = failure;
|
|
6937
|
+
this.name = "IdleObservationError";
|
|
6938
|
+
}
|
|
6939
|
+
code = "idle_observation_failed";
|
|
6940
|
+
};
|
|
6768
6941
|
async function waitForSootsimIdle({
|
|
6769
6942
|
bridge,
|
|
6770
6943
|
simId,
|
|
@@ -6775,6 +6948,7 @@ async function waitForSootsimIdle({
|
|
|
6775
6948
|
paintStill = false
|
|
6776
6949
|
}) {
|
|
6777
6950
|
let result;
|
|
6951
|
+
const observationStartedAt = Date.now();
|
|
6778
6952
|
try {
|
|
6779
6953
|
result = await bridge.send(
|
|
6780
6954
|
{
|
|
@@ -6805,27 +6979,23 @@ async function waitForSootsimIdle({
|
|
|
6805
6979
|
let screenPixels = null
|
|
6806
6980
|
try {
|
|
6807
6981
|
|
|
6808
|
-
//
|
|
6809
|
-
//
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
// transition FIRST, bounded by the overall budget. when no
|
|
6814
|
-
// transition is happening this returns in ~80ms (startWindowMs), so
|
|
6815
|
-
// a plain button tap barely pays for it.
|
|
6816
|
-
try {
|
|
6817
|
-
const wfst = window.__sootsimTest?.waitForScreenTransitions
|
|
6818
|
-
if (typeof wfst === 'function') {
|
|
6982
|
+
// discover transitions while observing layout. when motion starts,
|
|
6983
|
+
// observations from before its completion cannot prove the new screen.
|
|
6984
|
+
let transitionWait = (async () => {
|
|
6985
|
+
try {
|
|
6986
|
+
const wfst = window.__sootsimTest?.waitForScreenTransitions
|
|
6819
6987
|
const remaining = deadline - Date.now()
|
|
6820
|
-
if (remaining > 120) {
|
|
6821
|
-
await wfst({
|
|
6988
|
+
if (typeof wfst === 'function' && remaining > 120) {
|
|
6989
|
+
const transition = await wfst({
|
|
6822
6990
|
timeoutMs: Math.min(remaining - 80, 4000),
|
|
6823
6991
|
settleMs: 64,
|
|
6824
6992
|
startWindowMs: 80,
|
|
6825
6993
|
})
|
|
6994
|
+
return transition?.started === true
|
|
6826
6995
|
}
|
|
6827
|
-
}
|
|
6828
|
-
|
|
6996
|
+
} catch {}
|
|
6997
|
+
return false
|
|
6998
|
+
})()
|
|
6829
6999
|
|
|
6830
7000
|
// a worker that cannot answer within the remaining budget is busy, not
|
|
6831
7001
|
// idle: its poll reads as unsettled. bounding each read by the budget
|
|
@@ -6850,17 +7020,51 @@ async function waitForSootsimIdle({
|
|
|
6850
7020
|
let nodeCount = null
|
|
6851
7021
|
let renderStatsAvailable = false
|
|
6852
7022
|
let shellAnimating = false
|
|
7023
|
+
let shellBlockers = ''
|
|
6853
7024
|
let webViewStarting = false
|
|
6854
7025
|
let webViewBlocker = ''
|
|
7026
|
+
// the reads are independent, so they run concurrently: a loaded sim
|
|
7027
|
+
// answers each one late, and a poll that waits for them in turn
|
|
7028
|
+
// costs their sum, which fits too few polls in the budget to settle.
|
|
6855
7029
|
// strict also waits out shell motion: a system alert, sheet or menu
|
|
6856
7030
|
// animates in the shell worker while the app's own stats read still,
|
|
6857
7031
|
// so its presentation is complete only once the shell's list empties.
|
|
6858
|
-
|
|
6859
|
-
|
|
7032
|
+
const motionRead = strict
|
|
7033
|
+
? answer(() => window.__sootsimTest?.listAnimations?.()).catch(() => null)
|
|
7034
|
+
: null
|
|
7035
|
+
const statsRead = answer(() => window.__sootsimRenderHost?.queryStats?.()).catch(() => null)
|
|
7036
|
+
// image preparation ends in the tenant before the compositor decodes
|
|
7037
|
+
// and realizes its pixels. both owners must finish before settling.
|
|
7038
|
+
// the compositor rejects a stats request it is too busy to answer.
|
|
7039
|
+
const compositorRead = answer(() => window.__sootsimCompositor.getStats()).catch(() => BUSY)
|
|
7040
|
+
const countsRead = Promise.resolve().then(() => window.__sootsimTest?.getRequestCounts?.()).catch(() => null)
|
|
7041
|
+
// mounted-root membership: the live node count moves while the tree
|
|
7042
|
+
// mounts, unmounts or recycles, in either render mode.
|
|
7043
|
+
const nodeCountRead = Promise.resolve().then(() => window.__sootsimTest?.getNodeCount?.()).catch(() => null)
|
|
7044
|
+
// the mounted hierarchy in render-worker mode comes from the test
|
|
7045
|
+
// bridge: window.__sootsimRoot is an empty placeholder there, so a
|
|
7046
|
+
// walk over it hashes every screen to the same empty string while
|
|
7047
|
+
// it moves. listInspectable is the worker-backed read describe
|
|
7048
|
+
// uses; a worker too busy to answer it reads as unsettled. tight
|
|
7049
|
+
// budgets skip this read and settle on the cheaper signals above.
|
|
7050
|
+
const hierarchyRead =
|
|
7051
|
+
fullGeometry && typeof window.__sootsimTest?.listInspectable === 'function'
|
|
7052
|
+
? answer(() => window.__sootsimTest.listInspectable({})).catch(() => null)
|
|
7053
|
+
: null
|
|
7054
|
+
if (motionRead) {
|
|
7055
|
+
const motion = await motionRead
|
|
6860
7056
|
if (motion === BUSY) workerBusy = true
|
|
6861
|
-
else
|
|
7057
|
+
else if (Array.isArray(motion)) {
|
|
7058
|
+
const blocking = motion.filter((anim) => anim.realm === 'shell' && anim.priority !== 'low')
|
|
7059
|
+
shellAnimating = blocking.length > 0
|
|
7060
|
+
// name what holds the settle so a timeout points at its owner.
|
|
7061
|
+
shellBlockers = blocking
|
|
7062
|
+
.slice(0, 4)
|
|
7063
|
+
.map((anim) => anim.source + '/' + anim.kind + '#' + anim.id + ' at ' + anim.current + (anim.loop ? ' loop' : ''))
|
|
7064
|
+
.join(', ')
|
|
7065
|
+
}
|
|
6862
7066
|
}
|
|
6863
|
-
const stats = await
|
|
7067
|
+
const stats = await statsRead
|
|
6864
7068
|
if (stats === BUSY) {
|
|
6865
7069
|
workerBusy = true
|
|
6866
7070
|
} else if (stats) {
|
|
@@ -6897,10 +7101,7 @@ async function waitForSootsimIdle({
|
|
|
6897
7101
|
// mounting or remounting, even with no animation flag raised.
|
|
6898
7102
|
appCommits = typeof stats.appCommitCount === 'number' ? stats.appCommitCount : null
|
|
6899
7103
|
}
|
|
6900
|
-
|
|
6901
|
-
// and realizes its pixels. both owners must finish before settling.
|
|
6902
|
-
// the compositor rejects a stats request it is too busy to answer.
|
|
6903
|
-
const compositor = await answer(() => window.__sootsimCompositor.getStats()).catch(() => BUSY)
|
|
7104
|
+
const compositor = await compositorRead
|
|
6904
7105
|
if (compositor === BUSY) {
|
|
6905
7106
|
workerBusy = true
|
|
6906
7107
|
} else {
|
|
@@ -6911,31 +7112,12 @@ async function waitForSootsimIdle({
|
|
|
6911
7112
|
webViewBlocker = 'compositor webView capture not settled'
|
|
6912
7113
|
}
|
|
6913
7114
|
}
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
// mounts, unmounts or recycles, in either render mode.
|
|
6921
|
-
try {
|
|
6922
|
-
const total = await window.__sootsimTest?.getNodeCount?.()
|
|
6923
|
-
nodeCount = typeof total === 'number' ? total : null
|
|
6924
|
-
} catch {}
|
|
6925
|
-
// the mounted hierarchy in render-worker mode comes from the test
|
|
6926
|
-
// bridge: window.__sootsimRoot is an empty placeholder there, so a
|
|
6927
|
-
// walk over it hashes every screen to the same empty string while
|
|
6928
|
-
// it moves. listInspectable is the worker-backed read describe
|
|
6929
|
-
// uses; a worker too busy to answer it reads as unsettled. tight
|
|
6930
|
-
// budgets skip this read and settle on the cheaper signals above.
|
|
6931
|
-
let hierarchy = null
|
|
6932
|
-
if (fullGeometry && typeof window.__sootsimTest?.listInspectable === 'function') {
|
|
6933
|
-
try {
|
|
6934
|
-
hierarchy = await answer(() => window.__sootsimTest.listInspectable({}))
|
|
6935
|
-
} catch {
|
|
6936
|
-
hierarchy = null
|
|
6937
|
-
}
|
|
6938
|
-
}
|
|
7115
|
+
const counts = await countsRead
|
|
7116
|
+
requestTotal = typeof counts?.total === 'number' ? counts.total : 0
|
|
7117
|
+
requestInFlight = typeof counts?.inFlight === 'number' ? counts.inFlight : 0
|
|
7118
|
+
const total = await nodeCountRead
|
|
7119
|
+
nodeCount = typeof total === 'number' ? total : null
|
|
7120
|
+
let hierarchy = hierarchyRead ? await hierarchyRead : null
|
|
6939
7121
|
if (hierarchy === BUSY) {
|
|
6940
7122
|
workerBusy = true
|
|
6941
7123
|
hierarchy = null
|
|
@@ -7011,7 +7193,7 @@ async function waitForSootsimIdle({
|
|
|
7011
7193
|
pixelFrameToken = token
|
|
7012
7194
|
}
|
|
7013
7195
|
}
|
|
7014
|
-
return { layout: nodes.join(';'), screenPixels, animating, shellAnimating, layoutDirty, pendingFetches, workerBusy, webViewStarting, webViewBlocker, renderStatsAvailable, requestTotal, requestInFlight, appCommits, nodeCount }
|
|
7196
|
+
return { layout: nodes.join(';'), screenPixels, animating, shellAnimating, shellBlockers, layoutDirty, pendingFetches, workerBusy, webViewStarting, webViewBlocker, renderStatsAvailable, requestTotal, requestInFlight, appCommits, nodeCount }
|
|
7015
7197
|
}
|
|
7016
7198
|
|
|
7017
7199
|
// how long generic background network is allowed to keep us waiting AFTER
|
|
@@ -7098,6 +7280,19 @@ async function waitForSootsimIdle({
|
|
|
7098
7280
|
Date.now() - visuallyStillSince >= requiredStillMs &&
|
|
7099
7281
|
(networkQuiet || Date.now() - visuallyStillSince >= networkQuietGraceMs)
|
|
7100
7282
|
) {
|
|
7283
|
+
if (transitionWait) {
|
|
7284
|
+
const started = await transitionWait
|
|
7285
|
+
transitionWait = null
|
|
7286
|
+
if (started) {
|
|
7287
|
+
lastLayout = ''
|
|
7288
|
+
lastRequestTotal = -1
|
|
7289
|
+
lastAppCommits = null
|
|
7290
|
+
lastNodeCount = null
|
|
7291
|
+
stable = 0
|
|
7292
|
+
visuallyStillSince = 0
|
|
7293
|
+
continue
|
|
7294
|
+
}
|
|
7295
|
+
}
|
|
7101
7296
|
return { settled: true, elapsed: Date.now() - start, blockedBy: '' }
|
|
7102
7297
|
}
|
|
7103
7298
|
} else {
|
|
@@ -7116,7 +7311,7 @@ async function waitForSootsimIdle({
|
|
|
7116
7311
|
const blockers = []
|
|
7117
7312
|
if (strict && !last.renderStatsAvailable) blockers.push('render stats unavailable')
|
|
7118
7313
|
if (last.animating) blockers.push('animations still running')
|
|
7119
|
-
if (last.shellAnimating) blockers.push('shell animations still running')
|
|
7314
|
+
if (last.shellAnimating) blockers.push('shell animations still running (' + last.shellBlockers + ')')
|
|
7120
7315
|
if (last.layoutDirty) blockers.push('layout still dirty')
|
|
7121
7316
|
if (last.appCommits !== null && lastAppCommits !== null && last.appCommits !== lastAppCommits) blockers.push('layout commits still landing')
|
|
7122
7317
|
if (last.nodeCount !== null && lastNodeCount !== null && last.nodeCount !== lastNodeCount) blockers.push('node count still changing')
|
|
@@ -7147,12 +7342,7 @@ async function waitForSootsimIdle({
|
|
|
7147
7342
|
}
|
|
7148
7343
|
);
|
|
7149
7344
|
} catch (error) {
|
|
7150
|
-
|
|
7151
|
-
return {
|
|
7152
|
-
settled: false,
|
|
7153
|
-
elapsed: maxMs,
|
|
7154
|
-
blockedBy: message
|
|
7155
|
-
};
|
|
7345
|
+
throw new IdleObservationError(Math.max(0, Date.now() - observationStartedAt), error);
|
|
7156
7346
|
}
|
|
7157
7347
|
if (result?.error === "runtime_readiness_unsupported" && typeof result.runtimeVersion === "string" && Array.isArray(result.missingFields) && result.missingFields.every((field) => typeof field === "string")) {
|
|
7158
7348
|
throw new RuntimeReadinessUnsupportedError(
|
|
@@ -7719,7 +7909,12 @@ var SimClient = class {
|
|
|
7719
7909
|
if (!status.ready) throw new SimReadyTimeoutError(status);
|
|
7720
7910
|
return status;
|
|
7721
7911
|
}
|
|
7722
|
-
/**
|
|
7912
|
+
/**
|
|
7913
|
+
* wait for layout/animation/transition settle after an interaction.
|
|
7914
|
+
* a still-busy guest returns settled false with its own elapsed time.
|
|
7915
|
+
* a failed idle read throws IdleObservationError with the host elapsed
|
|
7916
|
+
* time and the original failure.
|
|
7917
|
+
*/
|
|
7723
7918
|
settle(opts = {}) {
|
|
7724
7919
|
return waitForSootsimIdle({
|
|
7725
7920
|
bridge: this,
|
|
@@ -8028,12 +8223,19 @@ async function connect(options = {}) {
|
|
|
8028
8223
|
commandTimeoutMs: options.timeoutMs ?? 15e3
|
|
8029
8224
|
});
|
|
8030
8225
|
}
|
|
8031
|
-
const port = options.port ?? resolveBridgeWorld().bridgePort;
|
|
8032
8226
|
const commandTimeoutMs = options.timeoutMs ?? 15e3;
|
|
8033
|
-
const
|
|
8227
|
+
const parsed = {
|
|
8228
|
+
...target,
|
|
8229
|
+
wsPort: options.port ?? resolveBridgeWorld().bridgePort,
|
|
8230
|
+
explicitPort: options.port !== void 0,
|
|
8231
|
+
commandTimeoutMs,
|
|
8232
|
+
positional: []
|
|
8233
|
+
};
|
|
8234
|
+
const discovery = createBridgeFromParsed(parsed);
|
|
8034
8235
|
let picked;
|
|
8035
8236
|
try {
|
|
8036
|
-
|
|
8237
|
+
const sims = await discovery.listSims();
|
|
8238
|
+
picked = pickSim(sims, options.sim, parsed.wsPort);
|
|
8037
8239
|
} catch (error) {
|
|
8038
8240
|
discovery.close();
|
|
8039
8241
|
if (error instanceof SimConnectError) throw error;
|
|
@@ -8041,7 +8243,7 @@ async function connect(options = {}) {
|
|
|
8041
8243
|
throw new SimConnectError(`${message} \u2014 is the Peach daemon or dev shell running?`);
|
|
8042
8244
|
}
|
|
8043
8245
|
discovery.close();
|
|
8044
|
-
const bridge = createBridge(
|
|
8246
|
+
const bridge = createBridge(parsed.wsPort, {
|
|
8045
8247
|
commandTimeoutMs,
|
|
8046
8248
|
cliLabel: "sdk",
|
|
8047
8249
|
simId: picked.id,
|
|
@@ -9095,7 +9297,7 @@ function peachPlugin(options = {}) {
|
|
|
9095
9297
|
const buildShellHtml = (runtimeRoot) => {
|
|
9096
9298
|
const html = import_fs4.default.readFileSync(import_path3.default.join(runtimeRoot, "index.html"), "utf8");
|
|
9097
9299
|
const lock = readDaemonLockfile();
|
|
9098
|
-
const bridgePort = lock && isDaemonLockfileFresh(lock) && lock.bridgePort > 0 ? lock.bridgePort :
|
|
9300
|
+
const bridgePort = lock && isDaemonLockfileFresh(lock) && lock.bridgePort > 0 ? lock.bridgePort : DEFAULT_SOOTSIM_BRIDGE_PORT2;
|
|
9099
9301
|
const inject = `<script>(function(){var u=new URL(location.href);if(!u.searchParams.has('bundle'))u.searchParams.set('bundle',${JSON.stringify(bundleForPort(listeningPort()))});window.__sootsimBridgePort=${bridgePort};history.replaceState(null,'','${prefix2}/'+u.search)})()</script>`;
|
|
9100
9302
|
return html.replace("</head>", inject + "</head>");
|
|
9101
9303
|
};
|
|
@@ -10123,14 +10325,14 @@ function workspaceReferences(workspace) {
|
|
|
10123
10325
|
if (!import_node_fs9.default.existsSync(data))
|
|
10124
10326
|
throw new Error(`${workspace} has no contents.xcworkspacedata`);
|
|
10125
10327
|
const container = import_node_path10.default.dirname(workspace);
|
|
10126
|
-
const locate = (
|
|
10127
|
-
const colon =
|
|
10128
|
-
const kind =
|
|
10129
|
-
const rest =
|
|
10328
|
+
const locate = (location2, base) => {
|
|
10329
|
+
const colon = location2.indexOf(":");
|
|
10330
|
+
const kind = location2.slice(0, colon);
|
|
10331
|
+
const rest = location2.slice(colon + 1);
|
|
10130
10332
|
if (kind === "group") return import_node_path10.default.resolve(base, rest);
|
|
10131
10333
|
if (kind === "container" || kind === "self") return import_node_path10.default.resolve(container, rest);
|
|
10132
10334
|
if (kind === "absolute") return import_node_path10.default.resolve(rest);
|
|
10133
|
-
throw new Error(`${import_node_path10.default.basename(workspace)} has an unsupported location ${
|
|
10335
|
+
throw new Error(`${import_node_path10.default.basename(workspace)} has an unsupported location ${location2}`);
|
|
10134
10336
|
};
|
|
10135
10337
|
const groups = [container];
|
|
10136
10338
|
const references = [];
|
|
@@ -10140,8 +10342,8 @@ function workspaceReferences(workspace) {
|
|
|
10140
10342
|
continue;
|
|
10141
10343
|
}
|
|
10142
10344
|
const base = groups.at(-1);
|
|
10143
|
-
const
|
|
10144
|
-
const resolved =
|
|
10345
|
+
const location2 = /\blocation\s*=\s*"([^"]*)"/.exec(attributes)?.[1];
|
|
10346
|
+
const resolved = location2 ? locate(decodeXml(location2), base) : base;
|
|
10145
10347
|
if (tag === "FileRef") references.push(resolved);
|
|
10146
10348
|
else if (!selfClosing) groups.push(resolved);
|
|
10147
10349
|
}
|
|
@@ -10842,59 +11044,61 @@ var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
|
10842
11044
|
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
10843
11045
|
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
10844
11046
|
init_is_record();
|
|
10845
|
-
|
|
10846
|
-
const result = {};
|
|
10847
|
-
let config = {};
|
|
10848
|
-
const appJsonPath = import_node_path12.default.join(projectRoot, "app.json");
|
|
10849
|
-
const appJson = import_node_fs11.default.existsSync(appJsonPath) ? JSON.parse(import_node_fs11.default.readFileSync(appJsonPath, "utf8")) : null;
|
|
10850
|
-
const staticExpo = isRecord(appJson) && (isRecord(appJson.expo) || [appJson.ios, appJson.android].some(
|
|
10851
|
-
(value) => isRecord(value) && typeof value.googleServicesFile === "string"
|
|
10852
|
-
));
|
|
10853
|
-
const dynamicExpo = [
|
|
10854
|
-
"app.config.js",
|
|
10855
|
-
"app.config.ts",
|
|
10856
|
-
"app.config.cjs",
|
|
10857
|
-
"app.config.mjs"
|
|
10858
|
-
].some((name2) => import_node_fs11.default.existsSync(import_node_path12.default.join(projectRoot, name2)));
|
|
10859
|
-
if (staticExpo || dynamicExpo) {
|
|
10860
|
-
const directory = import_node_fs11.default.mkdtempSync(import_node_path12.default.join(import_node_os2.default.tmpdir(), "peach-expo-config-"));
|
|
10861
|
-
const resultPath = import_node_path12.default.join(directory, "config.json");
|
|
10862
|
-
try {
|
|
10863
|
-
const child = (0, import_node_child_process3.spawnSync)(
|
|
10864
|
-
"node",
|
|
10865
|
-
[
|
|
10866
|
-
"--input-type=commonjs",
|
|
10867
|
-
"-e",
|
|
10868
|
-
`const { createRequire } = require('node:module');
|
|
11047
|
+
var EXPO_CONFIG_SCRIPT = `const { createRequire } = require('node:module');
|
|
10869
11048
|
const { writeFileSync } = require('node:fs');
|
|
10870
11049
|
const { join } = require('node:path');
|
|
10871
11050
|
const root = process.argv[1];
|
|
10872
11051
|
const { getConfig } = createRequire(join(root, 'package.json'))('@expo/config');
|
|
10873
11052
|
const result = JSON.stringify(getConfig(root, { skipSDKVersionRequirement: true }).exp);
|
|
10874
11053
|
if (Buffer.byteLength(result) > 1024 * 1024) throw new Error('Expo native configuration exceeds 1 MiB.');
|
|
10875
|
-
writeFileSync(process.argv[2], result, { mode: 0o600 })
|
|
10876
|
-
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
11054
|
+
writeFileSync(process.argv[2], result, { mode: 0o600 });`;
|
|
11055
|
+
function hasExpoConfig(projectRoot) {
|
|
11056
|
+
const appJsonPath = import_node_path12.default.join(projectRoot, "app.json");
|
|
11057
|
+
const appJson = import_node_fs11.default.existsSync(appJsonPath) ? JSON.parse(import_node_fs11.default.readFileSync(appJsonPath, "utf8")) : null;
|
|
11058
|
+
const staticExpo = isRecord(appJson) && (isRecord(appJson.expo) || [appJson.ios, appJson.android].some(
|
|
11059
|
+
(value) => isRecord(value) && typeof value.googleServicesFile === "string"
|
|
11060
|
+
));
|
|
11061
|
+
return staticExpo || ["app.config.js", "app.config.ts", "app.config.cjs", "app.config.mjs"].some(
|
|
11062
|
+
(name2) => import_node_fs11.default.existsSync(import_node_path12.default.join(projectRoot, name2))
|
|
11063
|
+
);
|
|
11064
|
+
}
|
|
11065
|
+
function expoConfigArgs(projectRoot, resultPath) {
|
|
11066
|
+
return [
|
|
11067
|
+
"--input-type=commonjs",
|
|
11068
|
+
"-e",
|
|
11069
|
+
EXPO_CONFIG_SCRIPT,
|
|
11070
|
+
import_node_path12.default.resolve(projectRoot),
|
|
11071
|
+
resultPath
|
|
11072
|
+
];
|
|
11073
|
+
}
|
|
11074
|
+
function readExpoConfigResult(resultPath, status, stderr) {
|
|
11075
|
+
if (status !== 0)
|
|
11076
|
+
throw new Error(stderr || "Expo native configuration evaluation failed.");
|
|
11077
|
+
const resolved = JSON.parse(import_node_fs11.default.readFileSync(resultPath, "utf8"));
|
|
11078
|
+
if (!isRecord(resolved)) throw new Error("Expo native configuration is unavailable.");
|
|
11079
|
+
return resolved;
|
|
11080
|
+
}
|
|
11081
|
+
var resultDirectory = () => import_node_fs11.default.mkdtempSync(import_node_path12.default.join(import_node_os2.default.tmpdir(), "peach-expo-config-"));
|
|
11082
|
+
function readExpoConfig(projectRoot) {
|
|
11083
|
+
if (!hasExpoConfig(projectRoot)) return {};
|
|
11084
|
+
const directory = resultDirectory();
|
|
11085
|
+
const resultPath = import_node_path12.default.join(directory, "config.json");
|
|
11086
|
+
try {
|
|
11087
|
+
const child = (0, import_node_child_process3.spawnSync)("node", expoConfigArgs(projectRoot, resultPath), {
|
|
11088
|
+
cwd: projectRoot,
|
|
11089
|
+
encoding: "utf8",
|
|
11090
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
11091
|
+
timeout: 3e4,
|
|
11092
|
+
maxBuffer: 1024 * 1024
|
|
11093
|
+
});
|
|
11094
|
+
if (child.error) throw child.error;
|
|
11095
|
+
return readExpoConfigResult(resultPath, child.status, child.stderr);
|
|
11096
|
+
} finally {
|
|
11097
|
+
import_node_fs11.default.rmSync(directory, { recursive: true, force: true });
|
|
10897
11098
|
}
|
|
11099
|
+
}
|
|
11100
|
+
function readNativeFirebaseConfig(projectRoot, platforms = ["ios", "android"], iosTarget, config = readExpoConfig(projectRoot)) {
|
|
11101
|
+
const result = {};
|
|
10898
11102
|
const ios = config.ios;
|
|
10899
11103
|
if (platforms.includes("ios") && (!isRecord(ios) || typeof ios.googleServicesFile !== "string")) {
|
|
10900
11104
|
const iosRoot = import_node_path12.default.join(projectRoot, "ios");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1463 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.1463 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|