@rangojs/router 0.0.0-experimental.120 → 0.0.0-experimental.121

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.
@@ -2130,7 +2130,7 @@ import { resolve } from "node:path";
2130
2130
  // package.json
2131
2131
  var package_default = {
2132
2132
  name: "@rangojs/router",
2133
- version: "0.0.0-experimental.120",
2133
+ version: "0.0.0-experimental.121",
2134
2134
  description: "Django-inspired RSC router with composable URL patterns",
2135
2135
  keywords: [
2136
2136
  "react",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rangojs/router",
3
- "version": "0.0.0-experimental.120",
3
+ "version": "0.0.0-experimental.121",
4
4
  "description": "Django-inspired RSC router with composable URL patterns",
5
5
  "keywords": [
6
6
  "react",
@@ -78,6 +78,9 @@ export const MAX_REVALIDATION_INTERVAL = 30;
78
78
  * per-colo, so a slow `match` signals a degraded colo; we don't want it adding
79
79
  * latency to the request. On timeout the lookup is abandoned, a warning is
80
80
  * logged, and the read falls through to its normal miss path (L2/KV or render).
81
+ *
82
+ * This is the default; override per store via
83
+ * `CFCacheStoreOptions.edgeLookupTimeoutMs` (<= 0 disables the budget).
81
84
  */
82
85
  export const EDGE_LOOKUP_TIMEOUT_MS = 10;
83
86
 
@@ -205,6 +208,17 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
205
208
  */
206
209
  version?: string;
207
210
 
211
+ /**
212
+ * Latency budget (ms) for an L1 edge cache (CF Cache API) read. A `match`
213
+ * slower than this is abandoned and treated as a miss, so a degraded colo
214
+ * cannot stall the request; the read then falls through to its normal miss
215
+ * path (L2/KV or render).
216
+ *
217
+ * Defaults to {@link EDGE_LOOKUP_TIMEOUT_MS} (10). Set to 0 (or any value
218
+ * <= 0) to disable the budget and always await `match`.
219
+ */
220
+ edgeLookupTimeoutMs?: number;
221
+
208
222
  /**
209
223
  * Custom key generator applied to all cache operations.
210
224
  * Receives the full RequestContext (including env) and the default-generated key.
@@ -261,6 +275,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
261
275
  private readonly explicitBaseUrl?: string;
262
276
  private readonly waitUntil?: (fn: () => Promise<void>) => void;
263
277
  private readonly version?: string;
278
+ private readonly edgeLookupTimeoutMs: number;
264
279
  private readonly kv?: KVNamespace;
265
280
 
266
281
  constructor(options: CFCacheStoreOptions<TEnv>) {
@@ -281,6 +296,8 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
281
296
  this.explicitBaseUrl = options.baseUrl;
282
297
  this.defaults = options.defaults;
283
298
  this.version = options.version ?? VERSION;
299
+ this.edgeLookupTimeoutMs =
300
+ options.edgeLookupTimeoutMs ?? EDGE_LOOKUP_TIMEOUT_MS;
284
301
  this.keyGenerator = options.keyGenerator;
285
302
  this.waitUntil = (fn) => options.ctx.waitUntil(fn());
286
303
  this.kv = options.kv;
@@ -352,23 +369,26 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
352
369
 
353
370
  /**
354
371
  * Read from the L1 edge cache with a latency budget. A `match` that takes
355
- * longer than EDGE_LOOKUP_TIMEOUT_MS is abandoned and reported as a miss
356
- * (undefined) so a degraded colo cannot stall the request; callers then fall
357
- * through to their normal miss path (L2/KV or render). The slow `match` is
358
- * left to settle in the background (errors swallowed) rather than aborted,
359
- * since the Cache API exposes no cancellation.
372
+ * longer than the configured budget (edgeLookupTimeoutMs, default
373
+ * EDGE_LOOKUP_TIMEOUT_MS) is abandoned and reported as a miss (undefined) so a
374
+ * degraded colo cannot stall the request; callers then fall through to their
375
+ * normal miss path (L2/KV or render). The slow `match` is left to settle in
376
+ * the background (errors swallowed) rather than aborted, since the Cache API
377
+ * exposes no cancellation. A budget <= 0 disables the timeout entirely and
378
+ * awaits `match` directly.
360
379
  * @internal
361
380
  */
362
381
  private async matchWithTimeout(
363
382
  cache: Cache,
364
383
  request: Request,
365
384
  ): Promise<Response | undefined> {
385
+ const budget = this.edgeLookupTimeoutMs;
386
+ if (budget <= 0) {
387
+ return cache.match(request);
388
+ }
366
389
  let timer: ReturnType<typeof setTimeout> | undefined;
367
390
  const timeout = new Promise<{ timedOut: true }>((resolve) => {
368
- timer = setTimeout(
369
- () => resolve({ timedOut: true }),
370
- EDGE_LOOKUP_TIMEOUT_MS,
371
- );
391
+ timer = setTimeout(() => resolve({ timedOut: true }), budget);
372
392
  });
373
393
  try {
374
394
  const matchPromise = cache.match(request);
@@ -384,7 +404,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
384
404
  ]);
385
405
  if (result.timedOut) {
386
406
  console.warn(
387
- `[CFCacheStore] edge cache lookup exceeded ${EDGE_LOOKUP_TIMEOUT_MS}ms; treating as miss`,
407
+ `[CFCacheStore] edge cache lookup exceeded ${budget}ms; treating as miss`,
388
408
  );
389
409
  return undefined;
390
410
  }