@bgord/tools 0.14.3 → 0.15.1
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.
- package/dist/age.vo.d.ts +10 -6
- package/dist/age.vo.js +22 -14
- package/dist/api-key.vo.d.ts +3 -0
- package/dist/api-key.vo.js +7 -1
- package/dist/clock-format.service.d.ts +9 -0
- package/dist/clock-format.service.js +10 -0
- package/dist/clock.vo.d.ts +7 -14
- package/dist/clock.vo.js +25 -34
- package/dist/height.vo.d.ts +7 -7
- package/dist/height.vo.js +6 -6
- package/dist/hour-format.service.d.ts +10 -0
- package/dist/hour-format.service.js +19 -0
- package/dist/hour.vo.d.ts +8 -17
- package/dist/hour.vo.js +22 -39
- package/dist/iban-mask.service.js +6 -3
- package/dist/iban.vo.d.ts +6 -4
- package/dist/iban.vo.js +7 -5
- package/dist/image.vo.d.ts +8 -2
- package/dist/image.vo.js +14 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/language.vo.d.ts +4 -1
- package/dist/language.vo.js +5 -3
- package/dist/mean.service.d.ts +4 -2
- package/dist/mean.service.js +9 -5
- package/dist/min-max-scaler.service.d.ts +22 -14
- package/dist/min-max-scaler.service.js +16 -15
- package/dist/minute.vo.d.ts +5 -6
- package/dist/minute.vo.js +14 -14
- package/dist/money.vo.d.ts +13 -2
- package/dist/money.vo.js +18 -13
- package/dist/outlier-detector.service.d.ts +2 -1
- package/dist/outlier-detector.service.js +5 -3
- package/dist/percentage.service.d.ts +3 -2
- package/dist/percentage.service.js +3 -2
- package/dist/population-standard-deviation.service.d.ts +3 -2
- package/dist/population-standard-deviation.service.js +5 -4
- package/dist/random.service.d.ts +6 -0
- package/dist/random.service.js +12 -6
- package/dist/rounding.adapter.d.ts +16 -0
- package/dist/{rounding.service.js → rounding.adapter.js} +8 -7
- package/dist/rounding.port.d.ts +3 -0
- package/dist/rounding.port.js +1 -0
- package/dist/simple-linear-regression.service.d.ts +11 -4
- package/dist/simple-linear-regression.service.js +39 -30
- package/dist/size.vo.js +1 -1
- package/dist/stopwatch.service.d.ts +1 -1
- package/dist/stopwatch.service.js +3 -4
- package/dist/sum.service.d.ts +2 -1
- package/dist/sum.service.js +11 -0
- package/dist/time.service.js +1 -1
- package/dist/timestamp.vo.d.ts +3 -0
- package/dist/timestamp.vo.js +7 -1
- package/dist/timezone.vo.d.ts +3 -0
- package/dist/timezone.vo.js +4 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/visually-unambiguous-characters-generator.service.js +0 -1
- package/dist/weight.vo.d.ts +4 -4
- package/dist/weight.vo.js +1 -1
- package/dist/z-score.service.d.ts +3 -2
- package/dist/z-score.service.js +3 -2
- package/package.json +2 -2
- package/readme.md +4 -2
- package/src/age.vo.ts +24 -14
- package/src/api-key.vo.ts +9 -1
- package/src/clock-format.service.ts +15 -0
- package/src/clock.vo.ts +24 -43
- package/src/height.vo.ts +12 -11
- package/src/hour-format.service.ts +21 -0
- package/src/hour.vo.ts +24 -47
- package/src/iban-mask.service.ts +8 -3
- package/src/iban.vo.ts +10 -8
- package/src/image.vo.ts +19 -4
- package/src/index.ts +2 -2
- package/src/language.vo.ts +7 -3
- package/src/mean.service.ts +13 -5
- package/src/min-max-scaler.service.ts +39 -24
- package/src/minute.vo.ts +18 -15
- package/src/money.vo.ts +26 -23
- package/src/outlier-detector.service.ts +6 -4
- package/src/percentage.service.ts +6 -7
- package/src/population-standard-deviation.service.ts +8 -5
- package/src/random.service.ts +16 -8
- package/src/relative-date.vo.ts +0 -1
- package/src/rounding.adapter.ts +33 -0
- package/src/rounding.port.ts +3 -0
- package/src/simple-linear-regression.service.ts +41 -31
- package/src/size.vo.ts +1 -1
- package/src/stopwatch.service.ts +4 -6
- package/src/sum.service.ts +15 -1
- package/src/time.service.ts +1 -1
- package/src/timestamp.vo.ts +9 -1
- package/src/timezone.vo.ts +15 -15
- package/src/visually-unambiguous-characters-generator.service.ts +0 -1
- package/src/weight.vo.ts +5 -4
- package/src/z-score.service.ts +6 -3
- package/dist/dates-of-the-week.vo.d.ts +0 -9
- package/dist/dates-of-the-week.vo.js +0 -10
- package/dist/rounding.service.d.ts +0 -17
- package/src/dates-of-the-week.vo.ts +0 -9
- package/src/rounding.service.ts +0 -31
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RoundingPort } from "./rounding.port";
|
|
2
2
|
type MinMaxScalerValueType = number;
|
|
3
3
|
type MinMaxScalerConfigType = {
|
|
4
4
|
min: MinMaxScalerValueType;
|
|
@@ -7,27 +7,35 @@ type MinMaxScalerConfigType = {
|
|
|
7
7
|
lower: MinMaxScalerValueType;
|
|
8
8
|
upper: MinMaxScalerValueType;
|
|
9
9
|
};
|
|
10
|
-
rounding?:
|
|
10
|
+
rounding?: RoundingPort;
|
|
11
|
+
};
|
|
12
|
+
export declare const MinMaxInvalidMinMaxError: "minmax.invalid.minmax";
|
|
13
|
+
export declare const MinMaxInvalidBoundError: "minmax.invalid.bound";
|
|
14
|
+
export declare const MinMaxValueOutOfRangeError: "minmax.value.out.of.range";
|
|
15
|
+
export declare const MinMaxScaledOutOfBoundsError: "minmax.scaled.out.of.bounds";
|
|
16
|
+
export declare const MinMaxEmptyArrayError: "minmax.empty.array";
|
|
17
|
+
type ScaleResult = {
|
|
18
|
+
original: MinMaxScalerValueType;
|
|
19
|
+
scaled: MinMaxScalerValueType;
|
|
20
|
+
isMin: boolean;
|
|
21
|
+
isMax: boolean;
|
|
22
|
+
};
|
|
23
|
+
type DescaleResult = {
|
|
24
|
+
original: MinMaxScalerValueType;
|
|
25
|
+
scaled: MinMaxScalerValueType;
|
|
26
|
+
isLowerBound: boolean;
|
|
27
|
+
isUpperBound: boolean;
|
|
11
28
|
};
|
|
12
29
|
export declare class MinMaxScaler {
|
|
30
|
+
private static readonly DEFAULT_ROUNDING;
|
|
13
31
|
private readonly min;
|
|
14
32
|
private readonly max;
|
|
15
33
|
private readonly lower;
|
|
16
34
|
private readonly upper;
|
|
17
35
|
private readonly rounding;
|
|
18
36
|
constructor(config: MinMaxScalerConfigType);
|
|
19
|
-
scale(value: MinMaxScalerValueType):
|
|
20
|
-
|
|
21
|
-
scaled: number;
|
|
22
|
-
isMin: boolean;
|
|
23
|
-
isMax: boolean;
|
|
24
|
-
};
|
|
25
|
-
descale(scaled: MinMaxScalerValueType): {
|
|
26
|
-
original: number;
|
|
27
|
-
scaled: number;
|
|
28
|
-
isLowerBound: boolean;
|
|
29
|
-
isUpperBound: boolean;
|
|
30
|
-
};
|
|
37
|
+
scale(value: MinMaxScalerValueType): ScaleResult;
|
|
38
|
+
descale(scaled: MinMaxScalerValueType): DescaleResult;
|
|
31
39
|
static getMinMax(values: MinMaxScalerValueType[]): {
|
|
32
40
|
min: number;
|
|
33
41
|
max: number;
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import { RoundToDecimal } from "./rounding.
|
|
1
|
+
import { RoundToDecimal } from "./rounding.adapter";
|
|
2
|
+
export const MinMaxInvalidMinMaxError = "minmax.invalid.minmax";
|
|
3
|
+
export const MinMaxInvalidBoundError = "minmax.invalid.bound";
|
|
4
|
+
export const MinMaxValueOutOfRangeError = "minmax.value.out.of.range";
|
|
5
|
+
export const MinMaxScaledOutOfBoundsError = "minmax.scaled.out.of.bounds";
|
|
6
|
+
export const MinMaxEmptyArrayError = "minmax.empty.array";
|
|
2
7
|
export class MinMaxScaler {
|
|
8
|
+
static DEFAULT_ROUNDING = new RoundToDecimal(2);
|
|
3
9
|
min;
|
|
4
10
|
max;
|
|
5
11
|
lower;
|
|
6
12
|
upper;
|
|
7
13
|
rounding;
|
|
8
14
|
constructor(config) {
|
|
9
|
-
const rounding = config.rounding ?? new RoundToDecimal(2);
|
|
10
15
|
const lower = config.bound?.lower ?? 0;
|
|
11
16
|
const upper = config.bound?.upper ?? 1;
|
|
12
17
|
if (config.max - config.min < 0)
|
|
13
|
-
throw new Error(
|
|
18
|
+
throw new Error(MinMaxInvalidMinMaxError);
|
|
14
19
|
if (upper - lower <= 0)
|
|
15
|
-
throw new Error(
|
|
16
|
-
this.rounding = rounding;
|
|
20
|
+
throw new Error(MinMaxInvalidBoundError);
|
|
21
|
+
this.rounding = config.rounding ?? MinMaxScaler.DEFAULT_ROUNDING;
|
|
17
22
|
this.min = config.min;
|
|
18
23
|
this.max = config.max;
|
|
19
24
|
this.lower = lower;
|
|
@@ -22,14 +27,10 @@ export class MinMaxScaler {
|
|
|
22
27
|
scale(value) {
|
|
23
28
|
const { min, max, lower, upper } = this;
|
|
24
29
|
if (value < min || value > max)
|
|
25
|
-
throw new Error(
|
|
26
|
-
if (min === max)
|
|
27
|
-
return {
|
|
28
|
-
|
|
29
|
-
scaled: (lower + upper) / 2,
|
|
30
|
-
isMin: value === min,
|
|
31
|
-
isMax: value === max,
|
|
32
|
-
};
|
|
30
|
+
throw new Error(MinMaxValueOutOfRangeError);
|
|
31
|
+
if (min === max) {
|
|
32
|
+
return { original: value, scaled: (lower + upper) / 2, isMin: value === min, isMax: value === max };
|
|
33
|
+
}
|
|
33
34
|
const result = ((value - min) / (max - min)) * (upper - lower) + lower;
|
|
34
35
|
return {
|
|
35
36
|
original: value,
|
|
@@ -41,7 +42,7 @@ export class MinMaxScaler {
|
|
|
41
42
|
descale(scaled) {
|
|
42
43
|
const { min, max, lower, upper } = this;
|
|
43
44
|
if (scaled < lower || scaled > upper)
|
|
44
|
-
throw new Error(
|
|
45
|
+
throw new Error(MinMaxScaledOutOfBoundsError);
|
|
45
46
|
const result = ((scaled - lower) / (upper - lower)) * (max - min) + min;
|
|
46
47
|
return {
|
|
47
48
|
original: this.rounding.round(result),
|
|
@@ -52,7 +53,7 @@ export class MinMaxScaler {
|
|
|
52
53
|
}
|
|
53
54
|
static getMinMax(values) {
|
|
54
55
|
if (values.length === 0)
|
|
55
|
-
throw new Error(
|
|
56
|
+
throw new Error(MinMaxEmptyArrayError);
|
|
56
57
|
return { min: Math.min(...values), max: Math.max(...values) };
|
|
57
58
|
}
|
|
58
59
|
}
|
package/dist/minute.vo.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { TimestampType } from "./timestamp.vo";
|
|
2
|
+
export declare const MinuteValueError: "invalid.minute";
|
|
2
3
|
export declare class Minute {
|
|
3
4
|
private readonly value;
|
|
4
5
|
static readonly ZERO: Minute;
|
|
5
6
|
static readonly MAX: Minute;
|
|
6
7
|
constructor(candidate: number);
|
|
7
|
-
static
|
|
8
|
-
get():
|
|
9
|
-
|
|
10
|
-
formatted: string;
|
|
11
|
-
};
|
|
8
|
+
static fromEpochMs(timestamp: TimestampType): Minute;
|
|
9
|
+
get(): number;
|
|
10
|
+
toString(): string;
|
|
12
11
|
equals(another: Minute): boolean;
|
|
13
12
|
isAfter(another: Minute): boolean;
|
|
14
13
|
isBefore(another: Minute): boolean;
|
|
15
|
-
static list(): Minute[];
|
|
14
|
+
static list(): readonly Minute[];
|
|
16
15
|
}
|
package/dist/minute.vo.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
+
export const MinuteValueError = "invalid.minute";
|
|
1
2
|
export class Minute {
|
|
2
3
|
value;
|
|
3
4
|
static ZERO = new Minute(0);
|
|
4
5
|
static MAX = new Minute(59);
|
|
5
6
|
constructor(candidate) {
|
|
6
|
-
if (!Number.isInteger(candidate))
|
|
7
|
-
throw new Error(
|
|
8
|
-
|
|
9
|
-
throw new Error("Invalid minute");
|
|
10
|
-
if (candidate >= 60)
|
|
11
|
-
throw new Error("Invalid minute");
|
|
7
|
+
if (!Number.isInteger(candidate) || candidate < 0 || candidate >= 60) {
|
|
8
|
+
throw new Error(MinuteValueError);
|
|
9
|
+
}
|
|
12
10
|
this.value = candidate;
|
|
13
11
|
}
|
|
14
|
-
static
|
|
15
|
-
|
|
16
|
-
return new Minute(minutes);
|
|
12
|
+
static fromEpochMs(timestamp) {
|
|
13
|
+
return new Minute(new Date(timestamp).getUTCMinutes());
|
|
17
14
|
}
|
|
18
15
|
get() {
|
|
19
|
-
return
|
|
16
|
+
return this.value;
|
|
17
|
+
}
|
|
18
|
+
toString() {
|
|
19
|
+
return this.value.toString().padStart(2, "0");
|
|
20
20
|
}
|
|
21
21
|
equals(another) {
|
|
22
|
-
return this.value === another.
|
|
22
|
+
return this.value === another.value;
|
|
23
23
|
}
|
|
24
24
|
isAfter(another) {
|
|
25
|
-
return this.value > another.
|
|
25
|
+
return this.value > another.value;
|
|
26
26
|
}
|
|
27
27
|
isBefore(another) {
|
|
28
|
-
return this.value < another.
|
|
28
|
+
return this.value < another.value;
|
|
29
29
|
}
|
|
30
30
|
static list() {
|
|
31
|
-
return Array.from({ length: 60 }
|
|
31
|
+
return Array.from({ length: 60 }, (_, index) => new Minute(index));
|
|
32
32
|
}
|
|
33
33
|
}
|
package/dist/money.vo.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
|
-
import {
|
|
2
|
+
import type { RoundingPort } from "./rounding.port";
|
|
3
|
+
export declare const MoneyAmountInvalidError: {
|
|
4
|
+
readonly error: "money.amount.invalid";
|
|
5
|
+
};
|
|
6
|
+
export declare const MoneyMultiplicationFactorInvalidError: {
|
|
7
|
+
readonly error: "money.multiplication-factor.invalid";
|
|
8
|
+
};
|
|
9
|
+
export declare const MoneyDivisionFactorInvalidError: {
|
|
10
|
+
readonly error: "money.division-factor.invalid";
|
|
11
|
+
};
|
|
12
|
+
export declare const MoneySubtractLessThanZeroError: "money.subtract.less.than.zero";
|
|
3
13
|
export declare const MoneyAmount: z.core.$ZodBranded<z.ZodNumber, "MoneyAmount">;
|
|
4
14
|
export type MoneyAmountType = z.infer<typeof MoneyAmount>;
|
|
5
15
|
export declare const MoneyMultiplicationFactor: z.core.$ZodBranded<z.ZodNumber, "MoneyMultiplicationFactor">;
|
|
@@ -8,9 +18,10 @@ export declare const MoneyDivisionFactor: z.core.$ZodBranded<z.ZodNumber, "Money
|
|
|
8
18
|
export type MoneyDivisionFactorType = z.infer<typeof MoneyDivisionFactor>;
|
|
9
19
|
export declare class Money {
|
|
10
20
|
private static readonly ZERO;
|
|
21
|
+
private static readonly DEFAULT_ROUNDING;
|
|
11
22
|
private readonly amount;
|
|
12
23
|
private readonly rounding;
|
|
13
|
-
constructor(value?: number, rounding?:
|
|
24
|
+
constructor(value?: number, rounding?: RoundingPort);
|
|
14
25
|
getAmount(): MoneyAmountType;
|
|
15
26
|
add(money: Money): Money;
|
|
16
27
|
multiply(factor: MoneyMultiplicationFactorType): Money;
|
package/dist/money.vo.js
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
|
-
import { RoundToNearest } from "./rounding.
|
|
2
|
+
import { RoundToNearest } from "./rounding.adapter";
|
|
3
|
+
export const MoneyAmountInvalidError = { error: "money.amount.invalid" };
|
|
4
|
+
export const MoneyMultiplicationFactorInvalidError = {
|
|
5
|
+
error: "money.multiplication-factor.invalid",
|
|
6
|
+
};
|
|
7
|
+
export const MoneyDivisionFactorInvalidError = { error: "money.division-factor.invalid" };
|
|
8
|
+
export const MoneySubtractLessThanZeroError = "money.subtract.less.than.zero";
|
|
3
9
|
export const MoneyAmount = z
|
|
4
|
-
.number()
|
|
5
|
-
.int(
|
|
6
|
-
.min(0,
|
|
10
|
+
.number(MoneyAmountInvalidError)
|
|
11
|
+
.int(MoneyAmountInvalidError)
|
|
12
|
+
.min(0, MoneyAmountInvalidError)
|
|
7
13
|
.brand("MoneyAmount");
|
|
8
14
|
export const MoneyMultiplicationFactor = z
|
|
9
|
-
.number()
|
|
10
|
-
.min(0,
|
|
15
|
+
.number(MoneyMultiplicationFactorInvalidError)
|
|
16
|
+
.min(0, MoneyMultiplicationFactorInvalidError)
|
|
11
17
|
.brand("MoneyMultiplicationFactor");
|
|
12
18
|
export const MoneyDivisionFactor = z
|
|
13
|
-
.number()
|
|
14
|
-
.
|
|
15
|
-
.refine((value) => value !== 0, { message: "money.division-factor.invalid" })
|
|
19
|
+
.number(MoneyDivisionFactorInvalidError)
|
|
20
|
+
.gt(0, MoneyDivisionFactorInvalidError)
|
|
16
21
|
.brand("MoneyDivisionFactor");
|
|
17
22
|
export class Money {
|
|
18
23
|
static ZERO = 0;
|
|
24
|
+
static DEFAULT_ROUNDING = new RoundToNearest();
|
|
19
25
|
amount;
|
|
20
26
|
rounding;
|
|
21
27
|
constructor(value = Money.ZERO, rounding) {
|
|
22
28
|
this.amount = MoneyAmount.parse(value);
|
|
23
|
-
this.rounding = rounding ??
|
|
29
|
+
this.rounding = rounding ?? Money.DEFAULT_ROUNDING;
|
|
24
30
|
}
|
|
25
31
|
getAmount() {
|
|
26
32
|
return this.amount;
|
|
@@ -36,7 +42,7 @@ export class Money {
|
|
|
36
42
|
subtract(money) {
|
|
37
43
|
const result = this.rounding.round(this.amount - money.getAmount());
|
|
38
44
|
if (result < Money.ZERO)
|
|
39
|
-
throw new Error(
|
|
45
|
+
throw new Error(MoneySubtractLessThanZeroError);
|
|
40
46
|
return new Money(MoneyAmount.parse(result), this.rounding);
|
|
41
47
|
}
|
|
42
48
|
divide(factor) {
|
|
@@ -56,8 +62,7 @@ export class Money {
|
|
|
56
62
|
return this.amount === Money.ZERO;
|
|
57
63
|
}
|
|
58
64
|
format() {
|
|
59
|
-
const
|
|
60
|
-
const whole = Math.floor(result);
|
|
65
|
+
const whole = Math.floor(this.amount / 100);
|
|
61
66
|
const fraction = this.amount % 100;
|
|
62
67
|
const fractionFormatted = fraction.toString().padStart(2, "0");
|
|
63
68
|
return `${whole}.${fractionFormatted}`;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export declare const OutlierDetectorMinValuesError: "outlier.detector.min.values";
|
|
1
2
|
export declare class OutlierDetector {
|
|
2
3
|
private readonly zScore;
|
|
3
4
|
private readonly threshold;
|
|
4
5
|
constructor(values: number[], threshold: number);
|
|
5
|
-
|
|
6
|
+
isInlier(value: number): boolean;
|
|
6
7
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { ZScore } from "./z-score.service";
|
|
2
|
+
export const OutlierDetectorMinValuesError = "outlier.detector.min.values";
|
|
2
3
|
export class OutlierDetector {
|
|
3
4
|
zScore;
|
|
4
5
|
threshold;
|
|
5
6
|
constructor(values, threshold) {
|
|
6
7
|
if (values.length < 2)
|
|
7
|
-
throw new Error(
|
|
8
|
+
throw new Error(OutlierDetectorMinValuesError);
|
|
8
9
|
this.zScore = new ZScore(values);
|
|
9
10
|
this.threshold = Math.abs(threshold);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
isInlier(value) {
|
|
13
|
+
const score = this.zScore.calculate(value);
|
|
14
|
+
return Math.abs(score) <= this.threshold;
|
|
13
15
|
}
|
|
14
16
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RoundingPort } from "./rounding.port";
|
|
2
|
+
export declare const PercentageInvalidDenominatorError: "percentage.invalid.denominator";
|
|
2
3
|
export declare class Percentage {
|
|
3
|
-
static of(numerator: number, denominator: number, rounding?:
|
|
4
|
+
static of(numerator: number, denominator: number, rounding?: RoundingPort): number;
|
|
4
5
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { RoundToNearest } from "./rounding.
|
|
1
|
+
import { RoundToNearest } from "./rounding.adapter";
|
|
2
|
+
export const PercentageInvalidDenominatorError = "percentage.invalid.denominator";
|
|
2
3
|
export class Percentage {
|
|
3
4
|
static of(numerator, denominator, rounding = new RoundToNearest()) {
|
|
4
5
|
if (denominator === 0)
|
|
5
|
-
throw new Error(
|
|
6
|
+
throw new Error(PercentageInvalidDenominatorError);
|
|
6
7
|
if (numerator === 0)
|
|
7
8
|
return 0;
|
|
8
9
|
return rounding.round((numerator / denominator) * 100);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RoundingPort } from "./rounding.port";
|
|
2
|
+
export declare const PopulationStandardDeviationMinValuesError: "population.standard.deviation.min.values";
|
|
2
3
|
export declare class PopulationStandardDeviation {
|
|
3
|
-
static calculate(values: number[], rounding?:
|
|
4
|
+
static calculate(values: number[], rounding?: RoundingPort): number;
|
|
4
5
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Mean } from "./mean.service";
|
|
2
|
-
import { RoundToDecimal } from "./rounding.
|
|
2
|
+
import { RoundToDecimal } from "./rounding.adapter";
|
|
3
3
|
import { Sum } from "./sum.service";
|
|
4
|
+
export const PopulationStandardDeviationMinValuesError = "population.standard.deviation.min.values";
|
|
4
5
|
export class PopulationStandardDeviation {
|
|
5
6
|
static calculate(values, rounding = new RoundToDecimal(2)) {
|
|
6
7
|
if (values.length < 2)
|
|
7
|
-
throw new Error(
|
|
8
|
+
throw new Error(PopulationStandardDeviationMinValuesError);
|
|
8
9
|
const mean = Mean.calculate(values);
|
|
9
|
-
const
|
|
10
|
+
const count = values.length;
|
|
10
11
|
const squaredDifferences = values.map((value) => (value - mean) ** 2);
|
|
11
12
|
const sumOfSquaredDifferences = Sum.of(squaredDifferences);
|
|
12
|
-
const variance = sumOfSquaredDifferences /
|
|
13
|
+
const variance = sumOfSquaredDifferences / count;
|
|
13
14
|
return rounding.round(Math.sqrt(variance));
|
|
14
15
|
}
|
|
15
16
|
}
|
package/dist/random.service.d.ts
CHANGED
|
@@ -2,7 +2,13 @@ type RandomGenerateConfigType = {
|
|
|
2
2
|
min: number;
|
|
3
3
|
max: number;
|
|
4
4
|
};
|
|
5
|
+
export declare const RandomMinNotIntegerError: "random.min.not.integer";
|
|
6
|
+
export declare const RandomMaxNotIntegerError: "random.max.not.integer";
|
|
7
|
+
export declare const RandomMinEqualsMaxError: "random.min.equals.max";
|
|
8
|
+
export declare const RandomMinGreaterThanMaxError: "random.min.greater.than.max";
|
|
5
9
|
export declare class Random {
|
|
10
|
+
private static readonly DEFAULT_MIN;
|
|
11
|
+
private static readonly DEFAULT_MAX;
|
|
6
12
|
static generate(config?: RandomGenerateConfigType): number;
|
|
7
13
|
}
|
|
8
14
|
export {};
|
package/dist/random.service.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
export const RandomMinNotIntegerError = "random.min.not.integer";
|
|
2
|
+
export const RandomMaxNotIntegerError = "random.max.not.integer";
|
|
3
|
+
export const RandomMinEqualsMaxError = "random.min.equals.max";
|
|
4
|
+
export const RandomMinGreaterThanMaxError = "random.min.greater.than.max";
|
|
1
5
|
export class Random {
|
|
6
|
+
static DEFAULT_MIN = 0;
|
|
7
|
+
static DEFAULT_MAX = 1;
|
|
2
8
|
static generate(config) {
|
|
3
|
-
const min = config
|
|
4
|
-
const max = config
|
|
9
|
+
const min = config ? config.min : Random.DEFAULT_MIN;
|
|
10
|
+
const max = config ? config.max : Random.DEFAULT_MAX;
|
|
5
11
|
if (!Number.isInteger(min))
|
|
6
|
-
throw new Error(
|
|
12
|
+
throw new Error(RandomMinNotIntegerError);
|
|
7
13
|
if (!Number.isInteger(max))
|
|
8
|
-
throw new Error(
|
|
14
|
+
throw new Error(RandomMaxNotIntegerError);
|
|
9
15
|
if (min === max)
|
|
10
|
-
throw new Error(
|
|
16
|
+
throw new Error(RandomMinEqualsMaxError);
|
|
11
17
|
if (min > max)
|
|
12
|
-
throw new Error(
|
|
18
|
+
throw new Error(RandomMinGreaterThanMaxError);
|
|
13
19
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
14
20
|
}
|
|
15
21
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RoundingPort } from "./rounding.port";
|
|
2
|
+
export declare class RoundToNearest implements RoundingPort {
|
|
3
|
+
round(value: number): number;
|
|
4
|
+
}
|
|
5
|
+
export declare class RoundUp implements RoundingPort {
|
|
6
|
+
round(value: number): number;
|
|
7
|
+
}
|
|
8
|
+
export declare class RoundDown implements RoundingPort {
|
|
9
|
+
round(value: number): number;
|
|
10
|
+
}
|
|
11
|
+
export declare const RoundingDecimalsError: "invalid.rounding.decimals";
|
|
12
|
+
export declare class RoundToDecimal implements RoundingPort {
|
|
13
|
+
private readonly decimals;
|
|
14
|
+
constructor(decimals: number);
|
|
15
|
+
round(value: number): number;
|
|
16
|
+
}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
export class
|
|
2
|
-
}
|
|
3
|
-
export class RoundToNearest extends RoundingStrategy {
|
|
1
|
+
export class RoundToNearest {
|
|
4
2
|
round(value) {
|
|
5
3
|
return Math.round(value);
|
|
6
4
|
}
|
|
7
5
|
}
|
|
8
|
-
export class RoundUp
|
|
6
|
+
export class RoundUp {
|
|
9
7
|
round(value) {
|
|
10
8
|
return Math.ceil(value);
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
|
-
export class RoundDown
|
|
11
|
+
export class RoundDown {
|
|
14
12
|
round(value) {
|
|
15
13
|
return Math.floor(value);
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
|
-
export
|
|
16
|
+
export const RoundingDecimalsError = "invalid.rounding.decimals";
|
|
17
|
+
export class RoundToDecimal {
|
|
19
18
|
decimals;
|
|
20
19
|
constructor(decimals) {
|
|
21
|
-
super();
|
|
22
20
|
this.decimals = decimals;
|
|
21
|
+
if (!Number.isInteger(decimals) || decimals < 0 || decimals > 100) {
|
|
22
|
+
throw new Error(RoundingDecimalsError);
|
|
23
|
+
}
|
|
23
24
|
}
|
|
24
25
|
round(value) {
|
|
25
26
|
return Number.parseFloat(value.toFixed(this.decimals));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RoundingPort } from "./rounding.port";
|
|
2
2
|
export type SLRPairType = {
|
|
3
3
|
x: number;
|
|
4
4
|
y: number;
|
|
@@ -8,11 +8,18 @@ export type SLRParamsType = {
|
|
|
8
8
|
b: number;
|
|
9
9
|
};
|
|
10
10
|
export type SLRPredictionType = number;
|
|
11
|
+
export declare const SLRMinPairsError: "slr.min.pairs";
|
|
12
|
+
export declare const SLRSumXTooBigError: "slr.sum.x.too.big";
|
|
13
|
+
export declare const SLRSumYTooBigError: "slr.sum.y.too.big";
|
|
14
|
+
export declare const SLRSumXSquaredTooBigError: "slr.sum.x.squared.too.big";
|
|
15
|
+
export declare const SLRSumXTimesYTooBigError: "slr.sum.x.times.y.too.big";
|
|
16
|
+
export declare const SLRModelCreationError: "slr.model.creation";
|
|
11
17
|
export declare class SimpleLinearRegression {
|
|
18
|
+
private static readonly DEFAULT_ROUNDING;
|
|
12
19
|
private readonly params;
|
|
13
20
|
private readonly rounding;
|
|
14
|
-
constructor(params: SLRParamsType, rounding?:
|
|
15
|
-
static fromPairs(pairs: SLRPairType[], rounding?:
|
|
16
|
-
predict(x: SLRPairType["x"],
|
|
21
|
+
constructor(params: SLRParamsType, rounding?: RoundingPort);
|
|
22
|
+
static fromPairs(pairs: SLRPairType[], rounding?: RoundingPort): SimpleLinearRegression;
|
|
23
|
+
predict(x: SLRPairType["x"], rounding?: RoundingPort): SLRPredictionType;
|
|
17
24
|
inspect(): SimpleLinearRegression["params"];
|
|
18
25
|
}
|
|
@@ -1,43 +1,52 @@
|
|
|
1
|
-
import { RoundToNearest } from "./rounding.
|
|
2
|
-
|
|
1
|
+
import { RoundToNearest } from "./rounding.adapter";
|
|
2
|
+
export const SLRMinPairsError = "slr.min.pairs";
|
|
3
|
+
export const SLRSumXTooBigError = "slr.sum.x.too.big";
|
|
4
|
+
export const SLRSumYTooBigError = "slr.sum.y.too.big";
|
|
5
|
+
export const SLRSumXSquaredTooBigError = "slr.sum.x.squared.too.big";
|
|
6
|
+
export const SLRSumXTimesYTooBigError = "slr.sum.x.times.y.too.big";
|
|
7
|
+
export const SLRModelCreationError = "slr.model.creation";
|
|
3
8
|
export class SimpleLinearRegression {
|
|
9
|
+
static DEFAULT_ROUNDING = new RoundToNearest();
|
|
4
10
|
params;
|
|
5
|
-
rounding
|
|
11
|
+
rounding;
|
|
6
12
|
constructor(params, rounding) {
|
|
7
13
|
this.params = params;
|
|
8
|
-
this.rounding = rounding ??
|
|
14
|
+
this.rounding = rounding ?? SimpleLinearRegression.DEFAULT_ROUNDING;
|
|
9
15
|
}
|
|
10
16
|
static fromPairs(pairs, rounding) {
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
throw new Error(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
throw new Error(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
const count = pairs.length;
|
|
18
|
+
if (count < 2)
|
|
19
|
+
throw new Error(SLRMinPairsError);
|
|
20
|
+
let sumX = 0;
|
|
21
|
+
let sumY = 0;
|
|
22
|
+
let sumXX = 0;
|
|
23
|
+
let sumXY = 0;
|
|
24
|
+
for (let index = 0; index < count; index++) {
|
|
25
|
+
const pair = pairs[index];
|
|
26
|
+
sumX += pair.x;
|
|
27
|
+
sumY += pair.y;
|
|
28
|
+
sumXX += pair.x * pair.x;
|
|
29
|
+
sumXY += pair.x * pair.y;
|
|
30
|
+
}
|
|
31
|
+
if (Math.abs(sumX) >= Number.MAX_SAFE_INTEGER)
|
|
32
|
+
throw new Error(SLRSumXTooBigError);
|
|
33
|
+
if (Math.abs(sumY) >= Number.MAX_SAFE_INTEGER)
|
|
34
|
+
throw new Error(SLRSumYTooBigError);
|
|
35
|
+
if (Math.abs(sumXY) >= Number.MAX_SAFE_INTEGER)
|
|
36
|
+
throw new Error(SLRSumXTimesYTooBigError);
|
|
37
|
+
if (Math.abs(sumXX) >= Number.MAX_SAFE_INTEGER)
|
|
38
|
+
throw new Error(SLRSumXSquaredTooBigError);
|
|
39
|
+
const bDenominator = sumXX - sumX ** 2 / count;
|
|
31
40
|
if (bDenominator === 0)
|
|
32
|
-
throw new Error(
|
|
33
|
-
const b = (
|
|
34
|
-
const a = (
|
|
41
|
+
throw new Error(SLRModelCreationError);
|
|
42
|
+
const b = (sumXY - (sumX * sumY) / count) / bDenominator;
|
|
43
|
+
const a = (sumY - b * sumX) / count;
|
|
35
44
|
return new SimpleLinearRegression({ a, b }, rounding);
|
|
36
45
|
}
|
|
37
|
-
predict(x,
|
|
38
|
-
const
|
|
46
|
+
predict(x, rounding) {
|
|
47
|
+
const chosen = rounding ?? this.rounding;
|
|
39
48
|
const prediction = this.params.b * x + this.params.a;
|
|
40
|
-
return
|
|
49
|
+
return chosen.round(prediction);
|
|
41
50
|
}
|
|
42
51
|
inspect() {
|
|
43
52
|
return this.params;
|
package/dist/size.vo.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type TimestampType } from "./timestamp.vo";
|
|
2
|
+
export declare const StopwatchStateError: "stopwatch.already.stopped";
|
|
2
3
|
export type StopwatchResultType = {
|
|
3
4
|
durationMs: TimestampType;
|
|
4
5
|
};
|
|
5
6
|
export declare class Stopwatch {
|
|
6
7
|
private readonly startMs;
|
|
7
8
|
private state;
|
|
8
|
-
private stopMs;
|
|
9
9
|
constructor(startMs: TimestampType);
|
|
10
10
|
stop(): StopwatchResultType;
|
|
11
11
|
}
|
|
@@ -4,18 +4,17 @@ var StopwatchState;
|
|
|
4
4
|
StopwatchState["started"] = "started";
|
|
5
5
|
StopwatchState["stopped"] = "stopped";
|
|
6
6
|
})(StopwatchState || (StopwatchState = {}));
|
|
7
|
+
export const StopwatchStateError = "stopwatch.already.stopped";
|
|
7
8
|
export class Stopwatch {
|
|
8
9
|
startMs;
|
|
9
10
|
state = StopwatchState.started;
|
|
10
|
-
stopMs;
|
|
11
11
|
constructor(startMs) {
|
|
12
12
|
this.startMs = startMs;
|
|
13
13
|
}
|
|
14
14
|
stop() {
|
|
15
15
|
if (this.state === StopwatchState.stopped)
|
|
16
|
-
throw new Error(
|
|
16
|
+
throw new Error(StopwatchStateError);
|
|
17
17
|
this.state = StopwatchState.stopped;
|
|
18
|
-
|
|
19
|
-
return { durationMs: Timestamp.parse(this.stopMs - this.startMs) };
|
|
18
|
+
return { durationMs: Timestamp.parse(Date.now() - this.startMs) };
|
|
20
19
|
}
|
|
21
20
|
}
|
package/dist/sum.service.d.ts
CHANGED