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.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,21 +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);
245
- } else if (import_core2.types.isJSXEmptyExpression(expression.node)) {
319
+ } else if (import_core3.types.isJSXEmptyExpression(expression.node)) {
246
320
  } else {
247
321
  throw new Error("Unsupported child type");
248
322
  }
249
323
  } else if (child.isJSXText()) {
250
- result.template += String(child.node.value);
324
+ result.template.push(String(child.node.value));
251
325
  } else {
252
326
  throw new Error("Unsupported child type");
253
327
  }
@@ -264,29 +338,6 @@ function getNodeText(path) {
264
338
  }
265
339
  return "";
266
340
  }
267
- function setNodeText(path, text) {
268
- if (path.isJSXText()) {
269
- path.node.value = text;
270
- }
271
- if (path.isJSXExpressionContainer()) {
272
- const expression = path.get("expression");
273
- if (expression.isStringLiteral() || expression.isNumericLiteral()) {
274
- expression.replaceWith(import_core2.types.stringLiteral(text));
275
- }
276
- }
277
- }
278
- function isTextChild(path) {
279
- if (path.isJSXExpressionContainer()) {
280
- const expression = path.get("expression");
281
- if (expression.isJSXText() || expression.isStringLiteral() || expression.isNumericLiteral()) {
282
- return true;
283
- }
284
- }
285
- if (path.isJSXText() || path.isStringLiteral() || path.isNullLiteral()) {
286
- return true;
287
- }
288
- return false;
289
- }
290
341
  function handleAttributes(props, result) {
291
342
  let klass = "";
292
343
  let style = "";
@@ -297,38 +348,20 @@ function handleAttributes(props, result) {
297
348
  delete props[prop];
298
349
  continue;
299
350
  }
300
- if (startsWith(prop, "class:")) {
301
- if (value === true) {
302
- const name = prop.replace(/^class:/, "");
303
- klass += ` ${name}`;
304
- delete props[prop];
305
- continue;
306
- }
307
- if (value === false) {
308
- delete props[prop];
309
- continue;
310
- }
311
- }
312
351
  if (prop === "style" && typeof value === "string") {
313
352
  style += `${value}${value.at(-1) === ";" ? "" : ";"}`;
314
353
  delete props[prop];
315
354
  continue;
316
355
  }
317
- if (startsWith(prop, "style:") && (typeof value === "string" || typeof value === "number")) {
318
- const name = prop.replace(/^style:/, "");
319
- style += `${name}:${value};`;
320
- delete props[prop];
321
- continue;
322
- }
323
356
  if (value === true) {
324
- result.template += ` ${prop}`;
357
+ result.template[result.template.length - 1] += ` ${prop}`;
325
358
  delete props[prop];
326
359
  }
327
360
  if (value === false) {
328
361
  delete props[prop];
329
362
  }
330
363
  if (typeof value === "string" || typeof value === "number") {
331
- result.template += ` ${prop}="${value}"`;
364
+ result.template[result.template.length - 1] += ` ${prop}="${value}"`;
332
365
  delete props[prop];
333
366
  }
334
367
  }
@@ -338,36 +371,34 @@ function handleAttributes(props, result) {
338
371
  klass = klass.trim();
339
372
  style = style.trim();
340
373
  if (klass) {
341
- result.template += ` class="${klass}"`;
374
+ result.template[result.template.length - 1] += ` class="${klass}"`;
342
375
  }
343
376
  if (style) {
344
- result.template += ` style="${style}"`;
377
+ result.template[result.template.length - 1] += ` style="${style}"`;
345
378
  }
346
379
  }
347
380
  function replaceChild(node, result) {
348
381
  var _a, _b, _c, _d, _e;
349
382
  if (result.isLastChild) {
350
383
  result.index--;
351
- } else {
352
- result.template += "<!-->";
353
384
  }
354
385
  (_c = (_a = result.props)[_b = result.parentIndex]) != null ? _c : _a[_b] = {};
355
386
  (_e = (_d = result.props[result.parentIndex]).children) != null ? _e : _d.children = [];
356
387
  result.props[result.parentIndex].children.push(
357
- import_core2.types.arrayExpression([
358
- import_core2.types.arrowFunctionExpression([], node),
359
- 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))
360
391
  ])
361
392
  );
362
393
  }
363
394
  function getChildren(path) {
364
395
  return path.get("children").filter((child) => isValidChild(child)).map((child) => {
365
396
  if (child.isJSXElement() || child.isJSXFragment()) {
366
- transformJSXClient(child);
397
+ transformJSXService(child);
367
398
  } else if (child.isJSXExpressionContainer()) {
368
399
  child.replaceWith(child.get("expression"));
369
400
  } else if (child.isJSXText()) {
370
- child.replaceWith(import_core2.types.stringLiteral(child.node.value));
401
+ child.replaceWith(import_core3.types.stringLiteral(child.node.value));
371
402
  } else {
372
403
  throw new Error("Unsupported child type");
373
404
  }
@@ -383,6 +414,7 @@ function isValidChild(path) {
383
414
  }
384
415
  function getAttrProps(path) {
385
416
  const props = {};
417
+ let hasExpression = false;
386
418
  path.get("openingElement").get("attributes").forEach((attribute) => {
387
419
  if (attribute.isJSXAttribute()) {
388
420
  const name = getAttrName(attribute.node);
@@ -399,77 +431,57 @@ function getAttrProps(path) {
399
431
  } else if (expression.isNumericLiteral()) {
400
432
  props[name] = expression.node.value;
401
433
  } else if (expression.isJSXElement() || expression.isJSXFragment()) {
402
- transformJSXClient(expression);
434
+ transformJSXService(expression);
403
435
  props[name] = expression.node;
404
436
  } else if (expression.isExpression()) {
437
+ hasExpression = true;
405
438
  if (/^key|ref|on.+$/.test(name)) {
406
439
  props[name] = expression.node;
407
440
  } else if (/^bind:.+/.test(name)) {
408
441
  const value2 = path.scope.generateUidIdentifier("value");
409
442
  const bindName = name.slice(5).toLocaleLowerCase();
410
443
  props[bindName] = expression.node;
411
- props[`update:${bindName}`] = import_core2.types.arrowFunctionExpression(
444
+ props[`update${capitalizeFirstLetter(bindName)}`] = import_core3.types.arrowFunctionExpression(
412
445
  [value2],
413
- import_core2.types.assignmentExpression("=", expression.node, value2)
446
+ import_core3.types.assignmentExpression("=", expression.node, value2)
414
447
  );
415
448
  } else {
416
449
  if (expression.isConditionalExpression()) {
417
- props[name] = import_core2.types.arrowFunctionExpression([], expression.node);
450
+ props[name] = import_core3.types.arrowFunctionExpression([], expression.node);
418
451
  } else {
419
452
  props[name] = expression.node;
420
453
  }
421
454
  }
422
455
  }
423
456
  } else if (value.isJSXElement() || value.isJSXFragment()) {
424
- transformJSXClient(value);
457
+ transformJSXService(value);
425
458
  props[name] = value.node;
426
459
  }
427
460
  }
428
461
  } else if (attribute.isJSXSpreadAttribute()) {
429
462
  props._$spread$ = attribute.get("argument").node;
463
+ hasExpression = true;
430
464
  } else {
431
465
  throw new Error("Unsupported attribute type");
432
466
  }
433
467
  });
434
- return props;
435
- }
436
- function getAttrName(attribute) {
437
- if (import_core2.types.isJSXIdentifier(attribute.name)) {
438
- return attribute.name.name;
439
- }
440
- if (import_core2.types.isJSXNamespacedName(attribute.name)) {
441
- return `${attribute.name.namespace.name}:${attribute.name.name.name}`;
442
- }
443
- throw new Error("Unsupported attribute type");
444
- }
445
- function isComponent(tagName) {
446
- return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^A-Za-z]/.test(tagName[0]);
447
- }
448
- function getTagName(node) {
449
- const tag = node.openingElement.name;
450
- return jsxElementNameToString(tag);
451
- }
452
- function jsxElementNameToString(node) {
453
- if (import_core2.types.isJSXMemberExpression(node)) {
454
- return `${jsxElementNameToString(node.object)}.${jsxElementNameToString(node.property)}`;
455
- }
456
- if (import_core2.types.isJSXIdentifier(node) || import_core2.types.isIdentifier(node)) {
457
- return node.name;
458
- }
459
- return `${node.namespace.name}:${node.name.name}`;
468
+ return {
469
+ props,
470
+ hasExpression
471
+ };
460
472
  }
461
473
 
462
- // src/jsx/server.ts
463
- function transformJSXService(path) {
474
+ // src/jsx/client.ts
475
+ var import_core4 = require("@babel/core");
476
+ function transformJSXClient(path) {
464
477
  const result = {
465
- index: 0,
478
+ index: 1,
466
479
  isLastChild: false,
467
480
  parentIndex: 0,
468
481
  props: {},
469
- template: []
470
- // 修改为数组
482
+ template: ""
471
483
  };
472
- transformJSXServiceElement(path, result, true);
484
+ transformJSXElement(path, result, true);
473
485
  path.replaceWith(createEssorNode2(path, result));
474
486
  }
475
487
  function createEssorNode2(path, result) {
@@ -477,94 +489,84 @@ function createEssorNode2(path, result) {
477
489
  const state = path.state;
478
490
  let tmpl;
479
491
  if (path.isJSXElement() && isComponent(getTagName(path.node))) {
480
- tmpl = import_core3.types.identifier(getTagName(path.node));
492
+ tmpl = import_core4.types.identifier(getTagName(path.node));
481
493
  } else {
482
494
  tmpl = path.scope.generateUidIdentifier("_tmpl$");
483
- const template = import_core3.types.callExpression(state.ssrtmpl, [
484
- import_core3.types.arrayExpression(result.template.map(import_core3.types.stringLiteral))
485
- ]);
486
- 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);
487
497
  state.tmplDeclaration.declarations.push(declarator);
488
- imports.add("ssrtmpl");
498
+ imports.add("template");
489
499
  }
490
500
  const args = [tmpl, createProps2(result.props)];
491
501
  const key = result.props.key || ((_a = result.props[0]) == null ? void 0 : _a.key);
492
502
  if (key) {
493
503
  args.push(key);
494
504
  }
495
- imports.add("ssr");
496
- return import_core3.types.callExpression(state.ssr, args);
505
+ imports.add("h");
506
+ return import_core4.types.callExpression(state.h, args);
497
507
  }
498
508
  function createProps2(props) {
499
- const result = [];
500
- for (const prop in props) {
501
- let value = props[prop];
502
- if (prop === "key") {
503
- continue;
504
- }
509
+ const toAstNode = (value) => {
505
510
  if (Array.isArray(value)) {
506
- value = import_core3.types.arrayExpression(value);
507
- }
508
- if (typeof value === "object" && value !== null && !import_core3.types.isNode(value)) {
509
- value = createProps2(value);
510
- }
511
- if (typeof value === "string") {
512
- value = import_core3.types.stringLiteral(value);
513
- }
514
- if (typeof value === "number") {
515
- value = import_core3.types.numericLiteral(value);
516
- }
517
- if (typeof value === "boolean") {
518
- value = import_core3.types.booleanLiteral(value);
519
- }
520
- if (value === void 0) {
521
- value = import_core3.types.tsUndefinedKeyword();
511
+ return import_core4.types.arrayExpression(value.map(toAstNode));
522
512
  }
523
- if (value === null) {
524
- value = import_core3.types.nullLiteral();
513
+ if (value && typeof value === "object" && !import_core4.types.isNode(value)) {
514
+ return createProps2(value);
525
515
  }
526
- if (prop === "_$spread$") {
527
- result.push(import_core3.types.spreadElement(value));
528
- } else {
529
- 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;
530
531
  }
531
- }
532
- 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);
533
538
  }
534
- function transformJSXServiceElement(path, result, isRoot = false) {
539
+ function transformJSXElement(path, result, isRoot = false) {
535
540
  if (path.isJSXElement()) {
536
541
  const tagName = getTagName(path.node);
537
542
  const tagIsComponent = isComponent(tagName);
538
543
  const isSelfClose = !tagIsComponent && selfClosingTags.includes(tagName);
539
544
  const isSvg = svgTags.includes(tagName) && result.index === 1;
540
- const { props, hasExpression } = getAttrProps2(path);
545
+ const props = getAttrProps2(path);
541
546
  if (tagIsComponent) {
542
547
  if (isRoot) {
543
548
  result.props = props;
544
549
  const children = getChildren2(path);
545
550
  if (children.length > 0) {
546
- 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);
547
552
  result.props.children = childrenGenerator;
548
553
  }
549
554
  } else {
550
- transformJSXService(path);
555
+ transformJSXClient(path);
551
556
  replaceChild2(path.node, result);
552
557
  }
553
558
  } else {
554
559
  if (isSvg) {
555
- result.template.push("<svg _svg_>");
560
+ result.template = "<svg _svg_>";
556
561
  }
557
- result.template.push(`<${tagName}`);
562
+ result.template += `<${tagName}`;
558
563
  handleAttributes2(props, result);
559
- if (hasExpression) {
560
- result.template.push(isSelfClose ? "/>" : ">");
561
- result.props || (result.props = {});
562
- } else {
563
- result.template[result.template.length - 1] += isSelfClose ? "/>" : ">";
564
- }
565
- transformChildren2(path, result);
564
+ result.template += isSelfClose ? "/>" : ">";
566
565
  if (!isSelfClose) {
567
- result.template.push(`</${tagName}>`);
566
+ transformChildren2(path, result);
567
+ if (hasSiblingElement(path)) {
568
+ result.template += `</${tagName}>`;
569
+ }
568
570
  }
569
571
  }
570
572
  } else {
@@ -573,12 +575,12 @@ function transformJSXServiceElement(path, result, isRoot = false) {
573
575
  }
574
576
  }
575
577
  function transformChildren2(path, result) {
576
- const parentIndex = result.template.length;
578
+ const parentIndex = result.index;
577
579
  path.get("children").reduce((pre, cur) => {
578
580
  if (isValidChild2(cur)) {
579
581
  const lastChild = pre.at(-1);
580
582
  if (lastChild && isTextChild(cur) && isTextChild(lastChild)) {
581
- setNodeText2(lastChild, getNodeText2(lastChild) + getNodeText2(cur));
583
+ setNodeText(lastChild, getNodeText2(lastChild) + getNodeText2(cur));
582
584
  } else {
583
585
  pre.push(cur);
584
586
  }
@@ -591,20 +593,21 @@ function transformChildren2(path, result) {
591
593
  });
592
594
  }
593
595
  function transformChild2(child, result) {
596
+ result.index++;
594
597
  if (child.isJSXElement() || child.isJSXFragment()) {
595
- transformJSXServiceElement(child, result, false);
598
+ transformJSXElement(child, result, false);
596
599
  } else if (child.isJSXExpressionContainer()) {
597
600
  const expression = child.get("expression");
598
601
  if (expression.isStringLiteral() || expression.isNumericLiteral()) {
599
- result.template[result.template.length - 1] += String(expression.node.value);
602
+ result.template += String(expression.node.value);
600
603
  } else if (expression.isExpression()) {
601
604
  replaceChild2(expression.node, result);
602
- } else if (import_core3.types.isJSXEmptyExpression(expression.node)) {
605
+ } else if (import_core4.types.isJSXEmptyExpression(expression.node)) {
603
606
  } else {
604
607
  throw new Error("Unsupported child type");
605
608
  }
606
609
  } else if (child.isJSXText()) {
607
- result.template.push(String(child.node.value));
610
+ result.template += String(child.node.value);
608
611
  } else {
609
612
  throw new Error("Unsupported child type");
610
613
  }
@@ -621,17 +624,6 @@ function getNodeText2(path) {
621
624
  }
622
625
  return "";
623
626
  }
624
- function setNodeText2(path, text) {
625
- if (path.isJSXText()) {
626
- path.node.value = text;
627
- }
628
- if (path.isJSXExpressionContainer()) {
629
- const expression = path.get("expression");
630
- if (expression.isStringLiteral() || expression.isNumericLiteral()) {
631
- expression.replaceWith(import_core3.types.stringLiteral(text));
632
- }
633
- }
634
- }
635
627
  function handleAttributes2(props, result) {
636
628
  let klass = "";
637
629
  let style = "";
@@ -642,38 +634,20 @@ function handleAttributes2(props, result) {
642
634
  delete props[prop];
643
635
  continue;
644
636
  }
645
- if (startsWith(prop, "class:")) {
646
- if (value === true) {
647
- const name = prop.replace(/^class:/, "");
648
- klass += ` ${name}`;
649
- delete props[prop];
650
- continue;
651
- }
652
- if (value === false) {
653
- delete props[prop];
654
- continue;
655
- }
656
- }
657
637
  if (prop === "style" && typeof value === "string") {
658
638
  style += `${value}${value.at(-1) === ";" ? "" : ";"}`;
659
639
  delete props[prop];
660
640
  continue;
661
641
  }
662
- if (startsWith(prop, "style:") && (typeof value === "string" || typeof value === "number")) {
663
- const name = prop.replace(/^style:/, "");
664
- style += `${name}:${value};`;
665
- delete props[prop];
666
- continue;
667
- }
668
642
  if (value === true) {
669
- result.template[result.template.length - 1] += ` ${prop}`;
643
+ result.template += ` ${prop}`;
670
644
  delete props[prop];
671
645
  }
672
646
  if (value === false) {
673
647
  delete props[prop];
674
648
  }
675
649
  if (typeof value === "string" || typeof value === "number") {
676
- result.template[result.template.length - 1] += ` ${prop}="${value}"`;
650
+ result.template += ` ${prop}="${value}"`;
677
651
  delete props[prop];
678
652
  }
679
653
  }
@@ -683,34 +657,36 @@ function handleAttributes2(props, result) {
683
657
  klass = klass.trim();
684
658
  style = style.trim();
685
659
  if (klass) {
686
- result.template[result.template.length - 1] += ` class="${klass}"`;
660
+ result.template += ` class="${klass}"`;
687
661
  }
688
662
  if (style) {
689
- result.template[result.template.length - 1] += ` style="${style}"`;
663
+ result.template += ` style="${style}"`;
690
664
  }
691
665
  }
692
666
  function replaceChild2(node, result) {
693
667
  var _a, _b, _c, _d, _e;
694
668
  if (result.isLastChild) {
695
669
  result.index--;
670
+ } else {
671
+ result.template += "<!>";
696
672
  }
697
673
  (_c = (_a = result.props)[_b = result.parentIndex]) != null ? _c : _a[_b] = {};
698
674
  (_e = (_d = result.props[result.parentIndex]).children) != null ? _e : _d.children = [];
699
675
  result.props[result.parentIndex].children.push(
700
- import_core3.types.arrayExpression([
701
- import_core3.types.arrowFunctionExpression([], node),
702
- 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))
703
679
  ])
704
680
  );
705
681
  }
706
682
  function getChildren2(path) {
707
683
  return path.get("children").filter((child) => isValidChild2(child)).map((child) => {
708
684
  if (child.isJSXElement() || child.isJSXFragment()) {
709
- transformJSXService(child);
685
+ transformJSXClient(child);
710
686
  } else if (child.isJSXExpressionContainer()) {
711
687
  child.replaceWith(child.get("expression"));
712
688
  } else if (child.isJSXText()) {
713
- child.replaceWith(import_core3.types.stringLiteral(child.node.value));
689
+ child.replaceWith(import_core4.types.stringLiteral(child.node.value));
714
690
  } else {
715
691
  throw new Error("Unsupported child type");
716
692
  }
@@ -726,7 +702,6 @@ function isValidChild2(path) {
726
702
  }
727
703
  function getAttrProps2(path) {
728
704
  const props = {};
729
- let hasExpression = false;
730
705
  path.get("openingElement").get("attributes").forEach((attribute) => {
731
706
  if (attribute.isJSXAttribute()) {
732
707
  const name = getAttrName(attribute.node);
@@ -743,81 +718,113 @@ function getAttrProps2(path) {
743
718
  } else if (expression.isNumericLiteral()) {
744
719
  props[name] = expression.node.value;
745
720
  } else if (expression.isJSXElement() || expression.isJSXFragment()) {
746
- transformJSXService(expression);
721
+ transformJSXClient(expression);
747
722
  props[name] = expression.node;
748
723
  } else if (expression.isExpression()) {
749
- hasExpression = true;
750
724
  if (/^key|ref|on.+$/.test(name)) {
751
725
  props[name] = expression.node;
752
726
  } else if (/^bind:.+/.test(name)) {
753
727
  const value2 = path.scope.generateUidIdentifier("value");
754
728
  const bindName = name.slice(5).toLocaleLowerCase();
755
729
  props[bindName] = expression.node;
756
- props[`update:${bindName}`] = import_core3.types.arrowFunctionExpression(
730
+ props[`update${capitalizeFirstLetter(bindName)}`] = import_core4.types.arrowFunctionExpression(
757
731
  [value2],
758
- import_core3.types.assignmentExpression("=", expression.node, value2)
732
+ import_core4.types.assignmentExpression("=", expression.node, value2)
759
733
  );
760
734
  } else {
761
735
  if (expression.isConditionalExpression()) {
762
- props[name] = import_core3.types.arrowFunctionExpression([], expression.node);
736
+ props[name] = import_core4.types.arrowFunctionExpression([], expression.node);
763
737
  } else {
764
738
  props[name] = expression.node;
765
739
  }
766
740
  }
767
741
  }
768
742
  } else if (value.isJSXElement() || value.isJSXFragment()) {
769
- transformJSXService(value);
743
+ transformJSXClient(value);
770
744
  props[name] = value.node;
771
745
  }
772
746
  }
773
747
  } else if (attribute.isJSXSpreadAttribute()) {
774
748
  props._$spread$ = attribute.get("argument").node;
775
- hasExpression = true;
776
749
  } else {
777
750
  throw new Error("Unsupported attribute type");
778
751
  }
779
752
  });
780
- return {
781
- props,
782
- hasExpression
783
- };
753
+ return props;
784
754
  }
785
755
 
786
756
  // src/jsx/index.ts
787
757
  function transformJSX(path) {
788
758
  const state = path.state;
789
- const isSsr = state.opts.ssr;
790
- return isSsr ? transformJSXService(path) : transformJSXClient(path);
759
+ const isSsg = state.opts.ssg;
760
+ return isSsg ? transformJSXService(path) : transformJSXClient(path);
791
761
  }
792
762
 
793
763
  // src/signal/symbol.ts
794
- var import_core4 = require("@babel/core");
795
- var import_types = require("@babel/types");
764
+ var import_core5 = require("@babel/core");
796
765
  function replaceSymbol(path) {
797
766
  const init = path.node.init;
798
767
  const variableName = path.node.id.name;
799
- 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)) {
800
769
  return;
801
770
  }
802
771
  if (!startsWith(variableName, "$")) {
803
772
  return;
804
773
  }
805
- if (init && (import_core4.types.isFunctionExpression(init) || import_core4.types.isArrowFunctionExpression(init)) && path.parent.kind === "const") {
806
- 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] : []);
807
776
  imports.add("useComputed");
808
777
  path.node.init = newInit;
809
778
  } else {
810
- const originalImportDeclarationNodes = (0, import_types.cloneNode)(path.get("id").node, true);
811
- 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] : []);
812
780
  imports.add("useSignal");
813
781
  path.node.init = newInit;
814
- path.scope.rename(variableName, `${variableName}.value`);
815
- path.get("id").replaceWith(originalImportDeclarationNodes);
816
782
  }
817
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
+ }
818
825
 
819
826
  // src/signal/import.ts
820
- var import_core5 = require("@babel/core");
827
+ var import_core6 = require("@babel/core");
821
828
  function isVariableUsedAsObject(path, variableName) {
822
829
  const binding = path.scope.getBinding(variableName);
823
830
  let isUsedObject = false;
@@ -825,7 +832,7 @@ function isVariableUsedAsObject(path, variableName) {
825
832
  return isUsedObject;
826
833
  }
827
834
  for (const referencePath of binding.referencePaths) {
828
- if (import_core5.types.isMemberExpression(referencePath.parent)) {
835
+ if (import_core6.types.isMemberExpression(referencePath.parent)) {
829
836
  isUsedObject = true;
830
837
  }
831
838
  }
@@ -842,6 +849,72 @@ function replaceImportDeclaration(path) {
842
849
  });
843
850
  }
844
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
+
845
918
  // src/index.ts
846
919
  function src_default() {
847
920
  return {
@@ -856,8 +929,13 @@ function src_default() {
856
929
  Program: transformProgram,
857
930
  JSXElement: transformJSX,
858
931
  JSXFragment: transformJSX,
932
+ FunctionDeclaration: replaceProps,
933
+ ArrowFunctionExpression: replaceProps,
859
934
  VariableDeclarator: replaceSymbol,
860
- ImportDeclaration: replaceImportDeclaration
935
+ ImportDeclaration: replaceImportDeclaration,
936
+ Identifier: symbolIdentifier,
937
+ ObjectPattern: symbolObjectPattern,
938
+ ArrayPattern: symbolArrayPattern
861
939
  }
862
940
  };
863
941
  }