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