@roomle/web-sdk 4.2.0 → 4.3.0-alpha.1
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/lib/ConfiguratorKernel.wasm +0 -0
- package/lib/{GaussianBlurNode-DEczNsyD.mjs → GaussianBlurNode-Bjszve7N.mjs} +15 -15
- package/lib/{GaussianBlurNode-DEczNsyD.mjs.map → GaussianBlurNode-Bjszve7N.mjs.map} +1 -1
- package/lib/RoomleCore.wasm +0 -0
- package/lib/RoomleToolsCore.wasm +0 -0
- package/lib/{api-B6sLiuiL.mjs → api-C0UElaCW.mjs} +2 -2
- package/lib/{api-B6sLiuiL.mjs.map → api-C0UElaCW.mjs.map} +1 -1
- package/lib/asset-loader.worker-eqHzNAwa.mjs.map +1 -1
- package/lib/{banana-for-scale-C-grIlTK.mjs → banana-for-scale-DGYmxeBG.mjs} +3 -3
- package/lib/{banana-for-scale-C-grIlTK.mjs.map → banana-for-scale-DGYmxeBG.mjs.map} +1 -1
- package/lib/budgeteer.sw-BUMElkO1.mjs.map +1 -1
- package/lib/{common-utils-6T8eGlhX.mjs → common-utils-CyQUubmw.mjs} +29 -15
- package/lib/{common-utils-6T8eGlhX.mjs.map → common-utils-CyQUubmw.mjs.map} +1 -1
- package/lib/{component-dimensioning-DJuokZnv.mjs → component-dimensioning--4sX2AgY.mjs} +4 -4
- package/lib/{component-dimensioning-DJuokZnv.mjs.map → component-dimensioning--4sX2AgY.mjs.map} +1 -1
- package/lib/{component-raycast-helper-SZg14d7A.mjs → component-raycast-helper-CskJedpv.mjs} +3 -3
- package/lib/{component-raycast-helper-SZg14d7A.mjs.map → component-raycast-helper-CskJedpv.mjs.map} +1 -1
- package/lib/configurator-CjFo24FH.mjs +2 -0
- package/lib/{configurator-Cbof6AET.mjs → configurator-vxRFxJ-B.mjs} +4 -4
- package/lib/{configurator-Cbof6AET.mjs.map → configurator-vxRFxJ-B.mjs.map} +1 -1
- package/lib/{decorate-CX1ZGuFY.mjs → decorate-CjaqqbUP.mjs} +12 -9
- package/lib/decorate-CjaqqbUP.mjs.map +1 -0
- package/lib/dimensioning-helper-0s61LK9R.mjs +2 -0
- package/lib/{dimensioning-helper-BwvR76_I.mjs → dimensioning-helper-Cgao7A18.mjs} +2 -2
- package/lib/{dimensioning-helper-BwvR76_I.mjs.map → dimensioning-helper-Cgao7A18.mjs.map} +1 -1
- package/lib/{glb-viewer-DmVh1uJg.mjs → glb-viewer-B-r0E1aa.mjs} +6 -6
- package/lib/{glb-viewer-DmVh1uJg.mjs.map → glb-viewer-B-r0E1aa.mjs.map} +1 -1
- package/lib/glb-viewer-BnJkmakv.mjs +2 -0
- package/lib/{highlight-coordinator-Qonmfsu1.mjs → highlight-coordinator-CR5rcFh_.mjs} +2 -2
- package/lib/{highlight-coordinator-Qonmfsu1.mjs.map → highlight-coordinator-CR5rcFh_.mjs.map} +1 -1
- package/lib/{homag-intelligence-CzD_RMQo.mjs → homag-intelligence-DHTCBB64.mjs} +8 -5
- package/lib/{homag-intelligence-CzD_RMQo.mjs.map → homag-intelligence-DHTCBB64.mjs.map} +1 -1
- package/lib/{imos-ix-poc-export-helper-Q6-OXziY.mjs → imos-ix-poc-export-helper-DRQK_p2h.mjs} +2 -2
- package/lib/{imos-ix-poc-export-helper-Q6-OXziY.mjs.map → imos-ix-poc-export-helper-DRQK_p2h.mjs.map} +1 -1
- package/lib/{material-viewer-BkSh-aG7.mjs → material-viewer-ZlNDhA8D.mjs} +6 -6
- package/lib/{material-viewer-BkSh-aG7.mjs.map → material-viewer-ZlNDhA8D.mjs.map} +1 -1
- package/lib/{packages-BGVMQMZK.mjs → packages-C9J0u-cc.mjs} +5 -5
- package/lib/{packages-BGVMQMZK.mjs.map → packages-C9J0u-cc.mjs.map} +1 -1
- package/lib/planner-C-5Mg-Lv.mjs +2 -0
- package/lib/{planner-DFa8uJOF.mjs → planner-ClY-VUWt.mjs} +3 -3
- package/lib/{planner-DFa8uJOF.mjs.map → planner-ClY-VUWt.mjs.map} +1 -1
- package/lib/{plugin-system-CqXT37-v.mjs → plugin-system-vlnG8j2T.mjs} +3 -3
- package/lib/{plugin-system-CqXT37-v.mjs.map → plugin-system-vlnG8j2T.mjs.map} +1 -1
- package/lib/{roomle-headless-setup-7xnQlZl3.mjs → roomle-headless-setup-DbO_rLjK.mjs} +54 -40
- package/lib/roomle-headless-setup-DbO_rLjK.mjs.map +1 -0
- package/lib/roomle-headless.d.ts +125 -115
- package/lib/roomle-headless.js +289 -358
- package/lib/roomle-headless.js.map +1 -1
- package/lib/roomle-renderer-FUqNfNIf.mjs.map +1 -1
- package/lib/{roomle-sdk-B73VmWod.mjs → roomle-sdk-BpCPIwDm.mjs} +2447 -2306
- package/lib/roomle-sdk-BpCPIwDm.mjs.map +1 -0
- package/lib/roomle-sdk.d.ts +79 -4
- package/lib/roomle-sdk.js +7 -7
- package/lib/{roomle-webgpu-renderer-Dzuy_Y39.mjs → roomle-webgpu-renderer-Lt55gNj5.mjs} +370 -303
- package/lib/roomle-webgpu-renderer-Lt55gNj5.mjs.map +1 -0
- package/lib/{scene-renderer-DR7EFd-8.mjs → scene-renderer-CLkhNnnv.mjs} +5 -5
- package/lib/{scene-renderer-DR7EFd-8.mjs.map → scene-renderer-CLkhNnnv.mjs.map} +1 -1
- package/lib/{script-loader-BlsGBrYo.mjs → script-loader-9GrUxzSB.mjs} +3 -3
- package/lib/{script-loader-BlsGBrYo.mjs.map → script-loader-9GrUxzSB.mjs.map} +1 -1
- package/lib/{shading-settings-Bnt9v9xJ.mjs → shading-settings-CRNmMpcn.mjs} +2 -2
- package/lib/{shading-settings-Bnt9v9xJ.mjs.map → shading-settings-CRNmMpcn.mjs.map} +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/package.json +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/ConfiguratorKernel.wasm +0 -0
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.wasm +0 -0
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleToolsCore.wasm +0 -0
- package/lib/{stats-helper-vEwFkDIt.mjs → stats-helper-D9l8soWd.mjs} +3 -3
- package/lib/{stats-helper-vEwFkDIt.mjs.map → stats-helper-D9l8soWd.mjs.map} +1 -1
- package/lib/three.tsl-BnL9nfJa.mjs +2 -0
- package/lib/{three.tsl-BElp7_oF.mjs → three.tsl-Dew9p5yF.mjs} +46 -48
- package/lib/{three.tsl-BElp7_oF.mjs.map → three.tsl-Dew9p5yF.mjs.map} +1 -1
- package/lib/{threejs-utils-C9zED_Tu.mjs → threejs-utils-CKV1QNU9.mjs} +4 -3
- package/lib/threejs-utils-CKV1QNU9.mjs.map +1 -0
- package/lib/{tools-core-DKYMilYC.mjs → tools-core-CKaB3WsP.mjs} +3 -3
- package/lib/{tools-core-DKYMilYC.mjs.map → tools-core-CKaB3WsP.mjs.map} +1 -1
- package/lib/{webgpu-BMwlJflc.mjs → webgpu-B0rxiqW-.mjs} +313 -313
- package/lib/{webgpu-BMwlJflc.mjs.map → webgpu-B0rxiqW-.mjs.map} +1 -1
- package/package.json +2 -2
- package/lib/configurator-BFd5022u.mjs +0 -2
- package/lib/decorate-CX1ZGuFY.mjs.map +0 -1
- package/lib/dimensioning-helper-yMfkA1IY.mjs +0 -2
- package/lib/glb-viewer-DlH5_aTU.mjs +0 -2
- package/lib/planner-CSKuhBke.mjs +0 -2
- package/lib/roomle-headless-setup-7xnQlZl3.mjs.map +0 -1
- package/lib/roomle-sdk-B73VmWod.mjs.map +0 -1
- package/lib/roomle-webgpu-renderer-Dzuy_Y39.mjs.map +0 -1
- package/lib/three.tsl-BtDRDR0q.mjs +0 -2
- package/lib/threejs-utils-C9zED_Tu.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as e, C as t, H as n, I as r, V as i, Z as a, c as o, ct as s, ft as c, n as l, ot as u, st as d, tt as f, u as p, w as m } from "./roomle-sdk-
|
|
2
|
-
import { t as h } from "./script-loader-
|
|
1
|
+
import { A as e, C as t, H as n, I as r, V as i, Z as a, c as o, ct as s, ft as c, n as l, ot as u, st as d, tt as f, u as p, w as m } from "./roomle-sdk-BpCPIwDm.mjs";
|
|
2
|
+
import { t as h } from "./script-loader-9GrUxzSB.mjs";
|
|
3
3
|
//#region packages/planner-core/src/input/planner-input-manager.ts
|
|
4
4
|
var g = class extends r {
|
|
5
5
|
_canDrag(e) {
|
|
@@ -41,4 +41,4 @@ var g = class extends r {
|
|
|
41
41
|
//#endregion
|
|
42
42
|
export { v as t };
|
|
43
43
|
|
|
44
|
-
//# sourceMappingURL=planner-
|
|
44
|
+
//# sourceMappingURL=planner-ClY-VUWt.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner-
|
|
1
|
+
{"version":3,"file":"planner-ClY-VUWt.mjs","names":[],"sources":["../../packages/planner-core/src/input/planner-input-manager.ts","../../packages/planner-core/src/utils/injectables.ts","../../packages/planner-core/src/planner.ts"],"sourcesContent":["import type { INPUT_EVENT_TYPE } from '../../../common-core/src/input/input-manager';\nimport InputManager from '../../../common-core/src/input/input-manager';\n\nexport default class PlannerInputManager extends InputManager {\n protected _canDrag(_type: INPUT_EVENT_TYPE): boolean {\n return true;\n }\n}\n","import ScriptLoader from '../../../common-core/src/script-loader';\nimport {\n DependencyInjectionAssignment,\n DI_TYPE,\n} from '../../../common-core/src/di/container';\nimport Logger from '../../../common-core/src/logger';\nimport { default as PlannerMeshGenerator } from '../webgl/planner-mesh-generator';\nimport { RapiAccess } from '../../../common-core/src/rapi-access';\nimport PlannerInputManager from '../input/planner-input-manager';\nimport PlannerSelectionHandler from './planner-selection-handler';\nimport GlobalInitData from '../../../common-core/src/utils/global-init-data';\nimport ConfiguratorViewModel from '../../../common-core/src/view-model/configurator-view-model';\n\nexport const INJECTABLES: DependencyInjectionAssignment[] = [\n new DependencyInjectionAssignment('script-loader', ScriptLoader),\n new DependencyInjectionAssignment(\n 'planner-input-manager',\n PlannerInputManager,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment('logger', Logger),\n new DependencyInjectionAssignment(\n 'planner-mesh-generator',\n PlannerMeshGenerator,\n ),\n new DependencyInjectionAssignment(\n 'configurator-view-model',\n ConfiguratorViewModel,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment('rapi-access', RapiAccess),\n new DependencyInjectionAssignment('global-init-data', GlobalInitData),\n new DependencyInjectionAssignment(\n 'planner-selection-handler',\n PlannerSelectionHandler,\n ),\n];\n","import './utils/global-definitions';\nimport { Main, BASE_CONTEXT } from '../../common-core/src/main';\nimport { RoomlePlanner } from './roomle-planner';\nimport RoomleDependencyInjection from '../../common-core/src/di/roomle-dependency-injection';\nimport { INJECTABLES } from './utils/injectables';\nimport type PlannerKernelAccess from './services/planner-kernel-access';\nimport type Logger from '../../common-core/src/logger';\nimport { KERNEL_TYPE } from '../../common-core/src/services/common-kernel-access';\nimport type { PluginName } from '../../configurator-core/src/utils/plugin-types';\nimport type InitData from '../../common-core/src/utils/init-data';\nimport { isInIframe } from '../../common-core/src/utils/rapi-utils';\n\nexport class Planner<\n P extends readonly PluginName[] = readonly [],\n> extends Main {\n private _planner: RoomlePlanner<P>;\n private _activePlugins: P;\n\n constructor(creator?: string, activePlugins?: P) {\n super(creator);\n this._activePlugins = (activePlugins || []) as P;\n }\n protected setupGlobals(): void {\n //globals are initialized in bootFinished()\n }\n\n protected setupDependencies(): void {\n RoomleDependencyInjection.setup(INJECTABLES);\n this.lookup<Logger>('logger', this._context);\n // instantiate kernel acccess\n // instantiate pka\n // set pka on kernel access\n const plannerKernelAccess = this.lookup<PlannerKernelAccess>(\n 'planner-kernel-access',\n this._context,\n );\n plannerKernelAccess.init(KERNEL_TYPE.PLANNER);\n }\n\n protected cleanUpGlobals(): void {\n throw new Error('Method not implemented.');\n }\n\n protected cleanUpDependencies(): void {\n throw new Error('Method not implemented.');\n }\n\n protected async bootFinished(): Promise<void> {\n this._planner = new RoomlePlanner<P>(this._context, this._activePlugins);\n\n this._planner.getMain = () => {\n return this;\n };\n\n if (!window.RoomlePlanner) {\n if (this._activePlugins.length === 0) {\n // cast to unknown because we know that the planner is a RoomlePlanner\n window.RoomlePlanner = this._planner as unknown as RoomlePlanner;\n } else {\n window.RoomlePlanner = this._planner as RoomlePlanner<\n readonly PluginName[]\n >;\n }\n }\n\n const initData = this.lookup<InitData>('init-data', this._context);\n\n if (initData?.hi && isInIframe()) {\n await this._planner.setupHomagIntelligence();\n }\n }\n\n public getApi(): RoomlePlanner<P> {\n return this._planner;\n }\n\n protected getContextName(): string {\n return BASE_CONTEXT.PLANNER;\n }\n}\n"],"mappings":";;;AAGA,IAAqB,IAArB,cAAiD,EAAa;CAC5D,SAAmB,GAAkC;AACnD,SAAO;;GCQE,IAA+C;CAC1D,IAAI,EAA8B,iBAAiB,EAAa;CAChE,IAAI,EACF,yBACA,GACA,EAAQ,QACT;CACD,IAAI,EAA8B,UAAU,EAAO;CACnD,IAAI,EACF,0BACA,EACD;CACD,IAAI,EACF,2BACA,GACA,EAAQ,QACT;CACD,IAAI,EAA8B,eAAe,EAAW;CAC5D,IAAI,EAA8B,oBAAoB,EAAe;CACrE,IAAI,EACF,6BACA,EACD;CACF,ECxBY,IAAb,cAEU,EAAK;CAIb,YAAY,GAAkB,GAAmB;AAE/C,EADA,MAAM,EAAQ,EACd,KAAK,iBAAkB,KAAiB,EAAE;;CAE5C,eAA+B;CAI/B,oBAAoC;AAMN,EAL5B,EAA0B,MAAM,EAAY,EAC5C,KAAK,OAAe,UAAU,KAAK,SAAS,EAIhB,KAAK,OAC/B,yBACA,KAAK,SACN,CACmB,KAAK,EAAY,QAAQ;;CAG/C,iBAAiC;AAC/B,QAAU,MAAM,0BAA0B;;CAG5C,sBAAsC;AACpC,QAAU,MAAM,0BAA0B;;CAG5C,MAAgB,eAA8B;AAoB5C,EAnBA,KAAK,WAAW,IAAI,EAAiB,KAAK,UAAU,KAAK,eAAe,EAExE,KAAK,SAAS,gBACL,MAGJ,OAAO,kBACN,KAAK,eAAe,QAEtB,OAAO,gBAAgB,KAAK,WAQf,KAAK,OAAiB,aAAa,KAAK,SAAS,EAEpD,MAAM,GAAY,IAC9B,MAAM,KAAK,SAAS,wBAAwB;;CAIhD,SAAkC;AAChC,SAAO,KAAK;;CAGd,iBAAmC;AACjC,SAAO,EAAa"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./decorate-
|
|
1
|
+
import { n as e, r as t, t as n } from "./decorate-CjaqqbUP.mjs";
|
|
2
2
|
//#region packages/configurator-core/src/webgl/plugin-system.ts
|
|
3
3
|
var r = class {
|
|
4
4
|
constructor(e) {
|
|
@@ -20,7 +20,7 @@ var r = class {
|
|
|
20
20
|
async init(e, t, n) {
|
|
21
21
|
this._scene = e, this._uiScene = t, this._cameraPosition = n;
|
|
22
22
|
let { bananaForScale: r } = this._initData;
|
|
23
|
-
r && await import("./banana-for-scale-
|
|
23
|
+
r && await import("./banana-for-scale-DGYmxeBG.mjs").then(({ default: e }) => this._plugins.push(new e(this._creator_))), this._plugins.forEach((e) => e.setScene(this._scene)), this._plugins.forEach((e) => e.setUiScene(this._uiScene)), this._plugins.forEach((e) => e.updateBounds(this._bounds)), this._plugins.forEach((e) => e.moveCameraEnd(this._cameraPosition));
|
|
24
24
|
}
|
|
25
25
|
addPlugin(e) {
|
|
26
26
|
this._plugins.push(e), e.setScene(this._scene), e.setUiScene(this._uiScene), e.updateBounds(this._bounds), e.moveCameraEnd(this._cameraPosition);
|
|
@@ -52,4 +52,4 @@ n([t, e("design:type", Object)], i.prototype, "_initData", void 0);
|
|
|
52
52
|
//#endregion
|
|
53
53
|
export { r as n, i as t };
|
|
54
54
|
|
|
55
|
-
//# sourceMappingURL=plugin-system-
|
|
55
|
+
//# sourceMappingURL=plugin-system-vlnG8j2T.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-system-
|
|
1
|
+
{"version":3,"file":"plugin-system-vlnG8j2T.mjs","names":[],"sources":["../../packages/configurator-core/src/webgl/plugin-system.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type { Context } from '../../../common-core/src/di/context';\nimport inject from '../../../common-core/src/di/inject';\nimport type InitData from '../../../common-core/src/utils/init-data';\nimport type { Box3, Scene, Vector3 } from 'three';\n\nexport declare interface ScenePluginHooks {\n updateBounds(bounds: Box3): void;\n\n clearScene(scene: Scene, uiScene: Scene): void;\n\n moveCameraEnd(position: Vector3): void;\n\n moveCameraStart(position: Vector3): void;\n\n needsUiScene(): boolean;\n}\n\nexport declare interface ScenePlugin extends ScenePluginHooks, Context {\n setScene(scene: Scene): void;\n\n setUiScene(uiScene: Scene): void;\n}\n\nexport class ScenePluginDefaultImplementation implements ScenePlugin {\n public _creator_: string;\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public setScene(scene: Scene): void {\n //noop\n }\n\n public setUiScene(uiScene: Scene): void {\n //noop\n }\n\n public updateBounds(bounds: Box3): void {\n //noop\n }\n\n public clearScene(scene: Scene, uiScene: Scene): void {\n //noop\n }\n\n public moveCameraEnd(position: Vector3): void {\n //noop\n }\n\n public moveCameraStart(position: Vector3): void {\n //noop\n }\n\n public needsUiScene(): boolean {\n return false;\n }\n}\n\nexport default class PluginSystem implements Context, ScenePluginHooks {\n public _creator_: string;\n\n @inject\n private _initData: InitData;\n\n private _scene: Scene;\n private _uiScene: Scene;\n private _bounds: Box3;\n private _cameraPosition: Vector3;\n\n private _plugins: ScenePlugin[] = [];\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public async init(scene: Scene, uiScene: Scene, cameraPosition: Vector3) {\n this._scene = scene;\n this._uiScene = uiScene;\n this._cameraPosition = cameraPosition;\n const { bananaForScale } = this._initData;\n\n if (bananaForScale) {\n await import('./banana-for-scale').then(({ default: BananaForScale }) =>\n this._plugins.push(new BananaForScale(this._creator_)),\n );\n }\n\n this._plugins.forEach((plugin) => plugin.setScene(this._scene));\n this._plugins.forEach((plugin) => plugin.setUiScene(this._uiScene));\n this._plugins.forEach((plugin) => plugin.updateBounds(this._bounds));\n this._plugins.forEach((plugin) =>\n plugin.moveCameraEnd(this._cameraPosition),\n );\n }\n\n public addPlugin(plugin: ScenePlugin) {\n this._plugins.push(plugin);\n plugin.setScene(this._scene);\n plugin.setUiScene(this._uiScene);\n plugin.updateBounds(this._bounds);\n plugin.moveCameraEnd(this._cameraPosition);\n }\n\n public updateBounds(bounds: Box3) {\n this._bounds = bounds;\n this._plugins.forEach((plugin) => plugin.updateBounds(bounds));\n }\n\n public clearScene(scene: Scene, uiScene: Scene): void {\n this._plugins.forEach((plugin) => plugin.clearScene(scene, uiScene));\n }\n\n public getActivePlugins(): ScenePlugin[] {\n return this._plugins;\n }\n\n public getPlugin<T extends ScenePlugin>(type: any): T | null {\n for (let plugin of this._plugins) {\n if (plugin instanceof type) {\n return plugin as T;\n }\n }\n return null;\n }\n\n public moveCameraEnd(position: Vector3): void {\n this._cameraPosition = position;\n this._plugins.forEach((plugin) => plugin.moveCameraEnd(position));\n }\n\n public moveCameraStart(position: Vector3): void {\n this._cameraPosition = position;\n this._plugins.forEach((plugin) => plugin.moveCameraStart(position));\n }\n\n public needsUiScene(): boolean {\n return this._plugins\n .map((plugin) => plugin.needsUiScene())\n .reduce(\n (previousValue, currentValue) => previousValue || currentValue,\n false,\n );\n }\n}\n"],"mappings":";;AAwBA,IAAa,IAAb,MAAqE;CAGnE,YAAY,GAAiB;AAC3B,OAAK,YAAY;;CAGnB,SAAgB,GAAoB;CAIpC,WAAkB,GAAsB;CAIxC,aAAoB,GAAoB;CAIxC,WAAkB,GAAc,GAAsB;CAItD,cAAqB,GAAyB;CAI9C,gBAAuB,GAAyB;CAIhD,eAA+B;AAC7B,SAAO;;GAIU,IAArB,MAAuE;CAarE,YAAY,GAAiB;AAC3B,kBAHgC,EAAE,EAGlC,KAAK,YAAY;;CAGnB,MAAa,KAAK,GAAc,GAAgB,GAAyB;AAGvE,EAFA,KAAK,SAAS,GACd,KAAK,WAAW,GAChB,KAAK,kBAAkB;EACvB,IAAM,EAAE,sBAAmB,KAAK;AAWhC,EATI,KACF,MAAM,OAAO,mCAAsB,MAAM,EAAE,SAAS,QAClD,KAAK,SAAS,KAAK,IAAI,EAAe,KAAK,UAAU,CAAC,CACvD,EAGH,KAAK,SAAS,SAAS,MAAW,EAAO,SAAS,KAAK,OAAO,CAAC,EAC/D,KAAK,SAAS,SAAS,MAAW,EAAO,WAAW,KAAK,SAAS,CAAC,EACnE,KAAK,SAAS,SAAS,MAAW,EAAO,aAAa,KAAK,QAAQ,CAAC,EACpE,KAAK,SAAS,SAAS,MACrB,EAAO,cAAc,KAAK,gBAAgB,CAC3C;;CAGH,UAAiB,GAAqB;AAKpC,EAJA,KAAK,SAAS,KAAK,EAAO,EAC1B,EAAO,SAAS,KAAK,OAAO,EAC5B,EAAO,WAAW,KAAK,SAAS,EAChC,EAAO,aAAa,KAAK,QAAQ,EACjC,EAAO,cAAc,KAAK,gBAAgB;;CAG5C,aAAoB,GAAc;AAEhC,EADA,KAAK,UAAU,GACf,KAAK,SAAS,SAAS,MAAW,EAAO,aAAa,EAAO,CAAC;;CAGhE,WAAkB,GAAc,GAAsB;AACpD,OAAK,SAAS,SAAS,MAAW,EAAO,WAAW,GAAO,EAAQ,CAAC;;CAGtE,mBAAyC;AACvC,SAAO,KAAK;;CAGd,UAAwC,GAAqB;AAC3D,OAAK,IAAI,KAAU,KAAK,SACtB,KAAI,aAAkB,EACpB,QAAO;AAGX,SAAO;;CAGT,cAAqB,GAAyB;AAE5C,EADA,KAAK,kBAAkB,GACvB,KAAK,SAAS,SAAS,MAAW,EAAO,cAAc,EAAS,CAAC;;CAGnE,gBAAuB,GAAyB;AAE9C,EADA,KAAK,kBAAkB,GACvB,KAAK,SAAS,SAAS,MAAW,EAAO,gBAAgB,EAAS,CAAC;;CAGrE,eAA+B;AAC7B,SAAO,KAAK,SACT,KAAK,MAAW,EAAO,cAAc,CAAC,CACtC,QACE,GAAe,MAAiB,KAAiB,GAClD,GACD;;;GAhFJ,GAAA,EAAA,eAAA,OAAA,CAAA,EAAA,EAAA,WAAA,aAAA,KAAA,EAAA"}
|
|
@@ -230,11 +230,11 @@ T && (globalThis.Request = new Proxy(T, {
|
|
|
230
230
|
var E = Symbol("napiImage"), D = document.createElement.bind(document), O = document.createElementNS.bind(document), k = (e) => {
|
|
231
231
|
let t = e.drawImage.bind(e);
|
|
232
232
|
return e.drawImage = (e, ...n) => t(e?.[E] ?? e, ...n), e;
|
|
233
|
-
}, A = null, j = () => A,
|
|
233
|
+
}, A = null, j = () => A, ee = 8192, M = 2147483647, N = (e) => {
|
|
234
234
|
let t = e.limits, n = {};
|
|
235
235
|
for (let e in t) {
|
|
236
236
|
let r = t[e];
|
|
237
|
-
n[e] = r === 0 ?
|
|
237
|
+
n[e] = r === 0 ? M : r;
|
|
238
238
|
}
|
|
239
239
|
return Object.defineProperty(e, "limits", {
|
|
240
240
|
value: n,
|
|
@@ -243,10 +243,10 @@ var E = Symbol("napiImage"), D = document.createElement.bind(document), O = docu
|
|
|
243
243
|
value: t,
|
|
244
244
|
configurable: !0
|
|
245
245
|
});
|
|
246
|
-
},
|
|
246
|
+
}, P = (e) => {
|
|
247
247
|
let { requiredLimits: t, ...n } = e ?? {};
|
|
248
248
|
return t && Object.keys(t).length > 0 ? { ...e } : n;
|
|
249
|
-
},
|
|
249
|
+
}, F = (e) => {
|
|
250
250
|
if (Array.isArray(e)) return e;
|
|
251
251
|
let { width: t, height: n, depthOrArrayLayers: r } = e;
|
|
252
252
|
return {
|
|
@@ -254,19 +254,22 @@ var E = Symbol("napiImage"), D = document.createElement.bind(document), O = docu
|
|
|
254
254
|
height: n ?? 1,
|
|
255
255
|
depthOrArrayLayers: r ?? 1
|
|
256
256
|
};
|
|
257
|
-
},
|
|
257
|
+
}, I = (e) => {
|
|
258
258
|
let t = e.createCommandEncoder.bind(e);
|
|
259
259
|
e.createCommandEncoder = (e) => {
|
|
260
260
|
let n = t(e), r = n.copyTextureToTexture.bind(n);
|
|
261
|
-
return n.copyTextureToTexture = (e, t, n) => r(e, t,
|
|
261
|
+
return n.copyTextureToTexture = (e, t, n) => r(e, t, F(n)), n;
|
|
262
262
|
};
|
|
263
|
-
}, R = (e
|
|
263
|
+
}, L = Promise.resolve(), R = (e) => {
|
|
264
|
+
let t = L.then(e);
|
|
265
|
+
return L = t.then(() => {}, () => {}), t;
|
|
266
|
+
}, z = (e, t) => {
|
|
264
267
|
let n = e.limits?.maxTextureDimension2D;
|
|
265
268
|
typeof n == "number" && n > 0 ? A = n : typeof t == "number" && (A = t);
|
|
266
|
-
},
|
|
267
|
-
let t = e.requestDevice.bind(e), n = e.limits?.maxTextureDimension2D, r = typeof n == "number" && n >
|
|
269
|
+
}, B = (e) => {
|
|
270
|
+
let t = e.requestDevice.bind(e), n = e.limits?.maxTextureDimension2D, r = typeof n == "number" && n > ee, i = (n) => {
|
|
268
271
|
if (!r) return t(n);
|
|
269
|
-
let i =
|
|
272
|
+
let i = N(e);
|
|
270
273
|
try {
|
|
271
274
|
return t(n);
|
|
272
275
|
} finally {
|
|
@@ -274,28 +277,28 @@ var E = Symbol("napiImage"), D = document.createElement.bind(document), O = docu
|
|
|
274
277
|
}
|
|
275
278
|
};
|
|
276
279
|
e.requestDevice = async (e) => {
|
|
277
|
-
let t =
|
|
280
|
+
let t = r ? {
|
|
278
281
|
...e,
|
|
279
282
|
requiredLimits: {
|
|
280
283
|
...e?.requiredLimits ?? {},
|
|
281
284
|
maxTextureDimension2D: n
|
|
282
285
|
}
|
|
283
|
-
} :
|
|
284
|
-
if (!
|
|
285
|
-
return
|
|
286
|
+
} : P(e), a = await R(() => i(t));
|
|
287
|
+
if (!a) throw Error("[headless] WebGPU adapter returned no device (adapter already invalid)");
|
|
288
|
+
return z(a, n), I(a), c(a, {
|
|
286
289
|
createNativeCanvas: d,
|
|
287
290
|
unwrapImage: (e) => e?.[E] ?? e
|
|
288
|
-
}),
|
|
291
|
+
}), a;
|
|
289
292
|
};
|
|
290
|
-
},
|
|
293
|
+
}, V = (e) => {
|
|
291
294
|
let t = e.requestAdapter.bind(e);
|
|
292
295
|
e.requestAdapter = async (e) => {
|
|
293
296
|
let n = { ...e };
|
|
294
297
|
n.powerPreference ||= "high-performance";
|
|
295
|
-
let r = await t(n);
|
|
296
|
-
return r?.info && console.log(`[headless] WebGPU adapter: ${r.info.vendor ?? "?"} ${r.info.device ?? ""} (${r.info.description ?? ""})`), r && typeof r.requestDevice == "function" &&
|
|
298
|
+
let r = await R(() => t(n));
|
|
299
|
+
return r?.info && console.log(`[headless] WebGPU adapter: ${r.info.vendor ?? "?"} ${r.info.device ?? ""} (${r.info.description ?? ""})`), r && typeof r.requestDevice == "function" && B(r), r;
|
|
297
300
|
};
|
|
298
|
-
},
|
|
301
|
+
}, H = (e) => {
|
|
299
302
|
let t = globalThis.navigator;
|
|
300
303
|
if (!t || typeof t != "object") {
|
|
301
304
|
Object.defineProperty(globalThis, "navigator", {
|
|
@@ -314,21 +317,21 @@ var E = Symbol("napiImage"), D = document.createElement.bind(document), O = docu
|
|
|
314
317
|
writable: !0
|
|
315
318
|
});
|
|
316
319
|
}
|
|
317
|
-
},
|
|
320
|
+
}, U = async (e) => {
|
|
318
321
|
try {
|
|
319
322
|
let t = (await e.requestAdapter({ powerPreference: "high-performance" }))?.limits?.maxTextureDimension2D;
|
|
320
323
|
typeof t == "number" && t > 0 && A == null && (A = t);
|
|
321
324
|
} catch (e) {
|
|
322
325
|
console.log("[headless] adapter texture-limit probe failed", e);
|
|
323
326
|
}
|
|
324
|
-
},
|
|
327
|
+
}, W = null;
|
|
325
328
|
try {
|
|
326
329
|
let e = await import("bun-webgpu");
|
|
327
|
-
|
|
330
|
+
W = e.createGPUInstance(), e.globals(), W.getPreferredCanvasFormat = () => "rgba8unorm", typeof W.requestAdapter == "function" && V(W), H(W), console.log("[headless] Using bun-webgpu (Dawn FFI) for real WebGPU rendering"), await U(W);
|
|
328
331
|
} catch (e) {
|
|
329
332
|
console.log("[headless] bun-webgpu not available, WebGPU disabled", e);
|
|
330
333
|
}
|
|
331
|
-
var
|
|
334
|
+
var G = 1, K = 16, q = 8, J = 1, Y = 1, X = 256, Z = 256 * 1024 * 1024, te = "\nstruct VSOut {\n @builtin(position) pos: vec4f,\n @location(0) uv: vec2f,\n};\n\n@vertex\nfn vs(@builtin(vertex_index) vertexIndex: u32) -> VSOut {\n var corners = array<vec2f, 3>(\n vec2f(0.0, 0.0),\n vec2f(2.0, 0.0),\n vec2f(0.0, 2.0)\n );\n let xy = corners[vertexIndex];\n var out: VSOut;\n out.pos = vec4f(xy * 2.0 - 1.0, 0.0, 1.0);\n // Clip-space y is up, texture v is down, flip v so the output keeps the\n // source orientation (row 0 = top), matching the direct readback path.\n out.uv = vec2f(xy.x, 1.0 - xy.y);\n return out;\n}\n\n@group(0) @binding(0) var srcTex: texture_2d<f32>;\n@group(0) @binding(1) var srcSampler: sampler;\n\n@fragment\nfn fs(in: VSOut) -> @location(0) vec4f {\n return textureSample(srcTex, srcSampler, in.uv);\n}\n", ne = (e) => {
|
|
332
335
|
let t = null, n = "bgra8unorm", r = 0, i = null, a = 0, o = 0, s = null, c = null, l = null, u = null, d = 0, f = 0, p = null, m = 0, h = !1, g = () => {
|
|
333
336
|
if (!t) throw Error("[headless] WebGPU canvas context has no device");
|
|
334
337
|
return t;
|
|
@@ -361,7 +364,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
361
364
|
}
|
|
362
365
|
}, b = (e) => g().createBuffer({
|
|
363
366
|
size: e,
|
|
364
|
-
usage:
|
|
367
|
+
usage: q | J
|
|
365
368
|
}), x = (e) => {
|
|
366
369
|
if (h) {
|
|
367
370
|
let t = b(e);
|
|
@@ -382,7 +385,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
382
385
|
e[t] = e[t + 2], e[t + 2] = n;
|
|
383
386
|
}
|
|
384
387
|
}, C = async (e, t, r) => {
|
|
385
|
-
let i = g(), a = t * 4, o = Math.ceil(a /
|
|
388
|
+
let i = g(), a = t * 4, o = Math.ceil(a / X) * X, s = Math.max(1, Math.floor(Z * .95 / o)), { buffer: c, release: l } = x(o * Math.min(s, r)), u = new Uint8Array(a * r);
|
|
386
389
|
try {
|
|
387
390
|
for (let n = 0; n < r; n += s) {
|
|
388
391
|
let l = Math.min(s, r - n), d = i.createCommandEncoder();
|
|
@@ -401,7 +404,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
401
404
|
width: t,
|
|
402
405
|
height: l,
|
|
403
406
|
depthOrArrayLayers: 1
|
|
404
|
-
}), i.queue.submit([d.finish()]), await c.mapAsync(
|
|
407
|
+
}), i.queue.submit([d.finish()]), await c.mapAsync(Y);
|
|
405
408
|
let f = new Uint8Array(c.getMappedRange());
|
|
406
409
|
for (let e = 0; e < l; e++) u.set(f.subarray(e * o, e * o + a), (n + e) * a);
|
|
407
410
|
c.unmap();
|
|
@@ -421,7 +424,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
421
424
|
pipeline: c,
|
|
422
425
|
sampler: l
|
|
423
426
|
};
|
|
424
|
-
let e = g(), t = e.createShaderModule({ code:
|
|
427
|
+
let e = g(), t = e.createShaderModule({ code: te }), r = e.createRenderPipeline({
|
|
425
428
|
layout: "auto",
|
|
426
429
|
vertex: {
|
|
427
430
|
module: t,
|
|
@@ -448,7 +451,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
448
451
|
depthOrArrayLayers: 1
|
|
449
452
|
},
|
|
450
453
|
format: n,
|
|
451
|
-
usage:
|
|
454
|
+
usage: K | G
|
|
452
455
|
}), u), D = () => {
|
|
453
456
|
i &&= (_(i), null);
|
|
454
457
|
}, O = () => {
|
|
@@ -520,10 +523,10 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
520
523
|
return s;
|
|
521
524
|
},
|
|
522
525
|
getPreferredFormat() {
|
|
523
|
-
return
|
|
526
|
+
return W?.getPreferredCanvasFormat?.() ?? "bgra8unorm";
|
|
524
527
|
}
|
|
525
528
|
};
|
|
526
|
-
},
|
|
529
|
+
}, Q = (e = 300, t = 150) => {
|
|
527
530
|
let n = d(e, t), r = null, i = null, a = new Proxy(n, {
|
|
528
531
|
get(e, t) {
|
|
529
532
|
if (t === E) return e;
|
|
@@ -538,7 +541,7 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
538
541
|
toggle() {}
|
|
539
542
|
};
|
|
540
543
|
if (t === Symbol.toStringTag) return "HTMLCanvasElement";
|
|
541
|
-
if (t === "getContext") return (t, n) => t === "2d" ? (r ||= k(e.getContext("2d", n)), r) : t === "webgl2" || t === "webgl" ? null : t === "webgpu" ?
|
|
544
|
+
if (t === "getContext") return (t, n) => t === "2d" ? (r ||= k(e.getContext("2d", n)), r) : t === "webgl2" || t === "webgl" ? null : t === "webgpu" ? W ? (i ||= ne(a), i) : null : e.getContext(t, n);
|
|
542
545
|
if (t === "addEventListener" || t === "removeEventListener") return () => {};
|
|
543
546
|
if (t === "getBoundingClientRect") return () => ({
|
|
544
547
|
x: 0,
|
|
@@ -568,7 +571,17 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
568
571
|
}
|
|
569
572
|
});
|
|
570
573
|
return a;
|
|
571
|
-
},
|
|
574
|
+
}, re = 3e4, $ = 3, ie = async (e) => {
|
|
575
|
+
let t;
|
|
576
|
+
for (let n = 1; n <= $; n++) try {
|
|
577
|
+
let t = await fetch(e, { signal: AbortSignal.timeout(re) });
|
|
578
|
+
if (!t.ok) throw Error(`HTTP ${t.status} for ${e}`);
|
|
579
|
+
return await t.arrayBuffer();
|
|
580
|
+
} catch (r) {
|
|
581
|
+
t = r, console.warn(`image request attempt ${n}/${$} failed for ${e}:`, r instanceof Error ? r.message : r);
|
|
582
|
+
}
|
|
583
|
+
throw t instanceof Error ? t : Error(String(t));
|
|
584
|
+
}, ae = () => {
|
|
572
585
|
let e = O("http://www.w3.org/1999/xhtml", "img"), t = new f();
|
|
573
586
|
e[E] = t;
|
|
574
587
|
let n = "";
|
|
@@ -577,14 +590,15 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
577
590
|
return n;
|
|
578
591
|
},
|
|
579
592
|
set(r) {
|
|
580
|
-
if (n = r, typeof r == "string" && r.startsWith("blob:")) {
|
|
581
|
-
fetch(r).then((e) => e.arrayBuffer()).then((e) => {
|
|
593
|
+
if (n = r, typeof r == "string" && (r.startsWith("blob:") || r.startsWith("http:") || r.startsWith("https:"))) {
|
|
594
|
+
(r.startsWith("blob:") ? fetch(r).then((e) => e.arrayBuffer()) : ie(r)).then((e) => {
|
|
582
595
|
n === r && (t.src = Buffer.from(e));
|
|
583
596
|
}).catch((t) => {
|
|
584
|
-
|
|
597
|
+
if (n !== r) return;
|
|
598
|
+
let i = t instanceof Error ? t : Error(String(t));
|
|
585
599
|
e.dispatchEvent(new ErrorEvent("error", {
|
|
586
|
-
error:
|
|
587
|
-
message:
|
|
600
|
+
error: i,
|
|
601
|
+
message: i.message
|
|
588
602
|
}));
|
|
589
603
|
});
|
|
590
604
|
return;
|
|
@@ -618,11 +632,11 @@ var W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\ns
|
|
|
618
632
|
}));
|
|
619
633
|
}, e;
|
|
620
634
|
};
|
|
621
|
-
document.createElement = (e, t) => e.toLowerCase() === "canvas" ?
|
|
635
|
+
document.createElement = (e, t) => e.toLowerCase() === "canvas" ? Q() : D(e, t), document.createElementNS = (e, t, n) => {
|
|
622
636
|
let r = t.toLowerCase();
|
|
623
|
-
return r === "canvas" ?
|
|
637
|
+
return r === "canvas" ? Q() : r === "img" ? ae() : O(e, t, n);
|
|
624
638
|
};
|
|
625
639
|
//#endregion
|
|
626
640
|
export { j as t };
|
|
627
641
|
|
|
628
|
-
//# sourceMappingURL=roomle-headless-setup-
|
|
642
|
+
//# sourceMappingURL=roomle-headless-setup-DbO_rLjK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roomle-headless-setup-DbO_rLjK.mjs","names":["#registered"],"sources":["../../packages/headless-core/src/headless-webgpu-queue-polyfill.ts","../../packages/headless-core/src/setup-environment.ts"],"sourcesContent":["/// <reference types=\"@webgpu/types\" />\n// Headless polyfill for GPUQueue.copyExternalImageToTexture (bun-webgpu stubs it).\n// See .agents/headless-sdk.md § copyExternalImageToTexture polyfill.\n\nimport type { RawImagePixels } from '../../common-core/src/common-interfaces';\n\ninterface NativeContext2d {\n clearRect(x: number, y: number, width: number, height: number): void;\n drawImage(\n image: unknown,\n x: number,\n y: number,\n width: number,\n height: number,\n ): void;\n getImageData(\n x: number,\n y: number,\n width: number,\n height: number,\n ): { data: ArrayBufferView };\n}\n\ninterface NativeCanvas {\n width: number;\n height: number;\n getContext(contextId: '2d'): NativeContext2d | null;\n}\n\ninterface ImageDataSource {\n data: ArrayBufferView;\n width: number;\n height: number;\n}\n\ninterface CanvasSource {\n width?: number;\n height?: number;\n getContext(contextId: '2d'): NativeContext2d | null;\n}\n\ninterface DrawableSource {\n width?: number;\n height?: number;\n videoWidth?: number;\n videoHeight?: number;\n}\n\nexport interface QueuePolyfillHelpers {\n createNativeCanvas: (width: number, height: number) => NativeCanvas;\n // The headless <img> proxy stores the real napi Image under a symbol; unwrap\n // it so drawImage runs native-to-native.\n unwrapImage?: (source: unknown) => unknown;\n}\n\nconst asUint8Array = (view: ArrayBufferView): Uint8Array =>\n view instanceof Uint8Array\n ? view\n : new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n\nconst toExtentSize = (\n size: GPUExtent3DStrict,\n): { width: number; height: number } => {\n if (Array.isArray(size)) {\n return { width: size[0] ?? 0, height: size[1] ?? 0 };\n }\n const { width, height } = size as GPUExtent3DDictStrict;\n return { width: width ?? 0, height: height ?? 0 };\n};\n\nconst isImageDataSource = (source: object): source is ImageDataSource =>\n ArrayBuffer.isView((source as ImageDataSource).data) &&\n typeof (source as ImageDataSource).width === 'number' &&\n typeof (source as ImageDataSource).height === 'number';\n\nconst isCanvasSource = (source: object): source is CanvasSource =>\n typeof (source as CanvasSource).getContext === 'function';\n\nconst flipRowsRGBA = (\n data: Uint8Array,\n width: number,\n height: number,\n): Uint8Array => {\n const rowBytes = width * 4;\n const flipped = new Uint8Array(rowBytes * height);\n for (let row = 0; row < height; row++) {\n flipped.set(\n data.subarray((height - 1 - row) * rowBytes, (height - row) * rowBytes),\n row * rowBytes,\n );\n }\n return flipped;\n};\n\nconst premultiplyAlphaRGBA = (data: Uint8Array): void => {\n for (let i = 0; i < data.length; i += 4) {\n const alpha = data[i + 3]!;\n if (alpha === 255) {\n continue;\n }\n const factor = alpha / 255;\n data[i] = Math.round(data[i]! * factor);\n data[i + 1] = Math.round(data[i + 1]! * factor);\n data[i + 2] = Math.round(data[i + 2]! * factor);\n }\n};\n\nconst swizzleRedBlueRGBA = (data: Uint8Array): void => {\n for (let i = 0; i < data.length; i += 4) {\n const red = data[i]!;\n data[i] = data[i + 2]!;\n data[i + 2] = red;\n }\n};\n\n// Overrides unconditionally: upstream stubs the method with a fatal error, so\n// there is nothing to feature-detect.\nexport function installCopyExternalImageToTexturePolyfill(\n device: GPUDevice | null | undefined,\n helpers: QueuePolyfillHelpers,\n): void {\n const queue = device?.queue;\n if (!queue || typeof queue.writeTexture !== 'function') {\n return;\n }\n\n // Pooled scratch canvas, reused across uploads instead of one per call.\n let scratchCanvas: NativeCanvas | null = null;\n const getScratchContext = (\n width: number,\n height: number,\n ): NativeContext2d | null => {\n if (!scratchCanvas) {\n scratchCanvas = helpers.createNativeCanvas(width, height);\n } else {\n // Assigning width/height resets the backing store, so only on a change.\n if (scratchCanvas.width !== width) {\n scratchCanvas.width = width;\n }\n if (scratchCanvas.height !== height) {\n scratchCanvas.height = height;\n }\n }\n const context = scratchCanvas.getContext('2d');\n // Resizing resets the canvas; clear defensively for same-size reuse so a\n // smaller-than-canvas draw never leaks the previous upload's pixels.\n context?.clearRect(0, 0, width, height);\n return context;\n };\n\n const extractImagePixels = (\n source: unknown,\n fallbackWidth: number,\n fallbackHeight: number,\n ): RawImagePixels | null => {\n if (!source || typeof source !== 'object') {\n return null;\n }\n\n if (isImageDataSource(source)) {\n return {\n data: asUint8Array(source.data),\n width: source.width,\n height: source.height,\n };\n }\n\n const drawable = source as DrawableSource;\n const width =\n (drawable.width ?? drawable.videoWidth ?? fallbackWidth) | 0 || 0;\n const height =\n (drawable.height ?? drawable.videoHeight ?? fallbackHeight) | 0 || 0;\n if (width <= 0 || height <= 0) {\n return null;\n }\n\n if (isCanvasSource(source)) {\n const canvasContext = source.getContext('2d');\n if (canvasContext) {\n const imageData = canvasContext.getImageData(0, 0, width, height);\n return { data: asUint8Array(imageData.data), width, height };\n }\n }\n\n const scratchContext = getScratchContext(width, height);\n if (!scratchContext) {\n return null;\n }\n scratchContext.drawImage(\n helpers.unwrapImage ? helpers.unwrapImage(source) : source,\n 0,\n 0,\n width,\n height,\n );\n const imageData = scratchContext.getImageData(0, 0, width, height);\n return { data: asUint8Array(imageData.data), width, height };\n };\n\n queue.copyExternalImageToTexture = (\n source: GPUCopyExternalImageSourceInfo,\n destination: GPUCopyExternalImageDestInfo,\n copySize: GPUExtent3DStrict,\n ): undefined => {\n const size = toExtentSize(copySize);\n const extracted = extractImagePixels(\n source?.source,\n size.width,\n size.height,\n );\n if (!extracted) {\n throw new Error(\n '[headless] copyExternalImageToTexture: could not read pixels from ' +\n \"source. Expected ImageData, a canvas exposing getContext('2d'), \" +\n 'or a drawable image.',\n );\n }\n\n const { width, height } = extracted;\n // Fall back to the source dimensions when a copySize dimension is absent.\n const copyWidth = Math.min(width, size.width || width);\n const copyHeight = Math.min(height, size.height || height);\n\n let data = extracted.data;\n let isPrivateCopy = false;\n\n if (source?.flipY) {\n data = flipRowsRGBA(data, width, height);\n isPrivateCopy = true;\n }\n\n // getImageData is straight-alpha RGBA; premultiply / bgra-swizzle to match\n // the destination as requested (bgra is rare, headless prefers rgba8unorm).\n const needsPremultiply = destination?.premultipliedAlpha === true;\n const format = destination?.texture?.format;\n const needsSwizzle =\n typeof format === 'string' && format.startsWith('bgra');\n\n if (needsPremultiply || needsSwizzle) {\n if (!isPrivateCopy) {\n data = new Uint8Array(data);\n isPrivateCopy = true;\n }\n if (needsPremultiply) {\n premultiplyAlphaRGBA(data);\n }\n if (needsSwizzle) {\n swizzleRedBlueRGBA(data);\n }\n }\n\n queue.writeTexture(\n {\n texture: destination.texture,\n mipLevel: destination.mipLevel ?? 0,\n origin: destination.origin ?? { x: 0, y: 0, z: 0 },\n aspect: destination.aspect ?? 'all',\n },\n data,\n { offset: 0, bytesPerRow: width * 4, rowsPerImage: height },\n { width: copyWidth, height: copyHeight, depthOrArrayLayers: 1 },\n );\n return undefined;\n };\n}\n","/// <reference types=\"@webgpu/types\" />\nimport { createRequire } from 'module';\nimport type { IOptionalBrowserSettings } from 'happy-dom';\nimport type { createGPUInstance } from 'bun-webgpu';\nimport { installCopyExternalImageToTexturePolyfill } from './headless-webgpu-queue-polyfill';\n\ntype BunWebGpuInstance = ReturnType<typeof createGPUInstance>;\n\nconst napiCanvas = await import('@napi-rs/canvas').catch((): null => null);\nconst happyDom = await import('happy-dom').catch((): null => null);\n\nif (!napiCanvas) {\n throw new Error(\n '[headless] @napi-rs/canvas is required for headless setup. ' +\n 'Install it (it is an optionalDependency of @roomle/web-sdk)',\n );\n}\n\nif (!happyDom) {\n throw new Error(\n '[headless] happy-dom is required for headless setup. ' +\n 'Install it (it is an optionalDependency of @roomle/web-sdk)',\n );\n}\n\nconst {\n createCanvas: createNapiCanvas,\n Image: NapiImage,\n ImageData: NapiImageData,\n} = napiCanvas;\nconst { GlobalWindow, PropertySymbol } = happyDom;\n\n// Network APIs and built-ins that happy-dom must not override\n// We rely on Node/Bun native implementations for these.\nconst IGNORE_LIST = [\n 'fetch',\n 'Response',\n 'Request',\n 'Headers',\n 'AbortController',\n 'AbortSignal',\n 'ReadableStream',\n 'WritableStream',\n 'TransformStream',\n 'FormData',\n 'URL',\n 'URLSearchParams',\n 'Blob',\n 'File',\n 'constructor',\n 'undefined',\n 'NaN',\n 'global',\n 'globalThis',\n];\n\nclass GlobalRegistrator {\n static #registered: {\n [key: string | symbol]: PropertyDescriptor | null;\n } | null = null;\n\n public static get isRegistered(): boolean {\n return this.#registered !== null;\n }\n\n public static register(options?: {\n width?: number;\n height?: number;\n url?: string;\n settings?: IOptionalBrowserSettings;\n }): void {\n if (this.#registered !== null) {\n throw new Error(\n 'Failed to register. Happy DOM has already been globally registered.',\n );\n }\n\n const window = new GlobalWindow({\n ...options,\n console: globalThis.console,\n });\n\n this.#registered = {};\n\n const propertyDescriptors = Object.getOwnPropertyDescriptors(window);\n\n for (const key of Object.keys(propertyDescriptors)) {\n if (!IGNORE_LIST.includes(key)) {\n const windowPropertyDescriptor = propertyDescriptors[key];\n const globalPropertyDescriptor = Object.getOwnPropertyDescriptor(\n globalThis,\n key,\n );\n\n if (\n globalPropertyDescriptor?.value === undefined ||\n globalPropertyDescriptor?.value !== windowPropertyDescriptor?.value\n ) {\n this.#registered[key] = globalPropertyDescriptor || null;\n\n if (windowPropertyDescriptor?.value === window) {\n (window as any)[key] = globalThis;\n windowPropertyDescriptor.value = globalThis;\n }\n\n Object.defineProperty(globalThis, key, {\n ...windowPropertyDescriptor,\n configurable: true,\n });\n }\n }\n }\n\n const propertySymbols = Object.getOwnPropertySymbols(window);\n\n for (const key of propertySymbols) {\n const propertyDescriptor = Object.getOwnPropertyDescriptor(window, key);\n this.#registered[key] = null;\n\n if (propertyDescriptor!.value === window) {\n (window as any)[key] = globalThis;\n propertyDescriptor!.value = globalThis;\n }\n\n Object.defineProperty(globalThis, key, {\n ...propertyDescriptor,\n configurable: true,\n });\n }\n\n (globalThis as any).document[PropertySymbol.defaultView] = globalThis;\n }\n\n public static async unregister(): Promise<void> {\n if (this.#registered === null) {\n throw new Error(\n 'Failed to unregister. Happy DOM has not previously been globally registered.',\n );\n }\n\n const happyDOM = (globalThis as any).happyDOM;\n\n for (const key of Object.keys(this.#registered)) {\n if (this.#registered[key] !== null) {\n Object.defineProperty(globalThis, key, this.#registered[key]!);\n } else {\n delete (globalThis as any)[key];\n }\n }\n\n this.#registered = null;\n\n if (happyDOM) {\n await happyDOM.close();\n }\n }\n}\n\n// Resolves the bundle directory so root-relative Vite asset URLs like\n// \"/default_256.exr\" can be mapped to real files next to the bundle.\n// We use a bare `import.meta.url` (not wrapped in `new URL(…, import.meta.url)`)\n// because Rollup replaces the latter pattern with a data: URI at build time.\nconst _setupRequire = createRequire(import.meta.url);\nconst _fsSync = _setupRequire('fs');\nconst _pathSync = _setupRequire('path');\nconst _urlSync = _setupRequire('url');\nlet _bundleDir = '';\ntry {\n _bundleDir = _pathSync.dirname(_urlSync.fileURLToPath(import.meta.url));\n} catch {\n // Not a file URL\n}\n\n// Maps a root-relative path (e.g. \"/default_256.exr\") to a local file path\n// next to the bundle. Returns null when the file doesn't exist. */\nconst _resolveRootRelative = (urlPath: string): string | null => {\n if (!_bundleDir || !urlPath.startsWith('/') || urlPath.startsWith('//')) {\n return null;\n }\n const candidate = _pathSync.join(_bundleDir, urlPath);\n return _fsSync.existsSync(candidate) ? candidate : null;\n};\n\n// Patch globalThis.fetch to handle:\n// 1. file:// URLs, Node/undici rejects these natively; Bun accepts them.\n// 2. Root-relative URLs (e.g. \"/default_256.exr\") emitted by Vite's ?url\n// transform; no web server in Node means native fetch throws \"Invalid URL\".\nconst _nativeFetch = globalThis.fetch;\n// @ts-ignore -- this conflicts with DOM types.\nglobalThis.fetch = async (\n input: string | URL | Request,\n init?: RequestInit,\n): Promise<Response> => {\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.href\n : (input as any).url ?? String(input);\n\n if (url.startsWith('file://')) {\n const buffer = _fsSync.readFileSync(_urlSync.fileURLToPath(url));\n return new Response(buffer, {\n status: 200,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n }\n\n if (url.startsWith('/') && !url.startsWith('//')) {\n const localPath = _resolveRootRelative(url);\n if (localPath) {\n return new Response(_fsSync.readFileSync(localPath), {\n status: 200,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n }\n console.warn(\n `[headless] fetch: root-relative asset not found: ${url} (bundle dir: ${_bundleDir || 'unknown'})`,\n );\n return new Response(null, { status: 404, statusText: 'Not Found' });\n }\n\n return _nativeFetch.call(this, input, init);\n};\n\n// Proxy-wrap globalThis.Request so root-relative paths are converted to\n// file:// URLs before the constructor validates them. Three.js's FileLoader\n// calls `new Request(url)` before fetch(), so our fetch patch above is never\n// reached if the constructor throws first.\nconst _OrigRequest = (globalThis as any).Request;\nif (_OrigRequest) {\n (globalThis as any).Request = new Proxy(_OrigRequest, {\n construct(Target: any, [input, init]: [any, any]) {\n if (\n typeof input === 'string' &&\n input.startsWith('/') &&\n !input.startsWith('//')\n ) {\n const localPath =\n _resolveRootRelative(input) ??\n _pathSync.join(_bundleDir || '/tmp', input);\n input = _urlSync.pathToFileURL(localPath).href;\n }\n return Reflect.construct(\n Target,\n init !== undefined ? [input, init] : [input],\n Target,\n );\n },\n get(target: any, prop: string | symbol) {\n return target[prop];\n },\n });\n}\n\nGlobalRegistrator.register();\n\n// Throttle requestAnimationFrame to ~60fps (happy-dom's is unthrottled).\n// See .agents/headless-sdk.md § requestAnimationFrame is throttled to ~60 fps.\n{\n const RAF_INTERVAL_MS = 1000 / 60;\n (globalThis as any).requestAnimationFrame = (\n callback: FrameRequestCallback,\n ): number =>\n setTimeout(\n () => callback(performance.now()),\n RAF_INTERVAL_MS,\n ) as unknown as number;\n (globalThis as any).cancelAnimationFrame = (handle: number): void =>\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n}\n\n// Provide napi-rs/canvas ImageData globally as GLTFExporter uses `new ImageData(…)`\nif (typeof (globalThis as any).ImageData === 'undefined') {\n (globalThis as any).ImageData = NapiImageData;\n}\n\n// FileReader shim because happy-dom's FileReader only accepts happy-dom Blobs\nclass NodeFileReader {\n public result: ArrayBuffer | string | null = null;\n public error: unknown = null;\n public readyState: number = 0;\n public onload: ((ev: any) => void) | null = null;\n public onloadend: ((ev: any) => void) | null = null;\n public onerror: ((ev: any) => void) | null = null;\n\n readAsArrayBuffer(blob: Blob): void {\n this.readyState = 1;\n blob.arrayBuffer().then(\n (buf) => {\n this.result = buf;\n this.readyState = 2;\n const ev = { target: this };\n this.onload?.(ev);\n this.onloadend?.(ev);\n },\n (err) => {\n this.error = err;\n this.readyState = 2;\n const ev = { target: this };\n this.onerror?.(ev);\n this.onloadend?.(ev);\n },\n );\n }\n\n readAsDataURL(blob: Blob): void {\n this.readyState = 1;\n blob.arrayBuffer().then(\n (buf) => {\n const b64 = Buffer.from(buf).toString('base64');\n const type = (blob as any).type || 'application/octet-stream';\n this.result = `data:${type};base64,${b64}`;\n this.readyState = 2;\n const ev = { target: this };\n this.onload?.(ev);\n this.onloadend?.(ev);\n },\n (err) => {\n this.error = err;\n this.readyState = 2;\n const ev = { target: this };\n this.onerror?.(ev);\n this.onloadend?.(ev);\n },\n );\n }\n\n readAsText(blob: Blob): void {\n this.readyState = 1;\n blob.text().then(\n (text) => {\n this.result = text;\n this.readyState = 2;\n const ev = { target: this };\n this.onload?.(ev);\n this.onloadend?.(ev);\n },\n (err) => {\n this.error = err;\n this.readyState = 2;\n const ev = { target: this };\n this.onerror?.(ev);\n this.onloadend?.(ev);\n },\n );\n }\n\n abort(): void {}\n}\n\n(globalThis as any).FileReader = NodeFileReader;\n\n// Symbol for storing the underlying NapiImage on wrapper elements so that\n// the patched 2d context can unwrap it before calling the native drawImage.\nconst NAPI_IMAGE = Symbol('napiImage');\n\ninterface NapiImageWrapper {\n [NAPI_IMAGE]?: CanvasImageSource;\n}\n\nconst origCreateElement = document.createElement.bind(document);\nconst origCreateElementNS = document.createElementNS.bind(document);\n\n// Patches a napi-rs/canvas 2d context so drawImage() unwraps NAPI_IMAGE wrappers.\n// Skia's native drawImage only accepts its own Image/Canvas types.\nconst patchContext2d = (\n ctx: CanvasRenderingContext2D,\n): CanvasRenderingContext2D => {\n const origDrawImage = ctx.drawImage.bind(ctx);\n ctx.drawImage = (image: CanvasImageSource, ...args: any[]) => {\n const real = (image as NapiImageWrapper | undefined)?.[NAPI_IMAGE] ?? image;\n return origDrawImage(real, ...args);\n };\n return ctx;\n};\n\nlet headlessWebGpuMaxTextureDimension: number | null = null;\n\n// The GPU's granted `maxTextureDimension2D`, or null before device creation\nexport const getHeadlessWebGpuMaxTextureDimension = (): number | null => {\n return headlessWebGpuMaxTextureDimension;\n};\n\nconst SPEC_DEFAULT_MAX_TEXTURE_DIMENSION = 8192;\nconst LIMIT_VALIDATION_HINT = 0x7fffffff;\n\n// Shadows the adapter's limits with mis-read-0 fields bumped high, for\n// bun-webgpu's requiredLimits validation ONLY (see .agents/headless-sdk.md\n// § Adaptive maxTextureDimension2D). Values sent to Dawn are unchanged; without\n// this the device request throws and three falls back to its null WebGL2 backend.\nconst shadowZeroLimits = (adapter: GPUAdapter): (() => void) => {\n const realLimits = adapter.limits;\n const validationHints: Record<string, number> = {};\n for (const limitName in realLimits) {\n const limit = (realLimits as unknown as Record<string, number>)[limitName]!;\n validationHints[limitName] = limit === 0 ? LIMIT_VALIDATION_HINT : limit;\n }\n Object.defineProperty(adapter, 'limits', {\n value: validationHints,\n configurable: true,\n });\n return () =>\n Object.defineProperty(adapter, 'limits', {\n value: realLimits,\n configurable: true,\n });\n};\n\n// Strips an empty requiredLimits ({} from three) so bun-webgpu doesn't\n// pack+validate the full limits struct.\nconst withoutEmptyRequiredLimits = (\n descriptor: GPUDeviceDescriptor | undefined,\n): GPUDeviceDescriptor => {\n const { requiredLimits, ...rest } = descriptor ?? {};\n return requiredLimits && Object.keys(requiredLimits).length > 0\n ? { ...descriptor }\n : (rest as GPUDeviceDescriptor);\n};\n\nconst getGPUExtent3D = (size: GPUExtent3DStrict): GPUExtent3DStrict => {\n if (Array.isArray(size)) {\n return size;\n }\n\n const { width, height, depthOrArrayLayers } = size as GPUExtent3DDictStrict;\n return {\n width: width ?? 1,\n height: height ?? 1,\n depthOrArrayLayers: depthOrArrayLayers ?? 1,\n };\n};\n\nconst patchCopyTextureToTexture = (device: GPUDevice) => {\n const createCommandEncoder = device.createCommandEncoder.bind(device);\n device.createCommandEncoder = (descriptor?: GPUCommandEncoderDescriptor) => {\n const encoder = createCommandEncoder(descriptor);\n const copyTextureToTexture = encoder.copyTextureToTexture.bind(encoder);\n encoder.copyTextureToTexture = (\n source: GPUTexelCopyTextureInfo,\n destination: GPUTexelCopyTextureInfo,\n copySize: GPUExtent3DStrict,\n ) => copyTextureToTexture(source, destination, getGPUExtent3D(copySize));\n return encoder;\n };\n};\n\nlet gpuAcquisitionQueue: Promise<void> = Promise.resolve();\n\nconst serializeGpuAcquisition = <T>(acquire: () => Promise<T>): Promise<T> => {\n const next = gpuAcquisitionQueue.then(acquire);\n gpuAcquisitionQueue = next.then(\n () => {},\n () => {},\n );\n return next;\n};\n\nconst rememberGrantedTextureDimension = (\n device: GPUDevice,\n adapterMaxTextureDimension: number | undefined,\n) => {\n const granted = device.limits?.maxTextureDimension2D;\n if (typeof granted === 'number' && granted > 0) {\n headlessWebGpuMaxTextureDimension = granted;\n } else if (typeof adapterMaxTextureDimension === 'number') {\n headlessWebGpuMaxTextureDimension = adapterMaxTextureDimension;\n }\n};\n\nconst patchRequestDevice = (adapter: GPUAdapter) => {\n const requestDevice = adapter.requestDevice.bind(adapter);\n const adapterMaxTextureDimension = adapter.limits?.maxTextureDimension2D;\n // Raise the texture limit only when the adapter beats the spec default;\n // otherwise keep the no-requiredLimits path.\n const canRaiseTextureLimit =\n typeof adapterMaxTextureDimension === 'number' &&\n adapterMaxTextureDimension > SPEC_DEFAULT_MAX_TEXTURE_DIMENSION;\n\n const requestDeviceWithShadowedLimits = (\n request: GPUDeviceDescriptor,\n ): Promise<GPUDevice | null> => {\n if (!canRaiseTextureLimit) {\n return requestDevice(request);\n }\n const restoreLimits = shadowZeroLimits(adapter);\n try {\n return requestDevice(request);\n } finally {\n restoreLimits();\n }\n };\n\n adapter.requestDevice = async (descriptor?: GPUDeviceDescriptor) => {\n // Only maxTextureDimension2D is set; every other limit stays unset so it\n // packs the spec default and reaches Dawn as before.\n const request = canRaiseTextureLimit\n ? {\n ...descriptor,\n requiredLimits: {\n ...(descriptor?.requiredLimits ?? {}),\n maxTextureDimension2D: adapterMaxTextureDimension,\n },\n }\n : withoutEmptyRequiredLimits(descriptor);\n\n const device = await serializeGpuAcquisition(() =>\n requestDeviceWithShadowedLimits(request as GPUDeviceDescriptor),\n );\n if (!device) {\n throw new Error(\n '[headless] WebGPU adapter returned no device (adapter already invalid)',\n );\n }\n\n rememberGrantedTextureDimension(device, adapterMaxTextureDimension);\n patchCopyTextureToTexture(device);\n installCopyExternalImageToTexturePolyfill(device, {\n createNativeCanvas: createNapiCanvas,\n unwrapImage: (source: unknown) =>\n (source as NapiImageWrapper | undefined)?.[NAPI_IMAGE] ?? source,\n });\n return device;\n };\n};\n\n// Default to the discrete GPU (Dawn may otherwise pick an iGPU/CPU adapter);\n// an explicit powerPreference still wins.\nconst patchRequestAdapter = (gpu: BunWebGpuInstance) => {\n const requestAdapter = gpu.requestAdapter.bind(gpu);\n gpu.requestAdapter = async (options?: GPURequestAdapterOptions) => {\n const adapterOptions: GPURequestAdapterOptions = { ...options };\n if (!adapterOptions.powerPreference) {\n adapterOptions.powerPreference = 'high-performance';\n }\n const adapter = await serializeGpuAcquisition<GPUAdapter | null>(() =>\n requestAdapter(adapterOptions),\n );\n if (adapter?.info) {\n console.log(\n `[headless] WebGPU adapter: ${adapter.info.vendor ?? '?'} ${adapter.info.device ?? ''} (${adapter.info.description ?? ''})`,\n );\n }\n if (adapter && typeof adapter.requestDevice === 'function') {\n patchRequestDevice(adapter);\n }\n return adapter;\n };\n};\n\nconst installNavigatorGpu = (gpu: BunWebGpuInstance) => {\n const currentNavigator = (globalThis as any).navigator;\n if (!currentNavigator || typeof currentNavigator !== 'object') {\n Object.defineProperty(globalThis, 'navigator', {\n value: { gpu },\n configurable: true,\n writable: true,\n });\n return;\n }\n try {\n currentNavigator.gpu = gpu;\n } catch {\n Object.defineProperty(currentNavigator, 'gpu', {\n value: gpu,\n configurable: true,\n writable: true,\n });\n }\n};\n\n// Device creation is lazy, so probe the adapter at setup time to have the\n// limit available before the first render.\nconst probeMaxTextureDimension = async (gpu: BunWebGpuInstance) => {\n try {\n const adapter = await gpu.requestAdapter({\n powerPreference: 'high-performance',\n });\n const maxTextureDimension = adapter?.limits?.maxTextureDimension2D;\n if (\n typeof maxTextureDimension === 'number' &&\n maxTextureDimension > 0 &&\n headlessWebGpuMaxTextureDimension == null\n ) {\n headlessWebGpuMaxTextureDimension = maxTextureDimension;\n }\n } catch (error) {\n console.log('[headless] adapter texture-limit probe failed', error);\n }\n};\n\nlet webgpuInstance: BunWebGpuInstance | null = null;\ntry {\n const bunWebgpu = await import('bun-webgpu');\n // Synchronous; loads the native Dawn wrapper from the platform companion\n // package (bun-webgpu-<platform>-<arch>) and returns the navigator.gpu object.\n webgpuInstance = bunWebgpu.createGPUInstance();\n // Install the WebGPU global constructors/enums three.js references.\n bunWebgpu.globals();\n // Prefer rgba8unorm for the offscreen canvas (avoids a full-frame B/R\n // swizzle per readback). See .agents/headless-sdk.md § Preferred canvas format.\n webgpuInstance.getPreferredCanvasFormat = () => 'rgba8unorm';\n // See .agents/headless-sdk.md § Device request workarounds.\n if (typeof webgpuInstance.requestAdapter === 'function') {\n patchRequestAdapter(webgpuInstance);\n }\n installNavigatorGpu(webgpuInstance);\n console.log(\n '[headless] Using bun-webgpu (Dawn FFI) for real WebGPU rendering',\n );\n await probeMaxTextureDimension(webgpuInstance);\n} catch (error) {\n console.log('[headless] bun-webgpu not available, WebGPU disabled', error);\n}\n\n// Spec-defined WebGPU flag constants. Used literally so we don't depend on\n// node-webgpu exposing them as module exports.\nconst GPU_TEXTURE_USAGE_COPY_SRC = 0x01;\nconst GPU_TEXTURE_USAGE_TEXTURE_BINDING = 0x04;\nconst GPU_TEXTURE_USAGE_RENDER_ATTACHMENT = 0x10;\nconst GPU_BUFFER_USAGE_COPY_DST = 0x08;\nconst GPU_BUFFER_USAGE_MAP_READ = 0x01;\nconst GPU_MAP_MODE_READ = 0x01;\n// WebGPU mandates copyTextureToBuffer bytesPerRow be a 256-byte multiple.\nconst READBACK_BYTES_PER_ROW_ALIGN = 256;\n// WebGPU spec-default maxBufferSize (256 MiB), enforced by Dawn\nconst MAX_READBACK_STAGING_BYTES = 256 * 1024 * 1024;\n\n// Fullscreen-triangle blit for readbackScaled() GPU downscale.\n// See .agents/headless-sdk.md § canvas WebGPU context shim.\nconst BLIT_WGSL = /* wgsl */ `\nstruct VSOut {\n @builtin(position) pos: vec4f,\n @location(0) uv: vec2f,\n};\n\n@vertex\nfn vs(@builtin(vertex_index) vertexIndex: u32) -> VSOut {\n var corners = array<vec2f, 3>(\n vec2f(0.0, 0.0),\n vec2f(2.0, 0.0),\n vec2f(0.0, 2.0)\n );\n let xy = corners[vertexIndex];\n var out: VSOut;\n out.pos = vec4f(xy * 2.0 - 1.0, 0.0, 1.0);\n // Clip-space y is up, texture v is down, flip v so the output keeps the\n // source orientation (row 0 = top), matching the direct readback path.\n out.uv = vec2f(xy.x, 1.0 - xy.y);\n return out;\n}\n\n@group(0) @binding(0) var srcTex: texture_2d<f32>;\n@group(0) @binding(1) var srcSampler: sampler;\n\n@fragment\nfn fs(in: VSOut) -> @location(0) vec4f {\n return textureSample(srcTex, srcSampler, in.uv);\n}\n`;\n\ninterface RawFramePixels {\n data: Uint8Array;\n width: number;\n height: number;\n}\n\n// Hand-rolled GPUCanvasContext shim (no swapchain surface, render to an\n// offscreen texture, read back). See .agents/headless-sdk.md § canvas WebGPU context shim.\nconst createHeadlessWebGPUContext = (canvas: HTMLCanvasElement) => {\n let device: GPUDevice | null = null;\n let format: GPUTextureFormat = 'bgra8unorm';\n let configuredUsage: GPUTextureUsageFlags = 0;\n let texture: GPUTexture | null = null;\n let textureWidth = 0;\n let textureHeight = 0;\n let lastFramePixels: Uint8Array | null = null;\n let blitPipeline: GPURenderPipeline | null = null;\n let blitSampler: GPUSampler | null = null;\n let blitTexture: GPUTexture | null = null;\n let blitWidth = 0;\n let blitHeight = 0;\n let stagingBuffer: GPUBuffer | null = null;\n let stagingSize = 0;\n let stagingBusy = false;\n\n // Every caller below runs behind a device check on the public methods.\n const requireDevice = (): GPUDevice => {\n if (!device) {\n throw new Error('[headless] WebGPU canvas context has no device');\n }\n return device;\n };\n\n const destroyTexture = (textureToDestroy: GPUTexture) => {\n try {\n textureToDestroy.destroy();\n } catch {\n console.error('[webgpu]: Failed to destroy texture image');\n }\n };\n\n const ensureTexture = (): GPUTexture | null => {\n if (!device) {\n return null;\n }\n const gpuDevice = device;\n const width = Math.max(1, canvas.width | 0);\n const height = Math.max(1, canvas.height | 0);\n if (texture && textureWidth === width && textureHeight === height) {\n return texture;\n }\n if (texture) {\n destroyTexture(texture);\n }\n textureWidth = width;\n textureHeight = height;\n // three's configured usage plus COPY_SRC (readback), RENDER_ATTACHMENT\n // (render target), and TEXTURE_BINDING (readbackScaled blit sampling).\n const usage =\n (configuredUsage || 0) |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING;\n texture = gpuDevice.createTexture({\n size: { width, height, depthOrArrayLayers: 1 },\n format,\n usage,\n });\n return texture;\n };\n\n const destroyBuffer = (bufferToDestroy: GPUBuffer) => {\n try {\n bufferToDestroy.destroy();\n } catch {\n console.error('[webgpu]: Failed to destroy staging buffer');\n }\n };\n\n const createReadbackBuffer = (sizeInBytes: number): GPUBuffer =>\n requireDevice().createBuffer({\n size: sizeInBytes,\n usage: GPU_BUFFER_USAGE_COPY_DST | GPU_BUFFER_USAGE_MAP_READ,\n });\n\n // Reuse the pooled buffer when free and sized to the band; else a fresh\n // throwaway (pool lifetime owned by configure()/unconfigure()).\n const acquireReadbackBuffer = (\n bandBytes: number,\n ): { buffer: GPUBuffer; release: () => void } => {\n if (stagingBusy) {\n const throwawayBuffer = createReadbackBuffer(bandBytes);\n return {\n buffer: throwawayBuffer,\n release: () => destroyBuffer(throwawayBuffer),\n };\n }\n if (!stagingBuffer || stagingSize !== bandBytes) {\n if (stagingBuffer) {\n destroyBuffer(stagingBuffer);\n }\n stagingBuffer = createReadbackBuffer(bandBytes);\n stagingSize = bandBytes;\n }\n stagingBusy = true;\n return {\n buffer: stagingBuffer,\n release: () => {\n stagingBusy = false;\n },\n };\n };\n\n // Dawn returns the texture's native channel order; the wrapped 2d canvas\n // expects RGBA, so bgra8unorm needs a B/R swizzle.\n const swizzleBgraToRgbaInPlace = (pixels: Uint8Array) => {\n for (let i = 0; i < pixels.length; i += 4) {\n const blue = pixels[i]!;\n pixels[i] = pixels[i + 2]!;\n pixels[i + 2] = blue;\n }\n };\n\n const readPixelsFrom = async (\n sourceTexture: GPUTexture,\n width: number,\n height: number,\n ): Promise<Uint8Array | null> => {\n const gpuDevice = requireDevice();\n const tightRowBytes = width * 4;\n const bytesPerRow =\n Math.ceil(tightRowBytes / READBACK_BYTES_PER_ROW_ALIGN) *\n READBACK_BYTES_PER_ROW_ALIGN;\n // Row-band the copy so no single staging buffer exceeds maxBufferSize\n const rowsPerBand = Math.max(\n 1,\n Math.floor((MAX_READBACK_STAGING_BYTES * 0.95) / bytesPerRow),\n );\n const { buffer: readBuffer, release } = acquireReadbackBuffer(\n bytesPerRow * Math.min(rowsPerBand, height),\n );\n\n const pixels = new Uint8Array(tightRowBytes * height);\n try {\n for (\n let bandStartRow = 0;\n bandStartRow < height;\n bandStartRow += rowsPerBand\n ) {\n const bandHeight = Math.min(rowsPerBand, height - bandStartRow);\n const encoder = gpuDevice.createCommandEncoder();\n encoder.copyTextureToBuffer(\n { texture: sourceTexture, origin: { x: 0, y: bandStartRow, z: 0 } },\n { buffer: readBuffer, bytesPerRow, rowsPerImage: bandHeight },\n { width, height: bandHeight, depthOrArrayLayers: 1 },\n );\n gpuDevice.queue.submit([encoder.finish()]);\n await readBuffer.mapAsync(GPU_MAP_MODE_READ);\n const mappedBytes = new Uint8Array(readBuffer.getMappedRange());\n // Copy tight rows out before unmap invalidates the mapped range.\n for (let rowInBand = 0; rowInBand < bandHeight; rowInBand++) {\n pixels.set(\n mappedBytes.subarray(\n rowInBand * bytesPerRow,\n rowInBand * bytesPerRow + tightRowBytes,\n ),\n (bandStartRow + rowInBand) * tightRowBytes,\n );\n }\n readBuffer.unmap();\n }\n } catch (error: unknown) {\n console.warn('[headless] WebGPU readback failed', error);\n return null;\n } finally {\n release();\n }\n\n if (format === 'bgra8unorm') {\n swizzleBgraToRgbaInPlace(pixels);\n }\n return pixels;\n };\n\n // Reads the current canvas texture into lastFramePixels (sync toDataURL\n // consumes that cache).\n const queueReadback = async (): Promise<void> => {\n if (!device || !texture) {\n return;\n }\n const pixels = await readPixelsFrom(texture, textureWidth, textureHeight);\n if (pixels) {\n lastFramePixels = pixels;\n }\n };\n\n const ensureBlitPipeline = (): {\n pipeline: GPURenderPipeline;\n sampler: GPUSampler;\n } => {\n if (blitPipeline && blitSampler) {\n return { pipeline: blitPipeline, sampler: blitSampler };\n }\n const gpuDevice = requireDevice();\n const shaderModule = gpuDevice.createShaderModule({ code: BLIT_WGSL });\n const pipeline = gpuDevice.createRenderPipeline({\n layout: 'auto',\n vertex: { module: shaderModule, entryPoint: 'vs' },\n fragment: {\n module: shaderModule,\n entryPoint: 'fs',\n targets: [{ format }],\n },\n primitive: { topology: 'triangle-list' },\n });\n const sampler = gpuDevice.createSampler({\n magFilter: 'linear',\n minFilter: 'linear',\n });\n blitPipeline = pipeline;\n blitSampler = sampler;\n return { pipeline, sampler };\n };\n\n const ensureBlitTexture = (width: number, height: number): GPUTexture => {\n if (blitTexture && blitWidth === width && blitHeight === height) {\n return blitTexture;\n }\n if (blitTexture) {\n destroyTexture(blitTexture);\n }\n blitWidth = width;\n blitHeight = height;\n blitTexture = requireDevice().createTexture({\n size: { width, height, depthOrArrayLayers: 1 },\n format,\n usage: GPU_TEXTURE_USAGE_RENDER_ATTACHMENT | GPU_TEXTURE_USAGE_COPY_SRC,\n });\n return blitTexture;\n };\n\n const releaseCanvasTexture = () => {\n if (texture) {\n destroyTexture(texture);\n texture = null;\n }\n };\n\n const releaseBlitResources = () => {\n blitPipeline = null;\n blitSampler = null;\n if (blitTexture) {\n destroyTexture(blitTexture);\n blitTexture = null;\n }\n };\n\n const releaseStagingBuffer = () => {\n if (stagingBuffer && !stagingBusy) {\n destroyBuffer(stagingBuffer);\n }\n stagingBuffer = null;\n stagingSize = 0;\n stagingBusy = false;\n };\n\n const readCanvasPixels = async (\n sourceTexture: GPUTexture,\n ): Promise<RawFramePixels | null> => {\n const pixels = await readPixelsFrom(\n sourceTexture,\n textureWidth,\n textureHeight,\n );\n return pixels\n ? { data: pixels, width: textureWidth, height: textureHeight }\n : null;\n };\n\n const blitAndReadScaled = async (\n sourceTexture: GPUTexture,\n targetWidth: number,\n targetHeight: number,\n ): Promise<RawFramePixels | null> => {\n const gpuDevice = requireDevice();\n const { pipeline, sampler } = ensureBlitPipeline();\n const blitTarget = ensureBlitTexture(targetWidth, targetHeight);\n const bindGroup = gpuDevice.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: sourceTexture.createView() },\n { binding: 1, resource: sampler },\n ],\n });\n const encoder = gpuDevice.createCommandEncoder();\n const renderPass = encoder.beginRenderPass({\n colorAttachments: [\n {\n view: blitTarget.createView(),\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n ],\n });\n renderPass.setPipeline(pipeline);\n renderPass.setBindGroup(0, bindGroup);\n renderPass.draw(3);\n renderPass.end();\n gpuDevice.queue.submit([encoder.finish()]);\n const pixels = await readPixelsFrom(blitTarget, targetWidth, targetHeight);\n return pixels\n ? { data: pixels, width: targetWidth, height: targetHeight }\n : null;\n };\n\n return {\n canvas,\n __isHeadlessWebGPUContext: true,\n configure(configuration: GPUCanvasConfiguration) {\n device = configuration.device;\n format = configuration.format || format;\n configuredUsage = configuration.usage || 0;\n // Pipeline, textures and staging buffer are format and device bound\n releaseCanvasTexture();\n releaseBlitResources();\n releaseStagingBuffer();\n },\n unconfigure() {\n releaseCanvasTexture();\n releaseBlitResources();\n releaseStagingBuffer();\n device = null;\n },\n getCurrentTexture() {\n // No implicit per-frame readback, export paths read back explicitly\n // (see .agents/headless-sdk.md § canvas WebGPU context shim).\n return ensureTexture();\n },\n // Read the current frame back (single copy + mapAsync) and cache it for\n // the sync toDataURL path.\n async flushReadback(): Promise<Uint8Array | null> {\n if (texture) {\n await queueReadback();\n }\n return lastFramePixels;\n },\n // GPU-downscale the current frame to target size and read back only that\n // (full-size fallback when no scaling). Does not touch the toDataURL cache.\n async readbackScaled(\n targetWidth: number,\n targetHeight: number,\n ): Promise<RawFramePixels | null> {\n if (!device || !texture) {\n return null;\n }\n const canvasTexture = texture;\n if (targetWidth >= textureWidth && targetHeight >= textureHeight) {\n return readCanvasPixels(canvasTexture);\n }\n try {\n return await blitAndReadScaled(\n canvasTexture,\n targetWidth,\n targetHeight,\n );\n } catch (error) {\n console.warn(\n '[headless] WebGPU scaled readback failed, falling back to full-size readback',\n error,\n );\n return readCanvasPixels(canvasTexture);\n }\n },\n getCachedPixels(): Uint8Array | null {\n return lastFramePixels;\n },\n getPreferredFormat() {\n return webgpuInstance?.getPreferredCanvasFormat?.() ?? 'bgra8unorm';\n },\n };\n};\n\nexport type WebGPUMockContext = ReturnType<typeof createHeadlessWebGPUContext>;\n\n// Wraps a napi-rs/canvas Canvas so it behaves like an HTMLCanvasElement.\n// Fakes the prototype chain via Proxy getPrototypeOf (GLTFExporter checks instanceof).\n// The 2d context's drawImage is patched to unwrap NAPI_IMAGE symbols.\nconst createCanvasProxy = (\n width: number = 300,\n height: number = 150,\n): HTMLCanvasElement => {\n const napiCanvas = createNapiCanvas(width, height);\n let cachedCtx: CanvasRenderingContext2D | null = null;\n let cachedWebGpuContext: WebGPUMockContext | null = null;\n\n const proxy = new Proxy(napiCanvas as unknown as HTMLCanvasElement, {\n get(target: any, prop: string | symbol) {\n if (prop === NAPI_IMAGE) {\n return target;\n }\n if (prop === 'data') {\n return undefined;\n }\n if (prop === 'style') {\n return target._style ?? (target._style = {});\n }\n if (prop === 'classList') {\n return (\n target._classList ??\n (target._classList = {\n add() {},\n remove() {},\n contains() {\n return false;\n },\n toggle() {},\n })\n );\n }\n if (prop === Symbol.toStringTag) {\n return 'HTMLCanvasElement';\n }\n\n if (prop === 'getContext') {\n return (contextType: string, attrs?: any) => {\n if (contextType === '2d') {\n if (!cachedCtx) {\n cachedCtx = patchContext2d(target.getContext('2d', attrs));\n }\n return cachedCtx;\n }\n if (contextType === 'webgl2' || contextType === 'webgl') {\n // headless-sdk only runs on webGPU\n return null;\n }\n if (contextType === 'webgpu') {\n if (!webgpuInstance) {\n return null;\n }\n if (!cachedWebGpuContext) {\n cachedWebGpuContext = createHeadlessWebGPUContext(proxy);\n }\n return cachedWebGpuContext;\n }\n return target.getContext(contextType, attrs);\n };\n }\n\n if (prop === 'addEventListener' || prop === 'removeEventListener') {\n return () => {};\n }\n\n if (prop === 'getBoundingClientRect') {\n return () => ({\n x: 0,\n y: 0,\n width: target.width,\n height: target.height,\n top: 0,\n left: 0,\n bottom: target.height,\n right: target.width,\n });\n }\n\n // WebGPU: blit the last cached frame into the 2d canvas (lags one frame\n // unless the caller flushed the readback first, as the image renderer does).\n if (prop === 'toDataURL' && cachedWebGpuContext) {\n const webGpuContext = cachedWebGpuContext;\n return (mimeType?: string, quality?: number) => {\n const pixels = webGpuContext.getCachedPixels();\n if (pixels) {\n target\n .getContext('2d')\n .putImageData(\n new NapiImageData(\n new Uint8ClampedArray(pixels.buffer),\n target.width,\n target.height,\n ),\n 0,\n 0,\n );\n }\n return target.toDataURL(mimeType, quality);\n };\n }\n const value = target[prop];\n return typeof value === 'function' ? value.bind(target) : value;\n },\n\n set(target: any, prop: string | symbol, value: any) {\n target[prop] = value;\n return true;\n },\n\n getPrototypeOf() {\n return HTMLCanvasElement.prototype;\n },\n });\n\n return proxy;\n};\n\n// Keeps texture downloads cancellable; see .agents/headless-sdk/debugging.md,\n// item 14.\nconst IMAGE_FETCH_TIMEOUT_MS = 30_000;\nconst IMAGE_FETCH_ATTEMPTS = 3;\n\nconst fetchImageBytes = async (url: string): Promise<ArrayBuffer> => {\n let lastError: unknown;\n for (let attempt = 1; attempt <= IMAGE_FETCH_ATTEMPTS; attempt++) {\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(IMAGE_FETCH_TIMEOUT_MS),\n });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} for ${url}`);\n }\n return await response.arrayBuffer();\n } catch (error) {\n lastError = error;\n console.warn(\n `image request attempt ${attempt}/${IMAGE_FETCH_ATTEMPTS} failed for ${url}:`,\n error instanceof Error ? error.message : error,\n );\n }\n }\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\n};\n\n// Creates a happy-dom HTMLImageElement backed by a napi-rs/canvas Image so that\n// images are actually decoded and canvas drawImage() works correctly.\nconst createNapiImageElement = (): HTMLImageElement => {\n const el = origCreateElementNS(\n 'http://www.w3.org/1999/xhtml',\n 'img',\n ) as HTMLImageElement;\n const napiImg = new NapiImage();\n\n (el as any)[NAPI_IMAGE] = napiImg;\n\n let currentSrc = '';\n Object.defineProperty(el, 'src', {\n get() {\n return currentSrc;\n },\n set(url: string) {\n currentSrc = url;\n // napi-rs/canvas Image cannot fetch blob: URLs (created by\n // URL.createObjectURL used heavily by GLTFLoader for embedded\n // textures). Resolve them ourselves via fetch (Node ≥18 understands\n // its own blob URL registry) and feed the bytes in as a Buffer.\n const isFetchable =\n typeof url === 'string' &&\n (url.startsWith('blob:') ||\n url.startsWith('http:') ||\n url.startsWith('https:'));\n if (isFetchable) {\n const load = url.startsWith('blob:')\n ? fetch(url).then((r) => r.arrayBuffer())\n : fetchImageBytes(url);\n load\n .then((ab) => {\n // Guard against a later src reassignment racing this resolution.\n if (currentSrc !== url) {\n return;\n }\n napiImg.src = Buffer.from(ab);\n })\n .catch((err) => {\n if (currentSrc !== url) {\n return;\n }\n const error = err instanceof Error ? err : new Error(String(err));\n el.dispatchEvent(\n new ErrorEvent('error', { error, message: error.message }),\n );\n });\n return;\n }\n napiImg.src = url;\n },\n configurable: true,\n });\n\n napiImg.onload = () => {\n Object.defineProperty(el, 'width', {\n value: napiImg.width,\n writable: true,\n configurable: true,\n });\n Object.defineProperty(el, 'height', {\n value: napiImg.height,\n writable: true,\n configurable: true,\n });\n Object.defineProperty(el, 'naturalWidth', {\n value: napiImg.naturalWidth,\n configurable: true,\n });\n Object.defineProperty(el, 'naturalHeight', {\n value: napiImg.naturalHeight,\n configurable: true,\n });\n Object.defineProperty(el, 'complete', { value: true, configurable: true });\n el.dispatchEvent(new Event('load'));\n };\n\n napiImg.onerror = (err: Error) => {\n el.dispatchEvent(\n new ErrorEvent('error', { error: err, message: err?.message }),\n );\n };\n\n return el;\n};\n\ndocument.createElement = (\n tagName: string,\n options?: ElementCreationOptions,\n) => {\n if (tagName.toLowerCase() === 'canvas') {\n return createCanvasProxy();\n }\n return origCreateElement(tagName, options);\n};\n\ndocument.createElementNS = (\n namespaceURI: string | null,\n qualifiedName: string,\n options?: ElementCreationOptions,\n) => {\n const tag = qualifiedName.toLowerCase();\n if (tag === 'canvas') {\n return createCanvasProxy();\n }\n if (tag === 'img') {\n return createNapiImageElement();\n }\n return origCreateElementNS(namespaceURI, qualifiedName, options);\n};\n"],"mappings":"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"}
|