@elaraai/e3-types 1.0.4 → 1.0.6

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/src/package.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  * - **Task**: A computation with input/output paths (stored separately)
16
16
  */
17
17
 
18
- import { StructType, StringType, IntegerType, VariantType, NullType, DictType, ValueTypeOf } from '@elaraai/east';
18
+ import { StructType, StringType, IntegerType, VariantType, NullType, DictType, ValueTypeOf, decodeBeast2For } from '@elaraai/east';
19
19
  import { DatasetRefType } from './dataset-ref.js';
20
20
  import { StructureType } from './structure.js';
21
21
 
@@ -77,11 +77,50 @@ export const PackageObjectType = StructType({
77
77
  tasks: DictType(StringType, StringType),
78
78
  /** Data structure and initial values */
79
79
  data: PackageDataType,
80
+ /** Functions defined in this package: name -> FunctionObject hash.
81
+ * BEAST2 encodes struct fields positionally in declaration order, so this
82
+ * field MUST stay last — never insert between `tasks` and `data`. */
83
+ functions: DictType(StringType, StringType),
80
84
  });
81
85
  export type PackageObjectType = typeof PackageObjectType;
82
86
 
83
87
  export type PackageObject = ValueTypeOf<typeof PackageObjectType>;
84
88
 
89
+ /**
90
+ * The pre-`functions` package object wire shape, kept only so
91
+ * {@link decodePackageObject} can read packages exported before functions
92
+ * existed.
93
+ */
94
+ const LegacyPackageObjectType = StructType({
95
+ tasks: DictType(StringType, StringType),
96
+ data: PackageDataType,
97
+ });
98
+
99
+ const decodeCurrent = decodeBeast2For(PackageObjectType);
100
+ const decodeLegacy = decodeBeast2For(LegacyPackageObjectType);
101
+
102
+ /**
103
+ * Decode a `PackageObject` from BEAST2 bytes, tolerating the pre-`functions`
104
+ * wire format (dual-decode migration).
105
+ *
106
+ * Every package-read path — local AND cloud — must use this instead of
107
+ * `decodeBeast2For(PackageObjectType)` directly, so packages exported before
108
+ * the `functions` field existed keep decoding. Old bytes decode with
109
+ * `functions` defaulted to an empty map.
110
+ */
111
+ export function decodePackageObject(data: Uint8Array): PackageObject {
112
+ try {
113
+ return decodeCurrent(data);
114
+ } catch (err) {
115
+ try {
116
+ const legacy = decodeLegacy(data);
117
+ return { tasks: legacy.tasks, data: legacy.data, functions: new Map() };
118
+ } catch {
119
+ throw err; // neither shape — surface the current-format error
120
+ }
121
+ }
122
+ }
123
+
85
124
  // =============================================================================
86
125
  // Package Transfer Types
87
126
  // =============================================================================
package/src/runner.ts ADDED
@@ -0,0 +1,56 @@
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
+ /**
7
+ * Runner wire types for e3 functions.
8
+ *
9
+ * `RunnerType` is the wire image of the SDK's `Runner` union (minus its
10
+ * `custom` raw-argv runtime — see the security note below). It pins the
11
+ * executable to a known runtime for every tag, so a function call can never
12
+ * name its own executable; only platform flags vary.
13
+ *
14
+ * A `platforms` entry is just a `-p <name>` flag on the wire; the SDK's
15
+ * `Platform<Known> | { custom }` distinction is authoring sugar that
16
+ * collapses to a string.
17
+ */
18
+
19
+ import { VariantType, StructType, ArrayType, StringType, ValueTypeOf } from '@elaraai/east';
20
+
21
+ /**
22
+ * Wire representation of a function's runner.
23
+ *
24
+ * Each tag names a known runtime binary; `platforms` are passed as `-p`
25
+ * flags. There is deliberately no raw-argv case: a resolved-argv field would
26
+ * let any caller choose the executable and every flag — arbitrary command
27
+ * execution by construction.
28
+ */
29
+ export const RunnerType = VariantType({
30
+ east_node: StructType({ platforms: ArrayType(StringType) }),
31
+ east_py: StructType({ platforms: ArrayType(StringType) }),
32
+ east_c: StructType({ platforms: ArrayType(StringType) }),
33
+ });
34
+ export type RunnerType = typeof RunnerType;
35
+
36
+ export type RunnerValue = ValueTypeOf<typeof RunnerType>;
37
+
38
+ function flags(platforms: string[]): string[] {
39
+ return platforms.flatMap((p) => ['-p', p]);
40
+ }
41
+
42
+ /**
43
+ * Resolve a {@link RunnerType} value to the argv prefix (the wire-value
44
+ * analogue of the SDK's `runnerToCommand`). Lives in e3-types so both
45
+ * e3-core (local) and the cloud execution kernel import the one resolver.
46
+ *
47
+ * Variant tags use underscores (`east_node`) mapped to the binary name
48
+ * (`east-node`) here.
49
+ */
50
+ export function runnerToArgv(r: RunnerValue): string[] {
51
+ switch (r.type) {
52
+ case 'east_node': return ['east-node', 'run', ...flags(r.value.platforms)];
53
+ case 'east_py': return ['east-py', 'run', ...flags(r.value.platforms)];
54
+ case 'east_c': return ['east-c', 'run', ...flags(r.value.platforms)];
55
+ }
56
+ }