Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@helium/account-fetch-cache

Package Overview
Dependencies
Maintainers
7
Versions
169
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@helium/account-fetch-cache - npm Package Compare versions

Comparing version 0.2.5 to 0.2.14-next.102

108

lib/cjs/accountFetchCache.js

@@ -12,5 +12,6 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.AccountFetchCache = exports.DEFAULT_DELAY = exports.DEFAULT_CHUNK_SIZE = void 0;
exports.AccountFetchCache = exports.getSingleton = exports.DEFAULT_DELAY = exports.DEFAULT_CHUNK_SIZE = void 0;
const web3_js_1 = require("@solana/web3.js");
const eventEmitter_1 = require("./eventEmitter");
const getMultipleAccounts_1 = require("./getMultipleAccounts");
exports.DEFAULT_CHUNK_SIZE = 99;

@@ -25,2 +26,20 @@ exports.DEFAULT_DELAY = 50;

let id = 0;
let singletons = {};
function getSingleton(conn) {
const commitment = conn.commitment || "confirmed";
const endp = conn.rpcEndpoint;
if (!singletons[endp + commitment]) {
singletons[endp + commitment] = new AccountFetchCache({
connection: conn,
commitment,
});
}
return singletons[endp + commitment];
}
exports.getSingleton = getSingleton;
function setSingleton(conn, cache) {
const commitment = conn.commitment || "confirmed";
const endp = conn.rpcEndpoint;
singletons[endp + commitment] = cache;
}
class AccountFetchCache {

@@ -39,2 +58,3 @@ constructor({ connection, chunkSize = exports.DEFAULT_CHUNK_SIZE, delay = exports.DEFAULT_DELAY, commitment, missingRefetchDelay = 10000, extendConnection = false, }) {

this.emitter = new eventEmitter_1.EventEmitter();
this.id = ++id;
this.connection = connection;

@@ -46,6 +66,8 @@ this.chunkSize = chunkSize;

this.oldSendTransaction = connection.sendTransaction.bind(connection);
this.oldSendRawTransaction =
connection.sendRawTransaction.bind(connection);
this.oldSendRawTransaction = connection.sendRawTransaction.bind(connection);
const self = this;
if (extendConnection) {
// @ts-ignore
if (extendConnection && !connection._accountFetchWrapped) {
// @ts-ignore
connection._accountFetchWrapped = true;
this.oldGetAccountinfo = connection.getAccountInfo.bind(connection);

@@ -90,2 +112,3 @@ connection.getAccountInfo = (publicKey, com) => __awaiter(this, void 0, void 0, function* () {

};
setSingleton(connection, this);
}

@@ -131,3 +154,3 @@ requeryMissing(instructions) {

const keys = Array.from(currentBatch);
const array = yield this.connection.getMultipleAccountsInfo(keys.map(b => new web3_js_1.PublicKey(b)), this.commitment);
const { array } = yield (0, getMultipleAccounts_1.getMultipleAccounts)(this.connection, keys, this.commitment);
keys.forEach((key, index) => {

@@ -148,2 +171,14 @@ const callback = this.pendingCallbacks.get(key);

}
addToBatchIgnoreResult(id) {
const idStr = id.toBase58();
this.currentBatch.add(idStr);
this.timeout != null && clearTimeout(this.timeout);
if (this.currentBatch.size > exports.DEFAULT_CHUNK_SIZE) {
return this.fetchBatch();
}
else {
this.timeout = setTimeout(() => this.fetchBatch(), this.delay);
}
return undefined;
}
addToBatch(id) {

@@ -249,2 +284,4 @@ return __awaiter(this, void 0, void 0, function* () {

// Rely on searchAndWatch to set the generic cache for everything else.
// Never update the cache with an account that isn't being watched. This could cause
// stale data to be returned.
if (isStatic && result && result.info) {

@@ -259,2 +296,62 @@ this.updateCache(address, result);

}
searchMultiple(pubKeys, parser, isStatic = false, // optimization, set if the data will never change
forceRequery = false) {
return __awaiter(this, void 0, void 0, function* () {
// Store results of batch fetches in this map. If isStatic is false, genericCache will have none of the
// results of our searches in the batch. So need to accumulate them here
const result = {};
const searched = new Set(pubKeys.map((p) => p.toBase58()));
for (const key of pubKeys) {
this.registerParser(key, parser);
const address = key.toBase58();
if (isStatic) {
this.statics.add(address);
}
else if (this.statics.has(address)) {
this.statics.delete(address); // If trying to use this as not static, need to rm it from the statics list.
}
if (forceRequery || !this.genericCache.has(address)) {
const { keys, array } = (yield this.addToBatchIgnoreResult(key)) || {
keys: [],
array: [],
};
keys.forEach((key, index) => {
this.statics.add(key);
if (searched.has(key)) {
const item = array[index];
if (item) {
const parsed = this.getParsed(key, item, parser) || null;
// Cache these results if they aren't going to change
if (isStatic) {
this.genericCache.set(key, parsed);
}
if (parsed) {
result[key] = parsed;
}
}
}
});
}
}
// Force a batch fetch to resolve all accounts
const { keys, array } = yield this.fetchBatch();
keys.forEach((key, index) => {
this.statics.add(key);
if (searched.has(key)) {
const item = array[index];
if (item) {
const parsed = this.getParsed(key, item, parser) || null;
// Cache these results if they aren't going to change
if (isStatic) {
this.genericCache.set(key, parsed);
}
if (parsed) {
result[key] = parsed;
}
}
}
});
return pubKeys.map((key) => result[key.toBase58()] || this.genericCache.get(key.toBase58()));
});
}
onAccountChange(key, parser, account) {

@@ -264,3 +361,2 @@ try {

const address = key.toBase58();
console.log("accountFetchCache", `Received account change ${key}`, parsed);
this.updateCache(address, parsed || null);

@@ -267,0 +363,0 @@ }

@@ -1,3 +0,4 @@

import { Connection, PublicKey, Transaction } from "@solana/web3.js";
import { Connection, PublicKey, Transaction, } from "@solana/web3.js";
import { EventEmitter } from "./eventEmitter";
import { getMultipleAccounts } from "./getMultipleAccounts";
export const DEFAULT_CHUNK_SIZE = 99;

@@ -12,2 +13,19 @@ export const DEFAULT_DELAY = 50;

let id = 0;
let singletons = {};
export function getSingleton(conn) {
const commitment = conn.commitment || "confirmed";
const endp = conn.rpcEndpoint;
if (!singletons[endp + commitment]) {
singletons[endp + commitment] = new AccountFetchCache({
connection: conn,
commitment,
});
}
return singletons[endp + commitment];
}
function setSingleton(conn, cache) {
const commitment = conn.commitment || "confirmed";
const endp = conn.rpcEndpoint;
singletons[endp + commitment] = cache;
}
export class AccountFetchCache {

@@ -29,2 +47,3 @@ connection;

emitter = new EventEmitter();
id; // For debugging, to see which cache is being used
oldGetAccountinfo;

@@ -35,2 +54,3 @@ oldSendTransaction;

constructor({ connection, chunkSize = DEFAULT_CHUNK_SIZE, delay = DEFAULT_DELAY, commitment, missingRefetchDelay = 10000, extendConnection = false, }) {
this.id = ++id;
this.connection = connection;

@@ -42,6 +62,8 @@ this.chunkSize = chunkSize;

this.oldSendTransaction = connection.sendTransaction.bind(connection);
this.oldSendRawTransaction =
connection.sendRawTransaction.bind(connection);
this.oldSendRawTransaction = connection.sendRawTransaction.bind(connection);
const self = this;
if (extendConnection) {
// @ts-ignore
if (extendConnection && !connection._accountFetchWrapped) {
// @ts-ignore
connection._accountFetchWrapped = true;
this.oldGetAccountinfo = connection.getAccountInfo.bind(connection);

@@ -82,2 +104,3 @@ connection.getAccountInfo = async (publicKey, com) => {

};
setSingleton(connection, this);
}

@@ -118,3 +141,3 @@ async requeryMissing(instructions) {

const keys = Array.from(currentBatch);
const array = await this.connection.getMultipleAccountsInfo(keys.map(b => new PublicKey(b)), this.commitment);
const { array } = await getMultipleAccounts(this.connection, keys, this.commitment);
keys.forEach((key, index) => {

@@ -134,2 +157,14 @@ const callback = this.pendingCallbacks.get(key);

}
addToBatchIgnoreResult(id) {
const idStr = id.toBase58();
this.currentBatch.add(idStr);
this.timeout != null && clearTimeout(this.timeout);
if (this.currentBatch.size > DEFAULT_CHUNK_SIZE) {
return this.fetchBatch();
}
else {
this.timeout = setTimeout(() => this.fetchBatch(), this.delay);
}
return undefined;
}
async addToBatch(id) {

@@ -230,2 +265,4 @@ const idStr = id.toBase58();

// Rely on searchAndWatch to set the generic cache for everything else.
// Never update the cache with an account that isn't being watched. This could cause
// stale data to be returned.
if (isStatic && result && result.info) {

@@ -239,2 +276,60 @@ this.updateCache(address, result);

}
async searchMultiple(pubKeys, parser, isStatic = false, // optimization, set if the data will never change
forceRequery = false) {
// Store results of batch fetches in this map. If isStatic is false, genericCache will have none of the
// results of our searches in the batch. So need to accumulate them here
const result = {};
const searched = new Set(pubKeys.map((p) => p.toBase58()));
for (const key of pubKeys) {
this.registerParser(key, parser);
const address = key.toBase58();
if (isStatic) {
this.statics.add(address);
}
else if (this.statics.has(address)) {
this.statics.delete(address); // If trying to use this as not static, need to rm it from the statics list.
}
if (forceRequery || !this.genericCache.has(address)) {
const { keys, array } = (await this.addToBatchIgnoreResult(key)) || {
keys: [],
array: [],
};
keys.forEach((key, index) => {
this.statics.add(key);
if (searched.has(key)) {
const item = array[index];
if (item) {
const parsed = this.getParsed(key, item, parser) || null;
// Cache these results if they aren't going to change
if (isStatic) {
this.genericCache.set(key, parsed);
}
if (parsed) {
result[key] = parsed;
}
}
}
});
}
}
// Force a batch fetch to resolve all accounts
const { keys, array } = await this.fetchBatch();
keys.forEach((key, index) => {
this.statics.add(key);
if (searched.has(key)) {
const item = array[index];
if (item) {
const parsed = this.getParsed(key, item, parser) || null;
// Cache these results if they aren't going to change
if (isStatic) {
this.genericCache.set(key, parsed);
}
if (parsed) {
result[key] = parsed;
}
}
}
});
return pubKeys.map((key) => result[key.toBase58()] || this.genericCache.get(key.toBase58()));
}
onAccountChange(key, parser, account) {

@@ -244,3 +339,2 @@ try {

const address = key.toBase58();
console.log("accountFetchCache", `Received account change ${key}`, parsed);
this.updateCache(address, parsed || null);

@@ -247,0 +341,0 @@ }

16

lib/types/src/accountFetchCache.d.ts

@@ -14,2 +14,3 @@ /// <reference types="node" />

export type AccountParser<T> = (pubkey: PublicKey, data: AccountInfo<Buffer>) => ParsedAccountBase<T> | undefined;
export declare function getSingleton(conn: Connection): AccountFetchCache;
export declare class AccountFetchCache {

@@ -23,5 +24,5 @@ connection: Connection;

statics: Set<string>;
missingAccounts: Map<string, AccountParser<unknown>>;
genericCache: Map<string, ParsedAccountBase<unknown>>;
keyToAccountParser: Map<string, AccountParser<unknown>>;
missingAccounts: Map<string, AccountParser<unknown> | undefined>;
genericCache: Map<string, ParsedAccountBase<unknown> | null>;
keyToAccountParser: Map<string, AccountParser<unknown> | undefined>;
timeout: NodeJS.Timeout | null;

@@ -32,2 +33,3 @@ currentBatch: Set<string>;

emitter: EventEmitter;
id: number;
oldGetAccountinfo?: (publicKey: PublicKey, com?: Commitment) => Promise<AccountInfo<Buffer> | null>;

@@ -53,2 +55,6 @@ oldSendTransaction: (...args: any[]) => Promise<string>;

}>;
addToBatchIgnoreResult(id: PublicKey): Promise<{
keys: string[];
array: AccountInfo<Buffer>[];
}> | undefined;
addToBatch(id: PublicKey): Promise<AccountInfo<Buffer>>;

@@ -62,2 +68,4 @@ flush(): Promise<void>;

forceRequery?: boolean): Promise<ParsedAccountBase<T> | undefined>;
searchMultiple<T>(pubKeys: PublicKey[], parser?: AccountParser<T> | undefined, isStatic?: Boolean, // optimization, set if the data will never change
forceRequery?: boolean): Promise<(ParsedAccountBase<T> | undefined)[]>;
onAccountChange<T>(key: PublicKey, parser: AccountParser<T> | undefined, account: AccountInfo<Buffer>): void;

@@ -67,3 +75,3 @@ watch<T>(id: PublicKey, parser?: AccountParser<T> | undefined, exists?: Boolean): () => void;

getParsed<T>(id: PublicKey | string, obj: AccountInfo<Buffer>, parser?: AccountParser<T>): ParsedAccountBase<T> | undefined;
get(pubKey: string | PublicKey): ParsedAccountBase<unknown>;
get(pubKey: string | PublicKey): ParsedAccountBase<unknown> | null | undefined;
delete(pubKey: string | PublicKey): boolean;

@@ -70,0 +78,0 @@ byParser<T>(parser: AccountParser<T>): string[];

{
"name": "@helium/account-fetch-cache",
"version": "0.2.5",
"version": "0.2.14-next.102+29959a97",
"description": "Solana account fetch cache to eliminate reduntant fetching, and batch fetches",

@@ -34,3 +34,3 @@ "publishConfig": {

"dependencies": {
"@solana/web3.js": "^1.43.4"
"@solana/web3.js": "^1.78.4"
},

@@ -40,6 +40,6 @@ "devDependencies": {

"ts-loader": "^9.2.3",
"typescript": "^4.3.4",
"typescript": "^4.8.4",
"yarn": "^1.22.18"
},
"gitHead": "d391d5f039aef3f222ebfa5ca69bcc403fff86a7"
"gitHead": "29959a976df5e40c25f66f9f8ff7fb0c6ace125f"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc