// src/jsx/streaming.ts
import { raw } from "../helper/html/index.js";
import { HtmlEscapedCallbackPhase, resolveCallback } from "../utils/html.js";
import { childrenToString } from "./components.js";
import { DOM_RENDERER, DOM_STASH } from "./constants.js";
import { Suspense as SuspenseDomRenderer } from "./dom/components.js";
import { buildDataStack } from "./dom/render.js";
var suspenseCounter = 0;
var Suspense = async ({
children,
fallback
}) => {
if (!children) {
return fallback.toString();
}
if (!Array.isArray(children)) {
children = [children];
}
let resArray = [];
const stackNode = { [DOM_STASH]: [0, []] };
const popNodeStack = (value) => {
buildDataStack.pop();
return value;
};
try {
stackNode[DOM_STASH][0] = 0;
buildDataStack.push([[], stackNode]);
resArray = children.map(
(c) => c == null || typeof c === "boolean" ? "" : c.toString()
);
} catch (e) {
if (e instanceof Promise) {
resArray = [
e.then(() => {
stackNode[DOM_STASH][0] = 0;
buildDataStack.push([[], stackNode]);
return childrenToString(children).then(popNodeStack);
})
];
} else {
throw e;
}
} finally {
popNodeStack();
}
if (resArray.some((res) => res instanceof Promise)) {
const index = suspenseCounter++;
const fallbackStr = await fallback.toString();
return raw(`${fallbackStr}`, [
...fallbackStr.callbacks || [],
({ phase, buffer, context }) => {
if (phase === HtmlEscapedCallbackPhase.BeforeStream) {
return;
}
return Promise.all(resArray).then(async (htmlArray) => {
htmlArray = htmlArray.flat();
const content = htmlArray.join("");
if (buffer) {
buffer[0] = buffer[0].replace(
new RegExp(`.*?`),
content
);
}
let html = buffer ? "" : `${content}