@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/index.js +37 -10
- package/lib/index.js.map +1 -1
- package/lib/link.js +11 -4
- package/lib/link.js.map +1 -1
- package/lib/server.js +27 -2
- package/lib/server.js.map +1 -1
- package/lib/theme.js +27 -7
- package/lib/theme.js.map +1 -1
- package/lib/types/config.d.ts +7 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/index.d.ts +13 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/link.d.ts.map +1 -1
- package/lib/types/server.d.ts +14 -0
- package/lib/types/server.d.ts.map +1 -1
- package/lib/types/theme.d.ts +6 -1
- package/lib/types/theme.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/isr.ts +34 -2
- package/src/link.tsx +18 -5
- package/src/theme.tsx +33 -11
- package/src/types.ts +7 -0
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
|
-
|
|
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 =
|
|
385
|
+
const entry = touch(key);
|
|
361
386
|
if (entry) {
|
|
362
387
|
const age = Date.now() - entry.timestamp;
|
|
363
388
|
if (age > revalidateMs) revalidate(url);
|