This commit is contained in:
2024-06-04 00:36:45 +00:00
commit 015e813bc4
22 changed files with 2715 additions and 0 deletions
+141
View File
@@ -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,
};
}