@stll/regex-set-wasm 1.0.8 → 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/regex-set.single-thread.wasm +0 -0
- package/dist/regex-set.wasm32-wasi.wasm +0 -0
- package/dist/single-thread-inline.d.mts +123 -0
- package/dist/single-thread-inline.mjs +1003 -0
- package/dist/single-thread-inline.mjs.map +1 -0
- package/dist/single-thread-size.json +5 -0
- package/dist/single-thread.d.mts +125 -0
- package/dist/single-thread.mjs +1015 -0
- package/dist/single-thread.mjs.map +1 -0
- package/dist/vite.mjs.map +1 -1
- package/dist/wasi-worker-browser.mjs.map +1 -1
- package/dist/wasm.d.mts +3 -0
- package/dist/wasm.mjs +278 -10
- package/dist/wasm.mjs.map +1 -1
- package/package.json +15 -4
package/dist/wasm.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { WASI, emnapiAsyncWorkPlugin, emnapiTSFNPlugin, instantiateNapiModule } from "@napi-rs/wasm-runtime";
|
|
2
1
|
import { createContext } from "@emnapi/runtime";
|
|
2
|
+
import { WASI, emnapiAsyncWorkPlugin, emnapiTSFNPlugin, instantiateNapiModule } from "@napi-rs/wasm-runtime";
|
|
3
3
|
//#region regex-set.wasi-browser.js
|
|
4
4
|
const __napiBindingTarget = "wasm32-wasi";
|
|
5
5
|
function __napiStampBindingTarget(exportsObject, target) {
|
|
@@ -60,6 +60,54 @@ let __emnapiWasmEnvCleanupDrainPromise;
|
|
|
60
60
|
let __wasiDisposed = false;
|
|
61
61
|
let __wasiAsyncWorkDrainPromise;
|
|
62
62
|
let __wasiDisposePromise;
|
|
63
|
+
let __wasiThreadCrashDisposePromise;
|
|
64
|
+
let __wasiInitializationRollbackActive = false;
|
|
65
|
+
let __wasiThreadCrashed = false;
|
|
66
|
+
let __wasiThreadCrashWorkerError;
|
|
67
|
+
function __recordWasiThreadCrashError(error) {
|
|
68
|
+
__wasiThreadCrashed = true;
|
|
69
|
+
if (__wasiThreadCrashWorkerError === void 0 && error !== void 0) __wasiThreadCrashWorkerError = error;
|
|
70
|
+
}
|
|
71
|
+
function __hasWasiThreadCrashed() {
|
|
72
|
+
if (__wasiThreadCrashed || __wasiAddonCrashFlag !== void 0 && Atomics.load(__wasiAddonCrashFlag, 0) !== 0) return true;
|
|
73
|
+
const manager = typeof __getWasiThreadManager === "function" ? __getWasiThreadManager() : void 0;
|
|
74
|
+
return Boolean(manager && manager._fatalError);
|
|
75
|
+
}
|
|
76
|
+
function __getWasiThreadCrashError() {
|
|
77
|
+
const error = /* @__PURE__ */ new Error("napi-rs: WASI binding cannot be disposed after a worker thread crashed");
|
|
78
|
+
const manager = typeof __getWasiThreadManager === "function" ? __getWasiThreadManager() : void 0;
|
|
79
|
+
const cause = __wasiThreadCrashWorkerError ?? (manager ? manager._fatalError : void 0);
|
|
80
|
+
if (cause !== void 0 && cause !== null) error.cause = cause;
|
|
81
|
+
return error;
|
|
82
|
+
}
|
|
83
|
+
function __disposeWasiBindingAfterThreadCrash() {
|
|
84
|
+
if (__wasiThreadCrashDisposePromise) return __wasiThreadCrashDisposePromise;
|
|
85
|
+
let workerResult;
|
|
86
|
+
try {
|
|
87
|
+
workerResult = __terminateWasiWorkers();
|
|
88
|
+
} catch (error) {
|
|
89
|
+
workerResult = Promise.reject(error);
|
|
90
|
+
}
|
|
91
|
+
__wasiThreadCrashDisposePromise = Promise.resolve(workerResult).then(() => {
|
|
92
|
+
throw __getWasiThreadCrashError();
|
|
93
|
+
}, (error) => {
|
|
94
|
+
throw error;
|
|
95
|
+
});
|
|
96
|
+
return __wasiThreadCrashDisposePromise;
|
|
97
|
+
}
|
|
98
|
+
function __abortWasiDisposalIfThreadCrashed() {
|
|
99
|
+
if ((__wasiDisposePromise !== void 0 || __wasiInitializationRollbackActive) && __hasWasiThreadCrashed()) throw __getWasiThreadCrashError();
|
|
100
|
+
}
|
|
101
|
+
function __settleWasiDisposalAfterThreadCrash(resolve, reject) {
|
|
102
|
+
if (!__hasWasiThreadCrashed()) return false;
|
|
103
|
+
__disposeWasiBindingAfterThreadCrash().then(resolve, reject);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
function __rollbackWasiInitializationAfterThreadCrash() {
|
|
107
|
+
const crashError = __getWasiThreadCrashError();
|
|
108
|
+
__disposeWasiBindingAfterThreadCrash().catch(() => {});
|
|
109
|
+
return [crashError];
|
|
110
|
+
}
|
|
63
111
|
let __completeWasiDisposal = function() {};
|
|
64
112
|
function __isThenable(value) {
|
|
65
113
|
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
@@ -111,6 +159,7 @@ function __wrapEmnapiContextDestroyForSettlement(context, prepareEnvCleanup, isP
|
|
|
111
159
|
enumerable: false,
|
|
112
160
|
writable: true,
|
|
113
161
|
value: function() {
|
|
162
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
114
163
|
if (isPreparingEnvCleanup?.()) return;
|
|
115
164
|
prepareEnvCleanup?.();
|
|
116
165
|
return Reflect.apply(destroy, this, arguments);
|
|
@@ -123,6 +172,7 @@ function __isPreparingWasmEnvCleanup() {
|
|
|
123
172
|
return __emnapiWasmEnvCleanupPreparing;
|
|
124
173
|
}
|
|
125
174
|
function __prepareWasmEnvCleanup() {
|
|
175
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
126
176
|
if (__emnapiWasmEnvCleanupPrepared) return;
|
|
127
177
|
const finishParked = __finishParkedWasmEnvCleanup;
|
|
128
178
|
if (finishParked !== void 0) {
|
|
@@ -388,6 +438,7 @@ function __prepareWasmEnvCleanupWithTurns() {
|
|
|
388
438
|
__emnapiWasmEnvCleanupPreparing = true;
|
|
389
439
|
let live;
|
|
390
440
|
try {
|
|
441
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
391
442
|
live = begin();
|
|
392
443
|
} catch (error) {
|
|
393
444
|
__emnapiWasmEnvCleanupPreparing = false;
|
|
@@ -395,6 +446,7 @@ function __prepareWasmEnvCleanupWithTurns() {
|
|
|
395
446
|
}
|
|
396
447
|
__emnapiWasmEnvCleanupRan = true;
|
|
397
448
|
const finishCleanup = () => {
|
|
449
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
398
450
|
if (__emnapiWasmEnvCleanupPrepared) return;
|
|
399
451
|
__finishParkedWasmEnvCleanup = void 0;
|
|
400
452
|
try {
|
|
@@ -409,17 +461,27 @@ function __prepareWasmEnvCleanupWithTurns() {
|
|
|
409
461
|
return;
|
|
410
462
|
}
|
|
411
463
|
__finishParkedWasmEnvCleanup = finishCleanup;
|
|
464
|
+
const finishCleanupUnlessCrashed = () => {
|
|
465
|
+
try {
|
|
466
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
467
|
+
} catch (error) {
|
|
468
|
+
__finishParkedWasmEnvCleanup = void 0;
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
471
|
+
finishCleanup();
|
|
472
|
+
};
|
|
412
473
|
return (async () => {
|
|
413
474
|
const pace = __createWasmRuntimePollPace();
|
|
414
475
|
for (;;) {
|
|
415
476
|
await __yieldWasmRuntimePollTurn(pace);
|
|
477
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
416
478
|
try {
|
|
417
479
|
if (!workPending()) return;
|
|
418
480
|
} catch {
|
|
419
481
|
return;
|
|
420
482
|
}
|
|
421
483
|
}
|
|
422
|
-
})().then(
|
|
484
|
+
})().then(finishCleanupUnlessCrashed, finishCleanupUnlessCrashed);
|
|
423
485
|
}
|
|
424
486
|
const __WASM_ENV_CLEANUP_DRAIN_TURNS = 128;
|
|
425
487
|
const __WASM_ENV_CLEANUP_BLIND_DRAIN_TURNS = 4;
|
|
@@ -500,6 +562,7 @@ function __drainWasmEnvCleanup() {
|
|
|
500
562
|
return drainPromise;
|
|
501
563
|
}
|
|
502
564
|
function __destroyEmnapiContext() {
|
|
565
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
503
566
|
if (__emnapiContextDestroyed || __emnapiContext === void 0) {
|
|
504
567
|
__emnapiContextDestroyed = true;
|
|
505
568
|
return;
|
|
@@ -692,16 +755,19 @@ function __finishWasiDisposal() {
|
|
|
692
755
|
if (__isThenable(workerResult)) return Promise.resolve(workerResult).then(__completeWasiDisposal);
|
|
693
756
|
}
|
|
694
757
|
function __continueWasiDisposal() {
|
|
758
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
695
759
|
const destroyResult = __destroyEmnapiContext();
|
|
696
760
|
if (__isThenable(destroyResult)) return Promise.resolve(destroyResult).then(__finishWasiDisposal);
|
|
697
761
|
return __finishWasiDisposal();
|
|
698
762
|
}
|
|
699
763
|
function __drainWasmEnvForWasiDisposal() {
|
|
764
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
700
765
|
const drainResult = __drainWasmEnvCleanup();
|
|
701
766
|
if (__isThenable(drainResult)) return Promise.resolve(drainResult).then(__continueWasiDisposal);
|
|
702
767
|
return __continueWasiDisposal();
|
|
703
768
|
}
|
|
704
769
|
function __cleanUpWasmEnvForWasiDisposal() {
|
|
770
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
705
771
|
const prepareResult = __prepareWasmEnvCleanupWithTurns();
|
|
706
772
|
if (__isThenable(prepareResult)) return Promise.resolve(prepareResult).then(__drainWasmEnvForWasiDisposal);
|
|
707
773
|
return __drainWasmEnvForWasiDisposal();
|
|
@@ -719,6 +785,7 @@ function __startWasiDisposal() {
|
|
|
719
785
|
*/
|
|
720
786
|
function __disposeWasiBinding() {
|
|
721
787
|
if (__wasiDisposePromise) return __wasiDisposePromise;
|
|
788
|
+
if (!__wasiDisposed && __hasWasiThreadCrashed()) return __disposeWasiBindingAfterThreadCrash();
|
|
722
789
|
if (__wasiDisposed) return Promise.resolve();
|
|
723
790
|
let resolveDispose;
|
|
724
791
|
let rejectDispose;
|
|
@@ -731,6 +798,7 @@ function __disposeWasiBinding() {
|
|
|
731
798
|
try {
|
|
732
799
|
result = __startWasiDisposal();
|
|
733
800
|
} catch (error) {
|
|
801
|
+
if (__settleWasiDisposalAfterThreadCrash(resolveDispose, rejectDispose)) return disposePromise;
|
|
734
802
|
__wasiDisposePromise = void 0;
|
|
735
803
|
rejectDispose(error);
|
|
736
804
|
return disposePromise;
|
|
@@ -739,6 +807,7 @@ function __disposeWasiBinding() {
|
|
|
739
807
|
__wasiDisposed = true;
|
|
740
808
|
resolveDispose(value);
|
|
741
809
|
}, (error) => {
|
|
810
|
+
if (__settleWasiDisposalAfterThreadCrash(resolveDispose, rejectDispose)) return;
|
|
742
811
|
__wasiDisposePromise = void 0;
|
|
743
812
|
rejectDispose(error);
|
|
744
813
|
});
|
|
@@ -766,6 +835,7 @@ function __finishWasiInitializationRollback(cleanupErrors) {
|
|
|
766
835
|
return cleanupErrors;
|
|
767
836
|
}
|
|
768
837
|
function __destroyContextForWasiRollback(cleanupErrors) {
|
|
838
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
769
839
|
let destroyResult;
|
|
770
840
|
try {
|
|
771
841
|
destroyResult = __destroyEmnapiContext();
|
|
@@ -823,8 +893,9 @@ function __retainFailedWasiRollback(cleanupErrors) {
|
|
|
823
893
|
* goes away. That is the deliberate choice: a hung promise is a silent liveness
|
|
824
894
|
* bug with no upper bound, while the retained bookkeeping is bounded by the page.
|
|
825
895
|
*/
|
|
826
|
-
function
|
|
896
|
+
function __runWasiInitializationRollbackSteps() {
|
|
827
897
|
function __rollbackWasmEnvForWasiInitialization() {
|
|
898
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
828
899
|
const cleanupErrors = [];
|
|
829
900
|
let prepareResult;
|
|
830
901
|
try {
|
|
@@ -840,6 +911,7 @@ function __rollbackWasiInitialization() {
|
|
|
840
911
|
return __drainWasmEnvForWasiRollback(cleanupErrors);
|
|
841
912
|
}
|
|
842
913
|
function __drainWasmEnvForWasiRollback(cleanupErrors) {
|
|
914
|
+
__abortWasiDisposalIfThreadCrashed();
|
|
843
915
|
let drainResult;
|
|
844
916
|
try {
|
|
845
917
|
drainResult = __drainWasmEnvCleanup();
|
|
@@ -863,6 +935,30 @@ function __rollbackWasiInitialization() {
|
|
|
863
935
|
if (__isThenable(asyncWorkResult)) return Promise.resolve(asyncWorkResult).then(__rollbackWasmEnvForWasiInitialization, __retainAfterAsyncWorkDrainFailure);
|
|
864
936
|
return __rollbackWasmEnvForWasiInitialization();
|
|
865
937
|
}
|
|
938
|
+
function __rollbackWasiInitialization() {
|
|
939
|
+
if (__hasWasiThreadCrashed()) return __rollbackWasiInitializationAfterThreadCrash();
|
|
940
|
+
__wasiInitializationRollbackActive = true;
|
|
941
|
+
let result;
|
|
942
|
+
try {
|
|
943
|
+
result = __runWasiInitializationRollbackSteps();
|
|
944
|
+
} catch (error) {
|
|
945
|
+
__wasiInitializationRollbackActive = false;
|
|
946
|
+
if (__hasWasiThreadCrashed()) return __rollbackWasiInitializationAfterThreadCrash();
|
|
947
|
+
throw error;
|
|
948
|
+
}
|
|
949
|
+
if (!__isThenable(result)) {
|
|
950
|
+
__wasiInitializationRollbackActive = false;
|
|
951
|
+
return __hasWasiThreadCrashed() ? __rollbackWasiInitializationAfterThreadCrash() : result;
|
|
952
|
+
}
|
|
953
|
+
return Promise.resolve(result).then((cleanupErrors) => {
|
|
954
|
+
__wasiInitializationRollbackActive = false;
|
|
955
|
+
return __hasWasiThreadCrashed() ? __rollbackWasiInitializationAfterThreadCrash() : cleanupErrors;
|
|
956
|
+
}, (error) => {
|
|
957
|
+
__wasiInitializationRollbackActive = false;
|
|
958
|
+
if (__hasWasiThreadCrashed()) return __rollbackWasiInitializationAfterThreadCrash();
|
|
959
|
+
throw error;
|
|
960
|
+
});
|
|
961
|
+
}
|
|
866
962
|
let __wasiAddonCrashFlag;
|
|
867
963
|
function __captureWasiAddonCrashFlag(instance) {
|
|
868
964
|
try {
|
|
@@ -898,6 +994,12 @@ try {
|
|
|
898
994
|
onCreateWorker() {
|
|
899
995
|
const worker = new Worker(new URL("./wasi-worker-browser.mjs", import.meta.url), { type: "module" });
|
|
900
996
|
__wasiWorkers.add(worker);
|
|
997
|
+
worker.addEventListener("error", (event) => {
|
|
998
|
+
__recordWasiThreadCrashError(event.error ?? event);
|
|
999
|
+
});
|
|
1000
|
+
worker.addEventListener("messageerror", (event) => {
|
|
1001
|
+
__recordWasiThreadCrashError(event);
|
|
1002
|
+
});
|
|
901
1003
|
__shareWasiAddonCrashFlag(worker);
|
|
902
1004
|
return worker;
|
|
903
1005
|
},
|
|
@@ -990,9 +1092,9 @@ function regexpToRust(re) {
|
|
|
990
1092
|
if (re.flags.includes("i")) flags += "i";
|
|
991
1093
|
if (re.flags.includes("m")) flags += "m";
|
|
992
1094
|
if (re.flags.includes("s")) flags += "s";
|
|
993
|
-
if (!flags) return re
|
|
994
|
-
if (!flags.includes("i")) return `(?${flags})${re
|
|
995
|
-
let src = re.
|
|
1095
|
+
if (!flags) return javascriptCharacterClasses(re);
|
|
1096
|
+
if (!flags.includes("i")) return `(?${flags})${javascriptCharacterClasses(re)}`;
|
|
1097
|
+
let src = re.unicode || re.unicodeSets ? javascriptCharacterClasses(re) : javascriptLegacyCaseFolding(re);
|
|
996
1098
|
let leading = "";
|
|
997
1099
|
let trailing = "";
|
|
998
1100
|
if (src.startsWith("\\b")) {
|
|
@@ -1017,8 +1119,165 @@ function regexpToRust(re) {
|
|
|
1017
1119
|
}
|
|
1018
1120
|
}
|
|
1019
1121
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1122
|
+
return `${leading}(?${flags}:${src})${trailing}`;
|
|
1123
|
+
}
|
|
1124
|
+
const JS_WHITESPACE = "\\x{0009}-\\x{000D}\\x{0020}\\x{00A0}\\x{1680}\\x{2000}-\\x{200A}\\x{2028}\\x{2029}\\x{202F}\\x{205F}\\x{3000}\\x{FEFF}";
|
|
1125
|
+
function javascriptCharacterClasses(re) {
|
|
1126
|
+
let result = "";
|
|
1127
|
+
let classDepth = 0;
|
|
1128
|
+
const unicodeCase = re.ignoreCase && (re.unicode || re.unicodeSets);
|
|
1129
|
+
const word = "a-zA-Z0-9_" + (unicodeCase ? "\\x{017F}\\x{212A}" : "");
|
|
1130
|
+
for (let i = 0; i < re.source.length; i++) {
|
|
1131
|
+
const char = re.source.charAt(i);
|
|
1132
|
+
if (char !== "\\") {
|
|
1133
|
+
if (char === "[" && (classDepth === 0 || re.unicodeSets)) classDepth++;
|
|
1134
|
+
if (char === "]" && classDepth > 0) classDepth--;
|
|
1135
|
+
result += char;
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
const escaped = re.source.charAt(++i);
|
|
1139
|
+
if (escaped === "b" || escaped === "B") {
|
|
1140
|
+
if (classDepth > 0) {
|
|
1141
|
+
result += escaped === "b" ? "\\x{0008}" : "B";
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
if (!unicodeCase) {
|
|
1145
|
+
result += `(?-u:\\${escaped})`;
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
const beforeWord = `(?<=[${word}])`;
|
|
1149
|
+
const beforeNonword = `(?<![${word}])`;
|
|
1150
|
+
const afterWord = `(?=[${word}])`;
|
|
1151
|
+
const afterNonword = `(?![${word}])`;
|
|
1152
|
+
result += escaped === "b" ? `(?-i:(?:${beforeWord}${afterNonword}|${beforeNonword}${afterWord}))` : `(?-i:(?:${beforeWord}${afterWord}|${beforeNonword}${afterNonword}))`;
|
|
1153
|
+
continue;
|
|
1154
|
+
}
|
|
1155
|
+
let members;
|
|
1156
|
+
switch (escaped.toLowerCase()) {
|
|
1157
|
+
case "s":
|
|
1158
|
+
members = JS_WHITESPACE;
|
|
1159
|
+
break;
|
|
1160
|
+
case "d":
|
|
1161
|
+
members = "0-9";
|
|
1162
|
+
break;
|
|
1163
|
+
case "w":
|
|
1164
|
+
members = word;
|
|
1165
|
+
break;
|
|
1166
|
+
default:
|
|
1167
|
+
result += "\\" + escaped;
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
const negation = escaped === escaped.toUpperCase() ? "^" : "";
|
|
1171
|
+
result += `[${negation}${members}]`;
|
|
1172
|
+
}
|
|
1173
|
+
return result;
|
|
1174
|
+
}
|
|
1175
|
+
let legacyUnicodeFolds;
|
|
1176
|
+
/** Legacy JS folding uses one UTF-16 unit's uppercase, excluding ASCII folds. */
|
|
1177
|
+
function getLegacyUnicodeFolds() {
|
|
1178
|
+
if (legacyUnicodeFolds) return legacyUnicodeFolds;
|
|
1179
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1180
|
+
for (let code = 128; code <= 65535; code++) {
|
|
1181
|
+
const char = String.fromCharCode(code);
|
|
1182
|
+
const canonical = char.toUpperCase();
|
|
1183
|
+
if (canonical.length !== 1 || canonical === char || canonical.charCodeAt(0) < 128) continue;
|
|
1184
|
+
const members = groups.get(canonical);
|
|
1185
|
+
if (members) members.push(char);
|
|
1186
|
+
else groups.set(canonical, [canonical, char]);
|
|
1187
|
+
}
|
|
1188
|
+
legacyUnicodeFolds = groups;
|
|
1189
|
+
return groups;
|
|
1190
|
+
}
|
|
1191
|
+
function legacyLiteralPattern(literal) {
|
|
1192
|
+
if (/[a-z]/i.test(literal)) return `(?-i:[${literal.toLowerCase()}${literal.toUpperCase()}])`;
|
|
1193
|
+
const code = literal.codePointAt(0);
|
|
1194
|
+
if (code === void 0) throw new Error("Missing literal");
|
|
1195
|
+
const canonical = literal.toUpperCase();
|
|
1196
|
+
const members = canonical.length === 1 && canonical.charCodeAt(0) >= 128 ? getLegacyUnicodeFolds().get(canonical) : void 0;
|
|
1197
|
+
return members ? `(?-i:[${members.join("")}])` : `(?-i:\\x{${code.toString(16)}})`;
|
|
1198
|
+
}
|
|
1199
|
+
/** Keep legacy /i folding local so dots and complements remain Unicode-safe. */
|
|
1200
|
+
function javascriptLegacyCaseFolding(re) {
|
|
1201
|
+
let result = "";
|
|
1202
|
+
for (let i = 0; i < re.source.length; i++) {
|
|
1203
|
+
const char = re.source.charAt(i);
|
|
1204
|
+
if (char === "\\") {
|
|
1205
|
+
const escaped = re.source.charAt(++i);
|
|
1206
|
+
if ("sSwWdDbB".includes(escaped)) {
|
|
1207
|
+
const token = new RegExp("\\" + escaped, "i");
|
|
1208
|
+
result += `(?-i:${javascriptCharacterClasses(token)})`;
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
const hex = re.source.slice(i).match(/^(?:x[\da-f]{2}|u[\da-f]{4})/i)?.[0];
|
|
1212
|
+
if (hex) {
|
|
1213
|
+
const literal = String.fromCharCode(Number.parseInt(hex.slice(1), 16));
|
|
1214
|
+
result += legacyLiteralPattern(literal);
|
|
1215
|
+
i += hex.length - 1;
|
|
1216
|
+
continue;
|
|
1217
|
+
}
|
|
1218
|
+
if (escaped === "k" && re.source.charAt(i + 1) === "<") {
|
|
1219
|
+
const end = re.source.indexOf(">", i + 2);
|
|
1220
|
+
if (end !== -1) {
|
|
1221
|
+
result += re.source.slice(i - 1, end + 1);
|
|
1222
|
+
i = end;
|
|
1223
|
+
continue;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
result += "\\" + escaped;
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
if (re.source.startsWith("(?<", i) && !"=!".includes(re.source.charAt(i + 3))) {
|
|
1230
|
+
const end = re.source.indexOf(">", i + 3);
|
|
1231
|
+
if (end !== -1) {
|
|
1232
|
+
result += re.source.slice(i, end + 1);
|
|
1233
|
+
i = end;
|
|
1234
|
+
continue;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
if (char !== "[") {
|
|
1238
|
+
const code = re.source.codePointAt(i);
|
|
1239
|
+
if (code !== void 0 && code >= 128) {
|
|
1240
|
+
const literal = String.fromCodePoint(code);
|
|
1241
|
+
result += legacyLiteralPattern(literal);
|
|
1242
|
+
i += literal.length - 1;
|
|
1243
|
+
} else result += /[a-z]/i.test(char) ? legacyLiteralPattern(char) : char;
|
|
1244
|
+
continue;
|
|
1245
|
+
}
|
|
1246
|
+
const start = i;
|
|
1247
|
+
while (++i < re.source.length) {
|
|
1248
|
+
const member = re.source.charAt(i);
|
|
1249
|
+
if (member === "]") break;
|
|
1250
|
+
if (member !== "\\") continue;
|
|
1251
|
+
i++;
|
|
1252
|
+
}
|
|
1253
|
+
const original = re.source.slice(start, i + 1);
|
|
1254
|
+
let normalized = "";
|
|
1255
|
+
let previousShortcut = false;
|
|
1256
|
+
for (let j = 0; j < original.length; j++) {
|
|
1257
|
+
const member = original.charAt(j);
|
|
1258
|
+
if (member === "\\") {
|
|
1259
|
+
const escaped = original.charAt(++j);
|
|
1260
|
+
normalized += "\\" + escaped;
|
|
1261
|
+
previousShortcut = "sSwWdD".includes(escaped);
|
|
1262
|
+
continue;
|
|
1263
|
+
}
|
|
1264
|
+
const nextShortcut = original.charAt(j + 1) === "\\" && "sSwWdD".includes(original.charAt(j + 2));
|
|
1265
|
+
normalized += member === "-" && (previousShortcut || nextShortcut) ? "\\-" : member;
|
|
1266
|
+
previousShortcut = false;
|
|
1267
|
+
}
|
|
1268
|
+
const classRegexp = new RegExp(normalized, "i");
|
|
1269
|
+
const escapedNonAscii = [...normalized.matchAll(/\\(?:x([\da-f]{2})|u([\da-f]{4}))/gi)].some((match) => Number.parseInt(match[1] ?? match[2] ?? "0", 16) >= 128);
|
|
1270
|
+
const body = original.slice(original.startsWith("[^") ? 2 : 1, -1);
|
|
1271
|
+
const positive = new RegExp(`[${body}]`, "i");
|
|
1272
|
+
let folds = "";
|
|
1273
|
+
for (const letter of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") if (positive.test(letter)) folds += letter;
|
|
1274
|
+
if (hasNonAscii(original) || escapedNonAscii) {
|
|
1275
|
+
for (const [canonical, members] of getLegacyUnicodeFolds()) if (positive.test(canonical)) folds += members.join("");
|
|
1276
|
+
}
|
|
1277
|
+
const translated = javascriptCharacterClasses(classRegexp);
|
|
1278
|
+
result += `(?-i:${translated.slice(0, -1)}${folds}])`;
|
|
1279
|
+
}
|
|
1280
|
+
return result;
|
|
1022
1281
|
}
|
|
1023
1282
|
/**
|
|
1024
1283
|
* Check if content uses character class shortcuts
|
|
@@ -1029,7 +1288,12 @@ function regexpToRust(re) {
|
|
|
1029
1288
|
* -u, so skipping -u for them is zero-cost.
|
|
1030
1289
|
*/
|
|
1031
1290
|
function needsAsciiMode(s) {
|
|
1032
|
-
|
|
1291
|
+
for (let i = 0; i < s.length; i++) {
|
|
1292
|
+
if (s.charAt(i) !== "\\") continue;
|
|
1293
|
+
const escaped = s.charAt(++i);
|
|
1294
|
+
if ("wWdDsSbB".includes(escaped)) return true;
|
|
1295
|
+
}
|
|
1296
|
+
return false;
|
|
1033
1297
|
}
|
|
1034
1298
|
/**
|
|
1035
1299
|
* Check if a string contains non-ASCII characters.
|
|
@@ -1054,7 +1318,7 @@ function hasNonAscii(s) {
|
|
|
1054
1318
|
*
|
|
1055
1319
|
* NOTE: -u also disables Unicode character classes
|
|
1056
1320
|
* (\w, \d, \s become ASCII-only), matching the
|
|
1057
|
-
* behaviour of regexpToRust() for /i RegExps.
|
|
1321
|
+
* behaviour of regexpToRust() for non-Unicode /i RegExps.
|
|
1058
1322
|
*/
|
|
1059
1323
|
function scopeInlineFlags(src) {
|
|
1060
1324
|
const leadingBare = src.match(/^\(\?([ims]+)(?:-([imsu]+))?\)/);
|
|
@@ -1406,6 +1670,10 @@ var RegexSet = class {
|
|
|
1406
1670
|
get patternCount() {
|
|
1407
1671
|
return this._patternCount;
|
|
1408
1672
|
}
|
|
1673
|
+
/** Internal diagnostics: fast DFA, verified DFA, and fallback pattern counts. */
|
|
1674
|
+
_enginePathCounts() {
|
|
1675
|
+
return [...this._inner._enginePathCounts()];
|
|
1676
|
+
}
|
|
1409
1677
|
/** Returns `true` if any pattern matches. */
|
|
1410
1678
|
isMatch(haystack) {
|
|
1411
1679
|
if (this._inner._isMatchBuf(encoder.encode(haystack))) return true;
|