Skip to content

Commit

Permalink
feat: HtmlStream type
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfiorette committed Sep 26, 2023
1 parent 8450089 commit 579a26f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 22 deletions.
26 changes: 11 additions & 15 deletions examples/suspense-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,24 @@ function renderLayout(rid: number) {
}

http
.createServer((req, res): void => {
.createServer((req, response) => {
// This simple webserver only has a index.html file
if (req.url !== '/' && req.url !== '/index.html') {
res.end();
response.end();
return;
}

// Charset utf8 is important to avoid old browsers utf7 xss attacks
res.setHeader('Content-Type', 'text/html; charset=utf-8');
// ⚠️ Charset utf8 is important to avoid old browsers utf7 xss attacks
response.setHeader('Content-Type', 'text/html; charset=utf-8');

const stream = renderToStream(renderLayout);
console.log(`[${stream.rid}] Rendering ${req.url}`);
// Creates the html stream
const htmlStream = renderToStream(renderLayout);

stream
// Streaming stuff happens after first chunk (fallback) is sent
.once('data', () => {
stream.on('data', () => {
console.log(`${stream.rid}> Streaming for ${req.url}`);
});
})
.once('close', () => console.log(`<${stream.rid} Finished stream for ${req.url}`))
.pipe(res);
// Pipes it into the response
htmlStream.pipe(response);

// If its an express or fastify server, just use
// response.type('text/html; charset=utf-8').send(htmlStream);
})
.listen(8080, () => {
console.log('Listening to http://localhost:8080');
Expand Down
12 changes: 7 additions & 5 deletions suspense.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ declare global {
/** How many are still running */
running: number;
/** The stream we should write */
stream: WeakRef<Readable>;
stream: WeakRef<HtmlStream>;
}
>;

Expand Down Expand Up @@ -83,10 +83,7 @@ export function Suspense(props: SuspenseProps): JSX.Element;
export function renderToStream(
factory: (this: void, rid: number) => JSX.Element,
rid?: number
): Readable & {
/** The final resource id used for this render */
rid: number;
};
): HtmlStream;

/**
* Returns a promise that resolves to the entire HTML generated by the component tree.
Expand Down Expand Up @@ -143,3 +140,8 @@ export interface SuspenseProps {
*/
catch?: JSX.Element | ((error: unknown) => JSX.Element);
}

export interface HtmlStream extends Readable {
/** The final resource id used for this render */
rid: number;
}
5 changes: 3 additions & 2 deletions suspense.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,10 @@ function renderToStream(factory, customRid) {
}

const resourceId = customRid || SUSPENSE_ROOT.requestCounter++;
const stream = new Readable({ read: function noop() {} });

// @ts-expect-error Defines the resource id used
/** @type {import('./suspense').HtmlStream} */
//@ts-expect-error - we manually set the rid
const stream = new Readable({ read: function noop() {} });
stream.rid = resourceId;

SUSPENSE_ROOT.resources.set(resourceId, {
Expand Down

0 comments on commit 579a26f

Please sign in to comment.