@stll/anonymize-wasm 1.5.0 → 2.0.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.
Files changed (152) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +93 -4
  3. package/dist/native/index.wasi-browser.js +12002 -0
  4. package/dist/native/index.wasi.cjs +122 -0
  5. package/dist/native/index.wasm32-wasi.wasm +0 -0
  6. package/dist/native/native-pipeline.cs.stlanonpkg +0 -0
  7. package/dist/native/native-pipeline.de.stlanonpkg +0 -0
  8. package/dist/native/native-pipeline.en.stlanonpkg +0 -0
  9. package/dist/native/native-pipeline.stlanonpkg +0 -0
  10. package/dist/native/wasi-worker-browser.mjs +10766 -0
  11. package/dist/native/wasi-worker.mjs +63 -0
  12. package/dist/vite.d.mts +18 -2
  13. package/dist/vite.mjs +89 -12
  14. package/dist/vite.mjs.map +1 -1
  15. package/dist/wasm.d.mts +553 -1102
  16. package/dist/wasm.mjs +359 -16223
  17. package/dist/wasm.mjs.map +1 -1
  18. package/package.json +15 -9
  19. package/dist/address-boundaries.mjs +0 -195
  20. package/dist/address-boundaries.mjs.map +0 -1
  21. package/dist/address-prepositions.mjs +0 -182
  22. package/dist/address-prepositions.mjs.map +0 -1
  23. package/dist/address-stop-keywords.mjs +0 -137
  24. package/dist/address-stop-keywords.mjs.map +0 -1
  25. package/dist/address-stopwords.mjs +0 -84
  26. package/dist/address-stopwords.mjs.map +0 -1
  27. package/dist/allow-list.mjs +0 -196
  28. package/dist/allow-list.mjs.map +0 -1
  29. package/dist/clause-noun-heads.mjs +0 -75
  30. package/dist/clause-noun-heads.mjs.map +0 -1
  31. package/dist/common-words-en.mjs +0 -9887
  32. package/dist/common-words-en.mjs.map +0 -1
  33. package/dist/coreference.cs.mjs +0 -14
  34. package/dist/coreference.cs.mjs.map +0 -1
  35. package/dist/coreference.de.mjs +0 -14
  36. package/dist/coreference.de.mjs.map +0 -1
  37. package/dist/coreference.en.mjs +0 -14
  38. package/dist/coreference.en.mjs.map +0 -1
  39. package/dist/coreference.es.mjs +0 -22
  40. package/dist/coreference.es.mjs.map +0 -1
  41. package/dist/coreference.fr.mjs +0 -32
  42. package/dist/coreference.fr.mjs.map +0 -1
  43. package/dist/coreference.it.mjs +0 -27
  44. package/dist/coreference.it.mjs.map +0 -1
  45. package/dist/coreference.pl.mjs +0 -27
  46. package/dist/coreference.pl.mjs.map +0 -1
  47. package/dist/coreference.pt-br.mjs +0 -14
  48. package/dist/coreference.pt-br.mjs.map +0 -1
  49. package/dist/coreference.sk.mjs +0 -27
  50. package/dist/coreference.sk.mjs.map +0 -1
  51. package/dist/currencies.mjs +0 -231
  52. package/dist/currencies.mjs.map +0 -1
  53. package/dist/date-months.mjs +0 -618
  54. package/dist/date-months.mjs.map +0 -1
  55. package/dist/document-structure-headings.mjs +0 -90
  56. package/dist/document-structure-headings.mjs.map +0 -1
  57. package/dist/generic-roles.mjs +0 -244
  58. package/dist/generic-roles.mjs.map +0 -1
  59. package/dist/hotword-rules.mjs +0 -149
  60. package/dist/hotword-rules.mjs.map +0 -1
  61. package/dist/legal-form-leading-clauses.mjs +0 -23
  62. package/dist/legal-form-leading-clauses.mjs.map +0 -1
  63. package/dist/legal-forms.mjs +0 -2115
  64. package/dist/legal-forms.mjs.map +0 -1
  65. package/dist/legal-role-heads.cs.mjs +0 -42
  66. package/dist/legal-role-heads.cs.mjs.map +0 -1
  67. package/dist/legal-role-heads.de.mjs +0 -33
  68. package/dist/legal-role-heads.de.mjs.map +0 -1
  69. package/dist/legal-role-heads.en.mjs +0 -37
  70. package/dist/legal-role-heads.en.mjs.map +0 -1
  71. package/dist/legal-role-heads.es.mjs +0 -54
  72. package/dist/legal-role-heads.es.mjs.map +0 -1
  73. package/dist/legal-role-heads.fr.mjs +0 -72
  74. package/dist/legal-role-heads.fr.mjs.map +0 -1
  75. package/dist/legal-role-heads.it.mjs +0 -68
  76. package/dist/legal-role-heads.it.mjs.map +0 -1
  77. package/dist/legal-role-heads.pl.mjs +0 -84
  78. package/dist/legal-role-heads.pl.mjs.map +0 -1
  79. package/dist/legal-role-heads.pt-br.mjs +0 -63
  80. package/dist/legal-role-heads.pt-br.mjs.map +0 -1
  81. package/dist/legal-role-heads.sk.mjs +0 -80
  82. package/dist/legal-role-heads.sk.mjs.map +0 -1
  83. package/dist/manifest.mjs +0 -69
  84. package/dist/manifest.mjs.map +0 -1
  85. package/dist/names-exclusions.mjs +0 -223
  86. package/dist/names-exclusions.mjs.map +0 -1
  87. package/dist/names-first.mjs +0 -418
  88. package/dist/names-first.mjs.map +0 -1
  89. package/dist/names-nw-ar.mjs +0 -202
  90. package/dist/names-nw-ar.mjs.map +0 -1
  91. package/dist/names-nw-excluded-allcaps.mjs +0 -112
  92. package/dist/names-nw-excluded-allcaps.mjs.map +0 -1
  93. package/dist/names-nw-fil.mjs +0 -202
  94. package/dist/names-nw-fil.mjs.map +0 -1
  95. package/dist/names-nw-id.mjs +0 -210
  96. package/dist/names-nw-id.mjs.map +0 -1
  97. package/dist/names-nw-in.mjs +0 -526
  98. package/dist/names-nw-in.mjs.map +0 -1
  99. package/dist/names-nw-ja-latn.mjs +0 -260
  100. package/dist/names-nw-ja-latn.mjs.map +0 -1
  101. package/dist/names-nw-ko.mjs +0 -162
  102. package/dist/names-nw-ko.mjs.map +0 -1
  103. package/dist/names-nw-th.mjs +0 -188
  104. package/dist/names-nw-th.mjs.map +0 -1
  105. package/dist/names-nw-vi.mjs +0 -151
  106. package/dist/names-nw-vi.mjs.map +0 -1
  107. package/dist/names-nw-zh-latn.mjs +0 -197
  108. package/dist/names-nw-zh-latn.mjs.map +0 -1
  109. package/dist/names-surnames.mjs +0 -113
  110. package/dist/names-surnames.mjs.map +0 -1
  111. package/dist/names-title-tokens.mjs +0 -40
  112. package/dist/names-title-tokens.mjs.map +0 -1
  113. package/dist/person-stopwords.mjs +0 -205
  114. package/dist/person-stopwords.mjs.map +0 -1
  115. package/dist/section-headings.mjs +0 -64
  116. package/dist/section-headings.mjs.map +0 -1
  117. package/dist/sentence-verb-indicators.mjs +0 -232
  118. package/dist/sentence-verb-indicators.mjs.map +0 -1
  119. package/dist/signing-clauses.mjs +0 -78
  120. package/dist/signing-clauses.mjs.map +0 -1
  121. package/dist/stopwords.mjs +0 -9915
  122. package/dist/stopwords.mjs.map +0 -1
  123. package/dist/structural-single-cap-prefixes.mjs +0 -99
  124. package/dist/structural-single-cap-prefixes.mjs.map +0 -1
  125. package/dist/triggers.cs.mjs +0 -569
  126. package/dist/triggers.cs.mjs.map +0 -1
  127. package/dist/triggers.de.mjs +0 -139
  128. package/dist/triggers.de.mjs.map +0 -1
  129. package/dist/triggers.en.mjs +0 -119
  130. package/dist/triggers.en.mjs.map +0 -1
  131. package/dist/triggers.es.mjs +0 -96
  132. package/dist/triggers.es.mjs.map +0 -1
  133. package/dist/triggers.fr.mjs +0 -275
  134. package/dist/triggers.fr.mjs.map +0 -1
  135. package/dist/triggers.global.mjs +0 -79
  136. package/dist/triggers.global.mjs.map +0 -1
  137. package/dist/triggers.hu.mjs +0 -41
  138. package/dist/triggers.hu.mjs.map +0 -1
  139. package/dist/triggers.it.mjs +0 -74
  140. package/dist/triggers.it.mjs.map +0 -1
  141. package/dist/triggers.pl.mjs +0 -271
  142. package/dist/triggers.pl.mjs.map +0 -1
  143. package/dist/triggers.pt-br.mjs +0 -193
  144. package/dist/triggers.pt-br.mjs.map +0 -1
  145. package/dist/triggers.ro.mjs +0 -59
  146. package/dist/triggers.ro.mjs.map +0 -1
  147. package/dist/triggers.sk.mjs +0 -555
  148. package/dist/triggers.sk.mjs.map +0 -1
  149. package/dist/triggers.sv.mjs +0 -58
  150. package/dist/triggers.sv.mjs.map +0 -1
  151. package/dist/year-words.mjs +0 -62
  152. package/dist/year-words.mjs.map +0 -1
@@ -0,0 +1,63 @@
1
+ import fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { parse } from "node:path";
4
+ import { WASI } from "node:wasi";
5
+ import { parentPort, Worker } from "node:worker_threads";
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ const { instantiateNapiModuleSync, MessageHandler, getDefaultContext } = require("@napi-rs/wasm-runtime");
10
+
11
+ if (parentPort) {
12
+ parentPort.on("message", (data) => {
13
+ globalThis.onmessage({ data });
14
+ });
15
+ }
16
+
17
+ Object.assign(globalThis, {
18
+ self: globalThis,
19
+ require,
20
+ Worker,
21
+ importScripts: function (f) {
22
+ ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
23
+ },
24
+ postMessage: function (msg) {
25
+ if (parentPort) {
26
+ parentPort.postMessage(msg);
27
+ }
28
+ },
29
+ });
30
+
31
+ const emnapiContext = getDefaultContext();
32
+
33
+ const __rootDir = parse(process.cwd()).root;
34
+
35
+ const handler = new MessageHandler({
36
+ onLoad({ wasmModule, wasmMemory }) {
37
+ const wasi = new WASI({
38
+ version: 'preview1',
39
+ env: process.env,
40
+ preopens: {
41
+ [__rootDir]: __rootDir,
42
+ },
43
+ });
44
+
45
+ return instantiateNapiModuleSync(wasmModule, {
46
+ childThread: true,
47
+ wasi,
48
+ context: emnapiContext,
49
+ overwriteImports(importObject) {
50
+ importObject.env = {
51
+ ...importObject.env,
52
+ ...importObject.napi,
53
+ ...importObject.emnapi,
54
+ memory: wasmMemory
55
+ };
56
+ },
57
+ });
58
+ },
59
+ });
60
+
61
+ globalThis.onmessage = function (e) {
62
+ handler.handle(e);
63
+ };
package/dist/vite.d.mts CHANGED
@@ -1,7 +1,23 @@
1
1
  import { Plugin } from "vite";
2
2
 
3
3
  //#region src/vite.d.ts
4
- declare function stllAnonymizeWasmVite(): Plugin;
4
+ /** Which bundled `.stlanonpkg` prepared packages the plugin emits into a
5
+ * production build. The wasm binary, glue, and workers are always emitted; only
6
+ * the prepared packages are selectable because they dominate the output size.
7
+ *
8
+ * - `"all"` (default): every bundled package, preserving prior behavior.
9
+ * - `"none"`: no prepared packages. The consumer must supply its own package to
10
+ * `loadPipeline`; `loadDefaultPipeline()` then fails at runtime with a fetch
11
+ * error because the asset was never emitted.
12
+ * - a name list: only these packages. Use `"default"` for the full-dictionary
13
+ * package and a language code (e.g. `"cs"`, `"de"`, `"en"`) for a scoped one,
14
+ * for example `["cs"]` or `["default", "en"]`. A requested package that is
15
+ * not bundled fails the build. */
16
+ type AnonymizeWasmPackages = "all" | "none" | readonly string[];
17
+ type AnonymizeWasmPluginOptions = {
18
+ packages?: AnonymizeWasmPackages;
19
+ };
20
+ declare function stllAnonymizeWasmVite(options?: AnonymizeWasmPluginOptions): Plugin;
5
21
  //#endregion
6
- export { stllAnonymizeWasmVite as default };
22
+ export { AnonymizeWasmPackages, AnonymizeWasmPluginOptions, stllAnonymizeWasmVite as default };
7
23
  //# sourceMappingURL=vite.d.mts.map
package/dist/vite.mjs CHANGED
@@ -1,19 +1,96 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import { basename, dirname, join } from "node:path";
1
3
  //#region src/vite.ts
2
- const PACKAGES = [
3
- "@stll/text-search-wasm",
4
- "@stll/aho-corasick-wasm",
5
- "@stll/aho-corasick-wasm32-wasi",
6
- "@stll/fuzzy-search-wasm",
7
- "@stll/fuzzy-search-wasm32-wasi",
8
- "@stll/regex-set-wasm",
9
- "@stll/regex-set-wasm32-wasi"
10
- ];
11
- function stllAnonymizeWasmVite() {
4
+ const OPTIMIZE_EXCLUDE = ["@stll/anonymize-wasm", "@napi-rs/wasm-runtime"];
5
+ const NATIVE_DIR = "native";
6
+ /** The Node glue is always shipped in `native/`; any file there works as the
7
+ * anchor. `new URL(fileName, <anchor>)` resolves to `native/<fileName>` because
8
+ * URL resolution replaces the anchor's last path segment. */
9
+ const ANCHOR_FILE = "index.wasi.cjs";
10
+ /** The exact `assetUrl` base expression emitted by the build (see wasm.ts).
11
+ * Kept in sync with the compiled `wasm.mjs`; the transform fails loudly if the
12
+ * dist shape drifts so this cannot silently ship broken asset paths. */
13
+ const ASSET_URL_BASE = "`./${NATIVE_ASSET_DIR}/${fileName}`, import.meta.url";
14
+ /** Prepared packages are named `native-pipeline.stlanonpkg` (the full-dictionary
15
+ * default) and `native-pipeline.<language>.stlanonpkg` (scoped variants). */
16
+ const PACKAGE_SUFFIX = ".stlanonpkg";
17
+ const PACKAGE_PREFIX = "native-pipeline.";
18
+ const DEFAULT_PACKAGE_FILE = `${PACKAGE_PREFIX}stlanonpkg`;
19
+ /** Selection name for the full-dictionary default package. Every other name is
20
+ * a language code that maps to `native-pipeline.<name>.stlanonpkg`. */
21
+ const DEFAULT_PACKAGE_NAME = "default";
22
+ const isWasmEntry = (id) => id.includes("anonymize-wasm") && basename(id) === "wasm.mjs";
23
+ const isPackageFile = (file) => file.endsWith(PACKAGE_SUFFIX);
24
+ /** Map a selection name to its on-disk package file name. */
25
+ const packageFileName = (name) => name === DEFAULT_PACKAGE_NAME ? DEFAULT_PACKAGE_FILE : `${PACKAGE_PREFIX}${name}${PACKAGE_SUFFIX}`;
26
+ /** Resolve which prepared-package files to emit for the given selection,
27
+ * validating that every explicitly requested name exists in `nativeFiles`. */
28
+ const resolvePackageSelection = (nativeFiles, packages) => {
29
+ const packageFiles = nativeFiles.filter(isPackageFile);
30
+ if (packages === "all") return {
31
+ status: "ok",
32
+ emit: new Set(packageFiles)
33
+ };
34
+ if (packages === "none") return {
35
+ status: "ok",
36
+ emit: /* @__PURE__ */ new Set()
37
+ };
38
+ if (!Array.isArray(packages)) return {
39
+ status: "invalid",
40
+ value: String(packages)
41
+ };
42
+ const available = new Set(packageFiles);
43
+ const emit = /* @__PURE__ */ new Set();
44
+ const missing = [];
45
+ for (const name of packages) {
46
+ const fileName = packageFileName(name);
47
+ if (available.has(fileName)) emit.add(fileName);
48
+ else missing.push(name);
49
+ }
50
+ if (missing.length > 0) return {
51
+ status: "missing",
52
+ names: missing,
53
+ available: packageFiles
54
+ };
55
+ return {
56
+ status: "ok",
57
+ emit
58
+ };
59
+ };
60
+ function stllAnonymizeWasmVite(options = {}) {
61
+ const packages = options.packages ?? "all";
62
+ let isBuild = false;
12
63
  return {
13
64
  name: "stll-anonymize-wasm",
14
- apply: "serve",
15
65
  config() {
16
- return { optimizeDeps: { exclude: PACKAGES } };
66
+ return { optimizeDeps: { exclude: OPTIMIZE_EXCLUDE } };
67
+ },
68
+ configResolved(resolved) {
69
+ isBuild = resolved.command === "build";
70
+ },
71
+ async transform(code, id) {
72
+ if (!(isBuild && isWasmEntry(id))) return null;
73
+ if (!code.includes(ASSET_URL_BASE)) this.error(`stll-anonymize-wasm: could not find the assetUrl base in ${id}. The @stll/anonymize-wasm dist shape changed; update ASSET_URL_BASE in the Vite plugin.`);
74
+ const nativeDir = join(dirname(id), NATIVE_DIR);
75
+ const files = await readdir(nativeDir);
76
+ const selection = resolvePackageSelection(files, packages);
77
+ if (selection.status === "invalid") this.error(`stll-anonymize-wasm: invalid packages option ${JSON.stringify(selection.value)}; expected "all", "none", or an array like ["default", "cs"].`);
78
+ if (selection.status === "missing") this.error(`stll-anonymize-wasm: requested package(s) not bundled: ${selection.names.join(", ")}. Available: ${selection.available.join(", ") || "(none)"}.`);
79
+ let anchorRef;
80
+ for (const file of files) {
81
+ if (isPackageFile(file) && !selection.emit.has(file)) continue;
82
+ const referenceId = this.emitFile({
83
+ type: "asset",
84
+ fileName: `${NATIVE_DIR}/${file}`,
85
+ source: await readFile(join(nativeDir, file))
86
+ });
87
+ if (file === ANCHOR_FILE) anchorRef = referenceId;
88
+ }
89
+ if (anchorRef === void 0) this.error(`stll-anonymize-wasm: ${ANCHOR_FILE} is missing from ${nativeDir}; cannot anchor the native asset base.`);
90
+ return {
91
+ code: code.replace(ASSET_URL_BASE, `fileName, import.meta.ROLLUP_FILE_URL_${anchorRef}`),
92
+ map: null
93
+ };
17
94
  }
18
95
  };
19
96
  }
package/dist/vite.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.mjs","names":[],"sources":["../../src/vite.ts"],"sourcesContent":["/* Vite plugin that wires up @stll/anonymize-wasm so its transitive\n * napi-rs-generated wasm loaders survive Vite's dep pre-bundler. Adds\n * this package plus its @stll/*-wasm dependencies to optimizeDeps.exclude\n * so the loader modules are served with their original paths, keeping\n * `new URL(\"./foo.wasm\", import.meta.url)` correct. */\nimport type { Plugin } from \"vite\";\n\n// Only the napi-rs WASM packages need excluding — they use\n// `new URL(\"./foo.wasm\", import.meta.url)` which Vite's optimizer\n// would rewrite. @stll/anonymize-wasm itself is pure JS and should\n// NOT be excluded.\nconst PACKAGES = [\n \"@stll/text-search-wasm\",\n \"@stll/aho-corasick-wasm\",\n \"@stll/aho-corasick-wasm32-wasi\",\n \"@stll/fuzzy-search-wasm\",\n \"@stll/fuzzy-search-wasm32-wasi\",\n \"@stll/regex-set-wasm\",\n \"@stll/regex-set-wasm32-wasi\",\n];\n\nexport default function stllAnonymizeWasmVite(): Plugin {\n return {\n name: \"stll-anonymize-wasm\",\n apply: \"serve\",\n config() {\n return {\n optimizeDeps: { exclude: PACKAGES },\n };\n },\n };\n}\n"],"mappings":";AAWA,MAAM,WAAW;CACf;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAwB,wBAAgC;CACtD,OAAO;EACL,MAAM;EACN,OAAO;EACP,SAAS;GACP,OAAO,EACL,cAAc,EAAE,SAAS,SAAS,EACpC;EACF;CACF;AACF"}
1
+ {"version":3,"file":"vite.mjs","names":[],"sources":["../../src/vite.ts"],"sourcesContent":["/* Vite plugin that wires up @stll/anonymize-wasm so its wasm binding and\n * prepared-package assets survive both Vite's dev pre-bundler and a production\n * `vite build`.\n *\n * The package loads its napi-rs binding and bundled `.stlanonpkg` packages at\n * runtime from its own `native/` asset directory via\n * `new URL(\"./native/…\", import.meta.url)` (the wasm module, the WASI worker,\n * the glue, and the packages). The paths are computed at runtime, so neither\n * Vite's optimizer nor Rollup's static `new URL(…, import.meta.url)` handling\n * can follow them on their own.\n *\n * Dev (`vite serve`): the package plus the `@napi-rs/wasm-runtime` loader are\n * added to `optimizeDeps.exclude`, keeping their original on-disk paths so the\n * relative URLs resolve next to the package's own files.\n *\n * Build (`vite build`): Rollup bundles `wasm.mjs` into a chunk, rewriting\n * `import.meta.url`, and never copies the `native/` files. This plugin emits\n * the wasm binary + glue as build assets under a stable `native/` subdir, emits\n * the selected `.stlanonpkg` prepared packages (see {@link\n * AnonymizeWasmPluginOptions.packages}), and re-anchors the package's\n * `assetUrl` base onto a Rollup file-URL reference, so the runtime URLs resolve\n * to the emitted assets from whatever chunk ends up referencing them. The\n * glue's own internal `new URL(…, import.meta.url)` references (its `.wasm` and\n * worker) keep working because the glue directory is emitted side by side.\n *\n * The bundled prepared packages dominate the emitted size (the default\n * full-dictionary package alone is ~20 MB, plus per-language variants). An app\n * that only ever calls `loadPipeline` with its own package, or\n * `loadDefaultPipeline(language)` for a known subset of languages, can drop the\n * rest with the `packages` option instead of shipping every bundled package.\n */\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { Plugin } from \"vite\";\n\nconst OPTIMIZE_EXCLUDE = [\"@stll/anonymize-wasm\", \"@napi-rs/wasm-runtime\"];\nconst NATIVE_DIR = \"native\";\n/** The Node glue is always shipped in `native/`; any file there works as the\n * anchor. `new URL(fileName, <anchor>)` resolves to `native/<fileName>` because\n * URL resolution replaces the anchor's last path segment. */\nconst ANCHOR_FILE = \"index.wasi.cjs\";\n/** The exact `assetUrl` base expression emitted by the build (see wasm.ts).\n * Kept in sync with the compiled `wasm.mjs`; the transform fails loudly if the\n * dist shape drifts so this cannot silently ship broken asset paths. */\nconst ASSET_URL_BASE = \"`./${NATIVE_ASSET_DIR}/${fileName}`, import.meta.url\";\n\n/** Prepared packages are named `native-pipeline.stlanonpkg` (the full-dictionary\n * default) and `native-pipeline.<language>.stlanonpkg` (scoped variants). */\nconst PACKAGE_SUFFIX = \".stlanonpkg\";\nconst PACKAGE_PREFIX = \"native-pipeline.\";\nconst DEFAULT_PACKAGE_FILE = `${PACKAGE_PREFIX}stlanonpkg`;\n/** Selection name for the full-dictionary default package. Every other name is\n * a language code that maps to `native-pipeline.<name>.stlanonpkg`. */\nconst DEFAULT_PACKAGE_NAME = \"default\";\n\n/** Which bundled `.stlanonpkg` prepared packages the plugin emits into a\n * production build. The wasm binary, glue, and workers are always emitted; only\n * the prepared packages are selectable because they dominate the output size.\n *\n * - `\"all\"` (default): every bundled package, preserving prior behavior.\n * - `\"none\"`: no prepared packages. The consumer must supply its own package to\n * `loadPipeline`; `loadDefaultPipeline()` then fails at runtime with a fetch\n * error because the asset was never emitted.\n * - a name list: only these packages. Use `\"default\"` for the full-dictionary\n * package and a language code (e.g. `\"cs\"`, `\"de\"`, `\"en\"`) for a scoped one,\n * for example `[\"cs\"]` or `[\"default\", \"en\"]`. A requested package that is\n * not bundled fails the build. */\nexport type AnonymizeWasmPackages = \"all\" | \"none\" | readonly string[];\n\nexport type AnonymizeWasmPluginOptions = {\n packages?: AnonymizeWasmPackages;\n};\n\nconst isWasmEntry = (id: string): boolean =>\n id.includes(\"anonymize-wasm\") && basename(id) === \"wasm.mjs\";\n\nconst isPackageFile = (file: string): boolean => file.endsWith(PACKAGE_SUFFIX);\n\n/** Map a selection name to its on-disk package file name. */\nconst packageFileName = (name: string): string =>\n name === DEFAULT_PACKAGE_NAME\n ? DEFAULT_PACKAGE_FILE\n : `${PACKAGE_PREFIX}${name}${PACKAGE_SUFFIX}`;\n\ntype PackageSelection =\n | { status: \"ok\"; emit: ReadonlySet<string> }\n | { status: \"missing\"; names: string[]; available: string[] }\n | { status: \"invalid\"; value: string };\n\n/** Resolve which prepared-package files to emit for the given selection,\n * validating that every explicitly requested name exists in `nativeFiles`. */\nconst resolvePackageSelection = (\n nativeFiles: readonly string[],\n packages: AnonymizeWasmPackages,\n): PackageSelection => {\n const packageFiles = nativeFiles.filter(isPackageFile);\n if (packages === \"all\") {\n return { status: \"ok\", emit: new Set(packageFiles) };\n }\n if (packages === \"none\") {\n return { status: \"ok\", emit: new Set() };\n }\n if (!Array.isArray(packages)) {\n // A bare string like \"cs\" would otherwise iterate per character below.\n return { status: \"invalid\", value: String(packages) };\n }\n const available = new Set(packageFiles);\n const emit = new Set<string>();\n const missing: string[] = [];\n for (const name of packages) {\n const fileName = packageFileName(name);\n if (available.has(fileName)) {\n emit.add(fileName);\n } else {\n missing.push(name);\n }\n }\n if (missing.length > 0) {\n return { status: \"missing\", names: missing, available: packageFiles };\n }\n return { status: \"ok\", emit };\n};\n\nexport default function stllAnonymizeWasmVite(\n options: AnonymizeWasmPluginOptions = {},\n): Plugin {\n const packages = options.packages ?? \"all\";\n let isBuild = false;\n return {\n name: \"stll-anonymize-wasm\",\n // optimizeDeps only affects dev; harmless (ignored) during build.\n config() {\n return { optimizeDeps: { exclude: OPTIMIZE_EXCLUDE } };\n },\n configResolved(resolved) {\n isBuild = resolved.command === \"build\";\n },\n async transform(code, id) {\n if (!(isBuild && isWasmEntry(id))) {\n return null;\n }\n if (!code.includes(ASSET_URL_BASE)) {\n this.error(\n `stll-anonymize-wasm: could not find the assetUrl base in ${id}. ` +\n \"The @stll/anonymize-wasm dist shape changed; update ASSET_URL_BASE \" +\n \"in the Vite plugin.\",\n );\n }\n const nativeDir = join(dirname(id), NATIVE_DIR);\n const files = await readdir(nativeDir);\n const selection = resolvePackageSelection(files, packages);\n if (selection.status === \"invalid\") {\n this.error(\n `stll-anonymize-wasm: invalid packages option ${JSON.stringify(selection.value)}; ` +\n `expected \"all\", \"none\", or an array like [\"default\", \"cs\"].`,\n );\n }\n if (selection.status === \"missing\") {\n this.error(\n `stll-anonymize-wasm: requested package(s) not bundled: ` +\n `${selection.names.join(\", \")}. Available: ${\n selection.available.join(\", \") || \"(none)\"\n }.`,\n );\n }\n let anchorRef: string | undefined;\n for (const file of files) {\n if (isPackageFile(file) && !selection.emit.has(file)) {\n continue;\n }\n const referenceId = this.emitFile({\n type: \"asset\",\n fileName: `${NATIVE_DIR}/${file}`,\n source: await readFile(join(nativeDir, file)),\n });\n if (file === ANCHOR_FILE) {\n anchorRef = referenceId;\n }\n }\n if (anchorRef === undefined) {\n this.error(\n `stll-anonymize-wasm: ${ANCHOR_FILE} is missing from ${nativeDir}; ` +\n \"cannot anchor the native asset base.\",\n );\n }\n return {\n code: code.replace(\n ASSET_URL_BASE,\n `fileName, import.meta.ROLLUP_FILE_URL_${anchorRef}`,\n ),\n map: null,\n };\n },\n };\n}\n"],"mappings":";;;AAmCA,MAAM,mBAAmB,CAAC,wBAAwB,uBAAuB;AACzE,MAAM,aAAa;;;;AAInB,MAAM,cAAc;;;;AAIpB,MAAM,iBAAiB;;;AAIvB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,uBAAuB,GAAG,eAAe;;;AAG/C,MAAM,uBAAuB;AAoB7B,MAAM,eAAe,OACnB,GAAG,SAAS,gBAAgB,KAAK,SAAS,EAAE,MAAM;AAEpD,MAAM,iBAAiB,SAA0B,KAAK,SAAS,cAAc;;AAG7E,MAAM,mBAAmB,SACvB,SAAS,uBACL,uBACA,GAAG,iBAAiB,OAAO;;;AASjC,MAAM,2BACJ,aACA,aACqB;CACrB,MAAM,eAAe,YAAY,OAAO,aAAa;CACrD,IAAI,aAAa,OACf,OAAO;EAAE,QAAQ;EAAM,MAAM,IAAI,IAAI,YAAY;CAAE;CAErD,IAAI,aAAa,QACf,OAAO;EAAE,QAAQ;EAAM,sBAAM,IAAI,IAAI;CAAE;CAEzC,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAEzB,OAAO;EAAE,QAAQ;EAAW,OAAO,OAAO,QAAQ;CAAE;CAEtD,MAAM,YAAY,IAAI,IAAI,YAAY;CACtC,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,UAAU;EAC3B,MAAM,WAAW,gBAAgB,IAAI;EACrC,IAAI,UAAU,IAAI,QAAQ,GACxB,KAAK,IAAI,QAAQ;OAEjB,QAAQ,KAAK,IAAI;CAErB;CACA,IAAI,QAAQ,SAAS,GACnB,OAAO;EAAE,QAAQ;EAAW,OAAO;EAAS,WAAW;CAAa;CAEtE,OAAO;EAAE,QAAQ;EAAM;CAAK;AAC9B;AAEA,SAAwB,sBACtB,UAAsC,CAAC,GAC/B;CACR,MAAM,WAAW,QAAQ,YAAY;CACrC,IAAI,UAAU;CACd,OAAO;EACL,MAAM;EAEN,SAAS;GACP,OAAO,EAAE,cAAc,EAAE,SAAS,iBAAiB,EAAE;EACvD;EACA,eAAe,UAAU;GACvB,UAAU,SAAS,YAAY;EACjC;EACA,MAAM,UAAU,MAAM,IAAI;GACxB,IAAI,EAAE,WAAW,YAAY,EAAE,IAC7B,OAAO;GAET,IAAI,CAAC,KAAK,SAAS,cAAc,GAC/B,KAAK,MACH,4DAA4D,GAAG,yFAGjE;GAEF,MAAM,YAAY,KAAK,QAAQ,EAAE,GAAG,UAAU;GAC9C,MAAM,QAAQ,MAAM,QAAQ,SAAS;GACrC,MAAM,YAAY,wBAAwB,OAAO,QAAQ;GACzD,IAAI,UAAU,WAAW,WACvB,KAAK,MACH,gDAAgD,KAAK,UAAU,UAAU,KAAK,EAAE,8DAElF;GAEF,IAAI,UAAU,WAAW,WACvB,KAAK,MACH,0DACK,UAAU,MAAM,KAAK,IAAI,EAAE,eAC5B,UAAU,UAAU,KAAK,IAAI,KAAK,SACnC,EACL;GAEF,IAAI;GACJ,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,cAAc,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,GACjD;IAEF,MAAM,cAAc,KAAK,SAAS;KAChC,MAAM;KACN,UAAU,GAAG,WAAW,GAAG;KAC3B,QAAQ,MAAM,SAAS,KAAK,WAAW,IAAI,CAAC;IAC9C,CAAC;IACD,IAAI,SAAS,aACX,YAAY;GAEhB;GACA,IAAI,cAAc,KAAA,GAChB,KAAK,MACH,wBAAwB,YAAY,mBAAmB,UAAU,uCAEnE;GAEF,OAAO;IACL,MAAM,KAAK,QACT,gBACA,yCAAyC,WAC3C;IACA,KAAK;GACP;EACF;CACF;AACF"}