diff --git a/UNIQUE_SETUPS.md b/UNIQUE_SETUPS.md index f383f925c0..017d1ba951 100644 --- a/UNIQUE_SETUPS.md +++ b/UNIQUE_SETUPS.md @@ -45,7 +45,6 @@ To use `xrpl.js` with React, you need to install shims for core NodeJS modules. assert: require.resolve("assert"), crypto: require.resolve("crypto-browserify"), stream: require.resolve("stream-browserify"), - ws: require.resolve("xrpl/dist/npm/client/WSWrapper"), }); config.resolve.fallback = fallback; config.plugins = (config.plugins || []).concat([ @@ -156,7 +155,6 @@ resolve: { events: 'events', crypto: 'crypto-browserify', stream: 'stream-browserify', - ws: 'xrpl/dist/npm/client/WSWrapper', }, }}) ``` diff --git a/package-lock.json b/package-lock.json index 337f40f88a..c3b902950d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8951,6 +8951,14 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -16282,6 +16290,7 @@ "bip32": "^2.0.6", "bip39": "^3.0.4", "cross-fetch": "^4.0.0", + "isomorphic-ws": "^5.0.0", "ripple-address-codec": "^4.3.0", "ripple-binary-codec": "^1.7.1", "ripple-keypairs": "^1.3.0", @@ -23350,6 +23359,12 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, + "isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "requires": {} + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -28997,6 +29012,7 @@ "cross-fetch": "^4.0.0", "https-browserify": "^1.0.0", "https-proxy-agent": "^7.0.1", + "isomorphic-ws": "^5.0.0", "karma": "^6.4.1", "karma-chrome-launcher": "^3.1.1", "karma-jasmine": "^5.1.0", diff --git a/packages/xrpl/package.json b/packages/xrpl/package.json index 60da5ee0e2..0f7b47d729 100644 --- a/packages/xrpl/package.json +++ b/packages/xrpl/package.json @@ -17,14 +17,12 @@ "directories": { "test": "test" }, - "browser": { - "ws": "./dist/npm/client/WSWrapper.js" - }, "dependencies": { "bignumber.js": "^9.0.0", "bip32": "^2.0.6", "bip39": "^3.0.4", "cross-fetch": "^4.0.0", + "isomorphic-ws": "^5.0.0", "ripple-address-codec": "^4.3.0", "ripple-binary-codec": "^1.7.1", "ripple-keypairs": "^1.3.0", diff --git a/packages/xrpl/src/client/WSWrapper.ts b/packages/xrpl/src/client/WSWrapper.ts deleted file mode 100644 index 6fca23022e..0000000000 --- a/packages/xrpl/src/client/WSWrapper.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* eslint-disable max-classes-per-file -- Needs to be a wrapper for ws */ -import { EventEmitter } from 'events' - -// Define the global WebSocket class found on the native browser -declare class WebSocket { - public onclose?: (closeEvent: CloseEvent) => void - public onopen?: (openEvent: Event) => void - public onerror?: (error: Error) => void - public onmessage?: (message: MessageEvent) => void - public readyState: number - public constructor(url: string) - public close(code?: number, reason?: Buffer): void - public send(message: string): void -} - -interface WSWrapperOptions { - perMessageDeflate: boolean - handshakeTimeout: number - protocolVersion: number - origin: string - maxPayload: number - followRedirects: boolean - maxRedirects: number -} - -/** - * Provides `EventEmitter` interface for native browser `WebSocket`, - * same, as `ws` package provides. - */ -export default class WSWrapper extends EventEmitter { - public static CONNECTING = 0 - public static OPEN = 1 - public static CLOSING = 2 - // eslint-disable-next-line @typescript-eslint/no-magic-numbers -- magic number is being defined here - public static CLOSED = 3 - private readonly ws: WebSocket - - /** - * Constructs a browser-safe websocket. - * - * @param url - URL to connect to. - * @param _protocols - Not used. - * @param _websocketOptions - Not used. - */ - public constructor( - url: string, - _protocols: string | string[] | WSWrapperOptions | undefined, - _websocketOptions: WSWrapperOptions, - ) { - super() - this.setMaxListeners(Infinity) - - this.ws = new WebSocket(url) - - this.ws.onclose = (closeEvent: CloseEvent): void => { - let reason: Uint8Array | undefined - if (closeEvent.reason) { - const enc = new TextEncoder() - reason = enc.encode(closeEvent.reason) - } - this.emit('close', closeEvent.code, reason) - } - - this.ws.onopen = (): void => { - this.emit('open') - } - - this.ws.onerror = (error): void => { - this.emit('error', error) - } - - this.ws.onmessage = (message: MessageEvent): void => { - this.emit('message', message.data) - } - } - - /** - * Get the ready state of the websocket. - * - * @returns The Websocket's ready state. - */ - public get readyState(): number { - return this.ws.readyState - } - - /** - * Closes the websocket. - * - * @param code - Close code. - * @param reason - Close reason. - */ - public close(code?: number, reason?: Buffer): void { - if (this.readyState === 1) { - this.ws.close(code, reason) - } - } - - /** - * Sends a message over the Websocket connection. - * - * @param message - Message to send. - */ - public send(message: string): void { - this.ws.send(message) - } -} diff --git a/packages/xrpl/src/client/connection.ts b/packages/xrpl/src/client/connection.ts index 91db47e020..f47a976f3f 100644 --- a/packages/xrpl/src/client/connection.ts +++ b/packages/xrpl/src/client/connection.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'events' import type { Agent } from 'http' -import WebSocket from 'ws' +import WebSocket from 'isomorphic-ws' import { DisconnectedError, diff --git a/packages/xrpl/test/connection.test.ts b/packages/xrpl/test/connection.test.ts index 0753f31b27..0fa8f225df 100644 --- a/packages/xrpl/test/connection.test.ts +++ b/packages/xrpl/test/connection.test.ts @@ -389,7 +389,7 @@ describe('Connection', function () { _ignore, sendCallback, ): void { - sendCallback({ message: 'not connected' }) + sendCallback(new Error('not connected')) } await clientContext.client .request({ command: 'server_info' }) diff --git a/packages/xrpl/test/webpack.config.js b/packages/xrpl/test/webpack.config.js index 07b2a9d28e..bca59c1113 100644 --- a/packages/xrpl/test/webpack.config.js +++ b/packages/xrpl/test/webpack.config.js @@ -38,7 +38,6 @@ function webpackForTest(testFileName) { filename: match[1] + '.js', }, plugins: [ - new webpack.NormalModuleReplacementPlugin(/^ws$/, './WSWrapper'), new webpack.ProvidePlugin({ process: 'process/browser', }), @@ -93,9 +92,6 @@ function webpackForTest(testFileName) { __dirname: true, }, resolve: { - alias: { - ws: './dist/npm/client/WSWrapper.js', - }, extensions: ['.ts', '.js', '.json'], fallback: { module: false, diff --git a/packages/xrpl/webpack.config.js b/packages/xrpl/webpack.config.js index e3cffc2d6c..e6dd61281f 100644 --- a/packages/xrpl/webpack.config.js +++ b/packages/xrpl/webpack.config.js @@ -25,7 +25,6 @@ function getDefaultConfiguration() { }, devtool: 'source-map', plugins: [ - new webpack.NormalModuleReplacementPlugin(/^ws$/, './WSWrapper'), new webpack.ProvidePlugin({ process: 'process/browser' }), new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }), new webpack.IgnorePlugin({ @@ -54,9 +53,6 @@ function getDefaultConfiguration() { ], }, resolve: { - alias: { - ws: './dist/npm/client/WSWrapper.js', - }, extensions: ['.js', '.json'], // We don't want to webpack any of the local dependencies: // ripple-address-codec, ripple-binary-codec, ripple-keypairs, which are