success pt. 2
This commit is contained in:
@@ -6,34 +6,22 @@ import { animeTable } from "$lib/db/schema";
|
||||
import { db, overwriteDatabaseFile } from "./client-db";
|
||||
|
||||
/**
|
||||
* Client-side, read-only AMQ database access.
|
||||
* Client-side, read-only AMQ database helper.
|
||||
*
|
||||
* - Seeds SQLocal's managed database file from `static/data/amq.sqlite`
|
||||
* - Uses a version key so you control when clients refresh their local snapshot
|
||||
* - Exposes a small query helper to fetch a short anime list for display
|
||||
* Responsibilities:
|
||||
* - Seed SQLocal's managed DB file from `static/data/amq.sqlite` (served at `/data/amq.sqlite`)
|
||||
* - Gate the overwrite behind a manual version key (so you decide when clients refresh)
|
||||
* - Provide minimal query helpers for browsing
|
||||
*
|
||||
* Notes:
|
||||
* - This module MUST only be used in the browser. Guard with `browser`, or call
|
||||
* the exported functions from `onMount`.
|
||||
* - `overwriteDatabaseFile()` resets connections, so only call it when needed.
|
||||
* IMPORTANT:
|
||||
* - Call these functions only in the browser (e.g. from `onMount`)
|
||||
* - `overwriteDatabaseFile()` resets connections; don't call it repeatedly
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bump this when you ship a new `static/data/amq.sqlite`.
|
||||
* This is intentionally manual so you control when clients refresh.
|
||||
*/
|
||||
/** Bump when you ship a new `static/data/amq.sqlite`. */
|
||||
export const AMQ_DB_SEED_VERSION = 1;
|
||||
|
||||
/**
|
||||
* The file name SQLocal uses internally (you can change this; it does not need
|
||||
* to match the static seed file name).
|
||||
*/
|
||||
const SQLOCAL_DB_FILE_NAME = "amq.sqlite3";
|
||||
|
||||
/**
|
||||
* Where the shipped, static database lives.
|
||||
* `static/data/amq.sqlite` -> served at `/data/amq.sqlite`
|
||||
*/
|
||||
/** Static seed location. `static/data/amq.sqlite` -> `/data/amq.sqlite` */
|
||||
const SEED_ASSET_PATH = "/data/amq.sqlite";
|
||||
|
||||
const seededStorageKey = (version: number) => `amq.sqlocal.seeded.v${version}`;
|
||||
@@ -41,11 +29,8 @@ const seededStorageKey = (version: number) => `amq.sqlocal.seeded.v${version}`;
|
||||
let initPromise: Promise<void> | null = null;
|
||||
|
||||
function ensureBrowser() {
|
||||
if (!browser) {
|
||||
throw new Error(
|
||||
"Client AMQ DB can only be used in the browser (SSR is not supported).",
|
||||
);
|
||||
}
|
||||
if (!browser)
|
||||
throw new Error("Client AMQ DB can only be used in the browser.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,8 +134,8 @@ export async function getAnimeList(limit = 25): Promise<
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: basic text search by `mainName` (and optionally other columns).
|
||||
* This is deliberately small and safe for client-side browsing.
|
||||
* Helper: basic text search by `mainName`.
|
||||
* (Good enough for POC browsing; consider FTS5 later for better UX/perf.)
|
||||
*/
|
||||
export async function searchAnimeByName(
|
||||
query: string,
|
||||
@@ -165,13 +150,9 @@ export async function searchAnimeByName(
|
||||
if (!q) return [];
|
||||
|
||||
const safeLimit = Math.max(1, Math.min(200, Math.floor(limit)));
|
||||
|
||||
// Simple LIKE search. If you want better search later, consider FTS5 in the shipped snapshot.
|
||||
// Note: we don't escape %/_ here; if you need literal matching, we'll switch to a raw SQL
|
||||
// fragment with an explicit ESCAPE clause.
|
||||
const pattern = `%${q}%`;
|
||||
|
||||
const rows = await db
|
||||
return db
|
||||
.select({
|
||||
annId: animeTable.annId,
|
||||
mainName: animeTable.mainName,
|
||||
@@ -186,9 +167,4 @@ export async function searchAnimeByName(
|
||||
desc(animeTable.annId),
|
||||
)
|
||||
.limit(safeLimit);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
// Re-export for convenience in components that need to ensure seeding first.
|
||||
export { db, overwriteDatabaseFile, SQLOCAL_DB_FILE_NAME };
|
||||
|
||||
Reference in New Issue
Block a user