@ghostspeak/sdk
Version:
TypeScript SDK for GhostSpeak AI Agent Commerce Protocol - Production Ready Beta
125 lines (124 loc) • 3.91 kB
JavaScript
// src/utils/batch-operations.ts
var MAX_ACCOUNTS_PER_BATCH = 100;
function chunkArray(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
async function batchGetAccounts(rpc, addresses, config = {}) {
const batchSize = Math.min(
config.batchSize ?? MAX_ACCOUNTS_PER_BATCH,
MAX_ACCOUNTS_PER_BATCH
);
if (addresses.length === 0) return [];
if (addresses.length <= batchSize) {
const result = await rpc.getMultipleAccounts(addresses).send();
return result.value;
}
const batches = chunkArray(addresses, batchSize);
const results = [];
let completed = 0;
const batchPromises = batches.map(async (batch) => {
const result = await rpc.getMultipleAccounts(batch).send();
completed += batch.length;
config.onProgress?.(completed, addresses.length);
return result.value;
});
results.push(...await Promise.all(batchPromises));
return results.flat();
}
async function batchGetExistingAccounts(rpc, addresses, config = {}) {
const accounts = await batchGetAccounts(rpc, addresses, config);
const existing = [];
for (let i = 0; i < accounts.length; i++) {
const account = accounts[i];
if (account !== null) {
existing.push({
address: addresses[i],
account
});
}
}
return existing;
}
async function batchGetAndMap(rpc, addresses, mapper, config = {}) {
const accounts = await batchGetAccounts(rpc, addresses, config);
return accounts.map(
(account, index) => mapper(account, addresses[index], index)
);
}
async function batchGetAccountsWithRetry(rpc, addresses, config = {}, maxRetries = 3) {
const batchSize = Math.min(
config.batchSize ?? MAX_ACCOUNTS_PER_BATCH,
MAX_ACCOUNTS_PER_BATCH
);
if (addresses.length === 0) return [];
const batches = chunkArray(addresses, batchSize);
const results = new Array(addresses.length);
let completed = 0;
await Promise.all(
batches.map(async (batch, batchIndex) => {
let retries = 0;
let success = false;
while (!success && retries <= maxRetries) {
try {
const result = await rpc.getMultipleAccounts(batch).send();
const batchResults = result.value;
batchResults.forEach((account, i) => {
results[batchIndex * batchSize + i] = account;
});
completed += batch.length;
config.onProgress?.(completed, addresses.length);
success = true;
} catch (error) {
retries++;
if (retries > maxRetries) {
throw new Error(
`Batch ${batchIndex} failed after ${maxRetries} retries: ${error}`
);
}
await new Promise(
(resolve) => setTimeout(resolve, 100 * Math.pow(2, retries - 1))
);
}
}
})
);
return results;
}
function createBatchFetcher(rpc, defaultConfig = {}) {
return {
/**
* Fetch multiple accounts
*/
getAccounts: (addresses, config) => batchGetAccounts(rpc, addresses, { ...defaultConfig, ...config }),
/**
* Fetch only existing accounts
*/
getExisting: (addresses, config) => batchGetExistingAccounts(rpc, addresses, {
...defaultConfig,
...config
}),
/**
* Fetch and map accounts
*/
getAndMap: (addresses, mapper, config) => batchGetAndMap(rpc, addresses, mapper, {
...defaultConfig,
...config
}),
/**
* Fetch with retry logic
*/
getWithRetry: (addresses, config, maxRetries) => batchGetAccountsWithRetry(
rpc,
addresses,
{ ...defaultConfig, ...config },
maxRetries
)
};
}
export { batchGetAccounts, batchGetAccountsWithRetry, batchGetAndMap, batchGetExistingAccounts, createBatchFetcher };
//# sourceMappingURL=chunk-SKMJJ3Q6.js.map
//# sourceMappingURL=chunk-SKMJJ3Q6.js.map