@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.
Files changed (87) hide show
  1. package/lib/ConfiguratorKernel.wasm +0 -0
  2. package/lib/{GaussianBlurNode-DEczNsyD.mjs → GaussianBlurNode-Bjszve7N.mjs} +15 -15
  3. package/lib/{GaussianBlurNode-DEczNsyD.mjs.map → GaussianBlurNode-Bjszve7N.mjs.map} +1 -1
  4. package/lib/RoomleCore.wasm +0 -0
  5. package/lib/RoomleToolsCore.wasm +0 -0
  6. package/lib/{api-B6sLiuiL.mjs → api-C0UElaCW.mjs} +2 -2
  7. package/lib/{api-B6sLiuiL.mjs.map → api-C0UElaCW.mjs.map} +1 -1
  8. package/lib/asset-loader.worker-eqHzNAwa.mjs.map +1 -1
  9. package/lib/{banana-for-scale-C-grIlTK.mjs → banana-for-scale-DGYmxeBG.mjs} +3 -3
  10. package/lib/{banana-for-scale-C-grIlTK.mjs.map → banana-for-scale-DGYmxeBG.mjs.map} +1 -1
  11. package/lib/budgeteer.sw-BUMElkO1.mjs.map +1 -1
  12. package/lib/{common-utils-6T8eGlhX.mjs → common-utils-CyQUubmw.mjs} +29 -15
  13. package/lib/{common-utils-6T8eGlhX.mjs.map → common-utils-CyQUubmw.mjs.map} +1 -1
  14. package/lib/{component-dimensioning-DJuokZnv.mjs → component-dimensioning--4sX2AgY.mjs} +4 -4
  15. package/lib/{component-dimensioning-DJuokZnv.mjs.map → component-dimensioning--4sX2AgY.mjs.map} +1 -1
  16. package/lib/{component-raycast-helper-SZg14d7A.mjs → component-raycast-helper-CskJedpv.mjs} +3 -3
  17. package/lib/{component-raycast-helper-SZg14d7A.mjs.map → component-raycast-helper-CskJedpv.mjs.map} +1 -1
  18. package/lib/configurator-CjFo24FH.mjs +2 -0
  19. package/lib/{configurator-Cbof6AET.mjs → configurator-vxRFxJ-B.mjs} +4 -4
  20. package/lib/{configurator-Cbof6AET.mjs.map → configurator-vxRFxJ-B.mjs.map} +1 -1
  21. package/lib/{decorate-CX1ZGuFY.mjs → decorate-CjaqqbUP.mjs} +12 -9
  22. package/lib/decorate-CjaqqbUP.mjs.map +1 -0
  23. package/lib/dimensioning-helper-0s61LK9R.mjs +2 -0
  24. package/lib/{dimensioning-helper-BwvR76_I.mjs → dimensioning-helper-Cgao7A18.mjs} +2 -2
  25. package/lib/{dimensioning-helper-BwvR76_I.mjs.map → dimensioning-helper-Cgao7A18.mjs.map} +1 -1
  26. package/lib/{glb-viewer-DmVh1uJg.mjs → glb-viewer-B-r0E1aa.mjs} +6 -6
  27. package/lib/{glb-viewer-DmVh1uJg.mjs.map → glb-viewer-B-r0E1aa.mjs.map} +1 -1
  28. package/lib/glb-viewer-BnJkmakv.mjs +2 -0
  29. package/lib/{highlight-coordinator-Qonmfsu1.mjs → highlight-coordinator-CR5rcFh_.mjs} +2 -2
  30. package/lib/{highlight-coordinator-Qonmfsu1.mjs.map → highlight-coordinator-CR5rcFh_.mjs.map} +1 -1
  31. package/lib/{homag-intelligence-CzD_RMQo.mjs → homag-intelligence-DHTCBB64.mjs} +8 -5
  32. package/lib/{homag-intelligence-CzD_RMQo.mjs.map → homag-intelligence-DHTCBB64.mjs.map} +1 -1
  33. package/lib/{imos-ix-poc-export-helper-Q6-OXziY.mjs → imos-ix-poc-export-helper-DRQK_p2h.mjs} +2 -2
  34. package/lib/{imos-ix-poc-export-helper-Q6-OXziY.mjs.map → imos-ix-poc-export-helper-DRQK_p2h.mjs.map} +1 -1
  35. package/lib/{material-viewer-BkSh-aG7.mjs → material-viewer-ZlNDhA8D.mjs} +6 -6
  36. package/lib/{material-viewer-BkSh-aG7.mjs.map → material-viewer-ZlNDhA8D.mjs.map} +1 -1
  37. package/lib/{packages-BGVMQMZK.mjs → packages-C9J0u-cc.mjs} +5 -5
  38. package/lib/{packages-BGVMQMZK.mjs.map → packages-C9J0u-cc.mjs.map} +1 -1
  39. package/lib/planner-C-5Mg-Lv.mjs +2 -0
  40. package/lib/{planner-DFa8uJOF.mjs → planner-ClY-VUWt.mjs} +3 -3
  41. package/lib/{planner-DFa8uJOF.mjs.map → planner-ClY-VUWt.mjs.map} +1 -1
  42. package/lib/{plugin-system-CqXT37-v.mjs → plugin-system-vlnG8j2T.mjs} +3 -3
  43. package/lib/{plugin-system-CqXT37-v.mjs.map → plugin-system-vlnG8j2T.mjs.map} +1 -1
  44. package/lib/{roomle-headless-setup-7xnQlZl3.mjs → roomle-headless-setup-DbO_rLjK.mjs} +54 -40
  45. package/lib/roomle-headless-setup-DbO_rLjK.mjs.map +1 -0
  46. package/lib/roomle-headless.d.ts +125 -115
  47. package/lib/roomle-headless.js +289 -358
  48. package/lib/roomle-headless.js.map +1 -1
  49. package/lib/roomle-renderer-FUqNfNIf.mjs.map +1 -1
  50. package/lib/{roomle-sdk-B73VmWod.mjs → roomle-sdk-BpCPIwDm.mjs} +2447 -2306
  51. package/lib/roomle-sdk-BpCPIwDm.mjs.map +1 -0
  52. package/lib/roomle-sdk.d.ts +79 -4
  53. package/lib/roomle-sdk.js +7 -7
  54. package/lib/{roomle-webgpu-renderer-Dzuy_Y39.mjs → roomle-webgpu-renderer-Lt55gNj5.mjs} +370 -303
  55. package/lib/roomle-webgpu-renderer-Lt55gNj5.mjs.map +1 -0
  56. package/lib/{scene-renderer-DR7EFd-8.mjs → scene-renderer-CLkhNnnv.mjs} +5 -5
  57. package/lib/{scene-renderer-DR7EFd-8.mjs.map → scene-renderer-CLkhNnnv.mjs.map} +1 -1
  58. package/lib/{script-loader-BlsGBrYo.mjs → script-loader-9GrUxzSB.mjs} +3 -3
  59. package/lib/{script-loader-BlsGBrYo.mjs.map → script-loader-9GrUxzSB.mjs.map} +1 -1
  60. package/lib/{shading-settings-Bnt9v9xJ.mjs → shading-settings-CRNmMpcn.mjs} +2 -2
  61. package/lib/{shading-settings-Bnt9v9xJ.mjs.map → shading-settings-CRNmMpcn.mjs.map} +1 -1
  62. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/package.json +1 -1
  63. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/ConfiguratorKernel.wasm +0 -0
  64. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.wasm +0 -0
  65. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleToolsCore.wasm +0 -0
  66. package/lib/{stats-helper-vEwFkDIt.mjs → stats-helper-D9l8soWd.mjs} +3 -3
  67. package/lib/{stats-helper-vEwFkDIt.mjs.map → stats-helper-D9l8soWd.mjs.map} +1 -1
  68. package/lib/three.tsl-BnL9nfJa.mjs +2 -0
  69. package/lib/{three.tsl-BElp7_oF.mjs → three.tsl-Dew9p5yF.mjs} +46 -48
  70. package/lib/{three.tsl-BElp7_oF.mjs.map → three.tsl-Dew9p5yF.mjs.map} +1 -1
  71. package/lib/{threejs-utils-C9zED_Tu.mjs → threejs-utils-CKV1QNU9.mjs} +4 -3
  72. package/lib/threejs-utils-CKV1QNU9.mjs.map +1 -0
  73. package/lib/{tools-core-DKYMilYC.mjs → tools-core-CKaB3WsP.mjs} +3 -3
  74. package/lib/{tools-core-DKYMilYC.mjs.map → tools-core-CKaB3WsP.mjs.map} +1 -1
  75. package/lib/{webgpu-BMwlJflc.mjs → webgpu-B0rxiqW-.mjs} +313 -313
  76. package/lib/{webgpu-BMwlJflc.mjs.map → webgpu-B0rxiqW-.mjs.map} +1 -1
  77. package/package.json +2 -2
  78. package/lib/configurator-BFd5022u.mjs +0 -2
  79. package/lib/decorate-CX1ZGuFY.mjs.map +0 -1
  80. package/lib/dimensioning-helper-yMfkA1IY.mjs +0 -2
  81. package/lib/glb-viewer-DlH5_aTU.mjs +0 -2
  82. package/lib/planner-CSKuhBke.mjs +0 -2
  83. package/lib/roomle-headless-setup-7xnQlZl3.mjs.map +0 -1
  84. package/lib/roomle-sdk-B73VmWod.mjs.map +0 -1
  85. package/lib/roomle-webgpu-renderer-Dzuy_Y39.mjs.map +0 -1
  86. package/lib/three.tsl-BtDRDR0q.mjs +0 -2
  87. 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-B73VmWod.mjs";
2
- import { t as h } from "./script-loader-BlsGBrYo.mjs";
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-DFa8uJOF.mjs.map
44
+ //# sourceMappingURL=planner-ClY-VUWt.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-DFa8uJOF.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
+ {"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-CX1ZGuFY.mjs";
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-C-grIlTK.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));
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-CqXT37-v.mjs.map
55
+ //# sourceMappingURL=plugin-system-vlnG8j2T.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-system-CqXT37-v.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"}
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, M = 8192, N = 2147483647, P = (e) => {
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 ? N : r;
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
- }, F = (e) => {
246
+ }, P = (e) => {
247
247
  let { requiredLimits: t, ...n } = e ?? {};
248
248
  return t && Object.keys(t).length > 0 ? { ...e } : n;
249
- }, I = (e) => {
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
- }, L = (e) => {
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, I(n)), n;
261
+ return n.copyTextureToTexture = (e, t, n) => r(e, t, F(n)), n;
262
262
  };
263
- }, R = (e, t) => {
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
- }, z = (e) => {
267
- let t = e.requestDevice.bind(e), n = e.limits?.maxTextureDimension2D, r = typeof n == "number" && n > M, i = (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 = P(e);
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 = await i(r ? {
280
+ let t = r ? {
278
281
  ...e,
279
282
  requiredLimits: {
280
283
  ...e?.requiredLimits ?? {},
281
284
  maxTextureDimension2D: n
282
285
  }
283
- } : F(e));
284
- if (!t) throw Error("[headless] WebGPU adapter returned no device (adapter already invalid)");
285
- return R(t, n), L(t), c(t, {
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
- }), t;
291
+ }), a;
289
292
  };
290
- }, B = (e) => {
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" && z(r), r;
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
- }, V = (e) => {
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
- }, H = async (e) => {
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
- }, U = null;
327
+ }, W = null;
325
328
  try {
326
329
  let e = await import("bun-webgpu");
327
- U = e.createGPUInstance(), e.globals(), U.getPreferredCanvasFormat = () => "rgba8unorm", typeof U.requestAdapter == "function" && B(U), V(U), console.log("[headless] Using bun-webgpu (Dawn FFI) for real WebGPU rendering"), await H(U);
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 W = 1, G = 16, K = 8, q = 1, J = 1, Y = 256, X = 256 * 1024 * 1024, Z = "\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", Q = (e) => {
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: K | q
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 / Y) * Y, s = Math.max(1, Math.floor(X * .95 / o)), { buffer: c, release: l } = x(o * Math.min(s, r)), u = new Uint8Array(a * r);
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(J);
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: Z }), r = e.createRenderPipeline({
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: G | W
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 U?.getPreferredCanvasFormat?.() ?? "bgra8unorm";
526
+ return W?.getPreferredCanvasFormat?.() ?? "bgra8unorm";
524
527
  }
525
528
  };
526
- }, $ = (e = 300, t = 150) => {
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" ? U ? (i ||= Q(a), i) : null : e.getContext(t, n);
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
- }, ee = () => {
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
- let n = t instanceof Error ? t : Error(String(t));
597
+ if (n !== r) return;
598
+ let i = t instanceof Error ? t : Error(String(t));
585
599
  e.dispatchEvent(new ErrorEvent("error", {
586
- error: n,
587
- message: n.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" ? $() : D(e, t), document.createElementNS = (e, t, n) => {
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" ? $() : r === "img" ? ee() : O(e, t, n);
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-7xnQlZl3.mjs.map
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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"}