From 224c7cebe238a5bc8668c84dd37413fc58410537 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Wed, 18 Jun 2025 18:23:01 +0300 Subject: [PATCH 01/25] chore: move tests from code --- package-lock.json | 44 ++-- package.json | 7 +- src/context/mixins/ApplicationContextMixin.js | 21 ++ src/context/mixins/JobContextMixin.js | 82 ++++++++ src/context/mixins/MaterialContextMixin.js | 67 ++++++ src/context/mixins/MaterialsContextMixin.js | 36 ++++ .../mixins/MaterialsSetContextMixin.js | 38 ++++ src/context/mixins/WorkflowContextMixin.js | 46 ++++ src/context/providers.js | 25 +++ .../BoundaryConditionsFormDataProvider.js | 16 +- .../CollinearMagnetizationContextProvider.js | 14 +- .../providers/ExecutableContextProvider.js | 10 + .../providers/HubbardUContextProvider.js | 14 +- .../providers/MLSettingsContextProvider.js | 14 +- .../MLTrainTestSplitContextProvider.js | 16 +- ...onCollinearMagnetizationContextProvider.js | 12 +- .../PlanewaveCutoffsContextProvider.js | 16 +- .../providers/PointsGridFormDataProvider.js | 14 +- .../providers/PointsPathFormDataProvider.js | 20 +- .../espresso/QENEBContextProvider.js | 86 ++++++++ .../espresso/QEPWXContextProvider.js | 198 ++++++++++++++++++ .../NWChemTotalEnergyContextProvider.js | 116 ++++++++++ .../providers/vasp/VASPContextProvider.js | 77 +++++++ .../providers/vasp/VASPNEBContextProvider.js | 72 +++++++ src/context/registry.js | 5 +- src/patch.js | 2 +- tests/context.test.js | 115 ++++++++++ tests/espresso.test.js | 21 ++ 28 files changed, 1122 insertions(+), 82 deletions(-) create mode 100644 src/context/mixins/ApplicationContextMixin.js create mode 100644 src/context/mixins/JobContextMixin.js create mode 100644 src/context/mixins/MaterialContextMixin.js create mode 100644 src/context/mixins/MaterialsContextMixin.js create mode 100644 src/context/mixins/MaterialsSetContextMixin.js create mode 100644 src/context/mixins/WorkflowContextMixin.js create mode 100644 src/context/providers/ExecutableContextProvider.js create mode 100644 src/context/providers/espresso/QENEBContextProvider.js create mode 100644 src/context/providers/espresso/QEPWXContextProvider.js create mode 100644 src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js create mode 100644 src/context/providers/vasp/VASPContextProvider.js create mode 100644 src/context/providers/vasp/VASPNEBContextProvider.js create mode 100644 tests/context.test.js create mode 100644 tests/espresso.test.js diff --git a/package-lock.json b/package-lock.json index c5b3d6bb..9c64c1ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@babel/preset-react": "7.16.7", "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", + "@exabyte-io/periodic-table.js": "2022.6.8-0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -25,14 +26,14 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.5.5-0", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "2025.4.27-0", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "2025.4.30-0", + "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", @@ -2335,23 +2336,13 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/@exabyte-io/ade.js": { - "version": "2025.5.5-0", - "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.5.5-0.tgz", - "integrity": "sha512-tMcToIDpo73Dm0KBITFJ1kFRLtWD+sRnG4wBX99XhRd+i/GxFca58SFUUcB+1axql862PPmhA90cvBnyAY6/7Q==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", + "integrity": "sha512-nNglWNXUCbTRL7Cm37TfNdqG7gDFW2PqtvOrP0cHp9hFNxPxUNZzcJd/SlU0jCe+awaUEA6ITA6j5fT4E11IEg==", "dev": true, - "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@babel/cli": "7.16.0", - "@babel/core": "7.16.0", - "@babel/eslint-parser": "7.16.3", - "@babel/plugin-proposal-class-properties": "7.16.0", - "@babel/preset-env": "7.16.4", - "@babel/preset-react": "7.16.7", - "@babel/register": "^7.16.0", - "@babel/runtime-corejs3": "7.16.8", - "@exabyte-io/periodic-table.js": "2022.6.8-0", "lodash": "^4.17.21", - "mixwith": "^0.1.1", "nunjucks": "^3.2.4", "underscore": "^1.13.3", "underscore.string": "^3.3.4" @@ -2543,7 +2534,6 @@ "version": "2022.6.8-0", "resolved": "https://registry.npmjs.org/@exabyte-io/periodic-table.js/-/periodic-table.js-2022.6.8-0.tgz", "integrity": "sha512-tN9V+Q6AUo/RVn9qrgx4dV+1VI5GbBjwJGbx4+K+zIw2W8Rnwp2l22lj123Xj9wdFLpygyPruETCM04XJkPNuw==", - "dev": true, "hasInstallScript": true, "dependencies": { "@babel/cli": "7.16.0", @@ -2562,7 +2552,6 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.0.tgz", "integrity": "sha512-lzl4yfs0zVXnooeLE0AAfYaT7F3SPA8yB2Bj4W1BiZwLbMS3MZH35ZvCWSRHvneUugwuM+Wsnrj7h0F7UmU3NQ==", - "dev": true, "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -2580,8 +2569,7 @@ "node_modules/@exabyte-io/periodic-table.js/node_modules/underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==", - "dev": true + "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", @@ -2770,10 +2758,11 @@ "dev": true }, "node_modules/@mat3ra/code": { - "version": "2025.4.27-0", - "resolved": "https://registry.npmjs.org/@mat3ra/code/-/code-2025.4.27-0.tgz", - "integrity": "sha512-v4fewXJEImCBh716z/hmI9GqU2JVl1XUYjUbvgZ3pYwxph1g1nU+H7DgRHu415t8ByJsjdLVkgkBlYU4+m/HSw==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", + "integrity": "sha512-8KhoEH+n+vIPl0n8qP9n/IluiM4huRntgqU3lKnBhwd6D+HvqFkAKdJAOP6E0ecvM1lFg6VPVsyAuG3I2yIhLA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/mathjs": "^5.0.1", "crypto-js": "^4.2.0", @@ -3155,10 +3144,11 @@ } }, "node_modules/@mat3ra/made": { - "version": "2025.4.30-0", - "resolved": "https://registry.npmjs.org/@mat3ra/made/-/made-2025.4.30-0.tgz", - "integrity": "sha512-vuXirZpSXEE77eqnUkS6+PyjPTfauCm0mc7FMIUggVN4Swi69t9COpd16IWe05DCtWSrzGebPbz+Bsqm77w9sg==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "integrity": "sha512-c+QC8p72ENTbRdx1aQOpP/soLLcnzF6P3uXf9cQicVeZ8H+IJpnvU3ORpMkPFWn4VZ5mU32EDqqnrRc4kXK+0A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/core": "7.24.1", "@exabyte-io/periodic-table.js": "2022.5.28-0", diff --git a/package.json b/package.json index 3c68d79e..133167d1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@babel/preset-react": "7.16.7", "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", + "@exabyte-io/periodic-table.js": "2022.6.8-0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -46,14 +47,14 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.5.5-0", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "2025.4.27-0", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "2025.4.30-0", + "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", diff --git a/src/context/mixins/ApplicationContextMixin.js b/src/context/mixins/ApplicationContextMixin.js new file mode 100644 index 00000000..d0fcf46b --- /dev/null +++ b/src/context/mixins/ApplicationContextMixin.js @@ -0,0 +1,21 @@ +export function applicationContextMixin(item) { + const properties = { + _application: undefined, + + initApplicationContextMixin() { + // @ts-ignore + if (!this.constructor.Application) { + throw Error("ApplicationContextMixin: Application is undefined"); + } + this._application = + (this.config.context && this.config.context.application) || + this.constructor.Application.createDefault(); + }, + + get application() { + return this._application; + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/JobContextMixin.js b/src/context/mixins/JobContextMixin.js new file mode 100644 index 00000000..64d95f08 --- /dev/null +++ b/src/context/mixins/JobContextMixin.js @@ -0,0 +1,82 @@ +// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +// import type { JobSchema } from "@mat3ra/esse/dist/js/types"; + +// type Job = JobSchema & { +// parentJob?: Job; +// }; + +// type JobConfig = { +// context?: { +// job?: Job; +// }; +// }; + +const defaultJob = { + workflow: { + subworkflows: [], + units: [], + }, + status: "pre-submission", + compute: { + queue: "D", + nodes: 1, + ppn: 1, + timeLimit: "3600", + }, + _project: { + _id: "", + }, +}; + +// export type JobContextMixinType = { +// isEdited?: boolean; +// job: Job; +// _job: Job; +// initJobContextMixin: () => void; +// }; + +// export function jobContextMixin(item: ContextProvider) { +// const properties = { +// isEdited: false, + +// _job: defaultJob, + +// get job() { +// return this._job; +// }, + +// initJobContextMixin() { +// const config = this.config as JobConfig; +// this._job = (config.context && config.context.job) || defaultJob; +// this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) +// }, +// } as JobContextMixinType & typeof item; + +// Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +// } + +// export function JobContextMixin>(superclass: T) { +// jobContextMixin(superclass.prototype); +// return superclass as T & Constructor; +// } + +export function jobContextMixin(item) { + const properties = { + isEdited: false, + + _job: defaultJob, + + get job() { + return this._job; + }, + + initJobContextMixin() { + const { config } = this; + this._job = (config.context && config.context.job) || defaultJob; + this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialContextMixin.js b/src/context/mixins/MaterialContextMixin.js new file mode 100644 index 00000000..91f31c54 --- /dev/null +++ b/src/context/mixins/MaterialContextMixin.js @@ -0,0 +1,67 @@ +// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; +// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; +// import type { ApplicationMixin } from "src/js/applicationMixin"; + +// import Application from "../../application"; + +// export type MaterialContextMixinType = { +// assertMaterial: () => void; +// isEditedIsSetToFalseOnMaterialUpdate?: boolean; +// updateMaterialHash: () => void; +// isMaterialCreatedDefault: boolean; +// isMaterialUpdated: boolean; +// material: MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet; +// extraData?: { +// materialHash: string; +// }; +// initMaterialContextMixin: () => void; +// _application: ApplicationMixin; +// }; + +export function materialContextMixin( + // item: ContextProvider & { _material?: MaterialMixin & InMemoryEntity }, + item, +) { + const properties = { + _material: undefined, + + updateMaterialHash() { + if (this.isEditedIsSetToFalseOnMaterialUpdate) this.isEdited = false; + this.extraData = { materialHash: this.material.hash }; + }, + + // Workaround: Material.createDefault() used to initiate workflow reducer and hence here too + // does not have an id. Here we catch when such material is used and avoid resetting isEdited + get isMaterialCreatedDefault() { + return !this.material.id; + }, + + get isMaterialUpdated() { + return Boolean(this.extraData && this.extraData.materialHash !== this.material.hash); + }, + + get material() { + if (!this._material) { + throw new Error("Material is not set"); + } + return this._material; + }, + + initMaterialContextMixin() { + // @ts-ignore + if (!this.constructor.Material) { + throw Error("MaterialContextMixin: Material is undefined"); + } + this._material = this.config.context && this.config.context.material; + if (!this._material) { + this._material = this.constructor.Material.createDefault(); + } + this.updateMaterialHash(); + }, + }; // as MaterialContextMixinType & typeof item + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialsContextMixin.js b/src/context/mixins/MaterialsContextMixin.js new file mode 100644 index 00000000..0aa667eb --- /dev/null +++ b/src/context/mixins/MaterialsContextMixin.js @@ -0,0 +1,36 @@ +// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; +// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; + +// export type MaterialsContextMixinType = { +// materials: (MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet)[]; +// initMaterialsContextMixin: () => void; +// }; + +export function materialsContextMixin( + // item: ContextProvider & { _materials: (MaterialMixin & InMemoryEntity)[] }, + item, +) { + const properties = { + get materials() { + return this._materials; + }, + initMaterialsContextMixin() { + // @ts-ignore + const materials = this.config.context?.materials; + // @ts-ignore + if (!this.constructor.Material) { + throw Error("MaterialsContextMixin: Material is undefined"); + } + this._materials = + materials && materials.length + ? materials + : // @ts-ignore + [this.constructor.Material.createDefault()]; + }, + }; // as MaterialsContextMixinType & typeof item; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialsSetContextMixin.js b/src/context/mixins/MaterialsSetContextMixin.js new file mode 100644 index 00000000..81c669fc --- /dev/null +++ b/src/context/mixins/MaterialsSetContextMixin.js @@ -0,0 +1,38 @@ +// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; +// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; +import { compareEntitiesInOrderedSetForSorting } from "@mat3ra/code/dist/js/entity/set/ordered/utils"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; + +// export type MaterialsSetContextMixinType = { +// materialsSet: any; +// _materialsSet: any; +// sortMaterialsByIndexInSet: ( +// materials?: OrderedInMemoryEntityInSet[], +// ) => OrderedInMemoryEntityInSet[]; +// initMaterialsSetContextMixin: () => void; +// }; + +export function materialsSetContextMixin(item) { + const properties = { + _materialsSet: undefined, + + get materialsSet() { + return this._materialsSet; + }, + + initMaterialsSetContextMixin() { + // @ts-ignore + this._materialsSet = this.config.context?.materialsSet; + }, + + // materials: OrderedInMemoryEntityInSet[] = [] + sortMaterialsByIndexInSet(materials = []) { + // DO NOT SORT IN PLACE AS IT CHANGES THE ORDER IN `this.materials` AND HAS SIDE EFFECTS (MaterialViewer). + return materials.concat().sort((a, b) => { + return compareEntitiesInOrderedSetForSorting(a, b, this.materialsSet._id, false); + }); + }, + }; // as MaterialsSetContextMixinType & typeof item; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/WorkflowContextMixin.js b/src/context/mixins/WorkflowContextMixin.js new file mode 100644 index 00000000..12a259b5 --- /dev/null +++ b/src/context/mixins/WorkflowContextMixin.js @@ -0,0 +1,46 @@ +// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +// import type { WorkflowSchema } from "@mat3ra/esse/dist/js/types"; + +// type Workflow = WorkflowSchema & { +// hasRelaxation: boolean; +// }; + +// type WorkflowConfig = { +// context?: { +// workflow?: Workflow; +// }; +// }; + +const defaultWorkflow = { + subworkflows: [], + units: [], + hasRelaxation: false, +}; + +// export type WorkflowContextMixinType = { +// isEdited?: boolean; +// workflow: Workflow; +// _workflow: Workflow; +// initWorkflowContextMixin: () => void; +// }; + +export function workflowContextMixin(item) { + const properties = { + isEdited: false, + + _workflow: defaultWorkflow, + + get workflow() { + return this._workflow; + }, + + initWorkflowContextMixin() { + const { config } = this; // as WorkflowConfig; + this._workflow = (config.context && config.context.workflow) || defaultWorkflow; + this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) + }, + }; // as WorkflowContextMixinType & typeof item; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/providers.js b/src/context/providers.js index 94e43831..c84447ab 100644 --- a/src/context/providers.js +++ b/src/context/providers.js @@ -1,4 +1,9 @@ import context from "./context"; +import QENEBContextProvider from "./providers/espresso/QENEBContextProvider"; +import QEPWXContextProvider from "./providers/espresso/QEPWXContextProvider"; +import NWChemTotalEnergyContextProvider from "./providers/nwchem/NWChemTotalEnergyContextProvider"; +import VASPContextProvider from "./providers/vasp/VASPContextProvider"; +import VASPNEBContextProvider from "./providers/vasp/VASPNEBContextProvider"; const { BoundaryConditionsFormDataProvider, @@ -112,4 +117,24 @@ export const wodeProviders = { providerCls: NonCollinearMagnetizationContextProvider, config: _makeImportant({ name: "nonCollinearMagnetization" }), }, + QEPWXInputDataManager: { + providerCls: QEPWXContextProvider, + config: { name: "input" }, + }, + QENEBInputDataManager: { + providerCls: QENEBContextProvider, + config: { name: "input" }, + }, + VASPInputDataManager: { + providerCls: VASPContextProvider, + config: { name: "input" }, + }, + VASPNEBInputDataManager: { + providerCls: VASPNEBContextProvider, + config: { name: "input" }, + }, + NWChemInputDataManager: { + providerCls: NWChemTotalEnergyContextProvider, + config: { name: "input" }, + }, }; diff --git a/src/context/providers/BoundaryConditionsFormDataProvider.js b/src/context/providers/BoundaryConditionsFormDataProvider.js index c9bd6f18..c6b7a253 100644 --- a/src/context/providers/BoundaryConditionsFormDataProvider.js +++ b/src/context/providers/BoundaryConditionsFormDataProvider.js @@ -1,13 +1,17 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { deepClone } from "@mat3ra/code/dist/js/utils"; import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; -export class BoundaryConditionsFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + +export class BoundaryConditionsFormDataProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; + constructor(config) { + super(config); + this.initMaterialContextMixin(); + } + get boundaryConditions() { return this.material.metadata.boundaryConditions || {}; } @@ -74,3 +78,5 @@ export class BoundaryConditionsFormDataProvider extends mix(JSONSchemaFormDataPr }; } } + +materialContextMixin(BoundaryConditionsFormDataProvider.prototype); diff --git a/src/context/providers/CollinearMagnetizationContextProvider.js b/src/context/providers/CollinearMagnetizationContextProvider.js index 71c53ff0..8cfa6e2c 100644 --- a/src/context/providers/CollinearMagnetizationContextProvider.js +++ b/src/context/providers/CollinearMagnetizationContextProvider.js @@ -1,15 +1,17 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; -import { mix } from "mixwith"; -export class CollinearMagnetizationContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + +export class CollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; constructor(config) { super(config); + + this.initMaterialContextMixin(); + this.firstElement = this.uniqueElementsWithLabels?.length > 0 ? this.uniqueElementsWithLabels[0] : ""; this.isTotalMagnetization = lodash.get(this.data, "isTotalMagnetization", false); @@ -114,3 +116,5 @@ export class CollinearMagnetizationContextProvider extends mix(JSONSchemaFormDat }; } } + +materialContextMixin(CollinearMagnetizationContextProvider.prototype); diff --git a/src/context/providers/ExecutableContextProvider.js b/src/context/providers/ExecutableContextProvider.js new file mode 100644 index 00000000..7787682a --- /dev/null +++ b/src/context/providers/ExecutableContextProvider.js @@ -0,0 +1,10 @@ +import { ContextProvider } from "@mat3ra/code/dist/js/context"; + +export default class ExecutableContextProvider extends ContextProvider { + constructor(config) { + super({ + ...config, + domain: "executable", + }); + } +} diff --git a/src/context/providers/HubbardUContextProvider.js b/src/context/providers/HubbardUContextProvider.js index 2324af35..8870f82d 100644 --- a/src/context/providers/HubbardUContextProvider.js +++ b/src/context/providers/HubbardUContextProvider.js @@ -1,6 +1,7 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; + +import { materialContextMixin } from "../mixins/MaterialContextMixin"; const defaultHubbardConfig = { atomicSpecies: "", @@ -8,13 +9,14 @@ const defaultHubbardConfig = { hubbardUValue: 1.0, }; -export class HubbardUContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { +export class HubbardUContextProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; constructor(config) { super(config); + + this.initMaterialContextMixin(); + this.uniqueElements = this.material?.Basis?.uniqueElements || []; this.orbitalList = [ "2p", @@ -97,3 +99,5 @@ export class HubbardUContextProvider extends mix(JSONSchemaFormDataProvider).wit }; } } + +materialContextMixin(HubbardUContextProvider.prototype); diff --git a/src/context/providers/MLSettingsContextProvider.js b/src/context/providers/MLSettingsContextProvider.js index f7360f7b..79b402e6 100644 --- a/src/context/providers/MLSettingsContextProvider.js +++ b/src/context/providers/MLSettingsContextProvider.js @@ -1,10 +1,16 @@ import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import { ContextProvider } from "@mat3ra/code/dist/js/context"; -export class MLSettingsContextProvider extends mix(ContextProvider).with(ApplicationContextMixin) { +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; + +export class MLSettingsContextProvider extends ContextProvider { static Application = Application; + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } + // eslint-disable-next-line class-methods-use-this get uiSchema() { return { @@ -41,3 +47,5 @@ export class MLSettingsContextProvider extends mix(ContextProvider).with(Applica }; } } + +applicationContextMixin(MLSettingsContextProvider.prototype); diff --git a/src/context/providers/MLTrainTestSplitContextProvider.js b/src/context/providers/MLTrainTestSplitContextProvider.js index 02d35854..8da32e5f 100644 --- a/src/context/providers/MLTrainTestSplitContextProvider.js +++ b/src/context/providers/MLTrainTestSplitContextProvider.js @@ -1,12 +1,16 @@ import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import { ContextProvider } from "@mat3ra/code/dist/js/context"; -export class MLTrainTestSplitContextProvider extends mix(ContextProvider).with( - ApplicationContextMixin, -) { +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; + +export class MLTrainTestSplitContextProvider extends ContextProvider { static Application = Application; + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } + // eslint-disable-next-line class-methods-use-this get uiSchema() { return { @@ -40,3 +44,5 @@ export class MLTrainTestSplitContextProvider extends mix(ContextProvider).with( }; } } + +applicationContextMixin(MLTrainTestSplitContextProvider.prototype); diff --git a/src/context/providers/NonCollinearMagnetizationContextProvider.js b/src/context/providers/NonCollinearMagnetizationContextProvider.js index d43b82b1..0c834dd9 100644 --- a/src/context/providers/NonCollinearMagnetizationContextProvider.js +++ b/src/context/providers/NonCollinearMagnetizationContextProvider.js @@ -1,15 +1,15 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; -import { mix } from "mixwith"; -export class NonCollinearMagnetizationContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + +export class NonCollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; constructor(config) { super(config); + this.initMaterialContextMixin(); this.isStartingMagnetization = lodash.get(this.data, "isStartingMagnetization", true); this.isConstrainedMagnetization = lodash.get( this.data, @@ -268,3 +268,5 @@ export class NonCollinearMagnetizationContextProvider extends mix(JSONSchemaForm }; } } + +materialContextMixin(NonCollinearMagnetizationContextProvider.prototype); diff --git a/src/context/providers/PlanewaveCutoffsContextProvider.js b/src/context/providers/PlanewaveCutoffsContextProvider.js index ee4249c1..bbcc25bf 100644 --- a/src/context/providers/PlanewaveCutoffsContextProvider.js +++ b/src/context/providers/PlanewaveCutoffsContextProvider.js @@ -1,6 +1,7 @@ import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import { ContextProvider } from "@mat3ra/code/dist/js/context"; + +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; const cutoffConfig = { vasp: {}, // assuming default cutoffs for VASP @@ -11,11 +12,14 @@ const cutoffConfig = { }, }; -export class PlanewaveCutoffsContextProvider extends mix(ContextProvider).with( - ApplicationContextMixin, -) { +export class PlanewaveCutoffsContextProvider extends ContextProvider { static Application = Application; + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } + // eslint-disable-next-line class-methods-use-this get uiSchema() { return { @@ -63,3 +67,5 @@ export class PlanewaveCutoffsContextProvider extends mix(ContextProvider).with( }; } } + +applicationContextMixin(PlanewaveCutoffsContextProvider.prototype); diff --git a/src/context/providers/PointsGridFormDataProvider.js b/src/context/providers/PointsGridFormDataProvider.js index 8af32b6d..65cb499e 100644 --- a/src/context/providers/PointsGridFormDataProvider.js +++ b/src/context/providers/PointsGridFormDataProvider.js @@ -1,20 +1,22 @@ import { units as UNITS } from "@mat3ra/code/dist/js/constants"; -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; -import { mix } from "mixwith"; + +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + // TODO : pass appSettings to use defaultKPPRA -export class PointsGridFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { +export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; static _defaultKPPRA = 5; constructor(config) { super(config); + this.initMaterialContextMixin(); + this._divisor = config.divisor || 1; // KPPRA will be divided by this number this.reciprocalLattice = new Made.ReciprocalLattice(this.material.lattice); @@ -284,3 +286,5 @@ export class PointsGridFormDataProvider extends mix(JSONSchemaFormDataProvider). return data; } } + +materialContextMixin(PointsGridFormDataProvider.prototype); diff --git a/src/context/providers/PointsPathFormDataProvider.js b/src/context/providers/PointsPathFormDataProvider.js index de472ea3..28857769 100644 --- a/src/context/providers/PointsPathFormDataProvider.js +++ b/src/context/providers/PointsPathFormDataProvider.js @@ -1,29 +1,26 @@ /* eslint-disable max-classes-per-file */ /* eslint react/prop-types: 0 */ import { Application } from "@exabyte-io/ade.js"; -import { - ApplicationContextMixin, - JSONSchemaFormDataProvider, - MaterialContextMixin, -} from "@mat3ra/code/dist/js/context"; +import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; import s from "underscore.string"; +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + const defaultPoint = "Г"; const defaultSteps = 10; -export class PointsPathFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - ApplicationContextMixin, - MaterialContextMixin, -) { +export class PointsPathFormDataProvider extends JSONSchemaFormDataProvider { static Material = Made.Material; static Application = Application; constructor(config) { super(config); + this.initMaterialContextMixin(); + this.initApplicationContextMixin(); this.reciprocalLattice = new Made.ReciprocalLattice(this.material.lattice); this.symmetryPoints = this.symmetryPointsFromMaterial; } @@ -168,3 +165,6 @@ export class ExplicitPointsPath2PIBAFormDataProvider extends ExplicitPointsPathF return true; } } + +materialContextMixin(PointsPathFormDataProvider.prototype); +applicationContextMixin(PointsPathFormDataProvider.prototype); diff --git a/src/context/providers/espresso/QENEBContextProvider.js b/src/context/providers/espresso/QENEBContextProvider.js new file mode 100644 index 00000000..9ed36a63 --- /dev/null +++ b/src/context/providers/espresso/QENEBContextProvider.js @@ -0,0 +1,86 @@ +import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; +import { + // type MethodDataContextMixinType, + methodDataContextMixin, +} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; +// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; +// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +import { Made } from "@mat3ra/made"; +// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; +import lodash from "lodash"; + +// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; +// import type { MaterialContextMixinType } from "../../mixins/MaterialContextMixin"; +import { materialContextMixin } from "../../mixins/MaterialContextMixin"; +// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; +import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; +import { + // type MaterialsSetContextMixinType, + materialsSetContextMixin, +} from "../../mixins/MaterialsSetContextMixin"; +import { + // type WorkflowContextMixinType, + workflowContextMixin, +} from "../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; +import QEPWXContextProvider from "./QEPWXContextProvider"; + +// export type Base = typeof ExecutableContextProvider & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor; + +// export type Material = MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet; + +export default class QENEBContextProvider extends ExecutableContextProvider { + static Material = Made.Material; + + _material = undefined; + + _materials = []; + + _materialsSet = undefined; + + constructor(config) { + super(config); + this.initJobContextMixin(); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initMaterialContextMixin(); + this.initMaterialsSetContextMixin(); + } + + getData() { + const sortedMaterials = this.sortMaterialsByIndexInSet(this.materials); + const PWXContexts = sortedMaterials.map((material) => { + const context = { ...this.config.context, material }; + const config = { ...this.config, context }; + return new QEPWXContextProvider(config).getData(); + }); + + return { + ...lodash.omit(PWXContexts[0], [ + "ATOMIC_POSITIONS", + "ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS", + ]), + FIRST_IMAGE: PWXContexts[0].ATOMIC_POSITIONS, + LAST_IMAGE: PWXContexts[PWXContexts.length - 1].ATOMIC_POSITIONS, + INTERMEDIATE_IMAGES: PWXContexts.slice(1, PWXContexts.length - 1).map( + (data) => data.ATOMIC_POSITIONS, + ), + }; + } +} + +materialContextMixin(QENEBContextProvider.prototype); +materialsContextMixin(QENEBContextProvider.prototype); +methodDataContextMixin(QENEBContextProvider.prototype); +workflowContextMixin(QENEBContextProvider.prototype); +jobContextMixin(QENEBContextProvider.prototype); +materialsSetContextMixin(QENEBContextProvider.prototype); diff --git a/src/context/providers/espresso/QEPWXContextProvider.js b/src/context/providers/espresso/QEPWXContextProvider.js new file mode 100644 index 00000000..8e154a4c --- /dev/null +++ b/src/context/providers/espresso/QEPWXContextProvider.js @@ -0,0 +1,198 @@ +import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; +import { + // type MethodDataContextMixinType, + // type Pseudo, + methodDataContextMixin, +} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; +// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity/in_memory"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +import { Made } from "@mat3ra/made"; +// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; +import path from "path"; +import s from "underscore.string"; + +import { + // type JobContextMixinType, + jobContextMixin, +} from "../../mixins/JobContextMixin"; +import { + // type MaterialContextMixinType, + materialContextMixin, +} from "../../mixins/MaterialContextMixin"; +import { + // type MaterialsContextMixinType, + materialsContextMixin, +} from "../../mixins/MaterialsContextMixin"; +import { + // type WorkflowContextMixinType, + workflowContextMixin, +} from "../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +// export type Material = MaterialMixin & InMemoryEntity; + +// export type Base = typeof ExecutableContextProvider & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor; + +export default class QEPWXContextProvider extends ExecutableContextProvider { + static Material = Made.Material; + + _material = undefined; + + _materials = []; + + constructor(config) { + super(config); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + this.initMaterialContextMixin(); + } + + static atomSymbols(material) { + return material.Basis.uniqueElements; + } + + static uniqueElementsWithLabels(material) { + // return unique items + return [...new Set(material.Basis.elementsWithLabelsArray)]; + } + + /** Returns the input text block for atomic positions WITH constraints. + */ + static atomicPositionsWithConstraints(material) { + return material.Basis.getAtomicPositionsWithConstraintsAsStrings().join("\n"); + } + + /** Returns the input text block for atomic positions + * Note: does NOT include constraints + */ + static atomicPositions(material) { + return material.Basis.atomicPositions.join("\n"); + } + + static NAT(material) { + return material.Basis.atomicPositions.length; + } + + static NTYP(material) { + return material.Basis.uniqueElements.length; + } + + static NTYP_WITH_LABELS(material) { + return this.uniqueElementsWithLabels(material).length; + } + + buildQEPWXContext(material) { + const IBRAV = 0; // use CELL_PARAMETERS to define Bravais lattice + + return { + IBRAV, + RESTART_MODE: this.RESTART_MODE, + ATOMIC_SPECIES: this.ATOMIC_SPECIES(material), + ATOMIC_SPECIES_WITH_LABELS: this.ATOMIC_SPECIES_WITH_LABELS(material), + NAT: QEPWXContextProvider.NAT(material), + NTYP: QEPWXContextProvider.NTYP(material), + NTYP_WITH_LABELS: QEPWXContextProvider.NTYP_WITH_LABELS(material), + ATOMIC_POSITIONS: QEPWXContextProvider.atomicPositionsWithConstraints(material), + ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS: QEPWXContextProvider.atomicPositions(material), + CELL_PARAMETERS: QEPWXContextProvider.CELL_PARAMETERS(material), + }; + } + + getDataPerMaterial() { + if (!this.materials || this.materials.length <= 1) return {}; + return { perMaterial: this.materials.map((material) => this.buildQEPWXContext(material)) }; + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + // the below values are read from PlanewaveDataManager instead + // ECUTWFC = 40; + // ECUTRHO = 200; + + return { + ...this.buildQEPWXContext(this.material), + ...this.getDataPerMaterial(), + }; + } + + get RESTART_MODE() { + return this.job.parentJob || this.workflow.hasRelaxation ? "restart" : "from_scratch"; + } + + getPseudoBySymbol(symbol) { + return (this.methodData.pseudo || []).find((p) => p.element === symbol); + } + + /** Builds ATOMIC SPECIES block of pw.x input in the format + * X Mass_X PseudoPot_X + * where X is the atom label + * Mass_X is the mass of element X [amu] + * PseudoPot_X is the pseudopotential filename associated with element X + * + * Note: assumes this.methodData is defined + */ + ATOMIC_SPECIES(material) { + return QEPWXContextProvider.atomSymbols(material) + .map((symbol) => { + const pseudo = this.getPseudoBySymbol(symbol); + return QEPWXContextProvider.symbolToAtomicSpecie(symbol, pseudo); + }) + .join("\n"); + } + + ATOMIC_SPECIES_WITH_LABELS(material) { + return QEPWXContextProvider.uniqueElementsWithLabels(material) + .map((symbol) => { + const symbolWithoutLabel = symbol.replace(/\d$/, ""); + const label = symbol.match(/\d$/g) ? symbol.match(/\d$/g)?.[0] : ""; + const pseudo = this.getPseudoBySymbol(symbolWithoutLabel); + return QEPWXContextProvider.elementAndPseudoToAtomicSpecieWithLabels( + symbolWithoutLabel, + pseudo, + label, + ); + }) + .join("\n"); + } + + static CELL_PARAMETERS(material) { + return material.Lattice.vectorArrays + .map((x) => { + return x + .map((y) => { + return s.sprintf("%14.9f", y).trim(); + }) + .join(" "); + }) + .join("\n"); + } + + static symbolToAtomicSpecie(symbol, pseudo) { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo?.filename || path.basename(pseudo?.path || ""); + return s.sprintf("%s %f %s", symbol, el.atomic_mass, filename) || ""; + } + + static elementAndPseudoToAtomicSpecieWithLabels(symbol, pseudo, label = "") { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo?.filename || path.basename(pseudo?.path || ""); + return s.sprintf("%s%s %f %s", symbol, label, el.atomic_mass, filename) || ""; + } +} + +materialContextMixin(QEPWXContextProvider.prototype); +materialsContextMixin(QEPWXContextProvider.prototype); +methodDataContextMixin(QEPWXContextProvider.prototype); +workflowContextMixin(QEPWXContextProvider.prototype); +jobContextMixin(QEPWXContextProvider.prototype); diff --git a/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js new file mode 100644 index 00000000..6c88f170 --- /dev/null +++ b/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js @@ -0,0 +1,116 @@ +import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; +import { + // type MethodDataContextMixinType, + // type Pseudo, + methodDataContextMixin, +} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; +// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity/in_memory"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +import { Made } from "@mat3ra/made"; +// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; +import lodash from "lodash"; +import _ from "underscore"; +import s from "underscore.string"; + +import { jobContextMixin } from "../../mixins/JobContextMixin"; +// import { type JobContextMixinType, jobContextMixin } from "../../mixins/JobContextMixin"; +import { + // type MaterialContextMixinType, + materialContextMixin, +} from "../../mixins/MaterialContextMixin"; +import { + // type WorkflowContextMixinType, + workflowContextMixin, +} from "../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +// export type Material = MaterialMixin & InMemoryEntity; + +// export type Base = typeof ExecutableContextProvider & +// Constructor & +// Constructor & +// Constructor & +// Constructor; + +// interface NWChemContextConfig extends ContextProviderConfig { +// context?: { +// material?: Material; +// }; +// } + +export default class NWChemTotalEnergyContextProvider extends ExecutableContextProvider { + static Material = Made.Material; + + _material = undefined; + + constructor(config) { + super(config); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + this.initMaterialContextMixin(); + } + + get atomicPositionsWithoutConstraints() { + return this.material.Basis.atomicPositions; + } + + get atomicPositions() { + return this.material.Basis.getAtomicPositionsWithConstraintsAsStrings(); + } + + get atomSymbols() { + return this.material.Basis.uniqueElements; + } + + get cartesianAtomicPositions() { + return this.material.Basis.toCartesian !== undefined; + } + + get ATOMIC_SPECIES() { + return _.map(this.atomSymbols, (symbol) => { + return NWChemTotalEnergyContextProvider.symbolToAtomicSpecies(symbol); + }).join("\n"); + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + /* + TODO: Create ability for user to define CHARGE, MULT, BASIS and FUNCTIONAL parameters. + */ + const CHARGE = 0; + const MULT = 1; + const BASIS = "6-31G"; + const FUNCTIONAL = "B3LYP"; + + return { + CHARGE, + MULT, + BASIS, + NAT: this.atomicPositions.length, + NTYP: this.atomSymbols.length, + ATOMIC_POSITIONS: this.atomicPositions.join("\n"), + ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS: this.atomicPositionsWithoutConstraints.join("\n"), + ATOMIC_SPECIES: this.ATOMIC_SPECIES, + FUNCTIONAL, + CARTESIAN: this.cartesianAtomicPositions, + }; + } + + static symbolToAtomicSpecies(symbol, pseudo) { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo + ? lodash.get(pseudo, "filename", s.strRightBack(pseudo.path || "", "/")) + : ""; + return el ? s.sprintf("%s %f %s", symbol, el.atomic_mass, filename) : undefined; + } +} + +materialContextMixin(NWChemTotalEnergyContextProvider.prototype); +methodDataContextMixin(NWChemTotalEnergyContextProvider.prototype); +workflowContextMixin(NWChemTotalEnergyContextProvider.prototype); +jobContextMixin(NWChemTotalEnergyContextProvider.prototype); diff --git a/src/context/providers/vasp/VASPContextProvider.js b/src/context/providers/vasp/VASPContextProvider.js new file mode 100644 index 00000000..0f3c4129 --- /dev/null +++ b/src/context/providers/vasp/VASPContextProvider.js @@ -0,0 +1,77 @@ +// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; +// import type { WorkflowContextMixinType } from "../../mixins/WorkflowContextMixin"; +// import type { Material } from "../espresso/QENEBContextProvider"; +import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; +import { materialsContextMixin } from "@mat3ra/code/dist/js/context/MaterialsContextMixin"; +// import type { MethodDataContextMixinType } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +import { methodDataContextMixin } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; +import { workflowContextMixin } from "@mat3ra/code/dist/js/context/WorkflowContextMixin"; +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +import { Made } from "@mat3ra/made"; + +// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; +import { + // type MaterialContextMixinType, + materialContextMixin, +} from "../../mixins/MaterialContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +// export type Base = typeof ExecutableContextProvider & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor; + +export default class VASPContextProvider extends ExecutableContextProvider { + static Material = Made.Material; + + _material = undefined; + + _materials = []; + + constructor(config) { + super(config); + this.initJobContextMixin(); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initMaterialContextMixin(); + } + + // eslint-disable-next-line class-methods-use-this + buildVASPContext(material) { + return { + // TODO: figure out whether we need two separate POSCARS, maybe one is enough + POSCAR: material.getAsPOSCAR(true, true), + POSCAR_WITH_CONSTRAINTS: material.getAsPOSCAR(true), + }; + } + + getDataPerMaterial() { + if (!this.materials || this.materials.length <= 1) return {}; + return { perMaterial: this.materials.map((material) => this.buildVASPContext(material)) }; + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + // consider adjusting so that below values are read from PlanewaveDataManager + // ECUTWFC; + // ECUTRHO; + + return { + ...this.buildVASPContext(this.material), + ...this.getDataPerMaterial(), + }; + } +} + +materialContextMixin(VASPContextProvider.prototype); +materialsContextMixin(VASPContextProvider.prototype); +methodDataContextMixin(VASPContextProvider.prototype); +workflowContextMixin(VASPContextProvider.prototype); +jobContextMixin(VASPContextProvider.prototype); diff --git a/src/context/providers/vasp/VASPNEBContextProvider.js b/src/context/providers/vasp/VASPNEBContextProvider.js new file mode 100644 index 00000000..d5d99226 --- /dev/null +++ b/src/context/providers/vasp/VASPNEBContextProvider.js @@ -0,0 +1,72 @@ +import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; +import { materialsContextMixin } from "@mat3ra/code/dist/js/context/MaterialsContextMixin"; +// import type { MethodDataContextMixinType } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +import { methodDataContextMixin } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; +// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; +import { workflowContextMixin } from "@mat3ra/code/dist/js/context/WorkflowContextMixin"; +import { Made } from "@mat3ra/made"; + +// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; +import { + // type MaterialContextMixinType, + materialContextMixin, +} from "../../mixins/MaterialContextMixin"; +// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; +import { + // type MaterialsSetContextMixinType, + materialsSetContextMixin, +} from "../../mixins/MaterialsSetContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; +// import type { WorkflowContextMixinType } from "../../mixins/WorkflowContextMixin"; +// import { ExecutableContextProvider } from "../../providers"; +// import type { Material } from "../espresso/QENEBContextProvider"; +import VASPContextProvider from "./VASPContextProvider"; + +// type Base = typeof ExecutableContextProvider & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor & +// Constructor; + +export default class VASPNEBContextProvider extends ExecutableContextProvider { + _materials = []; + + static Material = Made.Material; + + constructor(config) { + super(config); + this.initMaterialContextMixin(); + this.initMaterialsContextMixin(); + this.initMaterialsSetContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + } + + getData() { + const sortedMaterials = this.sortMaterialsByIndexInSet(this.materials); + const VASPContexts = sortedMaterials.map((material) => { + const context = { ...this.config.context, material }; + const config = { ...this.config, context }; + return new VASPContextProvider(config).getData(); + }); + + return { + FIRST_IMAGE: VASPContexts[0].POSCAR_WITH_CONSTRAINTS, + LAST_IMAGE: VASPContexts[VASPContexts.length - 1].POSCAR_WITH_CONSTRAINTS, + INTERMEDIATE_IMAGES: VASPContexts.slice(1, VASPContexts.length - 1).map( + (data) => data.POSCAR_WITH_CONSTRAINTS, + ), + }; + } +} + +materialContextMixin(VASPNEBContextProvider.prototype); +materialsContextMixin(VASPNEBContextProvider.prototype); +materialsSetContextMixin(VASPNEBContextProvider.prototype); +methodDataContextMixin(VASPNEBContextProvider.prototype); +workflowContextMixin(VASPNEBContextProvider.prototype); +jobContextMixin(VASPNEBContextProvider.prototype); diff --git a/src/context/registry.js b/src/context/registry.js index 1b1d6fdb..ba0ba0c9 100644 --- a/src/context/registry.js +++ b/src/context/registry.js @@ -1,6 +1,5 @@ -import { ContextProviderRegistry as clsInstance } from "@exabyte-io/ade.js"; -import { extendAndPatchRegistry } from "@mat3ra/code/dist/js/context"; +import { createAndPatchRegistry } from "@mat3ra/code/dist/js/context"; import { wodeProviders } from "./providers"; -export const ContextProviderRegistry = extendAndPatchRegistry(clsInstance, wodeProviders); +export const ContextProviderRegistry = createAndPatchRegistry(wodeProviders); diff --git a/src/patch.js b/src/patch.js index 05a4e59b..0fe65fa6 100644 --- a/src/patch.js +++ b/src/patch.js @@ -6,6 +6,6 @@ import { ContextProviderRegistry } from "./context/registry"; // Template has all context providers available // to it when creating workflows. It is then re-exported // from WoDe for use downstream. -Template.providerRegistry = ContextProviderRegistry; +Template.setProviderRegistry(ContextProviderRegistry); export { Template }; diff --git a/tests/context.test.js b/tests/context.test.js new file mode 100644 index 00000000..fc575728 --- /dev/null +++ b/tests/context.test.js @@ -0,0 +1,115 @@ +/* eslint-disable max-classes-per-file */ +import { ContextProvider, createAndPatchRegistry } from "@mat3ra/code/dist/js/context"; +import { expect } from "chai"; + +import { applicationContextMixin } from "../src/context/mixins/ApplicationContextMixin"; +import { materialContextMixin } from "../src/context/mixins/MaterialContextMixin"; + +class MockMaterial { + static createDefault() { + return "defaultMockMaterial"; + } +} + +class SpecificMockMaterial { + static createDefault() { + return "defaultSpecificMockMaterial"; + } +} + +class MockApplication { + static createDefault() { + return "defaultMockApplication"; + } +} + +class SpecificMockApplication { + static createDefault() { + return "defaultSpecificMockApplication"; + } +} + +class ProviderEntity extends ContextProvider { + static Material = MockMaterial; + + static Application = MockApplication; + + static setting = 10; + + constructor(config) { + super(config); + this.initApplicationContextMixin(); + this.initMaterialContextMixin(); + } +} + +applicationContextMixin(ProviderEntity.prototype); +materialContextMixin(ProviderEntity.prototype); + +class DerivedProviderEntity extends ProviderEntity { + static Material = SpecificMockMaterial; + + static Application = SpecificMockApplication; +} + +class ApplicationContextProvider extends ContextProvider { + static Application = SpecificMockApplication; + + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } +} + +applicationContextMixin(ApplicationContextProvider.prototype); + +describe("Material & Application ContextMixin", () => { + const config = { name: "test" }; + + it("uses static entity class", () => { + const provider = new ProviderEntity(config); + expect(provider.material).to.be.equal("defaultMockMaterial"); + expect(provider.application).to.be.equal("defaultMockApplication"); + }); + + it("uses static entity class from derived class", () => { + const provider = new DerivedProviderEntity(config); + expect(provider.material).to.be.equal("defaultSpecificMockMaterial"); + expect(provider.application).to.be.equal("defaultSpecificMockApplication"); + }); +}); + +describe("ContextProviderRegistryContainer", () => { + const classConfigObj = { + DataManager: { + providerCls: ProviderEntity, + config: { name: "example1", domain: "important" }, + }, + ApplicationDataManager: { + providerCls: ApplicationContextProvider, + config: { name: "example2", domain: "important" }, + }, + }; + + const defaultSettings = { + ProviderEntity: { + setting: 100, + }, + }; + + it("can be created and patched", () => { + const registry = createAndPatchRegistry( + classConfigObj, + { Material: SpecificMockMaterial }, + defaultSettings, + ); + + const _dataProvider = registry.findProviderInstanceByName("DataManager"); + const dataProvider = new _dataProvider.constructor(_dataProvider.config); + const _appProvider = registry.findProviderInstanceByName("ApplicationDataManager"); + const appProvider = new _appProvider.constructor(_appProvider.config); + expect(_dataProvider.constructor.setting).to.be.equal(100); + expect(dataProvider.material).to.be.equal("defaultSpecificMockMaterial"); + expect(appProvider.application).to.be.equal("defaultSpecificMockApplication"); + }); +}); diff --git a/tests/espresso.test.js b/tests/espresso.test.js new file mode 100644 index 00000000..0f8e82c4 --- /dev/null +++ b/tests/espresso.test.js @@ -0,0 +1,21 @@ +import { Constraint } from "@mat3ra/made/dist/js/constraints/constraints"; +import { Material } from "@mat3ra/made/dist/js/material"; +import { expect } from "chai"; + +import QEPWXContextProvider from "../src/context/providers/espresso/QEPWXContextProvider"; + +describe("QEPWXContextProvider.atomicPositionsWithConstraints", () => { + const expectedOutput = `Si 0.000000000 0.000000000 0.000000000 1 0 1 +Si 0.250000000 0.250000000 0.250000000 0 0 0`; + + it("returns each atom on its own line when input is array", () => { + const material = Material.createDefault(); + const constraints = [ + new Constraint({ id: 0, value: [true, false, true] }), + new Constraint({ id: 1, value: [false, false, false] }), + ]; + material.setBasisConstraints(constraints); + const result = QEPWXContextProvider.atomicPositionsWithConstraints(material); + expect(result).to.equal(expectedOutput); + }); +}); From 24a61c9afbe1ee2d0062e7f75eb5970c1df1cd0e Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Wed, 18 Jun 2025 18:43:44 +0300 Subject: [PATCH 02/25] fix: tests --- package-lock.json | 15 +++--- package.json | 5 +- src/context/mixins/ApplicationContextMixin.js | 1 - src/context/mixins/JobContextMixin.js | 46 ------------------ src/context/mixins/MaterialContextMixin.js | 30 +----------- src/context/mixins/MaterialsContextMixin.js | 23 ++------- .../mixins/MaterialsSetContextMixin.js | 16 +------ src/context/mixins/MethodDataContextMixin.js | 48 +++++++++++++++++++ src/context/mixins/WorkflowContextMixin.js | 23 +-------- .../espresso/QENEBContextProvider.js | 35 ++------------ .../espresso/QEPWXContextProvider.js | 39 ++------------- .../NWChemTotalEnergyContextProvider.js | 35 ++------------ .../providers/vasp/VASPContextProvider.js | 27 ++--------- .../providers/vasp/VASPNEBContextProvider.js | 34 +++---------- 14 files changed, 89 insertions(+), 288 deletions(-) create mode 100644 src/context/mixins/MethodDataContextMixin.js diff --git a/package-lock.json b/package-lock.json index 9c64c1ca..5f219344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", "@exabyte-io/periodic-table.js": "2022.6.8-0", + "crypto-js": "^4.2.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -26,12 +27,12 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-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#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#18e25cec1cd51bc450505d329bca9c38ec694006", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", @@ -2337,8 +2338,8 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", - "integrity": "sha512-nNglWNXUCbTRL7Cm37TfNdqG7gDFW2PqtvOrP0cHp9hFNxPxUNZzcJd/SlU0jCe+awaUEA6ITA6j5fT4E11IEg==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", + "integrity": "sha512-sk5uOXHM7jL3o35+A62CrfNyu8YUpT6P0Vvw4fhX/hWu7L1Wh94YMzR87VizGRhlefB8C1qcB6L2O2ORervk2A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2759,8 +2760,8 @@ }, "node_modules/@mat3ra/code": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", - "integrity": "sha512-8KhoEH+n+vIPl0n8qP9n/IluiM4huRntgqU3lKnBhwd6D+HvqFkAKdJAOP6E0ecvM1lFg6VPVsyAuG3I2yIhLA==", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#18e25cec1cd51bc450505d329bca9c38ec694006", + "integrity": "sha512-dLgNVJ0PodsfdKY+WMYBw96r2l+PJcuJfRdFixvBXtuDExWij38VB1wGSpmvfb5EKvLAMum56u1PgibsKa57SA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4434,7 +4435,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", - "dev": true + "license": "MIT" }, "node_modules/d": { "version": "1.0.2", diff --git a/package.json b/package.json index 133167d1..bcc69994 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", "@exabyte-io/periodic-table.js": "2022.6.8-0", + "crypto-js": "^4.2.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -47,12 +48,12 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#5f4ccaa2543df19b8b375751c3fce7c74eee4e29", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-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#05924d1e00a9ea88e0bfd70703b4c22b8c8537a1", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#18e25cec1cd51bc450505d329bca9c38ec694006", "@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/context/mixins/ApplicationContextMixin.js b/src/context/mixins/ApplicationContextMixin.js index d0fcf46b..3d4987a7 100644 --- a/src/context/mixins/ApplicationContextMixin.js +++ b/src/context/mixins/ApplicationContextMixin.js @@ -3,7 +3,6 @@ export function applicationContextMixin(item) { _application: undefined, initApplicationContextMixin() { - // @ts-ignore if (!this.constructor.Application) { throw Error("ApplicationContextMixin: Application is undefined"); } diff --git a/src/context/mixins/JobContextMixin.js b/src/context/mixins/JobContextMixin.js index 64d95f08..19213fef 100644 --- a/src/context/mixins/JobContextMixin.js +++ b/src/context/mixins/JobContextMixin.js @@ -1,17 +1,3 @@ -// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; -// import type { JobSchema } from "@mat3ra/esse/dist/js/types"; - -// type Job = JobSchema & { -// parentJob?: Job; -// }; - -// type JobConfig = { -// context?: { -// job?: Job; -// }; -// }; - const defaultJob = { workflow: { subworkflows: [], @@ -29,38 +15,6 @@ const defaultJob = { }, }; -// export type JobContextMixinType = { -// isEdited?: boolean; -// job: Job; -// _job: Job; -// initJobContextMixin: () => void; -// }; - -// export function jobContextMixin(item: ContextProvider) { -// const properties = { -// isEdited: false, - -// _job: defaultJob, - -// get job() { -// return this._job; -// }, - -// initJobContextMixin() { -// const config = this.config as JobConfig; -// this._job = (config.context && config.context.job) || defaultJob; -// this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) -// }, -// } as JobContextMixinType & typeof item; - -// Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); -// } - -// export function JobContextMixin>(superclass: T) { -// jobContextMixin(superclass.prototype); -// return superclass as T & Constructor; -// } - export function jobContextMixin(item) { const properties = { isEdited: false, diff --git a/src/context/mixins/MaterialContextMixin.js b/src/context/mixins/MaterialContextMixin.js index 91f31c54..7a61809b 100644 --- a/src/context/mixins/MaterialContextMixin.js +++ b/src/context/mixins/MaterialContextMixin.js @@ -1,30 +1,4 @@ -// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; -// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; -// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; -// import type { ApplicationMixin } from "src/js/applicationMixin"; - -// import Application from "../../application"; - -// export type MaterialContextMixinType = { -// assertMaterial: () => void; -// isEditedIsSetToFalseOnMaterialUpdate?: boolean; -// updateMaterialHash: () => void; -// isMaterialCreatedDefault: boolean; -// isMaterialUpdated: boolean; -// material: MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet; -// extraData?: { -// materialHash: string; -// }; -// initMaterialContextMixin: () => void; -// _application: ApplicationMixin; -// }; - -export function materialContextMixin( - // item: ContextProvider & { _material?: MaterialMixin & InMemoryEntity }, - item, -) { +export function materialContextMixin(item) { const properties = { _material: undefined, @@ -61,7 +35,7 @@ export function materialContextMixin( } this.updateMaterialHash(); }, - }; // as MaterialContextMixinType & typeof item + }; Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); } diff --git a/src/context/mixins/MaterialsContextMixin.js b/src/context/mixins/MaterialsContextMixin.js index 0aa667eb..b05782cb 100644 --- a/src/context/mixins/MaterialsContextMixin.js +++ b/src/context/mixins/MaterialsContextMixin.js @@ -1,36 +1,19 @@ -// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; -// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; -// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; - -// export type MaterialsContextMixinType = { -// materials: (MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet)[]; -// initMaterialsContextMixin: () => void; -// }; - -export function materialsContextMixin( - // item: ContextProvider & { _materials: (MaterialMixin & InMemoryEntity)[] }, - item, -) { +export function materialsContextMixin(item) { const properties = { get materials() { return this._materials; }, initMaterialsContextMixin() { - // @ts-ignore const materials = this.config.context?.materials; - // @ts-ignore if (!this.constructor.Material) { throw Error("MaterialsContextMixin: Material is undefined"); } this._materials = materials && materials.length ? materials - : // @ts-ignore - [this.constructor.Material.createDefault()]; + : [this.constructor.Material.createDefault()]; }, - }; // as MaterialsContextMixinType & typeof item; + }; Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); } diff --git a/src/context/mixins/MaterialsSetContextMixin.js b/src/context/mixins/MaterialsSetContextMixin.js index 81c669fc..35bef4fc 100644 --- a/src/context/mixins/MaterialsSetContextMixin.js +++ b/src/context/mixins/MaterialsSetContextMixin.js @@ -1,16 +1,4 @@ -// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; -// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; import { compareEntitiesInOrderedSetForSorting } from "@mat3ra/code/dist/js/entity/set/ordered/utils"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; - -// export type MaterialsSetContextMixinType = { -// materialsSet: any; -// _materialsSet: any; -// sortMaterialsByIndexInSet: ( -// materials?: OrderedInMemoryEntityInSet[], -// ) => OrderedInMemoryEntityInSet[]; -// initMaterialsSetContextMixin: () => void; -// }; export function materialsSetContextMixin(item) { const properties = { @@ -21,18 +9,16 @@ export function materialsSetContextMixin(item) { }, initMaterialsSetContextMixin() { - // @ts-ignore this._materialsSet = this.config.context?.materialsSet; }, - // materials: OrderedInMemoryEntityInSet[] = [] sortMaterialsByIndexInSet(materials = []) { // DO NOT SORT IN PLACE AS IT CHANGES THE ORDER IN `this.materials` AND HAS SIDE EFFECTS (MaterialViewer). return materials.concat().sort((a, b) => { return compareEntitiesInOrderedSetForSorting(a, b, this.materialsSet._id, false); }); }, - }; // as MaterialsSetContextMixinType & typeof item; + }; Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); } diff --git a/src/context/mixins/MethodDataContextMixin.js b/src/context/mixins/MethodDataContextMixin.js new file mode 100644 index 00000000..4443de20 --- /dev/null +++ b/src/context/mixins/MethodDataContextMixin.js @@ -0,0 +1,48 @@ +import CryptoJS from "crypto-js"; + +export function methodDataContextMixin(item) { + const properties = { + _methodData: undefined, + + isEdited: false, + + methodDataHash: undefined, + + extraData: undefined, + + initMethodDataContextMixin() { + this._methodData = (this.config.context && this.config.context.methodData) || {}; + this.isEdited = Boolean(this.config.isEdited); + }, + + /* @summary Replace the logic in constructor with this in order to enable passing `methodDataHash` between + * subsequent initializations of the derived class. Not used at present and kept for the record. + */ + _initMethodDataHash() { + this.methodDataHash = CryptoJS.MD5(JSON.stringify(this.methodData)).toString(); + this.extraData = { methodDataHash: this.methodDataHash }; + if (!this._methodData) { + this._methodData = {}; + this.isEdited = false; + // Commented out to reduce effect on performance. Uncomment for debugging purposes. + // TODO: remove on next refactoring or convert to log + // console.warn("MethodDataContextMixin: methodData is undefined or null"); + } else if (this.isMethodDataUpdated) { + this.isEdited = false; + } else { + // eslint-disable-next-line no-undef + this.isEdited = config.isEdited; + } + }, + + get methodData() { + return this._methodData; + }, + + get isMethodDataUpdated() { + return Boolean(this.extraData && this.extraData.methodDataHash !== this.methodDataHash); + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/WorkflowContextMixin.js b/src/context/mixins/WorkflowContextMixin.js index 12a259b5..c66c290c 100644 --- a/src/context/mixins/WorkflowContextMixin.js +++ b/src/context/mixins/WorkflowContextMixin.js @@ -1,30 +1,9 @@ -// import type { ContextProvider } from "@mat3ra/code/dist/js/context"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; -// import type { WorkflowSchema } from "@mat3ra/esse/dist/js/types"; - -// type Workflow = WorkflowSchema & { -// hasRelaxation: boolean; -// }; - -// type WorkflowConfig = { -// context?: { -// workflow?: Workflow; -// }; -// }; - const defaultWorkflow = { subworkflows: [], units: [], hasRelaxation: false, }; -// export type WorkflowContextMixinType = { -// isEdited?: boolean; -// workflow: Workflow; -// _workflow: Workflow; -// initWorkflowContextMixin: () => void; -// }; - export function workflowContextMixin(item) { const properties = { isEdited: false, @@ -40,7 +19,7 @@ export function workflowContextMixin(item) { this._workflow = (config.context && config.context.workflow) || defaultWorkflow; this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) }, - }; // as WorkflowContextMixinType & typeof item; + }; Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); } diff --git a/src/context/providers/espresso/QENEBContextProvider.js b/src/context/providers/espresso/QENEBContextProvider.js index 9ed36a63..7a1ce49b 100644 --- a/src/context/providers/espresso/QENEBContextProvider.js +++ b/src/context/providers/espresso/QENEBContextProvider.js @@ -1,42 +1,15 @@ -import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; -import { - // type MethodDataContextMixinType, - methodDataContextMixin, -} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; -// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity"; -// import type { OrderedInMemoryEntityInSet } from "@mat3ra/code/dist/js/entity/set/ordered/OrderedInMemoryEntityInSetMixin"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; import { Made } from "@mat3ra/made"; -// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; import lodash from "lodash"; -// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; -// import type { MaterialContextMixinType } from "../../mixins/MaterialContextMixin"; +import { jobContextMixin } from "../../mixins/JobContextMixin"; import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; -import { - // type MaterialsSetContextMixinType, - materialsSetContextMixin, -} from "../../mixins/MaterialsSetContextMixin"; -import { - // type WorkflowContextMixinType, - workflowContextMixin, -} from "../../mixins/WorkflowContextMixin"; +import { materialsSetContextMixin } from "../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; import QEPWXContextProvider from "./QEPWXContextProvider"; -// export type Base = typeof ExecutableContextProvider & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor; - -// export type Material = MaterialMixin & InMemoryEntity & OrderedInMemoryEntityInSet; - export default class QENEBContextProvider extends ExecutableContextProvider { static Material = Made.Material; diff --git a/src/context/providers/espresso/QEPWXContextProvider.js b/src/context/providers/espresso/QEPWXContextProvider.js index 8e154a4c..9fdecc22 100644 --- a/src/context/providers/espresso/QEPWXContextProvider.js +++ b/src/context/providers/espresso/QEPWXContextProvider.js @@ -1,44 +1,15 @@ import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; -import { - // type MethodDataContextMixinType, - // type Pseudo, - methodDataContextMixin, -} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; -// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity/in_memory"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; import { Made } from "@mat3ra/made"; -// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; import path from "path"; import s from "underscore.string"; -import { - // type JobContextMixinType, - jobContextMixin, -} from "../../mixins/JobContextMixin"; -import { - // type MaterialContextMixinType, - materialContextMixin, -} from "../../mixins/MaterialContextMixin"; -import { - // type MaterialsContextMixinType, - materialsContextMixin, -} from "../../mixins/MaterialsContextMixin"; -import { - // type WorkflowContextMixinType, - workflowContextMixin, -} from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; -// export type Material = MaterialMixin & InMemoryEntity; - -// export type Base = typeof ExecutableContextProvider & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor; - export default class QEPWXContextProvider extends ExecutableContextProvider { static Material = Made.Material; diff --git a/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js index 6c88f170..67eab14c 100644 --- a/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js @@ -1,44 +1,15 @@ import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; -import { - // type MethodDataContextMixinType, - // type Pseudo, - methodDataContextMixin, -} from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; -// import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity/in_memory"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; import { Made } from "@mat3ra/made"; -// import type { MaterialMixin } from "@mat3ra/made/dist/js/materialMixin"; import lodash from "lodash"; import _ from "underscore"; import s from "underscore.string"; import { jobContextMixin } from "../../mixins/JobContextMixin"; -// import { type JobContextMixinType, jobContextMixin } from "../../mixins/JobContextMixin"; -import { - // type MaterialContextMixinType, - materialContextMixin, -} from "../../mixins/MaterialContextMixin"; -import { - // type WorkflowContextMixinType, - workflowContextMixin, -} from "../../mixins/WorkflowContextMixin"; +import { materialContextMixin } from "../../mixins/MaterialContextMixin"; +import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; -// export type Material = MaterialMixin & InMemoryEntity; - -// export type Base = typeof ExecutableContextProvider & -// Constructor & -// Constructor & -// Constructor & -// Constructor; - -// interface NWChemContextConfig extends ContextProviderConfig { -// context?: { -// material?: Material; -// }; -// } - export default class NWChemTotalEnergyContextProvider extends ExecutableContextProvider { static Material = Made.Material; diff --git a/src/context/providers/vasp/VASPContextProvider.js b/src/context/providers/vasp/VASPContextProvider.js index 0f3c4129..607783a8 100644 --- a/src/context/providers/vasp/VASPContextProvider.js +++ b/src/context/providers/vasp/VASPContextProvider.js @@ -1,29 +1,12 @@ -// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; -// import type { WorkflowContextMixinType } from "../../mixins/WorkflowContextMixin"; -// import type { Material } from "../espresso/QENEBContextProvider"; -import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; -import { materialsContextMixin } from "@mat3ra/code/dist/js/context/MaterialsContextMixin"; -// import type { MethodDataContextMixinType } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -import { methodDataContextMixin } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; -import { workflowContextMixin } from "@mat3ra/code/dist/js/context/WorkflowContextMixin"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; import { Made } from "@mat3ra/made"; -// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; -import { - // type MaterialContextMixinType, - materialContextMixin, -} from "../../mixins/MaterialContextMixin"; +import { jobContextMixin } from "../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; -// export type Base = typeof ExecutableContextProvider & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor; - export default class VASPContextProvider extends ExecutableContextProvider { static Material = Made.Material; diff --git a/src/context/providers/vasp/VASPNEBContextProvider.js b/src/context/providers/vasp/VASPNEBContextProvider.js index d5d99226..e8a9d0d3 100644 --- a/src/context/providers/vasp/VASPNEBContextProvider.js +++ b/src/context/providers/vasp/VASPNEBContextProvider.js @@ -1,36 +1,14 @@ -import { jobContextMixin } from "@mat3ra/code/dist/js/context/JobContextMixin"; -import { materialsContextMixin } from "@mat3ra/code/dist/js/context/MaterialsContextMixin"; -// import type { MethodDataContextMixinType } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -import { methodDataContextMixin } from "@mat3ra/code/dist/js/context/MethodDataContextMixin"; -// import type { ContextProviderConfig } from "@mat3ra/code/dist/js/context/provider"; -import { workflowContextMixin } from "@mat3ra/code/dist/js/context/WorkflowContextMixin"; import { Made } from "@mat3ra/made"; -// import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; -// import type { JobContextMixinType } from "../../mixins/JobContextMixin"; -import { - // type MaterialContextMixinType, - materialContextMixin, -} from "../../mixins/MaterialContextMixin"; -// import type { MaterialsContextMixinType } from "../../mixins/MaterialsContextMixin"; -import { - // type MaterialsSetContextMixinType, - materialsSetContextMixin, -} from "../../mixins/MaterialsSetContextMixin"; +import { jobContextMixin } from "../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; +import { materialsSetContextMixin } from "../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; -// import type { WorkflowContextMixinType } from "../../mixins/WorkflowContextMixin"; -// import { ExecutableContextProvider } from "../../providers"; -// import type { Material } from "../espresso/QENEBContextProvider"; import VASPContextProvider from "./VASPContextProvider"; -// type Base = typeof ExecutableContextProvider & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor & -// Constructor; - export default class VASPNEBContextProvider extends ExecutableContextProvider { _materials = []; From 8ddcb6d124abe37d75f189863a527abc1fdc1e8a Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 19 Jun 2025 17:57:37 +0300 Subject: [PATCH 03/25] chore: cleanup --- package-lock.json | 45 +++++++++--- package.json | 4 +- src/context/context.js | 10 +++ src/context/providers.js | 10 +-- .../BoundaryConditionsFormDataProvider.js | 2 +- .../CollinearMagnetizationContextProvider.js | 2 +- .../providers/HubbardUContextProvider.js | 2 +- .../providers/IonDynamicsContextProvider.js | 2 +- .../providers/MLSettingsContextProvider.js | 2 +- .../MLTrainTestSplitContextProvider.js | 2 +- src/context/providers/NEBFormDataProvider.js | 2 +- ...onCollinearMagnetizationContextProvider.js | 2 +- .../PlanewaveCutoffsContextProvider.js | 2 +- .../providers/PointsGridFormDataProvider.js | 2 +- .../providers/PointsPathFormDataProvider.js | 2 +- .../ExecutableContextProvider.js | 2 +- .../espresso/QENEBContextProvider.js | 12 ++-- .../espresso/QEPWXContextProvider.js | 10 +-- .../NWChemTotalEnergyContextProvider.js | 8 +-- .../vasp/VASPContextProvider.js | 10 +-- .../vasp/VASPNEBContextProvider.js | 12 ++-- src/context/registry.js | 5 -- src/index.js | 2 - src/patch.js | 5 +- tests/context.test.js | 70 +++++++++---------- tests/espresso.test.js | 2 +- 26 files changed, 130 insertions(+), 99 deletions(-) rename src/context/providers/{ => by_application}/ExecutableContextProvider.js (70%) rename src/context/providers/{ => by_application}/espresso/QENEBContextProvider.js (79%) rename src/context/providers/{ => by_application}/espresso/QEPWXContextProvider.js (93%) rename src/context/providers/{ => by_application}/nwchem/NWChemTotalEnergyContextProvider.js (90%) rename src/context/providers/{ => by_application}/vasp/VASPContextProvider.js (82%) rename src/context/providers/{ => by_application}/vasp/VASPNEBContextProvider.js (77%) delete mode 100644 src/context/registry.js diff --git a/package-lock.json b/package-lock.json index 5f219344..f3a9ec45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,12 +27,12 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-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#18e25cec1cd51bc450505d329bca9c38ec694006", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", "@mat3ra/esse": "2025.4.26-0", "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", @@ -2338,15 +2338,15 @@ }, "node_modules/@exabyte-io/ade.js": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", - "integrity": "sha512-sk5uOXHM7jL3o35+A62CrfNyu8YUpT6P0Vvw4fhX/hWu7L1Wh94YMzR87VizGRhlefB8C1qcB6L2O2ORervk2A==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "integrity": "sha512-uhFBtkZN1rXnUwbhD7ntzDxsnuYQdacmXbZxyy6cjV4vctRmwkDUIrZ3hn7FapNaBxLi8xHz0xMYycBxTpYF8g==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@types/react-jsonschema-form": "^1.7.13", "lodash": "^4.17.21", "nunjucks": "^3.2.4", - "underscore": "^1.13.3", - "underscore.string": "^3.3.4" + "react-jsonschema-form": "^1.8.1" }, "engines": { "node": ">=12.0.0" @@ -2760,8 +2760,8 @@ }, "node_modules/@mat3ra/code": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#18e25cec1cd51bc450505d329bca9c38ec694006", - "integrity": "sha512-dLgNVJ0PodsfdKY+WMYBw96r2l+PJcuJfRdFixvBXtuDExWij38VB1wGSpmvfb5EKvLAMum56u1PgibsKa57SA==", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", + "integrity": "sha512-w/v9+NRIZkRt6Ov5jBVowGmxnuAv1JrXMOderAZd9kVqTEvDMcPpImd1NV1VQTHG8xy7Uq2piRS0a15SyyVh6Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2773,7 +2773,6 @@ "mathjs": "^5.10.3", "mixwith": "^0.1.1", "nunjucks": "^3.2.4", - "react-jsonschema-form": "^1.8.1", "semver": "^7.6.3", "underscore": "^1.13.7", "underscore.string": "^3.3.6", @@ -3431,6 +3430,27 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", "dev": true }, + "node_modules/@types/react": { + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-jsonschema-form": { + "version": "1.7.13", + "resolved": "https://registry.npmjs.org/@types/react-jsonschema-form/-/react-jsonschema-form-1.7.13.tgz", + "integrity": "sha512-C2jgO7/ow76oCSfUK++jKKox17R0A7ryMYNE5hJ2dR1Ske9jhuvjIlurvzMePh+Xjk8wey0nzB2C7HFKe2pRdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "*", + "@types/react": "*" + } + }, "node_modules/@types/underscore": { "version": "1.11.15", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.15.tgz", @@ -4437,6 +4457,13 @@ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", "license": "MIT" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, "node_modules/d": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", diff --git a/package.json b/package.json index bcc69994..7f31d942 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,12 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#9e9a7ca709d8a4b0f12ddbb82834695298979738", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", "@exabyte-io/eslint-config": "^2022.11.17-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#18e25cec1cd51bc450505d329bca9c38ec694006", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", "@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/context/context.js b/src/context/context.js index 082bc1e9..86a6eb0c 100644 --- a/src/context/context.js +++ b/src/context/context.js @@ -1,4 +1,9 @@ import { BoundaryConditionsFormDataProvider } from "./providers/BoundaryConditionsFormDataProvider"; +import QENEBContextProvider from "./providers/by_application/espresso/QENEBContextProvider"; +import QEPWXContextProvider from "./providers/by_application/espresso/QEPWXContextProvider"; +import NWChemTotalEnergyContextProvider from "./providers/by_application/nwchem/NWChemTotalEnergyContextProvider"; +import VASPContextProvider from "./providers/by_application/vasp/VASPContextProvider"; +import VASPNEBContextProvider from "./providers/by_application/vasp/VASPNEBContextProvider"; import { CollinearMagnetizationContextProvider } from "./providers/CollinearMagnetizationContextProvider"; import { HubbardContextProviderLegacy } from "./providers/HubbardContextProviderLegacy"; import { HubbardJContextProvider } from "./providers/HubbardJContextProvider"; @@ -34,4 +39,9 @@ export default { IonDynamicsContextProvider, CollinearMagnetizationContextProvider, NonCollinearMagnetizationContextProvider, + VASPContextProvider, + VASPNEBContextProvider, + QEPWXContextProvider, + QENEBContextProvider, + NWChemTotalEnergyContextProvider, }; diff --git a/src/context/providers.js b/src/context/providers.js index c84447ab..34157b35 100644 --- a/src/context/providers.js +++ b/src/context/providers.js @@ -1,9 +1,4 @@ import context from "./context"; -import QENEBContextProvider from "./providers/espresso/QENEBContextProvider"; -import QEPWXContextProvider from "./providers/espresso/QEPWXContextProvider"; -import NWChemTotalEnergyContextProvider from "./providers/nwchem/NWChemTotalEnergyContextProvider"; -import VASPContextProvider from "./providers/vasp/VASPContextProvider"; -import VASPNEBContextProvider from "./providers/vasp/VASPNEBContextProvider"; const { BoundaryConditionsFormDataProvider, @@ -22,6 +17,11 @@ const { IonDynamicsContextProvider, CollinearMagnetizationContextProvider, NonCollinearMagnetizationContextProvider, + VASPContextProvider, + VASPNEBContextProvider, + QEPWXContextProvider, + QENEBContextProvider, + NWChemTotalEnergyContextProvider, } = context; const CONTEXT_DOMAINS = { diff --git a/src/context/providers/BoundaryConditionsFormDataProvider.js b/src/context/providers/BoundaryConditionsFormDataProvider.js index c6b7a253..8e5b8a81 100644 --- a/src/context/providers/BoundaryConditionsFormDataProvider.js +++ b/src/context/providers/BoundaryConditionsFormDataProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { deepClone } from "@mat3ra/code/dist/js/utils"; import { Made } from "@mat3ra/made"; diff --git a/src/context/providers/CollinearMagnetizationContextProvider.js b/src/context/providers/CollinearMagnetizationContextProvider.js index 8cfa6e2c..562b6ff5 100644 --- a/src/context/providers/CollinearMagnetizationContextProvider.js +++ b/src/context/providers/CollinearMagnetizationContextProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; diff --git a/src/context/providers/HubbardUContextProvider.js b/src/context/providers/HubbardUContextProvider.js index 8870f82d..2faca898 100644 --- a/src/context/providers/HubbardUContextProvider.js +++ b/src/context/providers/HubbardUContextProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { Made } from "@mat3ra/made"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; diff --git a/src/context/providers/IonDynamicsContextProvider.js b/src/context/providers/IonDynamicsContextProvider.js index 097d5fe2..cc825025 100644 --- a/src/context/providers/IonDynamicsContextProvider.js +++ b/src/context/providers/IonDynamicsContextProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; const defaultMDConfig = { numberOfSteps: 100, diff --git a/src/context/providers/MLSettingsContextProvider.js b/src/context/providers/MLSettingsContextProvider.js index 79b402e6..d82003af 100644 --- a/src/context/providers/MLSettingsContextProvider.js +++ b/src/context/providers/MLSettingsContextProvider.js @@ -1,5 +1,5 @@ import { Application } from "@exabyte-io/ade.js"; -import { ContextProvider } from "@mat3ra/code/dist/js/context"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; diff --git a/src/context/providers/MLTrainTestSplitContextProvider.js b/src/context/providers/MLTrainTestSplitContextProvider.js index 8da32e5f..dbfa76ea 100644 --- a/src/context/providers/MLTrainTestSplitContextProvider.js +++ b/src/context/providers/MLTrainTestSplitContextProvider.js @@ -1,5 +1,5 @@ import { Application } from "@exabyte-io/ade.js"; -import { ContextProvider } from "@mat3ra/code/dist/js/context"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; diff --git a/src/context/providers/NEBFormDataProvider.js b/src/context/providers/NEBFormDataProvider.js index e13a4eff..c89c86f6 100644 --- a/src/context/providers/NEBFormDataProvider.js +++ b/src/context/providers/NEBFormDataProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; export class NEBFormDataProvider extends JSONSchemaFormDataProvider { // eslint-disable-next-line class-methods-use-this diff --git a/src/context/providers/NonCollinearMagnetizationContextProvider.js b/src/context/providers/NonCollinearMagnetizationContextProvider.js index 0c834dd9..8bbdfdc0 100644 --- a/src/context/providers/NonCollinearMagnetizationContextProvider.js +++ b/src/context/providers/NonCollinearMagnetizationContextProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; diff --git a/src/context/providers/PlanewaveCutoffsContextProvider.js b/src/context/providers/PlanewaveCutoffsContextProvider.js index bbcc25bf..80b0d7bd 100644 --- a/src/context/providers/PlanewaveCutoffsContextProvider.js +++ b/src/context/providers/PlanewaveCutoffsContextProvider.js @@ -1,5 +1,5 @@ import { Application } from "@exabyte-io/ade.js"; -import { ContextProvider } from "@mat3ra/code/dist/js/context"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; diff --git a/src/context/providers/PointsGridFormDataProvider.js b/src/context/providers/PointsGridFormDataProvider.js index 65cb499e..9ed1982f 100644 --- a/src/context/providers/PointsGridFormDataProvider.js +++ b/src/context/providers/PointsGridFormDataProvider.js @@ -1,5 +1,5 @@ +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { units as UNITS } from "@mat3ra/code/dist/js/constants"; -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; diff --git a/src/context/providers/PointsPathFormDataProvider.js b/src/context/providers/PointsPathFormDataProvider.js index 28857769..19e3655f 100644 --- a/src/context/providers/PointsPathFormDataProvider.js +++ b/src/context/providers/PointsPathFormDataProvider.js @@ -1,7 +1,7 @@ /* eslint-disable max-classes-per-file */ /* eslint react/prop-types: 0 */ import { Application } from "@exabyte-io/ade.js"; -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; import s from "underscore.string"; diff --git a/src/context/providers/ExecutableContextProvider.js b/src/context/providers/by_application/ExecutableContextProvider.js similarity index 70% rename from src/context/providers/ExecutableContextProvider.js rename to src/context/providers/by_application/ExecutableContextProvider.js index 7787682a..46d94ea4 100644 --- a/src/context/providers/ExecutableContextProvider.js +++ b/src/context/providers/by_application/ExecutableContextProvider.js @@ -1,4 +1,4 @@ -import { ContextProvider } from "@mat3ra/code/dist/js/context"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; export default class ExecutableContextProvider extends ContextProvider { constructor(config) { diff --git a/src/context/providers/espresso/QENEBContextProvider.js b/src/context/providers/by_application/espresso/QENEBContextProvider.js similarity index 79% rename from src/context/providers/espresso/QENEBContextProvider.js rename to src/context/providers/by_application/espresso/QENEBContextProvider.js index 7a1ce49b..57bddfe5 100644 --- a/src/context/providers/espresso/QENEBContextProvider.js +++ b/src/context/providers/by_application/espresso/QENEBContextProvider.js @@ -1,12 +1,12 @@ import { Made } from "@mat3ra/made"; import lodash from "lodash"; -import { jobContextMixin } from "../../mixins/JobContextMixin"; -import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; -import { materialsSetContextMixin } from "../../mixins/MaterialsSetContextMixin"; -import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; -import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { materialsSetContextMixin } from "../../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; import QEPWXContextProvider from "./QEPWXContextProvider"; diff --git a/src/context/providers/espresso/QEPWXContextProvider.js b/src/context/providers/by_application/espresso/QEPWXContextProvider.js similarity index 93% rename from src/context/providers/espresso/QEPWXContextProvider.js rename to src/context/providers/by_application/espresso/QEPWXContextProvider.js index 9fdecc22..36800f5f 100644 --- a/src/context/providers/espresso/QEPWXContextProvider.js +++ b/src/context/providers/by_application/espresso/QEPWXContextProvider.js @@ -3,11 +3,11 @@ import { Made } from "@mat3ra/made"; import path from "path"; import s from "underscore.string"; -import { jobContextMixin } from "../../mixins/JobContextMixin"; -import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; -import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; -import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class QEPWXContextProvider extends ExecutableContextProvider { diff --git a/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js similarity index 90% rename from src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js rename to src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js index 67eab14c..7eb0f874 100644 --- a/src/context/providers/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -4,10 +4,10 @@ import lodash from "lodash"; import _ from "underscore"; import s from "underscore.string"; -import { jobContextMixin } from "../../mixins/JobContextMixin"; -import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; -import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class NWChemTotalEnergyContextProvider extends ExecutableContextProvider { diff --git a/src/context/providers/vasp/VASPContextProvider.js b/src/context/providers/by_application/vasp/VASPContextProvider.js similarity index 82% rename from src/context/providers/vasp/VASPContextProvider.js rename to src/context/providers/by_application/vasp/VASPContextProvider.js index 607783a8..c2850a31 100644 --- a/src/context/providers/vasp/VASPContextProvider.js +++ b/src/context/providers/by_application/vasp/VASPContextProvider.js @@ -1,10 +1,10 @@ import { Made } from "@mat3ra/made"; -import { jobContextMixin } from "../../mixins/JobContextMixin"; -import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; -import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; -import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class VASPContextProvider extends ExecutableContextProvider { diff --git a/src/context/providers/vasp/VASPNEBContextProvider.js b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js similarity index 77% rename from src/context/providers/vasp/VASPNEBContextProvider.js rename to src/context/providers/by_application/vasp/VASPNEBContextProvider.js index e8a9d0d3..b6a2b5c5 100644 --- a/src/context/providers/vasp/VASPNEBContextProvider.js +++ b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js @@ -1,11 +1,11 @@ import { Made } from "@mat3ra/made"; -import { jobContextMixin } from "../../mixins/JobContextMixin"; -import { materialContextMixin } from "../../mixins/MaterialContextMixin"; -import { materialsContextMixin } from "../../mixins/MaterialsContextMixin"; -import { materialsSetContextMixin } from "../../mixins/MaterialsSetContextMixin"; -import { methodDataContextMixin } from "../../mixins/MethodDataContextMixin"; -import { workflowContextMixin } from "../../mixins/WorkflowContextMixin"; +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { materialsSetContextMixin } from "../../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; import VASPContextProvider from "./VASPContextProvider"; diff --git a/src/context/registry.js b/src/context/registry.js deleted file mode 100644 index ba0ba0c9..00000000 --- a/src/context/registry.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createAndPatchRegistry } from "@mat3ra/code/dist/js/context"; - -import { wodeProviders } from "./providers"; - -export const ContextProviderRegistry = createAndPatchRegistry(wodeProviders); diff --git a/src/index.js b/src/index.js index e915a80f..479cd548 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,3 @@ -import { ContextProviderRegistry } from "./context/registry"; import { UNIT_STATUSES, UNIT_TYPES } from "./enums"; import { createSubworkflowByName, Subworkflow } from "./subworkflows"; import { builders } from "./units/builders"; @@ -12,7 +11,6 @@ export { createSubworkflowByName, UnitFactory, builders, - ContextProviderRegistry, UNIT_TYPES, UNIT_STATUSES, }; diff --git a/src/patch.js b/src/patch.js index 0fe65fa6..1ce96308 100644 --- a/src/patch.js +++ b/src/patch.js @@ -1,11 +1,12 @@ import { Template } from "@exabyte-io/ade.js"; -import { ContextProviderRegistry } from "./context/registry"; +import { wodeProviders } from "./context/providers"; // We patch the static providerRegistry here so that // Template has all context providers available // to it when creating workflows. It is then re-exported // from WoDe for use downstream. -Template.setProviderRegistry(ContextProviderRegistry); + +Template.setContextProvidersConfig(wodeProviders); export { Template }; diff --git a/tests/context.test.js b/tests/context.test.js index fc575728..35779824 100644 --- a/tests/context.test.js +++ b/tests/context.test.js @@ -1,5 +1,5 @@ /* eslint-disable max-classes-per-file */ -import { ContextProvider, createAndPatchRegistry } from "@mat3ra/code/dist/js/context"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { expect } from "chai"; import { applicationContextMixin } from "../src/context/mixins/ApplicationContextMixin"; @@ -79,37 +79,37 @@ describe("Material & Application ContextMixin", () => { }); }); -describe("ContextProviderRegistryContainer", () => { - const classConfigObj = { - DataManager: { - providerCls: ProviderEntity, - config: { name: "example1", domain: "important" }, - }, - ApplicationDataManager: { - providerCls: ApplicationContextProvider, - config: { name: "example2", domain: "important" }, - }, - }; - - const defaultSettings = { - ProviderEntity: { - setting: 100, - }, - }; - - it("can be created and patched", () => { - const registry = createAndPatchRegistry( - classConfigObj, - { Material: SpecificMockMaterial }, - defaultSettings, - ); - - const _dataProvider = registry.findProviderInstanceByName("DataManager"); - const dataProvider = new _dataProvider.constructor(_dataProvider.config); - const _appProvider = registry.findProviderInstanceByName("ApplicationDataManager"); - const appProvider = new _appProvider.constructor(_appProvider.config); - expect(_dataProvider.constructor.setting).to.be.equal(100); - expect(dataProvider.material).to.be.equal("defaultSpecificMockMaterial"); - expect(appProvider.application).to.be.equal("defaultSpecificMockApplication"); - }); -}); +// describe("ContextProviderRegistryContainer", () => { +// const classConfigObj = { +// DataManager: { +// providerCls: ProviderEntity, +// config: { name: "example1", domain: "important" }, +// }, +// ApplicationDataManager: { +// providerCls: ApplicationContextProvider, +// config: { name: "example2", domain: "important" }, +// }, +// }; + +// const defaultSettings = { +// ProviderEntity: { +// setting: 100, +// }, +// }; + +// it("can be created and patched", () => { +// const registry = createAndPatchRegistry( +// classConfigObj, +// { Material: SpecificMockMaterial }, +// defaultSettings, +// ); + +// const _dataProvider = registry.findProviderInstanceByName("DataManager"); +// const dataProvider = new _dataProvider.constructor(_dataProvider.config); +// const _appProvider = registry.findProviderInstanceByName("ApplicationDataManager"); +// const appProvider = new _appProvider.constructor(_appProvider.config); +// expect(_dataProvider.constructor.setting).to.be.equal(100); +// expect(dataProvider.material).to.be.equal("defaultSpecificMockMaterial"); +// expect(appProvider.application).to.be.equal("defaultSpecificMockApplication"); +// }); +// }); diff --git a/tests/espresso.test.js b/tests/espresso.test.js index 0f8e82c4..4e33a802 100644 --- a/tests/espresso.test.js +++ b/tests/espresso.test.js @@ -2,7 +2,7 @@ import { Constraint } from "@mat3ra/made/dist/js/constraints/constraints"; import { Material } from "@mat3ra/made/dist/js/material"; import { expect } from "chai"; -import QEPWXContextProvider from "../src/context/providers/espresso/QEPWXContextProvider"; +import QEPWXContextProvider from "../src/context/providers/by_application/espresso/QEPWXContextProvider"; describe("QEPWXContextProvider.atomicPositionsWithConstraints", () => { const expectedOutput = `Si 0.000000000 0.000000000 0.000000000 1 0 1 From 69608798b57358bb1354c3662d4cf0e76efae711 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 19 Jun 2025 18:39:13 +0300 Subject: [PATCH 04/25] chore: introduce context providers settings --- src/context/mixins/ApplicationContextMixin.js | 7 +- src/context/mixins/MaterialContextMixin.js | 10 +-- src/context/mixins/MaterialsContextMixin.js | 7 +- .../BoundaryConditionsFormDataProvider.js | 2 - .../CollinearMagnetizationContextProvider.js | 3 - .../providers/HubbardUContextProvider.js | 3 - .../providers/MLSettingsContextProvider.js | 3 - .../MLTrainTestSplitContextProvider.js | 3 - ...onCollinearMagnetizationContextProvider.js | 3 - .../PlanewaveCutoffsContextProvider.js | 3 - .../providers/PointsGridFormDataProvider.js | 9 +-- .../providers/PointsPathFormDataProvider.js | 5 -- .../espresso/QENEBContextProvider.js | 3 - .../espresso/QEPWXContextProvider.js | 3 - .../NWChemTotalEnergyContextProvider.js | 3 - .../vasp/VASPContextProvider.js | 4 -- .../vasp/VASPNEBContextProvider.js | 4 -- src/context/providers/settings.js | 38 +++++++++++ tests/context.test.js | 68 +++---------------- 19 files changed, 62 insertions(+), 119 deletions(-) create mode 100644 src/context/providers/settings.js diff --git a/src/context/mixins/ApplicationContextMixin.js b/src/context/mixins/ApplicationContextMixin.js index 3d4987a7..942a375b 100644 --- a/src/context/mixins/ApplicationContextMixin.js +++ b/src/context/mixins/ApplicationContextMixin.js @@ -1,14 +1,13 @@ +import { contextProvidersGlobalSettings } from "../providers/settings"; + export function applicationContextMixin(item) { const properties = { _application: undefined, initApplicationContextMixin() { - if (!this.constructor.Application) { - throw Error("ApplicationContextMixin: Application is undefined"); - } this._application = (this.config.context && this.config.context.application) || - this.constructor.Application.createDefault(); + contextProvidersGlobalSettings.Application.createDefault(); }, get application() { diff --git a/src/context/mixins/MaterialContextMixin.js b/src/context/mixins/MaterialContextMixin.js index 7a61809b..fbbd6306 100644 --- a/src/context/mixins/MaterialContextMixin.js +++ b/src/context/mixins/MaterialContextMixin.js @@ -1,3 +1,5 @@ +import { contextProvidersGlobalSettings } from "../providers/settings"; + export function materialContextMixin(item) { const properties = { _material: undefined, @@ -25,14 +27,12 @@ export function materialContextMixin(item) { }, initMaterialContextMixin() { - // @ts-ignore - if (!this.constructor.Material) { - throw Error("MaterialContextMixin: Material is undefined"); - } this._material = this.config.context && this.config.context.material; + if (!this._material) { - this._material = this.constructor.Material.createDefault(); + this._material = contextProvidersGlobalSettings.Material.createDefault(); } + this.updateMaterialHash(); }, }; diff --git a/src/context/mixins/MaterialsContextMixin.js b/src/context/mixins/MaterialsContextMixin.js index b05782cb..348f214e 100644 --- a/src/context/mixins/MaterialsContextMixin.js +++ b/src/context/mixins/MaterialsContextMixin.js @@ -1,3 +1,5 @@ +import { contextProvidersGlobalSettings } from "../providers/settings"; + export function materialsContextMixin(item) { const properties = { get materials() { @@ -5,13 +7,10 @@ export function materialsContextMixin(item) { }, initMaterialsContextMixin() { const materials = this.config.context?.materials; - if (!this.constructor.Material) { - throw Error("MaterialsContextMixin: Material is undefined"); - } this._materials = materials && materials.length ? materials - : [this.constructor.Material.createDefault()]; + : [contextProvidersGlobalSettings.Material.createDefault()]; }, }; diff --git a/src/context/providers/BoundaryConditionsFormDataProvider.js b/src/context/providers/BoundaryConditionsFormDataProvider.js index 8e5b8a81..79b248b5 100644 --- a/src/context/providers/BoundaryConditionsFormDataProvider.js +++ b/src/context/providers/BoundaryConditionsFormDataProvider.js @@ -5,8 +5,6 @@ import { Made } from "@mat3ra/made"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; export class BoundaryConditionsFormDataProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - constructor(config) { super(config); this.initMaterialContextMixin(); diff --git a/src/context/providers/CollinearMagnetizationContextProvider.js b/src/context/providers/CollinearMagnetizationContextProvider.js index 562b6ff5..4134c291 100644 --- a/src/context/providers/CollinearMagnetizationContextProvider.js +++ b/src/context/providers/CollinearMagnetizationContextProvider.js @@ -1,12 +1,9 @@ import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; -import { Made } from "@mat3ra/made"; import lodash from "lodash"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; export class CollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - constructor(config) { super(config); diff --git a/src/context/providers/HubbardUContextProvider.js b/src/context/providers/HubbardUContextProvider.js index 2faca898..20103eba 100644 --- a/src/context/providers/HubbardUContextProvider.js +++ b/src/context/providers/HubbardUContextProvider.js @@ -1,5 +1,4 @@ import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; -import { Made } from "@mat3ra/made"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; @@ -10,8 +9,6 @@ const defaultHubbardConfig = { }; export class HubbardUContextProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - constructor(config) { super(config); diff --git a/src/context/providers/MLSettingsContextProvider.js b/src/context/providers/MLSettingsContextProvider.js index d82003af..e51ca213 100644 --- a/src/context/providers/MLSettingsContextProvider.js +++ b/src/context/providers/MLSettingsContextProvider.js @@ -1,11 +1,8 @@ -import { Application } from "@exabyte-io/ade.js"; import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; export class MLSettingsContextProvider extends ContextProvider { - static Application = Application; - constructor(config) { super(config); this.initApplicationContextMixin(); diff --git a/src/context/providers/MLTrainTestSplitContextProvider.js b/src/context/providers/MLTrainTestSplitContextProvider.js index dbfa76ea..5a6a0011 100644 --- a/src/context/providers/MLTrainTestSplitContextProvider.js +++ b/src/context/providers/MLTrainTestSplitContextProvider.js @@ -1,11 +1,8 @@ -import { Application } from "@exabyte-io/ade.js"; import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; export class MLTrainTestSplitContextProvider extends ContextProvider { - static Application = Application; - constructor(config) { super(config); this.initApplicationContextMixin(); diff --git a/src/context/providers/NonCollinearMagnetizationContextProvider.js b/src/context/providers/NonCollinearMagnetizationContextProvider.js index 8bbdfdc0..b5cf6865 100644 --- a/src/context/providers/NonCollinearMagnetizationContextProvider.js +++ b/src/context/providers/NonCollinearMagnetizationContextProvider.js @@ -1,12 +1,9 @@ import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; -import { Made } from "@mat3ra/made"; import lodash from "lodash"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; export class NonCollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - constructor(config) { super(config); this.initMaterialContextMixin(); diff --git a/src/context/providers/PlanewaveCutoffsContextProvider.js b/src/context/providers/PlanewaveCutoffsContextProvider.js index 80b0d7bd..2b83edfe 100644 --- a/src/context/providers/PlanewaveCutoffsContextProvider.js +++ b/src/context/providers/PlanewaveCutoffsContextProvider.js @@ -1,4 +1,3 @@ -import { Application } from "@exabyte-io/ade.js"; import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; @@ -13,8 +12,6 @@ const cutoffConfig = { }; export class PlanewaveCutoffsContextProvider extends ContextProvider { - static Application = Application; - constructor(config) { super(config); this.initApplicationContextMixin(); diff --git a/src/context/providers/PointsGridFormDataProvider.js b/src/context/providers/PointsGridFormDataProvider.js index 9ed1982f..26d27ece 100644 --- a/src/context/providers/PointsGridFormDataProvider.js +++ b/src/context/providers/PointsGridFormDataProvider.js @@ -5,14 +5,9 @@ import { Made } from "@mat3ra/made"; import lodash from "lodash"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; - -// TODO : pass appSettings to use defaultKPPRA +import { contextProvidersGlobalSettings } from "./settings"; export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - - static _defaultKPPRA = 5; - constructor(config) { super(config); this.initMaterialContextMixin(); @@ -55,7 +50,7 @@ export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { _getDefaultGridMetricValue(metric) { switch (metric) { case "KPPRA": - return Math.floor(PointsGridFormDataProvider._defaultKPPRA / this._divisor); + return Math.floor(contextProvidersGlobalSettings.defaultKPPRA / this._divisor); case "spacing": return 0.3; default: diff --git a/src/context/providers/PointsPathFormDataProvider.js b/src/context/providers/PointsPathFormDataProvider.js index 19e3655f..e4612896 100644 --- a/src/context/providers/PointsPathFormDataProvider.js +++ b/src/context/providers/PointsPathFormDataProvider.js @@ -1,6 +1,5 @@ /* eslint-disable max-classes-per-file */ /* eslint react/prop-types: 0 */ -import { Application } from "@exabyte-io/ade.js"; import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; @@ -13,10 +12,6 @@ const defaultPoint = "Г"; const defaultSteps = 10; export class PointsPathFormDataProvider extends JSONSchemaFormDataProvider { - static Material = Made.Material; - - static Application = Application; - constructor(config) { super(config); this.initMaterialContextMixin(); diff --git a/src/context/providers/by_application/espresso/QENEBContextProvider.js b/src/context/providers/by_application/espresso/QENEBContextProvider.js index 57bddfe5..b2d1ad3b 100644 --- a/src/context/providers/by_application/espresso/QENEBContextProvider.js +++ b/src/context/providers/by_application/espresso/QENEBContextProvider.js @@ -1,4 +1,3 @@ -import { Made } from "@mat3ra/made"; import lodash from "lodash"; import { jobContextMixin } from "../../../mixins/JobContextMixin"; @@ -11,8 +10,6 @@ import ExecutableContextProvider from "../ExecutableContextProvider"; import QEPWXContextProvider from "./QEPWXContextProvider"; export default class QENEBContextProvider extends ExecutableContextProvider { - static Material = Made.Material; - _material = undefined; _materials = []; diff --git a/src/context/providers/by_application/espresso/QEPWXContextProvider.js b/src/context/providers/by_application/espresso/QEPWXContextProvider.js index 36800f5f..a4ff9afc 100644 --- a/src/context/providers/by_application/espresso/QEPWXContextProvider.js +++ b/src/context/providers/by_application/espresso/QEPWXContextProvider.js @@ -1,5 +1,4 @@ import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; -import { Made } from "@mat3ra/made"; import path from "path"; import s from "underscore.string"; @@ -11,8 +10,6 @@ import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class QEPWXContextProvider extends ExecutableContextProvider { - static Material = Made.Material; - _material = undefined; _materials = []; diff --git a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js index 7eb0f874..8a229cc5 100644 --- a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -1,5 +1,4 @@ import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; -import { Made } from "@mat3ra/made"; import lodash from "lodash"; import _ from "underscore"; import s from "underscore.string"; @@ -11,8 +10,6 @@ import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class NWChemTotalEnergyContextProvider extends ExecutableContextProvider { - static Material = Made.Material; - _material = undefined; constructor(config) { diff --git a/src/context/providers/by_application/vasp/VASPContextProvider.js b/src/context/providers/by_application/vasp/VASPContextProvider.js index c2850a31..17e30c63 100644 --- a/src/context/providers/by_application/vasp/VASPContextProvider.js +++ b/src/context/providers/by_application/vasp/VASPContextProvider.js @@ -1,5 +1,3 @@ -import { Made } from "@mat3ra/made"; - import { jobContextMixin } from "../../../mixins/JobContextMixin"; import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; @@ -8,8 +6,6 @@ import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; import ExecutableContextProvider from "../ExecutableContextProvider"; export default class VASPContextProvider extends ExecutableContextProvider { - static Material = Made.Material; - _material = undefined; _materials = []; diff --git a/src/context/providers/by_application/vasp/VASPNEBContextProvider.js b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js index b6a2b5c5..28f01258 100644 --- a/src/context/providers/by_application/vasp/VASPNEBContextProvider.js +++ b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js @@ -1,5 +1,3 @@ -import { Made } from "@mat3ra/made"; - import { jobContextMixin } from "../../../mixins/JobContextMixin"; import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; @@ -12,8 +10,6 @@ import VASPContextProvider from "./VASPContextProvider"; export default class VASPNEBContextProvider extends ExecutableContextProvider { _materials = []; - static Material = Made.Material; - constructor(config) { super(config); this.initMaterialContextMixin(); diff --git a/src/context/providers/settings.js b/src/context/providers/settings.js new file mode 100644 index 00000000..1bbb992e --- /dev/null +++ b/src/context/providers/settings.js @@ -0,0 +1,38 @@ +import { Application } from "@exabyte-io/ade.js"; +import { Made } from "@mat3ra/made"; + +class ContextProvidersGlobalSettings { + "PointsGridFormDataProvider.defaultKPPRA" = 5; + + Material = Made.Material; + + Application = Application; + + constructor() { + this.resetDefaults(); + } + + get defaultKPPRA() { + return this["PointsGridFormDataProvider.defaultKPPRA"]; + } + + setApplication(application) { + this.Application = application; + } + + setMaterial(material) { + this.Material = material; + } + + setDefaultKPPRA(kppra) { + this["PointsGridFormDataProvider.defaultKPPRA"] = kppra; + } + + resetDefaults() { + this.Material = Made.Material; + this.Application = Application; + this["PointsGridFormDataProvider.defaultKPPRA"] = 5; + } +} + +export const contextProvidersGlobalSettings = new ContextProvidersGlobalSettings(); diff --git a/tests/context.test.js b/tests/context.test.js index 35779824..c540b962 100644 --- a/tests/context.test.js +++ b/tests/context.test.js @@ -4,6 +4,7 @@ import { expect } from "chai"; import { applicationContextMixin } from "../src/context/mixins/ApplicationContextMixin"; import { materialContextMixin } from "../src/context/mixins/MaterialContextMixin"; +import { contextProvidersGlobalSettings } from "../src/context/providers/settings"; class MockMaterial { static createDefault() { @@ -30,12 +31,6 @@ class SpecificMockApplication { } class ProviderEntity extends ContextProvider { - static Material = MockMaterial; - - static Application = MockApplication; - - static setting = 10; - constructor(config) { super(config); this.initApplicationContextMixin(); @@ -46,70 +41,29 @@ class ProviderEntity extends ContextProvider { applicationContextMixin(ProviderEntity.prototype); materialContextMixin(ProviderEntity.prototype); -class DerivedProviderEntity extends ProviderEntity { - static Material = SpecificMockMaterial; - - static Application = SpecificMockApplication; -} - -class ApplicationContextProvider extends ContextProvider { - static Application = SpecificMockApplication; - - constructor(config) { - super(config); - this.initApplicationContextMixin(); - } -} - -applicationContextMixin(ApplicationContextProvider.prototype); +class DerivedProviderEntity extends ProviderEntity {} describe("Material & Application ContextMixin", () => { const config = { name: "test" }; + after(() => { + contextProvidersGlobalSettings.resetDefaults(); + }); + it("uses static entity class", () => { + contextProvidersGlobalSettings.setMaterial(MockMaterial); + contextProvidersGlobalSettings.setApplication(MockApplication); + const provider = new ProviderEntity(config); expect(provider.material).to.be.equal("defaultMockMaterial"); expect(provider.application).to.be.equal("defaultMockApplication"); }); it("uses static entity class from derived class", () => { + contextProvidersGlobalSettings.setMaterial(SpecificMockMaterial); + contextProvidersGlobalSettings.setApplication(SpecificMockApplication); const provider = new DerivedProviderEntity(config); expect(provider.material).to.be.equal("defaultSpecificMockMaterial"); expect(provider.application).to.be.equal("defaultSpecificMockApplication"); }); }); - -// describe("ContextProviderRegistryContainer", () => { -// const classConfigObj = { -// DataManager: { -// providerCls: ProviderEntity, -// config: { name: "example1", domain: "important" }, -// }, -// ApplicationDataManager: { -// providerCls: ApplicationContextProvider, -// config: { name: "example2", domain: "important" }, -// }, -// }; - -// const defaultSettings = { -// ProviderEntity: { -// setting: 100, -// }, -// }; - -// it("can be created and patched", () => { -// const registry = createAndPatchRegistry( -// classConfigObj, -// { Material: SpecificMockMaterial }, -// defaultSettings, -// ); - -// const _dataProvider = registry.findProviderInstanceByName("DataManager"); -// const dataProvider = new _dataProvider.constructor(_dataProvider.config); -// const _appProvider = registry.findProviderInstanceByName("ApplicationDataManager"); -// const appProvider = new _appProvider.constructor(_appProvider.config); -// expect(_dataProvider.constructor.setting).to.be.equal(100); -// expect(dataProvider.material).to.be.equal("defaultSpecificMockMaterial"); -// expect(appProvider.application).to.be.equal("defaultSpecificMockApplication"); -// }); -// }); From 3efccc04f87a2a1e4cfb5d058dcb0eae0de14c06 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Thu, 19 Jun 2025 18:55:45 +0300 Subject: [PATCH 05/25] chore: introduce context providers settings --- .eslintrc.json | 21 +- package-lock.json | 914 +++++++++++++++++- package.json | 2 +- src/context/mixins/ApplicationContextMixin.js | 4 +- src/context/mixins/MaterialContextMixin.js | 4 +- src/context/mixins/MaterialsContextMixin.js | 4 +- .../providers/PointsGridFormDataProvider.js | 4 +- src/context/providers/settings.js | 4 +- tests/context.test.js | 12 +- 9 files changed, 912 insertions(+), 57 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0b5cb28d..e740de07 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,21 @@ { - "extends": ["@exabyte-io/eslint-config"] + "extends": [ + "@exabyte-io/eslint-config" + ], + "ignorePatterns": [ + "dist/", + "src/workflows/workflows.js" + ], + "settings": { + "import/resolver": { + "node": { + "extensions": [ + ".js", + ".jsx", + ".ts", + ".tsx" + ] + } + } + } } - diff --git a/package-lock.json b/package-lock.json index f3a9ec45..faea4bbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "devDependencies": { "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", - "@exabyte-io/eslint-config": "^2022.11.17-0", + "@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", @@ -2258,6 +2258,51 @@ "node": ">=12.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -2445,32 +2490,38 @@ } }, "node_modules/@exabyte-io/eslint-config": { - "version": "2022.11.17-0", - "resolved": "https://registry.npmjs.org/@exabyte-io/eslint-config/-/eslint-config-2022.11.17-0.tgz", - "integrity": "sha512-BYTDSqvjj6ZiWb8l46T5BKrVfkelct+vK2mh7joHu5UWtJMUzLkb0KQMV1+6SUy4xHFnws33XS7/+JSW1yeZOQ==", + "version": "2025.5.13-0", + "resolved": "https://registry.npmjs.org/@exabyte-io/eslint-config/-/eslint-config-2025.5.13-0.tgz", + "integrity": "sha512-uZcq9jzmDHl+N71GYEM7l0z6mwyYfuZdNA/bIyql6Mp2H++Oot62nIoMhgvds1r7dbrtL/3jD3Xv0YDj12NiYw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.0.0" }, "peerDependencies": { - "@babel/eslint-parser": "7.16.3", - "@babel/plugin-proposal-class-properties": "7.16.0", - "@babel/preset-env": "7.16.4", - "@babel/preset-react": "7.16.7", + "@babel/eslint-parser": "^7.16.3", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.7", "@babel/register": "^7.16.0", - "@babel/runtime-corejs3": "7.16.8", - "eslint": "7.32.0", - "eslint-config-airbnb": "19.0.2", + "@babel/runtime-corejs3": "^7.16.8", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", + "eslint": "^7.32.0", + "eslint-config-airbnb": "^19.0.2", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-exports": "^1.0.0-beta.2", "eslint-import-resolver-meteor": "^0.4.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-plugin-import": "2.25.3", - "eslint-plugin-jsdoc": "37.1.0", - "eslint-plugin-jsx-a11y": "6.5.1", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsdoc": "^37.1.0 || ^50.6.0", + "eslint-plugin-jsonc": "^2.12.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-mui-path-imports": "^0.0.15", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "7.30.0", - "eslint-plugin-simple-import-sort": "7.0.0" + "eslint-plugin-react": "^7.30.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "jsonc-eslint-parser": "^2.1.0" } }, "node_modules/@exabyte-io/ide.js": { @@ -3312,6 +3363,61 @@ "eslint-scope": "5.1.1" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.10.tgz", @@ -3451,6 +3557,14 @@ "@types/react": "*" } }, + "node_modules/@types/semver": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/underscore": { "version": "1.11.15", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.15.tgz", @@ -3466,6 +3580,277 @@ "@types/underscore": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -3479,9 +3864,10 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3723,6 +4109,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -3908,12 +4305,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4655,6 +5053,20 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4950,13 +5362,44 @@ "v8-compile-cache": "^2.0.3" }, "bin": { - "eslint": "bin/eslint.js" + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", + "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=10" } }, "node_modules/eslint-config-airbnb": { @@ -5067,6 +5510,29 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-json-compat-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", + "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esquery": "^1.6.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0" + }, + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } + } + }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -5215,6 +5681,66 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/eslint-plugin-jsonc": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.20.1.tgz", + "integrity": "sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.1", + "eslint-compat-utils": "^0.6.4", + "eslint-json-compat-utils": "^0.2.1", + "espree": "^9.6.1 || ^10.3.0", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.4.0", + "natural-compare": "^1.4.0", + "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-jsonc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-jsonc/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", @@ -5247,6 +5773,23 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/eslint-plugin-mui-path-imports": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/eslint-plugin-mui-path-imports/-/eslint-plugin-mui-path-imports-0.0.15.tgz", + "integrity": "sha512-u61kgRBtUAG+zoApuf8oWuW6mf3SIfrpMq/gSQEM2h/3qzkqvWXB4RRmPzVryS6bpeXT0QsW8rFcdcMVnoz0hw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "requireindex": "^1.2.0" + }, + "engines": { + "node": "12.x || 14.x || >= 16" + }, + "peerDependencies": { + "eslint": ">=6" + } + }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -5639,9 +6182,10 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5745,6 +6289,24 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5770,6 +6332,17 @@ } ] }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5782,10 +6355,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6126,6 +6700,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -6144,6 +6762,14 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -6566,6 +7192,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7103,6 +7730,73 @@ "node": ">=6" } }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -7627,13 +8321,25 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -8020,6 +8726,14 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -8615,6 +9329,17 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -8769,6 +9494,28 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -8996,6 +9743,17 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -9042,6 +9800,18 @@ "node": ">=8" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", @@ -9063,6 +9833,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -9548,6 +10343,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@pkgr/core": "^0.2.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -9630,6 +10442,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "devOptional": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9746,6 +10559,31 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD", + "peer": true + }, "node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", diff --git a/package.json b/package.json index 7f31d942..b735c483 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "devDependencies": { "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", - "@exabyte-io/eslint-config": "^2022.11.17-0", + "@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", diff --git a/src/context/mixins/ApplicationContextMixin.js b/src/context/mixins/ApplicationContextMixin.js index 942a375b..76484ad4 100644 --- a/src/context/mixins/ApplicationContextMixin.js +++ b/src/context/mixins/ApplicationContextMixin.js @@ -1,4 +1,4 @@ -import { contextProvidersGlobalSettings } from "../providers/settings"; +import { globalSettings } from "../providers/settings"; export function applicationContextMixin(item) { const properties = { @@ -7,7 +7,7 @@ export function applicationContextMixin(item) { initApplicationContextMixin() { this._application = (this.config.context && this.config.context.application) || - contextProvidersGlobalSettings.Application.createDefault(); + globalSettings.Application.createDefault(); }, get application() { diff --git a/src/context/mixins/MaterialContextMixin.js b/src/context/mixins/MaterialContextMixin.js index fbbd6306..6c0d6530 100644 --- a/src/context/mixins/MaterialContextMixin.js +++ b/src/context/mixins/MaterialContextMixin.js @@ -1,4 +1,4 @@ -import { contextProvidersGlobalSettings } from "../providers/settings"; +import { globalSettings } from "../providers/settings"; export function materialContextMixin(item) { const properties = { @@ -30,7 +30,7 @@ export function materialContextMixin(item) { this._material = this.config.context && this.config.context.material; if (!this._material) { - this._material = contextProvidersGlobalSettings.Material.createDefault(); + this._material = globalSettings.Material.createDefault(); } this.updateMaterialHash(); diff --git a/src/context/mixins/MaterialsContextMixin.js b/src/context/mixins/MaterialsContextMixin.js index 348f214e..9ebc2e59 100644 --- a/src/context/mixins/MaterialsContextMixin.js +++ b/src/context/mixins/MaterialsContextMixin.js @@ -1,4 +1,4 @@ -import { contextProvidersGlobalSettings } from "../providers/settings"; +import { globalSettings } from "../providers/settings"; export function materialsContextMixin(item) { const properties = { @@ -10,7 +10,7 @@ export function materialsContextMixin(item) { this._materials = materials && materials.length ? materials - : [contextProvidersGlobalSettings.Material.createDefault()]; + : [globalSettings.Material.createDefault()]; }, }; diff --git a/src/context/providers/PointsGridFormDataProvider.js b/src/context/providers/PointsGridFormDataProvider.js index 26d27ece..3d473125 100644 --- a/src/context/providers/PointsGridFormDataProvider.js +++ b/src/context/providers/PointsGridFormDataProvider.js @@ -5,7 +5,7 @@ import { Made } from "@mat3ra/made"; import lodash from "lodash"; import { materialContextMixin } from "../mixins/MaterialContextMixin"; -import { contextProvidersGlobalSettings } from "./settings"; +import { globalSettings } from "./settings"; export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { constructor(config) { @@ -50,7 +50,7 @@ export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { _getDefaultGridMetricValue(metric) { switch (metric) { case "KPPRA": - return Math.floor(contextProvidersGlobalSettings.defaultKPPRA / this._divisor); + return Math.floor(globalSettings.defaultKPPRA / this._divisor); case "spacing": return 0.3; default: diff --git a/src/context/providers/settings.js b/src/context/providers/settings.js index 1bbb992e..39f604b1 100644 --- a/src/context/providers/settings.js +++ b/src/context/providers/settings.js @@ -1,7 +1,7 @@ import { Application } from "@exabyte-io/ade.js"; import { Made } from "@mat3ra/made"; -class ContextProvidersGlobalSettings { +class GlobalSettings { "PointsGridFormDataProvider.defaultKPPRA" = 5; Material = Made.Material; @@ -35,4 +35,4 @@ class ContextProvidersGlobalSettings { } } -export const contextProvidersGlobalSettings = new ContextProvidersGlobalSettings(); +export const globalSettings = new GlobalSettings(); diff --git a/tests/context.test.js b/tests/context.test.js index c540b962..84a615ca 100644 --- a/tests/context.test.js +++ b/tests/context.test.js @@ -4,7 +4,7 @@ import { expect } from "chai"; import { applicationContextMixin } from "../src/context/mixins/ApplicationContextMixin"; import { materialContextMixin } from "../src/context/mixins/MaterialContextMixin"; -import { contextProvidersGlobalSettings } from "../src/context/providers/settings"; +import { globalSettings } from "../src/context/providers/settings"; class MockMaterial { static createDefault() { @@ -47,12 +47,12 @@ describe("Material & Application ContextMixin", () => { const config = { name: "test" }; after(() => { - contextProvidersGlobalSettings.resetDefaults(); + globalSettings.resetDefaults(); }); it("uses static entity class", () => { - contextProvidersGlobalSettings.setMaterial(MockMaterial); - contextProvidersGlobalSettings.setApplication(MockApplication); + globalSettings.setMaterial(MockMaterial); + globalSettings.setApplication(MockApplication); const provider = new ProviderEntity(config); expect(provider.material).to.be.equal("defaultMockMaterial"); @@ -60,8 +60,8 @@ describe("Material & Application ContextMixin", () => { }); it("uses static entity class from derived class", () => { - contextProvidersGlobalSettings.setMaterial(SpecificMockMaterial); - contextProvidersGlobalSettings.setApplication(SpecificMockApplication); + globalSettings.setMaterial(SpecificMockMaterial); + globalSettings.setApplication(SpecificMockApplication); const provider = new DerivedProviderEntity(config); expect(provider.material).to.be.equal("defaultSpecificMockMaterial"); expect(provider.application).to.be.equal("defaultSpecificMockApplication"); From 1477c63b051c48265679137a7a1a6f54f13ba47f Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Fri, 20 Jun 2025 20:28:17 +0300 Subject: [PATCH 06/25] fix: atomicPositions in NWChemTotalEnergyContextProvider --- .../nwchem/NWChemTotalEnergyContextProvider.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js index 8a229cc5..ec0f30c0 100644 --- a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -25,7 +25,17 @@ export default class NWChemTotalEnergyContextProvider extends ExecutableContextP } get atomicPositions() { - return this.material.Basis.getAtomicPositionsWithConstraintsAsStrings(); + const originalIsInCrystalUnits = this.material.Basis.isInCrystalUnits; + + this.material.Basis.toCartesian(); + + const atomicPositions = this.material.Basis.getAtomicPositionsWithConstraintsAsStrings(); + + if (originalIsInCrystalUnits) { + this.material.Basis.toCrystal(); + } + + return atomicPositions; } get atomSymbols() { From 353e1f771bd88d1308356c6c0a1f3e445f67c1ab Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Sat, 21 Jun 2025 00:36:19 +0300 Subject: [PATCH 07/25] fix: atomicPositions in NWChemTotalEnergyContextProvider --- .../nwchem/NWChemTotalEnergyContextProvider.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js index ec0f30c0..ff327c78 100644 --- a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -25,14 +25,15 @@ export default class NWChemTotalEnergyContextProvider extends ExecutableContextP } get atomicPositions() { - const originalIsInCrystalUnits = this.material.Basis.isInCrystalUnits; + const basis = this.material.Basis; + const originalIsInCrystalUnits = basis.isInCrystalUnits; - this.material.Basis.toCartesian(); + basis.toCartesian(); - const atomicPositions = this.material.Basis.getAtomicPositionsWithConstraintsAsStrings(); + const atomicPositions = basis.getAtomicPositionsWithConstraintsAsStrings(); if (originalIsInCrystalUnits) { - this.material.Basis.toCrystal(); + basis.toCrystal(); } return atomicPositions; From cc97ae3c2106d4f63206bb02e9eb07746b0131a1 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Mon, 23 Jun 2025 12:33:08 +0300 Subject: [PATCH 08/25] chore: cleanup --- .../nwchem/NWChemTotalEnergyContextProvider.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js index ff327c78..7ab58020 100644 --- a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -26,17 +26,8 @@ export default class NWChemTotalEnergyContextProvider extends ExecutableContextP get atomicPositions() { const basis = this.material.Basis; - const originalIsInCrystalUnits = basis.isInCrystalUnits; - basis.toCartesian(); - - const atomicPositions = basis.getAtomicPositionsWithConstraintsAsStrings(); - - if (originalIsInCrystalUnits) { - basis.toCrystal(); - } - - return atomicPositions; + return basis.getAtomicPositionsWithConstraintsAsStrings(); } get atomSymbols() { From 68a4f0e989e21cbf12aab9f252775dd6f6e724c8 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 24 Jun 2025 15:18:09 +0300 Subject: [PATCH 09/25] 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 faea4bbc..7f8a7679 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 b735c483..4583ad61 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 98b0dfc8..c97690b5 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 10/25] 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 7f8a7679..7c3e01b5 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 4583ad61..11d7af1c 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 0211a021..8acf579c 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 d9ed73ee..2bfb6f91 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 11/25] 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 7c3e01b5..160cc9b5 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 11d7af1c..aad632a5 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 8acf579c..ee03ff8d 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 12/25] 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 160cc9b5..4628e9ce 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 aad632a5..ba92c71d 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 ee03ff8d..4f0af4d4 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 13/25] 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 4628e9ce..1853cb19 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 ba92c71d..2f9c7df7 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 4f0af4d4..e961c95d 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 14/25] 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 e961c95d..71421712 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 15/25] 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 71421712..b24d2702 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 16/25] 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 1853cb19..7d6b2b7b 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 2f9c7df7..11ef69b1 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 b24d2702..3d2a3b98 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 17/25] 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 cb8f4362..b91e77d0 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 dfb1e04d..73ece9eb 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 8c02cd3a..57ad7f3c 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 b89361b9..7f115923 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 18/25] 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 73ece9eb..836e467e 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 19/25] 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 836e467e..587feb5e 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 20/25] 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 b91e77d0..4688373f 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 21/25] 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 7f115923..037ee38b 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; + }); }); From 3f0a0df7599a75bbdb727171a9ed200e7a6cc2a5 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 15 Jul 2025 12:39:33 +0300 Subject: [PATCH 22/25] chore: update ade --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d6b2b7b..e1c44323 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#51864363d0d9525a2481b733068cb00396806370", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#86b2161b58c8e1557722bffcdd6e131ff129ca8c", "@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#51864363d0d9525a2481b733068cb00396806370", - "integrity": "sha512-V5aYHiKdltBocyMeiPy35sTMk0h6KKpPiexZwONYlhfriOOFLh5xIaxaQqfUbsTgRBlx84MCV7nJiQJ7jMobwA==", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#86b2161b58c8e1557722bffcdd6e131ff129ca8c", + "integrity": "sha512-/blq34Bs5fNR/0x2qczcEEYfocapYWzKaAgzmtWPmsLdfCc+dc4jRRkZ6AfjkZWxc56s9WelFZUVF0zkH73o9Q==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 11ef69b1..ad574a8b 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#51864363d0d9525a2481b733068cb00396806370", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#86b2161b58c8e1557722bffcdd6e131ff129ca8c", "@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", From 4d876e8c5b0c01a558f1335bb75e1f7f1ce1a67d Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 15 Jul 2025 21:05:51 +0300 Subject: [PATCH 23/25] chore: update code/made/ade --- package-lock.json | 24 ++++++++++++------------ package.json | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 087538e9..fe06d532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,14 +28,14 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#1259e1c2e2d648ffa01598464510dce9a5d46771", + "@exabyte-io/ade.js": "2025.7.15-0", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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#72a4dd05240da180f09fcb04db9f469aea4077af", + "@mat3ra/code": "2025.7.15-0", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", @@ -2383,9 +2383,9 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/@exabyte-io/ade.js": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#1259e1c2e2d648ffa01598464510dce9a5d46771", - "integrity": "sha512-CcOtW3YfSpeYuC1lKa/5fEJFrHLGiM+9XB6KghC4IFEwvnDocs9FycuZm0m+o+378zE28p4X3ufQhS9d2QZIGA==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.7.15-0.tgz", + "integrity": "sha512-ivItgWJyaourwpRPuxcT+qENfPBkKlSmXzu20zRBrl6lG2iGcTXNsaUh/PKzrWbfzKegx5GADiPdygpHcuWgww==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2812,9 +2812,9 @@ "dev": true }, "node_modules/@mat3ra/code": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#72a4dd05240da180f09fcb04db9f469aea4077af", - "integrity": "sha512-hFH6YKXzLlVyc2B936NEnbyaptfXHbdNL01uqB741op4GdZTpy6eBvxA43BKt8ej1gRIzoIdKsxEZhZnTJUe7Q==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@mat3ra/code/-/code-2025.7.15-0.tgz", + "integrity": "sha512-3CZ9jIC57aIvDZatlizfwqR7tgjPiBU25eb7tZKH3QzdQfKRFjBPx8fBibqjZgu7l8qagyN+eZQoZ6utnYeojA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3197,9 +3197,9 @@ } }, "node_modules/@mat3ra/made": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", - "integrity": "sha512-c+QC8p72ENTbRdx1aQOpP/soLLcnzF6P3uXf9cQicVeZ8H+IJpnvU3ORpMkPFWn4VZ5mU32EDqqnrRc4kXK+0A==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@mat3ra/made/-/made-2025.7.15-0.tgz", + "integrity": "sha512-6mpQnpxrQ8FEP8mO+0N8oa36tURxeNM7N2zHthzz6gZlqYNf5ipJp9F6vHEqMLZ30RSIib4/oCmK3UQI4MBzAA==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index e8c2ba41..b97627f0 100644 --- a/package.json +++ b/package.json @@ -49,14 +49,14 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#1259e1c2e2d648ffa01598464510dce9a5d46771", + "@exabyte-io/ade.js": "2025.7.15-0", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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#72a4dd05240da180f09fcb04db9f469aea4077af", + "@mat3ra/code": "2025.7.15-0", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", From dd6c429caa4a47218cd63d029946e60e58edbddd Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 15 Jul 2025 21:06:47 +0300 Subject: [PATCH 24/25] chore: update code/made/ade --- package-lock.json | 24 ++++++++++++------------ package.json | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index c070b27b..fe06d532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,14 +28,14 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "@exabyte-io/ade.js": "2025.7.15-0", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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": "2025.7.15-0", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", @@ -2383,9 +2383,9 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "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==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.7.15-0.tgz", + "integrity": "sha512-ivItgWJyaourwpRPuxcT+qENfPBkKlSmXzu20zRBrl6lG2iGcTXNsaUh/PKzrWbfzKegx5GADiPdygpHcuWgww==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2812,9 +2812,9 @@ "dev": true }, "node_modules/@mat3ra/code": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", - "integrity": "sha512-w/v9+NRIZkRt6Ov5jBVowGmxnuAv1JrXMOderAZd9kVqTEvDMcPpImd1NV1VQTHG8xy7Uq2piRS0a15SyyVh6Q==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@mat3ra/code/-/code-2025.7.15-0.tgz", + "integrity": "sha512-3CZ9jIC57aIvDZatlizfwqR7tgjPiBU25eb7tZKH3QzdQfKRFjBPx8fBibqjZgu7l8qagyN+eZQoZ6utnYeojA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3197,9 +3197,9 @@ } }, "node_modules/@mat3ra/made": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", - "integrity": "sha512-c+QC8p72ENTbRdx1aQOpP/soLLcnzF6P3uXf9cQicVeZ8H+IJpnvU3ORpMkPFWn4VZ5mU32EDqqnrRc4kXK+0A==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@mat3ra/made/-/made-2025.7.15-0.tgz", + "integrity": "sha512-6mpQnpxrQ8FEP8mO+0N8oa36tURxeNM7N2zHthzz6gZlqYNf5ipJp9F6vHEqMLZ30RSIib4/oCmK3UQI4MBzAA==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 4966bfbc..b97627f0 100644 --- a/package.json +++ b/package.json @@ -49,14 +49,14 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "@exabyte-io/ade.js": "2025.7.15-0", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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": "2025.7.15-0", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", From be8965d8d3ba9b19ad5bbefed0c8d0be2186ed07 Mon Sep 17 00:00:00 2001 From: Kostiantyn Dvornik Date: Tue, 15 Jul 2025 21:23:55 +0300 Subject: [PATCH 25/25] chore: resolve conflicts --- package-lock.json | 17 +++++++++-------- package.json | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe06d532..6b93974c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,13 +28,13 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.7.15-0", + "@exabyte-io/ade.js": "2025.7.15-1", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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": "2025.7.15-0", - "@mat3ra/esse": "2025.4.26-0", + "@mat3ra/esse": "2025.7.15-0", "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0", @@ -2383,9 +2383,9 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/@exabyte-io/ade.js": { - "version": "2025.7.15-0", - "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.7.15-0.tgz", - "integrity": "sha512-ivItgWJyaourwpRPuxcT+qENfPBkKlSmXzu20zRBrl6lG2iGcTXNsaUh/PKzrWbfzKegx5GADiPdygpHcuWgww==", + "version": "2025.7.15-1", + "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.7.15-1.tgz", + "integrity": "sha512-w2anDB6p9+O/ioiNRYI8ykewi56vwV9+u/hO+KvgHI0TBPaFXmYbQkl73lnekm3QwWbqHSA/G5JSQ52Zez+Ttw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2851,10 +2851,11 @@ } }, "node_modules/@mat3ra/esse": { - "version": "2025.4.26-0", - "resolved": "https://registry.npmjs.org/@mat3ra/esse/-/esse-2025.4.26-0.tgz", - "integrity": "sha512-0xWNAZTTM6F7Gv1FGMWjs/6cnLVKsIKLwYpQqs5Tll/gqF9KwXdO6l3GJznjDZCUy1lrWgvBrHaD0NBGjKa5Iw==", + "version": "2025.7.15-0", + "resolved": "https://registry.npmjs.org/@mat3ra/esse/-/esse-2025.7.15-0.tgz", + "integrity": "sha512-q/oeMrx1wKGFB/e9USu+jzrKDVc0HEBz4Igar7VMIfvXEI/ucNq4Esd4chVkSalf/0BT4jbCJrL8PLojWMd7mg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/cli": "^7.27.0", "@babel/core": "^7.26.10", diff --git a/package.json b/package.json index b97627f0..1099d860 100644 --- a/package.json +++ b/package.json @@ -49,13 +49,13 @@ "v20": "^0.1.0" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.7.15-0", + "@exabyte-io/ade.js": "2025.7.15-1", "@exabyte-io/application-flavors.js": "2025.7.8-0", "@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": "2025.7.15-0", - "@mat3ra/esse": "2025.4.26-0", + "@mat3ra/esse": "2025.7.15-0", "@mat3ra/made": "2025.7.15-0", "chai": "^4.3.4", "eslint": "7.32.0",