7c825348b2
* Query regen * Fix anchor completion * Dependency fixes * Changelog update
85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
import type { FileMeta } from "../types.ts";
|
|
import type { SpacePrimitives } from "./space_primitives.ts";
|
|
import Dexie, { Table } from "dexie";
|
|
import { mime } from "../deps.ts";
|
|
|
|
export type FileContent = {
|
|
name: string;
|
|
meta: FileMeta;
|
|
data: Uint8Array;
|
|
};
|
|
|
|
export class IndexedDBSpacePrimitives implements SpacePrimitives {
|
|
private db: Dexie;
|
|
filesMetaTable: Table<FileMeta, string>;
|
|
filesContentTable: Table<FileContent, string>;
|
|
|
|
constructor(
|
|
dbName: string,
|
|
indexedDB?: any,
|
|
) {
|
|
this.db = new Dexie(dbName, {
|
|
indexedDB,
|
|
});
|
|
this.db.version(1).stores({
|
|
fileMeta: "name",
|
|
fileContent: "name",
|
|
});
|
|
this.filesMetaTable = this.db.table("fileMeta");
|
|
this.filesContentTable = this.db.table<FileContent, string>("fileContent");
|
|
}
|
|
|
|
fetchFileList(): Promise<FileMeta[]> {
|
|
return this.filesMetaTable.toArray();
|
|
}
|
|
|
|
async readFile(
|
|
name: string,
|
|
): Promise<{ data: Uint8Array; meta: FileMeta }> {
|
|
const fileContent = await this.filesContentTable.get(name);
|
|
if (!fileContent) {
|
|
throw new Error("Not found");
|
|
}
|
|
|
|
return {
|
|
data: fileContent.data,
|
|
meta: fileContent.meta,
|
|
};
|
|
}
|
|
|
|
async writeFile(
|
|
name: string,
|
|
data: Uint8Array,
|
|
_selfUpdate?: boolean,
|
|
suggestedMeta?: FileMeta,
|
|
): Promise<FileMeta> {
|
|
const meta: FileMeta = {
|
|
name,
|
|
lastModified: suggestedMeta?.lastModified || Date.now(),
|
|
contentType: mime.getType(name) || "application/octet-stream",
|
|
size: data.byteLength,
|
|
perm: suggestedMeta?.perm || "rw",
|
|
};
|
|
await this.filesContentTable.put({ name, data, meta });
|
|
await this.filesMetaTable.put(meta);
|
|
return meta;
|
|
}
|
|
|
|
async deleteFile(name: string): Promise<void> {
|
|
const fileMeta = await this.filesMetaTable.get(name);
|
|
if (!fileMeta) {
|
|
throw new Error("Not found");
|
|
}
|
|
await this.filesMetaTable.delete(name);
|
|
await this.filesContentTable.delete(name);
|
|
}
|
|
|
|
async getFileMeta(name: string): Promise<FileMeta> {
|
|
const fileMeta = await this.filesMetaTable.get(name);
|
|
if (!fileMeta) {
|
|
throw new Error("Not found");
|
|
}
|
|
return fileMeta;
|
|
}
|
|
}
|