import type { VaultPaths } from "./vault.js"; interface DatabaseHandle { exec(sql: string): unknown; prepare(sql: string): object; close(): void; } export type SqlValue = string | number | bigint | boolean | Uint8Array | null; export type SqlParameters = readonly unknown[] | Readonly>; export type SqlRow = Readonly>; export interface SqlRunResult { readonly changes: number | bigint; readonly lastInsertRowid: number | bigint; } export interface OpenDatabaseOptions { readonly readOnly?: boolean; readonly initializeSchema?: boolean; } export declare const SCHEMA_VERSION: 5; export declare const REQUIRED_TABLES: readonly ["schema_meta", "sources", "source_files", "source_chunks", "source_dependencies", "pages", "wiki_issues", "authored_snapshots", "page_learning", "page_prerequisites", "quizzes", "quiz_questions", "page_reviews", "question_pages", "quiz_answers", "question_results", "page_results", "quiz_evidence", "workflows", "settings"]; export declare const SCHEMA_SQL = "\nPRAGMA foreign_keys = ON;\n\nCREATE TABLE IF NOT EXISTS schema_meta (\n schema_version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS sources (\n source_id TEXT PRIMARY KEY,\n kind TEXT NOT NULL CHECK (kind IN ('document','url','text','note','code','directory','repository')),\n status TEXT NOT NULL CHECK (status IN ('pending','claimed','processing','published','failed','removed')),\n display_name TEXT NOT NULL,\n original_name TEXT,\n source_uri TEXT,\n media_type TEXT,\n repository_revision TEXT,\n captured_at TEXT,\n digest TEXT,\n manifest_digest TEXT,\n manifest_path TEXT,\n error_code TEXT,\n error_message TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS source_files (\n source_id TEXT NOT NULL REFERENCES sources(source_id) ON DELETE CASCADE,\n relative_path TEXT NOT NULL,\n byte_length INTEGER NOT NULL CHECK (byte_length >= 0),\n digest TEXT NOT NULL,\n media_type TEXT,\n PRIMARY KEY (source_id, relative_path)\n);\n\nCREATE TABLE IF NOT EXISTS source_chunks (\n chunk_id TEXT PRIMARY KEY,\n source_id TEXT NOT NULL REFERENCES sources(source_id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n relative_path TEXT NOT NULL,\n byte_length INTEGER NOT NULL CHECK (byte_length >= 0),\n digest TEXT NOT NULL,\n atom_start INTEGER NOT NULL CHECK (atom_start >= 0),\n atom_end INTEGER NOT NULL CHECK (atom_end >= atom_start),\n UNIQUE (source_id, ordinal),\n UNIQUE (source_id, chunk_id)\n);\n\nCREATE TABLE IF NOT EXISTS source_dependencies (\n source_id TEXT NOT NULL REFERENCES sources(source_id) ON DELETE RESTRICT,\n page_id TEXT REFERENCES pages(page_id) ON DELETE RESTRICT,\n chunk_id TEXT,\n relation TEXT NOT NULL CHECK (relation IN ('citation','claim','question')),\n CHECK (page_id IS NOT NULL OR chunk_id IS NOT NULL),\n FOREIGN KEY (source_id, chunk_id) REFERENCES source_chunks(source_id, chunk_id) ON DELETE RESTRICT,\n PRIMARY KEY (source_id, page_id, chunk_id, relation)\n);\n\nCREATE TABLE IF NOT EXISTS pages (\n page_id TEXT PRIMARY KEY,\n relative_path TEXT NOT NULL UNIQUE,\n title TEXT NOT NULL,\n digest TEXT NOT NULL,\n revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),\n status TEXT NOT NULL CHECK (status IN ('active','drifted','retired')),\n quiz_worthiness TEXT NOT NULL CHECK (quiz_worthiness IN ('eligible','skip','unknown')),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS wiki_issues (\n issue_id TEXT PRIMARY KEY,\n page_id TEXT REFERENCES pages(page_id) ON DELETE RESTRICT,\n heading TEXT,\n page_digest TEXT,\n kind TEXT NOT NULL CHECK (kind IN ('incorrect','unclear','missing','bad-boundary')),\n description TEXT NOT NULL,\n status TEXT NOT NULL CHECK (status IN ('open','resolved','reopened')),\n resolution TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS authored_snapshots (\n relative_path TEXT PRIMARY KEY,\n digest TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision > 0),\n captured_at TEXT NOT NULL,\n commit_id TEXT\n);\n\nCREATE TABLE IF NOT EXISTS page_learning (\n page_id TEXT PRIMARY KEY REFERENCES pages(page_id) ON DELETE RESTRICT,\n initial_due_at TEXT NOT NULL,\n due_at TEXT NOT NULL,\n fsrs_state INTEGER NOT NULL CHECK (fsrs_state BETWEEN 0 AND 3),\n stability REAL NOT NULL CHECK (stability >= 0),\n difficulty REAL NOT NULL CHECK (difficulty >= 0),\n reps INTEGER NOT NULL CHECK (reps >= 0),\n lapses INTEGER NOT NULL CHECK (lapses >= 0),\n scheduled_days INTEGER NOT NULL CHECK (scheduled_days >= 0),\n last_review_at TEXT,\n revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS page_prerequisites (\n page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE CASCADE,\n prerequisite_page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE RESTRICT,\n PRIMARY KEY (page_id, prerequisite_page_id),\n CHECK (page_id <> prerequisite_page_id)\n);\n\nCREATE TABLE IF NOT EXISTS quizzes (\n quiz_id TEXT PRIMARY KEY,\n date TEXT NOT NULL UNIQUE,\n revision INTEGER NOT NULL CHECK (revision > 0),\n status TEXT NOT NULL CHECK (status IN ('open','submitted','expired','skipped','failed')),\n sheet_path TEXT,\n generated_at TEXT,\n submitted_at TEXT,\n error_code TEXT,\n error_message TEXT\n);\n\nCREATE TABLE IF NOT EXISTS quiz_questions (\n question_id TEXT PRIMARY KEY,\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n kind TEXT NOT NULL CHECK (kind IN ('free-response','multiple-choice')),\n prompt TEXT NOT NULL,\n choices_json TEXT,\n answer_key_json TEXT,\n source_refs_json TEXT NOT NULL,\n UNIQUE (quiz_id, ordinal)\n);\nCREATE TABLE IF NOT EXISTS page_reviews (\n review_id TEXT PRIMARY KEY,\n page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE RESTRICT,\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE RESTRICT,\n submission_id TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n rating TEXT NOT NULL CHECK (rating IN ('Again','Hard','Good','Easy')),\n reviewed_at TEXT NOT NULL,\n state_before_json TEXT NOT NULL,\n state_after_json TEXT NOT NULL,\n settlement_id TEXT NOT NULL,\n UNIQUE (quiz_id, page_id, revision),\n UNIQUE (settlement_id, page_id)\n);\n\nCREATE TABLE IF NOT EXISTS question_pages (\n question_id TEXT NOT NULL REFERENCES quiz_questions(question_id) ON DELETE CASCADE,\n page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE RESTRICT,\n criterion_json TEXT NOT NULL,\n weight REAL NOT NULL CHECK (weight > 0),\n PRIMARY KEY (question_id, page_id)\n);\n\nCREATE TABLE IF NOT EXISTS quiz_answers (\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE CASCADE,\n question_id TEXT NOT NULL REFERENCES quiz_questions(question_id) ON DELETE CASCADE,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n answer_json TEXT NOT NULL,\n saved_at TEXT NOT NULL,\n PRIMARY KEY (quiz_id, question_id),\n UNIQUE (quiz_id, question_id, revision)\n);\n\nCREATE TABLE IF NOT EXISTS question_results (\n result_id TEXT PRIMARY KEY,\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE RESTRICT,\n question_id TEXT NOT NULL REFERENCES quiz_questions(question_id) ON DELETE RESTRICT,\n answer_revision INTEGER NOT NULL CHECK (answer_revision >= 0),\n feedback TEXT NOT NULL,\n graded_at TEXT NOT NULL,\n UNIQUE (quiz_id, question_id, answer_revision)\n);\n\nCREATE TABLE IF NOT EXISTS page_results (\n result_id TEXT PRIMARY KEY,\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE RESTRICT,\n page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE RESTRICT,\n rating TEXT NOT NULL CHECK (rating IN ('Again','Hard','Good','Easy')),\n feedback TEXT NOT NULL,\n evidence_json TEXT NOT NULL,\n readings_json TEXT NOT NULL,\n review_id TEXT NOT NULL REFERENCES page_reviews(review_id) ON DELETE RESTRICT,\n UNIQUE (quiz_id, page_id),\n UNIQUE (review_id)\n);\n\nCREATE TABLE IF NOT EXISTS quiz_evidence (\n quiz_id TEXT NOT NULL REFERENCES quizzes(quiz_id) ON DELETE CASCADE,\n reference TEXT NOT NULL,\n page_id TEXT NOT NULL REFERENCES pages(page_id) ON DELETE RESTRICT,\n relative_path TEXT NOT NULL,\n anchor TEXT NOT NULL,\n heading TEXT,\n page_digest TEXT NOT NULL,\n page_revision INTEGER NOT NULL CHECK (page_revision > 0),\n text_digest TEXT NOT NULL,\n excerpt TEXT NOT NULL,\n excerpt_digest TEXT NOT NULL,\n PRIMARY KEY (quiz_id, reference)\n);\n\nCREATE TABLE IF NOT EXISTS workflows (\n request_id TEXT PRIMARY KEY,\n kind TEXT NOT NULL CHECK (kind IN ('extract','ingest','lint','daily','quiz-grader','sync')),\n status TEXT NOT NULL CHECK (status IN ('queued','running','succeeded','failed','cancelled')),\n started_at TEXT,\n finished_at TEXT,\n progress REAL NOT NULL DEFAULT 0 CHECK (progress >= 0 AND progress <= 1),\n message TEXT,\n error_code TEXT,\n error_message TEXT,\n idempotency_key TEXT UNIQUE\n);\n\nCREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value_json TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n"; export declare class ScholarDatabase { #private; readonly path: string; constructor(path: string, database: DatabaseHandle); exec(sql: string): void; run(sql: string, parameters?: SqlParameters): SqlRunResult; get(sql: string, parameters?: SqlParameters): T | undefined; all(sql: string, parameters?: SqlParameters): T[]; checkpoint(): void; integrityCheck(): string[]; tableNames(): string[]; close(): void; get transactionDepth(): number; _beginTransaction(): string | undefined; _commitTransaction(savepoint: string | undefined): void; _rollbackTransaction(savepoint: string | undefined): void; } export declare function validateSchema(db: ScholarDatabase): void; export declare function openDatabase(input: string | VaultPaths, options?: OpenDatabaseOptions): ScholarDatabase; export declare function transaction(db: ScholarDatabase, operation: () => T): T; export {}; //# sourceMappingURL=database.d.ts.map