wesl-packager 0.6.15 → 0.6.17
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/bin/wesl-packager +104 -56
- package/package.json +2 -2
package/bin/wesl-packager
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
import { builtinModules } from "node:module";
|
|
3
3
|
import process$1, { exit } from "node:process";
|
|
4
4
|
import { hideBin } from "yargs/helpers";
|
|
5
|
-
import
|
|
5
|
+
import * as actualFS from "node:fs";
|
|
6
|
+
import fs, { realpathSync, statSync } from "node:fs";
|
|
7
|
+
import { RecordResolver, WeslParseError, bindIdentsRecursive, filterMap, findValidRootDecls, minimalMangle, noSuffix } from "wesl";
|
|
8
|
+
import fs$1, { lstat, mkdir, readdir, readlink, realpath } from "node:fs/promises";
|
|
6
9
|
import path, { posix, win32 } from "node:path";
|
|
7
10
|
import { URL as URL$1, fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
-
import { lstatSync, readdir as readdir$1, readdirSync, readlinkSync, realpathSync } from "fs";
|
|
9
|
-
import * as actualFS from "node:fs";
|
|
10
|
-
import fs$1, { realpathSync as realpathSync$1, statSync } from "node:fs";
|
|
11
|
+
import { lstatSync, readdir as readdir$1, readdirSync, readlinkSync, realpathSync as realpathSync$1 } from "fs";
|
|
11
12
|
import { EventEmitter } from "node:events";
|
|
12
13
|
import Stream from "node:stream";
|
|
13
14
|
import { StringDecoder } from "node:string_decoder";
|
|
14
15
|
import assert from "node:assert";
|
|
15
16
|
import v8 from "node:v8";
|
|
16
17
|
import { format, inspect } from "node:util";
|
|
17
|
-
import { WeslParseError, filterMap, findUnboundIdents, noSuffix, parseIntoRegistry, parsedRegistry } from "wesl";
|
|
18
18
|
import yargs from "yargs";
|
|
19
19
|
import { Biome, Distribution } from "@biomejs/js-api";
|
|
20
20
|
|
|
@@ -43,6 +43,41 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
43
43
|
enumerable: true
|
|
44
44
|
}) : target, mod));
|
|
45
45
|
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region ../wesl-tooling/src/FindUnboundIdents.ts
|
|
48
|
+
/**
|
|
49
|
+
* Find unbound package references in library sources.
|
|
50
|
+
*
|
|
51
|
+
* Binds local references without following cross-package imports, revealing
|
|
52
|
+
* which external packages are referenced but not resolved.
|
|
53
|
+
*
|
|
54
|
+
* @param resolver - Module resolver that supports batch operations
|
|
55
|
+
* @returns Array of unbound module paths, each as an array of path segments
|
|
56
|
+
* (e.g., [['foo', 'bar', 'baz'], ['other', 'pkg']])
|
|
57
|
+
*/
|
|
58
|
+
function findUnboundIdents(resolver) {
|
|
59
|
+
const bindContext = {
|
|
60
|
+
resolver,
|
|
61
|
+
conditions: {},
|
|
62
|
+
knownDecls: /* @__PURE__ */ new Set(),
|
|
63
|
+
foundScopes: /* @__PURE__ */ new Set(),
|
|
64
|
+
globalNames: /* @__PURE__ */ new Set(),
|
|
65
|
+
globalStatements: /* @__PURE__ */ new Map(),
|
|
66
|
+
mangler: minimalMangle,
|
|
67
|
+
unbound: [],
|
|
68
|
+
dontFollowDecls: true
|
|
69
|
+
};
|
|
70
|
+
for (const [_modulePath, ast] of resolver.allModules()) {
|
|
71
|
+
const declEntries = findValidRootDecls(ast.rootScope, {}).map((d) => [d.originalName, d]);
|
|
72
|
+
const liveDecls = {
|
|
73
|
+
decls: new Map(declEntries),
|
|
74
|
+
parent: null
|
|
75
|
+
};
|
|
76
|
+
bindIdentsRecursive(ast.rootScope, bindContext, liveDecls, true);
|
|
77
|
+
}
|
|
78
|
+
return bindContext.unbound;
|
|
79
|
+
}
|
|
80
|
+
|
|
46
81
|
//#endregion
|
|
47
82
|
//#region ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
48
83
|
const balanced = (a, b, str) => {
|
|
@@ -3327,7 +3362,7 @@ while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length);
|
|
|
3327
3362
|
|
|
3328
3363
|
//#endregion
|
|
3329
3364
|
//#region ../../node_modules/.pnpm/path-scurry@2.0.0/node_modules/path-scurry/dist/esm/index.js
|
|
3330
|
-
const realpathSync$2 = realpathSync.native;
|
|
3365
|
+
const realpathSync$2 = realpathSync$1.native;
|
|
3331
3366
|
const defaultFS = {
|
|
3332
3367
|
lstatSync,
|
|
3333
3368
|
readdir: readdir$1,
|
|
@@ -9632,16 +9667,17 @@ var require_toml = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/toml@3
|
|
|
9632
9667
|
var import_toml = /* @__PURE__ */ __toESM(require_toml(), 1);
|
|
9633
9668
|
/** Default configuration when no wesl.toml is found */
|
|
9634
9669
|
const defaultWeslToml = {
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9670
|
+
edition: "unstable_2025",
|
|
9671
|
+
include: ["shaders/**/*.w[eg]sl"],
|
|
9672
|
+
root: "shaders",
|
|
9673
|
+
dependencies: "auto"
|
|
9638
9674
|
};
|
|
9639
9675
|
/**
|
|
9640
9676
|
* Load and parse a wesl.toml file from the fs.
|
|
9641
9677
|
* Provide default values for any required WeslToml fields.
|
|
9642
9678
|
*/
|
|
9643
9679
|
async function loadWeslToml(tomlFile) {
|
|
9644
|
-
const tomlString = await fs.readFile(tomlFile, "utf-8");
|
|
9680
|
+
const tomlString = await fs$1.readFile(tomlFile, "utf-8");
|
|
9645
9681
|
const parsed = import_toml.default.parse(tomlString);
|
|
9646
9682
|
return {
|
|
9647
9683
|
...defaultWeslToml,
|
|
@@ -9658,11 +9694,11 @@ async function loadWeslToml(tomlFile) {
|
|
|
9658
9694
|
async function findWeslToml(projectDir, specifiedToml) {
|
|
9659
9695
|
let tomlFile;
|
|
9660
9696
|
if (specifiedToml) {
|
|
9661
|
-
await fs.access(specifiedToml);
|
|
9697
|
+
await fs$1.access(specifiedToml);
|
|
9662
9698
|
tomlFile = specifiedToml;
|
|
9663
9699
|
} else {
|
|
9664
9700
|
const tomlPath = path.join(projectDir, "wesl.toml");
|
|
9665
|
-
tomlFile = await fs.access(tomlPath).then(() => tomlPath).catch(() => {});
|
|
9701
|
+
tomlFile = await fs$1.access(tomlPath).then(() => tomlPath).catch(() => {});
|
|
9666
9702
|
}
|
|
9667
9703
|
let parsedToml;
|
|
9668
9704
|
let tomlDir;
|
|
@@ -9673,13 +9709,13 @@ async function findWeslToml(projectDir, specifiedToml) {
|
|
|
9673
9709
|
parsedToml = defaultWeslToml;
|
|
9674
9710
|
tomlDir = projectDir;
|
|
9675
9711
|
}
|
|
9676
|
-
const tomlToWeslRoot = path.resolve(tomlDir, parsedToml.
|
|
9712
|
+
const tomlToWeslRoot = path.resolve(tomlDir, parsedToml.root);
|
|
9677
9713
|
const projectDirAbs = path.resolve(projectDir);
|
|
9678
|
-
const
|
|
9714
|
+
const resolvedRoot = path.relative(projectDirAbs, tomlToWeslRoot);
|
|
9679
9715
|
return {
|
|
9680
9716
|
tomlFile,
|
|
9681
9717
|
tomlDir,
|
|
9682
|
-
|
|
9718
|
+
resolvedRoot,
|
|
9683
9719
|
toml: parsedToml
|
|
9684
9720
|
};
|
|
9685
9721
|
}
|
|
@@ -9702,8 +9738,8 @@ async function loadModules(projectDir, baseDir, srcGlob) {
|
|
|
9702
9738
|
let resolvedSrcGlob;
|
|
9703
9739
|
if (!baseDir || !srcGlob) {
|
|
9704
9740
|
const tomlInfo = await findWeslToml(projectDir);
|
|
9705
|
-
resolvedBaseDir = baseDir ?? tomlInfo.
|
|
9706
|
-
resolvedSrcGlob = srcGlob ?? tomlInfo.toml.
|
|
9741
|
+
resolvedBaseDir = baseDir ?? tomlInfo.resolvedRoot;
|
|
9742
|
+
resolvedSrcGlob = srcGlob ?? tomlInfo.toml.include[0];
|
|
9707
9743
|
} else {
|
|
9708
9744
|
resolvedBaseDir = baseDir;
|
|
9709
9745
|
resolvedSrcGlob = srcGlob;
|
|
@@ -9712,7 +9748,7 @@ async function loadModules(projectDir, baseDir, srcGlob) {
|
|
|
9712
9748
|
cwd: projectDir,
|
|
9713
9749
|
ignore: "node_modules/**"
|
|
9714
9750
|
})).map((f) => path.resolve(projectDir, f));
|
|
9715
|
-
const promisedSrcs = shaderFiles.map((f) => fs.readFile(f, { encoding: "utf8" }));
|
|
9751
|
+
const promisedSrcs = shaderFiles.map((f) => fs$1.readFile(f, { encoding: "utf8" }));
|
|
9716
9752
|
const src = await Promise.all(promisedSrcs);
|
|
9717
9753
|
if (src.length === 0) throw new Error(`no WGSL/WESL files found in ${resolvedSrcGlob}`);
|
|
9718
9754
|
const baseDirAbs = path.resolve(projectDir, resolvedBaseDir);
|
|
@@ -10064,7 +10100,7 @@ function read(jsonPath, { base, specifier }) {
|
|
|
10064
10100
|
/** @type {string | undefined} */
|
|
10065
10101
|
let string;
|
|
10066
10102
|
try {
|
|
10067
|
-
string = fs
|
|
10103
|
+
string = fs.readFileSync(path.toNamespacedPath(jsonPath), "utf8");
|
|
10068
10104
|
} catch (error) {
|
|
10069
10105
|
const exception = error;
|
|
10070
10106
|
if (exception.code !== "ENOENT") throw exception;
|
|
@@ -10410,7 +10446,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
|
|
|
10410
10446
|
throw error;
|
|
10411
10447
|
}
|
|
10412
10448
|
if (!preserveSymlinks) {
|
|
10413
|
-
const real = realpathSync
|
|
10449
|
+
const real = realpathSync(filePath);
|
|
10414
10450
|
const { search, hash } = resolved;
|
|
10415
10451
|
resolved = pathToFileURL(real + (filePath.endsWith(path.sep) ? "/" : ""));
|
|
10416
10452
|
resolved.search = search;
|
|
@@ -10948,48 +10984,48 @@ function resolve(specifier, parent) {
|
|
|
10948
10984
|
//#endregion
|
|
10949
10985
|
//#region ../wesl-tooling/src/ParseDependencies.ts
|
|
10950
10986
|
/**
|
|
10951
|
-
* Find
|
|
10952
|
-
*
|
|
10987
|
+
* Find package dependencies in WESL source files.
|
|
10988
|
+
*
|
|
10989
|
+
* Parses sources and partially binds identifiers to reveal unresolved package
|
|
10990
|
+
* references. Returns the longest resolvable npm subpath for each dependency.
|
|
10953
10991
|
*
|
|
10954
|
-
*
|
|
10955
|
-
*
|
|
10956
|
-
*
|
|
10992
|
+
* For example, 'foo::bar::baz' could resolve to:
|
|
10993
|
+
* - 'foo/bar' (package foo, export './bar' bundle)
|
|
10994
|
+
* - 'foo' (package foo, default export)
|
|
10957
10995
|
*
|
|
10958
|
-
*
|
|
10959
|
-
*
|
|
10960
|
-
*
|
|
10961
|
-
* . package foo, export './bar' bundle, element baz
|
|
10962
|
-
* . package foo, export './bar/baz' bundle, module lib.wesl, element baz
|
|
10963
|
-
* To distinguish these, we node resolve the longest path we can.
|
|
10996
|
+
* @param weslSrc - Record of WESL source files by path
|
|
10997
|
+
* @param projectDir - Project directory for resolving package imports
|
|
10998
|
+
* @returns Dependency paths in npm format (e.g., 'foo/bar', 'foo')
|
|
10964
10999
|
*/
|
|
10965
11000
|
function parseDependencies(weslSrc, projectDir) {
|
|
10966
|
-
|
|
11001
|
+
let resolver;
|
|
10967
11002
|
try {
|
|
10968
|
-
|
|
11003
|
+
resolver = new RecordResolver(weslSrc);
|
|
10969
11004
|
} catch (e) {
|
|
10970
|
-
if (e.cause instanceof WeslParseError)
|
|
10971
|
-
|
|
11005
|
+
if (e.cause instanceof WeslParseError) {
|
|
11006
|
+
console.error(e.message, "\n");
|
|
11007
|
+
return [];
|
|
11008
|
+
}
|
|
11009
|
+
throw e;
|
|
10972
11010
|
}
|
|
10973
|
-
const unbound = findUnboundIdents(
|
|
11011
|
+
const unbound = findUnboundIdents(resolver);
|
|
10974
11012
|
if (!unbound) return [];
|
|
10975
11013
|
const pkgRefs = unbound.filter((modulePath) => modulePath.length > 1 && modulePath[0] !== "constants");
|
|
10976
11014
|
if (pkgRefs.length === 0) return [];
|
|
10977
|
-
const projectURL =
|
|
11015
|
+
const projectURL = projectDirURL(projectDir);
|
|
10978
11016
|
const deps = filterMap(pkgRefs, (mPath) => unboundToDependency(mPath, projectURL));
|
|
10979
11017
|
return [...new Set(deps)];
|
|
10980
11018
|
}
|
|
10981
|
-
/**
|
|
10982
|
-
* Find the longest resolvable npm subpath from a module path.
|
|
11019
|
+
/** Find longest resolvable npm subpath from module path segments.
|
|
10983
11020
|
*
|
|
10984
|
-
* @param mPath
|
|
10985
|
-
* @param importerURL URL
|
|
10986
|
-
* @returns
|
|
11021
|
+
* @param mPath - Module path segments (e.g., ['foo', 'bar', 'baz', 'elem'])
|
|
11022
|
+
* @param importerURL - Base URL for resolution (e.g., 'file:///path/to/project/')
|
|
11023
|
+
* @returns Longest resolvable subpath (e.g., 'foo/bar/baz' or 'foo')
|
|
10987
11024
|
*/
|
|
10988
11025
|
function unboundToDependency(mPath, importerURL) {
|
|
10989
11026
|
return [...exportSubpaths(mPath)].find((subPath) => tryResolve(subPath, importerURL));
|
|
10990
11027
|
}
|
|
10991
|
-
/** Try
|
|
10992
|
-
* @return the resolved path */
|
|
11028
|
+
/** Try Node.js module resolution; returns undefined if unresolvable. */
|
|
10993
11029
|
function tryResolve(path$2, importerURL) {
|
|
10994
11030
|
try {
|
|
10995
11031
|
return resolve(path$2, importerURL);
|
|
@@ -10997,23 +11033,34 @@ function tryResolve(path$2, importerURL) {
|
|
|
10997
11033
|
return;
|
|
10998
11034
|
}
|
|
10999
11035
|
}
|
|
11000
|
-
/**
|
|
11001
|
-
*
|
|
11002
|
-
* longest subpath first.
|
|
11003
|
-
*/
|
|
11036
|
+
/** Yield possible export subpaths from module path, longest first.
|
|
11037
|
+
* Drops the last segment (element name) and iterates down. */
|
|
11004
11038
|
function* exportSubpaths(mPath) {
|
|
11005
11039
|
const longest = mPath.length - 1;
|
|
11006
11040
|
for (let i = longest; i >= 0; i--) yield mPath.slice(0, i).join("/");
|
|
11007
11041
|
}
|
|
11042
|
+
/** Normalize project directory to file:// URL with trailing slash. */
|
|
11043
|
+
function projectDirURL(projectDir) {
|
|
11044
|
+
if (projectDir.startsWith("file://")) return projectDir.endsWith("/") ? projectDir : `${projectDir}/`;
|
|
11045
|
+
const fileUrl = pathToFileURL(projectDir).href;
|
|
11046
|
+
return fileUrl.endsWith("/") ? fileUrl : `${fileUrl}/`;
|
|
11047
|
+
}
|
|
11008
11048
|
|
|
11009
11049
|
//#endregion
|
|
11010
11050
|
//#region ../wesl-tooling/src/Version.ts
|
|
11051
|
+
/** Read package.json from a directory.
|
|
11052
|
+
* @param projectDir - file:// URL string to directory containing package.json
|
|
11053
|
+
* @returns the parsed package.json contents */
|
|
11054
|
+
async function readPackageJson(projectDir) {
|
|
11055
|
+
const baseUrl = projectDir.endsWith("/") ? projectDir : `${projectDir}/`;
|
|
11056
|
+
return (await import(new URL("package.json", baseUrl).href, { with: { type: "json" } })).default;
|
|
11057
|
+
}
|
|
11011
11058
|
/**
|
|
11012
|
-
* @param projectDir -
|
|
11059
|
+
* @param projectDir - file:// URL string to directory containing package.json
|
|
11013
11060
|
* @returns the 'version' field from the package.json in the `projectDir`
|
|
11014
11061
|
*/
|
|
11015
11062
|
async function versionFromPackageJson(projectDir) {
|
|
11016
|
-
return (await
|
|
11063
|
+
return (await readPackageJson(projectDir)).version;
|
|
11017
11064
|
}
|
|
11018
11065
|
|
|
11019
11066
|
//#endregion
|
|
@@ -11044,7 +11091,7 @@ async function packageWgsl(args) {
|
|
|
11044
11091
|
/** add an 'exports' entry to package.json for the wesl bundles */
|
|
11045
11092
|
async function updatePackageJson(projectDir, outDir, multiBundle) {
|
|
11046
11093
|
const pkgJsonPath = path.join(projectDir, "package.json");
|
|
11047
|
-
const pkgJsonString = await fs.readFile(pkgJsonPath, { encoding: "utf8" });
|
|
11094
|
+
const pkgJsonString = await fs$1.readFile(pkgJsonPath, { encoding: "utf8" });
|
|
11048
11095
|
const pkgJson = JSON.parse(pkgJsonString);
|
|
11049
11096
|
const exports = {};
|
|
11050
11097
|
const distDir = path.relative(projectDir, outDir);
|
|
@@ -11058,7 +11105,7 @@ async function updatePackageJson(projectDir, outDir, multiBundle) {
|
|
|
11058
11105
|
};
|
|
11059
11106
|
const newPkgJson = insertExports(pkgJson, exports);
|
|
11060
11107
|
const jsonString = JSON.stringify(newPkgJson, null, 2).concat("\n");
|
|
11061
|
-
await fs.writeFile(pkgJsonPath, jsonString);
|
|
11108
|
+
await fs$1.writeFile(pkgJsonPath, jsonString);
|
|
11062
11109
|
}
|
|
11063
11110
|
/** insert the exports field into the package.json */
|
|
11064
11111
|
function insertExports(pkgJson, exports) {
|
|
@@ -11109,7 +11156,7 @@ async function writeJsBundle(weslBundle, dependencies, outDir) {
|
|
|
11109
11156
|
`;
|
|
11110
11157
|
const outPath = path.join(outDir, "weslBundle.js");
|
|
11111
11158
|
const formatted = biome.formatContent(biomeKey, outString, { filePath: "b.js" });
|
|
11112
|
-
await fs.writeFile(outPath, formatted.content);
|
|
11159
|
+
await fs$1.writeFile(outPath, formatted.content);
|
|
11113
11160
|
}
|
|
11114
11161
|
/** Write weslBundle.d.ts containing the type definitions for a WeslBundle */
|
|
11115
11162
|
async function writeTypeScriptDts(outDir) {
|
|
@@ -11119,7 +11166,7 @@ async function writeTypeScriptDts(outDir) {
|
|
|
11119
11166
|
`;
|
|
11120
11167
|
const formatted = biome.formatContent(biomeKey, declText, { filePath: "t.d.ts" });
|
|
11121
11168
|
const outPath = path.join(outDir, "weslBundle.d.ts");
|
|
11122
|
-
await fs.writeFile(outPath, formatted.content);
|
|
11169
|
+
await fs$1.writeFile(outPath, formatted.content);
|
|
11123
11170
|
}
|
|
11124
11171
|
/** @return the bundle plus dependencies as a JavaScript string */
|
|
11125
11172
|
function bundleToJsString(bundle, dependencies) {
|
|
@@ -11139,7 +11186,7 @@ function bundleToJsString(bundle, dependencies) {
|
|
|
11139
11186
|
/** parse and extract fields from package.json that we care about
|
|
11140
11187
|
* (the name of the package) */
|
|
11141
11188
|
async function loadPackageFields(pkgJsonPath) {
|
|
11142
|
-
const pkgJsonString = await fs.readFile(pkgJsonPath, { encoding: "utf8" });
|
|
11189
|
+
const pkgJsonString = await fs$1.readFile(pkgJsonPath, { encoding: "utf8" });
|
|
11143
11190
|
const { name } = JSON.parse(pkgJsonString);
|
|
11144
11191
|
verifyField("name", name);
|
|
11145
11192
|
function verifyField(field, value) {
|
|
@@ -11174,7 +11221,8 @@ async function packagerCli(rawArgs$1) {
|
|
|
11174
11221
|
await packageWgsl(cliArgs);
|
|
11175
11222
|
}
|
|
11176
11223
|
async function parseArgs(args) {
|
|
11177
|
-
const
|
|
11224
|
+
const projectDir = new URL("..", import.meta.url).href;
|
|
11225
|
+
const appVersion = await versionFromPackageJson(projectDir);
|
|
11178
11226
|
return yargs(args).command("$0", "create an npm package from WGSL/WESL files").version(appVersion).option("src", {
|
|
11179
11227
|
type: "string",
|
|
11180
11228
|
describe: "WGSL/WESL files to bundle in the package (glob syntax, defaults to wesl.toml or shaders/**/*.w[eg]sl)"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wesl-packager",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": "bin/wesl-packager",
|
|
6
6
|
"files": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"@biomejs/js-api": "^1.0.0",
|
|
11
11
|
"@biomejs/wasm-nodejs": "^2.0.6",
|
|
12
12
|
"yargs": "^18.0.0",
|
|
13
|
-
"wesl": "0.6.
|
|
13
|
+
"wesl": "0.6.17"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"dependent_package": "x",
|