@swapkit/helpers 1.0.0-rc.3 → 1.0.0-rc.30

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.
@@ -1,3 +1,5 @@
1
+ import { BaseDecimal } from '@swapkit/types';
2
+
1
3
  import type { SwapKitNumber } from './swapKitNumber.ts';
2
4
 
3
5
  type NumberPrimitivesType = {
@@ -5,7 +7,7 @@ type NumberPrimitivesType = {
5
7
  number: number;
6
8
  string: string;
7
9
  };
8
- type NumberPrimitives = bigint | number | string;
10
+ export type NumberPrimitives = bigint | number | string;
9
11
  type InitialisationValueType = NumberPrimitives | BigIntArithmetics | SwapKitNumber;
10
12
 
11
13
  type SKBigIntParams = InitialisationValueType | { decimal?: number; value: number | string };
@@ -69,12 +71,12 @@ export class BigIntArithmetics {
69
71
  from,
70
72
  to,
71
73
  }: {
72
- value: InitialisationValueType;
74
+ value: InstanceType<typeof SwapKitNumber>;
73
75
  from: number;
74
76
  to: number;
75
77
  }) {
76
- return BigIntArithmetics.fromBigInt(
77
- (new BigIntArithmetics(value).bigIntValue * toMultiplier(to)) / toMultiplier(from),
78
+ return this.fromBigInt(
79
+ (value.getBaseValue('bigint') * toMultiplier(to)) / toMultiplier(from),
78
80
  to,
79
81
  );
80
82
  }
@@ -85,22 +87,12 @@ export class BigIntArithmetics {
85
87
 
86
88
  // use the multiplier to keep track of decimal point - defaults to 8 if lower than 8
87
89
  this.decimalMultiplier = toMultiplier(
88
- Math.max(this.#getFloatDecimals(this.#toSafeValue(value)), this.decimal || 0),
90
+ Math.max(getFloatDecimals(toSafeValue(value)), this.decimal || 0),
89
91
  );
90
92
  this.#setValue(value);
91
93
  }
92
94
 
93
- get baseValue() {
94
- return this.getBaseValue('string') as string;
95
- }
96
- get baseValueNumber() {
97
- return this.getBaseValue('number') as number;
98
- }
99
- get baseValueBigInt() {
100
- return this.getBaseValue('bigint') as bigint;
101
- }
102
-
103
- set(value: SKBigIntParams) {
95
+ set(value: SKBigIntParams): this {
104
96
  // @ts-expect-error False positive
105
97
  return new this.constructor({ decimal: this.decimal, value, identifier: this.toString() });
106
98
  }
@@ -132,7 +124,7 @@ export class BigIntArithmetics {
132
124
  return this.bigIntValue === this.getBigIntValue(value);
133
125
  }
134
126
 
135
- getValue<T extends 'number' | 'string' | 'bigint'>(type: T): NumberPrimitivesType[T] {
127
+ getValue<T extends 'number' | 'string'>(type: T): NumberPrimitivesType[T] {
136
128
  const value = this.formatBigIntToSafeValue(
137
129
  this.bigIntValue,
138
130
  this.decimal || decimalFromMultiplier(this.decimalMultiplier),
@@ -147,12 +139,12 @@ export class BigIntArithmetics {
147
139
  return value;
148
140
  default:
149
141
  // @ts-expect-error False positive
150
- return this.bigIntValue;
142
+ return (this.bigIntValue * BigInt(this.decimal || 8n)) / this.decimalMultiplier;
151
143
  }
152
144
  }
153
145
 
154
146
  getBaseValue<T extends 'number' | 'string' | 'bigint'>(type: T): NumberPrimitivesType[T] {
155
- const divisor = this.decimalMultiplier / toMultiplier(this.decimal || 0);
147
+ const divisor = this.decimalMultiplier / toMultiplier(this.decimal || BaseDecimal.THOR);
156
148
  const baseValue = this.bigIntValue / divisor;
157
149
 
158
150
  switch (type) {
@@ -164,14 +156,18 @@ export class BigIntArithmetics {
164
156
  return baseValue.toString();
165
157
  default:
166
158
  // @ts-expect-error False positive
167
- return this.bigIntValue;
159
+ return baseValue;
168
160
  }
169
161
  }
170
162
 
171
163
  getBigIntValue(value: InitialisationValueType, decimal?: number) {
172
164
  if (!decimal && typeof value === 'object') return value.bigIntValue;
173
165
 
174
- return this.#toBigInt(this.#toSafeValue(getStringValue(value)), decimal);
166
+ const stringValue = getStringValue(value);
167
+ const safeValue = toSafeValue(stringValue);
168
+
169
+ if (safeValue === '0' || safeValue === 'undefined') return 0n;
170
+ return this.#toBigInt(safeValue, decimal);
175
171
  }
176
172
 
177
173
  formatBigIntToSafeValue(value: bigint, decimal?: number) {
@@ -223,7 +219,7 @@ export class BigIntArithmetics {
223
219
 
224
220
  if (parseInt(integer)) {
225
221
  return `${integer}.${decimal.slice(0, significantDigits - integer.length)}`.padEnd(
226
- valueLength - significantDigits,
222
+ significantDigits - integer.length,
227
223
  '0',
228
224
  );
229
225
  }
@@ -237,6 +233,63 @@ export class BigIntArithmetics {
237
233
  )}`;
238
234
  }
239
235
 
236
+ toFixed(fixedDigits: number = 6) {
237
+ const [int, dec] = this.getValue('string').split('.');
238
+ const integer = int || '';
239
+ const decimal = dec || '';
240
+
241
+ if (parseInt(integer)) {
242
+ return `${integer}.${decimal.slice(0, fixedDigits)}`.padEnd(fixedDigits, '0');
243
+ }
244
+
245
+ const trimmedDecimal = parseInt(decimal);
246
+ const slicedDecimal = `${trimmedDecimal}`.slice(0, fixedDigits);
247
+
248
+ return `0.${slicedDecimal.padStart(
249
+ decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
250
+ '0',
251
+ )}`;
252
+ }
253
+
254
+ toAbbreviation(digits = 2) {
255
+ const value = this.getValue('number');
256
+ const abbreviations = ['', 'K', 'M', 'B', 'T', 'Q', 'Qi', 'S'];
257
+ const tier = Math.floor(Math.log10(Math.abs(value)) / 3);
258
+ const suffix = abbreviations[tier];
259
+
260
+ if (!suffix) return this.getValue('string');
261
+
262
+ const scale = 10 ** (tier * 3);
263
+ const scaled = value / scale;
264
+
265
+ return `${scaled.toFixed(digits)}${suffix}`;
266
+ }
267
+
268
+ toCurrency(
269
+ currency = '$',
270
+ {
271
+ currencyPosition = 'start',
272
+ decimal = 2,
273
+ decimalSeparator = '.',
274
+ thousandSeparator = ',',
275
+ } = {},
276
+ ) {
277
+ const value = this.getValue('number');
278
+ const [int, dec = ''] = value.toFixed(6).split('.');
279
+ const integer = int.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
280
+
281
+ const parsedValue =
282
+ !int && !dec
283
+ ? '0.00'
284
+ : int === '0'
285
+ ? `${parseFloat(`0.${dec}`)}`.replace('.', decimalSeparator)
286
+ : `${integer}${parseInt(dec) ? `${decimalSeparator}${dec.slice(0, decimal)}` : ''}`;
287
+
288
+ return `${currencyPosition === 'start' ? currency : ''}${parsedValue}${
289
+ currencyPosition === 'end' ? currency : ''
290
+ }`;
291
+ }
292
+
240
293
  #arithmetics(method: 'add' | 'sub' | 'mul' | 'div', ...args: InitialisationValueType[]): this {
241
294
  const precisionDecimal = this.#retrievePrecisionDecimal(this, ...args);
242
295
  const precisionDecimalMultiplier = toMultiplier(precisionDecimal);
@@ -283,7 +336,7 @@ export class BigIntArithmetics {
283
336
  }
284
337
 
285
338
  #setValue(value: InitialisationValueType) {
286
- const safeValue = this.#toSafeValue(value) || '0';
339
+ const safeValue = toSafeValue(value) || '0';
287
340
  this.bigIntValue = this.#toBigInt(safeValue);
288
341
  }
289
342
 
@@ -292,7 +345,7 @@ export class BigIntArithmetics {
292
345
  .map((arg) =>
293
346
  typeof arg === 'object'
294
347
  ? arg.decimal || decimalFromMultiplier(arg.decimalMultiplier)
295
- : this.#getFloatDecimals(this.#toSafeValue(arg)),
348
+ : getFloatDecimals(toSafeValue(arg)),
296
349
  )
297
350
  .filter(Boolean) as number[];
298
351
  return Math.max(...decimals, DEFAULT_DECIMAL);
@@ -301,37 +354,36 @@ export class BigIntArithmetics {
301
354
  #toBigInt(value: string, decimal?: number) {
302
355
  const multiplier = decimal ? toMultiplier(decimal) : this.decimalMultiplier;
303
356
  const padDecimal = decimalFromMultiplier(multiplier);
304
- const [integerPart, decimalPart = ''] = value.split('.');
357
+ const [integerPart = '', decimalPart = ''] = value.split('.');
305
358
 
306
359
  return BigInt(`${integerPart}${decimalPart.padEnd(padDecimal, '0')}`);
307
360
  }
361
+ }
308
362
 
309
- #toSafeValue(value: InitialisationValueType) {
310
- const parsedValue =
311
- typeof value === 'number'
312
- ? Number(value).toLocaleString('fullwide', {
313
- useGrouping: false,
314
- maximumFractionDigits: 20,
315
- })
316
- : getStringValue(value);
317
-
318
- const splitValue = `${parsedValue}`.replaceAll(',', '.').split('.');
319
-
320
- return splitValue.length > 1
321
- ? `${splitValue.slice(0, -1).join('')}.${splitValue.at(-1)}`
322
- : splitValue[0];
323
- }
363
+ const numberFormatter = Intl.NumberFormat('fullwide', {
364
+ useGrouping: false,
365
+ maximumFractionDigits: 20,
366
+ });
324
367
 
325
- #getFloatDecimals(value: string) {
326
- const decimals = value.split('.')[1]?.length || 0;
327
- return Math.max(decimals, DEFAULT_DECIMAL);
328
- }
368
+ function toSafeValue(value: InitialisationValueType) {
369
+ const parsedValue =
370
+ typeof value === 'number' ? numberFormatter.format(value) : getStringValue(value);
371
+ const splitValue = `${parsedValue}`.replaceAll(',', '.').split('.');
372
+
373
+ return splitValue.length > 1
374
+ ? `${splitValue.slice(0, -1).join('')}.${splitValue.at(-1)}`
375
+ : splitValue[0];
376
+ }
377
+
378
+ function getFloatDecimals(value: string) {
379
+ const decimals = value.split('.')[1]?.length || 0;
380
+ return Math.max(decimals, DEFAULT_DECIMAL);
329
381
  }
330
382
 
331
- function getStringValue(value: SKBigIntParams) {
332
- return typeof value === 'object'
333
- ? 'getValue' in value
334
- ? value.getValue('string')
335
- : value.value
336
- : value;
383
+ function getStringValue(param: SKBigIntParams) {
384
+ return typeof param === 'object'
385
+ ? 'getValue' in param
386
+ ? param.getValue('string')
387
+ : param.value
388
+ : param;
337
389
  }
@@ -1,4 +1,4 @@
1
- import { BigIntArithmetics } from './bigIntArithmetics.ts';
1
+ import { BigIntArithmetics, formatBigIntToSafeValue } from './bigIntArithmetics.ts';
2
2
 
3
3
  export type SwapKitValueType = BigIntArithmetics | string | number;
4
4
 
@@ -6,4 +6,11 @@ export class SwapKitNumber extends BigIntArithmetics {
6
6
  eq(value: SwapKitValueType) {
7
7
  return this.eqValue(value);
8
8
  }
9
+
10
+ static fromBigInt(value: bigint, decimal?: number) {
11
+ return new SwapKitNumber({
12
+ decimal,
13
+ value: formatBigIntToSafeValue({ value, bigIntDecimal: decimal, decimal }),
14
+ });
15
+ }
9
16
  }