feat(singleton-manager): save singleton instance on window object
This commit is contained in:
parent
b52f74df58
commit
39d5e7670b
5 changed files with 35 additions and 17 deletions
8
.changeset/silent-ligers-clean.md
Normal file
8
.changeset/silent-ligers-clean.md
Normal 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)
|
||||||
|
|
@ -53,16 +53,17 @@ import { mySingleton } from 'my-singleton'; // will no always be what is "define
|
||||||
### Warning
|
### Warning
|
||||||
|
|
||||||
Overriding version is an App level concern hence components or "features" are not allowed to use it.
|
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
|
```js
|
||||||
// on app level
|
// on app level
|
||||||
singletonManager.set('my-singleton/index.js::1.x', compatibleSingleton);
|
singletonManager.set('my-singleton/index.js::1.x', compatibleSingleton);
|
||||||
|
|
||||||
// somewhere in a dependency
|
// 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
|
### Example Singleton Maintainers
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,14 @@
|
||||||
"types"
|
"types"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"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",
|
"prepublishOnly": "../../scripts/npm-prepublish.js",
|
||||||
"start:fail": "es-dev-server -c demo/fail/server.js",
|
"start:fail": "es-dev-server -c demo/fail/server.js",
|
||||||
"start:singleton": "es-dev-server -c demo/singleton/server.js",
|
"start:singleton": "es-dev-server -c demo/singleton/server.js",
|
||||||
"start:singleton-complex": "es-dev-server -c demo/singleton-complex/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": "cd ../../ && npm run test:browser -- --group singleton-manager"
|
||||||
"test:watch": "cd ../../ && npm run test:browser:watch --grep \"packages/singleton-manager/test/**/*.test.js\""
|
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
|
const sym = Symbol.for('lion::SingletonManagerClassStorage');
|
||||||
|
|
||||||
export class SingletonManagerClass {
|
export class SingletonManagerClass {
|
||||||
constructor() {
|
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 {string} key
|
||||||
* @param {any} value
|
* @param {any} value
|
||||||
* @throws {Error} Will throw if the key is already defined
|
|
||||||
*/
|
*/
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
if (this.has(key)) {
|
if (!this.has(key)) {
|
||||||
throw new Error(`The key "${key}" is already defined and can not be overridden.`);
|
this._map.set(key, value);
|
||||||
}
|
}
|
||||||
this._map.set(key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,18 @@ describe('SingletonManagerClass', () => {
|
||||||
expect(mngr.has('overlays/overlays.js::0.14.x')).to.be.false;
|
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();
|
const mngr = new SingletonManagerClass();
|
||||||
mngr.set('overlays/overlays.js::0.13.x', 'is-set');
|
mngr.set('overlays/overlays.js::0.14.x', 'is-set');
|
||||||
expect(() => {
|
mngr.set('overlays/overlays.js::0.14.x', 'new-set');
|
||||||
mngr.set('overlays/overlays.js::0.13.x', 'new-set');
|
expect(mngr.get('overlays/overlays.js::0.14.x')).to.equal('is-set');
|
||||||
}).to.throw(
|
});
|
||||||
'The key "overlays/overlays.js::0.13.x" is already defined and can not be overridden.',
|
|
||||||
);
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue