wesl 0.7.21 → 0.7.23

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/dist/index.js CHANGED
@@ -334,8 +334,8 @@ function throwClickableError(params) {
334
334
  }
335
335
  }
336
336
  /** Warn the user about an identifier and throw a clickable exception */
337
- function failIdent(ident$1, msg) {
338
- const { refIdentElem, originalName } = ident$1;
337
+ function failIdent(ident, msg) {
338
+ const { refIdentElem, originalName } = ident;
339
339
  const baseMessage = msg ?? `'${originalName}'`;
340
340
  if (refIdentElem) failIdentElem(refIdentElem, baseMessage);
341
341
  else throw new Error(baseMessage);
@@ -504,11 +504,78 @@ function childIdent(child) {
504
504
  }
505
505
 
506
506
  //#endregion
507
- //#region src/LowerAndEmit.ts
508
- /** Valid WGSL standard attributes (from spec). Non-WGSL attributes are stripped.
509
- * See: https://www.w3.org/TR/WGSL/#attributes
510
- * Note: @builtin, @diagnostic, @interpolate are parsed as separate attribute types. */
511
- const wgslStandardAttributes$1 = new Set([
507
+ //#region src/StandardTypes.ts
508
+ const stdFns = `bitcast all any select arrayLength
509
+ abs acos acosh asin asinh atan atanh atan2 ceil clamp cos cosh
510
+ countLeadingZeros countOneBits countTrailingZeros cross
511
+ degrees determinant distance dot dot4U8Packed dot4I8Packed
512
+ exp exp2 extractBits faceForward firstLeadingBit firstTrailingBit
513
+ floor fma fract frexp insertBits inverseSqrt ldexp length log log2
514
+ max min mix modf normalize pow quantizeToF16 radians reflect refract
515
+ reverseBits round saturate sign sin sinh smoothstep sqrt step tan tanh
516
+ transpose trunc
517
+ dpdx dpdxCoarse dpdxFine dpdy dpdyCoarse dpdyFine fwidth
518
+ fwidthCoarse fwidthFine
519
+ textureDimensions textureGather textureGatherCompare textureLoad
520
+ textureNumLayers textureNumLevels textureNumSamples
521
+ textureSample textureSampleBias textureSampleCompare textureSampleCompareLevel
522
+ textureSampleGrad textureSampleLevel textureSampleBaseClampToEdge
523
+ textureStore
524
+ atomicLoad atomicStore atomicAdd atomicSub atomicMax atomicMin
525
+ atomicAnd atomicOr atomicXor atomicExchange atomicCompareExchangeWeak
526
+ pack4x8snorm pack4x8unorm pack4xI8 pack4xU8 pack4xI8Clamp pack4xU8Clamp
527
+ pack2x16snorm pack2x16unorm pack2x16float
528
+ unpack4x8snorm unpack4x8unorm unpack4xI8 unpack4xU8
529
+ unpack2x16snorm unpack2x16unorm unpack2x16float
530
+ storageBarrier textureBarrier workgroupBarrier workgroupUniformLoad
531
+ subgroupAdd subgroupAll subgroupAnd subgroupAny subgroupBallot
532
+ subgroupBroadcast subgroupBroadcastFirst subgroupElect
533
+ subgroupExclusiveAdd subgroupExclusiveMul subgroupInclusiveAdd
534
+ subgroupInclusiveMul subgroupMax subgroupMin subgroupMul subgroupOr
535
+ subgroupShuffle subgroupShuffleUp subgroupShuffleXor subgroupXor
536
+ quadBroadcast quadSwapDiagonal quadSwapX quadSwapY`.split(/\s+/);
537
+ const sampledTextureTypes = `
538
+ texture_1d texture_2d texture_2d_array texture_3d
539
+ texture_cube texture_cube_array
540
+ `;
541
+ const multisampledTextureTypes = `
542
+ texture_multisampled_2d texture_depth_multisampled_2d
543
+ `;
544
+ const textureStorageTypes = `
545
+ texture_storage_1d texture_storage_2d texture_storage_2d_array
546
+ texture_storage_3d
547
+ `;
548
+ const stdTypes = `array atomic bool f16 f32 i32
549
+ mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4
550
+ mat2x2f mat2x3f mat2x4f mat3x2f mat3x3f mat3x4f
551
+ mat4x2f mat4x3f mat4x4f
552
+ mat2x2h mat2x3h mat2x4h mat3x2h mat3x3h mat3x4h
553
+ mat4x2h mat4x3h mat4x4h
554
+ u32 vec2 vec3 vec4 ptr
555
+ vec2i vec3i vec4i vec2u vec3u vec4u
556
+ vec2f vec3f vec4f vec2h vec3h vec4h
557
+ ${sampledTextureTypes}
558
+ ${multisampledTextureTypes}
559
+ texture_external
560
+ ${textureStorageTypes}
561
+ texture_depth_2d texture_depth_2d_array texture_depth_cube
562
+ texture_depth_cube_array
563
+ sampler sampler_comparison
564
+ rgba8unorm rgba8snorm rgba8uint rgba8sint
565
+ rgba16uint rgba16sint rgba16float
566
+ r32uint r32sint r32float rg32uint rg32sint rg32float
567
+ rgba32uint rgba32sint rgba32float
568
+ bgra8unorm`.split(/\s+/);
569
+ /** https://www.w3.org/TR/WGSL/#predeclared-enumerants */
570
+ const stdEnumerants = `read write read_write
571
+ function private workgroup uniform storage
572
+ rgba8unorm rgba8snorm rgba8uint rgba8sint
573
+ rgba16uint rgba16sint rgba16float
574
+ r32uint r32sint r32float rg32uint rg32sint rg32float
575
+ rgba32uint rgba32sint rgba32float bgra8unorm`.split(/\s+/);
576
+ /** WGSL standard attributes whose params need binding (e.g., @workgroup_size).
577
+ * See: https://www.w3.org/TR/WGSL/#attributes */
578
+ const wgslStandardAttributes = new Set([
512
579
  "align",
513
580
  "binding",
514
581
  "blend_src",
@@ -524,6 +591,21 @@ const wgslStandardAttributes$1 = new Set([
524
591
  "vertex",
525
592
  "workgroup_size"
526
593
  ]);
594
+ /** return true if the name is for a built in type (not a user struct) */
595
+ function stdType(name) {
596
+ return stdTypes.includes(name);
597
+ }
598
+ /** return true if the name is for a built in fn (not a user function) */
599
+ function stdFn(name) {
600
+ return stdFns.includes(name) || stdType(name);
601
+ }
602
+ /** return true if the name is for a built in enumerant */
603
+ function stdEnumerant(name) {
604
+ return stdEnumerants.includes(name);
605
+ }
606
+
607
+ //#endregion
608
+ //#region src/LowerAndEmit.ts
527
609
  /** Traverse the AST, starting from root elements, emitting WGSL for each. */
528
610
  function lowerAndEmit(params) {
529
611
  const { srcBuilder, rootElems, conditions } = params;
@@ -717,13 +799,13 @@ function emitContentsWithTrimming(elem, ctx) {
717
799
  const validElements = filterValidElements(elem.contents, ctx.conditions);
718
800
  const firstEmit = validElements.findIndex((e) => !isConditionalAttr(e));
719
801
  const lastEmit = validElements.findLastIndex((e) => !isConditionalAttr(e));
720
- validElements.forEach((elem$1, i) => {
721
- if (elem$1.kind === "text") {
722
- let text = elem$1.srcModule.src.slice(elem$1.start, elem$1.end);
802
+ validElements.forEach((elem, i) => {
803
+ if (elem.kind === "text") {
804
+ let text = elem.srcModule.src.slice(elem.start, elem.end);
723
805
  if (i === firstEmit) text = text.trimStart();
724
806
  if (i === lastEmit) text = text.trimEnd();
725
- if (text) ctx.srcBuilder.add(text, elem$1.start, elem$1.end);
726
- } else lowerAndEmitElem(elem$1, ctx);
807
+ if (text) ctx.srcBuilder.add(text, elem.start, elem.end);
808
+ } else lowerAndEmitElem(elem, ctx);
727
809
  });
728
810
  }
729
811
  function isConditionalAttr(e) {
@@ -803,7 +885,7 @@ function emitAttribute(e, ctx) {
803
885
  const { kind } = e.attribute;
804
886
  if (kind === "@if" || kind === "@elif" || kind === "@else") return false;
805
887
  if (kind === "@attribute") {
806
- if (!wgslStandardAttributes$1.has(e.attribute.name)) return false;
888
+ if (!wgslStandardAttributes.has(e.attribute.name)) return false;
807
889
  emitStandardAttribute(e, ctx);
808
890
  return true;
809
891
  }
@@ -885,13 +967,13 @@ function displayName(declIdent) {
885
967
  return declIdent.mangledName || declIdent.originalName;
886
968
  }
887
969
  /** Trace through refersTo links until we find the declaration. */
888
- function findDecl(ident$1) {
889
- let i = ident$1;
970
+ function findDecl(ident) {
971
+ let i = ident;
890
972
  do {
891
973
  if (i.kind === "decl") return i;
892
974
  i = i.refersTo;
893
975
  } while (i);
894
- throw new Error(`unresolved identifer: ${ident$1.originalName}`);
976
+ throw new Error(`unresolved identifer: ${ident.originalName}`);
895
977
  }
896
978
 
897
979
  //#endregion
@@ -1122,7 +1204,7 @@ function scopeToString(scope, indent = 0, shortIdents = true) {
1122
1204
  if (attrStrings) str.add(attrStrings + " ");
1123
1205
  if (kind === "partial") str.add("-");
1124
1206
  str.add("{ ");
1125
- const last$1 = contents.length - 1;
1207
+ const last = contents.length - 1;
1126
1208
  let lastWasScope = false;
1127
1209
  let hasBlock = false;
1128
1210
  contents.forEach((elem, i) => {
@@ -1135,10 +1217,10 @@ function scopeToString(scope, indent = 0, shortIdents = true) {
1135
1217
  } else {
1136
1218
  if (lastWasScope) str.add(" ");
1137
1219
  lastWasScope = false;
1138
- const ident$1 = elem;
1139
- if (shortIdents) str.add(identShortString(ident$1));
1140
- else str.add(identToString(ident$1));
1141
- if (i < last$1) str.add(" ");
1220
+ const ident = elem;
1221
+ if (shortIdents) str.add(identShortString(ident));
1222
+ else str.add(identToString(ident));
1223
+ if (i < last) str.add(" ");
1142
1224
  }
1143
1225
  });
1144
1226
  if (!hasBlock && str.oneLine) str.add(" }");
@@ -1154,17 +1236,17 @@ function scopeToStringLong(scope) {
1154
1236
  return scopeToString(scope, 0, false);
1155
1237
  }
1156
1238
  /** name of an identifier, with decls prefixed with '%' */
1157
- function identShortString(ident$1) {
1158
- const { kind, originalName } = ident$1;
1239
+ function identShortString(ident) {
1240
+ const { kind, originalName } = ident;
1159
1241
  return `${kind === "decl" ? "%" : ""}${originalName}`;
1160
1242
  }
1161
- function identToString(ident$1) {
1162
- if (!ident$1) return JSON.stringify(ident$1);
1163
- const { kind, originalName } = ident$1;
1164
- const idStr = ident$1.id ? `#${ident$1.id}` : "";
1165
- if (kind === "ref") return `${originalName} ${idStr} -> ${identToString(ident$1.refersTo)}`;
1243
+ function identToString(ident) {
1244
+ if (!ident) return JSON.stringify(ident);
1245
+ const { kind, originalName } = ident;
1246
+ const idStr = ident.id ? `#${ident.id}` : "";
1247
+ if (kind === "ref") return `${originalName} ${idStr} -> ${identToString(ident.refersTo)}`;
1166
1248
  else {
1167
- const { mangledName } = ident$1;
1249
+ const { mangledName } = ident;
1168
1250
  return `%${originalName}${mangledName ? `(${mangledName})` : ""} ${idStr} `;
1169
1251
  }
1170
1252
  }
@@ -1655,11 +1737,11 @@ function parseIdent(ctx, conditionRef) {
1655
1737
  const path = parseModulePath(ctx.stream);
1656
1738
  if (!path) return null;
1657
1739
  const { parts, start, end } = path;
1658
- const ident$1 = ctx.createRefIdent(parts.join("::"));
1659
- if (conditionRef) ident$1.conditionRef = true;
1660
- const refIdentElem = makeRefIdentElem(ctx, ident$1, start, end);
1740
+ const ident = ctx.createRefIdent(parts.join("::"));
1741
+ if (conditionRef) ident.conditionRef = true;
1742
+ const refIdentElem = makeRefIdentElem(ctx, ident, start, end);
1661
1743
  if (!conditionRef) {
1662
- ctx.saveIdent(ident$1);
1744
+ ctx.saveIdent(ident);
1663
1745
  ctx.addElem(refIdentElem);
1664
1746
  }
1665
1747
  return refIdentElem;
@@ -2202,8 +2284,8 @@ function parseElseChain(ctx) {
2202
2284
  while (stream.matchText("else")) {
2203
2285
  if (stream.matchText("if")) {
2204
2286
  expectExpression(ctx, "Expected expression after 'else if'");
2205
- const body$1 = expectCompound(ctx, "Expected '{' after else if");
2206
- ctx.addElem(body$1);
2287
+ const body = expectCompound(ctx, "Expected '{' after else if");
2288
+ ctx.addElem(body);
2207
2289
  continue;
2208
2290
  }
2209
2291
  const body = expectCompound(ctx, "Expected '{' after else");
@@ -3162,8 +3244,8 @@ var ParsingContext = class {
3162
3244
  declElem: null
3163
3245
  };
3164
3246
  }
3165
- saveIdent(ident$1) {
3166
- this.state.context.scope.contents.push(ident$1);
3247
+ saveIdent(ident) {
3248
+ this.state.context.scope.contents.push(ident);
3167
3249
  }
3168
3250
  };
3169
3251
 
@@ -3252,7 +3334,7 @@ function toRegexSource(nameExp) {
3252
3334
  }
3253
3335
  }
3254
3336
  function verifyNonCapturing(name, exp) {
3255
- if ((/* @__PURE__ */ new RegExp("|" + exp.source)).exec("").length > 1) throw new Error(`match expression groups must be non-capturing: ${name}: /${exp.source}/. Use (?:...) instead.`);
3337
+ if (new RegExp("|" + exp.source).exec("").length > 1) throw new Error(`match expression groups must be non-capturing: ${name}: /${exp.source}/. Use (?:...) instead.`);
3256
3338
  }
3257
3339
  const regexSpecials = /[$+*.?|(){}[\]\\/^]/g;
3258
3340
  function escapeRegex(s) {
@@ -3595,115 +3677,16 @@ function flatImports(ast, conditions) {
3595
3677
  return flat;
3596
3678
  }
3597
3679
 
3598
- //#endregion
3599
- //#region src/StandardTypes.ts
3600
- const stdFns = `bitcast all any select arrayLength
3601
- abs acos acosh asin asinh atan atanh atan2 ceil clamp cos cosh
3602
- countLeadingZeros countOneBits countTrailingZeros cross
3603
- degrees determinant distance dot dot4U8Packed dot4I8Packed
3604
- exp exp2 extractBits faceForward firstLeadingBit firstTrailingBit
3605
- floor fma fract frexp insertBits inverseSqrt ldexp length log log2
3606
- max min mix modf normalize pow quantizeToF16 radians reflect refract
3607
- reverseBits round saturate sign sin sinh smoothstep sqrt step tan tanh
3608
- transpose trunc
3609
- dpdx dpdxCoarse dpdxFine dpdy dpdyCoarse dpdyFine fwidth
3610
- fwidthCoarse fwidthFine
3611
- textureDimensions textureGather textureGatherCompare textureLoad
3612
- textureNumLayers textureNumLevels textureNumSamples
3613
- textureSample textureSampleBias textureSampleCompare textureSampleCompareLevel
3614
- textureSampleGrad textureSampleLevel textureSampleBaseClampToEdge
3615
- textureStore
3616
- atomicLoad atomicStore atomicAdd atomicSub atomicMax atomicMin
3617
- atomicAnd atomicOr atomicXor atomicExchange atomicCompareExchangeWeak
3618
- pack4x8snorm pack4x8unorm pack4xI8 pack4xU8 pack4xI8Clamp pack4xU8Clamp
3619
- pack2x16snorm pack2x16unorm pack2x16float
3620
- unpack4x8snorm unpack4x8unorm unpack4xI8 unpack4xU8
3621
- unpack2x16snorm unpack2x16unorm unpack2x16float
3622
- storageBarrier textureBarrier workgroupBarrier workgroupUniformLoad
3623
- subgroupAdd subgroupAll subgroupAnd subgroupAny subgroupBallot
3624
- subgroupBroadcast subgroupBroadcastFirst subgroupElect
3625
- subgroupExclusiveAdd subgroupExclusiveMul subgroupInclusiveAdd
3626
- subgroupInclusiveMul subgroupMax subgroupMin subgroupMul subgroupOr
3627
- subgroupShuffle subgroupShuffleUp subgroupShuffleXor subgroupXor
3628
- quadBroadcast quadSwapDiagonal quadSwapX quadSwapY`.split(/\s+/);
3629
- const sampledTextureTypes = `
3630
- texture_1d texture_2d texture_2d_array texture_3d
3631
- texture_cube texture_cube_array
3632
- `;
3633
- const multisampledTextureTypes = `
3634
- texture_multisampled_2d texture_depth_multisampled_2d
3635
- `;
3636
- const textureStorageTypes = `
3637
- texture_storage_1d texture_storage_2d texture_storage_2d_array
3638
- texture_storage_3d
3639
- `;
3640
- const stdTypes = `array atomic bool f16 f32 i32
3641
- mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4
3642
- mat2x2f mat2x3f mat2x4f mat3x2f mat3x3f mat3x4f
3643
- mat4x2f mat4x3f mat4x4f
3644
- mat2x2h mat2x3h mat2x4h mat3x2h mat3x3h mat3x4h
3645
- mat4x2h mat4x3h mat4x4h
3646
- u32 vec2 vec3 vec4 ptr
3647
- vec2i vec3i vec4i vec2u vec3u vec4u
3648
- vec2f vec3f vec4f vec2h vec3h vec4h
3649
- ${sampledTextureTypes}
3650
- ${multisampledTextureTypes}
3651
- texture_external
3652
- ${textureStorageTypes}
3653
- texture_depth_2d texture_depth_2d_array texture_depth_cube
3654
- texture_depth_cube_array
3655
- sampler sampler_comparison
3656
- rgba8unorm rgba8snorm rgba8uint rgba8sint
3657
- rgba16uint rgba16sint rgba16float
3658
- r32uint r32sint r32float rg32uint rg32sint rg32float
3659
- rgba32uint rgba32sint rgba32float
3660
- bgra8unorm`.split(/\s+/);
3661
- /** https://www.w3.org/TR/WGSL/#predeclared-enumerants */
3662
- const stdEnumerants = `read write read_write
3663
- function private workgroup uniform storage
3664
- rgba8unorm rgba8snorm rgba8uint rgba8sint
3665
- rgba16uint rgba16sint rgba16float
3666
- r32uint r32sint r32float rg32uint rg32sint rg32float
3667
- rgba32uint rgba32sint rgba32float bgra8unorm`.split(/\s+/);
3668
- /** return true if the name is for a built in type (not a user struct) */
3669
- function stdType(name) {
3670
- return stdTypes.includes(name);
3671
- }
3672
- /** return true if the name is for a built in fn (not a user function) */
3673
- function stdFn(name) {
3674
- return stdFns.includes(name) || stdType(name);
3675
- }
3676
- /** return true if the name is for a built in enumerant */
3677
- function stdEnumerant(name) {
3678
- return stdEnumerants.includes(name);
3679
- }
3680
-
3681
3680
  //#endregion
3682
3681
  //#region src/BindIdents.ts
3683
- /** WGSL standard attributes whose params need binding (e.g., @workgroup_size). */
3684
- const wgslStandardAttributes = new Set([
3685
- "align",
3686
- "binding",
3687
- "blend_src",
3688
- "compute",
3689
- "const",
3690
- "fragment",
3691
- "group",
3692
- "id",
3693
- "invariant",
3694
- "location",
3695
- "must_use",
3696
- "size",
3697
- "vertex",
3698
- "workgroup_size"
3699
- ]);
3700
3682
  /** Bind ref idents to declarations and mangle global declaration names. */
3701
3683
  function bindIdents(params) {
3702
3684
  const { rootAst, resolver, virtuals, accumulateUnbound } = params;
3703
3685
  const { conditions = {}, mangler = minimalMangle } = params;
3686
+ const { discoveryMode } = params;
3704
3687
  const packageName = rootAst.srcModule.modulePath.split("::")[0];
3705
- const validRootDecls = findValidRootDecls(rootAst.rootScope, conditions);
3706
- const { globalNames, knownDecls } = initRootDecls(validRootDecls);
3688
+ const rootDecls = discoveryMode ? findAllRootDecls(rootAst.rootScope) : findValidRootDecls(rootAst.rootScope, conditions);
3689
+ const { globalNames, knownDecls } = initRootDecls(rootDecls);
3707
3690
  const bindContext = {
3708
3691
  resolver,
3709
3692
  conditions,
@@ -3714,13 +3697,14 @@ function bindIdents(params) {
3714
3697
  foundScopes: /* @__PURE__ */ new Set(),
3715
3698
  globalNames,
3716
3699
  globalStatements: /* @__PURE__ */ new Map(),
3717
- unbound: accumulateUnbound ? [] : void 0
3700
+ unbound: accumulateUnbound ? [] : void 0,
3701
+ discoveryMode
3718
3702
  };
3719
3703
  const liveDecls = {
3720
- decls: new Map(validRootDecls.map((d) => [d.originalName, d])),
3704
+ decls: new Map(rootDecls.map((d) => [d.originalName, d])),
3721
3705
  parent: null
3722
3706
  };
3723
- const fromRootDecls = validRootDecls.flatMap((decl) => processDependentScope(decl, bindContext));
3707
+ const fromRootDecls = rootDecls.flatMap((decl) => processDependentScope(decl, bindContext));
3724
3708
  const fromRefs = bindIdentsRecursive(rootAst.rootScope, bindContext, liveDecls);
3725
3709
  const newStatements = [...bindContext.globalStatements.values()];
3726
3710
  return {
@@ -3756,10 +3740,11 @@ function* validItems(scope, conditions) {
3756
3740
  }
3757
3741
  /** Find all conditionally valid declarations at the root level. */
3758
3742
  function findValidRootDecls(rootScope, conditions) {
3759
- const found = [];
3760
- for (const item of validItems(rootScope, conditions)) if (item.kind === "decl") found.push(item);
3761
- else if (item.kind === "partial") collectDecls(item, found);
3762
- return found;
3743
+ return collectDecls(validItems(rootScope, conditions));
3744
+ }
3745
+ /** Find all declarations at the root level, ignoring conditions. */
3746
+ function findAllRootDecls(rootScope) {
3747
+ return collectDecls(rootScope.contents);
3763
3748
  }
3764
3749
  /** Find a public declaration with the given original name. */
3765
3750
  function publicDecl(scope, name, conditions) {
@@ -3785,7 +3770,8 @@ function bindIdentsRecursive(scope, bindContext, liveDecls) {
3785
3770
  function processScope(scope, bindContext, liveDecls) {
3786
3771
  const newGlobals = [];
3787
3772
  const newFromChildren = [];
3788
- for (const child of validItems(scope, bindContext.conditions)) if (child.kind === "decl") liveDecls.decls.set(child.originalName, child);
3773
+ const items = bindContext.discoveryMode ? scope.contents : validItems(scope, bindContext.conditions);
3774
+ for (const child of items) if (child.kind === "decl") liveDecls.decls.set(child.originalName, child);
3789
3775
  else if (child.kind === "ref") {
3790
3776
  const newDecl = handleRef(child, liveDecls, bindContext);
3791
3777
  if (newDecl) newGlobals.push(newDecl);
@@ -3811,25 +3797,26 @@ function processDependentScope(decl, ctx) {
3811
3797
  * Mutates to mangle declarations and mark std references.
3812
3798
  * @return found declaration, or undefined if already processed
3813
3799
  */
3814
- function handleRef(ident$1, liveDecls, bindContext) {
3815
- if (ident$1.refersTo || ident$1.std) return;
3816
- if (ident$1.conditionRef) return;
3817
- if (ident$1.attrParam && !wgslStandardAttributes.has(ident$1.attrParam)) return;
3818
- const foundDecl = findDeclInModule(ident$1, liveDecls) ?? findQualifiedImport(ident$1, bindContext);
3800
+ function handleRef(ident, liveDecls, bindContext) {
3801
+ if (ident.refersTo || ident.std) return;
3802
+ if (ident.conditionRef) return;
3803
+ if (ident.attrParam && !wgslStandardAttributes.has(ident.attrParam)) return;
3804
+ const foundDecl = findDeclInModule(ident, liveDecls) ?? findQualifiedImport(ident, bindContext);
3819
3805
  if (foundDecl) {
3820
- ident$1.refersTo = foundDecl.decl;
3821
- return handleNewDecl(ident$1, foundDecl, bindContext);
3806
+ ident.refersTo = foundDecl.decl;
3807
+ return handleNewDecl(ident, foundDecl, bindContext);
3822
3808
  }
3823
- if (stdWgsl(ident$1.originalName)) {
3824
- ident$1.std = true;
3809
+ if (stdWgsl(ident.originalName)) {
3810
+ ident.std = true;
3825
3811
  return;
3826
3812
  }
3827
- if (!bindContext.unbound) failIdent(ident$1, `unresolved identifier '${ident$1.originalName}'`);
3813
+ if (!bindContext.unbound) failIdent(ident, `unresolved identifier '${ident.originalName}'`);
3828
3814
  }
3815
+ /** Follow new global declarations into their dependent scopes. */
3829
3816
  function handleDecls(newGlobals, bindContext) {
3830
3817
  return newGlobals.flatMap((decl) => processDependentScope(decl, bindContext));
3831
3818
  }
3832
- /** If found declaration is new, mangle its name. Return if it's a global declaration. */
3819
+ /** If found declaration is new, mangle its name. @return the decl if it's global. */
3833
3820
  function handleNewDecl(refIdent, foundDecl, ctx) {
3834
3821
  const { decl, moduleAst } = foundDecl;
3835
3822
  const { knownDecls, globalNames, mangler, globalStatements } = ctx;
@@ -3845,18 +3832,19 @@ function handleNewDecl(refIdent, foundDecl, ctx) {
3845
3832
  return decl;
3846
3833
  }
3847
3834
  /** Search current scope and parent scopes for a matching declaration. */
3848
- function findDeclInModule(ident$1, liveDecls) {
3849
- const found = liveDecls.decls.get(ident$1.originalName);
3835
+ function findDeclInModule(ident, liveDecls) {
3836
+ const found = liveDecls.decls.get(ident.originalName);
3850
3837
  if (found) return {
3851
3838
  decl: found,
3852
- moduleAst: ident$1.ast
3839
+ moduleAst: ident.ast
3853
3840
  };
3854
- if (liveDecls.parent) return findDeclInModule(ident$1, liveDecls.parent);
3841
+ if (liveDecls.parent) return findDeclInModule(ident, liveDecls.parent);
3855
3842
  }
3856
3843
  /** Match a ref ident to a declaration in another module via import or qualified ident. */
3857
3844
  function findQualifiedImport(refIdent, ctx) {
3858
- const { conditions, unbound } = ctx;
3859
- const flatImps = flatImports(refIdent.ast, conditions);
3845
+ const { conditions, unbound, discoveryMode } = ctx;
3846
+ const conds = discoveryMode ? void 0 : conditions;
3847
+ const flatImps = flatImports(refIdent.ast, conds);
3860
3848
  const identParts = refIdent.originalName.split("::");
3861
3849
  const pathParts = matchingImport(identParts, flatImps) ?? qualifiedIdent(identParts);
3862
3850
  if (!pathParts) {
@@ -3910,7 +3898,7 @@ function virtualModule(moduleName, ctx) {
3910
3898
  /** Get cached valid root declarations, computing on first access. */
3911
3899
  function getValidRootDecls(rootScope, conditions) {
3912
3900
  const lexScope = rootScope;
3913
- if (!lexScope._validRootDecls) lexScope._validRootDecls = findValidRootDecls(rootScope, conditions);
3901
+ lexScope._validRootDecls ??= findValidRootDecls(rootScope, conditions);
3914
3902
  return lexScope._validRootDecls;
3915
3903
  }
3916
3904
  /** Given a global declIdent, return the liveDecls for its root scope. */
@@ -3939,13 +3927,167 @@ function setMangledName(proposedName, decl, globalNames, srcModule, mangler) {
3939
3927
  function stdWgsl(name) {
3940
3928
  return stdType(name) || stdFn(name) || stdEnumerant(name);
3941
3929
  }
3930
+ /** @return identParts if it's a qualified path (has ::). */
3942
3931
  function qualifiedIdent(identParts) {
3943
3932
  if (identParts.length > 1) return identParts;
3944
3933
  }
3945
- /** Collect all declarations in a scope (used when scope is already validated). */
3946
- function collectDecls(scope, found) {
3947
- for (const item of scope.contents) if (item.kind === "decl") found.push(item);
3948
- else if (item.kind === "partial") collectDecls(item, found);
3934
+ /** Collect all declarations from scope items, recursing into partial scopes. */
3935
+ function collectDecls(items) {
3936
+ return [...items].flatMap((item) => {
3937
+ const { kind } = item;
3938
+ if (kind === "decl") return [item];
3939
+ if (kind === "partial") return collectDecls(item.contents);
3940
+ return [];
3941
+ });
3942
+ }
3943
+
3944
+ //#endregion
3945
+ //#region src/PathUtil.ts
3946
+ /** simplistic path manipulation utilities */
3947
+ /** return path with ./ and foo/.. elements removed */
3948
+ function normalize(path) {
3949
+ const noDots = path.split("/").filter((s) => s !== ".");
3950
+ const noDbl = [];
3951
+ noDots.forEach((s) => {
3952
+ if (s !== "") if (s === ".." && noDbl.length && noDbl[noDbl.length - 1] !== "..") noDbl.pop();
3953
+ else noDbl.push(s);
3954
+ });
3955
+ return noDbl.join("/");
3956
+ }
3957
+ /** return path w/o a suffix.
3958
+ * e.g. /foo/bar.wgsl => /foo/bar */
3959
+ function noSuffix(path) {
3960
+ const lastSlash = path.lastIndexOf("/");
3961
+ const lastStart = lastSlash === -1 ? 0 : lastSlash + 1;
3962
+ const suffix = path.indexOf(".", lastStart);
3963
+ const suffixStart = suffix === -1 ? path.length : suffix;
3964
+ return path.slice(0, suffixStart);
3965
+ }
3966
+
3967
+ //#endregion
3968
+ //#region src/ModuleResolver.ts
3969
+ const libRegex = /^lib\.w[eg]sl$/i;
3970
+ /** Module resolver for in-memory source records. Lazy by default. */
3971
+ var RecordResolver = class {
3972
+ astCache = /* @__PURE__ */ new Map();
3973
+ sources;
3974
+ packageName;
3975
+ debugWeslRoot;
3976
+ constructor(sources, options = {}) {
3977
+ const { packageName = "package", debugWeslRoot } = options;
3978
+ this.sources = sources;
3979
+ this.packageName = packageName;
3980
+ this.debugWeslRoot = normalizeDebugRoot(debugWeslRoot);
3981
+ }
3982
+ resolveModule(modulePath) {
3983
+ const cached = this.astCache.get(modulePath);
3984
+ if (cached) return cached;
3985
+ const source = this.findSource(modulePath);
3986
+ if (source === void 0) return void 0;
3987
+ const ast = parseSrcModule({
3988
+ modulePath,
3989
+ debugFilePath: this.modulePathToDebugPath(modulePath),
3990
+ src: source
3991
+ });
3992
+ this.astCache.set(modulePath, ast);
3993
+ return ast;
3994
+ }
3995
+ findSource(modulePath) {
3996
+ if (this.sources[modulePath] !== void 0) return this.sources[modulePath];
3997
+ const filePath = this.moduleToFilePath(modulePath);
3998
+ if (filePath === void 0) return void 0;
3999
+ return findInVariants(this.sources, filePath);
4000
+ }
4001
+ /** Convert module path to file path, or undefined if not local. */
4002
+ moduleToFilePath(modulePath) {
4003
+ return moduleToRelativePath(modulePath, this.packageName);
4004
+ }
4005
+ modulePathToDebugPath(modulePath) {
4006
+ const filePath = this.moduleToFilePath(modulePath) ?? modulePath;
4007
+ return this.debugWeslRoot + filePath + ".wesl";
4008
+ }
4009
+ /** Parse all modules and return entries. */
4010
+ allModules() {
4011
+ for (const filePath of Object.keys(this.sources)) {
4012
+ const treatLibAsRoot = this.packageName !== "package";
4013
+ const modulePath = fileToModulePath(filePath, this.packageName, treatLibAsRoot);
4014
+ this.resolveModule(modulePath);
4015
+ }
4016
+ return this.astCache.entries();
4017
+ }
4018
+ };
4019
+ /** Composite resolver that tries each resolver in order until one succeeds. */
4020
+ var CompositeResolver = class {
4021
+ resolvers;
4022
+ constructor(resolvers) {
4023
+ this.resolvers = resolvers;
4024
+ }
4025
+ resolveModule(modulePath) {
4026
+ for (const resolver of this.resolvers) {
4027
+ const ast = resolver.resolveModule(modulePath);
4028
+ if (ast) return ast;
4029
+ }
4030
+ }
4031
+ };
4032
+ /** Lazy resolver for WeslBundle library modules. */
4033
+ var BundleResolver = class {
4034
+ astCache = /* @__PURE__ */ new Map();
4035
+ sources;
4036
+ packageName;
4037
+ debugWeslRoot;
4038
+ constructor(bundle, debugWeslRoot) {
4039
+ this.sources = bundle.modules;
4040
+ this.packageName = bundle.name;
4041
+ this.debugWeslRoot = normalizeDebugRoot(debugWeslRoot);
4042
+ }
4043
+ resolveModule(modulePath) {
4044
+ const pkgPrefix = this.packageName + "::";
4045
+ if (modulePath !== this.packageName && !modulePath.startsWith(pkgPrefix)) return;
4046
+ const cached = this.astCache.get(modulePath);
4047
+ if (cached) return cached;
4048
+ const source = this.findSource(modulePath);
4049
+ if (!source) return void 0;
4050
+ const ast = parseSrcModule({
4051
+ modulePath,
4052
+ debugFilePath: this.modulePathToDebugPath(modulePath),
4053
+ src: source
4054
+ });
4055
+ this.astCache.set(modulePath, ast);
4056
+ return ast;
4057
+ }
4058
+ findSource(modulePath) {
4059
+ const filePath = this.moduleToFilePath(modulePath);
4060
+ if (modulePath === this.packageName) {
4061
+ const libSrc = findInVariants(this.sources, "lib", ["wesl", "wgsl"]);
4062
+ if (libSrc) return libSrc;
4063
+ }
4064
+ return findInVariants(this.sources, filePath);
4065
+ }
4066
+ moduleToFilePath(modulePath) {
4067
+ return moduleToRelativePath(modulePath, this.packageName) ?? modulePath;
4068
+ }
4069
+ modulePathToDebugPath(modulePath) {
4070
+ const filePath = this.moduleToFilePath(modulePath);
4071
+ return this.debugWeslRoot + this.packageName + "/" + filePath + ".wesl";
4072
+ }
4073
+ };
4074
+ /** Convert file path to module path (e.g., "foo/bar.wesl" to "package::foo::bar"). */
4075
+ function fileToModulePath(filePath, packageName, treatLibAsRoot) {
4076
+ if (filePath.includes("::")) return filePath;
4077
+ if (treatLibAsRoot && libRegex.test(filePath)) return packageName;
4078
+ const moduleSuffix = noSuffix(normalize(filePath)).replaceAll("/", "::");
4079
+ return packageName + "::" + moduleSuffix;
4080
+ }
4081
+ /** Try path variants with/without ./ prefix and extension suffixes. */
4082
+ function findInVariants(sources, basePath, extensions = ["wesl", "wgsl"]) {
4083
+ for (const prefix of ["", "./"]) {
4084
+ const path = prefix + basePath;
4085
+ if (sources[path] !== void 0) return sources[path];
4086
+ for (const ext of extensions) {
4087
+ const withExt = `${path}.${ext}`;
4088
+ if (sources[withExt] !== void 0) return sources[withExt];
4089
+ }
4090
+ }
3949
4091
  }
3950
4092
 
3951
4093
  //#endregion
@@ -3975,21 +4117,57 @@ function findUnboundRefs(resolver) {
3975
4117
  mangler: minimalMangle,
3976
4118
  packageName: "package",
3977
4119
  unbound: [],
3978
- dontFollowDecls: true
4120
+ dontFollowDecls: true,
4121
+ discoveryMode: true
3979
4122
  };
3980
4123
  for (const [, ast] of resolver.allModules()) {
3981
- const rootDecls = findValidRootDecls(ast.rootScope, {});
4124
+ const rootDecls = findAllRootDecls(ast.rootScope);
3982
4125
  const liveDecls = {
3983
4126
  decls: new Map(rootDecls.map((d) => [d.originalName, d])),
3984
4127
  parent: null
3985
4128
  };
3986
- filterMap(rootDecls, (decl) => decl.dependentScope).forEach((s) => {
3987
- bindIdentsRecursive(s, bindContext, makeLiveDecls(liveDecls));
3988
- });
4129
+ for (const s of filterMap(rootDecls, (decl) => decl.dependentScope)) bindIdentsRecursive(s, bindContext, makeLiveDecls(liveDecls));
3989
4130
  bindIdentsRecursive(ast.rootScope, bindContext, liveDecls);
3990
4131
  }
3991
4132
  return bindContext.unbound;
3992
4133
  }
4134
+ /** Thin decorator that records which modules were resolved. */
4135
+ var TrackingResolver = class {
4136
+ visited = /* @__PURE__ */ new Set();
4137
+ #inner;
4138
+ constructor(inner) {
4139
+ this.#inner = inner;
4140
+ }
4141
+ resolveModule(modulePath) {
4142
+ const ast = this.#inner.resolveModule(modulePath);
4143
+ if (ast) this.visited.add(modulePath);
4144
+ return ast;
4145
+ }
4146
+ };
4147
+ /**
4148
+ * Discover reachable modules and unbound external refs from a single root.
4149
+ *
4150
+ * Traces the import graph from `rootModuleName`, returning only the reachable
4151
+ * local modules in `weslSrc` and unresolved external references in `unbound`.
4152
+ */
4153
+ function discoverModules(weslSrc, resolver, rootModuleName, packageName = "package") {
4154
+ const tracking = new TrackingResolver(resolver);
4155
+ const rootAst = tracking.resolveModule(rootModuleName);
4156
+ if (!rootAst) throw new Error(`root module not found: '${rootModuleName}'`);
4157
+ const result = bindIdents({
4158
+ rootAst,
4159
+ resolver: tracking,
4160
+ accumulateUnbound: true,
4161
+ discoveryMode: true
4162
+ });
4163
+ const moduleToKey = new Map(Object.keys(weslSrc).map((key) => [fileToModulePath(key, packageName, false), key]));
4164
+ const reachable = [...tracking.visited].map((m) => moduleToKey.get(m)).filter((key) => key !== void 0).map((key) => [key, weslSrc[key]]);
4165
+ const unbound = (result.unbound ?? []).map((ref) => ref.path);
4166
+ return {
4167
+ weslSrc: Object.fromEntries(reachable),
4168
+ unbound
4169
+ };
4170
+ }
3993
4171
 
3994
4172
  //#endregion
3995
4173
  //#region src/discovery/PackageNameUtils.ts
@@ -4160,155 +4338,6 @@ function compilationInfoToErrorMessage(compilationInfo, shaderModule) {
4160
4338
  return result;
4161
4339
  }
4162
4340
 
4163
- //#endregion
4164
- //#region src/PathUtil.ts
4165
- /** simplistic path manipulation utilities */
4166
- /** return path with ./ and foo/.. elements removed */
4167
- function normalize(path) {
4168
- const noDots = path.split("/").filter((s) => s !== ".");
4169
- const noDbl = [];
4170
- noDots.forEach((s) => {
4171
- if (s !== "") if (s === ".." && noDbl.length && noDbl[noDbl.length - 1] !== "..") noDbl.pop();
4172
- else noDbl.push(s);
4173
- });
4174
- return noDbl.join("/");
4175
- }
4176
- /** return path w/o a suffix.
4177
- * e.g. /foo/bar.wgsl => /foo/bar */
4178
- function noSuffix(path) {
4179
- const lastSlash = path.lastIndexOf("/");
4180
- const lastStart = lastSlash === -1 ? 0 : lastSlash + 1;
4181
- const suffix = path.indexOf(".", lastStart);
4182
- const suffixStart = suffix === -1 ? path.length : suffix;
4183
- return path.slice(0, suffixStart);
4184
- }
4185
-
4186
- //#endregion
4187
- //#region src/ModuleResolver.ts
4188
- const libRegex = /^lib\.w[eg]sl$/i;
4189
- /** Module resolver for in-memory source records. Lazy by default. */
4190
- var RecordResolver = class {
4191
- astCache = /* @__PURE__ */ new Map();
4192
- sources;
4193
- packageName;
4194
- debugWeslRoot;
4195
- constructor(sources, options = {}) {
4196
- const { packageName = "package", debugWeslRoot } = options;
4197
- this.sources = sources;
4198
- this.packageName = packageName;
4199
- this.debugWeslRoot = normalizeDebugRoot(debugWeslRoot);
4200
- }
4201
- resolveModule(modulePath) {
4202
- const cached = this.astCache.get(modulePath);
4203
- if (cached) return cached;
4204
- const source = this.findSource(modulePath);
4205
- if (source === void 0) return void 0;
4206
- const ast = parseSrcModule({
4207
- modulePath,
4208
- debugFilePath: this.modulePathToDebugPath(modulePath),
4209
- src: source
4210
- });
4211
- this.astCache.set(modulePath, ast);
4212
- return ast;
4213
- }
4214
- findSource(modulePath) {
4215
- if (this.sources[modulePath] !== void 0) return this.sources[modulePath];
4216
- const filePath = this.moduleToFilePath(modulePath);
4217
- if (filePath === void 0) return void 0;
4218
- return findInVariants(this.sources, filePath);
4219
- }
4220
- /** Convert module path to file path, or undefined if not local. */
4221
- moduleToFilePath(modulePath) {
4222
- return moduleToRelativePath(modulePath, this.packageName);
4223
- }
4224
- modulePathToDebugPath(modulePath) {
4225
- const filePath = this.moduleToFilePath(modulePath) ?? modulePath;
4226
- return this.debugWeslRoot + filePath + ".wesl";
4227
- }
4228
- /** Parse all modules and return entries. */
4229
- allModules() {
4230
- for (const filePath of Object.keys(this.sources)) {
4231
- const treatLibAsRoot = this.packageName !== "package";
4232
- const modulePath = fileToModulePath(filePath, this.packageName, treatLibAsRoot);
4233
- this.resolveModule(modulePath);
4234
- }
4235
- return this.astCache.entries();
4236
- }
4237
- };
4238
- /** Composite resolver that tries each resolver in order until one succeeds. */
4239
- var CompositeResolver = class {
4240
- resolvers;
4241
- constructor(resolvers) {
4242
- this.resolvers = resolvers;
4243
- }
4244
- resolveModule(modulePath) {
4245
- for (const resolver of this.resolvers) {
4246
- const ast = resolver.resolveModule(modulePath);
4247
- if (ast) return ast;
4248
- }
4249
- }
4250
- };
4251
- /** Lazy resolver for WeslBundle library modules. */
4252
- var BundleResolver = class {
4253
- astCache = /* @__PURE__ */ new Map();
4254
- sources;
4255
- packageName;
4256
- debugWeslRoot;
4257
- constructor(bundle, debugWeslRoot) {
4258
- this.sources = bundle.modules;
4259
- this.packageName = bundle.name;
4260
- this.debugWeslRoot = normalizeDebugRoot(debugWeslRoot);
4261
- }
4262
- resolveModule(modulePath) {
4263
- const pkgPrefix = this.packageName + "::";
4264
- if (modulePath !== this.packageName && !modulePath.startsWith(pkgPrefix)) return;
4265
- const cached = this.astCache.get(modulePath);
4266
- if (cached) return cached;
4267
- const source = this.findSource(modulePath);
4268
- if (!source) return void 0;
4269
- const ast = parseSrcModule({
4270
- modulePath,
4271
- debugFilePath: this.modulePathToDebugPath(modulePath),
4272
- src: source
4273
- });
4274
- this.astCache.set(modulePath, ast);
4275
- return ast;
4276
- }
4277
- findSource(modulePath) {
4278
- const filePath = this.moduleToFilePath(modulePath);
4279
- if (modulePath === this.packageName) {
4280
- const libSrc = findInVariants(this.sources, "lib", ["wesl", "wgsl"]);
4281
- if (libSrc) return libSrc;
4282
- }
4283
- return findInVariants(this.sources, filePath);
4284
- }
4285
- moduleToFilePath(modulePath) {
4286
- return moduleToRelativePath(modulePath, this.packageName) ?? modulePath;
4287
- }
4288
- modulePathToDebugPath(modulePath) {
4289
- const filePath = this.moduleToFilePath(modulePath);
4290
- return this.debugWeslRoot + this.packageName + "/" + filePath + ".wesl";
4291
- }
4292
- };
4293
- /** Convert file path to module path (e.g., "foo/bar.wesl" to "package::foo::bar"). */
4294
- function fileToModulePath(filePath, packageName, treatLibAsRoot) {
4295
- if (filePath.includes("::")) return filePath;
4296
- if (treatLibAsRoot && libRegex.test(filePath)) return packageName;
4297
- const moduleSuffix = noSuffix(normalize(filePath)).replaceAll("/", "::");
4298
- return packageName + "::" + moduleSuffix;
4299
- }
4300
- /** Try path variants with/without ./ prefix and extension suffixes. */
4301
- function findInVariants(sources, basePath, extensions = ["wesl", "wgsl"]) {
4302
- for (const prefix of ["", "./"]) {
4303
- const path = prefix + basePath;
4304
- if (sources[path] !== void 0) return sources[path];
4305
- for (const ext of extensions) {
4306
- const withExt = `${path}.${ext}`;
4307
- if (sources[withExt] !== void 0) return sources[withExt];
4308
- }
4309
- }
4310
- }
4311
-
4312
4341
  //#endregion
4313
4342
  //#region src/SrcMap.ts
4314
4343
  /** map text ranges in multiple src texts to a single dest text */
@@ -4857,8 +4886,8 @@ function refersToBindingStruct(memberRef) {
4857
4886
  };
4858
4887
  }
4859
4888
  /** If this identifier ultimately refers to a struct type, return the struct declaration */
4860
- function traceToStruct(ident$1) {
4861
- const declElem = findDecl(ident$1).declElem;
4889
+ function traceToStruct(ident) {
4890
+ const declElem = findDecl(ident).declElem;
4862
4891
  if (declElem && declElem.kind === "param") {
4863
4892
  const name = declElem.name.typeRef?.name;
4864
4893
  if (typeof name !== "string") {
@@ -4963,4 +4992,4 @@ function makeWeslDevice(device) {
4963
4992
  }
4964
4993
 
4965
4994
  //#endregion
4966
- export { BundleResolver, CompositeResolver, LinkedWesl, ParseError, RecordResolver, SrcMap, SrcMapBuilder, WeslParseError, WeslStream, _linkSync, astToString, attributeToString, bindAndTransform, bindIdents, bindIdentsRecursive, bindingStructsPlugin, childIdent, childScope, containsScope, debug, debugContentsToString, emptyScope, errorHighlight, fileToModulePath, filterMap, findMap, findRefsToBindingStructs, findUnboundIdents, findUnboundRefs, findValidRootDecls, flatImports, groupBy, grouped, identToString, last, lengthPrefixMangle, link, linkRegistry, liveDeclsToString, log, lowerBindingStructs, makeLiveDecls, makeWeslDevice, mapForward, mapValues, markBindingStructs, markEntryTypes, mergeScope, minimalMangle, minimallyMangledName, modulePartsToRelativePath, moduleToRelativePath, multiKeySet, multisampledTextureTypes, nextIdentId, noSuffix, normalize, normalizeDebugRoot, normalizeModuleName, npmNameVariations, offsetToLineNumber, overlapTail, parseSrcModule, partition, publicDecl, replaceWords, requestWeslDevice, resetScopeIds, resolveModulePath, sampledTextureTypes, sanitizePackageName, scan, scopeToString, scopeToStringLong, srcLog, stdEnumerant, stdEnumerants, stdFn, stdFns, stdType, stdTypes, textureStorageTypes, transformBindingReference, transformBindingStruct, underscoreMangle, validation, withLoggerAsync };
4995
+ export { BundleResolver, CompositeResolver, LinkedWesl, ParseError, RecordResolver, SrcMap, SrcMapBuilder, TrackingResolver, WeslParseError, WeslStream, _linkSync, astToString, attributeToString, bindAndTransform, bindIdents, bindIdentsRecursive, bindingStructsPlugin, childIdent, childScope, containsScope, debug, debugContentsToString, discoverModules, emptyScope, errorHighlight, fileToModulePath, filterMap, filterValidElements, findAllRootDecls, findMap, findRefsToBindingStructs, findUnboundIdents, findUnboundRefs, findValidRootDecls, flatImports, groupBy, grouped, identToString, last, lengthPrefixMangle, link, linkRegistry, liveDeclsToString, log, lowerBindingStructs, makeLiveDecls, makeWeslDevice, mapForward, mapValues, markBindingStructs, markEntryTypes, mergeScope, minimalMangle, minimallyMangledName, modulePartsToRelativePath, moduleToRelativePath, multiKeySet, multisampledTextureTypes, nextIdentId, noSuffix, normalize, normalizeDebugRoot, normalizeModuleName, npmNameVariations, offsetToLineNumber, overlapTail, parseSrcModule, partition, publicDecl, replaceWords, requestWeslDevice, resetScopeIds, resolveModulePath, sampledTextureTypes, sanitizePackageName, scan, scopeToString, scopeToStringLong, srcLog, stdEnumerant, stdEnumerants, stdFn, stdFns, stdType, stdTypes, textureStorageTypes, transformBindingReference, transformBindingStruct, underscoreMangle, validation, wgslStandardAttributes, withLoggerAsync };