Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/diagnostic-code-consolidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@solidjs/signals": patch
"solid-js": patch
"@solidjs/web": patch
---

Diagnostic code consolidation. Codes are public API (the Sentry fingerprint roots); three renames.

- `WIDE_WRITE` is folded into `HUGE_FAN_OUT` — one code, one threshold story. The core's always-on check warns at 2000 subscribers; the attribution engine's `fanOut` threshold (default 250, was `wideWrites`) warns earlier while it is enabled and reports through the same emitter, so `data.count` is the subscriber count and, from the engine, `data.write` says which write reached it (`"write"`, `"refresh"`, `"async"`). One WeakMap dedupes both reporters (re-warn after another 500). `AttributionOptions.wideWrites` → `fanOut`.
- `SERVER_FN_ERROR_SANITIZED` and `SSR_ERROR_SANITIZED` are one code, `SERVER_ERROR_SANITIZED` — the same fact from two roads. `data.source` is `"server-function"` (severity `error`, from `@solidjs/web/server-functions`) or `"ssr"` (severity `info`, from the SSR `<Errored>`/rejection path); `data.error` is the original and `data.wire` the replacement on both.
- `ASYNC_WATERFALL` is client-only again: the server's boundary-passes verdict is its own code, `SSR_BOUNDARY_WATERFALL` (kind `ssr`; `info` for two sequential waits, `warn` for three or more; `data: { boundary, passes, sequentialMs }`). `data.side` is gone with it.
8 changes: 8 additions & 0 deletions .changeset/source-names-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@solidjs/compiler": patch
"@solidjs/babel-plugin": patch
---

`sourceNames` follows `dev` in both JSX compilers. Unset, every kind (`components`, `bindings`) is on when `dev: true` and off otherwise; `true`/`false` sets every kind (`sourceNames: false` opts a dev build out); the object form picks, and each kind it leaves unspecified follows `dev` (previously `false`). Production output (`dev: false`) is byte-identical with the option set or unset. `@solidjs/babel-plugin`'s `PluginConfig.sourceNames` is now optional. Dev builds label components (`createComponent(Home, props, "Home")`) and binding effects (`span.children`) out of the box, so diagnostics and the Performance panel read as source without build-tool configuration.

Primitive naming (`createSignal(0, { name: "count" })`) stays with `@solidjs/compiler`'s standalone `transformSourceNames` pass, which the build tool runs on every module independently of the JSX compiler; it is not a JSX-transform kind, and the READMEs and RFC now say so.
6 changes: 3 additions & 3 deletions documentation/performance-experiments.md
Original file line number Diff line number Diff line change
Expand Up @@ -7079,9 +7079,9 @@ null)` leaves a `...false` spread in prod (rollup folds the conditional
pass with a module counter bumped per first-touch link, and CodSpeed
priced that). `HUGE_FAN_OUT` / `HUGE_FAN_IN` therefore
fire on the change / the recompute rather than the link, deduped through a
`WeakMap` (once per node, again after +500). `WIDE_WRITE` counts the
subscriber list itself on the write (engine-only walk) and hands over to
`HUGE_FAN_OUT` at 2000.
`WeakMap` (once per node, again after +500). The attribution engine's
lower-threshold `HUGE_FAN_OUT` check counts the subscriber list itself on
the write (engine-only walk) and hands over to the core's at 2000.
- **Prod byte-identical** modulo comments and the removed `...false ? {…} :
options` spread (`diff -w` of `dist/prod` before/after, comment lines
stripped: only that hunk).
Expand Down
2 changes: 1 addition & 1 deletion documentation/plans/observe-tier-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Site migration `__DEV__` → `__OBSERVE__` (everything not listed stays
| `core/scheduler.ts` | 223, 488, 1259, 1290 | hooks |
| `core/action.ts` | 140, 144, 147 | hooks |
| `core/effect.ts` | 210 | hooks |
| `core/graph.ts` | 18, 194 | edge counters (`WIDE_WRITE`) |
| `core/graph.ts` | 18, 194 | edge counters (`HUGE_FAN_OUT`) |
| `boundaries.ts` | 334, 372 | hooks |
| `map.ts` | 281, 290, 331 (hooks); 76, 102, 370 (name plumbing) | hooks; labels |
| `signals.ts` | 373, 1085 (`registerGraph` → `_owner` half); 515, 557, 612, 677, 1189 (name defaults) | labels |
Expand Down
6 changes: 3 additions & 3 deletions documentation/plans/server-dev-build-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ Decision: **reuse `@solidjs/signals`'s channel, do not fork it.**
> boundary's routing, `failed` from the root), `SSR_SUBTREE_ABANDONED`
> (`abandonSubtree` with pending work discarded), `SSR_STREAM_ABANDONED`
> (`abandon("consumer" | "sink")`), `LATE_HEADER_WRITE` (recorded, then the
> existing dev throw / prod log), `SERVER_FN_ERROR_SANITIZED`
> (`sanitizeServerError`, `data.error` the original). The server entry also
> existing dev throw / prod log), `SERVER_ERROR_SANITIZED`
> (`sanitizeServerError`, `data.source: "server-function"`, `data.error` the original). The server entry also
> installs the client's repair-guide console footer (`src/console-footer.ts`,
> shared). Specs: `packages/solid/test/server/server-diagnostics.spec.ts`,
> `packages/web/test/server/server-diagnostics.spec.tsx`,
Expand Down Expand Up @@ -334,7 +334,7 @@ becomes the contract test for server codes.
>
> **(b) Checks off the record.** `ssrLoadingBoundary` derives two dev checks
> from the same facts the `"boundary"` record carries (the clock now runs in
> dev without a listener): `ASYNC_WATERFALL` with `data.side: "server"` —
> dev without a listener): `SSR_BOUNDARY_WATERFALL` —
> `passes - 1` sequential flights, exact where the client's proof is
> inferred, same thresholds (2 → `info`, structured only; 3+ → `warn`) — and
> a new `SSR_CLIENT_CONTENT_MASKED` (`warn`, `ssr`) for a client-only outcome
Expand Down
20 changes: 11 additions & 9 deletions documentation/proposals/production-observability-sketch.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ causality off structure rather than inferring it:
`paintedDuringHold`). `SILENT_HOLD` is a responsiveness verdict no RUM tool
has.
- **Verdicts with prescribed repairs**: `ASYNC_WATERFALL` (graph-proven
sequential flights), `WIDE_WRITE`, `HOT_SCOPE_FANOUT`, `UNSTABLE_MEMO_OUTPUT`,
sequential flights), `HUGE_FAN_OUT`, `HOT_SCOPE_FANOUT`, `UNSTABLE_MEMO_OUTPUT`,
`WIDE_SCOPE_DEPS`, `SILENT_HOLD` — stable codes, `ownerPath`, and message
text that names the fix.

Expand Down Expand Up @@ -105,7 +105,7 @@ the sites survive the build. The surface is small and well-delineated:
needed for anything to be legible.
- **Edge counts**: none stored. Fan-out is counted by the notify walk
(`insertSubs`), fan-in by the recompute pass (`link()` into one module
counter) — the always-on graph-size warnings and `WIDE_WRITE` read those.
counter) — the always-on graph-size warnings and the engine's lower-threshold `HUGE_FAN_OUT` read those.
(An earlier draft kept live `_subCount`/`_depCount` fields per node; they
forked node shapes and were removed.)
- **Web runtime (`@solidjs/web`)**: 3 `withInteraction` wrap sites
Expand Down Expand Up @@ -174,7 +174,7 @@ A third build flavor alongside `dist/dev` and `dist/prod`: `dist/profiling`
- `__DEV__: false` (no strict-read checks, no owner-scope errors, no
invariants, no console reporting) but a new `__OBSERVE__: true` flag that
keeps exactly: the `attrHooks` call sites, `noteGraphLink`/`unnoteGraphLink`
counters (needed by `WIDE_WRITE`), the `_name` field, and `emitDiagnostic`
counters (needed by the engine's `HUGE_FAN_OUT` threshold), the `_name` field, and `emitDiagnostic`
with `DiagnosticEvent` typing. The engine itself (`attribution.ts`) stays
pay-for-use: not loaded unless a consumer calls `enable()`.
- `@solidjs/web` mirrors it: the `withInteraction` wrappers at
Expand Down Expand Up @@ -309,7 +309,7 @@ the PII surface — see §6.
- **Per-interaction cost cap**: the adapter drops rerun children above a
count and keeps aggregates. Findings are never dropped (they are rare and
already deduped once-per-node by the engine).
- **Thresholds are the engine's** (`hotRuns`, `hotTime`, `wideWrites`,
- **Thresholds are the engine's** (`hotRuns`, `hotTime`, `fanOut`,
`holds: { infoMs, warnMs }`, `waterfalls.minFlightMs`). The adapter may
raise them for prod; it must not lower them below dev defaults, or prod
reports things dev never showed the developer.
Expand Down Expand Up @@ -424,7 +424,7 @@ Vendor (e.g. `@sentry/solid`):
3. Scrubbing defaults per §6 hooked into their existing data-collection
controls.
4. Product side: new performance-issue detectors for `SILENT_HOLD`,
`ASYNC_WATERFALL`, `HOT_SCOPE_FANOUT`, `WIDE_WRITE` with the engine's
`ASYNC_WATERFALL`, `HOT_SCOPE_FANOUT`, `HUGE_FAN_OUT` with the engine's
repair text as the "how to fix" body; per-interaction cost/hold rows in the
INP/Web Vitals view. Their autofix/agent surface can consume the
`reactivity-diagnostics` skill directly — the repairs are already written
Expand Down Expand Up @@ -612,9 +612,11 @@ are proposals; thresholds follow the engine's tiering (`info` advisory,

### 10.2 Server / SSR

- `SSR_BOUNDARY_WATERFALL` — _prod verdict, new._ The client engine's
`ASYNC_WATERFALL` logic (causal chain + origin post-dates upstream landing +
duration gate) applied to server flights within one request. Server flights
- `SSR_BOUNDARY_WATERFALL` — _prod verdict; today a dev-only check._ The
shipped code reads `passes - 1` off the `<Loading>` boundary record in dev
(RFC 08); this proposes the client engine's `ASYNC_WATERFALL` logic (causal
chain + origin post-dates upstream landing + duration gate) applied to
server flights within one request, in observe builds too. Server flights
are already per-boundary awaits (`hydration.ts:176–317`); the server facade
needs `flightStart`/`asyncEnd`-equivalent hooks. This is exactly what
React's Server Requests track shows visually and does not judge.
Expand All @@ -638,7 +640,7 @@ are proposals; thresholds follow the engine's tiering (`info` advisory,
declared in one scope was retracted before commit (the ledger's own
semantics). Advisory: it is legal, but a retract-heavy request is usually a
boundary doing HTTP work it shouldn't.
- `SERVER_FN_ERROR_SANITIZED` — _wiring, new._ A server function threw a
- `SERVER_ERROR_SANITIZED` (`data.source: "server-function"`) — _wiring, new._ A server function threw a
plain error that prod sanitized before encoding. The telemetry side keeps
the original message + stack (server-only), the wire keeps the sanitized
form. Closes the "prod errors are opaque" gap without weakening the wire.
Expand Down
Loading
Loading