@vertesia/ui 0.79.0 → 0.79.2

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 (307) hide show
  1. package/lib/esm/core/components/Panel.js +8 -0
  2. package/lib/esm/core/components/Panel.js.map +1 -0
  3. package/lib/esm/core/components/SelectBox.js +1 -1
  4. package/lib/esm/core/components/SelectBox.js.map +1 -1
  5. package/lib/esm/core/components/SidePanel.js +2 -2
  6. package/lib/esm/core/components/SidePanel.js.map +1 -1
  7. package/lib/esm/core/components/TagsInput.js +194 -0
  8. package/lib/esm/core/components/TagsInput.js.map +1 -0
  9. package/lib/esm/core/components/index.js +2 -1
  10. package/lib/esm/core/components/index.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/breadcrumb.js +29 -8
  12. package/lib/esm/core/components/shadcn/breadcrumb.js.map +1 -1
  13. package/lib/esm/core/components/shadcn/button.js +3 -2
  14. package/lib/esm/core/components/shadcn/button.js.map +1 -1
  15. package/lib/esm/core/components/shadcn/filters/filterBar.js +2 -2
  16. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  17. package/lib/esm/core/components/shadcn/index.js +1 -0
  18. package/lib/esm/core/components/shadcn/index.js.map +1 -1
  19. package/lib/esm/core/components/shadcn/input.js +4 -1
  20. package/lib/esm/core/components/shadcn/input.js.map +1 -1
  21. package/lib/esm/core/components/shadcn/popover.js +1 -1
  22. package/lib/esm/core/components/shadcn/popover.js.map +1 -1
  23. package/lib/esm/core/components/shadcn/resizeable.js +2 -2
  24. package/lib/esm/core/components/shadcn/resizeable.js.map +1 -1
  25. package/lib/esm/core/components/shadcn/selectBox.js +15 -9
  26. package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
  27. package/lib/esm/core/components/shadcn/tabs.js +10 -3
  28. package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
  29. package/lib/esm/core/components/shadcn/textarea.js +7 -0
  30. package/lib/esm/core/components/shadcn/textarea.js.map +1 -0
  31. package/lib/esm/core/hooks/CompositeState.js +139 -1
  32. package/lib/esm/core/hooks/CompositeState.js.map +1 -1
  33. package/lib/esm/core/hooks/index.js +1 -0
  34. package/lib/esm/core/hooks/index.js.map +1 -1
  35. package/lib/esm/core/hooks/useScrollableSearch.js +92 -0
  36. package/lib/esm/core/hooks/useScrollableSearch.js.map +1 -0
  37. package/lib/esm/env/index.js +2 -2
  38. package/lib/esm/env/index.js.map +1 -1
  39. package/lib/esm/features/agent/PayloadBuilder.js +80 -55
  40. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  41. package/lib/esm/features/agent/chat/ModernAgentConversation.js +22 -24
  42. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  43. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -3
  44. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  45. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +2 -2
  46. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  47. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +15 -20
  48. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
  49. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js +1 -0
  50. package/lib/esm/features/agent/chat/ModernAgentOutput/PlanPanel.js.map +1 -1
  51. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js +3 -3
  52. package/lib/esm/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.js.map +1 -1
  53. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +6 -6
  54. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  55. package/lib/esm/features/facets/CollectionsFacetsNav.js +19 -0
  56. package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -1
  57. package/lib/esm/features/facets/InteractionsFacetsNav.js +9 -3
  58. package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -1
  59. package/lib/esm/features/facets/utils/VTypeFacet.js +4 -1
  60. package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -1
  61. package/lib/esm/features/layout/GenericPageNavHeader.js +58 -5
  62. package/lib/esm/features/layout/GenericPageNavHeader.js.map +1 -1
  63. package/lib/esm/features/store/collections/BrowseCollectionView.js +3 -0
  64. package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
  65. package/lib/esm/features/store/collections/CreateCollection.js +2 -2
  66. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
  67. package/lib/esm/features/store/collections/EditCollectionView.js +39 -29
  68. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  69. package/lib/esm/features/store/collections/SelectCollection.js +82 -16
  70. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
  71. package/lib/esm/features/store/collections/SharedPropsEditor.js +40 -0
  72. package/lib/esm/features/store/collections/SharedPropsEditor.js.map +1 -0
  73. package/lib/esm/features/store/collections/SyncMemberHeadsToggle.js +35 -0
  74. package/lib/esm/features/store/collections/SyncMemberHeadsToggle.js.map +1 -0
  75. package/lib/esm/features/store/collections/index.js +2 -0
  76. package/lib/esm/features/store/collections/index.js.map +1 -1
  77. package/lib/esm/features/store/objects/DocumentSearchResults.js +35 -9
  78. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  79. package/lib/esm/features/store/objects/DocumentTable.js +6 -6
  80. package/lib/esm/features/store/objects/DocumentTable.js.map +1 -1
  81. package/lib/esm/features/store/objects/components/ContentOverview.js +158 -114
  82. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  83. package/lib/esm/features/store/objects/components/DocumentIcon.js +5 -3
  84. package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
  85. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js +11 -2
  86. package/lib/esm/features/store/objects/components/SaveVersionConfirmModal.js.map +1 -1
  87. package/lib/esm/features/store/objects/components/useDownloadObject.js +2 -2
  88. package/lib/esm/features/store/objects/components/useDownloadObject.js.map +1 -1
  89. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js +13 -1
  90. package/lib/esm/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
  91. package/lib/esm/features/store/objects/layout/documentLayout.js +5 -5
  92. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  93. package/lib/esm/features/store/objects/layout/renderers.js +28 -12
  94. package/lib/esm/features/store/objects/layout/renderers.js.map +1 -1
  95. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +5 -1
  96. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  97. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js +1 -1
  98. package/lib/esm/features/store/objects/search/DocumentSearchProvider.js.map +1 -1
  99. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js +3 -2
  100. package/lib/esm/features/store/objects/selection/ObjectsActionContext.js.map +1 -1
  101. package/lib/esm/features/store/objects/selection/SelectionActions.js +2 -0
  102. package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
  103. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +10 -2
  104. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  105. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js +20 -2
  106. package/lib/esm/features/store/objects/selection/actions/DeleteObjectsAction.js.map +1 -1
  107. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +15 -7
  108. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  109. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js +10 -9
  110. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
  111. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js +1 -1
  112. package/lib/esm/features/store/types/CreateOrUpdateTypeModal.js.map +1 -1
  113. package/lib/esm/features/user/UserInfo.js +2 -0
  114. package/lib/esm/features/user/UserInfo.js.map +1 -1
  115. package/lib/esm/router/HistoryNavigator.js +25 -2
  116. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  117. package/lib/esm/router/Nav.js +3 -3
  118. package/lib/esm/router/Nav.js.map +1 -1
  119. package/lib/esm/session/UserSession.js +1 -0
  120. package/lib/esm/session/UserSession.js.map +1 -1
  121. package/lib/esm/session/UserSessionProvider.js +9 -2
  122. package/lib/esm/session/UserSessionProvider.js.map +1 -1
  123. package/lib/esm/session/auth/composable.js +66 -67
  124. package/lib/esm/session/auth/composable.js.map +1 -1
  125. package/lib/esm/shell/apps/AppProjectSelector.js +2 -2
  126. package/lib/esm/shell/apps/AppProjectSelector.js.map +1 -1
  127. package/lib/esm/widgets/form/Form.js +17 -30
  128. package/lib/esm/widgets/form/Form.js.map +1 -1
  129. package/lib/esm/widgets/form/FormContext.js +4 -2
  130. package/lib/esm/widgets/form/FormContext.js.map +1 -1
  131. package/lib/esm/widgets/form/ManagedObject.js +4 -0
  132. package/lib/esm/widgets/form/ManagedObject.js.map +1 -1
  133. package/lib/esm/widgets/form/fields.js +4 -3
  134. package/lib/esm/widgets/form/fields.js.map +1 -1
  135. package/lib/esm/widgets/form/inputs.js +2 -0
  136. package/lib/esm/widgets/form/inputs.js.map +1 -1
  137. package/lib/tsconfig.tsbuildinfo +1 -1
  138. package/lib/types/core/components/Panel.d.ts +11 -0
  139. package/lib/types/core/components/Panel.d.ts.map +1 -0
  140. package/lib/types/core/components/SidePanel.d.ts.map +1 -1
  141. package/lib/types/core/components/TagsInput.d.ts +16 -0
  142. package/lib/types/core/components/TagsInput.d.ts.map +1 -0
  143. package/lib/types/core/components/index.d.ts +2 -1
  144. package/lib/types/core/components/index.d.ts.map +1 -1
  145. package/lib/types/core/components/shadcn/breadcrumb.d.ts +3 -2
  146. package/lib/types/core/components/shadcn/breadcrumb.d.ts.map +1 -1
  147. package/lib/types/core/components/shadcn/button.d.ts.map +1 -1
  148. package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  149. package/lib/types/core/components/shadcn/index.d.ts +1 -0
  150. package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
  151. package/lib/types/core/components/shadcn/input.d.ts.map +1 -1
  152. package/lib/types/core/components/shadcn/popover.d.ts +7 -0
  153. package/lib/types/core/components/shadcn/popover.d.ts.map +1 -1
  154. package/lib/types/core/components/shadcn/selectBox.d.ts +3 -2
  155. package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
  156. package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
  157. package/lib/types/core/components/shadcn/textarea.d.ts +4 -0
  158. package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -0
  159. package/lib/types/core/hooks/CompositeState.d.ts +115 -6
  160. package/lib/types/core/hooks/CompositeState.d.ts.map +1 -1
  161. package/lib/types/core/hooks/index.d.ts +1 -0
  162. package/lib/types/core/hooks/index.d.ts.map +1 -1
  163. package/lib/types/core/hooks/useScrollableSearch.d.ts +82 -0
  164. package/lib/types/core/hooks/useScrollableSearch.d.ts.map +1 -0
  165. package/lib/types/env/index.d.ts +3 -1
  166. package/lib/types/env/index.d.ts.map +1 -1
  167. package/lib/types/features/agent/PayloadBuilder.d.ts +11 -19
  168. package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
  169. package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  170. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +1 -1
  171. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  172. package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  173. package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
  174. package/lib/types/features/agent/chat/ModernAgentOutput/PlanPanel.d.ts.map +1 -1
  175. package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
  176. package/lib/types/features/facets/InteractionsFacetsNav.d.ts +1 -0
  177. package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  178. package/lib/types/features/facets/utils/SearchInterface.d.ts +6 -1
  179. package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -1
  180. package/lib/types/features/facets/utils/VTypeFacet.d.ts +2 -1
  181. package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -1
  182. package/lib/types/features/layout/GenericPageNavHeader.d.ts +2 -1
  183. package/lib/types/features/layout/GenericPageNavHeader.d.ts.map +1 -1
  184. package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
  185. package/lib/types/features/store/collections/CreateCollection.d.ts.map +1 -1
  186. package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
  187. package/lib/types/features/store/collections/SelectCollection.d.ts +6 -3
  188. package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
  189. package/lib/types/features/store/collections/SharedPropsEditor.d.ts +7 -0
  190. package/lib/types/features/store/collections/SharedPropsEditor.d.ts.map +1 -0
  191. package/lib/types/features/store/collections/SyncMemberHeadsToggle.d.ts +7 -0
  192. package/lib/types/features/store/collections/SyncMemberHeadsToggle.d.ts.map +1 -0
  193. package/lib/types/features/store/collections/index.d.ts +2 -0
  194. package/lib/types/features/store/collections/index.d.ts.map +1 -1
  195. package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  196. package/lib/types/features/store/objects/DocumentTable.d.ts +4 -0
  197. package/lib/types/features/store/objects/DocumentTable.d.ts.map +1 -1
  198. package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  199. package/lib/types/features/store/objects/components/DocumentIcon.d.ts +3 -1
  200. package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
  201. package/lib/types/features/store/objects/components/SaveVersionConfirmModal.d.ts.map +1 -1
  202. package/lib/types/features/store/objects/components/useDownloadObject.d.ts +1 -1
  203. package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +1 -1
  204. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts +2 -1
  205. package/lib/types/features/store/objects/layout/DocumentTableColumn.d.ts.map +1 -1
  206. package/lib/types/features/store/objects/layout/documentLayout.d.ts +4 -2
  207. package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
  208. package/lib/types/features/store/objects/layout/renderers.d.ts +1 -1
  209. package/lib/types/features/store/objects/layout/renderers.d.ts.map +1 -1
  210. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -0
  211. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  212. package/lib/types/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
  213. package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
  214. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts +1 -0
  215. package/lib/types/features/store/objects/selection/actions/DeleteObjectsAction.d.ts.map +1 -1
  216. package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  217. package/lib/types/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
  218. package/lib/types/features/user/UserInfo.d.ts.map +1 -1
  219. package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
  220. package/lib/types/router/Nav.d.ts +2 -1
  221. package/lib/types/router/Nav.d.ts.map +1 -1
  222. package/lib/types/session/UserSession.d.ts.map +1 -1
  223. package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
  224. package/lib/types/session/auth/composable.d.ts.map +1 -1
  225. package/lib/types/widgets/form/Form.d.ts +2 -1
  226. package/lib/types/widgets/form/Form.d.ts.map +1 -1
  227. package/lib/types/widgets/form/FormContext.d.ts +5 -2
  228. package/lib/types/widgets/form/FormContext.d.ts.map +1 -1
  229. package/lib/types/widgets/form/ManagedObject.d.ts.map +1 -1
  230. package/lib/types/widgets/form/fields.d.ts +2 -2
  231. package/lib/types/widgets/form/fields.d.ts.map +1 -1
  232. package/lib/types/widgets/form/inputs.d.ts.map +1 -1
  233. package/lib/vertesia-ui-core.js +1 -1
  234. package/lib/vertesia-ui-core.js.map +1 -1
  235. package/lib/vertesia-ui-env.js +1 -1
  236. package/lib/vertesia-ui-env.js.map +1 -1
  237. package/lib/vertesia-ui-features.js +1 -1
  238. package/lib/vertesia-ui-features.js.map +1 -1
  239. package/lib/vertesia-ui-router.js +1 -1
  240. package/lib/vertesia-ui-router.js.map +1 -1
  241. package/lib/vertesia-ui-session.js +1 -1
  242. package/lib/vertesia-ui-session.js.map +1 -1
  243. package/lib/vertesia-ui-shell.js +1 -1
  244. package/lib/vertesia-ui-shell.js.map +1 -1
  245. package/lib/vertesia-ui-widgets.js +1 -1
  246. package/lib/vertesia-ui-widgets.js.map +1 -1
  247. package/package.json +4 -4
  248. package/src/core/components/Panel.tsx +34 -0
  249. package/src/core/components/SidePanel.tsx +5 -3
  250. package/src/core/components/index.ts +1 -1
  251. package/src/core/components/shadcn/breadcrumb.tsx +49 -30
  252. package/src/core/components/shadcn/button.tsx +3 -2
  253. package/src/core/components/shadcn/filters/filterBar.tsx +3 -3
  254. package/src/core/components/shadcn/index.ts +2 -1
  255. package/src/core/components/shadcn/input.tsx +10 -7
  256. package/src/core/components/shadcn/resizeable.tsx +4 -4
  257. package/src/core/components/shadcn/selectBox.tsx +87 -67
  258. package/src/core/components/shadcn/tabs.tsx +10 -3
  259. package/src/core/components/shadcn/textarea.tsx +21 -0
  260. package/src/core/hooks/index.ts +1 -0
  261. package/src/core/hooks/useScrollableSearch.tsx +193 -0
  262. package/src/env/index.ts +1 -1
  263. package/src/features/agent/chat/ModernAgentConversation.tsx +109 -118
  264. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -22
  265. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +1 -9
  266. package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +39 -55
  267. package/src/features/agent/chat/ModernAgentOutput/PlanPanel.tsx +1 -0
  268. package/src/features/agent/chat/ModernAgentOutput/SlidingPlanPanel.tsx +8 -8
  269. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +8 -8
  270. package/src/features/facets/CollectionsFacetsNav.tsx +21 -0
  271. package/src/features/facets/InteractionsFacetsNav.tsx +13 -3
  272. package/src/features/facets/utils/SearchInterface.tsx +5 -1
  273. package/src/features/facets/utils/VTypeFacet.tsx +6 -2
  274. package/src/features/layout/GenericPageNavHeader.tsx +73 -10
  275. package/src/features/store/collections/BrowseCollectionView.tsx +4 -0
  276. package/src/features/store/collections/CreateCollection.tsx +3 -4
  277. package/src/features/store/collections/EditCollectionView.tsx +91 -85
  278. package/src/features/store/collections/SelectCollection.tsx +105 -49
  279. package/src/features/store/objects/DocumentSearchResults.tsx +117 -51
  280. package/src/features/store/objects/DocumentTable.tsx +14 -4
  281. package/src/features/store/objects/components/ContentOverview.tsx +208 -110
  282. package/src/features/store/objects/components/DocumentIcon.tsx +11 -12
  283. package/src/features/store/objects/components/SaveVersionConfirmModal.tsx +12 -2
  284. package/src/features/store/objects/layout/DocumentTableColumn.tsx +16 -1
  285. package/src/features/store/objects/layout/documentLayout.tsx +7 -5
  286. package/src/features/store/objects/layout/knowledge.md +10 -10
  287. package/src/features/store/objects/layout/renderers.tsx +39 -18
  288. package/src/features/store/objects/search/DocumentSearchContext.ts +6 -1
  289. package/src/features/store/objects/search/DocumentSearchProvider.tsx +1 -1
  290. package/src/features/store/objects/selection/ObjectsActionContext.tsx +3 -2
  291. package/src/features/store/objects/selection/SelectionActions.tsx +2 -0
  292. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +8 -2
  293. package/src/features/store/objects/selection/actions/DeleteObjectsAction.tsx +22 -2
  294. package/src/features/store/objects/upload/DocumentUploadModal.tsx +18 -9
  295. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +11 -10
  296. package/src/features/store/types/CreateOrUpdateTypeModal.tsx +1 -1
  297. package/src/router/HistoryNavigator.ts +33 -2
  298. package/src/router/Nav.tsx +4 -3
  299. package/src/widgets/form/Form.tsx +19 -43
  300. package/src/widgets/form/FormContext.ts +5 -2
  301. package/src/widgets/form/fields.tsx +8 -6
  302. package/src/widgets/form/inputs.tsx +1 -0
  303. package/lib/esm/core/components/Textarea.js +0 -15
  304. package/lib/esm/core/components/Textarea.js.map +0 -1
  305. package/lib/types/core/components/Textarea.d.ts +0 -8
  306. package/lib/types/core/components/Textarea.d.ts.map +0 -1
  307. package/src/core/components/Textarea.tsx +0 -25
@@ -1,2 +1,2 @@
1
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import{useRef as n,useEffect as a,createContext as r,useContext as i,useState as s,useMemo as o}from"react";import{useSafeLayoutEffect as h}from"@vertesia/ui/core";function c(t){return"/"===t||""===t}function l(t,e){return e=t.endsWith("/")&&e.startsWith("/")?t+e.substring(1):t.endsWith("/")||e.startsWith("/")?t+e:t+"/"+e}function u(t){if(""===t)return[];if("/"===t)return[""];let e=0,n=t.length;return t.startsWith("./")?e=2:t.startsWith("/")&&(e=1),t.endsWith("/")&&(n=t.length-1),(e>0||n<t.length?t.substring(e,n):t).split("/")}function d(t){if("string"==typeof t)return u(t);if(Array.isArray(t))return t;throw new Error(`Unsupported path object: ${t}`)}var m=Object.freeze({__proto__:null,getPathSegments:u,isRootPath:c,joinPath:l,toSegments:d});class p{path;params;hash;constructor(t){let e=t.lastIndexOf("#");e>-1?(this.hash=t.substring(e),t=t.substring(0,e)):this.hash="",e=t.indexOf("?"),e>-1?(this.path=t.substring(0,e),this.params=new URLSearchParams(t.substring(e+1))):(this.path=t,this.params=new URLSearchParams)}add(t){for(const[e,n]of Object.entries(t))this.params.set(e,n);return this}toString(){return this.path+"?"+this.params.toString()+this.hash}}const f=Symbol("BASE_PATH");class g{name;type;location;state;_canceled=!1;constructor(t,e,n,a){this.name=t,this.type=e,this.location=n,this.state=a}get isPageLoad(){return"initial"===this.type}get isBackForward(){return"popState"===this.type}get isLinkClick(){return"linkClick"===this.type}get isNavigation(){return"navigate"===this.type}get isCancelable(){return"beforeChange"===this.name}cancel(){if("afterChange"===this.name)throw new Error("Cannot cancel afterChange event");this._canceled=!0}}class w extends g{constructor(t,e,n){super("beforeChange",t,e,n)}}class v extends g{constructor(t,e,n){super("afterChange",t,e,n)}}class P{stickyParams;_popStateListener;_linkNavListener;_listeners=[];constructor(){}addListener(t){this._listeners.push(t)}fireLocationChange(t){for(const e of this._listeners)e(t)}firePageLoad(){this.fireLocationChange(new v("initial",new URL(window.location.href)))}addStickyParams(t){return this.stickyParams?new p(t).add(this.stickyParams).toString():t}navigate(t,e={}){if(e.basePath){let n=e.basePath;n.startsWith("/")||(n="/"+n),t=l(n,t)}t=this.addStickyParams(t),this._navigate(new URL(t,window.location.href),"navigate",e)}_navigate(t,e,n){const a=new w(e,t,n.state);this.fireLocationChange(a),a._canceled||(window.history[n.replace?"replaceState":"pushState"]({from:window.location.href,data:n.state||void 0},"",t.href),this.fireLocationChange(new v(e,t,n.state)))}start(){if("undefined"==typeof window)return;const t=t=>{let e=t.state?"popState":"linkClick";const n=new URL(window.location.href);let a;t.state?(e="popState",a=t.state.data):e="linkClick",this.fireLocationChange(new v(e,n,a))};this._popStateListener=t,this._linkNavListener=t=>{const e=function(t){if(t&&"a"===t.tagName.toLowerCase()){const e=t?.href.trim();if("string"==typeof e&&e.length>0)return new URL(e)}return null}(t.target);if(e&&e.origin===window.location.origin){t.preventDefault();const n=new URL(this.addStickyParams(e.href)),a=t[f]||t.target[f];a&&(n.pathname=l(a,n.pathname)),this._navigate(n,"linkClick",{})}},window.addEventListener("popstate",t),document.body.addEventListener("click",this._linkNavListener)}stop(){this._popStateListener&&window.removeEventListener("popstate",this._popStateListener),this._linkNavListener&&document.body.removeEventListener("click",this._linkNavListener)}}function b({basePath:e,children:r}){const i=n(null);return a((()=>{if(i.current){const t=i.current,n=t=>{"a"===t.target.tagName.toLowerCase()&&(t[f]=e)};return t.addEventListener("click",n),()=>{t.removeEventListener("click",n)}}}),[i.current]),t("div",{ref:i,className:"h-full w-full",children:r})}class L{tree=new S;loadMapping(t){for(const[e,n]of Object.entries(t))this.addSegments(u(e),n)}addPath(t,e){this.addSegments(u(t),e)}addSegments(t,e){let n=this.tree;for(let a=0,r=t.length;a<r;a++){const i=t[a];if(":"===i[0]){let e=n.wildcard;if(e){if(!(e instanceof C))throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard ":" segment will overwrite an existing wildcard segment at path: ${"/"+t.slice(0,a).join("/")}`)}else e=new C(i),n.wildcard=e;n=e}else{if("*"===i){if(n.wildcard)throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard "*" segment already exists at path: ${"/"+t.slice(0,a).join("/")}`);if(n.wildcard=new _(i,e),a<r-1)throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard segment must be the last segment`);return}{let t=n.children[i];t||(t=new y(i),n.children[i]=t),n=t}}}if(void 0!==n.value)throw new Error(`Failed to index path segments: ${t.join("/")}. A value already exists at path: ${"/"+t.join("/")}`);n.value=e}match(t){const e=d(t);if(0===e.length)return null;const n={};let a,r,i=this.tree;for(const t of e){const e=i.match(t,n);if(!e)return null;i=e}if(!i.value){if(i instanceof k&&i.wildcard instanceof _&&(i=i.wildcard.match("",n),!i.value))throw new Error("Wildcard segment node `*` must have a value");if(!i.value)return null}return n._&&n._.length>0?(a=e.slice(0,-n._.length),r=n._):a=e,{params:n,matchedSegments:a,remainingSegments:r,value:i.value}}}class k{name;value;children={};wildcard;constructor(t,e){this.name=t,this.value=e}match(t,e){let n=this.children[t];if(n)return n;if(this.wildcard){if(this.wildcard instanceof _)return this.wildcard.match(t,e);if(this.wildcard instanceof C)return e[this.wildcard.paramName]=t,this.wildcard;throw new Error("Unknown wildcard segment node type: "+this.wildcard.constructor.name)}return null}}class S extends k{constructor(){super("#root")}}class y extends k{constructor(t,e){super(t,e)}}class C extends k{paramName;constructor(t,e){super(t,e),this.paramName=t.substring(1)}}class _{name;value;constructor(t,e){this.name=t,this.value=e}match(t,e){return e._?t&&e._.push(t):e._=t?[t]:[],this}}class x{index;matcher=new L;constructor(t,e){this.index=e;for(const e of t)this.matcher.addPath(e.path,e)}match(t){const e=c(t)&&this.index;return this.matcher.match(e?this.index:t)}}class R extends x{prompt;observer;navigator=new P;constructor(t,e){super(t),this.navigator.addListener((t=>{if((!(t.isCancelable&&this.prompt&&this.prompt.when)||window.confirm(this.prompt.message))&&(this.observer&&this.observer(t),"afterChange"===t.name)){const n=this.match(t.location.pathname);n&&n.value?e({...n,state:t.state}):e(null)}}))}getTopRouter(){return this}setStickyParams(t){this.navigator.stickyParams=null!=t?t:void 0}withObserver(t){return this.observer=t,this}start(){this.navigator.start(),this.navigator.firePageLoad()}stop(){this.navigator.stop()}navigate(t,e){this.navigator.navigate(t,e)}}class E extends x{parent;basePath;constructor(t,e,n){super(n),this.parent=t,this.basePath=e}getTopRouter(){return this.parent instanceof R?this.parent:this.parent.getTopRouter()}navigate(t,e){let n;if(e?.isBasePathNested??!0){const t=e?.basePath;n=t?l(this.basePath,t):this.basePath}else n=e?.basePath??this.basePath;this.parent.navigate(t,{...e,basePath:n})}}const j=r(void 0);function N(){const t=i(j);if(!t)throw new Error("useRouter must be used within a RouterProvider");return t}function $(){const{navigate:t}=N();return t}function U(t){const{params:e}=N();return t?e[t]:e}function W(){const{location:t}=N();return t}function A(t){const{router:e}=N();a((()=>(e.getTopRouter().prompt=t,()=>{e.getTopRouter().prompt=void 0})),[]),a((()=>{if(t.when){const e=t.when,n=function(t){e&&(t.preventDefault(),t.returnValue="")};return window.addEventListener("beforeunload",n),()=>{window.removeEventListener("beforeunload",n)}}}),[t.when])}function O({children:e,onClick:n}){const a=$();return t("span",{onClick:t=>{const e=t.target.closest("a");e&&e.href&&(t.stopPropagation(),t.preventDefault(),a(e.href),n?.(t))},children:e})}function T({children:e,href:n,className:a,topLevelNav:r}){const{router:i}=N();return t("a",{href:n,className:a,onClick:t=>{t.stopPropagation(),t.preventDefault();(r?i.getTopRouter():i).navigate(n)},children:e})}function z({spinner:e}){const n=N(),a=n.route;if(a.Component){const e=a.Component;return t(e,{...n.params})}if(a.LazyComponent)return t(F,{route:a,spinner:e});throw new Error(`Invalid route for ${a.path}. Either Component or LazyCOmponent must be specified.`)}function F({route:e,spinner:n}){const[r,i]=s(null);return a((()=>{e.LazyComponent().then((t=>{if(!t.default)throw new Error(`Lazy module for ${e.path} does not have a default export`);i((()=>t.default))}))}),[e]),r?t(r,{}):n||null}function D({basePath:e,fixLinks:n=!1,children:a}){const r=N(),i=n?e=>t(b,{basePath:r.matchedRoutePath,children:e}):t=>t;return t(j.Provider,{value:{...r,navigate:(t,n)=>{const a=n?.basePath?l(e,n.basePath):e;return r.navigate(t,{...n,basePath:a})}},children:i(a||t(z,{}))})}function B(){const t=N();return e("div",{children:["Route not found for path ",t.matchedRoutePath]})}function I(){return{params:{},matchedSegments:[],state:null,value:{path:"virtual:404",Component:()=>t(B,{})}}}function H({routes:e,index:n,children:r,fixLinks:i=!1}){const h=N(),[c,l]=s(void 0),u=o((()=>{if("undefined"==typeof window)return null;const t=h.matchedRoutePath,a=new E(h.router,t,e);return a.index=n,a}),[]);a((()=>{if(u){if(h.matchedRoutePath!==u.basePath)return;const t=u.match(h.remainingPath||"/")||I();l(t)}}),[u,h.remainingPath]);const d=i?e=>t(b,{basePath:h.matchedRoutePath,children:e}):t=>t;return c&&t(j.Provider,{value:{...h,router:u,route:c.value,params:c.params,matchedRoutePath:"/"+c.matchedSegments.join("/"),remainingPath:c.remainingSegments?"/"+c.remainingSegments.join("/"):void 0,navigate:(t,e)=>u.navigate(t,e)},children:d(r||t(z,{}))})}function M({routes:e,index:n,onChange:a,children:r}){const[i,c]=s(void 0),l=o((()=>{if("undefined"==typeof window)return null;const t=new R(e,(e=>{null===e&&(e=I()),c({location:window.location,route:e.value,params:e.params,state:e.state,router:t,matchedRoutePath:"/"+e.matchedSegments.join("/"),remainingPath:e.remainingSegments?"/"+e.remainingSegments.join("/"):void 0,navigate:(e,n)=>t.navigate(e,n)})})).withObserver(a);return t.index=n,t}),[]);return h((()=>(l&&l.start(),()=>{l&&l.stop()})),[]),i&&t(j.Provider,{value:i,children:r||t(z,{})})}export{v as AfterLocationChangeEvent,f as BASE_PATH,x as BaseRouter,w as BeforeLocationChangeEvent,b as FixLinks,P as HistoryNavigator,g as LocationChangeEvent,O as Nav,T as NavLink,D as NestedNavigationContext,E as NestedRouter,H as NestedRouterProvider,m as Path,L as PathMatcher,j as ReactRouterContext,z as RouteComponent,R as Router,M as RouterProvider,W as useLocation,$ as useNavigate,A as useNavigationPrompt,U as useParams,N as useRouterContext};
1
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import{useRef as n,useEffect as a,createContext as r,useContext as i,useState as s,useMemo as o}from"react";import{useSafeLayoutEffect as h}from"@vertesia/ui/core";function c(t){return"/"===t||""===t}function l(t,e){return e=t.endsWith("/")&&e.startsWith("/")?t+e.substring(1):t.endsWith("/")||e.startsWith("/")?t+e:t+"/"+e}function u(t){if(""===t)return[];if("/"===t)return[""];let e=0,n=t.length;return t.startsWith("./")?e=2:t.startsWith("/")&&(e=1),t.endsWith("/")&&(n=t.length-1),(e>0||n<t.length?t.substring(e,n):t).split("/")}function d(t){if("string"==typeof t)return u(t);if(Array.isArray(t))return t;throw new Error(`Unsupported path object: ${t}`)}var m=Object.freeze({__proto__:null,getPathSegments:u,isRootPath:c,joinPath:l,toSegments:d});class p{path;params;hash;constructor(t){let e=t.lastIndexOf("#");e>-1?(this.hash=t.substring(e),t=t.substring(0,e)):this.hash="",e=t.indexOf("?"),e>-1?(this.path=t.substring(0,e),this.params=new URLSearchParams(t.substring(e+1))):(this.path=t,this.params=new URLSearchParams)}add(t){for(const[e,n]of Object.entries(t))this.params.set(e,n);return this}toString(){return this.path+"?"+this.params.toString()+this.hash}}const f=Symbol("BASE_PATH");class g{name;type;location;state;_canceled=!1;constructor(t,e,n,a){this.name=t,this.type=e,this.location=n,this.state=a}get isPageLoad(){return"initial"===this.type}get isBackForward(){return"popState"===this.type}get isLinkClick(){return"linkClick"===this.type}get isNavigation(){return"navigate"===this.type}get isCancelable(){return"beforeChange"===this.name}cancel(){if("afterChange"===this.name)throw new Error("Cannot cancel afterChange event");this._canceled=!0}}class w extends g{constructor(t,e,n){super("beforeChange",t,e,n)}}class v extends g{constructor(t,e,n){super("afterChange",t,e,n)}}class P{stickyParams;_popStateListener;_linkNavListener;_listeners=[];constructor(){}addListener(t){this._listeners.push(t)}fireLocationChange(t){for(const e of this._listeners)e(t)}firePageLoad(){this.fireLocationChange(new v("initial",new URL(window.location.href)))}addStickyParams(t){return this.stickyParams?new p(t).add(this.stickyParams).toString():t}navigate(t,e={}){if(e.basePath){let n=e.basePath;n.startsWith("/")||(n="/"+n),t=l(n,t)}t=this.addStickyParams(t),this._navigate(new URL(t,window.location.href),"navigate",e)}_navigate(t,e,n){const a=new w(e,t,n.state);if(this.fireLocationChange(a),a._canceled)return;const r=window.history.state,i={title:document.title,href:window.location.pathname+window.location.search+window.location.hash};let s=[];!n.replace&&r?.historyChain&&(s=[...r.historyChain]),n.replace||(s.push(i),s.length>10&&(s=s.slice(-10)));const o={from:window.location.href,historyChain:s,data:n.state||void 0};window.history[n.replace?"replaceState":"pushState"](o,"",t.href),this.fireLocationChange(new v(e,t,n.state))}start(){if("undefined"==typeof window)return;const t=t=>{let e=t.state?"popState":"linkClick";const n=new URL(window.location.href);let a;t.state?(e="popState",a=t.state.data):e="linkClick",this.fireLocationChange(new v(e,n,a))};this._popStateListener=t,this._linkNavListener=t=>{const e=function(t){if(t&&"a"===t.tagName.toLowerCase()){const e=t?.href.trim();if("string"==typeof e&&e.length>0)return new URL(e)}return null}(t.target);if(e&&e.origin===window.location.origin){t.preventDefault();const n=new URL(this.addStickyParams(e.href)),a=t[f]||t.target[f];a&&(n.pathname=l(a,n.pathname)),this._navigate(n,"linkClick",{})}},window.addEventListener("popstate",t),document.body.addEventListener("click",this._linkNavListener)}stop(){this._popStateListener&&window.removeEventListener("popstate",this._popStateListener),this._linkNavListener&&document.body.removeEventListener("click",this._linkNavListener)}}function b({basePath:e,children:r}){const i=n(null);return a((()=>{if(i.current){const t=i.current,n=t=>{"a"===t.target.tagName.toLowerCase()&&(t[f]=e)};return t.addEventListener("click",n),()=>{t.removeEventListener("click",n)}}}),[i.current]),t("div",{ref:i,className:"h-full w-full",children:r})}class L{tree=new C;loadMapping(t){for(const[e,n]of Object.entries(t))this.addSegments(u(e),n)}addPath(t,e){this.addSegments(u(t),e)}addSegments(t,e){let n=this.tree;for(let a=0,r=t.length;a<r;a++){const i=t[a];if(":"===i[0]){let e=n.wildcard;if(e){if(!(e instanceof S))throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard ":" segment will overwrite an existing wildcard segment at path: ${"/"+t.slice(0,a).join("/")}`)}else e=new S(i),n.wildcard=e;n=e}else{if("*"===i){if(n.wildcard)throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard "*" segment already exists at path: ${"/"+t.slice(0,a).join("/")}`);if(n.wildcard=new _(i,e),a<r-1)throw new Error(`Failed to index path segments: ${t.join("/")}. A wildcard segment must be the last segment`);return}{let t=n.children[i];t||(t=new k(i),n.children[i]=t),n=t}}}if(void 0!==n.value)throw new Error(`Failed to index path segments: ${t.join("/")}. A value already exists at path: ${"/"+t.join("/")}`);n.value=e}match(t){const e=d(t);if(0===e.length)return null;const n={};let a,r,i=this.tree;for(const t of e){const e=i.match(t,n);if(!e)return null;i=e}if(!i.value){if(i instanceof y&&i.wildcard instanceof _&&(i=i.wildcard.match("",n),!i.value))throw new Error("Wildcard segment node `*` must have a value");if(!i.value)return null}return n._&&n._.length>0?(a=e.slice(0,-n._.length),r=n._):a=e,{params:n,matchedSegments:a,remainingSegments:r,value:i.value}}}class y{name;value;children={};wildcard;constructor(t,e){this.name=t,this.value=e}match(t,e){let n=this.children[t];if(n)return n;if(this.wildcard){if(this.wildcard instanceof _)return this.wildcard.match(t,e);if(this.wildcard instanceof S)return e[this.wildcard.paramName]=t,this.wildcard;throw new Error("Unknown wildcard segment node type: "+this.wildcard.constructor.name)}return null}}class C extends y{constructor(){super("#root")}}class k extends y{constructor(t,e){super(t,e)}}class S extends y{paramName;constructor(t,e){super(t,e),this.paramName=t.substring(1)}}class _{name;value;constructor(t,e){this.name=t,this.value=e}match(t,e){return e._?t&&e._.push(t):e._=t?[t]:[],this}}class x{index;matcher=new L;constructor(t,e){this.index=e;for(const e of t)this.matcher.addPath(e.path,e)}match(t){const e=c(t)&&this.index;return this.matcher.match(e?this.index:t)}}class R extends x{prompt;observer;navigator=new P;constructor(t,e){super(t),this.navigator.addListener((t=>{if((!(t.isCancelable&&this.prompt&&this.prompt.when)||window.confirm(this.prompt.message))&&(this.observer&&this.observer(t),"afterChange"===t.name)){const n=this.match(t.location.pathname);n&&n.value?e({...n,state:t.state}):e(null)}}))}getTopRouter(){return this}setStickyParams(t){this.navigator.stickyParams=null!=t?t:void 0}withObserver(t){return this.observer=t,this}start(){this.navigator.start(),this.navigator.firePageLoad()}stop(){this.navigator.stop()}navigate(t,e){this.navigator.navigate(t,e)}}class E extends x{parent;basePath;constructor(t,e,n){super(n),this.parent=t,this.basePath=e}getTopRouter(){return this.parent instanceof R?this.parent:this.parent.getTopRouter()}navigate(t,e){let n;if(e?.isBasePathNested??!0){const t=e?.basePath;n=t?l(this.basePath,t):this.basePath}else n=e?.basePath??this.basePath;this.parent.navigate(t,{...e,basePath:n})}}const j=r(void 0);function N(){const t=i(j);if(!t)throw new Error("useRouter must be used within a RouterProvider");return t}function $(){const{navigate:t}=N();return t}function U(t){const{params:e}=N();return t?e[t]:e}function W(){const{location:t}=N();return t}function A(t){const{router:e}=N();a((()=>(e.getTopRouter().prompt=t,()=>{e.getTopRouter().prompt=void 0})),[]),a((()=>{if(t.when){const e=t.when,n=function(t){e&&(t.preventDefault(),t.returnValue="")};return window.addEventListener("beforeunload",n),()=>{window.removeEventListener("beforeunload",n)}}}),[t.when])}function O({children:e,onClick:n}){const a=$();return t("span",{onClick:t=>{const e=t.target.closest("a");e&&e.href&&(t.stopPropagation(),t.preventDefault(),a(e.href,{replace:!0}),n?.(t))},children:e})}function T({children:e,href:n,className:a,topLevelNav:r,clearBreadcrumbs:i=!1}){const{router:s}=N();return t("a",{href:n,className:a,onClick:t=>{t.stopPropagation(),t.preventDefault();(r?s.getTopRouter():s).navigate(n,{replace:i})},children:e})}function z({spinner:e}){const n=N(),a=n.route;if(a.Component){const e=a.Component;return t(e,{...n.params})}if(a.LazyComponent)return t(F,{route:a,spinner:e});throw new Error(`Invalid route for ${a.path}. Either Component or LazyCOmponent must be specified.`)}function F({route:e,spinner:n}){const[r,i]=s(null);return a((()=>{e.LazyComponent().then((t=>{if(!t.default)throw new Error(`Lazy module for ${e.path} does not have a default export`);i((()=>t.default))}))}),[e]),r?t(r,{}):n||null}function B({basePath:e,fixLinks:n=!1,children:a}){const r=N(),i=n?e=>t(b,{basePath:r.matchedRoutePath,children:e}):t=>t;return t(j.Provider,{value:{...r,navigate:(t,n)=>{const a=n?.basePath?l(e,n.basePath):e;return r.navigate(t,{...n,basePath:a})}},children:i(a||t(z,{}))})}function D(){const t=N();return e("div",{children:["Route not found for path ",t.matchedRoutePath]})}function I(){return{params:{},matchedSegments:[],state:null,value:{path:"virtual:404",Component:()=>t(D,{})}}}function H({routes:e,index:n,children:r,fixLinks:i=!1}){const h=N(),[c,l]=s(void 0),u=o((()=>{if("undefined"==typeof window)return null;const t=h.matchedRoutePath,a=new E(h.router,t,e);return a.index=n,a}),[]);a((()=>{if(u){if(h.matchedRoutePath!==u.basePath)return;const t=u.match(h.remainingPath||"/")||I();l(t)}}),[u,h.remainingPath]);const d=i?e=>t(b,{basePath:h.matchedRoutePath,children:e}):t=>t;return c&&t(j.Provider,{value:{...h,router:u,route:c.value,params:c.params,matchedRoutePath:"/"+c.matchedSegments.join("/"),remainingPath:c.remainingSegments?"/"+c.remainingSegments.join("/"):void 0,navigate:(t,e)=>u.navigate(t,e)},children:d(r||t(z,{}))})}function M({routes:e,index:n,onChange:a,children:r}){const[i,c]=s(void 0),l=o((()=>{if("undefined"==typeof window)return null;const t=new R(e,(e=>{null===e&&(e=I()),c({location:window.location,route:e.value,params:e.params,state:e.state,router:t,matchedRoutePath:"/"+e.matchedSegments.join("/"),remainingPath:e.remainingSegments?"/"+e.remainingSegments.join("/"):void 0,navigate:(e,n)=>t.navigate(e,n)})})).withObserver(a);return t.index=n,t}),[]);return h((()=>(l&&l.start(),()=>{l&&l.stop()})),[]),i&&t(j.Provider,{value:i,children:r||t(z,{})})}export{v as AfterLocationChangeEvent,f as BASE_PATH,x as BaseRouter,w as BeforeLocationChangeEvent,b as FixLinks,P as HistoryNavigator,g as LocationChangeEvent,O as Nav,T as NavLink,B as NestedNavigationContext,E as NestedRouter,H as NestedRouterProvider,m as Path,L as PathMatcher,j as ReactRouterContext,z as RouteComponent,R as Router,M as RouterProvider,W as useLocation,$ as useNavigate,A as useNavigationPrompt,U as useParams,N as useRouterContext};
2
2
  //# sourceMappingURL=vertesia-ui-router.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vertesia-ui-router.js","sources":["esm/router/path.js","esm/router/PathWithParams.js","esm/router/HistoryNavigator.js","esm/router/FixLinks.js","esm/router/PathMatcher.js","esm/router/Router.js","esm/router/Nav.js","esm/router/RouteComponent.js","esm/router/NestedNavigationContext.js","esm/router/Route404.js","esm/router/NestedRouterProvider.js","esm/router/RouterProvider.js"],"sourcesContent":["export function isRootPath(path) {\n return path === '/' || path === '';\n}\nexport function joinPath(path1, path2) {\n if (path1.endsWith('/') && path2.startsWith('/')) {\n path2 = path1 + path2.substring(1);\n }\n else if (path1.endsWith('/')) {\n path2 = path1 + path2;\n }\n else if (path2.startsWith('/')) {\n path2 = path1 + path2;\n }\n else {\n path2 = path1 + '/' + path2;\n }\n return path2;\n}\nexport function getPathSegments(path) {\n if (path === '') {\n return [];\n }\n if (path === '/') {\n return [''];\n }\n let s = 0, e = path.length;\n if (path.startsWith('./')) {\n s = 2;\n }\n else if (path.startsWith('/')) {\n s = 1;\n }\n if (path.endsWith('/')) {\n e = path.length - 1;\n }\n return (s > 0 || e < path.length ? path.substring(s, e) : path).split('/');\n}\nexport function toSegments(path) {\n if (typeof path === 'string') {\n return getPathSegments(path);\n }\n else if (Array.isArray(path)) {\n return path;\n }\n else {\n throw new Error(`Unsupported path object: ${path}`);\n }\n}\n// export class Path {\n// static parse(path: string, abs = false) {\n// if (abs !== undefined) {\n// abs = path.startsWith('/');\n// }\n// return new Path(getPathSegments(path), abs);\n// }\n// constructor(public segments: string[], public isAbsolute = false) {\n// }\n// getParameters() {\n// const out = [];\n// for (const segment of this.segments) {\n// if (segment[0] === ':') {\n// out.push(segment.substring(1));\n// }\n// }\n// if (this.segments[this.segments.length - 1] === '*') {\n// out.push('_');\n// }\n// return out;\n// }\n// resolveParameters(path: string) {\n// const params: PathMatchParams = {};\n// const resolvedSegments = getPathSegments(path);\n// if (resolvedSegments.length < this.segments.length) {\n// return null;\n// }\n// const segments = this.segments;\n// for (let i = 0, l = segments.length; i < l; i++) {\n// const seg = segments[i];\n// if (seg[0] === ':') {\n// params[seg.substring(1)] = resolvedSegments[i];\n// }\n// }\n// if (resolvedSegments.length - this.segments.length) {\n// params._ = resolvedSegments.slice(this.segments.length);\n// }\n// return params;\n// }\n// match(path: string | string[] | Path) {\n// const segments = toSegments(path);\n// if (segments.length < this.segments.length) {\n// return false;\n// }\n// let params: PathMatchParams | undefined;\n// const mySegments = this.segments;\n// for (let i = 0, l = mySegments.length; i < l; i++) {\n// const segment = mySegments[i];\n// if (segment === ':') {\n// if (!params) params = {};\n// params[segment.substring(1)] = segment;\n// } else if (segment !== segments[i]) {\n// if (i === l - 1 && segment === '*') {\n// if (!params) params = {};\n// params._ = segments.slice(i);\n// return params;\n// }\n// return false;\n// }\n// }\n// return params ? params : false;\n// }\n// join(path: Path | string | string[]) {\n// const segments = toSegments(path);\n// return new Path(this.segments.concat(segments), this.isAbsolute);\n// }\n// getRelativePath(path: Path | string | string[], asAbsolute: boolean = false) {\n// const segments = toSegments(path);\n// const extraSegmentsCount = segments.length - this.segments.length;\n// if (extraSegmentsCount <= 0) {\n// return null;\n// }\n// return new Path(segments.slice(this.segments.length), asAbsolute);\n// }\n// prependSegments(segments: string[]) {\n// this.segments = segments.concat(this.segments);\n// }\n// appendSegments(segments: string[]) {\n// this.segments = this.segments.concat(segments);\n// }\n// toAbsolutePath() {\n// return '/' + this.segments.join('/');\n// }\n// toRelativePath() {\n// return this.segments.join('/');\n// }\n// toString() {\n// const path = this.segments.join('/');\n// return this.isAbsolute ? '/' + path : path;\n// }\n// }\n//# sourceMappingURL=path.js.map","export class PathWithParams {\n path;\n params;\n hash;\n constructor(path) {\n let i = path.lastIndexOf('#');\n if (i > -1) {\n this.hash = path.substring(i);\n path = path.substring(0, i);\n }\n else {\n this.hash = '';\n }\n i = path.indexOf('?');\n if (i > -1) {\n this.path = path.substring(0, i);\n this.params = new URLSearchParams(path.substring(i + 1));\n }\n else {\n this.path = path;\n this.params = new URLSearchParams();\n }\n }\n add(params) {\n for (const [key, value] of Object.entries(params)) {\n this.params.set(key, value);\n }\n return this;\n }\n toString() {\n return this.path + '?' + this.params.toString() + this.hash;\n }\n}\n//# sourceMappingURL=PathWithParams.js.map","import { joinPath } from \"./path\";\nimport { PathWithParams } from \"./PathWithParams\";\nconst BASE_PATH = Symbol('BASE_PATH');\nexport { BASE_PATH };\nexport class LocationChangeEvent {\n name;\n type;\n location;\n state;\n _canceled = false;\n constructor(name, type, location, state) {\n this.name = name;\n this.type = type;\n this.location = location;\n this.state = state;\n }\n get isPageLoad() {\n return this.type === 'initial';\n }\n get isBackForward() {\n return this.type === 'popState';\n }\n get isLinkClick() {\n return this.type === 'linkClick';\n }\n get isNavigation() {\n return this.type === 'navigate';\n }\n get isCancelable() {\n return this.name === 'beforeChange';\n }\n cancel() {\n if (this.name === 'afterChange') {\n throw new Error('Cannot cancel afterChange event');\n }\n this._canceled = true;\n }\n}\nexport class BeforeLocationChangeEvent extends LocationChangeEvent {\n constructor(type, location, state) {\n super('beforeChange', type, location, state);\n }\n}\nexport class AfterLocationChangeEvent extends LocationChangeEvent {\n constructor(type, location, state) {\n super('afterChange', type, location, state);\n }\n}\nfunction getElementHrefAsUrl(elem) {\n if (elem && elem.tagName.toLowerCase() === 'a') {\n const href = elem?.href.trim();\n if (typeof href === 'string' && href.length > 0) {\n return new URL(href);\n }\n }\n return null;\n}\nexport class HistoryNavigator {\n // params to preserve in the query string when navigating\n stickyParams;\n _popStateListener;\n _linkNavListener;\n _listeners = [];\n constructor() {\n }\n addListener(listener) {\n this._listeners.push(listener);\n }\n fireLocationChange(event) {\n for (const listener of this._listeners) {\n listener(event);\n }\n }\n /**\n * Should be called when the page is first loaded.\n * It will fire a location change event with type `initial` and the current window.location as the location\n */\n firePageLoad() {\n this.fireLocationChange(new AfterLocationChangeEvent('initial', new URL(window.location.href)));\n }\n addStickyParams(path) {\n if (this.stickyParams) {\n return new PathWithParams(path).add(this.stickyParams).toString();\n }\n return path;\n }\n navigate(to, options = {}) {\n if (options.basePath) {\n let basePath = options.basePath;\n if (!basePath.startsWith('/')) {\n basePath = '/' + basePath;\n }\n to = joinPath(basePath, to);\n }\n to = this.addStickyParams(to);\n this._navigate(new URL(to, window.location.href), 'navigate', options);\n }\n _navigate(to, type, options) {\n const beforeEvent = new BeforeLocationChangeEvent(type, to, options.state);\n this.fireLocationChange(beforeEvent);\n if (beforeEvent._canceled) {\n return;\n }\n window.history[options.replace ? 'replaceState' : 'pushState']({\n from: window.location.href,\n data: options.state || undefined\n }, '', to.href);\n this.fireLocationChange(new AfterLocationChangeEvent(type, to, options.state));\n }\n start() {\n if (typeof window === \"undefined\") {\n return;\n }\n const _popStateListener = (ev) => {\n let type = ev.state ? 'popState' : 'linkClick';\n const to = new URL(window.location.href);\n let state = undefined;\n if (ev.state) {\n type = 'popState';\n state = ev.state.data;\n }\n else {\n type = 'linkClick';\n }\n this.fireLocationChange(new AfterLocationChangeEvent(type, to, state));\n };\n const _linkNavListener = (ev) => {\n const url = getElementHrefAsUrl(ev.target);\n if (url && url.origin === window.location.origin) {\n ev.preventDefault();\n const to = new URL(this.addStickyParams(url.href));\n const basePath = ev[BASE_PATH] || ev.target[BASE_PATH];\n if (basePath) {\n to.pathname = joinPath(basePath, to.pathname);\n }\n this._navigate(to, 'linkClick', {});\n }\n };\n this._popStateListener = _popStateListener;\n this._linkNavListener = _linkNavListener;\n window.addEventListener('popstate', _popStateListener);\n document.body.addEventListener('click', this._linkNavListener);\n }\n stop() {\n this._popStateListener && window.removeEventListener('popstate', this._popStateListener);\n this._linkNavListener && document.body.removeEventListener('click', this._linkNavListener);\n }\n}\n//# sourceMappingURL=HistoryNavigator.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useRef } from \"react\";\nimport { BASE_PATH } from \"./HistoryNavigator\";\nexport function FixLinks({ basePath, children }) {\n const ref = useRef(null);\n useEffect(() => {\n if (ref.current) {\n const divElem = ref.current;\n const listener = (ev) => {\n const elem = ev.target;\n if (elem.tagName.toLowerCase() === 'a') {\n ev[BASE_PATH] = basePath;\n }\n };\n divElem.addEventListener('click', listener);\n return () => {\n divElem.removeEventListener('click', listener);\n };\n }\n }, [ref.current]);\n return (_jsx(\"div\", { ref: ref, className: \"h-full w-full\", children: children }));\n}\n//# sourceMappingURL=FixLinks.js.map","import { getPathSegments, toSegments } from \"./path\";\n/**\n * Path matcher which support :param and *wildcard segments.\n * The wildcard segment is only supported as the last segment\n */\nexport class PathMatcher {\n tree = new RootSegmentNode();\n loadMapping(mapping) {\n for (const [key, value] of Object.entries(mapping)) {\n this.addSegments(getPathSegments(key), value);\n }\n }\n addPath(path, value) {\n this.addSegments(getPathSegments(path), value);\n }\n addSegments(segments, value) {\n let node = this.tree;\n for (let i = 0, l = segments.length; i < l; i++) {\n const segment = segments[i];\n if (segment[0] === ':') {\n let childNode = node.wildcard;\n if (!childNode) {\n childNode = new VariableSegmentNode(segment);\n node.wildcard = childNode;\n }\n else if (!(childNode instanceof VariableSegmentNode)) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard \":\" segment will overwrite an existing wildcard segment at path: ${'/' + segments.slice(0, i).join(\"/\")}`);\n }\n node = childNode;\n }\n else if (segment === '*') {\n if (node.wildcard) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard \"*\" segment already exists at path: ${'/' + segments.slice(0, i).join(\"/\")}`);\n }\n node.wildcard = new WildcardSegmentNode(segment, value);\n if (i < l - 1) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard segment must be the last segment`);\n }\n return;\n }\n else {\n let childNode = node.children[segment];\n if (!childNode) {\n childNode = new LiteralSegmentNode(segment);\n node.children[segment] = childNode;\n } // else // a literal segment already exists\n node = childNode;\n }\n }\n if (node.value !== undefined) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A value already exists at path: ${'/' + segments.join(\"/\")}`);\n }\n node.value = value;\n }\n match(path) {\n const segments = toSegments(path);\n if (segments.length === 0) {\n return null;\n }\n const params = {};\n let node = this.tree;\n for (const segment of segments) {\n const match = node.match(segment, params);\n if (match) {\n node = match;\n }\n else {\n return null;\n }\n }\n if (!node.value) { // not a leaf node (partial match)\n if (node instanceof ParentSegmentNode) {\n if (node.wildcard instanceof WildcardSegmentNode) {\n node = node.wildcard.match('', params);\n if (!node.value) {\n throw new Error(\"Wildcard segment node `*` must have a value\");\n }\n }\n }\n if (!node.value)\n return null; // not a leaf node, neither a trailing wildcard (partial match)\n }\n let matchedSegments, remainingSegments;\n if (params._ && params._.length > 0) {\n matchedSegments = segments.slice(0, -params._.length);\n remainingSegments = params._;\n }\n else {\n matchedSegments = segments;\n }\n return { params, matchedSegments, remainingSegments, value: node.value };\n }\n}\nclass ParentSegmentNode {\n name;\n value;\n children = {};\n wildcard;\n constructor(name, value) {\n this.name = name;\n this.value = value;\n }\n match(segment, params) {\n let node = this.children[segment];\n if (node) {\n return node;\n }\n else if (this.wildcard) {\n if (this.wildcard instanceof WildcardSegmentNode) {\n return this.wildcard.match(segment, params);\n }\n else if (this.wildcard instanceof VariableSegmentNode) {\n params[this.wildcard.paramName] = segment;\n return this.wildcard;\n }\n else {\n throw new Error(\"Unknown wildcard segment node type: \" + this.wildcard.constructor.name);\n }\n }\n else {\n return null;\n }\n }\n}\nclass RootSegmentNode extends ParentSegmentNode {\n constructor() {\n super(\"#root\");\n }\n}\nclass LiteralSegmentNode extends ParentSegmentNode {\n constructor(name, value) {\n super(name, value);\n }\n}\nclass VariableSegmentNode extends ParentSegmentNode {\n paramName;\n constructor(name, value) {\n super(name, value);\n this.paramName = name.substring(1);\n }\n}\nclass WildcardSegmentNode {\n name;\n value;\n constructor(name, value) {\n this.name = name;\n this.value = value;\n }\n match(segment, params) {\n if (!params._) {\n params._ = segment ? [segment] : [];\n }\n else {\n segment && params._.push(segment);\n }\n return this;\n }\n}\n//# sourceMappingURL=PathMatcher.js.map","import { createContext, useContext, useEffect } from \"react\";\nimport { HistoryNavigator } from \"./HistoryNavigator\";\nimport { PathMatcher } from \"./PathMatcher\";\nimport { isRootPath, joinPath } from \"./path\";\nexport class BaseRouter {\n // the path to use when navigating to the root of the router\n index;\n matcher = new PathMatcher();\n constructor(routes, index) {\n this.index = index;\n for (const route of routes) {\n this.matcher.addPath(route.path, route);\n }\n }\n match(path) {\n const useIndex = isRootPath(path) && this.index;\n return this.matcher.match(useIndex ? this.index : path);\n }\n}\nexport class Router extends BaseRouter {\n prompt;\n observer;\n navigator = new HistoryNavigator();\n constructor(routes, updateState) {\n super(routes);\n this.navigator.addListener((event) => {\n if (event.isCancelable && this.prompt && !!this.prompt.when) {\n if (!window.confirm(this.prompt.message))\n return;\n }\n if (this.observer) {\n this.observer(event);\n }\n // only process afterChange events\n if (event.name === \"afterChange\") {\n const match = this.match(event.location.pathname);\n if (match && match.value) {\n updateState({\n ...match,\n state: event.state,\n });\n }\n else {\n updateState(null);\n }\n }\n });\n }\n getTopRouter() {\n return this;\n }\n /**\n * Subsequent navigations will preserve the given params in the query string.\n * Use null to clear the sticky params.\n * @param params\n */\n setStickyParams(params) {\n this.navigator.stickyParams = params != null ? params : undefined;\n }\n withObserver(observer) {\n this.observer = observer;\n return this;\n }\n start() {\n this.navigator.start();\n // initialize with the current location\n this.navigator.firePageLoad();\n }\n stop() {\n this.navigator.stop();\n }\n navigate(path, options) {\n this.navigator.navigate(path, options);\n }\n}\nexport class NestedRouter extends BaseRouter {\n parent;\n basePath;\n constructor(parent, basePath, routes) {\n super(routes);\n this.parent = parent;\n this.basePath = basePath;\n }\n getTopRouter() {\n if (this.parent instanceof Router) {\n return this.parent;\n }\n else {\n return this.parent.getTopRouter();\n }\n }\n navigate(path, options) {\n // base path is nested by default in a NestedRouter unless explicitly set to false by caller\n const isBasePathNested = options?.isBasePathNested ?? true;\n let basePath;\n if (isBasePathNested) {\n const childBasePath = options?.basePath;\n // e.g. \"/store\" + \"/objects/123\" => \"/store/objects/123\"\n basePath = childBasePath ? joinPath(this.basePath, childBasePath) : this.basePath;\n }\n else {\n // e.g. \"/store\" + \"/studio\" => \"/studio\"\n basePath = options?.basePath ?? this.basePath;\n }\n this.parent.navigate(path, {\n ...options,\n basePath,\n });\n }\n}\nconst ReactRouterContext = createContext(undefined);\nexport { ReactRouterContext };\nexport function useRouterContext() {\n const ctx = useContext(ReactRouterContext);\n if (!ctx) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n return ctx;\n}\nexport function useNavigate() {\n const { navigate } = useRouterContext();\n return navigate;\n}\nexport function useParams(arg) {\n const { params } = useRouterContext();\n if (arg) {\n return params[arg];\n }\n else {\n return params;\n }\n}\nexport function useLocation() {\n const { location } = useRouterContext();\n return location;\n}\nexport function useNavigationPrompt(prompt) {\n const { router } = useRouterContext();\n useEffect(() => {\n router.getTopRouter().prompt = prompt;\n return () => {\n router.getTopRouter().prompt = undefined;\n };\n }, []);\n useEffect(() => {\n if (prompt.when) {\n const doBlock = prompt.when;\n const listener = function (ev) {\n if (doBlock) {\n ev.preventDefault();\n ev.returnValue = \"\";\n }\n };\n window.addEventListener(\"beforeunload\", listener);\n return () => {\n window.removeEventListener(\"beforeunload\", listener);\n };\n }\n }, [prompt.when]);\n}\n//# sourceMappingURL=Router.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useNavigate, useRouterContext } from \"./Router\";\nexport function Nav({ children, onClick }) {\n const navigate = useNavigate();\n const _onClick = (ev) => {\n const link = ev.target.closest('a');\n if (link && link.href) {\n ev.stopPropagation();\n ev.preventDefault();\n navigate(link.href);\n onClick?.(ev);\n }\n };\n return (_jsx(\"span\", { onClick: _onClick, children: children }));\n}\nexport function NavLink({ children, href, className, topLevelNav }) {\n const { router } = useRouterContext();\n const _onClick = (ev) => {\n ev.stopPropagation();\n ev.preventDefault();\n const actualRouter = topLevelNav ? router.getTopRouter() : router;\n actualRouter.navigate(href);\n };\n return (_jsx(\"a\", { href: href, className: className, onClick: _onClick, children: children }));\n}\n//# sourceMappingURL=Nav.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useState } from \"react\";\nimport { useRouterContext } from \"./Router\";\nexport function RouteComponent({ spinner }) {\n const ctx = useRouterContext();\n const route = ctx.route;\n if (route.Component) {\n const Component = route.Component;\n return _jsx(Component, { ...ctx.params });\n }\n else if (route.LazyComponent) {\n return _jsx(LazyRouteComponent, { route: route, spinner: spinner });\n }\n else {\n throw new Error(`Invalid route for ${route.path}. Either Component or LazyCOmponent must be specified.`);\n }\n}\nfunction LazyRouteComponent({ route, spinner }) {\n const [Component, setComponent] = useState(null);\n useEffect(() => {\n route.LazyComponent().then(module => {\n if (!module.default) {\n throw new Error(`Lazy module for ${route.path} does not have a default export`);\n }\n // we need to wrap the component type in an arrow function\n // otherwise the setState function will execute the function as a state update function\n setComponent(() => module.default);\n });\n }, [route]);\n return Component ? (_jsx(Component, {})) : spinner || null;\n}\n//# sourceMappingURL=RouteComponent.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { FixLinks } from \"./FixLinks\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { ReactRouterContext, useRouterContext } from \"./Router\";\nimport { joinPath } from \"./path\";\nexport function NestedNavigationContext({ basePath, fixLinks = false, children }) {\n const ctx = useRouterContext();\n const wrapWithFixLinks = fixLinks ?\n (elem) => _jsx(FixLinks, { basePath: ctx.matchedRoutePath, children: elem })\n : (elem) => elem;\n return (_jsx(ReactRouterContext.Provider, { value: {\n ...ctx,\n navigate: (to, options) => {\n const actualBasePath = options?.basePath ? joinPath(basePath, options.basePath) : basePath;\n return ctx.navigate(to, { ...options, basePath: actualBasePath });\n }\n }, children: wrapWithFixLinks(children ? children : _jsx(RouteComponent, {})) }));\n}\n//# sourceMappingURL=NestedNavigationContext.js.map","import { jsxs as _jsxs, jsx as _jsx } from \"react/jsx-runtime\";\nimport { useRouterContext } from \"./Router\";\nexport function Route404Component() {\n const ctx = useRouterContext();\n return _jsxs(\"div\", { children: [\"Route not found for path \", ctx.matchedRoutePath] });\n}\nexport function createRoute404() {\n return {\n params: {},\n matchedSegments: [],\n state: null,\n value: {\n path: 'virtual:404',\n Component: () => _jsx(Route404Component, {})\n }\n };\n}\n//# sourceMappingURL=Route404.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FixLinks } from \"./FixLinks\";\nimport { createRoute404 } from \"./Route404\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { NestedRouter, ReactRouterContext, useRouterContext } from \"./Router\";\nexport function NestedRouterProvider({ routes, index, children, fixLinks = false }) {\n const ctx = useRouterContext();\n const [nestedRouteMatch, setNestedRouteMatch] = useState(undefined);\n const nestedRouter = useMemo(() => {\n if (typeof window === 'undefined')\n return null;\n const basePath = ctx.matchedRoutePath;\n const nestedRouter = new NestedRouter(ctx.router, basePath, routes);\n nestedRouter.index = index;\n return nestedRouter;\n }, []);\n useEffect(() => {\n if (nestedRouter) {\n if (ctx.matchedRoutePath !== nestedRouter.basePath) {\n // the change doesn't belong to this nested router\n // it should be handled by the top level router which will change the page or the nested router\n return;\n }\n const route = nestedRouter.match(ctx.remainingPath || '/') || createRoute404();\n setNestedRouteMatch(route);\n }\n }, [nestedRouter, ctx.remainingPath]);\n const wrapWithFixLinks = fixLinks ?\n (elem) => _jsx(FixLinks, { basePath: ctx.matchedRoutePath, children: elem })\n : (elem) => elem;\n return nestedRouteMatch && (_jsx(ReactRouterContext.Provider, { value: {\n ...ctx,\n router: nestedRouter,\n route: nestedRouteMatch.value,\n params: nestedRouteMatch.params,\n matchedRoutePath: '/' + nestedRouteMatch.matchedSegments.join('/'),\n remainingPath: nestedRouteMatch.remainingSegments ? '/' + nestedRouteMatch.remainingSegments.join('/') : undefined,\n navigate: (to, options) => {\n return nestedRouter.navigate(to, options);\n }\n }, children: wrapWithFixLinks(children ? children : _jsx(RouteComponent, {})) }));\n}\n//# sourceMappingURL=NestedRouterProvider.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useSafeLayoutEffect } from \"@vertesia/ui/core\";\n//import { useSafeLayoutEffect } from \"../core\";\nimport { useMemo, useState } from \"react\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { ReactRouterContext, Router } from \"./Router\";\nimport { createRoute404 } from \"./Route404\";\nexport function RouterProvider({ routes, index, onChange, children }) {\n const [state, setState] = useState(undefined);\n const router = useMemo(() => {\n if (typeof window === 'undefined')\n return null;\n const router = new Router(routes, (match) => {\n if (match === null) {\n match = createRoute404();\n }\n setState({\n location: window.location,\n route: match.value,\n params: match.params,\n state: match.state,\n router: router,\n matchedRoutePath: '/' + match.matchedSegments.join('/'),\n remainingPath: match.remainingSegments ? '/' + match.remainingSegments.join('/') : undefined,\n navigate: (to, options) => {\n return router.navigate(to, options);\n }\n });\n }).withObserver(onChange);\n router.index = index;\n return router;\n }, []);\n useSafeLayoutEffect(() => {\n router && router.start();\n return () => {\n router && router.stop();\n };\n }, []);\n return state && (_jsx(ReactRouterContext.Provider, { value: state, children: children ? children : _jsx(RouteComponent, {}) }));\n}\n//# sourceMappingURL=RouterProvider.js.map"],"names":["isRootPath","path","joinPath","path1","path2","endsWith","startsWith","substring","getPathSegments","s","e","length","split","toSegments","Array","isArray","Error","PathWithParams","params","hash","constructor","i","lastIndexOf","this","indexOf","URLSearchParams","add","key","value","Object","entries","set","toString","BASE_PATH","Symbol","LocationChangeEvent","name","type","location","state","_canceled","isPageLoad","isBackForward","isLinkClick","isNavigation","isCancelable","cancel","BeforeLocationChangeEvent","super","AfterLocationChangeEvent","HistoryNavigator","stickyParams","_popStateListener","_linkNavListener","_listeners","addListener","listener","push","fireLocationChange","event","firePageLoad","URL","window","href","addStickyParams","navigate","to","options","basePath","_navigate","beforeEvent","history","replace","from","data","undefined","start","ev","url","elem","tagName","toLowerCase","trim","getElementHrefAsUrl","target","origin","preventDefault","pathname","addEventListener","document","body","stop","removeEventListener","FixLinks","children","ref","useRef","useEffect","current","divElem","_jsx","className","PathMatcher","tree","RootSegmentNode","loadMapping","mapping","addSegments","addPath","segments","node","l","segment","childNode","wildcard","VariableSegmentNode","join","slice","WildcardSegmentNode","LiteralSegmentNode","match","matchedSegments","remainingSegments","ParentSegmentNode","_","paramName","BaseRouter","index","matcher","routes","route","useIndex","Router","prompt","observer","navigator","updateState","when","confirm","message","getTopRouter","setStickyParams","withObserver","NestedRouter","parent","isBasePathNested","childBasePath","ReactRouterContext","createContext","useRouterContext","ctx","useContext","useNavigate","useParams","arg","useLocation","useNavigationPrompt","router","doBlock","returnValue","Nav","onClick","link","closest","stopPropagation","NavLink","topLevelNav","RouteComponent","spinner","Component","LazyComponent","LazyRouteComponent","setComponent","useState","then","module","default","NestedNavigationContext","fixLinks","wrapWithFixLinks","matchedRoutePath","Provider","actualBasePath","Route404Component","_jsxs","createRoute404","NestedRouterProvider","nestedRouteMatch","setNestedRouteMatch","nestedRouter","useMemo","remainingPath","RouterProvider","onChange","setState","useSafeLayoutEffect"],"mappings":"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"}
1
+ {"version":3,"file":"vertesia-ui-router.js","sources":["esm/router/path.js","esm/router/PathWithParams.js","esm/router/HistoryNavigator.js","esm/router/FixLinks.js","esm/router/PathMatcher.js","esm/router/Router.js","esm/router/Nav.js","esm/router/RouteComponent.js","esm/router/NestedNavigationContext.js","esm/router/Route404.js","esm/router/NestedRouterProvider.js","esm/router/RouterProvider.js"],"sourcesContent":["export function isRootPath(path) {\n return path === '/' || path === '';\n}\nexport function joinPath(path1, path2) {\n if (path1.endsWith('/') && path2.startsWith('/')) {\n path2 = path1 + path2.substring(1);\n }\n else if (path1.endsWith('/')) {\n path2 = path1 + path2;\n }\n else if (path2.startsWith('/')) {\n path2 = path1 + path2;\n }\n else {\n path2 = path1 + '/' + path2;\n }\n return path2;\n}\nexport function getPathSegments(path) {\n if (path === '') {\n return [];\n }\n if (path === '/') {\n return [''];\n }\n let s = 0, e = path.length;\n if (path.startsWith('./')) {\n s = 2;\n }\n else if (path.startsWith('/')) {\n s = 1;\n }\n if (path.endsWith('/')) {\n e = path.length - 1;\n }\n return (s > 0 || e < path.length ? path.substring(s, e) : path).split('/');\n}\nexport function toSegments(path) {\n if (typeof path === 'string') {\n return getPathSegments(path);\n }\n else if (Array.isArray(path)) {\n return path;\n }\n else {\n throw new Error(`Unsupported path object: ${path}`);\n }\n}\n// export class Path {\n// static parse(path: string, abs = false) {\n// if (abs !== undefined) {\n// abs = path.startsWith('/');\n// }\n// return new Path(getPathSegments(path), abs);\n// }\n// constructor(public segments: string[], public isAbsolute = false) {\n// }\n// getParameters() {\n// const out = [];\n// for (const segment of this.segments) {\n// if (segment[0] === ':') {\n// out.push(segment.substring(1));\n// }\n// }\n// if (this.segments[this.segments.length - 1] === '*') {\n// out.push('_');\n// }\n// return out;\n// }\n// resolveParameters(path: string) {\n// const params: PathMatchParams = {};\n// const resolvedSegments = getPathSegments(path);\n// if (resolvedSegments.length < this.segments.length) {\n// return null;\n// }\n// const segments = this.segments;\n// for (let i = 0, l = segments.length; i < l; i++) {\n// const seg = segments[i];\n// if (seg[0] === ':') {\n// params[seg.substring(1)] = resolvedSegments[i];\n// }\n// }\n// if (resolvedSegments.length - this.segments.length) {\n// params._ = resolvedSegments.slice(this.segments.length);\n// }\n// return params;\n// }\n// match(path: string | string[] | Path) {\n// const segments = toSegments(path);\n// if (segments.length < this.segments.length) {\n// return false;\n// }\n// let params: PathMatchParams | undefined;\n// const mySegments = this.segments;\n// for (let i = 0, l = mySegments.length; i < l; i++) {\n// const segment = mySegments[i];\n// if (segment === ':') {\n// if (!params) params = {};\n// params[segment.substring(1)] = segment;\n// } else if (segment !== segments[i]) {\n// if (i === l - 1 && segment === '*') {\n// if (!params) params = {};\n// params._ = segments.slice(i);\n// return params;\n// }\n// return false;\n// }\n// }\n// return params ? params : false;\n// }\n// join(path: Path | string | string[]) {\n// const segments = toSegments(path);\n// return new Path(this.segments.concat(segments), this.isAbsolute);\n// }\n// getRelativePath(path: Path | string | string[], asAbsolute: boolean = false) {\n// const segments = toSegments(path);\n// const extraSegmentsCount = segments.length - this.segments.length;\n// if (extraSegmentsCount <= 0) {\n// return null;\n// }\n// return new Path(segments.slice(this.segments.length), asAbsolute);\n// }\n// prependSegments(segments: string[]) {\n// this.segments = segments.concat(this.segments);\n// }\n// appendSegments(segments: string[]) {\n// this.segments = this.segments.concat(segments);\n// }\n// toAbsolutePath() {\n// return '/' + this.segments.join('/');\n// }\n// toRelativePath() {\n// return this.segments.join('/');\n// }\n// toString() {\n// const path = this.segments.join('/');\n// return this.isAbsolute ? '/' + path : path;\n// }\n// }\n//# sourceMappingURL=path.js.map","export class PathWithParams {\n path;\n params;\n hash;\n constructor(path) {\n let i = path.lastIndexOf('#');\n if (i > -1) {\n this.hash = path.substring(i);\n path = path.substring(0, i);\n }\n else {\n this.hash = '';\n }\n i = path.indexOf('?');\n if (i > -1) {\n this.path = path.substring(0, i);\n this.params = new URLSearchParams(path.substring(i + 1));\n }\n else {\n this.path = path;\n this.params = new URLSearchParams();\n }\n }\n add(params) {\n for (const [key, value] of Object.entries(params)) {\n this.params.set(key, value);\n }\n return this;\n }\n toString() {\n return this.path + '?' + this.params.toString() + this.hash;\n }\n}\n//# sourceMappingURL=PathWithParams.js.map","import { joinPath } from \"./path\";\nimport { PathWithParams } from \"./PathWithParams\";\nconst BASE_PATH = Symbol('BASE_PATH');\nexport { BASE_PATH };\nexport class LocationChangeEvent {\n name;\n type;\n location;\n state;\n _canceled = false;\n constructor(name, type, location, state) {\n this.name = name;\n this.type = type;\n this.location = location;\n this.state = state;\n }\n get isPageLoad() {\n return this.type === 'initial';\n }\n get isBackForward() {\n return this.type === 'popState';\n }\n get isLinkClick() {\n return this.type === 'linkClick';\n }\n get isNavigation() {\n return this.type === 'navigate';\n }\n get isCancelable() {\n return this.name === 'beforeChange';\n }\n cancel() {\n if (this.name === 'afterChange') {\n throw new Error('Cannot cancel afterChange event');\n }\n this._canceled = true;\n }\n}\nexport class BeforeLocationChangeEvent extends LocationChangeEvent {\n constructor(type, location, state) {\n super('beforeChange', type, location, state);\n }\n}\nexport class AfterLocationChangeEvent extends LocationChangeEvent {\n constructor(type, location, state) {\n super('afterChange', type, location, state);\n }\n}\nfunction getElementHrefAsUrl(elem) {\n if (elem && elem.tagName.toLowerCase() === 'a') {\n const href = elem?.href.trim();\n if (typeof href === 'string' && href.length > 0) {\n return new URL(href);\n }\n }\n return null;\n}\nexport class HistoryNavigator {\n // params to preserve in the query string when navigating\n stickyParams;\n _popStateListener;\n _linkNavListener;\n _listeners = [];\n constructor() {\n }\n addListener(listener) {\n this._listeners.push(listener);\n }\n fireLocationChange(event) {\n for (const listener of this._listeners) {\n listener(event);\n }\n }\n /**\n * Should be called when the page is first loaded.\n * It will fire a location change event with type `initial` and the current window.location as the location\n */\n firePageLoad() {\n this.fireLocationChange(new AfterLocationChangeEvent('initial', new URL(window.location.href)));\n }\n addStickyParams(path) {\n if (this.stickyParams) {\n return new PathWithParams(path).add(this.stickyParams).toString();\n }\n return path;\n }\n navigate(to, options = {}) {\n if (options.basePath) {\n let basePath = options.basePath;\n if (!basePath.startsWith('/')) {\n basePath = '/' + basePath;\n }\n to = joinPath(basePath, to);\n }\n to = this.addStickyParams(to);\n this._navigate(new URL(to, window.location.href), 'navigate', options);\n }\n _navigate(to, type, options) {\n const beforeEvent = new BeforeLocationChangeEvent(type, to, options.state);\n this.fireLocationChange(beforeEvent);\n if (beforeEvent._canceled) {\n return;\n }\n // Build navigation chain by preserving previous history\n const currentState = window.history.state;\n const currentTitle = document.title;\n // Create new history chain entry\n const newChainEntry = {\n title: currentTitle,\n href: window.location.pathname + window.location.search + window.location.hash\n };\n // Build the history chain - clear if using replace\n let historyChain = [];\n if (!options.replace && currentState?.historyChain) {\n historyChain = [...currentState.historyChain];\n }\n // Only add to chain if not replacing\n if (!options.replace) {\n historyChain.push(newChainEntry);\n // Limit chain length to prevent memory issues (keep last 10 entries)\n if (historyChain.length > 10) {\n historyChain = historyChain.slice(-10);\n }\n }\n const stateToStore = {\n from: window.location.href,\n historyChain: historyChain,\n data: options.state || undefined\n };\n window.history[options.replace ? 'replaceState' : 'pushState'](stateToStore, '', to.href);\n this.fireLocationChange(new AfterLocationChangeEvent(type, to, options.state));\n }\n start() {\n if (typeof window === \"undefined\") {\n return;\n }\n const _popStateListener = (ev) => {\n let type = ev.state ? 'popState' : 'linkClick';\n const to = new URL(window.location.href);\n let state = undefined;\n if (ev.state) {\n type = 'popState';\n state = ev.state.data;\n }\n else {\n type = 'linkClick';\n }\n this.fireLocationChange(new AfterLocationChangeEvent(type, to, state));\n };\n const _linkNavListener = (ev) => {\n const url = getElementHrefAsUrl(ev.target);\n if (url && url.origin === window.location.origin) {\n ev.preventDefault();\n const to = new URL(this.addStickyParams(url.href));\n const basePath = ev[BASE_PATH] || ev.target[BASE_PATH];\n if (basePath) {\n to.pathname = joinPath(basePath, to.pathname);\n }\n this._navigate(to, 'linkClick', {});\n }\n };\n this._popStateListener = _popStateListener;\n this._linkNavListener = _linkNavListener;\n window.addEventListener('popstate', _popStateListener);\n document.body.addEventListener('click', this._linkNavListener);\n }\n stop() {\n this._popStateListener && window.removeEventListener('popstate', this._popStateListener);\n this._linkNavListener && document.body.removeEventListener('click', this._linkNavListener);\n }\n}\n//# sourceMappingURL=HistoryNavigator.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useRef } from \"react\";\nimport { BASE_PATH } from \"./HistoryNavigator\";\nexport function FixLinks({ basePath, children }) {\n const ref = useRef(null);\n useEffect(() => {\n if (ref.current) {\n const divElem = ref.current;\n const listener = (ev) => {\n const elem = ev.target;\n if (elem.tagName.toLowerCase() === 'a') {\n ev[BASE_PATH] = basePath;\n }\n };\n divElem.addEventListener('click', listener);\n return () => {\n divElem.removeEventListener('click', listener);\n };\n }\n }, [ref.current]);\n return (_jsx(\"div\", { ref: ref, className: \"h-full w-full\", children: children }));\n}\n//# sourceMappingURL=FixLinks.js.map","import { getPathSegments, toSegments } from \"./path\";\n/**\n * Path matcher which support :param and *wildcard segments.\n * The wildcard segment is only supported as the last segment\n */\nexport class PathMatcher {\n tree = new RootSegmentNode();\n loadMapping(mapping) {\n for (const [key, value] of Object.entries(mapping)) {\n this.addSegments(getPathSegments(key), value);\n }\n }\n addPath(path, value) {\n this.addSegments(getPathSegments(path), value);\n }\n addSegments(segments, value) {\n let node = this.tree;\n for (let i = 0, l = segments.length; i < l; i++) {\n const segment = segments[i];\n if (segment[0] === ':') {\n let childNode = node.wildcard;\n if (!childNode) {\n childNode = new VariableSegmentNode(segment);\n node.wildcard = childNode;\n }\n else if (!(childNode instanceof VariableSegmentNode)) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard \":\" segment will overwrite an existing wildcard segment at path: ${'/' + segments.slice(0, i).join(\"/\")}`);\n }\n node = childNode;\n }\n else if (segment === '*') {\n if (node.wildcard) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard \"*\" segment already exists at path: ${'/' + segments.slice(0, i).join(\"/\")}`);\n }\n node.wildcard = new WildcardSegmentNode(segment, value);\n if (i < l - 1) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A wildcard segment must be the last segment`);\n }\n return;\n }\n else {\n let childNode = node.children[segment];\n if (!childNode) {\n childNode = new LiteralSegmentNode(segment);\n node.children[segment] = childNode;\n } // else // a literal segment already exists\n node = childNode;\n }\n }\n if (node.value !== undefined) {\n throw new Error(`Failed to index path segments: ${segments.join('/')}. A value already exists at path: ${'/' + segments.join(\"/\")}`);\n }\n node.value = value;\n }\n match(path) {\n const segments = toSegments(path);\n if (segments.length === 0) {\n return null;\n }\n const params = {};\n let node = this.tree;\n for (const segment of segments) {\n const match = node.match(segment, params);\n if (match) {\n node = match;\n }\n else {\n return null;\n }\n }\n if (!node.value) { // not a leaf node (partial match)\n if (node instanceof ParentSegmentNode) {\n if (node.wildcard instanceof WildcardSegmentNode) {\n node = node.wildcard.match('', params);\n if (!node.value) {\n throw new Error(\"Wildcard segment node `*` must have a value\");\n }\n }\n }\n if (!node.value)\n return null; // not a leaf node, neither a trailing wildcard (partial match)\n }\n let matchedSegments, remainingSegments;\n if (params._ && params._.length > 0) {\n matchedSegments = segments.slice(0, -params._.length);\n remainingSegments = params._;\n }\n else {\n matchedSegments = segments;\n }\n return { params, matchedSegments, remainingSegments, value: node.value };\n }\n}\nclass ParentSegmentNode {\n name;\n value;\n children = {};\n wildcard;\n constructor(name, value) {\n this.name = name;\n this.value = value;\n }\n match(segment, params) {\n let node = this.children[segment];\n if (node) {\n return node;\n }\n else if (this.wildcard) {\n if (this.wildcard instanceof WildcardSegmentNode) {\n return this.wildcard.match(segment, params);\n }\n else if (this.wildcard instanceof VariableSegmentNode) {\n params[this.wildcard.paramName] = segment;\n return this.wildcard;\n }\n else {\n throw new Error(\"Unknown wildcard segment node type: \" + this.wildcard.constructor.name);\n }\n }\n else {\n return null;\n }\n }\n}\nclass RootSegmentNode extends ParentSegmentNode {\n constructor() {\n super(\"#root\");\n }\n}\nclass LiteralSegmentNode extends ParentSegmentNode {\n constructor(name, value) {\n super(name, value);\n }\n}\nclass VariableSegmentNode extends ParentSegmentNode {\n paramName;\n constructor(name, value) {\n super(name, value);\n this.paramName = name.substring(1);\n }\n}\nclass WildcardSegmentNode {\n name;\n value;\n constructor(name, value) {\n this.name = name;\n this.value = value;\n }\n match(segment, params) {\n if (!params._) {\n params._ = segment ? [segment] : [];\n }\n else {\n segment && params._.push(segment);\n }\n return this;\n }\n}\n//# sourceMappingURL=PathMatcher.js.map","import { createContext, useContext, useEffect } from \"react\";\nimport { HistoryNavigator } from \"./HistoryNavigator\";\nimport { PathMatcher } from \"./PathMatcher\";\nimport { isRootPath, joinPath } from \"./path\";\nexport class BaseRouter {\n // the path to use when navigating to the root of the router\n index;\n matcher = new PathMatcher();\n constructor(routes, index) {\n this.index = index;\n for (const route of routes) {\n this.matcher.addPath(route.path, route);\n }\n }\n match(path) {\n const useIndex = isRootPath(path) && this.index;\n return this.matcher.match(useIndex ? this.index : path);\n }\n}\nexport class Router extends BaseRouter {\n prompt;\n observer;\n navigator = new HistoryNavigator();\n constructor(routes, updateState) {\n super(routes);\n this.navigator.addListener((event) => {\n if (event.isCancelable && this.prompt && !!this.prompt.when) {\n if (!window.confirm(this.prompt.message))\n return;\n }\n if (this.observer) {\n this.observer(event);\n }\n // only process afterChange events\n if (event.name === \"afterChange\") {\n const match = this.match(event.location.pathname);\n if (match && match.value) {\n updateState({\n ...match,\n state: event.state,\n });\n }\n else {\n updateState(null);\n }\n }\n });\n }\n getTopRouter() {\n return this;\n }\n /**\n * Subsequent navigations will preserve the given params in the query string.\n * Use null to clear the sticky params.\n * @param params\n */\n setStickyParams(params) {\n this.navigator.stickyParams = params != null ? params : undefined;\n }\n withObserver(observer) {\n this.observer = observer;\n return this;\n }\n start() {\n this.navigator.start();\n // initialize with the current location\n this.navigator.firePageLoad();\n }\n stop() {\n this.navigator.stop();\n }\n navigate(path, options) {\n this.navigator.navigate(path, options);\n }\n}\nexport class NestedRouter extends BaseRouter {\n parent;\n basePath;\n constructor(parent, basePath, routes) {\n super(routes);\n this.parent = parent;\n this.basePath = basePath;\n }\n getTopRouter() {\n if (this.parent instanceof Router) {\n return this.parent;\n }\n else {\n return this.parent.getTopRouter();\n }\n }\n navigate(path, options) {\n // base path is nested by default in a NestedRouter unless explicitly set to false by caller\n const isBasePathNested = options?.isBasePathNested ?? true;\n let basePath;\n if (isBasePathNested) {\n const childBasePath = options?.basePath;\n // e.g. \"/store\" + \"/objects/123\" => \"/store/objects/123\"\n basePath = childBasePath ? joinPath(this.basePath, childBasePath) : this.basePath;\n }\n else {\n // e.g. \"/store\" + \"/studio\" => \"/studio\"\n basePath = options?.basePath ?? this.basePath;\n }\n this.parent.navigate(path, {\n ...options,\n basePath,\n });\n }\n}\nconst ReactRouterContext = createContext(undefined);\nexport { ReactRouterContext };\nexport function useRouterContext() {\n const ctx = useContext(ReactRouterContext);\n if (!ctx) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n return ctx;\n}\nexport function useNavigate() {\n const { navigate } = useRouterContext();\n return navigate;\n}\nexport function useParams(arg) {\n const { params } = useRouterContext();\n if (arg) {\n return params[arg];\n }\n else {\n return params;\n }\n}\nexport function useLocation() {\n const { location } = useRouterContext();\n return location;\n}\nexport function useNavigationPrompt(prompt) {\n const { router } = useRouterContext();\n useEffect(() => {\n router.getTopRouter().prompt = prompt;\n return () => {\n router.getTopRouter().prompt = undefined;\n };\n }, []);\n useEffect(() => {\n if (prompt.when) {\n const doBlock = prompt.when;\n const listener = function (ev) {\n if (doBlock) {\n ev.preventDefault();\n ev.returnValue = \"\";\n }\n };\n window.addEventListener(\"beforeunload\", listener);\n return () => {\n window.removeEventListener(\"beforeunload\", listener);\n };\n }\n }, [prompt.when]);\n}\n//# sourceMappingURL=Router.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useNavigate, useRouterContext } from \"./Router\";\nexport function Nav({ children, onClick }) {\n const navigate = useNavigate();\n const _onClick = (ev) => {\n const link = ev.target.closest('a');\n if (link && link.href) {\n ev.stopPropagation();\n ev.preventDefault();\n navigate(link.href, { replace: true });\n onClick?.(ev);\n }\n };\n return (_jsx(\"span\", { onClick: _onClick, children: children }));\n}\nexport function NavLink({ children, href, className, topLevelNav, clearBreadcrumbs = false }) {\n const { router } = useRouterContext();\n const _onClick = (ev) => {\n ev.stopPropagation();\n ev.preventDefault();\n const actualRouter = topLevelNav ? router.getTopRouter() : router;\n actualRouter.navigate(href, { replace: clearBreadcrumbs });\n };\n return (_jsx(\"a\", { href: href, className: className, onClick: _onClick, children: children }));\n}\n//# sourceMappingURL=Nav.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useState } from \"react\";\nimport { useRouterContext } from \"./Router\";\nexport function RouteComponent({ spinner }) {\n const ctx = useRouterContext();\n const route = ctx.route;\n if (route.Component) {\n const Component = route.Component;\n return _jsx(Component, { ...ctx.params });\n }\n else if (route.LazyComponent) {\n return _jsx(LazyRouteComponent, { route: route, spinner: spinner });\n }\n else {\n throw new Error(`Invalid route for ${route.path}. Either Component or LazyCOmponent must be specified.`);\n }\n}\nfunction LazyRouteComponent({ route, spinner }) {\n const [Component, setComponent] = useState(null);\n useEffect(() => {\n route.LazyComponent().then(module => {\n if (!module.default) {\n throw new Error(`Lazy module for ${route.path} does not have a default export`);\n }\n // we need to wrap the component type in an arrow function\n // otherwise the setState function will execute the function as a state update function\n setComponent(() => module.default);\n });\n }, [route]);\n return Component ? (_jsx(Component, {})) : spinner || null;\n}\n//# sourceMappingURL=RouteComponent.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { FixLinks } from \"./FixLinks\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { ReactRouterContext, useRouterContext } from \"./Router\";\nimport { joinPath } from \"./path\";\nexport function NestedNavigationContext({ basePath, fixLinks = false, children }) {\n const ctx = useRouterContext();\n const wrapWithFixLinks = fixLinks ?\n (elem) => _jsx(FixLinks, { basePath: ctx.matchedRoutePath, children: elem })\n : (elem) => elem;\n return (_jsx(ReactRouterContext.Provider, { value: {\n ...ctx,\n navigate: (to, options) => {\n const actualBasePath = options?.basePath ? joinPath(basePath, options.basePath) : basePath;\n return ctx.navigate(to, { ...options, basePath: actualBasePath });\n }\n }, children: wrapWithFixLinks(children ? children : _jsx(RouteComponent, {})) }));\n}\n//# sourceMappingURL=NestedNavigationContext.js.map","import { jsxs as _jsxs, jsx as _jsx } from \"react/jsx-runtime\";\nimport { useRouterContext } from \"./Router\";\nexport function Route404Component() {\n const ctx = useRouterContext();\n return _jsxs(\"div\", { children: [\"Route not found for path \", ctx.matchedRoutePath] });\n}\nexport function createRoute404() {\n return {\n params: {},\n matchedSegments: [],\n state: null,\n value: {\n path: 'virtual:404',\n Component: () => _jsx(Route404Component, {})\n }\n };\n}\n//# sourceMappingURL=Route404.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FixLinks } from \"./FixLinks\";\nimport { createRoute404 } from \"./Route404\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { NestedRouter, ReactRouterContext, useRouterContext } from \"./Router\";\nexport function NestedRouterProvider({ routes, index, children, fixLinks = false }) {\n const ctx = useRouterContext();\n const [nestedRouteMatch, setNestedRouteMatch] = useState(undefined);\n const nestedRouter = useMemo(() => {\n if (typeof window === 'undefined')\n return null;\n const basePath = ctx.matchedRoutePath;\n const nestedRouter = new NestedRouter(ctx.router, basePath, routes);\n nestedRouter.index = index;\n return nestedRouter;\n }, []);\n useEffect(() => {\n if (nestedRouter) {\n if (ctx.matchedRoutePath !== nestedRouter.basePath) {\n // the change doesn't belong to this nested router\n // it should be handled by the top level router which will change the page or the nested router\n return;\n }\n const route = nestedRouter.match(ctx.remainingPath || '/') || createRoute404();\n setNestedRouteMatch(route);\n }\n }, [nestedRouter, ctx.remainingPath]);\n const wrapWithFixLinks = fixLinks ?\n (elem) => _jsx(FixLinks, { basePath: ctx.matchedRoutePath, children: elem })\n : (elem) => elem;\n return nestedRouteMatch && (_jsx(ReactRouterContext.Provider, { value: {\n ...ctx,\n router: nestedRouter,\n route: nestedRouteMatch.value,\n params: nestedRouteMatch.params,\n matchedRoutePath: '/' + nestedRouteMatch.matchedSegments.join('/'),\n remainingPath: nestedRouteMatch.remainingSegments ? '/' + nestedRouteMatch.remainingSegments.join('/') : undefined,\n navigate: (to, options) => {\n return nestedRouter.navigate(to, options);\n }\n }, children: wrapWithFixLinks(children ? children : _jsx(RouteComponent, {})) }));\n}\n//# sourceMappingURL=NestedRouterProvider.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useSafeLayoutEffect } from \"@vertesia/ui/core\";\n//import { useSafeLayoutEffect } from \"../core\";\nimport { useMemo, useState } from \"react\";\nimport { RouteComponent } from \"./RouteComponent\";\nimport { ReactRouterContext, Router } from \"./Router\";\nimport { createRoute404 } from \"./Route404\";\nexport function RouterProvider({ routes, index, onChange, children }) {\n const [state, setState] = useState(undefined);\n const router = useMemo(() => {\n if (typeof window === 'undefined')\n return null;\n const router = new Router(routes, (match) => {\n if (match === null) {\n match = createRoute404();\n }\n setState({\n location: window.location,\n route: match.value,\n params: match.params,\n state: match.state,\n router: router,\n matchedRoutePath: '/' + match.matchedSegments.join('/'),\n remainingPath: match.remainingSegments ? '/' + match.remainingSegments.join('/') : undefined,\n navigate: (to, options) => {\n return router.navigate(to, options);\n }\n });\n }).withObserver(onChange);\n router.index = index;\n return router;\n }, []);\n useSafeLayoutEffect(() => {\n router && router.start();\n return () => {\n router && router.stop();\n };\n }, []);\n return state && (_jsx(ReactRouterContext.Provider, { value: state, children: children ? children : _jsx(RouteComponent, {}) }));\n}\n//# sourceMappingURL=RouterProvider.js.map"],"names":["isRootPath","path","joinPath","path1","path2","endsWith","startsWith","substring","getPathSegments","s","e","length","split","toSegments","Array","isArray","Error","PathWithParams","params","hash","constructor","i","lastIndexOf","this","indexOf","URLSearchParams","add","key","value","Object","entries","set","toString","BASE_PATH","Symbol","LocationChangeEvent","name","type","location","state","_canceled","isPageLoad","isBackForward","isLinkClick","isNavigation","isCancelable","cancel","BeforeLocationChangeEvent","super","AfterLocationChangeEvent","HistoryNavigator","stickyParams","_popStateListener","_linkNavListener","_listeners","addListener","listener","push","fireLocationChange","event","firePageLoad","URL","window","href","addStickyParams","navigate","to","options","basePath","_navigate","beforeEvent","currentState","history","newChainEntry","title","document","pathname","search","historyChain","replace","slice","stateToStore","from","data","undefined","start","ev","url","elem","tagName","toLowerCase","trim","getElementHrefAsUrl","target","origin","preventDefault","addEventListener","body","stop","removeEventListener","FixLinks","children","ref","useRef","useEffect","current","divElem","_jsx","className","PathMatcher","tree","RootSegmentNode","loadMapping","mapping","addSegments","addPath","segments","node","l","segment","childNode","wildcard","VariableSegmentNode","join","WildcardSegmentNode","LiteralSegmentNode","match","matchedSegments","remainingSegments","ParentSegmentNode","_","paramName","BaseRouter","index","matcher","routes","route","useIndex","Router","prompt","observer","navigator","updateState","when","confirm","message","getTopRouter","setStickyParams","withObserver","NestedRouter","parent","isBasePathNested","childBasePath","ReactRouterContext","createContext","useRouterContext","ctx","useContext","useNavigate","useParams","arg","useLocation","useNavigationPrompt","router","doBlock","returnValue","Nav","onClick","link","closest","stopPropagation","NavLink","topLevelNav","clearBreadcrumbs","RouteComponent","spinner","Component","LazyComponent","LazyRouteComponent","setComponent","useState","then","module","default","NestedNavigationContext","fixLinks","wrapWithFixLinks","matchedRoutePath","Provider","actualBasePath","Route404Component","_jsxs","createRoute404","NestedRouterProvider","nestedRouteMatch","setNestedRouteMatch","nestedRouter","useMemo","remainingPath","RouterProvider","onChange","setState","useSafeLayoutEffect"],"mappings":"sNAAO,SAASA,EAAWC,GACvB,MAAgB,MAATA,GAAyB,KAATA,CAC3B,CACO,SAASC,EAASC,EAAOC,GAa5B,OAXIA,EADAD,EAAME,SAAS,MAAQD,EAAME,WAAW,KAChCH,EAAQC,EAAMG,UAAU,GAE3BJ,EAAME,SAAS,MAGfD,EAAME,WAAW,KAFdH,EAAQC,EAMRD,EAAQ,IAAMC,CAG9B,CACO,SAASI,EAAgBP,GAC5B,GAAa,KAATA,EACA,MAAO,GAEX,GAAa,MAATA,EACA,MAAO,CAAC,IAEZ,IAAIQ,EAAI,EAAGC,EAAIT,EAAKU,OAUpB,OATIV,EAAKK,WAAW,MAChBG,EAAI,EAECR,EAAKK,WAAW,OACrBG,EAAI,GAEJR,EAAKI,SAAS,OACdK,EAAIT,EAAKU,OAAS,IAEdF,EAAI,GAAKC,EAAIT,EAAKU,OAASV,EAAKM,UAAUE,EAAGC,GAAKT,GAAMW,MAAM,IAC1E,CACO,SAASC,EAAWZ,GACvB,GAAoB,iBAATA,EACP,OAAOO,EAAgBP,GAEtB,GAAIa,MAAMC,QAAQd,GACnB,OAAOA,EAGP,MAAM,IAAIe,MAAM,4BAA4Bf,IAEpD,8FC/CO,MAAMgB,EACThB,KACAiB,OACAC,KACA,WAAAC,CAAYnB,GACR,IAAIoB,EAAIpB,EAAKqB,YAAY,KACrBD,GAAI,GACJE,KAAKJ,KAAOlB,EAAKM,UAAUc,GAC3BpB,EAAOA,EAAKM,UAAU,EAAGc,IAGzBE,KAAKJ,KAAO,GAEhBE,EAAIpB,EAAKuB,QAAQ,KACbH,GAAI,GACJE,KAAKtB,KAAOA,EAAKM,UAAU,EAAGc,GAC9BE,KAAKL,OAAS,IAAIO,gBAAgBxB,EAAKM,UAAUc,EAAI,MAGrDE,KAAKtB,KAAOA,EACZsB,KAAKL,OAAS,IAAIO,gBAE1B,CACA,GAAAC,CAAIR,GACA,IAAK,MAAOS,EAAKC,KAAUC,OAAOC,QAAQZ,GACtCK,KAAKL,OAAOa,IAAIJ,EAAKC,GAEzB,OAAOL,IACX,CACA,QAAAS,GACI,OAAOT,KAAKtB,KAAO,IAAMsB,KAAKL,OAAOc,WAAaT,KAAKJ,IAC3D,EC7BC,MAACc,EAAYC,OAAO,aAElB,MAAMC,EACTC,KACAC,KACAC,SACAC,MACAC,WAAY,EACZ,WAAApB,CAAYgB,EAAMC,EAAMC,EAAUC,GAC9BhB,KAAKa,KAAOA,EACZb,KAAKc,KAAOA,EACZd,KAAKe,SAAWA,EAChBf,KAAKgB,MAAQA,CACjB,CACA,cAAIE,GACA,MAAqB,YAAdlB,KAAKc,IAChB,CACA,iBAAIK,GACA,MAAqB,aAAdnB,KAAKc,IAChB,CACA,eAAIM,GACA,MAAqB,cAAdpB,KAAKc,IAChB,CACA,gBAAIO,GACA,MAAqB,aAAdrB,KAAKc,IAChB,CACA,gBAAIQ,GACA,MAAqB,iBAAdtB,KAAKa,IAChB,CACA,MAAAU,GACI,GAAkB,gBAAdvB,KAAKa,KACL,MAAM,IAAIpB,MAAM,mCAEpBO,KAAKiB,WAAY,CACrB,EAEG,MAAMO,UAAkCZ,EAC3C,WAAAf,CAAYiB,EAAMC,EAAUC,GACxBS,MAAM,eAAgBX,EAAMC,EAAUC,EAC1C,EAEG,MAAMU,UAAiCd,EAC1C,WAAAf,CAAYiB,EAAMC,EAAUC,GACxBS,MAAM,cAAeX,EAAMC,EAAUC,EACzC,EAWG,MAAMW,EAETC,aACAC,kBACAC,iBACAC,WAAa,GACb,WAAAlC,GACA,CACA,WAAAmC,CAAYC,GACRjC,KAAK+B,WAAWG,KAAKD,EACzB,CACA,kBAAAE,CAAmBC,GACf,IAAK,MAAMH,KAAYjC,KAAK+B,WACxBE,EAASG,EAEjB,CAKA,YAAAC,GACIrC,KAAKmC,mBAAmB,IAAIT,EAAyB,UAAW,IAAIY,IAAIC,OAAOxB,SAASyB,OAC5F,CACA,eAAAC,CAAgB/D,GACZ,OAAIsB,KAAK4B,aACE,IAAIlC,EAAehB,GAAMyB,IAAIH,KAAK4B,cAAcnB,WAEpD/B,CACX,CACA,QAAAgE,CAASC,EAAIC,EAAU,IACnB,GAAIA,EAAQC,SAAU,CAClB,IAAIA,EAAWD,EAAQC,SAClBA,EAAS9D,WAAW,OACrB8D,EAAW,IAAMA,GAErBF,EAAKhE,EAASkE,EAAUF,EAC5B,CACAA,EAAK3C,KAAKyC,gBAAgBE,GAC1B3C,KAAK8C,UAAU,IAAIR,IAAIK,EAAIJ,OAAOxB,SAASyB,MAAO,WAAYI,EAClE,CACA,SAAAE,CAAUH,EAAI7B,EAAM8B,GAChB,MAAMG,EAAc,IAAIvB,EAA0BV,EAAM6B,EAAIC,EAAQ5B,OAEpE,GADAhB,KAAKmC,mBAAmBY,GACpBA,EAAY9B,UACZ,OAGJ,MAAM+B,EAAeT,OAAOU,QAAQjC,MAG9BkC,EAAgB,CAClBC,MAHiBC,SAASD,MAI1BX,KAAMD,OAAOxB,SAASsC,SAAWd,OAAOxB,SAASuC,OAASf,OAAOxB,SAASnB,MAG9E,IAAI2D,EAAe,IACdX,EAAQY,SAAWR,GAAcO,eAClCA,EAAe,IAAIP,EAAaO,eAG/BX,EAAQY,UACTD,EAAarB,KAAKgB,GAEdK,EAAanE,OAAS,KACtBmE,EAAeA,EAAaE,aAGpC,MAAMC,EAAe,CACjBC,KAAMpB,OAAOxB,SAASyB,KACtBe,aAAcA,EACdK,KAAMhB,EAAQ5B,YAAS6C,GAE3BtB,OAAOU,QAAQL,EAAQY,QAAU,eAAiB,aAAaE,EAAc,GAAIf,EAAGH,MACpFxC,KAAKmC,mBAAmB,IAAIT,EAAyBZ,EAAM6B,EAAIC,EAAQ5B,OAC3E,CACA,KAAA8C,GACI,GAAsB,oBAAXvB,OACP,OAEJ,MAAMV,EAAqBkC,IACvB,IAAIjD,EAAOiD,EAAG/C,MAAQ,WAAa,YACnC,MAAM2B,EAAK,IAAIL,IAAIC,OAAOxB,SAASyB,MACnC,IAAIxB,EACA+C,EAAG/C,OACHF,EAAO,WACPE,EAAQ+C,EAAG/C,MAAM4C,MAGjB9C,EAAO,YAEXd,KAAKmC,mBAAmB,IAAIT,EAAyBZ,EAAM6B,EAAI3B,KAcnEhB,KAAK6B,kBAAoBA,EACzB7B,KAAK8B,iBAbqBiC,IACtB,MAAMC,EAtGlB,SAA6BC,GACzB,GAAIA,GAAuC,MAA/BA,EAAKC,QAAQC,cAAuB,CAC5C,MAAM3B,EAAOyB,GAAMzB,KAAK4B,OACxB,GAAoB,iBAAT5B,GAAqBA,EAAKpD,OAAS,EAC1C,OAAO,IAAIkD,IAAIE,EAEvB,CACA,OAAO,IACX,CA8FwB6B,CAAoBN,EAAGO,QACnC,GAAIN,GAAOA,EAAIO,SAAWhC,OAAOxB,SAASwD,OAAQ,CAC9CR,EAAGS,iBACH,MAAM7B,EAAK,IAAIL,IAAItC,KAAKyC,gBAAgBuB,EAAIxB,OACtCK,EAAWkB,EAAGrD,IAAcqD,EAAGO,OAAO5D,GACxCmC,IACAF,EAAGU,SAAW1E,EAASkE,EAAUF,EAAGU,WAExCrD,KAAK8C,UAAUH,EAAI,YAAa,CAAA,EACpC,GAIJJ,OAAOkC,iBAAiB,WAAY5C,GACpCuB,SAASsB,KAAKD,iBAAiB,QAASzE,KAAK8B,iBACjD,CACA,IAAA6C,GACI3E,KAAK6B,mBAAqBU,OAAOqC,oBAAoB,WAAY5E,KAAK6B,mBACtE7B,KAAK8B,kBAAoBsB,SAASsB,KAAKE,oBAAoB,QAAS5E,KAAK8B,iBAC7E,ECtKG,SAAS+C,GAAShC,SAAEA,EAAQiC,SAAEA,IACjC,MAAMC,EAAMC,EAAO,MAgBnB,OAfAC,GAAU,KACN,GAAIF,EAAIG,QAAS,CACb,MAAMC,EAAUJ,EAAIG,QACdjD,EAAY8B,IAEqB,MADtBA,EAAGO,OACPJ,QAAQC,gBACbJ,EAAGrD,GAAamC,IAIxB,OADAsC,EAAQV,iBAAiB,QAASxC,GAC3B,KACHkD,EAAQP,oBAAoB,QAAS3C,GAE7C,IACD,CAAC8C,EAAIG,UACAE,EAAK,MAAO,CAAEL,IAAKA,EAAKM,UAAW,gBAAiBP,SAAUA,GAC1E,CChBO,MAAMQ,EACTC,KAAO,IAAIC,EACX,WAAAC,CAAYC,GACR,IAAK,MAAOtF,EAAKC,KAAUC,OAAOC,QAAQmF,GACtC1F,KAAK2F,YAAY1G,EAAgBmB,GAAMC,EAE/C,CACA,OAAAuF,CAAQlH,EAAM2B,GACVL,KAAK2F,YAAY1G,EAAgBP,GAAO2B,EAC5C,CACA,WAAAsF,CAAYE,EAAUxF,GAClB,IAAIyF,EAAO9F,KAAKuF,KAChB,IAAK,IAAIzF,EAAI,EAAGiG,EAAIF,EAASzG,OAAQU,EAAIiG,EAAGjG,IAAK,CAC7C,MAAMkG,EAAUH,EAAS/F,GACzB,GAAmB,MAAfkG,EAAQ,GAAY,CACpB,IAAIC,EAAYH,EAAKI,SACrB,GAAKD,GAIA,KAAMA,aAAqBE,GAC5B,MAAM,IAAI1G,MAAM,kCAAkCoG,EAASO,KAAK,qFAAqF,IAAMP,EAASpC,MAAM,EAAG3D,GAAGsG,KAAK,aAJrLH,EAAY,IAAIE,EAAoBH,GACpCF,EAAKI,SAAWD,EAKpBH,EAAOG,CACX,KACK,IAAgB,MAAZD,EAAiB,CACtB,GAAIF,EAAKI,SACL,MAAM,IAAIzG,MAAM,kCAAkCoG,EAASO,KAAK,wDAAwD,IAAMP,EAASpC,MAAM,EAAG3D,GAAGsG,KAAK,QAG5J,GADAN,EAAKI,SAAW,IAAIG,EAAoBL,EAAS3F,GAC7CP,EAAIiG,EAAI,EACR,MAAM,IAAItG,MAAM,kCAAkCoG,EAASO,KAAK,qDAEpE,MACJ,CACK,CACD,IAAIH,EAAYH,EAAKhB,SAASkB,GACzBC,IACDA,EAAY,IAAIK,EAAmBN,GACnCF,EAAKhB,SAASkB,GAAWC,GAE7BH,EAAOG,CACX,EACJ,CACA,QAAmBpC,IAAfiC,EAAKzF,MACL,MAAM,IAAIZ,MAAM,kCAAkCoG,EAASO,KAAK,yCAAyC,IAAMP,EAASO,KAAK,QAEjIN,EAAKzF,MAAQA,CACjB,CACA,KAAAkG,CAAM7H,GACF,MAAMmH,EAAWvG,EAAWZ,GAC5B,GAAwB,IAApBmH,EAASzG,OACT,OAAO,KAEX,MAAMO,EAAS,CAAA,EACf,IAsBI6G,EAAiBC,EAtBjBX,EAAO9F,KAAKuF,KAChB,IAAK,MAAMS,KAAWH,EAAU,CAC5B,MAAMU,EAAQT,EAAKS,MAAMP,EAASrG,GAClC,IAAI4G,EAIA,OAAO,KAHPT,EAAOS,CAKf,CACA,IAAKT,EAAKzF,MAAO,CACb,GAAIyF,aAAgBY,GACZZ,EAAKI,oBAAoBG,IACzBP,EAAOA,EAAKI,SAASK,MAAM,GAAI5G,IAC1BmG,EAAKzF,OACN,MAAM,IAAIZ,MAAM,+CAI5B,IAAKqG,EAAKzF,MACN,OAAO,IACf,CASA,OAPIV,EAAOgH,GAAKhH,EAAOgH,EAAEvH,OAAS,GAC9BoH,EAAkBX,EAASpC,MAAM,GAAI9D,EAAOgH,EAAEvH,QAC9CqH,EAAoB9G,EAAOgH,GAG3BH,EAAkBX,EAEf,CAAElG,SAAQ6G,kBAAiBC,oBAAmBpG,MAAOyF,EAAKzF,MACrE,EAEJ,MAAMqG,EACF7F,KACAR,MACAyE,SAAW,CAAA,EACXoB,SACA,WAAArG,CAAYgB,EAAMR,GACdL,KAAKa,KAAOA,EACZb,KAAKK,MAAQA,CACjB,CACA,KAAAkG,CAAMP,EAASrG,GACX,IAAImG,EAAO9F,KAAK8E,SAASkB,GACzB,GAAIF,EACA,OAAOA,EAEN,GAAI9F,KAAKkG,SAAU,CACpB,GAAIlG,KAAKkG,oBAAoBG,EACzB,OAAOrG,KAAKkG,SAASK,MAAMP,EAASrG,GAEnC,GAAIK,KAAKkG,oBAAoBC,EAE9B,OADAxG,EAAOK,KAAKkG,SAASU,WAAaZ,EAC3BhG,KAAKkG,SAGZ,MAAM,IAAIzG,MAAM,uCAAyCO,KAAKkG,SAASrG,YAAYgB,KAE3F,CAEI,OAAO,IAEf,EAEJ,MAAM2E,UAAwBkB,EAC1B,WAAA7G,GACI4B,MAAM,QACV,EAEJ,MAAM6E,UAA2BI,EAC7B,WAAA7G,CAAYgB,EAAMR,GACdoB,MAAMZ,EAAMR,EAChB,EAEJ,MAAM8F,UAA4BO,EAC9BE,UACA,WAAA/G,CAAYgB,EAAMR,GACdoB,MAAMZ,EAAMR,GACZL,KAAK4G,UAAY/F,EAAK7B,UAAU,EACpC,EAEJ,MAAMqH,EACFxF,KACAR,MACA,WAAAR,CAAYgB,EAAMR,GACdL,KAAKa,KAAOA,EACZb,KAAKK,MAAQA,CACjB,CACA,KAAAkG,CAAMP,EAASrG,GAOX,OANKA,EAAOgH,EAIRX,GAAWrG,EAAOgH,EAAEzE,KAAK8D,GAHzBrG,EAAOgH,EAAIX,EAAU,CAACA,GAAW,GAK9BhG,IACX,ECxJG,MAAM6G,EAETC,MACAC,QAAU,IAAIzB,EACd,WAAAzF,CAAYmH,EAAQF,GAChB9G,KAAK8G,MAAQA,EACb,IAAK,MAAMG,KAASD,EAChBhH,KAAK+G,QAAQnB,QAAQqB,EAAMvI,KAAMuI,EAEzC,CACA,KAAAV,CAAM7H,GACF,MAAMwI,EAAWzI,EAAWC,IAASsB,KAAK8G,MAC1C,OAAO9G,KAAK+G,QAAQR,MAAMW,EAAWlH,KAAK8G,MAAQpI,EACtD,EAEG,MAAMyI,UAAeN,EACxBO,OACAC,SACAC,UAAY,IAAI3F,EAChB,WAAA9B,CAAYmH,EAAQO,GAChB9F,MAAMuF,GACNhH,KAAKsH,UAAUtF,aAAaI,IACxB,MAAIA,EAAMd,cAAgBtB,KAAKoH,QAAYpH,KAAKoH,OAAOI,OAC9CjF,OAAOkF,QAAQzH,KAAKoH,OAAOM,YAGhC1H,KAAKqH,UACLrH,KAAKqH,SAASjF,GAGC,gBAAfA,EAAMvB,MAAwB,CAC9B,MAAM0F,EAAQvG,KAAKuG,MAAMnE,EAAMrB,SAASsC,UACpCkD,GAASA,EAAMlG,MACfkH,EAAY,IACLhB,EACHvF,MAAOoB,EAAMpB,QAIjBuG,EAAY,KAEpB,IAER,CACA,YAAAI,GACI,OAAO3H,IACX,CAMA,eAAA4H,CAAgBjI,GACZK,KAAKsH,UAAU1F,aAAyB,MAAVjC,EAAiBA,OAASkE,CAC5D,CACA,YAAAgE,CAAaR,GAET,OADArH,KAAKqH,SAAWA,EACTrH,IACX,CACA,KAAA8D,GACI9D,KAAKsH,UAAUxD,QAEf9D,KAAKsH,UAAUjF,cACnB,CACA,IAAAsC,GACI3E,KAAKsH,UAAU3C,MACnB,CACA,QAAAjC,CAAShE,EAAMkE,GACX5C,KAAKsH,UAAU5E,SAAShE,EAAMkE,EAClC,EAEG,MAAMkF,UAAqBjB,EAC9BkB,OACAlF,SACA,WAAAhD,CAAYkI,EAAQlF,EAAUmE,GAC1BvF,MAAMuF,GACNhH,KAAK+H,OAASA,EACd/H,KAAK6C,SAAWA,CACpB,CACA,YAAA8E,GACI,OAAI3H,KAAK+H,kBAAkBZ,EAChBnH,KAAK+H,OAGL/H,KAAK+H,OAAOJ,cAE3B,CACA,QAAAjF,CAAShE,EAAMkE,GAGX,IAAIC,EACJ,GAFyBD,GAASoF,mBAAoB,EAEhC,CAClB,MAAMC,EAAgBrF,GAASC,SAE/BA,EAAWoF,EAAgBtJ,EAASqB,KAAK6C,SAAUoF,GAAiBjI,KAAK6C,QAC7E,MAGIA,EAAWD,GAASC,UAAY7C,KAAK6C,SAEzC7C,KAAK+H,OAAOrF,SAAShE,EAAM,IACpBkE,EACHC,YAER,EAEC,MAACqF,EAAqBC,OAActE,GAElC,SAASuE,IACZ,MAAMC,EAAMC,EAAWJ,GACvB,IAAKG,EACD,MAAM,IAAI5I,MAAM,kDAEpB,OAAO4I,CACX,CACO,SAASE,IACZ,MAAM7F,SAAEA,GAAa0F,IACrB,OAAO1F,CACX,CACO,SAAS8F,EAAUC,GACtB,MAAM9I,OAAEA,GAAWyI,IACnB,OAAIK,EACO9I,EAAO8I,GAGP9I,CAEf,CACO,SAAS+I,IACZ,MAAM3H,SAAEA,GAAaqH,IACrB,OAAOrH,CACX,CACO,SAAS4H,EAAoBvB,GAChC,MAAMwB,OAAEA,GAAWR,IACnBnD,GAAU,KACN2D,EAAOjB,eAAeP,OAASA,EACxB,KACHwB,EAAOjB,eAAeP,YAASvD,KAEpC,IACHoB,GAAU,KACN,GAAImC,EAAOI,KAAM,CACb,MAAMqB,EAAUzB,EAAOI,KACjBvF,EAAW,SAAU8B,GACnB8E,IACA9E,EAAGS,iBACHT,EAAG+E,YAAc,GAEzB,EAEA,OADAvG,OAAOkC,iBAAiB,eAAgBxC,GACjC,KACHM,OAAOqC,oBAAoB,eAAgB3C,GAEnD,IACD,CAACmF,EAAOI,MACf,CC7JO,SAASuB,GAAIjE,SAAEA,EAAQkE,QAAEA,IAC5B,MAAMtG,EAAW6F,IAUjB,OAAQnD,EAAK,OAAQ,CAAE4D,QATLjF,IACd,MAAMkF,EAAOlF,EAAGO,OAAO4E,QAAQ,KAC3BD,GAAQA,EAAKzG,OACbuB,EAAGoF,kBACHpF,EAAGS,iBACH9B,EAASuG,EAAKzG,KAAM,CAAEgB,SAAS,IAC/BwF,IAAUjF,KAGwBe,SAAUA,GACxD,CACO,SAASsE,GAAQtE,SAAEA,EAAQtC,KAAEA,EAAI6C,UAAEA,EAASgE,YAAEA,EAAWC,iBAAEA,GAAmB,IACjF,MAAMV,OAAEA,GAAWR,IAOnB,OAAQhD,EAAK,IAAK,CAAE5C,KAAMA,EAAM6C,UAAWA,EAAW2D,QANpCjF,IACdA,EAAGoF,kBACHpF,EAAGS,kBACkB6E,EAAcT,EAAOjB,eAAiBiB,GAC9ClG,SAASF,EAAM,CAAEgB,QAAS8F,KAE8BxE,SAAUA,GACvF,CCrBO,SAASyE,GAAeC,QAAEA,IAC7B,MAAMnB,EAAMD,IACNnB,EAAQoB,EAAIpB,MAClB,GAAIA,EAAMwC,UAAW,CACjB,MAAMA,EAAYxC,EAAMwC,UACxB,OAAOrE,EAAKqE,EAAW,IAAKpB,EAAI1I,QACpC,CACK,GAAIsH,EAAMyC,cACX,OAAOtE,EAAKuE,EAAoB,CAAE1C,MAAOA,EAAOuC,QAASA,IAGzD,MAAM,IAAI/J,MAAM,qBAAqBwH,EAAMvI,6DAEnD,CACA,SAASiL,GAAmB1C,MAAEA,EAAKuC,QAAEA,IACjC,MAAOC,EAAWG,GAAgBC,EAAS,MAW3C,OAVA5E,GAAU,KACNgC,EAAMyC,gBAAgBI,MAAKC,IACvB,IAAKA,EAAOC,QACR,MAAM,IAAIvK,MAAM,mBAAmBwH,EAAMvI,uCAI7CkL,GAAa,IAAMG,EAAOC,eAE/B,CAAC/C,IACGwC,EAAarE,EAAKqE,EAAW,CAAA,GAAOD,GAAW,IAC1D,CCzBO,SAASS,GAAwBpH,SAAEA,EAAQqH,SAAEA,GAAW,EAAKpF,SAAEA,IAClE,MAAMuD,EAAMD,IACN+B,EAAmBD,EACpBjG,GAASmB,EAAKP,EAAU,CAAEhC,SAAUwF,EAAI+B,iBAAkBtF,SAAUb,IAClEA,GAASA,EAChB,OAAQmB,EAAK8C,EAAmBmC,SAAU,CAAEhK,MAAO,IACxCgI,EACH3F,SAAU,CAACC,EAAIC,KACX,MAAM0H,EAAiB1H,GAASC,SAAWlE,EAASkE,EAAUD,EAAQC,UAAYA,EAClF,OAAOwF,EAAI3F,SAASC,EAAI,IAAKC,EAASC,SAAUyH,MAErDxF,SAAUqF,EAAiBrF,GAAsBM,EAAKmE,EAAgB,MACjF,CCfO,SAASgB,IACZ,MAAMlC,EAAMD,IACZ,OAAOoC,EAAM,MAAO,CAAE1F,SAAU,CAAC,4BAA6BuD,EAAI+B,mBACtE,CACO,SAASK,IACZ,MAAO,CACH9K,OAAQ,CAAA,EACR6G,gBAAiB,GACjBxF,MAAO,KACPX,MAAO,CACH3B,KAAM,cACN+K,UAAW,IAAMrE,EAAKmF,EAAmB,CAAA,IAGrD,CCVO,SAASG,GAAqB1D,OAAEA,EAAMF,MAAEA,EAAKhC,SAAEA,EAAQoF,SAAEA,GAAW,IACvE,MAAM7B,EAAMD,KACLuC,EAAkBC,GAAuBf,OAAShG,GACnDgH,EAAeC,GAAQ,KACzB,GAAsB,oBAAXvI,OACP,OAAO,KACX,MAAMM,EAAWwF,EAAI+B,iBACfS,EAAe,IAAI/C,EAAaO,EAAIO,OAAQ/F,EAAUmE,GAE5D,OADA6D,EAAa/D,MAAQA,EACd+D,IACR,IACH5F,GAAU,KACN,GAAI4F,EAAc,CACd,GAAIxC,EAAI+B,mBAAqBS,EAAahI,SAGtC,OAEJ,MAAMoE,EAAQ4D,EAAatE,MAAM8B,EAAI0C,eAAiB,MAAQN,IAC9DG,EAAoB3D,EACxB,IACD,CAAC4D,EAAcxC,EAAI0C,gBACtB,MAAMZ,EAAmBD,EACpBjG,GAASmB,EAAKP,EAAU,CAAEhC,SAAUwF,EAAI+B,iBAAkBtF,SAAUb,IAClEA,GAASA,EAChB,OAAO0G,GAAqBvF,EAAK8C,EAAmBmC,SAAU,CAAEhK,MAAO,IAC5DgI,EACHO,OAAQiC,EACR5D,MAAO0D,EAAiBtK,MACxBV,OAAQgL,EAAiBhL,OACzByK,iBAAkB,IAAMO,EAAiBnE,gBAAgBJ,KAAK,KAC9D2E,cAAeJ,EAAiBlE,kBAAoB,IAAMkE,EAAiBlE,kBAAkBL,KAAK,UAAOvC,EACzGnB,SAAU,CAACC,EAAIC,IACJiI,EAAanI,SAASC,EAAIC,IAEtCkC,SAAUqF,EAAiBrF,GAAsBM,EAAKmE,EAAgB,CAAA,KACjF,CCnCO,SAASyB,GAAehE,OAAEA,EAAMF,MAAEA,EAAKmE,SAAEA,EAAQnG,SAAEA,IACtD,MAAO9D,EAAOkK,GAAYrB,OAAShG,GAC7B+E,EAASkC,GAAQ,KACnB,GAAsB,oBAAXvI,OACP,OAAO,KACX,MAAMqG,EAAS,IAAIzB,EAAOH,GAAST,IACjB,OAAVA,IACAA,EAAQkE,KAEZS,EAAS,CACLnK,SAAUwB,OAAOxB,SACjBkG,MAAOV,EAAMlG,MACbV,OAAQ4G,EAAM5G,OACdqB,MAAOuF,EAAMvF,MACb4H,OAAQA,EACRwB,iBAAkB,IAAM7D,EAAMC,gBAAgBJ,KAAK,KACnD2E,cAAexE,EAAME,kBAAoB,IAAMF,EAAME,kBAAkBL,KAAK,UAAOvC,EACnFnB,SAAU,CAACC,EAAIC,IACJgG,EAAOlG,SAASC,EAAIC,QAGpCiF,aAAaoD,GAEhB,OADArC,EAAO9B,MAAQA,EACR8B,IACR,IAOH,OANAuC,GAAoB,KAChBvC,GAAUA,EAAO9E,QACV,KACH8E,GAAUA,EAAOjE,UAEtB,IACI3D,GAAUoE,EAAK8C,EAAmBmC,SAAU,CAAEhK,MAAOW,EAAO8D,SAAUA,GAAsBM,EAAKmE,EAAgB,CAAA,IAC5H"}
@@ -1,2 +1,2 @@
1
- import{jwtDecode as e}from"jwt-decode";import{Env as t}from"@vertesia/ui/env";import{getAnalytics as o,logEvent as n}from"firebase/analytics";import{initializeApp as r}from"firebase/app";import{getAuth as i,onAuthStateChanged as a}from"firebase/auth";import{useState as s,useEffect as c,createContext as l,useContext as u,useCallback as h}from"react";import{useUserSession as d}from"@vertesia/ui/session";import{VertesiaClient as g}from"@vertesia/client";import{jsx as m}from"react/jsx-runtime";const p="composableai.lastSelectedAccountId",f="composableai.lastSelectedProjectId";let w,v,k=null,b=null,y=null;function S(){if(!k)try{if(!t.firebase)throw new Error("Firebase configuration is not available in the environment");k=r(t.firebase)}catch(e){throw console.error("Failed to initialize Firebase app:",e),new Error("Firebase initialization failed - environment may not be properly initialized")}return k}function T(){return b||(b=o(S())),b}function _(){return y||(y=i(S())),y}async function j(e){if(e)if(t.firebase)try{e&&console.log(`Resolving tenant ID from email: ${e}`);let o=3,n=250;for(;o>0;)try{const o=await fetch("/api/resolve-tenant",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenantEmail:e}),signal:AbortSignal.timeout(5e3)});if(!o)throw new Error("No response received from tenant API");if(!o.ok){try{const e=await o.json();console.error("Failed to resolve tenant ID:",e.error)}catch(e){console.error(`Failed to resolve tenant ID: HTTP ${o.status}`)}if(404===o.status)return void console.warn(`Tenant not found for ${e}`);throw new Error(`HTTP error ${o.status}`)}const n=await o.json();if(n&&n.firebaseTenantId){const e=_();return e.tenantId=n.firebaseTenantId,t.firebase.providerType=n.provider??"oidc",console.log(`Tenant ID set to ${e.tenantId}`),n}return void console.error(`Invalid response format, missing tenantId for ${e}`)}catch(e){if(!(o>1))throw e;console.warn(`Tenant resolution failed, retrying in ${n}ms...`,e),await new Promise((e=>setTimeout(e,n))),n*=2,o--}}catch(e){console.error("Error setting Firebase tenant:",e instanceof Error?e.message:"Unknown error")}else console.log("Firebase configuration is not available in the environment");else console.log("No tenant name or email specified, skipping tenant setup")}async function I(e){const o=_().currentUser;return o?o.getIdToken(e).then((n=>(t.logger.info("Got Firebase token",{vertesia:{user_email:o.email,user_name:o.displayName,user_id:o.uid,refresh:e}}),n))).catch((n=>(t.logger.error("Failed to get Firebase token",{vertesia:{user_email:o.email,user_name:o.displayName,user_id:o.uid,refresh:e,error:n}}),console.error("Failed to get access token",n),null))):(t.logger.warn("No user found"),Promise.resolve(null))}async function F(o,n,r,i){console.log(`Getting/refreshing composable token for account ${n} and project ${r} `),t.logger.info("Getting/refreshing composable token",{vertesia:{account_id:n,project_id:r}});const a=await o();if(!a)throw console.log("No id token found - using cookie auth"),new Error("No id token found");console.log("Fetching composable token from "+t.endpoints.studio),t.logger.info("Fetching composable token from"+t.endpoints.studio,{vertesia:{account_id:n,project_id:r}});const s=new URL(t.endpoints.studio+"/auth/token");n&&s.searchParams.set("accountId",n),r&&s.searchParams.set("projectId",r),i&&s.searchParams.set("ttl",String(i)),console.log(`Getting composable token for account ${n} and project ${r}`),t.logger.info("Getting composable token",{vertesia:{account_id:n,project_id:r}});const c=await fetch(s,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}}).catch((e=>{throw localStorage.removeItem(p),localStorage.removeItem(f),console.error("Failed to get composable token",e),t.logger.error("Failed to get composable token",{vertesia:{account_id:n,project_id:r,error:e}}),new Error("Failed to get composable token")}));if(a&&412===c?.status){console.log("412: auth succeeded but user doesn't exist - signup required",c?.status),t.logger.error("412: auth succeeded but user doesn't exist - signup required",{vertesia:{account_id:n,project_id:r,status:c?.status}});const o=e(a);if(!o?.email)throw t.logger.error("No email found in id token"),new Error("No email found in id token");throw t.logger.error("User not found",{vertesia:{account_id:n,project_id:r,email:o.email}}),new P("User not found",o.email)}if(!c||!c.ok)throw console.error("Failed to get composable token",c),t.logger.error("Failed to get composable token",{vertesia:{account_id:n,project_id:r,status:c?.status}}),new Error("Failed to get composable token");const{token:l}=await c.json().catch((e=>{t.logger.error("Failed to parse composable token",{vertesia:{account_id:n,project_id:r,error:e}}),console.error("Failed to parse composable token",e)}));return l}async function E(e,t,o){return F(I,e,t,o)}async function A(o,n,r,i=!1,a=!1){const s=o??localStorage.getItem(p)??void 0,c=n??localStorage.getItem(f+"-"+s)??void 0;if(!i&&w&&v&&v.exp>Date.now()/1e3+300)return{rawToken:w,token:v,error:!1};if(!a&&_().currentUser?w=await E(s,c):(r||w)&&(w=await F((()=>Promise.resolve(r??w)),s,c)),!w)throw t.logger.error("Cannot acquire a composable token",{vertesia:{account_id:s,project_id:c}}),new Error("Cannot acquire a composable token");if(v=e(w),!v||!v.exp||!w)throw console.error("Invalid composable token",v),t.logger.error("Invalid composable token",{vertesia:{account_id:s,project_id:c}}),new Error("Invalid composable token");return{rawToken:w,token:v,error:!1}}class P extends Error{email;constructor(e,t){super(e),this.name="UserNotFoundError",this.email=t}}function $(){const{user:e}=d(),[t,o]=s(null),[n,r]=s(!0),[i,a]=s(null);return c((()=>{(async()=>{if(!e?.email)return o(null),void r(!1);try{const t=await fetch("/api/resolve-tenant",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenantEmail:e.email})});if(t.ok){const e=await t.json();o(e?{tenantKey:e.name||"unknown",name:e.label||e.name||"Unknown",domain:e.domain||[],firebaseTenantId:e.firebaseTenantId,provider:e.provider,logo:e.logo}:null)}else o(null)}catch(e){console.error("Error loading current tenant:",e),a("Failed to load tenant configuration"),o(null)}finally{r(!1)}})()}),[e?.email]),{currentTenant:t,isLoading:n,error:i}}class U{types;map={};constructor(e){this.types=e,e.sort(((e,t)=>e.name.localeCompare(t.name)));for(const t of e)this.map[t.id]=t}getType(e){return this.map[e]}getTypeLayout(e){const t=this.map[e];return t?t.table_layout:void 0}getTypeName(e){const t=this.map[e];return t?t.name:void 0}}class C{isLoading=!0;client;authError;authToken;typeRegistry;setSession;lastSelectedAccount;lastSelectedProject;onboardingComplete;constructor(e,o){this.client=e||new g({serverUrl:t.endpoints.studio,storeUrl:t.endpoints.zeno}),o&&(this.setSession=o),this.logout=this.logout.bind(this)}get store(){return this.client.store}get user(){return this.authToken}get account(){return this.authToken?.account}get project(){return this.authToken?.project}get accounts(){return this.authToken?.accounts}get authCallback(){return this.rawAuthToken.then((e=>`Bearer ${e}`))}get rawAuthToken(){return A().then((t=>{const o=t?.rawToken;if(!o)throw new Error("No token available");return this.authToken=e(o),o}))}signOut(){this.logout()}getAccount(){return this.authToken?.account}async login(o){return this.authError=void 0,this.isLoading=!1,this.client.withAuthCallback((()=>this.authCallback)),this.authToken=e(o),console.log(`Logging in as ${this.authToken?.name} with account ${this.authToken?.account.name} (${this.authToken?.account.id}, and project ${this.authToken?.project?.name} (${this.authToken?.project?.id})`),localStorage.setItem(p,this.authToken.account.id),localStorage.setItem(f+"-"+this.authToken.account.id,this.authToken.project?.id??""),t.onLogin?.(this.authToken),await Promise.all([this._loadTypes(),this.fetchOnboardingStatus()]),Promise.resolve()}isLoggedIn(){return!!this.authToken}logout(){console.log("Logging out"),this.authToken&&_().signOut(),this.authError=void 0,this.isLoading=!1,this.authToken=void 0,this.typeRegistry=void 0,this.setSession=void 0,this.client.withAuthCallback(void 0)}async switchAccount(e){localStorage.setItem(p,e),this&&(this.account&&this.project?localStorage.setItem(f+"-"+this.account.id,this.project.id):this.account&&localStorage.removeItem(f+"-"+this.account.id)),window.location.replace("/?a="+e)}async switchProject(e){this.account&&localStorage.setItem(f+"-"+this.account.id,e),window.location.replace("/?a="+this.account?.id+"&p="+e)}async _loadTypes(){if(this.project)return this.store.types.list({},{layout:!0}).then((e=>this.typeRegistry=new U(e))).catch((e=>{throw console.error("Failed to fetch object types",e),e}));console.log("No project selected")}async reloadTypes(){return this._loadTypes().then((()=>{this.setSession?.(this.clone())}))}async fetchAccounts(){return this.client.accounts.list().then((e=>{if(!this.authToken)throw new Error("No token available");this.authToken.accounts=e,this.setSession?.(this.clone())})).catch((e=>{throw console.error("Failed to fetch accounts",e),e}))}async fetchOnboardingStatus(){if(this.onboardingComplete)return console.log("Onboarding already completed"),!1;const e=this.onboardingComplete;try{const t=await this.client.account.onboardingProgress();if(this.onboardingComplete=Object.values(t).every((e=>!0===e)),e!==this.onboardingComplete)return!0;this.setSession?.(this.clone())}catch(e){console.error("Error fetching onboarding status:",e),this.onboardingComplete=!1,this.setSession?.(this.clone())}return!1}clone(){const e=new C(this.client);return e.isLoading=this.isLoading,e.authError=this.authError,e.authToken=this.authToken,e.setSession=this.setSession,e.lastSelectedAccount=this.lastSelectedAccount,e.switchAccount=this.switchAccount,e.typeRegistry=this.typeRegistry,e.onboardingComplete=this.onboardingComplete,e}}const N=l(void 0);function L(){const e=u(N);if(!e)throw new Error("useUserSession must be used within a UserSessionProvider");return e}const R="auth_state",D="auth_state_expiry";const O=[".composable.sh",".vertesia.dev","vertesia.app"];function x(){return!!t.isDocker||O.some((e=>window.location.hostname.endsWith(e)))}function G({children:e}){const o=new URLSearchParams(location.hash.substring(1)),n=o.get("token"),r=o.get("state"),[i,l]=s(new C),{generateState:u,verifyState:d,clearState:g}={generateState:h((()=>{const e=crypto.randomUUID(),t=Date.now()+3e5;return sessionStorage.setItem(R,e),sessionStorage.setItem(D,t.toString()),e}),[]),verifyState:h((e=>{if(!e)return"Missing state";const t=sessionStorage.getItem(R),o=parseInt(sessionStorage.getItem(D)||"0");let n;return n=t!==e?`State mismatched (${t} !== ${e})`:Date.now()>o?"State expired":void 0,n}),[]),clearState:h((()=>{sessionStorage.removeItem(R),sessionStorage.removeItem(D)}),[])},w=(e,t)=>{const o=new URL("https://internal-auth.vertesia.app/"),n=new URL(window.location.href);n.hash="",o.searchParams.set("redirect_uri",n.toString()),o.searchParams.set("state",u()),location.replace(o.toString())};return c((()=>{console.log("Auth: starting auth flow"),t.logger.info("Starting auth flow");const e=new URL(window.location.href),o=e.searchParams.get("a")??localStorage.getItem(p)??void 0,s=e.searchParams.get("p")??localStorage.getItem(f+"-"+o)??void 0;if(console.log("Auth: selected account",o),console.log("Auth: selected project",s),t.logger.info("Selected account and project",{vertesia:{account_id:o,project_id:s}}),n&&r){const e=d(r);return e?(console.error(`Auth: invalid state: ${e}`),t.logger.error(`Invalid state: ${e}`,{vertesia:{state:r}}),w()):g(),void A(o,s,n,!1,x()).then((e=>{i.login(e.rawToken).then((()=>{l(i.clone()),window.location.hash=""}))})).catch((e=>{console.error("Failed to fetch user token from studio, redirecting to central auth",e),t.logger.error("Failed to fetch user token from studio, redirecting to central auth",{vertesia:{error:e}}),w()}))}return i.isLoggedIn()||(console.log("Auth: not logged in & no token/state"),t.logger.info("Not logged in & no token/state",{vertesia:{account_id:o,project_id:s}}),x()?(console.log("Auth: on dev domain, redirecting to central auth with selection",o,s),t.logger.info("Redirecting to central auth with selection",{vertesia:{account_id:o,project_id:s}}),w()):(console.log("Auth: not on dev domain"),t.logger.info("Not on dev domain",{vertesia:{account_id:o,project_id:s}}))),a(_(),(async e=>{e?(console.log("Auth: successful login with firebase"),t.logger.info("Successful login with firebase",{vertesia:{account_id:o,project_id:s}}),i.setSession=l,await A(o,s,void 0,!1,x()).then((e=>{i.login(e.rawToken).then((()=>l(i.clone())))})).catch((e=>{console.error("Failed to fetch user token from studio",e),t.logger.error("Failed to fetch user token from studio",{vertesia:{account_id:o,project_id:s,error:e}}),e instanceof P||i.logout(),i.isLoading=!1,i.authError=e,l(i.clone())}))):(console.log("Auth: using anonymous user"),t.logger.info("Using anonymous user",{vertesia:{account_id:o,project_id:s}}),i.client.withAuthCallback(void 0),i.logout(),l(i.clone()))}))}),[]),m(N.Provider,{value:i,children:e})}function z(){return{tagUserSession:async e=>{const t=window.localStorage.getItem("composableSignupData");e?t&&window.localStorage.removeItem("composableSignupData"):console.error("No user found -- skipping tagging")},trackEvent:(e,o)=>{t.isProd||console.debug("track event",e,o),n(T(),e,{...o,debug_mode:!t.isProd})}}}export{p as LastSelectedAccountId_KEY,f as LastSelectedProjectId_KEY,U as TypeRegistry,P as UserNotFoundError,C as UserSession,N as UserSessionContext,G as UserSessionProvider,F as fetchComposableToken,E as fetchComposableTokenFromFirebaseToken,A as getComposableToken,T as getFirebaseAnalytics,S as getFirebaseApp,_ as getFirebaseAuth,I as getFirebaseAuthToken,j as setFirebaseTenant,$ as useCurrentTenant,z as useUXTracking,L as useUserSession};
1
+ import{jwtDecode as e}from"jwt-decode";import{Env as t}from"@vertesia/ui/env";import{getAnalytics as o,logEvent as n}from"firebase/analytics";import{initializeApp as r}from"firebase/app";import{getAuth as i,onAuthStateChanged as s}from"firebase/auth";import{useState as a,useEffect as c,createContext as l,useContext as u,useCallback as h,useRef as d}from"react";import{useUserSession as g}from"@vertesia/ui/session";import{VertesiaClient as m}from"@vertesia/client";import{jsx as p}from"react/jsx-runtime";const f="composableai.lastSelectedAccountId",w="composableai.lastSelectedProjectId";let v,k,S=null,y=null,b=null;function T(){if(!S)try{if(!t.firebase)throw new Error("Firebase configuration is not available in the environment");S=r(t.firebase)}catch(e){throw console.error("Failed to initialize Firebase app:",e),new Error("Firebase initialization failed - environment may not be properly initialized")}return S}function _(){return y||(y=o(T())),y}function I(){return b||(b=i(T())),b}async function j(e){if(e)if(t.firebase)try{e&&console.log(`Resolving tenant ID from email: ${e}`);let o=3,n=250;for(;o>0;)try{const o=await fetch("/api/resolve-tenant",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenantEmail:e}),signal:AbortSignal.timeout(5e3)});if(!o)throw new Error("No response received from tenant API");if(!o.ok){try{const e=await o.json();console.error("Failed to resolve tenant ID:",e.error)}catch(e){console.error(`Failed to resolve tenant ID: HTTP ${o.status}`)}if(404===o.status)return void console.warn(`Tenant not found for ${e}`);throw new Error(`HTTP error ${o.status}`)}const n=await o.json();if(n&&n.firebaseTenantId){const e=I();return e.tenantId=n.firebaseTenantId,t.firebase.providerType=n.provider??"oidc",console.log(`Tenant ID set to ${e.tenantId}`),n}return void console.error(`Invalid response format, missing tenantId for ${e}`)}catch(e){if(!(o>1))throw e;console.warn(`Tenant resolution failed, retrying in ${n}ms...`,e),await new Promise((e=>setTimeout(e,n))),n*=2,o--}}catch(e){console.error("Error setting Firebase tenant:",e instanceof Error?e.message:"Unknown error")}else console.log("Firebase configuration is not available in the environment");else console.log("No tenant name or email specified, skipping tenant setup")}async function E(e){const o=I().currentUser;return o?o.getIdToken(e).then((n=>(t.logger.info("Got Firebase token",{vertesia:{user_email:o.email,user_name:o.displayName,user_id:o.uid,refresh:e}}),n))).catch((n=>(t.logger.error("Failed to get Firebase token",{vertesia:{user_email:o.email,user_name:o.displayName,user_id:o.uid,refresh:e,error:n}}),console.error("Failed to get access token",n),null))):(t.logger.warn("No user found"),Promise.resolve(null))}async function A(o,n,r,i){console.log(`Getting/refreshing composable token for account ${n} and project ${r} `),t.logger.info("Getting/refreshing composable token",{vertesia:{account_id:n,project_id:r}});const s=await o();if(!s)throw console.log("No id token found - using cookie auth"),new Error("No id token found");const a=t.endpoints.sts;console.log("Using STS for token generation:",a),t.logger.info("Using STS for token generation",{vertesia:{account_id:n,project_id:r,sts_url:a}});try{const o=new URL(a+"/token/issue"),c={type:"user",account_id:n,project_id:r,expires_at:i?Math.floor(Date.now()/1e3)+i:void 0},l=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify(c)});if(s&&412===l?.status){console.log("412: auth succeeded but user doesn't exist - signup required",l?.status),t.logger.error("412: auth succeeded but user doesn't exist - signup required",{vertesia:{account_id:n,project_id:r,status:l?.status}});const o=e(s);if(!o?.email)throw t.logger.error("No email found in id token"),new Error("No email found in id token");throw t.logger.error("User not found",{vertesia:{account_id:n,project_id:r,email:o.email}}),new U("User not found",o.email)}if(!l.ok){const e=await l.text();throw console.error("STS token generation failed:",l.status,e),t.logger.error("STS token generation failed",{vertesia:{status:l.status,error:e,account_id:n,project_id:r}}),new Error(`Failed to get token from STS: ${l.status}`)}const{token:u}=await l.json();return console.log("Successfully got token from STS"),t.logger.info("Successfully got token from STS"),u}catch(e){if(e instanceof U)throw e;throw localStorage.removeItem(f),localStorage.removeItem(w),console.error("Failed to get composable token from STS",e),t.logger.error("Failed to get composable token from STS",{vertesia:{account_id:n,project_id:r,error:e}}),new Error("Failed to get composable token")}}async function F(e,t,o){return A(E,e,t,o)}async function P(o,n,r,i=!1,s=!1){const a=o??localStorage.getItem(f)??void 0,c=n??localStorage.getItem(w+"-"+a)??void 0;if(!i&&v&&k&&k.exp>Date.now()/1e3+300)return{rawToken:v,token:k,error:!1};if(!s&&I().currentUser?v=await F(a,c):(r||v)&&(v=await A((()=>Promise.resolve(r??v)),a,c)),!v)throw t.logger.error("Cannot acquire a composable token",{vertesia:{account_id:a,project_id:c}}),new Error("Cannot acquire a composable token");if(k=e(v),!k||!k.exp||!v)throw console.error("Invalid composable token",k),t.logger.error("Invalid composable token",{vertesia:{account_id:a,project_id:c}}),new Error("Invalid composable token");return{rawToken:v,token:k,error:!1}}class U extends Error{email;constructor(e,t){super(e),this.name="UserNotFoundError",this.email=t}}function $(){const{user:e}=g(),[t,o]=a(null),[n,r]=a(!0),[i,s]=a(null);return c((()=>{(async()=>{if(!e?.email)return o(null),void r(!1);try{const t=await fetch("/api/resolve-tenant",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenantEmail:e.email})});if(t.ok){const e=await t.json();o(e?{tenantKey:e.name||"unknown",name:e.label||e.name||"Unknown",domain:e.domain||[],firebaseTenantId:e.firebaseTenantId,provider:e.provider,logo:e.logo}:null)}else o(null)}catch(e){console.error("Error loading current tenant:",e),s("Failed to load tenant configuration"),o(null)}finally{r(!1)}})()}),[e?.email]),{currentTenant:t,isLoading:n,error:i}}class N{types;map={};constructor(e){this.types=e,e.sort(((e,t)=>e.name.localeCompare(t.name)));for(const t of e)this.map[t.id]=t}getType(e){return this.map[e]}getTypeLayout(e){const t=this.map[e];return t?t.table_layout:void 0}getTypeName(e){const t=this.map[e];return t?t.name:void 0}}class C{isLoading=!0;client;authError;authToken;typeRegistry;setSession;lastSelectedAccount;lastSelectedProject;onboardingComplete;constructor(e,o){this.client=e||new m({serverUrl:t.endpoints.studio,storeUrl:t.endpoints.zeno,tokenServerUrl:t.endpoints.sts}),o&&(this.setSession=o),this.logout=this.logout.bind(this)}get store(){return this.client.store}get user(){return this.authToken}get account(){return this.authToken?.account}get project(){return this.authToken?.project}get accounts(){return this.authToken?.accounts}get authCallback(){return this.rawAuthToken.then((e=>`Bearer ${e}`))}get rawAuthToken(){return P().then((t=>{const o=t?.rawToken;if(!o)throw new Error("No token available");return this.authToken=e(o),o}))}signOut(){this.logout()}getAccount(){return this.authToken?.account}async login(o){return this.authError=void 0,this.isLoading=!1,this.client.withAuthCallback((()=>this.authCallback)),this.authToken=e(o),console.log(`Logging in as ${this.authToken?.name} with account ${this.authToken?.account.name} (${this.authToken?.account.id}, and project ${this.authToken?.project?.name} (${this.authToken?.project?.id})`),localStorage.setItem(f,this.authToken.account.id),localStorage.setItem(w+"-"+this.authToken.account.id,this.authToken.project?.id??""),t.onLogin?.(this.authToken),await Promise.all([this._loadTypes(),this.fetchOnboardingStatus()]),Promise.resolve()}isLoggedIn(){return!!this.authToken}logout(){console.log("Logging out"),this.authToken&&I().signOut(),this.authError=void 0,this.isLoading=!1,this.authToken=void 0,this.typeRegistry=void 0,this.setSession=void 0,this.client.withAuthCallback(void 0)}async switchAccount(e){localStorage.setItem(f,e),this&&(this.account&&this.project?localStorage.setItem(w+"-"+this.account.id,this.project.id):this.account&&localStorage.removeItem(w+"-"+this.account.id)),window.location.replace("/?a="+e)}async switchProject(e){this.account&&localStorage.setItem(w+"-"+this.account.id,e),window.location.replace("/?a="+this.account?.id+"&p="+e)}async _loadTypes(){if(this.project)return this.store.types.list({},{layout:!0}).then((e=>this.typeRegistry=new N(e))).catch((e=>{throw console.error("Failed to fetch object types",e),e}));console.log("No project selected")}async reloadTypes(){return this._loadTypes().then((()=>{this.setSession?.(this.clone())}))}async fetchAccounts(){return this.client.accounts.list().then((e=>{if(!this.authToken)throw new Error("No token available");this.authToken.accounts=e,this.setSession?.(this.clone())})).catch((e=>{throw console.error("Failed to fetch accounts",e),e}))}async fetchOnboardingStatus(){if(this.onboardingComplete)return console.log("Onboarding already completed"),!1;const e=this.onboardingComplete;try{const t=await this.client.account.onboardingProgress();if(this.onboardingComplete=Object.values(t).every((e=>!0===e)),e!==this.onboardingComplete)return!0;this.setSession?.(this.clone())}catch(e){console.error("Error fetching onboarding status:",e),this.onboardingComplete=!1,this.setSession?.(this.clone())}return!1}clone(){const e=new C(this.client);return e.isLoading=this.isLoading,e.authError=this.authError,e.authToken=this.authToken,e.setSession=this.setSession,e.lastSelectedAccount=this.lastSelectedAccount,e.switchAccount=this.switchAccount,e.typeRegistry=this.typeRegistry,e.onboardingComplete=this.onboardingComplete,e}}const L=l(void 0);function D(){const e=u(L);if(!e)throw new Error("useUserSession must be used within a UserSessionProvider");return e}const O="auth_state",R="auth_state_expiry";const x=[".composable.sh",".vertesia.dev","vertesia.app"];function z(){return!!t.isDocker||x.some((e=>window.location.hostname.endsWith(e)))}function q({children:e}){const o=new URLSearchParams(location.hash.substring(1)),n=o.get("token"),r=o.get("state"),[i,l]=a(new C),{generateState:u,verifyState:g,clearState:m}={generateState:h((()=>{const e=crypto.randomUUID(),t=Date.now()+3e5;return sessionStorage.setItem(O,e),sessionStorage.setItem(R,t.toString()),e}),[]),verifyState:h((e=>{if(!e)return"Missing state";const t=sessionStorage.getItem(O),o=parseInt(sessionStorage.getItem(R)||"0");let n;return n=t!==e?`State mismatched (${t} !== ${e})`:Date.now()>o?"State expired":void 0,n}),[]),clearState:h((()=>{sessionStorage.removeItem(O),sessionStorage.removeItem(R)}),[])},v=d(!1),k=(e,o)=>{const n=new URL(`https://internal-auth.vertesia.app/?sts=${t.endpoints.sts??"https://sts.vertesia.io"}`),r=new URL(window.location.href);r.hash="",n.searchParams.set("redirect_uri",r.toString()),n.searchParams.set("state",u()),location.replace(n.toString())};return c((()=>{if(v.current)return void console.log("Auth: skipping duplicate auth flow initiation");v.current=!0,console.log("Auth: starting auth flow"),t.logger.info("Starting auth flow");const e=new URL(window.location.href),o=e.searchParams.get("a")??localStorage.getItem(f)??void 0,a=e.searchParams.get("p")??localStorage.getItem(w+"-"+o)??void 0;if(console.log("Auth: selected account",o),console.log("Auth: selected project",a),t.logger.info("Selected account and project",{vertesia:{account_id:o,project_id:a}}),n&&r){const e=g(r);return e?(console.error(`Auth: invalid state: ${e}`),t.logger.error(`Invalid state: ${e}`,{vertesia:{state:r}}),k()):m(),void P(o,a,n,!1,z()).then((e=>{i.login(e.rawToken).then((()=>{l(i.clone()),window.location.hash=""}))})).catch((e=>{console.error("Failed to fetch user token from studio, redirecting to central auth",e),t.logger.error("Failed to fetch user token from studio, redirecting to central auth",{vertesia:{error:e}}),k()}))}return i.isLoggedIn()||(console.log("Auth: not logged in & no token/state"),t.logger.info("Not logged in & no token/state",{vertesia:{account_id:o,project_id:a}}),z()?(console.log("Auth: on dev domain, redirecting to central auth with selection",o,a),t.logger.info("Redirecting to central auth with selection",{vertesia:{account_id:o,project_id:a}}),k()):(console.log("Auth: not on dev domain"),t.logger.info("Not on dev domain",{vertesia:{account_id:o,project_id:a}}))),s(I(),(async e=>{e?(console.log("Auth: successful login with firebase"),t.logger.info("Successful login with firebase",{vertesia:{account_id:o,project_id:a}}),i.setSession=l,await P(o,a,void 0,!1,z()).then((e=>{i.login(e.rawToken).then((()=>l(i.clone())))})).catch((e=>{console.error("Failed to fetch user token from studio",e),t.logger.error("Failed to fetch user token from studio",{vertesia:{account_id:o,project_id:a,error:e}}),e instanceof U||i.logout(),i.isLoading=!1,i.authError=e,l(i.clone())}))):(console.log("Auth: using anonymous user"),t.logger.info("Using anonymous user",{vertesia:{account_id:o,project_id:a}}),i.client.withAuthCallback(void 0),i.logout(),l(i.clone()))}))}),[]),p(L.Provider,{value:i,children:e})}function G(){return{tagUserSession:async e=>{const t=window.localStorage.getItem("composableSignupData");e?t&&window.localStorage.removeItem("composableSignupData"):console.error("No user found -- skipping tagging")},trackEvent:(e,o)=>{t.isProd||console.debug("track event",e,o),n(_(),e,{...o,debug_mode:!t.isProd})}}}export{f as LastSelectedAccountId_KEY,w as LastSelectedProjectId_KEY,N as TypeRegistry,U as UserNotFoundError,C as UserSession,L as UserSessionContext,q as UserSessionProvider,A as fetchComposableToken,F as fetchComposableTokenFromFirebaseToken,P as getComposableToken,_ as getFirebaseAnalytics,T as getFirebaseApp,I as getFirebaseAuth,E as getFirebaseAuthToken,j as setFirebaseTenant,$ as useCurrentTenant,G as useUXTracking,D as useUserSession};
2
2
  //# sourceMappingURL=vertesia-ui-session.js.map