@zenithbuild/core 1.2.0 → 1.2.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.
|
@@ -57,11 +57,6 @@ function lowerNode(
|
|
|
57
57
|
return lowerExpressionNode(node, filePath, expressions)
|
|
58
58
|
|
|
59
59
|
case 'element': {
|
|
60
|
-
// Check if this is a <for> element directive
|
|
61
|
-
if (node.tag === 'for') {
|
|
62
|
-
return lowerForElement(node, filePath, expressions)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
60
|
// Check if this is an <html-content> element directive
|
|
66
61
|
if (node.tag === 'html-content') {
|
|
67
62
|
return lowerHtmlContentElement(node, filePath, expressions)
|
|
@@ -287,95 +282,6 @@ function lowerInlineFragment(
|
|
|
287
282
|
return node
|
|
288
283
|
}
|
|
289
284
|
|
|
290
|
-
/**
|
|
291
|
-
* Lower <for> element directive to LoopFragmentNode
|
|
292
|
-
*
|
|
293
|
-
* Syntax: <for each="item" in="items">...body...</for>
|
|
294
|
-
* Or: <for each="item, index" in="items">...body...</for>
|
|
295
|
-
*
|
|
296
|
-
* This is compile-time sugar for {items.map(item => ...)}
|
|
297
|
-
*/
|
|
298
|
-
function lowerForElement(
|
|
299
|
-
node: import('../ir/types').ElementNode,
|
|
300
|
-
filePath: string,
|
|
301
|
-
expressions: ExpressionIR[]
|
|
302
|
-
): LoopFragmentNode {
|
|
303
|
-
// Extract 'each' and 'in' attributes
|
|
304
|
-
const eachAttr = node.attributes.find(a => a.name === 'each')
|
|
305
|
-
const inAttr = node.attributes.find(a => a.name === 'in')
|
|
306
|
-
|
|
307
|
-
if (!eachAttr || typeof eachAttr.value !== 'string') {
|
|
308
|
-
throw new InvariantError(
|
|
309
|
-
'ZEN001',
|
|
310
|
-
`<for> element requires an 'each' attribute specifying the item variable`,
|
|
311
|
-
'Usage: <for each="item" in="items">...body...</for>',
|
|
312
|
-
filePath,
|
|
313
|
-
node.location.line,
|
|
314
|
-
node.location.column
|
|
315
|
-
)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (!inAttr || typeof inAttr.value !== 'string') {
|
|
319
|
-
throw new InvariantError(
|
|
320
|
-
'ZEN001',
|
|
321
|
-
`<for> element requires an 'in' attribute specifying the source array`,
|
|
322
|
-
'Usage: <for each="item" in="items">...body...</for>',
|
|
323
|
-
filePath,
|
|
324
|
-
node.location.line,
|
|
325
|
-
node.location.column
|
|
326
|
-
)
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Parse item variable (may include index: "item, index" or "item, i")
|
|
330
|
-
const eachValue = eachAttr.value.trim()
|
|
331
|
-
let itemVar: string
|
|
332
|
-
let indexVar: string | undefined
|
|
333
|
-
|
|
334
|
-
if (eachValue.includes(',')) {
|
|
335
|
-
const parts = eachValue.split(',').map(p => p.trim())
|
|
336
|
-
itemVar = parts[0]!
|
|
337
|
-
indexVar = parts[1]
|
|
338
|
-
} else {
|
|
339
|
-
itemVar = eachValue
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const source = inAttr.value.trim()
|
|
343
|
-
|
|
344
|
-
// Create loop context for the body
|
|
345
|
-
const loopVariables = [itemVar]
|
|
346
|
-
if (indexVar) {
|
|
347
|
-
loopVariables.push(indexVar)
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const bodyLoopContext: LoopContext = {
|
|
351
|
-
variables: node.loopContext
|
|
352
|
-
? [...node.loopContext.variables, ...loopVariables]
|
|
353
|
-
: loopVariables,
|
|
354
|
-
mapSource: source
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Lower children with loop context
|
|
358
|
-
const body = node.children.map(child => {
|
|
359
|
-
// Recursively lower children
|
|
360
|
-
const lowered = lowerNode(child, filePath, expressions)
|
|
361
|
-
// Attach loop context to children that need it
|
|
362
|
-
if ('loopContext' in lowered) {
|
|
363
|
-
return { ...lowered, loopContext: bodyLoopContext }
|
|
364
|
-
}
|
|
365
|
-
return lowered
|
|
366
|
-
})
|
|
367
|
-
|
|
368
|
-
return {
|
|
369
|
-
type: 'loop-fragment',
|
|
370
|
-
source,
|
|
371
|
-
itemVar,
|
|
372
|
-
indexVar,
|
|
373
|
-
body,
|
|
374
|
-
location: node.location,
|
|
375
|
-
loopContext: bodyLoopContext
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
285
|
/**
|
|
380
286
|
* Lower <html-content> element directive
|
|
381
287
|
*
|
|
@@ -126,7 +126,8 @@ export function transformNode(
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
case 'loop-fragment': {
|
|
129
|
-
// Loop fragment: {items.map(item => <li>...</li>)}
|
|
129
|
+
// Loop fragment: {items.map(item => <li>...</li>)}
|
|
130
|
+
// .map() is compile-time sugar, lowered to LoopFragmentNode
|
|
130
131
|
// For SSR/SSG, we render one instance of the body as a template
|
|
131
132
|
// The runtime will hydrate and expand this for each actual item
|
|
132
133
|
const loopNode = node as LoopFragmentNode
|