@pezkuwi/util 14.0.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/README.md +17 -0
- package/package.json +49 -0
- package/src/array/chunk.spec.ts +29 -0
- package/src/array/chunk.ts +35 -0
- package/src/array/filter.spec.ts +20 -0
- package/src/array/filter.ts +24 -0
- package/src/array/flatten.spec.ts +33 -0
- package/src/array/flatten.ts +51 -0
- package/src/array/index.ts +14 -0
- package/src/array/range.spec.ts +29 -0
- package/src/array/range.ts +31 -0
- package/src/array/shuffle.spec.ts +39 -0
- package/src/array/shuffle.ts +27 -0
- package/src/array/unzip.spec.ts +14 -0
- package/src/array/unzip.ts +18 -0
- package/src/array/zip.spec.ts +26 -0
- package/src/array/zip.ts +17 -0
- package/src/assert.spec.ts +40 -0
- package/src/assert.ts +50 -0
- package/src/bi/consts.ts +112 -0
- package/src/bi/helpers.ts +23 -0
- package/src/bi/index.ts +16 -0
- package/src/bi/max.spec.ts +32 -0
- package/src/bi/min.spec.ts +26 -0
- package/src/bi/min.ts +16 -0
- package/src/bi/sqrt.spec.ts +59 -0
- package/src/bi/sqrt.ts +43 -0
- package/src/bi/toBigInt.spec.ts +69 -0
- package/src/bi/toBigInt.ts +33 -0
- package/src/bi/toHex.spec.ts +56 -0
- package/src/bi/toHex.ts +16 -0
- package/src/bi/toU8a.spec.ts +99 -0
- package/src/bi/toU8a.ts +72 -0
- package/src/bn/bn.ts +6 -0
- package/src/bn/consts.spec.ts +38 -0
- package/src/bn/consts.ts +112 -0
- package/src/bn/fromHex.spec.ts +15 -0
- package/src/bn/fromHex.ts +4 -0
- package/src/bn/index.ts +18 -0
- package/src/bn/max.spec.ts +32 -0
- package/src/bn/min.spec.ts +26 -0
- package/src/bn/min.ts +36 -0
- package/src/bn/sqrt.spec.ts +37 -0
- package/src/bn/sqrt.ts +50 -0
- package/src/bn/toBn.spec.ts +53 -0
- package/src/bn/toBn.ts +43 -0
- package/src/bn/toHex.spec.ts +50 -0
- package/src/bn/toHex.ts +27 -0
- package/src/bn/toU8a.spec.ts +60 -0
- package/src/bn/toU8a.ts +45 -0
- package/src/buffer/index.ts +8 -0
- package/src/buffer/toU8a.spec.ts +20 -0
- package/src/buffer/toU8a.ts +20 -0
- package/src/bundle.ts +35 -0
- package/src/compact/addLength.spec.ts +14 -0
- package/src/compact/addLength.ts +24 -0
- package/src/compact/defaults.ts +7 -0
- package/src/compact/fromU8a.spec.ts +84 -0
- package/src/compact/fromU8a.ts +109 -0
- package/src/compact/index.ts +28 -0
- package/src/compact/stripLength.spec.ts +17 -0
- package/src/compact/stripLength.ts +26 -0
- package/src/compact/toU8a.spec.ts +59 -0
- package/src/compact/toU8a.ts +53 -0
- package/src/compact/types.ts +4 -0
- package/src/detectPackage.spec.ts +110 -0
- package/src/detectPackage.ts +138 -0
- package/src/extractTime.spec.ts +21 -0
- package/src/extractTime.ts +71 -0
- package/src/float/index.ts +4 -0
- package/src/float/toU8a.spec.ts +52 -0
- package/src/float/toU8a.ts +30 -0
- package/src/format/formatBalance.spec.ts +296 -0
- package/src/format/formatBalance.ts +177 -0
- package/src/format/formatDate.spec.ts +17 -0
- package/src/format/formatDate.ts +22 -0
- package/src/format/formatDecimal.spec.ts +28 -0
- package/src/format/formatDecimal.ts +22 -0
- package/src/format/formatElapsed.spec.ts +44 -0
- package/src/format/formatElapsed.ts +35 -0
- package/src/format/formatNumber.spec.ts +60 -0
- package/src/format/formatNumber.ts +29 -0
- package/src/format/getSeparator.spec.ts +53 -0
- package/src/format/getSeparator.ts +15 -0
- package/src/format/index.ts +9 -0
- package/src/format/si.ts +52 -0
- package/src/has.spec.ts +12 -0
- package/src/has.ts +38 -0
- package/src/hex/addPrefix.spec.ts +32 -0
- package/src/hex/addPrefix.ts +26 -0
- package/src/hex/fixLength.spec.ts +38 -0
- package/src/hex/fixLength.ts +36 -0
- package/src/hex/hasPrefix.spec.ts +32 -0
- package/src/hex/hasPrefix.ts +24 -0
- package/src/hex/index.ts +16 -0
- package/src/hex/stripPrefix.spec.ts +44 -0
- package/src/hex/stripPrefix.ts +30 -0
- package/src/hex/toBigInt.spec.ts +74 -0
- package/src/hex/toBigInt.ts +19 -0
- package/src/hex/toBn.spec.ts +74 -0
- package/src/hex/toBn.ts +40 -0
- package/src/hex/toNumber.spec.ts +20 -0
- package/src/hex/toNumber.ts +24 -0
- package/src/hex/toString.spec.ts +20 -0
- package/src/hex/toString.ts +25 -0
- package/src/hex/toU8a.spec.ts +76 -0
- package/src/hex/toU8a.ts +68 -0
- package/src/hex/toU8aBuffer.spec.ts +38 -0
- package/src/hex/toU8aBuffer.ts +52 -0
- package/src/index.spec.ts +12 -0
- package/src/index.ts +6 -0
- package/src/is/array.spec.ts +20 -0
- package/src/is/array.ts +10 -0
- package/src/is/ascii.spec.ts +49 -0
- package/src/is/ascii.ts +52 -0
- package/src/is/bigInt.spec.ts +26 -0
- package/src/is/bigInt.ts +20 -0
- package/src/is/bn.spec.ts +21 -0
- package/src/is/bn.ts +23 -0
- package/src/is/boolean.spec.ts +26 -0
- package/src/is/boolean.ts +20 -0
- package/src/is/buffer.spec.ts +26 -0
- package/src/is/buffer.ts +28 -0
- package/src/is/childClass.spec.ts +36 -0
- package/src/is/childClass.ts +29 -0
- package/src/is/class.spec.ts +37 -0
- package/src/is/class.ts +12 -0
- package/src/is/codec.spec.ts +52 -0
- package/src/is/codec.ts +26 -0
- package/src/is/compact.spec.ts +27 -0
- package/src/is/compact.ts +19 -0
- package/src/is/error.spec.ts +20 -0
- package/src/is/error.ts +23 -0
- package/src/is/function.spec.ts +20 -0
- package/src/is/function.ts +23 -0
- package/src/is/helpers.ts +23 -0
- package/src/is/hex.spec.ts +77 -0
- package/src/is/hex.ts +36 -0
- package/src/is/index.ts +36 -0
- package/src/is/instanceOf.spec.ts +48 -0
- package/src/is/instanceOf.ts +24 -0
- package/src/is/ip.spec.ts +50 -0
- package/src/is/ip.ts +56 -0
- package/src/is/jsonObject.spec.ts +51 -0
- package/src/is/jsonObject.ts +45 -0
- package/src/is/null.spec.ts +20 -0
- package/src/is/null.ts +20 -0
- package/src/is/number.spec.ts +20 -0
- package/src/is/number.ts +20 -0
- package/src/is/object.spec.ts +32 -0
- package/src/is/object.ts +24 -0
- package/src/is/observable.spec.ts +26 -0
- package/src/is/observable.ts +22 -0
- package/src/is/promise.spec.ts +32 -0
- package/src/is/promise.ts +6 -0
- package/src/is/riscv.spec.ts +36 -0
- package/src/is/riscv.ts +27 -0
- package/src/is/string.spec.ts +32 -0
- package/src/is/string.ts +22 -0
- package/src/is/testChain.spec.ts +25 -0
- package/src/is/testChain.ts +12 -0
- package/src/is/toBigInt.spec.ts +22 -0
- package/src/is/toBigInt.ts +8 -0
- package/src/is/toBn.spec.ts +25 -0
- package/src/is/toBn.ts +8 -0
- package/src/is/u8a.spec.ts +42 -0
- package/src/is/u8a.ts +25 -0
- package/src/is/undefined.spec.ts +23 -0
- package/src/is/undefined.ts +21 -0
- package/src/is/utf8.spec.ts +42 -0
- package/src/is/utf8.ts +207 -0
- package/src/is/wasm.spec.ts +20 -0
- package/src/is/wasm.ts +17 -0
- package/src/lazy.spec.ts +71 -0
- package/src/lazy.ts +63 -0
- package/src/logger.spec.ts +188 -0
- package/src/logger.ts +160 -0
- package/src/memoize.spec.ts +79 -0
- package/src/memoize.ts +49 -0
- package/src/mod.ts +4 -0
- package/src/nextTick.ts +26 -0
- package/src/noop.ts +16 -0
- package/src/number/index.ts +9 -0
- package/src/number/toHex.spec.ts +44 -0
- package/src/number/toHex.ts +27 -0
- package/src/number/toU8a.spec.ts +50 -0
- package/src/number/toU8a.ts +25 -0
- package/src/object/clear.spec.ts +14 -0
- package/src/object/clear.ts +16 -0
- package/src/object/copy.spec.ts +17 -0
- package/src/object/copy.ts +12 -0
- package/src/object/entries.spec.ts +20 -0
- package/src/object/entries.ts +12 -0
- package/src/object/index.ts +10 -0
- package/src/object/keys.spec.ts +19 -0
- package/src/object/keys.ts +10 -0
- package/src/object/property.spec.ts +149 -0
- package/src/object/property.ts +39 -0
- package/src/object/spread.spec.ts +36 -0
- package/src/object/spread.ts +38 -0
- package/src/object/values.spec.ts +19 -0
- package/src/object/values.ts +10 -0
- package/src/packageDetect.ts +13 -0
- package/src/packageInfo.ts +6 -0
- package/src/promisify.spec.ts +50 -0
- package/src/promisify.ts +30 -0
- package/src/string/camelCase.spec.ts +119 -0
- package/src/string/camelCase.ts +79 -0
- package/src/string/index.ts +12 -0
- package/src/string/lowerFirst.spec.ts +41 -0
- package/src/string/lowerFirst.ts +46 -0
- package/src/string/pascalCase.spec.ts +26 -0
- package/src/string/shorten.spec.ts +38 -0
- package/src/string/shorten.ts +24 -0
- package/src/string/toHex.spec.ts +26 -0
- package/src/string/toHex.ts +27 -0
- package/src/string/toU8a.spec.ts +31 -0
- package/src/string/toU8a.ts +28 -0
- package/src/string/upperFirst.spec.ts +41 -0
- package/src/stringify.spec.ts +33 -0
- package/src/stringify.ts +20 -0
- package/src/test/index.ts +4 -0
- package/src/test/performance.ts +92 -0
- package/src/types.ts +100 -0
- package/src/u8a/cmp.spec.ts +62 -0
- package/src/u8a/cmp.ts +50 -0
- package/src/u8a/concat.spec.ts +42 -0
- package/src/u8a/concat.ts +60 -0
- package/src/u8a/concatBuffer.ts +34 -0
- package/src/u8a/empty.spec.ts +46 -0
- package/src/u8a/empty.ts +22 -0
- package/src/u8a/eq.spec.ts +113 -0
- package/src/u8a/eq.ts +46 -0
- package/src/u8a/fixLength.spec.ts +34 -0
- package/src/u8a/fixLength.ts +34 -0
- package/src/u8a/index.ts +22 -0
- package/src/u8a/sorted.spec.ts +20 -0
- package/src/u8a/sorted.ts +22 -0
- package/src/u8a/toBigInt.spec.ts +106 -0
- package/src/u8a/toBigInt.ts +100 -0
- package/src/u8a/toBn.spec.ts +106 -0
- package/src/u8a/toBn.ts +101 -0
- package/src/u8a/toBuffer.spec.ts +20 -0
- package/src/u8a/toBuffer.ts +28 -0
- package/src/u8a/toFloat.spec.ts +86 -0
- package/src/u8a/toFloat.ts +26 -0
- package/src/u8a/toHex.spec.ts +94 -0
- package/src/u8a/toHex.ts +68 -0
- package/src/u8a/toHexBuffer.spec.ts +63 -0
- package/src/u8a/toHexBuffer.ts +30 -0
- package/src/u8a/toNumber.spec.ts +47 -0
- package/src/u8a/toNumber.ts +80 -0
- package/src/u8a/toString.spec.ts +36 -0
- package/src/u8a/toString.ts +26 -0
- package/src/u8a/toU8a.spec.ts +63 -0
- package/src/u8a/toU8a.ts +46 -0
- package/src/u8a/wrap.spec.ts +139 -0
- package/src/u8a/wrap.ts +65 -0
- package/tsconfig.build.json +19 -0
- package/tsconfig.spec.json +17 -0
package/src/logger.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Logger } from './types.js';
|
|
5
|
+
|
|
6
|
+
import { xglobal } from '@pezkuwi/x-global';
|
|
7
|
+
|
|
8
|
+
import { formatDate } from './format/formatDate.js';
|
|
9
|
+
import { isBn } from './is/bn.js';
|
|
10
|
+
import { isBuffer } from './is/buffer.js';
|
|
11
|
+
import { isFunction } from './is/function.js';
|
|
12
|
+
import { isObject } from './is/object.js';
|
|
13
|
+
import { isU8a } from './is/u8a.js';
|
|
14
|
+
import { u8aToHex } from './u8a/toHex.js';
|
|
15
|
+
import { u8aToU8a } from './u8a/toU8a.js';
|
|
16
|
+
import { noop } from './noop.js';
|
|
17
|
+
|
|
18
|
+
type ConsoleType = 'error' | 'log' | 'warn';
|
|
19
|
+
type LogType = ConsoleType | 'debug';
|
|
20
|
+
|
|
21
|
+
const logTo = {
|
|
22
|
+
debug: 'log',
|
|
23
|
+
error: 'error',
|
|
24
|
+
log: 'log',
|
|
25
|
+
warn: 'warn'
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
function formatOther (value: unknown): unknown {
|
|
29
|
+
if (value && isObject(value) && value.constructor === Object) {
|
|
30
|
+
const result: Record<string, unknown> = {};
|
|
31
|
+
|
|
32
|
+
for (const [k, v] of Object.entries(value)) {
|
|
33
|
+
result[k] = loggerFormat(v);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function loggerFormat (value: unknown): unknown {
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
return value.map(loggerFormat);
|
|
45
|
+
} else if (isBn(value)) {
|
|
46
|
+
return value.toString();
|
|
47
|
+
} else if (isU8a(value) || isBuffer(value)) {
|
|
48
|
+
return u8aToHex(u8aToU8a(value));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return formatOther(value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function formatWithLength (maxLength: number): (v: unknown) => unknown {
|
|
55
|
+
return (v: unknown): unknown => {
|
|
56
|
+
if (maxLength <= 0) {
|
|
57
|
+
return v;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const r = `${v as string}`;
|
|
61
|
+
|
|
62
|
+
return r.length < maxLength
|
|
63
|
+
? v
|
|
64
|
+
: `${r.substring(0, maxLength)} ...`;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function apply (log: LogType, type: string, values: unknown[], maxSize = -1): void {
|
|
69
|
+
if (values.length === 1 && isFunction(values[0])) {
|
|
70
|
+
const fnResult = values[0]() as unknown;
|
|
71
|
+
|
|
72
|
+
return apply(log, type, Array.isArray(fnResult) ? fnResult : [fnResult], maxSize);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console[logTo[log]](
|
|
76
|
+
formatDate(new Date()),
|
|
77
|
+
type,
|
|
78
|
+
...values
|
|
79
|
+
.map(loggerFormat)
|
|
80
|
+
.map(formatWithLength(maxSize))
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isDebugOn (e: string, type: string): boolean {
|
|
85
|
+
return !!e && (
|
|
86
|
+
e === '*' ||
|
|
87
|
+
type === e ||
|
|
88
|
+
(
|
|
89
|
+
e.endsWith('*') &&
|
|
90
|
+
type.startsWith(e.slice(0, -1))
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isDebugOff (e: string, type: string): boolean {
|
|
96
|
+
return !!e && (
|
|
97
|
+
e.startsWith('-') &&
|
|
98
|
+
(
|
|
99
|
+
type === e.slice(1) ||
|
|
100
|
+
(
|
|
101
|
+
e.endsWith('*') &&
|
|
102
|
+
type.startsWith(e.slice(1, -1))
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getDebugFlag (env: readonly string[], type: string): boolean {
|
|
109
|
+
let flag = false;
|
|
110
|
+
|
|
111
|
+
for (const e of env) {
|
|
112
|
+
if (isDebugOn(e, type)) {
|
|
113
|
+
flag = true;
|
|
114
|
+
} else if (isDebugOff(e, type)) {
|
|
115
|
+
flag = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return flag;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function parseEnv (type: string): [boolean, number] {
|
|
123
|
+
const maxSize = parseInt(xglobal.process?.env?.['DEBUG_MAX'] || '-1', 10);
|
|
124
|
+
|
|
125
|
+
return [
|
|
126
|
+
getDebugFlag((xglobal.process?.env?.['DEBUG'] || '').toLowerCase().split(','), type),
|
|
127
|
+
isNaN(maxSize)
|
|
128
|
+
? -1
|
|
129
|
+
: maxSize
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @name Logger
|
|
135
|
+
* @summary Creates a consistent log interface for messages
|
|
136
|
+
* @description
|
|
137
|
+
* Returns a `Logger` that has `.log`, `.error`, `.warn` and `.debug` (controlled with environment `DEBUG=typeA,typeB`) methods. Logging is done with a consistent prefix (type of logger, date) followed by the actual message using the underlying console.
|
|
138
|
+
* @example
|
|
139
|
+
* <BR>
|
|
140
|
+
*
|
|
141
|
+
* ```javascript
|
|
142
|
+
* import { logger } from '@pezkuwi/util';
|
|
143
|
+
*
|
|
144
|
+
* const l = logger('test');
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export function logger (origin: string): Logger {
|
|
148
|
+
const type = `${origin.toUpperCase()}:`.padStart(16);
|
|
149
|
+
const [isDebug, maxSize] = parseEnv(origin.toLowerCase());
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
debug: isDebug
|
|
153
|
+
? (...values: unknown[]) => apply('debug', type, values, maxSize)
|
|
154
|
+
: noop,
|
|
155
|
+
error: (...values: unknown[]) => apply('error', type, values),
|
|
156
|
+
log: (...values: unknown[]) => apply('log', type, values),
|
|
157
|
+
noop,
|
|
158
|
+
warn: (...values: unknown[]) => apply('warn', type, values)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { memoize } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('memoize', (): void => {
|
|
9
|
+
it('returns actual values', (): void => {
|
|
10
|
+
const fn = memoize(() => 5);
|
|
11
|
+
|
|
12
|
+
expect(fn()).toEqual(5);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('caches executions', (): void => {
|
|
16
|
+
const spy = jest.fn((a: number, b: number) => a + b);
|
|
17
|
+
const fn = memoize(spy);
|
|
18
|
+
|
|
19
|
+
expect(fn(2, 4)).toEqual(6);
|
|
20
|
+
expect(fn(2, 4)).toEqual(6);
|
|
21
|
+
|
|
22
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
23
|
+
|
|
24
|
+
expect(fn(4, 2)).toEqual(6);
|
|
25
|
+
|
|
26
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('does unmemoize', (): void => {
|
|
30
|
+
const spy = jest.fn((a: number, b: number) => a + b);
|
|
31
|
+
const fn = memoize(spy);
|
|
32
|
+
|
|
33
|
+
expect(fn(2, 4)).toEqual(6);
|
|
34
|
+
expect(fn(4, 2)).toEqual(6);
|
|
35
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
36
|
+
|
|
37
|
+
fn.unmemoize(2, 4);
|
|
38
|
+
|
|
39
|
+
expect(fn(2, 4)).toEqual(6);
|
|
40
|
+
expect(fn(4, 2)).toEqual(6);
|
|
41
|
+
expect(spy).toHaveBeenCalledTimes(3);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('manages separate instances', (): void => {
|
|
45
|
+
let instanceId = 'a';
|
|
46
|
+
const spy = jest.fn((a: number, b: number) => a + b);
|
|
47
|
+
const fn = memoize(spy, { getInstanceId: () => instanceId });
|
|
48
|
+
|
|
49
|
+
expect(fn(1, 3)).toEqual(4);
|
|
50
|
+
|
|
51
|
+
instanceId = 'b';
|
|
52
|
+
|
|
53
|
+
expect(fn(1, 3)).toEqual(4);
|
|
54
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
55
|
+
|
|
56
|
+
instanceId = 'a';
|
|
57
|
+
|
|
58
|
+
expect(fn(1, 3)).toEqual(4);
|
|
59
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
60
|
+
|
|
61
|
+
instanceId = 'b';
|
|
62
|
+
fn.unmemoize(1, 3);
|
|
63
|
+
|
|
64
|
+
expect(fn(1, 3)).toEqual(4);
|
|
65
|
+
expect(spy).toHaveBeenCalledTimes(3);
|
|
66
|
+
|
|
67
|
+
instanceId = 'a';
|
|
68
|
+
fn.unmemoize(1, 3);
|
|
69
|
+
|
|
70
|
+
expect(fn(1, 3)).toEqual(4);
|
|
71
|
+
expect(spy).toHaveBeenCalledTimes(4);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('normalizes BigInt values as well', (): void => {
|
|
75
|
+
const fn = memoize((a: bigint, b: bigint) => a + b);
|
|
76
|
+
|
|
77
|
+
expect(fn(1n, 2n).toString()).toEqual('3');
|
|
78
|
+
});
|
|
79
|
+
});
|
package/src/memoize.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Memoized } from './types.js';
|
|
5
|
+
|
|
6
|
+
import { stringify } from './stringify.js';
|
|
7
|
+
|
|
8
|
+
interface Options {
|
|
9
|
+
getInstanceId?: () => string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function defaultGetId (): string {
|
|
13
|
+
return 'none';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @name memoize
|
|
18
|
+
* @description Memomize the function with a specific instanceId
|
|
19
|
+
*/
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
export function memoize <T, F extends (...args: any[]) => T> (fn: F, { getInstanceId = defaultGetId }: Options = {}): Memoized<F> {
|
|
22
|
+
const cache: Record<string, Record<string, T>> = {};
|
|
23
|
+
|
|
24
|
+
const memoized = (...args: unknown[]): T => {
|
|
25
|
+
const stringParams = stringify(args);
|
|
26
|
+
const instanceId = getInstanceId();
|
|
27
|
+
|
|
28
|
+
if (!cache[instanceId]) {
|
|
29
|
+
cache[instanceId] = {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (cache[instanceId][stringParams] === undefined) {
|
|
33
|
+
cache[instanceId][stringParams] = fn(...args);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return cache[instanceId][stringParams];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
memoized.unmemoize = (...args: unknown[]): void => {
|
|
40
|
+
const stringParams = stringify(args);
|
|
41
|
+
const instanceId = getInstanceId();
|
|
42
|
+
|
|
43
|
+
if (cache[instanceId]?.[stringParams] !== undefined) {
|
|
44
|
+
delete cache[instanceId][stringParams];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return memoized as Memoized<F>;
|
|
49
|
+
}
|
package/src/mod.ts
ADDED
package/src/nextTick.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @name nextTick
|
|
6
|
+
* @description Defer the operation to the queue for evaluation on the next tick
|
|
7
|
+
*/
|
|
8
|
+
export function nextTick (onExec: () => unknown, onError?: (error: Error) => unknown): void {
|
|
9
|
+
// While Promise.resolve().then(...) would defer to the nextTick, this
|
|
10
|
+
// actually does not play as nicely in browsers like the setTimeout(...)
|
|
11
|
+
// approach. So the safer, though less optimal approach is the one taken here
|
|
12
|
+
setTimeout((): void => {
|
|
13
|
+
Promise
|
|
14
|
+
.resolve()
|
|
15
|
+
.then((): void => {
|
|
16
|
+
onExec();
|
|
17
|
+
})
|
|
18
|
+
.catch((error: Error): void => {
|
|
19
|
+
if (onError) {
|
|
20
|
+
onError(error);
|
|
21
|
+
} else {
|
|
22
|
+
console.error(error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}, 0);
|
|
26
|
+
}
|
package/src/noop.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A sharable identity function. Returns the input as-is with no transformation applied.
|
|
6
|
+
*/
|
|
7
|
+
export function identity <T> (value: T): T {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A sharable noop function. As the name suggests, does nothing
|
|
13
|
+
*/
|
|
14
|
+
export function noop (): void {
|
|
15
|
+
// noop
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @summary Utility methods to convert to and from `number` values
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { numberToHex } from './toHex.js';
|
|
9
|
+
export { numberToU8a } from './toU8a.js';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { numberToHex } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('numberToHex', (): void => {
|
|
9
|
+
it('converts undefined to 0x00', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
numberToHex()
|
|
12
|
+
).toEqual('0x00');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('converts null to 0x00000000 (with bitLength)', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
numberToHex(null, 32)
|
|
18
|
+
).toEqual('0x00000000');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('converts Nan to 0x', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
numberToHex(NaN)
|
|
24
|
+
).toEqual('0x00');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('converts 0 to 0x00', (): void => {
|
|
28
|
+
expect(
|
|
29
|
+
numberToHex(0)
|
|
30
|
+
).toEqual('0x00');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('converts number to hex', (): void => {
|
|
34
|
+
expect(
|
|
35
|
+
numberToHex(0x1245)
|
|
36
|
+
).toEqual('0x1245');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('converts number to hex (specfified bitLength)', (): void => {
|
|
40
|
+
expect(
|
|
41
|
+
numberToHex(0x1245, 32)
|
|
42
|
+
).toEqual('0x00001245');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { HexString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { hexFixLength } from '../hex/fixLength.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @name numberToHex
|
|
10
|
+
* @summary Creates a hex value from a number.
|
|
11
|
+
* @description
|
|
12
|
+
* `null`/`undefined`/`NaN` inputs returns an empty `0x` result. `number` input values return the actual bytes value converted to a `hex`. With `bitLength` set, it converts the number to the equivalent size.
|
|
13
|
+
* @example
|
|
14
|
+
* <BR>
|
|
15
|
+
*
|
|
16
|
+
* ```javascript
|
|
17
|
+
* import { numberToHex } from '@pezkuwi/util';
|
|
18
|
+
*
|
|
19
|
+
* numberToHex(0x1234); // => '0x1234'
|
|
20
|
+
* numberToHex(0x1234, 32); // => 0x00001234
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function numberToHex (value?: number | null, bitLength = -1): HexString {
|
|
24
|
+
const hex = (!value || Number.isNaN(value) ? 0 : value).toString(16);
|
|
25
|
+
|
|
26
|
+
return hexFixLength(hex.length % 2 ? `0${hex}` : hex, bitLength, true);
|
|
27
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { numberToU8a } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('numberToU8a', (): void => {
|
|
9
|
+
it('converts undefined to empty', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
numberToU8a()
|
|
12
|
+
).toEqual(new Uint8Array(1));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('converts null to empty', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
numberToU8a(null)
|
|
18
|
+
).toEqual(new Uint8Array(1));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('converts NaN to empty', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
numberToU8a(NaN)
|
|
24
|
+
).toEqual(new Uint8Array(1));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('converts 0 to u8a', (): void => {
|
|
28
|
+
expect(
|
|
29
|
+
numberToU8a(0)
|
|
30
|
+
).toEqual(new Uint8Array([0]));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('converts 0 to u8a (with length)', (): void => {
|
|
34
|
+
expect(
|
|
35
|
+
numberToU8a(0, 16)
|
|
36
|
+
).toEqual(new Uint8Array([0, 0]));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('converts values to the u8a', (): void => {
|
|
40
|
+
expect(
|
|
41
|
+
numberToU8a(0x3456)
|
|
42
|
+
).toEqual(new Uint8Array([0x34, 0x56]));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('converts values to the u8a (bitLength)', (): void => {
|
|
46
|
+
expect(
|
|
47
|
+
numberToU8a(0x3456, 32)
|
|
48
|
+
).toEqual(new Uint8Array([0x00, 0x00, 0x34, 0x56]));
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { hexToU8a } from '../hex/toU8a.js';
|
|
5
|
+
import { numberToHex } from './toHex.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @name numberToU8a
|
|
9
|
+
* @summary Creates a Uint8Array object from a number.
|
|
10
|
+
* @description
|
|
11
|
+
* `null`/`undefined`/`NaN` inputs returns an empty `Uint8Array` result. `number` input values return the actual bytes value converted to a `Uint8Array`. With `bitLength`, it converts the value to the equivalent size.
|
|
12
|
+
* @example
|
|
13
|
+
* <BR>
|
|
14
|
+
*
|
|
15
|
+
* ```javascript
|
|
16
|
+
* import { numberToU8a } from '@pezkuwi/util';
|
|
17
|
+
*
|
|
18
|
+
* numberToU8a(0x1234); // => [0x12, 0x34]
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function numberToU8a (value?: number | null, bitLength = -1): Uint8Array {
|
|
22
|
+
return hexToU8a(
|
|
23
|
+
numberToHex(value, bitLength)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { objectClear } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('objectClear', (): void => {
|
|
9
|
+
it('clears an object', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
objectClear({ a: 1, b: 2, c: { d: 3, e: 4 } })
|
|
12
|
+
).toEqual({});
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @name objectClear
|
|
6
|
+
* @summary Removes all the keys from the input object
|
|
7
|
+
*/
|
|
8
|
+
export function objectClear <T> (value: Record<string, T>): Record<string, T> {
|
|
9
|
+
const keys = Object.keys(value);
|
|
10
|
+
|
|
11
|
+
for (let i = 0, count = keys.length; i < count; i++) {
|
|
12
|
+
delete value[keys[i]];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { objectCopy } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('objectCopy', (): void => {
|
|
9
|
+
it('makes a shallow copy of the object', (): void => {
|
|
10
|
+
const a = { a: 1, b: 2, c: { d: 3, e: 4 } };
|
|
11
|
+
const b = objectCopy(a);
|
|
12
|
+
|
|
13
|
+
expect(a).toEqual(b);
|
|
14
|
+
expect(a === b).toEqual(false);
|
|
15
|
+
expect(a.c === b.c).toEqual(true);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { objectSpread } from './spread.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name objectCopy
|
|
8
|
+
* @summary Creates a shallow clone of the input object
|
|
9
|
+
*/
|
|
10
|
+
export function objectCopy <T extends object> (source: T): T {
|
|
11
|
+
return objectSpread({}, source);
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { objectEntries } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('objectEntries', (): void => {
|
|
9
|
+
it('extracts all entries', (): void => {
|
|
10
|
+
const o = { a: 1, b: 2, c: 3 };
|
|
11
|
+
const entries = objectEntries(o);
|
|
12
|
+
|
|
13
|
+
expect(entries).toEqual([['a', 1], ['b', 2], ['c', 3]]);
|
|
14
|
+
|
|
15
|
+
for (const [k, v] of entries) {
|
|
16
|
+
expect(k).toBeDefined();
|
|
17
|
+
expect(v).toBeDefined();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T][];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name objectEntries
|
|
8
|
+
* @summary A version of Object.entries that is typed for TS
|
|
9
|
+
*/
|
|
10
|
+
export function objectEntries<T extends object> (obj: T): Entries<T> {
|
|
11
|
+
return Object.entries(obj) as Entries<T>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export { objectClear } from './clear.js';
|
|
5
|
+
export { objectCopy } from './copy.js';
|
|
6
|
+
export { objectEntries } from './entries.js';
|
|
7
|
+
export { objectKeys } from './keys.js';
|
|
8
|
+
export { objectProperties, objectProperty } from './property.js';
|
|
9
|
+
export { objectSpread } from './spread.js';
|
|
10
|
+
export { objectValues } from './values.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { objectKeys } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('objectKeys', (): void => {
|
|
9
|
+
it('extracts all keys', (): void => {
|
|
10
|
+
const o = { a: 1, b: 2, c: 3 };
|
|
11
|
+
const keys = objectKeys(o);
|
|
12
|
+
|
|
13
|
+
expect(keys).toEqual(['a', 'b', 'c']);
|
|
14
|
+
|
|
15
|
+
for (const k of keys) {
|
|
16
|
+
expect(o[k]).toBeDefined();
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @name objectKeys
|
|
6
|
+
* @summary A version of Object.keys that is typed for TS
|
|
7
|
+
*/
|
|
8
|
+
export function objectKeys<T extends object, K extends Extract<keyof T, string>> (value: T): K[] {
|
|
9
|
+
return Object.keys(value) as K[];
|
|
10
|
+
}
|