From 2f95363ea794fb14165b7539bd900544c76d6940 Mon Sep 17 00:00:00 2001 From: Arthur Fiorette Date: Tue, 29 Oct 2024 18:12:22 -0300 Subject: [PATCH 1/6] code --- .changeset/angry-knives-hope.md | 5 + .changeset/light-grapes-peel.md | 5 + packages/html/jsx.d.ts | 1 + packages/html/suspense.d.ts | 111 ++- packages/html/suspense.js | 352 ++++--- packages/html/test/generator.test.tsx | 1211 +++++++++++++++++++++++++ packages/html/test/suspense.test.tsx | 2 +- 7 files changed, 1536 insertions(+), 151 deletions(-) create mode 100644 .changeset/angry-knives-hope.md create mode 100644 .changeset/light-grapes-peel.md create mode 100644 packages/html/test/generator.test.tsx diff --git a/.changeset/angry-knives-hope.md b/.changeset/angry-knives-hope.md new file mode 100644 index 000000000..9c28ff976 --- /dev/null +++ b/.changeset/angry-knives-hope.md @@ -0,0 +1,5 @@ +--- +'@kitajs/html': minor +--- + +Added support for Generators diff --git a/.changeset/light-grapes-peel.md b/.changeset/light-grapes-peel.md new file mode 100644 index 000000000..b0cf122ad --- /dev/null +++ b/.changeset/light-grapes-peel.md @@ -0,0 +1,5 @@ +--- +'@kitajs/html': patch +--- + +Deprecated key attribute diff --git a/packages/html/jsx.d.ts b/packages/html/jsx.d.ts index 30eb75c0f..595f0631d 100644 --- a/packages/html/jsx.d.ts +++ b/packages/html/jsx.d.ts @@ -680,6 +680,7 @@ declare namespace JSX { * * **If you intend to utilize a similar property, please opt for an alternate name.** * + * @deprecated * @see https://github.com/reactjs/rfcs/pull/107 */ key?: undefined | never; diff --git a/packages/html/suspense.d.ts b/packages/html/suspense.d.ts index 8e7256927..93a5e79f2 100644 --- a/packages/html/suspense.d.ts +++ b/packages/html/suspense.d.ts @@ -1,5 +1,5 @@ import type { Readable } from 'node:stream'; -import type { Children } from './'; +import type { Children } from './index'; declare global { /** @@ -12,7 +12,7 @@ declare global { * write the HTML, the number of running promises and if the first suspense has * already resolved. */ - requests: Map; + requests: Map; /** * This value is used (and incremented shortly after) when no requestId is provided @@ -34,6 +34,9 @@ declare global { }; } +/** A unique request identifier that can be any literal type. */ +export type Rid = number | string; + /** Everything a suspense needs to know about its request lifecycle. */ export type RequestData = { /** If the first suspense has already resolved */ @@ -62,6 +65,14 @@ export type RequestData = { */ export function Suspense(props: SuspenseProps): JSX.Element; +/** + * A component that keeps injecting html while the generator is running. + * + * The `rid` prop is the one {@linkcode renderToStream} returns, this way the suspense + * knows which request it belongs to. + */ +export function Generator(props: GeneratorProps): JSX.Element; + /** * Transforms a component tree who may contain `Suspense` components into a stream of * HTML. @@ -89,10 +100,11 @@ export function Suspense(props: SuspenseProps): JSX.Element; * id will be used. * @see {@linkcode Suspense} */ -export function renderToStream( - html: JSX.Element | ((rid: number | string) => JSX.Element), - rid?: number | string +export declare function renderToStream( + html: (rid: Rid) => JSX.Element, + rid?: Rid ): Readable; +export declare function renderToStream(html: JSX.Element, rid: Rid): Readable; /** * Joins the html base template (with possible suspense's fallbacks) with the request data @@ -122,9 +134,70 @@ export function renderToStream( */ export function resolveHtmlStream(template: JSX.Element, data: RequestData): Readable; +/** A helper function to get the request data for a given request id. */ +export function useRequestData(rid: Rid): RequestData; + +/** + * A helper function to attempt to use the error handler to recovery an async error thrown + * by a suspense or generator. + * + * @param run A unique number to identify the current template **(not request id)** + */ +export function recoverPromiseRejection( + data: RequestData, + run: number, + handler: SuspenseProps['catch'], + mode: RcInsert, + error: Error +): Promise; + +/** + * A helper function to clear the request data once everything is resolved and the stream + * needs to be cleared to avoid memory leaks. + */ +export function clearRequestData(rid: Rid, data: RequestData): void; + +/** + * Creates the html