wesl-plugin 0.6.70 → 0.6.72

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
@@ -96,10 +96,10 @@ export default {
96
96
 
97
97
  ### Conditions in Import Path
98
98
 
99
- For `?static`, you can specify conditions directly in the import:
99
+ For `?static`, you can specify conditions as query parameters:
100
100
 
101
101
  ```ts
102
- import wgsl from "./app.wesl MOBILE=true DEBUG=false ?static";
102
+ import wgsl from "./app.wesl?MOBILE=true&DEBUG=false&static";
103
103
  ```
104
104
 
105
105
  ## Configuration (wesl.toml)
@@ -124,7 +124,7 @@ import type { PluginExtension } from "wesl-plugin";
124
124
 
125
125
  const myExtension: PluginExtension = {
126
126
  extensionName: "myfeature", // enables ?myfeature imports
127
- emitFn: async (shaderPath, api, conditions) => {
127
+ emitFn: async (shaderPath, api, conditions, options) => {
128
128
  const sources = await api.weslSrc();
129
129
  // Return JavaScript code as a string
130
130
  return `export default ${JSON.stringify(sources)};`;
@@ -31,14 +31,16 @@ interface WeslTomlInfo {
31
31
  }
32
32
  //#endregion
33
33
  //#region src/PluginExtension.d.ts
34
- /** function type required for for emit extensions */
34
+ /** function type required for emit extensions */
35
35
  type ExtensionEmitFn = (/** absolute path to the shader to which the extension is attached */
36
36
 
37
37
  shaderPath: string, /** support functions available to plugin extensions */
38
38
 
39
39
  pluginApi: PluginExtensionApi, /** static conditions specified on the js import */
40
40
 
41
- conditions?: Record<string, boolean>) => Promise<string>;
41
+ conditions?: Record<string, boolean>, /** plugin-level options from query params (e.g., { include: "all" }) */
42
+
43
+ options?: Record<string, string>) => Promise<string>;
42
44
  /** an extension that runs inside the wesl-js build plugin */
43
45
  interface PluginExtension extends WeslJsPlugin {
44
46
  /** javascript imports with this suffix will trigger the plugin */
@@ -47,6 +49,10 @@ interface PluginExtension extends WeslJsPlugin {
47
49
  * e.g. import myPluginJs from "./foo.wesl?myPlugin"; */
48
50
  emitFn: ExtensionEmitFn;
49
51
  }
52
+ interface ProjectSources {
53
+ weslSrc: Record<string, string>;
54
+ dependencies: string[];
55
+ }
50
56
  /** api supplied to plugin extensions */
51
57
  interface PluginExtensionApi {
52
58
  weslToml: () => Promise<WeslTomlInfo>;
@@ -54,6 +60,12 @@ interface PluginExtensionApi {
54
60
  weslRegistry: () => Promise<BatchModuleResolver>;
55
61
  weslMain: (baseId: string) => Promise<string>;
56
62
  weslDependencies: () => Promise<string[]>;
63
+ /** weslRoot relative to tomlDir, with forward slashes. */
64
+ debugWeslRoot: () => Promise<string>;
65
+ /** Get weslSrc scoped to modules reachable from a root, plus their deps. */
66
+ scopedProject: (rootModuleName: string) => Promise<ProjectSources>;
67
+ /** Fetch project sources, either all or scoped to reachable modules. */
68
+ fetchProject: (rootModuleName: string, options?: Record<string, string>) => Promise<ProjectSources>;
57
69
  }
58
70
  //#endregion
59
- export { PluginExtension as n, PluginExtensionApi as r, ExtensionEmitFn as t };
71
+ export { ProjectSources as i, PluginExtension as n, PluginExtensionApi as r, ExtensionEmitFn as t };
@@ -7,19 +7,15 @@ import fs, { realpathSync, statSync } from "node:fs";
7
7
  import process from "node:process";
8
8
  import v8 from "node:v8";
9
9
  import { format, inspect } from "node:util";
10
-
11
10
  //#region src/extensions/LinkExtension.ts
12
11
  const linkBuildExtension = {
13
12
  extensionName: "link",
14
13
  emitFn: emitLinkJs
15
14
  };
16
15
  /** Emit a JavaScript LinkParams structure, ready for linking at runtime. */
17
- async function emitLinkJs(baseId, api) {
18
- const { resolvedRoot, tomlDir } = await api.weslToml();
19
- const weslSrc = await api.weslSrc();
16
+ async function emitLinkJs(baseId, api, _conditions, options) {
20
17
  const rootModuleName = noSuffix(await api.weslMain(baseId));
21
- const debugWeslRoot = path.relative(tomlDir, resolvedRoot).replaceAll(path.sep, "/");
22
- const autoDeps = await api.weslDependencies();
18
+ const [{ weslSrc, dependencies: autoDeps }, debugWeslRoot] = await Promise.all([api.fetchProject(rootModuleName, options), api.debugWeslRoot()]);
23
19
  const sanitizedDeps = autoDeps.map((dep) => dep.replaceAll("/", "_"));
24
20
  const bundleImports = autoDeps.map((p, i) => `import ${sanitizedDeps[i]} from "${p}";`).join("\n");
25
21
  const paramsName = `link${path.basename(rootModuleName).replace(/\W/g, "_")}Config`;
@@ -41,7 +37,6 @@ async function emitLinkJs(baseId, api) {
41
37
  function serializeFields(record) {
42
38
  return Object.entries(record).map(([k, v]) => ` ${k}: ${JSON.stringify(v, null, 2)}`).join(",\n");
43
39
  }
44
-
45
40
  //#endregion
46
41
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/lib/errors.js
47
42
  /**
@@ -378,7 +373,6 @@ function determineSpecificType(value) {
378
373
  if (inspected.length > 28) inspected = `${inspected.slice(0, 25)}...`;
379
374
  return `type ${typeof value} (${inspected})`;
380
375
  }
381
-
382
376
  //#endregion
383
377
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/lib/package-json-reader.js
384
378
  /**
@@ -474,7 +468,6 @@ function getPackageScopeConfig(resolved) {
474
468
  function getPackageType(url) {
475
469
  return getPackageScopeConfig(url).type;
476
470
  }
477
-
478
471
  //#endregion
479
472
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/lib/get-format.js
480
473
  const { ERR_UNKNOWN_FILE_EXTENSION } = codes;
@@ -578,7 +571,6 @@ function defaultGetFormatWithoutErrors(url, context) {
578
571
  if (!hasOwnProperty.call(protocolHandlers, protocol)) return null;
579
572
  return protocolHandlers[protocol](url, context, true) || null;
580
573
  }
581
-
582
574
  //#endregion
583
575
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/lib/utils.js
584
576
  const { ERR_INVALID_ARG_VALUE } = codes;
@@ -607,7 +599,6 @@ function getConditionsSet(conditions) {
607
599
  }
608
600
  return getDefaultConditionsSet();
609
601
  }
610
-
611
602
  //#endregion
612
603
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/lib/resolve.js
613
604
  /**
@@ -1267,7 +1258,6 @@ function defaultResolve(specifier, context = {}) {
1267
1258
  format: defaultGetFormatWithoutErrors(url, { parentURL })
1268
1259
  };
1269
1260
  }
1270
-
1271
1261
  //#endregion
1272
1262
  //#region ../../node_modules/.pnpm/import-meta-resolve@4.1.0/node_modules/import-meta-resolve/index.js
1273
1263
  /**
@@ -1298,40 +1288,32 @@ function resolve(specifier, parent) {
1298
1288
  throw error;
1299
1289
  }
1300
1290
  }
1301
-
1302
1291
  //#endregion
1303
1292
  //#region src/extensions/StaticExtension.ts
1304
- /**
1305
- * a wesl-js ?static build extension that statically links from the root file
1306
- * and emits a JavaScript file containing the linked wgsl string.
1307
- *
1308
- * use it like this:
1309
- * import wgsl from "./shaders/app.wesl?static";
1310
- *
1311
- * or with conditions, like this:
1312
- * import wgsl from "../shaders/foo/app.wesl MOBILE=true FUN SAFE=false ?static";
1313
- */
1293
+ /** Build extension for ?static imports: links WESL at build time, emits WGSL string. */
1314
1294
  const staticBuildExtension = {
1315
1295
  extensionName: "static",
1316
1296
  emitFn: emitStaticJs
1317
1297
  };
1318
- /** Emit a JavaScript file containing the wgsl string */
1319
- async function emitStaticJs(baseId, api, conditions) {
1298
+ /** Emit a JS module exporting the statically linked WGSL string. */
1299
+ async function emitStaticJs(baseId, api, conditions, _options) {
1320
1300
  const { resolvedRoot, tomlDir } = await api.weslToml();
1321
1301
  const parentModule = url.pathToFileURL(path.join(tomlDir, "wesl.toml")).toString();
1322
- const futureLibs = (await api.weslDependencies()).map((d) => resolve(d, parentModule)).map((f) => import(f));
1323
- const libs = (await Promise.all(futureLibs)).map((m) => m.default);
1324
- return `
1325
- export const wgsl = \`${(await link({
1326
- weslSrc: await api.weslSrc(),
1327
- rootModuleName: noSuffix(await api.weslMain(baseId)),
1302
+ const rootModuleName = noSuffix(await api.weslMain(baseId));
1303
+ const [weslSrc, dependencies] = await Promise.all([api.weslSrc(), api.weslDependencies()]);
1304
+ const libFileUrls = dependencies.map((d) => resolve(d, parentModule));
1305
+ const libs = (await Promise.all(libFileUrls.map((f) => import(f)))).map((m) => m.default);
1306
+ const { dest: wgsl } = await link({
1307
+ weslSrc,
1308
+ rootModuleName,
1328
1309
  debugWeslRoot: path.relative(tomlDir, resolvedRoot).replaceAll(path.sep, "/"),
1329
1310
  libs,
1330
1311
  conditions
1331
- })).dest}\`;
1312
+ });
1313
+ return `
1314
+ export const wgsl = \`${wgsl}\`;
1332
1315
  export default wgsl;
1333
1316
  `;
1334
1317
  }
1335
-
1336
1318
  //#endregion
1337
- export { resolve as n, linkBuildExtension as r, staticBuildExtension as t };
1319
+ export { resolve as n, linkBuildExtension as r, staticBuildExtension as t };