@mat3ra/mode 2026.3.4-0 → 2026.5.28-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/js/tree.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ApplicationSchemaBase, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
1
+ import { type DFTModelSchema, type MLModelSchema, type UnknownModelSchema, ApplicationSchema } from "@mat3ra/esse/dist/js/types";
2
2
  import type { ModelTree } from "./types";
3
3
  export declare const MODEL_TREE: {
4
4
  dft: {
@@ -69,8 +69,10 @@ export declare const METHODS: {
69
69
  };
70
70
  export declare const getPseudopotentialTypesFromTree: () => string[];
71
71
  export declare const getDFTFunctionalsFromTree: () => string[];
72
- export declare const getDFTFunctionalsByApproximation: (approximation: string) => string[] | undefined;
73
- export declare const treeSlugToNamedObject: (modelSlug: string) => SlugifiedEntry;
74
- export declare const getTreeByApplicationNameAndVersion: ({ name, }: Pick<ApplicationSchemaBase, "name" | "version">) => ModelTree;
75
- export declare const getDefaultModelTypeForApplication: (application: ApplicationSchemaBase) => string;
76
- export declare const getDefaultModelSubtypeForApplicationAndType: (application: ApplicationSchemaBase, type: string) => string | undefined;
72
+ export declare const getDFTFunctionalsByApproximation: (approximation: "gga" | "lda" | "hybrid" | "other") => string[] | undefined;
73
+ export declare function treeSlugToNamedObject<T extends string>(modelSlug: T): {
74
+ readonly slug: T;
75
+ readonly name: string;
76
+ };
77
+ export declare const getTreeByApplicationNameAndVersion: ({ name, }: Pick<ApplicationSchema, "name" | "version">) => ModelTree | undefined;
78
+ export declare function getDefaultModelTypeSubtypeForApplication(application: Pick<ApplicationSchema, "name" | "version">): Pick<DFTModelSchema, "type" | "subtype"> | Pick<MLModelSchema, "type" | "subtype"> | Pick<UnknownModelSchema, "type" | "subtype">;
package/dist/js/tree.js CHANGED
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getDefaultModelSubtypeForApplicationAndType = exports.getDefaultModelTypeForApplication = exports.getTreeByApplicationNameAndVersion = exports.treeSlugToNamedObject = exports.getDFTFunctionalsByApproximation = exports.getDFTFunctionalsFromTree = exports.getPseudopotentialTypesFromTree = exports.METHODS = exports.MODEL_NAMES = exports.MODEL_TREE = void 0;
6
+ exports.getTreeByApplicationNameAndVersion = exports.getDFTFunctionalsByApproximation = exports.getDFTFunctionalsFromTree = exports.getPseudopotentialTypesFromTree = exports.METHODS = exports.MODEL_NAMES = exports.MODEL_TREE = void 0;
7
+ exports.treeSlugToNamedObject = treeSlugToNamedObject;
8
+ exports.getDefaultModelTypeSubtypeForApplication = getDefaultModelTypeSubtypeForApplication;
7
9
  const modelsTreeConfigByApplication_json_1 = __importDefault(require("@mat3ra/standata/dist/js/runtime_data/models/modelsTreeConfigByApplication.json"));
8
10
  const modelTree_json_1 = __importDefault(require("@mat3ra/standata/dist/js/runtime_data/models/modelTree.json"));
9
11
  const lodash_1 = __importDefault(require("lodash"));
@@ -30,26 +32,26 @@ const getDFTFunctionalsByApproximation = (approximation) => {
30
32
  return branch === null || branch === void 0 ? void 0 : branch.functionals;
31
33
  };
32
34
  exports.getDFTFunctionalsByApproximation = getDFTFunctionalsByApproximation;
33
- const treeSlugToNamedObject = (modelSlug) => {
35
+ function treeSlugToNamedObject(modelSlug) {
34
36
  return {
35
37
  slug: modelSlug,
36
38
  name: lodash_1.default.get(exports.MODEL_NAMES, modelSlug, modelSlug),
37
39
  };
38
- };
39
- exports.treeSlugToNamedObject = treeSlugToNamedObject;
40
+ }
40
41
  const getTreeByApplicationNameAndVersion = ({ name, }) => {
41
42
  // TODO: add logic to filter by version when necessary
42
- // @ts-ignore
43
- return modelsTreeConfigByApplication_json_1.default[name] || {};
43
+ if (!(name in modelsTreeConfigByApplication_json_1.default)) {
44
+ return undefined;
45
+ }
46
+ return modelsTreeConfigByApplication_json_1.default[name];
44
47
  };
45
48
  exports.getTreeByApplicationNameAndVersion = getTreeByApplicationNameAndVersion;
46
- const getDefaultModelTypeForApplication = (application) => {
47
- return Object.keys((0, exports.getTreeByApplicationNameAndVersion)(application))[0];
48
- };
49
- exports.getDefaultModelTypeForApplication = getDefaultModelTypeForApplication;
50
- const getDefaultModelSubtypeForApplicationAndType = (application, type) => {
49
+ function getDefaultModelTypeSubtypeForApplication(application) {
51
50
  const tree = (0, exports.getTreeByApplicationNameAndVersion)(application);
52
- const subtypes = Object.keys(tree[type] || {});
53
- return subtypes[0];
54
- };
55
- exports.getDefaultModelSubtypeForApplicationAndType = getDefaultModelSubtypeForApplicationAndType;
51
+ if (!tree) {
52
+ throw new Error(`getDefaultModelTypeForApplication: tree not found for application ${application.name}`);
53
+ }
54
+ const type = Object.keys(tree)[0];
55
+ const subtype = Object.keys(tree[type] || {})[0] || "unknown";
56
+ return { type, subtype };
57
+ }
@@ -1,16 +1,20 @@
1
- import type { ApplicationSchemaBase, BaseModel, CategorizedMethod, CategorizedModel, CategorizedUnitMethod } from "@mat3ra/esse/dist/js/types";
2
- export type ModelConfig = Pick<BaseModel, "type" | "subtype"> & Partial<Omit<BaseModel, "type" | "subtype">> & {
3
- application?: ApplicationSchemaBase;
1
+ import type { ApplicationSchema, CategorizedMethod, CategorizedModel, CategorizedUnitMethod, DFTModelSchema, MLModelSchema, UnknownModelSchema } from "@mat3ra/esse/dist/js/types";
2
+ /**
3
+ * Makes specified fields required and all others optional
4
+ * TODO: consider moving to code.js
5
+ */
6
+ export type RequireFields<T, K extends keyof T> = Required<Pick<T, K>> & Partial<Omit<T, K>>;
7
+ type ModelRequiredFields = "type" | "subtype";
8
+ export type DFTModelConfig = RequireFields<DFTModelSchema, ModelRequiredFields>;
9
+ export type MLModelConfig = RequireFields<MLModelSchema, ModelRequiredFields>;
10
+ export type UnknownModelConfig = RequireFields<UnknownModelSchema, ModelRequiredFields>;
11
+ export type ModelConfig = (DFTModelConfig | MLModelConfig | UnknownModelConfig) & {
12
+ application?: ApplicationSchema;
4
13
  };
5
14
  export type SimplifiedCategorizedModel = Pick<CategorizedModel, "name" | "path" | "categories" | "parameters">;
6
15
  export type SimplifiedCategorizedMethod = Pick<CategorizedMethod, "name" | "path"> & {
7
16
  units: CategorizedUnitMethod[];
8
17
  };
9
- export interface PseudopotentialLike {
10
- element?: string;
11
- toJSON(): Record<string, unknown>;
12
- }
13
- export type PseudopotentialCtor = new (config: Record<string, unknown>) => PseudopotentialLike;
14
18
  export interface MethodTreeBranch {
15
19
  methods: Record<string, string[]>;
16
20
  functionals?: string[];
@@ -18,3 +22,4 @@ export interface MethodTreeBranch {
18
22
  modifiers?: string[];
19
23
  }
20
24
  export type ModelTree = Record<string, Record<string, MethodTreeBranch>>;
25
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mat3ra/mode",
3
- "version": "2026.3.4-0",
3
+ "version": "2026.5.28-0",
4
4
  "description": "MOdel and method DEfinitions",
5
5
  "scripts": {
6
6
  "test": "nyc --reporter=text mocha --recursive --bail",
@@ -54,9 +54,10 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@exabyte-io/eslint-config": "2025.5.13-0",
57
- "@mat3ra/esse": "2025.10.8-0",
57
+ "@mat3ra/code": "2026.5.27-0",
58
+ "@mat3ra/esse": "2026.5.27-0",
59
+ "@mat3ra/prode": "2026.5.28-0",
58
60
  "@mat3ra/standata": "2025.11.12-0",
59
- "@mat3ra/code": "2025.10.8-0",
60
61
  "@mat3ra/tsconfig": "2024.6.3-0",
61
62
  "@types/chai": "^4.3.11",
62
63
  "@types/mocha": "^10.0.6",
@@ -82,8 +83,8 @@
82
83
  },
83
84
  "peerDependencies": {
84
85
  "@mat3ra/esse": "*",
85
- "@mat3ra/standata": "*",
86
- "@mat3ra/code": "*"
86
+ "@mat3ra/code": "*",
87
+ "@mat3ra/prode": "*"
87
88
  },
88
89
  "engines": {
89
90
  "node": ">20.0.0"
@@ -1,22 +1,28 @@
1
- import { BaseMethod, BaseModel, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
1
+ import { BaseModel, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
2
2
  import lodash from "lodash";
3
3
 
4
4
  import { MODEL_NAMES, MODEL_TREE } from "./tree";
5
5
 
6
- export const PseudopotentialMethodConfig: BaseMethod = {
6
+ export const PseudopotentialMethodConfig = {
7
7
  type: "pseudopotential",
8
8
  subtype: "us",
9
- };
9
+ } as const;
10
10
 
11
- export const LocalOrbitalMethodConfig: BaseMethod = {
11
+ export const LocalOrbitalMethodConfig = {
12
12
  type: "localorbital",
13
13
  subtype: "pople",
14
- };
14
+ } as const;
15
15
 
16
- export const UnknownMethodConfig: BaseMethod = {
16
+ export const UnknownMethodConfig = {
17
17
  type: "unknown",
18
18
  subtype: "unknown",
19
- };
19
+ } as const;
20
+
21
+ export const methodConfigs = {
22
+ pseudopotential: PseudopotentialMethodConfig,
23
+ localorbital: LocalOrbitalMethodConfig,
24
+ unknown: UnknownMethodConfig,
25
+ } as const;
20
26
 
21
27
  const mapSlugToNamedObject = (slug: string): SlugifiedEntry => {
22
28
  return {
@@ -30,7 +36,10 @@ export function allowedTypes(model: Pick<BaseModel, "type" | "subtype">): Slugif
30
36
  return lodash.keys(branch).map(mapSlugToNamedObject);
31
37
  }
32
38
 
33
- export function allowedSubtypes(model: Pick<BaseModel, "type" | "subtype">, type: string): SlugifiedEntry[] {
39
+ export function allowedSubtypes(
40
+ model: Pick<BaseModel, "type" | "subtype">,
41
+ type: string,
42
+ ): SlugifiedEntry[] {
34
43
  const branch = lodash.get(MODEL_TREE, `${model.type}.${model.subtype}.methods.${type}`, []);
35
44
  return (branch as string[]).map(mapSlugToNamedObject);
36
45
  }
@@ -1,11 +1,9 @@
1
- import type { ModelConfig } from "./types";
2
-
3
- export const DFTModelConfig: ModelConfig = {
1
+ export const DFTModelConfig = {
4
2
  type: "dft",
5
3
  subtype: "gga",
6
- };
4
+ } as const;
7
5
 
8
- export const UnknownModelConfig: ModelConfig = {
6
+ export const UnknownModelConfig = {
9
7
  type: "unknown",
10
8
  subtype: "unknown",
11
- };
9
+ } as const;
@@ -5,21 +5,35 @@ export type MethodSchemaMixin = BaseMethod;
5
5
 
6
6
  export type MethodInMemoryEntity = InMemoryEntity & MethodSchemaMixin;
7
7
 
8
- export function methodSchemaMixin(item: InMemoryEntity) {
8
+ export function methodSchemaMixin<T extends InMemoryEntity>(
9
+ item: InMemoryEntity,
10
+ ): asserts item is T & MethodSchemaMixin {
9
11
  // @ts-expect-error
10
12
  const properties: InMemoryEntity & MethodSchemaMixin = {
11
13
  get type() {
12
14
  return this.requiredProp<BaseMethod["type"]>("type");
13
15
  },
16
+ set type(value: BaseMethod["type"]) {
17
+ this.setProp("type", value);
18
+ },
14
19
  get subtype() {
15
20
  return this.requiredProp<BaseMethod["subtype"]>("subtype");
16
21
  },
22
+ set subtype(value: BaseMethod["subtype"]) {
23
+ this.setProp("subtype", value);
24
+ },
17
25
  get precision() {
18
26
  return this.prop<BaseMethod["precision"]>("precision");
19
27
  },
28
+ set precision(value: BaseMethod["precision"]) {
29
+ this.setProp("precision", value);
30
+ },
20
31
  get data() {
21
32
  return this.prop<BaseMethod["data"]>("data");
22
33
  },
34
+ set data(value: BaseMethod["data"]) {
35
+ this.setProp("data", value);
36
+ },
23
37
  };
24
38
 
25
39
  Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
@@ -5,18 +5,29 @@ export type ModelSchemaMixin = BaseModel;
5
5
 
6
6
  export type ModelInMemoryEntity = InMemoryEntity & ModelSchemaMixin;
7
7
 
8
- export function modelSchemaMixin(item: InMemoryEntity) {
8
+ export function modelSchemaMixin<T extends InMemoryEntity>(
9
+ item: InMemoryEntity,
10
+ ): asserts item is T & ModelSchemaMixin {
9
11
  // @ts-expect-error
10
12
  const properties: InMemoryEntity & ModelSchemaMixin = {
11
13
  get type() {
12
14
  return this.requiredProp<BaseModel["type"]>("type");
13
15
  },
16
+ set type(value: BaseModel["type"]) {
17
+ this.setProp("type", value);
18
+ },
14
19
  get subtype() {
15
20
  return this.requiredProp<BaseModel["subtype"]>("subtype");
16
21
  },
22
+ set subtype(value: BaseModel["subtype"]) {
23
+ this.setProp("subtype", value);
24
+ },
17
25
  get method() {
18
26
  return this.requiredProp<BaseModel["method"]>("method");
19
27
  },
28
+ set method(value: BaseModel["method"]) {
29
+ this.setProp("method", value);
30
+ },
20
31
  };
21
32
 
22
33
  Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
package/src/js/index.ts CHANGED
@@ -23,4 +23,3 @@ export {
23
23
  default_models,
24
24
  default_methods,
25
25
  };
26
-
package/src/js/method.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
2
2
  import { deepClone } from "@mat3ra/code/dist/js/utils";
3
3
  import type { Constructor } from "@mat3ra/code/dist/js/utils/types";
4
+ import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types";
4
5
  import type { BaseMethod, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
5
6
  import lodash from "lodash";
6
7
 
@@ -19,6 +20,8 @@ export class Method extends (InMemoryEntity as Base) implements BaseMethod {
19
20
  super({ ...config, data });
20
21
  }
21
22
 
23
+ declare toJSON: () => BaseMethod & AnyObject;
24
+
22
25
  cloneWithoutData(): Method {
23
26
  const clone = this.clone() as Method;
24
27
  clone.setData({});
@@ -29,7 +32,7 @@ export class Method extends (InMemoryEntity as Base) implements BaseMethod {
29
32
  this.setProp("subtype", subtype);
30
33
  }
31
34
 
32
- static get defaultConfig(): BaseMethod {
35
+ static get defaultConfig() {
33
36
  return PseudopotentialMethodConfig;
34
37
  }
35
38
 
@@ -1,79 +1,61 @@
1
- import { safeMakeArray } from "@mat3ra/code/dist/js/utils";
2
- import { BaseMethod } from "@mat3ra/esse/dist/js/types";
1
+ import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types";
2
+ import { type BaseMethod, type FileDataItem } from "@mat3ra/esse/dist/js/types";
3
+ import { PseudopotentialFilter, PseudopotentialMetaProperty } from "@mat3ra/prode";
3
4
  import _ from "underscore";
4
5
 
5
6
  import { Method } from "../method";
6
- import type { PseudopotentialCtor, PseudopotentialLike } from "../types";
7
7
 
8
- export class PseudopotentialMethod extends Method {
9
- PseudopotentialCls: PseudopotentialCtor | null;
10
-
11
- constructor(config: BaseMethod) {
12
- super(config);
13
- this.PseudopotentialCls = null;
14
- }
8
+ export type ExchangeCorrelation = {
9
+ approximation: string;
10
+ functional: string;
11
+ };
15
12
 
16
- get pseudo(): Record<string, unknown>[] {
17
- return this.prop<Record<string, unknown>[]>("data.pseudo", []);
18
- }
13
+ export class PseudopotentialMethod extends Method {
14
+ declare toJSON: () => BaseMethod & AnyObject;
19
15
 
20
- get allPseudo(): Record<string, unknown>[] {
21
- return this.prop<Record<string, unknown>[]>("data.allPseudo", []);
16
+ get pseudo() {
17
+ return this.prop<FileDataItem[]>("data.pseudo", []);
22
18
  }
23
19
 
24
- get pseudopotentials(): PseudopotentialLike[] {
25
- if (!this.PseudopotentialCls) return [];
26
- return this.pseudo.map((config) => new this.PseudopotentialCls!(config));
20
+ get allPseudo() {
21
+ return this.prop<FileDataItem[]>("data.allPseudo", []);
27
22
  }
28
23
 
29
- get allPseudopotentials(): PseudopotentialLike[] {
30
- if (!this.PseudopotentialCls) return [];
31
- return this.allPseudo.map((config) => new this.PseudopotentialCls!(config));
24
+ get pseudopotentials() {
25
+ return this.pseudo.map((config) => new PseudopotentialMetaProperty(config));
32
26
  }
33
27
 
34
- static extractExchangeCorrelationFromSubworkflow(subworkflow: any): {
35
- approximation: string;
36
- functional: string;
37
- } {
38
- const { model } = subworkflow;
39
- const approximation = model.subtype;
40
- const functionalValue = model.functional;
41
- const functional = functionalValue && (functionalValue.slug || functionalValue);
42
- return {
43
- approximation,
44
- functional: functional || "",
45
- };
28
+ get allPseudopotentials() {
29
+ return this.allPseudo.map((config) => new PseudopotentialMetaProperty(config));
46
30
  }
47
31
 
48
32
  hasPseudopotentialFor(element: string): boolean {
49
33
  return Boolean(this.pseudopotentials.find((pseudo) => pseudo.element === element));
50
34
  }
51
35
 
52
- setPseudopotentialPerElement(pseudo: PseudopotentialLike | undefined): void {
36
+ setPseudopotentialPerElement(pseudo?: PseudopotentialMetaProperty) {
53
37
  if (!pseudo) {
54
38
  this.setPseudopotentials([]);
55
39
  return;
56
40
  }
57
41
  const filtered = this.pseudopotentials.filter((item) => item.element !== pseudo.element);
58
- filtered.push(pseudo);
59
- this.setPseudopotentials(filtered);
42
+
43
+ this.setPseudopotentials([...filtered, pseudo]);
60
44
  }
61
45
 
62
- addToAllPseudos(pseudos: PseudopotentialLike | PseudopotentialLike[]): void {
63
- const list = safeMakeArray(pseudos);
64
- const all = this.allPseudopotentials;
65
- all.push(...list);
66
- this.setAllPseudopotentials(all);
46
+ addToAllPseudos(pseudos: PseudopotentialMetaProperty | PseudopotentialMetaProperty[]) {
47
+ const list = Array.isArray(pseudos) ? pseudos : [pseudos];
48
+ this.setAllPseudopotentials([...this.allPseudopotentials, ...list]);
67
49
  }
68
50
 
69
- setPseudopotentials(pseudopotentials: PseudopotentialLike[]): void {
51
+ setPseudopotentials(pseudopotentials: PseudopotentialMetaProperty[]) {
70
52
  this.setData({
71
53
  ...this.data,
72
54
  pseudo: _.sortBy(pseudopotentials, "element").map((item) => item.toJSON()),
73
55
  });
74
56
  }
75
57
 
76
- setAllPseudopotentials(pseudopotentials: PseudopotentialLike[]): void {
58
+ setAllPseudopotentials(pseudopotentials: PseudopotentialMetaProperty[]) {
77
59
  this.setData({
78
60
  ...this.data,
79
61
  allPseudo: _.sortBy(pseudopotentials, "element").map((item) => item.toJSON()),
@@ -83,4 +65,58 @@ export class PseudopotentialMethod extends Method {
83
65
  toJSONWithCleanData(exclude: string[] = []): BaseMethod {
84
66
  return super.toJSONWithCleanData(exclude.concat(["allPseudo"]));
85
67
  }
68
+
69
+ updateMethodDataByApplicationAndMaterials(
70
+ methodDataItems: PseudopotentialMetaProperty[],
71
+ pseudoFilter: Pick<PseudopotentialFilter, "elements" | "appName" | "exchangeCorrelation">,
72
+ ) {
73
+ const typeFilter = { type: this.subtype };
74
+ let pseudos = PseudopotentialMetaProperty.applyPseudoFilters(methodDataItems, {
75
+ ...pseudoFilter,
76
+ ...typeFilter,
77
+ });
78
+
79
+ // sorting pseudos, this is very hacky! TODO: find better approach for default pseudos per application
80
+ if (this.subtype === "us") {
81
+ pseudos = PseudopotentialMetaProperty.sortPseudosByPattern(pseudos);
82
+ }
83
+ pseudos = PseudopotentialMetaProperty.sortByPathApplicationSpecific(
84
+ pseudos,
85
+ pseudoFilter.appName,
86
+ );
87
+ pseudos = PseudopotentialMetaProperty.filterUnique(pseudos);
88
+
89
+ this.setAllPseudopotentials(pseudos);
90
+ this.setSearchText(this.searchText);
91
+
92
+ // if searchText is present => use it to filter the pseudos before selecting one per element
93
+ pseudos = PseudopotentialMetaProperty.safelyFilterRawDataBySearchText(
94
+ pseudos,
95
+ this.searchText,
96
+ );
97
+
98
+ const newFilter = {
99
+ elements: pseudoFilter.elements,
100
+ appName: pseudoFilter.appName,
101
+ exchangeCorrelation: pseudoFilter.exchangeCorrelation,
102
+ searchText: this.searchText,
103
+ ...typeFilter,
104
+ };
105
+
106
+ // try to keep previously selected pseudos
107
+ // TODO: rework creating/updating method data items once methodData has been removed from store
108
+ const filteredSelected = PseudopotentialMetaProperty.applyPseudoFilters(
109
+ this.pseudopotentials,
110
+ newFilter,
111
+ );
112
+
113
+ // set first pseudopotentials as selected per element, prioritize already selected
114
+ pseudoFilter.elements?.forEach((el) => {
115
+ const selected = filteredSelected.find((p) => p.element === el);
116
+ const pseudo = selected || pseudos.find((p) => p.element === el);
117
+ this.setPseudopotentialPerElement(pseudo);
118
+ });
119
+
120
+ return this;
121
+ }
86
122
  }
package/src/js/model.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
2
2
  import type { Constructor } from "@mat3ra/code/dist/js/utils/types";
3
+ import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types";
3
4
  import type {
4
- ApplicationSchemaBase,
5
+ AnyModelSchema,
6
+ ApplicationSchema,
5
7
  BaseMethod,
6
8
  BaseModel,
7
9
  SlugifiedEntry,
@@ -22,7 +24,7 @@ const EMPTY_BRANCH: MethodTreeBranch = { methods: {} };
22
24
  type Base = typeof InMemoryEntity & Constructor<ModelSchemaMixin>;
23
25
 
24
26
  export class Model extends (InMemoryEntity as Base) implements BaseModel {
25
- protected _application?: ApplicationSchemaBase;
27
+ protected _application?: ApplicationSchema;
26
28
 
27
29
  protected _MethodFactory: typeof MethodFactory;
28
30
 
@@ -31,14 +33,13 @@ export class Model extends (InMemoryEntity as Base) implements BaseModel {
31
33
  constructor(config: ModelConfig) {
32
34
  const { application, method = Method.defaultConfig, ...entityConfig } = config;
33
35
  super(entityConfig);
34
- this._application = application as ApplicationSchemaBase | undefined;
36
+ this._application = application;
35
37
  this._MethodFactory = MethodFactory;
36
- if (method) {
37
- this.setProp("method", method);
38
- }
38
+ this.method = method || this.method;
39
39
  }
40
40
 
41
41
  setSubtype(subtype: SlugifiedEntryOrSlug): void {
42
+ // TODO-question: subtype is a string, but we're setting it to a SlugifiedEntryOrSlug
42
43
  this.setProp("subtype", subtype);
43
44
  this.setMethod(this._MethodFactory.create(this.defaultMethodConfig));
44
45
  }
@@ -122,7 +123,7 @@ export class Model extends (InMemoryEntity as Base) implements BaseModel {
122
123
  return { type, subtype };
123
124
  }
124
125
 
125
- static get defaultConfig(): ModelConfig {
126
+ static get defaultConfig() {
126
127
  return {
127
128
  ...DFTModelConfig,
128
129
  method: Method.defaultConfig,
@@ -133,14 +134,15 @@ export class Model extends (InMemoryEntity as Base) implements BaseModel {
133
134
  return Object.keys(MODEL_TREE).map((modelSlug) => treeSlugToNamedObject(modelSlug));
134
135
  }
135
136
 
136
- toJSON(): Record<string, unknown> {
137
- const json = super.toJSON();
137
+ declare _json: AnyModelSchema & AnyObject;
138
+
139
+ toJSON(): AnyModelSchema & AnyObject {
138
140
  return {
139
- ...json,
141
+ ...super.toJSON(),
140
142
  type: this.type,
141
143
  subtype: this.subtype,
142
144
  method: this.Method.toJSONWithCleanData(),
143
- };
145
+ } as AnyModelSchema & AnyObject;
144
146
  }
145
147
 
146
148
  // eslint-disable-next-line class-methods-use-this