peachsim 0.1.2180 → 0.1.2182
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/cli/commands/shell-url.ts +28 -22
- 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 +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +141 -70
- 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 +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +68 -36
- 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 +106 -59
- package/dist-lib/host/fetch-proxy-handler.cjs +3 -3
- 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 +3 -3
- 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 +1 -1
- 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 +3 -3
- package/dist-lib/native-app-identity-project.cjs +2 -2
- package/dist-lib/native-app-identity-project.mjs +2 -2
- 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/pdfium-raster.cjs +1 -1
- package/dist-lib/pdfium-raster.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/public-origins-lib-esm.json +24 -24
- package/dist-lib/public-origins-lib.json +53 -53
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/reap-browser.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +131 -67
- package/dist-lib/swift-compile.cjs +13 -4
- package/dist-lib/swift-compile.mjs +13 -4
- 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 +15 -6
- package/dist-lib/vite.cjs +3 -3
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/dist-types/packages/peach-engine/src/render-worker/map-command-channel.d.ts +14 -0
- package/package.json +1 -1
- package/src/expo-native-workspace.ts +17 -20
- package/src/expo-swift-bundle.ts +6 -1
- package/src/expo-swift-host.ts +35 -6
- package/src/expoSwiftContract.ts +3 -0
- package/src/native-bundles.ts +30 -10
- package/src/one-sdk/source.ts +10 -4
- package/src/one-sdk-bundle.ts +56 -24
- package/src/swift-compile.ts +3 -1
- package/src/swift-submit.ts +2 -1
- package/src/wasm-optimize.ts +11 -1
package/dist-lib/vite-swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2182 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -14977,6 +14977,13 @@ var BINARYEN_RELEASES = /* @__PURE__ */ new Map([
|
|
|
14977
14977
|
]
|
|
14978
14978
|
]);
|
|
14979
14979
|
async function runWasmOpt(file, output2, skipPasses, binary) {
|
|
14980
|
+
const admittedCores = windowAdmission()?.cores ?? Number(process.env.TM_EXEC_CPU_CORES);
|
|
14981
|
+
const requestedCores = Number(process.env.BINARYEN_CORES);
|
|
14982
|
+
const environment = { ...process.env, WASM_OPT_PATH: binary };
|
|
14983
|
+
if (Number.isInteger(admittedCores) && admittedCores > 0)
|
|
14984
|
+
environment.BINARYEN_CORES = String(
|
|
14985
|
+
Number.isInteger(requestedCores) && requestedCores > 0 ? Math.min(admittedCores, requestedCores) : admittedCores
|
|
14986
|
+
);
|
|
14980
14987
|
const result = await (0, import_wasm_opt.wasmOpt)(
|
|
14981
14988
|
[
|
|
14982
14989
|
"-Oz",
|
|
@@ -14986,7 +14993,7 @@ async function runWasmOpt(file, output2, skipPasses, binary) {
|
|
|
14986
14993
|
"-o",
|
|
14987
14994
|
output2
|
|
14988
14995
|
],
|
|
14989
|
-
{ env:
|
|
14996
|
+
{ env: environment }
|
|
14990
14997
|
);
|
|
14991
14998
|
if (result.status !== 0)
|
|
14992
14999
|
throw new Error(`wasm-opt exited ${result.status}: ${result.stderr}`);
|
|
@@ -17039,7 +17046,7 @@ var darwinRecordsRegion = (quoted) => quoted.length ? ["-Wl,--start-lib", ...quo
|
|
|
17039
17046
|
var REACTOR_FLAG = '"-Xclang-linker", "-mexec-model=reactor",\n';
|
|
17040
17047
|
var MULTI_MANIFEST_VERSION = 68;
|
|
17041
17048
|
var SWIFT_HEADER_PRODUCTS_TARGET = "PeachHeaderProducts";
|
|
17042
|
-
var compilerSourceDigest = true ? "
|
|
17049
|
+
var compilerSourceDigest = true ? "73960368f0b83cf042511655d857d5f64204fa539e2c984423a12c08657b068e" : swiftCompilerSourceDigest(__sootsim_import_meta_dirname);
|
|
17043
17050
|
function swiftArtifactHash(input, release, moduleRoot) {
|
|
17044
17051
|
const hash = (0, import_node_crypto13.createHash)("sha256");
|
|
17045
17052
|
hash.update(`swift-compile
|
|
@@ -20343,7 +20350,7 @@ function readCompiledArtifact(directory, hash) {
|
|
|
20343
20350
|
return null;
|
|
20344
20351
|
const bytes = (0, import_node_fs27.readFileSync)(import_node_path27.default.join(directory, "app.wasm"));
|
|
20345
20352
|
const gzip2 = (0, import_node_fs27.readFileSync)(import_node_path27.default.join(directory, "icu.gz"));
|
|
20346
|
-
if ((0, import_node_crypto13.createHash)("sha256").update(bytes).digest("hex") !== receipt.wasm || (0, import_node_crypto13.createHash)("sha256").update(gzip2).digest("hex") !== receipt.icu || bytes.length
|
|
20353
|
+
if ((0, import_node_crypto13.createHash)("sha256").update(bytes).digest("hex") !== receipt.wasm || (0, import_node_crypto13.createHash)("sha256").update(gzip2).digest("hex") !== receipt.icu || bytes.length <= 8 || bytes.readUInt32LE(0) !== 1836278016 || bytes.readUInt32LE(4) !== 1)
|
|
20347
20354
|
return null;
|
|
20348
20355
|
return { hash, bytes, icu: { sha256: receipt.icu, gzip: gzip2 } };
|
|
20349
20356
|
} catch (error) {
|
|
@@ -21405,6 +21412,8 @@ function compileSwiftProjectOnce(input, options) {
|
|
|
21405
21412
|
bytes: (0, import_node_fs27.readFileSync)(executable),
|
|
21406
21413
|
icu: await icu
|
|
21407
21414
|
};
|
|
21415
|
+
if (artifact.bytes.length <= 8)
|
|
21416
|
+
throw new Error("swift-compile: deferred linker produced no executable");
|
|
21408
21417
|
if (!options.project) saveCompiledArtifact(root, artifact);
|
|
21409
21418
|
saveSharedArtifact(sharedRoot, artifact);
|
|
21410
21419
|
report("compiled artifact verified");
|
|
@@ -29589,7 +29598,7 @@ var MAX_SWIFT_COMPILE_METAL_TOTAL_BYTES = 8 * 1024 * 1024;
|
|
|
29589
29598
|
var MAX_SWIFT_COMPILE_IMAGES = 256;
|
|
29590
29599
|
var MAX_SWIFT_COMPILE_IMAGE_BYTES = 4 * 1024 * 1024;
|
|
29591
29600
|
var MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
29592
|
-
var SWIFT_HOST_ABI =
|
|
29601
|
+
var SWIFT_HOST_ABI = 70;
|
|
29593
29602
|
var POLL_INTERVAL_MS = 1500;
|
|
29594
29603
|
function swiftNativeEntry(native, file) {
|
|
29595
29604
|
return {
|
|
@@ -30440,7 +30449,7 @@ function sourceClosureDigest(srcDir, entrypoints) {
|
|
|
30440
30449
|
return hash.digest("hex");
|
|
30441
30450
|
}
|
|
30442
30451
|
var standinSourceDigest = (srcDir = __sootsim_import_meta_dirname) => sourceClosureDigest(srcDir, STANDIN_DIGEST_ENTRYPOINTS);
|
|
30443
|
-
var STANDIN_SOURCE_DIGEST = true ? "
|
|
30452
|
+
var STANDIN_SOURCE_DIGEST = true ? "cc396d180b261e922288f645807b4a704fa92410ffc902bfbaac72b81af6413a" : standinSourceDigest();
|
|
30444
30453
|
|
|
30445
30454
|
// src/swift-standins.ts
|
|
30446
30455
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2182 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1909,7 +1909,7 @@ function readIosSdkTree(root) {
|
|
|
1909
1909
|
|
|
1910
1910
|
// src/swift-standin-digest.ts
|
|
1911
1911
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
1912
|
-
var STANDIN_SOURCE_DIGEST = true ? "
|
|
1912
|
+
var STANDIN_SOURCE_DIGEST = true ? "cc396d180b261e922288f645807b4a704fa92410ffc902bfbaac72b81af6413a" : standinSourceDigest();
|
|
1913
1913
|
|
|
1914
1914
|
// src/expo-native-workspace.ts
|
|
1915
1915
|
init_define_SWIFT_COVERAGE_SOURCE_DIGESTS();
|
|
@@ -5388,7 +5388,7 @@ var FOUNDATION_IMPLICIT_MODULES = [
|
|
|
5388
5388
|
var FOUNDATION_IMPLICIT_FLAGS = FOUNDATION_IMPLICIT_MODULES.map(
|
|
5389
5389
|
(module2) => `, "-Xfrontend", "-import-module", "-Xfrontend", "${module2}"`
|
|
5390
5390
|
).join("");
|
|
5391
|
-
var compilerSourceDigest = true ? "
|
|
5391
|
+
var compilerSourceDigest = true ? "73960368f0b83cf042511655d857d5f64204fa539e2c984423a12c08657b068e" : swiftCompilerSourceDigest2(__sootsim_import_meta_dirname);
|
|
5392
5392
|
var CORE_FOUNDATION_HANDLE_IMPORTS = [
|
|
5393
5393
|
"CFAllocator",
|
|
5394
5394
|
"CFArray",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! peach v0.1.
|
|
1
|
+
/*! peach v0.1.2182 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = '', __sootsim_import_meta_filename = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; __sootsim_import_meta_filename = __filename; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -9,16 +9,22 @@ export type MapStyle = string | {
|
|
|
9
9
|
sources: Record<string, unknown>;
|
|
10
10
|
layers: Array<Record<string, unknown>>;
|
|
11
11
|
};
|
|
12
|
+
export type MapScaleLocale = {
|
|
13
|
+
languageTag: string;
|
|
14
|
+
measurementSystem: 'metric' | 'us' | 'uk';
|
|
15
|
+
};
|
|
12
16
|
export type MapMountOptions = {
|
|
13
17
|
style?: MapStyle;
|
|
14
18
|
nativeAppearance?: 'light' | 'dark';
|
|
15
19
|
apple?: NativeSurfaceIdentity & {
|
|
16
20
|
token: string;
|
|
17
21
|
evaluationId: string;
|
|
22
|
+
locale: MapScaleLocale;
|
|
18
23
|
};
|
|
19
24
|
mapType?: 'satellite' | 'hybrid';
|
|
20
25
|
controls?: {
|
|
21
26
|
kind: 'compass' | 'scale' | 'userLocation';
|
|
27
|
+
top?: number;
|
|
22
28
|
}[];
|
|
23
29
|
projection?: MapProjection;
|
|
24
30
|
center?: LngLat;
|
|
@@ -149,6 +155,14 @@ export type MapCommand = {
|
|
|
149
155
|
kind: 'markers';
|
|
150
156
|
mapId: string;
|
|
151
157
|
markers: MapMarker[];
|
|
158
|
+
} | {
|
|
159
|
+
kind: 'locale';
|
|
160
|
+
mapId: string;
|
|
161
|
+
locale: MapScaleLocale;
|
|
162
|
+
} | {
|
|
163
|
+
kind: 'controls';
|
|
164
|
+
mapId: string;
|
|
165
|
+
controls: NonNullable<MapMountOptions['controls']>;
|
|
152
166
|
} | {
|
|
153
167
|
kind: 'overlays';
|
|
154
168
|
mapId: string;
|
package/package.json
CHANGED
|
@@ -877,6 +877,7 @@ async function prepareWorkspace(
|
|
|
877
877
|
// a pinned bun installs into its own prefix: npm exec keeps one cached copy per spec, so a copy
|
|
878
878
|
// installed without its postinstall (hosts that set ignore-scripts) would stay broken
|
|
879
879
|
const bunPrefix = path.join(cacheDir(), 'package-managers', manager)
|
|
880
|
+
const bunExecutable = path.join(bunPrefix, 'node_modules/.bin/bun')
|
|
880
881
|
const install =
|
|
881
882
|
manager === 'pnpm' || manager.startsWith('pnpm@')
|
|
882
883
|
? [
|
|
@@ -893,11 +894,7 @@ async function prepareWorkspace(
|
|
|
893
894
|
: manager === 'bun' || manager.startsWith('bun@')
|
|
894
895
|
? manager === 'bun'
|
|
895
896
|
? ['bun', 'install', '--frozen-lockfile']
|
|
896
|
-
: [
|
|
897
|
-
path.join(bunPrefix, 'node_modules/.bin/bun'),
|
|
898
|
-
'install',
|
|
899
|
-
'--frozen-lockfile',
|
|
900
|
-
]
|
|
897
|
+
: [bunExecutable, 'install', '--frozen-lockfile']
|
|
901
898
|
: // npm ci would delete the cloned tree before installing it again
|
|
902
899
|
['npm', 'install', '--no-audit', '--no-fund']
|
|
903
900
|
// dependencies such as react-native-skia fetch their native binaries in a lifecycle
|
|
@@ -907,22 +904,22 @@ async function prepareWorkspace(
|
|
|
907
904
|
const command = [...prefix, ...args]
|
|
908
905
|
await run(command[0]!, command.slice(1), cwd, env)
|
|
909
906
|
}
|
|
907
|
+
if (manager.startsWith('bun@') && (!projectReady || !fs.existsSync(bunExecutable)))
|
|
908
|
+
await execute(
|
|
909
|
+
[
|
|
910
|
+
'npm',
|
|
911
|
+
'install',
|
|
912
|
+
'--prefix',
|
|
913
|
+
bunPrefix,
|
|
914
|
+
// the bun package ships a placeholder binary its postinstall replaces
|
|
915
|
+
'--ignore-scripts=false',
|
|
916
|
+
'--no-audit',
|
|
917
|
+
'--no-fund',
|
|
918
|
+
manager,
|
|
919
|
+
],
|
|
920
|
+
work,
|
|
921
|
+
)
|
|
910
922
|
if (!projectReady) {
|
|
911
|
-
if (manager.startsWith('bun@'))
|
|
912
|
-
await execute(
|
|
913
|
-
[
|
|
914
|
-
'npm',
|
|
915
|
-
'install',
|
|
916
|
-
'--prefix',
|
|
917
|
-
bunPrefix,
|
|
918
|
-
// the bun package ships a placeholder binary its postinstall replaces
|
|
919
|
-
'--ignore-scripts=false',
|
|
920
|
-
'--no-audit',
|
|
921
|
-
'--no-fund',
|
|
922
|
-
manager,
|
|
923
|
-
],
|
|
924
|
-
work,
|
|
925
|
-
)
|
|
926
923
|
// npm install keeps the cloned tree but can otherwise rewrite a stale lockfile.
|
|
927
924
|
if (install[0] === 'npm' && fs.existsSync(path.join(work, 'package-lock.json'))) {
|
|
928
925
|
await execute(
|
package/src/expo-swift-bundle.ts
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
// its immutable native assets beside the javascript bundle.
|
|
3
3
|
import { compileExpoSwiftModules } from './expo-swift-host'
|
|
4
4
|
import { swiftIcuBundleAsset } from './swift-icu'
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ExpoSwiftCompilationResult,
|
|
7
|
+
ExpoSwiftPreparationOptions,
|
|
8
|
+
} from './expoSwiftContract'
|
|
6
9
|
|
|
7
10
|
export interface ExpoSwiftBundle {
|
|
8
11
|
metadata: ExpoSwiftCompilationResult
|
|
@@ -11,6 +14,7 @@ export interface ExpoSwiftBundle {
|
|
|
11
14
|
|
|
12
15
|
export async function buildExpoSwiftBundle(
|
|
13
16
|
appRoot: string,
|
|
17
|
+
oneSDK?: ExpoSwiftPreparationOptions['oneSDK'],
|
|
14
18
|
): Promise<ExpoSwiftBundle | null> {
|
|
15
19
|
const assets: ExpoSwiftBundle['assets'] = []
|
|
16
20
|
const metadata = await compileExpoSwiftModules(
|
|
@@ -25,6 +29,7 @@ export async function buildExpoSwiftBundle(
|
|
|
25
29
|
})
|
|
26
30
|
if ('gzip' in artifact.icu) assets.push(await swiftIcuBundleAsset(artifact.icu))
|
|
27
31
|
},
|
|
32
|
+
{ oneSDK },
|
|
28
33
|
)
|
|
29
34
|
if (!metadata) return null
|
|
30
35
|
|
package/src/expo-swift-host.ts
CHANGED
|
@@ -1999,7 +1999,16 @@ function targetSettings(units: ExpoSwiftSourceUnit[]) {
|
|
|
1999
1999
|
return settings
|
|
2000
2000
|
}
|
|
2001
2001
|
|
|
2002
|
-
function
|
|
2002
|
+
function oneSDKStamp(oneSDK: ExpoSwiftPreparationOptions['oneSDK']): string {
|
|
2003
|
+
if (!oneSDK) return ''
|
|
2004
|
+
const hash = createHash('sha256')
|
|
2005
|
+
for (const files of [oneSDK.targets, oneSDK.entry])
|
|
2006
|
+
for (const [name, source] of [...files].sort(([a], [b]) => a.localeCompare(b)))
|
|
2007
|
+
hash.update(`${name}\0${source}\0`)
|
|
2008
|
+
return hash.digest('hex')
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
function expoEntry(units: ExpoSwiftSourceUnit[], oneSDK = false): string {
|
|
2003
2012
|
// an Objective-C bridge module registers with no Swift of its own
|
|
2004
2013
|
const namespaces = [...new Set(units.map((unit) => unit.namespace))]
|
|
2005
2014
|
.filter((namespace) => namespace !== 'PeachExpoApp')
|
|
@@ -2015,7 +2024,11 @@ function expoEntry(units: ExpoSwiftSourceUnit[]): string {
|
|
|
2015
2024
|
subscribers.length + handlers.length > 0
|
|
2016
2025
|
? `; PeachExpoRuntime.registerDelegates(subscribers: [${subscribers.join(', ')}], handlers: [${handlers.join(', ')}])`
|
|
2017
2026
|
: ''
|
|
2018
|
-
|
|
2027
|
+
// a One SDK host component marks its view; every other view is an Expo view
|
|
2028
|
+
const view = oneSDK
|
|
2029
|
+
? '@ViewBuilder func view(props: JSON) -> some View {\n if props["oneSDKHost"] != nil { OneSDKUIKitHost(props: props) } else { PeachExpoNativeView(props: props) }\n }'
|
|
2030
|
+
: 'func view(props: JSON) -> PeachExpoNativeView { PeachExpoNativeView(props: props) }'
|
|
2031
|
+
return `import SwiftUI\ninternal import ExpoModulesCore\n${bridgeModules.length ? 'import React\n' : ''}${oneSDK ? 'import One\nimport OneSDKBindings\n' : ''}${namespaces.map((namespace) => `import ${namespace}`).join('\n')}\n\n@main struct PeachExpoApp: PeachPackage {\n init() { MainActor.assumeIsolated { PeachExpoRuntime.register([${units.flatMap((unit) => unit.classes).join(', ')}])${delegates}${bridgeModules.length ? `; RCTModuleHost.register([${bridgeModules.join(', ')}])` : ''} } }\n ${view}\n}\n\n@_expose(wasm, "peach_expo_call")\n@_cdecl("peach_expo_call")\n@MainActor public func peachExpoCall(_ payload: UnsafePointer<UInt8>?, _ length: Int32) -> UnsafeMutablePointer<UInt8>? {\n PeachExpoRuntime.dispatch(payload, length)\n}\n`
|
|
2019
2032
|
}
|
|
2020
2033
|
|
|
2021
2034
|
// a compile outlives its client: a dropped open leaves the work running so the
|
|
@@ -2153,7 +2166,7 @@ export async function compileExpoSwiftModules(
|
|
|
2153
2166
|
installSwiftInputTrace()
|
|
2154
2167
|
let key: string
|
|
2155
2168
|
try {
|
|
2156
|
-
key = `${await discoveryKey(root, options.installedWorkspace, true, options.iosTarget, options.moduleRoot)}\0${options.only?.join(',') ?? ''}`
|
|
2169
|
+
key = `${await discoveryKey(root, options.installedWorkspace, true, options.iosTarget, options.moduleRoot)}\0${options.only?.join(',') ?? ''}\0${oneSDKStamp(options.oneSDK)}`
|
|
2157
2170
|
} catch {
|
|
2158
2171
|
return compileExpoSwiftModulesTraced(root, base, publishArtifact, options)
|
|
2159
2172
|
}
|
|
@@ -2406,11 +2419,23 @@ async function compileExpoSwiftModulesTraced(
|
|
|
2406
2419
|
throw new Error(`conflicting Expo Swift binary source ${name}`)
|
|
2407
2420
|
files[name] = source
|
|
2408
2421
|
}
|
|
2409
|
-
|
|
2422
|
+
const settings = targetSettings(linked)
|
|
2423
|
+
if (options.oneSDK) {
|
|
2424
|
+
for (const [name, source] of options.oneSDK.targets) files[name] = source
|
|
2425
|
+
for (const [name, source] of options.oneSDK.entry)
|
|
2426
|
+
files[`Sources/PeachExpoApp/${name}`] = source
|
|
2427
|
+
settings.set('OneSDKBindings', {
|
|
2428
|
+
languageMode: 5,
|
|
2429
|
+
mainActorIsolation: false,
|
|
2430
|
+
swiftFlags: ['-suppress-warnings'],
|
|
2431
|
+
dependencies: [{ kind: 'target', name: 'One' }],
|
|
2432
|
+
})
|
|
2433
|
+
}
|
|
2434
|
+
files[EXPO_SWIFT_ENTRY] = expoEntry(linked, options.oneSDK !== undefined)
|
|
2410
2435
|
files['Package.swift'] = expoManifest(
|
|
2411
2436
|
files,
|
|
2412
2437
|
linked.map((unit) => generations.get(unit) ?? '').join(','),
|
|
2413
|
-
|
|
2438
|
+
settings,
|
|
2414
2439
|
)
|
|
2415
2440
|
const provider = linked.some((unit) => unit.reactNativeProvider)
|
|
2416
2441
|
? reactProvider
|
|
@@ -2648,7 +2673,11 @@ async function compileExpoSwiftModulesTraced(
|
|
|
2648
2673
|
stamps.set(unit, stamp)
|
|
2649
2674
|
candidates.push(unit)
|
|
2650
2675
|
}
|
|
2651
|
-
const preparedKey = expoSwiftPreparedKey(
|
|
2676
|
+
const preparedKey = expoSwiftPreparedKey(
|
|
2677
|
+
base,
|
|
2678
|
+
units,
|
|
2679
|
+
reactProviderStamp + oneSDKStamp(options.oneSDK),
|
|
2680
|
+
)
|
|
2652
2681
|
if (!publishArtifact) {
|
|
2653
2682
|
const prepared = preparedExpoSwift.get(preparedKey)
|
|
2654
2683
|
if (prepared) {
|
package/src/expoSwiftContract.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import { isRecord } from './is-record'
|
|
6
6
|
import { isNativeAppIdentity, type NativeAppIdentity } from './native-app-identity'
|
|
7
7
|
import { isSwiftResourcePath } from './swiftContract'
|
|
8
|
+
import type { OneSDKLinkSources } from './one-sdk-bundle'
|
|
8
9
|
import type {
|
|
9
10
|
SwiftNativeTarget,
|
|
10
11
|
SwiftHeaderAliases,
|
|
@@ -19,6 +20,8 @@ export interface ExpoSwiftPreparationOptions {
|
|
|
19
20
|
moduleRoot?: string
|
|
20
21
|
// compile only these Swift modules and the modules they import
|
|
21
22
|
only?: readonly string[]
|
|
23
|
+
// the app's One SDK, linked into the same executable: one process per app
|
|
24
|
+
oneSDK?: Pick<OneSDKLinkSources, 'targets' | 'entry'>
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
export interface ExpoSwiftSourceOptions {
|
package/src/native-bundles.ts
CHANGED
|
@@ -47,17 +47,37 @@ export async function buildNativeBundles(
|
|
|
47
47
|
configuration: 'Debug' | 'Release',
|
|
48
48
|
): Promise<NativeBundles> {
|
|
49
49
|
return getRuntimePlatformAdapter(platform).select<() => Promise<NativeBundles>>({
|
|
50
|
-
ios: async () =>
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
ios: async () => {
|
|
51
|
+
const { appOneSDKLinkSources, buildOneSDKBundle } = await import('./one-sdk-bundle')
|
|
52
|
+
// on iOS an app is one process: its One SDK links into the Expo executable
|
|
53
|
+
// when the app has one, and its process serves both
|
|
54
|
+
const oneSDK = await appOneSDKLinkSources(projectRoot)
|
|
55
|
+
const expoSwift = await (
|
|
53
56
|
await import('./expo-swift-bundle')
|
|
54
|
-
).buildExpoSwiftBundle(projectRoot)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
).buildExpoSwiftBundle(projectRoot, oneSDK ?? undefined)
|
|
58
|
+
const linked = oneSDK && expoSwift?.metadata.modules[0]
|
|
59
|
+
return {
|
|
60
|
+
oneSDK: linked
|
|
61
|
+
? {
|
|
62
|
+
metadata: {
|
|
63
|
+
url: linked.url,
|
|
64
|
+
hash: linked.hash,
|
|
65
|
+
icuUrl: linked.icuUrl,
|
|
66
|
+
rootId: `${linked.rootId.split('/')[0]}/OneSDK`,
|
|
67
|
+
bundleFiles: linked.bundleFiles ?? {},
|
|
68
|
+
modules: oneSDK.modules,
|
|
69
|
+
},
|
|
70
|
+
assets: [],
|
|
71
|
+
}
|
|
72
|
+
: await buildOneSDKBundle(projectRoot),
|
|
73
|
+
expoSwift,
|
|
74
|
+
nitro: await (
|
|
75
|
+
await import('./nitro-bundle')
|
|
76
|
+
).buildNitroBundle(projectRoot, configuration),
|
|
77
|
+
turbo: await (await import('./turbo-bundle')).buildTurboBundle(projectRoot),
|
|
78
|
+
expoKotlin: null,
|
|
79
|
+
}
|
|
80
|
+
},
|
|
61
81
|
android: async () => ({
|
|
62
82
|
oneSDK: null,
|
|
63
83
|
expoSwift: null,
|
package/src/one-sdk/source.ts
CHANGED
|
@@ -30,12 +30,13 @@ extension OneNativeComposable {
|
|
|
30
30
|
}
|
|
31
31
|
`
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// the view a One SDK host component mounts, in whichever executable links the
|
|
34
|
+
// app's One SDK
|
|
35
|
+
export const oneSDKHost = String.raw`import SwiftUI
|
|
34
36
|
@_spi(Peach) import UIKit
|
|
35
37
|
import One
|
|
36
|
-
import OneSDKBindings
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
struct OneSDKUIKitHost: UIViewRepresentable {
|
|
39
40
|
let props: JSON
|
|
40
41
|
func makeUIView(context: Context) -> OneNativeUIKitHostView { OneNativeUIKitHostView() }
|
|
41
42
|
func updateUIView(_ view: OneNativeUIKitHostView, context: Context) {
|
|
@@ -47,10 +48,15 @@ private struct UIKitHost: UIViewRepresentable {
|
|
|
47
48
|
}
|
|
48
49
|
static func dismantleUIView(_ view: OneNativeUIKitHostView, coordinator: Coordinator) { view.reset() }
|
|
49
50
|
}
|
|
51
|
+
`
|
|
52
|
+
|
|
53
|
+
export const oneSDKApp = String.raw`import SwiftUI
|
|
54
|
+
import One
|
|
55
|
+
import OneSDKBindings
|
|
50
56
|
|
|
51
57
|
@main
|
|
52
58
|
struct SDKGuest: PeachPackage {
|
|
53
|
-
func view(props: JSON) -> some View {
|
|
59
|
+
func view(props: JSON) -> some View { OneSDKUIKitHost(props: props) }
|
|
54
60
|
}
|
|
55
61
|
`
|
|
56
62
|
|
package/src/one-sdk-bundle.ts
CHANGED
|
@@ -4,7 +4,7 @@ import path from 'node:path'
|
|
|
4
4
|
import { prepareExpoNativeProject } from './expo-native-workspace'
|
|
5
5
|
import { compiledModuleAssets, compiledModuleRequestHandler } from './nitro-bundle'
|
|
6
6
|
import { selectOneSDK } from './one-sdk-preparation'
|
|
7
|
-
import { oneSDKApp, oneSDKModule, oneSDKTransport } from './one-sdk/source'
|
|
7
|
+
import { oneSDKApp, oneSDKHost, oneSDKModule, oneSDKTransport } from './one-sdk/source'
|
|
8
8
|
import { ONE_SDK_SOURCE_DIRECTORY, readOneSDKSourceManifest } from './oneSdkContract'
|
|
9
9
|
import { syncSwiftTree } from './swift-compile'
|
|
10
10
|
import { resolveSwiftModule } from './swift-distribution'
|
|
@@ -24,12 +24,19 @@ export async function compileOneSDKApp(
|
|
|
24
24
|
return compilePreparedOneSDKApp(appRoot, prepared.app, origin, moduleRootOverride)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
// the One and OneSDKBindings targets an executable links for the app's One SDK
|
|
28
|
+
// imports, the host view and transport its executable target adds, and the
|
|
29
|
+
// module names the bundle registers
|
|
30
|
+
export interface OneSDKLinkSources {
|
|
31
|
+
targets: Map<string, string>
|
|
32
|
+
entry: Map<string, string>
|
|
33
|
+
modules: string[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function oneSDKLinkSources(
|
|
28
37
|
appRoot: string,
|
|
29
38
|
preparedRoot: string,
|
|
30
|
-
|
|
31
|
-
moduleRootOverride?: string,
|
|
32
|
-
) {
|
|
39
|
+
): Promise<OneSDKLinkSources> {
|
|
33
40
|
const selected = await selectOneSDK(appRoot)
|
|
34
41
|
if (!selected) throw new Error('prepared app has no One SDK imports')
|
|
35
42
|
const { one, frameworks } = selected
|
|
@@ -47,6 +54,47 @@ export async function compilePreparedOneSDKApp(
|
|
|
47
54
|
throw new Error(
|
|
48
55
|
'prepared One SDK sources differ from the installed facades or app imports',
|
|
49
56
|
)
|
|
57
|
+
const targets = new Map<string, string>()
|
|
58
|
+
targets.set('Sources/One/One.swift', oneSDKModule)
|
|
59
|
+
for (const source of [
|
|
60
|
+
'SDK/OneSDKRuntime.swift',
|
|
61
|
+
'OneNativeUIKitHostView.swift',
|
|
62
|
+
'OneNativeContent.swift',
|
|
63
|
+
'OneNativeAccessibility.swift',
|
|
64
|
+
'SDKViews/OneNativeViewsTable.swift',
|
|
65
|
+
])
|
|
66
|
+
targets.set(
|
|
67
|
+
`Sources/One/${path.basename(source)}`,
|
|
68
|
+
fs.readFileSync(path.join(one, 'ios', source), 'utf8'),
|
|
69
|
+
)
|
|
70
|
+
for (const name of generated.files)
|
|
71
|
+
targets.set(
|
|
72
|
+
`Sources/OneSDKBindings/${name}`,
|
|
73
|
+
fs.readFileSync(path.join(sourceRoot, name), 'utf8'),
|
|
74
|
+
)
|
|
75
|
+
return {
|
|
76
|
+
targets,
|
|
77
|
+
entry: new Map([
|
|
78
|
+
['OneSDKHost.swift', oneSDKHost],
|
|
79
|
+
['OneSDKTransport.swift', oneSDKTransport],
|
|
80
|
+
]),
|
|
81
|
+
modules: frameworks.map((name) => `${name}_${generated.generation}`),
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// the app's One SDK sources, when it imports One's SDK
|
|
86
|
+
export async function appOneSDKLinkSources(appRoot: string) {
|
|
87
|
+
if (!(await selectOneSDK(appRoot))) return null
|
|
88
|
+
return oneSDKLinkSources(appRoot, (await prepareExpoNativeProject(appRoot)).app)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function compilePreparedOneSDKApp(
|
|
92
|
+
appRoot: string,
|
|
93
|
+
preparedRoot: string,
|
|
94
|
+
origin: string,
|
|
95
|
+
moduleRootOverride?: string,
|
|
96
|
+
) {
|
|
97
|
+
const sources = await oneSDKLinkSources(appRoot, preparedRoot)
|
|
50
98
|
const moduleRoot = moduleRootOverride ?? (await resolveSwiftModule()).root
|
|
51
99
|
const packagePath = path.join(
|
|
52
100
|
swiftCacheDir(),
|
|
@@ -66,25 +114,9 @@ let package = Package(name: "OneSDKGuest", targets: [
|
|
|
66
114
|
])
|
|
67
115
|
`,
|
|
68
116
|
)
|
|
69
|
-
files.set(
|
|
70
|
-
for (const source of
|
|
71
|
-
'SDK/OneSDKRuntime.swift',
|
|
72
|
-
'OneNativeUIKitHostView.swift',
|
|
73
|
-
'OneNativeContent.swift',
|
|
74
|
-
'OneNativeAccessibility.swift',
|
|
75
|
-
'SDKViews/OneNativeViewsTable.swift',
|
|
76
|
-
])
|
|
77
|
-
files.set(
|
|
78
|
-
`Sources/One/${path.basename(source)}`,
|
|
79
|
-
fs.readFileSync(path.join(one, 'ios', source), 'utf8'),
|
|
80
|
-
)
|
|
81
|
-
for (const name of generated.files)
|
|
82
|
-
files.set(
|
|
83
|
-
`Sources/OneSDKBindings/${name}`,
|
|
84
|
-
fs.readFileSync(path.join(sourceRoot, name), 'utf8'),
|
|
85
|
-
)
|
|
117
|
+
for (const [name, source] of sources.targets) files.set(name, source)
|
|
118
|
+
for (const [name, source] of sources.entry) files.set(`Sources/App/${name}`, source)
|
|
86
119
|
files.set('Sources/App/App.swift', oneSDKApp)
|
|
87
|
-
files.set('Sources/App/Transport.swift', oneSDKTransport)
|
|
88
120
|
fs.mkdirSync(packagePath, { recursive: true })
|
|
89
121
|
syncSwiftTree(
|
|
90
122
|
packagePath,
|
|
@@ -100,7 +132,7 @@ let package = Package(name: "OneSDKGuest", targets: [
|
|
|
100
132
|
icuUrl: icuUrl(origin, artifact),
|
|
101
133
|
rootId: `one-sdk-${artifact.hash.slice(0, 16)}`,
|
|
102
134
|
bundleFiles: artifact.package.bundleFiles.files,
|
|
103
|
-
modules:
|
|
135
|
+
modules: sources.modules,
|
|
104
136
|
}
|
|
105
137
|
return { metadata, artifact }
|
|
106
138
|
}
|
package/src/swift-compile.ts
CHANGED
|
@@ -6053,7 +6053,7 @@ function readCompiledArtifact(
|
|
|
6053
6053
|
if (
|
|
6054
6054
|
createHash('sha256').update(bytes).digest('hex') !== receipt.wasm ||
|
|
6055
6055
|
createHash('sha256').update(gzip).digest('hex') !== receipt.icu ||
|
|
6056
|
-
bytes.length
|
|
6056
|
+
bytes.length <= 8 ||
|
|
6057
6057
|
bytes.readUInt32LE(0) !== 0x6d736100 ||
|
|
6058
6058
|
bytes.readUInt32LE(4) !== 1
|
|
6059
6059
|
)
|
|
@@ -7423,6 +7423,8 @@ function compileSwiftProjectOnce(
|
|
|
7423
7423
|
bytes: readFileSync(executable),
|
|
7424
7424
|
icu: await icu,
|
|
7425
7425
|
}
|
|
7426
|
+
if (artifact.bytes.length <= 8)
|
|
7427
|
+
throw new Error('swift-compile: deferred linker produced no executable')
|
|
7426
7428
|
if (!options.project) saveCompiledArtifact(root, artifact)
|
|
7427
7429
|
saveSharedArtifact(sharedRoot, artifact)
|
|
7428
7430
|
report('compiled artifact verified')
|
package/src/swift-submit.ts
CHANGED
|
@@ -146,7 +146,8 @@ export const MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024
|
|
|
146
146
|
// 68: fetch headers replies carry `setCookies`, the response's Set-Cookie list.
|
|
147
147
|
// 69: `peach.icu_item_v1` replaces `icu_data_v1`: the host fills icu's table of
|
|
148
148
|
// contents and places each item's pack the first time icu opens it.
|
|
149
|
-
|
|
149
|
+
// 70: full Objective-C forwarding uses exact typed IMPs (`peach.imp_forwarder_mint`).
|
|
150
|
+
export const SWIFT_HOST_ABI = 70
|
|
150
151
|
|
|
151
152
|
export interface SwiftImageUpload {
|
|
152
153
|
/** the raster file picked for the asset (has the extension). */
|
package/src/wasm-optimize.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs'
|
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { installVerifiedTarball } from '@contrast/runtime-delivery'
|
|
4
4
|
import { BINARYEN_VERSION, wasmOpt } from 'wasm-opt'
|
|
5
|
+
import { windowAdmission } from './admitted-mac-build'
|
|
5
6
|
import { rnxHomeDir } from './home-paths'
|
|
6
7
|
|
|
7
8
|
// packaged native executables, size-optimized. clang's own
|
|
@@ -60,6 +61,15 @@ async function runWasmOpt(
|
|
|
60
61
|
skipPasses: readonly string[],
|
|
61
62
|
binary: string,
|
|
62
63
|
): Promise<void> {
|
|
64
|
+
const admittedCores = windowAdmission()?.cores ?? Number(process.env.TM_EXEC_CPU_CORES)
|
|
65
|
+
const requestedCores = Number(process.env.BINARYEN_CORES)
|
|
66
|
+
const environment: NodeJS.ProcessEnv = { ...process.env, WASM_OPT_PATH: binary }
|
|
67
|
+
if (Number.isInteger(admittedCores) && admittedCores > 0)
|
|
68
|
+
environment.BINARYEN_CORES = String(
|
|
69
|
+
Number.isInteger(requestedCores) && requestedCores > 0
|
|
70
|
+
? Math.min(admittedCores, requestedCores)
|
|
71
|
+
: admittedCores,
|
|
72
|
+
)
|
|
63
73
|
const result = await wasmOpt(
|
|
64
74
|
[
|
|
65
75
|
'-Oz',
|
|
@@ -69,7 +79,7 @@ async function runWasmOpt(
|
|
|
69
79
|
'-o',
|
|
70
80
|
output,
|
|
71
81
|
],
|
|
72
|
-
{ env:
|
|
82
|
+
{ env: environment },
|
|
73
83
|
)
|
|
74
84
|
if (result.status !== 0)
|
|
75
85
|
throw new Error(`wasm-opt exited ${result.status}: ${result.stderr}`)
|