@arabig/origin 1.0.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.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # @arabig Origin
2
+
3
+ This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
8
+
9
+ ```bash
10
+ ng generate component component-name
11
+ ```
12
+
13
+ For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
14
+
15
+ ```bash
16
+ ng generate --help
17
+ ```
18
+
19
+ ## Building
20
+
21
+ To build the library, run:
22
+
23
+ ```bash
24
+ ng build origin
25
+ ```
26
+
27
+ This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
28
+
29
+ ### Publishing the Library
30
+
31
+ Once the project is built, you can publish your library by following these steps:
32
+
33
+ 1. Navigate to the `dist` directory:
34
+ ```bash
35
+ cd dist/origin
36
+ ```
37
+
38
+ 2. Run the `npm publish` command to publish your library to the npm registry:
39
+ ```bash
40
+ npm publish
41
+ ```
42
+
43
+ ## Running unit tests
44
+
45
+ To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
46
+
47
+ ```bash
48
+ ng test
49
+ ```
50
+
51
+ ## Running end-to-end tests
52
+
53
+ For end-to-end (e2e) testing, run:
54
+
55
+ ```bash
56
+ ng e2e
57
+ ```
58
+
59
+ Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
60
+
61
+ ## Additional Resources
62
+
63
+ For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @license
3
+ * Copyright Salar Arab All Rights Reserved.
4
+ *
5
+ * @author Salar Arab <salar_arab@outlook.com>
6
+ */
7
+ /**
8
+ * Converts the given value to a number based on given options.
9
+ * @param value The convertible input value.
10
+ * @param options The options object that handles different cases of numeric conversion.
11
+ * @returns The resulting number of the conversion
12
+ *
13
+ * @example
14
+ * doToNumber("563.68", {
15
+ * infinityAlt: 0,
16
+ * NaNAlt: 0
17
+ * });
18
+ */
19
+ function aoToNumber(value, options) {
20
+ const _options = {
21
+ NaNAlt: options?.NaNAlt ?? 0,
22
+ infinityAlt: options?.infinityAlt ?? 0,
23
+ };
24
+ const _value = Number(value);
25
+ if (Number.isNaN(_value)) {
26
+ return _options.NaNAlt;
27
+ }
28
+ else if (!Number.isFinite(_value)) {
29
+ return _options.infinityAlt;
30
+ }
31
+ else {
32
+ return _value;
33
+ }
34
+ }
35
+ /**
36
+ * Extracts the decimal part of the given value and returns it as raw string.
37
+ * @param value The input value whose decimal part is demanded.
38
+ * @returns The extracted decimal part as numeric string or empty string if no decimal part is found.
39
+ */
40
+ function aoExtractDecimal(value) {
41
+ function extract(param) {
42
+ return param.split(".")[1]?.replace(/0+$/, "") || "";
43
+ }
44
+ switch (typeof value) {
45
+ case "string":
46
+ const _value = Number(value);
47
+ if (Number.isNaN(_value) ||
48
+ Number.isInteger(_value)) {
49
+ return "";
50
+ }
51
+ else {
52
+ return extract(value) || "";
53
+ }
54
+ case "number":
55
+ if (Number.isNaN(value) ||
56
+ Number.isInteger(value) ||
57
+ !Number.isFinite(value)) {
58
+ return "";
59
+ }
60
+ else {
61
+ return extract(value.toString());
62
+ }
63
+ default:
64
+ return "";
65
+ }
66
+ }
67
+ /**
68
+ * Extracts the integer part of the given value and returns it as numeric string.
69
+ * @param value The input value whose integer part is demanded.
70
+ * @returns The extracted integer part as numeric string or empty string if no integer part is found.
71
+ */
72
+ function aoExtractInteger(value) {
73
+ function extract(param) {
74
+ return param.split(".")[0]?.replace(/\.+$/, "") || "";
75
+ }
76
+ switch (typeof value) {
77
+ case "string":
78
+ const _value = Number(value);
79
+ if (Number.isNaN(_value)) {
80
+ return "";
81
+ }
82
+ else {
83
+ return extract(value);
84
+ }
85
+ case "number":
86
+ if (Number.isNaN(value) ||
87
+ !Number.isFinite(value)) {
88
+ return "";
89
+ }
90
+ else {
91
+ return extract(value.toString());
92
+ }
93
+ case "bigint":
94
+ return extract(value.toString());
95
+ default:
96
+ return "";
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @license
102
+ * Copyright Salar Arab All Rights Reserved.
103
+ *
104
+ * @author Salar Arab <salar_arab@outlook.com>
105
+ */
106
+ /**
107
+ * Filters the given target object entries based on given condition.
108
+ * @typeParam `T` The type of the target object to be filtered
109
+ * @param target The `object` to be filtered
110
+ * @param predicate The callback that iterates within target entries.
111
+ * Provides the key and value in form of {@link DoEntryUnion} as parameter and must
112
+ * return a boolean type determines whether the current key should be remained in the
113
+ * resulting entries or not
114
+ * @returns The filtered `object`.
115
+ * @remarks
116
+ * Since the structure of the returning `object` is formed during the runtime, the
117
+ * type inference at the compile time is not possible, so an unbound `object` is considered
118
+ * as the return type.
119
+ */
120
+ function aoFilterObject(target, predicate) {
121
+ const result = {};
122
+ for (const key in target) {
123
+ if (!Object.hasOwn(target, key))
124
+ continue;
125
+ if (predicate({ key: key, value: target[key] })) {
126
+ result[key] = target[key];
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+
132
+ /**
133
+ * Generated bundle index. Do not edit.
134
+ */
135
+
136
+ export { aoExtractDecimal, aoExtractInteger, aoFilterObject, aoToNumber };
137
+ //# sourceMappingURL=arabig-origin-functions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arabig-origin-functions.mjs","sources":["../../../projects/origin/functions/number.function.ts","../../../projects/origin/functions/object.function.ts","../../../projects/origin/functions/arabig-origin-functions.ts"],"sourcesContent":["/**\r\n * @license\r\n * Copyright Salar Arab All Rights Reserved.\r\n * \r\n * @author Salar Arab <salar_arab@outlook.com>\r\n */\r\n\r\n/**\r\n * Converts the given value to a number based on given options.\r\n * @param value The convertible input value.\r\n * @param options The options object that handles different cases of numeric conversion.\r\n * @returns The resulting number of the conversion\r\n * \r\n * @example\r\n * doToNumber(\"563.68\", {\r\n * infinityAlt: 0,\r\n * NaNAlt: 0\r\n * });\r\n */\r\nexport function aoToNumber(\r\n value?: unknown,\r\n options?: {\r\n /**\r\n * Determines the alternative value, if the conversion results in {@link NaN}.\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN | NaN}\r\n * \r\n * @default 0\r\n */\r\n NaNAlt?: number,\r\n\r\n /**\r\n * Determines the alternative value, if the conversion leads to {@link Infinity}.\r\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity | Infinity}\r\n * \r\n * @default 0\r\n */\r\n infinityAlt?: number,\r\n },\r\n): number {\r\n const _options = {\r\n NaNAlt: options?.NaNAlt ?? 0,\r\n infinityAlt: options?.infinityAlt ?? 0,\r\n };\r\n const _value = Number(value);\r\n\r\n if (Number.isNaN(_value)) {\r\n return _options.NaNAlt;\r\n }\r\n else if (!Number.isFinite(_value)) {\r\n return _options.infinityAlt;\r\n }\r\n else {\r\n return _value;\r\n }\r\n}\r\n\r\n/**\r\n * Extracts the decimal part of the given value and returns it as raw string.\r\n * @param value The input value whose decimal part is demanded.\r\n * @returns The extracted decimal part as numeric string or empty string if no decimal part is found.\r\n */\r\nexport function aoExtractDecimal(value: unknown): `${number}` | \"\" {\r\n function extract(param: string): string {\r\n return param.split(\".\")[1]?.replace(/0+$/, \"\") || \"\";\r\n }\r\n\r\n switch (typeof value) {\r\n case \"string\": \r\n const _value = Number(value);\r\n\r\n if (\r\n Number.isNaN(_value) ||\r\n Number.isInteger(_value)\r\n ) {\r\n return \"\";\r\n }\r\n else {\r\n return extract(value) as `${number}` || \"\";\r\n }\r\n case \"number\":\r\n if (\r\n Number.isNaN(value) ||\r\n Number.isInteger(value) ||\r\n !Number.isFinite(value)\r\n ) {\r\n return \"\";\r\n }\r\n else {\r\n return extract(value.toString()) as `${number}`;\r\n }\r\n default:\r\n return \"\";\r\n }\r\n}\r\n\r\n/**\r\n * Extracts the integer part of the given value and returns it as numeric string.\r\n * @param value The input value whose integer part is demanded.\r\n * @returns The extracted integer part as numeric string or empty string if no integer part is found.\r\n */\r\nexport function aoExtractInteger(value: unknown): `${number}` | \"\" {\r\n function extract(param: string): string {\r\n return param.split(\".\")[0]?.replace(/\\.+$/, \"\") || \"\";\r\n }\r\n\r\n switch (typeof value) {\r\n case \"string\": \r\n const _value = Number(value);\r\n\r\n if (Number.isNaN(_value)) {\r\n return \"\";\r\n }\r\n else {\r\n return extract(value) as `${number}`;\r\n }\r\n case \"number\":\r\n if (\r\n Number.isNaN(value) ||\r\n !Number.isFinite(value)\r\n ) {\r\n return \"\";\r\n }\r\n else {\r\n return extract(value.toString()) as `${number}`;\r\n }\r\n case \"bigint\":\r\n return extract(value.toString()) as `${number}`;\r\n default:\r\n return \"\";\r\n }\r\n}","/**\r\n * @license\r\n * Copyright Salar Arab All Rights Reserved.\r\n * \r\n * @author Salar Arab <salar_arab@outlook.com>\r\n */\r\n\r\nimport { AoEntryUnion, AoObject } from \"@arabig/origin/types\";\r\n\r\n/**\r\n * Filters the given target object entries based on given condition.\r\n * @typeParam `T` The type of the target object to be filtered\r\n * @param target The `object` to be filtered\r\n * @param predicate The callback that iterates within target entries.\r\n * Provides the key and value in form of {@link DoEntryUnion} as parameter and must\r\n * return a boolean type determines whether the current key should be remained in the\r\n * resulting entries or not\r\n * @returns The filtered `object`.\r\n * @remarks\r\n * Since the structure of the returning `object` is formed during the runtime, the\r\n * type inference at the compile time is not possible, so an unbound `object` is considered\r\n * as the return type.\r\n */\r\nexport function aoFilterObject<T extends AoObject>(\r\n target: T,\r\n predicate: (entry: AoEntryUnion<T>) => boolean\r\n): AoObject {\r\n const result: AoObject = {};\r\n\r\n for (const key in target) {\r\n if (!Object.hasOwn(target, key)) continue;\r\n\r\n if (predicate({ key: key, value: target[key] })) {\r\n result[key] = target[key];\r\n }\r\n }\r\n\r\n return result;\r\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ import { aoExtractDecimal, aoExtractInteger } from '@arabig/origin/functions';
2
+
3
+ /**
4
+ * @license
5
+ * Copyright Salar Arab All Rights Reserved
6
+ *
7
+ * @author Salar Arab <salar_arab@outlook.com>
8
+ */
9
+ /**
10
+ * Utilizes performing precise arithmetic operations
11
+ * such as addition, subtraction, multiplication, and division in the form of pipeline.
12
+ *
13
+ * This class is designed to handle extremely large or small numeric values
14
+ * without resulting in {@link Infinity} or {@link NaN}, ensuring safe and predictable
15
+ * calculations across a wide range of inputs.
16
+ *
17
+ * All operations are performed using numeric strings to maintain precision,
18
+ * especially for decimal values, avoiding floating-point inaccuracies common
19
+ * in native JavaScript number handling.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const operand = new AoOperand(0.005).add(1.05).add(0.005);
24
+ *
25
+ * console.log(operand.currentValue) //expecting "1.06";
26
+ * ```
27
+ *
28
+ * @remarks
29
+ * This class is ideal for financial, scientific, or any domain where
30
+ * precision and scale are critical. It does not rely on native number
31
+ * arithmetic and instead uses string-based computation to preserve accuracy.
32
+ */
33
+ class AoOperand {
34
+ _initialValue;
35
+ _previousValue;
36
+ _currentValue;
37
+ //declaration
38
+ constructor(param) {
39
+ if (param instanceof AoOperand) {
40
+ this._initialValue = param.toString("initial");
41
+ this._currentValue = param.toString("current");
42
+ this._previousValue = param.toString("previous");
43
+ }
44
+ else {
45
+ this._initialValue = this.refine(param).value;
46
+ this._currentValue = this._initialValue;
47
+ this._previousValue = "0";
48
+ }
49
+ }
50
+ /**
51
+ * Converts and outputs the {@link AoOperand}'s value as number base on given state.
52
+ * @param state The state that determines temporal state of the value. Default is "current"
53
+ * @returns A number
54
+ */
55
+ toNumber(state = "current") {
56
+ return Number(this[`_${state}Value`]);
57
+ }
58
+ /**
59
+ * Converts and outputs the {@link AoOperand}'s value as bigint base on given state.
60
+ * @param state The state that determines temporal state of the value. Default is "current"
61
+ * @returns A bigint
62
+ */
63
+ toBigInt(state = "current") {
64
+ return BigInt(this[`_${state}Value`]);
65
+ }
66
+ /**
67
+ * Converts and outputs the {@link AoOperand}'s value as numeric string base on given state.
68
+ * @param state The state that determines temporal state of the value. Default is "current"
69
+ * @returns A numeric string
70
+ */
71
+ toString(state = "current") {
72
+ return this[`_${state}Value`];
73
+ }
74
+ /**
75
+ * Executes the Executes the {@link https://en.wikipedia.org/wiki/Addition | addition}
76
+ * operation for the given value.
77
+ * @param input The adding operand
78
+ * @returns A new instance of {@link AoOperand} that holds the operation latest result
79
+ */
80
+ add(input) {
81
+ //Step 1: prerequisites refinement
82
+ const inputRefined = this.refine(input);
83
+ const currentRefined = this.refine(this._currentValue);
84
+ const int1 = currentRefined.integer;
85
+ const dec1 = currentRefined.decimal;
86
+ const int2 = inputRefined.integer;
87
+ const dec2 = inputRefined.decimal;
88
+ //Step 2: decimals normalization
89
+ const mantissa = Math.max(dec1.length, dec2.length);
90
+ const dec1Norm = dec1.padEnd(mantissa, "0");
91
+ const dec2Norm = dec2.padEnd(mantissa, "0");
92
+ //Step 3: restraining resulting integer
93
+ const intFinal = this.restrain(() => {
94
+ const intSum = Number(int1) + Number(int2);
95
+ const decSum = Number(dec1Norm) + Number(dec2Norm);
96
+ const spillover = Math.floor(decSum / (mantissa ** 10));
97
+ return intSum + spillover;
98
+ }, () => {
99
+ const intSum = BigInt(int1) + BigInt(int2);
100
+ const decSum = BigInt(dec1Norm) + BigInt(dec2Norm);
101
+ const spillover = decSum / (BigInt(mantissa) ** 10n);
102
+ return intSum + spillover;
103
+ });
104
+ //Step 4: restraining resulting decimal
105
+ const decResult = this.restrain(() => {
106
+ const decSum = Number(dec1Norm) + Number(dec2Norm);
107
+ return decSum % (10 ** mantissa);
108
+ }, () => {
109
+ const decSum = BigInt(dec1Norm) + BigInt(dec2Norm);
110
+ return decSum % (10n ** BigInt(mantissa));
111
+ });
112
+ const decFinal = decResult.padStart(mantissa, "0");
113
+ //Step 5: taking snapshot and returning the new instance with the new value.
114
+ this.assign(this.normalize(intFinal, decFinal));
115
+ return this.clone();
116
+ }
117
+ /**
118
+ * Executes the {@link https://en.wikipedia.org/wiki/Subtraction | subtraction}
119
+ * operation for the given value.
120
+ * @param input The subtracting operand
121
+ * @returns A new instance of {@link AoOperand} that holds the operation latest result
122
+ */
123
+ subtract(input) {
124
+ //Step 1: prerequisites refinement
125
+ const inputRefined = this.refine(input);
126
+ const currentRefined = this.refine(this._currentValue);
127
+ const int1 = currentRefined.integer;
128
+ const dec1 = currentRefined.decimal;
129
+ const int2 = inputRefined.integer;
130
+ const dec2 = inputRefined.decimal;
131
+ //Step 2: decimals normalization
132
+ const mantissa = Math.max(dec1.length, dec2.length);
133
+ const dec1Norm = dec1.padEnd(mantissa, "0");
134
+ const dec2Norm = dec2.padEnd(mantissa, "0");
135
+ //Step 3: restraining resulting integer
136
+ const intFinal = this.restrain(() => {
137
+ const decSub = Number(dec1Norm) - Number(dec2Norm);
138
+ let intSub = Number(int1) - Number(int2);
139
+ return decSub < 0 ? intSub -= 1 : intSub;
140
+ }, () => {
141
+ const decSub = BigInt(dec1Norm) - BigInt(dec2Norm);
142
+ let intSub = BigInt(int1) - BigInt(int2);
143
+ return decSub < 0n ? intSub -= 1n : intSub;
144
+ });
145
+ //Step 4: restraining resulting decimal
146
+ const decResult = this.restrain(() => {
147
+ let sub = Number(dec1Norm) - Number(dec2Norm);
148
+ return sub < 0 ? sub += (Number(mantissa) ** 10) : sub;
149
+ }, () => {
150
+ let sub = BigInt(dec1Norm) - BigInt(dec2Norm);
151
+ return sub < 0n ? sub += (BigInt(mantissa) ** 10n) : sub;
152
+ });
153
+ const decFinal = decResult.padStart(mantissa, "0");
154
+ //Step 5: taking snapshot and returning the new instance with the new value.
155
+ this.assign(this.normalize(intFinal, decFinal));
156
+ return this.clone();
157
+ }
158
+ /**
159
+ * Executes the {@link https://en.wikipedia.org/wiki/Multiplication | multiplication}
160
+ * operation for the given value.
161
+ * @param input The multiplying operand
162
+ * @returns A new instance of {@link AoOperand} that holds the operation latest result
163
+ */
164
+ multiply(input) {
165
+ //Step 1: prerequisites refinement
166
+ const inputRefined = this.refine(input);
167
+ const currentRefined = this.refine(this._currentValue);
168
+ const int1 = currentRefined.integer;
169
+ const dec1 = currentRefined.decimal;
170
+ const int2 = inputRefined.integer;
171
+ const dec2 = inputRefined.decimal;
172
+ const totalDecLen = dec1.length + dec2.length;
173
+ //Step 2: product calculation
174
+ const product = this.restrain(() => Number(int1 + dec1) * Number(int2 + dec2), () => BigInt(int1 + dec1) * BigInt(int2 + dec2)).padStart(totalDecLen + 1, "0");
175
+ //Step 3: slicing numeric parts
176
+ const intFinal = product.slice(0, -totalDecLen);
177
+ const decFinal = product.slice(-totalDecLen);
178
+ //Step 4: taking snapshot and returning the new instance with the new value.
179
+ this.assign(this.normalize(intFinal, decFinal));
180
+ return this.clone();
181
+ }
182
+ /**
183
+ * Executes the {@link https://en.wikipedia.org/wiki/Division_(mathematics) | division}
184
+ * operation for the given value.
185
+ * @param input The dividing operand
186
+ * @param options The option object that determines calculation behavior.
187
+ * @returns A new instance of {@link AoOperand} that holds the operation latest result
188
+ */
189
+ divide(input, options) {
190
+ //Step 1: prerequisites refinement
191
+ const _options = {
192
+ precision: options?.precision ?? 10,
193
+ divideByZeroAlt: this.refine(options?.divideByZeroAlt).value,
194
+ };
195
+ const inputRefined = this.refine(input);
196
+ const currentRefined = this.refine(this._currentValue);
197
+ const int1 = currentRefined.integer;
198
+ const dec1 = currentRefined.decimal;
199
+ const int2 = inputRefined.integer;
200
+ const dec2 = inputRefined.decimal;
201
+ const whole1 = BigInt(int1 + dec1);
202
+ const whole2 = BigInt(int2 + dec2);
203
+ //Step 2: check divide by zero case
204
+ if (whole2 === 0n) {
205
+ this.assign(_options.divideByZeroAlt);
206
+ return this.clone();
207
+ }
208
+ //Step 3: adjust scale to preserve precision
209
+ const scale = BigInt(10 ** (_options.precision + dec2.length - dec1.length));
210
+ const numerator = whole1 * scale;
211
+ const quotient = numerator / whole2;
212
+ //Step 4: convert to string and insert decimal point
213
+ const quotientDigits = quotient.toString().padStart(_options.precision + 1, "0");
214
+ const intFinal = quotientDigits.slice(0, -_options.precision);
215
+ const decFinal = quotientDigits.slice(-_options.precision);
216
+ //Step 5: taking snapshot and returning the new instance with the new value.
217
+ this.assign(this.normalize(intFinal, decFinal));
218
+ return this.clone();
219
+ }
220
+ /**
221
+ * Creates a new instance based on current instance.
222
+ * @returns A new {@link AoOperand} instance
223
+ */
224
+ clone() {
225
+ return new AoOperand(this);
226
+ }
227
+ /**
228
+ * Takes snapshot from the current value then assigns the given value to it.
229
+ * @param value the input value that updates the current value
230
+ */
231
+ assign(value) {
232
+ this._previousValue = this._currentValue;
233
+ this._currentValue = value;
234
+ }
235
+ /**
236
+ * Restrains the given number operation by switching to its bigint alternative
237
+ * if it leads to {@link Infinity}.
238
+ * @param finiteOperator The callback that returns number
239
+ * @param infiniteOperator The callback that returns bigint
240
+ * @returns A numeric string
241
+ */
242
+ restrain(finiteOperator, infiniteOperator) {
243
+ const _finiteOperator = finiteOperator();
244
+ return Number.isFinite(_finiteOperator)
245
+ ? _finiteOperator.toString()
246
+ : infiniteOperator().toString();
247
+ }
248
+ /**
249
+ * Creates an info object from raw input that provides refined number parts for calculation.
250
+ * @param input The raw input needed for refinement.
251
+ * @returns An object info providing refined data for calculation
252
+ */
253
+ refine(input) {
254
+ const _decimal = aoExtractDecimal(input);
255
+ const _integer = aoExtractInteger(input) || "0";
256
+ const _value = _decimal
257
+ ? `${_integer}.${_decimal}`
258
+ : _integer;
259
+ return {
260
+ decimal: _decimal || "0",
261
+ integer: _integer,
262
+ value: _value,
263
+ };
264
+ }
265
+ /**
266
+ * Normalizes the decimal part if all of its digits are "0" and removes trailing zeros.
267
+ * @param integer The integer part of the value
268
+ * @param decimal The decimal part of the value
269
+ * @returns The normalized numeric string
270
+ */
271
+ normalize(integer, decimal) {
272
+ function unTrailZeros(value) {
273
+ return value.replace(/0+$/, '');
274
+ }
275
+ return /^0*$/.test(decimal)
276
+ ? integer
277
+ : `${integer}.${unTrailZeros(decimal)}`;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Generated bundle index. Do not edit.
283
+ */
284
+
285
+ export { AoOperand };
286
+ //# sourceMappingURL=arabig-origin-operand.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arabig-origin-operand.mjs","sources":["../../../projects/origin/operand/operand.ts","../../../projects/origin/operand/arabig-origin-operand.ts"],"sourcesContent":["/**\r\n * @license\r\n * Copyright Salar Arab All Rights Reserved\r\n * \r\n * @author Salar Arab <salar_arab@outlook.com>\r\n */\r\n\r\nimport { aoExtractDecimal, aoExtractInteger } from \"@arabig/origin/functions\";\r\n\r\n/**\r\n * Represents a numeric string\r\n */\r\ntype Digits = `${number}`;\r\n\r\n/**\r\n * The convertible input type used mostly in calculation methods\r\n */\r\ntype RawInput = string | number | bigint | null | undefined;\r\n\r\n/**\r\n * Represents different states of the value\r\n */\r\ntype ValueState = \"current\" | \"previous\" | \"initial\";\r\n\r\n/**\r\n * Utilizes performing precise arithmetic operations\r\n * such as addition, subtraction, multiplication, and division in the form of pipeline.\r\n *\r\n * This class is designed to handle extremely large or small numeric values\r\n * without resulting in {@link Infinity} or {@link NaN}, ensuring safe and predictable\r\n * calculations across a wide range of inputs.\r\n *\r\n * All operations are performed using numeric strings to maintain precision,\r\n * especially for decimal values, avoiding floating-point inaccuracies common\r\n * in native JavaScript number handling.\r\n *\r\n * @example\r\n * ```ts\r\n * const operand = new AoOperand(0.005).add(1.05).add(0.005);\r\n * \r\n * console.log(operand.currentValue) //expecting \"1.06\";\r\n * ```\r\n *\r\n * @remarks\r\n * This class is ideal for financial, scientific, or any domain where\r\n * precision and scale are critical. It does not rely on native number\r\n * arithmetic and instead uses string-based computation to preserve accuracy.\r\n */\r\nexport class AoOperand {\r\n\r\n private readonly _initialValue: Digits;\r\n\r\n private _previousValue: Digits;\r\n\r\n private _currentValue: Digits;\r\n\r\n /**\r\n * Creates a new instance based on given instance.\r\n * @param instance An instance of {@link AoOperand}\r\n */\r\n constructor(instance: AoOperand);\r\n /**\r\n * Creates a new instance of {@link AoOperand} with provided initial value.\r\n * @param initialValue\r\n * The initial value of the calculation. If the value is not provided or not numeric\r\n * convertible, is assigned to \"0\".\r\n */\r\n constructor(initialValue?: RawInput);\r\n //declaration\r\n constructor(param?: RawInput | AoOperand) {\r\n if (param instanceof AoOperand) {\r\n this._initialValue = param.toString(\"initial\");\r\n this._currentValue = param.toString(\"current\");\r\n this._previousValue = param.toString(\"previous\");\r\n }\r\n else {\r\n this._initialValue = this.refine(param).value;\r\n this._currentValue = this._initialValue;\r\n this._previousValue = \"0\";\r\n }\r\n }\r\n\r\n /**\r\n * Converts and outputs the {@link AoOperand}'s value as number base on given state.\r\n * @param state The state that determines temporal state of the value. Default is \"current\"\r\n * @returns A number\r\n */\r\n public toNumber(state: ValueState = \"current\"): number {\r\n return Number(this[`_${state}Value`]);\r\n }\r\n\r\n /**\r\n * Converts and outputs the {@link AoOperand}'s value as bigint base on given state.\r\n * @param state The state that determines temporal state of the value. Default is \"current\"\r\n * @returns A bigint\r\n */\r\n public toBigInt(state: ValueState = \"current\"): bigint {\r\n return BigInt(this[`_${state}Value`]);\r\n }\r\n\r\n /**\r\n * Converts and outputs the {@link AoOperand}'s value as numeric string base on given state.\r\n * @param state The state that determines temporal state of the value. Default is \"current\"\r\n * @returns A numeric string\r\n */\r\n public toString(state: ValueState = \"current\"): Digits {\r\n return this[`_${state}Value`];\r\n }\r\n\r\n /**\r\n * Executes the Executes the {@link https://en.wikipedia.org/wiki/Addition | addition}\r\n * operation for the given value.\r\n * @param input The adding operand\r\n * @returns A new instance of {@link AoOperand} that holds the operation latest result\r\n */\r\n public add(input: RawInput): AoOperand {\r\n //Step 1: prerequisites refinement\r\n const inputRefined = this.refine(input);\r\n const currentRefined = this.refine(this._currentValue);\r\n \r\n const int1 = currentRefined.integer;\r\n const dec1 = currentRefined.decimal;\r\n\r\n const int2 = inputRefined.integer;\r\n const dec2 = inputRefined.decimal;\r\n \r\n //Step 2: decimals normalization\r\n const mantissa = Math.max(dec1.length, dec2.length);\r\n\r\n const dec1Norm = dec1.padEnd(mantissa, \"0\") as Digits;\r\n const dec2Norm = dec2.padEnd(mantissa, \"0\") as Digits;\r\n\r\n //Step 3: restraining resulting integer\r\n const intFinal = this.restrain(\r\n () => {\r\n const intSum = Number(int1) + Number(int2);\r\n const decSum = Number(dec1Norm) + Number(dec2Norm);\r\n\r\n const spillover = Math.floor(decSum / (mantissa ** 10));\r\n\r\n return intSum + spillover;\r\n },\r\n () => {\r\n const intSum = BigInt(int1) + BigInt(int2);\r\n const decSum = BigInt(dec1Norm) + BigInt(dec2Norm);\r\n\r\n const spillover = decSum / (BigInt(mantissa) ** 10n);\r\n\r\n return intSum + spillover;\r\n },\r\n );\r\n\r\n //Step 4: restraining resulting decimal\r\n const decResult = this.restrain(\r\n () => {\r\n const decSum = Number(dec1Norm) + Number(dec2Norm);\r\n\r\n return decSum % (10 ** mantissa);\r\n },\r\n () => {\r\n const decSum = BigInt(dec1Norm) + BigInt(dec2Norm);\r\n\r\n return decSum % (10n ** BigInt(mantissa));\r\n },\r\n );\r\n\r\n const decFinal = decResult.padStart(mantissa, \"0\") as Digits;\r\n\r\n //Step 5: taking snapshot and returning the new instance with the new value.\r\n this.assign(this.normalize(intFinal, decFinal));\r\n\r\n return this.clone();\r\n }\r\n\r\n /**\r\n * Executes the {@link https://en.wikipedia.org/wiki/Subtraction | subtraction} \r\n * operation for the given value.\r\n * @param input The subtracting operand\r\n * @returns A new instance of {@link AoOperand} that holds the operation latest result\r\n */\r\n public subtract(input: RawInput): AoOperand {\r\n //Step 1: prerequisites refinement\r\n const inputRefined = this.refine(input);\r\n const currentRefined = this.refine(this._currentValue);\r\n\r\n const int1 = currentRefined.integer;\r\n const dec1 = currentRefined.decimal;\r\n \r\n const int2 = inputRefined.integer;\r\n const dec2 = inputRefined.decimal;\r\n\r\n //Step 2: decimals normalization\r\n const mantissa = Math.max(dec1.length, dec2.length);\r\n\r\n const dec1Norm = dec1.padEnd(mantissa, \"0\") as Digits;\r\n const dec2Norm = dec2.padEnd(mantissa, \"0\") as Digits;\r\n\r\n //Step 3: restraining resulting integer\r\n const intFinal = this.restrain(\r\n () => {\r\n const decSub = Number(dec1Norm) - Number(dec2Norm);\r\n let intSub = Number(int1) - Number(int2);\r\n\r\n return decSub < 0 ? intSub -= 1 : intSub;\r\n },\r\n () => {\r\n const decSub = BigInt(dec1Norm) - BigInt(dec2Norm);\r\n let intSub = BigInt(int1) - BigInt(int2);\r\n\r\n return decSub < 0n ? intSub -= 1n : intSub;\r\n },\r\n );\r\n\r\n //Step 4: restraining resulting decimal\r\n const decResult = this.restrain(\r\n () => {\r\n let sub = Number(dec1Norm) - Number(dec2Norm);\r\n\r\n return sub < 0 ? sub += (Number(mantissa) ** 10): sub;\r\n },\r\n () => {\r\n let sub = BigInt(dec1Norm) - BigInt(dec2Norm);\r\n\r\n return sub < 0n ? sub += (BigInt(mantissa) ** 10n): sub;\r\n },\r\n );\r\n\r\n const decFinal = decResult.padStart(mantissa, \"0\") as Digits;\r\n\r\n //Step 5: taking snapshot and returning the new instance with the new value.\r\n this.assign(this.normalize(intFinal, decFinal));\r\n\r\n return this.clone();\r\n }\r\n\r\n /**\r\n * Executes the {@link https://en.wikipedia.org/wiki/Multiplication | multiplication} \r\n * operation for the given value.\r\n * @param input The multiplying operand\r\n * @returns A new instance of {@link AoOperand} that holds the operation latest result\r\n */\r\n public multiply(input: RawInput): AoOperand {\r\n //Step 1: prerequisites refinement\r\n const inputRefined = this.refine(input);\r\n const currentRefined = this.refine(this._currentValue);\r\n\r\n const int1 = currentRefined.integer;\r\n const dec1 = currentRefined.decimal;\r\n \r\n const int2 = inputRefined.integer;\r\n const dec2 = inputRefined.decimal;\r\n\r\n const totalDecLen = dec1.length + dec2.length;\r\n //Step 2: product calculation\r\n const product = this.restrain(\r\n () => Number(int1 + dec1) * Number(int2 + dec2),\r\n () => BigInt(int1 + dec1) * BigInt(int2 + dec2),\r\n ).padStart(totalDecLen + 1, \"0\") as Digits;\r\n\r\n //Step 3: slicing numeric parts\r\n const intFinal = product.slice(0, -totalDecLen) as Digits;\r\n const decFinal = product.slice(-totalDecLen) as Digits;\r\n\r\n //Step 4: taking snapshot and returning the new instance with the new value.\r\n this.assign(this.normalize(intFinal, decFinal));\r\n\r\n return this.clone();\r\n }\r\n\r\n /**\r\n * Executes the {@link https://en.wikipedia.org/wiki/Division_(mathematics) | division} \r\n * operation for the given value.\r\n * @param input The dividing operand\r\n * @param options The option object that determines calculation behavior.\r\n * @returns A new instance of {@link AoOperand} that holds the operation latest result\r\n */\r\n public divide(\r\n input: RawInput,\r\n options?: {\r\n /**\r\n * The number of decimal places to keep. The default value is 10\r\n */\r\n precision?: number,\r\n /**\r\n * The alternative value in case of divide by zero\r\n */\r\n divideByZeroAlt?: RawInput,\r\n },\r\n ): AoOperand {\r\n //Step 1: prerequisites refinement\r\n const _options = {\r\n precision: options?.precision ?? 10,\r\n divideByZeroAlt: this.refine(options?.divideByZeroAlt).value,\r\n };\r\n\r\n const inputRefined = this.refine(input);\r\n const currentRefined = this.refine(this._currentValue);\r\n\r\n const int1 = currentRefined.integer;\r\n const dec1 = currentRefined.decimal;\r\n \r\n const int2 = inputRefined.integer;\r\n const dec2 = inputRefined.decimal;\r\n\r\n const whole1 = BigInt(int1 + dec1);\r\n const whole2 = BigInt(int2 + dec2);\r\n\r\n //Step 2: check divide by zero case\r\n if (whole2 === 0n) {\r\n this.assign(_options.divideByZeroAlt);\r\n return this.clone();\r\n }\r\n\r\n //Step 3: adjust scale to preserve precision\r\n const scale = BigInt(10 ** (_options.precision + dec2.length - dec1.length));\r\n const numerator = whole1 * scale;\r\n const quotient = numerator / whole2;\r\n\r\n //Step 4: convert to string and insert decimal point\r\n const quotientDigits = quotient.toString().padStart(_options.precision + 1, \"0\") as Digits;\r\n const intFinal = quotientDigits.slice(0, -_options.precision) as Digits;\r\n const decFinal = quotientDigits.slice(-_options.precision) as Digits;\r\n\r\n //Step 5: taking snapshot and returning the new instance with the new value.\r\n this.assign(this.normalize(intFinal, decFinal));\r\n\r\n return this.clone();\r\n }\r\n\r\n /**\r\n * Creates a new instance based on current instance.\r\n * @returns A new {@link AoOperand} instance\r\n */\r\n private clone(): AoOperand {\r\n return new AoOperand(this);\r\n }\r\n\r\n /**\r\n * Takes snapshot from the current value then assigns the given value to it.\r\n * @param value the input value that updates the current value\r\n */\r\n private assign(value: Digits): void {\r\n this._previousValue = this._currentValue;\r\n this._currentValue = value;\r\n }\r\n\r\n /**\r\n * Restrains the given number operation by switching to its bigint alternative\r\n * if it leads to {@link Infinity}.\r\n * @param finiteOperator The callback that returns number\r\n * @param infiniteOperator The callback that returns bigint\r\n * @returns A numeric string\r\n */\r\n private restrain(\r\n finiteOperator: () => number,\r\n infiniteOperator: () => bigint,\r\n ): Digits {\r\n const _finiteOperator = finiteOperator();\r\n\r\n return Number.isFinite(_finiteOperator)\r\n ? _finiteOperator.toString() as Digits\r\n : infiniteOperator().toString() as Digits;\r\n }\r\n\r\n /**\r\n * Creates an info object from raw input that provides refined number parts for calculation.\r\n * @param input The raw input needed for refinement.\r\n * @returns An object info providing refined data for calculation\r\n */\r\n private refine(input: RawInput): {\r\n decimal: Digits,\r\n integer: Digits,\r\n value: Digits,\r\n } {\r\n const _decimal = aoExtractDecimal(input);\r\n const _integer = aoExtractInteger(input) || \"0\";\r\n const _value = _decimal\r\n ? `${_integer}.${_decimal}` as Digits\r\n : _integer;\r\n \r\n return {\r\n decimal: _decimal || \"0\",\r\n integer: _integer,\r\n value: _value,\r\n };\r\n }\r\n\r\n /**\r\n * Normalizes the decimal part if all of its digits are \"0\" and removes trailing zeros.\r\n * @param integer The integer part of the value\r\n * @param decimal The decimal part of the value\r\n * @returns The normalized numeric string\r\n */\r\n private normalize(integer: Digits, decimal: Digits): Digits {\r\n function unTrailZeros(value: Digits): Digits {\r\n return value.replace(/0+$/, '') as Digits;\r\n }\r\n\r\n return /^0*$/.test(decimal)\r\n ? integer\r\n : `${integer}.${unTrailZeros(decimal)}` as Digits;\r\n }\r\n\r\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { aoFilterObject } from '@arabig/origin/functions';
2
+
3
+ /**
4
+ * @license
5
+ * Copyright Salar Arab All Rights Reserved.
6
+ *
7
+ * @author Salar Arab <salar_arab@outlook.com>
8
+ */
9
+ /**
10
+ * Utilizes performing common operations as pipeline on object-like.
11
+ *
12
+ * @remarks
13
+ * {@link AoRecord} provides a fluent and type-safe API for manipulating objects.
14
+ * It includes methods for filtering, mapping, and transforming key-value pairs—similar to
15
+ * array utilities but designed for object semantics.
16
+ *
17
+ * This class is ideal for scenarios where object-based data structures need to be processed
18
+ * functionally, such as configuration maps, lookup tables, or DTO transformations.
19
+ *
20
+ * @typeParam T - The type of entries contained in the record.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const rec = new AoRecord({
25
+ * name: "John",
26
+ * age: 33,
27
+ * married: false,
28
+ * }).filter(({ key }) => key !== "age");
29
+ * ```
30
+ */
31
+ class AoRecord {
32
+ _entries;
33
+ /**
34
+ *
35
+ * @param defaultEntries The default structure to initialize {@link AoRecord} entries
36
+ */
37
+ constructor(defaultEntries) {
38
+ this._entries = defaultEntries;
39
+ }
40
+ /**
41
+ * @readonly Gets keys of the current entries.
42
+ * @returns An array containing keys of the current entries
43
+ */
44
+ get keys() {
45
+ return Object.keys(this._entries);
46
+ }
47
+ /**
48
+ * @readonly Gets values of the current entries.
49
+ * @returns An array containing values of the current entries
50
+ */
51
+ get values() {
52
+ return Object.values(this._entries);
53
+ }
54
+ /**
55
+ * @readonly Gets the current entries.
56
+ * @returns An array containing the current entries in form of {@link AoEntryUnion}
57
+ */
58
+ get entries() {
59
+ return Object.entries(this._entries)
60
+ .map(e => ({ key: e[0], value: e[1] }));
61
+ }
62
+ /**
63
+ * Filters the current entries based on given condition.
64
+ * @param predicate The callback that iterates within {@link AoRecord} entries and
65
+ * provides the key and value in form of {@link AoEntryUnion} as parameter and must
66
+ * return a boolean type determines whether the current key should be remained in the
67
+ * resulting entries or not
68
+ * @returns A new instance of {@link AoRecord} containing the {@link Partial} filtered entries.
69
+ */
70
+ filter(predicate) {
71
+ return new AoRecord(aoFilterObject(this._entries, predicate));
72
+ }
73
+ /**
74
+ * Tests the trueness of the given condition for every entry.
75
+ * @param predicate The callback that iterates within {@link AoRecord} entries and
76
+ * provides the key and value in form of {@link AoEntryUnion} as parameter and must
77
+ * return a boolean type determines the condition for current entry
78
+ * @returns True, if the given conditions is true for every entry otherwise false
79
+ */
80
+ every(predicate) {
81
+ for (const key in this._entries) {
82
+ if (!Object.hasOwn(this._entries, key))
83
+ continue;
84
+ if (!predicate({ key: key, value: this._entries[key] }))
85
+ return false;
86
+ }
87
+ return true;
88
+ }
89
+ /**
90
+ * Tests the trueness of the given condition for atleast one entry.
91
+ * @param predicate The callback that iterates within {@link AoRecord} entries and
92
+ * provides the key and value in form of {@link AoEntryUnion} as parameter and must
93
+ * return a boolean type determines the condition for current entry
94
+ * @returns True, if the given conditions is true for atleast one entry otherwise false
95
+ */
96
+ some(predicate) {
97
+ for (const key in this._entries) {
98
+ if (!Object.hasOwn(this._entries, key))
99
+ continue;
100
+ if (predicate({ key: key, value: this._entries[key] }))
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Generated bundle index. Do not edit.
109
+ */
110
+
111
+ export { AoRecord };
112
+ //# sourceMappingURL=arabig-origin-record.mjs.map