@nodetool-ai/game-renderer 0.8.6 → 0.8.8

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.
Files changed (80) hide show
  1. package/dist/.nodetool-build-stamp +1 -1
  2. package/dist/build-expo.d.ts +76 -0
  3. package/dist/build-expo.d.ts.map +1 -0
  4. package/dist/build-expo.js +454 -0
  5. package/dist/build-expo.js.map +1 -0
  6. package/dist/build-tauri.d.ts +7 -0
  7. package/dist/build-tauri.d.ts.map +1 -1
  8. package/dist/build-tauri.js +2 -1
  9. package/dist/build-tauri.js.map +1 -1
  10. package/dist/build3d.d.ts.map +1 -1
  11. package/dist/build3d.js +3 -2
  12. package/dist/build3d.js.map +1 -1
  13. package/dist/frame-budget.d.ts +16 -0
  14. package/dist/frame-budget.d.ts.map +1 -1
  15. package/dist/frame-budget.js +19 -1
  16. package/dist/frame-budget.js.map +1 -1
  17. package/dist/game3d-capture-page.js +223 -223
  18. package/dist/game3d-player.js +346 -322
  19. package/dist/particles/curves.d.ts.map +1 -1
  20. package/dist/particles/curves.js +38 -14
  21. package/dist/particles/curves.js.map +1 -1
  22. package/dist/particles/index.d.ts +1 -1
  23. package/dist/particles/index.d.ts.map +1 -1
  24. package/dist/particles/index.js +1 -1
  25. package/dist/particles/index.js.map +1 -1
  26. package/dist/particles/particles3d.d.ts +35 -0
  27. package/dist/particles/particles3d.d.ts.map +1 -1
  28. package/dist/particles/particles3d.js +99 -2
  29. package/dist/particles/particles3d.js.map +1 -1
  30. package/dist/particles/pass3d.d.ts +9 -2
  31. package/dist/particles/pass3d.d.ts.map +1 -1
  32. package/dist/particles/pass3d.js +40 -7
  33. package/dist/particles/pass3d.js.map +1 -1
  34. package/dist/perf.d.ts +102 -0
  35. package/dist/perf.d.ts.map +1 -0
  36. package/dist/perf.js +238 -0
  37. package/dist/perf.js.map +1 -0
  38. package/dist/player-v1.js +445 -401
  39. package/dist/renderer3d/assets/cache.d.ts +3 -1
  40. package/dist/renderer3d/assets/cache.d.ts.map +1 -1
  41. package/dist/renderer3d/assets/cache.js +25 -1
  42. package/dist/renderer3d/assets/cache.js.map +1 -1
  43. package/dist/renderer3d/environment/index.d.ts +4 -0
  44. package/dist/renderer3d/environment/index.d.ts.map +1 -1
  45. package/dist/renderer3d/environment/index.js +30 -2
  46. package/dist/renderer3d/environment/index.js.map +1 -1
  47. package/dist/renderer3d/hud/paint.d.ts.map +1 -1
  48. package/dist/renderer3d/hud/paint.js +15 -0
  49. package/dist/renderer3d/hud/paint.js.map +1 -1
  50. package/dist/renderer3d/index.d.ts +7 -1
  51. package/dist/renderer3d/index.d.ts.map +1 -1
  52. package/dist/renderer3d/index.js +19 -8
  53. package/dist/renderer3d/index.js.map +1 -1
  54. package/dist/renderer3d/scene-sync.d.ts.map +1 -1
  55. package/dist/renderer3d/scene-sync.js +42 -18
  56. package/dist/renderer3d/scene-sync.js.map +1 -1
  57. package/dist/renderer3d/shadows/cascades.d.ts +25 -2
  58. package/dist/renderer3d/shadows/cascades.d.ts.map +1 -1
  59. package/dist/renderer3d/shadows/cascades.js +67 -11
  60. package/dist/renderer3d/shadows/cascades.js.map +1 -1
  61. package/dist/renderer3d/types.d.ts +7 -1
  62. package/dist/renderer3d/types.d.ts.map +1 -1
  63. package/dist/smoke.d.ts.map +1 -1
  64. package/dist/smoke.js +7 -45
  65. package/dist/smoke.js.map +1 -1
  66. package/dist/standalone-player.js +4 -2
  67. package/dist/standalone-player.js.map +1 -1
  68. package/dist/standalone-player3d.d.ts +13 -0
  69. package/dist/standalone-player3d.d.ts.map +1 -1
  70. package/dist/standalone-player3d.js +25 -8
  71. package/dist/standalone-player3d.js.map +1 -1
  72. package/dist/static-server.d.ts +10 -0
  73. package/dist/static-server.d.ts.map +1 -0
  74. package/dist/static-server.js +52 -0
  75. package/dist/static-server.js.map +1 -0
  76. package/dist/ui/controller.d.ts +2 -0
  77. package/dist/ui/controller.d.ts.map +1 -1
  78. package/dist/ui/controller.js +13 -0
  79. package/dist/ui/controller.js.map +1 -1
  80. package/package.json +15 -5
@@ -1 +1 @@
1
- 2026-10-18T07:13:51.543Z
1
+ 2026-10-25T16:17:41.903Z
@@ -0,0 +1,76 @@
1
+ import type { AnyGameDocument } from "@nodetool-ai/protocol";
2
+ import type { StandaloneAsset } from "./build.js";
3
+ /**
4
+ * Package versions the generated project pins. They are the versions Expo SDK 56 lists in its
5
+ * `bundledNativeModules.json`, which Expo Go and `npx expo install --check` expect. Bump them together.
6
+ */
7
+ export declare const EXPO_VERSIONS: {
8
+ readonly expo: "~56.0.23";
9
+ readonly expoAsset: "~56.0.25";
10
+ readonly expoFileSystem: "~56.0.11";
11
+ readonly expoKeepAwake: "~56.0.3";
12
+ readonly expoStatusBar: "~56.0.4";
13
+ readonly react: "19.2.3";
14
+ readonly reactNative: "0.85.3";
15
+ readonly webView: "13.16.1";
16
+ };
17
+ /** The page's origin inside the app. `.invalid` never resolves, and the page answers its own file requests. */
18
+ export declare const EXPO_GAME_BASE_URL = "https://game.invalid/";
19
+ /** Path of the single-page game inside the generated project. */
20
+ export declare const EXPO_GAME_HTML = "assets/game/game.html";
21
+ /** Bytes of game files one page may carry. Phones hold the whole page, base64 encoded, in memory. */
22
+ export declare const MAX_EXPO_GAME_BYTES: number;
23
+ export type ExpoOrientation = "default" | "portrait" | "landscape";
24
+ export interface ExpoAppOptions {
25
+ /** Home screen name. Defaults to "NodeTool Game". */
26
+ readonly name?: string;
27
+ /** iOS bundle identifier and Android package. Defaults to `ai.nodetool.game.<name>`. */
28
+ readonly identifier?: string;
29
+ /** Semantic version `MAJOR.MINOR.PATCH`. */
30
+ readonly version?: string;
31
+ /** Screen orientation lock. A 3D game defaults to its presentation shape, a 2D game to `default` (follows the device). */
32
+ readonly orientation?: ExpoOrientation;
33
+ /** PNG, JPEG or WebP bytes for the app icon. A generated icon is used when absent. */
34
+ readonly icon?: Uint8Array;
35
+ }
36
+ export interface BuildExpoGameOptions {
37
+ readonly document: AnyGameDocument;
38
+ readonly outputDir: string;
39
+ readonly resolveAsset: (sourceAssetId: string, signal?: AbortSignal) => Promise<StandaloneAsset | null>;
40
+ readonly app?: ExpoAppOptions;
41
+ readonly signal?: AbortSignal;
42
+ }
43
+ export interface ExpoAppMetadata {
44
+ readonly name: string;
45
+ /** Expo project slug and npm package name. */
46
+ readonly slug: string;
47
+ readonly identifier: string;
48
+ readonly version: string;
49
+ readonly orientation: ExpoOrientation;
50
+ readonly sourceRevision: string;
51
+ readonly dimension: "2d" | "3d";
52
+ }
53
+ export interface ExpoGameProject {
54
+ readonly outputDir: string;
55
+ /** The game as one self-contained HTML page. */
56
+ readonly htmlPath: string;
57
+ readonly metadata: ExpoAppMetadata;
58
+ }
59
+ /** Resolves and validates the name, identifiers, version and orientation of an exported mobile app. */
60
+ export declare function expoAppMetadata(document: AnyGameDocument, app?: ExpoAppOptions): ExpoAppMetadata;
61
+ /**
62
+ * Turns a standalone web build into one HTML page: the stylesheet and player module inline, every other file
63
+ * base64 encoded in a data block, and a script that serves the player's `fetch` of those files from the block.
64
+ * The page then runs from any origin, including a WebView's `loadHTMLString`/`loadDataWithBaseURL`, with no
65
+ * network or file access. Inline code is allowed by hash, so the policy stays as strict as the web build's.
66
+ */
67
+ export declare function inlineStandaloneGame(webDir: string, signal?: AbortSignal): Promise<string>;
68
+ /** `assets/icon.png` and the Android adaptive icon foreground, keyed by path in the project. */
69
+ export declare function expoIconFiles(source?: Uint8Array): Promise<Record<string, Uint8Array>>;
70
+ /** The text files of the Expo project, keyed by path relative to the project root. */
71
+ export declare function expoProjectFiles(metadata: ExpoAppMetadata): Record<string, string>;
72
+ /** Includes the web runtime, page template, project templates and generated icons in cache identity. */
73
+ export declare function expoGameRuntimeFingerprint(document: AnyGameDocument, app?: ExpoAppOptions): Promise<string>;
74
+ /** Exports a game as an Expo project: the standalone web player as one offline page, shown full screen in a WebView. */
75
+ export declare function buildExpoGameProject(options: BuildExpoGameOptions): Promise<ExpoGameProject>;
76
+ //# sourceMappingURL=build-expo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-expo.d.ts","sourceRoot":"","sources":["../src/build-expo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,454 @@
1
+ import { createHash } from "node:crypto";
2
+ import { mkdir, mkdtemp, readFile, readdir, rename, rm, rmdir, writeFile } from "node:fs/promises";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { createCanvas, loadImage } from "@napi-rs/canvas";
5
+ import { gameBuildFingerprint } from "./build-fingerprint.js";
6
+ import { renderIcons } from "./build-tauri.js";
7
+ /**
8
+ * Package versions the generated project pins. They are the versions Expo SDK 56 lists in its
9
+ * `bundledNativeModules.json`, which Expo Go and `npx expo install --check` expect. Bump them together.
10
+ */
11
+ export const EXPO_VERSIONS = {
12
+ expo: "~56.0.23",
13
+ expoAsset: "~56.0.25",
14
+ expoFileSystem: "~56.0.11",
15
+ expoKeepAwake: "~56.0.3",
16
+ expoStatusBar: "~56.0.4",
17
+ react: "19.2.3",
18
+ reactNative: "0.85.3",
19
+ webView: "13.16.1"
20
+ };
21
+ /** The page's origin inside the app. `.invalid` never resolves, and the page answers its own file requests. */
22
+ export const EXPO_GAME_BASE_URL = "https://game.invalid/";
23
+ /** Path of the single-page game inside the generated project. */
24
+ export const EXPO_GAME_HTML = "assets/game/game.html";
25
+ /** Bytes of game files one page may carry. Phones hold the whole page, base64 encoded, in memory. */
26
+ export const MAX_EXPO_GAME_BYTES = 128 * 1024 * 1024;
27
+ const DEFAULT_NAME = "NodeTool Game";
28
+ const DEFAULT_VERSION = "1.0.0";
29
+ const ICON_SIZE = 1024;
30
+ // Android masks an adaptive icon's foreground to the middle two thirds of the layer.
31
+ const ADAPTIVE_ICON_SCALE = 0.66;
32
+ // Android package segments must not be Java keywords or literals.
33
+ const JAVA_RESERVED = new Set(["abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const",
34
+ "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if",
35
+ "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected",
36
+ "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient",
37
+ "true", "try", "void", "volatile", "while"]);
38
+ function slug(value) {
39
+ return value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48).replace(/-+$/, "");
40
+ }
41
+ function appName(value) {
42
+ const cleaned = Array.from(value ?? "", (char) => {
43
+ const code = char.charCodeAt(0);
44
+ return code < 32 || code === 127 ? " " : char;
45
+ }).join("").replace(/\s+/g, " ").trim().slice(0, 64).trim();
46
+ return cleaned || DEFAULT_NAME;
47
+ }
48
+ function validIdentifier(identifier) {
49
+ // iOS bundle identifiers allow hyphens but not underscores, Android packages the reverse; both accept this subset.
50
+ const segments = identifier.split(".");
51
+ return identifier.length <= 128 && segments.length >= 2 &&
52
+ segments.every((segment) => /^[A-Za-z][A-Za-z0-9]*$/.test(segment) && !JAVA_RESERVED.has(segment));
53
+ }
54
+ /** Resolves and validates the name, identifiers, version and orientation of an exported mobile app. */
55
+ export function expoAppMetadata(document, app = {}) {
56
+ const name = appName(app.name);
57
+ const nameSlug = slug(name) || "game";
58
+ const projectSlug = /^[a-z]/.test(nameSlug) ? nameSlug : `game-${nameSlug}`;
59
+ const segment = projectSlug.replace(/-/g, "");
60
+ const identifier = app.identifier ?? `ai.nodetool.game.${JAVA_RESERVED.has(segment) ? `game${segment}` : segment}`;
61
+ if (!validIdentifier(identifier)) {
62
+ throw new Error("App identifier must be reverse-DNS with segments of letters and digits that start with a letter, such as com.example.mygame");
63
+ }
64
+ const version = app.version ?? DEFAULT_VERSION;
65
+ if (!/^(0|[1-9]\d{0,3})\.(0|[1-9]\d{0,3})\.(0|[1-9]\d{0,3})$/.test(version)) {
66
+ throw new Error("App version must be MAJOR.MINOR.PATCH with each part from 0 to 9999");
67
+ }
68
+ const orientation = app.orientation ?? (document.schemaVersion === 3
69
+ ? document.presentation.aspectRatio >= 1 ? "landscape" : "portrait"
70
+ : "default");
71
+ if (orientation !== "default" && orientation !== "portrait" && orientation !== "landscape") {
72
+ throw new Error("App orientation must be default, portrait or landscape");
73
+ }
74
+ return { name, slug: projectSlug, identifier, version, orientation, sourceRevision: document.revision,
75
+ dimension: document.schemaVersion === 3 ? "3d" : "2d" };
76
+ }
77
+ const CONTENT_TYPES = {
78
+ json: "application/json", wasm: "application/wasm", png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", webp: "image/webp",
79
+ wav: "audio/wav", ogg: "audio/ogg", mp3: "audio/mpeg", ttf: "font/ttf", otf: "font/otf", glb: "model/gltf-binary",
80
+ js: "text/javascript", css: "text/css"
81
+ };
82
+ /**
83
+ * Answers the player's `fetch` of its own files from the bytes embedded in the page, so the page needs no server
84
+ * and no file access. Any other request goes to the browser's `fetch`, which the page's policy limits to `blob:`.
85
+ */
86
+ const FILE_SHIM = `(() => {
87
+ const element = document.getElementById("nodetool-game-files");
88
+ const files = JSON.parse(element.textContent);
89
+ element.remove();
90
+ const types = ${JSON.stringify(CONTENT_TYPES)};
91
+ const base = new URL(".", document.baseURI).href;
92
+ const browserFetch = window.fetch.bind(window);
93
+ const decode = (text) => {
94
+ if (typeof Uint8Array.fromBase64 === "function") { return Uint8Array.fromBase64(text); }
95
+ const binary = atob(text);
96
+ const bytes = new Uint8Array(binary.length);
97
+ for (let index = 0; index < binary.length; index += 1) { bytes[index] = binary.charCodeAt(index); }
98
+ return bytes;
99
+ };
100
+ window.fetch = function (input, init) {
101
+ let url;
102
+ try { url = new URL(input instanceof Request ? input.url : String(input), document.baseURI); }
103
+ catch { return browserFetch(input, init); }
104
+ url.search = "";
105
+ url.hash = "";
106
+ if (!url.href.startsWith(base)) { return browserFetch(input, init); }
107
+ const signal = init && init.signal;
108
+ if (signal && signal.aborted) { return Promise.reject(signal.reason); }
109
+ const path = decodeURIComponent(url.href.slice(base.length));
110
+ if (!Object.prototype.hasOwnProperty.call(files, path)) {
111
+ return Promise.resolve(new Response("Not found", { status: 404, headers: { "content-type": "text/plain" } }));
112
+ }
113
+ const extension = path.slice(path.lastIndexOf(".") + 1).toLowerCase();
114
+ return Promise.resolve(new Response(decode(files[path]), {
115
+ status: 200, headers: { "content-type": types[extension] || "application/octet-stream" }
116
+ }));
117
+ };
118
+ })();`;
119
+ function cspHash(text) {
120
+ return `'sha256-${createHash("sha256").update(text, "utf8").digest("base64")}'`;
121
+ }
122
+ /** Keeps inline script text from ending its element or starting an HTML comment. `\x3C` is "<" in strings and patterns. */
123
+ function escapeScript(text) {
124
+ return text.replace(/<(?=\/script|!--)/gi, "\\x3C");
125
+ }
126
+ function replaceOnce(html, pattern, replacement, label) {
127
+ const matches = html.match(new RegExp(pattern.source, `${pattern.flags.replace("g", "")}g`));
128
+ if (matches?.length !== 1) {
129
+ throw new Error(`Web build has no single ${label} to inline`);
130
+ }
131
+ return html.replace(pattern, () => replacement);
132
+ }
133
+ async function listFiles(root, directory = "") {
134
+ const paths = [];
135
+ for (const entry of await readdir(join(root, directory), { withFileTypes: true })) {
136
+ const path = directory ? `${directory}/${entry.name}` : entry.name;
137
+ if (entry.isDirectory()) {
138
+ paths.push(...await listFiles(root, path));
139
+ }
140
+ else if (entry.isFile()) {
141
+ paths.push(path);
142
+ }
143
+ }
144
+ return paths.sort();
145
+ }
146
+ /**
147
+ * Turns a standalone web build into one HTML page: the stylesheet and player module inline, every other file
148
+ * base64 encoded in a data block, and a script that serves the player's `fetch` of those files from the block.
149
+ * The page then runs from any origin, including a WebView's `loadHTMLString`/`loadDataWithBaseURL`, with no
150
+ * network or file access. Inline code is allowed by hash, so the policy stays as strict as the web build's.
151
+ */
152
+ export async function inlineStandaloneGame(webDir, signal) {
153
+ let html = await readFile(join(webDir, "index.html"), "utf8");
154
+ const stylesheet = /<link rel="stylesheet" href="\.\/([A-Za-z0-9._-]+)">/.exec(html)?.[1];
155
+ const module = /<script type="module" src="\.\/([A-Za-z0-9._-]+)"><\/script>/.exec(html)?.[1];
156
+ if (!stylesheet || !module) {
157
+ throw new Error("Web build has no stylesheet or player module to inline");
158
+ }
159
+ const css = await readFile(join(webDir, stylesheet), "utf8");
160
+ if (/<\/style/i.test(css)) {
161
+ throw new Error("Web build stylesheet cannot be inlined");
162
+ }
163
+ const player = escapeScript(await readFile(join(webDir, module), "utf8"));
164
+ const files = {};
165
+ let totalBytes = 0;
166
+ for (const path of await listFiles(webDir)) {
167
+ signal?.throwIfAborted();
168
+ if (path === "index.html" || path === stylesheet || path === module) {
169
+ continue;
170
+ }
171
+ const bytes = await readFile(join(webDir, path));
172
+ totalBytes += bytes.byteLength;
173
+ if (totalBytes > MAX_EXPO_GAME_BYTES) {
174
+ throw new Error(`A mobile app build supports at most ${MAX_EXPO_GAME_BYTES} bytes of game files`);
175
+ }
176
+ files[path] = bytes.toString("base64");
177
+ }
178
+ const policy = ["default-src 'none'", `script-src ${cspHash(FILE_SHIM)} ${cspHash(player)} 'wasm-unsafe-eval'`, `style-src ${cspHash(css)}`,
179
+ "img-src blob: data:", "media-src blob:", "font-src blob: data:", "connect-src blob:", "base-uri 'none'", "form-action 'none'",
180
+ "object-src 'none'"].join("; ");
181
+ html = replaceOnce(html, /<meta http-equiv="Content-Security-Policy" content="[^"]*">/, `<meta http-equiv="Content-Security-Policy" content="${policy}">`, "security policy");
182
+ html = replaceOnce(html, /<link rel="stylesheet" href="[^"]*">/, `<style>${css}</style>`, "stylesheet");
183
+ html = replaceOnce(html, /<script type="module" src="[^"]*"><\/script>/, `<script type="module">${player}</script>`, "player module");
184
+ // JSON of base64 strings and plain paths holds no "<", so the data block cannot close early.
185
+ const data = JSON.stringify(files);
186
+ if (data.includes("<")) {
187
+ throw new Error("Web build file names must not contain <");
188
+ }
189
+ html = replaceOnce(html, /<meta charset="utf-8">/, `<meta charset="utf-8">\n<script type="application/json" id="nodetool-game-files">${data}</script>\n<script>${FILE_SHIM}</script>`, "charset");
190
+ return html;
191
+ }
192
+ /** `assets/icon.png` and the Android adaptive icon foreground, keyed by path in the project. */
193
+ export async function expoIconFiles(source) {
194
+ const icon = (await renderIcons([ICON_SIZE], source)).get(ICON_SIZE);
195
+ if (!icon) {
196
+ throw new Error(`Icon size ${ICON_SIZE} was not rendered`);
197
+ }
198
+ const canvas = createCanvas(ICON_SIZE, ICON_SIZE);
199
+ const inset = Math.round(ICON_SIZE * ADAPTIVE_ICON_SCALE);
200
+ const offset = Math.round((ICON_SIZE - inset) / 2);
201
+ canvas.getContext("2d").drawImage(await loadImage(Buffer.from(icon.png)), offset, offset, inset, inset);
202
+ return { "assets/icon.png": icon.png, "assets/adaptive-icon.png": new Uint8Array(await canvas.encode("png")) };
203
+ }
204
+ const APP_SOURCE = `import { useCallback, useEffect, useRef, useState } from "react";
205
+ import { ActivityIndicator, AppState, StyleSheet, Text, View } from "react-native";
206
+ import { StatusBar } from "expo-status-bar";
207
+ import { Asset } from "expo-asset";
208
+ import { File } from "expo-file-system";
209
+ import { useKeepAwake } from "expo-keep-awake";
210
+ import { WebView } from "react-native-webview";
211
+
212
+ // The page carries every game file and answers its own requests, so nothing is fetched from this origin.
213
+ // It gives the page a secure https origin for crypto, WebAssembly and saved games.
214
+ const BASE_URL = "${EXPO_GAME_BASE_URL}";
215
+ const GAME_PAGE = require("./${EXPO_GAME_HTML}");
216
+
217
+ const PAUSE_SCRIPT = \`(function () {
218
+ try { if (window.nativeGamePlayer) { window.nativeGamePlayer.pause(); } } catch (error) { /* not started */ }
219
+ window.dispatchEvent(new Event("blur"));
220
+ })();
221
+ true;\`;
222
+
223
+ function allowedUrl(url) {
224
+ return url === BASE_URL || url.startsWith("about:") || url.startsWith("blob:") || url.startsWith("data:");
225
+ }
226
+
227
+ export default function App() {
228
+ useKeepAwake();
229
+ const webView = useRef(null);
230
+ const [html, setHtml] = useState(null);
231
+ const [error, setError] = useState(null);
232
+ const [session, setSession] = useState(0);
233
+
234
+ useEffect(() => {
235
+ let active = true;
236
+ Asset.fromModule(GAME_PAGE).downloadAsync()
237
+ .then((asset) => new File(asset.localUri).text())
238
+ .then((text) => { if (active) { setHtml(text); } })
239
+ .catch((cause) => { if (active) { setError(String(cause && cause.message ? cause.message : cause)); } });
240
+ return () => { active = false; };
241
+ }, []);
242
+
243
+ // Leaving the app pauses the game and its audio. The player stays paused until the player taps Resume.
244
+ useEffect(() => {
245
+ const subscription = AppState.addEventListener("change", (state) => {
246
+ if (state !== "active") { webView.current?.injectJavaScript(PAUSE_SCRIPT); }
247
+ });
248
+ return () => subscription.remove();
249
+ }, []);
250
+
251
+ // The operating system can end the page's process to reclaim memory. Start the game again.
252
+ const restart = useCallback(() => setSession((value) => value + 1), []);
253
+
254
+ if (error) {
255
+ return <View style={styles.center}><Text style={styles.text}>The game could not load: {error}</Text></View>;
256
+ }
257
+ if (html === null) {
258
+ return <View style={styles.center}><StatusBar hidden /><ActivityIndicator color="#ffffff" /></View>;
259
+ }
260
+ return (
261
+ <View style={styles.root}>
262
+ <StatusBar hidden />
263
+ <WebView
264
+ key={session}
265
+ ref={webView}
266
+ style={styles.root}
267
+ source={{ html, baseUrl: BASE_URL }}
268
+ originWhitelist={["*"]}
269
+ onShouldStartLoadWithRequest={(request) => allowedUrl(request.url)}
270
+ setSupportMultipleWindows={false}
271
+ javaScriptEnabled
272
+ domStorageEnabled
273
+ allowFileAccess={false}
274
+ allowFileAccessFromFileURLs={false}
275
+ allowUniversalAccessFromFileURLs={false}
276
+ allowsBackForwardNavigationGestures={false}
277
+ allowsLinkPreview={false}
278
+ allowsInlineMediaPlayback
279
+ mediaPlaybackRequiresUserAction={false}
280
+ bounces={false}
281
+ scrollEnabled={false}
282
+ overScrollMode="never"
283
+ contentInsetAdjustmentBehavior="never"
284
+ textInteractionEnabled={false}
285
+ webviewDebuggingEnabled={__DEV__}
286
+ onContentProcessDidTerminate={restart}
287
+ onRenderProcessGone={restart}
288
+ />
289
+ </View>
290
+ );
291
+ }
292
+
293
+ const styles = StyleSheet.create({
294
+ root: { flex: 1, backgroundColor: "#000000" },
295
+ center: { flex: 1, alignItems: "center", justifyContent: "center", padding: 24, backgroundColor: "#000000" },
296
+ text: { color: "#ffffff", textAlign: "center" }
297
+ });
298
+ `;
299
+ /** The text files of the Expo project, keyed by path relative to the project root. */
300
+ export function expoProjectFiles(metadata) {
301
+ const appJson = {
302
+ expo: {
303
+ name: metadata.name,
304
+ slug: metadata.slug,
305
+ version: metadata.version,
306
+ orientation: metadata.orientation,
307
+ icon: "./assets/icon.png",
308
+ userInterfaceStyle: "dark",
309
+ backgroundColor: "#000000",
310
+ platforms: ["ios", "android"],
311
+ ios: { bundleIdentifier: metadata.identifier, supportsTablet: true, requireFullScreen: true },
312
+ android: {
313
+ package: metadata.identifier,
314
+ adaptiveIcon: { foregroundImage: "./assets/adaptive-icon.png", backgroundColor: "#000000" }
315
+ }
316
+ }
317
+ };
318
+ const packageJson = {
319
+ name: metadata.slug,
320
+ version: metadata.version,
321
+ private: true,
322
+ main: "index.js",
323
+ scripts: { start: "expo start", android: "expo start --android", ios: "expo start --ios" },
324
+ dependencies: {
325
+ expo: EXPO_VERSIONS.expo,
326
+ "expo-asset": EXPO_VERSIONS.expoAsset,
327
+ "expo-file-system": EXPO_VERSIONS.expoFileSystem,
328
+ "expo-keep-awake": EXPO_VERSIONS.expoKeepAwake,
329
+ "expo-status-bar": EXPO_VERSIONS.expoStatusBar,
330
+ react: EXPO_VERSIONS.react,
331
+ "react-native": EXPO_VERSIONS.reactNative,
332
+ "react-native-webview": EXPO_VERSIONS.webView
333
+ }
334
+ };
335
+ const eas = {
336
+ build: {
337
+ preview: { distribution: "internal", android: { buildType: "apk" } },
338
+ production: {}
339
+ }
340
+ };
341
+ const metro = `const { getDefaultConfig } = require("expo/metro-config");
342
+
343
+ const config = getDefaultConfig(__dirname);
344
+ // The game ships as one HTML page that the app reads from its bundled assets.
345
+ config.resolver.assetExts.push("html");
346
+
347
+ module.exports = config;
348
+ `;
349
+ const index = `import { registerRootComponent } from "expo";
350
+ import App from "./App";
351
+
352
+ registerRootComponent(App);
353
+ `;
354
+ const readme = `# ${metadata.name}
355
+
356
+ A mobile build of a NodeTool ${metadata.dimension.toUpperCase()} game (revision \`${metadata.sourceRevision}\`) for iOS and Android, made with [Expo](https://expo.dev) SDK 56.
357
+
358
+ \`${EXPO_GAME_HTML}\` is the whole game as one page: the web player, the game document, the script runtime and every asset. \`App.js\` shows that page full screen in a [WebView](https://github.com/react-native-webview/react-native-webview). The game runs offline. It needs no NodeTool server.
359
+
360
+ ## Try it on a phone
361
+
362
+ \`\`\`sh
363
+ npm install
364
+ npx expo start
365
+ \`\`\`
366
+
367
+ Scan the QR code with the Expo Go app (Android) or the Camera app (iOS).
368
+
369
+ ## Build installable apps
370
+
371
+ Builds run on Expo's EAS service. Create a free Expo account first, then:
372
+
373
+ \`\`\`sh
374
+ npm install -g eas-cli
375
+ eas build --platform android --profile preview # an .apk you can install directly
376
+ eas build --platform ios # needs an Apple Developer account
377
+ \`\`\`
378
+
379
+ To build on your own computer instead, run \`npx expo run:android\` (Android Studio) or \`npx expo run:ios\` (Xcode on macOS).
380
+
381
+ ## Change the app
382
+
383
+ The name, version, orientation (\`${metadata.orientation}\`) and app identifier (\`${metadata.identifier}\`) are in \`app.json\`. Replace \`assets/icon.png\` and \`assets/adaptive-icon.png\` to change the icon, or export again from NodeTool with a new icon. Export again from NodeTool to update the game itself.
384
+ `;
385
+ return {
386
+ "package.json": `${JSON.stringify(packageJson, null, 2)}\n`,
387
+ "app.json": `${JSON.stringify(appJson, null, 2)}\n`,
388
+ "eas.json": `${JSON.stringify(eas, null, 2)}\n`,
389
+ "metro.config.js": metro,
390
+ "index.js": index,
391
+ "App.js": APP_SOURCE,
392
+ "README.md": readme,
393
+ ".gitignore": "node_modules/\n.expo/\nios/\nandroid/\n"
394
+ };
395
+ }
396
+ /** Includes the web runtime, page template, project templates and generated icons in cache identity. */
397
+ export async function expoGameRuntimeFingerprint(document, app = {}) {
398
+ const metadata = expoAppMetadata(document, app);
399
+ const web = document.schemaVersion === 3
400
+ ? await (await import("./build3d.js")).standaloneGame3DRuntimeFingerprint()
401
+ : await (await import("./build.js")).standaloneGameRuntimeFingerprint();
402
+ return gameBuildFingerprint({ format: "nodetool-expo-v1", web, shim: FILE_SHIM, ...expoProjectFiles(metadata), ...await expoIconFiles(app.icon) });
403
+ }
404
+ /** Exports a game as an Expo project: the standalone web player as one offline page, shown full screen in a WebView. */
405
+ export async function buildExpoGameProject(options) {
406
+ options.signal?.throwIfAborted();
407
+ const metadata = expoAppMetadata(options.document, options.app);
408
+ const icons = await expoIconFiles(options.app?.icon);
409
+ const outputDir = resolve(options.outputDir);
410
+ await mkdir(dirname(outputDir), { recursive: true });
411
+ const staging = await mkdtemp(join(dirname(outputDir), ".nodetool-game-expo-"));
412
+ try {
413
+ const webDir = join(staging, ".web");
414
+ if (options.document.schemaVersion === 3) {
415
+ const { buildStandaloneGame3D } = await import("./build3d.js");
416
+ await buildStandaloneGame3D({ document: options.document, outputDir: webDir, resolveAsset: options.resolveAsset, signal: options.signal });
417
+ }
418
+ else {
419
+ const { buildStandaloneGame } = await import("./build.js");
420
+ await buildStandaloneGame({ document: options.document, outputDir: webDir, signal: options.signal, resolveAsset: (assetId) => options.resolveAsset(assetId, options.signal) });
421
+ }
422
+ const page = await inlineStandaloneGame(webDir, options.signal);
423
+ await rm(webDir, { recursive: true, force: true });
424
+ options.signal?.throwIfAborted();
425
+ const files = { ...expoProjectFiles(metadata), ...icons, [EXPO_GAME_HTML]: page };
426
+ for (const [path, content] of Object.entries(files)) {
427
+ await mkdir(dirname(join(staging, path)), { recursive: true });
428
+ await writeFile(join(staging, path), content);
429
+ }
430
+ options.signal?.throwIfAborted();
431
+ let existing;
432
+ try {
433
+ existing = await readdir(outputDir);
434
+ }
435
+ catch (error) {
436
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
437
+ throw error;
438
+ }
439
+ }
440
+ if (existing && existing.length > 0) {
441
+ throw new Error(`Output directory is not empty: ${outputDir}`);
442
+ }
443
+ if (existing) {
444
+ await rmdir(outputDir);
445
+ }
446
+ await rename(staging, outputDir);
447
+ return { outputDir, htmlPath: join(outputDir, EXPO_GAME_HTML), metadata };
448
+ }
449
+ catch (error) {
450
+ await rm(staging, { recursive: true, force: true });
451
+ throw error;
452
+ }
453
+ }
454
+ //# sourceMappingURL=build-expo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-expo.js","sourceRoot":"","sources":["../src/build-expo.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,13 @@ export interface TauriGameProject {
44
44
  }
45
45
  /** Resolves and validates the names, version and window size of an exported desktop app. */
46
46
  export declare function tauriAppMetadata(document: AnyGameDocument, app?: TauriAppOptions): TauriAppMetadata;
47
+ export interface RenderedIcon {
48
+ readonly size: number;
49
+ readonly png: Uint8Array;
50
+ readonly rgba: Uint8ClampedArray;
51
+ }
52
+ /** Square app icons at each size, cropped from `source` or drawn as the default NodeTool game icon. */
53
+ export declare function renderIcons(sizes: readonly number[], source?: Uint8Array): Promise<Map<number, RenderedIcon>>;
47
54
  /** Every icon file the Tauri bundler and window need, keyed by path under `src-tauri/`. */
48
55
  export declare function tauriIconFiles(source?: Uint8Array): Promise<Record<string, Uint8Array>>;
49
56
  /** The text files of the Tauri project, keyed by path relative to the project root. */
@@ -1 +1 @@
1
- {"version":3,"file":"build-tauri.d.ts","sourceRoot":"","sources":["../src/build-tauri.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-tauri.d.ts","sourceRoot":"","sources":["../src/build-tauri.ts"],"names":[],"mappings":"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"}
@@ -75,7 +75,8 @@ function drawDefaultIcon(context, size) {
75
75
  context.closePath();
76
76
  context.fill();
77
77
  }
78
- async function renderIcons(sizes, source) {
78
+ /** Square app icons at each size, cropped from `source` or drawn as the default NodeTool game icon. */
79
+ export async function renderIcons(sizes, source) {
79
80
  const image = source ? await loadImage(Buffer.from(source)) : null;
80
81
  if (image && (image.width < 1 || image.height < 1)) {
81
82
  throw new Error("App icon image is empty");