wesl-link 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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env -S node --experimental-strip-types
2
+ import "../src/main.ts";
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "wesl-link",
3
- "version": "0.6.47",
3
+ "version": "0.6.49",
4
4
  "type": "module",
5
- "bin": "bin/wesl-link",
5
+ "bin": "bin/wesl-link.js",
6
6
  "files": [
7
- "bin"
7
+ "bin",
8
+ "src"
8
9
  ],
9
10
  "repository": "https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/cli",
10
11
  "homepage": "https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/cli#readme",
@@ -12,13 +13,10 @@
12
13
  "import-meta-resolve": "^4.1.0",
13
14
  "yargs": "^18.0.0",
14
15
  "mini-parse": "0.6.41",
15
- "wesl": "0.6.47"
16
- },
17
- "devDependencies": {
18
- "wesl-tooling": "x"
16
+ "wesl": "0.6.49",
17
+ "wesl-tooling": "0.6.12"
19
18
  },
20
19
  "scripts": {
21
- "build": "tsdown",
22
20
  "test": "vitest --hideSkippedTests",
23
21
  "test:once": "vitest run",
24
22
  "typecheck": "tsgo"
package/src/LinkCli.ts ADDED
@@ -0,0 +1,153 @@
1
+ import path from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ import { resolve } from "import-meta-resolve";
4
+ import { enableTracing, log } from "mini-parse";
5
+ import {
6
+ astToString,
7
+ link,
8
+ RecordResolver,
9
+ scopeToString,
10
+ type WeslBundle,
11
+ } from "wesl";
12
+ import {
13
+ dependencyBundles,
14
+ loadModules,
15
+ versionFromPackageJson,
16
+ } from "wesl-tooling";
17
+ import yargs from "yargs";
18
+
19
+ type CliArgs = Awaited<ReturnType<typeof parseArgs>>;
20
+
21
+ export async function cli(rawArgs: string[]): Promise<void> {
22
+ enableTracing(); // so we get more debug info
23
+ const argv = await parseArgs(rawArgs);
24
+ await linkNormally(argv);
25
+ }
26
+
27
+ async function parseArgs(args: string[]) {
28
+ const toolDir = new URL("..", import.meta.url).href;
29
+ const appVersion = await versionFromPackageJson(toolDir);
30
+ return yargs(args)
31
+ .version(appVersion)
32
+ .command("$0 [module]", false, yargs => {
33
+ yargs.positional("module", {
34
+ type: "string",
35
+ describe:
36
+ "root module to link. Use :: for package references (lygia::utils), / for current package (utils/foo)",
37
+ });
38
+ })
39
+ .option("src", {
40
+ type: "string",
41
+ describe:
42
+ "WGSL/WESL files to bundle in the package (glob syntax, defaults to wesl.toml or shaders/**/*.w[eg]sl)",
43
+ })
44
+ .option("rootModule", {
45
+ type: "string",
46
+ default: "main",
47
+ describe: "start linking from this module name",
48
+ })
49
+ .option("conditions", {
50
+ type: "array",
51
+ describe: "settings for conditional compilation",
52
+ })
53
+ .option("baseDir", {
54
+ requiresArg: true,
55
+ type: "string",
56
+ describe: "root directory for shaders (defaults to wesl.toml or shaders)",
57
+ })
58
+ .option("projectDir", {
59
+ requiresArg: true,
60
+ type: "string",
61
+ default: ".",
62
+ describe: "directory containing package.json",
63
+ })
64
+ .option("details", {
65
+ type: "boolean",
66
+ default: false,
67
+ hidden: true,
68
+ describe: "show details about parsed files",
69
+ })
70
+ .option("emit", {
71
+ type: "boolean",
72
+ default: true,
73
+ hidden: true,
74
+ describe: "emit linked result",
75
+ })
76
+ .help()
77
+ .parse();
78
+ }
79
+
80
+ async function linkNormally(argv: CliArgs): Promise<void> {
81
+ const { baseDir, projectDir, module, rootModule } = argv;
82
+ const weslSrc = await loadModules(projectDir, baseDir, argv.src);
83
+ const projectDirAbs = path.resolve(projectDir);
84
+ const libs = await dependencyBundles(weslSrc, projectDirAbs);
85
+
86
+ const conditionEntries = argv.conditions?.map(c => [c, true]) || [];
87
+ const conditions = Object.fromEntries(conditionEntries);
88
+
89
+ // Use positional module argument if provided, otherwise use --rootModule option (default "main")
90
+ const rootModuleName = (module || rootModule || "main") as string;
91
+ const rootLib = await rootModuleLib(rootModuleName, projectDir, libs);
92
+ if (rootLib) libs.push(rootLib);
93
+
94
+ if (argv.emit) {
95
+ const linked = await link({ weslSrc, rootModuleName, libs, conditions });
96
+ log(linked.dest);
97
+ }
98
+
99
+ if (argv.details) {
100
+ const resolver = new RecordResolver(weslSrc);
101
+ for (const [modulePath, ast] of resolver.allModules()) {
102
+ log(`---\n${modulePath}`);
103
+ log(`\n->ast`);
104
+ log(astToString(ast.moduleElem));
105
+ log(`\n->scope`);
106
+ log(scopeToString(ast.rootScope));
107
+ log();
108
+ }
109
+ }
110
+ }
111
+
112
+ /** load the weslbundle containing the root module (if we haven't already loaded it) */
113
+ async function rootModuleLib(
114
+ rootModuleName: string,
115
+ projectDir: string,
116
+ libs: WeslBundle[],
117
+ ): Promise<WeslBundle | undefined> {
118
+ // Check if root module is from a dependency (contains :: and doesn't start with "package")
119
+ if (rootModuleName.includes("::")) {
120
+ const packageName = rootModuleName.split("::")[0];
121
+ if (packageName !== "package") {
122
+ const alreadyLoaded = libs.some(lib => lib.name === packageName);
123
+ if (!alreadyLoaded) {
124
+ const depBundle = await loadWeslBundle(packageName, projectDir);
125
+ if (depBundle) {
126
+ return depBundle;
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Load a specific dependency wesl bundle by package name.
135
+ *
136
+ * @param packageName npm package name (e.g., "random_wgsl" or "foo/bar")
137
+ * @param projectDir directory containing package.json
138
+ */
139
+ async function loadWeslBundle(
140
+ packageName: string,
141
+ projectDir: string,
142
+ ): Promise<WeslBundle | undefined> {
143
+ const projectDirAbs = path.resolve(path.join(projectDir, "dummy.js"));
144
+ const projectURL = pathToFileURL(projectDirAbs).href;
145
+
146
+ try {
147
+ const url = resolve(packageName, projectURL);
148
+ const module = await import(url);
149
+ return module.default;
150
+ } catch {
151
+ return undefined;
152
+ }
153
+ }
package/src/main.ts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { hideBin } from "yargs/helpers";
3
+ import { cli } from "./LinkCli.ts";
4
+
5
+ const rawArgs = hideBin(process.argv);
6
+
7
+ cli(rawArgs);
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />