mirror of
https://github.com/stack-auth/stack.git
synced 2026-07-20 21:29:36 +08:00
Auto-links a customer's BACKEND span to the caller's CLIENT session with zero glue.
The browser attaches one `x-hexclave-span-context` header to same-origin outgoing
fetches; `serverApp.withSpan(type, { request }, fn)` resolves the caller's refresh
token (from the session) plus that header, so the span — and everything created
inside the callback — parents under $refresh-token → $session-replay →
$session-replay-segment, exactly like a browser event.
- span-propagation.ts: versioned base64url header codec, same-origin fetch
auto-wrapper (idempotent, native header semantics preserved), origin predicate
- server-request-context.ts: AsyncLocalStorage ambient request context
- server-app-impl: withSpan/trackEvent({ request }) resolution; server telemetry
buffer re-keyed from userId to the full (user, refresh, replay, segment) context;
propagated custom parents flow as ambient frames
- backend events/batch: accept forwarded refresh_token_id/session_replay_id on
SERVER auth (rejected on client auth); compose [rti-,sri-,srsi-,cs-] + stamp
the scalar columns
- client-app-impl: install the fetch wrapper on init behind analytics.spanPropagation
(same-origin default + exact-origin allowlist); reads the live per-tab id
- tests: 24 propagation unit tests + 2 e2e (server-auth ancestry + client-auth reject)
The framework adapters (tRPC, Convex, oRPC, ElysiaJS) build on this primitive in a
separate stacked branch; with an adapter you never pass { request } yourself.