Skip to content

Commit 3b87be0

Browse files
committed
Merge branch 'main' into add-cache-handlers
2 parents f08e88b + 5f99235 commit 3b87be0

16 files changed

Lines changed: 436 additions & 488 deletions

File tree

.changeset/README.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
# Changesets
22

3-
Hello and welcome! This folder has been automatically generated by
4-
`@changesets/cli`, a build tool that works with multi-package repos, or
5-
single-package repos to help you version and publish your code. You can find the
6-
full documentation for it
7-
[in our repository](https://github.com/changesets/changesets)
3+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
84

9-
We have a quick list of common questions to get you started engaging with this
10-
project in
11-
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
5+
We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

.prettierignore

Lines changed: 0 additions & 4 deletions
This file was deleted.

.prettierrc

Lines changed: 0 additions & 3 deletions
This file was deleted.

.vscode/settings.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"typescript.tsdk": "node_modules/typescript/lib",
3-
"deno.enablePaths": [
4-
"packages/cache-handlers/"
5-
],
3+
"deno.enable": true,
64
"deno.config": "./deno.json",
75
"deno.suggest.imports.hosts": {
86
"https://deno.land": true,
@@ -13,5 +11,9 @@
1311
},
1412
"[javascript]": {
1513
"editor.defaultFormatter": "denoland.vscode-deno"
16-
}
14+
},
15+
"prettier.enable": false,
16+
"deno.enablePaths": [
17+
"packages"
18+
]
1719
}

CLAUDE.md

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
# CLAUDE.md
22

3-
This file provides guidance to Claude Code (claude.ai/code) when working with
4-
code in this repository.
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
54

65
## Repository Structure
76

87
This is a monorepo for CDN cache control libraries using pnpm workspaces:
98

109
- **Root**: Workspace configuration and shared tooling
1110
- **packages/**: Individual library packages
12-
- `cdn-cache-control`: Easy, opinionated CDN cache header handling (TypeScript
13-
class-based API)
14-
- `cache-handlers`: Modern CDN cache primitives using web-standard middleware
15-
(functional API)
11+
- `cdn-cache-control`: Easy, opinionated CDN cache header handling (TypeScript class-based API)
12+
- `cache-handlers`: Modern CDN cache primitives using web-standard middleware (functional API)
1613

1714
## Commands
1815

1916
### Root-level commands (run from repository root):
2017

2118
- `pnpm build` - Build all packages
22-
- `pnpm test` - Run tests for all packages (includes Deno, Node.js, and Workerd
23-
tests)
19+
- `pnpm test` - Run tests for all packages (includes Deno, Node.js, and Workerd tests)
2420
- `pnpm check` - Run type checking and linting for all packages
2521
- `pnpm lint` - Run linting for all packages
2622
- `pnpm format` - Format code using Prettier
@@ -41,8 +37,7 @@ This is a monorepo for CDN cache control libraries using pnpm workspaces:
4137
## Development Workflow
4238

4339
- Uses **pnpm** as package manager
44-
- **tsdown** for building TypeScript packages with ESM output and declaration
45-
files
40+
- **tsdown** for building TypeScript packages with ESM output and declaration files
4641
- **deno** for testing
4742
- **publint** and **@arethetypeswrong/cli** for package validation
4843
- **Prettier** for code formatting (configured to use tabs in `.prettierrc`)
@@ -65,8 +60,7 @@ This is a monorepo for CDN cache control libraries using pnpm workspaces:
6560
- HTTP conditional requests (ETag, Last-Modified, 304 responses)
6661
- Cache invalidation by tags and paths
6762
- Multi-runtime support (Deno, Node.js, Cloudflare Workers)
68-
- **Testing**: Multi-runtime (Deno tests, Node.js via Vitest, Workerd via
69-
Vitest)
63+
- **Testing**: Multi-runtime (Deno tests, Node.js via Vitest, Workerd via Vitest)
7064
- **Build**: ESM-only output
7165

7266
Each package follows this structure:
@@ -82,22 +76,15 @@ Uses strict TypeScript configuration with:
8276

8377
- Target: ES2022
8478
- Module: preserve (for bundler compatibility)
85-
- Strict mode with additional safety checks (`noUncheckedIndexedAccess`,
86-
`noImplicitOverride`)
79+
- Strict mode with additional safety checks (`noUncheckedIndexedAccess`, `noImplicitOverride`)
8780
- Library-focused settings (declaration files, declaration maps)
8881

8982
## Use Specialized Agents for Complex Tasks
9083

9184
ALWAYS use the appropriate specialized agents for complex work:
9285

93-
- **technical-architect**: For designing system architecture, evaluating
94-
technical approaches, planning major features
95-
- **code-reviewer**: For comprehensive code review after implementing
96-
significant code changes
97-
- **test-engineer**: For analyzing test failures, creating new tests, and
98-
enhancing test coverage. Should NOT fix application code - only
99-
creates/updates test files
100-
- **docs-author**: For creating or updating documentation, READMEs, changesets,
101-
or PR descriptions
102-
- **package-installer**: For installing npm packages with proper dependency
103-
management
86+
- **technical-architect**: For designing system architecture, evaluating technical approaches, planning major features
87+
- **code-reviewer**: For comprehensive code review after implementing significant code changes
88+
- **test-engineer**: For analyzing test failures, creating new tests, and enhancing test coverage. Should NOT fix application code - only creates/updates test files
89+
- **docs-author**: For creating or updating documentation, READMEs, changesets, or PR descriptions
90+
- **package-installer**: For installing npm packages with proper dependency management

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# cache-primitives
22

3-
This repository is a monorepo containing several packages related to CDN cache
4-
control.
3+
This repository is a monorepo containing several packages related to CDN cache control.
54

65
## Packages
76

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"useTabs": true,
88
"useBraces": "always",
99
"singleBodyPosition": "nextLine",
10+
"proseWrap": "never",
1011
"exclude": [
1112
"**/*/package.json",
1213
"pnpm-lock.yaml",

packages/cache-handlers/README.md

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
# cache-handlers
22

3-
Unified, modern HTTP caching + invalidation + conditional requests built
4-
directly on standard Web APIs (`Request`, `Response`, `CacheStorage`). One small
5-
API: `createCacheHandler` – works on Cloudflare Workers, Netlify Edge, Deno,
6-
workerd, and Node 20+ (with Undici polyfills).
3+
Unified, modern HTTP caching + invalidation + conditional requests built directly on standard Web APIs (`Request`, `Response`, `CacheStorage`). One small API: `createCacheHandler` – works on Cloudflare Workers, Netlify Edge, Deno, workerd, and Node 20+ (with Undici polyfills).
74

85
## Highlights
96

10-
- Single handler: read -> serve (fresh/stale) -> optional background revalidate
11-
(SWR) -> write
12-
- Uses only standard headers for core caching logic: `Cache-Control` (+
13-
`stale-while-revalidate`), `CDN-Cache-Control`, `Cache-Tag`, `Vary`, `ETag`,
14-
`Last-Modified`
15-
- Optional custom extension header: `Cache-Vary` (library-defined – lets your
16-
backend declare specific header/cookie/query components for key derivation
17-
without bloating the standard `Vary` header)
7+
- Single handler: read -> serve (fresh/stale) -> optional background revalidate (SWR) -> write
8+
- Uses only standard headers for core caching logic: `Cache-Control` (+ `stale-while-revalidate`), `CDN-Cache-Control`, `Cache-Tag`, `Vary`, `ETag`, `Last-Modified`
9+
- Optional custom extension header: `Cache-Vary` (library-defined – lets your backend declare specific header/cookie/query components for key derivation without bloating the standard `Vary` header)
1810
- Stale-While-Revalidate implemented purely via directives (no custom headers)
19-
- Tag & path invalidation helpers (`invalidateByTag`, `invalidateByPath`,
20-
`invalidateAll` + stats)
11+
- Tag & path invalidation helpers (`invalidateByTag`, `invalidateByPath`, `invalidateAll` + stats)
2112
- Optional automatic ETag generation & conditional 304 responses
2213
- Backend-driven Vary via custom `Cache-Vary` (header= / cookie= / query=)
2314
- Zero runtime dependencies, ESM only, fully typed
@@ -63,15 +54,12 @@ addEventListener("fetch", (event: FetchEvent) => {
6354
1. Request arrives; cache checked (GET only is cached)
6455
2. Miss -> `handler` runs, response cached
6556
3. Hit & still fresh -> served instantly
66-
4. Expired but inside `stale-while-revalidate` window -> stale response served,
67-
background revalidation queued
68-
5. Conditional client request (If-None-Match / If-Modified-Since) may yield a
69-
304
57+
4. Expired but inside `stale-while-revalidate` window -> stale response served, background revalidation queued
58+
5. Conditional client request (If-None-Match / If-Modified-Since) may yield a 304
7059

7160
## Node 20+ Usage (Undici Polyfill)
7261

73-
Node 20 ships `fetch` et al, but _not_ `caches` yet. Use `undici` to polyfill
74-
CacheStorage.
62+
Node 20 ships `fetch` et al, but _not_ `caches` yet. Use `undici` to polyfill CacheStorage.
7563

7664
```ts
7765
import { createServer } from "node:http";
@@ -146,9 +134,7 @@ Just send the directive in your upstream response:
146134
Cache-Control: public, max-age=30, stale-while-revalidate=300
147135
```
148136

149-
No custom headers are added. While inside the SWR window the _stale_ cached
150-
response is returned immediately and a background revalidation run is triggered
151-
(if a `handler` was supplied).
137+
No custom headers are added. While inside the SWR window the _stale_ cached response is returned immediately and a background revalidation run is triggered (if a `handler` was supplied).
152138

153139
To use a runtime scheduler (eg Workers' `event.waitUntil`):
154140

@@ -245,21 +231,15 @@ if (validation.shouldReturn304) {
245231

246232
## Backend-Driven Variations (`Cache-Vary` – custom header)
247233

248-
`Cache-Vary` is a _non-standard_, library-specific response header. It augments
249-
the standard `Vary` mechanism by letting you list only the precise components
250-
you want included in the cache key (headers, cookies, query params) without
251-
emitting a large `Vary` header externally. The library consumes & strips it when
252-
constructing the internal key.
234+
`Cache-Vary` is a _non-standard_, library-specific response header. It augments the standard `Vary` mechanism by letting you list only the precise components you want included in the cache key (headers, cookies, query params) without emitting a large `Vary` header externally. The library consumes & strips it when constructing the internal key.
253235

254236
Add selective vary dimensions without inflating the standard `Vary` header:
255237

256238
```http
257239
Cache-Vary: header=Accept-Language, cookie=session_id, query=version
258240
```
259241

260-
Each listed dimension becomes part of the derived cache key. Standard `Vary`
261-
remains fully respected; `Cache-Vary` is additive and internal – safe to use
262-
even if unknown to intermediaries.
242+
Each listed dimension becomes part of the derived cache key. Standard `Vary` remains fully respected; `Cache-Vary` is additive and internal – safe to use even if unknown to intermediaries.
263243

264244
## Types
265245

packages/cdn-cache-control/README.md

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ export default async function handler(req: Request) => {
9595
});
9696
return new Response("Purged!", { status: 202 })
9797
};
98-
9998
```
10099

101100
#### Using the generated headers
@@ -106,9 +105,9 @@ The headers object can be used anywhere that accepts a `fetch` `Headers` object.
106105
import { CacheHeaders } from "cdn-cache-control";
107106

108107
export default async function handler(request: Request): Promise<Response> {
109-
const headers = new CacheHeaders().swr();
110-
// The `Response` constructor accepts the object directly
111-
return new Response("Hello", { headers });
108+
const headers = new CacheHeaders().swr();
109+
// The `Response` constructor accepts the object directly
110+
return new Response("Hello", { headers });
112111
}
113112
```
114113

@@ -120,7 +119,6 @@ import { CacheHeaders, ONE_HOUR } from "cdn-cache-control";
120119
121120
new CacheHeaders().swr(ONE_HOUR).copyTo(Astro.response.headers);
122121
---
123-
124122
```
125123

126124
## API
@@ -181,32 +179,32 @@ Number of seconds in one year
181179

182180
- [Installation](#installation)
183181
- [Usage](#usage)
184-
- [Use cases](#use-cases)
185-
- [stale-while-revalidate](#stale-while-revalidate)
186-
- [Immutable content](#immutable-content)
187-
- [Cache tags](#cache-tags)
188-
- [Using the generated headers](#using-the-generated-headers)
182+
- [Use cases](#use-cases)
183+
- [stale-while-revalidate](#stale-while-revalidate)
184+
- [Immutable content](#immutable-content)
185+
- [Cache tags](#cache-tags)
186+
- [Using the generated headers](#using-the-generated-headers)
189187
- [API](#api)
190188
- [:wrench: Constants](#wrench-constants)
191-
- [:gear: ONE\_MINUTE](#gear-one_minute)
192-
- [:gear: ONE\_HOUR](#gear-one_hour)
193-
- [:gear: ONE\_DAY](#gear-one_day)
194-
- [:gear: ONE\_WEEK](#gear-one_week)
195-
- [:gear: ONE\_YEAR](#gear-one_year)
189+
- [:gear: ONE\_MINUTE](#gear-one_minute)
190+
- [:gear: ONE\_HOUR](#gear-one_hour)
191+
- [:gear: ONE\_DAY](#gear-one_day)
192+
- [:gear: ONE\_WEEK](#gear-one_week)
193+
- [:gear: ONE\_YEAR](#gear-one_year)
196194
- [:factory: CacheHeaders](#factory-cacheheaders)
197-
- [Methods](#methods)
198-
- [:gear: tag](#gear-tag)
199-
- [:gear: swr](#gear-swr)
200-
- [:gear: immutable](#gear-immutable)
201-
- [:gear: ttl](#gear-ttl)
202-
- [:gear: toObject](#gear-toobject)
203-
- [:gear: copyTo](#gear-copyto)
204-
- [:gear: getCdnCacheControl](#gear-getcdncachecontrol)
205-
- [:gear: setCdnCacheControl](#gear-setcdncachecontrol)
206-
- [:gear: getCacheControl](#gear-getcachecontrol)
207-
- [:gear: setCacheControl](#gear-setcachecontrol)
208-
- [:gear: getCacheTags](#gear-getcachetags)
209-
- [:gear: setCacheTags](#gear-setcachetags)
195+
- [Methods](#methods)
196+
- [:gear: tag](#gear-tag)
197+
- [:gear: swr](#gear-swr)
198+
- [:gear: immutable](#gear-immutable)
199+
- [:gear: ttl](#gear-ttl)
200+
- [:gear: toObject](#gear-toobject)
201+
- [:gear: copyTo](#gear-copyto)
202+
- [:gear: getCdnCacheControl](#gear-getcdncachecontrol)
203+
- [:gear: setCdnCacheControl](#gear-setcdncachecontrol)
204+
- [:gear: getCacheControl](#gear-getcachecontrol)
205+
- [:gear: setCacheControl](#gear-setcachecontrol)
206+
- [:gear: getCacheTags](#gear-getcachetags)
207+
- [:gear: setCacheTags](#gear-setcachetags)
210208

211209
#### :gear: tag
212210

@@ -222,8 +220,7 @@ Parameters:
222220

223221
#### :gear: swr
224222

225-
Sets stale-while-revalidate directive for the CDN cache. By default the browser is sent a must-revalidate
226-
directive to ensure that the browser always revalidates the cache with the server.
223+
Sets stale-while-revalidate directive for the CDN cache. By default the browser is sent a must-revalidate directive to ensure that the browser always revalidates the cache with the server.
227224

228225
| Method | Type |
229226
| ------ | -------------------------- |
@@ -235,10 +232,7 @@ Parameters:
235232

236233
#### :gear: immutable
237234

238-
Sets cache headers for content that should be cached for a long time and never revalidated.
239-
The CDN cache will cache the content for the specified time, and the browser will cache the content
240-
indefinitely without revalidating. Do not use this unless the URL is fingerprinted or otherwise unique.
241-
Otherwise, the browser will cache the content indefinitely and never check for updates, including for new deploys.
235+
Sets cache headers for content that should be cached for a long time and never revalidated. The CDN cache will cache the content for the specified time, and the browser will cache the content indefinitely without revalidating. Do not use this unless the URL is fingerprinted or otherwise unique. Otherwise, the browser will cache the content indefinitely and never check for updates, including for new deploys.
242236

243237
| Method | Type |
244238
| ----------- | -------------------------- |
@@ -250,9 +244,7 @@ Parameters:
250244

251245
#### :gear: ttl
252246

253-
Sets the s-maxage for items in the CDN cache. This is the maximum amount of time that the CDN will cache the content.
254-
If used with swr, the content will revalidate in the background after the max age has passed. Otherwise, the content will be
255-
removed from the cache after the max age has passed.
247+
Sets the s-maxage for items in the CDN cache. This is the maximum amount of time that the CDN will cache the content. If used with swr, the content will revalidate in the background after the max age has passed. Otherwise, the content will be removed from the cache after the max age has passed.
256248

257249
| Method | Type |
258250
| ------ | ------------------------- |
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
2-
"name": "@ascorbic/cdn-cache-control",
3-
"version": "1.3.1",
4-
"exports": "./src/index.ts",
5-
"license": "MIT",
6-
"publish": {
7-
"include": ["README.md", "src/index.ts"]
8-
}
2+
"name": "@ascorbic/cdn-cache-control",
3+
"version": "1.3.1",
4+
"exports": "./src/index.ts",
5+
"license": "MIT",
6+
"publish": {
7+
"include": ["README.md", "src/index.ts"]
8+
}
99
}

0 commit comments

Comments
 (0)