@nifrajs/web-svelte 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +18 -0
- package/dist/Await.svelte +27 -0
- package/dist/Await.svelte.d.ts +21 -0
- package/dist/Chain.svelte +35 -0
- package/dist/Content.svelte +13 -0
- package/dist/Content.svelte.d.ts +17 -0
- package/dist/I18nProvider.svelte +20 -0
- package/dist/I18nProvider.svelte.d.ts +15 -0
- package/dist/Image.svelte +27 -0
- package/dist/Image.svelte.d.ts +29 -0
- package/dist/Router.svelte +27 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +30 -0
- package/dist/client.js.map +1 -0
- package/dist/error.d.ts +13 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +5 -0
- package/dist/error.js.map +1 -0
- package/dist/fetcher.d.ts +36 -0
- package/dist/fetcher.d.ts.map +1 -0
- package/dist/fetcher.js +55 -0
- package/dist/fetcher.js.map +1 -0
- package/dist/i18n.d.ts +11 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +15 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mdx.d.ts +5 -0
- package/dist/mdx.d.ts.map +1 -0
- package/dist/mdx.js +74 -0
- package/dist/mdx.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +58 -0
- package/dist/plugin.js.map +1 -0
- package/dist/query.d.ts +26 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +55 -0
- package/dist/query.js.map +1 -0
- package/package.json +111 -0
- package/src/Await.svelte +27 -0
- package/src/Await.svelte.d.ts +21 -0
- package/src/Chain.svelte +35 -0
- package/src/Content.svelte +13 -0
- package/src/Content.svelte.d.ts +17 -0
- package/src/I18nProvider.svelte +20 -0
- package/src/I18nProvider.svelte.d.ts +15 -0
- package/src/Image.svelte +27 -0
- package/src/Image.svelte.d.ts +29 -0
- package/src/Router.svelte +27 -0
- package/src/client.ts +33 -0
- package/src/error.ts +15 -0
- package/src/fetcher.ts +66 -0
- package/src/i18n.ts +23 -0
- package/src/index.ts +51 -0
- package/src/mdx.ts +72 -0
- package/src/plugin.ts +60 -0
- package/src/query.ts +66 -0
- package/src/svelte-shim.d.ts +9 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nifra Authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @nifrajs/web-svelte
|
|
2
|
+
|
|
3
|
+
Svelte 5 render adapter for @nifrajs/web — SSR + hydration + the .svelte compiler Bun-plugin.
|
|
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`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
bun add @nifrajs/web-svelte
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Docs
|
|
14
|
+
|
|
15
|
+
- Reference: <https://nifra.dev/docs>
|
|
16
|
+
- AI-readable: <https://nifra.dev/llms.txt>
|
|
17
|
+
|
|
18
|
+
MIT
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Await.svelte — the `<Await>` primitive for deferred loader/action data (`defer()`), built on Svelte's
|
|
3
|
+
native `{#await}` block + scoped-snippet props: `children(value)` (resolved), `pending`, `error(err)`.
|
|
4
|
+
|
|
5
|
+
Svelte SSR renders the PENDING branch of `{#await}` (it does not block on the promise), so the server
|
|
6
|
+
emits the fallback and the client resolves it (hydration / soft-nav) — matching nifra's non-blocking
|
|
7
|
+
`defer()` (like the Vue adapter; contrast React/Preact, which stream the resolved content into the SSR
|
|
8
|
+
HTML). An already-resolved `resolve` (a plain value, or a client nav that awaited it) renders directly.
|
|
9
|
+
Plain-JS script (no TS) so it needs no svelte TS preprocessor.
|
|
10
|
+
-->
|
|
11
|
+
<script>
|
|
12
|
+
let { resolve, children, pending, error } = $props()
|
|
13
|
+
const isDeferred = (v) =>
|
|
14
|
+
v != null && typeof v === "object" && v.__velo_deferred === true
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#if isDeferred(resolve)}
|
|
18
|
+
{#await resolve.promise}
|
|
19
|
+
{@render pending?.()}
|
|
20
|
+
{:then value}
|
|
21
|
+
{@render children?.(value)}
|
|
22
|
+
{:catch err}
|
|
23
|
+
{@render error?.(err)}
|
|
24
|
+
{/await}
|
|
25
|
+
{:else}
|
|
26
|
+
{@render children?.(resolve)}
|
|
27
|
+
{/if}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Deferred } from "@nifrajs/web"
|
|
2
|
+
import type { Component, Snippet } from "svelte"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hand-written types for `Await.svelte` (svelte-package would generate this from the component). The
|
|
6
|
+
* internal build resolves `*.svelte` via the ambient `svelte-shim.d.ts`; this file is what *consumers*
|
|
7
|
+
* resolve through the `./await` export's `types` condition.
|
|
8
|
+
*/
|
|
9
|
+
export interface AwaitProps {
|
|
10
|
+
/** A `Deferred<T>` from a loader/action's `defer(...)`, or an already-resolved value. */
|
|
11
|
+
resolve: Deferred<unknown> | unknown
|
|
12
|
+
/** Rendered with the resolved value (the default snippet). */
|
|
13
|
+
children?: Snippet<[unknown]>
|
|
14
|
+
/** Rendered while the deferred is pending (the SSR + pre-resolve state). */
|
|
15
|
+
pending?: Snippet
|
|
16
|
+
/** Rendered if the deferred rejects. */
|
|
17
|
+
error?: Snippet<[unknown]>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const Await: Component<AwaitProps>
|
|
21
|
+
export default Await
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Chain.svelte — folds a nifra layout chain (outermost layout → page) into nested Svelte components:
|
|
3
|
+
the page (innermost, chain[last]) receives `props` (the loader data); each layout wraps the rest via
|
|
4
|
+
its `children` snippet ({@render children()} in the layout). Recurses on itself. This is the Svelte
|
|
5
|
+
analogue of the React/Vue `compose` — Svelte components are compiled (not callable), so the fold is a
|
|
6
|
+
component, not a function returning a node.
|
|
7
|
+
-->
|
|
8
|
+
<script>
|
|
9
|
+
import Self from "./Chain.svelte"
|
|
10
|
+
let { chain, props } = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{#if chain.length <= 1}
|
|
14
|
+
{#if chain[0]}
|
|
15
|
+
{@const Page = chain[0]}
|
|
16
|
+
<Page {...props} />
|
|
17
|
+
{/if}
|
|
18
|
+
{:else if chain[0] && chain[0].__veloErrorBoundary}
|
|
19
|
+
<!-- nifra `_error` boundary marker (from errorBoundary()): wrap the rest in <svelte:boundary>; the
|
|
20
|
+
`failed` snippet renders the route's _error component with the serialized error. -->
|
|
21
|
+
{@const Fallback = chain[0].__veloErrorBoundary}
|
|
22
|
+
<svelte:boundary>
|
|
23
|
+
<Self chain={chain.slice(1)} {props} />
|
|
24
|
+
{#snippet failed(error)}
|
|
25
|
+
<Fallback data={{ name: error?.name ?? "Error", message: String(error?.message ?? error) }} />
|
|
26
|
+
{/snippet}
|
|
27
|
+
</svelte:boundary>
|
|
28
|
+
{:else}
|
|
29
|
+
{@const Layout = chain[0]}
|
|
30
|
+
<Layout>
|
|
31
|
+
{#snippet children()}
|
|
32
|
+
<Self chain={chain.slice(1)} {props} />
|
|
33
|
+
{/snippet}
|
|
34
|
+
</Layout>
|
|
35
|
+
{/if}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Content.svelte — render trusted pre-rendered HTML (e.g. a @nifrajs/content collection entry's `.html`)
|
|
3
|
+
into the DOM via Svelte's {@html}. Pairs with content collections: <Content html={entry.html} />.
|
|
4
|
+
`as` picks the wrapper element; extra attributes in `...rest` (class/style/id/data-*) pass through.
|
|
5
|
+
|
|
6
|
+
Security: {@html} injects raw HTML, so `html` MUST be trusted (your own Markdown/content, rendered at
|
|
7
|
+
build/server time) — never pass user-supplied HTML without sanitizing it first. Plain-JS script.
|
|
8
|
+
-->
|
|
9
|
+
<script>
|
|
10
|
+
let { html, as = "div", ...rest } = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<svelte:element this={as} {...rest}>{@html html}</svelte:element>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Component } from "svelte"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hand-written types for `Content.svelte` (svelte-package would generate this). Consumers resolve this
|
|
5
|
+
* through the `./content` export's `types` condition.
|
|
6
|
+
*/
|
|
7
|
+
export interface ContentProps {
|
|
8
|
+
/** Trusted, pre-rendered HTML (e.g. `entry.html`). */
|
|
9
|
+
html: string
|
|
10
|
+
/** Wrapper element (default `"div"`). */
|
|
11
|
+
as?: string
|
|
12
|
+
/** DOM passthrough (`class`, `style`, `id`, `data-*`, …). */
|
|
13
|
+
[key: string]: unknown
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const Content: Component<ContentProps>
|
|
17
|
+
export default Content
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
I18nProvider.svelte — provides a nifra i18n `Formatter` (built from `locale` + `messages`) to the
|
|
3
|
+
subtree via Svelte context; consumers read it with `useT()` from `@nifrajs/web-svelte/i18n`. The
|
|
4
|
+
formatter is `$derived`, so switching locale rebuilds it. `locale` + `messages` are serializable, so
|
|
5
|
+
SSR renders the negotiated catalog and the client rebuilds the same formatter on hydrate (no
|
|
6
|
+
mismatch). Plain-JS script. The context key is a string (kept in sync with i18n.ts's `useT`) so this
|
|
7
|
+
component needs no `.ts` import.
|
|
8
|
+
-->
|
|
9
|
+
<script>
|
|
10
|
+
import { createFormatter } from "@nifrajs/i18n"
|
|
11
|
+
import { setContext } from "svelte"
|
|
12
|
+
|
|
13
|
+
let { locale, messages, children } = $props()
|
|
14
|
+
|
|
15
|
+
const formatter = $derived(createFormatter(locale, messages))
|
|
16
|
+
// A getter (not the value) so consumers read the current `$derived` formatter reactively.
|
|
17
|
+
setContext("@nifrajs/web-svelte:i18n", () => formatter)
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
{@render children?.()}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Messages } from "@nifrajs/i18n"
|
|
2
|
+
import type { Component, Snippet } from "svelte"
|
|
3
|
+
|
|
4
|
+
/** Hand-written types for `I18nProvider.svelte` (consumers resolve these via the `./i18n` re-export). */
|
|
5
|
+
export interface I18nProviderProps {
|
|
6
|
+
/** The active locale (e.g. `"en"`, `"fr-CA"`). */
|
|
7
|
+
locale: string
|
|
8
|
+
/** The ICU message catalog for `locale`. */
|
|
9
|
+
messages: Messages
|
|
10
|
+
/** The subtree that reads the formatter via `useT()`. */
|
|
11
|
+
children?: Snippet
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const I18nProvider: Component<I18nProviderProps>
|
|
15
|
+
export default I18nProvider
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Image.svelte — a CLS-safe responsive <Image> for nifra + Svelte. A thin wrapper over `resolveImage` +
|
|
3
|
+
`toHtmlAttrs` from @nifrajs/image: it computes the responsive <img> attributes (src/srcset/sizes/width/
|
|
4
|
+
height/loading/decoding/fetchpriority — lowercase HTML names) and renders an <img>. Any extra
|
|
5
|
+
attributes (class/style/id/data-*/handlers in `...rest`) pass through. `width`+`height` are required
|
|
6
|
+
(reserve layout space — no CLS); `priority` marks the LCP image. Resizing is delegated to the
|
|
7
|
+
`loader` (an image CDN); nifra bundles no codec. Plain-JS script (no TS preprocessor needed).
|
|
8
|
+
-->
|
|
9
|
+
<script>
|
|
10
|
+
import { resolveImage, toHtmlAttrs } from "@nifrajs/image"
|
|
11
|
+
|
|
12
|
+
let { src, width, height, alt, sizes, widths, quality, loading, priority, loader, ...rest } = $props()
|
|
13
|
+
|
|
14
|
+
// `$derived` keeps the attributes in sync if props change. Build ImageProps omitting unset optionals;
|
|
15
|
+
// resolveImage validates width/height > 0 (the CLS contract) and builds the responsive srcSet.
|
|
16
|
+
const attrs = $derived.by(() => {
|
|
17
|
+
const input = { src, width, height, alt }
|
|
18
|
+
if (sizes !== undefined) input.sizes = sizes
|
|
19
|
+
if (widths !== undefined) input.widths = widths
|
|
20
|
+
if (quality !== undefined) input.quality = quality
|
|
21
|
+
if (loading !== undefined) input.loading = loading
|
|
22
|
+
if (priority !== undefined) input.priority = priority
|
|
23
|
+
return toHtmlAttrs(resolveImage(input, loader))
|
|
24
|
+
})
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<img {...rest} {...attrs} />
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ImageLoader, ImageProps } from "@nifrajs/image"
|
|
2
|
+
import type { Component } from "svelte"
|
|
3
|
+
import type { HTMLImgAttributes } from "svelte/elements"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hand-written types for `Image.svelte` (svelte-package would generate this). The internal build
|
|
7
|
+
* resolves `*.svelte` via the ambient `svelte-shim.d.ts`; this file is what *consumers* resolve through
|
|
8
|
+
* the `./image` export's `types` condition.
|
|
9
|
+
*/
|
|
10
|
+
type ComputedAttrs =
|
|
11
|
+
| "src"
|
|
12
|
+
| "srcset"
|
|
13
|
+
| "sizes"
|
|
14
|
+
| "width"
|
|
15
|
+
| "height"
|
|
16
|
+
| "alt"
|
|
17
|
+
| "loading"
|
|
18
|
+
| "decoding"
|
|
19
|
+
| "fetchpriority"
|
|
20
|
+
|
|
21
|
+
export interface ImageComponentProps
|
|
22
|
+
extends ImageProps,
|
|
23
|
+
Omit<HTMLImgAttributes, ComputedAttrs | keyof ImageProps> {
|
|
24
|
+
/** CDN URL builder. Defaults to the identity loader (no transform — still CLS-safe + lazy). */
|
|
25
|
+
loader?: ImageLoader
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare const Image: Component<ImageComponentProps>
|
|
29
|
+
export default Image
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Router.svelte — the reactive root for client navigation. Holds the agnostic store's snapshot in
|
|
3
|
+
`$state`, subscribes via `$effect` (cleaned up on unmount), and renders the matched layout chain
|
|
4
|
+
through `Chain.svelte`. `$derived` recomputes the chain + props on every store change, so client
|
|
5
|
+
navigations swap routes without a full reload. The initial snapshot matches the SSR markup (the
|
|
6
|
+
server rendered `Chain` for the same matched route), so `hydrate` reconciles cleanly.
|
|
7
|
+
|
|
8
|
+
Runes (`$state`/`$effect`/`$derived`) only work in compiled `.svelte` files — which is why this
|
|
9
|
+
reactive root is a component, not a function in `client.ts`.
|
|
10
|
+
-->
|
|
11
|
+
<script>
|
|
12
|
+
import Chain from "./Chain.svelte"
|
|
13
|
+
let { router, routes } = $props()
|
|
14
|
+
|
|
15
|
+
let snapshot = $state(router.snapshot())
|
|
16
|
+
$effect(() => router.subscribe(() => { snapshot = router.snapshot() }))
|
|
17
|
+
|
|
18
|
+
let chain = $derived(routes[snapshot.routeId] ?? [])
|
|
19
|
+
let props = $derived({
|
|
20
|
+
data: snapshot.data,
|
|
21
|
+
actionData: snapshot.actionData,
|
|
22
|
+
pending: snapshot.pending,
|
|
23
|
+
...(snapshot.submission ? { submission: snapshot.submission } : {}),
|
|
24
|
+
})
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<Chain {chain} {props} />
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MountRouterOptions, RenderProps } from "@nifrajs/web";
|
|
2
|
+
export { errorBoundary } from "./error.js";
|
|
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;
|
|
5
|
+
/**
|
|
6
|
+
* Hydrate a stateful Svelte Router. The `Router` component holds the store snapshot in `$state` and
|
|
7
|
+
* re-renders the matched layout chain on each store change — so client navigations swap routes without
|
|
8
|
+
* a full reload. Its initial render matches the SSR markup (the server rendered `Chain` for the same
|
|
9
|
+
* matched route), so hydration reconciles cleanly.
|
|
10
|
+
*/
|
|
11
|
+
export declare function mountRouter(options: MountRouterOptions): void;
|
|
12
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +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,CAE/F;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAI7D"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nifrajs/web-svelte/client — Svelte 5 client runtime. `hydrate` hydrates a single SSR'd route via the
|
|
3
|
+
* recursive `Chain`; `mountRouter` hydrates the reactive `Router` component, which subscribes to the
|
|
4
|
+
* agnostic store and re-renders the matched chain on every client navigation (no full reload). Both
|
|
5
|
+
* use Svelte's `hydrate` (reconcile against the SSR markup). Kept in its own entry so server code
|
|
6
|
+
* stays out of the client bundle.
|
|
7
|
+
*/
|
|
8
|
+
import { hydrate as svelteHydrate } from "svelte";
|
|
9
|
+
import Chain from "./Chain.svelte";
|
|
10
|
+
import { setMountedRouter } from "./fetcher.js";
|
|
11
|
+
import Router from "./Router.svelte";
|
|
12
|
+
// The `_error` boundary marker — Chain.svelte renders it as a <svelte:boundary>. Re-exported here so
|
|
13
|
+
// nifra's client codegen resolves it from `@nifrajs/web-svelte/client` alongside `mountRouter`.
|
|
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, { target: container, props: { chain, props } });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hydrate a stateful Svelte Router. The `Router` component holds the store snapshot in `$state` and
|
|
21
|
+
* re-renders the matched layout chain on each store change — so client navigations swap routes without
|
|
22
|
+
* a full reload. Its initial render matches the SSR markup (the server rendered `Chain` for the same
|
|
23
|
+
* matched route), so hydration reconciles cleanly.
|
|
24
|
+
*/
|
|
25
|
+
export function mountRouter(options) {
|
|
26
|
+
const { router, routes, container } = options;
|
|
27
|
+
setMountedRouter(router); // expose it to useFetcher/useFetchers (same page, client-only)
|
|
28
|
+
svelteHydrate(Router, { target: container, props: { router, routes } });
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +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,EAAE,MAAM,EAAE,SAAoB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;AACjF,CAAC;AAED;;;;;GAKG;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,+DAA+D;IACxF,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAoB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;AACpF,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `errorBoundary` — the Svelte `_error.tsx` boundary chain element. Svelte components are compiled (not
|
|
3
|
+
* JS closures), so unlike the other adapters this can't return a component bound to `fallback`. Instead
|
|
4
|
+
* it returns a **marker** that `Chain.svelte` recognises and renders as a `<svelte:boundary>` (Svelte
|
|
5
|
+
* 5.3+) with `fallback` as the `failed` snippet. Re-exported from `@nifrajs/web-svelte/client` so nifra's
|
|
6
|
+
* client codegen inserts it before the page in the matched chain.
|
|
7
|
+
*/
|
|
8
|
+
export interface NifraSvelteErrorBoundary {
|
|
9
|
+
readonly __nifraErrorBoundary: unknown;
|
|
10
|
+
}
|
|
11
|
+
/** Wrap a route's `_error` component as a boundary marker for `Chain.svelte` to render. */
|
|
12
|
+
export declare function errorBoundary(fallback: unknown): NifraSvelteErrorBoundary;
|
|
13
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;CACvC;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,wBAAwB,CAEzE"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAWA,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,QAAiB;IAC7C,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAA;AAC3C,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ClientRouter, Fetcher, FetcherState } from "@nifrajs/web";
|
|
2
|
+
/**
|
|
3
|
+
* `@nifrajs/web-svelte/fetcher` — Svelte bindings for concurrent fetchers, as **Svelte stores** (plain
|
|
4
|
+
* `.ts`, no runes/compiler needed). `useFetcher(key)` returns a `Readable<FetcherState>` augmented with
|
|
5
|
+
* `load`/`submit` — read it reactively in a component with `$fetcher` (auto-subscription), call
|
|
6
|
+
* `fetcher.load(...)` / `fetcher.submit(...)` imperatively. `useFetchers()` returns the live collection
|
|
7
|
+
* as a store. The store's start/stop notifier subscribes to the agnostic store lazily (on the first
|
|
8
|
+
* `$`-subscription) and unsubscribes on the last — so lifecycle is tied to the component automatically.
|
|
9
|
+
*
|
|
10
|
+
* The router that owns the fetchers is the one `mountRouter` hydrated — it registers itself here via
|
|
11
|
+
* `setMountedRouter`. On the server (no mount) there is no router, so the stores hold an idle value
|
|
12
|
+
* (fetchers are client-only); the first client render starts from the same idle snapshot — no mismatch.
|
|
13
|
+
*/
|
|
14
|
+
import { type Readable } from "svelte/store";
|
|
15
|
+
/** Register (or clear) the router that owns fetchers — called by `mountRouter`. Not for app use. */
|
|
16
|
+
export declare function setMountedRouter(router: ClientRouter | undefined): void;
|
|
17
|
+
/** A fetcher store: a `Readable<FetcherState>` (read via `$`) plus imperative `load`/`submit`. */
|
|
18
|
+
export type FetcherStore = Readable<FetcherState> & {
|
|
19
|
+
/** Load a route path's loader data into this fetcher (concurrent; doesn't touch the active view). */
|
|
20
|
+
readonly load: (path: string) => Promise<void>;
|
|
21
|
+
/** Submit an action into this fetcher (concurrent); honors `X-Nifra-Revalidate`. */
|
|
22
|
+
readonly submit: (action: string, body: NonNullable<RequestInit["body"]>) => Promise<void>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Subscribe to the independent fetcher for `key` (created lazily, stable across renders). Returns a
|
|
26
|
+
* store of its state (`pending`/`data`/`actionData`/`submission`) augmented with `load`/`submit`.
|
|
27
|
+
* Multiple `useFetcher` calls with different keys run concurrently without disturbing the active route.
|
|
28
|
+
*/
|
|
29
|
+
export declare function useFetcher(key: string): FetcherStore;
|
|
30
|
+
/**
|
|
31
|
+
* Subscribe to the whole live fetcher collection — for a global busy view (e.g. "3 saving…"). Read
|
|
32
|
+
* each entry's `.snapshot()` for its state. The store updates whenever any fetcher transitions or a
|
|
33
|
+
* new one is created.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useFetchers(): Readable<readonly Fetcher[]>;
|
|
36
|
+
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACvE;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAA;AAMtD,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAEvE;AAKD,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG;IAClD,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,oFAAoF;IACpF,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3F,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAWpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,SAAS,OAAO,EAAE,CAAC,CAO1D"}
|
package/dist/fetcher.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nifrajs/web-svelte/fetcher` — Svelte bindings for concurrent fetchers, as **Svelte stores** (plain
|
|
3
|
+
* `.ts`, no runes/compiler needed). `useFetcher(key)` returns a `Readable<FetcherState>` augmented with
|
|
4
|
+
* `load`/`submit` — read it reactively in a component with `$fetcher` (auto-subscription), call
|
|
5
|
+
* `fetcher.load(...)` / `fetcher.submit(...)` imperatively. `useFetchers()` returns the live collection
|
|
6
|
+
* as a store. The store's start/stop notifier subscribes to the agnostic store lazily (on the first
|
|
7
|
+
* `$`-subscription) and unsubscribes on the last — so lifecycle is tied to the component automatically.
|
|
8
|
+
*
|
|
9
|
+
* The router that owns the fetchers is the one `mountRouter` hydrated — it registers itself here via
|
|
10
|
+
* `setMountedRouter`. On the server (no mount) there is no router, so the stores hold an idle value
|
|
11
|
+
* (fetchers are client-only); the first client render starts from the same idle snapshot — no mismatch.
|
|
12
|
+
*/
|
|
13
|
+
import { readable } from "svelte/store";
|
|
14
|
+
// The active client router (set by `mountRouter`). Module-scoped: the browser mounts one app per
|
|
15
|
+
// page, and fetchers never exist on the server. Shared with `client.ts`'s `mountRouter`.
|
|
16
|
+
let mountedRouter;
|
|
17
|
+
/** Register (or clear) the router that owns fetchers — called by `mountRouter`. Not for app use. */
|
|
18
|
+
export function setMountedRouter(router) {
|
|
19
|
+
mountedRouter = router;
|
|
20
|
+
}
|
|
21
|
+
const IDLE = { pending: false, data: undefined };
|
|
22
|
+
const noopAsync = async () => { };
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe to the independent fetcher for `key` (created lazily, stable across renders). Returns a
|
|
25
|
+
* store of its state (`pending`/`data`/`actionData`/`submission`) augmented with `load`/`submit`.
|
|
26
|
+
* Multiple `useFetcher` calls with different keys run concurrently without disturbing the active route.
|
|
27
|
+
*/
|
|
28
|
+
export function useFetcher(key) {
|
|
29
|
+
const fetcher = mountedRouter?.fetcher(key);
|
|
30
|
+
const store = readable(fetcher ? fetcher.snapshot() : IDLE, (set) => {
|
|
31
|
+
if (fetcher === undefined)
|
|
32
|
+
return;
|
|
33
|
+
set(fetcher.snapshot());
|
|
34
|
+
return fetcher.subscribe(() => set(fetcher.snapshot()));
|
|
35
|
+
});
|
|
36
|
+
return Object.assign(store, {
|
|
37
|
+
load: fetcher?.load ?? noopAsync,
|
|
38
|
+
submit: fetcher?.submit ?? noopAsync,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to the whole live fetcher collection — for a global busy view (e.g. "3 saving…"). Read
|
|
43
|
+
* each entry's `.snapshot()` for its state. The store updates whenever any fetcher transitions or a
|
|
44
|
+
* new one is created.
|
|
45
|
+
*/
|
|
46
|
+
export function useFetchers() {
|
|
47
|
+
const router = mountedRouter;
|
|
48
|
+
return readable(router ? router.fetchers() : [], (set) => {
|
|
49
|
+
if (router === undefined)
|
|
50
|
+
return;
|
|
51
|
+
set(router.fetchers());
|
|
52
|
+
return router.subscribeFetchers(() => set(router.fetchers()));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEtD,iGAAiG;AACjG,yFAAyF;AACzF,IAAI,aAAuC,CAAA;AAE3C,oGAAoG;AACpG,MAAM,UAAU,gBAAgB,CAAC,MAAgC;IAC/D,aAAa,GAAG,MAAM,CAAA;AACxB,CAAC;AAED,MAAM,IAAI,GAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAC9D,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE,GAAE,CAAC,CAAA;AAU/C;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,OAAO,GAAG,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,QAAQ,CAAe,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QAChF,IAAI,OAAO,KAAK,SAAS;YAAE,OAAM;QACjC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;QACvB,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE;QAC1B,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,SAAS;QAChC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,SAAS;KACrC,CAAC,CAAA;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,aAAa,CAAA;IAC5B,OAAO,QAAQ,CAAqB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;QAC3E,IAAI,MAAM,KAAK,SAAS;YAAE,OAAM;QAChC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACtB,OAAO,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nifrajs/web-svelte/i18n` — Svelte bindings for `@nifrajs/i18n`: the `<I18nProvider>` component (re-exported
|
|
3
|
+
* from `I18nProvider.svelte`) plus `useT()`, which reads the provided `Formatter` from Svelte context.
|
|
4
|
+
* Call `useT()` during a component's initialization (like any `getContext`).
|
|
5
|
+
*/
|
|
6
|
+
import type { Formatter } from "@nifrajs/i18n";
|
|
7
|
+
export { default as I18nProvider, type I18nProviderProps } from "./I18nProvider.svelte";
|
|
8
|
+
/** Read the current {@link Formatter} (`{ locale, t, n, d }`). Throws if no `<I18nProvider>` is above.
|
|
9
|
+
* nifra switches locale by re-navigating, which re-runs the consuming component with the new catalog. */
|
|
10
|
+
export declare function useT(): Formatter;
|
|
11
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAG9C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAMvF;yGACyG;AACzG,wBAAgB,IAAI,IAAI,SAAS,CAMhC"}
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getContext } from "svelte";
|
|
2
|
+
export { default as I18nProvider } from "./I18nProvider.svelte";
|
|
3
|
+
// Must match the string key `I18nProvider.svelte` passes to `setContext` (a string avoids a
|
|
4
|
+
// `.svelte` → `.ts` import that wouldn't resolve once the .svelte is copied to dist).
|
|
5
|
+
const I18N_KEY = "@nifrajs/web-svelte:i18n";
|
|
6
|
+
/** Read the current {@link Formatter} (`{ locale, t, n, d }`). Throws if no `<I18nProvider>` is above.
|
|
7
|
+
* nifra switches locale by re-navigating, which re-runs the consuming component with the new catalog. */
|
|
8
|
+
export function useT() {
|
|
9
|
+
const get = getContext(I18N_KEY);
|
|
10
|
+
if (get === undefined) {
|
|
11
|
+
throw new Error("[nifra/web-svelte] useT() must be used within an <I18nProvider>");
|
|
12
|
+
}
|
|
13
|
+
return get();
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=i18n.js.map
|
package/dist/i18n.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAA0B,MAAM,uBAAuB,CAAA;AAEvF,4FAA4F;AAC5F,sFAAsF;AACtF,MAAM,QAAQ,GAAG,0BAA0B,CAAA;AAE3C;yGACyG;AACzG,MAAM,UAAU,IAAI;IAClB,MAAM,GAAG,GAAG,UAAU,CAAgC,QAAQ,CAAC,CAAA;IAC/D,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;IACpF,CAAC;IACD,OAAO,GAAG,EAAE,CAAA;AACd,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
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 type { RenderAdapter } from "@nifrajs/web";
|
|
10
|
+
export { svelteBunPlugin } from "./plugin.js";
|
|
11
|
+
/** The Svelte server render adapter — pass to @nifrajs/web's `renderPage`. */
|
|
12
|
+
export declare const svelteAdapter: RenderAdapter;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
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.
|
|
6
|
+
export { svelteBunPlugin } from "./plugin.js";
|
|
7
|
+
// Svelte SSR yields a complete HTML string; the seam wants a stream, so emit it as one chunk.
|
|
8
|
+
function oneChunk(html) {
|
|
9
|
+
const bytes = new TextEncoder().encode(html);
|
|
10
|
+
return new ReadableStream({
|
|
11
|
+
start(controller) {
|
|
12
|
+
controller.enqueue(bytes);
|
|
13
|
+
controller.close();
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/** The Svelte server render adapter — pass to @nifrajs/web's `renderPage`. */
|
|
18
|
+
export const svelteAdapter = {
|
|
19
|
+
// Svelte SSR is already synchronous + string-based, so this is the native shape: `renderToString`
|
|
20
|
+
// returns the body directly (renderPage buffers it on the non-deferred fast path), and
|
|
21
|
+
// `renderToStream` wraps the same string in a one-chunk stream for the deferred path. No streaming
|
|
22
|
+
// renderer to skip here — but going straight to a string avoids the per-request stream allocation.
|
|
23
|
+
renderToString(chain, props) {
|
|
24
|
+
return render(Chain, { props: { chain, props } }).body;
|
|
25
|
+
},
|
|
26
|
+
renderToStream(chain, props) {
|
|
27
|
+
// `Chain` folds the layout chain (page innermost gets `props`; layouts wrap via their `children`
|
|
28
|
+
// snippet). Svelte's `render` returns { head, body }; the body goes into #root. (Svelte's dynamic
|
|
29
|
+
// `head` — from <svelte:head> — isn't surfaced through the seam's static `hydrationHead`; nifra's
|
|
30
|
+
// own meta/head API manages the document head instead.)
|
|
31
|
+
const { body } = render(Chain, { props: { chain, props } });
|
|
32
|
+
return oneChunk(body);
|
|
33
|
+
},
|
|
34
|
+
// Svelte's client `hydrate` reconciles against the existing DOM; no per-document bootstrap script is
|
|
35
|
+
// needed (contrast Solid's generateHydrationScript) — the seam allows the empty string.
|
|
36
|
+
hydrationHead() {
|
|
37
|
+
return "";
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,EAAE,CAAC,CAAC,IAAI,CAAA;IACxD,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,EAAE,CAAC,CAAA;QAC3D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;IACD,qGAAqG;IACrG,wFAAwF;IACxF,aAAa;QACX,OAAO,EAAE,CAAA;IACX,CAAC;CACF,CAAA"}
|
package/dist/mdx.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BunPlugin } from "bun";
|
|
2
|
+
/** Build a `Bun.build` plugin that loads `.mdx` files as Svelte components via mdsvex. `generate`:
|
|
3
|
+
* `"ssr"` for the server build, `"dom"` for the client (matches `svelteBunPlugin`). */
|
|
4
|
+
export declare function svelteMdxBunPlugin(generate: "dom" | "ssr"): BunPlugin;
|
|
5
|
+
//# sourceMappingURL=mdx.d.ts.map
|
|
@@ -0,0 +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"}
|