diigo-cache: SQL in .sql files, behind a read-only facet
No SQL text in the cache logic any more. Statements live in two files, parsed by sqlStatements (`-- name:` sections, as in finquick's brcal/gcbook.js) and imported as text (wrangler Text rule for *.sql): - cache-read.sql: selects only, checked when the module loads - cache-write.sql: schema, the v2 renumbering, etch, drops store.ts turns them into two frozen facets with domain methods: makeReader(sql) runs only the read statements (page, knownTotal, deepestPageSince, pagesThrough); makeWriter(storage) only the write ones (migrate, etch, dropPagesThrough), each change one transaction. The cache migrates in its constructor under blockConcurrencyWhile, as Cloudflare recommends, so readers never meet missing tables; the migration test plants v1 storage and evicts to get a fresh activation. A viewer() facet (PageViewer: stored pages and fill progress, from the reader alone) is added for the public page. Pure refactor: stored state and behavior unchanged. Generated-by: Claude Opus 5.5
This commit is contained in:
1 parent
6dd7a37532
commit
a17d287e1d
10 files changed
+275
-122
No files matched your search
@@ -133,19 +133,18 @@ describe("page numbering (schema v2)", () => {
|
||||
it("migrates v1 storage: a stored 'page n' was really page n+1, so it is renumbered, not refetched", async () => {
|
||||
const stub = testEnv.CACHE_DO.get(testEnv.CACHE_DO.newUniqueId());
|
||||
await stub.setup({ webappId: WEBAPP_ID });
|
||||
// the shape v1 left: tables, a page 1 holding what diigo's
|
||||
// page_num=1 returned (really page 2), and no schema marker
|
||||
// the shape v1 left: a page 1 holding what diigo's page_num=1
|
||||
// returned (really page 2), and no schema marker; then a fresh
|
||||
// activation, whose constructor migrates
|
||||
await runInDurableObject(stub, (_obj, state) => {
|
||||
const sql = state.storage.sql;
|
||||
sql.exec(`create table items (item_id text primary key, url text not null, title text not null,
|
||||
private integer not null, json text not null, updated text not null)`);
|
||||
sql.exec("create table pages (page_num integer primary key, count integer not null, total integer, etched_at text not null)");
|
||||
sql.exec("create table page_members (page_num integer not null, pos integer not null, item_id text not null, primary key (page_num, pos))");
|
||||
sql.exec("insert into items values ('a', 'https://a.example/', 'old page one, first', 0, '{\"title\":\"A\"}', '1')");
|
||||
sql.exec("insert into items values ('b', 'https://b.example/', 'old page one, second', 0, '{\"title\":\"B\"}', '1')");
|
||||
sql.exec("insert into pages values (1, 100, 250, '2026-10-07T00:00:00.000Z')");
|
||||
sql.exec("insert into page_members values (1, 1, 'a'), (1, 2, 'b')");
|
||||
state.storage.kv.delete("schema");
|
||||
});
|
||||
await evictDurableObject(stub);
|
||||
const before = await testEnv.WEBAPP.calls();
|
||||
const two = await stub.page(2, PAGE_SIZE);
|
||||
expect(two.cached).toBe(true);
|
||||
|
||||
Reference in new issue
Block a user