@hyperfixi/vite-plugin 2.0.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,3550 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ REGIONS: () => REGIONS,
34
+ SUPPORTED_LANGUAGES: () => SUPPORTED_LANGUAGES,
35
+ clearCustomKeywords: () => clearCustomKeywords,
36
+ clearSemanticParser: () => clearSemanticParser,
37
+ default: () => index_default,
38
+ detectLanguages: () => detectLanguages,
39
+ getAllLanguageCodes: () => getAllLanguageCodes,
40
+ getKeywordsForLanguage: () => getKeywordsForLanguage,
41
+ getOptimalRegion: () => getOptimalRegion,
42
+ hasSemanticParser: () => hasSemanticParser,
43
+ hyperfixi: () => hyperfixi,
44
+ isNonLatinLanguage: () => isNonLatinLanguage,
45
+ registerCustomKeywords: () => registerCustomKeywords,
46
+ setSemanticParser: () => setSemanticParser
47
+ });
48
+ module.exports = __toCommonJS(index_exports);
49
+
50
+ // src/language-keywords.ts
51
+ var SUPPORTED_LANGUAGES = [
52
+ "en",
53
+ "es",
54
+ "pt",
55
+ "fr",
56
+ "de",
57
+ "it",
58
+ "vi",
59
+ // Western (Latin script)
60
+ "pl",
61
+ "ru",
62
+ "uk",
63
+ // Slavic (Latin/Cyrillic)
64
+ "ja",
65
+ "zh",
66
+ "ko",
67
+ // East Asian
68
+ "ar",
69
+ // RTL (Arabic script)
70
+ "hi",
71
+ "bn",
72
+ // South Asian (Indic scripts)
73
+ "th",
74
+ // Southeast Asian (Thai script)
75
+ "tr",
76
+ // Agglutinative Latin
77
+ "id",
78
+ "sw",
79
+ "qu",
80
+ // Other
81
+ "tl"
82
+ // Tagalog (auto-added)
83
+ ];
84
+ var REGIONS = {
85
+ western: ["en", "es", "pt", "fr", "de", "it"],
86
+ "east-asian": ["ja", "zh", "ko"],
87
+ slavic: ["pl", "ru", "uk"],
88
+ "south-asian": ["hi", "bn"],
89
+ priority: [
90
+ "en",
91
+ "es",
92
+ "pt",
93
+ "fr",
94
+ "de",
95
+ "it",
96
+ "ja",
97
+ "zh",
98
+ "ko",
99
+ "ar",
100
+ "tr",
101
+ "ru",
102
+ "hi"
103
+ ],
104
+ all: SUPPORTED_LANGUAGES
105
+ };
106
+ var JAPANESE_KEYWORDS = /* @__PURE__ */ new Set([
107
+ "\u5207\u308A\u66FF\u3048",
108
+ "\u5207\u308A\u66FF\u3048\u308B",
109
+ "\u30C8\u30B0\u30EB",
110
+ "\u30C8\u30B0\u30EB\u3059\u308B",
111
+ "\u8FFD\u52A0",
112
+ "\u8FFD\u52A0\u3059\u308B",
113
+ "\u52A0\u3048\u308B",
114
+ "\u524A\u9664",
115
+ "\u524A\u9664\u3059\u308B",
116
+ "\u53D6\u308A\u9664\u304F",
117
+ "\u8868\u793A",
118
+ "\u8868\u793A\u3059\u308B",
119
+ "\u898B\u305B\u308B",
120
+ "\u96A0\u3059",
121
+ "\u975E\u8868\u793A",
122
+ "\u975E\u8868\u793A\u306B\u3059\u308B",
123
+ "\u8A2D\u5B9A",
124
+ "\u8A2D\u5B9A\u3059\u308B",
125
+ "\u30BB\u30C3\u30C8",
126
+ "\u5897\u52A0",
127
+ "\u5897\u3084\u3059",
128
+ "\u30A4\u30F3\u30AF\u30EA\u30E1\u30F3\u30C8",
129
+ "\u6E1B\u5C11",
130
+ "\u6E1B\u3089\u3059",
131
+ "\u30C7\u30AF\u30EA\u30E1\u30F3\u30C8",
132
+ "\u5F15\u304D\u91D1",
133
+ "\u767A\u706B",
134
+ "\u30C8\u30EA\u30AC\u30FC",
135
+ "\u9001\u308B",
136
+ "\u9001\u4FE1",
137
+ "\u3082\u3057",
138
+ "\u6761\u4EF6",
139
+ "\u305D\u3046\u3067\u306A\u3051\u308C\u3070",
140
+ "\u305D\u308C\u4EE5\u5916",
141
+ "\u7E70\u308A\u8FD4\u3057",
142
+ "\u7E70\u308A\u8FD4\u3059",
143
+ "\u30EA\u30D4\u30FC\u30C8",
144
+ "\u5F85\u3064",
145
+ "\u5F85\u6A5F",
146
+ "\u306E\u9593",
147
+ "\u9593"
148
+ ]);
149
+ var KOREAN_KEYWORDS = /* @__PURE__ */ new Set([
150
+ "\uD1A0\uAE00",
151
+ "\uC804\uD658",
152
+ "\uCD94\uAC00",
153
+ "\uC81C\uAC70",
154
+ "\uC0AD\uC81C",
155
+ "\uBCF4\uC774\uB2E4",
156
+ "\uD45C\uC2DC",
157
+ "\uBCF4\uC774\uAE30",
158
+ "\uC228\uAE30\uB2E4",
159
+ "\uC228\uAE30\uAE30",
160
+ "\uC124\uC815",
161
+ "\uC99D\uAC00",
162
+ "\uAC10\uC18C",
163
+ "\uD2B8\uB9AC\uAC70",
164
+ "\uBCF4\uB0B4\uB2E4",
165
+ "\uB9CC\uC57D",
166
+ "\uC544\uB2C8\uBA74",
167
+ "\uBC18\uBCF5",
168
+ "\uB300\uAE30",
169
+ "\uB3D9\uC548"
170
+ ]);
171
+ var CHINESE_KEYWORDS = /* @__PURE__ */ new Set([
172
+ "\u5207\u6362",
173
+ "\u6DFB\u52A0",
174
+ "\u52A0",
175
+ "\u79FB\u9664",
176
+ "\u5220\u9664",
177
+ "\u53BB\u6389",
178
+ "\u663E\u793A",
179
+ "\u5C55\u793A",
180
+ "\u9690\u85CF",
181
+ "\u8BBE\u7F6E",
182
+ "\u8BBE\u5B9A",
183
+ "\u589E\u52A0",
184
+ "\u51CF\u5C11",
185
+ "\u89E6\u53D1",
186
+ "\u53D1\u9001",
187
+ "\u5982\u679C",
188
+ "\u5426\u5219",
189
+ "\u91CD\u590D",
190
+ "\u7B49\u5F85",
191
+ "\u5F53"
192
+ ]);
193
+ var ARABIC_KEYWORDS = /* @__PURE__ */ new Set([
194
+ "\u0628\u062F\u0644",
195
+ "\u0628\u062F\u0651\u0644",
196
+ "\u063A\u064A\u0651\u0631",
197
+ "\u063A\u064A\u0631",
198
+ "\u0623\u0636\u0641",
199
+ "\u0627\u0636\u0641",
200
+ "\u0632\u0650\u062F",
201
+ "\u0627\u062D\u0630\u0641",
202
+ "\u0623\u0632\u0644",
203
+ "\u0627\u0645\u0633\u062D",
204
+ "\u0627\u0638\u0647\u0631",
205
+ "\u0623\u0638\u0647\u0631",
206
+ "\u0627\u0639\u0631\u0636",
207
+ "\u0627\u062E\u0641",
208
+ "\u0623\u062E\u0641\u0650",
209
+ "\u0627\u062E\u0641\u064A",
210
+ "\u0627\u0636\u0628\u0637",
211
+ "\u0639\u064A\u0651\u0646",
212
+ "\u062D\u062F\u062F",
213
+ "\u0627\u0631\u0641\u0639",
214
+ "\u0623\u0646\u0642\u0635",
215
+ "\u0642\u0644\u0644",
216
+ "\u062A\u0634\u063A\u064A\u0644",
217
+ "\u0623\u0637\u0644\u0642",
218
+ "\u0641\u0639\u0651\u0644",
219
+ "\u0623\u0631\u0633\u0644",
220
+ "\u0625\u0630\u0627",
221
+ "\u0648\u0625\u0644\u0627",
222
+ "\u062E\u0644\u0627\u0641 \u0630\u0644\u0643",
223
+ "\u0643\u0631\u0631",
224
+ "\u0627\u0646\u062A\u0638\u0631",
225
+ "\u0628\u064A\u0646\u0645\u0627"
226
+ ]);
227
+ var SPANISH_KEYWORDS = /* @__PURE__ */ new Set([
228
+ "alternar",
229
+ "cambiar",
230
+ "conmutar",
231
+ "agregar",
232
+ "a\xF1adir",
233
+ "quitar",
234
+ "eliminar",
235
+ "remover",
236
+ "sacar",
237
+ "mostrar",
238
+ "ense\xF1ar",
239
+ "ocultar",
240
+ "esconder",
241
+ "establecer",
242
+ "fijar",
243
+ "definir",
244
+ "incrementar",
245
+ "aumentar",
246
+ "decrementar",
247
+ "disminuir",
248
+ "disparar",
249
+ "activar",
250
+ "enviar",
251
+ "si",
252
+ "sino",
253
+ "de lo contrario",
254
+ "repetir",
255
+ "esperar",
256
+ "mientras"
257
+ ]);
258
+ var PORTUGUESE_KEYWORDS = /* @__PURE__ */ new Set([
259
+ "alternar",
260
+ "trocar",
261
+ "adicionar",
262
+ "acrescentar",
263
+ "remover",
264
+ "eliminar",
265
+ "apagar",
266
+ "mostrar",
267
+ "exibir",
268
+ "ocultar",
269
+ "esconder",
270
+ "definir",
271
+ "configurar",
272
+ "incrementar",
273
+ "aumentar",
274
+ "decrementar",
275
+ "diminuir",
276
+ "disparar",
277
+ "ativar",
278
+ "enviar",
279
+ "se",
280
+ "sen\xE3o",
281
+ "repetir",
282
+ "esperar",
283
+ "aguardar",
284
+ "enquanto"
285
+ ]);
286
+ var FRENCH_KEYWORDS = /* @__PURE__ */ new Set([
287
+ "basculer",
288
+ "permuter",
289
+ "alterner",
290
+ "ajouter",
291
+ "supprimer",
292
+ "enlever",
293
+ "retirer",
294
+ "montrer",
295
+ "afficher",
296
+ "cacher",
297
+ "masquer",
298
+ "d\xE9finir",
299
+ "\xE9tablir",
300
+ "incr\xE9menter",
301
+ "augmenter",
302
+ "d\xE9cr\xE9menter",
303
+ "diminuer",
304
+ "d\xE9clencher",
305
+ "envoyer",
306
+ "si",
307
+ "sinon",
308
+ "r\xE9p\xE9ter",
309
+ "attendre",
310
+ "pendant"
311
+ ]);
312
+ var GERMAN_KEYWORDS = /* @__PURE__ */ new Set([
313
+ "umschalten",
314
+ "wechseln",
315
+ "hinzuf\xFCgen",
316
+ "entfernen",
317
+ "l\xF6schen",
318
+ "zeigen",
319
+ "anzeigen",
320
+ "verbergen",
321
+ "verstecken",
322
+ "festlegen",
323
+ "definieren",
324
+ "erh\xF6hen",
325
+ "verringern",
326
+ "vermindern",
327
+ "ausl\xF6sen",
328
+ "senden",
329
+ "schicken",
330
+ "wenn",
331
+ "falls",
332
+ "sonst",
333
+ "ansonsten",
334
+ "wiederholen",
335
+ "warten",
336
+ "solange",
337
+ "w\xE4hrend"
338
+ ]);
339
+ var TURKISH_KEYWORDS = /* @__PURE__ */ new Set([
340
+ "de\u011Fi\u015Ftir",
341
+ "a\xE7/kapat",
342
+ "ekle",
343
+ "kald\u0131r",
344
+ "sil",
345
+ "g\xF6ster",
346
+ "gizle",
347
+ "ayarla",
348
+ "yap",
349
+ "belirle",
350
+ "art\u0131r",
351
+ "azalt",
352
+ "tetikle",
353
+ "g\xF6nder",
354
+ "e\u011Fer",
355
+ "yoksa",
356
+ "tekrarla",
357
+ "bekle",
358
+ "iken"
359
+ ]);
360
+ var INDONESIAN_KEYWORDS = /* @__PURE__ */ new Set([
361
+ "alihkan",
362
+ "ganti",
363
+ "tukar",
364
+ "tambah",
365
+ "tambahkan",
366
+ "hapus",
367
+ "buang",
368
+ "hilangkan",
369
+ "tampilkan",
370
+ "perlihatkan",
371
+ "sembunyikan",
372
+ "tutup",
373
+ "atur",
374
+ "tetapkan",
375
+ "tingkatkan",
376
+ "naikkan",
377
+ "turunkan",
378
+ "kurangi",
379
+ "picu",
380
+ "jalankan",
381
+ "kirim",
382
+ "kirimkan",
383
+ "jika",
384
+ "kalau",
385
+ "bila",
386
+ "selainnya",
387
+ "ulangi",
388
+ "tunggu",
389
+ "selama"
390
+ ]);
391
+ var SWAHILI_KEYWORDS = /* @__PURE__ */ new Set([
392
+ "badilisha",
393
+ "geuza",
394
+ "ongeza",
395
+ "weka",
396
+ "ondoa",
397
+ "futa",
398
+ "toa",
399
+ "onyesha",
400
+ "ficha",
401
+ "mficho",
402
+ "seti",
403
+ "punguza",
404
+ "chochea",
405
+ "anzisha",
406
+ "tuma",
407
+ "peleka",
408
+ "kama",
409
+ "ikiwa",
410
+ "vinginevyo",
411
+ "sivyo",
412
+ "rudia",
413
+ "subiri",
414
+ "ngoja",
415
+ "wakati"
416
+ ]);
417
+ var QUECHUA_KEYWORDS = /* @__PURE__ */ new Set([
418
+ "t",
419
+ "tikray",
420
+ "kutichiy",
421
+ "yapay",
422
+ "yapaykuy",
423
+ "qichuy",
424
+ "hurquy",
425
+ "anchuchiy",
426
+ "rikuchiy",
427
+ "qawachiy",
428
+ "pakay",
429
+ "pakakuy",
430
+ "churay",
431
+ "kamaykuy",
432
+ "yapachiy",
433
+ "pisiyachiy",
434
+ "qallarichiy",
435
+ "kachay",
436
+ "apachiy",
437
+ "sichus",
438
+ "manachus",
439
+ "hukniraq",
440
+ "kutipay",
441
+ "muyu",
442
+ "suyay",
443
+ "kaykamaqa"
444
+ ]);
445
+ var ITALIAN_KEYWORDS = /* @__PURE__ */ new Set([
446
+ "commutare",
447
+ "alternare",
448
+ "cambiare",
449
+ "aggiungere",
450
+ "aggiungi",
451
+ "rimuovere",
452
+ "eliminare",
453
+ "togliere",
454
+ "mostrare",
455
+ "visualizzare",
456
+ "nascondere",
457
+ "impostare",
458
+ "definire",
459
+ "incrementare",
460
+ "aumentare",
461
+ "decrementare",
462
+ "diminuire",
463
+ "scatenare",
464
+ "attivare",
465
+ "inviare",
466
+ "se",
467
+ "altrimenti",
468
+ "ripetere",
469
+ "aspettare",
470
+ "attendere",
471
+ "mentre"
472
+ ]);
473
+ var VIETNAMESE_KEYWORDS = /* @__PURE__ */ new Set([
474
+ "chuy\u1EC3n \u0111\u1ED5i",
475
+ "b\u1EADt t\u1EAFt",
476
+ "chuy\u1EC3n",
477
+ "th\xEAm",
478
+ "b\u1ED5 sung",
479
+ "x\xF3a",
480
+ "g\u1EE1 b\u1ECF",
481
+ "lo\u1EA1i b\u1ECF",
482
+ "b\u1ECF",
483
+ "hi\u1EC3n th\u1ECB",
484
+ "hi\u1EC7n",
485
+ "\u1EA9n",
486
+ "che",
487
+ "gi\u1EA5u",
488
+ "g\xE1n",
489
+ "thi\u1EBFt l\u1EADp",
490
+ "\u0111\u1EB7t",
491
+ "t\u0103ng",
492
+ "t\u0103ng l\xEAn",
493
+ "gi\u1EA3m",
494
+ "gi\u1EA3m \u0111i",
495
+ "k\xEDch ho\u1EA1t",
496
+ "g\u1EEDi",
497
+ "n\u1EBFu",
498
+ "kh\xF4ng th\xEC",
499
+ "n\u1EBFu kh\xF4ng",
500
+ "l\u1EB7p l\u1EA1i",
501
+ "ch\u1EDD",
502
+ "\u0111\u1EE3i",
503
+ "trong khi"
504
+ ]);
505
+ var POLISH_KEYWORDS = /* @__PURE__ */ new Set([
506
+ "prze\u0142\u0105cz",
507
+ "przelacz",
508
+ "dodaj",
509
+ "usu\u0144",
510
+ "usun",
511
+ "wyczy\u015B\u0107",
512
+ "wyczysc",
513
+ "poka\u017C",
514
+ "pokaz",
515
+ "wy\u015Bwietl",
516
+ "wyswietl",
517
+ "ukryj",
518
+ "schowaj",
519
+ "ustaw",
520
+ "okre\u015Bl",
521
+ "okresl",
522
+ "zwi\u0119ksz",
523
+ "zwieksz",
524
+ "zmniejsz",
525
+ "wywo\u0142aj",
526
+ "wywolaj",
527
+ "wyzw\xF3l",
528
+ "wyzwol",
529
+ "wy\u015Blij",
530
+ "wyslij",
531
+ "je\u015Bli",
532
+ "jesli",
533
+ "je\u017Celi",
534
+ "jezeli",
535
+ "inaczej",
536
+ "wpp",
537
+ "powt\xF3rz",
538
+ "powtorz",
539
+ "czekaj",
540
+ "poczekaj",
541
+ "dop\xF3ki",
542
+ "dopoki",
543
+ "podczas"
544
+ ]);
545
+ var RUSSIAN_KEYWORDS = /* @__PURE__ */ new Set([
546
+ "\u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C",
547
+ "\u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438",
548
+ "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C",
549
+ "\u0434\u043E\u0431\u0430\u0432\u044C",
550
+ "\u0443\u0434\u0430\u043B\u0438\u0442\u044C",
551
+ "\u0443\u0434\u0430\u043B\u0438",
552
+ "\u0443\u0431\u0440\u0430\u0442\u044C",
553
+ "\u0443\u0431\u0435\u0440\u0438",
554
+ "\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C",
555
+ "\u043F\u043E\u043A\u0430\u0436\u0438",
556
+ "\u0441\u043A\u0440\u044B\u0442\u044C",
557
+ "\u0441\u043A\u0440\u043E\u0439",
558
+ "\u0441\u043F\u0440\u044F\u0442\u0430\u0442\u044C",
559
+ "\u0441\u043F\u0440\u044F\u0447\u044C",
560
+ "\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C",
561
+ "\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438",
562
+ "\u0437\u0430\u0434\u0430\u0442\u044C",
563
+ "\u0437\u0430\u0434\u0430\u0439",
564
+ "\u0443\u0432\u0435\u043B\u0438\u0447\u0438\u0442\u044C",
565
+ "\u0443\u0432\u0435\u043B\u0438\u0447\u044C",
566
+ "\u0443\u043C\u0435\u043D\u044C\u0448\u0438\u0442\u044C",
567
+ "\u0443\u043C\u0435\u043D\u044C\u0448\u0438",
568
+ "\u0432\u044B\u0437\u0432\u0430\u0442\u044C",
569
+ "\u0432\u044B\u0437\u043E\u0432\u0438",
570
+ "\u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C",
571
+ "\u043E\u0442\u043F\u0440\u0430\u0432\u044C",
572
+ "\u0435\u0441\u043B\u0438",
573
+ "\u0438\u043D\u0430\u0447\u0435",
574
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C",
575
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438",
576
+ "\u0436\u0434\u0430\u0442\u044C",
577
+ "\u0436\u0434\u0438",
578
+ "\u043F\u043E\u0434\u043E\u0436\u0434\u0438",
579
+ "\u043F\u043E\u043A\u0430"
580
+ ]);
581
+ var UKRAINIAN_KEYWORDS = /* @__PURE__ */ new Set([
582
+ "\u043F\u0435\u0440\u0435\u043C\u043A\u043D\u0443\u0442\u0438",
583
+ "\u043F\u0435\u0440\u0435\u043C\u043A\u043D\u0438",
584
+ "\u0434\u043E\u0434\u0430\u0442\u0438",
585
+ "\u0434\u043E\u0434\u0430\u0439",
586
+ "\u0432\u0438\u0434\u0430\u043B\u0438\u0442\u0438",
587
+ "\u0432\u0438\u0434\u0430\u043B\u0438",
588
+ "\u043F\u0440\u0438\u0431\u0440\u0430\u0442\u0438",
589
+ "\u043F\u0440\u0438\u0431\u0435\u0440\u0438",
590
+ "\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u0438",
591
+ "\u043F\u043E\u043A\u0430\u0436\u0438",
592
+ "\u0441\u0445\u043E\u0432\u0430\u0442\u0438",
593
+ "\u0441\u0445\u043E\u0432\u0430\u0439",
594
+ "\u043F\u0440\u0438\u0445\u043E\u0432\u0430\u0442\u0438",
595
+ "\u043F\u0440\u0438\u0445\u043E\u0432\u0430\u0439",
596
+ "\u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0438",
597
+ "\u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438",
598
+ "\u0437\u0430\u0434\u0430\u0442\u0438",
599
+ "\u0437\u0430\u0434\u0430\u0439",
600
+ "\u0437\u0431\u0456\u043B\u044C\u0448\u0438\u0442\u0438",
601
+ "\u0437\u0431\u0456\u043B\u044C\u0448",
602
+ "\u0437\u043C\u0435\u043D\u0448\u0438\u0442\u0438",
603
+ "\u0437\u043C\u0435\u043D\u0448",
604
+ "\u0432\u0438\u043A\u043B\u0438\u043A\u0430\u0442\u0438",
605
+ "\u0432\u0438\u043A\u043B\u0438\u0447",
606
+ "\u043D\u0430\u0434\u0456\u0441\u043B\u0430\u0442\u0438",
607
+ "\u043D\u0430\u0434\u0456\u0448\u043B\u0438",
608
+ "\u044F\u043A\u0449\u043E",
609
+ "\u0456\u043D\u0430\u043A\u0448\u0435",
610
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0438",
611
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438",
612
+ "\u0447\u0435\u043A\u0430\u0442\u0438",
613
+ "\u0447\u0435\u043A\u0430\u0439",
614
+ "\u0437\u0430\u0447\u0435\u043A\u0430\u0439",
615
+ "\u043F\u043E\u043A\u0438"
616
+ ]);
617
+ var HINDI_KEYWORDS = /* @__PURE__ */ new Set([
618
+ "\u091F\u0949\u0917\u0932",
619
+ "\u092C\u0926\u0932\u0947\u0902",
620
+ "\u092C\u0926\u0932",
621
+ "\u091C\u094B\u0921\u093C\u0947\u0902",
622
+ "\u091C\u094B\u0921\u093C",
623
+ "\u0939\u091F\u093E\u090F\u0902",
624
+ "\u0939\u091F\u093E",
625
+ "\u092E\u093F\u091F\u093E\u090F\u0902",
626
+ "\u0926\u093F\u0916\u093E\u090F\u0902",
627
+ "\u0926\u093F\u0916\u093E",
628
+ "\u091B\u093F\u092A\u093E\u090F\u0902",
629
+ "\u091B\u093F\u092A\u093E",
630
+ "\u0938\u0947\u091F",
631
+ "\u0928\u093F\u0930\u094D\u0927\u093E\u0930\u093F\u0924",
632
+ "\u092C\u0922\u093C\u093E\u090F\u0902",
633
+ "\u092C\u0922\u093C\u093E",
634
+ "\u0918\u091F\u093E\u090F\u0902",
635
+ "\u0918\u091F\u093E",
636
+ "\u091F\u094D\u0930\u093F\u0917\u0930",
637
+ "\u092D\u0947\u091C\u0947\u0902",
638
+ "\u092D\u0947\u091C",
639
+ "\u0905\u0917\u0930",
640
+ "\u092F\u0926\u093F",
641
+ "\u0935\u0930\u0928\u093E",
642
+ "\u0928\u0939\u0940\u0902 \u0924\u094B",
643
+ "\u0926\u094B\u0939\u0930\u093E\u090F\u0902",
644
+ "\u0926\u094B\u0939\u0930\u093E",
645
+ "\u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E",
646
+ "\u0930\u0941\u0915\u0947\u0902",
647
+ "\u091C\u092C \u0924\u0915"
648
+ ]);
649
+ var BENGALI_KEYWORDS = /* @__PURE__ */ new Set([
650
+ "\u099F\u0997\u09B2",
651
+ "\u09AA\u09B0\u09BF\u09AC\u09B0\u09CD\u09A4\u09A8",
652
+ "\u09AF\u09CB\u0997",
653
+ "\u09AF\u09CB\u0997 \u0995\u09B0\u09C1\u09A8",
654
+ "\u09B8\u09B0\u09BE\u09A8",
655
+ "\u09B8\u09B0\u09BF\u09AF\u09BC\u09C7 \u09AB\u09C7\u09B2\u09C1\u09A8",
656
+ "\u09AE\u09C1\u099B\u09C1\u09A8",
657
+ "\u09A6\u09C7\u0996\u09BE\u09A8",
658
+ "\u09A6\u09C7\u0996\u09BE\u0993",
659
+ "\u09B2\u09C1\u0995\u09BE\u09A8",
660
+ "\u09B2\u09C1\u0995\u09BE\u0993",
661
+ "\u09B8\u09C7\u099F",
662
+ "\u09A8\u09BF\u09B0\u09CD\u09A7\u09BE\u09B0\u09A3",
663
+ "\u09AC\u09C3\u09A6\u09CD\u09A7\u09BF",
664
+ "\u09AC\u09BE\u09A1\u09BC\u09BE\u09A8",
665
+ "\u09B9\u09CD\u09B0\u09BE\u09B8",
666
+ "\u0995\u09AE\u09BE\u09A8",
667
+ "\u099F\u09CD\u09B0\u09BF\u0997\u09BE\u09B0",
668
+ "\u09AA\u09BE\u09A0\u09BE\u09A8",
669
+ "\u09AA\u09BE\u09A0\u09BE\u0993",
670
+ "\u09AF\u09A6\u09BF",
671
+ "\u09A8\u09A4\u09C1\u09AC\u09BE",
672
+ "\u09A8\u09BE \u09B9\u09B2\u09C7",
673
+ "\u09AA\u09C1\u09A8\u09B0\u09BE\u09AC\u09C3\u09A4\u09CD\u09A4\u09BF",
674
+ "\u09AC\u09BE\u09B0 \u09AC\u09BE\u09B0",
675
+ "\u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE",
676
+ "\u09A5\u09BE\u09AE\u09C1\u09A8",
677
+ "\u09AF\u09A4\u0995\u09CD\u09B7\u09A3"
678
+ ]);
679
+ var THAI_KEYWORDS = /* @__PURE__ */ new Set([
680
+ "\u0E2A\u0E25\u0E31\u0E1A",
681
+ "\u0E40\u0E1E\u0E34\u0E48\u0E21",
682
+ "\u0E25\u0E1A",
683
+ "\u0E25\u0E1A\u0E2D\u0E2D\u0E01",
684
+ "\u0E41\u0E2A\u0E14\u0E07",
685
+ "\u0E0B\u0E48\u0E2D\u0E19",
686
+ "\u0E15\u0E31\u0E49\u0E07",
687
+ "\u0E01\u0E33\u0E2B\u0E19\u0E14",
688
+ "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E04\u0E48\u0E32",
689
+ "\u0E25\u0E14\u0E04\u0E48\u0E32",
690
+ "\u0E17\u0E23\u0E34\u0E01\u0E40\u0E01\u0E2D\u0E23\u0E4C",
691
+ "\u0E2A\u0E48\u0E07",
692
+ "\u0E16\u0E49\u0E32",
693
+ "\u0E2B\u0E32\u0E01",
694
+ "\u0E44\u0E21\u0E48\u0E07\u0E31\u0E49\u0E19",
695
+ "\u0E44\u0E21\u0E48\u0E40\u0E0A\u0E48\u0E19\u0E19\u0E31\u0E49\u0E19",
696
+ "\u0E17\u0E33\u0E0B\u0E49\u0E33",
697
+ "\u0E23\u0E2D",
698
+ "\u0E43\u0E19\u0E02\u0E13\u0E30\u0E17\u0E35\u0E48"
699
+ ]);
700
+ var TL_KEYWORDS = /* @__PURE__ */ new Set([
701
+ "palitan",
702
+ "itoggle",
703
+ "idagdag",
704
+ "magdagdag",
705
+ "alisin",
706
+ "tanggalin",
707
+ "ipakita",
708
+ "magpakita",
709
+ "itago",
710
+ "magtago",
711
+ "itakda",
712
+ "magtakda",
713
+ "dagdagan",
714
+ "taasan",
715
+ "bawasan",
716
+ "ibaba",
717
+ "magpatugtog",
718
+ "ipadala",
719
+ "magpadala",
720
+ "kung",
721
+ "kapag",
722
+ "kung_hindi",
723
+ "kundi",
724
+ "ulitin",
725
+ "paulit-ulit",
726
+ "maghintay",
727
+ "hintay",
728
+ "habang"
729
+ ]);
730
+ var LANGUAGE_KEYWORDS = {
731
+ en: /* @__PURE__ */ new Set(),
732
+ // English is the default, no detection needed
733
+ ja: JAPANESE_KEYWORDS,
734
+ ko: KOREAN_KEYWORDS,
735
+ zh: CHINESE_KEYWORDS,
736
+ ar: ARABIC_KEYWORDS,
737
+ es: SPANISH_KEYWORDS,
738
+ pt: PORTUGUESE_KEYWORDS,
739
+ fr: FRENCH_KEYWORDS,
740
+ de: GERMAN_KEYWORDS,
741
+ it: ITALIAN_KEYWORDS,
742
+ vi: VIETNAMESE_KEYWORDS,
743
+ pl: POLISH_KEYWORDS,
744
+ ru: RUSSIAN_KEYWORDS,
745
+ uk: UKRAINIAN_KEYWORDS,
746
+ hi: HINDI_KEYWORDS,
747
+ bn: BENGALI_KEYWORDS,
748
+ th: THAI_KEYWORDS,
749
+ tr: TURKISH_KEYWORDS,
750
+ id: INDONESIAN_KEYWORDS,
751
+ sw: SWAHILI_KEYWORDS,
752
+ qu: QUECHUA_KEYWORDS,
753
+ tl: TL_KEYWORDS
754
+ };
755
+ function containsLanguageKeywords(script, language) {
756
+ const keywords = LANGUAGE_KEYWORDS[language];
757
+ if (!keywords || keywords.size === 0) return false;
758
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
759
+ if (nonLatinLangs.includes(language)) {
760
+ for (const keyword of keywords) {
761
+ if (script.includes(keyword)) {
762
+ return true;
763
+ }
764
+ }
765
+ return false;
766
+ }
767
+ const lowerScript = script.toLowerCase();
768
+ for (const keyword of keywords) {
769
+ if (keyword.length <= 2) continue;
770
+ const pattern = new RegExp(`\\b${escapeRegExp(keyword.toLowerCase())}\\b`);
771
+ if (pattern.test(lowerScript)) {
772
+ return true;
773
+ }
774
+ }
775
+ return false;
776
+ }
777
+ function escapeRegExp(str) {
778
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
779
+ }
780
+ function detectLanguages(script) {
781
+ const detected = /* @__PURE__ */ new Set();
782
+ for (const lang of SUPPORTED_LANGUAGES) {
783
+ if (lang === "en") continue;
784
+ if (containsLanguageKeywords(script, lang)) {
785
+ detected.add(lang);
786
+ }
787
+ }
788
+ return detected;
789
+ }
790
+ var customKeywordRegistry = /* @__PURE__ */ new Map();
791
+ function registerCustomKeywords(code, config) {
792
+ const existing = LANGUAGE_KEYWORDS[code];
793
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
794
+ const isNonLatin = config.isNonLatin ?? nonLatinLangs.includes(code);
795
+ if (config.extend && existing) {
796
+ const merged = /* @__PURE__ */ new Set([...existing, ...config.keywords]);
797
+ customKeywordRegistry.set(code, { keywords: merged, isNonLatin });
798
+ } else {
799
+ customKeywordRegistry.set(code, { keywords: config.keywords, isNonLatin });
800
+ }
801
+ }
802
+ function getKeywordsForLanguage(code) {
803
+ const custom = customKeywordRegistry.get(code);
804
+ if (custom) return custom.keywords;
805
+ return LANGUAGE_KEYWORDS[code];
806
+ }
807
+ function isNonLatinLanguage(code) {
808
+ const custom = customKeywordRegistry.get(code);
809
+ if (custom) return custom.isNonLatin;
810
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
811
+ return nonLatinLangs.includes(code);
812
+ }
813
+ function getAllLanguageCodes() {
814
+ const builtin = [...SUPPORTED_LANGUAGES];
815
+ const custom = [...customKeywordRegistry.keys()];
816
+ return [.../* @__PURE__ */ new Set([...builtin, ...custom])];
817
+ }
818
+ function clearCustomKeywords() {
819
+ customKeywordRegistry.clear();
820
+ }
821
+ function getOptimalRegion(languages) {
822
+ if (languages.size === 0) return null;
823
+ const langArray = [...languages];
824
+ if (langArray.every((l) => REGIONS.western.includes(l))) {
825
+ return "western";
826
+ }
827
+ if (langArray.every((l) => REGIONS["east-asian"].includes(l))) {
828
+ return "east-asian";
829
+ }
830
+ if (langArray.every((l) => REGIONS.slavic.includes(l))) {
831
+ return "slavic";
832
+ }
833
+ if (langArray.every((l) => REGIONS["south-asian"].includes(l))) {
834
+ return "south-asian";
835
+ }
836
+ if (langArray.every((l) => REGIONS.priority.includes(l))) {
837
+ return "priority";
838
+ }
839
+ return "all";
840
+ }
841
+
842
+ // src/scanner.ts
843
+ var HTMX_REQUEST_PATTERN = /\b(hx-get|hx-post|hx-put|hx-patch|hx-delete)\s*=\s*["']([^"']+)["']/gi;
844
+ var FIXI_ACTION_PATTERN = /\bfx-action\s*=\s*["']([^"']+)["']/gi;
845
+ var FIXI_METHOD_PATTERN = /\bfx-method\s*=\s*["'](GET|POST|PUT|PATCH|DELETE)["']/gi;
846
+ var HTMX_SWAP_PATTERN = /\b(hx-swap|fx-swap)\s*=\s*["']([^"']+)["']/gi;
847
+ var HTMX_TARGET_PATTERN = /\b(hx-target|fx-target)\s*=\s*["']([^"']+)["']/gi;
848
+ var HTMX_TRIGGER_PATTERN = /\b(hx-trigger|fx-trigger)\s*=\s*["']([^"']+)["']/gi;
849
+ var HTMX_URL_PATTERN = /\b(hx-push-url|hx-replace-url)\s*=\s*["'][^"']+["']/gi;
850
+ var HTMX_CONFIRM_PATTERN = /\bhx-confirm\s*=\s*["']/gi;
851
+ var HTMX_ON_PATTERN = /\bhx-on:(\w+)\s*=\s*["']([^"']+)["']/g;
852
+ function toRegex(pattern, defaultPattern) {
853
+ if (!pattern) return defaultPattern;
854
+ if (pattern instanceof RegExp) return pattern;
855
+ if (Array.isArray(pattern)) {
856
+ const escaped = pattern.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
857
+ return new RegExp(`(${escaped.join("|")})`);
858
+ }
859
+ return defaultPattern;
860
+ }
861
+ var Scanner = class {
862
+ constructor(options) {
863
+ this.include = toRegex(
864
+ options.include,
865
+ /\.(html?|vue|svelte|jsx?|tsx?|astro|php|erb|ejs|hbs|handlebars)$/
866
+ );
867
+ this.exclude = toRegex(options.exclude, /node_modules|\.git/);
868
+ this.debug = options.debug ?? false;
869
+ }
870
+ /**
871
+ * Check if a file should be scanned
872
+ */
873
+ shouldScan(id) {
874
+ return this.include.test(id) && !this.exclude.test(id);
875
+ }
876
+ /**
877
+ * Scan code for hyperscript usage
878
+ */
879
+ scan(code, id) {
880
+ const usage = {
881
+ commands: /* @__PURE__ */ new Set(),
882
+ blocks: /* @__PURE__ */ new Set(),
883
+ positional: false,
884
+ detectedLanguages: /* @__PURE__ */ new Set()
885
+ };
886
+ const attrPatterns = [
887
+ /_\s*=\s*"([^"]+)"/g,
888
+ // _="..."
889
+ /_\s*=\s*'([^']+)'/g,
890
+ // _='...'
891
+ /_\s*=\s*`([^`]+)`/g,
892
+ // _=`...`
893
+ /_=\{`([^`]+)`\}/g,
894
+ // _={`...`} (JSX)
895
+ /_=\{['"]([^'"]+)['"]\}/g
896
+ // _={"..."} or _={'...'} (JSX)
897
+ ];
898
+ for (const pattern of attrPatterns) {
899
+ let match2;
900
+ while (match2 = pattern.exec(code)) {
901
+ this.analyzeScript(match2[1], usage);
902
+ }
903
+ }
904
+ const scriptPattern = /<script[^>]*type=["']?text\/hyperscript["']?[^>]*>([^<]+)<\/script>/gi;
905
+ let match;
906
+ while (match = scriptPattern.exec(code)) {
907
+ this.analyzeScript(match[1], usage);
908
+ }
909
+ const htmxUsage = this.scanHtmxAttributes(code);
910
+ if (htmxUsage.hasHtmxAttributes) {
911
+ usage.htmx = htmxUsage;
912
+ this.inferCommandsFromHtmx(htmxUsage, usage);
913
+ for (const handlerCode of htmxUsage.onHandlers) {
914
+ this.analyzeScript(handlerCode, usage);
915
+ }
916
+ if (/hx-target\s*=\s*["'](closest|next|previous|find)\s/i.test(code)) {
917
+ usage.positional = true;
918
+ }
919
+ }
920
+ if (this.debug && (usage.commands.size > 0 || usage.blocks.size > 0 || usage.detectedLanguages.size > 0 || usage.htmx?.hasHtmxAttributes)) {
921
+ console.log(`[hyperfixi] Scanned ${id}:`, {
922
+ commands: [...usage.commands],
923
+ blocks: [...usage.blocks],
924
+ positional: usage.positional,
925
+ languages: [...usage.detectedLanguages],
926
+ htmx: usage.htmx ? {
927
+ hasHtmxAttributes: usage.htmx.hasHtmxAttributes,
928
+ hasFixiAttributes: usage.htmx.hasFixiAttributes,
929
+ httpMethods: [...usage.htmx.httpMethods],
930
+ swapStrategies: [...usage.htmx.swapStrategies]
931
+ } : void 0
932
+ });
933
+ }
934
+ return usage;
935
+ }
936
+ /**
937
+ * Analyze a hyperscript snippet for commands, blocks, and expressions
938
+ */
939
+ analyzeScript(script, usage) {
940
+ const commandPattern = /\b(toggle|add|remove|removeClass|show|hide|set|get|put|append|take|increment|decrement|log|send|trigger|wait|transition|go|call|focus|blur|return)\b/g;
941
+ let match;
942
+ while (match = commandPattern.exec(script)) {
943
+ usage.commands.add(match[1]);
944
+ }
945
+ if (/\bif\b/.test(script)) usage.blocks.add("if");
946
+ if (/\bunless\b/.test(script)) usage.blocks.add("if");
947
+ if (/\brepeat\s+(\d+|:\w+|\$\w+|[\w.]+)\s+times?\b/i.test(script)) usage.blocks.add("repeat");
948
+ if (/\bfor\s+(each|every)\b/i.test(script)) usage.blocks.add("for");
949
+ if (/\bwhile\b/.test(script)) usage.blocks.add("while");
950
+ if (/\bfetch\b/.test(script)) usage.blocks.add("fetch");
951
+ if (/\b(first|last|next|previous|closest|parent)\b/.test(script)) {
952
+ usage.positional = true;
953
+ }
954
+ const languages = detectLanguages(script);
955
+ for (const lang of languages) {
956
+ usage.detectedLanguages.add(lang);
957
+ }
958
+ }
959
+ /**
960
+ * Scan for htmx/fixi attributes
961
+ */
962
+ scanHtmxAttributes(code) {
963
+ const usage = {
964
+ hasHtmxAttributes: false,
965
+ hasFixiAttributes: false,
966
+ httpMethods: /* @__PURE__ */ new Set(),
967
+ swapStrategies: /* @__PURE__ */ new Set(),
968
+ onHandlers: [],
969
+ triggerModifiers: /* @__PURE__ */ new Set(),
970
+ urlManagement: /* @__PURE__ */ new Set(),
971
+ usesConfirm: false
972
+ };
973
+ let match;
974
+ const requestPattern = new RegExp(HTMX_REQUEST_PATTERN.source, "gi");
975
+ while (match = requestPattern.exec(code)) {
976
+ usage.hasHtmxAttributes = true;
977
+ usage.httpMethods.add(match[1].replace("hx-", "").toUpperCase());
978
+ }
979
+ if (new RegExp(FIXI_ACTION_PATTERN.source, "gi").test(code)) {
980
+ usage.hasHtmxAttributes = true;
981
+ usage.hasFixiAttributes = true;
982
+ }
983
+ const fixiMethodPattern = new RegExp(FIXI_METHOD_PATTERN.source, "gi");
984
+ while (match = fixiMethodPattern.exec(code)) {
985
+ usage.hasHtmxAttributes = true;
986
+ usage.hasFixiAttributes = true;
987
+ usage.httpMethods.add(match[1].toUpperCase());
988
+ }
989
+ const swapPattern = new RegExp(HTMX_SWAP_PATTERN.source, "gi");
990
+ while (match = swapPattern.exec(code)) {
991
+ usage.hasHtmxAttributes = true;
992
+ usage.swapStrategies.add(match[2].split(/\s+/)[0]);
993
+ }
994
+ const triggerPattern = new RegExp(HTMX_TRIGGER_PATTERN.source, "gi");
995
+ while (match = triggerPattern.exec(code)) {
996
+ usage.hasHtmxAttributes = true;
997
+ const trigger = match[2];
998
+ if (/delay:/i.test(trigger)) usage.triggerModifiers.add("debounce");
999
+ if (/throttle:/i.test(trigger)) usage.triggerModifiers.add("throttle");
1000
+ if (/\bonce\b/i.test(trigger)) usage.triggerModifiers.add("once");
1001
+ }
1002
+ if (new RegExp(HTMX_URL_PATTERN.source, "gi").test(code)) {
1003
+ usage.hasHtmxAttributes = true;
1004
+ if (/hx-push-url/i.test(code)) usage.urlManagement.add("push-url");
1005
+ if (/hx-replace-url/i.test(code)) usage.urlManagement.add("replace-url");
1006
+ }
1007
+ if (new RegExp(HTMX_CONFIRM_PATTERN.source, "gi").test(code)) {
1008
+ usage.hasHtmxAttributes = true;
1009
+ usage.usesConfirm = true;
1010
+ }
1011
+ const onPattern = new RegExp(HTMX_ON_PATTERN.source, "g");
1012
+ while (match = onPattern.exec(code)) {
1013
+ usage.hasHtmxAttributes = true;
1014
+ usage.onHandlers.push(match[2]);
1015
+ }
1016
+ const targetPattern = new RegExp(HTMX_TARGET_PATTERN.source, "gi");
1017
+ while (match = targetPattern.exec(code)) {
1018
+ usage.hasHtmxAttributes = true;
1019
+ }
1020
+ return usage;
1021
+ }
1022
+ /**
1023
+ * Infer commands from htmx usage
1024
+ */
1025
+ inferCommandsFromHtmx(htmx, usage) {
1026
+ if (htmx.httpMethods.size > 0) {
1027
+ usage.blocks.add("fetch");
1028
+ usage.commands.add("put");
1029
+ }
1030
+ for (const swap of htmx.swapStrategies) {
1031
+ switch (swap.toLowerCase()) {
1032
+ case "morph":
1033
+ usage.commands.add("morph");
1034
+ break;
1035
+ case "delete":
1036
+ usage.commands.add("remove");
1037
+ break;
1038
+ default:
1039
+ usage.commands.add("put");
1040
+ }
1041
+ }
1042
+ if (htmx.usesConfirm) {
1043
+ usage.blocks.add("if");
1044
+ }
1045
+ }
1046
+ /**
1047
+ * Scan all files in a project directory
1048
+ * Used during production build to scan the entire codebase
1049
+ */
1050
+ async scanProject(dir) {
1051
+ const results = /* @__PURE__ */ new Map();
1052
+ try {
1053
+ const { glob } = await import("glob");
1054
+ const fs = await import("fs");
1055
+ const files = await glob("**/*.{html,htm,vue,svelte,js,jsx,ts,tsx,astro,php,erb,ejs,hbs}", {
1056
+ cwd: dir,
1057
+ ignore: ["node_modules/**", "dist/**", ".git/**"],
1058
+ absolute: true
1059
+ });
1060
+ for (const file of files) {
1061
+ if (this.shouldScan(file)) {
1062
+ try {
1063
+ const code = fs.readFileSync(file, "utf-8");
1064
+ const usage = this.scan(code, file);
1065
+ if (usage.commands.size > 0 || usage.blocks.size > 0 || usage.positional || usage.detectedLanguages.size > 0) {
1066
+ results.set(file, usage);
1067
+ }
1068
+ } catch {
1069
+ }
1070
+ }
1071
+ }
1072
+ } catch (error) {
1073
+ console.warn("[hyperfixi] Error scanning project:", error);
1074
+ }
1075
+ return results;
1076
+ }
1077
+ };
1078
+
1079
+ // src/aggregator.ts
1080
+ var Aggregator = class {
1081
+ constructor() {
1082
+ this.fileUsage = /* @__PURE__ */ new Map();
1083
+ this.cachedUsage = null;
1084
+ }
1085
+ /**
1086
+ * Add or update usage for a file
1087
+ * @returns true if the overall usage changed
1088
+ */
1089
+ add(filePath, usage) {
1090
+ const existing = this.fileUsage.get(filePath);
1091
+ if (existing) {
1092
+ const commandsEqual = this.setsEqual(existing.commands, usage.commands);
1093
+ const blocksEqual = this.setsEqual(existing.blocks, usage.blocks);
1094
+ const positionalEqual = existing.positional === usage.positional;
1095
+ const languagesEqual = this.setsEqual(existing.detectedLanguages, usage.detectedLanguages);
1096
+ const htmxEqual = this.htmxUsageEqual(existing.htmx, usage.htmx);
1097
+ if (commandsEqual && blocksEqual && positionalEqual && languagesEqual && htmxEqual) {
1098
+ return false;
1099
+ }
1100
+ }
1101
+ this.fileUsage.set(filePath, usage);
1102
+ this.cachedUsage = null;
1103
+ return true;
1104
+ }
1105
+ /**
1106
+ * Remove a file from tracking (e.g., when deleted)
1107
+ * @returns true if the overall usage changed
1108
+ */
1109
+ remove(filePath) {
1110
+ const existed = this.fileUsage.delete(filePath);
1111
+ if (existed) {
1112
+ this.cachedUsage = null;
1113
+ }
1114
+ return existed;
1115
+ }
1116
+ /**
1117
+ * Get aggregated usage across all files
1118
+ */
1119
+ getUsage() {
1120
+ if (this.cachedUsage) {
1121
+ return this.cachedUsage;
1122
+ }
1123
+ const commands = /* @__PURE__ */ new Set();
1124
+ const blocks = /* @__PURE__ */ new Set();
1125
+ const detectedLanguages = /* @__PURE__ */ new Set();
1126
+ let positional = false;
1127
+ const htmx = {
1128
+ hasHtmxAttributes: false,
1129
+ hasFixiAttributes: false,
1130
+ httpMethods: /* @__PURE__ */ new Set(),
1131
+ swapStrategies: /* @__PURE__ */ new Set(),
1132
+ onHandlers: [],
1133
+ triggerModifiers: /* @__PURE__ */ new Set(),
1134
+ urlManagement: /* @__PURE__ */ new Set(),
1135
+ usesConfirm: false
1136
+ };
1137
+ for (const usage of this.fileUsage.values()) {
1138
+ for (const cmd of usage.commands) commands.add(cmd);
1139
+ for (const block of usage.blocks) blocks.add(block);
1140
+ for (const lang of usage.detectedLanguages) detectedLanguages.add(lang);
1141
+ if (usage.positional) positional = true;
1142
+ if (usage.htmx) {
1143
+ if (usage.htmx.hasHtmxAttributes) htmx.hasHtmxAttributes = true;
1144
+ if (usage.htmx.hasFixiAttributes) htmx.hasFixiAttributes = true;
1145
+ for (const method of usage.htmx.httpMethods) htmx.httpMethods.add(method);
1146
+ for (const swap of usage.htmx.swapStrategies) htmx.swapStrategies.add(swap);
1147
+ htmx.onHandlers.push(...usage.htmx.onHandlers);
1148
+ for (const modifier of usage.htmx.triggerModifiers) htmx.triggerModifiers.add(modifier);
1149
+ for (const url of usage.htmx.urlManagement) htmx.urlManagement.add(url);
1150
+ if (usage.htmx.usesConfirm) htmx.usesConfirm = true;
1151
+ }
1152
+ }
1153
+ this.cachedUsage = {
1154
+ commands,
1155
+ blocks,
1156
+ positional,
1157
+ detectedLanguages,
1158
+ htmx,
1159
+ fileUsage: new Map(this.fileUsage)
1160
+ };
1161
+ return this.cachedUsage;
1162
+ }
1163
+ /**
1164
+ * Load usage from a project scan
1165
+ */
1166
+ loadFromScan(scannedFiles) {
1167
+ this.fileUsage = new Map(scannedFiles);
1168
+ this.cachedUsage = null;
1169
+ }
1170
+ /**
1171
+ * Check if any hyperscript usage has been detected
1172
+ */
1173
+ hasUsage() {
1174
+ const usage = this.getUsage();
1175
+ return usage.commands.size > 0 || usage.blocks.size > 0 || usage.positional || usage.detectedLanguages.size > 0;
1176
+ }
1177
+ /**
1178
+ * Get summary for logging
1179
+ */
1180
+ getSummary() {
1181
+ const usage = this.getUsage();
1182
+ return {
1183
+ commands: [...usage.commands].sort(),
1184
+ blocks: [...usage.blocks].sort(),
1185
+ positional: usage.positional,
1186
+ languages: [...usage.detectedLanguages].sort(),
1187
+ fileCount: this.fileUsage.size
1188
+ };
1189
+ }
1190
+ /**
1191
+ * Clear all tracked usage
1192
+ */
1193
+ clear() {
1194
+ this.fileUsage.clear();
1195
+ this.cachedUsage = null;
1196
+ }
1197
+ /**
1198
+ * Compare two sets for equality
1199
+ */
1200
+ setsEqual(a, b) {
1201
+ if (a.size !== b.size) return false;
1202
+ for (const item of a) {
1203
+ if (!b.has(item)) return false;
1204
+ }
1205
+ return true;
1206
+ }
1207
+ /**
1208
+ * Compare two HtmxUsage objects for equality
1209
+ */
1210
+ htmxUsageEqual(a, b) {
1211
+ if (!a && !b) return true;
1212
+ if (!a || !b) return false;
1213
+ return a.hasHtmxAttributes === b.hasHtmxAttributes && a.hasFixiAttributes === b.hasFixiAttributes && this.setsEqual(a.httpMethods, b.httpMethods) && this.setsEqual(a.swapStrategies, b.swapStrategies) && this.setsEqual(a.triggerModifiers, b.triggerModifiers) && this.setsEqual(a.urlManagement, b.urlManagement) && a.usesConfirm === b.usesConfirm;
1214
+ }
1215
+ };
1216
+
1217
+ // src/generator.ts
1218
+ var import_bundle_generator = require("@hyperfixi/core/bundle-generator");
1219
+
1220
+ // src/semantic-integration.ts
1221
+ var MULTILINGUAL_COMMAND_ALIASES = {
1222
+ ja: {
1223
+ \u30C8\u30B0\u30EB: "toggle",
1224
+ \u5207\u308A\u66FF\u3048: "toggle",
1225
+ \u8FFD\u52A0: "add",
1226
+ \u524A\u9664: "remove",
1227
+ \u8868\u793A: "show",
1228
+ \u96A0\u3059: "hide",
1229
+ \u975E\u8868\u793A: "hide",
1230
+ \u8A2D\u5B9A: "set",
1231
+ \u30BB\u30C3\u30C8: "set",
1232
+ \u5897\u52A0: "increment",
1233
+ \u6E1B\u5C11: "decrement",
1234
+ \u30ED\u30B0: "log",
1235
+ \u51FA\u529B: "log"
1236
+ },
1237
+ ko: {
1238
+ \uD1A0\uAE00: "toggle",
1239
+ \uC804\uD658: "toggle",
1240
+ \uCD94\uAC00: "add",
1241
+ \uC81C\uAC70: "remove",
1242
+ \uC0AD\uC81C: "remove",
1243
+ \uD45C\uC2DC: "show",
1244
+ \uC228\uAE30\uB2E4: "hide",
1245
+ \uC124\uC815: "set",
1246
+ \uC99D\uAC00: "increment",
1247
+ \uAC10\uC18C: "decrement",
1248
+ \uB85C\uADF8: "log"
1249
+ },
1250
+ zh: {
1251
+ \u5207\u6362: "toggle",
1252
+ \u6DFB\u52A0: "add",
1253
+ \u79FB\u9664: "remove",
1254
+ \u5220\u9664: "remove",
1255
+ \u663E\u793A: "show",
1256
+ \u9690\u85CF: "hide",
1257
+ \u8BBE\u7F6E: "set",
1258
+ \u8BBE\u5B9A: "set",
1259
+ \u589E\u52A0: "increment",
1260
+ \u51CF\u5C11: "decrement",
1261
+ \u65E5\u5FD7: "log",
1262
+ \u8BB0\u5F55: "log"
1263
+ },
1264
+ ar: {
1265
+ \u0628\u062F\u0651\u0644: "toggle",
1266
+ \u0628\u062F\u0644: "toggle",
1267
+ \u0623\u0636\u0641: "add",
1268
+ \u0627\u0636\u0641: "add",
1269
+ \u0623\u0632\u0644: "remove",
1270
+ \u0627\u0632\u0644: "remove",
1271
+ \u0627\u062D\u0630\u0641: "remove",
1272
+ \u0623\u0638\u0647\u0631: "show",
1273
+ \u0627\u0638\u0647\u0631: "show",
1274
+ \u0623\u062E\u0641\u0650: "hide",
1275
+ \u0627\u062E\u0641: "hide",
1276
+ \u0636\u0639: "set",
1277
+ \u0627\u0636\u0639: "set",
1278
+ \u0632\u0650\u062F: "increment",
1279
+ \u0623\u0646\u0642\u0635: "decrement"
1280
+ },
1281
+ es: {
1282
+ alternar: "toggle",
1283
+ a\u00F1adir: "add",
1284
+ agregar: "add",
1285
+ quitar: "remove",
1286
+ eliminar: "remove",
1287
+ mostrar: "show",
1288
+ ocultar: "hide",
1289
+ esconder: "hide",
1290
+ establecer: "set",
1291
+ fijar: "set",
1292
+ incrementar: "increment",
1293
+ decrementar: "decrement"
1294
+ },
1295
+ pt: {
1296
+ alternar: "toggle",
1297
+ adicionar: "add",
1298
+ remover: "remove",
1299
+ mostrar: "show",
1300
+ esconder: "hide",
1301
+ ocultar: "hide",
1302
+ definir: "set",
1303
+ incrementar: "increment",
1304
+ decrementar: "decrement"
1305
+ },
1306
+ fr: {
1307
+ basculer: "toggle",
1308
+ ajouter: "add",
1309
+ supprimer: "remove",
1310
+ retirer: "remove",
1311
+ afficher: "show",
1312
+ montrer: "show",
1313
+ cacher: "hide",
1314
+ masquer: "hide",
1315
+ d\u00E9finir: "set",
1316
+ incr\u00E9menter: "increment",
1317
+ d\u00E9cr\u00E9menter: "decrement"
1318
+ },
1319
+ de: {
1320
+ umschalten: "toggle",
1321
+ hinzuf\u00FCgen: "add",
1322
+ entfernen: "remove",
1323
+ l\u00F6schen: "remove",
1324
+ anzeigen: "show",
1325
+ zeigen: "show",
1326
+ verbergen: "hide",
1327
+ verstecken: "hide",
1328
+ setzen: "set",
1329
+ festlegen: "set",
1330
+ erh\u00F6hen: "increment",
1331
+ verringern: "decrement"
1332
+ },
1333
+ tr: {
1334
+ de\u011Fi\u015Ftir: "toggle",
1335
+ de\u011Fistir: "toggle",
1336
+ ekle: "add",
1337
+ kald\u0131r: "remove",
1338
+ kaldir: "remove",
1339
+ sil: "remove",
1340
+ g\u00F6ster: "show",
1341
+ gizle: "hide",
1342
+ sakla: "hide",
1343
+ ayarla: "set",
1344
+ belirle: "set",
1345
+ artt\u0131r: "increment",
1346
+ azalt: "decrement"
1347
+ },
1348
+ id: {
1349
+ alih: "toggle",
1350
+ beralih: "toggle",
1351
+ tambah: "add",
1352
+ hapus: "remove",
1353
+ buang: "remove",
1354
+ tampilkan: "show",
1355
+ sembunyikan: "hide",
1356
+ atur: "set",
1357
+ tetapkan: "set",
1358
+ tambahkan: "increment",
1359
+ kurangi: "decrement"
1360
+ },
1361
+ sw: {
1362
+ badilisha: "toggle",
1363
+ ongeza: "add",
1364
+ ondoa: "remove",
1365
+ futa: "remove",
1366
+ onyesha: "show",
1367
+ ficha: "hide",
1368
+ weka: "set",
1369
+ sanidi: "set",
1370
+ ongezea: "increment",
1371
+ punguza: "decrement"
1372
+ },
1373
+ qu: {
1374
+ tikray: "toggle",
1375
+ yapay: "add",
1376
+ qichuy: "remove",
1377
+ pichay: "remove",
1378
+ rikuchiy: "show",
1379
+ pakay: "hide",
1380
+ churay: "set",
1381
+ pisiyachiy: "decrement"
1382
+ }
1383
+ };
1384
+ function getMultilingualCommandAliases(languages) {
1385
+ const aliases = {};
1386
+ for (const lang of languages) {
1387
+ const langAliases = MULTILINGUAL_COMMAND_ALIASES[lang];
1388
+ if (langAliases) {
1389
+ Object.assign(aliases, langAliases);
1390
+ }
1391
+ }
1392
+ return aliases;
1393
+ }
1394
+ function generateMultilingualAliases(languages) {
1395
+ const aliases = {};
1396
+ for (const lang of languages) {
1397
+ const langAliases = MULTILINGUAL_COMMAND_ALIASES[lang];
1398
+ if (langAliases) {
1399
+ Object.assign(aliases, langAliases);
1400
+ }
1401
+ }
1402
+ if (Object.keys(aliases).length === 0) {
1403
+ return `
1404
+ // No multilingual aliases needed - just pass through
1405
+ function preprocessMultilingual(code) { return code; }
1406
+ `;
1407
+ }
1408
+ const aliasEntries = Object.entries(aliases).map(([key, val]) => ` '${key}': '${val}'`).join(",\n");
1409
+ const escapedKeys = Object.keys(aliases).map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
1410
+ return `
1411
+ // Multilingual command aliases for HybridParser fallback
1412
+ const MULTILINGUAL_ALIASES = {
1413
+ ${aliasEntries}
1414
+ };
1415
+
1416
+ // Register multilingual aliases with the parser
1417
+ addCommandAliases(MULTILINGUAL_ALIASES);
1418
+
1419
+ // Preprocessing regex to translate multilingual keywords to English
1420
+ // The HybridParser tokenizer only accepts ASCII identifiers, so we need
1421
+ // to translate non-ASCII keywords before parsing.
1422
+ const MULTILINGUAL_KEYWORD_REGEX = new RegExp('(^|\\\\s)(${escapedKeys})(?=\\\\s|\\\\.|$)', 'g');
1423
+
1424
+ /**
1425
+ * Preprocess multilingual code to replace non-ASCII keywords with English equivalents.
1426
+ * This is needed because HybridParser's tokenizer only accepts ASCII identifiers.
1427
+ */
1428
+ function preprocessMultilingual(code) {
1429
+ return code.replace(MULTILINGUAL_KEYWORD_REGEX, (match, prefix, keyword) => {
1430
+ const english = MULTILINGUAL_ALIASES[keyword];
1431
+ return english ? prefix + english : match;
1432
+ });
1433
+ }
1434
+ `;
1435
+ }
1436
+ function resolveSemanticConfig(options, detectedLanguages) {
1437
+ const grammarEnabled = options.grammar ?? false;
1438
+ let semanticEnabled = grammarEnabled;
1439
+ if (options.semantic === true || options.semantic === "auto") {
1440
+ semanticEnabled = true;
1441
+ } else if (options.semantic === "en") {
1442
+ semanticEnabled = true;
1443
+ } else if (options.semantic === false) {
1444
+ semanticEnabled = false;
1445
+ }
1446
+ if (!semanticEnabled) {
1447
+ return {
1448
+ enabled: false,
1449
+ bundleType: null,
1450
+ languages: /* @__PURE__ */ new Set(),
1451
+ grammarEnabled: false
1452
+ };
1453
+ }
1454
+ const languages = /* @__PURE__ */ new Set();
1455
+ for (const lang of detectedLanguages) {
1456
+ languages.add(lang);
1457
+ }
1458
+ if (options.languages) {
1459
+ for (const lang of options.languages) {
1460
+ languages.add(lang);
1461
+ }
1462
+ }
1463
+ if (options.extraLanguages) {
1464
+ for (const lang of options.extraLanguages) {
1465
+ languages.add(lang);
1466
+ }
1467
+ }
1468
+ let bundleType = selectBundleType(options, languages);
1469
+ return {
1470
+ enabled: true,
1471
+ bundleType,
1472
+ languages,
1473
+ grammarEnabled
1474
+ };
1475
+ }
1476
+ function selectBundleType(options, languages) {
1477
+ if (options.region) {
1478
+ return options.region;
1479
+ }
1480
+ if (options.semantic === "en") {
1481
+ return "en";
1482
+ }
1483
+ if (options.languages?.length) {
1484
+ return selectOptimalBundle(new Set(options.languages));
1485
+ }
1486
+ if (languages.size === 0) {
1487
+ return "en";
1488
+ }
1489
+ return selectOptimalBundle(languages);
1490
+ }
1491
+ var SINGLE_LANGUAGE_BUNDLES = [
1492
+ "ar",
1493
+ "bn",
1494
+ "de",
1495
+ "en",
1496
+ "es",
1497
+ "es-MX",
1498
+ "fr",
1499
+ "he",
1500
+ "hi",
1501
+ "id",
1502
+ "it",
1503
+ "ja",
1504
+ "ko",
1505
+ "ms",
1506
+ "pl",
1507
+ "pt",
1508
+ "qu",
1509
+ "ru",
1510
+ "sw",
1511
+ "th",
1512
+ "tl",
1513
+ "tr",
1514
+ "uk",
1515
+ "vi",
1516
+ "zh"
1517
+ ];
1518
+ function selectOptimalBundle(languages) {
1519
+ if (languages.size === 0) {
1520
+ return "en";
1521
+ }
1522
+ const langArray = [...languages];
1523
+ if (langArray.length === 1) {
1524
+ const lang = langArray[0];
1525
+ if (SINGLE_LANGUAGE_BUNDLES.includes(lang)) {
1526
+ return lang;
1527
+ }
1528
+ }
1529
+ if (langArray.length === 2 && langArray.includes("en") && langArray.includes("es")) {
1530
+ return "es-en";
1531
+ }
1532
+ if (langArray.every((l) => REGIONS.western.includes(l))) {
1533
+ return "western";
1534
+ }
1535
+ if (langArray.every((l) => REGIONS["east-asian"].includes(l))) {
1536
+ return "east-asian";
1537
+ }
1538
+ if (langArray.every((l) => REGIONS.priority.includes(l))) {
1539
+ return "priority";
1540
+ }
1541
+ return "all";
1542
+ }
1543
+ var SEMANTIC_BUNDLE_SIZES = {
1544
+ // Single-language bundles (all 25 languages)
1545
+ ar: { raw: "66 KB", gzip: "~17 KB" },
1546
+ bn: { raw: "56 KB", gzip: "~14 KB" },
1547
+ de: { raw: "57 KB", gzip: "~14 KB" },
1548
+ en: { raw: "82 KB", gzip: "~20 KB" },
1549
+ es: { raw: "64 KB", gzip: "~16 KB" },
1550
+ "es-MX": { raw: "64 KB", gzip: "~16 KB" },
1551
+ fr: { raw: "57 KB", gzip: "~14 KB" },
1552
+ he: { raw: "56 KB", gzip: "~14 KB" },
1553
+ hi: { raw: "56 KB", gzip: "~14 KB" },
1554
+ id: { raw: "57 KB", gzip: "~14 KB" },
1555
+ it: { raw: "57 KB", gzip: "~14 KB" },
1556
+ ja: { raw: "67 KB", gzip: "~17 KB" },
1557
+ ko: { raw: "69 KB", gzip: "~18 KB" },
1558
+ ms: { raw: "56 KB", gzip: "~14 KB" },
1559
+ pl: { raw: "56 KB", gzip: "~14 KB" },
1560
+ pt: { raw: "56 KB", gzip: "~14 KB" },
1561
+ qu: { raw: "56 KB", gzip: "~14 KB" },
1562
+ ru: { raw: "56 KB", gzip: "~14 KB" },
1563
+ sw: { raw: "56 KB", gzip: "~14 KB" },
1564
+ th: { raw: "56 KB", gzip: "~14 KB" },
1565
+ tl: { raw: "56 KB", gzip: "~14 KB" },
1566
+ tr: { raw: "73 KB", gzip: "~18 KB" },
1567
+ uk: { raw: "56 KB", gzip: "~14 KB" },
1568
+ vi: { raw: "56 KB", gzip: "~14 KB" },
1569
+ zh: { raw: "58 KB", gzip: "~15 KB" },
1570
+ // Regional bundles
1571
+ "es-en": { raw: "99 KB", gzip: "~25 KB" },
1572
+ western: { raw: "127 KB", gzip: "~30 KB" },
1573
+ "east-asian": { raw: "99 KB", gzip: "~24 KB" },
1574
+ priority: { raw: "231 KB", gzip: "~48 KB" },
1575
+ all: { raw: "324 KB", gzip: "~61 KB" }
1576
+ };
1577
+ function getSemanticBundleSize(bundleType) {
1578
+ return SEMANTIC_BUNDLE_SIZES[bundleType] ?? SEMANTIC_BUNDLE_SIZES.all;
1579
+ }
1580
+ var LANGUAGES_WITH_ESM_EXPORTS = /* @__PURE__ */ new Set([
1581
+ "ar",
1582
+ "bn",
1583
+ "de",
1584
+ "en",
1585
+ "es",
1586
+ "es-MX",
1587
+ "fr",
1588
+ "he",
1589
+ "hi",
1590
+ "id",
1591
+ "it",
1592
+ "ja",
1593
+ "ko",
1594
+ "ms",
1595
+ "pl",
1596
+ "pt",
1597
+ "qu",
1598
+ "ru",
1599
+ "sw",
1600
+ "th",
1601
+ "tl",
1602
+ "tr",
1603
+ "uk",
1604
+ "vi",
1605
+ "zh"
1606
+ ]);
1607
+ function getLanguagesForBundleType(bundleType, configLanguages) {
1608
+ const languages = new Set(configLanguages);
1609
+ switch (bundleType) {
1610
+ case "western":
1611
+ REGIONS.western.forEach((l) => languages.add(l));
1612
+ break;
1613
+ case "east-asian":
1614
+ REGIONS["east-asian"].forEach((l) => languages.add(l));
1615
+ break;
1616
+ case "priority":
1617
+ REGIONS.priority.forEach((l) => languages.add(l));
1618
+ break;
1619
+ case "all":
1620
+ REGIONS.all.forEach((l) => languages.add(l));
1621
+ break;
1622
+ case "es-en":
1623
+ languages.add("en");
1624
+ languages.add("es");
1625
+ break;
1626
+ default:
1627
+ if (typeof bundleType === "string" && bundleType.length <= 3) {
1628
+ languages.add(bundleType);
1629
+ }
1630
+ break;
1631
+ }
1632
+ languages.add("en");
1633
+ return languages;
1634
+ }
1635
+ function filterToAvailableLanguages(languages) {
1636
+ const available = /* @__PURE__ */ new Set();
1637
+ for (const lang of languages) {
1638
+ if (LANGUAGES_WITH_ESM_EXPORTS.has(lang)) {
1639
+ available.add(lang);
1640
+ }
1641
+ }
1642
+ available.add("en");
1643
+ return available;
1644
+ }
1645
+ function generateSemanticIntegrationCode(config) {
1646
+ if (!config.enabled || !config.bundleType) {
1647
+ return "";
1648
+ }
1649
+ const resolvedLanguages = getLanguagesForBundleType(config.bundleType, config.languages);
1650
+ const availableLanguages = filterToAvailableLanguages(resolvedLanguages);
1651
+ const languages = [...config.languages].join("', '");
1652
+ let code = `
1653
+ // =============================================================================
1654
+ // SEMANTIC PARSER INTEGRATION
1655
+ // =============================================================================
1656
+
1657
+ // Core infrastructure (no language data bundled)
1658
+ import {
1659
+ createSemanticAnalyzer,
1660
+ buildAST,
1661
+ isLanguageSupported,
1662
+ } from '@lokascript/semantic/core';
1663
+
1664
+ // Register required languages (self-registering side-effect imports)
1665
+ `;
1666
+ const sortedLangs = [...availableLanguages].sort();
1667
+ for (const lang of sortedLangs) {
1668
+ code += `import '@lokascript/semantic/languages/${lang}';
1669
+ `;
1670
+ }
1671
+ if (config.grammarEnabled) {
1672
+ code += `
1673
+ import { GrammarTransformer, translate } from '@lokascript/i18n';
1674
+
1675
+ const grammarTransformer = new GrammarTransformer();
1676
+ `;
1677
+ }
1678
+ const aliasesCode = generateMultilingualAliases(config.languages);
1679
+ code += `
1680
+ const semanticAnalyzer = createSemanticAnalyzer();
1681
+ const SUPPORTED_SEMANTIC_LANGUAGES = ['${languages}', 'en'];
1682
+ const SEMANTIC_CONFIDENCE_THRESHOLD = 0.7;
1683
+
1684
+ ${aliasesCode}
1685
+
1686
+ /**
1687
+ * Parse hyperscript using semantic parser with auto-language detection.
1688
+ * Tries each supported language until one returns a high-confidence result.
1689
+ * Falls back to HybridParser if none match.
1690
+ *
1691
+ * @param code - The hyperscript code to parse
1692
+ * @param lang - Optional language hint. If provided, tries this language first.
1693
+ */
1694
+ function parseWithSemantic(code, lang = null) {
1695
+ // Determine languages to try: specified lang first, then others
1696
+ let languagesToTry = [...SUPPORTED_SEMANTIC_LANGUAGES];
1697
+ if (lang && !languagesToTry.includes(lang)) {
1698
+ languagesToTry.unshift(lang);
1699
+ } else if (lang) {
1700
+ // Move specified lang to front
1701
+ languagesToTry = [lang, ...languagesToTry.filter(l => l !== lang)];
1702
+ }
1703
+
1704
+ // Try each language until one succeeds
1705
+ for (const tryLang of languagesToTry) {
1706
+ if (!isLanguageSupported(tryLang)) continue;
1707
+ try {
1708
+ const result = semanticAnalyzer.analyze(code, tryLang);
1709
+ if (result && result.confidence >= SEMANTIC_CONFIDENCE_THRESHOLD) {
1710
+ // buildAST returns {ast, warnings} - extract the ast
1711
+ const buildResult = buildAST(result.node);
1712
+ const ast = buildResult.ast;
1713
+
1714
+ // Semantic parser doesn't fully handle event handlers - fallback to HybridParser
1715
+ // Event handlers like "on click toggle .active" produce incomplete AST
1716
+ if (ast && ast.type === 'command' && ast.name === 'on') {
1717
+ break; // Fallback to HybridParser
1718
+ }
1719
+
1720
+ return ast;
1721
+ }
1722
+ } catch (e) {
1723
+ // Continue trying other languages
1724
+ }
1725
+ }
1726
+
1727
+ // Fallback to HybridParser for event handlers and unrecognized patterns
1728
+ // Preprocess to translate non-ASCII keywords to English (tokenizer only accepts ASCII)
1729
+ const preprocessedCode = preprocessMultilingual(code);
1730
+ return new HybridParser(preprocessedCode).parse();
1731
+ }
1732
+ `;
1733
+ if (config.grammarEnabled) {
1734
+ code += `
1735
+ /**
1736
+ * Translate hyperscript between languages.
1737
+ */
1738
+ function translateHyperscript(code, fromLang, toLang) {
1739
+ return translate(code, fromLang, toLang);
1740
+ }
1741
+ `;
1742
+ }
1743
+ return code;
1744
+ }
1745
+ function getSemanticExports(config) {
1746
+ const exports2 = [];
1747
+ if (config.enabled) {
1748
+ exports2.push("parseWithSemantic");
1749
+ exports2.push("SUPPORTED_SEMANTIC_LANGUAGES");
1750
+ }
1751
+ if (config.grammarEnabled) {
1752
+ exports2.push("translateHyperscript");
1753
+ exports2.push("grammarTransformer");
1754
+ }
1755
+ return exports2;
1756
+ }
1757
+
1758
+ // src/generator.ts
1759
+ function stripTypes(code) {
1760
+ return code.replace(/\s+as\s+\w+<[^>]*(?:<[^>]*>[^>]*)*>/g, "").replace(/\s+as\s+\w+(?:\[\])?/g, "").replace(/:\s*\w+<[^>]*(?:<[^>]*>[^>]*)*>(?:\[\])?(?=\s*[=;,)\]])/g, "").replace(
1761
+ /:\s*(?:string|number|boolean|any|unknown|void|never|null|undefined|object|symbol|bigint)(?=\s*[=;,)\]])/g,
1762
+ ""
1763
+ ).replace(/:\s*[A-Z]\w*(?:\[\])?(?=\s*[=;,)\]])/g, "").replace(/\((\w+):\s*(?:\w+|unknown|any)\)/g, "($1)").replace(/Promise<[^>]+>/g, "Promise").replace(/Array<[^>]+>/g, "Array").replace(/\):\s*\w+(?:<[^>]*>)?(?:\[\])?\s*(?=[{=])/g, ") ").replace(/\):\s*\w+(?:<[^>]*>)?\s*=>/g, ") =>").replace(
1764
+ /:\s*(?:TransitionEvent|MouseEvent|KeyboardEvent|Event|Element|HTMLElement|Node)(?=\s*[=;,)\]])/g,
1765
+ ""
1766
+ ).replace(/(\w)!(?=[,;)\].\s])/g, "$1");
1767
+ }
1768
+ var COMMAND_IMPLEMENTATIONS = {};
1769
+ var BLOCK_IMPLEMENTATIONS = {};
1770
+ for (const [name, code] of Object.entries(import_bundle_generator.COMMAND_IMPLEMENTATIONS)) {
1771
+ COMMAND_IMPLEMENTATIONS[name] = stripTypes(code);
1772
+ }
1773
+ for (const [name, code] of Object.entries(import_bundle_generator.BLOCK_IMPLEMENTATIONS)) {
1774
+ BLOCK_IMPLEMENTATIONS[name] = stripTypes(code);
1775
+ }
1776
+ function generateBundleCode(config) {
1777
+ const {
1778
+ name,
1779
+ commands,
1780
+ blocks = [],
1781
+ htmxIntegration = false,
1782
+ globalName = "hyperfixi",
1783
+ positionalExpressions = false,
1784
+ autoInit = true,
1785
+ esModule = true,
1786
+ parserType = "hybrid"
1787
+ } = config;
1788
+ const needsStyleHelpers = commands.some((cmd) => import_bundle_generator.STYLE_COMMANDS.includes(cmd));
1789
+ const needsElementArrayHelper = commands.some((cmd) => import_bundle_generator.ELEMENT_ARRAY_COMMANDS.includes(cmd));
1790
+ const needsMorphlex = commands.some((cmd) => import_bundle_generator.MORPH_COMMANDS.includes(cmd));
1791
+ const hasBlocks = blocks.length > 0;
1792
+ const hasReturn = commands.includes("return");
1793
+ const commandCases = commands.filter((cmd) => COMMAND_IMPLEMENTATIONS[cmd]).map((cmd) => COMMAND_IMPLEMENTATIONS[cmd]).join("\n");
1794
+ const blockCases = blocks.filter((block) => BLOCK_IMPLEMENTATIONS[block]).map((block) => BLOCK_IMPLEMENTATIONS[block]).join("\n");
1795
+ const parserTemplate = parserType === "lite" ? import_bundle_generator.LITE_PARSER_TEMPLATE : import_bundle_generator.HYBRID_PARSER_TEMPLATE;
1796
+ const morphlexImport = needsMorphlex ? `import { morph as morphlexMorph, morphInner as morphlexMorphInner } from 'morphlex';
1797
+
1798
+ ` : "";
1799
+ return `/**
1800
+ * LokaScript ${name} Bundle (Auto-Generated)
1801
+ *
1802
+ * Generated by: @hyperfixi/vite-plugin
1803
+ * Parser: ${parserType}
1804
+ * Commands: ${commands.join(", ")}${blocks.length > 0 ? `
1805
+ * Blocks: ${blocks.join(", ")}` : ""}${positionalExpressions ? "\n * Positional expressions: enabled" : ""}${needsMorphlex ? "\n * Morphing: morphlex (~2.5KB)" : ""}
1806
+ *
1807
+ * DO NOT EDIT - This file is automatically regenerated.
1808
+ */
1809
+
1810
+ ${morphlexImport}// Embedded ${parserType} parser (no external dependencies)
1811
+ ${parserTemplate}
1812
+
1813
+ // Runtime state
1814
+ const globalVars = new Map();
1815
+ ${hasBlocks ? "const MAX_LOOP_ITERATIONS = 1000;" : ""}
1816
+
1817
+ async function evaluate(node, ctx) {
1818
+ switch (node.type) {
1819
+ case 'literal': return node.value;
1820
+
1821
+ case 'identifier':
1822
+ if (node.value === 'me' || node.value === 'my') return ctx.me;
1823
+ if (node.value === 'it') return ctx.it;
1824
+ if (node.value === 'you') return ctx.you;
1825
+ if (node.value === 'event') return ctx.event;
1826
+ if (node.value === 'body') return document.body;
1827
+ if (node.value === 'document') return document;
1828
+ if (node.value === 'window') return window;
1829
+ if (ctx.locals.has(node.value)) return ctx.locals.get(node.value);
1830
+ if (node.value in ctx.me) return ctx.me[node.value];
1831
+ return node.value;
1832
+
1833
+ case 'contextReference':
1834
+ // Semantic AST format for context references (me, you, it, etc.)
1835
+ switch (node.contextType || node.name) {
1836
+ case 'me': return ctx.me;
1837
+ case 'it': return ctx.it;
1838
+ case 'you': return ctx.you;
1839
+ case 'event': return ctx.event;
1840
+ case 'body': return document.body;
1841
+ case 'document': return document;
1842
+ case 'window': return window;
1843
+ default: return ctx.me;
1844
+ }
1845
+
1846
+ case 'variable':
1847
+ if (node.scope === 'local') return ctx.locals.get(node.name.slice(1));
1848
+ const gName = node.name.slice(1);
1849
+ if (globalVars.has(gName)) return globalVars.get(gName);
1850
+ return window[node.name];
1851
+
1852
+ case 'selector':
1853
+ const elements = document.querySelectorAll(node.value);
1854
+ return elements.length === 1 ? elements[0] : Array.from(elements);
1855
+
1856
+ case 'binary':
1857
+ return evaluateBinary(node, ctx);
1858
+
1859
+ case 'possessive':
1860
+ case 'member':
1861
+ const obj = await evaluate(node.object, ctx);
1862
+ if (obj == null) return undefined;
1863
+ const prop = node.computed ? await evaluate(node.property, ctx) : node.property;
1864
+ return obj[prop];
1865
+
1866
+ case 'call': {
1867
+ let callContext = null;
1868
+ let callee;
1869
+
1870
+ if (node.callee.type === 'member' || node.callee.type === 'possessive') {
1871
+ callContext = await evaluate(node.callee.object, ctx);
1872
+ const p = node.callee.computed
1873
+ ? await evaluate(node.callee.property, ctx)
1874
+ : node.callee.property;
1875
+ callee = callContext?.[p];
1876
+ } else {
1877
+ callee = await evaluate(node.callee, ctx);
1878
+ }
1879
+
1880
+ const args = await Promise.all(node.args.map(a => evaluate(a, ctx)));
1881
+ if (typeof callee === 'function') return callee.apply(callContext, args);
1882
+ return undefined;
1883
+ }
1884
+ ${positionalExpressions ? `
1885
+ case 'positional':
1886
+ return evaluatePositional(node, ctx);
1887
+ ` : ""}
1888
+ default: return undefined;
1889
+ }
1890
+ }
1891
+
1892
+ async function evaluateBinary(node, ctx) {
1893
+ if (node.operator === 'has') {
1894
+ const left = await evaluate(node.left, ctx);
1895
+ if (left instanceof Element && node.right.type === 'selector' && node.right.value.startsWith('.')) {
1896
+ return left.classList.contains(node.right.value.slice(1));
1897
+ }
1898
+ return false;
1899
+ }
1900
+
1901
+ const left = await evaluate(node.left, ctx);
1902
+ const right = await evaluate(node.right, ctx);
1903
+
1904
+ switch (node.operator) {
1905
+ case '+': return left + right;
1906
+ case '-': return left - right;
1907
+ case '*': return left * right;
1908
+ case '/': return left / right;
1909
+ case '%': return left % right;
1910
+ case '==': case 'is': return left == right;
1911
+ case '!=': case 'is not': return left != right;
1912
+ case '<': return left < right;
1913
+ case '>': return left > right;
1914
+ case '<=': return left <= right;
1915
+ case '>=': return left >= right;
1916
+ case 'and': case '&&': return left && right;
1917
+ case 'or': case '||': return left || right;
1918
+ case 'contains': case 'includes':
1919
+ if (typeof left === 'string') return left.includes(right);
1920
+ if (Array.isArray(left)) return left.includes(right);
1921
+ if (left instanceof Element) return left.contains(right);
1922
+ return false;
1923
+ case 'matches':
1924
+ if (left instanceof Element) return left.matches(right);
1925
+ if (typeof left === 'string') return new RegExp(right).test(left);
1926
+ return false;
1927
+ default: return undefined;
1928
+ }
1929
+ }
1930
+ ${positionalExpressions ? `
1931
+ function evaluatePositional(node, ctx) {
1932
+ const target = node.target;
1933
+ let elements = [];
1934
+
1935
+ let selector = null;
1936
+ if (target.type === 'selector') {
1937
+ selector = target.value;
1938
+ } else if (target.type === 'identifier') {
1939
+ selector = target.value;
1940
+ } else if (target.type === 'htmlSelector') {
1941
+ selector = target.value;
1942
+ }
1943
+ if (selector) {
1944
+ elements = Array.from(document.querySelectorAll(selector));
1945
+ }
1946
+
1947
+ switch (node.position) {
1948
+ case 'first': return elements[0] || null;
1949
+ case 'last': return elements[elements.length - 1] || null;
1950
+ case 'next': return ctx.me.nextElementSibling;
1951
+ case 'previous': return ctx.me.previousElementSibling;
1952
+ case 'closest': return target.value ? ctx.me.closest(target.value) : null;
1953
+ case 'parent': return ctx.me.parentElement;
1954
+ default: return elements[0] || null;
1955
+ }
1956
+ }
1957
+ ` : ""}
1958
+ ${needsStyleHelpers ? `
1959
+ const isStyleProp = (prop) => prop?.startsWith('*');
1960
+ const getStyleName = (prop) => prop.substring(1);
1961
+ const setStyleProp = (el, prop, value) => {
1962
+ if (!isStyleProp(prop)) return false;
1963
+ el.style.setProperty(getStyleName(prop), String(value));
1964
+ return true;
1965
+ };
1966
+ ` : ""}
1967
+
1968
+ ${needsElementArrayHelper ? `
1969
+ const toElementArray = (val) => {
1970
+ if (Array.isArray(val)) return val.filter(e => e instanceof Element);
1971
+ if (val instanceof Element) return [val];
1972
+ if (typeof val === 'string') return Array.from(document.querySelectorAll(val));
1973
+ return [];
1974
+ };
1975
+ ` : ""}
1976
+
1977
+ async function executeCommand(cmd, ctx) {
1978
+ const getTarget = async () => {
1979
+ // Support both HybridParser (cmd.target) and semantic AST (cmd.modifiers.on) formats
1980
+ const target = cmd.target || cmd.modifiers?.on;
1981
+ if (!target) return [ctx.me];
1982
+ const t = await evaluate(target, ctx);
1983
+ if (Array.isArray(t)) return t;
1984
+ if (t instanceof Element) return [t];
1985
+ if (typeof t === 'string') return Array.from(document.querySelectorAll(t));
1986
+ return [ctx.me];
1987
+ };
1988
+
1989
+ const getClassName = (node) => {
1990
+ if (!node) return '';
1991
+ if (node.type === 'selector') return node.value.slice(1);
1992
+ if (node.type === 'string' || node.type === 'literal') {
1993
+ const val = node.value;
1994
+ return typeof val === 'string' && val.startsWith('.') ? val.slice(1) : String(val);
1995
+ }
1996
+ if (node.type === 'identifier') return node.value;
1997
+ return '';
1998
+ };
1999
+
2000
+ switch (cmd.name) {
2001
+ ${commandCases}
2002
+
2003
+ default:
2004
+ console.warn(\`${name} bundle: Unknown command '\${cmd.name}'\`);
2005
+ return null;
2006
+ }
2007
+ }
2008
+ ${hasBlocks ? `
2009
+ async function executeBlock(block, ctx) {
2010
+ switch (block.type) {
2011
+ ${blockCases}
2012
+
2013
+ default:
2014
+ console.warn(\`${name} bundle: Unknown block '\${block.type}'\`);
2015
+ return null;
2016
+ }
2017
+ }
2018
+ ` : ""}
2019
+ async function executeSequence(nodes, ctx) {
2020
+ let result;
2021
+ for (const node of nodes) {
2022
+ if (node.type === 'command') {
2023
+ result = await executeCommand(node, ctx);
2024
+ }${hasBlocks ? ` else if (['if', 'repeat', 'for', 'while', 'fetch'].includes(node.type)) {
2025
+ result = await executeBlock(node, ctx);
2026
+ }` : ""}
2027
+ }
2028
+ return result;
2029
+ }
2030
+ ${hasBlocks ? `
2031
+ async function executeSequenceWithBlocks(nodes, ctx) {
2032
+ try {
2033
+ return await executeSequence(nodes, ctx);
2034
+ } catch (e) {
2035
+ if (e?.type === 'return') throw e;
2036
+ throw e;
2037
+ }
2038
+ }
2039
+ ` : ""}
2040
+ async function executeAST(ast, me, event) {
2041
+ const ctx = { me, event, locals: new Map() };
2042
+
2043
+ if (ast.type === 'sequence') {
2044
+ ${hasReturn || hasBlocks ? "try { return await executeSequence(ast.commands, ctx); } catch (e) { if (e?.type === 'return') return e.value; throw e; }" : "return executeSequence(ast.commands, ctx);"}
2045
+ }
2046
+
2047
+ if (ast.type === 'event') {
2048
+ const eventNode = ast;
2049
+ const eventName = eventNode.event;
2050
+
2051
+ if (eventName === 'init') {
2052
+ ${hasReturn || hasBlocks ? "try { await executeSequence(eventNode.body, ctx); } catch (e) { if (e?.type !== 'return') throw e; }" : "await executeSequence(eventNode.body, ctx);"}
2053
+ return;
2054
+ }
2055
+
2056
+ const target = eventNode.filter ? await evaluate(eventNode.filter, ctx) : me;
2057
+ const targetEl = target instanceof Element ? target : me;
2058
+ const mods = eventNode.modifiers;
2059
+
2060
+ let handler = async (e) => {
2061
+ if (mods.prevent) e.preventDefault();
2062
+ if (mods.stop) e.stopPropagation();
2063
+
2064
+ const handlerCtx = {
2065
+ me, event: e,
2066
+ you: e.target instanceof Element ? e.target : undefined,
2067
+ locals: new Map(),
2068
+ };
2069
+ ${hasReturn || hasBlocks ? "try { await executeSequence(eventNode.body, handlerCtx); } catch (err) { if (err?.type !== 'return') throw err; }" : "await executeSequence(eventNode.body, handlerCtx);"}
2070
+ };
2071
+
2072
+ if (mods.debounce) {
2073
+ let timeout;
2074
+ const orig = handler;
2075
+ handler = async (e) => {
2076
+ clearTimeout(timeout);
2077
+ timeout = setTimeout(() => orig(e), mods.debounce);
2078
+ };
2079
+ }
2080
+
2081
+ if (mods.throttle) {
2082
+ let lastCall = 0;
2083
+ const orig = handler;
2084
+ handler = async (e) => {
2085
+ const now = Date.now();
2086
+ if (now - lastCall >= mods.throttle) {
2087
+ lastCall = now;
2088
+ await orig(e);
2089
+ }
2090
+ };
2091
+ }
2092
+
2093
+ targetEl.addEventListener(eventName, handler, { once: !!mods.once });
2094
+ return;
2095
+ }
2096
+
2097
+ // Handle single command (not wrapped in event or sequence)
2098
+ if (ast.type === 'command') {
2099
+ return executeCommand(ast, ctx);
2100
+ }
2101
+
2102
+ return null;
2103
+ }
2104
+
2105
+ function processElement(el) {
2106
+ const code = el.getAttribute('_');
2107
+ if (!code) return;
2108
+
2109
+ try {
2110
+ const ast = ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2111
+ executeAST(ast, el);
2112
+ } catch (err) {
2113
+ console.error('LokaScript ${name} error:', err, 'Code:', code);
2114
+ }
2115
+ }
2116
+
2117
+ function processElements(root = document) {
2118
+ const elements = root.querySelectorAll('[_]');
2119
+ elements.forEach(processElement);
2120
+ }
2121
+
2122
+ const api = {
2123
+ version: '1.0.0-${name.toLowerCase().replace(/\s+/g, "-")}',
2124
+
2125
+ parse(code) {
2126
+ return ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2127
+ },
2128
+
2129
+ async execute(code, element) {
2130
+ const me = element || document.body;
2131
+ const ast = ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2132
+ return executeAST(ast, me);
2133
+ },
2134
+
2135
+ run: async (code, element) => api.execute(code, element),
2136
+ eval: async (code, element) => api.execute(code, element),
2137
+
2138
+ init: processElements,
2139
+ process: processElements,
2140
+
2141
+ commands: ${JSON.stringify(commands)},
2142
+ ${blocks.length > 0 ? `blocks: ${JSON.stringify(blocks)},` : ""}
2143
+ parserName: '${parserType}',
2144
+ };
2145
+ ${autoInit ? `
2146
+ if (typeof window !== 'undefined') {
2147
+ window.${globalName} = api;
2148
+ window._hyperscript = api;
2149
+
2150
+ if (document.readyState === 'loading') {
2151
+ document.addEventListener('DOMContentLoaded', () => processElements());
2152
+ } else {
2153
+ processElements();
2154
+ }
2155
+ ${htmxIntegration ? `
2156
+ document.addEventListener('htmx:afterSettle', (e) => {
2157
+ const target = e.detail?.target;
2158
+ if (target) processElements(target);
2159
+ });
2160
+ ` : ""}
2161
+ }
2162
+ ` : ""}
2163
+ ${esModule ? `
2164
+ export default api;
2165
+ export { api, processElements };
2166
+ ` : ""}`;
2167
+ }
2168
+ var Generator = class {
2169
+ constructor(options) {
2170
+ this.debug = options.debug ?? false;
2171
+ }
2172
+ /**
2173
+ * Generate bundle code from aggregated usage
2174
+ */
2175
+ generate(usage, options) {
2176
+ const commands = [...usage.commands, ...options.extraCommands ?? []];
2177
+ const blocks = [...usage.blocks, ...options.extraBlocks ?? []];
2178
+ const positional = usage.positional || options.positional || false;
2179
+ const semanticConfig = resolveSemanticConfig(options, usage.detectedLanguages);
2180
+ if (commands.length === 0 && blocks.length === 0 && !positional && !semanticConfig.enabled) {
2181
+ return this.generateEmptyBundle(options);
2182
+ }
2183
+ const unsupportedCommands = this.getUnsupportedCommands(commands);
2184
+ if (unsupportedCommands.length > 0) {
2185
+ if (this.debug) {
2186
+ console.log(
2187
+ `[hyperfixi] Commands detected that require full runtime: ${unsupportedCommands.join(", ")}
2188
+ Falling back to full browser bundle for complete functionality.`
2189
+ );
2190
+ }
2191
+ return this.generateDevFallback("full");
2192
+ }
2193
+ const parserType = (0, import_bundle_generator.canUseLiteParser)(commands, blocks, positional) ? "lite" : "hybrid";
2194
+ const config = {
2195
+ name: options.bundleName ?? "ViteAutoGenerated",
2196
+ commands,
2197
+ blocks,
2198
+ positionalExpressions: positional,
2199
+ htmxIntegration: options.htmx ?? usage.htmx?.hasHtmxAttributes ?? false,
2200
+ globalName: options.globalName ?? "hyperfixi",
2201
+ parserType,
2202
+ autoInit: true,
2203
+ esModule: true
2204
+ };
2205
+ if (this.debug) {
2206
+ const bundleInfo = {
2207
+ commands,
2208
+ blocks,
2209
+ positional,
2210
+ htmx: config.htmxIntegration,
2211
+ semantic: semanticConfig.enabled,
2212
+ parserType
2213
+ };
2214
+ if (semanticConfig.enabled && semanticConfig.bundleType) {
2215
+ const sizeInfo = getSemanticBundleSize(semanticConfig.bundleType);
2216
+ bundleInfo.semanticBundle = semanticConfig.bundleType;
2217
+ bundleInfo.semanticSize = sizeInfo.gzip;
2218
+ bundleInfo.languages = [...semanticConfig.languages];
2219
+ bundleInfo.grammar = semanticConfig.grammarEnabled;
2220
+ }
2221
+ console.log("[hyperfixi] Generating bundle:", bundleInfo);
2222
+ if (semanticConfig.bundleType === "all" || semanticConfig.bundleType === "priority") {
2223
+ console.log(
2224
+ `[hyperfixi] Note: Using '${semanticConfig.bundleType}' semantic bundle (${getSemanticBundleSize(semanticConfig.bundleType).gzip}). Consider using 'region' option to select a smaller regional bundle if all languages aren't needed.`
2225
+ );
2226
+ }
2227
+ }
2228
+ let bundleCode = generateBundleCode(config);
2229
+ if (semanticConfig.enabled) {
2230
+ bundleCode = this.addSemanticIntegration(bundleCode, semanticConfig);
2231
+ }
2232
+ return bundleCode;
2233
+ }
2234
+ /**
2235
+ * Add semantic integration code to the bundle
2236
+ */
2237
+ addSemanticIntegration(bundleCode, config) {
2238
+ const semanticCode = generateSemanticIntegrationCode(config);
2239
+ const semanticExports = getSemanticExports(config);
2240
+ const parserImportEnd = bundleCode.indexOf("// Runtime state");
2241
+ if (parserImportEnd === -1) {
2242
+ bundleCode = semanticCode + "\n" + bundleCode;
2243
+ } else {
2244
+ bundleCode = bundleCode.slice(0, parserImportEnd) + semanticCode + "\n\n" + bundleCode.slice(parserImportEnd);
2245
+ }
2246
+ bundleCode = bundleCode.replace(
2247
+ /function processElement\(el\) \{\s*const code = el\.getAttribute\('_'\);\s*if \(!code\) return;\s*try \{\s*const ast = (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2248
+ `function processElement(el) {
2249
+ const code = el.getAttribute('_');
2250
+ if (!code) return;
2251
+
2252
+ try {
2253
+ const ast = parseWithSemantic(code);`
2254
+ );
2255
+ bundleCode = bundleCode.replace(
2256
+ /parse\(code\) \{\s*return (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2257
+ `parse(code, lang = null) {
2258
+ return parseWithSemantic(code, lang);`
2259
+ );
2260
+ bundleCode = bundleCode.replace(
2261
+ /async execute\(code, element\) \{\s*const me = element \|\| document\.body;\s*const ast = (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2262
+ `async execute(code, element, lang = null) {
2263
+ const me = element || document.body;
2264
+ const ast = parseWithSemantic(code, lang);`
2265
+ );
2266
+ if (semanticExports.length > 0) {
2267
+ const apiExportsMarkerRegex = /parserName: '(?:lite|hybrid)',/;
2268
+ const additionalApiProps = semanticExports.map((exp) => ` ${exp},`).join("\n");
2269
+ bundleCode = bundleCode.replace(
2270
+ apiExportsMarkerRegex,
2271
+ `parserName: 'semantic',
2272
+ ${additionalApiProps}`
2273
+ );
2274
+ }
2275
+ return bundleCode;
2276
+ }
2277
+ /**
2278
+ * Get commands that require the full runtime and are not available in generated bundles
2279
+ */
2280
+ getUnsupportedCommands(commands) {
2281
+ const unsupported = [];
2282
+ for (const cmd of commands) {
2283
+ if (import_bundle_generator.FULL_RUNTIME_ONLY_COMMANDS.includes(cmd)) {
2284
+ unsupported.push(cmd);
2285
+ } else if (!(0, import_bundle_generator.isAvailableCommand)(cmd) && !COMMAND_IMPLEMENTATIONS[cmd]) {
2286
+ unsupported.push(cmd);
2287
+ }
2288
+ }
2289
+ return unsupported;
2290
+ }
2291
+ /**
2292
+ * Check if any commands require full runtime and should trigger fallback
2293
+ */
2294
+ requiresFullRuntime(commands) {
2295
+ return this.getUnsupportedCommands(commands).length > 0;
2296
+ }
2297
+ /**
2298
+ * Generate an empty bundle when no hyperscript is detected
2299
+ */
2300
+ generateEmptyBundle(options) {
2301
+ const globalName = options.globalName ?? "hyperfixi";
2302
+ return `/**
2303
+ * LokaScript Empty Bundle (Auto-Generated)
2304
+ *
2305
+ * No hyperscript usage detected. This bundle provides a minimal API.
2306
+ * Add hyperscript attributes (_="...") to your HTML to enable features.
2307
+ *
2308
+ * Generated by: @hyperfixi/vite-plugin
2309
+ */
2310
+
2311
+ const api = {
2312
+ version: '1.0.0-empty',
2313
+ commands: [],
2314
+ parserName: 'none',
2315
+
2316
+ parse() {
2317
+ console.warn('LokaScript: No parser loaded. Add hyperscript to your HTML to enable parsing.');
2318
+ return { type: 'empty' };
2319
+ },
2320
+
2321
+ async execute(code, element) {
2322
+ console.warn('LokaScript: No commands loaded. Detected commands will be automatically included.');
2323
+ return null;
2324
+ },
2325
+
2326
+ run: async (code, element) => api.execute(code, element),
2327
+ eval: async (code, element) => api.execute(code, element),
2328
+
2329
+ init() {},
2330
+ process() {},
2331
+ };
2332
+
2333
+ if (typeof window !== 'undefined') {
2334
+ (window).${globalName} = api;
2335
+ (window)._hyperscript = api;
2336
+ }
2337
+
2338
+ export default api;
2339
+ export { api };
2340
+ `;
2341
+ }
2342
+ /**
2343
+ * Generate a development fallback bundle
2344
+ */
2345
+ generateDevFallback(fallback) {
2346
+ const bundle = fallback === "full" ? "@hyperfixi/core/browser" : "@hyperfixi/core/browser/hybrid-complete";
2347
+ return `/**
2348
+ * LokaScript Dev Fallback Bundle
2349
+ *
2350
+ * Using pre-built ${fallback} bundle for faster development.
2351
+ * Production builds will generate minimal bundles.
2352
+ *
2353
+ * Generated by: @hyperfixi/vite-plugin
2354
+ */
2355
+
2356
+ export * from '${bundle}';
2357
+ export { default } from '${bundle}';
2358
+ `;
2359
+ }
2360
+ };
2361
+
2362
+ // src/compiler.ts
2363
+ var import_parser_core = require("@hyperfixi/core/parser/hybrid/parser-core");
2364
+ var semanticAnalyzer = null;
2365
+ var buildASTFn = null;
2366
+ function setSemanticParser(analyzer, buildAST) {
2367
+ semanticAnalyzer = analyzer;
2368
+ buildASTFn = buildAST;
2369
+ }
2370
+ function clearSemanticParser() {
2371
+ semanticAnalyzer = null;
2372
+ buildASTFn = null;
2373
+ }
2374
+ function hasSemanticParser() {
2375
+ return semanticAnalyzer !== null && buildASTFn !== null;
2376
+ }
2377
+ var SEMANTIC_CONFIDENCE_THRESHOLD = 0.7;
2378
+ var multilingualAliases = {};
2379
+ var multilingualRegex = null;
2380
+ function setMultilingualAliases(aliases) {
2381
+ multilingualAliases = { ...aliases };
2382
+ if (Object.keys(aliases).length > 0) {
2383
+ const escapedKeys = Object.keys(aliases).map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
2384
+ multilingualRegex = new RegExp(`(^|\\s)(${escapedKeys})(?=\\s|\\.|$)`, "g");
2385
+ } else {
2386
+ multilingualRegex = null;
2387
+ }
2388
+ }
2389
+ function preprocessMultilingual(code) {
2390
+ if (!multilingualRegex) return code;
2391
+ return code.replace(multilingualRegex, (match, prefix, keyword) => {
2392
+ const english = multilingualAliases[keyword];
2393
+ return english ? prefix + english : match;
2394
+ });
2395
+ }
2396
+ function sanitizeClassName(name) {
2397
+ if (!/^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(name)) {
2398
+ return null;
2399
+ }
2400
+ return name;
2401
+ }
2402
+ function sanitizeSelector(selector) {
2403
+ return selector.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\0/g, "");
2404
+ }
2405
+ function hashScript(script) {
2406
+ let hash = 5381;
2407
+ for (let i = 0; i < script.length; i++) {
2408
+ hash = (hash << 5) + hash ^ script.charCodeAt(i);
2409
+ }
2410
+ return Math.abs(hash).toString(36).slice(0, 4);
2411
+ }
2412
+ var usedIds = /* @__PURE__ */ new Set();
2413
+ function resetCompiler() {
2414
+ usedIds.clear();
2415
+ }
2416
+ function generateHandlerId(event, command, script) {
2417
+ const hash = hashScript(script);
2418
+ let id = `${event}_${command}_${hash}`;
2419
+ let suffix = 0;
2420
+ while (usedIds.has(id)) {
2421
+ id = `${event}_${command}_${hash}${suffix++}`;
2422
+ }
2423
+ usedIds.add(id);
2424
+ return id;
2425
+ }
2426
+ function compile(script, options = {}) {
2427
+ const { language = "en", debug = false } = options;
2428
+ try {
2429
+ let ast;
2430
+ if (language !== "en" && semanticAnalyzer && buildASTFn) {
2431
+ if (semanticAnalyzer.supportsLanguage(language)) {
2432
+ const result = semanticAnalyzer.analyze(script, language);
2433
+ if (result.node && result.confidence >= SEMANTIC_CONFIDENCE_THRESHOLD) {
2434
+ const { ast: builtAST, warnings } = buildASTFn(result.node);
2435
+ if (debug && warnings.length > 0) {
2436
+ console.log(`[hyperfixi] Semantic AST warnings for "${script}":`, warnings);
2437
+ }
2438
+ ast = builtAST;
2439
+ if (debug) {
2440
+ console.log(
2441
+ `[hyperfixi] Compiled ${language}: "${script}" (confidence: ${result.confidence.toFixed(2)})`
2442
+ );
2443
+ }
2444
+ } else {
2445
+ if (debug) {
2446
+ const reason = result.errors?.join(", ") || `low confidence (${result.confidence.toFixed(2)})`;
2447
+ console.log(`[hyperfixi] Semantic parse failed for "${script}": ${reason}`);
2448
+ }
2449
+ return null;
2450
+ }
2451
+ } else {
2452
+ if (debug) {
2453
+ console.log(`[hyperfixi] Language "${language}" not supported by semantic parser`);
2454
+ }
2455
+ return null;
2456
+ }
2457
+ } else if (language !== "en") {
2458
+ if (debug) {
2459
+ console.log(
2460
+ `[hyperfixi] Semantic parser not available for "${language}". Install @lokascript/semantic and call setSemanticParser().`
2461
+ );
2462
+ }
2463
+ return null;
2464
+ } else {
2465
+ const preprocessedScript = preprocessMultilingual(script);
2466
+ const parser = new import_parser_core.HybridParser(preprocessedScript);
2467
+ ast = parser.parse();
2468
+ }
2469
+ return compileAST(ast, script);
2470
+ } catch (error) {
2471
+ if (debug) {
2472
+ console.warn(`[hyperfixi] Failed to compile: ${script}`, error);
2473
+ }
2474
+ return null;
2475
+ }
2476
+ }
2477
+ function extractPrimaryCommand(body) {
2478
+ if (body.length === 0) return "handler";
2479
+ const first = body[0];
2480
+ if (first.type === "command") {
2481
+ return first.name || "cmd";
2482
+ }
2483
+ return first.type || "handler";
2484
+ }
2485
+ function compileAST(ast, original) {
2486
+ if (ast.type !== "event") {
2487
+ return null;
2488
+ }
2489
+ const eventNode = ast;
2490
+ const event = eventNode.event;
2491
+ const modifiers = eventNode.modifiers || {};
2492
+ const body = eventNode.body || [];
2493
+ const { code, needsEvaluator, needsLocals, needsGlobals } = compileBody(body);
2494
+ if (code === null || code === "") {
2495
+ return null;
2496
+ }
2497
+ const command = extractPrimaryCommand(body);
2498
+ const id = generateHandlerId(event, command, original);
2499
+ return {
2500
+ id,
2501
+ event,
2502
+ modifiers: {
2503
+ prevent: modifiers.prevent,
2504
+ stop: modifiers.stop,
2505
+ once: modifiers.once,
2506
+ debounce: modifiers.debounce,
2507
+ throttle: modifiers.throttle
2508
+ },
2509
+ code,
2510
+ needsEvaluator: needsEvaluator || needsLocals || needsGlobals,
2511
+ original
2512
+ };
2513
+ }
2514
+ function compileBody(nodes) {
2515
+ const statements = [];
2516
+ let needsEvaluator = false;
2517
+ let needsLocals = false;
2518
+ let needsGlobals = false;
2519
+ for (const node of nodes) {
2520
+ const result = compileNode(node);
2521
+ if (result === null) {
2522
+ return { code: null, needsEvaluator: false, needsLocals: false, needsGlobals: false };
2523
+ }
2524
+ statements.push(result.code);
2525
+ needsEvaluator = needsEvaluator || result.needsEvaluator;
2526
+ needsLocals = needsLocals || result.needsLocals;
2527
+ needsGlobals = needsGlobals || result.needsGlobals;
2528
+ }
2529
+ return {
2530
+ code: statements.join("\n"),
2531
+ needsEvaluator,
2532
+ needsLocals,
2533
+ needsGlobals
2534
+ };
2535
+ }
2536
+ function compileNode(node) {
2537
+ if (node.type === "command") {
2538
+ return compileCommand(node);
2539
+ }
2540
+ return null;
2541
+ }
2542
+ function compileCommand(cmd) {
2543
+ const target = cmd.target ? compileTarget(cmd.target) : "m";
2544
+ switch (cmd.name) {
2545
+ case "toggle":
2546
+ return compileToggle(cmd.args, target);
2547
+ case "add":
2548
+ return compileAdd(cmd.args, target);
2549
+ case "remove":
2550
+ return compileRemove(cmd.args, target);
2551
+ case "removeClass":
2552
+ return compileRemoveClass(cmd.args, target);
2553
+ case "show":
2554
+ return {
2555
+ code: `${target}.style.display = ''`,
2556
+ needsEvaluator: false,
2557
+ needsLocals: false,
2558
+ needsGlobals: false
2559
+ };
2560
+ case "hide":
2561
+ return {
2562
+ code: `${target}.style.display = 'none'`,
2563
+ needsEvaluator: false,
2564
+ needsLocals: false,
2565
+ needsGlobals: false
2566
+ };
2567
+ case "focus":
2568
+ return {
2569
+ code: `${target}.focus()`,
2570
+ needsEvaluator: false,
2571
+ needsLocals: false,
2572
+ needsGlobals: false
2573
+ };
2574
+ case "blur":
2575
+ return {
2576
+ code: `${target}.blur()`,
2577
+ needsEvaluator: false,
2578
+ needsLocals: false,
2579
+ needsGlobals: false
2580
+ };
2581
+ case "log":
2582
+ return compileLog(cmd.args);
2583
+ case "set":
2584
+ return compileSet(cmd.args);
2585
+ case "increment":
2586
+ return compileIncrement(cmd.args);
2587
+ case "decrement":
2588
+ return compileDecrement(cmd.args);
2589
+ case "put":
2590
+ return compilePut(cmd.args, target, cmd.modifier);
2591
+ case "send":
2592
+ case "trigger":
2593
+ return compileTrigger(cmd.args, target);
2594
+ case "wait":
2595
+ return compileWait(cmd.args);
2596
+ default:
2597
+ return null;
2598
+ }
2599
+ }
2600
+ function compileToggle(args, target) {
2601
+ const className = extractClassName(args[0]);
2602
+ if (!className) return null;
2603
+ if (target === "m") {
2604
+ return {
2605
+ code: `m.classList.toggle('${className}')`,
2606
+ needsEvaluator: false,
2607
+ needsLocals: false,
2608
+ needsGlobals: false
2609
+ };
2610
+ }
2611
+ return {
2612
+ code: `${target}.forEach(el => el.classList.toggle('${className}'))`,
2613
+ needsEvaluator: false,
2614
+ needsLocals: false,
2615
+ needsGlobals: false
2616
+ };
2617
+ }
2618
+ function compileAdd(args, target) {
2619
+ const className = extractClassName(args[0]);
2620
+ if (!className) return null;
2621
+ if (target === "m") {
2622
+ return {
2623
+ code: `m.classList.add('${className}')`,
2624
+ needsEvaluator: false,
2625
+ needsLocals: false,
2626
+ needsGlobals: false
2627
+ };
2628
+ }
2629
+ return {
2630
+ code: `${target}.forEach(el => el.classList.add('${className}'))`,
2631
+ needsEvaluator: false,
2632
+ needsLocals: false,
2633
+ needsGlobals: false
2634
+ };
2635
+ }
2636
+ function compileRemove(args, target) {
2637
+ if (!args || args.length === 0) {
2638
+ return {
2639
+ code: `${target}.remove()`,
2640
+ needsEvaluator: false,
2641
+ needsLocals: false,
2642
+ needsGlobals: false
2643
+ };
2644
+ }
2645
+ const className = extractClassName(args[0]);
2646
+ if (!className) return null;
2647
+ if (target === "m") {
2648
+ return {
2649
+ code: `m.classList.remove('${className}')`,
2650
+ needsEvaluator: false,
2651
+ needsLocals: false,
2652
+ needsGlobals: false
2653
+ };
2654
+ }
2655
+ return {
2656
+ code: `${target}.forEach(el => el.classList.remove('${className}'))`,
2657
+ needsEvaluator: false,
2658
+ needsLocals: false,
2659
+ needsGlobals: false
2660
+ };
2661
+ }
2662
+ function compileRemoveClass(args, target) {
2663
+ const className = extractClassName(args[0]);
2664
+ if (!className) return null;
2665
+ if (target === "m") {
2666
+ return {
2667
+ code: `m.classList.remove('${className}')`,
2668
+ needsEvaluator: false,
2669
+ needsLocals: false,
2670
+ needsGlobals: false
2671
+ };
2672
+ }
2673
+ return {
2674
+ code: `${target}.forEach(el => el.classList.remove('${className}'))`,
2675
+ needsEvaluator: false,
2676
+ needsLocals: false,
2677
+ needsGlobals: false
2678
+ };
2679
+ }
2680
+ function compileLog(args) {
2681
+ const compiled = args.map(compileExpression).filter(Boolean);
2682
+ if (compiled.length !== args.length) {
2683
+ return {
2684
+ code: `console.log(${compiled.join(", ")})`,
2685
+ needsEvaluator: true,
2686
+ needsLocals: false,
2687
+ needsGlobals: false
2688
+ };
2689
+ }
2690
+ return {
2691
+ code: `console.log(${compiled.join(", ")})`,
2692
+ needsEvaluator: false,
2693
+ needsLocals: false,
2694
+ needsGlobals: false
2695
+ };
2696
+ }
2697
+ function compileSet(args) {
2698
+ if (args.length < 2) return null;
2699
+ const [target, value] = args;
2700
+ const compiledValue = compileExpression(value);
2701
+ if (!compiledValue) return null;
2702
+ if (target.type === "variable") {
2703
+ const varNode = target;
2704
+ if (varNode.scope === "local") {
2705
+ const varName = varNode.name.slice(1);
2706
+ return {
2707
+ code: `L.${varName} = ${compiledValue}`,
2708
+ needsEvaluator: false,
2709
+ needsLocals: true,
2710
+ needsGlobals: false
2711
+ };
2712
+ }
2713
+ if (varNode.scope === "global") {
2714
+ const varName = varNode.name.slice(1);
2715
+ return {
2716
+ code: `G.${varName} = ${compiledValue}`,
2717
+ needsEvaluator: false,
2718
+ needsLocals: false,
2719
+ needsGlobals: true
2720
+ };
2721
+ }
2722
+ }
2723
+ if (target.type === "possessive") {
2724
+ const possNode = target;
2725
+ const obj = compileExpression(possNode.object);
2726
+ const prop = possNode.property;
2727
+ if (!obj) return null;
2728
+ if (prop.startsWith("*")) {
2729
+ const styleProp = prop.slice(1);
2730
+ return {
2731
+ code: `${obj}.style.${styleProp} = ${compiledValue}`,
2732
+ needsEvaluator: false,
2733
+ needsLocals: false,
2734
+ needsGlobals: false
2735
+ };
2736
+ }
2737
+ return {
2738
+ code: `${obj}.${prop} = ${compiledValue}`,
2739
+ needsEvaluator: false,
2740
+ needsLocals: false,
2741
+ needsGlobals: false
2742
+ };
2743
+ }
2744
+ if (target.type === "member") {
2745
+ const memNode = target;
2746
+ const obj = compileExpression(memNode.object);
2747
+ const prop = typeof memNode.property === "string" ? memNode.property : null;
2748
+ if (!obj || !prop) return null;
2749
+ if (prop.startsWith("*")) {
2750
+ const styleProp = prop.slice(1);
2751
+ return {
2752
+ code: `${obj}.style.${styleProp} = ${compiledValue}`,
2753
+ needsEvaluator: false,
2754
+ needsLocals: false,
2755
+ needsGlobals: false
2756
+ };
2757
+ }
2758
+ return {
2759
+ code: `${obj}.${prop} = ${compiledValue}`,
2760
+ needsEvaluator: false,
2761
+ needsLocals: false,
2762
+ needsGlobals: false
2763
+ };
2764
+ }
2765
+ return null;
2766
+ }
2767
+ function compileIncrement(args) {
2768
+ if (args.length < 1) return null;
2769
+ const target = args[0];
2770
+ const amount = args.length > 1 ? compileExpression(args[1]) : "1";
2771
+ if (target.type === "variable") {
2772
+ const varNode = target;
2773
+ if (varNode.scope === "local") {
2774
+ const varName = varNode.name.slice(1);
2775
+ return {
2776
+ code: `L.${varName} = (L.${varName} || 0) + ${amount}`,
2777
+ needsEvaluator: false,
2778
+ needsLocals: true,
2779
+ needsGlobals: false
2780
+ };
2781
+ }
2782
+ if (varNode.scope === "global") {
2783
+ const varName = varNode.name.slice(1);
2784
+ return {
2785
+ code: `G.${varName} = (G.${varName} || 0) + ${amount}`,
2786
+ needsEvaluator: false,
2787
+ needsLocals: false,
2788
+ needsGlobals: true
2789
+ };
2790
+ }
2791
+ }
2792
+ const compiled = compileExpression(target);
2793
+ if (compiled) {
2794
+ return {
2795
+ code: `${compiled}.textContent = (parseFloat(${compiled}.textContent) || 0) + ${amount}`,
2796
+ needsEvaluator: false,
2797
+ needsLocals: false,
2798
+ needsGlobals: false
2799
+ };
2800
+ }
2801
+ return null;
2802
+ }
2803
+ function compileDecrement(args) {
2804
+ if (args.length < 1) return null;
2805
+ const target = args[0];
2806
+ const amount = args.length > 1 ? compileExpression(args[1]) : "1";
2807
+ if (target.type === "variable") {
2808
+ const varNode = target;
2809
+ if (varNode.scope === "local") {
2810
+ const varName = varNode.name.slice(1);
2811
+ return {
2812
+ code: `L.${varName} = (L.${varName} || 0) - ${amount}`,
2813
+ needsEvaluator: false,
2814
+ needsLocals: true,
2815
+ needsGlobals: false
2816
+ };
2817
+ }
2818
+ if (varNode.scope === "global") {
2819
+ const varName = varNode.name.slice(1);
2820
+ return {
2821
+ code: `G.${varName} = (G.${varName} || 0) - ${amount}`,
2822
+ needsEvaluator: false,
2823
+ needsLocals: false,
2824
+ needsGlobals: true
2825
+ };
2826
+ }
2827
+ }
2828
+ const compiled = compileExpression(target);
2829
+ if (compiled) {
2830
+ return {
2831
+ code: `${compiled}.textContent = (parseFloat(${compiled}.textContent) || 0) - ${amount}`,
2832
+ needsEvaluator: false,
2833
+ needsLocals: false,
2834
+ needsGlobals: false
2835
+ };
2836
+ }
2837
+ return null;
2838
+ }
2839
+ function compilePut(args, target, modifier) {
2840
+ if (args.length < 1) return null;
2841
+ const content = compileExpression(args[0]);
2842
+ if (!content) return null;
2843
+ const mod = modifier || "into";
2844
+ switch (mod) {
2845
+ case "into":
2846
+ return {
2847
+ code: `${target}.innerHTML = ${content}`,
2848
+ needsEvaluator: false,
2849
+ needsLocals: false,
2850
+ needsGlobals: false
2851
+ };
2852
+ case "before":
2853
+ return {
2854
+ code: `${target}.insertAdjacentHTML('beforebegin', ${content})`,
2855
+ needsEvaluator: false,
2856
+ needsLocals: false,
2857
+ needsGlobals: false
2858
+ };
2859
+ case "after":
2860
+ return {
2861
+ code: `${target}.insertAdjacentHTML('afterend', ${content})`,
2862
+ needsEvaluator: false,
2863
+ needsLocals: false,
2864
+ needsGlobals: false
2865
+ };
2866
+ case "at start of":
2867
+ return {
2868
+ code: `${target}.insertAdjacentHTML('afterbegin', ${content})`,
2869
+ needsEvaluator: false,
2870
+ needsLocals: false,
2871
+ needsGlobals: false
2872
+ };
2873
+ case "at end of":
2874
+ return {
2875
+ code: `${target}.insertAdjacentHTML('beforeend', ${content})`,
2876
+ needsEvaluator: false,
2877
+ needsLocals: false,
2878
+ needsGlobals: false
2879
+ };
2880
+ default:
2881
+ return {
2882
+ code: `${target}.innerHTML = ${content}`,
2883
+ needsEvaluator: false,
2884
+ needsLocals: false,
2885
+ needsGlobals: false
2886
+ };
2887
+ }
2888
+ }
2889
+ function compileTrigger(args, target) {
2890
+ if (args.length < 1) return null;
2891
+ const eventName = compileExpression(args[0]);
2892
+ if (!eventName) return null;
2893
+ return {
2894
+ code: `${target}.dispatchEvent(new CustomEvent(${eventName}, { bubbles: true }))`,
2895
+ needsEvaluator: false,
2896
+ needsLocals: false,
2897
+ needsGlobals: false
2898
+ };
2899
+ }
2900
+ function compileWait(args) {
2901
+ if (args.length < 1) return null;
2902
+ const duration = compileExpression(args[0]);
2903
+ if (!duration) return null;
2904
+ return {
2905
+ code: `await new Promise(r => setTimeout(r, ${duration}))`,
2906
+ needsEvaluator: false,
2907
+ needsLocals: false,
2908
+ needsGlobals: false
2909
+ };
2910
+ }
2911
+ function compileExpression(node) {
2912
+ if (!node) return null;
2913
+ switch (node.type) {
2914
+ case "literal": {
2915
+ const litNode = node;
2916
+ return JSON.stringify(litNode.value);
2917
+ }
2918
+ case "identifier": {
2919
+ const idNode = node;
2920
+ const val = idNode.value;
2921
+ if (val === "me" || val === "my") return "m";
2922
+ if (val === "you") return "y";
2923
+ if (val === "it") return "it";
2924
+ if (val === "event") return "e";
2925
+ if (val === "body") return "document.body";
2926
+ if (val === "document") return "document";
2927
+ if (val === "window") return "window";
2928
+ return val;
2929
+ }
2930
+ case "variable": {
2931
+ const varNode = node;
2932
+ const name = varNode.name.slice(1);
2933
+ return varNode.scope === "local" ? `L.${name}` : `G.${name}`;
2934
+ }
2935
+ case "selector": {
2936
+ const selNode = node;
2937
+ const sanitized = sanitizeSelector(selNode.value);
2938
+ return `document.querySelector('${sanitized}')`;
2939
+ }
2940
+ case "possessive": {
2941
+ const possNode = node;
2942
+ const obj = compileExpression(possNode.object);
2943
+ const prop = possNode.property;
2944
+ if (!obj) return null;
2945
+ if (prop.startsWith("*")) {
2946
+ return `${obj}.style.${prop.slice(1)}`;
2947
+ }
2948
+ return `${obj}.${prop}`;
2949
+ }
2950
+ case "member": {
2951
+ const memNode = node;
2952
+ const obj = compileExpression(memNode.object);
2953
+ const prop = typeof memNode.property === "string" ? memNode.property : null;
2954
+ if (!obj || !prop) return null;
2955
+ if (prop.startsWith("*")) {
2956
+ return `${obj}.style.${prop.slice(1)}`;
2957
+ }
2958
+ return `${obj}.${prop}`;
2959
+ }
2960
+ case "binary": {
2961
+ const binNode = node;
2962
+ const left = compileExpression(binNode.left);
2963
+ const right = compileExpression(binNode.right);
2964
+ if (!left || !right) return null;
2965
+ const op = binNode.operator;
2966
+ switch (op) {
2967
+ case "+":
2968
+ case "-":
2969
+ case "*":
2970
+ case "/":
2971
+ case "%":
2972
+ return `(${left} ${op} ${right})`;
2973
+ case "==":
2974
+ case "is":
2975
+ return `(${left} == ${right})`;
2976
+ case "!=":
2977
+ case "is not":
2978
+ return `(${left} != ${right})`;
2979
+ case "<":
2980
+ case ">":
2981
+ case "<=":
2982
+ case ">=":
2983
+ return `(${left} ${op} ${right})`;
2984
+ case "and":
2985
+ case "&&":
2986
+ return `(${left} && ${right})`;
2987
+ case "or":
2988
+ case "||":
2989
+ return `(${left} || ${right})`;
2990
+ case "has": {
2991
+ const rightSel = binNode.right;
2992
+ const className = rightSel.value?.slice(1) || "";
2993
+ const sanitizedClass = sanitizeClassName(className);
2994
+ if (!sanitizedClass) return null;
2995
+ return `${left}.classList.contains('${sanitizedClass}')`;
2996
+ }
2997
+ default:
2998
+ return null;
2999
+ }
3000
+ }
3001
+ case "call": {
3002
+ const callNode = node;
3003
+ const callee = callNode.callee;
3004
+ const args = (callNode.args || []).map(compileExpression);
3005
+ if (args.some((a) => a === null)) return null;
3006
+ if (callee.type === "member" || callee.type === "possessive") {
3007
+ const memCallee = callee;
3008
+ const obj = compileExpression(memCallee.object);
3009
+ const prop = typeof memCallee.property === "string" ? memCallee.property : null;
3010
+ if (!obj || !prop) return null;
3011
+ return `${obj}.${prop}(${args.join(", ")})`;
3012
+ }
3013
+ const fn = compileExpression(callee);
3014
+ if (!fn) return null;
3015
+ return `${fn}(${args.join(", ")})`;
3016
+ }
3017
+ case "positional": {
3018
+ const posNode = node;
3019
+ const position = posNode.position;
3020
+ const target = posNode.target;
3021
+ switch (position) {
3022
+ case "first":
3023
+ if (target?.type === "selector") {
3024
+ const selNode = target;
3025
+ const sanitized = sanitizeSelector(selNode.value);
3026
+ return `document.querySelector('${sanitized}')`;
3027
+ }
3028
+ return null;
3029
+ // Arrays need runtime
3030
+ case "last":
3031
+ if (target?.type === "selector") {
3032
+ const selNode = target;
3033
+ const sanitized = sanitizeSelector(selNode.value);
3034
+ return `(()=>{const e=document.querySelectorAll('${sanitized}');return e[e.length-1]})()`;
3035
+ }
3036
+ return null;
3037
+ // Arrays need runtime
3038
+ case "next":
3039
+ return "m.nextElementSibling";
3040
+ case "previous":
3041
+ return "m.previousElementSibling";
3042
+ case "closest":
3043
+ if (target?.type === "selector") {
3044
+ const selNode = target;
3045
+ const sanitized = sanitizeSelector(selNode.value);
3046
+ return `m.closest('${sanitized}')`;
3047
+ }
3048
+ return null;
3049
+ case "parent":
3050
+ return "m.parentElement";
3051
+ default:
3052
+ return null;
3053
+ }
3054
+ }
3055
+ default:
3056
+ return null;
3057
+ }
3058
+ }
3059
+ function compileTarget(target) {
3060
+ if (target.type === "identifier") {
3061
+ const idNode = target;
3062
+ if (idNode.value === "me" || idNode.value === "my") return "m";
3063
+ if (idNode.value === "you") return "y";
3064
+ }
3065
+ if (target.type === "selector") {
3066
+ const selNode = target;
3067
+ const sanitized = sanitizeSelector(selNode.value);
3068
+ return `document.querySelectorAll('${sanitized}')`;
3069
+ }
3070
+ const compiled = compileExpression(target);
3071
+ return compiled || "m";
3072
+ }
3073
+ function extractClassName(node) {
3074
+ if (!node) return null;
3075
+ if (node.type === "selector") {
3076
+ const selNode = node;
3077
+ const val = selNode.value;
3078
+ const rawClass = val.startsWith(".") ? val.slice(1) : val;
3079
+ return sanitizeClassName(rawClass);
3080
+ }
3081
+ if (node.type === "literal" || node.type === "string") {
3082
+ const litNode = node;
3083
+ const val = litNode.value;
3084
+ if (typeof val === "string") {
3085
+ const rawClass = val.startsWith(".") ? val.slice(1) : val;
3086
+ return sanitizeClassName(rawClass);
3087
+ }
3088
+ }
3089
+ if (node.type === "identifier") {
3090
+ const idNode = node;
3091
+ return sanitizeClassName(idNode.value);
3092
+ }
3093
+ return null;
3094
+ }
3095
+
3096
+ // src/compiled-generator.ts
3097
+ function generateSourceMapTable(handlers) {
3098
+ if (handlers.length === 0) return "";
3099
+ const lines = [
3100
+ " *",
3101
+ " * Handler Source Map:",
3102
+ " * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"
3103
+ ];
3104
+ for (const h of handlers) {
3105
+ const original = h.original.replace(/\n/g, " ").slice(0, 40);
3106
+ const truncated = original.length < h.original.length ? original + "..." : original;
3107
+ lines.push(` * \u2502 ${h.id.padEnd(20)} \u2190 ${truncated.padEnd(40)} \u2502`);
3108
+ }
3109
+ lines.push(" * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
3110
+ lines.push(" *");
3111
+ return lines.join("\n");
3112
+ }
3113
+ function generateCompiledBundle(options) {
3114
+ const {
3115
+ handlers,
3116
+ needsLocals,
3117
+ needsGlobals,
3118
+ globalName = "hyperfixi",
3119
+ htmx = false,
3120
+ debug = false
3121
+ } = options;
3122
+ const handlerEntries = handlers.map((h) => {
3123
+ const isAsync = h.code.includes("await");
3124
+ const fn = isAsync ? `async(m,e,y)=>{${h.code}}` : `(m,e,y)=>{${h.code}}`;
3125
+ if (debug) {
3126
+ const escapedOriginal = h.original.replace(/\*/g, "\\*").replace(/\n/g, " ");
3127
+ return `
3128
+ /* ${escapedOriginal} */
3129
+ ${h.id}:${fn}`;
3130
+ }
3131
+ return `${h.id}:${fn}`;
3132
+ });
3133
+ const registrations = handlers.map((h) => {
3134
+ const modsCode = generateModifiersCode(h);
3135
+ return ` case '${h.id}': r(el,'${h.event}',H.${h.id}${modsCode}); break;`;
3136
+ });
3137
+ const localsCode = needsLocals ? "const L={};" : "";
3138
+ const globalsCode = needsGlobals ? "const G={};" : "";
3139
+ const sourceMapTable = debug ? generateSourceMapTable(handlers) : "";
3140
+ return `/**
3141
+ * HyperFixi Compiled Bundle (Auto-Generated)
3142
+ *
3143
+ * Pre-compiled hyperscript - no runtime parser needed!
3144
+ * Handlers: ${handlers.length}
3145
+ *
3146
+ * DO NOT EDIT - Regenerate with build.
3147
+ ${sourceMapTable} */
3148
+
3149
+ ${localsCode}${globalsCode}
3150
+ const H={${handlerEntries.join(",")}};
3151
+
3152
+ function r(el,ev,fn${hasModifiers(handlers) ? ",m" : ""}){
3153
+ let h=e=>fn(el,e,e.target);
3154
+ ${generateModifierWrappers(handlers)}
3155
+ el.addEventListener(ev,h${hasOnce(handlers) ? ",{once:m?.o}" : ""});
3156
+ }
3157
+
3158
+ function init(root=document){
3159
+ root.querySelectorAll('[data-h]').forEach(el=>{
3160
+ switch(el.dataset.h){
3161
+ ${registrations.join("\n")}
3162
+ }
3163
+ });
3164
+ }
3165
+
3166
+ ${htmx ? `document.addEventListener('htmx:afterSettle',e=>init(e.detail?.target));` : ""}
3167
+
3168
+ const api={
3169
+ version:'1.0.0-compiled',
3170
+ commands:${JSON.stringify(handlers.map((h) => h.id))},
3171
+ init,
3172
+ process:init,
3173
+ };
3174
+
3175
+ if(typeof window!=='undefined'){
3176
+ window.${globalName}=api;
3177
+ window._hyperscript=api;
3178
+ document.readyState==='loading'
3179
+ ?document.addEventListener('DOMContentLoaded',()=>init())
3180
+ :init();
3181
+ }
3182
+
3183
+ export default api;
3184
+ export{api,init};
3185
+ `;
3186
+ }
3187
+ function generateModifiersCode(h) {
3188
+ const mods = [];
3189
+ if (h.modifiers.prevent) mods.push("p:1");
3190
+ if (h.modifiers.stop) mods.push("s:1");
3191
+ if (h.modifiers.once) mods.push("o:1");
3192
+ if (h.modifiers.debounce) mods.push(`d:${h.modifiers.debounce}`);
3193
+ if (h.modifiers.throttle) mods.push(`t:${h.modifiers.throttle}`);
3194
+ if (mods.length === 0) return "";
3195
+ return `,{${mods.join(",")}}`;
3196
+ }
3197
+ function hasModifiers(handlers) {
3198
+ return handlers.some(
3199
+ (h) => h.modifiers.prevent || h.modifiers.stop || h.modifiers.once || h.modifiers.debounce || h.modifiers.throttle
3200
+ );
3201
+ }
3202
+ function hasOnce(handlers) {
3203
+ return handlers.some((h) => h.modifiers.once);
3204
+ }
3205
+ function generateModifierWrappers(handlers) {
3206
+ const lines = [];
3207
+ if (handlers.some((h) => h.modifiers.prevent || h.modifiers.stop)) {
3208
+ lines.push(
3209
+ ` if(m?.p||m?.s){const _h=h;h=e=>{m.p&&e.preventDefault();m.s&&e.stopPropagation();_h(e.currentTarget,e,e.target)};}`
3210
+ );
3211
+ }
3212
+ if (handlers.some((h) => h.modifiers.debounce)) {
3213
+ lines.push(
3214
+ ` if(m?.d){let t;const _h=h;h=e=>{clearTimeout(t);t=setTimeout(()=>_h(e.currentTarget,e,e.target),m.d)};}`
3215
+ );
3216
+ }
3217
+ if (handlers.some((h) => h.modifiers.throttle)) {
3218
+ lines.push(
3219
+ ` if(m?.t){let l=0;const _h=h;h=e=>{const n=Date.now();if(n-l>=m.t){l=n;_h(e.currentTarget,e,e.target)}};}`
3220
+ );
3221
+ }
3222
+ return lines.join("\n");
3223
+ }
3224
+
3225
+ // src/html-transformer.ts
3226
+ function transformHTML(html, handlerMap, fallbackScripts) {
3227
+ let modified = false;
3228
+ const fallbacks = [];
3229
+ const patterns = [
3230
+ /(\s)_\s*=\s*"([^"]+)"/g,
3231
+ // _="..."
3232
+ /(\s)_\s*=\s*'([^']+)'/g,
3233
+ // _='...'
3234
+ /(\s)_\s*=\s*`([^`]+)`/g
3235
+ // _=`...`
3236
+ ];
3237
+ let result = html;
3238
+ for (const pattern of patterns) {
3239
+ result = result.replace(pattern, (match, whitespace, script) => {
3240
+ const handlerId = handlerMap.get(script);
3241
+ if (handlerId) {
3242
+ modified = true;
3243
+ return `${whitespace}data-h="${handlerId}"`;
3244
+ }
3245
+ if (fallbackScripts.has(script)) {
3246
+ fallbacks.push(script);
3247
+ return match;
3248
+ }
3249
+ fallbacks.push(script);
3250
+ return match;
3251
+ });
3252
+ }
3253
+ return {
3254
+ code: result,
3255
+ modified,
3256
+ fallbacks
3257
+ };
3258
+ }
3259
+ function extractScripts(html) {
3260
+ const scripts = [];
3261
+ const patterns = [/_\s*=\s*"([^"]+)"/g, /_\s*=\s*'([^']+)'/g, /_\s*=\s*`([^`]+)`/g];
3262
+ for (const pattern of patterns) {
3263
+ let match;
3264
+ while (match = pattern.exec(html)) {
3265
+ scripts.push(match[1]);
3266
+ }
3267
+ }
3268
+ return scripts;
3269
+ }
3270
+
3271
+ // src/index.ts
3272
+ var VIRTUAL_MODULE_ID = "virtual:hyperfixi";
3273
+ var RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
3274
+ var IMPORT_ALIASES = ["hyperfixi", "@hyperfixi/core", "virtual:hyperfixi"];
3275
+ function hyperfixi(options = {}) {
3276
+ const mode = options.mode ?? "interpret";
3277
+ const scanner = new Scanner(options);
3278
+ const aggregator = new Aggregator();
3279
+ const generator = new Generator(options);
3280
+ let server = null;
3281
+ let cachedBundle = null;
3282
+ let lastUsageHash = "";
3283
+ let isDev = false;
3284
+ const compiledHandlers = [];
3285
+ const handlerMap = /* @__PURE__ */ new Map();
3286
+ const fallbackScripts = /* @__PURE__ */ new Set();
3287
+ let needsLocals = false;
3288
+ let needsGlobals = false;
3289
+ function computeUsageHash(usage) {
3290
+ const commands = [...usage.commands].sort().join(",");
3291
+ const blocks = [...usage.blocks].sort().join(",");
3292
+ const languages = [...usage.detectedLanguages].sort().join(",");
3293
+ return `${commands}|${blocks}|${usage.positional}|${languages}`;
3294
+ }
3295
+ function invalidateVirtualModule() {
3296
+ if (!server) return;
3297
+ const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);
3298
+ if (mod) {
3299
+ server.moduleGraph.invalidateModule(mod);
3300
+ server.ws.send({ type: "full-reload" });
3301
+ if (options.debug) {
3302
+ console.log("[hyperfixi] Virtual module invalidated, triggering reload");
3303
+ }
3304
+ }
3305
+ }
3306
+ function compileScript(script) {
3307
+ if (handlerMap.has(script)) {
3308
+ return handlerMap.get(script);
3309
+ }
3310
+ if (fallbackScripts.has(script)) {
3311
+ return null;
3312
+ }
3313
+ const handler = compile(script);
3314
+ if (handler) {
3315
+ compiledHandlers.push(handler);
3316
+ handlerMap.set(script, handler.id);
3317
+ if (handler.needsEvaluator) {
3318
+ if (handler.code.includes("L.")) needsLocals = true;
3319
+ if (handler.code.includes("G.")) needsGlobals = true;
3320
+ }
3321
+ if (options.debug) {
3322
+ console.log(`[hyperfixi] Compiled: "${script}" -> ${handler.id}`);
3323
+ }
3324
+ return handler.id;
3325
+ }
3326
+ fallbackScripts.add(script);
3327
+ if (options.debug) {
3328
+ console.log(`[hyperfixi] Fallback (not compilable): "${script}"`);
3329
+ }
3330
+ return null;
3331
+ }
3332
+ function generateInterpretBundle() {
3333
+ const usage = aggregator.getUsage();
3334
+ const usageHash = computeUsageHash(usage);
3335
+ if (cachedBundle && usageHash === lastUsageHash) {
3336
+ return cachedBundle;
3337
+ }
3338
+ if (isDev && options.devFallback && options.devFallback !== "auto") {
3339
+ cachedBundle = generator.generateDevFallback(options.devFallback);
3340
+ } else {
3341
+ cachedBundle = generator.generate(usage, options);
3342
+ }
3343
+ lastUsageHash = usageHash;
3344
+ if (options.debug) {
3345
+ const summary = aggregator.getSummary();
3346
+ console.log("[hyperfixi] Bundle generated:", summary);
3347
+ }
3348
+ return cachedBundle;
3349
+ }
3350
+ function generateCompiledBundleCode() {
3351
+ if (fallbackScripts.size > 0) {
3352
+ if (options.debug) {
3353
+ console.log(`[hyperfixi] ${fallbackScripts.size} scripts need interpreter fallback`);
3354
+ }
3355
+ return generateInterpretBundle();
3356
+ }
3357
+ const bundle = generateCompiledBundle({
3358
+ handlers: compiledHandlers,
3359
+ needsLocals,
3360
+ needsGlobals,
3361
+ globalName: options.globalName,
3362
+ htmx: options.htmx,
3363
+ debug: options.debug
3364
+ });
3365
+ if (options.debug) {
3366
+ console.log(`[hyperfixi] Compiled bundle: ${compiledHandlers.length} handlers`);
3367
+ }
3368
+ return bundle;
3369
+ }
3370
+ function generateBundle() {
3371
+ if (mode === "compile") {
3372
+ return generateCompiledBundleCode();
3373
+ }
3374
+ return generateInterpretBundle();
3375
+ }
3376
+ return {
3377
+ name: "vite-plugin-hyperfixi",
3378
+ enforce: "pre",
3379
+ /**
3380
+ * Configure plugin based on Vite mode
3381
+ */
3382
+ configResolved(config) {
3383
+ isDev = config.command === "serve";
3384
+ if (options.debug) {
3385
+ console.log("[hyperfixi] Plugin initialized, mode:", isDev ? "development" : "production");
3386
+ }
3387
+ },
3388
+ /**
3389
+ * Store server reference and pre-scan HTML files for HMR
3390
+ */
3391
+ async configureServer(_server) {
3392
+ server = _server;
3393
+ const cwd = _server.config.root;
3394
+ if (options.debug) {
3395
+ console.log("[hyperfixi] Pre-scanning project:", cwd);
3396
+ }
3397
+ const scannedFiles = await scanner.scanProject(cwd);
3398
+ aggregator.loadFromScan(scannedFiles);
3399
+ if (options.debug) {
3400
+ const summary = aggregator.getSummary();
3401
+ console.log("[hyperfixi] Pre-scan complete:", summary);
3402
+ }
3403
+ },
3404
+ /**
3405
+ * Resolve virtual module imports
3406
+ */
3407
+ resolveId(id) {
3408
+ if (IMPORT_ALIASES.includes(id)) {
3409
+ return RESOLVED_VIRTUAL_MODULE_ID;
3410
+ }
3411
+ return null;
3412
+ },
3413
+ /**
3414
+ * Load the virtual module with generated bundle
3415
+ */
3416
+ load(id) {
3417
+ if (id === RESOLVED_VIRTUAL_MODULE_ID) {
3418
+ return generateBundle();
3419
+ }
3420
+ return null;
3421
+ },
3422
+ /**
3423
+ * Scan files during transform for hyperscript usage
3424
+ */
3425
+ transform(code, id) {
3426
+ if (!scanner.shouldScan(id)) {
3427
+ return null;
3428
+ }
3429
+ if (mode === "compile" && !isDev) {
3430
+ const scripts = extractScripts(code);
3431
+ for (const script of scripts) {
3432
+ compileScript(script);
3433
+ }
3434
+ const result = transformHTML(code, handlerMap, fallbackScripts);
3435
+ if (result.modified) {
3436
+ if (options.debug) {
3437
+ console.log(`[hyperfixi] Transformed: ${id.split("/").pop()}`);
3438
+ }
3439
+ return { code: result.code, map: null };
3440
+ }
3441
+ return null;
3442
+ }
3443
+ const usage = scanner.scan(code, id);
3444
+ const changed = aggregator.add(id, usage);
3445
+ if (changed && server) {
3446
+ setImmediate(() => {
3447
+ const currentHash = computeUsageHash(aggregator.getUsage());
3448
+ if (currentHash !== lastUsageHash) {
3449
+ invalidateVirtualModule();
3450
+ }
3451
+ });
3452
+ }
3453
+ return null;
3454
+ },
3455
+ /**
3456
+ * Handle file changes in HMR
3457
+ */
3458
+ async handleHotUpdate(ctx) {
3459
+ const { file, read } = ctx;
3460
+ if (scanner.shouldScan(file)) {
3461
+ try {
3462
+ const content = await read();
3463
+ const usage = scanner.scan(content, file);
3464
+ const changed = aggregator.add(file, usage);
3465
+ if (options.debug) {
3466
+ console.log("[hyperfixi] HMR: Re-scanned", file.split("/").pop(), usage);
3467
+ }
3468
+ if (changed) {
3469
+ const currentHash = computeUsageHash(aggregator.getUsage());
3470
+ if (currentHash !== lastUsageHash) {
3471
+ invalidateVirtualModule();
3472
+ }
3473
+ }
3474
+ } catch {
3475
+ if (aggregator.remove(file)) {
3476
+ invalidateVirtualModule();
3477
+ }
3478
+ }
3479
+ }
3480
+ return void 0;
3481
+ },
3482
+ /**
3483
+ * Scan entire project before production build
3484
+ */
3485
+ async buildStart() {
3486
+ if (!isDev) {
3487
+ if (mode === "compile") {
3488
+ resetCompiler();
3489
+ compiledHandlers.length = 0;
3490
+ handlerMap.clear();
3491
+ fallbackScripts.clear();
3492
+ needsLocals = false;
3493
+ needsGlobals = false;
3494
+ if (options.debug) {
3495
+ console.log("[hyperfixi] Compile mode: ready for build");
3496
+ }
3497
+ }
3498
+ const cwd = process.cwd();
3499
+ if (options.debug) {
3500
+ console.log("[hyperfixi] Scanning project for hyperscript usage...");
3501
+ }
3502
+ const scannedFiles = await scanner.scanProject(cwd);
3503
+ aggregator.loadFromScan(scannedFiles);
3504
+ if (mode === "compile") {
3505
+ const usage = aggregator.getUsage();
3506
+ if (usage.detectedLanguages.size > 0) {
3507
+ const aliases = getMultilingualCommandAliases(
3508
+ usage.detectedLanguages
3509
+ );
3510
+ if (Object.keys(aliases).length > 0) {
3511
+ setMultilingualAliases(aliases);
3512
+ if (options.debug) {
3513
+ console.log(
3514
+ `[hyperfixi] Compile mode: configured ${Object.keys(aliases).length} multilingual aliases`
3515
+ );
3516
+ }
3517
+ }
3518
+ }
3519
+ }
3520
+ if (options.debug) {
3521
+ const summary = aggregator.getSummary();
3522
+ console.log(`[hyperfixi] Found ${summary.fileCount} files with hyperscript:`, {
3523
+ commands: summary.commands,
3524
+ blocks: summary.blocks,
3525
+ positional: summary.positional,
3526
+ languages: summary.languages
3527
+ });
3528
+ }
3529
+ }
3530
+ }
3531
+ };
3532
+ }
3533
+ var index_default = hyperfixi;
3534
+ // Annotate the CommonJS export names for ESM import in node:
3535
+ 0 && (module.exports = {
3536
+ REGIONS,
3537
+ SUPPORTED_LANGUAGES,
3538
+ clearCustomKeywords,
3539
+ clearSemanticParser,
3540
+ detectLanguages,
3541
+ getAllLanguageCodes,
3542
+ getKeywordsForLanguage,
3543
+ getOptimalRegion,
3544
+ hasSemanticParser,
3545
+ hyperfixi,
3546
+ isNonLatinLanguage,
3547
+ registerCustomKeywords,
3548
+ setSemanticParser
3549
+ });
3550
+ //# sourceMappingURL=index.cjs.map