@solana/rpc-subscriptions-channel-websocket 2.1.0 → 2.1.1-canary-20250310090649

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.
@@ -93,12 +93,12 @@ function createWebSocketChannel({
93
93
  const intervalId = setInterval(() => {
94
94
  if (webSocket.readyState !== e.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) {
95
95
  clearInterval(intervalId);
96
- bufferDrainWatcher = undefined;
96
+ bufferDrainWatcher = void 0;
97
97
  resolve();
98
98
  }
99
99
  }, 16);
100
100
  onCancel = () => {
101
- bufferDrainWatcher = undefined;
101
+ bufferDrainWatcher = void 0;
102
102
  clearInterval(intervalId);
103
103
  reject(
104
104
  new errors.SolanaError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default","SolanaError","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT","getDataPublisherFromEventEmitter","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default","SolanaError","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT","getDataPublisherFromEventEmitter","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
@@ -91,12 +91,12 @@ function createWebSocketChannel({
91
91
  const intervalId = setInterval(() => {
92
92
  if (webSocket.readyState !== e.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) {
93
93
  clearInterval(intervalId);
94
- bufferDrainWatcher = undefined;
94
+ bufferDrainWatcher = void 0;
95
95
  resolve();
96
96
  }
97
97
  }, 16);
98
98
  onCancel = () => {
99
- bufferDrainWatcher = undefined;
99
+ bufferDrainWatcher = void 0;
100
100
  clearInterval(intervalId);
101
101
  reject(
102
102
  new SolanaError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
@@ -91,12 +91,12 @@ function createWebSocketChannel({
91
91
  const intervalId = setInterval(() => {
92
92
  if (webSocket.readyState !== e.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) {
93
93
  clearInterval(intervalId);
94
- bufferDrainWatcher = undefined;
94
+ bufferDrainWatcher = void 0;
95
95
  resolve();
96
96
  }
97
97
  }, 16);
98
98
  onCancel = () => {
99
- bufferDrainWatcher = undefined;
99
+ bufferDrainWatcher = void 0;
100
100
  clearInterval(intervalId);
101
101
  reject(
102
102
  new SolanaError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../../ws-impl/src/index.browser.ts","../src/websocket-channel.ts"],"names":["EventTarget","index_browser_default"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","export default globalThis.WebSocket;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
@@ -101,12 +101,12 @@ function createWebSocketChannel({
101
101
  const intervalId = setInterval(() => {
102
102
  if (webSocket.readyState !== l.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) {
103
103
  clearInterval(intervalId);
104
- bufferDrainWatcher = undefined;
104
+ bufferDrainWatcher = void 0;
105
105
  resolve();
106
106
  }
107
107
  }, 16);
108
108
  onCancel = () => {
109
- bufferDrainWatcher = undefined;
109
+ bufferDrainWatcher = void 0;
110
110
  clearInterval(intervalId);
111
111
  reject(
112
112
  new errors.SolanaError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../../ws-impl/src/index.node.ts","../src/websocket-channel.ts"],"names":["EventTarget","args","setMaxListeners","index_node_default","WebSocketImpl","SolanaError","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT","getDataPublisherFromEventEmitter","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","// When building the browser bundle, this import gets replaced by `globalThis.WebSocket`.\nimport WebSocketImpl from 'ws';\n\nexport default globalThis.WebSocket\n ? globalThis.WebSocket // Use native `WebSocket` in runtimes that support it (eg. Deno)\n : WebSocketImpl;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../../ws-impl/src/index.node.ts","../src/websocket-channel.ts"],"names":["EventTarget","args","setMaxListeners","index_node_default","WebSocketImpl","SolanaError","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT","getDataPublisherFromEventEmitter","SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","// When building the browser bundle, this import gets replaced by `globalThis.WebSocket`.\nimport WebSocketImpl from 'ws';\n\nexport default globalThis.WebSocket\n ? globalThis.WebSocket // Use native `WebSocket` in runtimes that support it (eg. Deno)\n : WebSocketImpl;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
@@ -95,12 +95,12 @@ function createWebSocketChannel({
95
95
  const intervalId = setInterval(() => {
96
96
  if (webSocket.readyState !== l.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) {
97
97
  clearInterval(intervalId);
98
- bufferDrainWatcher = undefined;
98
+ bufferDrainWatcher = void 0;
99
99
  resolve();
100
100
  }
101
101
  }, 16);
102
102
  onCancel = () => {
103
- bufferDrainWatcher = undefined;
103
+ bufferDrainWatcher = void 0;
104
104
  clearInterval(intervalId);
105
105
  reject(
106
106
  new SolanaError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../../ws-impl/src/index.node.ts","../src/websocket-channel.ts"],"names":["EventTarget","args","setMaxListeners","index_node_default","WebSocketImpl"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","// When building the browser bundle, this import gets replaced by `globalThis.WebSocket`.\nimport WebSocketImpl from 'ws';\n\nexport default globalThis.WebSocket\n ? globalThis.WebSocket // Use native `WebSocket` in runtimes that support it (eg. Deno)\n : WebSocketImpl;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../../ws-impl/src/index.node.ts","../src/websocket-channel.ts"],"names":["EventTarget","args","setMaxListeners","index_node_default","WebSocketImpl"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","// When building the browser bundle, this import gets replaced by `globalThis.WebSocket`.\nimport WebSocketImpl from 'ws';\n\nexport default globalThis.WebSocket\n ? globalThis.WebSocket // Use native `WebSocket` in runtimes that support it (eg. Deno)\n : WebSocketImpl;\n","import {\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n sendBufferHighWatermark: number;\n signal: AbortSignal;\n url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\nexport function createWebSocketChannel({\n sendBufferHighWatermark,\n signal,\n url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n if (signal.aborted) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(signal.reason);\n }\n let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n let hasConnected = false;\n const listenerRemovers = new Set<() => void>();\n function cleanupListeners() {\n listenerRemovers.forEach(r => {\n r();\n });\n listenerRemovers.clear();\n }\n function handleAbort() {\n cleanupListeners();\n if (!hasConnected) {\n rejectOpen(signal.reason);\n }\n if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n webSocket.close(NORMAL_CLOSURE_CODE);\n }\n }\n function handleClose(ev: CloseEvent) {\n cleanupListeners();\n bufferDrainWatcher?.onCancel();\n signal.removeEventListener('abort', handleAbort);\n webSocket.removeEventListener('close', handleClose);\n webSocket.removeEventListener('error', handleError);\n webSocket.removeEventListener('message', handleMessage);\n webSocket.removeEventListener('open', handleOpen);\n if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n cause: ev,\n }),\n }),\n );\n }\n }\n function handleError(ev: Event) {\n if (signal.aborted) {\n return;\n }\n if (!hasConnected) {\n const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n errorEvent: ev,\n });\n rejectOpen(failedToConnectError);\n eventTarget.dispatchEvent(\n new CustomEvent('error', {\n detail: failedToConnectError,\n }),\n );\n }\n }\n function handleMessage(ev: MessageEvent) {\n if (signal.aborted) {\n return;\n }\n eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n }\n const eventTarget = new EventTarget();\n const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n function handleOpen() {\n hasConnected = true;\n resolveOpen({\n ...dataPublisher,\n async send(message) {\n if (webSocket.readyState !== WebSocket.OPEN) {\n throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n }\n if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n let onCancel!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const intervalId = setInterval(() => {\n if (\n webSocket.readyState !== WebSocket.OPEN ||\n !(webSocket.bufferedAmount > sendBufferHighWatermark)\n ) {\n clearInterval(intervalId);\n bufferDrainWatcher = undefined;\n resolve();\n }\n }, 16);\n onCancel = () => {\n bufferDrainWatcher = undefined;\n clearInterval(intervalId);\n reject(\n new SolanaError(\n SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n ),\n );\n };\n });\n bufferDrainWatcher = {\n onCancel,\n promise,\n };\n }\n if (bufferDrainWatcher) {\n if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n const TypedArrayConstructor = message.constructor as {\n new (...args: [typeof message]): typeof message;\n };\n // Clone the message to prevent mutation while queued.\n message = new TypedArrayConstructor(message);\n }\n await bufferDrainWatcher.promise;\n }\n webSocket.send(message);\n },\n });\n }\n const webSocket = new WebSocket(url);\n signal.addEventListener('abort', handleAbort);\n webSocket.addEventListener('close', handleClose);\n webSocket.addEventListener('error', handleError);\n webSocket.addEventListener('message', handleMessage);\n webSocket.addEventListener('open', handleOpen);\n let rejectOpen!: (e: SolanaError) => void;\n let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n rejectOpen = reject;\n resolveOpen = resolve;\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/rpc-subscriptions-channel-websocket",
3
- "version": "2.1.0",
3
+ "version": "2.1.1-canary-20250310090649",
4
4
  "description": "An RPC Subscriptions transport that uses WebSockets",
5
5
  "exports": {
6
6
  "edge-light": {
@@ -54,10 +54,10 @@
54
54
  "maintained node versions"
55
55
  ],
56
56
  "dependencies": {
57
- "@solana/errors": "2.1.0",
58
- "@solana/rpc-subscriptions-spec": "2.1.0",
59
- "@solana/subscribable": "2.1.0",
60
- "@solana/functional": "2.1.0"
57
+ "@solana/errors": "2.1.1-canary-20250310090649",
58
+ "@solana/functional": "2.1.1-canary-20250310090649",
59
+ "@solana/subscribable": "2.1.1-canary-20250310090649",
60
+ "@solana/rpc-subscriptions-spec": "2.1.1-canary-20250310090649"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "typescript": ">=5",