@elaraai/east-node-cli 1.0.68 → 1.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,6 +57,35 @@ east-node version
57
57
  east-node version -p @elaraai/east-node-std -p @elaraai/east-node-io
58
58
  ```
59
59
 
60
+ ### Transpiling IR to TypeScript
61
+
62
+ ```bash
63
+ # Print an IR program as East.function builder source
64
+ east-node transpile ./program.beast2 -o program.ts
65
+
66
+ # Every IR file in a directory, plus the IR each printed module builds
67
+ # back — the round-trip check
68
+ east-node transpile ./ir/ -o ./ts/ --rebuild ./rebuilt/
69
+ ```
70
+
71
+ The printed module imports `@elaraai/east` and rebuilds the same IR
72
+ (equal under `east-c ir normalize`): the `$`-forms for statements,
73
+ expression methods and `East.value(..., T)` constructions for values.
74
+ Builtins the TypeScript surface has no spelling for print through
75
+ `East.builtin(...)`. `east-py transpile` is the python twin; the two
76
+ printers and the cross-language sweep are described in
77
+ `docs/conventions/EAST_CODEGEN.md`.
78
+
79
+ ### Exporting functions for another language
80
+
81
+ ```bash
82
+ # Write a module's `eastFunctions` export as a function manifest that a python
83
+ # package (or another TypeScript package) imports with East.import_function /
84
+ # East.importFunction; -p names the platform packages implementing any
85
+ # platform calls the functions make
86
+ east-node export-functions dist/pricing.js -o pricing.functions.beast2 -p @elaraai/east-node-std
87
+ ```
88
+
60
89
  ## CLI Reference
61
90
 
62
91
  ### `east-node run`
@@ -77,6 +106,43 @@ Options:
77
106
  -h, --help Display help
78
107
  ```
79
108
 
109
+ ### `east-node transpile`
110
+
111
+ Print an East IR program as TypeScript `East.function` builder source.
112
+
113
+ ```
114
+ east-node transpile <input> [options]
115
+
116
+ Arguments:
117
+ input Path to an IR file (.beast2, .beast, .east, or .json), or a directory of them
118
+
119
+ Options:
120
+ -o, --output <path> Write the module here (a directory when <input> is one; default: stdout)
121
+ --name <name> The module-level export bound to the rebuilt function (default: main)
122
+ --import-from <specifier> The module the printed source imports East from (default: @elaraai/east)
123
+ --rebuild <path> Import the printed module and write the IR it builds here
124
+ (.beast2 or .json; a directory in directory mode)
125
+ ```
126
+
127
+ ### `east-node export-functions`
128
+
129
+ Write a module's `eastFunctions` export (name → `East.function` result) as a function manifest.
130
+
131
+ ```
132
+ east-node export-functions <module> -o <file> [options]
133
+
134
+ Arguments:
135
+ module Path to the built module exporting `eastFunctions`
136
+
137
+ Options:
138
+ -o, --output <file> The manifest to write (.beast2)
139
+ -p, --package <package...> Platform packages implementing the functions' platform calls
140
+ (every dependency must be provided by one; recorded as its provider)
141
+ --name <name> The package name importers use (default: the module file's stem)
142
+ --package-version <version> The version recorded in the manifest (default: 0.0.0)
143
+ --only <name...> Export only these functions of `eastFunctions` (default: all)
144
+ ```
145
+
80
146
  ### `east-node version`
81
147
 
82
148
  Show version information.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkLH,wBAAgB,IAAI,IAAI,IAAI,CAkC3B"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2PH,wBAAgB,IAAI,IAAI,IAAI,CAwD3B"}
package/dist/cli.js CHANGED
@@ -3,11 +3,15 @@
3
3
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
4
  */
5
5
  import { Command } from 'commander';
6
+ import { writeFileSync } from 'node:fs';
6
7
  import { createRequire } from 'module';
7
8
  import { EastError } from '@elaraai/east/internal';
8
9
  import { loadPlatforms, loadPlatformWithMetadata } from './loader.js';
9
10
  import { runProgram } from './runner.js';
10
11
  import { writeSnapshot, readSnapshot } from './snapshot.js';
12
+ import { encodeRebuilt, isDirectory, transpile, transpileDir } from './transpile.js';
13
+ import { exportFunctionsFromModule } from './export-functions.js';
14
+ import { East } from '@elaraai/east';
11
15
  const require = createRequire(import.meta.url);
12
16
  const pkg = require('../package.json');
13
17
  /** Parses the streaming-execution flags into runner options. */
@@ -111,6 +115,65 @@ async function cmdRun(irFile, options) {
111
115
  : (e.stack ?? `Error: ${e.message ?? String(err)}`));
112
116
  }
113
117
  }
118
+ /**
119
+ * `east-node transpile` (#628): print an IR file — or every IR file in a
120
+ * directory — as the TypeScript `East.function` builder surface. With
121
+ * `--rebuild`, the printed module is imported and the IR it builds is
122
+ * written too: the round-trip check, and the TypeScript leg of the
123
+ * cross-language conformance sweep.
124
+ */
125
+ async function cmdTranspile(input, options) {
126
+ try {
127
+ const common = {};
128
+ if (options.name !== undefined)
129
+ common.name = options.name;
130
+ if (options.importFrom !== undefined)
131
+ common.importFrom = options.importFrom;
132
+ if (isDirectory(input)) {
133
+ if (!options.output) {
134
+ return fail('Error: transpiling a directory needs -o <directory> for the modules');
135
+ }
136
+ const stems = await transpileDir(input, options.output, options.rebuild !== undefined ? { ...common, rebuildDir: options.rebuild } : common);
137
+ console.error(`Transpiled ${stems.length} IR file(s) to ${options.output}` +
138
+ (options.rebuild ? `, rebuilt to ${options.rebuild}` : ''));
139
+ return;
140
+ }
141
+ const { source, rebuilt } = await transpile(input, { ...common, rebuild: options.rebuild !== undefined });
142
+ if (options.output) {
143
+ writeFileSync(options.output, source, 'utf-8');
144
+ }
145
+ else {
146
+ process.stdout.write(source);
147
+ }
148
+ if (options.rebuild) {
149
+ writeFileSync(options.rebuild, encodeRebuilt(rebuilt, options.rebuild));
150
+ }
151
+ }
152
+ catch (err) {
153
+ return fail(`Error: ${err.message}`);
154
+ }
155
+ }
156
+ /**
157
+ * `east-node export-functions` (#628): write a module's `eastFunctions` as a
158
+ * function manifest other packages — in TypeScript or python — import.
159
+ */
160
+ async function cmdExportFunctions(modulePath, options) {
161
+ try {
162
+ const opts = { packages: options.package ?? [] };
163
+ if (options.name !== undefined)
164
+ opts.name = options.name;
165
+ if (options.packageVersion !== undefined)
166
+ opts.version = options.packageVersion;
167
+ if (options.only !== undefined)
168
+ opts.only = options.only;
169
+ const manifest = await exportFunctionsFromModule(modulePath, opts);
170
+ writeFileSync(options.output, East.encodeFunctionManifest(manifest));
171
+ console.error(`Exported ${manifest.functions.length} function(s) of ${manifest.package}@${manifest.version} to ${options.output}`);
172
+ }
173
+ catch (err) {
174
+ return fail(`Error: ${err.message}`);
175
+ }
176
+ }
114
177
  async function cmdVersion(options) {
115
178
  console.log(`${pkg.name} ${pkg.version}`);
116
179
  // Try to get east version
@@ -156,6 +219,25 @@ export function main() {
156
219
  .option('--stream <index>', 'Feed the given -i input (0-based) lazily, segment-by-segment')
157
220
  .option('--lazy-inputs <bytes>', 'Open indexed collection inputs at or above this size lazily (0 disables; default 64 MiB)')
158
221
  .action(cmdRun);
222
+ program
223
+ .command('transpile')
224
+ .description('Print an East IR program as TypeScript East.function builder source')
225
+ .argument('<input>', 'Path to an IR file (.beast2, .beast, .east, or .json), or a directory of them')
226
+ .option('-o, --output <path>', 'Write the module here (a directory when <input> is one; default: stdout)')
227
+ .option('--name <name>', 'The module-level export bound to the rebuilt function (default: main)')
228
+ .option('--import-from <specifier>', 'The module the printed source imports East from (default: @elaraai/east)')
229
+ .option('--rebuild <path>', 'Import the printed module and write the IR it builds here (.beast2 or .json; a directory in directory mode)')
230
+ .action(cmdTranspile);
231
+ program
232
+ .command('export-functions')
233
+ .description("Write a module's `eastFunctions` export as a function manifest other packages (TypeScript or python) import")
234
+ .argument('<module>', 'Path to the built module exporting `eastFunctions` (name -> East.function)')
235
+ .requiredOption('-o, --output <file>', 'The manifest to write (.beast2)')
236
+ .option('-p, --package <package...>', "Platform packages implementing the functions' platform calls (each dependency must be provided by one)")
237
+ .option('--name <name>', "The package name importers use (default: the module file's stem)")
238
+ .option('--package-version <version>', 'The version recorded in the manifest (default: 0.0.0)')
239
+ .option('--only <name...>', 'Export only these functions of `eastFunctions` (default: all)')
240
+ .action(cmdExportFunctions);
159
241
  program
160
242
  .command('version')
161
243
  .description('Show version information')
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAsC,CAAC;AAc5E,gEAAgE;AAChE,SAAS,gBAAgB,CAAC,OAAmB;IACzC,MAAM,GAAG,GAAuF,EAAE,CAAC;IACnG,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChF,MAAM,IAAI,KAAK,CAAC,kDAAkD,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QACvF,CAAC;QACD,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,qDAAqD,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5F,CAAC;QACD,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,6DAA6D,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QACxG,CAAC;QACD,GAAG,CAAC,cAAc,GAAG,KAAK,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAMD;;;;;;;;;GASG;AACH,SAAS,IAAI,CAAC,OAAe;IACzB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrB,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,MAA0B,EAAE,OAAmB;IACjE,IAAI,CAAC;QACD,sDAAsD;QACtD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;gBACrD,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;gBAClD,OAAO,IAAI,CAAC,qEAAqE,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACpD,IAAI,CAAC;gBACD,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;gBACrD,MAAM,UAAU,CACZ,EAAE,CAAC,MAAM,EACT,WAAW,EACX,EAAE,CAAC,QAAQ,EACX,EAAE,CAAC,UAAU,EACb,OAAO,CAAC,MAAM,EACd,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE,CACtE,CAAC;YACN,CAAC;oBAAS,CAAC;gBACP,EAAE,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;YACD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,IAAI,CAAC,iEAAiE,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,qDAAqD;gBAC7D,iEAAiE,CAAC,CAAC;QAC3E,CAAC;QAED,qEAAqE;QACrE,oEAAoE;QACpE,oEAAoE;QACpE,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,EAAE,CAAC;YACnF,OAAO,IAAI,CACP,gFAAgF;gBAChF,kFAAkF,CACrF,CAAC;QACN,CAAC;QAED,gFAAgF;QAChF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,aAAa,CAAC;gBAChB,OAAO,EAAK,OAAO,CAAC,QAAQ;gBAC5B,MAAM,EAAM,MAAM;gBAClB,UAAU,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;gBAC/B,QAAQ;gBACR,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE;aAC3C,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAElD,MAAM,UAAU,CACZ,MAAM,EACN,WAAW,EACX,QAAQ,EACR,OAAO,CAAC,KAAK,IAAI,EAAE,EACnB,OAAO,CAAC,MAAM,EACd,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE,CACtE,CAAC;IACN,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,kEAAkE;QAClE,sEAAsE;QACtE,qEAAqE;QACrE,qEAAqE;QACrE,oEAAoE;QACpE,MAAM,CAAC,GAAG,GAAY,CAAC;QACvB,OAAO,IAAI,CAAC,GAAG,YAAY,SAAS;YAChC,CAAC,CAAC,UAAU,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC5B,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAuB;IAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAE1C,0BAA0B;IAC1B,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,4BAA4B,CAAwB,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACL,mDAAmD;IACvD,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACvC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE1B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,wBAAwB,CAAC,OAAO,CAAC,CAAC;gBACrD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,sBAAsB,CAAC,CAAC;YAC1F,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC;AAED,MAAM,UAAU,IAAI;IAChB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACF,IAAI,CAAC,WAAW,CAAC;SACjB,WAAW,CAAC,sDAAsD,CAAC;SACnE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE1B,OAAO;SACF,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,wBAAwB,CAAC;SACrC,QAAQ,CAAC,WAAW,EAAE,oDAAoD,CAAC;SAC3E,MAAM,CAAC,4BAA4B,EAAE,6CAA6C,CAAC;SACnF,MAAM,CAAC,uBAAuB,EAAE,sDAAsD,CAAC;SACvF,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC;SAChD,MAAM,CAAC,mBAAmB,EAAE,wDAAwD,CAAC;SACrF,MAAM,CAAC,wBAAwB,EAC5B,wEAAwE,CAAC;SAC5E,MAAM,CAAC,eAAe,EACnB,6FAA6F,CAAC;SACjG,MAAM,CAAC,kBAAkB,EACtB,8DAA8D,CAAC;SAClE,MAAM,CAAC,uBAAuB,EAC3B,0FAA0F,CAAC;SAC9F,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpB,OAAO;SACF,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,4BAA4B,EAAE,4BAA4B,CAAC;SAClE,MAAM,CAAC,UAAU,CAAC,CAAC;IAExB,OAAO,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
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 FunctionManifest } from '@elaraai/east';
6
+ /** Options for {@link exportFunctionsFromModule}. */
7
+ export interface ExportFunctionsOptions {
8
+ /** The package name importers use (default: the module file's stem). */
9
+ name?: string;
10
+ /** The version recorded in the manifest (default `0.0.0`). */
11
+ version?: string;
12
+ /** Platform packages implementing the functions' platform calls. */
13
+ packages?: string[];
14
+ /** Export only these functions of `eastFunctions` (default: all); a name it does not export is an error naming what it does. */
15
+ only?: string[];
16
+ }
17
+ /**
18
+ * Loads a module and builds the manifest of its `eastFunctions` export
19
+ * (name → `East.function` result).
20
+ *
21
+ * @param modulePath - Path to the module (a built `.js` / `.mjs`)
22
+ * @param options - Package name, version, the providing platform packages, and the functions to export
23
+ * @returns The manifest value
24
+ * @throws When the module has no `eastFunctions` object, a function in
25
+ * `only` is not exported, a function is not a closed value, or a platform
26
+ * dependency has no providing package
27
+ */
28
+ export declare function exportFunctionsFromModule(modulePath: string, options?: ExportFunctionsOptions): Promise<FunctionManifest>;
29
+ //# sourceMappingURL=export-functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-functions.d.ts","sourceRoot":"","sources":["../src/export-functions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,OAAO,EAAQ,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAG5D,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACnC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gIAAgI;IAChI,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoCnI"}
@@ -0,0 +1,71 @@
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
+ * `east-node export-functions` (#628): a module's `eastFunctions` export
7
+ * written as a function manifest that other packages — in TypeScript or
8
+ * python — import with `East.importFunction` / `East.import_function`.
9
+ * The twin of `east-py export-functions`.
10
+ *
11
+ * Every platform function the exported functions call must be implemented
12
+ * by one of the `-p` platform packages, which is recorded as the
13
+ * dependency's provider; a dependency no package provides is an error
14
+ * naming it, so an importer's runner can be checked at its own build.
15
+ * `only` narrows the export to the named functions — what an importer
16
+ * actually uses — so a sibling function's platform call never fails an
17
+ * export that does not need it.
18
+ */
19
+ import { basename, extname, resolve } from 'node:path';
20
+ import { pathToFileURL } from 'node:url';
21
+ import { East } from '@elaraai/east';
22
+ import { loadPlatform } from './loader.js';
23
+ /**
24
+ * Loads a module and builds the manifest of its `eastFunctions` export
25
+ * (name → `East.function` result).
26
+ *
27
+ * @param modulePath - Path to the module (a built `.js` / `.mjs`)
28
+ * @param options - Package name, version, the providing platform packages, and the functions to export
29
+ * @returns The manifest value
30
+ * @throws When the module has no `eastFunctions` object, a function in
31
+ * `only` is not exported, a function is not a closed value, or a platform
32
+ * dependency has no providing package
33
+ */
34
+ export async function exportFunctionsFromModule(modulePath, options = {}) {
35
+ const path = resolve(modulePath);
36
+ const mod = await import(pathToFileURL(path).href);
37
+ const exported = mod.eastFunctions;
38
+ if (exported === null || typeof exported !== 'object') {
39
+ throw new Error(`${modulePath} exports no \`eastFunctions\` object (name -> East.function result)`);
40
+ }
41
+ let functions = exported;
42
+ if (options.only !== undefined) {
43
+ const missing = options.only.filter(name => !(name in functions));
44
+ if (missing.length > 0) {
45
+ throw new Error(`${modulePath} exports no function${missing.length === 1 ? '' : 's'} ${missing.map(n => JSON.stringify(n)).join(', ')} — ` +
46
+ `its eastFunctions are ${Object.keys(functions).join(', ') || '(none)'}`);
47
+ }
48
+ functions = Object.fromEntries(options.only.map(name => [name, exported[name]]));
49
+ }
50
+ const providers = {};
51
+ for (const pkg of options.packages ?? []) {
52
+ for (const fn of await loadPlatform(pkg)) {
53
+ if (!(fn.name in providers))
54
+ providers[fn.name] = pkg;
55
+ }
56
+ }
57
+ const missing = new Set();
58
+ for (const fn of Object.values(functions)) {
59
+ for (const dep of East.platformDependencies(fn)) {
60
+ if (!(dep.name in providers))
61
+ missing.add(dep.name);
62
+ }
63
+ }
64
+ if (missing.size > 0) {
65
+ throw new Error(`platform function(s) no -p package provides: ${[...missing].sort().join(', ')} — ` +
66
+ 'pass the implementing package with -p');
67
+ }
68
+ const name = options.name ?? basename(path, extname(path));
69
+ return East.exportFunctions(name, options.version ?? '0.0.0', functions, { providers });
70
+ }
71
+ //# sourceMappingURL=export-functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-functions.js","sourceRoot":"","sources":["../src/export-functions.ts"],"names":[],"mappings":"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"}
@@ -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=export-functions.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-functions.spec.d.ts","sourceRoot":"","sources":["../src/export-functions.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,104 @@
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
+ * Tests for `east-node export-functions` (#628): a module's `eastFunctions`
7
+ * export becomes a manifest that links and runs; unprovided platform
8
+ * dependencies and a missing export are named.
9
+ */
10
+ import { describe, it } from 'node:test';
11
+ import assert from 'node:assert/strict';
12
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
13
+ import { tmpdir } from 'node:os';
14
+ import { join } from 'node:path';
15
+ import { East, EastIR, FunctionType, IntegerType } from '@elaraai/east';
16
+ import { exportFunctionsFromModule } from './export-functions.js';
17
+ const EAST = import.meta.resolve('@elaraai/east');
18
+ const MODULE = `
19
+ import { East, IntegerType, NullType, StringType } from ${JSON.stringify(EAST)};
20
+ const log = East.platform("log", [StringType], NullType);
21
+ export const double = East.function([IntegerType], IntegerType, ($, x) => x.multiply(2n));
22
+ export const shout = East.function([StringType], NullType, ($, s) => { $(log(s.upperCase())); });
23
+ export const eastFunctions = { double, shout };
24
+ `;
25
+ /**
26
+ * Plants the module under a fake project that also provides the `log`
27
+ * platform as its own `./platform` package (`acme-platform`), the way the
28
+ * loader resolves a project's platform from the cwd.
29
+ */
30
+ function plant(source) {
31
+ const dir = mkdtempSync(join(tmpdir(), 'enc-export-'));
32
+ const path = join(dir, 'pricing.mjs');
33
+ writeFileSync(path, source, 'utf-8');
34
+ const pkg = join(dir, 'node_modules', 'acme-platform');
35
+ mkdirSync(join(pkg, 'dist'), { recursive: true });
36
+ writeFileSync(join(pkg, 'package.json'), JSON.stringify({
37
+ name: 'acme-platform', version: '1.0.0', type: 'module',
38
+ exports: { './platform': './dist/platform.js', './package.json': './package.json' },
39
+ }));
40
+ writeFileSync(join(pkg, 'dist', 'platform.js'), 'export default [{ name: "log", inputs: [{ type: "String", value: null }], output: { type: "Null", value: null }, type: "sync", fn: () => null }];\n');
41
+ return { dir, path };
42
+ }
43
+ /** Runs `fn` with `process.cwd()` at `dir`, where the fake platform package resolves. */
44
+ async function withCwd(dir, fn) {
45
+ const prev = process.cwd();
46
+ process.chdir(dir);
47
+ try {
48
+ return await fn();
49
+ }
50
+ finally {
51
+ process.chdir(prev);
52
+ }
53
+ }
54
+ describe('east-node export-functions', () => {
55
+ it('writes a manifest that links and runs, recording each dependency\'s provider', async () => {
56
+ const { dir, path } = plant(MODULE);
57
+ try {
58
+ const manifest = await withCwd(dir, () => exportFunctionsFromModule(path, { version: '2.0.0', packages: ['acme-platform'] }));
59
+ assert.equal(manifest.package, 'pricing');
60
+ assert.equal(manifest.version, '2.0.0');
61
+ assert.deepEqual(manifest.functions.map(f => f.name), ['double', 'shout']);
62
+ assert.equal(manifest.functions[1].platforms[0].provider.value, 'acme-platform');
63
+ const back = East.decodeFunctionManifest(East.encodeFunctionManifest(manifest));
64
+ const imported = East.importFunction('pricing', 'double', FunctionType([IntegerType], IntegerType));
65
+ const user = East.function([IntegerType], IntegerType, ($, x) => imported(x).add(1n));
66
+ const { ir } = East.linkImports(user, [back]);
67
+ assert.equal(new EastIR(ir).compile([])(4n), 9n);
68
+ }
69
+ finally {
70
+ rmSync(dir, { recursive: true, force: true });
71
+ }
72
+ });
73
+ it('names a platform dependency no package provides', async () => {
74
+ const { dir, path } = plant(MODULE);
75
+ try {
76
+ await assert.rejects(exportFunctionsFromModule(path, {}), /no -p package provides: log/);
77
+ }
78
+ finally {
79
+ rmSync(dir, { recursive: true, force: true });
80
+ }
81
+ });
82
+ it('exports only the named functions — a sibling\'s unprovided platform call no longer matters — and names an unknown one', async () => {
83
+ const { dir, path } = plant(MODULE);
84
+ try {
85
+ // `shout` calls `log`, which no -p package provides here; exporting `double` alone is fine
86
+ const manifest = await exportFunctionsFromModule(path, { only: ['double'] });
87
+ assert.deepEqual(manifest.functions.map(f => f.name), ['double']);
88
+ await assert.rejects(exportFunctionsFromModule(path, { only: ['double', 'nope'] }), /exports no function "nope" — its eastFunctions are double, shout/);
89
+ }
90
+ finally {
91
+ rmSync(dir, { recursive: true, force: true });
92
+ }
93
+ });
94
+ it('needs the eastFunctions export', async () => {
95
+ const { dir, path } = plant('export const x = 1;\n');
96
+ try {
97
+ await assert.rejects(exportFunctionsFromModule(path, {}), /exports no `eastFunctions` object/);
98
+ }
99
+ finally {
100
+ rmSync(dir, { recursive: true, force: true });
101
+ }
102
+ });
103
+ });
104
+ //# sourceMappingURL=export-functions.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-functions.spec.js","sourceRoot":"","sources":["../src/export-functions.spec.ts"],"names":[],"mappings":"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"}
package/dist/loader.d.ts CHANGED
@@ -79,6 +79,15 @@ export declare function loadEastIR(filePath: string): EastIR<any, any> | AsyncEa
79
79
  * @returns Decoded value
80
80
  */
81
81
  export declare function loadInput(filePath: string, type: EastTypeValue): unknown;
82
+ /**
83
+ * Bytes a value from {@link loadInputLazy} has read from its file so far:
84
+ * the geometry (tail and head), every fence probe, and each segment frame
85
+ * decoded. `undefined` for any other value.
86
+ *
87
+ * @param value - a task input value
88
+ * @returns the byte count, or `undefined` when the value was not opened lazily
89
+ */
90
+ export declare function lazyInputBytesRead(value: unknown): number | undefined;
82
91
  /**
83
92
  * Opens an input file as a lazy pager-backed collection value, when it can
84
93
  * be: a beast2 v5 collection blob carrying a segment index. Size, iteration
@@ -86,10 +95,17 @@ export declare function loadInput(filePath: string, type: EastTypeValue): unknow
86
95
  * memory; any other operation hydrates transparently to the eager value's
87
96
  * exact semantics.
88
97
  *
98
+ * The file is never buffered whole: the value pages segment frames from an
99
+ * open descriptor through positioned reads (a Set or Dict input's first
100
+ * keyed read probes every segment's fence once), so its residency is the
101
+ * page cache and the process heap holds one decoded segment at a time — the
102
+ * difference between an out-of-memory kill and graceful eviction for an
103
+ * input near the runner's memory limit.
104
+ *
89
105
  * Returns `undefined` when the file cannot be served lazily (a non-beast2
90
- * format, a v4 or index-less blob, a non-collection root, or an element
91
- * shape carrying a `Ref` or function values) — the caller falls back to
92
- * {@link loadInput}.
106
+ * format, a v4 or index-less blob, a non-collection root, cross-segment
107
+ * aliasing, or an element shape carrying a `Ref` or function values) — the
108
+ * caller falls back to {@link loadInput}.
93
109
  *
94
110
  * The value opens **frozen**, like every task input, which is what makes
95
111
  * lazy service safe for any nested element shape: frozen values cannot be
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAWH,MAAM,EACN,WAAW,EACX,KAAK,aAAa,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAWhF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,GAAG,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAsDD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyCnF;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsB7F;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CASvF;AAmDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAgCxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAuBrF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAoBxE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAUnE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAWH,MAAM,EACN,WAAW,EACX,KAAK,aAAa,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAWhF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,GAAG,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAsDD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyCnF;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsB7F;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CASvF;AAmDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAgCxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAuBrF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAoBxE;AAMD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAiCnE"}
package/dist/loader.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2025 Elara AI Pty Ltd
3
3
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
4
  */
5
- import { readFileSync } from 'fs';
5
+ import { closeSync, fstatSync, openSync, readFileSync, readSync } from 'fs';
6
6
  import { createRequire } from 'module';
7
7
  import * as path from 'path';
8
8
  import { extname } from 'path';
@@ -299,6 +299,31 @@ export function loadInput(filePath, type) {
299
299
  }
300
300
  }
301
301
  }
302
+ /** Bytes each lazily opened input has read from its descriptor so far —
303
+ * what "paged from the file" came to, for the runner's verbose summary. */
304
+ const lazyInputReads = new WeakMap();
305
+ /**
306
+ * Bytes a value from {@link loadInputLazy} has read from its file so far:
307
+ * the geometry (tail and head), every fence probe, and each segment frame
308
+ * decoded. `undefined` for any other value.
309
+ *
310
+ * @param value - a task input value
311
+ * @returns the byte count, or `undefined` when the value was not opened lazily
312
+ */
313
+ export function lazyInputBytesRead(value) {
314
+ return typeof value === 'object' && value !== null ? lazyInputReads.get(value)?.() : undefined;
315
+ }
316
+ /** The descriptors behind lazily opened inputs, closed when their value is
317
+ * collected: the value reads segment frames from the descriptor for its
318
+ * whole life. A runner holds one per lazy input. */
319
+ const lazyInputFiles = new FinalizationRegistry((fd) => {
320
+ try {
321
+ closeSync(fd);
322
+ }
323
+ catch {
324
+ // Already closed — nothing else to release.
325
+ }
326
+ });
302
327
  /**
303
328
  * Opens an input file as a lazy pager-backed collection value, when it can
304
329
  * be: a beast2 v5 collection blob carrying a segment index. Size, iteration
@@ -306,10 +331,17 @@ export function loadInput(filePath, type) {
306
331
  * memory; any other operation hydrates transparently to the eager value's
307
332
  * exact semantics.
308
333
  *
334
+ * The file is never buffered whole: the value pages segment frames from an
335
+ * open descriptor through positioned reads (a Set or Dict input's first
336
+ * keyed read probes every segment's fence once), so its residency is the
337
+ * page cache and the process heap holds one decoded segment at a time — the
338
+ * difference between an out-of-memory kill and graceful eviction for an
339
+ * input near the runner's memory limit.
340
+ *
309
341
  * Returns `undefined` when the file cannot be served lazily (a non-beast2
310
- * format, a v4 or index-less blob, a non-collection root, or an element
311
- * shape carrying a `Ref` or function values) — the caller falls back to
312
- * {@link loadInput}.
342
+ * format, a v4 or index-less blob, a non-collection root, cross-segment
343
+ * aliasing, or an element shape carrying a `Ref` or function values) — the
344
+ * caller falls back to {@link loadInput}.
313
345
  *
314
346
  * The value opens **frozen**, like every task input, which is what makes
315
347
  * lazy service safe for any nested element shape: frozen values cannot be
@@ -324,15 +356,41 @@ export function loadInput(filePath, type) {
324
356
  export function loadInputLazy(filePath) {
325
357
  if (getFileFormat(filePath) !== 'beast2')
326
358
  return undefined;
327
- const data = readFileSync(filePath);
359
+ let fd = -1;
328
360
  try {
329
- const extents = readBeast2Extents(data);
330
- if (!isBeast2LazySafe(extents.typeValue, { frozen: true }))
361
+ fd = openSync(filePath, 'r');
362
+ const handle = fd;
363
+ let bytesRead = 0;
364
+ const reader = {
365
+ size: fstatSync(handle).size,
366
+ read(offset, length) {
367
+ const out = new Uint8Array(length);
368
+ let done = 0;
369
+ while (done < length) {
370
+ const n = readSync(handle, out, done, length - done, offset + done);
371
+ if (n === 0)
372
+ throw new Error(`beast2: short read at offset ${offset + done}`);
373
+ done += n;
374
+ }
375
+ bytesRead += length;
376
+ return out;
377
+ },
378
+ };
379
+ const extents = readBeast2Extents(reader);
380
+ if (!extents.selfContained || !isBeast2LazySafe(extents.typeValue, { frozen: true }))
331
381
  return undefined;
332
- return openBeast2LazyFor(extents.typeValue, { frozen: true })(data);
382
+ const value = openBeast2LazyFor(extents.typeValue, { frozen: true })(reader);
383
+ lazyInputFiles.register(value, handle);
384
+ lazyInputReads.set(value, () => bytesRead);
385
+ fd = -1; // the value owns the descriptor from here
386
+ return value;
333
387
  }
334
388
  catch {
335
389
  return undefined;
336
390
  }
391
+ finally {
392
+ if (fd >= 0)
393
+ closeSync(fd);
394
+ }
337
395
  }
338
396
  //# sourceMappingURL=loader.js.map