@vue-jsx-vapor/compiler 0.2.2 → 0.2.4

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
@@ -3,6 +3,7 @@ var _shared = require('@vue/shared');
3
3
 
4
4
 
5
5
  var _compilervapor = require('@vue/compiler-vapor');
6
+ var _parser = require('@babel/parser');
6
7
 
7
8
  // src/transform.ts
8
9
 
@@ -64,10 +65,41 @@ var DynamicFlag = /* @__PURE__ */ ((DynamicFlag2) => {
64
65
 
65
66
 
66
67
 
67
-
68
-
69
-
70
68
  var _types = require('@babel/types');
69
+ function newDynamic() {
70
+ return {
71
+ flags: 1 /* REFERENCED */,
72
+ children: []
73
+ };
74
+ }
75
+ function newBlock(node) {
76
+ return {
77
+ type: 1,
78
+ node,
79
+ dynamic: newDynamic(),
80
+ effect: [],
81
+ operation: [],
82
+ returns: [],
83
+ expressions: [],
84
+ tempId: 0
85
+ };
86
+ }
87
+ function createBranch(node, context, isVFor) {
88
+ context.node = node = wrapFragment(node);
89
+ const branch = newBlock(node);
90
+ const exitBlock = context.enterBlock(branch, isVFor);
91
+ context.reference();
92
+ return [branch, exitBlock];
93
+ }
94
+ function wrapFragment(node) {
95
+ if (node.type === "JSXFragment") {
96
+ return node;
97
+ }
98
+ return _types.jsxFragment.call(void 0, _types.jsxOpeningFragment.call(void 0, ), _types.jsxClosingFragment.call(void 0, ), [
99
+ node.type === "JSXElement" ? node : _types.jsxExpressionContainer.call(void 0, node)
100
+ ]);
101
+ }
102
+ var EMPTY_EXPRESSION = _compilerdom.createSimpleExpression.call(void 0, "", true);
71
103
 
72
104
  // src/utils.ts
73
105
 
@@ -82,6 +114,9 @@ var _types = require('@babel/types');
82
114
 
83
115
 
84
116
 
117
+ function propToExpression(prop, context) {
118
+ return prop.type === "JSXAttribute" && _optionalChain([prop, 'access', _2 => _2.value, 'optionalAccess', _3 => _3.type]) === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
119
+ }
85
120
  function isConstantExpression(exp) {
86
121
  return _compilerdom.isLiteralWhitelisted.call(void 0, exp.content) || _shared.isGloballyAllowed.call(void 0, exp.content) || getLiteralExpressionValue(exp) !== null;
87
122
  }
@@ -120,7 +155,7 @@ var EMPTY_TEXT_REGEX = /^\s*[\n\r]\s*$/;
120
155
  var START_EMPTY_TEXT_REGEX = /^\s*[\n\r]/;
121
156
  var END_EMPTY_TEXT_REGEX = /[\n\r]\s*$/;
122
157
  function resolveJSXText(node) {
123
- if (EMPTY_TEXT_REGEX.test(`${_optionalChain([node, 'access', _2 => _2.extra, 'optionalAccess', _3 => _3.raw])}`)) {
158
+ if (EMPTY_TEXT_REGEX.test(`${_optionalChain([node, 'access', _4 => _4.extra, 'optionalAccess', _5 => _5.raw])}`)) {
124
159
  return "";
125
160
  }
126
161
  let value = node.value;
@@ -133,10 +168,10 @@ function resolveJSXText(node) {
133
168
  return value;
134
169
  }
135
170
  function isEmptyText(node) {
136
- return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(`${_optionalChain([node, 'access', _4 => _4.extra, 'optionalAccess', _5 => _5.raw])}`) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression";
171
+ return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(`${_optionalChain([node, 'access', _6 => _6.extra, 'optionalAccess', _7 => _7.raw])}`) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression";
137
172
  }
138
173
  function resolveExpression(node, context, effect = false) {
139
- node = _optionalChain([node, 'optionalAccess', _6 => _6.type]) === "JSXExpressionContainer" ? node.expression : node;
174
+ node = _optionalChain([node, 'optionalAccess', _8 => _8.type]) === "JSXExpressionContainer" ? node.expression : node;
140
175
  const isStatic = !!node && (node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier");
141
176
  let source = !node || node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end);
142
177
  const location = node ? node.loc : null;
@@ -262,7 +297,7 @@ function isJSXComponent(node) {
262
297
  }
263
298
  }
264
299
  function findProp(expression, key) {
265
- if (_optionalChain([expression, 'optionalAccess', _7 => _7.type]) === "JSXElement") {
300
+ if (_optionalChain([expression, 'optionalAccess', _9 => _9.type]) === "JSXElement") {
266
301
  for (const attr of expression.openingElement.attributes) {
267
302
  if (attr.type === "JSXAttribute" && attr.name.name === key) {
268
303
  return attr;
@@ -270,62 +305,10 @@ function findProp(expression, key) {
270
305
  }
271
306
  }
272
307
  }
273
- function isJSXElement(node) {
274
- return !!node && (node.type === "JSXElement" || node.type === "JSXFragment");
308
+ function getText(node, content) {
309
+ return content.ir.source.slice(node.start, node.end);
275
310
  }
276
311
 
277
- // src/transforms/utils.ts
278
- function newDynamic() {
279
- return {
280
- flags: 1 /* REFERENCED */,
281
- children: []
282
- };
283
- }
284
- function newBlock(node) {
285
- return {
286
- type: 1,
287
- node,
288
- dynamic: newDynamic(),
289
- effect: [],
290
- operation: [],
291
- returns: [],
292
- expressions: [],
293
- tempId: 0
294
- };
295
- }
296
- function createBranch(node, context, isVFor) {
297
- context.node = node = wrapFragment(node, isVFor);
298
- const branch = newBlock(node);
299
- const exitBlock = context.enterBlock(branch, isVFor);
300
- context.reference();
301
- return [branch, exitBlock];
302
- }
303
- function wrapFragment(node, isVFor) {
304
- if (node.type === "JSXFragment") {
305
- return node;
306
- }
307
- if (isVFor && (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression")) {
308
- if (isJSXElement(node.body)) {
309
- node = node.body;
310
- } else if (node.body.type === "BlockStatement" && node.body.body[0].type === "ReturnStatement" && node.body.body[0].argument) {
311
- node = node.body.body[0].argument;
312
- } else {
313
- node = {
314
- ..._types.callExpression.call(void 0,
315
- _types.parenthesizedExpression.call(void 0, _types.arrowFunctionExpression.call(void 0, [], node.body)),
316
- []
317
- ),
318
- start: node.body.start,
319
- end: node.body.end
320
- };
321
- }
322
- }
323
- return _types.jsxFragment.call(void 0, _types.jsxOpeningFragment.call(void 0, ), _types.jsxClosingFragment.call(void 0, ), [
324
- node.type === "JSXElement" ? node : _types.jsxExpressionContainer.call(void 0, node)
325
- ]);
326
- }
327
- var EMPTY_EXPRESSION = _compilerdom.createSimpleExpression.call(void 0, "", true);
328
-
329
312
  // src/transform.ts
330
313
  var defaultOptions = {
331
314
  filename: "",
@@ -483,6 +466,31 @@ function transformNode(context) {
483
466
  context.registerTemplate();
484
467
  }
485
468
  }
469
+ function createStructuralDirectiveTransform(name, fn) {
470
+ const matches = (n) => _shared.isString.call(void 0, name) ? n === name : name.includes(n);
471
+ return (node, context) => {
472
+ if (node.type === "JSXElement") {
473
+ const {
474
+ openingElement: { attributes, name: name2 }
475
+ } = node;
476
+ if (getText(name2, context) === "template" && findProp(node, "v-slot")) {
477
+ return;
478
+ }
479
+ const exitFns = [];
480
+ for (const prop of attributes) {
481
+ if (prop.type !== "JSXAttribute") continue;
482
+ const propName = getText(prop.name, context);
483
+ if (propName.startsWith("v-") && matches(propName.slice(2))) {
484
+ attributes.splice(attributes.indexOf(prop), 1);
485
+ const onExit = fn(node, prop, context);
486
+ if (onExit) exitFns.push(onExit);
487
+ break;
488
+ }
489
+ }
490
+ return exitFns;
491
+ }
492
+ };
493
+ }
486
494
 
487
495
  // src/transforms/transformElement.ts
488
496
 
@@ -770,7 +778,7 @@ function processDynamicChildren(context) {
770
778
  var transformTemplateRef = (node, context) => {
771
779
  if (node.type !== "JSXElement") return;
772
780
  const dir = findProp(node, "ref");
773
- if (!_optionalChain([dir, 'optionalAccess', _8 => _8.value])) return;
781
+ if (!_optionalChain([dir, 'optionalAccess', _10 => _10.value])) return;
774
782
  context.ir.hasTemplateRef = true;
775
783
  const value = resolveExpression(dir.value, context);
776
784
  return () => {
@@ -883,7 +891,7 @@ var transformText = (node, context) => {
883
891
  }
884
892
  };
885
893
  function processTextLike(context) {
886
- const nexts = _optionalChain([context, 'access', _9 => _9.parent, 'access', _10 => _10.node, 'access', _11 => _11.children, 'optionalAccess', _12 => _12.slice, 'call', _13 => _13(context.index)]);
894
+ const nexts = _optionalChain([context, 'access', _11 => _11.parent, 'access', _12 => _12.node, 'access', _13 => _13.children, 'optionalAccess', _14 => _14.slice, 'call', _15 => _15(context.index)]);
887
895
  const idx = nexts.findIndex((n) => !isTextLike(n));
888
896
  const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
889
897
  context.dynamic.flags |= 4 /* INSERT */ | 2 /* NON_TEMPLATE */;
@@ -1037,7 +1045,7 @@ var transformVSlot = (node, context) => {
1037
1045
  (attr) => attr.type === "JSXAttribute" && ["v-slots", "vSlots"].includes(attr.name.name.toString())
1038
1046
  );
1039
1047
  const vSlotsDir = openingElement.attributes[vSlotsIndex];
1040
- if (vSlotsDir && _optionalChain([vSlotsDir, 'access', _14 => _14.value, 'optionalAccess', _15 => _15.type]) === "JSXExpressionContainer") {
1048
+ if (vSlotsDir && _optionalChain([vSlotsDir, 'access', _16 => _16.value, 'optionalAccess', _17 => _17.type]) === "JSXExpressionContainer") {
1041
1049
  node.openingElement.attributes.splice(vSlotsIndex, 1);
1042
1050
  context.slots = [
1043
1051
  {
@@ -1121,14 +1129,97 @@ var transformVHtml = (dir, node, context) => {
1121
1129
  );
1122
1130
  };
1123
1131
 
1132
+ // src/transforms/vFor.ts
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+ var transformVFor = createStructuralDirectiveTransform(
1141
+ "for",
1142
+ processFor
1143
+ );
1144
+ function processFor(node, dir, context) {
1145
+ if (!dir.value) {
1146
+ context.options.onError(
1147
+ _compilerdom.createCompilerError.call(void 0,
1148
+ _compilerdom.ErrorCodes.X_V_FOR_NO_EXPRESSION,
1149
+ resolveLocation(dir.loc, context)
1150
+ )
1151
+ );
1152
+ return;
1153
+ }
1154
+ if (!_compilerdom.forAliasRE) {
1155
+ context.options.onError(
1156
+ _compilerdom.createCompilerError.call(void 0,
1157
+ _compilerdom.ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION,
1158
+ resolveLocation(dir.loc, context)
1159
+ )
1160
+ );
1161
+ return;
1162
+ }
1163
+ let value, index, key, source;
1164
+ if (dir.value.type === "JSXExpressionContainer" && dir.value.expression.type === "BinaryExpression") {
1165
+ if (dir.value.expression.left.type === "SequenceExpression") {
1166
+ const expressions = dir.value.expression.left.expressions;
1167
+ value = expressions[0] && resolveValueExpression(expressions[0], context);
1168
+ key = expressions[1] && resolveExpression(expressions[1], context);
1169
+ index = expressions[2] && resolveExpression(expressions[2], context);
1170
+ } else {
1171
+ value = resolveValueExpression(dir.value.expression.left, context);
1172
+ }
1173
+ source = resolveExpression(dir.value.expression.right, context);
1174
+ }
1175
+ const keyProp = findProp(node, "key");
1176
+ const keyProperty = keyProp && propToExpression(keyProp, context);
1177
+ const isComponent = isJSXComponent(node);
1178
+ const id = context.reference();
1179
+ context.dynamic.flags |= 2 /* NON_TEMPLATE */ | 4 /* INSERT */;
1180
+ const [render, exitBlock] = createBranch(node, context, true);
1181
+ return () => {
1182
+ exitBlock();
1183
+ const { parent } = context;
1184
+ const isOnlyChild = parent && parent.block.node !== parent.node && parent.node.children.length === 1;
1185
+ context.registerOperation({
1186
+ type: 17 /* FOR */,
1187
+ id,
1188
+ source,
1189
+ value,
1190
+ key,
1191
+ index,
1192
+ keyProp: keyProperty,
1193
+ render,
1194
+ once: context.inVOnce || !!(source.ast && _compilerdom.isConstantNode.call(void 0, source.ast, {})),
1195
+ component: isComponent,
1196
+ onlyChild: !!isOnlyChild
1197
+ });
1198
+ };
1199
+ }
1200
+ function resolveValueExpression(node, context) {
1201
+ const text = getText(node, context);
1202
+ return node.type === "Identifier" ? resolveSimpleExpression(text, false, node.loc) : resolveSimpleExpression(
1203
+ text,
1204
+ false,
1205
+ node.loc,
1206
+ _parser.parseExpression.call(void 0, `(${text})=>{}`, {
1207
+ plugins: ["typescript"]
1208
+ })
1209
+ );
1210
+ }
1211
+
1124
1212
  // src/compile.ts
1125
- function compile(root, options = {}) {
1213
+ function compile(source, options = {}) {
1126
1214
  const resolvedOptions = _shared.extend.call(void 0, {}, options, {
1127
1215
  inline: true,
1128
1216
  prefixIdentifiers: false,
1129
1217
  expressionPlugins: options.expressionPlugins || ["jsx"]
1130
1218
  });
1131
- if (options.isTS) {
1219
+ if (!resolvedOptions.source && _shared.isString.call(void 0, source)) {
1220
+ resolvedOptions.source = source;
1221
+ }
1222
+ if (resolvedOptions.isTS) {
1132
1223
  const { expressionPlugins } = resolvedOptions;
1133
1224
  if (!expressionPlugins.includes("typescript")) {
1134
1225
  resolvedOptions.expressionPlugins = [
@@ -1137,11 +1228,15 @@ function compile(root, options = {}) {
1137
1228
  ];
1138
1229
  }
1139
1230
  }
1231
+ const root = _shared.isString.call(void 0, source) ? _parser.parse.call(void 0, source, {
1232
+ sourceType: "module",
1233
+ plugins: resolvedOptions.expressionPlugins
1234
+ }).program.body[0].expression : source;
1140
1235
  const children = root.type === "JSXFragment" ? root.children : root.type === "JSXElement" ? [root] : [];
1141
1236
  const ast = {
1142
1237
  type: 0 /* ROOT */,
1143
1238
  children,
1144
- source: options.source || ""
1239
+ source: resolvedOptions.source || ""
1145
1240
  };
1146
1241
  const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
1147
1242
  const ir = transform(
@@ -1149,13 +1244,13 @@ function compile(root, options = {}) {
1149
1244
  _shared.extend.call(void 0, {}, resolvedOptions, {
1150
1245
  nodeTransforms: [
1151
1246
  ...nodeTransforms,
1152
- ...options.nodeTransforms || []
1247
+ ...resolvedOptions.nodeTransforms || []
1153
1248
  // user transforms
1154
1249
  ],
1155
1250
  directiveTransforms: _shared.extend.call(void 0,
1156
1251
  {},
1157
1252
  directiveTransforms,
1158
- options.directiveTransforms || {}
1253
+ resolvedOptions.directiveTransforms || {}
1159
1254
  // user transforms
1160
1255
  )
1161
1256
  })
@@ -1165,6 +1260,7 @@ function compile(root, options = {}) {
1165
1260
  function getBaseTransformPreset() {
1166
1261
  return [
1167
1262
  [
1263
+ transformVFor,
1168
1264
  transformTemplateRef,
1169
1265
  transformText,
1170
1266
  transformElement,
@@ -1202,4 +1298,6 @@ function getBaseTransformPreset() {
1202
1298
 
1203
1299
 
1204
1300
 
1205
- exports.DynamicFlag = DynamicFlag; exports.IRDynamicPropsKind = IRDynamicPropsKind; exports.IRNodeTypes = IRNodeTypes; exports.IRSlotType = IRSlotType; exports.TransformContext = TransformContext; exports.compile = compile; exports.generate = _compilervapor.generate; exports.resolveDirectiveNode = resolveDirectiveNode; exports.resolveNode = resolveNode; exports.transform = transform; exports.transformChildren = transformChildren; exports.transformElement = transformElement; exports.transformNode = transformNode; exports.transformTemplateRef = transformTemplateRef; exports.transformText = transformText; exports.transformVBind = transformVBind; exports.transformVHtml = transformVHtml; exports.transformVModel = transformVModel; exports.transformVOn = transformVOn; exports.transformVShow = transformVShow; exports.transformVSlot = transformVSlot;
1301
+
1302
+
1303
+ exports.DynamicFlag = DynamicFlag; exports.IRDynamicPropsKind = IRDynamicPropsKind; exports.IRNodeTypes = IRNodeTypes; exports.IRSlotType = IRSlotType; exports.TransformContext = TransformContext; exports.compile = compile; exports.createStructuralDirectiveTransform = createStructuralDirectiveTransform; exports.generate = _compilervapor.generate; exports.resolveDirectiveNode = resolveDirectiveNode; exports.resolveNode = resolveNode; exports.transform = transform; exports.transformChildren = transformChildren; exports.transformElement = transformElement; exports.transformNode = transformNode; exports.transformTemplateRef = transformTemplateRef; exports.transformText = transformText; exports.transformVBind = transformVBind; exports.transformVFor = transformVFor; exports.transformVHtml = transformVHtml; exports.transformVModel = transformVModel; exports.transformVOn = transformVOn; exports.transformVShow = transformVShow; exports.transformVSlot = transformVSlot;
package/dist/index.d.cts CHANGED
@@ -287,6 +287,7 @@ interface DirectiveTransformResult {
287
287
  model?: boolean;
288
288
  modelModifiers?: string[];
289
289
  }
290
+ type StructuralDirectiveTransform = (node: JSXElement, dir: JSXAttribute, context: TransformContext) => void | (() => void);
290
291
  type TransformOptions = HackOptions<TransformOptions$1>;
291
292
  declare class TransformContext<T extends BlockIRNode['node'] = BlockIRNode['node']> {
292
293
  ir: RootIRNode;
@@ -318,11 +319,12 @@ declare class TransformContext<T extends BlockIRNode['node'] = BlockIRNode['node
318
319
  }
319
320
  declare function transform(node: RootNode, options?: TransformOptions): RootIRNode;
320
321
  declare function transformNode(context: TransformContext<BlockIRNode['node']>): void;
322
+ declare function createStructuralDirectiveTransform(name: string | string[], fn: StructuralDirectiveTransform): NodeTransform;
321
323
 
322
324
  interface VaporCodegenResult extends Omit<VaporCodegenResult$1, 'ast'> {
323
325
  ast: RootIRNode;
324
326
  }
325
- declare function compile(root: JSXElement | JSXFragment, options?: CompilerOptions): VaporCodegenResult;
327
+ declare function compile(source: JSXElement | JSXFragment | string, options?: CompilerOptions): VaporCodegenResult;
326
328
  type CompilerOptions = HackOptions<CompilerOptions$1> & {
327
329
  source?: string;
328
330
  };
@@ -354,4 +356,6 @@ declare const transformVShow: DirectiveTransform;
354
356
 
355
357
  declare const transformVHtml: DirectiveTransform;
356
358
 
357
- export { type BaseIRNode, type BlockIRNode, type CompilerOptions, type CreateComponentIRNode, type CreateTextNodeIRNode, type DeclareOldRefIRNode, type DirectiveIRNode, type DirectiveTransform, type DirectiveTransformResult, DynamicFlag, type ForIRNode, type GetTextChildIRNode, type HackOptions, type IRDynamicInfo, IRDynamicPropsKind, type IREffect, type IRFor, type IRNode, IRNodeTypes, type IRProp, type IRProps, type IRPropsDynamicAttribute, type IRPropsDynamicExpression, type IRPropsStatic, type IRSlotDynamic, type IRSlotDynamicBasic, type IRSlotDynamicConditional, type IRSlotDynamicLoop, IRSlotType, type IRSlots, type IRSlotsExpression, type IRSlotsStatic, type IfIRNode, type InsertNodeIRNode, type KeyOverride, type NodeTransform, type OperationNode, type PrependNodeIRNode, type RootIRNode, type RootNode, type SetDynamicEventsIRNode, type SetDynamicPropsIRNode, type SetEventIRNode, type SetHtmlIRNode, type SetPropIRNode, type SetTemplateRefIRNode, type SetTextIRNode, type SlotBlockIRNode, type SlotOutletIRNode, TransformContext, type TransformOptions, type TransformPreset, type VaporDirectiveNode, compile, resolveDirectiveNode, resolveNode, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVHtml, transformVModel, transformVOn, transformVShow, transformVSlot };
359
+ declare const transformVFor: NodeTransform;
360
+
361
+ export { type BaseIRNode, type BlockIRNode, type CompilerOptions, type CreateComponentIRNode, type CreateTextNodeIRNode, type DeclareOldRefIRNode, type DirectiveIRNode, type DirectiveTransform, type DirectiveTransformResult, DynamicFlag, type ForIRNode, type GetTextChildIRNode, type HackOptions, type IRDynamicInfo, IRDynamicPropsKind, type IREffect, type IRFor, type IRNode, IRNodeTypes, type IRProp, type IRProps, type IRPropsDynamicAttribute, type IRPropsDynamicExpression, type IRPropsStatic, type IRSlotDynamic, type IRSlotDynamicBasic, type IRSlotDynamicConditional, type IRSlotDynamicLoop, IRSlotType, type IRSlots, type IRSlotsExpression, type IRSlotsStatic, type IfIRNode, type InsertNodeIRNode, type KeyOverride, type NodeTransform, type OperationNode, type PrependNodeIRNode, type RootIRNode, type RootNode, type SetDynamicEventsIRNode, type SetDynamicPropsIRNode, type SetEventIRNode, type SetHtmlIRNode, type SetPropIRNode, type SetTemplateRefIRNode, type SetTextIRNode, type SlotBlockIRNode, type SlotOutletIRNode, type StructuralDirectiveTransform, TransformContext, type TransformOptions, type TransformPreset, type VaporDirectiveNode, compile, createStructuralDirectiveTransform, resolveDirectiveNode, resolveNode, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVFor, transformVHtml, transformVModel, transformVOn, transformVShow, transformVSlot };
package/dist/index.d.ts CHANGED
@@ -287,6 +287,7 @@ interface DirectiveTransformResult {
287
287
  model?: boolean;
288
288
  modelModifiers?: string[];
289
289
  }
290
+ type StructuralDirectiveTransform = (node: JSXElement, dir: JSXAttribute, context: TransformContext) => void | (() => void);
290
291
  type TransformOptions = HackOptions<TransformOptions$1>;
291
292
  declare class TransformContext<T extends BlockIRNode['node'] = BlockIRNode['node']> {
292
293
  ir: RootIRNode;
@@ -318,11 +319,12 @@ declare class TransformContext<T extends BlockIRNode['node'] = BlockIRNode['node
318
319
  }
319
320
  declare function transform(node: RootNode, options?: TransformOptions): RootIRNode;
320
321
  declare function transformNode(context: TransformContext<BlockIRNode['node']>): void;
322
+ declare function createStructuralDirectiveTransform(name: string | string[], fn: StructuralDirectiveTransform): NodeTransform;
321
323
 
322
324
  interface VaporCodegenResult extends Omit<VaporCodegenResult$1, 'ast'> {
323
325
  ast: RootIRNode;
324
326
  }
325
- declare function compile(root: JSXElement | JSXFragment, options?: CompilerOptions): VaporCodegenResult;
327
+ declare function compile(source: JSXElement | JSXFragment | string, options?: CompilerOptions): VaporCodegenResult;
326
328
  type CompilerOptions = HackOptions<CompilerOptions$1> & {
327
329
  source?: string;
328
330
  };
@@ -354,4 +356,6 @@ declare const transformVShow: DirectiveTransform;
354
356
 
355
357
  declare const transformVHtml: DirectiveTransform;
356
358
 
357
- export { type BaseIRNode, type BlockIRNode, type CompilerOptions, type CreateComponentIRNode, type CreateTextNodeIRNode, type DeclareOldRefIRNode, type DirectiveIRNode, type DirectiveTransform, type DirectiveTransformResult, DynamicFlag, type ForIRNode, type GetTextChildIRNode, type HackOptions, type IRDynamicInfo, IRDynamicPropsKind, type IREffect, type IRFor, type IRNode, IRNodeTypes, type IRProp, type IRProps, type IRPropsDynamicAttribute, type IRPropsDynamicExpression, type IRPropsStatic, type IRSlotDynamic, type IRSlotDynamicBasic, type IRSlotDynamicConditional, type IRSlotDynamicLoop, IRSlotType, type IRSlots, type IRSlotsExpression, type IRSlotsStatic, type IfIRNode, type InsertNodeIRNode, type KeyOverride, type NodeTransform, type OperationNode, type PrependNodeIRNode, type RootIRNode, type RootNode, type SetDynamicEventsIRNode, type SetDynamicPropsIRNode, type SetEventIRNode, type SetHtmlIRNode, type SetPropIRNode, type SetTemplateRefIRNode, type SetTextIRNode, type SlotBlockIRNode, type SlotOutletIRNode, TransformContext, type TransformOptions, type TransformPreset, type VaporDirectiveNode, compile, resolveDirectiveNode, resolveNode, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVHtml, transformVModel, transformVOn, transformVShow, transformVSlot };
359
+ declare const transformVFor: NodeTransform;
360
+
361
+ export { type BaseIRNode, type BlockIRNode, type CompilerOptions, type CreateComponentIRNode, type CreateTextNodeIRNode, type DeclareOldRefIRNode, type DirectiveIRNode, type DirectiveTransform, type DirectiveTransformResult, DynamicFlag, type ForIRNode, type GetTextChildIRNode, type HackOptions, type IRDynamicInfo, IRDynamicPropsKind, type IREffect, type IRFor, type IRNode, IRNodeTypes, type IRProp, type IRProps, type IRPropsDynamicAttribute, type IRPropsDynamicExpression, type IRPropsStatic, type IRSlotDynamic, type IRSlotDynamicBasic, type IRSlotDynamicConditional, type IRSlotDynamicLoop, IRSlotType, type IRSlots, type IRSlotsExpression, type IRSlotsStatic, type IfIRNode, type InsertNodeIRNode, type KeyOverride, type NodeTransform, type OperationNode, type PrependNodeIRNode, type RootIRNode, type RootNode, type SetDynamicEventsIRNode, type SetDynamicPropsIRNode, type SetEventIRNode, type SetHtmlIRNode, type SetPropIRNode, type SetTemplateRefIRNode, type SetTextIRNode, type SlotBlockIRNode, type SlotOutletIRNode, type StructuralDirectiveTransform, TransformContext, type TransformOptions, type TransformPreset, type VaporDirectiveNode, compile, createStructuralDirectiveTransform, resolveDirectiveNode, resolveNode, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVFor, transformVHtml, transformVModel, transformVOn, transformVShow, transformVSlot };
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
1
  // src/compile.ts
2
- import { extend as extend5 } from "@vue/shared";
2
+ import { extend as extend5, isString as isString3 } from "@vue/shared";
3
3
  import {
4
4
  generate
5
5
  } from "@vue/compiler-vapor";
6
+ import { parse } from "@babel/parser";
6
7
 
7
8
  // src/transform.ts
8
9
  import {
9
10
  defaultOnError,
10
11
  defaultOnWarn
11
12
  } from "@vue/compiler-dom";
12
- import { EMPTY_OBJ, NOOP, extend, isArray } from "@vue/shared";
13
+ import { EMPTY_OBJ, NOOP, extend, isArray, isString as isString2 } from "@vue/shared";
13
14
 
14
15
  // src/ir/component.ts
15
16
  var IRDynamicPropsKind = /* @__PURE__ */ ((IRDynamicPropsKind2) => {
@@ -58,16 +59,47 @@ var DynamicFlag = /* @__PURE__ */ ((DynamicFlag2) => {
58
59
  })(DynamicFlag || {});
59
60
 
60
61
  // src/transforms/utils.ts
61
- import { createSimpleExpression as createSimpleExpression2 } from "@vue/compiler-dom";
62
+ import { createSimpleExpression } from "@vue/compiler-dom";
62
63
  import {
63
- arrowFunctionExpression,
64
- callExpression,
65
64
  jsxClosingFragment,
66
65
  jsxExpressionContainer,
67
66
  jsxFragment,
68
- jsxOpeningFragment,
69
- parenthesizedExpression
67
+ jsxOpeningFragment
70
68
  } from "@babel/types";
69
+ function newDynamic() {
70
+ return {
71
+ flags: 1 /* REFERENCED */,
72
+ children: []
73
+ };
74
+ }
75
+ function newBlock(node) {
76
+ return {
77
+ type: 1,
78
+ node,
79
+ dynamic: newDynamic(),
80
+ effect: [],
81
+ operation: [],
82
+ returns: [],
83
+ expressions: [],
84
+ tempId: 0
85
+ };
86
+ }
87
+ function createBranch(node, context, isVFor) {
88
+ context.node = node = wrapFragment(node);
89
+ const branch = newBlock(node);
90
+ const exitBlock = context.enterBlock(branch, isVFor);
91
+ context.reference();
92
+ return [branch, exitBlock];
93
+ }
94
+ function wrapFragment(node) {
95
+ if (node.type === "JSXFragment") {
96
+ return node;
97
+ }
98
+ return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), [
99
+ node.type === "JSXElement" ? node : jsxExpressionContainer(node)
100
+ ]);
101
+ }
102
+ var EMPTY_EXPRESSION = createSimpleExpression("", true);
71
103
 
72
104
  // src/utils.ts
73
105
  import { isGloballyAllowed, isHTMLTag, isSVGTag, isString } from "@vue/shared";
@@ -75,13 +107,16 @@ import {
75
107
  ElementTypes,
76
108
  Namespaces,
77
109
  NodeTypes,
78
- createSimpleExpression,
110
+ createSimpleExpression as createSimpleExpression2,
79
111
  isLiteralWhitelisted,
80
112
  walkIdentifiers
81
113
  } from "@vue/compiler-dom";
82
114
  import {
83
115
  isLiteral
84
116
  } from "@babel/types";
117
+ function propToExpression(prop, context) {
118
+ return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
119
+ }
85
120
  function isConstantExpression(exp) {
86
121
  return isLiteralWhitelisted(exp.content) || isGloballyAllowed(exp.content) || getLiteralExpressionValue(exp) !== null;
87
122
  }
@@ -162,7 +197,7 @@ function resolveExpression(node, context, effect = false) {
162
197
  return resolveSimpleExpression(source, isStatic, location, node);
163
198
  }
164
199
  function resolveSimpleExpression(source, isStatic, location, ast) {
165
- const result = createSimpleExpression(
200
+ const result = createSimpleExpression2(
166
201
  source,
167
202
  isStatic,
168
203
  resolveLocation(location, source)
@@ -248,7 +283,7 @@ function resolveDirectiveNode(node, context) {
248
283
  exp,
249
284
  arg,
250
285
  loc: resolveLocation(node.loc, context),
251
- modifiers: modifiers.map((modifier) => createSimpleExpression(modifier))
286
+ modifiers: modifiers.map((modifier) => createSimpleExpression2(modifier))
252
287
  };
253
288
  }
254
289
  function isJSXComponent(node) {
@@ -270,62 +305,10 @@ function findProp(expression, key) {
270
305
  }
271
306
  }
272
307
  }
273
- function isJSXElement(node) {
274
- return !!node && (node.type === "JSXElement" || node.type === "JSXFragment");
308
+ function getText(node, content) {
309
+ return content.ir.source.slice(node.start, node.end);
275
310
  }
276
311
 
277
- // src/transforms/utils.ts
278
- function newDynamic() {
279
- return {
280
- flags: 1 /* REFERENCED */,
281
- children: []
282
- };
283
- }
284
- function newBlock(node) {
285
- return {
286
- type: 1,
287
- node,
288
- dynamic: newDynamic(),
289
- effect: [],
290
- operation: [],
291
- returns: [],
292
- expressions: [],
293
- tempId: 0
294
- };
295
- }
296
- function createBranch(node, context, isVFor) {
297
- context.node = node = wrapFragment(node, isVFor);
298
- const branch = newBlock(node);
299
- const exitBlock = context.enterBlock(branch, isVFor);
300
- context.reference();
301
- return [branch, exitBlock];
302
- }
303
- function wrapFragment(node, isVFor) {
304
- if (node.type === "JSXFragment") {
305
- return node;
306
- }
307
- if (isVFor && (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression")) {
308
- if (isJSXElement(node.body)) {
309
- node = node.body;
310
- } else if (node.body.type === "BlockStatement" && node.body.body[0].type === "ReturnStatement" && node.body.body[0].argument) {
311
- node = node.body.body[0].argument;
312
- } else {
313
- node = {
314
- ...callExpression(
315
- parenthesizedExpression(arrowFunctionExpression([], node.body)),
316
- []
317
- ),
318
- start: node.body.start,
319
- end: node.body.end
320
- };
321
- }
322
- }
323
- return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), [
324
- node.type === "JSXElement" ? node : jsxExpressionContainer(node)
325
- ]);
326
- }
327
- var EMPTY_EXPRESSION = createSimpleExpression2("", true);
328
-
329
312
  // src/transform.ts
330
313
  var defaultOptions = {
331
314
  filename: "",
@@ -483,6 +466,31 @@ function transformNode(context) {
483
466
  context.registerTemplate();
484
467
  }
485
468
  }
469
+ function createStructuralDirectiveTransform(name, fn) {
470
+ const matches = (n) => isString2(name) ? n === name : name.includes(n);
471
+ return (node, context) => {
472
+ if (node.type === "JSXElement") {
473
+ const {
474
+ openingElement: { attributes, name: name2 }
475
+ } = node;
476
+ if (getText(name2, context) === "template" && findProp(node, "v-slot")) {
477
+ return;
478
+ }
479
+ const exitFns = [];
480
+ for (const prop of attributes) {
481
+ if (prop.type !== "JSXAttribute") continue;
482
+ const propName = getText(prop.name, context);
483
+ if (propName.startsWith("v-") && matches(propName.slice(2))) {
484
+ attributes.splice(attributes.indexOf(prop), 1);
485
+ const onExit = fn(node, prop, context);
486
+ if (onExit) exitFns.push(onExit);
487
+ break;
488
+ }
489
+ }
490
+ return exitFns;
491
+ }
492
+ };
493
+ }
486
494
 
487
495
  // src/transforms/transformElement.ts
488
496
  import { extend as extend2, isBuiltInDirective, isVoidTag, makeMap } from "@vue/shared";
@@ -1121,14 +1129,97 @@ var transformVHtml = (dir, node, context) => {
1121
1129
  );
1122
1130
  };
1123
1131
 
1132
+ // src/transforms/vFor.ts
1133
+ import {
1134
+ ErrorCodes as ErrorCodes2,
1135
+ createCompilerError as createCompilerError2,
1136
+ forAliasRE,
1137
+ isConstantNode
1138
+ } from "@vue/compiler-dom";
1139
+ import { parseExpression } from "@babel/parser";
1140
+ var transformVFor = createStructuralDirectiveTransform(
1141
+ "for",
1142
+ processFor
1143
+ );
1144
+ function processFor(node, dir, context) {
1145
+ if (!dir.value) {
1146
+ context.options.onError(
1147
+ createCompilerError2(
1148
+ ErrorCodes2.X_V_FOR_NO_EXPRESSION,
1149
+ resolveLocation(dir.loc, context)
1150
+ )
1151
+ );
1152
+ return;
1153
+ }
1154
+ if (!forAliasRE) {
1155
+ context.options.onError(
1156
+ createCompilerError2(
1157
+ ErrorCodes2.X_V_FOR_MALFORMED_EXPRESSION,
1158
+ resolveLocation(dir.loc, context)
1159
+ )
1160
+ );
1161
+ return;
1162
+ }
1163
+ let value, index, key, source;
1164
+ if (dir.value.type === "JSXExpressionContainer" && dir.value.expression.type === "BinaryExpression") {
1165
+ if (dir.value.expression.left.type === "SequenceExpression") {
1166
+ const expressions = dir.value.expression.left.expressions;
1167
+ value = expressions[0] && resolveValueExpression(expressions[0], context);
1168
+ key = expressions[1] && resolveExpression(expressions[1], context);
1169
+ index = expressions[2] && resolveExpression(expressions[2], context);
1170
+ } else {
1171
+ value = resolveValueExpression(dir.value.expression.left, context);
1172
+ }
1173
+ source = resolveExpression(dir.value.expression.right, context);
1174
+ }
1175
+ const keyProp = findProp(node, "key");
1176
+ const keyProperty = keyProp && propToExpression(keyProp, context);
1177
+ const isComponent = isJSXComponent(node);
1178
+ const id = context.reference();
1179
+ context.dynamic.flags |= 2 /* NON_TEMPLATE */ | 4 /* INSERT */;
1180
+ const [render, exitBlock] = createBranch(node, context, true);
1181
+ return () => {
1182
+ exitBlock();
1183
+ const { parent } = context;
1184
+ const isOnlyChild = parent && parent.block.node !== parent.node && parent.node.children.length === 1;
1185
+ context.registerOperation({
1186
+ type: 17 /* FOR */,
1187
+ id,
1188
+ source,
1189
+ value,
1190
+ key,
1191
+ index,
1192
+ keyProp: keyProperty,
1193
+ render,
1194
+ once: context.inVOnce || !!(source.ast && isConstantNode(source.ast, {})),
1195
+ component: isComponent,
1196
+ onlyChild: !!isOnlyChild
1197
+ });
1198
+ };
1199
+ }
1200
+ function resolveValueExpression(node, context) {
1201
+ const text = getText(node, context);
1202
+ return node.type === "Identifier" ? resolveSimpleExpression(text, false, node.loc) : resolveSimpleExpression(
1203
+ text,
1204
+ false,
1205
+ node.loc,
1206
+ parseExpression(`(${text})=>{}`, {
1207
+ plugins: ["typescript"]
1208
+ })
1209
+ );
1210
+ }
1211
+
1124
1212
  // src/compile.ts
1125
- function compile(root, options = {}) {
1213
+ function compile(source, options = {}) {
1126
1214
  const resolvedOptions = extend5({}, options, {
1127
1215
  inline: true,
1128
1216
  prefixIdentifiers: false,
1129
1217
  expressionPlugins: options.expressionPlugins || ["jsx"]
1130
1218
  });
1131
- if (options.isTS) {
1219
+ if (!resolvedOptions.source && isString3(source)) {
1220
+ resolvedOptions.source = source;
1221
+ }
1222
+ if (resolvedOptions.isTS) {
1132
1223
  const { expressionPlugins } = resolvedOptions;
1133
1224
  if (!expressionPlugins.includes("typescript")) {
1134
1225
  resolvedOptions.expressionPlugins = [
@@ -1137,11 +1228,15 @@ function compile(root, options = {}) {
1137
1228
  ];
1138
1229
  }
1139
1230
  }
1231
+ const root = isString3(source) ? parse(source, {
1232
+ sourceType: "module",
1233
+ plugins: resolvedOptions.expressionPlugins
1234
+ }).program.body[0].expression : source;
1140
1235
  const children = root.type === "JSXFragment" ? root.children : root.type === "JSXElement" ? [root] : [];
1141
1236
  const ast = {
1142
1237
  type: 0 /* ROOT */,
1143
1238
  children,
1144
- source: options.source || ""
1239
+ source: resolvedOptions.source || ""
1145
1240
  };
1146
1241
  const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
1147
1242
  const ir = transform(
@@ -1149,13 +1244,13 @@ function compile(root, options = {}) {
1149
1244
  extend5({}, resolvedOptions, {
1150
1245
  nodeTransforms: [
1151
1246
  ...nodeTransforms,
1152
- ...options.nodeTransforms || []
1247
+ ...resolvedOptions.nodeTransforms || []
1153
1248
  // user transforms
1154
1249
  ],
1155
1250
  directiveTransforms: extend5(
1156
1251
  {},
1157
1252
  directiveTransforms,
1158
- options.directiveTransforms || {}
1253
+ resolvedOptions.directiveTransforms || {}
1159
1254
  // user transforms
1160
1255
  )
1161
1256
  })
@@ -1165,6 +1260,7 @@ function compile(root, options = {}) {
1165
1260
  function getBaseTransformPreset() {
1166
1261
  return [
1167
1262
  [
1263
+ transformVFor,
1168
1264
  transformTemplateRef,
1169
1265
  transformText,
1170
1266
  transformElement,
@@ -1187,6 +1283,7 @@ export {
1187
1283
  IRSlotType,
1188
1284
  TransformContext,
1189
1285
  compile,
1286
+ createStructuralDirectiveTransform,
1190
1287
  generate,
1191
1288
  resolveDirectiveNode,
1192
1289
  resolveNode,
@@ -1197,6 +1294,7 @@ export {
1197
1294
  transformTemplateRef,
1198
1295
  transformText,
1199
1296
  transformVBind,
1297
+ transformVFor,
1200
1298
  transformVHtml,
1201
1299
  transformVModel,
1202
1300
  transformVOn,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-jsx-vapor/compiler",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Vue JSX Vapor Compiler",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -48,13 +48,11 @@
48
48
  "./*": "./*"
49
49
  },
50
50
  "dependencies": {
51
- "@babel/types": "^7.26.7",
52
- "@vue/compiler-dom": "https://pkg.pr.new/@vue/compiler-dom@dc910ac",
53
- "@vue/compiler-vapor": "https://pkg.pr.new/@vue/compiler-vapor@1e41c1d",
54
- "@vue/shared": "https://pkg.pr.new/@vue/shared@dc910ac"
55
- },
56
- "devDependencies": {
57
- "@babel/parser": "^7.26.7"
51
+ "@babel/parser": "^7.26.8",
52
+ "@babel/types": "^7.26.8",
53
+ "@vue/compiler-dom": "https://pkg.pr.new/@vue/compiler-dom@ce35a8c",
54
+ "@vue/compiler-vapor": "https://pkg.pr.new/@vue/compiler-vapor@ce35a8c",
55
+ "@vue/shared": "https://pkg.pr.new/@vue/shared@ce35a8c"
58
56
  },
59
57
  "scripts": {
60
58
  "build": "tsup",