Skip to content

Commit

Permalink
feat: strings as RequestId and fastify plugin support
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfiorette committed Jan 21, 2024
1 parent 81174b7 commit 307922a
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 182 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ To use the `@kitajs/html` package, follow these steps:
>
> # Be sure your setup is working correclty!
>
> Try writing `console.log(<div>{String.name}</div>);` in your editor. If it **THROWS**
> a `XSS` error, then your setup is correct. Refer to the
> Try writing `console.log(<div>{String.name}</div>);` in your editor. If it **THROWS** a
> `XSS` error, then your setup is correct. Refer to the
> [@kitajs/ts-html-plugin](https://github.com/kitajs/ts-html-plugin) repository for more
> details on setting up editor intellisense. _(It should throw, as `String.name` has a type of `string`, type which may or may not have special caracters)_
> details on setting up editor intellisense. _(It should throw, as `String.name` has a
> type of `string`, type which may or may not have special caracters)_
<br />
<br />
Expand Down Expand Up @@ -830,7 +831,7 @@ Typed Html and Common Tags.

You can run this yourself by running `pnpm bench`.

```md
```
cpu: 13th Gen Intel(R) Core(TM) i5-13600K
runtime: node v20.9.0 (x64-linux)
Expand Down
2 changes: 1 addition & 1 deletion examples/suspense-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function SleepForMs({ ms, children }: PropsWithChildren<{ ms: number }>) {
return Html.contentsToString([children || String(ms)]);
}

function renderLayout(rid: number) {
function renderLayout(rid: number | string) {
return (
<html>
<div>
Expand Down
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export function createElement<C extends Children[], N extends string | Function>
): Promise<string> extends C[number]
? Promise<string>
: N extends () => Promise<string>
? Promise<string>
: string;
? Promise<string>
: string;

/**
* Joins raw string html elements into a single html string.
Expand Down
70 changes: 38 additions & 32 deletions suspense.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Readable } from 'stream';
import type { Readable, Writable } from 'stream';
import type { Children } from './';

declare global {
Expand All @@ -8,23 +8,11 @@ declare global {
*/
var SUSPENSE_ROOT: {
/**
* The suspense resource map is a map of all request ids and its resources containing
* the stream to write the HTML, the number of running promises and if the first
* suspense has already resolved.
* The requests map is a map of RequestId x SuspenseData containing the stream to
* write the HTML, the number of running promises and if the first suspense has
* already resolved.
*/
resources: Map<
number,
{
/** If the first suspense has already resolved */
sent: boolean;
/** How many are still running */
running: number;
/** The stream we should write */
stream: WeakRef<HtmlStream>;
/** All suspense's runner id being rendered inside a parent suspense */
children?: { run: number; html: string }[];
}
>;
requests: Map<number | string, RequestData>;

/**
* This value is used (and incremented shortly after) when no requestId is provided
Expand Down Expand Up @@ -53,6 +41,22 @@ declare global {
};
}

/** Everything a suspense needs to know about its request lifecycle. */
export type RequestData = {
/** If the first suspense has already resolved */
sent: boolean;

/** How many are still running */
running: number;

/**
* The stream we should write
*
* WeakRef requires ES2021 typings (node 14+) to be installed.
*/
stream: WeakRef<Writable>;
};

/**
* A component that returns a fallback while the async children are loading.
*
Expand Down Expand Up @@ -85,14 +89,14 @@ export function Suspense(props: SuspenseProps): JSX.Element;
* ```
*
* @param factory The component tree to render.
* @param rid The resource id to identify the request, if not provided, a new incrementing
* @param rid The request id to identify the request, if not provided, a new incrementing
* id will be used.
* @see {@linkcode Suspense}
*/
export function renderToStream(
factory: (this: void, rid: number) => JSX.Element,
rid?: number
): HtmlStream;
factory: (this: void, rid: number | string) => JSX.Element,
rid?: number | string
): Readable;

/**
* Returns a promise that resolves to the entire HTML generated by the component tree.
Expand All @@ -114,12 +118,12 @@ export function renderToStream(
* ```
*
* @param factory The component tree to render
* @param rid The resource id to identify the request, if not provided, a new incrementing
* @param rid The request id to identify the request, if not provided, a new incrementing
* id will be used. @see {@linkcode renderToStream}
*/
export function renderToString(
factory: (this: void, rid: number) => JSX.Element,
rid?: number
factory: (this: void, rid: number | string) => JSX.Element,
rid?: number | string
): Promise<string>;

/**
Expand All @@ -136,8 +140,8 @@ export const SuspenseScript: string;
* @see {@linkcode Suspense}
*/
export interface SuspenseProps {
/** The resource id is used to identify the request for this suspense. */
rid: number;
/** The request id is used to identify the request for this suspense. */
rid: number | string;

/** The fallback to render while the async children are loading. */
fallback: JSX.Element;
Expand All @@ -158,10 +162,12 @@ export interface SuspenseProps {
}

/**
* A HtmlStream is a readable string stream that also contains the resource id used to
* identify the request.
* Internal function used to pipe the HTML to the stream. Users should not use this
* function directly. This function assumes that the stream is available and the request
* id is valid.
*
* This is helpful when integrating @kitajs/html suspense support into your own runtime.
*
* @internal
*/
export interface HtmlStream extends Readable {
/** The final resource id used for this render */
rid: number;
}
export function pipeHtml(html: JSX.Element, stream: Writable, rid: number | string): void;
Loading

0 comments on commit 307922a

Please sign in to comment.