From 39d5e7670b1d6482db6376350d87c8e510f1dd68 Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 18 Nov 2020 13:48:49 +0100 Subject: [PATCH] feat(singleton-manager): save singleton instance on window object --- .changeset/silent-ligers-clean.md | 8 ++++++++ packages/singleton-manager/README.md | 7 ++++--- packages/singleton-manager/package.json | 6 ++++-- .../src/SingletonManagerClass.js | 12 +++++++----- .../test/SingletonManagerClass.test.js | 19 ++++++++++++------- 5 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 .changeset/silent-ligers-clean.md diff --git a/.changeset/silent-ligers-clean.md b/.changeset/silent-ligers-clean.md new file mode 100644 index 000000000..0f835e140 --- /dev/null +++ b/.changeset/silent-ligers-clean.md @@ -0,0 +1,8 @@ +--- +'singleton-manager': minor +--- + +Changed on how to handle multiple instances of the singleton manager + +- save the map instance on the window object so multiple singleton manager versions can share the data. +- ignore subsequential set calls if the key is already set (did throw before) diff --git a/packages/singleton-manager/README.md b/packages/singleton-manager/README.md index 629793d5f..9d36b2d93 100644 --- a/packages/singleton-manager/README.md +++ b/packages/singleton-manager/README.md @@ -53,16 +53,17 @@ import { mySingleton } from 'my-singleton'; // will no always be what is "define ### Warning Overriding version is an App level concern hence components or "features" are not allowed to use it. -If you try to call multiple times for the same key then it will throw an error. +If you try to call it multiple times for the same key then it will be ignored. ```js // on app level singletonManager.set('my-singleton/index.js::1.x', compatibleSingleton); // somewhere in a dependency -singletonManager.set('my-singleton/index.js::1.x', compatibleSingleton); +singletonManager.set('my-singleton/index.js::1.x', otherSingleton); -// will throw an error that it is already defined +// .get('my-singleton/index.js::1.x') will always return the first set value +// e.g. the app can set it and no one can later override it ``` ### Example Singleton Maintainers diff --git a/packages/singleton-manager/package.json b/packages/singleton-manager/package.json index bdab3c43e..a48312a93 100644 --- a/packages/singleton-manager/package.json +++ b/packages/singleton-manager/package.json @@ -23,12 +23,14 @@ "types" ], "scripts": { + "debug": "cd ../../ && npm run debug -- --group singleton-manager", + "debug:firefox": "cd ../../ && npm run debug:firefox -- --group singleton-manager", + "debug:webkit": "cd ../../ && npm run debug:webkit -- --group singleton-manager", "prepublishOnly": "../../scripts/npm-prepublish.js", "start:fail": "es-dev-server -c demo/fail/server.js", "start:singleton": "es-dev-server -c demo/singleton/server.js", "start:singleton-complex": "es-dev-server -c demo/singleton-complex/server.js", - "test": "cd ../../ && npm run test:browser --grep \"packages/singleton-manager/test/**/*.test.js\"", - "test:watch": "cd ../../ && npm run test:browser:watch --grep \"packages/singleton-manager/test/**/*.test.js\"" + "test": "cd ../../ && npm run test:browser -- --group singleton-manager" }, "sideEffects": false, "keywords": [ diff --git a/packages/singleton-manager/src/SingletonManagerClass.js b/packages/singleton-manager/src/SingletonManagerClass.js index 49e9b7659..9b802bcb0 100644 --- a/packages/singleton-manager/src/SingletonManagerClass.js +++ b/packages/singleton-manager/src/SingletonManagerClass.js @@ -1,18 +1,20 @@ +const sym = Symbol.for('lion::SingletonManagerClassStorage'); + export class SingletonManagerClass { constructor() { - this._map = new Map(); + this._map = window[sym] ? window[sym] : (window[sym] = new Map()); } /** + * Ignores already existing keys (e.g. it will not override) + * * @param {string} key * @param {any} value - * @throws {Error} Will throw if the key is already defined */ set(key, value) { - if (this.has(key)) { - throw new Error(`The key "${key}" is already defined and can not be overridden.`); + if (!this.has(key)) { + this._map.set(key, value); } - this._map.set(key, value); } /** diff --git a/packages/singleton-manager/test/SingletonManagerClass.test.js b/packages/singleton-manager/test/SingletonManagerClass.test.js index bd2f0e77b..be494d927 100644 --- a/packages/singleton-manager/test/SingletonManagerClass.test.js +++ b/packages/singleton-manager/test/SingletonManagerClass.test.js @@ -19,13 +19,18 @@ describe('SingletonManagerClass', () => { expect(mngr.has('overlays/overlays.js::0.14.x')).to.be.false; }); - it('throws if an app tries to set an existing key again', () => { + it('does not override existing keys (e.g. subsequentual calls for the same keys are ignored)', () => { const mngr = new SingletonManagerClass(); - mngr.set('overlays/overlays.js::0.13.x', 'is-set'); - expect(() => { - mngr.set('overlays/overlays.js::0.13.x', 'new-set'); - }).to.throw( - 'The key "overlays/overlays.js::0.13.x" is already defined and can not be overridden.', - ); + mngr.set('overlays/overlays.js::0.14.x', 'is-set'); + mngr.set('overlays/overlays.js::0.14.x', 'new-set'); + expect(mngr.get('overlays/overlays.js::0.14.x')).to.equal('is-set'); + }); + + it('should return the same value with two SingletonManager instances', () => { + const mngr1 = new SingletonManagerClass(); + const mngr2 = new SingletonManagerClass(); + + mngr1.set('overlays/overlays.js::0.15.x', 'is-set'); + expect(mngr2.get('overlays/overlays.js::0.15.x')).to.equal('is-set'); }); });