@yali-engine/cli 0.0.0-stage → 0.4.0
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/bin/yali.mjs +12 -0
- package/dist/budgets.d.ts +25 -0
- package/dist/budgets.js +27 -0
- package/dist/budgets.js.map +1 -0
- package/dist/cdp.d.ts +25 -0
- package/dist/cdp.js +106 -0
- package/dist/cdp.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +83 -0
- package/dist/cli.js.map +1 -0
- package/dist/cmd-bench.d.ts +17 -0
- package/dist/cmd-bench.js +74 -0
- package/dist/cmd-bench.js.map +1 -0
- package/dist/cmd-build.d.ts +13 -0
- package/dist/cmd-build.js +40 -0
- package/dist/cmd-build.js.map +1 -0
- package/dist/cmd-convert.d.ts +27 -0
- package/dist/cmd-convert.js +456 -0
- package/dist/cmd-convert.js.map +1 -0
- package/dist/cmd-create.d.ts +8 -0
- package/dist/cmd-create.js +248 -0
- package/dist/cmd-create.js.map +1 -0
- package/dist/cmd-dev.d.ts +9 -0
- package/dist/cmd-dev.js +24 -0
- package/dist/cmd-dev.js.map +1 -0
- package/dist/cmd-game.d.ts +24 -0
- package/dist/cmd-game.js +127 -0
- package/dist/cmd-game.js.map +1 -0
- package/dist/cmd-headless.d.ts +15 -0
- package/dist/cmd-headless.js +59 -0
- package/dist/cmd-headless.js.map +1 -0
- package/dist/cmd-inspect.d.ts +13 -0
- package/dist/cmd-inspect.js +64 -0
- package/dist/cmd-inspect.js.map +1 -0
- package/dist/cmd-test.d.ts +9 -0
- package/dist/cmd-test.js +68 -0
- package/dist/cmd-test.js.map +1 -0
- package/dist/collision.d.ts +31 -0
- package/dist/collision.js +471 -0
- package/dist/collision.js.map +1 -0
- package/dist/commands.d.ts +18 -0
- package/dist/commands.js +105 -0
- package/dist/commands.js.map +1 -0
- package/dist/encoder.d.ts +63 -0
- package/dist/encoder.js +119 -0
- package/dist/encoder.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +9 -0
- package/dist/main.js.map +1 -0
- package/dist/native-encoder.d.ts +39 -0
- package/dist/native-encoder.js +142 -0
- package/dist/native-encoder.js.map +1 -0
- package/dist/output.d.ts +28 -0
- package/dist/output.js +27 -0
- package/dist/output.js.map +1 -0
- package/dist/png.d.ts +26 -0
- package/dist/png.js +134 -0
- package/dist/png.js.map +1 -0
- package/dist/project.d.ts +15 -0
- package/dist/project.js +35 -0
- package/dist/project.js.map +1 -0
- package/dist/size.d.ts +47 -0
- package/dist/size.js +100 -0
- package/dist/size.js.map +1 -0
- package/package.json +43 -3
- package/vendor/ENCODER-BUILD.json +33 -0
- package/vendor/LICENSE-basis_universal +201 -0
- package/vendor/LICENSE-zstd +30 -0
- package/vendor/NOTICE +33 -0
- package/vendor/basis_encoder.mjs +2 -0
- package/vendor/basis_encoder.wasm +0 -0
- package/README.md +0 -3
package/bin/yali.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The `yali` command. Workspace packages export TypeScript sources, which Node 22 loads only
|
|
3
|
+
// with --experimental-strip-types (ADR-0027), so this re-runs the CLI under that flag.
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
// In the workspace: the TypeScript source; published (no src): the built JS.
|
|
9
|
+
const source = fileURLToPath(new URL('../src/main.ts', import.meta.url));
|
|
10
|
+
const main = existsSync(source) ? source : fileURLToPath(new URL('../dist/main.js', import.meta.url));
|
|
11
|
+
const r = spawnSync(process.execPath, ['--experimental-strip-types', '--no-warnings', main, ...process.argv.slice(2)], { stdio: 'inherit' });
|
|
12
|
+
process.exit(r.status ?? 1);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** The budgets the CLI checks (a subset of the engine's `budgets.json`). */
|
|
2
|
+
export interface Budgets {
|
|
3
|
+
readonly size_brotli_kb: {
|
|
4
|
+
/** What a single-threaded page loads (ADR-0106: in this repo, the engine's reference page). */
|
|
5
|
+
readonly core_runtime_total: number;
|
|
6
|
+
/** What a threaded page loads (ADR-0106; default: `core_runtime_total`). */
|
|
7
|
+
readonly core_runtime_threaded?: number;
|
|
8
|
+
readonly core_wasm: number;
|
|
9
|
+
/**
|
|
10
|
+
* Capability fallbacks (ADR-0106): a JS chunk whose file name starts with a key is one only
|
|
11
|
+
* some devices load (the WebGL2 backend), gated against its own KB and left out of the totals.
|
|
12
|
+
*/
|
|
13
|
+
readonly fallback_chunks?: Readonly<Record<string, number>>;
|
|
14
|
+
};
|
|
15
|
+
readonly frame_ms: {
|
|
16
|
+
readonly desktop: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** The engine's own budgets (DESIGN.md §21), used when a project has no `budgets.json`. */
|
|
20
|
+
export declare const DEFAULT_BUDGETS: Budgets;
|
|
21
|
+
/** The nearest `budgets.json` at or above `root`, merged over the defaults. */
|
|
22
|
+
export declare function loadBudgets(root: string): {
|
|
23
|
+
budgets: Budgets;
|
|
24
|
+
file: string | null;
|
|
25
|
+
};
|
package/dist/budgets.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
/** The engine's own budgets (DESIGN.md §21), used when a project has no `budgets.json`. */
|
|
4
|
+
export const DEFAULT_BUDGETS = {
|
|
5
|
+
// ADR-0106: the threaded page and the WebGL2 fallback have budgets of their own.
|
|
6
|
+
size_brotli_kb: { core_runtime_total: 200, core_runtime_threaded: 210, core_wasm: 100, fallback_chunks: { webgl2: 22 } },
|
|
7
|
+
frame_ms: { desktop: 16.6 },
|
|
8
|
+
};
|
|
9
|
+
/** The nearest `budgets.json` at or above `root`, merged over the defaults. */
|
|
10
|
+
export function loadBudgets(root) {
|
|
11
|
+
for (let dir = root;; dir = dirname(dir)) {
|
|
12
|
+
const f = join(dir, 'budgets.json');
|
|
13
|
+
if (existsSync(f)) {
|
|
14
|
+
const raw = JSON.parse(readFileSync(f, 'utf8'));
|
|
15
|
+
return {
|
|
16
|
+
budgets: {
|
|
17
|
+
size_brotli_kb: { ...DEFAULT_BUDGETS.size_brotli_kb, ...raw.size_brotli_kb },
|
|
18
|
+
frame_ms: { ...DEFAULT_BUDGETS.frame_ms, ...raw.frame_ms },
|
|
19
|
+
},
|
|
20
|
+
file: f,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (dirname(dir) === dir)
|
|
24
|
+
return { budgets: DEFAULT_BUDGETS, file: null };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=budgets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budgets.js","sourceRoot":"","sources":["../src/budgets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmB1C,2FAA2F;AAC3F,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,iFAAiF;IACjF,cAAc,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE;IACxH,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;CAC5B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,KAAK,IAAI,GAAG,GAAG,IAAI,GAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAqB,CAAC;YACpE,OAAO;gBACL,OAAO,EAAE;oBACP,cAAc,EAAE,EAAE,GAAG,eAAe,CAAC,cAAc,EAAE,GAAG,GAAG,CAAC,cAAc,EAAE;oBAC5E,QAAQ,EAAE,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE;iBAC3D;gBACD,IAAI,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC5E,CAAC;AACH,CAAC"}
|
package/dist/cdp.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** A page opened in a Chrome DevTools Protocol browser for the length of one command. */
|
|
2
|
+
export interface CdpPage {
|
|
3
|
+
/** Evaluates an expression in the page (awaiting promises) and returns its JSON value. */
|
|
4
|
+
evaluate<T>(expression: string): Promise<T>;
|
|
5
|
+
/** Console errors, warnings and uncaught exceptions seen so far. */
|
|
6
|
+
readonly errors: readonly string[];
|
|
7
|
+
/** A PNG of the viewport, base64 (colour-converted by the browser: read pixels in-page). */
|
|
8
|
+
screenshot(): Promise<string>;
|
|
9
|
+
/** Reloads the page and waits for its load event. */
|
|
10
|
+
reload(): Promise<void>;
|
|
11
|
+
/** The page's current URL. */
|
|
12
|
+
readonly url: string;
|
|
13
|
+
/** Whether the connection is still open. */
|
|
14
|
+
readonly connected: boolean;
|
|
15
|
+
/** Detaches; closes the tab only if this page opened it. */
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Opens `url` in a new tab of the browser listening on `port` (`--remote-debugging-port`).
|
|
20
|
+
* The tab is brought to the front so its frames are not throttled. With `reuse`, an open
|
|
21
|
+
* tab already showing `url` (same origin and path) is attached instead, and left open.
|
|
22
|
+
*/
|
|
23
|
+
export declare function openPage(url: string, port: number, options?: {
|
|
24
|
+
reuse?: boolean;
|
|
25
|
+
}): Promise<CdpPage>;
|
package/dist/cdp.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { YaliError } from '@yali-engine/core';
|
|
2
|
+
/**
|
|
3
|
+
* Opens `url` in a new tab of the browser listening on `port` (`--remote-debugging-port`).
|
|
4
|
+
* The tab is brought to the front so its frames are not throttled. With `reuse`, an open
|
|
5
|
+
* tab already showing `url` (same origin and path) is attached instead, and left open.
|
|
6
|
+
*/
|
|
7
|
+
export async function openPage(url, port, options = {}) {
|
|
8
|
+
let target;
|
|
9
|
+
let opened = true;
|
|
10
|
+
try {
|
|
11
|
+
const want = new URL(url);
|
|
12
|
+
const existing = options.reuse
|
|
13
|
+
? (await (await fetch(`http://127.0.0.1:${port}/json/list`)).json()).find((t) => {
|
|
14
|
+
if (t.type !== 'page')
|
|
15
|
+
return false;
|
|
16
|
+
try {
|
|
17
|
+
const u = new URL(t.url);
|
|
18
|
+
return u.origin === want.origin && u.pathname === want.pathname;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
: undefined;
|
|
25
|
+
if (existing) {
|
|
26
|
+
target = existing;
|
|
27
|
+
opened = false;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
target = await (await fetch(`http://127.0.0.1:${port}/json/new?${encodeURIComponent(url)}`, { method: 'PUT' })).json();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw new YaliError('CDP_UNREACHABLE', `No browser answers on CDP port ${port}.`, `Start Chrome with --remote-debugging-port=${port} (and a dedicated --user-data-dir), or pass --cdp-port.`);
|
|
35
|
+
}
|
|
36
|
+
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
|
37
|
+
await new Promise((resolve, reject) => {
|
|
38
|
+
ws.onopen = resolve;
|
|
39
|
+
ws.onerror = () => reject(new YaliError('CDP_UNREACHABLE', `Could not attach to the tab on CDP port ${port}.`, 'Check the browser allows remote origins (--remote-allow-origins=*).'));
|
|
40
|
+
});
|
|
41
|
+
let id = 0;
|
|
42
|
+
let connected = true;
|
|
43
|
+
ws.onclose = () => (connected = false);
|
|
44
|
+
const pending = new Map();
|
|
45
|
+
const errors = [];
|
|
46
|
+
ws.onmessage = (m) => {
|
|
47
|
+
const msg = JSON.parse(String(m.data));
|
|
48
|
+
if (msg.id && pending.has(msg.id)) {
|
|
49
|
+
pending.get(msg.id)(msg);
|
|
50
|
+
pending.delete(msg.id);
|
|
51
|
+
}
|
|
52
|
+
else if (msg.method === 'Runtime.exceptionThrown') {
|
|
53
|
+
errors.push(`exception: ${msg.params.exceptionDetails.exception?.description ?? msg.params.exceptionDetails.text}`);
|
|
54
|
+
}
|
|
55
|
+
else if (msg.method === 'Runtime.consoleAPICalled' && (msg.params.type === 'error' || msg.params.type === 'warning')) {
|
|
56
|
+
errors.push(`${msg.params.type}: ${msg.params.args.map((a) => a.value ?? a.description ?? '').join(' ')}`);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const send = (method, params = {}) => new Promise((resolve) => {
|
|
60
|
+
const k = ++id;
|
|
61
|
+
pending.set(k, resolve);
|
|
62
|
+
ws.send(JSON.stringify({ id: k, method, params }));
|
|
63
|
+
});
|
|
64
|
+
await send('Runtime.enable');
|
|
65
|
+
await send('Page.enable');
|
|
66
|
+
await send('Page.bringToFront');
|
|
67
|
+
return {
|
|
68
|
+
errors,
|
|
69
|
+
url: target.url || url,
|
|
70
|
+
get connected() {
|
|
71
|
+
return connected;
|
|
72
|
+
},
|
|
73
|
+
async screenshot() {
|
|
74
|
+
const r = await send('Page.captureScreenshot', { format: 'png' });
|
|
75
|
+
return r.result?.data ?? '';
|
|
76
|
+
},
|
|
77
|
+
async reload() {
|
|
78
|
+
const loaded = new Promise((resolve) => {
|
|
79
|
+
const prev = ws.onmessage;
|
|
80
|
+
ws.onmessage = (m) => {
|
|
81
|
+
prev?.call(ws, m);
|
|
82
|
+
if (JSON.parse(String(m.data)).method === 'Page.loadEventFired') {
|
|
83
|
+
ws.onmessage = prev;
|
|
84
|
+
resolve();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
await send('Page.reload');
|
|
89
|
+
await loaded;
|
|
90
|
+
},
|
|
91
|
+
async evaluate(expression) {
|
|
92
|
+
const r = await send('Runtime.evaluate', { expression: `(async () => JSON.stringify(await (${expression})))()`, awaitPromise: true, returnByValue: true });
|
|
93
|
+
const ex = r.result?.exceptionDetails;
|
|
94
|
+
if (ex)
|
|
95
|
+
throw new YaliError('PAGE_EVAL_FAILED', `Evaluating ${expression} in the page failed: ${ex.exception?.description ?? ex.text}`, 'Check the page exposes what the command reads (see --probe).');
|
|
96
|
+
const v = r.result?.result?.value;
|
|
97
|
+
return (typeof v === 'string' ? JSON.parse(v) : undefined);
|
|
98
|
+
},
|
|
99
|
+
async close() {
|
|
100
|
+
ws.close();
|
|
101
|
+
if (opened)
|
|
102
|
+
await fetch(`http://127.0.0.1:${port}/json/close/${target.id}`).catch(() => { });
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cdp.js.map
|
package/dist/cdp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../src/cdp.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// `runCli`: one invocation of the `yali` command, as data (main.ts prints it).
|
|
2
|
+
//
|
|
3
|
+
// Exit codes: 0 ok · 1 error (the envelope says which) · 3 ran, but over a budget.
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { YaliError } from '@yali-engine/core';
|
|
6
|
+
import { benchCommand } from "./cmd-bench.js";
|
|
7
|
+
import { buildCommand } from "./cmd-build.js";
|
|
8
|
+
import { convertCommand } from "./cmd-convert.js";
|
|
9
|
+
import { createCommand } from "./cmd-create.js";
|
|
10
|
+
import { devCommand } from "./cmd-dev.js";
|
|
11
|
+
import { gameCommand } from "./cmd-game.js";
|
|
12
|
+
import { headlessCommand } from "./cmd-headless.js";
|
|
13
|
+
import { inspectCommand } from "./cmd-inspect.js";
|
|
14
|
+
import { testCommand } from "./cmd-test.js";
|
|
15
|
+
import { COMMANDS, GLOBAL_OPTIONS } from "./commands.js";
|
|
16
|
+
import { failure, ok } from "./output.js";
|
|
17
|
+
/** Runs one CLI invocation and returns its outcome (exported for tests). */
|
|
18
|
+
export async function runCli(argv) {
|
|
19
|
+
const command = argv[0] && !argv[0].startsWith('-') ? argv[0] : 'help';
|
|
20
|
+
const spec = COMMANDS.find((c) => c.name === command);
|
|
21
|
+
const json = argv.includes('--json');
|
|
22
|
+
if (!spec) {
|
|
23
|
+
const err = new YaliError('UNKNOWN_COMMAND', `yali has no command ${command}.`, `Commands: ${COMMANDS.map((c) => c.name).join(', ')}. Run \`yali help\`.`);
|
|
24
|
+
return { outcome: failure(command, err), json, keepAlive: false };
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const options = {};
|
|
28
|
+
for (const o of [...spec.options, ...GLOBAL_OPTIONS])
|
|
29
|
+
options[o.name] = { type: o.type };
|
|
30
|
+
const { values, positionals } = parseArgs({ args: argv.slice(1), options, allowPositionals: true, strict: true });
|
|
31
|
+
const v = values;
|
|
32
|
+
const s = (k) => v[k];
|
|
33
|
+
switch (spec.name) {
|
|
34
|
+
case 'help':
|
|
35
|
+
return {
|
|
36
|
+
outcome: ok('help', { commands: COMMANDS, globalOptions: GLOBAL_OPTIONS, exitCodes: { 0: 'ok', 1: 'error', 3: 'over a budget' } }, [
|
|
37
|
+
'yali <command> [options] [--json]',
|
|
38
|
+
'',
|
|
39
|
+
...COMMANDS.map((c) => ` ${c.name.padEnd(8)} ${c.summary}\n ${c.usage}`),
|
|
40
|
+
'',
|
|
41
|
+
'Every command takes --json and prints one envelope { ok, command, result | error }.',
|
|
42
|
+
]),
|
|
43
|
+
json,
|
|
44
|
+
keepAlive: false,
|
|
45
|
+
};
|
|
46
|
+
case 'create':
|
|
47
|
+
return { outcome: createCommand({ dir: positionals[0], port: s('port') }), json, keepAlive: false };
|
|
48
|
+
case 'dev':
|
|
49
|
+
return { outcome: await devCommand({ root: s('root'), json }), json, keepAlive: true };
|
|
50
|
+
case 'build':
|
|
51
|
+
return { outcome: await buildCommand({ root: s('root'), json, report: v.report === true }), json, keepAlive: false };
|
|
52
|
+
case 'bench':
|
|
53
|
+
return {
|
|
54
|
+
outcome: await benchCommand({ root: s('root'), url: s('url'), query: s('query'), seconds: s('seconds'), out: s('out'), cdpPort: s('cdp-port'), probe: s('probe') }),
|
|
55
|
+
json,
|
|
56
|
+
keepAlive: false,
|
|
57
|
+
};
|
|
58
|
+
case 'headless':
|
|
59
|
+
return {
|
|
60
|
+
outcome: await headlessCommand({ root: s('root'), frames: s('frames'), seed: s('seed'), query: s('query'), recording: s('recording'), expect: s('expect') }),
|
|
61
|
+
json,
|
|
62
|
+
keepAlive: false,
|
|
63
|
+
};
|
|
64
|
+
case 'test':
|
|
65
|
+
return { outcome: await testCommand({ root: s('root'), files: positionals }), json, keepAlive: false };
|
|
66
|
+
case 'inspect':
|
|
67
|
+
return { outcome: await inspectCommand({ root: s('root'), live: v.live === true, url: s('url'), cdpPort: s('cdp-port'), probe: s('probe') }), json, keepAlive: false };
|
|
68
|
+
case 'game':
|
|
69
|
+
return { outcome: await gameCommand({ crate: s('crate'), out: s('out'), threads: v.threads === true, dev: v.dev === true, features: s('features'), json }), json, keepAlive: false };
|
|
70
|
+
case 'convert':
|
|
71
|
+
return { outcome: await convertCommand({ input: positionals[0], output: positionals[1], maxSize: s('max-size'), rdo: s('rdo'), collision: v.collision === true, clusters: v.clusters === true, stream: v.stream === true, pageKb: s('page-kb'), clusterMin: s('cluster-min'), json }), json, keepAlive: false };
|
|
72
|
+
default:
|
|
73
|
+
throw new YaliError('UNKNOWN_COMMAND', `Unhandled command ${spec.name}.`, 'This is a CLI bug.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const e = err instanceof TypeError && 'code' in err && String(err.code).startsWith('ERR_PARSE_ARGS')
|
|
78
|
+
? new YaliError('BAD_OPTION', err.message, `Usage: ${spec.usage}. Run \`yali help --json\` for every option.`)
|
|
79
|
+
: err;
|
|
80
|
+
return { outcome: failure(command, e), json, keepAlive: false };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Outcome } from './output.ts';
|
|
2
|
+
/** Exit code when the bench ran but the frame is over budget. */
|
|
3
|
+
export declare const EXIT_OVER_FRAME_BUDGET = 3;
|
|
4
|
+
/**
|
|
5
|
+
* `yali bench`: opens the running app in a CDP browser, lets it run, and reads the profiler
|
|
6
|
+
* through the page's tools probe (`globalThis.__yali.profile()` by default). The frame
|
|
7
|
+
* interval p95 is checked against `frame_ms.desktop`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function benchCommand(opts: {
|
|
10
|
+
root?: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
query?: string;
|
|
13
|
+
seconds?: string;
|
|
14
|
+
out?: string;
|
|
15
|
+
cdpPort?: string;
|
|
16
|
+
probe?: string;
|
|
17
|
+
}): Promise<Outcome>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { YaliError } from '@yali-engine/core';
|
|
4
|
+
import { loadBudgets } from "./budgets.js";
|
|
5
|
+
import { openPage } from "./cdp.js";
|
|
6
|
+
import { ok } from "./output.js";
|
|
7
|
+
import { cdpPort, loadProject, pageUrl } from "./project.js";
|
|
8
|
+
/** Exit code when the bench ran but the frame is over budget. */
|
|
9
|
+
export const EXIT_OVER_FRAME_BUDGET = 3;
|
|
10
|
+
/**
|
|
11
|
+
* `yali bench`: opens the running app in a CDP browser, lets it run, and reads the profiler
|
|
12
|
+
* through the page's tools probe (`globalThis.__yali.profile()` by default). The frame
|
|
13
|
+
* interval p95 is checked against `frame_ms.desktop`.
|
|
14
|
+
*/
|
|
15
|
+
export async function benchCommand(opts) {
|
|
16
|
+
const project = await loadProject(opts.root);
|
|
17
|
+
const url = pageUrl(project, opts.url, opts.query);
|
|
18
|
+
const seconds = Number(opts.seconds ?? 6);
|
|
19
|
+
if (!(seconds > 0))
|
|
20
|
+
throw new YaliError('BAD_OPTION', `--seconds must be positive, got ${opts.seconds}.`, 'Pass e.g. --seconds 6.');
|
|
21
|
+
const probe = opts.probe ?? '__yali';
|
|
22
|
+
const page = await openPage(url, cdpPort(opts.cdpPort));
|
|
23
|
+
let read;
|
|
24
|
+
try {
|
|
25
|
+
await new Promise((r) => setTimeout(r, seconds * 1000));
|
|
26
|
+
read = await page.evaluate(`(() => {
|
|
27
|
+
const p = globalThis[${JSON.stringify(probe)}];
|
|
28
|
+
if (!p || typeof p.profile !== 'function') return null;
|
|
29
|
+
return { profile: p.profile(), quality: p.quality ? p.quality() : null, userAgent: navigator.userAgent,
|
|
30
|
+
error: document.getElementById('error')?.textContent || null };
|
|
31
|
+
})()`);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
await page.close();
|
|
35
|
+
}
|
|
36
|
+
if (!read) {
|
|
37
|
+
throw new YaliError('NO_PROBE', `${url} has no globalThis.${probe}.profile().`, `Expose the tools probe in the app: globalThis.${probe} = { profile: (w) => app.profiler.snapshot(w), quality: () => app.quality.knobs() }.`);
|
|
38
|
+
}
|
|
39
|
+
const { budgets } = loadBudgets(project.root);
|
|
40
|
+
const p = read.profile;
|
|
41
|
+
const budget = budgets.frame_ms.desktop;
|
|
42
|
+
// The interval is vsync-locked: a 60 Hz frame is 16.67 ms against a 16.6 ms budget, so
|
|
43
|
+
// the check allows 5 %. A missed frame shows as 33 ms and fails it.
|
|
44
|
+
const withinBudget = p.interval.p95 <= budget * 1.05 && !read.error;
|
|
45
|
+
const result = {
|
|
46
|
+
url,
|
|
47
|
+
seconds,
|
|
48
|
+
userAgent: read.userAgent,
|
|
49
|
+
fps: Math.round(p.fps * 10) / 10,
|
|
50
|
+
frameMs: { p50: p.interval.p50, p95: p.interval.p95, budget },
|
|
51
|
+
cpuMs: p.cpu,
|
|
52
|
+
gpuMs: p.gpu,
|
|
53
|
+
withinBudget,
|
|
54
|
+
pageError: read.error,
|
|
55
|
+
consoleErrors: [...page.errors],
|
|
56
|
+
quality: read.quality,
|
|
57
|
+
profile: p,
|
|
58
|
+
};
|
|
59
|
+
if (opts.out) {
|
|
60
|
+
const out = resolve(project.root, opts.out);
|
|
61
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
62
|
+
writeFileSync(out, `${JSON.stringify(result, null, 2)}\n`);
|
|
63
|
+
}
|
|
64
|
+
const text = [
|
|
65
|
+
`${url} ${result.fps} fps`,
|
|
66
|
+
`frame p50 ${p.interval.p50.toFixed(2)} ms p95 ${p.interval.p95.toFixed(2)} ms (budget ${budget} ms)`,
|
|
67
|
+
`cpu p50 ${p.cpu.p50.toFixed(2)} ms p95 ${p.cpu.p95.toFixed(2)} ms${p.gpu ? ` gpu mean ${p.gpu.mean.toFixed(2)} ms` : ''}`,
|
|
68
|
+
...p.scopes.filter((s) => s.category !== 'frame' && s.category !== 'stage').slice(0, 6).map((s) => ` ${s.name.padEnd(24)} mean ${s.mean.toFixed(3)} p95 ${s.p95.toFixed(3)} ms`),
|
|
69
|
+
...(read.error ? [`page error: ${read.error}`] : []),
|
|
70
|
+
withinBudget ? 'within budget' : 'OVER BUDGET',
|
|
71
|
+
];
|
|
72
|
+
return ok('bench', result, text, withinBudget ? 0 : EXIT_OVER_FRAME_BUDGET);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=cmd-bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-bench.js","sourceRoot":"","sources":["../src/cmd-bench.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Outcome } from './output.ts';
|
|
2
|
+
/** Exit code when the build succeeded but is over a size budget. */
|
|
3
|
+
export declare const EXIT_OVER_BUDGET = 3;
|
|
4
|
+
/**
|
|
5
|
+
* `yali build`: Vite build, then the size report against budgets.json. `report`: the sizes are
|
|
6
|
+
* reported and never fail the build (a demo page with app code; the engine is gated on its own
|
|
7
|
+
* reference page, ADR-0106).
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildCommand(opts: {
|
|
10
|
+
root?: string;
|
|
11
|
+
json: boolean;
|
|
12
|
+
report?: boolean;
|
|
13
|
+
}): Promise<Outcome>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { yali } from '@yali-engine/vite';
|
|
3
|
+
import { build as viteBuild, resolveConfig } from 'vite';
|
|
4
|
+
import { loadBudgets } from "./budgets.js";
|
|
5
|
+
import { ok } from "./output.js";
|
|
6
|
+
import { loadProject } from "./project.js";
|
|
7
|
+
import { sizeReport } from "./size.js";
|
|
8
|
+
/** Exit code when the build succeeded but is over a size budget. */
|
|
9
|
+
export const EXIT_OVER_BUDGET = 3;
|
|
10
|
+
/**
|
|
11
|
+
* `yali build`: Vite build, then the size report against budgets.json. `report`: the sizes are
|
|
12
|
+
* reported and never fail the build (a demo page with app code; the engine is gated on its own
|
|
13
|
+
* reference page, ADR-0106).
|
|
14
|
+
*/
|
|
15
|
+
export async function buildCommand(opts) {
|
|
16
|
+
const project = await loadProject(opts.root);
|
|
17
|
+
const inline = {
|
|
18
|
+
root: project.root,
|
|
19
|
+
configFile: project.viteConfig ?? false,
|
|
20
|
+
plugins: project.viteConfig ? [] : [yali()],
|
|
21
|
+
logLevel: opts.json ? 'silent' : 'info',
|
|
22
|
+
};
|
|
23
|
+
const t0 = performance.now();
|
|
24
|
+
await viteBuild(inline);
|
|
25
|
+
const ms = Math.round(performance.now() - t0);
|
|
26
|
+
const resolved = await resolveConfig(inline, 'build');
|
|
27
|
+
const outDir = resolve(project.root, resolved.build.outDir);
|
|
28
|
+
const { budgets, file } = loadBudgets(project.root);
|
|
29
|
+
const size = sizeReport(outDir, budgets);
|
|
30
|
+
const text = [
|
|
31
|
+
`built ${outDir} in ${ms} ms`,
|
|
32
|
+
...size.files.map((f) => ` ${f.path.padEnd(48)} ${f.brotliKb.toFixed(1).padStart(7)} KB br`),
|
|
33
|
+
`page total ${size.totalKb} of ${size.budgetKb} KB, threaded ${size.threadedTotalKb} of ${size.threadedBudgetKb} KB; core wasm ${size.wasmKb} of ${size.wasmBudgetKb} KB`,
|
|
34
|
+
...size.fallbacks.map((f) => `fallback ${f.name} ${f.kb} of ${f.budgetKb} KB (not in the totals): ${f.files.join(', ') || 'none'}`),
|
|
35
|
+
`workers only ${size.workerKb} KB, content ${size.contentKb} KB (reported, not budgeted)`,
|
|
36
|
+
opts.report ? `reported only (--report): ${size.withinBudget ? 'within' : 'over'} the budgets` : size.withinBudget ? 'within budget' : 'OVER BUDGET',
|
|
37
|
+
];
|
|
38
|
+
return ok('build', { outDir, ms, budgetsFile: file, size, report: !!opts.report }, text, size.withinBudget || opts.report ? 0 : EXIT_OVER_BUDGET);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=cmd-build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-build.js","sourceRoot":"","sources":["../src/cmd-build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Outcome } from './output.ts';
|
|
2
|
+
export interface ConvertOptions {
|
|
3
|
+
readonly input?: string;
|
|
4
|
+
readonly output?: string;
|
|
5
|
+
/** The largest texture side (default 2048: T2's size class). */
|
|
6
|
+
readonly maxSize?: string;
|
|
7
|
+
/** UASTC rate-distortion optimisation, the quality scalar (0: off). */
|
|
8
|
+
readonly rdo?: string;
|
|
9
|
+
/** Also write the level's collision (`<name>.collision.bin`). */
|
|
10
|
+
readonly collision?: boolean;
|
|
11
|
+
/** Store each big primitive's cluster LOD hierarchy in the GLB (`YALI_clusters`, ADR-0121). */
|
|
12
|
+
readonly clusters?: boolean;
|
|
13
|
+
/** The fewest triangles a primitive needs for --clusters (default 4096, `meshlets()`' own). */
|
|
14
|
+
readonly clusterMin?: string;
|
|
15
|
+
/** With --clusters: cut each hierarchy into streaming pages (`YALI_cluster_pages`, ADR-0134), the roots in the GLB and the rest in `<name>.pages.bin`. */
|
|
16
|
+
readonly stream?: boolean;
|
|
17
|
+
/** The most bytes a page holds on the GPU (default 65536). */
|
|
18
|
+
readonly pageKb?: string;
|
|
19
|
+
/** The texture encoder: `auto` (default: native basisu 1.60 if found, else WASM), `wasm`, `native` (ADR-0097). */
|
|
20
|
+
readonly encoder?: string;
|
|
21
|
+
readonly json: boolean;
|
|
22
|
+
/** Where --json's progress lines go (default stderr). */
|
|
23
|
+
readonly emit?: (line: string) => void;
|
|
24
|
+
}
|
|
25
|
+
/** Bilinear resample of RGBA8 `w × h` to a `size²` square (each output texel samples its centre). */
|
|
26
|
+
export declare function resampleSquare(rgba: Uint8Array, w: number, h: number, size: number): Uint8Array;
|
|
27
|
+
export declare function convertCommand(opts: ConvertOptions): Promise<Outcome>;
|