import { createEffect, createRoot, createSignal, Signal } from 'solid-js'; import PouchDB from 'pouchdb'; import indexeddb from 'pouchdb-adapter-indexeddb'; import { sleep, until } from '../lib/async-wait'; import { openDatabases } from './open'; import { toHex } from '../lib/to-hex'; import { isEqual } from 'lodash'; PouchDB.plugin(indexeddb); declare global { var localDb: any; var db: any; var remoteDb: any; var currentAccount: any; var sync: any; } const [state, setState] = createSignal({}); export { state }; export const watchDbLegacy = async () => { createRoot(async (dispose) => { console.log({ caller: 'watchDbLegacy' }); db = globalThis.db; localDb = globalThis.localDb; const [status, setStatus] = createSignal({}); const [syncState, setSyncState] = createSignal({}); const updateStatus = async () => { const dbInfo = await db.info(); const localDbInfo = await localDb.info(); const remoteDbInfo = globalThis.remoteDb ? await remoteDb.info() : undefined; const tasks = PouchDB.activeTasks.list(); const newStatus = { ...status(), tasks, dbInfo, localDbInfo, remoteDbInfo, // date: new Date(), }; if (!isEqual(status(), newStatus)) { setStatus(newStatus); } }; createEffect(() => { console.log({ caller: 'watchDbLegacy', state: state(), status: status(), syncState: syncState(), sync, }); }); createEffect(() => { const newState = { ...state(), dbName: status()?.dbInfo?.db_name, localUpdateSeq: status()?.dbInfo?.update_seq, remoteUrl: status()?.remoteDbInfo?.host, sync: syncState(), }; if (!isEqual(newState, state())) { setState(newState); } }); updateStatus(); if (globalThis.sync) { globalThis.sync .on('change', function (info) { // handle change console.log({ caller: 'Sync / change', info }); if (info.direction === 'push') { setSyncState({ ...syncState(), lastSeq: info.change.last_seq }); } }) .on('paused', function (err) { // replication paused (e.g. replication up to date, user went offline) setSyncState({ ...syncState(), paused: true }); console.log({ caller: 'Sync / paused', err }); }) .on('active', function () { // replicate resumed (e.g. new changes replicating, user went back online) setSyncState({ ...syncState(), paused: false }); console.log({ caller: 'Sync / active' }); }) .on('denied', function (err) { // a document failed to replicate (e.g. due to permissions) console.error({ caller: 'Sync / denied', err }); }) .on('complete', function (info) { // handle complete console.log({ caller: 'Sync / complete', info }); }) .on('error', function (err) { // handle error console.error({ caller: 'Sync / error', err }); }); } const timerId = setInterval(updateStatus, 10000); // db.compact(); // await sleep(10000); const openIDb = (name: string) => new Promise((resolve, reject) => { const iDb = indexedDB.open(name); iDb.onerror = (event: any) => { console.error({ caller: 'watchDb', message: 'open db error', target: event.target, }); reject(event.target.errorCode); }; iDb.onsuccess = (event: any) => { console.log({ caller: 'watchDb', message: 'open db', target: event.target, }); resolve(event.target.result); }; }); const getAll = (store: any) => new Promise((resolve, reject) => { const request = store.getAll(); request.onerror = (event: any) => { console.error({ caller: 'watchDb', message: 'getAll error', target: event.target, }); reject(event.target.errorCode); }; request.onsuccess = (event: any) => { console.log({ caller: 'watchDb', message: 'getAll', target: event.target, }); resolve(event.target.result as any[]); }; }); await until( () => state()?.sync?.paused && state()?.sync?.lastSeq >= state()?.localUpdateSeq, 1000 ); console.log({ caller: 'watchDbLegacy / ready to purge after sync ' }); // const iDb = (await openIDb('_pouch__dyomedea_')) as IDBDatabase; // const bySequence = iDb.transaction('docs', 'readonly'); // const store = bySequence.objectStore('docs'); // console.log({ // caller: 'watchDb', // message: 'transaction opened', // bySequence, // store, // }); // const docs = (await getAll(store)) as any[]; // docs.forEach(async (doc) => { // const { id, rev, deleted } = doc; // if (deleted !== 0) { // // const purge = await db.purge(id, rev); // console.log({ // caller: 'watchDb', // message: 'purging', // id, // rev, // doc, // // purge, // }); // await sleep(1000); // } // }); }); };