fynixui 1.0.2 → 1.0.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.

Potentially problematic release.


This version of fynixui might be problematic. Click here for more details.

package/dist/README.md DELETED
@@ -1,36 +0,0 @@
1
- # Fynix Core
2
-
3
- This is the core package for the Fynix UI framework. It contains the essential runtime, hooks, context, and utilities for building Fynix-based applications.
4
-
5
- ## Structure
6
- - `runtime.js`: Main runtime logic
7
- - `context/`: Context management
8
- - `custom/`: Custom UI elements
9
- - `error/`: Error overlays and handling
10
- - `fynix/`: Fynix core logic
11
- - `hooks/`: Reactivity and utility hooks
12
- - `plugins/`: Plugins (e.g., Vite integration)
13
- - `router/`: Routing logic
14
- - `types/`: TypeScript type definitions
15
- - `global.d.ts`: Global type extensions
16
-
17
- ## Usage
18
- Install via npm after publishing:
19
-
20
- ```sh
21
- npm install fynix-core
22
- ```
23
-
24
- Then import in your project:
25
-
26
- ```js
27
- import { ... } from 'fynix-core';
28
- ```
29
-
30
- ## Development
31
- - Ensure all files are included in `package.json`.
32
- - Update type definitions in `global.d.ts` as needed.
33
- - Export all public APIs via the `exports` field in `package.json`.
34
-
35
- ## License
36
- MIT
@@ -1,49 +0,0 @@
1
- export interface SourceMap {
2
- originalToTransformed: Map<number, number>;
3
- transformedToOriginal: Map<number, number>;
4
- }
5
- export interface ParsedFnxFile {
6
- logic: string;
7
- view: string;
8
- style: string;
9
- logicLang: "ts" | "js";
10
- hasLogic: boolean;
11
- hasView: boolean;
12
- hasStyle: boolean;
13
- isStyleScoped: boolean;
14
- imports: string[];
15
- exports: string[];
16
- logicStartLine: number;
17
- viewStartLine: number;
18
- styleStartLine: number;
19
- }
20
- export interface TransformResult {
21
- code: string;
22
- lineMap: number[];
23
- sourceMap: SourceMap;
24
- }
25
- export interface ParseOptions {
26
- debug?: boolean;
27
- logger?: (message: string) => void;
28
- }
29
- export interface TransformOptions extends ParseOptions {
30
- filePath: string;
31
- jsxFactory?: string;
32
- includeStyleInjection?: boolean;
33
- includeMetaInjection?: boolean;
34
- }
35
- export declare function parseFnxFile(source: string, options?: ParseOptions): ParsedFnxFile;
36
- export declare function validateParsedFnx(parsed: ParsedFnxFile, filePath: string): void;
37
- export declare function generateStyleId(filePath: string): string;
38
- export declare function scopeStyles(css: string, scopeId: string): string;
39
- export declare function buildSourceMap(originalContent: string, transformedContent: string, lineMap: number[]): SourceMap;
40
- export declare function transformToComponent(parsed: ParsedFnxFile, options: TransformOptions): TransformResult;
41
- export declare function transformToTsx(source: string, options?: ParseOptions): TransformResult;
42
- export declare function getLineAndCharacterOfPosition(text: string, pos: number): {
43
- line: number;
44
- character: number;
45
- };
46
- export declare function getPositionOfLineAndCharacter(text: string, line: number, character: number): number;
47
- export declare function mapTransformedToOriginal(position: number, transformedCode: string, originalContent: string, lineMap: number[], sourceMap: SourceMap): number;
48
- export declare function mapOriginalToTransformed(position: number, transformedCode: string, originalContent: string, lineMap: number[], sourceMap: SourceMap): number;
49
- //# sourceMappingURL=fnx-parser.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fnx-parser.d.ts","sourceRoot":"","sources":["../../parser/fnx-parser.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,SAAS;IACtB,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAKD,MAAM,WAAW,aAAa;IAE1B,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IAEvB,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EAAE,OAAO,CAAC;IAElB,aAAa,EAAE,OAAO,CAAC;IAEvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,cAAc,EAAE,MAAM,CAAC;IAEvB,aAAa,EAAE,MAAM,CAAC;IAEtB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAKD,MAAM,WAAW,eAAe;IAE5B,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,SAAS,EAAE,SAAS,CAAC;CACxB;AAKD,MAAM,WAAW,YAAY;IAEzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAKD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IAElD,QAAQ,EAAE,MAAM,CAAC;IAEjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAcD,wBAAgB,YAAY,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,YAAiB,GAC3B,aAAa,CAuJf;AAUD,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,GACjB,IAAI,CAyCN;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQxD;AAKD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBhE;AAKD,wBAAgB,cAAc,CAC1B,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,MAAM,EAAE,GAClB,SAAS,CAiDX;AAUD,wBAAgB,oBAAoB,CAChC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,GAC1B,eAAe,CAiKjB;AAUD,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,YAAiB,GAC3B,eAAe,CA6HjB;AA6CD,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAiBrC;AAKD,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAClB,MAAM,CAWR;AAKD,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,SAAS,GACrB,MAAM,CAmBR;AAKD,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,SAAS,GACrB,MAAM,CAkBR"}
@@ -1,483 +0,0 @@
1
- export function parseFnxFile(source, options = {}) {
2
- const { debug = false, logger = console.log } = options;
3
- const result = {
4
- logic: "",
5
- view: "",
6
- style: "",
7
- logicLang: "ts",
8
- hasLogic: false,
9
- hasView: false,
10
- hasStyle: false,
11
- isStyleScoped: false,
12
- imports: [],
13
- exports: [],
14
- logicStartLine: 0,
15
- viewStartLine: 0,
16
- styleStartLine: 0,
17
- };
18
- const logicMatch = source.match(/<logic\s+setup\s*=\s*["']?(ts|js)["']?\s*>([\s\S]*?)<\/logic>/i);
19
- if (logicMatch && logicMatch[1] && logicMatch[2] !== undefined) {
20
- result.hasLogic = true;
21
- result.logicLang = logicMatch[1].toLowerCase();
22
- const beforeLogic = source.slice(0, logicMatch.index);
23
- const beforeLineCount = beforeLogic.split("\n").length - 1;
24
- const openingTag = logicMatch[0].substring(0, logicMatch[0].indexOf(">") + 1);
25
- const tagLineCount = openingTag.split("\n").length - 1;
26
- result.logicStartLine = beforeLineCount + tagLineCount + 1;
27
- const rawLogic = logicMatch[2].trim();
28
- const leadingNewlines = logicMatch[2].match(/^\n*/)?.[0].length || 0;
29
- result.logicStartLine += leadingNewlines;
30
- const logicLines = rawLogic.split("\n");
31
- const imports = [];
32
- const exports = [];
33
- const otherLogic = [];
34
- let inExportBlock = false;
35
- let exportBuffer = [];
36
- let exportBraceDepth = 0;
37
- for (let i = 0; i < logicLines.length; i++) {
38
- const line = logicLines[i] ?? "";
39
- const trimmed = line.trim();
40
- if (inExportBlock) {
41
- exportBuffer.push(line);
42
- const openBraces = ((line && line.match(/{/g)) || []).length;
43
- const closeBraces = ((line && line.match(/}/g)) || []).length;
44
- exportBraceDepth += openBraces - closeBraces;
45
- if (exportBraceDepth <= 0) {
46
- exports.push(exportBuffer.join("\n"));
47
- exportBuffer = [];
48
- inExportBlock = false;
49
- exportBraceDepth = 0;
50
- }
51
- continue;
52
- }
53
- if (trimmed.startsWith("import ")) {
54
- imports.push(line ?? "");
55
- }
56
- else if (trimmed.startsWith("export ")) {
57
- if (/export\s+\w+\s*=\s*{/.test(trimmed) || trimmed.endsWith("{")) {
58
- inExportBlock = true;
59
- exportBuffer = [line];
60
- exportBraceDepth =
61
- ((line && line.match(/{/g)) || []).length -
62
- ((line && line.match(/}/g)) || []).length;
63
- if (exportBraceDepth <= 0) {
64
- exports.push(exportBuffer.join("\n"));
65
- exportBuffer = [];
66
- inExportBlock = false;
67
- exportBraceDepth = 0;
68
- }
69
- }
70
- else {
71
- exports.push(line ?? "");
72
- }
73
- }
74
- else if (trimmed) {
75
- otherLogic.push(line ?? "");
76
- }
77
- }
78
- if (exportBuffer.length > 0) {
79
- exports.push(exportBuffer.join("\n"));
80
- }
81
- result.imports = imports;
82
- result.exports = exports;
83
- result.logic = otherLogic.join("\n");
84
- if (debug) {
85
- logger(`[FnxParser] Logic block: lang=${result.logicLang}, start=${result.logicStartLine}, imports=${imports.length}, exports=${exports.length}`);
86
- }
87
- }
88
- const viewMatch = source.match(/<view\s*>([\s\S]*?)<\/view>/i);
89
- if (viewMatch && viewMatch[1] !== undefined) {
90
- result.hasView = true;
91
- result.view = viewMatch[1].trim();
92
- const beforeView = source.slice(0, viewMatch.index);
93
- result.viewStartLine = beforeView.split("\n").length;
94
- const leadingNewlines = viewMatch[1].match(/^\n*/)?.[0].length || 0;
95
- result.viewStartLine += leadingNewlines;
96
- if (debug) {
97
- logger(`[FnxParser] View block: start=${result.viewStartLine}`);
98
- }
99
- }
100
- const styleMatch = source.match(/<style(\s+scoped)?\s*>([\s\S]*?)<\/style>/i);
101
- if (styleMatch && styleMatch[2] !== undefined) {
102
- result.hasStyle = true;
103
- result.isStyleScoped = !!styleMatch[1];
104
- result.style = styleMatch[2].trim();
105
- const beforeStyle = source.slice(0, styleMatch.index);
106
- result.styleStartLine = beforeStyle.split("\n").length;
107
- if (debug) {
108
- logger(`[FnxParser] Style block: scoped=${result.isStyleScoped}, start=${result.styleStartLine}`);
109
- }
110
- }
111
- return result;
112
- }
113
- export function validateParsedFnx(parsed, filePath) {
114
- if (!parsed.hasView) {
115
- throw new Error(`[FnxParser] Missing <view> block in ${filePath}. Every .fnx file must have a <view> section.`);
116
- }
117
- if (parsed.hasLogic && !["ts", "js"].includes(parsed.logicLang)) {
118
- throw new Error(`[FnxParser] Invalid setup attribute in <logic> block in ${filePath}. Must be "ts" or "js".`);
119
- }
120
- if (parsed.hasLogic && parsed.logicLang === "js") {
121
- const tsPatterns = [
122
- { pattern: /\binterface\s+\w+/, name: "interface declaration" },
123
- { pattern: /\btype\s+\w+\s*=/, name: "type alias" },
124
- { pattern: /:\s*\w+(\[\]|<[^>]+>)?\s*[;,=)]/, name: "type annotation" },
125
- { pattern: /<\w+>(?!\s*<)/, name: "generic type" },
126
- { pattern: /\benum\s+\w+/, name: "enum declaration" },
127
- { pattern: /\bas\s+\w+/, name: "type assertion" },
128
- { pattern: /\bnamespace\s+\w+/, name: "namespace" },
129
- { pattern: /\babstract\s+class/, name: "abstract class" },
130
- {
131
- pattern: /\bpublic\s+|private\s+|protected\s+/,
132
- name: "access modifier",
133
- },
134
- ];
135
- const allCode = parsed.logic + "\n" + parsed.imports.join("\n");
136
- for (const { pattern, name } of tsPatterns) {
137
- if (pattern.test(allCode)) {
138
- throw new Error(`[FnxParser] TypeScript syntax detected (${name}) in ${filePath} with setup="js". ` +
139
- `Either change to setup="ts" or remove TypeScript-specific syntax.`);
140
- }
141
- }
142
- }
143
- }
144
- export function generateStyleId(filePath) {
145
- let hash = 0;
146
- for (let i = 0; i < filePath.length; i++) {
147
- const char = filePath.charCodeAt(i);
148
- hash = (hash << 5) - hash + char;
149
- hash = hash & hash;
150
- }
151
- return `fynix-${Math.abs(hash).toString(36)}`;
152
- }
153
- export function scopeStyles(css, scopeId) {
154
- const dataAttr = `[data-${scopeId}]`;
155
- return css.replace(/([^{}]+)\{([^{}]*)\}/g, (match, selector, rules) => {
156
- if (selector.trim().startsWith("@")) {
157
- return match;
158
- }
159
- const selectors = selector.split(",").map((s) => {
160
- const trimmed = s.trim();
161
- const pseudoMatch = trimmed.match(/^(.+?)(::?[a-z-]+(?:\([^)]*\))?)$/i);
162
- if (pseudoMatch) {
163
- return `${dataAttr} ${pseudoMatch[1]}${pseudoMatch[2]}`;
164
- }
165
- return `${dataAttr} ${trimmed}`;
166
- });
167
- return `${selectors.join(", ")}{${rules}}`;
168
- });
169
- }
170
- export function buildSourceMap(originalContent, transformedContent, lineMap) {
171
- const originalToTransformed = new Map();
172
- const transformedToOriginal = new Map();
173
- const originalLines = originalContent.split("\n");
174
- const transformedLines = transformedContent.split("\n");
175
- let transformedPos = 0;
176
- for (let tLine = 0; tLine < transformedLines.length; tLine++) {
177
- const originalLine = lineMap[tLine];
178
- if (originalLine !== undefined && originalLine >= 0 && originalLine < originalLines.length) {
179
- let originalPos = 0;
180
- for (let i = 0; i < originalLine; i++) {
181
- const lineLen = originalLines[i];
182
- originalPos += (lineLen?.length ?? 0) + 1;
183
- }
184
- transformedToOriginal.set(transformedPos, originalPos);
185
- originalToTransformed.set(originalPos, transformedPos);
186
- const transformedLineText = transformedLines[tLine] ?? "";
187
- const originalLineText = originalLines[originalLine] ?? "";
188
- const tTrimmed = transformedLineText.trimStart();
189
- const oTrimmed = originalLineText.trimStart();
190
- for (let char = 0; char < Math.min(tTrimmed.length, oTrimmed.length); char++) {
191
- const tPos = transformedPos + char + (transformedLineText.length - tTrimmed.length);
192
- const oPos = originalPos + char + (originalLineText.length - oTrimmed.length);
193
- transformedToOriginal.set(tPos, oPos);
194
- originalToTransformed.set(oPos, tPos);
195
- }
196
- }
197
- const currentTransLine = transformedLines[tLine];
198
- transformedPos += (currentTransLine?.length ?? 0) + 1;
199
- }
200
- return { originalToTransformed, transformedToOriginal };
201
- }
202
- export function transformToComponent(parsed, options) {
203
- const { filePath, jsxFactory = "Fynix", includeStyleInjection = true, includeMetaInjection = true, debug = false, logger = console.log, } = options;
204
- const styleId = generateStyleId(filePath);
205
- const lines = [];
206
- const lineMap = [];
207
- const push = (line, origin = -1) => {
208
- lines.push(line);
209
- lineMap.push(origin);
210
- };
211
- push(`import { ${jsxFactory} } from 'fynixui';`);
212
- if (parsed.imports.length > 0) {
213
- parsed.imports.forEach((importLine, i) => {
214
- push(importLine, parsed.logicStartLine + i);
215
- });
216
- }
217
- push("");
218
- if (parsed.hasStyle && includeStyleInjection) {
219
- let processedStyle = parsed.style;
220
- if (parsed.isStyleScoped) {
221
- processedStyle = scopeStyles(parsed.style, styleId);
222
- }
223
- push(`// Inject styles`);
224
- push(`if (typeof document !== 'undefined') {`);
225
- push(` const styleId = '${styleId}';`);
226
- push(` if (!document.getElementById(styleId)) {`);
227
- push(` const styleEl = document.createElement('style');`);
228
- push(` styleEl.id = styleId;`);
229
- push(` styleEl.textContent = ${JSON.stringify(processedStyle)};`);
230
- push(` document.head.appendChild(styleEl);`);
231
- push(` }`);
232
- push(`}`);
233
- push("");
234
- }
235
- if (parsed.exports.length > 0) {
236
- parsed.exports.forEach((exportLine) => {
237
- const exportLines = exportLine.split("\n");
238
- exportLines.forEach((line) => push(line));
239
- });
240
- push("");
241
- }
242
- push(`function FynixComponent(props = {}) {`);
243
- if (parsed.hasLogic && parsed.logic.trim()) {
244
- push(` // Component logic`);
245
- const logicLines = parsed.logic.split("\n");
246
- logicLines.forEach((line, i) => {
247
- if (line.trim()) {
248
- push(` ${line}`, parsed.logicStartLine + parsed.imports.length + i);
249
- }
250
- });
251
- push("");
252
- }
253
- if (includeMetaInjection &&
254
- parsed.exports.some((e) => e.trim().startsWith("export const meta"))) {
255
- push(` if (typeof document !== "undefined" && typeof meta !== "undefined") {`);
256
- push(` document.title = meta.title;`);
257
- push(` const metaTags = [`);
258
- push(` { name: "description", content: meta.description },`);
259
- push(` { name: "keywords", content: meta.keywords },`);
260
- push(` { property: "og:title", content: meta.ogTitle },`);
261
- push(` { property: "og:description", content: meta.ogDescription },`);
262
- push(` { property: "og:image", content: meta.ogImage },`);
263
- push(` ];`);
264
- push(` metaTags.forEach(({ name, property, content }) => {`);
265
- push(` if (!content) return;`);
266
- push(` let tag;`);
267
- push(` if (name) {`);
268
- push(` tag = document.querySelector(\`meta[name='\${name}']\`);`);
269
- push(` if (!tag) {`);
270
- push(` tag = document.createElement("meta");`);
271
- push(` tag.setAttribute("name", name);`);
272
- push(` document.head.appendChild(tag);`);
273
- push(` }`);
274
- push(` } else if (property) {`);
275
- push(` tag = document.querySelector(\`meta[property='\${property}']\`);`);
276
- push(` if (!tag) {`);
277
- push(` tag = document.createElement("meta");`);
278
- push(` tag.setAttribute("property", property);`);
279
- push(` document.head.appendChild(tag);`);
280
- push(` }`);
281
- push(` }`);
282
- push(` if (tag) tag.setAttribute("content", content);`);
283
- push(` });`);
284
- push(` }`);
285
- push("");
286
- }
287
- if (parsed.hasView) {
288
- push(` // Component view`);
289
- if (parsed.isStyleScoped) {
290
- push(` return (`);
291
- push(` <div data-${styleId}="">`);
292
- const viewLines = parsed.view.split("\n");
293
- viewLines.forEach((line, i) => {
294
- push(` ${line}`, parsed.viewStartLine + i);
295
- });
296
- push(` </div>`);
297
- push(` );`);
298
- }
299
- else {
300
- push(` return (`);
301
- const viewLines = parsed.view.split("\n");
302
- viewLines.forEach((line, i) => {
303
- push(` ${line}`, parsed.viewStartLine + i);
304
- });
305
- push(` );`);
306
- }
307
- }
308
- else {
309
- push(` return null;`);
310
- }
311
- push(`}`);
312
- push("");
313
- push(`export default FynixComponent;`);
314
- const code = lines.join("\n");
315
- const sourceMap = buildSourceMap(createOriginalContent(parsed), code, lineMap);
316
- if (debug) {
317
- logger(`[FnxParser] Transformed ${filePath}: ${code.length} bytes`);
318
- }
319
- return { code, lineMap, sourceMap };
320
- }
321
- export function transformToTsx(source, options = {}) {
322
- const { debug = false, logger = console.log } = options;
323
- const lines = [];
324
- const lineMap = [];
325
- const push = (line, origin = -1) => {
326
- lines.push(line);
327
- lineMap.push(origin);
328
- };
329
- const logicMatch = source.match(/<logic\s+setup\s*=\s*["']?(ts|js)["']?\s*>([\s\S]*?)<\/logic>/i);
330
- let logicStart = 0;
331
- let logicContent = "";
332
- if (logicMatch) {
333
- const before = source.slice(0, logicMatch.index);
334
- const beforeLineCount = before.split("\n").length - 1;
335
- const openingTag = logicMatch[0].substring(0, logicMatch[0].indexOf(">") + 1);
336
- const tagLineCount = openingTag.split("\n").length - 1;
337
- logicStart = beforeLineCount + tagLineCount + 1;
338
- logicContent = logicMatch[2] ?? "";
339
- const leadingNewlines = logicContent.match(/^\n*/)?.[0].length || 0;
340
- logicStart += leadingNewlines;
341
- logicContent = logicContent.trimStart();
342
- if (debug) {
343
- logger(`[FnxParser TSX] Logic starts at line ${logicStart}`);
344
- }
345
- }
346
- const userImports = [];
347
- const userBody = [];
348
- let hasFynixImport = false;
349
- if (logicContent) {
350
- const logicLines = logicContent.split("\n");
351
- const lastLine = logicLines[logicLines.length - 1];
352
- if (logicLines.length > 0 &&
353
- lastLine !== undefined &&
354
- lastLine.trim() === "") {
355
- logicLines.pop();
356
- }
357
- logicLines.forEach((line, i) => {
358
- const trimmed = line.trim();
359
- const origin = logicStart + i;
360
- if (trimmed.startsWith("import ")) {
361
- userImports.push({ line, origin });
362
- if (trimmed.includes("fynixui")) {
363
- hasFynixImport = true;
364
- }
365
- }
366
- else {
367
- userBody.push({ line, origin });
368
- }
369
- });
370
- }
371
- userImports.forEach((item) => {
372
- push(item.line, item.origin);
373
- });
374
- if (!hasFynixImport) {
375
- push(`import { Fynix } from "fynixui";`);
376
- }
377
- push("");
378
- push("export default function FynixComponent(props: any = {}) {");
379
- userBody.forEach((item) => {
380
- push(" " + item.line, item.origin);
381
- });
382
- const viewMatch = source.match(/<view\s*>([\s\S]*?)<\/view>/i);
383
- if (viewMatch) {
384
- let viewContent = viewMatch[1] ?? "";
385
- const before = source.slice(0, viewMatch.index);
386
- const beforeLineCount = before.split("\n").length - 1;
387
- let viewStart = beforeLineCount + 1;
388
- const leadingNewlines = viewContent.match(/^\n*/)?.[0].length || 0;
389
- viewStart += leadingNewlines;
390
- viewContent = viewContent.trimStart();
391
- if (debug) {
392
- logger(`[FnxParser TSX] View starts at line ${viewStart}`);
393
- }
394
- push(" return (");
395
- const viewLines = viewContent.split("\n");
396
- viewLines.forEach((line, i) => {
397
- push(" " + line, viewStart + i);
398
- });
399
- push(" );");
400
- }
401
- else {
402
- push(" return null;");
403
- }
404
- push("}");
405
- const code = lines.join("\n");
406
- const sourceMap = buildSourceMap(source, code, lineMap);
407
- return { code, lineMap, sourceMap };
408
- }
409
- function createOriginalContent(parsed) {
410
- const parts = [];
411
- if (parsed.hasLogic) {
412
- parts.push(`<logic setup="${parsed.logicLang}">`);
413
- if (parsed.imports.length > 0) {
414
- parts.push(parsed.imports.join("\n"));
415
- }
416
- if (parsed.exports.length > 0) {
417
- parts.push(parsed.exports.join("\n"));
418
- }
419
- if (parsed.logic.trim()) {
420
- parts.push(parsed.logic);
421
- }
422
- parts.push("</logic>");
423
- }
424
- if (parsed.hasView) {
425
- parts.push(`<view>`);
426
- parts.push(parsed.view);
427
- parts.push("</view>");
428
- }
429
- if (parsed.hasStyle) {
430
- parts.push(parsed.isStyleScoped ? `<style scoped>` : `<style>`);
431
- parts.push(parsed.style);
432
- parts.push("</style>");
433
- }
434
- return parts.join("\n");
435
- }
436
- export function getLineAndCharacterOfPosition(text, pos) {
437
- const lines = text.split("\n");
438
- let currentPos = 0;
439
- for (let line = 0; line < lines.length; line++) {
440
- const currentLine = lines[line];
441
- const lineLength = (currentLine?.length ?? 0) + 1;
442
- if (currentPos + lineLength > pos) {
443
- return {
444
- line,
445
- character: pos - currentPos,
446
- };
447
- }
448
- currentPos += lineLength;
449
- }
450
- return { line: Math.max(0, lines.length - 1), character: 0 };
451
- }
452
- export function getPositionOfLineAndCharacter(text, line, character) {
453
- const lines = text.split("\n");
454
- let pos = 0;
455
- for (let i = 0; i < line && i < lines.length; i++) {
456
- const currentLine = lines[i];
457
- pos += (currentLine?.length ?? 0) + 1;
458
- }
459
- const targetLine = lines[line];
460
- return pos + Math.min(character, targetLine?.length ?? 0);
461
- }
462
- export function mapTransformedToOriginal(position, transformedCode, originalContent, lineMap, sourceMap) {
463
- if (sourceMap.transformedToOriginal.has(position)) {
464
- return sourceMap.transformedToOriginal.get(position);
465
- }
466
- const { line: tLine, character: tChar } = getLineAndCharacterOfPosition(transformedCode, position);
467
- const originalLine = lineMap[tLine];
468
- if (originalLine === undefined || originalLine < 0) {
469
- return 0;
470
- }
471
- return getPositionOfLineAndCharacter(originalContent, originalLine, tChar);
472
- }
473
- export function mapOriginalToTransformed(position, transformedCode, originalContent, lineMap, sourceMap) {
474
- if (sourceMap.originalToTransformed.has(position)) {
475
- return sourceMap.originalToTransformed.get(position);
476
- }
477
- const { line: oLine, character: oChar } = getLineAndCharacterOfPosition(originalContent, position);
478
- const tLine = lineMap.indexOf(oLine);
479
- if (tLine < 0) {
480
- return 0;
481
- }
482
- return getPositionOfLineAndCharacter(transformedCode, tLine, oChar);
483
- }