@mat3ra/made 2024.3.22-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.
Files changed (176) hide show
  1. package/.babelrc +10 -0
  2. package/.eslintrc.json +11 -0
  3. package/.mocharc.json +5 -0
  4. package/.prettierignore +1 -0
  5. package/.prettierrc +6 -0
  6. package/LICENSE.md +15 -0
  7. package/README.md +167 -0
  8. package/dist/abstract/array_with_ids.d.ts +43 -0
  9. package/dist/abstract/array_with_ids.js +88 -0
  10. package/dist/abstract/scalar_with_id.d.ts +25 -0
  11. package/dist/abstract/scalar_with_id.js +44 -0
  12. package/dist/basis/basis.d.ts +269 -0
  13. package/dist/basis/basis.js +499 -0
  14. package/dist/basis/constrained_basis.d.ts +56 -0
  15. package/dist/basis/constrained_basis.js +90 -0
  16. package/dist/basis/types.d.ts +1 -0
  17. package/dist/basis/types.js +2 -0
  18. package/dist/cell/cell.d.ts +45 -0
  19. package/dist/cell/cell.js +88 -0
  20. package/dist/cell/conventional_cell.d.ts +22 -0
  21. package/dist/cell/conventional_cell.js +83 -0
  22. package/dist/cell/primitive_cell.d.ts +9 -0
  23. package/dist/cell/primitive_cell.js +166 -0
  24. package/dist/constants.d.ts +2 -0
  25. package/dist/constants.js +25 -0
  26. package/dist/constraints/constraints.d.ts +45 -0
  27. package/dist/constraints/constraints.js +49 -0
  28. package/dist/lattice/lattice.d.ts +104 -0
  29. package/dist/lattice/lattice.js +208 -0
  30. package/dist/lattice/lattice_bravais.d.ts +59 -0
  31. package/dist/lattice/lattice_bravais.js +120 -0
  32. package/dist/lattice/lattice_vectors.d.ts +46 -0
  33. package/dist/lattice/lattice_vectors.js +98 -0
  34. package/dist/lattice/reciprocal/lattice_reciprocal.d.ts +75 -0
  35. package/dist/lattice/reciprocal/lattice_reciprocal.js +148 -0
  36. package/dist/lattice/reciprocal/paths.d.ts +24 -0
  37. package/dist/lattice/reciprocal/paths.js +136 -0
  38. package/dist/lattice/reciprocal/symmetry_points.d.ts +8 -0
  39. package/dist/lattice/reciprocal/symmetry_points.js +866 -0
  40. package/dist/lattice/types.d.ts +49 -0
  41. package/dist/lattice/types.js +127 -0
  42. package/dist/lattice/unit_cell.d.ts +30 -0
  43. package/dist/lattice/unit_cell.js +31 -0
  44. package/dist/made.d.ts +40 -0
  45. package/dist/made.js +39 -0
  46. package/dist/material.d.ts +1562 -0
  47. package/dist/material.js +317 -0
  48. package/dist/math.d.ts +395 -0
  49. package/dist/math.js +7 -0
  50. package/dist/parsers/cif.d.ts +10 -0
  51. package/dist/parsers/cif.js +21 -0
  52. package/dist/parsers/errors.d.ts +5 -0
  53. package/dist/parsers/errors.js +11 -0
  54. package/dist/parsers/espresso.d.ts +10 -0
  55. package/dist/parsers/espresso.js +24 -0
  56. package/dist/parsers/native_format_parsers.d.ts +26 -0
  57. package/dist/parsers/native_format_parsers.js +52 -0
  58. package/dist/parsers/parsers.d.ts +13 -0
  59. package/dist/parsers/parsers.js +17 -0
  60. package/dist/parsers/poscar.d.ts +31 -0
  61. package/dist/parsers/poscar.js +180 -0
  62. package/dist/parsers/xyz.d.ts +62 -0
  63. package/dist/parsers/xyz.js +167 -0
  64. package/dist/parsers/xyz_combinatorial_basis.d.ts +64 -0
  65. package/dist/parsers/xyz_combinatorial_basis.js +241 -0
  66. package/dist/tools/basis.d.ts +22 -0
  67. package/dist/tools/basis.js +100 -0
  68. package/dist/tools/cell.d.ts +9 -0
  69. package/dist/tools/cell.js +39 -0
  70. package/dist/tools/index.d.ts +11 -0
  71. package/dist/tools/index.js +15 -0
  72. package/dist/tools/material.d.ts +25 -0
  73. package/dist/tools/material.js +54 -0
  74. package/dist/tools/supercell.d.ts +22 -0
  75. package/dist/tools/supercell.js +62 -0
  76. package/dist/tools/surface.d.ts +10 -0
  77. package/dist/tools/surface.js +147 -0
  78. package/dist/types.d.ts +3 -0
  79. package/dist/types.js +2 -0
  80. package/package.json +89 -0
  81. package/pyproject.toml +77 -0
  82. package/src/js/abstract/array_with_ids.ts +100 -0
  83. package/src/js/abstract/scalar_with_id.ts +53 -0
  84. package/src/js/basis/basis.ts +607 -0
  85. package/src/js/basis/constrained_basis.ts +107 -0
  86. package/src/js/basis/types.ts +1 -0
  87. package/src/js/cell/cell.ts +109 -0
  88. package/src/js/cell/conventional_cell.ts +89 -0
  89. package/src/js/cell/primitive_cell.ts +189 -0
  90. package/src/js/constants.js +4 -0
  91. package/src/js/constraints/constraints.ts +63 -0
  92. package/src/js/lattice/lattice.ts +229 -0
  93. package/src/js/lattice/lattice_bravais.ts +170 -0
  94. package/src/js/lattice/lattice_vectors.ts +126 -0
  95. package/src/js/lattice/reciprocal/lattice_reciprocal.js +155 -0
  96. package/src/js/lattice/reciprocal/paths.js +134 -0
  97. package/src/js/lattice/reciprocal/symmetry_points.ts +886 -0
  98. package/src/js/lattice/types.ts +142 -0
  99. package/src/js/lattice/unit_cell.ts +66 -0
  100. package/src/js/made.js +36 -0
  101. package/src/js/material.ts +398 -0
  102. package/src/js/math.js +6 -0
  103. package/src/js/parsers/cif.js +22 -0
  104. package/src/js/parsers/errors.js +7 -0
  105. package/src/js/parsers/espresso.ts +30 -0
  106. package/src/js/parsers/native_format_parsers.js +51 -0
  107. package/src/js/parsers/parsers.js +13 -0
  108. package/src/js/parsers/poscar.ts +201 -0
  109. package/src/js/parsers/xyz.ts +216 -0
  110. package/src/js/parsers/xyz_combinatorial_basis.js +243 -0
  111. package/src/js/tools/basis.js +116 -0
  112. package/src/js/tools/cell.js +36 -0
  113. package/src/js/tools/index.js +11 -0
  114. package/src/js/tools/material.js +60 -0
  115. package/src/js/tools/supercell.ts +80 -0
  116. package/src/js/tools/surface.js +176 -0
  117. package/src/js/types.ts +4 -0
  118. package/src/py/__init__.py +0 -0
  119. package/src/py/mat3ra/__init__.py +0 -0
  120. package/src/py/mat3ra/made/__init__.py +5 -0
  121. package/tests/.gitattributes +1 -0
  122. package/tests/fixtures/AsGe-basis.json +3 -0
  123. package/tests/fixtures/C2H4-translated.json +3 -0
  124. package/tests/fixtures/C2H4.json +3 -0
  125. package/tests/fixtures/FeLiSi-basis.json +3 -0
  126. package/tests/fixtures/FeO.json +3 -0
  127. package/tests/fixtures/Ge2-basis.json +3 -0
  128. package/tests/fixtures/Graphene.json +3 -0
  129. package/tests/fixtures/Graphene.poscar +3 -0
  130. package/tests/fixtures/H2+H-final.json +3 -0
  131. package/tests/fixtures/H2+H-image.json +3 -0
  132. package/tests/fixtures/H2+H-initial.json +3 -0
  133. package/tests/fixtures/H2O.poscar +3 -0
  134. package/tests/fixtures/LiFeSi-basis.json +3 -0
  135. package/tests/fixtures/Na.json +3 -0
  136. package/tests/fixtures/Na4Cl4-cartesian.json +3 -0
  137. package/tests/fixtures/Na4Cl4.json +3 -0
  138. package/tests/fixtures/Na4Cl4.poscar +3 -0
  139. package/tests/fixtures/Ni-hex.json +3 -0
  140. package/tests/fixtures/Ni-hex.poscar +3 -0
  141. package/tests/fixtures/OSi-basis.json +3 -0
  142. package/tests/fixtures/Si-hex.json +3 -0
  143. package/tests/fixtures/Si-hex.poscar +3 -0
  144. package/tests/fixtures/Si-pwscf.in +3 -0
  145. package/tests/fixtures/Si-slab.json +3 -0
  146. package/tests/fixtures/Si-supercell.json +3 -0
  147. package/tests/fixtures/Si.json +3 -0
  148. package/tests/fixtures/Si2-basis-repeated.json +3 -0
  149. package/tests/fixtures/Si2-basis.json +3 -0
  150. package/tests/fixtures/Zr1H23Zr1H1.json +3 -0
  151. package/tests/fixtures/Zr1H23Zr1H1.poscar +3 -0
  152. package/tests/fixtures/atomic-constraints.json +3 -0
  153. package/tests/js/basis/basis.js +221 -0
  154. package/tests/js/cell/cell.js +21 -0
  155. package/tests/js/cell/primitive_cell.js +17 -0
  156. package/tests/js/constraints/constraints.js +27 -0
  157. package/tests/js/enums.js +40 -0
  158. package/tests/js/lattice/lattice.js +31 -0
  159. package/tests/js/lattice/lattice_bravais.js +17 -0
  160. package/tests/js/lattice/lattice_reciprocal.js +99 -0
  161. package/tests/js/lattice/lattice_vectors.js +10 -0
  162. package/tests/js/material.test.js +11 -0
  163. package/tests/js/parsers/espresso.js +12 -0
  164. package/tests/js/parsers/native_formats.js +30 -0
  165. package/tests/js/parsers/poscar.js +21 -0
  166. package/tests/js/parsers/xyz.js +25 -0
  167. package/tests/js/parsers/xyz_combinatorial_basis.js +153 -0
  168. package/tests/js/setup.js +6 -0
  169. package/tests/js/tools/basis.js +18 -0
  170. package/tests/js/tools/supercell.js +23 -0
  171. package/tests/js/tools/surface.js +12 -0
  172. package/tests/js/utils.js +17 -0
  173. package/tests/py/__init__.py +0 -0
  174. package/tests/py/unit/__init__.py +0 -0
  175. package/tests/py/unit/test_sample.py +10 -0
  176. package/tsconfig.json +3 -0
package/.babelrc ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env"
4
+ ],
5
+ "plugins": [
6
+ [
7
+ "@babel/plugin-proposal-class-properties"
8
+ ]
9
+ ]
10
+ }
package/.eslintrc.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": ["@exabyte-io/eslint-config"],
3
+ "ignorePatterns": ["dist/"],
4
+ "settings": {
5
+ "import/resolver": {
6
+ "node": {
7
+ "extensions": [".js", ".jsx", ".ts", ".tsx"]
8
+ }
9
+ }
10
+ }
11
+ }
package/.mocharc.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extension": ["ts", "js"],
3
+ "spec": "tests/**/*.js",
4
+ "require": ["ts-node/register"]
5
+ }
@@ -0,0 +1 @@
1
+ tests/fixtures/*.json
package/.prettierrc ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "singleQuote": false,
3
+ "printWidth": 100,
4
+ "trailingComma": "all",
5
+ "tabWidth": 4
6
+ }
package/LICENSE.md ADDED
@@ -0,0 +1,15 @@
1
+ # LICENSE
2
+
3
+ Copyright 2019 Exabyte Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ [![npm version](https://badge.fury.io/js/%40mat3ra%2Fmade.svg)](https://badge.fury.io/js/%40mat3ra%2Fmade)
2
+ [![License: Apache](https://img.shields.io/badge/License-Apache-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
3
+
4
+ # Made
5
+
6
+ Made is a library for **MA**terials **DE**sign in JavaScript/TypeScript and Python. It allows for the creation and manipulation of material structures from atoms up on the web. The library is aimed to be used for the development of web applications, both on the client (web browser) and server (eg. Node.js) side.
7
+
8
+ The library was originally designed as part of and presently powers materials design capabilities of the [Exabyte.io](https://exabyte.io) platform. For example, [this page](https://platform.exabyte.io/demo/materials/n3HSzCmyoctgJFGGE) representing a crystal of Silicon online uses Made.js.
9
+
10
+ Exabyte.io believe in a collaborative future of materials design on the web.
11
+
12
+ ## Functionality
13
+
14
+ As below:
15
+
16
+ - the package provides a software environment for interacting with Materials-related data structures from ESSE Data Convention [[1]](#links) and is written in ECMAScript 2015 for use on the web
17
+ - High-level classes for the representation of the [Material](src/material.js) and the corresponding structural information, ie:
18
+ - [Basis](src/basis/basis.js),
19
+ - [Lattice](src/lattice/lattice.js),
20
+ - [ReciprocalLattice](src/lattice/reciprocal/lattice_reciprocal.js),
21
+ - [Cell](src/cell/cell.js),
22
+ - [AtomicConstraints](src/constraints/constraints.js)
23
+ - and others to be added.
24
+ - input/output support, including:
25
+ - POSCAR [[3]](#links),
26
+ - XYZ [[4]](#links),
27
+ - Quantum ESPRESSO [[5]](#links),
28
+ - and others to be added.
29
+ - structural generation and analysis tools:
30
+ - [supercell](src/tools/supercell.js)
31
+ - [surfaces](src/tools/surface.js)
32
+ - [combinatorial sets](src/parsers/xyz_combinatorial_basis.js)
33
+ - [interpolated sets for chemical reactions](src/tools/basis.js)
34
+
35
+ The package is written in a modular way easy to extend. Contributions can be in the form of additional tools or modules you develop, or feature requests and [bug/issue reports](https://help.github.com/articles/creating-an-issue/).
36
+
37
+ ## Installation
38
+
39
+ From NPM for use within a software project:
40
+
41
+ ```bash
42
+ npm install @mat3ra/made
43
+
44
+ ```
45
+
46
+ From source to contribute to development:
47
+
48
+ ```bash
49
+ git clone git@github.com:Exabyte-io/made
50
+ ```
51
+
52
+ ## Contribution
53
+
54
+ This repository is an [open-source](LICENSE.md) work-in-progress and we welcome contributions.
55
+
56
+ ### Why contribute?
57
+
58
+ We regularly deploy the latest code containing all accepted contributions online as part of the [Mat3ra.com](https://mat3ra.com) platform, so contributors will see their code in action there.
59
+
60
+ ### Adding new functionality
61
+
62
+ We suggest forking this repository and introducing the adjustments there to be considered for merging into this repository as explained in more details [here](https://gist.github.com/Chaser324/ce0505fbed06b947d962), for example.
63
+
64
+ ### Source code conventions
65
+
66
+ Made.js is written in EcmaScript 6th edition [[2]](#links) with the application of object-oriented design patterns encapsulating key concepts following the conventions below.
67
+
68
+ 1. Classes follow the Exabyte Data Convention and data structures defined in ESSE [[1]](#links)
69
+
70
+ 2. Only materials-related code is considered. Properties related to [simulation model](https://docs.exabyte.io/models/overview/) parameters (eg. type of approximation, numerical parameters) shall go elsewhere.
71
+
72
+ 3. `tools` directory contains helper functions that act on one or more classes and include an external parameter. Functions that use class data without any external parameters should be implemented inside the class. For example, `basis.clone()` is implemented in `Basis`, but basis repetition is implemented as a tool in the correspondingly named function ([tools/basis.js#repeat](src/tools/basis.js)) because the repetion requires a parameter external to basis - number of repetitions in 3 spatial dimensions.
73
+
74
+ 4. `parsers` directory contains the parsers to- and from- ESSE format mentioned in 1. All functionality related to external data conversion is contained in this directory.
75
+
76
+
77
+ ### TODO list
78
+
79
+ Desirable features for implementation:
80
+
81
+ - identify primitive / conventional structures
82
+ - support for molecular geometries
83
+ - support for polymer geometries
84
+ - radial correlation function calculation
85
+ - generation of complex atomic shapes:
86
+ - fullerene
87
+ - nanotube
88
+ - nanowire
89
+ - nano-cluster
90
+ - a combination of the above
91
+ - arbitrary atomic arrangement
92
+
93
+ ## Tests
94
+
95
+ Made tests are written based on Mocha [6](#links) testing framework and can be executed as follows.
96
+
97
+ ```bash
98
+ git pull
99
+ git lfs pull
100
+ ```
101
+ to get the latest test fixtures from LFS, and then:
102
+
103
+ ```bash
104
+ npm install
105
+ npm test
106
+ ```
107
+
108
+ ### Tests Important Notes
109
+
110
+ 1. Keep the tests directory structure similar to the main codebase directory structure. Every JS module in the main codebase should have a corresponding module in tests directory which implements the tests for provided functionality.
111
+
112
+ 2. Add tests fixtures into [fixtures](./tests/fixtures) directory. The fixtures are automatically stored on Git LFS [7](#links).
113
+
114
+ 3. If the fixtures are going to be used inside multiple cases, read and export them inside [enums](./tests/enums.js) to avoid code duplicates.
115
+
116
+ 4. [Tests setup module](./tests/setup.js) can be used to implement the hooks that are used to prepare the tests environment.
117
+
118
+ ## Using Linter
119
+
120
+ Linter setup will prevent committing files that don't adhere to the code standard. It will
121
+ attempt to fix what it can automatically prior to the commit in order to reduce diff noise. This can lead to "unexpected" behavior where a
122
+ file that is staged for commit is not identical to the file that actually gets committed. This happens
123
+ in the `lint-staged` directive of the `package.json` file (by using a `husky` pre-commit hook). For example,
124
+ if you add extra whitespace to a file, stage it, and try to commit it, you will see the following:
125
+
126
+ ```bash
127
+ ➜ made git:(feature/SOF-4398-TB) ✗ git add src/basis/constrained_basis.js
128
+ ➜ made git:(feature/SOF-4398-TB) ✗ git commit -m "Test commit non-linted code"
129
+ ✔ Preparing...
130
+ ✔ Running tasks...
131
+ ✖ Prevented an empty git commit!
132
+ ✔ Reverting to original state because of errors...
133
+ ✔ Cleaning up...
134
+
135
+ ⚠ lint-staged prevented an empty git commit.
136
+ Use the --allow-empty option to continue, or check your task configuration
137
+
138
+ husky - pre-commit hook exited with code 1 (error)
139
+ ```
140
+
141
+ The staged change may remain but will not have been committed. Then it will look like you still have a staged
142
+ change to commit, but the pre-commit hook will not actually commit it for you, quite frustrating! Styling can
143
+ be applied manually and fixed by running:
144
+
145
+ ```bash
146
+ npm run lint:fix
147
+ ```
148
+
149
+ In which case, you may need to then add the linter edits to your staging, which in the example above, puts the
150
+ file back to identical with the base branch, resulting in no staged changes whatsoever.
151
+
152
+ ## Configuring WebStorm for use with Linter
153
+
154
+ In order for the WebStorm IDE to take full advantage of the linting configuration, it can be configured in the project:
155
+
156
+ - `Preferences -> Languages & Frameworks -> JavaScript -> Code Quality Tools -> ESLint`
157
+ - Check `Automatic ESLint configuration` which should infer all the configurations from the project directory
158
+
159
+ ## Links
160
+
161
+ 1. [Exabyte Source of Schemas and Examples (ESSE), Github Repository](https://github.com/exabyte-io/exabyte-esse)
162
+ 2. [ECMAScript 2015 Language Specifications](https://www.ecma-international.org/ecma-262/6.0/)
163
+ 3. [POSCAR file format, official website](https://cms.mpi.univie.ac.at/vasp/guide/node59.html)
164
+ 4. [XYZ file format, Wikipedia](https://en.wikipedia.org/wiki/XYZ_file_format)
165
+ 5. [Quantum ESPRESSO, Official Website](https://www.quantum-espresso.org/)
166
+ 6. [Mocha, Official Website](https://mochajs.org/)
167
+ 7. [Git LFS, Official Website](https://git-lfs.github.com/)
@@ -0,0 +1,43 @@
1
+ import { ObjectWithIdAndValue, ValueOrObject } from "./scalar_with_id";
2
+ type Predicate<T> = (o: T) => boolean;
3
+ type MapFunction<T> = (value: T, index: number, array: T[]) => T;
4
+ export declare function isArrayOfObjectsWithIdAndValue<T>(valueOrObjects: ValueOrObject<T>[]): valueOrObjects is ObjectWithIdAndValue<T>[];
5
+ /**
6
+ * Helper class representing an ArrayWithIds. Used to explicitly track values assigned to atoms, for example.
7
+ */
8
+ export declare class ArrayWithIds<T> {
9
+ array: T[];
10
+ /**
11
+ * Create a an array with ids.
12
+ * @param {Array} array - Either regular array or ArrayWithIds (see @example above)
13
+ */
14
+ constructor(array?: ObjectWithIdAndValue<T>[] | T[]);
15
+ /**
16
+ * Serialize class instance to JSON.
17
+ * @example [{"id" : 0, "value" : "Si" }, {"id" : 1, "value" : "Si" }]
18
+ */
19
+ toJSON(): ObjectWithIdAndValue<T>[];
20
+ /**
21
+ * Apply function fn to each element of the array and replace `array` with the result.
22
+ * @param fn - The function to be applied to each array element.
23
+ */
24
+ mapArrayInPlace(fn: MapFunction<T>): void;
25
+ getArrayElementByIndex(idx: number): T;
26
+ /**
27
+ * Get the index of the array element that passes the predicate.
28
+ * @param {Function} predicate - The function to be applied to each array element.
29
+ */
30
+ getArrayIndexByPredicate(predicate: Predicate<T>): number;
31
+ /**
32
+ * Add an entity to array.
33
+ * @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
34
+ */
35
+ addElement(el: ValueOrObject<T>): void;
36
+ /**
37
+ * Remove an entity to array. Either by passing the entity, or the corresponding index.
38
+ * @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
39
+ * @param idx - The entity to be added to array. If Object with 'value' key, its value will be added.
40
+ */
41
+ removeElement(el: ValueOrObject<T> | null, idx?: number): void;
42
+ }
43
+ export {};
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ArrayWithIds = exports.isArrayOfObjectsWithIdAndValue = void 0;
7
+ const underscore_1 = __importDefault(require("underscore"));
8
+ const scalar_with_id_1 = require("./scalar_with_id");
9
+ function isArrayOfObjectsWithIdAndValue(valueOrObjects) {
10
+ return (0, scalar_with_id_1.isObjectWithIdAndValue)(valueOrObjects[0]);
11
+ }
12
+ exports.isArrayOfObjectsWithIdAndValue = isArrayOfObjectsWithIdAndValue;
13
+ /**
14
+ * Helper class representing an ArrayWithIds. Used to explicitly track values assigned to atoms, for example.
15
+ */
16
+ class ArrayWithIds {
17
+ /**
18
+ * Create a an array with ids.
19
+ * @param {Array} array - Either regular array or ArrayWithIds (see @example above)
20
+ */
21
+ constructor(array = []) {
22
+ if (!underscore_1.default.isArray(array)) {
23
+ throw new Error("ArrayWithIds.constructor: pass array on initialization");
24
+ }
25
+ // if passed an array with ids as config, only store the values in array
26
+ if (isArrayOfObjectsWithIdAndValue(array)) {
27
+ this.array = array.sort((a, b) => a.id - b.id).map((element) => element.value);
28
+ }
29
+ else {
30
+ this.array = [...array];
31
+ }
32
+ }
33
+ /**
34
+ * Serialize class instance to JSON.
35
+ * @example [{"id" : 0, "value" : "Si" }, {"id" : 1, "value" : "Si" }]
36
+ */
37
+ toJSON() {
38
+ // from ["a", "b"] to [{id: 0, value: "a"}, {id: 1, value: "b"}]
39
+ return this.array.map((el, idx) => new scalar_with_id_1.ScalarWithId(el, idx).toJSON());
40
+ }
41
+ /**
42
+ * Apply function fn to each element of the array and replace `array` with the result.
43
+ * @param fn - The function to be applied to each array element.
44
+ */
45
+ mapArrayInPlace(fn) {
46
+ if (!underscore_1.default.isFunction(fn)) {
47
+ throw new Error("ArrayWithIds.mapArray: must pass function as argument");
48
+ }
49
+ this.array = this.array.map(fn);
50
+ }
51
+ getArrayElementByIndex(idx) {
52
+ return this.array[idx];
53
+ }
54
+ /**
55
+ * Get the index of the array element that passes the predicate.
56
+ * @param {Function} predicate - The function to be applied to each array element.
57
+ */
58
+ getArrayIndexByPredicate(predicate) {
59
+ return this.array.findIndex((el) => predicate(el));
60
+ }
61
+ /**
62
+ * Add an entity to array.
63
+ * @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
64
+ */
65
+ addElement(el) {
66
+ const value = (0, scalar_with_id_1.isObjectWithIdAndValue)(el) ? el.value : el;
67
+ if (el)
68
+ this.array.push(value);
69
+ }
70
+ /**
71
+ * Remove an entity to array. Either by passing the entity, or the corresponding index.
72
+ * @param el - The entity to be added to array. If Object with 'value' key, its value will be added.
73
+ * @param idx - The entity to be added to array. If Object with 'value' key, its value will be added.
74
+ */
75
+ removeElement(el, idx) {
76
+ let _idx;
77
+ if (idx === undefined) {
78
+ _idx = this.array.findIndex((elm) => elm === el);
79
+ }
80
+ else {
81
+ _idx = idx;
82
+ }
83
+ if (_idx !== undefined) {
84
+ this.array.splice(_idx, 1);
85
+ }
86
+ }
87
+ }
88
+ exports.ArrayWithIds = ArrayWithIds;
@@ -0,0 +1,25 @@
1
+ export interface ObjectWithIdAndValue<T> {
2
+ id: number;
3
+ value: T;
4
+ }
5
+ export type ValueOrObject<T> = ObjectWithIdAndValue<T> | T;
6
+ export type ValueOrObjectArray<T> = ObjectWithIdAndValue<T>[] | T[];
7
+ export declare function isObjectWithIdAndValue<T>(valueOrObject: ValueOrObject<T>): valueOrObject is ObjectWithIdAndValue<T>;
8
+ /**
9
+ * Helper class representing a scalar with an associated id.
10
+ */
11
+ export declare class ScalarWithId<T> {
12
+ id: number;
13
+ value: T;
14
+ /**
15
+ * Create a an array with ids.
16
+ * @param valueOrObject - a ScalarWithID, or any other type.
17
+ * @param id - numerical id (Integer).
18
+ */
19
+ constructor(valueOrObject: ValueOrObject<T>, id?: number);
20
+ /**
21
+ * Serialize class instance to JSON.
22
+ * @example {"id" : 0, "value" : "Si" }
23
+ */
24
+ toJSON(): ObjectWithIdAndValue<T>;
25
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ScalarWithId = exports.isObjectWithIdAndValue = void 0;
7
+ const underscore_1 = __importDefault(require("underscore"));
8
+ function isObjectWithIdAndValue(valueOrObject) {
9
+ return Boolean(underscore_1.default.isObject(valueOrObject) && !underscore_1.default.isArray(valueOrObject) && valueOrObject.value);
10
+ }
11
+ exports.isObjectWithIdAndValue = isObjectWithIdAndValue;
12
+ /**
13
+ * Helper class representing a scalar with an associated id.
14
+ */
15
+ class ScalarWithId {
16
+ /**
17
+ * Create a an array with ids.
18
+ * @param valueOrObject - a ScalarWithID, or any other type.
19
+ * @param id - numerical id (Integer).
20
+ */
21
+ constructor(valueOrObject, id = 0) {
22
+ // if already passing a ScalarWithId => preserve original
23
+ if (isObjectWithIdAndValue(valueOrObject)) {
24
+ // NOTE - Arrays are Objects too
25
+ this.id = valueOrObject.id;
26
+ this.value = valueOrObject.value;
27
+ }
28
+ else {
29
+ this.id = id;
30
+ this.value = valueOrObject;
31
+ }
32
+ }
33
+ /**
34
+ * Serialize class instance to JSON.
35
+ * @example {"id" : 0, "value" : "Si" }
36
+ */
37
+ toJSON() {
38
+ return {
39
+ id: this.id,
40
+ value: this.value,
41
+ };
42
+ }
43
+ }
44
+ exports.ScalarWithId = ScalarWithId;