simpleton-state-manager
Version:
A Simple State Manager for WebApp UI
100 lines (84 loc) • 2.34 kB
JavaScript
export default class SimpletonStateManager {
static instance = null;
#models = {}; //private member
#subscribers = {}; //privare member
constructor() {
if (!SimpletonStateManager.instance) { //Singleton
SimpletonStateManager.instance = this;
this.modelsProxy = new Proxy(this.#models, this.proxyHandler);
} else {
return SimpletonStateManager.instance;
}
}
proxyHandler = {
get(target, prop, receiver) {
return Reflect.get(target, prop, receiver);
},
set(obj, prop, value) {
Reflect.set(obj, prop, value);
SimpletonStateManager.instance.modelChanged(prop);
return true;
},
};
setModel(modelName, model) {
this.modelsProxy[modelName] = model;
}
notifyModelListeners(modelName) {
this.modelChanged(modelName);
}
getModel(modelName) {
const model = this.modelsProxy[modelName];
const isArr = model instanceof Array;
const isObj = model instanceof Object;
if (model != null) {
if(model instanceof Function) {
return model;
}
else if (!isObj) {
return model;
} if (isArr) {
return [ ...model ];
}
return { ...model };
}
return model;
}
getModelList() {
return { ...this.modelsProxy };
}
subscribers(modelName) {
if (this.#subscribers[modelName] == null) {
this.#subscribers[modelName] = [];
}
return this.#subscribers[modelName];
}
subscribe(modelName, callback) {
const modelSubscribers = this.subscribers(modelName);
const key = modelSubscribers.push(callback) - 1;
// console.log('subscribe', modelName, callback, key);
return key;
}
unsubscribe(modelName, key) {
const modelSubscribers = this.#subscribers[modelName];
if (modelSubscribers) {
delete modelSubscribers[key];
}
}
unsubscribeAll() {
this.#models = {};
this.#subscribers = {};
this.modelsProxy = new Proxy(this.#models, this.proxyHandler);
}
modelChanged(modelName) {
const value = this.getModel(modelName);
const modelSubscribers = this.#subscribers[modelName];
if (modelSubscribers) {
for (const key of Object.keys(modelSubscribers)) {
const callback = modelSubscribers[key];
if (callback) {
callback(value);
}
}
}
}
}