@elaraai/e3 0.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
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
+ * e3: TypeScript SDK for authoring e3 packages.
7
+ *
8
+ * This package provides a fluent API for defining e3 packages in TypeScript:
9
+ * - `e3.input()` - Define input datasets
10
+ * - `e3.task()` - Define tasks that transform datasets
11
+ * - `e3.package()` - Bundle definitions into a package
12
+ * - `e3.export()` - Export package to a .zip bundle
13
+ *
14
+ * Terminology:
15
+ * - **Dataset**: A location holding a value (leaf node in the data tree)
16
+ * - **Tree**: A location containing datasets or nested trees (branch node)
17
+ * - **Structure**: The shape of the data tree
18
+ * - **Task**: A transformation that reads input datasets and produces an output dataset
19
+ * - **Path**: An address pointing to a dataset or tree
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { StringType } from '@elaraai/east';
24
+ * import e3 from '@elaraai/e3';
25
+ *
26
+ * const input_name = e3.input('name', StringType, 'World');
27
+ *
28
+ * const say_hello = e3.task(
29
+ * 'say_hello',
30
+ * [input_name],
31
+ * ($, name) => str`Hello, ${name}!`
32
+ * );
33
+ *
34
+ * // Only need to pass the final task - dependencies are collected automatically
35
+ * const pkg = e3.package('hello_world', '1.0.0', say_hello);
36
+ *
37
+ * // Discoverable access to package contents
38
+ * pkg.datasets.inputs.name; // input dataset
39
+ * pkg.datasets.outputs.say_hello; // output dataset
40
+ * pkg.tasks.say_hello; // task definition
41
+ *
42
+ * await e3.export(pkg, 'package.zip');
43
+ * ```
44
+ */
45
+ import type { DatasetDef, DataTreeDef, DatasetsOf, MergeDatasets, PackageDef, PackageItem, TaskDef } from './types.js';
46
+ import { input } from './input.js';
47
+ import { task, customTask } from './task.js';
48
+ import { package_ } from './package.js';
49
+ import { export_ } from './export.js';
50
+ export type { DataTreeDef, DatasetDef, DatasetsOf, TaskDef, PackageDef, PackageItem, MergeDatasets, };
51
+ /**
52
+ * The e3 SDK namespace.
53
+ *
54
+ * Provides functions for authoring e3 packages in TypeScript.
55
+ */
56
+ declare const e3: {
57
+ input: typeof input;
58
+ task: typeof task;
59
+ customTask: typeof customTask;
60
+ package: typeof package_;
61
+ export: typeof export_;
62
+ };
63
+ export default e3;
64
+ export { input, task, customTask, package_ as package, export_ as export };
65
+ export { inputsTree } from './input.js';
66
+ export { tasksTree } from './task.js';
67
+ export { sha256File, sha256Bytes, hashToPath } from './sha256.js';
68
+ export { addObject } from './export.js';
69
+ //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,EACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,YAAY,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,aAAa,GACd,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,EAAE;;;;;;CAMP,CAAC;AAEF,eAAe,EAAE,CAAC;AAGlB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,IAAI,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,CAAC;AAG3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,30 @@
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 { input } from './input.js';
6
+ import { task, customTask } from './task.js';
7
+ import { package_ } from './package.js';
8
+ import { export_ } from './export.js';
9
+ /**
10
+ * The e3 SDK namespace.
11
+ *
12
+ * Provides functions for authoring e3 packages in TypeScript.
13
+ */
14
+ const e3 = {
15
+ input,
16
+ task,
17
+ customTask,
18
+ package: package_,
19
+ export: export_,
20
+ };
21
+ export default e3;
22
+ // Also export individual functions for tree-shaking
23
+ export { input, task, customTask, package_ as package, export_ as export };
24
+ // Singleton tree definitions
25
+ export { inputsTree } from './input.js';
26
+ export { tasksTree } from './task.js';
27
+ // Utility exports
28
+ export { sha256File, sha256Bytes, hashToPath } from './sha256.js';
29
+ export { addObject } from './export.js';
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoDH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAYtC;;;;GAIG;AACH,MAAM,EAAE,GAAG;IACT,KAAK;IACL,IAAI;IACJ,UAAU;IACV,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,OAAO;CAChB,CAAC;AAEF,eAAe,EAAE,CAAC;AAElB,oDAAoD;AACpD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,IAAI,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,CAAC;AAE3E,6BAA6B;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,kBAAkB;AAClB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,40 @@
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
+ * Input dataset definitions for e3 packages.
7
+ */
8
+ import type { EastType, ValueTypeOf } from '@elaraai/east';
9
+ import { variant } from '@elaraai/east';
10
+ import type { DatasetDef, DataTreeDef } from './types.js';
11
+ /**
12
+ * Singleton datatree definition for `.inputs`.
13
+ *
14
+ * All input datasets are children of this datatree.
15
+ */
16
+ export declare const inputsTree: DataTreeDef;
17
+ /**
18
+ * Defines an input dataset.
19
+ *
20
+ * Creates a dataset at `.inputs.${name}` in the workspace.
21
+ *
22
+ * @typeParam T - The East type of the input value
23
+ * @param name - Dataset name (used as path segment in the tree)
24
+ * @param type - East type of the input value
25
+ * @param defaultValue - Optional default value
26
+ * @returns A DatasetDef that can be used in dataflows and packages
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { StringType, IntegerType } from '@elaraai/east';
31
+ *
32
+ * // Input with default
33
+ * const name = input('name', StringType, 'World');
34
+ *
35
+ * // Input without default
36
+ * const count = input('count', IntegerType);
37
+ * ```
38
+ */
39
+ export declare function input<Name extends string, T extends EastType>(name: Name, type: T, defaultValue?: ValueTypeOf<T>): DatasetDef<T, [variant<"field", "inputs">, variant<"field", Name>]>;
40
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/input.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,WAKxB,CAAC;AAGF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,KAAK,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,EAC3D,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,CAAC,EACP,YAAY,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAC5B,UAAU,CAAC,CAAC,EAAE,CAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAE,CAAC,CASvE"}
@@ -0,0 +1,49 @@
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 { variant } from '@elaraai/east';
6
+ /**
7
+ * Singleton datatree definition for `.inputs`.
8
+ *
9
+ * All input datasets are children of this datatree.
10
+ */
11
+ export const inputsTree = {
12
+ kind: 'datatree',
13
+ name: 'inputs',
14
+ path: [variant('field', 'inputs')],
15
+ deps: new Set(),
16
+ };
17
+ /**
18
+ * Defines an input dataset.
19
+ *
20
+ * Creates a dataset at `.inputs.${name}` in the workspace.
21
+ *
22
+ * @typeParam T - The East type of the input value
23
+ * @param name - Dataset name (used as path segment in the tree)
24
+ * @param type - East type of the input value
25
+ * @param defaultValue - Optional default value
26
+ * @returns A DatasetDef that can be used in dataflows and packages
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { StringType, IntegerType } from '@elaraai/east';
31
+ *
32
+ * // Input with default
33
+ * const name = input('name', StringType, 'World');
34
+ *
35
+ * // Input without default
36
+ * const count = input('count', IntegerType);
37
+ * ```
38
+ */
39
+ export function input(name, type, defaultValue) {
40
+ return {
41
+ kind: 'dataset',
42
+ name,
43
+ path: [variant('field', 'inputs'), variant('field', name)],
44
+ type,
45
+ default: defaultValue,
46
+ deps: new Set([...inputsTree.deps, inputsTree]),
47
+ };
48
+ }
49
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/input.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB;IACrC,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClC,IAAI,EAAE,IAAI,GAAG,EAAE;CAChB,CAAC;AAGF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,KAAK,CACnB,IAAU,EACV,IAAO,EACP,YAA6B;IAE7B,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI;QACJ,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1D,IAAI;QACJ,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;KAChD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
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
+ * Package definitions for e3.
7
+ */
8
+ import type { MergeDatasets, PackageDef, PackageItem } from './types.js';
9
+ /**
10
+ * Creates a package definition from items.
11
+ *
12
+ * Automatically collects all dependencies from the provided items.
13
+ * You only need to pass the "top-level" items - all inputs, intermediate
14
+ * tasks, and datasets they depend on are included automatically.
15
+ *
16
+ * Organizes items into a discoverable structure:
17
+ * - `pkg.datasets.inputs.*` - Input datasets
18
+ * - `pkg.datasets.outputs.*` - Output datasets
19
+ * - `pkg.tasks.*` - Tasks
20
+ *
21
+ * @param name - Package name
22
+ * @param version - Package version
23
+ * @param items - Items to include (datasets, tasks)
24
+ * @returns A PackageDef with typed access to contents
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const input_name = e3.input('name', StringType, 'World');
29
+ * const say_hello = e3.task('say_hello', [input_name], ...);
30
+ *
31
+ * // Only need to pass the final task - input_name is included automatically
32
+ * const pkg = e3.package('hello_world', '1.0.0', say_hello);
33
+ *
34
+ * // Typed access to contents
35
+ * const nameInput = pkg.datasets.inputs.name;
36
+ * const helloOutput = pkg.datasets.outputs.say_hello;
37
+ * const helloTask = pkg.tasks.say_hello;
38
+ * ```
39
+ */
40
+ export declare function package_<TItems extends (PackageItem | PackageDef<any>)[]>(name: string, version: string, ...items: TItems): PackageDef<MergeDatasets<TItems>>;
41
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/package.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,WAAW,EAEZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,QAAQ,CAAC,MAAM,SAAS,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EACvE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,KAAK,EAAE,MAAM,GACf,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CA6EnC"}
@@ -0,0 +1,111 @@
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
+ * Creates a package definition from items.
7
+ *
8
+ * Automatically collects all dependencies from the provided items.
9
+ * You only need to pass the "top-level" items - all inputs, intermediate
10
+ * tasks, and datasets they depend on are included automatically.
11
+ *
12
+ * Organizes items into a discoverable structure:
13
+ * - `pkg.datasets.inputs.*` - Input datasets
14
+ * - `pkg.datasets.outputs.*` - Output datasets
15
+ * - `pkg.tasks.*` - Tasks
16
+ *
17
+ * @param name - Package name
18
+ * @param version - Package version
19
+ * @param items - Items to include (datasets, tasks)
20
+ * @returns A PackageDef with typed access to contents
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const input_name = e3.input('name', StringType, 'World');
25
+ * const say_hello = e3.task('say_hello', [input_name], ...);
26
+ *
27
+ * // Only need to pass the final task - input_name is included automatically
28
+ * const pkg = e3.package('hello_world', '1.0.0', say_hello);
29
+ *
30
+ * // Typed access to contents
31
+ * const nameInput = pkg.datasets.inputs.name;
32
+ * const helloOutput = pkg.datasets.outputs.say_hello;
33
+ * const helloTask = pkg.tasks.say_hello;
34
+ * ```
35
+ */
36
+ export function package_(name, version, ...items) {
37
+ // Recursively collect all items and their transitive dependencies
38
+ const all_items = new Set();
39
+ const visited = new Set();
40
+ function collect(item) {
41
+ if (visited.has(item))
42
+ return;
43
+ visited.add(item);
44
+ // First collect all dependencies recursively
45
+ for (const dep of item.deps) {
46
+ collect(dep);
47
+ }
48
+ // Then add this item (ensures topological order)
49
+ all_items.add(item);
50
+ }
51
+ for (const item of items) {
52
+ if (item.kind === "package") {
53
+ for (const dep of item.contents) {
54
+ all_items.add(dep);
55
+ }
56
+ }
57
+ else {
58
+ collect(item);
59
+ }
60
+ }
61
+ const datasets = {};
62
+ const tasks = {};
63
+ // all_items is in topological order by construction
64
+ for (const item of all_items) {
65
+ if (item.kind === 'datatree') {
66
+ let current = datasets;
67
+ for (let i = 0; i < item.path.length - 1; i++) { // TODO should this path be the parent path?
68
+ const segment = item.path[i];
69
+ if (segment.type === 'field') {
70
+ current = current[segment.value];
71
+ if (current === undefined) {
72
+ throw new Error(`Parent tree not found in package(): ${segment.value}`);
73
+ }
74
+ }
75
+ else {
76
+ throw new Error(`Unsupported path segment type in package(): ${segment.type}`);
77
+ }
78
+ }
79
+ // the only tree type is struct for now
80
+ current[item.name] = {};
81
+ }
82
+ else if (item.kind === 'dataset') {
83
+ let current = datasets;
84
+ for (let i = 0; i < item.path.length - 1; i++) { // TODO should this path be the parent path?
85
+ const segment = item.path[i];
86
+ if (segment.type === 'field') {
87
+ current = current[segment.value];
88
+ if (current === undefined) {
89
+ throw new Error(`Parent tree not found in package(): ${segment.value}`);
90
+ }
91
+ }
92
+ else {
93
+ throw new Error(`Unsupported path segment type in package(): ${segment.type}`);
94
+ }
95
+ }
96
+ current[item.name] = item;
97
+ }
98
+ else if (item.kind === 'task') {
99
+ // TODO - check task inputs and output exist with correct types?
100
+ tasks[item.name] = item;
101
+ }
102
+ }
103
+ return {
104
+ kind: 'package',
105
+ name,
106
+ version,
107
+ datasets: datasets,
108
+ contents: [...all_items],
109
+ };
110
+ }
111
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","sourceRoot":"","sources":["../../src/package.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAY,EACZ,OAAe,EACf,GAAG,KAAa;IAEhB,kEAAkE;IAClE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IAEvC,SAAS,OAAO,CAAC,IAAiB;QAChC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAElB,6CAA6C;QAC7C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QAED,iDAAiD;QACjD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,oDAAoD;IACpD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,IAAI,OAAO,GAAG,QAAQ,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,4CAA4C;gBAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC7B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACjC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;wBAC1B,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC1E,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,+CAA+C,OAAO,CAAC,IAAoB,EAAE,CAAC,CAAC;gBACjG,CAAC;YACH,CAAC;YAED,uCAAuC;YACvC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,OAAO,GAAG,QAAQ,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,4CAA4C;gBAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC7B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACjC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;wBAC1B,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC1E,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,+CAA+C,OAAO,CAAC,IAAoB,EAAE,CAAC,CAAC;gBACjG,CAAC;YACH,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,gEAAgE;YAChE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI;QACJ,OAAO;QACP,QAAQ,EAAE,QAAe;QACzB,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,66 @@
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
+ * Computes the SHA256 hash of a file.
7
+ *
8
+ * Reads the file in streaming mode to handle large files efficiently
9
+ * without loading the entire contents into memory.
10
+ *
11
+ * @param path - Absolute or relative path to the file
12
+ * @returns The SHA256 hash as a 64-character lowercase hex string
13
+ *
14
+ * @throws {Error} When the file does not exist or cannot be read
15
+ *
16
+ * @remarks
17
+ * - Uses Node.js crypto module for hashing
18
+ * - Streams file contents to avoid memory pressure on large files
19
+ * - Returns lowercase hex encoding (64 characters for SHA256)
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { sha256File } from '@elaraai/e3';
24
+ *
25
+ * const hash = await sha256File('./myfile.txt');
26
+ * // hash: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
27
+ * ```
28
+ */
29
+ export declare function sha256File(path: string): Promise<string>;
30
+ /**
31
+ * Computes the SHA256 hash of a byte array.
32
+ *
33
+ * @param data - The bytes to hash
34
+ * @returns The SHA256 hash as a 64-character lowercase hex string
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { sha256Bytes } from '@elaraai/e3';
39
+ *
40
+ * const data = new TextEncoder().encode('hello world');
41
+ * const hash = sha256Bytes(data);
42
+ * // hash: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
43
+ * ```
44
+ */
45
+ export declare function sha256Bytes(data: Uint8Array): string;
46
+ /**
47
+ * Converts a SHA256 hex string to an object store path.
48
+ *
49
+ * The path uses the first 2 characters as a directory prefix for sharding,
50
+ * followed by the remaining 62 characters as the filename.
51
+ *
52
+ * @param hash - A 64-character lowercase hex SHA256 hash
53
+ * @returns Path of the form "objects/ab/cdef1234..."
54
+ *
55
+ * @throws {Error} When the hash is not a valid 64-character hex string
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { hashToPath } from '@elaraai/e3';
60
+ *
61
+ * const path = hashToPath('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9');
62
+ * // path: "objects/b9/4d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
63
+ * ```
64
+ */
65
+ export declare function hashToPath(hash: string): string;
66
+ //# sourceMappingURL=sha256.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../../src/sha256.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B9D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEpD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C"}
@@ -0,0 +1,106 @@
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
+ * SHA256 hashing utilities for e3.
7
+ */
8
+ import { createHash } from 'node:crypto';
9
+ import { createReadStream } from 'node:fs';
10
+ import { stat } from 'node:fs/promises';
11
+ /**
12
+ * Computes the SHA256 hash of a file.
13
+ *
14
+ * Reads the file in streaming mode to handle large files efficiently
15
+ * without loading the entire contents into memory.
16
+ *
17
+ * @param path - Absolute or relative path to the file
18
+ * @returns The SHA256 hash as a 64-character lowercase hex string
19
+ *
20
+ * @throws {Error} When the file does not exist or cannot be read
21
+ *
22
+ * @remarks
23
+ * - Uses Node.js crypto module for hashing
24
+ * - Streams file contents to avoid memory pressure on large files
25
+ * - Returns lowercase hex encoding (64 characters for SHA256)
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import { sha256File } from '@elaraai/e3';
30
+ *
31
+ * const hash = await sha256File('./myfile.txt');
32
+ * // hash: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
33
+ * ```
34
+ */
35
+ export async function sha256File(path) {
36
+ // Check file exists first for a clearer error message
37
+ try {
38
+ const stats = await stat(path);
39
+ if (!stats.isFile()) {
40
+ throw new Error(`Not a file: ${path}`);
41
+ }
42
+ }
43
+ catch (err) {
44
+ if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
45
+ throw new Error(`File not found: ${path}`);
46
+ }
47
+ throw err;
48
+ }
49
+ return new Promise((resolve, reject) => {
50
+ const hash = createHash('sha256');
51
+ const stream = createReadStream(path);
52
+ stream.on('data', (chunk) => {
53
+ hash.update(chunk);
54
+ });
55
+ stream.on('end', () => {
56
+ resolve(hash.digest('hex'));
57
+ });
58
+ stream.on('error', (err) => {
59
+ reject(err);
60
+ });
61
+ });
62
+ }
63
+ /**
64
+ * Computes the SHA256 hash of a byte array.
65
+ *
66
+ * @param data - The bytes to hash
67
+ * @returns The SHA256 hash as a 64-character lowercase hex string
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { sha256Bytes } from '@elaraai/e3';
72
+ *
73
+ * const data = new TextEncoder().encode('hello world');
74
+ * const hash = sha256Bytes(data);
75
+ * // hash: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
76
+ * ```
77
+ */
78
+ export function sha256Bytes(data) {
79
+ return createHash('sha256').update(data).digest('hex');
80
+ }
81
+ /**
82
+ * Converts a SHA256 hex string to an object store path.
83
+ *
84
+ * The path uses the first 2 characters as a directory prefix for sharding,
85
+ * followed by the remaining 62 characters as the filename.
86
+ *
87
+ * @param hash - A 64-character lowercase hex SHA256 hash
88
+ * @returns Path of the form "objects/ab/cdef1234..."
89
+ *
90
+ * @throws {Error} When the hash is not a valid 64-character hex string
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * import { hashToPath } from '@elaraai/e3';
95
+ *
96
+ * const path = hashToPath('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9');
97
+ * // path: "objects/b9/4d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
98
+ * ```
99
+ */
100
+ export function hashToPath(hash) {
101
+ if (!/^[0-9a-f]{64}$/.test(hash)) {
102
+ throw new Error(`Invalid SHA256 hash: expected 64 lowercase hex characters, got "${hash}"`);
103
+ }
104
+ return `objects/${hash.slice(0, 2)}/${hash.slice(2)}`;
105
+ }
106
+ //# sourceMappingURL=sha256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.js","sourceRoot":"","sources":["../../src/sha256.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,sDAAsD;IACtD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAEtC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACpB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,mEAAmE,IAAI,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,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=sha256.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.spec.d.ts","sourceRoot":"","sources":["../../src/sha256.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}