File
Blob: src/worker/lib/site-invalidation.ts
| 1 | import { and, eq, inArray, ne } from "drizzle-orm"; |
| 2 | |
| 3 | import type { Db } from "@/worker/db/d1/client"; |
| 4 | import { pages, workspaceSites } from "@/worker/db/d1/schema"; |
| 5 | |
| 6 | export function siteRevisionTimestamp(now: Date = new Date()): string { |
| 7 | return now.toISOString(); |
| 8 | } |
| 9 | |
| 10 | export async function bumpPublicSiteRevision( |
| 11 | db: Db, |
| 12 | workspaceId: string, |
| 13 | updatedAt = siteRevisionTimestamp(), |
| 14 | ): Promise<void> { |
| 15 | await db.update(workspaceSites).set({ updated_at: updatedAt }).where(eq(workspaceSites.workspace_id, workspaceId)); |
| 16 | } |
| 17 | |
| 18 | export async function updatePublicSiteSettingsWithRevision( |
| 19 | db: Db, |
| 20 | workspaceId: string, |
| 21 | values: Record<string, unknown>, |
| 22 | updatedAt = siteRevisionTimestamp(), |
| 23 | ): Promise<void> { |
| 24 | await db |
| 25 | .update(workspaceSites) |
| 26 | .set({ ...values, updated_at: updatedAt }) |
| 27 | .where(eq(workspaceSites.workspace_id, workspaceId)); |
| 28 | } |
| 29 | |
| 30 | /** |
| 31 | * DocSync stores the document body in its Durable Object. D1 mirrors the title |
| 32 | * and the page save timestamp used by Sites R2/HTML cache freshness. |
| 33 | */ |
| 34 | export async function recordDocSyncPageSave( |
| 35 | db: Db, |
| 36 | pageId: string, |
| 37 | title: string, |
| 38 | updatedAt = siteRevisionTimestamp(), |
| 39 | ): Promise<void> { |
| 40 | await db.batch([ |
| 41 | db |
| 42 | .update(workspaceSites) |
| 43 | .set({ updated_at: updatedAt }) |
| 44 | .where( |
| 45 | inArray( |
| 46 | workspaceSites.workspace_id, |
| 47 | db |
| 48 | .select({ workspaceId: pages.workspace_id }) |
| 49 | .from(pages) |
| 50 | .where(and(eq(pages.id, pageId), ne(pages.title, title))), |
| 51 | ), |
| 52 | ), |
| 53 | db.update(pages).set({ title, updated_at: updatedAt }).where(eq(pages.id, pageId)), |
| 54 | ]); |
| 55 | } |