@wildo-ai/saas-frontend-lib 1.1.5 → 1.1.6

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 (777) hide show
  1. package/dist/esm/components/actions/action-bar.d.ts +15 -0
  2. package/dist/esm/components/actions/action-bar.d.ts.map +1 -1
  3. package/dist/esm/components/actions/action-bar.js +15 -0
  4. package/dist/esm/components/actions/action-bar.js.map +1 -1
  5. package/dist/esm/components/ai-elements/decision/approval.d.ts +97 -7
  6. package/dist/esm/components/ai-elements/decision/approval.d.ts.map +1 -1
  7. package/dist/esm/components/ai-elements/decision/approval.js.map +1 -1
  8. package/dist/esm/components/app/AppLayout_AuthenticatedRoute.d.ts.map +1 -1
  9. package/dist/esm/components/app/AppLayout_AuthenticatedRoute.js +8 -3
  10. package/dist/esm/components/app/AppLayout_AuthenticatedRoute.js.map +1 -1
  11. package/dist/esm/components/auth/Auth_EnrollmentRequired.d.ts.map +1 -1
  12. package/dist/esm/components/auth/Auth_EnrollmentRequired.js +5 -1
  13. package/dist/esm/components/auth/Auth_EnrollmentRequired.js.map +1 -1
  14. package/dist/esm/components/auth/Auth_Main.d.ts.map +1 -1
  15. package/dist/esm/components/auth/Auth_Main.js +1 -4
  16. package/dist/esm/components/auth/Auth_Main.js.map +1 -1
  17. package/dist/esm/components/auth/Auth_Register.d.ts.map +1 -1
  18. package/dist/esm/components/auth/Auth_Register.js +1 -3
  19. package/dist/esm/components/auth/Auth_Register.js.map +1 -1
  20. package/dist/esm/components/auth/StepUpAuthDialog.d.ts +7 -0
  21. package/dist/esm/components/auth/StepUpAuthDialog.d.ts.map +1 -1
  22. package/dist/esm/components/auth/StepUpAuthDialog.js +13 -7
  23. package/dist/esm/components/auth/StepUpAuthDialog.js.map +1 -1
  24. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.d.ts.map +1 -1
  25. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.js +32 -33
  26. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.js.map +1 -1
  27. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.labels.d.ts.map +1 -1
  28. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.labels.js +18 -20
  29. package/dist/esm/components/auth/admin-config/AppPage_SecuritySettings.labels.js.map +1 -1
  30. package/dist/esm/components/auth/methods/ExternalOAuth2AuthMethod.d.ts.map +1 -1
  31. package/dist/esm/components/auth/methods/ExternalOAuth2AuthMethod.js +2 -3
  32. package/dist/esm/components/auth/methods/ExternalOAuth2AuthMethod.js.map +1 -1
  33. package/dist/esm/components/auth/utils/oauth-provider-display-label.frontend.utils.d.ts +13 -16
  34. package/dist/esm/components/auth/utils/oauth-provider-display-label.frontend.utils.d.ts.map +1 -1
  35. package/dist/esm/components/auth/utils/oauth-provider-display-label.frontend.utils.js +18 -15
  36. package/dist/esm/components/auth/utils/oauth-provider-display-label.frontend.utils.js.map +1 -1
  37. package/dist/esm/components/billing/billing-invoice-history.js +2 -2
  38. package/dist/esm/components/billing/billing-invoice-history.js.map +1 -1
  39. package/dist/esm/components/billing/billing-portal-link.js +2 -2
  40. package/dist/esm/components/billing/billing-portal-link.js.map +1 -1
  41. package/dist/esm/components/billing/billing-pricing-table.d.ts +33 -1
  42. package/dist/esm/components/billing/billing-pricing-table.d.ts.map +1 -1
  43. package/dist/esm/components/billing/billing-pricing-table.js +34 -5
  44. package/dist/esm/components/billing/billing-pricing-table.js.map +1 -1
  45. package/dist/esm/components/billing/billing-subscription-status.js +2 -2
  46. package/dist/esm/components/billing/billing-subscription-status.js.map +1 -1
  47. package/dist/esm/components/billing/billing-usage-dashboard.d.ts +2 -0
  48. package/dist/esm/components/billing/billing-usage-dashboard.d.ts.map +1 -1
  49. package/dist/esm/components/billing/billing-usage-dashboard.js +1 -0
  50. package/dist/esm/components/billing/billing-usage-dashboard.js.map +1 -1
  51. package/dist/esm/components/data-display/DisplayField.d.ts.map +1 -1
  52. package/dist/esm/components/data-display/DisplayField.js +15 -1
  53. package/dist/esm/components/data-display/DisplayField.js.map +1 -1
  54. package/dist/esm/components/data-display/DisplayFieldArray.d.ts.map +1 -1
  55. package/dist/esm/components/data-display/DisplayFieldArray.js +11 -0
  56. package/dist/esm/components/data-display/DisplayFieldArray.js.map +1 -1
  57. package/dist/esm/components/data-display/DisplayFieldEditable.d.ts.map +1 -1
  58. package/dist/esm/components/data-display/DisplayFieldEditable.js +2 -2
  59. package/dist/esm/components/data-display/DisplayFieldEditable.js.map +1 -1
  60. package/dist/esm/components/data-display/DisplayFieldEditableArray.d.ts +12 -2
  61. package/dist/esm/components/data-display/DisplayFieldEditableArray.d.ts.map +1 -1
  62. package/dist/esm/components/data-display/DisplayFieldEditableArray.js +3 -2
  63. package/dist/esm/components/data-display/DisplayFieldEditableArray.js.map +1 -1
  64. package/dist/esm/components/data-display/DisplayFieldReadOnly.d.ts.map +1 -1
  65. package/dist/esm/components/data-display/DisplayFieldReadOnly.js +2 -2
  66. package/dist/esm/components/data-display/DisplayFieldReadOnly.js.map +1 -1
  67. package/dist/esm/components/data-display/DisplayFieldReadOnlyArraySection.d.ts.map +1 -1
  68. package/dist/esm/components/data-display/DisplayFieldReadOnlyArraySection.js +8 -2
  69. package/dist/esm/components/data-display/DisplayFieldReadOnlyArraySection.js.map +1 -1
  70. package/dist/esm/components/data-display/DisplayValueDispatcher.d.ts.map +1 -1
  71. package/dist/esm/components/data-display/DisplayValueDispatcher.js +18 -4
  72. package/dist/esm/components/data-display/DisplayValueDispatcher.js.map +1 -1
  73. package/dist/esm/components/data-display/ResourceAutomaticDisplayer.d.ts.map +1 -1
  74. package/dist/esm/components/data-display/ResourceAutomaticDisplayer.js +61 -3
  75. package/dist/esm/components/data-display/ResourceAutomaticDisplayer.js.map +1 -1
  76. package/dist/esm/components/data-display/ResourceSummaryDisplayer.d.ts +7 -5
  77. package/dist/esm/components/data-display/ResourceSummaryDisplayer.d.ts.map +1 -1
  78. package/dist/esm/components/data-display/ResourceSummaryDisplayer.js.map +1 -1
  79. package/dist/esm/components/data-display/chromes/DisplayFieldChrome.d.ts +11 -1
  80. package/dist/esm/components/data-display/chromes/DisplayFieldChrome.d.ts.map +1 -1
  81. package/dist/esm/components/data-display/chromes/DisplayFieldChrome.js +36 -11
  82. package/dist/esm/components/data-display/chromes/DisplayFieldChrome.js.map +1 -1
  83. package/dist/esm/components/data-display/display-field-resolved-props.d.ts +6 -0
  84. package/dist/esm/components/data-display/display-field-resolved-props.d.ts.map +1 -1
  85. package/dist/esm/components/data-display/display-field-resolved-props.js.map +1 -1
  86. package/dist/esm/components/data-display/external-data-provenance/DisplayFieldProvenanceNote.d.ts +23 -0
  87. package/dist/esm/components/data-display/external-data-provenance/DisplayFieldProvenanceNote.d.ts.map +1 -0
  88. package/dist/esm/components/data-display/external-data-provenance/DisplayFieldProvenanceNote.js +35 -0
  89. package/dist/esm/components/data-display/external-data-provenance/DisplayFieldProvenanceNote.js.map +1 -0
  90. package/dist/esm/components/data-display/external-data-provenance/external-data-provenance.frontend.d.ts +47 -0
  91. package/dist/esm/components/data-display/external-data-provenance/external-data-provenance.frontend.d.ts.map +1 -0
  92. package/dist/esm/components/data-display/external-data-provenance/external-data-provenance.frontend.js +124 -0
  93. package/dist/esm/components/data-display/external-data-provenance/external-data-provenance.frontend.js.map +1 -0
  94. package/dist/esm/components/data-display/external-data-provenance/useExternalDataFieldProvenance.d.ts +8 -0
  95. package/dist/esm/components/data-display/external-data-provenance/useExternalDataFieldProvenance.d.ts.map +1 -0
  96. package/dist/esm/components/data-display/external-data-provenance/useExternalDataFieldProvenance.js +46 -0
  97. package/dist/esm/components/data-display/external-data-provenance/useExternalDataFieldProvenance.js.map +1 -0
  98. package/dist/esm/components/feedback/resource-empty-state.d.ts +21 -8
  99. package/dist/esm/components/feedback/resource-empty-state.d.ts.map +1 -1
  100. package/dist/esm/components/feedback/resource-empty-state.js +56 -26
  101. package/dist/esm/components/feedback/resource-empty-state.js.map +1 -1
  102. package/dist/esm/components/flows-actors/approval.d.ts +29 -7
  103. package/dist/esm/components/flows-actors/approval.d.ts.map +1 -1
  104. package/dist/esm/components/flows-actors/approval.js +231 -101
  105. package/dist/esm/components/flows-actors/approval.js.map +1 -1
  106. package/dist/esm/components/flows-actors/approval.labels.d.ts.map +1 -1
  107. package/dist/esm/components/flows-actors/approval.labels.js +57 -0
  108. package/dist/esm/components/flows-actors/approval.labels.js.map +1 -1
  109. package/dist/esm/components/flows-actors/system-catalog.d.ts.map +1 -1
  110. package/dist/esm/components/flows-actors/system-catalog.js +4 -4
  111. package/dist/esm/components/flows-actors/system-catalog.js.map +1 -1
  112. package/dist/esm/components/flows-actors/system-catalog.labels.d.ts.map +1 -1
  113. package/dist/esm/components/flows-actors/system-catalog.labels.js +0 -5
  114. package/dist/esm/components/flows-actors/system-catalog.labels.js.map +1 -1
  115. package/dist/esm/components/form/Form.d.ts +2 -2
  116. package/dist/esm/components/form/Form.js +2 -2
  117. package/dist/esm/components/form/Form.js.map +1 -1
  118. package/dist/esm/components/form/automated/AutomatedArrayField.d.ts +28 -3
  119. package/dist/esm/components/form/automated/AutomatedArrayField.d.ts.map +1 -1
  120. package/dist/esm/components/form/automated/AutomatedArrayField.js +43 -14
  121. package/dist/esm/components/form/automated/AutomatedArrayField.js.map +1 -1
  122. package/dist/esm/components/form/automated/FormField.d.ts +3 -0
  123. package/dist/esm/components/form/automated/FormField.d.ts.map +1 -1
  124. package/dist/esm/components/form/automated/FormField.js +60 -21
  125. package/dist/esm/components/form/automated/FormField.js.map +1 -1
  126. package/dist/esm/components/form/automated/FormFieldArray.d.ts +6 -3
  127. package/dist/esm/components/form/automated/FormFieldArray.d.ts.map +1 -1
  128. package/dist/esm/components/form/automated/FormFieldArray.js +3 -2
  129. package/dist/esm/components/form/automated/FormFieldArray.js.map +1 -1
  130. package/dist/esm/components/form/automated/ResourceAutomatedForm.d.ts +5 -4
  131. package/dist/esm/components/form/automated/ResourceAutomatedForm.d.ts.map +1 -1
  132. package/dist/esm/components/form/automated/ResourceAutomatedForm.js +148 -55
  133. package/dist/esm/components/form/automated/ResourceAutomatedForm.js.map +1 -1
  134. package/dist/esm/components/form/automated/ResourceFormActionsContext.d.ts +30 -0
  135. package/dist/esm/components/form/automated/ResourceFormActionsContext.d.ts.map +1 -1
  136. package/dist/esm/components/form/automated/ResourceFormActionsContext.js +30 -1
  137. package/dist/esm/components/form/automated/ResourceFormActionsContext.js.map +1 -1
  138. package/dist/esm/components/form/automated/TemplatePlacedFieldsContext.d.ts +79 -0
  139. package/dist/esm/components/form/automated/TemplatePlacedFieldsContext.d.ts.map +1 -0
  140. package/dist/esm/components/form/automated/TemplatePlacedFieldsContext.js +203 -0
  141. package/dist/esm/components/form/automated/TemplatePlacedFieldsContext.js.map +1 -0
  142. package/dist/esm/components/form/automated/automated-form-submit.utils.d.ts +12 -0
  143. package/dist/esm/components/form/automated/automated-form-submit.utils.d.ts.map +1 -1
  144. package/dist/esm/components/form/automated/automated-form-submit.utils.js +11 -0
  145. package/dist/esm/components/form/automated/automated-form-submit.utils.js.map +1 -1
  146. package/dist/esm/components/form/chromes/FormFieldChrome.d.ts.map +1 -1
  147. package/dist/esm/components/form/chromes/FormFieldChrome.js +2 -2
  148. package/dist/esm/components/form/chromes/FormFieldChrome.js.map +1 -1
  149. package/dist/esm/components/form/combobox.d.ts +7 -0
  150. package/dist/esm/components/form/combobox.d.ts.map +1 -1
  151. package/dist/esm/components/form/combobox.js.map +1 -1
  152. package/dist/esm/components/form/controls/form-field-checkbox-group.d.ts.map +1 -1
  153. package/dist/esm/components/form/controls/form-field-checkbox-group.js +13 -0
  154. package/dist/esm/components/form/controls/form-field-checkbox-group.js.map +1 -1
  155. package/dist/esm/components/form/fields/form-field-address.d.ts +58 -0
  156. package/dist/esm/components/form/fields/form-field-address.d.ts.map +1 -1
  157. package/dist/esm/components/form/fields/form-field-address.js +34 -6
  158. package/dist/esm/components/form/fields/form-field-address.js.map +1 -1
  159. package/dist/esm/components/form/fields/form-field-address.labels.d.ts.map +1 -1
  160. package/dist/esm/components/form/fields/form-field-address.labels.js +60 -1
  161. package/dist/esm/components/form/fields/form-field-address.labels.js.map +1 -1
  162. package/dist/esm/components/form/fields/form-field-file.d.ts +0 -12
  163. package/dist/esm/components/form/fields/form-field-file.d.ts.map +1 -1
  164. package/dist/esm/components/form/fields/form-field-file.js +34 -13
  165. package/dist/esm/components/form/fields/form-field-file.js.map +1 -1
  166. package/dist/esm/components/form/fields/form-field-file.labels.d.ts.map +1 -1
  167. package/dist/esm/components/form/fields/form-field-file.labels.js +46 -0
  168. package/dist/esm/components/form/fields/form-field-file.labels.js.map +1 -1
  169. package/dist/esm/components/form/fields/form-field-string-organization-role.d.ts +73 -0
  170. package/dist/esm/components/form/fields/form-field-string-organization-role.d.ts.map +1 -0
  171. package/dist/esm/components/form/fields/form-field-string-organization-role.js +64 -0
  172. package/dist/esm/components/form/fields/form-field-string-organization-role.js.map +1 -0
  173. package/dist/esm/components/form/fields/form-field-string.d.ts.map +1 -1
  174. package/dist/esm/components/form/fields/form-field-string.js +8 -1
  175. package/dist/esm/components/form/fields/form-field-string.js.map +1 -1
  176. package/dist/esm/components/form/fields/form-field-string.labels.d.ts.map +1 -1
  177. package/dist/esm/components/form/fields/form-field-string.labels.js +4 -0
  178. package/dist/esm/components/form/fields/form-field-string.labels.js.map +1 -1
  179. package/dist/esm/components/form/validation-errors/FormErrorSummary.js +1 -1
  180. package/dist/esm/components/form/validation-errors/FormErrorSummary.js.map +1 -1
  181. package/dist/esm/components/form/validation-errors/resolver-error-nesting.d.ts +31 -0
  182. package/dist/esm/components/form/validation-errors/resolver-error-nesting.d.ts.map +1 -0
  183. package/dist/esm/components/form/validation-errors/resolver-error-nesting.js +81 -0
  184. package/dist/esm/components/form/validation-errors/resolver-error-nesting.js.map +1 -0
  185. package/dist/esm/components/form/validation-errors/resource-error-notification-context.utils.d.ts +14 -1
  186. package/dist/esm/components/form/validation-errors/resource-error-notification-context.utils.d.ts.map +1 -1
  187. package/dist/esm/components/form/validation-errors/resource-error-notification-context.utils.js +14 -0
  188. package/dist/esm/components/form/validation-errors/resource-error-notification-context.utils.js.map +1 -1
  189. package/dist/esm/components/form/validation-errors/zod-issue-resolver.d.ts +22 -0
  190. package/dist/esm/components/form/validation-errors/zod-issue-resolver.d.ts.map +1 -1
  191. package/dist/esm/components/form/validation-errors/zod-issue-resolver.js +1 -22
  192. package/dist/esm/components/form/validation-errors/zod-issue-resolver.js.map +1 -1
  193. package/dist/esm/components/layout/resizable.d.ts +11 -0
  194. package/dist/esm/components/layout/resizable.d.ts.map +1 -1
  195. package/dist/esm/components/layout/resizable.js.map +1 -1
  196. package/dist/esm/components/navigation/app-level/ApplicationLevel_NavigationBack.d.ts +11 -1
  197. package/dist/esm/components/navigation/app-level/ApplicationLevel_NavigationBack.d.ts.map +1 -1
  198. package/dist/esm/components/navigation/app-level/ApplicationLevel_NavigationBack.js +15 -3
  199. package/dist/esm/components/navigation/app-level/ApplicationLevel_NavigationBack.js.map +1 -1
  200. package/dist/esm/components/navigation/app-level/ApplicationLevel_StatusBar.d.ts +2 -2
  201. package/dist/esm/components/navigation/app-level/ApplicationLevel_StatusBar.d.ts.map +1 -1
  202. package/dist/esm/components/navigation/app-level/ApplicationLevel_StatusBar.js.map +1 -1
  203. package/dist/esm/components/navigation/app-level/HostedComponentInteractionsProvider.d.ts +2 -2
  204. package/dist/esm/components/navigation/app-level/HostedComponentInteractionsProvider.js +2 -2
  205. package/dist/esm/components/navigation/app-level/HostedComponentInteractionsProvider.js.map +1 -1
  206. package/dist/esm/components/navigation/app-level/SidebarResourceBrowser.js +18 -20
  207. package/dist/esm/components/navigation/app-level/SidebarResourceBrowser.js.map +1 -1
  208. package/dist/esm/components/navigation/app-level/useCommandMenuBehavior.d.ts.map +1 -1
  209. package/dist/esm/components/navigation/app-level/useCommandMenuBehavior.js +7 -1
  210. package/dist/esm/components/navigation/app-level/useCommandMenuBehavior.js.map +1 -1
  211. package/dist/esm/components/navigation/app-level/useMenuBarBehavior.d.ts.map +1 -1
  212. package/dist/esm/components/navigation/app-level/useMenuBarBehavior.js +4 -1
  213. package/dist/esm/components/navigation/app-level/useMenuBarBehavior.js.map +1 -1
  214. package/dist/esm/components/navigation/app-level/useMenuUserOrgBehavior.d.ts.map +1 -1
  215. package/dist/esm/components/navigation/app-level/useMenuUserOrgBehavior.js +18 -2
  216. package/dist/esm/components/navigation/app-level/useMenuUserOrgBehavior.js.map +1 -1
  217. package/dist/esm/components/navigation/app-level/useSidebarBehavior.d.ts.map +1 -1
  218. package/dist/esm/components/navigation/app-level/useSidebarBehavior.js +82 -10
  219. package/dist/esm/components/navigation/app-level/useSidebarBehavior.js.map +1 -1
  220. package/dist/esm/components/navigation/app-level/useStatusBarBehavior.d.ts +2 -2
  221. package/dist/esm/components/navigation/app-level/useStatusBarBehavior.d.ts.map +1 -1
  222. package/dist/esm/components/navigation/app-level/useStatusBarBehavior.js.map +1 -1
  223. package/dist/esm/components/resources/ResourceCollectionQuickFilterTabs.d.ts.map +1 -1
  224. package/dist/esm/components/resources/ResourceCollectionQuickFilterTabs.js +8 -1
  225. package/dist/esm/components/resources/ResourceCollectionQuickFilterTabs.js.map +1 -1
  226. package/dist/esm/components/resources/ResourceCollectionToolbar.d.ts +8 -2
  227. package/dist/esm/components/resources/ResourceCollectionToolbar.d.ts.map +1 -1
  228. package/dist/esm/components/resources/ResourceCollectionToolbar.js +6 -2
  229. package/dist/esm/components/resources/ResourceCollectionToolbar.js.map +1 -1
  230. package/dist/esm/components/resources/ResourceLayout_Breadcrumb.d.ts.map +1 -1
  231. package/dist/esm/components/resources/ResourceLayout_Breadcrumb.js +31 -16
  232. package/dist/esm/components/resources/ResourceLayout_Breadcrumb.js.map +1 -1
  233. package/dist/esm/components/resources/ResourceLayout_ContainerDialogs.d.ts.map +1 -1
  234. package/dist/esm/components/resources/ResourceLayout_ContainerDialogs.js +23 -8
  235. package/dist/esm/components/resources/ResourceLayout_ContainerDialogs.js.map +1 -1
  236. package/dist/esm/components/resources/ResourceLayout_ContainerNested.js +2 -2
  237. package/dist/esm/components/resources/ResourceLayout_ContainerNested.js.map +1 -1
  238. package/dist/esm/components/resources/ResourceLayout_Header.d.ts +13 -0
  239. package/dist/esm/components/resources/ResourceLayout_Header.d.ts.map +1 -1
  240. package/dist/esm/components/resources/ResourceLayout_Header.js +55 -28
  241. package/dist/esm/components/resources/ResourceLayout_Header.js.map +1 -1
  242. package/dist/esm/components/resources/ResourceLayout_List.d.ts.map +1 -1
  243. package/dist/esm/components/resources/ResourceLayout_List.js +41 -20
  244. package/dist/esm/components/resources/ResourceLayout_List.js.map +1 -1
  245. package/dist/esm/components/resources/ResourceLayout_List.labels.d.ts.map +1 -1
  246. package/dist/esm/components/resources/ResourceLayout_List.labels.js +1 -2
  247. package/dist/esm/components/resources/ResourceLayout_List.labels.js.map +1 -1
  248. package/dist/esm/components/resources/ResourceLayout_Read.d.ts +9 -4
  249. package/dist/esm/components/resources/ResourceLayout_Read.d.ts.map +1 -1
  250. package/dist/esm/components/resources/ResourceLayout_Read.js +30 -11
  251. package/dist/esm/components/resources/ResourceLayout_Read.js.map +1 -1
  252. package/dist/esm/components/resources/ResourceLayout_ReadSummary.d.ts.map +1 -1
  253. package/dist/esm/components/resources/ResourceLayout_ReadSummary.js +4 -2
  254. package/dist/esm/components/resources/ResourceLayout_ReadSummary.js.map +1 -1
  255. package/dist/esm/components/resources/ResourceLayout_ReadSummary_TableRow.d.ts.map +1 -1
  256. package/dist/esm/components/resources/ResourceLayout_ReadSummary_TableRow.js +6 -2
  257. package/dist/esm/components/resources/ResourceLayout_ReadSummary_TableRow.js.map +1 -1
  258. package/dist/esm/components/resources/ResourceLayout_Search.d.ts.map +1 -1
  259. package/dist/esm/components/resources/ResourceLayout_Search.js +30 -14
  260. package/dist/esm/components/resources/ResourceLayout_Search.js.map +1 -1
  261. package/dist/esm/components/resources/ResourceLayout_SemanticOperationFallback.d.ts.map +1 -1
  262. package/dist/esm/components/resources/ResourceLayout_SemanticOperationFallback.js +14 -198
  263. package/dist/esm/components/resources/ResourceLayout_SemanticOperationFallback.js.map +1 -1
  264. package/dist/esm/components/resources/ResourceLayout_Update.d.ts +2 -2
  265. package/dist/esm/components/resources/ResourceLayout_Update.js +2 -2
  266. package/dist/esm/components/resources/ResourceLayout_Update.js.map +1 -1
  267. package/dist/esm/components/resources/ResourceListItemRenderer.d.ts.map +1 -1
  268. package/dist/esm/components/resources/ResourceListItemRenderer.js +69 -39
  269. package/dist/esm/components/resources/ResourceListItemRenderer.js.map +1 -1
  270. package/dist/esm/components/resources/ResourceOperationActionDropdown.d.ts +32 -0
  271. package/dist/esm/components/resources/ResourceOperationActionDropdown.d.ts.map +1 -0
  272. package/dist/esm/components/resources/ResourceOperationActionDropdown.js +130 -0
  273. package/dist/esm/components/resources/ResourceOperationActionDropdown.js.map +1 -0
  274. package/dist/esm/components/resources/collection-create-placement.utils.d.ts +32 -0
  275. package/dist/esm/components/resources/collection-create-placement.utils.d.ts.map +1 -0
  276. package/dist/esm/components/resources/collection-create-placement.utils.js +37 -0
  277. package/dist/esm/components/resources/collection-create-placement.utils.js.map +1 -0
  278. package/dist/esm/components/resources/embeds/RelatedResourcePreview.d.ts.map +1 -1
  279. package/dist/esm/components/resources/embeds/RelatedResourcePreview.js +5 -1
  280. package/dist/esm/components/resources/embeds/RelatedResourcePreview.js.map +1 -1
  281. package/dist/esm/components/resources/embeds/RelatedResourceSections.d.ts +8 -1
  282. package/dist/esm/components/resources/embeds/RelatedResourceSections.d.ts.map +1 -1
  283. package/dist/esm/components/resources/embeds/RelatedResourceSections.js +49 -2
  284. package/dist/esm/components/resources/embeds/RelatedResourceSections.js.map +1 -1
  285. package/dist/esm/components/resources/embeds/ResourceEmbeds.d.ts +22 -0
  286. package/dist/esm/components/resources/embeds/ResourceEmbeds.d.ts.map +1 -1
  287. package/dist/esm/components/resources/embeds/ResourceEmbeds.js +85 -2
  288. package/dist/esm/components/resources/embeds/ResourceEmbeds.js.map +1 -1
  289. package/dist/esm/components/resources/resourceLayout.utils.d.ts +14 -0
  290. package/dist/esm/components/resources/resourceLayout.utils.d.ts.map +1 -1
  291. package/dist/esm/components/resources/resourceLayout.utils.js +22 -0
  292. package/dist/esm/components/resources/resourceLayout.utils.js.map +1 -1
  293. package/dist/esm/components/resources/skeleton/ArrayField.d.ts.map +1 -1
  294. package/dist/esm/components/resources/skeleton/ArrayField.js +3 -0
  295. package/dist/esm/components/resources/skeleton/ArrayField.js.map +1 -1
  296. package/dist/esm/components/resources/skeleton/FormLayout.d.ts.map +1 -1
  297. package/dist/esm/components/resources/skeleton/FormLayout.js +33 -1
  298. package/dist/esm/components/resources/skeleton/FormLayout.js.map +1 -1
  299. package/dist/esm/components/resources/skeleton/ObjectScope.d.ts.map +1 -1
  300. package/dist/esm/components/resources/skeleton/ObjectScope.js +3 -0
  301. package/dist/esm/components/resources/skeleton/ObjectScope.js.map +1 -1
  302. package/dist/esm/components/resources/skeleton/Section.d.ts +12 -0
  303. package/dist/esm/components/resources/skeleton/Section.d.ts.map +1 -1
  304. package/dist/esm/components/resources/skeleton/Section.js +28 -2
  305. package/dist/esm/components/resources/skeleton/Section.js.map +1 -1
  306. package/dist/esm/components/resources/skeleton/SectionFieldsContext.d.ts +70 -0
  307. package/dist/esm/components/resources/skeleton/SectionFieldsContext.d.ts.map +1 -1
  308. package/dist/esm/components/resources/skeleton/SectionFieldsContext.js +157 -1
  309. package/dist/esm/components/resources/skeleton/SectionFieldsContext.js.map +1 -1
  310. package/dist/esm/components/resources/skeleton/WizardLayout.d.ts +6 -0
  311. package/dist/esm/components/resources/skeleton/WizardLayout.d.ts.map +1 -1
  312. package/dist/esm/components/resources/skeleton/WizardLayout.js +13 -2
  313. package/dist/esm/components/resources/skeleton/WizardLayout.js.map +1 -1
  314. package/dist/esm/components/resources/skeleton/WizardStep.d.ts.map +1 -1
  315. package/dist/esm/components/resources/skeleton/WizardStep.js +2 -1
  316. package/dist/esm/components/resources/skeleton/WizardStep.js.map +1 -1
  317. package/dist/esm/components/resources-fields/_presets/resource-reference/ResourceFieldDisplayPreset_ResourceReference_Default.d.ts.map +1 -1
  318. package/dist/esm/components/resources-fields/_presets/resource-reference/ResourceFieldDisplayPreset_ResourceReference_Default.js +61 -15
  319. package/dist/esm/components/resources-fields/_presets/resource-reference/ResourceFieldDisplayPreset_ResourceReference_Default.js.map +1 -1
  320. package/dist/esm/components/resources-fields/resource-reference/resource-reference.shared.utils.d.ts +24 -2
  321. package/dist/esm/components/resources-fields/resource-reference/resource-reference.shared.utils.d.ts.map +1 -1
  322. package/dist/esm/components/resources-fields/resource-reference/resource-reference.shared.utils.js +69 -1
  323. package/dist/esm/components/resources-fields/resource-reference/resource-reference.shared.utils.js.map +1 -1
  324. package/dist/esm/components/resources-fields/resource-reference/useResourceSearch.d.ts.map +1 -1
  325. package/dist/esm/components/resources-fields/resource-reference/useResourceSearch.js +18 -19
  326. package/dist/esm/components/resources-fields/resource-reference/useResourceSearch.js.map +1 -1
  327. package/dist/esm/components/sections/ContentSectionContainer.d.ts.map +1 -1
  328. package/dist/esm/components/sections/ContentSectionContainer.js +5 -4
  329. package/dist/esm/components/sections/ContentSectionContainer.js.map +1 -1
  330. package/dist/esm/components/sections/stepper.d.ts +5 -0
  331. package/dist/esm/components/sections/stepper.d.ts.map +1 -1
  332. package/dist/esm/components/sections/stepper.js.map +1 -1
  333. package/dist/esm/components/sections/surface.d.ts.map +1 -1
  334. package/dist/esm/components/sections/surface.js +12 -3
  335. package/dist/esm/components/sections/surface.js.map +1 -1
  336. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.d.ts +43 -0
  337. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.d.ts.map +1 -0
  338. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.js +129 -0
  339. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.js.map +1 -0
  340. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.labels.d.ts +3 -0
  341. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.labels.d.ts.map +1 -0
  342. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.labels.js +34 -0
  343. package/dist/esm/components/settings/AppPage_AgentWorkOverrideRateSettings.labels.js.map +1 -0
  344. package/dist/esm/components/settings/AppPage_AppearanceSettings.d.ts.map +1 -1
  345. package/dist/esm/components/settings/AppPage_AppearanceSettings.js +9 -11
  346. package/dist/esm/components/settings/AppPage_AppearanceSettings.js.map +1 -1
  347. package/dist/esm/components/settings/AppPage_AppearanceSettings.labels.d.ts.map +1 -1
  348. package/dist/esm/components/settings/AppPage_AppearanceSettings.labels.js +3 -2
  349. package/dist/esm/components/settings/AppPage_AppearanceSettings.labels.js.map +1 -1
  350. package/dist/esm/components/settings/AppPage_BillingSettings.d.ts +4 -2
  351. package/dist/esm/components/settings/AppPage_BillingSettings.d.ts.map +1 -1
  352. package/dist/esm/components/settings/AppPage_BillingSettings.js +21 -3
  353. package/dist/esm/components/settings/AppPage_BillingSettings.js.map +1 -1
  354. package/dist/esm/components/settings/AppPage_BillingSettings.labels.d.ts.map +1 -1
  355. package/dist/esm/components/settings/AppPage_BillingSettings.labels.js +5 -10
  356. package/dist/esm/components/settings/AppPage_BillingSettings.labels.js.map +1 -1
  357. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.d.ts +58 -0
  358. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.d.ts.map +1 -1
  359. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.js +243 -40
  360. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.js.map +1 -1
  361. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.d.ts.map +1 -1
  362. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.js +67 -6
  363. package/dist/esm/components/settings/AppPage_ConnectedAccountsSettings.labels.js.map +1 -1
  364. package/dist/esm/components/settings/AppPage_InvitationsSettings.d.ts.map +1 -1
  365. package/dist/esm/components/settings/AppPage_InvitationsSettings.js +19 -11
  366. package/dist/esm/components/settings/AppPage_InvitationsSettings.js.map +1 -1
  367. package/dist/esm/components/settings/AppPage_InvitationsSettings.labels.d.ts.map +1 -1
  368. package/dist/esm/components/settings/AppPage_InvitationsSettings.labels.js +4 -2
  369. package/dist/esm/components/settings/AppPage_InvitationsSettings.labels.js.map +1 -1
  370. package/dist/esm/components/settings/SettingsHub.d.ts.map +1 -1
  371. package/dist/esm/components/settings/SettingsHub.js +3 -0
  372. package/dist/esm/components/settings/SettingsHub.js.map +1 -1
  373. package/dist/esm/components/settings/SettingsResourceOperationPanel.d.ts.map +1 -1
  374. package/dist/esm/components/settings/SettingsResourceOperationPanel.js +16 -1
  375. package/dist/esm/components/settings/SettingsResourceOperationPanel.js.map +1 -1
  376. package/dist/esm/components/settings/useOwnerProviderConnections.d.ts +59 -0
  377. package/dist/esm/components/settings/useOwnerProviderConnections.d.ts.map +1 -0
  378. package/dist/esm/components/settings/useOwnerProviderConnections.js +136 -0
  379. package/dist/esm/components/settings/useOwnerProviderConnections.js.map +1 -0
  380. package/dist/esm/components/views/chart-view/chart-view.utils.d.ts +5 -0
  381. package/dist/esm/components/views/chart-view/chart-view.utils.d.ts.map +1 -1
  382. package/dist/esm/components/views/chart-view/chart-view.utils.js +5 -0
  383. package/dist/esm/components/views/chart-view/chart-view.utils.js.map +1 -1
  384. package/dist/esm/components/views/chart-view/useResourceChartData.d.ts +50 -0
  385. package/dist/esm/components/views/chart-view/useResourceChartData.d.ts.map +1 -0
  386. package/dist/esm/components/views/chart-view/useResourceChartData.js +72 -0
  387. package/dist/esm/components/views/chart-view/useResourceChartData.js.map +1 -0
  388. package/dist/esm/components/views/composite-view/CompositeLayout.d.ts.map +1 -1
  389. package/dist/esm/components/views/composite-view/CompositeLayout.js +2 -1
  390. package/dist/esm/components/views/composite-view/CompositeLayout.js.map +1 -1
  391. package/dist/esm/core/app-shell/AppShellBuildingBlocks.d.ts +86 -0
  392. package/dist/esm/core/app-shell/AppShellBuildingBlocks.d.ts.map +1 -0
  393. package/dist/esm/core/app-shell/AppShellBuildingBlocks.js +187 -0
  394. package/dist/esm/core/app-shell/AppShellBuildingBlocks.js.map +1 -0
  395. package/dist/esm/core/app-shell/PortalContainerContext.d.ts +5 -2
  396. package/dist/esm/core/app-shell/PortalContainerContext.d.ts.map +1 -1
  397. package/dist/esm/core/app-shell/PortalContainerContext.js +5 -2
  398. package/dist/esm/core/app-shell/PortalContainerContext.js.map +1 -1
  399. package/dist/esm/core/app-shell/app-shell.schemas.d.ts +18 -9
  400. package/dist/esm/core/app-shell/app-shell.schemas.d.ts.map +1 -1
  401. package/dist/esm/core/app-shell/app-shell.schemas.js +1 -0
  402. package/dist/esm/core/app-shell/app-shell.schemas.js.map +1 -1
  403. package/dist/esm/core/app-shell/useAppShellLayout.d.ts +10 -0
  404. package/dist/esm/core/app-shell/useAppShellLayout.d.ts.map +1 -1
  405. package/dist/esm/core/app-shell/useAppShellLayout.js +28 -5
  406. package/dist/esm/core/app-shell/useAppShellLayout.js.map +1 -1
  407. package/dist/esm/core/app-shell/usePublicShellLayout.d.ts.map +1 -1
  408. package/dist/esm/core/app-shell/usePublicShellLayout.js +38 -0
  409. package/dist/esm/core/app-shell/usePublicShellLayout.js.map +1 -1
  410. package/dist/esm/core/automated-layout/automated-layout.frontend.utils.d.ts +15 -1
  411. package/dist/esm/core/automated-layout/automated-layout.frontend.utils.d.ts.map +1 -1
  412. package/dist/esm/core/automated-layout/automated-layout.frontend.utils.js +47 -13
  413. package/dist/esm/core/automated-layout/automated-layout.frontend.utils.js.map +1 -1
  414. package/dist/esm/core/billing/BillingContext.d.ts +25 -2
  415. package/dist/esm/core/billing/BillingContext.d.ts.map +1 -1
  416. package/dist/esm/core/billing/BillingContext.js +16 -25
  417. package/dist/esm/core/billing/BillingContext.js.map +1 -1
  418. package/dist/esm/core/billing/billing-provider-display.frontend.utils.d.ts +11 -3
  419. package/dist/esm/core/billing/billing-provider-display.frontend.utils.d.ts.map +1 -1
  420. package/dist/esm/core/billing/billing-provider-display.frontend.utils.js +14 -8
  421. package/dist/esm/core/billing/billing-provider-display.frontend.utils.js.map +1 -1
  422. package/dist/esm/core/billing/useBillingPlanChange.d.ts.map +1 -1
  423. package/dist/esm/core/billing/useBillingPlanChange.js +2 -0
  424. package/dist/esm/core/billing/useBillingPlanChange.js.map +1 -1
  425. package/dist/esm/core/components-registry/assert-registry-completeness.frontend.helper.d.ts.map +1 -1
  426. package/dist/esm/core/components-registry/assert-registry-completeness.frontend.helper.js +1 -0
  427. package/dist/esm/core/components-registry/assert-registry-completeness.frontend.helper.js.map +1 -1
  428. package/dist/esm/core/components-registry/provider-component-registry.frontend.service.d.ts +29 -229
  429. package/dist/esm/core/components-registry/provider-component-registry.frontend.service.d.ts.map +1 -1
  430. package/dist/esm/core/components-registry/provider-component-registry.frontend.service.js +29 -327
  431. package/dist/esm/core/components-registry/provider-component-registry.frontend.service.js.map +1 -1
  432. package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.d.ts +17 -27
  433. package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.d.ts.map +1 -1
  434. package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.js +28 -48
  435. package/dist/esm/core/components-registry/useProviderComponent.frontend.hooks.js.map +1 -1
  436. package/dist/esm/core/config/app-configuration-frontend.schemas.d.ts +21 -11
  437. package/dist/esm/core/config/app-configuration-frontend.schemas.d.ts.map +1 -1
  438. package/dist/esm/core/config/app-configuration-frontend.schemas.js +4 -4
  439. package/dist/esm/core/config/app-configuration-frontend.schemas.js.map +1 -1
  440. package/dist/esm/core/config/app-level-components.frontend.schemas.d.ts +17 -0
  441. package/dist/esm/core/config/app-level-components.frontend.schemas.d.ts.map +1 -1
  442. package/dist/esm/core/config/app-level-components.frontend.schemas.js +17 -0
  443. package/dist/esm/core/config/app-level-components.frontend.schemas.js.map +1 -1
  444. package/dist/esm/core/config/chart-view.frontend.schemas.d.ts +10 -10
  445. package/dist/esm/core/config/engine-settings-destinations.d.ts.map +1 -1
  446. package/dist/esm/core/config/engine-settings-destinations.js +221 -6
  447. package/dist/esm/core/config/engine-settings-destinations.js.map +1 -1
  448. package/dist/esm/core/config/launcher-items.frontend.schemas.d.ts +8 -0
  449. package/dist/esm/core/config/launcher-items.frontend.schemas.d.ts.map +1 -1
  450. package/dist/esm/core/config/launcher-items.frontend.schemas.js +1 -0
  451. package/dist/esm/core/config/launcher-items.frontend.schemas.js.map +1 -1
  452. package/dist/esm/core/config/settings-hub.frontend.schemas.d.ts +10 -1
  453. package/dist/esm/core/config/settings-hub.frontend.schemas.d.ts.map +1 -1
  454. package/dist/esm/core/config/settings-hub.frontend.schemas.js +9 -0
  455. package/dist/esm/core/config/settings-hub.frontend.schemas.js.map +1 -1
  456. package/dist/esm/core/config/verify-launcher-content.d.ts.map +1 -1
  457. package/dist/esm/core/config/verify-launcher-content.js +30 -19
  458. package/dist/esm/core/config/verify-launcher-content.js.map +1 -1
  459. package/dist/esm/core/errors/ErrorContext.d.ts.map +1 -1
  460. package/dist/esm/core/errors/ErrorContext.js +9 -1
  461. package/dist/esm/core/errors/ErrorContext.js.map +1 -1
  462. package/dist/esm/core/errors/GlobalErrorHandler.d.ts.map +1 -1
  463. package/dist/esm/core/errors/GlobalErrorHandler.js +5 -4
  464. package/dist/esm/core/errors/GlobalErrorHandler.js.map +1 -1
  465. package/dist/esm/core/errors/RouterErrorBoundary.js +1 -1
  466. package/dist/esm/core/errors/RouterErrorBoundary.js.map +1 -1
  467. package/dist/esm/core/errors/errors-builder.frontend.services.d.ts +2 -2
  468. package/dist/esm/core/errors/errors-builder.frontend.services.d.ts.map +1 -1
  469. package/dist/esm/core/errors/errors-builder.frontend.services.js +4 -4
  470. package/dist/esm/core/errors/errors-builder.frontend.services.js.map +1 -1
  471. package/dist/esm/core/errors/user-facing-error-message.frontend.utils.js +1 -1
  472. package/dist/esm/core/errors/user-facing-error-message.frontend.utils.js.map +1 -1
  473. package/dist/esm/core/events/NotificationContext.d.ts.map +1 -1
  474. package/dist/esm/core/events/NotificationContext.js +23 -5
  475. package/dist/esm/core/events/NotificationContext.js.map +1 -1
  476. package/dist/esm/core/events/events.frontend.schemas.d.ts +110 -43
  477. package/dist/esm/core/events/events.frontend.schemas.d.ts.map +1 -1
  478. package/dist/esm/core/events/events.frontend.schemas.js +89 -15
  479. package/dist/esm/core/events/events.frontend.schemas.js.map +1 -1
  480. package/dist/esm/core/execution/useExecutionParticipationRMM.d.ts +2 -0
  481. package/dist/esm/core/execution/useExecutionParticipationRMM.d.ts.map +1 -1
  482. package/dist/esm/core/execution/useExecutionParticipationRMM.js +2 -1
  483. package/dist/esm/core/execution/useExecutionParticipationRMM.js.map +1 -1
  484. package/dist/esm/core/execution/useExecutionResourceOperationSurface.d.ts +1 -1
  485. package/dist/esm/core/execution/useExecutionResourceOperationSurface.d.ts.map +1 -1
  486. package/dist/esm/core/execution/useExecutionResourceOperationSurface.js +5 -2
  487. package/dist/esm/core/execution/useExecutionResourceOperationSurface.js.map +1 -1
  488. package/dist/esm/core/external-providers/ConsentBasedProviderSdks.d.ts +63 -0
  489. package/dist/esm/core/external-providers/ConsentBasedProviderSdks.d.ts.map +1 -0
  490. package/dist/esm/core/external-providers/ConsentBasedProviderSdks.js +131 -0
  491. package/dist/esm/core/external-providers/ConsentBasedProviderSdks.js.map +1 -0
  492. package/dist/esm/core/external-providers/ProviderAddressLookupCombobox.d.ts +61 -0
  493. package/dist/esm/core/external-providers/ProviderAddressLookupCombobox.d.ts.map +1 -0
  494. package/dist/esm/core/external-providers/ProviderAddressLookupCombobox.js +178 -0
  495. package/dist/esm/core/external-providers/ProviderAddressLookupCombobox.js.map +1 -0
  496. package/dist/esm/core/external-providers/ProviderAddressLookupHost.d.ts +52 -0
  497. package/dist/esm/core/external-providers/ProviderAddressLookupHost.d.ts.map +1 -0
  498. package/dist/esm/core/external-providers/ProviderAddressLookupHost.js +144 -0
  499. package/dist/esm/core/external-providers/ProviderAddressLookupHost.js.map +1 -0
  500. package/dist/esm/core/external-providers/ProviderFilePickerHost.d.ts +22 -1
  501. package/dist/esm/core/external-providers/ProviderFilePickerHost.d.ts.map +1 -1
  502. package/dist/esm/core/external-providers/ProviderFilePickerHost.js +23 -3
  503. package/dist/esm/core/external-providers/ProviderFilePickerHost.js.map +1 -1
  504. package/dist/esm/core/external-providers/provider-address-lookup-selection.frontend.utils.d.ts +55 -0
  505. package/dist/esm/core/external-providers/provider-address-lookup-selection.frontend.utils.d.ts.map +1 -0
  506. package/dist/esm/core/external-providers/provider-address-lookup-selection.frontend.utils.js +65 -0
  507. package/dist/esm/core/external-providers/provider-address-lookup-selection.frontend.utils.js.map +1 -0
  508. package/dist/esm/core/external-providers/provider-scope-reauthorization-offers.frontend.d.ts +63 -0
  509. package/dist/esm/core/external-providers/provider-scope-reauthorization-offers.frontend.d.ts.map +1 -0
  510. package/dist/esm/core/external-providers/provider-scope-reauthorization-offers.frontend.js +100 -0
  511. package/dist/esm/core/external-providers/provider-scope-reauthorization-offers.frontend.js.map +1 -0
  512. package/dist/esm/core/flows-actors/FlowsActorsContext.d.ts +45 -7
  513. package/dist/esm/core/flows-actors/FlowsActorsContext.d.ts.map +1 -1
  514. package/dist/esm/core/flows-actors/FlowsActorsContext.js +112 -28
  515. package/dist/esm/core/flows-actors/FlowsActorsContext.js.map +1 -1
  516. package/dist/esm/core/flows-actors/usePendingDecisions.d.ts +32 -0
  517. package/dist/esm/core/flows-actors/usePendingDecisions.d.ts.map +1 -0
  518. package/dist/esm/core/flows-actors/usePendingDecisions.js +91 -0
  519. package/dist/esm/core/flows-actors/usePendingDecisions.js.map +1 -0
  520. package/dist/esm/core/guidance/GuidanceRenderer.d.ts.map +1 -1
  521. package/dist/esm/core/guidance/GuidanceRenderer.js +3 -2
  522. package/dist/esm/core/guidance/GuidanceRenderer.js.map +1 -1
  523. package/dist/esm/core/i18n/I18nContext.d.ts +22 -8
  524. package/dist/esm/core/i18n/I18nContext.d.ts.map +1 -1
  525. package/dist/esm/core/i18n/I18nContext.js +21 -9
  526. package/dist/esm/core/i18n/I18nContext.js.map +1 -1
  527. package/dist/esm/core/i18n/component-label-resolution.utils.d.ts +5 -3
  528. package/dist/esm/core/i18n/component-label-resolution.utils.d.ts.map +1 -1
  529. package/dist/esm/core/i18n/component-label-resolution.utils.js +5 -3
  530. package/dist/esm/core/i18n/component-label-resolution.utils.js.map +1 -1
  531. package/dist/esm/core/i18n/useI18n.d.ts +2 -1
  532. package/dist/esm/core/i18n/useI18n.d.ts.map +1 -1
  533. package/dist/esm/core/i18n/useI18n.js +2 -1
  534. package/dist/esm/core/i18n/useI18n.js.map +1 -1
  535. package/dist/esm/core/loading/LoadingContext.d.ts.map +1 -1
  536. package/dist/esm/core/loading/LoadingContext.js +7 -1
  537. package/dist/esm/core/loading/LoadingContext.js.map +1 -1
  538. package/dist/esm/core/loading/LoadingGate.d.ts.map +1 -1
  539. package/dist/esm/core/loading/LoadingGate.js +19 -1
  540. package/dist/esm/core/loading/LoadingGate.js.map +1 -1
  541. package/dist/esm/core/monitoring/analytics/AnalyticsContext.d.ts +15 -2
  542. package/dist/esm/core/monitoring/analytics/AnalyticsContext.d.ts.map +1 -1
  543. package/dist/esm/core/monitoring/analytics/AnalyticsContext.js +183 -20
  544. package/dist/esm/core/monitoring/analytics/AnalyticsContext.js.map +1 -1
  545. package/dist/esm/core/monitoring/analytics/AnalyticsEventBridge.js +2 -2
  546. package/dist/esm/core/monitoring/analytics/AnalyticsEventBridge.js.map +1 -1
  547. package/dist/esm/core/monitoring/analytics/analytics-provider-registry.frontend.service.d.ts +7 -15
  548. package/dist/esm/core/monitoring/analytics/analytics-provider-registry.frontend.service.d.ts.map +1 -1
  549. package/dist/esm/core/monitoring/analytics/analytics-provider-registry.frontend.service.js +8 -26
  550. package/dist/esm/core/monitoring/analytics/analytics-provider-registry.frontend.service.js.map +1 -1
  551. package/dist/esm/core/monitoring/analytics/analytics-provider.frontend.interface.d.ts +12 -3
  552. package/dist/esm/core/monitoring/analytics/analytics-provider.frontend.interface.d.ts.map +1 -1
  553. package/dist/esm/core/monitoring/analytics/analytics-provider.frontend.interface.js +3 -2
  554. package/dist/esm/core/monitoring/analytics/analytics-provider.frontend.interface.js.map +1 -1
  555. package/dist/esm/core/monitoring/analytics/providers/backend-proxy-analytics.provider.d.ts +42 -0
  556. package/dist/esm/core/monitoring/analytics/providers/backend-proxy-analytics.provider.d.ts.map +1 -1
  557. package/dist/esm/core/monitoring/analytics/providers/backend-proxy-analytics.provider.js +89 -5
  558. package/dist/esm/core/monitoring/analytics/providers/backend-proxy-analytics.provider.js.map +1 -1
  559. package/dist/esm/core/monitoring/analytics/providers/console-analytics.provider.d.ts +2 -0
  560. package/dist/esm/core/monitoring/analytics/providers/console-analytics.provider.d.ts.map +1 -1
  561. package/dist/esm/core/monitoring/analytics/providers/console-analytics.provider.js +2 -0
  562. package/dist/esm/core/monitoring/analytics/providers/console-analytics.provider.js.map +1 -1
  563. package/dist/esm/core/navigation/NavigationContentAreas.d.ts +78 -0
  564. package/dist/esm/core/navigation/NavigationContentAreas.d.ts.map +1 -1
  565. package/dist/esm/core/navigation/NavigationContentAreas.js +264 -16
  566. package/dist/esm/core/navigation/NavigationContentAreas.js.map +1 -1
  567. package/dist/esm/core/navigation/NavigationContext.d.ts +8 -0
  568. package/dist/esm/core/navigation/NavigationContext.d.ts.map +1 -1
  569. package/dist/esm/core/navigation/NavigationContext.js +137 -30
  570. package/dist/esm/core/navigation/NavigationContext.js.map +1 -1
  571. package/dist/esm/core/navigation/launcher-resolution.d.ts +2 -0
  572. package/dist/esm/core/navigation/launcher-resolution.d.ts.map +1 -1
  573. package/dist/esm/core/navigation/launcher-resolution.js +1 -0
  574. package/dist/esm/core/navigation/launcher-resolution.js.map +1 -1
  575. package/dist/esm/core/navigation/navigation-cascade.d.ts +46 -0
  576. package/dist/esm/core/navigation/navigation-cascade.d.ts.map +1 -0
  577. package/dist/esm/core/navigation/navigation-cascade.js +222 -0
  578. package/dist/esm/core/navigation/navigation-cascade.js.map +1 -0
  579. package/dist/esm/core/navigation/navigation-clean-break.frontend.utils.d.ts.map +1 -1
  580. package/dist/esm/core/navigation/navigation-clean-break.frontend.utils.js +21 -2
  581. package/dist/esm/core/navigation/navigation-clean-break.frontend.utils.js.map +1 -1
  582. package/dist/esm/core/navigation/navigation-controller-internals.d.ts +71 -0
  583. package/dist/esm/core/navigation/navigation-controller-internals.d.ts.map +1 -0
  584. package/dist/esm/core/navigation/navigation-controller-internals.js +84 -0
  585. package/dist/esm/core/navigation/navigation-controller-internals.js.map +1 -0
  586. package/dist/esm/core/navigation/navigation-policy-resolver.service.d.ts +86 -2
  587. package/dist/esm/core/navigation/navigation-policy-resolver.service.d.ts.map +1 -1
  588. package/dist/esm/core/navigation/navigation-policy-resolver.service.js +242 -124
  589. package/dist/esm/core/navigation/navigation-policy-resolver.service.js.map +1 -1
  590. package/dist/esm/core/navigation/navigation.schemas.d.ts +170 -8
  591. package/dist/esm/core/navigation/navigation.schemas.d.ts.map +1 -1
  592. package/dist/esm/core/navigation/navigation.schemas.js +121 -2
  593. package/dist/esm/core/navigation/navigation.schemas.js.map +1 -1
  594. package/dist/esm/core/navigation/navigation.utils.d.ts +102 -6
  595. package/dist/esm/core/navigation/navigation.utils.d.ts.map +1 -1
  596. package/dist/esm/core/navigation/navigation.utils.js +283 -34
  597. package/dist/esm/core/navigation/navigation.utils.js.map +1 -1
  598. package/dist/esm/core/navigation/useIsStackEntryActive.d.ts +0 -10
  599. package/dist/esm/core/navigation/useIsStackEntryActive.d.ts.map +0 -1
  600. package/dist/esm/core/navigation/useIsStackEntryActive.js.map +0 -1
  601. package/dist/esm/core/navigation/useNavigationController.d.ts +28 -157
  602. package/dist/esm/core/navigation/useNavigationController.d.ts.map +1 -1
  603. package/dist/esm/core/navigation/useNavigationController.js +211 -1189
  604. package/dist/esm/core/navigation/useNavigationController.js.map +1 -1
  605. package/dist/esm/core/navigation/useNavigationRouterSync.d.ts +174 -0
  606. package/dist/esm/core/navigation/useNavigationRouterSync.d.ts.map +1 -0
  607. package/dist/esm/core/navigation/useNavigationRouterSync.js +977 -0
  608. package/dist/esm/core/navigation/useNavigationRouterSync.js.map +1 -0
  609. package/dist/esm/core/navigation/useOverlayTitle.d.ts +13 -1
  610. package/dist/esm/core/navigation/useOverlayTitle.d.ts.map +1 -1
  611. package/dist/esm/core/navigation/useOverlayTitle.js +15 -10
  612. package/dist/esm/core/navigation/useOverlayTitle.js.map +1 -1
  613. package/dist/esm/core/navigation/useResponsiveZoneMigration.d.ts +43 -0
  614. package/dist/esm/core/navigation/useResponsiveZoneMigration.d.ts.map +1 -0
  615. package/dist/esm/core/navigation/useResponsiveZoneMigration.js +44 -0
  616. package/dist/esm/core/navigation/useResponsiveZoneMigration.js.map +1 -0
  617. package/dist/esm/core/navigation/zone-collapse-migration.d.ts +83 -0
  618. package/dist/esm/core/navigation/zone-collapse-migration.d.ts.map +1 -0
  619. package/dist/esm/core/navigation/zone-collapse-migration.js +116 -0
  620. package/dist/esm/core/navigation/zone-collapse-migration.js.map +1 -0
  621. package/dist/esm/core/navigation/zone-collapse.d.ts +51 -0
  622. package/dist/esm/core/navigation/zone-collapse.d.ts.map +1 -0
  623. package/dist/esm/core/navigation/zone-collapse.js +59 -0
  624. package/dist/esm/core/navigation/zone-collapse.js.map +1 -0
  625. package/dist/esm/core/navigation/zone-emphasis.d.ts +3 -0
  626. package/dist/esm/core/navigation/zone-emphasis.d.ts.map +1 -1
  627. package/dist/esm/core/navigation/zone-emphasis.js +26 -4
  628. package/dist/esm/core/navigation/zone-emphasis.js.map +1 -1
  629. package/dist/esm/core/navigation/zone-visible-entry.d.ts +22 -0
  630. package/dist/esm/core/navigation/zone-visible-entry.d.ts.map +1 -1
  631. package/dist/esm/core/navigation/zone-visible-entry.js +25 -0
  632. package/dist/esm/core/navigation/zone-visible-entry.js.map +1 -1
  633. package/dist/esm/core/requests/websockets/WebSocketContext.d.ts.map +1 -1
  634. package/dist/esm/core/requests/websockets/WebSocketContext.js +53 -18
  635. package/dist/esm/core/requests/websockets/WebSocketContext.js.map +1 -1
  636. package/dist/esm/core/requests/websockets/WebSocketEventBridge.d.ts.map +1 -1
  637. package/dist/esm/core/requests/websockets/WebSocketEventBridge.js +3 -1
  638. package/dist/esm/core/requests/websockets/WebSocketEventBridge.js.map +1 -1
  639. package/dist/esm/core/requests/websockets/useNotificationBadges.d.ts +22 -0
  640. package/dist/esm/core/requests/websockets/useNotificationBadges.d.ts.map +1 -1
  641. package/dist/esm/core/requests/websockets/useNotificationBadges.js +72 -3
  642. package/dist/esm/core/requests/websockets/useNotificationBadges.js.map +1 -1
  643. package/dist/esm/core/requests/websockets/usePublishNotificationBadgeCount.d.ts +28 -0
  644. package/dist/esm/core/requests/websockets/usePublishNotificationBadgeCount.d.ts.map +1 -0
  645. package/dist/esm/core/requests/websockets/usePublishNotificationBadgeCount.js +86 -0
  646. package/dist/esm/core/requests/websockets/usePublishNotificationBadgeCount.js.map +1 -0
  647. package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.d.ts +38 -3
  648. package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.d.ts.map +1 -1
  649. package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.js +57 -2
  650. package/dist/esm/core/requests/wildo-http-client-manual-calls.frontend.service.js.map +1 -1
  651. package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.d.ts.map +1 -1
  652. package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.js +4 -2
  653. package/dist/esm/core/requests/wildo-http-client-resources.frontend.service.js.map +1 -1
  654. package/dist/esm/core/requests/wildo-http-client.frontend.service.d.ts +30 -1
  655. package/dist/esm/core/requests/wildo-http-client.frontend.service.d.ts.map +1 -1
  656. package/dist/esm/core/requests/wildo-http-client.frontend.service.js +47 -4
  657. package/dist/esm/core/requests/wildo-http-client.frontend.service.js.map +1 -1
  658. package/dist/esm/core/resources/ResourceRegistryContext.d.ts.map +1 -1
  659. package/dist/esm/core/resources/ResourceRegistryContext.js +22 -1
  660. package/dist/esm/core/resources/ResourceRegistryContext.js.map +1 -1
  661. package/dist/esm/core/resources/context-resource-identifiers.frontend.utils.js +1 -1
  662. package/dist/esm/core/resources/context-resource-identifiers.frontend.utils.js.map +1 -1
  663. package/dist/esm/core/resources/frontend-resource.utils.d.ts +22 -1
  664. package/dist/esm/core/resources/frontend-resource.utils.d.ts.map +1 -1
  665. package/dist/esm/core/resources/frontend-resource.utils.js +25 -2
  666. package/dist/esm/core/resources/frontend-resource.utils.js.map +1 -1
  667. package/dist/esm/core/resources/operation-semantics.frontend.utils.d.ts +113 -13
  668. package/dist/esm/core/resources/operation-semantics.frontend.utils.d.ts.map +1 -1
  669. package/dist/esm/core/resources/operation-semantics.frontend.utils.js +173 -20
  670. package/dist/esm/core/resources/operation-semantics.frontend.utils.js.map +1 -1
  671. package/dist/esm/core/resources/relationship-surface-runtime.frontend.utils.d.ts +11 -0
  672. package/dist/esm/core/resources/relationship-surface-runtime.frontend.utils.d.ts.map +1 -1
  673. package/dist/esm/core/resources/relationship-surface-runtime.frontend.utils.js +7 -0
  674. package/dist/esm/core/resources/relationship-surface-runtime.frontend.utils.js.map +1 -1
  675. package/dist/esm/core/resources/resource-label-field-paths.frontend.utils.d.ts +3 -2
  676. package/dist/esm/core/resources/resource-label-field-paths.frontend.utils.d.ts.map +1 -1
  677. package/dist/esm/core/resources/resource-label-field-paths.frontend.utils.js +13 -5
  678. package/dist/esm/core/resources/resource-label-field-paths.frontend.utils.js.map +1 -1
  679. package/dist/esm/core/resources/resources-repository.frontend.service.d.ts +6 -0
  680. package/dist/esm/core/resources/resources-repository.frontend.service.d.ts.map +1 -1
  681. package/dist/esm/core/resources/resources-repository.frontend.service.js +90 -1
  682. package/dist/esm/core/resources/resources-repository.frontend.service.js.map +1 -1
  683. package/dist/esm/core/resources/resources.frontend.schemas.d.ts +139 -16
  684. package/dist/esm/core/resources/resources.frontend.schemas.d.ts.map +1 -1
  685. package/dist/esm/core/resources/resources.frontend.schemas.js +110 -11
  686. package/dist/esm/core/resources/resources.frontend.schemas.js.map +1 -1
  687. package/dist/esm/core/resources/rmm/ResourceMutationManager.d.ts.map +1 -1
  688. package/dist/esm/core/resources/rmm/ResourceMutationManager.js +3 -1
  689. package/dist/esm/core/resources/rmm/ResourceMutationManager.js.map +1 -1
  690. package/dist/esm/core/resources/rmm/update-like-mutation-fallback.frontend.d.ts +10 -0
  691. package/dist/esm/core/resources/rmm/update-like-mutation-fallback.frontend.d.ts.map +1 -1
  692. package/dist/esm/core/resources/rmm/update-like-mutation-fallback.frontend.js +8 -0
  693. package/dist/esm/core/resources/rmm/update-like-mutation-fallback.frontend.js.map +1 -1
  694. package/dist/esm/core/resources/rmm/useResourceRMM.d.ts +7 -0
  695. package/dist/esm/core/resources/rmm/useResourceRMM.d.ts.map +1 -1
  696. package/dist/esm/core/resources/rmm/useResourceRMM.js +9 -2
  697. package/dist/esm/core/resources/rmm/useResourceRMM.js.map +1 -1
  698. package/dist/esm/core/resources/useOperationDirectExecution.d.ts +59 -0
  699. package/dist/esm/core/resources/useOperationDirectExecution.d.ts.map +1 -0
  700. package/dist/esm/core/resources/useOperationDirectExecution.js +278 -0
  701. package/dist/esm/core/resources/useOperationDirectExecution.js.map +1 -0
  702. package/dist/esm/core/resources/useResourceOperationActions.d.ts +1 -1
  703. package/dist/esm/core/resources/useResourceOperationActions.d.ts.map +1 -1
  704. package/dist/esm/core/resources/useResourceOperationActions.js +69 -22
  705. package/dist/esm/core/resources/useResourceOperationActions.js.map +1 -1
  706. package/dist/esm/core/resources/useResourceOperationSurface.d.ts +8 -6
  707. package/dist/esm/core/resources/useResourceOperationSurface.d.ts.map +1 -1
  708. package/dist/esm/core/resources/useResourceOperationSurface.js +3 -2
  709. package/dist/esm/core/resources/useResourceOperationSurface.js.map +1 -1
  710. package/dist/esm/core/runtime/AppRouter.d.ts.map +1 -1
  711. package/dist/esm/core/runtime/AppRouter.js +23 -2
  712. package/dist/esm/core/runtime/AppRouter.js.map +1 -1
  713. package/dist/esm/core/runtime/ApplicationContext.shared.d.ts +4 -2
  714. package/dist/esm/core/runtime/ApplicationContext.shared.d.ts.map +1 -1
  715. package/dist/esm/core/runtime/ApplicationContext.shared.js.map +1 -1
  716. package/dist/esm/core/runtime/ApplicationMainContext.d.ts +12 -2
  717. package/dist/esm/core/runtime/ApplicationMainContext.d.ts.map +1 -1
  718. package/dist/esm/core/runtime/ApplicationMainContext.js +5 -2
  719. package/dist/esm/core/runtime/ApplicationMainContext.js.map +1 -1
  720. package/dist/esm/core/runtime/domain-module.frontend.definitions.d.ts +25 -1
  721. package/dist/esm/core/runtime/domain-module.frontend.definitions.d.ts.map +1 -1
  722. package/dist/esm/core/runtime/domain-module.frontend.definitions.js +37 -1
  723. package/dist/esm/core/runtime/domain-module.frontend.definitions.js.map +1 -1
  724. package/dist/esm/core/runtime/start-application.frontend.service.d.ts +21 -2
  725. package/dist/esm/core/runtime/start-application.frontend.service.d.ts.map +1 -1
  726. package/dist/esm/core/runtime/start-application.frontend.service.js +51 -4
  727. package/dist/esm/core/runtime/start-application.frontend.service.js.map +1 -1
  728. package/dist/esm/core/security/AuthSessionContext.d.ts +11 -0
  729. package/dist/esm/core/security/AuthSessionContext.d.ts.map +1 -1
  730. package/dist/esm/core/security/AuthSessionContext.js +70 -22
  731. package/dist/esm/core/security/AuthSessionContext.js.map +1 -1
  732. package/dist/esm/core/security/StepUpAuthContext.d.ts.map +1 -1
  733. package/dist/esm/core/security/StepUpAuthContext.js +10 -2
  734. package/dist/esm/core/security/StepUpAuthContext.js.map +1 -1
  735. package/dist/esm/core/security/UserOrgsContext.d.ts.map +1 -1
  736. package/dist/esm/core/security/UserOrgsContext.js +72 -8
  737. package/dist/esm/core/security/UserOrgsContext.js.map +1 -1
  738. package/dist/esm/core/security/route-organization-access.frontend.utils.d.ts +7 -0
  739. package/dist/esm/core/security/route-organization-access.frontend.utils.d.ts.map +1 -1
  740. package/dist/esm/core/security/route-organization-access.frontend.utils.js +8 -2
  741. package/dist/esm/core/security/route-organization-access.frontend.utils.js.map +1 -1
  742. package/dist/esm/core/security/useGrantedConsentPurposes.d.ts +30 -0
  743. package/dist/esm/core/security/useGrantedConsentPurposes.d.ts.map +1 -0
  744. package/dist/esm/core/security/useGrantedConsentPurposes.js +38 -0
  745. package/dist/esm/core/security/useGrantedConsentPurposes.js.map +1 -0
  746. package/dist/esm/core/ui/UIContext.d.ts.map +1 -1
  747. package/dist/esm/core/ui/UIContext.js +10 -6
  748. package/dist/esm/core/ui/UIContext.js.map +1 -1
  749. package/dist/esm/core/ui/color-conversion.utils.d.ts +20 -0
  750. package/dist/esm/core/ui/color-conversion.utils.d.ts.map +1 -1
  751. package/dist/esm/core/ui/color-conversion.utils.js +39 -5
  752. package/dist/esm/core/ui/color-conversion.utils.js.map +1 -1
  753. package/dist/esm/core/ui/themes/default.theme.d.ts.map +1 -1
  754. package/dist/esm/core/ui/themes/default.theme.js +22 -2
  755. package/dist/esm/core/ui/themes/default.theme.js.map +1 -1
  756. package/dist/esm/core/ui/ui.frontend.schemas.d.ts +6 -6
  757. package/dist/esm/core/ui/ui.frontend.schemas.d.ts.map +1 -1
  758. package/dist/esm/core/ui/ui.frontend.schemas.js +3 -3
  759. package/dist/esm/core/ui/ui.frontend.schemas.js.map +1 -1
  760. package/dist/esm/index.d.ts +10 -1
  761. package/dist/esm/index.d.ts.map +1 -1
  762. package/dist/esm/index.js +19 -1
  763. package/dist/esm/index.js.map +1 -1
  764. package/dist/esm/testing/app-shell-placement-coverage.d.ts +43 -0
  765. package/dist/esm/testing/app-shell-placement-coverage.d.ts.map +1 -0
  766. package/dist/esm/testing/app-shell-placement-coverage.js +114 -0
  767. package/dist/esm/testing/app-shell-placement-coverage.js.map +1 -0
  768. package/dist/esm/testing/mock-builders.d.ts.map +1 -1
  769. package/dist/esm/testing/mock-builders.js +5 -0
  770. package/dist/esm/testing/mock-builders.js.map +1 -1
  771. package/dist/esm/testing.d.ts +1 -0
  772. package/dist/esm/testing.d.ts.map +1 -1
  773. package/dist/esm/testing.js +1 -0
  774. package/dist/esm/testing.js.map +1 -1
  775. package/package.json +9 -7
  776. package/dist/esm/core/navigation/useIsStackEntryActive.js +0 -15
  777. package/dist/tsconfig.build.tsbuildinfo +0 -1
@@ -0,0 +1,116 @@
1
+ import { NavigationZoneContentModel, NavigationZoneName, ResponsiveCollapseMode } from '@wildo-ai/saas-models';
2
+ import { NavigationZone } from './navigation.schemas.js';
3
+ import { resolveVisibleEntryIndex } from './zone-visible-entry.js';
4
+ /**
5
+ * Evacuate `zone` while it is collapsed under `mode`. Returns `state` itself when there is nothing
6
+ * to move, so a caller can compare by identity.
7
+ *
8
+ * - **SINGLE** — the whole stack moves, in order, so the pane's history survives: Back in primary
9
+ * walks it exactly as Back in the pane would have. An earlier version moved only the top, on the
10
+ * theory that history "in a pane that no longer exists" is not a place the reader can return to;
11
+ * but the pane DOES come back, and the contract (`ResponsiveCollapseMode`) says its content is
12
+ * preserved.
13
+ * - **TABBED** — every tab moves, with the tab on SCREEN last so it is the one primary shows. Tabs
14
+ * become history while the pane cannot be drawn: that is the only shape one column can give them,
15
+ * and it keeps every tab reachable rather than stranding the ones not in front.
16
+ *
17
+ * Each moved entry is stamped with `collapsedFromZone` — the one field that lets it go home — and its
18
+ * `zone` becomes where it now IS. The content area renders an entry under `entry.zone`, so an entry
19
+ * that kept `zone: secondary` while sitting in primary rendered a surface that believed it was in
20
+ * the pane: its Back called `goBack(secondary)` on an empty stack and did nothing (Wonder Todos,
21
+ * a `?pane=` record held in primary at 820px, 2026-09-28). Moving an object is not the same as
22
+ * re-describing it, but where it lives is not a property it keeps.
23
+ */
24
+ export function evacuateCollapsedZone(state, zone, mode, contentModel) {
25
+ const zoneState = state.zones[zone];
26
+ if (!zoneState || zoneState.stack.length === 0)
27
+ return state;
28
+ const visibleIndex = resolveVisibleEntryIndex(zoneState.stack, contentModel, zoneState.activeTabId);
29
+ const ordered = contentModel === NavigationZoneContentModel.TABBED
30
+ ? [...zoneState.stack.filter((_, index) => index !== visibleIndex), zoneState.stack[visibleIndex]]
31
+ : zoneState.stack;
32
+ const heldIn = mode === ResponsiveCollapseMode.OVERLAY ? NavigationZone.OVERLAY : NavigationZoneName.PRIMARY;
33
+ const moving = ordered.map((entry) => ({ ...entry, zone: heldIn, collapsedFromZone: zone }));
34
+ const emptied = { ...zoneState, stack: [], activeTabId: undefined, isVisible: false };
35
+ if (mode === ResponsiveCollapseMode.OVERLAY) {
36
+ return { ...state, overlay: [...state.overlay, ...moving], zones: { ...state.zones, [zone]: emptied } };
37
+ }
38
+ const primary = state.zones[NavigationZoneName.PRIMARY];
39
+ return {
40
+ ...state,
41
+ zones: {
42
+ ...state.zones,
43
+ [zone]: emptied,
44
+ [NavigationZoneName.PRIMARY]: { ...primary, stack: [...primary.stack, ...moving], isVisible: true },
45
+ },
46
+ };
47
+ }
48
+ /**
49
+ * The entries of `stack` held on behalf of `zone` that may still go home: those inside the TRAILING
50
+ * run of stamped entries.
51
+ *
52
+ * An entry the reader pushed on top of the borrowed content — an ordinary, unstamped navigation —
53
+ * ends the run. Everything beneath it is then history they walked through, and pulling it out from
54
+ * under the page they are standing on would be a worse surprise than leaving it where it is.
55
+ *
56
+ * Several zones may share one run (both panes collapse at MOBILE together), so the run is filtered
57
+ * by zone rather than required to be homogeneous. That is what makes the order in which zones are
58
+ * restored irrelevant — the defect the event-driven version had.
59
+ */
60
+ function returnableEntries(stack, zone) {
61
+ let runStart = stack.length;
62
+ while (runStart > 0 && stack[runStart - 1].collapsedFromZone !== undefined)
63
+ runStart -= 1;
64
+ return stack.slice(runStart).filter(entry => entry.collapsedFromZone === zone);
65
+ }
66
+ /**
67
+ * Return to `zone` everything held for it while it was collapsed. Returns `state` itself when there
68
+ * is nothing to return.
69
+ *
70
+ * Entries go home as the same objects, with `zone` set back and without their `collapsedFromZone`
71
+ * stamp, so `hostedPane`, `persistent`, `ephemeral`, `appearance` and anything added to the entry
72
+ * later all survive. A
73
+ * TABBED zone's active tab becomes the last returned entry — the one primary was showing, i.e. the
74
+ * one the reader was looking at.
75
+ */
76
+ export function restoreCollapsedZone(state, zone, contentModel) {
77
+ const primary = state.zones[NavigationZoneName.PRIMARY];
78
+ const fromPrimary = returnableEntries(primary.stack, zone);
79
+ const fromOverlay = returnableEntries(state.overlay, zone);
80
+ if (fromPrimary.length === 0 && fromOverlay.length === 0)
81
+ return state;
82
+ const leaving = new Set([...fromPrimary, ...fromOverlay].map(entry => entry.id));
83
+ const returning = [...fromPrimary, ...fromOverlay].map((entry) => {
84
+ const { collapsedFromZone: _home, ...rest } = entry;
85
+ return { ...rest, zone };
86
+ });
87
+ const zoneState = state.zones[zone];
88
+ const stack = [...zoneState.stack, ...returning];
89
+ return {
90
+ ...state,
91
+ overlay: fromOverlay.length > 0 ? state.overlay.filter(entry => !leaving.has(entry.id)) : state.overlay,
92
+ zones: {
93
+ ...state.zones,
94
+ [NavigationZoneName.PRIMARY]: fromPrimary.length > 0
95
+ ? { ...primary, stack: primary.stack.filter(entry => !leaving.has(entry.id)), isVisible: true }
96
+ : primary,
97
+ [zone]: {
98
+ ...zoneState,
99
+ stack,
100
+ isVisible: true,
101
+ activeTabId: contentModel === NavigationZoneContentModel.TABBED ? stack[stack.length - 1].id : zoneState.activeTabId,
102
+ },
103
+ },
104
+ };
105
+ }
106
+ /**
107
+ * Apply the invariant to every collapsible zone at once: evacuate each collapsed zone, return what
108
+ * is held for each shown one. Identity-preserving — the SAME state object comes back when nothing
109
+ * had to move — so it is safe to run on every render.
110
+ */
111
+ export function reconcileCollapsedZones(state, situations) {
112
+ return situations.reduce((current, { zone, mode, contentModel }) => (mode !== undefined
113
+ ? evacuateCollapsedZone(current, zone, mode, contentModel)
114
+ : restoreCollapsedZone(current, zone, contentModel)), state);
115
+ }
116
+ //# sourceMappingURL=zone-collapse-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-collapse-migration.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-collapse-migration.ts"],"names":[],"mappings":"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","sourcesContent":["import { NavigationZoneContentModel, NavigationZoneName, ResponsiveCollapseMode } from '@wildo-ai/saas-models';\n\nimport { NavigationZone } from './navigation.schemas';\nimport type { NavigationStackEntry, NavigationState, NavigationZoneState } from './navigation.schemas';\nimport { resolveVisibleEntryIndex } from './zone-visible-entry';\n\n/**\n * Moving a collapsed zone's content somewhere it can be SEEN, and home again — as pure state\n * transforms the reducer applies in ONE update.\n *\n * ## Why this is a reducer transform and not a sequence of events\n *\n * The first implementation (2026-09-25, `c8c8a7dc`) emitted `NAVIGATION_PUSH` / `CLEAR_ZONE` /\n * `POP` / `REPLACE` from a hook, one entry at a time. Each of those three defects followed from that\n * shape, and none of them could have been patched inside it:\n *\n * - **It read stale state.** `getZoneState` answers from the last RENDER, so within one pass the\n * hook could not see the POP it had just emitted. When both panes collapsed and then widened, the\n * secondary's restore saw the companion's entry on primary's top, skipped, and marked itself\n * done — the secondary's record stayed full-width beside an empty pane.\n * - **It lost what the entry was.** Every emit passes through a payload schema that STRIPS keys it\n * does not declare, and the migration re-described the entry field by field. `hostedPane`,\n * `persistent` and `ephemeral` did not make the round trip, so a hosted pane came home unflagged\n * under a URL still carrying its `?pane=`.\n * - **It moved one entry.** A pane's history came back as its last record, and a TABBED pane's\n * last tab was moved rather than the one on screen.\n *\n * A transform over `NavigationState` moves the entry OBJECTS — nothing is re-described, so nothing\n * can be dropped — and sees every zone at once, so two panes collapsing together are one decision.\n *\n * ## The invariant, which is what makes the caller a reconciler rather than an event handler\n *\n * **A collapsed zone holds nothing.** Content can reach one by any path — a click the resolver\n * already retargeted, a URL restored before the content area was measured, a `?pane=` reload —\n * and the rule does not care which: whatever sits in a collapsed zone is moved out. The inverse is\n * **nothing is held on behalf of a zone that is showing**. Both transforms are idempotent (a second\n * application changes nothing and returns the SAME object), so the caller may apply them on every\n * render without looping and without remembering what it did last time.\n */\n\n/** A zone's content model, as the layout declares it; `SINGLE` when undeclared. */\nexport type CollapsibleZoneContentModel = NavigationZoneContentModel | undefined;\n\n/**\n * Evacuate `zone` while it is collapsed under `mode`. Returns `state` itself when there is nothing\n * to move, so a caller can compare by identity.\n *\n * - **SINGLE** — the whole stack moves, in order, so the pane's history survives: Back in primary\n * walks it exactly as Back in the pane would have. An earlier version moved only the top, on the\n * theory that history \"in a pane that no longer exists\" is not a place the reader can return to;\n * but the pane DOES come back, and the contract (`ResponsiveCollapseMode`) says its content is\n * preserved.\n * - **TABBED** — every tab moves, with the tab on SCREEN last so it is the one primary shows. Tabs\n * become history while the pane cannot be drawn: that is the only shape one column can give them,\n * and it keeps every tab reachable rather than stranding the ones not in front.\n *\n * Each moved entry is stamped with `collapsedFromZone` — the one field that lets it go home — and its\n * `zone` becomes where it now IS. The content area renders an entry under `entry.zone`, so an entry\n * that kept `zone: secondary` while sitting in primary rendered a surface that believed it was in\n * the pane: its Back called `goBack(secondary)` on an empty stack and did nothing (Wonder Todos,\n * a `?pane=` record held in primary at 820px, 2026-09-28). Moving an object is not the same as\n * re-describing it, but where it lives is not a property it keeps.\n */\nexport function evacuateCollapsedZone(\n state: NavigationState,\n zone: NavigationZoneName,\n mode: ResponsiveCollapseMode,\n contentModel: CollapsibleZoneContentModel,\n): NavigationState {\n const zoneState = state.zones[zone];\n if (!zoneState || zoneState.stack.length === 0) return state;\n\n const visibleIndex = resolveVisibleEntryIndex(zoneState.stack, contentModel, zoneState.activeTabId);\n const ordered = contentModel === NavigationZoneContentModel.TABBED\n ? [...zoneState.stack.filter((_, index) => index !== visibleIndex), zoneState.stack[visibleIndex]!]\n : zoneState.stack;\n const heldIn = mode === ResponsiveCollapseMode.OVERLAY ? NavigationZone.OVERLAY : NavigationZoneName.PRIMARY;\n const moving = ordered.map((entry): NavigationStackEntry => ({ ...entry, zone: heldIn, collapsedFromZone: zone }));\n\n const emptied: NavigationZoneState = { ...zoneState, stack: [], activeTabId: undefined, isVisible: false };\n if (mode === ResponsiveCollapseMode.OVERLAY) {\n return { ...state, overlay: [...state.overlay, ...moving], zones: { ...state.zones, [zone]: emptied } };\n }\n const primary = state.zones[NavigationZoneName.PRIMARY];\n return {\n ...state,\n zones: {\n ...state.zones,\n [zone]: emptied,\n [NavigationZoneName.PRIMARY]: { ...primary, stack: [...primary.stack, ...moving], isVisible: true },\n },\n };\n}\n\n/**\n * The entries of `stack` held on behalf of `zone` that may still go home: those inside the TRAILING\n * run of stamped entries.\n *\n * An entry the reader pushed on top of the borrowed content — an ordinary, unstamped navigation —\n * ends the run. Everything beneath it is then history they walked through, and pulling it out from\n * under the page they are standing on would be a worse surprise than leaving it where it is.\n *\n * Several zones may share one run (both panes collapse at MOBILE together), so the run is filtered\n * by zone rather than required to be homogeneous. That is what makes the order in which zones are\n * restored irrelevant — the defect the event-driven version had.\n */\nfunction returnableEntries(stack: NavigationStackEntry[], zone: NavigationZoneName): NavigationStackEntry[] {\n let runStart = stack.length;\n while (runStart > 0 && stack[runStart - 1]!.collapsedFromZone !== undefined) runStart -= 1;\n return stack.slice(runStart).filter(entry => entry.collapsedFromZone === zone);\n}\n\n/**\n * Return to `zone` everything held for it while it was collapsed. Returns `state` itself when there\n * is nothing to return.\n *\n * Entries go home as the same objects, with `zone` set back and without their `collapsedFromZone`\n * stamp, so `hostedPane`, `persistent`, `ephemeral`, `appearance` and anything added to the entry\n * later all survive. A\n * TABBED zone's active tab becomes the last returned entry — the one primary was showing, i.e. the\n * one the reader was looking at.\n */\nexport function restoreCollapsedZone(\n state: NavigationState,\n zone: NavigationZoneName,\n contentModel: CollapsibleZoneContentModel,\n): NavigationState {\n const primary = state.zones[NavigationZoneName.PRIMARY];\n const fromPrimary = returnableEntries(primary.stack, zone);\n const fromOverlay = returnableEntries(state.overlay, zone);\n if (fromPrimary.length === 0 && fromOverlay.length === 0) return state;\n\n const leaving = new Set([...fromPrimary, ...fromOverlay].map(entry => entry.id));\n const returning = [...fromPrimary, ...fromOverlay].map((entry): NavigationStackEntry => {\n const { collapsedFromZone: _home, ...rest } = entry;\n return { ...rest, zone };\n });\n const zoneState = state.zones[zone];\n const stack = [...zoneState.stack, ...returning];\n\n return {\n ...state,\n overlay: fromOverlay.length > 0 ? state.overlay.filter(entry => !leaving.has(entry.id)) : state.overlay,\n zones: {\n ...state.zones,\n [NavigationZoneName.PRIMARY]: fromPrimary.length > 0\n ? { ...primary, stack: primary.stack.filter(entry => !leaving.has(entry.id)), isVisible: true }\n : primary,\n [zone]: {\n ...zoneState,\n stack,\n isVisible: true,\n activeTabId: contentModel === NavigationZoneContentModel.TABBED ? stack[stack.length - 1]!.id : zoneState.activeTabId,\n },\n },\n };\n}\n\n/** One collapsible zone's situation at this width, as the reconciler sees it. */\nexport interface CollapsibleZoneSituation {\n zone: NavigationZoneName;\n /** `undefined` when the zone is shown; otherwise the declared way it collapses. */\n mode: ResponsiveCollapseMode | undefined;\n contentModel: CollapsibleZoneContentModel;\n}\n\n/**\n * Apply the invariant to every collapsible zone at once: evacuate each collapsed zone, return what\n * is held for each shown one. Identity-preserving — the SAME state object comes back when nothing\n * had to move — so it is safe to run on every render.\n */\nexport function reconcileCollapsedZones(state: NavigationState, situations: CollapsibleZoneSituation[]): NavigationState {\n return situations.reduce(\n (current, { zone, mode, contentModel }) => (mode !== undefined\n ? evacuateCollapsedZone(current, zone, mode, contentModel)\n : restoreCollapsedZone(current, zone, contentModel)),\n state,\n );\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import { ViewportBreakpoint } from '@wildo-ai/zod-decorators';
2
+ import type { NavigationLayout, ZoneConfig } from '@wildo-ai/saas-models';
3
+ import { NavigationZoneName } from '@wildo-ai/saas-models';
4
+ /**
5
+ * Is an adjacent zone COLLAPSED right now — too narrow a viewport, or too narrow a content area?
6
+ *
7
+ * ## Why this is one function and not three conditions
8
+ *
9
+ * Three places answer this question, and until 2026-09-25 only one of them answered it completely:
10
+ *
11
+ * | asker | what it decides | what it used to read |
12
+ * |---|---|---|
13
+ * | `navigationPolicyResolver.resolveCollapseMode` | where a CLICK's content lands | viewport + content-area fit — correct |
14
+ * | `NavigationContentAreas` | whether the pane is RENDERED | `isMobile` only |
15
+ * | `NavigationUtils.resolveResourceTargetZone` | where a URL's content lands | nothing — it took no viewport at all |
16
+ *
17
+ * Both gaps produced a silent wrong result:
18
+ *
19
+ * - **The renderer's**: at VERT_TABLET (768–1023px) a declared `responsiveCollapse` retargets every
20
+ * click away from the pane while the pane keeps rendering — so a zone with `onEmpty: EMPTY_STATE`
21
+ * showed its "select an item" placeholder permanently, next to a list whose clicks went elsewhere.
22
+ * - **The URL path's**: a depth ≥ 1 resource was routed to SECONDARY regardless of viewport, and the
23
+ * mobile render branch draws PRIMARY and nothing else — so a bookmarked or refreshed nested record
24
+ * on a phone showed its PARENT, silently. The click path was correct the whole time, which is what
25
+ * made it invisible: the same content reached the right place when clicked and the wrong place when
26
+ * linked to. Note the viewport WAS threaded into the adjacent depth-0 branch
27
+ * (`prefersAdjacentZoneForDetail`) and not into this one — one invariant, two sites, one of them
28
+ * done (`.claude/rules/invariant-call-site-enumeration.md`).
29
+ *
30
+ * @param contentAreaWidth `undefined` until the first measurement, which answers "fits" — an
31
+ * unmeasured area is not a narrow one. See `contentAreaFitsSplit`.
32
+ */
33
+ export declare function zoneIsCollapsedAtViewport(params: {
34
+ zoneConfig: ZoneConfig | undefined;
35
+ viewport: ViewportBreakpoint | undefined;
36
+ contentAreaWidth?: number;
37
+ }): boolean;
38
+ /**
39
+ * The adjacent zone a URL-restored resource may actually be placed in, or `undefined` when every
40
+ * adjacent zone is collapsed and the content belongs in PRIMARY.
41
+ *
42
+ * The URL path's counterpart to the resolver's collapse handling: same predicate, same inputs, so a
43
+ * deep link and a click cannot disagree about where a record lives at a given width.
44
+ */
45
+ export declare function adjacentZoneUsableAtViewport(params: {
46
+ zone: NavigationZoneName;
47
+ layout: NavigationLayout | undefined;
48
+ viewport: ViewportBreakpoint | undefined;
49
+ contentAreaWidth?: number;
50
+ }): boolean;
51
+ //# sourceMappingURL=zone-collapse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-collapse.d.ts","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-collapse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;IACnC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAQV;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAOV"}
@@ -0,0 +1,59 @@
1
+ import { ViewportBreakpoint } from '@wildo-ai/zod-decorators';
2
+ import { NavigationZoneName } from '@wildo-ai/saas-models';
3
+ import { contentAreaFitsSplit } from './split-fit.js';
4
+ /**
5
+ * Is an adjacent zone COLLAPSED right now — too narrow a viewport, or too narrow a content area?
6
+ *
7
+ * ## Why this is one function and not three conditions
8
+ *
9
+ * Three places answer this question, and until 2026-09-25 only one of them answered it completely:
10
+ *
11
+ * | asker | what it decides | what it used to read |
12
+ * |---|---|---|
13
+ * | `navigationPolicyResolver.resolveCollapseMode` | where a CLICK's content lands | viewport + content-area fit — correct |
14
+ * | `NavigationContentAreas` | whether the pane is RENDERED | `isMobile` only |
15
+ * | `NavigationUtils.resolveResourceTargetZone` | where a URL's content lands | nothing — it took no viewport at all |
16
+ *
17
+ * Both gaps produced a silent wrong result:
18
+ *
19
+ * - **The renderer's**: at VERT_TABLET (768–1023px) a declared `responsiveCollapse` retargets every
20
+ * click away from the pane while the pane keeps rendering — so a zone with `onEmpty: EMPTY_STATE`
21
+ * showed its "select an item" placeholder permanently, next to a list whose clicks went elsewhere.
22
+ * - **The URL path's**: a depth ≥ 1 resource was routed to SECONDARY regardless of viewport, and the
23
+ * mobile render branch draws PRIMARY and nothing else — so a bookmarked or refreshed nested record
24
+ * on a phone showed its PARENT, silently. The click path was correct the whole time, which is what
25
+ * made it invisible: the same content reached the right place when clicked and the wrong place when
26
+ * linked to. Note the viewport WAS threaded into the adjacent depth-0 branch
27
+ * (`prefersAdjacentZoneForDetail`) and not into this one — one invariant, two sites, one of them
28
+ * done (`.claude/rules/invariant-call-site-enumeration.md`).
29
+ *
30
+ * @param contentAreaWidth `undefined` until the first measurement, which answers "fits" — an
31
+ * unmeasured area is not a narrow one. See `contentAreaFitsSplit`.
32
+ */
33
+ export function zoneIsCollapsedAtViewport(params) {
34
+ const narrowViewport = params.viewport === ViewportBreakpoint.MOBILE
35
+ || params.viewport === ViewportBreakpoint.VERT_TABLET;
36
+ if (narrowViewport)
37
+ return true;
38
+ return !contentAreaFitsSplit({
39
+ contentAreaWidth: params.contentAreaWidth,
40
+ paneMinWidthPx: params.zoneConfig?.minWidth,
41
+ });
42
+ }
43
+ /**
44
+ * The adjacent zone a URL-restored resource may actually be placed in, or `undefined` when every
45
+ * adjacent zone is collapsed and the content belongs in PRIMARY.
46
+ *
47
+ * The URL path's counterpart to the resolver's collapse handling: same predicate, same inputs, so a
48
+ * deep link and a click cannot disagree about where a record lives at a given width.
49
+ */
50
+ export function adjacentZoneUsableAtViewport(params) {
51
+ if (params.zone === NavigationZoneName.PRIMARY)
52
+ return true;
53
+ return !zoneIsCollapsedAtViewport({
54
+ zoneConfig: params.layout?.zones?.[params.zone],
55
+ viewport: params.viewport,
56
+ contentAreaWidth: params.contentAreaWidth,
57
+ });
58
+ }
59
+ //# sourceMappingURL=zone-collapse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-collapse.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-collapse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAIzC;IACC,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,KAAK,kBAAkB,CAAC,MAAM;WAC/D,MAAM,CAAC,QAAQ,KAAK,kBAAkB,CAAC,WAAW,CAAC;IACxD,IAAI,cAAc;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,CAAC,oBAAoB,CAAC;QAC3B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ;KAC5C,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAK5C;IACC,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC5D,OAAO,CAAC,yBAAyB,CAAC;QAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ViewportBreakpoint } from '@wildo-ai/zod-decorators';\nimport type { NavigationLayout, ZoneConfig } from '@wildo-ai/saas-models';\nimport { NavigationZoneName } from '@wildo-ai/saas-models';\n\nimport { contentAreaFitsSplit } from './split-fit';\n\n/**\n * Is an adjacent zone COLLAPSED right now — too narrow a viewport, or too narrow a content area?\n *\n * ## Why this is one function and not three conditions\n *\n * Three places answer this question, and until 2026-09-25 only one of them answered it completely:\n *\n * | asker | what it decides | what it used to read |\n * |---|---|---|\n * | `navigationPolicyResolver.resolveCollapseMode` | where a CLICK's content lands | viewport + content-area fit — correct |\n * | `NavigationContentAreas` | whether the pane is RENDERED | `isMobile` only |\n * | `NavigationUtils.resolveResourceTargetZone` | where a URL's content lands | nothing — it took no viewport at all |\n *\n * Both gaps produced a silent wrong result:\n *\n * - **The renderer's**: at VERT_TABLET (768–1023px) a declared `responsiveCollapse` retargets every\n * click away from the pane while the pane keeps rendering — so a zone with `onEmpty: EMPTY_STATE`\n * showed its \"select an item\" placeholder permanently, next to a list whose clicks went elsewhere.\n * - **The URL path's**: a depth ≥ 1 resource was routed to SECONDARY regardless of viewport, and the\n * mobile render branch draws PRIMARY and nothing else — so a bookmarked or refreshed nested record\n * on a phone showed its PARENT, silently. The click path was correct the whole time, which is what\n * made it invisible: the same content reached the right place when clicked and the wrong place when\n * linked to. Note the viewport WAS threaded into the adjacent depth-0 branch\n * (`prefersAdjacentZoneForDetail`) and not into this one — one invariant, two sites, one of them\n * done (`.claude/rules/invariant-call-site-enumeration.md`).\n *\n * @param contentAreaWidth `undefined` until the first measurement, which answers \"fits\" — an\n * unmeasured area is not a narrow one. See `contentAreaFitsSplit`.\n */\nexport function zoneIsCollapsedAtViewport(params: {\n zoneConfig: ZoneConfig | undefined;\n viewport: ViewportBreakpoint | undefined;\n contentAreaWidth?: number;\n}): boolean {\n const narrowViewport = params.viewport === ViewportBreakpoint.MOBILE\n || params.viewport === ViewportBreakpoint.VERT_TABLET;\n if (narrowViewport) return true;\n return !contentAreaFitsSplit({\n contentAreaWidth: params.contentAreaWidth,\n paneMinWidthPx: params.zoneConfig?.minWidth,\n });\n}\n\n/**\n * The adjacent zone a URL-restored resource may actually be placed in, or `undefined` when every\n * adjacent zone is collapsed and the content belongs in PRIMARY.\n *\n * The URL path's counterpart to the resolver's collapse handling: same predicate, same inputs, so a\n * deep link and a click cannot disagree about where a record lives at a given width.\n */\nexport function adjacentZoneUsableAtViewport(params: {\n zone: NavigationZoneName;\n layout: NavigationLayout | undefined;\n viewport: ViewportBreakpoint | undefined;\n contentAreaWidth?: number;\n}): boolean {\n if (params.zone === NavigationZoneName.PRIMARY) return true;\n return !zoneIsCollapsedAtViewport({\n zoneConfig: params.layout?.zones?.[params.zone],\n viewport: params.viewport,\n contentAreaWidth: params.contentAreaWidth,\n });\n}\n"]}
@@ -23,6 +23,9 @@ export declare function resolveEmphasizedZone(input: {
23
23
  isMobile: boolean;
24
24
  secondaryShown: boolean;
25
25
  companionShown: boolean;
26
+ /** Does the zone actually HOLD something? See the emptiness rule below. */
27
+ secondaryHasContent: boolean;
28
+ companionHasContent: boolean;
26
29
  }): NavigationZoneName.SECONDARY | NavigationZoneName.COMPANION | null;
27
30
  /**
28
31
  * Whether a keyboard Escape should restore the split.
@@ -1 +1 @@
1
- {"version":3,"file":"zone-emphasis.d.ts","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-emphasis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,kBAAkB,CAAC,SAAS,GAAG,kBAAkB,CAAC,SAAS,GAAG,IAAI,CAKrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAOV"}
1
+ {"version":3,"file":"zone-emphasis.d.ts","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-emphasis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AAqBH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,2EAA2E;IAC3E,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,GAAG,kBAAkB,CAAC,SAAS,GAAG,kBAAkB,CAAC,SAAS,GAAG,IAAI,CASrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAOV"}
@@ -18,13 +18,35 @@ import { NavigationZoneName } from '@wildo-ai/saas-models';
18
18
  * to a responsive collapse and got it back should find it expanded again; clearing the request on
19
19
  * every non-honouring render would make emphasis flicker off under them.
20
20
  */
21
+ /*
22
+ * ─── AN EMPTY ZONE IS NEVER EMPHASIZED, and that closes two ways of hiding the whole page ────────
23
+ *
24
+ * Emphasis hides every other structural zone, PRIMARY included (`primaryHidden = emphasized !== null`).
25
+ * Until 2026-09-25 it was released only when the requested zone was not SHOWN — and a zone whose
26
+ * `onEmpty` resolves to `EMPTY_STATE` is shown WHILE EMPTY, by construction.
27
+ *
28
+ * 1. **The pane empties while emphasized.** Navigate primary, let the dependency cleanup clear the
29
+ * pane, or pop its last entry: the zone keeps its width, keeps being shown, keeps being
30
+ * emphasized — and the entire content area becomes the pane's empty-state placeholder with the
31
+ * page behind it `display: none`. An `EMPTY_STATE` zone is deliberately NOT dismissable
32
+ * (`zoneIsDismissable`), so the only ways out were Escape and the emphasis toggle.
33
+ * 2. **The reader navigates the app.** Nothing cleared emphasis on navigation, so a sidebar click
34
+ * mounted the new destination in a hidden PRIMARY. This rule covers that case too rather than
35
+ * needing its own: an app-level navigation is a clean break, the clean break clears the adjacent
36
+ * zones, and a cleared zone now releases emphasis.
37
+ *
38
+ * "Shown" and "holds something" are different questions, and emphasis needs both. Asking only the
39
+ * first is what made an empty pane able to take the whole window.
40
+ */
21
41
  export function resolveEmphasizedZone(input) {
22
42
  if (input.requested === null || input.isMobile)
23
43
  return null;
24
- if (input.requested === NavigationZoneName.SECONDARY)
25
- return input.secondaryShown ? NavigationZoneName.SECONDARY : null;
26
- if (input.requested === NavigationZoneName.COMPANION)
27
- return input.companionShown ? NavigationZoneName.COMPANION : null;
44
+ if (input.requested === NavigationZoneName.SECONDARY) {
45
+ return input.secondaryShown && input.secondaryHasContent ? NavigationZoneName.SECONDARY : null;
46
+ }
47
+ if (input.requested === NavigationZoneName.COMPANION) {
48
+ return input.companionShown && input.companionHasContent ? NavigationZoneName.COMPANION : null;
49
+ }
28
50
  return null;
29
51
  }
30
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"zone-emphasis.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-emphasis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAKrC;IACC,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5D,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACxH,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACxH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAKtC;IACC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACnF,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,OAAO,CAAC,iBAAiB;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAC5B,OAAO,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,QAAQ,CAAC;AACnE,CAAC","sourcesContent":["import { NavigationZoneName } from '@wildo-ai/saas-models';\n\n/**\n * The zone that actually takes the whole content area this render, given what the reader asked for\n * and what the layout can currently show.\n *\n * Pure, so the rule is pinned without a provider stack. The reader's request\n * (`NavigationContextType.emphasizedZone`) is a wish; this is the decision, and it yields the area\n * back in every case where honouring the wish would hide the page:\n *\n * - on MOBILE there is one zone already, so emphasis means nothing;\n * - a zone with NOTHING IN IT cannot be emphasized — an empty full-width pane over a hidden list is\n * the blank screen the request was never about;\n * - PRIMARY is never emphasized: it has the whole area whenever nothing is beside it, and hiding the\n * adjacent zones to \"emphasize\" primary would be the same as closing them, which is a navigation\n * act with its own verbs.\n *\n * The request itself is left standing when it is not honoured. A reader who expanded a pane, lost it\n * to a responsive collapse and got it back should find it expanded again; clearing the request on\n * every non-honouring render would make emphasis flicker off under them.\n */\nexport function resolveEmphasizedZone(input: {\n requested: NavigationZoneName | null;\n isMobile: boolean;\n secondaryShown: boolean;\n companionShown: boolean;\n}): NavigationZoneName.SECONDARY | NavigationZoneName.COMPANION | null {\n if (input.requested === null || input.isMobile) return null;\n if (input.requested === NavigationZoneName.SECONDARY) return input.secondaryShown ? NavigationZoneName.SECONDARY : null;\n if (input.requested === NavigationZoneName.COMPANION) return input.companionShown ? NavigationZoneName.COMPANION : null;\n return null;\n}\n\n/**\n * Whether a keyboard Escape should restore the split.\n *\n * Escape is the universal \"leave this mode\" key and it is also what every text control, menu and\n * dialog listens for. Emphasis yields to all of them: a key pressed inside an editable control is\n * that control's, and a key pressed while an overlay is open belongs to the overlay (the overlay\n * layer sits above the content areas and has its own dismissal). What is left — Escape on the page\n * itself while a pane is emphasized — restores the split.\n */\nexport function escapeRestoresEmphasis(input: {\n key: string;\n emphasized: boolean;\n overlayOpen: boolean;\n target: EventTarget | null;\n}): boolean {\n if (input.key !== 'Escape' || !input.emphasized || input.overlayOpen) return false;\n const element = input.target instanceof HTMLElement ? input.target : null;\n if (element === null) return true;\n if (element.isContentEditable) return false;\n const tag = element.tagName;\n return tag !== 'INPUT' && tag !== 'TEXTAREA' && tag !== 'SELECT';\n}\n"]}
1
+ {"version":3,"file":"zone-emphasis.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-emphasis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAQrC;IACC,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5D,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,SAAS,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,SAAS,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAKtC;IACC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACnF,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,OAAO,CAAC,iBAAiB;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;IAC5B,OAAO,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,QAAQ,CAAC;AACnE,CAAC","sourcesContent":["import { NavigationZoneName } from '@wildo-ai/saas-models';\n\n/**\n * The zone that actually takes the whole content area this render, given what the reader asked for\n * and what the layout can currently show.\n *\n * Pure, so the rule is pinned without a provider stack. The reader's request\n * (`NavigationContextType.emphasizedZone`) is a wish; this is the decision, and it yields the area\n * back in every case where honouring the wish would hide the page:\n *\n * - on MOBILE there is one zone already, so emphasis means nothing;\n * - a zone with NOTHING IN IT cannot be emphasized — an empty full-width pane over a hidden list is\n * the blank screen the request was never about;\n * - PRIMARY is never emphasized: it has the whole area whenever nothing is beside it, and hiding the\n * adjacent zones to \"emphasize\" primary would be the same as closing them, which is a navigation\n * act with its own verbs.\n *\n * The request itself is left standing when it is not honoured. A reader who expanded a pane, lost it\n * to a responsive collapse and got it back should find it expanded again; clearing the request on\n * every non-honouring render would make emphasis flicker off under them.\n */\n/*\n * ─── AN EMPTY ZONE IS NEVER EMPHASIZED, and that closes two ways of hiding the whole page ────────\n *\n * Emphasis hides every other structural zone, PRIMARY included (`primaryHidden = emphasized !== null`).\n * Until 2026-09-25 it was released only when the requested zone was not SHOWN — and a zone whose\n * `onEmpty` resolves to `EMPTY_STATE` is shown WHILE EMPTY, by construction.\n *\n * 1. **The pane empties while emphasized.** Navigate primary, let the dependency cleanup clear the\n * pane, or pop its last entry: the zone keeps its width, keeps being shown, keeps being\n * emphasized — and the entire content area becomes the pane's empty-state placeholder with the\n * page behind it `display: none`. An `EMPTY_STATE` zone is deliberately NOT dismissable\n * (`zoneIsDismissable`), so the only ways out were Escape and the emphasis toggle.\n * 2. **The reader navigates the app.** Nothing cleared emphasis on navigation, so a sidebar click\n * mounted the new destination in a hidden PRIMARY. This rule covers that case too rather than\n * needing its own: an app-level navigation is a clean break, the clean break clears the adjacent\n * zones, and a cleared zone now releases emphasis.\n *\n * \"Shown\" and \"holds something\" are different questions, and emphasis needs both. Asking only the\n * first is what made an empty pane able to take the whole window.\n */\nexport function resolveEmphasizedZone(input: {\n requested: NavigationZoneName | null;\n isMobile: boolean;\n secondaryShown: boolean;\n companionShown: boolean;\n /** Does the zone actually HOLD something? See the emptiness rule below. */\n secondaryHasContent: boolean;\n companionHasContent: boolean;\n}): NavigationZoneName.SECONDARY | NavigationZoneName.COMPANION | null {\n if (input.requested === null || input.isMobile) return null;\n if (input.requested === NavigationZoneName.SECONDARY) {\n return input.secondaryShown && input.secondaryHasContent ? NavigationZoneName.SECONDARY : null;\n }\n if (input.requested === NavigationZoneName.COMPANION) {\n return input.companionShown && input.companionHasContent ? NavigationZoneName.COMPANION : null;\n }\n return null;\n}\n\n/**\n * Whether a keyboard Escape should restore the split.\n *\n * Escape is the universal \"leave this mode\" key and it is also what every text control, menu and\n * dialog listens for. Emphasis yields to all of them: a key pressed inside an editable control is\n * that control's, and a key pressed while an overlay is open belongs to the overlay (the overlay\n * layer sits above the content areas and has its own dismissal). What is left — Escape on the page\n * itself while a pane is emphasized — restores the split.\n */\nexport function escapeRestoresEmphasis(input: {\n key: string;\n emphasized: boolean;\n overlayOpen: boolean;\n target: EventTarget | null;\n}): boolean {\n if (input.key !== 'Escape' || !input.emphasized || input.overlayOpen) return false;\n const element = input.target instanceof HTMLElement ? input.target : null;\n if (element === null) return true;\n if (element.isContentEditable) return false;\n const tag = element.tagName;\n return tag !== 'INPUT' && tag !== 'TEXTAREA' && tag !== 'SELECT';\n}\n"]}
@@ -23,4 +23,26 @@ import type { NavigationStackEntry } from './navigation.schemas';
23
23
  * @returns The index to render, or `-1` for an empty stack.
24
24
  */
25
25
  export declare function resolveVisibleEntryIndex(stack: NavigationStackEntry[], contentModel: NavigationZoneContentModel | undefined, activeTabId: string | undefined): number;
26
+ /**
27
+ * Which entry a zone MUTATION acts on — the reducer's counterpart to {@link resolveVisibleEntryIndex}.
28
+ *
29
+ * ## Why it does not take the content model
30
+ *
31
+ * `resolveVisibleEntryIndex` is the renderer's answer and reads `contentModel` off the LAYOUT. The
32
+ * reducer has no layout, so it reads the one thing that is only ever written for a TABBED zone:
33
+ * `NavigationZoneState.activeTabId`. Absent, the acted-on entry is the top of the stack, which is
34
+ * the SINGLE contract exactly.
35
+ *
36
+ * ## Why it is a function and not two inline copies
37
+ *
38
+ * It was two, briefly, on 2026-09-25 — one in `replaceEntry` and one in `popEntry` — added in the
39
+ * change that deleted `useIsStackEntryActive` for being a third answer to the same question. Two
40
+ * copies with a rule of their own is the thing that change existed to remove, so they became this.
41
+ *
42
+ * A stale `activeTabId` matching no entry falls back to the top rather than dropping the write: a
43
+ * tab closed from under an id must not make the zone unwritable.
44
+ */
45
+ export declare function zoneMutationTargetIndex(stack: readonly {
46
+ id: string;
47
+ }[], activeTabId: string | undefined): number;
26
48
  //# sourceMappingURL=zone-visible-entry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zone-visible-entry.d.ts","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-visible-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,oBAAoB,EAAE,EAC7B,YAAY,EAAE,0BAA0B,GAAG,SAAS,EACpD,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,CAuDR"}
1
+ {"version":3,"file":"zone-visible-entry.d.ts","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-visible-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,oBAAoB,EAAE,EAC7B,YAAY,EAAE,0BAA0B,GAAG,SAAS,EACpD,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,CAuDR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAChC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,CAIR"}
@@ -73,4 +73,29 @@ export function resolveVisibleEntryIndex(stack, contentModel, activeTabId) {
73
73
  const activeIndex = stack.findIndex(entry => entry.id === activeTabId);
74
74
  return activeIndex >= 0 ? activeIndex : topIndex;
75
75
  }
76
+ /**
77
+ * Which entry a zone MUTATION acts on — the reducer's counterpart to {@link resolveVisibleEntryIndex}.
78
+ *
79
+ * ## Why it does not take the content model
80
+ *
81
+ * `resolveVisibleEntryIndex` is the renderer's answer and reads `contentModel` off the LAYOUT. The
82
+ * reducer has no layout, so it reads the one thing that is only ever written for a TABBED zone:
83
+ * `NavigationZoneState.activeTabId`. Absent, the acted-on entry is the top of the stack, which is
84
+ * the SINGLE contract exactly.
85
+ *
86
+ * ## Why it is a function and not two inline copies
87
+ *
88
+ * It was two, briefly, on 2026-09-25 — one in `replaceEntry` and one in `popEntry` — added in the
89
+ * change that deleted `useIsStackEntryActive` for being a third answer to the same question. Two
90
+ * copies with a rule of their own is the thing that change existed to remove, so they became this.
91
+ *
92
+ * A stale `activeTabId` matching no entry falls back to the top rather than dropping the write: a
93
+ * tab closed from under an id must not make the zone unwritable.
94
+ */
95
+ export function zoneMutationTargetIndex(stack, activeTabId) {
96
+ if (stack.length === 0)
97
+ return -1;
98
+ const activeIndex = activeTabId !== undefined ? stack.findIndex(entry => entry.id === activeTabId) : -1;
99
+ return activeIndex >= 0 ? activeIndex : stack.length - 1;
100
+ }
76
101
  //# sourceMappingURL=zone-visible-entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zone-visible-entry.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-visible-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAInE;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAA6B,EAC7B,YAAoD,EACpD,WAA+B;IAE/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAElC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAElC;;;;;;;;;;;;;;;;OAgBG;IACH,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAEhD,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,0BAA0B,CAAC,MAAM;YACpC,OAAO,QAAQ,CAAC;QAClB,KAAK,0BAA0B,CAAC,MAAM;YACpC,MAAM;QACR,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,sBAAsB,GAAU,YAAY,CAAC;YACnD;;;;;eAKG;YACH,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,CAAC,sBAAsB,CAAC,yBAAyB;kBACzF,8EAA8E,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;IACvE,OAAO,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnD,CAAC","sourcesContent":["/**\n * Which entry of a zone's stack is the VISIBLE one — the single behavioural difference between the\n * two `NavigationZoneContentModel` members (#411).\n *\n * Both models keep every entry mounted. `SINGLE` shows the TOP of the stack and BACK pops it;\n * `TABBED` shows the ACTIVE tab and the rest are one click away. Everything else about the two\n * renderings is identical, so this function is the whole distinction and is the only place it is\n * decided.\n *\n * It exists as a named pure function rather than an expression inside `ZoneContentRenderer` because\n * that expression is what `TABBED` was missing for its entire life: the member was declared,\n * documented as \"parallel tabs, tab bar visible\", validated by the layout schema and selected by one\n * of the framework's own shipped presets, while the renderer showed the top of the stack — with no\n * error. A behaviour that is one inline ternary is a behaviour nothing can pin.\n */\n\nimport { NavigationZoneContentModel } from '@wildo-ai/saas-models';\n\nimport type { NavigationStackEntry } from './navigation.schemas';\n\n/**\n * @param stack The zone's entries, oldest first.\n * @param contentModel The zone's DECLARED content model. `undefined` reads as `SINGLE` — the schema\n * default, and the behaviour every zone had before a model was declarable.\n * @param activeTabId `NavigationZoneState.activeTabId`. Ignored outside `TABBED`.\n * @returns The index to render, or `-1` for an empty stack.\n */\nexport function resolveVisibleEntryIndex(\n stack: NavigationStackEntry[],\n contentModel: NavigationZoneContentModel | undefined,\n activeTabId: string | undefined,\n): number {\n if (stack.length === 0) return -1;\n\n const topIndex = stack.length - 1;\n\n /*\n * ─── EXHAUSTIVE ON PURPOSE: a new content model must not be able to ship silently ───────────────\n *\n * This switch is the fourth item of #411, and it is the one that outlives the other three. All\n * three behaviours that issue fixed failed the SAME way — declared in a vocabulary, validated by a\n * schema, selected by a config, and read by no renderer, with no error — and `TABBED` is the\n * clearest case because the framework's own preset chose it and got a single stack.\n *\n * A `switch` with a `never` assignment turns the next such member into a COMPILE error at the\n * exact place a renderer has to exist. That is strictly stronger than a runtime warning, which\n * fires only if someone happens to configure the member and happens to be reading the console;\n * `preset-navigation.ts` selected TABBED for months with nobody reading anything.\n *\n * `undefined` (the schema default, and every zone that predates the field) is handled BEFORE the\n * switch so that adding a member cannot be satisfied by widening a `default:` arm — there is no\n * `default:` arm to widen.\n */\n if (contentModel === undefined) return topIndex;\n\n switch (contentModel) {\n case NavigationZoneContentModel.SINGLE:\n return topIndex;\n case NavigationZoneContentModel.TABBED:\n break;\n default: {\n const unrenderedContentModel: never = contentModel;\n /*\n * Unreachable while the switch is exhaustive. Kept as a THROW rather than a silent fallback\n * because the alternative — quietly returning the top entry — is precisely the degradation\n * this whole guard exists to make impossible, and a build that somehow reaches here (a value\n * from an older bundle, a cast) should say so rather than pretend.\n */\n throw new Error(\n `[navigation] Zone content model '${String(unrenderedContentModel)}' reaches no renderer. `\n + 'Add a case to resolveVisibleEntryIndex, and the rendering that case implies.',\n );\n }\n }\n\n /*\n * The TOP entry is the fallback in two situations, and both are ordinary rather than exceptional:\n * nothing has been activated yet (the frame after the first tab opens), and `activeTabId` names an\n * entry the stack no longer holds (a tab closed while it was active). Rendering nothing in either\n * case would blank the zone under a full tab bar.\n *\n * Falling back to the TOP rather than the FIRST is deliberate: the newest tab is the one the user\n * just caused to exist, so it is the one they are looking for.\n */\n const activeIndex = stack.findIndex(entry => entry.id === activeTabId);\n return activeIndex >= 0 ? activeIndex : topIndex;\n}\n"]}
1
+ {"version":3,"file":"zone-visible-entry.js","sourceRoot":"","sources":["../../../../../src/core/navigation/zone-visible-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAInE;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAA6B,EAC7B,YAAoD,EACpD,WAA+B;IAE/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAElC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAElC;;;;;;;;;;;;;;;;OAgBG;IACH,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAEhD,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,0BAA0B,CAAC,MAAM;YACpC,OAAO,QAAQ,CAAC;QAClB,KAAK,0BAA0B,CAAC,MAAM;YACpC,MAAM;QACR,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,sBAAsB,GAAU,YAAY,CAAC;YACnD;;;;;eAKG;YACH,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,CAAC,sBAAsB,CAAC,yBAAyB;kBACzF,8EAA8E,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;IACvE,OAAO,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAgC,EAChC,WAA+B;IAE/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,OAAO,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["/**\n * Which entry of a zone's stack is the VISIBLE one — the single behavioural difference between the\n * two `NavigationZoneContentModel` members (#411).\n *\n * Both models keep every entry mounted. `SINGLE` shows the TOP of the stack and BACK pops it;\n * `TABBED` shows the ACTIVE tab and the rest are one click away. Everything else about the two\n * renderings is identical, so this function is the whole distinction and is the only place it is\n * decided.\n *\n * It exists as a named pure function rather than an expression inside `ZoneContentRenderer` because\n * that expression is what `TABBED` was missing for its entire life: the member was declared,\n * documented as \"parallel tabs, tab bar visible\", validated by the layout schema and selected by one\n * of the framework's own shipped presets, while the renderer showed the top of the stack — with no\n * error. A behaviour that is one inline ternary is a behaviour nothing can pin.\n */\n\nimport { NavigationZoneContentModel } from '@wildo-ai/saas-models';\n\nimport type { NavigationStackEntry } from './navigation.schemas';\n\n/**\n * @param stack The zone's entries, oldest first.\n * @param contentModel The zone's DECLARED content model. `undefined` reads as `SINGLE` — the schema\n * default, and the behaviour every zone had before a model was declarable.\n * @param activeTabId `NavigationZoneState.activeTabId`. Ignored outside `TABBED`.\n * @returns The index to render, or `-1` for an empty stack.\n */\nexport function resolveVisibleEntryIndex(\n stack: NavigationStackEntry[],\n contentModel: NavigationZoneContentModel | undefined,\n activeTabId: string | undefined,\n): number {\n if (stack.length === 0) return -1;\n\n const topIndex = stack.length - 1;\n\n /*\n * ─── EXHAUSTIVE ON PURPOSE: a new content model must not be able to ship silently ───────────────\n *\n * This switch is the fourth item of #411, and it is the one that outlives the other three. All\n * three behaviours that issue fixed failed the SAME way — declared in a vocabulary, validated by a\n * schema, selected by a config, and read by no renderer, with no error — and `TABBED` is the\n * clearest case because the framework's own preset chose it and got a single stack.\n *\n * A `switch` with a `never` assignment turns the next such member into a COMPILE error at the\n * exact place a renderer has to exist. That is strictly stronger than a runtime warning, which\n * fires only if someone happens to configure the member and happens to be reading the console;\n * `preset-navigation.ts` selected TABBED for months with nobody reading anything.\n *\n * `undefined` (the schema default, and every zone that predates the field) is handled BEFORE the\n * switch so that adding a member cannot be satisfied by widening a `default:` arm — there is no\n * `default:` arm to widen.\n */\n if (contentModel === undefined) return topIndex;\n\n switch (contentModel) {\n case NavigationZoneContentModel.SINGLE:\n return topIndex;\n case NavigationZoneContentModel.TABBED:\n break;\n default: {\n const unrenderedContentModel: never = contentModel;\n /*\n * Unreachable while the switch is exhaustive. Kept as a THROW rather than a silent fallback\n * because the alternative — quietly returning the top entry — is precisely the degradation\n * this whole guard exists to make impossible, and a build that somehow reaches here (a value\n * from an older bundle, a cast) should say so rather than pretend.\n */\n throw new Error(\n `[navigation] Zone content model '${String(unrenderedContentModel)}' reaches no renderer. `\n + 'Add a case to resolveVisibleEntryIndex, and the rendering that case implies.',\n );\n }\n }\n\n /*\n * The TOP entry is the fallback in two situations, and both are ordinary rather than exceptional:\n * nothing has been activated yet (the frame after the first tab opens), and `activeTabId` names an\n * entry the stack no longer holds (a tab closed while it was active). Rendering nothing in either\n * case would blank the zone under a full tab bar.\n *\n * Falling back to the TOP rather than the FIRST is deliberate: the newest tab is the one the user\n * just caused to exist, so it is the one they are looking for.\n */\n const activeIndex = stack.findIndex(entry => entry.id === activeTabId);\n return activeIndex >= 0 ? activeIndex : topIndex;\n}\n\n/**\n * Which entry a zone MUTATION acts on — the reducer's counterpart to {@link resolveVisibleEntryIndex}.\n *\n * ## Why it does not take the content model\n *\n * `resolveVisibleEntryIndex` is the renderer's answer and reads `contentModel` off the LAYOUT. The\n * reducer has no layout, so it reads the one thing that is only ever written for a TABBED zone:\n * `NavigationZoneState.activeTabId`. Absent, the acted-on entry is the top of the stack, which is\n * the SINGLE contract exactly.\n *\n * ## Why it is a function and not two inline copies\n *\n * It was two, briefly, on 2026-09-25 — one in `replaceEntry` and one in `popEntry` — added in the\n * change that deleted `useIsStackEntryActive` for being a third answer to the same question. Two\n * copies with a rule of their own is the thing that change existed to remove, so they became this.\n *\n * A stale `activeTabId` matching no entry falls back to the top rather than dropping the write: a\n * tab closed from under an id must not make the zone unwritable.\n */\nexport function zoneMutationTargetIndex(\n stack: readonly { id: string }[],\n activeTabId: string | undefined,\n): number {\n if (stack.length === 0) return -1;\n const activeIndex = activeTabId !== undefined ? stack.findIndex(entry => entry.id === activeTabId) : -1;\n return activeIndex >= 0 ? activeIndex : stack.length - 1;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocketContext.d.ts","sourceRoot":"","sources":["../../../../../../src/core/requests/websockets/WebSocketContext.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WebSocketContext.d.ts","sourceRoot":"","sources":["../../../../../../src/core/requests/websockets/WebSocketContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA2B,SAAS,EAA2C,MAAM,OAAO,CAAC;AAM3G,OAAO,EAaL,sBAAsB,EASvB,MAAM,uBAAuB,CAAC;AA6E/B;;;;GAIG;AAEH,oBAAY,eAAe;IACzB,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,YAAY,iBAAiB;CAC9B;AAED,KAAK,+BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAsDlH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,qBAAqB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD;AAoCD,MAAM,WAAW,oBAAoB;IAEnC,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,cAAc,EAAE,CAAC;IAGlC,OAAO,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,kBAAkB,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,sBAAsB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAGtF,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAC9E,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;IACpE,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;IAGvD,mBAAmB,EAAE,CAAC,MAAM,EAAE;QAC5B,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0BAA0B,EAAE,+BAA+B,CAAC;KAC7D,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC7D,iBAAiB,EAAE,CAAC,MAAM,EAAE;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0BAA0B,EAAE,+BAA+B,CAAC;KAC7D,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC7D,uBAAuB,EAAE,CAAC,MAAM,EAAE;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0BAA0B,EAAE,+BAA+B,CAAC;KAC7D,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,mBAAmB,EAAE,CAAC,MAAM,EAAE;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0BAA0B,EAAE,+BAA+B,CAAC;KAC7D,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGpB,YAAY,EAAE,CAAC,MAAM,EAAE;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,0BAA0B,EAAE,+BAA+B,CAAC;KAC7D,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,MAAM,EAAE;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,KAAK,IAAI,CAAC;IAGX,eAAe,EAAE,CAAC,MAAM,EAAE;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,0BAA0B,EAAE,+BAA+B,CAAC;QAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,KAAK,IAAI,CAAC;IAGX,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClF,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAGlF,iBAAiB,EAAE,MAAM;QACvB,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;KAC1B,CAAC;CACH;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAA8D,CAAC;AAa5I,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,CA46C/D,CAAC"}
@@ -4,7 +4,7 @@ import { io } from 'socket.io-client';
4
4
  import axios from 'axios';
5
5
  import { errorManagement } from '../../../core/errors/error-management.frontend.service.js';
6
6
  import { ResourceOperationRiskLevel, WildoHeaderKeys } from '@wildo-ai/saas-models';
7
- import { CoreWebSocketEvent, CoreWebSocketConnectionErrorCode, buildResourceRoomName, buildScopeRoomName, safeValidateWebSocketPayload, WebSocketEventSchemas, } from '@wildo-ai/saas-models';
7
+ import { CoreWebSocketEvent, CoreWebSocketConnectionErrorCode, WebSocketSystemErrorCode, buildResourceRoomName, buildScopeRoomName, safeValidateWebSocketPayload, WebSocketEventSchemas, } from '@wildo-ai/saas-models';
8
8
  import { fullJitterBackoffMs } from '../../../core/requests/network-backoff.frontend.utils.js';
9
9
  import { getClientInstanceId } from '../../../core/requests/client-instance-id.frontend.service.js';
10
10
  import { envLoader } from '../../../core/runtime/env-variable-loader.frontend.service.js';
@@ -216,6 +216,9 @@ export const WebSocketProvider = ({ children }) => {
216
216
  // still renew once the backend returns), so this never suppresses legitimate
217
217
  // recovery. See `MAX_CONSECUTIVE_WS_AUTH_RENEWALS`.
218
218
  const authRenewalStreakRef = useRef(0);
219
+ // The organization a refused ORGANIZATION_SWITCH already triggered a re-handshake for (#1597). One resync per
220
+ // intended organization, reset by the next switch, so a switch the server keeps refusing cannot loop.
221
+ const switchResyncForOrganizationRef = useRef(null);
219
222
  const reconnectTimeoutRef = useRef(null);
220
223
  const reconnectAttemptsRef = useRef(0);
221
224
  // Backoff counter for the connectivity SUPERVISOR's watchdog probes (see the
@@ -567,7 +570,7 @@ export const WebSocketProvider = ({ children }) => {
567
570
  authRenewalStreakRef.current = 0;
568
571
  });
569
572
  socket.on(CoreWebSocketEvent.SYSTEM_ERROR, (payload) => {
570
- if (payload?.code === 'AUTH_REFRESH_FAILED') {
573
+ if (payload?.code === WebSocketSystemErrorCode.AUTH_REFRESH_FAILED) {
571
574
  // A live in-place `AUTH_REFRESH` emit was rejected — the token we believed
572
575
  // fresh did not validate (clock skew, a sub-second expiry race, or the
573
576
  // credential genuinely went stale on a long-lived connected socket while
@@ -580,7 +583,23 @@ export const WebSocketProvider = ({ children }) => {
580
583
  requestAuthRenewal('live refresh rejected');
581
584
  return;
582
585
  }
583
- if (payload?.code === 'RATE_LIMIT_EXCEEDED') {
586
+ if (payload?.code === WebSocketSystemErrorCode.ORGANIZATION_SWITCH_FORBIDDEN) {
587
+ // The server kept this connection in its PREVIOUS organization — its rooms, its subscription checks — while the
588
+ // UI has moved on (#1597). Left alone that lasts until some later reconnect. Re-handshake ONCE per intended
589
+ // organization: the handshake carries the latest token and the organization the user switched to, and the
590
+ // server re-derives everything from them. The handshake applies its own rules — a revoked session or an
591
+ // expired token fails it, an organization the user is not in is not honoured — and the once-per-organization
592
+ // guard keeps a refusal from looping.
593
+ const intendedOrganizationId = authStateRef.current.organizationId;
594
+ if (intendedOrganizationId && switchResyncForOrganizationRef.current !== intendedOrganizationId) {
595
+ switchResyncForOrganizationRef.current = intendedOrganizationId;
596
+ console.warn('WebSocket: Organization switch refused; re-handshaking into the intended organization', payload);
597
+ socket.disconnect();
598
+ socket.connect();
599
+ }
600
+ return;
601
+ }
602
+ if (payload?.code === WebSocketSystemErrorCode.RATE_LIMIT_EXCEEDED) {
584
603
  const errorMessage = payload.message || 'Too many real-time requests. Please slow down.';
585
604
  const detailsContext = normalizeSystemErrorDetails(payload.details);
586
605
  console.warn('WebSocket: Rate limit exceeded', payload);
@@ -1179,28 +1198,44 @@ export const WebSocketProvider = ({ children }) => {
1179
1198
  * Switch organization context
1180
1199
  */
1181
1200
  const switchOrganization = useCallback((organizationId, previousOrganizationId) => {
1201
+ // The organization this connection should be in from now on — recorded FIRST, connected or not (review 4). Every
1202
+ // later handshake must carry it: a transport drop, the resync after a refused switch, a revival that rebuilds the
1203
+ // socket from the stored config. A switch made while the socket was down used to return before this, so the
1204
+ // reconnect reopened the PREVIOUS organization with nothing left to correct it.
1205
+ authStateRef.current = { ...authStateRef.current, organizationId };
1206
+ if (configRef.current)
1207
+ configRef.current = { ...configRef.current, organizationId };
1208
+ switchResyncForOrganizationRef.current = null;
1209
+ // The previous organization's rooms are released whether or not the socket is up (#1597, review 5). Released while
1210
+ // connected, each release unsubscribes; released while disconnected, the claims are simply dropped — otherwise the
1211
+ // reconnect replays every claimed room, and the previous organization's rooms would be re-requested under the new
1212
+ // one, where they no longer belong.
1213
+ const releasePreviousOrganizationRooms = () => {
1214
+ if (!previousOrganizationId)
1215
+ return;
1216
+ const roomsToRelease = Array.from(roomClaimsRef.current.values())
1217
+ .filter((room) => roomMatchesOrganization(room, previousOrganizationId))
1218
+ .flatMap((room) => Array.from(room.ownerKeys).map((ownerKey) => ({
1219
+ ownerKey,
1220
+ resourceType: room.resourceType,
1221
+ resourceId: room.resourceId,
1222
+ scopeKey: room.scopeKey,
1223
+ scopeId: room.scopeId,
1224
+ contextResourceIdentifiers: room.ownerContexts.get(ownerKey) ?? room.contextResourceIdentifiers,
1225
+ })));
1226
+ void Promise.all(roomsToRelease.map((room) => releaseResourceRoom(room)));
1227
+ };
1182
1228
  if (!socketRef.current?.connected) {
1183
- console.warn('Cannot switch organization: not connected');
1229
+ // Nothing to emit: the next handshake carries the organization recorded above.
1230
+ console.warn('Organization switch recorded while not connected; the next handshake will carry it');
1231
+ releasePreviousOrganizationRooms();
1184
1232
  return;
1185
1233
  }
1186
1234
  socketRef.current.emit(CoreWebSocketEvent.ORGANIZATION_SWITCH, {
1187
1235
  organizationId,
1188
1236
  previousOrganizationId,
1189
1237
  });
1190
- if (!previousOrganizationId) {
1191
- return;
1192
- }
1193
- const roomsToRelease = Array.from(roomClaimsRef.current.values())
1194
- .filter((room) => roomMatchesOrganization(room, previousOrganizationId))
1195
- .flatMap((room) => Array.from(room.ownerKeys).map((ownerKey) => ({
1196
- ownerKey,
1197
- resourceType: room.resourceType,
1198
- resourceId: room.resourceId,
1199
- scopeKey: room.scopeKey,
1200
- scopeId: room.scopeId,
1201
- contextResourceIdentifiers: room.ownerContexts.get(ownerKey) ?? room.contextResourceIdentifiers,
1202
- })));
1203
- void Promise.all(roomsToRelease.map((room) => releaseResourceRoom(room)));
1238
+ releasePreviousOrganizationRooms();
1204
1239
  }, [releaseResourceRoom]);
1205
1240
  /**
1206
1241
  * Start editing a resource (acquire lock)