wgsl-edit 0.0.25 → 0.0.26
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 +49 -9
- package/dist/SaveEndpoint.d.mts +5 -0
- package/dist/SaveEndpoint.mjs +5 -0
- package/dist/SaveMiddleware.d.mts +9 -0
- package/dist/SaveMiddleware.mjs +49 -0
- package/dist/{WgslEdit-ByXfb3R9.js → WgslEdit-CNK80480.js} +252 -118
- package/dist/WgslEdit.d.ts +45 -1
- package/dist/WgslEdit.js +1 -1
- package/dist/autosave.d.mts +11 -0
- package/dist/autosave.mjs +18 -0
- package/dist/index.js +1 -1
- package/dist/jsx-preact.d.ts +12 -0
- package/dist/jsx-preact.js +0 -0
- package/dist/wgsl-edit.js +291 -501
- package/package.json +24 -6
- package/src/SaveEndpoint.ts +2 -0
- package/src/SaveMiddleware.ts +71 -0
- package/src/WgslEdit.ts +288 -157
- package/src/autosave.ts +24 -0
- package/src/jsx-preact.ts +15 -0
- package/src/test/Autosave.e2e.ts +100 -0
- package/src/test/E2eUtil.ts +6 -0
- package/src/test/Undo.e2e.ts +91 -0
- package/src/test/WgslEdit.e2e.ts +1 -4
package/dist/wgsl-edit.js
CHANGED
|
@@ -5073,11 +5073,11 @@ var shift = {
|
|
|
5073
5073
|
};
|
|
5074
5074
|
var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
|
|
5075
5075
|
var ie$1 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
|
|
5076
|
-
for (var i
|
|
5077
|
-
for (var i
|
|
5078
|
-
for (var i
|
|
5079
|
-
base[i
|
|
5080
|
-
shift[i
|
|
5076
|
+
for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i);
|
|
5077
|
+
for (var i = 1; i <= 24; i++) base[i + 111] = "F" + i;
|
|
5078
|
+
for (var i = 65; i <= 90; i++) {
|
|
5079
|
+
base[i] = String.fromCharCode(i + 32);
|
|
5080
|
+
shift[i] = String.fromCharCode(i);
|
|
5081
5081
|
}
|
|
5082
5082
|
for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
|
|
5083
5083
|
function keyName(event) {
|
|
@@ -15018,7 +15018,7 @@ tagHighlighter([
|
|
|
15018
15018
|
]);
|
|
15019
15019
|
//#endregion
|
|
15020
15020
|
//#region ../../node_modules/.pnpm/@codemirror+language@6.11.2/node_modules/@codemirror/language/dist/index.js
|
|
15021
|
-
var _a
|
|
15021
|
+
var _a;
|
|
15022
15022
|
/**
|
|
15023
15023
|
Node prop stored in a parser's top syntax node to provide the
|
|
15024
15024
|
facet that stores language-specific data for that language.
|
|
@@ -15479,7 +15479,7 @@ if (typeof requestIdleCallback != "undefined") requestIdle = (callback) => {
|
|
|
15479
15479
|
}, 100);
|
|
15480
15480
|
return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
|
|
15481
15481
|
};
|
|
15482
|
-
const isInputPending = typeof navigator != "undefined" && ((_a
|
|
15482
|
+
const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending) ? () => navigator.scheduling.isInputPending() : null;
|
|
15483
15483
|
const parseWorker = /* @__PURE__ */ ViewPlugin.fromClass(class ParseWorker {
|
|
15484
15484
|
constructor(view) {
|
|
15485
15485
|
this.view = view;
|
|
@@ -19035,12 +19035,13 @@ const isBrowser = "document" in globalThis;
|
|
|
19035
19035
|
/** Throw an error with an embedded source map so that browser users can
|
|
19036
19036
|
* click on the error in the browser debug console and see the wesl source code. */
|
|
19037
19037
|
function throwClickableError(params) {
|
|
19038
|
-
const { url, text, lineNumber, lineColumn, length, error } = params;
|
|
19038
|
+
const { url, text, lineNumber, lineColumn, length, offset, error } = params;
|
|
19039
19039
|
const weslLocation = {
|
|
19040
19040
|
file: url,
|
|
19041
19041
|
line: lineNumber,
|
|
19042
19042
|
column: lineColumn,
|
|
19043
|
-
length
|
|
19043
|
+
length,
|
|
19044
|
+
offset
|
|
19044
19045
|
};
|
|
19045
19046
|
error.weslLocation = weslLocation;
|
|
19046
19047
|
if (!isBrowser) throw error;
|
|
@@ -19101,6 +19102,7 @@ function failIdentElem(identElem, msg = "") {
|
|
|
19101
19102
|
lineNumber,
|
|
19102
19103
|
lineColumn,
|
|
19103
19104
|
length: end - start,
|
|
19105
|
+
offset: start,
|
|
19104
19106
|
error: new Error(detailedMessage)
|
|
19105
19107
|
});
|
|
19106
19108
|
}
|
|
@@ -19376,7 +19378,7 @@ function lowerAndEmitElem(e, ctx) {
|
|
|
19376
19378
|
case "let":
|
|
19377
19379
|
case "statement":
|
|
19378
19380
|
case "continuing":
|
|
19379
|
-
emitStatement
|
|
19381
|
+
emitStatement(e, ctx);
|
|
19380
19382
|
return;
|
|
19381
19383
|
case "override":
|
|
19382
19384
|
case "const":
|
|
@@ -19414,7 +19416,7 @@ function emitModule(e, ctx) {
|
|
|
19414
19416
|
lowerAndEmitElem(child, ctx);
|
|
19415
19417
|
}
|
|
19416
19418
|
}
|
|
19417
|
-
function emitStatement
|
|
19419
|
+
function emitStatement(e, ctx) {
|
|
19418
19420
|
if (!(e.contents.length > 0 && e.contents[0].kind === "attribute")) emitAttributes(e.attributes, ctx);
|
|
19419
19421
|
emitContents(e, ctx);
|
|
19420
19422
|
}
|
|
@@ -22751,20 +22753,13 @@ async function link(params) {
|
|
|
22751
22753
|
}
|
|
22752
22754
|
/** linker api for benchmarking */
|
|
22753
22755
|
function _linkSync(params) {
|
|
22754
|
-
const { weslSrc, libs = [], packageName, debugWeslRoot } = params;
|
|
22755
|
-
|
|
22756
|
-
const
|
|
22757
|
-
if (resolver) resolvers.push(resolver);
|
|
22758
|
-
else if (weslSrc) resolvers.push(new RecordResolver(weslSrc, {
|
|
22756
|
+
const { weslSrc, libs = [], packageName, debugWeslRoot, resolver } = params;
|
|
22757
|
+
if (!resolver && !weslSrc) throw new Error("Either resolver or weslSrc must be provided");
|
|
22758
|
+
const allResolvers = [resolver ?? new RecordResolver(weslSrc, {
|
|
22759
22759
|
packageName,
|
|
22760
22760
|
debugWeslRoot
|
|
22761
|
-
}));
|
|
22762
|
-
|
|
22763
|
-
if (libs.length > 0) {
|
|
22764
|
-
const libResolvers = createLibraryResolvers(libs, debugWeslRoot);
|
|
22765
|
-
resolvers.push(...libResolvers);
|
|
22766
|
-
}
|
|
22767
|
-
const finalResolver = resolvers.length === 1 ? resolvers[0] : new CompositeResolver(resolvers);
|
|
22761
|
+
}), ...createLibraryResolvers(libs, debugWeslRoot)];
|
|
22762
|
+
const finalResolver = allResolvers.length === 1 ? allResolvers[0] : new CompositeResolver(allResolvers);
|
|
22768
22763
|
return linkRegistry({
|
|
22769
22764
|
...params,
|
|
22770
22765
|
resolver: finalResolver
|
|
@@ -22848,6 +22843,7 @@ function setupVirtualLibs(virtualLibs, constants) {
|
|
|
22848
22843
|
}
|
|
22849
22844
|
return libs && mapValues(libs, (fn) => ({ fn }));
|
|
22850
22845
|
}
|
|
22846
|
+
/** Run registered transform plugins over the bound AST. */
|
|
22851
22847
|
function applyTransformPlugins(rootModule, globalNames, config) {
|
|
22852
22848
|
const { moduleElem, srcModule } = rootModule;
|
|
22853
22849
|
const startAst = {
|
|
@@ -22860,53 +22856,38 @@ function applyTransformPlugins(rootModule, globalNames, config) {
|
|
|
22860
22856
|
}
|
|
22861
22857
|
/** Assemble WGSL output from prologue statements, root module, and imported declarations. */
|
|
22862
22858
|
function emitWgsl(rootModuleElem, srcModule, newDecls, newStatements, conditions = {}) {
|
|
22863
|
-
const prologueBuilders = newStatements.map((s) =>
|
|
22864
|
-
const rootBuilder =
|
|
22865
|
-
text: srcModule.src,
|
|
22866
|
-
path: srcModule.debugFilePath
|
|
22867
|
-
});
|
|
22859
|
+
const prologueBuilders = newStatements.map((s) => emitElem(s.srcModule, s.elem, conditions, { addNl: true }));
|
|
22860
|
+
const rootBuilder = builderFromModule(srcModule);
|
|
22868
22861
|
lowerAndEmit({
|
|
22869
22862
|
srcBuilder: rootBuilder,
|
|
22870
22863
|
rootElems: [rootModuleElem],
|
|
22871
22864
|
conditions,
|
|
22872
22865
|
extracting: false
|
|
22873
22866
|
});
|
|
22874
|
-
const declBuilders = newDecls.map((decl) =>
|
|
22867
|
+
const declBuilders = newDecls.map((decl) => emitElem(decl.srcModule, decl.declElem, conditions, { skipConditionalFiltering: true }));
|
|
22875
22868
|
return [
|
|
22876
22869
|
...prologueBuilders,
|
|
22877
22870
|
rootBuilder,
|
|
22878
22871
|
...declBuilders
|
|
22879
22872
|
];
|
|
22880
22873
|
}
|
|
22881
|
-
|
|
22882
|
-
|
|
22883
|
-
const
|
|
22884
|
-
const builder = new SrcMapBuilder({
|
|
22885
|
-
text,
|
|
22886
|
-
path
|
|
22887
|
-
});
|
|
22874
|
+
/** Emit a single element (prologue statement or imported declaration) into a SrcMapBuilder. */
|
|
22875
|
+
function emitElem(srcModule, elem, conditions, opts = {}) {
|
|
22876
|
+
const builder = builderFromModule(srcModule);
|
|
22888
22877
|
lowerAndEmit({
|
|
22889
22878
|
srcBuilder: builder,
|
|
22890
22879
|
rootElems: [elem],
|
|
22891
|
-
conditions
|
|
22880
|
+
conditions,
|
|
22881
|
+
skipConditionalFiltering: opts.skipConditionalFiltering
|
|
22892
22882
|
});
|
|
22893
|
-
builder.addNl();
|
|
22883
|
+
if (opts.addNl) builder.addNl();
|
|
22894
22884
|
return builder;
|
|
22895
22885
|
}
|
|
22896
|
-
|
|
22897
|
-
|
|
22898
|
-
|
|
22899
|
-
|
|
22900
|
-
text,
|
|
22901
|
-
path
|
|
22902
|
-
});
|
|
22903
|
-
lowerAndEmit({
|
|
22904
|
-
srcBuilder: builder,
|
|
22905
|
-
rootElems: [decl.declElem],
|
|
22906
|
-
conditions,
|
|
22907
|
-
skipConditionalFiltering: true
|
|
22886
|
+
function builderFromModule(srcModule) {
|
|
22887
|
+
return new SrcMapBuilder({
|
|
22888
|
+
text: srcModule.src,
|
|
22889
|
+
path: srcModule.debugFilePath
|
|
22908
22890
|
});
|
|
22909
|
-
return builder;
|
|
22910
22891
|
}
|
|
22911
22892
|
matchOneOf(textureStorageTypes);
|
|
22912
22893
|
matchOneOf(sampledTextureTypes);
|
|
@@ -27394,338 +27375,6 @@ async function hydrateBundle(path, registry, hydrated, fetcher) {
|
|
|
27394
27375
|
return placeholder;
|
|
27395
27376
|
}
|
|
27396
27377
|
//#endregion
|
|
27397
|
-
//#region ../../node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/browser.js
|
|
27398
|
-
var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
|
|
27399
|
-
var fleb = new u8([
|
|
27400
|
-
0,
|
|
27401
|
-
0,
|
|
27402
|
-
0,
|
|
27403
|
-
0,
|
|
27404
|
-
0,
|
|
27405
|
-
0,
|
|
27406
|
-
0,
|
|
27407
|
-
0,
|
|
27408
|
-
1,
|
|
27409
|
-
1,
|
|
27410
|
-
1,
|
|
27411
|
-
1,
|
|
27412
|
-
2,
|
|
27413
|
-
2,
|
|
27414
|
-
2,
|
|
27415
|
-
2,
|
|
27416
|
-
3,
|
|
27417
|
-
3,
|
|
27418
|
-
3,
|
|
27419
|
-
3,
|
|
27420
|
-
4,
|
|
27421
|
-
4,
|
|
27422
|
-
4,
|
|
27423
|
-
4,
|
|
27424
|
-
5,
|
|
27425
|
-
5,
|
|
27426
|
-
5,
|
|
27427
|
-
5,
|
|
27428
|
-
0,
|
|
27429
|
-
0,
|
|
27430
|
-
0,
|
|
27431
|
-
0
|
|
27432
|
-
]);
|
|
27433
|
-
var fdeb = new u8([
|
|
27434
|
-
0,
|
|
27435
|
-
0,
|
|
27436
|
-
0,
|
|
27437
|
-
0,
|
|
27438
|
-
1,
|
|
27439
|
-
1,
|
|
27440
|
-
2,
|
|
27441
|
-
2,
|
|
27442
|
-
3,
|
|
27443
|
-
3,
|
|
27444
|
-
4,
|
|
27445
|
-
4,
|
|
27446
|
-
5,
|
|
27447
|
-
5,
|
|
27448
|
-
6,
|
|
27449
|
-
6,
|
|
27450
|
-
7,
|
|
27451
|
-
7,
|
|
27452
|
-
8,
|
|
27453
|
-
8,
|
|
27454
|
-
9,
|
|
27455
|
-
9,
|
|
27456
|
-
10,
|
|
27457
|
-
10,
|
|
27458
|
-
11,
|
|
27459
|
-
11,
|
|
27460
|
-
12,
|
|
27461
|
-
12,
|
|
27462
|
-
13,
|
|
27463
|
-
13,
|
|
27464
|
-
0,
|
|
27465
|
-
0
|
|
27466
|
-
]);
|
|
27467
|
-
var clim = new u8([
|
|
27468
|
-
16,
|
|
27469
|
-
17,
|
|
27470
|
-
18,
|
|
27471
|
-
0,
|
|
27472
|
-
8,
|
|
27473
|
-
7,
|
|
27474
|
-
9,
|
|
27475
|
-
6,
|
|
27476
|
-
10,
|
|
27477
|
-
5,
|
|
27478
|
-
11,
|
|
27479
|
-
4,
|
|
27480
|
-
12,
|
|
27481
|
-
3,
|
|
27482
|
-
13,
|
|
27483
|
-
2,
|
|
27484
|
-
14,
|
|
27485
|
-
1,
|
|
27486
|
-
15
|
|
27487
|
-
]);
|
|
27488
|
-
var freb = function(eb, start) {
|
|
27489
|
-
var b = new u16(31);
|
|
27490
|
-
for (var i = 0; i < 31; ++i) b[i] = start += 1 << eb[i - 1];
|
|
27491
|
-
var r = new i32(b[30]);
|
|
27492
|
-
for (var i = 1; i < 30; ++i) for (var j = b[i]; j < b[i + 1]; ++j) r[j] = j - b[i] << 5 | i;
|
|
27493
|
-
return {
|
|
27494
|
-
b,
|
|
27495
|
-
r
|
|
27496
|
-
};
|
|
27497
|
-
};
|
|
27498
|
-
var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
|
|
27499
|
-
fl[28] = 258, revfl[258] = 28;
|
|
27500
|
-
var _b = freb(fdeb, 0), fd = _b.b;
|
|
27501
|
-
_b.r;
|
|
27502
|
-
var rev = new u16(32768);
|
|
27503
|
-
for (var i = 0; i < 32768; ++i) {
|
|
27504
|
-
var x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
27505
|
-
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
27506
|
-
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
27507
|
-
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
27508
|
-
}
|
|
27509
|
-
var hMap = (function(cd, mb, r) {
|
|
27510
|
-
var s = cd.length;
|
|
27511
|
-
var i = 0;
|
|
27512
|
-
var l = new u16(mb);
|
|
27513
|
-
for (; i < s; ++i) if (cd[i]) ++l[cd[i] - 1];
|
|
27514
|
-
var le = new u16(mb);
|
|
27515
|
-
for (i = 1; i < mb; ++i) le[i] = le[i - 1] + l[i - 1] << 1;
|
|
27516
|
-
var co;
|
|
27517
|
-
if (r) {
|
|
27518
|
-
co = new u16(1 << mb);
|
|
27519
|
-
var rvb = 15 - mb;
|
|
27520
|
-
for (i = 0; i < s; ++i) if (cd[i]) {
|
|
27521
|
-
var sv = i << 4 | cd[i];
|
|
27522
|
-
var r_1 = mb - cd[i];
|
|
27523
|
-
var v = le[cd[i] - 1]++ << r_1;
|
|
27524
|
-
for (var m = v | (1 << r_1) - 1; v <= m; ++v) co[rev[v] >> rvb] = sv;
|
|
27525
|
-
}
|
|
27526
|
-
} else {
|
|
27527
|
-
co = new u16(s);
|
|
27528
|
-
for (i = 0; i < s; ++i) if (cd[i]) co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
|
|
27529
|
-
}
|
|
27530
|
-
return co;
|
|
27531
|
-
});
|
|
27532
|
-
var flt = new u8(288);
|
|
27533
|
-
for (var i = 0; i < 144; ++i) flt[i] = 8;
|
|
27534
|
-
for (var i = 144; i < 256; ++i) flt[i] = 9;
|
|
27535
|
-
for (var i = 256; i < 280; ++i) flt[i] = 7;
|
|
27536
|
-
for (var i = 280; i < 288; ++i) flt[i] = 8;
|
|
27537
|
-
var fdt = new u8(32);
|
|
27538
|
-
for (var i = 0; i < 32; ++i) fdt[i] = 5;
|
|
27539
|
-
var flrm = /* @__PURE__ */ hMap(flt, 9, 1), fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
27540
|
-
var max = function(a) {
|
|
27541
|
-
var m = a[0];
|
|
27542
|
-
for (var i = 1; i < a.length; ++i) if (a[i] > m) m = a[i];
|
|
27543
|
-
return m;
|
|
27544
|
-
};
|
|
27545
|
-
var bits = function(d, p, m) {
|
|
27546
|
-
var o = p / 8 | 0;
|
|
27547
|
-
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
27548
|
-
};
|
|
27549
|
-
var bits16 = function(d, p) {
|
|
27550
|
-
var o = p / 8 | 0;
|
|
27551
|
-
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
27552
|
-
};
|
|
27553
|
-
var shft = function(p) {
|
|
27554
|
-
return (p + 7) / 8 | 0;
|
|
27555
|
-
};
|
|
27556
|
-
var slc = function(v, s, e) {
|
|
27557
|
-
if (s == null || s < 0) s = 0;
|
|
27558
|
-
if (e == null || e > v.length) e = v.length;
|
|
27559
|
-
return new u8(v.subarray(s, e));
|
|
27560
|
-
};
|
|
27561
|
-
var ec = [
|
|
27562
|
-
"unexpected EOF",
|
|
27563
|
-
"invalid block type",
|
|
27564
|
-
"invalid length/literal",
|
|
27565
|
-
"invalid distance",
|
|
27566
|
-
"stream finished",
|
|
27567
|
-
"no stream handler",
|
|
27568
|
-
,
|
|
27569
|
-
"no callback",
|
|
27570
|
-
"invalid UTF-8 data",
|
|
27571
|
-
"extra field too long",
|
|
27572
|
-
"date not in range 1980-2099",
|
|
27573
|
-
"filename too long",
|
|
27574
|
-
"stream finishing",
|
|
27575
|
-
"invalid zip data"
|
|
27576
|
-
];
|
|
27577
|
-
var err = function(ind, msg, nt) {
|
|
27578
|
-
var e = new Error(msg || ec[ind]);
|
|
27579
|
-
e.code = ind;
|
|
27580
|
-
if (Error.captureStackTrace) Error.captureStackTrace(e, err);
|
|
27581
|
-
if (!nt) throw e;
|
|
27582
|
-
return e;
|
|
27583
|
-
};
|
|
27584
|
-
var inflt = function(dat, st, buf, dict) {
|
|
27585
|
-
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
27586
|
-
if (!sl || st.f && !st.l) return buf || new u8(0);
|
|
27587
|
-
var noBuf = !buf;
|
|
27588
|
-
var resize = noBuf || st.i != 2;
|
|
27589
|
-
var noSt = st.i;
|
|
27590
|
-
if (noBuf) buf = new u8(sl * 3);
|
|
27591
|
-
var cbuf = function(l) {
|
|
27592
|
-
var bl = buf.length;
|
|
27593
|
-
if (l > bl) {
|
|
27594
|
-
var nbuf = new u8(Math.max(bl * 2, l));
|
|
27595
|
-
nbuf.set(buf);
|
|
27596
|
-
buf = nbuf;
|
|
27597
|
-
}
|
|
27598
|
-
};
|
|
27599
|
-
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
27600
|
-
var tbts = sl * 8;
|
|
27601
|
-
do {
|
|
27602
|
-
if (!lm) {
|
|
27603
|
-
final = bits(dat, pos, 1);
|
|
27604
|
-
var type = bits(dat, pos + 1, 3);
|
|
27605
|
-
pos += 3;
|
|
27606
|
-
if (!type) {
|
|
27607
|
-
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
27608
|
-
if (t > sl) {
|
|
27609
|
-
if (noSt) err(0);
|
|
27610
|
-
break;
|
|
27611
|
-
}
|
|
27612
|
-
if (resize) cbuf(bt + l);
|
|
27613
|
-
buf.set(dat.subarray(s, t), bt);
|
|
27614
|
-
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
27615
|
-
continue;
|
|
27616
|
-
} else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
27617
|
-
else if (type == 2) {
|
|
27618
|
-
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
27619
|
-
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
27620
|
-
pos += 14;
|
|
27621
|
-
var ldt = new u8(tl);
|
|
27622
|
-
var clt = new u8(19);
|
|
27623
|
-
for (var i = 0; i < hcLen; ++i) clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
27624
|
-
pos += hcLen * 3;
|
|
27625
|
-
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
27626
|
-
var clm = hMap(clt, clb, 1);
|
|
27627
|
-
for (var i = 0; i < tl;) {
|
|
27628
|
-
var r = clm[bits(dat, pos, clbmsk)];
|
|
27629
|
-
pos += r & 15;
|
|
27630
|
-
var s = r >> 4;
|
|
27631
|
-
if (s < 16) ldt[i++] = s;
|
|
27632
|
-
else {
|
|
27633
|
-
var c = 0, n = 0;
|
|
27634
|
-
if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
27635
|
-
else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
|
|
27636
|
-
else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
|
|
27637
|
-
while (n--) ldt[i++] = c;
|
|
27638
|
-
}
|
|
27639
|
-
}
|
|
27640
|
-
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
27641
|
-
lbt = max(lt);
|
|
27642
|
-
dbt = max(dt);
|
|
27643
|
-
lm = hMap(lt, lbt, 1);
|
|
27644
|
-
dm = hMap(dt, dbt, 1);
|
|
27645
|
-
} else err(1);
|
|
27646
|
-
if (pos > tbts) {
|
|
27647
|
-
if (noSt) err(0);
|
|
27648
|
-
break;
|
|
27649
|
-
}
|
|
27650
|
-
}
|
|
27651
|
-
if (resize) cbuf(bt + 131072);
|
|
27652
|
-
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
27653
|
-
var lpos = pos;
|
|
27654
|
-
for (;; lpos = pos) {
|
|
27655
|
-
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
27656
|
-
pos += c & 15;
|
|
27657
|
-
if (pos > tbts) {
|
|
27658
|
-
if (noSt) err(0);
|
|
27659
|
-
break;
|
|
27660
|
-
}
|
|
27661
|
-
if (!c) err(2);
|
|
27662
|
-
if (sym < 256) buf[bt++] = sym;
|
|
27663
|
-
else if (sym == 256) {
|
|
27664
|
-
lpos = pos, lm = null;
|
|
27665
|
-
break;
|
|
27666
|
-
} else {
|
|
27667
|
-
var add = sym - 254;
|
|
27668
|
-
if (sym > 264) {
|
|
27669
|
-
var i = sym - 257, b = fleb[i];
|
|
27670
|
-
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
27671
|
-
pos += b;
|
|
27672
|
-
}
|
|
27673
|
-
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
27674
|
-
if (!d) err(3);
|
|
27675
|
-
pos += d & 15;
|
|
27676
|
-
var dt = fd[dsym];
|
|
27677
|
-
if (dsym > 3) {
|
|
27678
|
-
var b = fdeb[dsym];
|
|
27679
|
-
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
27680
|
-
}
|
|
27681
|
-
if (pos > tbts) {
|
|
27682
|
-
if (noSt) err(0);
|
|
27683
|
-
break;
|
|
27684
|
-
}
|
|
27685
|
-
if (resize) cbuf(bt + 131072);
|
|
27686
|
-
var end = bt + add;
|
|
27687
|
-
if (bt < dt) {
|
|
27688
|
-
var shift = dl - dt, dend = Math.min(dt, end);
|
|
27689
|
-
if (shift + bt < 0) err(3);
|
|
27690
|
-
for (; bt < dend; ++bt) buf[bt] = dict[shift + bt];
|
|
27691
|
-
}
|
|
27692
|
-
for (; bt < end; ++bt) buf[bt] = buf[bt - dt];
|
|
27693
|
-
}
|
|
27694
|
-
}
|
|
27695
|
-
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
27696
|
-
if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
27697
|
-
} while (!final);
|
|
27698
|
-
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
27699
|
-
};
|
|
27700
|
-
var et = /* @__PURE__ */ new u8(0);
|
|
27701
|
-
var gzs = function(d) {
|
|
27702
|
-
if (d[0] != 31 || d[1] != 139 || d[2] != 8) err(6, "invalid gzip data");
|
|
27703
|
-
var flg = d[3];
|
|
27704
|
-
var st = 10;
|
|
27705
|
-
if (flg & 4) st += (d[10] | d[11] << 8) + 2;
|
|
27706
|
-
for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++]);
|
|
27707
|
-
return st + (flg & 2);
|
|
27708
|
-
};
|
|
27709
|
-
var gzl = function(d) {
|
|
27710
|
-
var l = d.length;
|
|
27711
|
-
return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
|
|
27712
|
-
};
|
|
27713
|
-
/**
|
|
27714
|
-
* Expands GZIP data
|
|
27715
|
-
* @param data The data to decompress
|
|
27716
|
-
* @param opts The decompression options
|
|
27717
|
-
* @returns The decompressed version of the data
|
|
27718
|
-
*/
|
|
27719
|
-
function gunzipSync(data, opts) {
|
|
27720
|
-
var st = gzs(data);
|
|
27721
|
-
if (st + 8 > data.length) err(6, "invalid gzip data");
|
|
27722
|
-
return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
|
|
27723
|
-
}
|
|
27724
|
-
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
27725
|
-
try {
|
|
27726
|
-
td.decode(et, { stream: true });
|
|
27727
|
-
} catch (e) {}
|
|
27728
|
-
//#endregion
|
|
27729
27378
|
//#region ../../node_modules/.pnpm/nanotar@0.2.0/node_modules/nanotar/dist/index.mjs
|
|
27730
27379
|
const TAR_TYPE_FILE = 0;
|
|
27731
27380
|
const TAR_TYPE_DIR = 5;
|
|
@@ -27777,6 +27426,13 @@ function parseTar(data, opts) {
|
|
|
27777
27426
|
}
|
|
27778
27427
|
return files;
|
|
27779
27428
|
}
|
|
27429
|
+
async function parseTarGzip(data, opts = {}) {
|
|
27430
|
+
const stream = new ReadableStream({ start(controller) {
|
|
27431
|
+
controller.enqueue(new Uint8Array(data));
|
|
27432
|
+
controller.close();
|
|
27433
|
+
} }).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
|
|
27434
|
+
return parseTar(await new Response(stream).arrayBuffer(), opts);
|
|
27435
|
+
}
|
|
27780
27436
|
function _readString(buffer, offset, size) {
|
|
27781
27437
|
const view = new Uint8Array(buffer, offset, size);
|
|
27782
27438
|
const i = view.indexOf(0);
|
|
@@ -27813,7 +27469,7 @@ function memoAsync(fn) {
|
|
|
27813
27469
|
async function fetchAndExtractTgzRaw(tgzUrl) {
|
|
27814
27470
|
const response = await fetch(tgzUrl);
|
|
27815
27471
|
if (!response.ok) throw new Error(`Failed to fetch package: HTTP ${response.status}`);
|
|
27816
|
-
return
|
|
27472
|
+
return parseTarGzip(new Uint8Array(await response.arrayBuffer()));
|
|
27817
27473
|
}
|
|
27818
27474
|
async function npmPackageToUrlRaw(packageName) {
|
|
27819
27475
|
const metadataUrl = `https://registry.npmjs.org/${packageName}`;
|
|
@@ -27880,6 +27536,10 @@ async function fetchOnePackage(pkgId, loaded) {
|
|
|
27880
27536
|
throw new Error(`Package not found: ${pkgId}`);
|
|
27881
27537
|
}
|
|
27882
27538
|
//#endregion
|
|
27539
|
+
//#region src/SaveEndpoint.ts
|
|
27540
|
+
/** Shared between client (WgslEdit) and server (SaveMiddleware) so they can't drift. */
|
|
27541
|
+
const saveEndpoint = "/__wgsl-edit/save";
|
|
27542
|
+
//#endregion
|
|
27883
27543
|
//#region src/WgslEdit.css?inline
|
|
27884
27544
|
var WgslEdit_default = ":host {\n --tab-bar-bg: transparent;\n --tab-border: #ccc;\n --tab-color: #999;\n --tab-active-bg: #fff;\n --tab-active-color: #222;\n --tab-accent: #5f61d8;\n\n display: flex;\n flex-direction: column;\n position: relative;\n min-height: 100px;\n}\n\n:host(.dark) {\n --tab-bar-bg: transparent;\n --tab-border: #555;\n --tab-color: #999;\n --tab-active-bg: #1e1e1e;\n --tab-active-color: #fff;\n}\n\n.tab-bar {\n --bar-v: 6px;\n --bar-h: 8px;\n display: flex;\n align-items: center;\n gap: 14px;\n padding: var(--bar-v) var(--bar-h);\n background: var(--tab-bar-bg);\n flex-shrink: 0;\n position: relative;\n}\n\n.tab-bar::after {\n content: \"\";\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: var(--tab-border);\n}\n\n.tab {\n --tab-v: 5px;\n --tab-h: 12px;\n display: flex;\n align-items: center;\n gap: 16px;\n padding: var(--tab-v) var(--tab-h);\n background: transparent;\n border: none;\n border-radius: 0;\n color: var(--tab-color);\n cursor: pointer;\n position: relative;\n font-size: 15px;\n font-family: system-ui, sans-serif;\n}\n\n.tab.active {\n color: var(--tab-accent);\n font-weight: 600;\n padding-bottom: calc(var(--tab-v) + var(--bar-v) + 0.5px);\n margin-bottom: calc(-1 * (var(--bar-v) + 0.5px));\n position: relative;\n z-index: 1;\n border-bottom: 2px solid var(--tab-accent);\n}\n\n.tab.active:first-child {\n margin-left: calc(-1 * var(--bar-h));\n padding-left: calc(var(--tab-h) + var(--bar-h));\n}\n\n.tab-close {\n position: absolute;\n right: -8px;\n /* top: 2px; */\n width: 16px;\n height: 16px;\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n cursor: pointer;\n opacity: 0;\n font-size: 18px;\n line-height: 1;\n}\n\n.tab:hover .tab-close {\n opacity: 0.6;\n}\n\n.tab-close:hover {\n opacity: 1;\n}\n\n.tab-rename {\n background: var(--tab-active-bg);\n border: 1px solid var(--tab-border);\n border-radius: 4px;\n color: var(--tab-active-color);\n font-size: 15px;\n font-family: system-ui, sans-serif;\n padding: 0 4px;\n outline: none;\n}\n\n.tab-add {\n padding: 0 10px;\n background: transparent;\n border: none;\n color: var(--tab-color);\n cursor: pointer;\n font-size: 25px;\n line-height: 1;\n}\n\n.tab-add:hover {\n color: var(--tab-active-color);\n}\n\n.editor-container {\n flex: 1;\n min-height: 0;\n width: 100%;\n padding: var(--editor-padding, 16px 0 0);\n}\n\n.cm-editor {\n height: 100%;\n font-size: var(--editor-font-size, 14px);\n}\n\n.cm-scroller {\n overflow: auto;\n}\n\n.snackbar {\n position: absolute;\n bottom: 16px;\n left: 16px;\n background: #e8e8e8;\n color: #333;\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n font-family: system-ui, sans-serif;\n line-height: 1.4;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n z-index: 10;\n}\n\n:host(.dark) .snackbar {\n background: #3a3a3a;\n color: #e0e0e0;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);\n}\n\n.snackbar.visible {\n opacity: 1;\n}\n";
|
|
27885
27545
|
//#endregion
|
|
@@ -27918,7 +27578,8 @@ var WgslEdit = class extends HTMLElement {
|
|
|
27918
27578
|
"lint-from",
|
|
27919
27579
|
"line-numbers",
|
|
27920
27580
|
"fetch-libs",
|
|
27921
|
-
"gpu-lint"
|
|
27581
|
+
"gpu-lint",
|
|
27582
|
+
"autosave"
|
|
27922
27583
|
];
|
|
27923
27584
|
editorView = null;
|
|
27924
27585
|
editorContainer;
|
|
@@ -27947,6 +27608,10 @@ var WgslEdit = class extends HTMLElement {
|
|
|
27947
27608
|
_fetchingPkgs = /* @__PURE__ */ new Set();
|
|
27948
27609
|
_fetchedPkgs = /* @__PURE__ */ new Set();
|
|
27949
27610
|
_snackTimer;
|
|
27611
|
+
_devSaveListener = null;
|
|
27612
|
+
_saveTimer;
|
|
27613
|
+
_dirtyFiles = /* @__PURE__ */ new Set();
|
|
27614
|
+
_switchingFile = false;
|
|
27950
27615
|
_externalDiagnostics = [];
|
|
27951
27616
|
_lintFromEl = null;
|
|
27952
27617
|
/** Bound listeners for lint-from element's compile events. */
|
|
@@ -27970,10 +27635,13 @@ var WgslEdit = class extends HTMLElement {
|
|
|
27970
27635
|
connectedCallback() {
|
|
27971
27636
|
this.initEditor();
|
|
27972
27637
|
this.loadInitialContent();
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27638
|
+
for (const p of [
|
|
27639
|
+
"conditions",
|
|
27640
|
+
"source",
|
|
27641
|
+
"sources",
|
|
27642
|
+
"project",
|
|
27643
|
+
"autosave"
|
|
27644
|
+
]) upgradeProperty(this, p);
|
|
27977
27645
|
}
|
|
27978
27646
|
disconnectedCallback() {
|
|
27979
27647
|
this.connectLintSource(null);
|
|
@@ -27981,25 +27649,43 @@ var WgslEdit = class extends HTMLElement {
|
|
|
27981
27649
|
this.editorView = null;
|
|
27982
27650
|
}
|
|
27983
27651
|
attributeChangedCallback(name, _old, value) {
|
|
27984
|
-
|
|
27985
|
-
|
|
27986
|
-
|
|
27987
|
-
|
|
27988
|
-
|
|
27989
|
-
|
|
27990
|
-
|
|
27991
|
-
|
|
27992
|
-
|
|
27993
|
-
|
|
27994
|
-
|
|
27995
|
-
|
|
27996
|
-
|
|
27997
|
-
|
|
27998
|
-
|
|
27999
|
-
|
|
28000
|
-
|
|
28001
|
-
|
|
28002
|
-
|
|
27652
|
+
switch (name) {
|
|
27653
|
+
case "src":
|
|
27654
|
+
if (value && this.editorView) this.loadFromUrl(value);
|
|
27655
|
+
break;
|
|
27656
|
+
case "readonly":
|
|
27657
|
+
this.updateReadonly();
|
|
27658
|
+
break;
|
|
27659
|
+
case "theme":
|
|
27660
|
+
this.theme = value || "auto";
|
|
27661
|
+
break;
|
|
27662
|
+
case "tabs":
|
|
27663
|
+
this._tabs = value !== "false";
|
|
27664
|
+
this.renderTabs();
|
|
27665
|
+
break;
|
|
27666
|
+
case "lint":
|
|
27667
|
+
this._lint = value || "on";
|
|
27668
|
+
this.updateLint();
|
|
27669
|
+
break;
|
|
27670
|
+
case "lint-from":
|
|
27671
|
+
this.connectLintSource(value);
|
|
27672
|
+
break;
|
|
27673
|
+
case "line-numbers":
|
|
27674
|
+
this._lineNumbers = value === "true";
|
|
27675
|
+
this.updateLineNumbers();
|
|
27676
|
+
break;
|
|
27677
|
+
case "fetch-libs":
|
|
27678
|
+
this._fetchLibs = value !== "false";
|
|
27679
|
+
this.updateLint();
|
|
27680
|
+
break;
|
|
27681
|
+
case "gpu-lint":
|
|
27682
|
+
this._gpuLint = value !== "off";
|
|
27683
|
+
this.updateLint();
|
|
27684
|
+
break;
|
|
27685
|
+
case "autosave":
|
|
27686
|
+
if (value !== null && value !== "false") this.enableDevSave();
|
|
27687
|
+
else this.disableDevSave();
|
|
27688
|
+
break;
|
|
28003
27689
|
}
|
|
28004
27690
|
}
|
|
28005
27691
|
/** Conditions for conditional compilation (@if/@elif/@else). */
|
|
@@ -28011,6 +27697,10 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28011
27697
|
this.updateLint();
|
|
28012
27698
|
this.dispatchChange();
|
|
28013
27699
|
}
|
|
27700
|
+
/** Reconfigure a compartment via the active editor view (no-op if unmounted). */
|
|
27701
|
+
reconfigure(comp, ext) {
|
|
27702
|
+
this.editorView?.dispatch({ effects: comp.reconfigure(ext) });
|
|
27703
|
+
}
|
|
28014
27704
|
/** Active file content (single-file API). */
|
|
28015
27705
|
get source() {
|
|
28016
27706
|
return this.editorView?.state.doc.toString() ?? this._pendingSource ?? "";
|
|
@@ -28018,27 +27708,30 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28018
27708
|
/** Set active file content (single-file API). Auto-creates a default file entry. */
|
|
28019
27709
|
set source(value) {
|
|
28020
27710
|
if (!this._activeFile && this._files.size === 0) {
|
|
28021
|
-
this._files.set("main.wesl", { doc:
|
|
27711
|
+
this._files.set("main.wesl", { doc: toDoc(value) });
|
|
28022
27712
|
this._activeFile = "main.wesl";
|
|
28023
27713
|
this.renderTabs();
|
|
28024
27714
|
}
|
|
28025
27715
|
if (this.editorView) {
|
|
28026
|
-
const
|
|
28027
|
-
this.editorView.dispatch({
|
|
28028
|
-
|
|
28029
|
-
|
|
28030
|
-
|
|
28031
|
-
|
|
27716
|
+
const docLength = this.editorView.state.doc.length;
|
|
27717
|
+
this.editorView.dispatch({
|
|
27718
|
+
changes: {
|
|
27719
|
+
from: 0,
|
|
27720
|
+
to: docLength,
|
|
27721
|
+
insert: value
|
|
27722
|
+
},
|
|
27723
|
+
annotations: Transaction.addToHistory.of(false)
|
|
27724
|
+
});
|
|
28032
27725
|
} else {
|
|
28033
27726
|
this._pendingSource = value;
|
|
28034
27727
|
const entry = this._files.get(this._activeFile);
|
|
28035
|
-
if (entry) entry.doc =
|
|
27728
|
+
if (entry) entry.doc = toDoc(value);
|
|
28036
27729
|
}
|
|
28037
27730
|
}
|
|
28038
27731
|
/** All file contents keyed by module path (e.g., "package::main"). */
|
|
28039
27732
|
get sources() {
|
|
28040
27733
|
this.saveCurrentFileState();
|
|
28041
|
-
const pkg = this.
|
|
27734
|
+
const pkg = this.pkgName();
|
|
28042
27735
|
const result = {};
|
|
28043
27736
|
for (const [tabName, state] of this._files) result[fileToModulePath(tabName, pkg, false)] = state.doc.toString();
|
|
28044
27737
|
return result;
|
|
@@ -28048,12 +27741,13 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28048
27741
|
this._files.clear();
|
|
28049
27742
|
for (const [key, content] of Object.entries(value)) {
|
|
28050
27743
|
const tabName = toTabName(key);
|
|
28051
|
-
this._files.set(tabName, { doc:
|
|
27744
|
+
this._files.set(tabName, { doc: toDoc(content) });
|
|
28052
27745
|
}
|
|
28053
27746
|
const firstKey = Object.keys(value)[0];
|
|
28054
27747
|
if (firstKey) this.switchToFile(toTabName(firstKey));
|
|
28055
27748
|
this.renderTabs();
|
|
28056
27749
|
}
|
|
27750
|
+
/** Snapshot of all editor state needed to link: sources, conditions, libs, root module. */
|
|
28057
27751
|
get project() {
|
|
28058
27752
|
return {
|
|
28059
27753
|
weslSrc: this.sources,
|
|
@@ -28061,20 +27755,22 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28061
27755
|
conditions: this._conditions,
|
|
28062
27756
|
constants: this._constants,
|
|
28063
27757
|
libs: this._libs,
|
|
28064
|
-
packageName: this._packageName
|
|
27758
|
+
packageName: this._packageName,
|
|
27759
|
+
shaderRoot: this.shaderRoot ?? void 0
|
|
28065
27760
|
};
|
|
28066
27761
|
}
|
|
28067
27762
|
set project(value) {
|
|
28068
27763
|
const { weslSrc, rootModuleName, conditions } = value;
|
|
28069
|
-
const { constants, packageName, libs } = value;
|
|
27764
|
+
const { constants, packageName, libs, shaderRoot } = value;
|
|
28070
27765
|
if (conditions !== void 0) this._conditions = conditions;
|
|
28071
27766
|
if (constants !== void 0) this._constants = constants;
|
|
28072
27767
|
if (packageName !== void 0) this._packageName = packageName;
|
|
28073
27768
|
if (libs !== void 0) this._libs = libs;
|
|
28074
27769
|
if (rootModuleName !== void 0) this._rootModuleName = rootModuleName;
|
|
27770
|
+
if (shaderRoot !== void 0 && !this.hasAttribute("shader-root")) this.shaderRoot = shaderRoot;
|
|
28075
27771
|
if (weslSrc) {
|
|
28076
27772
|
this.sources = weslSrc;
|
|
28077
|
-
const tab = toTabName(
|
|
27773
|
+
const tab = toTabName(this._rootModuleName ?? "");
|
|
28078
27774
|
if (tab) this.activeFile = tab;
|
|
28079
27775
|
}
|
|
28080
27776
|
this.updateLint();
|
|
@@ -28087,14 +27783,13 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28087
27783
|
})).dest;
|
|
28088
27784
|
}
|
|
28089
27785
|
linkParams() {
|
|
28090
|
-
const pkg = this._packageName ?? "package";
|
|
28091
27786
|
return {
|
|
28092
27787
|
weslSrc: this.sources,
|
|
28093
|
-
rootModuleName: this._rootModuleName ??
|
|
27788
|
+
rootModuleName: this._rootModuleName ?? this.activeModulePath(),
|
|
28094
27789
|
conditions: this._conditions,
|
|
28095
27790
|
constants: this._constants,
|
|
28096
27791
|
libs: this._libs,
|
|
28097
|
-
packageName:
|
|
27792
|
+
packageName: this.pkgName()
|
|
28098
27793
|
};
|
|
28099
27794
|
}
|
|
28100
27795
|
get libs() {
|
|
@@ -28150,6 +27845,20 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28150
27845
|
if (!value) this.setAttribute("gpu-lint", "off");
|
|
28151
27846
|
else this.removeAttribute("gpu-lint");
|
|
28152
27847
|
}
|
|
27848
|
+
/** Persist edits to disk via the dev-server save endpoint.
|
|
27849
|
+
* Requires `wgslEditAutosave()` to be installed in vite.config.ts. */
|
|
27850
|
+
get autosave() {
|
|
27851
|
+
return this._devSaveListener !== null;
|
|
27852
|
+
}
|
|
27853
|
+
set autosave(value) {
|
|
27854
|
+
if (value) {
|
|
27855
|
+
this.enableDevSave();
|
|
27856
|
+
this.setAttribute("autosave", "");
|
|
27857
|
+
} else {
|
|
27858
|
+
this.disableDevSave();
|
|
27859
|
+
this.removeAttribute("autosave");
|
|
27860
|
+
}
|
|
27861
|
+
}
|
|
28153
27862
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
28154
27863
|
get fetchLibs() {
|
|
28155
27864
|
return this._fetchLibs;
|
|
@@ -28199,13 +27908,15 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28199
27908
|
if (value) this.setAttribute("shader-root", value);
|
|
28200
27909
|
else this.removeAttribute("shader-root");
|
|
28201
27910
|
}
|
|
27911
|
+
/** Add a new file and switch to it. No-op if `name` already exists. */
|
|
28202
27912
|
addFile(name, content = "") {
|
|
28203
27913
|
if (this._files.has(name)) return;
|
|
28204
|
-
this._files.set(name, { doc:
|
|
27914
|
+
this._files.set(name, { doc: toDoc(content) });
|
|
28205
27915
|
this.switchToFile(name);
|
|
28206
27916
|
this.renderTabs();
|
|
28207
27917
|
this.dispatchFileChange("add", name);
|
|
28208
27918
|
}
|
|
27919
|
+
/** Remove a file. No-op if it is missing or is the last remaining file. */
|
|
28209
27920
|
removeFile(name) {
|
|
28210
27921
|
if (!this._files.has(name) || this._files.size <= 1) return;
|
|
28211
27922
|
this._files.delete(name);
|
|
@@ -28216,6 +27927,7 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28216
27927
|
this.renderTabs();
|
|
28217
27928
|
this.dispatchFileChange("remove", name);
|
|
28218
27929
|
}
|
|
27930
|
+
/** Rename a file, preserving its document and editor state. No-op on collision. */
|
|
28219
27931
|
renameFile(oldName, newName) {
|
|
28220
27932
|
const state = this._files.get(oldName);
|
|
28221
27933
|
if (!state || this._files.has(newName)) return;
|
|
@@ -28231,28 +27943,36 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28231
27943
|
this.saveCurrentFileState();
|
|
28232
27944
|
this._activeFile = name;
|
|
28233
27945
|
const fileState = this._files.get(name);
|
|
28234
|
-
|
|
28235
|
-
|
|
28236
|
-
|
|
28237
|
-
|
|
28238
|
-
|
|
28239
|
-
|
|
28240
|
-
const effects = EditorView.scrollIntoView(fileState.scrollPos ?? 0);
|
|
28241
|
-
this.editorView.dispatch({
|
|
28242
|
-
changes,
|
|
28243
|
-
selection: fileState.selection,
|
|
28244
|
-
effects
|
|
28245
|
-
});
|
|
27946
|
+
const view = this.editorView;
|
|
27947
|
+
if (view) {
|
|
27948
|
+
const state = fileState.state ?? this.createFileState(fileState.doc);
|
|
27949
|
+
fileState.state = state;
|
|
27950
|
+
view.setState(state);
|
|
27951
|
+
if (fileState.scrollPos != null) view.scrollDOM.scrollTop = fileState.scrollPos;
|
|
28246
27952
|
}
|
|
28247
27953
|
this.renderTabs();
|
|
28248
27954
|
}
|
|
27955
|
+
/** Build a fresh EditorState seeded with `doc` and the current extension set. */
|
|
27956
|
+
createFileState(doc) {
|
|
27957
|
+
return EditorState.create({
|
|
27958
|
+
doc,
|
|
27959
|
+
extensions: this.buildExtensions()
|
|
27960
|
+
});
|
|
27961
|
+
}
|
|
28249
27962
|
saveCurrentFileState() {
|
|
28250
27963
|
const view = this.editorView;
|
|
28251
|
-
const
|
|
28252
|
-
if (!view || !
|
|
28253
|
-
state
|
|
28254
|
-
|
|
28255
|
-
|
|
27964
|
+
const fileState = this._activeFile ? this._files.get(this._activeFile) : void 0;
|
|
27965
|
+
if (!view || !fileState) return;
|
|
27966
|
+
fileState.state = view.state;
|
|
27967
|
+
fileState.doc = view.state.doc;
|
|
27968
|
+
fileState.selection = view.state.selection;
|
|
27969
|
+
fileState.scrollPos = view.scrollDOM.scrollTop;
|
|
27970
|
+
}
|
|
27971
|
+
pkgName() {
|
|
27972
|
+
return this._packageName ?? "package";
|
|
27973
|
+
}
|
|
27974
|
+
activeModulePath() {
|
|
27975
|
+
return fileToModulePath(this._activeFile, this.pkgName(), false);
|
|
28256
27976
|
}
|
|
28257
27977
|
dispatchChange() {
|
|
28258
27978
|
this.dispatchEvent(new CustomEvent("change", { detail: this.project }));
|
|
@@ -28264,25 +27984,86 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28264
27984
|
};
|
|
28265
27985
|
this.dispatchEvent(new CustomEvent("file-change", { detail }));
|
|
28266
27986
|
}
|
|
27987
|
+
scheduleAutosave() {
|
|
27988
|
+
this._dirtyFiles.add(this._activeFile);
|
|
27989
|
+
clearTimeout(this._saveTimer);
|
|
27990
|
+
this._saveTimer = setTimeout(() => this.fireAutosave(), 500);
|
|
27991
|
+
}
|
|
27992
|
+
/** Dispatch an `autosave` event with a fresh project snapshot and the dirty-file list. */
|
|
27993
|
+
fireAutosave() {
|
|
27994
|
+
const dirty = [...this._dirtyFiles];
|
|
27995
|
+
this._dirtyFiles.clear();
|
|
27996
|
+
const detail = {
|
|
27997
|
+
project: this.project,
|
|
27998
|
+
dirty
|
|
27999
|
+
};
|
|
28000
|
+
this.dispatchEvent(new CustomEvent("autosave", { detail }));
|
|
28001
|
+
}
|
|
28002
|
+
enableDevSave() {
|
|
28003
|
+
if (this._devSaveListener) return;
|
|
28004
|
+
this._devSaveListener = (e) => this.devSave(e);
|
|
28005
|
+
this.addEventListener("autosave", this._devSaveListener);
|
|
28006
|
+
}
|
|
28007
|
+
disableDevSave() {
|
|
28008
|
+
if (!this._devSaveListener) return;
|
|
28009
|
+
this.removeEventListener("autosave", this._devSaveListener);
|
|
28010
|
+
this._devSaveListener = null;
|
|
28011
|
+
}
|
|
28012
|
+
/** Built-in `autosave` listener: POST each dirty file to the dev-server save endpoint. */
|
|
28013
|
+
async devSave(e) {
|
|
28014
|
+
const root = this.shaderRoot;
|
|
28015
|
+
if (!root) return;
|
|
28016
|
+
const { project, dirty } = e.detail;
|
|
28017
|
+
const weslSrc = project.weslSrc;
|
|
28018
|
+
if (!weslSrc) return;
|
|
28019
|
+
const pkg = this.pkgName();
|
|
28020
|
+
for (const file of dirty) {
|
|
28021
|
+
const content = weslSrc[fileToModulePath(file, pkg, false)];
|
|
28022
|
+
if (content === void 0) continue;
|
|
28023
|
+
try {
|
|
28024
|
+
const res = await fetch(saveEndpoint, {
|
|
28025
|
+
method: "POST",
|
|
28026
|
+
headers: { "Content-Type": "application/json" },
|
|
28027
|
+
body: JSON.stringify({
|
|
28028
|
+
root,
|
|
28029
|
+
file,
|
|
28030
|
+
content
|
|
28031
|
+
})
|
|
28032
|
+
});
|
|
28033
|
+
if (!res.ok) return this.devSaveFailed(`HTTP ${res.status}`);
|
|
28034
|
+
} catch (err) {
|
|
28035
|
+
return this.devSaveFailed(err instanceof Error ? err.message : String(err));
|
|
28036
|
+
}
|
|
28037
|
+
}
|
|
28038
|
+
}
|
|
28039
|
+
/** One-shot disable on first failure: avoids spamming the console on every keystroke. */
|
|
28040
|
+
devSaveFailed(reason) {
|
|
28041
|
+
this.disableDevSave();
|
|
28042
|
+
console.error(`wgsl-edit: autosave disabled (${reason}). Make sure wgslEditAutosave() is installed in vite.config.ts.`);
|
|
28043
|
+
}
|
|
28044
|
+
/** First-time setup: read attributes, parse inline content, mount the EditorView. */
|
|
28267
28045
|
initEditor() {
|
|
28268
28046
|
this.readInitialAttributes();
|
|
28269
28047
|
this.parseInlineContent();
|
|
28270
28048
|
this._mediaQuery = matchMedia("(prefers-color-scheme: dark)");
|
|
28271
28049
|
this._mediaQuery.addEventListener("change", () => this.updateTheme());
|
|
28272
28050
|
const firstFile = this._files.keys().next().value;
|
|
28273
|
-
const
|
|
28051
|
+
const firstDoc = firstFile && this._files.get(firstFile).doc.toString();
|
|
28052
|
+
const initialDoc = this._pendingSource ?? firstDoc ?? "";
|
|
28274
28053
|
this._pendingSource = null;
|
|
28275
28054
|
if (firstFile) this._activeFile = firstFile;
|
|
28276
28055
|
else if (initialDoc) {
|
|
28277
|
-
this._files.set("main.wesl", { doc:
|
|
28056
|
+
this._files.set("main.wesl", { doc: toDoc(initialDoc) });
|
|
28278
28057
|
this._activeFile = "main.wesl";
|
|
28279
28058
|
}
|
|
28280
|
-
const
|
|
28059
|
+
const state = this.createFileState(initialDoc);
|
|
28060
|
+
const active = this._activeFile ? this._files.get(this._activeFile) : null;
|
|
28061
|
+
if (active) {
|
|
28062
|
+
active.state = state;
|
|
28063
|
+
active.doc = state.doc;
|
|
28064
|
+
}
|
|
28281
28065
|
this.editorView = new EditorView({
|
|
28282
|
-
state
|
|
28283
|
-
doc: initialDoc,
|
|
28284
|
-
extensions
|
|
28285
|
-
}),
|
|
28066
|
+
state,
|
|
28286
28067
|
parent: this.editorContainer
|
|
28287
28068
|
});
|
|
28288
28069
|
this.renderTabs();
|
|
@@ -28299,6 +28080,7 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28299
28080
|
const lintFromAttr = this.getAttribute("lint-from");
|
|
28300
28081
|
if (lintFromAttr) this.connectLintSource(lintFromAttr);
|
|
28301
28082
|
}
|
|
28083
|
+
/** Assemble the full CodeMirror extension set for a fresh EditorState. */
|
|
28302
28084
|
buildExtensions() {
|
|
28303
28085
|
const baseTheme = EditorView.theme({
|
|
28304
28086
|
".cm-content": { padding: "0" },
|
|
@@ -28343,6 +28125,7 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28343
28125
|
this._externalDiagnostics = [];
|
|
28344
28126
|
this.saveCurrentFileState();
|
|
28345
28127
|
this.dispatchChange();
|
|
28128
|
+
if (!this._switchingFile) this.scheduleAutosave();
|
|
28346
28129
|
}
|
|
28347
28130
|
})
|
|
28348
28131
|
];
|
|
@@ -28353,11 +28136,11 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28353
28136
|
return [EditorView.theme({}, { dark: isDark }), isDark ? darkColors : lightColors];
|
|
28354
28137
|
}
|
|
28355
28138
|
updateTheme() {
|
|
28356
|
-
this.
|
|
28139
|
+
this.reconfigure(this.themeCompartment, this.resolveTheme());
|
|
28357
28140
|
}
|
|
28358
28141
|
updateReadonly() {
|
|
28359
28142
|
const ext = EditorState.readOnly.of(this.readonly);
|
|
28360
|
-
this.
|
|
28143
|
+
this.reconfigure(this.readonlyCompartment, ext);
|
|
28361
28144
|
this.renderTabs();
|
|
28362
28145
|
}
|
|
28363
28146
|
resolveLint() {
|
|
@@ -28365,7 +28148,7 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28365
28148
|
const useGpuLint = this._gpuLint && !this._lintFromEl;
|
|
28366
28149
|
return createWeslLinter({
|
|
28367
28150
|
getSources: () => this.sources,
|
|
28368
|
-
rootModule: () =>
|
|
28151
|
+
rootModule: () => this.activeModulePath(),
|
|
28369
28152
|
conditions: () => this._conditions,
|
|
28370
28153
|
packageName: () => this._packageName,
|
|
28371
28154
|
getExternalDiagnostics: () => this._externalDiagnostics,
|
|
@@ -28378,11 +28161,8 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28378
28161
|
/** Link WESL->WGSL and validate via WebGPU, returning CodeMirror diagnostics. */
|
|
28379
28162
|
async gpuValidate() {
|
|
28380
28163
|
const { validateWgsl } = await import("./GpuValidator-D88-VTq9.js");
|
|
28381
|
-
const
|
|
28382
|
-
|
|
28383
|
-
const messages = await validateWgsl(linked.dest);
|
|
28384
|
-
const pkg = params.packageName ?? "package";
|
|
28385
|
-
return mapGpuDiagnostics(messages, linked, this._activeFile, pkg);
|
|
28164
|
+
const linked = await link(this.linkParams());
|
|
28165
|
+
return mapGpuDiagnostics(await validateWgsl(linked.dest), linked, this._activeFile, this.pkgName());
|
|
28386
28166
|
}
|
|
28387
28167
|
/** Fetch missing library packages, deduplicating in-flight requests. */
|
|
28388
28168
|
async fetchLibsOnDemand(names) {
|
|
@@ -28409,14 +28189,15 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28409
28189
|
}
|
|
28410
28190
|
}
|
|
28411
28191
|
updateLint() {
|
|
28412
|
-
this.
|
|
28192
|
+
this.reconfigure(this.lintCompartment, this.resolveLint());
|
|
28413
28193
|
}
|
|
28414
28194
|
/** Listen for compile-error/compile-success events from a lint source element. */
|
|
28415
28195
|
connectLintSource(id) {
|
|
28416
28196
|
const hadExternal = !!this._lintFromEl;
|
|
28417
|
-
|
|
28418
|
-
|
|
28419
|
-
|
|
28197
|
+
const prev = this._lintFromEl;
|
|
28198
|
+
if (prev) {
|
|
28199
|
+
prev.removeEventListener("compile-error", this._boundCompileError);
|
|
28200
|
+
prev.removeEventListener("compile-success", this._boundCompileSuccess);
|
|
28420
28201
|
this._lintFromEl = null;
|
|
28421
28202
|
}
|
|
28422
28203
|
this._externalDiagnostics = [];
|
|
@@ -28428,23 +28209,24 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28428
28209
|
}
|
|
28429
28210
|
if (hadExternal !== !!this._lintFromEl) this.updateLint();
|
|
28430
28211
|
}
|
|
28212
|
+
/** Convert external compile-error locations into CodeMirror diagnostics for the active file. */
|
|
28431
28213
|
onCompileError(e) {
|
|
28432
28214
|
const detail = e.detail;
|
|
28433
28215
|
if (!this.editorView || detail.source === "wesl") return;
|
|
28434
28216
|
const doc = this.editorView.state.doc;
|
|
28435
|
-
const pkg = this.
|
|
28436
|
-
const activeModule =
|
|
28437
|
-
|
|
28438
|
-
|
|
28439
|
-
return fileToModulePath(loc.file, pkg, false) === activeModule;
|
|
28440
|
-
}).map((loc) => {
|
|
28217
|
+
const pkg = this.pkgName();
|
|
28218
|
+
const activeModule = this.activeModulePath();
|
|
28219
|
+
const inActiveFile = (loc) => !loc.file || fileToModulePath(loc.file, pkg, false) === activeModule;
|
|
28220
|
+
this._externalDiagnostics = detail.locations.filter(inActiveFile).map((loc) => {
|
|
28441
28221
|
const line = doc.line(Math.max(1, Math.min(loc.line, doc.lines)));
|
|
28442
28222
|
const from = Math.min(line.from + (loc.column ?? 0), doc.length);
|
|
28223
|
+
const to = Math.min(from + (loc.length ?? 1), doc.length);
|
|
28224
|
+
const { severity, message } = loc;
|
|
28443
28225
|
return {
|
|
28444
28226
|
from,
|
|
28445
|
-
to
|
|
28446
|
-
severity
|
|
28447
|
-
message
|
|
28227
|
+
to,
|
|
28228
|
+
severity,
|
|
28229
|
+
message,
|
|
28448
28230
|
source: "WebGPU"
|
|
28449
28231
|
};
|
|
28450
28232
|
});
|
|
@@ -28459,21 +28241,20 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28459
28241
|
return this._lineNumbers ? [] : EditorView.theme({ ".cm-gutters": { display: "none" } });
|
|
28460
28242
|
}
|
|
28461
28243
|
updateLineNumbers() {
|
|
28462
|
-
|
|
28463
|
-
this.editorView?.dispatch({ effects: this.lineNumbersCompartment.reconfigure(ext) });
|
|
28244
|
+
this.reconfigure(this.lineNumbersCompartment, this.resolveLineNumbers());
|
|
28464
28245
|
}
|
|
28465
28246
|
/** Parse script tags into _files. Supports single or multi-file via data-name. */
|
|
28466
28247
|
parseInlineContent() {
|
|
28467
28248
|
const scripts = Array.from(this.querySelectorAll("script[type=\"text/wgsl\"], script[type=\"text/wesl\"]"));
|
|
28468
28249
|
if (scripts.length === 0) {
|
|
28469
28250
|
const content = this.textContent?.trim() ?? "";
|
|
28470
|
-
if (content) this._files.set("main.wesl", { doc:
|
|
28251
|
+
if (content) this._files.set("main.wesl", { doc: toDoc(content) });
|
|
28471
28252
|
return;
|
|
28472
28253
|
}
|
|
28473
28254
|
for (const script of scripts) {
|
|
28474
28255
|
const name = script.getAttribute("data-name") || "main.wesl";
|
|
28475
28256
|
const content = script.textContent?.trim() ?? "";
|
|
28476
|
-
this._files.set(name, { doc:
|
|
28257
|
+
this._files.set(name, { doc: toDoc(content) });
|
|
28477
28258
|
}
|
|
28478
28259
|
}
|
|
28479
28260
|
renderTabs() {
|
|
@@ -28518,28 +28299,27 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28518
28299
|
});
|
|
28519
28300
|
return btn;
|
|
28520
28301
|
}
|
|
28302
|
+
/** Replace the tab name span with an editable input; commit on Enter/blur, cancel on Escape. */
|
|
28521
28303
|
startRenameTab(tab, nameSpan, oldName) {
|
|
28522
28304
|
const input = document.createElement("input");
|
|
28523
28305
|
input.className = "tab-rename";
|
|
28524
28306
|
input.value = oldName;
|
|
28525
28307
|
input.size = Math.max(oldName.length, 8);
|
|
28308
|
+
const cancelRename = () => {
|
|
28309
|
+
nameSpan.style.display = "";
|
|
28310
|
+
input.remove();
|
|
28311
|
+
};
|
|
28526
28312
|
const finishRename = () => {
|
|
28527
28313
|
const newName = input.value.trim() || oldName;
|
|
28528
28314
|
if (newName !== oldName && !this._files.has(newName)) this.renameFile(oldName, newName);
|
|
28529
|
-
else
|
|
28530
|
-
nameSpan.style.display = "";
|
|
28531
|
-
input.remove();
|
|
28532
|
-
}
|
|
28315
|
+
else cancelRename();
|
|
28533
28316
|
};
|
|
28534
28317
|
input.addEventListener("keydown", (e) => {
|
|
28535
28318
|
if (e.key === "Enter") {
|
|
28536
28319
|
e.preventDefault();
|
|
28537
28320
|
finishRename();
|
|
28538
28321
|
}
|
|
28539
|
-
if (e.key === "Escape")
|
|
28540
|
-
nameSpan.style.display = "";
|
|
28541
|
-
input.remove();
|
|
28542
|
-
}
|
|
28322
|
+
if (e.key === "Escape") cancelRename();
|
|
28543
28323
|
});
|
|
28544
28324
|
input.addEventListener("blur", finishRename);
|
|
28545
28325
|
input.addEventListener("input", () => {
|
|
@@ -28567,6 +28347,7 @@ var WgslEdit = class extends HTMLElement {
|
|
|
28567
28347
|
if (src) this.loadFromUrl(src);
|
|
28568
28348
|
}
|
|
28569
28349
|
};
|
|
28350
|
+
/** Build a CodeMirror highlight style from a WESL color palette. */
|
|
28570
28351
|
function weslColors(c) {
|
|
28571
28352
|
return syntaxHighlighting(HighlightStyle.define([
|
|
28572
28353
|
{
|
|
@@ -28634,24 +28415,7 @@ function weslColors(c) {
|
|
|
28634
28415
|
fontStyle: "normal"
|
|
28635
28416
|
} }));
|
|
28636
28417
|
}
|
|
28637
|
-
/**
|
|
28638
|
-
function mapGpuDiagnostics(messages, linked, activeFile, pkg) {
|
|
28639
|
-
const { sourceMap } = linked;
|
|
28640
|
-
const active = fileToModulePath(activeFile, pkg, false);
|
|
28641
|
-
return messages.flatMap((msg) => {
|
|
28642
|
-
const srcPos = sourceMap.destToSrc(msg.offset);
|
|
28643
|
-
if ((srcPos.src.path ? fileToModulePath(srcPos.src.path, pkg, false) : null) !== active) return [];
|
|
28644
|
-
const endPos = sourceMap.destToSrc(msg.offset + msg.length);
|
|
28645
|
-
const from = srcPos.position;
|
|
28646
|
-
return {
|
|
28647
|
-
from,
|
|
28648
|
-
to: endPos.position > from ? endPos.position : from + 1,
|
|
28649
|
-
severity: msg.severity,
|
|
28650
|
-
message: msg.message,
|
|
28651
|
-
source: "WebGPU"
|
|
28652
|
-
};
|
|
28653
|
-
});
|
|
28654
|
-
}
|
|
28418
|
+
/** Lazily build and cache the shared component stylesheet. */
|
|
28655
28419
|
function getStyles() {
|
|
28656
28420
|
if (!cachedStyleSheet) {
|
|
28657
28421
|
cachedStyleSheet = new CSSStyleSheet();
|
|
@@ -28659,7 +28423,8 @@ function getStyles() {
|
|
|
28659
28423
|
}
|
|
28660
28424
|
return cachedStyleSheet;
|
|
28661
28425
|
}
|
|
28662
|
-
/** Absorb instance properties set before custom element upgrade.
|
|
28426
|
+
/** Absorb instance properties set before custom element upgrade.
|
|
28427
|
+
* Duplicated in WgslPlay.ts. Later, extract to a shared package. */
|
|
28663
28428
|
function upgradeProperty(el, prop) {
|
|
28664
28429
|
if (Object.hasOwn(el, prop)) {
|
|
28665
28430
|
const value = el[prop];
|
|
@@ -28667,11 +28432,36 @@ function upgradeProperty(el, prop) {
|
|
|
28667
28432
|
el[prop] = value;
|
|
28668
28433
|
}
|
|
28669
28434
|
}
|
|
28435
|
+
/** Build a CodeMirror Text doc from a string. */
|
|
28436
|
+
function toDoc(s) {
|
|
28437
|
+
return Text.of(s.split("\n"));
|
|
28438
|
+
}
|
|
28670
28439
|
/** Convert a module path or file path to a tab name: "package::main" -> "main", "main.wesl" -> "main.wesl" */
|
|
28671
28440
|
function toTabName(key) {
|
|
28672
28441
|
if (key.includes("::")) return key.replace(/^[^:]+::/, "").replaceAll("::", "/");
|
|
28673
28442
|
return key.replace(/^\.\//, "");
|
|
28674
28443
|
}
|
|
28444
|
+
/** Map GPU validation messages back to source positions via the source map. */
|
|
28445
|
+
function mapGpuDiagnostics(messages, linked, activeFile, pkg) {
|
|
28446
|
+
const { sourceMap } = linked;
|
|
28447
|
+
const active = fileToModulePath(activeFile, pkg, false);
|
|
28448
|
+
return messages.flatMap((msg) => {
|
|
28449
|
+
const srcPos = sourceMap.destToSrc(msg.offset);
|
|
28450
|
+
const path = srcPos.src.path;
|
|
28451
|
+
if ((path ? fileToModulePath(path, pkg, false) : null) !== active) return [];
|
|
28452
|
+
const endPos = sourceMap.destToSrc(msg.offset + msg.length);
|
|
28453
|
+
const from = srcPos.position;
|
|
28454
|
+
const to = endPos.position > from ? endPos.position : from + 1;
|
|
28455
|
+
const { severity, message } = msg;
|
|
28456
|
+
return {
|
|
28457
|
+
from,
|
|
28458
|
+
to,
|
|
28459
|
+
severity,
|
|
28460
|
+
message,
|
|
28461
|
+
source: "WebGPU"
|
|
28462
|
+
};
|
|
28463
|
+
});
|
|
28464
|
+
}
|
|
28675
28465
|
//#endregion
|
|
28676
28466
|
//#region src/index.ts
|
|
28677
28467
|
if (!customElements.get("wgsl-edit")) customElements.define("wgsl-edit", WgslEdit);
|