@stll/anonymize 0.0.9 → 1.0.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.
@@ -1,6 +1,17 @@
1
+ import { TextSearch } from "@stll/text-search";
1
2
  import { at, be, bg, cy, cz, de, dk, ee, es, fi, fr, gb, gr, hr, hu, ie, it, lt, lu, lv, mt, nl, pl, pt, ro, se, si, sk } from "@stll/stdnum";
2
3
  import { toRegex } from "@stll/stdnum/patterns";
3
- import { TextSearch } from "@stll/text-search";
4
+ import charGroupsJson from "@stll/anonymize-data/config/char-groups.json";
5
+ //#region src/search-engine.ts
6
+ let _TextSearch;
7
+ const initTextSearch = (ctor) => {
8
+ _TextSearch = ctor;
9
+ };
10
+ const getTextSearch = () => {
11
+ if (!_TextSearch) throw new Error("TextSearch not initialized. Import from @stll/anonymize or @stll/anonymize-wasm, not from internal modules.");
12
+ return _TextSearch;
13
+ };
14
+ //#endregion
4
15
  //#region src/types.ts
5
16
  /**
6
17
  * Source of a detected entity span.
@@ -565,7 +576,37 @@ const getNameCorpusFirstNames = (ctx = defaultContext) => ctx.nameCorpus?.firstN
565
576
  const getNameCorpusSurnames = (ctx = defaultContext) => ctx.nameCorpus?.surnamesList ?? [];
566
577
  const getNameCorpusTitles = (ctx = defaultContext) => ctx.nameCorpus?.titlesList ?? [];
567
578
  /**
568
- * Load name corpus data from JSON config files.
579
+ * Languages with per-language first/surname
580
+ * dictionaries in @stll/anonymize-data.
581
+ */
582
+ const NAME_LANGUAGES = [
583
+ "cs",
584
+ "sk",
585
+ "de",
586
+ "pl",
587
+ "hu",
588
+ "ro",
589
+ "fr",
590
+ "es",
591
+ "it",
592
+ "en",
593
+ "sv"
594
+ ];
595
+ /**
596
+ * Try importing a JSON module; return empty array
597
+ * if not found.
598
+ */
599
+ const tryImportArray = async (path) => {
600
+ try {
601
+ return (await import(path)).default;
602
+ } catch {
603
+ return [];
604
+ }
605
+ };
606
+ /**
607
+ * Load name corpus data from per-language dictionary
608
+ * files and legacy config files. Merges all sources.
609
+ *
569
610
  * Safe to call multiple times; only loads once per
570
611
  * context. Must be called before detectNameCorpus or
571
612
  * the getNameCorpus*() accessors are used.
@@ -574,23 +615,40 @@ const initNameCorpus = (ctx = defaultContext) => {
574
615
  if (ctx.nameCorpusPromise) return ctx.nameCorpusPromise;
575
616
  const promise = (async () => {
576
617
  try {
577
- const [firstMod, surnameMod, titleMod, exclusionMod] = await Promise.all([
618
+ const [legacyFirstMod, legacySurnameMod, titleMod, exclusionMod] = await Promise.all([
578
619
  import("@stll/anonymize-data/config/names-first.json"),
579
620
  import("@stll/anonymize-data/config/names-surnames.json"),
580
621
  import("@stll/anonymize-data/config/names-title-tokens.json"),
581
622
  import("@stll/anonymize-data/config/names-exclusions.json")
582
623
  ]);
583
- const firstNames = firstMod.default.names;
584
- const surnames = surnameMod.default.names;
624
+ const firstImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/first/${lang}.json`));
625
+ const surnameImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/surnames/${lang}.json`));
626
+ const [firstResults, surnameResults] = await Promise.all([Promise.all(firstImports), Promise.all(surnameImports)]);
627
+ const firstNames = [...legacyFirstMod.default.names];
628
+ for (const names of firstResults) for (const name of names) firstNames.push(name);
629
+ const surnames = [...legacySurnameMod.default.names];
630
+ for (const names of surnameResults) for (const name of names) surnames.push(name);
631
+ const dedup = (arr) => {
632
+ const seen = /* @__PURE__ */ new Set();
633
+ const result = [];
634
+ for (const item of arr) {
635
+ if (seen.has(item)) continue;
636
+ seen.add(item);
637
+ result.push(item);
638
+ }
639
+ return result;
640
+ };
641
+ const dedupFirst = dedup(firstNames);
642
+ const dedupSurnames = dedup(surnames);
585
643
  const titles = titleMod.default.tokens;
586
644
  const exclusions = exclusionMod.default.words;
587
645
  ctx.nameCorpus = {
588
- firstNames: Object.freeze(new Set(firstNames)),
589
- surnames: Object.freeze(new Set(surnames)),
646
+ firstNames: Object.freeze(new Set(dedupFirst)),
647
+ surnames: Object.freeze(new Set(dedupSurnames)),
590
648
  titleTokens: Object.freeze(new Set(titles)),
591
649
  excludedWords: Object.freeze(new Set(exclusions)),
592
- firstNamesList: Object.freeze(firstNames),
593
- surnamesList: Object.freeze(surnames),
650
+ firstNamesList: Object.freeze(dedupFirst),
651
+ surnamesList: Object.freeze(dedupSurnames),
594
652
  titlesList: Object.freeze(titles),
595
653
  excludedList: Object.freeze(exclusions)
596
654
  };
@@ -994,519 +1052,28 @@ const POST_NOMINALS = [
994
1052
  "CIPP"
995
1053
  ];
996
1054
  //#endregion
997
- //#region src/util/char-groups-data.json
998
- var char_groups_data_default = {
999
- _comment: "Unicode character equivalence groups. Used to build regex character classes that match all variants of a character type.",
1000
- groups: {
1001
- "dash": {
1002
- "description": "Dash-like characters (hyphens, en-dash, em-dash, minus)",
1003
- "chars": [
1004
- {
1005
- "char": "-",
1006
- "name": "hyphen-minus",
1007
- "code": "U+002D"
1008
- },
1009
- {
1010
- "char": "–",
1011
- "name": "en-dash",
1012
- "code": "U+2013"
1013
- },
1014
- {
1015
- "char": "—",
1016
- "name": "em-dash",
1017
- "code": "U+2014"
1018
- },
1019
- {
1020
- "char": "‐",
1021
- "name": "hyphen",
1022
- "code": "U+2010"
1023
- },
1024
- {
1025
- "char": "‑",
1026
- "name": "non-breaking hyphen",
1027
- "code": "U+2011"
1028
- },
1029
- {
1030
- "char": "−",
1031
- "name": "minus sign",
1032
- "code": "U+2212"
1033
- },
1034
- {
1035
- "char": "⁃",
1036
- "name": "hyphen bullet",
1037
- "code": "U+2043"
1038
- },
1039
- {
1040
- "char": "‒",
1041
- "name": "figure dash",
1042
- "code": "U+2012"
1043
- },
1044
- {
1045
- "char": "―",
1046
- "name": "horizontal bar",
1047
- "code": "U+2015"
1048
- },
1049
- {
1050
- "char": "⸺",
1051
- "name": "two-em dash",
1052
- "code": "U+2E3A"
1053
- },
1054
- {
1055
- "char": "⸻",
1056
- "name": "three-em dash",
1057
- "code": "U+2E3B"
1058
- },
1059
- {
1060
- "char": "־",
1061
- "name": "Hebrew maqaf",
1062
- "code": "U+05BE"
1063
- }
1064
- ]
1065
- },
1066
- "space": {
1067
- "description": "Space-like characters",
1068
- "chars": [
1069
- {
1070
- "char": " ",
1071
- "name": "space",
1072
- "code": "U+0020"
1073
- },
1074
- {
1075
- "char": "\xA0",
1076
- "name": "no-break space",
1077
- "code": "U+00A0"
1078
- },
1079
- {
1080
- "char": " ",
1081
- "name": "en space",
1082
- "code": "U+2002"
1083
- },
1084
- {
1085
- "char": " ",
1086
- "name": "em space",
1087
- "code": "U+2003"
1088
- },
1089
- {
1090
- "char": " ",
1091
- "name": "thin space",
1092
- "code": "U+2009"
1093
- },
1094
- {
1095
- "char": " ",
1096
- "name": "hair space",
1097
- "code": "U+200A"
1098
- },
1099
- {
1100
- "char": " ",
1101
- "name": "narrow no-break space",
1102
- "code": "U+202F"
1103
- },
1104
- {
1105
- "char": " ",
1106
- "name": "Ogham space mark",
1107
- "code": "U+1680"
1108
- },
1109
- {
1110
- "char": " ",
1111
- "name": "en quad",
1112
- "code": "U+2000"
1113
- },
1114
- {
1115
- "char": " ",
1116
- "name": "em quad",
1117
- "code": "U+2001"
1118
- },
1119
- {
1120
- "char": " ",
1121
- "name": "three-per-em space",
1122
- "code": "U+2004"
1123
- },
1124
- {
1125
- "char": " ",
1126
- "name": "four-per-em space",
1127
- "code": "U+2005"
1128
- },
1129
- {
1130
- "char": " ",
1131
- "name": "six-per-em space",
1132
- "code": "U+2006"
1133
- },
1134
- {
1135
- "char": " ",
1136
- "name": "figure space",
1137
- "code": "U+2007"
1138
- },
1139
- {
1140
- "char": " ",
1141
- "name": "punctuation space",
1142
- "code": "U+2008"
1143
- },
1144
- {
1145
- "char": " ",
1146
- "name": "medium mathematical space",
1147
- "code": "U+205F"
1148
- },
1149
- {
1150
- "char": " ",
1151
- "name": "ideographic space",
1152
- "code": "U+3000"
1153
- },
1154
- {
1155
- "char": "​",
1156
- "name": "zero width space",
1157
- "code": "U+200B"
1158
- }
1159
- ]
1160
- },
1161
- "quote-double": {
1162
- "description": "Double quotation marks",
1163
- "chars": [
1164
- {
1165
- "char": "\"",
1166
- "name": "quotation mark",
1167
- "code": "U+0022"
1168
- },
1169
- {
1170
- "char": "“",
1171
- "name": "left double quotation mark",
1172
- "code": "U+201C"
1173
- },
1174
- {
1175
- "char": "”",
1176
- "name": "right double quotation mark",
1177
- "code": "U+201D"
1178
- },
1179
- {
1180
- "char": "„",
1181
- "name": "double low-9 quotation mark",
1182
- "code": "U+201E"
1183
- },
1184
- {
1185
- "char": "«",
1186
- "name": "left guillemet",
1187
- "code": "U+00AB"
1188
- },
1189
- {
1190
- "char": "»",
1191
- "name": "right guillemet",
1192
- "code": "U+00BB"
1193
- }
1194
- ]
1195
- },
1196
- "quote-single": {
1197
- "description": "Single quotation marks and apostrophes",
1198
- "chars": [
1199
- {
1200
- "char": "'",
1201
- "name": "apostrophe",
1202
- "code": "U+0027"
1203
- },
1204
- {
1205
- "char": "‘",
1206
- "name": "left single quotation mark",
1207
- "code": "U+2018"
1208
- },
1209
- {
1210
- "char": "’",
1211
- "name": "right single quotation mark",
1212
- "code": "U+2019"
1213
- },
1214
- {
1215
- "char": "‚",
1216
- "name": "single low-9 quotation mark",
1217
- "code": "U+201A"
1218
- },
1219
- {
1220
- "char": "‹",
1221
- "name": "left single guillemet",
1222
- "code": "U+2039"
1223
- },
1224
- {
1225
- "char": "›",
1226
- "name": "right single guillemet",
1227
- "code": "U+203A"
1228
- },
1229
- {
1230
- "char": "ʼ",
1231
- "name": "modifier letter apostrophe",
1232
- "code": "U+02BC"
1233
- },
1234
- {
1235
- "char": "´",
1236
- "name": "acute accent",
1237
- "code": "U+00B4"
1238
- },
1239
- {
1240
- "char": "`",
1241
- "name": "grave accent",
1242
- "code": "U+0060"
1243
- },
1244
- {
1245
- "char": "ʽ",
1246
- "name": "modifier letter reversed comma",
1247
- "code": "U+02BD"
1248
- },
1249
- {
1250
- "char": "ʾ",
1251
- "name": "modifier letter right half ring",
1252
- "code": "U+02BE"
1253
- },
1254
- {
1255
- "char": "ʿ",
1256
- "name": "modifier letter left half ring",
1257
- "code": "U+02BF"
1258
- },
1259
- {
1260
- "char": "ˈ",
1261
- "name": "modifier letter vertical line",
1262
- "code": "U+02C8"
1263
- }
1264
- ]
1265
- },
1266
- "dot": {
1267
- "description": "Dot-like characters",
1268
- "chars": [
1269
- {
1270
- "char": ".",
1271
- "name": "full stop",
1272
- "code": "U+002E"
1273
- },
1274
- {
1275
- "char": "·",
1276
- "name": "middle dot",
1277
- "code": "U+00B7"
1278
- },
1279
- {
1280
- "char": "•",
1281
- "name": "bullet",
1282
- "code": "U+2022"
1283
- },
1284
- {
1285
- "char": "․",
1286
- "name": "one dot leader",
1287
- "code": "U+2024"
1288
- },
1289
- {
1290
- "char": "。",
1291
- "name": "CJK full stop",
1292
- "code": "U+3002"
1293
- },
1294
- {
1295
- "char": "׃",
1296
- "name": "Hebrew sof pasuq",
1297
- "code": "U+05C3"
1298
- }
1299
- ]
1300
- },
1301
- "slash": {
1302
- "description": "Slash-like characters",
1303
- "chars": [
1304
- {
1305
- "char": "/",
1306
- "name": "solidus",
1307
- "code": "U+002F"
1308
- },
1309
- {
1310
- "char": "⁄",
1311
- "name": "fraction slash",
1312
- "code": "U+2044"
1313
- },
1314
- {
1315
- "char": "∕",
1316
- "name": "division slash",
1317
- "code": "U+2215"
1318
- }
1319
- ]
1320
- },
1321
- "colon": {
1322
- "description": "Colon-like characters",
1323
- "chars": [
1324
- {
1325
- "char": ":",
1326
- "name": "colon",
1327
- "code": "U+003A"
1328
- },
1329
- {
1330
- "char": "꞉",
1331
- "name": "modifier letter colon",
1332
- "code": "U+A789"
1333
- },
1334
- {
1335
- "char": "∶",
1336
- "name": "ratio",
1337
- "code": "U+2236"
1338
- },
1339
- {
1340
- "char": ":",
1341
- "name": "full-width colon",
1342
- "code": "U+FF1A"
1343
- },
1344
- {
1345
- "char": "፥",
1346
- "name": "Ethiopic colon",
1347
- "code": "U+1365"
1348
- }
1349
- ]
1350
- },
1351
- "comma": {
1352
- "description": "Comma-like characters",
1353
- "chars": [
1354
- {
1355
- "char": ",",
1356
- "name": "comma",
1357
- "code": "U+002C"
1358
- },
1359
- {
1360
- "char": "‚",
1361
- "name": "single low-9 quotation mark (used as comma)",
1362
- "code": "U+201A"
1363
- },
1364
- {
1365
- "char": "،",
1366
- "name": "Arabic comma",
1367
- "code": "U+060C"
1368
- },
1369
- {
1370
- "char": "、",
1371
- "name": "ideographic comma",
1372
- "code": "U+3001"
1373
- },
1374
- {
1375
- "char": ",",
1376
- "name": "full-width comma",
1377
- "code": "U+FF0C"
1378
- },
1379
- {
1380
- "char": "﹐",
1381
- "name": "small comma",
1382
- "code": "U+FE50"
1383
- },
1384
- {
1385
- "char": "՝",
1386
- "name": "Armenian comma",
1387
- "code": "U+055D"
1388
- }
1389
- ]
1390
- },
1391
- "ellipsis": {
1392
- "description": "Ellipsis characters",
1393
- "chars": [{
1394
- "char": "…",
1395
- "name": "horizontal ellipsis",
1396
- "code": "U+2026"
1397
- }]
1398
- },
1399
- "question-mark": {
1400
- "description": "Question mark variants",
1401
- "chars": [
1402
- {
1403
- "char": "?",
1404
- "name": "question mark",
1405
- "code": "U+003F"
1406
- },
1407
- {
1408
- "char": "?",
1409
- "name": "full-width question mark",
1410
- "code": "U+FF1F"
1411
- },
1412
- {
1413
- "char": "⁇",
1414
- "name": "double question mark",
1415
- "code": "U+2047"
1416
- },
1417
- {
1418
- "char": "⁈",
1419
- "name": "question exclamation mark",
1420
- "code": "U+2048"
1421
- },
1422
- {
1423
- "char": "؟",
1424
- "name": "Arabic question mark",
1425
- "code": "U+061F"
1426
- },
1427
- {
1428
- "char": "‽",
1429
- "name": "interrobang",
1430
- "code": "U+203D"
1431
- }
1432
- ]
1433
- },
1434
- "exclamation-mark": {
1435
- "description": "Exclamation mark variants",
1436
- "chars": [
1437
- {
1438
- "char": "!",
1439
- "name": "exclamation mark",
1440
- "code": "U+0021"
1441
- },
1442
- {
1443
- "char": "!",
1444
- "name": "full-width exclamation mark",
1445
- "code": "U+FF01"
1446
- },
1447
- {
1448
- "char": "‼",
1449
- "name": "double exclamation mark",
1450
- "code": "U+203C"
1451
- },
1452
- {
1453
- "char": "¡",
1454
- "name": "inverted exclamation mark",
1455
- "code": "U+00A1"
1456
- }
1457
- ]
1458
- },
1459
- "semicolon": {
1460
- "description": "Semicolon variants",
1461
- "chars": [
1462
- {
1463
- "char": ";",
1464
- "name": "semicolon",
1465
- "code": "U+003B"
1466
- },
1467
- {
1468
- "char": "؛",
1469
- "name": "Arabic semicolon",
1470
- "code": "U+061B"
1471
- },
1472
- {
1473
- "char": ";",
1474
- "name": "full-width semicolon",
1475
- "code": "U+FF1B"
1476
- },
1477
- {
1478
- "char": "፤",
1479
- "name": "Ethiopic semicolon",
1480
- "code": "U+1364"
1481
- }
1482
- ]
1483
- },
1484
- "underscore": {
1485
- "description": "Underscore variants",
1486
- "chars": [{
1487
- "char": "_",
1488
- "name": "low line",
1489
- "code": "U+005F"
1490
- }, {
1491
- "char": "_",
1492
- "name": "full-width low line",
1493
- "code": "U+FF3F"
1494
- }]
1495
- }
1496
- }
1497
- };
1498
- //#endregion
1499
1055
  //#region src/util/char-groups.ts
1056
+ /**
1057
+ * Centralized Unicode character equivalence groups.
1058
+ *
1059
+ * Loads char-groups.json from @stll/anonymize-data and
1060
+ * provides helpers to build regex character classes that
1061
+ * match all typographic variants of a character type
1062
+ * (dashes, spaces, quotes, etc.).
1063
+ *
1064
+ * The JSON is statically imported so the bundler inlines
1065
+ * it, avoiding a runtime require() that breaks browsers.
1066
+ */
1500
1067
  /** Chars that need escaping inside a regex char class. */
1501
1068
  const REGEX_CLASS_SPECIAL = /[\\\]^-]/;
1502
1069
  const escapeForCharClass = (ch) => REGEX_CLASS_SPECIAL.test(ch) ? `\\${ch}` : ch;
1503
- const loadConfig = () => char_groups_data_default;
1070
+ const config = charGroupsJson;
1504
1071
  /**
1505
1072
  * Get the raw characters for a named group.
1506
1073
  * Throws if the group does not exist.
1507
1074
  */
1508
1075
  const charSet = (group) => {
1509
- const g = loadConfig().groups[group];
1076
+ const g = config.groups[group];
1510
1077
  if (!g) throw new Error(`Unknown char group: "${group}"`);
1511
1078
  return g.chars.map((entry) => entry.char);
1512
1079
  };
@@ -1696,7 +1263,7 @@ const CZ_BIRTH_NUMBER = {
1696
1263
  validator: cz.rc
1697
1264
  };
1698
1265
  const DATE_NUMERIC = {
1699
- pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2})\\b",
1266
+ pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2}|\\d{4}\\.\\d{2}\\.\\d{2})\\b",
1700
1267
  label: "date",
1701
1268
  score: 1
1702
1269
  };
@@ -1782,6 +1349,11 @@ const ALL_REGEX_DEFS = [
1782
1349
  label: "url",
1783
1350
  score: .9
1784
1351
  },
1352
+ {
1353
+ pattern: "\\b(?:1[0-2]|0?[1-9]):[0-5]\\d[^\\S\\n]?(?:[aApP]\\.?[mM]\\.?)(?=[\\s,;!?)]|$)",
1354
+ label: "date",
1355
+ score: .9
1356
+ },
1785
1357
  ...STDNUM_ENTRIES
1786
1358
  ];
1787
1359
  /** Flat pattern array for text-search. */
@@ -2765,6 +2337,7 @@ const TEMPLATE_PLACEHOLDER_RE = /^(?:\.{3,}|_{3,}|\[[\w\s]+\]|\{[\w\s]+\})$/;
2765
2337
  const POSTAL_CODE_RE = /\d{3}\s?\d{2}/;
2766
2338
  const HAS_DIGIT_RE = /\d/;
2767
2339
  const ADDRESS_COMPONENTS_RE = /(?:^|\s)(?:ul\.|ulice|nám\.|náměstí|tř\.|třída|nábř\.|nábřeží|č\.p\.|č\.ev\.|č\.|sídliště|bulvár)(?=[\s,./]|$)/i;
2340
+ const JURISDICTION_RE = /^(?:state|commonwealth|district|territory)\s+of\s+/i;
2768
2341
  const MAX_ENTITY_LENGTH = {
2769
2342
  organization: 80,
2770
2343
  person: 60
@@ -2816,8 +2389,8 @@ const filterFalsePositives = (entities, ctx = defaultContext) => {
2816
2389
  if (STANDALONE_YEAR_RE.test(trimmed)) continue;
2817
2390
  if (entity.label === "person" && HAS_DIGIT_RE.test(trimmed)) continue;
2818
2391
  if ((entity.label === "person" || entity.label === "organization") && roles.has(trimmed.toLowerCase())) continue;
2819
- if (entity.label === "address" && trimmed.length > 40 && !POSTAL_CODE_RE.test(trimmed) && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
2820
- if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
2392
+ if (entity.label === "address" && trimmed.length > 40 && !POSTAL_CODE_RE.test(trimmed) && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed) && !JURISDICTION_RE.test(trimmed)) continue;
2393
+ if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed) && !JURISDICTION_RE.test(trimmed)) continue;
2821
2394
  filtered.push(entity);
2822
2395
  }
2823
2396
  return filtered;
@@ -4090,7 +3663,7 @@ const loadRules = async () => {
4090
3663
  mapping.push(ruleIdx);
4091
3664
  }
4092
3665
  }
4093
- const builtSearch = patterns.length > 0 ? new TextSearch(patterns, {
3666
+ const builtSearch = patterns.length > 0 ? new (getTextSearch())(patterns, {
4094
3667
  overlapStrategy: "all",
4095
3668
  caseInsensitive: true,
4096
3669
  wholeWords: true
@@ -4482,24 +4055,6 @@ const enforceBoundaryConsistency = (entities, fullText) => {
4482
4055
  };
4483
4056
  //#endregion
4484
4057
  //#region src/build-unified-search.ts
4485
- /**
4486
- * Build the unified search instances from all
4487
- * detector pattern sources.
4488
- *
4489
- * Two TextSearch instances (not one) to avoid
4490
- * 200K per-pattern object allocations:
4491
- * 1. regex + triggers + legal-forms (mixed, ~140
4492
- * patterns, caseInsensitive for trigger AC)
4493
- * 2. deny-list + street-types + gazetteer
4494
- * (caseInsensitive, overlap "all";
4495
- * deny-list/street-type use per-pattern
4496
- * wholeWords: true; gazetteer exact use
4497
- * wholeWords: false; gazetteer fuzzy use
4498
- * distance: 2 via @stll/fuzzy-search)
4499
- *
4500
- * All patterns are PatternEntry objects with
4501
- * per-pattern literal/wholeWords settings.
4502
- */
4503
4058
  const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultContext) => {
4504
4059
  const [legalForms, triggers, denyListData, streetTypes, currencyPatterns, datePatterns, signingPatterns] = await Promise.all([
4505
4060
  buildLegalFormPatterns(),
@@ -4545,11 +4100,12 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
4545
4100
  literal: true,
4546
4101
  caseInsensitive: true
4547
4102
  }));
4548
- const tsRegex = new TextSearch([
4103
+ const regexAllPatterns = [
4549
4104
  ...allRegex,
4550
4105
  ...legalForms,
4551
4106
  ...triggerEntries
4552
- ]);
4107
+ ];
4108
+ const tsRegex = new (getTextSearch())(regexAllPatterns);
4553
4109
  offset = 0;
4554
4110
  const denyListOriginals = denyListData?.originals ?? [];
4555
4111
  const denyListSlice = {
@@ -4580,10 +4136,10 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
4580
4136
  ];
4581
4137
  return {
4582
4138
  tsRegex,
4583
- tsLiterals: literalAllPatterns.length > 0 ? new TextSearch(literalAllPatterns, {
4139
+ tsLiterals: literalAllPatterns.length > 0 ? new (getTextSearch())(literalAllPatterns, {
4584
4140
  caseInsensitive: true,
4585
4141
  overlapStrategy: "all"
4586
- }) : new TextSearch([]),
4142
+ }) : new (getTextSearch())([]),
4587
4143
  slices: {
4588
4144
  regex: regexSlice,
4589
4145
  legalForms: legalFormsSlice,
@@ -5551,6 +5107,9 @@ const levenshtein = (rawA, rawB) => {
5551
5107
  return row[aLen] ?? 0;
5552
5108
  };
5553
5109
  //#endregion
5110
+ //#region src/index.ts
5111
+ initTextSearch(TextSearch);
5112
+ //#endregion
5554
5113
  export { CURRENCY_PATTERN_META, DATE_PATTERN_META, DEFAULT_ENTITY_LABELS, DEFAULT_OPERATOR_CONFIG, DETECTION_SOURCES, DETECTOR_PRIORITY, OPERATOR_REGISTRY, OPERATOR_TYPES, REGEX_META, REGEX_PATTERNS, REGIONS, ZONE_SCORE_ADJUSTMENTS, applyHotwordRules, applyZoneAdjustments, boostNearMissEntities, buildDenyList, buildGazetteerPatterns, buildLegalFormPatterns, buildPlaceholderMap, buildStreetTypePatterns, buildTriggerPatterns, buildUnifiedSearch, chunkText, classifyZones, computeChunkOffsets, corefKey, createPipelineContext, deanonymise, decodeSpans, decodeTokenSpans, detectNameCorpus, ensureDenyListData, exportRedactionKey, extractDefinedTerms, filterFalsePositives, findCoreferenceSpans, getCurrencyPatterns, getDatePatterns, initHotwordRules, initNameCorpus, initZoneClassifier, levenshtein, mergeAndDedup, mergeChunkEntities, normalizeForSearch, prepareBatch, processAddressSeeds, processDenyListMatches, processGazetteerMatches, processLegalFormMatches, processRegexMatches, processTriggerMatches, propagateOrgNames, redactText, resolveCountries, resolveOperator, runPipeline, runUnifiedSearch, sanitizeEntities, tokenizeText };
5555
5114
 
5556
- //# sourceMappingURL=index.js.map
5115
+ //# sourceMappingURL=index.mjs.map