feat(singleton-manager): save singleton instance on window object

This commit is contained in:
Carlos 2020-11-18 13:48:49 +01:00 committed by Thomas Allmer
parent b52f74df58
commit 39d5e7670b
5 changed files with 35 additions and 17 deletions

View file

@ -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)

View file

@ -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

View file

@ -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": [

View file

@ -1,19 +1,21 @@
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);
}
}
/**
* @param {string} key

View file

@ -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');
});
});