@nifrajs/web-svelte 4.0.2 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Router.svelte +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -9
- package/dist/index.js.map +1 -1
- package/dist/server-components/client.d.ts +3 -0
- package/dist/server-components/client.d.ts.map +1 -0
- package/dist/server-components/client.js +58 -0
- package/dist/server-components/client.js.map +1 -0
- package/dist/server-components/server.d.ts +3 -0
- package/dist/server-components/server.d.ts.map +1 -0
- package/dist/server-components/server.js +16 -0
- package/dist/server-components/server.js.map +1 -0
- package/dist/server-components/state.svelte.d.ts +4 -0
- package/dist/server-components/state.svelte.d.ts.map +1 -0
- package/dist/server-components/state.svelte.js +5 -0
- package/dist/server-components/state.svelte.js.map +1 -0
- package/package.json +22 -7
- package/src/Router.svelte +1 -0
- package/src/index.ts +20 -10
- package/src/server-components/Island.svelte +5 -0
- package/src/server-components/Range.svelte +19 -0
- package/src/server-components/ServerComponent.svelte +9 -0
- package/src/server-components/ServerComponent.svelte.d.ts +35 -0
- package/src/server-components/client.ts +60 -0
- package/src/server-components/server.ts +20 -0
- package/src/server-components/state.svelte.ts +4 -0
package/dist/Router.svelte
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
const q = snapshot.path.indexOf("?")
|
|
34
34
|
return {
|
|
35
35
|
data: snapshot.data,
|
|
36
|
+
...(snapshot.serverComponents === undefined ? {} : { serverComponents: snapshot.serverComponents }),
|
|
36
37
|
actionData: snapshot.actionData,
|
|
37
38
|
pending: snapshot.pending,
|
|
38
39
|
// The same `params`/`path` the server render received, so `useMatches` reports the same chain.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAoC,MAAM,cAAc,CAAA;AAgGnF,8EAA8E;AAC9E,eAAO,MAAM,aAAa,EAAE,aA6B3B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -45,31 +45,37 @@ function oneChunk(html) {
|
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
+
/** The body of one render; what `<svelte:head>` rendered goes into the document's `<head>`. */
|
|
49
|
+
function bodyOf(Chain, props, options) {
|
|
50
|
+
const out = render(Chain, { props });
|
|
51
|
+
if (options?.parts !== undefined)
|
|
52
|
+
options.parts.head += out.head;
|
|
53
|
+
return out.body;
|
|
54
|
+
}
|
|
48
55
|
/** The Svelte server render adapter - pass to @nifrajs/web's `renderPage`. */
|
|
49
56
|
export const svelteAdapter = {
|
|
57
|
+
documentParts: true,
|
|
50
58
|
// Svelte SSR is already synchronous + string-based, so this is the native shape: `renderToString`
|
|
51
59
|
// returns the body directly (renderPage buffers it on the non-deferred fast path), and
|
|
52
60
|
// `renderToStream` wraps the same string in a one-chunk stream for the deferred path. No streaming
|
|
53
61
|
// renderer to skip here - but going straight to a string avoids the per-request stream allocation.
|
|
54
62
|
// The seam allows `string | Promise<string>`, so the first render can resolve `Chain` while every
|
|
55
63
|
// render after it stays a plain synchronous call - see `loadChain`.
|
|
56
|
-
renderToString(chain, props) {
|
|
64
|
+
renderToString(chain, props, options) {
|
|
57
65
|
const Chain = loadChain();
|
|
58
66
|
const props$ = { chain, props, layoutData: props.layoutData };
|
|
59
67
|
return Chain instanceof Promise
|
|
60
|
-
? Chain.then((C) =>
|
|
61
|
-
:
|
|
68
|
+
? Chain.then((C) => bodyOf(C, props$, options))
|
|
69
|
+
: bodyOf(Chain, props$, options);
|
|
62
70
|
},
|
|
63
|
-
renderToStream(chain, props) {
|
|
71
|
+
renderToStream(chain, props, options) {
|
|
64
72
|
// `Chain` folds the layout chain (page innermost gets `props`; layouts wrap via their `children`
|
|
65
|
-
// snippet). Svelte's `render` returns { head, body }; the body goes into #root.
|
|
66
|
-
// `head` - from <svelte:head> - isn't surfaced through the seam's static `hydrationHead`; nifra's
|
|
67
|
-
// own meta/head API manages the document head instead.)
|
|
73
|
+
// snippet). Svelte's `render` returns { head, body }; the body goes into #root.
|
|
68
74
|
const Chain = loadChain();
|
|
69
75
|
const props$ = { chain, props, layoutData: props.layoutData };
|
|
70
76
|
return Chain instanceof Promise
|
|
71
|
-
? Chain.then((C) => oneChunk(
|
|
72
|
-
: oneChunk(
|
|
77
|
+
? Chain.then((C) => oneChunk(bodyOf(C, props$, options)))
|
|
78
|
+
: oneChunk(bodyOf(Chain, props$, options));
|
|
73
79
|
},
|
|
74
80
|
// Svelte's client `hydrate` reconciles against the existing DOM; no per-document bootstrap script is
|
|
75
81
|
// 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,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,eAAe,CAAA;AAkCvD,IAAI,cAAiD,CAAA;AACrD,IAAI,YAAwD,CAAA;AAC5D;;;;GAIG;AACH,IAAI,MAAM,GAAyB,aAAa,CAAA;AAChD,sEAAsE;AACtE,MAAM,SAAS,GAAG,GAA2D,EAAE;IAC7E,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,cAAc,CAAA;IACvD,oGAAoG;IACpG,iGAAiG;IACjG,oGAAoG;IACpG,+FAA+F;IAC/F,qGAAqG;IACrG,oFAAoF;IACpF,MAAM,IAAI,GAAG,eAAe,EAAE,CAAA;IAC9B,YAAY,KAAK,CACf,IAAI,KAAK,SAAS;QAChB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;YACV,8FAA8F;YAC9F,wEAAwE;YACxE,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,eAAe,CAAC;YAC3C,IAAI,CAAC,eAAe,CAAC;SACtB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;YACxB,MAAM,GAAI,MAA2C,CAAC,MAAM,CAAA;YAC5D,OAAQ,GAA0C,CAAC,OAAO,CAAA;QAC5D,CAAC,CAAC;QACJ,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAgC,CAAC,CAC7E,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACX,cAAc,GAAG,CAAC,CAAA;QAClB,OAAO,CAAC,CAAA;IACV,CAAC,CAAC,CAAA;IACF,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAED,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,kGAAkG;IAClG,oEAAoE;IACpE,cAAc,CAAC,KAAK,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type NativeRangeOptions } from "@nifrajs/web/server-components/range";
|
|
2
|
+
export declare function svelteComponentClient(options: Omit<NativeRangeOptions, "adapter" | "runtime">): import("@nifrajs/web/server-components/client").ComponentClientAdapter;
|
|
3
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/server-components/client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,sCAAsC,CAAA;AAI7C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,SAAS,CAAC,0EAmD7F"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { disposeComponentPortals } from "@nifrajs/web/server-components/portal";
|
|
2
|
+
import { nativeComponentClient, } from "@nifrajs/web/server-components/range";
|
|
3
|
+
import { flushSync, hydrate, tick, unmount } from "svelte";
|
|
4
|
+
import Island from "./Island.svelte";
|
|
5
|
+
import { islandState } from "./state.svelte.js";
|
|
6
|
+
export function svelteComponentClient(options) {
|
|
7
|
+
return nativeComponentClient({
|
|
8
|
+
...options,
|
|
9
|
+
adapter: "svelte",
|
|
10
|
+
runtime: {
|
|
11
|
+
hydrate(host, contract, record) {
|
|
12
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: Only this adapter produces its prepared tree and native root; component records and public props are validated before native preparation.
|
|
13
|
+
const state = islandState(record.props);
|
|
14
|
+
const slots = Object.fromEntries(contract.slots.map((name) => [
|
|
15
|
+
name,
|
|
16
|
+
'<nifra-slot data-nifra-slot="' +
|
|
17
|
+
name +
|
|
18
|
+
'">' +
|
|
19
|
+
(record.slots?.[name] ?? "") +
|
|
20
|
+
"</nifra-slot>",
|
|
21
|
+
]));
|
|
22
|
+
const instance = hydrate(Island, {
|
|
23
|
+
target: host,
|
|
24
|
+
props: {
|
|
25
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: Only this adapter produces its prepared tree and native root; component records and public props are validated before native preparation.
|
|
26
|
+
component: contract.component,
|
|
27
|
+
state,
|
|
28
|
+
slots,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
flushSync();
|
|
32
|
+
let disposed = false;
|
|
33
|
+
return {
|
|
34
|
+
ready: tick(),
|
|
35
|
+
update(next, current) {
|
|
36
|
+
if (!disposed && current())
|
|
37
|
+
flushSync(() => {
|
|
38
|
+
if (current())
|
|
39
|
+
state.props = next;
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
async dispose() {
|
|
43
|
+
if (!disposed) {
|
|
44
|
+
disposed = true;
|
|
45
|
+
try {
|
|
46
|
+
await disposeComponentPortals(host);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await unmount(instance);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/server-components/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,OAAO,EAEL,qBAAqB,GACtB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAkB,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAC1E,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,MAAM,UAAU,qBAAqB,CAAC,OAAwD;IAC5F,OAAO,qBAAqB,CAAC;QAC3B,GAAG,OAAO;QACV,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE;YACP,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM;gBAC5B,2MAA2M;gBAC3M,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAA;gBAClE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAC9B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC3B,IAAI;oBACJ,+BAA+B;wBAC7B,IAAI;wBACJ,IAAI;wBACJ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;wBAC5B,eAAe;iBAClB,CAAC,CACH,CAAA;gBACD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE;oBAC/B,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE;wBACL,2MAA2M;wBAC3M,SAAS,EAAE,QAAQ,CAAC,SAA+C;wBACnE,KAAK;wBACL,KAAK;qBACN;iBACF,CAAC,CAAA;gBACF,SAAS,EAAE,CAAA;gBACX,IAAI,QAAQ,GAAG,KAAK,CAAA;gBACpB,OAAO;oBACL,KAAK,EAAE,IAAI,EAAE;oBACb,MAAM,CAAC,IAAI,EAAE,OAAO;wBAClB,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE;4BACxB,SAAS,CAAC,GAAG,EAAE;gCACb,IAAI,OAAO,EAAE;oCAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;4BACnC,CAAC,CAAC,CAAA;oBACN,CAAC;oBACD,KAAK,CAAC,OAAO;wBACX,IAAI,CAAC,QAAQ,EAAE,CAAC;4BACd,QAAQ,GAAG,IAAI,CAAA;4BACf,IAAI,CAAC;gCACH,MAAM,uBAAuB,CAAC,IAAI,CAAC,CAAA;4BACrC,CAAC;oCAAS,CAAC;gCACT,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;4BACzB,CAAC;wBACH,CAAC;oBACH,CAAC;iBACF,CAAA;YACH,CAAC;SACF;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server-components/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAKlF,eAAO,MAAM,sBAAsB,QAAO,4BAcvC,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { nativeServerComponents } from "@nifrajs/web/server-components/native";
|
|
2
|
+
import { render } from "svelte/server";
|
|
3
|
+
import Island from "./Island.svelte";
|
|
4
|
+
export const svelteServerComponents = () => nativeServerComponents("svelte", (component, props, renderId) => renderId.endsWith("-view")
|
|
5
|
+
? // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
6
|
+
render(component, { props }).body
|
|
7
|
+
: render(Island, {
|
|
8
|
+
props: {
|
|
9
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
10
|
+
component: component,
|
|
11
|
+
state: { props },
|
|
12
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
13
|
+
slots: props.slots,
|
|
14
|
+
},
|
|
15
|
+
}).body);
|
|
16
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server-components/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAiC,EAAE,CACvE,sBAAsB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAC9D,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;IACxB,CAAC,CAAC,iLAAiL;QACjL,MAAM,CAAC,SAA+C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI;IACzE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;QACb,KAAK,EAAE;YACL,iLAAiL;YACjL,SAAS,EAAE,SAA+C;YAC1D,KAAK,EAAE,EAAE,KAAK,EAAE;YAChB,iLAAiL;YACjL,KAAK,EAAE,KAAK,CAAC,KAA+B;SAC7C;KACF,CAAC,CAAC,IAAI,CACZ,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.svelte.d.ts","sourceRoot":"","sources":["../../src/server-components/state.svelte.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAGzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.svelte.js","sourceRoot":"","sources":["../../src/server-components/state.svelte.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAA8B;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAA;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/web-svelte",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Svelte 5 render adapter for @nifrajs/web - SSR + hydration, with the .svelte compiler Bun plugin (@nifrajs/web-svelte/plugin).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -88,6 +88,20 @@
|
|
|
88
88
|
"bun": "./src/fn.ts",
|
|
89
89
|
"types": "./dist/fn.d.ts",
|
|
90
90
|
"default": "./dist/fn.js"
|
|
91
|
+
},
|
|
92
|
+
"./server-components": {
|
|
93
|
+
"bun": "./src/server-components/server.ts",
|
|
94
|
+
"types": "./dist/server-components/server.d.ts",
|
|
95
|
+
"default": "./src/server-components/server.ts"
|
|
96
|
+
},
|
|
97
|
+
"./server-components/client": {
|
|
98
|
+
"bun": "./src/server-components/client.ts",
|
|
99
|
+
"types": "./dist/server-components/client.d.ts",
|
|
100
|
+
"default": "./src/server-components/client.ts"
|
|
101
|
+
},
|
|
102
|
+
"./server-components/outlet": {
|
|
103
|
+
"types": "./src/server-components/ServerComponent.svelte.d.ts",
|
|
104
|
+
"default": "./src/server-components/ServerComponent.svelte"
|
|
91
105
|
}
|
|
92
106
|
},
|
|
93
107
|
"files": [
|
|
@@ -96,17 +110,17 @@
|
|
|
96
110
|
],
|
|
97
111
|
"sideEffects": false,
|
|
98
112
|
"scripts": {
|
|
99
|
-
"build": "tsc -p tsconfig.build.json && bun run ../../scripts/fix-dts.ts dist && cp src/*.svelte dist/ && cp src/*.svelte.d.ts dist/"
|
|
113
|
+
"build": "node ../../scripts/gen-component-svelte-types.mjs && tsc -p tsconfig.build.json && bun run ../../scripts/fix-dts.ts dist && cp src/*.svelte dist/ && cp src/*.svelte.d.ts dist/"
|
|
100
114
|
},
|
|
101
115
|
"license": "MIT",
|
|
102
116
|
"publishConfig": {
|
|
103
117
|
"access": "public"
|
|
104
118
|
},
|
|
105
119
|
"dependencies": {
|
|
106
|
-
"@nifrajs/core": "
|
|
107
|
-
"@nifrajs/i18n": "
|
|
108
|
-
"@nifrajs/image": "
|
|
109
|
-
"@nifrajs/web": "
|
|
120
|
+
"@nifrajs/core": "5.1.0",
|
|
121
|
+
"@nifrajs/i18n": "5.1.0",
|
|
122
|
+
"@nifrajs/image": "5.1.0",
|
|
123
|
+
"@nifrajs/web": "5.1.0"
|
|
110
124
|
},
|
|
111
125
|
"peerDependencies": {
|
|
112
126
|
"mdsvex": "^0.12",
|
|
@@ -118,7 +132,8 @@
|
|
|
118
132
|
}
|
|
119
133
|
},
|
|
120
134
|
"devDependencies": {
|
|
121
|
-
"svelte": "^5.3.0"
|
|
135
|
+
"svelte": "^5.3.0",
|
|
136
|
+
"svelte2tsx": "0.7.61"
|
|
122
137
|
},
|
|
123
138
|
"repository": {
|
|
124
139
|
"type": "git",
|
package/src/Router.svelte
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
const q = snapshot.path.indexOf("?")
|
|
34
34
|
return {
|
|
35
35
|
data: snapshot.data,
|
|
36
|
+
...(snapshot.serverComponents === undefined ? {} : { serverComponents: snapshot.serverComponents }),
|
|
36
37
|
actionData: snapshot.actionData,
|
|
37
38
|
pending: snapshot.pending,
|
|
38
39
|
// The same `params`/`path` the server render received, so `useMatches` reports the same chain.
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `.svelte` files, so this adapter ships a build plugin at `@nifrajs/web-svelte/plugin` (like
|
|
7
7
|
* `@nifrajs/web-solid/plugin`) - there is no callable-component runtime.
|
|
8
8
|
*/
|
|
9
|
-
import type { RenderAdapter, RenderProps } from "@nifrajs/web"
|
|
9
|
+
import type { RenderAdapter, RenderProps, RenderStreamOptions } from "@nifrajs/web"
|
|
10
10
|
import { ssrModuleLoader } from "@nifrajs/web"
|
|
11
11
|
import type { Component } from "svelte"
|
|
12
12
|
import { render as runtimeRender } from "svelte/server"
|
|
@@ -91,31 +91,41 @@ function oneChunk(html: string): ReadableStream<Uint8Array> {
|
|
|
91
91
|
})
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/** The body of one render; what `<svelte:head>` rendered goes into the document's `<head>`. */
|
|
95
|
+
function bodyOf(
|
|
96
|
+
Chain: Component<ChainProps>,
|
|
97
|
+
props: ChainProps,
|
|
98
|
+
options?: RenderStreamOptions,
|
|
99
|
+
): string {
|
|
100
|
+
const out = render(Chain, { props })
|
|
101
|
+
if (options?.parts !== undefined) options.parts.head += out.head
|
|
102
|
+
return out.body
|
|
103
|
+
}
|
|
104
|
+
|
|
94
105
|
/** The Svelte server render adapter - pass to @nifrajs/web's `renderPage`. */
|
|
95
106
|
export const svelteAdapter: RenderAdapter = {
|
|
107
|
+
documentParts: true,
|
|
96
108
|
// Svelte SSR is already synchronous + string-based, so this is the native shape: `renderToString`
|
|
97
109
|
// returns the body directly (renderPage buffers it on the non-deferred fast path), and
|
|
98
110
|
// `renderToStream` wraps the same string in a one-chunk stream for the deferred path. No streaming
|
|
99
111
|
// renderer to skip here - but going straight to a string avoids the per-request stream allocation.
|
|
100
112
|
// The seam allows `string | Promise<string>`, so the first render can resolve `Chain` while every
|
|
101
113
|
// render after it stays a plain synchronous call - see `loadChain`.
|
|
102
|
-
renderToString(chain, props) {
|
|
114
|
+
renderToString(chain, props, options) {
|
|
103
115
|
const Chain = loadChain()
|
|
104
116
|
const props$ = { chain, props, layoutData: props.layoutData }
|
|
105
117
|
return Chain instanceof Promise
|
|
106
|
-
? Chain.then((C) =>
|
|
107
|
-
:
|
|
118
|
+
? Chain.then((C) => bodyOf(C, props$, options))
|
|
119
|
+
: bodyOf(Chain, props$, options)
|
|
108
120
|
},
|
|
109
|
-
renderToStream(chain, props) {
|
|
121
|
+
renderToStream(chain, props, options) {
|
|
110
122
|
// `Chain` folds the layout chain (page innermost gets `props`; layouts wrap via their `children`
|
|
111
|
-
// snippet). Svelte's `render` returns { head, body }; the body goes into #root.
|
|
112
|
-
// `head` - from <svelte:head> - isn't surfaced through the seam's static `hydrationHead`; nifra's
|
|
113
|
-
// own meta/head API manages the document head instead.)
|
|
123
|
+
// snippet). Svelte's `render` returns { head, body }; the body goes into #root.
|
|
114
124
|
const Chain = loadChain()
|
|
115
125
|
const props$ = { chain, props, layoutData: props.layoutData }
|
|
116
126
|
return Chain instanceof Promise
|
|
117
|
-
? Chain.then((C) => oneChunk(
|
|
118
|
-
: oneChunk(
|
|
127
|
+
? Chain.then((C) => oneChunk(bodyOf(C, props$, options)))
|
|
128
|
+
: oneChunk(bodyOf(Chain, props$, options))
|
|
119
129
|
},
|
|
120
130
|
// Svelte's client `hydrate` reconciles against the existing DOM; no per-document bootstrap script is
|
|
121
131
|
// needed (contrast Solid's generateHydrationScript) - the seam allows the empty string.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Component } from "svelte"
|
|
3
|
+
let { component: Native, state, slots }: { component: Component<Record<string, unknown>>; state: { props: Record<string, unknown> }; slots: Record<string, string> } = $props()
|
|
4
|
+
</script>
|
|
5
|
+
<Native {...state.props} {slots} />
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from "svelte"
|
|
3
|
+
import { ComponentController, type ComponentClientAdapter, type ComponentState, type ComponentRecord } from "@nifrajs/web/server-components/client"
|
|
4
|
+
let { state, record, controller, clientAdapter }: { state: ComponentState; record: ComponentRecord; controller?: ComponentController | undefined | undefined; clientAdapter?: ComponentClientAdapter | undefined | undefined } = $props()
|
|
5
|
+
// svelte-ignore state_referenced_locally
|
|
6
|
+
const initial = record.html
|
|
7
|
+
// svelte-ignore state_referenced_locally
|
|
8
|
+
const instance = record.instance
|
|
9
|
+
let host: HTMLElement
|
|
10
|
+
let active: ComponentController | undefined
|
|
11
|
+
onMount(() => {
|
|
12
|
+
if (controller === undefined && clientAdapter === undefined) throw new Error("component_contract")
|
|
13
|
+
active = controller ?? new ComponentController({ state, adapter: clientAdapter! })
|
|
14
|
+
void active.mount(host, instance).catch(() => active?.reportError("component_failed"))
|
|
15
|
+
return () => { if (active !== undefined) void (controller === undefined ? active.dispose() : active.unmount(instance)) }
|
|
16
|
+
})
|
|
17
|
+
$effect(() => { const next = state; if (active !== undefined) void active.adopt(next).catch(() => active?.reportError("component_failed")) })
|
|
18
|
+
</script>
|
|
19
|
+
<nifra-component bind:this={host} data-nifra-component={instance}>{@html initial}</nifra-component>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script lang="ts" generics="Input, Props, View">
|
|
2
|
+
import Range from "./Range.svelte"
|
|
3
|
+
import { ComponentController, resolveComponentRecord, type ComponentClientAdapter, type ComponentState, type ComponentKey, type ServerComponent as Handle } from "@nifrajs/web/server-components/client"
|
|
4
|
+
let { state, component, instanceKey, input, parent, controller, clientAdapter }: {
|
|
5
|
+
state: ComponentState; component: Handle<Input, Props, View>; instanceKey: ComponentKey; input: NoInfer<Input>; parent?: string; controller?: ComponentController | undefined; clientAdapter?: ComponentClientAdapter | undefined
|
|
6
|
+
} = $props()
|
|
7
|
+
const record = $derived(resolveComponentRecord(state, component, instanceKey, input, parent ?? null))
|
|
8
|
+
</script>
|
|
9
|
+
{#key record.instance}<Range {state} {record} {controller} {clientAdapter} />{/key}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Generated by scripts/gen-component-svelte-types.mjs from ServerComponent.svelte.
|
|
2
|
+
import { ComponentController, type ComponentClientAdapter, type ComponentState, type ComponentKey, type ServerComponent as Handle } from "@nifrajs/web/server-components/client";
|
|
3
|
+
declare function $$render<Input, Props, View>(): {
|
|
4
|
+
props: {
|
|
5
|
+
state: ComponentState;
|
|
6
|
+
component: Handle<Input, Props, View>;
|
|
7
|
+
instanceKey: ComponentKey;
|
|
8
|
+
input: NoInfer<Input>;
|
|
9
|
+
parent?: string;
|
|
10
|
+
controller?: ComponentController | undefined;
|
|
11
|
+
clientAdapter?: ComponentClientAdapter | undefined;
|
|
12
|
+
};
|
|
13
|
+
exports: {};
|
|
14
|
+
bindings: "";
|
|
15
|
+
slots: {};
|
|
16
|
+
events: {};
|
|
17
|
+
};
|
|
18
|
+
declare class __sveltets_Render<Input, Props, View> {
|
|
19
|
+
props(): ReturnType<typeof $$render<Input, Props, View>>['props'];
|
|
20
|
+
events(): ReturnType<typeof $$render<Input, Props, View>>['events'];
|
|
21
|
+
slots(): ReturnType<typeof $$render<Input, Props, View>>['slots'];
|
|
22
|
+
bindings(): "";
|
|
23
|
+
exports(): {};
|
|
24
|
+
}
|
|
25
|
+
interface $$IsomorphicComponent {
|
|
26
|
+
new <Input, Props, View>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Input, Props, View>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Input, Props, View>['props']>, ReturnType<__sveltets_Render<Input, Props, View>['events']>, ReturnType<__sveltets_Render<Input, Props, View>['slots']>> & {
|
|
27
|
+
$$bindings?: ReturnType<__sveltets_Render<Input, Props, View>['bindings']>;
|
|
28
|
+
} & ReturnType<__sveltets_Render<Input, Props, View>['exports']>;
|
|
29
|
+
<Input, Props, View>(internal: unknown, props: ReturnType<__sveltets_Render<Input, Props, View>['props']> & {}): ReturnType<__sveltets_Render<Input, Props, View>['exports']>;
|
|
30
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any, any>['bindings']>;
|
|
31
|
+
}
|
|
32
|
+
declare const ServerComponent: $$IsomorphicComponent;
|
|
33
|
+
type ServerComponent<Input, Props, View> = InstanceType<typeof ServerComponent<Input, Props, View>>;
|
|
34
|
+
export default ServerComponent;
|
|
35
|
+
//# sourceMappingURL=ServerComponent.svelte.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { disposeComponentPortals } from "@nifrajs/web/server-components/portal"
|
|
2
|
+
import {
|
|
3
|
+
type NativeRangeOptions,
|
|
4
|
+
nativeComponentClient,
|
|
5
|
+
} from "@nifrajs/web/server-components/range"
|
|
6
|
+
import { type Component, flushSync, hydrate, tick, unmount } from "svelte"
|
|
7
|
+
import Island from "./Island.svelte"
|
|
8
|
+
import { islandState } from "./state.svelte.ts"
|
|
9
|
+
export function svelteComponentClient(options: Omit<NativeRangeOptions, "adapter" | "runtime">) {
|
|
10
|
+
return nativeComponentClient({
|
|
11
|
+
...options,
|
|
12
|
+
adapter: "svelte",
|
|
13
|
+
runtime: {
|
|
14
|
+
hydrate(host, contract, record) {
|
|
15
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: Only this adapter produces its prepared tree and native root; component records and public props are validated before native preparation.
|
|
16
|
+
const state = islandState(record.props as Record<string, unknown>)
|
|
17
|
+
const slots = Object.fromEntries(
|
|
18
|
+
contract.slots.map((name) => [
|
|
19
|
+
name,
|
|
20
|
+
'<nifra-slot data-nifra-slot="' +
|
|
21
|
+
name +
|
|
22
|
+
'">' +
|
|
23
|
+
(record.slots?.[name] ?? "") +
|
|
24
|
+
"</nifra-slot>",
|
|
25
|
+
]),
|
|
26
|
+
)
|
|
27
|
+
const instance = hydrate(Island, {
|
|
28
|
+
target: host,
|
|
29
|
+
props: {
|
|
30
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: Only this adapter produces its prepared tree and native root; component records and public props are validated before native preparation.
|
|
31
|
+
component: contract.component as Component<Record<string, unknown>>,
|
|
32
|
+
state,
|
|
33
|
+
slots,
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
flushSync()
|
|
37
|
+
let disposed = false
|
|
38
|
+
return {
|
|
39
|
+
ready: tick(),
|
|
40
|
+
update(next, current) {
|
|
41
|
+
if (!disposed && current())
|
|
42
|
+
flushSync(() => {
|
|
43
|
+
if (current()) state.props = next
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
async dispose() {
|
|
47
|
+
if (!disposed) {
|
|
48
|
+
disposed = true
|
|
49
|
+
try {
|
|
50
|
+
await disposeComponentPortals(host)
|
|
51
|
+
} finally {
|
|
52
|
+
await unmount(instance)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ServerComponentRenderAdapter } from "@nifrajs/web/server-components"
|
|
2
|
+
import { nativeServerComponents } from "@nifrajs/web/server-components/native"
|
|
3
|
+
import type { Component } from "svelte"
|
|
4
|
+
import { render } from "svelte/server"
|
|
5
|
+
import Island from "./Island.svelte"
|
|
6
|
+
export const svelteServerComponents = (): ServerComponentRenderAdapter =>
|
|
7
|
+
nativeServerComponents("svelte", (component, props, renderId) =>
|
|
8
|
+
renderId.endsWith("-view")
|
|
9
|
+
? // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
10
|
+
render(component as Component<Record<string, unknown>>, { props }).body
|
|
11
|
+
: render(Island, {
|
|
12
|
+
props: {
|
|
13
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
14
|
+
component: component as Component<Record<string, unknown>>,
|
|
15
|
+
state: { props },
|
|
16
|
+
// biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The native renderer receives only its registered component and schema-projected props from the shared executor.
|
|
17
|
+
slots: props.slots as Record<string, string>,
|
|
18
|
+
},
|
|
19
|
+
}).body,
|
|
20
|
+
)
|