@bounded-sh/core 0.0.50 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-D6xrWKP7.js → index-BaSw33ec.js} +131 -19
- package/dist/index-BaSw33ec.js.map +1 -0
- package/dist/{index-CXyMnWgK.mjs → index-DpfaeNTQ.mjs} +130 -20
- package/dist/index-DpfaeNTQ.mjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{realtime-store-Djb_Dm-M.mjs → realtime-store-CBdRkQfZ.mjs} +2 -2
- package/dist/{realtime-store-Djb_Dm-M.mjs.map → realtime-store-CBdRkQfZ.mjs.map} +1 -1
- package/dist/{realtime-store-HkfnxBu3.js → realtime-store-PVPxsvPr.js} +2 -2
- package/dist/{realtime-store-HkfnxBu3.js.map → realtime-store-PVPxsvPr.js.map} +1 -1
- package/dist/{solana-message-CTUg0Tqd.js → solana-message-BVJWVB6C.js} +2 -2
- package/dist/{solana-message-CTUg0Tqd.js.map → solana-message-BVJWVB6C.js.map} +1 -1
- package/dist/{solana-message-l5OZo1j2.mjs → solana-message-kTeT43eQ.mjs} +2 -2
- package/dist/{solana-message-l5OZo1j2.mjs.map → solana-message-kTeT43eQ.mjs.map} +1 -1
- package/dist/{solana-operations-TSE5Tbgo.mjs → solana-operations-B8UyHL26.mjs} +2 -2
- package/dist/{solana-operations-TSE5Tbgo.mjs.map → solana-operations-B8UyHL26.mjs.map} +1 -1
- package/dist/{solana-operations-CSh2uF_0.js → solana-operations-bXuuPlov.js} +2 -2
- package/dist/{solana-operations-CSh2uF_0.js.map → solana-operations-bXuuPlov.js.map} +1 -1
- package/dist/utils/api.d.ts +12 -0
- package/package.json +2 -2
- package/dist/index-CXyMnWgK.mjs.map +0 -1
- package/dist/index-D6xrWKP7.js.map +0 -1
|
@@ -3410,7 +3410,7 @@ class ServerSessionManager {
|
|
|
3410
3410
|
const address = kp.publicKey.toBase58();
|
|
3411
3411
|
/* fetch nonce from auth API */
|
|
3412
3412
|
const nonce = await genAuthNonce();
|
|
3413
|
-
const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-
|
|
3413
|
+
const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-BVJWVB6C.js'); });
|
|
3414
3414
|
const message = await genSolanaMessage(address, nonce);
|
|
3415
3415
|
/* sign the message */
|
|
3416
3416
|
const sigBytes = nacl.sign.detached(new TextEncoder().encode(message), kp.secretKey);
|
|
@@ -3886,30 +3886,101 @@ class BoundedDeclineError extends Error {
|
|
|
3886
3886
|
|
|
3887
3887
|
const apiClient = axios.create();
|
|
3888
3888
|
const TRANSIENT_GET_STATUSES = new Set([500, 502, 503, 504]);
|
|
3889
|
+
const RATE_LIMIT_RETRY_BASE_DELAY_MS = 100;
|
|
3890
|
+
/** The window event emitted when the API responds with HTTP 429. */
|
|
3891
|
+
const RATE_LIMIT_EVENT_NAME = 'bounded:ratelimit';
|
|
3892
|
+
/** Dispatch a rate-limit event without affecting request error handling. */
|
|
3893
|
+
function dispatchRateLimitEvent(detail) {
|
|
3894
|
+
try {
|
|
3895
|
+
if (typeof window === 'undefined')
|
|
3896
|
+
return;
|
|
3897
|
+
const Ctor = globalThis.CustomEvent;
|
|
3898
|
+
if (typeof Ctor !== 'function')
|
|
3899
|
+
return;
|
|
3900
|
+
window.dispatchEvent(new Ctor(RATE_LIMIT_EVENT_NAME, {
|
|
3901
|
+
detail: Object.assign(Object.assign({}, detail), { at: Date.now() }),
|
|
3902
|
+
}));
|
|
3903
|
+
}
|
|
3904
|
+
catch (_a) {
|
|
3905
|
+
// Fire-and-forget: event consumers must never delay or mask the request.
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
function getRateLimitEventDetail(error, attempt, willRetry) {
|
|
3909
|
+
var _a, _b;
|
|
3910
|
+
const endpoint = typeof ((_a = error.config) === null || _a === void 0 ? void 0 : _a.url) === 'string' ? error.config.url : '';
|
|
3911
|
+
let path = endpoint;
|
|
3912
|
+
try {
|
|
3913
|
+
const parsed = new URL(endpoint);
|
|
3914
|
+
path = `${parsed.pathname}${parsed.search}`;
|
|
3915
|
+
}
|
|
3916
|
+
catch (_c) {
|
|
3917
|
+
// Keep a relative or otherwise non-standard endpoint as-is.
|
|
3918
|
+
}
|
|
3919
|
+
const responseBody = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data;
|
|
3920
|
+
const body = responseBody && typeof responseBody === 'object' && !Array.isArray(responseBody)
|
|
3921
|
+
? responseBody
|
|
3922
|
+
: responseBody == null
|
|
3923
|
+
? {}
|
|
3924
|
+
: { message: String(responseBody) };
|
|
3925
|
+
return Object.assign(Object.assign({}, body), { endpoint,
|
|
3926
|
+
path, status: 429, attempt,
|
|
3927
|
+
willRetry });
|
|
3928
|
+
}
|
|
3929
|
+
function getRateLimitAttempt(error) {
|
|
3930
|
+
var _a, _b;
|
|
3931
|
+
const retryCount = (_b = (_a = error.config) === null || _a === void 0 ? void 0 : _a['axios-retry']) === null || _b === void 0 ? void 0 : _b.retryCount;
|
|
3932
|
+
return typeof retryCount === 'number' ? retryCount + 1 : 1;
|
|
3933
|
+
}
|
|
3889
3934
|
axiosRetry(apiClient, {
|
|
3890
3935
|
retries: 2,
|
|
3891
3936
|
retryCondition: (error) => {
|
|
3892
|
-
var _a, _b, _c, _d, _e, _f;
|
|
3937
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3893
3938
|
// A caller cancellation is final. In particular, never turn a route
|
|
3894
3939
|
// unmount into a fresh GET after its AbortSignal has fired.
|
|
3895
|
-
|
|
3940
|
+
const canceled = axios.isCancel(error)
|
|
3941
|
+
|| error.code === 'ERR_CANCELED'
|
|
3942
|
+
|| ((_b = (_a = error.config) === null || _a === void 0 ? void 0 : _a.signal) === null || _b === void 0 ? void 0 : _b.aborted);
|
|
3943
|
+
if (canceled) {
|
|
3944
|
+
if (((_c = error.response) === null || _c === void 0 ? void 0 : _c.status) === 429) {
|
|
3945
|
+
dispatchRateLimitEvent(getRateLimitEventDetail(error, getRateLimitAttempt(error), false));
|
|
3946
|
+
}
|
|
3896
3947
|
return false;
|
|
3897
3948
|
}
|
|
3949
|
+
// A 429 means the server did not execute the request, so retrying is
|
|
3950
|
+
// safe for every method, including POST requests to the queries API.
|
|
3951
|
+
if (((_d = error.response) === null || _d === void 0 ? void 0 : _d.status) === 429)
|
|
3952
|
+
return true;
|
|
3898
3953
|
// Only retry idempotent GETs. Network failures and the small set of
|
|
3899
3954
|
// conventional transient gateway/runtime statuses get two bounded
|
|
3900
|
-
// retries; auth, policy, invariant, and
|
|
3955
|
+
// retries; auth, policy, invariant, and other terminal responses stay final.
|
|
3901
3956
|
// Writes are never retried because the server may already have applied
|
|
3902
3957
|
// them before the response was lost.
|
|
3903
|
-
if (((
|
|
3958
|
+
if (((_f = (_e = error.config) === null || _e === void 0 ? void 0 : _e.method) === null || _f === void 0 ? void 0 : _f.toLowerCase()) !== 'get')
|
|
3904
3959
|
return false;
|
|
3905
3960
|
return axiosRetry.isNetworkError(error)
|
|
3906
|
-
|| TRANSIENT_GET_STATUSES.has((
|
|
3961
|
+
|| TRANSIENT_GET_STATUSES.has((_h = (_g = error.response) === null || _g === void 0 ? void 0 : _g.status) !== null && _h !== void 0 ? _h : 0);
|
|
3962
|
+
},
|
|
3963
|
+
retryDelay: (retryCount, error) => {
|
|
3964
|
+
var _a;
|
|
3965
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 429) {
|
|
3966
|
+
const exponentialCap = RATE_LIMIT_RETRY_BASE_DELAY_MS * (2 ** retryCount);
|
|
3967
|
+
return Math.floor(Math.random() * exponentialCap);
|
|
3968
|
+
}
|
|
3969
|
+
return axiosRetry.exponentialDelay(retryCount, error);
|
|
3907
3970
|
},
|
|
3908
|
-
retryDelay: axiosRetry.exponentialDelay,
|
|
3909
3971
|
shouldResetTimeout: true,
|
|
3910
3972
|
onRetry: (retryCount, error, requestConfig) => {
|
|
3973
|
+
var _a, _b, _c;
|
|
3974
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 429) {
|
|
3975
|
+
dispatchRateLimitEvent(getRateLimitEventDetail(error, retryCount, !((_b = requestConfig.signal) === null || _b === void 0 ? void 0 : _b.aborted)));
|
|
3976
|
+
}
|
|
3977
|
+
console.warn(`[bounded-sdk] retry ${retryCount} for ${(_c = requestConfig.method) === null || _c === void 0 ? void 0 : _c.toUpperCase()} ${requestConfig.url} - ${error.code || error.message}`);
|
|
3978
|
+
},
|
|
3979
|
+
onMaxRetryTimesExceeded: (error, retryCount) => {
|
|
3911
3980
|
var _a;
|
|
3912
|
-
|
|
3981
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 429) {
|
|
3982
|
+
dispatchRateLimitEvent(getRateLimitEventDetail(error, retryCount + 1, false));
|
|
3983
|
+
}
|
|
3913
3984
|
},
|
|
3914
3985
|
});
|
|
3915
3986
|
const refreshInFlight = new Map();
|
|
@@ -5244,21 +5315,60 @@ async function getMany(paths, opts = {}) {
|
|
|
5244
5315
|
}
|
|
5245
5316
|
return results;
|
|
5246
5317
|
}
|
|
5247
|
-
|
|
5318
|
+
const MAX_RUN_QUERIES_PER_POST = 10;
|
|
5319
|
+
let pendingRunQueries = [];
|
|
5320
|
+
let runQueryFlushScheduled = false;
|
|
5321
|
+
function unwrapRunQueryRow(row, entry) {
|
|
5248
5322
|
var _a;
|
|
5249
|
-
const rows = await runQueryManyRows([{ absolutePath, queryName, queryArgs }], opts);
|
|
5250
|
-
const row = rows[0];
|
|
5251
5323
|
// The worker disambiguates a computed null from a failed/undeclared query
|
|
5252
|
-
// with a per-row `error` string
|
|
5324
|
+
// with a per-row `error` string, so surface it instead of returning undefined.
|
|
5253
5325
|
if ((row === null || row === void 0 ? void 0 : row.error) != null) {
|
|
5254
5326
|
const err = new Error(String(row.error));
|
|
5255
5327
|
err.isQueryError = true;
|
|
5256
|
-
err.queryName = queryName;
|
|
5257
|
-
err.path = absolutePath;
|
|
5328
|
+
err.queryName = entry.queryName;
|
|
5329
|
+
err.path = entry.absolutePath;
|
|
5258
5330
|
throw err;
|
|
5259
5331
|
}
|
|
5260
5332
|
return (_a = row === null || row === void 0 ? void 0 : row.result) !== null && _a !== void 0 ? _a : null;
|
|
5261
5333
|
}
|
|
5334
|
+
function flushPendingRunQueries() {
|
|
5335
|
+
const pending = pendingRunQueries;
|
|
5336
|
+
pendingRunQueries = [];
|
|
5337
|
+
runQueryFlushScheduled = false;
|
|
5338
|
+
// Calls with any request overrides bypass this buffer, so every entry here
|
|
5339
|
+
// belongs to the same default-overrides identity bucket.
|
|
5340
|
+
for (let offset = 0; offset < pending.length; offset += MAX_RUN_QUERIES_PER_POST) {
|
|
5341
|
+
const chunk = pending.slice(offset, offset + MAX_RUN_QUERIES_PER_POST);
|
|
5342
|
+
void runQueryManyRows(chunk.map(({ entry }) => entry)).then((rows) => {
|
|
5343
|
+
chunk.forEach((caller, index) => {
|
|
5344
|
+
try {
|
|
5345
|
+
caller.resolve(unwrapRunQueryRow(rows[index], caller.entry));
|
|
5346
|
+
}
|
|
5347
|
+
catch (error) {
|
|
5348
|
+
caller.reject(error);
|
|
5349
|
+
}
|
|
5350
|
+
});
|
|
5351
|
+
}, (error) => {
|
|
5352
|
+
chunk.forEach(({ reject }) => reject(error));
|
|
5353
|
+
});
|
|
5354
|
+
}
|
|
5355
|
+
}
|
|
5356
|
+
async function runQuery(absolutePath, queryName, queryArgs, opts) {
|
|
5357
|
+
const entry = { absolutePath, queryName, queryArgs };
|
|
5358
|
+
// Auth, custom headers, timeout, and signal overrides must remain local to
|
|
5359
|
+
// one request, so any override-bearing call deliberately bypasses coalescing.
|
|
5360
|
+
if ((opts === null || opts === void 0 ? void 0 : opts._overrides) != null) {
|
|
5361
|
+
const rows = await runQueryManyRows([entry], opts);
|
|
5362
|
+
return unwrapRunQueryRow(rows[0], entry);
|
|
5363
|
+
}
|
|
5364
|
+
return new Promise((resolve, reject) => {
|
|
5365
|
+
pendingRunQueries.push({ entry, resolve, reject });
|
|
5366
|
+
if (!runQueryFlushScheduled) {
|
|
5367
|
+
runQueryFlushScheduled = true;
|
|
5368
|
+
queueMicrotask(flushPendingRunQueries);
|
|
5369
|
+
}
|
|
5370
|
+
});
|
|
5371
|
+
}
|
|
5262
5372
|
async function runQueryMany(many, opts) {
|
|
5263
5373
|
// Batch shape stays an array of result values (errored rows map to null) so
|
|
5264
5374
|
// existing callers keep working; use runQuery for per-row error surfacing.
|
|
@@ -5447,11 +5557,11 @@ async function setMany(many, options) {
|
|
|
5447
5557
|
transactionResult = await handleEvmTransaction(curTx.evmTransaction, authProvider, options);
|
|
5448
5558
|
}
|
|
5449
5559
|
else if (curTx.serializedTransaction) {
|
|
5450
|
-
const { handlePreBuiltTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-
|
|
5560
|
+
const { handlePreBuiltTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-bXuuPlov.js'); });
|
|
5451
5561
|
transactionResult = await handlePreBuiltTransaction(curTx, authProvider, options, expectedWritePaths);
|
|
5452
5562
|
}
|
|
5453
5563
|
else {
|
|
5454
|
-
const { handleSolanaTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-
|
|
5564
|
+
const { handleSolanaTransaction } = await Promise.resolve().then(function () { return require('./solana-operations-bXuuPlov.js'); });
|
|
5455
5565
|
transactionResult = await handleSolanaTransaction(curTx, authProvider, options, expectedWritePaths);
|
|
5456
5566
|
}
|
|
5457
5567
|
// Sync items after all transactions are confirmed
|
|
@@ -7366,7 +7476,7 @@ async function doReconnectWithNewAuth() {
|
|
|
7366
7476
|
console.warn('[WS v2] Failed to clear HTTP read cache on auth change:', error);
|
|
7367
7477
|
}
|
|
7368
7478
|
try {
|
|
7369
|
-
const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-
|
|
7479
|
+
const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-PVPxsvPr.js'); });
|
|
7370
7480
|
await reconnectRealtimeStoreWithNewAuth();
|
|
7371
7481
|
}
|
|
7372
7482
|
catch (error) {
|
|
@@ -7711,7 +7821,7 @@ async function buildSetDocumentsTransaction(connection, idl, programProvider, pa
|
|
|
7711
7821
|
}
|
|
7712
7822
|
/** SIWS message creation is async already, so its onchain module can be lazy. */
|
|
7713
7823
|
async function genSolanaMessage(address, nonce) {
|
|
7714
|
-
const implementation = await Promise.resolve().then(function () { return require('./solana-message-
|
|
7824
|
+
const implementation = await Promise.resolve().then(function () { return require('./solana-message-BVJWVB6C.js'); });
|
|
7715
7825
|
return implementation.genSolanaMessage(address, nonce);
|
|
7716
7826
|
}
|
|
7717
7827
|
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
@@ -8251,6 +8361,7 @@ exports.EFFECT_INTENT_ADDRESS = EFFECT_INTENT_ADDRESS;
|
|
|
8251
8361
|
exports.FunctionInvokeError = FunctionInvokeError;
|
|
8252
8362
|
exports.InsufficientBalanceError = InsufficientBalanceError;
|
|
8253
8363
|
exports.LiveIntentError = LiveIntentError;
|
|
8364
|
+
exports.RATE_LIMIT_EVENT_NAME = RATE_LIMIT_EVENT_NAME;
|
|
8254
8365
|
exports.ReactNativeSessionManager = ReactNativeSessionManager;
|
|
8255
8366
|
exports.ServerSessionManager = ServerSessionManager;
|
|
8256
8367
|
exports.WebSessionManager = WebSessionManager;
|
|
@@ -8268,6 +8379,7 @@ exports.defineLiveModule = defineLiveModule;
|
|
|
8268
8379
|
exports.deriveDecline = deriveDecline;
|
|
8269
8380
|
exports.deriveUserIdentityFromIdToken = deriveUserIdentityFromIdToken;
|
|
8270
8381
|
exports.dispatchDeclineEvent = dispatchDeclineEvent;
|
|
8382
|
+
exports.dispatchRateLimitEvent = dispatchRateLimitEvent;
|
|
8271
8383
|
exports.docId = docId;
|
|
8272
8384
|
exports.functions = functions;
|
|
8273
8385
|
exports.genAuthNonce = genAuthNonce;
|
|
@@ -8314,4 +8426,4 @@ exports.toLowerEvmAddress = toLowerEvmAddress;
|
|
|
8314
8426
|
exports.toMillis = toMillis;
|
|
8315
8427
|
exports.toSeconds = toSeconds;
|
|
8316
8428
|
exports.withEffects = withEffects;
|
|
8317
|
-
//# sourceMappingURL=index-
|
|
8429
|
+
//# sourceMappingURL=index-BaSw33ec.js.map
|