@solana/rpc-subscriptions 2.0.0-experimental.fbbf6ba → 2.0.0-preview.1
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.browser.cjs +33 -33
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +34 -36
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +34 -36
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +33 -33
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +34 -36
- package/dist/index.node.js.map +1 -1
- package/dist/types/cached-abortable-iterable.d.ts +1 -2
- package/dist/types/cached-abortable-iterable.d.ts.map +1 -1
- package/dist/types/rpc-integer-overflow-error.d.ts +2 -2
- package/dist/types/rpc-integer-overflow-error.d.ts.map +1 -1
- package/dist/types/rpc-subscriptions-clusters.d.ts +1 -1
- package/dist/types/rpc-subscriptions-coalescer.d.ts.map +1 -1
- package/dist/types/rpc-subscriptions-connection-sharding.d.ts.map +1 -1
- package/dist/types/rpc-subscriptions-transport.d.ts +4 -6
- package/dist/types/rpc-subscriptions-transport.d.ts.map +1 -1
- package/dist/types/rpc-subscriptions.d.ts +8 -8
- package/dist/types/rpc-subscriptions.d.ts.map +1 -1
- package/package.json +15 -15
package/dist/index.browser.cjs
CHANGED
|
@@ -32,7 +32,7 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
|
|
|
32
32
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
33
33
|
}
|
|
34
34
|
const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
35
|
-
const error = new errors.SolanaError(errors.
|
|
35
|
+
const error = new errors.SolanaError(errors.SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
36
36
|
argumentLabel,
|
|
37
37
|
keyPath,
|
|
38
38
|
methodName,
|
|
@@ -53,8 +53,6 @@ var DEFAULT_RPC_CONFIG = {
|
|
|
53
53
|
throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
|
|
57
|
-
// src/cached-abortable-iterable.ts
|
|
58
56
|
function registerIterableCleanup(iterable, cleanupFn) {
|
|
59
57
|
(async () => {
|
|
60
58
|
try {
|
|
@@ -68,7 +66,6 @@ function registerIterableCleanup(iterable, cleanupFn) {
|
|
|
68
66
|
}
|
|
69
67
|
function getCachedAbortableIterableFactory({
|
|
70
68
|
getAbortSignalFromInputArgs,
|
|
71
|
-
getCacheEntryMissingError,
|
|
72
69
|
getCacheKeyFromInputArgs,
|
|
73
70
|
onCacheHit,
|
|
74
71
|
onCreateIterable
|
|
@@ -77,7 +74,9 @@ function getCachedAbortableIterableFactory({
|
|
|
77
74
|
function getCacheEntryOrThrow(cacheKey) {
|
|
78
75
|
const currentCacheEntry = cache.get(cacheKey);
|
|
79
76
|
if (!currentCacheEntry) {
|
|
80
|
-
throw
|
|
77
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING, {
|
|
78
|
+
cacheKey: cacheKey.toString()
|
|
79
|
+
});
|
|
81
80
|
}
|
|
82
81
|
return currentCacheEntry;
|
|
83
82
|
}
|
|
@@ -178,11 +177,6 @@ function getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
|
178
177
|
}
|
|
179
178
|
const iterableFactory = getCachedAbortableIterableFactory({
|
|
180
179
|
getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,
|
|
181
|
-
getCacheEntryMissingError(deduplicationKey2) {
|
|
182
|
-
return new Error(
|
|
183
|
-
`Found no cache entry for subscription with deduplication key \`${deduplicationKey2?.toString()}\``
|
|
184
|
-
);
|
|
185
|
-
},
|
|
186
180
|
getCacheKeyFromInputArgs: () => deduplicationKey,
|
|
187
181
|
async onCacheHit(_iterable, _config) {
|
|
188
182
|
},
|
|
@@ -241,26 +235,6 @@ function getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
|
241
235
|
});
|
|
242
236
|
}
|
|
243
237
|
|
|
244
|
-
// src/rpc-subscriptions.ts
|
|
245
|
-
function createSolanaRpcSubscriptions(config) {
|
|
246
|
-
return functional.pipe(
|
|
247
|
-
rpcSubscriptionsSpec.createSubscriptionRpc({
|
|
248
|
-
...config,
|
|
249
|
-
api: rpcSubscriptionsApi.createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG)
|
|
250
|
-
}),
|
|
251
|
-
(rpcSubscriptions) => getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
252
|
-
getDeduplicationKey: (...args) => fastStableStringify__default.default(args),
|
|
253
|
-
rpcSubscriptions
|
|
254
|
-
})
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
function createSolanaRpcSubscriptions_UNSTABLE(config) {
|
|
258
|
-
return rpcSubscriptionsSpec.createSubscriptionRpc({
|
|
259
|
-
...config,
|
|
260
|
-
api: rpcSubscriptionsApi.createSolanaRpcSubscriptionsApi_UNSTABLE(DEFAULT_RPC_CONFIG)
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
238
|
// src/rpc-subscriptions-autopinger.ts
|
|
265
239
|
var PING_PAYLOAD = {
|
|
266
240
|
jsonrpc: "2.0",
|
|
@@ -337,9 +311,6 @@ function getWebSocketTransportWithConnectionSharding({
|
|
|
337
311
|
}) {
|
|
338
312
|
return getCachedAbortableIterableFactory({
|
|
339
313
|
getAbortSignalFromInputArgs: ({ signal }) => signal,
|
|
340
|
-
getCacheEntryMissingError(shardKey) {
|
|
341
|
-
return new Error(`Found no cache entry for connection with shard key \`${shardKey?.toString()}\``);
|
|
342
|
-
},
|
|
343
314
|
getCacheKeyFromInputArgs: ({ payload }) => getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY,
|
|
344
315
|
onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),
|
|
345
316
|
onCreateIterable: (abortSignal, config) => transport({
|
|
@@ -369,8 +340,37 @@ function createDefaultRpcSubscriptionsTransport(config) {
|
|
|
369
340
|
);
|
|
370
341
|
}
|
|
371
342
|
|
|
343
|
+
// src/rpc-subscriptions.ts
|
|
344
|
+
function createSolanaRpcSubscriptions(clusterUrl, config) {
|
|
345
|
+
const transport = createDefaultRpcSubscriptionsTransport({ url: clusterUrl, ...config });
|
|
346
|
+
return createSolanaRpcSubscriptionsFromTransport(transport);
|
|
347
|
+
}
|
|
348
|
+
function createSolanaRpcSubscriptions_UNSTABLE(clusterUrl, config) {
|
|
349
|
+
return createSolanaRpcSubscriptions(
|
|
350
|
+
clusterUrl,
|
|
351
|
+
config
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
function createSolanaRpcSubscriptionsFromTransport(transport) {
|
|
355
|
+
return functional.pipe(
|
|
356
|
+
rpcSubscriptionsSpec.createSubscriptionRpc({
|
|
357
|
+
api: rpcSubscriptionsApi.createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),
|
|
358
|
+
transport
|
|
359
|
+
}),
|
|
360
|
+
(rpcSubscriptions) => getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
361
|
+
getDeduplicationKey: (...args) => fastStableStringify__default.default(args),
|
|
362
|
+
rpcSubscriptions
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
function createSolanaRpcSubscriptionsFromTransport_UNSTABLE(transport) {
|
|
367
|
+
return createSolanaRpcSubscriptionsFromTransport(transport);
|
|
368
|
+
}
|
|
369
|
+
|
|
372
370
|
exports.createDefaultRpcSubscriptionsTransport = createDefaultRpcSubscriptionsTransport;
|
|
373
371
|
exports.createSolanaRpcSubscriptions = createSolanaRpcSubscriptions;
|
|
372
|
+
exports.createSolanaRpcSubscriptionsFromTransport = createSolanaRpcSubscriptionsFromTransport;
|
|
373
|
+
exports.createSolanaRpcSubscriptionsFromTransport_UNSTABLE = createSolanaRpcSubscriptionsFromTransport_UNSTABLE;
|
|
374
374
|
exports.createSolanaRpcSubscriptions_UNSTABLE = createSolanaRpcSubscriptions_UNSTABLE;
|
|
375
375
|
Object.keys(rpcSubscriptionsApi).forEach(function (k) {
|
|
376
376
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../build-scripts/env-shim.ts","../src/index.ts","../src/rpc-subscriptions.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/cached-abortable-iterable.ts","../src/rpc-subscriptions-coalescer.ts","../src/rpc-subscriptions-transport.ts","../src/rpc-subscriptions-autopinger.ts","../src/rpc-subscriptions-connection-sharding.ts"],"names":["registerIterableCleanup","deduplicationKey","pendingSubscription","pipe","args"],"mappings":"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","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export * from '@solana/rpc-subscriptions-api';\nexport * from '@solana/rpc-subscriptions-spec';\n\nexport * from './rpc-subscriptions';\nexport * from './rpc-subscriptions-clusters';\nexport * from './rpc-subscriptions-transport';\n","import { pipe } from '@solana/functional';\nimport type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport {\n createSolanaRpcSubscriptionsApi,\n createSolanaRpcSubscriptionsApi_UNSTABLE,\n} from '@solana/rpc-subscriptions-api';\nimport { createSubscriptionRpc, type RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport type { RpcSubscriptionsFromTransport } from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsWithSubscriptionCoalescing } from './rpc-subscriptions-coalescer';\n\ntype RpcSubscriptionsConfig<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n transport: TTransport;\n}>;\n\nexport function createSolanaRpcSubscriptions<TTransport extends RpcSubscriptionsTransport>(\n config: RpcSubscriptionsConfig<TTransport>,\n): RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi, TTransport> {\n return pipe(\n createSubscriptionRpc({\n ...config,\n api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),\n }),\n rpcSubscriptions =>\n getRpcSubscriptionsWithSubscriptionCoalescing({\n getDeduplicationKey: (...args) => fastStableStringify(args),\n rpcSubscriptions,\n }),\n ) as RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi, TTransport>;\n}\n\nexport function createSolanaRpcSubscriptions_UNSTABLE<TTransport extends RpcSubscriptionsTransport>(\n config: RpcSubscriptionsConfig<TTransport>,\n): RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable, TTransport> {\n return createSubscriptionRpc({\n ...config,\n api: createSolanaRpcSubscriptionsApi_UNSTABLE(DEFAULT_RPC_CONFIG),\n }) as RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable, TTransport>;\n}\n","import { SOLANA_ERROR__RPC_INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC_INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC_INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (string | number | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n }\n return error;\n}\n","import type { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcSubscriptionsApi>[0]> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(methodName, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","type CacheEntry<TIterable extends AsyncIterable<unknown>> = {\n abortController: AbortController;\n iterable: Promise<TIterable> | TIterable;\n purgeScheduled: boolean;\n referenceCount: number;\n};\ntype CacheKey = string | symbol;\ntype Config<TInput extends unknown[], TIterable extends AsyncIterable<unknown>> = Readonly<{\n getAbortSignalFromInputArgs: (...args: TInput) => AbortSignal;\n getCacheEntryMissingError: (cacheKey: CacheKey) => Error;\n getCacheKeyFromInputArgs: (...args: TInput) =>\n | CacheKey\n // `undefined` implies 'do not cache'\n | undefined;\n onCacheHit: (iterable: TIterable, ...args: TInput) => Promise<void>;\n onCreateIterable: (abortSignal: AbortSignal, ...args: TInput) => Promise<TIterable>;\n}>;\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getCachedAbortableIterableFactory<TInput extends unknown[], TIterable extends AsyncIterable<unknown>>({\n getAbortSignalFromInputArgs,\n getCacheEntryMissingError,\n getCacheKeyFromInputArgs,\n onCacheHit,\n onCreateIterable,\n}: Config<TInput, TIterable>): (...args: TInput) => Promise<TIterable> {\n const cache = new Map<CacheKey, CacheEntry<TIterable>>();\n function getCacheEntryOrThrow(cacheKey: CacheKey) {\n const currentCacheEntry = cache.get(cacheKey);\n if (!currentCacheEntry) {\n throw getCacheEntryMissingError(cacheKey);\n }\n return currentCacheEntry;\n }\n return async (...args: TInput) => {\n const cacheKey = getCacheKeyFromInputArgs(...args);\n const signal = getAbortSignalFromInputArgs(...args);\n if (cacheKey === undefined) {\n return await onCreateIterable(signal, ...args);\n }\n const cleanup = () => {\n cache.delete(cacheKey);\n signal.removeEventListener('abort', handleAbort);\n };\n const handleAbort = () => {\n const cacheEntry = getCacheEntryOrThrow(cacheKey);\n if (cacheEntry.purgeScheduled !== true) {\n cacheEntry.purgeScheduled = true;\n globalThis.queueMicrotask(() => {\n cacheEntry.purgeScheduled = false;\n if (cacheEntry.referenceCount === 0) {\n cacheEntry.abortController.abort();\n cleanup();\n }\n });\n }\n cacheEntry.referenceCount--;\n };\n signal.addEventListener('abort', handleAbort);\n try {\n const cacheEntry = cache.get(cacheKey);\n if (!cacheEntry) {\n const singletonAbortController = new AbortController();\n const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);\n const newCacheEntry: CacheEntry<TIterable> = {\n abortController: singletonAbortController,\n iterable: newIterablePromise,\n purgeScheduled: false,\n referenceCount: 1,\n };\n cache.set(cacheKey, newCacheEntry);\n const newIterable = await newIterablePromise;\n registerIterableCleanup(newIterable, cleanup);\n newCacheEntry.iterable = newIterable;\n return newIterable;\n } else {\n cacheEntry.referenceCount++;\n const iterableOrIterablePromise = cacheEntry.iterable;\n const cachedIterable =\n 'then' in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;\n await onCacheHit(cachedIterable, ...args);\n return cachedIterable;\n }\n } catch (e) {\n cleanup();\n throw e;\n }\n };\n}\n","import { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype CacheKey = string | undefined;\ntype Config<TRpcSubscriptionsMethods> = Readonly<{\n getDeduplicationKey: GetDeduplicationKeyFn;\n rpcSubscriptions: RpcSubscriptions<TRpcSubscriptionsMethods>;\n}>;\ntype GetDeduplicationKeyFn = (subscriptionMethod: string | symbol, payload: unknown) => CacheKey;\n\nconst EXPLICIT_ABORT_TOKEN = Symbol(\n __DEV__\n ? \"This symbol is thrown from a subscription's iterator when the subscription is \" +\n 'explicitly aborted by the user'\n : undefined,\n);\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getRpcSubscriptionsWithSubscriptionCoalescing<TRpcSubscriptionsMethods>({\n getDeduplicationKey,\n rpcSubscriptions,\n}: Config<TRpcSubscriptionsMethods>): RpcSubscriptions<TRpcSubscriptionsMethods> {\n const cache = new Map<CacheKey, PendingRpcSubscriptionsRequest<unknown>>();\n return new Proxy(rpcSubscriptions, {\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n get(target, p, receiver) {\n const subscriptionMethod = Reflect.get(target, p, receiver);\n if (typeof subscriptionMethod !== 'function') {\n return subscriptionMethod;\n }\n return function (...rawParams: unknown[]) {\n const deduplicationKey = getDeduplicationKey(p, rawParams);\n if (deduplicationKey === undefined) {\n return (subscriptionMethod as CallableFunction)(...rawParams);\n }\n if (cache.has(deduplicationKey)) {\n return cache.get(deduplicationKey)!;\n }\n const iterableFactory = getCachedAbortableIterableFactory<\n Parameters<PendingRpcSubscriptionsRequest<unknown>['subscribe']>,\n AsyncIterable<unknown>\n >({\n getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,\n getCacheEntryMissingError(deduplicationKey) {\n // TODO: Coded error.\n return new Error(\n `Found no cache entry for subscription with deduplication key \\`${deduplicationKey?.toString()}\\``,\n );\n },\n getCacheKeyFromInputArgs: () => deduplicationKey,\n async onCacheHit(_iterable, _config) {\n /**\n * This transport's goal is to prevent duplicate subscriptions from\n * being made. If a cached iterable] is found, do not send the subscribe\n * message again.\n */\n },\n async onCreateIterable(abortSignal, config) {\n const pendingSubscription = (subscriptionMethod as CallableFunction)(\n ...rawParams,\n ) as PendingRpcSubscriptionsRequest<unknown>;\n const iterable = await pendingSubscription.subscribe({\n ...config,\n abortSignal,\n });\n registerIterableCleanup(iterable, () => {\n cache.delete(deduplicationKey);\n });\n return iterable;\n },\n });\n const pendingSubscription: PendingRpcSubscriptionsRequest<unknown> = {\n async subscribe(...args) {\n const iterable = await iterableFactory(...args);\n const { abortSignal } = args[0];\n let abortPromise;\n return {\n ...iterable,\n async *[Symbol.asyncIterator]() {\n abortPromise ||= abortSignal.aborted\n ? Promise.reject(EXPLICIT_ABORT_TOKEN)\n : new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => {\n reject(EXPLICIT_ABORT_TOKEN);\n });\n });\n try {\n const iterator = iterable[Symbol.asyncIterator]();\n while (true) {\n const iteratorResult = await Promise.race([iterator.next(), abortPromise]);\n if (iteratorResult.done) {\n return;\n } else {\n yield iteratorResult.value;\n }\n }\n } catch (e) {\n if (e === EXPLICIT_ABORT_TOKEN) {\n return;\n }\n cache.delete(deduplicationKey);\n throw e;\n }\n },\n };\n },\n };\n cache.set(deduplicationKey, pendingSubscription);\n return pendingSubscription;\n };\n },\n });\n}\n","import { pipe } from '@solana/functional';\nimport { createWebSocketTransport } from '@solana/rpc-subscriptions-transport-websocket';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { getWebSocketTransportWithAutoping } from './rpc-subscriptions-autopinger';\nimport { RpcSubscriptionsTransportFromClusterUrl } from './rpc-subscriptions-clusters';\nimport { getWebSocketTransportWithConnectionSharding } from './rpc-subscriptions-connection-sharding';\n\ntype Config<TClusterUrl extends ClusterUrl> = Readonly<{\n url: TClusterUrl;\n}>;\n\nexport function createDefaultRpcSubscriptionsTransport<TClusterUrl extends ClusterUrl>(\n config: Config<TClusterUrl> & {\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows\n * for. Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string;\n intervalMs?: number;\n sendBufferHighWatermark?: number;\n },\n): RpcSubscriptionsTransportFromClusterUrl<TClusterUrl> {\n const { getShard, intervalMs, ...rest } = config;\n return pipe(\n createWebSocketTransport({\n ...rest,\n sendBufferHighWatermark:\n config.sendBufferHighWatermark ??\n // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n 131_072,\n }) as RpcSubscriptionsTransportFromClusterUrl<TClusterUrl>,\n transport =>\n getWebSocketTransportWithAutoping({\n intervalMs: intervalMs ?? 5_000,\n transport,\n }),\n transport =>\n getWebSocketTransportWithConnectionSharding({\n getShard,\n transport,\n }),\n );\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n intervalMs: number;\n transport: TTransport;\n}>;\n\nconst PING_PAYLOAD = {\n jsonrpc: '2.0',\n method: 'ping',\n} as const;\n\nexport function getWebSocketTransportWithAutoping<TTransport extends RpcSubscriptionsTransport>({\n intervalMs,\n transport,\n}: Config<TTransport>): TTransport {\n const pingableConnections = new Map<\n Awaited<ReturnType<RpcSubscriptionsTransport>>,\n Awaited<ReturnType<RpcSubscriptionsTransport>>\n >();\n return (async (...args) => {\n const connection = await transport(...args);\n let intervalId: ReturnType<typeof setInterval> | undefined;\n function sendPing() {\n connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);\n }\n function restartPingTimer() {\n clearInterval(intervalId);\n intervalId = setInterval(sendPing, intervalMs);\n }\n if (pingableConnections.has(connection) === false) {\n pingableConnections.set(connection, {\n [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),\n send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (\n ...args: Parameters<typeof connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>\n ) => {\n restartPingTimer();\n return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args);\n },\n });\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of connection) {\n restartPingTimer();\n }\n } catch {\n /* empty */\n } finally {\n pingableConnections.delete(connection);\n clearInterval(intervalId);\n if (handleOffline) {\n globalThis.window.removeEventListener('offline', handleOffline);\n }\n if (handleOnline) {\n globalThis.window.removeEventListener('online', handleOnline);\n }\n }\n })();\n if (!__BROWSER__ || globalThis.navigator.onLine) {\n restartPingTimer();\n }\n let handleOffline;\n let handleOnline;\n if (__BROWSER__) {\n handleOffline = () => {\n clearInterval(intervalId);\n };\n handleOnline = () => {\n sendPing();\n restartPingTimer();\n };\n globalThis.window.addEventListener('offline', handleOffline);\n globalThis.window.addEventListener('online', handleOnline);\n }\n }\n return pingableConnections.get(connection)!;\n }) as TTransport;\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows for.\n * Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string | symbol;\n transport: TTransport;\n}>;\n\nconst NULL_SHARD_CACHE_KEY = Symbol(\n __DEV__ ? 'Cache key to use when there is no connection sharding strategy' : undefined,\n);\n\nexport function getWebSocketTransportWithConnectionSharding<TTransport extends RpcSubscriptionsTransport>({\n getShard,\n transport,\n}: Config<TTransport>): TTransport {\n return getCachedAbortableIterableFactory({\n getAbortSignalFromInputArgs: ({ signal }) => signal,\n getCacheEntryMissingError(shardKey) {\n // TODO: Coded error.\n return new Error(`Found no cache entry for connection with shard key \\`${shardKey?.toString()}\\``);\n },\n getCacheKeyFromInputArgs: ({ payload }) => (getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY),\n onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),\n onCreateIterable: (abortSignal, config) =>\n transport({\n ...config,\n signal: abortSignal,\n }),\n }) as TTransport;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../build-scripts/env-shim.ts","../src/index.ts","../src/rpc-subscriptions.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/cached-abortable-iterable.ts","../src/rpc-subscriptions-coalescer.ts","../src/rpc-subscriptions-transport.ts","../src/rpc-subscriptions-autopinger.ts","../src/rpc-subscriptions-connection-sharding.ts"],"names":["pipe","SolanaError","registerIterableCleanup","pendingSubscription","args"],"mappings":"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","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export * from '@solana/rpc-subscriptions-api';\nexport * from '@solana/rpc-subscriptions-spec';\n\nexport * from './rpc-subscriptions';\nexport * from './rpc-subscriptions-clusters';\nexport * from './rpc-subscriptions-transport';\n","import { pipe } from '@solana/functional';\nimport type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\nimport {\n createSubscriptionRpc,\n RpcSubscriptionsApiMethods,\n type RpcSubscriptionsTransport,\n} from '@solana/rpc-subscriptions-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport type { RpcSubscriptionsFromTransport } from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsWithSubscriptionCoalescing } from './rpc-subscriptions-coalescer';\nimport {\n createDefaultRpcSubscriptionsTransport,\n DefaultRpcSubscriptionsTransportConfig,\n} from './rpc-subscriptions-transport';\n\nexport function createSolanaRpcSubscriptions<\n TClusterUrl extends ClusterUrl,\n TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi,\n>(clusterUrl: TClusterUrl, config?: Omit<DefaultRpcSubscriptionsTransportConfig<TClusterUrl>, 'url'>) {\n const transport = createDefaultRpcSubscriptionsTransport({ url: clusterUrl, ...config });\n return createSolanaRpcSubscriptionsFromTransport<typeof transport, TApi>(transport);\n}\n\nexport function createSolanaRpcSubscriptions_UNSTABLE<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcSubscriptionsTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcSubscriptions<TClusterUrl, SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>(\n clusterUrl,\n config,\n );\n}\n\nexport function createSolanaRpcSubscriptionsFromTransport<\n TTransport extends RpcSubscriptionsTransport,\n TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi,\n>(transport: TTransport) {\n return pipe(\n createSubscriptionRpc({\n api: createSolanaRpcSubscriptionsApi<TApi>(DEFAULT_RPC_CONFIG),\n transport,\n }),\n rpcSubscriptions =>\n getRpcSubscriptionsWithSubscriptionCoalescing({\n getDeduplicationKey: (...args) => fastStableStringify(args),\n rpcSubscriptions,\n }),\n ) as RpcSubscriptionsFromTransport<TApi, TTransport>;\n}\n\nexport function createSolanaRpcSubscriptionsFromTransport_UNSTABLE<TTransport extends RpcSubscriptionsTransport>(\n transport: TTransport,\n) {\n return createSolanaRpcSubscriptionsFromTransport<\n TTransport,\n SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable\n >(transport);\n}\n","import { SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n }\n return error;\n}\n","import type { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcSubscriptionsApi>[0]> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(methodName, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING,\n SolanaError,\n} from '@solana/errors';\n\ntype CacheEntry<TIterable extends AsyncIterable<unknown>> = {\n abortController: AbortController;\n iterable: Promise<TIterable> | TIterable;\n purgeScheduled: boolean;\n referenceCount: number;\n};\ntype CacheKey = string | symbol;\ntype Config<TInput extends unknown[], TIterable extends AsyncIterable<unknown>> = Readonly<{\n getAbortSignalFromInputArgs: (...args: TInput) => AbortSignal;\n getCacheKeyFromInputArgs: (...args: TInput) =>\n | CacheKey\n // `undefined` implies 'do not cache'\n | undefined;\n onCacheHit: (iterable: TIterable, ...args: TInput) => Promise<void>;\n onCreateIterable: (abortSignal: AbortSignal, ...args: TInput) => Promise<TIterable>;\n}>;\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getCachedAbortableIterableFactory<TInput extends unknown[], TIterable extends AsyncIterable<unknown>>({\n getAbortSignalFromInputArgs,\n getCacheKeyFromInputArgs,\n onCacheHit,\n onCreateIterable,\n}: Config<TInput, TIterable>): (...args: TInput) => Promise<TIterable> {\n const cache = new Map<CacheKey, CacheEntry<TIterable>>();\n function getCacheEntryOrThrow(cacheKey: CacheKey) {\n const currentCacheEntry = cache.get(cacheKey);\n if (!currentCacheEntry) {\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING, {\n cacheKey: cacheKey.toString(),\n });\n }\n return currentCacheEntry;\n }\n return async (...args: TInput) => {\n const cacheKey = getCacheKeyFromInputArgs(...args);\n const signal = getAbortSignalFromInputArgs(...args);\n if (cacheKey === undefined) {\n return await onCreateIterable(signal, ...args);\n }\n const cleanup = () => {\n cache.delete(cacheKey);\n signal.removeEventListener('abort', handleAbort);\n };\n const handleAbort = () => {\n const cacheEntry = getCacheEntryOrThrow(cacheKey);\n if (cacheEntry.purgeScheduled !== true) {\n cacheEntry.purgeScheduled = true;\n globalThis.queueMicrotask(() => {\n cacheEntry.purgeScheduled = false;\n if (cacheEntry.referenceCount === 0) {\n cacheEntry.abortController.abort();\n cleanup();\n }\n });\n }\n cacheEntry.referenceCount--;\n };\n signal.addEventListener('abort', handleAbort);\n try {\n const cacheEntry = cache.get(cacheKey);\n if (!cacheEntry) {\n const singletonAbortController = new AbortController();\n const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);\n const newCacheEntry: CacheEntry<TIterable> = {\n abortController: singletonAbortController,\n iterable: newIterablePromise,\n purgeScheduled: false,\n referenceCount: 1,\n };\n cache.set(cacheKey, newCacheEntry);\n const newIterable = await newIterablePromise;\n registerIterableCleanup(newIterable, cleanup);\n newCacheEntry.iterable = newIterable;\n return newIterable;\n } else {\n cacheEntry.referenceCount++;\n const iterableOrIterablePromise = cacheEntry.iterable;\n const cachedIterable =\n 'then' in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;\n await onCacheHit(cachedIterable, ...args);\n return cachedIterable;\n }\n } catch (e) {\n cleanup();\n throw e;\n }\n };\n}\n","import { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype CacheKey = string | undefined;\ntype Config<TRpcSubscriptionsMethods> = Readonly<{\n getDeduplicationKey: GetDeduplicationKeyFn;\n rpcSubscriptions: RpcSubscriptions<TRpcSubscriptionsMethods>;\n}>;\ntype GetDeduplicationKeyFn = (subscriptionMethod: string | symbol, payload: unknown) => CacheKey;\n\nconst EXPLICIT_ABORT_TOKEN = Symbol(\n __DEV__\n ? \"This symbol is thrown from a subscription's iterator when the subscription is \" +\n 'explicitly aborted by the user'\n : undefined,\n);\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getRpcSubscriptionsWithSubscriptionCoalescing<TRpcSubscriptionsMethods>({\n getDeduplicationKey,\n rpcSubscriptions,\n}: Config<TRpcSubscriptionsMethods>): RpcSubscriptions<TRpcSubscriptionsMethods> {\n const cache = new Map<CacheKey, PendingRpcSubscriptionsRequest<unknown>>();\n return new Proxy(rpcSubscriptions, {\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n get(target, p, receiver) {\n const subscriptionMethod = Reflect.get(target, p, receiver);\n if (typeof subscriptionMethod !== 'function') {\n return subscriptionMethod;\n }\n return function (...rawParams: unknown[]) {\n const deduplicationKey = getDeduplicationKey(p, rawParams);\n if (deduplicationKey === undefined) {\n return (subscriptionMethod as CallableFunction)(...rawParams);\n }\n if (cache.has(deduplicationKey)) {\n return cache.get(deduplicationKey)!;\n }\n const iterableFactory = getCachedAbortableIterableFactory<\n Parameters<PendingRpcSubscriptionsRequest<unknown>['subscribe']>,\n AsyncIterable<unknown>\n >({\n getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,\n getCacheKeyFromInputArgs: () => deduplicationKey,\n async onCacheHit(_iterable, _config) {\n /**\n * This transport's goal is to prevent duplicate subscriptions from\n * being made. If a cached iterable] is found, do not send the subscribe\n * message again.\n */\n },\n async onCreateIterable(abortSignal, config) {\n const pendingSubscription = (subscriptionMethod as CallableFunction)(\n ...rawParams,\n ) as PendingRpcSubscriptionsRequest<unknown>;\n const iterable = await pendingSubscription.subscribe({\n ...config,\n abortSignal,\n });\n registerIterableCleanup(iterable, () => {\n cache.delete(deduplicationKey);\n });\n return iterable;\n },\n });\n const pendingSubscription: PendingRpcSubscriptionsRequest<unknown> = {\n async subscribe(...args) {\n const iterable = await iterableFactory(...args);\n const { abortSignal } = args[0];\n let abortPromise;\n return {\n ...iterable,\n async *[Symbol.asyncIterator]() {\n abortPromise ||= abortSignal.aborted\n ? Promise.reject(EXPLICIT_ABORT_TOKEN)\n : new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => {\n reject(EXPLICIT_ABORT_TOKEN);\n });\n });\n try {\n const iterator = iterable[Symbol.asyncIterator]();\n while (true) {\n const iteratorResult = await Promise.race([iterator.next(), abortPromise]);\n if (iteratorResult.done) {\n return;\n } else {\n yield iteratorResult.value;\n }\n }\n } catch (e) {\n if (e === EXPLICIT_ABORT_TOKEN) {\n return;\n }\n cache.delete(deduplicationKey);\n throw e;\n }\n },\n };\n },\n };\n cache.set(deduplicationKey, pendingSubscription);\n return pendingSubscription;\n };\n },\n });\n}\n","import { pipe } from '@solana/functional';\nimport { createWebSocketTransport } from '@solana/rpc-subscriptions-transport-websocket';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { getWebSocketTransportWithAutoping } from './rpc-subscriptions-autopinger';\nimport { RpcSubscriptionsTransportFromClusterUrl } from './rpc-subscriptions-clusters';\nimport { getWebSocketTransportWithConnectionSharding } from './rpc-subscriptions-connection-sharding';\n\nexport type DefaultRpcSubscriptionsTransportConfig<TClusterUrl extends ClusterUrl> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows\n * for. Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string;\n intervalMs?: number;\n sendBufferHighWatermark?: number;\n url: TClusterUrl;\n}>;\n\nexport function createDefaultRpcSubscriptionsTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcSubscriptionsTransportConfig<TClusterUrl>,\n): RpcSubscriptionsTransportFromClusterUrl<TClusterUrl> {\n const { getShard, intervalMs, ...rest } = config;\n return pipe(\n createWebSocketTransport({\n ...rest,\n sendBufferHighWatermark:\n config.sendBufferHighWatermark ??\n // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n 131_072,\n }) as RpcSubscriptionsTransportFromClusterUrl<TClusterUrl>,\n transport =>\n getWebSocketTransportWithAutoping({\n intervalMs: intervalMs ?? 5_000,\n transport,\n }),\n transport =>\n getWebSocketTransportWithConnectionSharding({\n getShard,\n transport,\n }),\n );\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n intervalMs: number;\n transport: TTransport;\n}>;\n\nconst PING_PAYLOAD = {\n jsonrpc: '2.0',\n method: 'ping',\n} as const;\n\nexport function getWebSocketTransportWithAutoping<TTransport extends RpcSubscriptionsTransport>({\n intervalMs,\n transport,\n}: Config<TTransport>): TTransport {\n const pingableConnections = new Map<\n Awaited<ReturnType<RpcSubscriptionsTransport>>,\n Awaited<ReturnType<RpcSubscriptionsTransport>>\n >();\n return (async (...args) => {\n const connection = await transport(...args);\n let intervalId: ReturnType<typeof setInterval> | undefined;\n function sendPing() {\n connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);\n }\n function restartPingTimer() {\n clearInterval(intervalId);\n intervalId = setInterval(sendPing, intervalMs);\n }\n if (pingableConnections.has(connection) === false) {\n pingableConnections.set(connection, {\n [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),\n send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (\n ...args: Parameters<typeof connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>\n ) => {\n restartPingTimer();\n return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args);\n },\n });\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of connection) {\n restartPingTimer();\n }\n } catch {\n /* empty */\n } finally {\n pingableConnections.delete(connection);\n clearInterval(intervalId);\n if (handleOffline) {\n globalThis.window.removeEventListener('offline', handleOffline);\n }\n if (handleOnline) {\n globalThis.window.removeEventListener('online', handleOnline);\n }\n }\n })();\n if (!__BROWSER__ || globalThis.navigator.onLine) {\n restartPingTimer();\n }\n let handleOffline;\n let handleOnline;\n if (__BROWSER__) {\n handleOffline = () => {\n clearInterval(intervalId);\n };\n handleOnline = () => {\n sendPing();\n restartPingTimer();\n };\n globalThis.window.addEventListener('offline', handleOffline);\n globalThis.window.addEventListener('online', handleOnline);\n }\n }\n return pingableConnections.get(connection)!;\n }) as TTransport;\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows for.\n * Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string | symbol;\n transport: TTransport;\n}>;\n\nconst NULL_SHARD_CACHE_KEY = Symbol(\n __DEV__ ? 'Cache key to use when there is no connection sharding strategy' : undefined,\n);\n\nexport function getWebSocketTransportWithConnectionSharding<TTransport extends RpcSubscriptionsTransport>({\n getShard,\n transport,\n}: Config<TTransport>): TTransport {\n return getCachedAbortableIterableFactory({\n getAbortSignalFromInputArgs: ({ signal }) => signal,\n getCacheKeyFromInputArgs: ({ payload }) => (getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY),\n onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),\n onCreateIterable: (abortSignal, config) =>\n transport({\n ...config,\n signal: abortSignal,\n }),\n }) as TTransport;\n}\n"]}
|
package/dist/index.browser.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { createSolanaRpcSubscriptionsApi
|
|
1
|
+
import { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';
|
|
2
2
|
export * from '@solana/rpc-subscriptions-api';
|
|
3
3
|
import { createSubscriptionRpc } from '@solana/rpc-subscriptions-spec';
|
|
4
4
|
export * from '@solana/rpc-subscriptions-spec';
|
|
5
5
|
import { pipe } from '@solana/functional';
|
|
6
6
|
import fastStableStringify from 'fast-stable-stringify';
|
|
7
|
-
import { SolanaError,
|
|
7
|
+
import { SolanaError, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING } from '@solana/errors';
|
|
8
8
|
import { createWebSocketTransport } from '@solana/rpc-subscriptions-transport-websocket';
|
|
9
9
|
|
|
10
10
|
// ../build-scripts/env-shim.ts
|
|
@@ -28,7 +28,7 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
|
|
|
28
28
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
29
29
|
}
|
|
30
30
|
const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
31
|
-
const error = new SolanaError(
|
|
31
|
+
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
32
32
|
argumentLabel,
|
|
33
33
|
keyPath,
|
|
34
34
|
methodName,
|
|
@@ -49,8 +49,6 @@ var DEFAULT_RPC_CONFIG = {
|
|
|
49
49
|
throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
-
|
|
53
|
-
// src/cached-abortable-iterable.ts
|
|
54
52
|
function registerIterableCleanup(iterable, cleanupFn) {
|
|
55
53
|
(async () => {
|
|
56
54
|
try {
|
|
@@ -64,7 +62,6 @@ function registerIterableCleanup(iterable, cleanupFn) {
|
|
|
64
62
|
}
|
|
65
63
|
function getCachedAbortableIterableFactory({
|
|
66
64
|
getAbortSignalFromInputArgs,
|
|
67
|
-
getCacheEntryMissingError,
|
|
68
65
|
getCacheKeyFromInputArgs,
|
|
69
66
|
onCacheHit,
|
|
70
67
|
onCreateIterable
|
|
@@ -73,7 +70,9 @@ function getCachedAbortableIterableFactory({
|
|
|
73
70
|
function getCacheEntryOrThrow(cacheKey) {
|
|
74
71
|
const currentCacheEntry = cache.get(cacheKey);
|
|
75
72
|
if (!currentCacheEntry) {
|
|
76
|
-
throw
|
|
73
|
+
throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING, {
|
|
74
|
+
cacheKey: cacheKey.toString()
|
|
75
|
+
});
|
|
77
76
|
}
|
|
78
77
|
return currentCacheEntry;
|
|
79
78
|
}
|
|
@@ -174,11 +173,6 @@ function getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
|
174
173
|
}
|
|
175
174
|
const iterableFactory = getCachedAbortableIterableFactory({
|
|
176
175
|
getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,
|
|
177
|
-
getCacheEntryMissingError(deduplicationKey2) {
|
|
178
|
-
return new Error(
|
|
179
|
-
`Found no cache entry for subscription with deduplication key \`${deduplicationKey2?.toString()}\``
|
|
180
|
-
);
|
|
181
|
-
},
|
|
182
176
|
getCacheKeyFromInputArgs: () => deduplicationKey,
|
|
183
177
|
async onCacheHit(_iterable, _config) {
|
|
184
178
|
},
|
|
@@ -237,26 +231,6 @@ function getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
|
237
231
|
});
|
|
238
232
|
}
|
|
239
233
|
|
|
240
|
-
// src/rpc-subscriptions.ts
|
|
241
|
-
function createSolanaRpcSubscriptions(config) {
|
|
242
|
-
return pipe(
|
|
243
|
-
createSubscriptionRpc({
|
|
244
|
-
...config,
|
|
245
|
-
api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG)
|
|
246
|
-
}),
|
|
247
|
-
(rpcSubscriptions) => getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
248
|
-
getDeduplicationKey: (...args) => fastStableStringify(args),
|
|
249
|
-
rpcSubscriptions
|
|
250
|
-
})
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
function createSolanaRpcSubscriptions_UNSTABLE(config) {
|
|
254
|
-
return createSubscriptionRpc({
|
|
255
|
-
...config,
|
|
256
|
-
api: createSolanaRpcSubscriptionsApi_UNSTABLE(DEFAULT_RPC_CONFIG)
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
234
|
// src/rpc-subscriptions-autopinger.ts
|
|
261
235
|
var PING_PAYLOAD = {
|
|
262
236
|
jsonrpc: "2.0",
|
|
@@ -333,9 +307,6 @@ function getWebSocketTransportWithConnectionSharding({
|
|
|
333
307
|
}) {
|
|
334
308
|
return getCachedAbortableIterableFactory({
|
|
335
309
|
getAbortSignalFromInputArgs: ({ signal }) => signal,
|
|
336
|
-
getCacheEntryMissingError(shardKey) {
|
|
337
|
-
return new Error(`Found no cache entry for connection with shard key \`${shardKey?.toString()}\``);
|
|
338
|
-
},
|
|
339
310
|
getCacheKeyFromInputArgs: ({ payload }) => getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY,
|
|
340
311
|
onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),
|
|
341
312
|
onCreateIterable: (abortSignal, config) => transport({
|
|
@@ -365,6 +336,33 @@ function createDefaultRpcSubscriptionsTransport(config) {
|
|
|
365
336
|
);
|
|
366
337
|
}
|
|
367
338
|
|
|
368
|
-
|
|
339
|
+
// src/rpc-subscriptions.ts
|
|
340
|
+
function createSolanaRpcSubscriptions(clusterUrl, config) {
|
|
341
|
+
const transport = createDefaultRpcSubscriptionsTransport({ url: clusterUrl, ...config });
|
|
342
|
+
return createSolanaRpcSubscriptionsFromTransport(transport);
|
|
343
|
+
}
|
|
344
|
+
function createSolanaRpcSubscriptions_UNSTABLE(clusterUrl, config) {
|
|
345
|
+
return createSolanaRpcSubscriptions(
|
|
346
|
+
clusterUrl,
|
|
347
|
+
config
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
function createSolanaRpcSubscriptionsFromTransport(transport) {
|
|
351
|
+
return pipe(
|
|
352
|
+
createSubscriptionRpc({
|
|
353
|
+
api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),
|
|
354
|
+
transport
|
|
355
|
+
}),
|
|
356
|
+
(rpcSubscriptions) => getRpcSubscriptionsWithSubscriptionCoalescing({
|
|
357
|
+
getDeduplicationKey: (...args) => fastStableStringify(args),
|
|
358
|
+
rpcSubscriptions
|
|
359
|
+
})
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
function createSolanaRpcSubscriptionsFromTransport_UNSTABLE(transport) {
|
|
363
|
+
return createSolanaRpcSubscriptionsFromTransport(transport);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export { createDefaultRpcSubscriptionsTransport, createSolanaRpcSubscriptions, createSolanaRpcSubscriptionsFromTransport, createSolanaRpcSubscriptionsFromTransport_UNSTABLE, createSolanaRpcSubscriptions_UNSTABLE };
|
|
369
367
|
//# sourceMappingURL=out.js.map
|
|
370
368
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../build-scripts/env-shim.ts","../src/index.ts","../src/rpc-subscriptions.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/cached-abortable-iterable.ts","../src/rpc-subscriptions-coalescer.ts","../src/rpc-subscriptions-transport.ts","../src/rpc-subscriptions-autopinger.ts","../src/rpc-subscriptions-connection-sharding.ts"],"names":["registerIterableCleanup","deduplicationKey","pendingSubscription","pipe","args"],"mappings":"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","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export * from '@solana/rpc-subscriptions-api';\nexport * from '@solana/rpc-subscriptions-spec';\n\nexport * from './rpc-subscriptions';\nexport * from './rpc-subscriptions-clusters';\nexport * from './rpc-subscriptions-transport';\n","import { pipe } from '@solana/functional';\nimport type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport {\n createSolanaRpcSubscriptionsApi,\n createSolanaRpcSubscriptionsApi_UNSTABLE,\n} from '@solana/rpc-subscriptions-api';\nimport { createSubscriptionRpc, type RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport type { RpcSubscriptionsFromTransport } from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsWithSubscriptionCoalescing } from './rpc-subscriptions-coalescer';\n\ntype RpcSubscriptionsConfig<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n transport: TTransport;\n}>;\n\nexport function createSolanaRpcSubscriptions<TTransport extends RpcSubscriptionsTransport>(\n config: RpcSubscriptionsConfig<TTransport>,\n): RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi, TTransport> {\n return pipe(\n createSubscriptionRpc({\n ...config,\n api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),\n }),\n rpcSubscriptions =>\n getRpcSubscriptionsWithSubscriptionCoalescing({\n getDeduplicationKey: (...args) => fastStableStringify(args),\n rpcSubscriptions,\n }),\n ) as RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi, TTransport>;\n}\n\nexport function createSolanaRpcSubscriptions_UNSTABLE<TTransport extends RpcSubscriptionsTransport>(\n config: RpcSubscriptionsConfig<TTransport>,\n): RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable, TTransport> {\n return createSubscriptionRpc({\n ...config,\n api: createSolanaRpcSubscriptionsApi_UNSTABLE(DEFAULT_RPC_CONFIG),\n }) as RpcSubscriptionsFromTransport<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable, TTransport>;\n}\n","import { SOLANA_ERROR__RPC_INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC_INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC_INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (string | number | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n }\n return error;\n}\n","import type { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcSubscriptionsApi>[0]> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(methodName, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","type CacheEntry<TIterable extends AsyncIterable<unknown>> = {\n abortController: AbortController;\n iterable: Promise<TIterable> | TIterable;\n purgeScheduled: boolean;\n referenceCount: number;\n};\ntype CacheKey = string | symbol;\ntype Config<TInput extends unknown[], TIterable extends AsyncIterable<unknown>> = Readonly<{\n getAbortSignalFromInputArgs: (...args: TInput) => AbortSignal;\n getCacheEntryMissingError: (cacheKey: CacheKey) => Error;\n getCacheKeyFromInputArgs: (...args: TInput) =>\n | CacheKey\n // `undefined` implies 'do not cache'\n | undefined;\n onCacheHit: (iterable: TIterable, ...args: TInput) => Promise<void>;\n onCreateIterable: (abortSignal: AbortSignal, ...args: TInput) => Promise<TIterable>;\n}>;\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getCachedAbortableIterableFactory<TInput extends unknown[], TIterable extends AsyncIterable<unknown>>({\n getAbortSignalFromInputArgs,\n getCacheEntryMissingError,\n getCacheKeyFromInputArgs,\n onCacheHit,\n onCreateIterable,\n}: Config<TInput, TIterable>): (...args: TInput) => Promise<TIterable> {\n const cache = new Map<CacheKey, CacheEntry<TIterable>>();\n function getCacheEntryOrThrow(cacheKey: CacheKey) {\n const currentCacheEntry = cache.get(cacheKey);\n if (!currentCacheEntry) {\n throw getCacheEntryMissingError(cacheKey);\n }\n return currentCacheEntry;\n }\n return async (...args: TInput) => {\n const cacheKey = getCacheKeyFromInputArgs(...args);\n const signal = getAbortSignalFromInputArgs(...args);\n if (cacheKey === undefined) {\n return await onCreateIterable(signal, ...args);\n }\n const cleanup = () => {\n cache.delete(cacheKey);\n signal.removeEventListener('abort', handleAbort);\n };\n const handleAbort = () => {\n const cacheEntry = getCacheEntryOrThrow(cacheKey);\n if (cacheEntry.purgeScheduled !== true) {\n cacheEntry.purgeScheduled = true;\n globalThis.queueMicrotask(() => {\n cacheEntry.purgeScheduled = false;\n if (cacheEntry.referenceCount === 0) {\n cacheEntry.abortController.abort();\n cleanup();\n }\n });\n }\n cacheEntry.referenceCount--;\n };\n signal.addEventListener('abort', handleAbort);\n try {\n const cacheEntry = cache.get(cacheKey);\n if (!cacheEntry) {\n const singletonAbortController = new AbortController();\n const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);\n const newCacheEntry: CacheEntry<TIterable> = {\n abortController: singletonAbortController,\n iterable: newIterablePromise,\n purgeScheduled: false,\n referenceCount: 1,\n };\n cache.set(cacheKey, newCacheEntry);\n const newIterable = await newIterablePromise;\n registerIterableCleanup(newIterable, cleanup);\n newCacheEntry.iterable = newIterable;\n return newIterable;\n } else {\n cacheEntry.referenceCount++;\n const iterableOrIterablePromise = cacheEntry.iterable;\n const cachedIterable =\n 'then' in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;\n await onCacheHit(cachedIterable, ...args);\n return cachedIterable;\n }\n } catch (e) {\n cleanup();\n throw e;\n }\n };\n}\n","import { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype CacheKey = string | undefined;\ntype Config<TRpcSubscriptionsMethods> = Readonly<{\n getDeduplicationKey: GetDeduplicationKeyFn;\n rpcSubscriptions: RpcSubscriptions<TRpcSubscriptionsMethods>;\n}>;\ntype GetDeduplicationKeyFn = (subscriptionMethod: string | symbol, payload: unknown) => CacheKey;\n\nconst EXPLICIT_ABORT_TOKEN = Symbol(\n __DEV__\n ? \"This symbol is thrown from a subscription's iterator when the subscription is \" +\n 'explicitly aborted by the user'\n : undefined,\n);\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getRpcSubscriptionsWithSubscriptionCoalescing<TRpcSubscriptionsMethods>({\n getDeduplicationKey,\n rpcSubscriptions,\n}: Config<TRpcSubscriptionsMethods>): RpcSubscriptions<TRpcSubscriptionsMethods> {\n const cache = new Map<CacheKey, PendingRpcSubscriptionsRequest<unknown>>();\n return new Proxy(rpcSubscriptions, {\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n get(target, p, receiver) {\n const subscriptionMethod = Reflect.get(target, p, receiver);\n if (typeof subscriptionMethod !== 'function') {\n return subscriptionMethod;\n }\n return function (...rawParams: unknown[]) {\n const deduplicationKey = getDeduplicationKey(p, rawParams);\n if (deduplicationKey === undefined) {\n return (subscriptionMethod as CallableFunction)(...rawParams);\n }\n if (cache.has(deduplicationKey)) {\n return cache.get(deduplicationKey)!;\n }\n const iterableFactory = getCachedAbortableIterableFactory<\n Parameters<PendingRpcSubscriptionsRequest<unknown>['subscribe']>,\n AsyncIterable<unknown>\n >({\n getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,\n getCacheEntryMissingError(deduplicationKey) {\n // TODO: Coded error.\n return new Error(\n `Found no cache entry for subscription with deduplication key \\`${deduplicationKey?.toString()}\\``,\n );\n },\n getCacheKeyFromInputArgs: () => deduplicationKey,\n async onCacheHit(_iterable, _config) {\n /**\n * This transport's goal is to prevent duplicate subscriptions from\n * being made. If a cached iterable] is found, do not send the subscribe\n * message again.\n */\n },\n async onCreateIterable(abortSignal, config) {\n const pendingSubscription = (subscriptionMethod as CallableFunction)(\n ...rawParams,\n ) as PendingRpcSubscriptionsRequest<unknown>;\n const iterable = await pendingSubscription.subscribe({\n ...config,\n abortSignal,\n });\n registerIterableCleanup(iterable, () => {\n cache.delete(deduplicationKey);\n });\n return iterable;\n },\n });\n const pendingSubscription: PendingRpcSubscriptionsRequest<unknown> = {\n async subscribe(...args) {\n const iterable = await iterableFactory(...args);\n const { abortSignal } = args[0];\n let abortPromise;\n return {\n ...iterable,\n async *[Symbol.asyncIterator]() {\n abortPromise ||= abortSignal.aborted\n ? Promise.reject(EXPLICIT_ABORT_TOKEN)\n : new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => {\n reject(EXPLICIT_ABORT_TOKEN);\n });\n });\n try {\n const iterator = iterable[Symbol.asyncIterator]();\n while (true) {\n const iteratorResult = await Promise.race([iterator.next(), abortPromise]);\n if (iteratorResult.done) {\n return;\n } else {\n yield iteratorResult.value;\n }\n }\n } catch (e) {\n if (e === EXPLICIT_ABORT_TOKEN) {\n return;\n }\n cache.delete(deduplicationKey);\n throw e;\n }\n },\n };\n },\n };\n cache.set(deduplicationKey, pendingSubscription);\n return pendingSubscription;\n };\n },\n });\n}\n","import { pipe } from '@solana/functional';\nimport { createWebSocketTransport } from '@solana/rpc-subscriptions-transport-websocket';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { getWebSocketTransportWithAutoping } from './rpc-subscriptions-autopinger';\nimport { RpcSubscriptionsTransportFromClusterUrl } from './rpc-subscriptions-clusters';\nimport { getWebSocketTransportWithConnectionSharding } from './rpc-subscriptions-connection-sharding';\n\ntype Config<TClusterUrl extends ClusterUrl> = Readonly<{\n url: TClusterUrl;\n}>;\n\nexport function createDefaultRpcSubscriptionsTransport<TClusterUrl extends ClusterUrl>(\n config: Config<TClusterUrl> & {\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows\n * for. Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string;\n intervalMs?: number;\n sendBufferHighWatermark?: number;\n },\n): RpcSubscriptionsTransportFromClusterUrl<TClusterUrl> {\n const { getShard, intervalMs, ...rest } = config;\n return pipe(\n createWebSocketTransport({\n ...rest,\n sendBufferHighWatermark:\n config.sendBufferHighWatermark ??\n // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n 131_072,\n }) as RpcSubscriptionsTransportFromClusterUrl<TClusterUrl>,\n transport =>\n getWebSocketTransportWithAutoping({\n intervalMs: intervalMs ?? 5_000,\n transport,\n }),\n transport =>\n getWebSocketTransportWithConnectionSharding({\n getShard,\n transport,\n }),\n );\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n intervalMs: number;\n transport: TTransport;\n}>;\n\nconst PING_PAYLOAD = {\n jsonrpc: '2.0',\n method: 'ping',\n} as const;\n\nexport function getWebSocketTransportWithAutoping<TTransport extends RpcSubscriptionsTransport>({\n intervalMs,\n transport,\n}: Config<TTransport>): TTransport {\n const pingableConnections = new Map<\n Awaited<ReturnType<RpcSubscriptionsTransport>>,\n Awaited<ReturnType<RpcSubscriptionsTransport>>\n >();\n return (async (...args) => {\n const connection = await transport(...args);\n let intervalId: ReturnType<typeof setInterval> | undefined;\n function sendPing() {\n connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);\n }\n function restartPingTimer() {\n clearInterval(intervalId);\n intervalId = setInterval(sendPing, intervalMs);\n }\n if (pingableConnections.has(connection) === false) {\n pingableConnections.set(connection, {\n [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),\n send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (\n ...args: Parameters<typeof connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>\n ) => {\n restartPingTimer();\n return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args);\n },\n });\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of connection) {\n restartPingTimer();\n }\n } catch {\n /* empty */\n } finally {\n pingableConnections.delete(connection);\n clearInterval(intervalId);\n if (handleOffline) {\n globalThis.window.removeEventListener('offline', handleOffline);\n }\n if (handleOnline) {\n globalThis.window.removeEventListener('online', handleOnline);\n }\n }\n })();\n if (!__BROWSER__ || globalThis.navigator.onLine) {\n restartPingTimer();\n }\n let handleOffline;\n let handleOnline;\n if (__BROWSER__) {\n handleOffline = () => {\n clearInterval(intervalId);\n };\n handleOnline = () => {\n sendPing();\n restartPingTimer();\n };\n globalThis.window.addEventListener('offline', handleOffline);\n globalThis.window.addEventListener('online', handleOnline);\n }\n }\n return pingableConnections.get(connection)!;\n }) as TTransport;\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows for.\n * Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string | symbol;\n transport: TTransport;\n}>;\n\nconst NULL_SHARD_CACHE_KEY = Symbol(\n __DEV__ ? 'Cache key to use when there is no connection sharding strategy' : undefined,\n);\n\nexport function getWebSocketTransportWithConnectionSharding<TTransport extends RpcSubscriptionsTransport>({\n getShard,\n transport,\n}: Config<TTransport>): TTransport {\n return getCachedAbortableIterableFactory({\n getAbortSignalFromInputArgs: ({ signal }) => signal,\n getCacheEntryMissingError(shardKey) {\n // TODO: Coded error.\n return new Error(`Found no cache entry for connection with shard key \\`${shardKey?.toString()}\\``);\n },\n getCacheKeyFromInputArgs: ({ payload }) => (getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY),\n onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),\n onCreateIterable: (abortSignal, config) =>\n transport({\n ...config,\n signal: abortSignal,\n }),\n }) as TTransport;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../build-scripts/env-shim.ts","../src/index.ts","../src/rpc-subscriptions.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/cached-abortable-iterable.ts","../src/rpc-subscriptions-coalescer.ts","../src/rpc-subscriptions-transport.ts","../src/rpc-subscriptions-autopinger.ts","../src/rpc-subscriptions-connection-sharding.ts"],"names":["pipe","SolanaError","registerIterableCleanup","pendingSubscription","args"],"mappings":"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","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export * from '@solana/rpc-subscriptions-api';\nexport * from '@solana/rpc-subscriptions-spec';\n\nexport * from './rpc-subscriptions';\nexport * from './rpc-subscriptions-clusters';\nexport * from './rpc-subscriptions-transport';\n","import { pipe } from '@solana/functional';\nimport type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\nimport {\n createSubscriptionRpc,\n RpcSubscriptionsApiMethods,\n type RpcSubscriptionsTransport,\n} from '@solana/rpc-subscriptions-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport type { RpcSubscriptionsFromTransport } from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsWithSubscriptionCoalescing } from './rpc-subscriptions-coalescer';\nimport {\n createDefaultRpcSubscriptionsTransport,\n DefaultRpcSubscriptionsTransportConfig,\n} from './rpc-subscriptions-transport';\n\nexport function createSolanaRpcSubscriptions<\n TClusterUrl extends ClusterUrl,\n TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi,\n>(clusterUrl: TClusterUrl, config?: Omit<DefaultRpcSubscriptionsTransportConfig<TClusterUrl>, 'url'>) {\n const transport = createDefaultRpcSubscriptionsTransport({ url: clusterUrl, ...config });\n return createSolanaRpcSubscriptionsFromTransport<typeof transport, TApi>(transport);\n}\n\nexport function createSolanaRpcSubscriptions_UNSTABLE<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcSubscriptionsTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcSubscriptions<TClusterUrl, SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>(\n clusterUrl,\n config,\n );\n}\n\nexport function createSolanaRpcSubscriptionsFromTransport<\n TTransport extends RpcSubscriptionsTransport,\n TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi,\n>(transport: TTransport) {\n return pipe(\n createSubscriptionRpc({\n api: createSolanaRpcSubscriptionsApi<TApi>(DEFAULT_RPC_CONFIG),\n transport,\n }),\n rpcSubscriptions =>\n getRpcSubscriptionsWithSubscriptionCoalescing({\n getDeduplicationKey: (...args) => fastStableStringify(args),\n rpcSubscriptions,\n }),\n ) as RpcSubscriptionsFromTransport<TApi, TTransport>;\n}\n\nexport function createSolanaRpcSubscriptionsFromTransport_UNSTABLE<TTransport extends RpcSubscriptionsTransport>(\n transport: TTransport,\n) {\n return createSolanaRpcSubscriptionsFromTransport<\n TTransport,\n SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable\n >(transport);\n}\n","import { SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n }\n return error;\n}\n","import type { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcSubscriptionsApi>[0]> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(methodName, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING,\n SolanaError,\n} from '@solana/errors';\n\ntype CacheEntry<TIterable extends AsyncIterable<unknown>> = {\n abortController: AbortController;\n iterable: Promise<TIterable> | TIterable;\n purgeScheduled: boolean;\n referenceCount: number;\n};\ntype CacheKey = string | symbol;\ntype Config<TInput extends unknown[], TIterable extends AsyncIterable<unknown>> = Readonly<{\n getAbortSignalFromInputArgs: (...args: TInput) => AbortSignal;\n getCacheKeyFromInputArgs: (...args: TInput) =>\n | CacheKey\n // `undefined` implies 'do not cache'\n | undefined;\n onCacheHit: (iterable: TIterable, ...args: TInput) => Promise<void>;\n onCreateIterable: (abortSignal: AbortSignal, ...args: TInput) => Promise<TIterable>;\n}>;\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getCachedAbortableIterableFactory<TInput extends unknown[], TIterable extends AsyncIterable<unknown>>({\n getAbortSignalFromInputArgs,\n getCacheKeyFromInputArgs,\n onCacheHit,\n onCreateIterable,\n}: Config<TInput, TIterable>): (...args: TInput) => Promise<TIterable> {\n const cache = new Map<CacheKey, CacheEntry<TIterable>>();\n function getCacheEntryOrThrow(cacheKey: CacheKey) {\n const currentCacheEntry = cache.get(cacheKey);\n if (!currentCacheEntry) {\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING, {\n cacheKey: cacheKey.toString(),\n });\n }\n return currentCacheEntry;\n }\n return async (...args: TInput) => {\n const cacheKey = getCacheKeyFromInputArgs(...args);\n const signal = getAbortSignalFromInputArgs(...args);\n if (cacheKey === undefined) {\n return await onCreateIterable(signal, ...args);\n }\n const cleanup = () => {\n cache.delete(cacheKey);\n signal.removeEventListener('abort', handleAbort);\n };\n const handleAbort = () => {\n const cacheEntry = getCacheEntryOrThrow(cacheKey);\n if (cacheEntry.purgeScheduled !== true) {\n cacheEntry.purgeScheduled = true;\n globalThis.queueMicrotask(() => {\n cacheEntry.purgeScheduled = false;\n if (cacheEntry.referenceCount === 0) {\n cacheEntry.abortController.abort();\n cleanup();\n }\n });\n }\n cacheEntry.referenceCount--;\n };\n signal.addEventListener('abort', handleAbort);\n try {\n const cacheEntry = cache.get(cacheKey);\n if (!cacheEntry) {\n const singletonAbortController = new AbortController();\n const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);\n const newCacheEntry: CacheEntry<TIterable> = {\n abortController: singletonAbortController,\n iterable: newIterablePromise,\n purgeScheduled: false,\n referenceCount: 1,\n };\n cache.set(cacheKey, newCacheEntry);\n const newIterable = await newIterablePromise;\n registerIterableCleanup(newIterable, cleanup);\n newCacheEntry.iterable = newIterable;\n return newIterable;\n } else {\n cacheEntry.referenceCount++;\n const iterableOrIterablePromise = cacheEntry.iterable;\n const cachedIterable =\n 'then' in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;\n await onCacheHit(cachedIterable, ...args);\n return cachedIterable;\n }\n } catch (e) {\n cleanup();\n throw e;\n }\n };\n}\n","import { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype CacheKey = string | undefined;\ntype Config<TRpcSubscriptionsMethods> = Readonly<{\n getDeduplicationKey: GetDeduplicationKeyFn;\n rpcSubscriptions: RpcSubscriptions<TRpcSubscriptionsMethods>;\n}>;\ntype GetDeduplicationKeyFn = (subscriptionMethod: string | symbol, payload: unknown) => CacheKey;\n\nconst EXPLICIT_ABORT_TOKEN = Symbol(\n __DEV__\n ? \"This symbol is thrown from a subscription's iterator when the subscription is \" +\n 'explicitly aborted by the user'\n : undefined,\n);\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getRpcSubscriptionsWithSubscriptionCoalescing<TRpcSubscriptionsMethods>({\n getDeduplicationKey,\n rpcSubscriptions,\n}: Config<TRpcSubscriptionsMethods>): RpcSubscriptions<TRpcSubscriptionsMethods> {\n const cache = new Map<CacheKey, PendingRpcSubscriptionsRequest<unknown>>();\n return new Proxy(rpcSubscriptions, {\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n get(target, p, receiver) {\n const subscriptionMethod = Reflect.get(target, p, receiver);\n if (typeof subscriptionMethod !== 'function') {\n return subscriptionMethod;\n }\n return function (...rawParams: unknown[]) {\n const deduplicationKey = getDeduplicationKey(p, rawParams);\n if (deduplicationKey === undefined) {\n return (subscriptionMethod as CallableFunction)(...rawParams);\n }\n if (cache.has(deduplicationKey)) {\n return cache.get(deduplicationKey)!;\n }\n const iterableFactory = getCachedAbortableIterableFactory<\n Parameters<PendingRpcSubscriptionsRequest<unknown>['subscribe']>,\n AsyncIterable<unknown>\n >({\n getAbortSignalFromInputArgs: ({ abortSignal }) => abortSignal,\n getCacheKeyFromInputArgs: () => deduplicationKey,\n async onCacheHit(_iterable, _config) {\n /**\n * This transport's goal is to prevent duplicate subscriptions from\n * being made. If a cached iterable] is found, do not send the subscribe\n * message again.\n */\n },\n async onCreateIterable(abortSignal, config) {\n const pendingSubscription = (subscriptionMethod as CallableFunction)(\n ...rawParams,\n ) as PendingRpcSubscriptionsRequest<unknown>;\n const iterable = await pendingSubscription.subscribe({\n ...config,\n abortSignal,\n });\n registerIterableCleanup(iterable, () => {\n cache.delete(deduplicationKey);\n });\n return iterable;\n },\n });\n const pendingSubscription: PendingRpcSubscriptionsRequest<unknown> = {\n async subscribe(...args) {\n const iterable = await iterableFactory(...args);\n const { abortSignal } = args[0];\n let abortPromise;\n return {\n ...iterable,\n async *[Symbol.asyncIterator]() {\n abortPromise ||= abortSignal.aborted\n ? Promise.reject(EXPLICIT_ABORT_TOKEN)\n : new Promise<never>((_, reject) => {\n abortSignal.addEventListener('abort', () => {\n reject(EXPLICIT_ABORT_TOKEN);\n });\n });\n try {\n const iterator = iterable[Symbol.asyncIterator]();\n while (true) {\n const iteratorResult = await Promise.race([iterator.next(), abortPromise]);\n if (iteratorResult.done) {\n return;\n } else {\n yield iteratorResult.value;\n }\n }\n } catch (e) {\n if (e === EXPLICIT_ABORT_TOKEN) {\n return;\n }\n cache.delete(deduplicationKey);\n throw e;\n }\n },\n };\n },\n };\n cache.set(deduplicationKey, pendingSubscription);\n return pendingSubscription;\n };\n },\n });\n}\n","import { pipe } from '@solana/functional';\nimport { createWebSocketTransport } from '@solana/rpc-subscriptions-transport-websocket';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { getWebSocketTransportWithAutoping } from './rpc-subscriptions-autopinger';\nimport { RpcSubscriptionsTransportFromClusterUrl } from './rpc-subscriptions-clusters';\nimport { getWebSocketTransportWithConnectionSharding } from './rpc-subscriptions-connection-sharding';\n\nexport type DefaultRpcSubscriptionsTransportConfig<TClusterUrl extends ClusterUrl> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows\n * for. Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string;\n intervalMs?: number;\n sendBufferHighWatermark?: number;\n url: TClusterUrl;\n}>;\n\nexport function createDefaultRpcSubscriptionsTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcSubscriptionsTransportConfig<TClusterUrl>,\n): RpcSubscriptionsTransportFromClusterUrl<TClusterUrl> {\n const { getShard, intervalMs, ...rest } = config;\n return pipe(\n createWebSocketTransport({\n ...rest,\n sendBufferHighWatermark:\n config.sendBufferHighWatermark ??\n // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n 131_072,\n }) as RpcSubscriptionsTransportFromClusterUrl<TClusterUrl>,\n transport =>\n getWebSocketTransportWithAutoping({\n intervalMs: intervalMs ?? 5_000,\n transport,\n }),\n transport =>\n getWebSocketTransportWithConnectionSharding({\n getShard,\n transport,\n }),\n );\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n intervalMs: number;\n transport: TTransport;\n}>;\n\nconst PING_PAYLOAD = {\n jsonrpc: '2.0',\n method: 'ping',\n} as const;\n\nexport function getWebSocketTransportWithAutoping<TTransport extends RpcSubscriptionsTransport>({\n intervalMs,\n transport,\n}: Config<TTransport>): TTransport {\n const pingableConnections = new Map<\n Awaited<ReturnType<RpcSubscriptionsTransport>>,\n Awaited<ReturnType<RpcSubscriptionsTransport>>\n >();\n return (async (...args) => {\n const connection = await transport(...args);\n let intervalId: ReturnType<typeof setInterval> | undefined;\n function sendPing() {\n connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);\n }\n function restartPingTimer() {\n clearInterval(intervalId);\n intervalId = setInterval(sendPing, intervalMs);\n }\n if (pingableConnections.has(connection) === false) {\n pingableConnections.set(connection, {\n [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),\n send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (\n ...args: Parameters<typeof connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>\n ) => {\n restartPingTimer();\n return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args);\n },\n });\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of connection) {\n restartPingTimer();\n }\n } catch {\n /* empty */\n } finally {\n pingableConnections.delete(connection);\n clearInterval(intervalId);\n if (handleOffline) {\n globalThis.window.removeEventListener('offline', handleOffline);\n }\n if (handleOnline) {\n globalThis.window.removeEventListener('online', handleOnline);\n }\n }\n })();\n if (!__BROWSER__ || globalThis.navigator.onLine) {\n restartPingTimer();\n }\n let handleOffline;\n let handleOnline;\n if (__BROWSER__) {\n handleOffline = () => {\n clearInterval(intervalId);\n };\n handleOnline = () => {\n sendPing();\n restartPingTimer();\n };\n globalThis.window.addEventListener('offline', handleOffline);\n globalThis.window.addEventListener('online', handleOnline);\n }\n }\n return pingableConnections.get(connection)!;\n }) as TTransport;\n}\n","import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype Config<TTransport extends RpcSubscriptionsTransport> = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows for.\n * Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string | symbol;\n transport: TTransport;\n}>;\n\nconst NULL_SHARD_CACHE_KEY = Symbol(\n __DEV__ ? 'Cache key to use when there is no connection sharding strategy' : undefined,\n);\n\nexport function getWebSocketTransportWithConnectionSharding<TTransport extends RpcSubscriptionsTransport>({\n getShard,\n transport,\n}: Config<TTransport>): TTransport {\n return getCachedAbortableIterableFactory({\n getAbortSignalFromInputArgs: ({ signal }) => signal,\n getCacheKeyFromInputArgs: ({ payload }) => (getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY),\n onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),\n onCreateIterable: (abortSignal, config) =>\n transport({\n ...config,\n signal: abortSignal,\n }),\n }) as TTransport;\n}\n"]}
|