@nifrajs/web-svelte 2.10.0 → 2.12.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.
@@ -9,10 +9,20 @@
9
9
  reactive root is a component, not a function in `client.ts`.
10
10
  -->
11
11
  <script>
12
- import { searchOfChain } from "@nifrajs/web"
12
+ // `/client`, not the package root: the root's module graph reaches server-only code (the public-dir
13
+ // reader and friends), and a bundler that externalizes node builtins for the browser turns that into
14
+ // a runtime `Module "node:fs/promises" has been externalized` on the first import. `/client` is the
15
+ // browser-safe half, and it is where every other adapter takes this from.
16
+ import { searchOfChain } from "@nifrajs/web/client"
13
17
  import Chain from "./Chain.svelte"
14
18
  let { router, routes, searchSchemas } = $props()
15
19
 
20
+ // Capturing the INITIAL `router` is the intent, not an oversight: one router instance is created
21
+ // once per page and mounted here, so it never changes identity for this component's lifetime, and
22
+ // the reactivity that matters is the subscription below - the store pushes, this does not re-read.
23
+ // Wrapping it in a `$derived` would re-run `snapshot()` and hand `$state` a fresh object on every
24
+ // change, discarding the very state the subscription is maintaining.
25
+ // svelte-ignore state_referenced_locally
16
26
  let snapshot = $state(router.snapshot())
17
27
  $effect(() => router.subscribe(() => { snapshot = router.snapshot() }))
18
28
 
package/dist/client.d.ts CHANGED
@@ -1,7 +1,15 @@
1
1
  import type { MountRouterOptions, RenderProps } from "@nifrajs/web";
2
2
  export { errorBoundary } from "./error.js";
3
3
  /** Hydrate a server-rendered Svelte layout `chain` (with the loader `props`) inside `container`. */
4
- export declare function hydrate(chain: readonly unknown[], props: RenderProps, container: unknown): void;
4
+ export interface HydrationAssuranceOptions {
5
+ readonly onWarning?: (message: string) => void;
6
+ }
7
+ export declare function hydrate(chain: readonly unknown[], props: RenderProps, container: unknown, options?: HydrationAssuranceOptions): void;
8
+ /** Testing hook used by verification runners to observe Svelte warnings and identity. */
9
+ export declare const hydrationAssuranceHook: Readonly<{
10
+ framework: "svelte";
11
+ runtimeIdentity: () => object;
12
+ }>;
5
13
  /**
6
14
  * Hydrate a stateful Svelte Router. The `Router` component holds the store snapshot in `$state` and
7
15
  * re-renders the matched layout chain on each store change - so client navigations swap routes without
@@ -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;AAenE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,oGAAoG;AACpG,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAK/F;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAI7D"}
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;AAenE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,oGAAoG;AACpG,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/C;AAWD,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,yBAAyB,GAClC,IAAI,CAYN;AAED,yFAAyF;AACzF,eAAO,MAAM,sBAAsB;;2BAEZ,MAAM;EAC3B,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAc7D"}
package/dist/client.js CHANGED
@@ -12,13 +12,34 @@ import Router from "./Router.svelte";
12
12
  // The `_error` boundary marker - Chain.svelte renders it as a <svelte:boundary>. Re-exported here so
13
13
  // nifra's client codegen resolves it from `@nifrajs/web-svelte/client` alongside `mountRouter`.
14
14
  export { errorBoundary } from "./error.js";
15
- /** Hydrate a server-rendered Svelte layout `chain` (with the loader `props`) inside `container`. */
16
- export function hydrate(chain, props, container) {
17
- svelteHydrate(Chain, {
18
- target: container,
19
- props: { chain, props, layoutData: props.layoutData },
20
- });
15
+ function assuranceWarning() {
16
+ const value = globalThis[Symbol.for("nifra.hydration.assurance")];
17
+ if (typeof value !== "object" || value === null)
18
+ return undefined;
19
+ const callback = value.onWarning;
20
+ return typeof callback === "function" ? callback : undefined;
21
21
  }
22
+ export function hydrate(chain, props, container, options) {
23
+ const warning = options?.onWarning ?? assuranceWarning();
24
+ const originalWarn = console.warn;
25
+ if (warning !== undefined)
26
+ console.warn = (...args) => warning(args.map(String).join(" "));
27
+ try {
28
+ svelteHydrate(Chain, {
29
+ target: container,
30
+ props: { chain, props, layoutData: props.layoutData },
31
+ });
32
+ }
33
+ finally {
34
+ if (warning !== undefined)
35
+ console.warn = originalWarn;
36
+ }
37
+ }
38
+ /** Testing hook used by verification runners to observe Svelte warnings and identity. */
39
+ export const hydrationAssuranceHook = Object.freeze({
40
+ framework: "svelte",
41
+ runtimeIdentity: () => svelteHydrate,
42
+ });
22
43
  /**
23
44
  * Hydrate a stateful Svelte Router. The `Router` component holds the store snapshot in `$state` and
24
45
  * re-renders the matched layout chain on each store change - so client navigations swap routes without
@@ -28,6 +49,19 @@ export function hydrate(chain, props, container) {
28
49
  export function mountRouter(options) {
29
50
  const { router, routes, searchSchemas, container } = options;
30
51
  setMountedRouter(router); // expose it to useFetcher/useFetchers (same page, client-only)
31
- svelteHydrate(Router, { target: container, props: { router, routes, searchSchemas } });
52
+ const warning = assuranceWarning();
53
+ const originalWarn = console.warn;
54
+ if (warning !== undefined)
55
+ console.warn = (...args) => warning(args.map(String).join(" "));
56
+ try {
57
+ svelteHydrate(Router, {
58
+ target: container,
59
+ props: { router, routes, searchSchemas },
60
+ });
61
+ }
62
+ finally {
63
+ if (warning !== undefined)
64
+ console.warn = originalWarn;
65
+ }
32
66
  }
33
67
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAEpC,qGAAqG;AACrG,gGAAgG;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,oGAAoG;AACpG,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB,EAAE,SAAkB;IACvF,aAAa,CAAC,KAAK,EAAE;QACnB,MAAM,EAAE,SAAoB;QAC5B,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE;KACtD,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC5D,gBAAgB,CAAC,MAAM,CAAC,CAAA,CAAC,+DAA+D;IACxF,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAoB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,CAAA;AACnG,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAEpC,qGAAqG;AACrG,gGAAgG;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAO1C,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAI,UAAsD,CACnE,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CACxC,CAAA;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACjE,MAAM,QAAQ,GAAI,KAAiC,CAAC,SAAS,CAAA;IAC7D,OAAO,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAE,QAAsC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC7F,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,KAAyB,EACzB,KAAkB,EAClB,SAAkB,EAClB,OAAmC;IAEnC,MAAM,OAAO,GAAG,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,CAAA;IACxD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAA;IACjC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1F,IAAI,CAAC;QACH,aAAa,CAAC,KAAK,EAAE;YACnB,MAAM,EAAE,SAAoB;YAC5B,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE;SACtD,CAAC,CAAA;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,GAAG,YAAY,CAAA;IACxD,CAAC;AACH,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,SAAS,EAAE,QAAiB;IAC5B,eAAe,EAAE,GAAW,EAAE,CAAC,aAAa;CAC7C,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC5D,gBAAgB,CAAC,MAAM,CAAC,CAAA,CAAC,+DAA+D;IACxF,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAA;IAClC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAA;IACjC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1F,IAAI,CAAC;QACH,aAAa,CAAC,MAAM,EAAE;YACpB,MAAM,EAAE,SAAoB;YAC5B,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE;SACzC,CAAC,CAAA;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,GAAG,YAAY,CAAA;IACxD,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,11 +1,3 @@
1
- /**
2
- * @nifrajs/web-svelte - the Svelte 5 render adapter for @nifrajs/web (server side) + the `.svelte` compiler
3
- * Bun-plugin. SSR via Svelte's `render` (svelte/server), which returns HTML strings (Svelte SSR is
4
- * string-based, not a stream), wrapped in a one-chunk Web `ReadableStream` (the seam's shape). The
5
- * layout-chain fold is the recursive `Chain.svelte`. Client hydration lives in `@nifrajs/web-svelte/client`.
6
- * Svelte components compile from `.svelte` files, so this adapter ships a build plugin (like
7
- * `@nifrajs/web-solid`'s Babel plugin) - there is no callable-component runtime.
8
- */
9
1
  import type { RenderAdapter } from "@nifrajs/web";
10
2
  export { svelteBunPlugin } from "./plugin.js";
11
3
  /** The Svelte server render adapter - pass to @nifrajs/web's `renderPage`. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAOjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAa7C,8EAA8E;AAC9E,eAAO,MAAM,aAAa,EAAE,aAqB3B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,cAAc,CAAA;AAM9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAgF7C,8EAA8E;AAC9E,eAAO,MAAM,aAAa,EAAE,aA8B3B,CAAA"}
package/dist/index.js CHANGED
@@ -1,9 +1,49 @@
1
- import { render } from "svelte/server";
2
- import Chain from "./Chain.svelte";
3
- // Re-export the compiler plugin for convenience. NOTE: the SSR preload must import it from
4
- // `@nifrajs/web-svelte/plugin` (not from here) - importing this module eagerly loads `Chain.svelte`,
5
- // which must be compiled by the already-registered plugin.
1
+ /**
2
+ * @nifrajs/web-svelte - the Svelte 5 render adapter for @nifrajs/web (server side) + the `.svelte` compiler
3
+ * Bun-plugin. SSR via Svelte's `render` (svelte/server), which returns HTML strings (Svelte SSR is
4
+ * string-based, not a stream), wrapped in a one-chunk Web `ReadableStream` (the seam's shape). The
5
+ * layout-chain fold is the recursive `Chain.svelte`. Client hydration lives in `@nifrajs/web-svelte/client`.
6
+ * Svelte components compile from `.svelte` files, so this adapter ships a build plugin (like
7
+ * `@nifrajs/web-solid`'s Babel plugin) - there is no callable-component runtime.
8
+ */
9
+ import { fileURLToPath } from "node:url";
10
+ import { ssrModuleLoader } from "@nifrajs/web";
11
+ import { render as runtimeRender } from "svelte/server";
12
+ // Re-export the compiler plugin for convenience.
6
13
  export { svelteBunPlugin } from "./plugin.js";
14
+ let chainComponent;
15
+ let chainPromise;
16
+ /**
17
+ * Svelte's server renderer. Normally the runtime's, but it is swapped for the dev server's copy when
18
+ * `Chain` comes from there - a component compiled by one toolchain has to render through the renderer
19
+ * that toolchain resolved, or `setContext` writes into a renderer the children never read.
20
+ */
21
+ let render = runtimeRender;
22
+ /** Resolved `Chain`, or the in-flight load on the very first call. */
23
+ const loadChain = () => {
24
+ if (chainComponent !== undefined)
25
+ return chainComponent;
26
+ // A dev server that owns SSR resolution compiles the app's `.svelte` routes itself, and `Chain` has
27
+ // to come from that same graph: the runtime has no `.svelte` loader on that pipeline, so a plain
28
+ // `import` yields the file PATH and SSR dies at `component is not a function`. Registering a second
29
+ // compiler in the runtime instead is the trap - it gives the tree two Svelte runtimes, and the
30
+ // renderer `Chain` sets context on is not the one the routes read it from. Taking BOTH the component
31
+ // and `svelte/server` from the dev server keeps it at one compiler and one runtime.
32
+ const load = ssrModuleLoader();
33
+ chainPromise ??= (load !== undefined
34
+ ? Promise.all([
35
+ load(fileURLToPath(new URL("./Chain.svelte", import.meta.url))),
36
+ load("svelte/server"),
37
+ ]).then(([mod, server]) => {
38
+ render = server.render;
39
+ return mod.default;
40
+ })
41
+ : import("./Chain.svelte").then((m) => m.default)).then((c) => {
42
+ chainComponent = c;
43
+ return c;
44
+ });
45
+ return chainPromise;
46
+ };
7
47
  // Svelte SSR yields a complete HTML string; the seam wants a stream, so emit it as one chunk.
8
48
  function oneChunk(html) {
9
49
  const bytes = new TextEncoder().encode(html);
@@ -20,16 +60,25 @@ export const svelteAdapter = {
20
60
  // returns the body directly (renderPage buffers it on the non-deferred fast path), and
21
61
  // `renderToStream` wraps the same string in a one-chunk stream for the deferred path. No streaming
22
62
  // renderer to skip here - but going straight to a string avoids the per-request stream allocation.
63
+ // The seam allows `string | Promise<string>`, so the first render can resolve `Chain` while every
64
+ // render after it stays a plain synchronous call - see `loadChain`.
23
65
  renderToString(chain, props) {
24
- return render(Chain, { props: { chain, props, layoutData: props.layoutData } }).body;
66
+ const Chain = loadChain();
67
+ const props$ = { chain, props, layoutData: props.layoutData };
68
+ return Chain instanceof Promise
69
+ ? Chain.then((C) => render(C, { props: props$ }).body)
70
+ : render(Chain, { props: props$ }).body;
25
71
  },
26
72
  renderToStream(chain, props) {
27
73
  // `Chain` folds the layout chain (page innermost gets `props`; layouts wrap via their `children`
28
74
  // snippet). Svelte's `render` returns { head, body }; the body goes into #root. (Svelte's dynamic
29
75
  // `head` - from <svelte:head> - isn't surfaced through the seam's static `hydrationHead`; nifra's
30
76
  // own meta/head API manages the document head instead.)
31
- const { body } = render(Chain, { props: { chain, props, layoutData: props.layoutData } });
32
- return oneChunk(body);
77
+ const Chain = loadChain();
78
+ const props$ = { chain, props, layoutData: props.layoutData };
79
+ return Chain instanceof Promise
80
+ ? Chain.then((C) => oneChunk(render(C, { props: props$ }).body))
81
+ : oneChunk(render(Chain, { props: props$ }).body);
33
82
  },
34
83
  // Svelte's client `hydrate` reconciles against the existing DOM; no per-document bootstrap script is
35
84
  // needed (contrast Solid's generateHydrationScript) - the seam allows the empty string.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,KAAK,MAAM,gBAAgB,CAAA;AAElC,2FAA2F;AAC3F,qGAAqG;AACrG,2DAA2D;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,8FAA8F;AAC9F,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC5C,OAAO,IAAI,cAAc,CAAC;QACxB,KAAK,CAAC,UAAU;YACd,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACzB,UAAU,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,kGAAkG;IAClG,uFAAuF;IACvF,mGAAmG;IACnG,mGAAmG;IACnG,cAAc,CAAC,KAAK,EAAE,KAAK;QACzB,OAAO,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAA;IACtF,CAAC;IACD,cAAc,CAAC,KAAK,EAAE,KAAK;QACzB,iGAAiG;QACjG,kGAAkG;QAClG,kGAAkG;QAClG,wDAAwD;QACxD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;QACzF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;IACD,qGAAqG;IACrG,wFAAwF;IACxF,aAAa;QACX,OAAO,EAAE,CAAA;IACX,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/mdx.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mdx.d.ts","sourceRoot":"","sources":["../src/mdx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAsBpC;uFACuF;AACvF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CA+CrE"}
1
+ {"version":3,"file":"mdx.d.ts","sourceRoot":"","sources":["../src/mdx.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAsBpC;uFACuF;AACvF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CA+CrE"}
package/dist/mdx.js CHANGED
@@ -6,6 +6,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
6
6
  }
7
7
  return path;
8
8
  };
9
+ import { rewriteSsrImports } from "@nifrajs/web/plugins/kit";
9
10
  import { compile } from "svelte/compiler";
10
11
  /**
11
12
  * `@nifrajs/web-svelte/mdx` - compile `.mdx` routes/files to **Svelte** components. Svelte has no JSX
@@ -58,7 +59,7 @@ export function svelteMdxBunPlugin(generate) {
58
59
  loader: "js",
59
60
  };
60
61
  }
61
- return { contents: js.code, loader: "js" };
62
+ return { contents: rewriteSsrImports(js.code, path, generate), loader: "js" };
62
63
  });
63
64
  build.onResolve({ filter: /\?svelte-mdx-css$/ }, (args) => ({
64
65
  path: args.path,
package/dist/mdx.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mdx.js","sourceRoot":"","sources":["../src/mdx.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mdx.js","sourceRoot":"","sources":["../src/mdx.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,27 @@
1
1
  import type { BunPlugin } from "bun";
2
+ /**
3
+ * The same hot-patch boundary as the Bun pipeline's, in the shape `@sveltejs/vite-plugin-svelte` takes:
4
+ *
5
+ * ```ts
6
+ * svelte({ dynamicCompileOptions: svelteHmrBoundary })
7
+ * ```
8
+ *
9
+ * Svelte's HMR wrapper resolves the component through a signal, which survives hydration only where
10
+ * the component is a plain child in a template. A layout or a page is not: the adapter's `Chain` enters
11
+ * chain members as dynamic components and through snippets, so a wrapper on one leaves the hydration
12
+ * cursor pointing at markup the wrapped component never claims. Svelte then throws the server's tree
13
+ * away and re-renders on the client - `hydration_mismatch` in the console, on first load, before any
14
+ * edit. Left on, the dev server quietly stops exercising hydration at all.
15
+ *
16
+ * Views keep hot-patching; route modules fall back to a full reload, which is what they want anyway
17
+ * (a route module carries the loader and meta the server ran, and re-running those is a navigation).
18
+ * Outside a nifra dev server nothing is announced and the answer is "no boundary" - a full reload is
19
+ * always correct, a mispatched tree is not.
20
+ */
21
+ export declare function svelteHmrBoundary({ filename }: {
22
+ filename: string;
23
+ }): {
24
+ hmr: boolean;
25
+ };
2
26
  export declare function svelteBunPlugin(generate: "dom" | "ssr"): BunPlugin;
3
27
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAsBpC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAqClE"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAsBpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAEtF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CA8DlE"}
package/dist/plugin.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { devHotComponent, devServerCompile, rewriteSsrImports } from "@nifrajs/web/plugins/kit";
1
2
  import { compile } from "svelte/compiler";
2
3
  /**
3
4
  * `@nifrajs/web-svelte/plugin` - the `.svelte` compiler Bun-plugin, in its OWN module (no `.svelte`
@@ -17,6 +18,28 @@ import { compile } from "svelte/compiler";
17
18
  */
18
19
  const STYLE_SUFFIX = "?svelte-css";
19
20
  const STYLE_NS = "nifra-svelte-css";
21
+ /**
22
+ * The same hot-patch boundary as the Bun pipeline's, in the shape `@sveltejs/vite-plugin-svelte` takes:
23
+ *
24
+ * ```ts
25
+ * svelte({ dynamicCompileOptions: svelteHmrBoundary })
26
+ * ```
27
+ *
28
+ * Svelte's HMR wrapper resolves the component through a signal, which survives hydration only where
29
+ * the component is a plain child in a template. A layout or a page is not: the adapter's `Chain` enters
30
+ * chain members as dynamic components and through snippets, so a wrapper on one leaves the hydration
31
+ * cursor pointing at markup the wrapped component never claims. Svelte then throws the server's tree
32
+ * away and re-renders on the client - `hydration_mismatch` in the console, on first load, before any
33
+ * edit. Left on, the dev server quietly stops exercising hydration at all.
34
+ *
35
+ * Views keep hot-patching; route modules fall back to a full reload, which is what they want anyway
36
+ * (a route module carries the loader and meta the server ran, and re-running those is a navigation).
37
+ * Outside a nifra dev server nothing is announced and the answer is "no boundary" - a full reload is
38
+ * always correct, a mispatched tree is not.
39
+ */
40
+ export function svelteHmrBoundary({ filename }) {
41
+ return { hmr: devHotComponent(filename) };
42
+ }
20
43
  export function svelteBunPlugin(generate) {
21
44
  // Compiled scoped CSS per `.svelte` file (client build only) - read back by the virtual-module loader.
22
45
  const cssByPath = new Map();
@@ -28,10 +51,35 @@ export function svelteBunPlugin(generate) {
28
51
  build.onLoad({ filter: /\.svelte(\?|$)/ }, async (args) => {
29
52
  const path = args.path.split("?")[0] ?? args.path;
30
53
  const source = await Bun.file(path).text();
54
+ // Per compile, not per registration: the CLI registers the SSR plugin before the dev server
55
+ // exists, and the flag is set by the dev server.
56
+ //
57
+ // Svelte's HMR is a compiler feature (`$.hmr` + a self-accepting `import.meta.hot.accept`), and
58
+ // it is only available under `dev`. `dev` is set on BOTH halves so the server and client builds
59
+ // stay the same Svelte, while `hmr` stays client-only, there being no `import.meta.hot` on the
60
+ // server. `nifra build` sets neither, so nothing here reaches a production bundle.
61
+ //
62
+ // The server half additionally needs Svelte's own runtime in its dev shape - `dev` output calls
63
+ // `push_element`, which reads state the runtime only records when ITS `DEV` is true. That flag
64
+ // resolves through `esm-env`, which falls back to `NODE_ENV` off the export conditions; the dev
65
+ // server sets it for exactly this reason. Getting that half wrong throws on the first element:
66
+ // `undefined is not an object (evaluating 'context.function[FILENAME]')`.
67
+ //
68
+ // `hmr` narrows further, to the app's own non-route components ({@link devHotComponent}).
69
+ // Svelte's wrapper replaces the component with a block that resolves it through a signal, and
70
+ // that survives hydration only where the component is a plain child in a template. A chain
71
+ // member is not: the adapter's `Chain` enters layouts and pages as dynamic components and
72
+ // through snippets, and a wrapper on either side of that leaves the hydration cursor pointing
73
+ // at markup the wrapped component never claims - the whole tree is then thrown away and
74
+ // re-rendered on the client, silently, before any edit. A view component is the boundary that
75
+ // works, and it is also the one worth patching.
76
+ const dev = devServerCompile();
31
77
  const { js, css } = compile(source, {
32
78
  generate: generate === "ssr" ? "server" : "client",
33
79
  filename: path,
34
80
  css: "external", // emit the scoped stylesheet separately (not injected into the JS)
81
+ dev,
82
+ hmr: dev && generate === "dom" && devHotComponent(path),
35
83
  });
36
84
  if (generate === "dom" && css?.code) {
37
85
  cssByPath.set(path, css.code);
@@ -41,7 +89,7 @@ export function svelteBunPlugin(generate) {
41
89
  loader: "js",
42
90
  };
43
91
  }
44
- return { contents: js.code, loader: "js" };
92
+ return { contents: rewriteSsrImports(js.code, path, generate), loader: "js" };
45
93
  });
46
94
  // Virtual CSS module: `<file>.svelte?svelte-css` → the compiled scoped stylesheet (css loader).
47
95
  build.onResolve({ filter: /\?svelte-css$/ }, (args) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,YAAY,GAAG,aAAa,CAAA;AAClC,MAAM,QAAQ,GAAG,kBAAkB,CAAA;AAEnC,MAAM,UAAU,eAAe,CAAC,QAAuB;IACrD,uGAAuG;IACvG,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC3C,OAAO;QACL,IAAI,EAAE,gBAAgB,QAAQ,EAAE;QAChC,KAAK,CAAC,KAAK;YACT,6FAA6F;YAC7F,qDAAqD;YACrD,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAA;gBACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC1C,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;oBAClC,QAAQ,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;oBAClD,QAAQ,EAAE,IAAI;oBACd,GAAG,EAAE,UAAU,EAAE,mEAAmE;iBACrF,CAAC,CAAA;gBACF,IAAI,QAAQ,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;oBACpC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;oBAC7B,+FAA+F;oBAC/F,OAAO;wBACL,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI;wBACvE,MAAM,EAAE,IAAI;qBACb,CAAA;gBACH,CAAC;gBACD,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;YAC5C,CAAC,CAAC,CAAA;YACF,gGAAgG;YAChG,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAC,CAAA;YACH,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7D,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;gBACvE,MAAM,EAAE,KAAK;aACd,CAAC,CAAC,CAAA;QACL,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/dist/query.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type QueryClient, type QueryState } from "@nifrajs/web";
1
+ import type { QueryClient, QueryState } from "@nifrajs/web";
2
2
  /**
3
3
  * `@nifrajs/web-svelte/query` - Svelte bindings for the keyed query-cache, as **Svelte stores** (plain
4
4
  * `.ts`). `useQuery(key, fn)` returns a `Readable<QueryState<T>>` augmented with `refetch` - read it
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AACrB;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAA;AAStD,wGAAwG;AACxG,wBAAgB,cAAc,IAAI,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAEvE;AAWD,gFAAgF;AAChF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACpD,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;CACnC,CAAA;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAe7E"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAe,UAAU,EAAE,MAAM,cAAc,CAAA;AAIxE;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAA;AAStD,wGAAwG;AACxG,wBAAgB,cAAc,IAAI,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAEvE;AAWD,gFAAgF;AAChF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACpD,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;CACnC,CAAA;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAe7E"}
package/dist/query.js CHANGED
@@ -1,4 +1,6 @@
1
- import { createQueryClient, } from "@nifrajs/web";
1
+ // `/client`, not the root - these are DOM values, and the root's graph carries the
2
+ // server, which Vite's dev server evaluates rather than tree-shakes.
3
+ import { createQueryClient } from "@nifrajs/web/client";
2
4
  /**
3
5
  * `@nifrajs/web-svelte/query` - Svelte bindings for the keyed query-cache, as **Svelte stores** (plain
4
6
  * `.ts`). `useQuery(key, fn)` returns a `Readable<QueryState<T>>` augmented with `refetch` - read it
package/dist/query.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAIlB,MAAM,cAAc,CAAA;AACrB;;;;;;;;;;GAUG;AACH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEtD,IAAI,MAA+B,CAAA;AACnC,SAAS,SAAS;IAChB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA,CAAC,wCAAwC;IAC5F,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,GAAG,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC/E,OAAO,MAAM,CAAA;AACf,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,cAAc;IAC5B,OAAO,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;AACvD,CAAC;AAED,0DAA0D;AAC1D,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,MAAM,CAAC,iBAAiB;CACpC,CAAC,CAAA;AAQF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAI,GAAY,EAAE,EAAoB;IAC5D,MAAM,MAAM,GAA+B,SAAS,EAAE,EAAE,KAAK,CAAI,GAAG,EAAE,EAAE,CAAC,CAAA;IACzE,MAAM,KAAK,GAAG,QAAQ,CAAgB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QAC/E,IAAI,MAAM,KAAK,SAAS;YAAE,OAAM;QAChC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACtB,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QAClE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,iDAAiD;QAChF,OAAO,WAAW,CAAA;IACpB,CAAC,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO;QAChB,CAAC,CAAE,CAAC,KAAK,IAAI,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;QAC9F,CAAC,CAAsB,CAAA;IAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;AAC1C,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AACA,mFAAmF;AACnF,qEAAqE;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD;;;;;;;;;;GAUG;AACH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEtD,IAAI,MAA+B,CAAA;AACnC,SAAS,SAAS;IAChB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA,CAAC,wCAAwC;IAC5F,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,GAAG,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC/E,OAAO,MAAM,CAAA;AACf,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,cAAc;IAC5B,OAAO,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;AACvD,CAAC;AAED,0DAA0D;AAC1D,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,MAAM,CAAC,iBAAiB;CACpC,CAAC,CAAA;AAQF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAI,GAAY,EAAE,EAAoB;IAC5D,MAAM,MAAM,GAA+B,SAAS,EAAE,EAAE,KAAK,CAAI,GAAG,EAAE,EAAE,CAAC,CAAA;IACzE,MAAM,KAAK,GAAG,QAAQ,CAAgB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QAC/E,IAAI,MAAM,KAAK,SAAS;YAAE,OAAM;QAChC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACtB,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QAClE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,iDAAiD;QAChF,OAAO,WAAW,CAAA;IACpB,CAAC,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO;QAChB,CAAC,CAAE,CAAC,KAAK,IAAI,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;QAC9F,CAAC,CAAsB,CAAA;IAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;AAC1C,CAAC"}
package/dist/router.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { InferOutput, StandardSchemaV1 } from "@nifrajs/core/server";
2
- import { type Blocker, type BlockerFunction, type NavigateFunction } from "@nifrajs/web";
2
+ import type { Blocker, BlockerFunction, BlockerState, NavigateFunction } from "@nifrajs/web";
3
3
  /**
4
4
  * `@nifrajs/web-svelte/router` - Svelte routing bindings over the agnostic `@nifrajs/web` history layer,
5
5
  * as plain `.ts` (no runes/compiler needed): `useNavigate` (programmatic navigation), `useBlocker` (the
@@ -9,7 +9,7 @@ import { type Blocker, type BlockerFunction, type NavigateFunction } from "@nifr
9
9
  * context on SSR + client alike. Idle before hydration (native `<a>` navigation still works). SSR-safe.
10
10
  */
11
11
  import { type Readable } from "svelte/store";
12
- export type { Blocker, BlockerFunction, BlockerState, NavigateFunction } from "@nifrajs/web";
12
+ export type { Blocker, BlockerFunction, BlockerState, NavigateFunction };
13
13
  /**
14
14
  * The route's typed, validated search params as a reactive accessor - the SAME value the loader received
15
15
  * as `ctx.search`. SSR-correct: `Chain.svelte` provides it from the URL server-side and from the
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACzE,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,eAAe,EAGpB,KAAK,gBAAgB,EAKtB,MAAM,cAAc,CAAA;AAErB;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAA;AAEtD,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAQ5F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,SAAS,gBAAgB,GAAG,SAAS,GAAG,SAAS,KACpD,MAAM,MAAM,SAAS,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzF;AAED;;kCAEkC;AAClC,wBAAgB,WAAW,IAAI,gBAAgB,CAO9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAOpF"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIzE,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,YAAY,EACZ,gBAAgB,EAGjB,MAAM,cAAc,CAAA;AAUrB;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAA;AAEtD,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAQxE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,SAAS,gBAAgB,GAAG,SAAS,GAAG,SAAS,KACpD,MAAM,MAAM,SAAS,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzF;AAED;;kCAEkC;AAClC,wBAAgB,WAAW,IAAI,gBAAgB,CAO9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAOpF"}
package/dist/router.js CHANGED
@@ -1,4 +1,6 @@
1
- import { getBrowserNavigate, IDLE_BLOCKER, registerBlocker, resolveNavigate, } from "@nifrajs/web";
1
+ // `/client`, not the root - these are DOM values, and the root's graph carries the
2
+ // server, which Vite's dev server evaluates rather than tree-shakes.
3
+ import { getBrowserNavigate, IDLE_BLOCKER, registerBlocker, resolveNavigate, } from "@nifrajs/web/client";
2
4
  import { getContext } from "svelte";
3
5
  /**
4
6
  * `@nifrajs/web-svelte/router` - Svelte routing bindings over the agnostic `@nifrajs/web` history layer,
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,kBAAkB,EAClB,YAAY,EAIZ,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC;;;;;;;GAOG;AACH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAItD,uGAAuG;AACvG,oEAAoE;AACpE,MAAM,UAAU,GAAG,4BAA4B,CAAA;AAC/C,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AACzE,MAAM,qBAAqB,GAAG,GAA4B,EAAE,CAAC,YAAY,CAAA;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS;IAGvB,MAAM,GAAG,GAAG,UAAU,CAA8C,UAAU,CAAC,CAAA;IAC/E,OAAO,CAAC,GAAG,IAAI,qBAAqB,CAET,CAAA;AAC7B,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,CAAC,EAAyC,EAAE,OAAyB,EAAE,EAAE;QAC/E,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;QACrC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAM;QAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IACzC,CAAC,CAAqB,CAAA;AACxB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,WAAsC;IAC/D,OAAO,QAAQ,CAAU,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAC7C,eAAe,CACb,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAC/E,GAAG,CACJ,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAYA,mFAAmF;AACnF,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC;;;;;;;GAOG;AACH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAItD,uGAAuG;AACvG,oEAAoE;AACpE,MAAM,UAAU,GAAG,4BAA4B,CAAA;AAC/C,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AACzE,MAAM,qBAAqB,GAAG,GAA4B,EAAE,CAAC,YAAY,CAAA;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS;IAGvB,MAAM,GAAG,GAAG,UAAU,CAA8C,UAAU,CAAC,CAAA;IAC/E,OAAO,CAAC,GAAG,IAAI,qBAAqB,CAET,CAAA;AAC7B,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,CAAC,EAAyC,EAAE,OAAyB,EAAE,EAAE;QAC/E,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;QACrC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAM;QAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IACzC,CAAC,CAAqB,CAAA;AACxB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,WAAsC;IAC/D,OAAO,QAAQ,CAAU,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAC7C,eAAe,CACb,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAC/E,GAAG,CACJ,CACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@nifrajs/web-svelte",
3
- "version": "2.10.0",
3
+ "version": "2.12.0",
4
4
  "description": "Svelte 5 render adapter for @nifrajs/web - SSR + hydration + the .svelte compiler Bun-plugin.",
5
5
  "keywords": [
6
6
  "bun",
7
7
  "typescript",
8
8
  "nifra",
9
- "web-framework",
10
- "full-stack",
11
- "edge",
12
- "ssr"
9
+ "svelte",
10
+ "svelte5",
11
+ "ssr",
12
+ "hydration",
13
+ "render-adapter",
14
+ "full-stack"
13
15
  ],
14
16
  "type": "module",
15
17
  "main": "./dist/index.js",
@@ -98,10 +100,10 @@
98
100
  "access": "public"
99
101
  },
100
102
  "dependencies": {
101
- "@nifrajs/core": "2.10.0",
102
- "@nifrajs/i18n": "2.10.0",
103
- "@nifrajs/image": "2.10.0",
104
- "@nifrajs/web": "2.10.0"
103
+ "@nifrajs/core": "2.12.0",
104
+ "@nifrajs/i18n": "2.12.0",
105
+ "@nifrajs/image": "2.12.0",
106
+ "@nifrajs/web": "2.12.0"
105
107
  },
106
108
  "peerDependencies": {
107
109
  "mdsvex": "^0.12",
package/src/Router.svelte CHANGED
@@ -9,10 +9,20 @@
9
9
  reactive root is a component, not a function in `client.ts`.
10
10
  -->
11
11
  <script>
12
- import { searchOfChain } from "@nifrajs/web"
12
+ // `/client`, not the package root: the root's module graph reaches server-only code (the public-dir
13
+ // reader and friends), and a bundler that externalizes node builtins for the browser turns that into
14
+ // a runtime `Module "node:fs/promises" has been externalized` on the first import. `/client` is the
15
+ // browser-safe half, and it is where every other adapter takes this from.
16
+ import { searchOfChain } from "@nifrajs/web/client"
13
17
  import Chain from "./Chain.svelte"
14
18
  let { router, routes, searchSchemas } = $props()
15
19
 
20
+ // Capturing the INITIAL `router` is the intent, not an oversight: one router instance is created
21
+ // once per page and mounted here, so it never changes identity for this component's lifetime, and
22
+ // the reactivity that matters is the subscription below - the store pushes, this does not re-read.
23
+ // Wrapping it in a `$derived` would re-run `snapshot()` and hand `$state` a fresh object on every
24
+ // change, discarding the very state the subscription is maintaining.
25
+ // svelte-ignore state_referenced_locally
16
26
  let snapshot = $state(router.snapshot())
17
27
  $effect(() => router.subscribe(() => { snapshot = router.snapshot() }))
18
28
 
package/src/client.ts CHANGED
@@ -16,13 +16,44 @@ import Router from "./Router.svelte"
16
16
  export { errorBoundary } from "./error.ts"
17
17
 
18
18
  /** Hydrate a server-rendered Svelte layout `chain` (with the loader `props`) inside `container`. */
19
- export function hydrate(chain: readonly unknown[], props: RenderProps, container: unknown): void {
20
- svelteHydrate(Chain, {
21
- target: container as Element,
22
- props: { chain, props, layoutData: props.layoutData },
23
- })
19
+ export interface HydrationAssuranceOptions {
20
+ readonly onWarning?: (message: string) => void
24
21
  }
25
22
 
23
+ function assuranceWarning(): ((message: string) => void) | undefined {
24
+ const value = (globalThis as unknown as Record<PropertyKey, unknown>)[
25
+ Symbol.for("nifra.hydration.assurance")
26
+ ]
27
+ if (typeof value !== "object" || value === null) return undefined
28
+ const callback = (value as { onWarning?: unknown }).onWarning
29
+ return typeof callback === "function" ? (callback as (message: string) => void) : undefined
30
+ }
31
+
32
+ export function hydrate(
33
+ chain: readonly unknown[],
34
+ props: RenderProps,
35
+ container: unknown,
36
+ options?: HydrationAssuranceOptions,
37
+ ): void {
38
+ const warning = options?.onWarning ?? assuranceWarning()
39
+ const originalWarn = console.warn
40
+ if (warning !== undefined) console.warn = (...args) => warning(args.map(String).join(" "))
41
+ try {
42
+ svelteHydrate(Chain, {
43
+ target: container as Element,
44
+ props: { chain, props, layoutData: props.layoutData },
45
+ })
46
+ } finally {
47
+ if (warning !== undefined) console.warn = originalWarn
48
+ }
49
+ }
50
+
51
+ /** Testing hook used by verification runners to observe Svelte warnings and identity. */
52
+ export const hydrationAssuranceHook = Object.freeze({
53
+ framework: "svelte" as const,
54
+ runtimeIdentity: (): object => svelteHydrate,
55
+ })
56
+
26
57
  /**
27
58
  * Hydrate a stateful Svelte Router. The `Router` component holds the store snapshot in `$state` and
28
59
  * re-renders the matched layout chain on each store change - so client navigations swap routes without
@@ -32,5 +63,15 @@ export function hydrate(chain: readonly unknown[], props: RenderProps, container
32
63
  export function mountRouter(options: MountRouterOptions): void {
33
64
  const { router, routes, searchSchemas, container } = options
34
65
  setMountedRouter(router) // expose it to useFetcher/useFetchers (same page, client-only)
35
- svelteHydrate(Router, { target: container as Element, props: { router, routes, searchSchemas } })
66
+ const warning = assuranceWarning()
67
+ const originalWarn = console.warn
68
+ if (warning !== undefined) console.warn = (...args) => warning(args.map(String).join(" "))
69
+ try {
70
+ svelteHydrate(Router, {
71
+ target: container as Element,
72
+ props: { router, routes, searchSchemas },
73
+ })
74
+ } finally {
75
+ if (warning !== undefined) console.warn = originalWarn
76
+ }
36
77
  }
package/src/index.ts CHANGED
@@ -6,15 +6,82 @@
6
6
  * Svelte components compile from `.svelte` files, so this adapter ships a build plugin (like
7
7
  * `@nifrajs/web-solid`'s Babel plugin) - there is no callable-component runtime.
8
8
  */
9
- import type { RenderAdapter } from "@nifrajs/web"
10
- import { render } from "svelte/server"
11
- import Chain from "./Chain.svelte"
9
+ import { fileURLToPath } from "node:url"
10
+ import type { RenderAdapter, RenderProps } from "@nifrajs/web"
11
+ import { ssrModuleLoader } from "@nifrajs/web"
12
+ import type { Component } from "svelte"
13
+ import { render as runtimeRender } from "svelte/server"
12
14
 
13
- // Re-export the compiler plugin for convenience. NOTE: the SSR preload must import it from
14
- // `@nifrajs/web-svelte/plugin` (not from here) - importing this module eagerly loads `Chain.svelte`,
15
- // which must be compiled by the already-registered plugin.
15
+ // Re-export the compiler plugin for convenience.
16
16
  export { svelteBunPlugin } from "./plugin.ts"
17
17
 
18
+ /**
19
+ * `Chain.svelte` is loaded on FIRST RENDER, not at module load.
20
+ *
21
+ * A static `import Chain from "./Chain.svelte"` here is unloadable in dev. The CLI's `loadApp` imports
22
+ * the app's config, which re-exports this adapter, so this module evaluates before any Svelte compiler
23
+ * is registered in the runtime - and a raw `.svelte` file then loads as a path string, so SSR dies at
24
+ * render with `component is not a function`, naming the asset rather than the ordering. Bundled builds
25
+ * never saw it: `Bun.build` compiles the whole graph up front.
26
+ *
27
+ * Deferring to first render moves the load AFTER the dev server has registered the app's
28
+ * `serverPlugins`, which is the only point at which a compiler is guaranteed to exist.
29
+ *
30
+ * Exactly ONE render pays for that. `chain` is memoized as a plain value, so every later call takes the
31
+ * synchronous branch below and allocates no promise - awaiting on the hot path measured as a real 3%
32
+ * throughput loss on the SSR benchmark, which is not a price worth paying for a one-time import.
33
+ */
34
+ /**
35
+ * What `Chain.svelte` destructures from `$props()`.
36
+ *
37
+ * A type alias rather than an `interface` on purpose. `.svelte` files are compiled by a bundler, not
38
+ * by tsc, so they arrive through the ambient shim as `Component<Record<string, unknown>>` and the load
39
+ * below narrows that to this shape. An interface has no implicit index signature, so that narrowing is
40
+ * a comparison between two unrelated types and `svelte-check` rejects it; a type alias does have one,
41
+ * which makes the narrowing legal to state directly instead of laundering it through `unknown`.
42
+ */
43
+ type ChainProps = {
44
+ readonly chain: readonly unknown[]
45
+ readonly props: RenderProps
46
+ /** Explicitly `| undefined`: the adapter always passes the key, and `RenderProps.layoutData` is
47
+ * optional, so under `exactOptionalPropertyTypes` the absent case has to be part of the type. */
48
+ readonly layoutData: readonly unknown[] | undefined
49
+ }
50
+ let chainComponent: Component<ChainProps> | undefined
51
+ let chainPromise: Promise<Component<ChainProps>> | undefined
52
+ /**
53
+ * Svelte's server renderer. Normally the runtime's, but it is swapped for the dev server's copy when
54
+ * `Chain` comes from there - a component compiled by one toolchain has to render through the renderer
55
+ * that toolchain resolved, or `setContext` writes into a renderer the children never read.
56
+ */
57
+ let render: typeof runtimeRender = runtimeRender
58
+ /** Resolved `Chain`, or the in-flight load on the very first call. */
59
+ const loadChain = (): Component<ChainProps> | Promise<Component<ChainProps>> => {
60
+ if (chainComponent !== undefined) return chainComponent
61
+ // A dev server that owns SSR resolution compiles the app's `.svelte` routes itself, and `Chain` has
62
+ // to come from that same graph: the runtime has no `.svelte` loader on that pipeline, so a plain
63
+ // `import` yields the file PATH and SSR dies at `component is not a function`. Registering a second
64
+ // compiler in the runtime instead is the trap - it gives the tree two Svelte runtimes, and the
65
+ // renderer `Chain` sets context on is not the one the routes read it from. Taking BOTH the component
66
+ // and `svelte/server` from the dev server keeps it at one compiler and one runtime.
67
+ const load = ssrModuleLoader()
68
+ chainPromise ??= (
69
+ load !== undefined
70
+ ? Promise.all([
71
+ load(fileURLToPath(new URL("./Chain.svelte", import.meta.url))),
72
+ load("svelte/server"),
73
+ ]).then(([mod, server]) => {
74
+ render = (server as { render: typeof runtimeRender }).render
75
+ return (mod as { default: Component<ChainProps> }).default
76
+ })
77
+ : import("./Chain.svelte").then((m) => m.default as Component<ChainProps>)
78
+ ).then((c) => {
79
+ chainComponent = c
80
+ return c
81
+ })
82
+ return chainPromise
83
+ }
84
+
18
85
  // Svelte SSR yields a complete HTML string; the seam wants a stream, so emit it as one chunk.
19
86
  function oneChunk(html: string): ReadableStream<Uint8Array> {
20
87
  const bytes = new TextEncoder().encode(html)
@@ -32,16 +99,25 @@ export const svelteAdapter: RenderAdapter = {
32
99
  // returns the body directly (renderPage buffers it on the non-deferred fast path), and
33
100
  // `renderToStream` wraps the same string in a one-chunk stream for the deferred path. No streaming
34
101
  // renderer to skip here - but going straight to a string avoids the per-request stream allocation.
102
+ // The seam allows `string | Promise<string>`, so the first render can resolve `Chain` while every
103
+ // render after it stays a plain synchronous call - see `loadChain`.
35
104
  renderToString(chain, props) {
36
- return render(Chain, { props: { chain, props, layoutData: props.layoutData } }).body
105
+ const Chain = loadChain()
106
+ const props$ = { chain, props, layoutData: props.layoutData }
107
+ return Chain instanceof Promise
108
+ ? Chain.then((C) => render(C, { props: props$ }).body)
109
+ : render(Chain, { props: props$ }).body
37
110
  },
38
111
  renderToStream(chain, props) {
39
112
  // `Chain` folds the layout chain (page innermost gets `props`; layouts wrap via their `children`
40
113
  // snippet). Svelte's `render` returns { head, body }; the body goes into #root. (Svelte's dynamic
41
114
  // `head` - from <svelte:head> - isn't surfaced through the seam's static `hydrationHead`; nifra's
42
115
  // own meta/head API manages the document head instead.)
43
- const { body } = render(Chain, { props: { chain, props, layoutData: props.layoutData } })
44
- return oneChunk(body)
116
+ const Chain = loadChain()
117
+ const props$ = { chain, props, layoutData: props.layoutData }
118
+ return Chain instanceof Promise
119
+ ? Chain.then((C) => oneChunk(render(C, { props: props$ }).body))
120
+ : oneChunk(render(Chain, { props: props$ }).body)
45
121
  },
46
122
  // Svelte's client `hydrate` reconciles against the existing DOM; no per-document bootstrap script is
47
123
  // needed (contrast Solid's generateHydrationScript) - the seam allows the empty string.
package/src/mdx.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { rewriteSsrImports } from "@nifrajs/web/plugins/kit"
1
2
  import type { BunPlugin } from "bun"
2
3
  import { compile } from "svelte/compiler"
3
4
 
@@ -57,7 +58,7 @@ export function svelteMdxBunPlugin(generate: "dom" | "ssr"): BunPlugin {
57
58
  loader: "js",
58
59
  }
59
60
  }
60
- return { contents: js.code, loader: "js" }
61
+ return { contents: rewriteSsrImports(js.code, path, generate), loader: "js" }
61
62
  })
62
63
  build.onResolve({ filter: /\?svelte-mdx-css$/ }, (args) => ({
63
64
  path: args.path,
package/src/plugin.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { devHotComponent, devServerCompile, rewriteSsrImports } from "@nifrajs/web/plugins/kit"
1
2
  import type { BunPlugin } from "bun"
2
3
  import { compile } from "svelte/compiler"
3
4
 
@@ -20,6 +21,29 @@ import { compile } from "svelte/compiler"
20
21
  const STYLE_SUFFIX = "?svelte-css"
21
22
  const STYLE_NS = "nifra-svelte-css"
22
23
 
24
+ /**
25
+ * The same hot-patch boundary as the Bun pipeline's, in the shape `@sveltejs/vite-plugin-svelte` takes:
26
+ *
27
+ * ```ts
28
+ * svelte({ dynamicCompileOptions: svelteHmrBoundary })
29
+ * ```
30
+ *
31
+ * Svelte's HMR wrapper resolves the component through a signal, which survives hydration only where
32
+ * the component is a plain child in a template. A layout or a page is not: the adapter's `Chain` enters
33
+ * chain members as dynamic components and through snippets, so a wrapper on one leaves the hydration
34
+ * cursor pointing at markup the wrapped component never claims. Svelte then throws the server's tree
35
+ * away and re-renders on the client - `hydration_mismatch` in the console, on first load, before any
36
+ * edit. Left on, the dev server quietly stops exercising hydration at all.
37
+ *
38
+ * Views keep hot-patching; route modules fall back to a full reload, which is what they want anyway
39
+ * (a route module carries the loader and meta the server ran, and re-running those is a navigation).
40
+ * Outside a nifra dev server nothing is announced and the answer is "no boundary" - a full reload is
41
+ * always correct, a mispatched tree is not.
42
+ */
43
+ export function svelteHmrBoundary({ filename }: { filename: string }): { hmr: boolean } {
44
+ return { hmr: devHotComponent(filename) }
45
+ }
46
+
23
47
  export function svelteBunPlugin(generate: "dom" | "ssr"): BunPlugin {
24
48
  // Compiled scoped CSS per `.svelte` file (client build only) - read back by the virtual-module loader.
25
49
  const cssByPath = new Map<string, string>()
@@ -31,10 +55,35 @@ export function svelteBunPlugin(generate: "dom" | "ssr"): BunPlugin {
31
55
  build.onLoad({ filter: /\.svelte(\?|$)/ }, async (args) => {
32
56
  const path = args.path.split("?")[0] ?? args.path
33
57
  const source = await Bun.file(path).text()
58
+ // Per compile, not per registration: the CLI registers the SSR plugin before the dev server
59
+ // exists, and the flag is set by the dev server.
60
+ //
61
+ // Svelte's HMR is a compiler feature (`$.hmr` + a self-accepting `import.meta.hot.accept`), and
62
+ // it is only available under `dev`. `dev` is set on BOTH halves so the server and client builds
63
+ // stay the same Svelte, while `hmr` stays client-only, there being no `import.meta.hot` on the
64
+ // server. `nifra build` sets neither, so nothing here reaches a production bundle.
65
+ //
66
+ // The server half additionally needs Svelte's own runtime in its dev shape - `dev` output calls
67
+ // `push_element`, which reads state the runtime only records when ITS `DEV` is true. That flag
68
+ // resolves through `esm-env`, which falls back to `NODE_ENV` off the export conditions; the dev
69
+ // server sets it for exactly this reason. Getting that half wrong throws on the first element:
70
+ // `undefined is not an object (evaluating 'context.function[FILENAME]')`.
71
+ //
72
+ // `hmr` narrows further, to the app's own non-route components ({@link devHotComponent}).
73
+ // Svelte's wrapper replaces the component with a block that resolves it through a signal, and
74
+ // that survives hydration only where the component is a plain child in a template. A chain
75
+ // member is not: the adapter's `Chain` enters layouts and pages as dynamic components and
76
+ // through snippets, and a wrapper on either side of that leaves the hydration cursor pointing
77
+ // at markup the wrapped component never claims - the whole tree is then thrown away and
78
+ // re-rendered on the client, silently, before any edit. A view component is the boundary that
79
+ // works, and it is also the one worth patching.
80
+ const dev = devServerCompile()
34
81
  const { js, css } = compile(source, {
35
82
  generate: generate === "ssr" ? "server" : "client",
36
83
  filename: path,
37
84
  css: "external", // emit the scoped stylesheet separately (not injected into the JS)
85
+ dev,
86
+ hmr: dev && generate === "dom" && devHotComponent(path),
38
87
  })
39
88
  if (generate === "dom" && css?.code) {
40
89
  cssByPath.set(path, css.code)
@@ -44,7 +93,7 @@ export function svelteBunPlugin(generate: "dom" | "ssr"): BunPlugin {
44
93
  loader: "js",
45
94
  }
46
95
  }
47
- return { contents: js.code, loader: "js" }
96
+ return { contents: rewriteSsrImports(js.code, path, generate), loader: "js" }
48
97
  })
49
98
  // Virtual CSS module: `<file>.svelte?svelte-css` → the compiled scoped stylesheet (css loader).
50
99
  build.onResolve({ filter: /\?svelte-css$/ }, (args) => ({
package/src/query.ts CHANGED
@@ -1,9 +1,7 @@
1
- import {
2
- createQueryClient,
3
- type QueryClient,
4
- type QueryHandle,
5
- type QueryState,
6
- } from "@nifrajs/web"
1
+ import type { QueryClient, QueryHandle, QueryState } from "@nifrajs/web"
2
+ // `/client`, not the root - these are DOM values, and the root's graph carries the
3
+ // server, which Vite's dev server evaluates rather than tree-shakes.
4
+ import { createQueryClient } from "@nifrajs/web/client"
7
5
  /**
8
6
  * `@nifrajs/web-svelte/query` - Svelte bindings for the keyed query-cache, as **Svelte stores** (plain
9
7
  * `.ts`). `useQuery(key, fn)` returns a `Readable<QueryState<T>>` augmented with `refetch` - read it
package/src/router.ts CHANGED
@@ -1,15 +1,23 @@
1
1
  import type { InferOutput, StandardSchemaV1 } from "@nifrajs/core/server"
2
+ // `import type` + a local re-export, NOT `export type { … } from "@nifrajs/web"`: that form leaves a
3
+ // bare `import "@nifrajs/web"` in the output, which pulls the server graph into the browser under
4
+ // Vite's dev server. Sourced from the ROOT so the generated `RouteSearch` augmentation applies.
5
+ import type {
6
+ Blocker,
7
+ BlockerFunction,
8
+ BlockerState,
9
+ NavigateFunction,
10
+ NavigateOptions,
11
+ NavigateTargetInput,
12
+ } from "@nifrajs/web"
13
+ // `/client`, not the root - these are DOM values, and the root's graph carries the
14
+ // server, which Vite's dev server evaluates rather than tree-shakes.
2
15
  import {
3
- type Blocker,
4
- type BlockerFunction,
5
16
  getBrowserNavigate,
6
17
  IDLE_BLOCKER,
7
- type NavigateFunction,
8
- type NavigateOptions,
9
- type NavigateTargetInput,
10
18
  registerBlocker,
11
19
  resolveNavigate,
12
- } from "@nifrajs/web"
20
+ } from "@nifrajs/web/client"
13
21
  import { getContext } from "svelte"
14
22
  /**
15
23
  * `@nifrajs/web-svelte/router` - Svelte routing bindings over the agnostic `@nifrajs/web` history layer,
@@ -21,7 +29,7 @@ import { getContext } from "svelte"
21
29
  */
22
30
  import { type Readable, readable } from "svelte/store"
23
31
 
24
- export type { Blocker, BlockerFunction, BlockerState, NavigateFunction } from "@nifrajs/web"
32
+ export type { Blocker, BlockerFunction, BlockerState, NavigateFunction }
25
33
 
26
34
  // Must match the string key `Chain.svelte` passes to `setContext` (a string avoids a `.svelte` → `.ts`
27
35
  // import that wouldn't resolve once the .svelte is copied to dist).