Skip to content

Commit aff268f

Browse files
committed
fix code gen issues due to new BIND CHILD and COMPONENT enums both need compose
1 parent 64b81d4 commit aff268f

File tree

14 files changed

+277
-192
lines changed

14 files changed

+277
-192
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"eslint": "^8.57.0",
2727
"globals": "^14.0.0",
2828
"happy-dom": "^13.10.1",
29-
"vite": "^5.2.6",
29+
"vite": "^5.2.7",
3030
"vite-plugin-inspect": "^0.8.3",
3131
"vitest": "^1.4.0"
3232
},

packages/thoth/transform/template-generators.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ export function makeTargets(template) {
66
const { length: elLength } = boundElements;
77
if(isStatic) return 'null';
88

9-
const values = bindings.map(({ element, type, index }) => {
10-
const { isRoot, queryIndex } = element;
11-
const target = isRoot ? 'r' : `${'t'}[${queryIndex}]`;
12-
return type === BIND.CHILD ? `${target}.childNodes[${index}]` : target;
13-
});
9+
const values = bindings
10+
.map(({ element, type, index }) => {
11+
const { isRoot, queryIndex } = element;
12+
const target = isRoot ? 'r' : `${'t'}[${queryIndex}]`;
13+
const isComposed = type === BIND.CHILD || type === BIND.COMPONENT;
14+
return isComposed ? `${target}.childNodes[${index}]` : target;
15+
})
16+
.join(',');
1417

15-
return elLength ? `(r,t) => [${values.join()}]` : `r => [${values.join()}]`;
18+
return elLength ? `(r,t) => [${values}]` : `r => [${values}]`;
1619
}
1720

1821
export function makeRenderer({ isEmpty, id, targetKey, tMap, bindKey, bMap, isDomFragment, html }, options) {
@@ -22,7 +25,7 @@ export function makeRenderer({ isEmpty, id, targetKey, tMap, bindKey, bMap, isDo
2225
const target = targetKey ? `g${targetKey}` : `null`;
2326
const bind = bindKey ? `b${bindKey}` : `null`;
2427
let renderer = `__renderer(`;
25-
renderer += `"${id}", /* ${JSON.stringify(tMap)} */ ${target}, /* ${JSON.stringify(bMap)} */ ${bind}, ${isDomFragment}`;
28+
renderer += `"${id}", ${target}, ${bind}, ${isDomFragment}`;
2629
if(content) renderer += ', `' + `${html}` + '`';
2730
renderer += `)`;
2831

packages/thoth/transform/template-generators.test.js

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,50 @@ import { makeTargets, makeRenderer, makeBind } from './template-generators.js';
33
import { parse, generate as _generate } from '../compiler.js';
44
import { describe, test, beforeEach } from 'vitest';
55

6-
function preParse(input, expect) {
6+
function preParse(input) {
7+
return preParseAll(input)[0];
8+
}
9+
10+
function preParseAll(input) {
711
const ast = parse(input);
812
const initial = _generate(ast);
9-
const template = initial.templates[0];
10-
expect(template.node.type).toBe('JSXElement');
11-
return template;
13+
return initial.templates;
1214
}
1315

1416
describe('targets generator', () => {
1517

1618
beforeEach(context => {
1719
context.compile = code => {
18-
const template = preParse(code, context.expect);
20+
const template = preParse(code);
1921
return makeTargets(template);
2022
};
23+
context.compileAll = code => {
24+
return preParseAll(code).map(makeTargets);
25+
};
2126
});
2227

23-
test('simple', ({ compile, expect }) => {
24-
const code = compile(`name => <p>{name}</p>`);
25-
expect(code).toMatchInlineSnapshot(`"r => [r.childNodes[0]]"`);
28+
test('composes', ({ compile, expect }) => {
29+
const code = compile(`name => <p>hello {name} <Display/></p>`);
30+
expect(code).toMatchInlineSnapshot(
31+
`"r => [r.childNodes[1],r.childNodes[3]]"`
32+
);
2633
});
2734

28-
test('edge case', ({ expect }) => {
29-
const input = `
35+
test('fragment composes', ({ compile, expect }) => {
36+
const code = compile(`name => <><p>hello</p><Display/></>`);
37+
expect(code).toMatchInlineSnapshot(`"r => [r.childNodes[1]]"`);
38+
});
39+
40+
test('edge case', ({ compileAll, expect }) => {
41+
const code = compileAll(`
3042
export const Loading = () => <p>loading...</p>;
3143
export const Cat = ({ name }) => <p>{name}</p>;
3244
export const CatList = cats => <ul>{cats.map(Cat)}</ul>;
3345
export const CatCount = cats => <p>{cats.length} cats</p>;
3446
export const CatName = (name) => <li>{name}</li>;
3547
export const CatNames = cats => <ul>{cats.map(CatName)}</ul>;
36-
`;
37-
38-
const ast = parse(input);
39-
const initial = _generate(ast);
40-
const mapped = initial.templates.map(makeTargets);
41-
expect(mapped).toMatchInlineSnapshot(`
48+
`);
49+
expect(code).toMatchInlineSnapshot(`
4250
[
4351
"null",
4452
"r => [r.childNodes[0]]",

packages/vite-plugin/index.test.js

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,38 @@
11
import { test } from 'vitest';
22
import plugin from './index.js';
33

4-
const [jsx] = plugin();
4+
function run(code) {
5+
const [jsx] = plugin();
6+
const out = jsx.transform(code, 'test.jsx');
7+
const { bindings, node, bMap, tMap, boundElements, ...rest } = [...jsx.templates.values()][0];
8+
const template = {
9+
bMap: JSON.stringify(bMap),
10+
tMap: JSON.stringify(tMap),
11+
...rest
12+
};
13+
// jsx.load()
14+
15+
return { code: out.code, template };
16+
}
517

618
test('basic plugin', ({ expect }) => {
7-
const code = `<div>
19+
const { code, template } = run`<div>
820
<p title="static" className={status} {...spread}>
921
Hello {world}
1022
</p>
1123
<Component prop1={prop1} {...obj} option="static">
1224
<p>{name} slottable!</p>
1325
</Component>
1426
</div>`;
15-
const out = jsx.transform(code, 'test.jsx');
16-
expect(out.code)
27+
28+
expect(code)
1729
.toMatchInlineSnapshot(`
1830
"import { tf89f8a98, tb550bd5b } from 'virtual:azoth-templates?id=f89f8a98&id=b550bd5b';
1931
2032
tf89f8a98(status,spread,world,[Component, { prop1: prop1, ...obj, option: "static", }, tb550bd5b(name)]);
2133
"
2234
`);
23-
const { bindings, node, bMap, tMap, boundElements, ...rest } = [...jsx.templates.values()][0];
24-
const template = {
25-
bMap: JSON.stringify(bMap),
26-
tMap: JSON.stringify(tMap),
27-
...rest
28-
};
35+
2936
expect(template).toMatchInlineSnapshot(`
3037
{
3138
"bMap": "[0,4,1,2]",
@@ -48,4 +55,39 @@ test('basic plugin', ({ expect }) => {
4855
"targetKey": "88185d12",
4956
}
5057
`);
58+
});
59+
60+
test('fragment w/ component', ({ expect }) => {
61+
const { code, template } = run`<>
62+
<h1>Hello Sandbox</h1>
63+
<div>
64+
<Title />
65+
</div>
66+
</>`;
67+
68+
expect(code).toMatchInlineSnapshot(`
69+
"import { tafdcadae } from 'virtual:azoth-templates?id=afdcadae';
70+
71+
tafdcadae([Title]);
72+
"
73+
`);
74+
75+
expect(template).toMatchInlineSnapshot(`
76+
{
77+
"bMap": "[2]",
78+
"bindKey": "dbc1b4c9",
79+
"html": "<h1>Hello Sandbox</h1>
80+
<div data-bind>
81+
<!--0-->
82+
</div>",
83+
"id": "afdcadae",
84+
"imports": [],
85+
"isDomFragment": true,
86+
"isEmpty": false,
87+
"isStatic": false,
88+
"propertyNames": null,
89+
"tMap": "[[0,1]]",
90+
"targetKey": "6e340b9c",
91+
}
92+
`);
5193
});

0 commit comments

Comments
 (0)