nagami-rs 2026.7.2 → 2026.9.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.
- package/README.md +25 -16
- package/nagami.d.ts +20 -6
- package/nagami.js +12 -35
- package/nagami_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ Nagami lowers WGSL into [Naga IR](https://github.com/gfx-rs/wgpu/tree/trunk/naga
|
|
|
36
36
|
- Float precision trimming - cap decimal places or significant figures, per type (lossy, opt-in)
|
|
37
37
|
- Preamble support - external declarations excluded from output
|
|
38
38
|
- Library modules - shader fragments without entry points preserved
|
|
39
|
+
- Name map - original -> final identifier mapping for hosts that address shaders by source names
|
|
39
40
|
|
|
40
41
|
Runs passes in fixed-point sweeps until the output stops shrinking. Typically converges in 3 sweeps.
|
|
41
42
|
|
|
@@ -44,7 +45,7 @@ Runs passes in fixed-point sweeps until the output stops shrinking. Typically co
|
|
|
44
45
|
Install with cargo:
|
|
45
46
|
|
|
46
47
|
```sh
|
|
47
|
-
cargo install nagami
|
|
48
|
+
cargo install nagami
|
|
48
49
|
```
|
|
49
50
|
|
|
50
51
|
Example usage:
|
|
@@ -52,10 +53,13 @@ Example usage:
|
|
|
52
53
|
```sh
|
|
53
54
|
nagami shader.wgsl -o shader.min.wgsl # minify (max profile by default)
|
|
54
55
|
nagami shader.wgsl --in-place --stats # in-place, print savings
|
|
55
|
-
nagami shader.wgsl -o out.wgsl -p baseline #
|
|
56
|
+
nagami shader.wgsl -o out.wgsl -p baseline # DCE + folding only
|
|
56
57
|
cat shader.wgsl | nagami - > out.wgsl # stdin -> stdout
|
|
57
58
|
nagami shader.wgsl --check # exit 1 if not minified
|
|
58
59
|
nagami shader.wgsl --preamble env.wgsl -o out.wgsl # external declarations
|
|
60
|
+
nagami shader.wgsl -o out.wgsl --name-map map.json # original -> final identifier map
|
|
61
|
+
nagami shader.wgsl --format json # one JSON document on stdout
|
|
62
|
+
nagami shader.wgsl -o out.wgsl --strict-fallback # fail instead of shipping a text-only bailout
|
|
59
63
|
nagami shader.wgsl --decimal-places 6 -o out.wgsl # lossy: cap fractional digits
|
|
60
64
|
nagami shader.wgsl --sig-figs 4 -o out.wgsl # lossy: cap significant figures
|
|
61
65
|
```
|
|
@@ -70,16 +74,16 @@ Three optimization profiles control which IR passes run. Generator-level optimiz
|
|
|
70
74
|
| Constant folding | ✓ | ✓ | ✓ |
|
|
71
75
|
| Dead parameter elimination | ✓ | ✓ | ✓ |
|
|
72
76
|
| Emit merge | ✓ | ✓ | ✓ |
|
|
73
|
-
|
|
|
77
|
+
| Identifier renaming (globals, functions, params, locals) | ✓ | ✓ | ✓ |
|
|
74
78
|
| Function inlining | - | ✓ (24 nodes / 3 call sites) | ✓ (48 nodes / 6 call sites) |
|
|
75
79
|
| Load dedup + dead stores | - | ✓ | ✓ |
|
|
76
80
|
| Variable coalescing | - | ✓ | ✓ |
|
|
77
81
|
| Struct-build coalescing | - | ✓ | ✓ |
|
|
78
|
-
| Vector-constant hoisting | - |
|
|
82
|
+
| Vector-constant hoisting | - | - | ✓ |
|
|
79
83
|
| Common subexpression elim | - | - | ✓ |
|
|
80
|
-
|
|
|
84
|
+
| Mangling (struct types/members, constants, overrides) | - | - | ✓ |
|
|
81
85
|
|
|
82
|
-
|
|
86
|
+
The `baseline` is fast and safe; `aggressive` adds the full IR pipeline without mangling; `max` raises inlining limits and enables CSE and vector-constant hoisting (both only while mangling is on) for maximum compression. `--no-mangle` disables mangling in any profile.
|
|
83
87
|
|
|
84
88
|
## Preamble
|
|
85
89
|
|
|
@@ -102,14 +106,14 @@ Preamble names are automatically preserved from renaming so that member access e
|
|
|
102
106
|
Install with cargo:
|
|
103
107
|
|
|
104
108
|
```sh
|
|
105
|
-
cargo add nagami
|
|
109
|
+
cargo add nagami --no-default-features
|
|
106
110
|
```
|
|
107
111
|
|
|
108
112
|
Run with default config:
|
|
109
113
|
|
|
110
114
|
```rust
|
|
111
115
|
let output = nagami::run(src, &nagami::config::Config::default())?;
|
|
112
|
-
println!("{}", output.source);
|
|
116
|
+
println!("{}", output.source);
|
|
113
117
|
```
|
|
114
118
|
|
|
115
119
|
With a preamble (external declarations excluded from output):
|
|
@@ -134,10 +138,15 @@ Browser / bundler:
|
|
|
134
138
|
|
|
135
139
|
```js
|
|
136
140
|
import init, { run } from 'nagami-rs';
|
|
137
|
-
await init();
|
|
138
|
-
const { source, report } = run(shader);
|
|
139
|
-
console.log(source);
|
|
140
|
-
console.log(report);
|
|
141
|
+
await init(); // load the WASM module once
|
|
142
|
+
const { source, report, nameMap } = run(shader);
|
|
143
|
+
console.log(source); // minified WGSL
|
|
144
|
+
console.log(report); // optimization report; report.bailout holds naga's
|
|
145
|
+
// error when the output is text-compacted only
|
|
146
|
+
console.log(nameMap); // original -> final names for bindings, functions,
|
|
147
|
+
// overrides, entry points, struct members; null when
|
|
148
|
+
// the shipped text is not the generator's output
|
|
149
|
+
// (bailout, emitter fallback, input already smaller)
|
|
141
150
|
```
|
|
142
151
|
|
|
143
152
|
With config (all fields optional):
|
|
@@ -145,7 +154,7 @@ With config (all fields optional):
|
|
|
145
154
|
```js
|
|
146
155
|
const { source, report } = run(shader, {
|
|
147
156
|
profile: 'max', // "baseline" | "aggressive" | "max" (default)
|
|
148
|
-
mangle: true, // rename
|
|
157
|
+
mangle: true, // also rename struct types/members, constants, overrides (default: on for "max")
|
|
149
158
|
preserveSymbols: ['main'], // names to keep untouched
|
|
150
159
|
beautify: false, // compact output (default: false)
|
|
151
160
|
indent: 2, // spaces per level when beautify is true
|
|
@@ -153,20 +162,20 @@ const { source, report } = run(shader, {
|
|
|
153
162
|
// also accepts { decimalPlaces: 6 }, { significantFigures: 4 },
|
|
154
163
|
// or per-type: { f32: 6, f64: { significantFigures: 12 } }
|
|
155
164
|
maxInlineNodeCount: 48, // inlining budget per function
|
|
156
|
-
maxInlineCallSites: 6, //
|
|
165
|
+
maxInlineCallSites: 6, // max call sites a function may have and still inline
|
|
157
166
|
preamble: preambleSrc, // external decls prepended for parsing, stripped from output
|
|
158
167
|
validateEachPass: false, // re-validate WGSL after every pass
|
|
159
168
|
});
|
|
160
169
|
```
|
|
161
170
|
|
|
162
|
-
Node.js (synchronous init):
|
|
171
|
+
Node.js 20.6+ (synchronous init):
|
|
163
172
|
|
|
164
173
|
```js
|
|
165
174
|
import { readFileSync } from 'node:fs';
|
|
166
175
|
import { initSync, run } from 'nagami-rs';
|
|
167
176
|
const wasm = readFileSync(new URL('nagami_bg.wasm', import.meta.resolve('nagami-rs')));
|
|
168
177
|
initSync({ module: wasm });
|
|
169
|
-
const { source, report } = run(shader);
|
|
178
|
+
const { source, report } = run(shader);
|
|
170
179
|
```
|
|
171
180
|
|
|
172
181
|
## License
|
package/nagami.d.ts
CHANGED
|
@@ -46,12 +46,29 @@ export interface Report {
|
|
|
46
46
|
outputBytes: number;
|
|
47
47
|
converged: boolean;
|
|
48
48
|
sweeps: number;
|
|
49
|
+
/** naga's error when the output is the input lexically compacted only. */
|
|
50
|
+
bailout: string | null;
|
|
49
51
|
passReports: PassReport[];
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
export interface StructRename {
|
|
55
|
+
name: string;
|
|
56
|
+
members: Record<string, string>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface NameMap {
|
|
60
|
+
entryPoints: Record<string, string>;
|
|
61
|
+
globals: Record<string, string>;
|
|
62
|
+
functions: Record<string, string>;
|
|
63
|
+
constants: Record<string, string>;
|
|
64
|
+
overrides: Record<string, string>;
|
|
65
|
+
structs: Record<string, StructRename>;
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
export interface Output {
|
|
53
69
|
source: string;
|
|
54
70
|
report: Report;
|
|
71
|
+
nameMap: NameMap | null;
|
|
55
72
|
}
|
|
56
73
|
|
|
57
74
|
export function run(source: string, config?: Config): Output;
|
|
@@ -60,12 +77,9 @@ export function version(): string;
|
|
|
60
77
|
|
|
61
78
|
|
|
62
79
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* `RuntimeError: unreachable executed`. Hand-rolled because the
|
|
67
|
-
* `console_error_panic_hook` crate adds only a JS stack trace of
|
|
68
|
-
* mangled wasm frame indices.
|
|
80
|
+
* Panic text to `console.error`: under `panic = "abort"` the hook still runs
|
|
81
|
+
* first, so browsers see the message instead of `RuntimeError: unreachable`.
|
|
82
|
+
* Hand-rolled; `console_error_panic_hook` adds only mangled wasm frames.
|
|
69
83
|
*/
|
|
70
84
|
export function install_panic_hook(): void;
|
|
71
85
|
|
package/nagami.js
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
/* @ts-self-types="./nagami.d.ts" */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `RuntimeError: unreachable executed`. Hand-rolled because the
|
|
8
|
-
* `console_error_panic_hook` crate adds only a JS stack trace of
|
|
9
|
-
* mangled wasm frame indices.
|
|
4
|
+
* Panic text to `console.error`: under `panic = "abort"` the hook still runs
|
|
5
|
+
* first, so browsers see the message instead of `RuntimeError: unreachable`.
|
|
6
|
+
* Hand-rolled; `console_error_panic_hook` adds only mangled wasm frames.
|
|
10
7
|
*/
|
|
11
8
|
export function install_panic_hook() {
|
|
12
9
|
wasm.install_panic_hook();
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
/**
|
|
16
|
-
* Minify
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* Propagates any [`crate::error::Error`] from the pipeline as a
|
|
22
|
-
* [`JsError`] carrying the rendered message.
|
|
13
|
+
* Minify `source` into the parsed [`crate::json`] document (TS `Output`).
|
|
14
|
+
* Errors are thrown JS `Error`s; a `JSON.parse` rejection (unreachable, the
|
|
15
|
+
* renderer emits valid JSON) propagates as its own `SyntaxError`, which keeps
|
|
16
|
+
* `JsValue`'s `Debug` glue out of the bundle.
|
|
23
17
|
* @param {string} source
|
|
24
18
|
* @param {any} config
|
|
25
19
|
* @returns {any}
|
|
@@ -43,7 +37,7 @@ export function run(source, config) {
|
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
/**
|
|
46
|
-
*
|
|
40
|
+
* Crate version baked into the bundle.
|
|
47
41
|
* @returns {string}
|
|
48
42
|
*/
|
|
49
43
|
export function version() {
|
|
@@ -104,7 +98,7 @@ function __wbg_get_imports() {
|
|
|
104
98
|
__wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
|
|
105
99
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
106
100
|
},
|
|
107
|
-
|
|
101
|
+
__wbg_error_82407668d9111acb: function(arg0, arg1) {
|
|
108
102
|
console.error(getStringFromWasm0(arg0, arg1));
|
|
109
103
|
},
|
|
110
104
|
__wbg_get_971a0c45d172643f: function() { return handleError(function (arg0, arg1) {
|
|
@@ -123,28 +117,11 @@ function __wbg_get_imports() {
|
|
|
123
117
|
const ret = getObject(arg0).length;
|
|
124
118
|
return ret;
|
|
125
119
|
},
|
|
126
|
-
|
|
127
|
-
const ret =
|
|
120
|
+
__wbg_parse_1cc93481b0865939: function() { return handleError(function (arg0, arg1) {
|
|
121
|
+
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
128
122
|
return addHeapObject(ret);
|
|
129
|
-
},
|
|
130
|
-
__wbg_new_ebe3e0f6837f0879: function() {
|
|
131
|
-
const ret = new Object();
|
|
132
|
-
return addHeapObject(ret);
|
|
133
|
-
},
|
|
134
|
-
__wbg_push_adb0107829f02d75: function(arg0, arg1) {
|
|
135
|
-
const ret = getObject(arg0).push(getObject(arg1));
|
|
136
|
-
return ret;
|
|
137
|
-
},
|
|
138
|
-
__wbg_set_8155bb79a948541b: function() { return handleError(function (arg0, arg1, arg2) {
|
|
139
|
-
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
|
140
|
-
return ret;
|
|
141
123
|
}, arguments); },
|
|
142
|
-
__wbindgen_cast_0000000000000001: function(arg0) {
|
|
143
|
-
// Cast intrinsic for `F64 -> Externref`.
|
|
144
|
-
const ret = arg0;
|
|
145
|
-
return addHeapObject(ret);
|
|
146
|
-
},
|
|
147
|
-
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
124
|
+
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
148
125
|
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
149
126
|
const ret = getStringFromWasm0(arg0, arg1);
|
|
150
127
|
return addHeapObject(ret);
|
package/nagami_bg.wasm
CHANGED
|
Binary file
|