@salsita-ai/sdk 0.50.0-develop.ca5894b56c → 0.50.0-develop.cba048b0d7

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 (238) hide show
  1. package/dist/application-spec/errors/diagnostic-codes.d.ts +7 -1
  2. package/dist/application-spec/errors/diagnostic-codes.js +1 -1
  3. package/dist/application-spec/errors/diagnostic-messages.d.ts +14 -1
  4. package/dist/application-spec/errors/diagnostic-messages.js +1 -1
  5. package/dist/application-spec/generate-application/implementations/phx-model.d.ts +1 -1
  6. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-model-runtime.d.ts +1 -2
  7. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.d.ts +1 -2
  8. package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.d.ts +1 -2
  9. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +1 -2
  10. package/dist/application-spec/generate-application/runtime/sections/actions-runtime.d.ts +1 -2
  11. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.d.ts +1 -1
  12. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
  13. package/dist/application-spec/generate-application/runtime/sections/build-user-bound-optic.d.ts +1 -1
  14. package/dist/application-spec/generate-application/runtime/sections/component-optic.d.ts +1 -2
  15. package/dist/application-spec/generate-application/runtime/sections/expression-runtime.d.ts +1 -2
  16. package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.d.ts +1 -2
  17. package/dist/application-spec/generate-application/runtime/sections/reflection-constants-runtime.d.ts +1 -2
  18. package/dist/application-spec/generate-application/runtime-spec/runtime-spec.d.ts +96 -31
  19. package/dist/application-spec/generate-application/runtime-spec/spec-code-id.d.ts +1 -1
  20. package/dist/application-spec/parse-application-files/merge/merged-assistant.d.ts +13 -4
  21. package/dist/application-spec/parse-application-files/merge/merged-assistant.js +1 -1
  22. package/dist/application-spec/parse-application-files/merge/merged-infra.d.ts +4 -11
  23. package/dist/application-spec/parse-application-files/merge/merged-transformers.d.ts +2 -4
  24. package/dist/application-spec/parse-application-files/raw-spec/raw-acl.d.ts +2 -2
  25. package/dist/application-spec/parse-application-files/raw-spec/raw-acl.js +1 -1
  26. package/dist/application-spec/parse-application-files/raw-spec/raw-admin-pages.d.ts +3 -24
  27. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +25 -20
  28. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
  29. package/dist/application-spec/parse-application-files/raw-spec/raw-resources.d.ts +19 -64
  30. package/dist/application-spec/parse-application-files/spec/application/admin-spec/admin-pages.d.ts +3 -20
  31. package/dist/application-spec/parse-application-files/spec/application/admin-spec/states.d.ts +3 -5
  32. package/dist/application-spec/parse-application-files/spec/application/configurator-spec/states.d.ts +3 -8
  33. package/dist/application-spec/parse-application-files/spec/components/bindings/read-binding.d.ts +3 -13
  34. package/dist/application-spec/parse-application-files/spec/components/bindings/write-binding.d.ts +4 -32
  35. package/dist/application-spec/parse-application-files/spec/components/component-filter.d.ts +4 -10
  36. package/dist/application-spec/parse-application-files/spec/components/components.d.ts +3 -4
  37. package/dist/application-spec/parse-application-files/spec/components/index.d.ts +1 -2
  38. package/dist/application-spec/parse-application-files/spec/components/index.js +1 -1
  39. package/dist/application-spec/parse-application-files/spec/components/sdk-component-entry.d.ts +1 -1
  40. package/dist/application-spec/parse-application-files/spec/components/user-component-entry.d.ts +2 -3
  41. package/dist/application-spec/parse-application-files/spec/components/user-component-entry.js +1 -1
  42. package/dist/application-spec/parse-application-files/spec/components/user-components.d.ts +2 -3
  43. package/dist/application-spec/parse-application-files/spec/expressions/expression-read-types.d.ts +2 -2
  44. package/dist/application-spec/parse-application-files/spec/expressions/expressions.d.ts +7 -29
  45. package/dist/application-spec/parse-application-files/spec/expressions/index.d.ts +0 -1
  46. package/dist/application-spec/parse-application-files/spec/expressions/memo-eval-plan.d.ts +4 -71
  47. package/dist/application-spec/parse-application-files/spec/expressions/memo-eval-plan.js +1 -1
  48. package/dist/application-spec/parse-application-files/spec/expressions/user-expressions.d.ts +2 -2
  49. package/dist/application-spec/parse-application-files/spec/invariants/invariant.d.ts +5 -21
  50. package/dist/application-spec/parse-application-files/spec/invariants/invariants.d.ts +4 -14
  51. package/dist/application-spec/parse-application-files/spec/sections/actions.d.ts +6 -23
  52. package/dist/application-spec/parse-application-files/spec/sections/app-metadata.d.ts +3 -18
  53. package/dist/application-spec/parse-application-files/spec/sections/application-version.d.ts +3 -7
  54. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  55. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant.js +1 -1
  56. package/dist/application-spec/parse-application-files/spec/sections/data-spec/chunks.d.ts +6 -23
  57. package/dist/application-spec/parse-application-files/spec/sections/data-spec/custom-data-spec.d.ts +1 -16
  58. package/dist/application-spec/parse-application-files/spec/sections/data-spec/data-entry-key.d.ts +3 -9
  59. package/dist/application-spec/parse-application-files/spec/sections/data-spec/data-spec.d.ts +1 -10
  60. package/dist/application-spec/parse-application-files/spec/sections/data-spec/swatch-data-spec.d.ts +1 -14
  61. package/dist/application-spec/parse-application-files/spec/sections/state-value.d.ts +3 -7
  62. package/dist/application-spec/parse-application-files/spec/sections/theme.d.ts +3 -10
  63. package/dist/application-spec/parse-application-files/spec/sections/transformers.d.ts +4 -11
  64. package/dist/application-spec/parse-application-files/spec/sections/ui.d.ts +3 -12
  65. package/dist/configurator/ConfiguratorApp.js +1 -1
  66. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  67. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +19 -3
  68. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
  69. package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.d.ts +70 -56
  70. package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.js +1 -1
  71. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +15 -0
  72. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  73. package/dist/configurator/application-runtime/extensions/systems/graphql-system/violations.d.ts +40 -0
  74. package/dist/configurator/application-runtime/extensions/systems/graphql-system/violations.js +1 -0
  75. package/dist/configurator/common/configurator-interface.d.ts +2 -2
  76. package/dist/configurator/common/configurator-interface.js +1 -1
  77. package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.js +1 -1
  78. package/dist/configurator/configurator-context/index.d.ts +0 -1
  79. package/dist/configurator/configurator-context/index.js +1 -1
  80. package/dist/configurator/pages/NewConfiguratorPage.js +1 -1
  81. package/dist/configurator/ui/assistant/AssistantChips.js +1 -1
  82. package/dist/configurator/ui/assistant/tool-chip.d.ts +19 -9
  83. package/dist/configurator/ui/assistant/tool-chip.js +1 -1
  84. package/dist/configurator/ui/configurator-layout/universal/DesktopPreview.js +1 -1
  85. package/dist/configurator/ui/configurator-layout/universal/MobilePreview.js +1 -1
  86. package/dist/configurator/ui/legacy/layout/common/CommonTopNavigation.js +1 -1
  87. package/dist/configurator/ui/legacy/layout/simple/SimpleTopNavigation.js +1 -1
  88. package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.js +1 -1
  89. package/dist/configurator/ui/legacy/layout/steps/StepsOwnerLayout.js +1 -1
  90. package/dist/configurator/ui/phoenix-layout-elements/header/common/back-button/use-go-back-action.js +1 -1
  91. package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.js +1 -1
  92. package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/basic/use-basic-sidebar-footer.js +1 -1
  93. package/dist/configurator/ui/preset-layout/CategoryPresetUi.js +1 -1
  94. package/dist/configurator/ui/save-message-snackbars/SaveMessageSnackbars.js +1 -1
  95. package/dist/docs/drag-and-drop/room-planner.mdx +1 -1
  96. package/dist/docs/index.json +1 -1
  97. package/dist/docs/phoenix/configurator-interface.mdx +1 -1
  98. package/dist/docs/phoenix/layout-slots.mdx +21 -0
  99. package/dist/docs/phoenix/phoenix-cli.mdx +1 -0
  100. package/dist/domain/application/application-config.d.ts +6 -24
  101. package/dist/domain/application/assistant/assistant-manifest.d.ts +13 -3
  102. package/dist/domain/application/assistant/assistant-manifest.js +1 -1
  103. package/dist/domain/application/assistant/assistant-resolved-manifest.d.ts +5 -9
  104. package/dist/domain/application/assistant/assistant-resolved-manifest.js +1 -1
  105. package/dist/domain/application/assistant/build-assistant-lenses.js +1 -1
  106. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  107. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  108. package/dist/domain/application/assistant/index.d.ts +3 -3
  109. package/dist/domain/application/assistant/index.js +1 -1
  110. package/dist/domain/application/assistant/session-setup/apply-assistant-setup.js +1 -1
  111. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.d.ts +2 -4
  112. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.js +1 -1
  113. package/dist/domain/application/assistant-mutations.js +1 -1
  114. package/dist/domain/available-system-components/available-system-components.d.ts +11 -0
  115. package/dist/domain/available-system-components/available-system-components.js +1 -0
  116. package/dist/domain/available-system-components/index.d.ts +1 -0
  117. package/dist/domain/available-system-components/index.js +1 -0
  118. package/dist/domain/{domain-builder.d.ts → domain-builder/domain-builder.d.ts} +2 -2
  119. package/dist/domain/domain-builder/domain-builder.js +1 -0
  120. package/dist/domain/domain-builder/index.d.ts +1 -0
  121. package/dist/domain/domain-builder/index.js +1 -0
  122. package/dist/domain/index.d.ts +2 -2
  123. package/dist/domain/index.js +1 -1
  124. package/dist/domain/spec/application/admin-pages-section.d.ts +29 -0
  125. package/dist/domain/spec/application/admin-pages.d.ts +26 -0
  126. package/dist/domain/spec/application/admin-states.d.ts +5 -0
  127. package/dist/domain/spec/application/admin-states.js +1 -0
  128. package/dist/domain/spec/application/configurator-states.d.ts +8 -0
  129. package/dist/domain/spec/application/configurator-states.js +1 -0
  130. package/dist/domain/spec/application/index.d.ts +4 -0
  131. package/dist/domain/spec/components/bindings/index.d.ts +2 -0
  132. package/dist/domain/spec/components/bindings/index.js +1 -0
  133. package/dist/domain/spec/components/bindings/read-binding.d.ts +13 -0
  134. package/dist/domain/spec/components/bindings/read-binding.js +1 -0
  135. package/dist/domain/spec/components/bindings/write-binding.d.ts +32 -0
  136. package/dist/domain/spec/components/bindings/write-binding.js +1 -0
  137. package/dist/{application-spec/parse-application-files → domain}/spec/components/component-entry.d.ts +3 -3
  138. package/dist/domain/spec/components/component-entry.js +1 -0
  139. package/dist/domain/spec/components/component-filters.d.ts +10 -0
  140. package/dist/domain/spec/components/component-filters.js +1 -0
  141. package/dist/domain/spec/components/components.d.ts +4 -0
  142. package/dist/domain/spec/components/components.js +1 -0
  143. package/dist/domain/spec/components/index.d.ts +4 -0
  144. package/dist/domain/spec/{enhanced-json-value.d.ts → enhanced-json/enhanced-json-value.d.ts} +1 -1
  145. package/dist/domain/spec/enhanced-json/index.d.ts +1 -0
  146. package/dist/domain/spec/enhanced-json/index.js +1 -0
  147. package/dist/{application-spec/parse-application-files → domain}/spec/expressions/expression.d.ts +9 -3
  148. package/dist/domain/spec/expressions/expression.js +1 -0
  149. package/dist/domain/spec/expressions/expressions.d.ts +27 -0
  150. package/dist/domain/spec/expressions/expressions.js +1 -0
  151. package/dist/domain/spec/expressions/index.d.ts +3 -0
  152. package/dist/domain/spec/expressions/memo-eval-plan.d.ts +70 -0
  153. package/dist/domain/spec/expressions/memo-eval-plan.js +1 -0
  154. package/dist/domain/spec/index.d.ts +3 -1
  155. package/dist/domain/spec/index.js +1 -1
  156. package/dist/domain/spec/invariants/index.d.ts +2 -0
  157. package/dist/domain/spec/invariants/index.js +1 -0
  158. package/dist/domain/spec/invariants/invariant.d.ts +24 -0
  159. package/dist/domain/spec/invariants/invariant.js +1 -0
  160. package/dist/domain/spec/invariants/invariants.d.ts +14 -0
  161. package/dist/domain/spec/invariants/invariants.js +1 -0
  162. package/dist/domain/spec/markers/index.d.ts +1 -0
  163. package/dist/domain/spec/markers/index.js +1 -1
  164. package/dist/domain/spec/model/defaults.d.ts +1 -1
  165. package/dist/domain/spec/sections/actions.d.ts +23 -0
  166. package/dist/domain/spec/sections/actions.js +1 -0
  167. package/dist/domain/spec/sections/app-metadata.d.ts +18 -0
  168. package/dist/domain/spec/sections/app-metadata.js +1 -0
  169. package/dist/domain/spec/sections/application-version.d.ts +7 -0
  170. package/dist/domain/spec/sections/application-version.js +1 -0
  171. package/dist/domain/spec/sections/data-spec/chunks.d.ts +23 -0
  172. package/dist/domain/spec/sections/data-spec/chunks.js +1 -0
  173. package/dist/domain/spec/sections/data-spec/custom-data-spec-entry.d.ts +16 -0
  174. package/dist/domain/spec/sections/data-spec/custom-data-spec-entry.js +1 -0
  175. package/dist/domain/spec/sections/data-spec/data-entry-key.d.ts +9 -0
  176. package/dist/domain/spec/sections/data-spec/data-entry-key.js +1 -0
  177. package/dist/domain/spec/sections/data-spec/index.d.ts +5 -0
  178. package/dist/domain/spec/sections/data-spec/index.js +1 -0
  179. package/dist/domain/spec/sections/data-spec/parsed-data-spec-entries.d.ts +10 -0
  180. package/dist/domain/spec/sections/data-spec/parsed-data-spec-entries.js +1 -0
  181. package/dist/domain/spec/sections/data-spec/swatch-data-spec-entry.d.ts +14 -0
  182. package/dist/domain/spec/sections/data-spec/swatch-data-spec-entry.js +1 -0
  183. package/dist/domain/spec/sections/index.d.ts +9 -0
  184. package/dist/domain/spec/sections/index.js +1 -0
  185. package/dist/domain/spec/sections/infra/acl.d.ts +12 -0
  186. package/dist/domain/spec/sections/infra/acl.js +1 -0
  187. package/dist/domain/spec/sections/infra/index.d.ts +3 -0
  188. package/dist/domain/spec/sections/infra/index.js +1 -0
  189. package/dist/domain/spec/sections/infra/resource-entry.d.ts +46 -0
  190. package/dist/domain/spec/sections/infra/resource-entry.js +1 -0
  191. package/dist/domain/spec/sections/infra/resources-config.d.ts +10 -0
  192. package/dist/domain/spec/sections/infra/resources-config.js +1 -0
  193. package/dist/domain/spec/sections/state-value.d.ts +7 -0
  194. package/dist/domain/spec/sections/state-value.js +1 -0
  195. package/dist/domain/spec/sections/theme.d.ts +10 -0
  196. package/dist/domain/spec/sections/theme.js +1 -0
  197. package/dist/domain/spec/sections/transformers.d.ts +15 -0
  198. package/dist/domain/spec/sections/transformers.js +1 -0
  199. package/dist/domain/spec/sections/ui.d.ts +12 -0
  200. package/dist/domain/spec/sections/ui.js +1 -0
  201. package/dist/domain/system-definitions.js +1 -1
  202. package/dist/domain/utils/index.d.ts +2 -0
  203. package/dist/domain/utils/index.js +1 -0
  204. package/dist/editor/graphql/GraphQLPanel.js +1 -1
  205. package/dist/phoenix/services/application-spec-project-watcher.js +1 -1
  206. package/dist/react-sdk/domain-application-context/ConfigurationPersistSystemFailureHandler.js +1 -1
  207. package/dist/react-sdk/index.d.ts +2 -0
  208. package/dist/react-sdk/index.js +1 -1
  209. package/dist/react-sdk/lifecycle-providers/ConfiguratorDataProvider.d.ts +8 -0
  210. package/dist/react-sdk/lifecycle-providers/ConfiguratorDataProvider.js +1 -0
  211. package/dist/react-sdk/lifecycle-providers/index.d.ts +1 -0
  212. package/dist/react-sdk/lifecycle-providers/index.js +1 -1
  213. package/dist/react-sdk/notifications/index.d.ts +1 -0
  214. package/dist/react-sdk/notifications/index.js +1 -0
  215. package/dist/react-sdk/notifications/snackbar-action-button.d.ts +30 -0
  216. package/dist/react-sdk/notifications/snackbar-action-button.js +1 -0
  217. package/dist/react-sdk/preset-selection/PresetSelectionProvider.js +1 -0
  218. package/dist/react-sdk/preset-selection/index.d.ts +1 -0
  219. package/dist/react-sdk/preset-selection/index.js +1 -0
  220. package/dist/ui-sdk/components/snackbar/Snackbar.d.ts +24 -3
  221. package/dist/ui-sdk/components/snackbar/Snackbar.js +1 -1
  222. package/dist/watch/glob-matcher.d.ts +4 -4
  223. package/dist/watch/glob-matcher.js +1 -1
  224. package/dist/watch/watch.d.ts +4 -4
  225. package/dist/watch/watch.js +1 -1
  226. package/package.json +3 -3
  227. package/dist/configurator/configurator-context/ConfiguratorDataProvider.d.ts +0 -2
  228. package/dist/configurator/configurator-context/ConfiguratorDataProvider.js +0 -1
  229. package/dist/configurator/configurator-context/PresetSelectionProvider.js +0 -1
  230. package/dist/domain/available-system-components.d.ts +0 -11
  231. package/dist/domain/available-system-components.js +0 -1
  232. package/dist/domain/domain-builder.js +0 -1
  233. /package/dist/{application-spec/parse-application-files/spec/components/component-entry.js → domain/spec/application/admin-pages-section.js} +0 -0
  234. /package/dist/{application-spec/parse-application-files/spec/expressions/expression.js → domain/spec/application/admin-pages.js} +0 -0
  235. /package/dist/domain/spec/{enhanced-json-value.js → enhanced-json/enhanced-json-value.js} +0 -0
  236. /package/dist/{application-spec/parse-application-files/spec/components → domain/spec/markers}/component-prop-target.d.ts +0 -0
  237. /package/dist/{application-spec/parse-application-files/spec/components → domain/spec/markers}/component-prop-target.js +0 -0
  238. /package/dist/{configurator/configurator-context → react-sdk/preset-selection}/PresetSelectionProvider.d.ts +0 -0
@@ -1 +1 @@
1
- import{findAssistantFieldOptions as e,findAssistantRecipeGroups as t,modifyEntityUpdateTag as i,prepareAssistantRecipeUpdates as r,readAssistantFieldOptions as n,readAssistantRecipeGroup as o,systemUpdateFactory as s}from"#package/domain";import{readSideEffects as a}from"./side-effects.js";let d=e=>({ok:!1,root:null,changedEntities:[],deletedEntityIds:[],sideEffects:[],errors:e}),l=(e,{state:t},{recipes:i,prepareStateEmission:r,find$Entity:n})=>{let{validity:o,state:s,updates:l}=r(e,t,"committed");if(o.valid){let e=new Map(t.entities.map(e=>[e.id,e])),r=new Set(s.entities.map(e=>e.id));return{ok:!0,root:n(s.rootEntityId,s),changedEntities:s.entities.filter(t=>e.get(t.id)!==t).flatMap(e=>n(e.id,s)??[]),deletedEntityIds:t.entities.map(e=>e.id).filter(e=>!r.has(e)),sideEffects:a(l,i.resolveLocalizable),errors:[]}}return d("uncaught"===o.severity?[{type:"uncaught",entityId:null,message:o.error.message}]:o.entityViolations.filter(({violation:e})=>e.severity===o.severity).map(({entityId:e,violation:t})=>({type:t.type,entityId:e,message:void 0===t.message?null:i.resolveLocalizable(t.message)})))};export const createEntityMeta=(a,u)=>{let c=e=>()=>t(u.manifest,e,a.entity.type).flatMap(t=>{let i=o(e,t,a.entity.id,a.state,u.recipes);return i?[((e,t,i)=>{let{group:n,label:o,description:s,recipes:a}=e,{resolveLocalizable:u}=i.recipes;return{groupId:n.groupId,name:void 0===o?n.instanceName:u(o),description:n.description??(void 0===s?null:u(s)),recipes:a.map(n=>((e,t,i,n)=>{let{key:o,item:s}=e,{resolveLocalizable:a}=n.recipes;return{key:o,name:a(s.title),description:void 0===s.description?null:a(s.description),imageUrl:void 0===s.thumbnailUrl?null:a(s.thumbnailUrl),dryRun:()=>t.group.dryRuns?((e,t,i,n)=>{let{updates:o,error:s}=((e,t,{entity:i,state:n},{recipes:o})=>{try{return{updates:r(e,t,i.id,n,o),error:void 0}}catch(e){if("child"===t.target.kind)throw e;return{updates:void 0,error:e instanceof Error?e.message:String(e)}}})(e,t,i,n);return void 0===o?d([{type:"uncaught",entityId:null,message:s}]):l(o,i,n)})(e,t,i,n):null}})(n,e,t,i))}})(i,a,u)]:[]});return{...Object.fromEntries(e(u.manifest,a.entity.type).map(e=>[e.edgeName,()=>n(e,a.entity.id,a.state,u.recipes)?.map(t=>({...t,dryRun:()=>e.dryRuns?(({field:e},{value:t},r,n)=>{let{entity:o}=r,a=Object.entries(Object.entries(n.manifest.writableFields??{}).find(([e])=>e===o.type)?.[1]??{}).find(([t])=>t===e)?.[1];if(void 0===a)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: the schema lists them, but the configurator has no writable field "${e}" on ${o.type}. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let u=r.state.entities.find(e=>e.id===o.id);if(!u)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: entity "${o.id}" does not exist. It may have been deleted by an earlier operation or field. Query the current entities and use an id they return.`);let c={[a]:t},p=n.validateEntity({...u,...c});return p.success?l([s.DomainEntityModification({entityId:o.id,stateDelta:c,updateTag:i})],r,n):d([{type:"uncaught",entityId:o.id,message:`Writing ${JSON.stringify(t)} to "${e}" would make "${o.id}" an invalid ${o.type}: ${p.errors.join("; ")}. The option comes from the configurator and cannot be corrected from here, so do not write it.`}])})(e,t,a,u):null}))??null])),childRecipes:c("child"),replaceRecipes:c("replace"),screenshot:({view:e})=>u.takeScreenshot(a,e)}};
1
+ import e from"lodash-es/isEqual.js";import{findAssistantFieldOptions as t,findAssistantRecipeGroups as i,modifyEntityUpdateTag as r,prepareAssistantRecipeUpdates as n,readAssistantFieldOptions as o,readAssistantRecipeGroup as a,systemUpdateFactory as s}from"#package/domain";import{readSideEffects as d}from"./side-effects.js";import{readEntityWarnings as l,readStateWarnings as c,readViolationEntries as u}from"./violations.js";let p=e=>({ok:!1,root:null,changedEntities:[],deletedEntityIds:[],sideEffects:[],warnings:[],errors:e}),m=(e,{state:t},{recipes:i,prepareStateEmission:r,find$Entity:n,validateState:o})=>{let{validity:a,state:s,updates:l}=r(e,t,"committed");if(a.valid){let e=new Map(t.entities.map(e=>[e.id,e])),r=new Set(s.entities.map(e=>e.id));return{ok:!0,root:n(s.rootEntityId,s),changedEntities:s.entities.filter(t=>e.get(t.id)!==t).flatMap(e=>n(e.id,s)??[]),deletedEntityIds:t.entities.map(e=>e.id).filter(e=>!r.has(e)),sideEffects:d(l,i.resolveLocalizable),warnings:()=>c(a,o(t),i.resolveLocalizable),errors:[]}}return p(u(a,i.resolveLocalizable))};export const createEntityMeta=(d,c)=>{let u=e=>()=>Object.fromEntries(i(c.manifest,e,d.entity.type).map(t=>[t.groupId,()=>{let i=a(e,t,d.entity.id,d.state,c.recipes);return i?((e,t,i)=>{let{group:r,label:o,description:a,recipes:s}=e,{resolveLocalizable:d}=i.recipes;return{groupId:r.groupId,name:void 0===o?r.instanceName:d(o),description:void 0===a?null:d(a),recipes:({keys:r})=>s.filter(e=>!r||r.includes(e.key)).map(r=>((e,t,i,r)=>{let{key:o,item:a}=e,{resolveLocalizable:s}=r.recipes;return{key:o,name:s(a.title),description:void 0===a.description?null:s(a.description),imageUrl:void 0===a.thumbnailUrl?null:s(a.thumbnailUrl),dryRun:()=>t.group.dryRuns?((e,t,i,r)=>{let{updates:o,error:a}=((e,t,{entity:i,state:r},{recipes:o})=>{try{return{updates:n(e,t,i.id,r,o),error:void 0}}catch(e){if("child"===t.target.kind)throw e;return{updates:void 0,error:e instanceof Error?e.message:String(e)}}})(e,t,i,r);return void 0===o?p([{type:"uncaught",entityId:null,message:a}]):m(o,i,r)})(e,t,i,r):null}})(r,e,t,i))}})(i,d,c):null}]));return{...Object.fromEntries(t(c.manifest,d.entity.type).map(t=>[t.edgeName,({values:i})=>o(t,d.entity.id,d.state,c.recipes)?.filter(t=>!i||i.some(i=>e(i,t.value))).map(e=>({...e,dryRun:()=>t.dryRuns?(({field:e},{value:t},i,n)=>{let{entity:o}=i,a=Object.entries(Object.entries(n.manifest.writableFields??{}).find(([e])=>e===o.type)?.[1]??{}).find(([t])=>t===e)?.[1];if(void 0===a)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: the schema lists them, but the configurator has no writable field "${e}" on ${o.type}. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let d=i.state.entities.find(e=>e.id===o.id);if(!d)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: entity "${o.id}" does not exist. It may have been deleted by an earlier operation or field. Query the current entities and use an id they return.`);let l={[a]:t},c=n.validateEntity({...d,...l});return c.success?m([s.DomainEntityModification({entityId:o.id,stateDelta:l,updateTag:r})],i,n):p([{type:"uncaught",entityId:o.id,message:`Writing ${JSON.stringify(t)} to "${e}" would make "${o.id}" an invalid ${o.type}: ${c.errors.join("; ")}. The option comes from the configurator and cannot be corrected from here, so do not write it.`}])})(t,e,d,c):null}))??null])),childRecipes:u("child"),replaceRecipes:u("replace"),screenshot:({view:e})=>c.takeScreenshot(d,e),warnings:()=>l(d.entity.id,c.validateState(d.state),c.recipes.resolveLocalizable)}};
@@ -1,6 +1,7 @@
1
1
  import { type ExecutionResult } from 'graphql';
2
2
  import { type Localizable } from '@salsita-ai/common/utils';
3
3
  import { type $DomainEntity, type AgentScreenshotComponent, type ComponentSnapshot, type DomainContextSelectors, type DomainEntity, type DomainServicesSelectors, type DomainState, type InitializationGeneration, type SessionAssistantSetup, type SpecSelectors, type StateUpdateEmission } from '#package/domain';
4
+ import { type AssistantWarning } from './violations.js';
4
5
  /** One single-operation GraphQL document with its own variables, as executed by {@link GraphQLSystem}. */
5
6
  export interface GraphQLOperation {
6
7
  readonly document: string;
@@ -61,6 +62,12 @@ export interface GraphQLExecution {
61
62
  readonly message?: string;
62
63
  /** What the configurator did, or would do, beyond what the operations asked for, in applied order. */
63
64
  readonly sideEffects: readonly string[];
65
+ /**
66
+ * The warnings and notices the prepared changes newly cause, whether or not they were committed:
67
+ * those of the prepared state that the state the operations started from did not have. Empty when
68
+ * nothing changed or an operation failed.
69
+ */
70
+ readonly warnings: readonly AssistantWarning[];
64
71
  /**
65
72
  * The state the operations prepared, when it was committed or held for the user's approval; a
66
73
  * held state is the one committed if the user approves. A caller can recognize its own change in
@@ -97,6 +104,8 @@ export declare class GraphQLSystem {
97
104
  constructor(_context: GraphQLSystemContext);
98
105
  private readonly _get$Entity;
99
106
  private readonly _find$Entity;
107
+ private readonly _validateState;
108
+ private readonly _validateCached;
100
109
  private readonly _recipeContext;
101
110
  /** Root field resolvers, called by the executor with the field arguments and the operation context. */
102
111
  private readonly _rootValue;
@@ -151,6 +160,12 @@ export declare class GraphQLSystem {
151
160
  readSideEffects: (prepared: readonly PreparedOperation[]) => readonly string[];
152
161
  /** The screenshots of prepared operations, by label, in the order they were taken. */
153
162
  readScreenshots: (prepared: readonly PreparedOperation[]) => ReadonlyMap<string, GraphQLScreenshot>;
163
+ /**
164
+ * The warnings and notices prepared operations newly cause: those of the state their last emission
165
+ * left that `originalState`, the state they were prepared from, did not have. Empty when nothing
166
+ * changed or an operation failed, so the original state is validated only for a change.
167
+ */
168
+ readWarnings: (originalState: AnyDomainState, prepared: readonly PreparedOperation[]) => readonly AssistantWarning[];
154
169
  private readonly _prepareAndCommit;
155
170
  /**
156
171
  * Prepares the operations from the committed state and commits their changes as one emission,
@@ -1 +1 @@
1
- import{GraphQLError as e,NoSchemaIntrospectionCustomRule as t,defaultFieldResolver as i,execute as n,getNamedType as o,parse as r,specifiedRules as s,validate as a,validateSchema as l}from"graphql";import{assertExistence as c,createSelector as h,isMessageDescriptor as d,isMultilingualString as u}from"@salsita-ai/common/utils";import{DomainEntityIdSchema as f,agentScreenshotComponent as m,createAssistantExecutionSchema as p,findAssistantMutation as g}from"#package/domain";import{ExportBusyError as y}from"../export-system/export-busy-error.js";import{closeUnclosedBraces as v}from"./close-unclosed-braces.js";import{createEntityMeta as S}from"./entity-meta.js";import{injectAssistantLenses as _}from"./inject-assistant-lenses.js";import{readSideEffects as w}from"./side-effects.js";let x={errors:[new e("The configurator does not provide this request. This is a fault in the configurator, not in your request. Tell the user this is not available.")]},$={errors:[new e("The configuration is not loaded yet, so there is no state to query. Run the query again once the configurator has finished loading.")]},b="Not taken: another configuration was loaded while this request ran. Query the current configuration before asking for screenshots again.",E=new RegExp(f.pattern),T=[...s,t],C=e=>"object"==typeof e&&null!==e&&"type"in e&&"string"==typeof e.type&&"id"in e&&"string"==typeof e.id,M=(e,t)=>"object"==typeof e&&null!==e?Reflect.get(e,t):void 0,j=e=>e instanceof Error?e.message:String(e),k=e=>/[.!?]$/.test(e)?e:`${e}.`,R=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype,N=(e,t)=>{let i=R(e)?e._raw:void 0;if(C(i))return i;if(!Array.isArray(e)&&!R(e))return e;if(t.has(e))throw Error("The value contains itself.");let n=new Set([...t,e]);return Array.isArray(e)?e.map(e=>N(e,n)):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,N(t,n)]))};export const localize=(e,t)=>Array.isArray(e)?e.map(e=>localize(e,t)):"string"==typeof e||d(e)||u(e)?t(e):e;let A=t=>new e(`The configurator cannot handle this request: ${k(t)} This is a fault in the configurator, not in your request. Tell the user this is not available.`),q="SCREENSHOT_NOT_TAKEN",z=(t,i)=>new e(t,{originalError:i,extensions:{code:q}}),L=e=>(e.errors??[]).some(e=>e.extensions.code!==q),F=t=>({errors:[new e(`Not run: operation ${t+1} failed, so the operations after it were skipped and no change of the list takes effect. Fix the failing operation and send the whole list again.`)]});export class GraphQLSystem{_context;_selectSchema=h([h.leaf(e=>e)],e=>{try{let t=p(e),i=l(t);return i.length>0?A(i.map(e=>e.message).join(" ")):t}catch(e){return A(j(e))}});_selectLenses=h([h.leaf(e=>e)],e=>r(e));_selectFieldResolver=h([h.leaf(e=>e)],t=>(n,r,s,a)=>{if(a.parentType===a.schema.getQueryType())return i(n,r,s,a);if(a.parentType===a.schema.getMutationType())return this._resolveMutation(a.fieldName,String(a.path.key),r,s);if(!C(n))return i(n,r,s,a);if("meta"===a.fieldName){let e;return S({entity:n,state:("object"==typeof(e=M(n,"_state"))&&null!==e&&"entities"in e&&"rootEntityId"in e?e:void 0)??s.state},{manifest:s.manifest,recipes:this._recipeContext(),prepareStateEmission:(e,t,i)=>this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(e,t,i),find$Entity:(e,t)=>this._find$Entity(e,t),validateEntity:e=>this._context.domainContextSelectors.getDomain().validateEntity(e),takeScreenshot:(e,t)=>this._takeScreenshot(e,t,s)})}let{source:l,localized:c}=t[a.parentType.name]?.[a.fieldName]??{source:a.fieldName},h=((t,i)=>{try{return M(t,i)}catch(n){throw new e(`Expression "${i}" failed on ${C(t)?t.id:"an entity"}: ${k(j(n))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:n instanceof Error?n:void 0})}})(n,l);return c?localize(h,this._context.domainServicesSelectors.getResolveLocalizable()):l.startsWith("$")&&"JSON"===o(a.returnType).name?((t,i,n)=>{try{return N(n,new Set)}catch(n){throw new e(`Expression "${i}" returned a value that is not plain serializable data on ${C(t)?t.id:"an entity"}: ${k(j(n))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:n instanceof Error?n:void 0})}})(n,l,h):h});constructor(e){this._context=e}_get$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().get$Entity(e,t);_find$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().getEntity(e,t)?this._get$Entity(e,t):null;_recipeContext=()=>({componentReader:this._context.domainContextSelectors.getComponentReader(),recipeCooker:this._context.domainContextSelectors.getRecipeCookerSystem(),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});_rootValue={root:(e,{state:t})=>this._get$Entity(t.rootEntityId,t),entities:({ids:t},{state:i})=>{if(null==t)return i.entities.map(e=>this._get$Entity(e.id,i));var n=i.rootEntityId;let o=t.filter(e=>!E.test(e));if(o.length>0)throw new e(`${o.map(e=>`"${e}"`).join(", ")} ${1===o.length?"is not an entity id":"are not entity ids"}. Entity ids have the form "<Type>-<number>", e.g. "${n}". Use ids as returned by the "id" field.`);return t.map(e=>E.test(e)?this._find$Entity(e,i):null)},selectedEntity:(e,{state:t})=>this._find$Entity(this._context.domainContextSelectors.getNavigationSystem().getActiveSelectionState(t),t),navigation:(e,{state:t})=>{let i=this._context.domainContextSelectors.getNavigationSystem();return{navigationState:i.getActiveNavigationState(t),viewState:i.getActiveViewState(t),toolState:i.getActiveToolState(t)}}};_resolveType=e=>C(e)?e.type:void 0;_generation={active:!0};_renderScreenshot=async(e,t,i)=>{let n=this._context.domainContextSelectors.getComponentReader().readOneComponent({entityId:e,componentType:m,instanceName:t},i);if(!n)return null;let o=await this._context.renderScreenshot(n,i);return null===o?null:new Blob([o],{type:"JPEG"===n.state.fileFormat?"image/jpeg":"image/png"})};initialize=()=>{this._generation.active=!1,this._generation={active:!0}};_resolveMutation=(t,i,n,o)=>{if(void 0!==o.failedMutationField)throw new e(`Not run: the earlier field "${o.failedMutationField}" of this operation failed, so "${i}" was skipped and no change of the operation takes effect. Fix the failing field and send the operation again.`);try{return this._runMutation(t,n,o)}catch(e){throw o.failedMutationField=i,e}};_runMutation=(t,i,n)=>{let o=g(t,n.manifest);if(!o)throw new e(`The schema declares the mutation "${t}", but the configurator has no implementation for it. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let r=n.state,s=o.implementation(i,r,{manifest:n.manifest,action:this._context.domainContextSelectors.getActionSystem().createContext(r),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});if(s.updates.length>0){let i=this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(s.updates,r,"committed");if(!i.validity.valid)throw new e(`The changes of "${t}" were not applied, because the resulting configuration is invalid: ${(e=>{if("uncaught"===e.severity)return`validating it threw: ${k(j(e.error))}`;let t=[...new Set(e.entityViolations.filter(({violation:t})=>t.severity===e.severity).map(({entityId:e})=>e))];return`it has ${e.severity} violations on ${t.join(", ")}.`})(i.validity)} Change the request so the configuration stays valid.`);n.emissions.push(i),n.state=i.state}return s.readResult({previousState:r,state:n.state})};_takeScreenshot=({entity:t,state:i},n,o)=>{let r=o.manifest.screenshots?.[t.type]?.find(e=>e.view===n);if(!r)return Promise.reject(new e(`The schema declares the screenshot view "${n}" on ${t.type}, but the configurator has no view of that name. This is a fault in the configurator, not in your request. Tell the user this is not available.`));let s=o.lastScreenshot.then(async()=>{if(!o.generation.active)throw z(b);let e=await this._renderScreenshot(t.id,r.instanceName,i).catch(e=>{throw z(e instanceof y?"User made concurrent actions that prevented the screenshot from being taken, try again":`The screenshot of ${t.id} from "${n}" could not be taken: ${k(j(e))} Try again; if it fails again, tell the user the screenshot is not available.`,e instanceof Error?e:void 0)});if(!o.generation.active)throw z(b);if(null===e)return null;let{imageId:s}=await this._context.uploadScreenshot(e).catch(e=>{throw z(`The screenshot of ${t.id} from "${n}" was taken but could not be stored: ${k(j(e))} Try again; if it fails again, tell the user the screenshot is not available.`,e instanceof Error?e:void 0)}),a=`${t.id}/${n}`,l=[...o.screenshots.values()].filter(e=>e.entityId===t.id&&e.view===n).length,c=0===l?a:`${a}#${l+1}`;return o.screenshots.set(c,{entityId:t.id,view:n,imageId:s}),{image:c}});return o.lastScreenshot=s.catch(()=>void 0),s};_setup=()=>{let{manifest:t,error:i}=this._context.getAssistantSetup();if(i)return{ready:!1,result:{errors:[new e(i.message,{originalError:i})]}};if(!t)return{ready:!1,result:x};let n=this._selectSchema(t.sdl);return n instanceof e?{ready:!1,result:{errors:[n]}}:{ready:!0,assistant:t,schema:n,lenses:t.lenses?.definitions?this._selectLenses(t.lenses.definitions):void 0,fieldResolver:this._selectFieldResolver(t.fields)}};_run=(t,i,o,s)=>{let l;try{l=r(t)}catch(t){return{errors:[t instanceof e?t:new e(j(t))]}}let c=a(o.schema,l,T);return c.length>0?{errors:c}:n({schema:o.schema,document:l,rootValue:this._rootValue,contextValue:s,variableValues:i.variables,operationName:i.operationName,fieldResolver:o.fieldResolver,typeResolver:this._resolveType})};prepare=async(t,i,n=this._generation)=>{let o,r=this._setup();if(!r.ready)return i.map(()=>({result:r.result,emissions:[],screenshots:new Map}));let s={manifest:r.assistant,state:t,emissions:[],failedMutationField:void 0,screenshots:new Map,lastScreenshot:Promise.resolve(),generation:n},a=[];for(let[t,n]of i.entries())if(void 0===o){let i=s.emissions.length,l=s.screenshots.size;s.failedMutationField=void 0;let c=v(n.document),h=r.lenses?_(c,r.lenses):c,d=h instanceof e?{errors:[h]}:await this._run(h,n,r,s);await s.lastScreenshot,a.push({result:d,emissions:s.emissions.slice(i),screenshots:new Map([...s.screenshots].slice(l))}),L(d)&&(o=t)}else a.push({result:F(o),emissions:[],screenshots:new Map});return a};readSideEffects=e=>{let t=this._context.domainServicesSelectors.getResolveLocalizable();return e.flatMap(({emissions:e})=>e.flatMap(e=>w(e.updates,t)))};readScreenshots=e=>new Map(e.flatMap(({screenshots:e})=>[...e]));_prepareAndCommit=async(e,t)=>{let i,n,o,r=this._context.domainContextSelectors.getStoreSystem(),s=await this.prepare(r.stateSlices.committed.value.state,e,t),a=s.map(({result:e})=>e),l=this.readSideEffects(s),h=this.readScreenshots(s),d=s.flatMap(e=>e.emissions);if(!t.active)return{results:a,sideEffects:l,screenshots:h,outcome:"conflict"};if(a.some(L)||0===d.length)return{results:a,sideEffects:l,screenshots:h,outcome:"none"};let u=(i=c(d[0]),n=c(d[d.length-1]),o=d.some(e=>void 0!==e.transformationLog),{kind:"committed",previousState:i.previousState,state:n.state,updates:d.flatMap(e=>e.updates),validity:n.validity,transformationLog:o?d.flatMap(e=>e.transformationLog??[]):void 0});return{results:a,sideEffects:l,screenshots:h,outcome:r.commitPrepared(u),preparedState:u.state}};execute=async e=>{let t=this._generation;if(!this._context.domainContextSelectors.getStoreSystem().isInitialized)return{results:e.map(()=>$),committed:!1,sideEffects:[],screenshots:new Map};let i=await this._prepareAndCommit(e,t),{results:n,sideEffects:o,screenshots:r,outcome:s,preparedState:a}="conflict"===i.outcome&&t.active?await this._prepareAndCommit(e,t):i;return"committed"===s?{results:n,committed:!0,sideEffects:o,screenshots:r,preparedState:a}:"held"===s?{results:n,committed:!1,message:"The changes wait for the user's approval and are not applied yet. Do not send them again; the next `[changes]` block lists them once approved.",sideEffects:o,screenshots:r,preparedState:a}:"conflict"===s?{results:n,committed:!1,message:"The changes were not committed, because the configuration changed while they were being applied. The results describe a state that was discarded. Query the current configuration and send the operations again if they still make sense.",sideEffects:o,screenshots:r}:{results:n,committed:!1,sideEffects:o,screenshots:r}}}
1
+ import{GraphQLError as e,NoSchemaIntrospectionCustomRule as t,defaultFieldResolver as i,execute as n,getNamedType as o,parse as r,specifiedRules as a,validate as s,validateSchema as l}from"graphql";import{assertExistence as c,createSelector as h,isMessageDescriptor as d,isMultilingualString as u}from"@salsita-ai/common/utils";import{DomainEntityIdSchema as m,agentScreenshotComponent as f,createAssistantExecutionSchema as p,findAssistantMutation as g}from"#package/domain";import{ExportBusyError as v}from"../export-system/export-busy-error.js";import{closeUnclosedBraces as y}from"./close-unclosed-braces.js";import{createEntityMeta as S}from"./entity-meta.js";import{injectAssistantLenses as _}from"./inject-assistant-lenses.js";import{readSideEffects as w}from"./side-effects.js";import{ViolationsError as x,readStateWarnings as b,readViolationEntries as E}from"./violations.js";let $={errors:[new e("The configurator does not provide this request. This is a fault in the configurator, not in your request. Tell the user this is not available.")]},T={errors:[new e("The configuration is not loaded yet, so there is no state to query. Run the query again once the configurator has finished loading.")]},C="Not taken: another configuration was loaded while this request ran. Query the current configuration before asking for screenshots again.",M=new RegExp(m.pattern),R=[...a,t],j=e=>"object"==typeof e&&null!==e&&"type"in e&&"string"==typeof e.type&&"id"in e&&"string"==typeof e.id,k=(e,t)=>"object"==typeof e&&null!==e?Reflect.get(e,t):void 0,N=e=>e instanceof Error?e.message:String(e),A=e=>/[.!?]$/.test(e)?e:`${e}.`,z=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype,L=(e,t)=>{let i=z(e)?e._raw:void 0;if(j(i))return i;if(!Array.isArray(e)&&!z(e))return e;if(t.has(e))throw Error("The value contains itself.");let n=new Set([...t,e]);return Array.isArray(e)?e.map(e=>L(e,n)):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,L(t,n)]))};export const localize=(e,t)=>Array.isArray(e)?e.map(e=>localize(e,t)):"string"==typeof e||d(e)||u(e)?t(e):e;let q=t=>new e(`The configurator cannot handle this request: ${A(t)} This is a fault in the configurator, not in your request. Tell the user this is not available.`),O="SCREENSHOT_NOT_TAKEN",F=(t,i)=>new e(t,{originalError:i,extensions:{code:O}}),I=e=>(e.errors??[]).some(e=>e.extensions.code!==O),V=t=>({errors:[new e(`Not run: operation ${t+1} failed, so the operations after it were skipped and no change of the list takes effect. Fix the failing operation and send the whole list again.`)]});export class GraphQLSystem{_context;_selectSchema=h([h.leaf(e=>e)],e=>{try{let t=p(e),i=l(t);return i.length>0?q(i.map(e=>e.message).join(" ")):t}catch(e){return q(N(e))}});_selectLenses=h([h.leaf(e=>e)],e=>r(e));_selectFieldResolver=h([h.leaf(e=>e)],t=>(n,r,a,s)=>{if(s.parentType===s.schema.getQueryType())return i(n,r,a,s);if(s.parentType===s.schema.getMutationType())return this._resolveMutation(s.fieldName,String(s.path.key),r,a);if(!j(n))return i(n,r,a,s);if("meta"===s.fieldName){let e;return S({entity:n,state:("object"==typeof(e=k(n,"_state"))&&null!==e&&"entities"in e&&"rootEntityId"in e?e:void 0)??a.state},{manifest:a.manifest,recipes:this._recipeContext(),prepareStateEmission:(e,t,i)=>{let n=this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(e,t,i);return a.validities.set(n.state,n.validity),n},find$Entity:(e,t)=>this._find$Entity(e,t),validateEntity:e=>this._context.domainContextSelectors.getDomain().validateEntity(e),takeScreenshot:(e,t)=>this._takeScreenshot(e,t,a),validateState:e=>this._validateCached(e,a)})}let{source:l,localized:c}=t[s.parentType.name]?.[s.fieldName]??{source:s.fieldName},h=((t,i)=>{try{return k(t,i)}catch(n){throw new e(`Expression "${i}" failed on ${j(t)?t.id:"an entity"}: ${A(N(n))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:n instanceof Error?n:void 0})}})(n,l);return c?localize(h,this._context.domainServicesSelectors.getResolveLocalizable()):l.startsWith("$")&&"JSON"===o(s.returnType).name?((t,i,n)=>{try{return L(n,new Set)}catch(n){throw new e(`Expression "${i}" returned a value that is not plain serializable data on ${j(t)?t.id:"an entity"}: ${A(N(n))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:n instanceof Error?n:void 0})}})(n,l,h):h});constructor(e){this._context=e}_get$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().get$Entity(e,t);_find$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().getEntity(e,t)?this._get$Entity(e,t):null;_validateState=e=>this._context.domainContextSelectors.getValidationProjections().validateState(e);_validateCached=(e,{validities:t})=>{let i=t.get(e);if(i)return i;let n=this._validateState(e);return t.set(e,n),n};_recipeContext=()=>({componentReader:this._context.domainContextSelectors.getComponentReader(),recipeCooker:this._context.domainContextSelectors.getRecipeCookerSystem(),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});_rootValue={warnings:(e,t)=>b(this._validateCached(t.state,t),void 0,this._context.domainServicesSelectors.getResolveLocalizable()),root:(e,{state:t})=>this._get$Entity(t.rootEntityId,t),entities:({ids:t},{state:i})=>{if(null==t)return i.entities.map(e=>this._get$Entity(e.id,i));var n=i.rootEntityId;let o=t.filter(e=>!M.test(e));if(o.length>0)throw new e(`${o.map(e=>`"${e}"`).join(", ")} ${1===o.length?"is not an entity id":"are not entity ids"}. Entity ids have the form "<Type>-<number>", e.g. "${n}". Use ids as returned by the "id" field.`);return t.map(e=>M.test(e)?this._find$Entity(e,i):null)},selectedEntity:(e,{state:t})=>this._find$Entity(this._context.domainContextSelectors.getNavigationSystem().getActiveSelectionState(t),t),navigation:(e,{state:t})=>{let i=this._context.domainContextSelectors.getNavigationSystem();return{navigationState:i.getActiveNavigationState(t),viewState:i.getActiveViewState(t),toolState:i.getActiveToolState(t)}}};_resolveType=e=>j(e)?e.type:void 0;_generation={active:!0};_renderScreenshot=async(e,t,i)=>{let n=this._context.domainContextSelectors.getComponentReader().readOneComponent({entityId:e,componentType:f,instanceName:t},i);if(!n)return null;let o=await this._context.renderScreenshot(n,i);return null===o?null:new Blob([o],{type:"JPEG"===n.state.fileFormat?"image/jpeg":"image/png"})};initialize=()=>{this._generation.active=!1,this._generation={active:!0}};_resolveMutation=(t,i,n,o)=>{if(void 0!==o.failedMutationField)throw new e(`Not run: the earlier field "${o.failedMutationField}" of this operation failed, so "${i}" was skipped and no change of the operation takes effect. Fix the failing field and send the operation again.`);try{return this._runMutation(t,n,o)}catch(e){throw o.failedMutationField=i,e}};_runMutation=(t,i,n)=>{let o=g(t,n.manifest);if(!o)throw new e(`The schema declares the mutation "${t}", but the configurator has no implementation for it. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let r=n.state,a=o.implementation(i,r,{manifest:n.manifest,action:this._context.domainContextSelectors.getActionSystem().createContext(r),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});if(a.updates.length>0){let i=this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(a.updates,r,"committed"),{validity:o}=i;if("uncaught"===o.severity)throw new e(`The changes of "${t}" were not applied, because the resulting configuration is invalid: validating it threw: ${A(N(o.error))} Change the request so the configuration stays valid.`,{originalError:o.error});if(!o.valid)throw new x(`The changes of "${t}" were not applied, because the resulting configuration has ${o.severity} violations.`,E(o,this._context.domainServicesSelectors.getResolveLocalizable()));n.emissions.push(i),n.validities.set(i.state,o),n.state=i.state}return a.readResult({previousState:r,state:n.state})};_takeScreenshot=({entity:t,state:i},n,o)=>{let r=o.manifest.screenshots?.[t.type]?.find(e=>e.view===n);if(!r)return Promise.reject(new e(`The schema declares the screenshot view "${n}" on ${t.type}, but the configurator has no view of that name. This is a fault in the configurator, not in your request. Tell the user this is not available.`));let a=o.lastScreenshot.then(async()=>{if(!o.generation.active)throw F(C);let e=await this._renderScreenshot(t.id,r.instanceName,i).catch(e=>{throw F(e instanceof v?"User made concurrent actions that prevented the screenshot from being taken, try again":`The screenshot of ${t.id} from "${n}" could not be taken: ${A(N(e))} Try again; if it fails again, tell the user the screenshot is not available.`,e instanceof Error?e:void 0)});if(!o.generation.active)throw F(C);if(null===e)return null;let{imageId:a}=await this._context.uploadScreenshot(e).catch(e=>{throw F(`The screenshot of ${t.id} from "${n}" was taken but could not be stored: ${A(N(e))} Try again; if it fails again, tell the user the screenshot is not available.`,e instanceof Error?e:void 0)}),s=`${t.id}/${n}`,l=[...o.screenshots.values()].filter(e=>e.entityId===t.id&&e.view===n).length,c=0===l?s:`${s}#${l+1}`;return o.screenshots.set(c,{entityId:t.id,view:n,imageId:a}),{image:c}});return o.lastScreenshot=a.catch(()=>void 0),a};_setup=()=>{let{manifest:t,error:i}=this._context.getAssistantSetup();if(i)return{ready:!1,result:{errors:[new e(i.message,{originalError:i})]}};if(!t)return{ready:!1,result:$};let n=this._selectSchema(t.sdl);return n instanceof e?{ready:!1,result:{errors:[n]}}:{ready:!0,assistant:t,schema:n,lenses:t.lenses?.definitions?this._selectLenses(t.lenses.definitions):void 0,fieldResolver:this._selectFieldResolver(t.fields)}};_run=async(t,i,o,a)=>{var l;let c;try{c=r(t)}catch(t){return{errors:[t instanceof e?t:new e(N(t))]}}let h=s(o.schema,c,R);return h.length>0?{errors:h}:(l=await n({schema:o.schema,document:c,rootValue:this._rootValue,contextValue:a,variableValues:i.variables,operationName:i.operationName,fieldResolver:o.fieldResolver,typeResolver:this._resolveType}),l.errors?.some(e=>e.originalError instanceof x)?{...l,errors:l.errors.flatMap(t=>t.originalError instanceof x?t.originalError.entries.map(({type:i,entityId:n,message:o})=>new e(o??i,{nodes:t.nodes,source:t.source,positions:t.positions,path:t.path,extensions:{code:"VIOLATION",type:i,entityId:n}})):[t])}:l)};prepare=async(t,i,n=this._generation)=>{let o,r=this._setup();if(!r.ready)return i.map(()=>({result:r.result,emissions:[],screenshots:new Map}));let a={manifest:r.assistant,state:t,emissions:[],failedMutationField:void 0,screenshots:new Map,lastScreenshot:Promise.resolve(),generation:n,validities:new WeakMap},s=[];for(let[t,n]of i.entries())if(void 0===o){let i=a.emissions.length,l=a.screenshots.size;a.failedMutationField=void 0;let c=y(n.document),h=r.lenses?_(c,r.lenses):c,d=h instanceof e?{errors:[h]}:await this._run(h,n,r,a);await a.lastScreenshot,s.push({result:d,emissions:a.emissions.slice(i),screenshots:new Map([...a.screenshots].slice(l))}),I(d)&&(o=t)}else s.push({result:V(o),emissions:[],screenshots:new Map});return s};readSideEffects=e=>{let t=this._context.domainServicesSelectors.getResolveLocalizable();return e.flatMap(({emissions:e})=>e.flatMap(e=>w(e.updates,t)))};readScreenshots=e=>new Map(e.flatMap(({screenshots:e})=>[...e]));readWarnings=(e,t)=>{let i=t.flatMap(({emissions:e})=>e).at(-1);return void 0===i||t.some(({result:e})=>I(e))?[]:b(i.validity,this._validateState(e),this._context.domainServicesSelectors.getResolveLocalizable())};_prepareAndCommit=async(e,t)=>{let i,n,o,r=this._context.domainContextSelectors.getStoreSystem(),a=r.stateSlices.committed.value.state,s=await this.prepare(a,e,t),l=s.map(({result:e})=>e),h=this.readSideEffects(s),d=this.readScreenshots(s),u=s.flatMap(e=>e.emissions);if(!t.active)return{results:l,sideEffects:h,screenshots:d,warnings:[],outcome:"conflict"};if(l.some(I)||0===u.length)return{results:l,sideEffects:h,screenshots:d,warnings:[],outcome:"none"};let m=(i=c(u[0]),n=c(u[u.length-1]),o=u.some(e=>void 0!==e.transformationLog),{kind:"committed",previousState:i.previousState,state:n.state,updates:u.flatMap(e=>e.updates),validity:n.validity,transformationLog:o?u.flatMap(e=>e.transformationLog??[]):void 0});return{results:l,sideEffects:h,screenshots:d,warnings:this.readWarnings(a,s),outcome:r.commitPrepared(m),preparedState:m.state}};execute=async e=>{let t=this._generation;if(!this._context.domainContextSelectors.getStoreSystem().isInitialized)return{results:e.map(()=>T),committed:!1,sideEffects:[],warnings:[],screenshots:new Map};let i=await this._prepareAndCommit(e,t),{results:n,sideEffects:o,warnings:r,screenshots:a,outcome:s,preparedState:l}="conflict"===i.outcome&&t.active?await this._prepareAndCommit(e,t):i;return"committed"===s?{results:n,committed:!0,sideEffects:o,warnings:r,screenshots:a,preparedState:l}:"held"===s?{results:n,committed:!1,message:"The changes wait for the user's approval and are not applied yet. Do not send them again; the next `[changes]` block lists them once approved.",sideEffects:o,warnings:r,screenshots:a,preparedState:l}:"conflict"===s?{results:n,committed:!1,message:"The changes were not committed, because the configuration changed while they were being applied. The results describe a state that was discarded. Query the current configuration and send the operations again if they still make sense.",sideEffects:o,warnings:r,screenshots:a}:{results:n,committed:!1,sideEffects:o,warnings:r,screenshots:a}}}
@@ -0,0 +1,40 @@
1
+ import type { Localizable } from '@salsita-ai/common/utils';
2
+ import type { DomainEntity, EntityId, StateValidationResult } from '#package/domain';
3
+ type AnyStateValidationResult = StateValidationResult<DomainEntity<string>, string>;
4
+ /** One violation that makes a change fail, as the agent reads it; a violation can sit on a virtual entity. */
5
+ export interface ViolationEntry {
6
+ readonly type: string;
7
+ readonly entityId: EntityId | null;
8
+ readonly message: string | null;
9
+ }
10
+ /** One warning or notice, which never makes a change fail. */
11
+ export interface AssistantWarning {
12
+ readonly type: string;
13
+ readonly severity: 'warning' | 'notice';
14
+ readonly entityId: EntityId | null;
15
+ readonly message: string | null;
16
+ }
17
+ /**
18
+ * Thrown by a mutation field whose changes would leave the configuration invalid. graphql-js reports
19
+ * one error per failed field, so the field throws this one error and the executor's caller replaces
20
+ * it with one GraphQL error per violation.
21
+ */
22
+ export declare class ViolationsError extends Error {
23
+ readonly entries: readonly ViolationEntry[];
24
+ constructor(message: string, entries: readonly ViolationEntry[]);
25
+ }
26
+ /**
27
+ * The violations an invalid validity fails on: those of its failing severity, or the one error that
28
+ * validation threw.
29
+ */
30
+ export declare const readViolationEntries: (validity: Extract<AnyStateValidationResult, {
31
+ readonly valid: false;
32
+ }>, resolveLocalizable: (message: Localizable) => string) => readonly ViolationEntry[];
33
+ /**
34
+ * The warnings and notices of `after` that `before` did not have, in the order of `after`; every one
35
+ * of `after` when there is no `before`.
36
+ */
37
+ export declare const readStateWarnings: (after: AnyStateValidationResult, before: AnyStateValidationResult | undefined, resolveLocalizable: (message: Localizable) => string) => readonly AssistantWarning[];
38
+ /** The warnings and notices of a validity that are on one entity, in the order of the validity. */
39
+ export declare const readEntityWarnings: (entityId: EntityId, validity: AnyStateValidationResult, resolveLocalizable: (message: Localizable) => string) => readonly AssistantWarning[];
40
+ export {};
@@ -0,0 +1 @@
1
+ export class ViolationsError extends Error{entries;constructor(e,t){super(e),this.entries=t}}let e=(e,t)=>void 0===e?null:t(e);export const readViolationEntries=(t,r)=>"uncaught"===t.severity?[{type:"uncaught",entityId:null,message:t.error.message}]:t.entityViolations.filter(({violation:e})=>e.severity===t.severity).map(({entityId:t,violation:i})=>({type:i.type,entityId:t,message:e(i.message,r)}));let t=e=>null===e.severity||"uncaught"===e.severity?[]:e.entityViolations.filter(({violation:e})=>{let t;return"warning"===(t=e.severity)||"notice"===t}),r=({entityId:e,violation:{type:t,severity:r}})=>JSON.stringify([e,t,r]),i=(t,r,i)=>({type:r.type,severity:"notice"===r.severity?"notice":"warning",entityId:t,message:e(r.message,i)});export const readStateWarnings=(e,n,s)=>{let a=new Set(void 0===n?[]:t(n).map(r));return t(e).filter(e=>!a.has(r(e))).map(({entityId:e,violation:t})=>i(e,t,s))};export const readEntityWarnings=(e,r,n)=>t(r).filter(t=>t.entityId===e).map(({violation:t})=>i(e,t,n));
@@ -1,8 +1,8 @@
1
1
  import { type $DomainEntity, type ConfiguratorBuilder, type CreateCustomPhoenixEntityElement, type CreateCustomPhoenixLayoutElement, type CreateGetThemeHandler, type CreateGetWebComponentOptionsHandler, type CreatePhoenixHandler, type DomainEntity, type IsCreateRecipeUpdate, type IsReplaceRecipeUpdate, type TransformerBuilder, type TransformerFactory, type UpdateFactory, getIdSequence } from '#package/domain';
2
- import { type CreateAddEntityFab, type CreateAppLoader, type CreateCollectFrontendDataHandler, type CreateConfigurationNotFoundPage, type CreateConfiguratorErrorPage, type CreateDeleteEntityFab, type CreateFilterPublishedChunksHandler, type CreateNavigationHotspot, type CreateNotAuthenticatedPage, type CreateOnApplicationStartProvider, type CreateOnBackendDataReadyProvider, type CreateOnConfiguratorReadyProvider, type CreateOnFrontendDataReadyProvider, type CreateOnGoToIndexHandler, type CreateOnPresetLoadedHandler, type CreateOnPublishedDataReadyProvider, type CreateOnRoutingReadyProvider, type CreateOnSessionReadyProvider, type CreatePresetUi, type CreateSelectionHotspot, type CreateToolMenuFab, type IsAngleDimensionUpdate, type IsAttributeSelectionUpdate, type IsAttributeSwitchUpdate, type IsDeleteEntityUpdate, type IsDistanceDimensionUpdate, type IsGenericDimensionUpdate, type IsSwatchSelectionUpdate, type IsTextValueUpdate, type UseAccessService, type UseActiveNavigationState, type UseActiveToolState, type UseActiveViewState, type UseActiveViewports, type UseAnalyticsService, type UseAngleDimension, type UseAttributeSelection, type UseAttributeSwitch, type UseAuthenticatedClient, type UseAuthorizedClient, type UseBackendData, type UseChildEntitySelection, type UseComponent, type UseComponents, type UseComposition, type UseConfigurationId, type UseConfigurationSaveState, type UseConfiguratorMessages, type UseConfiguratorRouting, type UseControlViolations, type UseCookRecipes, type UseCookReplaceRecipes, type UseCookedRecipes, type UseCookedReplaceRecipes, type UseCreateAuthorizedClient, type UseDeleteEntity, type UseDeletedEntity, type UseDeselect, type UseDistanceDimension, type UseDistanceDimensionSelection, type UseDomainApplicationContext, type UseDomainApplicationProps, type UseDomainContext, type UseDomainEntityState, type UseEntityPrice, type UseEntitySelector, type UseFinalizeAction, type UseFinalizeActions, type UseFinalizeViolations, type UseFirstComponent, type UseFirstRootComponent, type UseFrontendData, type UseGenericDimension, type UseGroupedRecipeOptions, type UseHoveredDomainEntityId, type UseHoveredEntity, type UseHoveredEntityId, type UseIntegrationService, type UseIntegrationState, type UseIsFullscreenActive, type UseLoadedData, type UseLoadingState, type UseLocaleSwitch, type UseMapViolationHints, type UseNavigate, type UsePopNavigate, type UsePresetEmbeddedState, type UsePublishedData, type UsePushNavigate, type UseRecipeEmbeddedState, type UseReplaceEntityRecipeOptions, type UseRootComponents, type UseRootEntityId, type UseRootEntityPrice, type UseRootEntitySelector, type UseRootEntityState, type UseSelectEntity, type UseSelectParent, type UseSelectedDomainEntityId, type UseSelectedEntity, type UseSelectedEntityId, type UseSession, type UseSessionRole, type UseSessionService, type UseSetFullscreen, type UseSetViewState, type UseShareLinks, type UseSlice, type UseState, type UseStateValidity, type UseStepNavigation, type UseSwatchSelection, type UseSynchronizedSelector, type UseSynchronizedSelector$, type UseTabNavigation, type UseTextValue, type UseUndoRedo, type UseUpdateControl, type UseUpdatedControl, useGenerateShareLink, useLoadingStateValue, useLocalizable, useResolveLocalizable } from '#package/react-sdk';
2
+ import { type CreateAddEntityFab, type CreateAppLoader, type CreateCollectFrontendDataHandler, type CreateConfigurationNotFoundPage, type CreateConfiguratorErrorPage, type CreateDeleteEntityFab, type CreateFilterPublishedChunksHandler, type CreateNavigationHotspot, type CreateNotAuthenticatedPage, type CreateOnApplicationStartProvider, type CreateOnBackendDataReadyProvider, type CreateOnConfiguratorReadyProvider, type CreateOnFrontendDataReadyProvider, type CreateOnGoToIndexHandler, type CreateOnPresetLoadedHandler, type CreateOnPublishedDataReadyProvider, type CreateOnRoutingReadyProvider, type CreateOnSessionReadyProvider, type CreatePresetUi, type CreateSelectionHotspot, type CreateToolMenuFab, type IsAngleDimensionUpdate, type IsAttributeSelectionUpdate, type IsAttributeSwitchUpdate, type IsDeleteEntityUpdate, type IsDistanceDimensionUpdate, type IsGenericDimensionUpdate, type IsSwatchSelectionUpdate, type IsTextValueUpdate, type UseAccessService, type UseActiveNavigationState, type UseActiveToolState, type UseActiveViewState, type UseActiveViewports, type UseAnalyticsService, type UseAngleDimension, type UseAttributeSelection, type UseAttributeSwitch, type UseAuthenticatedClient, type UseAuthorizedClient, type UseBackendData, type UseChildEntitySelection, type UseComponent, type UseComponents, type UseComposition, type UseConfigurationId, type UseConfigurationSaveState, type UseConfiguratorMessages, type UseConfiguratorRouting, type UseControlViolations, type UseCookRecipes, type UseCookReplaceRecipes, type UseCookedRecipes, type UseCookedReplaceRecipes, type UseCreateAuthorizedClient, type UseDeleteEntity, type UseDeletedEntity, type UseDeselect, type UseDistanceDimension, type UseDistanceDimensionSelection, type UseDomainApplicationContext, type UseDomainApplicationProps, type UseDomainContext, type UseDomainEntityState, type UseEntityPrice, type UseEntitySelector, type UseFinalizeAction, type UseFinalizeActions, type UseFinalizeViolations, type UseFirstComponent, type UseFirstRootComponent, type UseFrontendData, type UseGenericDimension, type UseGroupedRecipeOptions, type UseHoveredDomainEntityId, type UseHoveredEntity, type UseHoveredEntityId, type UseIntegrationService, type UseIntegrationState, type UseIsFullscreenActive, type UseLoadedData, type UseLoadingState, type UseLocaleSwitch, type UseMapViolationHints, type UseNavigate, type UsePopNavigate, type UsePresetEmbeddedState, type UsePresetSelection, type UsePublishedData, type UsePushNavigate, type UseRecipeEmbeddedState, type UseReplaceEntityRecipeOptions, type UseRootComponents, type UseRootEntityId, type UseRootEntityPrice, type UseRootEntitySelector, type UseRootEntityState, type UseSelectEntity, type UseSelectParent, type UseSelectedDomainEntityId, type UseSelectedEntity, type UseSelectedEntityId, type UseSession, type UseSessionRole, type UseSessionService, type UseSetFullscreen, type UseSetViewState, type UseShareLinks, type UseSlice, type UseState, type UseStateValidity, type UseStepNavigation, type UseSwatchSelection, type UseSynchronizedSelector, type UseSynchronizedSelector$, type UseTabNavigation, type UseTextValue, type UseUndoRedo, type UseUpdateControl, type UseUpdatedControl, useGenerateShareLink, useLoadingStateValue, useLocalizable, useResolveLocalizable } from '#package/react-sdk';
3
3
  import { type CreatePhoenixIconSet } from '#package/ui-sdk';
4
4
  import { type UseConfiguratorExtensions } from '../application-runtime/index.js';
5
- import { type UsePresetSelection, usePreview, usePropertyPageStack, usePropertyPageState } from '../configurator-context/index.js';
5
+ import { usePreview, usePropertyPageStack, usePropertyPageState } from '../configurator-context/index.js';
6
6
  import { useCloseAction } from '../integration/index.js';
7
7
  import { type CreateGetTextureProcessingMapHandler } from '../scene/index.js';
8
8
  import type { UseUpdateEntityObjectSelection } from '../scene/scene-entity/drag-and-drop/use-updated-selection.js';
@@ -1 +1 @@
1
- import{createCustomPhoenixEntityElement as e,createCustomPhoenixLayoutElement as t,createGetThemeHandler as r,createGetWebComponentOptionsHandler as o,createPhoenixHandler as i,createTransformer as n,createTransformerBuilder as s,createUpdateFactory as a,getIdSequence as m,isCreateEntityUpdate as p,isReplaceEntityUpdate as d}from"#package/domain";import{createAddEntityFab as c,createAppLoader as u,createCollectFrontendDataHandler as f,createConfigurationNotFoundPage as l,createConfiguratorErrorPage as g,createDeleteEntityFab as j,createFilterPublishedChunksHandler as x,createNavigationHotspot as k,createNotAuthenticatedPage as y,createOnApplicationStartProvider as I,createOnBackendDataReadyProvider as A,createOnConfiguratorReadyProvider as C,createOnFrontendDataReadyProvider as S,createOnGoToIndexHandler as w,createOnPresetLoadedHandler as E,createOnPublishedDataReadyProvider as b,createOnRoutingReadyProvider as q,createOnSessionReadyProvider as B,createPresetUi as P,createSelectionHotspot as R,createToolMenuFab as U,isAngleDimensionUpdate as h,isAttributeSelectionUpdate as v,isAttributeSwitchUpdate as z,isDeleteEntityUpdate as D,isDistanceDimensionUpdate as F,isGenericDimensionUpdate as G,isSwatchSelectionUpdate as H,isTextValueUpdate as J,useAccessService as K,useActiveNavigationState as L,useActiveToolState as M,useActiveViewState as N,useActiveViewports as O,useAnalyticsService as Q,useAngleDimension as T,useAttributeSelection as V,useAttributeSwitch as W,useAuthenticatedClient as X,useAuthorizedClient as Y,useBackendData as Z,useChildEntitySelection as $,useCommittedSlice as _,useCommittedState as ee,useComponent as et,useComponents as er,useComposition as eo,useConfigurationId as ei,useConfigurationSaveState as en,useConfiguratorMessages as es,useConfiguratorRouting as ea,useControlViolations as em,useCookRecipes as ep,useCookReplaceRecipes as ed,useCookedRecipes as ec,useCookedReplaceRecipes as eu,useCreateAuthorizedClient as ef,useDeleteEntity as el,useDeletedEntity as eg,useDeselect as ej,useDistanceDimension as ex,useDistanceDimensionSelection as ek,useDomain as ey,useDomainApplication as eI,useDomainApplicationProps as eA,useDomainEntityRenderedState as eC,useDomainEntityState as eS,useEntityPrice as ew,useEntitySelector as eE,useFinalizeAction as eb,useFinalizeActions as eq,useFinalizeViolations as eB,useFirstComponent as eP,useFirstRenderedComponent as eR,useFirstRootComponent as eU,useFirstRootRenderedComponent as eh,useFrontendData as ev,useGenerateShareLink as ez,useGenericDimension as eD,useGroupedRecipeOptions as eF,useHoveredDomainEntityId as eG,useHoveredEntity as eH,useHoveredEntityId as eJ,useIntegrationService as eK,useIntegrationState as eL,useIsFullscreenActive as eM,useLoadedData as eN,useLoadingState as eO,useLoadingStateValue as eQ,useLocaleSwitch as eT,useLocalizable as eV,useMapViolationHints as eW,useNavigate as eX,usePopNavigate as eY,usePresetEmbeddedState as eZ,usePublishedData as e$,usePushNavigate as e_,useRecipeEmbeddedState as e0,useRenderedComponent as e1,useRenderedComponents as e2,useRenderedEntitySelector as e3,useRenderedRootEntitySelector as e4,useRenderedSelector as e5,useRenderedSelector$ as e6,useRenderedSlice as e7,useRenderedState as e8,useReplaceEntityRecipeOptions as e9,useResolveLocalizable as te,useRootComponents as tt,useRootEntityId as tr,useRootEntityPrice as to,useRootEntityRenderedId as ti,useRootEntityRenderedState as tn,useRootEntitySelector as ts,useRootEntityState as ta,useRootRenderedComponents as tm,useSelectEntity as tp,useSelectParent as td,useSelectedDomainEntityId as tc,useSelectedEntity as tu,useSelectedEntityId as tf,useSession as tl,useSessionRole as tg,useSessionService as tj,useSetFullscreen as tx,useSetViewState as tk,useShareLinks as ty,useStateValidity as tI,useStepNavigation as tA,useStoreSelector as tC,useStoreSelector$ as tS,useSwatchSelection as tw,useTabNavigation as tE,useTextValue as tb,useUndoRedo as tq,useUpdateControl as tB,useUpdatedControl as tP}from"#package/react-sdk";import{createPhoenixIconSet as tR}from"#package/ui-sdk";import{useConfigurator as tU}from"../application-runtime/index.js";import{usePresetSelection as th,usePreview as tv,usePropertyPageStack as tz,usePropertyPageState as tD}from"../configurator-context/index.js";import{useCloseAction as tF}from"../integration/index.js";import{createGetTextureProcessingMapHandler as tG}from"../scene/index.js";import{useUpdateEntityObjectSelection as tH}from"../scene/scene-entity/drag-and-drop/use-updated-selection.js";import{useAssistantPanel as tJ,useMeasurements as tK,useToolbarActions as tL}from"../toolbar-actions/index.js";import{LayoutSlots as tM,createCanvasLoader as tN,createLayoutAdminUi as tO,createLayoutCustomOwnerUi as tQ,createLayoutCustomReadUi as tT,createLayoutDialog as tV,createLayoutFooter as tW,createLayoutToolbarDesktop as tX,createLayoutToolbarDesktopFullScreen as tY,createLayoutToolbarReadDesktop as tZ,createLayoutToolbarReadDesktopFullScreen as t$,createLayoutUserUi as t_,createToolbarHelp as t0,useSceneSafeArea as t1}from"../ui/index.js";import{createPresetDeviceNotSupported as t2,createPresetPageAction as t3}from"../ui/preset-layout/PresetUi.js";import{useResetCamera as t4}from"./use-reset-camera.js";export const createConfiguratorInterface=t5=>({updates:a(),getIdSequence:m,createGetWebComponentOptionsHandler:o,createGetThemeHandler:r,createPhoenixHandler:i,createCustomPhoenixEntityElement:e,createCustomPhoenixLayoutElement:t,createPhoenixIconSet:tR,createGetTextureProcessingMapHandler:tG,createCollectFrontendDataHandler:f,createFilterPublishedChunksHandler:x,createOnGoToIndexHandler:w,createOnApplicationStartProvider:I,createOnSessionReadyProvider:B,createOnPublishedDataReadyProvider:b,createOnFrontendDataReadyProvider:S,createOnBackendDataReadyProvider:A,createOnRoutingReadyProvider:q,createOnConfiguratorReadyProvider:C,createOnPresetLoadedHandler:E,createPresetUi:P,createPresetPageAction:t3,createPresetDeviceNotSupported:t2,createLayoutFooter:tW,createAppLoader:u,createCanvasLoader:tN,createLayoutDialog:tV,createLayoutToolbarDesktop:tX,createLayoutToolbarDesktopFullScreen:tY,createLayoutToolbarReadDesktop:tZ,createLayoutToolbarReadDesktopFullScreen:t$,createLayoutCustomOwnerUi:tQ,createLayoutCustomReadUi:tT,createLayoutAdminUi:tO,createLayoutUserUi:t_,createToolbarHelp:t0,createNotAuthenticatedPage:y,createConfigurationNotFoundPage:l,createConfiguratorErrorPage:g,createAddEntityFab:c,createDeleteEntityFab:j,createSelectionHotspot:R,createNavigationHotspot:k,createToolMenuFab:U,createTransformer:n,transformerBuilder:s(),useAnalytics:Q,useAuthenticatedClient:X,useAuthorizedClient:Y,useCreateAuthorizedClient:ef,useAccessService:K,useConfigurationId:ei,useSession:tl,useSessionRole:tg,useSessionService:tj,useDomain:ey,useDomainApplication:eI,useConfigurator:tU,useConfiguratorRouting:ea,usePresetSelection:th,usePublishedData:e$,useFrontendData:ev,useBackendData:Z,useDomainApplicationProps:eA,useLoadedData:eN,useIntegrationService:eK,useIntegrationState:eL,usePresetEmbeddedState:eZ,useRecipeEmbeddedState:e0,useCommittedSlice:_,useRenderedSlice:e7,useCommittedState:ee,useRenderedState:e8,useStoreSelector:tC,useRenderedSelector:e5,useStoreSelector$:tS,useRenderedSelector$:e6,useEntitySelector:eE,useRenderedEntitySelector:e3,useRootEntitySelector:ts,useRenderedRootEntitySelector:e4,useStateValidity:tI,useMapViolationHints:eW,useNavigate:eX,usePopNavigate:eY,usePushNavigate:e_,useControlViolations:em,useFinalizeViolations:eB,useConfiguratorMessages:es,useConfigurationSaveState:en,useFinalizeAction:eb,useFinalizeActions:eq,useComponent:et,useRenderedComponent:e1,useComponents:er,useRenderedComponents:e2,useFirstComponent:eP,useFirstRenderedComponent:eR,useRootComponents:tt,useRootRenderedComponents:tm,useFirstRootComponent:eU,useFirstRootRenderedComponent:eh,useEntityState:eS,useEntityRenderedState:eC,useRootEntityState:ta,useRootEntityRenderedState:tn,useRootEntityId:tr,useRootEntityRenderedId:ti,useEntityPrice:ew,useRootEntityPrice:to,useSelectedEntity:tu,useSelectedEntityId:tf,useSelectedDomainEntityId:tc,useSelectEntity:tp,useDeselect:ej,useSelectParent:td,useHoveredEntity:eH,useHoveredEntityId:eJ,useHoveredDomainEntityId:eG,useActiveNavigationState:L,useActiveViewState:N,useSetViewState:tk,useActiveToolState:M,useIsFullscreenActive:eM,useSetFullscreen:tx,useResetCamera:t4,useUndoRedo:tq,useTabNavigation:tE,useStepNavigation:tA,useSceneSafeArea:t1,useActiveViewports:O,usePreview:tv,useCloseAction:tF,useIsCloningAllowed:tM.useIsCloningAllowed,useResolveLocalizable:te,useLocalizable:eV,useToolbarActions:tL,useMeasurements:tK,useLocaleSwitch:eT,useShareLinks:ty,useAssistantPanel:tJ,useComposition:eo,useUpdateControl:tB,useUpdatedControl:tP,useCookRecipes:ep,useCookedRecipes:ec,useCookReplaceRecipes:ed,useCookedReplaceRecipes:eu,useDeleteEntity:el,useDeletedEntity:eg,useSwatchSelection:tw,useTextValue:tb,useAttributeSelection:V,useAttributeSwitch:W,useDistanceDimension:ex,useDistanceDimensionSelection:ek,useGenericDimension:eD,useAngleDimension:T,useChildEntitySelection:$,useGroupedRecipeOptions:eF,useReplaceEntityRecipeOptions:e9,useUpdateEntityObjectSelection:tH,useGenerateShareLink:ez,useLoadingState:eO,useLoadingStateValue:eQ,usePropertyPageStack:tz,usePropertyPageState:tD,isCreateEntityUpdate:p,isReplaceEntityUpdate:d,isDeleteEntityUpdate:D,isAngleDimensionUpdate:h,isDistanceDimensionUpdate:F,isGenericDimensionUpdate:G,isAttributeSelectionUpdate:v,isAttributeSwitchUpdate:z,isTextValueUpdate:J,isSwatchSelectionUpdate:H});
1
+ import{createCustomPhoenixEntityElement as e,createCustomPhoenixLayoutElement as t,createGetThemeHandler as r,createGetWebComponentOptionsHandler as o,createPhoenixHandler as i,createTransformer as n,createTransformerBuilder as s,createUpdateFactory as a,getIdSequence as m,isCreateEntityUpdate as p,isReplaceEntityUpdate as d}from"#package/domain";import{createAddEntityFab as c,createAppLoader as u,createCollectFrontendDataHandler as f,createConfigurationNotFoundPage as l,createConfiguratorErrorPage as g,createDeleteEntityFab as j,createFilterPublishedChunksHandler as x,createNavigationHotspot as k,createNotAuthenticatedPage as y,createOnApplicationStartProvider as I,createOnBackendDataReadyProvider as A,createOnConfiguratorReadyProvider as C,createOnFrontendDataReadyProvider as S,createOnGoToIndexHandler as w,createOnPresetLoadedHandler as E,createOnPublishedDataReadyProvider as b,createOnRoutingReadyProvider as q,createOnSessionReadyProvider as B,createPresetUi as P,createSelectionHotspot as R,createToolMenuFab as U,isAngleDimensionUpdate as h,isAttributeSelectionUpdate as v,isAttributeSwitchUpdate as z,isDeleteEntityUpdate as D,isDistanceDimensionUpdate as F,isGenericDimensionUpdate as G,isSwatchSelectionUpdate as H,isTextValueUpdate as J,useAccessService as K,useActiveNavigationState as L,useActiveToolState as M,useActiveViewState as N,useActiveViewports as O,useAnalyticsService as Q,useAngleDimension as T,useAttributeSelection as V,useAttributeSwitch as W,useAuthenticatedClient as X,useAuthorizedClient as Y,useBackendData as Z,useChildEntitySelection as $,useCommittedSlice as _,useCommittedState as ee,useComponent as et,useComponents as er,useComposition as eo,useConfigurationId as ei,useConfigurationSaveState as en,useConfiguratorMessages as es,useConfiguratorRouting as ea,useControlViolations as em,useCookRecipes as ep,useCookReplaceRecipes as ed,useCookedRecipes as ec,useCookedReplaceRecipes as eu,useCreateAuthorizedClient as ef,useDeleteEntity as el,useDeletedEntity as eg,useDeselect as ej,useDistanceDimension as ex,useDistanceDimensionSelection as ek,useDomain as ey,useDomainApplication as eI,useDomainApplicationProps as eA,useDomainEntityRenderedState as eC,useDomainEntityState as eS,useEntityPrice as ew,useEntitySelector as eE,useFinalizeAction as eb,useFinalizeActions as eq,useFinalizeViolations as eB,useFirstComponent as eP,useFirstRenderedComponent as eR,useFirstRootComponent as eU,useFirstRootRenderedComponent as eh,useFrontendData as ev,useGenerateShareLink as ez,useGenericDimension as eD,useGroupedRecipeOptions as eF,useHoveredDomainEntityId as eG,useHoveredEntity as eH,useHoveredEntityId as eJ,useIntegrationService as eK,useIntegrationState as eL,useIsFullscreenActive as eM,useLoadedData as eN,useLoadingState as eO,useLoadingStateValue as eQ,useLocaleSwitch as eT,useLocalizable as eV,useMapViolationHints as eW,useNavigate as eX,usePopNavigate as eY,usePresetEmbeddedState as eZ,usePresetSelection as e$,usePublishedData as e_,usePushNavigate as e0,useRecipeEmbeddedState as e1,useRenderedComponent as e2,useRenderedComponents as e3,useRenderedEntitySelector as e4,useRenderedRootEntitySelector as e5,useRenderedSelector as e6,useRenderedSelector$ as e7,useRenderedSlice as e8,useRenderedState as e9,useReplaceEntityRecipeOptions as te,useResolveLocalizable as tt,useRootComponents as tr,useRootEntityId as to,useRootEntityPrice as ti,useRootEntityRenderedId as tn,useRootEntityRenderedState as ts,useRootEntitySelector as ta,useRootEntityState as tm,useRootRenderedComponents as tp,useSelectEntity as td,useSelectParent as tc,useSelectedDomainEntityId as tu,useSelectedEntity as tf,useSelectedEntityId as tl,useSession as tg,useSessionRole as tj,useSessionService as tx,useSetFullscreen as tk,useSetViewState as ty,useShareLinks as tI,useStateValidity as tA,useStepNavigation as tC,useStoreSelector as tS,useStoreSelector$ as tw,useSwatchSelection as tE,useTabNavigation as tb,useTextValue as tq,useUndoRedo as tB,useUpdateControl as tP,useUpdatedControl as tR}from"#package/react-sdk";import{createPhoenixIconSet as tU}from"#package/ui-sdk";import{useConfigurator as th}from"../application-runtime/index.js";import{usePreview as tv,usePropertyPageStack as tz,usePropertyPageState as tD}from"../configurator-context/index.js";import{useCloseAction as tF}from"../integration/index.js";import{createGetTextureProcessingMapHandler as tG}from"../scene/index.js";import{useUpdateEntityObjectSelection as tH}from"../scene/scene-entity/drag-and-drop/use-updated-selection.js";import{useAssistantPanel as tJ,useMeasurements as tK,useToolbarActions as tL}from"../toolbar-actions/index.js";import{LayoutSlots as tM,createCanvasLoader as tN,createLayoutAdminUi as tO,createLayoutCustomOwnerUi as tQ,createLayoutCustomReadUi as tT,createLayoutDialog as tV,createLayoutFooter as tW,createLayoutToolbarDesktop as tX,createLayoutToolbarDesktopFullScreen as tY,createLayoutToolbarReadDesktop as tZ,createLayoutToolbarReadDesktopFullScreen as t$,createLayoutUserUi as t_,createToolbarHelp as t0,useSceneSafeArea as t1}from"../ui/index.js";import{createPresetDeviceNotSupported as t2,createPresetPageAction as t3}from"../ui/preset-layout/PresetUi.js";import{useResetCamera as t4}from"./use-reset-camera.js";export const createConfiguratorInterface=t5=>({updates:a(),getIdSequence:m,createGetWebComponentOptionsHandler:o,createGetThemeHandler:r,createPhoenixHandler:i,createCustomPhoenixEntityElement:e,createCustomPhoenixLayoutElement:t,createPhoenixIconSet:tU,createGetTextureProcessingMapHandler:tG,createCollectFrontendDataHandler:f,createFilterPublishedChunksHandler:x,createOnGoToIndexHandler:w,createOnApplicationStartProvider:I,createOnSessionReadyProvider:B,createOnPublishedDataReadyProvider:b,createOnFrontendDataReadyProvider:S,createOnBackendDataReadyProvider:A,createOnRoutingReadyProvider:q,createOnConfiguratorReadyProvider:C,createOnPresetLoadedHandler:E,createPresetUi:P,createPresetPageAction:t3,createPresetDeviceNotSupported:t2,createLayoutFooter:tW,createAppLoader:u,createCanvasLoader:tN,createLayoutDialog:tV,createLayoutToolbarDesktop:tX,createLayoutToolbarDesktopFullScreen:tY,createLayoutToolbarReadDesktop:tZ,createLayoutToolbarReadDesktopFullScreen:t$,createLayoutCustomOwnerUi:tQ,createLayoutCustomReadUi:tT,createLayoutAdminUi:tO,createLayoutUserUi:t_,createToolbarHelp:t0,createNotAuthenticatedPage:y,createConfigurationNotFoundPage:l,createConfiguratorErrorPage:g,createAddEntityFab:c,createDeleteEntityFab:j,createSelectionHotspot:R,createNavigationHotspot:k,createToolMenuFab:U,createTransformer:n,transformerBuilder:s(),useAnalytics:Q,useAuthenticatedClient:X,useAuthorizedClient:Y,useCreateAuthorizedClient:ef,useAccessService:K,useConfigurationId:ei,useSession:tg,useSessionRole:tj,useSessionService:tx,useDomain:ey,useDomainApplication:eI,useConfigurator:th,useConfiguratorRouting:ea,usePresetSelection:e$,usePublishedData:e_,useFrontendData:ev,useBackendData:Z,useDomainApplicationProps:eA,useLoadedData:eN,useIntegrationService:eK,useIntegrationState:eL,usePresetEmbeddedState:eZ,useRecipeEmbeddedState:e1,useCommittedSlice:_,useRenderedSlice:e8,useCommittedState:ee,useRenderedState:e9,useStoreSelector:tS,useRenderedSelector:e6,useStoreSelector$:tw,useRenderedSelector$:e7,useEntitySelector:eE,useRenderedEntitySelector:e4,useRootEntitySelector:ta,useRenderedRootEntitySelector:e5,useStateValidity:tA,useMapViolationHints:eW,useNavigate:eX,usePopNavigate:eY,usePushNavigate:e0,useControlViolations:em,useFinalizeViolations:eB,useConfiguratorMessages:es,useConfigurationSaveState:en,useFinalizeAction:eb,useFinalizeActions:eq,useComponent:et,useRenderedComponent:e2,useComponents:er,useRenderedComponents:e3,useFirstComponent:eP,useFirstRenderedComponent:eR,useRootComponents:tr,useRootRenderedComponents:tp,useFirstRootComponent:eU,useFirstRootRenderedComponent:eh,useEntityState:eS,useEntityRenderedState:eC,useRootEntityState:tm,useRootEntityRenderedState:ts,useRootEntityId:to,useRootEntityRenderedId:tn,useEntityPrice:ew,useRootEntityPrice:ti,useSelectedEntity:tf,useSelectedEntityId:tl,useSelectedDomainEntityId:tu,useSelectEntity:td,useDeselect:ej,useSelectParent:tc,useHoveredEntity:eH,useHoveredEntityId:eJ,useHoveredDomainEntityId:eG,useActiveNavigationState:L,useActiveViewState:N,useSetViewState:ty,useActiveToolState:M,useIsFullscreenActive:eM,useSetFullscreen:tk,useResetCamera:t4,useUndoRedo:tB,useTabNavigation:tb,useStepNavigation:tC,useSceneSafeArea:t1,useActiveViewports:O,usePreview:tv,useCloseAction:tF,useIsCloningAllowed:tM.useIsCloningAllowed,useResolveLocalizable:tt,useLocalizable:eV,useToolbarActions:tL,useMeasurements:tK,useLocaleSwitch:eT,useShareLinks:tI,useAssistantPanel:tJ,useComposition:eo,useUpdateControl:tP,useUpdatedControl:tR,useCookRecipes:ep,useCookedRecipes:ec,useCookReplaceRecipes:ed,useCookedReplaceRecipes:eu,useDeleteEntity:el,useDeletedEntity:eg,useSwatchSelection:tE,useTextValue:tq,useAttributeSelection:V,useAttributeSwitch:W,useDistanceDimension:ex,useDistanceDimensionSelection:ek,useGenericDimension:eD,useAngleDimension:T,useChildEntitySelection:$,useGroupedRecipeOptions:eF,useReplaceEntityRecipeOptions:te,useUpdateEntityObjectSelection:tH,useGenerateShareLink:ez,useLoadingState:eO,useLoadingStateValue:eQ,usePropertyPageStack:tz,usePropertyPageState:tD,isCreateEntityUpdate:p,isReplaceEntityUpdate:d,isDeleteEntityUpdate:D,isAngleDimensionUpdate:h,isDistanceDimensionUpdate:F,isGenericDimensionUpdate:G,isAttributeSelectionUpdate:v,isAttributeSwitchUpdate:z,isTextValueUpdate:J,isSwatchSelectionUpdate:H});
@@ -1 +1 @@
1
- import{useCallback as e,useMemo as t}from"react";import{fixedHeaderComponent as r,floatingHeaderComponent as s,isFixedHeaderSnapshot as a,isFloatingHeaderSnapshot as n,navigationStepsComponent as o}from"#package/domain";import{useActiveNavigationState as i,useDomain as m,useFirstComponent as u,usePresetEmbeddedState as d,useStoreSelector as l}from"#package/react-sdk";import{useConfigurator as p}from"../../application-runtime/index.js";import{usePresetSelection as c}from"../PresetSelectionProvider.js";export const useLayoutSystemConfig=()=>{let{layoutSystem:e}=p();return l(t=>e.getLayoutConfig(t.state),[e])};export const useEnterSidebarSummary=()=>{let{storeSystem:t}=m(),{layoutSystem:r}=p();return e(()=>{let e=r.getEnterSidebarSummaryUpdates(t.stateSlices.committed.value.state);t.stageAndCommit(e)},[r,t])};export const useLeaveSidebarSummary=()=>{let{storeSystem:t}=m(),{layoutSystem:r}=p();return e(()=>{let e=r.getLeaveSidebarSummaryUpdates(t.stateSlices.committed.value.state);t.stageAndCommit(e)},[r,t])};export const useIsSidebarSummaryActive=()=>{let{layoutSystem:e}=p();return l(t=>e.getSidebarSummaryPage(t.state).isSummaryActive,[e])};export const useSidebarSummary=()=>{let{layoutSystem:e}=p();return l(t=>e.getSidebarSummaryPage(t.state),[e])};export const useSidebarContents=()=>{let{layoutSystem:e}=p();return l(t=>e.getSidebarContent(t.state),[e])};export const useSidebarGoBack=()=>{let{layoutSystem:t}=p(),{storeSystem:r}=m();return e(()=>{let e=t.getSidebarBackUpdates(r.stateSlices.committed.value.state);r.stageAndCommit(e)},[t,r])};export const useHasSidebarSummary=()=>{let{page:e}=useSidebarSummary();return null!==e};export const useToolbarState=()=>{let{layoutSystem:e}=p();return l(t=>e.getToolbarState(t.state),[e])};export const useEmbeddedModeActive=()=>!!d();export const usePresetEmbeddedModeActive=()=>d()?.type==="preset";export const useBackToPresetEnabled=()=>{let{hasMultiplePresets:e}=c();return!d()&&e};export const useSteps=()=>{let e=u({componentTypes:[o]}),r=i(),{hasMultiplePresets:s}=c(),a=!!d(),n=t(()=>e?.state.steps??[],[e]),m=t(()=>n.findIndex(e=>e.navigationStates.includes(r)),[n,r]),l=t(()=>n.length>1&&0===m,[m,n.length]),p=t(()=>n.length>1&&m===n.length-1,[m,n.length]),S=t(()=>(m+1)/(n.length+1)*100,[m,n.length]);return{currentStep:t(()=>n.find(e=>e.navigationStates.includes(r)),[n,r]),progress:S,hasSteps:n.length>1,isFirstStep:l,isLastStep:p,previousStepDisabled:l&&!(!a&&s)}};export const useHasSteps=()=>{let{componentReader:e}=m();return l(t=>{let r=e.readFirstComponent({componentTypes:[o],entityIds:[t.state.rootEntityId]},t.state);return r&&r.state.steps.length>0},[e])};export const useHeaderStyle=()=>{let e=u({componentTypes:[s,r]});return t(()=>e?n(e)?"floating":a(e)?"fixed":"none":"none",[e])};
1
+ import{useCallback as e,useMemo as t}from"react";import{fixedHeaderComponent as r,floatingHeaderComponent as a,isFixedHeaderSnapshot as s,isFloatingHeaderSnapshot as n,navigationStepsComponent as o}from"#package/domain";import{useActiveNavigationState as i,useDomain as u,useFirstComponent as m,usePresetEmbeddedState as d,usePresetSelection as l,useStoreSelector as p}from"#package/react-sdk";import{useConfigurator as c}from"../../application-runtime/index.js";export const useLayoutSystemConfig=()=>{let{layoutSystem:e}=c();return p(t=>e.getLayoutConfig(t.state),[e])};export const useEnterSidebarSummary=()=>{let{storeSystem:t}=u(),{layoutSystem:r}=c();return e(()=>{let e=r.getEnterSidebarSummaryUpdates(t.stateSlices.committed.value.state);t.stageAndCommit(e)},[r,t])};export const useLeaveSidebarSummary=()=>{let{storeSystem:t}=u(),{layoutSystem:r}=c();return e(()=>{let e=r.getLeaveSidebarSummaryUpdates(t.stateSlices.committed.value.state);t.stageAndCommit(e)},[r,t])};export const useIsSidebarSummaryActive=()=>{let{layoutSystem:e}=c();return p(t=>e.getSidebarSummaryPage(t.state).isSummaryActive,[e])};export const useSidebarSummary=()=>{let{layoutSystem:e}=c();return p(t=>e.getSidebarSummaryPage(t.state),[e])};export const useSidebarContents=()=>{let{layoutSystem:e}=c();return p(t=>e.getSidebarContent(t.state),[e])};export const useSidebarGoBack=()=>{let{layoutSystem:t}=c(),{storeSystem:r}=u();return e(()=>{let e=t.getSidebarBackUpdates(r.stateSlices.committed.value.state);r.stageAndCommit(e)},[t,r])};export const useHasSidebarSummary=()=>{let{page:e}=useSidebarSummary();return null!==e};export const useToolbarState=()=>{let{layoutSystem:e}=c();return p(t=>e.getToolbarState(t.state),[e])};export const useEmbeddedModeActive=()=>!!d();export const usePresetEmbeddedModeActive=()=>d()?.type==="preset";export const useBackToPresetEnabled=()=>{let{hasMultiplePresets:e}=l();return!d()&&e};export const useSteps=()=>{let e=m({componentTypes:[o]}),r=i(),{hasMultiplePresets:a}=l(),s=!!d(),n=t(()=>e?.state.steps??[],[e]),u=t(()=>n.findIndex(e=>e.navigationStates.includes(r)),[n,r]),p=t(()=>n.length>1&&0===u,[u,n.length]),c=t(()=>n.length>1&&u===n.length-1,[u,n.length]),S=t(()=>(u+1)/(n.length+1)*100,[u,n.length]);return{currentStep:t(()=>n.find(e=>e.navigationStates.includes(r)),[n,r]),progress:S,hasSteps:n.length>1,isFirstStep:p,isLastStep:c,previousStepDisabled:p&&!(!s&&a)}};export const useHasSteps=()=>{let{componentReader:e}=u();return p(t=>{let r=e.readFirstComponent({componentTypes:[o],entityIds:[t.state.rootEntityId]},t.state);return r&&r.state.steps.length>0},[e])};export const useHeaderStyle=()=>{let e=m({componentTypes:[a,r]});return t(()=>e?n(e)?"floating":s(e)?"fixed":"none":"none",[e])};
@@ -1,4 +1,3 @@
1
- export { usePresetSelection, type UsePresetSelection, PresetSelectionProvider, type PresetSelectionProviderProps, } from './PresetSelectionProvider.js';
2
1
  export { ViewportStateSync } from './ViewportStateSync.js';
3
2
  export { PreviewApplicationProvider } from './PreviewApplicationProvider.js';
4
3
  export { PreviewContextProvider, usePreview } from './PreviewContextProvider.js';
@@ -1 +1 @@
1
- export{usePresetSelection,PresetSelectionProvider}from"./PresetSelectionProvider.js";export{ViewportStateSync}from"./ViewportStateSync.js";export{PreviewApplicationProvider}from"./PreviewApplicationProvider.js";export{PreviewContextProvider,usePreview}from"./PreviewContextProvider.js";export*from"./configurator-hooks/index.js";
1
+ export{ViewportStateSync}from"./ViewportStateSync.js";export{PreviewApplicationProvider}from"./PreviewApplicationProvider.js";export{PreviewContextProvider,usePreview}from"./PreviewContextProvider.js";export*from"./configurator-hooks/index.js";
@@ -1 +1 @@
1
- import{jsx as o}from"react/jsx-runtime";import{useEffect as t}from"react";import{assertExistence as e}from"@salsita-ai/common/utils";import{AnalyticsEventFactory as r}from"#package/domain";import{useAnalyticsService as a,useIsDev as i,useLogger as n,useOnMount as d}from"#package/react-sdk";import{usePresetSelection as m}from"../configurator-context/index.js";import{PresetUi as s}from"../ui/index.js";import{PresetCreationErrorPage as l}from"./PresetCreationErrorPage.js";let p=o=>{let{id:t}=o,e=n(),{selectPreset:r}=m();return d(()=>{e.debug("Only single preset available, creating configuration automatically."),r(t)}),null};export const NewConfiguratorPage=()=>{let d=n(),g=a(),f=i(),{presetCategories:u,selectionError:c}=m();t(()=>{g.push(r.DataLoadedEvent({configurationId:"notYetLoaded",revisionId:"notYetLoaded",mode:"notYetLoaded"})),d.appendToGlobalContext({navigationState:"NewConfiguratorPage",revisionId:"notYetLoaded",mode:"notYetLoaded"})},[g,d]);let x=u.flatMap(o=>o.presets),L=1===x.length;return c&&(f||L)?o(l,{error:c}):L?o(p,{id:e(x[0]).id}):o(s,{})};
1
+ import{jsx as e}from"react/jsx-runtime";import{useEffect as t}from"react";import{assertExistence as o}from"@salsita-ai/common/utils";import{AnalyticsEventFactory as a}from"#package/domain";import{useAnalyticsService as r,useIsDev as i,useLogger as n,useOnMount as d,usePresetSelection as m}from"#package/react-sdk";import{PresetUi as l}from"../ui/index.js";import{PresetCreationErrorPage as s}from"./PresetCreationErrorPage.js";let p=e=>{let{id:t}=e,o=n(),{selectPreset:a}=m();return d(()=>{o.debug("Only single preset available, creating configuration automatically."),a(t)}),null};export const NewConfiguratorPage=()=>{let d=n(),g=r(),u=i(),{presetCategories:f,selectionError:c}=m();t(()=>{g.push(a.DataLoadedEvent({configurationId:"notYetLoaded",revisionId:"notYetLoaded",mode:"notYetLoaded"})),d.appendToGlobalContext({navigationState:"NewConfiguratorPage",revisionId:"notYetLoaded",mode:"notYetLoaded"})},[g,d]);let L=f.flatMap(e=>e.presets),v=1===L.length;return c&&(u||v)?e(s,{error:c}):v?e(p,{id:o(L[0]).id}):e(l,{})};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import{ButtonBase as o,ClickAwayListener as i,Tooltip as a,styled as s}from"@mui/material";import{memo as r,useCallback as l,useMemo as d,useRef as c,useState as m}from"react";import{match as p}from"ts-pattern";import{useLocalizable as h}from"#package/react-sdk";import{PhxIcon as u}from"#package/ui-sdk";import{assistantReferenceStyles as g}from"./reference-link/index.js";import{ScreenshotThumbnails as f,readToolScreenshots as k}from"./screenshots/index.js";import{AssistantPanelName as x}from"./theme.js";let y={id:"sdk.assistant.tool.updateDesign.label",message:"Update design"},b={id:"sdk.assistant.tool.readDesign.label",message:"Read design"},w={id:"sdk.assistant.tool.mistake.hint",message:"The assistant made a mistake."},C={id:"sdk.assistant.tool.cancelled.hint",message:"Stopped before it finished."},v={id:"sdk.assistant.tool.noResult.hint",message:"The result of this step was lost. It may or may not have been done."},D={id:"sdk.assistant.tool.toolBudget.hint",message:"Not done: the assistant reached its limit of steps for one message."},I={id:"sdk.assistant.tool.undo.label",message:"Undo"},S={id:"sdk.assistant.tool.screenshots.label",message:"{count, plural, one {# screenshot} other {# screenshots}}"},j=s("div",{name:x,slot:"chips"})(({theme:{palette:e,spacing:t,typography:n}})=>({...n.caption,alignItems:"start",color:e.text.secondary,display:"grid",gap:t(.75),gridTemplateColumns:"min-content minmax(0, 1fr)"})),T=s("span",{name:x,slot:"activity"})(({theme:{typography:e}})=>({blockSize:`calc(${e.caption.lineHeight} * 1em)`,display:"grid",placeItems:"center"})),A=s(u,{name:x,slot:"activityIcon"})({fontSize:14,'[data-chips="active"] &':{animation:"phx-assistant-turn 2.4s linear infinite","@media (prefers-reduced-motion: reduce)":{animation:"none"}},"@keyframes phx-assistant-turn":{to:{rotate:"360deg"}}}),R=s("span",{name:x,slot:"chip"})(({theme:{palette:e,spacing:t}})=>({cursor:"default",display:"inline-block",whiteSpace:"nowrap","&:not(:last-of-type)::after":{color:e.text.secondary,content:'"\xb7"',display:"inline-block",marginInline:t(.75),textDecoration:"none"},'&[data-chip="failed"]':{color:e.error.main},'&[data-chip="flawed"]':{textDecoration:"line-through",textDecorationColor:e.error.main}})),z=s("span",{name:x,slot:"screenshotsLink"})(g),E=s(o,{name:x,slot:"undoButton"})(({theme:{palette:e,shape:t,spacing:n}})=>({alignItems:"center",animation:"phx-assistant-undo-in 150ms ease-out",borderRadius:t.borderRadius,color:e.primary.main,display:"inline-flex",font:"inherit",gap:n(.5),marginInlineStart:n(1),verticalAlign:"top","&:hover":{textDecoration:"underline"},"@media (prefers-reduced-motion: reduce)":{animation:"none"},"@keyframes phx-assistant-undo-in":{from:{opacity:0}}})),L=r(({tool:t})=>{let{chip:n,input:o,result:i}=t,s=h(y),r=h(b),d=h(w),c=h(C),m=h(v),u=h(D),g=p(n.label).with({kind:"text"},({text:e})=>e).with({kind:"updateDesign"},()=>s).with({kind:"readDesign"},()=>r).exhaustive(),f=l(()=>{console.info(`Assistant tool call "${g}"`,{input:o,result:i})},[o,g,i]);return e(a,{title:p(n).with({errorCode:"cancelled"},()=>c).with({errorCode:"no_result"},()=>m).with({errorCode:"tool_budget"},()=>u).with({state:"failed"},{state:"flawed"},()=>d).otherwise(()=>""),placement:"top-start",children:e(R,{onClick:f,"data-chip":n.state,children:g})})}),P=r(({screenshots:t})=>{let n=h({...S,values:{count:t.length}}),[o,s]=m(!1),r=l(()=>s(!0),[]),d=l(()=>s(!1),[]),p=c(null),u=l(e=>{p.current=e},[]),g=l(()=>{p.current?.update()},[]),k=l(e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),s(!0))},[]);return e(R,{"data-chip":"screenshots",children:e(i,{onClickAway:d,mouseEvent:!!o&&"onClick",touchEvent:!!o&&"onTouchEnd",children:e(a,{open:o,onOpen:r,onClose:d,title:e(f,{screenshots:t,onImageLoad:g}),placement:"top-start",describeChild:!0,disableTouchListener:!0,PopperProps:{popperRef:u},slotProps:{tooltip:{sx:{background:"none",maxInlineSize:"none",padding:0}}},children:e(z,{role:"button",tabIndex:0,"aria-expanded":o,onClick:r,onKeyDown:k,children:n})})})})}),B=({tool:o})=>{let i=d(()=>k(o.result),[o.result]);return t(n,{children:[e(L,{tool:o}),i.length>0&&e(P,{screenshots:i})]})};export const AssistantToolChips=r(({tools:n,isActive:o,canUndo:i,onUndo:a})=>{let s=h(I),r=l(()=>{a(new Set(n.map(({id:e})=>e)))},[a,n]);return t(j,{"data-chips":o?"active":"done","aria-busy":o,children:[e(T,{children:e(A,{name:"Gear"})}),t("div",{children:[n.map(t=>e(B,{tool:t},t.id)),i&&t(E,{onClick:r,children:[e(u,{name:"ArrowCounterClockwise",fontSize:"inherit"}),s]})]})]})});
1
+ import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import{ButtonBase as i,ClickAwayListener as o,Tooltip as s,styled as a}from"@mui/material";import{memo as r,useCallback as l,useMemo as d,useRef as c,useState as m}from"react";import{match as p}from"ts-pattern";import{useLocalizable as h}from"#package/react-sdk";import{PhxIcon as u}from"#package/ui-sdk";import{assistantReferenceStyles as f}from"./reference-link/index.js";import{ScreenshotThumbnails as g,readToolScreenshots as k}from"./screenshots/index.js";import{AssistantPanelName as x}from"./theme.js";let y={id:"sdk.assistant.tool.updateDesign.label",message:"Update design"},b={id:"sdk.assistant.tool.readDesign.label",message:"Read design"},w={id:"sdk.assistant.tool.mistake.hint",message:"The assistant made a mistake."},v={id:"sdk.assistant.tool.cancelled.hint",message:"Stopped before it finished."},C={id:"sdk.assistant.tool.noResult.hint",message:"The result of this step was lost. It may or may not have been done."},I={id:"sdk.assistant.tool.toolBudget.hint",message:"Not done: the assistant reached its limit of steps for one message."},S={id:"sdk.assistant.tool.undo.label",message:"Undo"},D={id:"sdk.assistant.tool.screenshots.label",message:"{count, plural, one {# screenshot} other {# screenshots}}"},j=a("div",{name:x,slot:"chips"})(({theme:{palette:e,spacing:t,typography:n}})=>({...n.caption,alignItems:"start",color:e.text.secondary,display:"grid",gap:t(.75),gridTemplateColumns:"min-content minmax(0, 1fr)"})),z=a("span",{name:x,slot:"activity"})(({theme:{typography:e}})=>({blockSize:`calc(${e.caption.lineHeight} * 1em)`,display:"grid",placeItems:"center"})),A=a(u,{name:x,slot:"activityIcon"})({fontSize:14,'[data-chips="active"] &':{animation:"phx-assistant-turn 2.4s linear infinite","@media (prefers-reduced-motion: reduce)":{animation:"none"}},"@keyframes phx-assistant-turn":{to:{rotate:"360deg"}}}),T=a("span",{name:x,slot:"chip"})(({theme:{palette:e,spacing:t}})=>({cursor:"default",display:"inline-flex",maxInlineSize:"100%",verticalAlign:"top",whiteSpace:"nowrap","&:not(:last-of-type)::after":{color:e.text.secondary,content:'"\xb7"',flexShrink:0,marginInline:t(.75)}})),E=a("span",{name:x,slot:"screenshotsLink"})(f),L=a(i,{name:x,slot:"undoButton"})(({theme:{palette:e,shape:t,spacing:n}})=>({alignItems:"center",animation:"phx-assistant-undo-in 150ms ease-out",borderRadius:t.borderRadius,color:e.primary.main,display:"inline-flex",font:"inherit",gap:n(.5),marginInlineStart:n(1),verticalAlign:"top","&:hover":{textDecoration:"underline"},"@media (prefers-reduced-motion: reduce)":{animation:"none"},"@keyframes phx-assistant-undo-in":{from:{opacity:0}}})),R=a("span",{name:x,slot:"chipLabel"})(({theme:{palette:e}})=>({minInlineSize:0,overflow:"hidden",textOverflow:"ellipsis",'[data-chip="failed"] > &':{textDecoration:"line-through",textDecorationColor:e.error.main}})),P=a("span",{name:x,slot:"violation"})({display:"block"}),B=a("span",{name:x,slot:"fullLabel"})({display:"block"}),O=r(({tool:i})=>{let{chip:o,input:a,result:r}=i,d=h(y),u=h(b),f=h(w),g=h(v),k=h(C),x=h(I),S=c(null),[D,j]=m(!1),z=p(o.label).with({kind:"text"},({text:e})=>e).with({kind:"updateDesign"},()=>d).with({kind:"readDesign"},()=>u).exhaustive(),A=l(()=>{console.info(`Assistant tool call "${z}"`,{input:a,result:r})},[a,z,r]),E=l(()=>{let e=S.current;j(null!=e&&e.scrollWidth>e.clientWidth)},[]),L=p(o).with({errorCode:"cancelled"},()=>g).with({errorCode:"no_result"},()=>k).with({errorCode:"tool_budget"},()=>x).when(({violations:e})=>e.length>0,({violations:t})=>t.map((t,n)=>e(P,{children:t},n))).with({state:"failed"},()=>f).otherwise(()=>""),O=D?t(n,{children:[e(B,{children:z}),L]}):L;return e(s,{title:O,placement:"top-start",children:e(T,{onClick:A,onPointerEnter:E,"data-chip":o.state,children:e(R,{ref:S,children:z})})})}),U=r(({screenshots:t})=>{let n=h({...D,values:{count:t.length}}),[i,a]=m(!1),r=l(()=>a(!0),[]),d=l(()=>a(!1),[]),p=c(null),u=l(e=>{p.current=e},[]),f=l(()=>{p.current?.update()},[]),k=l(e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),a(!0))},[]);return e(T,{"data-chip":"screenshots",children:e(o,{onClickAway:d,mouseEvent:!!i&&"onClick",touchEvent:!!i&&"onTouchEnd",children:e(s,{open:i,onOpen:r,onClose:d,title:e(g,{screenshots:t,onImageLoad:f}),placement:"top-start",describeChild:!0,disableTouchListener:!0,PopperProps:{popperRef:u},slotProps:{tooltip:{sx:{background:"none",maxInlineSize:"none",padding:0}}},children:e(E,{role:"button",tabIndex:0,"aria-expanded":i,onClick:r,onKeyDown:k,children:n})})})})}),W=({tool:i})=>{let o=d(()=>k(i.result),[i.result]);return t(n,{children:[e(O,{tool:i}),o.length>0&&e(U,{screenshots:o})]})};export const AssistantToolChips=r(({tools:n,isActive:i,canUndo:o,onUndo:s})=>{let a=h(S),r=l(()=>{s(new Set(n.map(({id:e})=>e)))},[s,n]);return t(j,{"data-chips":i?"active":"done","aria-busy":i,children:[e(z,{children:e(A,{name:"Gear"})}),t("div",{children:[n.map(t=>e(W,{tool:t},t.id)),o&&t(L,{onClick:r,children:[e(u,{name:"ArrowCounterClockwise",fontSize:"inherit"}),a]})]})]})});
@@ -1,11 +1,14 @@
1
1
  import { type AssistantToolErrorCode } from '@salsita-ai/contracts/assistant';
2
2
  /**
3
- * How a tool call of the assistant looks in the thread: still running, finished, a change that was
4
- * not kept (`failed`), or a read that answered with errors (`flawed`), which matters less because
5
- * the assistant usually just asks again.
3
+ * How a tool call of the assistant looks in the thread: still running, finished, or gone wrong
4
+ * (`failed`): a change that was not kept, or a read that answered with errors. Both look the same,
5
+ * since the reply says what came of them.
6
+ */
7
+ export type AssistantToolChipState = 'running' | 'done' | 'failed';
8
+ /**
9
+ * What a tool chip is called: the title or the operation names the model gave, a fixed text, or the
10
+ * tool's name.
6
11
  */
7
- export type AssistantToolChipState = 'running' | 'done' | 'failed' | 'flawed';
8
- /** What a tool chip is called: the operation names the model gave, a fixed text, or the tool's name. */
9
12
  export type AssistantToolChipLabel = {
10
13
  readonly kind: 'text';
11
14
  readonly text: string;
@@ -22,6 +25,12 @@ export interface AssistantToolChip {
22
25
  * panel knows. Nothing for a call that went wrong for any other reason.
23
26
  */
24
27
  readonly errorCode: AssistantToolErrorCode | undefined;
28
+ /**
29
+ * The messages of the violations a failed call failed on, written for the user, in result order.
30
+ * Empty for a call that did not fail, that failed for any other reason, or whose violations have
31
+ * no message.
32
+ */
33
+ readonly violations: readonly string[];
25
34
  }
26
35
  /** A tool call of a message as the chip reads it. */
27
36
  export interface AssistantToolCall {
@@ -36,9 +45,10 @@ export interface AssistantToolCall {
36
45
  readonly isReplyRunning: boolean;
37
46
  }
38
47
  /**
39
- * Describes one tool call for its chip: the label in the order operation names, fixed text for the
40
- * `apply` and `query` tools, tool name; and whether the call runs, finished, or went wrong. Why it
41
- * went wrong is part of it only as the code of an error the server recorded: the text of a tool
42
- * result is worded for the model, not for the user.
48
+ * Describes one tool call for its chip: the label in the order title, operation names, fixed text
49
+ * for the `apply` and `query` tools, tool name; and whether the call runs, finished, or went wrong.
50
+ * Why it went wrong is part of it only as the code of an error the server recorded, or as the
51
+ * messages of the violations it failed on, which are written for the user: the rest of a tool result
52
+ * is worded for the model.
43
53
  */
44
54
  export declare const describeToolCall: (call: AssistantToolCall) => AssistantToolChip;
@@ -1 +1 @@
1
- import{Kind as e,parse as t}from"graphql";import{z as n}from"zod";import{ASSISTANT_TOOL_ERROR_CODES as r,AssistantToolError as a,applyTool as s,queryTool as o}from"@salsita-ai/contracts/assistant";let i=n.object({operations:n.array(n.object({query:n.string(),operationName:n.string().nullish()}))}),l=n.object({results:n.array(n.object({errors:n.array(n.unknown()).optional()})),committed:n.boolean()}),u=n.tuple([n.object({type:n.literal("text"),content:n.string()})]).rest(n.unknown());export const describeToolCall=n=>{let d=(({name:n,input:r})=>{let a,l=(a=i.safeParse(r)).success?a.data.operations.flatMap(({query:n,operationName:r})=>r??(n=>{try{let r=t(n).definitions.find(t=>t.kind===e.OPERATION_DEFINITION);return r?.kind===e.OPERATION_DEFINITION?r.name?.value:void 0}catch{return}})(n)??[]):[];return l.length>0?{kind:"text",text:l.join(", ")}:n===s.name?{kind:"updateDesign"}:n===o.name?{kind:"readDesign"}:{kind:"text",text:n}})(n);if(null==n.result&&null==n.error)return{label:d,state:n.isReplyRunning?"running":"done",errorCode:void 0};let c=(e=>{let t=a.safeParse(e);if(t.success)return r.find(e=>e===t.data.code)})(n.result);return{label:d,state:(({name:e,result:t,error:n},r)=>{if(null!=n||null!=r)return e===o.name?"flawed":"failed";if(e!==s.name&&e!==o.name)return"done";let a=l.safeParse((e=>{let t=u.safeParse(e);if(!t.success)return e;try{return JSON.parse(t.data[0].content)}catch{return e}})(t));if(!a.success)return e===o.name?"flawed":"failed";let{results:i,committed:d}=a.data;return e===s.name?d?"done":"failed":i.some(({errors:e})=>(e?.length??0)>0)||0===i.length?"flawed":"done"})(n,c),errorCode:c}};
1
+ import{Kind as e,parse as t}from"graphql";import{z as r}from"zod";import{ASSISTANT_TOOL_ERROR_CODES as a,AssistantToolError as n,applyTool as s,queryTool as i}from"@salsita-ai/contracts/assistant";let l=r.object({title:r.string().nullish().catch(void 0),operations:r.array(r.object({query:r.string(),operationName:r.string().nullish()}))}),o=r.object({results:r.array(r.object({errors:r.array(r.unknown()).optional()})),committed:r.boolean()}),u=r.tuple([r.object({type:r.literal("text"),content:r.string()})]).rest(r.unknown()),d=e=>{let t=u.safeParse(e);if(!t.success)return e;try{return JSON.parse(t.data[0].content)}catch{return e}},c=r.object({message:r.string(),extensions:r.object({code:r.literal("VIOLATION"),type:r.string()})});export const describeToolCall=r=>{var u;let f,m=(({name:r,input:a})=>{let n,o,u=(n=l.safeParse(a)).success&&n.data.title?.trim()||void 0;if(null!=u)return{kind:"text",text:u};let d=(o=l.safeParse(a)).success?o.data.operations.flatMap(({query:r,operationName:a})=>a??(r=>{try{let a=t(r).definitions.find(t=>t.kind===e.OPERATION_DEFINITION);return a?.kind===e.OPERATION_DEFINITION?a.name?.value:void 0}catch{return}})(r)??[]):[];return d.length>0?{kind:"text",text:d.join(", ")}:r===s.name?{kind:"updateDesign"}:r===i.name?{kind:"readDesign"}:{kind:"text",text:r}})(r);if(null==r.result&&null==r.error)return{label:m,state:r.isReplyRunning?"running":"done",errorCode:void 0,violations:[]};let p=(e=>{let t=n.safeParse(e);if(t.success)return a.find(e=>e===t.data.code)})(r.result),g=(({name:e,result:t,error:r},a)=>{if(null!=r||null!=a)return"failed";if(e!==s.name&&e!==i.name)return"done";let n=o.safeParse(d(t));if(!n.success)return"failed";let{results:l,committed:u}=n.data;return e===s.name?u?"done":"failed":l.some(({errors:e})=>(e?.length??0)>0)||0===l.length?"failed":"done"})(r,p);return{label:m,state:g,errorCode:p,violations:"failed"===g?(u=r.result,(f=o.safeParse(d(u))).success?f.data.results.flatMap(({errors:e})=>(e??[]).flatMap(e=>{let t=c.safeParse(e);return t.success&&t.data.message!==t.data.extensions.type?[t.data.message]:[]})):[]):[]}};
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import{useCallback as e,useMemo as o}from"react";import{useResolveLocalizable as a}from"#package/react-sdk";import{Preview as i,useResponsive as r}from"#package/ui-sdk";import{usePresetSelection as n,usePreview as s}from"../../../configurator-context/index.js";import{useLayoutSceneSafeArea as p}from"./use-layout-scene-safe-area.js";let u={id:"sdk.preview.customize.title",message:"Customize product"},m={id:"sdk.preview.start.button.label",message:"Start configuring"},c={layoutId:"ui-layout",initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{layout:{type:"spring",bounce:.2,duration:.6},opacity:{duration:.2,ease:"linear"}}};export const DesktopPreview=l=>{let{slotProps:d={},slots:f}=l,{enter:y}=s(),{hasMultiplePresets:g}=n(),{setAnimating:b}=r(),{containerRef:k,safeAreaRef:x,update:S}=p({enabled:!0,hasMiniSidebar:!1}),j=a(),w=e(()=>{b(!0)},[b]),v=e(()=>{b(!1),S()},[b,S]),A=o(()=>({...d,root:{...c,onLayoutAnimationStart:w,onLayoutAnimationComplete:v,...d.root}}),[v,w,d]);return t(i,{title:j(u),buttonLabel:j(m),containerRef:k,safeAreaRef:x,withScene:!g,slots:f,slotProps:A,onStart:y})};
1
+ import{jsx as t}from"react/jsx-runtime";import{useCallback as e,useMemo as o}from"react";import{usePresetSelection as a,useResolveLocalizable as i}from"#package/react-sdk";import{Preview as r,useResponsive as n}from"#package/ui-sdk";import{usePreview as s}from"../../../configurator-context/index.js";import{useLayoutSceneSafeArea as p}from"./use-layout-scene-safe-area.js";let u={id:"sdk.preview.customize.title",message:"Customize product"},m={id:"sdk.preview.start.button.label",message:"Start configuring"},c={layoutId:"ui-layout",initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{layout:{type:"spring",bounce:.2,duration:.6},opacity:{duration:.2,ease:"linear"}}};export const DesktopPreview=l=>{let{slotProps:d={},slots:f}=l,{enter:y}=s(),{hasMultiplePresets:g}=a(),{setAnimating:b}=n(),{containerRef:k,safeAreaRef:x,update:S}=p({enabled:!0,hasMiniSidebar:!1}),j=i(),w=e(()=>{b(!0)},[b]),v=e(()=>{b(!1),S()},[b,S]),A=o(()=>({...d,root:{...c,onLayoutAnimationStart:w,onLayoutAnimationComplete:v,...d.root}}),[v,w,d]);return t(r,{title:j(u),buttonLabel:j(m),containerRef:k,safeAreaRef:x,withScene:!g,slots:f,slotProps:A,onStart:y})};
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import{useCallback as e,useMemo as o}from"react";import{useResolveLocalizable as i}from"#package/react-sdk";import{Preview as a}from"#package/ui-sdk";import{usePresetSelection as r,usePreview as s}from"../../../configurator-context/index.js";import{useLayoutSceneSafeArea as n}from"./use-layout-scene-safe-area.js";let m={id:"sdk.preview.customize.title",message:"Customize product"},p={id:"sdk.preview.start.button.label",message:"Start configuring"},c={initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{opacity:{duration:.1,ease:"linear"}}};export const MobilePreview=l=>{let{slotProps:u={},slots:d}=l,{enter:f,isPreview:b}=s(),{hasMultiplePresets:g}=r(),{containerRef:k,safeAreaRef:x,update:y}=n({enabled:b,hasMiniSidebar:!1}),j=i(),w=e(()=>{y()},[y]),S=o(()=>({...u,root:{...c,onLayoutAnimationComplete:w,...u.root}}),[w,u]);return t(a,{title:j(m),buttonLabel:j(p),containerRef:k,safeAreaRef:x,withScene:!g,slots:d,slotProps:S,onStart:f})};
1
+ import{jsx as t}from"react/jsx-runtime";import{useCallback as e,useMemo as o}from"react";import{usePresetSelection as i,useResolveLocalizable as a}from"#package/react-sdk";import{Preview as r}from"#package/ui-sdk";import{usePreview as s}from"../../../configurator-context/index.js";import{useLayoutSceneSafeArea as n}from"./use-layout-scene-safe-area.js";let m={id:"sdk.preview.customize.title",message:"Customize product"},p={id:"sdk.preview.start.button.label",message:"Start configuring"},c={initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{opacity:{duration:.1,ease:"linear"}}};export const MobilePreview=l=>{let{slotProps:u={},slots:d}=l,{enter:f,isPreview:b}=s(),{hasMultiplePresets:g}=i(),{containerRef:k,safeAreaRef:x,update:y}=n({enabled:b,hasMiniSidebar:!1}),j=a(),w=e(()=>{y()},[y]),S=o(()=>({...u,root:{...c,onLayoutAnimationComplete:w,...u.root}}),[w,u]);return t(r,{title:j(m),buttonLabel:j(p),containerRef:k,safeAreaRef:x,withScene:!g,slots:d,slotProps:S,onStart:f})};
@@ -1 +1 @@
1
- import{jsx as o}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t}from"@mui/material";import{memo as e,useCallback as i}from"react";import{FrontendAnalyticsFactory as a,useAnalyticsService as m,useConfiguratorRouting as n,useIntegrationState as s}from"#package/react-sdk";import{PhxIcon as c}from"#package/ui-sdk";import{usePresetSelection as l,usePreview as p}from"../../../../configurator-context/index.js";import{CloseConfiguratorButton as d}from"./CloseConfiguratorButton.js";export const CommonTopNavigation=e(()=>{let e=m(),f=n(),{presetCategories:u}=l(),{isPreview:g,isPreviewEnabled:k}=p(),x=u.flatMap(o=>o.presets).length>1,C=s(),j=i(()=>{e.push(a.GoToProductsClicked()),f.goToIndex()},[e,f]);if(!C.embeddedView)return x||!k||g?x?o(t,{size:"small",startIcon:o(c,{name:"ArrowLeft"}),onClick:j,children:o(r,{id:"sdk.layout.navigation.common.product.label",message:"Website"})}):null:o(d,{})});
1
+ import{jsx as o}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t}from"@mui/material";import{memo as e,useCallback as i}from"react";import{FrontendAnalyticsFactory as a,useAnalyticsService as m,useConfiguratorRouting as n,useIntegrationState as s,usePresetSelection as c}from"#package/react-sdk";import{PhxIcon as l}from"#package/ui-sdk";import{usePreview as p}from"../../../../configurator-context/index.js";import{CloseConfiguratorButton as d}from"./CloseConfiguratorButton.js";export const CommonTopNavigation=e(()=>{let e=m(),f=n(),{presetCategories:u}=c(),{isPreview:g,isPreviewEnabled:k}=p(),x=u.flatMap(o=>o.presets).length>1,C=s(),j=i(()=>{e.push(a.GoToProductsClicked()),f.goToIndex()},[e,f]);if(!C.embeddedView)return x||!k||g?x?o(t,{size:"small",startIcon:o(l,{name:"ArrowLeft"}),onClick:j,children:o(r,{id:"sdk.layout.navigation.common.product.label",message:"Website"})}):null:o(d,{})});
@@ -1 +1 @@
1
- import{jsx as o}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t}from"@mui/material";import{memo as e,useCallback as i}from"react";import{FrontendAnalyticsFactory as a,useAnalyticsService as m,useConfiguratorRouting as s,usePresetEmbeddedState as n}from"#package/react-sdk";import{PhxIcon as l}from"#package/ui-sdk";import{usePresetSelection as p,usePreview as c}from"../../../../configurator-context/index.js";import{CloseConfiguratorButton as f}from"../common/CloseConfiguratorButton.js";export const SimpleMobileTopNavigation=e(()=>{let e=m(),u=s(),{presetCategories:d}=p(),{isPreview:g,isPreviewEnabled:k}=c(),x=d.flatMap(o=>o.presets).length>1,b=i(()=>{e.push(a.GoToProductsClicked()),u.goToIndex()},[e,u]);if(!n())return x||g||!k?x?o(t,{size:"small",startIcon:o(l,{name:"ArrowLeft"}),onClick:b,children:o(r,{id:"sdk.layout.navigation.mobile.product.label",message:"Website"})}):null:o(f,{})});
1
+ import{jsx as o}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t}from"@mui/material";import{memo as e,useCallback as i}from"react";import{FrontendAnalyticsFactory as a,useAnalyticsService as m,useConfiguratorRouting as s,usePresetEmbeddedState as n,usePresetSelection as l}from"#package/react-sdk";import{PhxIcon as p}from"#package/ui-sdk";import{usePreview as c}from"../../../../configurator-context/index.js";import{CloseConfiguratorButton as f}from"../common/CloseConfiguratorButton.js";export const SimpleMobileTopNavigation=e(()=>{let e=m(),u=s(),{presetCategories:d}=l(),{isPreview:g,isPreviewEnabled:k}=c(),x=d.flatMap(o=>o.presets).length>1,b=i(()=>{e.push(a.GoToProductsClicked()),u.goToIndex()},[e,u]);if(!n())return x||g||!k?x?o(t,{size:"small",startIcon:o(p,{name:"ArrowLeft"}),onClick:b,children:o(r,{id:"sdk.layout.navigation.mobile.product.label",message:"Website"})}):null:o(f,{})});
@@ -1 +1 @@
1
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{memo as i,useCallback as o}from"react";import{FrontendAnalyticsFactory as s,useActiveNavigationState as n,useAnalyticsService as r,useConfiguratorRouting as p,useDomain as c,usePresetEmbeddedState as l,useResolveLocalizable as d}from"#package/react-sdk";import{TopNavigation as m,useResponsive as g}from"#package/ui-sdk";import{usePresetSelection as u}from"../../../../configurator-context/index.js";export const StepsNavigation=i(i=>{let{steps:f}=i,k=r(),{navigationSystem:v,storeSystem:x}=c(),h=n(),C=p(),S=d(),{presetCategories:T}=u(),j=l(),N=T.flatMap(t=>t.presets).length>1,b=!j&&N,I=f.findIndex(t=>t.navigationStates.includes(h))+ +!!b,{isTablet:P}=g(),y=o(()=>{k.push(s.GoToProductsClicked()),C.goToIndex()},[k,C]);return e(m.Root,{activeStep:I,nonLinear:!0,compact:P,fullWidth:!0,children:[b&&t(m.Step,{isCompleted:!0,onClick:y,compact:P,children:t(a,{id:"sdk.layout.navigation.steps.first.label",message:"Products"})}),f.map((e,a)=>{let i=b?a<I-1:a<I,o=S(e.label);return t(m.Step,{isCompleted:i,isDisabled:!i,compact:P,onClick:()=>{let t=e.navigationStates[0];t&&(k.push(s.TopNavigationStepClicked(t)),x.stageAndCommit([v.getNavigationUpdate(t)]))},children:o},o)})]})});
1
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{memo as i,useCallback as o}from"react";import{FrontendAnalyticsFactory as s,useActiveNavigationState as n,useAnalyticsService as r,useConfiguratorRouting as p,useDomain as c,usePresetEmbeddedState as l,usePresetSelection as d,useResolveLocalizable as m}from"#package/react-sdk";import{TopNavigation as g,useResponsive as u}from"#package/ui-sdk";export const StepsNavigation=i(i=>{let{steps:f}=i,k=r(),{navigationSystem:v,storeSystem:h}=c(),C=n(),S=p(),x=m(),{presetCategories:T}=d(),N=l(),b=T.flatMap(t=>t.presets).length>1,j=!N&&b,I=f.findIndex(t=>t.navigationStates.includes(C))+ +!!j,{isTablet:P}=u(),y=o(()=>{k.push(s.GoToProductsClicked()),S.goToIndex()},[k,S]);return e(g.Root,{activeStep:I,nonLinear:!0,compact:P,fullWidth:!0,children:[j&&t(g.Step,{isCompleted:!0,onClick:y,compact:P,children:t(a,{id:"sdk.layout.navigation.steps.first.label",message:"Products"})}),f.map((e,a)=>{let i=j?a<I-1:a<I,o=x(e.label);return t(g.Step,{isCompleted:i,isDisabled:!i,compact:P,onClick:()=>{let t=e.navigationStates[0];t&&(k.push(s.TopNavigationStepClicked(t)),h.stageAndCommit([v.getNavigationUpdate(t)]))},children:o},o)})]})});
@@ -1 +1 @@
1
- import{jsx as o,jsxs as t,Fragment as e}from"react/jsx-runtime";import{useCallback as a,useMemo as i}from"react";import{customPriceFooterComponent as n,navigationStepsComponent as r,sidebarTabsComponent as s}from"#package/domain";import{useActiveNavigationState as m,useComponents as l,useConfiguratorRouting as p,useDomain as c,useFirstRootComponent as f,usePresetEmbeddedState as d,useResolveLocalizable as g,useRootEntityPrice as u,useSelectedDomainEntityId as v,useStoreSelector as b}from"#package/react-sdk";import{MobileControls as j}from"#package/ui-sdk";import{usePresetSelection as S}from"../../../../configurator-context/index.js";import{LayoutSlots as x}from"../../../configurator-layout/index.js";import{LayoutDialog as C}from"../../../phoenix-layout-elements/LayoutDialog.js";import{LayoutFooter as y,LayoutToolbarDesktop as k,LayoutToolbarDesktopFullScreen as T}from"../../../phoenix-layout-elements/index.js";import{SaveMessageSnackbars as I}from"../../../save-message-snackbars/index.js";import{FullscreenDesktopToolbar as h}from"../../toolbar/desktop-toolbar/FullscreenDesktopToolbar.js";import{CommonDesktopToolbar as N}from"../common/CommonDesktopToolbar.js";import{CommonFinalizePage as w}from"../common/CommonFinalizePage.js";import{DefaultViewOnlyMessage as A}from"../common/DefaultViewOnlyMessage.js";import{InvariantViolations as D}from"../common/InvariantViolations.js";import{ReactiveInterfaceLayout as E}from"../common/ReactiveInterfaceLayout.js";import{SideEffects as L}from"../common/SideEffects.js";import{ToolControls as M}from"../common/ToolControls.js";import{ViewControls as P}from"../common/ViewControls.js";import{StepsNavigation as V}from"./StepsNavigation.js";import{StepsSideBar as F}from"./StepsSideBar.js";export const StepsOwnerLayout=()=>{let{storeSystem:O,navigationSystem:B}=c(),H=g(),R=m(),U=v(),z=f(r),$=f(n),q=l({componentTypes:[s],entityIds:[U]}),G=i(()=>z?.state.steps??[],[z]),J=i(()=>(q??[]).flatMap(o=>o.state.tabs).map(o=>{let t=o.navigationStates[0];if(!t)throw Error(`Tab ${t} has no navigation states!`);return{label:H(o.label),icon:o.icon,value:t,isActive:o.navigationStates.includes(R)}}),[q,R,H]),K=i(()=>{let o=J.find(o=>o.isActive);return o?.value??"none"},[J]),Q=b(o=>U===o.state.rootEntityId,[U]),W=u(),X=p(),{presetCategories:Y}=S(),Z=d(),_=Y.flatMap(o=>o.presets).length>1,oo=!Z&&_,ot=a(()=>{let o=G.findIndex(o=>o.navigationStates.includes(R)),t=G[o-1];if(!t){oo&&X.goToIndex();return}let e=t.navigationStates[0];e&&O.stageAndCommit([B.getNavigationUpdate(e)])},[B,R,G,oo,X,O]),oe=a(()=>{let o=G.findIndex(o=>o.navigationStates.includes(R)),t=G[o+1];if(!t)return;let e=t.navigationStates[0];e&&O.stageAndCommit([B.getNavigationUpdate(e)])},[B,R,G,O]),oa=i(()=>G.findIndex(o=>o.navigationStates.includes(R))===G.length-1,[G,R]);return o(E,{canvas:o(x.Canvas,{}),sidebar:o(F,{price:W,tabs:J,activeTab:K,isRootPage:Q,customPriceNode:$?.state.node,isLastStep:oa,onNextStepClick:oe,onPreviousStepClick:ot}),viewControls:o(P,{}),toolControls:o(M,{}),topNavigation:o(V,{steps:G}),branding:null,toolbar:o(k,{defaultSlot:()=>o(N,{})}),fullScreenToolbar:o(T,{defaultSlot:()=>o(h,{})}),overlay:t(e,{children:[o(D,{}),o(I,{}),o(w,{}),o(C,{})]}),mobileControls:o(j.ViewOnlyMode,{message:o(A,{})}),mobileTopNavigation:null,mobileHeaderActionButton:null,mobileHeaderCenter:null,sideEffects:o(L,{}),footer:o(y,{})})};
1
+ import{jsx as o,jsxs as t,Fragment as e}from"react/jsx-runtime";import{useCallback as a,useMemo as i}from"react";import{customPriceFooterComponent as n,navigationStepsComponent as r,sidebarTabsComponent as s}from"#package/domain";import{useActiveNavigationState as m,useComponents as l,useConfiguratorRouting as p,useDomain as c,useFirstRootComponent as f,usePresetEmbeddedState as d,usePresetSelection as g,useResolveLocalizable as u,useRootEntityPrice as v,useSelectedDomainEntityId as b,useStoreSelector as j}from"#package/react-sdk";import{MobileControls as S}from"#package/ui-sdk";import{LayoutSlots as x}from"../../../configurator-layout/index.js";import{LayoutDialog as C}from"../../../phoenix-layout-elements/LayoutDialog.js";import{LayoutFooter as y,LayoutToolbarDesktop as k,LayoutToolbarDesktopFullScreen as T}from"../../../phoenix-layout-elements/index.js";import{SaveMessageSnackbars as I}from"../../../save-message-snackbars/index.js";import{FullscreenDesktopToolbar as h}from"../../toolbar/desktop-toolbar/FullscreenDesktopToolbar.js";import{CommonDesktopToolbar as N}from"../common/CommonDesktopToolbar.js";import{CommonFinalizePage as w}from"../common/CommonFinalizePage.js";import{DefaultViewOnlyMessage as A}from"../common/DefaultViewOnlyMessage.js";import{InvariantViolations as D}from"../common/InvariantViolations.js";import{ReactiveInterfaceLayout as E}from"../common/ReactiveInterfaceLayout.js";import{SideEffects as L}from"../common/SideEffects.js";import{ToolControls as M}from"../common/ToolControls.js";import{ViewControls as P}from"../common/ViewControls.js";import{StepsNavigation as V}from"./StepsNavigation.js";import{StepsSideBar as F}from"./StepsSideBar.js";export const StepsOwnerLayout=()=>{let{storeSystem:O,navigationSystem:B}=c(),H=u(),R=m(),U=b(),z=f(r),$=f(n),q=l({componentTypes:[s],entityIds:[U]}),G=i(()=>z?.state.steps??[],[z]),J=i(()=>(q??[]).flatMap(o=>o.state.tabs).map(o=>{let t=o.navigationStates[0];if(!t)throw Error(`Tab ${t} has no navigation states!`);return{label:H(o.label),icon:o.icon,value:t,isActive:o.navigationStates.includes(R)}}),[q,R,H]),K=i(()=>{let o=J.find(o=>o.isActive);return o?.value??"none"},[J]),Q=j(o=>U===o.state.rootEntityId,[U]),W=v(),X=p(),{presetCategories:Y}=g(),Z=d(),_=Y.flatMap(o=>o.presets).length>1,oo=!Z&&_,ot=a(()=>{let o=G.findIndex(o=>o.navigationStates.includes(R)),t=G[o-1];if(!t){oo&&X.goToIndex();return}let e=t.navigationStates[0];e&&O.stageAndCommit([B.getNavigationUpdate(e)])},[B,R,G,oo,X,O]),oe=a(()=>{let o=G.findIndex(o=>o.navigationStates.includes(R)),t=G[o+1];if(!t)return;let e=t.navigationStates[0];e&&O.stageAndCommit([B.getNavigationUpdate(e)])},[B,R,G,O]),oa=i(()=>G.findIndex(o=>o.navigationStates.includes(R))===G.length-1,[G,R]);return o(E,{canvas:o(x.Canvas,{}),sidebar:o(F,{price:W,tabs:J,activeTab:K,isRootPage:Q,customPriceNode:$?.state.node,isLastStep:oa,onNextStepClick:oe,onPreviousStepClick:ot}),viewControls:o(P,{}),toolControls:o(M,{}),topNavigation:o(V,{steps:G}),branding:null,toolbar:o(k,{defaultSlot:()=>o(N,{})}),fullScreenToolbar:o(T,{defaultSlot:()=>o(h,{})}),overlay:t(e,{children:[o(D,{}),o(I,{}),o(w,{}),o(C,{})]}),mobileControls:o(S.ViewOnlyMode,{message:o(A,{})}),mobileTopNavigation:null,mobileHeaderActionButton:null,mobileHeaderCenter:null,sideEffects:o(L,{}),footer:o(y,{})})};
@@ -1 +1 @@
1
- import{useMemo as e}from"react";import{FrontendAnalyticsFactory as o,useAccessService as t,useAnalyticsService as i,useConfiguratorRouting as a,useDomainApplication as r,useIntegrationState as d}from"#package/react-sdk";import{usePresetSelection as n,usePreview as s}from"../../../../../configurator-context/index.js";import{useCloseAction as c}from"../../../../../integration/index.js";export const useGoBackAction=()=>{let l=i(),{configurationPersistSystem:p}=r(),u=a(),{presetCategories:m}=n(),{isPreview:w,isPreviewEnabled:f,leave:g}=s(),{accessInfo:x}=t(),k=m.flatMap(e=>e.presets).length>1,v=d(),C=c();return e(()=>v.embeddedView?null:k?async()=>{l.push(o.GoToProductsClicked()),x.viewMode||await p.save(),u.goToIndex()}:null!==C?async()=>{l.push(o.CloseConfiguratorClicked()),x.viewMode||await p.save(),await C()}:f&&!w?()=>{l.push(o.ExpandedViewClosed()),g()}:null,[l,p,k,v.embeddedView,w,f,g,u,C,x.viewMode])};
1
+ import{useMemo as e}from"react";import{FrontendAnalyticsFactory as o,useAccessService as t,useAnalyticsService as i,useConfiguratorRouting as a,useDomainApplication as r,useIntegrationState as d,usePresetSelection as n}from"#package/react-sdk";import{usePreview as s}from"../../../../../configurator-context/index.js";import{useCloseAction as c}from"../../../../../integration/index.js";export const useGoBackAction=()=>{let l=i(),{configurationPersistSystem:p}=r(),u=a(),{presetCategories:m}=n(),{isPreview:w,isPreviewEnabled:f,leave:g}=s(),{accessInfo:x}=t(),k=m.flatMap(e=>e.presets).length>1,v=d(),C=c();return e(()=>v.embeddedView?null:k?async()=>{l.push(o.GoToProductsClicked()),x.viewMode||await p.save(),u.goToIndex()}:null!==C?async()=>{l.push(o.CloseConfiguratorClicked()),x.viewMode||await p.save(),await C()}:f&&!w?()=>{l.push(o.ExpandedViewClosed()),g()}:null,[l,p,k,v.embeddedView,w,f,g,u,C,x.viewMode])};
@@ -1 +1 @@
1
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import{Trans as o}from"@lingui/react";import{memo as a,useCallback as i}from"react";import{FrontendAnalyticsFactory as r,useAnalyticsService as s,useConfiguratorRouting as c,usePresetEmbeddedState as p}from"#package/react-sdk";import{TopNavigation as l,useResponsive as n}from"#package/ui-sdk";import{usePresetSelection as m}from"../../../../../configurator-context/index.js";export const StepsNavigation=a(a=>{let{steps:d,activeIndex:u,goTo:f}=a,g=s(),k=c(),{presetCategories:x}=m(),h=p(),C=x.flatMap(t=>t.presets).length>1,b=!h&&C,{isTablet:j}=n(),v=i(()=>{g.push(r.GoToProductsClicked()),k.goToIndex()},[g,k]);return e(l.Root,{activeStep:u+ +!!b,nonLinear:!0,compact:j,fullWidth:!0,children:[b&&t(l.Step,{isCompleted:!0,onClick:v,compact:j,children:t(o,{id:"sdk.layout.navigation.steps.first.label",message:"Products"})}),d.map(e=>{let o="complete"===e.status;return t(l.Step,{isCompleted:o,isDisabled:!o,compact:j,onClick:()=>f(e.index),children:e.label},e.label)})]})});
1
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{memo as o,useCallback as i}from"react";import{FrontendAnalyticsFactory as s,useAnalyticsService as r,useConfiguratorRouting as l,usePresetEmbeddedState as p,usePresetSelection as c}from"#package/react-sdk";import{TopNavigation as n,useResponsive as m}from"#package/ui-sdk";export const StepsNavigation=o(o=>{let{steps:d,activeIndex:u,goTo:g}=o,f=r(),k=l(),{presetCategories:h}=c(),x=p(),C=h.flatMap(t=>t.presets).length>1,b=!x&&C,{isTablet:v}=m(),S=i(()=>{f.push(s.GoToProductsClicked()),k.goToIndex()},[f,k]);return e(n.Root,{activeStep:u+ +!!b,nonLinear:!0,compact:v,fullWidth:!0,children:[b&&t(n.Step,{isCompleted:!0,onClick:S,compact:v,children:t(a,{id:"sdk.layout.navigation.steps.first.label",message:"Products"})}),d.map(e=>{let a="complete"===e.status;return t(n.Step,{isCompleted:a,isDisabled:!a,compact:v,onClick:()=>g(e.index),children:e.label},e.label)})]})});
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{useMemo as t}from"react";import{customPriceFooterComponent as o,navigationStepsComponent as i}from"#package/domain";import{useAccessService as a,useActiveNavigationState as r,useFirstRootComponent as s,usePresetEmbeddedState as n,useRootEntityPrice as d}from"#package/react-sdk";import{useHasSidebarSummary as m,useIsSidebarSummaryActive as p,usePresetSelection as c}from"../../../../configurator-context/index.js";import{EnterSummaryButton as l,SaveTemplateButton as f}from"../common/index.js";import{BasicFinalizeButton as u}from"./BasicFinalizeButton.js";export const PRICE_LABEL={id:"sdk.layout.sidebar.price.label",message:"Total price"};export const useBasicSidebarFooter=()=>{let g=r(),v=s(i),x=s(o),B=t(()=>v?.state.steps??[],[v]),S=d(),{presetCategories:b}=c(),h=!!n(),j=b.flatMap(e=>e.presets).length>1,k=B.length>1,M=B.find(e=>e.navigationStates.includes(g)),w=t(()=>B.findIndex(e=>e.navigationStates.includes(g)),[B,g]),P=t(()=>0===w,[w]),D=t(()=>w===B.length-1,[w,B.length]),E=h?e(f,{}):e(u,{}),F=p(),I=m(),L=k||!I||F?E:e(l,{}),{accessInfo:y}=a(),z=!y.viewMode&&k&&(!D||!L),A=!y.viewMode&&k,C=!y.viewMode&&(!k||D);return{currentStep:M,currentStepIndex:w,customPriceNode:x?.state.node??void 0,finalizeOrSummaryButton:L,formattedPrice:x?.state.node?void 0:S??void 0,hasSteps:k,nextStepButtonDisabled:D,previousStepButtonDisabled:P&&!(!h&&j),showFinalizeButton:C,showNextStepButton:z,showPreviousStepButton:A,totalSteps:B.length}};
1
+ import{jsx as e}from"react/jsx-runtime";import{useMemo as t}from"react";import{customPriceFooterComponent as o,navigationStepsComponent as i}from"#package/domain";import{useAccessService as a,useActiveNavigationState as r,useFirstRootComponent as s,usePresetEmbeddedState as n,usePresetSelection as d,useRootEntityPrice as m}from"#package/react-sdk";import{useHasSidebarSummary as p,useIsSidebarSummaryActive as c}from"../../../../configurator-context/index.js";import{EnterSummaryButton as l,SaveTemplateButton as f}from"../common/index.js";import{BasicFinalizeButton as u}from"./BasicFinalizeButton.js";export const PRICE_LABEL={id:"sdk.layout.sidebar.price.label",message:"Total price"};export const useBasicSidebarFooter=()=>{let g=r(),v=s(i),x=s(o),B=t(()=>v?.state.steps??[],[v]),S=m(),{presetCategories:b}=d(),h=!!n(),j=b.flatMap(e=>e.presets).length>1,k=B.length>1,M=B.find(e=>e.navigationStates.includes(g)),w=t(()=>B.findIndex(e=>e.navigationStates.includes(g)),[B,g]),P=t(()=>0===w,[w]),D=t(()=>w===B.length-1,[w,B.length]),E=h?e(f,{}):e(u,{}),F=c(),I=p(),L=k||!I||F?E:e(l,{}),{accessInfo:y}=a(),z=!y.viewMode&&k&&(!D||!L),A=!y.viewMode&&k,C=!y.viewMode&&(!k||D);return{currentStep:M,currentStepIndex:w,customPriceNode:x?.state.node??void 0,finalizeOrSummaryButton:L,formattedPrice:x?.state.node?void 0:S??void 0,hasSteps:k,nextStepButtonDisabled:D,previousStepButtonDisabled:P&&!(!h&&j),showFinalizeButton:C,showNextStepButton:z,showPreviousStepButton:A,totalSteps:B.length}};
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import{useCallback as r,useState as s}from"react";import{useResolveLocalizable as o,useResourceUrl as l}from"#package/react-sdk";import{Preset as n}from"#package/ui-sdk";import{ConfigurationNotFoundPageElement as a}from"../../configuration-not-found-page/index.js";import{usePresetSelection as d,usePreview as m}from"../../configurator-context/index.js";import{ClosePresetScreenButton as c}from"./ClosePresetScreenButton.js";import{PresetBackButton as g}from"./PresetBackButton.js";import{PresetPreviewLayout as p}from"./PresetPreviewLayout.js";import{PresetSnackbarsRoot as u}from"./PresetSnackbarsRoot.js";let f={id:"sdk.presets.select.button.label",message:"Select"},k={id:"sdk.presets.detail.close.label",message:"Close"},S={id:"sdk.presets.detail.learnMore.label",message:"Learn more"},h={id:"sdk.presets.detail.select.label",message:"Select"},B=t=>{let{id:i,name:s,description:a,img:m,imgAlt:c,detailTitle:g,detailDescription:p}=t,{selectPreset:u,creatingPresetId:B}=d(),b=o(),{getResourceUrl:C}=l(),T=r(()=>{u(i)},[u,i]),j=(m&&C(m))??"",y=B===i;return e(n.Card,{title:b(s),description:b(a),imgSrc:j,imgAlt:b(c),selectButtonTitle:b(f),loading:y,disabled:null!==B&&!y,onSelect:T,additionalInfoButton:void 0!==g&&void 0!==p&&e(n.DetailDialog,{img:j,imgAlt:b(c),detailTitle:b(g),detailDescription:b(p),closeButtonTitle:b(k),learnMoreLinkTitle:b(S),selectButtonTitle:b(h),onSelect:T})},b(s))},b=t=>{let{id:i,name:s,description:a,img:d,imgAlt:m,onSelect:c}=t,g=o(),{getResourceUrl:p}=l(),u=r(()=>{c(i)},[c,i]);return e(n.Card,{title:g(s),description:g(a),imgSrc:(d&&p(d))??"",imgAlt:g(m),selectButtonTitle:g(f),onSelect:u},g(s))},C={id:"sdk.presets.category.count.message",message:"{presetCount, plural, one {# preset} other {# presets}}"},T=t=>{let{selectedCategory:r,onCategorySelected:s}=t,{presetCategories:l}=d(),n=o();if(1===l.length)return e(i,{children:l[0].presets.map(t=>e(B,{id:t.id,name:t.name,description:t.description,img:t.img,imgAlt:t.imgAlt,detailTitle:t.detailTitle,detailDescription:t.detailDescription},t.id))});if(null!==r){let t=l.find(e=>e.id===r);if(void 0===t)throw Error(`Category with id ${r} not found!`);return e(i,{children:t.presets.map(t=>e(B,{id:t.id,name:t.name,description:t.description,img:t.img,imgAlt:t.imgAlt,detailTitle:t.detailTitle,detailDescription:t.detailDescription},t.id))})}return e(i,{children:l.map(t=>e(b,{id:t.id,name:t.name,description:t.description??n({...C,values:{presetCount:t.presets.length}}),img:t.img,imgAlt:t.imgAlt,onSelect:s},t.id))})},j={id:"sdk.presets.category.heading.title",message:"Select starting preset"},y={id:"sdk.presets.preview.title",message:"Customize product"},A={id:"sdk.presets.start.button.label",message:"Start configuring"};export const CategoryPresetUi=l=>{let{action:f,footer:k,overlay:S}=l,[h,B]=s(null),{isPreview:b}=m(),C=o(),v=r(()=>{B(null)},[]),{presetCategories:x}=d();return b?e(p,{title:C(y),startButtonLabel:C(A)}):0===x.length?e(a,{}):t(i,{children:[e(n.ScreenLayout,{heading:C(j),action:f,footer:k,overlay:S,backButton:h&&e(g,{onBack:v}),closeButton:!h&&e(c,{}),children:e(T,{selectedCategory:h,onCategorySelected:B})}),e(u,{})]})};
1
+ import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import{useCallback as r,useState as s}from"react";import{usePresetSelection as o,useResolveLocalizable as l,useResourceUrl as n}from"#package/react-sdk";import{Preset as a}from"#package/ui-sdk";import{ConfigurationNotFoundPageElement as d}from"../../configuration-not-found-page/index.js";import{usePreview as m}from"../../configurator-context/index.js";import{ClosePresetScreenButton as c}from"./ClosePresetScreenButton.js";import{PresetBackButton as g}from"./PresetBackButton.js";import{PresetPreviewLayout as p}from"./PresetPreviewLayout.js";import{PresetSnackbarsRoot as u}from"./PresetSnackbarsRoot.js";let f={id:"sdk.presets.select.button.label",message:"Select"},k={id:"sdk.presets.detail.close.label",message:"Close"},S={id:"sdk.presets.detail.learnMore.label",message:"Learn more"},h={id:"sdk.presets.detail.select.label",message:"Select"},B=t=>{let{id:i,name:s,description:d,img:m,imgAlt:c,detailTitle:g,detailDescription:p}=t,{selectPreset:u,creatingPresetId:B}=o(),b=l(),{getResourceUrl:C}=n(),T=r(()=>{u(i)},[u,i]),j=(m&&C(m))??"",y=B===i;return e(a.Card,{title:b(s),description:b(d),imgSrc:j,imgAlt:b(c),selectButtonTitle:b(f),loading:y,disabled:null!==B&&!y,onSelect:T,additionalInfoButton:void 0!==g&&void 0!==p&&e(a.DetailDialog,{img:j,imgAlt:b(c),detailTitle:b(g),detailDescription:b(p),closeButtonTitle:b(k),learnMoreLinkTitle:b(S),selectButtonTitle:b(h),onSelect:T})},b(s))},b=t=>{let{id:i,name:s,description:o,img:d,imgAlt:m,onSelect:c}=t,g=l(),{getResourceUrl:p}=n(),u=r(()=>{c(i)},[c,i]);return e(a.Card,{title:g(s),description:g(o),imgSrc:(d&&p(d))??"",imgAlt:g(m),selectButtonTitle:g(f),onSelect:u},g(s))},C={id:"sdk.presets.category.count.message",message:"{presetCount, plural, one {# preset} other {# presets}}"},T=t=>{let{selectedCategory:r,onCategorySelected:s}=t,{presetCategories:n}=o(),a=l();if(1===n.length)return e(i,{children:n[0].presets.map(t=>e(B,{id:t.id,name:t.name,description:t.description,img:t.img,imgAlt:t.imgAlt,detailTitle:t.detailTitle,detailDescription:t.detailDescription},t.id))});if(null!==r){let t=n.find(e=>e.id===r);if(void 0===t)throw Error(`Category with id ${r} not found!`);return e(i,{children:t.presets.map(t=>e(B,{id:t.id,name:t.name,description:t.description,img:t.img,imgAlt:t.imgAlt,detailTitle:t.detailTitle,detailDescription:t.detailDescription},t.id))})}return e(i,{children:n.map(t=>e(b,{id:t.id,name:t.name,description:t.description??a({...C,values:{presetCount:t.presets.length}}),img:t.img,imgAlt:t.imgAlt,onSelect:s},t.id))})},j={id:"sdk.presets.category.heading.title",message:"Select starting preset"},y={id:"sdk.presets.preview.title",message:"Customize product"},A={id:"sdk.presets.start.button.label",message:"Start configuring"};export const CategoryPresetUi=n=>{let{action:f,footer:k,overlay:S}=n,[h,B]=s(null),{isPreview:b}=m(),C=l(),v=r(()=>{B(null)},[]),{presetCategories:x}=o();return b?e(p,{title:C(y),startButtonLabel:C(A)}):0===x.length?e(d,{}):t(i,{children:[e(a.ScreenLayout,{heading:C(j),action:f,footer:k,overlay:S,backButton:h&&e(g,{onBack:v}),closeButton:!h&&e(c,{}),children:e(T,{selectedCategory:h,onCategorySelected:B})}),e(u,{})]})};
@@ -1 +1 @@
1
- import{jsx as r}from"react/jsx-runtime";import{Trans as e}from"@lingui/react";import{Button as s}from"@mui/material";import{useSnackbar as i}from"notistack";import{useEffect as t}from"react";import{useApplicationRuntime as o,useApplicationRuntimeSelector as a,useConfiguratorMessages as n}from"#package/react-sdk";let m="phx-configuration-persist-system-failure";export const SaveMessageSnackbars=()=>{let c=a(o().selectors.domainContext.configurator.getIsViewMode),{enqueueSnackbar:d,closeSnackbar:p}=i();return t(()=>{c&&p(m)},[c,p]),n(i=>{c||("saveError"===i.kind&&d(r(e,{id:"sdk.persist.system.error.message",message:"An error occured when trying to update a configuration"}),{variant:"error",key:m,persist:!0,preventDuplicate:!0,action:i=>r(s,{color:"inherit",size:"small",onClick:()=>{p(i)},children:r(e,{id:"sdk.persist.system.error.dismiss",message:"Dismiss"})})}),"saveRecovery"===i.kind&&(p(m),d(r(e,{id:"sdk.persist.system.error.recovered",message:"Configuration updated"}),{variant:"info"})))}),null};
1
+ import{jsx as e}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{useSnackbar as s}from"notistack";import{useEffect as t}from"react";import{useApplicationRuntime as i,useApplicationRuntimeSelector as o,useConfiguratorMessages as a}from"#package/react-sdk";let n="phx-configuration-persist-system-failure";export const SaveMessageSnackbars=()=>{let m=o(i().selectors.domainContext.configurator.getIsViewMode),{enqueueSnackbar:c,closeSnackbar:d}=s();return t(()=>{m&&d(n)},[m,d]),a(s=>{m||("saveError"===s.kind&&c(e(r,{id:"sdk.persist.system.error.message",message:"An error occured when trying to update a configuration"}),{variant:"error",key:n,persist:!0,preventDuplicate:!0,actionButton:{label:e(r,{id:"sdk.persist.system.error.dismiss",message:"Dismiss"}),onClick:e=>{d(e)}}}),"saveRecovery"===s.kind&&(d(n),c(e(r,{id:"sdk.persist.system.error.recovered",message:"Configuration updated"}),{variant:"info"})))}),null};
@@ -777,7 +777,7 @@ components:
777
777
  autoRotate: true
778
778
  # Back-to-back snap: the dragged cabinet's back snaps onto another
779
779
  # cabinet's back face (the snapPlane below). autoRotate orients it
780
- # 180° so the two cabinets face away from each other. Same Moduline
780
+ # 180° so the two cabinets face away from each other. This is the
781
781
  # shape that drives the within-MTV bug when the target is flush
782
782
  # against a wall — AutoSnap puts the dragged cabinet behind the
783
783
  # wall, Pass 1 within clamps it back into the room, and Pass 2
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-10-19T08:23:55.313Z",
2
+ "generatedAt": "2026-10-19T12:52:03.179Z",
3
3
  "categories": [
4
4
  {
5
5
  "name": "Phoenix",
@@ -547,7 +547,7 @@ export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout
547
547
  - `LayoutSlots.DesktopSidebar` is the built-in desktop sidebar as one piece: the spec's tabs, back button, property pages and sidebar footer with their spacing, scrolling and empty states, and the assistant panel. Use it when the spec's property pages are what the customer should see and only their place changes, for example a sidebar on the left; build the controls yourself when they have to look like the brand's own. Without `width` it fills its container, so the layout positions and sizes that container; `miniSidebar` does not shrink it, so a layout that honours it reads `LayoutSlots.useSidebarContent().hasMiniSidebar` and lets the container take the sidebar's height. Its tabs sit outside it on the left; `side="start"` puts them on its right, for a sidebar on the left. In fullscreen it stays in place, transparent and inert, so a layout that wants the space back removes it while `phx.frontend.useIsFullscreenActive()` is set. See [Sidebar in a Custom Layout](?path=/docs/layouts-sidebar-in-a-custom-layout--docs).
548
548
  - Nothing of the built-in layouts is rendered for it. A project layout finalizes over the spec's `finalizeAction` components, see the finalize paragraph of [Hooks for a Project Layout](#hooks-for-a-project-layout). The `finalizePage` and `finalizeButton` components are legacy: they cannot be declared in YAML, only in TypeScript, and `Legacy.CommonFinalizePage`, which is deprecated, shows a `finalizePage` for projects that still have one. `LayoutDialog` renders only what the project registers with `createLayoutDialog` and is not part of the finalize flow. The preview start screen is `DesktopPreview` or `MobilePreview`, which the layout shows while `phx.frontend.usePreview().isPreview` is set. Both previews frame the scene themselves, so the layout renders the component that calls `phx.frontend.useSceneSafeArea()` only while `isPreview` is not set; it then measures when it mounts after the preview. The assistant panel is available to a project layout only inside `LayoutSlots.DesktopSidebar`.
549
549
  - The layout reads the state it has to react to from hooks, listed with what each returns in [Hooks for a Project Layout](#hooks-for-a-project-layout).
550
- - Messages for the user come one of two ways. `LayoutSlots.Services` shows violations of a rejected change, side-effect hints, errors and failed saves as the built-in snackbars, which render into `LayoutSlots.DesktopSnackbarsRoot` or `LayoutSlots.MobileSnackbarsRoot` wherever the layout mounts it. `phx.frontend.useConfiguratorMessages(onMessage)` hands the same messages to the layout's own UI instead, with their text resolved, as the toast in [Custom Layout](?path=/docs/layouts-custom-layout--docs#show-messages) does; mount one of the two, not both, or every message is shown twice. A failure to save the configuration, and the first successful save after it, are messages too, so a layout that mounts neither shows no sign of a failed save. An error of the built-in finalize and other actions stays a snackbar either way. It renders into the snackbar root, so a layout that mounts none shows it outside the configurator, in the page's `body`. A failure to start a configuration from a preset is not a message of the hook either: it happens on the preset screen, before any `ConfiguratorLayout` mounts. In production with more than one preset it is a snackbar there, also on a preset screen replaced with `createPresetUi` (see [Preset UI](#preset-ui)), which reads the error from `phx.frontend.usePresetSelection().selectionError` and mounts `PresetSnackbarsRoot` to keep the snackbar inside the configurator. With a single preset it is the [Configurator Error Page](#configurator-error-page). A finalize action the layout runs with `phx.frontend.useFinalizeActions` or `phx.frontend.useFinalizeAction` reports its error as the action's `error` instead, neither as a message nor as a snackbar.
550
+ - Messages for the user come one of two ways. `LayoutSlots.Services` shows violations of a rejected change, side-effect hints, errors and failed saves as the built-in snackbars, which render into `LayoutSlots.DesktopSnackbarsRoot` or `LayoutSlots.MobileSnackbarsRoot` wherever the layout mounts it; the theme styles them, see [Layout Slots → Styling the snackbars](?path=/docs/phoenix-layout-slots--docs#styling-the-snackbars). `phx.frontend.useConfiguratorMessages(onMessage)` hands the same messages to the layout's own UI instead, with their text resolved, as the toast in [Custom Layout](?path=/docs/layouts-custom-layout--docs#show-messages) does; mount one of the two, not both, or every message is shown twice. A failure to save the configuration, and the first successful save after it, are messages too, so a layout that mounts neither shows no sign of a failed save. An error of the built-in finalize and other actions stays a snackbar either way. It renders into the snackbar root, so a layout that mounts none shows it outside the configurator, in the page's `body`. A failure to start a configuration from a preset is not a message of the hook either: it happens on the preset screen, before any `ConfiguratorLayout` mounts. In production with more than one preset it is a snackbar there, also on a preset screen replaced with `createPresetUi` (see [Preset UI](#preset-ui)), which reads the error from `phx.frontend.usePresetSelection().selectionError` and mounts `PresetSnackbarsRoot` to keep the snackbar inside the configurator. With a single preset it is the [Configurator Error Page](#configurator-error-page). A finalize action the layout runs with `phx.frontend.useFinalizeActions` or `phx.frontend.useFinalizeAction` reports its error as the action's `error` instead, neither as a message nor as a snackbar.
551
551
  - Any project layout element named `ConfiguratorLayout` takes over the page.
552
552
 
553
553
  `defaultConfiguratorElements`, exported from `@salsita-ai/sdk/configurator`, holds the built-in UI as a `ConfiguratorLayout` registration that renders the layout the spec selects, the built-in not-found page as a `ConfigurationNotFoundPage` registration, the built-in not-authenticated page as a `NotAuthenticatedPage` registration, the built-in preset screen as a `PresetUi` registration, the built-in error page as a `ConfiguratorErrorPage` registration, the app loader's built-in content as an `AppLoaderContent` registration, and the built-in in-scene controls under the names of [In-Scene Controls](#in-scene-controls). Generated code registers these defaults with `withDefaultElements`, apart from the project's elements, so the built-in UI is a registration like any other; a project element registered under the same name wins over a default. The list also holds the configurator's built-in controls and layout elements under the kinds the spec names them by, such as `attributeSelect` or `undoToolbarButton`, so a project element registered under one of those names replaces the built-in one wherever the spec names that kind. A config assembled by hand, without generated code, calls `withDefaultElements(defaultConfiguratorElements)` too; the lists are the only way the built-in elements are registered, so without it the page shows a "not found" box instead of the configurator, and a project layout shows one in place of every built-in control. The admin mounts a full configurator, so its list, `defaultAdminElements` from `@salsita-ai/sdk/admin`, holds the configurator's defaults followed by the admin's built-in pages, sidebars and actions; generated admin code passes it to `withDefaultElements` in place of `defaultConfiguratorElements`, because each call replaces the defaults passed before.