Skip to content

Commit 047b604

Browse files
authored
Merge pull request #83 from Exabyte-io/update/SOF-7096
SOF-7096: TS for math module
2 parents 6af6382 + f27f808 commit 047b604

File tree

6 files changed

+77
-68
lines changed

6 files changed

+77
-68
lines changed

package-lock.json

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

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@
5656
"@babel/preset-react": "7.16.7",
5757
"@babel/register": "^7.16.0",
5858
"@babel/runtime-corejs3": "7.16.8",
59-
"@exabyte-io/esse.js": "2023.11.22-1",
59+
"@exabyte-io/esse.js": "2023.12.1-0",
6060
"@types/chai": "^4.3.5",
6161
"@types/crypto-js": "^4.1.1",
6262
"@types/js-yaml": "^4.0.5",
6363
"@types/json-schema": "^7.0.12",
64+
"@types/mathjs": "^3.21.1",
6465
"@types/mocha": "^10.0.1",
6566
"@types/node": "^20.4.2",
6667
"@types/react-jsonschema-form": "^1.7.8",

src/entity/in_memory.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { JSONSchema6 } from "json-schema";
12
import getValue from "lodash/get";
23
import omit from "lodash/omit";
34

@@ -70,7 +71,6 @@ export class InMemoryEntity {
7071

7172
/**
7273
* @summary Array of fields to exclude from resulted JSON
73-
* @param {String[]} exclude
7474
*/
7575
toJSON(exclude: string[] = []) {
7676
return (this.constructor as typeof InMemoryEntity)._isDeepCloneRequired
@@ -88,13 +88,17 @@ export class InMemoryEntity {
8888

8989
/**
9090
* @summary Clone this entity
91-
* @param extraContext {Object}
92-
* @returns {*}
9391
*/
94-
clone(extraContext: object = {}): InMemoryEntity {
95-
const Entity = this.constructor as typeof InMemoryEntity;
92+
clone(extraContext?: object): this {
93+
type ThisType = typeof this;
94+
type ThisConstructor = { new (o: object): ThisType };
95+
96+
const object = new (this.constructor as ThisConstructor)({
97+
...this.toJSON(),
98+
...extraContext,
99+
});
96100

97-
return new Entity({ ...this.toJSON(), ...extraContext });
101+
return object;
98102
}
99103

100104
// override upon inheritance
@@ -216,7 +220,7 @@ export class InMemoryEntity {
216220
/**
217221
* Returns class JSON schema
218222
*/
219-
static get jsonSchema() {
223+
static get jsonSchema(): JSONSchema6 | undefined {
220224
try {
221225
return getSchemaByClassName(this.name);
222226
} catch (e) {

src/math.js renamed to src/math.ts

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,36 @@ import { tolerance as TOLERANCE } from "./constants";
1111
const EPSILON = 1e-8;
1212
/**
1313
* @summary Returns scalar product of vectors
14-
* @param v1 {Number[]} Vector 1
15-
* @param v2 {Number[]} Vector 2
16-
* @return {Number}
14+
* @param v1 Vector 1
15+
* @param v2 Vector 2
1716
*/
18-
19-
const product = (v1, v2) => {
17+
const product = (v1: number[], v2: number[]) => {
2018
return math.multiply(v1, math.transpose(v2));
2119
};
2220

2321
/**
2422
* @summary Returns length of a vector.
25-
* @param v {Number[]} Vector
26-
* @return {Number}
23+
* @param v Vector
2724
*/
28-
const vlen = (v) => {
25+
const vlen = (v: number[]) => {
2926
return math.sqrt(product(v, v));
3027
};
3128

3229
/**
3330
* @summary Returns angle between `a` and `b` vectors.
34-
* @param a {Number[]} Vector a
35-
* @param b {Number[]} Vector b
36-
* @param [unit] {String} `rad`, `deg`
37-
* @return {Number}
31+
* @param a Vector a
32+
* @param b Vector b
33+
* @param unit `rad`, `deg`
3834
*/
39-
const angle = (a, b, unit) => {
35+
const angle = (a:number[], b:number[], unit: string) => {
4036
const lenA = vlen(a);
4137
const lenB = vlen(b);
38+
// @ts-ignore
4239
return math.unit(math.acos(product(a, b) / (lenA * lenB)), "rad").toNumber(unit || "deg");
4340
};
4441

45-
const angleUpTo90 = (...args) => {
46-
const angleUpTo180 = angle(...args);
42+
const angleUpTo90 = (a:number[], b:number[], unit: string) => {
43+
const angleUpTo180 = angle(a,b, unit);
4744
return angleUpTo180 < 90 ? angleUpTo180 : 180 - angleUpTo180;
4845
};
4946

@@ -53,7 +50,7 @@ const angleUpTo90 = (...args) => {
5350
* @param v2 {Number[]} Vector
5451
* @return {Number}
5552
*/
56-
const vDist = (v1, v2) => {
53+
const vDist = (v1:number[], v2:number[]) => {
5754
if (v1.length !== v2.length) {
5855
console.error(
5956
"Attempting to calculate distance between vectors of different dimensionality",
@@ -70,35 +67,36 @@ const vDist = (v1, v2) => {
7067
* @param tolerance {Number} Tolerance
7168
* @return {Number}
7269
*/
73-
const vEqualWithTolerance = (vec1, vec2, tolerance = TOLERANCE.pointsDistance) =>
74-
vDist(vec1, vec2) <= tolerance;
70+
const vEqualWithTolerance = (vec1:number[], vec2:number[], tolerance = TOLERANCE.pointsDistance): boolean => {
71+
const val = vDist(vec1, vec2);
72+
if (typeof val === "undefined") {
73+
return false;
74+
}
75+
// @ts-ignore
76+
return val <= tolerance;
77+
}
78+
7579

7680
/**
7781
* @summary Returns 0 if passed number is less than Made.math.EPSILON.
7882
* @param n {Number}
7983
* @return {Number}
8084
*/
81-
const roundToZero = (n) => {
85+
const roundToZero = (n: number) => {
8286
return Math.abs(n) < EPSILON ? 0 : n;
8387
};
8488

8589
/**
8690
* @summary Returns number with specified precision.
87-
* @param x {Number}
88-
* @param n {Number}
89-
* @return {Number}
9091
*/
91-
const precise = (x, n = 7) => {
92+
const precise = (x: number, n = 7) => {
9293
return Number(x.toPrecision(n));
9394
};
9495

9596
/**
9697
* @summary Returns mod of the passed value with the specified tolerance.
97-
* @param num {Number}
98-
* @param tolerance {Number}
99-
* @return {Number}
10098
*/
101-
const mod = (num, tolerance = 0.001) => {
99+
const mod = (num: number, tolerance = 0.001): number => {
102100
const m = num % 1;
103101
const x = num >= 0 ? m : 1 + m;
104102

@@ -112,11 +110,11 @@ const mod = (num, tolerance = 0.001) => {
112110
* @summary Returns cartesian of passed arrays.
113111
* @example combinations([1,2], [4,5], [6]) = [[1,4,6], [1,5,6], [2,4,6], [2,5,6]];
114112
*/
115-
const cartesianProduct = (...arg) => {
116-
const r = [];
113+
const cartesianProduct = (...arg: number[][]):number[][] => {
114+
const r: number[][] = [];
117115
const max = arg.length - 1;
118116

119-
const helper = (arr, i) => {
117+
const helper = (arr: number[], i: number) => {
120118
for (let j = 0, l = arg[i].length; j < l; j++) {
121119
const a = arr.slice(0); // clone arr
122120
a.push(arg[i][j]);
@@ -134,20 +132,16 @@ const cartesianProduct = (...arg) => {
134132

135133
/**
136134
* @summary Returns all possible positive integer combinations where each value changes from 0 to a, b, c.
137-
* @param a {Number}
138-
* @param b {Number}
139-
* @param tolerance {Number}
140135
*/
141-
const almostEqual = (a, b, tolerance = TOLERANCE.pointsDistance) => {
136+
const almostEqual = (a: number, b: number, tolerance = TOLERANCE.pointsDistance): boolean => {
142137
return Math.abs(a - b) < tolerance;
143138
};
144139

145140
/**
146141
* @summary Returns true if number is 0 <= x < 1, inclusive, otherwise false.
147142
* Helper to deal with JS arithmetic artifacts.
148-
* @number number {Number}
149143
*/
150-
const isBetweenZeroInclusiveAndOne = (number, tolerance = TOLERANCE.length) => {
144+
const isBetweenZeroInclusiveAndOne = (number: number, tolerance = TOLERANCE.length): boolean => {
151145
return roundToZero(number) >= 0 && !almostEqual(number, 1, tolerance) && number < 1;
152146
};
153147

@@ -160,7 +154,7 @@ const isBetweenZeroInclusiveAndOne = (number, tolerance = TOLERANCE.length) => {
160154
* @param b
161155
* @param c
162156
*/
163-
const combinations = (a, b, c) => {
157+
const combinations = (a: number, b: number, c: number) => {
164158
const combs = [];
165159
for (let i = 0; i <= a; i++) {
166160
for (let j = 0; j <= b; j++) {
@@ -175,7 +169,7 @@ const combinations = (a, b, c) => {
175169
/*
176170
* @summary Same as `combinations` but accepting intervals (tuples) of integers: eg. [-3, 4]
177171
*/
178-
const combinationsFromIntervals = (arrA, arrB, arrC) => {
172+
const combinationsFromIntervals = (arrA: number[], arrB:number[], arrC: number[]) => {
179173
const combs = [];
180174
for (let i = arrA[0]; i <= arrA[1]; i++) {
181175
for (let j = arrB[0]; j <= arrB[1]; j++) {
@@ -187,21 +181,18 @@ const combinationsFromIntervals = (arrA, arrB, arrC) => {
187181
return combs;
188182
};
189183

190-
const roundValueToNDecimals = (value, decimals = 3) => {
184+
const roundValueToNDecimals = (value: number, decimals = 3) => {
191185
return parseFloat(value.toFixed(decimals));
192186
};
193187

194188
/**
195189
* @summary Returns n splits of the passed segment.
196-
* @param point1 {Number[]}
197-
* @param point2 {Number[]}
198-
* @param n {Number}
199190
*/
200-
const calculateSegmentsBetweenPoints3D = (point1, point2, n) => {
191+
const calculateSegmentsBetweenPoints3D = (point1: (string | number)[], point2:(string | number)[], n: number | string) => {
201192
// safely parse if passed strings
202-
const point1_ = point1.map((x) => parseFloat(x));
203-
const point2_ = point2.map((x) => parseFloat(x));
204-
const n_ = parseInt(n);
193+
const point1_ = point1.map((x) => typeof x === "string" ? parseFloat(x) : x);
194+
const point2_ = point2.map((x) => typeof x === "string" ? parseFloat(x) : x);
195+
const n_ = typeof n === "string" ? parseInt(n) : n;
205196

206197
const result = [];
207198
for (let i = 1; i < n_; i++) {
@@ -223,10 +214,10 @@ const calculateSegmentsBetweenPoints3D = (point1, point2, n) => {
223214
* @locus Client
224215
* @method
225216
* @name toPrecision
226-
* @param {Number} number
227-
* @param {Number} precision Optional. An integer specifying the number of significant digits.
217+
* @param number
218+
* @param precision Optional. An integer specifying the number of significant digits.
228219
*/
229-
export function numberToPrecision(number, precision) {
220+
export function numberToPrecision(number: number | string, precision?: number): string {
230221
if (_.isNumber(number)) {
231222
return number.toPrecision(precision);
232223
}

src/utils/object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export function renameKeysForObject(
9292
return result;
9393
}
9494

95-
interface NameValueObject {
95+
export interface NameValueObject {
9696
name: string;
9797
value: unknown;
9898
[key: string]: unknown;

src/utils/schemas.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { JSONSchema } from "@exabyte-io/esse.js/schema";
2+
import { JSONSchema7Definition } from "json-schema";
23
import forEach from "lodash/forEach";
34
import hasProperty from "lodash/has";
45
import isEmpty from "lodash/isEmpty";
56

6-
import { JSONSchema7Definition } from "json-schema";
7-
87
import { JSONSchemasInterface } from "../JSONSchemasInterface";
98

109
export * from "@exabyte-io/esse.js/lib/js/esse/schemaUtils";
@@ -37,7 +36,7 @@ interface Node {
3736
* @returns
3837
*/
3938
export function getSchemaByClassName(className: string) {
40-
return schemas[className] ? JSONSchemasInterface.schemaById(schemas[className]) : null;
39+
return schemas[className] ? JSONSchemasInterface.schemaById(schemas[className]) : undefined;
4140
}
4241

4342
/**
@@ -245,7 +244,6 @@ const buildNamedEntitiesDependencies = (entities: NamedEntity[]) => {
245244
schemaByNamedEntityName(entity.name) ||
246245
defaultNamedEntitySchema(entity.name);
247246
return {
248-
249247
...filterForGenerativeProperties(schema),
250248
};
251249
}),

0 commit comments

Comments
 (0)