Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,501 changes: 1,732 additions & 769 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"prepare": "husky install",
"prettier": "prettier --check src/js tests/js",
"test": "nyc --reporter=text mocha --recursive --bail tests/js",
"transpile": "tsc -p tsconfig-transpile.json"
"transpile": "tsc -p tsconfig-transpile.json",
"generate-mixins": "ts-node scripts/generate-mixins.ts"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -54,7 +55,7 @@
"@babel/register": "^7.25.7",
"@babel/runtime-corejs3": "^7.25.7",
"@exabyte-io/eslint-config": "^2025.1.15-0",
"@mat3ra/esse": "2025.10.8-0",
"@mat3ra/esse": "git+https://github.com/Exabyte-io/esse#ca7bfd433dd1612fe27f2b8d39853c755359836d",
"@mat3ra/tsconfig": "2024.6.3-0",
"@types/chai": "^4.3.20",
"@types/crypto-js": "^4.2.2",
Expand Down
51 changes: 51 additions & 0 deletions scripts/generate-mixins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env node

/**
* Script to generate mixin properties from JSON schema
*
* This script generates mixin functions for property/holder, property/meta_holder,
* and property/proto_holder schemas automatically.
*
* Usage:
* npx ts-node scripts/generate-mixin-properties.ts
*/

import allSchemas from "@mat3ra/esse/dist/js/schemas.json";
import type { JSONSchema7 } from "json-schema";

import generateSchemaMixin from "../dist/js/generateSchemaMixin";

/**
* Fields to skip during generation
*/
const SKIP_FIELDS: string[] = [];

/**
* Output file paths for each schema
*/
const OUTPUT_PATHS = {
"system/defaultable": "src/js/generated/DefaultableSchemaMixin.ts",
"system/has-consistency-check": "src/js/generated/HasConsistencyChecksSchemaMixin.ts",
"system/description": "src/js/generated/HasDescriptionSchemaMixin.ts",
"system/name": "src/js/generated/NamedEntitySchemaMixin.ts",
"system/tags": "src/js/generated/TaggableSchemaMixin.ts",
"system/runtime-items": "src/js/generated/RuntimeItemsSchemaMixin.ts",
};

function main() {
// Type assertion to handle schema compatibility - the schemas from esse may have slightly different types
const result = generateSchemaMixin(
allSchemas as JSONSchema7[],
OUTPUT_PATHS,
SKIP_FIELDS,
undefined,
"../entity/in_memory",
);

if (result.errorCount > 0) {
process.exit(1);
}
}

// Run the script if it's executed directly
main();
38 changes: 35 additions & 3 deletions src/js/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
export enum Units {
bohr = "bohr",
angstrom = "angstrom",
degree = "degree",
radian = "radian",
alat = "alat",
}

/**
* @summary Coordinates units for a material's basis.
*/
export enum AtomicCoordinateUnits {
crystal = "crystal",
cartesian = "cartesian",
}

// in crystal coordinates
export enum Tolerance {
length = 0.01,
lengthAngstrom = 0.001,
pointsDistance = 0.001,
}

export enum Coefficients {
EV_TO_RY = 0.0734986176,
BOHR_TO_ANGSTROM = 0.52917721092,
ANGSTROM_TO_BOHR = 1 / 0.52917721092,
EV_A_TO_RY_BOHR = 1 / 25.71104309541616,
}

// Only 3 digits will be considered for lattice and basis params on hashing
export const HASH_TOLERANCE = 3 as const;

// TODO: remove everything below this line

export const coefficients = {
EV_TO_RY: 0.0734986176,
BOHR_TO_ANGSTROM: 0.52917721092,
Expand Down Expand Up @@ -28,9 +63,6 @@ export const ATOMIC_COORD_UNITS = {
cartesian: "cartesian",
};

// Only 3 digits will be considered for lattice and basis params on hashing
export const HASH_TOLERANCE = 3;

export default {
coefficients,
tolerance,
Expand Down
23 changes: 8 additions & 15 deletions src/js/entity/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { InMemoryEntity } from "./in_memory";
import { ContextAndRenderFieldsMixin } from "./mixins/context";
import { RuntimeContextFieldMixin } from "./mixins/context_runtime";
import { FlowchartEntityMixin, FlowchartItemMixin } from "./mixins/flowchart";
import { HasScopeTrackMixin } from "./mixins/props";
import { RuntimeItemsMixin } from "./mixins/runtime_items";
// import { RuntimeItemsMixin } from "./mixins/runtime_items";
import {
DefaultableInMemoryEntity,
HasConsistencyChecksHasMetadataNamedDefaultableInMemoryEntity,
HasMetadataNamedDefaultableInMemoryEntity,
NamedDefaultableInMemoryEntity,
NamedDefaultableRepetitionContextAndRenderInMemoryEntity,
NamedDefaultableRepetitionImportantSettingsInMemoryEntity,
NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity,
NamedInMemoryEntity,
// NamedDefaultableRepetitionContextAndRenderInMemoryEntity,
// NamedDefaultableRepetitionImportantSettingsInMemoryEntity,
// NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity,
} from "./other";
import { InMemoryEntitySet } from "./set";
import { ENTITY_SET_TYPES } from "./set/enums";
Expand All @@ -30,12 +27,11 @@ export {
DefaultableInMemoryEntity,
NamedDefaultableInMemoryEntity,
HasMetadataNamedDefaultableInMemoryEntity,
NamedDefaultableRepetitionContextAndRenderInMemoryEntity,
NamedDefaultableRepetitionImportantSettingsInMemoryEntity,
NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity,
// NamedDefaultableRepetitionContextAndRenderInMemoryEntity,
// NamedDefaultableRepetitionImportantSettingsInMemoryEntity,
// NamedDefaultableRepetitionRuntimeItemsImportantSettingsContextAndRenderHashedInMemoryEntity,
HasConsistencyChecksHasMetadataNamedDefaultableInMemoryEntity,
HasScopeTrackMixin,
RuntimeItemsMixin,
// RuntimeItemsMixin,
RuntimeContextFieldMixin,
InMemoryEntitySet,
ENTITY_SET_TYPES,
Expand All @@ -45,7 +41,4 @@ export {
InMemoryEntityInSetMixin,
OrderedInMemoryEntitySetMixin,
OrderedInMemoryEntityInSetMixin,
ContextAndRenderFieldsMixin,
FlowchartEntityMixin,
FlowchartItemMixin,
};
39 changes: 39 additions & 0 deletions src/js/entity/mixins/ContextAndRenderFieldsMixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { AnyObject } from "@mat3ra/esse/dist/js/esse/types";

import type { InMemoryEntity } from "../in_memory";

export type Context = AnyObject;

export type ContextAndRenderFields = {
context?: Context;
updateContext(ctx: Context): void;
getPersistentContext(): Context | undefined;
updatePersistentContext(ctx: Context): void;
getCombinedContext(): Context;
};

type AbstractBase = {
render(ctx: Context): void;
};

export function contextAndRenderFieldsMixin<T extends InMemoryEntity & AbstractBase>(
item: T,
): asserts item is T & ContextAndRenderFields {
// @ts-expect-error
const properties: InMemoryEntity & ContextAndRenderFields = {
updateContext(ctx: Context) {
this.context = { ...this.context, ...ctx };
},
getPersistentContext() {
return this.prop<Context>("context");
},
updatePersistentContext(ctx: Context) {
this.setProp("context", { ...ctx });
},
getCombinedContext() {
return { ...this.getPersistentContext(), ...this.context };
},
};

Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
}
43 changes: 17 additions & 26 deletions src/js/entity/mixins/DefaultableMixin.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import type { Constructor } from "../../utils/types";
import {
type DefaultableSchemaMixin,
defaultableSchemaMixin,
} from "../../generated/DefaultableSchemaMixin";
import type { AbstractConstructor, Constructor } from "../../utils/types";
import { InMemoryEntity } from "../in_memory";

export function defaultableEntityMixin<T extends InMemoryEntity>(item: T) {
// @ts-expect-error
const properties: InMemoryEntity & DefaultableInMemoryEntity = {
get isDefault() {
return this.prop("isDefault", false);
},
set isDefault(isDefault: boolean) {
this.setProp("isDefault", isDefault);
},
};
export type Defaultable = DefaultableSchemaMixin;

Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
export type DefaultableInMemoryStaticEntity = {
createDefault: () => InMemoryEntity & Defaultable;
};

return properties;
}
export type DefaultableInMemoryEntityConstructor = Constructor<Defaultable> &
DefaultableInMemoryStaticEntity;

export function defaultableEntityStaticMixin(Item: Constructor<InMemoryEntity>) {
function defaultableEntityStaticMixin(Item: AbstractConstructor<InMemoryEntity>) {
// @ts-expect-error
const staticProperties: DefaultableInMemoryStaticEntity &
Constructor<InMemoryEntity> &
Constructor<DefaultableInMemoryEntity> & {
Constructor<DefaultableSchemaMixin> & {
defaultConfig?: object | null;
} = {
createDefault() {
Expand All @@ -36,13 +33,7 @@ export function defaultableEntityStaticMixin(Item: Constructor<InMemoryEntity>)
return staticProperties;
}

export type DefaultableInMemoryEntity = {
isDefault: boolean;
};

export type DefaultableInMemoryStaticEntity = {
createDefault: () => InMemoryEntity & DefaultableInMemoryEntity;
};

export type DefaultableInMemoryEntityConstructor = Constructor<DefaultableInMemoryEntity> &
DefaultableInMemoryStaticEntity;
export function defaultableEntityMixin(Item: AbstractConstructor<InMemoryEntity>) {
defaultableSchemaMixin(Item.prototype);
defaultableEntityStaticMixin(Item);
}
36 changes: 18 additions & 18 deletions src/js/entity/mixins/HasConsistencyChecksMixin.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import type { ConsistencyCheck } from "@mat3ra/esse/dist/js/types";

import {
type HasConsistencyChecksSchemaMixin,
hasConsistencyChecksSchemaMixin,
} from "../../generated/HasConsistencyChecksSchemaMixin";
import type { Constructor } from "../../utils/types";
import { InMemoryEntity } from "../in_memory";

export function hasConsistencyChecksMixin<T extends InMemoryEntity>(item: T) {
type HasConsistencyChecksProperties = {
addConsistencyChecks: (array: ConsistencyCheck[]) => void;
};

export type HasConsistencyChecks = HasConsistencyChecksSchemaMixin & HasConsistencyChecksProperties;

export type HasConsistencyChecksInMemoryEntityConstructor = Constructor<HasConsistencyChecks>;

export function hasConsistencyChecksMixin<T extends InMemoryEntity>(
item: T,
): asserts item is T & HasConsistencyChecks {
hasConsistencyChecksSchemaMixin(item);

// @ts-expect-error
const properties: InMemoryEntity & HasConsistencyChecksInMemoryEntity = {
get consistencyChecks(): ConsistencyCheck[] {
return this.prop("consistencyChecks", []);
},
set consistencyChecks(array: ConsistencyCheck[]) {
this.setProp("consistencyChecks", array);
},
const properties: InMemoryEntity & HasConsistencyChecks = {
addConsistencyChecks(array: ConsistencyCheck[]) {
this.consistencyChecks = [...(this.consistencyChecks || []), ...array];
},
};

Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));

return properties;
}

export type HasConsistencyChecksInMemoryEntity = {
consistencyChecks: ConsistencyCheck[];
addConsistencyChecks: (array: ConsistencyCheck[]) => void;
};

export type HasConsistencyChecksInMemoryEntityConstructor =
Constructor<HasConsistencyChecksInMemoryEntity>;
37 changes: 6 additions & 31 deletions src/js/entity/mixins/HasDescriptionMixin.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
import type { DescriptionSchema } from "@mat3ra/esse/dist/js/types";
import {
type HasDescriptionSchemaMixin,
hasDescriptionSchemaMixin,
} from "../../generated/HasDescriptionSchemaMixin";

import type { Constructor } from "../../utils/types";
import { InMemoryEntity } from "../in_memory";
export type HasDescription = HasDescriptionSchemaMixin;

export function hasDescriptionMixin<T extends InMemoryEntity>(item: T) {
// @ts-expect-error
const properties: InMemoryEntity & HasDescriptionInMemoryEntity = {
get description(): string {
return this.prop("description", "");
},
set description(string: string) {
this.setProp("description", string);
},
get descriptionObject() {
return this.prop<DescriptionSchema["descriptionObject"]>("descriptionObject");
},
set descriptionObject(obj: DescriptionSchema["descriptionObject"]) {
this.setProp("descriptionObject", obj);
},
};

Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));

return properties;
}

export type HasDescriptionInMemoryEntity = {
description: string;
descriptionObject: DescriptionSchema["descriptionObject"];
};

export type HasDescriptionInMemoryEntityConstructor = Constructor<HasDescriptionInMemoryEntity>;
export const hasDescriptionPropertiesMixin = hasDescriptionSchemaMixin;
Loading
Loading