babel-plugin-essor 0.0.6-beta.9 → 0.0.6

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/dist/index.js CHANGED
@@ -1,9 +1,18 @@
1
1
  // ../shared/dist/essor-shared.js
2
2
  var isArray = Array.isArray;
3
+ function isString(val) {
4
+ return typeof val === "string";
5
+ }
3
6
  var noop = Function.prototype;
4
7
  function startsWith(str, searchString) {
8
+ if (!isString(str)) {
9
+ return false;
10
+ }
5
11
  return str.indexOf(searchString) === 0;
6
12
  }
13
+ var capitalizeFirstLetter = (inputString) => {
14
+ return inputString.charAt(0).toUpperCase() + inputString.slice(1);
15
+ };
7
16
 
8
17
  // src/jsx/server.ts
9
18
  import { types as t3 } from "@babel/core";
@@ -13,13 +22,14 @@ import { types as t } from "@babel/core";
13
22
  var imports = /* @__PURE__ */ new Set();
14
23
  var transformProgram = {
15
24
  enter(path, state) {
25
+ imports.clear();
16
26
  path.state = {
17
27
  h: path.scope.generateUidIdentifier("h$"),
18
- ssrtmpl: path.scope.generateUidIdentifier("ssrtmpl$"),
19
- ssr: path.scope.generateUidIdentifier("ssr$"),
28
+ renderTemplate: path.scope.generateUidIdentifier("renderTemplate$"),
20
29
  template: path.scope.generateUidIdentifier("template$"),
21
30
  useSignal: path.scope.generateUidIdentifier("signal$"),
22
31
  useComputed: path.scope.generateUidIdentifier("computed$"),
32
+ useReactive: path.scope.generateUidIdentifier("reactive$"),
23
33
  tmplDeclaration: t.variableDeclaration("const", []),
24
34
  opts: state.opts
25
35
  };
@@ -87,17 +97,73 @@ var svgTags = [
87
97
  "use"
88
98
  ];
89
99
 
90
- // src/jsx/client.ts
100
+ // src/jsx/shared.ts
91
101
  import { types as t2 } from "@babel/core";
92
- function transformJSXClient(path) {
102
+ function hasSiblingElement(path) {
103
+ const siblings = path.getAllPrevSiblings().concat(path.getAllNextSiblings());
104
+ const hasSibling = siblings.some((siblingPath) => siblingPath.isJSXElement());
105
+ return hasSibling;
106
+ }
107
+ function getAttrName(attribute) {
108
+ if (t2.isJSXIdentifier(attribute.name)) {
109
+ return attribute.name.name;
110
+ }
111
+ if (t2.isJSXNamespacedName(attribute.name)) {
112
+ return `${attribute.name.namespace.name}:${attribute.name.name.name}`;
113
+ }
114
+ throw new Error("Unsupported attribute type");
115
+ }
116
+ function getTagName(node) {
117
+ const tag = node.openingElement.name;
118
+ return jsxElementNameToString(tag);
119
+ }
120
+ function jsxElementNameToString(node) {
121
+ if (t2.isJSXMemberExpression(node)) {
122
+ return `${jsxElementNameToString(node.object)}.${jsxElementNameToString(node.property)}`;
123
+ }
124
+ if (t2.isJSXIdentifier(node) || t2.isIdentifier(node)) {
125
+ return node.name;
126
+ }
127
+ return `${node.namespace.name}:${node.name.name}`;
128
+ }
129
+ function isComponent(tagName) {
130
+ return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^A-Za-z]/.test(tagName[0]);
131
+ }
132
+ function isTextChild(path) {
133
+ if (path.isJSXExpressionContainer()) {
134
+ const expression = path.get("expression");
135
+ if (expression.isJSXText() || expression.isStringLiteral() || expression.isNumericLiteral()) {
136
+ return true;
137
+ }
138
+ }
139
+ if (path.isJSXText() || path.isStringLiteral() || path.isNullLiteral()) {
140
+ return true;
141
+ }
142
+ return false;
143
+ }
144
+ function setNodeText(path, text) {
145
+ if (path.isJSXText()) {
146
+ path.node.value = text;
147
+ }
148
+ if (path.isJSXExpressionContainer()) {
149
+ const expression = path.get("expression");
150
+ if (expression.isStringLiteral() || expression.isNumericLiteral()) {
151
+ expression.replaceWith(t2.stringLiteral(text));
152
+ }
153
+ }
154
+ }
155
+
156
+ // src/jsx/server.ts
157
+ function transformJSXService(path) {
93
158
  const result = {
94
- index: 1,
159
+ index: 0,
95
160
  isLastChild: false,
96
161
  parentIndex: 0,
97
162
  props: {},
98
- template: ""
163
+ template: []
164
+ // 修改为数组
99
165
  };
100
- transformJSXElement(path, result, true);
166
+ transformJSXServiceElement(path, result, true);
101
167
  path.replaceWith(createEssorNode(path, result));
102
168
  }
103
169
  function createEssorNode(path, result) {
@@ -105,82 +171,91 @@ function createEssorNode(path, result) {
105
171
  const state = path.state;
106
172
  let tmpl;
107
173
  if (path.isJSXElement() && isComponent(getTagName(path.node))) {
108
- tmpl = t2.identifier(getTagName(path.node));
174
+ tmpl = t3.identifier(getTagName(path.node));
109
175
  } else {
110
176
  tmpl = path.scope.generateUidIdentifier("_tmpl$");
111
- const template = t2.callExpression(state.template, [t2.stringLiteral(result.template)]);
112
- const declarator = t2.variableDeclarator(tmpl, template);
177
+ const template = t3.arrayExpression(result.template.map(t3.stringLiteral));
178
+ const declarator = t3.variableDeclarator(tmpl, template);
113
179
  state.tmplDeclaration.declarations.push(declarator);
114
- imports.add("template");
115
180
  }
116
181
  const args = [tmpl, createProps(result.props)];
117
182
  const key = result.props.key || ((_a = result.props[0]) == null ? void 0 : _a.key);
118
183
  if (key) {
119
184
  args.push(key);
120
185
  }
121
- imports.add("h");
122
- return t2.callExpression(state.h, args);
186
+ imports.add("renderTemplate");
187
+ return t3.callExpression(state.renderTemplate, args);
123
188
  }
124
189
  function createProps(props) {
125
- const toAstNode = (value) => {
190
+ const result = [];
191
+ for (const prop in props) {
192
+ let value = props[prop];
193
+ if (prop === "key") {
194
+ continue;
195
+ }
126
196
  if (Array.isArray(value)) {
127
- return t2.arrayExpression(value.map(toAstNode));
197
+ value = t3.arrayExpression(value);
128
198
  }
129
- if (value && typeof value === "object" && !t2.isNode(value)) {
130
- return createProps(value);
199
+ if (typeof value === "object" && value !== null && !t3.isNode(value)) {
200
+ value = createProps(value);
131
201
  }
132
- switch (typeof value) {
133
- case "string":
134
- return t2.stringLiteral(value);
135
- case "number":
136
- return t2.numericLiteral(value);
137
- case "boolean":
138
- return t2.booleanLiteral(value);
139
- case "undefined":
140
- return t2.tsUndefinedKeyword();
141
- case void 0:
142
- return t2.tsUndefinedKeyword();
143
- case null:
144
- return t2.nullLiteral();
145
- default:
146
- return value;
202
+ if (typeof value === "string") {
203
+ value = t3.stringLiteral(value);
147
204
  }
148
- };
149
- const result = Object.keys(props).filter((prop) => prop !== "key").map((prop) => {
150
- const value = toAstNode(props[prop]);
151
- return prop === "_$spread$" ? t2.spreadElement(value) : t2.objectProperty(t2.stringLiteral(prop), value);
152
- });
153
- return t2.objectExpression(result);
205
+ if (typeof value === "number") {
206
+ value = t3.numericLiteral(value);
207
+ }
208
+ if (typeof value === "boolean") {
209
+ value = t3.booleanLiteral(value);
210
+ }
211
+ if (value === void 0) {
212
+ value = t3.tsUndefinedKeyword();
213
+ }
214
+ if (value === null) {
215
+ value = t3.nullLiteral();
216
+ }
217
+ if (prop === "_$spread$") {
218
+ result.push(t3.spreadElement(value));
219
+ } else {
220
+ result.push(t3.objectProperty(t3.stringLiteral(prop), value));
221
+ }
222
+ }
223
+ return t3.objectExpression(result);
154
224
  }
155
- function transformJSXElement(path, result, isRoot = false) {
225
+ function transformJSXServiceElement(path, result, isRoot = false) {
156
226
  if (path.isJSXElement()) {
157
227
  const tagName = getTagName(path.node);
158
228
  const tagIsComponent = isComponent(tagName);
159
229
  const isSelfClose = !tagIsComponent && selfClosingTags.includes(tagName);
160
230
  const isSvg = svgTags.includes(tagName) && result.index === 1;
161
- const props = getAttrProps(path);
231
+ const { props, hasExpression } = getAttrProps(path);
162
232
  if (tagIsComponent) {
163
233
  if (isRoot) {
164
234
  result.props = props;
165
235
  const children = getChildren(path);
166
236
  if (children.length > 0) {
167
- const childrenGenerator = children.length === 1 ? children[0] : t2.arrayExpression(children);
237
+ const childrenGenerator = children.length === 1 ? children[0] : t3.arrayExpression(children);
168
238
  result.props.children = childrenGenerator;
169
239
  }
170
240
  } else {
171
- transformJSXClient(path);
241
+ transformJSXService(path);
172
242
  replaceChild(path.node, result);
173
243
  }
174
244
  } else {
175
245
  if (isSvg) {
176
- result.template = "<svg _svg_>";
246
+ result.template.push("<svg _svg_>");
177
247
  }
178
- result.template += `<${tagName}`;
248
+ result.template.push(`<${tagName}`);
179
249
  handleAttributes(props, result);
180
- result.template += isSelfClose ? "/>" : ">";
250
+ if (hasExpression) {
251
+ result.template.push(isSelfClose ? "/>" : ">");
252
+ result.props || (result.props = {});
253
+ } else {
254
+ result.template[result.template.length - 1] += isSelfClose ? "/>" : ">";
255
+ }
256
+ transformChildren(path, result);
181
257
  if (!isSelfClose) {
182
- transformChildren(path, result);
183
- result.template += `</${tagName}>`;
258
+ result.template.push(`</${tagName}>`);
184
259
  }
185
260
  }
186
261
  } else {
@@ -189,7 +264,7 @@ function transformJSXElement(path, result, isRoot = false) {
189
264
  }
190
265
  }
191
266
  function transformChildren(path, result) {
192
- const parentIndex = result.index;
267
+ const parentIndex = result.template.length;
193
268
  path.get("children").reduce((pre, cur) => {
194
269
  if (isValidChild(cur)) {
195
270
  const lastChild = pre.at(-1);
@@ -207,21 +282,20 @@ function transformChildren(path, result) {
207
282
  });
208
283
  }
209
284
  function transformChild(child, result) {
210
- result.index++;
211
285
  if (child.isJSXElement() || child.isJSXFragment()) {
212
- transformJSXElement(child, result, false);
286
+ transformJSXServiceElement(child, result, false);
213
287
  } else if (child.isJSXExpressionContainer()) {
214
288
  const expression = child.get("expression");
215
289
  if (expression.isStringLiteral() || expression.isNumericLiteral()) {
216
- result.template += String(expression.node.value);
290
+ result.template[result.template.length - 1] += String(expression.node.value);
217
291
  } else if (expression.isExpression()) {
218
292
  replaceChild(expression.node, result);
219
- } else if (t2.isJSXEmptyExpression(expression.node)) {
293
+ } else if (t3.isJSXEmptyExpression(expression.node)) {
220
294
  } else {
221
295
  throw new Error("Unsupported child type");
222
296
  }
223
297
  } else if (child.isJSXText()) {
224
- result.template += String(child.node.value);
298
+ result.template.push(String(child.node.value));
225
299
  } else {
226
300
  throw new Error("Unsupported child type");
227
301
  }
@@ -238,29 +312,6 @@ function getNodeText(path) {
238
312
  }
239
313
  return "";
240
314
  }
241
- function setNodeText(path, text) {
242
- if (path.isJSXText()) {
243
- path.node.value = text;
244
- }
245
- if (path.isJSXExpressionContainer()) {
246
- const expression = path.get("expression");
247
- if (expression.isStringLiteral() || expression.isNumericLiteral()) {
248
- expression.replaceWith(t2.stringLiteral(text));
249
- }
250
- }
251
- }
252
- function isTextChild(path) {
253
- if (path.isJSXExpressionContainer()) {
254
- const expression = path.get("expression");
255
- if (expression.isJSXText() || expression.isStringLiteral() || expression.isNumericLiteral()) {
256
- return true;
257
- }
258
- }
259
- if (path.isJSXText() || path.isStringLiteral() || path.isNullLiteral()) {
260
- return true;
261
- }
262
- return false;
263
- }
264
315
  function handleAttributes(props, result) {
265
316
  let klass = "";
266
317
  let style = "";
@@ -271,38 +322,20 @@ function handleAttributes(props, result) {
271
322
  delete props[prop];
272
323
  continue;
273
324
  }
274
- if (startsWith(prop, "class:")) {
275
- if (value === true) {
276
- const name = prop.replace(/^class:/, "");
277
- klass += ` ${name}`;
278
- delete props[prop];
279
- continue;
280
- }
281
- if (value === false) {
282
- delete props[prop];
283
- continue;
284
- }
285
- }
286
325
  if (prop === "style" && typeof value === "string") {
287
326
  style += `${value}${value.at(-1) === ";" ? "" : ";"}`;
288
327
  delete props[prop];
289
328
  continue;
290
329
  }
291
- if (startsWith(prop, "style:") && (typeof value === "string" || typeof value === "number")) {
292
- const name = prop.replace(/^style:/, "");
293
- style += `${name}:${value};`;
294
- delete props[prop];
295
- continue;
296
- }
297
330
  if (value === true) {
298
- result.template += ` ${prop}`;
331
+ result.template[result.template.length - 1] += ` ${prop}`;
299
332
  delete props[prop];
300
333
  }
301
334
  if (value === false) {
302
335
  delete props[prop];
303
336
  }
304
337
  if (typeof value === "string" || typeof value === "number") {
305
- result.template += ` ${prop}="${value}"`;
338
+ result.template[result.template.length - 1] += ` ${prop}="${value}"`;
306
339
  delete props[prop];
307
340
  }
308
341
  }
@@ -312,36 +345,34 @@ function handleAttributes(props, result) {
312
345
  klass = klass.trim();
313
346
  style = style.trim();
314
347
  if (klass) {
315
- result.template += ` class="${klass}"`;
348
+ result.template[result.template.length - 1] += ` class="${klass}"`;
316
349
  }
317
350
  if (style) {
318
- result.template += ` style="${style}"`;
351
+ result.template[result.template.length - 1] += ` style="${style}"`;
319
352
  }
320
353
  }
321
354
  function replaceChild(node, result) {
322
355
  var _a, _b, _c, _d, _e;
323
356
  if (result.isLastChild) {
324
357
  result.index--;
325
- } else {
326
- result.template += "<!-->";
327
358
  }
328
359
  (_c = (_a = result.props)[_b = result.parentIndex]) != null ? _c : _a[_b] = {};
329
360
  (_e = (_d = result.props[result.parentIndex]).children) != null ? _e : _d.children = [];
330
361
  result.props[result.parentIndex].children.push(
331
- t2.arrayExpression([
332
- t2.arrowFunctionExpression([], node),
333
- result.isLastChild ? t2.nullLiteral() : t2.identifier(String(result.index))
362
+ t3.arrayExpression([
363
+ t3.arrowFunctionExpression([], node),
364
+ t3.identifier(String(result.template.length))
334
365
  ])
335
366
  );
336
367
  }
337
368
  function getChildren(path) {
338
369
  return path.get("children").filter((child) => isValidChild(child)).map((child) => {
339
370
  if (child.isJSXElement() || child.isJSXFragment()) {
340
- transformJSXClient(child);
371
+ transformJSXService(child);
341
372
  } else if (child.isJSXExpressionContainer()) {
342
373
  child.replaceWith(child.get("expression"));
343
374
  } else if (child.isJSXText()) {
344
- child.replaceWith(t2.stringLiteral(child.node.value));
375
+ child.replaceWith(t3.stringLiteral(child.node.value));
345
376
  } else {
346
377
  throw new Error("Unsupported child type");
347
378
  }
@@ -357,6 +388,7 @@ function isValidChild(path) {
357
388
  }
358
389
  function getAttrProps(path) {
359
390
  const props = {};
391
+ let hasExpression = false;
360
392
  path.get("openingElement").get("attributes").forEach((attribute) => {
361
393
  if (attribute.isJSXAttribute()) {
362
394
  const name = getAttrName(attribute.node);
@@ -373,77 +405,57 @@ function getAttrProps(path) {
373
405
  } else if (expression.isNumericLiteral()) {
374
406
  props[name] = expression.node.value;
375
407
  } else if (expression.isJSXElement() || expression.isJSXFragment()) {
376
- transformJSXClient(expression);
408
+ transformJSXService(expression);
377
409
  props[name] = expression.node;
378
410
  } else if (expression.isExpression()) {
411
+ hasExpression = true;
379
412
  if (/^key|ref|on.+$/.test(name)) {
380
413
  props[name] = expression.node;
381
414
  } else if (/^bind:.+/.test(name)) {
382
415
  const value2 = path.scope.generateUidIdentifier("value");
383
416
  const bindName = name.slice(5).toLocaleLowerCase();
384
417
  props[bindName] = expression.node;
385
- props[`update:${bindName}`] = t2.arrowFunctionExpression(
418
+ props[`update${capitalizeFirstLetter(bindName)}`] = t3.arrowFunctionExpression(
386
419
  [value2],
387
- t2.assignmentExpression("=", expression.node, value2)
420
+ t3.assignmentExpression("=", expression.node, value2)
388
421
  );
389
422
  } else {
390
423
  if (expression.isConditionalExpression()) {
391
- props[name] = t2.arrowFunctionExpression([], expression.node);
424
+ props[name] = t3.arrowFunctionExpression([], expression.node);
392
425
  } else {
393
426
  props[name] = expression.node;
394
427
  }
395
428
  }
396
429
  }
397
430
  } else if (value.isJSXElement() || value.isJSXFragment()) {
398
- transformJSXClient(value);
431
+ transformJSXService(value);
399
432
  props[name] = value.node;
400
433
  }
401
434
  }
402
435
  } else if (attribute.isJSXSpreadAttribute()) {
403
436
  props._$spread$ = attribute.get("argument").node;
437
+ hasExpression = true;
404
438
  } else {
405
439
  throw new Error("Unsupported attribute type");
406
440
  }
407
441
  });
408
- return props;
409
- }
410
- function getAttrName(attribute) {
411
- if (t2.isJSXIdentifier(attribute.name)) {
412
- return attribute.name.name;
413
- }
414
- if (t2.isJSXNamespacedName(attribute.name)) {
415
- return `${attribute.name.namespace.name}:${attribute.name.name.name}`;
416
- }
417
- throw new Error("Unsupported attribute type");
418
- }
419
- function isComponent(tagName) {
420
- return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^A-Za-z]/.test(tagName[0]);
421
- }
422
- function getTagName(node) {
423
- const tag = node.openingElement.name;
424
- return jsxElementNameToString(tag);
425
- }
426
- function jsxElementNameToString(node) {
427
- if (t2.isJSXMemberExpression(node)) {
428
- return `${jsxElementNameToString(node.object)}.${jsxElementNameToString(node.property)}`;
429
- }
430
- if (t2.isJSXIdentifier(node) || t2.isIdentifier(node)) {
431
- return node.name;
432
- }
433
- return `${node.namespace.name}:${node.name.name}`;
442
+ return {
443
+ props,
444
+ hasExpression
445
+ };
434
446
  }
435
447
 
436
- // src/jsx/server.ts
437
- function transformJSXService(path) {
448
+ // src/jsx/client.ts
449
+ import { types as t4 } from "@babel/core";
450
+ function transformJSXClient(path) {
438
451
  const result = {
439
- index: 0,
452
+ index: 1,
440
453
  isLastChild: false,
441
454
  parentIndex: 0,
442
455
  props: {},
443
- template: []
444
- // 修改为数组
456
+ template: ""
445
457
  };
446
- transformJSXServiceElement(path, result, true);
458
+ transformJSXElement(path, result, true);
447
459
  path.replaceWith(createEssorNode2(path, result));
448
460
  }
449
461
  function createEssorNode2(path, result) {
@@ -451,94 +463,84 @@ function createEssorNode2(path, result) {
451
463
  const state = path.state;
452
464
  let tmpl;
453
465
  if (path.isJSXElement() && isComponent(getTagName(path.node))) {
454
- tmpl = t3.identifier(getTagName(path.node));
466
+ tmpl = t4.identifier(getTagName(path.node));
455
467
  } else {
456
468
  tmpl = path.scope.generateUidIdentifier("_tmpl$");
457
- const template = t3.callExpression(state.ssrtmpl, [
458
- t3.arrayExpression(result.template.map(t3.stringLiteral))
459
- ]);
460
- const declarator = t3.variableDeclarator(tmpl, template);
469
+ const template = t4.callExpression(state.template, [t4.stringLiteral(result.template)]);
470
+ const declarator = t4.variableDeclarator(tmpl, template);
461
471
  state.tmplDeclaration.declarations.push(declarator);
462
- imports.add("ssrtmpl");
472
+ imports.add("template");
463
473
  }
464
474
  const args = [tmpl, createProps2(result.props)];
465
475
  const key = result.props.key || ((_a = result.props[0]) == null ? void 0 : _a.key);
466
476
  if (key) {
467
477
  args.push(key);
468
478
  }
469
- imports.add("ssr");
470
- return t3.callExpression(state.ssr, args);
479
+ imports.add("h");
480
+ return t4.callExpression(state.h, args);
471
481
  }
472
482
  function createProps2(props) {
473
- const result = [];
474
- for (const prop in props) {
475
- let value = props[prop];
476
- if (prop === "key") {
477
- continue;
478
- }
483
+ const toAstNode = (value) => {
479
484
  if (Array.isArray(value)) {
480
- value = t3.arrayExpression(value);
481
- }
482
- if (typeof value === "object" && value !== null && !t3.isNode(value)) {
483
- value = createProps2(value);
484
- }
485
- if (typeof value === "string") {
486
- value = t3.stringLiteral(value);
487
- }
488
- if (typeof value === "number") {
489
- value = t3.numericLiteral(value);
490
- }
491
- if (typeof value === "boolean") {
492
- value = t3.booleanLiteral(value);
493
- }
494
- if (value === void 0) {
495
- value = t3.tsUndefinedKeyword();
485
+ return t4.arrayExpression(value.map(toAstNode));
496
486
  }
497
- if (value === null) {
498
- value = t3.nullLiteral();
487
+ if (value && typeof value === "object" && !t4.isNode(value)) {
488
+ return createProps2(value);
499
489
  }
500
- if (prop === "_$spread$") {
501
- result.push(t3.spreadElement(value));
502
- } else {
503
- result.push(t3.objectProperty(t3.stringLiteral(prop), value));
490
+ switch (typeof value) {
491
+ case "string":
492
+ return t4.stringLiteral(value);
493
+ case "number":
494
+ return t4.numericLiteral(value);
495
+ case "boolean":
496
+ return t4.booleanLiteral(value);
497
+ case "undefined":
498
+ return t4.tsUndefinedKeyword();
499
+ case void 0:
500
+ return t4.tsUndefinedKeyword();
501
+ case null:
502
+ return t4.nullLiteral();
503
+ default:
504
+ return value;
504
505
  }
505
- }
506
- return t3.objectExpression(result);
506
+ };
507
+ const result = Object.keys(props).filter((prop) => prop !== "key").map((prop) => {
508
+ const value = toAstNode(props[prop]);
509
+ return prop === "_$spread$" ? t4.spreadElement(value) : t4.objectProperty(t4.stringLiteral(prop), value);
510
+ });
511
+ return t4.objectExpression(result);
507
512
  }
508
- function transformJSXServiceElement(path, result, isRoot = false) {
513
+ function transformJSXElement(path, result, isRoot = false) {
509
514
  if (path.isJSXElement()) {
510
515
  const tagName = getTagName(path.node);
511
516
  const tagIsComponent = isComponent(tagName);
512
517
  const isSelfClose = !tagIsComponent && selfClosingTags.includes(tagName);
513
518
  const isSvg = svgTags.includes(tagName) && result.index === 1;
514
- const { props, hasExpression } = getAttrProps2(path);
519
+ const props = getAttrProps2(path);
515
520
  if (tagIsComponent) {
516
521
  if (isRoot) {
517
522
  result.props = props;
518
523
  const children = getChildren2(path);
519
524
  if (children.length > 0) {
520
- const childrenGenerator = children.length === 1 ? children[0] : t3.arrayExpression(children);
525
+ const childrenGenerator = children.length === 1 ? children[0] : t4.arrayExpression(children);
521
526
  result.props.children = childrenGenerator;
522
527
  }
523
528
  } else {
524
- transformJSXService(path);
529
+ transformJSXClient(path);
525
530
  replaceChild2(path.node, result);
526
531
  }
527
532
  } else {
528
533
  if (isSvg) {
529
- result.template.push("<svg _svg_>");
534
+ result.template = "<svg _svg_>";
530
535
  }
531
- result.template.push(`<${tagName}`);
536
+ result.template += `<${tagName}`;
532
537
  handleAttributes2(props, result);
533
- if (hasExpression) {
534
- result.template.push(isSelfClose ? "/>" : ">");
535
- result.props || (result.props = {});
536
- } else {
537
- result.template[result.template.length - 1] += isSelfClose ? "/>" : ">";
538
- }
539
- transformChildren2(path, result);
538
+ result.template += isSelfClose ? "/>" : ">";
540
539
  if (!isSelfClose) {
541
- result.template.push(`</${tagName}>`);
540
+ transformChildren2(path, result);
541
+ if (hasSiblingElement(path)) {
542
+ result.template += `</${tagName}>`;
543
+ }
542
544
  }
543
545
  }
544
546
  } else {
@@ -547,12 +549,12 @@ function transformJSXServiceElement(path, result, isRoot = false) {
547
549
  }
548
550
  }
549
551
  function transformChildren2(path, result) {
550
- const parentIndex = result.template.length;
552
+ const parentIndex = result.index;
551
553
  path.get("children").reduce((pre, cur) => {
552
554
  if (isValidChild2(cur)) {
553
555
  const lastChild = pre.at(-1);
554
556
  if (lastChild && isTextChild(cur) && isTextChild(lastChild)) {
555
- setNodeText2(lastChild, getNodeText2(lastChild) + getNodeText2(cur));
557
+ setNodeText(lastChild, getNodeText2(lastChild) + getNodeText2(cur));
556
558
  } else {
557
559
  pre.push(cur);
558
560
  }
@@ -565,20 +567,21 @@ function transformChildren2(path, result) {
565
567
  });
566
568
  }
567
569
  function transformChild2(child, result) {
570
+ result.index++;
568
571
  if (child.isJSXElement() || child.isJSXFragment()) {
569
- transformJSXServiceElement(child, result, false);
572
+ transformJSXElement(child, result, false);
570
573
  } else if (child.isJSXExpressionContainer()) {
571
574
  const expression = child.get("expression");
572
575
  if (expression.isStringLiteral() || expression.isNumericLiteral()) {
573
- result.template[result.template.length - 1] += String(expression.node.value);
576
+ result.template += String(expression.node.value);
574
577
  } else if (expression.isExpression()) {
575
578
  replaceChild2(expression.node, result);
576
- } else if (t3.isJSXEmptyExpression(expression.node)) {
579
+ } else if (t4.isJSXEmptyExpression(expression.node)) {
577
580
  } else {
578
581
  throw new Error("Unsupported child type");
579
582
  }
580
583
  } else if (child.isJSXText()) {
581
- result.template.push(String(child.node.value));
584
+ result.template += String(child.node.value);
582
585
  } else {
583
586
  throw new Error("Unsupported child type");
584
587
  }
@@ -595,17 +598,6 @@ function getNodeText2(path) {
595
598
  }
596
599
  return "";
597
600
  }
598
- function setNodeText2(path, text) {
599
- if (path.isJSXText()) {
600
- path.node.value = text;
601
- }
602
- if (path.isJSXExpressionContainer()) {
603
- const expression = path.get("expression");
604
- if (expression.isStringLiteral() || expression.isNumericLiteral()) {
605
- expression.replaceWith(t3.stringLiteral(text));
606
- }
607
- }
608
- }
609
601
  function handleAttributes2(props, result) {
610
602
  let klass = "";
611
603
  let style = "";
@@ -616,38 +608,20 @@ function handleAttributes2(props, result) {
616
608
  delete props[prop];
617
609
  continue;
618
610
  }
619
- if (startsWith(prop, "class:")) {
620
- if (value === true) {
621
- const name = prop.replace(/^class:/, "");
622
- klass += ` ${name}`;
623
- delete props[prop];
624
- continue;
625
- }
626
- if (value === false) {
627
- delete props[prop];
628
- continue;
629
- }
630
- }
631
611
  if (prop === "style" && typeof value === "string") {
632
612
  style += `${value}${value.at(-1) === ";" ? "" : ";"}`;
633
613
  delete props[prop];
634
614
  continue;
635
615
  }
636
- if (startsWith(prop, "style:") && (typeof value === "string" || typeof value === "number")) {
637
- const name = prop.replace(/^style:/, "");
638
- style += `${name}:${value};`;
639
- delete props[prop];
640
- continue;
641
- }
642
616
  if (value === true) {
643
- result.template[result.template.length - 1] += ` ${prop}`;
617
+ result.template += ` ${prop}`;
644
618
  delete props[prop];
645
619
  }
646
620
  if (value === false) {
647
621
  delete props[prop];
648
622
  }
649
623
  if (typeof value === "string" || typeof value === "number") {
650
- result.template[result.template.length - 1] += ` ${prop}="${value}"`;
624
+ result.template += ` ${prop}="${value}"`;
651
625
  delete props[prop];
652
626
  }
653
627
  }
@@ -657,34 +631,36 @@ function handleAttributes2(props, result) {
657
631
  klass = klass.trim();
658
632
  style = style.trim();
659
633
  if (klass) {
660
- result.template[result.template.length - 1] += ` class="${klass}"`;
634
+ result.template += ` class="${klass}"`;
661
635
  }
662
636
  if (style) {
663
- result.template[result.template.length - 1] += ` style="${style}"`;
637
+ result.template += ` style="${style}"`;
664
638
  }
665
639
  }
666
640
  function replaceChild2(node, result) {
667
641
  var _a, _b, _c, _d, _e;
668
642
  if (result.isLastChild) {
669
643
  result.index--;
644
+ } else {
645
+ result.template += "<!>";
670
646
  }
671
647
  (_c = (_a = result.props)[_b = result.parentIndex]) != null ? _c : _a[_b] = {};
672
648
  (_e = (_d = result.props[result.parentIndex]).children) != null ? _e : _d.children = [];
673
649
  result.props[result.parentIndex].children.push(
674
- t3.arrayExpression([
675
- t3.arrowFunctionExpression([], node),
676
- t3.identifier(String(result.template.length))
650
+ t4.arrayExpression([
651
+ t4.arrowFunctionExpression([], node),
652
+ result.isLastChild ? t4.nullLiteral() : t4.identifier(String(result.index))
677
653
  ])
678
654
  );
679
655
  }
680
656
  function getChildren2(path) {
681
657
  return path.get("children").filter((child) => isValidChild2(child)).map((child) => {
682
658
  if (child.isJSXElement() || child.isJSXFragment()) {
683
- transformJSXService(child);
659
+ transformJSXClient(child);
684
660
  } else if (child.isJSXExpressionContainer()) {
685
661
  child.replaceWith(child.get("expression"));
686
662
  } else if (child.isJSXText()) {
687
- child.replaceWith(t3.stringLiteral(child.node.value));
663
+ child.replaceWith(t4.stringLiteral(child.node.value));
688
664
  } else {
689
665
  throw new Error("Unsupported child type");
690
666
  }
@@ -700,7 +676,6 @@ function isValidChild2(path) {
700
676
  }
701
677
  function getAttrProps2(path) {
702
678
  const props = {};
703
- let hasExpression = false;
704
679
  path.get("openingElement").get("attributes").forEach((attribute) => {
705
680
  if (attribute.isJSXAttribute()) {
706
681
  const name = getAttrName(attribute.node);
@@ -717,81 +692,113 @@ function getAttrProps2(path) {
717
692
  } else if (expression.isNumericLiteral()) {
718
693
  props[name] = expression.node.value;
719
694
  } else if (expression.isJSXElement() || expression.isJSXFragment()) {
720
- transformJSXService(expression);
695
+ transformJSXClient(expression);
721
696
  props[name] = expression.node;
722
697
  } else if (expression.isExpression()) {
723
- hasExpression = true;
724
698
  if (/^key|ref|on.+$/.test(name)) {
725
699
  props[name] = expression.node;
726
700
  } else if (/^bind:.+/.test(name)) {
727
701
  const value2 = path.scope.generateUidIdentifier("value");
728
702
  const bindName = name.slice(5).toLocaleLowerCase();
729
703
  props[bindName] = expression.node;
730
- props[`update:${bindName}`] = t3.arrowFunctionExpression(
704
+ props[`update${capitalizeFirstLetter(bindName)}`] = t4.arrowFunctionExpression(
731
705
  [value2],
732
- t3.assignmentExpression("=", expression.node, value2)
706
+ t4.assignmentExpression("=", expression.node, value2)
733
707
  );
734
708
  } else {
735
709
  if (expression.isConditionalExpression()) {
736
- props[name] = t3.arrowFunctionExpression([], expression.node);
710
+ props[name] = t4.arrowFunctionExpression([], expression.node);
737
711
  } else {
738
712
  props[name] = expression.node;
739
713
  }
740
714
  }
741
715
  }
742
716
  } else if (value.isJSXElement() || value.isJSXFragment()) {
743
- transformJSXService(value);
717
+ transformJSXClient(value);
744
718
  props[name] = value.node;
745
719
  }
746
720
  }
747
721
  } else if (attribute.isJSXSpreadAttribute()) {
748
722
  props._$spread$ = attribute.get("argument").node;
749
- hasExpression = true;
750
723
  } else {
751
724
  throw new Error("Unsupported attribute type");
752
725
  }
753
726
  });
754
- return {
755
- props,
756
- hasExpression
757
- };
727
+ return props;
758
728
  }
759
729
 
760
730
  // src/jsx/index.ts
761
731
  function transformJSX(path) {
762
732
  const state = path.state;
763
- const isSsr = state.opts.ssr;
764
- return isSsr ? transformJSXService(path) : transformJSXClient(path);
733
+ const isSsg = state.opts.ssg;
734
+ return isSsg ? transformJSXService(path) : transformJSXClient(path);
765
735
  }
766
736
 
767
737
  // src/signal/symbol.ts
768
- import { types as t4 } from "@babel/core";
769
- import { cloneNode } from "@babel/types";
738
+ import { types as t5 } from "@babel/core";
770
739
  function replaceSymbol(path) {
771
740
  const init = path.node.init;
772
741
  const variableName = path.node.id.name;
773
- if (t4.isObjectPattern(path.node.id) || t4.isArrayPattern(path.node.id)) {
742
+ if (t5.isObjectPattern(path.node.id) || t5.isArrayPattern(path.node.id)) {
774
743
  return;
775
744
  }
776
745
  if (!startsWith(variableName, "$")) {
777
746
  return;
778
747
  }
779
- if (init && (t4.isFunctionExpression(init) || t4.isArrowFunctionExpression(init)) && path.parent.kind === "const") {
780
- const newInit = t4.callExpression(t4.identifier(path.state.useComputed.name), init ? [init] : []);
748
+ if (init && (t5.isFunctionExpression(init) || t5.isArrowFunctionExpression(init)) && path.parent.kind === "const") {
749
+ const newInit = t5.callExpression(t5.identifier(path.state.useComputed.name), init ? [init] : []);
781
750
  imports.add("useComputed");
782
751
  path.node.init = newInit;
783
752
  } else {
784
- const originalImportDeclarationNodes = cloneNode(path.get("id").node, true);
785
- const newInit = t4.callExpression(t4.identifier(path.state.useSignal.name), init ? [init] : []);
753
+ const newInit = t5.callExpression(t5.identifier(path.state.useSignal.name), init ? [init] : []);
786
754
  imports.add("useSignal");
787
755
  path.node.init = newInit;
788
- path.scope.rename(variableName, `${variableName}.value`);
789
- path.get("id").replaceWith(originalImportDeclarationNodes);
790
756
  }
791
757
  }
758
+ function symbolIdentifier(path) {
759
+ const parentPath = path.parentPath;
760
+ if (!parentPath || t5.isVariableDeclarator(parentPath) || t5.isImportSpecifier(parentPath) || t5.isObjectProperty(parentPath) || t5.isArrayPattern(parentPath) || t5.isObjectPattern(parentPath)) {
761
+ return;
762
+ }
763
+ const { node } = path;
764
+ if (node.name.startsWith("$")) {
765
+ let currentPath = path;
766
+ while (currentPath.parentPath && !currentPath.parentPath.isProgram()) {
767
+ if (currentPath.parentPath.isMemberExpression() && currentPath.parentPath.node.property.name === "value") {
768
+ return;
769
+ }
770
+ currentPath = currentPath.parentPath;
771
+ }
772
+ const newNode = t5.memberExpression(t5.identifier(node.name), t5.identifier("value"));
773
+ path.replaceWith(newNode);
774
+ }
775
+ }
776
+ function symbolObjectPattern(path) {
777
+ path.node.properties.forEach((property) => {
778
+ if (t5.isObjectProperty(property) && t5.isIdentifier(property.key) && property.key.name.startsWith("$")) {
779
+ const newKey = t5.identifier(property.key.name);
780
+ property.key = newKey;
781
+ }
782
+ });
783
+ }
784
+ function symbolArrayPattern(path) {
785
+ path.node.elements.forEach((element) => {
786
+ if (t5.isIdentifier(element) && element.name.startsWith("$")) {
787
+ const newElement = t5.identifier(element.name);
788
+ element.name = newElement.name;
789
+ } else if (t5.isObjectPattern(element)) {
790
+ element.properties.forEach((property) => {
791
+ if (t5.isObjectProperty(property) && t5.isIdentifier(property.key) && property.key.name.startsWith("$")) {
792
+ const newKey = t5.identifier(property.key.name);
793
+ property.key = newKey;
794
+ }
795
+ });
796
+ }
797
+ });
798
+ }
792
799
 
793
800
  // src/signal/import.ts
794
- import { types as t5 } from "@babel/core";
801
+ import { types as t6 } from "@babel/core";
795
802
  function isVariableUsedAsObject(path, variableName) {
796
803
  const binding = path.scope.getBinding(variableName);
797
804
  let isUsedObject = false;
@@ -799,7 +806,7 @@ function isVariableUsedAsObject(path, variableName) {
799
806
  return isUsedObject;
800
807
  }
801
808
  for (const referencePath of binding.referencePaths) {
802
- if (t5.isMemberExpression(referencePath.parent)) {
809
+ if (t6.isMemberExpression(referencePath.parent)) {
803
810
  isUsedObject = true;
804
811
  }
805
812
  }
@@ -816,6 +823,72 @@ function replaceImportDeclaration(path) {
816
823
  });
817
824
  }
818
825
 
826
+ // src/signal/props.ts
827
+ import { types as t7 } from "@babel/core";
828
+ function replaceProps(path) {
829
+ var _a;
830
+ const state = path.state;
831
+ const firstParam = path.node.params[0];
832
+ if (!firstParam || !t7.isObjectPattern(firstParam)) {
833
+ return;
834
+ }
835
+ const returnStatement = path.get("body").get("body").find((statement) => statement.isReturnStatement());
836
+ if (!returnStatement) {
837
+ return;
838
+ }
839
+ const returnValue = (_a = returnStatement.node) == null ? void 0 : _a.argument;
840
+ if (!t7.isJSXElement(returnValue)) {
841
+ return;
842
+ }
843
+ function replaceProperties(properties2, parentPath) {
844
+ properties2.forEach((property) => {
845
+ if (t7.isObjectProperty(property)) {
846
+ const keyName = property.key.name;
847
+ if (t7.isIdentifier(property.value)) {
848
+ const propertyName = property.value.name;
849
+ const newName = `${parentPath}${keyName}`;
850
+ path.scope.rename(propertyName, newName);
851
+ } else if (t7.isObjectPattern(property.value)) {
852
+ replaceProperties(property.value.properties, `${parentPath}${keyName}.`);
853
+ }
854
+ }
855
+ });
856
+ }
857
+ const properties = firstParam.properties;
858
+ replaceProperties(
859
+ properties.filter((property) => !t7.isRestElement(property)),
860
+ "__props."
861
+ );
862
+ const notRestProperties = properties.filter((property) => !t7.isRestElement(property));
863
+ const notRestNames = notRestProperties.map(
864
+ (property) => property.key.name
865
+ );
866
+ if (notRestNames.some((name) => startsWith(name, "$"))) {
867
+ console.warn("props name can not start with $");
868
+ return;
869
+ }
870
+ const restElement = properties.find((property) => t7.isRestElement(property));
871
+ path.node.params[0] = t7.identifier("__props");
872
+ if (restElement) {
873
+ const restName = restElement.argument.name;
874
+ if (notRestProperties.length === 0) {
875
+ path.node.params[0] = t7.identifier(restName);
876
+ } else {
877
+ const restVariableDeclaration = t7.variableDeclaration("const", [
878
+ t7.variableDeclarator(
879
+ t7.identifier(restName),
880
+ t7.callExpression(state.useReactive, [
881
+ t7.identifier("__props"),
882
+ t7.arrayExpression(notRestNames.map((name) => t7.stringLiteral(name)))
883
+ ])
884
+ )
885
+ ]);
886
+ imports.add("useReactive");
887
+ path.node.body.body.unshift(restVariableDeclaration);
888
+ }
889
+ }
890
+ }
891
+
819
892
  // src/index.ts
820
893
  function src_default() {
821
894
  return {
@@ -830,8 +903,13 @@ function src_default() {
830
903
  Program: transformProgram,
831
904
  JSXElement: transformJSX,
832
905
  JSXFragment: transformJSX,
906
+ FunctionDeclaration: replaceProps,
907
+ ArrowFunctionExpression: replaceProps,
833
908
  VariableDeclarator: replaceSymbol,
834
- ImportDeclaration: replaceImportDeclaration
909
+ ImportDeclaration: replaceImportDeclaration,
910
+ Identifier: symbolIdentifier,
911
+ ObjectPattern: symbolObjectPattern,
912
+ ArrayPattern: symbolArrayPattern
835
913
  }
836
914
  };
837
915
  }