@roomle/web-sdk 3.7.0-alpha.2 → 3.7.0-alpha.4

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 (130) hide show
  1. package/lib/{BufferGeometry-C696z6r3.mjs → BufferGeometry-BzmfTBQt.mjs} +1 -1
  2. package/lib/{BufferGeometry-C696z6r3.mjs.map → BufferGeometry-BzmfTBQt.mjs.map} +1 -1
  3. package/lib/ConfiguratorKernel.wasm +0 -0
  4. package/lib/{GLTFExporter-AfQIvZAD.mjs → GLTFExporter-CyhgWPq0.mjs} +2 -2
  5. package/lib/{GLTFExporter-AfQIvZAD.mjs.map → GLTFExporter-CyhgWPq0.mjs.map} +1 -1
  6. package/lib/{PointLightHelper-wVSmrAnD.mjs → PointLightHelper-DwIXACyT.mjs} +2 -2
  7. package/lib/{PointLightHelper-wVSmrAnD.mjs.map → PointLightHelper-DwIXACyT.mjs.map} +1 -1
  8. package/lib/RoomleCore.js +4 -4
  9. package/lib/RoomleCore.wasm +0 -0
  10. package/lib/RoomleToolsCore.wasm +0 -0
  11. package/lib/{SpotLightHelper-C7J95t4f.mjs → SpotLightHelper-CfLHM7LU.mjs} +2 -2
  12. package/lib/{SpotLightHelper-C7J95t4f.mjs.map → SpotLightHelper-CfLHM7LU.mjs.map} +1 -1
  13. package/lib/{USDZExporter-BBk0APeK.mjs → USDZExporter-kmxcTvnQ.mjs} +2 -2
  14. package/lib/{USDZExporter-BBk0APeK.mjs.map → USDZExporter-kmxcTvnQ.mjs.map} +1 -1
  15. package/lib/{api-oYzhcs_W.mjs → api-X1dDTDvL.mjs} +2 -2
  16. package/lib/{api-oYzhcs_W.mjs.map → api-X1dDTDvL.mjs.map} +1 -1
  17. package/lib/{banana-for-scale-D8t2dmc7.mjs → banana-for-scale-Bpf8RfLi.mjs} +4 -4
  18. package/lib/{banana-for-scale-D8t2dmc7.mjs.map → banana-for-scale-Bpf8RfLi.mjs.map} +1 -1
  19. package/lib/budgeteer.sw-CQWYbQSc.mjs.map +1 -1
  20. package/lib/budgeteer.sw.js +1 -1
  21. package/lib/{common-utils-qErzZAiR.mjs → common-utils-DMI8Yuhe.mjs} +5 -3
  22. package/lib/common-utils-DMI8Yuhe.mjs.map +1 -0
  23. package/lib/{component-dimensioning-DlB7-9Om.mjs → component-dimensioning-MtS9xiY-.mjs} +15 -15
  24. package/lib/{component-dimensioning-DlB7-9Om.mjs.map → component-dimensioning-MtS9xiY-.mjs.map} +1 -1
  25. package/lib/{component-raycast-helper-C6ptEb0K.mjs → component-raycast-helper-C1qWqpRH.mjs} +13 -9
  26. package/lib/component-raycast-helper-C1qWqpRH.mjs.map +1 -0
  27. package/lib/configurator-C5t3clCx.mjs +2 -0
  28. package/lib/{configurator-CRMunIq7.mjs → configurator-Cg1a9XSL.mjs} +4 -4
  29. package/lib/{configurator-CRMunIq7.mjs.map → configurator-Cg1a9XSL.mjs.map} +1 -1
  30. package/lib/{continuous-drawing-helper-BwulJHKj.mjs → continuous-drawing-helper-CQx5Sbns.mjs} +3 -3
  31. package/lib/{continuous-drawing-helper-BwulJHKj.mjs.map → continuous-drawing-helper-CQx5Sbns.mjs.map} +1 -1
  32. package/lib/{dat.gui.module-CZHqOVGq.mjs → dat.gui.module-CZ-DIWHM.mjs} +1 -1
  33. package/lib/{dat.gui.module-CZHqOVGq.mjs.map → dat.gui.module-CZ-DIWHM.mjs.map} +1 -1
  34. package/lib/{decorate-BAtqSPNS.mjs → decorate-Bck1_lG8.mjs} +1 -1
  35. package/lib/{decorate-BAtqSPNS.mjs.map → decorate-Bck1_lG8.mjs.map} +1 -1
  36. package/lib/dimensioning-helper-Bfe0fImX.mjs +2 -0
  37. package/lib/{dimensioning-helper--Y0Y-Wr1.mjs → dimensioning-helper-GPn7Z8GE.mjs} +7 -7
  38. package/lib/{dimensioning-helper--Y0Y-Wr1.mjs.map → dimensioning-helper-GPn7Z8GE.mjs.map} +1 -1
  39. package/lib/glb-viewer-DIEpkrvY.mjs +2 -0
  40. package/lib/{glb-viewer-CXEoIw1b.mjs → glb-viewer-tgKOPCaI.mjs} +44 -45
  41. package/lib/glb-viewer-tgKOPCaI.mjs.map +1 -0
  42. package/lib/highlight-coordinator-DRHeEU-E.mjs +116 -0
  43. package/lib/highlight-coordinator-DRHeEU-E.mjs.map +1 -0
  44. package/lib/{homag-intelligence-gb9MqBrz.mjs → homag-intelligence-D5mCTWgG.mjs} +19 -11
  45. package/lib/homag-intelligence-D5mCTWgG.mjs.map +1 -0
  46. package/lib/{imos-ix-poc-export-helper-CW7QZhhn.mjs → imos-ix-poc-export-helper-BKFs_Yhm.mjs} +5 -5
  47. package/lib/{imos-ix-poc-export-helper-CW7QZhhn.mjs.map → imos-ix-poc-export-helper-BKFs_Yhm.mjs.map} +1 -1
  48. package/lib/kernel-C7YDLxq8.mjs.map +1 -1
  49. package/lib/{kernel-utils-DCnHzW4n.mjs → kernel-utils-B80amC-l.mjs} +2 -2
  50. package/lib/{kernel-utils-DCnHzW4n.mjs.map → kernel-utils-B80amC-l.mjs.map} +1 -1
  51. package/lib/{layer-CFAr2mK_.mjs → layer-BfckfWZz.mjs} +1 -1
  52. package/lib/{layer-CFAr2mK_.mjs.map → layer-BfckfWZz.mjs.map} +1 -1
  53. package/lib/{main-BJZ9-cDk.mjs → main-CJ5TNhBt.mjs} +2518 -2554
  54. package/lib/main-CJ5TNhBt.mjs.map +1 -0
  55. package/lib/{material-viewer-D8Nmpwg0.mjs → material-viewer-DCqZzMZN.mjs} +40 -35
  56. package/lib/material-viewer-DCqZzMZN.mjs.map +1 -0
  57. package/lib/packages-DuOz6rk6.mjs +4 -0
  58. package/lib/{planner-5VarJrpy.mjs → planner-CSboZram.mjs} +3 -3
  59. package/lib/{planner-5VarJrpy.mjs.map → planner-CSboZram.mjs.map} +1 -1
  60. package/lib/planner-CWPqJktz.mjs +2 -0
  61. package/lib/{plugin-system-DInww4H_.mjs → plugin-system-DD0Z9Jvt.mjs} +3 -3
  62. package/lib/{plugin-system-DInww4H_.mjs.map → plugin-system-DD0Z9Jvt.mjs.map} +1 -1
  63. package/lib/{roomle-headless-setup-LoBO7UJe.mjs → roomle-headless-setup-nsoGENQV.mjs} +1 -1
  64. package/lib/{roomle-headless-setup-LoBO7UJe.mjs.map → roomle-headless-setup-nsoGENQV.mjs.map} +1 -1
  65. package/lib/roomle-headless.d.ts +252 -106
  66. package/lib/roomle-headless.js +20 -17
  67. package/lib/roomle-headless.js.map +1 -1
  68. package/lib/{roomle-renderer-DVlJsHYn.mjs → roomle-renderer-BEJNPCKx.mjs} +2 -2
  69. package/lib/roomle-renderer-BEJNPCKx.mjs.map +1 -0
  70. package/lib/roomle-sdk.d.ts +252 -106
  71. package/lib/roomle-sdk.js +6 -6
  72. package/lib/roomle-webgpu-renderer-D5flithq.mjs +1502 -0
  73. package/lib/roomle-webgpu-renderer-D5flithq.mjs.map +1 -0
  74. package/lib/{scene-renderer-BHZrQYAH.mjs → scene-renderer-Dm1kij1z.mjs} +26 -26
  75. package/lib/scene-renderer-Dm1kij1z.mjs.map +1 -0
  76. package/lib/{script-loader-gpkcl1h-.mjs → script-loader-DqaDm1FG.mjs} +3 -3
  77. package/lib/{script-loader-gpkcl1h-.mjs.map → script-loader-DqaDm1FG.mjs.map} +1 -1
  78. package/lib/static/packages/workers/generated/budgeteer.sw.js +1 -1
  79. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/package.json +1 -1
  80. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.d.ts +4 -4
  81. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.js +7 -7
  82. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.js.map +1 -1
  83. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCoreInterface.d.ts +28 -8
  84. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorUtils.js +27 -11
  85. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorUtils.js.map +1 -1
  86. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.d.ts +1 -1
  87. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.js +1 -1
  88. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.js.map +1 -1
  89. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreInterface.d.ts +37 -2
  90. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreInterface.js +6 -1
  91. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreInterface.js.map +1 -1
  92. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/loader/planElementManager.d.ts +4 -0
  93. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/loader/planElementManager.js +16 -1
  94. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/loader/planElementManager.js.map +1 -1
  95. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/ConfiguratorKernel.wasm +0 -0
  96. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.js +4 -4
  97. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.wasm +0 -0
  98. package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleToolsCore.wasm +0 -0
  99. package/lib/{stats-helper-Cv5SoEWT.mjs → stats-helper-D7a7oxnj.mjs} +3 -3
  100. package/lib/{stats-helper-Cv5SoEWT.mjs.map → stats-helper-D7a7oxnj.mjs.map} +1 -1
  101. package/lib/{three.core-mM-jZdgg.mjs → three.core-BmQnspOL.mjs} +819 -816
  102. package/lib/{three.core-mM-jZdgg.mjs.map → three.core-BmQnspOL.mjs.map} +1 -1
  103. package/lib/{three.module-Bmy3sVQ-.mjs → three.module-DkrZwaid.mjs} +455 -455
  104. package/lib/{three.module-Bmy3sVQ-.mjs.map → three.module-DkrZwaid.mjs.map} +1 -1
  105. package/lib/{three.webgpu-BbVYfCDp.mjs → three.webgpu-DLZjhIYv.mjs} +1517 -1517
  106. package/lib/{three.webgpu-BbVYfCDp.mjs.map → three.webgpu-DLZjhIYv.mjs.map} +1 -1
  107. package/lib/three.webgpu-RkQxSIwG.mjs +3 -0
  108. package/lib/{threejs-utils-Bq4pVWBA.mjs → threejs-utils-CrK_gp1x.mjs} +67 -63
  109. package/lib/threejs-utils-CrK_gp1x.mjs.map +1 -0
  110. package/lib/{tools-core-DqnhFefF.mjs → tools-core-CZWgXTFV.mjs} +3 -3
  111. package/lib/{tools-core-DqnhFefF.mjs.map → tools-core-CZWgXTFV.mjs.map} +1 -1
  112. package/package.json +1 -1
  113. package/lib/common-utils-qErzZAiR.mjs.map +0 -1
  114. package/lib/component-raycast-helper-C6ptEb0K.mjs.map +0 -1
  115. package/lib/component-raycast-helper-LrhRpeDD.mjs +0 -2
  116. package/lib/configurator-DqiW717d.mjs +0 -2
  117. package/lib/dimensioning-helper-BpUreWo2.mjs +0 -2
  118. package/lib/glb-viewer-CXEoIw1b.mjs.map +0 -1
  119. package/lib/glb-viewer-IDXgmONx.mjs +0 -2
  120. package/lib/homag-intelligence-gb9MqBrz.mjs.map +0 -1
  121. package/lib/main-BJZ9-cDk.mjs.map +0 -1
  122. package/lib/material-viewer-D8Nmpwg0.mjs.map +0 -1
  123. package/lib/packages-Uv53SHfb.mjs +0 -4
  124. package/lib/planner-DJcn-iih.mjs +0 -2
  125. package/lib/roomle-renderer-DVlJsHYn.mjs.map +0 -1
  126. package/lib/roomle-webgpu-renderer-CVxBRv6o.mjs +0 -217
  127. package/lib/roomle-webgpu-renderer-CVxBRv6o.mjs.map +0 -1
  128. package/lib/scene-renderer-BHZrQYAH.mjs.map +0 -1
  129. package/lib/three.webgpu-Bnp8Whu8.mjs +0 -3
  130. package/lib/threejs-utils-Bq4pVWBA.mjs.map +0 -1
@@ -1,13 +1,13 @@
1
1
  import { i as e, t } from "./kernel-C7YDLxq8.mjs";
2
- import { bi as n } from "./three.core-mM-jZdgg.mjs";
3
- import { $ as r, A as i, B as a, D as o, E as s, G as c, H as l, M as u, N as d, P as f, R as p, U as m, V as h, _ as g, a as _, at as v, c as y, ct as b, et as x, g as S, i as C, j as w, n as T, ot as E, rt as D, s as O, tt as k, v as A, y as j, z as M } from "./main-BJZ9-cDk.mjs";
4
- import { n as N } from "./script-loader-gpkcl1h-.mjs";
5
- import { t as P } from "./configurator-CRMunIq7.mjs";
6
- import { t as F } from "./planner-5VarJrpy.mjs";
7
- import { n as I, t as L } from "./glb-viewer-CXEoIw1b.mjs";
8
- import { t as R } from "./api-oYzhcs_W.mjs";
9
- import "./packages-Uv53SHfb.mjs";
10
- import "./roomle-headless-setup-LoBO7UJe.mjs";
2
+ import { bi as n } from "./three.core-BmQnspOL.mjs";
3
+ import { $ as r, A as i, B as a, D as o, E as s, G as c, H as l, M as u, N as d, P as f, R as p, U as m, V as h, _ as g, a as _, at as v, c as y, ct as b, et as x, g as S, i as C, j as w, n as T, ot as E, rt as D, s as O, tt as k, v as A, y as j, z as M } from "./main-CJ5TNhBt.mjs";
4
+ import { n as N } from "./script-loader-DqaDm1FG.mjs";
5
+ import { t as P } from "./configurator-Cg1a9XSL.mjs";
6
+ import { t as F } from "./planner-CSboZram.mjs";
7
+ import { n as I, t as L } from "./glb-viewer-tgKOPCaI.mjs";
8
+ import { t as R } from "./api-X1dDTDvL.mjs";
9
+ import "./packages-DuOz6rk6.mjs";
10
+ import "./roomle-headless-setup-nsoGENQV.mjs";
11
11
  import { createRequire as z } from "module";
12
12
  //#region packages/headless-core/src/headless-script-loader.ts
13
13
  var B = z(import.meta.url), V = {}, H = [
@@ -245,21 +245,24 @@ var B = z(import.meta.url), V = {}, H = [
245
245
  this._ensureInitialized();
246
246
  let n = this._configurator.getSceneManager(), r = t === "glb" ? await n.createExportGLB() : await n.createUSDZExport();
247
247
  if (!r) throw Error(`${t.toUpperCase()} export produced no data`);
248
- return e && (await import("fs")).writeFileSync(e, Buffer.from(r)), { buffer: r instanceof ArrayBuffer ? r : r.buffer };
248
+ let i = r instanceof ArrayBuffer ? r : r.buffer;
249
+ return e && (await import("fs")).writeFileSync(e, Buffer.from(i)), { buffer: i };
249
250
  }
250
251
  async exportScreenshot(e, t = {}) {
251
252
  this._ensureInitialized();
252
- let n = t.quality ?? 1, r = t.ssaa ?? 2, i = this._configurator.getSceneManager(), a, o;
253
+ let n = t.quality ?? 1, r = t.ssaa ?? 2, i = this._configurator.getSceneManager(), a = i.getRenderer();
254
+ if (!a) throw Error("HeadlessRoomleSdk: renderer is not available");
255
+ let o, s;
253
256
  if (r > 1) {
254
- let e = i.getRenderer(), t = i.getRoomleRenderer(), n = e.domElement;
255
- a = n.width, o = n.height, t?.setSize(a * r, o * r);
257
+ let e = i.getRoomleRenderer(), t = a.domElement;
258
+ o = t.width, s = t.height, e?.setSize(o * r, s * r);
256
259
  }
257
- let s = await i.exportCanvasScreenshot(n);
258
- if (r > 1 && a && o && (i.getRoomleRenderer()?.setSize(a, o), s = await this._ssaaDownscale(s, a, o)), e) {
259
- let t = await import("fs"), n = s.replace(/^data:image\/\w+;base64,/, "");
260
+ let c = await i.exportCanvasScreenshot(n);
261
+ if (r > 1 && o && s && (i.getRoomleRenderer()?.setSize(o, s), c = await this._ssaaDownscale(c, o, s)), e) {
262
+ let t = await import("fs"), n = c.replace(/^data:image\/\w+;base64,/, "");
260
263
  t.writeFileSync(e, Buffer.from(n, "base64"));
261
264
  }
262
- return { dataUrl: s };
265
+ return { dataUrl: c };
263
266
  }
264
267
  async exportPerspectiveImage(e, t = {}) {
265
268
  this._ensureInitialized();
@@ -1 +1 @@
1
- {"version":3,"file":"roomle-headless.js","names":[],"sources":["../../packages/headless-core/src/headless-script-loader.ts","../../packages/headless-core/src/stubs.ts","../../packages/headless-core/src/headless-dom-helper.ts","../../packages/headless-core/src/headless-data-syncer.ts","../../packages/headless-core/src/headless-sdk.ts"],"sourcesContent":["/**\n * Replaces the browser ScriptLoader for headless mode.\n * Instead of injecting <script> tags, directly imports the Emscripten JS modules.\n */\nimport { createRequire } from 'module';\nimport type { Context } from '../../common-core/src/di/context';\nimport { getHeadlessWasmPath } from '../../common-core/src/static-files/roomle-core';\n\n// createRequire is needed because the Emscripten kernel files are CommonJS\n// and must be loaded synchronously\nconst _require = createRequire(import.meta.url);\n\nlet _idCache: { [key: string]: boolean } = {};\n\n// Maps a .wasm filename found in the Emscripten factory's source to its global name.\n// Each Emscripten factory references its own .wasm file (e.g. ConfiguratorKernel.wasm).\nconst WASM_TO_GLOBAL: Array<\n [wasmFile: string, globalName: string, modulePath: string]\n> = [\n [\n 'ConfiguratorKernel.wasm',\n 'ConfiguratorKernel',\n 'roomle-core-hsc/wasm_modern/ConfiguratorKernel.js',\n ],\n [\n 'RoomleCore.wasm',\n 'RoomleCore',\n 'roomle-core-hsc/wasm_modern/RoomleCore.js',\n ],\n [\n 'RoomleToolsCore.wasm',\n 'RoomleToolsCore',\n 'roomle-core-hsc/wasm_modern/RoomleToolsCore.js',\n ],\n];\n\nexport default class HeadlessScriptLoader implements Context {\n public _creator_: string;\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public async fetch(url: string, options: { id: string }) {\n if (_idCache[options.id]) {\n return;\n }\n\n // In Bun, Vite's ?no-inline?url imports resolve to the module's default\n // export (a function) rather than a URL string. Handle both cases.\n if (typeof url === 'function') {\n this._registerFactory(url);\n _idCache[options.id] = true;\n return;\n }\n\n const entry = this._resolveEntry(url);\n if (entry) {\n const [, globalName, modulePath] = entry;\n // If url is an absolute filesystem path (from getHeadlessWasmPath),\n // require it directly. Otherwise fall back to the module specifier\n // (works from source where roomle-core-hsc is in node_modules).\n const pathToLoad = url.startsWith('/') ? url : modulePath;\n const mod = _require(pathToLoad);\n (globalThis as any)[globalName] = mod.default || mod;\n _idCache[options.id] = true;\n }\n }\n\n // Identify an Emscripten factory function by checking its source for the\n // unique .wasm filename it references, then register it on globalThis\n // under the name the kernel-access classes expect (e.g. window.ConfiguratorKernel).\n private _registerFactory(factory: () => void) {\n const source = factory.toString();\n for (const [wasmFile, globalName] of WASM_TO_GLOBAL) {\n if (source.includes(wasmFile)) {\n (globalThis as any)[globalName] = factory;\n return;\n }\n }\n console.warn(\n 'HeadlessScriptLoader: Could not identify Emscripten factory function',\n );\n }\n\n private _resolveEntry(url: string) {\n for (const entry of WASM_TO_GLOBAL) {\n const [wasmFile, globalName] = entry;\n const baseName = globalName; // e.g. \"ConfiguratorKernel\"\n if (url.includes(baseName) || url.includes(wasmFile)) {\n return entry;\n }\n }\n // Fallback: looser matching for generic URLs\n if (url.includes('configurator')) {\n return WASM_TO_GLOBAL[0];\n }\n if (url.includes('planner')) {\n return WASM_TO_GLOBAL[1];\n }\n if (url.includes('tools')) {\n return WASM_TO_GLOBAL[2];\n }\n console.warn(\n `HeadlessScriptLoader: Could not resolve module for URL: ${url}`,\n );\n return null;\n }\n\n public loadScripts(scripts: Array<{ id: string; name: string }>) {\n const promises = scripts.map((script) =>\n this.fetch(script.name, { id: script.id }),\n );\n return Promise.all(promises);\n }\n\n public resolveKernelPaths(type: 'configurator' | 'planner' | 'tools'): {\n wasm: string;\n loader: string;\n } {\n return getHeadlessWasmPath(type);\n }\n\n public cleanUp() {\n _idCache = {};\n }\n}\n","export const noop = () => {};\n","/**\n * Stub DomHelper for headless mode.\n * Returns fixed dimensions since we don't render to a real canvas.\n */\nimport { Vector2 } from 'three';\nimport { noop } from './stubs';\nimport type {\n LifeCycleCallbacks,\n LifeCycleManager,\n} from '../../common-core/src/life-cycle-manager';\nimport type { Context } from '../../common-core/src/di/context';\n\nexport default class HeadlessDomHelper implements LifeCycleCallbacks, Context {\n public _creator_: string;\n\n // Manual DI lookup instead of @inject decorator (avoids legacy/TC39 decorator mismatch)\n private get _lifeCycleManager(): LifeCycleManager | undefined {\n return (globalThis as any).__RML__DI__?.lookup(\n 'life-cycle-manager',\n this._creator_,\n );\n }\n\n private _width: number;\n private _height: number;\n private _stubElement: any;\n\n get element(): any {\n return this._stubElement;\n }\n\n constructor(creator: string, width = 1024, height = 768) {\n this._creator_ = creator;\n this._width = width;\n this._height = height;\n\n const w = this._width;\n const h = this._height;\n this._stubElement = {\n clientWidth: w,\n clientHeight: h,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: {\n add() {},\n remove() {},\n contains() {\n return false;\n },\n },\n setAttribute() {},\n getAttribute(): string | null {\n return null;\n },\n children: [] as any[],\n getBoundingClientRect() {\n return {\n x: 0,\n y: 0,\n width: w,\n height: h,\n top: 0,\n left: 0,\n bottom: h,\n right: w,\n };\n },\n addEventListener() {},\n removeEventListener() {},\n dispatchEvent() {\n return true;\n },\n offsetWidth: w,\n offsetHeight: h,\n scrollWidth: w,\n scrollHeight: h,\n contains() {\n return false;\n },\n };\n }\n\n public setDomElement(_element: any) {\n noop();\n }\n\n public getClientDimensions() {\n return new Vector2(this._width, this._height);\n }\n\n public getAspectRatio() {\n return this._width / this._height;\n }\n\n public ensureCanvasFocus() {}\n public reset() {}\n public pause() {}\n public resume() {}\n public destroy() {}\n}\n","/**\n * Replaces the Worker-based DataSyncer with a no-op for headless mode.\n * In headless mode, assets are loaded on-demand via RapiAccess rather than\n * being pre-synced with a Web Worker.\n */\nimport type { RapiId } from '@roomle/web-sdk';\nimport { noop } from './stubs';\nimport type { Context } from '../../common-core/src/di/context';\n\nexport default class HeadlessDataSyncer implements Context {\n public _creator_: string;\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public start(_catalogId: RapiId) {\n return Promise.resolve();\n }\n\n public syncCatalog(_catalogId: RapiId): Promise<void> {\n return Promise.resolve();\n }\n\n public syncFloorTag(_tagId: RapiId) {\n return Promise.resolve();\n }\n\n public syncTypeChangeTag(_tagId: RapiId) {\n return Promise.resolve();\n }\n\n public _syncTypeChangeTag(_tagId: RapiId): Promise<any> {\n return Promise.resolve();\n }\n\n public getIsCatalogSynced(_catalogId: RapiId) {\n return false;\n }\n\n public onCommand(_command: number, _conversationId: number, _data: any) {\n noop();\n }\n\n public requestAsset(url: string, _urlAsFallback: boolean = false): string {\n return url;\n }\n\n public setAlwaysUseCache(_alwaysUseCache: boolean): void {\n noop();\n }\n\n public preFillAssetCache(_key: string, _url: string) {\n noop();\n }\n}\n","/**\n * Main entry point for the headless Roomle SDK.\n * Provides the ability to run the Roomle web-sdk in Node.js/Bun\n * for loading configurations/plans and exporting them to GLB/USDZ.\n */\nimport HeadlessScriptLoader from './headless-script-loader';\nimport HeadlessDomHelper from './headless-dom-helper';\nimport HeadlessDataSyncer from './headless-data-syncer';\nimport CommonKernelAccess from '../../common-core/src/services/common-kernel-access';\nimport type {\n RoomlePlanner,\n Planner,\n RoomleConfigurator,\n Configurator,\n InitDataDefinition,\n GlobalInitDataDefinition,\n RapiId,\n} from '../../index';\nimport { RoomleSdk } from '../../index';\nimport {\n Container,\n DependencyInjectionAssignment,\n DI_TYPE,\n} from '../../common-core/src/di/container';\nimport { INJECTABLES } from '../../common-core/src/di/injectables';\n\nexport interface HeadlessInitData\n extends Partial<InitDataDefinition>,\n Partial<GlobalInitDataDefinition> {\n configuratorId: string;\n /** Canvas width in pixels. Defaults to 1024. */\n width?: number;\n /** Canvas height in pixels. Defaults to 768. */\n height?: number;\n}\n\nexport interface ExportResult {\n buffer: ArrayBuffer;\n}\n\nexport interface ImageExportOptions {\n /** Supersampling anti-aliasing factor. Defaults to 2. */\n ssaa?: number;\n}\n\nexport interface ScreenshotExportOptions extends ImageExportOptions {\n /** JPEG quality (0–1). Defaults to 1. */\n quality?: number;\n}\n\nexport interface PerspectiveImageExportOptions extends ImageExportOptions {\n /** Output image size in pixels. Defaults to 1024. */\n size?: number;\n showDimensions?: boolean;\n rotationY?: number;\n}\n\nexport interface TopImageExportOptions extends ImageExportOptions {\n /** Output image size in pixels. Defaults to 1024. */\n size?: number;\n showDimensions?: boolean;\n}\n\nexport class HeadlessRoomleSdk {\n private _planner: RoomlePlanner;\n private _plannerMain: Planner;\n private _configurator: RoomleConfigurator;\n private _configuratorMain: Configurator;\n private _initialized = false;\n private _width = 1024;\n private _height = 768;\n\n static async create(initData: HeadlessInitData): Promise<HeadlessRoomleSdk> {\n const instance = new HeadlessRoomleSdk();\n await instance._init(initData);\n return instance;\n }\n\n private async _init(initData: HeadlessInitData) {\n this._width = initData.width ?? 1024;\n this._height = initData.height ?? 768;\n\n // Register headless service overrides BEFORE the DI container initializes.\n // This monkey-patches Container so that headless overrides always win,\n // even after boot() re-registers the default INJECTABLES.\n this._registerHeadlessServices(this._width, this._height);\n\n await RoomleSdk.setGlobalInitData({\n configuratorId: initData.configuratorId,\n locale: initData.locale,\n // @ts-ignore -- tenant is untyped, but we still need it.\n tenant: initData.tenant,\n overrideCountry: initData.overrideCountry,\n animateCamera: false,\n });\n\n this._initialized = true;\n }\n\n private _registerHeadlessServices(width: number, height: number) {\n // Create the DI container early. When roomle-dependency-injection.ts is\n // later loaded transitively, its _ensureContainer() checks if __RML__DI__\n // already exists and skips creating a new one — so we must register the\n // full INJECTABLES here ourselves.\n const container = new Container();\n (globalThis as any).__RML__DI__ = container;\n\n // Capture width/height in a subclass so the DI container instantiates\n // HeadlessDomHelper with the correct dimensions (DI only passes `creator`).\n class SizedHeadlessDomHelper extends HeadlessDomHelper {\n constructor(creator: string) {\n super(creator, width, height);\n }\n }\n\n const headlessOverrides = [\n new DependencyInjectionAssignment(\n 'script-loader',\n HeadlessScriptLoader,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment(\n 'dom-helper',\n SizedHeadlessDomHelper,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment('data-syncer', HeadlessDataSyncer),\n ];\n\n // Monkey-patch addDependencyInjectionAssignments so that every time\n // the SDK registers its default INJECTABLES (during boot()), our headless\n // overrides are re-applied on top. This ensures headless services always win.\n const originalAdd = Container.prototype.addDependencyInjectionAssignments;\n Container.prototype.addDependencyInjectionAssignments = function (\n injections: DependencyInjectionAssignment[],\n ) {\n originalAdd.call(this, injections);\n originalAdd.call(this, headlessOverrides);\n };\n\n // Wrap kernel callbacks with a safety Proxy so that exceptions thrown\n // from JS callbacks invoked by C++ (via Embind) are caught and logged\n // rather than propagating into C++ which would call std::terminate → abort().\n (CommonKernelAccess.prototype as any)._buildCallbackTarget = function () {\n const target = this;\n return new Proxy(target, {\n get(_, prop) {\n const val = (target as any)[prop];\n if (typeof val === 'function') {\n return function (...args: any[]) {\n try {\n return val.apply(target, args);\n } catch (e) {\n console.error(\n `[Headless] Kernel callback '${String(prop)}' threw:`,\n e,\n );\n }\n };\n }\n return val;\n },\n });\n };\n\n // Register all default INJECTABLES + headless overrides.\n // The monkey-patch ensures headless overrides are applied on top.\n container.addDependencyInjectionAssignments(INJECTABLES);\n }\n\n async loadConfiguration(\n configurationId: RapiId,\n initData?: Partial<InitDataDefinition>,\n ): Promise<void> {\n this._ensureInitialized();\n\n const configuratorModule = await RoomleSdk.getConfigurator(initData);\n await configuratorModule.boot();\n this._configuratorMain = configuratorModule;\n this._configurator = configuratorModule.getApi();\n\n const stubElement = {\n clientWidth: this._width,\n clientHeight: this._height,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: { add() {} },\n };\n await this._configurator.init(stubElement as any);\n\n await this._configurator.loadConfigurableItemById(configurationId);\n }\n\n async loadPlan(\n planId: string,\n initData?: Partial<InitDataDefinition>,\n ): Promise<void> {\n this._ensureInitialized();\n\n const plannerModule = await RoomleSdk.getPlanner(initData);\n await plannerModule.boot();\n this._plannerMain = plannerModule;\n this._planner = plannerModule.getApi();\n\n const stubElement = {\n clientWidth: this._width,\n clientHeight: this._height,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: { add() {} },\n };\n await this._planner.init(stubElement as any);\n\n await this._planner.loadPlan(planId);\n }\n\n async exportGLB(outputPath?: string): Promise<ExportResult> {\n return this._export(outputPath, 'glb');\n }\n\n async exportUSDZ(outputPath?: string): Promise<ExportResult> {\n return this._export(outputPath, 'usdz');\n }\n\n private async _export(\n outputPath: string | undefined,\n type: 'glb' | 'usdz',\n ): Promise<ExportResult> {\n this._ensureInitialized();\n\n const sm = this._configurator.getSceneManager();\n const buffer =\n type === 'glb' ? await sm.createExportGLB() : await sm.createUSDZExport();\n\n if (!buffer) {\n throw new Error(`${type.toUpperCase()} export produced no data`);\n }\n\n if (outputPath) {\n const fs = await import('fs');\n // @ts-ignore -- ts thinks this is a different type of buffer\n fs.writeFileSync(outputPath, Buffer.from(buffer));\n }\n\n return { buffer: buffer instanceof ArrayBuffer ? buffer : buffer.buffer };\n }\n\n async exportScreenshot(\n outputPath?: string,\n options: ScreenshotExportOptions = {},\n ): Promise<{ dataUrl: string }> {\n this._ensureInitialized();\n\n const quality = options.quality ?? 1;\n const ssaa = options.ssaa ?? 2;\n const sm = this._configurator.getSceneManager();\n\n let originalWidth: number | undefined;\n let originalHeight: number | undefined;\n\n // Temporarily resize renderer for SSAA supersampling\n if (ssaa > 1) {\n const renderer = sm.getRenderer();\n const roomleRenderer = sm.getRoomleRenderer();\n const canvas = renderer.domElement;\n originalWidth = canvas.width;\n originalHeight = canvas.height;\n roomleRenderer?.setSize(originalWidth! * ssaa, originalHeight! * ssaa);\n }\n\n let dataUrl: string = await sm.exportCanvasScreenshot(quality);\n\n // Restore original size and downscale\n if (ssaa > 1 && originalWidth && originalHeight) {\n sm.getRoomleRenderer()?.setSize(originalWidth, originalHeight);\n dataUrl = await this._ssaaDownscale(\n dataUrl,\n originalWidth,\n originalHeight,\n );\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = dataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl };\n }\n\n async exportPerspectiveImage(\n outputPath?: string,\n options: PerspectiveImageExportOptions = {},\n ): Promise<{ dataUrl: string; width: number; height: number }> {\n this._ensureInitialized();\n\n const ssaa = options.ssaa ?? 2;\n const targetSize = options.size ?? 1024;\n const renderSize = targetSize * ssaa;\n\n const result = await this._configurator.preparePerspectiveImage({\n ...options,\n size: renderSize,\n });\n\n let finalDataUrl = result.image;\n let finalWidth = result.width;\n let finalHeight = result.height;\n\n // Downscale with SSAA if rendering at higher resolution, achieves antialiasing effect.\n if (ssaa > 1) {\n finalDataUrl = await this._ssaaDownscale(\n finalDataUrl,\n targetSize,\n targetSize,\n );\n finalWidth = targetSize;\n finalHeight = targetSize;\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = finalDataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl: finalDataUrl, width: finalWidth, height: finalHeight };\n }\n\n async exportTopImage(\n outputPath?: string,\n options: TopImageExportOptions = {},\n ): Promise<{ dataUrl: string; width: number; height: number }> {\n this._ensureInitialized();\n\n const ssaa = options.ssaa ?? 2;\n const result = await this._configurator.prepareTopImage({\n ...options,\n size: (options.size ?? 1024) * ssaa,\n showDimensions: options.showDimensions ?? false,\n });\n\n let finalDataUrl = result.image;\n let finalWidth = result.width;\n let finalHeight = result.height;\n\n if (ssaa > 1) {\n const targetWidth = Math.round(finalWidth / ssaa);\n const targetHeight = Math.round(finalHeight / ssaa);\n finalDataUrl = await this._ssaaDownscale(\n finalDataUrl,\n targetWidth,\n targetHeight,\n );\n finalWidth = targetWidth;\n finalHeight = targetHeight;\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = finalDataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl: finalDataUrl, width: finalWidth, height: finalHeight };\n }\n\n /** Downscale a data URL image to target dimensions using high-quality filtering. */\n private async _ssaaDownscale(\n dataUrl: string,\n targetWidth: number,\n targetHeight: number,\n ): Promise<string> {\n const { createCanvas, loadImage } = await import('@napi-rs/canvas');\n const imgBuffer = Buffer.from(\n dataUrl.replace(/^data:image\\/\\w+;base64,/, ''),\n 'base64',\n );\n const img = await loadImage(imgBuffer);\n const outCanvas = createCanvas(targetWidth, targetHeight);\n const ctx = outCanvas.getContext('2d');\n (ctx as any).imageSmoothingEnabled = true;\n (ctx as any).imageSmoothingQuality = 'high';\n ctx.drawImage(img, 0, 0, targetWidth, targetHeight);\n return outCanvas.toDataURL('image/png');\n }\n\n getConfiguratorApi() {\n return this._configurator;\n }\n\n getPlannerApi() {\n return this._planner;\n }\n\n async destroy() {\n if (this._configuratorMain) {\n this._configuratorMain.destroy();\n }\n if (this._plannerMain) {\n this._plannerMain.destroy();\n }\n }\n\n private _ensureInitialized() {\n if (!this._initialized) {\n throw new Error(\n 'HeadlessRoomleSdk not initialized. Call HeadlessRoomleSdk.create() first.',\n );\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"roomle-headless.js","names":[],"sources":["../../packages/headless-core/src/headless-script-loader.ts","../../packages/headless-core/src/stubs.ts","../../packages/headless-core/src/headless-dom-helper.ts","../../packages/headless-core/src/headless-data-syncer.ts","../../packages/headless-core/src/headless-sdk.ts"],"sourcesContent":["/**\n * Replaces the browser ScriptLoader for headless mode.\n * Instead of injecting <script> tags, directly imports the Emscripten JS modules.\n */\nimport { createRequire } from 'module';\nimport type { Context } from '../../common-core/src/di/context';\nimport { getHeadlessWasmPath } from '../../common-core/src/static-files/roomle-core';\n\n// createRequire is needed because the Emscripten kernel files are CommonJS\n// and must be loaded synchronously\nconst _require = createRequire(import.meta.url);\n\nlet _idCache: { [key: string]: boolean } = {};\n\n// Maps a .wasm filename found in the Emscripten factory's source to its global name.\n// Each Emscripten factory references its own .wasm file (e.g. ConfiguratorKernel.wasm).\nconst WASM_TO_GLOBAL: Array<\n [wasmFile: string, globalName: string, modulePath: string]\n> = [\n [\n 'ConfiguratorKernel.wasm',\n 'ConfiguratorKernel',\n 'roomle-core-hsc/wasm_modern/ConfiguratorKernel.js',\n ],\n [\n 'RoomleCore.wasm',\n 'RoomleCore',\n 'roomle-core-hsc/wasm_modern/RoomleCore.js',\n ],\n [\n 'RoomleToolsCore.wasm',\n 'RoomleToolsCore',\n 'roomle-core-hsc/wasm_modern/RoomleToolsCore.js',\n ],\n];\n\nexport default class HeadlessScriptLoader implements Context {\n public _creator_: string;\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public async fetch(url: string, options: { id: string }) {\n if (_idCache[options.id]) {\n return;\n }\n\n // In Bun, Vite's ?no-inline?url imports resolve to the module's default\n // export (a function) rather than a URL string. Handle both cases.\n if (typeof url === 'function') {\n this._registerFactory(url);\n _idCache[options.id] = true;\n return;\n }\n\n const entry = this._resolveEntry(url);\n if (entry) {\n const [, globalName, modulePath] = entry;\n // If url is an absolute filesystem path (from getHeadlessWasmPath),\n // require it directly. Otherwise fall back to the module specifier\n // (works from source where roomle-core-hsc is in node_modules).\n const pathToLoad = url.startsWith('/') ? url : modulePath;\n const mod = _require(pathToLoad);\n (globalThis as any)[globalName] = mod.default || mod;\n _idCache[options.id] = true;\n }\n }\n\n // Identify an Emscripten factory function by checking its source for the\n // unique .wasm filename it references, then register it on globalThis\n // under the name the kernel-access classes expect (e.g. window.ConfiguratorKernel).\n private _registerFactory(factory: () => void) {\n const source = factory.toString();\n for (const [wasmFile, globalName] of WASM_TO_GLOBAL) {\n if (source.includes(wasmFile)) {\n (globalThis as any)[globalName] = factory;\n return;\n }\n }\n console.warn(\n 'HeadlessScriptLoader: Could not identify Emscripten factory function',\n );\n }\n\n private _resolveEntry(url: string) {\n for (const entry of WASM_TO_GLOBAL) {\n const [wasmFile, globalName] = entry;\n const baseName = globalName; // e.g. \"ConfiguratorKernel\"\n if (url.includes(baseName) || url.includes(wasmFile)) {\n return entry;\n }\n }\n // Fallback: looser matching for generic URLs\n if (url.includes('configurator')) {\n return WASM_TO_GLOBAL[0];\n }\n if (url.includes('planner')) {\n return WASM_TO_GLOBAL[1];\n }\n if (url.includes('tools')) {\n return WASM_TO_GLOBAL[2];\n }\n console.warn(\n `HeadlessScriptLoader: Could not resolve module for URL: ${url}`,\n );\n return null;\n }\n\n public loadScripts(scripts: Array<{ id: string; name: string }>) {\n const promises = scripts.map((script) =>\n this.fetch(script.name, { id: script.id }),\n );\n return Promise.all(promises);\n }\n\n public resolveKernelPaths(type: 'configurator' | 'planner' | 'tools'): {\n wasm: string;\n loader: string;\n } {\n return getHeadlessWasmPath(type);\n }\n\n public cleanUp() {\n _idCache = {};\n }\n}\n","export const noop = () => {};\n","/**\n * Stub DomHelper for headless mode.\n * Returns fixed dimensions since we don't render to a real canvas.\n */\nimport { Vector2 } from 'three';\nimport { noop } from './stubs';\nimport type {\n LifeCycleCallbacks,\n LifeCycleManager,\n} from '../../common-core/src/life-cycle-manager';\nimport type { Context } from '../../common-core/src/di/context';\n\nexport default class HeadlessDomHelper implements LifeCycleCallbacks, Context {\n public _creator_: string;\n\n // Manual DI lookup instead of @inject decorator (avoids legacy/TC39 decorator mismatch)\n private get _lifeCycleManager(): LifeCycleManager | undefined {\n return (globalThis as any).__RML__DI__?.lookup(\n 'life-cycle-manager',\n this._creator_,\n );\n }\n\n private _width: number;\n private _height: number;\n private _stubElement: any;\n\n get element(): any {\n return this._stubElement;\n }\n\n constructor(creator: string, width = 1024, height = 768) {\n this._creator_ = creator;\n this._width = width;\n this._height = height;\n\n const w = this._width;\n const h = this._height;\n this._stubElement = {\n clientWidth: w,\n clientHeight: h,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: {\n add() {},\n remove() {},\n contains() {\n return false;\n },\n },\n setAttribute() {},\n getAttribute(): string | null {\n return null;\n },\n children: [] as any[],\n getBoundingClientRect() {\n return {\n x: 0,\n y: 0,\n width: w,\n height: h,\n top: 0,\n left: 0,\n bottom: h,\n right: w,\n };\n },\n addEventListener() {},\n removeEventListener() {},\n dispatchEvent() {\n return true;\n },\n offsetWidth: w,\n offsetHeight: h,\n scrollWidth: w,\n scrollHeight: h,\n contains() {\n return false;\n },\n };\n }\n\n public setDomElement(_element: any) {\n noop();\n }\n\n public getClientDimensions() {\n return new Vector2(this._width, this._height);\n }\n\n public getAspectRatio() {\n return this._width / this._height;\n }\n\n public ensureCanvasFocus() {}\n public reset() {}\n public pause() {}\n public resume() {}\n public destroy() {}\n}\n","/**\n * Replaces the Worker-based DataSyncer with a no-op for headless mode.\n * In headless mode, assets are loaded on-demand via RapiAccess rather than\n * being pre-synced with a Web Worker.\n */\nimport type { RapiId } from '@roomle/web-sdk';\nimport { noop } from './stubs';\nimport type { Context } from '../../common-core/src/di/context';\n\nexport default class HeadlessDataSyncer implements Context {\n public _creator_: string;\n\n constructor(creator: string) {\n this._creator_ = creator;\n }\n\n public start(_catalogId: RapiId) {\n return Promise.resolve();\n }\n\n public syncCatalog(_catalogId: RapiId): Promise<void> {\n return Promise.resolve();\n }\n\n public syncFloorTag(_tagId: RapiId) {\n return Promise.resolve();\n }\n\n public syncTypeChangeTag(_tagId: RapiId) {\n return Promise.resolve();\n }\n\n public _syncTypeChangeTag(_tagId: RapiId): Promise<any> {\n return Promise.resolve();\n }\n\n public getIsCatalogSynced(_catalogId: RapiId) {\n return false;\n }\n\n public onCommand(_command: number, _conversationId: number, _data: any) {\n noop();\n }\n\n public requestAsset(url: string, _urlAsFallback: boolean = false): string {\n return url;\n }\n\n public setAlwaysUseCache(_alwaysUseCache: boolean): void {\n noop();\n }\n\n public preFillAssetCache(_key: string, _url: string) {\n noop();\n }\n}\n","/**\n * Main entry point for the headless Roomle SDK.\n * Provides the ability to run the Roomle web-sdk in Node.js/Bun\n * for loading configurations/plans and exporting them to GLB/USDZ.\n */\nimport HeadlessScriptLoader from './headless-script-loader';\nimport HeadlessDomHelper from './headless-dom-helper';\nimport HeadlessDataSyncer from './headless-data-syncer';\nimport CommonKernelAccess from '../../common-core/src/services/common-kernel-access';\nimport type {\n RoomlePlanner,\n Planner,\n RoomleConfigurator,\n Configurator,\n InitDataDefinition,\n GlobalInitDataDefinition,\n RapiId,\n} from '../../index';\nimport { RoomleSdk } from '../../index';\nimport {\n Container,\n DependencyInjectionAssignment,\n DI_TYPE,\n} from '../../common-core/src/di/container';\nimport { INJECTABLES } from '../../common-core/src/di/injectables';\n\nexport interface HeadlessInitData\n extends Partial<InitDataDefinition>,\n Partial<GlobalInitDataDefinition> {\n configuratorId: string;\n /** Canvas width in pixels. Defaults to 1024. */\n width?: number;\n /** Canvas height in pixels. Defaults to 768. */\n height?: number;\n}\n\nexport interface ExportResult {\n buffer: ArrayBuffer;\n}\n\nexport interface ImageExportOptions {\n /** Supersampling anti-aliasing factor. Defaults to 2. */\n ssaa?: number;\n}\n\nexport interface ScreenshotExportOptions extends ImageExportOptions {\n /** JPEG quality (0–1). Defaults to 1. */\n quality?: number;\n}\n\nexport interface PerspectiveImageExportOptions extends ImageExportOptions {\n /** Output image size in pixels. Defaults to 1024. */\n size?: number;\n showDimensions?: boolean;\n rotationY?: number;\n}\n\nexport interface TopImageExportOptions extends ImageExportOptions {\n /** Output image size in pixels. Defaults to 1024. */\n size?: number;\n showDimensions?: boolean;\n}\n\nexport class HeadlessRoomleSdk {\n private _planner: RoomlePlanner;\n private _plannerMain: Planner;\n private _configurator: RoomleConfigurator;\n private _configuratorMain: Configurator;\n private _initialized = false;\n private _width = 1024;\n private _height = 768;\n\n static async create(initData: HeadlessInitData): Promise<HeadlessRoomleSdk> {\n const instance = new HeadlessRoomleSdk();\n await instance._init(initData);\n return instance;\n }\n\n private async _init(initData: HeadlessInitData) {\n this._width = initData.width ?? 1024;\n this._height = initData.height ?? 768;\n\n // Register headless service overrides BEFORE the DI container initializes.\n // This monkey-patches Container so that headless overrides always win,\n // even after boot() re-registers the default INJECTABLES.\n this._registerHeadlessServices(this._width, this._height);\n\n await RoomleSdk.setGlobalInitData({\n configuratorId: initData.configuratorId,\n locale: initData.locale,\n // @ts-ignore -- tenant is untyped, but we still need it.\n tenant: initData.tenant,\n overrideCountry: initData.overrideCountry,\n animateCamera: false,\n });\n\n this._initialized = true;\n }\n\n private _registerHeadlessServices(width: number, height: number) {\n // Create the DI container early. When roomle-dependency-injection.ts is\n // later loaded transitively, its _ensureContainer() checks if __RML__DI__\n // already exists and skips creating a new one — so we must register the\n // full INJECTABLES here ourselves.\n const container = new Container();\n (globalThis as any).__RML__DI__ = container;\n\n // Capture width/height in a subclass so the DI container instantiates\n // HeadlessDomHelper with the correct dimensions (DI only passes `creator`).\n class SizedHeadlessDomHelper extends HeadlessDomHelper {\n constructor(creator: string) {\n super(creator, width, height);\n }\n }\n\n const headlessOverrides = [\n new DependencyInjectionAssignment(\n 'script-loader',\n HeadlessScriptLoader,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment(\n 'dom-helper',\n SizedHeadlessDomHelper,\n DI_TYPE.CONTEXT,\n ),\n new DependencyInjectionAssignment('data-syncer', HeadlessDataSyncer),\n ];\n\n // Monkey-patch addDependencyInjectionAssignments so that every time\n // the SDK registers its default INJECTABLES (during boot()), our headless\n // overrides are re-applied on top. This ensures headless services always win.\n const originalAdd = Container.prototype.addDependencyInjectionAssignments;\n Container.prototype.addDependencyInjectionAssignments = function (\n injections: DependencyInjectionAssignment[],\n ) {\n originalAdd.call(this, injections);\n originalAdd.call(this, headlessOverrides);\n };\n\n // Wrap kernel callbacks with a safety Proxy so that exceptions thrown\n // from JS callbacks invoked by C++ (via Embind) are caught and logged\n // rather than propagating into C++ which would call std::terminate → abort().\n (CommonKernelAccess.prototype as any)._buildCallbackTarget = function () {\n const target = this;\n return new Proxy(target, {\n get(_, prop) {\n const val = (target as any)[prop];\n if (typeof val === 'function') {\n return function (...args: any[]) {\n try {\n return val.apply(target, args);\n } catch (e) {\n console.error(\n `[Headless] Kernel callback '${String(prop)}' threw:`,\n e,\n );\n }\n };\n }\n return val;\n },\n });\n };\n\n // Register all default INJECTABLES + headless overrides.\n // The monkey-patch ensures headless overrides are applied on top.\n container.addDependencyInjectionAssignments(INJECTABLES);\n }\n\n async loadConfiguration(\n configurationId: RapiId,\n initData?: Partial<InitDataDefinition>,\n ): Promise<void> {\n this._ensureInitialized();\n\n const configuratorModule = await RoomleSdk.getConfigurator(initData);\n await configuratorModule.boot();\n this._configuratorMain = configuratorModule;\n this._configurator = configuratorModule.getApi();\n\n const stubElement = {\n clientWidth: this._width,\n clientHeight: this._height,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: { add() {} },\n };\n await this._configurator.init(stubElement as any);\n\n await this._configurator.loadConfigurableItemById(configurationId);\n }\n\n async loadPlan(\n planId: string,\n initData?: Partial<InitDataDefinition>,\n ): Promise<void> {\n this._ensureInitialized();\n\n const plannerModule = await RoomleSdk.getPlanner(initData);\n await plannerModule.boot();\n this._plannerMain = plannerModule;\n this._planner = plannerModule.getApi();\n\n const stubElement = {\n clientWidth: this._width,\n clientHeight: this._height,\n appendChild() {},\n removeChild() {},\n style: {},\n classList: { add() {} },\n };\n await this._planner.init(stubElement as any);\n\n await this._planner.loadPlan(planId);\n }\n\n async exportGLB(outputPath?: string): Promise<ExportResult> {\n return this._export(outputPath, 'glb');\n }\n\n async exportUSDZ(outputPath?: string): Promise<ExportResult> {\n return this._export(outputPath, 'usdz');\n }\n\n private async _export(\n outputPath: string | undefined,\n type: 'glb' | 'usdz',\n ): Promise<ExportResult> {\n this._ensureInitialized();\n\n const sm = this._configurator.getSceneManager();\n const buffer =\n type === 'glb' ? await sm.createExportGLB() : await sm.createUSDZExport();\n\n if (!buffer) {\n throw new Error(`${type.toUpperCase()} export produced no data`);\n }\n\n // The buffer is either ArrayBuffer (GLB) or Uint8Array (USDZ).\n // Extract the underlying ArrayBuffer in both cases.\n const arrayBuffer =\n buffer instanceof ArrayBuffer\n ? buffer\n : ((buffer as Uint8Array).buffer as ArrayBuffer);\n\n if (outputPath) {\n const fs = await import('fs');\n fs.writeFileSync(outputPath, Buffer.from(arrayBuffer));\n }\n\n return { buffer: arrayBuffer };\n }\n\n async exportScreenshot(\n outputPath?: string,\n options: ScreenshotExportOptions = {},\n ): Promise<{ dataUrl: string }> {\n this._ensureInitialized();\n\n const quality = options.quality ?? 1;\n const ssaa = options.ssaa ?? 2;\n const sm = this._configurator.getSceneManager();\n const renderer = sm.getRenderer();\n if (!renderer) {\n throw new Error('HeadlessRoomleSdk: renderer is not available');\n }\n\n let originalWidth: number | undefined;\n let originalHeight: number | undefined;\n\n // Temporarily resize renderer for SSAA supersampling\n if (ssaa > 1) {\n const roomleRenderer = sm.getRoomleRenderer();\n const canvas = renderer.domElement;\n originalWidth = canvas.width;\n originalHeight = canvas.height;\n roomleRenderer?.setSize(originalWidth! * ssaa, originalHeight! * ssaa);\n }\n\n let dataUrl: string = await sm.exportCanvasScreenshot(quality);\n\n // Restore original size and downscale\n if (ssaa > 1 && originalWidth && originalHeight) {\n sm.getRoomleRenderer()?.setSize(originalWidth, originalHeight);\n dataUrl = await this._ssaaDownscale(\n dataUrl,\n originalWidth,\n originalHeight,\n );\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = dataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl };\n }\n\n async exportPerspectiveImage(\n outputPath?: string,\n options: PerspectiveImageExportOptions = {},\n ): Promise<{ dataUrl: string; width: number; height: number }> {\n this._ensureInitialized();\n\n const ssaa = options.ssaa ?? 2;\n const targetSize = options.size ?? 1024;\n const renderSize = targetSize * ssaa;\n\n const result = await this._configurator.preparePerspectiveImage({\n ...options,\n size: renderSize,\n });\n\n let finalDataUrl = result.image;\n let finalWidth = result.width;\n let finalHeight = result.height;\n\n // Downscale with SSAA if rendering at higher resolution, achieves antialiasing effect.\n if (ssaa > 1) {\n finalDataUrl = await this._ssaaDownscale(\n finalDataUrl,\n targetSize,\n targetSize,\n );\n finalWidth = targetSize;\n finalHeight = targetSize;\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = finalDataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl: finalDataUrl, width: finalWidth, height: finalHeight };\n }\n\n async exportTopImage(\n outputPath?: string,\n options: TopImageExportOptions = {},\n ): Promise<{ dataUrl: string; width: number; height: number }> {\n this._ensureInitialized();\n\n const ssaa = options.ssaa ?? 2;\n const result = await this._configurator.prepareTopImage({\n ...options,\n size: (options.size ?? 1024) * ssaa,\n showDimensions: options.showDimensions ?? false,\n });\n\n let finalDataUrl = result.image;\n let finalWidth = result.width;\n let finalHeight = result.height;\n\n if (ssaa > 1) {\n const targetWidth = Math.round(finalWidth / ssaa);\n const targetHeight = Math.round(finalHeight / ssaa);\n finalDataUrl = await this._ssaaDownscale(\n finalDataUrl,\n targetWidth,\n targetHeight,\n );\n finalWidth = targetWidth;\n finalHeight = targetHeight;\n }\n\n if (outputPath) {\n const fs = await import('fs');\n const base64 = finalDataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n fs.writeFileSync(outputPath, Buffer.from(base64, 'base64'));\n }\n\n return { dataUrl: finalDataUrl, width: finalWidth, height: finalHeight };\n }\n\n /** Downscale a data URL image to target dimensions using high-quality filtering. */\n private async _ssaaDownscale(\n dataUrl: string,\n targetWidth: number,\n targetHeight: number,\n ): Promise<string> {\n const { createCanvas, loadImage } = await import('@napi-rs/canvas');\n const imgBuffer = Buffer.from(\n dataUrl.replace(/^data:image\\/\\w+;base64,/, ''),\n 'base64',\n );\n const img = await loadImage(imgBuffer);\n const outCanvas = createCanvas(targetWidth, targetHeight);\n const ctx = outCanvas.getContext('2d');\n (ctx as any).imageSmoothingEnabled = true;\n (ctx as any).imageSmoothingQuality = 'high';\n ctx.drawImage(img, 0, 0, targetWidth, targetHeight);\n return outCanvas.toDataURL('image/png');\n }\n\n getConfiguratorApi() {\n return this._configurator;\n }\n\n getPlannerApi() {\n return this._planner;\n }\n\n async destroy() {\n if (this._configuratorMain) {\n this._configuratorMain.destroy();\n }\n if (this._plannerMain) {\n this._plannerMain.destroy();\n }\n }\n\n private _ensureInitialized() {\n if (!this._initialized) {\n throw new Error(\n 'HeadlessRoomleSdk not initialized. Call HeadlessRoomleSdk.create() first.',\n );\n }\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { d as e } from "./three.core-mM-jZdgg.mjs";
1
+ import { d as e } from "./three.core-BmQnspOL.mjs";
2
2
  //#region packages/common-core/src/roomle-renderer.ts
3
3
  var t = /* @__PURE__ */ function(e) {
4
4
  return e[e.Mode3D = 0] = "Mode3D", e[e.Mode2D = 1] = "Mode2D", e;
@@ -46,4 +46,4 @@ var t = /* @__PURE__ */ function(e) {
46
46
  //#endregion
47
47
  export { n, t };
48
48
 
49
- //# sourceMappingURL=roomle-renderer-DVlJsHYn.mjs.map
49
+ //# sourceMappingURL=roomle-renderer-BEJNPCKx.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roomle-renderer-BEJNPCKx.mjs","names":[],"sources":["../../packages/common-core/src/roomle-renderer.ts"],"sourcesContent":["import type { Camera, Object3D, Scene, Vector2, WebGLRenderer } from 'three';\nimport { Box3 } from 'three';\nimport type { Enumify } from '#/common/src/utils/types';\nimport type { CAMERA_TYPE } from './cameracontrol/camera-type';\nimport type { WebGPURenderer } from 'three/webgpu';\nimport type {\n CustomShadingParameters,\n SceneShadingType,\n} from './webgl/renderer/shading-settings';\nimport type {\n LutImageDefinition,\n OutlineCustomParameters,\n QualityLevel,\n QualityMap,\n} from './webgl/renderer/scene-renderer';\n\nexport type GenericRoomleRenderer = RoomleRenderer<\n WebGLRenderer | WebGPURenderer\n>;\n\nexport enum PlannerRenderMode {\n Mode3D,\n Mode2D,\n}\n\nexport abstract class RoomleRenderer<\n RendererType extends WebGLRenderer | WebGPURenderer,\n> {\n public _creator_: string;\n public renderer: RendererType;\n protected isConfiguratorMode: boolean = true;\n protected isCameraMoving: boolean = false;\n protected cameraType: Enumify<typeof CAMERA_TYPE>;\n protected shadowNeedsUpdate: boolean = false;\n protected boundingBox: Box3 = new Box3();\n protected boundingBoxNeedsUpdate: boolean = false;\n\n protected constructor(creator: string, renderer: RendererType) {\n this._creator_ = creator;\n this.renderer = renderer;\n }\n\n public get isConfiguring(): boolean {\n return this.isConfiguratorMode;\n }\n\n public dispose(): void {\n this.renderer.dispose();\n }\n\n public setSize(width: number, height: number): void {\n this.renderer.setSize(width, height);\n }\n\n public getSize(target: Vector2): Vector2 {\n return this.renderer.getSize(target);\n }\n\n public setCameraType(cameraType: Enumify<typeof CAMERA_TYPE>) {\n this.cameraType = cameraType;\n }\n\n public movingCameraStarts(): void {\n this.isCameraMoving = true;\n }\n\n public movingCameraStops(): void {\n this.isCameraMoving = false;\n }\n\n public forceShadowUpdates(_updateBakedGroundShadow: boolean): void {\n this.shadowNeedsUpdate = true;\n }\n\n public clear() {\n this.renderer.clear();\n }\n\n public updateBounds(geometryBounds: Box3) {\n this.boundingBox.copy(geometryBounds);\n this.boundingBoxNeedsUpdate = true;\n }\n\n public switchToConfigurator(): void {\n this.isConfiguratorMode = true;\n }\n\n public switchToPlanner(_renderMode: PlannerRenderMode) {\n this.isConfiguratorMode = false;\n }\n\n public abstract setShadingType(shadingType: SceneShadingType): void;\n\n public abstract setAutoQuality(autoQuality: boolean): void;\n\n public abstract setQualityLevel(qualityLevel: QualityLevel): void;\n\n public abstract getQualityLevel(): QualityLevel;\n\n public abstract setQualityMap(qualityMap: QualityMap): void;\n\n public abstract setCustomShadingParameters(\n customShadingParameters?: CustomShadingParameters,\n customShadingParametersMoc?: CustomShadingParameters,\n ): void;\n\n public abstract setCustomOutlineParameters(\n outlineCustomParameters: OutlineCustomParameters,\n ): void;\n\n public abstract loadLutImages(luts: LutImageDefinition[]): void;\n\n public abstract render(scene: Scene, camera: Camera): void;\n\n public abstract showGUI(updateCallback: () => void): void;\n\n public abstract setOnQualityLevelChangeCallback(\n callback: (qualityLevel: QualityLevel) => void,\n ): void;\n\n public abstract clearCache(): void;\n\n public abstract highlightObjects(selectedMeshes: Object3D[]): void;\n\n public abstract setGroundShadow(enabled: boolean): void;\n\n public abstract enableUiInteractionMode(): void;\n\n public abstract disableUiInteractionMode(): void;\n}\n"],"mappings":";;AAoBA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,EAAA,SAAA,KAAA,UACA,EAAA,EAAA,SAAA,KAAA;KACD,EAEqB,IAAtB,MAEE;CAUA,YAAsB,GAAiB,GAAwB;AAE7D,4BATsC,0BACJ,6BAEG,uBACT,IAAI,GAAM,gCACI,IAG1C,KAAK,YAAY,GACjB,KAAK,WAAW;;CAGlB,IAAW,gBAAyB;AAClC,SAAO,KAAK;;CAGd,UAAuB;AACrB,OAAK,SAAS,SAAS;;CAGzB,QAAe,GAAe,GAAsB;AAClD,OAAK,SAAS,QAAQ,GAAO,EAAO;;CAGtC,QAAe,GAA0B;AACvC,SAAO,KAAK,SAAS,QAAQ,EAAO;;CAGtC,cAAqB,GAAyC;AAC5D,OAAK,aAAa;;CAGpB,qBAAkC;AAChC,OAAK,iBAAiB;;CAGxB,oBAAiC;AAC/B,OAAK,iBAAiB;;CAGxB,mBAA0B,GAAyC;AACjE,OAAK,oBAAoB;;CAG3B,QAAe;AACb,OAAK,SAAS,OAAO;;CAGvB,aAAoB,GAAsB;AAExC,EADA,KAAK,YAAY,KAAK,EAAe,EACrC,KAAK,yBAAyB;;CAGhC,uBAAoC;AAClC,OAAK,qBAAqB;;CAG5B,gBAAuB,GAAgC;AACrD,OAAK,qBAAqB"}