@sigx/server-renderer 0.1.4 → 0.1.6
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/client/hydrate.d.ts +24 -0
- package/dist/client/hydrate.d.ts.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +2 -0
- package/dist/client/plugin.d.ts +52 -0
- package/dist/client/plugin.d.ts.map +1 -0
- package/dist/client/registry.d.ts +54 -0
- package/dist/client/registry.d.ts.map +1 -0
- package/dist/client/types.d.ts +23 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client-DiLwBAD-.js +541 -0
- package/dist/client-DiLwBAD-.js.map +1 -0
- package/dist/client-directives.d.ts +96 -0
- package/dist/client-directives.d.ts.map +1 -0
- package/dist/index.d.ts +47 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -133
- package/dist/server/context.d.ts +118 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +2 -0
- package/dist/server/stream.d.ts +62 -0
- package/dist/server/stream.d.ts.map +1 -0
- package/dist/server-BCOJt2Bi.js +459 -0
- package/dist/server-BCOJt2Bi.js.map +1 -0
- package/dist/shared/utils.d.ts +9 -0
- package/dist/shared/utils.d.ts.map +1 -0
- package/package.json +24 -10
- package/src/jsx.d.ts +62 -0
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client hydration directive types.
|
|
3
|
+
*
|
|
4
|
+
* These directives control selective hydration behavior for SSR components.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Client hydration directive props
|
|
8
|
+
*/
|
|
9
|
+
export interface ClientDirectives {
|
|
10
|
+
/**
|
|
11
|
+
* Hydrate this component immediately when the page loads.
|
|
12
|
+
* Use for critical interactive components above the fold.
|
|
13
|
+
*/
|
|
14
|
+
'client:load'?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Hydrate this component during browser idle time (requestIdleCallback).
|
|
17
|
+
* Use for non-critical components that don't need immediate interactivity.
|
|
18
|
+
*/
|
|
19
|
+
'client:idle'?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Hydrate this component when it enters the viewport (IntersectionObserver).
|
|
22
|
+
* Use for below-the-fold components to improve initial load performance.
|
|
23
|
+
*/
|
|
24
|
+
'client:visible'?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Hydrate this component when the media query matches.
|
|
27
|
+
* Pass the media query string as the value.
|
|
28
|
+
* @example <Sidebar client:media="(min-width: 768px)" />
|
|
29
|
+
*/
|
|
30
|
+
'client:media'?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Skip server rendering entirely; only render on client.
|
|
33
|
+
* Use for components that cannot run on the server (e.g., use browser APIs).
|
|
34
|
+
* A placeholder will be rendered on the server.
|
|
35
|
+
*/
|
|
36
|
+
'client:only'?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* SSR helper object for async data loading.
|
|
40
|
+
* Provides clean async data loading that works seamlessly across server and client.
|
|
41
|
+
*/
|
|
42
|
+
export interface SSRHelper {
|
|
43
|
+
/**
|
|
44
|
+
* Load async data during SSR. The callback runs on the server and is skipped
|
|
45
|
+
* during client hydration (state is automatically restored from server).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* export const UserCard = component(({ signal, props, ssr }) => {
|
|
50
|
+
* const state = signal({ user: null, loading: true });
|
|
51
|
+
*
|
|
52
|
+
* ssr.load(async () => {
|
|
53
|
+
* state.user = await fetchUser(props.userId);
|
|
54
|
+
* state.loading = false;
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* return () => state.loading
|
|
58
|
+
* ? <div>Loading...</div>
|
|
59
|
+
* : <div>{state.user.name}</div>;
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
load(fn: () => Promise<void>): void;
|
|
64
|
+
/**
|
|
65
|
+
* Whether we're currently running on the server (SSR context).
|
|
66
|
+
*/
|
|
67
|
+
readonly isServer: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Whether we're hydrating on the client with server state.
|
|
70
|
+
*/
|
|
71
|
+
readonly isHydrating: boolean;
|
|
72
|
+
}
|
|
73
|
+
declare module '@sigx/runtime-core' {
|
|
74
|
+
interface ComponentAttributeExtensions extends ClientDirectives {
|
|
75
|
+
}
|
|
76
|
+
interface ComponentSetupContext {
|
|
77
|
+
/**
|
|
78
|
+
* SSR helper for async data loading.
|
|
79
|
+
* Use `ssr.load()` to fetch data that runs on server and is skipped on client hydration.
|
|
80
|
+
*/
|
|
81
|
+
ssr: SSRHelper;
|
|
82
|
+
/**
|
|
83
|
+
* @internal Map of signal names to their current values (for SSR state capture)
|
|
84
|
+
*/
|
|
85
|
+
_signals?: Map<string, any>;
|
|
86
|
+
/**
|
|
87
|
+
* @internal Pre-captured server state (for client hydration restoration)
|
|
88
|
+
*/
|
|
89
|
+
_serverState?: Record<string, any>;
|
|
90
|
+
/**
|
|
91
|
+
* @internal Array of pending SSR load promises
|
|
92
|
+
*/
|
|
93
|
+
_ssrLoads?: Promise<void>[];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client-directives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-directives.d.ts","sourceRoot":"","sources":["../src/client-directives.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACtB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEpC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CACjC;AAID,OAAO,QAAQ,oBAAoB,CAAC;IAEhC,UAAU,4BAA6B,SAAQ,gBAAgB;KAAI;IAGnE,UAAU,qBAAqB;QAC3B;;;WAGG;QACH,GAAG,EAAE,SAAS,CAAC;QAEf;;WAEG;QACH,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE5B;;WAEG;QACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEnC;;WAEG;QACH,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;KAC/B;CACJ"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @sigx/server-renderer
|
|
3
|
+
*
|
|
4
|
+
* Server-side rendering and client-side hydration for SigX applications.
|
|
5
|
+
*
|
|
6
|
+
* ## Server Usage
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { renderToStream, renderToString } from '@sigx/server-renderer/server';
|
|
9
|
+
*
|
|
10
|
+
* // Streaming (recommended)
|
|
11
|
+
* const stream = renderToStream(<App />);
|
|
12
|
+
*
|
|
13
|
+
* // Or string
|
|
14
|
+
* const html = await renderToString(<App />);
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* ## Client Usage
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { defineApp } from 'sigx';
|
|
20
|
+
* import { ssrClientPlugin } from '@sigx/server-renderer/client';
|
|
21
|
+
*
|
|
22
|
+
* defineApp(<App />)
|
|
23
|
+
* .use(ssrClientPlugin)
|
|
24
|
+
* .hydrate('#root');
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ## Selective Hydration (Islands)
|
|
28
|
+
* ```tsx
|
|
29
|
+
* // Enable JSX types for client directives
|
|
30
|
+
* import '@sigx/server-renderer/jsx';
|
|
31
|
+
*
|
|
32
|
+
* // Use directives on components
|
|
33
|
+
* <Counter client:visible /> // Hydrate when visible
|
|
34
|
+
* <Widget client:idle /> // Hydrate during idle time
|
|
35
|
+
* <Modal client:load /> // Hydrate immediately
|
|
36
|
+
* <Sidebar client:media="(min-width: 768px)" /> // Hydrate on media match
|
|
37
|
+
* <Map client:only /> // Client-only, no SSR
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @module
|
|
41
|
+
*/
|
|
42
|
+
export { renderToStream, renderToString } from './server/index.js';
|
|
43
|
+
export { createSSRContext } from './server/context.js';
|
|
44
|
+
export type { SSRContext, SSRContextOptions, RenderOptions, IslandInfo, HydrationStrategy } from './server/context.js';
|
|
45
|
+
export { ssrClientPlugin, hydrateIslands } from './client/index.js';
|
|
46
|
+
export { registerComponent, registerComponents, HydrationRegistry } from './client/registry.js';
|
|
47
|
+
export type { HydrationOptions } from './client/types.js';
|
|
3
48
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGvH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAChG,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,133 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Creates a simple props accessor for SSR (no reactivity needed)
|
|
6
|
-
*/
|
|
7
|
-
function createSSRPropsAccessor(rawProps) {
|
|
8
|
-
let defaults = {};
|
|
9
|
-
const proxy = new Proxy(function propsAccessor() {}, {
|
|
10
|
-
get(_, key) {
|
|
11
|
-
if (typeof key === "symbol") return void 0;
|
|
12
|
-
const value = rawProps[key];
|
|
13
|
-
return value != null ? value : defaults[key];
|
|
14
|
-
},
|
|
15
|
-
apply(_, __, args) {
|
|
16
|
-
if (args[0] && typeof args[0] === "object") defaults = {
|
|
17
|
-
...defaults,
|
|
18
|
-
...args[0]
|
|
19
|
-
};
|
|
20
|
-
return proxy;
|
|
21
|
-
},
|
|
22
|
-
has(_, key) {
|
|
23
|
-
if (typeof key === "symbol") return false;
|
|
24
|
-
return key in rawProps || key in defaults;
|
|
25
|
-
},
|
|
26
|
-
ownKeys() {
|
|
27
|
-
return [...new Set([...Object.keys(rawProps), ...Object.keys(defaults)])];
|
|
28
|
-
},
|
|
29
|
-
getOwnPropertyDescriptor(_, key) {
|
|
30
|
-
if (typeof key === "symbol") return void 0;
|
|
31
|
-
if (key in rawProps || key in defaults) return {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
configurable: true,
|
|
34
|
-
writable: false
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
return proxy;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Check if a vnode type is a component (has __setup)
|
|
42
|
-
*/
|
|
43
|
-
function isComponent(type) {
|
|
44
|
-
return typeof type === "function" && "__setup" in type;
|
|
45
|
-
}
|
|
46
|
-
async function renderToString(element) {
|
|
47
|
-
if (element == null || element === false || element === true) return "";
|
|
48
|
-
if (typeof element === "string" || typeof element === "number") return escapeHtml(String(element));
|
|
49
|
-
const vnode = element;
|
|
50
|
-
if (vnode.type === Text) return escapeHtml(String(vnode.text));
|
|
51
|
-
if (vnode.type === Fragment) return (await Promise.all(vnode.children.map(renderToString))).join("");
|
|
52
|
-
if (isComponent(vnode.type)) {
|
|
53
|
-
const setup = vnode.type.__setup;
|
|
54
|
-
const { children, ...propsData } = vnode.props || {};
|
|
55
|
-
const ctx = {
|
|
56
|
-
el: null,
|
|
57
|
-
signal,
|
|
58
|
-
props: createSSRPropsAccessor(propsData),
|
|
59
|
-
slots: { default: () => children ? Array.isArray(children) ? children : [children] : [] },
|
|
60
|
-
emit: () => {},
|
|
61
|
-
parent: null,
|
|
62
|
-
onMount: () => {},
|
|
63
|
-
onCleanup: () => {},
|
|
64
|
-
expose: () => {},
|
|
65
|
-
renderFn: null,
|
|
66
|
-
update: () => {}
|
|
67
|
-
};
|
|
68
|
-
const prev = setCurrentInstance(ctx);
|
|
69
|
-
try {
|
|
70
|
-
const renderFn = setup(ctx);
|
|
71
|
-
if (renderFn) {
|
|
72
|
-
const result = renderFn();
|
|
73
|
-
if (result) {
|
|
74
|
-
if (Array.isArray(result)) return (await Promise.all(result.map(renderToString))).join("");
|
|
75
|
-
return await renderToString(result);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.error(`Error rendering component:`, e);
|
|
80
|
-
} finally {
|
|
81
|
-
setCurrentInstance(prev || null);
|
|
82
|
-
}
|
|
83
|
-
return "";
|
|
84
|
-
}
|
|
85
|
-
if (typeof vnode.type === "string") {
|
|
86
|
-
const tagName = vnode.type;
|
|
87
|
-
let props = "";
|
|
88
|
-
let children = "";
|
|
89
|
-
for (const key in vnode.props) {
|
|
90
|
-
const value = vnode.props[key];
|
|
91
|
-
if (key === "children" || key === "key" || key === "ref") continue;
|
|
92
|
-
if (key === "style") {
|
|
93
|
-
const styleString = typeof value === "object" ? Object.entries(value).map(([k, v]) => `${k}:${v}`).join(";") : String(value);
|
|
94
|
-
props += ` style="${escapeHtml(styleString)}"`;
|
|
95
|
-
} else if (key === "className") props += ` class="${escapeHtml(String(value))}"`;
|
|
96
|
-
else if (key.startsWith("on")) {} else if (value === true) props += ` ${key}`;
|
|
97
|
-
else if (value !== false && value != null) props += ` ${key}="${escapeHtml(String(value))}"`;
|
|
98
|
-
}
|
|
99
|
-
if (vnode.children.length > 0) children = (await Promise.all(vnode.children.map(renderToString))).join("");
|
|
100
|
-
if ([
|
|
101
|
-
"area",
|
|
102
|
-
"base",
|
|
103
|
-
"br",
|
|
104
|
-
"col",
|
|
105
|
-
"embed",
|
|
106
|
-
"hr",
|
|
107
|
-
"img",
|
|
108
|
-
"input",
|
|
109
|
-
"link",
|
|
110
|
-
"meta",
|
|
111
|
-
"param",
|
|
112
|
-
"source",
|
|
113
|
-
"track",
|
|
114
|
-
"wbr"
|
|
115
|
-
].includes(tagName)) return `<${tagName}${props}>`;
|
|
116
|
-
return `<${tagName}${props}>${children}</${tagName}>`;
|
|
117
|
-
}
|
|
118
|
-
return "";
|
|
119
|
-
}
|
|
120
|
-
const ESCAPE = {
|
|
121
|
-
"&": "&",
|
|
122
|
-
"<": "<",
|
|
123
|
-
">": ">",
|
|
124
|
-
"\"": """,
|
|
125
|
-
"'": "'"
|
|
126
|
-
};
|
|
127
|
-
function escapeHtml(s) {
|
|
128
|
-
return s.replace(/[&<>"']/g, (c) => ESCAPE[c]);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
//#endregion
|
|
132
|
-
export { renderToString };
|
|
133
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import { i as createSSRContext, r as renderToString, t as renderToStream } from "./server-BCOJt2Bi.js";
|
|
2
|
+
import { a as registerComponents, i as registerComponent, n as hydrateIslands, r as HydrationRegistry, t as ssrClientPlugin } from "./client-DiLwBAD-.js";
|
|
3
|
+
export { HydrationRegistry, createSSRContext, hydrateIslands, registerComponent, registerComponents, renderToStream, renderToString, ssrClientPlugin };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR Context - tracks component boundaries and hydration markers during rendering
|
|
3
|
+
*/
|
|
4
|
+
export interface SSRContextOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Enable streaming mode (default: true)
|
|
7
|
+
*/
|
|
8
|
+
streaming?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface RenderOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Custom SSR context (created automatically if not provided)
|
|
13
|
+
*/
|
|
14
|
+
context?: SSRContext;
|
|
15
|
+
}
|
|
16
|
+
export interface SSRContext {
|
|
17
|
+
/**
|
|
18
|
+
* Unique ID counter for component markers
|
|
19
|
+
*/
|
|
20
|
+
_componentId: number;
|
|
21
|
+
/**
|
|
22
|
+
* Stack of component IDs for nested tracking
|
|
23
|
+
*/
|
|
24
|
+
_componentStack: number[];
|
|
25
|
+
/**
|
|
26
|
+
* Registered islands and their hydration strategies
|
|
27
|
+
*/
|
|
28
|
+
_islands: Map<number, IslandInfo>;
|
|
29
|
+
/**
|
|
30
|
+
* Collected head elements (scripts, styles, etc.)
|
|
31
|
+
*/
|
|
32
|
+
_head: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Pending async components for streaming
|
|
35
|
+
*/
|
|
36
|
+
_pendingAsync: PendingAsyncComponent[];
|
|
37
|
+
/**
|
|
38
|
+
* Generate next component ID
|
|
39
|
+
*/
|
|
40
|
+
nextId(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Push a component onto the stack
|
|
43
|
+
*/
|
|
44
|
+
pushComponent(id: number): void;
|
|
45
|
+
/**
|
|
46
|
+
* Pop the current component from stack
|
|
47
|
+
*/
|
|
48
|
+
popComponent(): number | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Register an island for selective hydration
|
|
51
|
+
*/
|
|
52
|
+
registerIsland(id: number, info: IslandInfo): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get all registered islands
|
|
55
|
+
*/
|
|
56
|
+
getIslands(): Map<number, IslandInfo>;
|
|
57
|
+
/**
|
|
58
|
+
* Add a head element
|
|
59
|
+
*/
|
|
60
|
+
addHead(html: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get collected head HTML
|
|
63
|
+
*/
|
|
64
|
+
getHead(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Register a pending async component for streaming
|
|
67
|
+
*/
|
|
68
|
+
addPendingAsync(pending: PendingAsyncComponent): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get all pending async components
|
|
71
|
+
*/
|
|
72
|
+
getPendingAsync(): PendingAsyncComponent[];
|
|
73
|
+
}
|
|
74
|
+
export interface IslandInfo {
|
|
75
|
+
/**
|
|
76
|
+
* Hydration strategy: 'load' | 'idle' | 'visible' | 'media' | 'only'
|
|
77
|
+
*/
|
|
78
|
+
strategy: HydrationStrategy;
|
|
79
|
+
/**
|
|
80
|
+
* Media query for 'media' strategy
|
|
81
|
+
*/
|
|
82
|
+
media?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Component props to serialize for client hydration
|
|
85
|
+
*/
|
|
86
|
+
props?: Record<string, any>;
|
|
87
|
+
/**
|
|
88
|
+
* Component name/identifier for client
|
|
89
|
+
*/
|
|
90
|
+
componentId?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Captured signal state from async setup for client hydration
|
|
93
|
+
*/
|
|
94
|
+
state?: Record<string, any>;
|
|
95
|
+
/**
|
|
96
|
+
* Placeholder HTML for streaming async components
|
|
97
|
+
*/
|
|
98
|
+
placeholder?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Pending async component that will be streamed later
|
|
102
|
+
*/
|
|
103
|
+
export interface PendingAsyncComponent {
|
|
104
|
+
/** Component ID */
|
|
105
|
+
id: number;
|
|
106
|
+
/** Promise that resolves to rendered HTML */
|
|
107
|
+
promise: Promise<string>;
|
|
108
|
+
/** Signal state captured during render */
|
|
109
|
+
signalMap: Map<string, any>;
|
|
110
|
+
/** Island info reference */
|
|
111
|
+
islandInfo: IslandInfo;
|
|
112
|
+
}
|
|
113
|
+
export type HydrationStrategy = 'load' | 'idle' | 'visible' | 'media' | 'only';
|
|
114
|
+
/**
|
|
115
|
+
* Create a new SSR context for rendering
|
|
116
|
+
*/
|
|
117
|
+
export declare function createSSRContext(options?: SSRContextOptions): SSRContext;
|
|
118
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAElC;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,aAAa,EAAE,qBAAqB,EAAE,CAAC;IAEvC;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,SAAS,CAAC;IAEnC;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEtC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B;;OAEG;IACH,OAAO,IAAI,MAAM,CAAC;IAElB;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,eAAe,IAAI,qBAAqB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,QAAQ,EAAE,iBAAiB,CAAC;IAE5B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,0CAA0C;IAC1C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,4BAA4B;IAC5B,UAAU,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/E;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAkD5E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sigx/server-renderer/server
|
|
3
|
+
*
|
|
4
|
+
* Server-side rendering with streaming support and hydration markers.
|
|
5
|
+
*/
|
|
6
|
+
import '../client-directives.js';
|
|
7
|
+
export { renderToStream, renderToString, renderToStreamWithCallbacks } from './stream.js';
|
|
8
|
+
export type { StreamCallbacks } from './stream.js';
|
|
9
|
+
export { createSSRContext } from './context.js';
|
|
10
|
+
export type { SSRContext, SSRContextOptions, RenderOptions } from './context.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,yBAAyB,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC1F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming SSR renderer with hydration markers
|
|
3
|
+
*/
|
|
4
|
+
import { JSXElement } from 'sigx';
|
|
5
|
+
import type { App } from 'sigx';
|
|
6
|
+
import { SSRContext } from './context.js';
|
|
7
|
+
/**
|
|
8
|
+
* Render JSX element or App to a ReadableStream with streaming async support.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // Simple usage with JSX
|
|
13
|
+
* renderToStream(<App />)
|
|
14
|
+
*
|
|
15
|
+
* // With App instance for DI/plugins
|
|
16
|
+
* const app = defineApp(<App />).use(router);
|
|
17
|
+
* renderToStream(app)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderToStream(input: JSXElement | App, context?: SSRContext): ReadableStream<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Streaming callbacks interface
|
|
23
|
+
*/
|
|
24
|
+
export interface StreamCallbacks {
|
|
25
|
+
/** Called when the initial shell (synchronous content) is ready */
|
|
26
|
+
onShellReady: (html: string) => void;
|
|
27
|
+
/** Called for each async chunk (replacement scripts, hydration data) */
|
|
28
|
+
onAsyncChunk: (chunk: string) => void;
|
|
29
|
+
/** Called when all streaming is complete */
|
|
30
|
+
onComplete: () => void;
|
|
31
|
+
/** Called on error */
|
|
32
|
+
onError: (error: Error) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Render with callbacks for fine-grained streaming control.
|
|
36
|
+
* This allows the server to inject scripts between shell and async content.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* // With App instance for DI/plugins
|
|
41
|
+
* const app = defineApp(<App />).use(router);
|
|
42
|
+
* await renderToStreamWithCallbacks(app, callbacks)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function renderToStreamWithCallbacks(input: JSXElement | App, callbacks: StreamCallbacks, context?: SSRContext): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Render JSX element or App to string (convenience wrapper around stream).
|
|
48
|
+
* For renderToString, we wait for all async components to complete,
|
|
49
|
+
* then include the replacement scripts inline so the final HTML is complete.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* // Simple usage with JSX
|
|
54
|
+
* const html = await renderToString(<App />);
|
|
55
|
+
*
|
|
56
|
+
* // With App instance for DI/plugins
|
|
57
|
+
* const app = defineApp(<App />).use(router);
|
|
58
|
+
* const html = await renderToString(app);
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function renderToString(input: JSXElement | App, context?: SSRContext): Promise<string>;
|
|
62
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGH,UAAU,EAeb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,GAAG,EAAc,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,UAAU,EAA0E,MAAM,cAAc,CAAC;AA4XlH;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAyEpG;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,mEAAmE;IACnE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,wEAAwE;IACxE,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,4CAA4C;IAC5C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACnC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC7C,KAAK,EAAE,UAAU,GAAG,GAAG,EACvB,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAuFf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2DnG"}
|