From 51686f0cd4355da4b5e2f3901a012ce4ae20e9f0 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 22 Feb 2020 13:56:37 +0100 Subject: [PATCH] Don't clobber global space in WS provider (#1922) * Don't clbber global space in WS provider * Re-use getWSClass --- packages/rpc-provider/src/ws/Provider.ts | 9 ++++--- .../{polyfill.spec.ts => getWSClass.spec.ts} | 17 +++++++----- packages/rpc-provider/src/ws/getWSClass.ts | 13 +++++++++ packages/rpc-provider/src/ws/polyfill.ts | 7 ----- packages/typegen/package.json | 2 ++ packages/typegen/src/extractChain.ts | 3 ++- packages/typegen/src/fromChain.ts | 27 ++++++++++--------- yarn.lock | 7 +++++ 8 files changed, 54 insertions(+), 31 deletions(-) rename packages/rpc-provider/src/ws/{polyfill.spec.ts => getWSClass.spec.ts} (61%) create mode 100644 packages/rpc-provider/src/ws/getWSClass.ts delete mode 100644 packages/rpc-provider/src/ws/polyfill.ts diff --git a/packages/rpc-provider/src/ws/Provider.ts b/packages/rpc-provider/src/ws/Provider.ts index 592b1c10d3..5a34597013 100644 --- a/packages/rpc-provider/src/ws/Provider.ts +++ b/packages/rpc-provider/src/ws/Provider.ts @@ -5,13 +5,12 @@ import { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitted, ProviderInterfaceEmitCb } from '../types'; -import './polyfill'; - import EventEmitter from 'eventemitter3'; import { assert, isNull, isUndefined, logger } from '@polkadot/util'; import Coder from '../coder'; import defaults from '../defaults'; +import getWSClass from './getWSClass'; type CallbackHandler = (error?: null | Error, value?: any) => void; @@ -122,9 +121,11 @@ export default class WsProvider implements WSProviderInterface { * @description The [[WsProvider]] connects automatically by default, however if you decided otherwise, you may * connect manually using this method. */ - public connect (): void { + public async connect (): Promise { try { - this.#websocket = new WebSocket(this.#endpoint); + const WS = await getWSClass(); + + this.#websocket = new WS(this.#endpoint); this.#websocket.onclose = this.#onSocketClose; this.#websocket.onerror = this.#onSocketError; this.#websocket.onmessage = this.#onSocketMessage; diff --git a/packages/rpc-provider/src/ws/polyfill.spec.ts b/packages/rpc-provider/src/ws/getWSClass.spec.ts similarity index 61% rename from packages/rpc-provider/src/ws/polyfill.spec.ts rename to packages/rpc-provider/src/ws/getWSClass.spec.ts index 7780063265..930b96ab44 100644 --- a/packages/rpc-provider/src/ws/polyfill.spec.ts +++ b/packages/rpc-provider/src/ws/getWSClass.spec.ts @@ -5,10 +5,11 @@ import { Constructor } from '@polkadot/types/types'; import { Global } from './../mock/types'; +import getWSClass from './getWSClass'; declare const global: Global; -describe('ws/polyfill', (): void => { +describe('getWebScoket', (): void => { let origWs: Constructor; beforeEach((): void => { @@ -19,17 +20,19 @@ describe('ws/polyfill', (): void => { global.WebSocket = origWs; }); - it('polyfills with no exceptions (with WebSocket)', (): void => { + it('polyfills with no exceptions (with WebSocket)', async (): Promise => { (global as any).WebSocket = undefined; - require('./polyfill'); - expect(global.WebSocket).toBeDefined(); + const WS = await getWSClass(); + + expect(WS).toBeDefined(); }); - it('polyfills with no exceptions (without WebSocket)', (): void => { + it('polyfills with no exceptions (without WebSocket)', async (): Promise => { (global as any).WebSocket = (): boolean => true; - require('./polyfill'); - expect(global.WebSocket).toBeDefined(); + const WS = await getWSClass(); + + expect(WS).toBeDefined(); }); }); diff --git a/packages/rpc-provider/src/ws/getWSClass.ts b/packages/rpc-provider/src/ws/getWSClass.ts new file mode 100644 index 0000000000..f8214b9a2d --- /dev/null +++ b/packages/rpc-provider/src/ws/getWSClass.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2020 @polkadot/rpc-provider authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +export default async function getWSClass (): Promise { + if (typeof WebSocket === 'undefined') { + const { w3cwebsocket } = await import('websocket'); + + return w3cwebsocket as unknown as typeof WebSocket; + } + + return WebSocket; +} diff --git a/packages/rpc-provider/src/ws/polyfill.ts b/packages/rpc-provider/src/ws/polyfill.ts deleted file mode 100644 index acb1bbd75d..0000000000 --- a/packages/rpc-provider/src/ws/polyfill.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017-2020 @polkadot/rpc-provider authors & contributors -// This software may be modified and distributed under the terms -// of the Apache-2.0 license. See the LICENSE file for details. - -if (typeof WebSocket === 'undefined') { - (global as any).WebSocket = require('websocket').w3cwebsocket; -} diff --git a/packages/typegen/package.json b/packages/typegen/package.json index 745cabeee8..398e9f28d9 100644 --- a/packages/typegen/package.json +++ b/packages/typegen/package.json @@ -39,12 +39,14 @@ "@polkadot/api": "1.4.0-beta.27", "@polkadot/jsonrpc": "1.4.0-beta.27", "@polkadot/metadata": "1.4.0-beta.27", + "@polkadot/rpc-provider": "1.4.0-beta.27", "@polkadot/types": "1.4.0-beta.27", "@polkadot/util": "^2.4.1", "websocket": "^1.0.31", "yargs": "^15.1.0" }, "devDependencies": { + "@types/websocket": "^1.0.0", "@types/yargs": "^15.0.3" } } diff --git a/packages/typegen/src/extractChain.ts b/packages/typegen/src/extractChain.ts index b864433003..dfb8f97980 100644 --- a/packages/typegen/src/extractChain.ts +++ b/packages/typegen/src/extractChain.ts @@ -30,10 +30,11 @@ export default function main (): void { const { ws } = yargs .usage('Usage: [options]') .wrap(120) + .strict() .options({ ws: { default: 'ws://127.0.0.1:9944', - description: 'The API endpoint to connect to, e.g. wss://poc3-rpc.polkadot.io', + description: 'The API endpoint to connect to, e.g. wss://kusama-rpc.polkadot.io', type: 'string', required: true } diff --git a/packages/typegen/src/fromChain.ts b/packages/typegen/src/fromChain.ts index d7b6517691..187d2aa3ae 100644 --- a/packages/typegen/src/fromChain.ts +++ b/packages/typegen/src/fromChain.ts @@ -4,16 +4,13 @@ import path from 'path'; import yargs from 'yargs'; +import getWSClass from '@polkadot/rpc-provider/ws/getWSClass'; import { formatNumber } from '@polkadot/util'; import generateConst from './generate/consts'; import generateQuery from './generate/query'; import generateTx from './generate/tx'; -if (typeof WebSocket === 'undefined') { - (global as any).WebSocket = require('websocket').w3cwebsocket; -} - let websocket: any = null; function generate (metaHex: string, pkg: string | undefined, output: string, isStrict?: boolean): void { @@ -67,19 +64,25 @@ export default function main (): void { type: 'string' }, strict: { - description: 'Turns on stirct mode, not outputting genric versions', + description: 'Turns on stict mode, no output of catch-all generic versions', type: 'boolean' } }).argv; if (endpoint.startsWith('wss://') || endpoint.startsWith('ws://')) { - websocket = new WebSocket(endpoint); - websocket.onclose = onSocketClose; - websocket.onerror = onSocketError; - websocket.onopen = onSocketOpen; - websocket.onmessage = (message: any): void => { - generate(JSON.parse(message.data).result, pkg, output, isStrict); - }; + getWSClass() + .then((WS): void => { + websocket = new WS(endpoint); + websocket.onclose = onSocketClose; + websocket.onerror = onSocketError; + websocket.onopen = onSocketOpen; + websocket.onmessage = (message: any): void => { + generate(JSON.parse(message.data).result, pkg, output, isStrict); + }; + }) + .catch((): void => { + process.exit(1); + }); } else { generate(require(path.join(process.cwd(), endpoint)).result, pkg, output, isStrict); } diff --git a/yarn.lock b/yarn.lock index 5c0d500d98..9102c27757 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2257,6 +2257,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/websocket@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.0.tgz#828c794b0a50949ad061aa311af1009934197e4b" + integrity sha512-MLr8hDM8y7vvdAdnoDEP5LotRoYJj7wgT6mWzCUQH/gHqzS4qcnOT/K4dhC0WimWIUiA3Arj9QAJGGKNRiRZKA== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"