ajo
Version: 
ajo is a JavaScript view library for building user interfaces
74 lines (73 loc) • 3.21 kB
JavaScript
import { Context as y, current as f } from "./context.js";
const m = /* @__PURE__ */ new Set(["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]), b = Symbol.for("ajo.args"), d = (e) => e.replace(/[&<>"']/g, (r) => `&#${r.charCodeAt(0)};`), u = () => {
}, j = (e) => [...p(e)].join(""), p = function* (e, { alloc: r = u, push: t = u, placeholder: n = u } = {}) {
  for (e of o(e, { alloc: r, push: t, placeholder: n }))
    typeof e == "string" ? yield d(e) : yield* $(e, { alloc: r, push: t, placeholder: n });
}, $ = function* ({ nodeName: e, children: r, ...t }, n) {
  let l = "";
  for (const i in t)
    i.startsWith("set:") || t[i] == null || t[i] === !1 || (t[i] === !0 ? l += ` ${i}` : l += ` ${i}="${d(String(t[i]))}"`);
  m.has(e) ? yield `<${e}${l}>` : (yield `<${e}${l}>`, r != null && (yield* p(r, n)), yield `</${e}>`);
}, o = function* (e, r) {
  if (e == null) return;
  const t = typeof e;
  if (t != "boolean")
    if (t == "string") yield e;
    else if (t == "number" || t == "bigint") yield String(e);
    else if (Symbol.iterator in e) for (e of e) yield* o(e, r);
    else "nodeName" in e ? typeof e.nodeName == "function" ? yield* w(e, r) : yield a(e, r) : yield String(e);
}, w = function* ({ nodeName: e, fallback: r = e.fallback, ...t }, n) {
  const l = e.constructor.name;
  e.src ? yield v(e.src, t, n) : l == "GeneratorFunction" ? yield x(e, t, n) : l == "AsyncGeneratorFunction" ? yield S(e, r, t, n) : (t = e(t), typeof t?.then == "function" ? yield A(r, t, n) : yield* o(t, n));
}, v = (e, r, t) => {
  const n = t.alloc();
  return t.push({ id: n, src: e, h: a(r, t), done: !0 }), t.placeholder(n);
}, x = (e, r, t) => {
  const n = { ...e.attrs }, l = { ...e.args };
  for (const c in r)
    c.startsWith("attr:") ? n[c.slice(5)] = r[c] : c == "key" || c == "skip" || c == "memo" || c == "ref" || c.startsWith("set:") ? n[c] = r[c] : l[c] = r[c];
  const i = {
    [y]: Object.create(f()?.[y] ?? null),
    [b]: l,
    next: u,
    return: u,
    throw: (c) => {
      throw c;
    }
  }, s = e.call(i, l), g = f();
  f(i);
  try {
    const c = [...o(s.next().value, t)];
    return { ...n, nodeName: e.is ?? "div", children: c.length == 1 ? c[0] : c };
  } finally {
    s.return?.(), f(g);
  }
}, S = (e, r, t, n) => {
  const l = n.alloc();
  return Promise.resolve().then(async () => {
    const i = e(t);
    n = { ...n, alloc: (s = l) => n.alloc(s) };
    try {
      for (t = await i.next(); !t.done; )
        n.push({ id: l, h: a(t.value, n), done: !1 }), t = await i.next();
      n.push({ id: l, h: a(t.value, n), done: !0 });
    } catch (s) {
      n.push({ id: l, h: a(s, n), done: !0 });
    } finally {
      i.return?.();
    }
  }), n.placeholder(l, r);
}, A = (e, r, t) => {
  const n = t.alloc();
  return r.then((l) => t.push({ id: n, h: a(l, { ...t, alloc: (i = n) => t.alloc(i) }), done: !0 })), t.placeholder(n, e);
}, a = ({ key: e, skip: r, memo: t, ref: n, ...l }, i) => {
  if ("children" in l) {
    const s = [...o(l.children, i)];
    s.length ? l.children = s.length == 1 ? s[0] : s : delete l.children;
  }
  return l;
};
export {
  p as html,
  j as render
};