@rangojs/router 0.17.0 → 0.18.0
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/README.md +3 -2
- package/dist/types/browser/cookie-name.d.ts +6 -0
- package/dist/types/browser/history-state.d.ts +16 -0
- package/dist/types/cache/cache-key-utils.d.ts +17 -2
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +98 -14
- package/dist/types/cache/cache-tag.d.ts +92 -7
- package/dist/types/cache/cf/cf-base64.d.ts +6 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +185 -44
- package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
- package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +34 -0
- package/dist/types/cache/handle-snapshot.d.ts +4 -3
- package/dist/types/cache/index.d.ts +1 -0
- package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
- package/dist/types/cache/shell-memo.d.ts +178 -0
- package/dist/types/cache/shell-snapshot.d.ts +110 -21
- package/dist/types/cache/tag-invalidation.d.ts +30 -3
- package/dist/types/cache/types.d.ts +207 -43
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +111 -13
- package/dist/types/prerender/build-shell-capture.d.ts +11 -4
- package/dist/types/router/instrument.d.ts +8 -0
- package/dist/types/router/middleware-types.d.ts +6 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +40 -11
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +21 -10
- package/dist/types/router/segment-resolution/mask-nested.d.ts +65 -24
- package/dist/types/rsc/full-payload.d.ts +14 -0
- package/dist/types/rsc/handler.d.ts +1 -1
- package/dist/types/rsc/shell-build-manifest.d.ts +8 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +53 -6
- package/dist/types/rsc/shell-capture.d.ts +146 -15
- package/dist/types/rsc/shell-serve.d.ts +140 -17
- package/dist/types/rsc/types.d.ts +7 -0
- package/dist/types/server/context.d.ts +109 -15
- package/dist/types/server/cookie-store.d.ts +21 -0
- package/dist/types/server/request-context.d.ts +159 -33
- package/dist/types/ssr/index.d.ts +9 -0
- package/dist/types/ssr/ssr-root.d.ts +9 -8
- package/dist/types/testing/flight.entry.d.ts +7 -0
- package/dist/types/testing/run-loader.d.ts +18 -3
- package/dist/types/testing/serve-shell-request.d.ts +132 -0
- package/dist/types/testing/shell-status.d.ts +23 -10
- package/dist/types/types/handler-context.d.ts +14 -1
- package/dist/types/urls/pattern-types.d.ts +22 -18
- package/dist/types/vite/router-discovery.d.ts +29 -2
- package/dist/vite/index.js +46 -9
- package/package.json +1 -1
- package/skills/breadcrumbs/SKILL.md +17 -7
- package/skills/cache-guide/SKILL.md +123 -51
- package/skills/caching/SKILL.md +253 -23
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +11 -6
- package/skills/cloudflare/SKILL.md +15 -0
- package/skills/comparison/references/framework-comparison.md +44 -32
- package/skills/defer-hydration/SKILL.md +50 -30
- package/skills/deployment-caching/SKILL.md +5 -2
- package/skills/document-cache/SKILL.md +8 -2
- package/skills/handler-use/SKILL.md +2 -0
- package/skills/hooks/handle-and-actions.md +3 -1
- package/skills/hooks/state.md +3 -1
- package/skills/loader/SKILL.md +161 -39
- package/skills/middleware/SKILL.md +16 -9
- package/skills/migrate-nextjs/SKILL.md +67 -36
- package/skills/migrate-react-router/SKILL.md +2 -1
- package/skills/migrate-react-router/component-migration.md +3 -1
- package/skills/migrate-react-router/data-and-actions.md +3 -1
- package/skills/migrate-react-router/route-mapping.md +7 -4
- package/skills/observability/SKILL.md +64 -0
- package/skills/parallel/SKILL.md +13 -8
- package/skills/ppr/SKILL.md +655 -363
- package/skills/prerender/SKILL.md +27 -14
- package/skills/rango/SKILL.md +52 -33
- package/skills/route/SKILL.md +12 -7
- package/skills/router-setup/SKILL.md +4 -2
- package/skills/scripts/SKILL.md +8 -1
- package/skills/server-actions/SKILL.md +11 -0
- package/skills/shell-manifest/SKILL.md +21 -12
- package/skills/testing/SKILL.md +25 -21
- package/skills/testing/cache-prerender.md +15 -14
- package/skills/testing/loader.md +18 -1
- package/skills/testing/serve-shell-request.md +188 -0
- package/skills/theme/SKILL.md +52 -4
- package/skills/typesafety/env-and-bindings.md +10 -2
- package/skills/use-cache/SKILL.md +39 -16
- package/skills/vercel/SKILL.md +14 -2
- package/skills/view-transitions/SKILL.md +1 -1
- package/src/browser/cookie-name.ts +23 -0
- package/src/browser/history-state.ts +23 -0
- package/src/browser/rsc-router.tsx +5 -0
- package/src/cache/cache-key-utils.ts +22 -2
- package/src/cache/cache-policy.ts +22 -0
- package/src/cache/cache-runtime.ts +34 -7
- package/src/cache/cache-scope.ts +345 -33
- package/src/cache/cache-tag.ts +375 -11
- package/src/cache/cf/cf-base64.ts +36 -4
- package/src/cache/cf/cf-cache-constants.ts +12 -0
- package/src/cache/cf/cf-cache-store.ts +990 -348
- package/src/cache/cf/cf-cache-types.ts +32 -4
- package/src/cache/cf/cf-shell-frame.ts +258 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +143 -39
- package/src/cache/handle-snapshot.ts +4 -3
- package/src/cache/index.ts +2 -0
- package/src/cache/isolate-tag-memo.ts +308 -0
- package/src/cache/shell-memo.ts +341 -0
- package/src/cache/shell-snapshot.ts +217 -27
- package/src/cache/tag-invalidation.ts +104 -19
- package/src/cache/types.ts +211 -43
- package/src/cache/vercel/vercel-cache-store.ts +545 -61
- package/src/prerender/build-shell-capture.ts +65 -11
- package/src/route-definition/dsl-helpers.ts +4 -3
- package/src/router/handler-context.ts +38 -4
- package/src/router/instrument.ts +54 -2
- package/src/router/intercept-resolution.ts +19 -7
- package/src/router/loader-resolution.ts +63 -32
- package/src/router/match-api.ts +28 -9
- package/src/router/match-handlers.ts +5 -0
- package/src/router/match-middleware/cache-lookup.ts +17 -0
- package/src/router/match-middleware/cache-store.ts +31 -11
- package/src/router/middleware-types.ts +6 -1
- package/src/router/middleware.ts +23 -4
- package/src/router/prerender-match.ts +6 -0
- package/src/router/segment-resolution/fresh.ts +18 -9
- package/src/router/segment-resolution/helpers.ts +4 -2
- package/src/router/segment-resolution/loader-cache.ts +227 -56
- package/src/router/segment-resolution/loader-snapshot.ts +203 -51
- package/src/router/segment-resolution/mask-nested.ts +136 -42
- package/src/router/segment-resolution/revalidation.ts +27 -10
- package/src/rsc/full-payload.ts +25 -1
- package/src/rsc/handler.ts +14 -2
- package/src/rsc/progressive-enhancement.ts +3 -2
- package/src/rsc/response-cache-serve.ts +9 -6
- package/src/rsc/rsc-rendering.ts +601 -181
- package/src/rsc/shell-build-manifest.ts +27 -9
- package/src/rsc/shell-capture-constants.ts +60 -6
- package/src/rsc/shell-capture.ts +1001 -250
- package/src/rsc/shell-serve.ts +316 -34
- package/src/rsc/types.ts +7 -0
- package/src/server/context.ts +219 -28
- package/src/server/cookie-store.ts +87 -62
- package/src/server/request-context.ts +263 -38
- package/src/ssr/index.tsx +96 -37
- package/src/ssr/ssr-root.tsx +9 -8
- package/src/testing/flight.entry.ts +14 -0
- package/src/testing/run-loader.ts +63 -5
- package/src/testing/serve-shell-request.ts +378 -0
- package/src/testing/shell-status.ts +34 -12
- package/src/theme/ThemeProvider.tsx +7 -6
- package/src/types/handler-context.ts +14 -1
- package/src/urls/pattern-types.ts +22 -18
- package/src/vite/discovery/shell-prerender-phase.ts +9 -0
- package/src/vite/router-discovery.ts +14 -4
|
@@ -107,6 +107,7 @@ import {
|
|
|
107
107
|
createShellImplicitDocScope,
|
|
108
108
|
type CacheScope,
|
|
109
109
|
} from "../../cache/cache-scope.js";
|
|
110
|
+
import { ShellRecordUnavailableError } from "../../cache/shell-snapshot.js";
|
|
110
111
|
import { prerenderStoreShortCircuits } from "../navigation-snapshot.js";
|
|
111
112
|
import { paramsEqual } from "../params-util.js";
|
|
112
113
|
|
|
@@ -508,6 +509,15 @@ export function withCacheLookup<TEnv>(
|
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
|
|
512
|
+
// A document HIT tail replays the handler layer through the implicit doc
|
|
513
|
+
// scope and never runs a handler: without that scope (a context that lost
|
|
514
|
+
// the marker before the scope resolved), fail like a lookup miss instead
|
|
515
|
+
// of falling through to the handlers below.
|
|
516
|
+
const tailMarker = pipelineReqCtx?._shellImplicitCache;
|
|
517
|
+
if (tailMarker?.docTail && !ctx.cacheScope?.isShellImplicitDocScope) {
|
|
518
|
+
throw new ShellRecordUnavailableError(tailMarker.fixedDocKey);
|
|
519
|
+
}
|
|
520
|
+
|
|
511
521
|
if (ctx.isAction || !ctx.cacheScope?.enabled) {
|
|
512
522
|
yield* source;
|
|
513
523
|
if (ms) {
|
|
@@ -585,6 +595,13 @@ export function withCacheLookup<TEnv>(
|
|
|
585
595
|
}
|
|
586
596
|
|
|
587
597
|
if (!cacheResult) {
|
|
598
|
+
// A document shell HIT tail replays the handler layer from the entry's
|
|
599
|
+
// doc record and must never run a handler behind the committed prelude:
|
|
600
|
+
// a record that did not hit (it failed to decode, or the entry lost it)
|
|
601
|
+
// ends the tail here; serveShellHit degrades the response.
|
|
602
|
+
if (replayMarker?.docTail) {
|
|
603
|
+
throw new ShellRecordUnavailableError(replayMarker.fixedDocKey);
|
|
604
|
+
}
|
|
588
605
|
yield* source;
|
|
589
606
|
if (ms) {
|
|
590
607
|
ms.metrics.push({
|
|
@@ -106,7 +106,11 @@ import {
|
|
|
106
106
|
type RequestContext,
|
|
107
107
|
} from "../../server/request-context.js";
|
|
108
108
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
109
|
-
import {
|
|
109
|
+
import {
|
|
110
|
+
createShellImplicitDocScope,
|
|
111
|
+
resolveCacheTags,
|
|
112
|
+
} from "../../cache/cache-scope.js";
|
|
113
|
+
import { recordSegmentTags } from "../../cache/cache-tag.js";
|
|
110
114
|
import { getRouterContext } from "../router-context.js";
|
|
111
115
|
import { debugLog, debugWarn, getOrCreateRequestId } from "../logging.js";
|
|
112
116
|
import { INTERNAL_RANGO_DEBUG } from "../../internal-debug.js";
|
|
@@ -316,9 +320,10 @@ export function withCacheStore<TEnv>(
|
|
|
316
320
|
* store) on the no-eligible-snapshot path, so the lookup's own refusal is
|
|
317
321
|
* still surfaced while the fallback has nothing to serve.
|
|
318
322
|
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
323
|
+
* Registered through requestCtx.onResponse, which a capture fires only after
|
|
324
|
+
* the handler pushes settle (settleCaptureRecord), and wrapped in
|
|
325
|
+
* requestCtx.waitUntil — during a capture that is the tracked-write override,
|
|
326
|
+
* so settleWrites awaits the record before the capture reads it.
|
|
322
327
|
*/
|
|
323
328
|
function recordShellCaptureDocRecord<TEnv>(
|
|
324
329
|
ctx: MatchContext<TEnv>,
|
|
@@ -336,12 +341,27 @@ function recordShellCaptureDocRecord<TEnv>(
|
|
|
336
341
|
if (!scope.allowsCache("write")) return;
|
|
337
342
|
|
|
338
343
|
const docScope = createShellImplicitDocScope(marker);
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
),
|
|
344
|
+
// The route scope's cache({ tags }) describe these segments too: on its
|
|
345
|
+
// HIT they arrive with the replayed record (recordSegmentTags in
|
|
346
|
+
// lookupRouteDetailed); on a fresh render they are recorded here, so the
|
|
347
|
+
// doc record, and the shell taking its tags, carries them either way.
|
|
348
|
+
recordSegmentTags(
|
|
349
|
+
segments.map((s) => s.id),
|
|
350
|
+
resolveCacheTags(scope.config, requestCtx),
|
|
351
|
+
requestCtx,
|
|
346
352
|
);
|
|
353
|
+
// Through onResponse, like the implicit scope's own write: the capture
|
|
354
|
+
// fires these callbacks (settleCaptureRecord) only after the handler
|
|
355
|
+
// pushes settled, so the record's handle encode never races them.
|
|
356
|
+
requestCtx.onResponse((response) => {
|
|
357
|
+
requestCtx.waitUntil(() =>
|
|
358
|
+
docScope.cacheRoute(
|
|
359
|
+
ctx.pathname,
|
|
360
|
+
ctx.matched.params,
|
|
361
|
+
segments,
|
|
362
|
+
ctx.isIntercept,
|
|
363
|
+
),
|
|
364
|
+
);
|
|
365
|
+
return response;
|
|
366
|
+
});
|
|
347
367
|
}
|
|
@@ -68,7 +68,12 @@ export interface MiddlewareContext<
|
|
|
68
68
|
|
|
69
69
|
debugPerformance(): void;
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The visitor's theme (cookie or default); undefined without theme config.
|
|
73
|
+
* Guarded like `cookies()`: a read inside a `"use cache"` function throws
|
|
74
|
+
* (#971).
|
|
75
|
+
*/
|
|
76
|
+
readonly theme?: Theme;
|
|
72
77
|
|
|
73
78
|
setTheme?: (theme: Theme) => void;
|
|
74
79
|
|
package/src/router/middleware.ts
CHANGED
|
@@ -31,6 +31,8 @@ import {
|
|
|
31
31
|
} from "../cache/taint.js";
|
|
32
32
|
import { getCacheExecScope } from "../cache/cache-exec-scope.js";
|
|
33
33
|
import { assertNonCacheableReadAllowed } from "../server/context.js";
|
|
34
|
+
import { assertThemeReadAllowed } from "../server/cookie-store.js";
|
|
35
|
+
import type { Theme } from "../theme/types.js";
|
|
34
36
|
|
|
35
37
|
// Re-export types consumed through this module's path.
|
|
36
38
|
export type {
|
|
@@ -40,6 +42,25 @@ export type {
|
|
|
40
42
|
MiddlewareFn,
|
|
41
43
|
} from "./middleware-types.js";
|
|
42
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Middleware ctx.theme: the visitor's theme cookie, guarded like the handler
|
|
47
|
+
* ctx.theme and cookies() (#971, #946), so a read inside a "use cache"
|
|
48
|
+
* function the middleware calls throws. Non-enumerable like the handler and
|
|
49
|
+
* request-context getters: a spread of the ctx (inside a "use cache"
|
|
50
|
+
* function, say) does not read it. One shared descriptor, so every ctx keeps
|
|
51
|
+
* the same property shape.
|
|
52
|
+
*/
|
|
53
|
+
const MIDDLEWARE_THEME_DESCRIPTOR: PropertyDescriptor = {
|
|
54
|
+
get(): Theme | undefined {
|
|
55
|
+
const reqCtx = _getRequestContext();
|
|
56
|
+
if (!reqCtx?._themeConfig) return undefined;
|
|
57
|
+
assertThemeReadAllowed(reqCtx, "ctx.theme");
|
|
58
|
+
return reqCtx._readTheme();
|
|
59
|
+
},
|
|
60
|
+
enumerable: false,
|
|
61
|
+
configurable: true,
|
|
62
|
+
};
|
|
63
|
+
|
|
43
64
|
const MIDDLEWARE_METRIC_DEPTH = 1;
|
|
44
65
|
const POST_METRIC_MIN_DURATION_MS = 0.01;
|
|
45
66
|
|
|
@@ -320,10 +341,7 @@ export function createMiddlewareContext<TEnv>(
|
|
|
320
341
|
responseHolder.response.headers.set(name, value);
|
|
321
342
|
},
|
|
322
343
|
|
|
323
|
-
|
|
324
|
-
return _getRequestContext()?.theme;
|
|
325
|
-
},
|
|
326
|
-
|
|
344
|
+
// theme: MIDDLEWARE_THEME_DESCRIPTOR, defined after this literal.
|
|
327
345
|
get setTheme(): MiddlewareContext<TEnv>["setTheme"] {
|
|
328
346
|
return _getRequestContext()?.setTheme;
|
|
329
347
|
},
|
|
@@ -361,6 +379,7 @@ export function createMiddlewareContext<TEnv>(
|
|
|
361
379
|
}
|
|
362
380
|
},
|
|
363
381
|
};
|
|
382
|
+
Object.defineProperty(ctx, "theme", MIDDLEWARE_THEME_DESCRIPTOR);
|
|
364
383
|
(ctx as any)[NOCACHE_SYMBOL] = true;
|
|
365
384
|
return ctx;
|
|
366
385
|
}
|
|
@@ -230,6 +230,7 @@ export async function matchForPrerender<TEnv = any>(
|
|
|
230
230
|
_setStatus: () => {},
|
|
231
231
|
_rotateStateCookie: () => {},
|
|
232
232
|
_setKeepCacheDirective: () => {},
|
|
233
|
+
_setFreshReadsCookie: () => {},
|
|
233
234
|
use: (() => {
|
|
234
235
|
throw new Error("use() not available during pre-rendering");
|
|
235
236
|
}) as any,
|
|
@@ -239,6 +240,8 @@ export async function matchForPrerender<TEnv = any>(
|
|
|
239
240
|
waitUntil: () => {},
|
|
240
241
|
onResponse: () => {},
|
|
241
242
|
_onResponseCallbacks: [],
|
|
243
|
+
// No theme at build time: no request cookie.
|
|
244
|
+
_readTheme: () => undefined,
|
|
242
245
|
setLocationState() {},
|
|
243
246
|
_locationState: undefined,
|
|
244
247
|
_renderBarrier: Promise.resolve(),
|
|
@@ -530,6 +533,7 @@ export async function renderStaticSegment<TEnv = any>(
|
|
|
530
533
|
_setStatus: () => {},
|
|
531
534
|
_rotateStateCookie: () => {},
|
|
532
535
|
_setKeepCacheDirective: () => {},
|
|
536
|
+
_setFreshReadsCookie: () => {},
|
|
533
537
|
use: (() => {
|
|
534
538
|
throw new Error("use() not available during static pre-rendering");
|
|
535
539
|
}) as any,
|
|
@@ -539,6 +543,8 @@ export async function renderStaticSegment<TEnv = any>(
|
|
|
539
543
|
waitUntil: () => {},
|
|
540
544
|
onResponse: () => {},
|
|
541
545
|
_onResponseCallbacks: [],
|
|
546
|
+
// No theme at build time: no request cookie.
|
|
547
|
+
_readTheme: () => undefined,
|
|
542
548
|
setLocationState() {},
|
|
543
549
|
_locationState: undefined,
|
|
544
550
|
_renderBarrier: Promise.resolve(),
|
|
@@ -37,7 +37,7 @@ import { applyViewTransitionDefault } from "./view-transition-default.js";
|
|
|
37
37
|
import { _getRequestContext } from "../../server/request-context.js";
|
|
38
38
|
import { getRouterContext } from "../router-context.js";
|
|
39
39
|
import { observeStreamedHandler } from "./streamed-handler-telemetry.js";
|
|
40
|
-
import {
|
|
40
|
+
import { observeSegmentHandler } from "../instrument.js";
|
|
41
41
|
import {
|
|
42
42
|
track,
|
|
43
43
|
RangoContext,
|
|
@@ -173,9 +173,7 @@ export async function resolveLoaders<TEnv>(
|
|
|
173
173
|
// bakes at capture regardless of the entry's loading() lane
|
|
174
174
|
// (loader-cache.ts capture branch) and its HIT-tail seed
|
|
175
175
|
// overlay needs the same key.
|
|
176
|
-
bakeLane || loaderEntry.
|
|
177
|
-
? segmentId
|
|
178
|
-
: null,
|
|
176
|
+
bakeLane || loaderEntry.bake === true ? segmentId : null,
|
|
179
177
|
),
|
|
180
178
|
),
|
|
181
179
|
entry,
|
|
@@ -223,7 +221,7 @@ export async function resolveLoaders<TEnv>(
|
|
|
223
221
|
loaderEntry,
|
|
224
222
|
ctx,
|
|
225
223
|
ctx.pathname,
|
|
226
|
-
bakeLane || loaderEntry.
|
|
224
|
+
bakeLane || loaderEntry.bake === true ? segmentId : null,
|
|
227
225
|
),
|
|
228
226
|
),
|
|
229
227
|
entry,
|
|
@@ -396,7 +394,7 @@ export async function resolveSegment<TEnv>(
|
|
|
396
394
|
const doneRouteHandler = track(`handler:${entry.id}`, 2);
|
|
397
395
|
if (entry.loading) {
|
|
398
396
|
const result = handleHandlerResult(
|
|
399
|
-
|
|
397
|
+
observeSegmentHandler(entry.shortCode, entry.id, handler, context),
|
|
400
398
|
);
|
|
401
399
|
if (result instanceof Promise) {
|
|
402
400
|
warnOnStreamedResponse(result, entry.id);
|
|
@@ -420,7 +418,12 @@ export async function resolveSegment<TEnv>(
|
|
|
420
418
|
}
|
|
421
419
|
} else {
|
|
422
420
|
component = handleHandlerResult(
|
|
423
|
-
await
|
|
421
|
+
await observeSegmentHandler(
|
|
422
|
+
entry.shortCode,
|
|
423
|
+
entry.id,
|
|
424
|
+
handler,
|
|
425
|
+
context,
|
|
426
|
+
),
|
|
424
427
|
);
|
|
425
428
|
doneRouteHandler();
|
|
426
429
|
}
|
|
@@ -670,7 +673,12 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
670
673
|
if (hasLoadingFallback) {
|
|
671
674
|
const result =
|
|
672
675
|
typeof handler === "function"
|
|
673
|
-
?
|
|
676
|
+
? observeSegmentHandler(
|
|
677
|
+
`${parentShortCode}.${slot}`,
|
|
678
|
+
`${parallelEntry.id}.${slot}`,
|
|
679
|
+
handler,
|
|
680
|
+
context,
|
|
681
|
+
)
|
|
674
682
|
: handler;
|
|
675
683
|
if (result instanceof Promise) {
|
|
676
684
|
result.finally(doneParallelHandler).catch(() => {});
|
|
@@ -694,7 +702,8 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
694
702
|
} else {
|
|
695
703
|
component =
|
|
696
704
|
typeof handler === "function"
|
|
697
|
-
? await
|
|
705
|
+
? await observeSegmentHandler(
|
|
706
|
+
`${parentShortCode}.${slot}`,
|
|
698
707
|
`${parallelEntry.id}.${slot}`,
|
|
699
708
|
handler,
|
|
700
709
|
context,
|
|
@@ -29,7 +29,7 @@ import type {
|
|
|
29
29
|
import type { SegmentResolutionDeps } from "../types.js";
|
|
30
30
|
import { debugLog } from "../logging.js";
|
|
31
31
|
import { tryStaticLookup } from "./static-store.js";
|
|
32
|
-
import {
|
|
32
|
+
import { observeSegmentHandler } from "../instrument.js";
|
|
33
33
|
import type { TelemetrySink } from "../telemetry.js";
|
|
34
34
|
import { resolveSink, safeEmit, getRequestId } from "../telemetry.js";
|
|
35
35
|
|
|
@@ -175,7 +175,9 @@ export async function resolveLayoutComponent<TEnv>(
|
|
|
175
175
|
// by track("handler:<id>") at the call site). handleHandlerResult stays OUTSIDE
|
|
176
176
|
// the span so a handler that returns a Response (redirect control flow, which it
|
|
177
177
|
// rethrows) is not recorded as a span error — mirrors the route-handler sites.
|
|
178
|
-
return handleHandlerResult(
|
|
178
|
+
return handleHandlerResult(
|
|
179
|
+
await observeSegmentHandler(entry.shortCode, entry.id, handler, context),
|
|
180
|
+
);
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
// ---------------------------------------------------------------------------
|