@stll/anonymize-wasm 2.0.0-alpha.1 → 2.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.
Files changed (161) hide show
  1. package/README.md +93 -4
  2. package/dist/native/index.wasi-browser.js +12002 -0
  3. package/dist/native/index.wasi.cjs +122 -0
  4. package/dist/native/index.wasm32-wasi.wasm +0 -0
  5. package/dist/native/native-pipeline.cs.stlanonpkg +0 -0
  6. package/dist/native/native-pipeline.de.stlanonpkg +0 -0
  7. package/dist/native/native-pipeline.en.stlanonpkg +0 -0
  8. package/dist/native/native-pipeline.stlanonpkg +0 -0
  9. package/dist/native/wasi-worker-browser.mjs +10766 -0
  10. package/dist/native/wasi-worker.mjs +63 -0
  11. package/dist/vite.d.mts +18 -2
  12. package/dist/vite.mjs +89 -12
  13. package/dist/vite.mjs.map +1 -1
  14. package/dist/wasm.d.mts +417 -1348
  15. package/dist/wasm.mjs +461 -18598
  16. package/dist/wasm.mjs.map +1 -1
  17. package/package.json +15 -9
  18. package/dist/address-boundaries.mjs +0 -197
  19. package/dist/address-boundaries.mjs.map +0 -1
  20. package/dist/address-jurisdiction-prefixes.mjs +0 -16
  21. package/dist/address-jurisdiction-prefixes.mjs.map +0 -1
  22. package/dist/address-stop-keywords.mjs +0 -148
  23. package/dist/address-stop-keywords.mjs.map +0 -1
  24. package/dist/address-stopwords.mjs +0 -84
  25. package/dist/address-stopwords.mjs.map +0 -1
  26. package/dist/address-unit-abbreviations.mjs +0 -15
  27. package/dist/address-unit-abbreviations.mjs.map +0 -1
  28. package/dist/allow-list.mjs +0 -196
  29. package/dist/allow-list.mjs.map +0 -1
  30. package/dist/clause-noun-heads.mjs +0 -79
  31. package/dist/clause-noun-heads.mjs.map +0 -1
  32. package/dist/common-words-en.mjs +0 -9887
  33. package/dist/common-words-en.mjs.map +0 -1
  34. package/dist/coreference-org-determiners.mjs +0 -19
  35. package/dist/coreference-org-determiners.mjs.map +0 -1
  36. package/dist/coreference.cs.mjs +0 -14
  37. package/dist/coreference.cs.mjs.map +0 -1
  38. package/dist/coreference.de.mjs +0 -14
  39. package/dist/coreference.de.mjs.map +0 -1
  40. package/dist/coreference.en.mjs +0 -14
  41. package/dist/coreference.en.mjs.map +0 -1
  42. package/dist/coreference.es.mjs +0 -22
  43. package/dist/coreference.es.mjs.map +0 -1
  44. package/dist/coreference.fr.mjs +0 -32
  45. package/dist/coreference.fr.mjs.map +0 -1
  46. package/dist/coreference.it.mjs +0 -27
  47. package/dist/coreference.it.mjs.map +0 -1
  48. package/dist/coreference.pl.mjs +0 -27
  49. package/dist/coreference.pl.mjs.map +0 -1
  50. package/dist/coreference.pt-br.mjs +0 -14
  51. package/dist/coreference.pt-br.mjs.map +0 -1
  52. package/dist/coreference.sk.mjs +0 -27
  53. package/dist/coreference.sk.mjs.map +0 -1
  54. package/dist/currencies.mjs +0 -231
  55. package/dist/currencies.mjs.map +0 -1
  56. package/dist/date-months.mjs +0 -618
  57. package/dist/date-months.mjs.map +0 -1
  58. package/dist/defined-term-heads.mjs +0 -15
  59. package/dist/defined-term-heads.mjs.map +0 -1
  60. package/dist/document-structure-headings.mjs +0 -90
  61. package/dist/document-structure-headings.mjs.map +0 -1
  62. package/dist/false-positive-shapes.mjs +0 -36
  63. package/dist/false-positive-shapes.mjs.map +0 -1
  64. package/dist/generic-roles.mjs +0 -244
  65. package/dist/generic-roles.mjs.map +0 -1
  66. package/dist/hotword-rules.mjs +0 -149
  67. package/dist/hotword-rules.mjs.map +0 -1
  68. package/dist/legal-form-leading-clauses.mjs +0 -23
  69. package/dist/legal-form-leading-clauses.mjs.map +0 -1
  70. package/dist/legal-forms.mjs +0 -2115
  71. package/dist/legal-forms.mjs.map +0 -1
  72. package/dist/legal-role-heads.cs.mjs +0 -48
  73. package/dist/legal-role-heads.cs.mjs.map +0 -1
  74. package/dist/legal-role-heads.de.mjs +0 -33
  75. package/dist/legal-role-heads.de.mjs.map +0 -1
  76. package/dist/legal-role-heads.en.mjs +0 -37
  77. package/dist/legal-role-heads.en.mjs.map +0 -1
  78. package/dist/legal-role-heads.es.mjs +0 -54
  79. package/dist/legal-role-heads.es.mjs.map +0 -1
  80. package/dist/legal-role-heads.fr.mjs +0 -72
  81. package/dist/legal-role-heads.fr.mjs.map +0 -1
  82. package/dist/legal-role-heads.it.mjs +0 -68
  83. package/dist/legal-role-heads.it.mjs.map +0 -1
  84. package/dist/legal-role-heads.pl.mjs +0 -84
  85. package/dist/legal-role-heads.pl.mjs.map +0 -1
  86. package/dist/legal-role-heads.pt-br.mjs +0 -63
  87. package/dist/legal-role-heads.pt-br.mjs.map +0 -1
  88. package/dist/legal-role-heads.sk.mjs +0 -80
  89. package/dist/legal-role-heads.sk.mjs.map +0 -1
  90. package/dist/manifest.mjs +0 -69
  91. package/dist/manifest.mjs.map +0 -1
  92. package/dist/names-exclusions.mjs +0 -223
  93. package/dist/names-exclusions.mjs.map +0 -1
  94. package/dist/names-first.mjs +0 -418
  95. package/dist/names-first.mjs.map +0 -1
  96. package/dist/names-nw-ar.mjs +0 -202
  97. package/dist/names-nw-ar.mjs.map +0 -1
  98. package/dist/names-nw-excluded-allcaps.mjs +0 -112
  99. package/dist/names-nw-excluded-allcaps.mjs.map +0 -1
  100. package/dist/names-nw-fil.mjs +0 -202
  101. package/dist/names-nw-fil.mjs.map +0 -1
  102. package/dist/names-nw-id.mjs +0 -210
  103. package/dist/names-nw-id.mjs.map +0 -1
  104. package/dist/names-nw-in.mjs +0 -526
  105. package/dist/names-nw-in.mjs.map +0 -1
  106. package/dist/names-nw-ja-latn.mjs +0 -260
  107. package/dist/names-nw-ja-latn.mjs.map +0 -1
  108. package/dist/names-nw-ko.mjs +0 -162
  109. package/dist/names-nw-ko.mjs.map +0 -1
  110. package/dist/names-nw-th.mjs +0 -188
  111. package/dist/names-nw-th.mjs.map +0 -1
  112. package/dist/names-nw-vi.mjs +0 -151
  113. package/dist/names-nw-vi.mjs.map +0 -1
  114. package/dist/names-nw-zh-latn.mjs +0 -197
  115. package/dist/names-nw-zh-latn.mjs.map +0 -1
  116. package/dist/names-surnames.mjs +0 -113
  117. package/dist/names-surnames.mjs.map +0 -1
  118. package/dist/names-title-tokens.mjs +0 -40
  119. package/dist/names-title-tokens.mjs.map +0 -1
  120. package/dist/organization-unit-heads.mjs +0 -20
  121. package/dist/organization-unit-heads.mjs.map +0 -1
  122. package/dist/person-stopwords.mjs +0 -211
  123. package/dist/person-stopwords.mjs.map +0 -1
  124. package/dist/section-headings.mjs +0 -64
  125. package/dist/section-headings.mjs.map +0 -1
  126. package/dist/sentence-verb-indicators.mjs +0 -232
  127. package/dist/sentence-verb-indicators.mjs.map +0 -1
  128. package/dist/signing-clauses.mjs +0 -102
  129. package/dist/signing-clauses.mjs.map +0 -1
  130. package/dist/stopwords.mjs +0 -9915
  131. package/dist/stopwords.mjs.map +0 -1
  132. package/dist/structural-single-cap-prefixes.mjs +0 -99
  133. package/dist/structural-single-cap-prefixes.mjs.map +0 -1
  134. package/dist/triggers.cs.mjs +0 -569
  135. package/dist/triggers.cs.mjs.map +0 -1
  136. package/dist/triggers.de.mjs +0 -139
  137. package/dist/triggers.de.mjs.map +0 -1
  138. package/dist/triggers.en.mjs +0 -119
  139. package/dist/triggers.en.mjs.map +0 -1
  140. package/dist/triggers.es.mjs +0 -96
  141. package/dist/triggers.es.mjs.map +0 -1
  142. package/dist/triggers.fr.mjs +0 -275
  143. package/dist/triggers.fr.mjs.map +0 -1
  144. package/dist/triggers.global.mjs +0 -79
  145. package/dist/triggers.global.mjs.map +0 -1
  146. package/dist/triggers.hu.mjs +0 -41
  147. package/dist/triggers.hu.mjs.map +0 -1
  148. package/dist/triggers.it.mjs +0 -74
  149. package/dist/triggers.it.mjs.map +0 -1
  150. package/dist/triggers.pl.mjs +0 -271
  151. package/dist/triggers.pl.mjs.map +0 -1
  152. package/dist/triggers.pt-br.mjs +0 -193
  153. package/dist/triggers.pt-br.mjs.map +0 -1
  154. package/dist/triggers.ro.mjs +0 -59
  155. package/dist/triggers.ro.mjs.map +0 -1
  156. package/dist/triggers.sk.mjs +0 -555
  157. package/dist/triggers.sk.mjs.map +0 -1
  158. package/dist/triggers.sv.mjs +0 -58
  159. package/dist/triggers.sv.mjs.map +0 -1
  160. package/dist/year-words.mjs +0 -62
  161. 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"}