@yoroi/common
Version:
The Common package of Yoroi SDK
97 lines (96 loc) • 3.17 kB
JavaScript
;
import { observerMaker } from '../../observer/observer';
import { intersection } from '../../utils/arrays';
import { isString } from '../../utils/parsers';
export const observableStorageMaker = storage => {
const triggers = ['clear',
// 'removeFolder', can be added later as long the key checks for "/" in the arg when string
'multiSet', 'setItem', 'multiRemove', 'removeItem'];
const observer = observerMaker();
const onChange = (keysToObserve, callback) => {
const wrappedCallback = keysUpdated => {
if (!keysUpdated) {
callback(null);
} else {
const keysToAnnounce = intersection(keysToObserve, keysUpdated);
if (keysToAnnounce.length > 0) callback(keysToAnnounce);
}
};
return observer.subscribe(wrappedCallback);
};
const proxyHandler = {
get(target, property, receiver) {
const origProperty = target[property];
if (typeof origProperty === 'function' && triggers.includes(property)) {
const origMethod = origProperty;
return function (...args) {
const notify = () => {
const [firstArg] = args;
const isArray = Array.isArray(firstArg);
if (isString(firstArg)) {
// single operations
observer.notify([firstArg]);
} else if (isArray) {
// multi operations
const keys = firstArg;
observer.notify(keys);
} else {
// clear
observer.notify(null);
}
};
const result = origMethod.apply(target, args);
if (result instanceof Promise) {
return result.then(resolvedValue => {
notify();
return resolvedValue;
});
} else {
notify();
return result;
}
};
}
return Reflect.get(target, property, receiver);
}
};
const proxiedStorage = new Proxy(storage, proxyHandler);
return {
...proxiedStorage,
onChange,
observable: observer.observable
};
};
export const observableMultiStorageMaker = storage => {
const triggers = ['clear', 'saveMany'];
const observer = observerMaker();
const onChange = callback => observer.subscribe(callback);
const proxyHandler = {
get(target, property, receiver) {
const origProperty = target[property];
if (typeof origProperty === 'function' && triggers.includes(property)) {
const origMethod = origProperty;
return function (...args) {
const result = origMethod.apply(target, args);
if (result instanceof Promise) {
return result.then(resolvedValue => {
observer.notify(null);
return resolvedValue;
});
} else {
observer.notify(null);
return result;
}
};
}
return Reflect.get(target, property, receiver);
}
};
const proxiedStorage = new Proxy(storage, proxyHandler);
return {
...proxiedStorage,
onChange,
observable: observer.observable
};
};
//# sourceMappingURL=observable-storage.js.map