peachsim 0.1.638 → 0.1.640
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/command-registry.ts +1 -0
- package/cli/commands/control.ts +75 -6
- package/cli/commands/swift.ts +326 -0
- package/cli/main.ts +11 -0
- package/cli/outbound-endpoints.ts +5 -1
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +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/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- 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 +13 -4
- 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 +1 -1
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.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/render-mode.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 +389 -232
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +89 -8
- package/dist-lib/swift-submit.mjs +78 -8
- package/dist-lib/swift.cjs +16 -33308
- package/dist-lib/vite-swift.cjs +422 -247
- package/dist-lib/vite.cjs +13 -4
- package/package.json +1 -1
- package/skills/contrast/SKILL.md +1 -0
- package/src/assetCatalogContract.ts +16 -0
- package/src/dot-env.ts +148 -0
- package/src/metro-runtime-source.ts +15 -0
- package/src/swift-guest.ts +51 -0
- package/src/swift-host.ts +900 -0
- package/src/swift-submit.ts +97 -6
- package/src/swift.ts +36 -8
- package/src/swiftContract.ts +52 -0
- package/src/vite-plugin-one.ts +4 -3
- package/src/vite-plugin-swift.ts +43 -755
package/dist-lib/vite-swift.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -45,6 +45,31 @@ __export(vite_plugin_swift_exports, {
|
|
|
45
45
|
swiftPlugin: () => swiftPlugin
|
|
46
46
|
});
|
|
47
47
|
module.exports = __toCommonJS(vite_plugin_swift_exports);
|
|
48
|
+
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
49
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
50
|
+
|
|
51
|
+
// ../sootsim-swift/src/entryModule.ts
|
|
52
|
+
function nativeExportLines(args, commonjs) {
|
|
53
|
+
const native = args.native;
|
|
54
|
+
if (!native) return [];
|
|
55
|
+
return Object.entries(native.modules).map(([name, methods]) => {
|
|
56
|
+
const calls = methods.map(
|
|
57
|
+
(method) => `${method}: (...args) => callSwiftModule(options, ${JSON.stringify(`${native.packageId}.${name}`)}, ${JSON.stringify(method)}, args, ${JSON.stringify(native.contractHash)})`
|
|
58
|
+
).join(", ");
|
|
59
|
+
return commonjs ? `module.exports.${name} = Object.freeze({ ${calls} })` : `export const ${name} = Object.freeze({ ${calls} })`;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function swiftEntryModuleEsm(args) {
|
|
63
|
+
return [
|
|
64
|
+
`import { createSwiftEntry, callSwiftModule } from 'peachsim/swift'`,
|
|
65
|
+
`const options = ${JSON.stringify({ url: args.url, hash: args.hash, icuUrl: args.icuUrl, rootId: args.rootId, resources: args.resources, bundleFiles: args.bundleFiles, colors: args.colors, symbols: args.symbols })}`,
|
|
66
|
+
...!args.native || args.native.defaultView ? ["export default createSwiftEntry(options)"] : [],
|
|
67
|
+
...nativeExportLines(args, false),
|
|
68
|
+
""
|
|
69
|
+
].join("\n");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/swift-host.ts
|
|
48
73
|
var import_node_crypto3 = require("node:crypto");
|
|
49
74
|
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
50
75
|
var import_node_os3 = __toESM(require("node:os"), 1);
|
|
@@ -82,8 +107,8 @@ function pickImagesetFile(images) {
|
|
|
82
107
|
scale: pick.scale === "2x" ? 2 : pick.scale === "3x" ? 3 : 1
|
|
83
108
|
};
|
|
84
109
|
}
|
|
85
|
-
function flatScale(
|
|
86
|
-
const match = /@([23])x\.[^./]+$/.exec(
|
|
110
|
+
function flatScale(path6) {
|
|
111
|
+
const match = /@([23])x\.[^./]+$/.exec(path6);
|
|
87
112
|
return match ? Number(match[1]) : 1;
|
|
88
113
|
}
|
|
89
114
|
function providesNamespace(text) {
|
|
@@ -110,13 +135,13 @@ function catalogEntryName(contentsPath, kind, readText) {
|
|
|
110
135
|
}
|
|
111
136
|
return segments.join("/");
|
|
112
137
|
}
|
|
113
|
-
function isFlatResourceImage(
|
|
114
|
-
return
|
|
138
|
+
function isFlatResourceImage(path6) {
|
|
139
|
+
return path6.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path6));
|
|
115
140
|
}
|
|
116
141
|
function enumerateBundleImages(paths, readText) {
|
|
117
142
|
const table = [];
|
|
118
143
|
const seen = /* @__PURE__ */ new Set();
|
|
119
|
-
const catalogs = paths.filter((
|
|
144
|
+
const catalogs = paths.filter((path6) => baseOf(path6) === "Contents.json");
|
|
120
145
|
for (const contentsPath of catalogs) {
|
|
121
146
|
const name = catalogEntryName(contentsPath, ".imageset", readText);
|
|
122
147
|
if (name === null || seen.has(name)) continue;
|
|
@@ -137,12 +162,12 @@ function enumerateBundleImages(paths, readText) {
|
|
|
137
162
|
seen.add(name);
|
|
138
163
|
table.push({ name, file: `${dir}/${pick.filename}`, scale: pick.scale });
|
|
139
164
|
}
|
|
140
|
-
for (const
|
|
141
|
-
if (!isFlatResourceImage(
|
|
142
|
-
const name = baseOf(
|
|
165
|
+
for (const path6 of paths) {
|
|
166
|
+
if (!isFlatResourceImage(path6)) continue;
|
|
167
|
+
const name = baseOf(path6).slice(0, -extOf(path6).length);
|
|
143
168
|
if (name === "" || seen.has(name)) continue;
|
|
144
169
|
seen.add(name);
|
|
145
|
-
table.push({ name, file:
|
|
170
|
+
table.push({ name, file: path6, scale: flatScale(path6) });
|
|
146
171
|
}
|
|
147
172
|
return table;
|
|
148
173
|
}
|
|
@@ -171,7 +196,7 @@ function colorsetValue(color) {
|
|
|
171
196
|
}
|
|
172
197
|
function enumerateBundleColors(paths, readText) {
|
|
173
198
|
const table = {};
|
|
174
|
-
for (const contentsPath of paths.filter((
|
|
199
|
+
for (const contentsPath of paths.filter((path6) => baseOf(path6) === "Contents.json")) {
|
|
175
200
|
const name = catalogEntryName(contentsPath, ".colorset", readText);
|
|
176
201
|
if (name === null || name in table) continue;
|
|
177
202
|
let colors;
|
|
@@ -236,8 +261,8 @@ function axisExtremes(points) {
|
|
|
236
261
|
function pathBounds(d) {
|
|
237
262
|
const xs = [];
|
|
238
263
|
const ys = [];
|
|
239
|
-
for (const
|
|
240
|
-
(0, import_svgpath.default)(
|
|
264
|
+
for (const path6 of d)
|
|
265
|
+
(0, import_svgpath.default)(path6).abs().unshort().unarc().iterate((segment, _index, x, y) => {
|
|
241
266
|
const [command, ...args] = segment;
|
|
242
267
|
if (command === "M" || command === "L") {
|
|
243
268
|
xs.push(Number(args[0]));
|
|
@@ -264,7 +289,7 @@ function guide(svg, id, axis) {
|
|
|
264
289
|
}
|
|
265
290
|
function enumerateBundleSymbols(paths, readText) {
|
|
266
291
|
const table = {};
|
|
267
|
-
for (const contentsPath of paths.filter((
|
|
292
|
+
for (const contentsPath of paths.filter((path6) => baseOf(path6) === "Contents.json")) {
|
|
268
293
|
const name = catalogEntryName(contentsPath, ".symbolset", readText);
|
|
269
294
|
if (name === null || name in table) continue;
|
|
270
295
|
let symbols;
|
|
@@ -297,8 +322,8 @@ function enumerateBundleSymbols(paths, readText) {
|
|
|
297
322
|
viewBox: "0 0 24 24",
|
|
298
323
|
advance,
|
|
299
324
|
box: [12 - advance / 2, 12 - tall / 2, advance, tall],
|
|
300
|
-
layers: d.map((
|
|
301
|
-
d: (0, import_svgpath.default)(
|
|
325
|
+
layers: d.map((path6) => ({
|
|
326
|
+
d: (0, import_svgpath.default)(path6).abs().scale(scale).translate(translateX, translateY).round(3).toString()
|
|
302
327
|
}))
|
|
303
328
|
};
|
|
304
329
|
}
|
|
@@ -308,7 +333,7 @@ function enumerateBundleJson(paths) {
|
|
|
308
333
|
const found = [];
|
|
309
334
|
const seen = /* @__PURE__ */ new Set();
|
|
310
335
|
const ordered = [...paths].filter(
|
|
311
|
-
(
|
|
336
|
+
(path6) => path6.split("/").includes("Resources") && path6.split("/").every((segment) => segment !== "" && segment !== "..") && (extOf(path6) === ".json" || extOf(path6) === ".xcstrings")
|
|
312
337
|
).sort((a, b) => {
|
|
313
338
|
const aDepth = a.split("/").length;
|
|
314
339
|
const bDepth = b.split("/").length;
|
|
@@ -323,27 +348,6 @@ function enumerateBundleJson(paths) {
|
|
|
323
348
|
return found;
|
|
324
349
|
}
|
|
325
350
|
|
|
326
|
-
// ../sootsim-swift/src/entryModule.ts
|
|
327
|
-
function nativeExportLines(args, commonjs) {
|
|
328
|
-
const native = args.native;
|
|
329
|
-
if (!native) return [];
|
|
330
|
-
return Object.entries(native.modules).map(([name, methods]) => {
|
|
331
|
-
const calls = methods.map(
|
|
332
|
-
(method) => `${method}: (...args) => callSwiftModule(options, ${JSON.stringify(`${native.packageId}.${name}`)}, ${JSON.stringify(method)}, args, ${JSON.stringify(native.contractHash)})`
|
|
333
|
-
).join(", ");
|
|
334
|
-
return commonjs ? `module.exports.${name} = Object.freeze({ ${calls} })` : `export const ${name} = Object.freeze({ ${calls} })`;
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
function swiftEntryModuleEsm(args) {
|
|
338
|
-
return [
|
|
339
|
-
`import { createSwiftEntry, callSwiftModule } from 'peachsim/swift'`,
|
|
340
|
-
`const options = ${JSON.stringify({ url: args.url, hash: args.hash, icuUrl: args.icuUrl, rootId: args.rootId, resources: args.resources, bundleFiles: args.bundleFiles, colors: args.colors, symbols: args.symbols })}`,
|
|
341
|
-
...!args.native || args.native.defaultView ? ["export default createSwiftEntry(options)"] : [],
|
|
342
|
-
...nativeExportLines(args, false),
|
|
343
|
-
""
|
|
344
|
-
].join("\n");
|
|
345
|
-
}
|
|
346
|
-
|
|
347
351
|
// src/auth/shared-session.ts
|
|
348
352
|
var import_node_fs = require("node:fs");
|
|
349
353
|
var import_node_path2 = require("node:path");
|
|
@@ -1155,7 +1159,15 @@ function compileSwiftProjectUnit(input, options) {
|
|
|
1155
1159
|
|
|
1156
1160
|
// src/swift-submit.ts
|
|
1157
1161
|
var SWIFT_COMPILE_PATH = "/api/swift-compile";
|
|
1158
|
-
var
|
|
1162
|
+
var MAX_SWIFT_COMPILE_FILES = 256;
|
|
1163
|
+
var MAX_SWIFT_COMPILE_SOURCE_BYTES = 2 * 1024 * 1024;
|
|
1164
|
+
var MAX_SWIFT_COMPILE_RESOURCES = 128;
|
|
1165
|
+
var MAX_SWIFT_COMPILE_RESOURCE_BYTES = 2 * 1024 * 1024;
|
|
1166
|
+
var MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES = 8 * 1024 * 1024;
|
|
1167
|
+
var MAX_SWIFT_COMPILE_IMAGES = 128;
|
|
1168
|
+
var MAX_SWIFT_COMPILE_IMAGE_BYTES = 4 * 1024 * 1024;
|
|
1169
|
+
var MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
1170
|
+
var SWIFT_HOST_ABI = 2;
|
|
1159
1171
|
var POLL_INTERVAL_MS = 1500;
|
|
1160
1172
|
function swiftNativeEntry(native, file) {
|
|
1161
1173
|
return {
|
|
@@ -1176,6 +1188,7 @@ function httpSwiftCompileSubmit(context) {
|
|
|
1176
1188
|
try {
|
|
1177
1189
|
response = await fetch(url, {
|
|
1178
1190
|
method: "POST",
|
|
1191
|
+
signal: context.signal,
|
|
1179
1192
|
headers: {
|
|
1180
1193
|
"content-type": "application/json",
|
|
1181
1194
|
...authorization ? { authorization } : {}
|
|
@@ -1198,30 +1211,78 @@ function httpSwiftCompileSubmit(context) {
|
|
|
1198
1211
|
`contrast-bundler: the swift compile for ${work.entry} answered ${response.status}${detail ? `: ${detail}` : ""}`
|
|
1199
1212
|
);
|
|
1200
1213
|
}
|
|
1201
|
-
|
|
1214
|
+
const outcome = await response.json();
|
|
1215
|
+
if (!isSwiftCompileOutcome(outcome)) {
|
|
1216
|
+
throw new Error("swift compile: the service returned invalid artifact metadata");
|
|
1217
|
+
}
|
|
1218
|
+
return outcome;
|
|
1202
1219
|
};
|
|
1203
1220
|
}
|
|
1221
|
+
function isRecord(value) {
|
|
1222
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1223
|
+
}
|
|
1224
|
+
function isSwiftNativeModules(value) {
|
|
1225
|
+
return isRecord(value) && typeof value.packageId === "string" && typeof value.hash === "string" && isRecord(value.files) && isRecord(value.modules) && [...Object.values(value.files), ...Object.values(value.modules)].every(
|
|
1226
|
+
(names) => Array.isArray(names) && names.every((name) => typeof name === "string")
|
|
1227
|
+
) && Array.isArray(value.defaultViewFiles) && value.defaultViewFiles.every((file) => typeof file === "string");
|
|
1228
|
+
}
|
|
1229
|
+
function isSwiftCompileOutcome(value) {
|
|
1230
|
+
if (!isRecord(value)) return false;
|
|
1231
|
+
switch (value.status) {
|
|
1232
|
+
case "published":
|
|
1233
|
+
return typeof value.artifactUrl === "string" && typeof value.icuUrl === "string" && typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash) && (value.imageUrls === void 0 || isRecord(value.imageUrls) && Object.values(value.imageUrls).every((url) => typeof url === "string")) && (value.native === void 0 || isSwiftNativeModules(value.native));
|
|
1234
|
+
case "compiling":
|
|
1235
|
+
return typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash);
|
|
1236
|
+
case "refused":
|
|
1237
|
+
case "failed":
|
|
1238
|
+
return typeof value.detail === "string";
|
|
1239
|
+
default:
|
|
1240
|
+
return false;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
function compileAssetUrl(value, origin) {
|
|
1244
|
+
const url = new URL(value, origin);
|
|
1245
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.origin !== new URL(origin).origin) {
|
|
1246
|
+
throw new Error("swift compile: artifact address escapes the compile origin");
|
|
1247
|
+
}
|
|
1248
|
+
return url.href;
|
|
1249
|
+
}
|
|
1204
1250
|
function resolveImageUrls(urls, origin) {
|
|
1205
1251
|
const resolved = {};
|
|
1206
1252
|
for (const [name, url] of Object.entries(urls)) {
|
|
1207
|
-
resolved[name] =
|
|
1253
|
+
resolved[name] = compileAssetUrl(url, origin);
|
|
1208
1254
|
}
|
|
1209
1255
|
return resolved;
|
|
1210
1256
|
}
|
|
1211
|
-
async function compileSwiftProject(submit, work, origin) {
|
|
1257
|
+
async function compileSwiftProject(submit, work, origin, signal) {
|
|
1212
1258
|
while (true) {
|
|
1259
|
+
signal?.throwIfAborted();
|
|
1213
1260
|
const outcome = await submit(work);
|
|
1214
1261
|
switch (outcome.status) {
|
|
1215
1262
|
case "published":
|
|
1216
1263
|
return {
|
|
1217
|
-
url:
|
|
1264
|
+
url: compileAssetUrl(outcome.artifactUrl, origin),
|
|
1218
1265
|
hash: outcome.hash,
|
|
1219
|
-
icuUrl:
|
|
1266
|
+
icuUrl: compileAssetUrl(outcome.icuUrl, origin),
|
|
1220
1267
|
...outcome.imageUrls === void 0 ? {} : { imageUrls: resolveImageUrls(outcome.imageUrls, origin) },
|
|
1221
1268
|
...outcome.native === void 0 ? {} : { native: outcome.native }
|
|
1222
1269
|
};
|
|
1223
1270
|
case "compiling":
|
|
1224
|
-
await new Promise((resolve2) =>
|
|
1271
|
+
await new Promise((resolve2, reject) => {
|
|
1272
|
+
const finish = () => {
|
|
1273
|
+
signal?.removeEventListener("abort", abort);
|
|
1274
|
+
resolve2();
|
|
1275
|
+
};
|
|
1276
|
+
const timer = setTimeout(finish, POLL_INTERVAL_MS);
|
|
1277
|
+
const abort = () => {
|
|
1278
|
+
clearTimeout(timer);
|
|
1279
|
+
signal?.removeEventListener("abort", abort);
|
|
1280
|
+
const reason = signal?.reason;
|
|
1281
|
+
reject(reason instanceof Error ? reason : new Error(String(reason)));
|
|
1282
|
+
};
|
|
1283
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1284
|
+
if (signal?.aborted) abort();
|
|
1285
|
+
});
|
|
1225
1286
|
continue;
|
|
1226
1287
|
case "refused":
|
|
1227
1288
|
case "failed":
|
|
@@ -1232,11 +1293,10 @@ async function compileSwiftProject(submit, work, origin) {
|
|
|
1232
1293
|
}
|
|
1233
1294
|
}
|
|
1234
1295
|
|
|
1235
|
-
// src/
|
|
1296
|
+
// src/swift-host.ts
|
|
1236
1297
|
var ARTIFACT_PATH = "/__peach/swift/";
|
|
1237
1298
|
var RESOURCE_PATH = "/__peach/swift-res/";
|
|
1238
1299
|
var ICU_PATH = "/__peach/swift-icu/";
|
|
1239
|
-
var VIRTUAL_PREFIX = "\0peach-swift:";
|
|
1240
1300
|
var SKIP_SOURCE_DIRS = /* @__PURE__ */ new Set([
|
|
1241
1301
|
"node_modules",
|
|
1242
1302
|
"ios",
|
|
@@ -1251,89 +1311,124 @@ function swiftPackageId(packagePath) {
|
|
|
1251
1311
|
return import_node_path5.default.basename(packagePath).replace(/[^A-Za-z0-9_]/g, "_").replace(/^(\d)/, "_$1");
|
|
1252
1312
|
}
|
|
1253
1313
|
function nativeSourceDescriptor(packagePath) {
|
|
1314
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1254
1315
|
const file = import_node_path5.default.join(packagePath, NATIVE_DESCRIPTOR);
|
|
1255
1316
|
if (!import_node_fs4.default.existsSync(file)) return null;
|
|
1256
|
-
const value = JSON.parse(
|
|
1317
|
+
const value = JSON.parse(
|
|
1318
|
+
readPackageFile(packagePath, file, MAX_SWIFT_COMPILE_SOURCE_BYTES).toString("utf8")
|
|
1319
|
+
);
|
|
1257
1320
|
const invalid = () => new Error(`${file}: invalid One native source descriptor; run one typegen`);
|
|
1258
1321
|
if (!value || typeof value !== "object" || Reflect.get(value, "generatedBy") !== "one typegen" || !import_node_fs4.default.existsSync(import_node_path5.default.join(packagePath, NATIVE_GLUE))) {
|
|
1259
1322
|
throw invalid();
|
|
1260
1323
|
}
|
|
1261
|
-
|
|
1262
|
-
const hash = Reflect.get(value, "hash");
|
|
1263
|
-
const rawFiles = Reflect.get(value, "files");
|
|
1264
|
-
const rawModules = Reflect.get(value, "modules");
|
|
1265
|
-
const rawDefaults = Reflect.get(value, "defaultViewFiles");
|
|
1266
|
-
if (typeof packageId !== "string" || typeof hash !== "string" || !rawFiles || typeof rawFiles !== "object" || !rawModules || typeof rawModules !== "object" || !Array.isArray(rawDefaults) || !rawDefaults.every((name) => typeof name === "string")) {
|
|
1324
|
+
if (!isSwiftNativeModules(value) || value.packageId !== swiftPackageId(packagePath)) {
|
|
1267
1325
|
throw invalid();
|
|
1268
1326
|
}
|
|
1269
|
-
|
|
1270
|
-
const modules = {};
|
|
1271
|
-
for (const [key, names] of Object.entries(rawFiles)) {
|
|
1272
|
-
if (!Array.isArray(names) || !names.every((name) => typeof name === "string"))
|
|
1273
|
-
throw invalid();
|
|
1274
|
-
files[key] = names;
|
|
1275
|
-
}
|
|
1276
|
-
for (const [key, names] of Object.entries(rawModules)) {
|
|
1277
|
-
if (!Array.isArray(names) || !names.every((name) => typeof name === "string"))
|
|
1278
|
-
throw invalid();
|
|
1279
|
-
modules[key] = names;
|
|
1280
|
-
}
|
|
1281
|
-
if (packageId !== swiftPackageId(packagePath)) {
|
|
1282
|
-
throw new Error(`${file}: invalid One native source descriptor; run one typegen`);
|
|
1283
|
-
}
|
|
1284
|
-
return { packageId, hash, files, modules, defaultViewFiles: rawDefaults };
|
|
1327
|
+
return value;
|
|
1285
1328
|
}
|
|
1286
1329
|
function nativeSourceFiles(packagePath) {
|
|
1330
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1287
1331
|
return [NATIVE_DESCRIPTOR, NATIVE_GLUE].map((name) => import_node_path5.default.join(packagePath, name)).filter((file) => import_node_fs4.default.existsSync(file));
|
|
1288
1332
|
}
|
|
1289
1333
|
var projects = /* @__PURE__ */ new Map();
|
|
1290
|
-
|
|
1291
|
-
|
|
1334
|
+
function projectFor(packagePath, hosted) {
|
|
1335
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1292
1336
|
const existing = projects.get(packagePath);
|
|
1293
|
-
if (existing)
|
|
1337
|
+
if (existing) {
|
|
1338
|
+
if (hosted && !existing.hosted) {
|
|
1339
|
+
throw new Error("a Swift package cannot share local and hosted compile ownership");
|
|
1340
|
+
}
|
|
1341
|
+
return existing;
|
|
1342
|
+
}
|
|
1294
1343
|
const created = {
|
|
1295
1344
|
packagePath,
|
|
1296
1345
|
artifact: null,
|
|
1297
1346
|
building: null,
|
|
1298
|
-
resourceFiles: /* @__PURE__ */ new Map()
|
|
1347
|
+
resourceFiles: /* @__PURE__ */ new Map(),
|
|
1348
|
+
resourcesPrevious: /* @__PURE__ */ new Map(),
|
|
1349
|
+
artifacts: [],
|
|
1350
|
+
hosted
|
|
1299
1351
|
};
|
|
1300
1352
|
projects.set(packagePath, created);
|
|
1301
1353
|
return created;
|
|
1302
1354
|
}
|
|
1303
|
-
function
|
|
1355
|
+
function packageFiles(root) {
|
|
1356
|
+
const canonicalRoot = import_node_fs4.default.realpathSync(root);
|
|
1304
1357
|
const found = [];
|
|
1305
1358
|
const walk = (dir) => {
|
|
1306
|
-
for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true })) {
|
|
1307
|
-
if (entry.name.startsWith(".") || SKIP_SOURCE_DIRS.has(entry.name))
|
|
1308
|
-
const full = import_node_path5.default.join(dir, entry.name);
|
|
1309
|
-
if (entry.isDirectory()) {
|
|
1310
|
-
if (full !== root && import_node_fs4.default.existsSync(import_node_path5.default.join(full, "Package.swift"))) continue;
|
|
1311
|
-
walk(full);
|
|
1312
|
-
} else if (entry.name.endsWith(".swift") && (entry.isFile() || entry.isSymbolicLink() && import_node_fs4.default.statSync(full).isFile()))
|
|
1313
|
-
found.push(full);
|
|
1314
|
-
}
|
|
1315
|
-
};
|
|
1316
|
-
walk(root);
|
|
1317
|
-
return found;
|
|
1318
|
-
}
|
|
1319
|
-
function resourceCandidateFiles(root) {
|
|
1320
|
-
const found = [];
|
|
1321
|
-
const walk = (dir) => {
|
|
1322
|
-
for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true })) {
|
|
1323
|
-
if (entry.name.startsWith(".") || SKIP_SOURCE_DIRS.has(entry.name) || entry.name === ".build")
|
|
1359
|
+
for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
|
|
1360
|
+
if (entry.name.startsWith(".") && entry.name !== NATIVE_DESCRIPTOR && entry.name !== NATIVE_GLUE || SKIP_SOURCE_DIRS.has(entry.name))
|
|
1324
1361
|
continue;
|
|
1325
1362
|
const full = import_node_path5.default.join(dir, entry.name);
|
|
1363
|
+
if (entry.isSymbolicLink()) throw new Error(`swift input is a symlink: ${full}`);
|
|
1364
|
+
const real = import_node_fs4.default.realpathSync(full);
|
|
1365
|
+
const relative = import_node_path5.default.relative(canonicalRoot, real);
|
|
1366
|
+
if (relative.startsWith(`..${import_node_path5.default.sep}`) || relative === ".." || import_node_path5.default.isAbsolute(relative)) {
|
|
1367
|
+
throw new Error(`swift input escapes the selected package: ${full}`);
|
|
1368
|
+
}
|
|
1326
1369
|
if (entry.isDirectory()) {
|
|
1327
|
-
if (
|
|
1370
|
+
if (import_node_fs4.default.existsSync(import_node_path5.default.join(full, "Package.swift"))) continue;
|
|
1328
1371
|
walk(full);
|
|
1329
|
-
} else {
|
|
1372
|
+
} else if (entry.isFile()) {
|
|
1330
1373
|
found.push(full);
|
|
1374
|
+
if (found.length > 4096) throw new Error("swift package exceeds 4096 input files");
|
|
1331
1375
|
}
|
|
1332
1376
|
}
|
|
1333
1377
|
};
|
|
1334
|
-
walk(
|
|
1378
|
+
walk(canonicalRoot);
|
|
1335
1379
|
return found;
|
|
1336
1380
|
}
|
|
1381
|
+
function readPackageFile(root, file, maxBytes) {
|
|
1382
|
+
const canonicalRoot = import_node_fs4.default.realpathSync(root);
|
|
1383
|
+
const relative = import_node_path5.default.relative(canonicalRoot, import_node_fs4.default.realpathSync(file));
|
|
1384
|
+
if (relative === ".." || relative.startsWith(`..${import_node_path5.default.sep}`) || import_node_path5.default.isAbsolute(relative)) {
|
|
1385
|
+
throw new Error(`swift input escapes the selected package: ${file}`);
|
|
1386
|
+
}
|
|
1387
|
+
let ancestor = import_node_path5.default.resolve(file);
|
|
1388
|
+
while (ancestor !== canonicalRoot) {
|
|
1389
|
+
if (import_node_fs4.default.lstatSync(ancestor).isSymbolicLink()) {
|
|
1390
|
+
throw new Error(`swift input is a symlink: ${ancestor}`);
|
|
1391
|
+
}
|
|
1392
|
+
const parent = import_node_path5.default.dirname(ancestor);
|
|
1393
|
+
if (parent === ancestor)
|
|
1394
|
+
throw new Error(`swift input escapes the selected package: ${file}`);
|
|
1395
|
+
ancestor = parent;
|
|
1396
|
+
}
|
|
1397
|
+
const expected = import_node_fs4.default.statSync(file);
|
|
1398
|
+
const fd = import_node_fs4.default.openSync(file, import_node_fs4.default.constants.O_RDONLY | import_node_fs4.default.constants.O_NOFOLLOW);
|
|
1399
|
+
try {
|
|
1400
|
+
const stat = import_node_fs4.default.fstatSync(fd);
|
|
1401
|
+
if (stat.dev !== expected.dev || stat.ino !== expected.ino) {
|
|
1402
|
+
throw new Error(`swift input changed while opening: ${file}`);
|
|
1403
|
+
}
|
|
1404
|
+
if (!stat.isFile() || stat.size > maxBytes) {
|
|
1405
|
+
throw new Error(`swift input exceeds ${maxBytes} bytes: ${file}`);
|
|
1406
|
+
}
|
|
1407
|
+
const bytes = Buffer.alloc(stat.size + 1);
|
|
1408
|
+
let offset = 0;
|
|
1409
|
+
while (offset < bytes.length) {
|
|
1410
|
+
const count = import_node_fs4.default.readSync(fd, bytes, offset, bytes.length - offset, null);
|
|
1411
|
+
if (count === 0) break;
|
|
1412
|
+
offset += count;
|
|
1413
|
+
}
|
|
1414
|
+
if (offset !== stat.size || import_node_fs4.default.fstatSync(fd).size !== stat.size) {
|
|
1415
|
+
throw new Error(`swift input changed while reading: ${file}`);
|
|
1416
|
+
}
|
|
1417
|
+
return bytes.subarray(0, offset);
|
|
1418
|
+
} finally {
|
|
1419
|
+
import_node_fs4.default.closeSync(fd);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
function sourceFiles(root) {
|
|
1423
|
+
const files = packageFiles(root).filter((file) => file.endsWith(".swift"));
|
|
1424
|
+
if (files.length > MAX_SWIFT_COMPILE_FILES || files.reduce((total, file) => total + import_node_fs4.default.statSync(file).size, 0) > MAX_SWIFT_COMPILE_SOURCE_BYTES) {
|
|
1425
|
+
throw new Error("swift sources exceed the compile service caps");
|
|
1426
|
+
}
|
|
1427
|
+
return files;
|
|
1428
|
+
}
|
|
1429
|
+
function resourceCandidateFiles(root) {
|
|
1430
|
+
return packageFiles(root).filter((file) => !file.endsWith(".swift"));
|
|
1431
|
+
}
|
|
1337
1432
|
var RESOURCE_CONTENT_TYPES = {
|
|
1338
1433
|
".avif": "image/avif",
|
|
1339
1434
|
".bmp": "image/bmp",
|
|
@@ -1354,11 +1449,11 @@ function buildSwiftResourceTable(project, baseUrl) {
|
|
|
1354
1449
|
const file = byRelative.get(candidate);
|
|
1355
1450
|
if (!file || !/(^|\/)Contents\.json$|\.symbolset\/[^/]+\.svg$/.test(candidate))
|
|
1356
1451
|
return null;
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1452
|
+
return readPackageFile(
|
|
1453
|
+
project.packagePath,
|
|
1454
|
+
file,
|
|
1455
|
+
MAX_SWIFT_COMPILE_RESOURCE_BYTES
|
|
1456
|
+
).toString("utf8");
|
|
1362
1457
|
};
|
|
1363
1458
|
const found = enumerateBundleImages(relative, readContents);
|
|
1364
1459
|
const colors = enumerateBundleColors(relative, readContents);
|
|
@@ -1367,15 +1462,19 @@ function buildSwiftResourceTable(project, baseUrl) {
|
|
|
1367
1462
|
const images = {};
|
|
1368
1463
|
const watched = [];
|
|
1369
1464
|
const registered = /* @__PURE__ */ new Map();
|
|
1465
|
+
let imageBytes = 0;
|
|
1370
1466
|
for (const { name, file, scale } of found) {
|
|
1371
1467
|
const disk = byRelative.get(file);
|
|
1372
1468
|
if (!disk) continue;
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
bytes = import_node_fs4.default.readFileSync(disk);
|
|
1376
|
-
} catch {
|
|
1377
|
-
continue;
|
|
1469
|
+
if (Object.keys(images).length >= MAX_SWIFT_COMPILE_IMAGES || imageBytes + import_node_fs4.default.statSync(disk).size > MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES) {
|
|
1470
|
+
throw new Error("swift image pack exceeds the compile service caps");
|
|
1378
1471
|
}
|
|
1472
|
+
const bytes = readPackageFile(
|
|
1473
|
+
project.packagePath,
|
|
1474
|
+
disk,
|
|
1475
|
+
MAX_SWIFT_COMPILE_IMAGE_BYTES
|
|
1476
|
+
);
|
|
1477
|
+
imageBytes += bytes.length;
|
|
1379
1478
|
const hash = (0, import_node_crypto3.createHash)("sha256").update(bytes).digest("hex").slice(0, 16);
|
|
1380
1479
|
const ext = import_node_path5.default.posix.extname(file).toLowerCase();
|
|
1381
1480
|
table[name] = { uri: `${baseUrl}${RESOURCE_PATH}${hash}${ext}`, scale };
|
|
@@ -1386,65 +1485,60 @@ function buildSwiftResourceTable(project, baseUrl) {
|
|
|
1386
1485
|
watched.push(file);
|
|
1387
1486
|
const contents = file.replace(/\/[^/]+$/, "/Contents.json");
|
|
1388
1487
|
if (byRelative.has(contents)) watched.push(contents);
|
|
1389
|
-
registered.set(`${hash}${ext}`,
|
|
1488
|
+
registered.set(`${hash}${ext}`, {
|
|
1489
|
+
bytes,
|
|
1490
|
+
contentType: RESOURCE_CONTENT_TYPES[ext] ?? "application/octet-stream"
|
|
1491
|
+
});
|
|
1390
1492
|
}
|
|
1391
1493
|
for (const file of relative) {
|
|
1392
1494
|
if (file.endsWith(".colorset/Contents.json") || file.includes(".symbolset/"))
|
|
1393
1495
|
watched.push(file);
|
|
1394
1496
|
}
|
|
1395
|
-
project.resourceFiles
|
|
1497
|
+
if (registered.size !== project.resourceFiles.size || [...registered].some(
|
|
1498
|
+
([key, value]) => !project.resourceFiles.get(key)?.bytes.equals(value.bytes)
|
|
1499
|
+
)) {
|
|
1500
|
+
project.resourcesPrevious = project.resourceFiles;
|
|
1501
|
+
project.resourceFiles = registered;
|
|
1502
|
+
}
|
|
1396
1503
|
return { table, images, colors, symbols, watched };
|
|
1397
1504
|
}
|
|
1398
|
-
var BUNDLE_MAX_FILES =
|
|
1399
|
-
var BUNDLE_MAX_FILE_BYTES =
|
|
1400
|
-
var BUNDLE_MAX_TOTAL_BYTES =
|
|
1505
|
+
var BUNDLE_MAX_FILES = MAX_SWIFT_COMPILE_RESOURCES;
|
|
1506
|
+
var BUNDLE_MAX_FILE_BYTES = MAX_SWIFT_COMPILE_RESOURCE_BYTES;
|
|
1507
|
+
var BUNDLE_MAX_TOTAL_BYTES = MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES;
|
|
1401
1508
|
function buildSwiftBundleFiles(packagePath) {
|
|
1509
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1402
1510
|
const relative = resourceCandidateFiles(packagePath).map(
|
|
1403
1511
|
(file) => import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep)
|
|
1404
1512
|
);
|
|
1405
1513
|
const files = {};
|
|
1406
1514
|
const watched = [];
|
|
1407
|
-
const skipped = [];
|
|
1408
1515
|
let total = 0;
|
|
1409
1516
|
for (const { base, file } of enumerateBundleJson(relative)) {
|
|
1410
1517
|
watched.push(file);
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
continue;
|
|
1416
|
-
}
|
|
1417
|
-
if (bytes.length > BUNDLE_MAX_FILE_BYTES) {
|
|
1418
|
-
skipped.push(`${file} (${bytes.length} bytes past the per-file cap)`);
|
|
1419
|
-
continue;
|
|
1420
|
-
}
|
|
1421
|
-
if (Object.keys(files).length >= BUNDLE_MAX_FILES || total + bytes.length > BUNDLE_MAX_TOTAL_BYTES) {
|
|
1422
|
-
skipped.push(
|
|
1423
|
-
`${file} (pack caps: ${BUNDLE_MAX_FILES} files / ${BUNDLE_MAX_TOTAL_BYTES} bytes)`
|
|
1518
|
+
const disk = import_node_path5.default.join(packagePath, ...file.split("/"));
|
|
1519
|
+
if (Object.keys(files).length >= BUNDLE_MAX_FILES || total + import_node_fs4.default.statSync(disk).size > BUNDLE_MAX_TOTAL_BYTES) {
|
|
1520
|
+
throw new Error(
|
|
1521
|
+
`swift bundle pack exceeds ${BUNDLE_MAX_FILES} files / ${BUNDLE_MAX_TOTAL_BYTES} bytes`
|
|
1424
1522
|
);
|
|
1425
|
-
continue;
|
|
1426
1523
|
}
|
|
1524
|
+
const bytes = readPackageFile(packagePath, disk, BUNDLE_MAX_FILE_BYTES);
|
|
1427
1525
|
files[base] = bytes.toString("base64");
|
|
1428
1526
|
total += bytes.length;
|
|
1429
1527
|
}
|
|
1430
|
-
return { files, watched
|
|
1528
|
+
return { files, watched };
|
|
1431
1529
|
}
|
|
1432
1530
|
function serveSwiftResource(project, key) {
|
|
1433
|
-
|
|
1434
|
-
if (!disk) return null;
|
|
1435
|
-
try {
|
|
1436
|
-
return {
|
|
1437
|
-
bytes: import_node_fs4.default.readFileSync(disk),
|
|
1438
|
-
contentType: RESOURCE_CONTENT_TYPES[import_node_path5.default.extname(disk).toLowerCase()] ?? "application/octet-stream"
|
|
1439
|
-
};
|
|
1440
|
-
} catch {
|
|
1441
|
-
return null;
|
|
1442
|
-
}
|
|
1531
|
+
return project.resourceFiles.get(key) ?? project.resourcesPrevious.get(key) ?? null;
|
|
1443
1532
|
}
|
|
1444
1533
|
function linkedModuleRoots(packagePath) {
|
|
1534
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1445
1535
|
let manifest;
|
|
1446
1536
|
try {
|
|
1447
|
-
manifest =
|
|
1537
|
+
manifest = readPackageFile(
|
|
1538
|
+
packagePath,
|
|
1539
|
+
import_node_path5.default.join(packagePath, "Package.swift"),
|
|
1540
|
+
MAX_SWIFT_COMPILE_SOURCE_BYTES
|
|
1541
|
+
).toString("utf8");
|
|
1448
1542
|
} catch {
|
|
1449
1543
|
return [];
|
|
1450
1544
|
}
|
|
@@ -1456,25 +1550,16 @@ function linkedModuleRoots(packagePath) {
|
|
|
1456
1550
|
}
|
|
1457
1551
|
return [...roots].sort();
|
|
1458
1552
|
}
|
|
1459
|
-
function sourceStamp(packagePath, moduleRootOverride) {
|
|
1553
|
+
function sourceStamp(packagePath, moduleRootOverride, hosted = false) {
|
|
1460
1554
|
const hash = (0, import_node_crypto3.createHash)("sha256");
|
|
1461
1555
|
hash.update(packagePath);
|
|
1462
|
-
const projectInputs =
|
|
1463
|
-
import_node_path5.default.join(packagePath, "Package.swift"),
|
|
1464
|
-
...sourceFiles(packagePath),
|
|
1465
|
-
...nativeSourceFiles(packagePath),
|
|
1466
|
-
...buildSwiftBundleFiles(packagePath).watched.map(
|
|
1467
|
-
(file) => import_node_path5.default.join(packagePath, ...file.split(import_node_path5.default.posix.sep))
|
|
1468
|
-
),
|
|
1469
|
-
...buildSwiftResourceTable(projectFor(packagePath), "").watched.map(
|
|
1470
|
-
(file) => import_node_path5.default.join(packagePath, ...file.split(import_node_path5.default.posix.sep))
|
|
1471
|
-
)
|
|
1472
|
-
]);
|
|
1556
|
+
const projectInputs = new Set(packageFiles(packagePath));
|
|
1473
1557
|
for (const file of [...projectInputs].sort()) {
|
|
1474
1558
|
hash.update(import_node_path5.default.relative(packagePath, file));
|
|
1475
|
-
|
|
1559
|
+
const stat = import_node_fs4.default.statSync(file);
|
|
1560
|
+
hash.update(`${stat.mtimeMs}/${stat.ctimeMs}/${stat.size}`);
|
|
1476
1561
|
}
|
|
1477
|
-
const moduleRoot = moduleRootOverride ?? linkedModuleRoots(packagePath).find(
|
|
1562
|
+
const moduleRoot = hosted ? void 0 : moduleRootOverride ?? linkedModuleRoots(packagePath).find(
|
|
1478
1563
|
(root) => import_node_fs4.default.existsSync(import_node_path5.default.join(root, "toolchain.json"))
|
|
1479
1564
|
);
|
|
1480
1565
|
if (moduleRoot) {
|
|
@@ -1490,46 +1575,85 @@ function entryRootId(packagePath, file) {
|
|
|
1490
1575
|
const relative = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
|
|
1491
1576
|
return `${import_node_path5.default.basename(packagePath)}${import_node_path5.default.posix.sep}${relative}`;
|
|
1492
1577
|
}
|
|
1493
|
-
function serverOrigin() {
|
|
1494
|
-
const address = devServer?.httpServer?.address();
|
|
1495
|
-
const port = address && typeof address === "object" ? address.port : devServer?.config.server.port;
|
|
1496
|
-
if (!port) throw new Error("the swift urls need the dev server port");
|
|
1497
|
-
return `http://localhost:${port}`;
|
|
1498
|
-
}
|
|
1499
|
-
function artifactUrl(project, artifact) {
|
|
1500
|
-
return `${serverOrigin()}${ARTIFACT_PATH}${artifact.hash}.wasm`;
|
|
1501
|
-
}
|
|
1502
1578
|
function icuUrl(origin, artifact) {
|
|
1503
1579
|
return "url" in artifact.icu ? artifact.icu.url : `${origin}${ICU_PATH}${artifact.icu.sha256}`;
|
|
1504
1580
|
}
|
|
1505
1581
|
function packageSources(packagePath) {
|
|
1582
|
+
const sources = sourceFiles(packagePath);
|
|
1583
|
+
if (sources.length > MAX_SWIFT_COMPILE_FILES)
|
|
1584
|
+
throw new Error("swift source file cap exceeded");
|
|
1585
|
+
let total = 0;
|
|
1586
|
+
for (const file of sources) total += import_node_fs4.default.statSync(file).size;
|
|
1587
|
+
if (total > MAX_SWIFT_COMPILE_SOURCE_BYTES)
|
|
1588
|
+
throw new Error("swift source byte cap exceeded");
|
|
1506
1589
|
const files = {};
|
|
1507
|
-
for (const file of
|
|
1590
|
+
for (const file of sources) {
|
|
1508
1591
|
const relative = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
|
|
1509
|
-
files[relative] =
|
|
1592
|
+
files[relative] = readPackageFile(
|
|
1593
|
+
packagePath,
|
|
1594
|
+
file,
|
|
1595
|
+
MAX_SWIFT_COMPILE_SOURCE_BYTES
|
|
1596
|
+
).toString("utf8");
|
|
1510
1597
|
}
|
|
1511
|
-
const manifest = import_node_path5.default.join(packagePath, "Package.swift");
|
|
1512
|
-
if (import_node_fs4.default.existsSync(manifest)) files["Package.swift"] = import_node_fs4.default.readFileSync(manifest, "utf8");
|
|
1513
1598
|
return files;
|
|
1514
1599
|
}
|
|
1515
|
-
function
|
|
1600
|
+
function packageSnapshot(project) {
|
|
1601
|
+
const files = packageSources(project.packagePath);
|
|
1602
|
+
const native = nativeSourceDescriptor(project.packagePath);
|
|
1603
|
+
return {
|
|
1604
|
+
files,
|
|
1605
|
+
resources: buildSwiftResourceTable(project, ""),
|
|
1606
|
+
bundleFiles: buildSwiftBundleFiles(project.packagePath),
|
|
1607
|
+
native,
|
|
1608
|
+
...native ? {
|
|
1609
|
+
glue: readPackageFile(
|
|
1610
|
+
project.packagePath,
|
|
1611
|
+
import_node_path5.default.join(project.packagePath, NATIVE_GLUE),
|
|
1612
|
+
MAX_SWIFT_COMPILE_SOURCE_BYTES
|
|
1613
|
+
).toString("utf8")
|
|
1614
|
+
} : {}
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
function snapshotCompileInput(snapshot, entry) {
|
|
1516
1618
|
const input = {
|
|
1517
|
-
files:
|
|
1518
|
-
resources:
|
|
1519
|
-
images:
|
|
1619
|
+
files: snapshot.files,
|
|
1620
|
+
resources: snapshot.bundleFiles.files,
|
|
1621
|
+
images: snapshot.resources.images,
|
|
1520
1622
|
entry,
|
|
1521
1623
|
oneModule: true
|
|
1522
1624
|
};
|
|
1523
|
-
return
|
|
1524
|
-
input,
|
|
1525
|
-
import_node_fs4.default.readFileSync(import_node_path5.default.join(packagePath, NATIVE_GLUE), "utf8")
|
|
1526
|
-
) : input;
|
|
1625
|
+
return snapshot.glue ? withNativeSourceGlue(input, snapshot.glue) : input;
|
|
1527
1626
|
}
|
|
1528
|
-
|
|
1627
|
+
function compileInput(packagePath, entry) {
|
|
1628
|
+
return snapshotCompileInput(packageSnapshot(projectFor(packagePath)), entry);
|
|
1629
|
+
}
|
|
1630
|
+
async function compile(packagePath, entry, stamp, moduleRootOverride, hosted, snapshot) {
|
|
1631
|
+
const resources = {
|
|
1632
|
+
table: snapshot.resources.table,
|
|
1633
|
+
colors: snapshot.resources.colors,
|
|
1634
|
+
symbols: snapshot.resources.symbols,
|
|
1635
|
+
watched: snapshot.resources.watched
|
|
1636
|
+
};
|
|
1637
|
+
const content = {
|
|
1638
|
+
resources,
|
|
1639
|
+
bundleFiles: snapshot.bundleFiles,
|
|
1640
|
+
native: snapshot.native
|
|
1641
|
+
};
|
|
1642
|
+
if (hosted)
|
|
1643
|
+
return {
|
|
1644
|
+
...await compileRemote(packagePath, entry, snapshot, hosted),
|
|
1645
|
+
stamp,
|
|
1646
|
+
package: content
|
|
1647
|
+
};
|
|
1529
1648
|
const moduleRoot = moduleRootOverride ?? linkedModuleRoots(packagePath).find(
|
|
1530
1649
|
(root) => import_node_fs4.default.existsSync(import_node_path5.default.join(root, "toolchain.json"))
|
|
1531
1650
|
);
|
|
1532
|
-
if (!moduleRoot)
|
|
1651
|
+
if (!moduleRoot)
|
|
1652
|
+
return {
|
|
1653
|
+
...await compileRemote(packagePath, entry, snapshot),
|
|
1654
|
+
stamp,
|
|
1655
|
+
package: content
|
|
1656
|
+
};
|
|
1533
1657
|
const toolchain = JSON.parse(
|
|
1534
1658
|
import_node_fs4.default.readFileSync(import_node_path5.default.join(moduleRoot, "toolchain.json"), "utf8")
|
|
1535
1659
|
);
|
|
@@ -1537,7 +1661,7 @@ async function compile(packagePath, entry, stamp, moduleRootOverride) {
|
|
|
1537
1661
|
if (typeof release !== "string") {
|
|
1538
1662
|
throw new Error(`swift toolchain manifest at ${moduleRoot} has no release`);
|
|
1539
1663
|
}
|
|
1540
|
-
const artifact = await compileSwiftProjectUnit(
|
|
1664
|
+
const artifact = await compileSwiftProjectUnit(snapshotCompileInput(snapshot, entry), {
|
|
1541
1665
|
// the compile rewrites Sources/App in its root before swiftpm builds, and
|
|
1542
1666
|
// its lock orders one process only: two vites on one root (a lane's dev
|
|
1543
1667
|
// server and a capture, or two checkouts) build each other's sources. so
|
|
@@ -1555,50 +1679,75 @@ async function compile(packagePath, entry, stamp, moduleRootOverride) {
|
|
|
1555
1679
|
`Library/Developer/Toolchains/${release}.xctoolchain/usr/bin`
|
|
1556
1680
|
)
|
|
1557
1681
|
});
|
|
1558
|
-
return { ...artifact, stamp };
|
|
1682
|
+
return { ...artifact, stamp, package: content };
|
|
1559
1683
|
}
|
|
1560
|
-
async function compileRemote(packagePath, entry) {
|
|
1561
|
-
const auth = resolveCliAuth();
|
|
1562
|
-
if (!auth || auth.kind === "github") {
|
|
1684
|
+
async function compileRemote(packagePath, entry, snapshot, hosted) {
|
|
1685
|
+
const auth = hosted ? null : resolveCliAuth();
|
|
1686
|
+
if (!hosted && (!auth || auth.kind === "github")) {
|
|
1563
1687
|
throw new Error(
|
|
1564
1688
|
`compiling ${import_node_path5.default.basename(packagePath)} for Peach needs \`peach login\` or PEACH_API_KEY: this peachsim has no local SwiftUI module, so Contrast compiles it`
|
|
1565
1689
|
);
|
|
1566
1690
|
}
|
|
1567
|
-
const origin = resolveContrastBackendOrigin(
|
|
1568
|
-
|
|
1569
|
-
|
|
1691
|
+
const origin = hosted?.origin ?? resolveContrastBackendOrigin(auth?.kind === "session" ? auth.origin : null);
|
|
1692
|
+
const authorization = hosted?.authorization ?? (auth ? authHeaderValue(auth) : void 0);
|
|
1693
|
+
const signal = AbortSignal.any([
|
|
1694
|
+
...hosted ? [hosted.signal] : [],
|
|
1695
|
+
AbortSignal.timeout(5 * 6e4)
|
|
1696
|
+
]);
|
|
1570
1697
|
const submit = httpSwiftCompileSubmit({
|
|
1571
1698
|
endpoint: origin,
|
|
1572
|
-
authorization
|
|
1699
|
+
authorization,
|
|
1700
|
+
signal
|
|
1573
1701
|
});
|
|
1574
1702
|
if (!submit) throw new Error("swift compile: no credential to submit with");
|
|
1575
|
-
const descriptor =
|
|
1703
|
+
const descriptor = snapshot.native;
|
|
1576
1704
|
const address = await compileSwiftProject(
|
|
1577
1705
|
submit,
|
|
1578
1706
|
{
|
|
1579
|
-
files:
|
|
1707
|
+
files: snapshot.files,
|
|
1708
|
+
resources: snapshot.bundleFiles.files,
|
|
1709
|
+
images: snapshot.resources.images,
|
|
1580
1710
|
entry,
|
|
1581
1711
|
packageId: descriptor?.packageId ?? swiftPackageId(packagePath)
|
|
1582
1712
|
},
|
|
1583
|
-
origin
|
|
1713
|
+
origin,
|
|
1714
|
+
signal
|
|
1584
1715
|
);
|
|
1585
1716
|
if (descriptor && address.native?.hash !== descriptor.hash) {
|
|
1586
1717
|
throw new Error(
|
|
1587
1718
|
`${import_node_path5.default.basename(packagePath)}: Contrast compiled native contract ${address.native?.hash ?? "none"} but one typegen wrote ${descriptor.hash}; the app's One and the compile host's differ, or the compile host is older than this peachsim`
|
|
1588
1719
|
);
|
|
1589
1720
|
}
|
|
1590
|
-
const response = await fetch(address.url);
|
|
1721
|
+
const response = await fetch(address.url, { signal });
|
|
1591
1722
|
if (!response.ok) {
|
|
1592
1723
|
throw new Error(`swift compile: ${address.url} answered ${response.status}`);
|
|
1593
1724
|
}
|
|
1725
|
+
const maxArtifactBytes = 64 * 1024 * 1024;
|
|
1726
|
+
if (Number(response.headers.get("content-length")) > maxArtifactBytes || !response.body) {
|
|
1727
|
+
throw new Error("swift compile: artifact exceeds 64 MiB or has no body");
|
|
1728
|
+
}
|
|
1729
|
+
const reader = response.body.getReader();
|
|
1730
|
+
const chunks = [];
|
|
1731
|
+
let total = 0;
|
|
1732
|
+
for (; ; ) {
|
|
1733
|
+
signal.throwIfAborted();
|
|
1734
|
+
const next = await reader.read();
|
|
1735
|
+
if (next.done) break;
|
|
1736
|
+
total += next.value.byteLength;
|
|
1737
|
+
if (total > maxArtifactBytes) {
|
|
1738
|
+
await reader.cancel();
|
|
1739
|
+
throw new Error("swift compile: artifact exceeds 64 MiB");
|
|
1740
|
+
}
|
|
1741
|
+
chunks.push(next.value);
|
|
1742
|
+
}
|
|
1594
1743
|
return {
|
|
1595
1744
|
hash: address.hash,
|
|
1596
|
-
bytes: Buffer.
|
|
1745
|
+
bytes: Buffer.concat(chunks),
|
|
1597
1746
|
icu: { url: address.icuUrl }
|
|
1598
1747
|
};
|
|
1599
1748
|
}
|
|
1600
1749
|
function artifactFor(project, entry, moduleRoot) {
|
|
1601
|
-
const stamp = sourceStamp(project.packagePath, moduleRoot);
|
|
1750
|
+
const stamp = sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted));
|
|
1602
1751
|
if (project.artifact?.stamp === stamp) return Promise.resolve(project.artifact);
|
|
1603
1752
|
if (project.building) {
|
|
1604
1753
|
const running = project.building;
|
|
@@ -1606,9 +1755,24 @@ function artifactFor(project, entry, moduleRoot) {
|
|
|
1606
1755
|
const again = () => artifactFor(project, entry, moduleRoot);
|
|
1607
1756
|
return running.promise.then(again, again);
|
|
1608
1757
|
}
|
|
1609
|
-
const
|
|
1758
|
+
const snapshot = packageSnapshot(project);
|
|
1759
|
+
if (sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) !== stamp) {
|
|
1760
|
+
return artifactFor(project, entry, moduleRoot);
|
|
1761
|
+
}
|
|
1762
|
+
const promise = compile(
|
|
1763
|
+
project.packagePath,
|
|
1764
|
+
entry,
|
|
1765
|
+
stamp,
|
|
1766
|
+
moduleRoot,
|
|
1767
|
+
project.hosted,
|
|
1768
|
+
snapshot
|
|
1769
|
+
).then(
|
|
1610
1770
|
(artifact) => {
|
|
1611
1771
|
project.artifact = artifact;
|
|
1772
|
+
project.artifacts = [
|
|
1773
|
+
artifact,
|
|
1774
|
+
...project.artifacts.filter((old) => old.hash !== artifact.hash)
|
|
1775
|
+
].slice(0, 2);
|
|
1612
1776
|
project.building = null;
|
|
1613
1777
|
return artifact;
|
|
1614
1778
|
},
|
|
@@ -1617,10 +1781,14 @@ function artifactFor(project, entry, moduleRoot) {
|
|
|
1617
1781
|
throw error;
|
|
1618
1782
|
}
|
|
1619
1783
|
);
|
|
1620
|
-
|
|
1621
|
-
|
|
1784
|
+
const fresh = promise.then(
|
|
1785
|
+
(artifact) => sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) === artifact.stamp ? artifact : artifactFor(project, entry, moduleRoot)
|
|
1786
|
+
);
|
|
1787
|
+
project.building = { stamp, promise: fresh };
|
|
1788
|
+
return fresh;
|
|
1622
1789
|
}
|
|
1623
1790
|
function swiftPackageWatchFiles(packagePath, moduleRoot) {
|
|
1791
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1624
1792
|
return [
|
|
1625
1793
|
import_node_path5.default.join(packagePath, "Package.swift"),
|
|
1626
1794
|
...sourceFiles(packagePath),
|
|
@@ -1629,9 +1797,12 @@ function swiftPackageWatchFiles(packagePath, moduleRoot) {
|
|
|
1629
1797
|
...moduleRoot ? swiftModuleInputFiles(moduleRoot).map((file) => import_node_path5.default.join(moduleRoot, file)) : []
|
|
1630
1798
|
];
|
|
1631
1799
|
}
|
|
1632
|
-
async function swiftPackageMetadata(packagePath, packageName, moduleRoot, origin) {
|
|
1800
|
+
async function swiftPackageMetadata(packagePath, packageName, moduleRoot, origin, hosted) {
|
|
1801
|
+
packagePath = import_node_fs4.default.realpathSync(packagePath);
|
|
1633
1802
|
const mains = sourceFiles(packagePath).filter(
|
|
1634
|
-
(file) => /@main\s+(?:public\s+)?struct\s+\w+\s*:/.test(
|
|
1803
|
+
(file) => /@main\s+(?:public\s+)?struct\s+\w+\s*:/.test(
|
|
1804
|
+
readPackageFile(packagePath, file, MAX_SWIFT_COMPILE_SOURCE_BYTES).toString("utf8")
|
|
1805
|
+
)
|
|
1635
1806
|
);
|
|
1636
1807
|
const native = nativeSourceDescriptor(packagePath);
|
|
1637
1808
|
if (mains.length > 1 || mains.length === 0 && !native) {
|
|
@@ -1639,27 +1810,32 @@ async function swiftPackageMetadata(packagePath, packageName, moduleRoot, origin
|
|
|
1639
1810
|
`swift package ${packageName} needs exactly one @main source or generated native modules; found ${mains.length}`
|
|
1640
1811
|
);
|
|
1641
1812
|
}
|
|
1642
|
-
const project = projectFor(packagePath);
|
|
1813
|
+
const project = projectFor(packagePath, hosted);
|
|
1643
1814
|
const entry = mains.length === 1 ? import_node_path5.default.relative(packagePath, mains[0]).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep) : Object.entries(native?.files ?? {}).find(
|
|
1644
1815
|
([_file, names]) => names.length > 0
|
|
1645
1816
|
)?.[0];
|
|
1646
1817
|
if (!entry) throw new Error(`swift package ${packageName} has no native module source`);
|
|
1647
1818
|
const artifact = await artifactFor(project, entry, moduleRoot);
|
|
1648
|
-
const resources =
|
|
1649
|
-
const bundleFiles =
|
|
1819
|
+
const resources = artifact.package.resources;
|
|
1820
|
+
const bundleFiles = artifact.package.bundleFiles;
|
|
1650
1821
|
return {
|
|
1651
1822
|
url: `${origin}${ARTIFACT_PATH}${artifact.hash}.wasm`,
|
|
1652
1823
|
hash: artifact.hash,
|
|
1653
1824
|
icuUrl: icuUrl(origin, artifact),
|
|
1654
1825
|
rootId: `${packageName}/${entry}`,
|
|
1655
|
-
resources:
|
|
1826
|
+
resources: Object.fromEntries(
|
|
1827
|
+
Object.entries(resources.table).map(([name, image]) => [
|
|
1828
|
+
name,
|
|
1829
|
+
{ ...image, uri: `${origin}${image.uri}` }
|
|
1830
|
+
])
|
|
1831
|
+
),
|
|
1656
1832
|
bundleFiles: bundleFiles.files,
|
|
1657
1833
|
colors: resources.colors,
|
|
1658
1834
|
symbols: resources.symbols,
|
|
1659
|
-
native: native ? {
|
|
1660
|
-
packageId: native.packageId,
|
|
1661
|
-
contractHash: native.hash,
|
|
1662
|
-
modules: native.modules,
|
|
1835
|
+
native: artifact.package.native ? {
|
|
1836
|
+
packageId: artifact.package.native.packageId,
|
|
1837
|
+
contractHash: artifact.package.native.hash,
|
|
1838
|
+
modules: artifact.package.native.modules,
|
|
1663
1839
|
defaultView: mains.length === 1
|
|
1664
1840
|
} : void 0
|
|
1665
1841
|
};
|
|
@@ -1680,7 +1856,9 @@ function serveSwiftPackageAsset(pathname, res) {
|
|
|
1680
1856
|
}
|
|
1681
1857
|
if (pathname.startsWith(ICU_PATH)) {
|
|
1682
1858
|
for (const project of projects.values()) {
|
|
1683
|
-
const icu = project.
|
|
1859
|
+
const icu = project.artifacts.find(
|
|
1860
|
+
(artifact) => "sha256" in artifact.icu && pathname === `${ICU_PATH}${artifact.icu.sha256}`
|
|
1861
|
+
)?.icu;
|
|
1684
1862
|
if (!icu || "url" in icu || pathname !== `${ICU_PATH}${icu.sha256}`) continue;
|
|
1685
1863
|
res.setHeader("access-control-allow-origin", "*");
|
|
1686
1864
|
res.setHeader("content-type", "application/gzip");
|
|
@@ -1694,7 +1872,9 @@ function serveSwiftPackageAsset(pathname, res) {
|
|
|
1694
1872
|
}
|
|
1695
1873
|
if (!pathname.startsWith(ARTIFACT_PATH)) return false;
|
|
1696
1874
|
for (const project of projects.values()) {
|
|
1697
|
-
const artifact = project.
|
|
1875
|
+
const artifact = project.artifacts.find(
|
|
1876
|
+
(artifact2) => pathname === `${ARTIFACT_PATH}${artifact2.hash}.wasm`
|
|
1877
|
+
);
|
|
1698
1878
|
if (!artifact || pathname !== `${ARTIFACT_PATH}${artifact.hash}.wasm`) continue;
|
|
1699
1879
|
res.setHeader("access-control-allow-origin", "*");
|
|
1700
1880
|
res.setHeader("content-type", "application/wasm");
|
|
@@ -1705,13 +1885,27 @@ function serveSwiftPackageAsset(pathname, res) {
|
|
|
1705
1885
|
res.end("swift artifact is stale");
|
|
1706
1886
|
return true;
|
|
1707
1887
|
}
|
|
1888
|
+
|
|
1889
|
+
// src/vite-plugin-swift.ts
|
|
1890
|
+
var ARTIFACT_PATH2 = "/__peach/swift/";
|
|
1891
|
+
var VIRTUAL_PREFIX = "\0peach-swift:";
|
|
1892
|
+
var devServer;
|
|
1893
|
+
function serverOrigin() {
|
|
1894
|
+
const address = devServer?.httpServer?.address();
|
|
1895
|
+
const port = address && typeof address === "object" ? address.port : devServer?.config.server.port;
|
|
1896
|
+
if (!port) throw new Error("the swift urls need the dev server port");
|
|
1897
|
+
return `http://localhost:${port}`;
|
|
1898
|
+
}
|
|
1899
|
+
function artifactUrl(project, artifact) {
|
|
1900
|
+
return `${serverOrigin()}${ARTIFACT_PATH2}${artifact.hash}.wasm`;
|
|
1901
|
+
}
|
|
1708
1902
|
function packageFor(file) {
|
|
1709
|
-
let dir =
|
|
1903
|
+
let dir = import_node_path6.default.dirname(file);
|
|
1710
1904
|
const stop = devServer?.config.root;
|
|
1711
1905
|
for (; ; ) {
|
|
1712
|
-
if (
|
|
1713
|
-
if (stop !== void 0 && dir === stop ||
|
|
1714
|
-
dir =
|
|
1906
|
+
if (import_node_fs5.default.existsSync(import_node_path6.default.join(dir, "Package.swift"))) return dir;
|
|
1907
|
+
if (stop !== void 0 && dir === stop || import_node_path6.default.dirname(dir) === dir) break;
|
|
1908
|
+
dir = import_node_path6.default.dirname(dir);
|
|
1715
1909
|
}
|
|
1716
1910
|
throw new Error(
|
|
1717
1911
|
`no Package.swift above ${file}${stop === void 0 ? "" : ` (searched up to ${stop})`}; a .swift import needs a swiftpm package like the one in packages/sootsim-swift/example`
|
|
@@ -1732,9 +1926,9 @@ function swiftPlugin(options = {}) {
|
|
|
1732
1926
|
if (!resolved) throw new Error(`cannot resolve swift source ${source}`);
|
|
1733
1927
|
let id = resolved.id;
|
|
1734
1928
|
if (importer && (source.startsWith("./") || source.startsWith("../"))) {
|
|
1735
|
-
const raw2 =
|
|
1929
|
+
const raw2 = import_node_path6.default.resolve(import_node_path6.default.dirname(importer.split("?")[0] ?? importer), source);
|
|
1736
1930
|
try {
|
|
1737
|
-
if (
|
|
1931
|
+
if (import_node_fs5.default.realpathSync(raw2) === import_node_fs5.default.realpathSync(resolved.id)) id = raw2;
|
|
1738
1932
|
} catch {
|
|
1739
1933
|
}
|
|
1740
1934
|
}
|
|
@@ -1743,16 +1937,16 @@ function swiftPlugin(options = {}) {
|
|
|
1743
1937
|
async load(id) {
|
|
1744
1938
|
if (!id.startsWith(VIRTUAL_PREFIX)) return null;
|
|
1745
1939
|
const file = id.slice(VIRTUAL_PREFIX.length);
|
|
1746
|
-
if (!
|
|
1940
|
+
if (!import_node_fs5.default.existsSync(file)) throw new Error(`swift source ${file} no longer exists`);
|
|
1747
1941
|
const packagePath = options.packagePath ?? packageFor(file);
|
|
1748
1942
|
const project = projectFor(packagePath);
|
|
1749
|
-
const entry =
|
|
1943
|
+
const entry = import_node_path6.default.relative(packagePath, file).split(import_node_path6.default.sep).join(import_node_path6.default.posix.sep);
|
|
1750
1944
|
for (const source of [
|
|
1751
1945
|
...sourceFiles(packagePath),
|
|
1752
1946
|
...nativeSourceFiles(packagePath)
|
|
1753
1947
|
])
|
|
1754
1948
|
this.addWatchFile(source);
|
|
1755
|
-
this.addWatchFile(
|
|
1949
|
+
this.addWatchFile(import_node_path6.default.join(packagePath, "Package.swift"));
|
|
1756
1950
|
for (const root of linkedModuleRoots(packagePath)) {
|
|
1757
1951
|
for (const source of sourceFiles(root)) this.addWatchFile(source);
|
|
1758
1952
|
}
|
|
@@ -1764,39 +1958,20 @@ function swiftPlugin(options = {}) {
|
|
|
1764
1958
|
this.warn(error instanceof Error ? error.message : String(error));
|
|
1765
1959
|
artifact = project.artifact;
|
|
1766
1960
|
}
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
);
|
|
1782
|
-
}
|
|
1783
|
-
let bundleFiles = {};
|
|
1784
|
-
try {
|
|
1785
|
-
const packed = buildSwiftBundleFiles(packagePath);
|
|
1786
|
-
bundleFiles = packed.files;
|
|
1787
|
-
for (const watched of packed.watched) {
|
|
1788
|
-
this.addWatchFile(import_node_path5.default.join(packagePath, ...watched.split(import_node_path5.default.posix.sep)));
|
|
1789
|
-
}
|
|
1790
|
-
if (packed.skipped.length > 0) {
|
|
1791
|
-
this.warn(
|
|
1792
|
-
`swift bundle files skipped for ${packagePath}: ${packed.skipped.join("; ")}`
|
|
1793
|
-
);
|
|
1794
|
-
}
|
|
1795
|
-
} catch (error) {
|
|
1796
|
-
this.warn(
|
|
1797
|
-
`swift bundle files for ${packagePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1798
|
-
);
|
|
1799
|
-
}
|
|
1961
|
+
const resources = Object.fromEntries(
|
|
1962
|
+
Object.entries(artifact.package.resources.table).map(([name, image]) => [
|
|
1963
|
+
name,
|
|
1964
|
+
{ ...image, uri: `${serverOrigin()}${image.uri}` }
|
|
1965
|
+
])
|
|
1966
|
+
);
|
|
1967
|
+
for (const watched of [
|
|
1968
|
+
...artifact.package.resources.watched,
|
|
1969
|
+
...artifact.package.bundleFiles.watched
|
|
1970
|
+
])
|
|
1971
|
+
this.addWatchFile(import_node_path6.default.join(packagePath, ...watched.split(import_node_path6.default.posix.sep)));
|
|
1972
|
+
const colors = artifact.package.resources.colors;
|
|
1973
|
+
const symbols = artifact.package.resources.symbols;
|
|
1974
|
+
const bundleFiles = artifact.package.bundleFiles.files;
|
|
1800
1975
|
const native = nativeSourceDescriptor(packagePath);
|
|
1801
1976
|
return swiftEntryModuleEsm({
|
|
1802
1977
|
url: artifactUrl(project, artifact),
|