{"_id":"@altpsyche/engine","_rev":"8-8aed4beeb60a129f8869acd035bc6727","name":"@altpsyche/engine","dist-tags":{"latest":"0.6.1"},"versions":{"0.1.0":{"name":"@altpsyche/engine","version":"0.1.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.1.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"73877dfaa85fdabb05e617f0a2eb2123e4574b1e","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.1.0.tgz","fileCount":39,"integrity":"sha512-Bv9OcsIew7NtznRsvITelp/ewyxqNDTI2tEFh/iPpnpiTZSVp0FrT7TF8RSa6wxU2acw8xX5/LzB+ST+eBMttA==","signatures":[{"sig":"MEQCICY24acoqymeZKOFN/UUBGpKjKNIulJAVOOLCelRMX5vAiARZI+AqpcUMzhyvSU1NOrcx/dh25Tx91jAF49FPEciLg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":282327},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"b789aaf8ffed5c2477b5c8239092ab53e639a98a","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","typescript":"^5.9.3","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.1.0_1787470391656_0.48846469110149937","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@altpsyche/engine","version":"0.1.1","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.1.1","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"798abfe7c89bec123850b08efc71c169f7375845","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.1.1.tgz","fileCount":39,"integrity":"sha512-uS6pyjWVuTmbECcaV9MsCApvoTAjI7wvxNMGh46hfwDKW4Cl+hKe048uQJkC3BS+lGvWPjibj/9ZjWGaczxDFg==","signatures":[{"sig":"MEQCIFyPjfu20iIDL7sEBIma9H8gek6L9KOLZ1rL0hG7VCbWAiADRBI81CbNgpzItcBdvvLoTRprYev+mXF66Pp/SL9BJw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":282327},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"3d395594e4256b95f8aa3d0473b0f5781b8a46c0","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","typescript":"^5.9.3","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.1.1_1787471380994_0.26696709612089853","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@altpsyche/engine","version":"0.2.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.2.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"b4bb1432966bdde764bce21f972afb636721834e","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.2.0.tgz","fileCount":41,"integrity":"sha512-entTxr2Pjn5DFQguXXxonKZjQVdjmrKbPCHyINPcy38AAghvXHkOo9FAJ21x1IgaxIer209qpkdfCPc2zN9aVw==","signatures":[{"sig":"MEUCIQDxMq1TsQSukXRU91rw9QKPTOb0I/ZezLgmzVmAhXX10QIgCyz0FF0ETjbmjyJO2VC1jtQ+wjjWmNGaYDJvn7gCHpE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":289310},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"d39037a389ddfc97d3f44be079fb3d33f45b2e49","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","prepack":"npm run build","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh","type-check":"tsc --noEmit -p tsconfig.json","gate:browser":"node gates/all.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","esbuild":"^0.27.2","playwright":"^1.62.1","typescript":"^5.9.3","@types/node":"^20.19.43","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.2.0_1787505460486_0.3633202335007657","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@altpsyche/engine","version":"0.3.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.3.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"62ba1f868cb274812cb9214adb0a361f7a909640","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.3.0.tgz","fileCount":79,"integrity":"sha512-nWDnkqXspqAwhVl2A0r81Wy79s4rDOpG/UxQE8C1HCsTmLw0WyjzyXwGC57m+IyMCx8bd/9g4ubECHYCF+GSCg==","signatures":[{"sig":"MEUCIQC4Q4l5GjSVd/AMQgLX82ZxZ0UGpT+TMl9OeqBrVElDBQIgFQnu37rVXQtxRgg68SNV7xo4LYDLBrZ2n2sfLuWlfig=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":673331},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"8dba3f2d3b91bdb7a8a12f2a0d751e22bac4975a","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","example":"node examples/run.mjs","prepack":"npm run build","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh","translate":"node gates/translate.mjs","type-check":"tsc --noEmit -p tsconfig.json","bench:times":"node gates/times.mjs","gate:browser":"node gates/all.mjs","bench:traffic":"node gates/traffic.mjs","device-report":"node gates/device-report.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","esbuild":"^0.27.2","playwright":"^1.62.1","typescript":"^5.9.3","@types/node":"^20.19.43","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.3.0_1787774412168_0.8749952350047587","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@altpsyche/engine","version":"0.4.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.4.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"b58bd85ed97786a07c99d02214eddc7c84c853ca","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.4.0.tgz","fileCount":79,"integrity":"sha512-N3B0Oho8YT8zbXGkvUHgJ1uVOcYPIE8EAJNYG8WJKJm6LI4HBygf/qq1LKzOT/eTrrqDmy06m1axqvS+sW93+w==","signatures":[{"sig":"MEQCIBr/VCg08sBDWQpGxGWNI64RYVpSRIwZOC8VHdGIDwqsAiBMkGO8qyBmmaI6muWHfneyBQ12LjLyWk/L6hPE6nuHNA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":675635},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./maths":{"types":"./dist/scene/maths.d.ts","default":"./dist/scene/maths.js"}},"gitHead":"e80f3e823119450d0aaf1525ca8e9919d1be91a5","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","example":"node examples/run.mjs","prepack":"npm run build","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh","translate":"node gates/translate.mjs","type-check":"tsc --noEmit -p tsconfig.json","bench:times":"node gates/times.mjs","gate:browser":"node gates/all.mjs","bench:traffic":"node gates/traffic.mjs","device-report":"node gates/device-report.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","esbuild":"^0.27.2","playwright":"^1.62.1","typescript":"^5.9.3","@types/node":"^20.19.43","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.4.0_1789054254392_0.3457798767502309","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@altpsyche/engine","version":"0.5.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.5.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"ac109bcf4964402705b955deb40f4b02d6f8b0b5","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.5.0.tgz","fileCount":91,"integrity":"sha512-+HzQb3b42v9sh27YnfXaAXJUwdbWnu+/U+hgEMVa2PqkrA9GAUe4Q7+HiiDhbss48lXX5lGb4E8d1cqhJmwPmw==","signatures":[{"sig":"MEUCIQCQL1hvqISbBEnilJcTPRY7JPPDmUCANqdOvPVUsIs+NwIgTHUyXLaOXwb4vAxXzhTdE37yqNwpyH/7ZZd/P61CqT8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":875762},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./maths":{"types":"./dist/scene/maths.d.ts","default":"./dist/scene/maths.js"}},"gitHead":"14281cff1981410f66e4184e8f5382915048a66c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","example":"node examples/run.mjs","prepack":"npm run build","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh","translate":"node gates/translate.mjs","type-check":"tsc --noEmit -p tsconfig.json","bench:times":"node gates/times.mjs","gate:browser":"node gates/all.mjs","bench:traffic":"node gates/traffic.mjs","device-report":"node gates/device-report.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","esbuild":"^0.27.2","playwright":"^1.62.1","typescript":"^5.9.3","@types/node":"^20.19.43","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.5.0_1789190364298_0.4442721692962541","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@altpsyche/engine","version":"0.6.0","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"author":{"name":"Siva"},"license":"MIT","_id":"@altpsyche/engine@0.6.0","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"dist":{"shasum":"9fe3d3c468d546aa23117a3093a758d582c1f827","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.6.0.tgz","fileCount":91,"integrity":"sha512-10RXArp3HbYgG/fSDYapEXcohanLqQdygmuSlsW5tqQLvphM0n7u45ozma0y7kzlxdixcjJR1GGQn2wKMADKYw==","signatures":[{"sig":"MEQCID4dUkK8QZQFbKf/VNlzIm1wKmYF4SPBILtu6QX70cjaAiBhczT8TfIPbOGS3YIKbkeNDlhLL+u94PKlgOMQSHQj7A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":880642},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./maths":{"types":"./dist/scene/maths.d.ts","default":"./dist/scene/maths.js"}},"gitHead":"cb75ea64fa80455d639d79d8f2b5205fb4e80d48","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","example":"node examples/run.mjs","prepack":"npm run build","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh","translate":"node gates/translate.mjs","type-check":"tsc --noEmit -p tsconfig.json","bench:times":"node gates/times.mjs","gate:browser":"node gates/all.mjs","bench:traffic":"node gates/traffic.mjs","device-report":"node gates/device-report.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"repository":{"url":"git+https://github.com/altpsyche/altpsyche-engine.git","type":"git"},"_npmVersion":"12.0.2","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"devDependencies":{"jsdom":"^27.4.0","vitest":"^4.0.17","esbuild":"^0.27.2","playwright":"^1.62.1","typescript":"^5.9.3","@types/node":"^20.19.43","@webgpu/types":"^0.1.71"},"_npmOperationalInternal":{"tmp":"tmp/engine_0.6.0_1789328076332_0.47068737947383466","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@altpsyche/engine","version":"0.6.1","description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","license":"MIT","author":{"name":"Siva"},"repository":{"type":"git","url":"git+https://github.com/altpsyche/altpsyche-engine.git"},"homepage":"https://github.com/altpsyche/altpsyche-engine","bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"type":"module","sideEffects":false,"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./maths":{"types":"./dist/scene/maths.d.ts","default":"./dist/scene/maths.js"}},"scripts":{"build":"tsc -p tsconfig.build.json","test":"vitest run","type-check":"tsc --noEmit -p tsconfig.json","example":"node examples/run.mjs","translate":"node gates/translate.mjs","device-report":"node gates/device-report.mjs","bench:traffic":"node gates/traffic.mjs","bench:times":"node gates/times.mjs","prepack":"npm run build","gate:browser":"node gates/all.mjs","gate:card":"node gates/card.mjs","gate:pack":"bash gates/pack.sh"},"devDependencies":{"@types/node":"^20.19.43","@webgpu/types":"^0.1.71","esbuild":"^0.27.2","jsdom":"^27.4.0","playwright":"^1.62.1","typescript":"^5.9.3","vitest":"^4.0.17"},"engines":{"node":">=20"},"gitHead":"84889ba822ffa6583d4757732d84e6cde651e9ba","_id":"@altpsyche/engine@0.6.1","_nodeVersion":"24.20.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-9pgL6GGlGv/munKpfSiL0IvVhWm089UHNYeQhjqdbSmuL5C+faU3LFrpPc0kprd0KSsFodUJrjN/s6SnKJsIMA==","shasum":"e5052de65a74e2add11b29caab23ba32835a0a4f","tarball":"https://registry.npmjs.org/@altpsyche/engine/-/engine-0.6.1.tgz","fileCount":91,"unpackedSize":884329,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@altpsyche%2fengine@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDqmd0DPRXZ6TzxMCDHXSvHjRLH3xCd46jmrdSGB4qAegIgWN8GKi3n0iqP2xtBMis8d+YC/vBlr2Q7SmwMX9ROahY="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e2463231-f2f8-4627-b679-fcaaafc37839"}},"directories":{},"maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/engine_0.6.1_1789333392525_0.6282465823571945"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T07:33:11.413Z","modified":"2026-09-13T21:03:12.982Z","0.1.0":"2026-08-23T07:33:11.800Z","0.1.1":"2026-08-23T07:49:41.126Z","0.2.0":"2026-08-23T17:17:40.635Z","0.3.0":"2026-08-26T20:00:12.297Z","0.4.0":"2026-09-10T15:30:54.534Z","0.5.0":"2026-09-12T05:19:24.437Z","0.6.0":"2026-09-13T19:34:36.502Z","0.6.1":"2026-09-13T21:03:12.676Z"},"bugs":{"url":"https://github.com/altpsyche/altpsyche-engine/issues"},"author":{"name":"Siva"},"license":"MIT","homepage":"https://github.com/altpsyche/altpsyche-engine","keywords":["webgpu","webgl2","renderer","shader","wgsl","glsl","graphics"],"repository":{"type":"git","url":"git+https://github.com/altpsyche/altpsyche-engine.git"},"description":"The AltPsyche renderer and the engine above it: one door onto WebGL 2 and WebGPU, and a scene becoming a frame.","maintainers":[{"name":"altpsyche","email":"v.sivavadlamani@gmail.com"}],"readme":"# @altpsyche/engine\n\nA renderer for WebGPU and WebGL 2, with a small scene layer above it. One import path for\neverything, no runtime dependencies.\n\nYou describe a frame as data: which resources exist, which pipelines run, what order the\npasses go in. Hand that to the renderer and it picks a backend and makes the calls. Because\nthe frame is data, you can also ask what it will cost and whether this device can draw it,\nbefore anything reaches a driver.\n\n[![npm](https://img.shields.io/npm/v/@altpsyche/engine)](https://www.npmjs.com/package/@altpsyche/engine)\n[![gates](https://github.com/altpsyche/altpsyche-engine/actions/workflows/gates.yml/badge.svg)](https://github.com/altpsyche/altpsyche-engine/actions/workflows/gates.yml)\n![dependencies: none](https://img.shields.io/badge/dependencies-none-brightgreen)\n![types: included](https://img.shields.io/badge/types-included-blue)\n\n```bash\nnpm install @altpsyche/engine\n```\n\n## Draw something\n\nThis is a whole page. Paste it into a project with a bundler in front of it and it runs.\n\n```ts\nimport { createSurface, glslFrame } from '@altpsyche/engine';\n\nconst canvas = document.createElement('canvas');\ncanvas.style.cssText = 'display:block;width:100vw;height:100vh';\ndocument.body.append(canvas);\n\n// The backend supplies the three corners of a fullscreen triangle, so the vertex\n// shader passes its position through. `position` is the attribute name it fills.\nconst VERTEX = `#version 300 es\nin vec3 position;\nvoid main() { gl_Position = vec4(position, 1.0); }`;\n\nconst FRAGMENT = `#version 300 es\nprecision highp float;\nuniform float uTime;\nuniform vec3 iResolution;\nout vec4 fragColour;\nvoid main() {\n  vec2 uv = gl_FragCoord.xy / iResolution.xy;\n  fragColour = vec4(0.5 + 0.5 * cos(uTime + uv.xyx * 6.283185 + vec3(0, 2, 4)), 1.0);\n}`;\n\n// One frame: one pass, one pipeline, drawn over the canvas.\nconst frame = glslFrame('first-frame', VERTEX, FRAGMENT);\n\n// Both factories return promises, because the backend behind them is a dynamic import.\nconst surface = await createSurface(canvas, frame, {\n  uniforms: (seconds) => ({ uTime: seconds, iResolution: [canvas.width, canvas.height, 1] }),\n  onError: (message) => console.error(message),\n});\n\nif (!surface) throw new Error('no backend would give this canvas a context');\n\nconst fit = () => surface.resize(canvas.clientWidth, canvas.clientHeight);\naddEventListener('resize', fit);\nfit();\nsurface.start();\n```\n\nThe window fills with a gradient that moves, and it follows a resize. `wgslFrame` is the\nsame call for WGSL, though a fullscreen WGSL frame draws on WebGPU only, since there is no\nvertex document for WebGL 2 to link. [docs/EXAMPLES.md](docs/EXAMPLES.md) breaks this page\ninto the four files it really is, and lists six longer ones that run in this repository.\n\n## How it works\n\n**The frame is data.** A frame graph is a plain object: resources, pipelines, passes. It\nserialises, so a worker can build one and post it. Two of them can be compared.\n`cost(graph, size)` gives you passes, draws, dispatches and transient bytes with no device\npresent.\n\n**Capabilities are data too.** A graph lists what it needs, a device reports what it has,\nand `refusal` compares the two and gives you the name of what is missing, or `null`.\nNeither backend owns a method the other has to throw from, so a graph WebGL 2 cannot draw\nis refused before a driver sees it.\n\n**You do not name a backend.** `selectBackend` reads two facts and answers with one: the\nlanguage the frame is authored in, and what the device offers. Where both backends can draw\na frame they draw the same picture. On an RTX 5080 they agree to within a single channel on\nevery scene preset in this repository's corpus.\n\n**A browser downloads one backend.** Each sits behind `await import()`, so a bundler gives\neach its own file and a browser without WebGPU never downloads the WebGPU one. `npm test`\nbundles the entry point and fails if either backend turns up in the first download.\n\n## What a page downloads\n\nFrom the chunk gate, `gates/chunk.mjs`, minified with splitting on, measured on the commit\nyou are reading:\n\n| chunk | raw | gzipped | downloaded |\n| --- | --- | --- | --- |\n| the entry point and your own calls | 3.7 kB | **1.8 kB** | always |\n| the WebGL 2 backend | 21.6 kB | **7.1 kB** | where it draws |\n| the WebGPU backend | 25.4 kB | **8.9 kB** | where it draws |\n| four shared chunks | 15.0 kB | 5.9 kB | as a graph needs them |\n\nA browser with no WebGPU downloads the first row, the second, and whichever shared chunks\nits graph reaches. That is about 15 kB gzipped at most, and never the WebGPU backend. No\npage downloads a WGSL translator either, because translation happens in the build.\n\n## Five things to know before you start\n\n1. **Both factories are asynchronous.** The backend behind them is a dynamic import, so\n   `createSurface` and `createFrameRenderer` return promises.\n2. **`openRenderer(canvas, frame)` picks the backend for you**, asks for a card only where\n   the answer wants one, translates the frame where the chosen backend speaks another\n   language, and hands back `{ renderer, frame }` or `{ refusal }`. **Submit the frame it\n   hands back**, since a WGSL frame drawn on WebGL 2 is drawn as its GLSL translation.\n   `createFrameRenderer` is the primitive underneath and **uses WebGL 2 unless you give it a\n   WebGPU device** — you call `requestWebGPUDevice()` and pass `{ backend: 'webgpu', device }`\n   — so a page that never wants WebGPU never downloads that backend. Either way the card is\n   yours to own: a page with more than one canvas asks once and hands the same device to each.\n3. **Do not call `getContext('webgl2')` on the canvas you are going to draw into.** A canvas\n   keeps the first context type it is given and refuses every other one for as long as it\n   lives, so that call as a capability check breaks WebGPU on the machines that have it. Ask\n   a throwaway canvas instead.\n4. **A GLSL frame goes to WebGL 2 even where WebGPU exists.** GLSL ES 3.0 has no syntax for\n   the capabilities WebGPU adds, so the language you wrote in settles which backend draws.\n5. **`wgslFrame` expects two conventions of its source:** the fragment entry point is called\n   `fragMain`, and the uniforms are one struct at group 0, binding 0. `uniformBlockOf(code)`\n   reads the offsets off the source, so you never write the layout down twice.\n\n## Past a fullscreen shader\n\nReal geometry, several passes, a depth buffer or a compute stage mean writing the graph\nyourself: resources, pipelines and passes, with every resource addressed by a kind-branded\nhandle like `uniform(0)` or `texture(2)`, never by a string. Hand a texture handle to\nsomething expecting a buffer and it is a compile error, not an `undefined` at draw time.\n[docs/GUIDE-frame-graph.md](docs/GUIDE-frame-graph.md) builds one line by line.\n\nThere is a scene layer above the renderer: entities carry a transform and may name a\nparent, and `sceneView` turns a world and its cameras into a frame graph, packing each\nobject's record into a storage buffer the shader indexes by instance. A rotation is a\n`Mat4` and never three angles, because Euler orders disagree between codebases and nothing\ntells you when they do. The maths is `vec3`, `mat3` and `mat4`, column major, depth from\nzero to one. A vector's length is `vec3.magnitude`, since a function's own `length` in\nJavaScript cannot be replaced. Every signature is in [docs/API.md](docs/API.md).\n\nThose three names have a second import path, `@altpsyche/engine/maths`, and they stay on the\nmain one as well — so this is a shortcut and never a move. It is worth using only if you have\nno bundler: reaching `mat4` through the package name loads the renderer with it, twenty-seven\nfiles against one, and a bundler shakes that difference down to two gzipped bytes. With a\nbundler, keep the one import.\n\n## Ask before you draw\n\n```ts\nimport {\n  cost, requestWebGPUDevice, resolve, webgl2Capabilities, webgpuCapabilities,\n  type DeviceProfile,\n} from '@altpsyche/engine';\n\n// Ask for the device first: whether asking returns one is the fact selection reads.\nconst device = await requestWebGPUDevice();\nconst gl = document.createElement('canvas').getContext('webgl2'); // a throwaway canvas\n\nconst profile: DeviceProfile = {\n  webgpu: device ? webgpuCapabilities(device.features) : null,\n  webgl2: gl ? webgl2Capabilities(gl.getSupportedExtensions() ?? []) : null,\n};\n\n// One reading: the backend that will draw this frame, or a refusal saying what is missing.\nconst selection = resolve(frame, profile);\nif ('refusal' in selection) console.error(selection.refusal);\nelse console.log('drawing on', selection.backend);\n\n// What it costs, before a pixel exists.\nconst { passes, draws, transientBytes } = cost(frame, { width: 800, height: 600 });\n```\n\n`resolve` does selection and the capability check in one call. `selectBackend` and\n`refusal` are the two halves on their own. All three are pure functions over data, so they\nanswer in a test or in a worker, on a machine with no graphics card in it.\n\n`probe()` is a different thing, easy to mistake for these. It draws a frame and returns a\ndated `DeviceReading`: what the browser reported, what came back when asked, whether the\ndevice survived being composited. It is a diagnostic, and a row for\n[docs/DEVICES.md](docs/DEVICES.md). Selection reads a `DeviceProfile`, not a reading.\n\n## Drawing one frame, on your own schedule\n\n```ts\nimport { createFrameRenderer, requestWebGPUDevice, submit } from '@altpsyche/engine';\n\nconst device = await requestWebGPUDevice();\nconst renderer = await createFrameRenderer(canvas, device ? { backend: 'webgpu', device } : {});\nif (!renderer) throw new Error('no backend would give this canvas a context');\n\nsubmit(renderer, frame, { u_time: 0 });          // uniforms are an argument, not an option\n```\n\nA fourth argument, `{ into }`, lands the frame in a texture you own as well as on the\ncanvas: a capture target, or an XR layer the compositor reads. Where a frame lands is yours\nto decide.\n\n## Checking what your shader asked the device\n\nThe recording double is part of the package. `wrapDevice` wraps a real device and records\nevery call made on it, `projectTrace` cuts a recording down to the calls worth comparing,\nand `compareTraces` says where two recordings differ. So you can show that editing a shader\ndid not quietly change what the device was asked to do. The package uses the same three\ncalls on its own two backends, and\n[docs/API.md](docs/API.md#checking-what-your-shader-asked-the-device) shows them in use.\n\n## What it needs\n\nAny browser with WebGL 2, which is every current one, and WebGPU where you want that\nbackend. TypeScript declarations ship with the package, so there is no `@types` install.\n\nThe two backends are not equal, and the difference is in the capability data. WebGL 2 draws\nthe whole toy tier and the scene tier's per-instance records. It has no compute stage, no\nshader-written storage buffer, no storage texture, no indirect draw, no timestamp query and\nno occlusion query, because GLSL ES 3.0 has none of them. Ask `probe` or\n`webgl2Capabilities` instead of trusting this paragraph;\n[docs/GUIDE-backends.md](docs/GUIDE-backends.md) has the rest.\n\n## Status\n\n**0.x, and 0.x is unstable.** Names and shapes change between releases without a major\nbump, and the [CHANGELOG](CHANGELOG.md) says what moved in each one. A caret range on a\n`0.x` version tracks the last number alone, so `^0.3.0` will not pick up a later `0.4.0`.\nYou move to a feature release by asking for it.\n\n## Where to read next\n\n| document | what it answers |\n| --- | --- |\n| [docs/EXAMPLES.md](docs/EXAMPLES.md) | a complete page as four files, and the six that run in this repository |\n| [docs/API.md](docs/API.md) | every exported name with the signature the compiler gives it |\n| [docs/GUIDE-frame-graph.md](docs/GUIDE-frame-graph.md) | writing a frame graph by hand |\n| [docs/GUIDE-backends.md](docs/GUIDE-backends.md) | capabilities, selection, refusal, and what each backend reaches |\n| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | how the library is put together, and why |\n| [CHANGELOG.md](CHANGELOG.md) | what moved in each release |\n\nIf you are changing the package instead of using it,\n[CONTRIBUTING.md](CONTRIBUTING.md) has the gates and the rules that are not negotiable, and\n[docs/DEVICES.md](docs/DEVICES.md) is the hardware log: dated readings from real machines,\nkept so a claim about a graphics card has a source.\n\n## Licence\n\nMIT.\n","readmeFilename":"README.md"}