Event lazy create classes (#3685)

* Event lazy create classes

* head fallback
This commit is contained in:
Jaco
2021-06-22 09:49:45 +02:00
committed by GitHub
parent abb54d2538
commit 060275d1ae
6 changed files with 48 additions and 34 deletions
+1 -1
View File
@@ -286,7 +286,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
}
// get unique types & validate
metadata.getUniqTypes(false);
metadata.getUniqTypes(this._options.throwOnUnknown || false);
return [genesisHash, metadata];
}
+4
View File
@@ -73,6 +73,10 @@ export interface ApiOptions extends RegisteredTypes {
* @description Throws an error when the initial connection fails (same as isReadyOrError)
*/
throwOnConnect?: boolean;
/**
* @description Throws an error when some types are unknown (useful with throwOnConnect)
*/
throwOnUnknown?: boolean;
}
// A smaller interface of ApiRx, used in derive and in SubmittableExtrinsic
@@ -89,7 +89,7 @@ function extendHeadMeta (registry: Registry, { meta: { documentation, name, type
// meta fallback only applies to actual entry values, create one for head
(iterFn as IterFn).meta = registry.createType('StorageEntryMetadataLatest', {
documentation,
fallback: registry.createType('Bytes', registry.createType(outputType.toString() as 'Raw').toHex()),
fallback: registry.createType('Bytes'),
modifier: registry.createType('StorageEntryModifierLatest', 1), // required
name,
type: registry.createType('StorageEntryTypeLatest', registry.createType('Type', outputType), 0)
+15 -14
View File
@@ -51,31 +51,32 @@ function injectErrors (_: Registry, metadata: Metadata, metadataErrors: Record<s
// create event classes from metadata
function injectEvents (registry: Registry, metadata: Metadata, metadataEvents: Record<string, Constructor<GenericEventData>>): void {
const modules = metadata.asLatest.modules;
// decorate the events
modules
metadata.asLatest.modules
.filter(({ events }) => events.isSome)
.forEach((section, _sectionIndex): void => {
const sectionIndex = metadata.version >= 12 ? section.index.toNumber() : _sectionIndex;
const sectionIndex = metadata.version >= 12
? section.index.toNumber()
: _sectionIndex;
const sectionName = stringCamelCase(section.name);
section.events.unwrap().forEach((meta, methodIndex): void => {
const methodName = meta.name.toString();
const eventIndex = new Uint8Array([sectionIndex, methodIndex]);
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
const typeDef = meta.args.map((arg) => getTypeDef(arg));
let Types: Constructor<Codec>[] = [];
let Types: Constructor<Codec>[] | null = null;
try {
Types = typeDef.map((typeDef) => getTypeClass(registry, typeDef));
} catch (error) {
l.error(error);
}
// Lazy create the actual type classes right at the point of use
const getTypes = (): Constructor<Codec>[] => {
if (!Types) {
Types = typeDef.map((typeDef) => getTypeClass(registry, typeDef));
}
metadataEvents[u8aToHex(eventIndex)] = class extends GenericEventData {
return Types;
};
metadataEvents[u8aToHex(new Uint8Array([sectionIndex, methodIndex]))] = class extends GenericEventData {
constructor (registry: Registry, value: Uint8Array) {
super(registry, value, Types, typeDef, meta, sectionName, methodName);
super(registry, value, getTypes(), typeDef, meta, sectionName, methodName);
}
};
});
+26 -18
View File
@@ -10,6 +10,31 @@ import { Struct } from '../codec/Struct';
import { Tuple } from '../codec/Tuple';
import { Null } from '../primitive/Null';
interface Decoded {
DataType: Constructor<Null> | Constructor<GenericEventData>;
value?: {
index: Uint8Array;
data: Uint8Array;
}
}
/** @internal */
function decodeEvent (registry: Registry, value?: Uint8Array): Decoded {
if (!value || !value.length) {
return { DataType: Null };
}
const index = value.subarray(0, 2);
return {
DataType: registry.findMetaEvent(index),
value: {
data: value.subarray(2),
index
}
};
}
/**
* @name GenericEventData
* @description
@@ -72,7 +97,7 @@ export class GenericEvent extends Struct implements IEvent<Codec[]> {
// Currently we _only_ decode from Uint8Array, since we expect it to
// be used via EventRecord
constructor (registry: Registry, _value?: Uint8Array) {
const { DataType, value } = GenericEvent.decodeEvent(registry, _value);
const { DataType, value } = decodeEvent(registry, _value);
super(registry, {
index: 'EventId',
@@ -81,23 +106,6 @@ export class GenericEvent extends Struct implements IEvent<Codec[]> {
}, value);
}
/** @internal */
public static decodeEvent (registry: Registry, value: Uint8Array = new Uint8Array()): { DataType: Constructor<Null> | Constructor<GenericEventData>; value?: { index: Uint8Array; data: Uint8Array } } {
if (!value.length) {
return { DataType: Null };
}
const index = value.subarray(0, 2);
return {
DataType: registry.findMetaEvent(index),
value: {
data: value.subarray(2),
index
}
};
}
/**
* @description The wrapped [[EventData]]
*/