Skip to content

Commit 3884838

Browse files
docs: observability — the observe build, the error hooks, records, traces, and attribution in production
Two Learn pages and the reference behind them. "Observability" is the app author's page: the three builds and what each costs, the two error hooks (where an error was thrown against where it was met; the server hook's return value is the wire), the trace the runtime carries into the browser on Server-Timing and <meta>, the records channel, the attribution engine on the observe build, and the fields that carry user data. "Build an observability adapter" is the tool author's contract: capture from the hooks alone, build spans from settled records in a microtask, join a call to its interaction by the identity of `origin`, answer the trace slot once per request, treat diagnostics as issues, and exclude the adapter's own root. App structure gains `start.instrument`. Reference: OBSERVE, configureClientErrors, configureServerErrors, and the `solid-js/attribution` entry get pages of their own instead of folding into DEV; the diagnostics types sit on both. observeServerFunctionCalls is gone upstream, so its page goes and a redirect points at the records channel. The generator strips member JSDoc from inline object types, which the render/renderToStream option lists had begun to carry. Existing guides move from `attribution.why()`/`costs()`/`feedback()`/`subscriptions()` to the named exports they became. Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent e1b24a4 commit 3884838

99 files changed

Lines changed: 5138 additions & 2682 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

netlify.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@
66
from = "/migration/from-solidstart"
77
to = "/migration/from-solid-start"
88
status = 301
9+
10+
# observeServerFunctionCalls was removed; calls are "call" records on OBSERVE.records.
11+
[[redirects]]
12+
from = "/reference/solid-web/server-functions/observe-calls"
13+
to = "/reference/solid-js/advanced/diagnostics-dev-hooks/observe"
14+
status = 301

scripts/extract-solid-ref.mjs

Lines changed: 216 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ const ENTRYPOINTS = [
3333
packageName: "@solidjs/signals",
3434
path: "packages/signals/src/index.ts",
3535
},
36+
{
37+
// Re-exported by solid-js/attribution as-is; read from the engine so the
38+
// page carries the engine's JSDoc.
39+
packageName: "solid-js/attribution",
40+
path: "packages/signals/src/attribution.ts",
41+
},
3642
{
3743
packageName: "@solidjs/web/server-functions",
3844
path: "packages/web/server-functions/src/client.ts",
@@ -174,6 +180,10 @@ const CANONICAL_ROUTES = {
174180
"request-response/get-trace-context.mdx",
175181
"Request & response",
176182
],
183+
configureServerErrors: [
184+
"request-response/configure-server-errors.mdx",
185+
"Request & response",
186+
],
177187
redirect: ["request-response/redirect.mdx", "Request & response"],
178188
reload: ["request-response/reload.mdx", "Request & response"],
179189
respond: ["request-response/respond.mdx", "Request & response"],
@@ -287,6 +297,42 @@ const ADVANCED_ROUTES = {
287297
"advanced/diagnostics-dev-hooks/dev.mdx",
288298
"Advanced / Diagnostics & Dev Hooks",
289299
],
300+
OBSERVE: [
301+
"advanced/diagnostics-dev-hooks/observe.mdx",
302+
"Advanced / Diagnostics & Dev Hooks",
303+
],
304+
configureClientErrors: [
305+
"advanced/diagnostics-dev-hooks/configure-client-errors.mdx",
306+
"Advanced / Diagnostics & Dev Hooks",
307+
],
308+
attribution: [
309+
"advanced/diagnostics-dev-hooks/attribution.mdx",
310+
"Advanced / Diagnostics & Dev Hooks",
311+
],
312+
feedback: [
313+
"advanced/diagnostics-dev-hooks/attribution.mdx",
314+
"Advanced / Diagnostics & Dev Hooks",
315+
],
316+
costs: [
317+
"advanced/diagnostics-dev-hooks/attribution.mdx",
318+
"Advanced / Diagnostics & Dev Hooks",
319+
],
320+
why: [
321+
"advanced/diagnostics-dev-hooks/attribution.mdx",
322+
"Advanced / Diagnostics & Dev Hooks",
323+
],
324+
subscriptions: [
325+
"advanced/diagnostics-dev-hooks/attribution.mdx",
326+
"Advanced / Diagnostics & Dev Hooks",
327+
],
328+
formatRerun: [
329+
"advanced/diagnostics-dev-hooks/attribution.mdx",
330+
"Advanced / Diagnostics & Dev Hooks",
331+
],
332+
formatOrigin: [
333+
"advanced/diagnostics-dev-hooks/attribution.mdx",
334+
"Advanced / Diagnostics & Dev Hooks",
335+
],
290336
configureServerFunctionsServer: [
291337
"server-functions/host-configuration.mdx",
292338
"Server functions / Integration",
@@ -311,6 +357,14 @@ const ADVANCED_ROUTES = {
311357
"server-functions/addressing.mdx",
312358
"Server functions / Integration",
313359
],
360+
serverFunctionActionUrl: [
361+
"server-functions/addressing.mdx",
362+
"Server functions / Integration",
363+
],
364+
parseServerFunctionActionUrl: [
365+
"server-functions/addressing.mdx",
366+
"Server functions / Integration",
367+
],
314368
createNoJSHandler: [
315369
"server-functions/progressive-enhancement.mdx",
316370
"Server functions / Integration",
@@ -327,10 +381,6 @@ const ADVANCED_ROUTES = {
327381
"server-functions/single-flight.mdx",
328382
"Server functions / Integration",
329383
],
330-
observeServerFunctionCalls: [
331-
"server-functions/observe-calls.mdx",
332-
"Server functions / Integration",
333-
],
334384
};
335385

336386
const STANDALONE_TYPE_ROUTES = {
@@ -372,37 +422,81 @@ const FOLD_INTO = {
372422
ArrayElement: "JSXElement",
373423
Dev: "DEV",
374424
DevHooks: "DEV",
375-
DiagnosticCapture: "DEV",
376-
DiagnosticCode: "DEV",
377-
DiagnosticEvent: "DEV",
378-
DiagnosticKind: "DEV",
379-
DiagnosticListener: "DEV",
380-
DiagnosticSubject: "DEV",
381-
Diagnostics: "DEV",
382-
DiagnosticSeverity: "DEV",
383-
AttributionHooks: "DEV",
384-
AttributionSlot: "DEV",
385-
AttributionRecords: "DEV",
386-
AttributionRecordType: "DEV",
387-
Acknowledgement: "DEV",
388-
ChangeOrigin: "DEV",
389-
ChangeRecord: "DEV",
390-
HeldWrite: "DEV",
391-
HoldEvent: "DEV",
392-
InteractionEvent: "DEV",
393-
InteractionRef: "DEV",
394-
NavigationEvent: "DEV",
395-
NavigationHop: "DEV",
396-
NavigationRef: "DEV",
397-
OriginRef: "DEV",
398-
RerunEvent: "DEV",
399-
Observe: "DEV",
400-
OBSERVE: "DEV",
401-
ServerObserve: "DEV",
402-
InvocationChannel: "DEV",
403-
InvocationEvent: "DEV",
404-
InvocationListener: "DEV",
405-
InvocationLive: "DEV",
425+
// The diagnostics channel is OBSERVE's; DEV reports from it.
426+
DiagnosticCapture: ["OBSERVE", "DEV"],
427+
DiagnosticCode: ["OBSERVE", "DEV"],
428+
DiagnosticEvent: ["OBSERVE", "DEV"],
429+
DiagnosticKind: ["OBSERVE", "DEV"],
430+
DiagnosticListener: ["OBSERVE", "DEV"],
431+
DiagnosticSubject: ["OBSERVE", "DEV"],
432+
Diagnostics: ["OBSERVE", "DEV"],
433+
DiagnosticSeverity: ["OBSERVE", "DEV"],
434+
// OBSERVE: the wiring — channels, slots, records.
435+
Observe: "OBSERVE",
436+
ServerObserve: "OBSERVE",
437+
ServerTrace: "OBSERVE",
438+
AttributionSlot: "OBSERVE",
439+
Records: "OBSERVE",
440+
RecordTypes: "OBSERVE",
441+
HostRecordTypes: "OBSERVE",
442+
RecordType: "OBSERVE",
443+
RecordEvent: "OBSERVE",
444+
RecordLive: "OBSERVE",
445+
RecordListener: "OBSERVE",
446+
BoundaryEvent: "OBSERVE",
447+
BoundaryListener: "OBSERVE",
448+
BoundaryLive: "OBSERVE",
449+
CallEvent: "OBSERVE",
450+
CallListener: "OBSERVE",
451+
CallLive: "OBSERVE",
452+
FrameEvent: "OBSERVE",
453+
FrameProducedEvent: "OBSERVE",
454+
FrameAppliedEvent: "OBSERVE",
455+
FrameListener: "OBSERVE",
456+
FrameLive: "OBSERVE",
457+
InvocationChannel: "OBSERVE",
458+
InvocationEvent: "OBSERVE",
459+
InvocationListener: "OBSERVE",
460+
InvocationLive: "OBSERVE",
461+
// solid-js/attribution: the engine and its records.
462+
Attribution: "attribution",
463+
AttributionOptions: "attribution",
464+
AttributionHooks: "attribution",
465+
AttributionRecords: "attribution",
466+
AttributionRecordType: "attribution",
467+
Acknowledgement: "attribution",
468+
ChangeKind: "attribution",
469+
ChangeOrigin: "attribution",
470+
ChangeRecord: "attribution",
471+
FlightLink: "attribution",
472+
HeldWrite: "attribution",
473+
HoldEvent: "attribution",
474+
InteractionEvent: "attribution",
475+
InteractionRef: "attribution",
476+
NavigationEvent: "attribution",
477+
NavigationHop: "attribution",
478+
NavigationRef: "attribution",
479+
OriginRef: "attribution",
480+
RerunEvent: "attribution",
481+
WaterfallRecord: "attribution",
482+
AttributionCostTables: "costs",
483+
ScopeCost: "costs",
484+
WriteCost: "costs",
485+
AttributionFeedbackTables: "feedback",
486+
FallbackStats: "feedback",
487+
FeedbackInteraction: "feedback",
488+
FeedbackNavigation: "feedback",
489+
FeedbackSource: "feedback",
490+
FlightStats: "feedback",
491+
// Error hooks.
492+
ClientErrorHook: "configureClientErrors",
493+
ClientErrorContext: "configureClientErrors",
494+
ClientErrorsConfig: "configureClientErrors",
495+
ServerErrorHook: "configureServerErrors",
496+
ServerErrorContext: "configureServerErrors",
497+
ServerErrorsConfig: "configureServerErrors",
498+
ServerErrorSite: "configureServerErrors",
499+
REVALIDATE_ALL: "respond",
406500
TraceContext: "getTraceContext",
407501
TraceProvider: "getTraceContext",
408502
TraceSlot: "getTraceContext",
@@ -475,9 +569,6 @@ const FOLD_INTO = {
475569
ServerFunctionOutcome: "subscribeFlightData",
476570
SingleFlightPayload: "subscribeFlightData",
477571
ServerFunctionInvocation: "getServerFunctionInvocation",
478-
ServerFunctionCall: "observeServerFunctionCalls",
479-
ServerFunctionRequestCall: "observeServerFunctionCalls",
480-
ServerFunctionResponseCall: "observeServerFunctionCalls",
481572
NoJSHandlerOptions: "createNoJSHandler",
482573
FlashSubmission: "createNoJSHandler",
483574
WrapInvocationHook: "configureServerFunctionsServer",
@@ -602,6 +693,18 @@ const HIDDEN_EXPORTS = new Set([
602693
"storeHasFamily",
603694
"storeHasOptimisticFamily",
604695
"storeIsShallow",
696+
// Store-source kinds and the static-key probe: consumed by the merge/omit
697+
// views and the DOM list driver.
698+
"SOURCE_MEMO",
699+
"SOURCE_MERGE",
700+
"SOURCE_OMIT",
701+
"SOURCE_PROXY",
702+
"SourceKind",
703+
"isStatic",
704+
// The root error hook's storage key; configureClientErrors is the API.
705+
"ROOT_ERROR_HOOK",
706+
// Engine-side owner labelling; records carry the result as `ownerPath`.
707+
"ownerPath",
605708
// Compiler-emitted tracked one-layer read for object-valued style/class bindings.
606709
"readShallow",
607710
"RequestContext",
@@ -681,6 +784,14 @@ const ENTRY_CALLOUTS = {
681784
};
682785

683786
const ENTRY_SUMMARY_OVERRIDES = {
787+
OBSERVE:
788+
"The observe tier's wiring: the records channel, the diagnostics channel, the attribution slot, and on the server the boundary channel and the trace-provider slot. `undefined` in a production build; an object in the observe and dev builds.",
789+
attribution:
790+
"The attribution engine from `solid-js/attribution`: install it with `enable()`, read the interaction, navigation, hold, and re-run records it settles through `subscribe()`, and fold them with `costs()`, `feedback()`, `why()`, and `subscriptions()`. Inert in a production build.",
791+
configureClientErrors:
792+
"Registers the ambient client error hook: called once per error object when an error boundary renders its fallback, with where the error was thrown and where it was met.",
793+
configureServerErrors:
794+
"Registers the ambient server error hook: called once per error object for every failure the server runtime handles or fails on, with the site that met it; the return value, when given, replaces what the client receives.",
684795
SourceAccessor:
685796
"The getter `createSignal` and `createMemo` return: an `Accessor<T>` carrying the `Refreshable` brand, which is what lets [`refresh()`](/reference/solid-js/lifecycle-actions/refresh) accept it. A plain `Accessor<T>` parameter accepts a `SourceAccessor<T>`; the reverse does not hold.",
686797
until:
@@ -741,8 +852,6 @@ const ENTRY_SUMMARY_OVERRIDES = {
741852
"Registers the integration that receives data folded into a mutation response.",
742853
decodeResponse:
743854
"Decodes a server-function response, including response envelopes and single-flight payloads.",
744-
observeServerFunctionCalls:
745-
"Subscribes to cloned client requests and responses for development tools and diagnostics.",
746855
provideRequestEvent:
747856
"Runs a callback in a server request-event scope backed by `AsyncLocalStorage`.",
748857
getRequestEvent:
@@ -890,6 +999,10 @@ const VALUE_IMPORTS = new Set(["storePath"]);
890999
const PREFERRED_SOURCE_PATHS = {
8911000
getRequestEvent: "packages/web/src/server.ts",
8921001
getTraceContext: "packages/web/src/server.ts",
1002+
configureServerErrors: "packages/web/src/server.ts",
1003+
ServerErrorContext: "packages/web/src/server.ts",
1004+
ServerErrorHook: "packages/web/src/server.ts",
1005+
ServerErrorsConfig: "packages/web/src/server.ts",
8931006
};
8941007

8951008
const ENTRY_EXAMPLES = {
@@ -1878,6 +1991,54 @@ const ENTRY_PROBLEMS = {
18781991
// apply to every page in the category; entry links are listed first.
18791992
// Shape: [["Label", "/path"], ...].
18801993
const ENTRY_LEARN = {
1994+
OBSERVE: [
1995+
["Observability", "/guides/observability"],
1996+
["Build an observability adapter", "/guides/observability-adapters"],
1997+
],
1998+
configureClientErrors: [
1999+
[
2000+
"Hear the errors your boundaries catch",
2001+
"/guides/observability#hear-the-errors-your-boundaries-catch",
2002+
],
2003+
["Build an observability adapter", "/guides/observability-adapters"],
2004+
],
2005+
configureServerErrors: [
2006+
[
2007+
"Hear every failure the server handles",
2008+
"/guides/observability#hear-every-failure-the-server-handles",
2009+
],
2010+
["Build an observability adapter", "/guides/observability-adapters"],
2011+
],
2012+
attribution: [
2013+
[
2014+
"Something updates too often",
2015+
"/guides/debugging-reactivity#something-updates-too-often",
2016+
],
2017+
[
2018+
"What each interaction cost",
2019+
"/guides/observability#what-each-interaction-cost",
2020+
],
2021+
["Build an observability adapter", "/guides/observability-adapters"],
2022+
],
2023+
why: [
2024+
[
2025+
"Something updates too often",
2026+
"/guides/debugging-reactivity#something-updates-too-often",
2027+
],
2028+
],
2029+
subscriptions: [
2030+
[
2031+
"Something updates too often",
2032+
"/guides/debugging-reactivity#something-updates-too-often",
2033+
],
2034+
],
2035+
costs: [["Performance", "/guides/performance"]],
2036+
feedback: [
2037+
[
2038+
"The screen looks dead after a click",
2039+
"/guides/debugging-reactivity#the-screen-looks-dead-after-a-click",
2040+
],
2041+
],
18812042
onCleanup: [
18822043
[
18832044
"Clean up what you start",
@@ -2230,6 +2391,10 @@ const ENTRY_LEARN = {
22302391
"Read trusted request context",
22312392
"/building-apps/server-functions/arguments-and-security#read-trusted-request-context",
22322393
],
2394+
[
2395+
"Follow a request into the browser",
2396+
"/guides/observability#follow-a-request-into-the-browser",
2397+
],
22332398
],
22342399
parseCookieHeader: [
22352400
["Sessions and auth", "/building-apps/sessions-and-auth"],
@@ -2355,6 +2520,8 @@ const COLLAPSED_RELATED_TYPES = new Set([
23552520
"MemoOptions",
23562521
"SignalOptions",
23572522
"HydrationProjectionOptions",
2523+
// The core's hook interface: for engine implementers, not engine users.
2524+
"AttributionHooks",
23582525
]);
23592526

23602527
const REFERENCE_FIXUPS = [
@@ -3407,7 +3574,15 @@ function dedent(value) {
34073574
}
34083575

34093576
function cleanTypeText(value) {
3410-
return rewriteTypeText(String(value).replace(/\s+/g, " ").trim());
3577+
// Inline object types carry their members' JSDoc; a one-line type has no
3578+
// room for it, and the member docs are rendered in their own sections.
3579+
return rewriteTypeText(
3580+
String(value)
3581+
.replace(/\/\*\*[\s\S]*?\*\//g, "")
3582+
.replace(/\s+/g, " ")
3583+
.replace(/\{ /g, "{ ")
3584+
.trim()
3585+
);
34113586
}
34123587

34133588
function rewriteTypeText(value) {

0 commit comments

Comments
 (0)