@solana/rpc-subscriptions-channel-websocket 2.1.0 → 2.1.1-canary-20250310215239
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.cjs +2 -2
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.native.mjs +2 -2
- package/dist/index.native.mjs.map +1 -1
- package/dist/index.node.cjs +2 -2
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +2 -2
- package/dist/index.node.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.browser.cjs
CHANGED
|
@@ -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 =
|
|
96
|
+
bufferDrainWatcher = void 0;
|
|
97
97
|
resolve();
|
|
98
98
|
}
|
|
99
99
|
}, 16);
|
|
100
100
|
onCancel = () => {
|
|
101
|
-
bufferDrainWatcher =
|
|
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"]}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -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 =
|
|
94
|
+
bufferDrainWatcher = void 0;
|
|
95
95
|
resolve();
|
|
96
96
|
}
|
|
97
97
|
}, 16);
|
|
98
98
|
onCancel = () => {
|
|
99
|
-
bufferDrainWatcher =
|
|
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":";;;;AAAO,IACMA,IAAc,UAAW,CAAA,WAAA;;;ACDtC,IAAOC,IAAQ,UAAW,CAAA,SAAA;;;ACmB1B,IAAM,mBAAsB,GAAA,GAAA;AAErB,SAAS,sBAAuB,CAAA;AAAA,EACnC,uBAAA;AAAA,EACA,MAAA;AAAA,EACA;AACJ,CAAuE,EAAA;AACnE,EAAA,IAAI,OAAO,OAAS,EAAA;AAEhB,IAAO,OAAA,OAAA,CAAQ,MAAO,CAAA,MAAA,CAAO,MAAM,CAAA;AAAA;AAEvC,EAAI,IAAA,kBAAA;AACJ,EAAA,IAAI,YAAe,GAAA,KAAA;AACnB,EAAM,MAAA,gBAAA,uBAAuB,GAAgB,EAAA;AAC7C,EAAA,SAAS,gBAAmB,GAAA;AACxB,IAAA,gBAAA,CAAiB,QAAQ,CAAK,CAAA,KAAA;AAC1B,MAAE,CAAA,EAAA;AAAA,KACL,CAAA;AACD,IAAA,gBAAA,CAAiB,KAAM,EAAA;AAAA;AAE3B,EAAA,SAAS,WAAc,GAAA;AACnB,IAAiB,gBAAA,EAAA;AACjB,IAAA,IAAI,CAAC,YAAc,EAAA;AACf,MAAA,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA;AAE5B,IAAA,IAAI,UAAU,UAAe,KAAA,CAAA,CAAU,UAAU,SAAU,CAAA,UAAA,KAAe,EAAU,OAAS,EAAA;AACzF,MAAA,SAAA,CAAU,MAAM,mBAAmB,CAAA;AAAA;AACvC;AAEJ,EAAA,SAAS,YAAY,EAAgB,EAAA;AACjC,IAAiB,gBAAA,EAAA;AACjB,IAAA,kBAAA,EAAoB,QAAS,EAAA;AAC7B,IAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC/C,IAAU,SAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAClD,IAAU,SAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAClD,IAAU,SAAA,CAAA,mBAAA,CAAoB,WAAW,aAAa,CAAA;AACtD,IAAU,SAAA,CAAA,mBAAA,CAAoB,QAAQ,UAAU,CAAA;AAChD,IAAI,IAAA,CAAC,OAAO,OAAW,IAAA,EAAE,GAAG,QAAY,IAAA,EAAA,CAAG,SAAS,mBAAsB,CAAA,EAAA;AACtE,MAAY,WAAA,CAAA,aAAA;AAAA,QACR,IAAI,YAAY,OAAS,EAAA;AAAA,UACrB,MAAA,EAAQ,IAAI,WAAA,CAAY,0DAA4D,EAAA;AAAA,YAChF,KAAO,EAAA;AAAA,WACV;AAAA,SACJ;AAAA,OACL;AAAA;AACJ;AAEJ,EAAA,SAAS,YAAY,EAAW,EAAA;AAC5B,IAAA,IAAI,OAAO,OAAS,EAAA;AAChB,MAAA;AAAA;AAEJ,IAAA,IAAI,CAAC,YAAc,EAAA;AACf,MAAM,MAAA,oBAAA,GAAuB,IAAI,WAAA,CAAY,0DAA4D,EAAA;AAAA,QACrG,UAAY,EAAA;AAAA,OACf,CAAA;AACD,MAAA,UAAA,CAAW,oBAAoB,CAAA;AAC/B,MAAY,WAAA,CAAA,aAAA;AAAA,QACR,IAAI,YAAY,OAAS,EAAA;AAAA,UACrB,MAAQ,EAAA;AAAA,SACX;AAAA,OACL;AAAA;AACJ;AAEJ,EAAA,SAAS,cAAc,EAAkB,EAAA;AACrC,IAAA,IAAI,OAAO,OAAS,EAAA;AAChB,MAAA;AAAA;AAEJ,IAAY,WAAA,CAAA,aAAA,CAAc,IAAI,WAAY,CAAA,SAAA,EAAW,EAAE,MAAQ,EAAA,EAAA,CAAG,IAAK,EAAC,CAAC,CAAA;AAAA;AAE7E,EAAM,MAAA,WAAA,GAAc,IAAI,CAAY,EAAA;AACpC,EAAM,MAAA,aAAA,GAAgB,iCAAiC,WAAW,CAAA;AAClE,EAAA,SAAS,UAAa,GAAA;AAClB,IAAe,YAAA,GAAA,IAAA;AACf,IAAY,WAAA,CAAA;AAAA,MACR,GAAG,aAAA;AAAA,MACH,MAAM,KAAK,OAAS,EAAA;AAChB,QAAI,IAAA,SAAA,CAAU,UAAe,KAAA,CAAA,CAAU,IAAM,EAAA;AACzC,UAAM,MAAA,IAAI,YAAY,0DAA0D,CAAA;AAAA;AAEpF,QAAA,IAAI,CAAC,kBAAA,IAAsB,SAAU,CAAA,cAAA,GAAiB,uBAAyB,EAAA;AAC3E,UAAI,IAAA,QAAA;AACJ,UAAA,MAAM,OAAU,GAAA,IAAI,OAAc,CAAA,CAAC,SAAS,MAAW,KAAA;AACnD,YAAM,MAAA,UAAA,GAAa,YAAY,MAAM;AACjC,cAAA,IACI,UAAU,UAAe,KAAA,CAAA,CAAU,QACnC,EAAE,SAAA,CAAU,iBAAiB,uBAC/B,CAAA,EAAA;AACE,gBAAA,aAAA,CAAc,UAAU,CAAA;AACxB,gBAAqB,kBAAA,GAAA,SAAA;AACrB,gBAAQ,OAAA,EAAA;AAAA;AACZ,eACD,EAAE,CAAA;AACL,YAAA,QAAA,GAAW,MAAM;AACb,cAAqB,kBAAA,GAAA,SAAA;AACrB,cAAA,aAAA,CAAc,UAAU,CAAA;AACxB,cAAA,MAAA;AAAA,gBACI,IAAI,WAAA;AAAA,kBACA;AAAA;AACJ,eACJ;AAAA,aACJ;AAAA,WACH,CAAA;AACD,UAAqB,kBAAA,GAAA;AAAA,YACjB,QAAA;AAAA,YACA;AAAA,WACJ;AAAA;AAEJ,QAAA,IAAI,kBAAoB,EAAA;AACpB,UAAA,IAAI,YAAY,MAAO,CAAA,OAAO,CAAK,IAAA,EAAE,mBAAmB,QAAW,CAAA,EAAA;AAC/D,YAAA,MAAM,wBAAwB,OAAQ,CAAA,WAAA;AAItC,YAAU,OAAA,GAAA,IAAI,sBAAsB,OAAO,CAAA;AAAA;AAE/C,UAAA,MAAM,kBAAmB,CAAA,OAAA;AAAA;AAE7B,QAAA,SAAA,CAAU,KAAK,OAAO,CAAA;AAAA;AAC1B,KACH,CAAA;AAAA;AAEL,EAAM,MAAA,SAAA,GAAY,IAAI,CAAA,CAAU,GAAG,CAAA;AACnC,EAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC5C,EAAU,SAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC/C,EAAU,SAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC/C,EAAU,SAAA,CAAA,gBAAA,CAAiB,WAAW,aAAa,CAAA;AACnD,EAAU,SAAA,CAAA,gBAAA,CAAiB,QAAQ,UAAU,CAAA;AAC7C,EAAI,IAAA,UAAA;AACJ,EAAI,IAAA,WAAA;AACJ,EAAA,OAAO,IAAI,OAAA,CAA2D,CAAC,OAAA,EAAS,MAAW,KAAA;AACvF,IAAa,UAAA,GAAA,MAAA;AACb,IAAc,WAAA,GAAA,OAAA;AAAA,GACjB,CAAA;AACL","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"]}
|
package/dist/index.native.mjs
CHANGED
|
@@ -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 =
|
|
94
|
+
bufferDrainWatcher = void 0;
|
|
95
95
|
resolve();
|
|
96
96
|
}
|
|
97
97
|
}, 16);
|
|
98
98
|
onCancel = () => {
|
|
99
|
-
bufferDrainWatcher =
|
|
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"]}
|
package/dist/index.node.cjs
CHANGED
|
@@ -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 =
|
|
104
|
+
bufferDrainWatcher = void 0;
|
|
105
105
|
resolve();
|
|
106
106
|
}
|
|
107
107
|
}, 16);
|
|
108
108
|
onCancel = () => {
|
|
109
|
-
bufferDrainWatcher =
|
|
109
|
+
bufferDrainWatcher = void 0;
|
|
110
110
|
clearInterval(intervalId);
|
|
111
111
|
reject(
|
|
112
112
|
new errors.SolanaError(
|
package/dist/index.node.cjs.map
CHANGED
|
@@ -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":";;;;;;;;;;;;IASaA,CAAc,GAAA,cAAc,WAAW,WAAY,CAAA;AAC5D,EAAA,WAAA,CAAA,GAAeC,CAA4D,EAAA;AACvE,IAAA,KAAA,CAAM,GAAGA,CAAI,CAAA,EACbC,sBAAgB,CAAA,MAAA,CAAO,kBAAkB,IAAI,CAAA;AACjD;AACJ,CAAA;ACXA,IAAOC,CAAQ,GAAA,UAAA,CAAW,SACpB,GAAA,UAAA,CAAW,SACXC,GAAAA,mBAAAA;;;ACcN,IAAM,mBAAsB,GAAA,GAAA;AAErB,SAAS,sBAAuB,CAAA;AAAA,EACnC,uBAAA;AAAA,EACA,MAAA;AAAA,EACA;AACJ,CAAuE,EAAA;AACnE,EAAA,IAAI,OAAO,OAAS,EAAA;AAEhB,IAAO,OAAA,OAAA,CAAQ,MAAO,CAAA,MAAA,CAAO,MAAM,CAAA;AAAA;AAEvC,EAAI,IAAA,kBAAA;AACJ,EAAA,IAAI,YAAe,GAAA,KAAA;AACnB,EAAM,MAAA,gBAAA,uBAAuB,GAAgB,EAAA;AAC7C,EAAA,SAAS,gBAAmB,GAAA;AACxB,IAAA,gBAAA,CAAiB,QAAQ,CAAK,CAAA,KAAA;AAC1B,MAAE,CAAA,EAAA;AAAA,KACL,CAAA;AACD,IAAA,gBAAA,CAAiB,KAAM,EAAA;AAAA;AAE3B,EAAA,SAAS,WAAc,GAAA;AACnB,IAAiB,gBAAA,EAAA;AACjB,IAAA,IAAI,CAAC,YAAc,EAAA;AACf,MAAA,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA;AAE5B,IAAA,IAAI,UAAU,UAAe,KAAA,CAAA,CAAU,UAAU,SAAU,CAAA,UAAA,KAAe,EAAU,OAAS,EAAA;AACzF,MAAA,SAAA,CAAU,MAAM,mBAAmB,CAAA;AAAA;AACvC;AAEJ,EAAA,SAAS,YAAY,EAAgB,EAAA;AACjC,IAAiB,gBAAA,EAAA;AACjB,IAAA,kBAAA,EAAoB,QAAS,EAAA;AAC7B,IAAO,MAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC/C,IAAU,SAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAClD,IAAU,SAAA,CAAA,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAClD,IAAU,SAAA,CAAA,mBAAA,CAAoB,WAAW,aAAa,CAAA;AACtD,IAAU,SAAA,CAAA,mBAAA,CAAoB,QAAQ,UAAU,CAAA;AAChD,IAAI,IAAA,CAAC,OAAO,OAAW,IAAA,EAAE,GAAG,QAAY,IAAA,EAAA,CAAG,SAAS,mBAAsB,CAAA,EAAA;AACtE,MAAY,WAAA,CAAA,aAAA;AAAA,QACR,IAAI,YAAY,OAAS,EAAA;AAAA,UACrB,MAAA,EAAQ,IAAIC,kBAAA,CAAYC,iEAA4D,EAAA;AAAA,YAChF,KAAO,EAAA;AAAA,WACV;AAAA,SACJ;AAAA,OACL;AAAA;AACJ;AAEJ,EAAA,SAAS,YAAY,EAAW,EAAA;AAC5B,IAAA,IAAI,OAAO,OAAS,EAAA;AAChB,MAAA;AAAA;AAEJ,IAAA,IAAI,CAAC,YAAc,EAAA;AACf,MAAM,MAAA,oBAAA,GAAuB,IAAID,kBAAA,CAAYE,iEAA4D,EAAA;AAAA,QACrG,UAAY,EAAA;AAAA,OACf,CAAA;AACD,MAAA,UAAA,CAAW,oBAAoB,CAAA;AAC/B,MAAY,WAAA,CAAA,aAAA;AAAA,QACR,IAAI,YAAY,OAAS,EAAA;AAAA,UACrB,MAAQ,EAAA;AAAA,SACX;AAAA,OACL;AAAA;AACJ;AAEJ,EAAA,SAAS,cAAc,EAAkB,EAAA;AACrC,IAAA,IAAI,OAAO,OAAS,EAAA;AAChB,MAAA;AAAA;AAEJ,IAAY,WAAA,CAAA,aAAA,CAAc,IAAI,WAAY,CAAA,SAAA,EAAW,EAAE,MAAQ,EAAA,EAAA,CAAG,IAAK,EAAC,CAAC,CAAA;AAAA;AAE7E,EAAM,MAAA,WAAA,GAAc,IAAI,CAAY,EAAA;AACpC,EAAM,MAAA,aAAA,GAAgBC,8CAAiC,WAAW,CAAA;AAClE,EAAA,SAAS,UAAa,GAAA;AAClB,IAAe,YAAA,GAAA,IAAA;AACf,IAAY,WAAA,CAAA;AAAA,MACR,GAAG,aAAA;AAAA,MACH,MAAM,KAAK,OAAS,EAAA;AAChB,QAAI,IAAA,SAAA,CAAU,UAAe,KAAA,CAAA,CAAU,IAAM,EAAA;AACzC,UAAM,MAAA,IAAIH,mBAAYC,iEAA0D,CAAA;AAAA;AAEpF,QAAA,IAAI,CAAC,kBAAA,IAAsB,SAAU,CAAA,cAAA,GAAiB,uBAAyB,EAAA;AAC3E,UAAI,IAAA,QAAA;AACJ,UAAA,MAAM,OAAU,GAAA,IAAI,OAAc,CAAA,CAAC,SAAS,MAAW,KAAA;AACnD,YAAM,MAAA,UAAA,GAAa,YAAY,MAAM;AACjC,cAAA,IACI,UAAU,UAAe,KAAA,CAAA,CAAU,QACnC,EAAE,SAAA,CAAU,iBAAiB,uBAC/B,CAAA,EAAA;AACE,gBAAA,aAAA,CAAc,UAAU,CAAA;AACxB,gBAAqB,kBAAA,GAAA,MAAA;AACrB,gBAAQ,OAAA,EAAA;AAAA;AACZ,eACD,EAAE,CAAA;AACL,YAAA,QAAA,GAAW,MAAM;AACb,cAAqB,kBAAA,GAAA,MAAA;AACrB,cAAA,aAAA,CAAc,UAAU,CAAA;AACxB,cAAA,MAAA;AAAA,gBACI,IAAID,kBAAA;AAAA,kBACAI;AAAA;AACJ,eACJ;AAAA,aACJ;AAAA,WACH,CAAA;AACD,UAAqB,kBAAA,GAAA;AAAA,YACjB,QAAA;AAAA,YACA;AAAA,WACJ;AAAA;AAEJ,QAAA,IAAI,kBAAoB,EAAA;AACpB,UAAA,IAAI,YAAY,MAAO,CAAA,OAAO,CAAK,IAAA,EAAE,mBAAmB,QAAW,CAAA,EAAA;AAC/D,YAAA,MAAM,wBAAwB,OAAQ,CAAA,WAAA;AAItC,YAAU,OAAA,GAAA,IAAI,sBAAsB,OAAO,CAAA;AAAA;AAE/C,UAAA,MAAM,kBAAmB,CAAA,OAAA;AAAA;AAE7B,QAAA,SAAA,CAAU,KAAK,OAAO,CAAA;AAAA;AAC1B,KACH,CAAA;AAAA;AAEL,EAAM,MAAA,SAAA,GAAY,IAAI,CAAA,CAAU,GAAG,CAAA;AACnC,EAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC5C,EAAU,SAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC/C,EAAU,SAAA,CAAA,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC/C,EAAU,SAAA,CAAA,gBAAA,CAAiB,WAAW,aAAa,CAAA;AACnD,EAAU,SAAA,CAAA,gBAAA,CAAiB,QAAQ,UAAU,CAAA;AAC7C,EAAI,IAAA,UAAA;AACJ,EAAI,IAAA,WAAA;AACJ,EAAA,OAAO,IAAI,OAAA,CAA2D,CAAC,OAAA,EAAS,MAAW,KAAA;AACvF,IAAa,UAAA,GAAA,MAAA;AACb,IAAc,WAAA,GAAA,OAAA;AAAA,GACjB,CAAA;AACL","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"]}
|
package/dist/index.node.mjs
CHANGED
|
@@ -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 =
|
|
98
|
+
bufferDrainWatcher = void 0;
|
|
99
99
|
resolve();
|
|
100
100
|
}
|
|
101
101
|
}, 16);
|
|
102
102
|
onCancel = () => {
|
|
103
|
-
bufferDrainWatcher =
|
|
103
|
+
bufferDrainWatcher = void 0;
|
|
104
104
|
clearInterval(intervalId);
|
|
105
105
|
reject(
|
|
106
106
|
new SolanaError(
|
package/dist/index.node.mjs.map
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "2.1.1-canary-20250310215239",
|
|
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.
|
|
58
|
-
"@solana/
|
|
59
|
-
"@solana/
|
|
60
|
-
"@solana/
|
|
57
|
+
"@solana/errors": "2.1.1-canary-20250310215239",
|
|
58
|
+
"@solana/functional": "2.1.1-canary-20250310215239",
|
|
59
|
+
"@solana/rpc-subscriptions-spec": "2.1.1-canary-20250310215239",
|
|
60
|
+
"@solana/subscribable": "2.1.1-canary-20250310215239"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"typescript": ">=5",
|