lingotweaker-wasm 0.0.1 → 0.1.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 (3) hide show
  1. package/README.md +80 -4
  2. package/pack.js +76 -0
  3. package/package.json +49 -3
package/README.md CHANGED
@@ -1,5 +1,81 @@
1
- # lingotweaker-wasm
1
+ # LingoTweaker (WebAssembly)
2
2
 
3
- Placeholder release. The real package ships the WebAssembly bindings of the
4
- LingoTweaker proofreading engine for browsers and Node.js. See
5
- https://github.com/fiduswriter/LingoTweaker
3
+ WebAssembly bindings for the LingoTweaker proofreading engine (wasm-bindgen),
4
+ for browsers and Node.js. The engine runs entirely from an in-memory data pack,
5
+ so no file system or native addon is required.
6
+
7
+ ```sh
8
+ npm install lingotweaker-wasm@next
9
+ ```
10
+
11
+ ## Browser
12
+
13
+ ```js
14
+ import init, { LtEngine } from "lingotweaker-wasm";
15
+ import { fetchPack } from "lingotweaker-wasm/pack";
16
+
17
+ await init();
18
+
19
+ const pack = await fetchPack("en"); // release asset for this package version
20
+ const engine = new LtEngine(
21
+ "en-US",
22
+ pack,
23
+ JSON.stringify({ today: new Date().toISOString() }),
24
+ );
25
+ const result = JSON.parse(engine.check_json("I can heard you."));
26
+ for (const match of result.matches) {
27
+ console.log(match.rule_id, match.suggestions);
28
+ }
29
+ ```
30
+
31
+ ## Node.js
32
+
33
+ The Node build is CommonJS (`lingotweaker-wasm/node`); the data helper is ESM,
34
+ so import it dynamically from CJS:
35
+
36
+ ```js
37
+ const { LtEngine } = require("lingotweaker-wasm/node");
38
+
39
+ (async () => {
40
+ const { fetchPack } = await import("lingotweaker-wasm/pack");
41
+ const pack = await fetchPack("en");
42
+ const engine = new LtEngine(
43
+ "en-US",
44
+ pack,
45
+ JSON.stringify({ today: new Date().toISOString() }),
46
+ );
47
+ console.log(engine.check_json("I can heard you."));
48
+ })();
49
+ ```
50
+
51
+ Or, from an ES module: `import { LtEngine } from "lingotweaker-wasm/node"`.
52
+
53
+ `today` is required in practice: WebAssembly has no clock, so the date is
54
+ passed in and pinned for the engine's date filters.
55
+
56
+ ## Data
57
+
58
+ The package ships **code only** and depends on `lingotweaker-data`, which
59
+ carries one gzipped pack per language. In Node.js the data helper resolves that
60
+ package locally; in the browser (or without it) it falls back to the per-release
61
+ GitHub Release assets:
62
+
63
+ ```js
64
+ import { fetchPack, packUrl, manifestUrl } from "lingotweaker-wasm/pack";
65
+
66
+ await fetchPack("en"); // local lingotweaker-data in Node, else release assets
67
+ await fetchPack("gn", { baseUrl: "https://fiduswriter.github.io/LingoTweaker" });
68
+ packUrl("de"); // build a URL yourself
69
+ ```
70
+
71
+ `baseUrl` points at a directory that contains `packs/<lang>.pack.gz` and
72
+ `manifest.json`. All languages are attached to every release; `manifest.json`
73
+ lists file sizes and sha256 hashes. `lingotweaker-data` is also served from any
74
+ npm CDN (`https://cdn.jsdelivr.net/npm/lingotweaker-data/packs/<lang>.pack.gz`),
75
+ and you can host the packs yourself.
76
+
77
+ LingoTweaker is an independent project and includes a port of the legacy
78
+ LanguageTool proofreading engine and its rule data. Upstream references and
79
+ licenses are kept; see `THIRD_PARTY_NOTICES.md` in the repository.
80
+
81
+ License: LGPL-2.1-or-later.
package/pack.js ADDED
@@ -0,0 +1,76 @@
1
+ // Data helpers for the `lingotweaker-wasm` package.
2
+ //
3
+ // The engine itself is loaded from an in-memory data pack
4
+ // (`LtEngine(lang, pack, optionsJson)`); this module fetches those packs from
5
+ // the per-release GitHub Release assets and inflates the gzip wrapper.
6
+ //
7
+ // import { fetchPack } from "lingotweaker-wasm/pack";
8
+ // const pack = await fetchPack("en");
9
+ // const engine = new LtEngine("en-US", pack, JSON.stringify({ today: new Date().toISOString() }));
10
+
11
+ // Updated by scripts/release/set-version.sh together with the package version.
12
+ export const DEFAULT_DATA_BASE_URL =
13
+ "https://github.com/fiduswriter/LingoTweaker/releases/download/v0.1.1";
14
+
15
+ /** The URL of the release data manifest (`{ <lang>: { file, bytes, sha256 } }`). */
16
+ export function manifestUrl(baseUrl = DEFAULT_DATA_BASE_URL) {
17
+ return `${baseUrl}/manifest.json`;
18
+ }
19
+
20
+ /** The URL of the gzipped pack for `lang`. */
21
+ export function packUrl(lang, baseUrl = DEFAULT_DATA_BASE_URL) {
22
+ return `${baseUrl}/packs/${lang}.pack.gz`;
23
+ }
24
+
25
+ /** Inflate a gzipped pack (browser `DecompressionStream`, else Node `zlib`). */
26
+ export async function decompressPack(bytes) {
27
+ const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
28
+ if (typeof DecompressionStream === "function" && typeof Blob === "function") {
29
+ const stream = new Blob([u8]).stream().pipeThrough(new DecompressionStream("gzip"));
30
+ return new Uint8Array(await new Response(stream).arrayBuffer());
31
+ }
32
+ const { gunzipSync } = await import("node:zlib");
33
+ return new Uint8Array(gunzipSync(u8));
34
+ }
35
+
36
+ /**
37
+ * Fetch and inflate the pack for `lang` (`en`, `de`, `gn`, …).
38
+ *
39
+ * Node.js prefers the locally installed `lingotweaker-data` package; browsers
40
+ * (and any environment without it) fall back to the release assets for this
41
+ * package version. Pass `baseUrl` to use different data — the Pages demo
42
+ * (`https://fiduswriter.github.io/LingoTweaker`) or a local directory.
43
+ */
44
+ export async function fetchPack(lang, options = {}) {
45
+ const { fetch: fetchImpl = fetch } = options;
46
+ let { baseUrl } = options;
47
+ if (!baseUrl) {
48
+ const local = await localPack(lang);
49
+ if (local) return local;
50
+ baseUrl = DEFAULT_DATA_BASE_URL;
51
+ }
52
+ const url = packUrl(lang, baseUrl);
53
+ const response = await fetchImpl(url);
54
+ if (!response.ok) {
55
+ throw new Error(`cannot load ${url}: HTTP ${response.status}`);
56
+ }
57
+ return decompressPack(await response.arrayBuffer());
58
+ }
59
+
60
+ /**
61
+ * Read and inflate a pack from the installed `lingotweaker-data` package.
62
+ * Returns `null` outside Node.js, or when the package/language is missing.
63
+ */
64
+ export async function localPack(lang) {
65
+ if (typeof process === "undefined" || !process.versions?.node) return null;
66
+ try {
67
+ const { createRequire } = await import("node:module");
68
+ const require = createRequire(import.meta.url);
69
+ const data = require("lingotweaker-data");
70
+ const { readFile } = await import("node:fs/promises");
71
+ const bytes = await readFile(data.packPath(lang));
72
+ return decompressPack(bytes);
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
package/package.json CHANGED
@@ -1,11 +1,57 @@
1
1
  {
2
2
  "name": "lingotweaker-wasm",
3
- "version": "0.0.1",
4
- "description": "LingoTweaker proofreading engine compiled to WebAssembly",
3
+ "version": "0.1.1",
4
+ "description": "LingoTweaker proofreading engine compiled to WebAssembly (browser and Node)",
5
5
  "license": "LGPL-2.1-or-later",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/fiduswriter/LingoTweaker.git"
9
9
  },
10
- "homepage": "https://fiduswriter.github.io/LingoTweaker/"
10
+ "homepage": "https://fiduswriter.github.io/LingoTweaker/",
11
+ "keywords": [
12
+ "proofreading",
13
+ "grammar",
14
+ "spellcheck",
15
+ "nlp",
16
+ "language",
17
+ "wasm",
18
+ "webassembly"
19
+ ],
20
+ "type": "module",
21
+ "main": "./node/lt_wasm.js",
22
+ "module": "./web/lt_wasm.js",
23
+ "types": "./web/lt_wasm.d.ts",
24
+ "dependencies": {
25
+ "lingotweaker-data": "0.1.1"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "types": "./web/lt_wasm.d.ts",
30
+ "browser": "./web/lt_wasm.js",
31
+ "import": "./web/lt_wasm.js",
32
+ "require": "./node/lt_wasm.js",
33
+ "default": "./web/lt_wasm.js"
34
+ },
35
+ "./web": {
36
+ "types": "./web/lt_wasm.d.ts",
37
+ "default": "./web/lt_wasm.js"
38
+ },
39
+ "./node": {
40
+ "types": "./node/lt_wasm.d.ts",
41
+ "default": "./node/lt_wasm.js"
42
+ },
43
+ "./pack": {
44
+ "default": "./pack.js"
45
+ },
46
+ "./package.json": "./package.json"
47
+ },
48
+ "files": [
49
+ "web",
50
+ "node",
51
+ "pack.js",
52
+ "README.md"
53
+ ],
54
+ "engines": {
55
+ "node": ">= 18"
56
+ }
11
57
  }