Skip to content

Commit

Permalink
Merge pull request #92 from Exabyte-io/update/SOF-7096
Browse files Browse the repository at this point in the history
SOF-7096: Typescript
  • Loading branch information
k0stik authored Dec 1, 2023
2 parents fdb4642 + a21d80c commit e90e345
Show file tree
Hide file tree
Showing 31 changed files with 1,864 additions and 2,998 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"extends": ["@exabyte-io/eslint-config"],
"ignorePatterns": ["lib/"],
"settings": {
"import/resolver": {
"node": {
Expand Down
5 changes: 5 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extension": ["ts", "js"],
"spec": "tests/**/*.js",
"require": ["ts-node/register", "tests/setup.js"]
}
3,084 changes: 858 additions & 2,226 deletions package-lock.json

Large diffs are not rendered by default.

36 changes: 23 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"description": "Materials Design in Javascript",
"scripts": {
"prepublishOnly": "rm -rf lib; npm run transpile",
"transpile": "tsc",
"postinstall": "npm run transpile",
"transpile": "mkdir -p lib && babel --extensions '.js,.jsx,.ts,.tsx' src --out-dir lib",
"test": "nyc --reporter=text mocha --recursive --bail --require @babel/register/lib --require tests/setup.js tests",
"test": "mocha",
"lint": "eslint src tests && prettier --write src tests",
"lint:fix": "eslint --fix --cache src tests && prettier --write src tests",
"prettier": "prettier --check src tests",
Expand All @@ -27,39 +27,49 @@
"node": ">=0.12"
},
"devDependencies": {
"@exabyte-io/code.js": "2023.11.1-0",
"@exabyte-io/eslint-config": "^2022.11.17-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.22.15",
"@babel/runtime-corejs3": "^7.16.8",
"@exabyte-io/code.js": "2023.12.1-0",
"@exabyte-io/eslint-config": "^2023.8.29-1",
"@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.1",
"chai": "^4.3.4",
"chai-almost": "^1.0.1",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^19.0.2",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-exports": "^1.0.0-beta.5",
"eslint-import-resolver-meteor": "^0.4.0",
"eslint-import-resolver-node": "^0.3.9",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsdoc": "^37.1.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.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.1.2",
"mocha": "^9.1.3",
"nyc": "^15.1.0",
"prettier": "^2.5.1"
},
"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/register": "^7.16.0",
"@exabyte-io/periodic-table.js": "2022.5.28-0",
"@types/chai": "^4.3.5",
"@types/mocha": "^10.0.1",
"@types/node": "^20.4.2",
"@types/underscore": "^1.11.6",
"@types/underscore.string": "^0.0.40",
"array-almost-equal": "^1.0.0",
"crypto-js": "^3.1.9-1",
"lodash": "^4.17.4",
"mathjs": "^3.9.0",
"mixwith": "^0.1.1",
"typescript": "^4.5.5",
"underscore": "^1.8.3",
"underscore.string": "^3.3.4"
},
Expand Down
75 changes: 0 additions & 75 deletions src/abstract/array_with_ids.js

This file was deleted.

100 changes: 100 additions & 0 deletions src/abstract/array_with_ids.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import _ from "underscore";

import {
isObjectWithIdAndValue,
ObjectWithIdAndValue,
ScalarWithId,
ValueOrObject,
} from "./scalar_with_id";

type Predicate<T> = (o: T) => boolean;

type MapFunction<T> = (value: T, index: number, array: T[]) => T;

export function isArrayOfObjectsWithIdAndValue<T>(
valueOrObjects: ValueOrObject<T>[],
): valueOrObjects is ObjectWithIdAndValue<T>[] {
return isObjectWithIdAndValue(valueOrObjects[0]);
}

/**
* Helper class representing an ArrayWithIds. Used to explicitly track values assigned to atoms, for example.
*/
export class ArrayWithIds<T> {
array: T[];

/**
* Create a an array with ids.
* @param {Array} array - Either regular array or ArrayWithIds (see @example above)
*/
constructor(array: ObjectWithIdAndValue<T>[] | T[] = []) {
if (!_.isArray(array)) {
throw new Error("ArrayWithIds.constructor: pass array on initialization");
}
// if passed an array with ids as config, only store the values in array
if (isArrayOfObjectsWithIdAndValue<T>(array)) {
this.array = array.sort((a, b) => a.id - b.id).map((element) => element.value);
} else {
this.array = [...array];
}
}

/**
* Serialize class instance to JSON.
* @example [{"id" : 0, "value" : "Si" }, {"id" : 1, "value" : "Si" }]
*/
toJSON(): ObjectWithIdAndValue<T>[] {
// from ["a", "b"] to [{id: 0, value: "a"}, {id: 1, value: "b"}]
return this.array.map((el, idx) => new ScalarWithId<T>(el, idx).toJSON());
}

/**
* Apply function fn to each element of the array and replace `array` with the result.
* @param fn - The function to be applied to each array element.
*/
mapArrayInPlace(fn: MapFunction<T>) {
if (!_.isFunction(fn)) {
throw new Error("ArrayWithIds.mapArray: must pass function as argument");
}

this.array = this.array.map(fn);
}

getArrayElementByIndex(idx: number) {
return this.array[idx];
}

/**
* Get the index of the array element that passes the predicate.
* @param {Function} predicate - The function to be applied to each array element.
*/
getArrayIndexByPredicate(predicate: Predicate<T>) {
return this.array.findIndex((el) => predicate(el));
}

/**
* Add an entity to array.
* @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
*/
addElement(el: ValueOrObject<T>) {
const value = isObjectWithIdAndValue(el) ? el.value : el;
if (el) this.array.push(value);
}

/**
* Remove an entity to array. Either by passing the entity, or the corresponding index.
* @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
* @param idx - The entity to be added to array. If Object with 'value' key, its value will be added.
*/
removeElement(el: ValueOrObject<T> | null, idx?: number) {
let _idx;
if (idx === undefined) {
_idx = this.array.findIndex((elm) => elm === el);
} else {
_idx = idx;
}
if (_idx !== undefined) {
this.array.splice(_idx, 1);
}
}
}
37 changes: 0 additions & 37 deletions src/abstract/scalar_with_id.js

This file was deleted.

53 changes: 53 additions & 0 deletions src/abstract/scalar_with_id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import _ from "underscore";

export interface ObjectWithIdAndValue<T> {
id: number;
value: T;
}

export type ValueOrObject<T> = ObjectWithIdAndValue<T> | T;

export type ValueOrObjectArray<T> = ObjectWithIdAndValue<T>[] | T[];

export function isObjectWithIdAndValue<T>(
valueOrObject: ValueOrObject<T>,
): valueOrObject is ObjectWithIdAndValue<T> {
return Boolean(_.isObject(valueOrObject) && !_.isArray(valueOrObject) && valueOrObject.value);
}

/**
* Helper class representing a scalar with an associated id.
*/
export class ScalarWithId<T> {
id: number;

value: T;

/**
* Create a an array with ids.
* @param valueOrObject - a ScalarWithID, or any other type.
* @param id - numerical id (Integer).
*/
constructor(valueOrObject: ValueOrObject<T>, id = 0) {
// if already passing a ScalarWithId => preserve original
if (isObjectWithIdAndValue(valueOrObject)) {
// NOTE - Arrays are Objects too
this.id = valueOrObject.id;
this.value = valueOrObject.value;
} else {
this.id = id;
this.value = valueOrObject;
}
}

/**
* Serialize class instance to JSON.
* @example {"id" : 0, "value" : "Si" }
*/
toJSON(): ObjectWithIdAndValue<T> {
return {
id: this.id,
value: this.value,
};
}
}
Loading

0 comments on commit e90e345

Please sign in to comment.