UNPKG

@mysten/sui

Version:
1 lines 13.1 kB
{"version":3,"file":"ObjectCache.mjs","names":["#caches","#cache","#onEffects","cached"],"sources":["../../src/transactions/ObjectCache.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { bcs } from '../bcs/index.js';\nimport { normalizeSuiAddress } from '../utils/sui-types.js';\nimport type { SuiClientTypes } from '../client/types.js';\nimport type { TransactionPlugin } from './resolve.js';\n\nexport interface ObjectCacheEntry {\n\tobjectId: string;\n\tversion: string;\n\tdigest: string;\n\towner: string | null;\n\tinitialSharedVersion: string | null;\n}\n\nexport interface MoveFunctionCacheEntry {\n\tpackage: string;\n\tmodule: string;\n\tfunction: string;\n\tparameters: SuiClientTypes.OpenSignature[];\n}\n\nexport interface CacheEntryTypes {\n\tOwnedObject: ObjectCacheEntry;\n\tSharedOrImmutableObject: ObjectCacheEntry;\n\tMoveFunction: MoveFunctionCacheEntry;\n\tCustom: unknown;\n}\nexport abstract class AsyncCache {\n\tprotected abstract get<T extends keyof CacheEntryTypes>(\n\t\ttype: T,\n\t\tkey: string,\n\t): Promise<CacheEntryTypes[T] | null>;\n\tprotected abstract set<T extends keyof CacheEntryTypes>(\n\t\ttype: T,\n\t\tkey: string,\n\t\tvalue: CacheEntryTypes[T],\n\t): Promise<void>;\n\tprotected abstract delete<T extends keyof CacheEntryTypes>(type: T, key: string): Promise<void>;\n\tabstract clear<T extends keyof CacheEntryTypes>(type?: T): Promise<void>;\n\n\tasync getObject(id: string) {\n\t\tconst [owned, shared] = await Promise.all([\n\t\t\tthis.get('OwnedObject', id),\n\t\t\tthis.get('SharedOrImmutableObject', id),\n\t\t]);\n\n\t\treturn owned ?? shared ?? null;\n\t}\n\n\tasync getObjects(ids: string[]) {\n\t\treturn Promise.all(ids.map((id) => this.getObject(id)));\n\t}\n\n\tasync addObject(object: ObjectCacheEntry) {\n\t\tif (object.owner) {\n\t\t\tawait this.set('OwnedObject', object.objectId, object);\n\t\t} else {\n\t\t\tawait this.set('SharedOrImmutableObject', object.objectId, object);\n\t\t}\n\n\t\treturn object;\n\t}\n\n\tasync addObjects(objects: ObjectCacheEntry[]) {\n\t\tawait Promise.all(objects.map(async (object) => this.addObject(object)));\n\t}\n\n\tasync deleteObject(id: string) {\n\t\tawait Promise.all([this.delete('OwnedObject', id), this.delete('SharedOrImmutableObject', id)]);\n\t}\n\n\tasync deleteObjects(ids: string[]) {\n\t\tawait Promise.all(ids.map((id) => this.deleteObject(id)));\n\t}\n\n\tasync getMoveFunctionDefinition(ref: { package: string; module: string; function: string }) {\n\t\tconst functionName = `${normalizeSuiAddress(ref.package)}::${ref.module}::${ref.function}`;\n\t\treturn this.get('MoveFunction', functionName);\n\t}\n\n\tasync addMoveFunctionDefinition(functionEntry: MoveFunctionCacheEntry) {\n\t\tconst pkg = normalizeSuiAddress(functionEntry.package);\n\t\tconst functionName = `${pkg}::${functionEntry.module}::${functionEntry.function}`;\n\t\tconst entry = {\n\t\t\t...functionEntry,\n\t\t\tpackage: pkg,\n\t\t};\n\n\t\tawait this.set('MoveFunction', functionName, entry);\n\n\t\treturn entry;\n\t}\n\n\tasync deleteMoveFunctionDefinition(ref: { package: string; module: string; function: string }) {\n\t\tconst functionName = `${normalizeSuiAddress(ref.package)}::${ref.module}::${ref.function}`;\n\t\tawait this.delete('MoveFunction', functionName);\n\t}\n\n\tasync getCustom<T>(key: string) {\n\t\treturn this.get('Custom', key) as Promise<T | null>;\n\t}\n\n\tasync setCustom<T>(key: string, value: T) {\n\t\treturn this.set('Custom', key, value);\n\t}\n\n\tasync deleteCustom(key: string) {\n\t\treturn this.delete('Custom', key);\n\t}\n}\n\nexport class InMemoryCache extends AsyncCache {\n\t#caches = {\n\t\tOwnedObject: new Map<string, ObjectCacheEntry>(),\n\t\tSharedOrImmutableObject: new Map<string, ObjectCacheEntry>(),\n\t\tMoveFunction: new Map<string, MoveFunctionCacheEntry>(),\n\t\tCustom: new Map<string, unknown>(),\n\t};\n\n\tprotected async get<T extends keyof CacheEntryTypes>(type: T, key: string) {\n\t\treturn (this.#caches[type].get(key) as CacheEntryTypes[T]) ?? null;\n\t}\n\n\tprotected async set<T extends keyof CacheEntryTypes>(\n\t\ttype: T,\n\t\tkey: string,\n\t\tvalue: CacheEntryTypes[T],\n\t) {\n\t\t(this.#caches[type] as Map<string, typeof value>).set(key, value as never);\n\t}\n\n\tprotected async delete<T extends keyof CacheEntryTypes>(type: T, key: string) {\n\t\tthis.#caches[type].delete(key);\n\t}\n\n\tasync clear<T extends keyof CacheEntryTypes>(type?: T) {\n\t\tif (type) {\n\t\t\tthis.#caches[type].clear();\n\t\t} else {\n\t\t\tfor (const cache of Object.values(this.#caches)) {\n\t\t\t\tcache.clear();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport interface ObjectCacheOptions {\n\tcache?: AsyncCache;\n\tonEffects?: (effects: typeof bcs.TransactionEffects.$inferType) => Promise<void>;\n}\n\nexport class ObjectCache {\n\t#cache: AsyncCache;\n\t#onEffects?: (effects: typeof bcs.TransactionEffects.$inferType) => Promise<void>;\n\n\tconstructor({ cache = new InMemoryCache(), onEffects }: ObjectCacheOptions) {\n\t\tthis.#cache = cache;\n\t\tthis.#onEffects = onEffects;\n\t}\n\n\tasPlugin(): TransactionPlugin {\n\t\treturn async (transactionData, _options, next) => {\n\t\t\tconst unresolvedObjects = transactionData.inputs\n\t\t\t\t.filter((input) => input.UnresolvedObject)\n\t\t\t\t.map((input) => input.UnresolvedObject!.objectId);\n\n\t\t\tconst cached = (await this.#cache.getObjects(unresolvedObjects)).filter(\n\t\t\t\t(obj) => obj !== null,\n\t\t\t);\n\n\t\t\tconst byId = new Map(cached.map((obj) => [obj!.objectId, obj]));\n\n\t\t\tfor (const input of transactionData.inputs) {\n\t\t\t\tif (!input.UnresolvedObject) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst cached = byId.get(input.UnresolvedObject.objectId);\n\n\t\t\t\tif (!cached) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (cached.initialSharedVersion && !input.UnresolvedObject.initialSharedVersion) {\n\t\t\t\t\tinput.UnresolvedObject.initialSharedVersion = cached.initialSharedVersion;\n\t\t\t\t} else {\n\t\t\t\t\tif (cached.version && !input.UnresolvedObject.version) {\n\t\t\t\t\t\tinput.UnresolvedObject.version = cached.version;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (cached.digest && !input.UnresolvedObject.digest) {\n\t\t\t\t\t\tinput.UnresolvedObject.digest = cached.digest;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait Promise.all(\n\t\t\t\ttransactionData.commands.map(async (commands) => {\n\t\t\t\t\tif (commands.MoveCall) {\n\t\t\t\t\t\tconst def = await this.getMoveFunctionDefinition({\n\t\t\t\t\t\t\tpackage: commands.MoveCall.package,\n\t\t\t\t\t\t\tmodule: commands.MoveCall.module,\n\t\t\t\t\t\t\tfunction: commands.MoveCall.function,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (def) {\n\t\t\t\t\t\t\tcommands.MoveCall._argumentTypes = def.parameters;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tawait next();\n\n\t\t\tawait Promise.all(\n\t\t\t\ttransactionData.commands.map(async (commands) => {\n\t\t\t\t\tif (commands.MoveCall?._argumentTypes) {\n\t\t\t\t\t\tawait this.#cache.addMoveFunctionDefinition({\n\t\t\t\t\t\t\tpackage: commands.MoveCall.package,\n\t\t\t\t\t\t\tmodule: commands.MoveCall.module,\n\t\t\t\t\t\t\tfunction: commands.MoveCall.function,\n\t\t\t\t\t\t\tparameters: commands.MoveCall._argumentTypes,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\t}\n\n\tasync clear() {\n\t\tawait this.#cache.clear();\n\t}\n\n\tasync getMoveFunctionDefinition(ref: { package: string; module: string; function: string }) {\n\t\treturn this.#cache.getMoveFunctionDefinition(ref);\n\t}\n\n\tasync getObjects(ids: string[]) {\n\t\treturn this.#cache.getObjects(ids);\n\t}\n\n\tasync deleteObjects(ids: string[]) {\n\t\treturn this.#cache.deleteObjects(ids);\n\t}\n\n\tasync clearOwnedObjects() {\n\t\tawait this.#cache.clear('OwnedObject');\n\t}\n\n\tasync clearCustom() {\n\t\tawait this.#cache.clear('Custom');\n\t}\n\n\tasync getCustom<T>(key: string) {\n\t\treturn this.#cache.getCustom<T>(key);\n\t}\n\n\tasync setCustom<T>(key: string, value: T) {\n\t\treturn this.#cache.setCustom(key, value);\n\t}\n\n\tasync deleteCustom(key: string) {\n\t\treturn this.#cache.deleteCustom(key);\n\t}\n\n\tasync applyEffects(effects: typeof bcs.TransactionEffects.$inferType) {\n\t\tif (!effects.V2) {\n\t\t\tthrow new Error(`Unsupported transaction effects version ${effects.$kind}`);\n\t\t}\n\n\t\tconst { lamportVersion, changedObjects } = effects.V2;\n\n\t\tconst deletedIds: string[] = [];\n\t\tconst addedObjects: ObjectCacheEntry[] = [];\n\n\t\tchangedObjects.forEach(([id, change]) => {\n\t\t\tif (change.outputState.NotExist) {\n\t\t\t\tdeletedIds.push(id);\n\t\t\t} else if (change.outputState.ObjectWrite) {\n\t\t\t\tconst [digest, owner] = change.outputState.ObjectWrite;\n\n\t\t\t\taddedObjects.push({\n\t\t\t\t\tobjectId: id,\n\t\t\t\t\tdigest,\n\t\t\t\t\tversion: lamportVersion,\n\t\t\t\t\towner: owner.AddressOwner ?? owner.ObjectOwner ?? null,\n\t\t\t\t\tinitialSharedVersion: owner.Shared?.initialSharedVersion ?? null,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all([\n\t\t\tthis.#cache.addObjects(addedObjects),\n\t\t\tthis.#cache.deleteObjects(deletedIds),\n\t\t\tthis.#onEffects?.(effects),\n\t\t]);\n\t}\n}\n"],"mappings":"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"}