"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GetServiceManifest = void 0; exports.getServiceManifest = getServiceManifest; const AbortedError_1 = require("../../../base/lib/util/AbortedError"); const Drop_1 = require("../../../base/lib/util/Drop"); const deepEqual_1 = require("../../../base/lib/util/deepEqual"); class GetServiceManifest { constructor(effects, packageId, map, eq) { this.effects = effects; this.packageId = packageId; this.map = map; this.eq = eq; } /** * Returns the manifest of a service. Reruns the context from which it has been called if the underlying value changes */ async const() { let abort = new AbortController(); const watch = this.watch(abort.signal); const res = await watch.next(); if (this.effects.constRetry) { watch .next() .then(() => { abort.abort(); this.effects.constRetry && this.effects.constRetry(); }) .catch(); } return res.value; } /** * Returns the manifest of a service. Does nothing if it changes */ async once() { const manifest = await this.effects.getServiceManifest({ packageId: this.packageId, }); return this.map(manifest); } async *watchGen(abort) { let prev = null; const resolveCell = { resolve: () => { } }; this.effects.onLeaveContext(() => { resolveCell.resolve(); }); abort?.addEventListener('abort', () => resolveCell.resolve()); while (this.effects.isInContext && !abort?.aborted) { let callback = () => { }; const waitForNext = new Promise((resolve) => { callback = resolve; resolveCell.resolve = resolve; }); const next = this.map(await this.effects.getServiceManifest({ packageId: this.packageId, callback: () => callback(), })); if (!prev || !this.eq(prev.value, next)) { prev = { value: next }; yield next; } await waitForNext; } return new Promise((_, rej) => rej(new AbortedError_1.AbortedError())); } /** * Watches the manifest of a service. Returns an async iterator that yields whenever the value changes */ watch(abort) { const ctrl = new AbortController(); abort?.addEventListener('abort', () => ctrl.abort()); return Drop_1.DropGenerator.of(this.watchGen(ctrl.signal), () => ctrl.abort()); } /** * Watches the manifest of a service. Takes a custom callback function to run whenever it changes */ onChange(callback) { ; (async () => { const ctrl = new AbortController(); for await (const value of this.watch(ctrl.signal)) { try { const res = await callback(value); if (res.cancel) { ctrl.abort(); break; } } catch (e) { console.error('callback function threw an error @ GetServiceManifest.onChange', e); } } })() .catch((e) => callback(null, e)) .catch((e) => console.error('callback function threw an error @ GetServiceManifest.onChange', e)); } /** * Watches the manifest of a service. Returns when the predicate is true */ waitFor(pred) { const ctrl = new AbortController(); return Drop_1.DropPromise.of(Promise.resolve().then(async () => { for await (const next of this.watchGen(ctrl.signal)) { if (pred(next)) { return next; } } throw new Error('context left before predicate passed'); }), () => ctrl.abort()); } } exports.GetServiceManifest = GetServiceManifest; function getServiceManifest(effects, packageId, map, eq) { return new GetServiceManifest(effects, packageId, map ?? ((a) => a), eq ?? ((a, b) => (0, deepEqual_1.deepEqual)(a, b))); } //# sourceMappingURL=GetServiceManifest.js.map