@canvasengine/compiler 2.0.0-beta.49 → 2.0.0-beta.50
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/grammar2.pegjs +119 -3
- package/dist/index.js +164 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/grammar2.pegjs
CHANGED
|
@@ -179,6 +179,106 @@
|
|
|
179
179
|
return { domAttrs, displayObjectAttrs };
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
function formatDOMContainerAttributes(attributes) {
|
|
183
|
+
if (attributes.length === 0) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const propsEntries = [];
|
|
188
|
+
const domAttrs = [];
|
|
189
|
+
const classValues = [];
|
|
190
|
+
let classInsertIndex = null;
|
|
191
|
+
let attrsInsertIndex = null;
|
|
192
|
+
let attrsIndex = null;
|
|
193
|
+
let attrsValue = null;
|
|
194
|
+
|
|
195
|
+
attributes.forEach(attr => {
|
|
196
|
+
if (attr.startsWith('...')) {
|
|
197
|
+
propsEntries.push(attr);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let attrName;
|
|
202
|
+
let attrValue;
|
|
203
|
+
if (attr.includes(':')) {
|
|
204
|
+
const colonIndex = attr.indexOf(':');
|
|
205
|
+
attrName = attr.slice(0, colonIndex).trim().replace(/['"]/g, '');
|
|
206
|
+
attrValue = attr.slice(colonIndex + 1).trim();
|
|
207
|
+
} else {
|
|
208
|
+
attrName = attr.replace(/['"]/g, '');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (attrName === 'class' && attrValue !== undefined) {
|
|
212
|
+
classValues.push(attrValue);
|
|
213
|
+
if (classInsertIndex === null) {
|
|
214
|
+
classInsertIndex = domAttrs.length;
|
|
215
|
+
}
|
|
216
|
+
if (attrsInsertIndex === null) {
|
|
217
|
+
attrsInsertIndex = propsEntries.length;
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (attrName === 'style') {
|
|
223
|
+
domAttrs.push(attr);
|
|
224
|
+
if (attrsInsertIndex === null) {
|
|
225
|
+
attrsInsertIndex = propsEntries.length;
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (attrName === 'attrs' && attrValue !== undefined) {
|
|
231
|
+
attrsValue = attrValue;
|
|
232
|
+
attrsIndex = propsEntries.length;
|
|
233
|
+
propsEntries.push(null);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
propsEntries.push(attr);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
if (classValues.length > 0) {
|
|
241
|
+
const mergedClass = classValues.length === 1
|
|
242
|
+
? `class: ${classValues[0]}`
|
|
243
|
+
: `class: [${classValues.join(', ')}]`;
|
|
244
|
+
if (classInsertIndex === null) {
|
|
245
|
+
domAttrs.push(mergedClass);
|
|
246
|
+
} else {
|
|
247
|
+
domAttrs.splice(classInsertIndex, 0, mergedClass);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let attrsEntry = null;
|
|
252
|
+
if (attrsValue && domAttrs.length > 0) {
|
|
253
|
+
attrsEntry = `attrs: { ...${attrsValue}, ${domAttrs.join(', ')} }`;
|
|
254
|
+
} else if (attrsValue) {
|
|
255
|
+
attrsEntry = `attrs: ${attrsValue}`;
|
|
256
|
+
} else if (domAttrs.length > 0) {
|
|
257
|
+
attrsEntry = `attrs: { ${domAttrs.join(', ')} }`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (attrsEntry) {
|
|
261
|
+
if (attrsIndex !== null) {
|
|
262
|
+
propsEntries[attrsIndex] = attrsEntry;
|
|
263
|
+
} else if (attrsInsertIndex !== null) {
|
|
264
|
+
propsEntries.splice(attrsInsertIndex, 0, attrsEntry);
|
|
265
|
+
} else {
|
|
266
|
+
propsEntries.unshift(attrsEntry);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const filteredEntries = propsEntries.filter(entry => entry !== null);
|
|
271
|
+
if (filteredEntries.length === 0) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (filteredEntries.length === 1 && filteredEntries[0].startsWith('...')) {
|
|
276
|
+
return filteredEntries[0].substring(3);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return `{ ${filteredEntries.join(', ')} }`;
|
|
280
|
+
}
|
|
281
|
+
|
|
182
282
|
function hasFunctionCall(value) {
|
|
183
283
|
return /[a-zA-Z_][a-zA-Z0-9_]*\s*\(/.test(value);
|
|
184
284
|
}
|
|
@@ -256,6 +356,10 @@ selfClosingElement "self-closing component tag"
|
|
|
256
356
|
if (isDOMElement(tagName)) {
|
|
257
357
|
return formatDOMElement(tagName, attributes);
|
|
258
358
|
}
|
|
359
|
+
if (tagName === 'DOMContainer') {
|
|
360
|
+
const attrsString = formatDOMContainerAttributes(attributes);
|
|
361
|
+
return attrsString ? `h(DOMContainer, ${attrsString})` : `h(DOMContainer)`;
|
|
362
|
+
}
|
|
259
363
|
// Otherwise, treat as regular component
|
|
260
364
|
const attrsString = formatAttributes(attributes);
|
|
261
365
|
return attrsString ? `h(${tagName}, ${attrsString})` : `h(${tagName})`;
|
|
@@ -405,10 +509,10 @@ openCloseElement "component with content"
|
|
|
405
509
|
);
|
|
406
510
|
}
|
|
407
511
|
|
|
512
|
+
const children = content ? content : null;
|
|
513
|
+
|
|
408
514
|
// Check if it's a DOM element
|
|
409
515
|
if (isDOMElement(tagName)) {
|
|
410
|
-
const children = content ? content : null;
|
|
411
|
-
|
|
412
516
|
if (attributes.length === 0) {
|
|
413
517
|
if (children) {
|
|
414
518
|
return `h(DOMElement, { element: "${tagName}" }, ${children})`;
|
|
@@ -438,8 +542,20 @@ openCloseElement "component with content"
|
|
|
438
542
|
}
|
|
439
543
|
|
|
440
544
|
// Otherwise, treat as regular component
|
|
545
|
+
if (tagName === 'DOMContainer') {
|
|
546
|
+
const attrsString = formatDOMContainerAttributes(attributes);
|
|
547
|
+
if (attrsString && children) {
|
|
548
|
+
return `h(DOMContainer, ${attrsString}, ${children})`;
|
|
549
|
+
} else if (attrsString) {
|
|
550
|
+
return `h(DOMContainer, ${attrsString})`;
|
|
551
|
+
} else if (children) {
|
|
552
|
+
return `h(DOMContainer, null, ${children})`;
|
|
553
|
+
} else {
|
|
554
|
+
return `h(DOMContainer)`;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
441
558
|
const attrsString = formatAttributes(attributes);
|
|
442
|
-
const children = content ? content : null;
|
|
443
559
|
if (attrsString && children) {
|
|
444
560
|
return `h(${tagName}, ${attrsString}, ${children})`;
|
|
445
561
|
} else if (attrsString) {
|
package/dist/index.js
CHANGED
|
@@ -103,6 +103,169 @@ function scopeCSS(css, scopeClass) {
|
|
|
103
103
|
}
|
|
104
104
|
return result;
|
|
105
105
|
}
|
|
106
|
+
function splitCallArguments(argsText) {
|
|
107
|
+
const args = [];
|
|
108
|
+
let current = "";
|
|
109
|
+
let depth = 0;
|
|
110
|
+
let inSingle = false;
|
|
111
|
+
let inDouble = false;
|
|
112
|
+
let inTemplate = false;
|
|
113
|
+
let escaped = false;
|
|
114
|
+
for (let i = 0; i < argsText.length; i++) {
|
|
115
|
+
const char = argsText[i];
|
|
116
|
+
if (escaped) {
|
|
117
|
+
current += char;
|
|
118
|
+
escaped = false;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (char === "\\") {
|
|
122
|
+
current += char;
|
|
123
|
+
escaped = true;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (inSingle) {
|
|
127
|
+
current += char;
|
|
128
|
+
if (char === "'") inSingle = false;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (inDouble) {
|
|
132
|
+
current += char;
|
|
133
|
+
if (char === '"') inDouble = false;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (inTemplate) {
|
|
137
|
+
current += char;
|
|
138
|
+
if (char === "`") inTemplate = false;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (char === "'") {
|
|
142
|
+
inSingle = true;
|
|
143
|
+
current += char;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (char === '"') {
|
|
147
|
+
inDouble = true;
|
|
148
|
+
current += char;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (char === "`") {
|
|
152
|
+
inTemplate = true;
|
|
153
|
+
current += char;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (char === "(" || char === "{" || char === "[") {
|
|
157
|
+
depth++;
|
|
158
|
+
current += char;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (char === ")" || char === "}" || char === "]") {
|
|
162
|
+
depth--;
|
|
163
|
+
current += char;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (char === "," && depth === 0) {
|
|
167
|
+
args.push(current.trim());
|
|
168
|
+
current = "";
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
current += char;
|
|
172
|
+
}
|
|
173
|
+
if (current.trim()) {
|
|
174
|
+
args.push(current.trim());
|
|
175
|
+
}
|
|
176
|
+
return args;
|
|
177
|
+
}
|
|
178
|
+
function addScopeClassToDOMContainer(parsedTemplate, scopeClass) {
|
|
179
|
+
let result = "";
|
|
180
|
+
let cursor = 0;
|
|
181
|
+
while (cursor < parsedTemplate.length) {
|
|
182
|
+
const start = parsedTemplate.indexOf("h(DOMContainer", cursor);
|
|
183
|
+
if (start === -1) {
|
|
184
|
+
result += parsedTemplate.slice(cursor);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
result += parsedTemplate.slice(cursor, start);
|
|
188
|
+
const openParen = parsedTemplate.indexOf("(", start);
|
|
189
|
+
if (openParen === -1) {
|
|
190
|
+
result += parsedTemplate.slice(start);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
let depth = 0;
|
|
194
|
+
let inSingle = false;
|
|
195
|
+
let inDouble = false;
|
|
196
|
+
let inTemplate = false;
|
|
197
|
+
let escaped = false;
|
|
198
|
+
let end = -1;
|
|
199
|
+
for (let i = openParen; i < parsedTemplate.length; i++) {
|
|
200
|
+
const char = parsedTemplate[i];
|
|
201
|
+
if (escaped) {
|
|
202
|
+
escaped = false;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (char === "\\") {
|
|
206
|
+
escaped = true;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (inSingle) {
|
|
210
|
+
if (char === "'") inSingle = false;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (inDouble) {
|
|
214
|
+
if (char === '"') inDouble = false;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (inTemplate) {
|
|
218
|
+
if (char === "`") inTemplate = false;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (char === "'") {
|
|
222
|
+
inSingle = true;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (char === '"') {
|
|
226
|
+
inDouble = true;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (char === "`") {
|
|
230
|
+
inTemplate = true;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (char === "(") depth++;
|
|
234
|
+
if (char === ")") depth--;
|
|
235
|
+
if (depth === 0) {
|
|
236
|
+
end = i + 1;
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (end === -1) {
|
|
241
|
+
result += parsedTemplate.slice(start);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
const callText = parsedTemplate.slice(start, end);
|
|
245
|
+
const argsText = parsedTemplate.slice(openParen + 1, end - 1);
|
|
246
|
+
const args = splitCallArguments(argsText);
|
|
247
|
+
if (args[0]?.trim() !== "DOMContainer") {
|
|
248
|
+
result += callText;
|
|
249
|
+
cursor = end;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (args.length === 1) {
|
|
253
|
+
args.push(`{ _scopeClass: '${scopeClass}' }`);
|
|
254
|
+
} else {
|
|
255
|
+
const props = args[1].trim();
|
|
256
|
+
if (props === "null" || props === "undefined") {
|
|
257
|
+
args[1] = `{ _scopeClass: '${scopeClass}' }`;
|
|
258
|
+
} else if (props.startsWith("{")) {
|
|
259
|
+
args[1] = props.replace(/^\{\s*/, `{ _scopeClass: '${scopeClass}', `);
|
|
260
|
+
} else {
|
|
261
|
+
args[1] = `{ _scopeClass: '${scopeClass}', ...${props} }`;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
result += `h(${args.join(", ")})`;
|
|
265
|
+
cursor = end;
|
|
266
|
+
}
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
106
269
|
function shaderLoader() {
|
|
107
270
|
const filter = createFilter(/\.(frag|vert|wgsl)$/);
|
|
108
271
|
return {
|
|
@@ -244,20 +407,7 @@ ${importsCode}`;
|
|
|
244
407
|
const fileHash = generateHash(id);
|
|
245
408
|
scopeClass = fileHash;
|
|
246
409
|
processedStyleContent = scopeCSS(styleContent, scopeClass);
|
|
247
|
-
parsedTemplate = parsedTemplate
|
|
248
|
-
/h\(DOMContainer\s*,\s*(\{([^}]*)\}|null)\s*(,\s*[^)]*)?\)/g,
|
|
249
|
-
(match, propsPart, propsContent, childrenPart) => {
|
|
250
|
-
if (propsPart === "null") {
|
|
251
|
-
return `h(DOMContainer, { _scopeClass: '${scopeClass}' }${childrenPart || ""})`;
|
|
252
|
-
} else {
|
|
253
|
-
return `h(DOMContainer, { _scopeClass: '${scopeClass}', ${propsContent || ""} }${childrenPart || ""})`;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
parsedTemplate = parsedTemplate.replace(
|
|
258
|
-
/h\(DOMContainer\s*\)(?!\s*\()/g,
|
|
259
|
-
`h(DOMContainer, { _scopeClass: '${scopeClass}' })`
|
|
260
|
-
);
|
|
410
|
+
parsedTemplate = addScopeClassToDOMContainer(parsedTemplate, scopeClass);
|
|
261
411
|
}
|
|
262
412
|
const escapedStyleContent = processedStyleContent.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
263
413
|
const styleId = `ce-style-${id.replace(/[^a-zA-Z0-9]/g, "-")}`;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { createFilter } from \"vite\";\nimport { parse } from \"acorn\";\nimport fs from \"fs\";\nimport pkg from \"peggy\";\nimport path from \"path\";\nimport * as ts from \"typescript\";\nimport { fileURLToPath } from 'url';\n\nconst { generate } = pkg;\n\nconst DEV_SRC = \"../../src\"\n\n/**\n * Generates a short hash (8 characters, letters only) from a string\n * \n * @param {string} str - The string to hash\n * @returns {string} - An 8-character hash containing only lowercase letters (a-z)\n */\nfunction generateHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n // Convert to positive number and map to letters only (a-z)\n // Use modulo to map to 26 letters, then convert to character\n const positiveHash = Math.abs(hash);\n let result = '';\n for (let i = 0; i < 8; i++) {\n const letterIndex = (positiveHash + i * 31) % 26; // 31 is a prime to spread values\n result += String.fromCharCode(97 + letterIndex); // 97 is 'a'\n }\n return result;\n}\n\n/**\n * Formats a syntax error message with visual pointer to the error location\n * \n * @param {string} template - The template content that failed to parse\n * @param {object} error - The error object with location information\n * @returns {string} - Formatted error message with a visual pointer\n * \n * @example\n * ```\n * const errorMessage = showErrorMessage(\"<Canvas>test(d)</Canvas>\", syntaxError);\n * // Returns a formatted error message with an arrow pointing to 'd'\n * ```\n */\nfunction showErrorMessage(template: string, error: any): string {\n if (!error.location) {\n return `Syntax error: ${error.message}`;\n }\n\n const lines = template.split('\\n');\n const { line, column } = error.location.start;\n const errorLine = lines[line - 1] || '';\n \n // Create a visual pointer with an arrow\n const pointer = ' '.repeat(column - 1) + '^';\n \n return `Syntax error at line ${line}, column ${column}: ${error.message}\\n\\n` +\n `${errorLine}\\n${pointer}\\n`;\n}\n\n/**\n * Scopes CSS selectors by prefixing them with a class selector\n * \n * This function prefixes all CSS rule selectors (not @rules) with a class\n * selector to scope the styles to a specific component instance.\n * \n * @param {string} css - The CSS content to scope\n * @param {string} scopeClass - The unique scope class to use (without the dot)\n * @returns {string} - The scoped CSS content\n * \n * @example\n * ```\n * const scoped = scopeCSS('.my-class { color: red; }', 'ce-scope-abc123');\n * // Returns: '.ce-scope-abc123 .my-class { color: red; }'\n * ```\n */\nfunction scopeCSS(css: string, scopeClass: string): string {\n const scopeSelector = `.${scopeClass}`;\n \n // Process CSS by finding rule blocks while skipping @rules\n let result = '';\n let i = 0;\n let depth = 0;\n let inRule = false;\n let selectorBuffer = '';\n \n while (i < css.length) {\n const char = css[i];\n \n if (char === '@' && !inRule && selectorBuffer === '') {\n // Found @rule - copy it as-is until matching closing brace\n const atRuleStart = i;\n i++; // Skip '@'\n \n // Find the opening brace\n while (i < css.length && css[i] !== '{') {\n i++;\n }\n \n if (i < css.length) {\n // Found opening brace, now find matching closing brace\n depth = 1;\n i++; // Skip '{'\n \n while (i < css.length && depth > 0) {\n if (css[i] === '{') depth++;\n else if (css[i] === '}') depth--;\n i++;\n }\n \n // Copy entire @rule as-is\n result += css.substring(atRuleStart, i);\n }\n continue;\n }\n \n if (char === '{' && !inRule) {\n // Start of a rule block - scope the selector we just collected\n const selectorText = selectorBuffer.trim();\n \n if (selectorText) {\n // Split selectors by comma and scope each one\n const scopedSelectors = selectorText\n .split(',')\n .map(sel => {\n const trimmed = sel.trim();\n return trimmed ? `${scopeSelector} ${trimmed}` : trimmed;\n })\n .join(', ');\n \n result += scopedSelectors;\n }\n result += ' {';\n inRule = true;\n depth = 1;\n selectorBuffer = '';\n } else if (char === '{' && inRule) {\n // Nested brace\n result += char;\n depth++;\n } else if (char === '}' && inRule) {\n result += char;\n depth--;\n if (depth === 0) {\n inRule = false;\n }\n } else if (!inRule) {\n // Collecting selector\n selectorBuffer += char;\n } else {\n // Inside rule block\n result += char;\n if (char === '{') depth++;\n }\n \n i++;\n }\n \n // Add any remaining selector (shouldn't happen in valid CSS, but handle it)\n if (selectorBuffer.trim()) {\n const scopedSelectors = selectorBuffer.trim()\n .split(',')\n .map(sel => {\n const trimmed = sel.trim();\n return trimmed ? `${scopeSelector} ${trimmed}` : trimmed;\n })\n .join(', ');\n result += scopedSelectors;\n }\n \n return result;\n}\n\n/**\n * Vite plugin to load shader files (.frag, .vert, .wgsl) as text strings\n * \n * This plugin allows importing shader files directly as string literals in your code.\n * It supports fragment shaders (.frag), vertex shaders (.vert), and WebGPU shaders (.wgsl).\n * The content is loaded as a raw string and can be used directly with graphics APIs.\n * \n * @returns {object} - Vite plugin configuration object\n * \n * @example\n * ```typescript\n * // In your vite.config.ts\n * import { shaderLoader } from './path/to/compiler'\n * \n * export default defineConfig({\n * plugins: [shaderLoader()]\n * })\n * \n * // In your code\n * import fragmentShader from './shader.frag'\n * import vertexShader from './shader.vert'\n * import computeShader from './shader.wgsl'\n * \n * console.log(fragmentShader) // Raw shader code as string\n * ```\n */\nexport function shaderLoader() {\n const filter = createFilter(/\\.(frag|vert|wgsl)$/);\n\n return {\n name: \"vite-plugin-shader-loader\",\n transform(code: string, id: string) {\n if (!filter(id)) return;\n\n // Escape the shader code to be safely embedded in a JavaScript string\n const escapedCode = code\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/`/g, '\\\\`') // Escape backticks\n .replace(/\\$/g, '\\\\$'); // Escape dollar signs\n\n // Return the shader content as a default export string\n return {\n code: `export default \\`${escapedCode}\\`;`,\n map: null,\n };\n },\n };\n}\n\nexport default function canvasengine() {\n const filter = createFilter(\"**/*.ce\");\n const useLegacyGrammar = process.env.CANVASENGINE_COMPILER_V1 === \"1\";\n\n // Convert import.meta.url to a file path\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n\n const grammarFile = useLegacyGrammar ? \"grammar.pegjs\" : \"grammar2.pegjs\";\n const grammar = fs.readFileSync(\n path.join(__dirname, grammarFile),\n \"utf8\"\n );\n const parser = generate(grammar);\n const isDev = process.env.NODE_ENV === \"dev\";\n const FLAG_COMMENT = \"/*--[TPL]--*/\";\n let warnedAboutGrammar = false;\n\n const PRIMITIVE_COMPONENTS = [\n \"Canvas\",\n \"Sprite\",\n \"Text\",\n \"Viewport\",\n \"Graphics\",\n \"Container\",\n \"Navigation\",\n \"ImageMap\",\n \"NineSliceSprite\",\n \"Rect\",\n \"Circle\",\n \"Ellipse\",\n \"Triangle\",\n \"TilingSprite\",\n \"svg\",\n \"Video\",\n \"Mesh\",\n \"Svg\",\n \"DOMContainer\",\n \"DOMElement\",\n \"DOMSprite\",\n \"Button\",\n \"Joystick\"\n ];\n\n return {\n name: \"vite-plugin-ce\",\n transform(code: string, id: string) {\n if (!filter(id)) return null;\n if (!warnedAboutGrammar) {\n warnedAboutGrammar = true;\n const legacyNote = \"Set CANVASENGINE_COMPILER_V1=1 to compile with the legacy grammar (v1).\";\n if (useLegacyGrammar) {\n console.warn(`[canvasengine] Using legacy grammar v1. ${legacyNote}`);\n } else {\n console.warn(`[canvasengine] Breaking change: compiler grammar v2 is now the default. ${legacyNote}`);\n }\n }\n\n // Extract the script content\n const scriptMatch = code.match(/<script>([\\s\\S]*?)<\\/script>/);\n let scriptContent = scriptMatch ? scriptMatch[1].trim() : \"\";\n \n // Extract the style tag with attributes and content\n const styleTagMatch = code.match(/<style([^>]*)>([\\s\\S]*?)<\\/style>/);\n let styleContent = \"\";\n let isScoped = false;\n \n if (styleTagMatch) {\n const styleAttributes = styleTagMatch[1].trim();\n styleContent = styleTagMatch[2].trim();\n \n // Check if scoped attribute is present\n isScoped = /scoped(?:\\s|>|$)/.test(styleAttributes);\n }\n \n // Remove script and style tags from template before parsing\n let template = code\n .replace(/<script>[\\s\\S]*?<\\/script>/, \"\")\n .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/, \"\")\n .replace(/^\\s+|\\s+$/g, '');\n\n let parsedTemplate;\n try {\n parsedTemplate = parser.parse(template);\n } catch (error) {\n const errorMsg = showErrorMessage(template, error);\n throw new Error(`Error parsing template in file ${id}:\\n${errorMsg}`);\n }\n\n // trick to avoid typescript remove imports in scriptContent\n scriptContent += FLAG_COMMENT + parsedTemplate\n\n let transpiledCode = ts.transpileModule(scriptContent, {\n compilerOptions: {\n module: ts.ModuleKind.Preserve,\n },\n }).outputText;\n\n // remove code after /*---*/\n transpiledCode = transpiledCode.split(FLAG_COMMENT)[0]\n\n // Use Acorn to parse the script content\n const parsed = parse(transpiledCode, {\n sourceType: \"module\",\n ecmaVersion: 2020,\n });\n\n // Extract imports\n const imports = parsed.body.filter(\n (node) => node.type === \"ImportDeclaration\"\n );\n\n // Extract non-import statements from scriptContent\n const nonImportCode = parsed.body\n .filter((node) => node.type !== \"ImportDeclaration\")\n .map((node) => transpiledCode.slice(node.start, node.end))\n .join(\"\\n\");\n\n let importsCode = imports\n .map((imp) => {\n let importCode = transpiledCode.slice(imp.start, imp.end);\n if (isDev && importCode.includes(\"from 'canvasengine'\")) {\n importCode = importCode.replace(\n \"from 'canvasengine'\",\n `from '${DEV_SRC}'`\n );\n }\n return importCode;\n })\n .join(\"\\n\");\n\n // Define an array for required imports\n const requiredImports = [\"h\", \"computed\", \"cond\", \"loop\"];\n\n // Check for missing imports\n const missingImports = requiredImports.filter(\n (importName) =>\n !imports.some(\n (imp) =>\n imp.specifiers &&\n imp.specifiers.some(\n (spec) =>\n spec.type === \"ImportSpecifier\" &&\n spec.imported && \n 'name' in spec.imported &&\n spec.imported.name === importName\n )\n )\n );\n\n // Add missing imports\n if (missingImports.length > 0) {\n const additionalImportCode = `import { ${missingImports.join(\n \", \"\n )} } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"};`;\n importsCode = `${additionalImportCode}\\n${importsCode}`;\n }\n\n // Check for primitive components in parsedTemplate\n const primitiveImports = PRIMITIVE_COMPONENTS.filter((component) =>\n parsedTemplate.includes(`h(${component}`)\n );\n\n // Add missing imports for primitive components\n primitiveImports.forEach((component) => {\n const importStatement = `import { ${component} } from ${\n isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"\n };`;\n if (!importsCode.includes(importStatement)) {\n importsCode = `${importStatement}\\n${importsCode}`;\n }\n });\n\n // Process CSS: scope it if scoped attribute is present\n let processedStyleContent = styleContent;\n let scopeClass = '';\n \n if (isScoped && styleContent) {\n // Generate short hash (8 characters) based on file path\n const fileHash = generateHash(id);\n scopeClass = fileHash;\n processedStyleContent = scopeCSS(styleContent, scopeClass);\n \n // Add _scopeClass prop to all DOMContainer in the template\n // Pattern: h(DOMContainer, { ... }) or h(DOMContainer) or h(DOMContainer, null, ...)\n parsedTemplate = parsedTemplate.replace(\n /h\\(DOMContainer\\s*,\\s*(\\{([^}]*)\\}|null)\\s*(,\\s*[^)]*)?\\)/g,\n (match, propsPart, propsContent, childrenPart) => {\n if (propsPart === 'null') {\n // h(DOMContainer, null, ...) -> h(DOMContainer, { _scopeClass: '...' }, ...)\n return `h(DOMContainer, { _scopeClass: '${scopeClass}' }${childrenPart || ''})`;\n } else {\n // h(DOMContainer, { ... }, ...) -> h(DOMContainer, { _scopeClass: '...', ... }, ...)\n // Need to insert _scopeClass at the beginning of the props object\n return `h(DOMContainer, { _scopeClass: '${scopeClass}', ${propsContent || ''} }${childrenPart || ''})`;\n }\n }\n );\n \n // Also handle h(DOMContainer) without props\n parsedTemplate = parsedTemplate.replace(\n /h\\(DOMContainer\\s*\\)(?!\\s*\\()/g,\n `h(DOMContainer, { _scopeClass: '${scopeClass}' })`\n );\n }\n \n // Escape style content for safe embedding in JavaScript string (using single quotes)\n // We need to escape: backslashes, single quotes, and line breaks\n const escapedStyleContent = processedStyleContent\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes first\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\\n/g, '\\\\n') // Escape newlines\n .replace(/\\r/g, '\\\\r'); // Escape carriage returns\n\n // Generate unique ID for style element based on file path\n const styleId = `ce-style-${id.replace(/[^a-zA-Z0-9]/g, '-')}`;\n\n // Generate CSS injection code if style content exists\n // Use single quotes to avoid escaping issues with backticks\n const styleInjectionCode = styleContent ? \n '// Inject CSS styles into the document head\\n' +\n `if (typeof document !== 'undefined' && !document.getElementById('${styleId}')) {\\n` +\n ' const styleElement = document.createElement(\\'style\\');\\n' +\n ` styleElement.id = '${styleId}';\\n` +\n ` styleElement.textContent = '${escapedStyleContent}';\\n` +\n ' document.head.appendChild(styleElement);\\n' +\n '}\\n'\n : '';\n \n\n // Generate the output\n const output = String.raw`\n ${importsCode}\n import { useProps, useDefineProps } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"}\n ${styleInjectionCode}\n export default function component($$props) {\n const $props = useProps($$props)\n const defineProps = useDefineProps($$props)\n ${nonImportCode}\n let $this = ${parsedTemplate}\n return $this\n }\n `;\n\n return {\n code: output,\n map: null,\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { createFilter } from \"vite\";\nimport { parse } from \"acorn\";\nimport fs from \"fs\";\nimport pkg from \"peggy\";\nimport path from \"path\";\nimport * as ts from \"typescript\";\nimport { fileURLToPath } from 'url';\n\nconst { generate } = pkg;\n\nconst DEV_SRC = \"../../src\"\n\n/**\n * Generates a short hash (8 characters, letters only) from a string\n * \n * @param {string} str - The string to hash\n * @returns {string} - An 8-character hash containing only lowercase letters (a-z)\n */\nfunction generateHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n // Convert to positive number and map to letters only (a-z)\n // Use modulo to map to 26 letters, then convert to character\n const positiveHash = Math.abs(hash);\n let result = '';\n for (let i = 0; i < 8; i++) {\n const letterIndex = (positiveHash + i * 31) % 26; // 31 is a prime to spread values\n result += String.fromCharCode(97 + letterIndex); // 97 is 'a'\n }\n return result;\n}\n\n/**\n * Formats a syntax error message with visual pointer to the error location\n * \n * @param {string} template - The template content that failed to parse\n * @param {object} error - The error object with location information\n * @returns {string} - Formatted error message with a visual pointer\n * \n * @example\n * ```\n * const errorMessage = showErrorMessage(\"<Canvas>test(d)</Canvas>\", syntaxError);\n * // Returns a formatted error message with an arrow pointing to 'd'\n * ```\n */\nfunction showErrorMessage(template: string, error: any): string {\n if (!error.location) {\n return `Syntax error: ${error.message}`;\n }\n\n const lines = template.split('\\n');\n const { line, column } = error.location.start;\n const errorLine = lines[line - 1] || '';\n \n // Create a visual pointer with an arrow\n const pointer = ' '.repeat(column - 1) + '^';\n \n return `Syntax error at line ${line}, column ${column}: ${error.message}\\n\\n` +\n `${errorLine}\\n${pointer}\\n`;\n}\n\n/**\n * Scopes CSS selectors by prefixing them with a class selector\n * \n * This function prefixes all CSS rule selectors (not @rules) with a class\n * selector to scope the styles to a specific component instance.\n * \n * @param {string} css - The CSS content to scope\n * @param {string} scopeClass - The unique scope class to use (without the dot)\n * @returns {string} - The scoped CSS content\n * \n * @example\n * ```\n * const scoped = scopeCSS('.my-class { color: red; }', 'ce-scope-abc123');\n * // Returns: '.ce-scope-abc123 .my-class { color: red; }'\n * ```\n */\nfunction scopeCSS(css: string, scopeClass: string): string {\n const scopeSelector = `.${scopeClass}`;\n \n // Process CSS by finding rule blocks while skipping @rules\n let result = '';\n let i = 0;\n let depth = 0;\n let inRule = false;\n let selectorBuffer = '';\n \n while (i < css.length) {\n const char = css[i];\n \n if (char === '@' && !inRule && selectorBuffer === '') {\n // Found @rule - copy it as-is until matching closing brace\n const atRuleStart = i;\n i++; // Skip '@'\n \n // Find the opening brace\n while (i < css.length && css[i] !== '{') {\n i++;\n }\n \n if (i < css.length) {\n // Found opening brace, now find matching closing brace\n depth = 1;\n i++; // Skip '{'\n \n while (i < css.length && depth > 0) {\n if (css[i] === '{') depth++;\n else if (css[i] === '}') depth--;\n i++;\n }\n \n // Copy entire @rule as-is\n result += css.substring(atRuleStart, i);\n }\n continue;\n }\n \n if (char === '{' && !inRule) {\n // Start of a rule block - scope the selector we just collected\n const selectorText = selectorBuffer.trim();\n \n if (selectorText) {\n // Split selectors by comma and scope each one\n const scopedSelectors = selectorText\n .split(',')\n .map(sel => {\n const trimmed = sel.trim();\n return trimmed ? `${scopeSelector} ${trimmed}` : trimmed;\n })\n .join(', ');\n \n result += scopedSelectors;\n }\n result += ' {';\n inRule = true;\n depth = 1;\n selectorBuffer = '';\n } else if (char === '{' && inRule) {\n // Nested brace\n result += char;\n depth++;\n } else if (char === '}' && inRule) {\n result += char;\n depth--;\n if (depth === 0) {\n inRule = false;\n }\n } else if (!inRule) {\n // Collecting selector\n selectorBuffer += char;\n } else {\n // Inside rule block\n result += char;\n if (char === '{') depth++;\n }\n \n i++;\n }\n \n // Add any remaining selector (shouldn't happen in valid CSS, but handle it)\n if (selectorBuffer.trim()) {\n const scopedSelectors = selectorBuffer.trim()\n .split(',')\n .map(sel => {\n const trimmed = sel.trim();\n return trimmed ? `${scopeSelector} ${trimmed}` : trimmed;\n })\n .join(', ');\n result += scopedSelectors;\n }\n \n return result;\n}\n\nfunction splitCallArguments(argsText: string): string[] {\n const args: string[] = [];\n let current = \"\";\n let depth = 0;\n let inSingle = false;\n let inDouble = false;\n let inTemplate = false;\n let escaped = false;\n\n for (let i = 0; i < argsText.length; i++) {\n const char = argsText[i];\n\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n current += char;\n escaped = true;\n continue;\n }\n\n if (inSingle) {\n current += char;\n if (char === \"'\") inSingle = false;\n continue;\n }\n\n if (inDouble) {\n current += char;\n if (char === '\"') inDouble = false;\n continue;\n }\n\n if (inTemplate) {\n current += char;\n if (char === \"`\") inTemplate = false;\n continue;\n }\n\n if (char === \"'\") {\n inSingle = true;\n current += char;\n continue;\n }\n\n if (char === '\"') {\n inDouble = true;\n current += char;\n continue;\n }\n\n if (char === \"`\") {\n inTemplate = true;\n current += char;\n continue;\n }\n\n if (char === \"(\" || char === \"{\" || char === \"[\") {\n depth++;\n current += char;\n continue;\n }\n\n if (char === \")\" || char === \"}\" || char === \"]\") {\n depth--;\n current += char;\n continue;\n }\n\n if (char === \",\" && depth === 0) {\n args.push(current.trim());\n current = \"\";\n continue;\n }\n\n current += char;\n }\n\n if (current.trim()) {\n args.push(current.trim());\n }\n\n return args;\n}\n\nfunction addScopeClassToDOMContainer(parsedTemplate: string, scopeClass: string): string {\n let result = \"\";\n let cursor = 0;\n\n while (cursor < parsedTemplate.length) {\n const start = parsedTemplate.indexOf(\"h(DOMContainer\", cursor);\n if (start === -1) {\n result += parsedTemplate.slice(cursor);\n break;\n }\n\n result += parsedTemplate.slice(cursor, start);\n const openParen = parsedTemplate.indexOf(\"(\", start);\n if (openParen === -1) {\n result += parsedTemplate.slice(start);\n break;\n }\n\n let depth = 0;\n let inSingle = false;\n let inDouble = false;\n let inTemplate = false;\n let escaped = false;\n let end = -1;\n\n for (let i = openParen; i < parsedTemplate.length; i++) {\n const char = parsedTemplate[i];\n\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (inSingle) {\n if (char === \"'\") inSingle = false;\n continue;\n }\n\n if (inDouble) {\n if (char === '\"') inDouble = false;\n continue;\n }\n\n if (inTemplate) {\n if (char === \"`\") inTemplate = false;\n continue;\n }\n\n if (char === \"'\") {\n inSingle = true;\n continue;\n }\n\n if (char === '\"') {\n inDouble = true;\n continue;\n }\n\n if (char === \"`\") {\n inTemplate = true;\n continue;\n }\n\n if (char === \"(\") depth++;\n if (char === \")\") depth--;\n\n if (depth === 0) {\n end = i + 1;\n break;\n }\n }\n\n if (end === -1) {\n result += parsedTemplate.slice(start);\n break;\n }\n\n const callText = parsedTemplate.slice(start, end);\n const argsText = parsedTemplate.slice(openParen + 1, end - 1);\n const args = splitCallArguments(argsText);\n\n if (args[0]?.trim() !== \"DOMContainer\") {\n result += callText;\n cursor = end;\n continue;\n }\n\n if (args.length === 1) {\n args.push(`{ _scopeClass: '${scopeClass}' }`);\n } else {\n const props = args[1].trim();\n if (props === \"null\" || props === \"undefined\") {\n args[1] = `{ _scopeClass: '${scopeClass}' }`;\n } else if (props.startsWith(\"{\")) {\n args[1] = props.replace(/^\\{\\s*/, `{ _scopeClass: '${scopeClass}', `);\n } else {\n args[1] = `{ _scopeClass: '${scopeClass}', ...${props} }`;\n }\n }\n\n result += `h(${args.join(\", \")})`;\n cursor = end;\n }\n\n return result;\n}\n\n/**\n * Vite plugin to load shader files (.frag, .vert, .wgsl) as text strings\n * \n * This plugin allows importing shader files directly as string literals in your code.\n * It supports fragment shaders (.frag), vertex shaders (.vert), and WebGPU shaders (.wgsl).\n * The content is loaded as a raw string and can be used directly with graphics APIs.\n * \n * @returns {object} - Vite plugin configuration object\n * \n * @example\n * ```typescript\n * // In your vite.config.ts\n * import { shaderLoader } from './path/to/compiler'\n * \n * export default defineConfig({\n * plugins: [shaderLoader()]\n * })\n * \n * // In your code\n * import fragmentShader from './shader.frag'\n * import vertexShader from './shader.vert'\n * import computeShader from './shader.wgsl'\n * \n * console.log(fragmentShader) // Raw shader code as string\n * ```\n */\nexport function shaderLoader() {\n const filter = createFilter(/\\.(frag|vert|wgsl)$/);\n\n return {\n name: \"vite-plugin-shader-loader\",\n transform(code: string, id: string) {\n if (!filter(id)) return;\n\n // Escape the shader code to be safely embedded in a JavaScript string\n const escapedCode = code\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/`/g, '\\\\`') // Escape backticks\n .replace(/\\$/g, '\\\\$'); // Escape dollar signs\n\n // Return the shader content as a default export string\n return {\n code: `export default \\`${escapedCode}\\`;`,\n map: null,\n };\n },\n };\n}\n\nexport default function canvasengine() {\n const filter = createFilter(\"**/*.ce\");\n const useLegacyGrammar = process.env.CANVASENGINE_COMPILER_V1 === \"1\";\n\n // Convert import.meta.url to a file path\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n\n const grammarFile = useLegacyGrammar ? \"grammar.pegjs\" : \"grammar2.pegjs\";\n const grammar = fs.readFileSync(\n path.join(__dirname, grammarFile),\n \"utf8\"\n );\n const parser = generate(grammar);\n const isDev = process.env.NODE_ENV === \"dev\";\n const FLAG_COMMENT = \"/*--[TPL]--*/\";\n let warnedAboutGrammar = false;\n\n const PRIMITIVE_COMPONENTS = [\n \"Canvas\",\n \"Sprite\",\n \"Text\",\n \"Viewport\",\n \"Graphics\",\n \"Container\",\n \"Navigation\",\n \"ImageMap\",\n \"NineSliceSprite\",\n \"Rect\",\n \"Circle\",\n \"Ellipse\",\n \"Triangle\",\n \"TilingSprite\",\n \"svg\",\n \"Video\",\n \"Mesh\",\n \"Svg\",\n \"DOMContainer\",\n \"DOMElement\",\n \"DOMSprite\",\n \"Button\",\n \"Joystick\"\n ];\n\n return {\n name: \"vite-plugin-ce\",\n transform(code: string, id: string) {\n if (!filter(id)) return null;\n if (!warnedAboutGrammar) {\n warnedAboutGrammar = true;\n const legacyNote = \"Set CANVASENGINE_COMPILER_V1=1 to compile with the legacy grammar (v1).\";\n if (useLegacyGrammar) {\n console.warn(`[canvasengine] Using legacy grammar v1. ${legacyNote}`);\n } else {\n console.warn(`[canvasengine] Breaking change: compiler grammar v2 is now the default. ${legacyNote}`);\n }\n }\n\n // Extract the script content\n const scriptMatch = code.match(/<script>([\\s\\S]*?)<\\/script>/);\n let scriptContent = scriptMatch ? scriptMatch[1].trim() : \"\";\n \n // Extract the style tag with attributes and content\n const styleTagMatch = code.match(/<style([^>]*)>([\\s\\S]*?)<\\/style>/);\n let styleContent = \"\";\n let isScoped = false;\n \n if (styleTagMatch) {\n const styleAttributes = styleTagMatch[1].trim();\n styleContent = styleTagMatch[2].trim();\n \n // Check if scoped attribute is present\n isScoped = /scoped(?:\\s|>|$)/.test(styleAttributes);\n }\n \n // Remove script and style tags from template before parsing\n let template = code\n .replace(/<script>[\\s\\S]*?<\\/script>/, \"\")\n .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/, \"\")\n .replace(/^\\s+|\\s+$/g, '');\n\n let parsedTemplate;\n try {\n parsedTemplate = parser.parse(template);\n } catch (error) {\n const errorMsg = showErrorMessage(template, error);\n throw new Error(`Error parsing template in file ${id}:\\n${errorMsg}`);\n }\n\n // trick to avoid typescript remove imports in scriptContent\n scriptContent += FLAG_COMMENT + parsedTemplate\n\n let transpiledCode = ts.transpileModule(scriptContent, {\n compilerOptions: {\n module: ts.ModuleKind.Preserve,\n },\n }).outputText;\n\n // remove code after /*---*/\n transpiledCode = transpiledCode.split(FLAG_COMMENT)[0]\n\n // Use Acorn to parse the script content\n const parsed = parse(transpiledCode, {\n sourceType: \"module\",\n ecmaVersion: 2020,\n });\n\n // Extract imports\n const imports = parsed.body.filter(\n (node) => node.type === \"ImportDeclaration\"\n );\n\n // Extract non-import statements from scriptContent\n const nonImportCode = parsed.body\n .filter((node) => node.type !== \"ImportDeclaration\")\n .map((node) => transpiledCode.slice(node.start, node.end))\n .join(\"\\n\");\n\n let importsCode = imports\n .map((imp) => {\n let importCode = transpiledCode.slice(imp.start, imp.end);\n if (isDev && importCode.includes(\"from 'canvasengine'\")) {\n importCode = importCode.replace(\n \"from 'canvasengine'\",\n `from '${DEV_SRC}'`\n );\n }\n return importCode;\n })\n .join(\"\\n\");\n\n // Define an array for required imports\n const requiredImports = [\"h\", \"computed\", \"cond\", \"loop\"];\n\n // Check for missing imports\n const missingImports = requiredImports.filter(\n (importName) =>\n !imports.some(\n (imp) =>\n imp.specifiers &&\n imp.specifiers.some(\n (spec) =>\n spec.type === \"ImportSpecifier\" &&\n spec.imported && \n 'name' in spec.imported &&\n spec.imported.name === importName\n )\n )\n );\n\n // Add missing imports\n if (missingImports.length > 0) {\n const additionalImportCode = `import { ${missingImports.join(\n \", \"\n )} } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"};`;\n importsCode = `${additionalImportCode}\\n${importsCode}`;\n }\n\n // Check for primitive components in parsedTemplate\n const primitiveImports = PRIMITIVE_COMPONENTS.filter((component) =>\n parsedTemplate.includes(`h(${component}`)\n );\n\n // Add missing imports for primitive components\n primitiveImports.forEach((component) => {\n const importStatement = `import { ${component} } from ${\n isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"\n };`;\n if (!importsCode.includes(importStatement)) {\n importsCode = `${importStatement}\\n${importsCode}`;\n }\n });\n\n // Process CSS: scope it if scoped attribute is present\n let processedStyleContent = styleContent;\n let scopeClass = '';\n \n if (isScoped && styleContent) {\n // Generate short hash (8 characters) based on file path\n const fileHash = generateHash(id);\n scopeClass = fileHash;\n processedStyleContent = scopeCSS(styleContent, scopeClass);\n \n // Add _scopeClass prop to all DOMContainer in the template\n parsedTemplate = addScopeClassToDOMContainer(parsedTemplate, scopeClass);\n }\n \n // Escape style content for safe embedding in JavaScript string (using single quotes)\n // We need to escape: backslashes, single quotes, and line breaks\n const escapedStyleContent = processedStyleContent\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes first\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\\n/g, '\\\\n') // Escape newlines\n .replace(/\\r/g, '\\\\r'); // Escape carriage returns\n\n // Generate unique ID for style element based on file path\n const styleId = `ce-style-${id.replace(/[^a-zA-Z0-9]/g, '-')}`;\n\n // Generate CSS injection code if style content exists\n // Use single quotes to avoid escaping issues with backticks\n const styleInjectionCode = styleContent ? \n '// Inject CSS styles into the document head\\n' +\n `if (typeof document !== 'undefined' && !document.getElementById('${styleId}')) {\\n` +\n ' const styleElement = document.createElement(\\'style\\');\\n' +\n ` styleElement.id = '${styleId}';\\n` +\n ` styleElement.textContent = '${escapedStyleContent}';\\n` +\n ' document.head.appendChild(styleElement);\\n' +\n '}\\n'\n : '';\n \n\n // Generate the output\n const output = String.raw`\n ${importsCode}\n import { useProps, useDefineProps } from ${isDev ? `'${DEV_SRC}'` : \"'canvasengine'\"}\n ${styleInjectionCode}\n export default function component($$props) {\n const $props = useProps($$props)\n const defineProps = useDefineProps($$props)\n ${nonImportCode}\n let $this = ${parsedTemplate}\n return $this\n }\n `;\n\n return {\n code: output,\n map: null,\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
|