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.

Revisions

  1. patheticGeek revised this gist Jun 20, 2025. 3 changed files with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,9 @@
    "version": "1.0.0",
    "description": "",
    "type": "module",
    "main": "index.js",
    "main": "streaming-by-hand-extras.js",
    "scripts": {
    "start": "nodemon index.js"
    "start": "nodemon streaming-by-hand-extras.js"
    },
    "keywords": [],
    "author": "",
    File renamed without changes.
    File renamed without changes.
  2. patheticGeek created this gist Jun 20, 2025.
    178 changes: 178 additions & 0 deletions extra.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,178 @@
    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}`);
    });
    145 changes: 145 additions & 0 deletions index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,145 @@
    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}`);
    });
    19 changes: 19 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    {
    "name": "streaming-by-hand",
    "version": "1.0.0",
    "description": "",
    "type": "module",
    "main": "index.js",
    "scripts": {
    "start": "nodemon index.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
    "express": "^4.18.3",
    "morgan": "^1.10.0",
    "nanoid": "^5.0.6",
    "nodemon": "^3.1.0"
    }
    }