From 68a4f0e989e21cbf12aab9f252775dd6f6e724c8 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 24 Jun 2025 15:18:09 +0300 Subject: [PATCH 01/13] chore: fix TaggableMixin usage --- package-lock.json | 6 +++--- package.json | 2 +- src/units/base.js | 13 +++++-------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index faea4bb..7f8a767 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", @@ -2811,8 +2811,8 @@ }, "node_modules/@mat3ra/code": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", - "integrity": "sha512-w/v9+NRIZkRt6Ov5jBVowGmxnuAv1JrXMOderAZd9kVqTEvDMcPpImd1NV1VQTHG8xy7Uq2piRS0a15SyyVh6Q==", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", + "integrity": "sha512-msD7wOpiPSGD0ZF9FPRx541KdaOrodqi8xdpp1UFHcDQNt0Synjpmu42ThdYt6xjJG+IrulhQ8dZleggzIIGcQ==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index b735c48..4583ad6 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", diff --git a/src/units/base.js b/src/units/base.js index 98b0dfc..c97690b 100644 --- a/src/units/base.js +++ b/src/units/base.js @@ -1,17 +1,12 @@ -import { - NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity, - TaggableMixin, -} from "@mat3ra/code/dist/js/entity"; +import { NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity } from "@mat3ra/code/dist/js/entity"; +import { taggableMixin } from "@mat3ra/code/dist/js/entity/mixins/TaggableMixin"; import { getUUID } from "@mat3ra/code/dist/js/utils"; import lodash from "lodash"; -import { mix } from "mixwith"; import { UNIT_STATUSES } from "../enums"; // eslint-disable-next-line max-len -export class BaseUnit extends mix( - NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity, -).with(TaggableMixin) { +export class BaseUnit extends NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity { constructor(config) { super({ ...config, @@ -92,3 +87,5 @@ export class BaseUnit extends mix( return super.clone(flowchartIDOverrideConfigAsExtraContext); } } + +taggableMixin(BaseUnit.prototype); From 5e2e3de441520d8fdb2ef492321717cb014f6c47 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Wed, 25 Jun 2025 15:15:43 +0300 Subject: [PATCH 02/13] chore: new ade --- package-lock.json | 6 +++--- package.json | 2 +- src/units/execution.js | 7 ++++--- tests/subworkflow.test.js | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f8a767..7c3e01b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", @@ -2383,8 +2383,8 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", - "integrity": "sha512-uhFBtkZN1rXnUwbhD7ntzDxsnuYQdacmXbZxyy6cjV4vctRmwkDUIrZ3hn7FapNaBxLi8xHz0xMYycBxTpYF8g==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", + "integrity": "sha512-4rc12Aezx4J7vYUU3p2VVJae3d9ZIYknUR0ME0ixlvEeO6LxbTvQ6clEeqgQNmfwnXDizzG4xsvmi5fxce/wlQ==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 4583ad6..11d7af1 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", diff --git a/src/units/execution.js b/src/units/execution.js index 0211a02..8acf579 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -1,4 +1,5 @@ import { Application, Template } from "@exabyte-io/ade.js"; +import AdeFactory from "@exabyte-io/ade.js/dist/js/AdeFactory"; import { HashedInputArrayMixin } from "@mat3ra/code/dist/js/entity"; import { removeTimestampableKeysFromConfig } from "@mat3ra/code/dist/js/utils"; import { mix } from "mixwith"; @@ -23,9 +24,9 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { ]; _initApplication(config) { - this._application = this.constructor.Application.create(config.application); - this._executable = this._application.getExecutableByConfig(config.executable); - this._flavor = this._executable.getFlavorByConfig(config.flavor); + this._application = AdeFactory.createApplication(config.application); + this._executable = AdeFactory.getExecutableByConfig(this._application, config.executable); + this._flavor = AdeFactory.getFlavorByConfig(this._executable, config.flavor); this._templates = this._flavor ? this._flavor.inputAsTemplates : []; } diff --git a/tests/subworkflow.test.js b/tests/subworkflow.test.js index d9ed73e..2bfb6f9 100644 --- a/tests/subworkflow.test.js +++ b/tests/subworkflow.test.js @@ -1,4 +1,4 @@ -import { Application } from "@exabyte-io/ade.js"; +import AdeFactory from "@exabyte-io/ade.js/dist/js/AdeFactory"; import { expect } from "chai"; import { createSubworkflowByName } from "../src/subworkflows"; @@ -101,7 +101,7 @@ describe("subworkflows", () => { expect(subworkflow.units[0].application.version).to.be.equal("6.3"); expect(subworkflow.units[1].application?.version).to.be.equal(undefined); - const newApplication = Application.createFromNameVersionBuild({ + const newApplication = AdeFactory.createApplication({ name: "espresso", version: "6.7.0", }); From 46194f07186461dd78b84406e9b58c9b9411cd3f Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 26 Jun 2025 18:46:16 +0300 Subject: [PATCH 03/13] chore: new ade --- package-lock.json | 6 +++--- package.json | 2 +- src/units/execution.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c3e01b..160cc9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", @@ -2383,8 +2383,8 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", - "integrity": "sha512-4rc12Aezx4J7vYUU3p2VVJae3d9ZIYknUR0ME0ixlvEeO6LxbTvQ6clEeqgQNmfwnXDizzG4xsvmi5fxce/wlQ==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", + "integrity": "sha512-g9xwjloYtg8mzQe02jBMoecECDg1XgNuCUW0stE7wBzzPZlvPJB/X4wz0x7fTQpdQCGmhx7r1m2FNwFnJdO/cA==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 11d7af1..aad632a 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#8362680c135be8c94a4c0f27f85b91cf50fba1bc", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", diff --git a/src/units/execution.js b/src/units/execution.js index 8acf579..ee03ff8 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -129,7 +129,7 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { get input() { return ( this.prop("input") || - this.flavor.getInputAsRenderedTemplates(this.getCombinedContext()) || + AdeFactory.getInputAsRenderedTemplates(this.flavor, this.getCombinedContext()) || [] ); } From 4508df3bccf7db819c0ed0d4c5b0adb563afc176 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Fri, 27 Jun 2025 15:35:24 +0300 Subject: [PATCH 04/13] chore: new ade --- package-lock.json | 6 +++--- package.json | 2 +- src/units/execution.js | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 160cc9b..4628e9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", @@ -2383,8 +2383,8 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", - "integrity": "sha512-g9xwjloYtg8mzQe02jBMoecECDg1XgNuCUW0stE7wBzzPZlvPJB/X4wz0x7fTQpdQCGmhx7r1m2FNwFnJdO/cA==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", + "integrity": "sha512-EprsdkqRypfUbS+mHTiW4pWDnlLT4sj9PzWp2pBkP5L82WN16Vgin0R/C5WtYyGcb1NUA636vvcCjRGOW2ZdGQ==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index aad632a..ba92c71 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#e2c0f151519b21b53a217b705b10d94c55eab143", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", diff --git a/src/units/execution.js b/src/units/execution.js index ee03ff8..4f0af4d 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -25,7 +25,10 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { _initApplication(config) { this._application = AdeFactory.createApplication(config.application); - this._executable = AdeFactory.getExecutableByConfig(this._application, config.executable); + this._executable = AdeFactory.getExecutableByConfig( + this._application.name, + config.executable, + ); this._flavor = AdeFactory.getFlavorByConfig(this._executable, config.flavor); this._templates = this._flavor ? this._flavor.inputAsTemplates : []; } From 83e35c49dd849602c2721c42b20ca37e266c0dee Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 1 Jul 2025 23:16:13 +0300 Subject: [PATCH 05/13] fix: default entities --- package-lock.json | 6 +++--- package.json | 2 +- src/units/execution.js | 21 +++++++++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4628e9c..1853cb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#51864363d0d9525a2481b733068cb00396806370", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", @@ -2383,8 +2383,8 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", - "integrity": "sha512-EprsdkqRypfUbS+mHTiW4pWDnlLT4sj9PzWp2pBkP5L82WN16Vgin0R/C5WtYyGcb1NUA636vvcCjRGOW2ZdGQ==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#51864363d0d9525a2481b733068cb00396806370", + "integrity": "sha512-V5aYHiKdltBocyMeiPy35sTMk0h6KKpPiexZwONYlhfriOOFLh5xIaxaQqfUbsTgRBlx84MCV7nJiQJ7jMobwA==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index ba92c71..2f9c7df 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#81bc325032c828aa9142df9e2f639ffc0a1f8e86", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#51864363d0d9525a2481b733068cb00396806370", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", diff --git a/src/units/execution.js b/src/units/execution.js index 4f0af4d..e961c95 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -23,6 +23,9 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { "hasRelaxation", ]; + /** + * @override this method to provide entities from other sources + */ _initApplication(config) { this._application = AdeFactory.createApplication(config.application); this._executable = AdeFactory.getExecutableByConfig( @@ -33,6 +36,20 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { this._templates = this._flavor ? this._flavor.inputAsTemplates : []; } + /** + * @override this method to provide default executable from other source + */ + _getDefaultExecutable() { + return AdeFactory.getExecutableByName(this.application.name); + } + + /** + * @override this method to provide default flavor from other source + */ + _getDefaultFlavor() { + return AdeFactory.getFlavorByName(this.executable.name); + } + _initRuntimeItems(keys, config) { this._initApplication(config); super._initRuntimeItems(keys); @@ -66,14 +83,14 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { this._application = application; this.setProp("application", application.toJSON()); if (!omitSettingExecutable) { - this.setExecutable(this.application.defaultExecutable); + this.setExecutable(this._getDefaultExecutable()); } } setExecutable(executable) { this._executable = executable; this.setProp("executable", executable.toJSON()); - this.setFlavor(this.executable.defaultFlavor); + this.setFlavor(this._getDefaultFlavor()); } setFlavor(flavor) { From 3128c72d11d341a0043337b1347953136061377f Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 1 Jul 2025 23:39:33 +0300 Subject: [PATCH 06/13] fix: default entities --- src/units/execution.js | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/units/execution.js b/src/units/execution.js index e961c95..7142171 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -1,4 +1,4 @@ -import { Application, Template } from "@exabyte-io/ade.js"; +import { Template } from "@exabyte-io/ade.js"; import AdeFactory from "@exabyte-io/ade.js/dist/js/AdeFactory"; import { HashedInputArrayMixin } from "@mat3ra/code/dist/js/entity"; import { removeTimestampableKeysFromConfig } from "@mat3ra/code/dist/js/utils"; @@ -8,10 +8,6 @@ import _ from "underscore"; import { BaseUnit } from "./base"; export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { - static Application = Application; - - static Template = Template; - // keys to be omitted during toJSON static omitKeys = [ "job", @@ -50,6 +46,24 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { return AdeFactory.getFlavorByName(this.executable.name); } + /** + * @override this method to provide custom templates + */ + _getTemplatesFromInput() { + return this.getInput().map((i) => new Template(i)); + } + + /** + * @override this method to provide custom input from other sources + */ + _getInput() { + return ( + this.input || + AdeFactory.getInputAsRenderedTemplates(this.flavor, this.getCombinedContext()) || + [] + ); + } + _initRuntimeItems(keys, config) { this._initApplication(config); super._initRuntimeItems(keys); @@ -75,10 +89,6 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { return this._templates; } - get templatesFromInput() { - return this.input.map((i) => new this.constructor.Template(i)); - } - setApplication(application, omitSettingExecutable = false) { this._application = application; this.setProp("application", application.toJSON()); @@ -147,11 +157,7 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { } get input() { - return ( - this.prop("input") || - AdeFactory.getInputAsRenderedTemplates(this.flavor, this.getCombinedContext()) || - [] - ); + return this.prop("input"); } get renderingContext() { @@ -188,7 +194,7 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { const newRenderingContext = {}; const renderingContext = { ...this.context, ...context }; this.updateContext(renderingContext); // update in-memory context to properly render templates from input below - (fromTemplates ? this.templates : this.templatesFromInput).forEach((t) => { + (fromTemplates ? this.templates : this._getTemplatesFromInput()).forEach((t) => { newInput.push(t.getRenderedJSON(renderingContext)); Object.assign( newRenderingContext, @@ -225,7 +231,7 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { ...super.toJSON(), executable: this.executable.toJSON(), flavor: this.flavor.toJSON(), - input: this.input, + input: this._getInput(), // keys below are not propagated to the parent class on initialization of a new unit unless explicitly given name: this.name, // TODO: figure out the problem with storing context below From d739b103cd82b027920c429ba2aa4dec85c6b043 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Wed, 2 Jul 2025 00:23:44 +0300 Subject: [PATCH 07/13] fix: default entities --- src/units/execution.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/units/execution.js b/src/units/execution.js index 7142171..b24d270 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -64,6 +64,13 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { ); } + /** + * @override this method to provide custom input as templates + */ + _getInputAsTemplates() { + return AdeFactory.getInputAsTemplates(this.flavor); + } + _initRuntimeItems(keys, config) { this._initApplication(config); super._initRuntimeItems(keys); @@ -107,7 +114,7 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { this._flavor = flavor; this.setRuntimeItemsToDefaultValues(); this.setProp("flavor", flavor.toJSON()); - this.setTemplates(this.flavor.inputAsTemplates); + this.setTemplates(this._getInputAsTemplates()); } setTemplates(templates) { From e9428f5397efecc8b222bcf04187fbfad399bff1 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Wed, 2 Jul 2025 15:53:22 +0300 Subject: [PATCH 08/13] chore: remove HashedInputArrayMixin usage --- package-lock.json | 6 +++--- package.json | 2 +- src/units/execution.js | 21 +++++++++++++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1853cb1..7d6b2b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#72a4dd05240da180f09fcb04db9f469aea4077af", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", @@ -2811,8 +2811,8 @@ }, "node_modules/@mat3ra/code": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", - "integrity": "sha512-msD7wOpiPSGD0ZF9FPRx541KdaOrodqi8xdpp1UFHcDQNt0Synjpmu42ThdYt6xjJG+IrulhQ8dZleggzIIGcQ==", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#72a4dd05240da180f09fcb04db9f469aea4077af", + "integrity": "sha512-hFH6YKXzLlVyc2B936NEnbyaptfXHbdNL01uqB741op4GdZTpy6eBvxA43BKt8ej1gRIzoIdKsxEZhZnTJUe7Q==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 2f9c7df..11ef69b 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#556631e195b0b863c301f4c3d0af2723d354ebc1", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#72a4dd05240da180f09fcb04db9f469aea4077af", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", diff --git a/src/units/execution.js b/src/units/execution.js index b24d270..3d2a3b9 100644 --- a/src/units/execution.js +++ b/src/units/execution.js @@ -1,13 +1,16 @@ import { Template } from "@exabyte-io/ade.js"; import AdeFactory from "@exabyte-io/ade.js/dist/js/AdeFactory"; -import { HashedInputArrayMixin } from "@mat3ra/code/dist/js/entity"; -import { removeTimestampableKeysFromConfig } from "@mat3ra/code/dist/js/utils"; -import { mix } from "mixwith"; +import { + calculateHashFromObject, + removeCommentsFromSourceCode, + removeEmptyLinesFromString, + removeTimestampableKeysFromConfig, +} from "@mat3ra/code/dist/js/utils"; import _ from "underscore"; import { BaseUnit } from "./base"; -export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { +export class ExecutionUnit extends BaseUnit { // keys to be omitted during toJSON static omitKeys = [ "job", @@ -76,6 +79,16 @@ export class ExecutionUnit extends mix(BaseUnit).with(HashedInputArrayMixin) { super._initRuntimeItems(keys); } + /* + * @summary expects an array with elements containing field [{content: "..."}] + */ + get hashFromArrayInputContent() { + const objectForHashing = this._getInput().map((i) => { + return removeEmptyLinesFromString(removeCommentsFromSourceCode(i.content)); + }); + return calculateHashFromObject(objectForHashing); + } + get name() { return this.prop("name", this.flavor.name); } From 41266de9df1de05784f410ee46865ebea02cab22 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 3 Jul 2025 11:01:26 +0300 Subject: [PATCH 09/13] fix: ExecutionUnitConfigBuilder --- src/subworkflows/create.js | 2 +- .../builders/ExecutionUnitConfigBuilder.js | 37 +++++++++++-------- tests/unit.test.js | 34 +++++++++++++++++ tests/workflow.test.js | 10 +++++ 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/subworkflows/create.js b/src/subworkflows/create.js index cb8f436..b91e77d 100644 --- a/src/subworkflows/create.js +++ b/src/subworkflows/create.js @@ -91,7 +91,7 @@ function createTopLevel({ subworkflowData, applicationCls, modelFactoryCls, meth * @param unitFactoryCls {*} workflow unit class factory * @returns {*|{head: boolean, preProcessors: [], postProcessors: [], name: *, flowchartId: *, type: *, results: [], monitors: []}} */ -function createUnit({ config, application, unitBuilders, unitFactoryCls }) { +export function createUnit({ config, application, unitBuilders, unitFactoryCls }) { const { type, config: unitConfig } = config; if (type === "executionBuilder") { const { name, execName, flavorName, flowchartId } = unitConfig; diff --git a/src/units/builders/ExecutionUnitConfigBuilder.js b/src/units/builders/ExecutionUnitConfigBuilder.js index dfb1e04..73ece9e 100644 --- a/src/units/builders/ExecutionUnitConfigBuilder.js +++ b/src/units/builders/ExecutionUnitConfigBuilder.js @@ -1,15 +1,10 @@ -import { Application, Executable, Flavor } from "@exabyte-io/ade.js"; +/* eslint-disable class-methods-use-this */ +import AdeFactory from "@exabyte-io/ade.js/dist/js/AdeFactory"; import { UNIT_TYPES } from "../../enums"; import { UnitConfigBuilder } from "./UnitConfigBuilder"; export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { - static Application = Application; - - static Executable = Executable; - - static Flavor = Flavor; - constructor(name, application, execName, flavorName, flowchartId) { super({ name, type: UNIT_TYPES.execution, flowchartId }); @@ -29,14 +24,8 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { initialize(application, execName, flavorName) { this.application = application; - this.executable = this.constructor.Executable.create({ - name: execName, - application: this.application, - }); - this.flavor = this.constructor.Flavor.create({ - name: flavorName, - executable: this.executable, - }); + this.executable = this._createExecutable(this.application.name, execName); + this.flavor = this._createFlavor(this.executable, flavorName); } build() { @@ -47,4 +36,22 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { flavor: this.flavor.toJSON(), }; } + + /** + * Creates an executable instance. This method is intended to be overridden in subclasses. + * @param {Object} config - Configuration object for the executable + * @returns {Executable} The created executable instance + */ + _createExecutable(applicationName, execName) { + return AdeFactory.getExecutableByName(applicationName, execName); + } + + /** + * Creates a flavor instance. This method is intended to be overridden in subclasses. + * @param {Object} config - Configuration object for the flavor + * @returns {Flavor} The created flavor instance + */ + _createFlavor(executable, flavorName) { + return AdeFactory.getFlavorByName(executable, flavorName); + } } diff --git a/tests/unit.test.js b/tests/unit.test.js index 8c02cd3..57ad7f3 100644 --- a/tests/unit.test.js +++ b/tests/unit.test.js @@ -1,5 +1,9 @@ +import { Application } from "@exabyte-io/ade.js"; import { expect } from "chai"; +import { createUnit } from "../src/subworkflows/create"; +import { builders } from "../src/units/builders"; +import { UnitFactory } from "../src/units/factory"; import { createWorkflows } from "../src/workflows"; describe("units", () => { @@ -13,4 +17,34 @@ describe("units", () => { expect(exampleUnitClone).to.exist; expect(exampleUnit.flowchartId).to.not.equal(exampleUnitClone.flowchartId); }); + + it("can create execution unit", () => { + const unit = createUnit({ + config: { + type: "executionBuilder", + config: { + name: "test", + execName: "pw.x", + flavorName: "pw_scf", + flowchartId: "test", + }, + }, + application: new Application({ name: "espresso" }), + unitBuilders: builders, + unitFactoryCls: UnitFactory, + }); + + const expectedResults = [ + { name: "atomic_forces" }, + { name: "fermi_energy" }, + { name: "pressure" }, + { name: "stress_tensor" }, + { name: "total_energy" }, + { name: "total_energy_contributions" }, + { name: "total_force" }, + ]; + + expect(unit.flavor.results).to.deep.equal(expectedResults); + expect(unit.results).to.deep.equal(expectedResults); + }); }); diff --git a/tests/workflow.test.js b/tests/workflow.test.js index b89361b..7f11592 100644 --- a/tests/workflow.test.js +++ b/tests/workflow.test.js @@ -34,4 +34,14 @@ describe("workflow property", () => { // eslint-disable-next-line no-unused-expressions expect(mmWorkflow.isMultiMaterial).to.be.true; }); + + // it("properties are not empty", () => { + // // Nudged Elastic Band is multi-material + // const workflow = createWorkflow({ + // appName: "espresso", + // workflowData: allWorkflowData.workflows.espresso.total_energy, + // }); + + // console.log(JSON.stringify(workflow.toJSON(), null, 2)); + // }); }); From 25081998bf4dfbe3ed2bf8afaed1d8d422ced974 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 3 Jul 2025 11:05:17 +0300 Subject: [PATCH 10/13] fix: ExecutionUnitConfigBuilder --- src/units/builders/ExecutionUnitConfigBuilder.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/units/builders/ExecutionUnitConfigBuilder.js b/src/units/builders/ExecutionUnitConfigBuilder.js index 73ece9e..836e467 100644 --- a/src/units/builders/ExecutionUnitConfigBuilder.js +++ b/src/units/builders/ExecutionUnitConfigBuilder.js @@ -24,7 +24,7 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { initialize(application, execName, flavorName) { this.application = application; - this.executable = this._createExecutable(this.application.name, execName); + this.executable = this._createExecutable(this.application, execName); this.flavor = this._createFlavor(this.executable, flavorName); } @@ -42,8 +42,8 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { * @param {Object} config - Configuration object for the executable * @returns {Executable} The created executable instance */ - _createExecutable(applicationName, execName) { - return AdeFactory.getExecutableByName(applicationName, execName); + _createExecutable(application, execName) { + return AdeFactory.getExecutableByName(application.name, execName); } /** From bafcb5245c32c67486d62d4560dfdd5a54845f02 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 3 Jul 2025 11:07:21 +0300 Subject: [PATCH 11/13] chore: docstring --- src/units/builders/ExecutionUnitConfigBuilder.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/units/builders/ExecutionUnitConfigBuilder.js b/src/units/builders/ExecutionUnitConfigBuilder.js index 836e467..587feb5 100644 --- a/src/units/builders/ExecutionUnitConfigBuilder.js +++ b/src/units/builders/ExecutionUnitConfigBuilder.js @@ -39,7 +39,8 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { /** * Creates an executable instance. This method is intended to be overridden in subclasses. - * @param {Object} config - Configuration object for the executable + * @param {Application} application - The application object + * @param {string} execName - The name of the executable * @returns {Executable} The created executable instance */ _createExecutable(application, execName) { @@ -48,7 +49,8 @@ export class ExecutionUnitConfigBuilder extends UnitConfigBuilder { /** * Creates a flavor instance. This method is intended to be overridden in subclasses. - * @param {Object} config - Configuration object for the flavor + * @param {Executable} executable - The executable object + * @param {string} flavorName - The name of the flavor * @returns {Flavor} The created flavor instance */ _createFlavor(executable, flavorName) { From 442c84626f51281d522879a8c32e57bfedaceb7a Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 3 Jul 2025 11:40:32 +0300 Subject: [PATCH 12/13] chore: use AdeFactory in createSubworkflow --- src/subworkflows/create.js | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/subworkflows/create.js b/src/subworkflows/create.js index b91e77d..4688373 100644 --- a/src/subworkflows/create.js +++ b/src/subworkflows/create.js @@ -1,4 +1,4 @@ -import { Application } from "@exabyte-io/ade.js"; +import AdeFactoryDefault from "@exabyte-io/ade.js/dist/js/AdeFactory"; import { default_methods as MethodConfigs, default_models as ModelConfigs, @@ -14,17 +14,6 @@ import { workflowData as allWorkflowData } from "../workflows/workflows"; import { dynamicSubworkflowsByApp, getSurfaceEnergySubworkflowUnits } from "./dynamic"; import { Subworkflow } from "./subworkflow"; -/** - * @summary Thin wrapper around Application.createFromStored for extensibility - * @param config {Object} application config - * @param applicationCls {any} application class - * @returns {Application} the application - */ -function createApplication({ config, applicationCls }) { - const { name, version, build = "Default" } = config; - return applicationCls.create({ name, version, build }); -} - // NOTE: DFTModel => DFTModelConfig, configs should have the same name as the model/method class + "Config" at the end function _getConfigFromModelOrMethodName(name, kind) { const configs = kind === "Model" ? ModelConfigs : MethodConfigs; @@ -63,14 +52,14 @@ function createMethod({ config, methodFactoryCls }) { /** * @summary Create top-level objects used in subworkflow initialization * @param subworkflowData {Object} subworkflow data - * @param applicationCls {any} application class + * @param AdeFactory * @param modelFactoryCls {any} model factory class * @param methodFactoryCls {any} method factory class * @returns {{application: *, method: *, model: (DFTModel|Model), setSearchText: String|null}} */ -function createTopLevel({ subworkflowData, applicationCls, modelFactoryCls, methodFactoryCls }) { +function createTopLevel({ subworkflowData, modelFactoryCls, methodFactoryCls, AdeFactory }) { const { application: appConfig, model: modelConfig, method: methodConfig } = subworkflowData; - const application = createApplication({ config: appConfig, applicationCls }); + const application = AdeFactory.createApplication(appConfig); const model = createModel({ config: modelConfig, modelFactoryCls }); const { method, setSearchText } = createMethod({ config: methodConfig, methodFactoryCls }); return { @@ -143,7 +132,7 @@ function createDynamicUnits({ function createSubworkflow({ subworkflowData, - applicationCls = Application, + AdeFactory = AdeFactoryDefault, modelFactoryCls = ModelFactory, methodFactoryCls = MethodFactory, subworkflowCls = Subworkflow, @@ -152,7 +141,7 @@ function createSubworkflow({ }) { const { application, model, method, setSearchText } = createTopLevel({ subworkflowData, - applicationCls, + AdeFactory, modelFactoryCls, methodFactoryCls, }); From db8b5c883d32eb7e0dba2ab08f1f8c55fef00af8 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 3 Jul 2025 20:33:31 +0300 Subject: [PATCH 13/13] chore: add 'properties are not empty' test --- tests/workflow.test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/workflow.test.js b/tests/workflow.test.js index 7f11592..037ee38 100644 --- a/tests/workflow.test.js +++ b/tests/workflow.test.js @@ -35,13 +35,13 @@ describe("workflow property", () => { expect(mmWorkflow.isMultiMaterial).to.be.true; }); - // it("properties are not empty", () => { - // // Nudged Elastic Band is multi-material - // const workflow = createWorkflow({ - // appName: "espresso", - // workflowData: allWorkflowData.workflows.espresso.total_energy, - // }); - - // console.log(JSON.stringify(workflow.toJSON(), null, 2)); - // }); + it("properties are not empty", () => { + const workflow = createWorkflow({ + appName: "espresso", + workflowData: allWorkflowData.workflows.espresso.total_energy, + }); + + // eslint-disable-next-line no-unused-expressions + expect(workflow.properties).to.be.an("array").that.is.not.empty; + }); });