diff --git a/packages/util/src/array/filter.ts b/packages/util/src/array/filter.ts index e48096995..c7ca27789 100644 --- a/packages/util/src/array/filter.ts +++ b/packages/util/src/array/filter.ts @@ -16,7 +16,7 @@ * arrayFilter([0, void 0, true, null, false, ''], false); // [0, true, false, ''] * ``` */ -export function arrayFilter (array: (T | null | undefined)[], allowNulls = true): T[] { +export function arrayFilter (array: readonly (T | null | undefined)[], allowNulls = true): T[] { return array.filter((v): v is T => v !== undefined && (allowNulls || v !== null) diff --git a/packages/util/src/array/flatten.ts b/packages/util/src/array/flatten.ts index 3d6321b1b..f0f3bd592 100644 --- a/packages/util/src/array/flatten.ts +++ b/packages/util/src/array/flatten.ts @@ -18,7 +18,7 @@ * arrayFlatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5] * ``` */ -export function arrayFlatten (arrays: T[][]): T[] { +export function arrayFlatten (arrays: readonly T[][]): T[] { // noop for the single-entry case if (arrays.length === 1) { return arrays[0]; diff --git a/packages/util/src/array/zip.ts b/packages/util/src/array/zip.ts index d4e8e4b68..cd8989fc1 100644 --- a/packages/util/src/array/zip.ts +++ b/packages/util/src/array/zip.ts @@ -5,7 +5,7 @@ * @name arrayZip * @description Combines 2 distinct key/value arrays into a single [K, V] array */ -export function arrayZip (keys: K[], values: V[]): [K, V][] { +export function arrayZip (keys: readonly K[], values: readonly V[]): [K, V][] { const result = new Array<[K, V]>(keys.length); for (let i = 0; i < keys.length; i++) { diff --git a/packages/util/src/lazy.ts b/packages/util/src/lazy.ts index d08eab68f..ab8cd3882 100644 --- a/packages/util/src/lazy.ts +++ b/packages/util/src/lazy.ts @@ -54,7 +54,7 @@ export function lazyMethod (result: Record | AnyFn, item: K, c * @description * Creates lazy, on-demand getters for the specific values. */ -export function lazyMethods (result: Record, items: K[], creator: (v: K) => T, getName?: (m: K) => string): Record { +export function lazyMethods (result: Record, items: readonly K[], creator: (v: K) => T, getName?: (m: K) => string): Record { for (let i = 0; i < items.length; i++) { lazyMethod(result, items[i], creator, getName); } diff --git a/packages/util/src/logger.ts b/packages/util/src/logger.ts index 82ad682e9..f02ef083f 100644 --- a/packages/util/src/logger.ts +++ b/packages/util/src/logger.ts @@ -107,7 +107,7 @@ function isDebugOff (e: string, type: string): boolean { ); } -function getDebugFlag (env: string[], type: string): boolean { +function getDebugFlag (env: readonly string[], type: string): boolean { let flag = false; for (const e of env) { diff --git a/packages/util/src/string/lowerFirst.ts b/packages/util/src/string/lowerFirst.ts index f7f851361..8998de66c 100644 --- a/packages/util/src/string/lowerFirst.ts +++ b/packages/util/src/string/lowerFirst.ts @@ -6,7 +6,7 @@ import type { AnyString } from '../types'; import { CC_TO_LO, CC_TO_UP } from './camelCase'; /** @internal */ -function converter (map: string[]): (value?: AnyString | null) => string { +function converter (map: readonly string[]): (value?: AnyString | null) => string { return (value?: AnyString | null): string => value ? map[value.charCodeAt(0)] + value.slice(1) diff --git a/packages/util/src/test/performance.ts b/packages/util/src/test/performance.ts index f3e3f7d2c..d28a235f1 100644 --- a/packages/util/src/test/performance.ts +++ b/packages/util/src/test/performance.ts @@ -9,7 +9,7 @@ type ExecFn = (...params: any[]) => unknown; const NUM_PAD = 16; const PRE_PAD = 32; -function loop (count: number, inputs: unknown[][], exec: ExecFn): [number, unknown[]] { +function loop (count: number, inputs: readonly unknown[][], exec: ExecFn): [number, unknown[]] { const start = performance.now(); const results = new Array(inputs.length); @@ -39,7 +39,7 @@ ${formatFixed(ops).padStart(NUM_PAD + PRE_PAD + 1)} ops/s ${formatFixed(micro).padStart(NUM_PAD + PRE_PAD + 1)} μs/op`; } -export function perf (name: string, count: number, inputs: unknown[][], exec: ExecFn): void { +export function perf (name: string, count: number, inputs: readonly unknown[][], exec: ExecFn): void { if (process.env.GITHUB_REPOSITORY) { return; } @@ -55,7 +55,7 @@ ${`${name}:`.padStart(PRE_PAD)} ${time.toFixed(2).padStart(NUM_PAD)} ms${formatO }); } -export function perfCmp (name: string, [first, second]: [string, string], count: number, inputs: unknown[][], exec: ExecFn): void { +export function perfCmp (name: string, [first, second]: [string, string], count: number, inputs: readonly unknown[][], exec: ExecFn): void { if (process.env.GITHUB_REPOSITORY) { return; } diff --git a/packages/util/src/u8a/concat.ts b/packages/util/src/u8a/concat.ts index 1213727b7..00dc2d3f3 100644 --- a/packages/util/src/u8a/concat.ts +++ b/packages/util/src/u8a/concat.ts @@ -22,7 +22,7 @@ import { u8aToU8a } from './toU8a'; * ); // [1, 2, 3, 4, 5, 6] * ``` */ -export function u8aConcat (...list: U8aLike[]): Uint8Array { +export function u8aConcat (...list: readonly U8aLike[]): Uint8Array { const u8as = new Array(list.length); let length = 0; @@ -38,7 +38,7 @@ export function u8aConcat (...list: U8aLike[]): Uint8Array { * @name u8aConcatStrict * @description A strict version of [[u8aConcat]], accepting only Uint8Array inputs */ -export function u8aConcatStrict (u8as: Uint8Array[], length = 0): Uint8Array { +export function u8aConcatStrict (u8as: readonly Uint8Array[], length = 0): Uint8Array { let offset = 0; if (!length) { diff --git a/packages/util/src/u8a/concatBuffer.ts b/packages/util/src/u8a/concatBuffer.ts index 0d50d660b..e665b4104 100644 --- a/packages/util/src/u8a/concatBuffer.ts +++ b/packages/util/src/u8a/concatBuffer.ts @@ -22,7 +22,7 @@ import { u8aToU8a } from './toU8a'; * ); // [1, 2, 3, 4, 5, 6] * ``` */ -export function u8aConcat (...list: U8aLike[]): Uint8Array { +export function u8aConcat (...list: readonly U8aLike[]): Uint8Array { const u8as = new Array(list.length); for (let i = 0; i < list.length; i++) { diff --git a/packages/util/src/u8a/empty.spec.ts b/packages/util/src/u8a/empty.spec.ts index 739f4f2ae..7d2b4c4b8 100644 --- a/packages/util/src/u8a/empty.spec.ts +++ b/packages/util/src/u8a/empty.spec.ts @@ -4,8 +4,6 @@ import { perf } from '../test/performance'; import { u8aEmpty } from '.'; -const ztest = new Uint8Array(32); - describe('u8aEmpty', (): void => { it('returns true on zero length', (): void => { expect( @@ -25,5 +23,22 @@ describe('u8aEmpty', (): void => { ).toEqual(false); }); - perf('u8aEmpty (32 cmp)', 1000000, [[ztest]], u8aEmpty); + it('returns false when value is found (256)', (): void => { + const test = new Uint8Array(256); + + expect( + u8aEmpty(test) + ).toEqual(true); + + test[128] = 1; + + expect( + u8aEmpty(test) + ).toEqual(false); + }); + + perf('u8aEmpty (32 cmp)', 1_000_000, [[new Uint8Array(32)]], u8aEmpty); + perf('u8aEmpty (64 cmp)', 500_000, [[new Uint8Array(64)]], u8aEmpty); + perf('u8aEmpty (128 cmp)', 250_000, [[new Uint8Array(128)]], u8aEmpty); + perf('u8aEmpty (256 cmp)', 125_000, [[new Uint8Array(256)]], u8aEmpty); }); diff --git a/packages/util/src/u8a/empty.ts b/packages/util/src/u8a/empty.ts index d8b9d1c37..3f6af7552 100644 --- a/packages/util/src/u8a/empty.ts +++ b/packages/util/src/u8a/empty.ts @@ -8,10 +8,11 @@ * Checks to see if the input `Uint8Array` has zero length or contains all 0 values. */ export function u8aEmpty (value: Uint8Array): boolean { - // on smaller values < 64 bytes, the byte-by-byte compare is faster than - // allocating yet another object for DataView (on large buffers the DataView - // is much faster) - for (let i = 0; i < value.length; i++) { + const len = value.length; + + // on smaller sizes, the byte-by-byte compare is faster than allocating + // another object for DataView (on very large arrays the DataView is faster) + for (let i = 0; i < len; i++) { if (value[i]) { return false; }