Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 55x 1x 15x 15x 15x 15x 13x 13x 13x 4x 9x 9x 9x 9x 9x 9x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 6x 2x 2x 1x 1x 7x 2x 49x 23204x 641x | import {ABI, ABIDef, API, APIClient, NameType} from '@wharfkit/antelope' import {AbiProvider} from '@wharfkit/signing-request' export interface ABICacheInterface extends AbiProvider { readonly cache: Map<string, ABI> readonly pending: Map<string, Promise<API.v1.GetRawAbiResponse>> getAbi(account: NameType): Promise<ABI> setAbi(account: NameType, abi: ABIDef, merge?: boolean): void } /** * Given an APIClient instance, this class provides an AbiProvider interface for retrieving and caching ABIs. */ export class ABICache implements ABICacheInterface { readonly cache: Map<string, ABI> = new Map() readonly pending: Map<string, Promise<API.v1.GetRawAbiResponse>> = new Map() // Keys whose cached ABI came only from merged partial (action-synthesized) ABIs and is not yet reconciled with chain. readonly partial: Set<string> = new Set() constructor(readonly client: APIClient) {} async getAbi(account: NameType): Promise<ABI> { const key = String(account) const record = this.cache.get(key) if (record && !this.partial.has(key)) { return record } let getAbi = this.pending.get(key) if (!getAbi) { getAbi = this.client.v1.chain.get_raw_abi(account).finally(() => { this.pending.delete(key) }) this.pending.set(key, getAbi) } const response = await getAbi if (response.abi) { const chainAbi = ABI.from(response.abi) const resolved = record ? ABICache.merge(chainAbi, record, chainAbi.version) : chainAbi this.cache.set(key, resolved) this.partial.delete(key) return resolved E} else if (record) { return record } else { throw new Error(`ABI for ${key} could not be loaded.`) } } setAbi(account: NameType, abiDef: ABIDef, merge = false) { const key = String(account) const abi = ABI.from(abiDef) const existing = this.cache.get(key) if (merge && existing) { this.cache.set(key, ABICache.merge(existing, abi, abi.version)) } else { this.cache.set(key, abi) if (merge) { this.partial.add(key) } else { this.partial.delete(key) } } } private static merge(base: ABI, addition: ABI, version: string): ABI { return ABI.from({ action_results: mergeAndDeduplicate(base.action_results, addition.action_results), types: mergeAndDeduplicate(base.types, addition.types, 'new_type_name'), structs: mergeAndDeduplicate(base.structs, addition.structs), actions: mergeAndDeduplicate(base.actions, addition.actions), tables: mergeAndDeduplicate(base.tables, addition.tables), ricardian_clauses: mergeAndDeduplicate( base.ricardian_clauses, addition.ricardian_clauses, 'id' ), variants: mergeAndDeduplicate(base.variants, addition.variants), version, }) } } function mergeAndDeduplicate(array1, array2, byField = 'name') { return array2.reduce((acc: any[], current: any) => { Iif (!acc.some((obj: any) => String(obj[byField]) === String(current[byField]))) { acc.push(current) } return acc }, array1.slice()) } |