Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
87d5f42
docs: implementation plan for sponsors image router
Brooooooklyn Jul 6, 2026
7dd9e2c
feat(sponsors-image): theme tokens + parseTheme
Brooooooklyn Jul 6, 2026
8aee9da
feat(sponsors-image): base64-inline sponsor avatars
Brooooooklyn Jul 6, 2026
108d6a7
feat(sponsors-image): runtime Manrope font loader + vendored TTFs
Brooooooklyn Jul 6, 2026
65d27de
feat(sponsors-image): satori sponsor-wall card renderer
Brooooooklyn Jul 6, 2026
bec1cc8
feat(sponsors-image): resvg-wasm svg->png + add @resvg/resvg-wasm dep
Brooooooklyn Jul 6, 2026
42f0ada
feat(sponsors-image): render orchestrator (svg/png)
Brooooooklyn Jul 6, 2026
0c0a1d1
feat(sponsors-image): /sponsors.svg + /sponsors.png route handlers
Brooooooklyn Jul 6, 2026
097b993
fix(sponsors-image): avatar fetch timeout, cap backers before inlinin…
Brooooooklyn Jul 6, 2026
9476a74
Merge remote-tracking branch 'origin/main' into feat/sponsors-image-r…
Brooooooklyn Jul 6, 2026
3d329ae
fix(sponsors-image): satisfy tsc --noEmit (font weight type, ArrayBuf…
Brooooooklyn Jul 6, 2026
3cb4bca
fix(sponsors-image): cap avatar fetch concurrency (Workers 6-connecti…
Brooooooklyn Jul 6, 2026
7aae01e
docs: implementation plan for sponsors cache + webhook + cron
Brooooooklyn Jul 6, 2026
9d146fd
feat(sponsors-cache): enable KV + R2 bindings + webhook secret
Brooooooklyn Jul 6, 2026
d4d3b71
feat(sponsors-cache): GitHub webhook signature verification
Brooooooklyn Jul 6, 2026
bbc4e84
feat(sponsors-cache): KV manifest + R2 blob store
Brooooooklyn Jul 6, 2026
55a8429
feat(sponsors-cache): loadSponsors bypassCache option
Brooooooklyn Jul 6, 2026
057c736
docs: correct load-sponsors test env-seeding note (void/env uses glob…
Brooooooklyn Jul 6, 2026
1fe3dbb
feat(sponsors-cache): KV-first getCachedSponsors
Brooooooklyn Jul 6, 2026
bc7628c
feat(sponsors-cache): refresh pipeline (render 4 + snapshot, hash-skip)
Brooooooklyn Jul 6, 2026
7ddc42a
feat(sponsors-cache): daily cron + GitHub Sponsors webhook refresh
Brooooooklyn Jul 6, 2026
056edc6
feat(sponsors-cache): serve cached sponsor images + KV-first landing
Brooooooklyn Jul 6, 2026
eb30c2a
fix(sponsors-cache): preserve snapshot on degraded fetch + defensive …
Brooooooklyn Jul 6, 2026
d1cdc6f
fix(sponsors-cache): type hexToBytes return as Uint8Array<ArrayBuffer>
Brooooooklyn Jul 6, 2026
9d8a0b2
fix(sponsors-cache): cold-warm reuses rendered data, not a 2nd fetch
Brooooooklyn Jul 6, 2026
8ead569
fix(sponsors-cache): never publish a degraded empty snapshot (close T…
Brooooooklyn Jul 6, 2026
5fce43e
fix(sponsors-cache): CAS the manifest flip to prevent stale-refresh r…
Brooooooklyn Jul 6, 2026
caf3053
fix(sponsors-cache): stage image blobs off live keys + degrade on KV …
Brooooooklyn Jul 6, 2026
8ec4e81
fix(sponsors-cache): degrade to live render when the R2 read fails
Brooooooklyn Jul 6, 2026
a366f86
docs(sponsors-cache): document the accepted residual CAS window
Brooooooklyn Jul 6, 2026
abc0615
fix(sponsors-cache): render image cold miss from KV-first snapshot, n…
Brooooooklyn Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions crons/refresh-sponsors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// crons/refresh-sponsors.ts
// Daily full re-render of the sponsors cache (force) so avatar/name changes that
// never fire a sponsorship webhook are still picked up. 05:00 UTC = low traffic.
import { defineScheduled } from 'void'
import yogaWasm from 'satori/yoga.wasm'
import resvgWasm from '@resvg/resvg-wasm/index_bg.wasm'
import { loadSponsors } from '../lib/landing/load-sponsors.ts'
import {
loadFonts,
readAsset,
type AssetsFetcher,
} from '../lib/sponsors-image/fonts.ts'
import { refreshSponsorsCache } from '../lib/sponsors-cache/refresh.ts'
import type { KVStore, R2Store } from '../lib/sponsors-cache/store.ts'

export const cron = '0 5 * * *'

export default defineScheduled(async (_controller, env) => {
const e = env as unknown as {
KV: KVStore
STORAGE: R2Store
ASSETS: AssetsFetcher
}
// The scheduled context has no request URL; the ASSETS binding serves by path,
// so the host in the base URL is irrelevant — any absolute URL works.
const base = 'https://napi.rs/'
await refreshSponsorsCache({
kv: e.KV,
r2: e.STORAGE,
loadFresh: () => loadSponsors({ bypassCache: true }),
loadFonts: () => loadFonts((p) => readAsset(e.ASSETS, base, p)),
yogaWasm,
resvgWasm,
force: true,
})
})
1,458 changes: 1,458 additions & 0 deletions docs/superpowers/plans/2026-07-06-sponsors-cache-refresh.md

Large diffs are not rendered by default.

Loading
Loading