peachsim 0.1.527
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 +22 -0
- package/README.md +640 -0
- package/cli/app-config.ts +82 -0
- package/cli/app-fonts.ts +388 -0
- package/cli/app-project.ts +59 -0
- package/cli/app-splash.ts +171 -0
- package/cli/app-state-reset.ts +26 -0
- package/cli/auth.ts +184 -0
- package/cli/bin.ts +59 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2806 -0
- package/cli/browser-backend.ts +44 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/cli-update.ts +261 -0
- package/cli/cloud-client.ts +1530 -0
- package/cli/cloud-dispatch.ts +206 -0
- package/cli/cloud-session.ts +227 -0
- package/cli/command-contract.ts +221 -0
- package/cli/command-registry.ts +304 -0
- package/cli/commands/agent-wrapper.ts +1048 -0
- package/cli/commands/agent.ts +439 -0
- package/cli/commands/app-fonts.ts +99 -0
- package/cli/commands/assert.ts +542 -0
- package/cli/commands/auth.ts +71 -0
- package/cli/commands/box/bundle-plane.ts +71 -0
- package/cli/commands/box/checkout-plane.ts +256 -0
- package/cli/commands/box/plane-share.ts +208 -0
- package/cli/commands/box/rnx-command.ts +60 -0
- package/cli/commands/box/search-command.ts +157 -0
- package/cli/commands/box.ts +925 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +176 -0
- package/cli/commands/config.ts +34 -0
- package/cli/commands/control.ts +2154 -0
- package/cli/commands/cpu-profile.ts +941 -0
- package/cli/commands/daemon-mac-app.ts +165 -0
- package/cli/commands/daemon.ts +800 -0
- package/cli/commands/debug.ts +751 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +201 -0
- package/cli/commands/detox.ts +481 -0
- package/cli/commands/device.ts +134 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/do-chain.ts +408 -0
- package/cli/commands/electron.ts +94 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1240 -0
- package/cli/commands/inspect/actions.ts +516 -0
- package/cli/commands/inspect/core.ts +2086 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +119 -0
- package/cli/commands/inspect/env.ts +25 -0
- package/cli/commands/inspect/find.ts +169 -0
- package/cli/commands/inspect/get-layout.ts +53 -0
- package/cli/commands/inspect/keyboard.ts +54 -0
- package/cli/commands/inspect/list.ts +175 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +77 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +32 -0
- package/cli/commands/inspect/settling.ts +197 -0
- package/cli/commands/inspect/shared.ts +259 -0
- package/cli/commands/inspect/sleep.ts +15 -0
- package/cli/commands/inspect/tree.ts +23 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +211 -0
- package/cli/commands/inspect/wait-idle.ts +25 -0
- package/cli/commands/inspect/wait-ready.ts +87 -0
- package/cli/commands/inspect/wait-selector.ts +59 -0
- package/cli/commands/inspect/wait.ts +32 -0
- package/cli/commands/inspect.ts +4738 -0
- package/cli/commands/install-cli.ts +275 -0
- package/cli/commands/install-desktop.ts +385 -0
- package/cli/commands/login.ts +357 -0
- package/cli/commands/logout.ts +24 -0
- package/cli/commands/maestro-generate.ts +375 -0
- package/cli/commands/maestro.ts +536 -0
- package/cli/commands/mode.ts +58 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +67 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/platform.ts +410 -0
- package/cli/commands/preview.ts +103 -0
- package/cli/commands/profile.ts +106 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1435 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +89 -0
- package/cli/commands/runtime.ts +348 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +144 -0
- package/cli/commands/screenshot-mode.ts +38 -0
- package/cli/commands/screenshot.ts +492 -0
- package/cli/commands/screenshots-capture.ts +608 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +139 -0
- package/cli/commands/setup.ts +416 -0
- package/cli/commands/shell-boolean-mode.ts +82 -0
- package/cli/commands/skills.ts +468 -0
- package/cli/commands/slides.ts +357 -0
- package/cli/commands/state.ts +94 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +55 -0
- package/cli/commands/test.ts +535 -0
- package/cli/commands/three-mode.ts +771 -0
- package/cli/commands/timeline.ts +121 -0
- package/cli/commands/upgrade.ts +167 -0
- package/cli/commands/upload.ts +1203 -0
- package/cli/commands/version.ts +63 -0
- package/cli/commands/welcome.ts +17 -0
- package/cli/commands/what-happened.ts +328 -0
- package/cli/current-sim.ts +217 -0
- package/cli/desktop-companion.ts +315 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +184 -0
- package/cli/drivers/playwright-sim-host.ts +537 -0
- package/cli/drivers/playwright.ts +209 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-export.ts +55 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +126 -0
- package/cli/flow-session.ts +140 -0
- package/cli/help-core.ts +143 -0
- package/cli/help.ts +44 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +214 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/internal-child.ts +176 -0
- package/cli/maestro-js.ts +323 -0
- package/cli/main.ts +704 -0
- package/cli/open-url.ts +8 -0
- package/cli/outbound-endpoints.ts +830 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +189 -0
- package/cli/privacy.ts +53 -0
- package/cli/prompt.ts +56 -0
- package/cli/recording-access.ts +108 -0
- package/cli/registry.ts +2 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/rnx-in-process.ts +98 -0
- package/cli/run-registry.ts +226 -0
- package/cli/run-rnx-core.ts +148 -0
- package/cli/run-rnx.ts +137 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/secure-file.ts +31 -0
- package/cli/self-invocation.ts +58 -0
- package/cli/send-to-box.ts +109 -0
- package/cli/setup-repository.ts +191 -0
- package/cli/shell-init.ts +98 -0
- package/cli/standalone.ts +4 -0
- package/cli/telemetry.ts +84 -0
- package/cli/ui.ts +68 -0
- package/cli/ws-bridge.ts +1020 -0
- package/detox/attempt-events.cjs +23 -0
- package/detox/colors.ts +54 -0
- package/detox/config-loader.ts +135 -0
- package/detox/element-types.ts +48 -0
- package/detox/expectations.ts +534 -0
- package/detox/gestures.ts +501 -0
- package/detox/index.ts +2694 -0
- package/detox/jest-preset.cjs +29 -0
- package/detox/jest-setup-after-env.cjs +22 -0
- package/detox/matchers.ts +30 -0
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/detox/navigation-lifecycle.ts +290 -0
- package/detox/navigation.ts +43 -0
- package/detox/proof-frame.cjs +114 -0
- package/detox/record-block-execution.cjs +78 -0
- package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
- package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
- package/detox/screenshots/color-test-rest-norngh.png +0 -0
- package/detox/screenshots/theme-blue-toggle.png +0 -0
- package/detox/screenshots/theme-blue.png +0 -0
- package/detox/screenshots/theme-red-toggle.png +0 -0
- package/detox/screenshots/theme-red.png +0 -0
- package/dist-lib/agent-daemon-client.cjs +502 -0
- package/dist-lib/agent-events.cjs +48 -0
- package/dist-lib/agent-identity.cjs +53 -0
- package/dist-lib/agent-sessions.cjs +759 -0
- package/dist-lib/attached-projects.cjs +526 -0
- package/dist-lib/auth/shared-session.cjs +208 -0
- package/dist-lib/backend-origin.cjs +88 -0
- package/dist-lib/beta.cjs +41 -0
- package/dist-lib/beta.mjs +13 -0
- package/dist-lib/bridge-constants.cjs +161 -0
- package/dist-lib/bridge-contract-input.cjs +451 -0
- package/dist-lib/bridge-contract-input.mjs +414 -0
- package/dist-lib/bridge-contract.cjs +130 -0
- package/dist-lib/bridge-contract.mjs +94 -0
- package/dist-lib/capture-contract.cjs +220 -0
- package/dist-lib/capture-contract.mjs +190 -0
- package/dist-lib/cli-constants.cjs +32 -0
- package/dist-lib/cloud-contract.cjs +194 -0
- package/dist-lib/cloud-contract.mjs +145 -0
- package/dist-lib/cloud.cjs +670 -0
- package/dist-lib/cloud.mjs +639 -0
- package/dist-lib/config.cjs +96 -0
- package/dist-lib/detox/index.cjs +3789 -0
- package/dist-lib/detox/jest-preset.cjs +29 -0
- package/dist-lib/dev-bundle-resolution.cjs +290 -0
- package/dist-lib/home-paths.cjs +638 -0
- package/dist-lib/host/bridge-host.cjs +10903 -0
- package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
- package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
- package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
- package/dist-lib/host/replacement-module-handler.cjs +469 -0
- package/dist-lib/host/websocket-proxy.cjs +298 -0
- package/dist-lib/index.cjs +4268 -0
- package/dist-lib/jump-to-source-babel.cjs +93 -0
- package/dist-lib/jump-to-source-native.cjs +112 -0
- package/dist-lib/menu.cjs +646 -0
- package/dist-lib/menu.mjs +604 -0
- package/dist-lib/metro-fingerprint-registry.cjs +186 -0
- package/dist-lib/metro-fingerprint-registry.mjs +156 -0
- package/dist-lib/metro-production-bundle.cjs +329 -0
- package/dist-lib/metro-production-bundle.mjs +295 -0
- package/dist-lib/metro.cjs +904 -0
- package/dist-lib/profiles.cjs +246 -0
- package/dist-lib/public-brand.cjs +39 -0
- package/dist-lib/react-native-host-modules.cjs +51 -0
- package/dist-lib/react-native-host-modules.mjs +25 -0
- package/dist-lib/render-mode.cjs +54 -0
- package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
- package/dist-lib/sdk.cjs +2433 -0
- package/dist-lib/sdk.mjs +2336 -0
- package/dist-lib/skills.cjs +39132 -0
- package/dist-lib/swift-submit.cjs +92 -0
- package/dist-lib/swift-submit.mjs +65 -0
- package/dist-lib/swift.cjs +1646 -0
- package/dist-lib/vite.cjs +1591 -0
- package/package.json +290 -0
- package/scripts/dev-server-scanner.ts +1291 -0
- package/scripts/optional-demo-registry.ts +113 -0
- package/skills/contrast/SKILL.md +165 -0
- package/skills/rnx-debug/SKILL.md +433 -0
- package/skills/rnx-perf/SKILL.md +399 -0
- package/skills/rnx-setup/SKILL.md +172 -0
- package/skills/rnx-test/SKILL.md +321 -0
- package/skills/rnx-visual/SKILL.md +126 -0
- package/src/agent-daemon-client.ts +410 -0
- package/src/agent-events.ts +71 -0
- package/src/agent-identity.ts +23 -0
- package/src/agent-prompt.ts +71 -0
- package/src/agent-sessions.ts +580 -0
- package/src/app-url.ts +39 -0
- package/src/attached-projects.ts +539 -0
- package/src/auth/shared-session.ts +235 -0
- package/src/backend-origin.ts +70 -0
- package/src/beta.ts +19 -0
- package/src/bridge-constants.ts +175 -0
- package/src/bridge-contract-input.ts +502 -0
- package/src/bridge-contract.ts +558 -0
- package/src/browser-cache.ts +16 -0
- package/src/capture-contract.ts +587 -0
- package/src/cli-constants.ts +1 -0
- package/src/cli-version.ts +40 -0
- package/src/cloud-contract.ts +274 -0
- package/src/cloud.ts +762 -0
- package/src/codex-client.ts +234 -0
- package/src/config.ts +132 -0
- package/src/connect.ts +101 -0
- package/src/dev-bundle-resolution.ts +346 -0
- package/src/dev-server-open.ts +198 -0
- package/src/disk-cleanup.ts +540 -0
- package/src/flow-timeout-scale.ts +15 -0
- package/src/home-paths.ts +806 -0
- package/src/host/agent-host.ts +666 -0
- package/src/host/bridge-host.ts +2788 -0
- package/src/host/fetch-proxy-handler.ts +449 -0
- package/src/host/fetch-proxy-overrides.ts +51 -0
- package/src/host/open-url.ts +89 -0
- package/src/host/plane-host.ts +203 -0
- package/src/host/replacement-module-handler.ts +158 -0
- package/src/host/websocket-proxy.ts +315 -0
- package/src/index.ts +71 -0
- package/src/jump-to-source-babel.ts +135 -0
- package/src/jump-to-source-native.ts +102 -0
- package/src/menu.ts +777 -0
- package/src/metro-fingerprint-registry.ts +302 -0
- package/src/metro-plugin.ts +341 -0
- package/src/metro-production-bundle.ts +471 -0
- package/src/native-dev-bundle-url.ts +118 -0
- package/src/native-seam-manifest.ts +341 -0
- package/src/playwright-host-log.ts +16 -0
- package/src/plist.ts +27 -0
- package/src/poll-until.ts +123 -0
- package/src/profiles.ts +179 -0
- package/src/public-brand.ts +9 -0
- package/src/react-native-host-modules.ts +26 -0
- package/src/render-mode.ts +27 -0
- package/src/rolldown-plugin-swift.ts +240 -0
- package/src/runtime-assets.ts +233 -0
- package/src/runtime-delivery.ts +54 -0
- package/src/screenshots/compose.ts +422 -0
- package/src/screenshots/frame-compose.ts +514 -0
- package/src/screenshots/orchestrate.ts +256 -0
- package/src/screenshots/org-deck.ts +91 -0
- package/src/screenshots/registry.ts +58 -0
- package/src/screenshots/schema.ts +364 -0
- package/src/sdk.ts +15 -0
- package/src/settings-bundle.ts +418 -0
- package/src/shell-bridge-identity.ts +15 -0
- package/src/sim-client.ts +697 -0
- package/src/skills/builtin/a11y-review.ts +132 -0
- package/src/skills/builtin/compat-check.ts +71 -0
- package/src/skills/builtin/maestro-test.ts +121 -0
- package/src/skills/builtin/perf-profile.ts +90 -0
- package/src/skills/builtin/screenshot-all.ts +52 -0
- package/src/skills/builtin/visual-diff.ts +100 -0
- package/src/skills/registry.ts +107 -0
- package/src/skills/types.ts +41 -0
- package/src/swift-submit.ts +185 -0
- package/src/swift.ts +7 -0
- package/src/team-machine-prompt.ts +73 -0
- package/src/vite-plugin-one.ts +264 -0
- package/src/vite-plugin-swift.ts +620 -0
- package/src/vite-plugin.ts +1946 -0
- package/src/worklets-babel.ts +250 -0
|
@@ -0,0 +1,1646 @@
|
|
|
1
|
+
/*! rnx v0.1.527 | (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/swift.ts
|
|
33
|
+
var swift_exports = {};
|
|
34
|
+
__export(swift_exports, {
|
|
35
|
+
createSwiftEntry: () => createSwiftEntry
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(swift_exports);
|
|
38
|
+
|
|
39
|
+
// ../sootsim-swift/src/mount.tsx
|
|
40
|
+
var import_native = require("@react-navigation/native");
|
|
41
|
+
var import_native_stack = require("@react-navigation/native-stack");
|
|
42
|
+
var import_runtime = require("contrast-kit/runtime");
|
|
43
|
+
var import_ui = require("contrast-kit/ui");
|
|
44
|
+
var import_react = require("react");
|
|
45
|
+
var import_react_native = require("react-native");
|
|
46
|
+
var import_react_native_bottom_tabs = __toESM(require("react-native-bottom-tabs"), 1);
|
|
47
|
+
|
|
48
|
+
// ../sootsim-swift/src/bundleAssets.ts
|
|
49
|
+
function resolveImageSource(source, table, onMiss) {
|
|
50
|
+
if (typeof source !== "string") return source;
|
|
51
|
+
const url = table[source];
|
|
52
|
+
if (typeof url === "string") return { uri: url };
|
|
53
|
+
onMiss(source);
|
|
54
|
+
return source;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ../sootsim-swift/src/resfs.ts
|
|
58
|
+
var RES_BADF = 8;
|
|
59
|
+
var RES_INVAL = 28;
|
|
60
|
+
var RES_NOENT = 44;
|
|
61
|
+
var RES_NOTDIR = 54;
|
|
62
|
+
var RES_NOTCAPABLE = 76;
|
|
63
|
+
var RES_DIRTYPE = 3;
|
|
64
|
+
var RES_FILETYPE = 4;
|
|
65
|
+
var O_CREAT = 1;
|
|
66
|
+
var O_DIRECTORY = 2;
|
|
67
|
+
var O_EXCL = 4;
|
|
68
|
+
var O_TRUNC = 8;
|
|
69
|
+
var RES_PREOPEN = 3;
|
|
70
|
+
var RES_DIR_NAME = "/res";
|
|
71
|
+
var B64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
72
|
+
function decodeBase64(text) {
|
|
73
|
+
const clean = text.replace(/\s/g, "");
|
|
74
|
+
if (clean.length % 4 !== 0) {
|
|
75
|
+
throw new Error(`swift bundle file is not base64 (length ${clean.length})`);
|
|
76
|
+
}
|
|
77
|
+
const values = new Uint8Array(clean.length);
|
|
78
|
+
let length = clean.length;
|
|
79
|
+
let pad = 0;
|
|
80
|
+
if (clean.endsWith("==")) pad = 2;
|
|
81
|
+
else if (clean.endsWith("=")) pad = 1;
|
|
82
|
+
length -= pad;
|
|
83
|
+
for (let index = 0; index < clean.length - pad; index += 1) {
|
|
84
|
+
const digit = B64_DIGITS.indexOf(clean[index]);
|
|
85
|
+
if (digit < 0) {
|
|
86
|
+
throw new Error(`swift bundle file is not base64 (char '${clean[index]}')`);
|
|
87
|
+
}
|
|
88
|
+
values[index] = digit;
|
|
89
|
+
}
|
|
90
|
+
const out = new Uint8Array((clean.length / 4 | 0) * 3 - pad);
|
|
91
|
+
let at = 0;
|
|
92
|
+
for (let index = 0; index < clean.length; index += 4) {
|
|
93
|
+
const group = values[index] << 18 | values[index + 1] << 12 | values[index + 2] << 6 | values[index + 3];
|
|
94
|
+
out[at] = group >> 16 & 255;
|
|
95
|
+
if (at + 1 < out.length) out[at + 1] = group >> 8 & 255;
|
|
96
|
+
if (at + 2 < out.length) out[at + 2] = group & 255;
|
|
97
|
+
at += 3;
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
function resIno(name) {
|
|
102
|
+
let hash = 0xcbf29ce484222325n;
|
|
103
|
+
const bytes = new TextEncoder().encode(name);
|
|
104
|
+
for (const byte of bytes) {
|
|
105
|
+
hash ^= BigInt(byte);
|
|
106
|
+
hash = hash * 0x100000001b3n & 0xffffffffffffffffn;
|
|
107
|
+
}
|
|
108
|
+
return hash === 0n ? 1n : hash;
|
|
109
|
+
}
|
|
110
|
+
function resArgv0(moduleUrl) {
|
|
111
|
+
const base = moduleUrl.split("/").pop()?.split("?")[0] ?? "app.wasm";
|
|
112
|
+
return `${RES_DIR_NAME}/${base === "" ? "app.wasm" : base}`;
|
|
113
|
+
}
|
|
114
|
+
function resolveName(files, rel) {
|
|
115
|
+
let rest = rel;
|
|
116
|
+
if (rest === RES_DIR_NAME || rest === `${RES_DIR_NAME}/`) return null;
|
|
117
|
+
if (rest.startsWith(`${RES_DIR_NAME}/`)) rest = rest.slice(RES_DIR_NAME.length + 1);
|
|
118
|
+
if (rest.startsWith("/")) rest = rest.slice(1);
|
|
119
|
+
while (rest.startsWith("./")) rest = rest.slice(2);
|
|
120
|
+
if (rest === "" || rest === ".") return null;
|
|
121
|
+
if (rest.includes("/")) return null;
|
|
122
|
+
return Object.prototype.hasOwnProperty.call(files, rest) ? rest : null;
|
|
123
|
+
}
|
|
124
|
+
function writeStat(mem, ptr, filetype, size, ino) {
|
|
125
|
+
mem.bytes().fill(0, ptr, ptr + 64);
|
|
126
|
+
mem.bytes()[ptr + 16] = filetype;
|
|
127
|
+
mem.writeU64(ptr + 8, ino);
|
|
128
|
+
mem.writeU64(ptr + 32, BigInt(size));
|
|
129
|
+
}
|
|
130
|
+
function createResFs(files) {
|
|
131
|
+
const names = Object.keys(files).sort();
|
|
132
|
+
const fds = /* @__PURE__ */ new Map();
|
|
133
|
+
let nextFd = RES_PREOPEN + 1;
|
|
134
|
+
const freeFds = [];
|
|
135
|
+
let preopenOpen = true;
|
|
136
|
+
const allocFd = () => {
|
|
137
|
+
if (freeFds.length > 0) return freeFds.shift();
|
|
138
|
+
nextFd += 1;
|
|
139
|
+
return nextFd - 1;
|
|
140
|
+
};
|
|
141
|
+
const dirFdOk = (fd) => {
|
|
142
|
+
if (fd === RES_PREOPEN) return preopenOpen;
|
|
143
|
+
const found = fds.get(fd);
|
|
144
|
+
return found !== void 0 && found.kind === "dir";
|
|
145
|
+
};
|
|
146
|
+
const inoOf = (name) => resIno(name);
|
|
147
|
+
return {
|
|
148
|
+
imports(mem) {
|
|
149
|
+
return {
|
|
150
|
+
path_open: (dirfd, _dirflags, pathPtr, pathLen, oflags, _r1, _r2, _r3, fdPtr) => {
|
|
151
|
+
if (!dirFdOk(dirfd)) return RES_BADF;
|
|
152
|
+
if ((oflags & (O_CREAT | O_EXCL | O_TRUNC)) !== 0) return RES_INVAL;
|
|
153
|
+
const rel = mem.readString(pathPtr, pathLen);
|
|
154
|
+
if (rel === "." || rel === "./" || rel === RES_DIR_NAME || rel === `${RES_DIR_NAME}/`) {
|
|
155
|
+
const fd2 = allocFd();
|
|
156
|
+
fds.set(fd2, { kind: "dir" });
|
|
157
|
+
mem.writeU32(fdPtr, fd2);
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
|
160
|
+
const hit = resolveName(files, rel);
|
|
161
|
+
if (hit === null) return RES_NOENT;
|
|
162
|
+
if ((oflags & O_DIRECTORY) !== 0) return RES_NOTDIR;
|
|
163
|
+
const fd = allocFd();
|
|
164
|
+
fds.set(fd, { kind: "file", name: hit, bytes: files[hit], offset: 0 });
|
|
165
|
+
mem.writeU32(fdPtr, fd);
|
|
166
|
+
return 0;
|
|
167
|
+
},
|
|
168
|
+
path_filestat_get: (dirfd, _flags, pathPtr, pathLen, statPtr) => {
|
|
169
|
+
if (!dirFdOk(dirfd)) return RES_BADF;
|
|
170
|
+
const rel = mem.readString(pathPtr, pathLen);
|
|
171
|
+
if (rel === "." || rel === "./" || rel === RES_DIR_NAME || rel === `${RES_DIR_NAME}/`) {
|
|
172
|
+
writeStat(mem, statPtr, RES_DIRTYPE, 0, inoOf(RES_DIR_NAME));
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
const hit = resolveName(files, rel);
|
|
176
|
+
if (hit === null) return RES_NOENT;
|
|
177
|
+
writeStat(mem, statPtr, RES_FILETYPE, files[hit].length, inoOf(hit));
|
|
178
|
+
return 0;
|
|
179
|
+
},
|
|
180
|
+
fd_fdstat_get: (fd, statPtr) => {
|
|
181
|
+
if (fd === RES_PREOPEN) {
|
|
182
|
+
if (!preopenOpen) return RES_BADF;
|
|
183
|
+
mem.bytes().fill(0, statPtr, statPtr + 24);
|
|
184
|
+
mem.bytes()[statPtr] = RES_DIRTYPE;
|
|
185
|
+
return 0;
|
|
186
|
+
}
|
|
187
|
+
const found = fds.get(fd);
|
|
188
|
+
if (!found) return RES_BADF;
|
|
189
|
+
mem.bytes().fill(0, statPtr, statPtr + 24);
|
|
190
|
+
mem.bytes()[statPtr] = found.kind === "dir" ? RES_DIRTYPE : RES_FILETYPE;
|
|
191
|
+
return 0;
|
|
192
|
+
},
|
|
193
|
+
fd_filestat_get: (fd, statPtr) => {
|
|
194
|
+
const found = fds.get(fd);
|
|
195
|
+
if (!found) return RES_BADF;
|
|
196
|
+
if (found.kind === "dir") {
|
|
197
|
+
writeStat(mem, statPtr, RES_DIRTYPE, 0, inoOf(RES_DIR_NAME));
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
writeStat(mem, statPtr, RES_FILETYPE, found.bytes.length, inoOf(found.name));
|
|
201
|
+
return 0;
|
|
202
|
+
},
|
|
203
|
+
fd_prestat_get: (fd, prestatPtr) => {
|
|
204
|
+
if (fd === RES_PREOPEN && preopenOpen) {
|
|
205
|
+
mem.bytes().fill(0, prestatPtr, prestatPtr + 8);
|
|
206
|
+
mem.bytes()[prestatPtr] = 0;
|
|
207
|
+
mem.writeU32(prestatPtr + 4, RES_DIR_NAME.length);
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
return RES_BADF;
|
|
211
|
+
},
|
|
212
|
+
fd_prestat_dir_name: (fd, pathPtr, pathLen) => {
|
|
213
|
+
if (fd !== RES_PREOPEN || !preopenOpen) return RES_BADF;
|
|
214
|
+
if (pathLen < RES_DIR_NAME.length) return RES_INVAL;
|
|
215
|
+
mem.bytes().set(new TextEncoder().encode(RES_DIR_NAME), pathPtr);
|
|
216
|
+
return 0;
|
|
217
|
+
},
|
|
218
|
+
fd_readdir: (fd, bufPtr, bufLen, cookie, usedPtr) => {
|
|
219
|
+
const isPreopen = fd === RES_PREOPEN && preopenOpen;
|
|
220
|
+
const found = fds.get(fd);
|
|
221
|
+
if (!isPreopen && !found) return RES_BADF;
|
|
222
|
+
if (!isPreopen && found?.kind !== "dir") return RES_NOTCAPABLE;
|
|
223
|
+
let used = 0;
|
|
224
|
+
names.forEach((name, index) => {
|
|
225
|
+
const next = index + 1;
|
|
226
|
+
if (next <= cookie) return;
|
|
227
|
+
const encoded = new TextEncoder().encode(name);
|
|
228
|
+
if (used + 24 + encoded.length > bufLen) return;
|
|
229
|
+
const at = bufPtr + used;
|
|
230
|
+
mem.writeU64(at, BigInt(next));
|
|
231
|
+
mem.writeU64(at + 8, inoOf(name));
|
|
232
|
+
mem.writeU32(at + 16, encoded.length);
|
|
233
|
+
mem.bytes()[at + 20] = RES_FILETYPE;
|
|
234
|
+
mem.bytes().fill(0, at + 21, at + 24);
|
|
235
|
+
mem.bytes().set(encoded, at + 24);
|
|
236
|
+
used += 24 + encoded.length;
|
|
237
|
+
});
|
|
238
|
+
mem.writeU32(usedPtr, used);
|
|
239
|
+
return 0;
|
|
240
|
+
},
|
|
241
|
+
fd_read: (fd, iovsPtr, iovsLen, donePtr) => {
|
|
242
|
+
const found = fds.get(fd);
|
|
243
|
+
if (!found) return RES_BADF;
|
|
244
|
+
if (found.kind !== "file") return RES_NOTCAPABLE;
|
|
245
|
+
let done = 0;
|
|
246
|
+
for (let index = 0; index < iovsLen; index += 1) {
|
|
247
|
+
const ptr = mem.readU32(iovsPtr + index * 8);
|
|
248
|
+
const want = mem.readU32(iovsPtr + index * 8 + 4);
|
|
249
|
+
const chunk = found.bytes.subarray(found.offset, found.offset + want);
|
|
250
|
+
mem.bytes().set(chunk, ptr);
|
|
251
|
+
found.offset += chunk.length;
|
|
252
|
+
done += chunk.length;
|
|
253
|
+
if (chunk.length < want) break;
|
|
254
|
+
}
|
|
255
|
+
mem.writeU32(donePtr, done);
|
|
256
|
+
return 0;
|
|
257
|
+
},
|
|
258
|
+
// the tree is read-only: any write to it is not-capable, and an
|
|
259
|
+
// unknown fd is a bad descriptor. stdio never reaches here; the
|
|
260
|
+
// mount answers fds 0-2 itself before delegating.
|
|
261
|
+
fd_write: (fd, _iovsPtr, _iovsLen, _donePtr) => {
|
|
262
|
+
if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
|
|
263
|
+
return RES_BADF;
|
|
264
|
+
},
|
|
265
|
+
fd_pread: (fd, _iovsPtr, _iovsLen, _offset, _donePtr) => {
|
|
266
|
+
if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
|
|
267
|
+
return RES_BADF;
|
|
268
|
+
},
|
|
269
|
+
fd_seek: (fd, _offLo, _offHi, _whence, _posPtr) => {
|
|
270
|
+
if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
|
|
271
|
+
return RES_BADF;
|
|
272
|
+
},
|
|
273
|
+
fd_tell: (fd, _posPtr) => {
|
|
274
|
+
if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
|
|
275
|
+
return RES_BADF;
|
|
276
|
+
},
|
|
277
|
+
fd_close: (fd) => {
|
|
278
|
+
if (fd === RES_PREOPEN) {
|
|
279
|
+
if (!preopenOpen) return RES_BADF;
|
|
280
|
+
preopenOpen = false;
|
|
281
|
+
return 0;
|
|
282
|
+
}
|
|
283
|
+
if (!fds.has(fd)) return RES_BADF;
|
|
284
|
+
fds.delete(fd);
|
|
285
|
+
const at = freeFds.findIndex((other) => other > fd);
|
|
286
|
+
if (at < 0) freeFds.push(fd);
|
|
287
|
+
else freeFds.splice(at, 0, fd);
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ../sootsim-swift/src/mount.tsx
|
|
296
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
297
|
+
function isRecord(value) {
|
|
298
|
+
return typeof value === "object" && value !== null;
|
|
299
|
+
}
|
|
300
|
+
function readModifier(value) {
|
|
301
|
+
if (!isRecord(value) || typeof value.$type !== "string") {
|
|
302
|
+
throw new Error("swift modifier is not a { $type } object");
|
|
303
|
+
}
|
|
304
|
+
return { ...value, $type: value.$type };
|
|
305
|
+
}
|
|
306
|
+
function readNode(value) {
|
|
307
|
+
if (!isRecord(value)) throw new Error("swift node is not an object");
|
|
308
|
+
const { t, id, p, m, c, h } = value;
|
|
309
|
+
if (typeof t !== "string" || typeof id !== "string") {
|
|
310
|
+
throw new Error("swift node has no type or identity");
|
|
311
|
+
}
|
|
312
|
+
const node = { t, id };
|
|
313
|
+
if (p !== void 0) {
|
|
314
|
+
if (!isRecord(p)) throw new Error(`swift node ${id} has a non-object props`);
|
|
315
|
+
node.p = p;
|
|
316
|
+
}
|
|
317
|
+
if (m !== void 0) {
|
|
318
|
+
if (!Array.isArray(m)) throw new Error(`swift node ${id} has a non-array modifiers`);
|
|
319
|
+
node.m = m.map(readModifier);
|
|
320
|
+
}
|
|
321
|
+
if (c !== void 0) {
|
|
322
|
+
if (!Array.isArray(c)) throw new Error(`swift node ${id} has non-array children`);
|
|
323
|
+
node.c = c.map(readNode);
|
|
324
|
+
}
|
|
325
|
+
if (h !== void 0) {
|
|
326
|
+
if (!isRecord(h)) throw new Error(`swift node ${id} has non-object handlers`);
|
|
327
|
+
const handlers = {};
|
|
328
|
+
for (const [name, handlerId2] of Object.entries(h)) {
|
|
329
|
+
if (typeof handlerId2 !== "number") {
|
|
330
|
+
throw new Error(`swift node ${id} handler ${name} is not a number`);
|
|
331
|
+
}
|
|
332
|
+
handlers[name] = handlerId2;
|
|
333
|
+
}
|
|
334
|
+
node.h = handlers;
|
|
335
|
+
}
|
|
336
|
+
return node;
|
|
337
|
+
}
|
|
338
|
+
function readTree(text) {
|
|
339
|
+
const value = JSON.parse(text);
|
|
340
|
+
if (!Array.isArray(value)) throw new Error("swift tree is not an array");
|
|
341
|
+
return value.map(readNode);
|
|
342
|
+
}
|
|
343
|
+
var WASI_BADF = 8;
|
|
344
|
+
var WASI_INVAL = 28;
|
|
345
|
+
function wasiImports(host, argv, resFiles) {
|
|
346
|
+
const argvBytes = argv.map((arg) => new TextEncoder().encode(`${arg}\0`));
|
|
347
|
+
const resImports = createResFs(resFiles).imports(host);
|
|
348
|
+
return {
|
|
349
|
+
args_get: (argvPtr, bufPtr) => {
|
|
350
|
+
let argp = argvPtr;
|
|
351
|
+
let bufp = bufPtr;
|
|
352
|
+
for (const bytes of argvBytes) {
|
|
353
|
+
host.writeU32(argp, bufp);
|
|
354
|
+
host.bytes().set(bytes, bufp);
|
|
355
|
+
argp += 4;
|
|
356
|
+
bufp += bytes.length;
|
|
357
|
+
}
|
|
358
|
+
host.writeU32(argp, 0);
|
|
359
|
+
return 0;
|
|
360
|
+
},
|
|
361
|
+
args_sizes_get: (argcPtr, argvSizePtr) => {
|
|
362
|
+
host.writeU32(argcPtr, argvBytes.length);
|
|
363
|
+
host.writeU32(
|
|
364
|
+
argvSizePtr,
|
|
365
|
+
argvBytes.reduce((total, bytes) => total + bytes.length, 0)
|
|
366
|
+
);
|
|
367
|
+
return 0;
|
|
368
|
+
},
|
|
369
|
+
environ_get: () => 0,
|
|
370
|
+
environ_sizes_get: (countPtr, sizePtr) => {
|
|
371
|
+
host.writeU32(countPtr, 0);
|
|
372
|
+
host.writeU32(sizePtr, 0);
|
|
373
|
+
return 0;
|
|
374
|
+
},
|
|
375
|
+
fd_close: (...args) => resImports.fd_close(...args),
|
|
376
|
+
fd_fdstat_get: (...args) => resImports.fd_fdstat_get(...args),
|
|
377
|
+
fd_fdstat_set_flags: () => WASI_BADF,
|
|
378
|
+
fd_filestat_get: (...args) => resImports.fd_filestat_get(...args),
|
|
379
|
+
fd_filestat_set_size: () => WASI_BADF,
|
|
380
|
+
fd_filestat_set_times: () => WASI_BADF,
|
|
381
|
+
fd_pread: (...args) => resImports.fd_pread(...args),
|
|
382
|
+
fd_prestat_get: (...args) => resImports.fd_prestat_get(...args),
|
|
383
|
+
fd_prestat_dir_name: (...args) => resImports.fd_prestat_dir_name(...args),
|
|
384
|
+
fd_read: (...args) => resImports.fd_read(...args),
|
|
385
|
+
fd_readdir: (...args) => resImports.fd_readdir(...args),
|
|
386
|
+
fd_seek: (...args) => resImports.fd_seek(...args),
|
|
387
|
+
fd_sync: () => WASI_BADF,
|
|
388
|
+
fd_tell: (...args) => resImports.fd_tell(...args),
|
|
389
|
+
fd_write: (fd, iovsPtr, iovsLen, writtenPtr) => {
|
|
390
|
+
if (fd !== 1 && fd !== 2)
|
|
391
|
+
return resImports.fd_write(fd, iovsPtr, iovsLen, writtenPtr);
|
|
392
|
+
const view = new DataView(host.bytes().buffer);
|
|
393
|
+
let written = 0;
|
|
394
|
+
for (let index = 0; index < iovsLen; index += 1) {
|
|
395
|
+
written += view.getUint32(iovsPtr + index * 8 + 4, true);
|
|
396
|
+
}
|
|
397
|
+
host.writeU32(writtenPtr, written);
|
|
398
|
+
return 0;
|
|
399
|
+
},
|
|
400
|
+
path_create_directory: () => WASI_BADF,
|
|
401
|
+
path_filestat_get: (...args) => resImports.path_filestat_get(...args),
|
|
402
|
+
path_filestat_set_times: () => WASI_BADF,
|
|
403
|
+
path_link: () => WASI_BADF,
|
|
404
|
+
path_open: (...args) => resImports.path_open(...args),
|
|
405
|
+
path_readlink: () => WASI_BADF,
|
|
406
|
+
path_remove_directory: () => WASI_BADF,
|
|
407
|
+
path_rename: () => WASI_BADF,
|
|
408
|
+
path_symlink: () => WASI_BADF,
|
|
409
|
+
path_unlink_file: () => WASI_BADF,
|
|
410
|
+
// the 6.3 sdk's libraries call the clocks even when the app never reads
|
|
411
|
+
// the time, so instantiation fails without them. clock 0 is realtime
|
|
412
|
+
// and clock 1 is monotonic, the only two swift asks for here; anything
|
|
413
|
+
// else is a loud inval. the resolutions are wasi-libc's for those two:
|
|
414
|
+
// a millisecond for the wall clock and a nanosecond for the monotonic one.
|
|
415
|
+
clock_res_get: (clockId, resolutionPtr) => {
|
|
416
|
+
const resolution = clockId === 1 ? 1n : clockId === 0 ? 1000000n : null;
|
|
417
|
+
if (resolution === null) return WASI_INVAL;
|
|
418
|
+
host.writeU64(resolutionPtr, resolution);
|
|
419
|
+
return 0;
|
|
420
|
+
},
|
|
421
|
+
clock_time_get: (clockId, _precision, timePtr) => {
|
|
422
|
+
const nanos = clockId === 1 ? BigInt(Math.round(performance.now() * 1e6)) : clockId === 0 ? BigInt(Date.now()) * 1000000n : null;
|
|
423
|
+
if (nanos === null) return WASI_INVAL;
|
|
424
|
+
host.writeU64(timePtr, nanos);
|
|
425
|
+
return 0;
|
|
426
|
+
},
|
|
427
|
+
// a poll is the one call the tenant cannot answer: there is no descriptor
|
|
428
|
+
// to wait on and no clock to sleep against, so it says so instead of
|
|
429
|
+
// returning an event nobody subscribed to.
|
|
430
|
+
poll_oneoff: () => {
|
|
431
|
+
throw new Error("swift app polled for events, which the tenant has no source for");
|
|
432
|
+
},
|
|
433
|
+
proc_exit: (code) => {
|
|
434
|
+
throw new Error(`swift app exited with code ${code}`);
|
|
435
|
+
},
|
|
436
|
+
random_get: (bufferPtr, length) => {
|
|
437
|
+
crypto.getRandomValues(host.bytes().subarray(bufferPtr, bufferPtr + length));
|
|
438
|
+
return 0;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function rawExport(exports2, name) {
|
|
443
|
+
const value = exports2[name];
|
|
444
|
+
if (typeof value !== "function") {
|
|
445
|
+
throw new Error(`swift artifact has no exported function ${name}`);
|
|
446
|
+
}
|
|
447
|
+
return value;
|
|
448
|
+
}
|
|
449
|
+
function pointerExport(exports2, name) {
|
|
450
|
+
const fn = rawExport(exports2, name);
|
|
451
|
+
return (...args) => {
|
|
452
|
+
const result = Reflect.apply(fn, void 0, args);
|
|
453
|
+
if (typeof result !== "number") {
|
|
454
|
+
throw new Error(`swift export ${name} returned ${typeof result}`);
|
|
455
|
+
}
|
|
456
|
+
return result;
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
function voidExport(exports2, name) {
|
|
460
|
+
const fn = rawExport(exports2, name);
|
|
461
|
+
return (...args) => {
|
|
462
|
+
Reflect.apply(fn, void 0, args);
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function instantiate(module2, bundle) {
|
|
466
|
+
let memory;
|
|
467
|
+
const requireMemory = () => {
|
|
468
|
+
if (!memory) throw new Error("swift artifact memory is not live");
|
|
469
|
+
return memory;
|
|
470
|
+
};
|
|
471
|
+
const host = {
|
|
472
|
+
writeU32(ptr, value) {
|
|
473
|
+
new DataView(requireMemory().buffer).setUint32(ptr, value, true);
|
|
474
|
+
},
|
|
475
|
+
writeU64(ptr, value) {
|
|
476
|
+
new DataView(requireMemory().buffer).setBigUint64(ptr, value, true);
|
|
477
|
+
},
|
|
478
|
+
readU32(ptr) {
|
|
479
|
+
return new DataView(requireMemory().buffer).getUint32(ptr, true);
|
|
480
|
+
},
|
|
481
|
+
readString(ptr, len) {
|
|
482
|
+
return new TextDecoder().decode(
|
|
483
|
+
new Uint8Array(requireMemory().buffer).subarray(ptr, ptr + len)
|
|
484
|
+
);
|
|
485
|
+
},
|
|
486
|
+
bytes: () => new Uint8Array(requireMemory().buffer)
|
|
487
|
+
};
|
|
488
|
+
const argv = bundle === null ? [] : [bundle.argv0];
|
|
489
|
+
const instance = new WebAssembly.Instance(module2, {
|
|
490
|
+
wasi_snapshot_preview1: wasiImports(host, argv, bundle?.files ?? {})
|
|
491
|
+
});
|
|
492
|
+
const exportedMemory = instance.exports.memory;
|
|
493
|
+
if (!(exportedMemory instanceof WebAssembly.Memory)) {
|
|
494
|
+
throw new Error("swift artifact does not export its memory");
|
|
495
|
+
}
|
|
496
|
+
memory = exportedMemory;
|
|
497
|
+
const initialize = voidExport(instance.exports, "_initialize");
|
|
498
|
+
const mainArgv = voidExport(instance.exports, "__main_argc_argv");
|
|
499
|
+
const mount = pointerExport(instance.exports, "rnx_mount");
|
|
500
|
+
const mountViewExport = pointerExport(instance.exports, "rnx_mount_view");
|
|
501
|
+
const hasViewExport = pointerExport(instance.exports, "rnx_has_view");
|
|
502
|
+
const event = pointerExport(instance.exports, "rnx_event");
|
|
503
|
+
const stateExport = pointerExport(instance.exports, "rnx_state_export");
|
|
504
|
+
const stateImport = voidExport(instance.exports, "rnx_state_import");
|
|
505
|
+
const alloc = pointerExport(instance.exports, "rnx_alloc");
|
|
506
|
+
const free = voidExport(instance.exports, "rnx_free");
|
|
507
|
+
const openURLDrain = typeof instance.exports.rnx_open_url_drain === "function" ? pointerExport(instance.exports, "rnx_open_url_drain") : null;
|
|
508
|
+
const drainOpenURLs = () => {
|
|
509
|
+
if (!openURLDrain) return;
|
|
510
|
+
let urls;
|
|
511
|
+
try {
|
|
512
|
+
urls = JSON.parse(readBuffer(openURLDrain()));
|
|
513
|
+
} catch {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (!Array.isArray(urls)) return;
|
|
517
|
+
for (const url of urls) {
|
|
518
|
+
if (typeof url !== "string") continue;
|
|
519
|
+
import_react_native.Linking.canOpenURL(url).then(
|
|
520
|
+
(open) => {
|
|
521
|
+
if (open) import_react_native.Linking.openURL(url).catch(() => {
|
|
522
|
+
});
|
|
523
|
+
},
|
|
524
|
+
() => {
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
const readBuffer = (ptr) => {
|
|
530
|
+
const view = new DataView(requireMemory().buffer);
|
|
531
|
+
const length = view.getUint32(ptr, true);
|
|
532
|
+
return new TextDecoder().decode(
|
|
533
|
+
new Uint8Array(requireMemory().buffer, ptr + 4, length)
|
|
534
|
+
);
|
|
535
|
+
};
|
|
536
|
+
const withPayload = (value, run) => {
|
|
537
|
+
const encoded = new TextEncoder().encode(JSON.stringify(value));
|
|
538
|
+
const ptr = alloc(encoded.length);
|
|
539
|
+
new Uint8Array(requireMemory().buffer).set(encoded, ptr);
|
|
540
|
+
const result = run(ptr, encoded.length);
|
|
541
|
+
free(ptr);
|
|
542
|
+
return result;
|
|
543
|
+
};
|
|
544
|
+
initialize();
|
|
545
|
+
if (bundle === null) {
|
|
546
|
+
mainArgv(0, 0);
|
|
547
|
+
} else {
|
|
548
|
+
const encoded = new TextEncoder().encode(`${bundle.argv0}\0`);
|
|
549
|
+
const ptr = alloc(encoded.length + 4);
|
|
550
|
+
new Uint8Array(requireMemory().buffer).set(encoded, ptr + 4);
|
|
551
|
+
new DataView(requireMemory().buffer).setUint32(ptr, ptr + 4, true);
|
|
552
|
+
mainArgv(1, ptr);
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
mount: () => {
|
|
556
|
+
if (hasViewExport() === 1) {
|
|
557
|
+
throw new Error(
|
|
558
|
+
"swift package has an RNXPackage entry, not an App entry; mount it as a view or make its @main type conform to App"
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
const tree = readTree(readBuffer(mount()));
|
|
562
|
+
drainOpenURLs();
|
|
563
|
+
return tree;
|
|
564
|
+
},
|
|
565
|
+
mountView: (props) => {
|
|
566
|
+
if (hasViewExport() !== 1) {
|
|
567
|
+
throw new Error(
|
|
568
|
+
"swift package has no RNXPackage entry; its @main type must conform to RNXPackage to mount as a view"
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
const tree = readTree(
|
|
572
|
+
readBuffer(withPayload(props, (ptr, length) => mountViewExport(ptr, length)))
|
|
573
|
+
);
|
|
574
|
+
drainOpenURLs();
|
|
575
|
+
return tree;
|
|
576
|
+
},
|
|
577
|
+
hasView: () => hasViewExport() === 1,
|
|
578
|
+
deliver: (handlerId2, payload) => {
|
|
579
|
+
const tree = readTree(
|
|
580
|
+
readBuffer(
|
|
581
|
+
withPayload(
|
|
582
|
+
payload,
|
|
583
|
+
(ptr, length) => (
|
|
584
|
+
// handler ids are opaque to the tenant: they come from the tree
|
|
585
|
+
// this instance just returned and they are only meaningful to it
|
|
586
|
+
event(handlerId2, ptr, length)
|
|
587
|
+
)
|
|
588
|
+
)
|
|
589
|
+
)
|
|
590
|
+
);
|
|
591
|
+
drainOpenURLs();
|
|
592
|
+
return tree;
|
|
593
|
+
},
|
|
594
|
+
exportState: () => readBuffer(stateExport()),
|
|
595
|
+
importState: (state) => {
|
|
596
|
+
withPayload(JSON.parse(state), (ptr, length) => {
|
|
597
|
+
stateImport(ptr, length);
|
|
598
|
+
return 0;
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
var compiledModules = /* @__PURE__ */ new Map();
|
|
604
|
+
function decodeBundle(moduleUrl, packed) {
|
|
605
|
+
if (packed === void 0) return null;
|
|
606
|
+
const files = {};
|
|
607
|
+
for (const [name, base64] of Object.entries(packed)) {
|
|
608
|
+
try {
|
|
609
|
+
files[name] = decodeBase64(base64);
|
|
610
|
+
} catch (error) {
|
|
611
|
+
throw new Error(
|
|
612
|
+
`swift bundle file '${name}' is not decodable: ${error instanceof Error ? error.message : String(error)}`
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (Object.keys(files).length === 0) return null;
|
|
617
|
+
return { files, argv0: resArgv0(moduleUrl) };
|
|
618
|
+
}
|
|
619
|
+
function compile(url) {
|
|
620
|
+
const cached = compiledModules.get(url);
|
|
621
|
+
if (cached) return cached;
|
|
622
|
+
const pending = fetch(url).then((response) => {
|
|
623
|
+
if (!response.ok) {
|
|
624
|
+
throw new Error(`swift artifact ${url} answered ${response.status}`);
|
|
625
|
+
}
|
|
626
|
+
return response.arrayBuffer();
|
|
627
|
+
}).then((bytes) => WebAssembly.compile(bytes));
|
|
628
|
+
compiledModules.set(url, pending);
|
|
629
|
+
return pending;
|
|
630
|
+
}
|
|
631
|
+
var HIERARCHICAL = /* @__PURE__ */ new Map([
|
|
632
|
+
["label", "primary"],
|
|
633
|
+
["secondaryLabel", "secondary"]
|
|
634
|
+
]);
|
|
635
|
+
function withAlpha(color, alpha) {
|
|
636
|
+
const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color);
|
|
637
|
+
if (hex) {
|
|
638
|
+
const digits = hex[1];
|
|
639
|
+
const full = digits.length === 3 ? digits.split("").map((digit) => digit + digit).join("") : digits;
|
|
640
|
+
const value = Number.parseInt(full, 16);
|
|
641
|
+
return `rgba(${value >> 16 & 255},${value >> 8 & 255},${value & 255},${alpha})`;
|
|
642
|
+
}
|
|
643
|
+
const rgba = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)$/.exec(color);
|
|
644
|
+
if (rgba) {
|
|
645
|
+
return `rgba(${rgba[1]},${rgba[2]},${rgba[3]},${Number(rgba[4]) * alpha})`;
|
|
646
|
+
}
|
|
647
|
+
throw new Error(`swift color ${color} cannot take opacity ${alpha}`);
|
|
648
|
+
}
|
|
649
|
+
function splitColor(value) {
|
|
650
|
+
const at = value.lastIndexOf("@");
|
|
651
|
+
return at === -1 ? { name: value, alpha: 1 } : { name: value.slice(0, at), alpha: Number(value.slice(at + 1)) };
|
|
652
|
+
}
|
|
653
|
+
function resolveColor(value) {
|
|
654
|
+
const { name, alpha } = splitColor(value);
|
|
655
|
+
const resolved = (0, import_react_native.PlatformColor)(name);
|
|
656
|
+
if (alpha === 1) return resolved;
|
|
657
|
+
if (typeof resolved === "string") return withAlpha(resolved, alpha);
|
|
658
|
+
if (isRecord(resolved) && isRecord(resolved.dynamic)) {
|
|
659
|
+
const variants = {};
|
|
660
|
+
for (const [scheme, variant] of Object.entries(resolved.dynamic)) {
|
|
661
|
+
if (typeof variant !== "string") {
|
|
662
|
+
throw new Error(`swift color ${name} has a non-string ${scheme} variant`);
|
|
663
|
+
}
|
|
664
|
+
variants[scheme] = withAlpha(variant, alpha);
|
|
665
|
+
}
|
|
666
|
+
return { dynamic: variants };
|
|
667
|
+
}
|
|
668
|
+
throw new Error(`swift color ${name} cannot take opacity ${alpha}`);
|
|
669
|
+
}
|
|
670
|
+
function resolveModifier(modifier) {
|
|
671
|
+
const color = modifier.color;
|
|
672
|
+
if (typeof color !== "string") {
|
|
673
|
+
const glass = modifier.glass;
|
|
674
|
+
if (modifier.$type === "glassEffect" && isRecord(glass) && typeof glass.tint === "string") {
|
|
675
|
+
return { ...modifier, glass: { ...glass, tint: resolveColor(glass.tint) } };
|
|
676
|
+
}
|
|
677
|
+
return modifier;
|
|
678
|
+
}
|
|
679
|
+
const { name, alpha } = splitColor(color);
|
|
680
|
+
const level = modifier.$type === "foregroundStyle" ? HIERARCHICAL.get(name) : void 0;
|
|
681
|
+
if (level !== void 0 && alpha === 1) {
|
|
682
|
+
return {
|
|
683
|
+
$type: "foregroundStyle",
|
|
684
|
+
styleType: "hierarchical",
|
|
685
|
+
hierarchicalStyle: level
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
return { ...modifier, color: resolveColor(color) };
|
|
689
|
+
}
|
|
690
|
+
var SwiftResourcesContext = (0, import_react.createContext)(void 0);
|
|
691
|
+
function SwiftImage(props) {
|
|
692
|
+
const table = (0, import_react.useContext)(SwiftResourcesContext);
|
|
693
|
+
const { source, ...rest } = props ?? {};
|
|
694
|
+
const resolved = resolveImageSource(source, table ?? {}, (name) => {
|
|
695
|
+
console.error(`swift: no bundle asset named '${name}' in this mount's resources`);
|
|
696
|
+
});
|
|
697
|
+
return (0, import_react.createElement)(import_ui.Image, {
|
|
698
|
+
...rest,
|
|
699
|
+
...source === void 0 ? {} : { source: resolved }
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
var NODE_COMPONENTS = {
|
|
703
|
+
Alert: SwiftAlert,
|
|
704
|
+
BottomSheet: import_ui.BottomSheet,
|
|
705
|
+
Button: import_ui.Button,
|
|
706
|
+
Capsule: import_ui.Capsule,
|
|
707
|
+
Circle: import_ui.Circle,
|
|
708
|
+
ConfirmationDialog: import_ui.ConfirmationDialog,
|
|
709
|
+
ContextMenu: import_ui.ContextMenu,
|
|
710
|
+
DatePicker: import_ui.DatePicker,
|
|
711
|
+
Divider: import_ui.Divider,
|
|
712
|
+
Ellipse: import_ui.Ellipse,
|
|
713
|
+
Form: import_ui.Form,
|
|
714
|
+
GeometryReader: import_ui.GeometryReader,
|
|
715
|
+
GlassEffectContainer: import_ui.GlassEffectContainer,
|
|
716
|
+
Group: import_ui.Group,
|
|
717
|
+
HStack: import_ui.HStack,
|
|
718
|
+
Image: SwiftImage,
|
|
719
|
+
Label: import_ui.Label,
|
|
720
|
+
LazyVStack: import_ui.LazyVStack,
|
|
721
|
+
LinearGradient: import_ui.LinearGradient,
|
|
722
|
+
List: import_ui.List,
|
|
723
|
+
Menu: import_ui.Menu,
|
|
724
|
+
Path: import_ui.Path,
|
|
725
|
+
Picker: import_ui.Picker,
|
|
726
|
+
ProgressView: import_ui.ProgressView,
|
|
727
|
+
Rectangle: import_ui.Rectangle,
|
|
728
|
+
RoundedRectangle: import_ui.RoundedRectangle,
|
|
729
|
+
ScrollView: import_ui.ScrollView,
|
|
730
|
+
Section: import_ui.Section,
|
|
731
|
+
SecureField: import_ui.SecureField,
|
|
732
|
+
Slider: import_ui.Slider,
|
|
733
|
+
Spacer: import_ui.Spacer,
|
|
734
|
+
Stepper: import_ui.Stepper,
|
|
735
|
+
SwipeActions: import_ui.SwipeActions,
|
|
736
|
+
Text: import_ui.Text,
|
|
737
|
+
TextField: import_ui.TextField,
|
|
738
|
+
Toggle: import_ui.Toggle,
|
|
739
|
+
Tab: SwiftTabScene,
|
|
740
|
+
TabView: SwiftTabView,
|
|
741
|
+
VStack: import_ui.VStack,
|
|
742
|
+
ZStack: import_ui.ZStack
|
|
743
|
+
};
|
|
744
|
+
var TEXT_STYLE_SIZES = /* @__PURE__ */ new Map([
|
|
745
|
+
["largeTitle", 34],
|
|
746
|
+
["title", 28],
|
|
747
|
+
["title2", 22],
|
|
748
|
+
["title3", 20],
|
|
749
|
+
["headline", 17],
|
|
750
|
+
["subheadline", 15],
|
|
751
|
+
["body", 17],
|
|
752
|
+
["callout", 16],
|
|
753
|
+
["footnote", 13],
|
|
754
|
+
["caption", 12],
|
|
755
|
+
["caption2", 11]
|
|
756
|
+
]);
|
|
757
|
+
var FONT_WEIGHTS = /* @__PURE__ */ new Map([
|
|
758
|
+
["ultraLight", "100"],
|
|
759
|
+
["thin", "200"],
|
|
760
|
+
["light", "300"],
|
|
761
|
+
["regular", "400"],
|
|
762
|
+
["medium", "500"],
|
|
763
|
+
["semibold", "600"],
|
|
764
|
+
["bold", "700"],
|
|
765
|
+
["heavy", "800"],
|
|
766
|
+
["black", "900"]
|
|
767
|
+
]);
|
|
768
|
+
function fontModifier(modifiers) {
|
|
769
|
+
return modifiers?.find((modifier) => modifier.$type === "font");
|
|
770
|
+
}
|
|
771
|
+
function fontStyle(font) {
|
|
772
|
+
if (!font) return void 0;
|
|
773
|
+
const style = {};
|
|
774
|
+
if (typeof font.size === "number") style.fontSize = font.size;
|
|
775
|
+
else if (typeof font.style === "string") {
|
|
776
|
+
const size = TEXT_STYLE_SIZES.get(font.style);
|
|
777
|
+
if (size === void 0) throw new Error(`swift font style ${font.style} has no size`);
|
|
778
|
+
style.fontSize = size;
|
|
779
|
+
}
|
|
780
|
+
if (typeof font.weight === "string") {
|
|
781
|
+
const weight = FONT_WEIGHTS.get(font.weight);
|
|
782
|
+
if (weight === void 0)
|
|
783
|
+
throw new Error(`swift font weight ${font.weight} has no value`);
|
|
784
|
+
style.fontWeight = weight;
|
|
785
|
+
}
|
|
786
|
+
return style;
|
|
787
|
+
}
|
|
788
|
+
function sameValue(a, b) {
|
|
789
|
+
if (a === b) return true;
|
|
790
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
791
|
+
if (a.length !== b.length) return false;
|
|
792
|
+
for (let index = 0; index < a.length; index += 1) {
|
|
793
|
+
if (!sameValue(a[index], b[index])) return false;
|
|
794
|
+
}
|
|
795
|
+
return true;
|
|
796
|
+
}
|
|
797
|
+
if (isRecord(a) && isRecord(b)) {
|
|
798
|
+
const keys = Object.keys(a);
|
|
799
|
+
if (keys.length !== Object.keys(b).length) return false;
|
|
800
|
+
for (const key of keys) {
|
|
801
|
+
if (!sameValue(a[key], b[key])) return false;
|
|
802
|
+
}
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
function sameNode(a, b) {
|
|
808
|
+
if (a === b) return true;
|
|
809
|
+
if (a.t !== b.t || a.id !== b.id) return false;
|
|
810
|
+
if (!sameValue(a.p, b.p) || !sameValue(a.m, b.m) || !sameValue(a.h, b.h)) return false;
|
|
811
|
+
const left = a.c ?? [];
|
|
812
|
+
const right = b.c ?? [];
|
|
813
|
+
if (left.length !== right.length) return false;
|
|
814
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
815
|
+
if (!sameNode(left[index], right[index])) return false;
|
|
816
|
+
}
|
|
817
|
+
return true;
|
|
818
|
+
}
|
|
819
|
+
function handlerId(node, name) {
|
|
820
|
+
return node.h?.[name];
|
|
821
|
+
}
|
|
822
|
+
function pressProps(node, deliver) {
|
|
823
|
+
const presses = [];
|
|
824
|
+
for (const name of ["onPress", "onTap"]) {
|
|
825
|
+
const id = handlerId(node, name);
|
|
826
|
+
if (id !== void 0) presses.push(id);
|
|
827
|
+
}
|
|
828
|
+
if (presses.length === 0) return {};
|
|
829
|
+
return {
|
|
830
|
+
onPress: () => {
|
|
831
|
+
for (const id of presses) deliver(id, null);
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
function SwiftTabScene({ children }) {
|
|
836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
837
|
+
}
|
|
838
|
+
function SwiftTabView({
|
|
839
|
+
tabs,
|
|
840
|
+
selection,
|
|
841
|
+
onSelect,
|
|
842
|
+
modifiers,
|
|
843
|
+
children
|
|
844
|
+
}) {
|
|
845
|
+
const scenes = import_react.Children.toArray(children);
|
|
846
|
+
const routes = tabs.map((tab, index2) => ({
|
|
847
|
+
key: tab.testID,
|
|
848
|
+
name: tab.title ?? `tab-${index2}`,
|
|
849
|
+
title: tab.title,
|
|
850
|
+
sfSymbol: tab.systemImage,
|
|
851
|
+
testID: tab.testID
|
|
852
|
+
}));
|
|
853
|
+
const index = selection >= 0 && selection < routes.length ? selection : 0;
|
|
854
|
+
(0, import_react.useEffect)(() => {
|
|
855
|
+
if (selection !== index) onSelect?.(index);
|
|
856
|
+
}, [selection, index, onSelect]);
|
|
857
|
+
const bar = (0, import_react.createElement)(import_react_native_bottom_tabs.default, {
|
|
858
|
+
navigationState: { index, routes },
|
|
859
|
+
renderScene: ({ route }) => scenes[routes.findIndex((candidate) => candidate.key === route.key)],
|
|
860
|
+
onIndexChange: (next) => onSelect?.(next),
|
|
861
|
+
getLabelText: ({ route }) => route.title ?? route.key,
|
|
862
|
+
getIcon: ({ route }) => route.sfSymbol ? { sfSymbol: route.sfSymbol } : void 0,
|
|
863
|
+
getTestID: ({ route }) => route.testID
|
|
864
|
+
});
|
|
865
|
+
return (0, import_react.createElement)(
|
|
866
|
+
import_ui.VStack,
|
|
867
|
+
{
|
|
868
|
+
...modifiers?.length ? { modifiers } : {},
|
|
869
|
+
style: {
|
|
870
|
+
alignSelf: "stretch",
|
|
871
|
+
alignItems: "stretch",
|
|
872
|
+
flexGrow: 1,
|
|
873
|
+
flexShrink: 1,
|
|
874
|
+
flexBasis: "auto"
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
bar
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
function SwiftAlert({
|
|
881
|
+
title,
|
|
882
|
+
message,
|
|
883
|
+
buttons,
|
|
884
|
+
onButtonPress,
|
|
885
|
+
onDismiss
|
|
886
|
+
}) {
|
|
887
|
+
const latest = (0, import_react.useRef)({ title, message, buttons, onButtonPress, onDismiss });
|
|
888
|
+
(0, import_react.useEffect)(() => {
|
|
889
|
+
latest.current = { title, message, buttons, onButtonPress, onDismiss };
|
|
890
|
+
});
|
|
891
|
+
(0, import_react.useEffect)(() => {
|
|
892
|
+
const handle = (0, import_runtime.getNativeAlerts)().show(
|
|
893
|
+
latest.current.title,
|
|
894
|
+
latest.current.message,
|
|
895
|
+
latest.current.buttons.map((button, index) => ({
|
|
896
|
+
text: button.text,
|
|
897
|
+
style: button.role === "destructive" ? "destructive" : button.role === "cancel" ? "cancel" : "default",
|
|
898
|
+
// the tapped action runs its swift closure and clears isPresented,
|
|
899
|
+
// which is the order the system alert uses on the way out: the action
|
|
900
|
+
// body is the last thing that runs with the alert still up. the
|
|
901
|
+
// handlers come off the ref at tap time, not from this render.
|
|
902
|
+
onPress: () => {
|
|
903
|
+
latest.current.onButtonPress?.(index);
|
|
904
|
+
latest.current.onDismiss?.();
|
|
905
|
+
}
|
|
906
|
+
}))
|
|
907
|
+
);
|
|
908
|
+
return () => {
|
|
909
|
+
(0, import_runtime.getNativeAlerts)().dismiss(handle);
|
|
910
|
+
};
|
|
911
|
+
}, []);
|
|
912
|
+
return null;
|
|
913
|
+
}
|
|
914
|
+
function readAlertButtons(value) {
|
|
915
|
+
if (!Array.isArray(value)) return [];
|
|
916
|
+
return value.map((entry) => {
|
|
917
|
+
if (!isRecord(entry)) return {};
|
|
918
|
+
return {
|
|
919
|
+
...typeof entry.text === "string" ? { text: entry.text } : {},
|
|
920
|
+
...typeof entry.role === "string" ? { role: entry.role } : {}
|
|
921
|
+
};
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
function nodeProps(node, deliver) {
|
|
925
|
+
const props = node.p ?? {};
|
|
926
|
+
switch (node.t) {
|
|
927
|
+
case "Text": {
|
|
928
|
+
const style = fontStyle(fontModifier(node.m));
|
|
929
|
+
return {
|
|
930
|
+
children: typeof props.children === "string" ? props.children : "",
|
|
931
|
+
...style ? { style } : {},
|
|
932
|
+
...pressProps(node, deliver)
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
case "Image": {
|
|
936
|
+
const font = fontModifier(node.m);
|
|
937
|
+
const size = typeof font?.size === "number" ? font.size : void 0;
|
|
938
|
+
return {
|
|
939
|
+
...typeof props.systemName === "string" ? { systemName: props.systemName } : {},
|
|
940
|
+
// a bundle asset name rides as the kit image source; the kit paints
|
|
941
|
+
// resolved { uri } sources and keeps its placeholder for names the
|
|
942
|
+
// table could not resolve.
|
|
943
|
+
...typeof props.name === "string" ? { source: props.name } : {},
|
|
944
|
+
...props.resizable === true ? { resizable: true } : {},
|
|
945
|
+
...typeof props.renderingMode === "string" ? { renderingMode: props.renderingMode } : {},
|
|
946
|
+
...size === void 0 ? {} : { size },
|
|
947
|
+
...pressProps(node, deliver)
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
case "Toggle": {
|
|
951
|
+
const onValueChange = handlerId(node, "onValueChange");
|
|
952
|
+
return {
|
|
953
|
+
isOn: props.value === true,
|
|
954
|
+
...onValueChange === void 0 ? {} : { onIsOnChange: (value) => deliver(onValueChange, value) },
|
|
955
|
+
// the gesture replaces the row's own press (a label tap runs it and
|
|
956
|
+
// does not toggle); the switch keeps toggling through onValueChange.
|
|
957
|
+
...pressProps(node, deliver)
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
case "TextField": {
|
|
961
|
+
const onChangeText = handlerId(node, "onChangeText");
|
|
962
|
+
return {
|
|
963
|
+
...typeof props.placeholder === "string" ? { placeholder: props.placeholder } : {},
|
|
964
|
+
...typeof props.defaultValue === "string" ? { defaultValue: props.defaultValue } : {},
|
|
965
|
+
...onChangeText === void 0 ? {} : { onChangeText: (value) => deliver(onChangeText, value) }
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
case "Slider": {
|
|
969
|
+
const onValueChange = handlerId(node, "onValueChange");
|
|
970
|
+
return {
|
|
971
|
+
value: typeof props.value === "number" ? props.value : 0,
|
|
972
|
+
min: typeof props.min === "number" ? props.min : 0,
|
|
973
|
+
max: typeof props.max === "number" ? props.max : 1,
|
|
974
|
+
...onValueChange === void 0 ? {} : { onValueChange: (value) => deliver(onValueChange, value) },
|
|
975
|
+
// a tap runs the gesture and leaves the value alone: only a drag
|
|
976
|
+
// moves it, so the gesture rides onPress beside the drag handler.
|
|
977
|
+
...pressProps(node, deliver)
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
case "Button":
|
|
981
|
+
return pressProps(node, deliver);
|
|
982
|
+
case "EditButton":
|
|
983
|
+
return pressProps(node, deliver);
|
|
984
|
+
case "TabView": {
|
|
985
|
+
const onSelect = handlerId(node, "onSelect");
|
|
986
|
+
const tabs = (node.c ?? []).map((tab, index) => {
|
|
987
|
+
const tabProps = tab.p ?? {};
|
|
988
|
+
return {
|
|
989
|
+
...typeof tabProps.title === "string" ? { title: tabProps.title } : {},
|
|
990
|
+
...typeof tabProps.systemImage === "string" ? { systemImage: tabProps.systemImage } : {},
|
|
991
|
+
...typeof tabProps.role === "string" ? { role: tabProps.role } : {},
|
|
992
|
+
testID: `swift-tab-${index}`
|
|
993
|
+
};
|
|
994
|
+
});
|
|
995
|
+
return {
|
|
996
|
+
tabs,
|
|
997
|
+
selection: typeof props.selection === "number" ? props.selection : 0,
|
|
998
|
+
...onSelect === void 0 ? {} : { onSelect: (index) => deliver(onSelect, index) }
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
case "BottomSheet": {
|
|
1002
|
+
const onDismiss = handlerId(node, "onDismiss");
|
|
1003
|
+
const detents = (node.c ?? []).flatMap((child) => nodeModifiers(child) ?? []).filter((modifier) => modifier.$type === "presentationDetents");
|
|
1004
|
+
return {
|
|
1005
|
+
isOpened: props.isOpened === true,
|
|
1006
|
+
...detents.length === 0 ? {} : { modifiers: detents },
|
|
1007
|
+
...onDismiss === void 0 ? {} : { onDismiss: () => deliver(onDismiss, null) }
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
case "ConfirmationDialog": {
|
|
1011
|
+
return { isPresented: props.isPresented === true };
|
|
1012
|
+
}
|
|
1013
|
+
case "Alert": {
|
|
1014
|
+
const onButtonPress = handlerId(node, "onButtonPress");
|
|
1015
|
+
const onDismiss = handlerId(node, "onDismiss");
|
|
1016
|
+
return {
|
|
1017
|
+
title: typeof props.title === "string" ? props.title : "",
|
|
1018
|
+
...typeof props.message === "string" ? { message: props.message } : {},
|
|
1019
|
+
buttons: readAlertButtons(props.buttons),
|
|
1020
|
+
...onButtonPress === void 0 ? {} : { onButtonPress: (index) => deliver(onButtonPress, index) },
|
|
1021
|
+
...onDismiss === void 0 ? {} : { onDismiss: () => deliver(onDismiss, null) }
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
case "SecureField": {
|
|
1025
|
+
const onChangeText = handlerId(node, "onChangeText");
|
|
1026
|
+
return {
|
|
1027
|
+
...typeof props.placeholder === "string" ? { placeholder: props.placeholder } : {},
|
|
1028
|
+
...typeof props.prompt === "string" ? { prompt: props.prompt } : {},
|
|
1029
|
+
...typeof props.defaultValue === "string" ? { defaultValue: props.defaultValue } : {},
|
|
1030
|
+
...onChangeText === void 0 ? {} : { onChangeText: (value) => deliver(onChangeText, value) }
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
case "Picker": {
|
|
1034
|
+
const onSelectionChange = handlerId(node, "onSelectionChange");
|
|
1035
|
+
return {
|
|
1036
|
+
...typeof props.title === "string" ? { label: props.title } : {},
|
|
1037
|
+
...props.selection === void 0 ? {} : { selection: props.selection },
|
|
1038
|
+
...onSelectionChange === void 0 ? {} : {
|
|
1039
|
+
onSelectionChange: (value) => deliver(onSelectionChange, value)
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
case "DatePicker": {
|
|
1044
|
+
return {
|
|
1045
|
+
...typeof props.title === "string" ? { label: props.title } : {},
|
|
1046
|
+
// the wire carries epoch seconds; the kit takes a Date and formats it
|
|
1047
|
+
...typeof props.value === "number" ? { value: new Date(props.value * 1e3) } : {},
|
|
1048
|
+
...Array.isArray(props.components) ? { components: props.components } : {}
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
case "GlassEffectContainer":
|
|
1052
|
+
return {};
|
|
1053
|
+
case "ProgressView":
|
|
1054
|
+
return {
|
|
1055
|
+
...typeof props.title === "string" ? { label: props.title } : {},
|
|
1056
|
+
...typeof props.value === "number" || props.value === null ? { value: props.value } : {},
|
|
1057
|
+
...typeof props.total === "number" ? { total: props.total } : {}
|
|
1058
|
+
};
|
|
1059
|
+
default:
|
|
1060
|
+
return { ...props, ...pressProps(node, deliver) };
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
function numberProp(node, name) {
|
|
1064
|
+
const value = node.p?.[name];
|
|
1065
|
+
return typeof value === "number" ? value : 0;
|
|
1066
|
+
}
|
|
1067
|
+
function menuItemLabel(node) {
|
|
1068
|
+
const [only] = node.c ?? [];
|
|
1069
|
+
if (node.t !== "Button" || node.c?.length !== 1 || !only) return void 0;
|
|
1070
|
+
if (only.t === "Text" && typeof only.p?.children === "string") {
|
|
1071
|
+
return { label: only.p.children };
|
|
1072
|
+
}
|
|
1073
|
+
if (only.t === "Label" && typeof only.p?.title === "string" && (only.p?.systemImage === void 0 || typeof only.p?.systemImage === "string")) {
|
|
1074
|
+
return {
|
|
1075
|
+
label: only.p.title,
|
|
1076
|
+
...typeof only.p?.systemImage === "string" ? { systemImage: only.p.systemImage } : {}
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
return void 0;
|
|
1080
|
+
}
|
|
1081
|
+
function renderMenuItem(node, deliver, cache) {
|
|
1082
|
+
const item = menuItemLabel(node);
|
|
1083
|
+
if (item !== void 0) {
|
|
1084
|
+
const modifiers = nodeModifiers(node);
|
|
1085
|
+
return (0, import_react.createElement)(import_ui.Button, {
|
|
1086
|
+
key: node.id,
|
|
1087
|
+
...item,
|
|
1088
|
+
...modifiers === void 0 ? {} : { modifiers },
|
|
1089
|
+
...pressProps(node, deliver)
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
return renderNode(node, deliver, cache);
|
|
1093
|
+
}
|
|
1094
|
+
function renderMenu(node, deliver, cache) {
|
|
1095
|
+
const labelCount = numberProp(node, "labelCount");
|
|
1096
|
+
const kids = node.c ?? [];
|
|
1097
|
+
const labels = kids.slice(0, labelCount);
|
|
1098
|
+
const items = kids.slice(labelCount);
|
|
1099
|
+
const [only] = labels;
|
|
1100
|
+
const onlyText = labels.length === 1 && only.t === "Text" && typeof only.p?.children === "string" ? only.p.children : void 0;
|
|
1101
|
+
const onlyLabel = labels.length === 1 && only.t === "Label" && typeof only.p?.title === "string" && (only.p?.systemImage === void 0 || typeof only.p?.systemImage === "string") ? only : void 0;
|
|
1102
|
+
const label = onlyText !== void 0 || onlyLabel !== void 0 ? void 0 : (0, import_react.createElement)(
|
|
1103
|
+
import_react.Fragment,
|
|
1104
|
+
null,
|
|
1105
|
+
...labels.map((child) => renderNode(child, deliver, cache))
|
|
1106
|
+
);
|
|
1107
|
+
const labelModifiers = labels.length === 1 ? nodeModifiers(only) : void 0;
|
|
1108
|
+
const modifiers = nodeModifiers(node);
|
|
1109
|
+
const combined = [...labelModifiers ?? [], ...modifiers ?? []];
|
|
1110
|
+
return (0, import_react.createElement)(
|
|
1111
|
+
import_ui.Menu,
|
|
1112
|
+
{
|
|
1113
|
+
key: node.id,
|
|
1114
|
+
...combined.length > 0 ? { modifiers: combined } : {},
|
|
1115
|
+
...onlyText !== void 0 ? { label: onlyText } : {},
|
|
1116
|
+
...onlyLabel !== void 0 ? {
|
|
1117
|
+
label: onlyLabel.p?.title,
|
|
1118
|
+
...typeof onlyLabel.p?.systemImage === "string" ? { systemImage: onlyLabel.p.systemImage } : {}
|
|
1119
|
+
} : {},
|
|
1120
|
+
...label === void 0 ? {} : { label }
|
|
1121
|
+
},
|
|
1122
|
+
...items.map((child) => renderMenuItem(child, deliver))
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1125
|
+
function renderContextMenu(node, deliver, cache) {
|
|
1126
|
+
const kids = node.c ?? [];
|
|
1127
|
+
const contentCount = numberProp(node, "contentCount");
|
|
1128
|
+
const itemCount = numberProp(node, "itemCount");
|
|
1129
|
+
const content = kids.slice(0, contentCount);
|
|
1130
|
+
const items = kids.slice(contentCount, contentCount + itemCount);
|
|
1131
|
+
const preview = kids.slice(contentCount + itemCount);
|
|
1132
|
+
const modifiers = nodeModifiers(node);
|
|
1133
|
+
return (0, import_react.createElement)(
|
|
1134
|
+
import_ui.ContextMenu,
|
|
1135
|
+
{
|
|
1136
|
+
key: node.id,
|
|
1137
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
1138
|
+
},
|
|
1139
|
+
(0, import_react.createElement)(
|
|
1140
|
+
import_ui.Trigger,
|
|
1141
|
+
{ key: `${node.id}/trigger` },
|
|
1142
|
+
...content.map((child) => renderNode(child, deliver, cache))
|
|
1143
|
+
),
|
|
1144
|
+
(0, import_react.createElement)(
|
|
1145
|
+
import_ui.Items,
|
|
1146
|
+
{ key: `${node.id}/items` },
|
|
1147
|
+
...items.map((child) => renderMenuItem(child, deliver))
|
|
1148
|
+
),
|
|
1149
|
+
...preview.length > 0 ? [
|
|
1150
|
+
(0, import_react.createElement)(
|
|
1151
|
+
import_ui.Preview,
|
|
1152
|
+
{ key: `${node.id}/preview` },
|
|
1153
|
+
...preview.map((child) => renderNode(child, deliver, cache))
|
|
1154
|
+
)
|
|
1155
|
+
] : []
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
function renderSwipeActions(node, deliver, cache) {
|
|
1159
|
+
const kids = node.c ?? [];
|
|
1160
|
+
const content = kids.slice(0, numberProp(node, "contentCount"));
|
|
1161
|
+
const actions = kids.slice(numberProp(node, "contentCount"));
|
|
1162
|
+
const modifiers = nodeModifiers(node);
|
|
1163
|
+
const { Actions } = import_ui.SwipeActions;
|
|
1164
|
+
return (0, import_react.createElement)(
|
|
1165
|
+
import_ui.SwipeActions,
|
|
1166
|
+
{
|
|
1167
|
+
key: node.id,
|
|
1168
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
1169
|
+
},
|
|
1170
|
+
...content.map((child) => renderNode(child, deliver, cache)),
|
|
1171
|
+
...actions.length > 0 ? [
|
|
1172
|
+
(0, import_react.createElement)(
|
|
1173
|
+
Actions,
|
|
1174
|
+
{
|
|
1175
|
+
key: `${node.id}/actions`,
|
|
1176
|
+
edge: node.p?.edge === "leading" ? "leading" : "trailing",
|
|
1177
|
+
...typeof node.p?.allowsFullSwipe === "boolean" ? { allowsFullSwipe: node.p.allowsFullSwipe } : {}
|
|
1178
|
+
},
|
|
1179
|
+
...actions.map((child) => renderNode(child, deliver, cache))
|
|
1180
|
+
)
|
|
1181
|
+
] : []
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
function ClosureStepper({
|
|
1185
|
+
deliver,
|
|
1186
|
+
onIncrement,
|
|
1187
|
+
onDecrement,
|
|
1188
|
+
...rest
|
|
1189
|
+
}) {
|
|
1190
|
+
const last = (0, import_react.useRef)(0);
|
|
1191
|
+
return (0, import_react.createElement)(import_ui.Stepper, {
|
|
1192
|
+
...rest,
|
|
1193
|
+
onValueChange: (next) => {
|
|
1194
|
+
if (next > last.current && onIncrement !== void 0) {
|
|
1195
|
+
deliver(onIncrement, null);
|
|
1196
|
+
} else if (next < last.current && onDecrement !== void 0) {
|
|
1197
|
+
deliver(onDecrement, null);
|
|
1198
|
+
}
|
|
1199
|
+
last.current = next;
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
function renderStepper(node, deliver, cache) {
|
|
1204
|
+
const kids = node.c ?? [];
|
|
1205
|
+
const label = kids.length === 0 ? void 0 : (0, import_react.createElement)(
|
|
1206
|
+
import_react.Fragment,
|
|
1207
|
+
null,
|
|
1208
|
+
...kids.map((child) => renderNode(child, deliver, cache))
|
|
1209
|
+
);
|
|
1210
|
+
const modifiers = nodeModifiers(node);
|
|
1211
|
+
const shared = {
|
|
1212
|
+
key: node.id,
|
|
1213
|
+
...modifiers === void 0 ? {} : { modifiers },
|
|
1214
|
+
...label === void 0 ? {} : { label },
|
|
1215
|
+
...typeof node.p?.min === "number" ? { min: node.p.min } : {},
|
|
1216
|
+
...typeof node.p?.max === "number" ? { max: node.p.max } : {},
|
|
1217
|
+
...typeof node.p?.step === "number" ? { step: node.p.step } : {}
|
|
1218
|
+
};
|
|
1219
|
+
const onValueChange = handlerId(node, "onValueChange");
|
|
1220
|
+
if (onValueChange !== void 0) {
|
|
1221
|
+
return (0, import_react.createElement)(import_ui.Stepper, {
|
|
1222
|
+
...shared,
|
|
1223
|
+
...typeof node.p?.value === "number" ? { value: node.p.value } : {},
|
|
1224
|
+
onValueChange: (value) => deliver(onValueChange, value)
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
return (0, import_react.createElement)(ClosureStepper, {
|
|
1228
|
+
...shared,
|
|
1229
|
+
deliver,
|
|
1230
|
+
...handlerId(node, "onIncrement") === void 0 ? {} : { onIncrement: handlerId(node, "onIncrement") },
|
|
1231
|
+
...handlerId(node, "onDecrement") === void 0 ? {} : { onDecrement: handlerId(node, "onDecrement") }
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
function buttonModifier(modifier) {
|
|
1235
|
+
if (modifier.$type === "glassEffect") {
|
|
1236
|
+
const glass = modifier.glass;
|
|
1237
|
+
const variant = isRecord(glass) && typeof glass.variant === "string" ? glass.variant : "regular";
|
|
1238
|
+
return variant === "identity" ? modifier : { $type: "buttonStyle", style: "glass" };
|
|
1239
|
+
}
|
|
1240
|
+
if (modifier.$type === "foregroundStyle" && modifier.color !== void 0) {
|
|
1241
|
+
return { $type: "tint", color: modifier.color };
|
|
1242
|
+
}
|
|
1243
|
+
return modifier;
|
|
1244
|
+
}
|
|
1245
|
+
function nodeModifiers(node) {
|
|
1246
|
+
const resolved = node.m?.map(resolveModifier);
|
|
1247
|
+
if (node.t !== "Button") return resolved;
|
|
1248
|
+
return resolved?.map(buttonModifier);
|
|
1249
|
+
}
|
|
1250
|
+
function dialogChildren(node, deliver) {
|
|
1251
|
+
const children = node.c?.map((child) => renderNode(child, deliver));
|
|
1252
|
+
const props = node.p ?? {};
|
|
1253
|
+
if (props.showsTitle !== true || typeof props.title !== "string") return children;
|
|
1254
|
+
const title = (0, import_react.createElement)(import_ui.Text, { key: `${node.id}/title`, children: props.title });
|
|
1255
|
+
return [title, ...children ?? []];
|
|
1256
|
+
}
|
|
1257
|
+
var Stack = (0, import_native_stack.createNativeStackNavigator)();
|
|
1258
|
+
var NAVIGATOR_FILL = { flex: 1, alignSelf: "stretch" };
|
|
1259
|
+
function readNodes(value) {
|
|
1260
|
+
if (!Array.isArray(value)) return [];
|
|
1261
|
+
return value.map(readNode);
|
|
1262
|
+
}
|
|
1263
|
+
function hasPrefix(names, of) {
|
|
1264
|
+
return names.every((name, index) => of[index] === name);
|
|
1265
|
+
}
|
|
1266
|
+
function sameNames(a, b) {
|
|
1267
|
+
return a.length === b.length && a.every((name, index) => b[index] === name);
|
|
1268
|
+
}
|
|
1269
|
+
function commonPrefixLength(a, b) {
|
|
1270
|
+
let length = 0;
|
|
1271
|
+
while (length < a.length && length < b.length && a[length] === b[length]) length++;
|
|
1272
|
+
return length;
|
|
1273
|
+
}
|
|
1274
|
+
function reconcilePlan(names, desired) {
|
|
1275
|
+
const common = commonPrefixLength(names, desired);
|
|
1276
|
+
if (common === names.length && common === desired.length) return { kind: "in-step" };
|
|
1277
|
+
if (common === names.length) return { kind: "push" };
|
|
1278
|
+
if (common === desired.length) return { kind: "pop" };
|
|
1279
|
+
const top = desired[desired.length - 1];
|
|
1280
|
+
return { kind: "replace", replaceAnimation: names.includes(top) ? "pop" : "push" };
|
|
1281
|
+
}
|
|
1282
|
+
function resolveLargeTitles(modes) {
|
|
1283
|
+
let previous = true;
|
|
1284
|
+
return modes.map((mode) => {
|
|
1285
|
+
const large = mode === "inline" ? false : mode === "large" ? true : previous;
|
|
1286
|
+
previous = large;
|
|
1287
|
+
return large;
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
function screenOptions(node, deliver, largeTitle, replaceAnimation) {
|
|
1291
|
+
const props = node.p ?? {};
|
|
1292
|
+
const options = {
|
|
1293
|
+
title: typeof props.title === "string" ? props.title : "",
|
|
1294
|
+
headerLargeTitleEnabled: largeTitle
|
|
1295
|
+
};
|
|
1296
|
+
if (replaceAnimation !== void 0) options.animationTypeForReplace = replaceAnimation;
|
|
1297
|
+
const leading = readNodes(props.leading);
|
|
1298
|
+
const trailing = readNodes(props.trailing);
|
|
1299
|
+
const principal = readNodes(props.principal);
|
|
1300
|
+
const render = (nodes) => () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: nodes.map((child) => renderNode(child, deliver)) });
|
|
1301
|
+
if (leading.length > 0) {
|
|
1302
|
+
options.headerLeft = render(leading);
|
|
1303
|
+
options.headerBackVisible = true;
|
|
1304
|
+
}
|
|
1305
|
+
if (trailing.length > 0) options.headerRight = render(trailing);
|
|
1306
|
+
if (principal.length > 0) options.headerTitle = render(principal);
|
|
1307
|
+
return options;
|
|
1308
|
+
}
|
|
1309
|
+
function SwiftScreen({
|
|
1310
|
+
node,
|
|
1311
|
+
navigation,
|
|
1312
|
+
deliver,
|
|
1313
|
+
report
|
|
1314
|
+
}) {
|
|
1315
|
+
const routes = (0, import_native.useNavigationState)(
|
|
1316
|
+
(state) => state.routes.map((route) => route.name).join("\0")
|
|
1317
|
+
);
|
|
1318
|
+
(0, import_react.useEffect)(() => {
|
|
1319
|
+
report(navigation, routes === "" ? [] : routes.split("\0"));
|
|
1320
|
+
});
|
|
1321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: node.c?.map((child) => renderNode(child, deliver)) });
|
|
1322
|
+
}
|
|
1323
|
+
function NavigationStackHost({ node, deliver }) {
|
|
1324
|
+
const screens = (node.c ?? []).filter((child) => child.t === "NavigationScreen");
|
|
1325
|
+
const desired = screens.map((screen) => screen.id);
|
|
1326
|
+
const largeTitles = resolveLargeTitles(
|
|
1327
|
+
screens.map((screen) => {
|
|
1328
|
+
const mode = screen.p?.titleDisplayMode;
|
|
1329
|
+
return typeof mode === "string" ? mode : void 0;
|
|
1330
|
+
})
|
|
1331
|
+
);
|
|
1332
|
+
const onPop = node.h?.onPop;
|
|
1333
|
+
const reportRef = (0, import_react.useRef)(null);
|
|
1334
|
+
const reportedRef = (0, import_react.useRef)([]);
|
|
1335
|
+
const expectedRef = (0, import_react.useRef)(null);
|
|
1336
|
+
const syncedRef = (0, import_react.useRef)(null);
|
|
1337
|
+
const [, rerender] = (0, import_react.useReducer)((count) => count + 1, 0);
|
|
1338
|
+
const report = (0, import_react.useCallback)((navigation, names) => {
|
|
1339
|
+
const previous = reportRef.current;
|
|
1340
|
+
reportRef.current = { navigation, names };
|
|
1341
|
+
if (previous && sameNames(previous.names, names)) return;
|
|
1342
|
+
rerender();
|
|
1343
|
+
}, []);
|
|
1344
|
+
const reported = reportRef.current?.names ?? [];
|
|
1345
|
+
const plan = reportRef.current ? reconcilePlan(reported, desired) : null;
|
|
1346
|
+
const replaceTop = plan?.kind === "replace" ? desired[desired.length - 1] : void 0;
|
|
1347
|
+
(0, import_react.useEffect)(() => {
|
|
1348
|
+
const current = reportRef.current;
|
|
1349
|
+
if (!current) return;
|
|
1350
|
+
const names = current.names;
|
|
1351
|
+
const previous = reportedRef.current;
|
|
1352
|
+
const isReport = !sameNames(previous, names);
|
|
1353
|
+
if (isReport) reportedRef.current = names;
|
|
1354
|
+
const expected = expectedRef.current;
|
|
1355
|
+
if (expected) {
|
|
1356
|
+
if (sameNames(expected, names)) expectedRef.current = null;
|
|
1357
|
+
else if (!isReport) return;
|
|
1358
|
+
else expectedRef.current = null;
|
|
1359
|
+
}
|
|
1360
|
+
const dropped = previous.slice(names.length);
|
|
1361
|
+
const settled = syncedRef.current;
|
|
1362
|
+
const navigatorPopped = isReport && dropped.length > 0 && settled !== null && sameNames(settled, desired) && hasPrefix(names, desired) && hasPrefix(desired.slice(names.length), dropped);
|
|
1363
|
+
if (navigatorPopped && onPop !== void 0) {
|
|
1364
|
+
deliver(onPop, { count: dropped.length });
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
const next = reconcilePlan(names, desired);
|
|
1368
|
+
if (next.kind === "in-step") {
|
|
1369
|
+
expectedRef.current = null;
|
|
1370
|
+
syncedRef.current = desired;
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
expectedRef.current = desired;
|
|
1374
|
+
if (next.kind === "push") {
|
|
1375
|
+
for (const name of desired.slice(names.length)) current.navigation.push(name);
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
if (next.kind === "pop") {
|
|
1379
|
+
current.navigation.pop(names.length - desired.length);
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
current.navigation.reset({
|
|
1383
|
+
index: Math.max(0, desired.length - 1),
|
|
1384
|
+
routes: desired.map((name) => ({ name }))
|
|
1385
|
+
});
|
|
1386
|
+
});
|
|
1387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Stack.Navigator, { initialRouteName: desired[0], children: screens.map((screen, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1388
|
+
Stack.Screen,
|
|
1389
|
+
{
|
|
1390
|
+
name: screen.id,
|
|
1391
|
+
options: screenOptions(
|
|
1392
|
+
screen,
|
|
1393
|
+
deliver,
|
|
1394
|
+
largeTitles[index],
|
|
1395
|
+
screen.id === replaceTop ? plan?.kind === "replace" ? plan.replaceAnimation : void 0 : void 0
|
|
1396
|
+
),
|
|
1397
|
+
children: (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1398
|
+
SwiftScreen,
|
|
1399
|
+
{
|
|
1400
|
+
node: screen,
|
|
1401
|
+
navigation: props.navigation,
|
|
1402
|
+
deliver,
|
|
1403
|
+
report
|
|
1404
|
+
}
|
|
1405
|
+
)
|
|
1406
|
+
},
|
|
1407
|
+
screen.id
|
|
1408
|
+
)) });
|
|
1409
|
+
}
|
|
1410
|
+
var REGULAR_WIDTH = 768;
|
|
1411
|
+
function SplitViewHost({
|
|
1412
|
+
node,
|
|
1413
|
+
deliver,
|
|
1414
|
+
cache
|
|
1415
|
+
}) {
|
|
1416
|
+
const { width } = (0, import_react_native.useWindowDimensions)();
|
|
1417
|
+
const screens = (node.c ?? []).filter((child) => child.t === "NavigationScreen");
|
|
1418
|
+
if (width < REGULAR_WIDTH) {
|
|
1419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: NAVIGATOR_FILL, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node, deliver }) });
|
|
1420
|
+
}
|
|
1421
|
+
const sidebar = screens[0];
|
|
1422
|
+
const pushed = screens.slice(1);
|
|
1423
|
+
const detailProp = node.p?.detail;
|
|
1424
|
+
const detail = isRecord(detailProp) && detailProp.t === "SplitDetail" ? readNodes(detailProp.c) : [];
|
|
1425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: { flex: 1, flexDirection: "row", alignSelf: "stretch" }, children: [
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { width: 320 }, children: sidebar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node: { ...node, c: [sidebar] }, deliver }) : null }),
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { flex: 1 }, children: pushed.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node: { ...node, c: pushed }, deliver }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: detail.map((child) => renderNode(child, deliver, cache)) }) })
|
|
1428
|
+
] });
|
|
1429
|
+
}
|
|
1430
|
+
function SwiftAppear({
|
|
1431
|
+
node,
|
|
1432
|
+
deliver,
|
|
1433
|
+
children
|
|
1434
|
+
}) {
|
|
1435
|
+
const onAppear = handlerId(node, "onAppear");
|
|
1436
|
+
const onDisappear = handlerId(node, "onDisappear");
|
|
1437
|
+
(0, import_react.useEffect)(() => {
|
|
1438
|
+
if (onAppear !== void 0) deliver(onAppear, null);
|
|
1439
|
+
return () => {
|
|
1440
|
+
if (onDisappear !== void 0) deliver(onDisappear, null);
|
|
1441
|
+
};
|
|
1442
|
+
}, []);
|
|
1443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
1444
|
+
}
|
|
1445
|
+
function renderNode(node, deliver, cache) {
|
|
1446
|
+
const cached = cache?.entries.get(node.id);
|
|
1447
|
+
if (cached && sameNode(cached.node, node)) return cached.element;
|
|
1448
|
+
const built = buildNode(node, deliver, cache);
|
|
1449
|
+
const element = node.h?.onAppear !== void 0 || node.h?.onDisappear !== void 0 ? (0, import_react.createElement)(SwiftAppear, { key: node.id, node, deliver }, built) : built;
|
|
1450
|
+
cache?.entries.set(node.id, { node, element });
|
|
1451
|
+
return element;
|
|
1452
|
+
}
|
|
1453
|
+
function buildNode(node, deliver, cache) {
|
|
1454
|
+
if (node.t === "Menu") return renderMenu(node, deliver, cache);
|
|
1455
|
+
if (node.t === "ContextMenu") return renderContextMenu(node, deliver, cache);
|
|
1456
|
+
if (node.t === "SwipeActions") return renderSwipeActions(node, deliver, cache);
|
|
1457
|
+
if (node.t === "Stepper") return renderStepper(node, deliver, cache);
|
|
1458
|
+
if (node.t === "NavigationStack") {
|
|
1459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: NAVIGATOR_FILL, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node, deliver }) }, node.id);
|
|
1460
|
+
}
|
|
1461
|
+
if (node.t === "NavigationSplitView") {
|
|
1462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SplitViewHost, { node, deliver, cache }, node.id);
|
|
1463
|
+
}
|
|
1464
|
+
if (node.t === "NavigationLink") {
|
|
1465
|
+
return (0, import_react.createElement)(
|
|
1466
|
+
import_ui.Button,
|
|
1467
|
+
{
|
|
1468
|
+
key: node.id,
|
|
1469
|
+
...pressProps(node, deliver)
|
|
1470
|
+
},
|
|
1471
|
+
...(node.c ?? []).map((child) => renderNode(child, deliver, cache))
|
|
1472
|
+
);
|
|
1473
|
+
}
|
|
1474
|
+
const component = NODE_COMPONENTS[node.t];
|
|
1475
|
+
if (!component) throw new Error(`swift view ${node.t} has no rnx kit component`);
|
|
1476
|
+
const modifiers = nodeModifiers(node);
|
|
1477
|
+
const children = node.t === "ConfirmationDialog" ? dialogChildren(node, deliver) : node.c?.map((child) => renderNode(child, deliver));
|
|
1478
|
+
return (0, import_react.createElement)(
|
|
1479
|
+
component,
|
|
1480
|
+
{
|
|
1481
|
+
key: node.id,
|
|
1482
|
+
...modifiers === void 0 ? {} : { modifiers },
|
|
1483
|
+
...nodeProps(node, deliver)
|
|
1484
|
+
},
|
|
1485
|
+
...children ?? []
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
function SwiftTree({
|
|
1489
|
+
tree,
|
|
1490
|
+
deliver,
|
|
1491
|
+
cache,
|
|
1492
|
+
resources
|
|
1493
|
+
}) {
|
|
1494
|
+
return (
|
|
1495
|
+
// a navigation stack at the root lays its own bar out under the status
|
|
1496
|
+
// bar and insets each screen itself, so the host must not also pad it
|
|
1497
|
+
// down: that pad would move the whole stack a status bar lower
|
|
1498
|
+
// a swiftui scene is opaque: the window behind every screen is
|
|
1499
|
+
// systemBackground, and lists paint their grouped fill over it (the kit's
|
|
1500
|
+
// grouped container already does). without this a listless screen shows
|
|
1501
|
+
// whatever sits beneath the mount. RAN on the safeArea probe (iphone 17
|
|
1502
|
+
// pro): (600,1300) reads #ffffff ios against #f2f2f7 rnx, 99.92% of the
|
|
1503
|
+
// frame; dark matches on both legs (the oracle's falsifier: the two
|
|
1504
|
+
// fills coincide there). PlatformColor is this lane's spelling for a
|
|
1505
|
+
// semantic color.
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1507
|
+
import_ui.Host,
|
|
1508
|
+
{
|
|
1509
|
+
style: { flex: 1, backgroundColor: (0, import_react_native.PlatformColor)("systemBackground") },
|
|
1510
|
+
ignoreSafeArea: tree.some(
|
|
1511
|
+
(node) => node.t === "NavigationStack" || node.t === "NavigationSplitView"
|
|
1512
|
+
),
|
|
1513
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationIndependentTree, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: tree.map((node) => renderNode(node, deliver, cache)) }) }) })
|
|
1514
|
+
}
|
|
1515
|
+
)
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
var ROOT_KEY = "__rnx_swift_roots__";
|
|
1519
|
+
function rootRegistry() {
|
|
1520
|
+
const existing = Reflect.get(globalThis, ROOT_KEY);
|
|
1521
|
+
if (existing instanceof Map) return existing;
|
|
1522
|
+
const created = /* @__PURE__ */ new Map();
|
|
1523
|
+
Reflect.set(globalThis, ROOT_KEY, created);
|
|
1524
|
+
return created;
|
|
1525
|
+
}
|
|
1526
|
+
function slotFor(rootId, mountTree) {
|
|
1527
|
+
const registry = rootRegistry();
|
|
1528
|
+
const existing = registry.get(rootId);
|
|
1529
|
+
if (existing) return existing;
|
|
1530
|
+
const created = { root: createRoot(mountTree) };
|
|
1531
|
+
registry.set(rootId, created);
|
|
1532
|
+
return created;
|
|
1533
|
+
}
|
|
1534
|
+
function createRoot(mountTree) {
|
|
1535
|
+
let instance = null;
|
|
1536
|
+
let source = null;
|
|
1537
|
+
let refresh;
|
|
1538
|
+
let state = { tree: null, isView: false, error: null };
|
|
1539
|
+
let swap = Promise.resolve();
|
|
1540
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1541
|
+
const cache = { entries: /* @__PURE__ */ new Map() };
|
|
1542
|
+
const publish = (next) => {
|
|
1543
|
+
state = next;
|
|
1544
|
+
for (const listener of listeners) listener();
|
|
1545
|
+
};
|
|
1546
|
+
const apply = async (options, props) => {
|
|
1547
|
+
const carried = instance?.exportState() ?? null;
|
|
1548
|
+
const created = instantiate(
|
|
1549
|
+
await compile(options.url),
|
|
1550
|
+
decodeBundle(options.url, options.bundleFiles)
|
|
1551
|
+
);
|
|
1552
|
+
if (carried !== null) created.importState(carried);
|
|
1553
|
+
if (source !== options) return;
|
|
1554
|
+
instance = created;
|
|
1555
|
+
const mounted = mountTree(created, props);
|
|
1556
|
+
publish({ tree: mounted.tree, isView: mounted.isView, error: null });
|
|
1557
|
+
};
|
|
1558
|
+
const component = function SwiftRoot() {
|
|
1559
|
+
const rendered = (0, import_react.useSyncExternalStore)(
|
|
1560
|
+
(listener) => {
|
|
1561
|
+
listeners.add(listener);
|
|
1562
|
+
return () => listeners.delete(listener);
|
|
1563
|
+
},
|
|
1564
|
+
() => state
|
|
1565
|
+
);
|
|
1566
|
+
if (rendered.error) throw rendered.error;
|
|
1567
|
+
if (!rendered.tree) return null;
|
|
1568
|
+
const deliver = (handlerId2, payload) => {
|
|
1569
|
+
if (!instance) throw new Error("swift app received an event before it mounted");
|
|
1570
|
+
publish({
|
|
1571
|
+
tree: instance.deliver(handlerId2, payload),
|
|
1572
|
+
isView: rendered.isView,
|
|
1573
|
+
error: null
|
|
1574
|
+
});
|
|
1575
|
+
};
|
|
1576
|
+
const resources = source?.resources;
|
|
1577
|
+
if (rendered.isView)
|
|
1578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: rendered.tree.map((node) => renderNode(node, deliver, cache)) }) });
|
|
1579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1580
|
+
SwiftTree,
|
|
1581
|
+
{
|
|
1582
|
+
tree: rendered.tree,
|
|
1583
|
+
deliver,
|
|
1584
|
+
cache,
|
|
1585
|
+
resources
|
|
1586
|
+
}
|
|
1587
|
+
);
|
|
1588
|
+
};
|
|
1589
|
+
return {
|
|
1590
|
+
component,
|
|
1591
|
+
use(options, refreshKey, props) {
|
|
1592
|
+
const changed = source === null || source.hash !== options.hash || source.url !== options.url || JSON.stringify(source.resources ?? null) !== JSON.stringify(options.resources ?? null) || JSON.stringify(source.bundleFiles ?? null) !== JSON.stringify(options.bundleFiles ?? null) || refreshKey !== void 0 && refreshKey !== refresh;
|
|
1593
|
+
if (changed) {
|
|
1594
|
+
source = options;
|
|
1595
|
+
refresh = refreshKey;
|
|
1596
|
+
const next = props ?? {};
|
|
1597
|
+
swap = swap.then(
|
|
1598
|
+
() => apply(options, next),
|
|
1599
|
+
() => apply(options, next)
|
|
1600
|
+
);
|
|
1601
|
+
swap.catch((error) => {
|
|
1602
|
+
publish({
|
|
1603
|
+
tree: null,
|
|
1604
|
+
isView: false,
|
|
1605
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
1606
|
+
});
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
return component;
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
function propsSignature(props) {
|
|
1614
|
+
try {
|
|
1615
|
+
return JSON.stringify(props, (_key, value) => {
|
|
1616
|
+
if (typeof value === "function" || typeof value === "symbol" || typeof value === "bigint") {
|
|
1617
|
+
throw new Error(`swift view props must be json; found ${typeof value}`);
|
|
1618
|
+
}
|
|
1619
|
+
return value;
|
|
1620
|
+
}) ?? "null";
|
|
1621
|
+
} catch (error) {
|
|
1622
|
+
if (error instanceof Error && error.message.startsWith("swift view props"))
|
|
1623
|
+
throw error;
|
|
1624
|
+
throw new Error(
|
|
1625
|
+
`swift view props must be json: ${error instanceof Error ? error.message : String(error)}`
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
function createSwiftEntry(options) {
|
|
1630
|
+
const rootId = options.rootId ?? "root";
|
|
1631
|
+
const slot = slotFor(
|
|
1632
|
+
rootId,
|
|
1633
|
+
(instance, props) => instance.hasView() ? { tree: instance.mountView(props), isView: true } : { tree: instance.mount(), isView: false }
|
|
1634
|
+
);
|
|
1635
|
+
return function SwiftEntry(props) {
|
|
1636
|
+
if (props.children !== void 0) {
|
|
1637
|
+
throw new Error("swift entries take data props, not children");
|
|
1638
|
+
}
|
|
1639
|
+
const component = slot.root.use(options, propsSignature(props), props);
|
|
1640
|
+
return (0, import_react.createElement)(component);
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1644
|
+
0 && (module.exports = {
|
|
1645
|
+
createSwiftEntry
|
|
1646
|
+
});
|