wgsl-play 0.0.37 → 0.0.38
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 +7 -5
- package/dist/{WgslPlay-DZgeJ1h6.js → WgslPlay-BuIuE3cB.js} +39 -55
- package/dist/{WgslPlay-B86UkrM7.d.ts → WgslPlay-uTIOrTQq.d.ts} +10 -11
- package/dist/WgslPlay.d.ts +2 -2
- package/dist/WgslPlay.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/wgsl-play.js +45 -60
- package/package.json +4 -4
- package/src/WgslPlay.ts +43 -72
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ You can include shader code inline if you'd prefer. Use a `<script type="text/wg
|
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
58
|
const player = document.querySelector("wgsl-play");
|
|
59
|
-
player.
|
|
59
|
+
player.shader = shaderCode;
|
|
60
60
|
player.pause();
|
|
61
61
|
player.rewind();
|
|
62
62
|
player.play();
|
|
@@ -68,7 +68,7 @@ player.play();
|
|
|
68
68
|
import shader from './examples/noise.wesl?raw';
|
|
69
69
|
|
|
70
70
|
const player = document.querySelector("wgsl-play");
|
|
71
|
-
player.
|
|
71
|
+
player.shader = shader;
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
The `?raw` suffix imports the file as a string. This keeps shaders alongside your source files with HMR support.
|
|
@@ -80,12 +80,14 @@ The `?raw` suffix imports the file as a string. This keeps shaders alongside you
|
|
|
80
80
|
- `shader-root` - Root path for internal imports (default: `/shaders`)
|
|
81
81
|
- `autoplay` - Start animating on load (default: `true`). Set `autoplay="false"` to start paused
|
|
82
82
|
- `transparent` - Use premultiplied alpha for transparent backgrounds (default: opaque)
|
|
83
|
+
- `from` - Element ID of a source provider (e.g., wgsl-edit) to connect to
|
|
83
84
|
- `fetch-libs` - Auto-fetch missing libraries from npm (default: `true`). Set `fetch-libs="false"` to disable
|
|
85
|
+
- `fetch-sources` - Auto-fetch local .wesl source files via HTTP (default: `true`). Set `fetch-sources="false"` to disable
|
|
84
86
|
|
|
85
87
|
### Properties
|
|
86
|
-
- `
|
|
88
|
+
- `shader: string` - Get/set shader source (single-file convenience)
|
|
87
89
|
- `conditions: Record<string, boolean>` - Get/set conditions for conditional compilation (`@if`/`@elif`/`@else`)
|
|
88
|
-
- `project: WeslProject` -
|
|
90
|
+
- `project: WeslProject` - Get/set full project config (weslSrc, libs, conditions, constants)
|
|
89
91
|
- `isPlaying: boolean` - Playback state (readonly)
|
|
90
92
|
- `time: number` - Animation time in seconds (readonly)
|
|
91
93
|
- `hasError: boolean` - Compilation error state (readonly)
|
|
@@ -147,7 +149,7 @@ import super::common::tint;
|
|
|
147
149
|
|
|
148
150
|
## Using with wesl-plugin
|
|
149
151
|
|
|
150
|
-
For more control, use the [wesl-plugin](https://github.com/wgsl-tooling-wg/wesl-js/tree/main/
|
|
152
|
+
For more control, use the [wesl-plugin](https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/wesl-plugin) to
|
|
151
153
|
assemble shaders and libraries at build time and provide
|
|
152
154
|
them wgsl-play in JavaScript or TypeScript.
|
|
153
155
|
- provides full support for Hot Module Reloading during development
|
|
@@ -204,12 +204,13 @@ var WgslPlay = class extends HTMLElement {
|
|
|
204
204
|
static observedAttributes = [
|
|
205
205
|
"src",
|
|
206
206
|
"shader-root",
|
|
207
|
-
"
|
|
207
|
+
"from",
|
|
208
208
|
"no-controls",
|
|
209
209
|
"theme",
|
|
210
210
|
"autoplay",
|
|
211
211
|
"transparent",
|
|
212
|
-
"fetch-libs"
|
|
212
|
+
"fetch-libs",
|
|
213
|
+
"fetch-sources"
|
|
213
214
|
];
|
|
214
215
|
canvas;
|
|
215
216
|
errorOverlay;
|
|
@@ -226,7 +227,7 @@ var WgslPlay = class extends HTMLElement {
|
|
|
226
227
|
_rootModuleName = "package::main";
|
|
227
228
|
_libs;
|
|
228
229
|
_linkOptions = {};
|
|
229
|
-
|
|
230
|
+
_fetchSources = true;
|
|
230
231
|
_initPromise;
|
|
231
232
|
_sourceEl = null;
|
|
232
233
|
_sourceListener = null;
|
|
@@ -274,7 +275,7 @@ var WgslPlay = class extends HTMLElement {
|
|
|
274
275
|
}
|
|
275
276
|
this.initialize();
|
|
276
277
|
upgradeProperty(this, "conditions");
|
|
277
|
-
upgradeProperty(this, "
|
|
278
|
+
upgradeProperty(this, "shader");
|
|
278
279
|
upgradeProperty(this, "project");
|
|
279
280
|
}
|
|
280
281
|
disconnectedCallback() {
|
|
@@ -302,17 +303,20 @@ var WgslPlay = class extends HTMLElement {
|
|
|
302
303
|
this._fetchLibs = newValue !== "false";
|
|
303
304
|
return;
|
|
304
305
|
}
|
|
306
|
+
if (name === "fetch-sources") {
|
|
307
|
+
this._fetchSources = newValue !== "false";
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
305
310
|
if (name === "src" && newValue && this._initPromise) this.loadFromUrl(newValue);
|
|
306
311
|
}
|
|
307
312
|
/** Current shader source code (main module). */
|
|
308
|
-
get
|
|
313
|
+
get shader() {
|
|
309
314
|
return this._weslSrc[this._rootModuleName] ?? "";
|
|
310
315
|
}
|
|
311
|
-
/** Set shader source directly. */
|
|
312
|
-
set
|
|
316
|
+
/** Set shader source directly (single-file convenience). */
|
|
317
|
+
set shader(value) {
|
|
313
318
|
this._weslSrc = { [this._rootModuleName]: value };
|
|
314
319
|
this._libs = void 0;
|
|
315
|
-
this._fromFullProject = false;
|
|
316
320
|
this.requestBuild();
|
|
317
321
|
}
|
|
318
322
|
/** Conditions for conditional compilation (@if/@elif/@else). */
|
|
@@ -330,28 +334,21 @@ var WgslPlay = class extends HTMLElement {
|
|
|
330
334
|
/** Set project configuration (mirrors wesl link() API). */
|
|
331
335
|
set project(value) {
|
|
332
336
|
const { weslSrc, rootModuleName, libs, packageName, conditions, constants } = value;
|
|
333
|
-
if (packageName
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
constants
|
|
337
|
-
};
|
|
337
|
+
if (packageName !== void 0) this._linkOptions.packageName = packageName;
|
|
338
|
+
if (conditions !== void 0) this._linkOptions.conditions = conditions;
|
|
339
|
+
if (constants !== void 0) this._linkOptions.constants = constants;
|
|
338
340
|
if (libs) this._libs = libs;
|
|
339
341
|
if (weslSrc) {
|
|
340
|
-
this.
|
|
342
|
+
const pkg = this._linkOptions.packageName || "package";
|
|
343
|
+
const root = rootModuleName ?? "main";
|
|
344
|
+
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
345
|
+
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
346
|
+
this.requestBuild();
|
|
341
347
|
return;
|
|
342
348
|
}
|
|
343
349
|
if (Object.keys(this._weslSrc).length === 0) return;
|
|
344
350
|
this.requestBuild();
|
|
345
351
|
}
|
|
346
|
-
/** Set sources from a full project with weslSrc. */
|
|
347
|
-
setProjectSources(weslSrc, rootModuleName) {
|
|
348
|
-
const pkg = this._linkOptions.packageName || "package";
|
|
349
|
-
const root = rootModuleName ?? "main";
|
|
350
|
-
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
351
|
-
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
352
|
-
this._fromFullProject = true;
|
|
353
|
-
this.requestBuild();
|
|
354
|
-
}
|
|
355
352
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
356
353
|
get fetchLibs() {
|
|
357
354
|
return this._fetchLibs;
|
|
@@ -361,6 +358,15 @@ var WgslPlay = class extends HTMLElement {
|
|
|
361
358
|
if (value) this.removeAttribute("fetch-libs");
|
|
362
359
|
else this.setAttribute("fetch-libs", "false");
|
|
363
360
|
}
|
|
361
|
+
/** Whether to fetch local .wesl source files via HTTP (default: true). */
|
|
362
|
+
get fetchSources() {
|
|
363
|
+
return this._fetchSources;
|
|
364
|
+
}
|
|
365
|
+
set fetchSources(value) {
|
|
366
|
+
this._fetchSources = value;
|
|
367
|
+
if (value) this.removeAttribute("fetch-sources");
|
|
368
|
+
else this.setAttribute("fetch-sources", "false");
|
|
369
|
+
}
|
|
364
370
|
/** Whether autoplay is enabled (default: true). Set autoplay="false" to start paused. */
|
|
365
371
|
get autoplay() {
|
|
366
372
|
return this.getAttribute("autoplay") !== "false";
|
|
@@ -456,9 +462,9 @@ var WgslPlay = class extends HTMLElement {
|
|
|
456
462
|
}
|
|
457
463
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
458
464
|
loadInitialContent() {
|
|
459
|
-
const
|
|
460
|
-
if (
|
|
461
|
-
this.
|
|
465
|
+
const fromId = this.getAttribute("from");
|
|
466
|
+
if (fromId) {
|
|
467
|
+
this.connectFrom(fromId);
|
|
462
468
|
return;
|
|
463
469
|
}
|
|
464
470
|
const src = this.getAttribute("src");
|
|
@@ -469,43 +475,21 @@ var WgslPlay = class extends HTMLElement {
|
|
|
469
475
|
const inlineSource = this.querySelector("script[type=\"text/wgsl\"], script[type=\"text/wesl\"]")?.textContent?.trim() ?? this.textContent?.trim();
|
|
470
476
|
if (!inlineSource) return;
|
|
471
477
|
this._weslSrc = { [this._rootModuleName]: inlineSource };
|
|
472
|
-
this._fromFullProject = false;
|
|
473
478
|
this.requestBuild();
|
|
474
479
|
}
|
|
475
480
|
/** Connect to a source provider element (e.g., wgsl-edit). */
|
|
476
|
-
|
|
481
|
+
connectFrom(id) {
|
|
477
482
|
const el = document.getElementById(id);
|
|
478
483
|
if (!el) {
|
|
479
484
|
console.error(`wgsl-play: source element "${id}" not found`);
|
|
480
485
|
return;
|
|
481
486
|
}
|
|
482
487
|
this._sourceEl = el;
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
if (sources && Object.keys(sources).length > 0) return sources;
|
|
486
|
-
const source = el.source ?? el.textContent ?? "";
|
|
487
|
-
return { [this._rootModuleName]: source };
|
|
488
|
-
};
|
|
489
|
-
const { conditions, rootModuleName, libs } = el;
|
|
490
|
-
const root = rootModuleName ?? "main";
|
|
491
|
-
this._weslSrc = getSources();
|
|
492
|
-
this._rootModuleName = fileToModulePath(root, "package", false);
|
|
493
|
-
if (conditions) this._linkOptions = {
|
|
494
|
-
...this._linkOptions,
|
|
495
|
-
conditions
|
|
496
|
-
};
|
|
497
|
-
if (libs) this._libs = libs;
|
|
498
|
-
this._fromFullProject = false;
|
|
499
|
-
this.requestBuild();
|
|
488
|
+
const p = el.project;
|
|
489
|
+
if (p) this.project = p;
|
|
500
490
|
this._sourceListener = (e) => {
|
|
501
491
|
const detail = e.detail;
|
|
502
|
-
|
|
503
|
-
this.project = {
|
|
504
|
-
weslSrc: detail?.sources ?? fallback,
|
|
505
|
-
rootModuleName: detail?.rootModuleName,
|
|
506
|
-
conditions: detail?.conditions,
|
|
507
|
-
libs: detail?.libs
|
|
508
|
-
};
|
|
492
|
+
if (detail) this.project = detail;
|
|
509
493
|
};
|
|
510
494
|
el.addEventListener("change", this._sourceListener);
|
|
511
495
|
}
|
|
@@ -515,7 +499,6 @@ var WgslPlay = class extends HTMLElement {
|
|
|
515
499
|
const { weslSrc, libs, rootModuleName } = await loadShaderFromUrl(url, this.getConfigOverrides()?.shaderRoot);
|
|
516
500
|
this._weslSrc = weslSrc;
|
|
517
501
|
this._libs = libs;
|
|
518
|
-
this._fromFullProject = false;
|
|
519
502
|
if (rootModuleName) this._rootModuleName = rootModuleName;
|
|
520
503
|
this.requestBuild();
|
|
521
504
|
} catch (error) {
|
|
@@ -540,11 +523,12 @@ var WgslPlay = class extends HTMLElement {
|
|
|
540
523
|
}
|
|
541
524
|
try {
|
|
542
525
|
this.errorOverlay.hide();
|
|
543
|
-
if (
|
|
526
|
+
if (this._fetchSources || this._fetchLibs) {
|
|
544
527
|
const { weslSrc, libs } = await fetchDependencies(mainSource, {
|
|
545
528
|
shaderRoot: this.getConfigOverrides()?.shaderRoot,
|
|
546
529
|
existingSources: this._weslSrc,
|
|
547
|
-
|
|
530
|
+
fetchLibs: this._fetchLibs,
|
|
531
|
+
fetchSources: this._fetchSources
|
|
548
532
|
});
|
|
549
533
|
this._weslSrc = {
|
|
550
534
|
...this._weslSrc,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Conditions,
|
|
1
|
+
import { Conditions, WeslProject } from "wesl";
|
|
2
2
|
|
|
3
3
|
//#region src/Config.d.ts
|
|
4
4
|
/** Configuration for wgsl-play. */
|
|
@@ -14,8 +14,6 @@ declare function getConfig(overrides?: Partial<WgslPlayConfig>): WgslPlayConfig;
|
|
|
14
14
|
declare function resetConfig(): void;
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/WgslPlay.d.ts
|
|
17
|
-
/** Project configuration for multi-file shaders (subset of wesl link() API). */
|
|
18
|
-
type WeslProject = Pick<LinkParams, "weslSrc" | "rootModuleName" | "conditions" | "constants" | "libs" | "packageName">;
|
|
19
17
|
/** One source location within a compile error. */
|
|
20
18
|
interface CompileErrorLocation {
|
|
21
19
|
file?: string;
|
|
@@ -45,7 +43,7 @@ declare class WgslPlay extends HTMLElement {
|
|
|
45
43
|
private _rootModuleName;
|
|
46
44
|
private _libs?;
|
|
47
45
|
private _linkOptions;
|
|
48
|
-
private
|
|
46
|
+
private _fetchSources;
|
|
49
47
|
private _initPromise?;
|
|
50
48
|
private _sourceEl;
|
|
51
49
|
private _sourceListener;
|
|
@@ -62,19 +60,20 @@ declare class WgslPlay extends HTMLElement {
|
|
|
62
60
|
disconnectedCallback(): void;
|
|
63
61
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
64
62
|
/** Current shader source code (main module). */
|
|
65
|
-
get
|
|
66
|
-
/** Set shader source directly. */
|
|
67
|
-
set
|
|
63
|
+
get shader(): string;
|
|
64
|
+
/** Set shader source directly (single-file convenience). */
|
|
65
|
+
set shader(value: string);
|
|
68
66
|
/** Conditions for conditional compilation (@if/@elif/@else). */
|
|
69
67
|
get conditions(): Conditions;
|
|
70
68
|
set conditions(value: Conditions);
|
|
71
69
|
/** Set project configuration (mirrors wesl link() API). */
|
|
72
70
|
set project(value: WeslProject);
|
|
73
|
-
/** Set sources from a full project with weslSrc. */
|
|
74
|
-
private setProjectSources;
|
|
75
71
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
76
72
|
get fetchLibs(): boolean;
|
|
77
73
|
set fetchLibs(value: boolean);
|
|
74
|
+
/** Whether to fetch local .wesl source files via HTTP (default: true). */
|
|
75
|
+
get fetchSources(): boolean;
|
|
76
|
+
set fetchSources(value: boolean);
|
|
78
77
|
/** Whether autoplay is enabled (default: true). Set autoplay="false" to start paused. */
|
|
79
78
|
get autoplay(): boolean;
|
|
80
79
|
set autoplay(value: boolean | string);
|
|
@@ -106,7 +105,7 @@ declare class WgslPlay extends HTMLElement {
|
|
|
106
105
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
107
106
|
private loadInitialContent;
|
|
108
107
|
/** Connect to a source provider element (e.g., wgsl-edit). */
|
|
109
|
-
private
|
|
108
|
+
private connectFrom;
|
|
110
109
|
/** Fetch shader from URL, then trigger a build. */
|
|
111
110
|
private loadFromUrl;
|
|
112
111
|
/** Mark build as needed. Coalesces rapid requests into a single build. */
|
|
@@ -118,4 +117,4 @@ declare class WgslPlay extends HTMLElement {
|
|
|
118
117
|
private extractLocations;
|
|
119
118
|
}
|
|
120
119
|
//#endregion
|
|
121
|
-
export {
|
|
120
|
+
export { defaults as a, WgslPlayConfig as i, CompileErrorLocation as n, getConfig as o, WgslPlay as r, resetConfig as s, CompileErrorDetail as t };
|
package/dist/WgslPlay.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { CompileErrorDetail, CompileErrorLocation,
|
|
1
|
+
import { a as defaults, n as CompileErrorLocation, o as getConfig, r as WgslPlay, s as resetConfig, t as CompileErrorDetail } from "./WgslPlay-uTIOrTQq.js";
|
|
2
|
+
export { CompileErrorDetail, CompileErrorLocation, WgslPlay, defaults, getConfig, resetConfig };
|
package/dist/WgslPlay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as resetConfig, n as defaults, r as getConfig, t as WgslPlay } from "./WgslPlay-
|
|
1
|
+
import { i as resetConfig, n as defaults, r as getConfig, t as WgslPlay } from "./WgslPlay-BuIuE3cB.js";
|
|
2
2
|
export { WgslPlay, defaults, getConfig, resetConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as defaults, i as WgslPlayConfig, n as CompileErrorLocation, o as getConfig, r as WgslPlay, s as resetConfig, t as CompileErrorDetail } from "./WgslPlay-uTIOrTQq.js";
|
|
2
2
|
export * from "wesl-fetch";
|
|
3
|
-
export { CompileErrorDetail, CompileErrorLocation,
|
|
3
|
+
export { CompileErrorDetail, CompileErrorLocation, WgslPlay, WgslPlayConfig, defaults, getConfig, resetConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as resetConfig, n as defaults, r as getConfig, t as WgslPlay } from "./WgslPlay-
|
|
1
|
+
import { i as resetConfig, n as defaults, r as getConfig, t as WgslPlay } from "./WgslPlay-BuIuE3cB.js";
|
|
2
2
|
export * from "wesl-fetch";
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
if (typeof customElements !== "undefined" && !customElements.get("wgsl-play")) customElements.define("wgsl-play", WgslPlay);
|
package/dist/wgsl-play.js
CHANGED
|
@@ -5035,7 +5035,8 @@ async function fetchDependencies(rootModuleSource, options) {
|
|
|
5035
5035
|
const shaderRoot = options?.shaderRoot ?? "/shaders";
|
|
5036
5036
|
const currentPath = options?.currentPath;
|
|
5037
5037
|
const existingSources = options?.existingSources;
|
|
5038
|
-
const
|
|
5038
|
+
const fetchLibs = options?.fetchLibs ?? true;
|
|
5039
|
+
const fetchSources = options?.fetchSources ?? true;
|
|
5039
5040
|
const rootModuleName = currentPath ? urlToModulePath(currentPath, shaderRoot) : "package::main";
|
|
5040
5041
|
const resolver = new FetchingResolver({
|
|
5041
5042
|
...existingSources,
|
|
@@ -5051,12 +5052,12 @@ async function fetchDependencies(rootModuleSource, options) {
|
|
|
5051
5052
|
const unresolved = getNonVirtualUnresolved(resolver, fetched);
|
|
5052
5053
|
if (unresolved.length === 0) break;
|
|
5053
5054
|
const [internal, external] = partition(unresolved, isInternal);
|
|
5054
|
-
await Promise.all(internal.map((p) => resolver.resolveModuleAsync(p)));
|
|
5055
|
-
|
|
5056
|
-
|
|
5055
|
+
if (fetchSources) await Promise.all(internal.map((p) => resolver.resolveModuleAsync(p)));
|
|
5056
|
+
else for (const p of internal) fetched.add(p);
|
|
5057
|
+
if (fetchLibs) {
|
|
5057
5058
|
const newLibs = await fetchExternalBundles(external, fetched);
|
|
5058
5059
|
libs.push(...newLibs);
|
|
5059
|
-
}
|
|
5060
|
+
} else for (const p of external) fetched.add(p.split("::")[0]);
|
|
5060
5061
|
}
|
|
5061
5062
|
return {
|
|
5062
5063
|
libs,
|
|
@@ -5606,12 +5607,13 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5606
5607
|
static observedAttributes = [
|
|
5607
5608
|
"src",
|
|
5608
5609
|
"shader-root",
|
|
5609
|
-
"
|
|
5610
|
+
"from",
|
|
5610
5611
|
"no-controls",
|
|
5611
5612
|
"theme",
|
|
5612
5613
|
"autoplay",
|
|
5613
5614
|
"transparent",
|
|
5614
|
-
"fetch-libs"
|
|
5615
|
+
"fetch-libs",
|
|
5616
|
+
"fetch-sources"
|
|
5615
5617
|
];
|
|
5616
5618
|
canvas;
|
|
5617
5619
|
errorOverlay;
|
|
@@ -5628,7 +5630,7 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5628
5630
|
_rootModuleName = "package::main";
|
|
5629
5631
|
_libs;
|
|
5630
5632
|
_linkOptions = {};
|
|
5631
|
-
|
|
5633
|
+
_fetchSources = true;
|
|
5632
5634
|
_initPromise;
|
|
5633
5635
|
_sourceEl = null;
|
|
5634
5636
|
_sourceListener = null;
|
|
@@ -5676,7 +5678,7 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5676
5678
|
}
|
|
5677
5679
|
this.initialize();
|
|
5678
5680
|
upgradeProperty(this, "conditions");
|
|
5679
|
-
upgradeProperty(this, "
|
|
5681
|
+
upgradeProperty(this, "shader");
|
|
5680
5682
|
upgradeProperty(this, "project");
|
|
5681
5683
|
}
|
|
5682
5684
|
disconnectedCallback() {
|
|
@@ -5704,17 +5706,20 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5704
5706
|
this._fetchLibs = newValue !== "false";
|
|
5705
5707
|
return;
|
|
5706
5708
|
}
|
|
5709
|
+
if (name === "fetch-sources") {
|
|
5710
|
+
this._fetchSources = newValue !== "false";
|
|
5711
|
+
return;
|
|
5712
|
+
}
|
|
5707
5713
|
if (name === "src" && newValue && this._initPromise) this.loadFromUrl(newValue);
|
|
5708
5714
|
}
|
|
5709
5715
|
/** Current shader source code (main module). */
|
|
5710
|
-
get
|
|
5716
|
+
get shader() {
|
|
5711
5717
|
return this._weslSrc[this._rootModuleName] ?? "";
|
|
5712
5718
|
}
|
|
5713
|
-
/** Set shader source directly. */
|
|
5714
|
-
set
|
|
5719
|
+
/** Set shader source directly (single-file convenience). */
|
|
5720
|
+
set shader(value) {
|
|
5715
5721
|
this._weslSrc = { [this._rootModuleName]: value };
|
|
5716
5722
|
this._libs = void 0;
|
|
5717
|
-
this._fromFullProject = false;
|
|
5718
5723
|
this.requestBuild();
|
|
5719
5724
|
}
|
|
5720
5725
|
/** Conditions for conditional compilation (@if/@elif/@else). */
|
|
@@ -5732,28 +5737,21 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5732
5737
|
/** Set project configuration (mirrors wesl link() API). */
|
|
5733
5738
|
set project(value) {
|
|
5734
5739
|
const { weslSrc, rootModuleName, libs, packageName, conditions, constants } = value;
|
|
5735
|
-
if (packageName
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
constants
|
|
5739
|
-
};
|
|
5740
|
+
if (packageName !== void 0) this._linkOptions.packageName = packageName;
|
|
5741
|
+
if (conditions !== void 0) this._linkOptions.conditions = conditions;
|
|
5742
|
+
if (constants !== void 0) this._linkOptions.constants = constants;
|
|
5740
5743
|
if (libs) this._libs = libs;
|
|
5741
5744
|
if (weslSrc) {
|
|
5742
|
-
this.
|
|
5745
|
+
const pkg = this._linkOptions.packageName || "package";
|
|
5746
|
+
const root = rootModuleName ?? "main";
|
|
5747
|
+
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
5748
|
+
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
5749
|
+
this.requestBuild();
|
|
5743
5750
|
return;
|
|
5744
5751
|
}
|
|
5745
5752
|
if (Object.keys(this._weslSrc).length === 0) return;
|
|
5746
5753
|
this.requestBuild();
|
|
5747
5754
|
}
|
|
5748
|
-
/** Set sources from a full project with weslSrc. */
|
|
5749
|
-
setProjectSources(weslSrc, rootModuleName) {
|
|
5750
|
-
const pkg = this._linkOptions.packageName || "package";
|
|
5751
|
-
const root = rootModuleName ?? "main";
|
|
5752
|
-
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
5753
|
-
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
5754
|
-
this._fromFullProject = true;
|
|
5755
|
-
this.requestBuild();
|
|
5756
|
-
}
|
|
5757
5755
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
5758
5756
|
get fetchLibs() {
|
|
5759
5757
|
return this._fetchLibs;
|
|
@@ -5763,6 +5761,15 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5763
5761
|
if (value) this.removeAttribute("fetch-libs");
|
|
5764
5762
|
else this.setAttribute("fetch-libs", "false");
|
|
5765
5763
|
}
|
|
5764
|
+
/** Whether to fetch local .wesl source files via HTTP (default: true). */
|
|
5765
|
+
get fetchSources() {
|
|
5766
|
+
return this._fetchSources;
|
|
5767
|
+
}
|
|
5768
|
+
set fetchSources(value) {
|
|
5769
|
+
this._fetchSources = value;
|
|
5770
|
+
if (value) this.removeAttribute("fetch-sources");
|
|
5771
|
+
else this.setAttribute("fetch-sources", "false");
|
|
5772
|
+
}
|
|
5766
5773
|
/** Whether autoplay is enabled (default: true). Set autoplay="false" to start paused. */
|
|
5767
5774
|
get autoplay() {
|
|
5768
5775
|
return this.getAttribute("autoplay") !== "false";
|
|
@@ -5858,9 +5865,9 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5858
5865
|
}
|
|
5859
5866
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
5860
5867
|
loadInitialContent() {
|
|
5861
|
-
const
|
|
5862
|
-
if (
|
|
5863
|
-
this.
|
|
5868
|
+
const fromId = this.getAttribute("from");
|
|
5869
|
+
if (fromId) {
|
|
5870
|
+
this.connectFrom(fromId);
|
|
5864
5871
|
return;
|
|
5865
5872
|
}
|
|
5866
5873
|
const src = this.getAttribute("src");
|
|
@@ -5871,43 +5878,21 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5871
5878
|
const inlineSource = this.querySelector("script[type=\"text/wgsl\"], script[type=\"text/wesl\"]")?.textContent?.trim() ?? this.textContent?.trim();
|
|
5872
5879
|
if (!inlineSource) return;
|
|
5873
5880
|
this._weslSrc = { [this._rootModuleName]: inlineSource };
|
|
5874
|
-
this._fromFullProject = false;
|
|
5875
5881
|
this.requestBuild();
|
|
5876
5882
|
}
|
|
5877
5883
|
/** Connect to a source provider element (e.g., wgsl-edit). */
|
|
5878
|
-
|
|
5884
|
+
connectFrom(id) {
|
|
5879
5885
|
const el = document.getElementById(id);
|
|
5880
5886
|
if (!el) {
|
|
5881
5887
|
console.error(`wgsl-play: source element "${id}" not found`);
|
|
5882
5888
|
return;
|
|
5883
5889
|
}
|
|
5884
5890
|
this._sourceEl = el;
|
|
5885
|
-
const
|
|
5886
|
-
|
|
5887
|
-
if (sources && Object.keys(sources).length > 0) return sources;
|
|
5888
|
-
const source = el.source ?? el.textContent ?? "";
|
|
5889
|
-
return { [this._rootModuleName]: source };
|
|
5890
|
-
};
|
|
5891
|
-
const { conditions, rootModuleName, libs } = el;
|
|
5892
|
-
const root = rootModuleName ?? "main";
|
|
5893
|
-
this._weslSrc = getSources();
|
|
5894
|
-
this._rootModuleName = fileToModulePath(root, "package", false);
|
|
5895
|
-
if (conditions) this._linkOptions = {
|
|
5896
|
-
...this._linkOptions,
|
|
5897
|
-
conditions
|
|
5898
|
-
};
|
|
5899
|
-
if (libs) this._libs = libs;
|
|
5900
|
-
this._fromFullProject = false;
|
|
5901
|
-
this.requestBuild();
|
|
5891
|
+
const p = el.project;
|
|
5892
|
+
if (p) this.project = p;
|
|
5902
5893
|
this._sourceListener = (e) => {
|
|
5903
5894
|
const detail = e.detail;
|
|
5904
|
-
|
|
5905
|
-
this.project = {
|
|
5906
|
-
weslSrc: detail?.sources ?? fallback,
|
|
5907
|
-
rootModuleName: detail?.rootModuleName,
|
|
5908
|
-
conditions: detail?.conditions,
|
|
5909
|
-
libs: detail?.libs
|
|
5910
|
-
};
|
|
5895
|
+
if (detail) this.project = detail;
|
|
5911
5896
|
};
|
|
5912
5897
|
el.addEventListener("change", this._sourceListener);
|
|
5913
5898
|
}
|
|
@@ -5917,7 +5902,6 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5917
5902
|
const { weslSrc, libs, rootModuleName } = await loadShaderFromUrl(url, this.getConfigOverrides()?.shaderRoot);
|
|
5918
5903
|
this._weslSrc = weslSrc;
|
|
5919
5904
|
this._libs = libs;
|
|
5920
|
-
this._fromFullProject = false;
|
|
5921
5905
|
if (rootModuleName) this._rootModuleName = rootModuleName;
|
|
5922
5906
|
this.requestBuild();
|
|
5923
5907
|
} catch (error) {
|
|
@@ -5942,11 +5926,12 @@ var WgslPlay = class extends HTMLElement {
|
|
|
5942
5926
|
}
|
|
5943
5927
|
try {
|
|
5944
5928
|
this.errorOverlay.hide();
|
|
5945
|
-
if (
|
|
5929
|
+
if (this._fetchSources || this._fetchLibs) {
|
|
5946
5930
|
const { weslSrc, libs } = await fetchDependencies(mainSource, {
|
|
5947
5931
|
shaderRoot: this.getConfigOverrides()?.shaderRoot,
|
|
5948
5932
|
existingSources: this._weslSrc,
|
|
5949
|
-
|
|
5933
|
+
fetchLibs: this._fetchLibs,
|
|
5934
|
+
fetchSources: this._fetchSources
|
|
5950
5935
|
});
|
|
5951
5936
|
this._weslSrc = {
|
|
5952
5937
|
...this._weslSrc,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wgsl-play",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.38",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"wesl": "0.
|
|
26
|
-
"wesl-gpu": "0.1.
|
|
27
|
-
"wesl
|
|
25
|
+
"wesl-fetch": "0.0.13",
|
|
26
|
+
"wesl-gpu": "0.1.27",
|
|
27
|
+
"wesl": "0.7.25"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@playwright/test": "^1.53.2",
|
package/src/WgslPlay.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Conditions,
|
|
1
|
+
import type { Conditions, WeslBundle, WeslProject } from "wesl";
|
|
2
2
|
import { fileToModulePath, WeslParseError } from "wesl";
|
|
3
3
|
import { fetchDependencies, loadShaderFromUrl } from "wesl-fetch";
|
|
4
4
|
import type { WgslPlayConfig } from "./Config.ts";
|
|
@@ -16,17 +16,6 @@ import cssText from "./WgslPlay.css?inline";
|
|
|
16
16
|
|
|
17
17
|
export { defaults, getConfig, resetConfig } from "./Config.ts";
|
|
18
18
|
|
|
19
|
-
/** Project configuration for multi-file shaders (subset of wesl link() API). */
|
|
20
|
-
export type WeslProject = Pick<
|
|
21
|
-
LinkParams,
|
|
22
|
-
| "weslSrc"
|
|
23
|
-
| "rootModuleName"
|
|
24
|
-
| "conditions"
|
|
25
|
-
| "constants"
|
|
26
|
-
| "libs"
|
|
27
|
-
| "packageName"
|
|
28
|
-
>;
|
|
29
|
-
|
|
30
19
|
/** One source location within a compile error. */
|
|
31
20
|
export interface CompileErrorLocation {
|
|
32
21
|
file?: string;
|
|
@@ -53,12 +42,13 @@ export class WgslPlay extends HTMLElement {
|
|
|
53
42
|
static observedAttributes = [
|
|
54
43
|
"src",
|
|
55
44
|
"shader-root",
|
|
56
|
-
"
|
|
45
|
+
"from",
|
|
57
46
|
"no-controls",
|
|
58
47
|
"theme",
|
|
59
48
|
"autoplay",
|
|
60
49
|
"transparent",
|
|
61
50
|
"fetch-libs",
|
|
51
|
+
"fetch-sources",
|
|
62
52
|
];
|
|
63
53
|
|
|
64
54
|
private canvas: HTMLCanvasElement;
|
|
@@ -78,7 +68,7 @@ export class WgslPlay extends HTMLElement {
|
|
|
78
68
|
private _rootModuleName = "package::main";
|
|
79
69
|
private _libs?: WeslBundle[];
|
|
80
70
|
private _linkOptions: LinkOptions = {};
|
|
81
|
-
private
|
|
71
|
+
private _fetchSources = true;
|
|
82
72
|
private _initPromise?: Promise<boolean>;
|
|
83
73
|
private _sourceEl: HTMLElement | null = null;
|
|
84
74
|
private _sourceListener: ((e: Event) => void) | null = null;
|
|
@@ -138,7 +128,7 @@ export class WgslPlay extends HTMLElement {
|
|
|
138
128
|
}
|
|
139
129
|
this.initialize();
|
|
140
130
|
upgradeProperty(this, "conditions");
|
|
141
|
-
upgradeProperty(this, "
|
|
131
|
+
upgradeProperty(this, "shader");
|
|
142
132
|
upgradeProperty(this, "project");
|
|
143
133
|
}
|
|
144
134
|
|
|
@@ -179,6 +169,11 @@ export class WgslPlay extends HTMLElement {
|
|
|
179
169
|
return;
|
|
180
170
|
}
|
|
181
171
|
|
|
172
|
+
if (name === "fetch-sources") {
|
|
173
|
+
this._fetchSources = newValue !== "false";
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
182
177
|
// Initial src is handled by initialize(); this handles later changes
|
|
183
178
|
if (name === "src" && newValue && this._initPromise) {
|
|
184
179
|
this.loadFromUrl(newValue);
|
|
@@ -186,15 +181,14 @@ export class WgslPlay extends HTMLElement {
|
|
|
186
181
|
}
|
|
187
182
|
|
|
188
183
|
/** Current shader source code (main module). */
|
|
189
|
-
get
|
|
184
|
+
get shader(): string {
|
|
190
185
|
return this._weslSrc[this._rootModuleName] ?? "";
|
|
191
186
|
}
|
|
192
187
|
|
|
193
|
-
/** Set shader source directly. */
|
|
194
|
-
set
|
|
188
|
+
/** Set shader source directly (single-file convenience). */
|
|
189
|
+
set shader(value: string) {
|
|
195
190
|
this._weslSrc = { [this._rootModuleName]: value };
|
|
196
191
|
this._libs = undefined;
|
|
197
|
-
this._fromFullProject = false;
|
|
198
192
|
this.requestBuild();
|
|
199
193
|
}
|
|
200
194
|
|
|
@@ -219,15 +213,17 @@ export class WgslPlay extends HTMLElement {
|
|
|
219
213
|
conditions,
|
|
220
214
|
constants,
|
|
221
215
|
} = value;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (
|
|
225
|
-
this._linkOptions = { packageName, conditions, constants };
|
|
226
|
-
}
|
|
216
|
+
if (packageName !== undefined) this._linkOptions.packageName = packageName;
|
|
217
|
+
if (conditions !== undefined) this._linkOptions.conditions = conditions;
|
|
218
|
+
if (constants !== undefined) this._linkOptions.constants = constants;
|
|
227
219
|
if (libs) this._libs = libs;
|
|
228
220
|
|
|
229
221
|
if (weslSrc) {
|
|
230
|
-
this.
|
|
222
|
+
const pkg = this._linkOptions.packageName || "package";
|
|
223
|
+
const root = rootModuleName ?? "main";
|
|
224
|
+
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
225
|
+
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
226
|
+
this.requestBuild();
|
|
231
227
|
return;
|
|
232
228
|
}
|
|
233
229
|
|
|
@@ -235,19 +231,6 @@ export class WgslPlay extends HTMLElement {
|
|
|
235
231
|
this.requestBuild();
|
|
236
232
|
}
|
|
237
233
|
|
|
238
|
-
/** Set sources from a full project with weslSrc. */
|
|
239
|
-
private setProjectSources(
|
|
240
|
-
weslSrc: Record<string, string>,
|
|
241
|
-
rootModuleName?: string,
|
|
242
|
-
): void {
|
|
243
|
-
const pkg = this._linkOptions.packageName || "package";
|
|
244
|
-
const root = rootModuleName ?? "main";
|
|
245
|
-
this._weslSrc = toModulePaths(weslSrc, pkg);
|
|
246
|
-
this._rootModuleName = fileToModulePath(root, pkg, false);
|
|
247
|
-
this._fromFullProject = true;
|
|
248
|
-
this.requestBuild();
|
|
249
|
-
}
|
|
250
|
-
|
|
251
234
|
/** Whether to auto-fetch missing library packages from npm (default: true). */
|
|
252
235
|
get fetchLibs(): boolean {
|
|
253
236
|
return this._fetchLibs;
|
|
@@ -259,6 +242,17 @@ export class WgslPlay extends HTMLElement {
|
|
|
259
242
|
else this.setAttribute("fetch-libs", "false");
|
|
260
243
|
}
|
|
261
244
|
|
|
245
|
+
/** Whether to fetch local .wesl source files via HTTP (default: true). */
|
|
246
|
+
get fetchSources(): boolean {
|
|
247
|
+
return this._fetchSources;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
set fetchSources(value: boolean) {
|
|
251
|
+
this._fetchSources = value;
|
|
252
|
+
if (value) this.removeAttribute("fetch-sources");
|
|
253
|
+
else this.setAttribute("fetch-sources", "false");
|
|
254
|
+
}
|
|
255
|
+
|
|
262
256
|
/** Whether autoplay is enabled (default: true). Set autoplay="false" to start paused. */
|
|
263
257
|
get autoplay(): boolean {
|
|
264
258
|
return this.getAttribute("autoplay") !== "false";
|
|
@@ -383,9 +377,9 @@ export class WgslPlay extends HTMLElement {
|
|
|
383
377
|
|
|
384
378
|
/** Load from source element, src URL, script child, or inline textContent. */
|
|
385
379
|
private loadInitialContent(): void {
|
|
386
|
-
const
|
|
387
|
-
if (
|
|
388
|
-
this.
|
|
380
|
+
const fromId = this.getAttribute("from");
|
|
381
|
+
if (fromId) {
|
|
382
|
+
this.connectFrom(fromId);
|
|
389
383
|
return;
|
|
390
384
|
}
|
|
391
385
|
|
|
@@ -404,12 +398,11 @@ export class WgslPlay extends HTMLElement {
|
|
|
404
398
|
if (!inlineSource) return;
|
|
405
399
|
|
|
406
400
|
this._weslSrc = { [this._rootModuleName]: inlineSource };
|
|
407
|
-
this._fromFullProject = false;
|
|
408
401
|
this.requestBuild();
|
|
409
402
|
}
|
|
410
403
|
|
|
411
404
|
/** Connect to a source provider element (e.g., wgsl-edit). */
|
|
412
|
-
private
|
|
405
|
+
private connectFrom(id: string): void {
|
|
413
406
|
const el = document.getElementById(id);
|
|
414
407
|
if (!el) {
|
|
415
408
|
console.error(`wgsl-play: source element "${id}" not found`);
|
|
@@ -417,34 +410,12 @@ export class WgslPlay extends HTMLElement {
|
|
|
417
410
|
}
|
|
418
411
|
this._sourceEl = el;
|
|
419
412
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
const sources = (el as any).sources;
|
|
423
|
-
if (sources && Object.keys(sources).length > 0) return sources;
|
|
424
|
-
const source = (el as any).source ?? el.textContent ?? "";
|
|
425
|
-
return { [this._rootModuleName]: source };
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// Load initial sources, conditions, and libs from source element.
|
|
429
|
-
const { conditions, rootModuleName, libs } = el as any;
|
|
430
|
-
const root = rootModuleName ?? "main";
|
|
431
|
-
this._weslSrc = getSources();
|
|
432
|
-
this._rootModuleName = fileToModulePath(root, "package", false);
|
|
433
|
-
if (conditions) this._linkOptions = { ...this._linkOptions, conditions };
|
|
434
|
-
if (libs) this._libs = libs;
|
|
435
|
-
this._fromFullProject = false;
|
|
436
|
-
this.requestBuild();
|
|
413
|
+
const p = (el as any).project as WeslProject | undefined;
|
|
414
|
+
if (p) this.project = p;
|
|
437
415
|
|
|
438
|
-
// Listen for changes - rebuild with libs from source element
|
|
439
416
|
this._sourceListener = (e: Event) => {
|
|
440
|
-
const detail = (e as CustomEvent).detail;
|
|
441
|
-
|
|
442
|
-
this.project = {
|
|
443
|
-
weslSrc: detail?.sources ?? fallback,
|
|
444
|
-
rootModuleName: detail?.rootModuleName,
|
|
445
|
-
conditions: detail?.conditions,
|
|
446
|
-
libs: detail?.libs,
|
|
447
|
-
};
|
|
417
|
+
const detail = (e as CustomEvent).detail as WeslProject | undefined;
|
|
418
|
+
if (detail) this.project = detail;
|
|
448
419
|
};
|
|
449
420
|
el.addEventListener("change", this._sourceListener);
|
|
450
421
|
}
|
|
@@ -458,7 +429,6 @@ export class WgslPlay extends HTMLElement {
|
|
|
458
429
|
);
|
|
459
430
|
this._weslSrc = weslSrc;
|
|
460
431
|
this._libs = libs;
|
|
461
|
-
this._fromFullProject = false;
|
|
462
432
|
if (rootModuleName) this._rootModuleName = rootModuleName;
|
|
463
433
|
this.requestBuild();
|
|
464
434
|
} catch (error) {
|
|
@@ -490,11 +460,12 @@ export class WgslPlay extends HTMLElement {
|
|
|
490
460
|
|
|
491
461
|
try {
|
|
492
462
|
this.errorOverlay.hide();
|
|
493
|
-
if (
|
|
463
|
+
if (this._fetchSources || this._fetchLibs) {
|
|
494
464
|
const { weslSrc, libs } = await fetchDependencies(mainSource, {
|
|
495
465
|
shaderRoot: this.getConfigOverrides()?.shaderRoot,
|
|
496
466
|
existingSources: this._weslSrc,
|
|
497
|
-
|
|
467
|
+
fetchLibs: this._fetchLibs,
|
|
468
|
+
fetchSources: this._fetchSources,
|
|
498
469
|
});
|
|
499
470
|
this._weslSrc = { ...this._weslSrc, ...weslSrc };
|
|
500
471
|
this._libs = dedupLibs(this._libs, libs);
|