2020-08-25 22:11:26 +00:00
|
|
|
/**
|
|
|
|
* @author Martin Karkowski
|
|
|
|
* @email m.karkowski@zema.de
|
|
|
|
* @desc [description]
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2022-01-18 07:01:50 +00:00
|
|
|
* Function to get a singleton. To create the singleton, the parameter *create* is used. This will be called once.
|
|
|
|
* The singleton will be stored as *global* variable and can be accessed by the identifier
|
2022-01-18 20:51:19 +00:00
|
|
|
*
|
2022-01-18 07:01:50 +00:00
|
|
|
* @author M.Karkowski
|
|
|
|
* @export
|
|
|
|
* @template T The Type of the singleton
|
|
|
|
* @param {string} identifier Identifier to access the singleton
|
|
|
|
* @param {() => T} create The Callback which is used to create the instance.
|
|
|
|
* @return An object, containing the key **instances**, where you'll find the instance and an helper function **setInstance** to redefine the instance
|
2020-08-25 22:11:26 +00:00
|
|
|
*/
|
2022-01-18 20:51:19 +00:00
|
|
|
export function getSingleton<T>(
|
|
|
|
identifier: string,
|
|
|
|
create: () => T
|
|
|
|
): {
|
2022-01-18 07:01:50 +00:00
|
|
|
instance: T;
|
|
|
|
setInstance: (value: T) => void;
|
|
|
|
} {
|
2021-12-04 07:25:26 +00:00
|
|
|
// Extract all
|
2020-08-25 22:11:26 +00:00
|
|
|
const globalSymbols = Object.getOwnPropertySymbols(global);
|
|
|
|
|
|
|
|
// create a unique, global symbol name
|
|
|
|
// -----------------------------------
|
|
|
|
const IDENTIFIER_DISPATCHER_CONTAINER = Symbol.for(identifier);
|
|
|
|
|
|
|
|
// check if the global object has this symbol
|
|
|
|
// add it if it does not have the symbol, yet
|
|
|
|
// ------------------------------------------
|
2021-12-04 07:25:26 +00:00
|
|
|
const hasContainer =
|
|
|
|
globalSymbols.indexOf(IDENTIFIER_DISPATCHER_CONTAINER) > -1;
|
2020-08-25 22:11:26 +00:00
|
|
|
|
|
|
|
if (!hasContainer) {
|
|
|
|
global[IDENTIFIER_DISPATCHER_CONTAINER] = create();
|
|
|
|
}
|
|
|
|
|
|
|
|
const ret: {
|
2021-12-04 07:25:26 +00:00
|
|
|
instance: T;
|
|
|
|
setInstance: (value: T) => void;
|
2020-08-25 22:11:26 +00:00
|
|
|
} = {
|
|
|
|
instance: global[IDENTIFIER_DISPATCHER_CONTAINER],
|
|
|
|
setInstance: (value: T) => {
|
|
|
|
global[IDENTIFIER_DISPATCHER_CONTAINER] = value;
|
2021-12-04 07:25:26 +00:00
|
|
|
},
|
|
|
|
};
|
2020-08-25 22:11:26 +00:00
|
|
|
|
|
|
|
// define the singleton API
|
|
|
|
// ------------------------
|
2021-12-04 07:25:26 +00:00
|
|
|
Object.defineProperty(ret, "instance", {
|
2020-08-25 22:11:26 +00:00
|
|
|
get: function () {
|
|
|
|
return global[IDENTIFIER_DISPATCHER_CONTAINER];
|
2021-12-04 07:25:26 +00:00
|
|
|
},
|
2020-08-25 22:11:26 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// ensure the API is never changed
|
|
|
|
// -------------------------------
|
|
|
|
Object.freeze(ret);
|
|
|
|
|
|
|
|
return ret;
|
2021-12-04 07:25:26 +00:00
|
|
|
}
|