🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@stll/regex-set

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@stll/regex-set - npm Package Compare versions

Comparing version
1.0.1
to
1.0.2
+12
-3
dist/index.d.mts
//#region src/core.d.ts
type NativeBinding = {
RegexSet: new (patterns: string[], options?: NativeOptions | undefined | null) => NativeRegexSetInstance;
RegexSet: new (patterns: string[], options?: NativeOptions | null) => NativeRegexSetInstance;
_uax29Boundaries: (haystack: Buffer | Uint8Array) => number[];
};
type NativeOptions = {
wholeWords?: boolean | undefined;
unicodeBoundaries?: boolean | undefined;
wholeWords?: boolean;
unicodeBoundaries?: boolean;
};

@@ -103,2 +103,7 @@ type NativeRegexSetInstance = {

private _hasNames;
private _patternCount;
private _nativeIndexMap;
private _jsFallbacks;
private _nativeSingles;
private _boundaryOptions;
constructor(patterns: PatternEntry[], options?: Options);

@@ -118,2 +123,6 @@ /** Number of patterns. */

replaceAll(haystack: string, replacements: string[]): string;
private findJsFallbacks;
private findNativeSingles;
private findFirstJsFallback;
private acceptJsFallbackMatch;
}

@@ -120,0 +129,0 @@ //#endregion

+248
-27

@@ -10,3 +10,3 @@ import { createRequire } from "node:module";

};
function unpack(packed, haystack, names) {
function unpack(packed, haystack, names, indexMap) {
const len = packed.length;

@@ -19,4 +19,6 @@ const matches = new Array(len / 3);

if (idx === void 0 || s === void 0 || e === void 0) throw new Error(`Corrupt packed match data at offset ${i}`);
const pattern = indexMap ? indexMap[idx] : idx;
if (pattern === void 0) throw new Error(`Missing native index map ${idx}`);
const m = {
pattern: idx,
pattern,
start: s,

@@ -26,3 +28,3 @@ end: e,

};
if (names && names[idx] !== void 0) m.name = names[idx];
if (names && names[pattern] !== void 0) m.name = names[pattern];
matches[j] = m;

@@ -80,7 +82,7 @@ }

if (src.length >= 2) {
const last = src.charAt(src.length - 1);
const last = src.at(-1);
if (last === "b" || last === "B") {
let bs = 0;
let k = src.length - 2;
while (k >= 0 && src.charAt(k) === "\\") {
while (k >= 0 && src[k] === "\\") {
bs++;

@@ -151,7 +153,7 @@ k--;

if (rest.length >= 2) {
const last = rest.charAt(rest.length - 1);
const last = rest.at(-1);
if (last === "b" || last === "B") {
let bs = 0;
let k = rest.length - 2;
while (k >= 0 && rest.charAt(k) === "\\") {
while (k >= 0 && rest[k] === "\\") {
bs++;

@@ -231,12 +233,11 @@ k--;

};
if (typeof p === "object" && p !== null && "pattern" in p) {
if (typeof p.pattern !== "string" && !(p.pattern instanceof RegExp)) throw new TypeError(`Pattern at index ${i}: "pattern" field must be a string or RegExp`);
const inner = p.pattern instanceof RegExp ? { pattern: regexpToRust(p.pattern) } : { pattern: scopeInlineFlags(p.pattern) };
if (p.name !== void 0 && typeof p.name !== "string") throw new TypeError(`Pattern at index ${i}: "name" field must be a string`);
return {
pattern: inner.pattern,
name: p.name
};
}
throw new TypeError(`Pattern at index ${i} must be a string, RegExp, or { pattern, name }`);
if (typeof p !== "object" || p === null || !("pattern" in p)) throw new TypeError(`Pattern at index ${i} must be a string, RegExp, or { pattern, name }`);
const pattern = p.pattern;
if (typeof pattern !== "string" && !(pattern instanceof RegExp)) throw new TypeError(`Pattern at index ${i}: "pattern" field must be a string or RegExp`);
const name = "name" in p ? p.name : void 0;
if (name !== void 0 && typeof name !== "string") throw new TypeError(`Pattern at index ${i}: "name" field must be a string`);
return {
pattern: pattern instanceof RegExp ? regexpToRust(pattern) : scopeInlineFlags(pattern),
name
};
}

@@ -271,2 +272,7 @@ /**

_hasNames;
_patternCount;
_nativeIndexMap;
_jsFallbacks;
_nativeSingles;
_boundaryOptions;
constructor(patterns, options) {

@@ -276,4 +282,10 @@ const entries = patterns.map(normalizeEntry);

this._hasNames = entries.some((e) => e.name !== void 0);
this._patternCount = entries.length;
const unicode = options?.unicodeBoundaries ?? true;
const wholeWords = options?.wholeWords ?? false;
const ci = options?.caseInsensitive ?? false;
this._boundaryOptions = {
wholeWords,
unicodeBoundaries: unicode
};
let processed = entries.map((e) => e.pattern);

@@ -299,7 +311,7 @@ if (ci) processed = processed.map((p) => {

if (src.length >= 2) {
const last = src.charAt(src.length - 1);
const last = src.at(-1);
if (last === "b" || last === "B") {
let bs = 0;
let k = src.length - 2;
while (k >= 0 && src.charAt(k) === "\\") {
while (k >= 0 && src[k] === "\\") {
bs++;

@@ -319,22 +331,57 @@ k--;

const nativeOpts = options ? {
wholeWords: options.wholeWords,
unicodeBoundaries: options.unicodeBoundaries
...options.wholeWords !== void 0 ? { wholeWords: options.wholeWords } : {},
...options.unicodeBoundaries !== void 0 ? { unicodeBoundaries: options.unicodeBoundaries } : {}
} : void 0;
this._inner = new binding.RegexSet(processed, nativeOpts);
const nativePatterns = [];
this._nativeIndexMap = [];
this._jsFallbacks = [];
this._nativeSingles = [];
for (let i = 0; i < processed.length; i++) {
const pattern = processed[i];
if (pattern === void 0) throw new Error(`Missing processed pattern ${i}`);
const jsFallback = jsFallbackRegExp(pattern, unicode);
if (jsFallback) this._jsFallbacks.push({
pattern: i,
re: jsFallback
});
else {
this._nativeIndexMap.push(i);
nativePatterns.push(pattern);
}
}
this._inner = new binding.RegexSet(nativePatterns, nativeOpts);
if (this._jsFallbacks.length > 0) this._nativeSingles = nativePatterns.map((pattern, i) => {
const original = this._nativeIndexMap[i];
if (original === void 0) throw new Error(`Missing native index map ${i}`);
return {
pattern: original,
inner: new binding.RegexSet([pattern], nativeOpts)
};
});
}
/** Number of patterns. */
get patternCount() {
return this._inner.patternCount;
return this._patternCount;
}
/** Returns `true` if any pattern matches. */
isMatch(haystack) {
return this._inner._isMatchBuf(encoder.encode(haystack));
if (this._inner._isMatchBuf(encoder.encode(haystack))) return true;
for (const fb of this._jsFallbacks) if (this.findFirstJsFallback(haystack, fb)) return true;
return false;
}
/** Find all non-overlapping matches. */
findIter(haystack) {
return unpack(this._inner._findIterPackedBuf(encoder.encode(haystack)), haystack, this._hasNames ? this._names : null);
if (this._jsFallbacks.length > 0) return selectNonOverlapping(this.findNativeSingles(haystack).concat(this.findJsFallbacks(haystack)));
return unpack(this._inner._findIterPackedBuf(encoder.encode(haystack)), haystack, this._hasNames ? this._names : null, this._nativeIndexMap);
}
/** Which pattern indices matched (not where). */
whichMatch(haystack) {
return this._inner.whichMatch(haystack);
const seen = /* @__PURE__ */ new Set();
for (const pattern of this._inner.whichMatch(haystack)) {
const original = this._nativeIndexMap[pattern];
if (original === void 0) throw new Error(`Missing native index map ${pattern}`);
seen.add(original);
}
for (const fb of this._jsFallbacks) if (this.findFirstJsFallback(haystack, fb)) seen.add(fb.pattern);
return [...seen];
}

@@ -346,5 +393,179 @@ /**

replaceAll(haystack, replacements) {
return this._inner.replaceAll(haystack, replacements);
if (this._jsFallbacks.length === 0 && this._nativeIndexMap.length === this._patternCount && this._nativeIndexMap.every((idx, i) => idx === i)) return this._inner.replaceAll(haystack, replacements);
if (replacements.length !== this._patternCount) throw new Error(`Expected ${this._patternCount} replacements, got ${replacements.length}`);
const matches = this.findIter(haystack);
let result = "";
let last = 0;
for (const m of matches) {
result += haystack.slice(last, m.start);
const replacement = replacements[m.pattern];
if (replacement === void 0) throw new Error(`Missing replacement for pattern ${m.pattern}`);
result += replacement;
last = m.end;
}
result += haystack.slice(last);
return result;
}
findJsFallbacks(haystack) {
const matches = [];
for (const fb of this._jsFallbacks) {
fb.re.lastIndex = 0;
for (;;) {
const m = fb.re.exec(haystack);
if (!m) break;
const text = m[0];
const start = m.index;
const end = start + text.length;
if (this.acceptJsFallbackMatch(haystack, start, end)) {
const match = {
pattern: fb.pattern,
start,
end,
text
};
const name = this._names[fb.pattern];
if (name !== void 0) match.name = name;
matches.push(match);
if (text.length === 0) fb.re.lastIndex = nextRegexStart(haystack, start);
} else fb.re.lastIndex = nextRegexStart(haystack, start);
}
}
return matches;
}
findNativeSingles(haystack) {
const encoded = encoder.encode(haystack);
const matches = [];
for (const single of this._nativeSingles) matches.push(...unpack(single.inner._findIterPackedBuf(encoded), haystack, this._hasNames ? this._names : null, [single.pattern]));
return matches;
}
findFirstJsFallback(haystack, fb) {
fb.re.lastIndex = 0;
for (;;) {
const m = fb.re.exec(haystack);
if (!m) return false;
const text = m[0];
const start = m.index;
const end = start + text.length;
if (this.acceptJsFallbackMatch(haystack, start, end)) return true;
fb.re.lastIndex = nextRegexStart(haystack, start);
}
}
acceptJsFallbackMatch(haystack, start, end) {
if (!this._boundaryOptions.wholeWords) return true;
return isWordBoundary(haystack, start, this._boundaryOptions.unicodeBoundaries) && isWordBoundary(haystack, end, this._boundaryOptions.unicodeBoundaries);
}
};
function jsFallbackRegExp(pattern, unicodeBoundaries) {
if (!hasLookaround(pattern) || unicodeBoundaries && hasRegexWordBoundary(pattern) || hasRustUnicodeShorthand(pattern) || hasRustClassSetOperation(pattern) || countAlternations(pattern) < 128) return;
try {
return new RegExp(pattern, "gu");
} catch {
return;
}
}
function hasLookaround(pattern) {
return pattern.includes("(?=") || pattern.includes("(?!") || pattern.includes("(?<=") || pattern.includes("(?<!");
}
function countAlternations(pattern) {
let count = 0;
let inClass = false;
for (let i = 0; i < pattern.length; i++) {
const ch = pattern[i];
if (ch === "\\") {
i++;
continue;
}
if (ch === "[") inClass = true;
else if (ch === "]") inClass = false;
else if (ch === "|" && !inClass) count++;
}
return count;
}
function hasRegexWordBoundary(pattern) {
let inClass = false;
for (let i = 0; i < pattern.length; i++) {
const ch = pattern[i];
if (ch === "\\") {
const next = pattern[i + 1];
if (!inClass && (next === "b" || next === "B")) return true;
i++;
continue;
}
if (ch === "[") inClass = true;
else if (ch === "]") inClass = false;
}
return false;
}
function hasRustUnicodeShorthand(pattern) {
for (let i = 0; i < pattern.length; i++) {
if (pattern[i] !== "\\") continue;
const next = pattern[i + 1];
if (next === "d" || next === "D" || next === "w" || next === "W" || next === "s" || next === "S") return true;
i++;
}
return false;
}
function hasRustClassSetOperation(pattern) {
let inClass = false;
for (let i = 0; i < pattern.length; i++) {
const ch = pattern[i];
if (ch === "\\") {
i++;
continue;
}
if (ch === "[") {
inClass = true;
continue;
}
if (ch === "]") {
inClass = false;
continue;
}
if (inClass && i + 1 < pattern.length && (ch === "&" && pattern[i + 1] === "&" || ch === "-" && pattern[i + 1] === "-" || ch === "~" && pattern[i + 1] === "~")) return true;
}
return false;
}
function nextRegexStart(text, index) {
if (index >= text.length) return index + 1;
const first = text.charCodeAt(index);
if (first >= 55296 && first <= 56319 && index + 1 < text.length) {
const second = text.charCodeAt(index + 1);
if (second >= 56320 && second <= 57343) return index + 2;
}
return index + 1;
}
function selectNonOverlapping(matches) {
if (matches.length <= 1) return matches;
matches.sort((a, b) => {
if (a.start !== b.start) return a.start - b.start;
const lengthOrder = b.end - b.start - (a.end - a.start);
if (lengthOrder !== 0) return lengthOrder;
return a.pattern - b.pattern;
});
const selected = [];
let lastEnd = 0;
for (const m of matches) if (m.start >= lastEnd) {
selected.push(m);
lastEnd = m.end;
}
return selected;
}
function isWordBoundary(text, pos, unicode) {
const before = previousCodePoint(text, pos);
const after = nextCodePoint(text, pos);
return isWordChar(before, unicode) !== isWordChar(after, unicode);
}
function previousCodePoint(text, pos) {
if (pos <= 0) return void 0;
return Array.from(text.slice(0, pos)).at(-1);
}
function nextCodePoint(text, pos) {
if (pos >= text.length) return void 0;
const cp = text.codePointAt(pos);
return cp === void 0 ? void 0 : String.fromCodePoint(cp);
}
function isWordChar(ch, unicode) {
if (ch === void 0) return false;
return unicode ? /^[\p{Alphabetic}\p{Number}_]$/u.test(ch) : /^[A-Za-z0-9_]$/.test(ch);
}
//#endregion

@@ -351,0 +572,0 @@ //#region src/index.ts

@@ -1,1 +0,1 @@

{"version":3,"file":"index.mjs","names":[],"sources":["../src/core.ts","../src/index.ts"],"sourcesContent":["/* Shared core: types, helpers, and the RegexSet\n * class that uses a late-bound native backend\n * (NAPI-RS or WASM).\n * Call initBinding() before constructing classes. */\n\nconst encoder = new TextEncoder();\n\n// -- Native binding types --------------------------------\n\nexport type NativeBinding = {\n RegexSet: new (\n patterns: string[],\n options?: NativeOptions | undefined | null,\n ) => NativeRegexSetInstance;\n _uax29Boundaries: (haystack: Buffer | Uint8Array) => number[];\n};\n\ntype NativeOptions = {\n wholeWords?: boolean | undefined;\n unicodeBoundaries?: boolean | undefined;\n};\n\ntype NativeRegexSetInstance = {\n patternCount: number;\n isMatch(haystack: string): boolean;\n _isMatchBuf(haystack: Buffer | Uint8Array): boolean;\n _findIterPacked(haystack: string): Uint32Array;\n _findIterPackedBuf(haystack: Buffer | Uint8Array): Uint32Array;\n whichMatch(haystack: string): number[];\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string;\n};\n\n// -- Late-bound native binding ---------------------------\n\nlet binding: NativeBinding;\n\n/** Set the native backend. Must be called once\n * before any class constructor. */\nexport const initBinding = (b: NativeBinding) => {\n binding = b;\n};\n\n// -- Public types ----------------------------------------\n\n/** Options for constructing a RegexSet. */\nexport type Options = {\n /**\n * Only match whole words. Wraps each pattern\n * with `\\b...\\b`.\n * @default false\n */\n wholeWords?: boolean;\n /**\n * Use Unicode word boundaries. When `true`,\n * `\\b` treats accented letters, CJK, etc. as\n * word characters (correct for non-English text).\n * When `false` (default), `\\b` uses ASCII\n * semantics matching JS `RegExp` behavior.\n *\n * Zero performance overhead in either mode;\n * boundaries are verified inline per match.\n * Automatically uses UAX#29 segmentation for\n * Thai/CJK/Lao/Khmer/Myanmar text.\n * @default true\n */\n unicodeBoundaries?: boolean;\n /**\n * Case-insensitive matching. Wraps each pattern\n * with `(?i-u:...)` for ASCII case folding.\n * Uses `-u` to prevent DFA state explosion from\n * Unicode case tables.\n *\n * Edge `\\b`/`\\B` boundaries and leading bare-flag\n * prefixes (e.g. `(?m)`, `(?m-s)`) are extracted\n * before wrapping so they remain outside the `-u`\n * scope, preserving `unicodeBoundaries` semantics.\n * Patterns already containing any `(?{flags}-u`\n * group (from RegExp `/i`, inline `(?i)`, or\n * `scopeInlineFlags`) are not double-wrapped.\n * @default false\n */\n caseInsensitive?: boolean;\n};\n\n/** A named pattern entry. */\nexport type NamedPattern = {\n /** The regex pattern (string or RegExp). */\n pattern: string | RegExp;\n /** Optional name for this pattern. */\n name?: string;\n};\n\n/** A pattern entry: string, RegExp, or named. */\nexport type PatternEntry = string | RegExp | NamedPattern;\n\n/** A single match result. */\nexport type Match = {\n /** Index of the pattern that matched. */\n pattern: number;\n /** Start UTF-16 code unit offset. */\n start: number;\n /** End offset (exclusive). */\n end: number;\n /** The matched text. */\n text: string;\n /** Pattern name (if provided at construction). */\n name?: string;\n};\n\n// -- Unpack helper ---------------------------------------\n\nfunction unpack(\n packed: Uint32Array,\n haystack: string,\n names: (string | undefined)[] | null,\n): Match[] {\n const len = packed.length;\n // eslint-disable-next-line unicorn/no-new-array\n const matches = new Array<Match>(len / 3);\n for (let i = 0, j = 0; i < len; i += 3, j++) {\n const idx = packed[i];\n const s = packed[i + 1];\n const e = packed[i + 2];\n if (\n idx === undefined ||\n s === undefined ||\n e === undefined\n ) {\n throw new Error(\n `Corrupt packed match data at offset ${i}`,\n );\n }\n const m: Match = {\n pattern: idx,\n start: s,\n end: e,\n text: haystack.slice(s, e),\n };\n if (names && names[idx] !== undefined)\n m.name = names[idx];\n matches[j] = m;\n }\n return matches;\n}\n\n// -- Regex flag helpers ----------------------------------\n\n/**\n * Replace unescaped `\\b` and `\\B` with their\n * ASCII-only equivalents `(?-u:\\b)` / `(?-u:\\B)`.\n * Skips character classes `[...]` (where `\\b` means\n * backspace) and escaped backslashes `\\\\b`.\n */\nfunction asciiBoundaries(src: string): string {\n let result = \"\";\n let inClass = false;\n let i = 0;\n while (i < src.length) {\n if (src.charAt(i) === \"\\\\\" && i + 1 < src.length) {\n const next = src.charAt(i + 1);\n if (!inClass && (next === \"b\" || next === \"B\")) {\n result += `(?-u:\\\\${next})`;\n i += 2;\n } else {\n // escaped char (including \\\\) -- emit as-is\n result += src.charAt(i) + src.charAt(i + 1);\n i += 2;\n }\n } else {\n if (src.charAt(i) === \"[\") inClass = true;\n if (src.charAt(i) === \"]\") inClass = false;\n result += src.charAt(i);\n i++;\n }\n }\n return result;\n}\n\n/**\n * Convert a RegExp to Rust regex syntax string.\n */\nfunction regexpToRust(re: RegExp): string {\n let flags = \"\";\n if (re.flags.includes(\"i\")) flags += \"i\";\n if (re.flags.includes(\"m\")) flags += \"m\";\n if (re.flags.includes(\"s\")) flags += \"s\";\n\n // JS RegExp objects can't contain inline (?i) in\n // .source -- it's a SyntaxError. No need to run\n // scopeInlineFlags here; it only matters for\n // string patterns (handled in normalizeEntry).\n if (!flags) {\n return re.source;\n }\n\n if (!flags.includes(\"i\")) {\n return `(?${flags})${re.source}`;\n }\n\n let src = re.source;\n let leading = \"\";\n let trailing = \"\";\n\n if (src.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n src = src.slice(2);\n } else if (src.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n src = src.slice(2);\n }\n if (src.length >= 2) {\n const last = src.charAt(src.length - 1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = src.length - 2;\n while (k >= 0 && src.charAt(k) === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n src = src.slice(0, -2);\n }\n }\n }\n\n const uFlag =\n needsAsciiMode(src) && !hasNonAscii(src) ? \"-u\" : \"\";\n return `${leading}(?${flags}${uFlag}:${src})${trailing}`;\n}\n\n/**\n * Check if content uses character class shortcuts\n * (\\w, \\W, \\d, \\D, \\s, \\S, \\b, \\B) that have\n * Unicode-aware versions. Only these benefit from\n * -u (ASCII-only mode). Literal strings like\n * \"dollars\" produce identical DFAs with or without\n * -u, so skipping -u for them is zero-cost.\n */\nfunction needsAsciiMode(s: string): boolean {\n return /\\\\[wWdDsSbB]/.test(s);\n}\n\n/**\n * Check if a string contains non-ASCII characters.\n * When true, -u MUST NOT be added: regex-automata\n * rejects (?-u) alongside non-ASCII content like\n * [ACDE] or literal zlotych.\n */\nfunction hasNonAscii(s: string): boolean {\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) > 127) return true;\n }\n return false;\n}\n\n/**\n * Convert inline (?i) flags to (?i-u) for ASCII\n * case folding. Handles bare and scoped groups.\n *\n * Bare (?i) at the start of a pattern is converted\n * to a scoped group (?i-u:...) with edge \\b pulled\n * outside, matching the RegExp path behaviour. This\n * prevents -u from affecting \\b word boundary\n * semantics (which should remain Unicode when\n * unicodeBoundaries is true).\n *\n * NOTE: -u also disables Unicode character classes\n * (\\w, \\d, \\s become ASCII-only), matching the\n * behaviour of regexpToRust() for /i RegExps.\n */\nfunction scopeInlineFlags(src: string): string {\n // Handle bare (?i...) at the start: convert to\n // scoped (?i-u:...) with edge \\b/\\B outside.\n const leadingBare = src.match(\n /^\\(\\?([ims]+)(?:-([imsu]+))?\\)/,\n );\n const enableGroup = leadingBare?.[1];\n if (leadingBare && enableGroup?.includes(\"i\")) {\n const enable = enableGroup;\n const disable = leadingBare[2] ?? \"\";\n let rest = src.slice(leadingBare[0].length);\n\n // Strip edge \\b/\\B\n let leading = \"\";\n let trailing = \"\";\n if (rest.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n rest = rest.slice(2);\n } else if (rest.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n rest = rest.slice(2);\n }\n if (rest.length >= 2) {\n const last = rest.charAt(rest.length - 1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = rest.length - 2;\n while (k >= 0 && rest.charAt(k) === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n rest = rest.slice(0, -2);\n }\n }\n }\n\n // Scope the flags and recurse for any nested\n // inline flags in the content.\n const inner = scopeInnerFlags(rest);\n // Only add -u when content uses char class\n // shortcuts (\\w, \\d, \\s) that benefit from it.\n const addU =\n needsAsciiMode(rest) &&\n !hasNonAscii(rest) &&\n !disable.includes(\"u\");\n const merged = addU ? disable + \"u\" : disable;\n const disablePart = merged ? `-${merged}` : \"\";\n return `${leading}(?${enable}${disablePart}:${inner})${trailing}`;\n }\n\n return scopeInnerFlags(src);\n}\n\n/**\n * Replace inline (?i) / (?i:...) groups with -u\n * variants. Does not handle leading bare flags\n * (that's done by scopeInlineFlags above).\n */\nfunction scopeInnerFlags(src: string): string {\n let result = \"\";\n let inClass = false;\n let i = 0;\n while (i < src.length) {\n if (src[i] === \"\\\\\" && i + 1 < src.length) {\n result += src.charAt(i) + src.charAt(i + 1);\n i += 2;\n continue;\n }\n if (src.charAt(i) === \"[\") inClass = true;\n if (src.charAt(i) === \"]\") inClass = false;\n if (\n !inClass &&\n src.charAt(i) === \"(\" &&\n src.charAt(i + 1) === \"?\"\n ) {\n let j = i + 2;\n let enable = \"\";\n while (\n j < src.length &&\n \"ims\".includes(src.charAt(j))\n ) {\n enable += src.charAt(j);\n j++;\n }\n // Handle disable part: (?i-s) or (?i-s:...)\n let disable = \"\";\n if (j < src.length && src.charAt(j) === \"-\") {\n j++; // skip -\n while (\n j < src.length &&\n \"imsu\".includes(src.charAt(j))\n ) {\n disable += src.charAt(j);\n j++;\n }\n }\n if (\n enable.length > 0 &&\n (src.charAt(j) === \")\" || src.charAt(j) === \":\")\n ) {\n if (enable.includes(\"i\")) {\n // For scoped groups (?i:content), don't add\n // -u: literal strings produce identical DFAs\n // with or without -u, and -u breaks when\n // the overall pattern has non-ASCII chars.\n // For bare flags (?i), the -u would apply to\n // the rest of the pattern which might have\n // \\w/\\d -- but bare flags are handled by\n // scopeInlineFlags, not here.\n if (disable.length > 0) {\n result += `(?${enable}-${disable}${src.charAt(j)}`;\n } else {\n result += `(?${enable}${src.charAt(j)}`;\n }\n } else if (disable.length > 0) {\n result += `(?${enable}-${disable}${src.charAt(j)}`;\n } else {\n result += `(?${enable}${src.charAt(j)}`;\n }\n i = j + 1;\n continue;\n }\n }\n result += src.charAt(i);\n i++;\n }\n return result;\n}\n\n// -- Pattern normalization -------------------------------\n\ntype NormalizedEntry = {\n pattern: string;\n name: string | undefined;\n};\n\n/**\n * Normalize a pattern entry to { pattern, name }.\n */\nfunction normalizeEntry(\n p: PatternEntry,\n i: number,\n): NormalizedEntry {\n if (typeof p === \"string\") {\n return {\n pattern: scopeInlineFlags(p),\n name: undefined,\n };\n }\n if (p instanceof RegExp) {\n return {\n pattern: regexpToRust(p),\n name: undefined,\n };\n }\n if (\n typeof p === \"object\" &&\n p !== null &&\n \"pattern\" in p\n ) {\n if (\n typeof p.pattern !== \"string\" &&\n !(p.pattern instanceof RegExp)\n ) {\n throw new TypeError(\n `Pattern at index ${i}: \"pattern\" ` +\n \"field must be a string or RegExp\",\n );\n }\n const inner =\n p.pattern instanceof RegExp\n ? { pattern: regexpToRust(p.pattern) }\n : {\n pattern: scopeInlineFlags(p.pattern),\n };\n if (\n p.name !== undefined &&\n typeof p.name !== \"string\"\n ) {\n throw new TypeError(\n `Pattern at index ${i}: \"name\" ` +\n \"field must be a string\",\n );\n }\n return {\n pattern: inner.pattern,\n name: p.name,\n };\n }\n throw new TypeError(\n `Pattern at index ${i} must be a string, ` +\n \"RegExp, or { pattern, name }\",\n );\n}\n\n// -- RegexSet class --------------------------------------\n\n/**\n * Multi-pattern regex matcher.\n *\n * Compiles multiple regex patterns into a single\n * automaton for the main matching path. Standard\n * scans use Rust's DFA engine without catastrophic\n * backtracking. Some lookaround cases may use a\n * targeted fallback verifier to preserve\n * correctness. Uses Rust regex syntax for string\n * patterns (no lookaheads/backreferences).\n *\n * @example\n * ```ts\n * // Simple\n * new RegexSet([/\\d{8}/, \"\\\\+?\\\\d{9,12}\"]);\n *\n * // Named\n * new RegexSet([\n * { pattern: /\\d{8}/, name: \"ico\" },\n * { pattern: /\\d{2}\\.\\d{2}\\.\\d{4}/, name: \"date\" },\n * ]);\n * // match.name === \"date\"\n * ```\n */\nexport class RegexSet {\n private _inner: NativeRegexSetInstance;\n private _names: (string | undefined)[];\n private _hasNames: boolean;\n\n constructor(patterns: PatternEntry[], options?: Options) {\n const entries = patterns.map(normalizeEntry);\n this._names = entries.map((e) => e.name);\n this._hasNames = entries.some(\n (e) => e.name !== undefined,\n );\n\n const unicode = options?.unicodeBoundaries ?? true;\n const ci = options?.caseInsensitive ?? false;\n\n let processed = entries.map((e) => e.pattern);\n\n // Wrap with (?i-u:...) for case-insensitive\n // matching. Edge \\b/\\B are extracted first so\n // they stay outside the -u scope (preserving\n // Unicode word boundary semantics).\n if (ci) {\n processed = processed.map((p) => {\n // Skip patterns already wrapped by\n // regexpToRust or scopeInlineFlags.\n if (\n /^(?:\\\\[bB]|\\(\\?[ims]+(?:-[imsu]+)?\\))*\\(\\?[ims]*i[ims]*(?:-[imsu]+)?[:(]/.test(\n p,\n )\n )\n return p;\n // Strip leading bare-flag prefix (e.g. (?m),\n // (?ms)) before extracting edge \\b.\n let src = p;\n let flagPrefix = \"\";\n const bareFlagMatch = src.match(\n /^\\(\\?[ims]+(?:-[imsu]+)?\\)/,\n );\n if (bareFlagMatch) {\n flagPrefix = bareFlagMatch[0];\n src = src.slice(flagPrefix.length);\n }\n // Extract edge \\b/\\B\n let leading = \"\";\n let trailing = \"\";\n if (src.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n src = src.slice(2);\n } else if (src.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n src = src.slice(2);\n }\n if (src.length >= 2) {\n const last = src.charAt(src.length - 1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = src.length - 2;\n while (k >= 0 && src.charAt(k) === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n src = src.slice(0, -2);\n }\n }\n }\n const uFlag =\n needsAsciiMode(src) && !hasNonAscii(src)\n ? \"-u\"\n : \"\";\n return `${flagPrefix}${leading}(?i${uFlag}:${src})${trailing}`;\n });\n }\n\n if (!unicode) {\n processed = processed.map(asciiBoundaries);\n }\n\n // Strip JS-only options before passing to native\n const nativeOpts: NativeOptions | undefined = options\n ? {\n wholeWords: options.wholeWords,\n unicodeBoundaries: options.unicodeBoundaries,\n }\n : undefined;\n\n this._inner = new binding.RegexSet(\n processed,\n nativeOpts,\n );\n }\n\n /** Number of patterns. */\n get patternCount(): number {\n return this._inner.patternCount;\n }\n\n /** Returns `true` if any pattern matches. */\n isMatch(haystack: string): boolean {\n return this._inner._isMatchBuf(encoder.encode(haystack));\n }\n\n /** Find all non-overlapping matches. */\n findIter(haystack: string): Match[] {\n return unpack(\n this._inner._findIterPackedBuf(encoder.encode(haystack)),\n haystack,\n this._hasNames ? this._names : null,\n );\n }\n\n /** Which pattern indices matched (not where). */\n whichMatch(haystack: string): number[] {\n return this._inner.whichMatch(haystack);\n }\n\n /**\n * Replace all non-overlapping matches.\n * `replacements[i]` replaces pattern `i`.\n */\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string {\n return this._inner.replaceAll(haystack, replacements);\n }\n}\n","/* Main entry point -- loads the native NAPI-RS\n * binding and re-exports the public API. */\n\nimport { createRequire } from \"node:module\";\n\nimport { initBinding, type NativeBinding } from \"./core\";\n\nconst require = createRequire(import.meta.url);\n// SAFETY: NAPI-RS auto-generated loader returns the\n// native binding object; its shape is validated by\n// usage in the core classes.\nconst native = require(\"../index.cjs\") as NativeBinding;\n\ninitBinding(native);\n\nexport { RegexSet } from \"./core\";\n\nexport type {\n Match,\n NamedPattern,\n NativeBinding,\n Options,\n PatternEntry,\n} from \"./core\";\n"],"mappings":"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"}
{"version":3,"file":"index.mjs","names":[],"sources":["../src/core.ts","../src/index.ts"],"sourcesContent":["/* Shared core: types, helpers, and the RegexSet\n * class that uses a late-bound native backend\n * (NAPI-RS or WASM).\n * Call initBinding() before constructing classes. */\n\nconst encoder = new TextEncoder();\n\n// -- Native binding types --------------------------------\n\nexport type NativeBinding = {\n RegexSet: new (\n patterns: string[],\n options?: NativeOptions | null,\n ) => NativeRegexSetInstance;\n _uax29Boundaries: (haystack: Buffer | Uint8Array) => number[];\n};\n\ntype NativeOptions = {\n wholeWords?: boolean;\n unicodeBoundaries?: boolean;\n};\n\ntype NativeRegexSetInstance = {\n patternCount: number;\n isMatch(haystack: string): boolean;\n _isMatchBuf(haystack: Buffer | Uint8Array): boolean;\n _findIterPacked(haystack: string): Uint32Array;\n _findIterPackedBuf(haystack: Buffer | Uint8Array): Uint32Array;\n whichMatch(haystack: string): number[];\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string;\n};\n\ntype JsFallback = {\n pattern: number;\n re: RegExp;\n};\n\ntype NativeSingle = {\n pattern: number;\n inner: NativeRegexSetInstance;\n};\n\ntype BoundaryOptions = {\n wholeWords: boolean;\n unicodeBoundaries: boolean;\n};\n\n// -- Late-bound native binding ---------------------------\n\nlet binding: NativeBinding;\n\n/** Set the native backend. Must be called once\n * before any class constructor. */\nexport const initBinding = (b: NativeBinding) => {\n binding = b;\n};\n\n// -- Public types ----------------------------------------\n\n/** Options for constructing a RegexSet. */\nexport type Options = {\n /**\n * Only match whole words. Wraps each pattern\n * with `\\b...\\b`.\n * @default false\n */\n wholeWords?: boolean;\n /**\n * Use Unicode word boundaries. When `true`,\n * `\\b` treats accented letters, CJK, etc. as\n * word characters (correct for non-English text).\n * When `false` (default), `\\b` uses ASCII\n * semantics matching JS `RegExp` behavior.\n *\n * Zero performance overhead in either mode;\n * boundaries are verified inline per match.\n * Automatically uses UAX#29 segmentation for\n * Thai/CJK/Lao/Khmer/Myanmar text.\n * @default true\n */\n unicodeBoundaries?: boolean;\n /**\n * Case-insensitive matching. Wraps each pattern\n * with `(?i-u:...)` for ASCII case folding.\n * Uses `-u` to prevent DFA state explosion from\n * Unicode case tables.\n *\n * Edge `\\b`/`\\B` boundaries and leading bare-flag\n * prefixes (e.g. `(?m)`, `(?m-s)`) are extracted\n * before wrapping so they remain outside the `-u`\n * scope, preserving `unicodeBoundaries` semantics.\n * Patterns already containing any `(?{flags}-u`\n * group (from RegExp `/i`, inline `(?i)`, or\n * `scopeInlineFlags`) are not double-wrapped.\n * @default false\n */\n caseInsensitive?: boolean;\n};\n\n/** A named pattern entry. */\nexport type NamedPattern = {\n /** The regex pattern (string or RegExp). */\n pattern: string | RegExp;\n /** Optional name for this pattern. */\n name?: string;\n};\n\n/** A pattern entry: string, RegExp, or named. */\nexport type PatternEntry = string | RegExp | NamedPattern;\n\n/** A single match result. */\nexport type Match = {\n /** Index of the pattern that matched. */\n pattern: number;\n /** Start UTF-16 code unit offset. */\n start: number;\n /** End offset (exclusive). */\n end: number;\n /** The matched text. */\n text: string;\n /** Pattern name (if provided at construction). */\n name?: string;\n};\n\n// -- Unpack helper ---------------------------------------\n\nfunction unpack(\n packed: Uint32Array,\n haystack: string,\n names: (string | undefined)[] | null,\n indexMap?: number[],\n): Match[] {\n const len = packed.length;\n // eslint-disable-next-line unicorn/no-new-array\n const matches = new Array<Match>(len / 3);\n for (let i = 0, j = 0; i < len; i += 3, j++) {\n const idx = packed[i];\n const s = packed[i + 1];\n const e = packed[i + 2];\n if (\n idx === undefined ||\n s === undefined ||\n e === undefined\n ) {\n throw new Error(\n `Corrupt packed match data at offset ${i}`,\n );\n }\n const pattern = indexMap ? indexMap[idx] : idx;\n if (pattern === undefined) {\n throw new Error(`Missing native index map ${idx}`);\n }\n const m: Match = {\n pattern,\n start: s,\n end: e,\n text: haystack.slice(s, e),\n };\n if (names && names[pattern] !== undefined)\n m.name = names[pattern];\n matches[j] = m;\n }\n return matches;\n}\n\n// -- Regex flag helpers ----------------------------------\n\n/**\n * Replace unescaped `\\b` and `\\B` with their\n * ASCII-only equivalents `(?-u:\\b)` / `(?-u:\\B)`.\n * Skips character classes `[...]` (where `\\b` means\n * backspace) and escaped backslashes `\\\\b`.\n */\nfunction asciiBoundaries(src: string): string {\n let result = \"\";\n let inClass = false;\n let i = 0;\n while (i < src.length) {\n if (src.charAt(i) === \"\\\\\" && i + 1 < src.length) {\n const next = src.charAt(i + 1);\n if (!inClass && (next === \"b\" || next === \"B\")) {\n result += `(?-u:\\\\${next})`;\n i += 2;\n } else {\n // escaped char (including \\\\) -- emit as-is\n result += src.charAt(i) + src.charAt(i + 1);\n i += 2;\n }\n } else {\n if (src.charAt(i) === \"[\") inClass = true;\n if (src.charAt(i) === \"]\") inClass = false;\n result += src.charAt(i);\n i++;\n }\n }\n return result;\n}\n\n/**\n * Convert a RegExp to Rust regex syntax string.\n */\nfunction regexpToRust(re: RegExp): string {\n let flags = \"\";\n if (re.flags.includes(\"i\")) flags += \"i\";\n if (re.flags.includes(\"m\")) flags += \"m\";\n if (re.flags.includes(\"s\")) flags += \"s\";\n\n // JS RegExp objects can't contain inline (?i) in\n // .source -- it's a SyntaxError. No need to run\n // scopeInlineFlags here; it only matters for\n // string patterns (handled in normalizeEntry).\n if (!flags) {\n return re.source;\n }\n\n if (!flags.includes(\"i\")) {\n return `(?${flags})${re.source}`;\n }\n\n let src = re.source;\n let leading = \"\";\n let trailing = \"\";\n\n if (src.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n src = src.slice(2);\n } else if (src.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n src = src.slice(2);\n }\n if (src.length >= 2) {\n const last = src.at(-1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = src.length - 2;\n while (k >= 0 && src[k] === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n src = src.slice(0, -2);\n }\n }\n }\n\n const uFlag =\n needsAsciiMode(src) && !hasNonAscii(src) ? \"-u\" : \"\";\n return `${leading}(?${flags}${uFlag}:${src})${trailing}`;\n}\n\n/**\n * Check if content uses character class shortcuts\n * (\\w, \\W, \\d, \\D, \\s, \\S, \\b, \\B) that have\n * Unicode-aware versions. Only these benefit from\n * -u (ASCII-only mode). Literal strings like\n * \"dollars\" produce identical DFAs with or without\n * -u, so skipping -u for them is zero-cost.\n */\nfunction needsAsciiMode(s: string): boolean {\n return /\\\\[wWdDsSbB]/.test(s);\n}\n\n/**\n * Check if a string contains non-ASCII characters.\n * When true, -u MUST NOT be added: regex-automata\n * rejects (?-u) alongside non-ASCII content like\n * [ACDE] or literal zlotych.\n */\nfunction hasNonAscii(s: string): boolean {\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) > 127) return true;\n }\n return false;\n}\n\n/**\n * Convert inline (?i) flags to (?i-u) for ASCII\n * case folding. Handles bare and scoped groups.\n *\n * Bare (?i) at the start of a pattern is converted\n * to a scoped group (?i-u:...) with edge \\b pulled\n * outside, matching the RegExp path behaviour. This\n * prevents -u from affecting \\b word boundary\n * semantics (which should remain Unicode when\n * unicodeBoundaries is true).\n *\n * NOTE: -u also disables Unicode character classes\n * (\\w, \\d, \\s become ASCII-only), matching the\n * behaviour of regexpToRust() for /i RegExps.\n */\nfunction scopeInlineFlags(src: string): string {\n // Handle bare (?i...) at the start: convert to\n // scoped (?i-u:...) with edge \\b/\\B outside.\n const leadingBare = src.match(\n /^\\(\\?([ims]+)(?:-([imsu]+))?\\)/,\n );\n const enableGroup = leadingBare?.[1];\n if (leadingBare && enableGroup?.includes(\"i\")) {\n const enable = enableGroup;\n const disable = leadingBare[2] ?? \"\";\n let rest = src.slice(leadingBare[0].length);\n\n // Strip edge \\b/\\B\n let leading = \"\";\n let trailing = \"\";\n if (rest.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n rest = rest.slice(2);\n } else if (rest.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n rest = rest.slice(2);\n }\n if (rest.length >= 2) {\n const last = rest.at(-1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = rest.length - 2;\n while (k >= 0 && rest[k] === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n rest = rest.slice(0, -2);\n }\n }\n }\n\n // Scope the flags and recurse for any nested\n // inline flags in the content.\n const inner = scopeInnerFlags(rest);\n // Only add -u when content uses char class\n // shortcuts (\\w, \\d, \\s) that benefit from it.\n const addU =\n needsAsciiMode(rest) &&\n !hasNonAscii(rest) &&\n !disable.includes(\"u\");\n const merged = addU ? disable + \"u\" : disable;\n const disablePart = merged ? `-${merged}` : \"\";\n return `${leading}(?${enable}${disablePart}:${inner})${trailing}`;\n }\n\n return scopeInnerFlags(src);\n}\n\n/**\n * Replace inline (?i) / (?i:...) groups with -u\n * variants. Does not handle leading bare flags\n * (that's done by scopeInlineFlags above).\n */\nfunction scopeInnerFlags(src: string): string {\n let result = \"\";\n let inClass = false;\n let i = 0;\n while (i < src.length) {\n if (src[i] === \"\\\\\" && i + 1 < src.length) {\n result += src.charAt(i) + src.charAt(i + 1);\n i += 2;\n continue;\n }\n if (src.charAt(i) === \"[\") inClass = true;\n if (src.charAt(i) === \"]\") inClass = false;\n if (\n !inClass &&\n src.charAt(i) === \"(\" &&\n src.charAt(i + 1) === \"?\"\n ) {\n let j = i + 2;\n let enable = \"\";\n while (\n j < src.length &&\n \"ims\".includes(src.charAt(j))\n ) {\n enable += src.charAt(j);\n j++;\n }\n // Handle disable part: (?i-s) or (?i-s:...)\n let disable = \"\";\n if (j < src.length && src.charAt(j) === \"-\") {\n j++; // skip -\n while (\n j < src.length &&\n \"imsu\".includes(src.charAt(j))\n ) {\n disable += src.charAt(j);\n j++;\n }\n }\n if (\n enable.length > 0 &&\n (src.charAt(j) === \")\" || src.charAt(j) === \":\")\n ) {\n if (enable.includes(\"i\")) {\n // For scoped groups (?i:content), don't add\n // -u: literal strings produce identical DFAs\n // with or without -u, and -u breaks when\n // the overall pattern has non-ASCII chars.\n // For bare flags (?i), the -u would apply to\n // the rest of the pattern which might have\n // \\w/\\d -- but bare flags are handled by\n // scopeInlineFlags, not here.\n if (disable.length > 0) {\n result += `(?${enable}-${disable}${src.charAt(j)}`;\n } else {\n result += `(?${enable}${src.charAt(j)}`;\n }\n } else if (disable.length > 0) {\n result += `(?${enable}-${disable}${src.charAt(j)}`;\n } else {\n result += `(?${enable}${src.charAt(j)}`;\n }\n i = j + 1;\n continue;\n }\n }\n result += src.charAt(i);\n i++;\n }\n return result;\n}\n\n// -- Pattern normalization -------------------------------\n\ntype NormalizedEntry = {\n pattern: string;\n name: string | undefined;\n};\n\n/**\n * Normalize a pattern entry to { pattern, name }.\n */\nfunction normalizeEntry(\n p: unknown,\n i: number,\n): NormalizedEntry {\n if (typeof p === \"string\") {\n return {\n pattern: scopeInlineFlags(p),\n name: undefined,\n };\n }\n if (p instanceof RegExp) {\n return {\n pattern: regexpToRust(p),\n name: undefined,\n };\n }\n if (typeof p !== \"object\" || p === null || !(\"pattern\" in p)) {\n throw new TypeError(\n `Pattern at index ${i} must be a string, ` +\n \"RegExp, or { pattern, name }\",\n );\n }\n\n const pattern = p.pattern;\n if (\n typeof pattern !== \"string\" &&\n !(pattern instanceof RegExp)\n ) {\n throw new TypeError(\n `Pattern at index ${i}: \"pattern\" ` +\n \"field must be a string or RegExp\",\n );\n }\n\n const name = \"name\" in p ? p.name : undefined;\n if (name !== undefined && typeof name !== \"string\") {\n throw new TypeError(\n `Pattern at index ${i}: \"name\" ` +\n \"field must be a string\",\n );\n }\n\n return {\n pattern:\n pattern instanceof RegExp\n ? regexpToRust(pattern)\n : scopeInlineFlags(pattern),\n name,\n };\n}\n\n// -- RegexSet class --------------------------------------\n\n/**\n * Multi-pattern regex matcher.\n *\n * Compiles multiple regex patterns into a single\n * automaton for the main matching path. Standard\n * scans use Rust's DFA engine without catastrophic\n * backtracking. Some lookaround cases may use a\n * targeted fallback verifier to preserve\n * correctness. Uses Rust regex syntax for string\n * patterns (no lookaheads/backreferences).\n *\n * @example\n * ```ts\n * // Simple\n * new RegexSet([/\\d{8}/, \"\\\\+?\\\\d{9,12}\"]);\n *\n * // Named\n * new RegexSet([\n * { pattern: /\\d{8}/, name: \"ico\" },\n * { pattern: /\\d{2}\\.\\d{2}\\.\\d{4}/, name: \"date\" },\n * ]);\n * // match.name === \"date\"\n * ```\n */\nexport class RegexSet {\n private _inner: NativeRegexSetInstance;\n private _names: (string | undefined)[];\n private _hasNames: boolean;\n private _patternCount: number;\n private _nativeIndexMap: number[];\n private _jsFallbacks: JsFallback[];\n private _nativeSingles: NativeSingle[];\n private _boundaryOptions: BoundaryOptions;\n\n constructor(patterns: PatternEntry[], options?: Options) {\n const entries = patterns.map(normalizeEntry);\n this._names = entries.map((e) => e.name);\n this._hasNames = entries.some(\n (e) => e.name !== undefined,\n );\n this._patternCount = entries.length;\n\n const unicode = options?.unicodeBoundaries ?? true;\n const wholeWords = options?.wholeWords ?? false;\n const ci = options?.caseInsensitive ?? false;\n this._boundaryOptions = {\n wholeWords,\n unicodeBoundaries: unicode,\n };\n\n let processed = entries.map((e) => e.pattern);\n\n // Wrap with (?i-u:...) for case-insensitive\n // matching. Edge \\b/\\B are extracted first so\n // they stay outside the -u scope (preserving\n // Unicode word boundary semantics).\n if (ci) {\n processed = processed.map((p) => {\n // Skip patterns already wrapped by\n // regexpToRust or scopeInlineFlags.\n if (\n /^(?:\\\\[bB]|\\(\\?[ims]+(?:-[imsu]+)?\\))*\\(\\?[ims]*i[ims]*(?:-[imsu]+)?[:(]/.test(\n p,\n )\n )\n return p;\n // Strip leading bare-flag prefix (e.g. (?m),\n // (?ms)) before extracting edge \\b.\n let src = p;\n let flagPrefix = \"\";\n const bareFlagMatch = src.match(\n /^\\(\\?[ims]+(?:-[imsu]+)?\\)/,\n );\n if (bareFlagMatch) {\n flagPrefix = bareFlagMatch[0];\n src = src.slice(flagPrefix.length);\n }\n // Extract edge \\b/\\B\n let leading = \"\";\n let trailing = \"\";\n if (src.startsWith(\"\\\\b\")) {\n leading = \"\\\\b\";\n src = src.slice(2);\n } else if (src.startsWith(\"\\\\B\")) {\n leading = \"\\\\B\";\n src = src.slice(2);\n }\n if (src.length >= 2) {\n const last = src.at(-1);\n if (last === \"b\" || last === \"B\") {\n let bs = 0;\n let k = src.length - 2;\n while (k >= 0 && src[k] === \"\\\\\") {\n bs++;\n k--;\n }\n if (bs > 0 && bs % 2 === 1) {\n trailing = \"\\\\\" + last;\n src = src.slice(0, -2);\n }\n }\n }\n const uFlag =\n needsAsciiMode(src) && !hasNonAscii(src)\n ? \"-u\"\n : \"\";\n return `${flagPrefix}${leading}(?i${uFlag}:${src})${trailing}`;\n });\n }\n\n if (!unicode) {\n processed = processed.map(asciiBoundaries);\n }\n\n // Strip JS-only options before passing to native\n const nativeOpts: NativeOptions | undefined = options\n ? {\n ...(options.wholeWords !== undefined\n ? { wholeWords: options.wholeWords }\n : {}),\n ...(options.unicodeBoundaries !== undefined\n ? { unicodeBoundaries: options.unicodeBoundaries }\n : {}),\n }\n : undefined;\n\n const nativePatterns: string[] = [];\n this._nativeIndexMap = [];\n this._jsFallbacks = [];\n this._nativeSingles = [];\n\n for (let i = 0; i < processed.length; i++) {\n const pattern = processed[i];\n if (pattern === undefined) {\n throw new Error(`Missing processed pattern ${i}`);\n }\n const jsFallback = jsFallbackRegExp(pattern, unicode);\n if (jsFallback) {\n this._jsFallbacks.push({\n pattern: i,\n re: jsFallback,\n });\n } else {\n this._nativeIndexMap.push(i);\n nativePatterns.push(pattern);\n }\n }\n\n this._inner = new binding.RegexSet(nativePatterns, nativeOpts);\n if (this._jsFallbacks.length > 0) {\n this._nativeSingles = nativePatterns.map((pattern, i) => {\n const original = this._nativeIndexMap[i];\n if (original === undefined) {\n throw new Error(`Missing native index map ${i}`);\n }\n return {\n pattern: original,\n inner: new binding.RegexSet([pattern], nativeOpts),\n };\n });\n }\n }\n\n /** Number of patterns. */\n get patternCount(): number {\n return this._patternCount;\n }\n\n /** Returns `true` if any pattern matches. */\n isMatch(haystack: string): boolean {\n if (this._inner._isMatchBuf(encoder.encode(haystack))) {\n return true;\n }\n for (const fb of this._jsFallbacks) {\n if (this.findFirstJsFallback(haystack, fb)) return true;\n }\n return false;\n }\n\n /** Find all non-overlapping matches. */\n findIter(haystack: string): Match[] {\n if (this._jsFallbacks.length > 0) {\n const all = this.findNativeSingles(haystack).concat(\n this.findJsFallbacks(haystack),\n );\n return selectNonOverlapping(all);\n }\n\n const native = unpack(\n this._inner._findIterPackedBuf(encoder.encode(haystack)),\n haystack,\n this._hasNames ? this._names : null,\n this._nativeIndexMap,\n );\n return native;\n }\n\n /** Which pattern indices matched (not where). */\n whichMatch(haystack: string): number[] {\n const seen = new Set<number>();\n for (const pattern of this._inner.whichMatch(haystack)) {\n const original = this._nativeIndexMap[pattern];\n if (original === undefined) {\n throw new Error(`Missing native index map ${pattern}`);\n }\n seen.add(original);\n }\n for (const fb of this._jsFallbacks) {\n if (this.findFirstJsFallback(haystack, fb)) {\n seen.add(fb.pattern);\n }\n }\n return [...seen];\n }\n\n /**\n * Replace all non-overlapping matches.\n * `replacements[i]` replaces pattern `i`.\n */\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string {\n if (\n this._jsFallbacks.length === 0 &&\n this._nativeIndexMap.length === this._patternCount &&\n this._nativeIndexMap.every((idx, i) => idx === i)\n ) {\n return this._inner.replaceAll(haystack, replacements);\n }\n if (replacements.length !== this._patternCount) {\n throw new Error(\n `Expected ${this._patternCount} ` +\n `replacements, got ${replacements.length}`,\n );\n }\n\n const matches = this.findIter(haystack);\n let result = \"\";\n let last = 0;\n\n for (const m of matches) {\n result += haystack.slice(last, m.start);\n const replacement = replacements[m.pattern];\n if (replacement === undefined) {\n throw new Error(\n `Missing replacement for pattern ${m.pattern}`,\n );\n }\n result += replacement;\n last = m.end;\n }\n\n result += haystack.slice(last);\n return result;\n }\n\n private findJsFallbacks(haystack: string): Match[] {\n const matches: Match[] = [];\n for (const fb of this._jsFallbacks) {\n fb.re.lastIndex = 0;\n for (;;) {\n const m = fb.re.exec(haystack);\n if (!m) break;\n const text = m[0];\n const start = m.index;\n const end = start + text.length;\n if (this.acceptJsFallbackMatch(haystack, start, end)) {\n const match: Match = {\n pattern: fb.pattern,\n start,\n end,\n text,\n };\n const name = this._names[fb.pattern];\n if (name !== undefined) match.name = name;\n matches.push(match);\n if (text.length === 0) {\n fb.re.lastIndex = nextRegexStart(haystack, start);\n }\n } else {\n fb.re.lastIndex = nextRegexStart(haystack, start);\n }\n }\n }\n return matches;\n }\n\n private findNativeSingles(haystack: string): Match[] {\n const encoded = encoder.encode(haystack);\n const matches: Match[] = [];\n for (const single of this._nativeSingles) {\n matches.push(\n ...unpack(\n single.inner._findIterPackedBuf(encoded),\n haystack,\n this._hasNames ? this._names : null,\n [single.pattern],\n ),\n );\n }\n return matches;\n }\n\n private findFirstJsFallback(\n haystack: string,\n fb: JsFallback,\n ): boolean {\n fb.re.lastIndex = 0;\n for (;;) {\n const m = fb.re.exec(haystack);\n if (!m) return false;\n const text = m[0];\n const start = m.index;\n const end = start + text.length;\n if (this.acceptJsFallbackMatch(haystack, start, end)) {\n return true;\n }\n fb.re.lastIndex = nextRegexStart(haystack, start);\n }\n }\n\n private acceptJsFallbackMatch(\n haystack: string,\n start: number,\n end: number,\n ): boolean {\n if (!this._boundaryOptions.wholeWords) return true;\n return (\n isWordBoundary(\n haystack,\n start,\n this._boundaryOptions.unicodeBoundaries,\n ) &&\n isWordBoundary(\n haystack,\n end,\n this._boundaryOptions.unicodeBoundaries,\n )\n );\n }\n}\n\nfunction jsFallbackRegExp(\n pattern: string,\n unicodeBoundaries: boolean,\n): RegExp | undefined {\n if (\n !hasLookaround(pattern) ||\n (unicodeBoundaries && hasRegexWordBoundary(pattern)) ||\n hasRustUnicodeShorthand(pattern) ||\n hasRustClassSetOperation(pattern) ||\n countAlternations(pattern) < 128\n ) {\n return undefined;\n }\n try {\n return new RegExp(pattern, \"gu\");\n } catch {\n return undefined;\n }\n}\n\nfunction hasLookaround(pattern: string): boolean {\n return (\n pattern.includes(\"(?=\") ||\n pattern.includes(\"(?!\") ||\n pattern.includes(\"(?<=\") ||\n pattern.includes(\"(?<!\")\n );\n}\n\nfunction countAlternations(pattern: string): number {\n let count = 0;\n let inClass = false;\n for (let i = 0; i < pattern.length; i++) {\n const ch = pattern[i];\n if (ch === \"\\\\\") {\n i++;\n continue;\n }\n if (ch === \"[\") inClass = true;\n else if (ch === \"]\") inClass = false;\n else if (ch === \"|\" && !inClass) count++;\n }\n return count;\n}\n\nfunction hasRegexWordBoundary(pattern: string): boolean {\n let inClass = false;\n for (let i = 0; i < pattern.length; i++) {\n const ch = pattern[i];\n if (ch === \"\\\\\") {\n const next = pattern[i + 1];\n if (!inClass && (next === \"b\" || next === \"B\")) {\n return true;\n }\n i++;\n continue;\n }\n if (ch === \"[\") inClass = true;\n else if (ch === \"]\") inClass = false;\n }\n return false;\n}\n\nfunction hasRustUnicodeShorthand(pattern: string): boolean {\n for (let i = 0; i < pattern.length; i++) {\n const ch = pattern[i];\n if (ch !== \"\\\\\") continue;\n const next = pattern[i + 1];\n if (\n next === \"d\" ||\n next === \"D\" ||\n next === \"w\" ||\n next === \"W\" ||\n next === \"s\" ||\n next === \"S\"\n ) {\n return true;\n }\n i++;\n }\n return false;\n}\n\nfunction hasRustClassSetOperation(pattern: string): boolean {\n let inClass = false;\n for (let i = 0; i < pattern.length; i++) {\n const ch = pattern[i];\n if (ch === \"\\\\\") {\n i++;\n continue;\n }\n if (ch === \"[\") {\n inClass = true;\n continue;\n }\n if (ch === \"]\") {\n inClass = false;\n continue;\n }\n if (\n inClass &&\n i + 1 < pattern.length &&\n ((ch === \"&\" && pattern[i + 1] === \"&\") ||\n (ch === \"-\" && pattern[i + 1] === \"-\") ||\n (ch === \"~\" && pattern[i + 1] === \"~\"))\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction nextRegexStart(text: string, index: number): number {\n if (index >= text.length) return index + 1;\n const first = text.charCodeAt(index);\n if (\n first >= 0xd800 &&\n first <= 0xdbff &&\n index + 1 < text.length\n ) {\n const second = text.charCodeAt(index + 1);\n if (second >= 0xdc00 && second <= 0xdfff) {\n return index + 2;\n }\n }\n return index + 1;\n}\n\nfunction selectNonOverlapping(matches: Match[]): Match[] {\n if (matches.length <= 1) return matches;\n\n matches.sort((a, b) => {\n if (a.start !== b.start) return a.start - b.start;\n const lengthOrder = b.end - b.start - (a.end - a.start);\n if (lengthOrder !== 0) return lengthOrder;\n return a.pattern - b.pattern;\n });\n\n const selected: Match[] = [];\n let lastEnd = 0;\n for (const m of matches) {\n if (m.start >= lastEnd) {\n selected.push(m);\n lastEnd = m.end;\n }\n }\n return selected;\n}\n\nfunction isWordBoundary(\n text: string,\n pos: number,\n unicode: boolean,\n): boolean {\n const before = previousCodePoint(text, pos);\n const after = nextCodePoint(text, pos);\n return isWordChar(before, unicode) !== isWordChar(after, unicode);\n}\n\nfunction previousCodePoint(\n text: string,\n pos: number,\n): string | undefined {\n if (pos <= 0) return undefined;\n return Array.from(text.slice(0, pos)).at(-1);\n}\n\nfunction nextCodePoint(\n text: string,\n pos: number,\n): string | undefined {\n if (pos >= text.length) return undefined;\n const cp = text.codePointAt(pos);\n return cp === undefined ? undefined : String.fromCodePoint(cp);\n}\n\nfunction isWordChar(\n ch: string | undefined,\n unicode: boolean,\n): boolean {\n if (ch === undefined) return false;\n return unicode\n ? /^[\\p{Alphabetic}\\p{Number}_]$/u.test(ch)\n : /^[A-Za-z0-9_]$/.test(ch);\n}\n","/* Main entry point -- loads the native NAPI-RS\n * binding and re-exports the public API. */\n\nimport { createRequire } from \"node:module\";\n\nimport { initBinding, type NativeBinding } from \"./core\";\n\nconst require = createRequire(import.meta.url);\n// SAFETY: NAPI-RS auto-generated loader returns the\n// native binding object; its shape is validated by\n// usage in the core classes.\nconst native = require(\"../index.cjs\") as NativeBinding;\n\ninitBinding(native);\n\nexport { RegexSet } from \"./core\";\n\nexport type {\n Match,\n NamedPattern,\n NativeBinding,\n Options,\n PatternEntry,\n} from \"./core\";\n"],"mappings":"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"}
+66
-56

@@ -80,4 +80,4 @@ // prettier-ignore

const bindingPackageVersion = require('@stll/regex-set-android-arm64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -97,4 +97,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-android-arm-eabi/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -119,4 +119,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-win32-x64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -136,4 +136,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-win32-x64-msvc/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -154,4 +154,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-win32-ia32-msvc/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -171,4 +171,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-win32-arm64-msvc/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -191,4 +191,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-darwin-universal/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -208,4 +208,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-darwin-x64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -225,4 +225,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-darwin-arm64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -246,4 +246,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-freebsd-x64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -263,4 +263,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-freebsd-arm64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -285,4 +285,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-x64-musl/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -302,4 +302,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-x64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -321,4 +321,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-arm64-musl/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -338,4 +338,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-arm64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -357,4 +357,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-arm-musleabihf/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -374,4 +374,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-arm-gnueabihf/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -393,4 +393,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-loong64-musl/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -410,4 +410,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-loong64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -429,4 +429,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-riscv64-musl/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -446,4 +446,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-riscv64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -464,4 +464,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-ppc64-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -481,4 +481,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-linux-s390x-gnu/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -502,4 +502,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-openharmony-arm64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -519,4 +519,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-openharmony-x64/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -536,4 +536,4 @@ return binding

const bindingPackageVersion = require('@stll/regex-set-openharmony-arm/package.json').version
if (bindingPackageVersion !== '1.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
if (bindingPackageVersion !== '1.0.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
throw new Error(`Native binding package version mismatch, expected 1.0.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
}

@@ -554,3 +554,13 @@ return binding

if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
// NAPI_RS_FORCE_WASI is a tri-state flag:
// unset / any other value → native binding preferred, WASI is only a fallback
// 'true' → force WASI fallback even if native loaded
// 'error' → force WASI and throw if no WASI binding is found
// Treating any non-empty string as truthy (the historical behavior) meant
// NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
// the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
const forceWasi =
process.env.NAPI_RS_FORCE_WASI === 'true' || process.env.NAPI_RS_FORCE_WASI === 'error'
if (!nativeBinding || forceWasi) {
let wasiBinding = null

@@ -562,7 +572,7 @@ let wasiBindingError = null

} catch (err) {
if (process.env.NAPI_RS_FORCE_WASI) {
if (forceWasi) {
wasiBindingError = err
}
}
if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
if (!nativeBinding || forceWasi) {
try {

@@ -572,3 +582,3 @@ wasiBinding = require('@stll/regex-set-wasm32-wasi')

} catch (err) {
if (process.env.NAPI_RS_FORCE_WASI) {
if (forceWasi) {
if (!wasiBindingError) {

@@ -575,0 +585,0 @@ wasiBindingError = err

{
"name": "@stll/regex-set",
"version": "1.0.1",
"version": "1.0.2",
"description": "Single-pass multi-pattern regex for Node.js/Bun. Backtracking-immune, Unicode-aware Rust engine via NAPI-RS.",

@@ -54,4 +54,6 @@ "keywords": [

"version:check": "node scripts/version-sync.mjs check",
"format": "oxfmt . && rustfmt src/lib.rs",
"lint": "oxlint .",
"format": "oxfmt . \"!.ai/**\" \"!.agents/**\" \"!.claude/**\" \"!AGENTS.md\" \"!CLAUDE.md\" \"!GEMINI.md\" && rustfmt src/lib.rs",
"typecheck": "tsc --noEmit",
"lint": "bun --bun oxlint -c oxlint.config.ts --report-unused-disable-directives-severity=error --deny-warnings --type-aware .",
"lint:fix": "bun --bun oxlint -c oxlint.config.ts --type-aware --fix .",
"check:wasm-compat": "node scripts/check-wasm-compat.mjs",

@@ -62,26 +64,31 @@ "bench": "bun __bench__/speed.ts",

"bench:install": "cd __bench__ && bun install",
"bench:download": "bash __bench__/download-corpus.sh"
"bench:download": "bash __bench__/download-corpus.sh",
"sync-ai": "bash scripts/sync-ai-skills.sh",
"sync-ai:check": "bash scripts/sync-ai-skills.sh --check"
},
"devDependencies": {
"@emnapi/core": "^1.9.2",
"@emnapi/runtime": "^1.9.2",
"@napi-rs/cli": "^3.6.1",
"@napi-rs/wasm-runtime": "^1.1.3",
"@tybys/wasm-util": "^0.10.1",
"@types/node": "^25.5.2",
"bun-types": "^1.3.11",
"emnapi": "^1.9.2",
"fast-check": "^4.6.0",
"oxfmt": "^0.44.0",
"oxlint": "^1.59.0",
"tsdown": "^0.21.7",
"typescript": "^6.0.2",
"vite": "^8.0.8"
"@emnapi/core": "^1.10.0",
"@emnapi/runtime": "^1.10.0",
"@napi-rs/cli": "^3.7.0",
"@napi-rs/wasm-runtime": "^1.1.4",
"@stll/oxlint-config": "^0.2.0",
"@stll/typescript-config": "^0.2.0",
"@tybys/wasm-util": "^0.10.2",
"@types/node": "^25.9.1",
"bun-types": "^1.3.14",
"emnapi": "^1.10.0",
"fast-check": "^4.8.0",
"oxfmt": "^0.52.0",
"oxlint": "^1.67.0",
"oxlint-tsgolint": "^0.23.0",
"tsdown": "^0.22.1",
"typescript": "^6.0.3",
"vite": "^8.0.14"
},
"optionalDependencies": {
"@stll/regex-set-darwin-arm64": "1.0.1",
"@stll/regex-set-darwin-x64": "1.0.1",
"@stll/regex-set-linux-arm64-gnu": "1.0.1",
"@stll/regex-set-linux-x64-gnu": "1.0.1",
"@stll/regex-set-wasm32-wasi": "1.0.1"
"@stll/regex-set-darwin-arm64": "1.0.2",
"@stll/regex-set-darwin-x64": "1.0.2",
"@stll/regex-set-linux-arm64-gnu": "1.0.2",
"@stll/regex-set-linux-x64-gnu": "1.0.2",
"@stll/regex-set-wasm32-wasi": "1.0.2"
},

@@ -88,0 +95,0 @@ "napi": {