terlik.js 2.2.0 → 2.2.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/README.md CHANGED
@@ -451,6 +451,18 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution guidelines.
451
451
 
452
452
  ## Changelog
453
453
 
454
+ ### 2026-02-28 (v2.2.1) — CI Fix: Timeout Race Condition + İ Platform Compatibility
455
+
456
+ **Fixes detection failures on slow runners and cross-platform İ (U+0130) handling.**
457
+
458
+ - **Timeout race condition fix** — `REGEX_TIMEOUT_MS` check moved from _before_ match processing to _after_. Previously, V8 JIT compilation on first `exec()` call (triggered by lazy compilation) could exceed 250ms, causing the timeout to discard a valid match before it was recorded. Now the current match is always processed; the timeout only prevents scanning for additional matches.
459
+ - **İ (U+0130) cross-platform fix** — First regex pass now runs on `text.toLocaleLowerCase(locale)` instead of raw text. Turkish İ→i mapping is performed explicitly before regex matching, avoiding inconsistent V8/ICU case-folding behavior across platforms (Ubuntu vs macOS). The `mapNormalizedToOriginal()` mapper recovers original-cased words for result output.
460
+
461
+ | Change | File |
462
+ |---|---|
463
+ | Timeout check moved after match processing | `src/detector.ts` (`runPatterns`) |
464
+ | Locale-lower first pass for İ safety | `src/detector.ts` (`detectPattern`) |
465
+
454
466
  ### 2026-02-28 (v2.2) — Lazy Compilation + Linguistic Patch
455
467
 
456
468
  **Zero-cost construction. Background warmup. Turkish agglutination hardening.**
package/dist/index.js CHANGED
@@ -383,9 +383,9 @@ var Detector = class {
383
383
  }
384
384
  }
385
385
  detectPattern(text, whitelist, results) {
386
- this.runPatterns(text, text, whitelist, results, false);
387
- const normalizedText = this.normalizeFn(text);
388
386
  const lowerText = text.toLocaleLowerCase(this.locale);
387
+ this.runPatterns(lowerText, text, whitelist, results, lowerText !== text);
388
+ const normalizedText = this.normalizeFn(text);
389
389
  if (normalizedText !== lowerText && normalizedText.length > 0) {
390
390
  this.runPatterns(normalizedText, text, whitelist, results, true);
391
391
  }
@@ -398,7 +398,6 @@ var Detector = class {
398
398
  pattern.regex.lastIndex = 0;
399
399
  let match;
400
400
  while ((match = pattern.regex.exec(searchText)) !== null) {
401
- if (Date.now() - patternStart > REGEX_TIMEOUT_MS) break;
402
401
  const matchedText = match[0];
403
402
  const matchIndex = match.index;
404
403
  const normalizedMatch = this.normalizeFn(matchedText);
@@ -433,6 +432,7 @@ var Detector = class {
433
432
  if (matchedText.length === 0) {
434
433
  pattern.regex.lastIndex++;
435
434
  }
435
+ if (Date.now() - patternStart > REGEX_TIMEOUT_MS) break;
436
436
  }
437
437
  }
438
438
  }
package/dist/index.mjs CHANGED
@@ -350,9 +350,9 @@ var Detector = class {
350
350
  }
351
351
  }
352
352
  detectPattern(text, whitelist, results) {
353
- this.runPatterns(text, text, whitelist, results, false);
354
- const normalizedText = this.normalizeFn(text);
355
353
  const lowerText = text.toLocaleLowerCase(this.locale);
354
+ this.runPatterns(lowerText, text, whitelist, results, lowerText !== text);
355
+ const normalizedText = this.normalizeFn(text);
356
356
  if (normalizedText !== lowerText && normalizedText.length > 0) {
357
357
  this.runPatterns(normalizedText, text, whitelist, results, true);
358
358
  }
@@ -365,7 +365,6 @@ var Detector = class {
365
365
  pattern.regex.lastIndex = 0;
366
366
  let match;
367
367
  while ((match = pattern.regex.exec(searchText)) !== null) {
368
- if (Date.now() - patternStart > REGEX_TIMEOUT_MS) break;
369
368
  const matchedText = match[0];
370
369
  const matchIndex = match.index;
371
370
  const normalizedMatch = this.normalizeFn(matchedText);
@@ -400,6 +399,7 @@ var Detector = class {
400
399
  if (matchedText.length === 0) {
401
400
  pattern.regex.lastIndex++;
402
401
  }
402
+ if (Date.now() - patternStart > REGEX_TIMEOUT_MS) break;
403
403
  }
404
404
  }
405
405
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terlik.js",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Ultra-fast, zero-dependency multi-language profanity detection engine for Turkish, English, Spanish, and German with lazy compilation, deep agglutination support, and ReDoS-safe regex patterns",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",