@constl/bohr-db
Version:
Type-safe databases for OrbitDB.
61 lines (55 loc) • 1.59 kB
text/typescript
import type { JSONSchemaType } from "ajv";
import type { FeedDatabaseType } from "@orbitdb/feed-db";
import type { DBElements } from "./types.ts";
import { generateListValidator, removeUndefinedProperties } from "./utils.ts";
export type TypedFeed<T extends DBElements> = Omit<
FeedDatabaseType,
"add" | "all"
> & {
add: (value: T) => Promise<string>;
all: () => Promise<
{
value: T;
hash: string;
}[]
>;
};
export const typedFeed = <T extends DBElements>({
db,
schema,
}: {
db: FeedDatabaseType;
schema: JSONSchemaType<T>;
}): TypedFeed<T> => {
const { validate } = generateListValidator(schema);
return new Proxy(db, {
get(target, prop) {
if (prop === "all") {
return async (): Promise<{ value: T; hash: string }[]> => {
const all = await target[prop]();
const valid = all.filter((x) => validate(x.value)) as {
value: T;
hash: string;
}[];
return valid;
};
} else if (prop === "add") {
return async (data: T): Promise<string> => {
if (typeof data === "object" && !Array.isArray(data)) {
data = removeUndefinedProperties(data) as T;
}
const valid = validate(data);
if (valid) {
return await target.add(data);
}
throw new Error(
JSON.stringify(data) +
JSON.stringify(validate.errors, undefined, 2),
);
};
} else {
return target[prop as keyof typeof target];
}
},
}) as TypedFeed<T>;
};