@solana/rpc-subscriptions 2.0.0-experimental.12ae1c6

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.
Files changed (33) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +17 -0
  3. package/dist/index.browser.cjs +388 -0
  4. package/dist/index.browser.cjs.map +1 -0
  5. package/dist/index.browser.js +370 -0
  6. package/dist/index.browser.js.map +1 -0
  7. package/dist/index.native.js +359 -0
  8. package/dist/index.native.js.map +1 -0
  9. package/dist/index.node.cjs +377 -0
  10. package/dist/index.node.cjs.map +1 -0
  11. package/dist/index.node.js +359 -0
  12. package/dist/index.node.js.map +1 -0
  13. package/dist/types/cached-abortable-iterable.d.ts +11 -0
  14. package/dist/types/cached-abortable-iterable.d.ts.map +1 -0
  15. package/dist/types/index.d.ts +6 -0
  16. package/dist/types/index.d.ts.map +1 -0
  17. package/dist/types/rpc-default-config.d.ts +3 -0
  18. package/dist/types/rpc-default-config.d.ts.map +1 -0
  19. package/dist/types/rpc-integer-overflow-error.d.ts +4 -0
  20. package/dist/types/rpc-integer-overflow-error.d.ts.map +1 -0
  21. package/dist/types/rpc-subscriptions-autopinger.d.ts +8 -0
  22. package/dist/types/rpc-subscriptions-autopinger.d.ts.map +1 -0
  23. package/dist/types/rpc-subscriptions-clusters.d.ts +24 -0
  24. package/dist/types/rpc-subscriptions-clusters.d.ts.map +1 -0
  25. package/dist/types/rpc-subscriptions-coalescer.d.ts +10 -0
  26. package/dist/types/rpc-subscriptions-coalescer.d.ts.map +1 -0
  27. package/dist/types/rpc-subscriptions-connection-sharding.d.ts +13 -0
  28. package/dist/types/rpc-subscriptions-connection-sharding.d.ts.map +1 -0
  29. package/dist/types/rpc-subscriptions-transport.d.ts +17 -0
  30. package/dist/types/rpc-subscriptions-transport.d.ts.map +1 -0
  31. package/dist/types/rpc-subscriptions.d.ts +10 -0
  32. package/dist/types/rpc-subscriptions.d.ts.map +1 -0
  33. package/package.json +82 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2023 Solana Labs, Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ [![npm][npm-image]][npm-url]
2
+ [![npm-downloads][npm-downloads-image]][npm-url]
3
+ [![semantic-release][semantic-release-image]][semantic-release-url]
4
+ <br />
5
+ [![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
6
+
7
+ [code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
8
+ [code-style-prettier-url]: https://github.com/prettier/prettier
9
+ [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-subscriptions/experimental.svg?style=flat
10
+ [npm-image]: https://img.shields.io/npm/v/@solana/rpc-subscriptions/experimental.svg?style=flat
11
+ [npm-url]: https://www.npmjs.com/package/@solana/rpc-subscriptions/v/experimental
12
+ [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
13
+ [semantic-release-url]: https://github.com/semantic-release/semantic-release
14
+
15
+ # @solana/rpc-subscriptions
16
+
17
+ TODO
@@ -0,0 +1,388 @@
1
+ 'use strict';
2
+
3
+ var rpcSubscriptionsApi = require('@solana/rpc-subscriptions-api');
4
+ var rpcSubscriptionsSpec = require('@solana/rpc-subscriptions-spec');
5
+ var functional = require('@solana/functional');
6
+ var fastStableStringify = require('fast-stable-stringify');
7
+ var errors = require('@solana/errors');
8
+ var rpcSubscriptionsTransportWebsocket = require('@solana/rpc-subscriptions-transport-websocket');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var fastStableStringify__default = /*#__PURE__*/_interopDefault(fastStableStringify);
13
+
14
+ // ../build-scripts/env-shim.ts
15
+ var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
16
+ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
17
+ let argumentLabel = "";
18
+ if (typeof keyPath[0] === "number") {
19
+ const argPosition = keyPath[0] + 1;
20
+ const lastDigit = argPosition % 10;
21
+ const lastTwoDigits = argPosition % 100;
22
+ if (lastDigit == 1 && lastTwoDigits != 11) {
23
+ argumentLabel = argPosition + "st";
24
+ } else if (lastDigit == 2 && lastTwoDigits != 12) {
25
+ argumentLabel = argPosition + "nd";
26
+ } else if (lastDigit == 3 && lastTwoDigits != 13) {
27
+ argumentLabel = argPosition + "rd";
28
+ } else {
29
+ argumentLabel = argPosition + "th";
30
+ }
31
+ } else {
32
+ argumentLabel = `\`${keyPath[0].toString()}\``;
33
+ }
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.SOLANA_ERROR__RPC_INTEGER_OVERFLOW, {
36
+ argumentLabel,
37
+ keyPath,
38
+ methodName,
39
+ optionalPathLabel: path ? ` at path \`${path}\`` : "",
40
+ value,
41
+ ...path !== void 0 ? { path } : void 0
42
+ });
43
+ if ("captureStackTrace" in Error && typeof Error.captureStackTrace === "function") {
44
+ Error.captureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
45
+ }
46
+ return error;
47
+ }
48
+
49
+ // src/rpc-default-config.ts
50
+ var DEFAULT_RPC_CONFIG = {
51
+ defaultCommitment: "confirmed",
52
+ onIntegerOverflow(methodName, keyPath, value) {
53
+ throw createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
54
+ }
55
+ };
56
+
57
+ // src/cached-abortable-iterable.ts
58
+ function registerIterableCleanup(iterable, cleanupFn) {
59
+ (async () => {
60
+ try {
61
+ for await (const _ of iterable)
62
+ ;
63
+ } catch {
64
+ } finally {
65
+ cleanupFn();
66
+ }
67
+ })();
68
+ }
69
+ function getCachedAbortableIterableFactory({
70
+ getAbortSignalFromInputArgs,
71
+ getCacheEntryMissingError,
72
+ getCacheKeyFromInputArgs,
73
+ onCacheHit,
74
+ onCreateIterable
75
+ }) {
76
+ const cache = /* @__PURE__ */ new Map();
77
+ function getCacheEntryOrThrow(cacheKey) {
78
+ const currentCacheEntry = cache.get(cacheKey);
79
+ if (!currentCacheEntry) {
80
+ throw getCacheEntryMissingError(cacheKey);
81
+ }
82
+ return currentCacheEntry;
83
+ }
84
+ return async (...args) => {
85
+ const cacheKey = getCacheKeyFromInputArgs(...args);
86
+ const signal = getAbortSignalFromInputArgs(...args);
87
+ if (cacheKey === void 0) {
88
+ return await onCreateIterable(signal, ...args);
89
+ }
90
+ const cleanup = () => {
91
+ cache.delete(cacheKey);
92
+ signal.removeEventListener("abort", handleAbort);
93
+ };
94
+ const handleAbort = () => {
95
+ const cacheEntry = getCacheEntryOrThrow(cacheKey);
96
+ if (cacheEntry.purgeScheduled !== true) {
97
+ cacheEntry.purgeScheduled = true;
98
+ globalThis.queueMicrotask(() => {
99
+ cacheEntry.purgeScheduled = false;
100
+ if (cacheEntry.referenceCount === 0) {
101
+ cacheEntry.abortController.abort();
102
+ cleanup();
103
+ }
104
+ });
105
+ }
106
+ cacheEntry.referenceCount--;
107
+ };
108
+ signal.addEventListener("abort", handleAbort);
109
+ try {
110
+ const cacheEntry = cache.get(cacheKey);
111
+ if (!cacheEntry) {
112
+ const singletonAbortController = new AbortController();
113
+ const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);
114
+ const newCacheEntry = {
115
+ abortController: singletonAbortController,
116
+ iterable: newIterablePromise,
117
+ purgeScheduled: false,
118
+ referenceCount: 1
119
+ };
120
+ cache.set(cacheKey, newCacheEntry);
121
+ const newIterable = await newIterablePromise;
122
+ registerIterableCleanup(newIterable, cleanup);
123
+ newCacheEntry.iterable = newIterable;
124
+ return newIterable;
125
+ } else {
126
+ cacheEntry.referenceCount++;
127
+ const iterableOrIterablePromise = cacheEntry.iterable;
128
+ const cachedIterable = "then" in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;
129
+ await onCacheHit(cachedIterable, ...args);
130
+ return cachedIterable;
131
+ }
132
+ } catch (e) {
133
+ cleanup();
134
+ throw e;
135
+ }
136
+ };
137
+ }
138
+
139
+ // src/rpc-subscriptions-coalescer.ts
140
+ var EXPLICIT_ABORT_TOKEN = Symbol(
141
+ __DEV__ ? "This symbol is thrown from a subscription's iterator when the subscription is explicitly aborted by the user" : void 0
142
+ );
143
+ function registerIterableCleanup2(iterable, cleanupFn) {
144
+ (async () => {
145
+ try {
146
+ for await (const _ of iterable)
147
+ ;
148
+ } catch {
149
+ } finally {
150
+ cleanupFn();
151
+ }
152
+ })();
153
+ }
154
+ function getRpcSubscriptionsWithSubscriptionCoalescing({
155
+ getDeduplicationKey,
156
+ rpcSubscriptions
157
+ }) {
158
+ const cache = /* @__PURE__ */ new Map();
159
+ return new Proxy(rpcSubscriptions, {
160
+ defineProperty() {
161
+ return false;
162
+ },
163
+ deleteProperty() {
164
+ return false;
165
+ },
166
+ get(target, p, receiver) {
167
+ const subscriptionMethod = Reflect.get(target, p, receiver);
168
+ if (typeof subscriptionMethod !== "function") {
169
+ return subscriptionMethod;
170
+ }
171
+ return function(...rawParams) {
172
+ const deduplicationKey = getDeduplicationKey(p, rawParams);
173
+ if (deduplicationKey === void 0) {
174
+ return subscriptionMethod(...rawParams);
175
+ }
176
+ if (cache.has(deduplicationKey)) {
177
+ return cache.get(deduplicationKey);
178
+ }
179
+ const iterableFactory = getCachedAbortableIterableFactory({
180
+ 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
+ getCacheKeyFromInputArgs: () => deduplicationKey,
187
+ async onCacheHit(_iterable, _config) {
188
+ },
189
+ async onCreateIterable(abortSignal, config) {
190
+ const pendingSubscription2 = subscriptionMethod(
191
+ ...rawParams
192
+ );
193
+ const iterable = await pendingSubscription2.subscribe({
194
+ ...config,
195
+ abortSignal
196
+ });
197
+ registerIterableCleanup2(iterable, () => {
198
+ cache.delete(deduplicationKey);
199
+ });
200
+ return iterable;
201
+ }
202
+ });
203
+ const pendingSubscription = {
204
+ async subscribe(...args) {
205
+ const iterable = await iterableFactory(...args);
206
+ const { abortSignal } = args[0];
207
+ let abortPromise;
208
+ return {
209
+ ...iterable,
210
+ async *[Symbol.asyncIterator]() {
211
+ abortPromise ||= abortSignal.aborted ? Promise.reject(EXPLICIT_ABORT_TOKEN) : new Promise((_, reject) => {
212
+ abortSignal.addEventListener("abort", () => {
213
+ reject(EXPLICIT_ABORT_TOKEN);
214
+ });
215
+ });
216
+ try {
217
+ const iterator = iterable[Symbol.asyncIterator]();
218
+ while (true) {
219
+ const iteratorResult = await Promise.race([iterator.next(), abortPromise]);
220
+ if (iteratorResult.done) {
221
+ return;
222
+ } else {
223
+ yield iteratorResult.value;
224
+ }
225
+ }
226
+ } catch (e) {
227
+ if (e === EXPLICIT_ABORT_TOKEN) {
228
+ return;
229
+ }
230
+ cache.delete(deduplicationKey);
231
+ throw e;
232
+ }
233
+ }
234
+ };
235
+ }
236
+ };
237
+ cache.set(deduplicationKey, pendingSubscription);
238
+ return pendingSubscription;
239
+ };
240
+ }
241
+ });
242
+ }
243
+
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
+ // src/rpc-subscriptions-autopinger.ts
265
+ var PING_PAYLOAD = {
266
+ jsonrpc: "2.0",
267
+ method: "ping"
268
+ };
269
+ function getWebSocketTransportWithAutoping({
270
+ intervalMs,
271
+ transport
272
+ }) {
273
+ const pingableConnections = /* @__PURE__ */ new Map();
274
+ return async (...args) => {
275
+ const connection = await transport(...args);
276
+ let intervalId;
277
+ function sendPing() {
278
+ connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);
279
+ }
280
+ function restartPingTimer() {
281
+ clearInterval(intervalId);
282
+ intervalId = setInterval(sendPing, intervalMs);
283
+ }
284
+ if (pingableConnections.has(connection) === false) {
285
+ pingableConnections.set(connection, {
286
+ [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),
287
+ send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (...args2) => {
288
+ restartPingTimer();
289
+ return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args2);
290
+ }
291
+ });
292
+ (async () => {
293
+ try {
294
+ for await (const _ of connection) {
295
+ restartPingTimer();
296
+ }
297
+ } catch {
298
+ } finally {
299
+ pingableConnections.delete(connection);
300
+ clearInterval(intervalId);
301
+ if (handleOffline) {
302
+ globalThis.window.removeEventListener("offline", handleOffline);
303
+ }
304
+ if (handleOnline) {
305
+ globalThis.window.removeEventListener("online", handleOnline);
306
+ }
307
+ }
308
+ })();
309
+ if (globalThis.navigator.onLine) {
310
+ restartPingTimer();
311
+ }
312
+ let handleOffline;
313
+ let handleOnline;
314
+ {
315
+ handleOffline = () => {
316
+ clearInterval(intervalId);
317
+ };
318
+ handleOnline = () => {
319
+ sendPing();
320
+ restartPingTimer();
321
+ };
322
+ globalThis.window.addEventListener("offline", handleOffline);
323
+ globalThis.window.addEventListener("online", handleOnline);
324
+ }
325
+ }
326
+ return pingableConnections.get(connection);
327
+ };
328
+ }
329
+
330
+ // src/rpc-subscriptions-connection-sharding.ts
331
+ var NULL_SHARD_CACHE_KEY = Symbol(
332
+ __DEV__ ? "Cache key to use when there is no connection sharding strategy" : void 0
333
+ );
334
+ function getWebSocketTransportWithConnectionSharding({
335
+ getShard,
336
+ transport
337
+ }) {
338
+ return getCachedAbortableIterableFactory({
339
+ getAbortSignalFromInputArgs: ({ signal }) => signal,
340
+ getCacheEntryMissingError(shardKey) {
341
+ return new Error(`Found no cache entry for connection with shard key \`${shardKey?.toString()}\``);
342
+ },
343
+ getCacheKeyFromInputArgs: ({ payload }) => getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY,
344
+ onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),
345
+ onCreateIterable: (abortSignal, config) => transport({
346
+ ...config,
347
+ signal: abortSignal
348
+ })
349
+ });
350
+ }
351
+
352
+ // src/rpc-subscriptions-transport.ts
353
+ function createDefaultRpcSubscriptionsTransport(config) {
354
+ const { getShard, intervalMs, ...rest } = config;
355
+ return functional.pipe(
356
+ rpcSubscriptionsTransportWebsocket.createWebSocketTransport({
357
+ ...rest,
358
+ sendBufferHighWatermark: config.sendBufferHighWatermark ?? // Let 128KB of data into the WebSocket buffer before buffering it in the app.
359
+ 131072
360
+ }),
361
+ (transport) => getWebSocketTransportWithAutoping({
362
+ intervalMs: intervalMs ?? 5e3,
363
+ transport
364
+ }),
365
+ (transport) => getWebSocketTransportWithConnectionSharding({
366
+ getShard,
367
+ transport
368
+ })
369
+ );
370
+ }
371
+
372
+ exports.createDefaultRpcSubscriptionsTransport = createDefaultRpcSubscriptionsTransport;
373
+ exports.createSolanaRpcSubscriptions = createSolanaRpcSubscriptions;
374
+ exports.createSolanaRpcSubscriptions_UNSTABLE = createSolanaRpcSubscriptions_UNSTABLE;
375
+ Object.keys(rpcSubscriptionsApi).forEach(function (k) {
376
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
377
+ enumerable: true,
378
+ get: function () { return rpcSubscriptionsApi[k]; }
379
+ });
380
+ });
381
+ Object.keys(rpcSubscriptionsSpec).forEach(function (k) {
382
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
383
+ enumerable: true,
384
+ get: function () { return rpcSubscriptionsSpec[k]; }
385
+ });
386
+ });
387
+ //# sourceMappingURL=out.js.map
388
+ //# sourceMappingURL=index.browser.cjs.map
@@ -0,0 +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"]}