@pyreon/zero 0.12.14 → 0.12.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/server.js CHANGED
@@ -328,11 +328,36 @@ function resolveConfig(userConfig = {}) {
328
328
  *
329
329
  * Wraps an SSR handler and caches responses per URL path.
330
330
  * Serves stale content immediately while revalidating in the background.
331
+ *
332
+ * Bounded by `config.maxEntries` (default: 1000) with LRU eviction. The
333
+ * `Map` preserves insertion order, so re-inserting an entry on every
334
+ * serve (touching it) keeps the LRU order correct. Without the cap,
335
+ * unbounded URL spaces like `/user/:id` would grow cache memory without
336
+ * limit over the server's lifetime — a real leak in long-running
337
+ * deployments.
331
338
  */
332
339
  function createISRHandler(handler, config) {
333
340
  const cache = /* @__PURE__ */ new Map();
334
341
  const revalidating = /* @__PURE__ */ new Set();
335
342
  const revalidateMs = config.revalidate * 1e3;
343
+ const maxEntries = Math.max(1, config.maxEntries ?? 1e3);
344
+ function set(key, entry) {
345
+ if (cache.has(key)) cache.delete(key);
346
+ cache.set(key, entry);
347
+ while (cache.size > maxEntries) {
348
+ const oldest = cache.keys().next().value;
349
+ if (oldest === void 0) break;
350
+ cache.delete(oldest);
351
+ }
352
+ }
353
+ function touch(key) {
354
+ const entry = cache.get(key);
355
+ if (entry !== void 0) {
356
+ cache.delete(key);
357
+ cache.set(key, entry);
358
+ }
359
+ return entry;
360
+ }
336
361
  async function revalidate(url) {
337
362
  const key = url.pathname;
338
363
  if (revalidating.has(key)) return;
@@ -344,7 +369,7 @@ function createISRHandler(handler, config) {
344
369
  res.headers.forEach((v, k) => {
345
370
  headers[k] = v;
346
371
  });
347
- cache.set(key, {
372
+ set(key, {
348
373
  html,
349
374
  headers,
350
375
  timestamp: Date.now()
@@ -357,7 +382,7 @@ function createISRHandler(handler, config) {
357
382
  if (req.method !== "GET") return handler(req);
358
383
  const url = new URL(req.url);
359
384
  const key = url.pathname;
360
- const entry = cache.get(key);
385
+ const entry = touch(key);
361
386
  if (entry) {
362
387
  const age = Date.now() - entry.timestamp;
363
388
  if (age > revalidateMs) revalidate(url);