peachsim 0.1.578 → 0.1.580
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +11 -9
- package/cli/app-catalog.ts +77 -0
- package/cli/app-fonts.ts +4 -20
- package/cli/app-splash.ts +2 -18
- package/cli/bridge-flow-runner.ts +505 -139
- package/cli/cloud-client.ts +1 -4
- package/cli/cloud-session.ts +1 -4
- package/cli/cloud-test-result-files.ts +3 -0
- package/cli/cloud-test-tunnel.ts +2 -5
- package/cli/command-registry.ts +2 -0
- package/cli/commands/agent.ts +149 -23
- package/cli/commands/assert.ts +1 -4
- package/cli/commands/box/peach-command.ts +62 -0
- package/cli/commands/box/plane-share.ts +0 -70
- package/cli/commands/box/rnx-command.ts +1 -60
- package/cli/commands/box/search-command.ts +14 -0
- package/cli/commands/box.ts +2 -2
- package/cli/commands/control.ts +121 -27
- package/cli/commands/cpu-profile.ts +23 -10
- package/cli/commands/daemon.ts +1 -9
- package/cli/commands/detox.ts +26 -18
- package/cli/commands/device.ts +129 -1
- package/cli/commands/film.ts +25 -16
- package/cli/commands/flow.ts +9 -2
- package/cli/commands/inspect/actions.ts +75 -1
- package/cli/commands/inspect/core.ts +81 -2
- package/cli/commands/inspect/describe.ts +2 -6
- package/cli/commands/inspect/env.ts +1 -1
- package/cli/commands/inspect/settling.ts +20 -3
- package/cli/commands/inspect/shared.ts +1 -4
- package/cli/commands/inspect/sleep.ts +1 -1
- package/cli/commands/inspect.ts +16 -49
- package/cli/commands/install-desktop.ts +8 -6
- package/cli/commands/login.ts +3 -5
- package/cli/commands/maestro-generate.ts +1 -4
- package/cli/commands/maestro.ts +38 -21
- package/cli/commands/no-bridge-hint.ts +0 -14
- package/cli/commands/permissions.ts +2 -2
- package/cli/commands/platform.ts +13 -6
- package/cli/commands/screenshot.ts +6 -1
- package/cli/commands/skills.ts +1 -1
- package/cli/commands/test.ts +6 -2
- package/cli/commands/three-mode.ts +162 -19
- package/cli/commands/upload.ts +3 -18
- package/cli/current-sim.ts +0 -1
- package/cli/desktop-companion.ts +40 -8
- package/cli/drivers/playwright-provisioning.ts +1 -4
- package/cli/flow-export.ts +1 -8
- package/cli/flow-session.ts +0 -4
- package/cli/hints.ts +1 -16
- package/cli/inspect-notice-state.ts +0 -4
- package/cli/main.ts +2 -4
- package/cli/outbound-endpoints.ts +1 -24
- package/cli/parse-args.ts +1 -2
- package/cli/rnx-in-process.ts +3 -1
- package/cli/run-rnx-core.ts +4 -2
- package/cli/run-rnx.ts +18 -10
- package/cli/send-to-box.ts +1 -4
- package/cli/telemetry.ts +1 -1
- package/cli/ws-bridge.ts +1 -5
- package/detox/gestures.ts +20 -6
- package/detox/index.ts +379 -123
- package/detox/navigation-lifecycle.ts +22 -13
- package/dist-lib/agent-daemon-client.cjs +21 -15
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +3 -17
- package/dist-lib/agent-sessions.cjs +5 -4
- package/dist-lib/attached-projects.cjs +1 -77
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +11 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +7 -5
- package/dist-lib/bridge-contract-input.mjs +7 -5
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +30 -7
- package/dist-lib/capture-contract.mjs +30 -7
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +17 -11
- package/dist-lib/cloud.mjs +17 -11
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +321 -122
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +427 -212
- package/dist-lib/host/fetch-proxy-handler.cjs +5 -28
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +315 -58
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +67 -31
- package/dist-lib/menu.mjs +64 -28
- package/dist-lib/metro-fingerprint-registry.cjs +8 -4
- package/dist-lib/metro-fingerprint-registry.mjs +6 -4
- package/dist-lib/metro-production-bundle.cjs +2 -2
- package/dist-lib/metro-production-bundle.mjs +2 -2
- package/dist-lib/metro.cjs +8 -4
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +7 -4
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +3 -13
- package/dist-lib/scripts/dev-server-scanner.cjs +5 -17
- package/dist-lib/sdk.cjs +129 -10
- package/dist-lib/sdk.mjs +127 -10
- package/dist-lib/skills.cjs +1635 -1121
- package/dist-lib/swift-compile.cjs +277 -70
- package/dist-lib/swift-compile.mjs +275 -70
- package/dist-lib/swift-package.cjs +17 -5
- package/dist-lib/swift-package.mjs +15 -4
- package/dist-lib/swift-submit.cjs +32 -8
- package/dist-lib/swift-submit.mjs +29 -7
- package/dist-lib/swift.cjs +30912 -577
- package/dist-lib/vite-kotlin.cjs +356 -0
- package/dist-lib/vite-swift.cjs +1743 -0
- package/dist-lib/vite.cjs +208 -1039
- package/kotlin/README.md +18 -0
- package/kotlin/Sources/androidx/annotation/Keep.kt +4 -0
- package/kotlin/Sources/dev/onejs/one/OneNativeSourceDispatch.kt +7 -0
- package/kotlin/Sources/dev/onejs/one/source/OneModule.kt +4 -0
- package/kotlin/Sources/org/json/JSON.kt +244 -0
- package/kotlin/toolchain.json +19 -0
- package/package.json +14 -2
- package/scripts/dev-server-scanner.ts +0 -18
- package/scripts/optional-demo-registry.ts +0 -17
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-setup/SKILL.md +16 -0
- package/src/agent-daemon-client.ts +36 -22
- package/src/agent-identity.ts +0 -15
- package/src/agent-prompt.ts +12 -0
- package/src/attached-projects.ts +0 -72
- package/src/backend-origin.ts +10 -0
- package/src/bridge-contract-input.ts +2 -5
- package/src/bridge-contract.ts +2 -0
- package/src/capture-contract.ts +53 -11
- package/src/cloud.ts +4 -9
- package/src/dev-server-open.ts +0 -99
- package/src/home-paths.ts +2 -3
- package/src/host/agent-host.ts +82 -36
- package/src/host/bridge-host.ts +5 -11
- package/src/host/fetch-proxy-handler.ts +19 -43
- package/src/is-record.ts +4 -0
- package/src/menu.ts +82 -37
- package/src/metro-fingerprint-registry.ts +1 -4
- package/src/metro-production-bundle.ts +1 -1
- package/src/plist.ts +1 -4
- package/src/public-brand.ts +5 -3
- package/src/render-mode.ts +0 -12
- package/src/runtime-assets.ts +9 -2
- package/src/screenshots/compose.ts +7 -1
- package/src/screenshots/frame-compose.ts +21 -10
- package/src/screenshots/schema.ts +1 -4
- package/src/sim-client.ts +2 -4
- package/src/skills/builtin/maestro-test.ts +1 -4
- package/src/sleep.ts +4 -0
- package/src/swift-compile.ts +209 -47
- package/src/swift-icu.ts +140 -0
- package/src/swift-package.ts +26 -2
- package/src/swift-submit.ts +84 -4
- package/src/swift.ts +2 -0
- package/src/vite-plugin-kotlin.ts +376 -0
- package/src/vite-plugin-one.ts +224 -36
- package/src/vite-plugin-swift.ts +382 -96
- package/src/vite-plugin.ts +121 -134
- package/src/vite.d.ts +10 -0
- package/cli/resolve-assets.ts +0 -63
- package/src/rolldown-plugin-swift.ts +0 -244
- package/src/team-machine-prompt.ts +0 -73
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/*! rnx v0.1.580 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
|
+
"use strict";
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
+
|
|
32
|
+
// src/vite-plugin-kotlin.ts
|
|
33
|
+
var vite_plugin_kotlin_exports = {};
|
|
34
|
+
__export(vite_plugin_kotlin_exports, {
|
|
35
|
+
KOTLIN_ARTIFACT_PREFIX: () => KOTLIN_ARTIFACT_PREFIX,
|
|
36
|
+
kotlinArtifact: () => kotlinArtifact,
|
|
37
|
+
kotlinSources: () => kotlinSources,
|
|
38
|
+
serveKotlinArtifact: () => serveKotlinArtifact
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(vite_plugin_kotlin_exports);
|
|
41
|
+
var import_node_child_process = require("node:child_process");
|
|
42
|
+
var import_node_crypto = require("node:crypto");
|
|
43
|
+
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
44
|
+
var import_node_module = require("node:module");
|
|
45
|
+
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
46
|
+
var import_node_util = require("node:util");
|
|
47
|
+
|
|
48
|
+
// src/home-paths.ts
|
|
49
|
+
var import_node_os = require("node:os");
|
|
50
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
51
|
+
var PEACH_HOME_ENV = "PEACH_HOME";
|
|
52
|
+
function rnxHomeDir() {
|
|
53
|
+
const override = process.env[PEACH_HOME_ENV];
|
|
54
|
+
if (override && override.length > 0) return import_node_path.default.resolve(override);
|
|
55
|
+
return import_node_path.default.join((0, import_node_os.homedir)(), ".peach");
|
|
56
|
+
}
|
|
57
|
+
var DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
|
|
58
|
+
|
|
59
|
+
// src/is-record.ts
|
|
60
|
+
function isRecord(value) {
|
|
61
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/vite-plugin-kotlin.ts
|
|
65
|
+
var run = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
66
|
+
var KOTLIN_ARTIFACT_PREFIX = "/__peach/kotlin-artifact/";
|
|
67
|
+
function readToolchain(moduleRoot) {
|
|
68
|
+
const parsed = JSON.parse(
|
|
69
|
+
import_node_fs.default.readFileSync(import_node_path2.default.join(moduleRoot, "toolchain.json"), "utf8")
|
|
70
|
+
);
|
|
71
|
+
const download = (value) => {
|
|
72
|
+
if (!isRecord(value) || typeof value.url !== "string" || typeof value.sha256 !== "string")
|
|
73
|
+
throw new Error(
|
|
74
|
+
"peachsim kotlin/toolchain.json names a download without url and sha256"
|
|
75
|
+
);
|
|
76
|
+
return { url: value.url, sha256: value.sha256 };
|
|
77
|
+
};
|
|
78
|
+
if (!isRecord(parsed) || !isRecord(parsed.compiler) || !Array.isArray(parsed.libraries))
|
|
79
|
+
throw new Error("peachsim kotlin/toolchain.json has no compiler and libraries");
|
|
80
|
+
const version = parsed.compiler.version;
|
|
81
|
+
if (typeof version !== "string")
|
|
82
|
+
throw new Error("peachsim kotlin/toolchain.json has no compiler version");
|
|
83
|
+
return {
|
|
84
|
+
compiler: { ...download(parsed.compiler), version },
|
|
85
|
+
libraries: parsed.libraries.map((library) => {
|
|
86
|
+
if (!isRecord(library) || typeof library.name !== "string")
|
|
87
|
+
throw new Error("peachsim kotlin/toolchain.json names a library without a name");
|
|
88
|
+
return { ...download(library), name: library.name };
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function kotlinHome() {
|
|
93
|
+
return import_node_path2.default.join(rnxHomeDir(), "kotlin");
|
|
94
|
+
}
|
|
95
|
+
async function fetchVerified(download, target) {
|
|
96
|
+
if (import_node_fs.default.existsSync(target)) return;
|
|
97
|
+
const response = await fetch(download.url);
|
|
98
|
+
if (!response.ok) throw new Error(`${download.url} answered ${response.status}`);
|
|
99
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
100
|
+
const digest = (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
101
|
+
if (digest !== download.sha256)
|
|
102
|
+
throw new Error(`${download.url} has sha256 ${digest}, expected ${download.sha256}`);
|
|
103
|
+
import_node_fs.default.mkdirSync(import_node_path2.default.dirname(target), { recursive: true });
|
|
104
|
+
const partial = `${target}.${process.pid}.partial`;
|
|
105
|
+
import_node_fs.default.writeFileSync(partial, bytes);
|
|
106
|
+
import_node_fs.default.renameSync(partial, target);
|
|
107
|
+
}
|
|
108
|
+
var toolchainReady;
|
|
109
|
+
function ensureToolchain(toolchain) {
|
|
110
|
+
toolchainReady ??= (async () => {
|
|
111
|
+
const dir = import_node_path2.default.join(kotlinHome(), toolchain.compiler.version);
|
|
112
|
+
const kotlinc = import_node_path2.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
|
|
113
|
+
if (!import_node_fs.default.existsSync(kotlinc)) {
|
|
114
|
+
const zip = import_node_path2.default.join(dir, "kotlin-compiler.zip");
|
|
115
|
+
await fetchVerified(toolchain.compiler, zip);
|
|
116
|
+
await run("unzip", ["-q", "-o", zip, "-d", dir]);
|
|
117
|
+
import_node_fs.default.rmSync(zip);
|
|
118
|
+
}
|
|
119
|
+
const java = process.env.JAVA_HOME ? import_node_path2.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
|
|
120
|
+
await run(java, ["-version"]).catch(() => {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Kotlin in Peach compiles with kotlinc, which needs a Java runtime (17 or newer, as android builds use); ${process.env.JAVA_HOME ? `JAVA_HOME ${process.env.JAVA_HOME} has none` : "set JAVA_HOME or put java on PATH"}`
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
const libraries = [import_node_path2.default.join(dir, "kotlinc", "lib", "kotlin-stdlib-wasm-js.klib")];
|
|
126
|
+
for (const library of toolchain.libraries) {
|
|
127
|
+
const target = import_node_path2.default.join(dir, library.name);
|
|
128
|
+
await fetchVerified(library, target);
|
|
129
|
+
libraries.push(target);
|
|
130
|
+
}
|
|
131
|
+
return { kotlinc, libraries };
|
|
132
|
+
})().catch((error) => {
|
|
133
|
+
toolchainReady = void 0;
|
|
134
|
+
throw error;
|
|
135
|
+
});
|
|
136
|
+
return toolchainReady;
|
|
137
|
+
}
|
|
138
|
+
function appKotlinLanguage(root) {
|
|
139
|
+
const reactNative = import_node_path2.default.dirname(
|
|
140
|
+
(0, import_node_module.createRequire)(import_node_path2.default.join(root, "package.json")).resolve("react-native/package.json")
|
|
141
|
+
);
|
|
142
|
+
const versions = import_node_fs.default.readFileSync(
|
|
143
|
+
import_node_path2.default.join(reactNative, "gradle", "libs.versions.toml"),
|
|
144
|
+
"utf8"
|
|
145
|
+
);
|
|
146
|
+
const match = /^kotlin\s*=\s*"(\d+)\.(\d+)/m.exec(versions);
|
|
147
|
+
if (!match)
|
|
148
|
+
throw new Error(`${reactNative}/gradle/libs.versions.toml names no kotlin version`);
|
|
149
|
+
return `${match[1]}.${match[2]}`;
|
|
150
|
+
}
|
|
151
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
152
|
+
"node_modules",
|
|
153
|
+
"ios",
|
|
154
|
+
"android",
|
|
155
|
+
"dist",
|
|
156
|
+
"types",
|
|
157
|
+
"build",
|
|
158
|
+
"tests",
|
|
159
|
+
"__tests__",
|
|
160
|
+
"scripts"
|
|
161
|
+
]);
|
|
162
|
+
function kotlinSources(root) {
|
|
163
|
+
const sources = [];
|
|
164
|
+
const walk = (dir) => {
|
|
165
|
+
for (const entry of import_node_fs.default.readdirSync(dir, { withFileTypes: true })) {
|
|
166
|
+
if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name)) continue;
|
|
167
|
+
const full = import_node_path2.default.join(dir, entry.name);
|
|
168
|
+
if (entry.isDirectory()) walk(full);
|
|
169
|
+
else if (entry.isFile() && entry.name.endsWith(".kt")) sources.push(full);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
walk(root);
|
|
173
|
+
return sources.sort();
|
|
174
|
+
}
|
|
175
|
+
function entrySource(ids) {
|
|
176
|
+
return [
|
|
177
|
+
"import kotlin.js.JsAny",
|
|
178
|
+
"import kotlin.js.Promise",
|
|
179
|
+
"import kotlinx.coroutines.CoroutineStart",
|
|
180
|
+
"import kotlinx.coroutines.Dispatchers",
|
|
181
|
+
"import kotlinx.coroutines.GlobalScope",
|
|
182
|
+
"import kotlinx.coroutines.promise",
|
|
183
|
+
"import dev.onejs.one.OneNativeSourceDispatch",
|
|
184
|
+
"import org.json.JSONObject",
|
|
185
|
+
"",
|
|
186
|
+
"private val instances = mutableMapOf<String, OneNativeSourceDispatch>()",
|
|
187
|
+
"",
|
|
188
|
+
"private fun dispatcher(packageName: String): OneNativeSourceDispatch? = instances[packageName] ?: when (packageName) {",
|
|
189
|
+
...ids.map((id) => ` ${JSON.stringify(id)} -> OneNativeSource_${id}()`),
|
|
190
|
+
" else -> null",
|
|
191
|
+
"}?.also { instances[packageName] = it }",
|
|
192
|
+
"",
|
|
193
|
+
"@OptIn(kotlin.js.ExperimentalJsExport::class, kotlin.js.ExperimentalWasmJsInterop::class, kotlinx.coroutines.DelicateCoroutinesApi::class)",
|
|
194
|
+
"@JsExport",
|
|
195
|
+
"fun peachNativeCall(module: String, method: String, argsJson: String, contractHash: String): Promise<JsAny?> =",
|
|
196
|
+
" GlobalScope.promise(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {",
|
|
197
|
+
" val reply = JSONObject()",
|
|
198
|
+
" try {",
|
|
199
|
+
` val packageName = module.substringBefore('.', "")`,
|
|
200
|
+
" val dispatch = dispatcher(packageName)",
|
|
201
|
+
" if (packageName.isEmpty() || !module.contains('.')) {",
|
|
202
|
+
' reply.put("ok", false).put("code", "E_NATIVE_SOURCE").put("error", "invalid module $module")',
|
|
203
|
+
" } else if (dispatch == null) {",
|
|
204
|
+
' reply.put("ok", false).put("code", "E_NATIVE_SOURCE").put("error", "$module.$method: OneNativeSource_$packageName")',
|
|
205
|
+
" } else if (dispatch.contractHash != contractHash) {",
|
|
206
|
+
' reply.put("ok", false).put("code", "E_NATIVE_SOURCE_REBUILD").put("error", "native module $module changed; rebuild the app")',
|
|
207
|
+
" } else {",
|
|
208
|
+
' reply.put("ok", true).put("value", dispatch.call(module, method, argsJson))',
|
|
209
|
+
" }",
|
|
210
|
+
" } catch (error: Exception) {",
|
|
211
|
+
' reply.put("ok", false).put("code", "E_NATIVE_SOURCE").put("error", "$module.$method: ${error.message}")',
|
|
212
|
+
" }",
|
|
213
|
+
" reply.toString().toJsString()",
|
|
214
|
+
" }",
|
|
215
|
+
""
|
|
216
|
+
].join("\n");
|
|
217
|
+
}
|
|
218
|
+
var BUILD_FORMAT = 1;
|
|
219
|
+
var builds = /* @__PURE__ */ new Map();
|
|
220
|
+
function buildsDir() {
|
|
221
|
+
return import_node_path2.default.join(kotlinHome(), "builds");
|
|
222
|
+
}
|
|
223
|
+
async function kotlinArtifact(root, moduleRoot, origin) {
|
|
224
|
+
const { kotlinSourceId, nativeSourceContract, renderKotlinSourceGlue } = await import("vxrn/native-source-contract");
|
|
225
|
+
const toolchain = readToolchain(moduleRoot);
|
|
226
|
+
const language = appKotlinLanguage(root);
|
|
227
|
+
const sources = kotlinSources(root);
|
|
228
|
+
if (sources.length === 0) throw new Error(`${root} holds no Kotlin sources`);
|
|
229
|
+
const generated = {};
|
|
230
|
+
const ids = [];
|
|
231
|
+
for (const file of sources) {
|
|
232
|
+
const contract = nativeSourceContract(file, import_node_fs.default.readFileSync(file, "utf8"));
|
|
233
|
+
if (contract.modules.length === 0) continue;
|
|
234
|
+
const id = kotlinSourceId(root, file);
|
|
235
|
+
ids.push(id);
|
|
236
|
+
generated[`OneNativeSource_${id}.kt`] = renderKotlinSourceGlue(id, contract).source;
|
|
237
|
+
}
|
|
238
|
+
generated["PeachEntry.kt"] = entrySource(ids);
|
|
239
|
+
const shims = kotlinSources(import_node_path2.default.join(moduleRoot, "Sources"));
|
|
240
|
+
const digest = (0, import_node_crypto.createHash)("sha256");
|
|
241
|
+
digest.update(JSON.stringify({ format: BUILD_FORMAT, toolchain, language }));
|
|
242
|
+
for (const file of [...shims, ...sources])
|
|
243
|
+
digest.update(`${import_node_path2.default.relative(root, file)}\0${import_node_fs.default.readFileSync(file, "utf8")}\0`);
|
|
244
|
+
for (const [name, text] of Object.entries(generated))
|
|
245
|
+
digest.update(`${name}\0${text}\0`);
|
|
246
|
+
const hash = digest.digest("hex").slice(0, 24);
|
|
247
|
+
const artifact = { url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`, hash };
|
|
248
|
+
const out = import_node_path2.default.join(buildsDir(), hash);
|
|
249
|
+
if (import_node_fs.default.existsSync(import_node_path2.default.join(out, "js", "app.wasm"))) return artifact;
|
|
250
|
+
const pending = builds.get(hash);
|
|
251
|
+
if (pending) return pending;
|
|
252
|
+
const build = (async () => {
|
|
253
|
+
const { kotlinc, libraries } = await ensureToolchain(toolchain);
|
|
254
|
+
import_node_fs.default.mkdirSync(buildsDir(), { recursive: true });
|
|
255
|
+
const work = import_node_fs.default.mkdtempSync(import_node_path2.default.join(buildsDir(), `${hash}-`));
|
|
256
|
+
const generatedDir = import_node_path2.default.join(work, "generated");
|
|
257
|
+
import_node_fs.default.mkdirSync(generatedDir);
|
|
258
|
+
for (const [name, text] of Object.entries(generated))
|
|
259
|
+
import_node_fs.default.writeFileSync(import_node_path2.default.join(generatedDir, name), text);
|
|
260
|
+
const common = ["-Xwasm-target=js", "-libraries", libraries.join(import_node_path2.default.delimiter)];
|
|
261
|
+
try {
|
|
262
|
+
await run(
|
|
263
|
+
kotlinc,
|
|
264
|
+
[
|
|
265
|
+
...common,
|
|
266
|
+
"-language-version",
|
|
267
|
+
language,
|
|
268
|
+
"-api-version",
|
|
269
|
+
language,
|
|
270
|
+
"-nowarn",
|
|
271
|
+
"-nopack",
|
|
272
|
+
"-ir-output-dir",
|
|
273
|
+
import_node_path2.default.join(work, "klib"),
|
|
274
|
+
"-ir-output-name",
|
|
275
|
+
"app",
|
|
276
|
+
...shims,
|
|
277
|
+
...sources,
|
|
278
|
+
...Object.keys(generated).map((name) => import_node_path2.default.join(generatedDir, name))
|
|
279
|
+
],
|
|
280
|
+
{ maxBuffer: 16 * 1024 * 1024 }
|
|
281
|
+
);
|
|
282
|
+
await run(
|
|
283
|
+
kotlinc,
|
|
284
|
+
[
|
|
285
|
+
...common,
|
|
286
|
+
"-nowarn",
|
|
287
|
+
`-Xinclude=${import_node_path2.default.join(work, "klib")}`,
|
|
288
|
+
"-Xir-produce-js",
|
|
289
|
+
"-ir-output-dir",
|
|
290
|
+
import_node_path2.default.join(work, "js"),
|
|
291
|
+
"-ir-output-name",
|
|
292
|
+
"app"
|
|
293
|
+
],
|
|
294
|
+
{ maxBuffer: 16 * 1024 * 1024 }
|
|
295
|
+
);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
import_node_fs.default.rmSync(work, { recursive: true, force: true });
|
|
298
|
+
const output = isRecord(error) ? `${String(error.stderr ?? "")}${String(error.stdout ?? "")}` : "";
|
|
299
|
+
throw new Error(
|
|
300
|
+
`kotlin compile failed:
|
|
301
|
+
${output.trim() || (error instanceof Error ? error.message : String(error))}`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
let patched = 0;
|
|
305
|
+
for (const file of import_node_fs.default.readdirSync(import_node_path2.default.join(work, "js"))) {
|
|
306
|
+
if (!file.endsWith(".mjs")) continue;
|
|
307
|
+
const target = import_node_path2.default.join(work, "js", file);
|
|
308
|
+
const text = import_node_fs.default.readFileSync(target, "utf8");
|
|
309
|
+
const next = text.replaceAll("process.release.name", "process.release?.name");
|
|
310
|
+
if (next !== text) {
|
|
311
|
+
patched++;
|
|
312
|
+
import_node_fs.default.writeFileSync(target, next);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (patched === 0)
|
|
316
|
+
throw new Error(
|
|
317
|
+
"kotlin loader no longer reads process.release.name; recheck its node detection in Peach"
|
|
318
|
+
);
|
|
319
|
+
import_node_fs.default.renameSync(work, out);
|
|
320
|
+
return artifact;
|
|
321
|
+
})().finally(() => builds.delete(hash));
|
|
322
|
+
builds.set(hash, build);
|
|
323
|
+
return build;
|
|
324
|
+
}
|
|
325
|
+
var CONTENT_TYPES = {
|
|
326
|
+
".mjs": "text/javascript",
|
|
327
|
+
".wasm": "application/wasm"
|
|
328
|
+
};
|
|
329
|
+
function serveKotlinArtifact(pathname, res) {
|
|
330
|
+
if (!pathname.startsWith(KOTLIN_ARTIFACT_PREFIX)) return false;
|
|
331
|
+
const [hash, file, ...rest] = pathname.slice(KOTLIN_ARTIFACT_PREFIX.length).split("/");
|
|
332
|
+
const type = file ? CONTENT_TYPES[import_node_path2.default.extname(file)] : void 0;
|
|
333
|
+
if (!hash || !/^[0-9a-f]+$/.test(hash) || !file || rest.length > 0 || !type || file.includes("..")) {
|
|
334
|
+
res.statusCode = 404;
|
|
335
|
+
res.end("not a kotlin artifact");
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
const target = import_node_path2.default.join(buildsDir(), hash, "js", file);
|
|
339
|
+
if (!import_node_fs.default.existsSync(target)) {
|
|
340
|
+
res.statusCode = 404;
|
|
341
|
+
res.end(`kotlin artifact ${hash}/${file} was not built`);
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
res.setHeader("access-control-allow-origin", "*");
|
|
345
|
+
res.setHeader("content-type", type);
|
|
346
|
+
res.setHeader("cache-control", "public, max-age=31536000, immutable");
|
|
347
|
+
res.end(import_node_fs.default.readFileSync(target));
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
351
|
+
0 && (module.exports = {
|
|
352
|
+
KOTLIN_ARTIFACT_PREFIX,
|
|
353
|
+
kotlinArtifact,
|
|
354
|
+
kotlinSources,
|
|
355
|
+
serveKotlinArtifact
|
|
356
|
+
});
|