File size: 2,461 Bytes
b91e262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
 * Simple LRU cache handler with max entries eviction policy.
 * When the cache exceeds maxEntries, the least recently used entries are evicted.
 */

const MAX_IMAGE_ENTRIES = parseInt(
  process.env.MAX_IMAGE_CACHE_ENTRIES || '2',
  10
)

class LRUCache {
  constructor(maxEntries) {
    this.maxEntries = maxEntries
    this.cache = new Map()
  }

  get(key) {
    if (!this.cache.has(key)) {
      return undefined
    }
    // Move to end (most recently used)
    const value = this.cache.get(key)
    this.cache.delete(key)
    this.cache.set(key, value)
    return value
  }

  set(key, value) {
    // If key exists, delete it first (will be re-added at end)
    if (this.cache.has(key)) {
      this.cache.delete(key)
    }
    // Evict oldest entries if at capacity
    while (this.cache.size >= this.maxEntries) {
      const oldestKey = this.cache.keys().next().value
      console.log('cache-handler evicting', oldestKey)
      this.cache.delete(oldestKey)
    }
    this.cache.set(key, value)
  }

  has(key) {
    return this.cache.has(key)
  }

  get size() {
    return this.cache.size
  }

  keys() {
    return Array.from(this.cache.keys())
  }
}

// Separate caches for different kinds
const imageCache = new LRUCache(MAX_IMAGE_ENTRIES)
const pageCache = new LRUCache(100) // Higher limit for pages

class CacheHandler {
  constructor(options) {
    this.options = options
    console.log('initialized custom cache-handler')
    console.log('max image cache entries:', MAX_IMAGE_ENTRIES)
  }

  async get(key, ctx) {
    const kind = ctx?.kind
    console.log('cache-handler get', key, 'kind:', kind)

    const cache = kind === 'IMAGE' ? imageCache : pageCache
    const entry = cache.get(key)

    if (entry) {
      console.log('cache-handler hit', key)
      return entry
    }
    console.log('cache-handler miss', key)
    return null
  }

  async set(key, data, ctx) {
    const kind = data?.kind
    console.log('cache-handler set', key, 'kind:', kind)

    const cache = kind === 'IMAGE' ? imageCache : pageCache
    cache.set(key, {
      value: data,
      lastModified: Date.now(),
    })

    if (kind === 'IMAGE') {
      console.log('cache-handler image cache size:', imageCache.size)
      console.log(
        'cache-handler image cache keys:',
        imageCache.keys().join(', ')
      )
    }
  }

  async revalidateTag(tags) {
    console.log('cache-handler revalidateTag', tags)
  }
}

module.exports = CacheHandler