Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
38 changes: 26 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ jobs:
pull-requests: write # Grant write access to pull request comments
strategy:
matrix:
next-test-app:
- next-app-15-0-3
- next-app-15-3-2
- next-app-15-4-7
- next-app-16-0-3
- next-app-16-1-1
include:
- next-test-app: next-app-15-0-3
run-cache-components: false
- next-test-app: next-app-15-3-2
run-cache-components: false
- next-test-app: next-app-15-4-7
run-cache-components: false
- next-test-app: next-app-16-0-3
run-cache-components: true

steps:
- name: Checkout code
Expand Down Expand Up @@ -78,18 +81,29 @@ jobs:
SKIP_BUILD: true
NEXT_TEST_APP: ${{ matrix.next-test-app }}

- name: Install Playwright browsers (Next 16 only)
if: startsWith(matrix.next-test-app, 'next-app-16')
- name: Install Cache Components Integration Test Project
if: matrix.run-cache-components
run: cd test/integration/next-app-16-1-1-cache-components && pnpm install

- name: Build Cache Components Integration Test Project
if: matrix.run-cache-components
run: cd test/integration/next-app-16-1-1-cache-components && pnpm build

- name: Run Cache Components integration tests
if: matrix.run-cache-components
run: pnpm test:cache-components

- name: Install Playwright browsers
if: matrix.run-cache-components
run: pnpm exec playwright install --with-deps

- name: Run Playwright E2E tests (Next 16 only)
if: startsWith(matrix.next-test-app, 'next-app-16')
- name: Run Playwright E2E tests
if: matrix.run-cache-components
run: pnpm test:e2e
env:
PLAYWRIGHT_BASE_URL: http://localhost:3055
PLAYWRIGHT_BASE_URL: http://localhost:3101

- name: Code Coverage Comments
# only run for pull requests from this repository - so no problems for external PRs
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
uses: kcjpop/coverage-comments@v2.2
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ coverage
.idea
debug
.last-run.json

/.next/
**/.next/
11 changes: 0 additions & 11 deletions .next/trace

This file was deleted.

94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ To run all tests you can use the following command:
pnpm build && pnpm test
```

Folder layout / runners:

- **Vitest** (unit + integration) lives in `src/**/*.test.ts(x)` and `test/**`.
- **Playwright** (E2E) lives in `tests/**` (see `playwright.config.ts`).
- `test/browser/**` contains Vitest tests that hit a running Next.js app over HTTP. Despite the folder name, this is not Playwright and does not use Vitest browser mode.

### Unit tests

To run unit tests you can use the following command:
Expand All @@ -231,6 +237,14 @@ To run integration tests you can use the following command:
pnpm build && pnpm test:integration
```

### E2E tests (Playwright)

To run Playwright tests (`tests/**`) you can use:

```bash
pnpm test:e2e
```

The integration tests will start a Next.js server and test the caching handler. You can modify testing behavior by setting the following environment variables:

- SKIP_BUILD: If set to true, the integration tests will not build the Next.js app. Therefore the nextjs app needs to be built before running the tests. Or you execute the test once without skip build and the re-execute `pnpm test:integration` with skip build set to true.
Expand All @@ -239,6 +253,86 @@ The integration tests will start a Next.js server and test the caching handler.

Integration tests may have dependencies between test cases, so individual test failures should be evaluated in the context of the full test suite rather than in isolation.

## Cache Components handler (Next.js 16+)

This package can be used as a Cache Components handler (Node.js runtime) for Next.js apps that enable Cache Components.

### Enable Cache Components + cache handler

Install the package in your Next.js app:

```bash
pnpm add @trieb.work/nextjs-turbo-redis-cache redis
```

In your Next.js app, enable Cache Components and point `cacheHandlers.default` to a module that exports the handler instance:

```ts
// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
cacheComponents: true,
cacheHandlers: {
default: require.resolve('./cache-handler.js'),
},
};

export default nextConfig;
```

```js
// cache-handler.js
const { redisCacheHandler } = require('@trieb.work/nextjs-turbo-redis-cache');

module.exports = redisCacheHandler;
```

If you prefer ESM:

```js
// cache-handler.js
import { redisCacheHandler } from '@trieb.work/nextjs-turbo-redis-cache';

export default redisCacheHandler;
```

### Required environment variables

- `REDIS_URL` (recommended): e.g. `redis://localhost:6379`

Optional:

- `VERCEL_URL`: used as a key prefix for multi-tenant isolation (also useful in tests). If unset, a default prefix is used.
- `REDIS_COMMAND_TIMEOUT_MS`: timeout (ms) for Redis commands used by the handler.

### Local manual testing (Cache Lab)

This repo includes a dedicated Next.js Cache Components integration app with real pages for manual testing.

1. Start Redis locally.
1. Install + start the Cache Components test app:

```bash
pnpm -C test/integration/next-app-16-1-1-cache-components install
pnpm -C test/integration/next-app-16-1-1-cache-components dev
```

Then open the Cache Lab pages:

- `/cache-lab`
- `/cache-lab/use-cache-nondeterministic`
- `/cache-lab/cachelife-short`
- `/cache-lab/tag-invalidation`
- `/cache-lab/stale-while-revalidate`
- `/cache-lab/runtime-data-suspense`

To run the Playwright E2E tests against a running dev server:

```bash
PLAYWRIGHT_BASE_URL=http://localhost:3101 pnpm test:e2e
```

## Some words on nextjs caching internals

Nextjs will use different caching objects for different pages and api routes. Currently supported are kind: APP_ROUTE and APP_PAGE.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"test:ui": "vitest --ui --config vite.config.ts",
"test:unit": "vitest --config vite.config.ts src/**/*.test.ts src/**/*.test.tsx",
"test:integration": "vitest --config vite.config.ts ./test/integration/nextjs-cache-handler.integration.test.ts",
"test:cache-components": "vitest --run --config vitest.cache-components.config.ts",
"prepare": "./scripts/prepare.sh",
"test:browser": "vitest --config=vitest.browser.config.ts",
"test:e2e": "playwright test"
Expand Down Expand Up @@ -91,7 +92,7 @@
"vitest": "^4.0.13"
},
"peerDependencies": {
"next": ">=15.0.3 <= 16.1.1",
"next": ">=15.0.3 <16.2.0",
"redis": "4.7.0"
},
"packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531"
Expand Down
9 changes: 8 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: 'tests',
use: {
baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000',
baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3101',
trace: 'on-first-retry',
},
webServer: {
command:
'pnpm -C test/integration/next-app-16-1-1-cache-components dev -p 3101',
url: 'http://localhost:3101',
reuseExistingServer: true,
timeout: 120_000,
},
});
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading