diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd9a8e88..d7ef2d0da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# 0.41.0 +# 0.42.1 + +- Add assertSingletonPackage to util +- Ensure that only a single keyring instance is loaded (uses above) + +# 0.41.1 - Extensions to the client-specific database interfaces (non-breaking for API and util users) diff --git a/packages/keyring/src/index.ts b/packages/keyring/src/index.ts index 567b84cb5..9ab68cabb 100644 --- a/packages/keyring/src/index.ts +++ b/packages/keyring/src/index.ts @@ -5,7 +5,7 @@ import { KeypairType } from '@polkadot/util-crypto/types'; import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringOptions } from './types'; -import { assert, hexToU8a, isNumber, isHex, stringToU8a } from '@polkadot/util'; +import { assert, assertSingletonPackage, hexToU8a, isNumber, isHex, stringToU8a } from '@polkadot/util'; import { keyExtractSuri, mnemonicToSeed , naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, mnemonicToMiniSecret, keyFromPath } from '@polkadot/util-crypto'; import { decodeAddress, encodeAddress, setAddressPrefix } from './address'; @@ -13,6 +13,8 @@ import { DEV_PHRASE } from './defaults'; import createPair from './pair'; import Pairs from './pairs'; +assertSingletonPackage('@polkadot/keyring'); + /** * # @polkadot/keyring * diff --git a/packages/util/src/assertSingletonPackage.spec.ts b/packages/util/src/assertSingletonPackage.spec.ts new file mode 100644 index 000000000..9fc763c69 --- /dev/null +++ b/packages/util/src/assertSingletonPackage.spec.ts @@ -0,0 +1,21 @@ +// Copyright 2017-2019 @polkadot/util authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { assertSingletonPackage } from '.'; + +describe('assertSingletonPackage', () => { + const NAME = 'assertSingletonPackage'; + + it('should not throw the first time', () => { + expect( + () => assertSingletonPackage(NAME) + ).not.toThrow(); + }); + + it('should throw the second time', () => { + expect( + () => assertSingletonPackage(NAME) + ).toThrow(/Multiple versions of assertSingletonPackage detected/); + }); +}); diff --git a/packages/util/src/assertSingletonPackage.ts b/packages/util/src/assertSingletonPackage.ts new file mode 100644 index 000000000..77ed9de19 --- /dev/null +++ b/packages/util/src/assertSingletonPackage.ts @@ -0,0 +1,22 @@ +// Copyright 2017-2019 @polkadot/util authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import isUndefined from './is/undefined'; +import assert from './assert'; + +/** + * @name assertSingletonPackage + * @summary Checks that a specific package is only imported once + */ +export default function assertSingletonPackage (name: string): void { + const _global: any = isUndefined(window) ? global : window; + + if (isUndefined(_global.__polkadotjs)) { + _global.__polkadotjs = {}; + } + + assert(isUndefined(_global.__polkadotjs[name]), `Multiple versions of ${name} detected, ensure that there is only version one in your dependency tree`); + + _global.__polkadotjs[name] = true; +} diff --git a/packages/util/src/index.ts b/packages/util/src/index.ts index d756c198f..b4c3a5f9b 100644 --- a/packages/util/src/index.ts +++ b/packages/util/src/index.ts @@ -9,6 +9,7 @@ import './polyfill'; */ export { default as assert } from './assert'; +export { default as assertSingletonPackage } from './assertSingletonPackage'; export { default as logger } from './logger'; export { default as promisify } from './promisify';