utils.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Arr = exports.BigNumOps = exports.rawRegExp = exports.customError = exports.CustomError = exports.neverResolves = exports.chainPromises = void 0;
  4. const CallableInstance = require("callable-instance");
  5. const chainPromises = (lazyPromises, reducer = (lp1, lp2) => (p) => lp1(p).then(lp2), initialValue) => lazyPromises.reduce(reducer, p => Promise.resolve(p))(initialValue);
  6. exports.chainPromises = chainPromises;
  7. const neverResolves = () => new Promise(() => undefined);
  8. exports.neverResolves = neverResolves;
  9. class CustomErrorConstructor extends CallableInstance {
  10. constructor(name) {
  11. super('getError');
  12. Object.defineProperty(this.constructor, 'name', { value: name });
  13. }
  14. getError(message) { return new CustomError(this.constructor.name, message); }
  15. }
  16. class CustomError extends Error {
  17. constructor(name, message) {
  18. super(message);
  19. this.name = name;
  20. Object.defineProperty(this.constructor, 'name', { value: name });
  21. }
  22. }
  23. exports.CustomError = CustomError;
  24. const customError = (name) => new CustomErrorConstructor(name);
  25. exports.customError = customError;
  26. const chunkArray = (arr, size) => {
  27. const noOfChunks = Math.ceil(size && arr.length / size);
  28. const res = Array(noOfChunks);
  29. for (let [i, j] = [0, 0]; i < noOfChunks; i++) {
  30. res[i] = arr.slice(j, j += size);
  31. }
  32. return res;
  33. };
  34. const rawRegExp = (...args) => RegExp(String.raw(...args));
  35. exports.rawRegExp = rawRegExp;
  36. const splitBigNumAt = (num, at) => num.replace((0, exports.rawRegExp) `^([+-]?)(\d+)(\d{${at}})$`, '$1$2,$1$3')
  37. .replace(/^([^,]*)$/, '0,$1').split(',')
  38. .map(Number);
  39. const bigNumPlus = (num1, num2) => {
  40. let [high, low] = [splitBigNumAt(num1, 15), splitBigNumAt(num2, 15)]
  41. .reduce((a, b) => [a[0] + b[0], a[1] + b[1]]);
  42. const [highSign, lowSign] = [high, low].map(Math.sign);
  43. if (highSign === 0)
  44. return low.toString();
  45. if (highSign + lowSign === 0) {
  46. [high, low] = [high - highSign, low - lowSign * Math.pow(10, 15)];
  47. }
  48. else {
  49. [high, low] = [high + Math.trunc(low / Math.pow(10, 15)), low % Math.pow(10, 15)];
  50. }
  51. if (high === 0)
  52. return low.toString();
  53. return `${high}${Math.abs(low).toString().padStart(15, '0')}`;
  54. };
  55. const bigNumCompare = (num1, num2) => Math.sign(Number(bigNumPlus(num1, num2.replace(/^([+-]?)(\d+)/, (_, $1, $2) => `${$1 === '-' ? '' : '-'}${$2}`))));
  56. const bigNumMin = (...nums) => {
  57. if (!nums || !nums.length)
  58. return undefined;
  59. let min = nums[0];
  60. for (let i = 1; i < nums.length; i++) {
  61. if (bigNumCompare(nums[i], min) < 0)
  62. min = nums[i];
  63. }
  64. return min;
  65. };
  66. const bigNumLShift = (num, by) => {
  67. if (by < 0)
  68. throw Error('cannot perform right shift');
  69. const at = Math.trunc((52 - by) / 10) * 3;
  70. const [high, low] = splitBigNumAt(num, at).map(n => n * Math.pow(2, by));
  71. return bigNumPlus(`${high}${'0'.repeat(at)}`, low.toString());
  72. };
  73. const parseBigNum = (str) => (/^-?\d+$/.exec(str) || [''])[0].replace(/^(-)?0*/, '$1');
  74. exports.BigNumOps = {
  75. splitAt: splitBigNumAt,
  76. plus: bigNumPlus,
  77. compare: bigNumCompare,
  78. min: bigNumMin,
  79. lShift: bigNumLShift,
  80. parse: parseBigNum,
  81. };
  82. exports.Arr = { chunk: chunkArray };