@mbler/mcx-core 0.1.2-rc.9 → 0.1.3-rc.2
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/README.md +40 -40
- package/dist/chunk-6Ep1yQYe.js +16 -0
- package/dist/chunk-D0rfrjR5.js +21 -0
- package/dist/index.d.ts +8 -11
- package/dist/index.js +508 -377
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
- package/client.d.ts +0 -17
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { n as __require, t as __exportAll } from "./chunk-
|
|
1
|
+
import { n as __require, t as __exportAll } from "./chunk-D0rfrjR5.js";
|
|
2
2
|
import * as Module from "node:module";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
+
import { NodeTypes, baseParse } from "@vue/compiler-core";
|
|
4
5
|
import * as path from "node:path";
|
|
5
6
|
import { extname } from "node:path";
|
|
6
7
|
import * as t from "@babel/types";
|
|
@@ -16,295 +17,165 @@ import * as vm from "node:vm";
|
|
|
16
17
|
import { Buffer } from "node:buffer";
|
|
17
18
|
import { existsSync, readFileSync } from "node:fs";
|
|
18
19
|
import { styleText } from "node:util";
|
|
19
|
-
import { BlockComponent, BlockComponent as BlockComponent$1, EntityComponent, EntityComponent as EntityComponent$1, GIFImageComponent, GIFImageComponent as GIFImageComponent$1, ItemComponent, ItemComponent as ItemComponent$1, JPGImageComponent, JPGImageComponent as JPGImageComponent$1, PNGImageComponent, PNGImageComponent as PNGImageComponent$1, SVGImageComponent, SVGImageComponent as SVGImageComponent$1 } from "@mbler/mcx-component";
|
|
20
20
|
import MagicString from "magic-string";
|
|
21
|
+
|
|
21
22
|
//#region src/ast/tag.ts
|
|
22
|
-
function
|
|
23
|
+
function getExpressionContent(expr) {
|
|
24
|
+
return expr?.content ?? "true";
|
|
25
|
+
}
|
|
26
|
+
/** Convert absolute character offset in source to MCX position (line: 1-indexed, column: 0-indexed) */
|
|
27
|
+
function absOffsetToMCXPos(source, absOffset) {
|
|
28
|
+
let line = 1;
|
|
29
|
+
let col = 0;
|
|
30
|
+
const len = Math.min(absOffset, source.length);
|
|
31
|
+
for (let i = 0; i < len; i++) if (source.charCodeAt(i) === 10) {
|
|
32
|
+
line++;
|
|
33
|
+
col = 0;
|
|
34
|
+
} else col++;
|
|
23
35
|
return {
|
|
24
36
|
line,
|
|
25
|
-
column
|
|
37
|
+
column: col
|
|
26
38
|
};
|
|
27
39
|
}
|
|
28
|
-
var
|
|
29
|
-
text;
|
|
30
|
-
constructor(text) {
|
|
31
|
-
this.text = text;
|
|
32
|
-
}
|
|
33
|
-
*splitTokens() {
|
|
34
|
-
const text = this.text;
|
|
35
|
-
let i = 0;
|
|
36
|
-
let line = 1;
|
|
37
|
-
let column = 0;
|
|
38
|
-
const len = text.length;
|
|
39
|
-
while (i < len) if (text[i] === "<") {
|
|
40
|
-
if (text.startsWith("!--", i + 1)) {
|
|
41
|
-
const commentStart = i;
|
|
42
|
-
const tokenStartLine = line;
|
|
43
|
-
const tokenStartColumn = column;
|
|
44
|
-
const endIdx = text.indexOf("-->", i + 4);
|
|
45
|
-
const commentEnd = endIdx === -1 ? len - 1 : endIdx + 2;
|
|
46
|
-
for (let j = i; j <= commentEnd; j++) if (text[j] === "\n") {
|
|
47
|
-
line++;
|
|
48
|
-
column = 0;
|
|
49
|
-
} else column++;
|
|
50
|
-
yield {
|
|
51
|
-
data: text.slice(commentStart, commentEnd + 1),
|
|
52
|
-
type: "Comment",
|
|
53
|
-
start: createPos(tokenStartLine, tokenStartColumn),
|
|
54
|
-
end: createPos(line, column)
|
|
55
|
-
};
|
|
56
|
-
i = commentEnd + 1;
|
|
57
|
-
if (i < len && text[i] === ">") column++;
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
const tokenStart = i;
|
|
61
|
-
const tokenStartLine = line;
|
|
62
|
-
const tokenStartColumn = column;
|
|
63
|
-
let j = i + 1;
|
|
64
|
-
let sawGt = false;
|
|
65
|
-
for (; j < len; j++) {
|
|
66
|
-
const c = text[j];
|
|
67
|
-
if (c === ">") {
|
|
68
|
-
sawGt = true;
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
if (c === "\n") {
|
|
72
|
-
line++;
|
|
73
|
-
column = 0;
|
|
74
|
-
} else column++;
|
|
75
|
-
}
|
|
76
|
-
const buffer = text.slice(tokenStart, sawGt ? j + 1 : len);
|
|
77
|
-
yield {
|
|
78
|
-
data: buffer,
|
|
79
|
-
type: buffer.startsWith("</") ? "TagEnd" : "Tag",
|
|
80
|
-
start: createPos(tokenStartLine, tokenStartColumn),
|
|
81
|
-
end: createPos(line, column)
|
|
82
|
-
};
|
|
83
|
-
i = sawGt ? j + 1 : len;
|
|
84
|
-
if (sawGt) column++;
|
|
85
|
-
} else {
|
|
86
|
-
const contentStart = i;
|
|
87
|
-
const contentStartLine = line;
|
|
88
|
-
const contentStartColumn = column;
|
|
89
|
-
let j = i;
|
|
90
|
-
for (; j < len; j++) {
|
|
91
|
-
const c = text[j];
|
|
92
|
-
if (c === "<") break;
|
|
93
|
-
if (c === "\n") {
|
|
94
|
-
line++;
|
|
95
|
-
column = 0;
|
|
96
|
-
} else column++;
|
|
97
|
-
}
|
|
98
|
-
yield {
|
|
99
|
-
data: text.slice(contentStart, j),
|
|
100
|
-
type: "Content",
|
|
101
|
-
start: createPos(contentStartLine, contentStartColumn),
|
|
102
|
-
end: createPos(line, j > contentStart ? column - 1 : column)
|
|
103
|
-
};
|
|
104
|
-
i = j;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
var Lexer$1 = class {
|
|
40
|
+
var McxAst = class McxAst {
|
|
109
41
|
text;
|
|
110
42
|
includeComments;
|
|
111
|
-
booleanProxyCache;
|
|
112
43
|
constructor(text, includeComments = false) {
|
|
113
44
|
this.text = text;
|
|
114
45
|
this.includeComments = includeComments;
|
|
115
|
-
this.booleanProxyCache = /* @__PURE__ */ new WeakMap();
|
|
116
46
|
}
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
47
|
+
parseAST() {
|
|
48
|
+
const ast = baseParse(this.text, {
|
|
49
|
+
comments: true,
|
|
50
|
+
whitespace: "preserve"
|
|
51
|
+
});
|
|
52
|
+
const result = [];
|
|
53
|
+
for (const child of ast.children) {
|
|
54
|
+
const node = this.convertTemplateChild(child);
|
|
55
|
+
if (node && node.type === "TagNode") result.push(node);
|
|
122
56
|
}
|
|
57
|
+
return result;
|
|
123
58
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
59
|
+
convertTemplateChild(node) {
|
|
60
|
+
if (node.type === NodeTypes.ELEMENT) return this.convertVueElement(node);
|
|
61
|
+
if (node.type === NodeTypes.TEXT) {
|
|
62
|
+
const textNode = node;
|
|
63
|
+
if (textNode.content.trim()) return {
|
|
64
|
+
data: textNode.content,
|
|
65
|
+
type: "TagContent"
|
|
66
|
+
};
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (node.type === NodeTypes.INTERPOLATION) return {
|
|
70
|
+
data: `{{ ${getExpressionContent(node.content)} }}`,
|
|
71
|
+
type: "TagContent"
|
|
72
|
+
};
|
|
73
|
+
if (this.includeComments && node.type === NodeTypes.COMMENT) {
|
|
74
|
+
const commentNode = node;
|
|
75
|
+
return {
|
|
76
|
+
data: commentNode.content,
|
|
77
|
+
type: "Comment",
|
|
78
|
+
loc: {
|
|
79
|
+
start: {
|
|
80
|
+
line: commentNode.loc.start.line,
|
|
81
|
+
column: commentNode.loc.start.column
|
|
82
|
+
},
|
|
83
|
+
end: {
|
|
84
|
+
line: commentNode.loc.end.line,
|
|
85
|
+
column: commentNode.loc.end.column
|
|
86
|
+
}
|
|
148
87
|
}
|
|
149
|
-
}
|
|
150
|
-
this.booleanProxyCache.set(this, proxy);
|
|
88
|
+
};
|
|
151
89
|
}
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
/** Parser - 负责将Token流解析为AST */
|
|
156
|
-
var Parser$1 = class {
|
|
157
|
-
lexer;
|
|
158
|
-
constructor(lexer) {
|
|
159
|
-
this.lexer = lexer;
|
|
90
|
+
return null;
|
|
160
91
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const char = tagContent[i];
|
|
175
|
-
if (isTagName) {
|
|
176
|
-
if (char === " " || char === ">") {
|
|
177
|
-
name = currentKey.trim();
|
|
178
|
-
currentKey = "";
|
|
179
|
-
isTagName = false;
|
|
180
|
-
if (char === ">") break;
|
|
181
|
-
} else currentKey += char;
|
|
182
|
-
continue;
|
|
92
|
+
convertVueElement(node) {
|
|
93
|
+
const attrs = {};
|
|
94
|
+
for (const prop of node.props) if (prop.type === NodeTypes.ATTRIBUTE) {
|
|
95
|
+
const attr = prop;
|
|
96
|
+
attrs[attr.name] = attr.value?.content ?? "true";
|
|
97
|
+
} else if (prop.type === NodeTypes.DIRECTIVE) {
|
|
98
|
+
const dir = prop;
|
|
99
|
+
if (dir.name === "bind") {
|
|
100
|
+
const key = `:${getExpressionContent(dir.arg)}`;
|
|
101
|
+
attrs[key] = getExpressionContent(dir.exp);
|
|
102
|
+
} else if (dir.name === "on") {
|
|
103
|
+
const key = `@${getExpressionContent(dir.arg)}`;
|
|
104
|
+
attrs[key] = "true";
|
|
183
105
|
}
|
|
184
|
-
if (inValue) if (char === quoteChar && (currentValue.length === 0 || currentValue[currentValue.length - 1] !== "\\")) {
|
|
185
|
-
attributes[currentKey.trim()] = currentValue;
|
|
186
|
-
currentKey = "";
|
|
187
|
-
currentValue = "";
|
|
188
|
-
inKey = true;
|
|
189
|
-
inValue = false;
|
|
190
|
-
quoteChar = null;
|
|
191
|
-
} else currentValue += char;
|
|
192
|
-
else if (char === "=" && inKey) {
|
|
193
|
-
inKey = false;
|
|
194
|
-
inValue = true;
|
|
195
|
-
const nextIndex = i + 1;
|
|
196
|
-
const nextChar = nextIndex < tagContent.length ? tagContent[nextIndex] : " ";
|
|
197
|
-
if (nextChar === "\"" || nextChar === "'") {
|
|
198
|
-
quoteChar = nextChar;
|
|
199
|
-
i = nextIndex;
|
|
200
|
-
} else quoteChar = " ";
|
|
201
|
-
} else if (char === " " && inKey && currentKey) {
|
|
202
|
-
attributes[currentKey.trim()] = "true";
|
|
203
|
-
currentKey = "";
|
|
204
|
-
} else if (inKey) currentKey += char;
|
|
205
106
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const rawTokens = Array.from(this.lexer.tokenStream());
|
|
219
|
-
const root = [];
|
|
220
|
-
const stack = [];
|
|
221
|
-
for (let idx = 0; idx < rawTokens.length; idx++) {
|
|
222
|
-
const token = rawTokens[idx];
|
|
223
|
-
if (!token) continue;
|
|
224
|
-
if (token.type === "Content") {
|
|
225
|
-
const contentNode = {
|
|
226
|
-
data: token.data,
|
|
227
|
-
type: "TagContent"
|
|
228
|
-
};
|
|
229
|
-
if (stack.length > 0) stack[stack.length - 1].content.push(contentNode);
|
|
230
|
-
else root.push(contentNode);
|
|
231
|
-
} else if (token.type === "Comment") {
|
|
232
|
-
const commentNode = {
|
|
233
|
-
data: token.data,
|
|
234
|
-
type: "Comment",
|
|
235
|
-
loc: {
|
|
236
|
-
start: { ...token.start },
|
|
237
|
-
end: { ...token.end }
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
if (stack.length > 0) stack[stack.length - 1].content.push(commentNode);
|
|
241
|
-
else root.push(commentNode);
|
|
242
|
-
} else if (token.type === "Tag") {
|
|
243
|
-
const inner = token.data.slice(1, -1).trim();
|
|
244
|
-
const isSelfClosing = inner.endsWith("/");
|
|
245
|
-
const arr = this.parseAttributes(isSelfClosing ? inner.slice(0, -1).trim() : inner);
|
|
246
|
-
const node = {
|
|
247
|
-
start: token,
|
|
248
|
-
name: arr.name,
|
|
249
|
-
arr: arr.arr,
|
|
250
|
-
content: [],
|
|
251
|
-
end: null,
|
|
252
|
-
type: "TagNode",
|
|
253
|
-
loc: {
|
|
254
|
-
start: { ...token.start },
|
|
255
|
-
end: { ...token.end }
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
if (isSelfClosing) if (stack.length > 0) stack[stack.length - 1].content.push(node);
|
|
259
|
-
else yield node;
|
|
260
|
-
else stack.push(node);
|
|
261
|
-
} else if (token.type === "TagEnd") {
|
|
262
|
-
const name = token.data.replace(/^<\/\s*/, "").replace(/\s*>$/, "").trim();
|
|
263
|
-
for (let s = stack.length - 1; s >= 0; s--) {
|
|
264
|
-
const candidate = stack[s];
|
|
265
|
-
if (candidate && candidate.name === name) {
|
|
266
|
-
candidate.end = token;
|
|
267
|
-
candidate.loc.end = { ...token.end };
|
|
268
|
-
stack.splice(s, 1);
|
|
269
|
-
if (stack.length > 0) stack[stack.length - 1].content.push(candidate);
|
|
270
|
-
else yield candidate;
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
107
|
+
const children = this.convertVueChildren(node.children);
|
|
108
|
+
const fullSource = this.text;
|
|
109
|
+
const baseOffset = node.loc.start.offset;
|
|
110
|
+
const elementSource = node.loc.source;
|
|
111
|
+
let openEnd = elementSource.length;
|
|
112
|
+
let inQuote = null;
|
|
113
|
+
for (let i = 0; i < elementSource.length; i++) {
|
|
114
|
+
const c = elementSource[i];
|
|
115
|
+
if (inQuote) {
|
|
116
|
+
if (c === "\\") {
|
|
117
|
+
i++;
|
|
118
|
+
continue;
|
|
273
119
|
}
|
|
120
|
+
if (c === inQuote) inQuote = null;
|
|
121
|
+
} else if (c === "\"" || c === "'") inQuote = c;
|
|
122
|
+
else if (c === ">") {
|
|
123
|
+
openEnd = i + 1;
|
|
124
|
+
break;
|
|
274
125
|
}
|
|
275
126
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
127
|
+
let closeStart = -1;
|
|
128
|
+
if (!node.isSelfClosing) {
|
|
129
|
+
for (let i = elementSource.length - 2; i >= 0; i--) if (elementSource[i] === "<" && elementSource[i + 1] === "/") {
|
|
130
|
+
closeStart = i;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
280
133
|
}
|
|
134
|
+
const openTagStartAbs = baseOffset;
|
|
135
|
+
const openTagEndAbs = baseOffset + openEnd;
|
|
136
|
+
let endToken = null;
|
|
137
|
+
if (closeStart >= 0) {
|
|
138
|
+
const closeTagStartAbs = baseOffset + closeStart;
|
|
139
|
+
const closeTagEndAbs = baseOffset + elementSource.length;
|
|
140
|
+
endToken = {
|
|
141
|
+
data: elementSource.slice(closeStart),
|
|
142
|
+
type: "TagEnd",
|
|
143
|
+
start: absOffsetToMCXPos(fullSource, closeTagStartAbs),
|
|
144
|
+
end: absOffsetToMCXPos(fullSource, closeTagEndAbs)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
start: {
|
|
149
|
+
data: elementSource.slice(0, openEnd),
|
|
150
|
+
type: "Tag",
|
|
151
|
+
start: absOffsetToMCXPos(fullSource, openTagStartAbs),
|
|
152
|
+
end: absOffsetToMCXPos(fullSource, openTagEndAbs)
|
|
153
|
+
},
|
|
154
|
+
name: node.tag,
|
|
155
|
+
arr: attrs,
|
|
156
|
+
content: children,
|
|
157
|
+
end: endToken,
|
|
158
|
+
loc: {
|
|
159
|
+
start: {
|
|
160
|
+
line: node.loc.start.line,
|
|
161
|
+
column: node.loc.start.column
|
|
162
|
+
},
|
|
163
|
+
end: {
|
|
164
|
+
line: node.loc.end.line,
|
|
165
|
+
column: node.loc.end.column
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
type: "TagNode"
|
|
169
|
+
};
|
|
281
170
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
constructor(text, includeComments = false) {
|
|
290
|
-
this.text = text;
|
|
291
|
-
this.includeComments = includeComments;
|
|
292
|
-
}
|
|
293
|
-
getAST() {
|
|
294
|
-
const parser = new Parser$1(new Lexer$1(this.text, this.includeComments));
|
|
295
|
-
return Array.from(parser.parseAST());
|
|
296
|
-
}
|
|
297
|
-
get data() {
|
|
298
|
-
return this.getAST();
|
|
299
|
-
}
|
|
300
|
-
parseAST() {
|
|
301
|
-
return this.getAST();
|
|
171
|
+
convertVueChildren(children) {
|
|
172
|
+
const result = [];
|
|
173
|
+
for (const child of children) {
|
|
174
|
+
const node = this.convertTemplateChild(child);
|
|
175
|
+
if (node) result.push(node);
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
302
178
|
}
|
|
303
|
-
/**
|
|
304
|
-
* 生成代码字符串
|
|
305
|
-
* @param node 代码的AST节点
|
|
306
|
-
* @returns 代码字符串
|
|
307
|
-
*/
|
|
308
179
|
static generateCode(node) {
|
|
309
180
|
let code = `<${node.name}`;
|
|
310
181
|
for (const [key, value] of Object.entries(node.arr || {})) if (value === "true") code += ` ${key}`;
|
|
@@ -312,6 +183,7 @@ var McxAst = class McxAst {
|
|
|
312
183
|
code += ">";
|
|
313
184
|
const contentArr = node.content;
|
|
314
185
|
if (Array.isArray(contentArr)) for (const item of contentArr) if (item.type === "TagContent") code += item.data;
|
|
186
|
+
else if (item.type === "Comment") code += item.data;
|
|
315
187
|
else code += McxAst.generateCode(item);
|
|
316
188
|
code += `</${node.name}>`;
|
|
317
189
|
return code;
|
|
@@ -330,31 +202,32 @@ var MCXUtils = class MCXUtils {
|
|
|
330
202
|
static isAttributeMap(obj) {
|
|
331
203
|
return !!obj && typeof obj === "object" && !Array.isArray(obj);
|
|
332
204
|
}
|
|
333
|
-
static
|
|
334
|
-
return
|
|
205
|
+
static isParseNode(node) {
|
|
206
|
+
return Array.isArray(node) && node.every(MCXUtils.isTagNode);
|
|
335
207
|
}
|
|
336
|
-
static
|
|
337
|
-
return
|
|
208
|
+
static isToken(_obj) {
|
|
209
|
+
return false;
|
|
338
210
|
}
|
|
339
|
-
static
|
|
340
|
-
return
|
|
211
|
+
static isTagToken(_obj) {
|
|
212
|
+
return false;
|
|
341
213
|
}
|
|
342
|
-
static
|
|
343
|
-
return
|
|
214
|
+
static isTagEndToken(_obj) {
|
|
215
|
+
return false;
|
|
344
216
|
}
|
|
345
|
-
static
|
|
346
|
-
return
|
|
217
|
+
static isContentToken(_obj) {
|
|
218
|
+
return false;
|
|
347
219
|
}
|
|
348
|
-
static
|
|
349
|
-
return
|
|
220
|
+
static isCommentToken(_obj) {
|
|
221
|
+
return false;
|
|
350
222
|
}
|
|
351
|
-
static
|
|
352
|
-
return
|
|
223
|
+
static isBaseToken(_obj) {
|
|
224
|
+
return false;
|
|
353
225
|
}
|
|
354
|
-
static
|
|
355
|
-
return
|
|
226
|
+
static isTokenType(_value) {
|
|
227
|
+
return false;
|
|
356
228
|
}
|
|
357
229
|
};
|
|
230
|
+
|
|
358
231
|
//#endregion
|
|
359
232
|
//#region src/ast/prop.ts
|
|
360
233
|
const STATUS = [0, 1];
|
|
@@ -404,12 +277,14 @@ function PropParser(code) {
|
|
|
404
277
|
const lexer = new Lexer(code);
|
|
405
278
|
return Array.from(lexer.tokenize());
|
|
406
279
|
}
|
|
280
|
+
|
|
407
281
|
//#endregion
|
|
408
282
|
//#region src/ast/index.ts
|
|
409
283
|
var ast_default = {
|
|
410
284
|
tag: McxAst,
|
|
411
285
|
prop: PropParser
|
|
412
286
|
};
|
|
287
|
+
|
|
413
288
|
//#endregion
|
|
414
289
|
//#region src/compile-mcx/types.ts
|
|
415
290
|
const _MCXstructureLocComponentTypes = {
|
|
@@ -417,6 +292,7 @@ const _MCXstructureLocComponentTypes = {
|
|
|
417
292
|
blocks: "block",
|
|
418
293
|
entities: "entity"
|
|
419
294
|
};
|
|
295
|
+
|
|
420
296
|
//#endregion
|
|
421
297
|
//#region src/compile-mcx/compiler/compileData.ts
|
|
422
298
|
var JsCompileData = class {
|
|
@@ -449,6 +325,7 @@ var MCXCompileData = class {
|
|
|
449
325
|
this.File = dir;
|
|
450
326
|
}
|
|
451
327
|
};
|
|
328
|
+
|
|
452
329
|
//#endregion
|
|
453
330
|
//#region src/compile-mcx/compiler/utils.ts
|
|
454
331
|
var Utils$1 = class Utils$1 {
|
|
@@ -525,6 +402,7 @@ var Utils$1 = class Utils$1 {
|
|
|
525
402
|
};
|
|
526
403
|
}
|
|
527
404
|
};
|
|
405
|
+
|
|
528
406
|
//#endregion
|
|
529
407
|
//#region src/compile-mcx/compiler/index.ts
|
|
530
408
|
var compiler_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -724,7 +602,8 @@ var CompileMCX = class {
|
|
|
724
602
|
isLoad: false
|
|
725
603
|
},
|
|
726
604
|
Component: {},
|
|
727
|
-
UI: null
|
|
605
|
+
UI: null,
|
|
606
|
+
Form: null
|
|
728
607
|
};
|
|
729
608
|
getCompileData() {
|
|
730
609
|
return this.CompileData;
|
|
@@ -756,6 +635,7 @@ var CompileMCX = class {
|
|
|
756
635
|
script: "",
|
|
757
636
|
Event: null,
|
|
758
637
|
ui: null,
|
|
638
|
+
form: null,
|
|
759
639
|
Component: {}
|
|
760
640
|
};
|
|
761
641
|
for (const node of this.mcxCode || []) {
|
|
@@ -781,6 +661,9 @@ var CompileMCX = class {
|
|
|
781
661
|
} else if (node.name == "Ui") {
|
|
782
662
|
if (component || temp.Event || temp.ui) throw makeError("[compile error]: UI node can't use with component or event or other ui node", node);
|
|
783
663
|
temp.ui = node;
|
|
664
|
+
} else if (node.name == "Form") {
|
|
665
|
+
if (component || temp.Event || temp.form || temp.ui) throw makeError("[compile error]: Form node can't use with component, event, Ui, or other Form node", node);
|
|
666
|
+
temp.form = node;
|
|
784
667
|
}
|
|
785
668
|
}
|
|
786
669
|
if (!temp.script) throw makeError("[compile error]: mcx must has a script");
|
|
@@ -803,6 +686,7 @@ var CompileMCX = class {
|
|
|
803
686
|
this.handlerChildComponent(subNode);
|
|
804
687
|
}
|
|
805
688
|
if (temp.ui) this.tempLoc.UI = temp.ui;
|
|
689
|
+
if (temp.form) this.tempLoc.Form = temp.form;
|
|
806
690
|
}
|
|
807
691
|
handlerChildComponent(node) {
|
|
808
692
|
const name = node.name;
|
|
@@ -868,6 +752,7 @@ const compileMCXFn = ((mcxCode) => {
|
|
|
868
752
|
});
|
|
869
753
|
compileJSFn.cache = {};
|
|
870
754
|
compileMCXFn.cache = {};
|
|
755
|
+
|
|
871
756
|
//#endregion
|
|
872
757
|
//#region src/transforms/config.ts
|
|
873
758
|
var config_default = {
|
|
@@ -877,6 +762,7 @@ var config_default = {
|
|
|
877
762
|
eventExtendsName: "McxExtendsBy",
|
|
878
763
|
paramCtx: "__mcx__ctx"
|
|
879
764
|
};
|
|
765
|
+
|
|
880
766
|
//#endregion
|
|
881
767
|
//#region src/utils.ts
|
|
882
768
|
var Utils = class Utils {
|
|
@@ -925,12 +811,14 @@ var Utils = class Utils {
|
|
|
925
811
|
return path.isAbsolute(inputPath) ? inputPath : path.join(baseDir, inputPath);
|
|
926
812
|
}
|
|
927
813
|
};
|
|
814
|
+
|
|
928
815
|
//#endregion
|
|
929
816
|
//#region src/transforms/file_id.ts
|
|
930
817
|
let fileIdCounter = 0;
|
|
931
818
|
function generateFileId() {
|
|
932
819
|
return `__file_import_${fileIdCounter++}__`;
|
|
933
820
|
}
|
|
821
|
+
|
|
934
822
|
//#endregion
|
|
935
823
|
//#region src/transforms/utils.ts
|
|
936
824
|
function extractVarDefIdList(express) {
|
|
@@ -1049,110 +937,328 @@ function _enableWithData() {
|
|
|
1049
937
|
fn.prototype.enable = d;
|
|
1050
938
|
return fn;
|
|
1051
939
|
}
|
|
940
|
+
function processDefineProp(code, mode, impBody) {
|
|
941
|
+
const obsMap = {};
|
|
942
|
+
for (const stmt of code.node.body) if (t.isVariableDeclaration(stmt)) {
|
|
943
|
+
for (const decl of stmt.declarations) if (t.isCallExpression(decl.init) && t.isIdentifier(decl.init.callee) && decl.init.callee.name === "defineProp" && t.isIdentifier(decl.id)) {
|
|
944
|
+
const varName = decl.id.name;
|
|
945
|
+
const defaultVal = decl.init.arguments[1] || decl.init.arguments[0];
|
|
946
|
+
let defaultExpr = t.nullLiteral();
|
|
947
|
+
if (defaultVal && t.isExpression(defaultVal)) defaultExpr = defaultVal;
|
|
948
|
+
const propAccess = t.logicalExpression("??", t.memberExpression(t.memberExpression(t.identifier("__mcx__ctx"), t.identifier("$prop")), t.identifier(varName)), defaultExpr);
|
|
949
|
+
if (mode === "ui") {
|
|
950
|
+
const obsType = inferObservableType(defaultExpr);
|
|
951
|
+
if (obsType) {
|
|
952
|
+
obsMap[obsType] = obsType;
|
|
953
|
+
decl.init = t.newExpression(t.identifier(obsType), [propAccess]);
|
|
954
|
+
} else decl.init = propAccess;
|
|
955
|
+
} else decl.init = propAccess;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
if (mode === "ui" && Object.keys(obsMap).length > 0) impBody.push(t.importDeclaration(Object.values(obsMap).map((name) => t.importSpecifier(t.identifier(name), t.identifier(name))), t.stringLiteral("@minecraft/server-ui")));
|
|
959
|
+
}
|
|
960
|
+
function inferObservableType(expr) {
|
|
961
|
+
if (t.isStringLiteral(expr)) return "ObservableString";
|
|
962
|
+
if (t.isBooleanLiteral(expr)) return "ObservableBoolean";
|
|
963
|
+
if (t.isNumericLiteral(expr)) return "ObservableNumber";
|
|
964
|
+
if (t.isNullLiteral(expr)) return "ObservableString";
|
|
965
|
+
if (t.isIdentifier(expr) && expr.name === "undefined") return "ObservableString";
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
function collectSetupDeclarations(code, existingReturnMembers) {
|
|
969
|
+
const result = [];
|
|
970
|
+
const seen = new Set(existingReturnMembers);
|
|
971
|
+
for (const stmt of code.node.body) {
|
|
972
|
+
if (!t.isDeclaration(stmt)) continue;
|
|
973
|
+
const ids = extractIdList(stmt);
|
|
974
|
+
for (const id of ids) if (id && !seen.has(id)) {
|
|
975
|
+
seen.add(id);
|
|
976
|
+
result.push(t.objectProperty(t.identifier(id), t.identifier(id)));
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return result;
|
|
980
|
+
}
|
|
981
|
+
function processHooks(code) {
|
|
982
|
+
let startup = null;
|
|
983
|
+
let mounted = null;
|
|
984
|
+
const toRemove = [];
|
|
985
|
+
for (let i = 0; i < code.node.body.length; i++) {
|
|
986
|
+
const stmt = code.node.body[i];
|
|
987
|
+
if (!stmt) continue;
|
|
988
|
+
if (t.isExpressionStatement(stmt) && t.isCallExpression(stmt.expression)) {
|
|
989
|
+
const call = stmt.expression;
|
|
990
|
+
if (t.isIdentifier(call.callee)) {
|
|
991
|
+
const name = call.callee.name;
|
|
992
|
+
if (name === "onStartup" || name === "onMounted") {
|
|
993
|
+
if (call.arguments.length > 0) {
|
|
994
|
+
const cb = call.arguments[0];
|
|
995
|
+
if (t.isExpression(cb)) if (name === "onStartup") startup = cb;
|
|
996
|
+
else mounted = cb;
|
|
997
|
+
}
|
|
998
|
+
toRemove.push(i);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
for (const idx of toRemove.reverse()) code.node.body.splice(idx, 1);
|
|
1004
|
+
const hookNames = new Set(["onStartup", "onMounted"]);
|
|
1005
|
+
for (const imp of code.BuildCache.import) if (imp.source === "@mbler/mcx") imp.imported = imp.imported.filter((item) => !hookNames.has(item.import || item.as));
|
|
1006
|
+
code.BuildCache.import = code.BuildCache.import.filter((imp) => imp.source !== "@mbler/mcx" || imp.imported.length > 0);
|
|
1007
|
+
return {
|
|
1008
|
+
startup,
|
|
1009
|
+
mounted
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1052
1013
|
//#endregion
|
|
1053
|
-
//#region src/transforms/transform/
|
|
1054
|
-
|
|
1014
|
+
//#region src/transforms/transform/layout.ts
|
|
1015
|
+
/**
|
|
1016
|
+
* Shared layout generation for both <Form> and <Ui>.
|
|
1017
|
+
* Generates layout config with (s) => expr functions for content and params.
|
|
1018
|
+
*/
|
|
1019
|
+
function generateLayout(ctx, tagNode, tagName, mode) {
|
|
1055
1020
|
const internalCtx = ctx.ctx;
|
|
1056
|
-
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
line: uiClientTag.loc.start.line
|
|
1021
|
+
const parsedObj = [];
|
|
1022
|
+
const typeTags = [];
|
|
1023
|
+
const elements = [];
|
|
1024
|
+
for (const child of tagNode.content) {
|
|
1025
|
+
if (child.type !== "TagNode") continue;
|
|
1026
|
+
if (child.content.some((i) => i.type === "TagNode")) internalCtx.rollupContext.error(`[${tagName}]: can't support nested elements`, child.loc ? {
|
|
1027
|
+
column: child.loc.start.column,
|
|
1028
|
+
line: child.loc.start.line
|
|
1065
1029
|
} : void 0);
|
|
1066
1030
|
let _for;
|
|
1067
|
-
if (typeof
|
|
1068
|
-
const match =
|
|
1031
|
+
if (typeof child.arr.for === "string") {
|
|
1032
|
+
const match = child.arr.for.match(/^(\w+)\s+in\s+(\w+)$/);
|
|
1069
1033
|
if (match) _for = {
|
|
1070
1034
|
variable: match[1],
|
|
1071
|
-
|
|
1035
|
+
useSetup: match[2]
|
|
1072
1036
|
};
|
|
1073
|
-
else internalCtx.rollupContext.error(
|
|
1074
|
-
column:
|
|
1075
|
-
line:
|
|
1037
|
+
else internalCtx.rollupContext.error(`[${tagName}]: invalid for syntax, expected 'variable in propName'`, child.loc ? {
|
|
1038
|
+
column: child.loc.start.column,
|
|
1039
|
+
line: child.loc.start.line
|
|
1076
1040
|
} : void 0);
|
|
1077
1041
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1042
|
+
let _if;
|
|
1043
|
+
if (typeof child.arr.if === "string") _if = { useSetup: child.arr.if };
|
|
1044
|
+
elements.push({
|
|
1045
|
+
arr: child.arr,
|
|
1046
|
+
content: child.content.map((i) => i.type === "TagContent" && i.data || "").join(""),
|
|
1047
|
+
type: child.name,
|
|
1048
|
+
loc: child.loc,
|
|
1049
|
+
..._for ? { for: _for } : {},
|
|
1050
|
+
..._if ? { if: _if } : {}
|
|
1084
1051
|
});
|
|
1085
1052
|
}
|
|
1086
|
-
const
|
|
1087
|
-
|
|
1053
|
+
for (const el of elements) {
|
|
1054
|
+
const name = el.type;
|
|
1055
|
+
const cleanedArr = { ...el.arr };
|
|
1056
|
+
delete cleanedArr.for;
|
|
1057
|
+
delete cleanedArr.if;
|
|
1058
|
+
const formType = detectFormType(name);
|
|
1059
|
+
if (formType === "invalid") {
|
|
1060
|
+
internalCtx.rollupContext.error(`[${tagName}]: don't support tag: ${name}`, el.loc ? {
|
|
1061
|
+
line: el.loc.start.line,
|
|
1062
|
+
column: el.loc.start.column
|
|
1063
|
+
} : void 0);
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
if (formType) typeTags.push(formType);
|
|
1067
|
+
const paramsObj = t.objectExpression(Object.entries(cleanedArr).filter(([key]) => key !== "for" && key !== "if").map(([key, value]) => {
|
|
1068
|
+
const isDynamic = key.startsWith(":");
|
|
1069
|
+
const paramName = isDynamic ? key.slice(1) : key;
|
|
1070
|
+
if (paramName === "click") return t.objectProperty(t.identifier(paramName), simpleFn(String(value)));
|
|
1071
|
+
return t.objectProperty(t.identifier(paramName), isDynamic ? simpleFn(String(value)) : typeof value === "boolean" ? t.booleanLiteral(value) : t.stringLiteral(value));
|
|
1072
|
+
}));
|
|
1073
|
+
const contentExpr = parseContent(el.content);
|
|
1088
1074
|
const props = [
|
|
1089
1075
|
t.objectProperty(t.identifier("type"), t.stringLiteral(name)),
|
|
1090
|
-
t.objectProperty(t.identifier("params"),
|
|
1091
|
-
|
|
1092
|
-
const paramName = isDynamic ? key.slice(1) : key;
|
|
1093
|
-
return t.objectProperty(t.identifier(paramName), isDynamic ? t.objectExpression([t.objectProperty(t.identifier("useProp"), t.stringLiteral(String(value)))]) : typeof value == "boolean" ? t.booleanLiteral(value) : t.stringLiteral(value));
|
|
1094
|
-
}))),
|
|
1095
|
-
t.objectProperty(t.identifier("content"), content.startsWith("{{ ") && content.endsWith(" }}") ? t.objectExpression([t.objectProperty(t.identifier("useProp"), t.stringLiteral(content.slice(3, content.length - 3).trim()))]) : t.stringLiteral(content))
|
|
1076
|
+
t.objectProperty(t.identifier("params"), paramsObj),
|
|
1077
|
+
t.objectProperty(t.identifier("content"), contentExpr)
|
|
1096
1078
|
];
|
|
1097
|
-
if (
|
|
1079
|
+
if (el.for) props.push(t.objectProperty(t.identifier("for"), t.objectExpression([t.objectProperty(t.identifier("variable"), t.stringLiteral(el.for.variable)), t.objectProperty(t.identifier("useSetup"), t.stringLiteral(el.for.useSetup))])));
|
|
1080
|
+
if (el.if) props.push(t.objectProperty(t.identifier("if"), t.objectExpression([t.objectProperty(t.identifier("useSetup"), t.stringLiteral(el.if.useSetup))])));
|
|
1098
1081
|
parsedObj.push(t.objectExpression(props));
|
|
1099
1082
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1083
|
+
let formTypeStr = "ActionFormData";
|
|
1084
|
+
if (typeTags.some((t) => [
|
|
1085
|
+
"input",
|
|
1086
|
+
"dropdown",
|
|
1087
|
+
"submit",
|
|
1088
|
+
"toggle",
|
|
1089
|
+
"slider"
|
|
1090
|
+
].includes(t))) formTypeStr = "ModalFormData";
|
|
1091
|
+
else if (typeTags.some((t) => t === "button-m")) formTypeStr = "MessageFormData";
|
|
1092
|
+
else if (typeTags.some((t) => t === "button")) formTypeStr = "ActionFormData";
|
|
1093
|
+
return {
|
|
1094
|
+
parsedObj,
|
|
1095
|
+
formTypeStr
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
function detectFormType(tag) {
|
|
1099
|
+
if ([
|
|
1100
|
+
"input",
|
|
1101
|
+
"dropdown",
|
|
1102
|
+
"submit",
|
|
1103
|
+
"toggle",
|
|
1104
|
+
"slider"
|
|
1105
|
+
].includes(tag)) return "modal";
|
|
1106
|
+
if (tag === "button-m") return "message";
|
|
1107
|
+
if (tag === "button") return "action";
|
|
1108
|
+
if ([
|
|
1109
|
+
"body",
|
|
1110
|
+
"divider",
|
|
1111
|
+
"title",
|
|
1112
|
+
"label",
|
|
1113
|
+
"header",
|
|
1114
|
+
"spacer",
|
|
1115
|
+
"close-button"
|
|
1116
|
+
].includes(tag)) return "shared";
|
|
1117
|
+
return "invalid";
|
|
1118
|
+
}
|
|
1119
|
+
/** Simple arrow function for params (non-reactive): (ctx) => ctx[0].a.b.c */
|
|
1120
|
+
function simpleFn(expr) {
|
|
1121
|
+
const ctx = t.identifier("ctx");
|
|
1122
|
+
const body = dotAccess(expr, ctx);
|
|
1123
|
+
return t.arrowFunctionExpression([ctx], body);
|
|
1124
|
+
}
|
|
1125
|
+
/** Extract root identifiers from an expression for dependency tracking */
|
|
1126
|
+
function extractIdentifiers(expr) {
|
|
1127
|
+
const reserved = new Set([
|
|
1128
|
+
"true",
|
|
1129
|
+
"false",
|
|
1130
|
+
"null",
|
|
1131
|
+
"undefined",
|
|
1132
|
+
"this",
|
|
1133
|
+
"new",
|
|
1134
|
+
"typeof",
|
|
1135
|
+
"instanceof"
|
|
1136
|
+
]);
|
|
1137
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1138
|
+
const regex = /\b([a-zA-Z_$][\w$]*)\b/g;
|
|
1139
|
+
let m;
|
|
1140
|
+
while ((m = regex.exec(expr)) !== null) if (!reserved.has(m[1])) ids.add(m[1]);
|
|
1141
|
+
return [...ids];
|
|
1142
|
+
}
|
|
1143
|
+
/** Generate new Computation((ctx) => expr, [deps]) */
|
|
1144
|
+
function arrowFn(expr) {
|
|
1145
|
+
const ctx = t.identifier("ctx");
|
|
1146
|
+
const body = dotAccess(expr, ctx);
|
|
1147
|
+
const evalFn = t.arrowFunctionExpression([ctx], body);
|
|
1148
|
+
const deps = extractIdentifiers(expr).map((id) => {
|
|
1149
|
+
const c = t.identifier("ctx");
|
|
1150
|
+
return t.arrowFunctionExpression([c], dotAccess(id, c));
|
|
1151
|
+
});
|
|
1152
|
+
return t.newExpression(t.identifier("Computation"), [evalFn, t.arrayExpression(deps)]);
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Parse content string, returns:
|
|
1156
|
+
* - t.stringLiteral for pure static text
|
|
1157
|
+
* - t.NewExpression (Computation) for content with {{ }} interpolation
|
|
1158
|
+
*
|
|
1159
|
+
* Supports:
|
|
1160
|
+
* - "Hello" → "Hello"
|
|
1161
|
+
* - "{{ a }}" → new Computation((ctx) => ctx[0].a, [ctx => ctx[0].a])
|
|
1162
|
+
* - "Hi {{ a }}" → new Computation((ctx) => `Hi ${ctx[0].a}`, [ctx => ctx[0].a])
|
|
1163
|
+
* - "{{ a.slice(1,2) }}" → new Computation((ctx) => ctx[0].a.slice(1,2), [ctx => ctx[0].a])
|
|
1164
|
+
*/
|
|
1165
|
+
function parseContent(raw) {
|
|
1166
|
+
if (!raw.includes("{{ ")) return t.stringLiteral(raw);
|
|
1167
|
+
const parts = splitInterpolation(raw);
|
|
1168
|
+
if (parts.length === 1 && parts[0].type === "expr") return arrowFn(parts[0].value);
|
|
1169
|
+
const ctx = t.identifier("ctx");
|
|
1170
|
+
const quasis = [];
|
|
1171
|
+
const expressions = [];
|
|
1172
|
+
const allIds = /* @__PURE__ */ new Set();
|
|
1173
|
+
for (const part of parts) if (part.type === "text") quasis.push(t.templateElement({
|
|
1174
|
+
raw: part.value,
|
|
1175
|
+
cooked: part.value
|
|
1176
|
+
}));
|
|
1177
|
+
else {
|
|
1178
|
+
expressions.push(dotAccess(part.value, ctx));
|
|
1179
|
+
for (const id of extractIdentifiers(part.value)) allIds.add(id);
|
|
1180
|
+
}
|
|
1181
|
+
quasis.push(t.templateElement({
|
|
1182
|
+
raw: "",
|
|
1183
|
+
cooked: ""
|
|
1184
|
+
}, true));
|
|
1185
|
+
const tpl = t.templateLiteral(quasis, expressions);
|
|
1186
|
+
const evalFn = t.arrowFunctionExpression([ctx], tpl);
|
|
1187
|
+
const deps = [...allIds].map((id) => {
|
|
1188
|
+
const c = t.identifier("ctx");
|
|
1189
|
+
return t.arrowFunctionExpression([c], dotAccess(id, c));
|
|
1190
|
+
});
|
|
1191
|
+
return t.newExpression(t.identifier("Computation"), [evalFn, t.arrayExpression(deps)]);
|
|
1192
|
+
}
|
|
1193
|
+
function splitInterpolation(raw) {
|
|
1194
|
+
const result = [];
|
|
1195
|
+
const regex = /\{\{\s*(.*?)\s*\}\}/g;
|
|
1196
|
+
let lastIndex = 0;
|
|
1197
|
+
let match;
|
|
1198
|
+
while ((match = regex.exec(raw)) !== null) {
|
|
1199
|
+
if (match.index > lastIndex) result.push({
|
|
1200
|
+
type: "text",
|
|
1201
|
+
value: raw.slice(lastIndex, match.index)
|
|
1202
|
+
});
|
|
1203
|
+
result.push({
|
|
1204
|
+
type: "expr",
|
|
1205
|
+
value: match[1]
|
|
1206
|
+
});
|
|
1207
|
+
lastIndex = regex.lastIndex;
|
|
1141
1208
|
}
|
|
1142
|
-
if (
|
|
1143
|
-
|
|
1209
|
+
if (lastIndex < raw.length) result.push({
|
|
1210
|
+
type: "text",
|
|
1211
|
+
value: raw.slice(lastIndex)
|
|
1212
|
+
});
|
|
1213
|
+
return result;
|
|
1214
|
+
}
|
|
1215
|
+
/** "a.b.c" → __ctx[0].a.b.c */
|
|
1216
|
+
function dotAccess(expr, root) {
|
|
1217
|
+
const parts = expr.split(".");
|
|
1218
|
+
let node = t.memberExpression(root, t.numericLiteral(0), true);
|
|
1219
|
+
for (const part of parts) node = t.memberExpression(node, t.identifier(part));
|
|
1220
|
+
return node;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
//#endregion
|
|
1224
|
+
//#region src/transforms/transform/ui.ts
|
|
1225
|
+
async function Comp$3(ctx) {
|
|
1226
|
+
ctx.impBody.push(t.importDeclaration([t.importSpecifier(t.identifier("__mcx__ui"), t.identifier("ui"))], t.stringLiteral("@mbler/mcx")), t.importDeclaration([t.importNamespaceSpecifier(t.identifier("__minecraft__ui"))], t.stringLiteral("@minecraft/server-ui")));
|
|
1227
|
+
const tagNode = ctx.ctx.compiledCode.strLoc.UI;
|
|
1228
|
+
if (!tagNode || tagNode.name !== "Ui") throw new Error("[UI Component]: why did parent not verify?");
|
|
1229
|
+
const { parsedObj, formTypeStr } = generateLayout(ctx, tagNode, "Ui", "ui");
|
|
1230
|
+
const configObj = t.objectExpression([
|
|
1231
|
+
t.objectProperty(t.identifier("mode"), t.stringLiteral("ui")),
|
|
1232
|
+
t.objectProperty(t.identifier("layout"), t.arrayExpression(parsedObj)),
|
|
1233
|
+
t.objectProperty(t.identifier("use"), t.memberExpression(t.identifier("__minecraft__ui"), t.identifier(formTypeStr))),
|
|
1234
|
+
t.objectProperty(t.identifier("UI"), t.identifier("__minecraft__ui"))
|
|
1235
|
+
]);
|
|
1236
|
+
ctx.app([t.objectProperty(t.identifier("ui"), t.newExpression(t.identifier("__mcx__ui"), [configObj, t.identifier(config_default.scriptCompileFn)]))]);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
//#endregion
|
|
1240
|
+
//#region src/transforms/transform/form.ts
|
|
1241
|
+
async function Comp$2(ctx) {
|
|
1242
|
+
ctx.impBody.push(t.importDeclaration([t.importSpecifier(t.identifier("__mcx__ui"), t.identifier("ui"))], t.stringLiteral("@mbler/mcx")), t.importDeclaration([t.importNamespaceSpecifier(t.identifier("__minecraft__ui"))], t.stringLiteral("@minecraft/server-ui")));
|
|
1243
|
+
const tagNode = ctx.ctx.compiledCode.strLoc.Form;
|
|
1244
|
+
if (!tagNode || tagNode.name !== "Form") throw new Error("[Form Component]: why did parent not verify?");
|
|
1245
|
+
const { parsedObj, formTypeStr } = generateLayout(ctx, tagNode, "Form", "form");
|
|
1246
|
+
const configObj = t.objectExpression([
|
|
1247
|
+
t.objectProperty(t.identifier("mode"), t.stringLiteral("form")),
|
|
1144
1248
|
t.objectProperty(t.identifier("layout"), t.arrayExpression(parsedObj)),
|
|
1145
|
-
t.objectProperty(t.identifier("use"), t.memberExpression(t.identifier("__minecraft__ui"), t.identifier(
|
|
1249
|
+
t.objectProperty(t.identifier("use"), t.memberExpression(t.identifier("__minecraft__ui"), t.identifier(formTypeStr))),
|
|
1146
1250
|
t.objectProperty(t.identifier("UI"), t.identifier("__minecraft__ui"))
|
|
1147
1251
|
]);
|
|
1148
|
-
ctx.app([t.objectProperty(t.identifier("ui"), t.newExpression(t.identifier("__mcx__ui"), [
|
|
1252
|
+
ctx.app([t.objectProperty(t.identifier("ui"), t.newExpression(t.identifier("__mcx__ui"), [configObj, t.identifier(config_default.scriptCompileFn)]))]);
|
|
1149
1253
|
}
|
|
1254
|
+
|
|
1150
1255
|
//#endregion
|
|
1151
1256
|
//#region src/transforms/transform/event.ts
|
|
1152
1257
|
async function Comp$1(ctx) {
|
|
1153
1258
|
const appData = [t.objectProperty(t.identifier("event"), await generateEventConfig(ctx.ctx.compiledCode.raw.find((node) => node.name === "Event"), ctx.ctx, ctx.impBody))];
|
|
1154
1259
|
ctx.app(appData);
|
|
1155
1260
|
}
|
|
1261
|
+
|
|
1156
1262
|
//#endregion
|
|
1157
1263
|
//#region src/transforms/transform/app.ts
|
|
1158
1264
|
async function Comp(ctx) {
|
|
@@ -1194,6 +1300,7 @@ async function Comp(ctx) {
|
|
|
1194
1300
|
ctx.app(appData);
|
|
1195
1301
|
}
|
|
1196
1302
|
}
|
|
1303
|
+
|
|
1197
1304
|
//#endregion
|
|
1198
1305
|
//#region src/mcx-component/cjsTransform.ts
|
|
1199
1306
|
/**
|
|
@@ -1283,6 +1390,7 @@ function transformImportIRtoRequire(importIR) {
|
|
|
1283
1390
|
}
|
|
1284
1391
|
return define;
|
|
1285
1392
|
}
|
|
1393
|
+
|
|
1286
1394
|
//#endregion
|
|
1287
1395
|
//#region src/mcx-component/vm.ts
|
|
1288
1396
|
const BLOCKED_MODULES = new Set([
|
|
@@ -1394,17 +1502,11 @@ var RunScript = class {
|
|
|
1394
1502
|
}
|
|
1395
1503
|
static isCanUseEsmRunVm = typeof vm.SourceTextModule == "function";
|
|
1396
1504
|
};
|
|
1505
|
+
|
|
1397
1506
|
//#endregion
|
|
1398
1507
|
//#region src/mcx-component/index.ts
|
|
1399
1508
|
var mcx_component_exports = /* @__PURE__ */ __exportAll({
|
|
1400
|
-
BlockComponent: () => BlockComponent$1,
|
|
1401
|
-
EntityComponent: () => EntityComponent$1,
|
|
1402
|
-
GIFImageComponent: () => GIFImageComponent$1,
|
|
1403
|
-
ItemComponent: () => ItemComponent$1,
|
|
1404
|
-
JPGImageComponent: () => JPGImageComponent$1,
|
|
1405
|
-
PNGImageComponent: () => PNGImageComponent$1,
|
|
1406
1509
|
RunScript: () => RunScript,
|
|
1407
|
-
SVGImageComponent: () => SVGImageComponent$1,
|
|
1408
1510
|
clearCachedOptions: () => clearCachedOptions,
|
|
1409
1511
|
compileComponent: () => compileComponent,
|
|
1410
1512
|
execESMMethod: () => execESMMethod,
|
|
@@ -1650,9 +1752,14 @@ async function compileComponent(compiledCode, ctx) {
|
|
|
1650
1752
|
await writeFile(filePoint, JSON.stringify(json, null, 2));
|
|
1651
1753
|
}
|
|
1652
1754
|
}
|
|
1755
|
+
|
|
1653
1756
|
//#endregion
|
|
1654
1757
|
//#region src/transforms/main.ts
|
|
1655
1758
|
async function _transform(ctx) {
|
|
1759
|
+
const formTag = ctx.compiledCode.strLoc.Form;
|
|
1760
|
+
const uiTag = ctx.compiledCode.strLoc.UI;
|
|
1761
|
+
const isSetupMode = formTag && formTag.arr.setup !== void 0 || uiTag && uiTag.arr.setup !== void 0;
|
|
1762
|
+
const modeType = formTag && formTag.arr.setup !== void 0 ? "form" : uiTag && uiTag.arr.setup !== void 0 ? "ui" : null;
|
|
1656
1763
|
const _temp_main = generateMain(ctx.compiledCode.JSIR);
|
|
1657
1764
|
const mainFn = ctx.mainFn.body = _temp_main[0];
|
|
1658
1765
|
const prop = [];
|
|
@@ -1666,16 +1773,22 @@ async function _transform(ctx) {
|
|
|
1666
1773
|
app
|
|
1667
1774
|
};
|
|
1668
1775
|
let type = "app";
|
|
1776
|
+
if (isSetupMode && modeType) processDefineProp(ctx.compiledCode.JSIR, modeType, parseCtx.impBody);
|
|
1669
1777
|
const enableSetup = _enable();
|
|
1670
1778
|
if (ctx.compiledCode.strLoc.Event.isLoad) {
|
|
1671
1779
|
type = "event";
|
|
1672
1780
|
enableSetup();
|
|
1673
1781
|
await Comp$1(parseCtx);
|
|
1674
1782
|
}
|
|
1783
|
+
if (ctx.compiledCode.strLoc.Form) {
|
|
1784
|
+
type = "form";
|
|
1785
|
+
enableSetup();
|
|
1786
|
+
await Comp$2(parseCtx);
|
|
1787
|
+
}
|
|
1675
1788
|
if (ctx.compiledCode.strLoc.UI) {
|
|
1676
1789
|
type = "ui";
|
|
1677
1790
|
enableSetup();
|
|
1678
|
-
await Comp$
|
|
1791
|
+
await Comp$3(parseCtx);
|
|
1679
1792
|
}
|
|
1680
1793
|
if (Object.getOwnPropertyNames(ctx.compiledCode.strLoc.Component).length >= 1) {
|
|
1681
1794
|
type = "component";
|
|
@@ -1686,6 +1799,22 @@ async function _transform(ctx) {
|
|
|
1686
1799
|
enableSetup();
|
|
1687
1800
|
await Comp(parseCtx);
|
|
1688
1801
|
}
|
|
1802
|
+
if (isSetupMode) {
|
|
1803
|
+
const existingExportNames = /* @__PURE__ */ new Set();
|
|
1804
|
+
for (const exp of ctx.compiledCode.JSIR.BuildCache.export) if (t.isExportNamedDeclaration(exp) && exp.declaration) {
|
|
1805
|
+
const ids = extractIdList(exp.declaration);
|
|
1806
|
+
for (const id of ids) existingExportNames.add(id);
|
|
1807
|
+
}
|
|
1808
|
+
for (const p of parseCtx.prop) if (t.isObjectProperty(p) && t.isIdentifier(p.key)) existingExportNames.add(p.key.name);
|
|
1809
|
+
const setupDecls = collectSetupDeclarations(ctx.compiledCode.JSIR, existingExportNames);
|
|
1810
|
+
const hooks = processHooks(ctx.compiledCode.JSIR);
|
|
1811
|
+
const returnStmt = mainFn[mainFn.length - 1];
|
|
1812
|
+
if (t.isReturnStatement(returnStmt) && t.isObjectExpression(returnStmt.argument)) {
|
|
1813
|
+
returnStmt.argument.properties.push(...setupDecls);
|
|
1814
|
+
if (hooks.startup) returnStmt.argument.properties.push(t.objectProperty(t.identifier("__mcx_startup"), hooks.startup));
|
|
1815
|
+
if (hooks.mounted) returnStmt.argument.properties.push(t.objectProperty(t.identifier("__mcx_mounted"), hooks.mounted));
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1689
1818
|
prop.push(t.objectProperty(t.identifier("type"), t.stringLiteral(type)));
|
|
1690
1819
|
if (enableSetup.prototype.enable) prop.push(t.objectProperty(t.identifier("setup"), t.identifier(config_default.scriptCompileFn)));
|
|
1691
1820
|
if (app.prototype.enable) prop.push(t.objectProperty(t.identifier("app"), t.objectExpression(app.prototype.enable)));
|
|
@@ -1695,6 +1824,7 @@ async function _transform(ctx) {
|
|
|
1695
1824
|
t.exportDefaultDeclaration(t.objectExpression(prop))
|
|
1696
1825
|
])).code;
|
|
1697
1826
|
}
|
|
1827
|
+
|
|
1698
1828
|
//#endregion
|
|
1699
1829
|
//#region src/transforms/index.ts
|
|
1700
1830
|
function createErrorProxy(err, id) {
|
|
@@ -1727,8 +1857,10 @@ async function transform(code, cache, id, context, opt, output) {
|
|
|
1727
1857
|
});
|
|
1728
1858
|
} catch (err) {
|
|
1729
1859
|
context.error(createErrorProxy(err, id));
|
|
1860
|
+
return "";
|
|
1730
1861
|
}
|
|
1731
1862
|
}
|
|
1863
|
+
|
|
1732
1864
|
//#endregion
|
|
1733
1865
|
//#region src/compile-mcx/compiler/main.ts
|
|
1734
1866
|
function createMcxPlugin(opt, output) {
|
|
@@ -1859,14 +1991,11 @@ function createMcxPlugin(opt, output) {
|
|
|
1859
1991
|
compileData = cache.has(id) ? cache.get(id) : compileMCXFn(code);
|
|
1860
1992
|
cache.set(id, compileData);
|
|
1861
1993
|
} catch (err) {
|
|
1862
|
-
if (err instanceof CompileError) {
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
});
|
|
1868
|
-
}
|
|
1869
|
-
this.error(err instanceof Error ? `${err.message} : ${err.stack}` : String(err));
|
|
1994
|
+
if (err instanceof CompileError) this.error(err.message, {
|
|
1995
|
+
column: err.loc.column,
|
|
1996
|
+
line: err.loc.line
|
|
1997
|
+
});
|
|
1998
|
+
else this.error(err instanceof Error ? `${err.message} : ${err.stack}` : String(err));
|
|
1870
1999
|
return;
|
|
1871
2000
|
}
|
|
1872
2001
|
compileData.setFilePath(id);
|
|
@@ -1905,16 +2034,18 @@ function rollupPlugin(opt, output) {
|
|
|
1905
2034
|
function rolldownPlugin(opt, output) {
|
|
1906
2035
|
return createMcxPlugin(opt, output);
|
|
1907
2036
|
}
|
|
2037
|
+
|
|
1908
2038
|
//#endregion
|
|
1909
2039
|
//#region src/types.ts
|
|
1910
2040
|
var types_exports$1 = /* @__PURE__ */ __exportAll({});
|
|
2041
|
+
|
|
1911
2042
|
//#endregion
|
|
1912
2043
|
//#region src/mcx-component/types.ts
|
|
1913
2044
|
var types_exports = /* @__PURE__ */ __exportAll({ createFileEdit: () => createFileEdit });
|
|
1914
2045
|
function createFileEdit(expression) {
|
|
1915
2046
|
return expression;
|
|
1916
2047
|
}
|
|
1917
|
-
//#endregion
|
|
1918
|
-
export { ast_default as AST, BlockComponent, types_exports as ComponentType, EntityComponent, GIFImageComponent, ItemComponent, JPGImageComponent, PNGImageComponent, types_exports$1 as PubType, SVGImageComponent, mcx_component_exports as compile_component, compiler_exports as compiler, rolldownPlugin, rollupPlugin, transform, Utils as utils };
|
|
1919
2048
|
|
|
2049
|
+
//#endregion
|
|
2050
|
+
export { ast_default as AST, types_exports as ComponentType, types_exports$1 as PubType, mcx_component_exports as compile_component, compiler_exports as compiler, rolldownPlugin, rollupPlugin, transform, Utils as utils };
|
|
1920
2051
|
//# sourceMappingURL=index.js.map
|