solid2-agent-kit 0.24.0 → 0.25.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/bin/baseline.mjs +8 -8
- package/files/shared/rules-body.md +8 -2
- package/files/skills/solid-2/SKILL.md +70 -20
- package/package.json +1 -1
package/bin/baseline.mjs
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
// pulls them in — so doctor also checks an undeclared install of any package
|
|
20
20
|
// here, which is where a lockfile holds an older compiler.
|
|
21
21
|
export const BASELINE = {
|
|
22
|
-
'solid-js': { line: 2, baseline: '2.0.0-rc.
|
|
23
|
-
'@solidjs/web': { line: 2, baseline: '2.0.0-rc.
|
|
24
|
-
'@solidjs/signals': { line: 2, baseline: '2.0.0-rc.
|
|
25
|
-
'@solidjs/diagnostics': { line: 2, baseline: '2.0.0-rc.
|
|
26
|
-
'@solidjs/compiler': { line: 2, baseline: '2.0.0-rc.
|
|
27
|
-
'@solidjs/babel-plugin': { line: 2, baseline: '2.0.0-rc.
|
|
28
|
-
'@solidjs/router': { line: 2, baseline: '2.0.0-next.
|
|
29
|
-
'@solidjs/vite-plugin': { line: 3, baseline: '3.0.0-next.
|
|
22
|
+
'solid-js': { line: 2, baseline: '2.0.0-rc.21' },
|
|
23
|
+
'@solidjs/web': { line: 2, baseline: '2.0.0-rc.21' },
|
|
24
|
+
'@solidjs/signals': { line: 2, baseline: '2.0.0-rc.21' },
|
|
25
|
+
'@solidjs/diagnostics': { line: 2, baseline: '2.0.0-rc.21' },
|
|
26
|
+
'@solidjs/compiler': { line: 2, baseline: '2.0.0-rc.21' },
|
|
27
|
+
'@solidjs/babel-plugin': { line: 2, baseline: '2.0.0-rc.21' },
|
|
28
|
+
'@solidjs/router': { line: 2, baseline: '2.0.0-next.44' },
|
|
29
|
+
'@solidjs/vite-plugin': { line: 3, baseline: '3.0.0-next.57' },
|
|
30
30
|
'@solidjs/testing-library': { line: 1, baseline: '1.0.0-rc.2' },
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -209,7 +209,8 @@ Claude Code) for full patterns, decision tables, and official documentation URLs
|
|
|
209
209
|
the callback. The `onSettled` callback is a restricted scope: `onCleanup`
|
|
210
210
|
(`[CLEANUP_IN_FORBIDDEN_SCOPE]`), creating a memo or effect
|
|
211
211
|
(`[PRIMITIVE_IN_FORBIDDEN_SCOPE]`), and `flush()` all throw there in dev and halt
|
|
212
|
-
the reactive system
|
|
212
|
+
the reactive system; a pending async read there warns `[PENDING_ASYNC_FORBIDDEN_SCOPE]`
|
|
213
|
+
<!-- upstream:pending-async-forbidden-scope --> (nothing re-runs the callback when the answer lands). A 1.x `onMount(() => { …; onCleanup(…) })` becomes
|
|
213
214
|
`onSettled(() => { const id = setInterval(tick, 1000); return () => clearInterval(id); })`.
|
|
214
215
|
13. **Writes are staged** and commit on the next microtask. Event handlers need nothing
|
|
215
216
|
special; tests and imperative integration code must call `flush()` before observing
|
|
@@ -550,7 +551,7 @@ directory (default `src/`).
|
|
|
550
551
|
| `import ... from "solid-js/store"` or `"solid-js/web"` | stores/`merge`/`omit` from `"solid-js"`; `render`/`hydrate`/`Portal`/`Dynamic` from `"@solidjs/web"` |
|
|
551
552
|
| `import type { JSX } from "solid-js"` | `solid-js` exports no `JSX` namespace: markup types are `JSX.Element` from `"@solidjs/web"` (with `JSX.IntrinsicElements`, `JSX.CSSProperties`) or `Element` from `"solid-js"` — import the latter as `type Element as SolidElement` where the DOM `Element` is also used, or it shadows it <!-- upstream:jsx-namespace-absent --> |
|
|
552
553
|
| `createResource` | async `createMemo` + `<Loading>`/`<Errored>`; `refresh()`, `latest()`, `isPending()` |
|
|
553
|
-
| `createEffect(fn)` (one arg), `on(...)`, `createTrackedEffect` (deprecated in 2.0) <!-- upstream:tracked-effect-deprecated --> | `createEffect(compute, apply)`; deps belong in `compute`; one-time DOM work is `onSettled` |
|
|
554
|
+
| `createEffect(fn)` (one arg — dev throws `[MISSING_EFFECT_FN]` <!-- upstream:missing-effect-fn -->), `on(...)`, `createTrackedEffect` (deprecated in 2.0) <!-- upstream:tracked-effect-deprecated --> | `createEffect(compute, apply)`; deps belong in `compute`; one-time DOM work is `onSettled` |
|
|
554
555
|
| `onMount` | `onSettled(() => { ...; return cleanup })` — return the cleanup; `onCleanup`, memo/effect creation, and `flush()` throw inside the callback |
|
|
555
556
|
| `batch(...)` | delete it — writes auto-batch; `flush()` only to observe synchronously |
|
|
556
557
|
| `<Suspense>`, `<ErrorBoundary>`, `<SuspenseList>` | `<Loading>`, `<Errored>` (fallback gets an error *accessor*), `<Reveal>` |
|
|
@@ -582,6 +583,11 @@ When unsure about any API, verify against the official Solid 2.0 docs — fetcha
|
|
|
582
583
|
listed in `references/official-docs.md` next to the `solid-2` skill. Do not guess from
|
|
583
584
|
Solid 1.x or React memory.
|
|
584
585
|
|
|
586
|
+
`createOwner` is not public API either: since 2.0.0-rc.21 it is typed only through
|
|
587
|
+
`solid-js/internal` (a runtime export kept for the renderers) <!-- upstream:create-owner-internal --> — host a
|
|
588
|
+
scope with `createRoot()`, pass its `dispose` around as a plain function, and re-enter
|
|
589
|
+
with `runWithOwner(owner, …)`.
|
|
590
|
+
|
|
585
591
|
`createRenderEffect` exists in Solid 2 but is not a default. `storePath`
|
|
586
592
|
(the 1.x path-setter migration helper) is no longer exported from `solid-js` as of
|
|
587
593
|
2.0.0-rc.9 — convert path setters to draft setters instead of importing it from
|
|
@@ -307,7 +307,10 @@ returns the value it set. Dev throws `effect callback returned an invalid cleanu
|
|
|
307
307
|
production throws a `TypeError` on the next run, and both halt the whole
|
|
308
308
|
reactive system (`[REACTIVITY_HALTED]`). TypeScript reports it as TS2345; a JS project
|
|
309
309
|
gets no warning. The cleanup of an effect is the `apply` return value — `onCleanup`
|
|
310
|
-
inside `apply` has no owner and never runs (`[NO_OWNER_CLEANUP]`).
|
|
310
|
+
inside `apply` has no owner and never runs (`[NO_OWNER_CLEANUP]`). The two-phase
|
|
311
|
+
signature itself is enforced: `createEffect(compute)` with no apply function throws
|
|
312
|
+
`[MISSING_EFFECT_FN]` in dev <!-- upstream:missing-effect-fn --> (prod dies on the same call with an uncoded
|
|
313
|
+
`TypeError`).
|
|
311
314
|
|
|
312
315
|
**Effects never compare.** `apply` runs on every re-run of `compute`, whether or not the
|
|
313
316
|
computed value changed; there is no `equals` on an effect. When equal results should skip
|
|
@@ -330,6 +333,13 @@ intercepted with the bundle form `createEffect(compute, { effect, error })`. Ski
|
|
|
330
333
|
initial run with `{ defer: true }` — the `on(deps, fn, { defer: true })` replacement;
|
|
331
334
|
the effect first runs on the next change.
|
|
332
335
|
|
|
336
|
+
When the side effect should fire **once per arming** rather than on every change —
|
|
337
|
+
"run this the first time the value crosses the threshold" — use `createReaction(fn)`
|
|
338
|
+
from `solid-js`: it returns a tracker; `fn` runs once after a source read inside a
|
|
339
|
+
`track(() => …)` call changes, then stays silent until the tracker is called again
|
|
340
|
+
(re-arm from inside `fn` to keep listening). Nothing runs at creation, and changes
|
|
341
|
+
made while unarmed are ignored. <!-- upstream:create-reaction -->
|
|
342
|
+
|
|
333
343
|
A two-phase effect whose apply only calls a local signal setter is "state + effect" in
|
|
334
344
|
disguise — formally legal Solid 2, still rule 4 (`solid2-kit check` flags it). The reset
|
|
335
345
|
form of a writable derivation replaces it, and moves the source read to the read site
|
|
@@ -452,7 +462,9 @@ return <StoryDetail story={story} />;
|
|
|
452
462
|
`affects(item, "quantity")`) or `isPending(() => todos.length)` dims only what
|
|
453
463
|
that read depends on. A hold with no feedback at all is `[SILENT_HOLD]` under
|
|
454
464
|
attribution — always pair a held write with one of these questions, an
|
|
455
|
-
optimistic value, or `affects()`.
|
|
465
|
+
optimistic value, or `affects()`. `affects` keys address store leaves only:
|
|
466
|
+
`affects(accessor, "quantity")` throws `[INVALID_AFFECTS_TARGET]` in dev
|
|
467
|
+
<!-- upstream:invalid-affects-target --> — the keyed form needs a store (or store row); a bare accessor takes no key.
|
|
456
468
|
- Default navigation **holds**. `selectedId()` and the old story stay put until
|
|
457
469
|
the new answer lands, so the highlight never points at the wrong content.
|
|
458
470
|
`latest(selectedId)` is the opt-in when the design wants the highlight to move
|
|
@@ -478,7 +490,9 @@ return <StoryDetail story={story} />;
|
|
|
478
490
|
`fallback={(error, reset) => ...}`. The boundary **heals** when the source succeeds
|
|
479
491
|
again (refresh, live reconnect, input change) — it is graph status, not a terminal
|
|
480
492
|
React ErrorBoundary. `reset` retries the collected *data sources*, not a UI remount.
|
|
481
|
-
- Refetch: `refresh(results)`.
|
|
493
|
+
- Refetch: `refresh(results)`. `refresh` takes a source accessor or a refreshable
|
|
494
|
+
store only — anything else (a plain function included) throws `[INVALID_REFRESH_TARGET]`
|
|
495
|
+
in dev <!-- upstream:invalid-refresh-target -->, and prod silently accepts it. In-flight indicator: `isPending(results)` (or
|
|
482
496
|
`isPending(() => results())`). Freshest in-flight value for a preview:
|
|
483
497
|
`latest(results)`. `latest` is not a null-safe probe: before the source's first value
|
|
484
498
|
it throws `NotReadyError` in every scope (since 2.0.0-rc.9 also in event handlers and
|
|
@@ -551,7 +565,7 @@ functions (middleware, request setup) reported via
|
|
|
551
565
|
`renderToString` / `renderToStream`'s first pass is reported `render` / `failed`
|
|
552
566
|
before rethrow. <!-- upstream:report-request-failure --> A monitoring SDK's `init()` that
|
|
553
567
|
registers this hook must load before the server graph — put it in the plugin's
|
|
554
|
-
`start: {
|
|
568
|
+
`start: { serverSetup: "./src/instrument.ts" }`, not at the top of an entry (see
|
|
555
569
|
[Production observability](#production-observability-the-observe-build)).
|
|
556
570
|
|
|
557
571
|
`render` / `hydrate` accept a per-root `onError` that wins over the ambient hook —
|
|
@@ -755,7 +769,8 @@ list). An in-flight action does not freeze unrelated writes. Collecting failed
|
|
|
755
769
|
actions to replay is a design choice, not something the runtime requires.
|
|
756
770
|
|
|
757
771
|
Ordinary signal/store writes inside an action are held until it settles. Never call
|
|
758
|
-
`flush()` inside an action. Invoke actions from handlers, not from component/computation bodies
|
|
772
|
+
`flush()` inside an action. Invoke actions from handlers, not from component/computation bodies (dev warns
|
|
773
|
+
`[ACTION_CALLED_IN_OWNED_SCOPE]` <!-- upstream:action-in-owned-scope -->).
|
|
759
774
|
Do not set a `submitted` signal and watch it from an effect — that work belongs in the
|
|
760
775
|
handler or the `action`.
|
|
761
776
|
|
|
@@ -767,7 +782,9 @@ leaves an empty list once the action settles, with no warning. <!-- upstream:opt
|
|
|
767
782
|
from the function form — `createOptimisticStore(() => api.list(), [])` refreshed
|
|
768
783
|
after the `yield`, or `createOptimisticStore(() => base.todos, [])` over a separate
|
|
769
784
|
`createStore` that the action writes the confirmed value into. Keep the value form for
|
|
770
|
-
in-flight flags.
|
|
785
|
+
in-flight flags. A write against a function-form source whose first answer has not
|
|
786
|
+
landed yet is not guessed at all — dev warns `[OPTIMISTIC_WRITE_BEFORE_LOAD]`
|
|
787
|
+
<!-- upstream:optimistic-write-before-load -->; let the first answer land before writing.
|
|
771
788
|
|
|
772
789
|
`createOptimistic` / `createOptimisticStore` are for a tentative value during an
|
|
773
790
|
active mutation, not a local editing session (use a writable derivation or a plain
|
|
@@ -1092,7 +1109,11 @@ do not `return () => cleanup`. Put owned setup in a **directive factory** (like
|
|
|
1092
1109
|
`onCleanup` throws there (`[CLEANUP_IN_FORBIDDEN_SCOPE]`), creating a memo or effect
|
|
1093
1110
|
throws (`[PRIMITIVE_IN_FORBIDDEN_SCOPE]`), and so does `flush()` — each halts the
|
|
1094
1111
|
reactive system in dev. Return the cleanup; create effects and memos in the component
|
|
1095
|
-
body, next to the `onSettled` call, not inside it.
|
|
1112
|
+
body, next to the `onSettled` call, not inside it. A pending async read inside the
|
|
1113
|
+
callback warns `[PENDING_ASYNC_FORBIDDEN_SCOPE]` <!-- upstream:pending-async-forbidden-scope --> — the callback is not a
|
|
1114
|
+
computation, so nothing re-runs it when the answer lands. Register `onSettled` in the
|
|
1115
|
+
body, not out-of-band after an `await`: a cleanup returned from an unowned registration
|
|
1116
|
+
warns `[SETTLED_CLEANUP_UNOWNED]` <!-- upstream:settled-cleanup-unowned --> and never runs.
|
|
1096
1117
|
|
|
1097
1118
|
```tsx
|
|
1098
1119
|
// WRONG — the mechanical 1.x port of onMount + onCleanup
|
|
@@ -1117,6 +1138,12 @@ component body or the compute phase, or attach them to an owner captured with
|
|
|
1117
1138
|
`getOwner()` in the body via `runWithOwner(owner, …)`.
|
|
1118
1139
|
<!-- upstream:primitive-in-effect-callback -->
|
|
1119
1140
|
|
|
1141
|
+
`createOwner` is not public API: since rc.21 it is typed only through
|
|
1142
|
+
`solid-js/internal`, as a runtime export kept for the renderers
|
|
1143
|
+
<!-- upstream:create-owner-internal -->. Host a scope with `createRoot()` and pass its `dispose` argument
|
|
1144
|
+
around as a plain function (a detached `owner.dispose` is a method and throws unbound
|
|
1145
|
+
<!-- upstream:ownerless-and-disposed -->); re-enter the scope with `runWithOwner(owner, …)`.
|
|
1146
|
+
|
|
1120
1147
|
### Per-value SSR policy: `ssrSource`
|
|
1121
1148
|
|
|
1122
1149
|
`clientOnly` splits a *component*; `ssrSource` keeps one *value* off the server,
|
|
@@ -1246,13 +1273,23 @@ Always-on dev checks include misplaced reads
|
|
|
1246
1273
|
for a first read made after an `await` in an async compute — V8 engines only), misplaced writes
|
|
1247
1274
|
(`[REACTIVE_WRITE_IN_OWNED_SCOPE]` — since rc.9 also for store setters called in a
|
|
1248
1275
|
component or root body <!-- upstream:store-write-owned-scope -->, `[ASYNC_STORE_SETTER]` for a store setter callback that returns
|
|
1249
|
-
a promise <!-- upstream:async-store-setter-throws -->, `[FLUSH_IN_ACTION]`,
|
|
1276
|
+
a promise <!-- upstream:async-store-setter-throws -->, `[FLUSH_IN_ACTION]`,
|
|
1277
|
+
`[ACTION_CALLED_IN_OWNED_SCOPE]` for an `action()` invoked from a component body or
|
|
1278
|
+
computation <!-- upstream:action-in-owned-scope -->, `[SERVER_WRITE]`,
|
|
1250
1279
|
and since rc.17 `[STORE_WRITE_OUTSIDE_SETTER]` for a write to the store proxy itself
|
|
1251
1280
|
<!-- upstream:store-write-outside-setter -->), misplaced bindings
|
|
1252
1281
|
(`[UNCOMMITTED_INPUT_OVERWRITTEN]` — a `value` / `checked` binding re-applied its
|
|
1253
1282
|
committed value over uncommitted user input <!-- upstream:uncommitted-input-overwritten -->),
|
|
1254
|
-
`[ASYNC_OUTSIDE_LOADING_BOUNDARY]` when a tracked read has no boundary above it,
|
|
1255
|
-
`[LOADING_ON_OUTSIDE_HOLD]` when a `<Loading on>` boundary's data is also read outside it
|
|
1283
|
+
`[ASYNC_OUTSIDE_LOADING_BOUNDARY]` when a tracked read has no boundary above it,
|
|
1284
|
+
`[LOADING_ON_OUTSIDE_HOLD]` when a `<Loading on>` boundary's data is also read outside it,
|
|
1285
|
+
`[LOADING_ON_ACCESSOR]` when a `<Loading on>` receives a function instead of the value
|
|
1286
|
+
(the boundary never calls it, so it never re-arms; since rc.20) <!-- upstream:loading-on-accessor -->, and
|
|
1287
|
+
since rc.21 `[CAUGHT_REACTIVE_READ]` when a computation catches a reactive read's throw
|
|
1288
|
+
itself and completes with a value — the catch masks the load or hides the error from the
|
|
1289
|
+
boundaries <!-- upstream:caught-reactive-read -->. Ownerless creation warns rather than throws: `[NO_OWNER_EFFECT]`
|
|
1290
|
+
for an effect created outside any root or component, `[NO_OWNER_BOUNDARY]` for a
|
|
1291
|
+
boundary invoked outside a reactive context, and `[RUN_WITH_DISPOSED_OWNER]` for
|
|
1292
|
+
`runWithOwner` on a disposed owner <!-- upstream:ownerless-and-disposed --> — none of them is ever disposed.
|
|
1256
1293
|
Each entry carries a stable `[CODE]`, what the runtime observed, an owner chain
|
|
1257
1294
|
(`in <App> › <Cart> › <LineItem>`), and — since rc.16, under `vite dev` — an
|
|
1258
1295
|
`at src/Cart.tsx:12:5` line naming where the scope was created (the compiler's
|
|
@@ -1344,7 +1381,8 @@ first), `[ABANDONED_FLIGHTS]` (a source re-asked on every keystroke, answers thr
|
|
|
1344
1381
|
— debounce at the handler), `[STACKED_HOLDS]` (repeated clicks piling into one hold),
|
|
1345
1382
|
`[FALLBACK_FLASH]` (a fallback shown under 150ms), `[WASTED_RECOMPUTE]` (a scope whose
|
|
1346
1383
|
runs mostly compared equal — narrow its reads upstream), `[GRAPH_GROWTH]` (the graph grows
|
|
1347
|
-
on every visit to a route — an undisposed root or subscription),
|
|
1384
|
+
on every visit to a route — an undisposed root or subscription), `[HOT_SCOPE_FANOUT]`
|
|
1385
|
+
(many scopes hot from one root cause), and `[OPTIMISTIC_REVERTED]`
|
|
1348
1386
|
(info: a guess the screen showed was replaced). `costs()` and `feedback()` (named imports)
|
|
1349
1387
|
rank the session worst-first; `attribution.history("hold")` / `("waterfall")` /
|
|
1350
1388
|
`("navigation")` / `("interaction")` hold the fact tables behind the verdicts (each hold
|
|
@@ -1565,10 +1603,15 @@ production too (observe build; a no-op on the prod build).
|
|
|
1565
1603
|
- **Instrumentation order.** A monitoring SDK's `init()` (and `configureServerErrors`)
|
|
1566
1604
|
must run before the modules it patches load. `import "./instrument"` at the top of an
|
|
1567
1605
|
entry does not achieve that in ESM (static imports are hoisted in dependency order);
|
|
1568
|
-
the plugin's `start: {
|
|
1569
|
-
module before anything else in the server graph —
|
|
1570
|
-
`
|
|
1571
|
-
|
|
1606
|
+
the plugin's `start: { serverSetup: "./src/instrument.ts" }` awaits that server-only
|
|
1607
|
+
module before anything else in the server graph — the `node` entry too:
|
|
1608
|
+
`dist/server/node.js` awaits `./server.js` (which awaits the
|
|
1609
|
+
setup module) and then loads `node-runtime.js`, so deploy both files. The option was
|
|
1610
|
+
renamed from `start.instrument` between vite-plugin next.52 and next.57 — the plugin
|
|
1611
|
+
throws on the old key <!-- upstream:start-server-setup -->. The sibling seam
|
|
1612
|
+
`start: { serverRenderSetup: "./src/render-setup.ts" }` runs per request immediately
|
|
1613
|
+
before SSR — `(event, App) => Component | void` — for integrations that must prepare
|
|
1614
|
+
a per-request app instance before the render. Failures the
|
|
1572
1615
|
handler contains itself reach the hook as `{ kind: "request", handling: "failed" }`.
|
|
1573
1616
|
The client-side counterpart is `start: { clientSetup: "./src/client-setup.ts" }`: a
|
|
1574
1617
|
browser module run (and awaited, top-level `await` allowed) before `hydrate` / `render`,
|
|
@@ -1700,7 +1743,10 @@ plain `<a href={Router.paths.about}>` (or `useNavigate`); there is no `<A>` /
|
|
|
1700
1743
|
`<Navigate>` / `<HashRouter>` / `<FileRoutes />`. Do not assign
|
|
1701
1744
|
`window.location.href` or call `history.pushState` for in-app navigation.
|
|
1702
1745
|
Session location is `useLocation` / `useParams`,
|
|
1703
|
-
not `Router.paths`.
|
|
1746
|
+
not `Router.paths`. `useMatch(() => "/docs/:page")` tests a pattern against the
|
|
1747
|
+
current pathname without a route existing for it — the memo answers the match (params
|
|
1748
|
+
typed from the pattern) or nothing; that is the breadcrumb / section-highlight read
|
|
1749
|
+
<!-- upstream:router-use-match -->.
|
|
1704
1750
|
|
|
1705
1751
|
**Route `preload` starts reads; the page reads them in a memo.** `preload` runs when
|
|
1706
1752
|
the route matches (and ahead of a click under a `preloadLinks` strategy <!-- upstream:preload-links-opt-in -->), so it should kick off the query and return
|
|
@@ -2052,9 +2098,13 @@ every POST call as one). `live(GET(fn))` is the same declaration spelled out —
|
|
|
2052
2098
|
component rendered into a document that reads an *undeclared* async iterable still
|
|
2053
2099
|
producing after 5s is `[SSR_UNDECLARED_LIVE_SOURCE]` in dev — declare it `live()` (the
|
|
2054
2100
|
document takes the first value and closes it; the client connects after hydration) or
|
|
2055
|
-
bound the source. `broadcast(fn)`
|
|
2101
|
+
bound the source. `broadcast(fn)` is `live()` for one answer shared across
|
|
2056
2102
|
every viewer — the server runs the generator once per argument set instead of once per
|
|
2057
|
-
connection.
|
|
2103
|
+
connection. In a router app, `liveQuery(fn, "key")` from `@solidjs/router` declares
|
|
2104
|
+
the `live()` server function itself and keeps one connection per key, shared by every
|
|
2105
|
+
consumer — when several components need the same stream, declare it once with
|
|
2106
|
+
`liveQuery` instead of hoisting a hand-rolled `live()` declaration and sharing code
|
|
2107
|
+
<!-- upstream:router-live-query -->.
|
|
2058
2108
|
|
|
2059
2109
|
```ts
|
|
2060
2110
|
// src/data/auction.ts
|
|
@@ -2190,7 +2240,7 @@ how to reuse. Prefer the form on the right.
|
|
|
2190
2240
|
| `createEffect(() => user, (u) => { log(u.name); })` | `createEffect(() => user.name, (name) => { log(name); })` |
|
|
2191
2241
|
| `createEffect(() => title(), (t) => (document.title = t))` / `(v) => setX(v)` | `(t) => { document.title = t; }` — apply returns a cleanup or nothing; any other return value halts reactivity. An apply that only calls a local setter is rule 4 even with braces (`solid2-kit check` flags it): use a (writable) derivation |
|
|
2192
2242
|
| `<Loading fallback={<PageSkeleton />}>{/* header + data */}</Loading>` | wrap only the data slot; chrome stays outside |
|
|
2193
|
-
| `<Loading on={id} fallback={...}>` (the accessor), or `` on={`${a()}/${b()}`} `` to key several inputs | `on={id()}` / `on={[a(), b()]}` — `on` is a tracked dependency list, not a compared key: a bare accessor is never read (`solid2-kit check` flags it), and an array is the several-inputs form <!-- upstream:loading-on-dependency-list --> |
|
|
2243
|
+
| `<Loading on={id} fallback={...}>` (the accessor), or `` on={`${a()}/${b()}`} `` to key several inputs | `on={id()}` / `on={[a(), b()]}` — `on` is a tracked dependency list, not a compared key: a bare accessor is never read (`solid2-kit check` flags it; dev warns `[LOADING_ON_ACCESSOR]` since rc.20 <!-- upstream:loading-on-accessor -->), and an array is the several-inputs form <!-- upstream:loading-on-dependency-list --> |
|
|
2194
2244
|
| `setCount(count() + 1)` when writes can batch | `setCount((c) => c + 1)` |
|
|
2195
2245
|
| `setHandler(fn)` to store a function | `setHandler(() => fn)` (otherwise `fn` is an updater) |
|
|
2196
2246
|
| `{user() ? <P user={user()!} /> : <SignIn />}` | `<Show when={user()}>{(u) => <P user={u()} />}</Show>` |
|
|
@@ -2298,7 +2348,7 @@ how to reuse. Prefer the form on the right.
|
|
|
2298
2348
|
| `attribution.enable()` unguarded in app code, or `enable()` with the default `log: true` left on | `if (isDev) attribution.enable({ log: false })` — on the observe build an unguarded `enable()` records in production; prefer the `/__solid/diagnostics` session (`begin` enables, `end` disables) so app code carries nothing |
|
|
2299
2349
|
| `solid({ observe: true })` added "to see diagnostics in dev" | `vite dev` is always the dev build; `observe: true` is the production-observability opt-in (observe condition + `sourceNames` for `vite build`/preview <!-- upstream:source-names-option -->) |
|
|
2300
2350
|
| `configureServerErrors({ onError: (e) => { report(e); return e; } })` | return nothing or a reference (`new Error(\`ref ${id}\`)`) — the return value replaces the sanitized wire value; the error itself leaks message/stack/secrets |
|
|
2301
|
-
| `import "./instrument"` at the top of the server entry for a monitoring SDK | `start: {
|
|
2351
|
+
| `import "./instrument"` at the top of the server entry for a monitoring SDK | `start: { serverSetup: "./src/instrument.ts" }` — ESM hoists static imports in dependency order, so the entry's own deps load first (the `node` entry wraps it too: deploy `node.js` with `server.js`; the pre-rename spelling `start.instrument` throws in the plugin). Browser-side init before `hydrate` / `render` is `start: { clientSetup: "./src/client-setup.ts" }` |
|
|
2302
2352
|
| Express/middleware injecting `traceparent` / trace headers into responses | the runtime carries a sampled or provided trace on `Server-Timing` + `<meta>`; forward downstream with `getTraceContext()?.entries`; SDKs use `OBSERVE?.server.trace.provide` |
|
|
2303
2353
|
| `OBSERVE.records.subscribe("call", (e) => setStats(...))` | listeners run synchronously inside the runtime and must not write signals; collect into a plain buffer and drain from outside |
|
|
2304
2354
|
| `import { storePath } from "solid-js"` | gone from `solid-js` (rc.9); write draft setters `setState((d) => { d.user.name = "Grace"; })` <!-- upstream:store-path-removed --> |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid2-agent-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Teach AI coding agents (Cursor, Claude Code) to write correct Solid 2.0 instead of React or Solid 1.x — always-applied rules, an agent skill, and a mechanical pattern gate.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|