@motion-core/motion-gpu
Version:
Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.
138 lines (137 loc) • 6.93 kB
JavaScript
//#region src/lib/core/error-diagnostics.ts
function isMaterialSourceMetadata(value) {
if (value === null || typeof value !== "object") return false;
const record = value;
if (record.component !== void 0 && typeof record.component !== "string") return false;
if (record.file !== void 0 && typeof record.file !== "string") return false;
if (record.functionName !== void 0 && typeof record.functionName !== "string") return false;
if (record.line !== void 0 && typeof record.line !== "number") return false;
if (record.column !== void 0 && typeof record.column !== "number") return false;
return true;
}
function isShaderSourceLocation(value) {
if (value === null) return true;
if (typeof value !== "object") return false;
const record = value;
const kind = record.kind;
if (kind !== "fragment" && kind !== "include" && kind !== "define" && kind !== "compute") return false;
return typeof record.line === "number";
}
function isShaderCompilationDiagnostic(value) {
if (value === null || typeof value !== "object") return false;
const record = value;
if (typeof record.generatedLine !== "number") return false;
if (typeof record.message !== "string") return false;
if (record.linePos !== void 0 && typeof record.linePos !== "number") return false;
if (record.lineLength !== void 0 && typeof record.lineLength !== "number") return false;
if (!isShaderSourceLocation(record.sourceLocation)) return false;
return true;
}
function isStringArray(value) {
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
}
function isShaderCompilationRuntimeContext(value) {
if (value === null || typeof value !== "object") return false;
const record = value;
if (record.materialSignature !== void 0 && typeof record.materialSignature !== "string") return false;
if (!isStringArray(record.activeRenderTargets)) return false;
const passGraph = record.passGraph;
if (passGraph === void 0) return true;
if (passGraph === null || typeof passGraph !== "object") return false;
const passGraphRecord = passGraph;
if (typeof passGraphRecord.passCount !== "number") return false;
if (typeof passGraphRecord.enabledPassCount !== "number") return false;
if (!isStringArray(passGraphRecord.inputs) || !isStringArray(passGraphRecord.outputs)) return false;
return true;
}
function freezeShaderSourceLocation(location) {
if (location === null) return null;
return Object.freeze({
kind: location.kind,
line: location.line,
..."include" in location && location.include !== void 0 ? { include: location.include } : {},
..."define" in location && location.define !== void 0 ? { define: location.define } : {}
});
}
function freezeMaterialSource(source) {
if (source === null) return null;
return Object.freeze({
...source.component !== void 0 ? { component: source.component } : {},
...source.file !== void 0 ? { file: source.file } : {},
...source.line !== void 0 ? { line: source.line } : {},
...source.column !== void 0 ? { column: source.column } : {},
...source.functionName !== void 0 ? { functionName: source.functionName } : {}
});
}
function freezeRuntimeContext(context) {
return Object.freeze({
...context.materialSignature !== void 0 ? { materialSignature: context.materialSignature } : {},
...context.passGraph !== void 0 ? { passGraph: Object.freeze({
passCount: context.passGraph.passCount,
enabledPassCount: context.passGraph.enabledPassCount,
inputs: Object.freeze([...context.passGraph.inputs]),
outputs: Object.freeze([...context.passGraph.outputs])
}) } : {},
activeRenderTargets: Object.freeze([...context.activeRenderTargets])
});
}
function freezeDiagnosticsPayload(payload) {
return Object.freeze({
kind: "shader-compilation",
...payload.shaderStage !== void 0 ? { shaderStage: payload.shaderStage } : {},
diagnostics: Object.freeze(payload.diagnostics.map((diagnostic) => Object.freeze({
generatedLine: diagnostic.generatedLine,
message: diagnostic.message,
...diagnostic.linePos !== void 0 ? { linePos: diagnostic.linePos } : {},
...diagnostic.lineLength !== void 0 ? { lineLength: diagnostic.lineLength } : {},
sourceLocation: freezeShaderSourceLocation(diagnostic.sourceLocation)
}))),
fragmentSource: payload.fragmentSource,
...payload.computeSource !== void 0 ? { computeSource: payload.computeSource } : {},
includeSources: Object.freeze(Object.fromEntries(Object.entries(payload.includeSources))),
...payload.defineBlockSource !== void 0 ? { defineBlockSource: payload.defineBlockSource } : {},
materialSource: freezeMaterialSource(payload.materialSource),
...payload.runtimeContext !== void 0 ? { runtimeContext: freezeRuntimeContext(payload.runtimeContext) } : {}
});
}
/**
* Attaches structured diagnostics payload to an Error.
*/
function attachShaderCompilationDiagnostics(error, payload) {
error.motiongpuDiagnostics = freezeDiagnosticsPayload(payload);
return error;
}
/**
* Extracts structured diagnostics payload from unknown error value.
*/
function getShaderCompilationDiagnostics(error) {
if (!(error instanceof Error)) return null;
const payload = error.motiongpuDiagnostics;
if (payload === null || typeof payload !== "object") return null;
const record = payload;
if (record.kind !== "shader-compilation") return null;
if (record.shaderStage !== void 0 && record.shaderStage !== "fragment" && record.shaderStage !== "compute") return null;
if (!Array.isArray(record.diagnostics) || !record.diagnostics.every(isShaderCompilationDiagnostic)) return null;
if (typeof record.fragmentSource !== "string") return null;
if (record.computeSource !== void 0 && typeof record.computeSource !== "string") return null;
if (record.defineBlockSource !== void 0 && typeof record.defineBlockSource !== "string") return null;
if (record.includeSources === null || typeof record.includeSources !== "object") return null;
const includeSources = record.includeSources;
if (Object.values(includeSources).some((value) => typeof value !== "string")) return null;
if (record.materialSource !== null && !isMaterialSourceMetadata(record.materialSource)) return null;
if (record.runtimeContext !== void 0 && !isShaderCompilationRuntimeContext(record.runtimeContext)) return null;
return freezeDiagnosticsPayload({
kind: "shader-compilation",
...record.shaderStage !== void 0 ? { shaderStage: record.shaderStage } : {},
diagnostics: record.diagnostics,
fragmentSource: record.fragmentSource,
...record.computeSource !== void 0 ? { computeSource: record.computeSource } : {},
includeSources,
...record.defineBlockSource !== void 0 ? { defineBlockSource: record.defineBlockSource } : {},
materialSource: record.materialSource ?? null,
...record.runtimeContext !== void 0 ? { runtimeContext: record.runtimeContext } : {}
});
}
//#endregion
export { attachShaderCompilationDiagnostics, getShaderCompilationDiagnostics };
//# sourceMappingURL=error-diagnostics.js.map