Skip to content

Commit a71421f

Browse files
authored
Merge pull request #1 from Exabyte-io/chore/SOF-5949
Chore/sof 5949 - init repository with sources from `imports/core_code` in the main web application
2 parents 8a17058 + 839eb9e commit a71421f

32 files changed

+6088
-18
lines changed

.nycrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"all": true,
3+
"include": [
4+
"src/**/*.js",
5+
"src/**/*.jsx"
6+
]
7+
}

README.md

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
1-
# template-definitions
1+
[![npm version](https://badge.fury.io/js/%40exabyte-io%2F/code.js.svg)](https://badge.fury.io/js/%40exabyte-io%2F/code.js)
2+
[![License: Apache](https://img.shields.io/badge/License-Apache-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
23

3-
Template repository for entity definition libraries in Javascript
4+
# @exabyte-io/code.js
45

5-
See [here](https://docs.github.com/en/github-ae@latest/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template)
6-
for details on how to use this repository.
6+
@exabyte-io/code.js houses entity definitions for use in the Mat3ra platform.
77

8-
Included is a simple `template.py` analog to `cookiecutter` which will prompt
9-
the user for some information and then write out templated values in select files.
10-
After usage, the `template.py` file can be removed and the `README.md` and associated
11-
`files` can be committed.
8+
9+
### Installation
10+
11+
For usage within a javascript project:
12+
13+
```bash
14+
npm install @exabyte-io/code.js
15+
```
16+
17+
For development:
18+
19+
```bash
20+
git clone https://github.com/Exabyte-io/code.js.git
21+
```
22+
23+
24+
### Contribution
25+
26+
This repository is an [open-source](LICENSE.md) work-in-progress and we welcome contributions.
27+
28+
We regularly deploy the latest code containing all accepted contributions online as part of the
29+
[Mat3ra.com](https://mat3ra.com) platform, so contributors will see their code in action there.
30+
31+
See [ESSE](https://github.com/Exabyte-io/esse) for additional context regarding the data schemas used here.
32+
33+
Useful commands for development:
34+
35+
```bash
36+
# run linter without persistence
37+
npm run lint
38+
39+
# run linter and save edits
40+
npm run lint:fix
41+
42+
# compile the library
43+
npm run transpile
44+
45+
# run tests
46+
npm run test
47+
```
1248

package-lock.json

Lines changed: 5066 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
{
2-
"name": "@exabyte-io/PROJECT_NAME",
2+
"name": "@exabyte-io/code.js",
33
"version": "0.0.0",
4-
"description": "PROJECT_DESCRIPTION",
4+
"description": "COre DEfinitions in JS for Mat3ra.com (Exabyte.io)",
55
"scripts": {
66
"test": "nyc --reporter=text mocha --recursive --bail --require @babel/register/lib --require tests/setup.js tests",
77
"lint": "eslint src tests && prettier --write src tests",
88
"lint:fix": "eslint --fix --cache src tests && prettier --write src tests",
99
"transpile": "babel --out-dir dist src",
10-
"postinstall": "npm run transpile",
11-
"prepare": "husky install"
10+
"postinstall": "npm run transpile"
1211
},
1312
"repository": {
1413
"type": "git",
15-
"url": "https://github.com/Exabyte-io/PROJECT_NAME.git"
14+
"url": "https://github.com/Exabyte-io/code.js.git"
1615
},
1716
"main": "dist/index.js",
17+
"exports": {
18+
"./context": "./dist/context/index.js",
19+
"./entity": "./dist/entity/index.js",
20+
"./utils": "./dist/utils/index.js"
21+
},
1822
"files": [
1923
"/dist",
2024
"/src",
2125
".babelrc"
2226
],
2327
"author": "Exabyte Inc.",
2428
"bugs": {
25-
"url": "https://github.com/Exabyte-io/PROJECT_NAME/issues"
29+
"url": "https://github.com/Exabyte-io/code.js/issues"
2630
},
2731
"license": "Apache-2.0",
28-
"homepage": "https://github.com/Exabyte-io/PROJECT_NAME",
32+
"homepage": "https://github.com/Exabyte-io/code.js",
2933
"dependencies": {
3034
"@babel/cli": "7.16.0",
3135
"@babel/core": "7.16.0",
@@ -34,7 +38,11 @@
3438
"@babel/preset-env": "7.16.4",
3539
"@babel/preset-react": "7.16.7",
3640
"@babel/register": "^7.16.0",
37-
"@babel/runtime-corejs3": "7.16.8"
41+
"@babel/runtime-corejs3": "7.16.8",
42+
"crypto-js": "^4.1.1",
43+
"lodash": "^4.17.21",
44+
"mixwith": "^0.1.1",
45+
"underscore": "^1.13.3"
3846
},
3947
"devDependencies": {
4048
"chai": "^4.3.4",
@@ -59,4 +67,3 @@
5967
"*.{js,css}": "prettier --write"
6068
}
6169
}
62-

src/context/index.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ContextProvider } from "./provider";
2+
import { ContextProviderRegistryContainer } from "./registry";
3+
4+
import { JobContextPickKeysForMixin, WorkflowContextPickKeysForMixin } from "./pickers";
5+
6+
import {
7+
ApplicationContextMixinBuilder,
8+
MaterialContextMixinBuilder,
9+
MaterialsContextMixinBuilder,
10+
MaterialsSetContextMixin,
11+
MethodDataContextMixin,
12+
JobContextMixin,
13+
WorkflowContextMixin,
14+
} from "./mixins";
15+
16+
export {
17+
ContextProvider,
18+
ContextProviderRegistryContainer,
19+
20+
JobContextPickKeysForMixin,
21+
WorkflowContextPickKeysForMixin,
22+
23+
ApplicationContextMixinBuilder,
24+
MaterialContextMixinBuilder,
25+
MaterialsContextMixinBuilder,
26+
MaterialsSetContextMixin,
27+
MethodDataContextMixin,
28+
JobContextMixin,
29+
WorkflowContextMixin,
30+
31+
};

src/context/mixins.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import CryptoJS from "crypto-js";
2+
3+
import { compareEntitiesInOrderedSetForSorting } from "../entity/set/ordered/utils";
4+
5+
export const ApplicationContextMixinBuilder = (applicationCls) => (superclass) => class extends superclass {
6+
constructor(config) {
7+
super(config);
8+
if (!applicationCls) throw Error("ApplicationContextMixinBuilder: applicationCls is undefined");
9+
this._application = config.context && config.context.application || applicationCls.createDefault();
10+
}
11+
12+
get application() {
13+
return this._application;
14+
}
15+
};
16+
17+
export const MaterialContextMixinBuilder = (materialCls) => (superclass) => class extends superclass {
18+
19+
constructor(config) {
20+
super(config);
21+
if (!materialCls) throw Error("MaterialContextMixinBuilder: materialCls is undefined");
22+
this._material = config.context && config.context.material;
23+
if (!this._material) this._material = materialCls.createDefault();
24+
this.updateMaterialHash();
25+
}
26+
27+
get isEditedIsSetToFalseOnMaterialUpdate() {
28+
return false;
29+
}
30+
31+
updateMaterialHash() {
32+
if (this.isEditedIsSetToFalseOnMaterialUpdate) this.isEdited = false;
33+
this.extraData = {materialHash: this.material.hash};
34+
}
35+
36+
// Workaround: Material.createDefault() used to initiate workflow reducer and hence here too
37+
// does not have an id. Here we catch when such material is used and avoid resetting isEdited
38+
get isMaterialCreatedDefault() {
39+
return !Boolean(this.material.id);
40+
}
41+
42+
get isMaterialUpdated() {
43+
return Boolean(this.extraData && (this.extraData.materialHash !== this.material.hash));
44+
}
45+
46+
get material() {
47+
return this._material;
48+
}
49+
};
50+
51+
export const MaterialsSetContextMixin = (superclass) => class extends superclass {
52+
53+
constructor(config) {
54+
super(config);
55+
this._materialsSet = this.config.context && this.config.context.materialsSet;
56+
}
57+
58+
get materialsSet() {return this._materialsSet}
59+
60+
sortMaterialsByIndexInSet(materials = []) {
61+
// DO NOT SORT IN PLACE AS IT CHANGES THE ORDER IN `this.materials` AND HAS SIDE EFFECTS (MaterialViewer).
62+
return materials.concat().sort((a, b) => compareEntitiesInOrderedSetForSorting(a, b, this.materialsSet._id, false));
63+
}
64+
65+
};
66+
67+
export const MaterialsContextMixinBuilder = (materialCls) => (superclass) => class extends superclass {
68+
69+
constructor(config) {
70+
super(config);
71+
const materials = this.config.context && this.config.context.materials;
72+
if (!materialCls) throw Error("MaterialsContextMixinBuilder: materialCls is undefined");
73+
this._materials = (materials && materials.length) ? materials : [materialCls.createDefault()];
74+
}
75+
76+
get materials() {return this._materials}
77+
};
78+
79+
export const MethodDataContextMixin = (superclass) => class extends superclass {
80+
81+
constructor(config) {
82+
super(config);
83+
this._methodData = config.context && config.context.methodData || {};
84+
this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent)
85+
}
86+
87+
/* @summary Replace the logic in constructor with this in order to enable passing `methodDataHash` between
88+
* subsequent initializations of the derived class. Not used at present and kept for the record.
89+
*/
90+
_initMethodDataHash() {
91+
this.methodDataHash = CryptoJS.MD5(JSON.stringify(this.methodData)).toString();
92+
this.extraData = {methodDataHash: this.methodDataHash};
93+
if (!this._methodData) {
94+
this._methodData = {};
95+
this.isEdited = false;
96+
// Commented out to reduce effect on performance. Uncomment for debugging purposes.
97+
// TODO: remove on next refactoring or convert to log
98+
// console.warn("MethodDataContextMixin: methodData is undefined or null");
99+
} else {
100+
if (this.isMethodDataUpdated) {
101+
this.isEdited = false;
102+
} else {
103+
this.isEdited = config.isEdited;
104+
}
105+
}
106+
}
107+
108+
get methodData() {return this._methodData}
109+
110+
get isMethodDataUpdated() {
111+
return Boolean(this.extraData && (this.extraData.methodDataHash !== this.methodDataHash));
112+
}
113+
114+
};
115+
116+
export const WorkflowContextMixin = (superclass) => class extends superclass {
117+
118+
constructor(config) {
119+
super(config);
120+
this._workflow = config.context && config.context.workflow || {};
121+
this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent)
122+
}
123+
124+
get workflow() {return this._workflow}
125+
126+
};
127+
128+
export const JobContextMixin = (superclass) => class extends superclass {
129+
130+
constructor(config) {
131+
super(config);
132+
this._job = config.context && config.context.job || {};
133+
this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent)
134+
}
135+
136+
get job() {return this._job}
137+
138+
};

src/context/pickers.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import _ from "underscore";
2+
3+
export const WorkflowContextPickKeysForMixin = (workflow) => {
4+
return {
5+
workflow: _.pick(workflow, [
6+
"hasRelaxation"
7+
])
8+
};
9+
};
10+
11+
export const JobContextPickKeysForMixin = (job) => {
12+
return {
13+
job: _.pick(job, [
14+
"parentJob"
15+
])
16+
};
17+
};

0 commit comments

Comments
 (0)