@cloudwerk/ui 0.3.0 → 0.4.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/index.d.ts +67 -3
- package/dist/index.js +30 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ interface HtmlOptions {
|
|
|
75
75
|
headers?: Record<string, string>;
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Options for streaming render.
|
|
78
|
+
* Options for streaming render (loading-swap pattern).
|
|
79
79
|
*/
|
|
80
80
|
interface StreamRenderOptions {
|
|
81
81
|
/**
|
|
@@ -89,6 +89,29 @@ interface StreamRenderOptions {
|
|
|
89
89
|
*/
|
|
90
90
|
headers?: Record<string, string>;
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Options for native progressive streaming render with Suspense boundaries.
|
|
94
|
+
*
|
|
95
|
+
* This is used by renderToStream() which uses Hono's renderToReadableStream
|
|
96
|
+
* for native progressive streaming with Suspense support.
|
|
97
|
+
*/
|
|
98
|
+
interface RenderToStreamOptions {
|
|
99
|
+
/**
|
|
100
|
+
* HTTP status code for the response.
|
|
101
|
+
* @default 200
|
|
102
|
+
*/
|
|
103
|
+
status?: number;
|
|
104
|
+
/**
|
|
105
|
+
* Additional response headers.
|
|
106
|
+
* These are merged with the default Content-Type header.
|
|
107
|
+
*/
|
|
108
|
+
headers?: Record<string, string>;
|
|
109
|
+
/**
|
|
110
|
+
* Whether to include the <!DOCTYPE html> declaration.
|
|
111
|
+
* @default true
|
|
112
|
+
*/
|
|
113
|
+
doctype?: boolean;
|
|
114
|
+
}
|
|
92
115
|
/**
|
|
93
116
|
* Props for components that receive children.
|
|
94
117
|
*
|
|
@@ -202,7 +225,8 @@ declare function _resetRenderers(): void;
|
|
|
202
225
|
* - Automatic doctype handling
|
|
203
226
|
* - Proper Content-Type headers
|
|
204
227
|
*
|
|
205
|
-
*
|
|
228
|
+
* Native progressive streaming is available via renderToStream() using Hono's
|
|
229
|
+
* renderToReadableStream for Suspense boundary support.
|
|
206
230
|
*/
|
|
207
231
|
declare const honoJsxRenderer: Renderer;
|
|
208
232
|
/**
|
|
@@ -232,6 +256,46 @@ declare const honoJsxRenderer: Renderer;
|
|
|
232
256
|
* return renderStream(loadingElement, contentPromise)
|
|
233
257
|
*/
|
|
234
258
|
declare function renderStream(loadingElement: unknown, contentPromise: Promise<unknown>, options?: StreamRenderOptions): Response;
|
|
259
|
+
/**
|
|
260
|
+
* Render a JSX element to a streaming Response using native progressive streaming.
|
|
261
|
+
*
|
|
262
|
+
* This uses Hono's renderToReadableStream for native support of React-style
|
|
263
|
+
* Suspense boundaries. Content inside Suspense components will be progressively
|
|
264
|
+
* streamed as their async content resolves.
|
|
265
|
+
*
|
|
266
|
+
* Unlike renderStream() which uses a loading-swap pattern, this function
|
|
267
|
+
* provides true progressive streaming where:
|
|
268
|
+
* - The initial shell is sent immediately
|
|
269
|
+
* - Suspense fallbacks are shown while async content loads
|
|
270
|
+
* - Async content is streamed in-place as it resolves
|
|
271
|
+
* - No JavaScript is required for the initial render
|
|
272
|
+
*
|
|
273
|
+
* @param element - Hono JSX element to render (may contain Suspense boundaries)
|
|
274
|
+
* @param options - Render options
|
|
275
|
+
* @returns Promise resolving to Response with streaming HTML content
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* // In a route handler
|
|
279
|
+
* import { Suspense } from 'hono/jsx/streaming'
|
|
280
|
+
*
|
|
281
|
+
* function Page() {
|
|
282
|
+
* return (
|
|
283
|
+
* <html>
|
|
284
|
+
* <body>
|
|
285
|
+
* <h1>Dashboard</h1>
|
|
286
|
+
* <Suspense fallback={<p>Loading stats...</p>}>
|
|
287
|
+
* <AsyncStats />
|
|
288
|
+
* </Suspense>
|
|
289
|
+
* </body>
|
|
290
|
+
* </html>
|
|
291
|
+
* )
|
|
292
|
+
* }
|
|
293
|
+
*
|
|
294
|
+
* export function GET() {
|
|
295
|
+
* return renderToStream(<Page />)
|
|
296
|
+
* }
|
|
297
|
+
*/
|
|
298
|
+
declare function renderToStream(element: unknown, options?: RenderToStreamOptions): Promise<Response>;
|
|
235
299
|
|
|
236
300
|
/**
|
|
237
301
|
* @cloudwerk/ui
|
|
@@ -315,4 +379,4 @@ declare function html(content: string, options?: HtmlOptions): Response;
|
|
|
315
379
|
*/
|
|
316
380
|
declare function hydrate(element: unknown, root: Element): void;
|
|
317
381
|
|
|
318
|
-
export { type HtmlOptions, type PropsWithChildren, type RenderOptions, type Renderer, type StreamRenderOptions, _resetRenderers, getActiveRenderer, getActiveRendererName, getAvailableRenderers, honoJsxRenderer, html, hydrate, registerRenderer, render, renderStream, setActiveRenderer };
|
|
382
|
+
export { type HtmlOptions, type PropsWithChildren, type RenderOptions, type RenderToStreamOptions, type Renderer, type StreamRenderOptions, _resetRenderers, getActiveRenderer, getActiveRendererName, getAvailableRenderers, honoJsxRenderer, html, hydrate, registerRenderer, render, renderStream, renderToStream, setActiveRenderer };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/renderers/hono-jsx.ts
|
|
2
|
+
import { renderToReadableStream } from "hono/jsx/streaming";
|
|
2
3
|
var honoJsxRenderer = {
|
|
3
4
|
/**
|
|
4
5
|
* Render a JSX element to an HTML Response.
|
|
@@ -102,6 +103,34 @@ function renderStream(loadingElement, contentPromise, options = {}) {
|
|
|
102
103
|
}
|
|
103
104
|
});
|
|
104
105
|
}
|
|
106
|
+
function prependDoctype(stream) {
|
|
107
|
+
const encoder = new TextEncoder();
|
|
108
|
+
const doctypeBytes = encoder.encode("<!DOCTYPE html>");
|
|
109
|
+
let doctypeSent = false;
|
|
110
|
+
return stream.pipeThrough(
|
|
111
|
+
new TransformStream({
|
|
112
|
+
transform(chunk, controller) {
|
|
113
|
+
if (!doctypeSent) {
|
|
114
|
+
controller.enqueue(doctypeBytes);
|
|
115
|
+
doctypeSent = true;
|
|
116
|
+
}
|
|
117
|
+
controller.enqueue(chunk);
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
async function renderToStream(element, options = {}) {
|
|
123
|
+
const { status = 200, headers = {}, doctype = true } = options;
|
|
124
|
+
const contentStream = renderToReadableStream(element);
|
|
125
|
+
const stream = doctype ? prependDoctype(contentStream) : contentStream;
|
|
126
|
+
return new Response(stream, {
|
|
127
|
+
status,
|
|
128
|
+
headers: {
|
|
129
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
130
|
+
...headers
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
105
134
|
|
|
106
135
|
// src/renderer.ts
|
|
107
136
|
var renderers = {
|
|
@@ -166,5 +195,6 @@ export {
|
|
|
166
195
|
registerRenderer,
|
|
167
196
|
render,
|
|
168
197
|
renderStream,
|
|
198
|
+
renderToStream,
|
|
169
199
|
setActiveRenderer
|
|
170
200
|
};
|