var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { defer, from, map, combineLatest } from 'rxjs';
import BroadcastChannelSender from '../../../../../backend/channels/BroadcastChannelSender';
import { broadcastStatus } from '../../../../../backend/channels/broadcastStatus';
import { EntryType } from '../../../../../CozoDb/types/entities';
import { QueuePriority } from '../../../../../QueueManager/types';
import { fetchCyberlinksAndResolveParticles } from '../utils/links';
import { createLoopObservable } from '../utils/rxjs';
import { PARTICLES_SYNC_INTERVAL } from '../consts';
import { changeSyncStatus } from '../../utils';
import { serializeError } from 'serialize-error';
class SyncParticlesLoop {
    get loop$() {
        return this._loop$;
    }
    constructor(deps, particlesResolver) {
        this.statusApi = broadcastStatus('particle', new BroadcastChannelSender());
        if (!deps.params$) {
            throw new Error('params$ is not defined');
        }
        deps.dbInstance$.subscribe((db) => {
            this.db = db;
        });
        deps.params$.subscribe((params) => {
            this.params = params;
        });
        this.particlesResolver = particlesResolver;
        this.isInitialized$ = combineLatest([
            deps.dbInstance$,
            deps.ipfsInstance$,
            deps.params$,
            particlesResolver.isInitialized$,
        ]).pipe(map(([dbInstance, ipfsInstance, params, syncQueueInitialized]) => !!ipfsInstance &&
            !!dbInstance &&
            !!syncQueueInitialized &&
            !!params.cyberIndexUrl &&
            !!params.myAddress));
    }
    syncParticles() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const result = yield this.db.findSyncStatus({
                    entryType: EntryType.particle,
                });
                const syncStatusEntities = (yield Promise.all(result.map((syncStatus) => __awaiter(this, void 0, void 0, function* () {
                    const { id, timestampUpdate } = syncStatus;
                    const links = yield fetchCyberlinksAndResolveParticles(this.params.cyberIndexUrl, id, timestampUpdate, this.particlesResolver, QueuePriority.MEDIUM);
                    return links.length > 0
                        ? changeSyncStatus(syncStatus, links)
                        : undefined;
                })))).filter((i) => !!i);
                syncStatusEntities.length > 0 &&
                    (yield this.db.putSyncStatus(syncStatusEntities));
            }
            catch (e) {
                const serializedError = serializeError(e);
                console.log('>>> SyncParticlesLoop error:', JSON.stringify(serializedError, null, 2));
                throw e;
            }
        });
    }
    start() {
        this._loop$ = createLoopObservable(PARTICLES_SYNC_INTERVAL, this.isInitialized$, defer(() => from(this.syncParticles())), () => this.statusApi.sendStatus('in-progress'));
        this._loop$.subscribe({
            next: (result) => this.statusApi.sendStatus('idle'),
            error: (err) => this.statusApi.sendStatus('error', err.toString()),
        });
        return this;
    }
}
export default SyncParticlesLoop;
//# sourceMappingURL=SyncParticlesLoop.js.map