export type DELETE = 9; export type INSERT = 18; export type UPDATE = 23; export type UpdateType = DELETE | INSERT | UPDATE; export const UPDATE_TYPE: { readonly DELETE: DELETE; readonly INSERT: INSERT; readonly UPDATE: UPDATE; } = { DELETE: 9, INSERT: 18, UPDATE: 23, } as const; export type DBID = string & { readonly DBID: unique symbol; // this is the phantom type }; export type Schema = { namespace: string; name: string; active: boolean; content: string; }; export interface DB { readonly siteid: string; execMany(sql: string[]): void; exec(sql: string, bind?: unknown[]): void; execO(sql: string, bind?: unknown[]): T[]; execA(sql: string, bind?: unknown[]): T[]; close(): void; prepare(sql: string): Stmt; createFunction(name: string, fn: (...args: any) => unknown, opts?: {}): void; savepoint(cb: () => void): void; transaction(cb: () => void): void; onUpdate( cb: ( type: UpdateType, dbName: string, tblName: string, rowid: bigint ) => void ): () => void; } export type TMutex = { runExclusive(cb: () => Promise | T): Promise; acquire(): Promise<() => void>; release(): void; }; export interface TXAsync { readonly __mutex: TMutex; execMany(sql: string[]): Promise; exec(sql: string, bind?: unknown[]): Promise; execO(sql: string, bind?: unknown[]): Promise; execA(sql: string, bind?: unknown[]): Promise; prepare(sql: string): Promise; tx(cb: (tx: TXAsync) => Promise): Promise; imperativeTx(): Promise<[() => void, TXAsync]>; } export interface DBAsync extends TXAsync { readonly siteid: string; readonly filename: string; readonly tablesUsedStmt: StmtAsync; close(): Promise; onUpdate( cb: ( type: UpdateType, dbName: string, tblName: string, rowid: bigint ) => void ): () => void; createFunction(name: string, fn: (...args: any) => unknown, opts?: {}): void; automigrateTo( schemaName: string, schemaContent: string ): Promise<"noop" | "apply" | "migrate">; } export interface Stmt { run(...bindArgs: any[]): void; get(...bindArgs: any[]): any; all(...bindArgs: any[]): any[]; iterate(...bindArgs: any[]): Iterator; raw(isRaw?: boolean): this; bind(args: any[]): this; finalize(): void; } export interface StmtAsync { run(tx: TXAsync | null, ...bindArgs: any[]): Promise; get(tx: TXAsync | null, ...bindArgs: any[]): Promise; all(tx: TXAsync | null, ...bindArgs: any[]): Promise; iterate(tx: TXAsync | null, ...bindArgs: any[]): AsyncIterator; raw(isRaw?: boolean): this; bind(args: readonly any[]): this; finalize(tx: TXAsync | null): Promise; } export const version = 1; export function cryb64(str: string, seed: number = 0) { let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; for (let i = 0, ch; i < str.length; i++) { ch = str.charCodeAt(i); h1 = Math.imul(h1 ^ ch, 2654435761); h2 = Math.imul(h2 ^ ch, 1597334677); } h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); return 4294967296n * BigInt(h2) + BigInt(h1); } export function first(data: T[]): T | undefined { if (!data) { return undefined; } return data[0]; } export function firstPick(data: any[]): T | undefined { const d = data[0]; if (d == null) { return undefined; } return d[Object.keys(d)[0]]; } export function pick(data: T[]): R[] { return data.map((d: any) => d[Object.keys(d)[0] as any]); }