UNPKG

wesl-plugin

Version:

[![NPM Version](https://img.shields.io/npm/v/wesl-plugin)](https://www.npmjs.com/package/wesl-plugin) [![Static Badge](https://img.shields.io/badge/Read%20the%20-Docs-blue)](https://wesl-lang.dev/)

91 lines (88 loc) 3.08 kB
import path from "node:path"; import { link, noSuffix } from "wesl"; import url from "node:url"; import { resolve } from "import-meta-resolve"; //#region src/extensions/LinkExtension.ts const linkBuildExtension = { extensionName: "link", emitFn: emitLinkJs }; /** Emit a JavaScript LinkParams structure, ready for linking at runtime. */ async function emitLinkJs(baseId, api) { const { resolvedWeslRoot, tomlDir } = await api.weslToml(); const weslSrc = await api.weslSrc(); const rootModule = await api.weslMain(baseId); const rootModuleName = noSuffix(rootModule); const tomlRelative = path.relative(tomlDir, resolvedWeslRoot); const debugWeslRoot = tomlRelative.replaceAll(path.sep, "/"); const autoDeps = await api.weslDependencies(); const sanitizedDeps = autoDeps.map((dep) => dep.replaceAll("/", "_")); const bundleImports = autoDeps.map((p, i) => `import ${sanitizedDeps[i]} from "${p}";`).join("\n"); const rootName = path.basename(rootModuleName); const paramsName = `link${rootName}Config`; const linkParams = { rootModuleName, weslSrc, debugWeslRoot }; const libsStr = `libs: [${sanitizedDeps.join(", ")}]`; const linkParamsStr = `{ ${serializeFields(linkParams)}, ${libsStr}, }`; const src = ` ${bundleImports} export const ${paramsName} = ${linkParamsStr}; export default ${paramsName}; `; return src; } function serializeFields(record) { return Object.entries(record).map(([k, v]) => ` ${k}: ${JSON.stringify(v, null, 2)}`).join(",\n"); } //#endregion //#region src/extensions/StaticExtension.ts /** * a wesl-js ?static build extension that statically links from the root file * and emits a JavaScript file containing the linked wgsl string. * * use it like this: * import wgsl from "./shaders/app.wesl?static"; * * or with conditions, like this: * import wgsl from "../shaders/foo/app.wesl MOBILE=true FUN SAFE=false ?static"; */ const staticBuildExtension = { extensionName: "static", emitFn: emitStaticJs }; /** Emit a JavaScript file containing the wgsl string */ async function emitStaticJs(baseId, api, conditions) { const { resolvedWeslRoot, tomlDir } = await api.weslToml(); const parentModule = url.pathToFileURL(path.join(tomlDir, "wesl.toml")).toString(); const dependencies = await api.weslDependencies(); const libFileUrls = dependencies.map((d) => resolve(d, parentModule)); const futureLibs = libFileUrls.map((f) => import(f)); const libModules = await Promise.all(futureLibs); const libs = libModules.map((m) => m.default); const weslSrc = await api.weslSrc(); const rootModule = await api.weslMain(baseId); const rootModuleName = noSuffix(rootModule); const tomlRelative = path.relative(tomlDir, resolvedWeslRoot); const debugWeslRoot = tomlRelative.replaceAll(path.sep, "/"); const result = await link({ weslSrc, rootModuleName, debugWeslRoot, libs, conditions }); const wgsl = result.dest; const src = ` export const wgsl = \`${wgsl}\`; export default wgsl; `; return src; } //#endregion export { linkBuildExtension, staticBuildExtension };