@bitmagic/cli 0.1.70-dev.1 → 0.1.70-dev.2
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/README.md +47 -1
- package/assets/skills/publishing-to-poki/SKILL.md +50 -0
- package/dist/cli.d.ts +8 -0
- package/dist/commands/publish.d.ts +11 -0
- package/dist/commands/publish.js +18 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/ios/collect-urls.d.ts +1 -75
- package/dist/ios/collect-urls.js +2 -219
- package/dist/ios/collect-urls.js.map +1 -1
- package/dist/ios/local-server.d.ts +1 -11
- package/dist/ios/local-server.js +2 -87
- package/dist/ios/local-server.js.map +1 -1
- package/dist/ios/transform.d.ts +4 -45
- package/dist/ios/transform.js +3 -59
- package/dist/ios/transform.js.map +1 -1
- package/dist/ios/vendor.d.ts +1 -29
- package/dist/ios/vendor.js +2 -112
- package/dist/ios/vendor.js.map +1 -1
- package/dist/package/collect-urls.d.ts +75 -0
- package/dist/package/collect-urls.js +220 -0
- package/dist/package/collect-urls.js.map +1 -0
- package/dist/package/local-server.d.ts +13 -0
- package/dist/package/local-server.js +102 -0
- package/dist/package/local-server.js.map +1 -0
- package/dist/package/transform.d.ts +47 -0
- package/dist/package/transform.js +62 -0
- package/dist/package/transform.js.map +1 -0
- package/dist/package/vendor.d.ts +33 -0
- package/dist/package/vendor.js +114 -0
- package/dist/package/vendor.js.map +1 -0
- package/dist/poki/assets.d.ts +20 -0
- package/dist/poki/assets.js +154 -0
- package/dist/poki/assets.js.map +1 -0
- package/dist/poki/check.d.ts +21 -0
- package/dist/poki/check.js +134 -0
- package/dist/poki/check.js.map +1 -0
- package/dist/poki/publish.d.ts +22 -0
- package/dist/poki/publish.js +207 -0
- package/dist/poki/publish.js.map +1 -0
- package/dist/poki/transform.d.ts +6 -0
- package/dist/poki/transform.js +30 -0
- package/dist/poki/transform.js.map +1 -0
- package/dist/publish/bundle.d.ts +1 -0
- package/dist/publish/bundle.js +2 -2
- package/dist/publish/bundle.js.map +1 -1
- package/dist/scaffold/poki-skill-files.d.ts +2 -0
- package/dist/scaffold/poki-skill-files.js +7 -0
- package/dist/scaffold/poki-skill-files.js.map +1 -0
- package/dist/scaffold/project-files.js +1 -1
- package/dist/scaffold/project.js +2 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +6 -4
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/verify/browser.d.ts +3 -1
- package/dist/verify/browser.js +14 -9
- package/dist/verify/browser.js.map +1 -1
- package/dist/verify/classify.d.ts +2 -0
- package/dist/verify/classify.js +4 -1
- package/dist/verify/classify.js.map +1 -1
- package/package.json +4 -4
package/dist/ios/local-server.js
CHANGED
|
@@ -1,88 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* validation passes. GET only, no caching, path-traversal guarded. The MIME table is exported
|
|
4
|
-
* because the Swift scheme handler (xcode-template.ts) is generated from the SAME table — the
|
|
5
|
-
* validation browser and the shipped app must answer identically or the validation proves
|
|
6
|
-
* nothing.
|
|
7
|
-
*/
|
|
8
|
-
import * as fs from 'fs';
|
|
9
|
-
import * as http from 'http';
|
|
10
|
-
import * as path from 'path';
|
|
11
|
-
/** Extension → content type, shared by this server and the generated Swift handler. */
|
|
12
|
-
export const MIME_TYPES = new Map([
|
|
13
|
-
['html', 'text/html; charset=utf-8'],
|
|
14
|
-
['js', 'text/javascript; charset=utf-8'],
|
|
15
|
-
['mjs', 'text/javascript; charset=utf-8'],
|
|
16
|
-
['css', 'text/css; charset=utf-8'],
|
|
17
|
-
['json', 'application/json'],
|
|
18
|
-
['wasm', 'application/wasm'],
|
|
19
|
-
['glb', 'model/gltf-binary'],
|
|
20
|
-
['gltf', 'model/gltf+json'],
|
|
21
|
-
['png', 'image/png'],
|
|
22
|
-
['webp', 'image/webp'],
|
|
23
|
-
['jpg', 'image/jpeg'],
|
|
24
|
-
['jpeg', 'image/jpeg'],
|
|
25
|
-
['gif', 'image/gif'],
|
|
26
|
-
['svg', 'image/svg+xml'],
|
|
27
|
-
['ico', 'image/png'],
|
|
28
|
-
['opus', 'audio/ogg'],
|
|
29
|
-
['ogg', 'audio/ogg'],
|
|
30
|
-
['mp3', 'audio/mpeg'],
|
|
31
|
-
['wav', 'audio/wav'],
|
|
32
|
-
['mp4', 'video/mp4'],
|
|
33
|
-
['webm', 'video/webm'],
|
|
34
|
-
['txt', 'text/plain; charset=utf-8'],
|
|
35
|
-
]);
|
|
36
|
-
export const FALLBACK_MIME = 'application/octet-stream';
|
|
37
|
-
export function mimeTypeFor(filePath) {
|
|
38
|
-
const ext = filePath.split('?')[0].split('.').pop()?.toLowerCase() ?? '';
|
|
39
|
-
return MIME_TYPES.get(ext) ?? FALLBACK_MIME;
|
|
40
|
-
}
|
|
41
|
-
/** Serve `dir` on an ephemeral localhost port. */
|
|
42
|
-
export function startPayloadServer(dir) {
|
|
43
|
-
const rootDir = path.resolve(dir);
|
|
44
|
-
const server = http.createServer((req, res) => {
|
|
45
|
-
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
46
|
-
res.writeHead(405).end();
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const requestPath = decodeURIComponent((req.url ?? '/').split('?')[0]);
|
|
50
|
-
const resolved = path.resolve(rootDir, `.${requestPath}`);
|
|
51
|
-
if (resolved !== rootDir && !resolved.startsWith(rootDir + path.sep)) {
|
|
52
|
-
res.writeHead(403).end();
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
let filePath = resolved;
|
|
56
|
-
try {
|
|
57
|
-
if (fs.statSync(filePath).isDirectory())
|
|
58
|
-
filePath = path.join(filePath, 'index.html');
|
|
59
|
-
const bytes = fs.readFileSync(filePath);
|
|
60
|
-
res
|
|
61
|
-
.writeHead(200, { 'Content-Type': mimeTypeFor(filePath), 'Cache-Control': 'no-store' })
|
|
62
|
-
.end(req.method === 'HEAD' ? undefined : bytes);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' }).end('not found');
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
return new Promise((resolve, reject) => {
|
|
69
|
-
server.once('error', reject);
|
|
70
|
-
server.listen(0, '127.0.0.1', () => {
|
|
71
|
-
const address = server.address();
|
|
72
|
-
if (address === null || typeof address === 'string') {
|
|
73
|
-
reject(new Error('The payload server did not report a port.'));
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
resolve({
|
|
77
|
-
port: address.port,
|
|
78
|
-
origin: `http://127.0.0.1:${address.port}`,
|
|
79
|
-
close: () => new Promise((resolveClose) => {
|
|
80
|
-
server.close(() => resolveClose());
|
|
81
|
-
// Sockets Chrome keeps alive would otherwise hold close() open past the command.
|
|
82
|
-
server.closeAllConnections();
|
|
83
|
-
}),
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
1
|
+
// Compatibility entry point for the iOS packager.
|
|
2
|
+
export * from '../package/local-server.js';
|
|
88
3
|
//# sourceMappingURL=local-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../../src/ios/local-server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../../src/ios/local-server.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,cAAc,4BAA4B,CAAC"}
|
package/dist/ios/transform.d.ts
CHANGED
|
@@ -1,47 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* - the `bm-bundled-assets` map (original URL → relative vendor path), which the engine's own
|
|
6
|
-
* ASSET_MAP mechanism resolves through — every three.js loader plus the explicit
|
|
7
|
-
* `ASSET_MAP.get` fetch sites;
|
|
8
|
-
* - a literal rewrite of every vendored URL AND the animation base-URL constants, which fixes
|
|
9
|
-
* the sites that bypass the map (raw fetch in PlacedObjectSystem/HeightmapSystem/physics2d/
|
|
10
|
-
* splat loaders, and the StartScreen/SelectionSteps/AchievementToast DOM urls): the world
|
|
11
|
-
* data is inlined in this HTML, so rewriting the literals fixes what those sites read.
|
|
12
|
-
*
|
|
13
|
-
* No DOM parser — the bundle is one multi-MB HTML string and the three edits are anchored on
|
|
14
|
-
* markers the scaffold's own template guarantees (`<head>`, `</head>`).
|
|
15
|
-
*/
|
|
16
|
-
export interface TransformOptions {
|
|
17
|
-
html: string;
|
|
18
|
-
/** Original absolute URL → document-relative vendor path (`vendor/<host>/<path>`). */
|
|
19
|
-
assetMap: ReadonlyMap<string, string>;
|
|
20
|
-
/** Base-URL constant → relative base (see vendor.ts vendorBasePathFor). */
|
|
21
|
-
baseRewrites: ReadonlyMap<string, string>;
|
|
22
|
-
}
|
|
23
|
-
export interface TransformResult {
|
|
24
|
-
html: string;
|
|
25
|
-
/** How many URL literals were rewritten, for the build's notes. */
|
|
26
|
-
rewrites: number;
|
|
27
|
-
}
|
|
1
|
+
import { type TransformOptions as PackageTransformOptions, type TransformResult } from '../package/transform.js';
|
|
2
|
+
export { BUNDLED_ASSETS_ID, renderAssetMapJson, rewriteUrlLiterals } from '../package/transform.js';
|
|
3
|
+
export type { TransformResult } from '../package/transform.js';
|
|
28
4
|
export declare const DISTRIBUTION_META = "<meta name=\"bm:distribution\" content=\"ios\">";
|
|
29
|
-
export
|
|
30
|
-
/**
|
|
31
|
-
* Rewrite every occurrence of the given URLs/bases in one pass. Longest key first, so an exact
|
|
32
|
-
* asset URL wins over a base that prefixes it — both rewrite into the same vendor layout, but
|
|
33
|
-
* the ordering keeps the replacement deterministic.
|
|
34
|
-
*/
|
|
35
|
-
export declare function rewriteUrlLiterals(html: string, replacements: ReadonlyMap<string, string>): {
|
|
36
|
-
html: string;
|
|
37
|
-
rewrites: number;
|
|
38
|
-
};
|
|
39
|
-
/** Serialize the asset map for the inline block. `<` is escaped so no URL can ever terminate
|
|
40
|
-
* the script element early — standard inline-JSON hygiene, and still valid JSON. */
|
|
41
|
-
export declare function renderAssetMapJson(assetMap: ReadonlyMap<string, string>): string;
|
|
42
|
-
/**
|
|
43
|
-
* The full §4d transform. Throws when the bundle carries no `<head>`/`</head>` markers — that
|
|
44
|
-
* is not a page this lane understands, and silently skipping the injection would ship an app
|
|
45
|
-
* that fetches from the network.
|
|
46
|
-
*/
|
|
5
|
+
export type TransformOptions = Omit<PackageTransformOptions, 'distribution'>;
|
|
47
6
|
export declare function transformBundleHtml(options: TransformOptions): TransformResult;
|
package/dist/ios/transform.js
CHANGED
|
@@ -1,63 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* the payload page. Two deliberately redundant mechanisms:
|
|
4
|
-
*
|
|
5
|
-
* - the `bm-bundled-assets` map (original URL → relative vendor path), which the engine's own
|
|
6
|
-
* ASSET_MAP mechanism resolves through — every three.js loader plus the explicit
|
|
7
|
-
* `ASSET_MAP.get` fetch sites;
|
|
8
|
-
* - a literal rewrite of every vendored URL AND the animation base-URL constants, which fixes
|
|
9
|
-
* the sites that bypass the map (raw fetch in PlacedObjectSystem/HeightmapSystem/physics2d/
|
|
10
|
-
* splat loaders, and the StartScreen/SelectionSteps/AchievementToast DOM urls): the world
|
|
11
|
-
* data is inlined in this HTML, so rewriting the literals fixes what those sites read.
|
|
12
|
-
*
|
|
13
|
-
* No DOM parser — the bundle is one multi-MB HTML string and the three edits are anchored on
|
|
14
|
-
* markers the scaffold's own template guarantees (`<head>`, `</head>`).
|
|
15
|
-
*/
|
|
1
|
+
import { transformBundleHtml as transform } from '../package/transform.js';
|
|
2
|
+
export { BUNDLED_ASSETS_ID, renderAssetMapJson, rewriteUrlLiterals } from '../package/transform.js';
|
|
16
3
|
export const DISTRIBUTION_META = '<meta name="bm:distribution" content="ios">';
|
|
17
|
-
export const BUNDLED_ASSETS_ID = 'bm-bundled-assets';
|
|
18
|
-
function escapeRegExp(value) {
|
|
19
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Rewrite every occurrence of the given URLs/bases in one pass. Longest key first, so an exact
|
|
23
|
-
* asset URL wins over a base that prefixes it — both rewrite into the same vendor layout, but
|
|
24
|
-
* the ordering keeps the replacement deterministic.
|
|
25
|
-
*/
|
|
26
|
-
export function rewriteUrlLiterals(html, replacements) {
|
|
27
|
-
if (replacements.size === 0)
|
|
28
|
-
return { html, rewrites: 0 };
|
|
29
|
-
const keys = [...replacements.keys()].sort((a, b) => b.length - a.length);
|
|
30
|
-
const pattern = new RegExp(keys.map(escapeRegExp).join('|'), 'g');
|
|
31
|
-
let rewrites = 0;
|
|
32
|
-
const rewritten = html.replace(pattern, (match) => {
|
|
33
|
-
rewrites += 1;
|
|
34
|
-
// The alternation only matches keys of the map, so the lookup cannot miss.
|
|
35
|
-
return replacements.get(match) ?? match;
|
|
36
|
-
});
|
|
37
|
-
return { html: rewritten, rewrites };
|
|
38
|
-
}
|
|
39
|
-
/** Serialize the asset map for the inline block. `<` is escaped so no URL can ever terminate
|
|
40
|
-
* the script element early — standard inline-JSON hygiene, and still valid JSON. */
|
|
41
|
-
export function renderAssetMapJson(assetMap) {
|
|
42
|
-
return JSON.stringify(Object.fromEntries(assetMap)).replace(/</g, '\\u003c');
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* The full §4d transform. Throws when the bundle carries no `<head>`/`</head>` markers — that
|
|
46
|
-
* is not a page this lane understands, and silently skipping the injection would ship an app
|
|
47
|
-
* that fetches from the network.
|
|
48
|
-
*/
|
|
49
4
|
export function transformBundleHtml(options) {
|
|
50
|
-
|
|
51
|
-
const { html: rewritten, rewrites } = rewriteUrlLiterals(options.html, combined);
|
|
52
|
-
if (!rewritten.includes('<head>') || !rewritten.includes('</head>')) {
|
|
53
|
-
throw new Error('The built bundle has no <head> section to inject the asset map into.');
|
|
54
|
-
}
|
|
55
|
-
const mapBlock = `<script type="application/json" id="${BUNDLED_ASSETS_ID}">`
|
|
56
|
-
+ renderAssetMapJson(options.assetMap)
|
|
57
|
-
+ '</script>';
|
|
58
|
-
const html = rewritten
|
|
59
|
-
.replace('<head>', `<head>\n ${DISTRIBUTION_META}`)
|
|
60
|
-
.replace('</head>', ` ${mapBlock}\n</head>`);
|
|
61
|
-
return { html, rewrites };
|
|
5
|
+
return transform({ ...options, distribution: 'ios' });
|
|
62
6
|
}
|
|
63
7
|
//# sourceMappingURL=transform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/ios/transform.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/ios/transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,SAAS,EAA0E,MAAM,yBAAyB,CAAC;AACnJ,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEpG,MAAM,CAAC,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAE/E,MAAM,UAAU,mBAAmB,CAAC,OAAyB;IAC3D,OAAO,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;AACxD,CAAC"}
|
package/dist/ios/vendor.d.ts
CHANGED
|
@@ -1,29 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* The document-relative path a URL is vendored at, or null for a URL this lane cannot mirror
|
|
3
|
-
* (unparseable, or a path that escapes the tree). The query string is dropped — asset URLs do
|
|
4
|
-
* not carry meaningful queries, and a `?` cannot survive as a same-file request path anyway.
|
|
5
|
-
*/
|
|
6
|
-
export declare function vendorPathFor(url: string): string | null;
|
|
7
|
-
/** Where a BASE url's rewrite points: the same mapping, minus the appended 'index'. */
|
|
8
|
-
export declare function vendorBasePathFor(baseUrl: string): string | null;
|
|
9
|
-
export interface VendorFailure {
|
|
10
|
-
url: string;
|
|
11
|
-
error: string;
|
|
12
|
-
}
|
|
13
|
-
export interface VendorResult {
|
|
14
|
-
/** URL → document-relative vendor path, for every URL that is now on disk. */
|
|
15
|
-
entries: Map<string, string>;
|
|
16
|
-
failures: VendorFailure[];
|
|
17
|
-
/** How many came from the cache rather than the network. */
|
|
18
|
-
cacheHits: number;
|
|
19
|
-
}
|
|
20
|
-
export interface VendorOptions {
|
|
21
|
-
urls: Iterable<string>;
|
|
22
|
-
cacheDir: string;
|
|
23
|
-
payloadDir: string;
|
|
24
|
-
fetchImpl?: typeof globalThis.fetch;
|
|
25
|
-
log?: (message: string) => void;
|
|
26
|
-
concurrency?: number;
|
|
27
|
-
}
|
|
28
|
-
/** Download (or copy from cache) every URL into the payload's vendor tree. */
|
|
29
|
-
export declare function vendorUrls(options: VendorOptions): Promise<VendorResult>;
|
|
1
|
+
export * from '../package/vendor.js';
|
package/dist/ios/vendor.js
CHANGED
|
@@ -1,113 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The layout preserves `<host>/<pathname>` so that rewriting a BASE url in the bundle (see
|
|
5
|
-
* transform.ts) makes runtime-constructed `${base}/${file}` URLs land on the mirrored file —
|
|
6
|
-
* exact-URL map entries alone could never cover those.
|
|
7
|
-
*
|
|
8
|
-
* Downloads are cached under `.bitmagic/ios/cache` keyed by URL hash: generated-asset URLs are
|
|
9
|
-
* immutable in practice (uuid/content-addressed paths), and a rebuild should not re-download a
|
|
10
|
-
* hundred GLBs. Bytes are stored post-Content-Encoding (node fetch inflates); the engine's
|
|
11
|
-
* gzip-sniffing loaders accept raw bytes unchanged (fetchVwld.ts).
|
|
12
|
-
*/
|
|
13
|
-
import { createHash } from 'crypto';
|
|
14
|
-
import * as fs from 'fs';
|
|
15
|
-
import * as path from 'path';
|
|
16
|
-
/**
|
|
17
|
-
* The document-relative path a URL is vendored at, or null for a URL this lane cannot mirror
|
|
18
|
-
* (unparseable, or a path that escapes the tree). The query string is dropped — asset URLs do
|
|
19
|
-
* not carry meaningful queries, and a `?` cannot survive as a same-file request path anyway.
|
|
20
|
-
*/
|
|
21
|
-
export function vendorPathFor(url) {
|
|
22
|
-
let parsed;
|
|
23
|
-
try {
|
|
24
|
-
parsed = new URL(url);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
|
|
30
|
-
return null;
|
|
31
|
-
let pathname = parsed.pathname;
|
|
32
|
-
if (pathname.endsWith('/') || pathname === '')
|
|
33
|
-
pathname += 'index';
|
|
34
|
-
const segments = [];
|
|
35
|
-
for (const rawSegment of pathname.split('/')) {
|
|
36
|
-
if (rawSegment === '')
|
|
37
|
-
continue;
|
|
38
|
-
let segment;
|
|
39
|
-
try {
|
|
40
|
-
segment = decodeURIComponent(rawSegment);
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
segment = rawSegment;
|
|
44
|
-
}
|
|
45
|
-
if (segment === '.' || segment === '..')
|
|
46
|
-
return null;
|
|
47
|
-
segments.push(segment);
|
|
48
|
-
}
|
|
49
|
-
if (segments.length === 0)
|
|
50
|
-
return null;
|
|
51
|
-
return ['vendor', parsed.host, ...segments].join('/');
|
|
52
|
-
}
|
|
53
|
-
/** Where a BASE url's rewrite points: the same mapping, minus the appended 'index'. */
|
|
54
|
-
export function vendorBasePathFor(baseUrl) {
|
|
55
|
-
const mapped = vendorPathFor(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`);
|
|
56
|
-
if (mapped === null)
|
|
57
|
-
return null;
|
|
58
|
-
return mapped.replace(/\/index$/, '');
|
|
59
|
-
}
|
|
60
|
-
function cacheFileFor(cacheDir, url) {
|
|
61
|
-
return path.join(cacheDir, createHash('sha256').update(url).digest('hex'));
|
|
62
|
-
}
|
|
63
|
-
/** Download (or copy from cache) every URL into the payload's vendor tree. */
|
|
64
|
-
export async function vendorUrls(options) {
|
|
65
|
-
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
66
|
-
const log = options.log ?? (() => { });
|
|
67
|
-
const entries = new Map();
|
|
68
|
-
const failures = [];
|
|
69
|
-
let cacheHits = 0;
|
|
70
|
-
fs.mkdirSync(options.cacheDir, { recursive: true });
|
|
71
|
-
const queue = [...new Set(options.urls)];
|
|
72
|
-
const worker = async () => {
|
|
73
|
-
for (;;) {
|
|
74
|
-
const url = queue.shift();
|
|
75
|
-
if (url === undefined)
|
|
76
|
-
return;
|
|
77
|
-
const relPath = vendorPathFor(url);
|
|
78
|
-
if (relPath === null) {
|
|
79
|
-
failures.push({ url, error: 'not a vendorable URL' });
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
const cacheFile = cacheFileFor(options.cacheDir, url);
|
|
83
|
-
try {
|
|
84
|
-
if (fs.existsSync(cacheFile)) {
|
|
85
|
-
cacheHits += 1;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
const response = await fetchImpl(url);
|
|
89
|
-
if (!response.ok)
|
|
90
|
-
throw new Error(`HTTP ${response.status}`);
|
|
91
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
92
|
-
// Write-then-rename so a crashed download never leaves a truncated cache entry that
|
|
93
|
-
// every later build would trust.
|
|
94
|
-
const tmp = `${cacheFile}.tmp-${process.pid}`;
|
|
95
|
-
fs.writeFileSync(tmp, bytes);
|
|
96
|
-
fs.renameSync(tmp, cacheFile);
|
|
97
|
-
log(` fetched ${url} (${bytes.byteLength} bytes)`);
|
|
98
|
-
}
|
|
99
|
-
const target = path.join(options.payloadDir, ...relPath.split('/'));
|
|
100
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
101
|
-
fs.copyFileSync(cacheFile, target);
|
|
102
|
-
entries.set(url, relPath);
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
failures.push({ url, error: error instanceof Error ? error.message : String(error) });
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const width = Math.max(1, Math.min(options.concurrency ?? 6, queue.length));
|
|
110
|
-
await Promise.all(Array.from({ length: width }, worker));
|
|
111
|
-
return { entries, failures, cacheHits };
|
|
112
|
-
}
|
|
1
|
+
// Compatibility entry point for the iOS packager.
|
|
2
|
+
export * from '../package/vendor.js';
|
|
113
3
|
//# sourceMappingURL=vendor.js.map
|
package/dist/ios/vendor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendor.js","sourceRoot":"","sources":["../../src/ios/vendor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vendor.js","sourceRoot":"","sources":["../../src/ios/vendor.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export interface CollectedUrls {
|
|
2
|
+
/** Every absolute URL to vendor. */
|
|
3
|
+
urls: Set<string>;
|
|
4
|
+
/**
|
|
5
|
+
* Base-URL constants the engine concatenates file names onto (`${base}/${file}`). Rewriting
|
|
6
|
+
* these in the bundle makes runtime-constructed URLs resolve into the mirrored vendor tree,
|
|
7
|
+
* which no exact-URL map entry could cover.
|
|
8
|
+
*/
|
|
9
|
+
bases: Set<string>;
|
|
10
|
+
/** Creator-facing lines about what was (or could not be) collected. */
|
|
11
|
+
notes: string[];
|
|
12
|
+
}
|
|
13
|
+
/** Walk any JSON value, collecting remote-URL strings outside the deny-listed fields. */
|
|
14
|
+
export declare function deepWalkUrls(value: unknown, out: Set<string>): void;
|
|
15
|
+
/** The same compiled-code .glb scan the standalone lane runs, over the pro project's dist. */
|
|
16
|
+
export declare function scanCompiledCodeUrls(compiledCode: string): Set<string>;
|
|
17
|
+
/** All compiled game JS under dist/src/work, concatenated — for reference scans. */
|
|
18
|
+
export declare function readCompiledGameCode(root: string): string;
|
|
19
|
+
interface AnimationEntry {
|
|
20
|
+
file: string;
|
|
21
|
+
/** Absolute URL overriding `<base>/<file>` — the capture-backed default locomotion uses it. */
|
|
22
|
+
url?: string;
|
|
23
|
+
motionId: string;
|
|
24
|
+
}
|
|
25
|
+
interface WeaponAnimationEntry {
|
|
26
|
+
url: string;
|
|
27
|
+
motionId: string;
|
|
28
|
+
}
|
|
29
|
+
/** The shape of `animationAssets` this collector relies on — structural, checked at runtime. */
|
|
30
|
+
export interface AnimationAssetsData {
|
|
31
|
+
activeLibrary: 'cdn' | 'generated';
|
|
32
|
+
animationBaseUrl: string;
|
|
33
|
+
generatedAnimationBaseUrl: string;
|
|
34
|
+
animalBaseUrl: string;
|
|
35
|
+
voxelAnimalBaseUrl: string;
|
|
36
|
+
voxelFishBaseUrl: string;
|
|
37
|
+
characterUrls: {
|
|
38
|
+
default: string;
|
|
39
|
+
defaultFallback: string;
|
|
40
|
+
};
|
|
41
|
+
coreAnimations: AnimationEntry[];
|
|
42
|
+
generatedAnimations: AnimationEntry[];
|
|
43
|
+
meleeWeaponAnimations: WeaponAnimationEntry[];
|
|
44
|
+
generatedMeleeWeaponAnimations: AnimationEntry[];
|
|
45
|
+
generatedRangedWeaponAnimations: AnimationEntry[];
|
|
46
|
+
generatedDirectionalAnimations: AnimationEntry[];
|
|
47
|
+
generatedPostureAnimations: AnimationEntry[];
|
|
48
|
+
animalSkeletons: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Import the vendored engine's compiled AnimationAssets — a pure data module with no imports,
|
|
52
|
+
* which is what makes this safe from plain node. Null (with the caller noting it) when the
|
|
53
|
+
* engine predates the module or the shape moved: the record pass still catches whatever the
|
|
54
|
+
* running game actually fetches.
|
|
55
|
+
*/
|
|
56
|
+
export declare function loadAnimationAssets(root: string): Promise<AnimationAssetsData | null>;
|
|
57
|
+
interface WorldDataShape {
|
|
58
|
+
worldProfileData?: {
|
|
59
|
+
hasPlayerCharacter?: unknown;
|
|
60
|
+
animals?: unknown;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The built-in animation URLs this game can load. The ACTIVE library ships whole — its optional
|
|
65
|
+
* packs (melee/ranged/directional/posture) are loaded on demand by engine systems whose names
|
|
66
|
+
* game code never contains, so reference-scanning cannot bound them. The inactive library ships
|
|
67
|
+
* only clips the compiled game code names (`getBuiltinAnimationDef` resolves ids from either).
|
|
68
|
+
*/
|
|
69
|
+
export declare function collectAnimationUrls(assets: AnimationAssetsData, worldData: WorldDataShape, compiledCode: string): {
|
|
70
|
+
urls: Set<string>;
|
|
71
|
+
bases: Set<string>;
|
|
72
|
+
};
|
|
73
|
+
/** The full §4b collection: deep walk + compiled-code scan + built-in animation surface. */
|
|
74
|
+
export declare function collectUrls(root: string): Promise<CollectedUrls>;
|
|
75
|
+
export {};
|