diff --git a/TODO.md b/TODO.md index 46446808..7ad25737 100644 --- a/TODO.md +++ b/TODO.md @@ -10,7 +10,6 @@ controller pattern; `Map` per-row model). Legacy Open: - **Rerenderer naming bikeshed** (Rerender vs Rerenderer) — deferred. -- **AnchorBlock** cut candidate; **Toggle** disposition — decide. - **VirtualList** (recycled-pool / virtualization, FUTURE, separate block) — `docs/design/VirtualList.md` + `frame-primitives.md`. - **`stopRerenderer`** (name TBD): opt a subtree out of reuse (mint fresh nodes) diff --git a/docs/design/VirtualList.md b/docs/design/VirtualList.md index 9fadf7f3..cfcbf022 100644 --- a/docs/design/VirtualList.md +++ b/docs/design/VirtualList.md @@ -1,7 +1,7 @@ # VirtualList (name TBD) — recycled-pool / virtualized list > Status: FUTURE, separate block. Notes parked while designing -> [KeyedList](../../packages/maya/blocks/KeyedList.js). Not started. +> [KeyedList](../../packages/maya/lists/KeyedList.js). Not started. The second list strategy from the 2026-06-17 TODO decision. Distinguished from `KeyedList` by **node lifecycle**, not by a config flag — so it's a diff --git a/packages/azoth/maya.js b/packages/azoth/maya.js index 7a3b0cd9..ec436115 100644 --- a/packages/azoth/maya.js +++ b/packages/azoth/maya.js @@ -1,3 +1,3 @@ export * from '@azothjs/maya/compose'; -export * from '@azothjs/maya/renderer'; -export * from '@azothjs/maya/blocks'; \ No newline at end of file +export * from '@azothjs/maya/lists'; +export * from '@azothjs/maya/renderer'; \ No newline at end of file diff --git a/packages/azoth/runtime.js b/packages/azoth/runtime.js index 6be362fd..43379554 100644 --- a/packages/azoth/runtime.js +++ b/packages/azoth/runtime.js @@ -1,9 +1,9 @@ export { - compose as __c, - createComponent as __rC, - composeComponent as __cC, + compose as __compose, + createComponent as __createComponent, + composeComponent as __composeComponent, } from '@azothjs/maya/compose'; export { - renderer as __renderer, + render as __render, } from '@azothjs/maya/renderer'; \ No newline at end of file diff --git a/packages/maya/blocks/AnchorBlock.js b/packages/maya/blocks/AnchorBlock.js deleted file mode 100644 index ad108349..00000000 --- a/packages/maya/blocks/AnchorBlock.js +++ /dev/null @@ -1,21 +0,0 @@ -import { compose } from '../compose'; - -export class BlockAnchor { - #anchor = document.createComment(0); - - replace(input) { - compose(this.#anchor, input, false); - } - - append(input) { - compose(this.#anchor, input, true); - } - - remove() { - compose(this.#anchor, null, false); - } - - render() { - return this.#anchor; - } -} diff --git a/packages/maya/blocks/Toggle.js b/packages/maya/blocks/Toggle.js deleted file mode 100644 index b1f3e46f..00000000 --- a/packages/maya/blocks/Toggle.js +++ /dev/null @@ -1,3 +0,0 @@ -export function Toggle({ on: predicate }, childNodes) { - return payload => predicate(payload) ? childNodes : null; -} diff --git a/packages/maya/compose/compose.js b/packages/maya/compose/compose.js index 1abcef8c..2103b102 100644 --- a/packages/maya/compose/compose.js +++ b/packages/maya/compose/compose.js @@ -1,5 +1,5 @@ import { Channel } from '../channels/channel.js'; -import { activeRerenderer } from '../renderer/rerenderer.js'; +import { activeRenderer } from '../renderer/rerenderer.js'; export const IGNORE = Symbol.for('azoth.compose.IGNORE'); @@ -12,7 +12,7 @@ export function compose(anchor, input, keepLast, props, childNodes) { // only on the replace path: keepLast=true means accumulate, where // a repeated value is a legitimate "add another." if(!keepLast) { - const rr = activeRerenderer(); + const rr = activeRenderer(); if(rr && rr.skipIfSame(anchor, input)) return; } @@ -113,7 +113,7 @@ export function compose(anchor, input, keepLast, props, childNodes) { } export function composeComponent(anchor, [Constructor, props, childNodes]) { - const rr = activeRerenderer(); + const rr = activeRenderer(); if(rr) { // The update verb. Same Constructor at this anchor → update in // place. Different Constructor → fall through to create (=== fails diff --git a/packages/maya/blocks/KeyedList.js b/packages/maya/lists/KeyedList.js similarity index 100% rename from packages/maya/blocks/KeyedList.js rename to packages/maya/lists/KeyedList.js diff --git a/packages/maya/blocks/KeyedOList.js b/packages/maya/lists/KeyedOList.js similarity index 100% rename from packages/maya/blocks/KeyedOList.js rename to packages/maya/lists/KeyedOList.js diff --git a/packages/maya/blocks/KeyedTable.js b/packages/maya/lists/KeyedTable.js similarity index 100% rename from packages/maya/blocks/KeyedTable.js rename to packages/maya/lists/KeyedTable.js diff --git a/packages/maya/blocks/KeyedUList.js b/packages/maya/lists/KeyedUList.js similarity index 100% rename from packages/maya/blocks/KeyedUList.js rename to packages/maya/lists/KeyedUList.js diff --git a/packages/maya/blocks/blocks.js b/packages/maya/lists/index.js similarity index 81% rename from packages/maya/blocks/blocks.js rename to packages/maya/lists/index.js index dfff707b..b2d3af0f 100644 --- a/packages/maya/blocks/blocks.js +++ b/packages/maya/lists/index.js @@ -1,4 +1,3 @@ -export * from './Toggle.js'; export * from './KeyedList.js'; export * from './KeyedUList.js'; export * from './KeyedOList.js'; diff --git a/packages/maya/package.json b/packages/maya/package.json index 0d6f4830..5783e80d 100644 --- a/packages/maya/package.json +++ b/packages/maya/package.json @@ -26,10 +26,10 @@ "**/!(*test|*config).js" ], "exports": { - "./blocks": "./blocks/blocks.js", "./channels": "./channels/index.js", "./compose": "./compose/compose.js", - "./renderer": "./renderer/renderer.js" + "./lists": "./lists/index.js", + "./renderer": "./renderer/render.js" }, "devDependencies": { "test-utils": "workspace:^" diff --git a/packages/maya/renderer/renderer.js b/packages/maya/renderer/render.js similarity index 86% rename from packages/maya/renderer/renderer.js rename to packages/maya/renderer/render.js index 89841619..bc922673 100644 --- a/packages/maya/renderer/renderer.js +++ b/packages/maya/renderer/render.js @@ -1,8 +1,8 @@ import { DOMRenderer } from './dom-renderer.js'; import { HTMLRenderer } from './html-renderer.js'; -import { activeRerenderer } from './rerenderer.js'; +import { activeRenderer } from './rerenderer.js'; -export { rerenderer, activeRerenderer } from './rerenderer.js'; +export { rerenderer, activeRenderer } from './rerenderer.js'; const templates = new Map(); // cache let renderEngine = DOMRenderer; // DOM or HTML engine @@ -25,10 +25,10 @@ function get(id, isFragment = false, content) { return template; } -export function renderer(id, targets, makeBind, isFragment, content) { +export function render(id, targets, makeBind, isFragment, content) { const create = get(id, isFragment, content); - // Per-declaration identity: the rerenderer's cache key. Each renderer() + // Per-declaration identity: the rerenderer's cache key. Each render() // call is one compiled call site (per-site factory) — closure identity IS // the key, so deduped templates (same id, multiple sites) cannot collide // across sites. @@ -43,7 +43,7 @@ export function renderer(id, targets, makeBind, isFragment, content) { return (...args) => { if(!create) return null; - const rr = activeRerenderer(); + const rr = activeRenderer(); // Under a rerenderer: reuse this site's cached node, rebound. Otherwise // (plain forward render): a fresh build. const { node: root, bind } = rr diff --git a/packages/maya/renderer/rerenderer.js b/packages/maya/renderer/rerenderer.js index 700516c4..ca0d6404 100644 --- a/packages/maya/renderer/rerenderer.js +++ b/packages/maya/renderer/rerenderer.js @@ -34,7 +34,7 @@ const stack = []; -export function activeRerenderer() { +export function activeRenderer() { return stack.length ? stack[stack.length - 1] : null; } diff --git a/packages/maya/renderer/rerenderer.test.js b/packages/maya/renderer/rerenderer.test.js index 3a8b764f..8b0b7171 100644 --- a/packages/maya/renderer/rerenderer.test.js +++ b/packages/maya/renderer/rerenderer.test.js @@ -1,12 +1,12 @@ import { describe, test, beforeAll } from 'vitest'; import { compose, composeComponent, createComponent } from '../compose/compose.js'; import { Channel } from '../channels/channel.js'; -import { renderer, RenderService } from './renderer.js'; +import { render, RenderService } from './render.js'; import { rerenderer } from './rerenderer.js'; /** * Increment (a) of the Rerenderer spike — runtime only, intrinsic only. - * Templates are hand-built renderer(...) calls (what thoth emits), per + * Templates are hand-built render(...) calls (what thoth emits), per * the pattern in controller.test.js. See docs/design/rerenderer.md. */ @@ -18,7 +18,7 @@ const slotBind = targets => { const t0 = targets[0]; return v0 => compose(t0, v0); }; -const makeP = id => renderer(id, slotTargets, slotBind, false, `

`); +const makeP = id => render(id, slotTargets, slotBind, false, `

`); describe('rerenderer — the gate', () => { @@ -65,8 +65,8 @@ describe('rerenderer — control flow (the hooks coin, flipped)', () => { test('conditional branches: each cached by its own site; sleeping, not dead', ({ expect }) => { // anchor comment is childNodes[1] here — text "A:" is [0] const prefixTargets = r => [r.childNodes[1]]; - const tA = renderer('rr-br-a', prefixTargets, slotBind, false, `

A:

`); - const tB = renderer('rr-br-b', prefixTargets, slotBind, false, `

B:

`); + const tA = render('rr-br-a', prefixTargets, slotBind, false, `

A:

`); + const tB = render('rr-br-b', prefixTargets, slotBind, false, `

B:

`); const fn = rerenderer((flag, v) => flag ? tA(v) : tB(v)); const a1 = fn(true, 'x'); @@ -107,8 +107,8 @@ describe('rerenderer — control flow (the hooks coin, flipped)', () => { // Two declarations, SAME template id — the compiled shape after // per-site factory emission. Closure identity keys the cache. const html = `

`; - const tX = renderer('rr-dup', slotTargets, slotBind, false, html); - const tY = renderer('rr-dup', slotTargets, slotBind, false, html); + const tX = render('rr-dup', slotTargets, slotBind, false, html); + const tY = render('rr-dup', slotTargets, slotBind, false, html); const fn = rerenderer((a, b) => [tX(a), tY(b)]); const [x1, y1] = fn('left', 'right'); @@ -168,13 +168,13 @@ describe('rerenderer — anchor memory (=== skip)', () => { describe('rerenderer — components inside the wrap (increment c)', () => { // Simulates the compiled component slot: bind receives the tuple - // [Constructor, props] and calls composeComponent (what __cC does). + // [Constructor, props] and calls composeComponent (what __composeComponent does). const componentBind = targets => { const t0 = targets[0]; return v0 => composeComponent(t0, v0); }; const makeHost = id => - renderer(id, slotTargets, componentBind, false, `

`); + render(id, slotTargets, componentBind, false, `

`); test('chain rule: setup runs once, the returned rerenderable is re-invoked', ({ expect }) => { const tCard = makeP('rr-c-card'); @@ -336,11 +336,11 @@ describe('rerenderer — UIComponent protocol (increment d)', () => { return v0 => composeComponent(t0, v0); }; const makeHost = id => - renderer(id, slotTargets, componentBind, false, `

`); + render(id, slotTargets, componentBind, false, `

`); // Transpiled JSX emits one factory declaration per call site (increment // b). Site identity is the factory's CLOSURE identity (fresh per - // renderer() call), so a render() and an update() that each contain + // render() call), so a render() and an update() that each contain // are distinct sites even with identical HTML — they can't share a node // the way two calls to one factory would. (That same-HTML-still-distinct // path is proven by the "deduped templates cannot collide" test above; @@ -460,7 +460,7 @@ describe('rerenderer — Channel update verb (increment e)', () => { return v0 => composeComponent(t0, v0); }; const makeHost = id => - renderer(id, slotTargets, channelBind, false, `

`); + render(id, slotTargets, channelBind, false, `

`); // A minimal Observable whose subscribe/unsubscribe we can count. const observable = () => { diff --git a/packages/thoth/COMPILER.md b/packages/thoth/COMPILER.md index 5278466e..284ea146 100644 --- a/packages/thoth/COMPILER.md +++ b/packages/thoth/COMPILER.md @@ -159,8 +159,8 @@ The function receives the root element (`r`) and optionally the array of `data-b const t0 = ts[0], t1 = ts[1], t2 = ts[2]; return (v0, v1, v2) => { t0.className = v0; // Property assignment - __c(t1, v1); // Compose into child position - __c(t2, v2); // Compose into child position + __compose(t1, v1); // Compose into child position + __compose(t2, v2); // Compose into child position }; } ``` @@ -169,16 +169,16 @@ The function receives the root element (`r`) and optionally the array of `data-b - Property assignment: `t0.className = v0` - Dataset assignment: `t0.dataset.id = v0` - Spread props: `Object.assign(t0, v0)` -- Child compose: `__c(t0, v0)` (calls Maya's compose) -- Component compose: `__cC(t0, v0)` (calls Maya's composeComponent) +- Child compose: `__compose(t0, v0)` (calls Maya's compose) +- Component compose: `__composeComponent(t0, v0)` (calls Maya's composeComponent) ### 3. Render Generator (`makeRenderer`) -**Purpose:** Generate the call to Maya's `__renderer` function. +**Purpose:** Generate the call to Maya's `__render` function. ```javascript // Output -__renderer("77e67b80", g5feceb66, b6b86b273, false, `

`) +__render("77e67b80", g5feceb66, b6b86b273, false, `

`) ``` Arguments: @@ -263,7 +263,7 @@ const b =

{name2}

; const a =

{x}

; const b =
{y}
; // Different elements, but same binding pattern (one child compose) -// Can share the same bind function: (ts) => { return (v0) => { __c(ts[0], v0); }; } +// Can share the same bind function: (ts) => { return (v0) => { __compose(ts[0], v0); }; } ``` This emerges naturally from decomposing the compilation into these pieces. diff --git a/packages/thoth/compiler.test.js b/packages/thoth/compiler.test.js index 52c74ac3..6bb22975 100644 --- a/packages/thoth/compiler.test.js +++ b/packages/thoth/compiler.test.js @@ -752,10 +752,10 @@ describe('components and custom element', () => { const { code, templates } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; import { tdb0b7033 } from 'virtual:azoth-templates?id=db0b7033'; - const c = __rC(Component, { flag: true, }); - const cProps = __rC(Component, { flag: true, other: value, }); + const c = __createComponent(Component, { flag: true, }); + const cProps = __createComponent(Component, { flag: true, other: value, }); const nested = tdb0b7033([Component, { flag: true, }]); " `); @@ -806,10 +806,10 @@ describe('components and custom element', () => { const { code, templates } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; - const c = __rC(Component, {}); - const cProps = __rC(Component, { prop: value, ...spread, attr: "static", }); + const c = __createComponent(Component, {}); + const cProps = __createComponent(Component, { prop: value, ...spread, attr: "static", }); " `); expect(templates).toMatchInlineSnapshot(` @@ -844,9 +844,9 @@ describe('components and custom element', () => { const input = `const c = ;`; const { code } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; - const c = __rC(Component, { "data-id": x, "aria-label": y, name: z, }); + const c = __createComponent(Component, { "data-id": x, "aria-label": y, name: z, }); " `); }); @@ -899,10 +899,10 @@ describe('components and custom element', () => { const { code, templates } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; import { t6e8375c4 } from 'virtual:azoth-templates?id=6e8375c4'; - const $A = __rC(A, {}); - const $B = __rC(B, {}); + const $A = __createComponent(A, {}); + const $B = __createComponent(B, {}); const dom = t6e8375c4($A,$B); " `); @@ -968,14 +968,14 @@ describe('components and custom element', () => { const { code, templates } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; import { t15aa2705, t15aa2705_1, t15aa2705_2, t15aa2705_3, t982d9e3e, t9155678a } from 'virtual:azoth-templates?id=15aa2705&id=15aa2705&id=15aa2705&id=15aa2705&id=982d9e3e&id=9155678a'; - const c = __rC(Component, {}, t15aa2705("test")); - const cTrim = __rC(Component, {}, t15aa2705_1("test")); - const cTrimStart = __rC(Component, {}, t15aa2705_2("test")); - const cTrimEnd = __rC(Component, {}, t15aa2705_3("test")); - const cText = __rC(Component, {}, t982d9e3e()); - const cFrag = __rC(Component, {}, t9155678a(1,2)); + const c = __createComponent(Component, {}, t15aa2705("test")); + const cTrim = __createComponent(Component, {}, t15aa2705_1("test")); + const cTrimStart = __createComponent(Component, {}, t15aa2705_2("test")); + const cTrimEnd = __createComponent(Component, {}, t15aa2705_3("test")); + const cText = __createComponent(Component, {}, t982d9e3e()); + const cFrag = __createComponent(Component, {}, t9155678a(1,2)); " `); @@ -1412,12 +1412,12 @@ describe('controller', () => { const { code, templates } = compile(input); expect(code).toMatchInlineSnapshot(` - "import { __rC } from 'azoth/runtime'; + "import { __createComponent } from 'azoth/runtime'; import { t3514925d, tab8527d7, t286a9d57 } from 'virtual:azoth-templates?id=3514925d&id=ab8527d7&id=286a9d57'; const C = Updater.for(({status}, childNodes) => t3514925d("status",childNodes)); const Greeting = Controller.for(({name}) => tab8527d7(name)); const greeting = Greeting.render(data); - const t = __rC(C, { status: status, }, t286a9d57(greeting)); + const t = __createComponent(C, { status: status, }, t286a9d57(greeting)); " `); expect(templates).toMatchInlineSnapshot(` diff --git a/packages/thoth/playground.test.js b/packages/thoth/playground.test.js index 7da8d1cc..9a04a661 100644 --- a/packages/thoth/playground.test.js +++ b/packages/thoth/playground.test.js @@ -17,7 +17,7 @@ import { * html: the template HTML (delivered in the .html page, by id) * targets: the generated target-selector function (g…) * bind: the generated binder (b…) — values in, DOM writes out - * renderer: the template factory wiring (t… = __renderer(…)) + * renderer: the template factory wiring (t… = __render(…)) * * To reason about a new scenario: add a test with empty snapshots and run * @@ -57,24 +57,24 @@ describe('decomposition playground', () => { expect(decompose(input)).toMatchInlineSnapshot(` " ==== code ==== - import { __rC } from 'azoth/runtime'; + import { __createComponent } from 'azoth/runtime'; import { t4a104a2a } from 'virtual:azoth-templates?id=4a104a2a'; const Greeting = ({name}) => { const salutation = name === 'CascadiaJS' ? "Whazzup" : "Hello"; return t4a104a2a(salutation,name.toUpperCase()); }; - document.body.append(__rC(Greeting, { name: "CascadiaJS", })); + document.body.append(__createComponent(Greeting, { name: "CascadiaJS", })); ==== template 4a104a2a ==== html:

, !

targets: r => [r.childNodes[0],r.childNodes[2]] bind: (ts) => { const t0 = ts[0], t1 = ts[1]; return (v0, v1) => { - __c(t0, v0); - __c(t1, v1); + __compose(t0, v0); + __compose(t1, v1); }; } - renderer: __renderer("4a104a2a", g356056d3, bac4750db, false) + renderer: __render("4a104a2a", g356056d3, bac4750db, false) ==== template e3b0c442 ==== html: targets: null @@ -102,7 +102,7 @@ describe('decomposition playground', () => { t0.className = v0; }; } - renderer: __renderer("0095e1b8", gd124b23c, bc38a3225, false) + renderer: __render("0095e1b8", gd124b23c, bc38a3225, false) " `); @@ -135,7 +135,7 @@ describe('decomposition playground', () => { t1.name = v1; }; } - renderer: __renderer("9ca71c1d", ga95fa6bb, b90264fbb, false) + renderer: __render("9ca71c1d", ga95fa6bb, b90264fbb, false) " `); @@ -181,20 +181,20 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("9a2e4cdb", gdb407f11, b6b86b273, false) + renderer: __render("9a2e4cdb", gdb407f11, b6b86b273, false) ==== template 732d1cd1 ==== html:
targets: r => [r.childNodes[0]] bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("732d1cd1", gdb407f11, b6b86b273, false) + renderer: __render("732d1cd1", gdb407f11, b6b86b273, false) " `); }); @@ -217,20 +217,20 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("f4127425", gdb407f11, b6b86b273, false) + renderer: __render("f4127425", gdb407f11, b6b86b273, false) ==== template 79ccc8b8 ==== html:

loading %

targets: r => [r.childNodes[1]] bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("79ccc8b8", g043f347c, b6b86b273, false) + renderer: __render("79ccc8b8", g043f347c, b6b86b273, false) " `); }); @@ -255,10 +255,10 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0]; return (v0) => { - __cC(t0, v0); + __composeComponent(t0, v0); }; } - renderer: __renderer("3d3e41e0", g043f347c, bd4735e3a, false) + renderer: __render("3d3e41e0", g043f347c, bd4735e3a, false) " `); }); @@ -281,20 +281,20 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("15aa2705", gdb407f11, b6b86b273, false) + renderer: __render("15aa2705", gdb407f11, b6b86b273, false) ==== template 15aa2705 ==== html:

targets: r => [r.childNodes[0]] bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("15aa2705", gdb407f11, b6b86b273, false) + renderer: __render("15aa2705", gdb407f11, b6b86b273, false) " `); }); @@ -319,20 +319,20 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("057b50eb", g043f347c, b6b86b273, false) + renderer: __render("057b50eb", g043f347c, b6b86b273, false) ==== template fbb7e8b4 ==== html:
  • targets: r => [r.childNodes[0]] bind: (ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; } - renderer: __renderer("fbb7e8b4", gdb407f11, b6b86b273, false) + renderer: __render("fbb7e8b4", gdb407f11, b6b86b273, false) " `); }); @@ -359,11 +359,11 @@ describe('decomposition playground', () => { bind: (ts) => { const t0 = ts[0], t1 = ts[1]; return (v0, v1) => { - __c(t0, v0); - __c(t1, v1); + __compose(t0, v0); + __compose(t1, v1); }; } - renderer: __renderer("47556cd8", g356056d3, bac4750db, false) + renderer: __render("47556cd8", g356056d3, bac4750db, false) " `); }); diff --git a/packages/thoth/transform/Analyzer.js b/packages/thoth/transform/Analyzer.js index b18118b0..a5428206 100644 --- a/packages/thoth/transform/Analyzer.js +++ b/packages/thoth/transform/Analyzer.js @@ -70,7 +70,7 @@ export class Analyzer { } else { assessElement(node); - if(node.isComponent) this.#imports.add('rC'); + if(node.isComponent) this.#imports.add('createComponent'); this.JSXElement(node); } } diff --git a/packages/thoth/transform/Transpiler.js b/packages/thoth/transform/Transpiler.js index a971a420..8cc48721 100644 --- a/packages/thoth/transform/Transpiler.js +++ b/packages/thoth/transform/Transpiler.js @@ -141,7 +141,7 @@ export class Transpiler extends Generator { } CreateElement(node, state) { - state.write(`__rC(`, node); + state.write(`__createComponent(`, node); this.CompleteElement(node, node.componentExpr, state); state.write(`)`); } @@ -153,7 +153,7 @@ export class Transpiler extends Generator { } else { // Always emit empty object so components can safely destructure props - // -> __rC(Component, {}) not __rC(Component) + // -> __createComponent(Component, {}) not __createComponent(Component) state.write(`, {}`); } diff --git a/packages/thoth/transform/template-generators.js b/packages/thoth/transform/template-generators.js index 7059619a..41f88e09 100644 --- a/packages/thoth/transform/template-generators.js +++ b/packages/thoth/transform/template-generators.js @@ -24,7 +24,7 @@ export function makeRenderer({ isEmpty, id, targetKey, tMap, bindKey, bMap, isDo const content = !options?.noContent; const target = targetKey ? `g${targetKey}` : `null`; const bind = bindKey ? `b${bindKey}` : `null`; - let renderer = `__renderer(`; + let renderer = `__render(`; renderer += `"${id}", ${target}, ${bind}, ${isDomFragment}`; if(content) renderer += ', `' + `${html}` + '`'; renderer += `)`; @@ -36,7 +36,7 @@ const TARGETS = 'ts'; const TARGET = 't'; const VALUE = 'v'; // reserved, child, component, prop, spread -const METHOD = ['', '__c', '__cC', '', 'Object.assign']; +const METHOD = ['', '__compose', '__composeComponent', '', 'Object.assign']; export function makeBind({ isStatic, bindings }) { if(isStatic) return 'null'; diff --git a/packages/thoth/transform/template-generators.test.js b/packages/thoth/transform/template-generators.test.js index ae4bf4cd..6fc44fc7 100644 --- a/packages/thoth/transform/template-generators.test.js +++ b/packages/thoth/transform/template-generators.test.js @@ -93,7 +93,7 @@ describe('bind generator', () => { "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }" `); @@ -105,7 +105,7 @@ describe('bind generator', () => { "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }" `); @@ -121,8 +121,8 @@ describe('bind generator', () => { const t0 = ts[0], t1 = ts[1], t2 = ts[2]; return (v0, v1, v2) => { t0.className = v0; - __c(t1, v1); - __c(t2, v2); + __compose(t1, v1); + __compose(t2, v2); }; }" ` @@ -138,7 +138,7 @@ describe('bind generator', () => { "(ts) => { const t0 = ts[0]; return (v0) => { - __cC(t0, v0); + __composeComponent(t0, v0); }; }" ` @@ -192,31 +192,31 @@ describe('bind generator', () => { "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }", "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }", "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }", "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }", "(ts) => { const t0 = ts[0]; return (v0) => { - __c(t0, v0); + __compose(t0, v0); }; }", "null", @@ -237,13 +237,13 @@ describe('render generator', () => { test('simple', ({ compile, expect }) => { const code = compile(`name =>

    {name}

    `); - expect(code).toMatchInlineSnapshot(`"__renderer("15aa2705", gdb407f11, b6b86b273, false, \`

    \`)"`); + expect(code).toMatchInlineSnapshot(`"__render("15aa2705", gdb407f11, b6b86b273, false, \`

    \`)"`); }); test('static', ({ compile, expect }) => { const code = compile(`() =>

    static

    `); - expect(code).toMatchInlineSnapshot(`"__renderer("a84dfd44", null, null, false, \`

    static

    \`)"`); + expect(code).toMatchInlineSnapshot(`"__render("a84dfd44", null, null, false, \`

    static

    \`)"`); }); test('jsx comments are ignored', ({ compile, expect }) => { @@ -254,7 +254,7 @@ describe('render generator', () => { `); // Only one for the conditional, none for the comment - expect(code).toMatchInlineSnapshot(`"__renderer("77ff2813", g24227028, b6b86b273, false, \`
    + expect(code).toMatchInlineSnapshot(`"__render("77ff2813", g24227028, b6b86b273, false, \`
    \`)"`); @@ -268,7 +268,7 @@ describe('render generator', () => { expect(code).toMatchInlineSnapshot( ` - "__renderer("2ce4ea27", gedc11336, b8477292e, false, \`

    + "__render("2ce4ea27", gedc11336, b8477292e, false, \`

    hey !

    \`)" ` @@ -279,7 +279,7 @@ describe('render generator', () => { const template = preParse(`name =>

    {name}

    `, expect); const code = makeRenderer(template, { noContent: true }); - expect(code).toMatchInlineSnapshot(`"__renderer("15aa2705", gdb407f11, b6b86b273, false)"`); + expect(code).toMatchInlineSnapshot(`"__render("15aa2705", gdb407f11, b6b86b273, false)"`); }); @@ -298,12 +298,12 @@ describe('render generator', () => { const mapped = initial.templates.map(makeRenderer); expect(mapped).toMatchInlineSnapshot(` [ - "__renderer("191b5e03", null, null, false, \`

    loading...

    \`)", - "__renderer("15aa2705", gdb407f11, b6b86b273, false, \`

    \`)", - "__renderer("3fcf8b87", gdb407f11, b6b86b273, false, \`
    \`)", - "__renderer("2c4a6c0f", gdb407f11, b6b86b273, false, \`

    cats

    \`)", - "__renderer("fbb7e8b4", gdb407f11, b6b86b273, false, \`
  • \`)", - "__renderer("3fcf8b87", gdb407f11, b6b86b273, false, \`
    \`)", + "__render("191b5e03", null, null, false, \`

    loading...

    \`)", + "__render("15aa2705", gdb407f11, b6b86b273, false, \`

    \`)", + "__render("3fcf8b87", gdb407f11, b6b86b273, false, \`
    \`)", + "__render("2c4a6c0f", gdb407f11, b6b86b273, false, \`

    cats

    \`)", + "__render("fbb7e8b4", gdb407f11, b6b86b273, false, \`
  • \`)", + "__render("3fcf8b87", gdb407f11, b6b86b273, false, \`
    \`)", ] `); }); diff --git a/packages/thoth/vite/index.js b/packages/thoth/vite/index.js index 28ae0dc4..2f5ede42 100644 --- a/packages/thoth/vite/index.js +++ b/packages/thoth/vite/index.js @@ -97,11 +97,11 @@ export default function azothPlugin(options) { function loadBindModule([id]) { // TODO: conditionally import based on what was used in templates - return `import { __c, __cC } from 'azoth/runtime';\nexport const b${id} = ${makeBind(byBind.get(id))};`; + return `import { __compose, __composeComponent } from 'azoth/runtime';\nexport const b${id} = ${makeBind(byBind.get(id))};`; } function loadTemplateModule(ids, isBuild) { - const moduleImports = [`import { __renderer } from 'azoth/runtime';\n`]; + const moduleImports = [`import { __render } from 'azoth/runtime';\n`]; const targetGenerators = new Set(); const bindGenerators = new Set(); diff --git a/packages/valhalla/keyed-list.test.tsx b/packages/valhalla/keyed-list.test.tsx index 2e96d4cc..cdffeb63 100644 --- a/packages/valhalla/keyed-list.test.tsx +++ b/packages/valhalla/keyed-list.test.tsx @@ -17,7 +17,7 @@ * reconcile-by-diff. `update(key, data)` rebinds that row's node IN PLACE * (its own per-row rerenderer — the Q3 contract this file also covers). * - * Provisional: module home (`@azothjs/maya/blocks`) and the JSX form + * Provisional: module home (`@azothjs/maya/lists`) and the JSX form * `` (needs an IntrinsicElements declaration — the next * author-first constraint) are TBD. This file creates via * document.createElement to isolate the authoring stance from JSX typing. @@ -28,7 +28,7 @@ * (unfixed in vitest 4.x; see CLAUDE.md). */ import { describe, test } from 'vitest'; -import { KeyedUList, KeyedOList, KeyedTable } from '@azothjs/maya/blocks'; +import { KeyedUList, KeyedOList, KeyedTable } from '@azothjs/maya/lists'; import { rerenderer } from '@azothjs/maya/renderer'; type Pet = { id: number; name: string };