wesl-plugin 0.6.47 → 0.6.49
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 +96 -70
- package/dist/{WeslPlugin-BhkB-CW-.js → WeslPlugin-JYxf2uLM.js} +43 -11
- package/dist/{WeslPluginOptions-BXvD7dWh.d.ts → WeslPluginOptions-BljqDSO5.d.ts} +2 -0
- package/dist/pluginIndex.js +1 -1
- package/dist/plugins/astro.d.ts +1 -1
- package/dist/plugins/astro.js +1 -1
- package/dist/plugins/esbuild.d.ts +1 -1
- package/dist/plugins/esbuild.js +1 -1
- package/dist/plugins/farm.d.ts +1 -1
- package/dist/plugins/farm.js +1 -1
- package/dist/plugins/nuxt.d.ts +1 -1
- package/dist/plugins/nuxt.js +3 -3
- package/dist/plugins/rollup.d.ts +1 -1
- package/dist/plugins/rollup.js +1 -1
- package/dist/plugins/rspack.d.ts +1 -1
- package/dist/plugins/rspack.js +1 -1
- package/dist/plugins/vite.d.ts +1 -1
- package/dist/plugins/vite.js +2 -2
- package/dist/plugins/webpack.d.ts +1 -1
- package/dist/plugins/webpack.js +2 -2
- package/dist/{vite-BqdMYd8l.js → vite-CE8Yhwk-.js} +1 -1
- package/dist/{webpack-D-jacRMO.js → webpack-C7YoLSyP.js} +1 -1
- package/package.json +2 -2
- package/src/WeslPlugin.ts +40 -9
- package/src/WeslPluginOptions.ts +3 -0
- package/src/extensions/LinkExtension.ts +1 -1
package/README.md
CHANGED
|
@@ -1,109 +1,135 @@
|
|
|
1
|
-
#
|
|
1
|
+
# WESL Plugin
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/wesl-plugin)
|
|
4
4
|
[](https://wesl-lang.dev/)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
in JavaScript bundlers to make using webgpu shaders more convenient.
|
|
6
|
+
Bundler plugin for importing `.wesl` and `.wgsl` shader files in JavaScript/TypeScript.
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
## Install
|
|
10
9
|
|
|
11
|
-
```ts
|
|
12
|
-
import linkConfig from "./shaders/app.wesl?link";
|
|
13
10
|
```
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import linkConfig from "./shaders/app.wesl?static";
|
|
11
|
+
npm install wesl wesl-plugin
|
|
17
12
|
```
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
## Quick Start
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
### Build-time linking (?static)
|
|
17
|
+
|
|
18
|
+
Link shaders at build time for the smallest application bundle size.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// vite.config.ts
|
|
22
|
+
import { staticBuildExtension } from "wesl-plugin";
|
|
23
|
+
import viteWesl from "wesl-plugin/vite";
|
|
22
24
|
|
|
25
|
+
export default {
|
|
26
|
+
plugins: [viteWesl({ extensions: [staticBuildExtension] })]
|
|
27
|
+
};
|
|
23
28
|
```
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// app.ts
|
|
32
|
+
import wgsl from "./shaders/main.wesl?static";
|
|
33
|
+
|
|
34
|
+
const module = device.createShaderModule({ code: wgsl });
|
|
26
35
|
```
|
|
27
36
|
|
|
28
|
-
###
|
|
37
|
+
### Runtime linking (?link)
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
Link shaders at runtime when you need dynamic conditions or constants:
|
|
31
40
|
|
|
32
41
|
```ts
|
|
33
|
-
|
|
34
|
-
import weslPlugin from "wesl-plugin/vite";
|
|
42
|
+
// vite.config.ts
|
|
35
43
|
import { linkBuildExtension } from "wesl-plugin";
|
|
44
|
+
import viteWesl from "wesl-plugin/vite";
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
plugins: [
|
|
46
|
+
export default {
|
|
47
|
+
plugins: [viteWesl({ extensions: [linkBuildExtension] })]
|
|
39
48
|
};
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// app.ts
|
|
53
|
+
import { link } from "wesl";
|
|
54
|
+
import shaderConfig from "./shaders/main.wesl?link";
|
|
55
|
+
|
|
56
|
+
const linked = await link({
|
|
57
|
+
...shaderConfig,
|
|
58
|
+
conditions: { MOBILE: isMobileGPU },
|
|
59
|
+
constants: { num_lights: 4 }
|
|
60
|
+
});
|
|
40
61
|
|
|
41
|
-
|
|
62
|
+
const module = linked.createShaderModule(device, {});
|
|
42
63
|
```
|
|
43
64
|
|
|
44
|
-
|
|
45
|
-
wesl or wgsl shaders with a `?link` suffix and link them into WGSL at runtime.
|
|
65
|
+
## Other Bundlers
|
|
46
66
|
|
|
47
67
|
```ts
|
|
48
|
-
import
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
rootModuleName: "myVerts.wesl",
|
|
54
|
-
conditions: {mobileGPU: true}
|
|
55
|
-
});
|
|
56
|
-
const computeShader = await link({
|
|
57
|
-
...linkConfig,
|
|
58
|
-
rootModuleName: "myCompute.wesl",
|
|
59
|
-
constants: {num_lights: 1}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
68
|
+
import viteWesl from "wesl-plugin/vite";
|
|
69
|
+
import esbuildWesl from "wesl-plugin/esbuild";
|
|
70
|
+
import rollupWesl from "wesl-plugin/rollup";
|
|
71
|
+
import webpackWesl from "wesl-plugin/webpack";
|
|
72
|
+
// Also: nuxt, farm, rspack, astro
|
|
63
73
|
```
|
|
64
74
|
|
|
65
|
-
|
|
75
|
+
## Extensions
|
|
76
|
+
|
|
77
|
+
Extensions enable different import suffixes:
|
|
78
|
+
|
|
79
|
+
| Extension | Suffix | Output | Use Case |
|
|
80
|
+
|-----------|--------|--------|----------|
|
|
81
|
+
| `staticBuildExtension` | `?static` | WGSL string | Build-time linking, simplest |
|
|
82
|
+
| `linkBuildExtension` | `?link` | LinkParams object | Runtime conditions/constants |
|
|
66
83
|
|
|
67
|
-
|
|
84
|
+
### Combining Extensions
|
|
68
85
|
|
|
69
|
-
```
|
|
70
|
-
import
|
|
71
|
-
import
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
```ts
|
|
87
|
+
import { staticBuildExtension, linkBuildExtension } from "wesl-plugin";
|
|
88
|
+
import viteWesl from "wesl-plugin/vite";
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
plugins: [viteWesl({
|
|
92
|
+
extensions: [staticBuildExtension, linkBuildExtension]
|
|
93
|
+
})]
|
|
94
|
+
};
|
|
77
95
|
```
|
|
78
96
|
|
|
79
|
-
|
|
97
|
+
### Conditions in Import Path
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
Reads the `wesl.toml` file to find local shader files and libraries,
|
|
83
|
-
Returns a `LinkParams` object ready to use for runtime linking.
|
|
99
|
+
For `?static`, you can specify conditions directly in the import:
|
|
84
100
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
101
|
+
```ts
|
|
102
|
+
import wgsl from "./app.wesl MOBILE=true DEBUG=false ?static";
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Configuration (wesl.toml)
|
|
106
|
+
|
|
107
|
+
The plugin reads `wesl.toml` to find shader files and dependencies:
|
|
89
108
|
|
|
90
|
-
|
|
109
|
+
```toml
|
|
110
|
+
weslFiles = ["shaders/**/*.wesl"]
|
|
111
|
+
weslRoot = "shaders"
|
|
112
|
+
dependencies = ["auto"] # Auto-detect from package.json
|
|
113
|
+
```
|
|
91
114
|
|
|
92
|
-
|
|
93
|
-
translate some wgsl `struct` elements into JavaScript and TypeScript.
|
|
94
|
-
Demonstrates to wesl-plugin extension authors how to connect
|
|
95
|
-
to the wesl-plugin, how to produce JavaScript, and how to produce TypeScript.
|
|
96
|
-
- **BindingLayoutExtension** - (_prototype_) import `?bindingLayout` to collect JavaScript
|
|
97
|
-
`BindingGroupLayout` objects.
|
|
98
|
-
Works in concert with the `bindingStructsPlugin` to translate a proposed new WGSL
|
|
99
|
-
feature for defining binding group layouts in shaders [#4957](https://github.com/gpuweb/gpuweb/issues/4957).
|
|
115
|
+
## Prototype Extensions
|
|
100
116
|
|
|
101
|
-
|
|
117
|
+
- **SimpleReflectExtension** - Demo for extension authors showing how to generate JS/TS from shader structs
|
|
118
|
+
- **BindingLayoutExtension** - Prototype for generating `BindGroupLayout` objects from shaders
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
## Writing Custom Extensions
|
|
104
121
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
122
|
+
```ts
|
|
123
|
+
import type { PluginExtension } from "wesl-plugin";
|
|
124
|
+
|
|
125
|
+
const myExtension: PluginExtension = {
|
|
126
|
+
extensionName: "myfeature", // enables ?myfeature imports
|
|
127
|
+
emitFn: async (shaderPath, api, conditions) => {
|
|
128
|
+
const sources = await api.weslSrc();
|
|
129
|
+
// Return JavaScript code as a string
|
|
130
|
+
return `export default ${JSON.stringify(sources)};`;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
```
|
|
108
134
|
|
|
109
|
-
See [PluginExtension.ts](https://github.com/wgsl-tooling-wg/wesl-js/blob/
|
|
135
|
+
See [PluginExtension.ts](https://github.com/wgsl-tooling-wg/wesl-js/blob/main/tools/packages/wesl-plugin/src/PluginExtension.ts) for the full API.
|
|
@@ -9880,11 +9880,14 @@ function weslPlugin(options, meta) {
|
|
|
9880
9880
|
meta,
|
|
9881
9881
|
options
|
|
9882
9882
|
};
|
|
9883
|
+
const log = options.debug ? debugLog : noopLog;
|
|
9884
|
+
log("init", { extensions: options.extensions?.map((e) => e.extensionName) });
|
|
9883
9885
|
return {
|
|
9884
9886
|
name: "wesl-plugin",
|
|
9885
|
-
resolveId: buildResolver(options, context),
|
|
9886
|
-
load: buildLoader(context),
|
|
9887
|
+
resolveId: buildResolver(options, context, log),
|
|
9888
|
+
load: buildLoader(context, log),
|
|
9887
9889
|
watchChange(id, _change) {
|
|
9890
|
+
log("watchChange", { id });
|
|
9888
9891
|
if (id.endsWith("wesl.toml")) {
|
|
9889
9892
|
cache.weslToml = void 0;
|
|
9890
9893
|
cache.registry = void 0;
|
|
@@ -9905,15 +9908,18 @@ function pluginsByName(options) {
|
|
|
9905
9908
|
* or
|
|
9906
9909
|
* foo/bar.wesl COND=false ?static
|
|
9907
9910
|
*
|
|
9911
|
+
* Bundlers may add extra query params (e.g. Vite adds ?import for dynamic imports,
|
|
9912
|
+
* ?t=123 for cache busting), so we capture the full query and search within it.
|
|
9913
|
+
*
|
|
9908
9914
|
* someday it'd be nice to support import attributes like:
|
|
9909
9915
|
* import "foo.bar.wesl?static" with { COND: false};
|
|
9910
9916
|
* (but that doesn't seem supported to be supported in the the bundler plugins yet)
|
|
9911
9917
|
*/
|
|
9912
|
-
const pluginMatch = /(^^)?(?<baseId>.*\.w[eg]sl)(?<cond>(\s*\w+(=\w+)?\s*)*)\?(?<
|
|
9918
|
+
const pluginMatch = /(^^)?(?<baseId>.*\.w[eg]sl)(?<cond>(\s*\w+(=\w+)?\s*)*)\?(?<query>.+)$/;
|
|
9913
9919
|
const resolvedPrefix = "^^";
|
|
9914
9920
|
/** build plugin entry for 'resolverId'
|
|
9915
9921
|
* to validate our javascript virtual module imports (with e.g. ?static or ?link suffixes) */
|
|
9916
|
-
function buildResolver(options, context) {
|
|
9922
|
+
function buildResolver(options, context, log) {
|
|
9917
9923
|
const suffixes = pluginNames(options);
|
|
9918
9924
|
return resolver;
|
|
9919
9925
|
/**
|
|
@@ -9927,39 +9933,58 @@ function buildResolver(options, context) {
|
|
|
9927
9933
|
if (id.startsWith(resolvedPrefix)) return id;
|
|
9928
9934
|
if (id === context.weslToml) return id;
|
|
9929
9935
|
const matched = pluginSuffixMatch(id, suffixes);
|
|
9936
|
+
log("resolveId", {
|
|
9937
|
+
id,
|
|
9938
|
+
matched: !!matched,
|
|
9939
|
+
suffixes
|
|
9940
|
+
});
|
|
9930
9941
|
if (matched) {
|
|
9931
9942
|
const { importParams, baseId, pluginName } = matched;
|
|
9932
9943
|
const importerDir = path.dirname(importer);
|
|
9933
|
-
|
|
9944
|
+
const result = resolvedPrefix + path.join(importerDir, baseId) + importParams + "?" + pluginName;
|
|
9945
|
+
log("resolveId resolved", { result });
|
|
9946
|
+
return result;
|
|
9934
9947
|
}
|
|
9935
9948
|
return matched ? id : null;
|
|
9936
9949
|
}
|
|
9937
9950
|
}
|
|
9951
|
+
/** Find matching plugin suffix in query string (handles ?import&static, ?t=123&static, etc.) */
|
|
9938
9952
|
function pluginSuffixMatch(id, suffixes) {
|
|
9939
|
-
const
|
|
9940
|
-
const
|
|
9941
|
-
if (!
|
|
9953
|
+
const match$1 = id.match(pluginMatch);
|
|
9954
|
+
const query = match$1?.groups?.query;
|
|
9955
|
+
if (!query) return null;
|
|
9956
|
+
const segments = query.split("&");
|
|
9957
|
+
const pluginName = suffixes.find((s) => segments.includes(s));
|
|
9958
|
+
if (!pluginName) return null;
|
|
9942
9959
|
return {
|
|
9943
9960
|
pluginName,
|
|
9944
|
-
baseId:
|
|
9945
|
-
importParams:
|
|
9961
|
+
baseId: match$1.groups.baseId,
|
|
9962
|
+
importParams: match$1.groups?.cond
|
|
9946
9963
|
};
|
|
9947
9964
|
}
|
|
9948
9965
|
/** build plugin function for serving a javascript module in response to
|
|
9949
9966
|
* an import of of our virtual import modules. */
|
|
9950
|
-
function buildLoader(context) {
|
|
9967
|
+
function buildLoader(context, log) {
|
|
9951
9968
|
const { options } = context;
|
|
9952
9969
|
const suffixes = pluginNames(options);
|
|
9953
9970
|
const pluginsMap = pluginsByName(options);
|
|
9954
9971
|
return loader;
|
|
9955
9972
|
async function loader(id) {
|
|
9956
9973
|
const matched = pluginSuffixMatch(id, suffixes);
|
|
9974
|
+
log("load", {
|
|
9975
|
+
id,
|
|
9976
|
+
matched: matched?.pluginName ?? null
|
|
9977
|
+
});
|
|
9957
9978
|
if (matched) {
|
|
9958
9979
|
const buildPluginApi = buildApi(context, this);
|
|
9959
9980
|
const plugin = pluginsMap[matched.pluginName];
|
|
9960
9981
|
const { baseId, importParams } = matched;
|
|
9961
9982
|
const conditions = importParamsToConditions(importParams);
|
|
9962
9983
|
const shaderPath = baseId.startsWith(resolvedPrefix) ? baseId.slice(2) : baseId;
|
|
9984
|
+
log("load emitting", {
|
|
9985
|
+
shaderPath,
|
|
9986
|
+
conditions
|
|
9987
|
+
});
|
|
9963
9988
|
return await plugin.emitFn(shaderPath, buildPluginApi, conditions);
|
|
9964
9989
|
}
|
|
9965
9990
|
return null;
|
|
@@ -9981,6 +10006,13 @@ function importParamsToConditions(importParams) {
|
|
|
9981
10006
|
});
|
|
9982
10007
|
return Object.fromEntries(condEntries);
|
|
9983
10008
|
}
|
|
10009
|
+
function fmtDebugData(data) {
|
|
10010
|
+
return data ? " " + JSON.stringify(data) : "";
|
|
10011
|
+
}
|
|
10012
|
+
function debugLog(msg, data) {
|
|
10013
|
+
console.error(`[wesl-plugin] ${msg}${fmtDebugData(data)}`);
|
|
10014
|
+
}
|
|
10015
|
+
function noopLog() {}
|
|
9984
10016
|
const unplugin = createUnplugin((options, meta) => {
|
|
9985
10017
|
return weslPlugin(options, meta);
|
|
9986
10018
|
});
|
|
@@ -4,6 +4,8 @@ import { n as PluginExtension } from "./PluginExtension-DlhUTOLC.js";
|
|
|
4
4
|
interface WeslPluginOptions {
|
|
5
5
|
weslToml?: string;
|
|
6
6
|
extensions?: PluginExtension[];
|
|
7
|
+
/** Log plugin activity to stderr for debugging */
|
|
8
|
+
debug?: boolean;
|
|
7
9
|
}
|
|
8
10
|
//#endregion
|
|
9
11
|
export { WeslPluginOptions as t };
|
package/dist/pluginIndex.js
CHANGED
|
@@ -17,7 +17,7 @@ async function emitLinkJs(baseId, api) {
|
|
|
17
17
|
const autoDeps = await api.weslDependencies();
|
|
18
18
|
const sanitizedDeps = autoDeps.map((dep) => dep.replaceAll("/", "_"));
|
|
19
19
|
const bundleImports = autoDeps.map((p, i) => `import ${sanitizedDeps[i]} from "${p}";`).join("\n");
|
|
20
|
-
const paramsName = `link${path.basename(rootModuleName)}Config`;
|
|
20
|
+
const paramsName = `link${path.basename(rootModuleName).replace(/\W/g, "_")}Config`;
|
|
21
21
|
const linkParams = {
|
|
22
22
|
rootModuleName,
|
|
23
23
|
weslSrc,
|
package/dist/plugins/astro.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/astro.d.ts
|
|
5
5
|
declare const _default: (options: WeslPluginOptions) => any;
|
package/dist/plugins/astro.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
import * as esbuild0 from "esbuild";
|
|
4
4
|
|
|
5
5
|
//#region src/plugins/esbuild.d.ts
|
package/dist/plugins/esbuild.js
CHANGED
package/dist/plugins/farm.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
import * as _farmfe_core0 from "@farmfe/core";
|
|
4
4
|
|
|
5
5
|
//#region src/plugins/farm.d.ts
|
package/dist/plugins/farm.js
CHANGED
package/dist/plugins/nuxt.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
import * as _nuxt_schema0 from "@nuxt/schema";
|
|
4
4
|
|
|
5
5
|
//#region src/plugins/nuxt.d.ts
|
package/dist/plugins/nuxt.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "../WeslPlugin-
|
|
1
|
+
import "../WeslPlugin-JYxf2uLM.js";
|
|
2
2
|
import "../import-meta-resolve-CUFqnZwT.js";
|
|
3
|
-
import { t as vite_default } from "../vite-
|
|
4
|
-
import { t as webpack_default } from "../webpack-
|
|
3
|
+
import { t as vite_default } from "../vite-CE8Yhwk-.js";
|
|
4
|
+
import { t as webpack_default } from "../webpack-C7YoLSyP.js";
|
|
5
5
|
import { addVitePlugin, addWebpackPlugin, defineNuxtModule } from "@nuxt/kit";
|
|
6
6
|
import "@nuxt/schema";
|
|
7
7
|
|
package/dist/plugins/rollup.d.ts
CHANGED
package/dist/plugins/rollup.js
CHANGED
package/dist/plugins/rspack.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/rspack.d.ts
|
|
5
5
|
declare const _default: (options: WeslPluginOptions) => RspackPluginInstance;
|
package/dist/plugins/rspack.js
CHANGED
package/dist/plugins/vite.d.ts
CHANGED
package/dist/plugins/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../WeslPlugin-
|
|
1
|
+
import "../WeslPlugin-JYxf2uLM.js";
|
|
2
2
|
import "../import-meta-resolve-CUFqnZwT.js";
|
|
3
|
-
import { t as vite_default } from "../vite-
|
|
3
|
+
import { t as vite_default } from "../vite-CE8Yhwk-.js";
|
|
4
4
|
|
|
5
5
|
export { vite_default as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../PluginExtension-DlhUTOLC.js";
|
|
2
|
-
import { t as WeslPluginOptions } from "../WeslPluginOptions-
|
|
2
|
+
import { t as WeslPluginOptions } from "../WeslPluginOptions-BljqDSO5.js";
|
|
3
3
|
import * as webpack0 from "webpack";
|
|
4
4
|
|
|
5
5
|
//#region src/plugins/webpack.d.ts
|
package/dist/plugins/webpack.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../WeslPlugin-
|
|
1
|
+
import "../WeslPlugin-JYxf2uLM.js";
|
|
2
2
|
import "../import-meta-resolve-CUFqnZwT.js";
|
|
3
|
-
import { t as webpack_default } from "../webpack-
|
|
3
|
+
import { t as webpack_default } from "../webpack-C7YoLSyP.js";
|
|
4
4
|
|
|
5
5
|
export { webpack_default as default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wesl-plugin",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.49",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"src",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"unplugin": "^2.3.5",
|
|
28
|
-
"wesl": "0.6.
|
|
28
|
+
"wesl": "0.6.49"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@nuxt/kit": "^3.17.6",
|
package/src/WeslPlugin.ts
CHANGED
|
@@ -50,6 +50,8 @@ export interface PluginContext {
|
|
|
50
50
|
weslToml?: string;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
type DebugLog = (msg: string, data?: Record<string, unknown>) => void;
|
|
54
|
+
|
|
53
55
|
/**
|
|
54
56
|
* A bundler plugin for processing WESL files.
|
|
55
57
|
*
|
|
@@ -66,12 +68,16 @@ export function weslPlugin(
|
|
|
66
68
|
): UnpluginOptions {
|
|
67
69
|
const cache: PluginCache = {};
|
|
68
70
|
const context: PluginContext = { cache, meta, options };
|
|
71
|
+
const log = options.debug ? debugLog : noopLog;
|
|
72
|
+
|
|
73
|
+
log("init", { extensions: options.extensions?.map(e => e.extensionName) });
|
|
69
74
|
|
|
70
75
|
return {
|
|
71
76
|
name: "wesl-plugin",
|
|
72
|
-
resolveId: buildResolver(options, context),
|
|
73
|
-
load: buildLoader(context),
|
|
77
|
+
resolveId: buildResolver(options, context, log),
|
|
78
|
+
load: buildLoader(context, log),
|
|
74
79
|
watchChange(id, _change) {
|
|
80
|
+
log("watchChange", { id });
|
|
75
81
|
if (id.endsWith("wesl.toml")) {
|
|
76
82
|
// The cache is shared for multiple imports
|
|
77
83
|
cache.weslToml = undefined;
|
|
@@ -100,12 +106,15 @@ function pluginsByName(
|
|
|
100
106
|
* or
|
|
101
107
|
* foo/bar.wesl COND=false ?static
|
|
102
108
|
*
|
|
109
|
+
* Bundlers may add extra query params (e.g. Vite adds ?import for dynamic imports,
|
|
110
|
+
* ?t=123 for cache busting), so we capture the full query and search within it.
|
|
111
|
+
*
|
|
103
112
|
* someday it'd be nice to support import attributes like:
|
|
104
113
|
* import "foo.bar.wesl?static" with { COND: false};
|
|
105
114
|
* (but that doesn't seem supported to be supported in the the bundler plugins yet)
|
|
106
115
|
*/
|
|
107
116
|
const pluginMatch =
|
|
108
|
-
/(^^)?(?<baseId>.*\.w[eg]sl)(?<cond>(\s*\w+(=\w+)?\s*)*)\?(?<
|
|
117
|
+
/(^^)?(?<baseId>.*\.w[eg]sl)(?<cond>(\s*\w+(=\w+)?\s*)*)\?(?<query>.+)$/;
|
|
109
118
|
|
|
110
119
|
const resolvedPrefix = "^^";
|
|
111
120
|
|
|
@@ -114,6 +123,7 @@ const resolvedPrefix = "^^";
|
|
|
114
123
|
function buildResolver(
|
|
115
124
|
options: WeslPluginOptions,
|
|
116
125
|
context: PluginContext,
|
|
126
|
+
log: DebugLog,
|
|
117
127
|
): Resolver {
|
|
118
128
|
const suffixes = pluginNames(options);
|
|
119
129
|
return resolver;
|
|
@@ -141,6 +151,7 @@ function buildResolver(
|
|
|
141
151
|
return id;
|
|
142
152
|
}
|
|
143
153
|
const matched = pluginSuffixMatch(id, suffixes);
|
|
154
|
+
log("resolveId", { id, matched: !!matched, suffixes });
|
|
144
155
|
if (matched) {
|
|
145
156
|
const { importParams, baseId, pluginName } = matched;
|
|
146
157
|
|
|
@@ -149,6 +160,7 @@ function buildResolver(
|
|
|
149
160
|
const pathToShader = path.join(importerDir, baseId);
|
|
150
161
|
const result =
|
|
151
162
|
resolvedPrefix + pathToShader + importParams + "?" + pluginName;
|
|
163
|
+
log("resolveId resolved", { result });
|
|
152
164
|
return result;
|
|
153
165
|
}
|
|
154
166
|
return matched ? id : null; // this case doesn't happen AFAIK
|
|
@@ -161,20 +173,27 @@ interface PluginMatch {
|
|
|
161
173
|
pluginName: string;
|
|
162
174
|
}
|
|
163
175
|
|
|
176
|
+
/** Find matching plugin suffix in query string (handles ?import&static, ?t=123&static, etc.) */
|
|
164
177
|
function pluginSuffixMatch(id: string, suffixes: string[]): PluginMatch | null {
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
if (!
|
|
178
|
+
const match = id.match(pluginMatch);
|
|
179
|
+
const query = match?.groups?.query;
|
|
180
|
+
if (!query) return null;
|
|
181
|
+
|
|
182
|
+
// Query params are &-separated; find one that matches a configured suffix
|
|
183
|
+
const segments = query.split("&");
|
|
184
|
+
const pluginName = suffixes.find(s => segments.includes(s));
|
|
185
|
+
if (!pluginName) return null;
|
|
186
|
+
|
|
168
187
|
return {
|
|
169
188
|
pluginName,
|
|
170
|
-
baseId:
|
|
171
|
-
importParams:
|
|
189
|
+
baseId: match.groups!.baseId,
|
|
190
|
+
importParams: match.groups?.cond,
|
|
172
191
|
};
|
|
173
192
|
}
|
|
174
193
|
|
|
175
194
|
/** build plugin function for serving a javascript module in response to
|
|
176
195
|
* an import of of our virtual import modules. */
|
|
177
|
-
function buildLoader(context: PluginContext): Loader {
|
|
196
|
+
function buildLoader(context: PluginContext, log: DebugLog): Loader {
|
|
178
197
|
const { options } = context;
|
|
179
198
|
const suffixes = pluginNames(options);
|
|
180
199
|
const pluginsMap = pluginsByName(options);
|
|
@@ -185,6 +204,7 @@ function buildLoader(context: PluginContext): Loader {
|
|
|
185
204
|
id: string,
|
|
186
205
|
) {
|
|
187
206
|
const matched = pluginSuffixMatch(id, suffixes);
|
|
207
|
+
log("load", { id, matched: matched?.pluginName ?? null });
|
|
188
208
|
if (matched) {
|
|
189
209
|
const buildPluginApi = buildApi(context, this);
|
|
190
210
|
const plugin = pluginsMap[matched.pluginName];
|
|
@@ -194,6 +214,7 @@ function buildLoader(context: PluginContext): Loader {
|
|
|
194
214
|
? baseId.slice(resolvedPrefix.length)
|
|
195
215
|
: baseId;
|
|
196
216
|
|
|
217
|
+
log("load emitting", { shaderPath, conditions });
|
|
197
218
|
return await plugin.emitFn(shaderPath, buildPluginApi, conditions);
|
|
198
219
|
}
|
|
199
220
|
|
|
@@ -226,6 +247,16 @@ function importParamsToConditions(
|
|
|
226
247
|
return conditions;
|
|
227
248
|
}
|
|
228
249
|
|
|
250
|
+
function fmtDebugData(data?: Record<string, unknown>): string {
|
|
251
|
+
return data ? " " + JSON.stringify(data) : "";
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function debugLog(msg: string, data?: Record<string, unknown>): void {
|
|
255
|
+
console.error(`[wesl-plugin] ${msg}${fmtDebugData(data)}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function noopLog(): void {}
|
|
259
|
+
|
|
229
260
|
export const unplugin = createUnplugin(
|
|
230
261
|
(options: WeslPluginOptions, meta: UnpluginContextMeta) => {
|
|
231
262
|
return weslPlugin(options, meta);
|
package/src/WeslPluginOptions.ts
CHANGED
|
@@ -32,7 +32,7 @@ async function emitLinkJs(
|
|
|
32
32
|
.map((p, i) => `import ${sanitizedDeps[i]} from "${p}";`)
|
|
33
33
|
.join("\n");
|
|
34
34
|
|
|
35
|
-
const rootName = path.basename(rootModuleName);
|
|
35
|
+
const rootName = path.basename(rootModuleName).replace(/\W/g, "_");
|
|
36
36
|
const paramsName = `link${rootName}Config`;
|
|
37
37
|
|
|
38
38
|
const linkParams: LinkParams = {
|