@three-blocks/devtools 1.0.0-alpha.176.g8ff8a72e6369
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/CHANGELOG.md +11 -0
- package/LICENSE +76 -0
- package/NOTICE +32 -0
- package/README.md +254 -0
- package/dist/browser/environment-bake.js +1 -0
- package/dist/browser/shader-capture.d.ts +45 -0
- package/dist/browser/shader-capture.js +3 -0
- package/dist/browser-smoke-76626IZQ.js +254 -0
- package/dist/chunk-26FK4CRS.js +6 -0
- package/dist/chunk-4EHPYBKA.cjs +1 -0
- package/dist/chunk-5L2VS3BN.js +2 -0
- package/dist/chunk-76WRV5MZ.js +7 -0
- package/dist/chunk-EI7MMDWY.js +1 -0
- package/dist/chunk-HOZDD6PW.js +2 -0
- package/dist/chunk-HRYYNBVC.js +3 -0
- package/dist/chunk-INDAJN42.js +94 -0
- package/dist/chunk-JMS5NTP7.js +3 -0
- package/dist/chunk-ME3X2KFY.js +14 -0
- package/dist/chunk-NE7SC2BX.js +2 -0
- package/dist/chunk-SCJNCGMF.js +17 -0
- package/dist/chunk-UDUICSME.js +1 -0
- package/dist/chunk-VGJ3V4QQ.js +78 -0
- package/dist/chunk-ZDNZCQUQ.js +2 -0
- package/dist/chunk-ZKK6E42X.js +1 -0
- package/dist/chunk-ZT6T2W4B.js +2 -0
- package/dist/cli.js +24 -0
- package/dist/environment-bake-5P4IAL4O.js +4 -0
- package/dist/index.d.ts +1183 -0
- package/dist/index.js +272 -0
- package/dist/shader-autowire-DCODBFMX.js +18 -0
- package/dist/shader-browser-65V22LLL.js +1 -0
- package/dist/shader-browser-JII6ZFCW.js +2 -0
- package/dist/shader-capture-server.d.ts +272 -0
- package/dist/shader-capture-server.js +19 -0
- package/dist/shader-config-4EXO5DKK.js +2 -0
- package/dist/shader-parity-QXJWR6OZ.js +1 -0
- package/dist/shader-parity-XPKQQK26.js +2 -0
- package/dist/shader-project-runner-GUR3LTYS.js +5 -0
- package/dist/shader-transform-CUkZn5Oa.d.ts +55 -0
- package/dist/shader-watch-QHTNTSZE.js +2 -0
- package/dist/shader-workflow-U4G565EB.js +2 -0
- package/dist/status-DV2BYZHR.js +2 -0
- package/dist/text-atlas-BHPSDU7C.js +2 -0
- package/dist/transform.cjs +1 -0
- package/dist/transform.d.ts +62 -0
- package/dist/transform.js +1 -0
- package/dist/webpack-loader.cjs +1 -0
- package/dist/webpack-loader.d.ts +17 -0
- package/dist/webpack-loader.js +1 -0
- package/fonts/OFL-1.1.txt +93 -0
- package/package.json +113 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a as a$1}from'./chunk-ZDNZCQUQ.js';import {d,j,a as a$2,c,g as g$1,f,k}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath,readFile,stat,chmod}from'fs/promises';import p from'path';var g="@three-blocks/devtools/transform",M=["next.config.ts","next.config.mts","next.config.mjs","next.config.js","next.config.cjs"],_=["webpack.config.ts","webpack.config.mts","webpack.config.mjs","webpack.config.js","webpack.config.cjs"],O=["rollup.config.ts","rollup.config.mts","rollup.config.mjs","rollup.config.js","rollup.config.cjs"],C=["build.mjs","build.js","build.ts","scripts/build.mjs","scripts/build.js","scripts/build.ts"];function $(e,n){return [e.dependencies,e.devDependencies,e.peerDependencies,e.optionalDependencies].some(t=>a$1(t)&&typeof t[n]=="string")}a($,"dependency");async function J(e){let n=p.join(e,"package.json");if(!await d(n))return {};let t=await j(e,n,a$2.packageJson,"Project package.json"),r=JSON.parse(t.data.toString("utf8"));if(!a$1(r))throw new Error("Project package.json must contain an object.");return r}a(J,"readPackageManifest");async function y(e,n){for(let t of n)if(await d(p.join(e,t)))return t}a(y,"firstExisting");function S(e,n){switch(n){case "next":return e.includes(g)&&/\bwithThreeBlocksNext\s*\(/u.test(e);case "webpack":return e.includes(g)&&/\bwithThreeBlocksWebpack\s*\(/u.test(e)||e.includes("@three-blocks/devtools/webpack-loader");case "esbuild":return e.includes(g)&&/\bcreateEsbuildShaderPlugin\s*\(/u.test(e);case "rollup":return e.includes(g)&&/\bcreateRollupShaderPlugin\s*\(/u.test(e)}}a(S,"sourceUsesAdapter");function R(e,n){if(!e.startsWith("#!"))return `${n}
|
|
3
|
+
${e}`;let t=e.indexOf(`
|
|
4
|
+
`);return t<0?`${e}
|
|
5
|
+
${n}
|
|
6
|
+
`:`${e.slice(0,t+1)}${n}
|
|
7
|
+
${e.slice(t+1)}`}a(R,"prependImport");function N(e){let n=0;for(;n<e.length;){let t=e[n];if(t!==void 0&&/\s/u.test(t)){n+=1;continue}if(e.startsWith("//",n)){let r=e.indexOf(`
|
|
8
|
+
`,n+2);n=r<0?e.length:r+1;continue}if(e.startsWith("/*",n)){let r=e.indexOf("*/",n+2);if(r<0)return false;n=r+2;continue}return false}return true}a(N,"containsOnlyJavaScriptTrivia");function q(e){let n,t=false,r=false,s=false,o=0,a=0,d=0,f=false;for(let l=0;l<e.length;l++){let i=e[l],c=e[l+1];if(r){i===`
|
|
9
|
+
`&&(r=false);continue}if(s){i==="*"&&c==="/"&&(s=false,l+=1);continue}if(n!==void 0){t?t=false:i==="\\"?t=true:i===n&&(n=void 0);continue}if(i==="/"&&c==="/"){r=true,l+=1;continue}if(i==="/"&&c==="*"){s=true,l+=1;continue}if(i==='"'||i==="'"||i==="`"){n=i,f=true;continue}if(i==="("?o+=1:i===")"?o-=1:i==="["?a+=1:i==="]"?a-=1:i==="{"?d+=1:i==="}"&&(d-=1),o<0||a<0||d<0)return;let F=o===0&&a===0&&d===0;if(F&&i===";"){let w=e.slice(l+1);if(!N(w))return;let b=e.slice(0,l).trim();return b.length===0?void 0:{expression:b,suffix:w}}if(F&&i===`
|
|
10
|
+
`&&f){let w=e.slice(l);if(!N(w))return;let b=e.slice(0,l).trim();return b.length===0?void 0:{expression:b,suffix:w}}i!==void 0&&!/\s/u.test(i)&&(f=true);}if(n!==void 0||s||o!==0||a!==0||d!==0)return;let h=e.trim();return h.length===0?void 0:{expression:h,suffix:`
|
|
11
|
+
`}}a(q,"safeTrailingExportExpression");function D(e,n){let t=n.commonJs?"module.exports =":"export default",r=e.lastIndexOf(t);if(r<0)return;let s=q(e.slice(r+t.length));if(s===void 0)return;let o=e.slice(0,r),a=n.commonJs?`const { ${n.wrapper} } = require('${g}');`:`import { ${n.wrapper} } from '${g}';`;return R(`${o}${t} ${n.wrapper}( ${s.expression} );${s.suffix}`,a)}a(D,"wrapTrailingExport");function H(e,n){let t=n.endsWith(".cjs")||/\bmodule\.exports\s*=/u.test(e);return D(e,{commonJs:t,wrapper:"withThreeBlocksNext"})}a(H,"nextSource");function K(e,n){let t=n.endsWith(".cjs")||/\bmodule\.exports\s*=/u.test(e);return D(e,{commonJs:t,wrapper:"withThreeBlocksWebpack"})}a(K,"webpackSource");function B(e,n){let t=`import { ${n} } from '${g}';`,r=/\bplugins\s*:\s*\[/u.exec(e);if(r?.index!==void 0){let s=r.index+r[0].length;return R(`${e.slice(0,s)} ${n}(),${e.slice(s)}`,t)}if(n==="createEsbuildShaderPlugin"){let s=/\b(?:build|context)\s*\(\s*\{/u.exec(e);if(s?.index!==void 0){let o=s.index+s[0].length;return R(`${e.slice(0,o)}
|
|
12
|
+
plugins: [ ${n}() ],${e.slice(o)}`,t)}}}a(B,"pluginSource");function U(e,n,t){let r=n.replace(/\n$/u,"").split(`
|
|
13
|
+
`),s=t.replace(/\n$/u,"").split(`
|
|
14
|
+
`),o=0;for(;o<r.length&&o<s.length&&r[o]===s[o];)o+=1;let a=0;for(;a<r.length-o&&a<s.length-o&&r[r.length-1-a]===s[s.length-1-a];)a+=1;let d=Math.max(0,o-2),f=Math.min(r.length,r.length-a+2),h=Math.min(s.length,s.length-a+2),l=[`--- a/${e}`,`+++ b/${e}`,`@@ -${d+1},${f-d} +${d+1},${h-d} @@`];for(let i=d;i<o;i++)l.push(` ${r[i]??""}`);for(let i=o;i<r.length-a;i++)l.push(`-${r[i]??""}`);for(let i=o;i<s.length-a;i++)l.push(`+${s[i]??""}`);for(let i=Math.max(o,s.length-a);i<h;i++)l.push(` ${s[i]??""}`);return l.join(`
|
|
15
|
+
`)}a(U,"unifiedDiff");async function v(e,n,t,r,s){let o=p.join(e,t),a=!await d(o),d$1=a?"":(await j(e,o,a$2.metadata,`${n} configuration`)).data.toString("utf8");if(S(d$1,n))return;let f=a?s:r(d$1,t);if(!(f===void 0||f===d$1))return {schemaVersion:1,root:e,bundler:n,file:o,relativeFile:t,created:a,beforeHash:c(d$1),before:d$1,after:f,diff:U(t,d$1,f)}}a(v,"createPlan");function G(e){let n=e.scripts?.build;if(typeof n!="string")return C;let t=[...n.matchAll(/(?:^|\s)([^\s"';&|]+\.(?:[cm]?[jt]s))(?:\s|$)/gu)].map(r=>r[1]).filter(r=>r!==void 0&&!p.isAbsolute(r)&&!r.startsWith("../"));return [...new Set([...t,...C])]}a(G,"scriptFileCandidates");async function Z(e){let n=await realpath(e),t=await J(n),r=await y(n,M);if($(t,"next")||r!==void 0){let l=r??"next.config.mjs",i=await v(n,"next",l,H,`import { withThreeBlocksNext } from '${g}';
|
|
16
|
+
|
|
17
|
+
export default withThreeBlocksNext( {} );
|
|
18
|
+
`);if(i===void 0){let c=await readFile(p.join(n,l),"utf8");return S(c,"next")?{schemaVersion:1,root:n,bundler:"next",configured:true,reason:`Detected the shader adapter in ${l}.`}:{schemaVersion:1,root:n,bundler:"next",configured:false,reason:`Could not safely wrap ${l}; add withThreeBlocksNext around its default export.`}}return {schemaVersion:1,root:n,bundler:"next",configured:false,reason:`Next.js needs the provider transform in ${l}.`,plan:i}}let s=await y(n,["vite.config.ts","vite.config.mts","vite.config.mjs","vite.config.js","vite.config.cjs"]);if($(t,"vite")||s!==void 0)return {schemaVersion:1,root:n,bundler:"vite",configured:true,reason:"The isolated Vite capture driver installs the provider transform."};let o=await y(n,_);if($(t,"webpack")||o!==void 0){let l=o??"webpack.config.mjs",i=await v(n,"webpack",l,K);if(i===void 0){let c=o!==void 0&&S(await readFile(p.join(n,o),"utf8"),"webpack");return {schemaVersion:1,root:n,bundler:"webpack",configured:c,reason:c?`Detected the shader adapter in ${o}.`:o===void 0?"No webpack configuration file was found to update safely.":`Could not safely wrap ${o}; wrap its export with withThreeBlocksWebpack.`}}return {schemaVersion:1,root:n,bundler:"webpack",configured:false,reason:`webpack needs the provider transform in ${l}.`,plan:i}}let a=await y(n,O);if($(t,"rollup")||a!==void 0){let l=a??"rollup.config.mjs",i=a===void 0?void 0:await v(n,"rollup",l,c=>B(c,"createRollupShaderPlugin"));if(i===void 0){let c=a!==void 0&&S(await readFile(p.join(n,a),"utf8"),"rollup");return {schemaVersion:1,root:n,bundler:"rollup",configured:c,reason:c?`Detected the shader adapter in ${a}.`:a===void 0?"No Rollup configuration file was found to update safely.":`Could not safely add createRollupShaderPlugin to ${a}.`}}return {schemaVersion:1,root:n,bundler:"rollup",configured:false,reason:`Rollup needs the provider transform in ${l}.`,plan:i}}let d=await y(n,G(t)),f=d===void 0?void 0:await readFile(p.join(n,d),"utf8"),h=f!==void 0&&/(?:from\s*['"]esbuild['"]|require\s*\(\s*['"]esbuild['"]\s*\)|import\s*\(\s*['"]esbuild['"]\s*\))/u.test(f);if($(t,"esbuild")||h){let l=d??"build.mjs",i=d===void 0?void 0:await v(n,"esbuild",l,c=>B(c,"createEsbuildShaderPlugin"));if(i===void 0){let c=f!==void 0&&S(f,"esbuild");return {schemaVersion:1,root:n,bundler:"esbuild",configured:c,reason:c?`Detected the shader adapter in ${d}.`:d===void 0?"No esbuild script was found to update safely.":`Could not safely add createEsbuildShaderPlugin to ${d}.`}}return {schemaVersion:1,root:n,bundler:"esbuild",configured:false,reason:`esbuild needs the provider transform in ${l}.`,plan:i}}return {schemaVersion:1,root:n,bundler:"unknown",configured:false,reason:"No supported bundler configuration was detected."}}a(Z,"inspectShaderAutoWire");async function ee(e){let n=await realpath(e.root);if(n!==e.root||p.resolve(n,e.relativeFile)!==e.file)throw new Error("Shader adapter patch no longer targets the inspected project.");if(e.created){if(!await g$1(e.file,e.after))throw new Error(`${e.relativeFile} was created after the adapter preview; inspect it and rerun capture.`);return}let t=await j(n,e.file,a$2.metadata,`${e.bundler} configuration`);if(c(t.data)!==e.beforeHash)throw new Error(`${e.relativeFile} changed after the adapter preview; no edit was applied.`);let r=(await stat(e.file)).mode&511;await f(e.file,e.after),await chmod(e.file,r);}a(ee,"applyShaderAutoWire");async function ne(e){let n=await realpath(e),t=["src","app","pages"],r=new Set;for(let s of t){let o=p.join(n,s);if(!await d(o))continue;let a=await k(n,o,d=>/\.[cm]?[jt]sx?$/u.test(d),4096);for(let d of a){if(r.has(d))continue;r.add(d);let f=await j(n,d,a$2.semanticInput,"Runtime source");if(/\b(?:registerDevtools|createWorkerRuntime|installAutomaticShaderHydration)\s*\(/u.test(f.data.toString("utf8")))return true}}return false}a(ne,"hasRegisterDevtoolsCall");export{ee as applyShaderAutoWire,ne as hasRegisterDevtoolsCall,Z as inspectShaderAutoWire};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{g as canReuseShaderBrowserSession,k as createAttachedPlaywrightShaderDriver,i as createPlaywrightShaderDriver,j as createStaticPlaywrightShaderDriver,h as isRetryableShaderObservationNavigation,f as settleShaderParityFrames,e as waitForShaderCaptureAcrossNavigation}from'./chunk-VGJ3V4QQ.js';import'./chunk-SCJNCGMF.js';import'./chunk-EI7MMDWY.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{k as canReuseShaderBrowserSession,o as createAttachedPlaywrightShaderDriver,m as createPlaywrightShaderDriver,n as createStaticPlaywrightShaderDriver,l as isRetryableShaderObservationNavigation,j as settleShaderParityFrames,i as waitForShaderCaptureAcrossNavigation}from'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { PrecompiledManifest } from 'three-blocks/shaders';
|
|
2
|
+
|
|
3
|
+
interface ShaderSceneConfig {
|
|
4
|
+
readonly key: string;
|
|
5
|
+
/** Project-relative browser URL, including an optional query string. */
|
|
6
|
+
readonly url: string;
|
|
7
|
+
readonly requiresText: boolean;
|
|
8
|
+
/** Optional authoritative project-relative semantic inputs for this scene. */
|
|
9
|
+
readonly inputs?: readonly string[];
|
|
10
|
+
/** Optional scene-specific completed-frame count for deterministic parity. */
|
|
11
|
+
readonly parityFrames?: number;
|
|
12
|
+
/** Optional scene-specific pixel-difference budget for intrinsically nondeterministic GPU work. */
|
|
13
|
+
readonly maxDiffRatio?: number;
|
|
14
|
+
/** Permit Three's backend pipeline cache to reuse an earlier injected pipeline with identical WGSL. */
|
|
15
|
+
readonly allowPipelineReuse?: boolean;
|
|
16
|
+
/** Require the normal published page's primary canvas to keep changing after startup. */
|
|
17
|
+
readonly runtimeMotion?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface ShaderParityConfig {
|
|
20
|
+
readonly frames: number;
|
|
21
|
+
readonly channelTolerance: number;
|
|
22
|
+
readonly maxDiffRatio: number;
|
|
23
|
+
}
|
|
24
|
+
interface ShaderBridgeConfig {
|
|
25
|
+
/** Temporary compatibility for the private integration lab's v1 globals. */
|
|
26
|
+
readonly legacyLab: boolean;
|
|
27
|
+
/** Browser module exposing the lab's deterministic recording store. */
|
|
28
|
+
readonly deterministicModule?: string;
|
|
29
|
+
}
|
|
30
|
+
interface ShaderReadinessConfig {
|
|
31
|
+
/** CSS selector whose presence marks the application ready for capture. */
|
|
32
|
+
readonly selector?: string;
|
|
33
|
+
/** Dot-separated window/global property containing `true` or a readiness promise. */
|
|
34
|
+
readonly global?: string;
|
|
35
|
+
}
|
|
36
|
+
interface ShaderToolConfig {
|
|
37
|
+
readonly schemaVersion: 1;
|
|
38
|
+
readonly scenes: readonly ShaderSceneConfig[];
|
|
39
|
+
readonly settleFrames: number;
|
|
40
|
+
/** Total post-readiness settle ceiling. Defaults to 30 seconds. */
|
|
41
|
+
readonly settleTimeoutMs?: number;
|
|
42
|
+
/** Chromium is relaunched after this many isolated capture contexts. Defaults to 8. */
|
|
43
|
+
readonly browserRelaunchScenes?: number;
|
|
44
|
+
readonly timeoutMs: number;
|
|
45
|
+
readonly viewport: {
|
|
46
|
+
readonly width: number;
|
|
47
|
+
readonly height: number;
|
|
48
|
+
};
|
|
49
|
+
readonly parity: ShaderParityConfig;
|
|
50
|
+
readonly bridge: ShaderBridgeConfig;
|
|
51
|
+
readonly readiness: ShaderReadinessConfig;
|
|
52
|
+
/** Static-asset root used for zero-import runtime manifests. Defaults to `public`. */
|
|
53
|
+
readonly publicDir?: string;
|
|
54
|
+
/** Permit unregistered Three-internal/live builds in a receipt. Defaults true; set false for a strict matrix. */
|
|
55
|
+
readonly allowLiveBuilds: boolean;
|
|
56
|
+
}
|
|
57
|
+
declare function loadShaderToolConfig(root: string): Promise<ShaderToolConfig>;
|
|
58
|
+
|
|
59
|
+
type ArtifactState = 'fresh' | 'pending';
|
|
60
|
+
interface ProjectMetadataV2 {
|
|
61
|
+
readonly schemaVersion: 2;
|
|
62
|
+
/** Stable default shader scene key. It is not a template catalogue identity. */
|
|
63
|
+
readonly template: string;
|
|
64
|
+
/** Informational project layers; devtools does not prescribe their catalogue or order. */
|
|
65
|
+
readonly layers: readonly string[];
|
|
66
|
+
readonly generator?: {
|
|
67
|
+
readonly name: string;
|
|
68
|
+
readonly version: string;
|
|
69
|
+
};
|
|
70
|
+
readonly runtime: {
|
|
71
|
+
readonly three: string;
|
|
72
|
+
readonly threeBlocks: string;
|
|
73
|
+
};
|
|
74
|
+
readonly features: {
|
|
75
|
+
/** The only project capability currently consumed by the generic engine. */
|
|
76
|
+
readonly text: boolean;
|
|
77
|
+
};
|
|
78
|
+
readonly artifacts?: {
|
|
79
|
+
readonly shaders: ArtifactState;
|
|
80
|
+
readonly text: ArtifactState | 'not-applicable';
|
|
81
|
+
};
|
|
82
|
+
readonly protocol: {
|
|
83
|
+
readonly resultFile: 1;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
interface ShaderCoverage {
|
|
87
|
+
readonly render: number;
|
|
88
|
+
readonly vertex: number;
|
|
89
|
+
readonly fragment: number;
|
|
90
|
+
readonly compute: number;
|
|
91
|
+
}
|
|
92
|
+
interface ShaderSceneReceipt {
|
|
93
|
+
readonly artifact: string;
|
|
94
|
+
readonly artifactHash: string;
|
|
95
|
+
/** Path relative to the configured public directory. */
|
|
96
|
+
readonly asset?: string;
|
|
97
|
+
readonly assetHash?: string;
|
|
98
|
+
readonly inputs: Readonly<Record<string, string>>;
|
|
99
|
+
readonly coverage: ShaderCoverage;
|
|
100
|
+
readonly bytes?: number;
|
|
101
|
+
readonly skipped?: {
|
|
102
|
+
readonly render: number;
|
|
103
|
+
readonly compute: number;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
interface ShaderReceiptV2 {
|
|
107
|
+
readonly schemaVersion: 2;
|
|
108
|
+
readonly runtime: ProjectMetadataV2['runtime'] & {
|
|
109
|
+
readonly threeBlocksShaderClosure: string;
|
|
110
|
+
readonly capture?: {
|
|
111
|
+
readonly userAgent: string;
|
|
112
|
+
readonly adapter: string;
|
|
113
|
+
readonly features: readonly string[];
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
readonly tool?: {
|
|
117
|
+
readonly name: '@three-blocks/devtools';
|
|
118
|
+
readonly version: string;
|
|
119
|
+
readonly compatibility: string;
|
|
120
|
+
readonly transform: number;
|
|
121
|
+
readonly address: number;
|
|
122
|
+
readonly recipe: number;
|
|
123
|
+
readonly hydration: number;
|
|
124
|
+
};
|
|
125
|
+
readonly scenes: Readonly<Record<string, ShaderSceneReceipt>>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Snapshot declared scene inputs, or discover shader roots and their local runtime import closure. */
|
|
129
|
+
declare function snapshotShaderInputs(root: string, declaredInputs?: readonly string[]): Promise<Readonly<Record<string, string>>>;
|
|
130
|
+
interface InstalledShaderRuntime {
|
|
131
|
+
readonly three: string;
|
|
132
|
+
readonly threeBlocks: string;
|
|
133
|
+
readonly threeBlocksShaderClosure: string;
|
|
134
|
+
}
|
|
135
|
+
/** Read exact installed versions and hash the public `three-blocks/shaders` ESM closure. */
|
|
136
|
+
declare function readInstalledShaderRuntime(root: string): Promise<InstalledShaderRuntime>;
|
|
137
|
+
|
|
138
|
+
type ShaderMatrixState = 'fresh' | 'stale' | 'invalid' | 'missing';
|
|
139
|
+
interface ShaderSceneArtifactStatus {
|
|
140
|
+
readonly scene: string;
|
|
141
|
+
readonly state: ShaderMatrixState;
|
|
142
|
+
readonly reason: string;
|
|
143
|
+
readonly coverage?: ShaderCoverage;
|
|
144
|
+
/** Build timing, exposed only while its exact receipt is fresh. */
|
|
145
|
+
readonly timing?: ShaderSceneTiming & {
|
|
146
|
+
readonly schemaVersion: 3;
|
|
147
|
+
readonly measuredAt: string;
|
|
148
|
+
readonly source: ShaderTiming['source'];
|
|
149
|
+
readonly adapter?: string;
|
|
150
|
+
readonly platform?: string;
|
|
151
|
+
};
|
|
152
|
+
readonly changedInputs?: readonly string[];
|
|
153
|
+
readonly addedInputs?: readonly string[];
|
|
154
|
+
readonly removedInputs?: readonly string[];
|
|
155
|
+
}
|
|
156
|
+
interface ShaderMatrixStatus {
|
|
157
|
+
readonly schemaVersion: 1;
|
|
158
|
+
readonly root: string;
|
|
159
|
+
readonly state: ShaderMatrixState;
|
|
160
|
+
readonly reason: string;
|
|
161
|
+
readonly scenes: readonly ShaderSceneArtifactStatus[];
|
|
162
|
+
readonly runtime?: InstalledShaderRuntime;
|
|
163
|
+
readonly receipt?: ShaderReceiptV2;
|
|
164
|
+
readonly timing?: ShaderTiming;
|
|
165
|
+
}
|
|
166
|
+
/** Inspect all configured manifests without launching Vite, a browser, or a GPU. */
|
|
167
|
+
declare function inspectShaderMatrix(start?: string): Promise<ShaderMatrixStatus>;
|
|
168
|
+
|
|
169
|
+
declare const SHADER_PROVIDER_TRANSFORM_VERSION: 3;
|
|
170
|
+
interface ShaderSceneTiming {
|
|
171
|
+
/** Number of registered render/compute NodeBuilder builds covered by the manifest. */
|
|
172
|
+
readonly builds: number;
|
|
173
|
+
/** Cumulative NodeBuilder time in the live half of the capture. */
|
|
174
|
+
readonly liveBuildMs: number;
|
|
175
|
+
/** Cumulative NodeBuilder time in the precompiled half of the same capture. */
|
|
176
|
+
readonly precompiledBuildMs: number;
|
|
177
|
+
/** Non-negative live minus precompiled NodeBuilder time. */
|
|
178
|
+
readonly avoidedBuildMs: number;
|
|
179
|
+
/** Number of measured live/precompiled pairs represented by the medians. */
|
|
180
|
+
readonly runs: number;
|
|
181
|
+
/** Maximum absolute per-run saved-time deviation from the median. */
|
|
182
|
+
readonly spreadMs: number;
|
|
183
|
+
}
|
|
184
|
+
interface ShaderLocalTiming {
|
|
185
|
+
readonly schemaVersion: 3;
|
|
186
|
+
/** Binds this machine-local observation to the exact committed shader receipt. */
|
|
187
|
+
readonly receiptHash: string;
|
|
188
|
+
readonly measuredAt: string;
|
|
189
|
+
readonly source: 'latest-local-capture';
|
|
190
|
+
readonly scenes: Readonly<Record<string, ShaderSceneTiming>>;
|
|
191
|
+
}
|
|
192
|
+
interface ShaderCommittedTiming {
|
|
193
|
+
readonly schemaVersion: 3;
|
|
194
|
+
readonly receiptHash: string;
|
|
195
|
+
readonly measuredAt: string;
|
|
196
|
+
readonly source: 'committed-capture';
|
|
197
|
+
readonly adapter: string;
|
|
198
|
+
readonly platform: string;
|
|
199
|
+
readonly scenes: Readonly<Record<string, ShaderSceneTiming>>;
|
|
200
|
+
}
|
|
201
|
+
type ShaderTiming = ShaderLocalTiming | ShaderCommittedTiming;
|
|
202
|
+
interface ShaderSkippedBuild {
|
|
203
|
+
readonly kind: 'render' | 'compute';
|
|
204
|
+
readonly name: string;
|
|
205
|
+
readonly reason: string;
|
|
206
|
+
}
|
|
207
|
+
interface ShaderCaptureStats {
|
|
208
|
+
readonly buildCalls: number;
|
|
209
|
+
readonly renderBuilds: number;
|
|
210
|
+
readonly computeBuilds: number;
|
|
211
|
+
readonly registeredBuilds: number;
|
|
212
|
+
readonly registeredRenderBuilds: number;
|
|
213
|
+
readonly registeredComputeBuilds: number;
|
|
214
|
+
readonly buildMs: number;
|
|
215
|
+
readonly injected: number;
|
|
216
|
+
readonly injectedRender: number;
|
|
217
|
+
readonly injectedCompute: number;
|
|
218
|
+
readonly missed: number;
|
|
219
|
+
readonly missedRender: number;
|
|
220
|
+
readonly missedCompute: number;
|
|
221
|
+
/** Stable registered shader keys that fell back to a live build. */
|
|
222
|
+
readonly missedKeys?: readonly string[];
|
|
223
|
+
}
|
|
224
|
+
interface ShaderCaptureStageTiming {
|
|
225
|
+
readonly launch?: number;
|
|
226
|
+
readonly firstRequest?: number;
|
|
227
|
+
readonly readiness?: number;
|
|
228
|
+
readonly lastBuild?: number;
|
|
229
|
+
readonly settled?: number;
|
|
230
|
+
readonly posted?: number;
|
|
231
|
+
}
|
|
232
|
+
interface ShaderCaptureProvenance {
|
|
233
|
+
readonly userAgent: string;
|
|
234
|
+
readonly adapter: string;
|
|
235
|
+
readonly features: readonly string[];
|
|
236
|
+
}
|
|
237
|
+
interface ValidatedShaderCapture {
|
|
238
|
+
readonly scene: string;
|
|
239
|
+
readonly manifest: PrecompiledManifest;
|
|
240
|
+
readonly skipped: readonly ShaderSkippedBuild[];
|
|
241
|
+
readonly stats: ShaderCaptureStats;
|
|
242
|
+
readonly coverage: ShaderCoverage;
|
|
243
|
+
readonly timing?: ShaderCaptureStageTiming;
|
|
244
|
+
readonly provenance?: ShaderCaptureProvenance;
|
|
245
|
+
}
|
|
246
|
+
interface ValidateShaderCaptureOptions {
|
|
247
|
+
readonly scene: string;
|
|
248
|
+
readonly runtime: InstalledShaderRuntime;
|
|
249
|
+
}
|
|
250
|
+
/** Validate untrusted browser capture data through the public runtime manifest schema. */
|
|
251
|
+
declare function validateShaderCapture(value: unknown, options: ValidateShaderCaptureOptions): ValidatedShaderCapture;
|
|
252
|
+
declare function stableStringify(value: unknown, indent?: number): string;
|
|
253
|
+
interface WriteShaderArtifactsOptions {
|
|
254
|
+
readonly root: string;
|
|
255
|
+
readonly scenes: readonly ShaderSceneConfig[];
|
|
256
|
+
readonly captures: ReadonlyMap<string, ValidatedShaderCapture>;
|
|
257
|
+
readonly runtime: InstalledShaderRuntime;
|
|
258
|
+
readonly inputs: ReadonlyMap<string, Readonly<Record<string, string>>>;
|
|
259
|
+
readonly previousReceipt?: ShaderReceiptV2;
|
|
260
|
+
readonly publicDirectory?: string;
|
|
261
|
+
}
|
|
262
|
+
interface WrittenShaderArtifacts {
|
|
263
|
+
readonly directory: string;
|
|
264
|
+
readonly receipt: ShaderReceiptV2;
|
|
265
|
+
readonly files: readonly string[];
|
|
266
|
+
}
|
|
267
|
+
/** Write a complete deterministic scene matrix, with meta.json committed last. */
|
|
268
|
+
declare function writeShaderArtifacts(options: WriteShaderArtifactsOptions): Promise<WrittenShaderArtifacts>;
|
|
269
|
+
|
|
270
|
+
declare function loadShaderCaptureRuntimeSource(): Promise<string>;
|
|
271
|
+
|
|
272
|
+
export { type InstalledShaderRuntime, SHADER_PROVIDER_TRANSFORM_VERSION, type ShaderMatrixStatus, type ValidatedShaderCapture, inspectShaderMatrix, loadShaderCaptureRuntimeSource, loadShaderToolConfig, readInstalledShaderRuntime, snapshotShaderInputs, stableStringify, validateShaderCapture, writeShaderArtifacts };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {realpath,readFile,mkdir,readdir,unlink,lstat,open,rename,rm}from'fs/promises';import S from'path';import {THREE_WEBGPU_R185_COMPATIBILITY,parsePrecompiledManifest,SHADER_HYDRATION_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_ADDRESS_SCHEMA_VERSION,PRECOMPILED_MANIFEST_VERSION}from'three-blocks/shaders';import {createHash,randomUUID}from'crypto';import {createRequire}from'module';var pt=Object.defineProperty;var a=(e,t)=>pt(e,"name",{value:t,configurable:true});var k=Object.freeze({metadata:1024*1024,receipt:2*1024*1024,manifest:32*1024*1024,semanticInput:8*1024*1024,semanticTotal:64*1024*1024,metrics:8*1024*1024,texture:128*1024*1024,packageJson:1024*1024});function Ce(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:void 0}a(Ce,"errorCode");function A(e){return createHash("sha256").update(e).digest("hex")}a(A,"sha256");async function j(e){try{return await lstat(e),!0}catch(t){if(Ce(t)==="ENOENT")return false;throw t}}a(j,"pathExists");function N(e,t){let r=S.relative(e,t);return r===""||!S.isAbsolute(r)&&r!==".."&&!r.startsWith(`..${S.sep}`)}a(N,"isWithin");function F(e){return JSON.stringify(e)}a(F,"displayPath");async function Ie(e,t,r){let n=await open(e,"r");try{let[s,i,o]=await Promise.all([lstat(e),n.stat(),realpath(e)]);if(s.isSymbolicLink())throw new Error(`${r} must not be a symbolic link: ${F(e)}.`);if(!i.isFile())throw new Error(`${r} must be a regular file: ${F(e)}.`);if(i.size>t)throw new Error(`${r} exceeds the ${t}-byte inspection limit: ${F(e)}.`);let c=await n.readFile();if(c.byteLength>t)throw new Error(`${r} grew beyond the ${t}-byte inspection limit while being read.`);return {path:o,data:c}}finally{await n.close();}}a(Ie,"readBoundedRegularFile");async function Y(e,t){let r=S.dirname(e);await mkdir(r,{recursive:true});try{if((await lstat(e)).isSymbolicLink())throw new Error(`Atomic write target must not be a symbolic link: ${F(e)}.`)}catch(i){if(Ce(i)!=="ENOENT")throw i}let n=S.join(r,`.${S.basename(e)}.${process.pid}.${randomUUID()}.tmp`),s;try{s=await open(n,"wx",384),await s.writeFile(t),await s.sync(),await s.close(),s=void 0,await rename(n,e);}finally{await s?.close().catch(()=>{}),await rm(n,{force:true});}}a(Y,"writeAtomicRegularFile");async function ce(e,t,r){return Ie(e,t,r)}a(ce,"readExternalRegularFile");async function V(e,t,r){let n=S.resolve(e),s=S.resolve(t);if(!N(n,s))throw new Error(`${r} escapes its allowed directory.`);let i=await lstat(s);if(i.isSymbolicLink())throw new Error(`${r} must not be a symbolic link.`);if(!i.isDirectory())throw new Error(`${r} must be a directory.`);let[o,c]=await Promise.all([realpath(n),realpath(s)]);if(!N(o,c))throw new Error(`${r} resolves outside its allowed directory.`);return c}a(V,"canonicalDirectoryWithin");async function $(e,t,r,n){let s=S.resolve(e),i=S.resolve(t);if(!N(s,i)||s===i)throw new Error(`${n} escapes its allowed directory.`);let o=await Ie(i,r,n),c=await realpath(s);if(!N(c,o.path)||c===o.path)throw new Error(`${n} resolves outside its allowed directory.`);return o}a($,"readRegularFileWithin");async function _e(e,t,r,n=8192){let i=[await V(e,t,"Inspected directory")],o=[],c=0;for(;i.length>0;){let f=i.shift();if(f===void 0)break;let h=(await readdir(f,{withFileTypes:true})).sort((y,u)=>y.name.localeCompare(u.name));for(let y of h){if(c+=1,c>n)throw new Error(`Inspected directory exceeds the ${n}-entry limit.`);let u=S.join(f,y.name);if(y.isSymbolicLink())throw new Error(`Inspected directory contains a symbolic link: ${F(S.relative(e,u))}.`);if(y.isDirectory()){i.push(await V(e,u,"Nested inspected directory"));continue}if(y.isFile()&&r(y.name))o.push(u);else if(r(y.name))throw new Error(`Semantic input is not a regular file: ${F(u)}.`)}}return o.sort()}a(_e,"listRegularFilesRecursively");var Z=/^[a-f0-9]{64}$/,bt=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/,Me=/^[a-z0-9][a-z0-9_-]{0,63}$/,Pe=/^[0-9A-Za-z][0-9A-Za-z._/-]{0,127}$/;function l(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}a(l,"isRecord");function H(e){return typeof e=="string"&&bt.test(e)}a(H,"isSafeVersion");function ue(e){if(e.length===0||e.length>512||e.includes("\\")||/[\u0000-\u001f\u007f]/.test(e))return false;let t=e.split("/");return !e.startsWith("/")&&t.every(r=>r.length>0&&r!=="."&&r!=="..")}a(ue,"isSafeRelativePath");function Oe(e){if(!l(e)||e.schemaVersion!==2)throw new Error("three-blocks.json must use schemaVersion 2.");if(typeof e.template!="string"||!Me.test(e.template))throw new Error("three-blocks.json has an invalid default shader scene key.");if(!Array.isArray(e.layers)||!e.layers.every(t=>typeof t=="string"&&Pe.test(t))||new Set(e.layers).size!==e.layers.length)throw new Error("three-blocks.json has invalid layers.");if(e.generator!==void 0&&(!l(e.generator)||typeof e.generator.name!="string"||!Pe.test(e.generator.name)||!H(e.generator.version)))throw new Error("three-blocks.json has invalid generator metadata.");if(!l(e.runtime)||!H(e.runtime.three)||!H(e.runtime.threeBlocks))throw new Error("three-blocks.json has invalid runtime versions.");if(!l(e.features)||typeof e.features.text!="boolean")throw new Error("three-blocks.json has invalid feature metadata.");if(!l(e.protocol)||e.protocol.resultFile!==1)throw new Error("three-blocks.json has an unsupported protocol schema.");if(e.artifacts!==void 0){if(!l(e.artifacts)||typeof e.artifacts.shaders!="string"||!["fresh","pending"].includes(e.artifacts.shaders)||typeof e.artifacts.text!="string"||!["fresh","pending","not-applicable"].includes(e.artifacts.text))throw new Error("three-blocks.json has invalid artifact metadata.");if(e.features.text?e.artifacts.text==="not-applicable":e.artifacts.text!=="not-applicable")throw new Error("three-blocks.json text artifact state does not match the text capability.")}return {schemaVersion:2,template:e.template,layers:e.layers,...e.generator===void 0?{}:{generator:{name:e.generator.name,version:e.generator.version}},runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks},features:{text:e.features.text},...e.artifacts===void 0?{}:{artifacts:{shaders:e.artifacts.shaders,text:e.artifacts.text}},protocol:{resultFile:1}}}a(Oe,"parseProjectMetadata");function Et(e){if(!l(e))throw new Error("Shader coverage is missing.");for(let t of ["render","vertex","fragment","compute"])if(typeof e[t]!="number"||!Number.isSafeInteger(e[t])||e[t]<0)throw new Error(`Shader coverage.${t} must be a non-negative integer.`);return e}a(Et,"parseCoverage");function Rt(e,t){if(!l(e))throw new Error(`Shader receipt inputs for "${t}" are invalid.`);let r=Object.entries(e);if(r.length===0||r.length>4096)throw new Error(`Shader receipt inputs for "${t}" must contain between 1 and 4096 files.`);for(let[n,s]of r)if(!ue(n)||typeof s!="string"||!Z.test(s))throw new Error(`Shader receipt input for "${t}" is invalid.`)}a(Rt,"parseInputs");function Q(e){if(!l(e)||e.schemaVersion!==2||!l(e.runtime)||!H(e.runtime.three)||!H(e.runtime.threeBlocks)||typeof e.runtime.threeBlocksShaderClosure!="string"||!Z.test(e.runtime.threeBlocksShaderClosure)||!l(e.scenes))throw new Error("Shader meta.json does not match receipt schema 2.");if(e.runtime.capture!==void 0&&(!l(e.runtime.capture)||typeof e.runtime.capture.userAgent!="string"||e.runtime.capture.userAgent.length>1024||typeof e.runtime.capture.adapter!="string"||e.runtime.capture.adapter.length>1024||!Array.isArray(e.runtime.capture.features)||e.runtime.capture.features.length>256||!e.runtime.capture.features.every(r=>typeof r=="string"&&r.length>0&&r.length<=128)))throw new Error("Shader meta.json has invalid browser capture provenance.");let t=Object.entries(e.scenes);if(t.length===0)throw new Error("Shader meta.json contains no scenes.");for(let[r,n]of t){if(!Me.test(r)||!l(n)||typeof n.artifact!="string"||!ue(n.artifact)||!n.artifact.endsWith(".webgpu.ts")||typeof n.artifactHash!="string"||!Z.test(n.artifactHash))throw new Error(`Shader receipt for "${r}" is invalid.`);if(n.asset===void 0!=(n.assetHash===void 0)||n.asset!==void 0&&(typeof n.asset!="string"||!ue(n.asset)||!n.asset.endsWith(".json")||typeof n.assetHash!="string"||!Z.test(n.assetHash)))throw new Error(`Shader static asset receipt for "${r}" is invalid.`);if(Rt(n.inputs,r),Et(n.coverage),n.bytes!==void 0&&(!Number.isSafeInteger(n.bytes)||Number(n.bytes)<0))throw new Error(`Shader receipt byte count for "${r}" is invalid.`);if(n.skipped!==void 0&&(!l(n.skipped)||!Number.isSafeInteger(n.skipped.render)||Number(n.skipped.render)<0||!Number.isSafeInteger(n.skipped.compute)||Number(n.skipped.compute)<0))throw new Error(`Shader receipt skipped-build counts for "${r}" are invalid.`)}if(e.tool!==void 0&&(!l(e.tool)||e.tool.name!=="@three-blocks/devtools"||!H(e.tool.version)||typeof e.tool.compatibility!="string"||!Number.isSafeInteger(e.tool.transform)||!Number.isSafeInteger(e.tool.address)||!Number.isSafeInteger(e.tool.recipe)||!Number.isSafeInteger(e.tool.hydration)))throw new Error("Shader meta.json has invalid tool compatibility metadata.");return e}a(Q,"parseShaderReceipt");var De="three-blocks.shaders.json",pe=".three-blocks/shaders";var xt=/^[a-z0-9][a-z0-9_-]{0,63}$/u,Tt=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u,Ne=64,Be=64,jt={schemaVersion:1,scenes:[{key:"default",url:"/"}]};function ve(e,t,r){if(e===void 0)return r;if(typeof e!="string"||e.length===0||e.length>512||S.isAbsolute(e)||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${t} must be a bounded project-relative directory.`);let n=S.posix.normalize(e.replaceAll("\\","/")).replace(/\/+$/u,"");if(n==="."||n===".."||n.startsWith("../"))throw new Error(`${t} must stay inside the project.`);return n}a(ve,"safeProjectDirectory");function At(e,t){let r=ve(e,t,"");if(typeof e!="string"||e.endsWith("/"))throw new Error(`${t} must be a project-relative file.`);return r}a(At,"safeProjectFile");function B(e,t,r,n,s){if(e===void 0)return s;if(!Number.isSafeInteger(e)||Number(e)<r||Number(e)>n)throw new Error(`${t} must be an integer in ${r}...${n}.`);return Number(e)}a(B,"boundedInteger");function Le(e,t,r){if(e===void 0)return r;if(typeof e!="number"||!Number.isFinite(e)||e<0||e>1)throw new Error(`${t} must be a finite ratio in 0...1.`);return e}a(Le,"finiteRatio");function Fe(e,t){if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${t} must be a bounded project-relative URL.`);let r;try{r=new URL(e,"http://three-blocks.invalid/");}catch{throw new Error(`${t} is not a valid URL.`)}if(r.origin!=="http://three-blocks.invalid"||r.hash.length>0)throw new Error(`${t} must stay within the project and must not contain a fragment.`);return `${r.pathname}${r.search}`}a(Fe,"safeBrowserUrl");function $t(e){if(!Array.isArray(e)||e.length===0||e.length>Ne)throw new Error(`Shader config scenes must contain 1...${Ne} entries.`);let t=new Set;return e.map((r,n)=>{if(!l(r)||typeof r.key!="string"||!xt.test(r.key))throw new Error(`Shader config scene ${n} has an invalid key.`);if(t.has(r.key))throw new Error(`Shader config scene key "${r.key}" is duplicated.`);t.add(r.key);let s=r.parityFrames,i=r.maxDiffRatio;if(r.inputs!==void 0&&(!Array.isArray(r.inputs)||r.inputs.length===0||r.inputs.length>Be))throw new Error(`Shader config scene "${r.key}" inputs must contain 1...${Be} files.`);let o=r.inputs===void 0?void 0:r.inputs.map((c,f)=>At(c,`Shader config scene "${r.key}" input ${f}`));if(o!==void 0&&new Set(o).size!==o.length)throw new Error(`Shader config scene "${r.key}" inputs must be unique.`);if(r.allowPipelineReuse!==void 0&&typeof r.allowPipelineReuse!="boolean")throw new Error(`Shader config scene "${r.key}" allowPipelineReuse must be a boolean.`);if(r.runtimeMotion!==void 0&&typeof r.runtimeMotion!="boolean")throw new Error(`Shader config scene "${r.key}" runtimeMotion must be a boolean.`);return {key:r.key,url:Fe(r.url,`Shader config scene "${r.key}" URL`),requiresText:r.requiresText===true,...o===void 0?{}:{inputs:o},...s===void 0?{}:{parityFrames:B(s,`Shader config scene "${r.key}" parityFrames`,0,1e4,0)},...i===void 0?{}:{maxDiffRatio:Le(i,`Shader config scene "${r.key}" maxDiffRatio`,.01)},...r.allowPipelineReuse===true?{allowPipelineReuse:true}:{},...r.runtimeMotion===true?{runtimeMotion:true}:{}}})}a($t,"parseScenes");function fe(e){if(!l(e)||e.schemaVersion!==void 0&&e.schemaVersion!==1)throw new Error("Shader config must use schemaVersion 1.");let t=e.viewport;if(t!==void 0&&!l(t))throw new Error("Shader config viewport must be an object.");let r=e.parity;if(r!==void 0&&!l(r))throw new Error("Shader config parity must be an object.");let n=e.bridge;if(n!==void 0&&!l(n))throw new Error("Shader config bridge must be an object.");let s=l(n)?n.deterministicModule:void 0;s!==void 0&&Fe(s,"Shader deterministic module");let i=e.readiness;if(i!==void 0&&!l(i))throw new Error("Shader config readiness must be an object.");let o=l(i)?i.selector:void 0;if(o!==void 0&&(typeof o!="string"||o.length===0||o.length>512||/[\u0000-\u001f\u007f]/u.test(o)))throw new Error("Shader readiness selector must be a bounded, non-empty CSS selector.");let c=l(i)?i.global:void 0;if(c!==void 0&&(typeof c!="string"||!Tt.test(c)))throw new Error("Shader readiness global must be a dot-separated JavaScript property path.");return {schemaVersion:1,scenes:$t(e.scenes),settleFrames:B(e.settleFrames,"Shader settleFrames",0,1e4,60),settleTimeoutMs:B(e.settleTimeoutMs,"Shader settleTimeoutMs",1e3,15*6e4,3e4),browserRelaunchScenes:B(e.browserRelaunchScenes,"Shader browserRelaunchScenes",1,64,8),timeoutMs:B(e.timeoutMs,"Shader timeoutMs",1e3,15*6e4,24e4),viewport:{width:B(l(t)?t.width:void 0,"Shader viewport width",64,8192,1024),height:B(l(t)?t.height:void 0,"Shader viewport height",64,8192,640)},parity:{frames:B(l(r)?r.frames:void 0,"Shader parity frames",0,1e4,90),channelTolerance:B(l(r)?r.channelTolerance:void 0,"Shader parity channelTolerance",0,255,8),maxDiffRatio:Le(l(r)?r.maxDiffRatio:void 0,"Shader parity maxDiffRatio",.01)},bridge:{legacyLab:l(n)&&n.legacyLab===true,...typeof s=="string"?{deterministicModule:s}:{}},readiness:{...typeof o=="string"?{selector:o}:{},...typeof c=="string"?{global:c}:{}},publicDir:ve(e.publicDir,"Shader publicDir","public"),allowLiveBuilds:e.allowLiveBuilds!==false}}a(fe,"parseShaderToolConfig");async function Ve(e=process.cwd()){let t=S.resolve(e);for(;;){if(await j(S.join(t,De))||await j(S.join(t,"three-blocks.json")))return realpath(t);let r=S.join(t,"package.json");if(await j(r)){let s=await $(t,r,k.packageJson,"Project package.json"),i;try{i=JSON.parse(s.data.toString("utf8"));}catch{throw new Error(`Project package.json is not valid JSON: ${r}.`)}if(l(i)&&[i.dependencies,i.devDependencies,i.peerDependencies,i.optionalDependencies].filter(l).some(f=>typeof f.three=="string"||typeof f["three-blocks"]=="string"||typeof f["@three-blocks/devtools"]=="string"))return realpath(t)}let n=S.dirname(t);if(n===t)throw new Error(`No Three Blocks shader project found from ${JSON.stringify(S.resolve(e))}; add Three.js to package.json or pass --root.`);t=n;}}a(Ve,"findShaderProjectRoot");async function me(e){let t=await realpath(e),r=S.join(t,De);if(await j(r)){let s=await $(t,r,k.metadata,"Shader configuration");return fe(JSON.parse(s.data.toString("utf8")))}let n=S.join(t,"three-blocks.json");if(await j(n)){let s=Oe(JSON.parse(await readFile(n,"utf8")));return fe({schemaVersion:1,scenes:[{key:s.template,url:"/",requiresText:s.features.text}]})}return fe(jt)}a(me,"loadShaderToolConfig");var W="0.1.0";var ne=3,_t="timing.local.json",Pt="timing.json";var re=4096,Mt=4096;function he(e,t,r=8192){if(typeof e!="string"||e.length===0||e.length>r||/[\u0000\u007f]/u.test(e))throw new Error(`${t} must be a bounded non-empty string.`);return e}a(he,"boundedString");function R(e,t,r=true){if(typeof e!="number"||!Number.isFinite(e)||e<0||r&&!Number.isSafeInteger(e))throw new Error(`${t} must be a non-negative ${r?"integer":"finite number"}.`);return e}a(R,"nonNegativeNumber");function Ot(e){if(!l(e))throw new Error("Shader capture stats are missing.");let t={buildCalls:R(e.buildCalls,"capture stats.buildCalls"),renderBuilds:R(e.renderBuilds,"capture stats.renderBuilds"),computeBuilds:R(e.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:R(e.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:R(e.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:R(e.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:R(e.buildMs,"capture stats.buildMs",false),injected:R(e.injected,"capture stats.injected"),injectedRender:R(e.injectedRender,"capture stats.injectedRender"),injectedCompute:R(e.injectedCompute,"capture stats.injectedCompute"),missed:R(e.missed,"capture stats.missed"),missedRender:R(e.missedRender,"capture stats.missedRender"),missedCompute:R(e.missedCompute,"capture stats.missedCompute"),...Array.isArray(e.missedKeys)&&e.missedKeys.every(r=>typeof r=="string")?{missedKeys:e.missedKeys.slice(0,re)}:{}};if(t.renderBuilds+t.computeBuilds!==t.buildCalls||t.registeredRenderBuilds+t.registeredComputeBuilds!==t.registeredBuilds||t.injectedRender+t.injectedCompute!==t.injected||t.missedRender+t.missedCompute!==t.missed||t.registeredBuilds>t.buildCalls)throw new Error("Shader capture stats totals are inconsistent.");return t}a(Ot,"captureStats");function Nt(e){if(!Array.isArray(e)||e.length>re)throw new Error("Shader capture skipped builds are invalid.");return e.map((t,r)=>{if(!l(t)||t.kind!=="render"&&t.kind!=="compute")throw new Error(`Shader capture skipped build ${r} is invalid.`);return {kind:t.kind,name:he(t.name,`skipped build ${r} name`,512),reason:he(t.reason,`skipped build ${r} reason`)}})}a(Nt,"skippedBuilds");function Bt(e){let t=0,r=0,n=0,s=0;for(let i of Object.values(e.entries)){let o=e.states[i];o!==void 0&&((o.vertex!==null||o.fragment!==null)&&t++,o.vertex!==null&&r++,o.fragment!==null&&n++,o.compute!==null&&s++);}return {render:t,vertex:r,fragment:n,compute:s}}a(Bt,"shaderCoverage");function Dt(e,t){if(!l(e))throw new Error("Shader capture payload must be an object.");if(e.scene!==t.scene)throw new Error(`Shader capture scene does not match "${t.scene}".`);if(e.protocolVersion!==2)throw new Error("Shader capture protocolVersion must be 2.");if(e.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)throw new Error(`Shader capture compatibility must be "${THREE_WEBGPU_R185_COMPATIBILITY}".`);if(!l(e.entries))throw new Error("Shader capture entries must be an object.");let r=Object.keys(e.entries).length;if(r===0||r>re)throw new Error(`Shader capture must contain 1...${re} entries.`);if(!Array.isArray(e.errors)||e.errors.length>Mt)throw new Error("Shader capture errors are invalid.");let n=e.errors.map((u,d)=>he(u,`capture error ${d}`,64*1024));if(n.length>0)throw new Error(`Shader capture failed:
|
|
2
|
+
- ${n.join(`
|
|
3
|
+
- `)}`);let s=Nt(e.skipped),i=Ot(e.stats),o=l(e.timing)?e.timing:void 0,c=o===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(u=>{let d=o[u];if(d===void 0)return [];if(typeof d!="number"||!Number.isFinite(d)||d<0)throw new Error(`Shader capture timing.${u} is invalid.`);return [[u,d]]})),f;if(e.provenance!==void 0){if(!l(e.provenance)||typeof e.provenance.userAgent!="string"||e.provenance.userAgent.length>1024||typeof e.provenance.adapter!="string"||e.provenance.adapter.length>1024||!Array.isArray(e.provenance.features)||e.provenance.features.length>256||!e.provenance.features.every(u=>typeof u=="string"&&u.length<=128))throw new Error("Shader capture provenance is invalid.");f={userAgent:e.provenance.userAgent,adapter:e.provenance.adapter,features:[...new Set(e.provenance.features)].sort()};}let h=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:t.scene,three:t.runtime.three,threeBlocks:t.runtime.threeBlocks,runtime:{id:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...e.automatic===void 0?{}:{automatic:e.automatic},modules:e.modules,nodes:e.nodes,layouts:e.layouts,attributePlans:e.attributePlans,updatePlans:e.updatePlans,requirementPlans:e.requirementPlans,states:e.states,entries:e.entries}),y=Bt(h);if(i.registeredRenderBuilds<y.render||i.registeredComputeBuilds<y.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:t.scene,manifest:h,skipped:s,stats:i,coverage:y,...c===void 0?{}:{timing:c},...f===void 0?{}:{provenance:f}}}a(Dt,"validateShaderCapture");function z(e,t=0){let r=" ".repeat(t),n=" ".repeat(t+1);if(Array.isArray(e))return e.length===0?"[]":e.every(i=>i===null||["number","string","boolean"].includes(typeof i))?JSON.stringify(e):`[
|
|
4
|
+
${e.map(i=>`${n}${z(i,t+1)}`).join(`,
|
|
5
|
+
`)}
|
|
6
|
+
${r}]`;if(e!==null&&typeof e=="object"){let i=e,o=Object.keys(i).sort();return o.length===0?"{}":`{
|
|
7
|
+
${o.map(c=>{let f=i[c];return `${n}${JSON.stringify(c)}: ${z(f,t+1)}`}).join(`,
|
|
8
|
+
`)}
|
|
9
|
+
${r}}`}let s=JSON.stringify(e);if(s===void 0)throw new Error("Shader artifact contains a non-serializable value.");return s}a(z,"stableStringify");function vt(e){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${z(e)} satisfies PrecompiledManifest;`,""].join(`
|
|
10
|
+
`)}a(vt,"serializeShaderManifest");function Ue(e,t){if(typeof e!="string"||e.length===0||e.length>256||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${t} is invalid.`);return e}a(Ue,"timingLabel");function Lt(e){if(!l(e)||e.schemaVersion!==3||e.source!=="latest-local-capture"&&e.source!=="committed-capture"||typeof e.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(e.receiptHash)||typeof e.measuredAt!="string"||!Number.isFinite(Date.parse(e.measuredAt))||!l(e.scenes))throw new Error("Shader timing is invalid.");let t={};for(let[n,s]of Object.entries(e.scenes)){if(n.length===0||n.length>128||!l(s))throw new Error("Shader timing scene is invalid.");let i={builds:R(s.builds,`timing ${n}.builds`),liveBuildMs:R(s.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:R(s.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:R(s.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:R(s.runs,`timing ${n}.runs`),spreadMs:R(s.spreadMs,`timing ${n}.spreadMs`,false)};if(i.runs<1)throw new Error(`Shader timing runs are invalid for scene "${n}".`);if(Math.abs(i.avoidedBuildMs-Math.max(0,i.liveBuildMs-i.precompiledBuildMs))>.001)throw new Error(`Shader timing delta is inconsistent for scene "${n}".`);t[n]=i;}if(Object.keys(t).length===0)throw new Error("Shader timing contains no scenes.");let r={schemaVersion:3,receiptHash:e.receiptHash,measuredAt:e.measuredAt,scenes:t};return e.source==="latest-local-capture"?{...r,source:"latest-local-capture"}:{...r,source:"committed-capture",adapter:Ue(e.adapter,"Shader timing adapter"),platform:Ue(e.platform,"Shader timing platform")}}a(Lt,"parseShaderTiming");async function We(e,t,r,n){let s=S.join(e,r);try{if(!await j(s))return;let i=await lstat(s);if(i.isSymbolicLink()||!i.isFile()||i.size>1024*1024)return;let o=Lt(JSON.parse(await readFile(s,"utf8")));return o.source===n&&o.receiptHash===A(t)?o:void 0}catch{return}}a(We,"readShaderTimingFile");async function Ze(e,t){return await We(e,t,_t,"latest-local-capture")??await We(e,t,Pt,"committed-capture")}a(Ze,"readShaderTiming");async function Je(e){if(!await j(e)){await mkdir(e);return}let t=await lstat(e);if(t.isSymbolicLink()||!t.isDirectory())throw new Error(`Shader artifact path is not a real directory: ${e}.`)}a(Je,"assertDirectory");async function Ft(e){let t=S.resolve(e),r=S.join(t,".three-blocks");await Je(r);let n=S.join(r,"shaders");return await Je(n),n}a(Ft,"artifactRoot");async function Vt(e){let t=await Ft(e.root),r=S.resolve(e.root),n=S.resolve(r,e.publicDirectory??"public");if(!N(r,n)||n===r)throw new Error("Shader public directory must stay inside the project root.");let s=S.join(n,"three-blocks","shaders");await mkdir(s,{recursive:true}),await V(r,s,"Shader static-asset directory");let i={},o=[];for(let d of [...e.scenes].sort((p,g)=>p.key.localeCompare(g.key))){let p=e.captures.get(d.key),g=e.inputs.get(d.key);if(g===void 0)throw new Error(`Shader input matrix is missing scene "${d.key}".`);if(p===void 0){let m=e.previousReceipt?.scenes[d.key];if(m===void 0)throw new Error(`Capture matrix is missing scene "${d.key}".`);let b=await readFile(S.join(t,m.artifact));if(A(b)!==m.artifactHash)throw new Error(`Preserved shader artifact checksum differs for scene "${d.key}".`);if(m.asset!==void 0&&m.assetHash!==void 0){let _=await readFile(S.join(n,m.asset));if(A(_)!==m.assetHash)throw new Error(`Preserved static shader manifest checksum differs for scene "${d.key}".`)}i[d.key]={...m,inputs:Object.fromEntries(Object.entries(g).sort(([_],[L])=>_.localeCompare(L)))},o.push(m.artifact),m.asset!==void 0&&o.push(S.relative(r,S.join(n,m.asset)).split(S.sep).join("/"));continue}if(p.scene!==d.key||p.manifest.scene!==d.key)throw new Error(`Capture matrix scene "${d.key}" is inconsistent.`);let E=`${d.key}.webgpu.ts`,x=vt(p.manifest);await Y(S.join(t,E),x),o.push(E);let P=`three-blocks/shaders/${d.key}.json`,C=`${z(p.manifest)}
|
|
11
|
+
`;await Y(S.join(n,P),C),o.push(S.relative(r,S.join(n,P)).split(S.sep).join("/"));let O=p.skipped.filter(m=>m.kind==="render").length,D=p.skipped.length-O;i[d.key]={artifact:E,artifactHash:A(x),asset:P,assetHash:A(C),inputs:Object.fromEntries(Object.entries(g).sort(([m],[b])=>m.localeCompare(b))),coverage:p.coverage,bytes:Buffer.byteLength(x),skipped:{render:O,compute:D}};}let c=[...e.captures.values()].find(d=>d.provenance!==void 0)?.provenance??e.previousReceipt?.runtime.capture,f={schemaVersion:2,runtime:{...e.runtime,...c===void 0?{}:{capture:c}},tool:{name:"@three-blocks/devtools",version:W,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,transform:ne,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:i},h=new Set(o);for(let d of await readdir(t,{withFileTypes:true}))if(!(!d.name.endsWith(".webgpu.ts")||h.has(d.name))){if(d.isSymbolicLink()||!d.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${d.name}.`);await unlink(S.join(t,d.name));}let y=new Set(e.scenes.map(d=>`${d.key}.json`)),u=new Set(Object.values(e.previousReceipt?.scenes??{}).map(d=>d.asset===void 0?void 0:S.posix.basename(d.asset)).filter(d=>d!==void 0));try{let d=Q(JSON.parse(await readFile(S.join(t,"meta.json"),"utf8")));for(let p of Object.values(d.scenes))p.asset!==void 0&&u.add(S.posix.basename(p.asset));}catch{}for(let d of await readdir(s,{withFileTypes:true}))if(!(!d.name.endsWith(".json")||y.has(d.name))&&u.has(d.name)){if(d.isSymbolicLink()||!d.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${d.name}.`);await unlink(S.join(s,d.name));}return await Y(S.join(t,"meta.json"),`${z(f)}
|
|
12
|
+
`),o.push("meta.json"),{directory:t,receipt:f,files:o}}a(Vt,"writeShaderArtifacts");var ye=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".wgsl",".glsl",".vert",".frag",".json",".css"],Se=new Set(ye),ge=/^(?:three-blocks\.shaders\.json|(?:precompile|three-blocks\.shaders)\.config\.(?:cjs|cts|js|mjs|mts|ts))$/u,zt=/(?:^|\/)scene\.(?:cjs|cts|js|jsx|mjs|mts|ts|tsx)$/u,Ut=/\b(?:export\s+)?(?:async\s+)?function\s+createScene\b|\bcreateScene\s*=\s*(?:async\s*)?\(/u,Wt=/\b(?:[A-Za-z_$][\w$]*\.)*(?:shaders|shaderCache|sceneShaders)\s*\.\s*(?:material|pipeline|compute|container)\s*\(/u,Jt=/\b(import|export)(?!\s*\()\s*(type\b\s*)?(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']/gu,qt=/\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Gt=/\b(?:import|export)(?!\s*\()\s*(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Kt=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/u,we=4096,Xt="./shaders";function tt(e,t){let r=S.relative(e,t).split(S.sep).join("/");if(r.length===0||/[\u0000-\u001f\u007f]/u.test(r))throw new Error("Semantic input has an unsafe relative path.");return r}a(tt,"portableRelativePath");function be(e,t){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{throw new Error(`Shader-relevant source ${JSON.stringify(t)} is not valid UTF-8.`)}}a(be,"sourceText");function Re(e,t){let r="",n="code";for(let s=0;s<e.length;s++){let i=e[s]??"",o=e[s+1]??"";if(n==="code"){if(i==="/"&&o==="/"){r+=" ",n="line-comment",s++;continue}if(i==="/"&&o==="*"){r+=" ",n="block-comment",s++;continue}if(i==="'"||i==='"'||i==="`"){n=i==="'"?"single":i==='"'?"double":"template",r+=t?i:" ";continue}r+=i;continue}if(n==="line-comment"){i===`
|
|
13
|
+
`?(r+=`
|
|
14
|
+
`,n="code"):r+=" ";continue}if(n==="block-comment"){i==="*"&&o==="/"?(r+=" ",n="code",s++):r+=i===`
|
|
15
|
+
`?`
|
|
16
|
+
`:" ";continue}let c=n==="single"?"'":n==="double"?'"':"`";if(i==="\\"&&o.length>0){r+=t?`${i}${o}`:" ",s++;continue}r+=t?i:i===`
|
|
17
|
+
`?`
|
|
18
|
+
`:" ",i===c&&(n="code");}return r}a(Re,"lexicalSource");function Yt(e){let t=new Set,r=Re(e,true);for(let n of r.matchAll(Jt))n[2]===void 0&&n[3]!==void 0&&t.add(n[3]);for(let n of r.matchAll(qt))n[1]!==void 0&&t.add(n[1]);return [...t].sort()}a(Yt,"importSpecifiers");function Zt(e){let t=new Set;for(let r of Re(e,true).matchAll(Gt)){let n=r[1]??r[2];n!==void 0&&t.add(n);}return [...t].sort()}a(Zt,"runtimeSpecifiers");function rt(e){return (e.split(/[?#]/u,1)[0]??e).replaceAll("\\","/")}a(rt,"cleanSpecifier");function Qt(e,t,r){let n=rt(t),s;if(n.startsWith("./")||n.startsWith("../"))s=S.posix.normalize(S.posix.join(S.posix.dirname(e),n));else if(n.startsWith("@/"))s=`src/${n.slice(2)}`;else if(n.startsWith("/src/"))s=n.slice(1);else return;if(s===".three-blocks"||s.startsWith(".three-blocks/"))return;let i=S.posix.extname(s).toLowerCase(),o=new Set([s]);if(i.length===0||!Se.has(i)){for(let c of ye)o.add(`${s}${c}`);for(let c of ye)o.add(`${s}/index${c}`);}else if([".js",".mjs",".cjs",".jsx"].includes(i)){let c=s.slice(0,-i.length);for(let f of [".ts",".tsx",".mts",".cts"])o.add(`${c}${f}`);}return [...o].find(c=>r.has(c))}a(Qt,"resolveProjectImport");function er(e,t){let r=Re(t,false);return zt.test(e)||Ut.test(r)||Wt.test(r)}a(er,"isShaderRoot");async function ke(e,t){let r=await realpath(e);if(t!==void 0){let u={},d=0;for(let p of t){let g=await $(r,S.join(r,p),k.semanticInput,"Declared shader semantic input");if(d+=g.data.byteLength,d>k.semanticTotal)throw new Error("Declared shader semantic inputs exceed the total inspection size limit.");u[p]=A(g.data);}return u}let n=new Map,s=S.join(r,"src");if(await j(s))for(let u of await _e(r,s,d=>Se.has(S.extname(d).toLowerCase()))){let d=await $(r,u,k.semanticInput,"Shader semantic input");n.set(tt(r,u),d.data);}for(let u of await readdir(r,{withFileTypes:true})){if(!u.isFile()||!ge.test(u.name)&&!Se.has(S.extname(u.name).toLowerCase()))continue;let d=await $(r,S.join(r,u.name),k.semanticInput,ge.test(u.name)?"Shader configuration input":"Shader semantic input");n.set(u.name,d.data);}if(n.size>we)throw new Error(`Shader input discovery exceeds the ${we}-file limit.`);let i=new Set,o=new Map;for(let[u,d]of n){if(!u.includes("/")&&ge.test(u)&&i.add(u),!u.startsWith("src/"))continue;let p=be(d,u);o.set(u,p),er(u,p)&&i.add(u);}if(i.size===0)throw new Error("No shader registration or scene source root was found.");let c=new Set,f=[...i].sort();for(;f.length>0;){let u=f.shift();if(u===void 0||c.has(u))continue;let d=n.get(u);if(d===void 0)continue;c.add(u);let p=o.get(u)??be(d,u);for(let g of Yt(p)){let E=Qt(u,g,n);E!==void 0&&!c.has(E)&&f.push(E);}f.sort();}let h=0,y={};for(let u of [...c].sort()){let d=n.get(u);if(d===void 0)throw new Error(`Shader input ${JSON.stringify(u)} disappeared during inspection.`);if(h+=d.byteLength,h>k.semanticTotal)throw new Error("Semantic shader inputs exceed the total inspection size limit.");y[u]=A(d);}return y}a(ke,"snapshotShaderInputs");function Ee(e){if(typeof e=="string")return e;if(l(e))return Ee(e.import)??Ee(e.default)}a(Ee,"conditionalImportTarget");async function Qe(e,t){let r=e;for(;;){let n=S.join(r,"node_modules",...t.split("/"),"package.json");if(await j(n)){let i=await ce(n,k.packageJson,`${t} package.json`),o=JSON.parse(i.data.toString("utf8"));if(!l(o)||o.name!==t||typeof o.version!="string"||!Kt.test(o.version))throw new Error(`Installed ${t} package metadata is invalid.`);return {root:S.dirname(i.path),manifest:o}}let s=S.dirname(r);if(s===r)break;r=s;}throw new Error(`Cannot verify the installed ${t} package.`)}a(Qe,"findInstalledPackage");async function tr(e,t){if(!l(t.exports))throw new Error("Installed three-blocks package has no public exports map.");let r=Ee(t.exports[Xt]);if(r===void 0||!r.startsWith("./"))throw new Error("Installed three-blocks shader export has no import target.");let n=await realpath(e),s=[S.resolve(n,r)],i=new Map,o=0;for(;s.length>0;){let f=s.shift();if(f===void 0)break;let h=await ce(f,k.semanticInput,"Three Blocks shader runtime module");if(!N(n,h.path)||h.path===n)throw new Error("Three Blocks shader runtime closure escapes its package.");let y=tt(n,h.path);if(i.has(y))continue;if(o+=h.data.byteLength,o>k.semanticTotal)throw new Error("Three Blocks shader runtime closure exceeds the inspection limit.");i.set(y,A(h.data));let u=be(h.data,y);for(let d of Zt(u)){let p=rt(d);if(!p.startsWith("./")&&!p.startsWith("../"))continue;let g=S.resolve(S.dirname(h.path),p);if(!N(n,g))throw new Error("Three Blocks shader runtime import escapes its package.");s.push(g);}if(s.sort(),i.size+s.length>we)throw new Error("Three Blocks shader runtime closure exceeds the file limit.")}let c=[...i].sort((f,h)=>f[0].localeCompare(h[0])).map(([f,h])=>`${f}\0${h}`).join(`
|
|
19
|
+
`);return A(c)}a(tr,"shaderRuntimeClosure");async function xe(e){let[t,r]=await Promise.all([Qe(e,"three"),Qe(e,"three-blocks")]);return {three:String(t.manifest.version),threeBlocks:String(r.manifest.version),threeBlocksShaderClosure:await tr(r.root,r.manifest)}}a(xe,"readInstalledShaderRuntime");var J;async function nr(){J===void 0&&(J=(async()=>{let t=createRequire(S.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),r=S.resolve(S.dirname(t),"../..");return (await $(r,t,k.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let e=J;try{return await e}catch(t){throw J===e&&(J=void 0),t}}a(nr,"loadShaderCaptureRuntimeSource");var nt=4096,sr=createRequire(import.meta.url),it,w=new Proxy({},{get(e,t){return it??=sr("typescript"),Reflect.get(it,t)}});function v(e){let t=e;for(;w.isParenthesizedExpression(t)||w.isAsExpression(t)||w.isSatisfiesExpression(t)||w.isNonNullExpression(t);)t=t.expression;return t}a(v,"unwrap");function or(e){if(w.isIdentifier(e)||w.isStringLiteral(e)||w.isNumericLiteral(e))return e.text}a(or,"propertyName");function ie(e,t){let r=new Map;for(let n of e.properties){if(!w.isPropertyAssignment(n))throw new Error(`${t} may contain only static property assignments.`);let s=or(n.name);if(s===void 0||r.has(s))throw new Error(`${t} contains a computed or duplicate property.`);r.set(s,n.initializer);}return r}a(ie,"properties");function se(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=v(e);if(!w.isObjectLiteralExpression(r))throw new Error(`${t} must be a static object literal.`);return r}a(se,"objectLiteral");function oe(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=v(e);if(!w.isStringLiteral(r)&&!w.isNoSubstitutionTemplateLiteral(r))throw new Error(`${t} must be a string literal.`);return r.text}a(oe,"stringLiteral");function ae(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=v(e);if(!w.isNumericLiteral(r))throw new Error(`${t} must be a numeric literal.`);return Number(r.text)}a(ae,"numericLiteral");function st(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=v(e);if(!w.isArrayLiteralExpression(r))throw new Error(`${t} must be a static array literal.`);return r.elements}a(st,"arrayLiteral");function ar(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=v(e);if(r.kind===w.SyntaxKind.NullKeyword)return null;if(!w.isNumericLiteral(r))throw new Error(`${t} must be null or a numeric literal.`);return Number(r.text)}a(ar,"numericOrNullLiteral");function dr(e){return e.parseDiagnostics??[]}a(dr,"parseDiagnostics");function ot(e,t,r,n){let s=w.createSourceFile(t,e,w.ScriptTarget.Latest,true,w.ScriptKind.TS),i=dr(s);if(i.length>0)throw new Error(`Shader manifest is not valid TypeScript: ${w.flattenDiagnosticMessageText(i[0]?.messageText??"parse error"," ")}`);let o=s.statements.filter(w.isExportAssignment).filter(p=>!p.isExportEquals);if(o.length!==1)throw new Error("Shader manifest must contain exactly one default export.");let c=ie(se(o[0]?.expression,"Shader manifest default export"),"Shader manifest"),f=c.get("version");if(f===void 0||!w.isNumericLiteral(v(f))||Number(v(f).getText(s))!==3)throw new Error("Shader manifest version must be the numeric literal 3.");if(oe(c.get("scene"),"Shader manifest scene")!==r)throw new Error(`Shader manifest scene does not match "${r}".`);if(n){if(oe(c.get("three"),"Shader manifest Three.js version")!==n.three||oe(c.get("threeBlocks"),"Shader manifest Three Blocks version")!==n.threeBlocks)throw new Error("Shader manifest runtime versions do not match its receipt.");let p=ie(se(c.get("runtime"),"Shader manifest runtime"),"Shader manifest runtime");if(oe(p.get("id"),"Shader manifest runtime id")!==n.compatibility||ae(p.get("address"),"Shader manifest address schema")!==n.address||ae(p.get("recipe"),"Shader manifest recipe schema")!==n.recipe||ae(p.get("hydration"),"Shader manifest hydration schema")!==n.hydration)throw new Error("Shader manifest runtime compatibility schemas do not match its receipt.")}let h=ie(se(c.get("entries"),"Shader manifest entries"),"Shader manifest entries");if(h.size===0||h.size>nt)throw new Error(`Shader manifest must contain between 1 and ${nt} entries.`);let y=st(c.get("modules"),"Shader manifest modules").map((p,g)=>{let E=v(p);if(!w.isStringLiteral(E)&&!w.isNoSubstitutionTemplateLiteral(E))throw new Error(`Shader manifest module ${g} must be a WGSL string literal.`);if(E.text.length===0)throw new Error(`Shader manifest module ${g} is empty.`);return E.text}),u=st(c.get("states"),"Shader manifest states").map((p,g)=>{let E=ie(se(p,`Shader manifest state ${g}`),`Shader manifest state ${g}`),x=a((D,m)=>{let b=ar(E.get(D),`Shader manifest state ${g} ${D}`);if(b===null)return false;let _=y[b];if(_===void 0||!_.includes(m))throw new Error(`Shader manifest state ${g} ${D} does not reference a ${m} module.`);return true},"moduleAt"),P=x("vertex","@vertex"),C=x("fragment","@fragment"),O=x("compute","@compute");if(O&&(P||C))throw new Error(`Shader manifest state ${g} mixes render and compute stages.`);if(!O&&!P&&!C)throw new Error(`Shader manifest state ${g} contains no shader stage.`);return {vertex:P,fragment:C,compute:O}}),d={render:0,vertex:0,fragment:0,compute:0};for(let[p,g]of h){if(p.length===0||/[\u0000-\u001f\u007f]/.test(p))throw new Error("Shader manifest contains an invalid entry key.");let E=ae(g,`Shader manifest entry "${p}"`),x=u[E];if(x===void 0)throw new Error(`Shader manifest entry "${p}" references an absent state.`);(x.vertex||x.fragment)&&(d.render+=1),x.vertex&&(d.vertex+=1),x.fragment&&(d.fragment+=1),x.compute&&(d.compute+=1);}return d}a(ot,"inspectPrecompiledManifest");function cr(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(cr,"sameCoverage");function ur(e){let t=e.some(n=>n.state==="invalid")?"invalid":e.some(n=>n.state==="missing")?"missing":e.some(n=>n.state==="stale")?"stale":"fresh",r=e.filter(n=>n.state===t);return {state:t,reason:t==="fresh"?`${e.length} configured shader scene${e.length===1?" is":"s are"} fresh.`:r.map(n=>`${n.scene}: ${n.reason}`).join("; ")}}a(ur,"classifyMatrix");function fr(e){let t=e.tool;if(!t)return "Shader receipt has no public tool compatibility metadata.";if(t.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)return "Shader receipt targets a different runtime compatibility contract.";if(t.transform!==ne)return "Shader receipt uses a different provider transform version.";if(t.address!==SHADER_ADDRESS_SCHEMA_VERSION||t.recipe!==SHADER_RECIPE_SCHEMA_VERSION||t.hydration!==SHADER_HYDRATION_SCHEMA_VERSION)return "Shader receipt uses incompatible address, recipe, or hydration schemas."}a(fr,"exactToolCompatibility");function lr(e,t){let r=Object.keys(t).filter(i=>Object.hasOwn(e,i)&&e[i]!==t[i]),n=Object.keys(t).filter(i=>!Object.hasOwn(e,i)),s=Object.keys(e).filter(i=>!Object.hasOwn(t,i));return {...r.length>0?{changedInputs:r}:{},...n.length>0?{addedInputs:n}:{},...s.length>0?{removedInputs:s}:{}}}a(lr,"inputChanges");async function pr(e=process.cwd()){let t=await Ve(e),r=await me(t),n=S.join(t,pe),s=a(()=>({schemaVersion:1,root:t,state:"missing",reason:`${pe}/meta.json is absent.`,scenes:r.scenes.map(i=>({scene:i.key,state:"missing",reason:"No committed shader receipt."}))}),"missing");if(!await j(n)||!await j(S.join(n,"meta.json")))return s();try{let i=await V(t,n,"Shader artifact directory"),o=await $(i,S.join(i,"meta.json"),k.receipt,"Shader receipt"),c=Q(JSON.parse(o.data.toString("utf8"))),f=await Ze(i,o.data),h=await xe(t),y=new Set(r.scenes.map(m=>m.key)),d=Object.keys(c.scenes).filter(m=>!y.has(m));if(d.length>0)throw new Error(`Shader receipt contains unconfigured scenes: ${d.join(", ")}.`);let p=fr(c);if(p)throw new Error(p);if(!/^0\.185\./u.test(h.three))throw new Error(`Installed Three.js ${h.three} is outside the r185 capture contract.`);let g=c.runtime.three!==h.three||c.runtime.threeBlocks!==h.threeBlocks,E=c.runtime.threeBlocksShaderClosure!==h.threeBlocksShaderClosure,x=c.tool?.version!==W,P=S.join(t,r.publicDir??"public"),C=[];for(let m of r.scenes){let b=c.scenes[m.key];if(!b){C.push({scene:m.key,state:"missing",reason:"Scene is absent from the complete receipt matrix."});continue}let _=await $(i,S.join(i,b.artifact),k.manifest,"Shader manifest");if(A(_.data)!==b.artifactHash)throw new Error(`Shader artifact checksum differs for scene "${m.key}".`);if(b.asset!==void 0&&b.assetHash!==void 0){let lt=await $(P,S.join(P,b.asset),k.manifest,"Static shader manifest");if(A(lt.data)!==b.assetHash)throw new Error(`Static shader manifest checksum differs for scene "${m.key}".`)}if(b.bytes!==void 0&&b.bytes!==_.data.byteLength)throw new Error(`Shader artifact byte count differs for scene "${m.key}".`);let L=ot(_.data.toString("utf8"),_.path,m.key,{three:c.runtime.three,threeBlocks:c.runtime.threeBlocks,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION});if(!cr(L,b.coverage))throw new Error(`Shader coverage differs for scene "${m.key}".`);if(!r.allowLiveBuilds&&b.skipped&&b.skipped.render+b.skipped.compute>0)throw new Error(`Scene "${m.key}" contains skipped live builds but allowLiveBuilds is false.`);let ft=await ke(t,m.inputs),q=lr(b.inputs,ft),G=(q.changedInputs?.length??0)+(q.addedInputs?.length??0)+(q.removedInputs?.length??0),je=g||E||x||G>0,Ae=f?.scenes[m.key],de=Ae===void 0||f===void 0?void 0:{...Ae,schemaVersion:f.schemaVersion,measuredAt:f.measuredAt,source:f.source,...f.source==="committed-capture"?{adapter:f.adapter,platform:f.platform}:{}};C.push({scene:m.key,state:je?"stale":"fresh",reason:g?"Installed runtime versions differ from the receipt.":E?"Installed three-blocks/shaders runtime closure differs from the receipt.":x?`Receipt was generated by @three-blocks/devtools ${c.tool?.version??"unknown"}.`:G>0?`${G} semantic shader input${G===1?"":"s"} changed.`:"Manifest, runtime, schemas, transform, and semantic inputs match.",coverage:L,...!je&&de!==void 0&&de.builds===L.render+L.compute?{timing:de}:{},...q});}let O=ur(C),D=O.state==="fresh"&&f!==void 0&&C.every(m=>m.timing!==void 0)?f:void 0;return {schemaVersion:1,root:t,...O,scenes:C,runtime:h,receipt:c,...D===void 0?{}:{timing:D}}}catch(i){let o=i instanceof Error?i.message:String(i);return {schemaVersion:1,root:t,state:"invalid",reason:o,scenes:r.scenes.map(c=>({scene:c.key,state:"invalid",reason:o}))}}}a(pr,"inspectShaderMatrix");export{ne as SHADER_PROVIDER_TRANSFORM_VERSION,pr as inspectShaderMatrix,nr as loadShaderCaptureRuntimeSource,me as loadShaderToolConfig,xe as readInstalledShaderRuntime,ke as snapshotShaderInputs,z as stableStringify,Dt as validateShaderCapture,Vt as writeShaderArtifacts};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{b as SHADER_ARTIFACT_DIRECTORY,c as SHADER_PARITY_DIRECTORY,a as SHADER_TOOL_CONFIG_FILE,h as ensureShaderToolConfig,e as findShaderProjectRoot,g as inferShaderCaptureTarget,f as loadShaderToolConfig,d as parseShaderToolConfig}from'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{b as compareShaderScreenshots,a as shaderScreenshotMetrics}from'./chunk-UDUICSME.js';import'./chunk-EI7MMDWY.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a}from'./chunk-HOZDD6PW.js';import {PNG}from'pngjs';var x=2/255,E=4096*4096,P=64*1024*1024;function u(t){if(t.byteLength<24||t.byteLength>P||t[0]!==137||t[1]!==80||t[2]!==78||t[3]!==71)throw new Error("Shader screenshot is not a bounded PNG file.");let i=new DataView(t.buffer,t.byteOffset,t.byteLength),n=i.getUint32(16)*i.getUint32(20);if(!Number.isSafeInteger(n)||n<=0||n>E)throw new Error("Shader screenshot dimensions are invalid or exceed the inspection limit.");let a=PNG.sync.read(t),e=a.width*a.height;if(!Number.isSafeInteger(e)||e<=0||e>E)throw new Error("Shader screenshot dimensions are invalid or exceed the inspection limit.");if(a.data.byteLength!==e*4)throw new Error("Shader screenshot has invalid RGBA data.");return a}a(u,"decode");function b(t){let i=0;for(let n=0;n<t.data.byteLength;n+=4){let a=t.data[n]??0,e=t.data[n+1]??0,h=t.data[n+2]??0,d=(t.data[n+3]??0)/255;i+=(.2126*a+.7152*e+.0722*h)*d;}return i/(t.width*t.height*255)}a(b,"imageLuminance");function N(t){let i=u(t);return {width:i.width,height:i.height,luminance:b(i)}}a(N,"shaderScreenshotMetrics");function A(t,i,n,a){if(!Number.isSafeInteger(n)||n<0||n>255)throw new Error("Shader parity channel tolerance must be an integer in 0...255.");if(!Number.isFinite(a)||a<0||a>1)throw new Error("Shader parity maximum diff ratio must be in 0...1.");let e=u(t),h=u(i);if(e.width!==h.width||e.height!==h.height)throw new Error(`Shader parity dimensions differ (${e.width}\xD7${e.height} vs ${h.width}\xD7${h.height}).`);let d=new Uint8Array(e.data.byteLength),c=0,f=0;for(let r=0;r<e.data.byteLength;r+=4){let p=false;for(let o=0;o<4;o++){let s=Math.abs((e.data[r+o]??0)-(h.data[r+o]??0));f=Math.max(f,s),s>n&&(p=true);}if(p)c++,d[r]=255,d[r+1]=24,d[r+2]=24,d[r+3]=255;else {let o=Math.round(.2126*(e.data[r]??0)+.7152*(e.data[r+1]??0)+.0722*(e.data[r+2]??0)),s=Math.round(o*.25);d[r]=s,d[r+1]=s,d[r+2]=s,d[r+3]=255;}}let y=e.width*e.height,w=c/y,g=b(e),m=b(h),S=g>x&&m>x;return {width:e.width,height:e.height,luminance:m,differentPixels:c,totalPixels:y,diffRatio:w,maximumChannelDelta:f,baselineLuminance:g,precompiledLuminance:m,nonBlack:S,matches:S&&w<=a,diff:PNG.sync.write({width:e.width,height:e.height,data:d})}}a(A,"compareShaderScreenshots");export{A as compareShaderScreenshots,N as shaderScreenshotMetrics};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a as a$2}from'./chunk-ZDNZCQUQ.js';import {j,a as a$1,d}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {spawn}from'child_process';import {readFile}from'fs/promises';import {createRequire}from'module';import T from'net';import l from'path';var P=128*1024;function h(e,t){let n=`${e}${String(t)}`;return n.length<=P?n:n.slice(n.length-P)}a(h,"appendOutput");async function C(e){let t=await j(e,l.join(e,"package.json"),a$1.packageJson,"Project package.json"),n=JSON.parse(t.data.toString("utf8"));if(!a$2(n))throw new Error("Project package.json must contain an object.");return n}a(C,"projectManifest");async function _(){return new Promise((e,t)=>{let n=T.createServer();n.unref(),n.once("error",t),n.listen({host:"127.0.0.1",port:0},()=>{let r=n.address(),o=typeof r=="object"&&r!==null?r.port:void 0;n.close(i=>{i?t(i):o===void 0?t(new Error("Could not allocate a local capture port.")):e(o);});});})}a(_,"availablePort");function S(e,t,n,r){let o=r.trim();return new Error(`${e} exited with code ${n??"unknown"} while running ${t}.`+(o.length===0?"":`
|
|
3
|
+
${o}`))}a(S,"childFailure");async function b(e){if(e.exitCode!==null||e.signalCode!==null)return;e.kill("SIGTERM");let t=Date.now()+3e3;for(;e.exitCode===null&&e.signalCode===null&&Date.now()<t;)await new Promise(n=>setTimeout(n,25));if(e.exitCode===null&&e.signalCode===null)for(e.kill("SIGKILL");e.exitCode===null&&e.signalCode===null;)await new Promise(n=>setTimeout(n,25));}a(b,"stopChild");async function N(e,t,n,r,o){let i=Date.now()+o,s;for(e.once("exit",c=>{s=c;});Date.now()<i;){if(s!==void 0||e.exitCode!==null||e.signalCode!==null)throw S("Next.js capture server",n,s??e.exitCode,r());try{await(await fetch(t,{redirect:"manual",signal:AbortSignal.timeout(5e3)})).body?.cancel();return}catch{await new Promise(c=>{setTimeout(c,150).unref();});}}throw new Error(`Next.js capture server did not answer ${t} within ${o}ms while running ${n}.`+(r().trim().length===0?"":`
|
|
4
|
+
${r().trim()}`))}a(N,"waitForServer");async function A(e,t=12e4){await C(e);let n;try{n=createRequire(l.join(e,"package.json")).resolve("next/package.json");}catch(d){throw new Error("Next.js is declared but could not be resolved from the target project.",{cause:d})}let r=JSON.parse(await readFile(n,"utf8"));if(!a$2(r))throw new Error("Resolved Next.js package metadata is invalid.");let o=r.bin,i=typeof o=="string"?o:a$2(o)&&typeof o.next=="string"?o.next:void 0;if(i===void 0)throw new Error("Resolved Next.js package does not expose its CLI.");let s=typeof r.version=="string"?Number.parseInt(r.version.split(".")[0]??"",10):Number.NaN,c=await _(),p=[l.resolve(l.dirname(n),i),"dev",...Number.isFinite(s)&&s>=16?["--webpack"]:[],"--hostname","127.0.0.1","--port",String(c)],v=`${process.execPath} ${p.map(d=>JSON.stringify(d)).join(" ")}`,g=spawn(process.execPath,p,{cwd:e,env:{...process.env,THREE_BLOCKS_SHADER_TOOL:"1"},stdio:["ignore","pipe","pipe"]}),m="";g.stdout?.on("data",d=>{m=h(m,d);}),g.stderr?.on("data",d=>{m=h(m,d);});let y=`http://127.0.0.1:${c}/`;try{await N(g,y,v,()=>m,t);}catch(d){throw await b(g),d}return {url:y,command:v,diagnostics:a(()=>m,"diagnostics"),close:a(()=>b(g),"close")}}a(A,"startNextShaderCaptureServer");async function R(e,t){if(typeof t.packageManager=="string"){let n=t.packageManager.split("@")[0];if(n==="bun"||n==="npm"||n==="pnpm"||n==="yarn")return n}return await d(l.join(e,"bun.lock"))||await d(l.join(e,"bun.lockb"))?"bun":await d(l.join(e,"pnpm-lock.yaml"))?"pnpm":await d(l.join(e,"yarn.lock"))?"yarn":"npm"}a(R,"packageManager");function L(e){switch(e){case "bun":return {command:"bun",arguments:["run","build"]};case "pnpm":return {command:"pnpm",arguments:["run","build"]};case "yarn":return {command:"yarn",arguments:["build"]};case "npm":return {command:"npm",arguments:["run","build"]}}}a(L,"buildCommand");async function J(e,t=10*6e4){let n=await C(e);if(!a$2(n.scripts)||typeof n.scripts.build!="string")throw new Error('The detected non-Vite project has no package.json "build" script. Build it with THREE_BLOCKS_SHADER_TOOL=1, then pass --driver static --serve <directory>.');let r=L(await R(e,n)),o=`${r.command} ${r.arguments.join(" ")}`,i=spawn(r.command,r.arguments,{cwd:e,env:{...process.env,THREE_BLOCKS_SHADER_TOOL:"1"},stdio:["ignore","pipe","pipe"]}),s="";i.stdout?.on("data",u=>{s=h(s,u);}),i.stderr?.on("data",u=>{s=h(s,u);});let c=await Promise.race([new Promise((u,p)=>{i.once("error",p),i.once("exit",u);}),new Promise(u=>{setTimeout(()=>u("timeout"),t).unref();})]);if(c==="timeout")throw await b(i),new Error(`Capture build exceeded ${t}ms while running ${o}.`);if(c!==0)throw S("Capture build",o,c,s)}a(J,"buildShaderCaptureProject");
|
|
5
|
+
export{J as buildShaderCaptureProject,A as startNextShaderCaptureServer};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
declare const SHADER_CAPTURE_CLIENT_ID: "virtual:three-blocks-shader-capture-client";
|
|
4
|
+
interface ShaderProviderTransformStatus {
|
|
5
|
+
seen: boolean;
|
|
6
|
+
applied: boolean;
|
|
7
|
+
alreadyPresent: boolean;
|
|
8
|
+
id?: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
captureApplied?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface ShaderProviderTransform {
|
|
13
|
+
readonly plugin: Plugin;
|
|
14
|
+
readonly status: ShaderProviderTransformStatus;
|
|
15
|
+
}
|
|
16
|
+
interface AppliedShaderProviderTransform {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
readonly alreadyPresent: boolean;
|
|
19
|
+
readonly captureApplied: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ApplyShaderProviderTransformOptions {
|
|
22
|
+
readonly instrumentCapture?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Optional side-effect import that installs the browser capture runtime.
|
|
25
|
+
* Vite uses its virtual module; static builds leave this unset and let the
|
|
26
|
+
* static capture driver inject the published browser entry.
|
|
27
|
+
*/
|
|
28
|
+
readonly captureRuntimeImport?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Pure form of the provider transform, exposed for compatibility tests and Vite adapters. */
|
|
31
|
+
declare function applyShaderProviderTransform(source: string, threeVersion: string, options?: ApplyShaderProviderTransformOptions): AppliedShaderProviderTransform;
|
|
32
|
+
interface ShaderCaptureTransformOptions {
|
|
33
|
+
readonly capture: boolean;
|
|
34
|
+
readonly forceLive: boolean;
|
|
35
|
+
readonly settleFrames: number;
|
|
36
|
+
readonly settleTimeoutMs?: number;
|
|
37
|
+
readonly visibilityGuard?: boolean;
|
|
38
|
+
readonly captureId?: string;
|
|
39
|
+
readonly sessionKey?: string;
|
|
40
|
+
readonly token?: string;
|
|
41
|
+
readonly readiness?: {
|
|
42
|
+
readonly selector?: string;
|
|
43
|
+
readonly global?: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
interface ShaderProviderTransformOptions {
|
|
47
|
+
readonly capture?: ShaderCaptureTransformOptions;
|
|
48
|
+
/** Software Vulkan drivers can expose timestamps that crash Chromium's GPU process. */
|
|
49
|
+
readonly disableTimestampQueries?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Version-gated, in-memory Three.js provider hook. It never writes node_modules. */
|
|
52
|
+
declare function createShaderProviderTransform(threeVersion: string, options?: ShaderProviderTransformOptions): ShaderProviderTransform;
|
|
53
|
+
declare function assertShaderProviderTransform(status: Readonly<ShaderProviderTransformStatus>): void;
|
|
54
|
+
|
|
55
|
+
export { type AppliedShaderProviderTransform as A, SHADER_CAPTURE_CLIENT_ID as S, type ApplyShaderProviderTransformOptions as a, type ShaderCaptureTransformOptions as b, type ShaderProviderTransform as c, type ShaderProviderTransformOptions as d, type ShaderProviderTransformStatus as e, applyShaderProviderTransform as f, assertShaderProviderTransform as g, createShaderProviderTransform as h };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {e as e$1}from'./chunk-ME3X2KFY.js';import'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import {e}from'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {watch}from'fs';import v from'path';var o=class{static{a(this,"ShaderWatchQueue");}#s;#r;#a;#e;#t;#i=false;#n=false;constructor(r){if(this.#s=r.capture,this.#r=r.debounceMs??200,this.#a=r.onError??(()=>{}),!Number.isSafeInteger(this.#r)||this.#r<0||this.#r>6e4)throw new Error("Shader watch debounce must be an integer in 0...60000ms.")}notify(){this.#n||(this.#i=true,!this.#t&&(this.#e&&clearTimeout(this.#e),this.#e=setTimeout(()=>{this.#e=void 0,this.#o();},this.#r)));}#o(){this.#n||this.#t||!this.#i||(this.#i=false,this.#t=this.#s().catch(r=>{this.#a(r instanceof Error?r:new Error(String(r)));}).finally(()=>{this.#t=void 0,this.#i&&!this.#n&&this.notify();}));}async close(){this.#n=true,this.#i=false,this.#e&&clearTimeout(this.#e),this.#e=void 0,await this.#t;}};function y(e){let r=e.split(v.sep).join("/");return r===""||r.startsWith("node_modules/")||r.startsWith(".git/")||r.startsWith("dist/")||r===".three-blocks"||r.startsWith(".three-blocks/")}a(y,"ignored");async function W(e$2={}){let r=e$2.root??await e(e$2.start),d,l=new Promise(t=>{d=t;}),n=new o({...e$2.debounceMs!==void 0?{debounceMs:e$2.debounceMs}:{},...e$2.onError?{onError:e$2.onError}:{},capture:a(async()=>{let t=await e$1({root:r,...e$2.config?{config:e$2.config}:{},...e$2.driver?{driver:e$2.driver}:{},...e$2.driverKind?{driverKind:e$2.driverKind}:{},...e$2.serve?{serve:e$2.serve}:{},...e$2.url?{url:e$2.url}:{},...e$2.headed!==void 0?{headed:e$2.headed}:{},...e$2.attempts!==void 0?{attempts:e$2.attempts}:{}});e$2.onResult?.(t);},"capture")}),s,u=false,a$1=a(async()=>{u||(u=true,s?.close(),await n.close(),d?.());},"close");return s=watch(r,{recursive:true},(t,f)=>{y(f??"")||n.notify();}),s.on("error",t=>e$2.onError?.(t)),e$2.signal&&(e$2.signal.aborted?await a$1():e$2.signal.addEventListener("abort",()=>{a$1();},{once:true})),e$2.initial!==false&&n.notify(),{root:r,done:l,close:a$1}}a(W,"watchShaders");export{o as ShaderWatchQueue,W as watchShaders};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{e as captureShaders,d as inspectShaderMatrix,f as testShaders}from'./chunk-ME3X2KFY.js';import'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{b as RUNTIME_STATUS_RECEIPT_MAX_BYTES,a as RUNTIME_STATUS_RECEIPT_PATH,c as RUNTIME_STATUS_RECOVERY,e as findProjectRoot,i as formatShaderMatrixStatus,j as formatStatus,k as formatThreeBlocksStatus,f as inspectProject,g as inspectThreeBlocksStatus,d as parseRuntimeStatusReceipt,h as threeBlocksStatusIsFresh}from'./chunk-26FK4CRS.js';import'./chunk-76WRV5MZ.js';import'./chunk-JMS5NTP7.js';export{c as readInstalledShaderRuntime,b as snapshotShaderInputs}from'./chunk-ME3X2KFY.js';import'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export{b as TEXT_ATLAS_GENERATOR_VERSION,a as TEXT_ATLAS_SCHEMA_VERSION,c as builtinFontMetadata,e as generateTextAtlases,g as inspectTextAtlases,f as parseTextAtlasReceipt,d as prewarmBuiltinFont}from'./chunk-JMS5NTP7.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunk4EHPYBKA_cjs=require('./chunk-4EHPYBKA.cjs');Object.defineProperty(exports,"THREE_BLOCKS_WEBPACK_LOADER",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.b}});Object.defineProperty(exports,"createEsbuildShaderPlugin",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.g}});Object.defineProperty(exports,"createRollupShaderPlugin",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.h}});Object.defineProperty(exports,"resolveShaderAdapterThreeVersion",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.e}});Object.defineProperty(exports,"transformThreeWebGPUModule",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.f}});Object.defineProperty(exports,"withThreeBlocksNext",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.d}});Object.defineProperty(exports,"withThreeBlocksWebpack",{enumerable:true,get:function(){return chunk4EHPYBKA_cjs.c}});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { A as AppliedShaderProviderTransform } from './shader-transform-CUkZn5Oa.js';
|
|
2
|
+
import 'vite';
|
|
3
|
+
|
|
4
|
+
interface ShaderBundlerTransformOptions {
|
|
5
|
+
/** Defaults to the Three.js package resolved from `root`. */
|
|
6
|
+
readonly threeVersion?: string;
|
|
7
|
+
/** Defaults true only while THREE_BLOCKS_SHADER_TOOL=1. */
|
|
8
|
+
readonly capture?: boolean;
|
|
9
|
+
/** Module-resolution root. Defaults to process.cwd(). */
|
|
10
|
+
readonly root?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const THREE_BLOCKS_WEBPACK_LOADER = "@three-blocks/devtools/webpack-loader";
|
|
13
|
+
/**
|
|
14
|
+
* Add the provider loader to a plain webpack configuration.
|
|
15
|
+
*
|
|
16
|
+
* The loader reads `THREE_BLOCKS_SHADER_TOOL=1` itself, so the same configuration
|
|
17
|
+
* hydrates in normal builds and records capture data only in tool-owned builds.
|
|
18
|
+
*/
|
|
19
|
+
declare function withThreeBlocksWebpack<T extends object>(configuration: T): T;
|
|
20
|
+
/**
|
|
21
|
+
* Compose the provider loader with a Next.js configuration without replacing an
|
|
22
|
+
* adopter's existing `webpack` callback.
|
|
23
|
+
*/
|
|
24
|
+
declare function withThreeBlocksNext<T extends object>(configuration: T): T;
|
|
25
|
+
/** Resolve the exact target-project Three.js version without importing Three itself. */
|
|
26
|
+
declare function resolveShaderAdapterThreeVersion(root?: string): string;
|
|
27
|
+
/** Shared implementation used by every non-Vite adapter. */
|
|
28
|
+
declare function transformThreeWebGPUModule(source: string, id: string, options?: ShaderBundlerTransformOptions): AppliedShaderProviderTransform | null;
|
|
29
|
+
interface EsbuildShaderPlugin {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
setup(build: {
|
|
32
|
+
onResolve?(options: {
|
|
33
|
+
readonly filter: RegExp;
|
|
34
|
+
}, callback: (args: {
|
|
35
|
+
readonly path: string;
|
|
36
|
+
}) => {
|
|
37
|
+
readonly path: string;
|
|
38
|
+
} | undefined): void;
|
|
39
|
+
onLoad(options: {
|
|
40
|
+
readonly filter: RegExp;
|
|
41
|
+
}, callback: (args: {
|
|
42
|
+
readonly path: string;
|
|
43
|
+
}) => Promise<{
|
|
44
|
+
readonly contents: string;
|
|
45
|
+
readonly loader: 'js';
|
|
46
|
+
} | undefined>): void;
|
|
47
|
+
}): void;
|
|
48
|
+
}
|
|
49
|
+
/** esbuild adapter for the canonical `three/build/three.webgpu.js` module. */
|
|
50
|
+
declare function createEsbuildShaderPlugin(options?: ShaderBundlerTransformOptions): EsbuildShaderPlugin;
|
|
51
|
+
interface RollupShaderPlugin {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly enforce: 'pre';
|
|
54
|
+
transform(source: string, id: string): {
|
|
55
|
+
readonly code: string;
|
|
56
|
+
readonly map: null;
|
|
57
|
+
} | null;
|
|
58
|
+
}
|
|
59
|
+
/** Rollup-compatible adapter; also works in compatible plugin hosts. */
|
|
60
|
+
declare function createRollupShaderPlugin(options?: ShaderBundlerTransformOptions): RollupShaderPlugin;
|
|
61
|
+
|
|
62
|
+
export { type EsbuildShaderPlugin, type RollupShaderPlugin, type ShaderBundlerTransformOptions, THREE_BLOCKS_WEBPACK_LOADER, createEsbuildShaderPlugin, createRollupShaderPlugin, resolveShaderAdapterThreeVersion, transformThreeWebGPUModule, withThreeBlocksNext, withThreeBlocksWebpack };
|