@stll/regex-set-wasm 0.1.1
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/wasm.d.mts +117 -0
- package/dist/wasm.mjs +341 -0
- package/dist/wasm.mjs.map +1 -0
- package/package.json +40 -0
package/dist/wasm.d.mts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
type NativeBinding = {
|
|
3
|
+
RegexSet: new (patterns: string[], options?: NativeOptions | undefined | null) => NativeRegexSetInstance;
|
|
4
|
+
_uax29Boundaries: (haystack: Buffer) => number[];
|
|
5
|
+
};
|
|
6
|
+
type NativeOptions = {
|
|
7
|
+
wholeWords?: boolean | undefined;
|
|
8
|
+
unicodeBoundaries?: boolean | undefined;
|
|
9
|
+
};
|
|
10
|
+
type NativeRegexSetInstance = {
|
|
11
|
+
patternCount: number;
|
|
12
|
+
isMatch(haystack: string): boolean;
|
|
13
|
+
_isMatchBuf(haystack: Buffer): boolean;
|
|
14
|
+
_findIterPacked(haystack: string): Uint32Array;
|
|
15
|
+
_findIterPackedBuf(haystack: Buffer): Uint32Array;
|
|
16
|
+
whichMatch(haystack: string): number[];
|
|
17
|
+
replaceAll(haystack: string, replacements: string[]): string;
|
|
18
|
+
};
|
|
19
|
+
/** Set the native backend. Must be called once
|
|
20
|
+
* before any class constructor. */
|
|
21
|
+
/** Options for constructing a RegexSet. */
|
|
22
|
+
type Options = {
|
|
23
|
+
/**
|
|
24
|
+
* Only match whole words. Wraps each pattern
|
|
25
|
+
* with `\b...\b`.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
wholeWords?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Use Unicode word boundaries. When `true`,
|
|
31
|
+
* `\b` treats accented letters, CJK, etc. as
|
|
32
|
+
* word characters (correct for non-English text).
|
|
33
|
+
* When `false` (default), `\b` uses ASCII
|
|
34
|
+
* semantics matching JS `RegExp` behavior.
|
|
35
|
+
*
|
|
36
|
+
* Zero performance overhead in either mode;
|
|
37
|
+
* boundaries are verified inline per match.
|
|
38
|
+
* Automatically uses UAX#29 segmentation for
|
|
39
|
+
* Thai/CJK/Lao/Khmer/Myanmar text.
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
unicodeBoundaries?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Case-insensitive matching. Wraps each pattern
|
|
45
|
+
* with `(?i-u:...)` for ASCII case folding.
|
|
46
|
+
* Uses `-u` to prevent DFA state explosion from
|
|
47
|
+
* Unicode case tables.
|
|
48
|
+
*
|
|
49
|
+
* Edge `\b`/`\B` boundaries and leading bare-flag
|
|
50
|
+
* prefixes (e.g. `(?m)`, `(?m-s)`) are extracted
|
|
51
|
+
* before wrapping so they remain outside the `-u`
|
|
52
|
+
* scope, preserving `unicodeBoundaries` semantics.
|
|
53
|
+
* Patterns already containing any `(?{flags}-u`
|
|
54
|
+
* group (from RegExp `/i`, inline `(?i)`, or
|
|
55
|
+
* `scopeInlineFlags`) are not double-wrapped.
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
caseInsensitive?: boolean;
|
|
59
|
+
};
|
|
60
|
+
/** A named pattern entry. */
|
|
61
|
+
type NamedPattern = {
|
|
62
|
+
/** The regex pattern (string or RegExp). */pattern: string | RegExp; /** Optional name for this pattern. */
|
|
63
|
+
name?: string;
|
|
64
|
+
};
|
|
65
|
+
/** A pattern entry: string, RegExp, or named. */
|
|
66
|
+
type PatternEntry = string | RegExp | NamedPattern;
|
|
67
|
+
/** A single match result. */
|
|
68
|
+
type Match = {
|
|
69
|
+
/** Index of the pattern that matched. */pattern: number; /** Start UTF-16 code unit offset. */
|
|
70
|
+
start: number; /** End offset (exclusive). */
|
|
71
|
+
end: number; /** The matched text. */
|
|
72
|
+
text: string; /** Pattern name (if provided at construction). */
|
|
73
|
+
name?: string;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Multi-pattern regex matcher.
|
|
77
|
+
*
|
|
78
|
+
* Compiles multiple regex patterns into a single
|
|
79
|
+
* automaton. Guaranteed O(m * n); no catastrophic
|
|
80
|
+
* backtracking. Uses Rust regex syntax for string
|
|
81
|
+
* patterns (no lookaheads/backreferences).
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* // Simple
|
|
86
|
+
* new RegexSet([/\d{8}/, "\\+?\\d{9,12}"]);
|
|
87
|
+
*
|
|
88
|
+
* // Named
|
|
89
|
+
* new RegexSet([
|
|
90
|
+
* { pattern: /\d{8}/, name: "ico" },
|
|
91
|
+
* { pattern: /\d{2}\.\d{2}\.\d{4}/, name: "date" },
|
|
92
|
+
* ]);
|
|
93
|
+
* // match.name === "date"
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare class RegexSet {
|
|
97
|
+
private _inner;
|
|
98
|
+
private _names;
|
|
99
|
+
private _hasNames;
|
|
100
|
+
constructor(patterns: PatternEntry[], options?: Options);
|
|
101
|
+
/** Number of patterns. */
|
|
102
|
+
get patternCount(): number;
|
|
103
|
+
/** Returns `true` if any pattern matches. */
|
|
104
|
+
isMatch(haystack: string): boolean;
|
|
105
|
+
/** Find all non-overlapping matches. */
|
|
106
|
+
findIter(haystack: string): Match[];
|
|
107
|
+
/** Which pattern indices matched (not where). */
|
|
108
|
+
whichMatch(haystack: string): number[];
|
|
109
|
+
/**
|
|
110
|
+
* Replace all non-overlapping matches.
|
|
111
|
+
* `replacements[i]` replaces pattern `i`.
|
|
112
|
+
*/
|
|
113
|
+
replaceAll(haystack: string, replacements: string[]): string;
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { type Match, type NamedPattern, type NativeBinding, type Options, type PatternEntry, RegexSet };
|
|
117
|
+
//# sourceMappingURL=wasm.d.mts.map
|
package/dist/wasm.mjs
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import native from "@stll/regex-set-wasm32-wasi";
|
|
2
|
+
//#region src/core.ts
|
|
3
|
+
let binding;
|
|
4
|
+
/** Set the native backend. Must be called once
|
|
5
|
+
* before any class constructor. */
|
|
6
|
+
const initBinding = (b) => {
|
|
7
|
+
binding = b;
|
|
8
|
+
};
|
|
9
|
+
function unpack(packed, haystack, names) {
|
|
10
|
+
const len = packed.length;
|
|
11
|
+
const matches = new Array(len / 3);
|
|
12
|
+
for (let i = 0, j = 0; i < len; i += 3, j++) {
|
|
13
|
+
const idx = packed[i];
|
|
14
|
+
const s = packed[i + 1];
|
|
15
|
+
const e = packed[i + 2];
|
|
16
|
+
if (idx === void 0 || s === void 0 || e === void 0) throw new Error(`Corrupt packed match data at offset ${i}`);
|
|
17
|
+
const m = {
|
|
18
|
+
pattern: idx,
|
|
19
|
+
start: s,
|
|
20
|
+
end: e,
|
|
21
|
+
text: haystack.slice(s, e)
|
|
22
|
+
};
|
|
23
|
+
if (names && names[idx] !== void 0) m.name = names[idx];
|
|
24
|
+
matches[j] = m;
|
|
25
|
+
}
|
|
26
|
+
return matches;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Replace unescaped `\b` and `\B` with their
|
|
30
|
+
* ASCII-only equivalents `(?-u:\b)` / `(?-u:\B)`.
|
|
31
|
+
* Skips character classes `[...]` (where `\b` means
|
|
32
|
+
* backspace) and escaped backslashes `\\b`.
|
|
33
|
+
*/
|
|
34
|
+
function asciiBoundaries(src) {
|
|
35
|
+
let result = "";
|
|
36
|
+
let inClass = false;
|
|
37
|
+
let i = 0;
|
|
38
|
+
while (i < src.length) if (src.charAt(i) === "\\" && i + 1 < src.length) {
|
|
39
|
+
const next = src.charAt(i + 1);
|
|
40
|
+
if (!inClass && (next === "b" || next === "B")) {
|
|
41
|
+
result += `(?-u:\\${next})`;
|
|
42
|
+
i += 2;
|
|
43
|
+
} else {
|
|
44
|
+
result += src.charAt(i) + src.charAt(i + 1);
|
|
45
|
+
i += 2;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
if (src.charAt(i) === "[") inClass = true;
|
|
49
|
+
if (src.charAt(i) === "]") inClass = false;
|
|
50
|
+
result += src.charAt(i);
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Convert a RegExp to Rust regex syntax string.
|
|
57
|
+
*/
|
|
58
|
+
function regexpToRust(re) {
|
|
59
|
+
let flags = "";
|
|
60
|
+
if (re.flags.includes("i")) flags += "i";
|
|
61
|
+
if (re.flags.includes("m")) flags += "m";
|
|
62
|
+
if (re.flags.includes("s")) flags += "s";
|
|
63
|
+
if (!flags) return re.source;
|
|
64
|
+
if (!flags.includes("i")) return `(?${flags})${re.source}`;
|
|
65
|
+
let src = re.source;
|
|
66
|
+
let leading = "";
|
|
67
|
+
let trailing = "";
|
|
68
|
+
if (src.startsWith("\\b")) {
|
|
69
|
+
leading = "\\b";
|
|
70
|
+
src = src.slice(2);
|
|
71
|
+
} else if (src.startsWith("\\B")) {
|
|
72
|
+
leading = "\\B";
|
|
73
|
+
src = src.slice(2);
|
|
74
|
+
}
|
|
75
|
+
if (src.length >= 2) {
|
|
76
|
+
const last = src.charAt(src.length - 1);
|
|
77
|
+
if (last === "b" || last === "B") {
|
|
78
|
+
let bs = 0;
|
|
79
|
+
let k = src.length - 2;
|
|
80
|
+
while (k >= 0 && src.charAt(k) === "\\") {
|
|
81
|
+
bs++;
|
|
82
|
+
k--;
|
|
83
|
+
}
|
|
84
|
+
if (bs > 0 && bs % 2 === 1) {
|
|
85
|
+
trailing = "\\" + last;
|
|
86
|
+
src = src.slice(0, -2);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const uFlag = needsAsciiMode(src) && !hasNonAscii(src) ? "-u" : "";
|
|
91
|
+
return `${leading}(?${flags}${uFlag}:${src})${trailing}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if content uses character class shortcuts
|
|
95
|
+
* (\w, \W, \d, \D, \s, \S, \b, \B) that have
|
|
96
|
+
* Unicode-aware versions. Only these benefit from
|
|
97
|
+
* -u (ASCII-only mode). Literal strings like
|
|
98
|
+
* "dollars" produce identical DFAs with or without
|
|
99
|
+
* -u, so skipping -u for them is zero-cost.
|
|
100
|
+
*/
|
|
101
|
+
function needsAsciiMode(s) {
|
|
102
|
+
return /\\[wWdDsSbB]/.test(s);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Check if a string contains non-ASCII characters.
|
|
106
|
+
* When true, -u MUST NOT be added: regex-automata
|
|
107
|
+
* rejects (?-u) alongside non-ASCII content like
|
|
108
|
+
* [ACDE] or literal zlotych.
|
|
109
|
+
*/
|
|
110
|
+
function hasNonAscii(s) {
|
|
111
|
+
for (let i = 0; i < s.length; i++) if (s.charCodeAt(i) > 127) return true;
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Convert inline (?i) flags to (?i-u) for ASCII
|
|
116
|
+
* case folding. Handles bare and scoped groups.
|
|
117
|
+
*
|
|
118
|
+
* Bare (?i) at the start of a pattern is converted
|
|
119
|
+
* to a scoped group (?i-u:...) with edge \b pulled
|
|
120
|
+
* outside, matching the RegExp path behaviour. This
|
|
121
|
+
* prevents -u from affecting \b word boundary
|
|
122
|
+
* semantics (which should remain Unicode when
|
|
123
|
+
* unicodeBoundaries is true).
|
|
124
|
+
*
|
|
125
|
+
* NOTE: -u also disables Unicode character classes
|
|
126
|
+
* (\w, \d, \s become ASCII-only), matching the
|
|
127
|
+
* behaviour of regexpToRust() for /i RegExps.
|
|
128
|
+
*/
|
|
129
|
+
function scopeInlineFlags(src) {
|
|
130
|
+
const leadingBare = src.match(/^\(\?([ims]+)(?:-([imsu]+))?\)/);
|
|
131
|
+
const enableGroup = leadingBare?.[1];
|
|
132
|
+
if (leadingBare && enableGroup?.includes("i")) {
|
|
133
|
+
const enable = enableGroup;
|
|
134
|
+
const disable = leadingBare[2] ?? "";
|
|
135
|
+
let rest = src.slice(leadingBare[0].length);
|
|
136
|
+
let leading = "";
|
|
137
|
+
let trailing = "";
|
|
138
|
+
if (rest.startsWith("\\b")) {
|
|
139
|
+
leading = "\\b";
|
|
140
|
+
rest = rest.slice(2);
|
|
141
|
+
} else if (rest.startsWith("\\B")) {
|
|
142
|
+
leading = "\\B";
|
|
143
|
+
rest = rest.slice(2);
|
|
144
|
+
}
|
|
145
|
+
if (rest.length >= 2) {
|
|
146
|
+
const last = rest.charAt(rest.length - 1);
|
|
147
|
+
if (last === "b" || last === "B") {
|
|
148
|
+
let bs = 0;
|
|
149
|
+
let k = rest.length - 2;
|
|
150
|
+
while (k >= 0 && rest.charAt(k) === "\\") {
|
|
151
|
+
bs++;
|
|
152
|
+
k--;
|
|
153
|
+
}
|
|
154
|
+
if (bs > 0 && bs % 2 === 1) {
|
|
155
|
+
trailing = "\\" + last;
|
|
156
|
+
rest = rest.slice(0, -2);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const inner = scopeInnerFlags(rest);
|
|
161
|
+
const merged = needsAsciiMode(rest) && !hasNonAscii(rest) && !disable.includes("u") ? disable + "u" : disable;
|
|
162
|
+
const disablePart = merged ? `-${merged}` : "";
|
|
163
|
+
return `${leading}(?${enable}${disablePart}:${inner})${trailing}`;
|
|
164
|
+
}
|
|
165
|
+
return scopeInnerFlags(src);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Replace inline (?i) / (?i:...) groups with -u
|
|
169
|
+
* variants. Does not handle leading bare flags
|
|
170
|
+
* (that's done by scopeInlineFlags above).
|
|
171
|
+
*/
|
|
172
|
+
function scopeInnerFlags(src) {
|
|
173
|
+
let result = "";
|
|
174
|
+
let inClass = false;
|
|
175
|
+
let i = 0;
|
|
176
|
+
while (i < src.length) {
|
|
177
|
+
if (src[i] === "\\" && i + 1 < src.length) {
|
|
178
|
+
result += src.charAt(i) + src.charAt(i + 1);
|
|
179
|
+
i += 2;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (src.charAt(i) === "[") inClass = true;
|
|
183
|
+
if (src.charAt(i) === "]") inClass = false;
|
|
184
|
+
if (!inClass && src.charAt(i) === "(" && src.charAt(i + 1) === "?") {
|
|
185
|
+
let j = i + 2;
|
|
186
|
+
let enable = "";
|
|
187
|
+
while (j < src.length && "ims".includes(src.charAt(j))) {
|
|
188
|
+
enable += src.charAt(j);
|
|
189
|
+
j++;
|
|
190
|
+
}
|
|
191
|
+
let disable = "";
|
|
192
|
+
if (j < src.length && src.charAt(j) === "-") {
|
|
193
|
+
j++;
|
|
194
|
+
while (j < src.length && "imsu".includes(src.charAt(j))) {
|
|
195
|
+
disable += src.charAt(j);
|
|
196
|
+
j++;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (enable.length > 0 && (src.charAt(j) === ")" || src.charAt(j) === ":")) {
|
|
200
|
+
if (enable.includes("i")) if (disable.length > 0) result += `(?${enable}-${disable}${src.charAt(j)}`;
|
|
201
|
+
else result += `(?${enable}${src.charAt(j)}`;
|
|
202
|
+
else if (disable.length > 0) result += `(?${enable}-${disable}${src.charAt(j)}`;
|
|
203
|
+
else result += `(?${enable}${src.charAt(j)}`;
|
|
204
|
+
i = j + 1;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
result += src.charAt(i);
|
|
209
|
+
i++;
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Normalize a pattern entry to { pattern, name }.
|
|
215
|
+
*/
|
|
216
|
+
function normalizeEntry(p, i) {
|
|
217
|
+
if (typeof p === "string") return {
|
|
218
|
+
pattern: scopeInlineFlags(p),
|
|
219
|
+
name: void 0
|
|
220
|
+
};
|
|
221
|
+
if (p instanceof RegExp) return {
|
|
222
|
+
pattern: regexpToRust(p),
|
|
223
|
+
name: void 0
|
|
224
|
+
};
|
|
225
|
+
if (typeof p === "object" && p !== null && "pattern" in p) {
|
|
226
|
+
if (typeof p.pattern !== "string" && !(p.pattern instanceof RegExp)) throw new TypeError(`Pattern at index ${i}: "pattern" field must be a string or RegExp`);
|
|
227
|
+
const inner = p.pattern instanceof RegExp ? { pattern: regexpToRust(p.pattern) } : { pattern: scopeInlineFlags(p.pattern) };
|
|
228
|
+
if (p.name !== void 0 && typeof p.name !== "string") throw new TypeError(`Pattern at index ${i}: "name" field must be a string`);
|
|
229
|
+
return {
|
|
230
|
+
pattern: inner.pattern,
|
|
231
|
+
name: p.name
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
throw new TypeError(`Pattern at index ${i} must be a string, RegExp, or { pattern, name }`);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Multi-pattern regex matcher.
|
|
238
|
+
*
|
|
239
|
+
* Compiles multiple regex patterns into a single
|
|
240
|
+
* automaton. Guaranteed O(m * n); no catastrophic
|
|
241
|
+
* backtracking. Uses Rust regex syntax for string
|
|
242
|
+
* patterns (no lookaheads/backreferences).
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* // Simple
|
|
247
|
+
* new RegexSet([/\d{8}/, "\\+?\\d{9,12}"]);
|
|
248
|
+
*
|
|
249
|
+
* // Named
|
|
250
|
+
* new RegexSet([
|
|
251
|
+
* { pattern: /\d{8}/, name: "ico" },
|
|
252
|
+
* { pattern: /\d{2}\.\d{2}\.\d{4}/, name: "date" },
|
|
253
|
+
* ]);
|
|
254
|
+
* // match.name === "date"
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
var RegexSet = class {
|
|
258
|
+
_inner;
|
|
259
|
+
_names;
|
|
260
|
+
_hasNames;
|
|
261
|
+
constructor(patterns, options) {
|
|
262
|
+
const entries = patterns.map(normalizeEntry);
|
|
263
|
+
this._names = entries.map((e) => e.name);
|
|
264
|
+
this._hasNames = entries.some((e) => e.name !== void 0);
|
|
265
|
+
const unicode = options?.unicodeBoundaries ?? true;
|
|
266
|
+
const ci = options?.caseInsensitive ?? false;
|
|
267
|
+
let processed = entries.map((e) => e.pattern);
|
|
268
|
+
if (ci) processed = processed.map((p) => {
|
|
269
|
+
if (/^(?:\\[bB]|\(\?[ims]+(?:-[imsu]+)?\))*\(\?[ims]*i[ims]*(?:-[imsu]+)?[:(]/.test(p)) return p;
|
|
270
|
+
let src = p;
|
|
271
|
+
let flagPrefix = "";
|
|
272
|
+
const bareFlagMatch = src.match(/^\(\?[ims]+(?:-[imsu]+)?\)/);
|
|
273
|
+
if (bareFlagMatch) {
|
|
274
|
+
flagPrefix = bareFlagMatch[0];
|
|
275
|
+
src = src.slice(flagPrefix.length);
|
|
276
|
+
}
|
|
277
|
+
let leading = "";
|
|
278
|
+
let trailing = "";
|
|
279
|
+
if (src.startsWith("\\b")) {
|
|
280
|
+
leading = "\\b";
|
|
281
|
+
src = src.slice(2);
|
|
282
|
+
} else if (src.startsWith("\\B")) {
|
|
283
|
+
leading = "\\B";
|
|
284
|
+
src = src.slice(2);
|
|
285
|
+
}
|
|
286
|
+
if (src.length >= 2) {
|
|
287
|
+
const last = src.charAt(src.length - 1);
|
|
288
|
+
if (last === "b" || last === "B") {
|
|
289
|
+
let bs = 0;
|
|
290
|
+
let k = src.length - 2;
|
|
291
|
+
while (k >= 0 && src.charAt(k) === "\\") {
|
|
292
|
+
bs++;
|
|
293
|
+
k--;
|
|
294
|
+
}
|
|
295
|
+
if (bs > 0 && bs % 2 === 1) {
|
|
296
|
+
trailing = "\\" + last;
|
|
297
|
+
src = src.slice(0, -2);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const uFlag = needsAsciiMode(src) && !hasNonAscii(src) ? "-u" : "";
|
|
302
|
+
return `${flagPrefix}${leading}(?i${uFlag}:${src})${trailing}`;
|
|
303
|
+
});
|
|
304
|
+
if (!unicode) processed = processed.map(asciiBoundaries);
|
|
305
|
+
const nativeOpts = options ? {
|
|
306
|
+
wholeWords: options.wholeWords,
|
|
307
|
+
unicodeBoundaries: options.unicodeBoundaries
|
|
308
|
+
} : void 0;
|
|
309
|
+
this._inner = new binding.RegexSet(processed, nativeOpts);
|
|
310
|
+
}
|
|
311
|
+
/** Number of patterns. */
|
|
312
|
+
get patternCount() {
|
|
313
|
+
return this._inner.patternCount;
|
|
314
|
+
}
|
|
315
|
+
/** Returns `true` if any pattern matches. */
|
|
316
|
+
isMatch(haystack) {
|
|
317
|
+
return this._inner._isMatchBuf(Buffer.from(haystack));
|
|
318
|
+
}
|
|
319
|
+
/** Find all non-overlapping matches. */
|
|
320
|
+
findIter(haystack) {
|
|
321
|
+
return unpack(this._inner._findIterPackedBuf(Buffer.from(haystack)), haystack, this._hasNames ? this._names : null);
|
|
322
|
+
}
|
|
323
|
+
/** Which pattern indices matched (not where). */
|
|
324
|
+
whichMatch(haystack) {
|
|
325
|
+
return this._inner.whichMatch(haystack);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Replace all non-overlapping matches.
|
|
329
|
+
* `replacements[i]` replaces pattern `i`.
|
|
330
|
+
*/
|
|
331
|
+
replaceAll(haystack, replacements) {
|
|
332
|
+
return this._inner.replaceAll(haystack, replacements);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region src/wasm.ts
|
|
337
|
+
initBinding(native);
|
|
338
|
+
//#endregion
|
|
339
|
+
export { RegexSet };
|
|
340
|
+
|
|
341
|
+
//# sourceMappingURL=wasm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.mjs","names":[],"sources":["../../src/core.ts","../../src/wasm.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\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) => 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): boolean;\n _findIterPacked(haystack: string): Uint32Array;\n _findIterPackedBuf(haystack: Buffer): 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. Guaranteed O(m * n); no catastrophic\n * backtracking. 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(Buffer.from(haystack));\n }\n\n /** Find all non-overlapping matches. */\n findIter(haystack: string): Match[] {\n return unpack(\n this._inner._findIterPackedBuf(Buffer.from(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","/* Browser/WASM entry point -- loads the WASM binding\n * from the sub-package and re-exports the public API\n * through the shared core. */\n\nimport native from \"@stll/regex-set-wasm32-wasi\";\n\nimport { initBinding, type NativeBinding } from \"./core\";\n\ninitBinding(native as unknown as NativeBinding);\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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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stll/regex-set-wasm",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Multi-pattern regex for browsers via WebAssembly. Same API as @stll/regex-set.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"multi-pattern",
|
|
7
|
+
"napi-rs",
|
|
8
|
+
"regex",
|
|
9
|
+
"regex-set",
|
|
10
|
+
"rust",
|
|
11
|
+
"wasm"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/stella/regex-set#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/stella/regex-set/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/stella/regex-set"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"module": "dist/wasm.mjs",
|
|
27
|
+
"types": "dist/wasm.d.mts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/wasm.d.mts",
|
|
31
|
+
"import": "./dist/wasm.mjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "restricted"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@stll/regex-set-wasm32-wasi": "0.0.3"
|
|
39
|
+
}
|
|
40
|
+
}
|