@jmruthers/pace-core 0.5.186 → 0.5.188

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 (290) hide show
  1. package/dist/{DataTable-IX2NBUTP.js → DataTable-GUFUNZ3N.js} +7 -7
  2. package/dist/{DataTable-Z9NLVJh0.d.ts → DataTable-IVYljGJ6.d.ts} +1 -1
  3. package/dist/{PublicPageProvider-DIzEzwKl.d.ts → PublicPageProvider-DrLDztHt.d.ts} +211 -106
  4. package/dist/{UnifiedAuthProvider-A4BCQRJY.js → UnifiedAuthProvider-643PUAIM.js} +2 -2
  5. package/dist/{api-BMFCXVQX.js → api-YP7XD5L6.js} +3 -3
  6. package/dist/{audit-WRS3KJKI.js → audit-B5P6FFIR.js} +2 -2
  7. package/dist/{chunk-HGPQUCBC.js → chunk-2UUZZJFT.js} +3 -3
  8. package/dist/{chunk-445GEP27.js → chunk-3GOZZZYH.js} +33 -8
  9. package/dist/chunk-3GOZZZYH.js.map +1 -0
  10. package/dist/{chunk-FSFQFJCU.js → chunk-63FOKYGO.js} +174 -6
  11. package/dist/chunk-63FOKYGO.js.map +1 -0
  12. package/dist/{chunk-DAGICKHT.js → chunk-DDM4CCYT.js} +3 -3
  13. package/dist/{chunk-XAUHJD3L.js → chunk-E7UAOUMY.js} +2 -2
  14. package/dist/{chunk-HDCUMOOI.js → chunk-EFCLXK7F.js} +792 -559
  15. package/dist/chunk-EFCLXK7F.js.map +1 -0
  16. package/dist/{chunk-U6WNSFX5.js → chunk-HEHYGYOX.js} +279 -44
  17. package/dist/chunk-HEHYGYOX.js.map +1 -0
  18. package/dist/{chunk-GRIQLQ52.js → chunk-IM4QE42D.js} +27 -23
  19. package/dist/chunk-IM4QE42D.js.map +1 -0
  20. package/dist/{chunk-OALXJH4Y.js → chunk-IPCH26AG.js} +8 -8
  21. package/dist/chunk-IPCH26AG.js.map +1 -0
  22. package/dist/{chunk-UQWSHFVX.js → chunk-SAUPYVLF.js} +1 -1
  23. package/dist/{chunk-UQWSHFVX.js.map → chunk-SAUPYVLF.js.map} +1 -1
  24. package/dist/{chunk-TC7D3CR3.js → chunk-UNOTYLQF.js} +556 -101
  25. package/dist/chunk-UNOTYLQF.js.map +1 -0
  26. package/dist/{chunk-FXFJRTKI.js → chunk-VGZZXKBR.js} +5 -5
  27. package/dist/chunk-VGZZXKBR.js.map +1 -0
  28. package/dist/chunk-YHCN776L.js +447 -0
  29. package/dist/chunk-YHCN776L.js.map +1 -0
  30. package/dist/components.d.ts +4 -4
  31. package/dist/components.js +12 -10
  32. package/dist/components.js.map +1 -1
  33. package/dist/{file-reference-PRTSLxKx.d.ts → file-reference-D037xOFK.d.ts} +0 -1
  34. package/dist/hooks.d.ts +221 -6
  35. package/dist/hooks.js +146 -49
  36. package/dist/hooks.js.map +1 -1
  37. package/dist/index.d.ts +24 -9
  38. package/dist/index.js +62 -28
  39. package/dist/index.js.map +1 -1
  40. package/dist/providers.js +1 -1
  41. package/dist/rbac/index.d.ts +124 -7
  42. package/dist/rbac/index.js +27 -7
  43. package/dist/{types-DUyCRSTj.d.ts → types-Bwgl--Xo.d.ts} +162 -1
  44. package/dist/types.d.ts +1 -1
  45. package/dist/types.js +1 -1
  46. package/dist/{usePublicRouteParams-D71QLlg4.d.ts → usePublicRouteParams-CTDELQ7H.d.ts} +2 -2
  47. package/dist/utils.d.ts +213 -3
  48. package/dist/utils.js +22 -2
  49. package/dist/utils.js.map +1 -1
  50. package/docs/api/classes/ColumnFactory.md +1 -1
  51. package/docs/api/classes/ErrorBoundary.md +1 -1
  52. package/docs/api/classes/InvalidScopeError.md +1 -1
  53. package/docs/api/classes/Logger.md +1 -1
  54. package/docs/api/classes/MissingUserContextError.md +1 -1
  55. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  56. package/docs/api/classes/PermissionDeniedError.md +1 -1
  57. package/docs/api/classes/RBACAuditManager.md +21 -17
  58. package/docs/api/classes/RBACCache.md +31 -23
  59. package/docs/api/classes/RBACEngine.md +5 -5
  60. package/docs/api/classes/RBACError.md +1 -1
  61. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  62. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  63. package/docs/api/classes/StorageUtils.md +1 -1
  64. package/docs/api/enums/FileCategory.md +1 -1
  65. package/docs/api/enums/LogLevel.md +1 -1
  66. package/docs/api/enums/RBACErrorCode.md +1 -1
  67. package/docs/api/enums/RPCFunction.md +1 -1
  68. package/docs/api/interfaces/AddressFieldProps.md +241 -0
  69. package/docs/api/interfaces/AddressFieldRef.md +94 -0
  70. package/docs/api/interfaces/AggregateConfig.md +1 -1
  71. package/docs/api/interfaces/AutocompleteOptions.md +75 -0
  72. package/docs/api/interfaces/BadgeProps.md +1 -1
  73. package/docs/api/interfaces/ButtonProps.md +1 -1
  74. package/docs/api/interfaces/CalendarProps.md +1 -1
  75. package/docs/api/interfaces/CardProps.md +1 -1
  76. package/docs/api/interfaces/ColorPalette.md +1 -1
  77. package/docs/api/interfaces/ColorShade.md +1 -1
  78. package/docs/api/interfaces/ComplianceResult.md +1 -1
  79. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  80. package/docs/api/interfaces/DataRecord.md +1 -1
  81. package/docs/api/interfaces/DataTableAction.md +1 -1
  82. package/docs/api/interfaces/DataTableColumn.md +1 -1
  83. package/docs/api/interfaces/DataTableProps.md +1 -1
  84. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  85. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  86. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  87. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  88. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  89. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  90. package/docs/api/interfaces/ExportColumn.md +1 -1
  91. package/docs/api/interfaces/ExportOptions.md +1 -1
  92. package/docs/api/interfaces/FileDisplayProps.md +15 -15
  93. package/docs/api/interfaces/FileMetadata.md +1 -1
  94. package/docs/api/interfaces/FileReference.md +1 -1
  95. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  96. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  97. package/docs/api/interfaces/FileUploadProps.md +1 -1
  98. package/docs/api/interfaces/FooterProps.md +1 -1
  99. package/docs/api/interfaces/FormFieldProps.md +1 -1
  100. package/docs/api/interfaces/FormProps.md +1 -1
  101. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoggerConfig.md +1 -1
  106. package/docs/api/interfaces/LoginFormProps.md +1 -1
  107. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  108. package/docs/api/interfaces/NavigationContextType.md +1 -1
  109. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  110. package/docs/api/interfaces/NavigationItem.md +1 -1
  111. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  112. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  113. package/docs/api/interfaces/Organisation.md +1 -1
  114. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  115. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  116. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  117. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  118. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  119. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  120. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  121. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  122. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  123. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  124. package/docs/api/interfaces/PaletteData.md +1 -1
  125. package/docs/api/interfaces/ParsedAddress.md +120 -0
  126. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  127. package/docs/api/interfaces/ProgressProps.md +1 -1
  128. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  131. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  132. package/docs/api/interfaces/QuickFix.md +1 -1
  133. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  134. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  135. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  136. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  137. package/docs/api/interfaces/RBACConfig.md +26 -3
  138. package/docs/api/interfaces/RBACContext.md +1 -1
  139. package/docs/api/interfaces/RBACLogger.md +5 -5
  140. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  141. package/docs/api/interfaces/RBACPerformanceMetrics.md +138 -0
  142. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  143. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  144. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  145. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  146. package/docs/api/interfaces/RBACResult.md +1 -1
  147. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  148. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  149. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  150. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  151. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  152. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  153. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  154. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  155. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  156. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  157. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  158. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  159. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  160. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  161. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  162. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  163. package/docs/api/interfaces/RouteConfig.md +1 -1
  164. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  165. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  166. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  167. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  168. package/docs/api/interfaces/SetupIssue.md +1 -1
  169. package/docs/api/interfaces/StorageConfig.md +1 -1
  170. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  171. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  172. package/docs/api/interfaces/StorageListOptions.md +1 -1
  173. package/docs/api/interfaces/StorageListResult.md +1 -1
  174. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  175. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  176. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  177. package/docs/api/interfaces/StyleImport.md +1 -1
  178. package/docs/api/interfaces/SwitchProps.md +1 -1
  179. package/docs/api/interfaces/TabsContentProps.md +1 -1
  180. package/docs/api/interfaces/TabsListProps.md +1 -1
  181. package/docs/api/interfaces/TabsProps.md +1 -1
  182. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  183. package/docs/api/interfaces/TextareaProps.md +1 -1
  184. package/docs/api/interfaces/ToastActionElement.md +1 -1
  185. package/docs/api/interfaces/ToastProps.md +1 -1
  186. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  187. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  188. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  189. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  190. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  191. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  192. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  193. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  194. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  195. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  196. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  197. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  198. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  199. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  200. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  201. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  202. package/docs/api/interfaces/UserEventAccess.md +1 -1
  203. package/docs/api/interfaces/UserMenuProps.md +1 -1
  204. package/docs/api/interfaces/UserProfile.md +1 -1
  205. package/docs/api/modules.md +318 -59
  206. package/docs/best-practices/performance.md +11 -0
  207. package/docs/getting-started/examples/README.md +2 -2
  208. package/docs/implementation-guides/file-upload-storage.md +29 -0
  209. package/docs/implementation-guides/public-pages.md +140 -1230
  210. package/docs/rbac/README.md +2 -1
  211. package/docs/rbac/api-reference.md +11 -0
  212. package/docs/rbac/performance.md +320 -0
  213. package/docs/standards/01-architecture-standard.md +5 -0
  214. package/docs/standards/05-security-standard.md +14 -0
  215. package/docs/standards/07-rbac-and-rls-standard.md +356 -0
  216. package/package.json +1 -1
  217. package/src/__tests__/public-recipe-view.test.ts +199 -0
  218. package/src/__tests__/rls-policies.test.ts +333 -0
  219. package/src/components/AddressField/AddressField.test.tsx +411 -0
  220. package/src/components/AddressField/AddressField.tsx +323 -0
  221. package/src/components/AddressField/README.md +336 -0
  222. package/src/components/AddressField/index.ts +10 -0
  223. package/src/components/AddressField/types.ts +65 -0
  224. package/src/components/FileDisplay/FileDisplay.test.tsx +454 -0
  225. package/src/components/FileDisplay/FileDisplay.tsx +28 -1
  226. package/src/components/index.ts +2 -0
  227. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +30 -5
  228. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +11 -10
  229. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +31 -6
  230. package/src/hooks/index.ts +6 -0
  231. package/src/hooks/public/usePublicFileDisplay.ts +8 -10
  232. package/src/hooks/useAddressAutocomplete.test.ts +318 -0
  233. package/src/hooks/useAddressAutocomplete.ts +268 -0
  234. package/src/hooks/useFileDisplay.ts +3 -15
  235. package/src/hooks/useFileReference.test.ts +20 -3
  236. package/src/hooks/useFileReference.ts +3 -24
  237. package/src/hooks/useFileUrlCache.ts +246 -0
  238. package/src/hooks/useInactivityTracker.ts +31 -20
  239. package/src/hooks/useOrganisationSecurity.test.ts +10 -7
  240. package/src/hooks/useOrganisationSecurity.ts +3 -3
  241. package/src/hooks/useQueryCache.ts +315 -0
  242. package/src/index.ts +2 -0
  243. package/src/providers/services/EventServiceProvider.tsx +4 -1
  244. package/src/rbac/api.test.ts +21 -6
  245. package/src/rbac/api.ts +32 -11
  246. package/src/rbac/audit-batched.ts +223 -0
  247. package/src/rbac/audit-enhanced.ts +2 -2
  248. package/src/rbac/audit.test.ts +6 -5
  249. package/src/rbac/audit.ts +34 -6
  250. package/src/rbac/cache-invalidation.ts +63 -12
  251. package/src/rbac/cache.test.ts +2 -2
  252. package/src/rbac/cache.ts +61 -14
  253. package/src/rbac/components/PagePermissionGuard.tsx +19 -10
  254. package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +248 -0
  255. package/src/rbac/config.ts +9 -0
  256. package/src/rbac/engine.ts +2 -21
  257. package/src/rbac/hooks/usePermissions.ts +21 -5
  258. package/src/rbac/index.ts +19 -0
  259. package/src/rbac/performance.ts +210 -0
  260. package/src/rbac/request-deduplication.ts +87 -0
  261. package/src/rbac/utils/deep-equal.ts +93 -0
  262. package/src/services/OrganisationService.ts +5 -4
  263. package/src/types/file-reference.ts +0 -1
  264. package/src/utils/file-reference/__tests__/file-reference.test.ts +31 -4
  265. package/src/utils/file-reference/index.ts +44 -15
  266. package/src/utils/google-places/googlePlacesUtils.test.ts +403 -0
  267. package/src/utils/google-places/googlePlacesUtils.ts +475 -0
  268. package/src/utils/google-places/index.ts +26 -0
  269. package/src/utils/google-places/loadGoogleMapsScript.ts +207 -0
  270. package/src/utils/google-places/types.ts +94 -0
  271. package/src/utils/index.ts +23 -0
  272. package/src/utils/request-deduplication.ts +165 -0
  273. package/src/utils/storage/helpers.ts +143 -4
  274. package/dist/chunk-445GEP27.js.map +0 -1
  275. package/dist/chunk-FMUCXFII.js +0 -76
  276. package/dist/chunk-FMUCXFII.js.map +0 -1
  277. package/dist/chunk-FSFQFJCU.js.map +0 -1
  278. package/dist/chunk-FXFJRTKI.js.map +0 -1
  279. package/dist/chunk-GRIQLQ52.js.map +0 -1
  280. package/dist/chunk-HDCUMOOI.js.map +0 -1
  281. package/dist/chunk-OALXJH4Y.js.map +0 -1
  282. package/dist/chunk-TC7D3CR3.js.map +0 -1
  283. package/dist/chunk-U6WNSFX5.js.map +0 -1
  284. /package/dist/{DataTable-IX2NBUTP.js.map → DataTable-GUFUNZ3N.js.map} +0 -0
  285. /package/dist/{UnifiedAuthProvider-A4BCQRJY.js.map → UnifiedAuthProvider-643PUAIM.js.map} +0 -0
  286. /package/dist/{api-BMFCXVQX.js.map → api-YP7XD5L6.js.map} +0 -0
  287. /package/dist/{audit-WRS3KJKI.js.map → audit-B5P6FFIR.js.map} +0 -0
  288. /package/dist/{chunk-HGPQUCBC.js.map → chunk-2UUZZJFT.js.map} +0 -0
  289. /package/dist/{chunk-DAGICKHT.js.map → chunk-DDM4CCYT.js.map} +0 -0
  290. /package/dist/{chunk-XAUHJD3L.js.map → chunk-E7UAOUMY.js.map} +0 -0
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useFocusManagement.ts","../src/hooks/useFocusTrap.ts","../src/hooks/useKeyboardShortcuts.ts","../src/hooks/useIsMobile.ts","../src/hooks/useDebounce.ts","../src/hooks/useDataTableState.ts","../src/hooks/usePerformanceMonitor.ts","../src/hooks/useStorage.ts"],"sourcesContent":["\nimport { useRef, useCallback, useEffect } from 'react';\n\nexport interface FocusManagementOptions {\n trapFocus?: boolean;\n autoFocus?: boolean;\n restoreFocus?: boolean;\n onEscape?: () => void;\n onFocusFirst?: () => void;\n onFocusLast?: () => void;\n}\n\nexport interface FocusManagementReturn {\n containerRef: React.RefObject<HTMLDivElement>;\n focusRef: React.RefObject<HTMLElement>;\n setFocus: (element: HTMLElement | null) => void;\n focusFirst: () => void;\n focusLast: () => void;\n trapFocus: () => void;\n releaseFocus: () => void;\n getFocusableElements: () => HTMLElement[];\n handleEscape: (callback: () => void) => () => void;\n}\n\nexport function useFocusManagement(options: FocusManagementOptions = {}): FocusManagementReturn {\n const { \n trapFocus = false, \n autoFocus = false, \n restoreFocus = false,\n onEscape,\n onFocusFirst,\n onFocusLast \n } = options;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const focusRef = useRef<HTMLElement | null>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const trapFocusActiveRef = useRef<boolean>(false);\n\n const setFocus = useCallback((element: HTMLElement | null) => {\n focusRef.current = element;\n element?.focus();\n }, []);\n\n const getFocusableElements = useCallback((): HTMLElement[] => {\n if (!containerRef.current) return [];\n\n return Array.from(\n containerRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n )\n ).filter((el) => !el.hasAttribute('disabled') && !el.hasAttribute('hidden'));\n }, []);\n\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n setFocus(elements[0]);\n onFocusFirst?.();\n }\n }, [getFocusableElements, setFocus, onFocusFirst]);\n\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n setFocus(elements[elements.length - 1]);\n onFocusLast?.();\n }\n }, [getFocusableElements, setFocus, onFocusLast]);\n\n const trapFocusMethod = useCallback(() => {\n trapFocusActiveRef.current = true;\n }, []);\n\n const releaseFocus = useCallback(() => {\n trapFocusActiveRef.current = false;\n }, []);\n\n const handleEscape = useCallback((callback: () => void) => {\n return () => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n callback();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n // Handle focus trap\n useEffect(() => {\n if (!trapFocus || !containerRef.current) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const elements = getFocusableElements();\n if (elements.length === 0) return;\n\n const firstElement = elements[0];\n const lastElement = elements[elements.length - 1];\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n const current = containerRef.current;\n current.addEventListener('keydown', handleKeyDown);\n return () => {\n current?.removeEventListener('keydown', handleKeyDown);\n };\n }, [trapFocus, onEscape, getFocusableElements]);\n\n // Handle auto focus\n useEffect(() => {\n if (autoFocus) {\n focusFirst();\n }\n }, [autoFocus, focusFirst]);\n\n // Handle focus restoration\n useEffect(() => {\n if (!restoreFocus) return;\n\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n return () => {\n if (previousFocusRef.current) {\n previousFocusRef.current.focus();\n }\n };\n }, [restoreFocus]);\n\n return {\n containerRef,\n focusRef,\n setFocus,\n focusFirst,\n focusLast,\n trapFocus: trapFocusMethod,\n releaseFocus,\n getFocusableElements,\n handleEscape,\n };\n}\n","\nimport { useRef, useEffect, useCallback } from 'react';\n\nexport interface FocusTrapOptions {\n /** Whether the focus trap is active */\n isActive?: boolean;\n /** Whether to auto-focus the first element when activated */\n autoFocus?: boolean;\n /** Whether to restore focus to the previously focused element when deactivated */\n restoreFocus?: boolean;\n /** Callback when Escape key is pressed */\n onEscape?: () => void;\n /** Selector for focusable elements (optional override) */\n focusableSelector?: string;\n}\n\nexport interface FocusTrapReturn {\n /** Ref to attach to the container element */\n containerRef: React.RefObject<HTMLElement>;\n /** Focus the first focusable element */\n focusFirst: () => void;\n /** Focus the last focusable element */\n focusLast: () => void;\n /** Get all focusable elements in the container */\n getFocusableElements: () => HTMLElement[];\n}\n\nconst DEFAULT_FOCUSABLE_SELECTOR = [\n 'button:not([disabled])',\n '[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]'\n].join(', ');\n\n/**\n * Hook for creating accessible focus traps\n * Useful for modals, dropdowns, and other overlay components\n */\nexport function useFocusTrap(options: FocusTrapOptions = {}): FocusTrapReturn {\n const {\n isActive = false,\n autoFocus = false,\n restoreFocus = false,\n onEscape,\n focusableSelector = DEFAULT_FOCUSABLE_SELECTOR\n } = options;\n\n const containerRef = useRef<HTMLElement>(null);\n const previouslyFocusedElement = useRef<HTMLElement | null>(null);\n\n const getFocusableElements = useCallback((): HTMLElement[] => {\n if (!containerRef.current) return [];\n\n return Array.from(\n containerRef.current.querySelectorAll<HTMLElement>(focusableSelector)\n ).filter((element) => {\n return (\n !element.hasAttribute('disabled') &&\n !element.hasAttribute('hidden') &&\n element.offsetParent !== null // visible check\n );\n });\n }, [focusableSelector]);\n\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[0].focus();\n }\n }, [getFocusableElements]);\n\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[elements.length - 1].focus();\n }\n }, [getFocusableElements]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive || !containerRef.current) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Handle Escape key\n if (event.key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n // Handle Tab key for focus trapping\n if (event.key === 'Tab') {\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: moving backwards\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: moving forwards\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n }\n };\n\n const container = containerRef.current;\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n }, [isActive, onEscape, getFocusableElements]);\n\n // Handle focus restoration\n useEffect(() => {\n if (!isActive) return;\n\n // Store the previously focused element\n if (restoreFocus) {\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n }\n\n // Auto-focus first element if requested\n if (autoFocus) {\n const timer = setTimeout(focusFirst, 0);\n return () => clearTimeout(timer);\n }\n\n return () => {\n // Restore focus when trap is deactivated\n if (restoreFocus && previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n previouslyFocusedElement.current = null;\n }\n };\n }, [isActive, autoFocus, restoreFocus, focusFirst]);\n\n return {\n containerRef,\n focusFirst,\n focusLast,\n getFocusableElements\n };\n}\n","import { useEffect, useCallback } from 'react';\n\nexport interface KeyboardShortcut {\n /** Key combination (e.g., 'Escape', 'Enter', 'ArrowDown', 'ctrl+s') */\n key: string;\n /** Callback function to execute */\n handler: (event: KeyboardEvent) => void;\n /** Description for documentation/help */\n description?: string;\n /** Whether the shortcut is enabled */\n enabled?: boolean;\n /** Prevent default browser behavior */\n preventDefault?: boolean;\n /** Stop event propagation */\n stopPropagation?: boolean;\n}\n\nexport interface KeyboardShortcutsOptions {\n /** Element to attach listeners to (defaults to document) */\n element?: HTMLElement | Document;\n /** Whether shortcuts are globally enabled */\n enabled?: boolean;\n}\n\n/**\n * Parse key combination string into modifier and key parts\n */\nfunction parseKeyCombo(combo: string) {\n const parts = combo.toLowerCase().split('+');\n const key = parts.pop()!;\n const modifiers = {\n ctrl: parts.includes('ctrl') || parts.includes('control'),\n alt: parts.includes('alt'),\n shift: parts.includes('shift'),\n meta: parts.includes('meta') || parts.includes('cmd')\n };\n return { key, modifiers };\n}\n\n/**\n * Check if event matches the key combination\n */\nfunction matchesKeyCombo(event: KeyboardEvent, combo: string): boolean {\n const { key, modifiers } = parseKeyCombo(combo);\n \n // Check if the main key matches\n const eventKey = event.key.toLowerCase();\n const targetKey = key.toLowerCase();\n \n if (eventKey !== targetKey) {\n return false;\n }\n \n // Check modifiers\n return (\n event.ctrlKey === modifiers.ctrl &&\n event.altKey === modifiers.alt &&\n event.shiftKey === modifiers.shift &&\n event.metaKey === modifiers.meta\n );\n}\n\n/**\n * Hook for managing keyboard shortcuts\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const shortcuts = [\n * {\n * key: 'Escape',\n * handler: () => setIsOpen(false),\n * description: 'Close modal'\n * },\n * {\n * key: 'ctrl+s',\n * handler: (e) => handleSave(),\n * description: 'Save document',\n * preventDefault: true\n * }\n * ];\n * \n * useKeyboardShortcuts(shortcuts);\n * \n * return <div>Content</div>;\n * }\n * ```\n */\nexport function useKeyboardShortcuts(\n shortcuts: KeyboardShortcut[],\n options: KeyboardShortcutsOptions = {}\n): void {\n const { element = document, enabled = true } = options;\n\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (!enabled) return;\n\n for (const shortcut of shortcuts) {\n if (shortcut.enabled === false) continue;\n\n if (matchesKeyCombo(event, shortcut.key)) {\n if (shortcut.preventDefault) {\n event.preventDefault();\n }\n if (shortcut.stopPropagation) {\n event.stopPropagation();\n }\n \n shortcut.handler(event);\n break; // Only handle first matching shortcut\n }\n }\n }, [shortcuts, enabled]);\n\n useEffect(() => {\n if (!enabled) return;\n\n element.addEventListener('keydown', handleKeyDown as EventListener);\n return () => element.removeEventListener('keydown', handleKeyDown as EventListener);\n }, [element, enabled, handleKeyDown]);\n}\n\n/**\n * Hook for common accessibility keyboard shortcuts\n */\nexport function useAccessibilityShortcuts(handlers: {\n onEscape?: () => void;\n onEnter?: () => void;\n onSpace?: () => void;\n onArrowUp?: () => void;\n onArrowDown?: () => void;\n onArrowLeft?: () => void;\n onArrowRight?: () => void;\n onHome?: () => void;\n onEnd?: () => void;\n onTab?: () => void;\n onShiftTab?: () => void;\n}) {\n const shortcuts: KeyboardShortcut[] = [];\n\n if (handlers.onEscape) {\n shortcuts.push({\n key: 'Escape',\n handler: handlers.onEscape,\n description: 'Escape/Cancel'\n });\n }\n\n if (handlers.onEnter) {\n shortcuts.push({\n key: 'Enter',\n handler: handlers.onEnter,\n description: 'Activate/Submit'\n });\n }\n\n if (handlers.onSpace) {\n shortcuts.push({\n key: ' ',\n handler: handlers.onSpace,\n description: 'Activate',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowUp) {\n shortcuts.push({\n key: 'ArrowUp',\n handler: handlers.onArrowUp,\n description: 'Navigate up',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowDown) {\n shortcuts.push({\n key: 'ArrowDown',\n handler: handlers.onArrowDown,\n description: 'Navigate down',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowLeft) {\n shortcuts.push({\n key: 'ArrowLeft',\n handler: handlers.onArrowLeft,\n description: 'Navigate left',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowRight) {\n shortcuts.push({\n key: 'ArrowRight',\n handler: handlers.onArrowRight,\n description: 'Navigate right',\n preventDefault: true\n });\n }\n\n if (handlers.onHome) {\n shortcuts.push({\n key: 'Home',\n handler: handlers.onHome,\n description: 'Go to first item',\n preventDefault: true\n });\n }\n\n if (handlers.onEnd) {\n shortcuts.push({\n key: 'End',\n handler: handlers.onEnd,\n description: 'Go to last item',\n preventDefault: true\n });\n }\n\n if (handlers.onTab) {\n shortcuts.push({\n key: 'Tab',\n handler: handlers.onTab,\n description: 'Navigate forward'\n });\n }\n\n if (handlers.onShiftTab) {\n shortcuts.push({\n key: 'shift+Tab',\n handler: handlers.onShiftTab,\n description: 'Navigate backward'\n });\n }\n\n useKeyboardShortcuts(shortcuts);\n}\n","/**\n * @file useIsMobile Hook\n * @description Hook for detecting mobile viewport using modern matchMedia API\n */\n\nimport { useState, useEffect } from 'react';\n\nconst MOBILE_BREAKPOINT = 768;\n\n/**\n * Hook to detect if the viewport is mobile-sized using matchMedia API.\n * More performant than window resize events.\n * @returns {boolean} True if mobile, false otherwise.\n */\nexport function useIsMobile(): boolean {\n const [isMobile, setIsMobile] = useState<boolean | undefined>(undefined);\n\n useEffect(() => {\n // Handle SSR case\n if (typeof window === 'undefined') {\n setIsMobile(false);\n return;\n }\n\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n \n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n\n // Set initial value\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n\n // Add event listener\n mql.addEventListener('change', onChange);\n\n // Cleanup\n return () => mql.removeEventListener('change', onChange);\n }, []);\n\n return !!isMobile;\n}\n","\nimport { useState, useEffect } from 'react';\n\nexport function useDebounce<T>(value: T, delay: number): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","/**\n * @file useDataTableState Hook\n * @description Hook for managing DataTable state\n */\n\nimport { useState, useCallback, useMemo } from 'react';\nimport type { SortingState, ColumnFiltersState, ExpandedState } from '@tanstack/react-table';\n\nexport interface DataTableState {\n sorting: SortingState;\n columnFilters: ColumnFiltersState;\n expanded: ExpandedState;\n pageSize: number;\n pageIndex: number;\n selectedRows: string[];\n}\n\nexport interface DataTableActions {\n setSorting: (sorting: SortingState) => void;\n setColumnFilters: (filters: ColumnFiltersState) => void;\n setExpanded: (expanded: ExpandedState) => void;\n setPageSize: (size: number) => void;\n setPageIndex: (index: number) => void;\n setSelectedRows: (rows: string[]) => void;\n resetState: () => void;\n}\n\nexport interface DataTableComputed {\n paginatedData: any[];\n totalPages: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n}\n\nexport interface UseDataTableStateOptions {\n initialPageSize?: number;\n data: any[];\n}\n\n/**\n * Hook for managing DataTable state\n * @param options Configuration options\n * @returns Object containing state, actions, and computed values\n */\nexport function useDataTableState(options: UseDataTableStateOptions) {\n const { initialPageSize = 10, data } = options;\n\n // State\n const [sorting, setSorting] = useState<SortingState>([]);\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [expanded, setExpanded] = useState<ExpandedState>({});\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageIndex, setPageIndex] = useState(0);\n const [selectedRows, setSelectedRows] = useState<string[]>([]);\n\n // Actions\n const resetState = useCallback(() => {\n setSorting([]);\n setColumnFilters([]);\n setExpanded({});\n setPageSize(initialPageSize);\n setPageIndex(0);\n setSelectedRows([]);\n }, [initialPageSize]);\n\n // Computed values\n const paginatedData = useMemo(() => {\n const start = pageIndex * pageSize;\n const end = start + pageSize;\n return data.slice(start, end);\n }, [data, pageIndex, pageSize]);\n\n const totalPages = useMemo(() => {\n return Math.ceil(data.length / pageSize);\n }, [data.length, pageSize]);\n\n const hasNextPage = useMemo(() => {\n return pageIndex < totalPages - 1;\n }, [pageIndex, totalPages]);\n\n const hasPreviousPage = useMemo(() => {\n return pageIndex > 0;\n }, [pageIndex]);\n\n return {\n state: {\n sorting,\n columnFilters,\n expanded,\n pageSize,\n pageIndex,\n selectedRows\n },\n actions: {\n setSorting,\n setColumnFilters,\n setExpanded,\n setPageSize,\n setPageIndex,\n setSelectedRows,\n resetState\n },\n computed: {\n paginatedData,\n totalPages,\n hasNextPage,\n hasPreviousPage\n }\n };\n}\n","\nimport { useEffect, useRef, useCallback } from 'react';\nimport { performanceBudgetMonitor, PERFORMANCE_BUDGETS } from '../utils/performance/performanceBudgets';\nimport { createLogger } from '../utils/core/logger';\n\nconst log = createLogger('usePerformanceMonitor');\n\nexport interface PerformanceMetrics {\n renderTime: number;\n componentName: string;\n timestamp: number;\n}\n\n/**\n * Hook for monitoring component performance with budget validation\n * @param componentName - Name of the component being monitored\n * @param enabled - Whether performance monitoring is enabled\n * @param budgetName - Performance budget to validate against\n */\nexport function usePerformanceMonitor(\n componentName: string, \n enabled = import.meta.env.MODE === 'development',\n budgetName: string = 'COMPONENT_RENDER'\n) {\n const renderStartTime = useRef<number>(0);\n const metrics = useRef<PerformanceMetrics[]>([]);\n\n // Start performance measurement\n const startMeasurement = useCallback(() => {\n if (!enabled) return;\n renderStartTime.current = performance.now();\n }, [enabled]);\n\n // End performance measurement with budget validation\n const endMeasurement = useCallback(() => {\n if (!enabled || renderStartTime.current === 0) return;\n \n const renderTime = performance.now() - renderStartTime.current;\n const metric: PerformanceMetrics = {\n renderTime,\n componentName,\n timestamp: Date.now()\n };\n \n metrics.current.push(metric);\n \n // Keep only last 10 measurements\n if (metrics.current.length > 10) {\n metrics.current = metrics.current.slice(-10);\n }\n \n // Validate against performance budget\n const measurement = performanceBudgetMonitor.measure(budgetName, renderTime, {\n componentName,\n renderCount: metrics.current.length\n });\n \n // Log slow renders in development\n if (!measurement.passed) {\n log.warn(\n `Performance budget exceeded in ${componentName}: ${renderTime.toFixed(2)}ms ` +\n `(budget: ${PERFORMANCE_BUDGETS[budgetName]?.threshold}ms)`\n );\n }\n \n renderStartTime.current = 0;\n }, [enabled, componentName, budgetName]);\n\n // Get performance metrics\n const getMetrics = useCallback(() => {\n return metrics.current.slice();\n }, []);\n\n // Get average render time\n const getAverageRenderTime = useCallback(() => {\n if (metrics.current.length === 0) return 0;\n \n const total = metrics.current.reduce((sum, metric) => sum + metric.renderTime, 0);\n return total / metrics.current.length;\n }, []);\n\n // Get performance budget status\n const getBudgetStatus = useCallback(() => {\n const budget = PERFORMANCE_BUDGETS[budgetName];\n if (!budget) return null;\n\n const averageTime = getAverageRenderTime();\n return {\n budget: budget.threshold,\n average: averageTime,\n passed: averageTime <= budget.threshold,\n efficiency: budget.threshold > 0 ? (budget.threshold - averageTime) / budget.threshold : 0\n };\n }, [budgetName, getAverageRenderTime]);\n\n // Start measurement on every render\n useEffect(() => {\n startMeasurement();\n return endMeasurement;\n });\n\n return {\n getMetrics,\n getAverageRenderTime,\n getBudgetStatus,\n startMeasurement,\n endMeasurement\n };\n}\n\n// Hook for measuring specific operations\nexport function useOperationPerformance(operationName: string, budgetName?: string) {\n const measureOperation = useCallback(async <T>(\n operation: () => Promise<T> | T,\n context?: Record<string, any>\n ): Promise<T> => {\n const start = performance.now();\n const result = await operation();\n const duration = performance.now() - start;\n \n const budget = budgetName || 'COMPONENT_RENDER';\n performanceBudgetMonitor.measure(budget, duration, {\n operation: operationName,\n ...context\n });\n \n return result;\n }, [operationName, budgetName]);\n\n return { measureOperation };\n}\n","/**\n * React hook for storage operations\n */\n\nimport { useState, useCallback } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n StorageUploadOptions, \n StorageUploadResult, \n StorageFileInfo,\n StorageListOptions,\n StorageListResult,\n uploadFile,\n getPublicUrl,\n getSignedUrl,\n deleteFile,\n listFiles,\n archiveFile\n} from '../utils/storage';\nimport { createLogger } from '../utils/core/logger';\n\nconst log = createLogger('useStorage');\n\nexport interface UseStorageOptions {\n supabase: SupabaseClient;\n appName: string;\n orgId: string;\n}\n\nexport interface UseStorageReturn {\n // Upload\n uploadFile: (file: File, options?: Partial<StorageUploadOptions>) => Promise<StorageUploadResult>;\n isUploading: boolean;\n uploadError: string | null;\n \n // URLs\n getPublicUrl: (path: string) => string;\n getSignedUrl: (path: string, expiresIn?: number) => Promise<string | null>;\n getFileUrl: (path: string) => string; // Alias for getPublicUrl\n \n // File management\n deleteFile: (path: string) => Promise<{ success: boolean; error?: string }>;\n archiveFile: (path: string) => Promise<{ success: boolean; error?: string }>;\n \n // Listing\n listFiles: (options?: Partial<StorageListOptions>) => Promise<StorageListResult>;\n isListing: boolean;\n listError: string | null;\n isLoading: boolean; // Alias for isListing\n error: string | null; // Alias for listError\n \n // State\n files: StorageFileInfo[];\n refreshFiles: () => Promise<void>;\n}\n\n/**\n * Hook for storage operations with app and organisation context\n */\nexport function useStorage({ supabase, appName, orgId }: UseStorageOptions): UseStorageReturn {\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [isListing, setIsListing] = useState(false);\n const [listError, setListError] = useState<string | null>(null);\n const [files, setFiles] = useState<StorageFileInfo[]>([]);\n\n // Upload file\n const handleUploadFile = useCallback(async (\n file: File, \n options: Partial<StorageUploadOptions> = {}\n ): Promise<StorageUploadResult> => {\n setIsUploading(true);\n setUploadError(null);\n\n try {\n const uploadOptions: StorageUploadOptions = {\n appName,\n orgId,\n isPublic: false,\n ...options\n };\n\n const result = await uploadFile(supabase, file, uploadOptions);\n \n if (result.success) {\n // Refresh file list\n await refreshFiles();\n } else {\n setUploadError(result.error || 'Upload failed');\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Upload failed';\n setUploadError(errorMessage);\n return {\n success: false,\n error: errorMessage\n };\n } finally {\n setIsUploading(false);\n }\n }, [supabase, appName, orgId]);\n\n // Get public URL\n const handleGetPublicUrl = useCallback((path: string): string => {\n return getPublicUrl(supabase, path);\n }, [supabase]);\n\n // Get signed URL\n const handleGetSignedUrl = useCallback(async (\n path: string, \n expiresIn?: number\n ): Promise<string | null> => {\n try {\n const result = await getSignedUrl(supabase, path, {\n appName,\n orgId,\n expiresIn\n });\n return result?.url || null;\n } catch (error) {\n log.error('Failed to get signed URL:', error);\n return null;\n }\n }, [supabase, appName, orgId]);\n\n // Delete file\n const handleDeleteFile = useCallback(async (path: string) => {\n try {\n const result = await deleteFile(supabase, path);\n if (result.success) {\n await refreshFiles();\n }\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Delete failed'\n };\n }\n }, [supabase]);\n\n // Archive file\n const handleArchiveFile = useCallback(async (path: string) => {\n try {\n const result = await archiveFile(supabase, path, { appName, orgId });\n if (result.success) {\n await refreshFiles();\n }\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Archive failed'\n };\n }\n }, [supabase, appName, orgId]);\n\n // List files\n const handleListFiles = useCallback(async (\n options: Partial<StorageListOptions> = {}\n ): Promise<StorageListResult> => {\n setIsListing(true);\n setListError(null);\n\n try {\n const listOptions: StorageListOptions = {\n appName,\n orgId,\n ...options\n };\n\n const result = await listFiles(supabase, listOptions);\n setFiles(result.files);\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'List failed';\n setListError(errorMessage);\n return { files: [], totalCount: 0, hasMore: false };\n } finally {\n setIsListing(false);\n }\n }, [supabase, appName, orgId]);\n\n // Refresh files\n const refreshFiles = useCallback(async () => {\n await handleListFiles();\n }, [handleListFiles]);\n\n return {\n // Upload\n uploadFile: handleUploadFile,\n isUploading,\n uploadError,\n \n // URLs\n getPublicUrl: handleGetPublicUrl,\n getSignedUrl: handleGetSignedUrl,\n getFileUrl: handleGetPublicUrl, // Alias for getPublicUrl\n \n // File management\n deleteFile: handleDeleteFile,\n archiveFile: handleArchiveFile,\n \n // Listing\n listFiles: handleListFiles,\n isListing,\n listError,\n isLoading: isListing, // Alias for isListing\n error: listError, // Alias for listError\n \n // State\n files,\n refreshFiles\n };\n}\n\n/**\n * Hook for file upload with progress tracking\n */\nexport function useFileUpload({ supabase, appName, orgId }: UseStorageOptions) {\n const [uploadProgress, setUploadProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n\n const uploadWithProgress = useCallback(async (\n file: File,\n options: Partial<StorageUploadOptions> = {}\n ): Promise<StorageUploadResult> => {\n setIsUploading(true);\n setUploadProgress(0);\n setUploadError(null);\n\n try {\n // Simulate progress (Supabase doesn't provide real progress)\n const progressInterval = setInterval(() => {\n setUploadProgress(prev => Math.min(prev + 10, 90));\n }, 100);\n\n const uploadOptions: StorageUploadOptions = {\n appName,\n orgId,\n isPublic: false,\n ...options\n };\n\n const result = await uploadFile(supabase, file, uploadOptions);\n \n clearInterval(progressInterval);\n setUploadProgress(100);\n\n if (!result.success) {\n setUploadError(result.error || 'Upload failed');\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Upload failed';\n setUploadError(errorMessage);\n return {\n success: false,\n error: errorMessage\n };\n } finally {\n setIsUploading(false);\n setTimeout(() => setUploadProgress(0), 1000);\n }\n }, [supabase, appName, orgId]);\n\n return {\n uploadWithProgress,\n uploadProgress,\n isUploading,\n uploadError\n };\n}\n"],"mappings":"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","names":["useRef","useEffect","useCallback","useEffect","useCallback","useEffect","useState","useEffect","useState","useCallback","useEffect","useRef","useCallback","useRef","useCallback","useEffect","useState","useCallback","log","useState","useCallback"]}
1
+ {"version":3,"sources":["../src/hooks/useFocusManagement.ts","../src/hooks/useFocusTrap.ts","../src/hooks/useKeyboardShortcuts.ts","../src/hooks/useIsMobile.ts","../src/hooks/useDataTableState.ts","../src/hooks/usePerformanceMonitor.ts","../src/hooks/useFileUrlCache.ts","../src/hooks/useStorage.ts"],"sourcesContent":["\nimport { useRef, useCallback, useEffect } from 'react';\n\nexport interface FocusManagementOptions {\n trapFocus?: boolean;\n autoFocus?: boolean;\n restoreFocus?: boolean;\n onEscape?: () => void;\n onFocusFirst?: () => void;\n onFocusLast?: () => void;\n}\n\nexport interface FocusManagementReturn {\n containerRef: React.RefObject<HTMLDivElement>;\n focusRef: React.RefObject<HTMLElement>;\n setFocus: (element: HTMLElement | null) => void;\n focusFirst: () => void;\n focusLast: () => void;\n trapFocus: () => void;\n releaseFocus: () => void;\n getFocusableElements: () => HTMLElement[];\n handleEscape: (callback: () => void) => () => void;\n}\n\nexport function useFocusManagement(options: FocusManagementOptions = {}): FocusManagementReturn {\n const { \n trapFocus = false, \n autoFocus = false, \n restoreFocus = false,\n onEscape,\n onFocusFirst,\n onFocusLast \n } = options;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const focusRef = useRef<HTMLElement | null>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const trapFocusActiveRef = useRef<boolean>(false);\n\n const setFocus = useCallback((element: HTMLElement | null) => {\n focusRef.current = element;\n element?.focus();\n }, []);\n\n const getFocusableElements = useCallback((): HTMLElement[] => {\n if (!containerRef.current) return [];\n\n return Array.from(\n containerRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n )\n ).filter((el) => !el.hasAttribute('disabled') && !el.hasAttribute('hidden'));\n }, []);\n\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n setFocus(elements[0]);\n onFocusFirst?.();\n }\n }, [getFocusableElements, setFocus, onFocusFirst]);\n\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n setFocus(elements[elements.length - 1]);\n onFocusLast?.();\n }\n }, [getFocusableElements, setFocus, onFocusLast]);\n\n const trapFocusMethod = useCallback(() => {\n trapFocusActiveRef.current = true;\n }, []);\n\n const releaseFocus = useCallback(() => {\n trapFocusActiveRef.current = false;\n }, []);\n\n const handleEscape = useCallback((callback: () => void) => {\n return () => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n callback();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n };\n }, []);\n\n // Handle focus trap\n useEffect(() => {\n if (!trapFocus || !containerRef.current) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const elements = getFocusableElements();\n if (elements.length === 0) return;\n\n const firstElement = elements[0];\n const lastElement = elements[elements.length - 1];\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n const current = containerRef.current;\n current.addEventListener('keydown', handleKeyDown);\n return () => {\n current?.removeEventListener('keydown', handleKeyDown);\n };\n }, [trapFocus, onEscape, getFocusableElements]);\n\n // Handle auto focus\n useEffect(() => {\n if (autoFocus) {\n focusFirst();\n }\n }, [autoFocus, focusFirst]);\n\n // Handle focus restoration\n useEffect(() => {\n if (!restoreFocus) return;\n\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n return () => {\n if (previousFocusRef.current) {\n previousFocusRef.current.focus();\n }\n };\n }, [restoreFocus]);\n\n return {\n containerRef,\n focusRef,\n setFocus,\n focusFirst,\n focusLast,\n trapFocus: trapFocusMethod,\n releaseFocus,\n getFocusableElements,\n handleEscape,\n };\n}\n","\nimport { useRef, useEffect, useCallback } from 'react';\n\nexport interface FocusTrapOptions {\n /** Whether the focus trap is active */\n isActive?: boolean;\n /** Whether to auto-focus the first element when activated */\n autoFocus?: boolean;\n /** Whether to restore focus to the previously focused element when deactivated */\n restoreFocus?: boolean;\n /** Callback when Escape key is pressed */\n onEscape?: () => void;\n /** Selector for focusable elements (optional override) */\n focusableSelector?: string;\n}\n\nexport interface FocusTrapReturn {\n /** Ref to attach to the container element */\n containerRef: React.RefObject<HTMLElement>;\n /** Focus the first focusable element */\n focusFirst: () => void;\n /** Focus the last focusable element */\n focusLast: () => void;\n /** Get all focusable elements in the container */\n getFocusableElements: () => HTMLElement[];\n}\n\nconst DEFAULT_FOCUSABLE_SELECTOR = [\n 'button:not([disabled])',\n '[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]'\n].join(', ');\n\n/**\n * Hook for creating accessible focus traps\n * Useful for modals, dropdowns, and other overlay components\n */\nexport function useFocusTrap(options: FocusTrapOptions = {}): FocusTrapReturn {\n const {\n isActive = false,\n autoFocus = false,\n restoreFocus = false,\n onEscape,\n focusableSelector = DEFAULT_FOCUSABLE_SELECTOR\n } = options;\n\n const containerRef = useRef<HTMLElement>(null);\n const previouslyFocusedElement = useRef<HTMLElement | null>(null);\n\n const getFocusableElements = useCallback((): HTMLElement[] => {\n if (!containerRef.current) return [];\n\n return Array.from(\n containerRef.current.querySelectorAll<HTMLElement>(focusableSelector)\n ).filter((element) => {\n return (\n !element.hasAttribute('disabled') &&\n !element.hasAttribute('hidden') &&\n element.offsetParent !== null // visible check\n );\n });\n }, [focusableSelector]);\n\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[0].focus();\n }\n }, [getFocusableElements]);\n\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[elements.length - 1].focus();\n }\n }, [getFocusableElements]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive || !containerRef.current) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Handle Escape key\n if (event.key === 'Escape' && onEscape) {\n onEscape();\n return;\n }\n\n // Handle Tab key for focus trapping\n if (event.key === 'Tab') {\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: moving backwards\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: moving forwards\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n }\n };\n\n const container = containerRef.current;\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n }, [isActive, onEscape, getFocusableElements]);\n\n // Handle focus restoration\n useEffect(() => {\n if (!isActive) return;\n\n // Store the previously focused element\n if (restoreFocus) {\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n }\n\n // Auto-focus first element if requested\n if (autoFocus) {\n const timer = setTimeout(focusFirst, 0);\n return () => clearTimeout(timer);\n }\n\n return () => {\n // Restore focus when trap is deactivated\n if (restoreFocus && previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n previouslyFocusedElement.current = null;\n }\n };\n }, [isActive, autoFocus, restoreFocus, focusFirst]);\n\n return {\n containerRef,\n focusFirst,\n focusLast,\n getFocusableElements\n };\n}\n","import { useEffect, useCallback } from 'react';\n\nexport interface KeyboardShortcut {\n /** Key combination (e.g., 'Escape', 'Enter', 'ArrowDown', 'ctrl+s') */\n key: string;\n /** Callback function to execute */\n handler: (event: KeyboardEvent) => void;\n /** Description for documentation/help */\n description?: string;\n /** Whether the shortcut is enabled */\n enabled?: boolean;\n /** Prevent default browser behavior */\n preventDefault?: boolean;\n /** Stop event propagation */\n stopPropagation?: boolean;\n}\n\nexport interface KeyboardShortcutsOptions {\n /** Element to attach listeners to (defaults to document) */\n element?: HTMLElement | Document;\n /** Whether shortcuts are globally enabled */\n enabled?: boolean;\n}\n\n/**\n * Parse key combination string into modifier and key parts\n */\nfunction parseKeyCombo(combo: string) {\n const parts = combo.toLowerCase().split('+');\n const key = parts.pop()!;\n const modifiers = {\n ctrl: parts.includes('ctrl') || parts.includes('control'),\n alt: parts.includes('alt'),\n shift: parts.includes('shift'),\n meta: parts.includes('meta') || parts.includes('cmd')\n };\n return { key, modifiers };\n}\n\n/**\n * Check if event matches the key combination\n */\nfunction matchesKeyCombo(event: KeyboardEvent, combo: string): boolean {\n const { key, modifiers } = parseKeyCombo(combo);\n \n // Check if the main key matches\n const eventKey = event.key.toLowerCase();\n const targetKey = key.toLowerCase();\n \n if (eventKey !== targetKey) {\n return false;\n }\n \n // Check modifiers\n return (\n event.ctrlKey === modifiers.ctrl &&\n event.altKey === modifiers.alt &&\n event.shiftKey === modifiers.shift &&\n event.metaKey === modifiers.meta\n );\n}\n\n/**\n * Hook for managing keyboard shortcuts\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const shortcuts = [\n * {\n * key: 'Escape',\n * handler: () => setIsOpen(false),\n * description: 'Close modal'\n * },\n * {\n * key: 'ctrl+s',\n * handler: (e) => handleSave(),\n * description: 'Save document',\n * preventDefault: true\n * }\n * ];\n * \n * useKeyboardShortcuts(shortcuts);\n * \n * return <div>Content</div>;\n * }\n * ```\n */\nexport function useKeyboardShortcuts(\n shortcuts: KeyboardShortcut[],\n options: KeyboardShortcutsOptions = {}\n): void {\n const { element = document, enabled = true } = options;\n\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (!enabled) return;\n\n for (const shortcut of shortcuts) {\n if (shortcut.enabled === false) continue;\n\n if (matchesKeyCombo(event, shortcut.key)) {\n if (shortcut.preventDefault) {\n event.preventDefault();\n }\n if (shortcut.stopPropagation) {\n event.stopPropagation();\n }\n \n shortcut.handler(event);\n break; // Only handle first matching shortcut\n }\n }\n }, [shortcuts, enabled]);\n\n useEffect(() => {\n if (!enabled) return;\n\n element.addEventListener('keydown', handleKeyDown as EventListener);\n return () => element.removeEventListener('keydown', handleKeyDown as EventListener);\n }, [element, enabled, handleKeyDown]);\n}\n\n/**\n * Hook for common accessibility keyboard shortcuts\n */\nexport function useAccessibilityShortcuts(handlers: {\n onEscape?: () => void;\n onEnter?: () => void;\n onSpace?: () => void;\n onArrowUp?: () => void;\n onArrowDown?: () => void;\n onArrowLeft?: () => void;\n onArrowRight?: () => void;\n onHome?: () => void;\n onEnd?: () => void;\n onTab?: () => void;\n onShiftTab?: () => void;\n}) {\n const shortcuts: KeyboardShortcut[] = [];\n\n if (handlers.onEscape) {\n shortcuts.push({\n key: 'Escape',\n handler: handlers.onEscape,\n description: 'Escape/Cancel'\n });\n }\n\n if (handlers.onEnter) {\n shortcuts.push({\n key: 'Enter',\n handler: handlers.onEnter,\n description: 'Activate/Submit'\n });\n }\n\n if (handlers.onSpace) {\n shortcuts.push({\n key: ' ',\n handler: handlers.onSpace,\n description: 'Activate',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowUp) {\n shortcuts.push({\n key: 'ArrowUp',\n handler: handlers.onArrowUp,\n description: 'Navigate up',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowDown) {\n shortcuts.push({\n key: 'ArrowDown',\n handler: handlers.onArrowDown,\n description: 'Navigate down',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowLeft) {\n shortcuts.push({\n key: 'ArrowLeft',\n handler: handlers.onArrowLeft,\n description: 'Navigate left',\n preventDefault: true\n });\n }\n\n if (handlers.onArrowRight) {\n shortcuts.push({\n key: 'ArrowRight',\n handler: handlers.onArrowRight,\n description: 'Navigate right',\n preventDefault: true\n });\n }\n\n if (handlers.onHome) {\n shortcuts.push({\n key: 'Home',\n handler: handlers.onHome,\n description: 'Go to first item',\n preventDefault: true\n });\n }\n\n if (handlers.onEnd) {\n shortcuts.push({\n key: 'End',\n handler: handlers.onEnd,\n description: 'Go to last item',\n preventDefault: true\n });\n }\n\n if (handlers.onTab) {\n shortcuts.push({\n key: 'Tab',\n handler: handlers.onTab,\n description: 'Navigate forward'\n });\n }\n\n if (handlers.onShiftTab) {\n shortcuts.push({\n key: 'shift+Tab',\n handler: handlers.onShiftTab,\n description: 'Navigate backward'\n });\n }\n\n useKeyboardShortcuts(shortcuts);\n}\n","/**\n * @file useIsMobile Hook\n * @description Hook for detecting mobile viewport using modern matchMedia API\n */\n\nimport { useState, useEffect } from 'react';\n\nconst MOBILE_BREAKPOINT = 768;\n\n/**\n * Hook to detect if the viewport is mobile-sized using matchMedia API.\n * More performant than window resize events.\n * @returns {boolean} True if mobile, false otherwise.\n */\nexport function useIsMobile(): boolean {\n const [isMobile, setIsMobile] = useState<boolean | undefined>(undefined);\n\n useEffect(() => {\n // Handle SSR case\n if (typeof window === 'undefined') {\n setIsMobile(false);\n return;\n }\n\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n \n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n\n // Set initial value\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n\n // Add event listener\n mql.addEventListener('change', onChange);\n\n // Cleanup\n return () => mql.removeEventListener('change', onChange);\n }, []);\n\n return !!isMobile;\n}\n","/**\n * @file useDataTableState Hook\n * @description Hook for managing DataTable state\n */\n\nimport { useState, useCallback, useMemo } from 'react';\nimport type { SortingState, ColumnFiltersState, ExpandedState } from '@tanstack/react-table';\n\nexport interface DataTableState {\n sorting: SortingState;\n columnFilters: ColumnFiltersState;\n expanded: ExpandedState;\n pageSize: number;\n pageIndex: number;\n selectedRows: string[];\n}\n\nexport interface DataTableActions {\n setSorting: (sorting: SortingState) => void;\n setColumnFilters: (filters: ColumnFiltersState) => void;\n setExpanded: (expanded: ExpandedState) => void;\n setPageSize: (size: number) => void;\n setPageIndex: (index: number) => void;\n setSelectedRows: (rows: string[]) => void;\n resetState: () => void;\n}\n\nexport interface DataTableComputed {\n paginatedData: any[];\n totalPages: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n}\n\nexport interface UseDataTableStateOptions {\n initialPageSize?: number;\n data: any[];\n}\n\n/**\n * Hook for managing DataTable state\n * @param options Configuration options\n * @returns Object containing state, actions, and computed values\n */\nexport function useDataTableState(options: UseDataTableStateOptions) {\n const { initialPageSize = 10, data } = options;\n\n // State\n const [sorting, setSorting] = useState<SortingState>([]);\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [expanded, setExpanded] = useState<ExpandedState>({});\n const [pageSize, setPageSize] = useState(initialPageSize);\n const [pageIndex, setPageIndex] = useState(0);\n const [selectedRows, setSelectedRows] = useState<string[]>([]);\n\n // Actions\n const resetState = useCallback(() => {\n setSorting([]);\n setColumnFilters([]);\n setExpanded({});\n setPageSize(initialPageSize);\n setPageIndex(0);\n setSelectedRows([]);\n }, [initialPageSize]);\n\n // Computed values\n const paginatedData = useMemo(() => {\n const start = pageIndex * pageSize;\n const end = start + pageSize;\n return data.slice(start, end);\n }, [data, pageIndex, pageSize]);\n\n const totalPages = useMemo(() => {\n return Math.ceil(data.length / pageSize);\n }, [data.length, pageSize]);\n\n const hasNextPage = useMemo(() => {\n return pageIndex < totalPages - 1;\n }, [pageIndex, totalPages]);\n\n const hasPreviousPage = useMemo(() => {\n return pageIndex > 0;\n }, [pageIndex]);\n\n return {\n state: {\n sorting,\n columnFilters,\n expanded,\n pageSize,\n pageIndex,\n selectedRows\n },\n actions: {\n setSorting,\n setColumnFilters,\n setExpanded,\n setPageSize,\n setPageIndex,\n setSelectedRows,\n resetState\n },\n computed: {\n paginatedData,\n totalPages,\n hasNextPage,\n hasPreviousPage\n }\n };\n}\n","\nimport { useEffect, useRef, useCallback } from 'react';\nimport { performanceBudgetMonitor, PERFORMANCE_BUDGETS } from '../utils/performance/performanceBudgets';\nimport { createLogger } from '../utils/core/logger';\n\nconst log = createLogger('usePerformanceMonitor');\n\nexport interface PerformanceMetrics {\n renderTime: number;\n componentName: string;\n timestamp: number;\n}\n\n/**\n * Hook for monitoring component performance with budget validation\n * @param componentName - Name of the component being monitored\n * @param enabled - Whether performance monitoring is enabled\n * @param budgetName - Performance budget to validate against\n */\nexport function usePerformanceMonitor(\n componentName: string, \n enabled = import.meta.env.MODE === 'development',\n budgetName: string = 'COMPONENT_RENDER'\n) {\n const renderStartTime = useRef<number>(0);\n const metrics = useRef<PerformanceMetrics[]>([]);\n\n // Start performance measurement\n const startMeasurement = useCallback(() => {\n if (!enabled) return;\n renderStartTime.current = performance.now();\n }, [enabled]);\n\n // End performance measurement with budget validation\n const endMeasurement = useCallback(() => {\n if (!enabled || renderStartTime.current === 0) return;\n \n const renderTime = performance.now() - renderStartTime.current;\n const metric: PerformanceMetrics = {\n renderTime,\n componentName,\n timestamp: Date.now()\n };\n \n metrics.current.push(metric);\n \n // Keep only last 10 measurements\n if (metrics.current.length > 10) {\n metrics.current = metrics.current.slice(-10);\n }\n \n // Validate against performance budget\n const measurement = performanceBudgetMonitor.measure(budgetName, renderTime, {\n componentName,\n renderCount: metrics.current.length\n });\n \n // Log slow renders in development\n if (!measurement.passed) {\n log.warn(\n `Performance budget exceeded in ${componentName}: ${renderTime.toFixed(2)}ms ` +\n `(budget: ${PERFORMANCE_BUDGETS[budgetName]?.threshold}ms)`\n );\n }\n \n renderStartTime.current = 0;\n }, [enabled, componentName, budgetName]);\n\n // Get performance metrics\n const getMetrics = useCallback(() => {\n return metrics.current.slice();\n }, []);\n\n // Get average render time\n const getAverageRenderTime = useCallback(() => {\n if (metrics.current.length === 0) return 0;\n \n const total = metrics.current.reduce((sum, metric) => sum + metric.renderTime, 0);\n return total / metrics.current.length;\n }, []);\n\n // Get performance budget status\n const getBudgetStatus = useCallback(() => {\n const budget = PERFORMANCE_BUDGETS[budgetName];\n if (!budget) return null;\n\n const averageTime = getAverageRenderTime();\n return {\n budget: budget.threshold,\n average: averageTime,\n passed: averageTime <= budget.threshold,\n efficiency: budget.threshold > 0 ? (budget.threshold - averageTime) / budget.threshold : 0\n };\n }, [budgetName, getAverageRenderTime]);\n\n // Start measurement on every render\n useEffect(() => {\n startMeasurement();\n return endMeasurement;\n });\n\n return {\n getMetrics,\n getAverageRenderTime,\n getBudgetStatus,\n startMeasurement,\n endMeasurement\n };\n}\n\n// Hook for measuring specific operations\nexport function useOperationPerformance(operationName: string, budgetName?: string) {\n const measureOperation = useCallback(async <T>(\n operation: () => Promise<T> | T,\n context?: Record<string, any>\n ): Promise<T> => {\n const start = performance.now();\n const result = await operation();\n const duration = performance.now() - start;\n \n const budget = budgetName || 'COMPONENT_RENDER';\n performanceBudgetMonitor.measure(budget, duration, {\n operation: operationName,\n ...context\n });\n \n return result;\n }, [operationName, budgetName]);\n\n return { measureOperation };\n}\n","/**\n * @file File URL Cache Hook\n * @package @jmruthers/pace-core\n * @module Hooks\n *\n * Centralized caching hook for file URLs to prevent duplicate requests\n * and improve performance across components.\n *\n * Features:\n * - TTL-based caching matching signed URL expiration (3600s)\n * - Automatic cache cleanup\n * - Supports both public and signed URLs\n * - Thread-safe cache operations\n *\n * @example\n * ```tsx\n * import { useFileUrlCache } from '@jmruthers/pace-core';\n *\n * function MyComponent() {\n * const { getUrl, setUrl, clearCache } = useFileUrlCache();\n *\n * const url = await getUrl(fileReference, supabase, organisationId);\n * return <img src={url} alt=\"File\" />;\n * }\n * ```\n */\n\nimport { useRef, useCallback } from 'react';\nimport type { SupabaseClient } from '@supabase/supabase-js';\nimport { FileReference } from '../types/file-reference';\nimport { getPublicUrl, getSignedUrl } from '../utils/storage/helpers';\n\ninterface CachedUrl {\n url: string;\n expiresAt: number; // Timestamp in milliseconds\n}\n\n// Global cache shared across all hook instances\nconst globalUrlCache = new Map<string, CachedUrl>();\n\n// Cache size limit to prevent memory leaks\nconst MAX_CACHE_SIZE = 500;\n\n// Default TTL matches signed URL expiration (3600 seconds = 1 hour)\nconst DEFAULT_TTL_MS = 3600 * 1000;\n\n/**\n * Generate cache key from file reference\n */\nfunction getCacheKey(fileReference: FileReference): string {\n return `file-url:${fileReference.id}:${fileReference.is_public ? 'public' : 'private'}`;\n}\n\n/**\n * Clean up expired entries and enforce size limit\n */\nfunction cleanupCache(): void {\n const now = Date.now();\n \n // Remove expired entries\n for (const [key, value] of globalUrlCache.entries()) {\n if (value.expiresAt < now) {\n globalUrlCache.delete(key);\n }\n }\n \n // Enforce size limit by removing oldest entries\n if (globalUrlCache.size > MAX_CACHE_SIZE) {\n const entries = Array.from(globalUrlCache.entries());\n // Sort by expiration time (oldest first)\n entries.sort((a, b) => a[1].expiresAt - b[1].expiresAt);\n \n // Remove oldest 20% of entries\n const toRemove = Math.floor(MAX_CACHE_SIZE * 0.2);\n for (let i = 0; i < toRemove && i < entries.length; i++) {\n globalUrlCache.delete(entries[i][0]);\n }\n }\n}\n\nexport interface UseFileUrlCacheReturn {\n /**\n * Get URL for a file reference, using cache if available\n * @param fileReference - File reference to get URL for\n * @param supabase - Supabase client instance\n * @param organisationId - Organisation ID for signed URLs\n * @param ttl - Time to live in milliseconds (default: 3600000 = 1 hour)\n * @returns Promise resolving to URL string or null\n */\n getUrl: (\n fileReference: FileReference,\n supabase: SupabaseClient,\n organisationId: string,\n ttl?: number\n ) => Promise<string | null>;\n \n /**\n * Set URL in cache\n * @param fileReference - File reference\n * @param url - URL to cache\n * @param ttl - Time to live in milliseconds (default: 3600000 = 1 hour)\n */\n setUrl: (fileReference: FileReference, url: string, ttl?: number) => void;\n \n /**\n * Get URL from cache without generating if missing\n * @param fileReference - File reference\n * @returns Cached URL or null if not in cache or expired\n */\n getCachedUrl: (fileReference: FileReference) => string | null;\n \n /**\n * Clear cache for a specific file reference\n * @param fileReference - File reference to clear\n */\n clearFile: (fileReference: FileReference) => void;\n \n /**\n * Clear all cached URLs\n */\n clearCache: () => void;\n \n /**\n * Get cache statistics\n */\n getCacheStats: () => { size: number; maxSize: number };\n}\n\n/**\n * Hook for centralized file URL caching\n * \n * This hook provides a shared cache for file URLs across all components,\n * preventing duplicate requests for the same file.\n * \n * @returns Cache operations and utilities\n */\nexport function useFileUrlCache(): UseFileUrlCacheReturn {\n // Use ref to ensure stable reference across renders\n const cleanupIntervalRef = useRef<number | null>(null);\n \n // Set up periodic cleanup (every 5 minutes)\n if (cleanupIntervalRef.current === null && typeof window !== 'undefined') {\n cleanupIntervalRef.current = window.setInterval(() => {\n cleanupCache();\n }, 5 * 60 * 1000); // 5 minutes\n }\n \n const getUrl = useCallback(async (\n fileReference: FileReference,\n supabase: SupabaseClient,\n organisationId: string,\n ttl: number = DEFAULT_TTL_MS\n ): Promise<string | null> => {\n const cacheKey = getCacheKey(fileReference);\n const cached = globalUrlCache.get(cacheKey);\n const now = Date.now();\n \n // Return cached URL if still valid\n if (cached && cached.expiresAt > now) {\n return cached.url;\n }\n \n // Generate new URL\n let url: string | null = null;\n \n try {\n if (fileReference.is_public) {\n // Public files: generate public URL (synchronous)\n url = getPublicUrl(supabase, fileReference.file_path, true);\n } else {\n // Private files: generate signed URL (async)\n const signedUrlResult = await getSignedUrl(supabase, fileReference.file_path, {\n appName: 'pace-core',\n orgId: organisationId,\n expiresIn: Math.floor(ttl / 1000) // Convert ms to seconds\n });\n url = signedUrlResult?.url || null;\n }\n \n // Cache the URL if generated successfully\n if (url) {\n globalUrlCache.set(cacheKey, {\n url,\n expiresAt: now + ttl\n });\n cleanupCache(); // Clean up after adding\n }\n \n return url;\n } catch (error) {\n console.error('Failed to generate file URL:', error);\n return null;\n }\n }, []);\n \n const setUrl = useCallback((\n fileReference: FileReference,\n url: string,\n ttl: number = DEFAULT_TTL_MS\n ): void => {\n const cacheKey = getCacheKey(fileReference);\n globalUrlCache.set(cacheKey, {\n url,\n expiresAt: Date.now() + ttl\n });\n cleanupCache();\n }, []);\n \n const getCachedUrl = useCallback((fileReference: FileReference): string | null => {\n const cacheKey = getCacheKey(fileReference);\n const cached = globalUrlCache.get(cacheKey);\n const now = Date.now();\n \n if (cached && cached.expiresAt > now) {\n return cached.url;\n }\n \n return null;\n }, []);\n \n const clearFile = useCallback((fileReference: FileReference): void => {\n const cacheKey = getCacheKey(fileReference);\n globalUrlCache.delete(cacheKey);\n }, []);\n \n const clearCache = useCallback((): void => {\n globalUrlCache.clear();\n }, []);\n \n const getCacheStats = useCallback(() => {\n return {\n size: globalUrlCache.size,\n maxSize: MAX_CACHE_SIZE\n };\n }, []);\n \n return {\n getUrl,\n setUrl,\n getCachedUrl,\n clearFile,\n clearCache,\n getCacheStats\n };\n}\n\n","/**\n * React hook for storage operations\n */\n\nimport { useState, useCallback } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n StorageUploadOptions, \n StorageUploadResult, \n StorageFileInfo,\n StorageListOptions,\n StorageListResult,\n uploadFile,\n getPublicUrl,\n getSignedUrl,\n deleteFile,\n listFiles,\n archiveFile\n} from '../utils/storage';\nimport { createLogger } from '../utils/core/logger';\n\nconst log = createLogger('useStorage');\n\nexport interface UseStorageOptions {\n supabase: SupabaseClient;\n appName: string;\n orgId: string;\n}\n\nexport interface UseStorageReturn {\n // Upload\n uploadFile: (file: File, options?: Partial<StorageUploadOptions>) => Promise<StorageUploadResult>;\n isUploading: boolean;\n uploadError: string | null;\n \n // URLs\n getPublicUrl: (path: string) => string;\n getSignedUrl: (path: string, expiresIn?: number) => Promise<string | null>;\n getFileUrl: (path: string) => string; // Alias for getPublicUrl\n \n // File management\n deleteFile: (path: string) => Promise<{ success: boolean; error?: string }>;\n archiveFile: (path: string) => Promise<{ success: boolean; error?: string }>;\n \n // Listing\n listFiles: (options?: Partial<StorageListOptions>) => Promise<StorageListResult>;\n isListing: boolean;\n listError: string | null;\n isLoading: boolean; // Alias for isListing\n error: string | null; // Alias for listError\n \n // State\n files: StorageFileInfo[];\n refreshFiles: () => Promise<void>;\n}\n\n/**\n * Hook for storage operations with app and organisation context\n */\nexport function useStorage({ supabase, appName, orgId }: UseStorageOptions): UseStorageReturn {\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [isListing, setIsListing] = useState(false);\n const [listError, setListError] = useState<string | null>(null);\n const [files, setFiles] = useState<StorageFileInfo[]>([]);\n\n // Upload file\n const handleUploadFile = useCallback(async (\n file: File, \n options: Partial<StorageUploadOptions> = {}\n ): Promise<StorageUploadResult> => {\n setIsUploading(true);\n setUploadError(null);\n\n try {\n const uploadOptions: StorageUploadOptions = {\n appName,\n orgId,\n isPublic: false,\n ...options\n };\n\n const result = await uploadFile(supabase, file, uploadOptions);\n \n if (result.success) {\n // Refresh file list\n await refreshFiles();\n } else {\n setUploadError(result.error || 'Upload failed');\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Upload failed';\n setUploadError(errorMessage);\n return {\n success: false,\n error: errorMessage\n };\n } finally {\n setIsUploading(false);\n }\n }, [supabase, appName, orgId]);\n\n // Get public URL\n const handleGetPublicUrl = useCallback((path: string): string => {\n return getPublicUrl(supabase, path);\n }, [supabase]);\n\n // Get signed URL\n const handleGetSignedUrl = useCallback(async (\n path: string, \n expiresIn?: number\n ): Promise<string | null> => {\n try {\n const result = await getSignedUrl(supabase, path, {\n appName,\n orgId,\n expiresIn\n });\n return result?.url || null;\n } catch (error) {\n log.error('Failed to get signed URL:', error);\n return null;\n }\n }, [supabase, appName, orgId]);\n\n // Delete file\n const handleDeleteFile = useCallback(async (path: string) => {\n try {\n const result = await deleteFile(supabase, path);\n if (result.success) {\n await refreshFiles();\n }\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Delete failed'\n };\n }\n }, [supabase]);\n\n // Archive file\n const handleArchiveFile = useCallback(async (path: string) => {\n try {\n const result = await archiveFile(supabase, path, { appName, orgId });\n if (result.success) {\n await refreshFiles();\n }\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Archive failed'\n };\n }\n }, [supabase, appName, orgId]);\n\n // List files\n const handleListFiles = useCallback(async (\n options: Partial<StorageListOptions> = {}\n ): Promise<StorageListResult> => {\n setIsListing(true);\n setListError(null);\n\n try {\n const listOptions: StorageListOptions = {\n appName,\n orgId,\n ...options\n };\n\n const result = await listFiles(supabase, listOptions);\n setFiles(result.files);\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'List failed';\n setListError(errorMessage);\n return { files: [], totalCount: 0, hasMore: false };\n } finally {\n setIsListing(false);\n }\n }, [supabase, appName, orgId]);\n\n // Refresh files\n const refreshFiles = useCallback(async () => {\n await handleListFiles();\n }, [handleListFiles]);\n\n return {\n // Upload\n uploadFile: handleUploadFile,\n isUploading,\n uploadError,\n \n // URLs\n getPublicUrl: handleGetPublicUrl,\n getSignedUrl: handleGetSignedUrl,\n getFileUrl: handleGetPublicUrl, // Alias for getPublicUrl\n \n // File management\n deleteFile: handleDeleteFile,\n archiveFile: handleArchiveFile,\n \n // Listing\n listFiles: handleListFiles,\n isListing,\n listError,\n isLoading: isListing, // Alias for isListing\n error: listError, // Alias for listError\n \n // State\n files,\n refreshFiles\n };\n}\n\n/**\n * Hook for file upload with progress tracking\n */\nexport function useFileUpload({ supabase, appName, orgId }: UseStorageOptions) {\n const [uploadProgress, setUploadProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n\n const uploadWithProgress = useCallback(async (\n file: File,\n options: Partial<StorageUploadOptions> = {}\n ): Promise<StorageUploadResult> => {\n setIsUploading(true);\n setUploadProgress(0);\n setUploadError(null);\n\n try {\n // Simulate progress (Supabase doesn't provide real progress)\n const progressInterval = setInterval(() => {\n setUploadProgress(prev => Math.min(prev + 10, 90));\n }, 100);\n\n const uploadOptions: StorageUploadOptions = {\n appName,\n orgId,\n isPublic: false,\n ...options\n };\n\n const result = await uploadFile(supabase, file, uploadOptions);\n \n clearInterval(progressInterval);\n setUploadProgress(100);\n\n if (!result.success) {\n setUploadError(result.error || 'Upload failed');\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Upload failed';\n setUploadError(errorMessage);\n return {\n success: false,\n error: errorMessage\n };\n } finally {\n setIsUploading(false);\n setTimeout(() => setUploadProgress(0), 1000);\n }\n }, [supabase, appName, orgId]);\n\n return {\n uploadWithProgress,\n uploadProgress,\n isUploading,\n uploadError\n };\n}\n"],"mappings":"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","names":["useRef","useEffect","useCallback","useEffect","useCallback","useEffect","useState","useCallback","useEffect","useRef","useCallback","useRef","useCallback","useEffect","useRef","useCallback","useRef","useCallback","useState","useCallback","log","useState","useCallback"]}
package/dist/index.d.ts CHANGED
@@ -9,17 +9,17 @@ export { O as Organisation, a as OrganisationMembership, g as OrganisationSecuri
9
9
  import { S as SessionRestorationState } from './auth-BZOJqrdd.js';
10
10
  export { A as AccessLevel, E as EventAppRole, G as GlobalRole, I as InvalidScopeError, M as MissingUserContextError, O as Operation, e as OrganisationContextRequiredError, c as OrganisationRole, P as Permission, a as PermissionCheck, d as PermissionDeniedError, b as PermissionMap, R as RBACError, f as RBACNotInitializedError, S as Scope, U as UUID } from './types-UU913iLA.js';
11
11
  export { A as AccessLevelContext, s as AuditEventType, P as PermissionSource, d as RBACAccessValidateParams, e as RBACAccessValidateResult, q as RBACAuditLogParams, r as RBACAuditLogResult, t as RBACContext, w as RBACErrorCode, v as RBACFunctionResponse, f as RBACPageAccessCheckParams, R as RBACPermissionCheckParams, a as RBACPermissionCheckResult, b as RBACPermissionsGetParams, c as RBACPermissionsGetResult, u as RBACResult, g as RBACRoleGrantParams, h as RBACRoleGrantResult, i as RBACRoleRevokeParams, j as RBACRoleRevokeResult, m as RBACRoleValidateParams, n as RBACRoleValidateResult, k as RBACRolesListParams, l as RBACRolesListResult, o as RBACSessionTrackParams, p as RBACSessionTrackResult, x as RPCFunction, S as SessionType } from './functions-D_kgHktt.js';
12
- export { ALL_PERMISSIONS, AccessLevelGuard, AllPermissions, CACHE_PATTERNS, ComplianceResult, DataAccessRecord, DatabaseComplianceResult, DatabaseIssue, EVENT_APP_PERMISSIONS, EnhancedNavigationMenu, EnhancedNavigationMenuProps, EventAppRoleData, GLOBAL_PERMISSIONS, GrantEventAppRoleParams, NavigationAccessRecord, NavigationContextType, NavigationGuard, NavigationGuardProps, NavigationProvider, NavigationProviderProps, ORGANISATION_PERMISSIONS, PAGE_PERMISSIONS, PageAccessRecord, PagePermissionContextType, PagePermissionGuard, PagePermissionGuardProps, PagePermissionProvider, PagePermissionProviderProps, PermissionEnforcer, PermissionEnforcerProps, PermissionGuard, QuickFix, RBACAuditManager, RBACCache, RBACConfig, RBACEngine, RBACLogger, ResourcePermissions, RevokeEventAppRoleParams, RoleBasedRouter, RoleBasedRouterContextType, RoleBasedRouterProps, RoleManagementResult, RouteAccessRecord, RouteConfig, RuntimeComplianceResult, SecureDataContextType, SecureDataProvider, SecureDataProviderProps, SecureSupabaseClient, SetupIssue, UseResolvedScopeOptions, UseResolvedScopeReturn, UseResourcePermissionsOptions, checkRuntimeCompliance, createAuditManager, createRBACConfig, createRBACEngine, createRBACExpressMiddleware, createRBACMiddleware, createSecureClient, emitAuditEvent, fromSupabaseClient, getAccessLevel, getCustomAuthCodeFixes, getDirectSupabaseAuthFixes, getDuplicateConfigFixes, getGlobalAuditManager, getPermissionMap, getPermissionsForRole, getQuickFixes, getRBACConfig, getRBACLogger, getRoleContext, getSetupIssues, getUnprotectedPageFixes, hasAllPermissions, hasAnyPermission, hasAnyPermissionCached, hasPermission, hasPermissionCached, isDebugMode, isDevelopmentMode, isPermitted, isPermittedCached, isRBACInitialized, isValidPermission, rbacCache, resolveAppContext, setGlobalAuditManager, setupRBAC, useAccessLevel, useCachedPermissions, useCan, useHasAllPermissions, useHasAnyPermission, useMultiplePermissions, useNavigationPermissions, usePagePermissions, usePermissions, useRBAC, useResolvedScope, useResourcePermissions, useRoleBasedRouter, useRoleManagement, useSecureData, useSecureSupabase, validateAndWarn, validateDatabaseConfiguration, validateRBACSetup, withAccessLevelGuard, withPermissionGuard, withRoleGuard } from './rbac/index.js';
13
- export { A as Alert, n as AlertDescription, m as AlertTitle, o as Avatar, q as AvatarFallback, p as AvatarImage, r as Badge, s as BadgeProps, t as BadgeVariant, B as Button, a as ButtonProps, al as Calendar, am as CalendarProps, C as Card, g as CardActions, f as CardContent, e as CardDescription, c as CardFooter, b as CardHeader, h as CardProps, d as CardTitle, u as Checkbox, J as Dialog, U as DialogBody, O as DialogClose, Q as DialogContent, X as DialogDescription, V as DialogFooter, R as DialogHeader, M as DialogOverlay, K as DialogPortal, W as DialogTitle, N as DialogTrigger, aT as ErrorBoundary, aZ as EventSelector, b0 as FileDisplay, b1 as FileDisplayProps, a_ as FileUpload, a$ as FileUploadProps, aJ as Footer, aK as FooterProps, aC as Form, aD as FormField, aF as FormFieldProps, aE as FormProps, aI as Header, I as Input, j as InputProps, L as Label, k as LabelProps, aW as LoadingSpinner, aG as LoginForm, aH as LoginFormProps, aP as NavigationItem, aN as NavigationMenu, aO as NavigationMenuProps, bm as NavigationMode, aQ as OrganisationSelector, bj as PaceAppLayout, bi as PaceAppLayoutProps, bl as PaceLoginPage, bk as PaceLoginPageProps, bo as PasswordChangeForm, P as Progress, w as ProgressProps, aL as ProtectedRoute, aM as ProtectedRouteProps, bb as PublicPageFooter, bh as PublicPageFooterProps, ba as PublicPageHeader, bg as PublicPageHeaderProps, b9 as PublicPageLayout, bf as PublicPageLayoutProps, bc as PublicPageProvider, a5 as Select, a9 as SelectContent, a6 as SelectGroup, ab as SelectItem, aa as SelectLabel, ac as SelectSeparator, a8 as SelectTrigger, a7 as SelectValue, aX as SessionRestorationLoader, aY as SessionRestorationLoaderProps, S as Switch, v as SwitchProps, x as Table, z as TableBody, D as TableCaption, E as TableCell, F as TableFooter, G as TableHead, y as TableHeader, H as TableRow, ad as Tabs, ag as TabsContent, ak as TabsContentProps, ae as TabsList, ai as TabsListProps, ah as TabsProps, af as TabsTrigger, aj as TabsTriggerProps, T as Textarea, l as TextareaProps, an as Toast, ap as ToastAction, av as ToastActionElement, au as ToastClose, at as ToastDescription, aw as ToastProps, aq as ToastProvider, as as ToastTitle, ar as ToastViewport, ao as Toaster, ax as Tooltip, az as TooltipContent, aA as TooltipProvider, aB as TooltipRoot, ay as TooltipTrigger, b8 as UseFileReferenceForRecordReturn, b6 as UseFileReferenceOptions, b7 as UseFileReferenceReturn, aS as UserMenu, bn as UserMenuProps, b2 as useFileReference, b4 as useFileReferenceById, b3 as useFileReferenceForRecord, b5 as useFilesByCategory, be as useIsPublicPage, bd as usePublicPageContext } from './PublicPageProvider-DIzEzwKl.js';
12
+ export { ALL_PERMISSIONS, AccessLevelGuard, AllPermissions, CACHE_PATTERNS, ComplianceResult, DataAccessRecord, DatabaseComplianceResult, DatabaseIssue, EVENT_APP_PERMISSIONS, EnhancedNavigationMenu, EnhancedNavigationMenuProps, EventAppRoleData, GLOBAL_PERMISSIONS, GrantEventAppRoleParams, NavigationAccessRecord, NavigationContextType, NavigationGuard, NavigationGuardProps, NavigationProvider, NavigationProviderProps, ORGANISATION_PERMISSIONS, PAGE_PERMISSIONS, PageAccessRecord, PagePermissionContextType, PagePermissionGuard, PagePermissionGuardProps, PagePermissionProvider, PagePermissionProviderProps, PermissionEnforcer, PermissionEnforcerProps, PermissionGuard, QuickFix, RBACAuditManager, RBACCache, RBACConfig, RBACEngine, RBACLogger, RBACPerformanceMetrics, ResourcePermissions, RevokeEventAppRoleParams, RoleBasedRouter, RoleBasedRouterContextType, RoleBasedRouterProps, RoleManagementResult, RouteAccessRecord, RouteConfig, RuntimeComplianceResult, SecureDataContextType, SecureDataProvider, SecureDataProviderProps, SecureSupabaseClient, SetupIssue, UseResolvedScopeOptions, UseResolvedScopeReturn, UseResourcePermissionsOptions, checkRuntimeCompliance, clearInFlightRequests, createAuditManager, createRBACConfig, createRBACEngine, createRBACExpressMiddleware, createRBACMiddleware, createSecureClient, disablePerformanceMonitoring, emitAuditEvent, enablePerformanceMonitoring, fromSupabaseClient, getAccessLevel, getCustomAuthCodeFixes, getDirectSupabaseAuthFixes, getDuplicateConfigFixes, getGlobalAuditManager, getInFlightRequestCount, getPerformanceMetrics, getPerformanceSummary, getPermissionMap, getPermissionsForRole, getQuickFixes, getRBACConfig, getRBACLogger, getRoleContext, getSetupIssues, getUnprotectedPageFixes, hasAllPermissions, hasAnyPermission, hasAnyPermissionCached, hasPermission, hasPermissionCached, isDebugMode, isDevelopmentMode, isPerformanceMonitoringEnabled, isPermitted, isPermittedCached, isRBACInitialized, isValidPermission, rbacCache, recordAuditEvent, recordPermissionCheck, resetPerformanceMetrics, resolveAppContext, setGlobalAuditManager, setupRBAC, useAccessLevel, useCachedPermissions, useCan, useHasAllPermissions, useHasAnyPermission, useMultiplePermissions, useNavigationPermissions, usePagePermissions, usePermissions, useRBAC, useResolvedScope, useResourcePermissions, useRoleBasedRouter, useRoleManagement, useSecureData, useSecureSupabase, validateAndWarn, validateDatabaseConfiguration, validateRBACSetup, withAccessLevelGuard, withPermissionGuard, withRoleGuard } from './rbac/index.js';
13
+ export { A as AddressField, k as AddressFieldProps, l as AddressFieldRef, o as Alert, q as AlertDescription, p as AlertTitle, r as Avatar, t as AvatarFallback, s as AvatarImage, u as Badge, v as BadgeProps, w as BadgeVariant, B as Button, a as ButtonProps, ao as Calendar, ap as CalendarProps, C as Card, g as CardActions, f as CardContent, e as CardDescription, c as CardFooter, b as CardHeader, h as CardProps, d as CardTitle, x as Checkbox, N as Dialog, X as DialogBody, U as DialogClose, V as DialogContent, _ as DialogDescription, Y as DialogFooter, W as DialogHeader, Q as DialogOverlay, O as DialogPortal, Z as DialogTitle, R as DialogTrigger, aW as ErrorBoundary, b0 as EventSelector, b3 as FileDisplay, b4 as FileDisplayProps, b1 as FileUpload, b2 as FileUploadProps, aM as Footer, aN as FooterProps, aF as Form, aG as FormField, aI as FormFieldProps, aH as FormProps, aL as Header, I as Input, j as InputProps, L as Label, m as LabelProps, aZ as LoadingSpinner, aJ as LoginForm, aK as LoginFormProps, aS as NavigationItem, aQ as NavigationMenu, aR as NavigationMenuProps, bp as NavigationMode, aT as OrganisationSelector, bm as PaceAppLayout, bl as PaceAppLayoutProps, bo as PaceLoginPage, bn as PaceLoginPageProps, br as PasswordChangeForm, P as Progress, z as ProgressProps, aO as ProtectedRoute, aP as ProtectedRouteProps, be as PublicPageFooter, bk as PublicPageFooterProps, bd as PublicPageHeader, bj as PublicPageHeaderProps, bc as PublicPageLayout, bi as PublicPageLayoutProps, bf as PublicPageProvider, a8 as Select, ac as SelectContent, a9 as SelectGroup, ae as SelectItem, ad as SelectLabel, af as SelectSeparator, ab as SelectTrigger, aa as SelectValue, a_ as SessionRestorationLoader, a$ as SessionRestorationLoaderProps, S as Switch, y as SwitchProps, D as Table, F as TableBody, G as TableCaption, H as TableCell, J as TableFooter, K as TableHead, E as TableHeader, M as TableRow, ag as Tabs, aj as TabsContent, an as TabsContentProps, ah as TabsList, al as TabsListProps, ak as TabsProps, ai as TabsTrigger, am as TabsTriggerProps, T as Textarea, n as TextareaProps, aq as Toast, as as ToastAction, ay as ToastActionElement, ax as ToastClose, aw as ToastDescription, az as ToastProps, at as ToastProvider, av as ToastTitle, au as ToastViewport, ar as Toaster, aA as Tooltip, aC as TooltipContent, aD as TooltipProvider, aE as TooltipRoot, aB as TooltipTrigger, bb as UseFileReferenceForRecordReturn, b9 as UseFileReferenceOptions, ba as UseFileReferenceReturn, aV as UserMenu, bq as UserMenuProps, b5 as useFileReference, b7 as useFileReferenceById, b6 as useFileReferenceForRecord, b8 as useFilesByCategory, bh as useIsPublicPage, bg as usePublicPageContext } from './PublicPageProvider-DrLDztHt.js';
14
14
  export { u as useToast } from './useToast-C8gR5ir4.js';
15
- export { D as DataTable, a as DataTableProps } from './DataTable-Z9NLVJh0.js';
16
- import { c as DataRecord, a as DataTableAction, D as DataTableColumn } from './types-DUyCRSTj.js';
17
- export { A as AggregateConfig, e as DataTableFeatureConfig, b as DataTableToolbarButton, E as EmptyStateConfig, h as ExportOptions, G as GetRowId } from './types-DUyCRSTj.js';
15
+ export { D as DataTable, a as DataTableProps } from './DataTable-IVYljGJ6.js';
16
+ import { d as DataRecord, a as DataTableAction, D as DataTableColumn } from './types-Bwgl--Xo.js';
17
+ export { c as AggregateConfig, A as AutocompleteOptions, f as DataTableFeatureConfig, b as DataTableToolbarButton, E as EmptyStateConfig, j as ExportOptions, G as GetRowId, P as ParsedAddress } from './types-Bwgl--Xo.js';
18
18
  import { ColumnDef } from '@tanstack/react-table';
19
- import { H as FileSizeLimits, I as StorageConfig, S as StorageUploadOptions, J as StorageFileMetadata, a as StorageUploadResult, K as StorageUrlOptions, b as StorageListOptions, c as StorageListResult } from './usePublicRouteParams-D71QLlg4.js';
20
- export { d as StorageFileInfo, i as UseFormDialogOptions, j as UseFormDialogReturn, F as UsePublicEventLogoOptions, E as UsePublicEventLogoReturn, B as UsePublicEventOptions, A as UsePublicEventReturn, D as UsePublicFileDisplayOptions, C as UsePublicFileDisplayReturn, G as UsePublicRouteParamsReturn, n as clearPublicEventCache, q as clearPublicFileDisplayCache, t as clearPublicLogoCache, z as extractEventCodeFromPath, y as generatePublicRoutePath, o as getPublicEventCacheStats, r as getPublicFileDisplayCacheStats, v as getPublicLogoCacheStats, k as useAppConfig, u as useEventTheme, h as useFormDialog, e as useOrganisationPermissions, f as useOrganisationSecurity, m as usePublicEvent, x as usePublicEventCode, s as usePublicEventLogo, p as usePublicFileDisplay, w as usePublicRouteParams, g as useZodForm } from './usePublicRouteParams-D71QLlg4.js';
19
+ import { F as FileSizeLimits, S as StorageConfig, a as StorageUploadOptions, b as StorageFileMetadata, c as StorageUploadResult, d as StorageUrlOptions, e as StorageListOptions, f as StorageListResult } from './usePublicRouteParams-CTDELQ7H.js';
20
+ export { m as StorageFileInfo, U as UseFormDialogOptions, h as UseFormDialogReturn, H as UsePublicEventLogoOptions, G as UsePublicEventLogoReturn, C as UsePublicEventOptions, B as UsePublicEventReturn, E as UsePublicFileDisplayOptions, D as UsePublicFileDisplayReturn, I as UsePublicRouteParamsReturn, o as clearPublicEventCache, r as clearPublicFileDisplayCache, v as clearPublicLogoCache, A as extractEventCodeFromPath, z as generatePublicRoutePath, p as getPublicEventCacheStats, s as getPublicFileDisplayCacheStats, w as getPublicLogoCacheStats, k as useAppConfig, l as useEventTheme, g as useFormDialog, i as useOrganisationPermissions, j as useOrganisationSecurity, n as usePublicEvent, y as usePublicEventCode, t as usePublicEventLogo, q as usePublicFileDisplay, x as usePublicRouteParams, u as useZodForm } from './usePublicRouteParams-CTDELQ7H.js';
21
21
  export { z } from 'zod';
22
- export { F as FileCategory, b as FileMetadata, a as FileReference, c as FileUploadOptions } from './file-reference-PRTSLxKx.js';
22
+ export { F as FileCategory, b as FileMetadata, a as FileReference, c as FileUploadOptions } from './file-reference-D037xOFK.js';
23
23
  import { SupabaseClient } from '@supabase/supabase-js';
24
24
  export { StyleImport, getAllStylePaths, getStylePath, styleConfig } from './styles/index.js';
25
25
  export { ColorPalette, ColorShade, PaletteData, applyPalette, clearPalette, parseAndNormalizeEventColours } from './theming/runtime.js';
@@ -747,6 +747,21 @@ declare function getSignedUrl(supabase: SupabaseClient, path: string, options: S
747
747
  url: string;
748
748
  expiresAt: string;
749
749
  } | null>;
750
+ /**
751
+ * Generate URLs for multiple file references in parallel
752
+ * This batches URL generation to reduce sequential requests and uses caching
753
+ * @param supabase - Supabase client instance
754
+ * @param fileReferences - Array of file references to generate URLs for
755
+ * @param options - URL options including expiry time and organisation ID
756
+ * @returns Map of file ID to URL string (only includes successful URL generations)
757
+ */
758
+ declare function generateFileUrlsBatch(supabase: SupabaseClient, fileReferences: Array<{
759
+ id: string;
760
+ file_path: string;
761
+ is_public: boolean;
762
+ }>, options: StorageUrlOptions & {
763
+ orgId?: string;
764
+ }): Promise<Map<string, string>>;
750
765
  /**
751
766
  * Delete a file from storage
752
767
  * @param supabase - Supabase client instance
@@ -819,4 +834,4 @@ declare class StorageUtils {
819
834
  static archiveFile: typeof archiveFile;
820
835
  }
821
836
 
822
- export { APP_PATH_MAPPING, ColumnFactory, DEFAULT_FILE_SIZE_LIMIT, DataRecord, DataTableAction, DataTableColumn, type ExportColumn, FILE_SIZE_LIMITS, FileSizeLimits, InactivityWarningModal, type InactivityWarningModalProps, OrganisationContextType, OrganisationProvider, type OrganisationProviderProps, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, average, count, deleteFile, downloadFile, exportToCSV, exportToCSVWithTableRows, extractFileMetadata, generateCSVContent, generateFilePath, generateUniqueFileName, getBucketName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, max, min, sum, uploadFile, useAuthService, useEventService, useEvents, useInactivityService, useInactivityTracker, useOrganisationService, useOrganisations, useSessionRestoration, validateFileSize };
837
+ export { APP_PATH_MAPPING, ColumnFactory, DEFAULT_FILE_SIZE_LIMIT, DataRecord, DataTableAction, DataTableColumn, type ExportColumn, FILE_SIZE_LIMITS, FileSizeLimits, InactivityWarningModal, type InactivityWarningModalProps, OrganisationContextType, OrganisationProvider, type OrganisationProviderProps, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, average, count, deleteFile, downloadFile, exportToCSV, exportToCSVWithTableRows, extractFileMetadata, generateCSVContent, generateFilePath, generateFileUrlsBatch, generateUniqueFileName, getBucketName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, max, min, sum, uploadFile, useAuthService, useEventService, useEvents, useInactivityService, useInactivityTracker, useOrganisationService, useOrganisations, useSessionRestoration, validateFileSize };
package/dist/index.js CHANGED
@@ -40,8 +40,9 @@ import {
40
40
  withAccessLevelGuard,
41
41
  withPermissionGuard,
42
42
  withRoleGuard
43
- } from "./chunk-GRIQLQ52.js";
43
+ } from "./chunk-IM4QE42D.js";
44
44
  import {
45
+ AddressField,
45
46
  Avatar,
46
47
  AvatarFallback,
47
48
  AvatarImage,
@@ -93,7 +94,7 @@ import {
93
94
  useFileReferenceById,
94
95
  useFileReferenceForRecord,
95
96
  useFilesByCategory
96
- } from "./chunk-HDCUMOOI.js";
97
+ } from "./chunk-EFCLXK7F.js";
97
98
  import {
98
99
  Alert,
99
100
  AlertDescription,
@@ -143,7 +144,7 @@ import {
143
144
  max,
144
145
  min,
145
146
  sum
146
- } from "./chunk-HGPQUCBC.js";
147
+ } from "./chunk-2UUZZJFT.js";
147
148
  import {
148
149
  SecureSupabaseClient,
149
150
  createSecureClient,
@@ -160,14 +161,20 @@ import {
160
161
  useResourcePermissions,
161
162
  useRoleManagement,
162
163
  useSecureSupabase
163
- } from "./chunk-445GEP27.js";
164
+ } from "./chunk-3GOZZZYH.js";
164
165
  import {
165
166
  CACHE_PATTERNS,
166
167
  RBACCache,
167
168
  RBACEngine,
169
+ clearInFlightRequests,
168
170
  createRBACConfig,
169
171
  createRBACEngine,
172
+ disablePerformanceMonitoring,
173
+ enablePerformanceMonitoring,
170
174
  getAccessLevel,
175
+ getInFlightRequestCount,
176
+ getPerformanceMetrics,
177
+ getPerformanceSummary,
171
178
  getPermissionMap,
172
179
  getRBACConfig,
173
180
  getRBACLogger,
@@ -177,19 +184,23 @@ import {
177
184
  hasPermission,
178
185
  isDebugMode,
179
186
  isDevelopmentMode,
187
+ isPerformanceMonitoringEnabled,
180
188
  isPermitted,
181
189
  isPermittedCached,
182
190
  rbacCache,
191
+ recordAuditEvent,
192
+ recordPermissionCheck,
193
+ resetPerformanceMetrics,
183
194
  resolveAppContext,
184
195
  setupRBAC
185
- } from "./chunk-U6WNSFX5.js";
196
+ } from "./chunk-HEHYGYOX.js";
186
197
  import {
187
198
  RBACAuditManager,
188
199
  createAuditManager,
189
200
  emitAuditEvent,
190
201
  getGlobalAuditManager,
191
202
  setGlobalAuditManager
192
- } from "./chunk-FSFQFJCU.js";
203
+ } from "./chunk-63FOKYGO.js";
193
204
  import {
194
205
  StorageUtils,
195
206
  clearPublicEventCache,
@@ -206,8 +217,8 @@ import {
206
217
  usePublicEventLogo,
207
218
  usePublicRouteParams,
208
219
  useZodForm
209
- } from "./chunk-OALXJH4Y.js";
210
- import "./chunk-DAGICKHT.js";
220
+ } from "./chunk-IPCH26AG.js";
221
+ import "./chunk-DDM4CCYT.js";
211
222
  import {
212
223
  APP_PATH_MAPPING,
213
224
  DEFAULT_FILE_SIZE_LIMIT,
@@ -221,6 +232,7 @@ import {
221
232
  downloadFile,
222
233
  extractFileMetadata,
223
234
  generateFilePath,
235
+ generateFileUrlsBatch,
224
236
  generateUniqueFileName,
225
237
  getBucketName,
226
238
  getFileSizeLimit,
@@ -235,14 +247,14 @@ import {
235
247
  usePublicFileDisplay,
236
248
  usePublicPageContext,
237
249
  validateFileSize
238
- } from "./chunk-TC7D3CR3.js";
250
+ } from "./chunk-UNOTYLQF.js";
239
251
  import {
240
252
  useToast
241
253
  } from "./chunk-6C4YBBJM.js";
242
254
  import {
243
255
  useEvents,
244
256
  useOrganisations
245
- } from "./chunk-XAUHJD3L.js";
257
+ } from "./chunk-E7UAOUMY.js";
246
258
  import "./chunk-KQCRWDSA.js";
247
259
  import {
248
260
  EventServiceProvider,
@@ -255,10 +267,10 @@ import {
255
267
  useOrganisationService,
256
268
  useSessionRestoration,
257
269
  useUnifiedAuth
258
- } from "./chunk-FXFJRTKI.js";
270
+ } from "./chunk-VGZZXKBR.js";
259
271
  import {
260
272
  FileCategory
261
- } from "./chunk-UQWSHFVX.js";
273
+ } from "./chunk-SAUPYVLF.js";
262
274
  import "./chunk-QXHPKYJV.js";
263
275
  import {
264
276
  emailSchema,
@@ -295,7 +307,7 @@ import {
295
307
  cn
296
308
  } from "./chunk-R77UEZ4E.js";
297
309
  import "./chunk-F2IMUDXZ.js";
298
- import "./chunk-FMUCXFII.js";
310
+ import "./chunk-YHCN776L.js";
299
311
  import "./chunk-VBXEHIUJ.js";
300
312
  import {
301
313
  getAllStylePaths,
@@ -475,6 +487,7 @@ function useInactivityTracker({
475
487
  const countdownIntervalRef = useRef(null);
476
488
  const lastActivityRef = useRef(Date.now());
477
489
  const channelRef = useRef(null);
490
+ const throttledResetActivityRef = useRef(null);
478
491
  const clearTimers = useCallback2(() => {
479
492
  if (timeoutRef.current) {
480
493
  clearTimeout(timeoutRef.current);
@@ -576,33 +589,41 @@ function useInactivityTracker({
576
589
  } catch (error) {
577
590
  logger.warn("useInactivityTracker", "Failed to check persisted activity time:", error);
578
591
  }
579
- const throttledResetActivity = throttle((event) => {
580
- resetActivity();
581
- }, 100);
582
- const addEventListeners = () => {
583
- ACTIVITY_EVENTS.forEach((event) => {
584
- document.addEventListener(event, throttledResetActivity, { passive: true });
585
- });
586
- };
587
- const removeEventListeners = () => {
592
+ if (throttledResetActivityRef.current) {
588
593
  ACTIVITY_EVENTS.forEach((event) => {
589
- document.removeEventListener(event, throttledResetActivity);
594
+ document.removeEventListener(event, throttledResetActivityRef.current);
590
595
  });
591
- };
592
- addEventListeners();
596
+ }
597
+ throttledResetActivityRef.current = throttle((event) => {
598
+ resetActivity();
599
+ }, 100);
600
+ ACTIVITY_EVENTS.forEach((event) => {
601
+ document.addEventListener(event, throttledResetActivityRef.current, { passive: true });
602
+ });
593
603
  resetActivity(true);
594
604
  return () => {
595
- removeEventListeners();
605
+ if (throttledResetActivityRef.current) {
606
+ ACTIVITY_EVENTS.forEach((event) => {
607
+ document.removeEventListener(event, throttledResetActivityRef.current);
608
+ });
609
+ throttledResetActivityRef.current = null;
610
+ }
596
611
  clearTimers();
597
612
  if (channelRef.current) {
598
613
  channelRef.current.close();
599
614
  channelRef.current = null;
600
615
  }
601
616
  };
602
- }, [enabled, isTracking, channelName, storageKey, idleTimeoutMs, warnBeforeMs, onIdle, onWarning]);
617
+ }, [enabled, isTracking, channelName, storageKey, idleTimeoutMs, warnBeforeMs, onIdle, onWarning, onActivity, resetActivity]);
603
618
  const stopTracking = useCallback2(() => {
604
619
  setIsTracking(false);
605
620
  clearTimers();
621
+ if (throttledResetActivityRef.current) {
622
+ ACTIVITY_EVENTS.forEach((event) => {
623
+ document.removeEventListener(event, throttledResetActivityRef.current);
624
+ });
625
+ throttledResetActivityRef.current = null;
626
+ }
606
627
  if (channelRef.current) {
607
628
  channelRef.current.close();
608
629
  channelRef.current = null;
@@ -614,8 +635,9 @@ function useInactivityTracker({
614
635
  return cleanup;
615
636
  } else {
616
637
  stopTracking();
638
+ return void 0;
617
639
  }
618
- }, [enabled, idleTimeoutMs, warnBeforeMs]);
640
+ }, [enabled, idleTimeoutMs, warnBeforeMs, startTracking, stopTracking]);
619
641
  useEffect2(() => {
620
642
  return () => {
621
643
  clearTimers();
@@ -868,6 +890,7 @@ export {
868
890
  ALL_PERMISSIONS,
869
891
  APP_PATH_MAPPING,
870
892
  AccessLevelGuard,
893
+ AddressField,
871
894
  Alert,
872
895
  AlertDescription,
873
896
  AlertTitle,
@@ -995,6 +1018,7 @@ export {
995
1018
  archiveFile,
996
1019
  average,
997
1020
  checkRuntimeCompliance,
1021
+ clearInFlightRequests,
998
1022
  clearPalette,
999
1023
  clearPublicEventCache,
1000
1024
  clearPublicFileDisplayCache,
@@ -1010,9 +1034,11 @@ export {
1010
1034
  createSecureClient,
1011
1035
  createSecureDataAccess,
1012
1036
  deleteFile,
1037
+ disablePerformanceMonitoring,
1013
1038
  downloadFile,
1014
1039
  emailSchema,
1015
1040
  emitAuditEvent,
1041
+ enablePerformanceMonitoring,
1016
1042
  exportToCSV,
1017
1043
  exportToCSVWithTableRows,
1018
1044
  extractEventCodeFromPath,
@@ -1031,6 +1057,7 @@ export {
1031
1057
  fromZonedTime,
1032
1058
  generateCSVContent,
1033
1059
  generateFilePath,
1060
+ generateFileUrlsBatch,
1034
1061
  generatePublicRoutePath,
1035
1062
  generateUniqueFileName,
1036
1063
  getAccessLevel,
@@ -1044,6 +1071,9 @@ export {
1044
1071
  getDuplicateConfigFixes,
1045
1072
  getFileSizeLimit,
1046
1073
  getGlobalAuditManager,
1074
+ getInFlightRequestCount,
1075
+ getPerformanceMetrics,
1076
+ getPerformanceSummary,
1047
1077
  getPermissionMap,
1048
1078
  getPermissionsForRole,
1049
1079
  getPublicEventCacheStats,
@@ -1068,6 +1098,7 @@ export {
1068
1098
  hasPermissionCached,
1069
1099
  isDebugMode,
1070
1100
  isDevelopmentMode,
1101
+ isPerformanceMonitoringEnabled,
1071
1102
  isPermitted,
1072
1103
  isPermittedCached,
1073
1104
  isRBACInitialized,
@@ -1081,6 +1112,9 @@ export {
1081
1112
  passwordSchema,
1082
1113
  phoneSchema,
1083
1114
  rbacCache,
1115
+ recordAuditEvent,
1116
+ recordPermissionCheck,
1117
+ resetPerformanceMetrics,
1084
1118
  resolveAppContext,
1085
1119
  roundToNearestMinutes,
1086
1120
  setAppConfig,