@nifrajs/web-solid 2.1.0 → 2.3.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.
Files changed (50) hide show
  1. package/README.md +3 -3
  2. package/dist/await.d.ts +2 -2
  3. package/dist/await.js +3 -3
  4. package/dist/client.d.ts +4 -4
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +19 -11
  7. package/dist/client.js.map +1 -1
  8. package/dist/compose.d.ts +4 -1
  9. package/dist/compose.d.ts.map +1 -1
  10. package/dist/compose.js +21 -3
  11. package/dist/compose.js.map +1 -1
  12. package/dist/content.d.ts +2 -2
  13. package/dist/content.js +2 -2
  14. package/dist/error.d.ts +1 -1
  15. package/dist/error.js +2 -2
  16. package/dist/fetcher.d.ts +4 -4
  17. package/dist/fetcher.js +4 -4
  18. package/dist/fn.d.ts +29 -0
  19. package/dist/fn.d.ts.map +1 -0
  20. package/dist/fn.js +28 -0
  21. package/dist/fn.js.map +1 -0
  22. package/dist/i18n.d.ts +1 -1
  23. package/dist/i18n.js +1 -1
  24. package/dist/image.d.ts +3 -3
  25. package/dist/image.js +1 -1
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +7 -7
  28. package/dist/mdx-runtime.js +2 -2
  29. package/dist/mdx.js +5 -5
  30. package/dist/query.d.ts +2 -2
  31. package/dist/query.js +2 -2
  32. package/dist/router.d.ts +45 -0
  33. package/dist/router.d.ts.map +1 -0
  34. package/dist/router.js +60 -0
  35. package/dist/router.js.map +1 -0
  36. package/package.json +16 -5
  37. package/src/await.ts +3 -3
  38. package/src/client.ts +22 -12
  39. package/src/compose.ts +23 -3
  40. package/src/content.ts +2 -2
  41. package/src/error.ts +2 -2
  42. package/src/fetcher.ts +4 -4
  43. package/src/fn.ts +42 -0
  44. package/src/i18n.ts +1 -1
  45. package/src/image.ts +3 -3
  46. package/src/index.ts +7 -7
  47. package/src/mdx-runtime.ts +2 -2
  48. package/src/mdx.ts +5 -5
  49. package/src/query.ts +2 -2
  50. package/src/router.ts +85 -0
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @nifrajs/web-solid
2
2
 
3
- Solid render adapter for @nifrajs/web — SSR + hydration + the Solid Babel build plugin.
3
+ Solid render adapter for @nifrajs/web - SSR + hydration + the Solid Babel build plugin.
4
4
 
5
- Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework — one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
5
+ Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
6
6
 
7
7
  ## Install
8
8
 
@@ -19,7 +19,7 @@ MIT
19
19
 
20
20
  ## For AI agents
21
21
 
22
- Start with [`LLM.md`](./LLM.md) — this package's contract card (the exports you call + its footguns),
22
+ Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
23
23
  one cheap read instead of the whole corpus. For the wider framework: the repo's
24
24
  [`AGENTS.md`](../../AGENTS.md) is the copy-paste quick reference, and
25
25
  [`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
package/dist/await.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import type { Deferred } from "@nifrajs/web";
2
2
  /**
3
- * `@nifrajs/web-solid/await` — the `<Await>` primitive for deferred loader data (`defer()`). Isomorphic
3
+ * `@nifrajs/web-solid/await` - the `<Await>` primitive for deferred loader data (`defer()`). Isomorphic
4
4
  * and imports only `solid-js` + a type from `@nifrajs/web` (never `solid-js/web`'s server or the Babel
5
5
  * plugin), so route components can use it without dragging server/build code into the client bundle.
6
6
  * No JSX (the package builds with plain `tsc`).
7
7
  *
8
8
  * Solid streams the boundary natively: on the server `createResource` awaits the deferred promise,
9
9
  * `<Suspense>` flushes the fallback then the resolved content mid-stream, and Solid serializes the
10
- * resource value into its hydration data — so the client hydrates the streamed content without a
10
+ * resource value into its hydration data - so the client hydrates the streamed content without a
11
11
  * re-fetch (it reads `_$HY`, not the registry promise).
12
12
  */
13
13
  import { type JSX } from "solid-js";
package/dist/await.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
- * `@nifrajs/web-solid/await` — the `<Await>` primitive for deferred loader data (`defer()`). Isomorphic
2
+ * `@nifrajs/web-solid/await` - the `<Await>` primitive for deferred loader data (`defer()`). Isomorphic
3
3
  * and imports only `solid-js` + a type from `@nifrajs/web` (never `solid-js/web`'s server or the Babel
4
4
  * plugin), so route components can use it without dragging server/build code into the client bundle.
5
5
  * No JSX (the package builds with plain `tsc`).
6
6
  *
7
7
  * Solid streams the boundary natively: on the server `createResource` awaits the deferred promise,
8
8
  * `<Suspense>` flushes the fallback then the resolved content mid-stream, and Solid serializes the
9
- * resource value into its hydration data — so the client hydrates the streamed content without a
9
+ * resource value into its hydration data - so the client hydrates the streamed content without a
10
10
  * re-fetch (it reads `_$HY`, not the registry promise).
11
11
  */
12
12
  import { createComponent, createResource, Suspense } from "solid-js";
@@ -32,7 +32,7 @@ export function Await(props) {
32
32
  get children() {
33
33
  // Errored? Render `errorFallback`, else rethrow to an outer <ErrorBoundary>. Check `data.error`
34
34
  // BEFORE `data()` (which would rethrow). Otherwise: `data()` suspends until the resource
35
- // settles (on the client Solid reads the serialized value — no re-fetch).
35
+ // settles (on the client Solid reads the serialized value - no re-fetch).
36
36
  if (data.error !== undefined) {
37
37
  if (props.errorFallback)
38
38
  return props.errorFallback(data.error);
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MountRouterOptions, RenderProps } from "@nifrajs/web";
1
+ import { type MountRouterOptions, type RenderProps } from "@nifrajs/web";
2
2
  export { errorBoundary } from "./error.js";
3
3
  /** Hydrate a server-rendered Solid layout `chain` (with the loader `props`) inside `container`. */
4
4
  export declare function hydrate(chain: readonly unknown[], props: RenderProps, container: unknown): void;
@@ -6,13 +6,13 @@ export declare function hydrate(chain: readonly unknown[], props: RenderProps, c
6
6
  * Mount a Solid Router driven by the agnostic store. The first render *hydrates* the SSR'd chain. The
7
7
  * route's props are exposed as **getters over a signal** created inside the render root, so:
8
8
  *
9
- * - **Same route** (revalidation, a param change, an optimistic submit) — the snapshot signal is
9
+ * - **Same route** (revalidation, a param change, an optimistic submit) - the snapshot signal is
10
10
  * updated and only the components reading the changed props re-run; the layout chain stays mounted,
11
11
  * so **focus and scroll are preserved**. This is the case the old "dispose + re-render on every
12
12
  * navigation" implementation regressed.
13
- * - **Different route** — the matched chain genuinely changed (different page + layouts), so the root
13
+ * - **Different route** - the matched chain genuinely changed (different page + layouts), so the root
14
14
  * is disposed and the new chain is rendered. (Getter-props are a transparent reactive boundary, so
15
- * they don't shift Solid's structural hydration keys — unlike a `<Show>`, which would.)
15
+ * they don't shift Solid's structural hydration keys - unlike a `<Show>`, which would.)
16
16
  */
17
17
  export declare function mountRouter(options: MountRouterOptions): void;
18
18
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAgBnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAE/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAqD7D"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAiB,MAAM,cAAc,CAAA;AAgBvF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAE/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CA+D7D"}
package/dist/client.js CHANGED
@@ -1,16 +1,17 @@
1
+ import { searchOfChain } from "@nifrajs/web";
1
2
  /**
2
- * @nifrajs/web-solid/client — Solid client runtime. `hydrate` hydrates a single SSR'd route;
3
- * `mountRouter` hydrates the initial route then drives navigation through a Solid signal — so a
3
+ * @nifrajs/web-solid/client - Solid client runtime. `hydrate` hydrates a single SSR'd route;
4
+ * `mountRouter` hydrates the initial route then drives navigation through a Solid signal - so a
4
5
  * same-route update (revalidation, a param change, an optimistic submit) updates **in place** via
5
6
  * fine-grained reactivity, preserving the layout chain + focus + scroll. Runs against Solid's client
6
- * build; kept in its own entry so SSR code never ships to the client bundle. No JSX — Solid's package
7
+ * build; kept in its own entry so SSR code never ships to the client bundle. No JSX - Solid's package
7
8
  * build is plain `tsc`, so this uses Solid's runtime functions directly, like `compose`.
8
9
  */
9
10
  import { createSignal } from "solid-js";
10
11
  import { hydrate as solidHydrate, render as solidRender } from "solid-js/web";
11
12
  import { compose } from "./compose.js";
12
13
  import { setMountedRouter } from "./fetcher.js";
13
- // The `_error` boundary chain element — defined in its own module, re-exported here so nifra's client
14
+ // The `_error` boundary chain element - defined in its own module, re-exported here so nifra's client
14
15
  // codegen resolves it from `@nifrajs/web-solid/client` alongside `mountRouter`.
15
16
  export { errorBoundary } from "./error.js";
16
17
  /** Hydrate a server-rendered Solid layout `chain` (with the loader `props`) inside `container`. */
@@ -21,21 +22,21 @@ export function hydrate(chain, props, container) {
21
22
  * Mount a Solid Router driven by the agnostic store. The first render *hydrates* the SSR'd chain. The
22
23
  * route's props are exposed as **getters over a signal** created inside the render root, so:
23
24
  *
24
- * - **Same route** (revalidation, a param change, an optimistic submit) — the snapshot signal is
25
+ * - **Same route** (revalidation, a param change, an optimistic submit) - the snapshot signal is
25
26
  * updated and only the components reading the changed props re-run; the layout chain stays mounted,
26
27
  * so **focus and scroll are preserved**. This is the case the old "dispose + re-render on every
27
28
  * navigation" implementation regressed.
28
- * - **Different route** — the matched chain genuinely changed (different page + layouts), so the root
29
+ * - **Different route** - the matched chain genuinely changed (different page + layouts), so the root
29
30
  * is disposed and the new chain is rendered. (Getter-props are a transparent reactive boundary, so
30
- * they don't shift Solid's structural hydration keys — unlike a `<Show>`, which would.)
31
+ * they don't shift Solid's structural hydration keys - unlike a `<Show>`, which would.)
31
32
  */
32
33
  export function mountRouter(options) {
33
- const { router, routes, container } = options;
34
+ const { router, routes, searchSchemas, container } = options;
34
35
  setMountedRouter(router); // expose it to createFetcher/useFetchers (same page, client-only)
35
36
  const el = container;
36
37
  let dispose;
37
38
  let mountedRouteId = null;
38
- // The setter for the currently-mounted route's reactive props — same-route settles push through it.
39
+ // The setter for the currently-mounted route's reactive props - same-route settles push through it.
39
40
  let update = null;
40
41
  const mount = (first) => {
41
42
  const initial = router.snapshot();
@@ -43,9 +44,9 @@ export function mountRouter(options) {
43
44
  const renderer = first ? solidHydrate : solidRender;
44
45
  dispose = renderer(() => {
45
46
  // Signal owned by THIS render root (so it's never ownerless). `props` are getters over it; a
46
- // same-route settle calls `update(snapshot)` and the reading components update in place — no
47
+ // same-route settle calls `update(snapshot)` and the reading components update in place - no
47
48
  // recompose, so the layout chain + focus + scroll survive. Cast bridges
48
- // `exactOptionalPropertyTypes` (a getter is always present, returning `undefined` when idle —
49
+ // `exactOptionalPropertyTypes` (a getter is always present, returning `undefined` when idle -
49
50
  // the documented "absent on idle" semantics for `submission`).
50
51
  const [snapshot, setSnapshot] = createSignal(initial);
51
52
  update = setSnapshot;
@@ -59,6 +60,13 @@ export function mountRouter(options) {
59
60
  get pending() {
60
61
  return snapshot().pending;
61
62
  },
63
+ get search() {
64
+ // The SAME searchOfChain the server ran, over this snapshot's URL - a same-route search change
65
+ // updates in place (fine-grained), matching the SSR value on hydration.
66
+ const s = snapshot();
67
+ const idx = s.path.indexOf("?");
68
+ return searchOfChain(searchSchemas?.[s.routeId] ?? [], idx === -1 ? "" : s.path.slice(idx));
69
+ },
62
70
  get submission() {
63
71
  return snapshot().submission;
64
72
  },
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,cAAc,CAAA;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,sGAAsG;AACtG,gFAAgF;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,mGAAmG;AACnG,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB,EAAE,SAAkB;IACvF,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,SAAoB,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC7C,gBAAgB,CAAC,MAAM,CAAC,CAAA,CAAC,kEAAkE;IAC3F,MAAM,EAAE,GAAG,SAAoB,CAAA;IAE/B,IAAI,OAAiC,CAAA;IACrC,IAAI,cAAc,GAAkB,IAAI,CAAA;IACxC,oGAAoG;IACpG,IAAI,MAAM,GAAoE,IAAI,CAAA;IAElF,MAAM,KAAK,GAAG,CAAC,KAAc,EAAQ,EAAE;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QACjC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAA;QAChC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAA;QACnD,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE;YACtB,6FAA6F;YAC7F,6FAA6F;YAC7F,wEAAwE;YACxE,8FAA8F;YAC9F,+DAA+D;YAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;YACrD,MAAM,GAAG,WAAW,CAAA;YACpB,MAAM,KAAK,GAAG;gBACZ,IAAI,IAAI;oBACN,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAA;gBACxB,CAAC;gBACD,IAAI,UAAU;oBACZ,OAAO,QAAQ,EAAE,CAAC,UAAU,CAAA;gBAC9B,CAAC;gBACD,IAAI,OAAO;oBACT,OAAO,QAAQ,EAAE,CAAC,OAAO,CAAA;gBAC3B,CAAC;gBACD,IAAI,UAAU;oBACZ,OAAO,QAAQ,EAAE,CAAC,UAAU,CAAA;gBAC9B,CAAC;aACa,CAAA;YAChB,kGAAkG;YAClG,2FAA2F;YAC3F,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,EAAE,CAAA;QACxD,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC,CAAA;IAED,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAClC,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAM,CAAC,4CAA4C;QACzE,IAAI,QAAQ,CAAC,OAAO,KAAK,cAAc,EAAE,CAAC;YACxC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA,CAAC,wEAAwE;QAC7F,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,EAAE,CAAA,CAAC,qDAAqD;YACjE,KAAK,CAAC,KAAK,CAAC,CAAA;QACd,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/compose.d.ts CHANGED
@@ -3,7 +3,10 @@ import { type JSX } from "solid-js";
3
3
  /**
4
4
  * Fold a layout chain (outermost layout → page) into a single Solid tree: the page
5
5
  * (innermost) receives `props` (the loader data); each layout wraps the child via its
6
- * `children`. Shared by the server adapter (renderToString) and the client (hydrate).
6
+ * `children`. The whole tree is wrapped in a {@link SearchContext} provider carrying an accessor of the
7
+ * validated `search` (threaded through `RenderProps` identically on SSR + client), so `useSearch` reads
8
+ * the same value on both sides - no hydration mismatch. Shared by the server adapter (renderToString) and
9
+ * the client (hydrate).
7
10
  */
8
11
  export declare function compose(chain: readonly unknown[], props: RenderProps): () => JSX.Element;
9
12
  //# sourceMappingURL=compose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAEpE;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CASxF"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAMpE;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CAsBxF"}
package/dist/compose.js CHANGED
@@ -1,8 +1,14 @@
1
1
  import { createComponent } from "solid-js";
2
+ import { SearchContext } from "./router.js";
3
+ // Frozen empty search so a render with no search context has a stable provider value.
4
+ const EMPTY_SEARCH = Object.freeze({});
2
5
  /**
3
6
  * Fold a layout chain (outermost layout → page) into a single Solid tree: the page
4
7
  * (innermost) receives `props` (the loader data); each layout wraps the child via its
5
- * `children`. Shared by the server adapter (renderToString) and the client (hydrate).
8
+ * `children`. The whole tree is wrapped in a {@link SearchContext} provider carrying an accessor of the
9
+ * validated `search` (threaded through `RenderProps` identically on SSR + client), so `useSearch` reads
10
+ * the same value on both sides - no hydration mismatch. Shared by the server adapter (renderToString) and
11
+ * the client (hydrate).
6
12
  */
7
13
  export function compose(chain, props) {
8
14
  const last = chain.length - 1;
@@ -10,8 +16,20 @@ export function compose(chain, props) {
10
16
  for (let i = last - 1; i >= 0; i--) {
11
17
  const Layout = chain[i];
12
18
  const child = node;
13
- node = () => createComponent(Layout, { children: child() });
19
+ // Each layout receives its own loader data at its own index. Layouts are the chain's leading
20
+ // prefix, so `layoutData[i]` belongs to `chain[i]`; anything past that end (a client-only `_error`
21
+ // boundary marker, the page) reads `undefined` and is unaffected.
22
+ const layoutData = props.layoutData?.[i] ?? null;
23
+ node = () => createComponent(Layout, { data: layoutData, children: child() });
14
24
  }
15
- return node;
25
+ const inner = node;
26
+ // The provider `value` is an ACCESSOR reading `props.search` - a getter over the mount's snapshot on
27
+ // the client (so a same-route search change updates in place), a static value on SSR.
28
+ return () => createComponent(SearchContext.Provider, {
29
+ value: () => (props.search ?? EMPTY_SEARCH),
30
+ get children() {
31
+ return inner();
32
+ },
33
+ });
16
34
  }
17
35
  //# sourceMappingURL=compose.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,eAAe,EAAY,MAAM,UAAU,CAAA;AAEpE;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAsB,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAA2B,EAAE,KAAK,CAAC,CAAA;IACjG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAyC,CAAA;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,eAAe,EAAY,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,sFAAsF;AACtF,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEzE;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAsB,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAA2B,EAAE,KAAK,CAAC,CAAA;IACjG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAyC,CAAA;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAA;QAClB,6FAA6F;QAC7F,mGAAmG;QACnG,kEAAkE;QAClE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;QAChD,IAAI,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAA;IAClB,qGAAqG;IACrG,sFAAsF;IACtF,OAAO,GAAG,EAAE,CACV,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE;QACtC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,YAAY,CAA4B;QACtE,IAAI,QAAQ;YACV,OAAO,KAAK,EAAE,CAAA;QAChB,CAAC;KACF,CAAC,CAAA;AACN,CAAC"}
package/dist/content.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * `@nifrajs/web-solid/content` — render pre-rendered HTML (e.g. a `@nifrajs/content` collection entry's
2
+ * `@nifrajs/web-solid/content` - render pre-rendered HTML (e.g. a `@nifrajs/content` collection entry's
3
3
  * `.html`) into the DOM. Solid sets `innerHTML` reactively on a `<Dynamic>` element. Pairs with content
4
4
  * collections: `<Content html={entry.html} />`. No JSX (`createComponent`/`Dynamic`), so it builds with
5
5
  * plain `tsc`.
6
6
  *
7
7
  * Security: injects raw HTML, so `html` MUST be trusted (your own Markdown/content, rendered at
8
- * build/server time) — never pass user-supplied HTML without sanitizing it first.
8
+ * build/server time) - never pass user-supplied HTML without sanitizing it first.
9
9
  */
10
10
  import { type JSX } from "solid-js";
11
11
  export interface ContentProps {
package/dist/content.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * `@nifrajs/web-solid/content` — render pre-rendered HTML (e.g. a `@nifrajs/content` collection entry's
2
+ * `@nifrajs/web-solid/content` - render pre-rendered HTML (e.g. a `@nifrajs/content` collection entry's
3
3
  * `.html`) into the DOM. Solid sets `innerHTML` reactively on a `<Dynamic>` element. Pairs with content
4
4
  * collections: `<Content html={entry.html} />`. No JSX (`createComponent`/`Dynamic`), so it builds with
5
5
  * plain `tsc`.
6
6
  *
7
7
  * Security: injects raw HTML, so `html` MUST be trusted (your own Markdown/content, rendered at
8
- * build/server time) — never pass user-supplied HTML without sanitizing it first.
8
+ * build/server time) - never pass user-supplied HTML without sanitizing it first.
9
9
  */
10
10
  import { createComponent, mergeProps, splitProps } from "solid-js";
11
11
  import { Dynamic } from "solid-js/web";
package/dist/error.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Build an error-boundary chain element bound to `fallback` (a route's `_error` component). nifra's
3
3
  * client codegen inserts it before the page in the matched chain; a render error in the subtree renders
4
4
  * `fallback` with `{ data: { name, message } }` (via Solid's `<ErrorBoundary>`) instead of crashing.
5
- * DOM-transparent (renders its children directly — no wrapper element), so it never disturbs hydration.
5
+ * DOM-transparent (renders its children directly - no wrapper element), so it never disturbs hydration.
6
6
  */
7
7
  export declare function errorBoundary(fallback: unknown): unknown;
8
8
  //# sourceMappingURL=error.d.ts.map
package/dist/error.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `errorBoundary` — the Solid error-boundary chain element for nifra's `_error.tsx`. Its own module
2
+ * `errorBoundary` - the Solid error-boundary chain element for nifra's `_error.tsx`. Its own module
3
3
  * (imports only `solid-js`) so the client codegen can import it from `@nifrajs/web-solid/client` (which
4
4
  * re-exports it). No JSX (`createComponent`), so the package builds with plain `tsc`.
5
5
  */
@@ -8,7 +8,7 @@ import { createComponent, ErrorBoundary } from "solid-js";
8
8
  * Build an error-boundary chain element bound to `fallback` (a route's `_error` component). nifra's
9
9
  * client codegen inserts it before the page in the matched chain; a render error in the subtree renders
10
10
  * `fallback` with `{ data: { name, message } }` (via Solid's `<ErrorBoundary>`) instead of crashing.
11
- * DOM-transparent (renders its children directly — no wrapper element), so it never disturbs hydration.
11
+ * DOM-transparent (renders its children directly - no wrapper element), so it never disturbs hydration.
12
12
  */
13
13
  export function errorBoundary(fallback) {
14
14
  const Fallback = fallback;
package/dist/fetcher.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ClientRouter, Fetcher, FetcherState } from "@nifrajs/web";
2
2
  /**
3
- * `@nifrajs/web-solid/fetcher` — Solid bindings for concurrent fetchers. `createFetcher(key)` bridges an
3
+ * `@nifrajs/web-solid/fetcher` - Solid bindings for concurrent fetchers. `createFetcher(key)` bridges an
4
4
  * independent {@link Fetcher}'s `subscribe`/`snapshot` store into a Solid signal (the pattern the F16
5
5
  * spike confirmed) and returns its reactive state accessor plus `load`/`submit`; `useFetchers()`
6
6
  * bridges the whole live collection. Imports only `solid-js` (never `solid-js/web`), so route
@@ -8,11 +8,11 @@ import type { ClientRouter, Fetcher, FetcherState } from "@nifrajs/web";
8
8
  * bundle. No JSX (the package builds with plain `tsc`).
9
9
  *
10
10
  * The router that owns the fetchers registers itself via `setMountedRouter` from `mountRouter`. On the
11
- * server (no mount) the accessors return an idle state — fetchers are client-only — so SSR markup is
11
+ * server (no mount) the accessors return an idle state - fetchers are client-only - so SSR markup is
12
12
  * unchanged and the first client render after `mountRouter` takes over cleanly.
13
13
  */
14
14
  import { type Accessor } from "solid-js";
15
- /** Register (or clear) the router that owns fetchers — called by `mountRouter`. Not for app use. */
15
+ /** Register (or clear) the router that owns fetchers - called by `mountRouter`. Not for app use. */
16
16
  export declare function setMountedRouter(router: ClientRouter | undefined): void;
17
17
  /** A fetcher's reactive state accessor plus its imperative `load`/`submit`. */
18
18
  export interface FetcherHandle {
@@ -30,7 +30,7 @@ export interface FetcherHandle {
30
30
  */
31
31
  export declare function createFetcher(key: string): FetcherHandle;
32
32
  /**
33
- * Bind the whole live fetcher collection — for a global busy view. Returns a reactive accessor; read
33
+ * Bind the whole live fetcher collection - for a global busy view. Returns a reactive accessor; read
34
34
  * each entry's `.snapshot()` for its state. Updates whenever any fetcher transitions or one is created.
35
35
  */
36
36
  export declare function useFetchers(): Accessor<readonly Fetcher[]>;
package/dist/fetcher.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-solid/fetcher` — Solid bindings for concurrent fetchers. `createFetcher(key)` bridges an
2
+ * `@nifrajs/web-solid/fetcher` - Solid bindings for concurrent fetchers. `createFetcher(key)` bridges an
3
3
  * independent {@link Fetcher}'s `subscribe`/`snapshot` store into a Solid signal (the pattern the F16
4
4
  * spike confirmed) and returns its reactive state accessor plus `load`/`submit`; `useFetchers()`
5
5
  * bridges the whole live collection. Imports only `solid-js` (never `solid-js/web`), so route
@@ -7,13 +7,13 @@
7
7
  * bundle. No JSX (the package builds with plain `tsc`).
8
8
  *
9
9
  * The router that owns the fetchers registers itself via `setMountedRouter` from `mountRouter`. On the
10
- * server (no mount) the accessors return an idle state — fetchers are client-only — so SSR markup is
10
+ * server (no mount) the accessors return an idle state - fetchers are client-only - so SSR markup is
11
11
  * unchanged and the first client render after `mountRouter` takes over cleanly.
12
12
  */
13
13
  import { createSignal, onCleanup } from "solid-js";
14
14
  // The active client router (set by `mountRouter`). Module-scoped: one app per page, client-only.
15
15
  let mountedRouter;
16
- /** Register (or clear) the router that owns fetchers — called by `mountRouter`. Not for app use. */
16
+ /** Register (or clear) the router that owns fetchers - called by `mountRouter`. Not for app use. */
17
17
  export function setMountedRouter(router) {
18
18
  mountedRouter = router;
19
19
  }
@@ -34,7 +34,7 @@ export function createFetcher(key) {
34
34
  return { state, load: noopAsync, submit: noopAsync };
35
35
  }
36
36
  /**
37
- * Bind the whole live fetcher collection — for a global busy view. Returns a reactive accessor; read
37
+ * Bind the whole live fetcher collection - for a global busy view. Returns a reactive accessor; read
38
38
  * each entry's `.snapshot()` for its state. Updates whenever any fetcher transitions or one is created.
39
39
  */
40
40
  export function useFetchers() {
package/dist/fn.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `@nifrajs/web-solid/fn` - Solid binding for a server function's pending/error state.
3
+ *
4
+ * Calling a server function needs no hook: the client stub is `(input) => Promise<Output>`. This adds
5
+ * the part a component usually wants around it - in flight, last result, last error - and nothing more.
6
+ *
7
+ * The state machine is `@nifrajs/web`'s `createServerFnStore`, shared with every other adapter, so
8
+ * "is it pending" has one answer rather than five that drift. This file contributes only a signal fed by the store.
9
+ */
10
+ import type { ServerFnReference } from "@nifrajs/web/fn";
11
+ import { type ServerFnState } from "@nifrajs/web/fn-state";
12
+ import { type Accessor } from "solid-js";
13
+ /** A server function's state accessor plus the call itself. */
14
+ export interface ServerFnHandle<Input, Output> {
15
+ /** Reactive state - read it inside JSX so Solid tracks it. */
16
+ readonly state: Accessor<ServerFnState<Output>>;
17
+ /** Invoke it. Records state, and rejects on failure - attach `.catch` if you only render state. */
18
+ readonly call: (input: Input) => Promise<Output>;
19
+ /** Back to idle. */
20
+ readonly reset: () => void;
21
+ }
22
+ /**
23
+ * Track one server function's call state.
24
+ *
25
+ * const addTodo = useServerFn(fns.addTodo)
26
+ * <button disabled={addTodo.state().pending} onClick={() => addTodo.call({ text }).catch(() => {})}>
27
+ */
28
+ export declare function useServerFn<Input, Output>(fn: ServerFnReference<Input, Output>): ServerFnHandle<Input, Output>;
29
+ //# sourceMappingURL=fn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fn.d.ts","sourceRoot":"","sources":["../src/fn.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC/E,OAAO,EAAE,KAAK,QAAQ,EAA2B,MAAM,UAAU,CAAA;AAEjE,+DAA+D;AAC/D,MAAM,WAAW,cAAc,CAAC,KAAK,EAAE,MAAM;IAC3C,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/C,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EACvC,EAAE,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,GACnC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAS/B"}
package/dist/fn.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@nifrajs/web-solid/fn` - Solid binding for a server function's pending/error state.
3
+ *
4
+ * Calling a server function needs no hook: the client stub is `(input) => Promise<Output>`. This adds
5
+ * the part a component usually wants around it - in flight, last result, last error - and nothing more.
6
+ *
7
+ * The state machine is `@nifrajs/web`'s `createServerFnStore`, shared with every other adapter, so
8
+ * "is it pending" has one answer rather than five that drift. This file contributes only a signal fed by the store.
9
+ */
10
+ import { createServerFnStore } from "@nifrajs/web/fn-state";
11
+ import { createSignal, onCleanup } from "solid-js";
12
+ /**
13
+ * Track one server function's call state.
14
+ *
15
+ * const addTodo = useServerFn(fns.addTodo)
16
+ * <button disabled={addTodo.state().pending} onClick={() => addTodo.call({ text }).catch(() => {})}>
17
+ */
18
+ export function useServerFn(fn) {
19
+ const store = createServerFnStore(fn);
20
+ // Seeded from the store, not from the idle constant. They are the same value here - the store is
21
+ // created one line up and cannot have moved - so this is correctness that does not depend on that
22
+ // staying true. Svelte had exactly this line reading the constant, and when its subscription turned
23
+ // out to be lazy the first render showed idle for a call that had already finished.
24
+ const [state, setState] = createSignal(store.snapshot());
25
+ onCleanup(store.subscribe(() => setState(() => store.snapshot())));
26
+ return { state, call: store.call, reset: store.reset };
27
+ }
28
+ //# sourceMappingURL=fn.js.map
package/dist/fn.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fn.js","sourceRoot":"","sources":["../src/fn.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,mBAAmB,EAAsB,MAAM,uBAAuB,CAAA;AAC/E,OAAO,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAYjE;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,EAAoC;IAEpC,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAmC,CAAC,CAAA;IACtE,iGAAiG;IACjG,kGAAkG;IAClG,oGAAoG;IACpG,oFAAoF;IACpF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAwB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC/E,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;IAClE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAA;AACxD,CAAC"}
package/dist/i18n.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-solid/i18n` — Solid bindings for `@nifrajs/i18n`. `<I18nProvider locale messages>` builds a
2
+ * `@nifrajs/web-solid/i18n` - Solid bindings for `@nifrajs/i18n`. `<I18nProvider locale messages>` builds a
3
3
  * `Formatter` (a `createMemo`, so switching locale rebuilds it) and provides it; `useT()` reads it.
4
4
  * Both `locale` + `messages` are serializable, so a loader returns them, the page renders with the
5
5
  * negotiated catalog on the server, and the client rebuilds the same formatter on hydrate (no
package/dist/i18n.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-solid/i18n` — Solid bindings for `@nifrajs/i18n`. `<I18nProvider locale messages>` builds a
2
+ * `@nifrajs/web-solid/i18n` - Solid bindings for `@nifrajs/i18n`. `<I18nProvider locale messages>` builds a
3
3
  * `Formatter` (a `createMemo`, so switching locale rebuilds it) and provides it; `useT()` reads it.
4
4
  * Both `locale` + `messages` are serializable, so a loader returns them, the page renders with the
5
5
  * negotiated catalog on the server, and the client rebuilds the same formatter on hydrate (no
package/dist/image.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-solid/image` — a CLS-safe responsive Solid `<Image>`. A thin wrapper over `resolveImage`
2
+ * `@nifrajs/web-solid/image` - a CLS-safe responsive Solid `<Image>`. A thin wrapper over `resolveImage`
3
3
  * from `@nifrajs/image`: it computes the responsive `<img>` attributes (`src`/`srcset`/`sizes`/`width`/
4
4
  * `height`/`loading`/`decoding`/`fetchpriority` via `toHtmlAttrs`) and renders an `<img>` through
5
5
  * Solid's `<Dynamic>`. Extra DOM props (`class`, `style`, `id`, `data-*`, handlers) pass through
@@ -8,10 +8,10 @@
8
8
  */
9
9
  import { type ImageLoader, type ImageProps } from "@nifrajs/image";
10
10
  import { type JSX } from "solid-js";
11
- /** Attributes `resolveImage` computes — callers can't override them via DOM passthrough. */
11
+ /** Attributes `resolveImage` computes - callers can't override them via DOM passthrough. */
12
12
  type ComputedAttrs = "src" | "srcset" | "sizes" | "width" | "height" | "alt" | "loading" | "decoding" | "fetchpriority";
13
13
  export interface ImageComponentProps extends ImageProps, Omit<JSX.ImgHTMLAttributes<HTMLImageElement>, ComputedAttrs | keyof ImageProps> {
14
- /** CDN URL builder. Defaults to the identity loader (no transform — still CLS-safe + lazy). */
14
+ /** CDN URL builder. Defaults to the identity loader (no transform - still CLS-safe + lazy). */
15
15
  readonly loader?: ImageLoader;
16
16
  }
17
17
  /**
package/dist/image.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-solid/image` — a CLS-safe responsive Solid `<Image>`. A thin wrapper over `resolveImage`
2
+ * `@nifrajs/web-solid/image` - a CLS-safe responsive Solid `<Image>`. A thin wrapper over `resolveImage`
3
3
  * from `@nifrajs/image`: it computes the responsive `<img>` attributes (`src`/`srcset`/`sizes`/`width`/
4
4
  * `height`/`loading`/`decoding`/`fetchpriority` via `toHtmlAttrs`) and renders an `<img>` through
5
5
  * Solid's `<Dynamic>`. Extra DOM props (`class`, `style`, `id`, `data-*`, handlers) pass through
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { RenderAdapter } from "@nifrajs/web";
2
2
  import type { BunPlugin } from "bun";
3
- /** The Solid server render adapter — pass to @nifrajs/web's `renderPage`. */
3
+ /** The Solid server render adapter - pass to @nifrajs/web's `renderPage`. */
4
4
  export declare const solidAdapter: RenderAdapter;
5
5
  /**
6
- * Bun build/runtime plugin that compiles Solid components with Babel — `generate: "ssr"`
6
+ * Bun build/runtime plugin that compiles Solid components with Babel - `generate: "ssr"`
7
7
  * for the server, `"dom"` for the client, `hydratable` so SSR and hydrate align. Solid's
8
8
  * reactive-JSX compiler ships only as a Babel plugin (no swc/native port); this runs at
9
9
  * build time, on `.tsx` files only.
package/dist/index.js CHANGED
@@ -1,30 +1,30 @@
1
1
  /**
2
- * @nifrajs/web-solid — the Solid render adapter for @nifrajs/web (server side) + the Solid Babel
2
+ * @nifrajs/web-solid - the Solid render adapter for @nifrajs/web (server side) + the Solid Babel
3
3
  * Bun-plugin. Streaming SSR via `renderToStream` + `generateHydrationScript`; the layout-chain
4
4
  * fold is in `./compose`. Client hydration lives in `@nifrajs/web-solid/client` (Solid's browser
5
5
  * build).
6
6
  */
7
7
  import { transformAsync } from "@babel/core";
8
- // @ts-expect-error — no type declarations published
8
+ // @ts-expect-error - no type declarations published
9
9
  import presetTypeScript from "@babel/preset-typescript";
10
- // @ts-expect-error — no type declarations published
10
+ // @ts-expect-error - no type declarations published
11
11
  import presetSolid from "babel-preset-solid";
12
12
  import { generateHydrationScript, renderToStream as solidRenderToStream, renderToString as solidRenderToString, } from "solid-js/web";
13
13
  import { compose } from "./compose.js";
14
14
  const HYDRATION_HEAD = generateHydrationScript();
15
- /** The Solid server render adapter — pass to @nifrajs/web's `renderPage`. */
15
+ /** The Solid server render adapter - pass to @nifrajs/web's `renderPage`. */
16
16
  export const solidAdapter = {
17
17
  // Synchronous one-pass render for non-deferred pages (renderPage's buffered fast path). Solid's
18
18
  // `renderToString` emits the same hydratable markup (same `data-hk` keys seeded by
19
19
  // `generateHydrationScript()`) as `renderToStream`, but skips the TransformStream + Solid's
20
- // streaming machinery — the heaviest of the five renderers on Bun. A page that defer()s/Suspends
20
+ // streaming machinery - the heaviest of the five renderers on Bun. A page that defer()s/Suspends
21
21
  // takes `renderToStream` below (progressive resolution needs it).
22
22
  renderToString(chain, props) {
23
23
  return solidRenderToString(compose(chain, props));
24
24
  },
25
25
  renderToStream(chain, props) {
26
26
  // Solid's `renderToStream` streams `Uint8Array` chunks into a Web `WritableStream` via
27
- // `pipeTo` (fire-and-forget — returns void); pipe into a TransformStream and hand back the
27
+ // `pipeTo` (fire-and-forget - returns void); pipe into a TransformStream and hand back the
28
28
  // readable side. Suspense boundaries stream as they resolve; `generateHydrationScript()` (in
29
29
  // <head>) seeds client hydration. A render failure errors `ts.readable`, which `renderPage`
30
30
  // surfaces on the response body.
@@ -37,7 +37,7 @@ export const solidAdapter = {
37
37
  },
38
38
  };
39
39
  /**
40
- * Bun build/runtime plugin that compiles Solid components with Babel — `generate: "ssr"`
40
+ * Bun build/runtime plugin that compiles Solid components with Babel - `generate: "ssr"`
41
41
  * for the server, `"dom"` for the client, `hydratable` so SSR and hydrate align. Solid's
42
42
  * reactive-JSX compiler ships only as a Babel plugin (no swc/native port); this runs at
43
43
  * build time, on `.tsx` files only.
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Solid MDX runtime — the `useMDXComponents` provider that `@nifrajs/web-solid/mdx`'s compiled MDX imports
2
+ * Solid MDX runtime - the `useMDXComponents` provider that `@nifrajs/web-solid/mdx`'s compiled MDX imports
3
3
  * (via `@mdx-js`'s `providerImportSource`). MDX emits intrinsic elements (`h1`, `p`, …) as *string*
4
- * component references, but Solid can't `createComponent("h1")` — its JSX is compile-time. So we map
4
+ * component references, but Solid can't `createComponent("h1")` - its JSX is compile-time. So we map
5
5
  * each Markdown-output tag to a Solid component that renders it via `<Dynamic component={tag}>`.
6
6
  */
7
7
  import { createComponent } from "solid-js";
package/dist/mdx.js CHANGED
@@ -7,17 +7,17 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  /**
10
- * `solidMdxBunPlugin` — compile `.mdx` routes/files to **Solid** components. MDX is JSX-oriented but
10
+ * `solidMdxBunPlugin` - compile `.mdx` routes/files to **Solid** components. MDX is JSX-oriented but
11
11
  * Solid's JSX is compile-time, so this: (1) compiles MDX → JSX with `@mdx-js` (keeping JSX), pointing
12
12
  * intrinsic elements at `@nifrajs/web-solid/mdx-runtime` (which renders them via Solid's `<Dynamic>`), then
13
- * (2) runs `babel-preset-solid` — the same transform `solidBunPlugin` applies to `.tsx`. Pass it to
13
+ * (2) runs `babel-preset-solid` - the same transform `solidBunPlugin` applies to `.tsx`. Pass it to
14
14
  * `buildClient`/`buildServer`'s `plugins` (`"dom"` for the client, `"ssr"` for the server), like
15
15
  * `solidBunPlugin`. `@mdx-js/mdx` is an optional peer (lazy-loaded at build time).
16
16
  */
17
17
  import { transformAsync } from "@babel/core";
18
- // @ts-expect-error — no type declarations published
18
+ // @ts-expect-error - no type declarations published
19
19
  import presetTypeScript from "@babel/preset-typescript";
20
- // @ts-expect-error — no type declarations published
20
+ // @ts-expect-error - no type declarations published
21
21
  import presetSolid from "babel-preset-solid";
22
22
  // Non-literal so tsc/consumers don't need `@mdx-js/mdx`'s types to typecheck this file (optional peer).
23
23
  const MDX_MODULE = "@mdx-js/mdx";
@@ -32,7 +32,7 @@ export function solidMdxBunPlugin(generate) {
32
32
  compile = (await import(__rewriteRelativeImportExtension(MDX_MODULE))).compile;
33
33
  }
34
34
  catch {
35
- throw new Error("@nifrajs/web-solid/mdx: compiling `.mdx` needs the `@mdx-js/mdx` package — install it (`bun add @mdx-js/mdx`).");
35
+ throw new Error("@nifrajs/web-solid/mdx: compiling `.mdx` needs the `@mdx-js/mdx` package - install it (`bun add @mdx-js/mdx`).");
36
36
  }
37
37
  build.onLoad({ filter: /\.mdx(\?|$)/ }, async (args) => {
38
38
  const path = args.path.split("?")[0] ?? args.path;
package/dist/query.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { type QueryClient, type QueryState } from "@nifrajs/web";
2
2
  /**
3
- * `@nifrajs/web-solid/query` — Solid bindings for the keyed query-cache. `createQuery(key, fn)` bridges a
3
+ * `@nifrajs/web-solid/query` - Solid bindings for the keyed query-cache. `createQuery(key, fn)` bridges a
4
4
  * query's `subscribe`/`snapshot` store into a Solid signal and fetches on mount; `useQueryClient`
5
5
  * exposes `invalidateQueries` for after a mutation. Imports only `solid-js` + `@nifrajs/web` (never
6
6
  * `solid-js/web`), so route components use it on the server *and* client. No JSX.
7
7
  *
8
- * The query client is created lazily **client-side only** (`typeof window`) — on the server the
8
+ * The query client is created lazily **client-side only** (`typeof window`) - on the server the
9
9
  * accessor returns the idle/pending state (queries are client-first; loaders are the SSR data source).
10
10
  * The `key` is captured once (Solid setup runs once); a reactive key is a documented future enhancement.
11
11
  */