diff --git a/packages/api/src/base/Init.ts b/packages/api/src/base/Init.ts index be78f40ef9..ca9842cd71 100644 --- a/packages/api/src/base/Init.ts +++ b/packages/api/src/base/Init.ts @@ -31,7 +31,7 @@ export abstract class Init extends Decorate { #registries: VersionedRegistry[] = []; - #updateSub?: Subscription; + #updateSub?: Subscription | null = null; constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod) { super(options, type, decorateMethod); @@ -156,10 +156,10 @@ export abstract class Init extends Decorate { // on re-connection to the same chain, we don't want to re-do everything from chain again if (this._isReady) { return true; - } else if (this.#updateSub) { - this.#updateSub.unsubscribe(); } + this._unsubscribeUpdates(); + // only load from on-chain if we are not a clone (default path), alternatively // just use the values from the source instance provided [this._genesisHash, this._runtimeMetadata] = this._options.source?._isReady @@ -302,6 +302,25 @@ export abstract class Init extends Decorate { return true; } + private _unsubscribeHealth (): void { + if (this.#healthTimer) { + clearInterval(this.#healthTimer); + this.#healthTimer = null; + } + } + + private _unsubscribeUpdates (): void { + if (this.#updateSub) { + this.#updateSub.unsubscribe(); + this.#updateSub = null; + } + } + + protected _unsubscribe (): void { + this._unsubscribeHealth(); + this._unsubscribeUpdates(); + } + #onProviderConnect = async (): Promise => { this.emit('connected'); this._isConnected.next(true); @@ -337,10 +356,7 @@ export abstract class Init extends Decorate { this.emit('disconnected'); this._isConnected.next(false); - if (this.#healthTimer) { - clearInterval(this.#healthTimer); - this.#healthTimer = null; - } + this._unsubscribeHealth(); }; #onProviderError = (error: Error): void => { diff --git a/packages/api/src/base/index.ts b/packages/api/src/base/index.ts index 593b8769e5..01cb37df2b 100644 --- a/packages/api/src/base/index.ts +++ b/packages/api/src/base/index.ts @@ -50,6 +50,8 @@ export abstract class ApiBase extends Getters * @description Disconnect from the underlying provider, halting all network traffic */ public disconnect (): Promise { + this._unsubscribe(); + return this._rpcCore.disconnect(); } diff --git a/packages/api/src/rx/index.ts b/packages/api/src/rx/index.ts index 922d75e425..b211030eb2 100644 --- a/packages/api/src/rx/index.ts +++ b/packages/api/src/rx/index.ts @@ -165,9 +165,7 @@ export class ApiRx extends ApiBase<'rxjs'> { this.#isReadyRx = from>( // You can create an observable from an event, however my mind groks this form better new Promise((resolve): void => { - super.on('ready', (): void => { - resolve(this); - }); + super.on('ready', () => resolve(this)); }) ); } diff --git a/packages/metadata/src/Metadata.ts b/packages/metadata/src/Metadata.ts index 2732a77258..d48fb6a397 100644 --- a/packages/metadata/src/Metadata.ts +++ b/packages/metadata/src/Metadata.ts @@ -3,7 +3,7 @@ import type { Registry } from '@polkadot/types/types'; -import { isString, u8aConcat, u8aToU8a } from '@polkadot/util'; +import { isString, u8aToU8a } from '@polkadot/util'; import { MetadataVersioned } from './MetadataVersioned'; @@ -11,7 +11,7 @@ import { MetadataVersioned } from './MetadataVersioned'; const VERSION_IDX = 4; // magic + lowest supported version -const EMPTY_METADATA = u8aConcat(new Uint8Array([0x6d, 0x65, 0x74, 0x61, 9])); +const EMPTY_METADATA = new Uint8Array([0x6d, 0x65, 0x74, 0x61, 9]); const EMPTY_U8A = new Uint8Array(); function sanitizeInput (_value: Uint8Array | string = EMPTY_U8A): Uint8Array { diff --git a/packages/types/src/codec/AbstractArray.ts b/packages/types/src/codec/AbstractArray.ts index 22e9fef91a..a531838df4 100644 --- a/packages/types/src/codec/AbstractArray.ts +++ b/packages/types/src/codec/AbstractArray.ts @@ -30,9 +30,7 @@ export abstract class AbstractArray extends Array implements * @description The length of the value when encoded as a Uint8Array */ public get encodedLength (): number { - return this.reduce((total, raw): number => { - return total + raw.encodedLength; - }, compactToU8a(this.length).length); + return this.reduce((total, entry) => total + entry.encodedLength, compactToU8a(this.length).length); } /** diff --git a/packages/types/src/codec/Tuple.ts b/packages/types/src/codec/Tuple.ts index c8369787e8..ec572acd08 100644 --- a/packages/types/src/codec/Tuple.ts +++ b/packages/types/src/codec/Tuple.ts @@ -74,11 +74,7 @@ export class Tuple extends AbstractArray { * @description The length of the value when encoded as a Uint8Array */ public get encodedLength (): number { - return this.reduce((length: number, entry: Codec): number => { - length += entry.encodedLength; - - return length; - }, 0); + return this.reduce((total, entry) => total + entry.encodedLength, 0); } /** diff --git a/packages/types/src/codec/VecFixed.ts b/packages/types/src/codec/VecFixed.ts index 8eeb35c16d..f6ba5972c5 100644 --- a/packages/types/src/codec/VecFixed.ts +++ b/packages/types/src/codec/VecFixed.ts @@ -63,7 +63,7 @@ export class VecFixed extends AbstractArray { * @description The length of the value when encoded as a Uint8Array */ public get encodedLength (): number { - return this.toU8a().length; + return this.reduce((total, entry) => total + entry.encodedLength, 0); } public toU8a (): Uint8Array { diff --git a/packages/types/src/create/sanitize.spec.ts b/packages/types/src/create/sanitize.spec.ts index 278891a4c3..814e476a09 100644 --- a/packages/types/src/create/sanitize.spec.ts +++ b/packages/types/src/create/sanitize.spec.ts @@ -5,7 +5,7 @@ import { alias, removeColons } from './sanitize'; describe('sanitize', (): void => { describe('alias', (): void => { - const exec = alias(['String'], 'Text'); + const exec = alias('String', 'Text'); it('replaces all occurrences for types', (): void => { expect(exec('(String,Address,MasterString,String)')).toEqual( @@ -27,7 +27,7 @@ describe('sanitize', (): void => { }); it('handles emdedded Vec/Tuples', (): void => { - const ann = alias(['Announcement'], 'ProxyAnnouncement'); + const ann = alias('Announcement', 'ProxyAnnouncement'); expect(ann('(Vec,BalanceOf)')).toEqual( '(Vec,BalanceOf)' diff --git a/packages/types/src/create/sanitize.ts b/packages/types/src/create/sanitize.ts index d4aadea9e4..9528ad50c8 100644 --- a/packages/types/src/create/sanitize.ts +++ b/packages/types/src/create/sanitize.ts @@ -12,8 +12,8 @@ const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fi const mappings: Mapper[] = [ // alias ::Inherent -> InherentOfflineReport - alias(['::Inherent'], 'InherentOfflineReport', false), - alias(['VecDeque<'], 'Vec<', false), + alias('::Inherent', 'InherentOfflineReport', false), + alias('VecDeque<', 'Vec<', false), // cleanupCompact(), // Change BoundedVec to Vec @@ -27,16 +27,17 @@ const mappings: Mapper[] = [ // remove generics, `MisbehaviorReport` -> `MisbehaviorReport` removeGenerics(), // alias String -> Text (compat with jsonrpc methods) - alias(['String'], 'Text'), + alias('String', 'Text'), // alias Vec -> Bytes - alias(['Vec', '&\\[u8\\]'], 'Bytes'), + alias('Vec', 'Bytes'), + alias('&\\[u8\\]', 'Bytes'), // alias RawAddress -> Address - alias(['RawAddress'], 'Address'), + alias('RawAddress', 'Address'), // lookups, mapped to Address/AccountId as appropriate in runtime - alias(['Lookup::Source'], 'LookupSource'), - alias(['Lookup::Target'], 'LookupTarget'), + alias('Lookup::Source', 'LookupSource'), + alias('Lookup::Target', 'LookupTarget'), // HACK duplication between contracts & primitives, however contracts prefixed with exec - alias(['exec::StorageKey'], 'ContractStorageKey'), + alias('exec::StorageKey', 'ContractStorageKey'), // flattens tuples with one value, `(AccountId)` -> `AccountId` flattenSingleTuple(), // converts ::Type to Type, >::Proposal -> Proposal @@ -62,17 +63,14 @@ export function findClosing (value: string, start: number): number { throw new Error(`Unable to find closing matching <> on '${value}' (start ${start})`); } -export function alias (src: string[], dest: string, withChecks = true): Mapper { +export function alias (src: string, dest: string, withChecks = true): Mapper { return (value: string): string => - src.reduce((value, src): string => - value - .replace( - new RegExp(`(^${src}|${BOX_PRECEDING.map((box) => `\\${box}${src}`).join('|')})`, 'g'), - (src): string => - withChecks && BOX_PRECEDING.includes(src[0]) - ? `${src[0]}${dest}` - : dest - ), value + value.replace( + new RegExp(`(^${src}|${BOX_PRECEDING.map((box) => `\\${box}${src}`).join('|')})`, 'g'), + (src): string => + withChecks && BOX_PRECEDING.includes(src[0]) + ? `${src[0]}${dest}` + : dest ); } diff --git a/packages/types/src/primitive/Text.ts b/packages/types/src/primitive/Text.ts index 3810fd5c1c..abecb459f7 100644 --- a/packages/types/src/primitive/Text.ts +++ b/packages/types/src/primitive/Text.ts @@ -28,7 +28,7 @@ function decodeText (value?: null | Text | string | AnyU8a | { toString: () => s const [offset, length] = compactFromU8a(value); const total = offset + length.toNumber(); - assert(length.lten(MAX_LENGTH), () => `Text length ${length.toString()} exceeds ${MAX_LENGTH}`); + assert(length.lten(MAX_LENGTH), () => `Text: length ${length.toString()} exceeds ${MAX_LENGTH}`); assert(total <= value.length, () => `Text: required length less than remainder, expected at least ${total}, found ${value.length}`); return u8aToString(value.subarray(offset, total));