@stll/anonymize-wasm 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities.d.mts +139 -4
- package/dist/capabilities.mjs +88 -3
- package/dist/capabilities.mjs.map +1 -1
- package/dist/constants.mjs +9 -4
- package/dist/constants.mjs.map +1 -1
- package/dist/constants2.d.mts +8 -4
- package/dist/native/index.wasi-browser.js +6 -0
- package/dist/native/index.wasi.cjs +3 -0
- package/dist/native/index.wasm32-wasi.wasm +0 -0
- package/dist/native/native-pipeline.cs.stlanonpkg +0 -0
- package/dist/native/native-pipeline.de.stlanonpkg +0 -0
- package/dist/native/native-pipeline.en.stlanonpkg +0 -0
- package/dist/native/native-pipeline.stlanonpkg +0 -0
- package/dist/wasm.d.mts +22 -15
- package/dist/wasm.mjs +61 -14
- package/dist/wasm.mjs.map +1 -1
- package/package.json +1 -1
package/dist/wasm.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_ENTITY_LABELS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, OPERATOR_TYPES } from "./constants.mjs";
|
|
2
|
-
import { CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_RUNTIMES } from "./capabilities.mjs";
|
|
2
|
+
import { CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES } from "./capabilities.mjs";
|
|
3
3
|
//#region src/native.ts
|
|
4
4
|
const CALLER_DETECTION_CONTRACT_VERSION = 2;
|
|
5
5
|
const callerDetectionRequestJson = (detections) => JSON.stringify({
|
|
@@ -706,12 +706,31 @@ const pipelineConfigKey = (config, gazetteerEntries) => {
|
|
|
706
706
|
const gazFingerprint = config.enableGazetteer && gazetteerEntries.length > 0 ? gazetteerEntries.map((entry) => `${entry.id}:${entry.canonical}:${entry.label}:${[...entry.variants].sort().join(",")}`).toSorted().join(";") : "";
|
|
707
707
|
return `${config.enableDenyList}:${config.enableTriggerPhrases}:${legalFormsEnabled}:${config.enableNameCorpus}:${contentLanguageFingerprint(config)}:${config.nameCorpusLanguages?.toSorted().join(",") ?? ""}:${config.enableRegex}:${config.threshold}:${config.enableConfidenceBoost}:${config.enableHotwordRules === true}:${config.enableCoreference === true}:${config.enableZoneClassification === true}:${config.labels.toSorted().join(",")}:${config.denyListCountries?.toSorted().join(",") ?? ""}:${config.denyListRegions?.toSorted().join(",") ?? ""}:${config.denyListExcludeCategories?.toSorted().join(",") ?? ""}:${customDenyFingerprint}:${customRegexFingerprint}:${config.enableGazetteer}:${gazFingerprint}:${config.enableCountries !== false}`;
|
|
708
708
|
};
|
|
709
|
-
//#endregion
|
|
710
|
-
//#region src/native-pipeline.ts
|
|
711
709
|
const sharedPackageByDictionaries = /* @__PURE__ */ new WeakMap();
|
|
712
710
|
const sharedPackageWithoutDictionaries = /* @__PURE__ */ new Map();
|
|
713
711
|
const dictionaryCacheIds = /* @__PURE__ */ new WeakMap();
|
|
714
712
|
let nextDictionaryCacheId = 0;
|
|
713
|
+
/** Record `key` as most-recently-used in `cache`, evicting the
|
|
714
|
+
* least-recently-used entry first once the cache is at capacity. A `Map`'s
|
|
715
|
+
* insertion order doubles as recency order here: touching an existing key
|
|
716
|
+
* deletes then re-sets it to move it to the end, and eviction drops the
|
|
717
|
+
* first (oldest) key.
|
|
718
|
+
*
|
|
719
|
+
* Evicting a still-in-flight build only drops the cache's reference to its
|
|
720
|
+
* promise; the caller that started the build (and any concurrent caller that
|
|
721
|
+
* already read the promise before eviction) still resolves it correctly via
|
|
722
|
+
* the guarded `sharedCache.get(key) === promise` checks in
|
|
723
|
+
* `getCachedNativePipelinePackage`. A later caller for the same key just
|
|
724
|
+
* misses the dedupe and starts a fresh build — bounded memory takes priority
|
|
725
|
+
* over perfect dedupe under cache pressure. */
|
|
726
|
+
const touchSharedPackageCacheEntry = (cache, key, value) => {
|
|
727
|
+
cache.delete(key);
|
|
728
|
+
if (cache.size >= 32) {
|
|
729
|
+
const oldestKey = cache.keys().next().value;
|
|
730
|
+
if (oldestKey !== void 0) cache.delete(oldestKey);
|
|
731
|
+
}
|
|
732
|
+
cache.set(key, value);
|
|
733
|
+
};
|
|
715
734
|
const dictionaryCacheKey = (dictionaries) => {
|
|
716
735
|
if (dictionaries === void 0) return "none";
|
|
717
736
|
const existing = dictionaryCacheIds.get(dictionaries);
|
|
@@ -730,7 +749,7 @@ const sharedPackageCacheFor = (dictionaries) => {
|
|
|
730
749
|
};
|
|
731
750
|
const getNativePipelineCompatibility = (config) => {
|
|
732
751
|
const unsupportedFeatures = [];
|
|
733
|
-
if (config.enableNer) unsupportedFeatures.push("enableNer");
|
|
752
|
+
if ("enableNer" in config && Boolean(config.enableNer)) unsupportedFeatures.push("enableNer");
|
|
734
753
|
if (unsupportedFeatures.length === 0) return { status: "supported" };
|
|
735
754
|
return {
|
|
736
755
|
status: "unsupported",
|
|
@@ -749,11 +768,8 @@ const encoder = new TextEncoder();
|
|
|
749
768
|
* the separate bundle preferentially, and keeping the (large) dictionaries out
|
|
750
769
|
* of the config JSON avoids serializing them twice.
|
|
751
770
|
*/
|
|
752
|
-
const toAssembleInputs = ({ dictionaries,
|
|
753
|
-
pipelineConfigJson: encoder.encode(JSON.stringify(
|
|
754
|
-
...config,
|
|
755
|
-
enableNer
|
|
756
|
-
})),
|
|
771
|
+
const toAssembleInputs = ({ dictionaries, ...config }, gazetteerEntries) => ({
|
|
772
|
+
pipelineConfigJson: encoder.encode(JSON.stringify(config)),
|
|
757
773
|
dictionariesJson: dictionaries === void 0 ? void 0 : encoder.encode(JSON.stringify(dictionaries)),
|
|
758
774
|
gazetteerJson: gazetteerEntries.length === 0 ? void 0 : encoder.encode(JSON.stringify(gazetteerEntries))
|
|
759
775
|
});
|
|
@@ -807,6 +823,7 @@ const getCachedNativePipelinePackage = async ({ binding, config, gazetteerEntrie
|
|
|
807
823
|
const sharedCache = sharedPackageCacheFor(scopedConfig.dictionaries);
|
|
808
824
|
const shared = sharedCache.get(key);
|
|
809
825
|
if (shared !== void 0) {
|
|
826
|
+
touchSharedPackageCacheEntry(sharedCache, key, shared);
|
|
810
827
|
const packageBytes = await shared;
|
|
811
828
|
ctx.nativePipelinePackage = packageBytes;
|
|
812
829
|
ctx.nativePipelinePackageKey = key;
|
|
@@ -822,7 +839,7 @@ const getCachedNativePipelinePackage = async ({ binding, config, gazetteerEntrie
|
|
|
822
839
|
compressed
|
|
823
840
|
});
|
|
824
841
|
ctx.nativePipelinePackagePromise = promise;
|
|
825
|
-
sharedCache
|
|
842
|
+
touchSharedPackageCacheEntry(sharedCache, key, promise);
|
|
826
843
|
let packageBytes;
|
|
827
844
|
try {
|
|
828
845
|
packageBytes = await promise;
|
|
@@ -856,6 +873,8 @@ const NODE_FS_MODULE = "node:fs/promises";
|
|
|
856
873
|
const NATIVE_ASSET_DIR = "native";
|
|
857
874
|
const DEFAULT_PACKAGE_FILE = "native-pipeline.stlanonpkg";
|
|
858
875
|
const LANGUAGE_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
876
|
+
const DEFAULT_PIPELINE_CACHE_KEY = "<default>";
|
|
877
|
+
const DEFAULT_PIPELINE_CACHE_MAX_ENTRIES = 32;
|
|
859
878
|
let bindingPromise;
|
|
860
879
|
const defaultPipelineCache = /* @__PURE__ */ new Map();
|
|
861
880
|
/** Instantiate (once) and return the wasm binding. Safe to call repeatedly:
|
|
@@ -933,6 +952,26 @@ const loadDefaultPipeline = async (language, options) => {
|
|
|
933
952
|
return loadPipeline(defaultPackageUrl(baseLanguage), options);
|
|
934
953
|
}
|
|
935
954
|
};
|
|
955
|
+
/** Normalized cache key for {@link defaultPipelineCache}: `undefined` maps to
|
|
956
|
+
* the bundled-default sentinel, everything else goes through the same
|
|
957
|
+
* {@link normalizeLanguage} helper `loadDefaultPipeline`/`defaultPackageUrl`
|
|
958
|
+
* already validate against, so aliases that differ only by case or whitespace
|
|
959
|
+
* (e.g. `"EN"` vs `"en"`) share one cached pipeline instead of each minting
|
|
960
|
+
* their own. */
|
|
961
|
+
const defaultPipelineCacheKey = (language) => language === void 0 ? DEFAULT_PIPELINE_CACHE_KEY : normalizeLanguage(language);
|
|
962
|
+
/** Record `key` as most-recently-used in {@link defaultPipelineCache},
|
|
963
|
+
* evicting the least-recently-used entry first once the cache is at
|
|
964
|
+
* capacity. A `Map`'s insertion order doubles as recency order here: touching
|
|
965
|
+
* an existing key deletes then re-sets it to move it to the end, and
|
|
966
|
+
* eviction drops the first (oldest) key. */
|
|
967
|
+
const touchDefaultPipelineCacheEntry = (key, pipeline) => {
|
|
968
|
+
defaultPipelineCache.delete(key);
|
|
969
|
+
if (defaultPipelineCache.size >= DEFAULT_PIPELINE_CACHE_MAX_ENTRIES) {
|
|
970
|
+
const oldestKey = defaultPipelineCache.keys().next().value;
|
|
971
|
+
if (oldestKey !== void 0) defaultPipelineCache.delete(oldestKey);
|
|
972
|
+
}
|
|
973
|
+
defaultPipelineCache.set(key, pipeline);
|
|
974
|
+
};
|
|
936
975
|
/** Cached variant of {@link loadDefaultPipeline}: the default pipeline for a
|
|
937
976
|
* given language is fetched and prepared once, then reused.
|
|
938
977
|
*
|
|
@@ -943,14 +982,22 @@ const loadDefaultPipeline = async (language, options) => {
|
|
|
943
982
|
* alive. Injected-binding callers get a fresh pipeline each call. */
|
|
944
983
|
const getDefaultPipeline = (language, options) => {
|
|
945
984
|
if (options?.binding) return loadDefaultPipeline(language, options);
|
|
946
|
-
|
|
985
|
+
let key;
|
|
986
|
+
try {
|
|
987
|
+
key = defaultPipelineCacheKey(language);
|
|
988
|
+
} catch (error) {
|
|
989
|
+
return Promise.reject(error);
|
|
990
|
+
}
|
|
947
991
|
const cached = defaultPipelineCache.get(key);
|
|
948
|
-
if (cached !== void 0)
|
|
992
|
+
if (cached !== void 0) {
|
|
993
|
+
touchDefaultPipelineCacheEntry(key, cached);
|
|
994
|
+
return cached;
|
|
995
|
+
}
|
|
949
996
|
const pipeline = loadDefaultPipeline(language).catch((error) => {
|
|
950
997
|
defaultPipelineCache.delete(key);
|
|
951
998
|
throw error;
|
|
952
999
|
});
|
|
953
|
-
|
|
1000
|
+
touchDefaultPipelineCacheEntry(key, pipeline);
|
|
954
1001
|
return pipeline;
|
|
955
1002
|
};
|
|
956
1003
|
const redactDefaultText = async (fullText, operators, language) => (await getDefaultPipeline(language)).redactText(fullText, operators);
|
|
@@ -1030,6 +1077,6 @@ const normalizeLanguage = (language) => {
|
|
|
1030
1077
|
return normalized;
|
|
1031
1078
|
};
|
|
1032
1079
|
//#endregion
|
|
1033
|
-
export { CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_RUNTIMES, DEFAULT_ENTITY_LABELS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, OPERATOR_TYPES, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, assertNativeBindingVersion, assertNativePipelineSupported, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromPackage, createPipelineContext, deanonymise, defaultPackageUrl, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getBinding, getDefaultPipeline, getNativeBindingVersion, getNativePipelineCompatibility, loadDefaultPipeline, loadPipeline, load_prepared_package, native_package_version, normalize_for_search, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, redactDefaultText, redactDefaultTextJson, redact_text, redact_text_json, redact_text_stream_json, summary_diagnostics_json };
|
|
1080
|
+
export { CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, DEFAULT_ENTITY_LABELS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, OPERATOR_TYPES, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, assertNativeBindingVersion, assertNativePipelineSupported, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromPackage, createPipelineContext, deanonymise, defaultPackageUrl, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getBinding, getDefaultPipeline, getNativeBindingVersion, getNativePipelineCompatibility, loadDefaultPipeline, loadPipeline, load_prepared_package, native_package_version, normalize_for_search, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, redactDefaultText, redactDefaultTextJson, redact_text, redact_text_json, redact_text_stream_json, summary_diagnostics_json };
|
|
1034
1081
|
|
|
1035
1082
|
//# sourceMappingURL=wasm.mjs.map
|