diff --git a/packages/gallery/src/app.js b/packages/gallery/src/app.js index 2afa314..995f353 100644 --- a/packages/gallery/src/app.js +++ b/packages/gallery/src/app.js @@ -35,7 +35,7 @@ function onRouteChange(router, route) { update(route); } -image.imported.subscribe(generateThumbnails); +image.watcher(generateThumbnails); image.imported.subscribe(redraw); image.removed.subscribe(redraw); index.added.subscribe(redraw); diff --git a/packages/gallery/src/contextLoaders/generateThumbnails.js b/packages/gallery/src/contextLoaders/generateThumbnails.js index 9aa753f..58da3ee 100644 --- a/packages/gallery/src/contextLoaders/generateThumbnails.js +++ b/packages/gallery/src/contextLoaders/generateThumbnails.js @@ -1,4 +1,6 @@ -export default async function(...args) { - const module = await import('../context/generateThumbnails'); - module.invoke(...args); +export default async function(id, deleted) { + if (!deleted) { + const module = await import('../context/generateThumbnails'); + module.invoke(id, deleted); + } } diff --git a/packages/gallery/src/data/image.js b/packages/gallery/src/data/image.js index 242db68..c9dad65 100644 --- a/packages/gallery/src/data/image.js +++ b/packages/gallery/src/data/image.js @@ -3,15 +3,31 @@ import { log, error } from '../services/console.js'; import { sha256 } from '../utils/crypto.js'; import { blobToArrayBuffer, deepAssign } from '../utils/conversion.js'; import { Event, backgroundTask } from '../utils/event.js'; +import { Watcher } from '../utils/watcher.js'; const db = getDatabase(); const PROCESS_PREFIX = 'importing'; const PREFIX = 'image'; +const SELECTOR = { + _id: { + $gt: `${PREFIX}_`, + $lt: `${PREFIX}_\ufff0` + } +}; +const IMPORT_SELECTOR = { + _id: { + $gt: `${PROCESS_PREFIX}_`, + $lt: `${PROCESS_PREFIX}_\ufff0` + } +}; // Events export const imported = new Event('Image.imported'); export const removed = new Event('Image.removed'); +// Watchers +export const watcher = Watcher(db, SELECTOR); + // Methods const getId = id => (id.startsWith(PREFIX) ? id : `${PREFIX}_${id}`); @@ -76,12 +92,7 @@ export async function addAttachment(doc, key, blob) { // Internal Functions const processImportables = backgroundTask(async function _processImportables() { const result = await db.find({ - selector: { - _id: { - $gt: `${PROCESS_PREFIX}_`, - $lt: `${PROCESS_PREFIX}_\ufff0` - } - }, + selector: IMPORT_SELECTOR, limit: 1 }); diff --git a/packages/gallery/src/utils/watcher.js b/packages/gallery/src/utils/watcher.js new file mode 100644 index 0000000..269a047 --- /dev/null +++ b/packages/gallery/src/utils/watcher.js @@ -0,0 +1,36 @@ +import { log, error } from '../services/console.js'; + +export function Watcher(db, selector) { + const subscribers = new Set(); + let changes = null; + + return function subscribe(fn) { + subscribers.add(fn); + + if (subscribers.size === 1 && !changes) { + log('Watching:', db, selector); + changes = db + .changes({ + since: 'now', + live: true, + selector + }) + .on('change', change => { + log('changed:', change); + subscribers.forEach(s => s(change.id, !!change.deleted)); + }) + .on('error', err => { + error(err); + subscribers.empty(); + }); + } + return () => { + this.subscribers.delete(fn); + if (subscribers.size === 0 && changes) { + log('Unwatching:', db, selector); + changes.cancel(); + changes = null; + } + }; + }; +}