@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.
Files changed (64) hide show
  1. package/CLA.md +26 -0
  2. package/CONTRIBUTING.md +28 -0
  3. package/LICENSE.md +31 -0
  4. package/README.md +158 -0
  5. package/bin/e3-ui.mjs +13 -0
  6. package/dist/app/assets/dm-sans-latin-ext-wght-normal-BOFOeGcA.woff2 +0 -0
  7. package/dist/app/assets/dm-sans-latin-wght-normal-Xz1IZZA0.woff2 +0 -0
  8. package/dist/app/assets/engine-Daqj4eDD-BQb68g_1.js +4 -0
  9. package/dist/app/assets/index-30g1JIHt.js +2255 -0
  10. package/dist/app/assets/index-CYR-0Grb.css +1 -0
  11. package/dist/app/assets/inter-tight-cyrillic-ext-wght-normal-okcGN4Nq.woff2 +0 -0
  12. package/dist/app/assets/inter-tight-cyrillic-wght-normal-BS41q_Tv.woff2 +0 -0
  13. package/dist/app/assets/inter-tight-greek-ext-wght-normal-DQgQPNk4.woff2 +0 -0
  14. package/dist/app/assets/inter-tight-greek-wght-normal-sS1B39LI.woff2 +0 -0
  15. package/dist/app/assets/inter-tight-latin-ext-wght-normal-B4u9PlvR.woff2 +0 -0
  16. package/dist/app/assets/inter-tight-latin-wght-normal-DX-nOvPD.woff2 +0 -0
  17. package/dist/app/assets/inter-tight-vietnamese-wght-normal-TKKdAiBA.woff2 +0 -0
  18. package/dist/app/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  19. package/dist/app/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  20. package/dist/app/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  21. package/dist/app/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  22. package/dist/app/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  23. package/dist/app/index.html +13 -0
  24. package/dist/browser.d.ts +88 -0
  25. package/dist/browser.d.ts.map +1 -0
  26. package/dist/browser.js +249 -0
  27. package/dist/browser.js.map +1 -0
  28. package/dist/capture.d.ts +80 -0
  29. package/dist/capture.d.ts.map +1 -0
  30. package/dist/capture.js +275 -0
  31. package/dist/capture.js.map +1 -0
  32. package/dist/cli.d.ts +6 -0
  33. package/dist/cli.d.ts.map +1 -0
  34. package/dist/cli.js +70 -0
  35. package/dist/cli.js.map +1 -0
  36. package/dist/commands/shot.d.ts +42 -0
  37. package/dist/commands/shot.d.ts.map +1 -0
  38. package/dist/commands/shot.js +134 -0
  39. package/dist/commands/shot.js.map +1 -0
  40. package/dist/e3-server.d.ts +21 -0
  41. package/dist/e3-server.d.ts.map +1 -0
  42. package/dist/e3-server.js +34 -0
  43. package/dist/e3-server.js.map +1 -0
  44. package/dist/index.d.ts +17 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +17 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/load-source.d.ts +21 -0
  49. package/dist/load-source.d.ts.map +1 -0
  50. package/dist/load-source.js +163 -0
  51. package/dist/load-source.js.map +1 -0
  52. package/dist/payload.d.ts +26 -0
  53. package/dist/payload.d.ts.map +1 -0
  54. package/dist/payload.js +87 -0
  55. package/dist/payload.js.map +1 -0
  56. package/dist/render.d.ts +80 -0
  57. package/dist/render.d.ts.map +1 -0
  58. package/dist/render.js +79 -0
  59. package/dist/render.js.map +1 -0
  60. package/dist/shot-payload.d.ts +31 -0
  61. package/dist/shot-payload.d.ts.map +1 -0
  62. package/dist/shot-payload.js +6 -0
  63. package/dist/shot-payload.js.map +1 -0
  64. package/package.json +82 -0
@@ -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":"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"}
@@ -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"}
@@ -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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"}
@@ -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,6 @@
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 {};
6
+ //# sourceMappingURL=shot-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shot-payload.js","sourceRoot":"","sources":["../src/shot-payload.ts"],"names":[],"mappings":"AAAA;;;GAGG"}