@furystack/shades
Version:
Google Authentication Provider for FuryStack
58 lines • 2.47 kB
JavaScript
import { AggregatedError } from '@furystack/core';
import { ObservableValue, isAsyncDisposable, isDisposable } from '@furystack/utils';
/**
* Class for managing observables and disposables for components, based on key-value maps
*/
export class ResourceManager {
disposables = new Map();
useDisposable(key, factory) {
const existing = this.disposables.get(key);
if (!existing) {
const created = factory();
this.disposables.set(key, created);
return created;
}
return existing;
}
observers = new Map();
useObservable = (key, observable, onChange, options) => {
const alreadyUsed = this.observers.get(key);
if (alreadyUsed) {
return [alreadyUsed.observable.getValue(), alreadyUsed.observable.setValue.bind(alreadyUsed.observable)];
}
const observer = observable.subscribe(onChange, options);
this.observers.set(key, observer);
return [observable.getValue(), observable.setValue.bind(observable)];
};
stateObservers = new Map();
useState = (key, initialValue, callback) => {
if (!this.stateObservers.has(key)) {
const newObservable = new ObservableValue(initialValue);
this.stateObservers.set(key, newObservable);
newObservable.subscribe(callback);
}
const observable = this.stateObservers.get(key);
return [observable.getValue(), observable.setValue.bind(observable)];
};
async [Symbol.asyncDispose]() {
const disposeResult = await Promise.allSettled([...this.disposables].map(async ([_key, resource]) => {
if (isDisposable(resource)) {
resource[Symbol.dispose]();
}
if (isAsyncDisposable(resource)) {
await resource[Symbol.asyncDispose]();
}
}));
const fails = disposeResult.filter((r) => r.status === 'rejected');
if (fails && fails.length) {
const error = new AggregatedError(`There was an error during disposing ${fails.length} stores: ${fails.map((f) => f.reason).join(', ')}`, fails);
throw error;
}
this.disposables.clear();
this.observers.forEach((r) => r[Symbol.dispose]());
this.observers.clear();
this.stateObservers.forEach((r) => r[Symbol.dispose]());
this.stateObservers.clear();
}
}
//# sourceMappingURL=resource-manager.js.map