UNPKG

@furystack/shades

Version:

Google Authentication Provider for FuryStack

58 lines 2.47 kB
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