@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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AnyString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { CC_TO_LO, CC_TO_UP } from './camelCase.js';
|
|
7
|
+
|
|
8
|
+
/** @internal */
|
|
9
|
+
function converter (map: readonly string[]): (value?: AnyString | null) => string {
|
|
10
|
+
return (value?: AnyString | null): string =>
|
|
11
|
+
value
|
|
12
|
+
? map[value.charCodeAt(0)] + value.slice(1)
|
|
13
|
+
: '';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @name stringLowerFirst
|
|
18
|
+
* @summary Lowercase the first letter of a string
|
|
19
|
+
* @description
|
|
20
|
+
* Lowercase the first letter of a string
|
|
21
|
+
* @example
|
|
22
|
+
* <BR>
|
|
23
|
+
*
|
|
24
|
+
* ```javascript
|
|
25
|
+
* import { stringLowerFirst } from '@pezkuwi/util';
|
|
26
|
+
*
|
|
27
|
+
* stringLowerFirst('ABC'); // => 'aBC'
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const stringLowerFirst = /*#__PURE__*/ converter(CC_TO_LO);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @name stringUpperFirst
|
|
34
|
+
* @summary Uppercase the first letter of a string
|
|
35
|
+
* @description
|
|
36
|
+
* Lowercase the first letter of a string
|
|
37
|
+
* @example
|
|
38
|
+
* <BR>
|
|
39
|
+
*
|
|
40
|
+
* ```javascript
|
|
41
|
+
* import { stringUpperFirst } from '@pezkuwi/util';
|
|
42
|
+
*
|
|
43
|
+
* stringUpperFirst('abc'); // => 'Abc'
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const stringUpperFirst = /*#__PURE__*/ converter(CC_TO_UP);
|
|
@@ -0,0 +1,26 @@
|
|
|
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 { stringPascalCase } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('stringPascalCase', (): void => {
|
|
9
|
+
it('works correctly', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
stringPascalCase('Snake_case-something spaced')
|
|
12
|
+
).toBe('SnakeCaseSomethingSpaced');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('works correctly for String (class)', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
stringPascalCase(String('foo_bar-- __baz Bob'))
|
|
18
|
+
).toBe('FooBarBazBob');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('adjusts all-uppercase + digits', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
stringPascalCase('UUID64')
|
|
24
|
+
).toEqual('Uuid64');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
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 { stringShorten } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('stringShorten', (): void => {
|
|
9
|
+
it('returns the value as-is when <= maxLength', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
stringShorten('0123456789', 4)
|
|
12
|
+
).toEqual('0123456789');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns the shortened value when > maxLength', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
stringShorten('0123456789', 3)
|
|
18
|
+
).toEqual('012…789');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('returns the shortened value when > maxLength (String)', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
stringShorten(String('0123456789'), 3)
|
|
24
|
+
).toEqual('012…789');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns the value as-is when <= maxLength (defaults)', (): void => {
|
|
28
|
+
expect(
|
|
29
|
+
stringShorten('012345', 4)
|
|
30
|
+
).toEqual('012345');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('returns the shortened value when > maxLength (defaults)', (): void => {
|
|
34
|
+
expect(
|
|
35
|
+
stringShorten('01234567890123456789')
|
|
36
|
+
).toEqual('012345…456789');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AnyString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name stringShorten
|
|
8
|
+
* @summary Returns a string with maximum length
|
|
9
|
+
* @description
|
|
10
|
+
* Checks the string against the `prefixLength`, if longer than double this, shortens it by placing `..` in the middle of it
|
|
11
|
+
* @example
|
|
12
|
+
* <BR>
|
|
13
|
+
*
|
|
14
|
+
* ```javascript
|
|
15
|
+
* import { stringShorten } from '@pezkuwi/util';
|
|
16
|
+
*
|
|
17
|
+
* stringShorten('1234567890', 2); // => 12..90
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function stringShorten (value: AnyString, prefixLength = 6): string {
|
|
21
|
+
return value.length <= 2 + 2 * prefixLength
|
|
22
|
+
? value.toString()
|
|
23
|
+
: `${value.substring(0, prefixLength)}…${value.slice(-prefixLength)}`;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 { stringToHex } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('hexToString', (): void => {
|
|
9
|
+
it('converts an empty to ""', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
stringToHex()
|
|
12
|
+
).toEqual('0x');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('converts to a hex from string', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
stringToHex('hello')
|
|
18
|
+
).toEqual('0x68656c6c6f');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('converts to a hex from String', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
stringToHex(String('hello'))
|
|
24
|
+
).toEqual('0x68656c6c6f');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AnyString, HexString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { u8aToHex } from '../u8a/toHex.js';
|
|
7
|
+
import { stringToU8a } from './toU8a.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @name stringToHex
|
|
11
|
+
* @summary Creates a hex string from a utf-8 string
|
|
12
|
+
* @description
|
|
13
|
+
* String input values return the actual encoded hex value.
|
|
14
|
+
* @example
|
|
15
|
+
* <BR>
|
|
16
|
+
*
|
|
17
|
+
* ```javascript
|
|
18
|
+
* import { stringToHex } from '@pezkuwi/util';
|
|
19
|
+
*
|
|
20
|
+
* stringToU8a('hello'); // 0x68656c6c6f
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function stringToHex (value?: AnyString): HexString {
|
|
24
|
+
return u8aToHex(
|
|
25
|
+
stringToU8a(value)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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 { stringToU8a } from '../index.js';
|
|
7
|
+
|
|
8
|
+
const RUSS_HELLO = new Uint8Array([208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 44, 32, 208, 188, 208, 184, 209, 128, 33]);
|
|
9
|
+
|
|
10
|
+
describe('stringToU8a', (): void => {
|
|
11
|
+
it('decodes to an empty string for undefined/null', (): void => {
|
|
12
|
+
expect(
|
|
13
|
+
stringToU8a()
|
|
14
|
+
).toEqual(new Uint8Array());
|
|
15
|
+
expect(
|
|
16
|
+
stringToU8a(null)
|
|
17
|
+
).toEqual(new Uint8Array());
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('encodes the string correctly', (): void => {
|
|
21
|
+
expect(
|
|
22
|
+
stringToU8a('Привет, мир!')
|
|
23
|
+
).toEqual(RUSS_HELLO);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('encodes the string correctly (String)', (): void => {
|
|
27
|
+
expect(
|
|
28
|
+
stringToU8a(String('Привет, мир!'))
|
|
29
|
+
).toEqual(RUSS_HELLO);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AnyString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { TextEncoder } from '@pezkuwi/x-textencoder';
|
|
7
|
+
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @name stringToU8a
|
|
12
|
+
* @summary Creates a Uint8Array object from a utf-8 string.
|
|
13
|
+
* @description
|
|
14
|
+
* String input values return the actual encoded `UInt8Array`. `null` or `undefined` values returns an empty encoded array.
|
|
15
|
+
* @example
|
|
16
|
+
* <BR>
|
|
17
|
+
*
|
|
18
|
+
* ```javascript
|
|
19
|
+
* import { stringToU8a } from '@pezkuwi/util';
|
|
20
|
+
*
|
|
21
|
+
* stringToU8a('hello'); // [0x68, 0x65, 0x6c, 0x6c, 0x6f]
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function stringToU8a (value?: AnyString | null): Uint8Array {
|
|
25
|
+
return value
|
|
26
|
+
? encoder.encode(value.toString())
|
|
27
|
+
: new Uint8Array();
|
|
28
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 { perf } from '../test/index.js';
|
|
7
|
+
import { stringUpperFirst } from './index.js';
|
|
8
|
+
|
|
9
|
+
describe('stringUpperFirst', (): void => {
|
|
10
|
+
it("uppers the first letter if it's a capital letter", (): void => {
|
|
11
|
+
expect(
|
|
12
|
+
stringUpperFirst('ABC')
|
|
13
|
+
).toBe('ABC');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("uppers the first letter if it's a lowercase letter", (): void => {
|
|
17
|
+
expect(
|
|
18
|
+
stringUpperFirst('abc')
|
|
19
|
+
).toBe('Abc');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("uppers the first letter if it's a lowercase letter (String)", (): void => {
|
|
23
|
+
expect(
|
|
24
|
+
stringUpperFirst(String('abc'))
|
|
25
|
+
).toBe('Abc');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('returns undefined as empty', (): void => {
|
|
29
|
+
expect(
|
|
30
|
+
stringUpperFirst()
|
|
31
|
+
).toBe('');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('returns null as empty', (): void => {
|
|
35
|
+
expect(
|
|
36
|
+
stringUpperFirst(null)
|
|
37
|
+
).toBe('');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
perf('stringUpperFirst', 1_000_000, [['helloWorldSomething']], stringUpperFirst);
|
|
41
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
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 { BN } from './bn/index.js';
|
|
7
|
+
import { stringify } from './stringify.js';
|
|
8
|
+
|
|
9
|
+
describe('stringify', (): void => {
|
|
10
|
+
it('stringifies a BigInt', (): void => {
|
|
11
|
+
expect(
|
|
12
|
+
stringify(1234n)
|
|
13
|
+
).toEqual('"1234"');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('stringifies an array of values', (): void => {
|
|
17
|
+
expect(
|
|
18
|
+
stringify(['a', 1, 2n, new BN(69)])
|
|
19
|
+
).toEqual('["a",1,"2","45"]');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('stringifies an array of values (with spaces)', (): void => {
|
|
23
|
+
expect(
|
|
24
|
+
stringify(['a', 1, 2n, new BN(3)], 2)
|
|
25
|
+
).toEqual('[\n "a",\n 1,\n "2",\n "03"\n]');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('stringifies a nested object', (): void => {
|
|
29
|
+
expect(
|
|
30
|
+
stringify({ a: 'a', b: 1, c: { d: 2n, e: new BN(3) } })
|
|
31
|
+
).toEqual('{"a":"a","b":1,"c":{"d":"2","e":"03"}}');
|
|
32
|
+
});
|
|
33
|
+
});
|
package/src/stringify.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { isBigInt } from './is/bigInt.js';
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
function replacer (_: unknown, v: unknown): unknown {
|
|
8
|
+
return isBigInt(v)
|
|
9
|
+
? v.toString()
|
|
10
|
+
: v;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @name stringify
|
|
15
|
+
* @summary Performs a JSON.stringify, with BigInt handling
|
|
16
|
+
* @description A wrapper for JSON.stringify that handles BigInt values transparently, converting them to string. No differences from the native JSON.stringify function otherwise.
|
|
17
|
+
*/
|
|
18
|
+
export function stringify (value: unknown, space?: string | number): string {
|
|
19
|
+
return JSON.stringify(value, replacer, space);
|
|
20
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
/* global it, expect */
|
|
7
|
+
|
|
8
|
+
import { formatDecimal, formatNumber, stringify } from '../index.js';
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
type ExecFn = (...params: any[]) => unknown;
|
|
12
|
+
|
|
13
|
+
const NUM_PAD = 16;
|
|
14
|
+
const PRE_PAD = 32;
|
|
15
|
+
|
|
16
|
+
function loop (exec: ExecFn, count: number, inputs: readonly unknown[][]): [number, unknown[]] {
|
|
17
|
+
const start = performance.now();
|
|
18
|
+
const results = new Array<unknown>(inputs.length);
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < count; i++) {
|
|
21
|
+
const result = exec(...inputs[i % inputs.length]);
|
|
22
|
+
|
|
23
|
+
if (i < inputs.length) {
|
|
24
|
+
results[i] = result;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return [performance.now() - start, results];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function formatFixed (value: number): string {
|
|
32
|
+
const [a, b] = value.toFixed(2).split('.');
|
|
33
|
+
|
|
34
|
+
return [formatDecimal(a), b].join('.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function formatOps (count: number, time: number): string {
|
|
38
|
+
const micro = (time * 1000) / count;
|
|
39
|
+
const ops = 1_000_000 / micro;
|
|
40
|
+
|
|
41
|
+
return `
|
|
42
|
+
${formatFixed(ops).padStart(NUM_PAD + PRE_PAD + 1)} ops/s
|
|
43
|
+
${formatFixed(micro).padStart(NUM_PAD + PRE_PAD + 1)} μs/op`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function perf (name: string, count: number, inputs: readonly unknown[][], exec: ExecFn, withLog?: boolean): void {
|
|
47
|
+
const test = process.env['GITHUB_REPOSITORY']
|
|
48
|
+
? it.skip
|
|
49
|
+
: it;
|
|
50
|
+
|
|
51
|
+
test(`performance: ${name}`, (): void => {
|
|
52
|
+
const [time, results] = loop(exec, count, inputs);
|
|
53
|
+
|
|
54
|
+
console.error(`
|
|
55
|
+
performance run for ${name} completed with ${formatNumber(count)} iterations.
|
|
56
|
+
|
|
57
|
+
${`${name}:`.padStart(PRE_PAD)} ${time.toFixed(2).padStart(NUM_PAD)} ms${formatOps(count, time)}
|
|
58
|
+
`);
|
|
59
|
+
|
|
60
|
+
if (withLog) {
|
|
61
|
+
console.log(results);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function perfCmp (name: string, [first, second]: [string, string], count: number, inputs: readonly unknown[][], exec: ExecFn): void {
|
|
67
|
+
const test = process.env['GITHUB_REPOSITORY']
|
|
68
|
+
? it.skip
|
|
69
|
+
: it;
|
|
70
|
+
|
|
71
|
+
test(`performance: ${name}`, (): void => {
|
|
72
|
+
const [[t1, r1], [t2, r2]] = [false, true].map((flag) =>
|
|
73
|
+
loop(exec, count, inputs.map((values) =>
|
|
74
|
+
[...values, flag]
|
|
75
|
+
))
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
console.error(`
|
|
79
|
+
performance run for ${name} completed with ${formatNumber(count)} iterations.
|
|
80
|
+
|
|
81
|
+
${`${first}:`.padStart(PRE_PAD)} ${t1.toFixed(2).padStart(NUM_PAD)} ms ${t1 < t2 ? '(fastest)' : `(slowest, ${(t1 / t2).toFixed(2)}x)`}${formatOps(count, t1)}
|
|
82
|
+
|
|
83
|
+
${`${second}:`.padStart(PRE_PAD)} ${t2.toFixed(2).padStart(NUM_PAD)} ms ${t1 > t2 ? '(fastest)' : `(slowest, ${(t2 / t1).toFixed(2)}x)`}${formatOps(count, t2)}
|
|
84
|
+
`);
|
|
85
|
+
|
|
86
|
+
expect(
|
|
87
|
+
r1.filter((_, i) =>
|
|
88
|
+
stringify(r1[i]) !== stringify(r2[i])
|
|
89
|
+
)
|
|
90
|
+
).toHaveLength(0);
|
|
91
|
+
});
|
|
92
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { BN } from './bn/bn.js';
|
|
5
|
+
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
|
|
8
|
+
/** An interface that defines an actual JS class */
|
|
9
|
+
export interface Class<T = any, A extends unknown[] = any[]> {
|
|
10
|
+
prototype: T;
|
|
11
|
+
|
|
12
|
+
new (...args: A): T;
|
|
13
|
+
|
|
14
|
+
hasOwnProperty (prop: string): boolean;
|
|
15
|
+
isPrototypeOf (other: unknown): boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// @deprecated Use Class<T, A> instead
|
|
19
|
+
export type Constructor<T = any, A extends unknown[] = any[]> = Class<T, A>;
|
|
20
|
+
|
|
21
|
+
export interface ToBigInt {
|
|
22
|
+
toBigInt: () => bigint;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ToBn {
|
|
26
|
+
toBn: () => BN;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SiDef {
|
|
30
|
+
power: number;
|
|
31
|
+
text: string;
|
|
32
|
+
value: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface Logger {
|
|
36
|
+
debug: (...values: unknown[]) => void;
|
|
37
|
+
error: (...values: unknown[]) => void;
|
|
38
|
+
log: (...values: unknown[]) => void;
|
|
39
|
+
noop: (...values: unknown[]) => void;
|
|
40
|
+
warn: (...values: unknown[]) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ToBnOptions {
|
|
44
|
+
/** Convert in LE format */
|
|
45
|
+
isLe?: boolean;
|
|
46
|
+
/** Number is signed, apply two's complement */
|
|
47
|
+
isNegative?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface NumberOptions extends ToBnOptions {
|
|
51
|
+
/** Limit to the specified bitLength, despite input length */
|
|
52
|
+
bitLength?: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface Time {
|
|
56
|
+
days: number;
|
|
57
|
+
hours: number;
|
|
58
|
+
minutes: number;
|
|
59
|
+
seconds: number;
|
|
60
|
+
milliseconds: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type Memoized<F> = F & {
|
|
64
|
+
unmemoize: (...args: unknown[]) => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
68
|
+
export type AnyString = string | String;
|
|
69
|
+
|
|
70
|
+
export type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
|
|
71
|
+
|
|
72
|
+
// One day when template strings support regex, we can improve this
|
|
73
|
+
export type HexString = `0x${string}`;
|
|
74
|
+
|
|
75
|
+
// BufferObject interface compatible with Buffer since we don't want to require
|
|
76
|
+
// references to the Buffer types from the node typings
|
|
77
|
+
//
|
|
78
|
+
// Caveat: the references still do sneak in in the d.ts files, specifically
|
|
79
|
+
// inside u8a/toBuffer & is/buffer (but not in compiled outputs)
|
|
80
|
+
export interface BufferObject extends Uint8Array {
|
|
81
|
+
// Possibly used externally via type imports
|
|
82
|
+
equals: (otherBuffer: Uint8Array) => boolean;
|
|
83
|
+
// As used in is/buffer
|
|
84
|
+
readDoubleLE: (offset?: number) => number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// We define a scappy low-level interface to mock Buffer
|
|
88
|
+
// (this removes the need for the node typings in built bundles)
|
|
89
|
+
export interface BufferClass extends Class<BufferObject> {
|
|
90
|
+
// As used in u8a/toBuffer
|
|
91
|
+
from: <T = BufferObject>(value: unknown) => T;
|
|
92
|
+
// As used in is/buffer
|
|
93
|
+
isBuffer: (value: unknown) => boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type U8aLike = number[] | Uint8Array | AnyString;
|
|
97
|
+
|
|
98
|
+
export interface Observable {
|
|
99
|
+
next: (...params: unknown[]) => unknown;
|
|
100
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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 { perf } from '../test/index.js';
|
|
7
|
+
import { u8aCmp } from './index.js';
|
|
8
|
+
|
|
9
|
+
const ltest = new Uint8Array(32768);
|
|
10
|
+
const stest = new Uint8Array(256);
|
|
11
|
+
const ztest = new Uint8Array(64);
|
|
12
|
+
|
|
13
|
+
for (let i = 0, count = ltest.length; i < count; i++) {
|
|
14
|
+
if (i < ztest.length) {
|
|
15
|
+
ztest[i] = i % 256;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (i < stest.length) {
|
|
19
|
+
stest[i] = i % 256;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ltest[i] = i % 256;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('u8aCmp', (): void => {
|
|
26
|
+
it('has the same result as localCompare (equal length)', (): void => {
|
|
27
|
+
const a = 'test abc';
|
|
28
|
+
const b = 'test def';
|
|
29
|
+
|
|
30
|
+
expect(
|
|
31
|
+
u8aCmp(a, b)
|
|
32
|
+
).toEqual(a.localeCompare(b));
|
|
33
|
+
expect(
|
|
34
|
+
u8aCmp(b, a)
|
|
35
|
+
).toEqual(b.localeCompare(a));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('has the same result as localCompare (diff length)', (): void => {
|
|
39
|
+
const a = 'test';
|
|
40
|
+
const b = 'test abc';
|
|
41
|
+
|
|
42
|
+
expect(
|
|
43
|
+
u8aCmp(a, b)
|
|
44
|
+
).toEqual(a.localeCompare(b));
|
|
45
|
+
expect(
|
|
46
|
+
u8aCmp(b, a)
|
|
47
|
+
).toEqual(b.localeCompare(a));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('compares between string and Uint8Array', (): void => {
|
|
51
|
+
expect(
|
|
52
|
+
u8aCmp(
|
|
53
|
+
'0x12345678',
|
|
54
|
+
new Uint8Array([0x12, 0x34, 0x56, 0x78])
|
|
55
|
+
)
|
|
56
|
+
).toEqual(0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
perf('u8aCmp (64 cmp)', 100_000, [[ztest, ztest]], u8aCmp);
|
|
60
|
+
perf('u8aCmp (256 cmp)', 50_000, [[stest, stest]], u8aCmp);
|
|
61
|
+
perf('u8aCmp (32k cmp)', 500, [[ltest, ltest]], u8aCmp);
|
|
62
|
+
});
|
package/src/u8a/cmp.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { u8aToU8a } from './toU8a.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name u8aCmp
|
|
8
|
+
* @summary Compares two Uint8Arrays for sorting.
|
|
9
|
+
* @description
|
|
10
|
+
* For `UInt8Array` (or hex string) input values returning -1, 0 or +1
|
|
11
|
+
* @example
|
|
12
|
+
* <BR>
|
|
13
|
+
*
|
|
14
|
+
* ```javascript
|
|
15
|
+
* import { u8aCmp } from '@pezkuwi/util';
|
|
16
|
+
*
|
|
17
|
+
* u8aCmp(new Uint8Array([0x67, 0x65]), new Uint8Array([0x68, 0x65])); // -1
|
|
18
|
+
* u8aCmp(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // 0
|
|
19
|
+
* u8aCmp(new Uint8Array([0x69, 0x65]), new Uint8Array([0x68, 0x65])); // +1
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function u8aCmp (a: string | Uint8Array, b: string | Uint8Array): number {
|
|
23
|
+
const u8aa = u8aToU8a(a);
|
|
24
|
+
const u8ab = u8aToU8a(b);
|
|
25
|
+
let i = 0;
|
|
26
|
+
|
|
27
|
+
while (true) {
|
|
28
|
+
const overA = i >= u8aa.length;
|
|
29
|
+
const overB = i >= u8ab.length;
|
|
30
|
+
|
|
31
|
+
if (overA && overB) {
|
|
32
|
+
// both ends reached
|
|
33
|
+
return 0;
|
|
34
|
+
} else if (overA) {
|
|
35
|
+
// a has no more data, b has data
|
|
36
|
+
return -1;
|
|
37
|
+
} else if (overB) {
|
|
38
|
+
// b has no more data, a has data
|
|
39
|
+
return 1;
|
|
40
|
+
} else if (u8aa[i] !== u8ab[i]) {
|
|
41
|
+
// the number in this index doesn't match
|
|
42
|
+
// (we don't use u8aa[i] - u8ab[i] since that doesn't match with localeCompare)
|
|
43
|
+
return u8aa[i] > u8ab[i]
|
|
44
|
+
? 1
|
|
45
|
+
: -1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
}
|