@lokascript/vite-plugin 1.0.0 → 1.1.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 +147 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +147 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -153,6 +153,27 @@ interface CustomLanguageKeywords {
|
|
|
153
153
|
*/
|
|
154
154
|
extend?: boolean;
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* HTMX/Fixi attribute usage information
|
|
158
|
+
*/
|
|
159
|
+
interface HtmxUsage {
|
|
160
|
+
/** Whether any htmx attributes were found */
|
|
161
|
+
hasHtmxAttributes: boolean;
|
|
162
|
+
/** Whether any fixi-specific attributes were found (fx-action, etc.) */
|
|
163
|
+
hasFixiAttributes: boolean;
|
|
164
|
+
/** HTTP methods used (GET, POST, PUT, PATCH, DELETE) */
|
|
165
|
+
httpMethods: Set<string>;
|
|
166
|
+
/** Swap strategies used (innerHTML, morph, delete, beforeend, etc.) */
|
|
167
|
+
swapStrategies: Set<string>;
|
|
168
|
+
/** hx-on:* handler values (raw hyperscript) */
|
|
169
|
+
onHandlers: string[];
|
|
170
|
+
/** Trigger modifiers detected (debounce, throttle, once) */
|
|
171
|
+
triggerModifiers: Set<string>;
|
|
172
|
+
/** URL management strategies (push-url, replace-url) */
|
|
173
|
+
urlManagement: Set<string>;
|
|
174
|
+
/** Whether hx-confirm is used */
|
|
175
|
+
usesConfirm: boolean;
|
|
176
|
+
}
|
|
156
177
|
/**
|
|
157
178
|
* Usage information detected from a single file
|
|
158
179
|
*/
|
|
@@ -165,6 +186,8 @@ interface FileUsage {
|
|
|
165
186
|
positional: boolean;
|
|
166
187
|
/** Non-English languages detected in hyperscript (ISO 639-1 codes) */
|
|
167
188
|
detectedLanguages: Set<string>;
|
|
189
|
+
/** HTMX/Fixi attribute usage (if detected) */
|
|
190
|
+
htmx?: HtmxUsage;
|
|
168
191
|
}
|
|
169
192
|
/**
|
|
170
193
|
* Aggregated usage information across all files
|
|
@@ -178,6 +201,8 @@ interface AggregatedUsage {
|
|
|
178
201
|
positional: boolean;
|
|
179
202
|
/** All non-English languages detected across all files */
|
|
180
203
|
detectedLanguages: Set<string>;
|
|
204
|
+
/** Aggregated HTMX/Fixi usage across all files */
|
|
205
|
+
htmx: HtmxUsage;
|
|
181
206
|
/** Map of file paths to their usage */
|
|
182
207
|
fileUsage: Map<string, FileUsage>;
|
|
183
208
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,27 @@ interface CustomLanguageKeywords {
|
|
|
153
153
|
*/
|
|
154
154
|
extend?: boolean;
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* HTMX/Fixi attribute usage information
|
|
158
|
+
*/
|
|
159
|
+
interface HtmxUsage {
|
|
160
|
+
/** Whether any htmx attributes were found */
|
|
161
|
+
hasHtmxAttributes: boolean;
|
|
162
|
+
/** Whether any fixi-specific attributes were found (fx-action, etc.) */
|
|
163
|
+
hasFixiAttributes: boolean;
|
|
164
|
+
/** HTTP methods used (GET, POST, PUT, PATCH, DELETE) */
|
|
165
|
+
httpMethods: Set<string>;
|
|
166
|
+
/** Swap strategies used (innerHTML, morph, delete, beforeend, etc.) */
|
|
167
|
+
swapStrategies: Set<string>;
|
|
168
|
+
/** hx-on:* handler values (raw hyperscript) */
|
|
169
|
+
onHandlers: string[];
|
|
170
|
+
/** Trigger modifiers detected (debounce, throttle, once) */
|
|
171
|
+
triggerModifiers: Set<string>;
|
|
172
|
+
/** URL management strategies (push-url, replace-url) */
|
|
173
|
+
urlManagement: Set<string>;
|
|
174
|
+
/** Whether hx-confirm is used */
|
|
175
|
+
usesConfirm: boolean;
|
|
176
|
+
}
|
|
156
177
|
/**
|
|
157
178
|
* Usage information detected from a single file
|
|
158
179
|
*/
|
|
@@ -165,6 +186,8 @@ interface FileUsage {
|
|
|
165
186
|
positional: boolean;
|
|
166
187
|
/** Non-English languages detected in hyperscript (ISO 639-1 codes) */
|
|
167
188
|
detectedLanguages: Set<string>;
|
|
189
|
+
/** HTMX/Fixi attribute usage (if detected) */
|
|
190
|
+
htmx?: HtmxUsage;
|
|
168
191
|
}
|
|
169
192
|
/**
|
|
170
193
|
* Aggregated usage information across all files
|
|
@@ -178,6 +201,8 @@ interface AggregatedUsage {
|
|
|
178
201
|
positional: boolean;
|
|
179
202
|
/** All non-English languages detected across all files */
|
|
180
203
|
detectedLanguages: Set<string>;
|
|
204
|
+
/** Aggregated HTMX/Fixi usage across all files */
|
|
205
|
+
htmx: HtmxUsage;
|
|
181
206
|
/** Map of file paths to their usage */
|
|
182
207
|
fileUsage: Map<string, FileUsage>;
|
|
183
208
|
}
|
package/dist/index.js
CHANGED
|
@@ -791,6 +791,15 @@ function getOptimalRegion(languages) {
|
|
|
791
791
|
}
|
|
792
792
|
|
|
793
793
|
// src/scanner.ts
|
|
794
|
+
var HTMX_REQUEST_PATTERN = /\b(hx-get|hx-post|hx-put|hx-patch|hx-delete)\s*=\s*["']([^"']+)["']/gi;
|
|
795
|
+
var FIXI_ACTION_PATTERN = /\bfx-action\s*=\s*["']([^"']+)["']/gi;
|
|
796
|
+
var FIXI_METHOD_PATTERN = /\bfx-method\s*=\s*["'](GET|POST|PUT|PATCH|DELETE)["']/gi;
|
|
797
|
+
var HTMX_SWAP_PATTERN = /\b(hx-swap|fx-swap)\s*=\s*["']([^"']+)["']/gi;
|
|
798
|
+
var HTMX_TARGET_PATTERN = /\b(hx-target|fx-target)\s*=\s*["']([^"']+)["']/gi;
|
|
799
|
+
var HTMX_TRIGGER_PATTERN = /\b(hx-trigger|fx-trigger)\s*=\s*["']([^"']+)["']/gi;
|
|
800
|
+
var HTMX_URL_PATTERN = /\b(hx-push-url|hx-replace-url)\s*=\s*["'][^"']+["']/gi;
|
|
801
|
+
var HTMX_CONFIRM_PATTERN = /\bhx-confirm\s*=\s*["']/gi;
|
|
802
|
+
var HTMX_ON_PATTERN = /\bhx-on:(\w+)\s*=\s*["']([^"']+)["']/g;
|
|
794
803
|
function toRegex(pattern, defaultPattern) {
|
|
795
804
|
if (!pattern) return defaultPattern;
|
|
796
805
|
if (pattern instanceof RegExp) return pattern;
|
|
@@ -848,12 +857,29 @@ var Scanner = class {
|
|
|
848
857
|
while (match = scriptPattern.exec(code)) {
|
|
849
858
|
this.analyzeScript(match[1], usage);
|
|
850
859
|
}
|
|
851
|
-
|
|
860
|
+
const htmxUsage = this.scanHtmxAttributes(code);
|
|
861
|
+
if (htmxUsage.hasHtmxAttributes) {
|
|
862
|
+
usage.htmx = htmxUsage;
|
|
863
|
+
this.inferCommandsFromHtmx(htmxUsage, usage);
|
|
864
|
+
for (const handlerCode of htmxUsage.onHandlers) {
|
|
865
|
+
this.analyzeScript(handlerCode, usage);
|
|
866
|
+
}
|
|
867
|
+
if (/hx-target\s*=\s*["'](closest|next|previous|find)\s/i.test(code)) {
|
|
868
|
+
usage.positional = true;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (this.debug && (usage.commands.size > 0 || usage.blocks.size > 0 || usage.detectedLanguages.size > 0 || usage.htmx?.hasHtmxAttributes)) {
|
|
852
872
|
console.log(`[hyperfixi] Scanned ${id}:`, {
|
|
853
873
|
commands: [...usage.commands],
|
|
854
874
|
blocks: [...usage.blocks],
|
|
855
875
|
positional: usage.positional,
|
|
856
|
-
languages: [...usage.detectedLanguages]
|
|
876
|
+
languages: [...usage.detectedLanguages],
|
|
877
|
+
htmx: usage.htmx ? {
|
|
878
|
+
hasHtmxAttributes: usage.htmx.hasHtmxAttributes,
|
|
879
|
+
hasFixiAttributes: usage.htmx.hasFixiAttributes,
|
|
880
|
+
httpMethods: [...usage.htmx.httpMethods],
|
|
881
|
+
swapStrategies: [...usage.htmx.swapStrategies]
|
|
882
|
+
} : void 0
|
|
857
883
|
});
|
|
858
884
|
}
|
|
859
885
|
return usage;
|
|
@@ -881,6 +907,93 @@ var Scanner = class {
|
|
|
881
907
|
usage.detectedLanguages.add(lang);
|
|
882
908
|
}
|
|
883
909
|
}
|
|
910
|
+
/**
|
|
911
|
+
* Scan for htmx/fixi attributes
|
|
912
|
+
*/
|
|
913
|
+
scanHtmxAttributes(code) {
|
|
914
|
+
const usage = {
|
|
915
|
+
hasHtmxAttributes: false,
|
|
916
|
+
hasFixiAttributes: false,
|
|
917
|
+
httpMethods: /* @__PURE__ */ new Set(),
|
|
918
|
+
swapStrategies: /* @__PURE__ */ new Set(),
|
|
919
|
+
onHandlers: [],
|
|
920
|
+
triggerModifiers: /* @__PURE__ */ new Set(),
|
|
921
|
+
urlManagement: /* @__PURE__ */ new Set(),
|
|
922
|
+
usesConfirm: false
|
|
923
|
+
};
|
|
924
|
+
let match;
|
|
925
|
+
const requestPattern = new RegExp(HTMX_REQUEST_PATTERN.source, "gi");
|
|
926
|
+
while (match = requestPattern.exec(code)) {
|
|
927
|
+
usage.hasHtmxAttributes = true;
|
|
928
|
+
usage.httpMethods.add(match[1].replace("hx-", "").toUpperCase());
|
|
929
|
+
}
|
|
930
|
+
if (new RegExp(FIXI_ACTION_PATTERN.source, "gi").test(code)) {
|
|
931
|
+
usage.hasHtmxAttributes = true;
|
|
932
|
+
usage.hasFixiAttributes = true;
|
|
933
|
+
}
|
|
934
|
+
const fixiMethodPattern = new RegExp(FIXI_METHOD_PATTERN.source, "gi");
|
|
935
|
+
while (match = fixiMethodPattern.exec(code)) {
|
|
936
|
+
usage.hasHtmxAttributes = true;
|
|
937
|
+
usage.hasFixiAttributes = true;
|
|
938
|
+
usage.httpMethods.add(match[1].toUpperCase());
|
|
939
|
+
}
|
|
940
|
+
const swapPattern = new RegExp(HTMX_SWAP_PATTERN.source, "gi");
|
|
941
|
+
while (match = swapPattern.exec(code)) {
|
|
942
|
+
usage.hasHtmxAttributes = true;
|
|
943
|
+
usage.swapStrategies.add(match[2].split(/\s+/)[0]);
|
|
944
|
+
}
|
|
945
|
+
const triggerPattern = new RegExp(HTMX_TRIGGER_PATTERN.source, "gi");
|
|
946
|
+
while (match = triggerPattern.exec(code)) {
|
|
947
|
+
usage.hasHtmxAttributes = true;
|
|
948
|
+
const trigger = match[2];
|
|
949
|
+
if (/delay:/i.test(trigger)) usage.triggerModifiers.add("debounce");
|
|
950
|
+
if (/throttle:/i.test(trigger)) usage.triggerModifiers.add("throttle");
|
|
951
|
+
if (/\bonce\b/i.test(trigger)) usage.triggerModifiers.add("once");
|
|
952
|
+
}
|
|
953
|
+
if (new RegExp(HTMX_URL_PATTERN.source, "gi").test(code)) {
|
|
954
|
+
usage.hasHtmxAttributes = true;
|
|
955
|
+
if (/hx-push-url/i.test(code)) usage.urlManagement.add("push-url");
|
|
956
|
+
if (/hx-replace-url/i.test(code)) usage.urlManagement.add("replace-url");
|
|
957
|
+
}
|
|
958
|
+
if (new RegExp(HTMX_CONFIRM_PATTERN.source, "gi").test(code)) {
|
|
959
|
+
usage.hasHtmxAttributes = true;
|
|
960
|
+
usage.usesConfirm = true;
|
|
961
|
+
}
|
|
962
|
+
const onPattern = new RegExp(HTMX_ON_PATTERN.source, "g");
|
|
963
|
+
while (match = onPattern.exec(code)) {
|
|
964
|
+
usage.hasHtmxAttributes = true;
|
|
965
|
+
usage.onHandlers.push(match[2]);
|
|
966
|
+
}
|
|
967
|
+
const targetPattern = new RegExp(HTMX_TARGET_PATTERN.source, "gi");
|
|
968
|
+
while (match = targetPattern.exec(code)) {
|
|
969
|
+
usage.hasHtmxAttributes = true;
|
|
970
|
+
}
|
|
971
|
+
return usage;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Infer commands from htmx usage
|
|
975
|
+
*/
|
|
976
|
+
inferCommandsFromHtmx(htmx, usage) {
|
|
977
|
+
if (htmx.httpMethods.size > 0) {
|
|
978
|
+
usage.blocks.add("fetch");
|
|
979
|
+
usage.commands.add("put");
|
|
980
|
+
}
|
|
981
|
+
for (const swap of htmx.swapStrategies) {
|
|
982
|
+
switch (swap.toLowerCase()) {
|
|
983
|
+
case "morph":
|
|
984
|
+
usage.commands.add("morph");
|
|
985
|
+
break;
|
|
986
|
+
case "delete":
|
|
987
|
+
usage.commands.add("remove");
|
|
988
|
+
break;
|
|
989
|
+
default:
|
|
990
|
+
usage.commands.add("put");
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
if (htmx.usesConfirm) {
|
|
994
|
+
usage.blocks.add("if");
|
|
995
|
+
}
|
|
996
|
+
}
|
|
884
997
|
/**
|
|
885
998
|
* Scan all files in a project directory
|
|
886
999
|
* Used during production build to scan the entire codebase
|
|
@@ -931,7 +1044,8 @@ var Aggregator = class {
|
|
|
931
1044
|
const blocksEqual = this.setsEqual(existing.blocks, usage.blocks);
|
|
932
1045
|
const positionalEqual = existing.positional === usage.positional;
|
|
933
1046
|
const languagesEqual = this.setsEqual(existing.detectedLanguages, usage.detectedLanguages);
|
|
934
|
-
|
|
1047
|
+
const htmxEqual = this.htmxUsageEqual(existing.htmx, usage.htmx);
|
|
1048
|
+
if (commandsEqual && blocksEqual && positionalEqual && languagesEqual && htmxEqual) {
|
|
935
1049
|
return false;
|
|
936
1050
|
}
|
|
937
1051
|
}
|
|
@@ -961,17 +1075,38 @@ var Aggregator = class {
|
|
|
961
1075
|
const blocks = /* @__PURE__ */ new Set();
|
|
962
1076
|
const detectedLanguages = /* @__PURE__ */ new Set();
|
|
963
1077
|
let positional = false;
|
|
1078
|
+
const htmx = {
|
|
1079
|
+
hasHtmxAttributes: false,
|
|
1080
|
+
hasFixiAttributes: false,
|
|
1081
|
+
httpMethods: /* @__PURE__ */ new Set(),
|
|
1082
|
+
swapStrategies: /* @__PURE__ */ new Set(),
|
|
1083
|
+
onHandlers: [],
|
|
1084
|
+
triggerModifiers: /* @__PURE__ */ new Set(),
|
|
1085
|
+
urlManagement: /* @__PURE__ */ new Set(),
|
|
1086
|
+
usesConfirm: false
|
|
1087
|
+
};
|
|
964
1088
|
for (const usage of this.fileUsage.values()) {
|
|
965
1089
|
for (const cmd of usage.commands) commands.add(cmd);
|
|
966
1090
|
for (const block of usage.blocks) blocks.add(block);
|
|
967
1091
|
for (const lang of usage.detectedLanguages) detectedLanguages.add(lang);
|
|
968
1092
|
if (usage.positional) positional = true;
|
|
1093
|
+
if (usage.htmx) {
|
|
1094
|
+
if (usage.htmx.hasHtmxAttributes) htmx.hasHtmxAttributes = true;
|
|
1095
|
+
if (usage.htmx.hasFixiAttributes) htmx.hasFixiAttributes = true;
|
|
1096
|
+
for (const method of usage.htmx.httpMethods) htmx.httpMethods.add(method);
|
|
1097
|
+
for (const swap of usage.htmx.swapStrategies) htmx.swapStrategies.add(swap);
|
|
1098
|
+
htmx.onHandlers.push(...usage.htmx.onHandlers);
|
|
1099
|
+
for (const modifier of usage.htmx.triggerModifiers) htmx.triggerModifiers.add(modifier);
|
|
1100
|
+
for (const url of usage.htmx.urlManagement) htmx.urlManagement.add(url);
|
|
1101
|
+
if (usage.htmx.usesConfirm) htmx.usesConfirm = true;
|
|
1102
|
+
}
|
|
969
1103
|
}
|
|
970
1104
|
this.cachedUsage = {
|
|
971
1105
|
commands,
|
|
972
1106
|
blocks,
|
|
973
1107
|
positional,
|
|
974
1108
|
detectedLanguages,
|
|
1109
|
+
htmx,
|
|
975
1110
|
fileUsage: new Map(this.fileUsage)
|
|
976
1111
|
};
|
|
977
1112
|
return this.cachedUsage;
|
|
@@ -1020,6 +1155,14 @@ var Aggregator = class {
|
|
|
1020
1155
|
}
|
|
1021
1156
|
return true;
|
|
1022
1157
|
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Compare two HtmxUsage objects for equality
|
|
1160
|
+
*/
|
|
1161
|
+
htmxUsageEqual(a, b) {
|
|
1162
|
+
if (!a && !b) return true;
|
|
1163
|
+
if (!a || !b) return false;
|
|
1164
|
+
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;
|
|
1165
|
+
}
|
|
1023
1166
|
};
|
|
1024
1167
|
|
|
1025
1168
|
// src/generator.ts
|
|
@@ -1894,7 +2037,7 @@ var Generator = class {
|
|
|
1894
2037
|
commands,
|
|
1895
2038
|
blocks,
|
|
1896
2039
|
positionalExpressions: positional,
|
|
1897
|
-
htmxIntegration: options.htmx ?? false,
|
|
2040
|
+
htmxIntegration: options.htmx ?? usage.htmx?.hasHtmxAttributes ?? false,
|
|
1898
2041
|
globalName: options.globalName ?? "hyperfixi",
|
|
1899
2042
|
// Use @lokascript/core package path for virtual module
|
|
1900
2043
|
parserImportPath: "@lokascript/core/parser/hybrid",
|