snapshot
This commit is contained in:
+141
@@ -0,0 +1,141 @@
|
||||
import { openDB, type IDBPDatabase } from "idb";
|
||||
import type { Readable } from "svelte/motion";
|
||||
import { readable, writable } from "svelte/store";
|
||||
|
||||
export interface IGalleryImage {
|
||||
id: IDBValidKey;
|
||||
when: Date;
|
||||
dataUrl: string;
|
||||
}
|
||||
|
||||
export interface IFetchGalleryImagesArgs {
|
||||
constraint?: IDBKeyRange;
|
||||
direction?: IDBCursorDirection;
|
||||
take?: number;
|
||||
skip?: number;
|
||||
}
|
||||
|
||||
export interface IFetchGalleryImagesPage {
|
||||
count: number;
|
||||
images: Array<IGalleryImage>;
|
||||
}
|
||||
|
||||
export interface IFetchGalleryImagesQuery {
|
||||
result: Readable<IFetchGalleryImagesPage>;
|
||||
|
||||
refresh() : Promise<void>;
|
||||
|
||||
setArgs(args: IFetchGalleryImagesArgs): void;
|
||||
}
|
||||
|
||||
export interface IGalleryDb {
|
||||
storeImage (image: Omit<IGalleryImage, 'id'>) : Promise<IDBValidKey>;
|
||||
|
||||
selectImages (index: string): IFetchGalleryImagesQuery;
|
||||
}
|
||||
|
||||
const storeName = "images";
|
||||
|
||||
export async function initGallery() {
|
||||
const updates = Array<CallableFunction>();
|
||||
|
||||
const db = await openDB("image-diary", 1, {
|
||||
upgrade(db) {
|
||||
const images = db.createObjectStore(storeName, { keyPath: "id", autoIncrement: true });
|
||||
|
||||
images.createIndex("ix_when", ["when"]);
|
||||
},
|
||||
});
|
||||
|
||||
const fnStoreImage = async (image: IGalleryImage) => {
|
||||
const tx = db.transaction(storeName, "readwrite");
|
||||
const id = await tx.objectStore(storeName).add(image);
|
||||
|
||||
await tx.done;
|
||||
|
||||
for (const update of updates) {
|
||||
update();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
const fnSelectImages = (index: string): IFetchGalleryImagesQuery => {
|
||||
var skip = 0;
|
||||
var take = 5;
|
||||
var direction: IDBCursorDirection = 'next';
|
||||
var constraint: IDBKeyRange | null = null;
|
||||
|
||||
const setters = new Array<(v: IFetchGalleryImagesPage) => void>();
|
||||
|
||||
const fnRefresh = async () => {
|
||||
if (setters.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// console.log('refresh', 'skip', skip, 'take', take, 'direction', direction, 'constraint', constraint);
|
||||
|
||||
const tx = db.transaction(storeName, "readonly");
|
||||
const store = tx.objectStore(storeName);
|
||||
const index = store.index("ix_when");
|
||||
|
||||
var shouldSkip = skip;
|
||||
var shouldTake = take;
|
||||
|
||||
var result = new Array<IGalleryImage>();
|
||||
|
||||
const count = await index.count();
|
||||
|
||||
for await (const cursor of index.iterate(constraint, direction)) {
|
||||
if (shouldSkip > 0) {
|
||||
cursor.advance(skip);
|
||||
|
||||
shouldSkip = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldTake > 0) {
|
||||
result.push(cursor.value);
|
||||
|
||||
shouldTake--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
for (const set of setters) {
|
||||
set({
|
||||
count: count,
|
||||
images: result
|
||||
});
|
||||
}
|
||||
|
||||
await tx.done;
|
||||
};
|
||||
|
||||
return {
|
||||
result: readable<IFetchGalleryImagesPage>({count: 0, images: []}, (set) => {
|
||||
setters.push(set);
|
||||
updates.push(fnRefresh);
|
||||
|
||||
return () => {
|
||||
setters.splice(setters.indexOf(set), 1);
|
||||
updates.splice(updates.indexOf(fnRefresh), 1);
|
||||
};
|
||||
}),
|
||||
refresh: fnRefresh,
|
||||
setArgs: (args) => {
|
||||
constraint = args.constraint ?? null;
|
||||
direction = args.direction ?? 'next';
|
||||
skip = args.skip ?? 0;
|
||||
take = args.take ?? 5;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
storeImage: fnStoreImage,
|
||||
selectImages: fnSelectImages,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user