Skip to content

Instantly share code, notes, and snippets.

@patheticGeek
Last active June 20, 2025 20:12
Show Gist options
  • Save patheticGeek/9dc0a2e8dba6bcd770b2f98d393c541d to your computer and use it in GitHub Desktop.
Save patheticGeek/9dc0a2e8dba6bcd770b2f98d393c541d to your computer and use it in GitHub Desktop.
streaming-by-hand
{
"name": "streaming-by-hand",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "streaming-by-hand-extras.js",
"scripts": {
"start": "nodemon streaming-by-hand-extras.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.3",
"morgan": "^1.10.0",
"nanoid": "^5.0.6",
"nodemon": "^3.1.0"
}
}
import express from "express";
import morgan from "morgan";
import { nanoid } from "nanoid";
import { Readable } from "stream";
const app = express();
const port = 3000;
app.use(morgan("combined"));
const h = (component, children = [], props = {}) => {
return {
component,
children: Array.isArray(children) ? children : [children],
props,
};
};
const attribAlias = { className: "class" };
const getAlias = (key) => attribAlias[key] || key;
const selfClosing = {
br: true,
input: true,
};
const renderTag = (tag, props = {}) => {
if (!tag) return "";
const attrib = Object.entries(props)
.map(([k, v]) => `${getAlias(k)}="${v}"`)
.join(" ");
if (selfClosing[tag]) return `<${tag}${attrib ? ` ${attrib}` : ""} />`;
return { start: `<${tag}${attrib ? ` ${attrib}` : ""}>`, end: `</${tag}>` };
};
const renderTree = (readable, item, promises) => {
// console.log("renderTree item", item);
if (item === undefined || item === null) {
return;
} else if (["string", "number", "boolean"].includes(typeof item)) {
if (!readable) return item;
readable.push(item);
} else if (typeof item === "object") {
// weird js - we can destructure item even if it is a string
const { component, children, props } = item;
if (typeof component === "string") {
const result = renderTag(component, props);
if (typeof result === "string") {
if (!readable) return result;
else readable.push(result);
}
if (!readable) {
return `${result.start}${children.map((child) =>
renderTree(readable, child, promises)
)}${result.end}`;
} else {
readable.push(result.start);
children.forEach((child) => renderTree(readable, child, promises));
readable.push(result.end);
}
} else if (typeof component === "function") {
const result = component({ ...props, children });
if (result instanceof Promise) {
const id = `${component.name}-${nanoid()}`;
promises.push({ result, id });
renderTree(readable, h("template", "", { id }));
} else {
renderTree(readable, result, promises);
}
}
}
};
const getRedirectMeta = (url) => {
return h("meta", undefined, {
"http-equiv": "refresh",
content: `0; url = ${url}`,
});
};
const getReplacer = (id, rendered) => {
return renderTree(
undefined,
h(
"script",
`document.querySelector("#${id}").insertAdjacentHTML("afterEnd", "${rendered}");document.querySelector("#${id}").remove()`
)
);
};
class NotFoundError extends Error {
url;
constructor({ message, url }) {
super(message);
this.url = url;
}
}
const notFound = ({ message, url } = {}) => {
return new NotFoundError({ message, url });
};
const render = async (response, tree) => {
const readable = new Readable({
read() {
// lie, keep telling there is more data
return true;
},
});
readable.pipe(response);
const promises = [];
renderTree(readable, tree, promises);
const toWait = [];
for (const promise of promises) {
const wait = promise.result
.then((value) => {
const result = renderTree(undefined, value);
const rendered = renderTree(undefined, result);
readable.push(getReplacer(promise.id, rendered));
})
.catch((err) => {
if (err instanceof NotFoundError) {
readable.push(getRedirectMeta(err.url || "/404"));
} else {
readable.push(getRedirectMeta(err.url || "/500"));
}
});
toWait.push(wait);
}
await Promise.all(toWait);
// end the response
readable.push(null);
};
function Button({ value }) {
return h("button", value);
}
async function AwaitMe({ wait = 1 }) {
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
if (Math.random() > 0.5) throw notFound();
return h("p", `i came after ${wait}s`);
}
function App() {
return h(
"main",
[
h("h1", "Hello world"),
h(AwaitMe, undefined, { wait: 5 }),
h(Button, null, { value: "Click Me" }),
h(AwaitMe),
h("br"),
h("p", "hi"),
],
{ className: "bg-blue" }
);
}
app.get("/", async (req, res) => {
res.setHeader("Content-Type", "text/html");
await render(res, h(App));
});
app.get("404", async (req, res) => {
await render(res, h("main", "Not found"));
});
app.get("500", async (req, res) => {
await render(res, h("main", "Server error"));
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
import express from "express";
import morgan from "morgan";
import { nanoid } from "nanoid";
import { Readable } from "stream";
const app = express();
const port = 3000;
app.use(morgan("combined"));
const h = (component, children = [], props = {}) => {
return {
component,
children: Array.isArray(children) ? children : [children],
props,
};
};
const attribAlias = { className: "class" };
const getAlias = (key) => attribAlias[key] || key;
const selfClosing = {
br: true,
input: true,
};
const renderTag = (tag, props = {}) => {
if (!tag) return "";
const attrib = Object.entries(props)
.map(([k, v]) => `${getAlias(k)}="${v}"`)
.join(" ");
if (selfClosing[tag]) return `<${tag}${attrib ? ` ${attrib}` : ""} />`;
return { start: `<${tag}${attrib ? ` ${attrib}` : ""}>`, end: `</${tag}>` };
};
const renderTree = (readable, item, promises) => {
// console.log("renderTree item", item);
if (item === undefined || item === null) {
return;
} else if (["string", "number", "boolean"].includes(typeof item)) {
if (!readable) return item;
readable.push(item);
} else if (typeof item === "object") {
// weird js - we can destructure item even if it is a string
const { component, children, props } = item;
if (typeof component === "string") {
const result = renderTag(component, props);
if (typeof result === "string") {
if (!readable) return result;
else readable.push(result);
}
if (!readable) {
return `${result.start}${children.map((child) =>
renderTree(readable, child, promises)
)}${result.end}`;
} else {
readable.push(result.start);
children.forEach((child) => renderTree(readable, child, promises));
readable.push(result.end);
}
} else if (typeof component === "function") {
const result = component({ ...props, children });
if (result instanceof Promise) {
const id = `${component.name}-${nanoid()}`;
promises.push({ result, id });
renderTree(readable, h("template", "", { id }));
} else {
renderTree(readable, result, promises);
}
}
}
};
const getReplacer = (id, rendered) => {
return renderTree(
undefined,
h(
"script",
`document.querySelector("#${id}").insertAdjacentHTML("afterEnd", "${rendered}");document.querySelector("#${id}").remove()`
)
);
};
const render = async (readable, tree) => {
if (!tree) throw new Error("Pass a component to render");
if (!readable) throw new Error("Pass an readable to output to");
const promises = [];
renderTree(readable, tree, promises);
console.log("renderTree done", promises);
const toWait = [];
for (const promise of promises) {
const wait = promise.result.then((value) => {
const result = renderTree(undefined, value);
const rendered = renderTree(undefined, result);
readable.push(getReplacer(promise.id, rendered));
});
toWait.push(wait);
}
return Promise.all(toWait);
};
function Button({ value }) {
return h("button", value);
}
async function AwaitMe({ wait = 1 }) {
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
return h("p", `i came after ${wait}s`);
}
function App() {
return h(
"div",
[
h("h1", "Hello world"),
h(AwaitMe, undefined, { wait: 5 }),
h(Button, null, { value: "Click Me" }),
h(AwaitMe),
h("br"),
h("p", "hi"),
],
{ className: "bg-blue" }
);
}
app.get("/", async (req, res) => {
const readable = new Readable({
read() {
// lie, keep telling there is more data
return true;
},
});
readable.pipe(res);
await render(readable, h(App));
// end the response
readable.push(null);
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment