@elaraai/e3-ui-cli 1.0.28
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/CLA.md +26 -0
- package/CONTRIBUTING.md +28 -0
- package/LICENSE.md +31 -0
- package/README.md +158 -0
- package/bin/e3-ui.mjs +13 -0
- package/dist/app/assets/dm-sans-latin-ext-wght-normal-BOFOeGcA.woff2 +0 -0
- package/dist/app/assets/dm-sans-latin-wght-normal-Xz1IZZA0.woff2 +0 -0
- package/dist/app/assets/engine-Daqj4eDD-BQb68g_1.js +4 -0
- package/dist/app/assets/index-30g1JIHt.js +2255 -0
- package/dist/app/assets/index-CYR-0Grb.css +1 -0
- package/dist/app/assets/inter-tight-cyrillic-ext-wght-normal-okcGN4Nq.woff2 +0 -0
- package/dist/app/assets/inter-tight-cyrillic-wght-normal-BS41q_Tv.woff2 +0 -0
- package/dist/app/assets/inter-tight-greek-ext-wght-normal-DQgQPNk4.woff2 +0 -0
- package/dist/app/assets/inter-tight-greek-wght-normal-sS1B39LI.woff2 +0 -0
- package/dist/app/assets/inter-tight-latin-ext-wght-normal-B4u9PlvR.woff2 +0 -0
- package/dist/app/assets/inter-tight-latin-wght-normal-DX-nOvPD.woff2 +0 -0
- package/dist/app/assets/inter-tight-vietnamese-wght-normal-TKKdAiBA.woff2 +0 -0
- package/dist/app/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/app/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/app/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/app/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/app/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/app/index.html +13 -0
- package/dist/browser.d.ts +88 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +249 -0
- package/dist/browser.js.map +1 -0
- package/dist/capture.d.ts +80 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +275 -0
- package/dist/capture.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/shot.d.ts +42 -0
- package/dist/commands/shot.d.ts.map +1 -0
- package/dist/commands/shot.js +134 -0
- package/dist/commands/shot.js.map +1 -0
- package/dist/e3-server.d.ts +21 -0
- package/dist/e3-server.d.ts.map +1 -0
- package/dist/e3-server.js +34 -0
- package/dist/e3-server.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/load-source.d.ts +21 -0
- package/dist/load-source.d.ts.map +1 -0
- package/dist/load-source.js +163 -0
- package/dist/load-source.js.map +1 -0
- package/dist/payload.d.ts +26 -0
- package/dist/payload.d.ts.map +1 -0
- package/dist/payload.js +87 -0
- package/dist/payload.js.map +1 -0
- package/dist/render.d.ts +80 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +79 -0
- package/dist/render.js.map +1 -0
- package/dist/shot-payload.d.ts +31 -0
- package/dist/shot-payload.d.ts.map +1 -0
- package/dist/shot-payload.js +6 -0
- package/dist/shot-payload.js.map +1 -0
- package/package.json +82 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Programmatic API for `@elaraai/e3-ui-cli` — render east-ui / e3-ui components
|
|
7
|
+
* to PNG without the CLI. The command-line entry lives in `cli.ts`.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
export { renderToPng, renderTaskToPng, defaultAppDir, type RenderToPngOptions, type RenderTaskOptions } from './render.js';
|
|
12
|
+
export { buildPayload, detectFormat, type ShotInput, type ShotPayload, type ComponentPayload, type TaskPayload, type InputFormat, } from './payload.js';
|
|
13
|
+
export { capture, type CaptureOptions, type CaptureMode } from './capture.js';
|
|
14
|
+
export { loadComponentFromSource, type EastFunctionLike } from './load-source.js';
|
|
15
|
+
export { startRepoServer, type RepoServerHandle } from './e3-server.js';
|
|
16
|
+
export { launchBrowser, installBrowser, doctor, type BrowserSource } from './browser.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3H,OAAO,EACH,YAAY,EAAE,YAAY,EAC1B,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,GAC9F,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Programmatic API for `@elaraai/e3-ui-cli` — render east-ui / e3-ui components
|
|
7
|
+
* to PNG without the CLI. The command-line entry lives in `cli.ts`.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
export { renderToPng, renderTaskToPng, defaultAppDir } from './render.js';
|
|
12
|
+
export { buildPayload, detectFormat, } from './payload.js';
|
|
13
|
+
export { capture } from './capture.js';
|
|
14
|
+
export { loadComponentFromSource } from './load-source.js';
|
|
15
|
+
export { startRepoServer } from './e3-server.js';
|
|
16
|
+
export { launchBrowser, installBrowser, doctor } from './browser.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAC3H,OAAO,EACH,YAAY,EAAE,YAAY,GAE7B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAyC,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAyB,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAyB,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/** Minimal shape of an East function — anything carrying a `toIR()`. East
|
|
6
|
+
* functions are callable, so they are `typeof === 'function'`, not 'object'. */
|
|
7
|
+
export interface EastFunctionLike {
|
|
8
|
+
toIR(): unknown;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Transpile, execute, and extract an East UI function from a `.ts`/`.tsx` source.
|
|
12
|
+
*
|
|
13
|
+
* @param filePath - Path to the source file
|
|
14
|
+
* @param exportName - Named export to render; when omitted, falls back to the
|
|
15
|
+
* `default` export, then to the sole renderable export
|
|
16
|
+
* @returns The East function (carrying `toIR()`)
|
|
17
|
+
* @throws If the file produces no renderable export, or `exportName` is absent
|
|
18
|
+
* or not renderable
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadComponentFromSource(filePath: string, exportName?: string): Promise<EastFunctionLike>;
|
|
21
|
+
//# sourceMappingURL=load-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-source.d.ts","sourceRoot":"","sources":["../src/load-source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH;iFACiF;AACjF,MAAM,WAAW,gBAAgB;IAC7B,IAAI,IAAI,OAAO,CAAC;CACnB;AAoFD;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CACzC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAsE3B"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Load an East UI function from a TypeScript/TSX source file — without writing
|
|
7
|
+
* any temp files.
|
|
8
|
+
*
|
|
9
|
+
* esbuild transpiles + bundles the entry IN MEMORY, then it is executed via a
|
|
10
|
+
* `data:` URL `import()`. Bare `@elaraai/*` (and other package) imports are
|
|
11
|
+
* resolved from the source file to absolute `file://` URLs and kept external,
|
|
12
|
+
* so the East runtime the source imports is the SAME instance this CLI encodes
|
|
13
|
+
* with (single-instance type identity matters for IR serialization) and nothing
|
|
14
|
+
* is ever written to disk. JSX is forced to the automatic `@elaraai/east-ui`
|
|
15
|
+
* runtime, matching how east-ui components are authored.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
import { createRequire } from 'node:module';
|
|
20
|
+
import { pathToFileURL } from 'node:url';
|
|
21
|
+
import * as path from 'node:path';
|
|
22
|
+
import * as fs from 'node:fs';
|
|
23
|
+
import * as esbuild from 'esbuild';
|
|
24
|
+
function hasToIR(x) {
|
|
25
|
+
return (typeof x === 'function' || (typeof x === 'object' && x !== null))
|
|
26
|
+
&& typeof x.toIR === 'function';
|
|
27
|
+
}
|
|
28
|
+
function isExampleDef(x) {
|
|
29
|
+
return typeof x === 'object' && x !== null && hasToIR(x.fn);
|
|
30
|
+
}
|
|
31
|
+
function isUiTaskDef(x) {
|
|
32
|
+
if (typeof x !== 'object' || x === null)
|
|
33
|
+
return false;
|
|
34
|
+
const t = x;
|
|
35
|
+
return t.kind === 'task'
|
|
36
|
+
&& t.taskKind === 'ui'
|
|
37
|
+
&& Array.isArray(t.inputs)
|
|
38
|
+
&& t.inputs[0]?.name === 'function_ir'
|
|
39
|
+
&& t.inputs[0].default != null;
|
|
40
|
+
}
|
|
41
|
+
const PARAMETERIZED_UI_TASK_MESSAGE = `it is a ui() task with compute-time inputs, which a standalone render cannot supply — ` +
|
|
42
|
+
`render it from a deployed workspace instead: e3-ui shot --from-task <workspace>.<task> --repo <path>`;
|
|
43
|
+
/**
|
|
44
|
+
* Pull the East function out of an export: a bare fn, an `example()` def, or a
|
|
45
|
+
* zero-input e3 `ui()` task (unwrapped to its stored `fn.toIR()` bundle). A
|
|
46
|
+
* ui() task WITH compute-time inputs (`inputs.length > 1` — inputs[0] is
|
|
47
|
+
* always the function_ir dataset) is not renderable standalone; callers
|
|
48
|
+
* surface {@link PARAMETERIZED_UI_TASK_MESSAGE} for those.
|
|
49
|
+
*/
|
|
50
|
+
function asEastFunction(value) {
|
|
51
|
+
if (hasToIR(value))
|
|
52
|
+
return value;
|
|
53
|
+
if (isExampleDef(value))
|
|
54
|
+
return value.fn;
|
|
55
|
+
if (isUiTaskDef(value) && value.inputs.length === 1) {
|
|
56
|
+
const bundle = value.inputs[0].default;
|
|
57
|
+
return { toIR: () => bundle };
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* esbuild plugin: keep every bare (package) import external, resolved from its
|
|
63
|
+
* importer to an absolute `file://` URL so the `data:`-URL bundle can load it
|
|
64
|
+
* with Node's own resolver (preserving a single `@elaraai/east` instance).
|
|
65
|
+
* Relative/absolute source imports are bundled normally.
|
|
66
|
+
*/
|
|
67
|
+
const externalizeBareImports = {
|
|
68
|
+
name: 'externalize-bare-imports',
|
|
69
|
+
setup(build) {
|
|
70
|
+
build.onResolve({ filter: /.*/ }, args => {
|
|
71
|
+
if (args.kind === 'entry-point')
|
|
72
|
+
return null;
|
|
73
|
+
const spec = args.path;
|
|
74
|
+
if (spec.startsWith('node:'))
|
|
75
|
+
return { path: spec, external: true };
|
|
76
|
+
if (spec.startsWith('.') || path.isAbsolute(spec))
|
|
77
|
+
return null; // bundle source files
|
|
78
|
+
// Bare package import → resolve from the importer, externalize.
|
|
79
|
+
try {
|
|
80
|
+
const resolved = createRequire(args.importer).resolve(spec);
|
|
81
|
+
return { path: pathToFileURL(resolved).href, external: true };
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null; // let esbuild surface the resolution error
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Transpile, execute, and extract an East UI function from a `.ts`/`.tsx` source.
|
|
91
|
+
*
|
|
92
|
+
* @param filePath - Path to the source file
|
|
93
|
+
* @param exportName - Named export to render; when omitted, falls back to the
|
|
94
|
+
* `default` export, then to the sole renderable export
|
|
95
|
+
* @returns The East function (carrying `toIR()`)
|
|
96
|
+
* @throws If the file produces no renderable export, or `exportName` is absent
|
|
97
|
+
* or not renderable
|
|
98
|
+
*/
|
|
99
|
+
export async function loadComponentFromSource(filePath, exportName) {
|
|
100
|
+
const absolutePath = path.resolve(filePath);
|
|
101
|
+
if (!fs.existsSync(absolutePath)) {
|
|
102
|
+
throw new Error(`Source file not found: ${absolutePath}`);
|
|
103
|
+
}
|
|
104
|
+
const result = await esbuild.build({
|
|
105
|
+
entryPoints: [absolutePath],
|
|
106
|
+
bundle: true,
|
|
107
|
+
platform: 'node',
|
|
108
|
+
format: 'esm',
|
|
109
|
+
write: false,
|
|
110
|
+
jsx: 'automatic',
|
|
111
|
+
jsxImportSource: '@elaraai/east-ui',
|
|
112
|
+
plugins: [externalizeBareImports],
|
|
113
|
+
logLevel: 'silent',
|
|
114
|
+
});
|
|
115
|
+
const code = result.outputFiles?.[0]?.text;
|
|
116
|
+
if (!code) {
|
|
117
|
+
throw new Error(`esbuild produced no output for ${filePath}`);
|
|
118
|
+
}
|
|
119
|
+
let moduleExports;
|
|
120
|
+
try {
|
|
121
|
+
const dataUrl = `data:text/javascript;base64,${Buffer.from(code).toString('base64')}`;
|
|
122
|
+
moduleExports = await import(dataUrl);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
throw new Error(`Failed to execute ${path.basename(filePath)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
126
|
+
}
|
|
127
|
+
if (exportName !== undefined) {
|
|
128
|
+
const fn = asEastFunction(moduleExports[exportName]);
|
|
129
|
+
if (!fn) {
|
|
130
|
+
if (isUiTaskDef(moduleExports[exportName])) {
|
|
131
|
+
throw new Error(`Cannot render export "${exportName}" in ${path.basename(filePath)}: ${PARAMETERIZED_UI_TASK_MESSAGE}`);
|
|
132
|
+
}
|
|
133
|
+
const available = renderableExportNames(moduleExports);
|
|
134
|
+
throw new Error(`Export "${exportName}" is not a renderable East UI function in ${path.basename(filePath)}.` +
|
|
135
|
+
(available.length ? ` Available: ${available.join(', ')}` : ' No renderable exports found.'));
|
|
136
|
+
}
|
|
137
|
+
return fn;
|
|
138
|
+
}
|
|
139
|
+
const fromDefault = asEastFunction(moduleExports['default']);
|
|
140
|
+
if (fromDefault)
|
|
141
|
+
return fromDefault;
|
|
142
|
+
const renderable = Object.entries(moduleExports)
|
|
143
|
+
.map(([name, value]) => [name, asEastFunction(value)])
|
|
144
|
+
.filter((e) => e[1] !== null);
|
|
145
|
+
if (renderable.length === 1)
|
|
146
|
+
return renderable[0][1];
|
|
147
|
+
if (renderable.length === 0) {
|
|
148
|
+
const parameterized = Object.entries(moduleExports).find(([, v]) => isUiTaskDef(v));
|
|
149
|
+
if (parameterized) {
|
|
150
|
+
throw new Error(`Cannot render export "${parameterized[0]}" in ${path.basename(filePath)}: ${PARAMETERIZED_UI_TASK_MESSAGE}`);
|
|
151
|
+
}
|
|
152
|
+
throw new Error(`No renderable East UI function found in ${path.basename(filePath)}. ` +
|
|
153
|
+
`Export a default East function returning a UIComponentType (or an example({ fn })).`);
|
|
154
|
+
}
|
|
155
|
+
throw new Error(`Multiple renderable exports in ${path.basename(filePath)} — pass --export <name>. ` +
|
|
156
|
+
`Available: ${renderable.map(([n]) => n).join(', ')}`);
|
|
157
|
+
}
|
|
158
|
+
function renderableExportNames(moduleExports) {
|
|
159
|
+
return Object.entries(moduleExports)
|
|
160
|
+
.filter(([, value]) => asEastFunction(value) !== null)
|
|
161
|
+
.map(([name]) => name);
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=load-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-source.js","sourceRoot":"","sources":["../src/load-source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAanC,SAAS,OAAO,CAAC,CAAU;IACvB,OAAO,CAAC,OAAO,CAAC,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;WAClE,OAAQ,CAAwB,CAAC,IAAI,KAAK,UAAU,CAAC;AAChE,CAAC;AAED,SAAS,YAAY,CAAC,CAAU;IAC5B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAE,CAAsB,CAAC,EAAE,CAAC,CAAC;AACtF,CAAC;AAcD,SAAS,WAAW,CAAC,CAAU;IAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,CAAC,GAAG,CAA6D,CAAC;IACxE,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM;WACjB,CAAC,CAAC,QAAQ,KAAK,IAAI;WACnB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;WACtB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAoC,EAAE,IAAI,KAAK,aAAa;WACtE,CAAC,CAAC,MAAM,CAAC,CAAC,CAA2B,CAAC,OAAO,IAAI,IAAI,CAAC;AAClE,CAAC;AAED,MAAM,6BAA6B,GAC/B,wFAAwF;IACxF,sGAAsG,CAAC;AAE3G;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,KAAc;IAClC,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,CAAC;IACzC,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,sBAAsB,GAAmB;IAC3C,IAAI,EAAE,0BAA0B;IAChC,KAAK,CAAC,KAAK;QACP,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE;YACrC,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO,IAAI,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACpE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;YACtF,gEAAgE;YAChE,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC5D,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAClE,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,IAAI,CAAC,CAAC,2CAA2C;YAC5D,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CACzC,QAAgB,EAChB,UAAmB;IAEnB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;QAC/B,WAAW,EAAE,CAAC,YAAY,CAAC;QAC3B,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,KAAK;QACZ,GAAG,EAAE,WAAW;QAChB,eAAe,EAAE,kBAAkB;QACnC,OAAO,EAAE,CAAC,sBAAsB,CAAC;QACjC,QAAQ,EAAE,QAAQ;KACrB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,aAAsC,CAAC;IAC3C,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,+BAA+B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtF,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAA4B,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACX,qBAAqB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACtG,CAAC;IACN,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,cAAc,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,EAAE,CAAC;YACN,IAAI,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,6BAA6B,EAAE,CAAC,CAAC;YAC5H,CAAC;YACD,MAAM,SAAS,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;YACvD,MAAM,IAAI,KAAK,CACX,WAAW,UAAU,6CAA6C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG;gBAC5F,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAC/F,CAAC;QACN,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7D,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;SAC3C,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,CAAU,CAAC;SAC9D,MAAM,CAAC,CAAC,CAAC,EAA4C,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAE5E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,IAAI,aAAa,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,yBAAyB,aAAa,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,6BAA6B,EAAE,CAAC,CAAC;QAClI,CAAC;QACD,MAAM,IAAI,KAAK,CACX,2CAA2C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI;YACtE,qFAAqF,CACxF,CAAC;IACN,CAAC;IACD,MAAM,IAAI,KAAK,CACX,kCAAkC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,2BAA2B;QACpF,cAAc,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxD,CAAC;AACN,CAAC;AAED,SAAS,qBAAqB,CAAC,aAAsC;IACjE,OAAO,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
export type { ComponentPayload, TaskPayload, ShotPayload } from './shot-payload.js';
|
|
6
|
+
import type { ComponentPayload } from './shot-payload.js';
|
|
7
|
+
/** Recognised input formats. `ts` covers `.ts` and `.tsx`. */
|
|
8
|
+
export type InputFormat = 'ts' | 'beast2' | 'json';
|
|
9
|
+
/** A resolved component input. `path: null` reads from stdin. */
|
|
10
|
+
export interface ShotInput {
|
|
11
|
+
path: string | null;
|
|
12
|
+
from?: InputFormat | undefined;
|
|
13
|
+
exportName?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
/** Detect the input format from a file extension. */
|
|
16
|
+
export declare function detectFormat(filePath: string): InputFormat;
|
|
17
|
+
/**
|
|
18
|
+
* Build the render payload from a component input.
|
|
19
|
+
*
|
|
20
|
+
* @param input - The resolved input (path/format/export)
|
|
21
|
+
* @returns The base64 IR payload for the browser app
|
|
22
|
+
* @throws If a `.ts`/`.tsx` source is read from stdin, on JSON/IR decode
|
|
23
|
+
* failure, or when the input is not a renderable East UI function
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildPayload(input: ShotInput): Promise<ComponentPayload>;
|
|
26
|
+
//# sourceMappingURL=payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,8DAA8D;AAC9D,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEnD,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAQ1D;AASD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyC9E"}
|
package/dist/payload.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Normalise a component input into the render payload the browser app consumes.
|
|
7
|
+
*
|
|
8
|
+
* Every accepted input is reduced to Beast2-encoded **function IR** (base64) —
|
|
9
|
+
* the exact form `EncodedEastFunction` (`@elaraai/east-ui-components`) decodes
|
|
10
|
+
* via `decodeBeast2For(IRType)` and compiles in-browser. The Node→browser
|
|
11
|
+
* serialization boundary decouples the two `@elaraai/east` instances.
|
|
12
|
+
*
|
|
13
|
+
* Format is auto-detected from the file extension (mirroring `e3 convert` /
|
|
14
|
+
* `e3 dataset set`), with an explicit `--from` override.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
import { readFile } from 'node:fs/promises';
|
|
19
|
+
import { extname } from 'node:path';
|
|
20
|
+
import { encodeEastIR, fromJSONFor, decodeEastIR, encodeBeast2For } from '@elaraai/east';
|
|
21
|
+
import { IRType } from '@elaraai/east/internal';
|
|
22
|
+
import { loadComponentFromSource } from './load-source.js';
|
|
23
|
+
/** Detect the input format from a file extension. */
|
|
24
|
+
export function detectFormat(filePath) {
|
|
25
|
+
const ext = extname(filePath).toLowerCase();
|
|
26
|
+
if (ext === '.ts' || ext === '.tsx')
|
|
27
|
+
return 'ts';
|
|
28
|
+
if (ext === '.beast2')
|
|
29
|
+
return 'beast2';
|
|
30
|
+
if (ext === '.json')
|
|
31
|
+
return 'json';
|
|
32
|
+
throw new Error(`Cannot detect format from extension "${ext}" (expected .ts/.tsx, .beast2, or .json) — pass --from`);
|
|
33
|
+
}
|
|
34
|
+
/** Read all of stdin as bytes. */
|
|
35
|
+
async function readStdin() {
|
|
36
|
+
const chunks = [];
|
|
37
|
+
for await (const chunk of process.stdin)
|
|
38
|
+
chunks.push(chunk);
|
|
39
|
+
return new Uint8Array(Buffer.concat(chunks));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build the render payload from a component input.
|
|
43
|
+
*
|
|
44
|
+
* @param input - The resolved input (path/format/export)
|
|
45
|
+
* @returns The base64 IR payload for the browser app
|
|
46
|
+
* @throws If a `.ts`/`.tsx` source is read from stdin, on JSON/IR decode
|
|
47
|
+
* failure, or when the input is not a renderable East UI function
|
|
48
|
+
*/
|
|
49
|
+
export async function buildPayload(input) {
|
|
50
|
+
const format = input.from ?? (input.path ? detectFormat(input.path) : 'beast2');
|
|
51
|
+
let bytes;
|
|
52
|
+
switch (format) {
|
|
53
|
+
case 'ts': {
|
|
54
|
+
if (!input.path) {
|
|
55
|
+
throw new Error('A TypeScript source cannot be read from stdin — pass a file path.');
|
|
56
|
+
}
|
|
57
|
+
const fn = await loadComponentFromSource(input.path, input.exportName);
|
|
58
|
+
bytes = encodeEastIR(fn.toIR());
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'beast2': {
|
|
62
|
+
bytes = input.path ? new Uint8Array(await readFile(input.path)) : await readStdin();
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'json': {
|
|
66
|
+
const text = input.path
|
|
67
|
+
? await readFile(input.path, 'utf8')
|
|
68
|
+
: Buffer.from(await readStdin()).toString('utf8');
|
|
69
|
+
bytes = encodeBeast2For(IRType)(fromJSONFor(IRType)(JSON.parse(text)));
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Uniform validation across all three formats: decodeEastIR throws unless the
|
|
74
|
+
// root IR is a (sync) Function — catching an async function, non-function IR
|
|
75
|
+
// JSON, and an evaluated-value / corrupt .beast2 alike, with one clear Node-side
|
|
76
|
+
// message instead of a confusing in-browser compile failure.
|
|
77
|
+
try {
|
|
78
|
+
decodeEastIR(bytes);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
throw new Error(`Input is not a renderable component — expected a Beast2/JSON-encoded zero-argument East UI function. ` +
|
|
82
|
+
`(Async functions, non-function IR, and evaluated values are not supported.) ` +
|
|
83
|
+
`Cause: ${err instanceof Error ? err.message : String(err)}`);
|
|
84
|
+
}
|
|
85
|
+
return { kind: 'component', b64: Buffer.from(bytes).toString('base64') };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { type ShotInput } from './payload.js';
|
|
6
|
+
import { type CaptureMode } from './capture.js';
|
|
7
|
+
/** Options for {@link renderToPng}. */
|
|
8
|
+
export interface RenderToPngOptions {
|
|
9
|
+
/** The component input (source/serialized + format/export). */
|
|
10
|
+
input: ShotInput;
|
|
11
|
+
/** Output PNG path. */
|
|
12
|
+
output: string;
|
|
13
|
+
/** Also write a self-contained HTML here. */
|
|
14
|
+
html?: string | undefined;
|
|
15
|
+
/** Override the prebuilt app directory (defaults to the shipped `dist/app`). */
|
|
16
|
+
appDir?: string | undefined;
|
|
17
|
+
/** Chromium viewport. */
|
|
18
|
+
viewport?: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/** Device scale factor. */
|
|
23
|
+
deviceScaleFactor?: number | undefined;
|
|
24
|
+
/** Framing. */
|
|
25
|
+
mode?: CaptureMode | undefined;
|
|
26
|
+
/** Settle time after skeletons clear. */
|
|
27
|
+
settleMs?: number | undefined;
|
|
28
|
+
/** Max time to wait for the render to complete. */
|
|
29
|
+
timeoutMs?: number | undefined;
|
|
30
|
+
/** Storage key prefix for persisted component state. */
|
|
31
|
+
storageKey?: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** Resolve the shipped prebuilt app directory (`dist/app`, sibling of this module). */
|
|
34
|
+
export declare function defaultAppDir(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Render a component input to a PNG (and optionally a standalone HTML).
|
|
37
|
+
*
|
|
38
|
+
* @param opts - Render options
|
|
39
|
+
* @throws If the input cannot be decoded, or the component fails to render
|
|
40
|
+
*/
|
|
41
|
+
export declare function renderToPng(opts: RenderToPngOptions): Promise<void>;
|
|
42
|
+
/** Options for {@link renderTaskToPng}. */
|
|
43
|
+
export interface RenderTaskOptions {
|
|
44
|
+
/** Local e3 repository directory. */
|
|
45
|
+
repo: string;
|
|
46
|
+
/** Workspace name. */
|
|
47
|
+
workspace: string;
|
|
48
|
+
/** Task name within the workspace. */
|
|
49
|
+
task: string;
|
|
50
|
+
/** Output PNG path. */
|
|
51
|
+
output: string;
|
|
52
|
+
/** Also write a self-contained HTML here. */
|
|
53
|
+
html?: string | undefined;
|
|
54
|
+
/** Override the prebuilt app directory. */
|
|
55
|
+
appDir?: string | undefined;
|
|
56
|
+
/** Chromium viewport. */
|
|
57
|
+
viewport?: {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
} | undefined;
|
|
61
|
+
/** Device scale factor. */
|
|
62
|
+
deviceScaleFactor?: number | undefined;
|
|
63
|
+
/** Framing. */
|
|
64
|
+
mode?: CaptureMode | undefined;
|
|
65
|
+
/** Settle time (defaults higher than component mode — the task must fetch). */
|
|
66
|
+
settleMs?: number | undefined;
|
|
67
|
+
/** Max time to wait for the task to render (drives the in-app hard-stop too). */
|
|
68
|
+
timeoutMs?: number | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Render a LIVE e3 task's output to a PNG. Starts a local e3 API server over
|
|
72
|
+
* the repo, lets the browser app fetch the already-computed task output + bound
|
|
73
|
+
* datasets, screenshots, and stops the server. The workspace dataflow must have
|
|
74
|
+
* already produced the task's output.
|
|
75
|
+
*
|
|
76
|
+
* @param opts - Render options
|
|
77
|
+
* @throws If the server cannot start, the task fails to render, or capture times out
|
|
78
|
+
*/
|
|
79
|
+
export declare function renderTaskToPng(opts: RenderTaskOptions): Promise<void>;
|
|
80
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAAgB,KAAK,SAAS,EAAoB,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAGzD,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IAC/B,+DAA+D;IAC/D,KAAK,EAAE,SAAS,CAAC;IACjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,yBAAyB;IACzB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACzD,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,eAAe;IACf,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,uFAAuF;AACvF,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAczE;AAED,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAC9B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,yBAAyB;IACzB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACzD,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,eAAe;IACf,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B5E"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Programmatic entry point: normalise an input into a payload and capture it to
|
|
7
|
+
* a PNG. The CLI's `shot` command is a thin wrapper over {@link renderToPng}.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { buildPayload } from './payload.js';
|
|
14
|
+
import { capture } from './capture.js';
|
|
15
|
+
import { startRepoServer } from './e3-server.js';
|
|
16
|
+
/** Resolve the shipped prebuilt app directory (`dist/app`, sibling of this module). */
|
|
17
|
+
export function defaultAppDir() {
|
|
18
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
return path.resolve(here, 'app');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Render a component input to a PNG (and optionally a standalone HTML).
|
|
23
|
+
*
|
|
24
|
+
* @param opts - Render options
|
|
25
|
+
* @throws If the input cannot be decoded, or the component fails to render
|
|
26
|
+
*/
|
|
27
|
+
export async function renderToPng(opts) {
|
|
28
|
+
const payload = await buildPayload(opts.input);
|
|
29
|
+
await capture({
|
|
30
|
+
appDir: opts.appDir ?? defaultAppDir(),
|
|
31
|
+
payload,
|
|
32
|
+
outPng: opts.output,
|
|
33
|
+
outHtml: opts.html,
|
|
34
|
+
storageKey: opts.storageKey,
|
|
35
|
+
viewport: opts.viewport,
|
|
36
|
+
deviceScaleFactor: opts.deviceScaleFactor,
|
|
37
|
+
mode: opts.mode,
|
|
38
|
+
settleMs: opts.settleMs,
|
|
39
|
+
timeoutMs: opts.timeoutMs,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Render a LIVE e3 task's output to a PNG. Starts a local e3 API server over
|
|
44
|
+
* the repo, lets the browser app fetch the already-computed task output + bound
|
|
45
|
+
* datasets, screenshots, and stops the server. The workspace dataflow must have
|
|
46
|
+
* already produced the task's output.
|
|
47
|
+
*
|
|
48
|
+
* @param opts - Render options
|
|
49
|
+
* @throws If the server cannot start, the task fails to render, or capture times out
|
|
50
|
+
*/
|
|
51
|
+
export async function renderTaskToPng(opts) {
|
|
52
|
+
const server = await startRepoServer(opts.repo);
|
|
53
|
+
try {
|
|
54
|
+
const payload = {
|
|
55
|
+
kind: 'task',
|
|
56
|
+
apiUrl: server.apiUrl,
|
|
57
|
+
repo: server.repo,
|
|
58
|
+
workspace: opts.workspace,
|
|
59
|
+
task: opts.task,
|
|
60
|
+
};
|
|
61
|
+
await capture({
|
|
62
|
+
appDir: opts.appDir ?? defaultAppDir(),
|
|
63
|
+
payload,
|
|
64
|
+
outPng: opts.output,
|
|
65
|
+
outHtml: opts.html,
|
|
66
|
+
viewport: opts.viewport,
|
|
67
|
+
deviceScaleFactor: opts.deviceScaleFactor,
|
|
68
|
+
mode: opts.mode,
|
|
69
|
+
// Extra grace after the app reports ready (the task render settles
|
|
70
|
+
// its own async fetches first via the data-shot-status marker).
|
|
71
|
+
settleMs: opts.settleMs ?? 800,
|
|
72
|
+
timeoutMs: opts.timeoutMs,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await server.stop();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAoC,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA0BjD,uFAAuF;AACvF,MAAM,UAAU,aAAa;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAwB;IACtD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,OAAO,CAAC;QACV,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa,EAAE;QACtC,OAAO;QACP,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,IAAI;QAClB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;KAC5B,CAAC,CAAC;AACP,CAAC;AA4BD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAuB;IACzD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC;QACD,MAAM,OAAO,GAAgB;YACzB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;SAClB,CAAC;QACF,MAAM,OAAO,CAAC;YACV,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa,EAAE;YACtC,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,IAAI;YAClB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,mEAAmE;YACnE,gEAAgE;YAChE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG;YAC9B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC5B,CAAC,CAAC;IACP,CAAC;YAAS,CAAC;QACP,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The render payload injected into the browser app as `window.__E3_UI_SHOT__`.
|
|
7
|
+
*
|
|
8
|
+
* This module has NO runtime imports so it can be shared by both the Node CLI
|
|
9
|
+
* (`payload.ts`) and the browser app (`app/main.tsx`) — keeping the Node→browser
|
|
10
|
+
* contract type-checked rather than duplicated.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
/** A standalone component to render: base64 Beast2-encoded function IR
|
|
15
|
+
* (consumed in-browser by `EncodedEastFunction`). */
|
|
16
|
+
export interface ComponentPayload {
|
|
17
|
+
kind: 'component';
|
|
18
|
+
b64: string;
|
|
19
|
+
}
|
|
20
|
+
/** A live e3 task to render: the browser fetches its already-computed output +
|
|
21
|
+
* bound datasets from the server (consumed by `TaskPreview`). */
|
|
22
|
+
export interface TaskPayload {
|
|
23
|
+
kind: 'task';
|
|
24
|
+
apiUrl: string;
|
|
25
|
+
repo: string;
|
|
26
|
+
workspace: string;
|
|
27
|
+
task: string;
|
|
28
|
+
}
|
|
29
|
+
/** The render payload — a component or a live task. */
|
|
30
|
+
export type ShotPayload = ComponentPayload | TaskPayload;
|
|
31
|
+
//# sourceMappingURL=shot-payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shot-payload.d.ts","sourceRoot":"","sources":["../src/shot-payload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;GAQG;AAEH;sDACsD;AACtD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAED;kEACkE;AAClE,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shot-payload.js","sourceRoot":"","sources":["../src/shot-payload.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|