@vesk/compiler 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/acorn-ts-plugin/index.d.ts +482 -0
- package/dist/acorn-ts-plugin/index.d.ts.map +1 -0
- package/dist/acorn-ts-plugin/index.js +5028 -0
- package/dist/actions.d.ts +22 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +167 -0
- package/dist/api-routes.d.ts +30 -0
- package/dist/api-routes.d.ts.map +1 -0
- package/dist/api-routes.js +350 -0
- package/dist/client-codegen.d.ts +19 -0
- package/dist/client-codegen.d.ts.map +1 -0
- package/dist/client-codegen.js +1523 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +106 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +210 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/ir-generator.d.ts +10 -0
- package/dist/ir-generator.d.ts.map +1 -0
- package/dist/ir-generator.js +1062 -0
- package/dist/ir.d.ts +160 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +219 -0
- package/dist/middleware.d.ts +15 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +183 -0
- package/dist/package.json +15 -0
- package/dist/parser.d.ts +38 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +242 -0
- package/dist/router.d.ts +31 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +451 -0
- package/dist/scan.d.ts +106 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +438 -0
- package/dist/server-codegen.d.ts +5 -0
- package/dist/server-codegen.d.ts.map +1 -0
- package/dist/server-codegen.js +4 -0
- package/dist/server-cookies.d.ts +2 -0
- package/dist/server-cookies.d.ts.map +1 -0
- package/dist/server-cookies.js +15 -0
- package/dist/server-head.d.ts +10 -0
- package/dist/server-head.d.ts.map +1 -0
- package/dist/server-head.js +289 -0
- package/dist/server-jsgen.d.ts +6 -0
- package/dist/server-jsgen.d.ts.map +1 -0
- package/dist/server-jsgen.js +446 -0
- package/dist/server-render.d.ts +16 -0
- package/dist/server-render.d.ts.map +1 -0
- package/dist/server-render.js +397 -0
- package/dist/server-utils.d.ts +93 -0
- package/dist/server-utils.d.ts.map +1 -0
- package/dist/server-utils.js +747 -0
- package/dist/ssr-store.d.ts +4 -0
- package/dist/ssr-store.d.ts.map +1 -0
- package/dist/ssr-store.js +29 -0
- package/dist/strip-ts.d.ts +25 -0
- package/dist/strip-ts.d.ts.map +1 -0
- package/dist/strip-ts.js +171 -0
- package/dist/tokens.d.ts +50 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +334 -0
- package/dist/typecheck.d.ts +19 -0
- package/dist/typecheck.d.ts.map +1 -0
- package/dist/typecheck.js +365 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/vesk-plugin.d.ts +53 -0
- package/dist/vesk-plugin.d.ts.map +1 -0
- package/dist/vesk-plugin.js +413 -0
- package/dist/vsk-imports.d.ts +30 -0
- package/dist/vsk-imports.d.ts.map +1 -0
- package/dist/vsk-imports.js +141 -0
- package/dist/vsk-tsx.d.ts +3 -0
- package/dist/vsk-tsx.d.ts.map +1 -0
- package/dist/vsk-tsx.js +604 -0
- package/package.json +52 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, WhileLoop, SwitchBlock, TryCatch, ForLoop, TrackDecl, RuntimeStatement, ComponentRef, ComponentCall, ServerBlock, ClientBlock, HeadBlock, SlotNode, } from '@vesk/compiler/src/ir';
|
|
2
|
+
import { isStaticIR, collectTrackedNames, transformTracked, semicolonizeStatement } from '@vesk/compiler/src/client-codegen';
|
|
3
|
+
import { unwrapTrackCall, stripTrackGeneric, hasTopLevelComma, skipWhitespace, findBalancedEnd, startsWithIdentifier } from '@vesk/compiler/src/scan';
|
|
4
|
+
import { escapeHtml, indent, exprJS, extractTopLevelNames, extractRuntimeNames, buildParamInit, __vskHydrate, __vskImportedNames, setVskImportedNames, setVskForceClaim, takeVskForceClaim, nextVskId, } from '@vesk/compiler/src/server-utils';
|
|
5
|
+
export function irNodeToJS(node, importedNames, isAsync = false, tracked) {
|
|
6
|
+
importedNames = importedNames || __vskImportedNames;
|
|
7
|
+
if (node instanceof StaticNode)
|
|
8
|
+
return staticNodeToJS(node, isAsync, tracked);
|
|
9
|
+
if (node instanceof TextNode) {
|
|
10
|
+
if (!node.value)
|
|
11
|
+
return '';
|
|
12
|
+
return `__out.push(${JSON.stringify(node.value)});`;
|
|
13
|
+
}
|
|
14
|
+
if (node instanceof DynamicBinding)
|
|
15
|
+
return dynamicBindingToJS(node, tracked);
|
|
16
|
+
if (node instanceof OpaqueDynamicRegion)
|
|
17
|
+
return opaqueRegionToJS(node, isAsync, tracked);
|
|
18
|
+
if (node instanceof MapRegion)
|
|
19
|
+
return mapRegionToJS(node, isAsync, tracked);
|
|
20
|
+
if (node instanceof WhileLoop)
|
|
21
|
+
return whileLoopToJS(node, isAsync, tracked);
|
|
22
|
+
if (node instanceof SwitchBlock)
|
|
23
|
+
return switchBlockToJS(node, isAsync, tracked);
|
|
24
|
+
if (node instanceof TryCatch)
|
|
25
|
+
return tryCatchToJS(node, isAsync, tracked);
|
|
26
|
+
if (node instanceof ComponentRef)
|
|
27
|
+
return '';
|
|
28
|
+
if (node instanceof ComponentCall)
|
|
29
|
+
return componentCallToJS(node, importedNames, isAsync, tracked);
|
|
30
|
+
if (node instanceof ServerBlock) {
|
|
31
|
+
const lines = [];
|
|
32
|
+
for (const n of node.children) {
|
|
33
|
+
const code = irNodeToJS(n, importedNames, isAsync, tracked);
|
|
34
|
+
if (code)
|
|
35
|
+
lines.push(code);
|
|
36
|
+
}
|
|
37
|
+
return lines.join('\n');
|
|
38
|
+
}
|
|
39
|
+
if (node instanceof ClientBlock)
|
|
40
|
+
return '';
|
|
41
|
+
if (node instanceof HeadBlock)
|
|
42
|
+
return '';
|
|
43
|
+
if (node instanceof ForLoop)
|
|
44
|
+
return forLoopToJS(node, isAsync, tracked);
|
|
45
|
+
if (node instanceof TrackDecl) {
|
|
46
|
+
const cellName = node.rawName || node.name;
|
|
47
|
+
const unwrapped = unwrapTrackCall(node.init);
|
|
48
|
+
const inner = hasTopLevelComma(unwrapped) ? stripTrackGeneric(node.init) : unwrapped;
|
|
49
|
+
const key = JSON.stringify(`${compKey(node)}:${node.name}`);
|
|
50
|
+
return [
|
|
51
|
+
`const ${cellName} = (() => {`,
|
|
52
|
+
` const __s = globalThis.__vsk_ssr_cells || (globalThis.__vsk_ssr_cells = new Map());`,
|
|
53
|
+
` const __k = __tk + ${key};`,
|
|
54
|
+
` if (__s.has(__k)) return __s.get(__k);`,
|
|
55
|
+
` let __c;`,
|
|
56
|
+
` try { const __v = (${inner}); __c = track(typeof __v === 'function' ? __v() : __v); } catch (e) { __c = track(void 0); }`,
|
|
57
|
+
` __s.set(__k, __c);`,
|
|
58
|
+
` return __c;`,
|
|
59
|
+
`})();`,
|
|
60
|
+
].join('\n');
|
|
61
|
+
}
|
|
62
|
+
if (node instanceof RuntimeStatement)
|
|
63
|
+
return semicolonizeStatement(transformTracked(node, tracked || new Map()));
|
|
64
|
+
if (node instanceof SlotNode)
|
|
65
|
+
return `__out.push(props.children || '');`;
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
let __currentCompName = '';
|
|
69
|
+
function compKey(_node) {
|
|
70
|
+
return __currentCompName || 'comp';
|
|
71
|
+
}
|
|
72
|
+
function isEvent(target) {
|
|
73
|
+
return !!target && target.startsWith('on') && target.length > 2;
|
|
74
|
+
}
|
|
75
|
+
function exprJSX(node, tracked) {
|
|
76
|
+
return exprJS(transformTracked(node, tracked || new Map()));
|
|
77
|
+
}
|
|
78
|
+
function staticNodeToJS(node, isAsync = false, tracked) {
|
|
79
|
+
const lines = [];
|
|
80
|
+
const dynAttrTargets = new Set();
|
|
81
|
+
const dynAttrOrder = [];
|
|
82
|
+
for (const child of node.children) {
|
|
83
|
+
if (child instanceof DynamicBinding && child.kind === 'attribute' && child.target !== null && child.target !== 'ref') {
|
|
84
|
+
if (isEvent(child.target))
|
|
85
|
+
continue;
|
|
86
|
+
dynAttrTargets.add(child.target);
|
|
87
|
+
dynAttrOrder.push(child.target);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const hasDynamicAttrs = dynAttrTargets.size > 0;
|
|
91
|
+
let openTag = `<${node.tag}`;
|
|
92
|
+
const forceClaim = takeVskForceClaim();
|
|
93
|
+
const subtreeNeedsJS = __vskHydrate && (forceClaim || !isStaticIR(node.children));
|
|
94
|
+
if (subtreeNeedsJS) {
|
|
95
|
+
lines.push(`__out.push('<!--vsk-->');`);
|
|
96
|
+
}
|
|
97
|
+
for (const attr of node.attributes) {
|
|
98
|
+
if (isEvent(attr.name))
|
|
99
|
+
continue;
|
|
100
|
+
if (dynAttrTargets.has(attr.name))
|
|
101
|
+
continue;
|
|
102
|
+
if (attr.value === '') {
|
|
103
|
+
openTag += ` ${attr.name}`;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
openTag += ` ${attr.name}="${escapeHtml(attr.value)}"`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (const target of dynAttrOrder) {
|
|
110
|
+
openTag += ` ${target}=""`;
|
|
111
|
+
}
|
|
112
|
+
if (node.selfClosing) {
|
|
113
|
+
let tag = openTag + ' />';
|
|
114
|
+
if (hasDynamicAttrs) {
|
|
115
|
+
let expr = JSON.stringify(tag);
|
|
116
|
+
for (const child of node.children) {
|
|
117
|
+
if (child instanceof DynamicBinding && child.kind === 'attribute' && child.target !== 'ref' && !isEvent(child.target)) {
|
|
118
|
+
const val = `__escape(String(${exprJSX(child.expression, tracked)}))`;
|
|
119
|
+
expr = `${expr}.replace(${JSON.stringify(' ' + child.target + '=""')}, ' ' + ${JSON.stringify(child.target)} + '=\"' + ${val} + '\"')`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
lines.push(`__out.push(${expr});`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
lines.push(`__out.push(${JSON.stringify(tag)});`);
|
|
126
|
+
}
|
|
127
|
+
return lines.join('\n');
|
|
128
|
+
}
|
|
129
|
+
const childNodes = node.children.filter((c) => !(c instanceof DynamicBinding && c.kind === 'attribute' && c.target !== 'ref'));
|
|
130
|
+
if (hasDynamicAttrs) {
|
|
131
|
+
let expr = JSON.stringify(openTag);
|
|
132
|
+
for (const child of node.children) {
|
|
133
|
+
if (child instanceof DynamicBinding && child.kind === 'attribute' && child.target !== 'ref' && !isEvent(child.target)) {
|
|
134
|
+
const val = `__escape(String(${exprJSX(child.expression, tracked)}))`;
|
|
135
|
+
expr = `${expr}.replace(${JSON.stringify(' ' + child.target + '=""')}, ' ' + ${JSON.stringify(child.target)} + '=\"' + ${val} + '\"')`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
lines.push(`__out.push(${expr});`);
|
|
139
|
+
lines.push(`__out.push('>');`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
lines.push(`__out.push(${JSON.stringify(openTag + '>')});`);
|
|
143
|
+
}
|
|
144
|
+
for (const child of childNodes) {
|
|
145
|
+
const code = irNodeToJS(child, null, isAsync, tracked);
|
|
146
|
+
if (code)
|
|
147
|
+
lines.push(code);
|
|
148
|
+
}
|
|
149
|
+
lines.push(`__out.push(${JSON.stringify('</' + node.tag + '>')});`);
|
|
150
|
+
return lines.join('\n');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Returns the inner expression of a whole `raw(<expr>)` binding, or `null`
|
|
154
|
+
* when `raw` is not a complete `raw(...)` call.
|
|
155
|
+
*/
|
|
156
|
+
function extractRawInner(raw) {
|
|
157
|
+
if (!startsWithIdentifier(raw, 'raw'))
|
|
158
|
+
return null;
|
|
159
|
+
let i = skipWhitespace(raw, 3);
|
|
160
|
+
if (raw[i] !== '(')
|
|
161
|
+
return null;
|
|
162
|
+
const end = findBalancedEnd(raw, i);
|
|
163
|
+
if (skipWhitespace(raw, end + 1) !== raw.length)
|
|
164
|
+
return null;
|
|
165
|
+
return raw.slice(i + 1, end);
|
|
166
|
+
}
|
|
167
|
+
function dynamicBindingToJS(node, tracked) {
|
|
168
|
+
if (node.kind === 'attribute')
|
|
169
|
+
return '';
|
|
170
|
+
const raw = node.expression.raw;
|
|
171
|
+
const inner = extractRawInner(raw);
|
|
172
|
+
if (inner !== null) {
|
|
173
|
+
const innerAst = node.expression.ast?.arguments?.[0] ?? null;
|
|
174
|
+
return `{ const __v = ${exprJSX({ raw: inner, ast: innerAst }, tracked)}; if (__v != null) __out.push(typeof __v === 'boolean' ? 'true' : String(__v)); }`;
|
|
175
|
+
}
|
|
176
|
+
return `{ const __v = ${exprJSX(node.expression, tracked)}; if (__v != null) __out.push(typeof __v === 'boolean' ? (__v ? 'true' : '') : __escape(String(__v))); }`;
|
|
177
|
+
}
|
|
178
|
+
function opaqueRegionToJS(node, isAsync = false, tracked) {
|
|
179
|
+
const lines = [];
|
|
180
|
+
const cond = exprJSX(node.condition, tracked);
|
|
181
|
+
lines.push(`if (${cond}) {`);
|
|
182
|
+
for (const n of node.consequentNodes) {
|
|
183
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
184
|
+
if (code)
|
|
185
|
+
lines.push(indent(code));
|
|
186
|
+
}
|
|
187
|
+
if (node.alternateNodes.length > 0) {
|
|
188
|
+
lines.push(`} else {`);
|
|
189
|
+
for (const n of node.alternateNodes) {
|
|
190
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
191
|
+
if (code)
|
|
192
|
+
lines.push(indent(code));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
lines.push(`}`);
|
|
196
|
+
return lines.join('\n');
|
|
197
|
+
}
|
|
198
|
+
function mapRegionToJS(node, isAsync = false, tracked) {
|
|
199
|
+
const lines = [];
|
|
200
|
+
const arr = exprJSX(node.expression, tracked);
|
|
201
|
+
const item = node.itemVariable;
|
|
202
|
+
const hasAlternate = node.alternateNodes.length > 0;
|
|
203
|
+
const arrVar = hasAlternate ? `__a${nextVskId()}` : null;
|
|
204
|
+
if (hasAlternate) {
|
|
205
|
+
lines.push(`const ${arrVar} = ${arr};`);
|
|
206
|
+
lines.push(`if (${arrVar} == null || ${arrVar}.length === 0) {`);
|
|
207
|
+
for (const n of node.alternateNodes) {
|
|
208
|
+
setVskForceClaim(true);
|
|
209
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
210
|
+
if (code)
|
|
211
|
+
lines.push(indent(code));
|
|
212
|
+
}
|
|
213
|
+
setVskForceClaim(false);
|
|
214
|
+
lines.push(`} else {`);
|
|
215
|
+
}
|
|
216
|
+
const loopArr = arrVar || arr;
|
|
217
|
+
if (node.indexVariable) {
|
|
218
|
+
lines.push('let __i = 0;');
|
|
219
|
+
lines.push(`for (const ${item} of ${loopArr}) {`);
|
|
220
|
+
lines.push(indent(`const ${node.indexVariable} = __i;`));
|
|
221
|
+
for (const n of node.bodyTemplate) {
|
|
222
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
223
|
+
if (code)
|
|
224
|
+
lines.push(indent(code));
|
|
225
|
+
}
|
|
226
|
+
lines.push(indent('__i++;'));
|
|
227
|
+
lines.push(`}`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
lines.push(`for (const ${item} of ${loopArr}) {`);
|
|
231
|
+
for (const n of node.bodyTemplate) {
|
|
232
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
233
|
+
if (code)
|
|
234
|
+
lines.push(indent(code));
|
|
235
|
+
}
|
|
236
|
+
lines.push(`}`);
|
|
237
|
+
}
|
|
238
|
+
if (hasAlternate) {
|
|
239
|
+
lines.push(`}`);
|
|
240
|
+
}
|
|
241
|
+
return lines.join('\n');
|
|
242
|
+
}
|
|
243
|
+
function whileLoopToJS(node, isAsync = false, tracked) {
|
|
244
|
+
const lines = [];
|
|
245
|
+
if (node.isDoWhile) {
|
|
246
|
+
lines.push(`do {`);
|
|
247
|
+
for (const n of node.bodyTemplate) {
|
|
248
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
249
|
+
if (code)
|
|
250
|
+
lines.push(indent(code));
|
|
251
|
+
}
|
|
252
|
+
lines.push(`} while (${exprJSX(node.condition, tracked)});`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
lines.push(`while (${exprJSX(node.condition, tracked)}) {`);
|
|
256
|
+
for (const n of node.bodyTemplate) {
|
|
257
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
258
|
+
if (code)
|
|
259
|
+
lines.push(indent(code));
|
|
260
|
+
}
|
|
261
|
+
lines.push(`}`);
|
|
262
|
+
}
|
|
263
|
+
return lines.join('\n');
|
|
264
|
+
}
|
|
265
|
+
function switchBlockToJS(node, isAsync = false, tracked) {
|
|
266
|
+
const lines = [];
|
|
267
|
+
lines.push(`switch (${exprJSX(node.discriminant, tracked)}) {`);
|
|
268
|
+
for (const c of node.cases) {
|
|
269
|
+
if (c.test) {
|
|
270
|
+
lines.push(`case ${exprJSX(c.test, tracked)}:`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
lines.push(`default:`);
|
|
274
|
+
}
|
|
275
|
+
for (const n of c.body) {
|
|
276
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
277
|
+
if (code)
|
|
278
|
+
lines.push(indent(code, 2));
|
|
279
|
+
}
|
|
280
|
+
lines.push(indent('break;', 2));
|
|
281
|
+
}
|
|
282
|
+
lines.push(`}`);
|
|
283
|
+
return lines.join('\n');
|
|
284
|
+
}
|
|
285
|
+
function tryCatchToJS(node, isAsync = false, tracked) {
|
|
286
|
+
const lines = [];
|
|
287
|
+
const catchParam = node.catchParamName || '__e';
|
|
288
|
+
lines.push(`try {`);
|
|
289
|
+
for (const n of node.bodyTemplate) {
|
|
290
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
291
|
+
if (code)
|
|
292
|
+
lines.push(indent(code));
|
|
293
|
+
}
|
|
294
|
+
if (node.catchBody.length > 0) {
|
|
295
|
+
lines.push(`} catch (${catchParam}) {`);
|
|
296
|
+
for (const n of node.catchBody) {
|
|
297
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
298
|
+
if (code)
|
|
299
|
+
lines.push(indent(code));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
lines.push(`}`);
|
|
303
|
+
return lines.join('\n');
|
|
304
|
+
}
|
|
305
|
+
function forLoopToJS(node, isAsync = false, tracked) {
|
|
306
|
+
const lines = [];
|
|
307
|
+
if (node.kind === 'for-in') {
|
|
308
|
+
const arr = exprJSX(node.condition, tracked);
|
|
309
|
+
lines.push(`for (${node.init} of (Array.isArray(${arr}) ? ${arr} : (${arr} == null ? [] : Object.keys(${arr})))) {`);
|
|
310
|
+
for (const n of node.bodyTemplate) {
|
|
311
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
312
|
+
if (code)
|
|
313
|
+
lines.push(indent(code));
|
|
314
|
+
}
|
|
315
|
+
lines.push(`}`);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
if (node.init)
|
|
319
|
+
lines.push(`${node.init}`);
|
|
320
|
+
lines.push(`while (${exprJSX(node.condition, tracked)}) {`);
|
|
321
|
+
for (const n of node.bodyTemplate) {
|
|
322
|
+
const code = irNodeToJS(n, null, isAsync, tracked);
|
|
323
|
+
if (code)
|
|
324
|
+
lines.push(indent(code));
|
|
325
|
+
}
|
|
326
|
+
if (node.update)
|
|
327
|
+
lines.push(indent(`${node.update}`));
|
|
328
|
+
lines.push(`}`);
|
|
329
|
+
}
|
|
330
|
+
return lines.join('\n');
|
|
331
|
+
}
|
|
332
|
+
function componentCallToJS(node, importedNames, isAsync = false, tracked) {
|
|
333
|
+
const propsEntries = node.props.map((p) => {
|
|
334
|
+
if (typeof p.value === 'string')
|
|
335
|
+
return `${JSON.stringify(p.name)}: ${JSON.stringify(p.value)}`;
|
|
336
|
+
return `${JSON.stringify(p.name)}: ${exprJSX(p.value, tracked)}`;
|
|
337
|
+
});
|
|
338
|
+
for (const sp of node.spreadProps) {
|
|
339
|
+
propsEntries.push(`...${exprJSX(sp, tracked)}`);
|
|
340
|
+
}
|
|
341
|
+
const lines = [];
|
|
342
|
+
if (node.children.length > 0) {
|
|
343
|
+
const childLines = [];
|
|
344
|
+
for (const child of node.children) {
|
|
345
|
+
const code = irNodeToJS(child, importedNames, isAsync, tracked);
|
|
346
|
+
if (code)
|
|
347
|
+
childLines.push(code);
|
|
348
|
+
}
|
|
349
|
+
if (childLines.length > 0) {
|
|
350
|
+
const childrenVar = `__ch${nextVskId()}`;
|
|
351
|
+
propsEntries.push(`children: ${childrenVar}`);
|
|
352
|
+
lines.push(`const ${childrenVar} = ${isAsync ? 'await (async ' : '('}() => {`);
|
|
353
|
+
lines.push(`const __out = [];`);
|
|
354
|
+
lines.push(indent(childLines.join('\n')));
|
|
355
|
+
lines.push(`return __out.join(''); })();`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const propsObj = `{ ${propsEntries.join(', ')} }`;
|
|
359
|
+
const compName = node.componentName;
|
|
360
|
+
const isImported = importedNames && importedNames.has(compName);
|
|
361
|
+
const callee = isImported ? compName : `__registry.get(${JSON.stringify(compName)})`;
|
|
362
|
+
const awaitKw = isAsync ? 'await ' : '';
|
|
363
|
+
if (__vskHydrate) {
|
|
364
|
+
lines.push(`__out.push('<!--vsk--><div>' + (${awaitKw}${callee}(${propsObj}, __registry, __vesk) || '') + '</div>');`);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
lines.push(`__out.push(${awaitKw}${callee}(${propsObj}, __registry, __vesk) || '');`);
|
|
368
|
+
}
|
|
369
|
+
return lines.join('\n');
|
|
370
|
+
}
|
|
371
|
+
export function generateFunctionBody(comp, importedNames) {
|
|
372
|
+
const tracked = collectTrackedNames(comp.body);
|
|
373
|
+
const asyncMode = comp.isAsync || comp.ssrAwait;
|
|
374
|
+
__currentCompName = comp.name;
|
|
375
|
+
const lines = [];
|
|
376
|
+
lines.push(`const __sa = (__vesk && __vesk.setActiveComponent) || ((c) => { globalThis.__vesk_ctx = c; });`);
|
|
377
|
+
lines.push(`const __ga = (__vesk && __vesk.getActiveComponent) || (() => globalThis.__vesk_ctx);`);
|
|
378
|
+
lines.push(`const __prev = __ga();`);
|
|
379
|
+
lines.push(`__sa({ c: null, p: __prev });`);
|
|
380
|
+
lines.push(`try {`);
|
|
381
|
+
lines.push(`const __escape = (s) => String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\x22/g,'"');`);
|
|
382
|
+
lines.push(`const raw = (s) => s == null ? '' : String(s);`);
|
|
383
|
+
lines.push(`const __tk = globalThis.__vsk_ssr_token || '';`);
|
|
384
|
+
if (asyncMode) {
|
|
385
|
+
lines.push(`const __pk = __tk ? '__vsk_ssr_promises_' + __tk : '__vsk_ssr_promises';`);
|
|
386
|
+
lines.push(`for (let __pass = 0; __pass < 3; __pass++) {`);
|
|
387
|
+
lines.push(`const __out = [];`);
|
|
388
|
+
lines.push(`const __start = (globalThis[__pk] || []).length;`);
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
lines.push(`const __out = [];`);
|
|
392
|
+
}
|
|
393
|
+
if (comp.style) {
|
|
394
|
+
lines.push(`__out.push('<style>');`);
|
|
395
|
+
lines.push(`__out.push(${JSON.stringify(comp.style)});`);
|
|
396
|
+
lines.push(`__out.push('</style>');`);
|
|
397
|
+
}
|
|
398
|
+
for (const node of comp.body) {
|
|
399
|
+
const code = irNodeToJS(node, importedNames, asyncMode, tracked);
|
|
400
|
+
if (code)
|
|
401
|
+
lines.push(code);
|
|
402
|
+
}
|
|
403
|
+
if (asyncMode) {
|
|
404
|
+
lines.push(`const __all = globalThis[__pk] || [];`);
|
|
405
|
+
lines.push(`if (__all.length <= __start) return __out.join('');`);
|
|
406
|
+
lines.push(`const __ps = __all.slice(__start);`);
|
|
407
|
+
lines.push(`globalThis[__pk] = __all.slice(0, __start);`);
|
|
408
|
+
lines.push(`await Promise.allSettled(__ps);`);
|
|
409
|
+
lines.push(`}`);
|
|
410
|
+
lines.push(`return '';`);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
lines.push(`return __out.join('');`);
|
|
414
|
+
}
|
|
415
|
+
lines.push(`} finally {`);
|
|
416
|
+
lines.push(`__sa(__prev);`);
|
|
417
|
+
lines.push(`}`);
|
|
418
|
+
__currentCompName = '';
|
|
419
|
+
return lines.join('\n');
|
|
420
|
+
}
|
|
421
|
+
export function buildComponentMap(irRoot, useSharedScope) {
|
|
422
|
+
const map = new Map();
|
|
423
|
+
const runtimeNames = extractRuntimeNames(irRoot.imports);
|
|
424
|
+
const importedNames = new Set(runtimeNames);
|
|
425
|
+
const topNames = extractTopLevelNames(irRoot.topLevelCode);
|
|
426
|
+
const hasTracked = irRoot.components.some((c) => c.body.some((n) => n instanceof TrackDecl));
|
|
427
|
+
const extraNames = hasTracked ? ['get', 'set', 'track'] : [];
|
|
428
|
+
const allNames = [...new Set([...runtimeNames, ...topNames, ...extraNames])];
|
|
429
|
+
const scopeDecl = allNames.length > 0 ? `const { ${allNames.join(', ')} } = __vesk;\n` : '';
|
|
430
|
+
setVskImportedNames(importedNames);
|
|
431
|
+
for (const comp of irRoot.components) {
|
|
432
|
+
const bodyCode = generateFunctionBody(comp, importedNames);
|
|
433
|
+
const paramInit = buildParamInit(comp.paramNames);
|
|
434
|
+
const code = `${scopeDecl}${paramInit}\n${bodyCode}`;
|
|
435
|
+
let fn;
|
|
436
|
+
if (comp.isAsync || comp.ssrAwait) {
|
|
437
|
+
fn = new Function('props', '__registry', '__vesk', `return (async () => {\n${code}\n})()`);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
fn = new Function('props', '__registry', '__vesk', code);
|
|
441
|
+
}
|
|
442
|
+
map.set(comp.name, fn);
|
|
443
|
+
}
|
|
444
|
+
setVskImportedNames(null);
|
|
445
|
+
return map;
|
|
446
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CompileFileResult, RenderPageResult, SSGResult, FullPageOptions, ExternalDataScript } from '@vesk/compiler/src/types';
|
|
2
|
+
export declare function compileFile(source: string, options?: {
|
|
3
|
+
sourcePath?: string;
|
|
4
|
+
}): CompileFileResult;
|
|
5
|
+
export declare function render(source: string, componentName: string, props?: Record<string, unknown>, registry?: Map<string, Function>, options?: Record<string, unknown>): string | Promise<string>;
|
|
6
|
+
export declare function renderPage(source: string, componentName: string, props?: Record<string, unknown>, registry?: Map<string, Function>, options?: Record<string, unknown>): RenderPageResult | Promise<RenderPageResult>;
|
|
7
|
+
export declare function ssg(source: string, componentName?: string, customProps?: Record<string, unknown>, options?: {
|
|
8
|
+
registry?: Map<string, Function>;
|
|
9
|
+
cssUrl?: string;
|
|
10
|
+
cssUrls?: string[];
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}): Promise<SSGResult>;
|
|
13
|
+
export declare function buildDataScripts(ssrProps: Record<string, unknown> | null | undefined, ssrData: Record<string, unknown>, external?: ExternalDataScript | null): string[];
|
|
14
|
+
export declare function renderFullPage(source: string, componentName: string, props?: Record<string, unknown>, registry?: Map<string, Function>, options?: FullPageOptions): Promise<string>;
|
|
15
|
+
export declare function renderPageStream(source: string, componentName: string, props?: Record<string, unknown>, registry?: Map<string, Function>, options?: FullPageOptions): AsyncGenerator<string>;
|
|
16
|
+
//# sourceMappingURL=server-render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAqB,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAcvJ,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAEhG;AA0BD,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC1B;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiE9C;AAYD,wBAAsB,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAO,GAC9G,OAAO,CAAC,SAAS,CAAC,CA8DpB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,GACnC,MAAM,EAAE,CAuBV;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoEjB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,MAAM,CAAC,CAkFxB"}
|