File
Blob: src/worker/sites/load-page-pm-json.ts
| 1 | import type { JSONContent } from "@tiptap/core"; |
| 2 | |
| 3 | import type { EditorTextMetrics } from "@/shared/editor/schema/metrics"; |
| 4 | import type { ResolvedPublishedPage } from "@/worker/lib/published-pages"; |
| 5 | import { readSiteR2 } from "@/worker/sites/cache"; |
| 6 | |
| 7 | type SiteTiming = <T>(name: string, operation: () => Promise<T>) => Promise<T>; |
| 8 | |
| 9 | export interface LoadedPmJson { |
| 10 | content: JSONContent; |
| 11 | metrics: EditorTextMetrics; |
| 12 | stale: boolean; |
| 13 | artifactEtag: string; |
| 14 | artifactUpdatedAt: string; |
| 15 | } |
| 16 | |
| 17 | export interface LoadPagePmJsonArgs { |
| 18 | env: Pick<Env, "SITES">; |
| 19 | page: ResolvedPublishedPage; |
| 20 | timings?: SiteTiming; |
| 21 | } |
| 22 | |
| 23 | export async function loadPagePmJson({ env, page, timings }: LoadPagePmJsonArgs): Promise<LoadedPmJson | null> { |
| 24 | const r2 = await timeMaybe(timings, "r2_document", () => |
| 25 | readSiteR2(env, page.workspace_id, page.id, page.updated_at), |
| 26 | ); |
| 27 | if (!r2?.envelope) return null; |
| 28 | return { |
| 29 | content: r2.envelope.content, |
| 30 | metrics: r2.envelope.metrics, |
| 31 | stale: !r2.fresh, |
| 32 | artifactEtag: r2.etag, |
| 33 | artifactUpdatedAt: r2.envelope.updatedAt, |
| 34 | }; |
| 35 | } |
| 36 | |
| 37 | function timeMaybe<T>(timings: SiteTiming | undefined, name: string, operation: () => Promise<T>): Promise<T> { |
| 38 | return timings ? timings(name, operation) : operation(); |
| 39 | } |