@divvun/cg3 0.0.0-stage → 0.4.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/README.md CHANGED
@@ -1,3 +1,153 @@
1
- # Temporary Holding Version
1
+ # @divvun/cg3
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [VISL CG-3](https://visl.sdu.dk/cg3.html) for JavaScript. It loads compiled
4
+ Constraint Grammars (`.cg3b`) and runs them on text, and a run gives the
5
+ output `vislcg3` gives for the same grammar, input and options, byte for
6
+ byte. It is the [cg3-rs](https://github.com/divvun/cg3-rs) library, written
7
+ in Rust and built as WebAssembly. It runs in browsers, Web Workers, Deno,
8
+ Node 20 and later, and Bun, as one ES module and one `.wasm` file.
9
+
10
+ ```sh
11
+ npm install @divvun/cg3
12
+ ```
13
+
14
+ ## Running a grammar
15
+
16
+ ```js
17
+ import { init, readGrammar } from "@divvun/cg3";
18
+
19
+ await init();
20
+
21
+ const response = await fetch("/cg3/disambiguator.cg3b");
22
+ const grammar = readGrammar(new Uint8Array(await response.arrayBuffer()));
23
+
24
+ const { output, warnings } = grammar.apply(input);
25
+
26
+ grammar.free();
27
+ ```
28
+
29
+ `readGrammar` takes a compiled grammar, as `cg-comp` writes it. It does not
30
+ read textual grammars: their `INCLUDE`s name files a browser does not have,
31
+ so compile them first. `apply(input, options?)` runs the grammar on one input
32
+ and returns `{ output, warnings }`: the output as a string, and every warning
33
+ and non-fatal error the run logged, in order. Each call is a run of its own,
34
+ and a run that fails throws without harming the grammar.
35
+
36
+ lang-kal's disambiguator, given "Inuit nunaat." as
37
+ [@divvun/hfst](https://www.npmjs.com/package/@divvun/hfst)'s tokeniser
38
+ analyses it, keeps one of the twelve readings of "Inuit" and one of the five
39
+ of "nunaat":
40
+
41
+ ```js
42
+ import { readTokeniser } from "@divvun/hfst"; // after its own init()
43
+
44
+ const input = readTokeniser(pmhfstBytes).format("Inuit nunaat.", "giella-cg");
45
+ grammar.apply(input).output;
46
+ // "<Inuit>"
47
+ // "inuk" Gram/str N Rel Pl <W:0.0>
48
+ // :
49
+ // "<nunaat>"
50
+ // "nuna" N Abs Sg 3PlPoss <W:0.0>
51
+ // "<.>"
52
+ // "." CLB <W:0.0>
53
+ ```
54
+
55
+ ## Options
56
+
57
+ `options` names each run option after its `vislcg3` long option, in
58
+ camelCase: `--num-windows 4` is `{ numWindows: 4 }` and `--trace` is
59
+ `{ trace: true }`. With `trace`, each removed reading stays in the output,
60
+ commented out, with the rule that removed it:
61
+
62
+ ```js
63
+ grammar.apply(input, { trace: true }).output;
64
+ // "<Inuit>"
65
+ // "inuk" Gram/str N Rel Pl <W:0.0>
66
+ // ; "Inuit" Sem/Hum Prop Abs Pl <W:0.0> REMOVE:3212:tidlig0665
67
+ // ; "Inuit" Sem/Hum Prop Rel Pl <W:0.0> REMOVE:3212:tidlig0665
68
+ // ...
69
+ ```
70
+
71
+ The `input` and `output` formats are `"cg"` (the default), `"niceline"`,
72
+ `"apertium"`, `"fst"`, `"plain"` and `"jsonl"`. An option the package does not
73
+ know throws `Cg3Error` with code `invalid-argument`, and the message lists the
74
+ ones it does. The options a grammar sets with `CMDARGS` apply as they do in
75
+ `vislcg3`. An `EXTERNAL` rule fails its run, since there is no process to
76
+ start.
77
+
78
+ ## Grammar information
79
+
80
+ `grammar.info()` gives what `vislcg3 -v` reports about a grammar:
81
+
82
+ ```js
83
+ grammar.info();
84
+ // { sections: 6, templates: 0, rules: 5070, sets: 11233, tags: 11285,
85
+ // rulesAny: 1672, hasDependencyRules: false, hasRelationRules: false }
86
+ ```
87
+
88
+ ## Starting the module
89
+
90
+ `init()` loads the `.wasm` file that ships beside the package, in every
91
+ runtime, Node included. Call it once and wait for it before anything else;
92
+ calling it again returns the same promise. It also takes a URL, a `Response`,
93
+ the module's bytes or a compiled `WebAssembly.Module`, for bundlers and for
94
+ workers that are handed one. `version()` gives the version of the cg3 library
95
+ the package was built from.
96
+
97
+ ## Memory
98
+
99
+ A grammar holds WebAssembly memory. Call `free()` when done with it, or
100
+ declare it with `using`:
101
+
102
+ ```js
103
+ {
104
+ using grammar = readGrammar(bytes);
105
+ grammar.apply(input);
106
+ } // freed here
107
+ ```
108
+
109
+ A grammar dropped without `free()` is released after it is garbage collected.
110
+ A call on a freed grammar throws `Cg3Error` with code `freed`.
111
+
112
+ ## Errors
113
+
114
+ Every error is a `Cg3Error` with a `code` that code can test:
115
+ `not-initialised`, `init-failed`, `poisoned`, `freed`, `invalid-argument`,
116
+ `invalid-grammar` (bytes that are not a `.cg3b`) and `run-failed`. A panic
117
+ inside the module traps it. The instance is poisoned from then on and every
118
+ call throws `poisoned`, because its memory can no longer be trusted. Load the
119
+ page or process again to recover.
120
+
121
+ ## Logging
122
+
123
+ The library's log events, from loading a grammar and from running one, go to
124
+ the console, warnings and errors only by default. `setLogger((event) => ...)`
125
+ takes them instead, each with its `level`, `target` and `message`.
126
+ `setLogLevel("debug")` changes how much is sent, and `setLogLevel("off")`
127
+ sends nothing. Whatever the logger, `apply` still returns its run's warnings.
128
+
129
+ ## How it is checked
130
+
131
+ The suite runs every grammar of cg3-rs's golden corpus through the package,
132
+ under Node, Bun, Deno and a headless Chromium, on a page and in a Web Worker,
133
+ and compares the output with `vislcg3`'s byte for byte. 65 of the 68 tests
134
+ match. Three are exempt, because they run an `EXTERNAL` rule or pass an option
135
+ the package does not offer (`--nrules`, `--vislcg-compat`); none differ.
136
+
137
+ ## Developing
138
+
139
+ The package is built from `crates/cg3-wasm` in the
140
+ [cg3-rs](https://github.com/divvun/cg3-rs) repository:
141
+
142
+ ```sh
143
+ node js/build.mjs # js/cg3/dist, ready for npm publish from js/cg3
144
+ node js/build.mjs --test # and the test build, the tools and the fixtures
145
+ node js/test/run.mjs --require-all
146
+ ```
147
+
148
+ The build needs the `wasm32-unknown-unknown` target, the `wasm-bindgen` CLI
149
+ at the version `crates/cg3-wasm` pins, `wasm-opt` and `npx`.
150
+
151
+ ## Licence
152
+
153
+ GPL-3.0-or-later. The package carries the licence's text in `dist/COPYING`.