Skip to content
Merged
Changes from 2 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import type { NextConfig } from 'next'

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

Expand All @@ -52,8 +52,8 @@ export default nextConfig
```js filename="next.config.js" switcher
module.exports = {
cacheHandlers: {
default: './cache-handlers/default-handler.js',
remote: './cache-handlers/remote-handler.js',
default: require.resolve('./cache-handlers/default-handler.js'),
remote: require.resolve('./cache-handlers/remote-handler.js'),
},
}
```
Expand Down Expand Up @@ -91,7 +91,7 @@ Returns a `CacheEntry` object if found, or `undefined` if not found or expired.
Your `get` method should retrieve the cache entry from storage, check if it has expired based on the `revalidate` time, and return `undefined` for missing or expired entries.

```js
class CacheHandler {
const cacheHandler = {
async get(cacheKey, softTags) {
const entry = cache.get(cacheKey)
if (!entry) return undefined
Expand Down Expand Up @@ -127,7 +127,7 @@ Returns `Promise<void>`.
Your `set` method must await the `pendingEntry` promise before storing it, since the cache entry may still be generating when this method is called. Once resolved, store the entry in your cache system.

```js
class CacheHandler {
const cacheHandler = {
async set(cacheKey, pendingEntry) {
// Wait for the entry to be ready
const entry = await pendingEntry
Expand All @@ -153,7 +153,7 @@ Returns `Promise<void>`.
For in-memory caches, this can be a no-op. For distributed caches, use this to sync tag state from an external service or database before processing requests.

```js
class CacheHandler {
const cacheHandler = {
async refreshTags() {
// For in-memory cache, no action needed
// For distributed cache, sync tag state from external service
Expand Down Expand Up @@ -182,7 +182,7 @@ Returns:
If you're not tracking tag revalidation timestamps, return `0`. Otherwise, find the most recent revalidation timestamp across all the provided tags. Return `Infinity` if you prefer to handle soft tag checking in the `get` method.

```js
class CacheHandler {
const cacheHandler = {
async getExpiration(tags) {
// Return 0 if not tracking tag revalidation
return 0
Expand Down Expand Up @@ -213,7 +213,7 @@ Returns `Promise<void>`.
When tags are revalidated, your handler should invalidate all cache entries that have any of those tags. Iterate through your cache and remove entries whose tags match the provided list.

```js
class CacheHandler {
const cacheHandler = {
async updateTags(tags, durations) {
// Invalidate all cache entries with matching tags
for (const [key, entry] of cache.entries()) {
Expand Down Expand Up @@ -264,7 +264,7 @@ Here's a minimal implementation using a `Map` for storage. This example demonstr
const cache = new Map()
const pendingSets = new Map()

module.exports = class MemoryCacheHandler {
module.exports = {
async get(cacheKey, softTags) {
// Wait for any pending set operation to complete
const pendingPromise = pendingSets.get(cacheKey)
Expand Down Expand Up @@ -333,7 +333,7 @@ For durable storage like Redis or a database, you'll need to serialize the cache
```js filename="cache-handlers/redis-handler.js"
const { createClient } = require('redis')

module.exports = class RedisCacheHandler {
module.exports = {
constructor() {
this.client = createClient({ url: process.env.REDIS_URL })
this.client.connect()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The object literal syntax doesn't support constructor methods like classes do. When converting from a class to an object, the Redis client initialization needs to be moved outside the exported object. Consider restructuring like this:

const { createClient } = require('redis')
const client = createClient({ url: process.env.REDIS_URL })
client.connect()

module.exports = {
  // Methods that use client
  async get(cacheKey, softTags) {
    // Implementation using client
  },
  // Other methods...
}

This ensures the Redis client is properly initialized before the module is exported and can be used by the handler methods.

Suggested change
module.exports = {
constructor() {
this.client = createClient({ url: process.env.REDIS_URL })
this.client.connect()
const { createClient } = require('redis')
const client = createClient({ url: process.env.REDIS_URL })
client.connect()
module.exports = {

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Expand Down
Loading