@litsx/authoring 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1067 @@
1
+ 'use strict';
2
+
3
+ var MagicString = require('magic-string');
4
+
5
+ const PREFIX_TO_KIND = {
6
+ "@": "event",
7
+ ".": "prop",
8
+ "?": "bool",
9
+ };
10
+
11
+ const KIND_TO_PREFIX = {
12
+ event: "@",
13
+ prop: ".",
14
+ bool: "?",
15
+ };
16
+
17
+ const ATTR_NAME_CHAR = /[\w:-]/;
18
+ const TAG_NAME_START_CHAR = /[A-Za-z]/;
19
+ const TAG_NAME_CHAR = /[\w:.-]/;
20
+ const MACRO_NAME_START_CHAR = /[A-Za-z$_]/;
21
+ const MACRO_NAME_CHAR = /[A-Za-z0-9$_]/;
22
+
23
+ function isWhitespace(char) {
24
+ return char === " " || char === "\t" || char === "\n" || char === "\r";
25
+ }
26
+
27
+ function isReservedVirtualAttributeName(name) {
28
+ return /^__litsx_(event|prop|bool)_/.test(name);
29
+ }
30
+
31
+ function sanitizeIdentifierTailChar(char) {
32
+ return /[A-Za-z0-9$_]/.test(char) ? char : "_";
33
+ }
34
+
35
+ function isIdentifierStartChar(char) {
36
+ return /[A-Za-z$_]/.test(char);
37
+ }
38
+
39
+ function isIdentifierChar(char) {
40
+ return /[A-Za-z0-9$_]/.test(char);
41
+ }
42
+
43
+ function encodeEditorVirtualAttributeName(name) {
44
+ const prefix = name[0];
45
+ const localName = name.slice(1);
46
+ const encodedPrefix = prefix === "@" ? "e" : prefix === "." ? "p" : "b";
47
+ return `${encodedPrefix}${Array.from(localName, sanitizeIdentifierTailChar).join("")}`;
48
+ }
49
+
50
+ function encodeEditorStaticHoistAssignment(name) {
51
+ return `const $${name} = `;
52
+ }
53
+
54
+ function scanQuotedString(sourceText, start, quote) {
55
+ let index = start + 1;
56
+
57
+ while (index < sourceText.length) {
58
+ const char = sourceText[index];
59
+ if (char === "\\") {
60
+ index += 2;
61
+ continue;
62
+ }
63
+ if (char === quote) {
64
+ return index + 1;
65
+ }
66
+ index += 1;
67
+ }
68
+
69
+ return index;
70
+ }
71
+
72
+ function scanLineComment(sourceText, start) {
73
+ let index = start + 2;
74
+ while (index < sourceText.length && sourceText[index] !== "\n") {
75
+ index += 1;
76
+ }
77
+ return index;
78
+ }
79
+
80
+ function scanBlockComment(sourceText, start) {
81
+ let index = start + 2;
82
+ while (index < sourceText.length) {
83
+ if (sourceText[index] === "*" && sourceText[index + 1] === "/") {
84
+ return index + 2;
85
+ }
86
+ index += 1;
87
+ }
88
+ return index;
89
+ }
90
+
91
+ function scanTemplateLiteral(sourceText, start) {
92
+ let index = start + 1;
93
+
94
+ while (index < sourceText.length) {
95
+ const char = sourceText[index];
96
+ if (char === "\\") {
97
+ index += 2;
98
+ continue;
99
+ }
100
+ if (char === "`") {
101
+ return index + 1;
102
+ }
103
+ if (char === "$" && sourceText[index + 1] === "{") {
104
+ index = scanBalancedBraces(sourceText, index + 1);
105
+ continue;
106
+ }
107
+ index += 1;
108
+ }
109
+
110
+ return index;
111
+ }
112
+
113
+ function scanBalancedBraces(sourceText, start) {
114
+ let depth = 0;
115
+ let index = start;
116
+
117
+ while (index < sourceText.length) {
118
+ const char = sourceText[index];
119
+ const next = sourceText[index + 1];
120
+
121
+ if (char === "'" || char === "\"") {
122
+ index = scanQuotedString(sourceText, index, char);
123
+ continue;
124
+ }
125
+
126
+ if (char === "`") {
127
+ index = scanTemplateLiteral(sourceText, index);
128
+ continue;
129
+ }
130
+
131
+ if (char === "/" && next === "/") {
132
+ index = scanLineComment(sourceText, index);
133
+ continue;
134
+ }
135
+
136
+ if (char === "/" && next === "*") {
137
+ index = scanBlockComment(sourceText, index);
138
+ continue;
139
+ }
140
+
141
+ if (char === "{") {
142
+ depth += 1;
143
+ index += 1;
144
+ continue;
145
+ }
146
+
147
+ if (char === "}") {
148
+ depth -= 1;
149
+ index += 1;
150
+ if (depth <= 0) {
151
+ return index;
152
+ }
153
+ continue;
154
+ }
155
+
156
+ index += 1;
157
+ }
158
+
159
+ return index;
160
+ }
161
+
162
+ function scanBalancedBracesWithJsx(sourceText, start, replacements, encodeAttributeName) {
163
+ let depth = 0;
164
+ let index = start;
165
+
166
+ while (index < sourceText.length) {
167
+ const char = sourceText[index];
168
+ const next = sourceText[index + 1];
169
+
170
+ if (char === "'" || char === "\"") {
171
+ index = scanQuotedString(sourceText, index, char);
172
+ continue;
173
+ }
174
+
175
+ if (char === "`") {
176
+ index = scanTemplateLiteral(sourceText, index);
177
+ continue;
178
+ }
179
+
180
+ if (char === "/" && next === "/") {
181
+ index = scanLineComment(sourceText, index);
182
+ continue;
183
+ }
184
+
185
+ if (char === "/" && next === "*") {
186
+ index = scanBlockComment(sourceText, index);
187
+ continue;
188
+ }
189
+
190
+ if (char === "<" && isLikelyJsxTagStart(sourceText, index)) {
191
+ index = scanJsxElement(sourceText, index, replacements, encodeAttributeName);
192
+ continue;
193
+ }
194
+
195
+ if (char === "{") {
196
+ depth += 1;
197
+ index += 1;
198
+ continue;
199
+ }
200
+
201
+ if (char === "}") {
202
+ depth -= 1;
203
+ index += 1;
204
+ if (depth <= 0) {
205
+ return index;
206
+ }
207
+ continue;
208
+ }
209
+
210
+ index += 1;
211
+ }
212
+
213
+ return index;
214
+ }
215
+
216
+ function trimTrailingWhitespaceAndComments(sourceText) {
217
+ let text = sourceText;
218
+ let changed = true;
219
+
220
+ while (changed) {
221
+ changed = false;
222
+
223
+ const trimmedWhitespace = text.replace(/\s+$/u, "");
224
+ if (trimmedWhitespace !== text) {
225
+ text = trimmedWhitespace;
226
+ changed = true;
227
+ }
228
+
229
+ const trimmedLineComment = text.replace(/\/\/[^\n\r]*$/u, "");
230
+ if (trimmedLineComment !== text) {
231
+ text = trimmedLineComment;
232
+ changed = true;
233
+ continue;
234
+ }
235
+
236
+ const trimmedBlockComment = text.replace(/\/\*[\s\S]*?\*\/$/u, "");
237
+ if (trimmedBlockComment !== text) {
238
+ text = trimmedBlockComment;
239
+ changed = true;
240
+ }
241
+ }
242
+
243
+ return text;
244
+ }
245
+
246
+ function previousSignificantIndex(sourceText, start) {
247
+ let index = start - 1;
248
+ while (index >= 0 && isWhitespace(sourceText[index])) {
249
+ index -= 1;
250
+ }
251
+ return index;
252
+ }
253
+
254
+ function readPreviousWord(sourceText, endIndex) {
255
+ let index = endIndex;
256
+ while (index >= 0 && /[A-Za-z]/.test(sourceText[index])) {
257
+ index -= 1;
258
+ }
259
+ return sourceText.slice(index + 1, endIndex + 1);
260
+ }
261
+
262
+ function isLikelyJsxTagStart(sourceText, index) {
263
+ const next = sourceText[index + 1];
264
+ if (!TAG_NAME_START_CHAR.test(next || "")) {
265
+ return false;
266
+ }
267
+
268
+ const previousIndex = previousSignificantIndex(sourceText, index);
269
+ if (previousIndex < 0) {
270
+ return true;
271
+ }
272
+
273
+ const previousChar = sourceText[previousIndex];
274
+ if ("=({[,!?:;>&|".includes(previousChar)) {
275
+ return true;
276
+ }
277
+
278
+ const previousWord = readPreviousWord(sourceText, previousIndex);
279
+ return ["return", "case", "throw", "yield", "else"].includes(previousWord);
280
+ }
281
+
282
+ function readJsxTagName(sourceText, start) {
283
+ let index = start + 1;
284
+ const isClosing = sourceText[index] === "/";
285
+
286
+ if (isClosing) {
287
+ index += 1;
288
+ }
289
+
290
+ if (!TAG_NAME_START_CHAR.test(sourceText[index] || "")) {
291
+ return null;
292
+ }
293
+
294
+ const nameStart = index;
295
+
296
+ while (index < sourceText.length && TAG_NAME_CHAR.test(sourceText[index])) {
297
+ index += 1;
298
+ }
299
+
300
+ return {
301
+ name: sourceText.slice(nameStart, index),
302
+ isClosing,
303
+ end: index,
304
+ };
305
+ }
306
+
307
+ function scanJsxTag(sourceText, start, replacements, encodeAttributeName) {
308
+ const tag = readJsxTagName(sourceText, start);
309
+
310
+ if (!tag) {
311
+ return {
312
+ end: start + 1,
313
+ tagName: null,
314
+ isClosing: false,
315
+ selfClosing: false,
316
+ };
317
+ }
318
+
319
+ let index = tag.end;
320
+
321
+ if (tag.isClosing) {
322
+ while (index < sourceText.length) {
323
+ if (sourceText[index] === ">") {
324
+ return {
325
+ end: index + 1,
326
+ tagName: tag.name,
327
+ isClosing: true,
328
+ selfClosing: false,
329
+ };
330
+ }
331
+
332
+ index += 1;
333
+ }
334
+
335
+ return {
336
+ end: index,
337
+ tagName: tag.name,
338
+ isClosing: true,
339
+ selfClosing: false,
340
+ };
341
+ }
342
+
343
+ function scanAttributeValue(valueStart) {
344
+ let valueIndex = valueStart;
345
+
346
+ while (valueIndex < sourceText.length && isWhitespace(sourceText[valueIndex])) {
347
+ valueIndex += 1;
348
+ }
349
+
350
+ if (valueIndex >= sourceText.length) {
351
+ return valueIndex;
352
+ }
353
+
354
+ const valueChar = sourceText[valueIndex];
355
+ if (valueChar === "{") {
356
+ return scanBalancedBracesWithJsx(
357
+ sourceText,
358
+ valueIndex,
359
+ replacements,
360
+ encodeAttributeName
361
+ );
362
+ }
363
+
364
+ if (valueChar === "'" || valueChar === "\"") {
365
+ return scanQuotedString(sourceText, valueIndex, valueChar);
366
+ }
367
+
368
+ while (
369
+ valueIndex < sourceText.length &&
370
+ !isWhitespace(sourceText[valueIndex]) &&
371
+ sourceText[valueIndex] !== ">" &&
372
+ !(sourceText[valueIndex] === "/" && sourceText[valueIndex + 1] === ">")
373
+ ) {
374
+ valueIndex += 1;
375
+ }
376
+
377
+ return valueIndex;
378
+ }
379
+
380
+ while (index < sourceText.length) {
381
+ const char = sourceText[index];
382
+ const next = sourceText[index + 1];
383
+
384
+ if (char === ">") {
385
+ return {
386
+ end: index + 1,
387
+ tagName: tag.name,
388
+ isClosing: false,
389
+ selfClosing: false,
390
+ };
391
+ }
392
+
393
+ if (char === "/" && next === ">") {
394
+ return {
395
+ end: index + 2,
396
+ tagName: tag.name,
397
+ isClosing: false,
398
+ selfClosing: true,
399
+ };
400
+ }
401
+
402
+ if (isWhitespace(char)) {
403
+ index += 1;
404
+ continue;
405
+ }
406
+
407
+ if (char === "{") {
408
+ index = scanBalancedBracesWithJsx(
409
+ sourceText,
410
+ index,
411
+ replacements,
412
+ encodeAttributeName
413
+ );
414
+ continue;
415
+ }
416
+
417
+ if (char === "'" || char === "\"") {
418
+ index = scanQuotedString(sourceText, index, char);
419
+ continue;
420
+ }
421
+
422
+ if (Object.hasOwn(PREFIX_TO_KIND, char) && ATTR_NAME_CHAR.test(next || "")) {
423
+ const attrStart = index;
424
+ index += 1;
425
+
426
+ while (index < sourceText.length && ATTR_NAME_CHAR.test(sourceText[index])) {
427
+ index += 1;
428
+ }
429
+
430
+ const originalName = sourceText.slice(attrStart, index);
431
+ replacements.push({
432
+ start: attrStart,
433
+ end: index,
434
+ originalName,
435
+ replacement: encodeAttributeName(originalName),
436
+ });
437
+
438
+ while (index < sourceText.length && isWhitespace(sourceText[index])) {
439
+ index += 1;
440
+ }
441
+ if (sourceText[index] === "=") {
442
+ index = scanAttributeValue(index + 1);
443
+ }
444
+ continue;
445
+ }
446
+
447
+ const attrStart = index;
448
+ while (
449
+ index < sourceText.length &&
450
+ !isWhitespace(sourceText[index]) &&
451
+ sourceText[index] !== "=" &&
452
+ sourceText[index] !== ">" &&
453
+ !(sourceText[index] === "/" && sourceText[index + 1] === ">")
454
+ ) {
455
+ index += 1;
456
+ }
457
+
458
+ if (index === attrStart) {
459
+ index += 1;
460
+ continue;
461
+ }
462
+
463
+ while (index < sourceText.length && isWhitespace(sourceText[index])) {
464
+ index += 1;
465
+ }
466
+ if (sourceText[index] === "=") {
467
+ index = scanAttributeValue(index + 1);
468
+ }
469
+ }
470
+
471
+ return {
472
+ end: index,
473
+ tagName: tag.name,
474
+ isClosing: false,
475
+ selfClosing: false,
476
+ };
477
+ }
478
+
479
+ function scanJsxElement(sourceText, start, replacements, encodeAttributeName) {
480
+ const openingTag = scanJsxTag(sourceText, start, replacements, encodeAttributeName);
481
+
482
+ if (
483
+ openingTag.isClosing ||
484
+ openingTag.selfClosing ||
485
+ !openingTag.tagName
486
+ ) {
487
+ return openingTag.end;
488
+ }
489
+
490
+ let index = openingTag.end;
491
+
492
+ while (index < sourceText.length) {
493
+ const char = sourceText[index];
494
+ const next = sourceText[index + 1];
495
+
496
+ if (char === "'" || char === "\"") {
497
+ index = scanQuotedString(sourceText, index, char);
498
+ continue;
499
+ }
500
+
501
+ if (char === "`") {
502
+ index = scanTemplateLiteral(sourceText, index);
503
+ continue;
504
+ }
505
+
506
+ if (char === "/" && next === "/") {
507
+ index = scanLineComment(sourceText, index);
508
+ continue;
509
+ }
510
+
511
+ if (char === "/" && next === "*") {
512
+ index = scanBlockComment(sourceText, index);
513
+ continue;
514
+ }
515
+
516
+ if (char === "{") {
517
+ index = scanBalancedBracesWithJsx(
518
+ sourceText,
519
+ index,
520
+ replacements,
521
+ encodeAttributeName
522
+ );
523
+ continue;
524
+ }
525
+
526
+ if (char === "<") {
527
+ const nestedTag = readJsxTagName(sourceText, index);
528
+
529
+ if (!nestedTag) {
530
+ index += 1;
531
+ continue;
532
+ }
533
+
534
+ if (nestedTag.isClosing && nestedTag.name === openingTag.tagName) {
535
+ return scanJsxTag(sourceText, index, replacements, encodeAttributeName).end;
536
+ }
537
+
538
+ if (!nestedTag.isClosing) {
539
+ index = scanJsxElement(sourceText, index, replacements, encodeAttributeName);
540
+ continue;
541
+ }
542
+ }
543
+
544
+ index += 1;
545
+ }
546
+
547
+ return index;
548
+ }
549
+
550
+ function encodeVirtualAttributeName(name) {
551
+ const prefix = name[0];
552
+ const localName = name.slice(1);
553
+ const kind = PREFIX_TO_KIND[prefix];
554
+
555
+ if (!kind) {
556
+ return name;
557
+ }
558
+
559
+ return `__litsx_${kind}_${localName}`;
560
+ }
561
+
562
+ function decodeVirtualAttributeName(name) {
563
+ const match = /^__litsx_(event|prop|bool)_(.+)$/.exec(name);
564
+
565
+ if (!match) {
566
+ return null;
567
+ }
568
+
569
+ const [, kind, localName] = match;
570
+ return `${KIND_TO_PREFIX[kind]}${localName}`;
571
+ }
572
+
573
+ function decodeVirtualStaticHoistName(name) {
574
+ const match = /^__litsx_static_([A-Za-z$_][A-Za-z0-9$_]*)$/.exec(name);
575
+
576
+ if (!match) {
577
+ return null;
578
+ }
579
+
580
+ return `static ${match[1]}`;
581
+ }
582
+
583
+ function remapVirtualText(text) {
584
+ if (typeof text !== "string") {
585
+ return text;
586
+ }
587
+
588
+ return text
589
+ .replace(/__litsx_(event|prop|bool)_[\w:-]+/g, (name) => (
590
+ decodeVirtualAttributeName(name) ?? name
591
+ ))
592
+ .replace(/__litsx_static_[A-Za-z$_][A-Za-z0-9$_]*/g, (name) => (
593
+ decodeVirtualStaticHoistName(name) ?? name
594
+ ));
595
+ }
596
+
597
+ function looksLikeLitsxJsx(sourceText) {
598
+ return (
599
+ /<[\w.-]+[^>]*\s(?:[@.?][\w:-]+)/m.test(sourceText) ||
600
+ /(?:^|[;{}]\s*)static\s+[A-Za-z$_][A-Za-z0-9$_]*\s*=/m.test(sourceText) ||
601
+ /^\s*static\s+[A-Za-z$_][A-Za-z0-9$_]*\s*=/m.test(sourceText)
602
+ );
603
+ }
604
+
605
+ function isLikelyStaticHoistAssignmentStart(sourceText, index) {
606
+ if (sourceText.slice(index, index + 6) !== "static") {
607
+ return false;
608
+ }
609
+
610
+ const previousChar = sourceText[index - 1];
611
+ if (previousChar && /[A-Za-z0-9$_]/.test(previousChar)) {
612
+ return false;
613
+ }
614
+
615
+ const next = sourceText[index + 6];
616
+ if (!isWhitespace(next || "")) {
617
+ return false;
618
+ }
619
+
620
+ const prefix = trimTrailingWhitespaceAndComments(sourceText.slice(0, index));
621
+ if (!prefix) {
622
+ return true;
623
+ }
624
+
625
+ const previousSignificantChar = prefix[prefix.length - 1];
626
+ return (
627
+ previousSignificantChar === ";" ||
628
+ previousSignificantChar === "{" ||
629
+ previousSignificantChar === "}"
630
+ );
631
+ }
632
+
633
+ function readStaticHoistAssignment(sourceText, start) {
634
+ let index = start + 6;
635
+
636
+ while (index < sourceText.length && isWhitespace(sourceText[index])) {
637
+ index += 1;
638
+ }
639
+
640
+ const nameStart = index;
641
+ if (!MACRO_NAME_START_CHAR.test(sourceText[index] || "")) {
642
+ return null;
643
+ }
644
+
645
+ index += 1;
646
+ while (index < sourceText.length && MACRO_NAME_CHAR.test(sourceText[index])) {
647
+ index += 1;
648
+ }
649
+
650
+ const macroName = sourceText.slice(nameStart, index);
651
+
652
+ while (index < sourceText.length && isWhitespace(sourceText[index])) {
653
+ index += 1;
654
+ }
655
+
656
+ if (sourceText[index] !== "=") {
657
+ return null;
658
+ }
659
+
660
+ index += 1;
661
+ while (index < sourceText.length && isWhitespace(sourceText[index])) {
662
+ index += 1;
663
+ }
664
+
665
+ return {
666
+ macroName,
667
+ valueStart: index,
668
+ };
669
+ }
670
+
671
+ function scanStaticHoistAssignment(sourceText, start, replacements, strategy) {
672
+ const assignment = readStaticHoistAssignment(sourceText, start);
673
+ if (!assignment) {
674
+ return start + 1;
675
+ }
676
+
677
+ const { macroName, valueStart } = assignment;
678
+
679
+ let index = valueStart;
680
+ let parenDepth = 0;
681
+ let bracketDepth = 0;
682
+ let braceDepth = 0;
683
+ let statementEnd = sourceText.length;
684
+
685
+ while (index < sourceText.length) {
686
+ const char = sourceText[index];
687
+ const next = sourceText[index + 1];
688
+
689
+ if (char === "'" || char === "\"") {
690
+ index = scanQuotedString(sourceText, index, char);
691
+ continue;
692
+ }
693
+
694
+ if (char === "`") {
695
+ index = scanTemplateLiteral(sourceText, index);
696
+ continue;
697
+ }
698
+
699
+ if (char === "/" && next === "/") {
700
+ index = scanLineComment(sourceText, index);
701
+ continue;
702
+ }
703
+
704
+ if (char === "/" && next === "*") {
705
+ index = scanBlockComment(sourceText, index);
706
+ continue;
707
+ }
708
+
709
+ if (char === "(") {
710
+ parenDepth += 1;
711
+ index += 1;
712
+ continue;
713
+ }
714
+
715
+ if (char === ")") {
716
+ parenDepth = Math.max(0, parenDepth - 1);
717
+ index += 1;
718
+ continue;
719
+ }
720
+
721
+ if (char === "[") {
722
+ bracketDepth += 1;
723
+ index += 1;
724
+ continue;
725
+ }
726
+
727
+ if (char === "]") {
728
+ bracketDepth = Math.max(0, bracketDepth - 1);
729
+ index += 1;
730
+ continue;
731
+ }
732
+
733
+ if (char === "{") {
734
+ braceDepth += 1;
735
+ index += 1;
736
+ continue;
737
+ }
738
+
739
+ if (char === "}") {
740
+ if (parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) {
741
+ statementEnd = index;
742
+ break;
743
+ }
744
+
745
+ braceDepth = Math.max(0, braceDepth - 1);
746
+ index += 1;
747
+ continue;
748
+ }
749
+
750
+ if (
751
+ char === ";" &&
752
+ parenDepth === 0 &&
753
+ bracketDepth === 0 &&
754
+ braceDepth === 0
755
+ ) {
756
+ statementEnd = index + 1;
757
+ break;
758
+ }
759
+
760
+ index += 1;
761
+ }
762
+
763
+ const hasSemicolon = statementEnd > valueStart && sourceText[statementEnd - 1] === ";";
764
+ const expressionSegment = sourceText.slice(
765
+ valueStart,
766
+ hasSemicolon ? statementEnd - 1 : statementEnd,
767
+ );
768
+ const statementBody = sourceText.slice(valueStart, statementEnd);
769
+ const expressionText = trimTrailingWhitespaceAndComments(expressionSegment);
770
+ const trailingText = statementBody.slice(expressionSegment.length);
771
+
772
+ replacements.push({
773
+ start,
774
+ end: statementEnd,
775
+ originalName: `static ${macroName}`,
776
+ replacement:
777
+ strategy === "editor"
778
+ ? `${encodeEditorStaticHoistAssignment(macroName)}${statementBody}`
779
+ : `__litsx_static_${macroName}(${expressionText})${trailingText}`,
780
+ });
781
+
782
+ return statementEnd;
783
+ }
784
+
785
+ function createVirtualLitsxJsxSource(sourceText, options = {}) {
786
+ const strategy = options.strategy === "editor" ? "editor" : "compiler";
787
+ const includeSourceMap = options.sourceMap === true;
788
+ const encodeAttributeName =
789
+ strategy === "editor"
790
+ ? encodeEditorVirtualAttributeName
791
+ : encodeVirtualAttributeName;
792
+
793
+ if (!sourceText || typeof sourceText !== "string") {
794
+ return {
795
+ code: sourceText,
796
+ map: null,
797
+ replacements: [],
798
+ };
799
+ }
800
+
801
+ if (strategy === "compiler" && sourceText.includes("__litsx_")) {
802
+ return {
803
+ code: sourceText,
804
+ map: null,
805
+ replacements: [],
806
+ collision: true,
807
+ };
808
+ }
809
+
810
+ if (!looksLikeLitsxJsx(sourceText)) {
811
+ return {
812
+ code: sourceText,
813
+ map: null,
814
+ replacements: [],
815
+ };
816
+ }
817
+
818
+ const replacements = [];
819
+ let index = 0;
820
+ const blockStack = [];
821
+ let pendingClassBody = false;
822
+
823
+ while (index < sourceText.length) {
824
+ const char = sourceText[index];
825
+ const next = sourceText[index + 1];
826
+
827
+ if (char === "'" || char === "\"") {
828
+ index = scanQuotedString(sourceText, index, char);
829
+ continue;
830
+ }
831
+
832
+ if (char === "`") {
833
+ index = scanTemplateLiteral(sourceText, index);
834
+ continue;
835
+ }
836
+
837
+ if (char === "/" && next === "/") {
838
+ index = scanLineComment(sourceText, index);
839
+ continue;
840
+ }
841
+
842
+ if (char === "/" && next === "*") {
843
+ index = scanBlockComment(sourceText, index);
844
+ continue;
845
+ }
846
+
847
+ if (char === "<" && isLikelyJsxTagStart(sourceText, index)) {
848
+ index = scanJsxElement(sourceText, index, replacements, encodeAttributeName);
849
+ continue;
850
+ }
851
+
852
+ if (
853
+ char === "s" &&
854
+ blockStack[blockStack.length - 1] !== "class" &&
855
+ isLikelyStaticHoistAssignmentStart(sourceText, index)
856
+ ) {
857
+ index = scanStaticHoistAssignment(sourceText, index, replacements, strategy);
858
+ continue;
859
+ }
860
+
861
+ if (isIdentifierStartChar(char)) {
862
+ const wordStart = index;
863
+ index += 1;
864
+ while (index < sourceText.length && isIdentifierChar(sourceText[index])) {
865
+ index += 1;
866
+ }
867
+
868
+ const word = sourceText.slice(wordStart, index);
869
+ if (word === "class") {
870
+ let lookahead = index;
871
+ while (lookahead < sourceText.length && isWhitespace(sourceText[lookahead])) {
872
+ lookahead += 1;
873
+ }
874
+
875
+ pendingClassBody = sourceText[lookahead] !== ":";
876
+ }
877
+
878
+ continue;
879
+ }
880
+
881
+ if (char === "{") {
882
+ blockStack.push(pendingClassBody ? "class" : "block");
883
+ pendingClassBody = false;
884
+ index += 1;
885
+ continue;
886
+ }
887
+
888
+ if (char === "}") {
889
+ blockStack.pop();
890
+ pendingClassBody = false;
891
+ index += 1;
892
+ continue;
893
+ }
894
+
895
+ if (char === ";" || char === "=") {
896
+ pendingClassBody = false;
897
+ }
898
+
899
+ index += 1;
900
+ }
901
+
902
+ if (!replacements.length) {
903
+ return {
904
+ code: sourceText,
905
+ map: null,
906
+ replacements: [],
907
+ };
908
+ }
909
+
910
+ let lastIndex = 0;
911
+ let transformed = "";
912
+
913
+ for (const replacement of replacements) {
914
+ transformed += sourceText.slice(lastIndex, replacement.start);
915
+ transformed += replacement.replacement;
916
+ lastIndex = replacement.end;
917
+ }
918
+
919
+ transformed += sourceText.slice(lastIndex);
920
+
921
+ return {
922
+ code: transformed,
923
+ map: includeSourceMap
924
+ ? createVirtualLitsxJsxSourceMap(sourceText, replacements, {
925
+ sourceFileName: options.sourceFileName,
926
+ })
927
+ : null,
928
+ replacements,
929
+ };
930
+ }
931
+
932
+ function createVirtualLitsxJsxSourceMap(
933
+ sourceText,
934
+ replacements = [],
935
+ options = {}
936
+ ) {
937
+ const editable = new MagicString(sourceText);
938
+ applyVirtualAttributeReplacements(editable, replacements);
939
+
940
+ return editable.generateMap({
941
+ hires: true,
942
+ source: options.sourceFileName,
943
+ includeContent: true,
944
+ });
945
+ }
946
+
947
+ function findReplacementByVirtualPosition(position, replacements) {
948
+ let originalCursor = 0;
949
+ let virtualCursor = 0;
950
+
951
+ for (const replacement of replacements) {
952
+ const untouchedLength = replacement.start - originalCursor;
953
+ const replacementVirtualStart = virtualCursor + untouchedLength;
954
+ const replacementVirtualEnd =
955
+ replacementVirtualStart + replacement.replacement.length;
956
+
957
+ if (position >= replacementVirtualStart && position < replacementVirtualEnd) {
958
+ return {
959
+ replacement,
960
+ virtualStart: replacementVirtualStart,
961
+ virtualEnd: replacementVirtualEnd,
962
+ };
963
+ }
964
+
965
+ originalCursor = replacement.end;
966
+ virtualCursor = replacementVirtualEnd;
967
+ }
968
+
969
+ return null;
970
+ }
971
+
972
+ function mapOriginalPositionToVirtual(position, replacements = []) {
973
+ if (!replacements.length) {
974
+ return position;
975
+ }
976
+
977
+ let offset = 0;
978
+
979
+ for (const replacement of replacements) {
980
+ if (position < replacement.start) {
981
+ break;
982
+ }
983
+
984
+ const originalLength = replacement.end - replacement.start;
985
+ const replacementLength = replacement.replacement.length;
986
+
987
+ if (position < replacement.end) {
988
+ return replacement.start + offset;
989
+ }
990
+
991
+ offset += replacementLength - originalLength;
992
+ }
993
+
994
+ return position + offset;
995
+ }
996
+
997
+ function remapTextSpanToOriginal(span, replacements = []) {
998
+ if (!span || !replacements.length) {
999
+ return span;
1000
+ }
1001
+
1002
+ const startMapping = findReplacementByVirtualPosition(span.start, replacements);
1003
+ if (startMapping) {
1004
+ return {
1005
+ start: startMapping.replacement.start,
1006
+ length: startMapping.replacement.end - startMapping.replacement.start,
1007
+ };
1008
+ }
1009
+
1010
+ let originalStart = span.start;
1011
+ let originalEnd = span.start + span.length;
1012
+
1013
+ for (const replacement of replacements) {
1014
+ const originalLength = replacement.end - replacement.start;
1015
+ const replacementLength = replacement.replacement.length;
1016
+ const delta = originalLength - replacementLength;
1017
+ const virtualStart = mapOriginalPositionToVirtual(replacement.start, replacements);
1018
+ const virtualEnd = virtualStart + replacementLength;
1019
+
1020
+ if (virtualEnd <= span.start) {
1021
+ originalStart += delta;
1022
+ originalEnd += delta;
1023
+ continue;
1024
+ }
1025
+
1026
+ if (virtualStart < span.start) {
1027
+ originalStart = replacement.start;
1028
+ }
1029
+
1030
+ if (virtualStart < span.start + span.length) {
1031
+ originalEnd += delta;
1032
+ }
1033
+ }
1034
+
1035
+ return {
1036
+ start: originalStart,
1037
+ length: Math.max(0, originalEnd - originalStart),
1038
+ };
1039
+ }
1040
+
1041
+ function remapVirtualPositionToOriginal(position, replacements = []) {
1042
+ const span = remapTextSpanToOriginal({ start: position, length: 0 }, replacements);
1043
+ return span.start;
1044
+ }
1045
+
1046
+ const mapVirtualPositionToOriginal = remapVirtualPositionToOriginal;
1047
+
1048
+ function applyVirtualAttributeReplacements(editable, replacements = []) {
1049
+ for (const replacement of replacements) {
1050
+ editable.overwrite(replacement.start, replacement.end, replacement.replacement);
1051
+ }
1052
+ }
1053
+
1054
+ exports.applyVirtualAttributeReplacements = applyVirtualAttributeReplacements;
1055
+ exports.createVirtualLitsxJsxSource = createVirtualLitsxJsxSource;
1056
+ exports.createVirtualLitsxJsxSourceMap = createVirtualLitsxJsxSourceMap;
1057
+ exports.decodeVirtualAttributeName = decodeVirtualAttributeName;
1058
+ exports.decodeVirtualStaticHoistName = decodeVirtualStaticHoistName;
1059
+ exports.encodeVirtualAttributeName = encodeVirtualAttributeName;
1060
+ exports.isReservedVirtualAttributeName = isReservedVirtualAttributeName;
1061
+ exports.looksLikeLitsxJsx = looksLikeLitsxJsx;
1062
+ exports.mapOriginalPositionToVirtual = mapOriginalPositionToVirtual;
1063
+ exports.mapVirtualPositionToOriginal = mapVirtualPositionToOriginal;
1064
+ exports.remapTextSpanToOriginal = remapTextSpanToOriginal;
1065
+ exports.remapVirtualPositionToOriginal = remapVirtualPositionToOriginal;
1066
+ exports.remapVirtualText = remapVirtualText;
1067
+ //# sourceMappingURL=index.cjs.map