Files
vercel_dashboard_example/.pnpm-store/v11/files/a4/3099049d81f3b27ff792716c66b81cd7e057f3e630b624e2fbbe465a2d3329588aeca22fff3d89efa2df1db88ae6b1eb63abd116639602e35b36dff7b89e9d
T
2026-05-12 14:53:15 +00:00

67 lines
1.4 KiB
Plaintext

import { PassThrough } from 'node:stream';
import { renderToChunks } from './lib/chunked.js';
/**
* @typedef {object} RenderToPipeableStreamOptions
* @property {() => void} [onShellReady]
* @property {() => void} [onAllReady]
* @property {(error) => void} [onError]
*/
/**
* @typedef {object} PipeableStream
* @property {() => void} abort
* @property {(writable: import('stream').Writable) => void} pipe
*/
/**
* @param {import('preact').VNode} vnode
* @param {RenderToPipeableStreamOptions} options
* @param {any} [context]
* @returns {PipeableStream}
*/
export function renderToPipeableStream(vnode, options, context) {
const encoder = new TextEncoder('utf-8');
const controller = new AbortController();
const stream = new PassThrough();
renderToChunks(vnode, {
context,
abortSignal: controller.signal,
onError: (error) => {
if (options.onError) {
options.onError(error);
}
controller.abort(error);
},
onWrite(s) {
stream.write(encoder.encode(s));
}
})
.then(() => {
options.onAllReady && options.onAllReady();
stream.end();
})
.catch((error) => {
stream.destroy(error);
});
Promise.resolve().then(() => {
options.onShellReady && options.onShellReady();
});
return {
abort() {
controller.abort();
stream.destroy(new Error('aborted'));
},
/**
* @param {import("stream").Writable} writable
*/
pipe(writable) {
stream.pipe(writable, { end: true });
}
};
}