tempest-react-sdk 0.77.0 → 0.79.0
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.
- package/README.md +6 -6
- package/bin/lib/alias/collect.mjs +20 -3
- package/bin/lib/alias/index.mjs +12 -1
- package/bin/lib/alias/index.test.mjs +24 -0
- package/bin/lib/css/analyze.test.mjs +21 -1
- package/bin/lib/css/collect.mjs +14 -0
- package/bin/lib/css/extract.mjs +63 -5
- package/bin/lib/css/extract.test.mjs +110 -1
- package/bin/lib/css/fix.e2e.test.mjs +50 -0
- package/bin/lib/css/index.mjs +6 -1
- package/bin/lib/fs/contain.mjs +50 -0
- package/bin/lib/icons/generate.mjs +28 -3
- package/bin/lib/icons/generate.test.mjs +57 -1
- package/bin/lib/openapi/escape.mjs +20 -6
- package/bin/lib/openapi/generate.encode.test.mjs +120 -0
- package/bin/lib/openapi/generate.hostile.test.mjs +38 -9
- package/bin/lib/openapi/generate.mjs +203 -64
- package/bin/lib/openapi/generate.pagination.test.mjs +3 -2
- package/bin/lib/openapi/generate.test.mjs +270 -3
- package/bin/lib/openapi/schema-to-zod.mjs +5 -3
- package/bin/tempest-gen.test.mjs +188 -0
- package/bin/tempest.mjs +120 -44
- package/dist/access/Can.cjs.map +1 -1
- package/dist/access/Can.js.map +1 -1
- package/dist/access/access-control-context.cjs.map +1 -1
- package/dist/access/access-control-context.js.map +1 -1
- package/dist/access/create-role-access-control.cjs.map +1 -1
- package/dist/access/create-role-access-control.js.map +1 -1
- package/dist/access/permissions-from-token.cjs.map +1 -1
- package/dist/access/permissions-from-token.js.map +1 -1
- package/dist/access/use-can.cjs.map +1 -1
- package/dist/access/use-can.js.map +1 -1
- package/dist/app/AppProviders.cjs.map +1 -1
- package/dist/app/AppProviders.js.map +1 -1
- package/dist/audio/audio-bus.cjs.map +1 -1
- package/dist/audio/audio-bus.js.map +1 -1
- package/dist/audio/audio-output.cjs.map +1 -1
- package/dist/audio/audio-output.js.map +1 -1
- package/dist/audio/audio-player.cjs.map +1 -1
- package/dist/audio/audio-player.js.map +1 -1
- package/dist/audio/audio-recorder.cjs.map +1 -1
- package/dist/audio/audio-recorder.js.map +1 -1
- package/dist/audio/duration.cjs.map +1 -1
- package/dist/audio/duration.js.map +1 -1
- package/dist/audio/level-meter.cjs.map +1 -1
- package/dist/audio/level-meter.js.map +1 -1
- package/dist/audio/media-access.cjs.map +1 -1
- package/dist/audio/media-access.js.map +1 -1
- package/dist/audio/noise-floor.cjs.map +1 -1
- package/dist/audio/noise-floor.js.map +1 -1
- package/dist/audio/sfx-pool.cjs.map +1 -1
- package/dist/audio/sfx-pool.js.map +1 -1
- package/dist/audio/use-audio-bus.cjs.map +1 -1
- package/dist/audio/use-audio-bus.js.map +1 -1
- package/dist/audio/use-audio-recorder.cjs.map +1 -1
- package/dist/audio/use-audio-recorder.js.map +1 -1
- package/dist/audio/use-audio.cjs.map +1 -1
- package/dist/audio/use-audio.js.map +1 -1
- package/dist/audio/use-microphone.cjs +1 -1
- package/dist/audio/use-microphone.cjs.map +1 -1
- package/dist/audio/use-microphone.js +1 -5
- package/dist/audio/use-microphone.js.map +1 -1
- package/dist/audio/use-sfx-pool.cjs.map +1 -1
- package/dist/audio/use-sfx-pool.js.map +1 -1
- package/dist/audio/voice-activity.cjs.map +1 -1
- package/dist/audio/voice-activity.js.map +1 -1
- package/dist/audio/voice-chain-stages.cjs.map +1 -1
- package/dist/audio/voice-chain-stages.js.map +1 -1
- package/dist/audio/voice-chain.cjs.map +1 -1
- package/dist/audio/voice-chain.js.map +1 -1
- package/dist/audio/wav.cjs.map +1 -1
- package/dist/audio/wav.js.map +1 -1
- package/dist/auth/AuthGuard.cjs.map +1 -1
- package/dist/auth/AuthGuard.js.map +1 -1
- package/dist/auth/create-auth-store.cjs.map +1 -1
- package/dist/auth/create-auth-store.js.map +1 -1
- package/dist/auth/create-tempest-auth.cjs +1 -1
- package/dist/auth/create-tempest-auth.cjs.map +1 -1
- package/dist/auth/create-tempest-auth.js +185 -114
- package/dist/auth/create-tempest-auth.js.map +1 -1
- package/dist/auth/jwt.cjs.map +1 -1
- package/dist/auth/jwt.js.map +1 -1
- package/dist/auth/lazy-with-retry.cjs.map +1 -1
- package/dist/auth/lazy-with-retry.js.map +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js.map +1 -1
- package/dist/auth/refresh-queue.cjs.map +1 -1
- package/dist/auth/refresh-queue.js.map +1 -1
- package/dist/auth/use-passkey.cjs +1 -1
- package/dist/auth/use-passkey.cjs.map +1 -1
- package/dist/auth/use-passkey.js +1 -1
- package/dist/auth/use-passkey.js.map +1 -1
- package/dist/br/BrazilMap.cjs.map +1 -1
- package/dist/br/BrazilMap.js.map +1 -1
- package/dist/br/BrazilMap.module.cjs.map +1 -1
- package/dist/br/BrazilMap.module.js.map +1 -1
- package/dist/br/BrazilStateCitySelect.cjs.map +1 -1
- package/dist/br/BrazilStateCitySelect.js.map +1 -1
- package/dist/br/BrazilStateMap.cjs.map +1 -1
- package/dist/br/BrazilStateMap.js.map +1 -1
- package/dist/br/MapLegend.cjs.map +1 -1
- package/dist/br/MapLegend.js.map +1 -1
- package/dist/br/MapLegend.module.cjs.map +1 -1
- package/dist/br/MapLegend.module.js.map +1 -1
- package/dist/br/MapMarkers.cjs.map +1 -1
- package/dist/br/MapMarkers.js.map +1 -1
- package/dist/br/MapTooltip.cjs.map +1 -1
- package/dist/br/MapTooltip.js.map +1 -1
- package/dist/br/MunicipalitySearch.cjs +1 -1
- package/dist/br/MunicipalitySearch.cjs.map +1 -1
- package/dist/br/MunicipalitySearch.js +2 -5
- package/dist/br/MunicipalitySearch.js.map +1 -1
- package/dist/br/MunicipalitySearch.module.cjs.map +1 -1
- package/dist/br/MunicipalitySearch.module.js.map +1 -1
- package/dist/br/PixQRCode.cjs.map +1 -1
- package/dist/br/PixQRCode.js.map +1 -1
- package/dist/br/PixQRCode.module.cjs.map +1 -1
- package/dist/br/PixQRCode.module.js.map +1 -1
- package/dist/br/boleto.cjs.map +1 -1
- package/dist/br/boleto.js.map +1 -1
- package/dist/br/br-geo.cjs.map +1 -1
- package/dist/br/br-geo.js.map +1 -1
- package/dist/br/data/br-centroids.cjs.map +1 -1
- package/dist/br/data/br-centroids.js.map +1 -1
- package/dist/br/data/br-locations.cjs.map +1 -1
- package/dist/br/data/br-locations.js.map +1 -1
- package/dist/br/data/br-uf-geo.cjs.map +1 -1
- package/dist/br/data/br-uf-geo.js.map +1 -1
- package/dist/br/data/mun/AC.cjs.map +1 -1
- package/dist/br/data/mun/AC.js.map +1 -1
- package/dist/br/data/mun/AL.cjs.map +1 -1
- package/dist/br/data/mun/AL.js.map +1 -1
- package/dist/br/data/mun/AM.cjs.map +1 -1
- package/dist/br/data/mun/AM.js.map +1 -1
- package/dist/br/data/mun/AP.cjs.map +1 -1
- package/dist/br/data/mun/AP.js.map +1 -1
- package/dist/br/data/mun/BA.cjs.map +1 -1
- package/dist/br/data/mun/BA.js.map +1 -1
- package/dist/br/data/mun/CE.cjs.map +1 -1
- package/dist/br/data/mun/CE.js.map +1 -1
- package/dist/br/data/mun/DF.cjs.map +1 -1
- package/dist/br/data/mun/DF.js.map +1 -1
- package/dist/br/data/mun/ES.cjs.map +1 -1
- package/dist/br/data/mun/ES.js.map +1 -1
- package/dist/br/data/mun/GO.cjs.map +1 -1
- package/dist/br/data/mun/GO.js.map +1 -1
- package/dist/br/data/mun/MA.cjs.map +1 -1
- package/dist/br/data/mun/MA.js.map +1 -1
- package/dist/br/data/mun/MG.cjs.map +1 -1
- package/dist/br/data/mun/MG.js.map +1 -1
- package/dist/br/data/mun/MS.cjs.map +1 -1
- package/dist/br/data/mun/MS.js.map +1 -1
- package/dist/br/data/mun/MT.cjs.map +1 -1
- package/dist/br/data/mun/MT.js.map +1 -1
- package/dist/br/data/mun/PA.cjs.map +1 -1
- package/dist/br/data/mun/PA.js.map +1 -1
- package/dist/br/data/mun/PB.cjs.map +1 -1
- package/dist/br/data/mun/PB.js.map +1 -1
- package/dist/br/data/mun/PE.cjs.map +1 -1
- package/dist/br/data/mun/PE.js.map +1 -1
- package/dist/br/data/mun/PI.cjs.map +1 -1
- package/dist/br/data/mun/PI.js.map +1 -1
- package/dist/br/data/mun/PR.cjs.map +1 -1
- package/dist/br/data/mun/PR.js.map +1 -1
- package/dist/br/data/mun/RJ.cjs.map +1 -1
- package/dist/br/data/mun/RJ.js.map +1 -1
- package/dist/br/data/mun/RN.cjs.map +1 -1
- package/dist/br/data/mun/RN.js.map +1 -1
- package/dist/br/data/mun/RO.cjs.map +1 -1
- package/dist/br/data/mun/RO.js.map +1 -1
- package/dist/br/data/mun/RR.cjs.map +1 -1
- package/dist/br/data/mun/RR.js.map +1 -1
- package/dist/br/data/mun/RS.cjs.map +1 -1
- package/dist/br/data/mun/RS.js.map +1 -1
- package/dist/br/data/mun/SC.cjs.map +1 -1
- package/dist/br/data/mun/SC.js.map +1 -1
- package/dist/br/data/mun/SE.cjs.map +1 -1
- package/dist/br/data/mun/SE.js.map +1 -1
- package/dist/br/data/mun/SP.cjs.map +1 -1
- package/dist/br/data/mun/SP.js.map +1 -1
- package/dist/br/data/mun/TO.cjs.map +1 -1
- package/dist/br/data/mun/TO.js.map +1 -1
- package/dist/br/geocode.cjs.map +1 -1
- package/dist/br/geocode.js.map +1 -1
- package/dist/br/holidays.cjs.map +1 -1
- package/dist/br/holidays.js.map +1 -1
- package/dist/br/locations.cjs.map +1 -1
- package/dist/br/locations.js.map +1 -1
- package/dist/br/nfe.cjs.map +1 -1
- package/dist/br/nfe.js.map +1 -1
- package/dist/br/pix.cjs +1 -1
- package/dist/br/pix.cjs.map +1 -1
- package/dist/br/pix.js +108 -71
- package/dist/br/pix.js.map +1 -1
- package/dist/br/regions.cjs.map +1 -1
- package/dist/br/regions.js.map +1 -1
- package/dist/br/scales.cjs.map +1 -1
- package/dist/br/scales.js.map +1 -1
- package/dist/br/state-geo.cjs.map +1 -1
- package/dist/br/state-geo.js.map +1 -1
- package/dist/br/svg-utils.cjs.map +1 -1
- package/dist/br/svg-utils.js.map +1 -1
- package/dist/br/use-map-hover.cjs.map +1 -1
- package/dist/br/use-map-hover.js.map +1 -1
- package/dist/br/use-map-zoom.cjs.map +1 -1
- package/dist/br/use-map-zoom.js.map +1 -1
- package/dist/br/whatsapp.cjs.map +1 -1
- package/dist/br/whatsapp.js.map +1 -1
- package/dist/br.cjs.map +1 -1
- package/dist/br.d.ts +16 -5
- package/dist/br.js.map +1 -1
- package/dist/capture/barcode.cjs.map +1 -1
- package/dist/capture/barcode.js.map +1 -1
- package/dist/capture/media-recorder.cjs.map +1 -1
- package/dist/capture/media-recorder.js.map +1 -1
- package/dist/capture/use-barcode-scanner.cjs.map +1 -1
- package/dist/capture/use-barcode-scanner.js.map +1 -1
- package/dist/capture/use-screen-capture.cjs +1 -1
- package/dist/capture/use-screen-capture.cjs.map +1 -1
- package/dist/capture/use-screen-capture.js +1 -7
- package/dist/capture/use-screen-capture.js.map +1 -1
- package/dist/capture/use-speech-recognition.cjs +1 -1
- package/dist/capture/use-speech-recognition.cjs.map +1 -1
- package/dist/capture/use-speech-recognition.js +35 -36
- package/dist/capture/use-speech-recognition.js.map +1 -1
- package/dist/capture/use-torch.cjs.map +1 -1
- package/dist/capture/use-torch.js.map +1 -1
- package/dist/capture/use-video-recorder.cjs.map +1 -1
- package/dist/capture/use-video-recorder.js.map +1 -1
- package/dist/capture/video-recorder.cjs.map +1 -1
- package/dist/capture/video-recorder.js.map +1 -1
- package/dist/charts/AreaChart.cjs.map +1 -1
- package/dist/charts/AreaChart.js.map +1 -1
- package/dist/charts/BarChart.cjs.map +1 -1
- package/dist/charts/BarChart.js.map +1 -1
- package/dist/charts/LineChart.cjs.map +1 -1
- package/dist/charts/LineChart.js.map +1 -1
- package/dist/charts/PieChart.cjs.map +1 -1
- package/dist/charts/PieChart.js.map +1 -1
- package/dist/charts/RadarChart.cjs.map +1 -1
- package/dist/charts/RadarChart.js.map +1 -1
- package/dist/charts/palette.cjs.map +1 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/scales.cjs.map +1 -1
- package/dist/charts/scales.js.map +1 -1
- package/dist/charts/types.cjs.map +1 -1
- package/dist/charts/types.js.map +1 -1
- package/dist/charts/use-chart-colors.cjs.map +1 -1
- package/dist/charts/use-chart-colors.js.map +1 -1
- package/dist/components/AIChat/AIChat.cjs +1 -1
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js +1 -5
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChat.module.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.module.js.map +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
- package/dist/components/AIChat/AIChatComposer.js +1 -7
- package/dist/components/AIChat/AIChatComposer.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/AIChat/ai-chat-turns.cjs.map +1 -1
- package/dist/components/AIChat/ai-chat-turns.js.map +1 -1
- package/dist/components/Accordion/Accordion.cjs.map +1 -1
- package/dist/components/Accordion/Accordion.js.map +1 -1
- package/dist/components/Accordion/Accordion.module.cjs.map +1 -1
- package/dist/components/Accordion/Accordion.module.js.map +1 -1
- package/dist/components/Alert/Alert.cjs.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/Alert/Alert.module.cjs.map +1 -1
- package/dist/components/Alert/Alert.module.js.map +1 -1
- package/dist/components/AppBar/AppBar.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.js.map +1 -1
- package/dist/components/AppBar/AppBar.module.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.module.js.map +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.cjs +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.cjs.map +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.js +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.js.map +1 -1
- package/dist/components/AppShell/AppShell.cjs.map +1 -1
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/AppShell/AppShell.module.cjs.map +1 -1
- package/dist/components/AppShell/AppShell.module.js.map +1 -1
- package/dist/components/AspectRatio/AspectRatio.cjs.map +1 -1
- package/dist/components/AspectRatio/AspectRatio.js.map +1 -1
- package/dist/components/AspectRatio/AspectRatio.module.cjs.map +1 -1
- package/dist/components/AspectRatio/AspectRatio.module.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.js +1 -7
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.js +16 -21
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -1
- package/dist/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.module.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.module.js.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.cjs.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.js.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.module.cjs.map +1 -1
- package/dist/components/AvatarGroup/AvatarGroup.module.js.map +1 -1
- package/dist/components/Badge/Badge.cjs.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.module.cjs.map +1 -1
- package/dist/components/Badge/Badge.module.js.map +1 -1
- package/dist/components/Banner/Banner.cjs.map +1 -1
- package/dist/components/Banner/Banner.js.map +1 -1
- package/dist/components/Banner/Banner.module.cjs.map +1 -1
- package/dist/components/Banner/Banner.module.js.map +1 -1
- package/dist/components/BarList/BarList.cjs.map +1 -1
- package/dist/components/BarList/BarList.js.map +1 -1
- package/dist/components/BarList/BarList.module.cjs.map +1 -1
- package/dist/components/BarList/BarList.module.js.map +1 -1
- package/dist/components/BarList/bar-list-model.cjs.map +1 -1
- package/dist/components/BarList/bar-list-model.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.js.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.module.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.module.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.cjs.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.module.js.map +1 -1
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/Button.module.cjs.map +1 -1
- package/dist/components/Button/Button.module.js.map +1 -1
- package/dist/components/Button/ButtonContent.cjs.map +1 -1
- package/dist/components/Button/ButtonContent.js.map +1 -1
- package/dist/components/Button/ButtonSlot.cjs.map +1 -1
- package/dist/components/Button/ButtonSlot.js.map +1 -1
- package/dist/components/Button/button-class.cjs.map +1 -1
- package/dist/components/Button/button-class.js.map +1 -1
- package/dist/components/Button/link-rel.cjs.map +1 -1
- package/dist/components/Button/link-rel.js.map +1 -1
- package/dist/components/Button/slot.cjs.map +1 -1
- package/dist/components/Button/slot.js.map +1 -1
- package/dist/components/Calendar/Calendar.cjs.map +1 -1
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/Calendar.module.cjs.map +1 -1
- package/dist/components/Calendar/Calendar.module.js.map +1 -1
- package/dist/components/Card/Card.cjs.map +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Card/Card.module.cjs.map +1 -1
- package/dist/components/Card/Card.module.js.map +1 -1
- package/dist/components/Carousel/Carousel.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.js.map +1 -1
- package/dist/components/Carousel/Carousel.module.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.module.js.map +1 -1
- package/dist/components/Center/Center.cjs.map +1 -1
- package/dist/components/Center/Center.js.map +1 -1
- package/dist/components/Center/Center.module.cjs.map +1 -1
- package/dist/components/Center/Center.module.js.map +1 -1
- package/dist/components/Chat/Chat.cjs.map +1 -1
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/Chat/Chat.module.cjs.map +1 -1
- package/dist/components/Chat/Chat.module.js.map +1 -1
- package/dist/components/Chat/ChatActionsMenu.cjs.map +1 -1
- package/dist/components/Chat/ChatActionsMenu.js.map +1 -1
- package/dist/components/Chat/ChatAttachments.cjs.map +1 -1
- package/dist/components/Chat/ChatAttachments.js.map +1 -1
- package/dist/components/Chat/ChatBubble.cjs.map +1 -1
- package/dist/components/Chat/ChatBubble.js.map +1 -1
- package/dist/components/Chat/ChatComposer.cjs.map +1 -1
- package/dist/components/Chat/ChatComposer.js.map +1 -1
- package/dist/components/Chat/chat-groups.cjs +1 -1
- package/dist/components/Chat/chat-groups.cjs.map +1 -1
- package/dist/components/Chat/chat-groups.js +2 -6
- package/dist/components/Chat/chat-groups.js.map +1 -1
- package/dist/components/Chat/chat-receipt.cjs.map +1 -1
- package/dist/components/Chat/chat-receipt.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.js.map +1 -1
- package/dist/components/ChipInput/ChipInput.cjs +1 -1
- package/dist/components/ChipInput/ChipInput.cjs.map +1 -1
- package/dist/components/ChipInput/ChipInput.js +2 -12
- package/dist/components/ChipInput/ChipInput.js.map +1 -1
- package/dist/components/ChipInput/ChipInput.module.cjs.map +1 -1
- package/dist/components/ChipInput/ChipInput.module.js.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.cjs +1 -1
- package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.js +1 -1
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.module.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.module.js.map +1 -1
- package/dist/components/CodeBlock/tokenize.cjs +1 -1
- package/dist/components/CodeBlock/tokenize.cjs.map +1 -1
- package/dist/components/CodeBlock/tokenize.js +54 -25
- package/dist/components/CodeBlock/tokenize.js.map +1 -1
- package/dist/components/Collapsible/Collapsible.cjs.map +1 -1
- package/dist/components/Collapsible/Collapsible.js.map +1 -1
- package/dist/components/Collapsible/Collapsible.module.cjs.map +1 -1
- package/dist/components/Collapsible/Collapsible.module.js.map +1 -1
- package/dist/components/Combobox/Combobox.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.module.js.map +1 -1
- package/dist/components/Combobox/use-listbox-dismiss.cjs.map +1 -1
- package/dist/components/Combobox/use-listbox-dismiss.js.map +1 -1
- package/dist/components/Command/Command.cjs +1 -1
- package/dist/components/Command/Command.cjs.map +1 -1
- package/dist/components/Command/Command.js +4 -11
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/Command/Command.module.cjs.map +1 -1
- package/dist/components/Command/Command.module.js.map +1 -1
- package/dist/components/ConditionalWrapper/ConditionalWrapper.cjs.map +1 -1
- package/dist/components/ConditionalWrapper/ConditionalWrapper.js.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.cjs +1 -1
- package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +1 -1
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.module.cjs.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.module.js.map +1 -1
- package/dist/components/CopyButton/CopyButton.cjs.map +1 -1
- package/dist/components/CopyButton/CopyButton.js.map +1 -1
- package/dist/components/CopyButton/CopyButton.module.cjs.map +1 -1
- package/dist/components/CopyButton/CopyButton.module.js.map +1 -1
- package/dist/components/DataList/DataList.cjs.map +1 -1
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.module.cjs.map +1 -1
- package/dist/components/DataList/DataList.module.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +6 -14
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.module.js.map +1 -1
- package/dist/components/DataTable/EditableCell.cjs +1 -1
- package/dist/components/DataTable/EditableCell.cjs.map +1 -1
- package/dist/components/DataTable/EditableCell.js +1 -9
- package/dist/components/DataTable/EditableCell.js.map +1 -1
- package/dist/components/DataTable/LoadingRows.cjs.map +1 -1
- package/dist/components/DataTable/LoadingRows.js.map +1 -1
- package/dist/components/DataTable/edit-labels.cjs.map +1 -1
- package/dist/components/DataTable/edit-labels.js.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.cjs.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.js.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.module.cjs.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.module.js.map +1 -1
- package/dist/components/Divider/Divider.cjs.map +1 -1
- package/dist/components/Divider/Divider.js.map +1 -1
- package/dist/components/Divider/Divider.module.cjs.map +1 -1
- package/dist/components/Divider/Divider.module.js.map +1 -1
- package/dist/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.js.map +1 -1
- package/dist/components/Drawer/Drawer.module.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.module.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +2 -14
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.module.cjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.module.js.map +1 -1
- package/dist/components/Dropzone/Dropzone.cjs.map +1 -1
- package/dist/components/Dropzone/Dropzone.js.map +1 -1
- package/dist/components/Dropzone/Dropzone.module.cjs.map +1 -1
- package/dist/components/Dropzone/Dropzone.module.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.cjs.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.module.cjs.map +1 -1
- package/dist/components/EmptyState/EmptyState.module.js.map +1 -1
- package/dist/components/ErrorState/ErrorState.cjs.map +1 -1
- package/dist/components/ErrorState/ErrorState.js.map +1 -1
- package/dist/components/ErrorState/ErrorState.module.cjs.map +1 -1
- package/dist/components/ErrorState/ErrorState.module.js.map +1 -1
- package/dist/components/ErrorText/ErrorText.cjs.map +1 -1
- package/dist/components/ErrorText/ErrorText.js.map +1 -1
- package/dist/components/ErrorText/ErrorText.module.cjs.map +1 -1
- package/dist/components/ErrorText/ErrorText.module.js.map +1 -1
- package/dist/components/FileUpload/FileUpload.cjs +1 -1
- package/dist/components/FileUpload/FileUpload.cjs.map +1 -1
- package/dist/components/FileUpload/FileUpload.js +7 -17
- package/dist/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/components/FileUpload/FileUpload.module.cjs.map +1 -1
- package/dist/components/FileUpload/FileUpload.module.js.map +1 -1
- package/dist/components/FilterBar/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar/FilterBar.js.map +1 -1
- package/dist/components/FilterBar/FilterBar.module.cjs.map +1 -1
- package/dist/components/FilterBar/FilterBar.module.js.map +1 -1
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
- package/dist/components/FilterBar/filter-apply.js.map +1 -1
- package/dist/components/FilterBar/filter-model.cjs.map +1 -1
- package/dist/components/FilterBar/filter-model.js.map +1 -1
- package/dist/components/FilterBar/filter-query.cjs +1 -1
- package/dist/components/FilterBar/filter-query.cjs.map +1 -1
- package/dist/components/FilterBar/filter-query.js +2 -5
- package/dist/components/FilterBar/filter-query.js.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.cjs.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.js.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.module.cjs.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.module.js.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.cjs.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.js.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs.map +1 -1
- package/dist/components/FloatingActionButton/FloatingActionButton.module.js.map +1 -1
- package/dist/components/For/For.cjs.map +1 -1
- package/dist/components/For/For.js.map +1 -1
- package/dist/components/Form/Form.cjs.map +1 -1
- package/dist/components/Form/Form.js.map +1 -1
- package/dist/components/Form/Form.module.cjs.map +1 -1
- package/dist/components/Form/Form.module.js.map +1 -1
- package/dist/components/HoverCard/HoverCard.cjs.map +1 -1
- package/dist/components/HoverCard/HoverCard.js.map +1 -1
- package/dist/components/HoverCard/HoverCard.module.cjs.map +1 -1
- package/dist/components/HoverCard/HoverCard.module.js.map +1 -1
- package/dist/components/Image/Image.cjs.map +1 -1
- package/dist/components/Image/Image.js.map +1 -1
- package/dist/components/Image/Image.module.cjs.map +1 -1
- package/dist/components/Image/Image.module.js.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.js +4 -8
- package/dist/components/ImageCropper/ImageCropper.js.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.module.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.module.js.map +1 -1
- package/dist/components/ImageCropper/crop-geometry.cjs.map +1 -1
- package/dist/components/ImageCropper/crop-geometry.js.map +1 -1
- package/dist/components/Input/Input.cjs.map +1 -1
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.module.cjs.map +1 -1
- package/dist/components/Input/Input.module.js.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.cjs.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.js.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.module.cjs.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.module.js.map +1 -1
- package/dist/components/InstallButton/InstallButton.cjs.map +1 -1
- package/dist/components/InstallButton/InstallButton.js.map +1 -1
- package/dist/components/InstallButton/InstallButton.module.cjs.map +1 -1
- package/dist/components/InstallButton/InstallButton.module.js.map +1 -1
- package/dist/components/InstallButton/install-hints.cjs.map +1 -1
- package/dist/components/InstallButton/install-hints.js.map +1 -1
- package/dist/components/Kanban/Kanban.cjs.map +1 -1
- package/dist/components/Kanban/Kanban.js.map +1 -1
- package/dist/components/Kanban/Kanban.module.cjs.map +1 -1
- package/dist/components/Kanban/Kanban.module.js.map +1 -1
- package/dist/components/Kbd/Kbd.cjs.map +1 -1
- package/dist/components/Kbd/Kbd.js.map +1 -1
- package/dist/components/Kbd/Kbd.module.cjs.map +1 -1
- package/dist/components/Kbd/Kbd.module.js.map +1 -1
- package/dist/components/Label/Label.cjs.map +1 -1
- package/dist/components/Label/Label.js.map +1 -1
- package/dist/components/Label/Label.module.cjs.map +1 -1
- package/dist/components/Label/Label.module.js.map +1 -1
- package/dist/components/Layout/Layout.cjs.map +1 -1
- package/dist/components/Layout/Layout.js.map +1 -1
- package/dist/components/Layout/Layout.module.cjs.map +1 -1
- package/dist/components/Layout/Layout.module.js.map +1 -1
- package/dist/components/Lightbox/Lightbox.cjs +1 -1
- package/dist/components/Lightbox/Lightbox.cjs.map +1 -1
- package/dist/components/Lightbox/Lightbox.js +1 -1
- package/dist/components/Lightbox/Lightbox.js.map +1 -1
- package/dist/components/Lightbox/Lightbox.module.cjs.map +1 -1
- package/dist/components/Lightbox/Lightbox.module.js.map +1 -1
- package/dist/components/ListTile/ListTile.cjs.map +1 -1
- package/dist/components/ListTile/ListTile.js.map +1 -1
- package/dist/components/ListTile/ListTile.module.cjs.map +1 -1
- package/dist/components/ListTile/ListTile.module.js.map +1 -1
- package/dist/components/Markdown/Markdown.cjs.map +1 -1
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Markdown/Markdown.module.cjs.map +1 -1
- package/dist/components/Markdown/Markdown.module.js.map +1 -1
- package/dist/components/Markdown/markdown-parse.cjs +6 -6
- package/dist/components/Markdown/markdown-parse.cjs.map +1 -1
- package/dist/components/Markdown/markdown-parse.js +94 -96
- package/dist/components/Markdown/markdown-parse.js.map +1 -1
- package/dist/components/Masonry/Masonry.cjs.map +1 -1
- package/dist/components/Masonry/Masonry.js.map +1 -1
- package/dist/components/Masonry/Masonry.module.cjs.map +1 -1
- package/dist/components/Masonry/Masonry.module.js.map +1 -1
- package/dist/components/Masonry/masonry-layout.cjs.map +1 -1
- package/dist/components/Masonry/masonry-layout.js.map +1 -1
- package/dist/components/Menubar/Menubar.cjs.map +1 -1
- package/dist/components/Menubar/Menubar.js.map +1 -1
- package/dist/components/Menubar/Menubar.module.cjs.map +1 -1
- package/dist/components/Menubar/Menubar.module.js.map +1 -1
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Modal/Modal.module.cjs.map +1 -1
- package/dist/components/Modal/Modal.module.js.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.cjs.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.js.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.module.cjs.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.module.js.map +1 -1
- package/dist/components/Money/Money.cjs.map +1 -1
- package/dist/components/Money/Money.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
- package/dist/components/NProgress/NProgress.cjs.map +1 -1
- package/dist/components/NProgress/NProgress.js.map +1 -1
- package/dist/components/NProgress/NProgress.module.cjs.map +1 -1
- package/dist/components/NProgress/NProgress.module.js.map +1 -1
- package/dist/components/Navbar/Navbar.cjs.map +1 -1
- package/dist/components/Navbar/Navbar.js.map +1 -1
- package/dist/components/Navbar/Navbar.module.cjs.map +1 -1
- package/dist/components/Navbar/Navbar.module.js.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.cjs.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.js.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.module.cjs.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.module.js.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.cjs.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.js.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -1
- package/dist/components/NotificationCenter/use-notification-inbox.cjs.map +1 -1
- package/dist/components/NotificationCenter/use-notification-inbox.js.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.cjs.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.js.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs.map +1 -1
- package/dist/components/OfflineIndicator/OfflineIndicator.module.js.map +1 -1
- package/dist/components/Page/Page.cjs.map +1 -1
- package/dist/components/Page/Page.js.map +1 -1
- package/dist/components/Page/Page.module.cjs.map +1 -1
- package/dist/components/Page/Page.module.js.map +1 -1
- package/dist/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Pagination/Pagination.module.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.module.js.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.module.cjs.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.module.js.map +1 -1
- package/dist/components/PinInput/PinInput.cjs.map +1 -1
- package/dist/components/PinInput/PinInput.js.map +1 -1
- package/dist/components/PinInput/PinInput.module.cjs.map +1 -1
- package/dist/components/PinInput/PinInput.module.js.map +1 -1
- package/dist/components/Popover/Popover.cjs.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/Popover.module.cjs.map +1 -1
- package/dist/components/Popover/Popover.module.js.map +1 -1
- package/dist/components/Portal/Portal.cjs.map +1 -1
- package/dist/components/Portal/Portal.js.map +1 -1
- package/dist/components/Portal/anchor-position.cjs.map +1 -1
- package/dist/components/Portal/anchor-position.js.map +1 -1
- package/dist/components/Portal/escape-layer.cjs.map +1 -1
- package/dist/components/Portal/escape-layer.js.map +1 -1
- package/dist/components/Portal/portal-host.cjs.map +1 -1
- package/dist/components/Portal/portal-host.js.map +1 -1
- package/dist/components/Portal/tab-bridge.cjs +1 -1
- package/dist/components/Portal/tab-bridge.cjs.map +1 -1
- package/dist/components/Portal/tab-bridge.js +1 -5
- package/dist/components/Portal/tab-bridge.js.map +1 -1
- package/dist/components/Progress/Progress.cjs.map +1 -1
- package/dist/components/Progress/Progress.js.map +1 -1
- package/dist/components/Progress/Progress.module.cjs.map +1 -1
- package/dist/components/Progress/Progress.module.js.map +1 -1
- package/dist/components/QRCode/QRCode.cjs.map +1 -1
- package/dist/components/QRCode/QRCode.js.map +1 -1
- package/dist/components/QRCode/QRCode.module.cjs.map +1 -1
- package/dist/components/QRCode/QRCode.module.js.map +1 -1
- package/dist/components/QRCode/qr-encode.cjs +1 -1
- package/dist/components/QRCode/qr-encode.cjs.map +1 -1
- package/dist/components/QRCode/qr-encode.js +7 -13
- package/dist/components/QRCode/qr-encode.js.map +1 -1
- package/dist/components/QRCode/qr-tables.cjs.map +1 -1
- package/dist/components/QRCode/qr-tables.js.map +1 -1
- package/dist/components/Radio/Radio.cjs.map +1 -1
- package/dist/components/Radio/Radio.js.map +1 -1
- package/dist/components/Radio/Radio.module.cjs.map +1 -1
- package/dist/components/Radio/Radio.module.js.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.module.cjs.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.module.js.map +1 -1
- package/dist/components/RatingStars/RatingStars.cjs.map +1 -1
- package/dist/components/RatingStars/RatingStars.js.map +1 -1
- package/dist/components/RatingStars/RatingStars.module.cjs.map +1 -1
- package/dist/components/RatingStars/RatingStars.module.js.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.js +10 -18
- package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.module.js.map +1 -1
- package/dist/components/RelativeTime/RelativeTime.cjs.map +1 -1
- package/dist/components/RelativeTime/RelativeTime.js.map +1 -1
- package/dist/components/Resizable/Resizable.cjs +1 -1
- package/dist/components/Resizable/Resizable.cjs.map +1 -1
- package/dist/components/Resizable/Resizable.js +1 -9
- package/dist/components/Resizable/Resizable.js.map +1 -1
- package/dist/components/Resizable/Resizable.module.cjs.map +1 -1
- package/dist/components/Resizable/Resizable.module.js.map +1 -1
- package/dist/components/Responsive/Responsive.cjs.map +1 -1
- package/dist/components/Responsive/Responsive.js.map +1 -1
- package/dist/components/Reveal/Reveal.cjs.map +1 -1
- package/dist/components/Reveal/Reveal.js.map +1 -1
- package/dist/components/Reveal/Reveal.module.cjs.map +1 -1
- package/dist/components/Reveal/Reveal.module.js.map +1 -1
- package/dist/components/Reveal/reveal-threshold.cjs.map +1 -1
- package/dist/components/Reveal/reveal-threshold.js.map +1 -1
- package/dist/components/SafeArea/SafeArea.cjs.map +1 -1
- package/dist/components/SafeArea/SafeArea.js.map +1 -1
- package/dist/components/SafeArea/SafeArea.module.cjs.map +1 -1
- package/dist/components/SafeArea/SafeArea.module.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
- package/dist/components/Scheduler/scheduler-layout.cjs.map +1 -1
- package/dist/components/Scheduler/scheduler-layout.js.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.cjs.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.js.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.module.js.map +1 -1
- package/dist/components/SearchBar/SearchBar.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.js.map +1 -1
- package/dist/components/SearchBar/SearchBar.module.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.module.js.map +1 -1
- package/dist/components/SectionHeader/SectionHeader.cjs.map +1 -1
- package/dist/components/SectionHeader/SectionHeader.js.map +1 -1
- package/dist/components/SectionHeader/SectionHeader.module.cjs.map +1 -1
- package/dist/components/SectionHeader/SectionHeader.module.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.module.js.map +1 -1
- package/dist/components/Select/CaretIcon.cjs.map +1 -1
- package/dist/components/Select/CaretIcon.js.map +1 -1
- package/dist/components/Select/Select.cjs.map +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/Select.module.cjs.map +1 -1
- package/dist/components/Select/Select.module.js.map +1 -1
- package/dist/components/Select/options.cjs.map +1 -1
- package/dist/components/Select/options.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.cjs +1 -1
- package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.js +13 -23
- package/dist/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
- package/dist/components/Sidebar/SidebarEntry.cjs.map +1 -1
- package/dist/components/Sidebar/SidebarEntry.js.map +1 -1
- package/dist/components/Sidebar/active-nav-key.cjs.map +1 -1
- package/dist/components/Sidebar/active-nav-key.js.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.cjs +1 -1
- package/dist/components/SignaturePad/SignaturePad.cjs.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.js +1 -5
- package/dist/components/SignaturePad/SignaturePad.js.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.module.cjs.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.module.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.cjs.map +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.module.cjs.map +1 -1
- package/dist/components/Skeleton/Skeleton.module.js.map +1 -1
- package/dist/components/Slider/Slider.cjs.map +1 -1
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Slider/Slider.module.cjs.map +1 -1
- package/dist/components/Slider/Slider.module.js.map +1 -1
- package/dist/components/Spacer/Spacer.cjs.map +1 -1
- package/dist/components/Spacer/Spacer.js.map +1 -1
- package/dist/components/Spacer/Spacer.module.cjs.map +1 -1
- package/dist/components/Spacer/Spacer.module.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.cjs.map +1 -1
- package/dist/components/Sparkline/Sparkline.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.module.cjs.map +1 -1
- package/dist/components/Sparkline/Sparkline.module.js.map +1 -1
- package/dist/components/Sparkline/sparkline-geometry.cjs.map +1 -1
- package/dist/components/Sparkline/sparkline-geometry.js.map +1 -1
- package/dist/components/Spinner/Spinner.cjs.map +1 -1
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/Spinner/Spinner.module.cjs.map +1 -1
- package/dist/components/Spinner/Spinner.module.js.map +1 -1
- package/dist/components/Stat/Stat.cjs.map +1 -1
- package/dist/components/Stat/Stat.js.map +1 -1
- package/dist/components/Stat/Stat.module.cjs.map +1 -1
- package/dist/components/Stat/Stat.module.js.map +1 -1
- package/dist/components/Stepper/Stepper.cjs.map +1 -1
- package/dist/components/Stepper/Stepper.js.map +1 -1
- package/dist/components/Stepper/Stepper.module.cjs.map +1 -1
- package/dist/components/Stepper/Stepper.module.js.map +1 -1
- package/dist/components/StepperInput/StepperInput.cjs.map +1 -1
- package/dist/components/StepperInput/StepperInput.js.map +1 -1
- package/dist/components/StepperInput/StepperInput.module.cjs.map +1 -1
- package/dist/components/StepperInput/StepperInput.module.js.map +1 -1
- package/dist/components/Switch/Switch.cjs.map +1 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Switch/Switch.module.cjs.map +1 -1
- package/dist/components/Switch/Switch.module.js.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js.map +1 -1
- package/dist/components/Table/Table.cjs.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.module.cjs.map +1 -1
- package/dist/components/Table/Table.module.js.map +1 -1
- package/dist/components/Tabs/Tabs.cjs.map +1 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tabs/Tabs.module.cjs.map +1 -1
- package/dist/components/Tabs/Tabs.module.js.map +1 -1
- package/dist/components/Tag/Tag.cjs.map +1 -1
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.module.cjs.map +1 -1
- package/dist/components/Tag/Tag.module.js.map +1 -1
- package/dist/components/Textarea/Textarea.cjs.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/Textarea/Textarea.module.cjs.map +1 -1
- package/dist/components/Textarea/Textarea.module.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.cjs.map +1 -1
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.module.cjs.map +1 -1
- package/dist/components/TimePicker/TimePicker.module.js.map +1 -1
- package/dist/components/Timeline/Timeline.cjs.map +1 -1
- package/dist/components/Timeline/Timeline.js.map +1 -1
- package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
- package/dist/components/Timeline/Timeline.module.js.map +1 -1
- package/dist/components/Toast/Toast.module.cjs.map +1 -1
- package/dist/components/Toast/Toast.module.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/components/Toggle/Toggle.cjs.map +1 -1
- package/dist/components/Toggle/Toggle.js.map +1 -1
- package/dist/components/Toggle/Toggle.module.cjs.map +1 -1
- package/dist/components/Toggle/Toggle.module.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.module.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.module.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.module.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.module.js.map +1 -1
- package/dist/components/Tour/Tour.cjs +1 -1
- package/dist/components/Tour/Tour.cjs.map +1 -1
- package/dist/components/Tour/Tour.js +1 -5
- package/dist/components/Tour/Tour.js.map +1 -1
- package/dist/components/Tour/Tour.module.cjs.map +1 -1
- package/dist/components/Tour/Tour.module.js.map +1 -1
- package/dist/components/Tour/tour-position.cjs.map +1 -1
- package/dist/components/Tour/tour-position.js.map +1 -1
- package/dist/components/Transfer/Transfer.cjs.map +1 -1
- package/dist/components/Transfer/Transfer.js.map +1 -1
- package/dist/components/Transfer/Transfer.module.cjs.map +1 -1
- package/dist/components/Transfer/Transfer.module.js.map +1 -1
- package/dist/components/Transfer/transfer-state.cjs.map +1 -1
- package/dist/components/Transfer/transfer-state.js.map +1 -1
- package/dist/components/TreeView/TreeView.cjs.map +1 -1
- package/dist/components/TreeView/TreeView.js.map +1 -1
- package/dist/components/TreeView/TreeView.module.cjs.map +1 -1
- package/dist/components/TreeView/TreeView.module.js.map +1 -1
- package/dist/components/TruncateText/TruncateText.cjs.map +1 -1
- package/dist/components/TruncateText/TruncateText.js.map +1 -1
- package/dist/components/TruncateText/TruncateText.module.cjs.map +1 -1
- package/dist/components/TruncateText/TruncateText.module.js.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.cjs.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.js.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs.map +1 -1
- package/dist/components/UpdatePrompt/UpdatePrompt.module.js.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.cjs +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.cjs.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.js +1 -7
- package/dist/components/VideoPlayer/VideoPlayer.js.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -1
- package/dist/components/VideoPlayer/playback-rates.cjs.map +1 -1
- package/dist/components/VideoPlayer/playback-rates.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.module.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.module.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.cjs.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.js.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.module.js.map +1 -1
- package/dist/components/Wizard/Wizard.cjs +1 -1
- package/dist/components/Wizard/Wizard.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.js +4 -11
- package/dist/components/Wizard/Wizard.js.map +1 -1
- package/dist/components/Wizard/Wizard.module.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.module.js.map +1 -1
- package/dist/data/create-data-provider.cjs.map +1 -1
- package/dist/data/create-data-provider.js.map +1 -1
- package/dist/data/data-provider-context.cjs.map +1 -1
- package/dist/data/data-provider-context.js.map +1 -1
- package/dist/data/use-resource.cjs.map +1 -1
- package/dist/data/use-resource.js.map +1 -1
- package/dist/editor/RichTextEditor.cjs.map +1 -1
- package/dist/editor/RichTextEditor.js.map +1 -1
- package/dist/editor/RichTextEditor.module.cjs.map +1 -1
- package/dist/editor/RichTextEditor.module.js.map +1 -1
- package/dist/editor.js +1 -2
- package/dist/error-boundary/ErrorBoundary.cjs.map +1 -1
- package/dist/error-boundary/ErrorBoundary.js.map +1 -1
- package/dist/error-boundary/use-error-handler.cjs.map +1 -1
- package/dist/error-boundary/use-error-handler.js.map +1 -1
- package/dist/feature-flags/FeatureFlagsProvider.cjs.map +1 -1
- package/dist/feature-flags/FeatureFlagsProvider.js.map +1 -1
- package/dist/feature-flags/growthbook-adapter.cjs.map +1 -1
- package/dist/feature-flags/growthbook-adapter.js.map +1 -1
- package/dist/feature-flags/in-memory-adapter.cjs.map +1 -1
- package/dist/feature-flags/in-memory-adapter.js.map +1 -1
- package/dist/feature-flags/launchdarkly-adapter.cjs.map +1 -1
- package/dist/feature-flags/launchdarkly-adapter.js.map +1 -1
- package/dist/forms/FormField.cjs.map +1 -1
- package/dist/forms/FormField.js.map +1 -1
- package/dist/forms/br-validators.cjs.map +1 -1
- package/dist/forms/br-validators.js.map +1 -1
- package/dist/forms/masked-inputs.cjs.map +1 -1
- package/dist/forms/masked-inputs.js.map +1 -1
- package/dist/forms/use-viacep.cjs.map +1 -1
- package/dist/forms/use-viacep.js.map +1 -1
- package/dist/forms/use-zod-form.cjs.map +1 -1
- package/dist/forms/use-zod-form.js.map +1 -1
- package/dist/forms/validate-form.cjs.map +1 -1
- package/dist/forms/validate-form.js.map +1 -1
- package/dist/forms/zod-resolver.cjs.map +1 -1
- package/dist/forms/zod-resolver.js.map +1 -1
- package/dist/geo/TrajectoryMap.cjs.map +1 -1
- package/dist/geo/TrajectoryMap.js.map +1 -1
- package/dist/geo/TrajectoryMap.module.cjs.map +1 -1
- package/dist/geo/TrajectoryMap.module.js.map +1 -1
- package/dist/geo/bounds.cjs.map +1 -1
- package/dist/geo/bounds.js.map +1 -1
- package/dist/geo/create-position-tracker.cjs +1 -1
- package/dist/geo/create-position-tracker.cjs.map +1 -1
- package/dist/geo/create-position-tracker.js +1 -7
- package/dist/geo/create-position-tracker.js.map +1 -1
- package/dist/geo/distance.cjs.map +1 -1
- package/dist/geo/distance.js.map +1 -1
- package/dist/geo/estimate.cjs.map +1 -1
- package/dist/geo/estimate.js.map +1 -1
- package/dist/geo/leaflet-map.cjs.map +1 -1
- package/dist/geo/leaflet-map.js.map +1 -1
- package/dist/geo/projection.cjs.map +1 -1
- package/dist/geo/projection.js.map +1 -1
- package/dist/geo/routing.cjs.map +1 -1
- package/dist/geo/routing.js.map +1 -1
- package/dist/geo/types.cjs.map +1 -1
- package/dist/geo/types.js.map +1 -1
- package/dist/geo/use-position-tracker.cjs.map +1 -1
- package/dist/geo/use-position-tracker.js.map +1 -1
- package/dist/hooks/pwa-env.cjs.map +1 -1
- package/dist/hooks/pwa-env.js.map +1 -1
- package/dist/hooks/tab-sequence.cjs.map +1 -1
- package/dist/hooks/tab-sequence.js.map +1 -1
- package/dist/hooks/use-announce.cjs +1 -1
- package/dist/hooks/use-announce.cjs.map +1 -1
- package/dist/hooks/use-announce.js +2 -2
- package/dist/hooks/use-announce.js.map +1 -1
- package/dist/hooks/use-async.cjs.map +1 -1
- package/dist/hooks/use-async.js.map +1 -1
- package/dist/hooks/use-before-install-prompt.cjs.map +1 -1
- package/dist/hooks/use-before-install-prompt.js.map +1 -1
- package/dist/hooks/use-breakpoint.cjs.map +1 -1
- package/dist/hooks/use-breakpoint.js.map +1 -1
- package/dist/hooks/use-click-outside.cjs.map +1 -1
- package/dist/hooks/use-click-outside.js.map +1 -1
- package/dist/hooks/use-client-filter.cjs.map +1 -1
- package/dist/hooks/use-client-filter.js.map +1 -1
- package/dist/hooks/use-clipboard.cjs.map +1 -1
- package/dist/hooks/use-clipboard.js.map +1 -1
- package/dist/hooks/use-countdown.cjs.map +1 -1
- package/dist/hooks/use-countdown.js.map +1 -1
- package/dist/hooks/use-counter.cjs.map +1 -1
- package/dist/hooks/use-counter.js.map +1 -1
- package/dist/hooks/use-debounce.cjs.map +1 -1
- package/dist/hooks/use-debounce.js.map +1 -1
- package/dist/hooks/use-deep-memo.cjs.map +1 -1
- package/dist/hooks/use-deep-memo.js.map +1 -1
- package/dist/hooks/use-disclosure.cjs.map +1 -1
- package/dist/hooks/use-disclosure.js.map +1 -1
- package/dist/hooks/use-document-title.cjs.map +1 -1
- package/dist/hooks/use-document-title.js.map +1 -1
- package/dist/hooks/use-document-visibility.cjs.map +1 -1
- package/dist/hooks/use-document-visibility.js.map +1 -1
- package/dist/hooks/use-draft-filters.cjs.map +1 -1
- package/dist/hooks/use-draft-filters.js.map +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-event-listener.js.map +1 -1
- package/dist/hooks/use-favicon.cjs.map +1 -1
- package/dist/hooks/use-favicon.js.map +1 -1
- package/dist/hooks/use-focus-trap.cjs.map +1 -1
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-fullscreen-element.cjs.map +1 -1
- package/dist/hooks/use-fullscreen-element.js.map +1 -1
- package/dist/hooks/use-fullscreen.cjs +1 -1
- package/dist/hooks/use-fullscreen.cjs.map +1 -1
- package/dist/hooks/use-fullscreen.js +7 -23
- package/dist/hooks/use-fullscreen.js.map +1 -1
- package/dist/hooks/use-geolocation.cjs.map +1 -1
- package/dist/hooks/use-geolocation.js.map +1 -1
- package/dist/hooks/use-hover.cjs.map +1 -1
- package/dist/hooks/use-hover.js.map +1 -1
- package/dist/hooks/use-idle.cjs.map +1 -1
- package/dist/hooks/use-idle.js.map +1 -1
- package/dist/hooks/use-install-prompt.cjs +1 -1
- package/dist/hooks/use-install-prompt.cjs.map +1 -1
- package/dist/hooks/use-install-prompt.js +1 -1
- package/dist/hooks/use-install-prompt.js.map +1 -1
- package/dist/hooks/use-intersection-observer.cjs.map +1 -1
- package/dist/hooks/use-intersection-observer.js.map +1 -1
- package/dist/hooks/use-interval.cjs.map +1 -1
- package/dist/hooks/use-interval.js.map +1 -1
- package/dist/hooks/use-is-first-render.cjs.map +1 -1
- package/dist/hooks/use-is-first-render.js.map +1 -1
- package/dist/hooks/use-keyboard-shortcut.cjs.map +1 -1
- package/dist/hooks/use-keyboard-shortcut.js.map +1 -1
- package/dist/hooks/use-latest-ref.cjs.map +1 -1
- package/dist/hooks/use-latest-ref.js.map +1 -1
- package/dist/hooks/use-list-state.cjs.map +1 -1
- package/dist/hooks/use-list-state.js.map +1 -1
- package/dist/hooks/use-local-storage.cjs +1 -1
- package/dist/hooks/use-local-storage.cjs.map +1 -1
- package/dist/hooks/use-local-storage.js +2 -5
- package/dist/hooks/use-local-storage.js.map +1 -1
- package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
- package/dist/hooks/use-long-press-handlers.js.map +1 -1
- package/dist/hooks/use-long-press.cjs.map +1 -1
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-map.cjs.map +1 -1
- package/dist/hooks/use-map.js.map +1 -1
- package/dist/hooks/use-media-devices.cjs.map +1 -1
- package/dist/hooks/use-media-devices.js.map +1 -1
- package/dist/hooks/use-media-permission.cjs +1 -1
- package/dist/hooks/use-media-permission.cjs.map +1 -1
- package/dist/hooks/use-media-permission.js +2 -5
- package/dist/hooks/use-media-permission.js.map +1 -1
- package/dist/hooks/use-media-query.cjs.map +1 -1
- package/dist/hooks/use-media-query.js.map +1 -1
- package/dist/hooks/use-object-url.cjs.map +1 -1
- package/dist/hooks/use-object-url.js.map +1 -1
- package/dist/hooks/use-online.cjs.map +1 -1
- package/dist/hooks/use-online.js.map +1 -1
- package/dist/hooks/use-pagination.cjs.map +1 -1
- package/dist/hooks/use-pagination.js.map +1 -1
- package/dist/hooks/use-previous.cjs.map +1 -1
- package/dist/hooks/use-previous.js.map +1 -1
- package/dist/hooks/use-push-to-talk.cjs.map +1 -1
- package/dist/hooks/use-push-to-talk.js.map +1 -1
- package/dist/hooks/use-queue.cjs.map +1 -1
- package/dist/hooks/use-queue.js.map +1 -1
- package/dist/hooks/use-resize-observer.cjs.map +1 -1
- package/dist/hooks/use-resize-observer.js.map +1 -1
- package/dist/hooks/use-scroll-lock.cjs.map +1 -1
- package/dist/hooks/use-scroll-lock.js.map +1 -1
- package/dist/hooks/use-scroll-overflow.cjs.map +1 -1
- package/dist/hooks/use-scroll-overflow.js.map +1 -1
- package/dist/hooks/use-service-worker-update.cjs.map +1 -1
- package/dist/hooks/use-service-worker-update.js.map +1 -1
- package/dist/hooks/use-set.cjs.map +1 -1
- package/dist/hooks/use-set.js.map +1 -1
- package/dist/hooks/use-sortable.cjs.map +1 -1
- package/dist/hooks/use-sortable.js.map +1 -1
- package/dist/hooks/use-stable-callback.cjs.map +1 -1
- package/dist/hooks/use-stable-callback.js.map +1 -1
- package/dist/hooks/use-storage-estimate.cjs.map +1 -1
- package/dist/hooks/use-storage-estimate.js.map +1 -1
- package/dist/hooks/use-throttle.cjs.map +1 -1
- package/dist/hooks/use-throttle.js.map +1 -1
- package/dist/hooks/use-timeout.cjs.map +1 -1
- package/dist/hooks/use-timeout.js.map +1 -1
- package/dist/hooks/use-toggle.cjs.map +1 -1
- package/dist/hooks/use-toggle.js.map +1 -1
- package/dist/hooks/use-typewriter.cjs.map +1 -1
- package/dist/hooks/use-typewriter.js.map +1 -1
- package/dist/hooks/use-window-size.cjs.map +1 -1
- package/dist/hooks/use-window-size.js.map +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/build-url.cjs.map +1 -1
- package/dist/http/build-url.js.map +1 -1
- package/dist/http/credential-scope.cjs.map +1 -1
- package/dist/http/credential-scope.js.map +1 -1
- package/dist/http/csrf.cjs.map +1 -1
- package/dist/http/csrf.js.map +1 -1
- package/dist/http/decode-response.cjs.map +1 -1
- package/dist/http/decode-response.js.map +1 -1
- package/dist/http/describe-api-error.cjs.map +1 -1
- package/dist/http/describe-api-error.js.map +1 -1
- package/dist/http/errors.cjs.map +1 -1
- package/dist/http/errors.js.map +1 -1
- package/dist/http/idempotency.cjs.map +1 -1
- package/dist/http/idempotency.js.map +1 -1
- package/dist/http/parse-response.cjs.map +1 -1
- package/dist/http/parse-response.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +141 -105
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +5 -6
- package/dist/http/retry.js.map +1 -1
- package/dist/http/timeout.cjs.map +1 -1
- package/dist/http/timeout.js.map +1 -1
- package/dist/http/upload-with-progress.cjs +1 -1
- package/dist/http/upload-with-progress.cjs.map +1 -1
- package/dist/http/upload-with-progress.js +2 -7
- package/dist/http/upload-with-progress.js.map +1 -1
- package/dist/http/use-describe-api-error.cjs.map +1 -1
- package/dist/http/use-describe-api-error.js.map +1 -1
- package/dist/http/use-poll.cjs +1 -1
- package/dist/http/use-poll.cjs.map +1 -1
- package/dist/http/use-poll.js +2 -5
- package/dist/http/use-poll.js.map +1 -1
- package/dist/i18n/I18nProvider.cjs.map +1 -1
- package/dist/i18n/I18nProvider.js.map +1 -1
- package/dist/i18n/create-i18n.cjs.map +1 -1
- package/dist/i18n/create-i18n.js.map +1 -1
- package/dist/icons/Icon.cjs.map +1 -1
- package/dist/icons/Icon.js.map +1 -1
- package/dist/icons/IconPicker.cjs.map +1 -1
- package/dist/icons/IconPicker.js.map +1 -1
- package/dist/icons/IconPicker.module.cjs.map +1 -1
- package/dist/icons/IconPicker.module.js.map +1 -1
- package/dist/icons/IconProvider.cjs.map +1 -1
- package/dist/icons/IconProvider.js.map +1 -1
- package/dist/icons/alias.cjs.map +1 -1
- package/dist/icons/alias.js.map +1 -1
- package/dist/icons/generated/aliases.cjs.map +1 -1
- package/dist/icons/generated/aliases.js.map +1 -1
- package/dist/icons/generated/icon-names.cjs.map +1 -1
- package/dist/icons/generated/icon-names.js.map +1 -1
- package/dist/icons/generated/loaders.cjs.map +1 -1
- package/dist/icons/generated/loaders.js.map +1 -1
- package/dist/icons/generated/shard-00.cjs.map +1 -1
- package/dist/icons/generated/shard-00.js.map +1 -1
- package/dist/icons/generated/shard-01.cjs.map +1 -1
- package/dist/icons/generated/shard-01.js.map +1 -1
- package/dist/icons/generated/shard-02.cjs.map +1 -1
- package/dist/icons/generated/shard-02.js.map +1 -1
- package/dist/icons/generated/shard-03.cjs.map +1 -1
- package/dist/icons/generated/shard-03.js.map +1 -1
- package/dist/icons/generated/shard-04.cjs.map +1 -1
- package/dist/icons/generated/shard-04.js.map +1 -1
- package/dist/icons/generated/shard-05.cjs.map +1 -1
- package/dist/icons/generated/shard-05.js.map +1 -1
- package/dist/icons/generated/shard-06.cjs.map +1 -1
- package/dist/icons/generated/shard-06.js.map +1 -1
- package/dist/icons/generated/shard-07.cjs.map +1 -1
- package/dist/icons/generated/shard-07.js.map +1 -1
- package/dist/icons/generated/shard-08.cjs.map +1 -1
- package/dist/icons/generated/shard-08.js.map +1 -1
- package/dist/icons/generated/shard-09.cjs.map +1 -1
- package/dist/icons/generated/shard-09.js.map +1 -1
- package/dist/icons/generated/shard-10.cjs.map +1 -1
- package/dist/icons/generated/shard-10.js.map +1 -1
- package/dist/icons/generated/shard-11.cjs.map +1 -1
- package/dist/icons/generated/shard-11.js.map +1 -1
- package/dist/icons/generated/shard-12.cjs.map +1 -1
- package/dist/icons/generated/shard-12.js.map +1 -1
- package/dist/icons/generated/shard-13.cjs.map +1 -1
- package/dist/icons/generated/shard-13.js.map +1 -1
- package/dist/icons/generated/shard-14.cjs.map +1 -1
- package/dist/icons/generated/shard-14.js.map +1 -1
- package/dist/icons/generated/shard-15.cjs.map +1 -1
- package/dist/icons/generated/shard-15.js.map +1 -1
- package/dist/icons/generated/shard-16.cjs.map +1 -1
- package/dist/icons/generated/shard-16.js.map +1 -1
- package/dist/icons/generated/shard-17.cjs.map +1 -1
- package/dist/icons/generated/shard-17.js.map +1 -1
- package/dist/icons/generated/shard-18.cjs.map +1 -1
- package/dist/icons/generated/shard-18.js.map +1 -1
- package/dist/icons/generated/shard-19.cjs.map +1 -1
- package/dist/icons/generated/shard-19.js.map +1 -1
- package/dist/icons/generated/shard-20.cjs.map +1 -1
- package/dist/icons/generated/shard-20.js.map +1 -1
- package/dist/icons/generated/shard-21.cjs.map +1 -1
- package/dist/icons/generated/shard-21.js.map +1 -1
- package/dist/icons/generated/shard-22.cjs.map +1 -1
- package/dist/icons/generated/shard-22.js.map +1 -1
- package/dist/icons/generated/shard-23.cjs.map +1 -1
- package/dist/icons/generated/shard-23.js.map +1 -1
- package/dist/icons/generated/shard-24.cjs.map +1 -1
- package/dist/icons/generated/shard-24.js.map +1 -1
- package/dist/icons/generated/shard-25.cjs.map +1 -1
- package/dist/icons/generated/shard-25.js.map +1 -1
- package/dist/icons/generated/shard-26.cjs.map +1 -1
- package/dist/icons/generated/shard-26.js.map +1 -1
- package/dist/icons/generated/shard-27.cjs.map +1 -1
- package/dist/icons/generated/shard-27.js.map +1 -1
- package/dist/icons/generated/shard-28.cjs.map +1 -1
- package/dist/icons/generated/shard-28.js.map +1 -1
- package/dist/icons/generated/shard-29.cjs.map +1 -1
- package/dist/icons/generated/shard-29.js.map +1 -1
- package/dist/icons/generated/shard-30.cjs.map +1 -1
- package/dist/icons/generated/shard-30.js.map +1 -1
- package/dist/icons/generated/shard-31.cjs.map +1 -1
- package/dist/icons/generated/shard-31.js.map +1 -1
- package/dist/icons/generated/shard-32.cjs.map +1 -1
- package/dist/icons/generated/shard-32.js.map +1 -1
- package/dist/icons/generated/shard-33.cjs.map +1 -1
- package/dist/icons/generated/shard-33.js.map +1 -1
- package/dist/icons/generated/shard-34.cjs.map +1 -1
- package/dist/icons/generated/shard-34.js.map +1 -1
- package/dist/icons/generated/shard-35.cjs.map +1 -1
- package/dist/icons/generated/shard-35.js.map +1 -1
- package/dist/icons/generated/shard-36.cjs.map +1 -1
- package/dist/icons/generated/shard-36.js.map +1 -1
- package/dist/icons/generated/shard-37.cjs.map +1 -1
- package/dist/icons/generated/shard-37.js.map +1 -1
- package/dist/icons/generated/shard-38.cjs.map +1 -1
- package/dist/icons/generated/shard-38.js.map +1 -1
- package/dist/icons/generated/shard-39.cjs.map +1 -1
- package/dist/icons/generated/shard-39.js.map +1 -1
- package/dist/icons/generated/shard-40.cjs.map +1 -1
- package/dist/icons/generated/shard-40.js.map +1 -1
- package/dist/icons/generated/shard-41.cjs.map +1 -1
- package/dist/icons/generated/shard-41.js.map +1 -1
- package/dist/icons/generated/shard-42.cjs.map +1 -1
- package/dist/icons/generated/shard-42.js.map +1 -1
- package/dist/icons/generated/shard-43.cjs.map +1 -1
- package/dist/icons/generated/shard-43.js.map +1 -1
- package/dist/icons/generated/shard-44.cjs.map +1 -1
- package/dist/icons/generated/shard-44.js.map +1 -1
- package/dist/icons/generated/shard-45.cjs.map +1 -1
- package/dist/icons/generated/shard-45.js.map +1 -1
- package/dist/icons/icon-context.cjs.map +1 -1
- package/dist/icons/icon-context.js.map +1 -1
- package/dist/icons/is-icon-name.cjs.map +1 -1
- package/dist/icons/is-icon-name.js.map +1 -1
- package/dist/icons/material-symbols.cjs.map +1 -1
- package/dist/icons/material-symbols.js.map +1 -1
- package/dist/icons/normalize-icon-name.cjs.map +1 -1
- package/dist/icons/normalize-icon-name.js.map +1 -1
- package/dist/icons/shard-cache.cjs +1 -1
- package/dist/icons/shard-cache.cjs.map +1 -1
- package/dist/icons/shard-cache.js +2 -5
- package/dist/icons/shard-cache.js.map +1 -1
- package/dist/icons/use-icon.cjs.map +1 -1
- package/dist/icons/use-icon.js.map +1 -1
- package/dist/icons/validate-icon-name.cjs.map +1 -1
- package/dist/icons/validate-icon-name.js.map +1 -1
- package/dist/icons-virtual.cjs.map +1 -1
- package/dist/icons-virtual.js.map +1 -1
- package/dist/imaging/canvas.cjs.map +1 -1
- package/dist/imaging/canvas.js.map +1 -1
- package/dist/imaging/compress.cjs.map +1 -1
- package/dist/imaging/compress.js.map +1 -1
- package/dist/imaging/decode.cjs.map +1 -1
- package/dist/imaging/decode.js.map +1 -1
- package/dist/imaging/encode.cjs.map +1 -1
- package/dist/imaging/encode.js.map +1 -1
- package/dist/imaging/exceptions.cjs.map +1 -1
- package/dist/imaging/exceptions.js.map +1 -1
- package/dist/imaging/frame.cjs.map +1 -1
- package/dist/imaging/frame.js.map +1 -1
- package/dist/imaging/thumbnails.cjs.map +1 -1
- package/dist/imaging/thumbnails.js.map +1 -1
- package/dist/imaging/transform.cjs.map +1 -1
- package/dist/imaging/transform.js.map +1 -1
- package/dist/imaging/use-image-processing.cjs.map +1 -1
- package/dist/imaging/use-image-processing.js.map +1 -1
- package/dist/logger/logger.cjs.map +1 -1
- package/dist/logger/logger.js.map +1 -1
- package/dist/neural.cjs.map +1 -1
- package/dist/neural.js.map +1 -1
- package/dist/oauth/GoogleSignIn.cjs +1 -1
- package/dist/oauth/GoogleSignIn.cjs.map +1 -1
- package/dist/oauth/GoogleSignIn.js +6 -9
- package/dist/oauth/GoogleSignIn.js.map +1 -1
- package/dist/oauth/callback.cjs.map +1 -1
- package/dist/oauth/callback.js.map +1 -1
- package/dist/oauth/use-oauth-callback.cjs.map +1 -1
- package/dist/oauth/use-oauth-callback.js.map +1 -1
- package/dist/offline/conflict.cjs.map +1 -1
- package/dist/offline/conflict.js.map +1 -1
- package/dist/offline/create-offline-database.cjs.map +1 -1
- package/dist/offline/create-offline-database.js.map +1 -1
- package/dist/offline/create-offline-store.cjs +1 -1
- package/dist/offline/create-offline-store.cjs.map +1 -1
- package/dist/offline/create-offline-store.js +1 -5
- package/dist/offline/create-offline-store.js.map +1 -1
- package/dist/offline/create-offline-sync.cjs +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js +9 -14
- package/dist/offline/create-offline-sync.js.map +1 -1
- package/dist/offline/use-offline-sync.cjs.map +1 -1
- package/dist/offline/use-offline-sync.js.map +1 -1
- package/dist/perf/cache-size.cjs.map +1 -1
- package/dist/perf/cache-size.js.map +1 -1
- package/dist/perf/device.cjs.map +1 -1
- package/dist/perf/device.js.map +1 -1
- package/dist/perf/format.cjs.map +1 -1
- package/dist/perf/format.js.map +1 -1
- package/dist/perf/profiler.cjs.map +1 -1
- package/dist/perf/profiler.js.map +1 -1
- package/dist/push/use-push-subscription.cjs.map +1 -1
- package/dist/push/use-push-subscription.js.map +1 -1
- package/dist/push/utils.cjs.map +1 -1
- package/dist/push/utils.js.map +1 -1
- package/dist/push/web-push-client.cjs.map +1 -1
- package/dist/push/web-push-client.js.map +1 -1
- package/dist/query/QueryProvider.cjs.map +1 -1
- package/dist/query/QueryProvider.js.map +1 -1
- package/dist/query/constants.cjs.map +1 -1
- package/dist/query/constants.js.map +1 -1
- package/dist/query/create-query-keys.cjs.map +1 -1
- package/dist/query/create-query-keys.js.map +1 -1
- package/dist/query/foreign-client-warning.cjs.map +1 -1
- package/dist/query/foreign-client-warning.js.map +1 -1
- package/dist/query/offline-persistence.cjs +1 -1
- package/dist/query/offline-persistence.cjs.map +1 -1
- package/dist/query/offline-persistence.js +2 -10
- package/dist/query/offline-persistence.js.map +1 -1
- package/dist/query/optimistic.cjs.map +1 -1
- package/dist/query/optimistic.js.map +1 -1
- package/dist/query/pagination.cjs.map +1 -1
- package/dist/query/pagination.js.map +1 -1
- package/dist/query/retry-policy.cjs.map +1 -1
- package/dist/query/retry-policy.js.map +1 -1
- package/dist/query/use-cursor-query.cjs.map +1 -1
- package/dist/query/use-cursor-query.js.map +1 -1
- package/dist/query/use-offline-mutation.cjs.map +1 -1
- package/dist/query/use-offline-mutation.js.map +1 -1
- package/dist/query/use-paginated-query.cjs.map +1 -1
- package/dist/query/use-paginated-query.js.map +1 -1
- package/dist/router/AppRouter.cjs.map +1 -1
- package/dist/router/AppRouter.js.map +1 -1
- package/dist/router/RouteGuard.cjs.map +1 -1
- package/dist/router/RouteGuard.js.map +1 -1
- package/dist/router/index.js +2 -2
- package/dist/share/share-or-download.cjs.map +1 -1
- package/dist/share/share-or-download.js.map +1 -1
- package/dist/share/share.cjs.map +1 -1
- package/dist/share/share.js.map +1 -1
- package/dist/sse/create-event-stream.cjs.map +1 -1
- package/dist/sse/create-event-stream.js.map +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/sse/use-event-stream.js.map +1 -1
- package/dist/store/create-selectors.cjs.map +1 -1
- package/dist/store/create-selectors.js.map +1 -1
- package/dist/store/create-store.cjs.map +1 -1
- package/dist/store/create-store.js.map +1 -1
- package/dist/sw/background-sync.cjs +1 -1
- package/dist/sw/background-sync.cjs.map +1 -1
- package/dist/sw/background-sync.js +32 -31
- package/dist/sw/background-sync.js.map +1 -1
- package/dist/sw/cache-inspect.cjs.map +1 -1
- package/dist/sw/cache-inspect.js.map +1 -1
- package/dist/sw/cache.cjs +1 -1
- package/dist/sw/cache.cjs.map +1 -1
- package/dist/sw/cache.js +2 -6
- package/dist/sw/cache.js.map +1 -1
- package/dist/sw/create-push-handler.cjs.map +1 -1
- package/dist/sw/create-push-handler.js.map +1 -1
- package/dist/sw/credential-headers.cjs.map +1 -1
- package/dist/sw/credential-headers.js.map +1 -1
- package/dist/sw/periodic-sync.cjs.map +1 -1
- package/dist/sw/periodic-sync.js.map +1 -1
- package/dist/sw/register-service-worker.cjs.map +1 -1
- package/dist/sw/register-service-worker.js.map +1 -1
- package/dist/sw/session-data.cjs.map +1 -1
- package/dist/sw/session-data.js.map +1 -1
- package/dist/sw.d.ts +46 -8
- package/dist/tabular/assets.cjs.map +1 -1
- package/dist/tabular/assets.js.map +1 -1
- package/dist/tabular/cache.cjs.map +1 -1
- package/dist/tabular/cache.js.map +1 -1
- package/dist/tabular/compact.cjs.map +1 -1
- package/dist/tabular/compact.js.map +1 -1
- package/dist/tabular/exceptions.cjs.map +1 -1
- package/dist/tabular/exceptions.js.map +1 -1
- package/dist/tabular/manifest.cjs.map +1 -1
- package/dist/tabular/manifest.js.map +1 -1
- package/dist/tabular/predictor.cjs.map +1 -1
- package/dist/tabular/predictor.js.map +1 -1
- package/dist/tabular/use-tabular-predictor.cjs.map +1 -1
- package/dist/tabular/use-tabular-predictor.js.map +1 -1
- package/dist/telemetry/TelemetryProvider.cjs.map +1 -1
- package/dist/telemetry/TelemetryProvider.js.map +1 -1
- package/dist/telemetry/app-error-adapter.cjs.map +1 -1
- package/dist/telemetry/app-error-adapter.js.map +1 -1
- package/dist/telemetry/app-error-queue.cjs.map +1 -1
- package/dist/telemetry/app-error-queue.js.map +1 -1
- package/dist/telemetry/app-error-reporter.cjs +1 -1
- package/dist/telemetry/app-error-reporter.cjs.map +1 -1
- package/dist/telemetry/app-error-reporter.js +1 -1
- package/dist/telemetry/app-error-reporter.js.map +1 -1
- package/dist/telemetry/app-error-schema.cjs.map +1 -1
- package/dist/telemetry/app-error-schema.js.map +1 -1
- package/dist/telemetry/app-error-transport.cjs.map +1 -1
- package/dist/telemetry/app-error-transport.js.map +1 -1
- package/dist/telemetry/console-adapter.cjs.map +1 -1
- package/dist/telemetry/console-adapter.js.map +1 -1
- package/dist/telemetry/describe-app-error.cjs.map +1 -1
- package/dist/telemetry/describe-app-error.js.map +1 -1
- package/dist/telemetry/posthog-adapter.cjs +1 -1
- package/dist/telemetry/posthog-adapter.cjs.map +1 -1
- package/dist/telemetry/posthog-adapter.js +1 -5
- package/dist/telemetry/posthog-adapter.js.map +1 -1
- package/dist/telemetry/sentry-adapter.cjs.map +1 -1
- package/dist/telemetry/sentry-adapter.js.map +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +448 -15
- package/dist/tempest-react-sdk.js +119 -119
- package/dist/testing/create-mock-handlers.cjs.map +1 -1
- package/dist/testing/create-mock-handlers.js.map +1 -1
- package/dist/testing.js +1 -2
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/apply-theme.cjs.map +1 -1
- package/dist/theme/apply-theme.js.map +1 -1
- package/dist/theme/color.cjs.map +1 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/create-theme.cjs.map +1 -1
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/theme/data-viz-ramps.cjs.map +1 -1
- package/dist/theme/data-viz-ramps.js.map +1 -1
- package/dist/theme/initial-theme.cjs.map +1 -1
- package/dist/theme/initial-theme.js.map +1 -1
- package/dist/theme/inverse-render.cjs.map +1 -1
- package/dist/theme/inverse-render.js.map +1 -1
- package/dist/theme/inverse-restore.cjs.map +1 -1
- package/dist/theme/inverse-restore.js.map +1 -1
- package/dist/theme/inverse-surface.cjs.map +1 -1
- package/dist/theme/inverse-surface.js.map +1 -1
- package/dist/theme/status-tokens.cjs.map +1 -1
- package/dist/theme/status-tokens.js.map +1 -1
- package/dist/theme/theme-presets.cjs.map +1 -1
- package/dist/theme/theme-presets.js.map +1 -1
- package/dist/utils/absent.cjs.map +1 -1
- package/dist/utils/absent.js.map +1 -1
- package/dist/utils/arrays.cjs.map +1 -1
- package/dist/utils/arrays.js.map +1 -1
- package/dist/utils/base64.cjs.map +1 -1
- package/dist/utils/base64.js.map +1 -1
- package/dist/utils/cn.cjs.map +1 -1
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/compare-values.cjs.map +1 -1
- package/dist/utils/compare-values.js.map +1 -1
- package/dist/utils/compressed-storage.cjs.map +1 -1
- package/dist/utils/compressed-storage.js.map +1 -1
- package/dist/utils/csv.cjs +3 -3
- package/dist/utils/csv.cjs.map +1 -1
- package/dist/utils/csv.js +11 -10
- package/dist/utils/csv.js.map +1 -1
- package/dist/utils/dev-mode.cjs.map +1 -1
- package/dist/utils/dev-mode.js.map +1 -1
- package/dist/utils/duplicate-instance.cjs.map +1 -1
- package/dist/utils/duplicate-instance.js.map +1 -1
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/functions.cjs +1 -1
- package/dist/utils/functions.cjs.map +1 -1
- package/dist/utils/functions.js +1 -1
- package/dist/utils/functions.js.map +1 -1
- package/dist/utils/guards.cjs.map +1 -1
- package/dist/utils/guards.js.map +1 -1
- package/dist/utils/ids.cjs.map +1 -1
- package/dist/utils/ids.js.map +1 -1
- package/dist/utils/intl-cache.cjs.map +1 -1
- package/dist/utils/intl-cache.js.map +1 -1
- package/dist/utils/json-frame.cjs.map +1 -1
- package/dist/utils/json-frame.js.map +1 -1
- package/dist/utils/numbers.cjs.map +1 -1
- package/dist/utils/numbers.js.map +1 -1
- package/dist/utils/objects.cjs.map +1 -1
- package/dist/utils/objects.js.map +1 -1
- package/dist/{telemetry/app-error-owner.cjs → utils/owner-fingerprint.cjs} +2 -2
- package/dist/utils/owner-fingerprint.cjs.map +1 -0
- package/dist/{telemetry/app-error-owner.js → utils/owner-fingerprint.js} +3 -3
- package/dist/utils/owner-fingerprint.js.map +1 -0
- package/dist/utils/promises.cjs.map +1 -1
- package/dist/utils/promises.js.map +1 -1
- package/dist/utils/relative-time.cjs.map +1 -1
- package/dist/utils/relative-time.js.map +1 -1
- package/dist/utils/safe-url.cjs.map +1 -1
- package/dist/utils/safe-url.js.map +1 -1
- package/dist/utils/schema-like.cjs.map +1 -1
- package/dist/utils/schema-like.js.map +1 -1
- package/dist/utils/storage.cjs +1 -1
- package/dist/utils/storage.cjs.map +1 -1
- package/dist/utils/storage.js +2 -2
- package/dist/utils/storage.js.map +1 -1
- package/dist/utils/strings.cjs.map +1 -1
- package/dist/utils/strings.js.map +1 -1
- package/dist/utils/xlsx.cjs.map +1 -1
- package/dist/utils/xlsx.js.map +1 -1
- package/dist/vision/core/canvas.cjs.map +1 -1
- package/dist/vision/core/canvas.js.map +1 -1
- package/dist/vision/core/dtypes.cjs.map +1 -1
- package/dist/vision/core/dtypes.js.map +1 -1
- package/dist/vision/core/exceptions.cjs.map +1 -1
- package/dist/vision/core/exceptions.js.map +1 -1
- package/dist/vision/core/graph.cjs.map +1 -1
- package/dist/vision/core/graph.js.map +1 -1
- package/dist/vision/core/metadata.cjs +1 -1
- package/dist/vision/core/metadata.cjs.map +1 -1
- package/dist/vision/core/metadata.js +9 -26
- package/dist/vision/core/metadata.js.map +1 -1
- package/dist/vision/core/providers.cjs.map +1 -1
- package/dist/vision/core/providers.js.map +1 -1
- package/dist/vision/core/session.cjs.map +1 -1
- package/dist/vision/core/session.js.map +1 -1
- package/dist/vision/core/timing.cjs.map +1 -1
- package/dist/vision/core/timing.js.map +1 -1
- package/dist/vision/fusion.cjs.map +1 -1
- package/dist/vision/fusion.js.map +1 -1
- package/dist/vision/index.cjs.map +1 -1
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/io/image.cjs.map +1 -1
- package/dist/vision/io/image.js.map +1 -1
- package/dist/vision/labels.cjs.map +1 -1
- package/dist/vision/labels.js.map +1 -1
- package/dist/vision/luminance.cjs.map +1 -1
- package/dist/vision/luminance.js.map +1 -1
- package/dist/vision/normalization.cjs.map +1 -1
- package/dist/vision/normalization.js.map +1 -1
- package/dist/vision/postprocess/classification.cjs.map +1 -1
- package/dist/vision/postprocess/classification.js.map +1 -1
- package/dist/vision/postprocess/detection.cjs.map +1 -1
- package/dist/vision/postprocess/detection.js.map +1 -1
- package/dist/vision/postprocess/segmentation.cjs.map +1 -1
- package/dist/vision/postprocess/segmentation.js.map +1 -1
- package/dist/vision/preprocess/image.cjs.map +1 -1
- package/dist/vision/preprocess/image.js.map +1 -1
- package/dist/vision/preprocess/pipeline.cjs.map +1 -1
- package/dist/vision/preprocess/pipeline.js.map +1 -1
- package/dist/vision/results.cjs.map +1 -1
- package/dist/vision/results.js.map +1 -1
- package/dist/vision/tasks/base.cjs.map +1 -1
- package/dist/vision/tasks/base.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision/tasks/detectClassify.cjs.map +1 -1
- package/dist/vision/tasks/detectClassify.js.map +1 -1
- package/dist/vision/tasks/detector.cjs.map +1 -1
- package/dist/vision/tasks/detector.js.map +1 -1
- package/dist/vision/tasks/segmenter.cjs.map +1 -1
- package/dist/vision/tasks/segmenter.js.map +1 -1
- package/dist/vision/types.cjs.map +1 -1
- package/dist/vision/types.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +3 -9
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vision/use-live-luminance.cjs +1 -1
- package/dist/vision/use-live-luminance.cjs.map +1 -1
- package/dist/vision/use-live-luminance.js +1 -5
- package/dist/vision/use-live-luminance.js.map +1 -1
- package/dist/vite/base-url.cjs.map +1 -1
- package/dist/vite/base-url.js.map +1 -1
- package/dist/vite/create-vite-config.cjs.map +1 -1
- package/dist/vite/create-vite-config.js.map +1 -1
- package/dist/vite/narrow-tokens.cjs.map +1 -1
- package/dist/vite/narrow-tokens.js.map +1 -1
- package/dist/vite/tempest-csp.cjs +2 -2
- package/dist/vite/tempest-csp.cjs.map +1 -1
- package/dist/vite/tempest-csp.js +69 -66
- package/dist/vite/tempest-csp.js.map +1 -1
- package/dist/vite/tempest-icons.cjs.map +1 -1
- package/dist/vite/tempest-icons.js.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.js +9 -16
- package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
- package/dist/vite/tempest-pwa-icons.cjs.map +1 -1
- package/dist/vite/tempest-pwa-icons.js.map +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/vite/tempest-styles.cjs.map +1 -1
- package/dist/vite/tempest-styles.js.map +1 -1
- package/dist/vite/tempest-vitest.cjs.map +1 -1
- package/dist/vite/tempest-vitest.js.map +1 -1
- package/dist/vite.d.ts +5 -3
- package/dist/webrtc/link-stats.cjs.map +1 -1
- package/dist/webrtc/link-stats.js.map +1 -1
- package/dist/webrtc/mesh-quality.cjs.map +1 -1
- package/dist/webrtc/mesh-quality.js.map +1 -1
- package/dist/webrtc/opus-sdp.cjs.map +1 -1
- package/dist/webrtc/opus-sdp.js.map +1 -1
- package/dist/webrtc/peer-link.cjs +1 -1
- package/dist/webrtc/peer-link.cjs.map +1 -1
- package/dist/webrtc/peer-link.js +2 -5
- package/dist/webrtc/peer-link.js.map +1 -1
- package/dist/webrtc/peer-mesh.cjs +1 -1
- package/dist/webrtc/peer-mesh.cjs.map +1 -1
- package/dist/webrtc/peer-mesh.js +8 -24
- package/dist/webrtc/peer-mesh.js.map +1 -1
- package/dist/webrtc/sender-bitrate.cjs.map +1 -1
- package/dist/webrtc/sender-bitrate.js.map +1 -1
- package/dist/webrtc/use-link-stats.cjs.map +1 -1
- package/dist/webrtc/use-link-stats.js.map +1 -1
- package/dist/ws/create-web-socket.cjs +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js +4 -22
- package/dist/ws/create-web-socket.js.map +1 -1
- package/dist/ws/resilience.cjs.map +1 -1
- package/dist/ws/resilience.js.map +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +9 -6
- package/template/package.json +1 -1
- package/dist/telemetry/app-error-owner.cjs.map +0 -1
- package/dist/telemetry/app-error-owner.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.cjs","names":[],"sources":["../../src/logger/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n context?: Record<string, unknown>;\n timestamp: number;\n}\n\nexport interface LoggerSink {\n (entry: LogEntry): void;\n}\n\nexport interface Logger {\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n /** Build a child logger that prefixes the namespace to each message. */\n child: (namespace: string) => Logger;\n}\n\nexport interface CreateLoggerOptions {\n /** Lowest level recorded. Default: `\"info\"`. */\n level?: LogLevel;\n /** Output adapters. Default: a `console.*` sink. */\n sinks?: LoggerSink[];\n /** Initial namespace (prepended to every message). */\n namespace?: string;\n}\n\nconst LEVELS: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(threshold: LogLevel, level: LogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(threshold);\n}\n\n/** Default sink that writes to the browser console. */\nexport const consoleSink: LoggerSink = ({ level, message, context }) => {\n const method = level === \"debug\" ? \"log\" : level;\n if (context) {\n console[method](message, context);\n } else {\n console[method](message);\n }\n};\n\n/**\n * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,\n * remote ingestion) by implementing the `LoggerSink` interface.\n *\n * @tempest-limits empty-catch — a sink that throws must not take the app with it,\n * and it must not stop the sinks after it in the list either. Logging is the thing\n * you reach for when something is already going wrong; a transport failure that\n * propagates would turn a diagnostic into the outage. Nothing here can report the\n * failure without recursing into the logger that just failed.\n */\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const threshold = options.level ?? \"info\";\n const sinks = options.sinks ?? [consoleSink];\n const namespace = options.namespace ?? \"\";\n\n function emit(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!shouldLog(threshold, level)) return;\n const entry: LogEntry = {\n level,\n message: namespace ? `[${namespace}] ${message}` : message,\n context,\n timestamp: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(entry);\n } catch {\n /* empty */\n }\n }\n }\n\n return {\n debug: (message, context) => emit(\"debug\", message, context),\n info: (message, context) => emit(\"info\", message, context),\n warn: (message, context) => emit(\"warn\", message, context),\n error: (message, context) => emit(\"error\", message, context),\n child: (childNamespace: string) =>\n createLogger({\n level: threshold,\n sinks,\n namespace: namespace ? `${namespace}:${childNamespace}` : childNamespace,\n }),\n };\n}\n"],"mappings":"AA+BA,
|
|
1
|
+
{"version":3,"file":"logger.cjs","names":["LEVELS","shouldLog","level","threshold","consoleSink","method","context","message","createLogger","options","sinks","namespace","emit","entry","sink","childNamespace"],"sources":["../../src/logger/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n context?: Record<string, unknown>;\n timestamp: number;\n}\n\nexport interface LoggerSink {\n (entry: LogEntry): void;\n}\n\nexport interface Logger {\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n /** Build a child logger that prefixes the namespace to each message. */\n child: (namespace: string) => Logger;\n}\n\nexport interface CreateLoggerOptions {\n /** Lowest level recorded. Default: `\"info\"`. */\n level?: LogLevel;\n /** Output adapters. Default: a `console.*` sink. */\n sinks?: LoggerSink[];\n /** Initial namespace (prepended to every message). */\n namespace?: string;\n}\n\nconst LEVELS: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(threshold: LogLevel, level: LogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(threshold);\n}\n\n/** Default sink that writes to the browser console. */\nexport const consoleSink: LoggerSink = ({ level, message, context }) => {\n const method = level === \"debug\" ? \"log\" : level;\n if (context) {\n console[method](message, context);\n } else {\n console[method](message);\n }\n};\n\n/**\n * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,\n * remote ingestion) by implementing the `LoggerSink` interface.\n *\n * @tempest-limits empty-catch — a sink that throws must not take the app with it,\n * and it must not stop the sinks after it in the list either. Logging is the thing\n * you reach for when something is already going wrong; a transport failure that\n * propagates would turn a diagnostic into the outage. Nothing here can report the\n * failure without recursing into the logger that just failed.\n */\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const threshold = options.level ?? \"info\";\n const sinks = options.sinks ?? [consoleSink];\n const namespace = options.namespace ?? \"\";\n\n function emit(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!shouldLog(threshold, level)) return;\n const entry: LogEntry = {\n level,\n message: namespace ? `[${namespace}] ${message}` : message,\n context,\n timestamp: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(entry);\n } catch {\n /* empty */\n }\n }\n }\n\n return {\n debug: (message, context) => emit(\"debug\", message, context),\n info: (message, context) => emit(\"info\", message, context),\n warn: (message, context) => emit(\"warn\", message, context),\n error: (message, context) => emit(\"error\", message, context),\n child: (childNamespace: string) =>\n createLogger({\n level: threshold,\n sinks,\n namespace: namespace ? `${namespace}:${childNamespace}` : childNamespace,\n }),\n };\n}\n"],"mappings":"AA+BA,IAAMA,EAAqB,CAAC,QAAS,OAAQ,OAAQ,OAAO,EAE5D,SAASC,EAAU,EAAqB,EAA0B,CAC9D,OAAOD,EAAO,QAAQE,CAAK,GAAKF,EAAO,QAAQG,CAAS,CAC5D,CAGA,IAAaC,GAA2B,CAAE,QAAO,UAAS,aAAc,CACpE,IAAMC,EAASH,IAAU,QAAU,MAAQA,EACvCI,EACA,QAAQD,EAAO,CAACE,EAASD,CAAO,EAEhC,QAAQD,EAAO,CAACE,CAAO,CAE/B,EAYA,SAAgBC,EAAa,EAA+B,CAAC,EAAW,CACpE,IAAML,EAAYM,EAAQ,OAAS,OAC7BC,EAAQD,EAAQ,OAAS,CAACL,CAAW,EACrCO,EAAYF,EAAQ,WAAa,GAEvC,SAASG,EAAK,EAAiB,EAAiB,EAAyC,CACrF,GAAI,CAACX,EAAUE,EAAWD,CAAK,EAAG,OAClC,IAAMW,EAAkB,CACpB,QACA,QAASF,EAAY,IAAIA,EAAU,IAAIJ,IAAYA,EACnD,UACA,UAAW,KAAK,IAAI,CACxB,EACA,IAAK,IAAMO,KAAQJ,EACf,GAAI,CACAI,EAAKD,CAAK,CACd,MAAQ,CAER,CAER,CAEA,MAAO,CACH,OAAQ,EAAS,IAAYD,EAAK,QAASL,EAASD,CAAO,EAC3D,MAAO,EAAS,IAAYM,EAAK,OAAQL,EAASD,CAAO,EACzD,MAAO,EAAS,IAAYM,EAAK,OAAQL,EAASD,CAAO,EACzD,OAAQ,EAAS,IAAYM,EAAK,QAASL,EAASD,CAAO,EAC3D,MAAQ,GACJE,EAAa,CACT,MAAOL,EACP,QACA,UAAWQ,EAAY,GAAGA,EAAU,GAAGI,IAAmBA,CAC9D,CAAC,CACT,CACJ,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","names":[],"sources":["../../src/logger/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n context?: Record<string, unknown>;\n timestamp: number;\n}\n\nexport interface LoggerSink {\n (entry: LogEntry): void;\n}\n\nexport interface Logger {\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n /** Build a child logger that prefixes the namespace to each message. */\n child: (namespace: string) => Logger;\n}\n\nexport interface CreateLoggerOptions {\n /** Lowest level recorded. Default: `\"info\"`. */\n level?: LogLevel;\n /** Output adapters. Default: a `console.*` sink. */\n sinks?: LoggerSink[];\n /** Initial namespace (prepended to every message). */\n namespace?: string;\n}\n\nconst LEVELS: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(threshold: LogLevel, level: LogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(threshold);\n}\n\n/** Default sink that writes to the browser console. */\nexport const consoleSink: LoggerSink = ({ level, message, context }) => {\n const method = level === \"debug\" ? \"log\" : level;\n if (context) {\n console[method](message, context);\n } else {\n console[method](message);\n }\n};\n\n/**\n * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,\n * remote ingestion) by implementing the `LoggerSink` interface.\n *\n * @tempest-limits empty-catch — a sink that throws must not take the app with it,\n * and it must not stop the sinks after it in the list either. Logging is the thing\n * you reach for when something is already going wrong; a transport failure that\n * propagates would turn a diagnostic into the outage. Nothing here can report the\n * failure without recursing into the logger that just failed.\n */\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const threshold = options.level ?? \"info\";\n const sinks = options.sinks ?? [consoleSink];\n const namespace = options.namespace ?? \"\";\n\n function emit(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!shouldLog(threshold, level)) return;\n const entry: LogEntry = {\n level,\n message: namespace ? `[${namespace}] ${message}` : message,\n context,\n timestamp: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(entry);\n } catch {\n /* empty */\n }\n }\n }\n\n return {\n debug: (message, context) => emit(\"debug\", message, context),\n info: (message, context) => emit(\"info\", message, context),\n warn: (message, context) => emit(\"warn\", message, context),\n error: (message, context) => emit(\"error\", message, context),\n child: (childNamespace: string) =>\n createLogger({\n level: threshold,\n sinks,\n namespace: namespace ? `${namespace}:${childNamespace}` : childNamespace,\n }),\n };\n}\n"],"mappings":";AA+BA,
|
|
1
|
+
{"version":3,"file":"logger.js","names":["LEVELS","shouldLog","level","threshold","consoleSink","method","context","message","createLogger","options","sinks","namespace","emit","entry","sink","childNamespace"],"sources":["../../src/logger/logger.ts"],"sourcesContent":["export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n context?: Record<string, unknown>;\n timestamp: number;\n}\n\nexport interface LoggerSink {\n (entry: LogEntry): void;\n}\n\nexport interface Logger {\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n /** Build a child logger that prefixes the namespace to each message. */\n child: (namespace: string) => Logger;\n}\n\nexport interface CreateLoggerOptions {\n /** Lowest level recorded. Default: `\"info\"`. */\n level?: LogLevel;\n /** Output adapters. Default: a `console.*` sink. */\n sinks?: LoggerSink[];\n /** Initial namespace (prepended to every message). */\n namespace?: string;\n}\n\nconst LEVELS: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(threshold: LogLevel, level: LogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(threshold);\n}\n\n/** Default sink that writes to the browser console. */\nexport const consoleSink: LoggerSink = ({ level, message, context }) => {\n const method = level === \"debug\" ? \"log\" : level;\n if (context) {\n console[method](message, context);\n } else {\n console[method](message);\n }\n};\n\n/**\n * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,\n * remote ingestion) by implementing the `LoggerSink` interface.\n *\n * @tempest-limits empty-catch — a sink that throws must not take the app with it,\n * and it must not stop the sinks after it in the list either. Logging is the thing\n * you reach for when something is already going wrong; a transport failure that\n * propagates would turn a diagnostic into the outage. Nothing here can report the\n * failure without recursing into the logger that just failed.\n */\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const threshold = options.level ?? \"info\";\n const sinks = options.sinks ?? [consoleSink];\n const namespace = options.namespace ?? \"\";\n\n function emit(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!shouldLog(threshold, level)) return;\n const entry: LogEntry = {\n level,\n message: namespace ? `[${namespace}] ${message}` : message,\n context,\n timestamp: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(entry);\n } catch {\n /* empty */\n }\n }\n }\n\n return {\n debug: (message, context) => emit(\"debug\", message, context),\n info: (message, context) => emit(\"info\", message, context),\n warn: (message, context) => emit(\"warn\", message, context),\n error: (message, context) => emit(\"error\", message, context),\n child: (childNamespace: string) =>\n createLogger({\n level: threshold,\n sinks,\n namespace: namespace ? `${namespace}:${childNamespace}` : childNamespace,\n }),\n };\n}\n"],"mappings":";AA+BA,IAAMA,IAAqB;CAAC;CAAS;CAAQ;CAAQ;AAAO;AAE5D,SAASC,EAAU,GAAqB,GAA0B;CAC9D,OAAOD,EAAO,QAAQE,CAAK,KAAKF,EAAO,QAAQG,CAAS;AAC5D;AAGA,IAAaC,KAA2B,EAAE,UAAO,YAAS,iBAAc;CACpE,IAAMC,IAASH,MAAU,UAAU,QAAQA;CAC3C,AAAII,IACA,QAAQD,EAAO,CAACE,GAASD,CAAO,IAEhC,QAAQD,EAAO,CAACE,CAAO;AAE/B;AAYA,SAAgBC,EAAa,IAA+B,CAAC,GAAW;CACpE,IAAML,IAAYM,EAAQ,SAAS,QAC7BC,IAAQD,EAAQ,SAAS,CAACL,CAAW,GACrCO,IAAYF,EAAQ,aAAa;CAEvC,SAASG,EAAK,GAAiB,GAAiB,GAAyC;EACrF,IAAI,CAACX,EAAUE,GAAWD,CAAK,GAAG;EAClC,IAAMW,IAAkB;GACpB;GACA,SAASF,IAAY,IAAIA,EAAU,IAAIJ,MAAYA;GACnD;GACA,WAAW,KAAK,IAAI;EACxB;EACA,KAAK,IAAMO,KAAQJ,GACf,IAAI;GACA,EAAKG,CAAK;EACd,QAAQ,CAER;CAER;CAEA,OAAO;EACH,QAAQ,GAAS,MAAYD,EAAK,SAASL,GAASD,CAAO;EAC3D,OAAO,GAAS,MAAYM,EAAK,QAAQL,GAASD,CAAO;EACzD,OAAO,GAAS,MAAYM,EAAK,QAAQL,GAASD,CAAO;EACzD,QAAQ,GAAS,MAAYM,EAAK,SAASL,GAASD,CAAO;EAC3D,QAAQ,MACJE,EAAa;GACT,OAAOL;GACP;GACA,WAAWQ,IAAY,GAAGA,EAAU,GAAGI,MAAmBA;EAC9D,CAAC;CACT;AACJ"}
|
package/dist/neural.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural.cjs","names":[],"sources":["../src/neural/index.ts"],"sourcesContent":["import { RnnoiseWorkletNode, loadRnnoise } from \"@sapphi-red/web-noise-suppressor\";\n\n/**\n * Where the suppressor's three pieces live, as URLs a bundler hands over.\n *\n * The `@sapphi-red/web-noise-suppressor` package ships the runnable assets next\n * to its code, but it cannot say where they are from inside a library: the\n * `?url` suffix that resolves a module to its served address is a bundler\n * feature, and every bundler answers it differently. So this subpath takes the\n * three resolved addresses as arguments and does the honest part — the graph,\n * the load-once semantics, the per-context registration — here.\n */\nexport interface NeuralSuppressorAssets {\n /**\n * The `AudioWorklet` processor module the model runs its DSP in\n * (`rnnoiseWorklet.js`).\n */\n workletUrl: string;\n /** The SIMD build of the model's wasm (`rnnoise_simd.wasm`). */\n simdWasmUrl: string;\n /** The baseline build, used where the engine lacks SIMD (`rnnoise.wasm`). */\n wasmUrl: string;\n}\n\n/**\n * Whether this browser can run a worklet-based noise suppressor.\n *\n * Answered from the two things the path needs that nothing but the platform can\n * supply: `AudioWorkletNode` runs custom DSP on the audio thread, and a secure\n * context is what the browser requires before letting a module near the\n * microphone graph. Everything else — the models, the wasm — ships with the\n * caller, so it cannot be missing. The context must also run at 48 kHz, which\n * is checked at build time rather than here because the caller owns how its\n * context was opened.\n *\n * Deliberately conservative: anything it cannot establish answers `false`, and\n * a `false` sends the caller back to the browser's own `noiseSuppression`\n * constraint, which is weaker but always there.\n *\n * @returns True when a neural suppressor can be built on top of a capture.\n */\nexport function isNeuralSuppressionSupported(): boolean {\n return (\n typeof AudioWorkletNode !== \"undefined\" &&\n typeof window !== \"undefined\" &&\n window.isSecureContext\n );\n}\n\n/**\n * The one wasm binary every suppressor shares, fetched once.\n *\n * `loadRnnoise` compiles the whole model, and the answer is identical for every\n * graph that opens afterwards — a mesh can build a suppressor per published\n * track and a settings dialog may build a second for its monitor within a\n * single frame. Held as the promise rather than the result so the first two\n * callers race into one fetch instead of two. Reset on failure, so the next\n * call retries instead of replaying a dead promise.\n */\nlet loadingBinary: Promise<ArrayBuffer> | null = null;\n\n/**\n * The contexts the worklet module has already been registered on, mapped to the\n * registration's own promise.\n *\n * `addModule` is per-context and throws on a name it already holds, so the\n * module records the moment a context is ready and skips the call next time.\n * The promise is what makes a fast caller that cannot wait — a mesh can open a\n * microphone and a preview within a single frame — race into one `addModule`\n * instead of two: had this been a set, the second caller would see the context\n * absent while the first was still awaiting and register the module twice.\n * Mapped to a promise rather than the module itself the way the wasm is,\n * because the registration belongs to one context while the wasm is shared,\n * and nothing here should keep a dead context alive — the value is dropped\n * with the context. On failure the entry is removed, so the next attempt\n * actually retries instead of replaying the broken registration.\n */\nconst readyContexts = new WeakMap<AudioContext, Promise<void>>();\n\n/**\n * The compiled model for this context, loading what is not ready yet.\n *\n * Idempotent across calls: the wasm fetch and the module registration both\n * happen exactly once. The wasm is shared by every suppressor, while the module\n * registration belongs to one context.\n *\n * @param context - The context the suppression graph will run in.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @returns The compiled model binary, ready to hand to a worklet node.\n * @throws Whatever the fetch or the compile threw, for the caller to fall back on.\n */\nexport async function prepareNeuralSuppressor(\n context: AudioContext,\n assets: NeuralSuppressorAssets,\n): Promise<ArrayBuffer> {\n let ready = readyContexts.get(context);\n if (!ready) {\n ready = context.audioWorklet.addModule(assets.workletUrl).then(\n () => undefined,\n (error: unknown) => {\n readyContexts.delete(context);\n throw error;\n },\n );\n readyContexts.set(context, ready);\n }\n await ready;\n if (loadingBinary === null) {\n loadingBinary = loadRnnoise({ url: assets.wasmUrl, simdUrl: assets.simdWasmUrl }).catch(\n (error: unknown) => {\n loadingBinary = null;\n throw error;\n },\n );\n }\n return loadingBinary;\n}\n\n/**\n * A denoised track plus the graph that has to come down with it.\n *\n * `track` is not the captured one — it is the output of a `MediaStream`\n * destination the worklet feeds — so stopping the published track is not enough\n * to free the microphone. `release` closes the graph; the captured track behind\n * it belongs to the caller.\n */\nexport interface NeuralSuppressor {\n /** The track to publish in place of the captured one. */\n track: MediaStreamTrack;\n /** Tears the graph down. Does not stop the source track it was built from. */\n release(): void;\n}\n\n/**\n * Build a suppressor graph on top of a captured microphone track.\n *\n * The model runs on the audio thread through an `AudioWorkletNode` — a\n * recurrent network trained on speech that separates a voice from everything\n * that is not one: keyboards, fans, traffic, a room full of people. The\n * browser's `noiseSuppression` constraint answers the same question with a\n * stationary-noise gate that either lets a transient through or eats the voice\n * with it.\n *\n * Prefer {@link prepareNeuralSuppressor} before the capture opens: the fallback\n * to the browser's own suppression is a `getUserMedia` constraint, and a\n * constraint cannot be added to a capture that already exists. A caller that\n * did not preload still works — the load happens here, idempotently.\n *\n * The model assumes 48 kHz. A context opened at any other rate answers `null`\n * before anything is fetched, because feeding speech samples of the wrong rate\n * into a network trained on 48 kHz produces mush, not a voice.\n *\n * Failure is not fatal and is reported as `null` — whether the wasm would not\n * load or the worklet node could not be built: by the time this runs the caller\n * has already committed to the neural path, so the honest outcome is a call\n * without suppression rather than a microphone that will not open. {@link\n * prepareNeuralSuppressor}, which exists to be called *before* the capture,\n * still throws so the caller can pick a different fallback while one is\n * reachable.\n *\n * @param context - The shared context, prepared at 48 kHz.\n * @param source - The captured microphone track.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @param options - `maxChannels` is the channel count of the capture; the model\n * is mono, and a stereo capture asks for two so a second channel is not lost.\n * @returns The denoised track and its teardown, or `null` when this context or\n * this graph cannot host the suppressor.\n */\nexport async function createNeuralSuppressor(\n context: AudioContext,\n source: MediaStreamTrack,\n assets: NeuralSuppressorAssets,\n options: { maxChannels: number },\n): Promise<NeuralSuppressor | null> {\n if (context.sampleRate !== 48_000) return null;\n\n let binary: ArrayBuffer;\n try {\n binary = await prepareNeuralSuppressor(context, assets);\n } catch {\n return null;\n }\n\n let node: RnnoiseWorkletNode;\n try {\n node = new RnnoiseWorkletNode(context, {\n maxChannels: options.maxChannels,\n wasmBinary: binary,\n });\n } catch {\n return null;\n }\n\n const input = context.createMediaStreamSource(new MediaStream([source]));\n const output = context.createMediaStreamDestination();\n input.connect(node);\n node.connect(output);\n\n const track = output.stream.getAudioTracks()[0];\n if (!track) {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n return null;\n }\n track.contentHint = source.contentHint;\n\n return {\n track,\n release: () => {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n track.stop();\n },\n };\n}\n"],"mappings":"qHAyCA,SAAgB,GAAwC,CACpD,OACI,OAAO,iBAAqB,KAC5B,OAAO,OAAW,KAClB,OAAO,eAEf,CAYA,IAAI,EAA6C,KAkB3C,EAAgB,IAAI,QAc1B,eAAsB,EAClB,EACA,EACoB,CACpB,IAAI,EAAQ,EAAc,IAAI,CAAO,EAoBrC,OAnBK,IACD,EAAQ,EAAQ,aAAa,UAAU,EAAO,UAAU,CAAC,CAAC,SAChD,IAAA,GACL,GAAmB,CAEhB,MADA,EAAc,OAAO,CAAO,EACtB,CACV,CACJ,EACA,EAAc,IAAI,EAAS,CAAK,GAEpC,MAAM,EACF,IAAkB,OAClB,GAAA,EAAgB,EAAA,YAAA,CAAY,CAAE,IAAK,EAAO,QAAS,QAAS,EAAO,WAAY,CAAC,CAAC,CAAC,MAC7E,GAAmB,CAEhB,KADA,GAAgB,KACV,CACV,CACJ,GAEG,CACX,CAoDA,eAAsB,EAClB,EACA,EACA,EACA,EACgC,CAChC,GAAI,EAAQ,aAAe,KAAQ,OAAO,KAE1C,IAAI,EACJ,GAAI,CACA,EAAS,MAAM,EAAwB,EAAS,CAAM,CAC1D,MAAQ,CACJ,OAAO,IACX,CAEA,IAAI,EACJ,GAAI,CACA,EAAO,IAAI,EAAA,mBAAmB,EAAS,CACnC,YAAa,EAAQ,YACrB,WAAY,CAChB,CAAC,CACL,MAAQ,CACJ,OAAO,IACX,CAEA,IAAM,EAAQ,EAAQ,wBAAwB,IAAI,YAAY,CAAC,CAAM,CAAC,CAAC,EACjE,EAAS,EAAQ,6BAA6B,EACpD,EAAM,QAAQ,CAAI,EAClB,EAAK,QAAQ,CAAM,EAEnB,IAAM,EAAQ,EAAO,OAAO,eAAe,CAAC,CAAC,GAU7C,OATK,GAOL,EAAM,YAAc,EAAO,YAEpB,CACH,QACA,YAAe,CACX,EAAM,WAAW,EACjB,EAAK,WAAW,EAChB,EAAO,WAAW,EAClB,EAAK,QAAQ,EACb,EAAM,KAAK,CACf,CACJ,IAjBI,EAAM,WAAW,EACjB,EAAK,WAAW,EAChB,EAAO,WAAW,EAClB,EAAK,QAAQ,EACN,KAcf"}
|
|
1
|
+
{"version":3,"file":"neural.cjs","names":["loadRnnoise","RnnoiseWorkletNode","_sapphi_red_web_noise_suppressor","isNeuralSuppressionSupported","loadingBinary","readyContexts","prepareNeuralSuppressor","ready","context","assets","error","createNeuralSuppressor","binary","node","options","input","source","output","track"],"sources":["../src/neural/index.ts"],"sourcesContent":["import { RnnoiseWorkletNode, loadRnnoise } from \"@sapphi-red/web-noise-suppressor\";\n\n/**\n * Where the suppressor's three pieces live, as URLs a bundler hands over.\n *\n * The `@sapphi-red/web-noise-suppressor` package ships the runnable assets next\n * to its code, but it cannot say where they are from inside a library: the\n * `?url` suffix that resolves a module to its served address is a bundler\n * feature, and every bundler answers it differently. So this subpath takes the\n * three resolved addresses as arguments and does the honest part — the graph,\n * the load-once semantics, the per-context registration — here.\n */\nexport interface NeuralSuppressorAssets {\n /**\n * The `AudioWorklet` processor module the model runs its DSP in\n * (`rnnoiseWorklet.js`).\n */\n workletUrl: string;\n /** The SIMD build of the model's wasm (`rnnoise_simd.wasm`). */\n simdWasmUrl: string;\n /** The baseline build, used where the engine lacks SIMD (`rnnoise.wasm`). */\n wasmUrl: string;\n}\n\n/**\n * Whether this browser can run a worklet-based noise suppressor.\n *\n * Answered from the two things the path needs that nothing but the platform can\n * supply: `AudioWorkletNode` runs custom DSP on the audio thread, and a secure\n * context is what the browser requires before letting a module near the\n * microphone graph. Everything else — the models, the wasm — ships with the\n * caller, so it cannot be missing. The context must also run at 48 kHz, which\n * is checked at build time rather than here because the caller owns how its\n * context was opened.\n *\n * Deliberately conservative: anything it cannot establish answers `false`, and\n * a `false` sends the caller back to the browser's own `noiseSuppression`\n * constraint, which is weaker but always there.\n *\n * @returns True when a neural suppressor can be built on top of a capture.\n */\nexport function isNeuralSuppressionSupported(): boolean {\n return (\n typeof AudioWorkletNode !== \"undefined\" &&\n typeof window !== \"undefined\" &&\n window.isSecureContext\n );\n}\n\n/**\n * The one wasm binary every suppressor shares, fetched once.\n *\n * `loadRnnoise` compiles the whole model, and the answer is identical for every\n * graph that opens afterwards — a mesh can build a suppressor per published\n * track and a settings dialog may build a second for its monitor within a\n * single frame. Held as the promise rather than the result so the first two\n * callers race into one fetch instead of two. Reset on failure, so the next\n * call retries instead of replaying a dead promise.\n */\nlet loadingBinary: Promise<ArrayBuffer> | null = null;\n\n/**\n * The contexts the worklet module has already been registered on, mapped to the\n * registration's own promise.\n *\n * `addModule` is per-context and throws on a name it already holds, so the\n * module records the moment a context is ready and skips the call next time.\n * The promise is what makes a fast caller that cannot wait — a mesh can open a\n * microphone and a preview within a single frame — race into one `addModule`\n * instead of two: had this been a set, the second caller would see the context\n * absent while the first was still awaiting and register the module twice.\n * Mapped to a promise rather than the module itself the way the wasm is,\n * because the registration belongs to one context while the wasm is shared,\n * and nothing here should keep a dead context alive — the value is dropped\n * with the context. On failure the entry is removed, so the next attempt\n * actually retries instead of replaying the broken registration.\n */\nconst readyContexts = new WeakMap<AudioContext, Promise<void>>();\n\n/**\n * The compiled model for this context, loading what is not ready yet.\n *\n * Idempotent across calls: the wasm fetch and the module registration both\n * happen exactly once. The wasm is shared by every suppressor, while the module\n * registration belongs to one context.\n *\n * @param context - The context the suppression graph will run in.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @returns The compiled model binary, ready to hand to a worklet node.\n * @throws Whatever the fetch or the compile threw, for the caller to fall back on.\n */\nexport async function prepareNeuralSuppressor(\n context: AudioContext,\n assets: NeuralSuppressorAssets,\n): Promise<ArrayBuffer> {\n let ready = readyContexts.get(context);\n if (!ready) {\n ready = context.audioWorklet.addModule(assets.workletUrl).then(\n () => undefined,\n (error: unknown) => {\n readyContexts.delete(context);\n throw error;\n },\n );\n readyContexts.set(context, ready);\n }\n await ready;\n if (loadingBinary === null) {\n loadingBinary = loadRnnoise({ url: assets.wasmUrl, simdUrl: assets.simdWasmUrl }).catch(\n (error: unknown) => {\n loadingBinary = null;\n throw error;\n },\n );\n }\n return loadingBinary;\n}\n\n/**\n * A denoised track plus the graph that has to come down with it.\n *\n * `track` is not the captured one — it is the output of a `MediaStream`\n * destination the worklet feeds — so stopping the published track is not enough\n * to free the microphone. `release` closes the graph; the captured track behind\n * it belongs to the caller.\n */\nexport interface NeuralSuppressor {\n /** The track to publish in place of the captured one. */\n track: MediaStreamTrack;\n /** Tears the graph down. Does not stop the source track it was built from. */\n release(): void;\n}\n\n/**\n * Build a suppressor graph on top of a captured microphone track.\n *\n * The model runs on the audio thread through an `AudioWorkletNode` — a\n * recurrent network trained on speech that separates a voice from everything\n * that is not one: keyboards, fans, traffic, a room full of people. The\n * browser's `noiseSuppression` constraint answers the same question with a\n * stationary-noise gate that either lets a transient through or eats the voice\n * with it.\n *\n * Prefer {@link prepareNeuralSuppressor} before the capture opens: the fallback\n * to the browser's own suppression is a `getUserMedia` constraint, and a\n * constraint cannot be added to a capture that already exists. A caller that\n * did not preload still works — the load happens here, idempotently.\n *\n * The model assumes 48 kHz. A context opened at any other rate answers `null`\n * before anything is fetched, because feeding speech samples of the wrong rate\n * into a network trained on 48 kHz produces mush, not a voice.\n *\n * Failure is not fatal and is reported as `null` — whether the wasm would not\n * load or the worklet node could not be built: by the time this runs the caller\n * has already committed to the neural path, so the honest outcome is a call\n * without suppression rather than a microphone that will not open. {@link\n * prepareNeuralSuppressor}, which exists to be called *before* the capture,\n * still throws so the caller can pick a different fallback while one is\n * reachable.\n *\n * @param context - The shared context, prepared at 48 kHz.\n * @param source - The captured microphone track.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @param options - `maxChannels` is the channel count of the capture; the model\n * is mono, and a stereo capture asks for two so a second channel is not lost.\n * @returns The denoised track and its teardown, or `null` when this context or\n * this graph cannot host the suppressor.\n */\nexport async function createNeuralSuppressor(\n context: AudioContext,\n source: MediaStreamTrack,\n assets: NeuralSuppressorAssets,\n options: { maxChannels: number },\n): Promise<NeuralSuppressor | null> {\n if (context.sampleRate !== 48_000) return null;\n\n let binary: ArrayBuffer;\n try {\n binary = await prepareNeuralSuppressor(context, assets);\n } catch {\n return null;\n }\n\n let node: RnnoiseWorkletNode;\n try {\n node = new RnnoiseWorkletNode(context, {\n maxChannels: options.maxChannels,\n wasmBinary: binary,\n });\n } catch {\n return null;\n }\n\n const input = context.createMediaStreamSource(new MediaStream([source]));\n const output = context.createMediaStreamDestination();\n input.connect(node);\n node.connect(output);\n\n const track = output.stream.getAudioTracks()[0];\n if (!track) {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n return null;\n }\n track.contentHint = source.contentHint;\n\n return {\n track,\n release: () => {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n track.stop();\n },\n };\n}\n"],"mappings":"A,qHAyCA,SAAgBG,GAAwC,CACpD,OACI,OAAO,iBAAqB,KAC5B,OAAO,OAAW,KAClB,OAAO,eAEf,CAYA,IAAIC,EAA6C,KAkB3CC,EAAgB,IAAI,QAc1B,eAAsBC,EAClB,EACA,EACoB,CACpB,IAAIC,EAAQF,EAAc,IAAIG,CAAO,EAoBrC,OAnBKD,IACD,EAAQC,EAAQ,aAAa,UAAUC,EAAO,UAAU,CAAC,CAAC,SAChD,IAAA,GACL,GAAmB,CAEhB,MADAJ,EAAc,OAAOG,CAAO,EACtBE,CACV,CACJ,EACAL,EAAc,IAAIG,EAASD,CAAK,GAEpC,MAAMA,EACFH,IAAkB,OAClB,GAAA,EAAgBJ,EAAAA,YAAAA,CAAY,CAAE,IAAKS,EAAO,QAAS,QAASA,EAAO,WAAY,CAAC,CAAC,CAAC,MAC7E,GAAmB,CAEhB,KADA,GAAgB,KACVC,CACV,CACJ,GAEGN,CACX,CAoDA,eAAsBO,EAClB,EACA,EACA,EACA,EACgC,CAChC,GAAIH,EAAQ,aAAe,KAAQ,OAAO,KAE1C,IAAII,EACJ,GAAI,CACA,EAAS,MAAMN,EAAwBE,EAASC,CAAM,CAC1D,MAAQ,CACJ,OAAO,IACX,CAEA,IAAII,EACJ,GAAI,CACA,EAAO,IAAIZ,EAAAA,mBAAmBO,EAAS,CACnC,YAAaM,EAAQ,YACrB,WAAYF,CAChB,CAAC,CACL,MAAQ,CACJ,OAAO,IACX,CAEA,IAAMG,EAAQP,EAAQ,wBAAwB,IAAI,YAAY,CAACQ,CAAM,CAAC,CAAC,EACjEC,EAAST,EAAQ,6BAA6B,EACpDO,EAAM,QAAQF,CAAI,EAClBA,EAAK,QAAQI,CAAM,EAEnB,IAAMC,EAAQD,EAAO,OAAO,eAAe,CAAC,CAAC,GAU7C,OATKC,GAOL,EAAM,YAAcF,EAAO,YAEpB,CACH,QACA,YAAe,CACXD,EAAM,WAAW,EACjBF,EAAK,WAAW,EAChBI,EAAO,WAAW,EAClBJ,EAAK,QAAQ,EACbK,EAAM,KAAK,CACf,CACJ,IAjBIH,EAAM,WAAW,EACjBF,EAAK,WAAW,EAChBI,EAAO,WAAW,EAClBJ,EAAK,QAAQ,EACN,KAcf,C"}
|
package/dist/neural.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural.js","names":[],"sources":["../src/neural/index.ts"],"sourcesContent":["import { RnnoiseWorkletNode, loadRnnoise } from \"@sapphi-red/web-noise-suppressor\";\n\n/**\n * Where the suppressor's three pieces live, as URLs a bundler hands over.\n *\n * The `@sapphi-red/web-noise-suppressor` package ships the runnable assets next\n * to its code, but it cannot say where they are from inside a library: the\n * `?url` suffix that resolves a module to its served address is a bundler\n * feature, and every bundler answers it differently. So this subpath takes the\n * three resolved addresses as arguments and does the honest part — the graph,\n * the load-once semantics, the per-context registration — here.\n */\nexport interface NeuralSuppressorAssets {\n /**\n * The `AudioWorklet` processor module the model runs its DSP in\n * (`rnnoiseWorklet.js`).\n */\n workletUrl: string;\n /** The SIMD build of the model's wasm (`rnnoise_simd.wasm`). */\n simdWasmUrl: string;\n /** The baseline build, used where the engine lacks SIMD (`rnnoise.wasm`). */\n wasmUrl: string;\n}\n\n/**\n * Whether this browser can run a worklet-based noise suppressor.\n *\n * Answered from the two things the path needs that nothing but the platform can\n * supply: `AudioWorkletNode` runs custom DSP on the audio thread, and a secure\n * context is what the browser requires before letting a module near the\n * microphone graph. Everything else — the models, the wasm — ships with the\n * caller, so it cannot be missing. The context must also run at 48 kHz, which\n * is checked at build time rather than here because the caller owns how its\n * context was opened.\n *\n * Deliberately conservative: anything it cannot establish answers `false`, and\n * a `false` sends the caller back to the browser's own `noiseSuppression`\n * constraint, which is weaker but always there.\n *\n * @returns True when a neural suppressor can be built on top of a capture.\n */\nexport function isNeuralSuppressionSupported(): boolean {\n return (\n typeof AudioWorkletNode !== \"undefined\" &&\n typeof window !== \"undefined\" &&\n window.isSecureContext\n );\n}\n\n/**\n * The one wasm binary every suppressor shares, fetched once.\n *\n * `loadRnnoise` compiles the whole model, and the answer is identical for every\n * graph that opens afterwards — a mesh can build a suppressor per published\n * track and a settings dialog may build a second for its monitor within a\n * single frame. Held as the promise rather than the result so the first two\n * callers race into one fetch instead of two. Reset on failure, so the next\n * call retries instead of replaying a dead promise.\n */\nlet loadingBinary: Promise<ArrayBuffer> | null = null;\n\n/**\n * The contexts the worklet module has already been registered on, mapped to the\n * registration's own promise.\n *\n * `addModule` is per-context and throws on a name it already holds, so the\n * module records the moment a context is ready and skips the call next time.\n * The promise is what makes a fast caller that cannot wait — a mesh can open a\n * microphone and a preview within a single frame — race into one `addModule`\n * instead of two: had this been a set, the second caller would see the context\n * absent while the first was still awaiting and register the module twice.\n * Mapped to a promise rather than the module itself the way the wasm is,\n * because the registration belongs to one context while the wasm is shared,\n * and nothing here should keep a dead context alive — the value is dropped\n * with the context. On failure the entry is removed, so the next attempt\n * actually retries instead of replaying the broken registration.\n */\nconst readyContexts = new WeakMap<AudioContext, Promise<void>>();\n\n/**\n * The compiled model for this context, loading what is not ready yet.\n *\n * Idempotent across calls: the wasm fetch and the module registration both\n * happen exactly once. The wasm is shared by every suppressor, while the module\n * registration belongs to one context.\n *\n * @param context - The context the suppression graph will run in.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @returns The compiled model binary, ready to hand to a worklet node.\n * @throws Whatever the fetch or the compile threw, for the caller to fall back on.\n */\nexport async function prepareNeuralSuppressor(\n context: AudioContext,\n assets: NeuralSuppressorAssets,\n): Promise<ArrayBuffer> {\n let ready = readyContexts.get(context);\n if (!ready) {\n ready = context.audioWorklet.addModule(assets.workletUrl).then(\n () => undefined,\n (error: unknown) => {\n readyContexts.delete(context);\n throw error;\n },\n );\n readyContexts.set(context, ready);\n }\n await ready;\n if (loadingBinary === null) {\n loadingBinary = loadRnnoise({ url: assets.wasmUrl, simdUrl: assets.simdWasmUrl }).catch(\n (error: unknown) => {\n loadingBinary = null;\n throw error;\n },\n );\n }\n return loadingBinary;\n}\n\n/**\n * A denoised track plus the graph that has to come down with it.\n *\n * `track` is not the captured one — it is the output of a `MediaStream`\n * destination the worklet feeds — so stopping the published track is not enough\n * to free the microphone. `release` closes the graph; the captured track behind\n * it belongs to the caller.\n */\nexport interface NeuralSuppressor {\n /** The track to publish in place of the captured one. */\n track: MediaStreamTrack;\n /** Tears the graph down. Does not stop the source track it was built from. */\n release(): void;\n}\n\n/**\n * Build a suppressor graph on top of a captured microphone track.\n *\n * The model runs on the audio thread through an `AudioWorkletNode` — a\n * recurrent network trained on speech that separates a voice from everything\n * that is not one: keyboards, fans, traffic, a room full of people. The\n * browser's `noiseSuppression` constraint answers the same question with a\n * stationary-noise gate that either lets a transient through or eats the voice\n * with it.\n *\n * Prefer {@link prepareNeuralSuppressor} before the capture opens: the fallback\n * to the browser's own suppression is a `getUserMedia` constraint, and a\n * constraint cannot be added to a capture that already exists. A caller that\n * did not preload still works — the load happens here, idempotently.\n *\n * The model assumes 48 kHz. A context opened at any other rate answers `null`\n * before anything is fetched, because feeding speech samples of the wrong rate\n * into a network trained on 48 kHz produces mush, not a voice.\n *\n * Failure is not fatal and is reported as `null` — whether the wasm would not\n * load or the worklet node could not be built: by the time this runs the caller\n * has already committed to the neural path, so the honest outcome is a call\n * without suppression rather than a microphone that will not open. {@link\n * prepareNeuralSuppressor}, which exists to be called *before* the capture,\n * still throws so the caller can pick a different fallback while one is\n * reachable.\n *\n * @param context - The shared context, prepared at 48 kHz.\n * @param source - The captured microphone track.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @param options - `maxChannels` is the channel count of the capture; the model\n * is mono, and a stereo capture asks for two so a second channel is not lost.\n * @returns The denoised track and its teardown, or `null` when this context or\n * this graph cannot host the suppressor.\n */\nexport async function createNeuralSuppressor(\n context: AudioContext,\n source: MediaStreamTrack,\n assets: NeuralSuppressorAssets,\n options: { maxChannels: number },\n): Promise<NeuralSuppressor | null> {\n if (context.sampleRate !== 48_000) return null;\n\n let binary: ArrayBuffer;\n try {\n binary = await prepareNeuralSuppressor(context, assets);\n } catch {\n return null;\n }\n\n let node: RnnoiseWorkletNode;\n try {\n node = new RnnoiseWorkletNode(context, {\n maxChannels: options.maxChannels,\n wasmBinary: binary,\n });\n } catch {\n return null;\n }\n\n const input = context.createMediaStreamSource(new MediaStream([source]));\n const output = context.createMediaStreamDestination();\n input.connect(node);\n node.connect(output);\n\n const track = output.stream.getAudioTracks()[0];\n if (!track) {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n return null;\n }\n track.contentHint = source.contentHint;\n\n return {\n track,\n release: () => {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n track.stop();\n },\n };\n}\n"],"mappings":";;AAyCA,SAAgB,IAAwC;CACpD,OACI,OAAO,mBAAqB,OAC5B,OAAO,SAAW,OAClB,OAAO;AAEf;AAYA,IAAI,IAA6C,MAkB3C,oBAAgB,IAAI,QAAqC;AAc/D,eAAsB,EAClB,GACA,GACoB;CACpB,IAAI,IAAQ,EAAc,IAAI,CAAO;CAoBrC,OAnBK,MACD,IAAQ,EAAQ,aAAa,UAAU,EAAO,UAAU,CAAC,CAAC,WAChD,KAAA,IACL,MAAmB;EAEhB,MADA,EAAc,OAAO,CAAO,GACtB;CACV,CACJ,GACA,EAAc,IAAI,GAAS,CAAK,IAEpC,MAAM,GACF,MAAkB,SAClB,IAAgB,EAAY;EAAE,KAAK,EAAO;EAAS,SAAS,EAAO;CAAY,CAAC,CAAC,CAAC,OAC7E,MAAmB;EAEhB,MADA,IAAgB,MACV;CACV,CACJ,IAEG;AACX;AAoDA,eAAsB,EAClB,GACA,GACA,GACA,GACgC;CAChC,IAAI,EAAQ,eAAe,MAAQ,OAAO;CAE1C,IAAI;CACJ,IAAI;EACA,IAAS,MAAM,EAAwB,GAAS,CAAM;CAC1D,QAAQ;EACJ,OAAO;CACX;CAEA,IAAI;CACJ,IAAI;EACA,IAAO,IAAI,EAAmB,GAAS;GACnC,aAAa,EAAQ;GACrB,YAAY;EAChB,CAAC;CACL,QAAQ;EACJ,OAAO;CACX;CAEA,IAAM,IAAQ,EAAQ,wBAAwB,IAAI,YAAY,CAAC,CAAM,CAAC,CAAC,GACjE,IAAS,EAAQ,6BAA6B;CAEpD,AADA,EAAM,QAAQ,CAAI,GAClB,EAAK,QAAQ,CAAM;CAEnB,IAAM,IAAQ,EAAO,OAAO,eAAe,CAAC,CAAC;CAU7C,OATK,KAOL,EAAM,cAAc,EAAO,aAEpB;EACH;EACA,eAAe;GAKX,AAJA,EAAM,WAAW,GACjB,EAAK,WAAW,GAChB,EAAO,WAAW,GAClB,EAAK,QAAQ,GACb,EAAM,KAAK;EACf;CACJ,MAjBI,EAAM,WAAW,GACjB,EAAK,WAAW,GAChB,EAAO,WAAW,GAClB,EAAK,QAAQ,GACN;AAcf"}
|
|
1
|
+
{"version":3,"file":"neural.js","names":["isNeuralSuppressionSupported","loadingBinary","readyContexts","prepareNeuralSuppressor","ready","context","assets","error","loadRnnoise","createNeuralSuppressor","binary","node","RnnoiseWorkletNode","options","input","source","output","track"],"sources":["../src/neural/index.ts"],"sourcesContent":["import { RnnoiseWorkletNode, loadRnnoise } from \"@sapphi-red/web-noise-suppressor\";\n\n/**\n * Where the suppressor's three pieces live, as URLs a bundler hands over.\n *\n * The `@sapphi-red/web-noise-suppressor` package ships the runnable assets next\n * to its code, but it cannot say where they are from inside a library: the\n * `?url` suffix that resolves a module to its served address is a bundler\n * feature, and every bundler answers it differently. So this subpath takes the\n * three resolved addresses as arguments and does the honest part — the graph,\n * the load-once semantics, the per-context registration — here.\n */\nexport interface NeuralSuppressorAssets {\n /**\n * The `AudioWorklet` processor module the model runs its DSP in\n * (`rnnoiseWorklet.js`).\n */\n workletUrl: string;\n /** The SIMD build of the model's wasm (`rnnoise_simd.wasm`). */\n simdWasmUrl: string;\n /** The baseline build, used where the engine lacks SIMD (`rnnoise.wasm`). */\n wasmUrl: string;\n}\n\n/**\n * Whether this browser can run a worklet-based noise suppressor.\n *\n * Answered from the two things the path needs that nothing but the platform can\n * supply: `AudioWorkletNode` runs custom DSP on the audio thread, and a secure\n * context is what the browser requires before letting a module near the\n * microphone graph. Everything else — the models, the wasm — ships with the\n * caller, so it cannot be missing. The context must also run at 48 kHz, which\n * is checked at build time rather than here because the caller owns how its\n * context was opened.\n *\n * Deliberately conservative: anything it cannot establish answers `false`, and\n * a `false` sends the caller back to the browser's own `noiseSuppression`\n * constraint, which is weaker but always there.\n *\n * @returns True when a neural suppressor can be built on top of a capture.\n */\nexport function isNeuralSuppressionSupported(): boolean {\n return (\n typeof AudioWorkletNode !== \"undefined\" &&\n typeof window !== \"undefined\" &&\n window.isSecureContext\n );\n}\n\n/**\n * The one wasm binary every suppressor shares, fetched once.\n *\n * `loadRnnoise` compiles the whole model, and the answer is identical for every\n * graph that opens afterwards — a mesh can build a suppressor per published\n * track and a settings dialog may build a second for its monitor within a\n * single frame. Held as the promise rather than the result so the first two\n * callers race into one fetch instead of two. Reset on failure, so the next\n * call retries instead of replaying a dead promise.\n */\nlet loadingBinary: Promise<ArrayBuffer> | null = null;\n\n/**\n * The contexts the worklet module has already been registered on, mapped to the\n * registration's own promise.\n *\n * `addModule` is per-context and throws on a name it already holds, so the\n * module records the moment a context is ready and skips the call next time.\n * The promise is what makes a fast caller that cannot wait — a mesh can open a\n * microphone and a preview within a single frame — race into one `addModule`\n * instead of two: had this been a set, the second caller would see the context\n * absent while the first was still awaiting and register the module twice.\n * Mapped to a promise rather than the module itself the way the wasm is,\n * because the registration belongs to one context while the wasm is shared,\n * and nothing here should keep a dead context alive — the value is dropped\n * with the context. On failure the entry is removed, so the next attempt\n * actually retries instead of replaying the broken registration.\n */\nconst readyContexts = new WeakMap<AudioContext, Promise<void>>();\n\n/**\n * The compiled model for this context, loading what is not ready yet.\n *\n * Idempotent across calls: the wasm fetch and the module registration both\n * happen exactly once. The wasm is shared by every suppressor, while the module\n * registration belongs to one context.\n *\n * @param context - The context the suppression graph will run in.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @returns The compiled model binary, ready to hand to a worklet node.\n * @throws Whatever the fetch or the compile threw, for the caller to fall back on.\n */\nexport async function prepareNeuralSuppressor(\n context: AudioContext,\n assets: NeuralSuppressorAssets,\n): Promise<ArrayBuffer> {\n let ready = readyContexts.get(context);\n if (!ready) {\n ready = context.audioWorklet.addModule(assets.workletUrl).then(\n () => undefined,\n (error: unknown) => {\n readyContexts.delete(context);\n throw error;\n },\n );\n readyContexts.set(context, ready);\n }\n await ready;\n if (loadingBinary === null) {\n loadingBinary = loadRnnoise({ url: assets.wasmUrl, simdUrl: assets.simdWasmUrl }).catch(\n (error: unknown) => {\n loadingBinary = null;\n throw error;\n },\n );\n }\n return loadingBinary;\n}\n\n/**\n * A denoised track plus the graph that has to come down with it.\n *\n * `track` is not the captured one — it is the output of a `MediaStream`\n * destination the worklet feeds — so stopping the published track is not enough\n * to free the microphone. `release` closes the graph; the captured track behind\n * it belongs to the caller.\n */\nexport interface NeuralSuppressor {\n /** The track to publish in place of the captured one. */\n track: MediaStreamTrack;\n /** Tears the graph down. Does not stop the source track it was built from. */\n release(): void;\n}\n\n/**\n * Build a suppressor graph on top of a captured microphone track.\n *\n * The model runs on the audio thread through an `AudioWorkletNode` — a\n * recurrent network trained on speech that separates a voice from everything\n * that is not one: keyboards, fans, traffic, a room full of people. The\n * browser's `noiseSuppression` constraint answers the same question with a\n * stationary-noise gate that either lets a transient through or eats the voice\n * with it.\n *\n * Prefer {@link prepareNeuralSuppressor} before the capture opens: the fallback\n * to the browser's own suppression is a `getUserMedia` constraint, and a\n * constraint cannot be added to a capture that already exists. A caller that\n * did not preload still works — the load happens here, idempotently.\n *\n * The model assumes 48 kHz. A context opened at any other rate answers `null`\n * before anything is fetched, because feeding speech samples of the wrong rate\n * into a network trained on 48 kHz produces mush, not a voice.\n *\n * Failure is not fatal and is reported as `null` — whether the wasm would not\n * load or the worklet node could not be built: by the time this runs the caller\n * has already committed to the neural path, so the honest outcome is a call\n * without suppression rather than a microphone that will not open. {@link\n * prepareNeuralSuppressor}, which exists to be called *before* the capture,\n * still throws so the caller can pick a different fallback while one is\n * reachable.\n *\n * @param context - The shared context, prepared at 48 kHz.\n * @param source - The captured microphone track.\n * @param assets - The resolved asset addresses from {@link NeuralSuppressorAssets}.\n * @param options - `maxChannels` is the channel count of the capture; the model\n * is mono, and a stereo capture asks for two so a second channel is not lost.\n * @returns The denoised track and its teardown, or `null` when this context or\n * this graph cannot host the suppressor.\n */\nexport async function createNeuralSuppressor(\n context: AudioContext,\n source: MediaStreamTrack,\n assets: NeuralSuppressorAssets,\n options: { maxChannels: number },\n): Promise<NeuralSuppressor | null> {\n if (context.sampleRate !== 48_000) return null;\n\n let binary: ArrayBuffer;\n try {\n binary = await prepareNeuralSuppressor(context, assets);\n } catch {\n return null;\n }\n\n let node: RnnoiseWorkletNode;\n try {\n node = new RnnoiseWorkletNode(context, {\n maxChannels: options.maxChannels,\n wasmBinary: binary,\n });\n } catch {\n return null;\n }\n\n const input = context.createMediaStreamSource(new MediaStream([source]));\n const output = context.createMediaStreamDestination();\n input.connect(node);\n node.connect(output);\n\n const track = output.stream.getAudioTracks()[0];\n if (!track) {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n return null;\n }\n track.contentHint = source.contentHint;\n\n return {\n track,\n release: () => {\n input.disconnect();\n node.disconnect();\n output.disconnect();\n node.destroy();\n track.stop();\n },\n };\n}\n"],"mappings":";;AAyCA,SAAgBA,IAAwC;CACpD,OACI,OAAO,mBAAqB,OAC5B,OAAO,SAAW,OAClB,OAAO;AAEf;AAYA,IAAIC,IAA6C,MAkB3CC,oBAAgB,IAAI,QAAqC;AAc/D,eAAsBC,EAClB,GACA,GACoB;CACpB,IAAIC,IAAQF,EAAc,IAAIG,CAAO;CAoBrC,OAnBKD,MACD,IAAQC,EAAQ,aAAa,UAAUC,EAAO,UAAU,CAAC,CAAC,WAChD,KAAA,IACL,MAAmB;EAEhB,MADAJ,EAAc,OAAOG,CAAO,GACtBE;CACV,CACJ,GACAL,EAAc,IAAIG,GAASD,CAAK,IAEpC,MAAMA,GACFH,MAAkB,SAClB,IAAgBO,EAAY;EAAE,KAAKF,EAAO;EAAS,SAASA,EAAO;CAAY,CAAC,CAAC,CAAC,OAC7E,MAAmB;EAEhB,MADA,IAAgB,MACVC;CACV,CACJ,IAEGN;AACX;AAoDA,eAAsBQ,EAClB,GACA,GACA,GACA,GACgC;CAChC,IAAIJ,EAAQ,eAAe,MAAQ,OAAO;CAE1C,IAAIK;CACJ,IAAI;EACA,IAAS,MAAMP,EAAwBE,GAASC,CAAM;CAC1D,QAAQ;EACJ,OAAO;CACX;CAEA,IAAIK;CACJ,IAAI;EACA,IAAO,IAAIC,EAAmBP,GAAS;GACnC,aAAaQ,EAAQ;GACrB,YAAYH;EAChB,CAAC;CACL,QAAQ;EACJ,OAAO;CACX;CAEA,IAAMI,IAAQT,EAAQ,wBAAwB,IAAI,YAAY,CAACU,CAAM,CAAC,CAAC,GACjEC,IAASX,EAAQ,6BAA6B;CAEpD,AADAS,EAAM,QAAQH,CAAI,GAClBA,EAAK,QAAQK,CAAM;CAEnB,IAAMC,IAAQD,EAAO,OAAO,eAAe,CAAC,CAAC;CAU7C,OATKC,KAOL,EAAM,cAAcF,EAAO,aAEpB;EACH;EACA,eAAe;GAKX,AAJAD,EAAM,WAAW,GACjBH,EAAK,WAAW,GAChBK,EAAO,WAAW,GAClBL,EAAK,QAAQ,GACbM,EAAM,KAAK;EACf;CACJ,MAjBIH,EAAM,WAAW,GACjBH,EAAK,WAAW,GAChBK,EAAO,WAAW,GAClBL,EAAK,QAAQ,GACN;AAcf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("react/jsx-runtime");function t({component:t,onSuccess:n,onError:r,locale:i,theme:a,text:o,shape:s,size:c,disableOneTap:l,width:u,className:d,style:f}){return(0,e.jsx)(`div`,{className:d,style:f,children:t({onSuccess:e=>{if(!e.credential)
|
|
1
|
+
let e=require("react/jsx-runtime");function t({component:t,onSuccess:n,onError:r,locale:i,theme:a,text:o,shape:s,size:c,disableOneTap:l,width:u,className:d,style:f}){return(0,e.jsx)(`div`,{className:d,style:f,children:t({onSuccess:e=>{if(!e.credential)r?.({provider:`google`,message:`Google returned no credential`,raw:e});else return n({idToken:e.credential,provider:`google`,raw:e})},onError:()=>{r?.({provider:`google`,message:`Google login failed`})},locale:i,theme:a,text:o,shape:s,size:c,useOneTap:!l,width:u})})}exports.GoogleSignIn=t;
|
|
2
2
|
//# sourceMappingURL=GoogleSignIn.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleSignIn.cjs","names":[],"sources":["../../src/oauth/GoogleSignIn.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — component, theme, text, shape, size and width are\n * Google's own button parameters, passed through with their names intact so the\n * reader can match them to Google's documentation;\n * onSuccess/onError/locale/disableOneTap are the wrapper's.\n */\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { OAuthCredential, OAuthError } from \"./types\";\n\nexport type GoogleSignInTheme = \"filled_blue\" | \"filled_black\" | \"outline\";\nexport type GoogleSignInText = \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\nexport type GoogleSignInShape = \"rectangular\" | \"pill\" | \"circle\" | \"square\";\nexport type GoogleSignInSize = \"large\" | \"medium\" | \"small\";\n\nexport interface GoogleSignInProps {\n /**\n * `GoogleLogin` component from `@react-oauth/google`. The caller imports\n * it and passes it through so the SDK doesn't take `@react-oauth/google`\n * as a peer dep.\n */\n component: (props: Record<string, unknown>) => ReactNode;\n /** Fired with the validated credential on success. */\n onSuccess: (credential: OAuthCredential) => void | Promise<void>;\n /** Fired with a normalised error on failure. */\n onError?: (error: OAuthError) => void;\n /** Optional locale override (e.g. `\"pt-BR\"`). Falls back to browser locale. */\n locale?: string;\n /** Visual theme — passed through to `<GoogleLogin>`. */\n theme?: GoogleSignInTheme;\n /** Button text variant. */\n text?: GoogleSignInText;\n /** Button shape. */\n shape?: GoogleSignInShape;\n /** Button size. */\n size?: GoogleSignInSize;\n /** Disable Google's \"One Tap\" auto-prompt. Default `false`. */\n disableOneTap?: boolean;\n /** Optional `width` override (px) — Google's button is fixed-width. */\n width?: number;\n /** Optional className applied to the wrapper. */\n className?: string;\n /** Optional inline style applied to the wrapper. */\n style?: CSSProperties;\n}\n\n/**\n * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:\n *\n * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,\n * `provider: \"google\"`, `raw`).\n * 2. Normalises errors into [[OAuthError]].\n * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does\n * not declare `@react-oauth/google` as a peer dep — apps that don't use\n * Google never pay for it.\n *\n * @example\n * import { GoogleLogin, GoogleOAuthProvider } from \"@react-oauth/google\";\n * import { GoogleSignIn } from \"tempest-react-sdk\";\n *\n * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>\n * <GoogleSignIn\n * component={GoogleLogin}\n * onSuccess={async ({ idToken }) => {\n * await api.post(\"/auth/google\", { body: { id_token: idToken } });\n * }}\n * onError={(err) => toast.error(err.message)}\n * />\n * </GoogleOAuthProvider>\n */\nexport function GoogleSignIn({\n component: Component,\n onSuccess,\n onError,\n locale,\n theme,\n text,\n shape,\n size,\n disableOneTap,\n width,\n className,\n style,\n}: GoogleSignInProps) {\n return (\n <div className={className} style={style}>\n {Component({\n onSuccess: (response: { credential?: string }) => {\n if (!response.credential) {\n onError?.({\n provider: \"google\",\n message: \"Google returned no credential\",\n raw: response,\n });\n return;\n }\n return onSuccess({\n idToken: response.credential,\n provider: \"google\",\n raw: response,\n });\n },\n onError: () => {\n onError?.({\n provider: \"google\",\n message: \"Google login failed\",\n });\n },\n locale,\n theme,\n text,\n shape,\n size,\n useOneTap: !disableOneTap,\n width,\n })}\n </div>\n );\n}\n"],"mappings":"mCAqEA,
|
|
1
|
+
{"version":3,"file":"GoogleSignIn.cjs","names":["react_jsx_runtime","GoogleSignIn","Component","response","onError","onSuccess","disableOneTap"],"sources":["../../src/oauth/GoogleSignIn.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — component, theme, text, shape, size and width are\n * Google's own button parameters, passed through with their names intact so the\n * reader can match them to Google's documentation;\n * onSuccess/onError/locale/disableOneTap are the wrapper's.\n */\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { OAuthCredential, OAuthError } from \"./types\";\n\nexport type GoogleSignInTheme = \"filled_blue\" | \"filled_black\" | \"outline\";\nexport type GoogleSignInText = \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\nexport type GoogleSignInShape = \"rectangular\" | \"pill\" | \"circle\" | \"square\";\nexport type GoogleSignInSize = \"large\" | \"medium\" | \"small\";\n\nexport interface GoogleSignInProps {\n /**\n * `GoogleLogin` component from `@react-oauth/google`. The caller imports\n * it and passes it through so the SDK doesn't take `@react-oauth/google`\n * as a peer dep.\n */\n component: (props: Record<string, unknown>) => ReactNode;\n /** Fired with the validated credential on success. */\n onSuccess: (credential: OAuthCredential) => void | Promise<void>;\n /** Fired with a normalised error on failure. */\n onError?: (error: OAuthError) => void;\n /** Optional locale override (e.g. `\"pt-BR\"`). Falls back to browser locale. */\n locale?: string;\n /** Visual theme — passed through to `<GoogleLogin>`. */\n theme?: GoogleSignInTheme;\n /** Button text variant. */\n text?: GoogleSignInText;\n /** Button shape. */\n shape?: GoogleSignInShape;\n /** Button size. */\n size?: GoogleSignInSize;\n /** Disable Google's \"One Tap\" auto-prompt. Default `false`. */\n disableOneTap?: boolean;\n /** Optional `width` override (px) — Google's button is fixed-width. */\n width?: number;\n /** Optional className applied to the wrapper. */\n className?: string;\n /** Optional inline style applied to the wrapper. */\n style?: CSSProperties;\n}\n\n/**\n * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:\n *\n * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,\n * `provider: \"google\"`, `raw`).\n * 2. Normalises errors into [[OAuthError]].\n * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does\n * not declare `@react-oauth/google` as a peer dep — apps that don't use\n * Google never pay for it.\n *\n * @example\n * import { GoogleLogin, GoogleOAuthProvider } from \"@react-oauth/google\";\n * import { GoogleSignIn } from \"tempest-react-sdk\";\n *\n * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>\n * <GoogleSignIn\n * component={GoogleLogin}\n * onSuccess={async ({ idToken }) => {\n * await api.post(\"/auth/google\", { body: { id_token: idToken } });\n * }}\n * onError={(err) => toast.error(err.message)}\n * />\n * </GoogleOAuthProvider>\n */\nexport function GoogleSignIn({\n component: Component,\n onSuccess,\n onError,\n locale,\n theme,\n text,\n shape,\n size,\n disableOneTap,\n width,\n className,\n style,\n}: GoogleSignInProps) {\n return (\n <div className={className} style={style}>\n {Component({\n onSuccess: (response: { credential?: string }) => {\n if (!response.credential) {\n onError?.({\n provider: \"google\",\n message: \"Google returned no credential\",\n raw: response,\n });\n return;\n }\n return onSuccess({\n idToken: response.credential,\n provider: \"google\",\n raw: response,\n });\n },\n onError: () => {\n onError?.({\n provider: \"google\",\n message: \"Google login failed\",\n });\n },\n locale,\n theme,\n text,\n shape,\n size,\n useOneTap: !disableOneTap,\n width,\n })}\n </div>\n );\n}\n"],"mappings":"A,mCAqEA,SAAgBC,EAAa,CACzB,UAAWC,EACX,YACA,UACA,SACA,QACA,OACA,QACA,OACA,gBACA,QACA,YACA,SACkB,CAClB,OACI,EAAAF,EAAA,IAAA,CAAC,MAAD,CAAgB,YAAkB,QAC7B,SAAAE,EAAU,CACP,UAAY,GAAsC,CAC9C,GAAI,CAACC,EAAS,WACVC,IAAU,CACN,SAAU,SACV,QAAS,gCACT,IAAKD,CACT,CAAC,OAGL,OAAOE,EAAU,CACb,QAASF,EAAS,WAClB,SAAU,SACV,IAAKA,CACT,CAAC,CACL,EACA,YAAe,CACXC,IAAU,CACN,SAAU,SACV,QAAS,qBACb,CAAC,CACL,EACA,SACA,QACA,OACA,QACA,OACA,UAAW,CAACE,EACZ,OACJ,CAAC,CACA,CAAA,CAEb,C"}
|
|
@@ -6,15 +6,12 @@ function t({ component: t, onSuccess: n, onError: r, locale: i, theme: a, text:
|
|
|
6
6
|
style: f,
|
|
7
7
|
children: t({
|
|
8
8
|
onSuccess: (e) => {
|
|
9
|
-
if (!e.credential) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
return n({
|
|
9
|
+
if (!e.credential) r?.({
|
|
10
|
+
provider: "google",
|
|
11
|
+
message: "Google returned no credential",
|
|
12
|
+
raw: e
|
|
13
|
+
});
|
|
14
|
+
else return n({
|
|
18
15
|
idToken: e.credential,
|
|
19
16
|
provider: "google",
|
|
20
17
|
raw: e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleSignIn.js","names":[],"sources":["../../src/oauth/GoogleSignIn.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — component, theme, text, shape, size and width are\n * Google's own button parameters, passed through with their names intact so the\n * reader can match them to Google's documentation;\n * onSuccess/onError/locale/disableOneTap are the wrapper's.\n */\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { OAuthCredential, OAuthError } from \"./types\";\n\nexport type GoogleSignInTheme = \"filled_blue\" | \"filled_black\" | \"outline\";\nexport type GoogleSignInText = \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\nexport type GoogleSignInShape = \"rectangular\" | \"pill\" | \"circle\" | \"square\";\nexport type GoogleSignInSize = \"large\" | \"medium\" | \"small\";\n\nexport interface GoogleSignInProps {\n /**\n * `GoogleLogin` component from `@react-oauth/google`. The caller imports\n * it and passes it through so the SDK doesn't take `@react-oauth/google`\n * as a peer dep.\n */\n component: (props: Record<string, unknown>) => ReactNode;\n /** Fired with the validated credential on success. */\n onSuccess: (credential: OAuthCredential) => void | Promise<void>;\n /** Fired with a normalised error on failure. */\n onError?: (error: OAuthError) => void;\n /** Optional locale override (e.g. `\"pt-BR\"`). Falls back to browser locale. */\n locale?: string;\n /** Visual theme — passed through to `<GoogleLogin>`. */\n theme?: GoogleSignInTheme;\n /** Button text variant. */\n text?: GoogleSignInText;\n /** Button shape. */\n shape?: GoogleSignInShape;\n /** Button size. */\n size?: GoogleSignInSize;\n /** Disable Google's \"One Tap\" auto-prompt. Default `false`. */\n disableOneTap?: boolean;\n /** Optional `width` override (px) — Google's button is fixed-width. */\n width?: number;\n /** Optional className applied to the wrapper. */\n className?: string;\n /** Optional inline style applied to the wrapper. */\n style?: CSSProperties;\n}\n\n/**\n * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:\n *\n * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,\n * `provider: \"google\"`, `raw`).\n * 2. Normalises errors into [[OAuthError]].\n * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does\n * not declare `@react-oauth/google` as a peer dep — apps that don't use\n * Google never pay for it.\n *\n * @example\n * import { GoogleLogin, GoogleOAuthProvider } from \"@react-oauth/google\";\n * import { GoogleSignIn } from \"tempest-react-sdk\";\n *\n * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>\n * <GoogleSignIn\n * component={GoogleLogin}\n * onSuccess={async ({ idToken }) => {\n * await api.post(\"/auth/google\", { body: { id_token: idToken } });\n * }}\n * onError={(err) => toast.error(err.message)}\n * />\n * </GoogleOAuthProvider>\n */\nexport function GoogleSignIn({\n component: Component,\n onSuccess,\n onError,\n locale,\n theme,\n text,\n shape,\n size,\n disableOneTap,\n width,\n className,\n style,\n}: GoogleSignInProps) {\n return (\n <div className={className} style={style}>\n {Component({\n onSuccess: (response: { credential?: string }) => {\n if (!response.credential) {\n onError?.({\n provider: \"google\",\n message: \"Google returned no credential\",\n raw: response,\n });\n return;\n }\n return onSuccess({\n idToken: response.credential,\n provider: \"google\",\n raw: response,\n });\n },\n onError: () => {\n onError?.({\n provider: \"google\",\n message: \"Google login failed\",\n });\n },\n locale,\n theme,\n text,\n shape,\n size,\n useOneTap: !disableOneTap,\n width,\n })}\n </div>\n );\n}\n"],"mappings":";;AAqEA,
|
|
1
|
+
{"version":3,"file":"GoogleSignIn.js","names":["GoogleSignIn","Component","response","onSuccess","disableOneTap"],"sources":["../../src/oauth/GoogleSignIn.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — component, theme, text, shape, size and width are\n * Google's own button parameters, passed through with their names intact so the\n * reader can match them to Google's documentation;\n * onSuccess/onError/locale/disableOneTap are the wrapper's.\n */\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { OAuthCredential, OAuthError } from \"./types\";\n\nexport type GoogleSignInTheme = \"filled_blue\" | \"filled_black\" | \"outline\";\nexport type GoogleSignInText = \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\nexport type GoogleSignInShape = \"rectangular\" | \"pill\" | \"circle\" | \"square\";\nexport type GoogleSignInSize = \"large\" | \"medium\" | \"small\";\n\nexport interface GoogleSignInProps {\n /**\n * `GoogleLogin` component from `@react-oauth/google`. The caller imports\n * it and passes it through so the SDK doesn't take `@react-oauth/google`\n * as a peer dep.\n */\n component: (props: Record<string, unknown>) => ReactNode;\n /** Fired with the validated credential on success. */\n onSuccess: (credential: OAuthCredential) => void | Promise<void>;\n /** Fired with a normalised error on failure. */\n onError?: (error: OAuthError) => void;\n /** Optional locale override (e.g. `\"pt-BR\"`). Falls back to browser locale. */\n locale?: string;\n /** Visual theme — passed through to `<GoogleLogin>`. */\n theme?: GoogleSignInTheme;\n /** Button text variant. */\n text?: GoogleSignInText;\n /** Button shape. */\n shape?: GoogleSignInShape;\n /** Button size. */\n size?: GoogleSignInSize;\n /** Disable Google's \"One Tap\" auto-prompt. Default `false`. */\n disableOneTap?: boolean;\n /** Optional `width` override (px) — Google's button is fixed-width. */\n width?: number;\n /** Optional className applied to the wrapper. */\n className?: string;\n /** Optional inline style applied to the wrapper. */\n style?: CSSProperties;\n}\n\n/**\n * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:\n *\n * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,\n * `provider: \"google\"`, `raw`).\n * 2. Normalises errors into [[OAuthError]].\n * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does\n * not declare `@react-oauth/google` as a peer dep — apps that don't use\n * Google never pay for it.\n *\n * @example\n * import { GoogleLogin, GoogleOAuthProvider } from \"@react-oauth/google\";\n * import { GoogleSignIn } from \"tempest-react-sdk\";\n *\n * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>\n * <GoogleSignIn\n * component={GoogleLogin}\n * onSuccess={async ({ idToken }) => {\n * await api.post(\"/auth/google\", { body: { id_token: idToken } });\n * }}\n * onError={(err) => toast.error(err.message)}\n * />\n * </GoogleOAuthProvider>\n */\nexport function GoogleSignIn({\n component: Component,\n onSuccess,\n onError,\n locale,\n theme,\n text,\n shape,\n size,\n disableOneTap,\n width,\n className,\n style,\n}: GoogleSignInProps) {\n return (\n <div className={className} style={style}>\n {Component({\n onSuccess: (response: { credential?: string }) => {\n if (!response.credential) {\n onError?.({\n provider: \"google\",\n message: \"Google returned no credential\",\n raw: response,\n });\n return;\n }\n return onSuccess({\n idToken: response.credential,\n provider: \"google\",\n raw: response,\n });\n },\n onError: () => {\n onError?.({\n provider: \"google\",\n message: \"Google login failed\",\n });\n },\n locale,\n theme,\n text,\n shape,\n size,\n useOneTap: !disableOneTap,\n width,\n })}\n </div>\n );\n}\n"],"mappings":";;AAqEA,SAAgBA,EAAa,EACzB,WAAWC,GACX,cACA,YACA,WACA,UACA,SACA,UACA,SACA,kBACA,UACA,cACA,YACkB;CAClB,OACI,kBAAC,OAAD;EAAgB;EAAkB;EAC7B,UAAAA,EAAU;GACP,YAAY,MAAsC;IAC9C,IAAI,CAACC,EAAS,YACV,IAAU;KACN,UAAU;KACV,SAAS;KACT,KAAKA;IACT,CAAC;SAGL,OAAOC,EAAU;KACb,SAASD,EAAS;KAClB,UAAU;KACV,KAAKA;IACT,CAAC;GACL;GACA,eAAe;IACX,IAAU;KACN,UAAU;KACV,SAAS;IACb,CAAC;GACL;GACA;GACA;GACA;GACA;GACA;GACA,WAAW,CAACE;GACZ;EACJ,CAAC;CACA,CAAA;AAEb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.cjs","names":[],"sources":["../../src/oauth/callback.ts"],"sourcesContent":["import type { ApiClient } from \"@/http/types\";\n\n/** Why {@link readOAuthCallbackParams} refused a callback URL. */\nexport type OAuthCallbackErrorReason = \"provider_error\" | \"missing_state\" | \"missing_code\";\n\n/**\n * A provider redirect that cannot be exchanged for a session.\n *\n * Thrown before any request leaves the browser, so a forged or truncated\n * callback never reaches the backend's exchange route.\n */\nexport class OAuthCallbackError extends Error {\n /** Which part of the callback was wrong. */\n readonly reason: OAuthCallbackErrorReason;\n /** The provider's `error` param (e.g. `\"access_denied\"`), when `reason` is `\"provider_error\"`. */\n readonly providerError?: string;\n\n /**\n * @param reason - Which part of the callback was wrong.\n * @param providerError - The provider's `error` param, when it sent one.\n */\n constructor(reason: OAuthCallbackErrorReason, providerError?: string) {\n super(\n reason === \"provider_error\"\n ? `OAuth provider returned an error: ${providerError ?? \"unknown\"}`\n : `OAuth callback is missing the \"${reason === \"missing_state\" ? \"state\" : \"code\"}\" param`,\n );\n this.name = \"OAuthCallbackError\";\n this.reason = reason;\n this.providerError = providerError;\n }\n}\n\n/** The two values a provider appends to the redirect URI on success. */\nexport interface OAuthCallbackParams {\n /** Single-use authorization code. */\n code: string;\n /**\n * The CSRF `state` the backend minted when the flow started. Forwarded\n * verbatim: only the backend holds the value it must match.\n */\n state: string;\n}\n\n/** Options for {@link readOAuthCallbackParams}. */\nexport interface ReadOAuthCallbackOptions {\n /**\n * Remove `code` and `state` from the address bar after reading them, with\n * `history.replaceState` — other params, the hash and `history.state` are\n * kept. Default: `true` when reading `window.location`, `false` when an\n * explicit `search` is passed (there is no URL of yours to clean then).\n */\n scrubUrl?: boolean;\n}\n\nconst CALLBACK_SECRETS: readonly string[] = [\"code\", \"state\"];\n\n/**\n * Drop `code` and `state` from the current URL without a navigation.\n *\n * Left in place, the single-use code sits in the history entry, in a bookmark,\n * in a shared screenshot and in the `Referer` of the next request. Passing\n * `history.state` back keeps a router's own bookkeeping (React Router's `idx`)\n * intact. No-op when neither param is present.\n */\nfunction scrubCallbackUrl(): void {\n const url = new URL(window.location.href);\n if (!CALLBACK_SECRETS.some((key) => url.searchParams.has(key))) return;\n for (const key of CALLBACK_SECRETS) url.searchParams.delete(key);\n window.history.replaceState(\n window.history.state,\n \"\",\n `${url.pathname}${url.search}${url.hash}`,\n );\n}\n\n/**\n * Read `code` and `state` from a provider's redirect, refusing an incomplete one.\n *\n * The `state` is what ties the callback to the browser that started the flow.\n * Without it, an attacker sends the victim to `/callback?code=<attacker's code>`\n * and the victim ends up signed in to the attacker's account — a login CSRF.\n * The old recipe read only `code` and posted `{ code }`, so the `state` never\n * reached a backend that could compare it (#449). This reader makes dropping it\n * impossible: it returns both or throws.\n *\n * It does **not** compare the state. In the `tempest-fastapi-sdk` flow the\n * backend mints it in `GET {prefix}/oauth/{provider}/login`, keeps it in an\n * `HttpOnly` cookie bound to the provider, and checks it with\n * `hmac.compare_digest` in the callback (single use, `AUTH_OAUTH_STATE_TTL_SECONDS`\n * expiry). The browser cannot read that cookie, so any check here would be\n * theatre; forwarding the value is the browser's whole job.\n *\n * When it reads `window.location`, it also removes `code` and `state` from the\n * address bar (see {@link ReadOAuthCallbackOptions.scrubUrl}) — before\n * validating, so a refused callback is cleaned too.\n *\n * @param search - The query string or params to read. Default: `window.location.search`.\n * @param options - Whether to scrub the URL.\n * @returns The `code` and `state`.\n * @throws {OAuthCallbackError} `\"provider_error\"` when the provider sent `error`\n * (the user declined, for instance), `\"missing_state\"` without `state`,\n * `\"missing_code\"` without `code`.\n *\n * @example\n * const { code, state } = readOAuthCallbackParams(\"?code=4%2F0A&state=xyz\");\n */\nexport function readOAuthCallbackParams(\n search?: string | URLSearchParams,\n options: ReadOAuthCallbackOptions = {},\n): OAuthCallbackParams {\n const fromLocation = search === undefined;\n const { scrubUrl = fromLocation } = options;\n const source = search ?? globalThis.location?.search ?? \"\";\n const params = typeof source === \"string\" ? new URLSearchParams(source) : source;\n const error = params.get(\"error\");\n const state = params.get(\"state\");\n const code = params.get(\"code\");\n if (scrubUrl && typeof window !== \"undefined\") scrubCallbackUrl();\n if (error) throw new OAuthCallbackError(\"provider_error\", error);\n if (!state) throw new OAuthCallbackError(\"missing_state\");\n if (!code) throw new OAuthCallbackError(\"missing_code\");\n return { code, state };\n}\n\n/** Options for {@link exchangeOAuthCallback}. */\nexport interface ExchangeOAuthCallbackOptions {\n /**\n * Path the backend's auth router is mounted at — the `prefix` given to\n * `make_auth_router`. Default: `\"/auth\"`.\n */\n prefix?: string;\n /** Where to read the provider's redirect from. Default: `window.location.search`. */\n search?: string | URLSearchParams;\n /** Forwarded to {@link readOAuthCallbackParams}. Default: scrub when reading `window.location`. */\n scrubUrl?: boolean;\n /** Abort the exchange. */\n signal?: AbortSignal;\n}\n\n/**\n * Finish a `tempest-fastapi-sdk` social login from the SPA's callback route.\n *\n * Reads the redirect with {@link readOAuthCallbackParams} and forwards `code`\n * **and** `state` to `GET {prefix}/oauth/{provider}/callback`, where the backend\n * compares the state against its `HttpOnly` cookie, redeems the code and\n * answers with the same JWT pair `POST {prefix}/login` returns.\n *\n * The request goes with `credentials: \"include\"` because the state cookie is\n * the other half of the comparison; with `skipAuth`, since there is no session\n * yet and a `401` here means a forged or expired callback, not an expired token\n * to refresh; and with `retry: false`, because the backend clears the state\n * cookie on the first attempt and a code redeems once.\n *\n * Pass it as the `exchange` of {@link useOAuthCallback}, which runs it once even\n * under StrictMode.\n *\n * @param api - The client from `createApiClient` (or `createTempestAuth().api`).\n * @param provider - The provider key registered on the backend (e.g. `\"google\"`).\n * @param options - Router prefix, the query string to read, abort signal.\n * @returns The backend's login response.\n * @throws {OAuthCallbackError} Before any request, when the redirect carries\n * `error` or lacks `state` or `code`.\n *\n * @example\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: () => navigate(\"/\", { replace: true }),\n * });\n */\nexport async function exchangeOAuthCallback<T>(\n api: ApiClient,\n provider: string,\n options: ExchangeOAuthCallbackOptions = {},\n): Promise<T> {\n const { prefix = \"/auth\", search, scrubUrl, signal } = options;\n const { code, state } = readOAuthCallbackParams(search, { scrubUrl });\n const base = prefix.replace(/\\/+$/, \"\");\n return api.get<T>(`${base}/oauth/${encodeURIComponent(provider)}/callback`, {\n params: { code, state },\n credentials: \"include\",\n skipAuth: true,\n retry: false,\n signal,\n });\n}\n"],"mappings":"AAWA,
|
|
1
|
+
{"version":3,"file":"callback.cjs","names":["OAuthCallbackError","reason","providerError","CALLBACK_SECRETS","scrubCallbackUrl","url","key","readOAuthCallbackParams","fromLocation","search","options","source","params","error","state","code","scrubUrl","exchangeOAuthCallback","base","prefix","api","provider"],"sources":["../../src/oauth/callback.ts"],"sourcesContent":["import type { ApiClient } from \"@/http/types\";\n\n/** Why {@link readOAuthCallbackParams} refused a callback URL. */\nexport type OAuthCallbackErrorReason = \"provider_error\" | \"missing_state\" | \"missing_code\";\n\n/**\n * A provider redirect that cannot be exchanged for a session.\n *\n * Thrown before any request leaves the browser, so a forged or truncated\n * callback never reaches the backend's exchange route.\n */\nexport class OAuthCallbackError extends Error {\n /** Which part of the callback was wrong. */\n readonly reason: OAuthCallbackErrorReason;\n /** The provider's `error` param (e.g. `\"access_denied\"`), when `reason` is `\"provider_error\"`. */\n readonly providerError?: string;\n\n /**\n * @param reason - Which part of the callback was wrong.\n * @param providerError - The provider's `error` param, when it sent one.\n */\n constructor(reason: OAuthCallbackErrorReason, providerError?: string) {\n super(\n reason === \"provider_error\"\n ? `OAuth provider returned an error: ${providerError ?? \"unknown\"}`\n : `OAuth callback is missing the \"${reason === \"missing_state\" ? \"state\" : \"code\"}\" param`,\n );\n this.name = \"OAuthCallbackError\";\n this.reason = reason;\n this.providerError = providerError;\n }\n}\n\n/** The two values a provider appends to the redirect URI on success. */\nexport interface OAuthCallbackParams {\n /** Single-use authorization code. */\n code: string;\n /**\n * The CSRF `state` the backend minted when the flow started. Forwarded\n * verbatim: only the backend holds the value it must match.\n */\n state: string;\n}\n\n/** Options for {@link readOAuthCallbackParams}. */\nexport interface ReadOAuthCallbackOptions {\n /**\n * Remove `code` and `state` from the address bar after reading them, with\n * `history.replaceState` — other params, the hash and `history.state` are\n * kept. Default: `true` when reading `window.location`, `false` when an\n * explicit `search` is passed (there is no URL of yours to clean then).\n */\n scrubUrl?: boolean;\n}\n\nconst CALLBACK_SECRETS: readonly string[] = [\"code\", \"state\"];\n\n/**\n * Drop `code` and `state` from the current URL without a navigation.\n *\n * Left in place, the single-use code sits in the history entry, in a bookmark,\n * in a shared screenshot and in the `Referer` of the next request. Passing\n * `history.state` back keeps a router's own bookkeeping (React Router's `idx`)\n * intact. No-op when neither param is present.\n */\nfunction scrubCallbackUrl(): void {\n const url = new URL(window.location.href);\n if (!CALLBACK_SECRETS.some((key) => url.searchParams.has(key))) return;\n for (const key of CALLBACK_SECRETS) url.searchParams.delete(key);\n window.history.replaceState(\n window.history.state,\n \"\",\n `${url.pathname}${url.search}${url.hash}`,\n );\n}\n\n/**\n * Read `code` and `state` from a provider's redirect, refusing an incomplete one.\n *\n * The `state` is what ties the callback to the browser that started the flow.\n * Without it, an attacker sends the victim to `/callback?code=<attacker's code>`\n * and the victim ends up signed in to the attacker's account — a login CSRF.\n * The old recipe read only `code` and posted `{ code }`, so the `state` never\n * reached a backend that could compare it (#449). This reader makes dropping it\n * impossible: it returns both or throws.\n *\n * It does **not** compare the state. In the `tempest-fastapi-sdk` flow the\n * backend mints it in `GET {prefix}/oauth/{provider}/login`, keeps it in an\n * `HttpOnly` cookie bound to the provider, and checks it with\n * `hmac.compare_digest` in the callback (single use, `AUTH_OAUTH_STATE_TTL_SECONDS`\n * expiry). The browser cannot read that cookie, so any check here would be\n * theatre; forwarding the value is the browser's whole job.\n *\n * When it reads `window.location`, it also removes `code` and `state` from the\n * address bar (see {@link ReadOAuthCallbackOptions.scrubUrl}) — before\n * validating, so a refused callback is cleaned too.\n *\n * @param search - The query string or params to read. Default: `window.location.search`.\n * @param options - Whether to scrub the URL.\n * @returns The `code` and `state`.\n * @throws {OAuthCallbackError} `\"provider_error\"` when the provider sent `error`\n * (the user declined, for instance), `\"missing_state\"` without `state`,\n * `\"missing_code\"` without `code`.\n *\n * @example\n * const { code, state } = readOAuthCallbackParams(\"?code=4%2F0A&state=xyz\");\n */\nexport function readOAuthCallbackParams(\n search?: string | URLSearchParams,\n options: ReadOAuthCallbackOptions = {},\n): OAuthCallbackParams {\n const fromLocation = search === undefined;\n const { scrubUrl = fromLocation } = options;\n const source = search ?? globalThis.location?.search ?? \"\";\n const params = typeof source === \"string\" ? new URLSearchParams(source) : source;\n const error = params.get(\"error\");\n const state = params.get(\"state\");\n const code = params.get(\"code\");\n if (scrubUrl && typeof window !== \"undefined\") scrubCallbackUrl();\n if (error) throw new OAuthCallbackError(\"provider_error\", error);\n if (!state) throw new OAuthCallbackError(\"missing_state\");\n if (!code) throw new OAuthCallbackError(\"missing_code\");\n return { code, state };\n}\n\n/** Options for {@link exchangeOAuthCallback}. */\nexport interface ExchangeOAuthCallbackOptions {\n /**\n * Path the backend's auth router is mounted at — the `prefix` given to\n * `make_auth_router`. Default: `\"/auth\"`.\n */\n prefix?: string;\n /** Where to read the provider's redirect from. Default: `window.location.search`. */\n search?: string | URLSearchParams;\n /** Forwarded to {@link readOAuthCallbackParams}. Default: scrub when reading `window.location`. */\n scrubUrl?: boolean;\n /** Abort the exchange. */\n signal?: AbortSignal;\n}\n\n/**\n * Finish a `tempest-fastapi-sdk` social login from the SPA's callback route.\n *\n * Reads the redirect with {@link readOAuthCallbackParams} and forwards `code`\n * **and** `state` to `GET {prefix}/oauth/{provider}/callback`, where the backend\n * compares the state against its `HttpOnly` cookie, redeems the code and\n * answers with the same JWT pair `POST {prefix}/login` returns.\n *\n * The request goes with `credentials: \"include\"` because the state cookie is\n * the other half of the comparison; with `skipAuth`, since there is no session\n * yet and a `401` here means a forged or expired callback, not an expired token\n * to refresh; and with `retry: false`, because the backend clears the state\n * cookie on the first attempt and a code redeems once.\n *\n * Pass it as the `exchange` of {@link useOAuthCallback}, which runs it once even\n * under StrictMode.\n *\n * @param api - The client from `createApiClient` (or `createTempestAuth().api`).\n * @param provider - The provider key registered on the backend (e.g. `\"google\"`).\n * @param options - Router prefix, the query string to read, abort signal.\n * @returns The backend's login response.\n * @throws {OAuthCallbackError} Before any request, when the redirect carries\n * `error` or lacks `state` or `code`.\n *\n * @example\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: () => navigate(\"/\", { replace: true }),\n * });\n */\nexport async function exchangeOAuthCallback<T>(\n api: ApiClient,\n provider: string,\n options: ExchangeOAuthCallbackOptions = {},\n): Promise<T> {\n const { prefix = \"/auth\", search, scrubUrl, signal } = options;\n const { code, state } = readOAuthCallbackParams(search, { scrubUrl });\n const base = prefix.replace(/\\/+$/, \"\");\n return api.get<T>(`${base}/oauth/${encodeURIComponent(provider)}/callback`, {\n params: { code, state },\n credentials: \"include\",\n skipAuth: true,\n retry: false,\n signal,\n });\n}\n"],"mappings":"AAWA,IAAaA,EAAb,cAAwC,KAAM,CAE1C,OAEA,cAMA,YAAY,EAAkC,EAAwB,CAClE,MACIC,IAAW,iBACL,qCAAqCC,GAAiB,YACtD,kCAAkCD,IAAW,gBAAkB,QAAU,OAAO,QAC1F,EACA,KAAK,KAAO,qBACZ,KAAK,OAASA,EACd,KAAK,cAAgBC,CACzB,CACJ,EAwBMC,EAAsC,CAAC,OAAQ,OAAO,EAU5D,SAASC,GAAyB,CAC9B,IAAMC,EAAM,IAAI,IAAI,OAAO,SAAS,IAAI,EACxC,GAAKF,EAAiB,KAAM,GAAQE,EAAI,aAAa,IAAIC,CAAG,CAAC,EAC7D,KAAK,IAAMA,KAAOH,EAAkBE,EAAI,aAAa,OAAOC,CAAG,EAC/D,OAAO,QAAQ,aACX,OAAO,QAAQ,MACf,GACA,GAAGD,EAAI,WAAWA,EAAI,SAASA,EAAI,MACvC,CAL+D,CAMnE,CAiCA,SAAgBE,EACZ,EACA,EAAoC,CAAC,EAClB,CACnB,IAAMC,EAAeC,IAAW,IAAA,GAC1B,CAAE,WAAWD,GAAiBE,EAC9BC,EAASF,GAAU,WAAW,UAAU,QAAU,GAClDG,EAAS,OAAOD,GAAW,SAAW,IAAI,gBAAgBA,CAAM,EAAIA,EACpEE,EAAQD,EAAO,IAAI,OAAO,EAC1BE,EAAQF,EAAO,IAAI,OAAO,EAC1BG,EAAOH,EAAO,IAAI,MAAM,EAE9B,GADII,GAAY,OAAO,OAAW,KAAaZ,EAAiB,EAC5DS,EAAO,MAAM,IAAIb,EAAmB,iBAAkBa,CAAK,EAC/D,GAAI,CAACC,EAAO,MAAM,IAAId,EAAmB,eAAe,EACxD,GAAI,CAACe,EAAM,MAAM,IAAIf,EAAmB,cAAc,EACtD,MAAO,CAAE,OAAM,OAAM,CACzB,CA+CA,eAAsBiB,EAClB,EACA,EACA,EAAwC,CAAC,EAC/B,CACV,GAAM,CAAE,SAAS,QAAS,SAAQ,WAAU,UAAWP,EACjD,CAAE,OAAM,SAAUH,EAAwBE,EAAQ,CAAE,UAAS,CAAC,EAC9DS,EAAOC,EAAO,QAAQ,OAAQ,EAAE,EACtC,OAAOC,EAAI,IAAO,GAAGF,EAAK,SAAS,mBAAmBG,CAAQ,EAAE,WAAY,CACxE,OAAQ,CAAE,OAAM,OAAM,EACtB,YAAa,UACb,SAAU,GACV,MAAO,GACP,QACJ,CAAC,CACL,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.js","names":[],"sources":["../../src/oauth/callback.ts"],"sourcesContent":["import type { ApiClient } from \"@/http/types\";\n\n/** Why {@link readOAuthCallbackParams} refused a callback URL. */\nexport type OAuthCallbackErrorReason = \"provider_error\" | \"missing_state\" | \"missing_code\";\n\n/**\n * A provider redirect that cannot be exchanged for a session.\n *\n * Thrown before any request leaves the browser, so a forged or truncated\n * callback never reaches the backend's exchange route.\n */\nexport class OAuthCallbackError extends Error {\n /** Which part of the callback was wrong. */\n readonly reason: OAuthCallbackErrorReason;\n /** The provider's `error` param (e.g. `\"access_denied\"`), when `reason` is `\"provider_error\"`. */\n readonly providerError?: string;\n\n /**\n * @param reason - Which part of the callback was wrong.\n * @param providerError - The provider's `error` param, when it sent one.\n */\n constructor(reason: OAuthCallbackErrorReason, providerError?: string) {\n super(\n reason === \"provider_error\"\n ? `OAuth provider returned an error: ${providerError ?? \"unknown\"}`\n : `OAuth callback is missing the \"${reason === \"missing_state\" ? \"state\" : \"code\"}\" param`,\n );\n this.name = \"OAuthCallbackError\";\n this.reason = reason;\n this.providerError = providerError;\n }\n}\n\n/** The two values a provider appends to the redirect URI on success. */\nexport interface OAuthCallbackParams {\n /** Single-use authorization code. */\n code: string;\n /**\n * The CSRF `state` the backend minted when the flow started. Forwarded\n * verbatim: only the backend holds the value it must match.\n */\n state: string;\n}\n\n/** Options for {@link readOAuthCallbackParams}. */\nexport interface ReadOAuthCallbackOptions {\n /**\n * Remove `code` and `state` from the address bar after reading them, with\n * `history.replaceState` — other params, the hash and `history.state` are\n * kept. Default: `true` when reading `window.location`, `false` when an\n * explicit `search` is passed (there is no URL of yours to clean then).\n */\n scrubUrl?: boolean;\n}\n\nconst CALLBACK_SECRETS: readonly string[] = [\"code\", \"state\"];\n\n/**\n * Drop `code` and `state` from the current URL without a navigation.\n *\n * Left in place, the single-use code sits in the history entry, in a bookmark,\n * in a shared screenshot and in the `Referer` of the next request. Passing\n * `history.state` back keeps a router's own bookkeeping (React Router's `idx`)\n * intact. No-op when neither param is present.\n */\nfunction scrubCallbackUrl(): void {\n const url = new URL(window.location.href);\n if (!CALLBACK_SECRETS.some((key) => url.searchParams.has(key))) return;\n for (const key of CALLBACK_SECRETS) url.searchParams.delete(key);\n window.history.replaceState(\n window.history.state,\n \"\",\n `${url.pathname}${url.search}${url.hash}`,\n );\n}\n\n/**\n * Read `code` and `state` from a provider's redirect, refusing an incomplete one.\n *\n * The `state` is what ties the callback to the browser that started the flow.\n * Without it, an attacker sends the victim to `/callback?code=<attacker's code>`\n * and the victim ends up signed in to the attacker's account — a login CSRF.\n * The old recipe read only `code` and posted `{ code }`, so the `state` never\n * reached a backend that could compare it (#449). This reader makes dropping it\n * impossible: it returns both or throws.\n *\n * It does **not** compare the state. In the `tempest-fastapi-sdk` flow the\n * backend mints it in `GET {prefix}/oauth/{provider}/login`, keeps it in an\n * `HttpOnly` cookie bound to the provider, and checks it with\n * `hmac.compare_digest` in the callback (single use, `AUTH_OAUTH_STATE_TTL_SECONDS`\n * expiry). The browser cannot read that cookie, so any check here would be\n * theatre; forwarding the value is the browser's whole job.\n *\n * When it reads `window.location`, it also removes `code` and `state` from the\n * address bar (see {@link ReadOAuthCallbackOptions.scrubUrl}) — before\n * validating, so a refused callback is cleaned too.\n *\n * @param search - The query string or params to read. Default: `window.location.search`.\n * @param options - Whether to scrub the URL.\n * @returns The `code` and `state`.\n * @throws {OAuthCallbackError} `\"provider_error\"` when the provider sent `error`\n * (the user declined, for instance), `\"missing_state\"` without `state`,\n * `\"missing_code\"` without `code`.\n *\n * @example\n * const { code, state } = readOAuthCallbackParams(\"?code=4%2F0A&state=xyz\");\n */\nexport function readOAuthCallbackParams(\n search?: string | URLSearchParams,\n options: ReadOAuthCallbackOptions = {},\n): OAuthCallbackParams {\n const fromLocation = search === undefined;\n const { scrubUrl = fromLocation } = options;\n const source = search ?? globalThis.location?.search ?? \"\";\n const params = typeof source === \"string\" ? new URLSearchParams(source) : source;\n const error = params.get(\"error\");\n const state = params.get(\"state\");\n const code = params.get(\"code\");\n if (scrubUrl && typeof window !== \"undefined\") scrubCallbackUrl();\n if (error) throw new OAuthCallbackError(\"provider_error\", error);\n if (!state) throw new OAuthCallbackError(\"missing_state\");\n if (!code) throw new OAuthCallbackError(\"missing_code\");\n return { code, state };\n}\n\n/** Options for {@link exchangeOAuthCallback}. */\nexport interface ExchangeOAuthCallbackOptions {\n /**\n * Path the backend's auth router is mounted at — the `prefix` given to\n * `make_auth_router`. Default: `\"/auth\"`.\n */\n prefix?: string;\n /** Where to read the provider's redirect from. Default: `window.location.search`. */\n search?: string | URLSearchParams;\n /** Forwarded to {@link readOAuthCallbackParams}. Default: scrub when reading `window.location`. */\n scrubUrl?: boolean;\n /** Abort the exchange. */\n signal?: AbortSignal;\n}\n\n/**\n * Finish a `tempest-fastapi-sdk` social login from the SPA's callback route.\n *\n * Reads the redirect with {@link readOAuthCallbackParams} and forwards `code`\n * **and** `state` to `GET {prefix}/oauth/{provider}/callback`, where the backend\n * compares the state against its `HttpOnly` cookie, redeems the code and\n * answers with the same JWT pair `POST {prefix}/login` returns.\n *\n * The request goes with `credentials: \"include\"` because the state cookie is\n * the other half of the comparison; with `skipAuth`, since there is no session\n * yet and a `401` here means a forged or expired callback, not an expired token\n * to refresh; and with `retry: false`, because the backend clears the state\n * cookie on the first attempt and a code redeems once.\n *\n * Pass it as the `exchange` of {@link useOAuthCallback}, which runs it once even\n * under StrictMode.\n *\n * @param api - The client from `createApiClient` (or `createTempestAuth().api`).\n * @param provider - The provider key registered on the backend (e.g. `\"google\"`).\n * @param options - Router prefix, the query string to read, abort signal.\n * @returns The backend's login response.\n * @throws {OAuthCallbackError} Before any request, when the redirect carries\n * `error` or lacks `state` or `code`.\n *\n * @example\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: () => navigate(\"/\", { replace: true }),\n * });\n */\nexport async function exchangeOAuthCallback<T>(\n api: ApiClient,\n provider: string,\n options: ExchangeOAuthCallbackOptions = {},\n): Promise<T> {\n const { prefix = \"/auth\", search, scrubUrl, signal } = options;\n const { code, state } = readOAuthCallbackParams(search, { scrubUrl });\n const base = prefix.replace(/\\/+$/, \"\");\n return api.get<T>(`${base}/oauth/${encodeURIComponent(provider)}/callback`, {\n params: { code, state },\n credentials: \"include\",\n skipAuth: true,\n retry: false,\n signal,\n });\n}\n"],"mappings":";AAWA,
|
|
1
|
+
{"version":3,"file":"callback.js","names":["OAuthCallbackError","reason","providerError","CALLBACK_SECRETS","scrubCallbackUrl","url","key","readOAuthCallbackParams","fromLocation","search","options","source","params","error","state","code","scrubUrl","exchangeOAuthCallback","base","prefix","api","provider"],"sources":["../../src/oauth/callback.ts"],"sourcesContent":["import type { ApiClient } from \"@/http/types\";\n\n/** Why {@link readOAuthCallbackParams} refused a callback URL. */\nexport type OAuthCallbackErrorReason = \"provider_error\" | \"missing_state\" | \"missing_code\";\n\n/**\n * A provider redirect that cannot be exchanged for a session.\n *\n * Thrown before any request leaves the browser, so a forged or truncated\n * callback never reaches the backend's exchange route.\n */\nexport class OAuthCallbackError extends Error {\n /** Which part of the callback was wrong. */\n readonly reason: OAuthCallbackErrorReason;\n /** The provider's `error` param (e.g. `\"access_denied\"`), when `reason` is `\"provider_error\"`. */\n readonly providerError?: string;\n\n /**\n * @param reason - Which part of the callback was wrong.\n * @param providerError - The provider's `error` param, when it sent one.\n */\n constructor(reason: OAuthCallbackErrorReason, providerError?: string) {\n super(\n reason === \"provider_error\"\n ? `OAuth provider returned an error: ${providerError ?? \"unknown\"}`\n : `OAuth callback is missing the \"${reason === \"missing_state\" ? \"state\" : \"code\"}\" param`,\n );\n this.name = \"OAuthCallbackError\";\n this.reason = reason;\n this.providerError = providerError;\n }\n}\n\n/** The two values a provider appends to the redirect URI on success. */\nexport interface OAuthCallbackParams {\n /** Single-use authorization code. */\n code: string;\n /**\n * The CSRF `state` the backend minted when the flow started. Forwarded\n * verbatim: only the backend holds the value it must match.\n */\n state: string;\n}\n\n/** Options for {@link readOAuthCallbackParams}. */\nexport interface ReadOAuthCallbackOptions {\n /**\n * Remove `code` and `state` from the address bar after reading them, with\n * `history.replaceState` — other params, the hash and `history.state` are\n * kept. Default: `true` when reading `window.location`, `false` when an\n * explicit `search` is passed (there is no URL of yours to clean then).\n */\n scrubUrl?: boolean;\n}\n\nconst CALLBACK_SECRETS: readonly string[] = [\"code\", \"state\"];\n\n/**\n * Drop `code` and `state` from the current URL without a navigation.\n *\n * Left in place, the single-use code sits in the history entry, in a bookmark,\n * in a shared screenshot and in the `Referer` of the next request. Passing\n * `history.state` back keeps a router's own bookkeeping (React Router's `idx`)\n * intact. No-op when neither param is present.\n */\nfunction scrubCallbackUrl(): void {\n const url = new URL(window.location.href);\n if (!CALLBACK_SECRETS.some((key) => url.searchParams.has(key))) return;\n for (const key of CALLBACK_SECRETS) url.searchParams.delete(key);\n window.history.replaceState(\n window.history.state,\n \"\",\n `${url.pathname}${url.search}${url.hash}`,\n );\n}\n\n/**\n * Read `code` and `state` from a provider's redirect, refusing an incomplete one.\n *\n * The `state` is what ties the callback to the browser that started the flow.\n * Without it, an attacker sends the victim to `/callback?code=<attacker's code>`\n * and the victim ends up signed in to the attacker's account — a login CSRF.\n * The old recipe read only `code` and posted `{ code }`, so the `state` never\n * reached a backend that could compare it (#449). This reader makes dropping it\n * impossible: it returns both or throws.\n *\n * It does **not** compare the state. In the `tempest-fastapi-sdk` flow the\n * backend mints it in `GET {prefix}/oauth/{provider}/login`, keeps it in an\n * `HttpOnly` cookie bound to the provider, and checks it with\n * `hmac.compare_digest` in the callback (single use, `AUTH_OAUTH_STATE_TTL_SECONDS`\n * expiry). The browser cannot read that cookie, so any check here would be\n * theatre; forwarding the value is the browser's whole job.\n *\n * When it reads `window.location`, it also removes `code` and `state` from the\n * address bar (see {@link ReadOAuthCallbackOptions.scrubUrl}) — before\n * validating, so a refused callback is cleaned too.\n *\n * @param search - The query string or params to read. Default: `window.location.search`.\n * @param options - Whether to scrub the URL.\n * @returns The `code` and `state`.\n * @throws {OAuthCallbackError} `\"provider_error\"` when the provider sent `error`\n * (the user declined, for instance), `\"missing_state\"` without `state`,\n * `\"missing_code\"` without `code`.\n *\n * @example\n * const { code, state } = readOAuthCallbackParams(\"?code=4%2F0A&state=xyz\");\n */\nexport function readOAuthCallbackParams(\n search?: string | URLSearchParams,\n options: ReadOAuthCallbackOptions = {},\n): OAuthCallbackParams {\n const fromLocation = search === undefined;\n const { scrubUrl = fromLocation } = options;\n const source = search ?? globalThis.location?.search ?? \"\";\n const params = typeof source === \"string\" ? new URLSearchParams(source) : source;\n const error = params.get(\"error\");\n const state = params.get(\"state\");\n const code = params.get(\"code\");\n if (scrubUrl && typeof window !== \"undefined\") scrubCallbackUrl();\n if (error) throw new OAuthCallbackError(\"provider_error\", error);\n if (!state) throw new OAuthCallbackError(\"missing_state\");\n if (!code) throw new OAuthCallbackError(\"missing_code\");\n return { code, state };\n}\n\n/** Options for {@link exchangeOAuthCallback}. */\nexport interface ExchangeOAuthCallbackOptions {\n /**\n * Path the backend's auth router is mounted at — the `prefix` given to\n * `make_auth_router`. Default: `\"/auth\"`.\n */\n prefix?: string;\n /** Where to read the provider's redirect from. Default: `window.location.search`. */\n search?: string | URLSearchParams;\n /** Forwarded to {@link readOAuthCallbackParams}. Default: scrub when reading `window.location`. */\n scrubUrl?: boolean;\n /** Abort the exchange. */\n signal?: AbortSignal;\n}\n\n/**\n * Finish a `tempest-fastapi-sdk` social login from the SPA's callback route.\n *\n * Reads the redirect with {@link readOAuthCallbackParams} and forwards `code`\n * **and** `state` to `GET {prefix}/oauth/{provider}/callback`, where the backend\n * compares the state against its `HttpOnly` cookie, redeems the code and\n * answers with the same JWT pair `POST {prefix}/login` returns.\n *\n * The request goes with `credentials: \"include\"` because the state cookie is\n * the other half of the comparison; with `skipAuth`, since there is no session\n * yet and a `401` here means a forged or expired callback, not an expired token\n * to refresh; and with `retry: false`, because the backend clears the state\n * cookie on the first attempt and a code redeems once.\n *\n * Pass it as the `exchange` of {@link useOAuthCallback}, which runs it once even\n * under StrictMode.\n *\n * @param api - The client from `createApiClient` (or `createTempestAuth().api`).\n * @param provider - The provider key registered on the backend (e.g. `\"google\"`).\n * @param options - Router prefix, the query string to read, abort signal.\n * @returns The backend's login response.\n * @throws {OAuthCallbackError} Before any request, when the redirect carries\n * `error` or lacks `state` or `code`.\n *\n * @example\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: () => navigate(\"/\", { replace: true }),\n * });\n */\nexport async function exchangeOAuthCallback<T>(\n api: ApiClient,\n provider: string,\n options: ExchangeOAuthCallbackOptions = {},\n): Promise<T> {\n const { prefix = \"/auth\", search, scrubUrl, signal } = options;\n const { code, state } = readOAuthCallbackParams(search, { scrubUrl });\n const base = prefix.replace(/\\/+$/, \"\");\n return api.get<T>(`${base}/oauth/${encodeURIComponent(provider)}/callback`, {\n params: { code, state },\n credentials: \"include\",\n skipAuth: true,\n retry: false,\n signal,\n });\n}\n"],"mappings":";AAWA,IAAaA,IAAb,cAAwC,MAAM;CAE1C;CAEA;CAMA,YAAY,GAAkC,GAAwB;EAQlE,AAPA,MACIC,MAAW,mBACL,qCAAqCC,KAAiB,cACtD,kCAAkCD,MAAW,kBAAkB,UAAU,OAAO,QAC1F,GACA,KAAK,OAAO,sBACZ,KAAK,SAASA,GACd,KAAK,gBAAgBC;CACzB;AACJ,GAwBMC,IAAsC,CAAC,QAAQ,OAAO;AAU5D,SAASC,IAAyB;CAC9B,IAAMC,IAAM,IAAI,IAAI,OAAO,SAAS,IAAI;CACxC,IAAKF,EAAiB,MAAM,MAAQE,EAAI,aAAa,IAAIC,CAAG,CAAC,GAC7D;OAAK,IAAMA,KAAOH,GAAkB,EAAI,aAAa,OAAOG,CAAG;EAC/D,OAAO,QAAQ,aACX,OAAO,QAAQ,OACf,IACA,GAAGD,EAAI,WAAWA,EAAI,SAASA,EAAI,MACvC;CAL+D;AAMnE;AAiCA,SAAgBE,EACZ,GACA,IAAoC,CAAC,GAClB;CACnB,IAAMC,IAAeC,MAAW,KAAA,GAC1B,EAAE,cAAWD,MAAiBE,GAC9BC,IAASF,KAAU,WAAW,UAAU,UAAU,IAClDG,IAAS,OAAOD,KAAW,WAAW,IAAI,gBAAgBA,CAAM,IAAIA,GACpEE,IAAQD,EAAO,IAAI,OAAO,GAC1BE,IAAQF,EAAO,IAAI,OAAO,GAC1BG,IAAOH,EAAO,IAAI,MAAM;CAE9B,IADII,KAAY,OAAO,SAAW,OAAaZ,EAAiB,GAC5DS,GAAO,MAAM,IAAIb,EAAmB,kBAAkBa,CAAK;CAC/D,IAAI,CAACC,GAAO,MAAM,IAAId,EAAmB,eAAe;CACxD,IAAI,CAACe,GAAM,MAAM,IAAIf,EAAmB,cAAc;CACtD,OAAO;EAAE;EAAM;CAAM;AACzB;AA+CA,eAAsBiB,EAClB,GACA,GACA,IAAwC,CAAC,GAC/B;CACV,IAAM,EAAE,YAAS,SAAS,WAAQ,aAAU,cAAWP,GACjD,EAAE,SAAM,aAAUH,EAAwBE,GAAQ,EAAE,YAAS,CAAC,GAC9DS,IAAOC,EAAO,QAAQ,QAAQ,EAAE;CACtC,OAAOC,EAAI,IAAO,GAAGF,EAAK,SAAS,mBAAmBG,CAAQ,EAAE,YAAY;EACxE,QAAQ;GAAE;GAAM;EAAM;EACtB,aAAa;EACb,UAAU;EACV,OAAO;EACP;CACJ,CAAC;AACL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-oauth-callback.cjs","names":[],"sources":["../../src/oauth/use-oauth-callback.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nexport interface UseOAuthCallbackOptions<T> {\n /** Function that exchanges the provider response for an app session. Called once on mount. */\n exchange: () => Promise<T>;\n /** Fired with the result on success. Receives the value resolved by `exchange`. */\n onSuccess?: (result: T) => void | Promise<void>;\n /** Fired when `exchange` throws or rejects. */\n onError?: (error: unknown) => void;\n}\n\nexport interface UseOAuthCallbackResult<T> {\n /** `true` while the exchange promise is pending. */\n loading: boolean;\n /** Last resolved value, when `status === \"success\"`. */\n data: T | null;\n /** Last rejection reason, when `status === \"error\"`. */\n error: unknown;\n /** Aggregated state — `\"pending\"`, `\"success\"`, or `\"error\"`. */\n status: \"pending\" | \"success\" | \"error\";\n}\n\n/**\n * Run an OAuth-callback \"exchange\" exactly once on mount. Designed for\n * `/callback` routes that receive provider redirects and need to swap a\n * code/token for an app session via the backend.\n *\n * Runs `exchange` once per logical mount and keeps its result. StrictMode's\n * simulated unmount/remount in dev and a parent re-render with inline\n * callbacks used to cancel the only exchange and skip the second, leaving the\n * hook `\"pending\"` forever with the single-use code already spent. Now the\n * options live in a latest-value ref, the effect has no dependencies, and the\n * result is dropped only when the component is still unmounted when it lands.\n * The newest `onSuccess`/`onError` are the ones called.\n *\n * For a provider redirect, the exchange must carry the `state` along with the\n * `code`, or no backend can tell a forged callback from a real one (login\n * CSRF). `exchangeOAuthCallback` does that against a\n * `tempest-fastapi-sdk` backend; `readOAuthCallbackParams` returns both\n * values (or throws) for any other backend.\n *\n * @example\n * function OAuthCallback() {\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: ({ user_id, access_token }) => {\n * useAuthStore.getState().setSession({ user: { id: user_id }, token: access_token });\n * navigate(\"/dashboard\", { replace: true });\n * },\n * onError: () => navigate(\"/login?error=oauth\", { replace: true }),\n * });\n *\n * if (loading) return <Spinner />;\n * if (error) return <ErrorState description=\"OAuth falhou\" />;\n * return null;\n * }\n */\nexport function useOAuthCallback<T>(\n options: UseOAuthCallbackOptions<T>,\n): UseOAuthCallbackResult<T> {\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [status, setStatus] = useState<\"pending\" | \"success\" | \"error\">(\"pending\");\n const optionsRef = useRef<UseOAuthCallbackOptions<T>>(options);\n const ranRef = useRef<boolean>(false);\n const mountedRef = useRef<boolean>(false);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n mountedRef.current = true;\n if (!ranRef.current) {\n ranRef.current = true;\n optionsRef.current\n .exchange()\n .then((result) => {\n if (!mountedRef.current) return;\n setData(result);\n setStatus(\"success\");\n return optionsRef.current.onSuccess?.(result);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current) return;\n setError(err);\n setStatus(\"error\");\n optionsRef.current.onError?.(err);\n });\n }\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return { loading: status === \"pending\", data, error, status };\n}\n"],"mappings":"uBAyDA,
|
|
1
|
+
{"version":3,"file":"use-oauth-callback.cjs","names":["useState","useRef","react","useOAuthCallback","data","setData","error","setError","status","setStatus","optionsRef","options","ranRef","mountedRef","result","err"],"sources":["../../src/oauth/use-oauth-callback.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nexport interface UseOAuthCallbackOptions<T> {\n /** Function that exchanges the provider response for an app session. Called once on mount. */\n exchange: () => Promise<T>;\n /** Fired with the result on success. Receives the value resolved by `exchange`. */\n onSuccess?: (result: T) => void | Promise<void>;\n /** Fired when `exchange` throws or rejects. */\n onError?: (error: unknown) => void;\n}\n\nexport interface UseOAuthCallbackResult<T> {\n /** `true` while the exchange promise is pending. */\n loading: boolean;\n /** Last resolved value, when `status === \"success\"`. */\n data: T | null;\n /** Last rejection reason, when `status === \"error\"`. */\n error: unknown;\n /** Aggregated state — `\"pending\"`, `\"success\"`, or `\"error\"`. */\n status: \"pending\" | \"success\" | \"error\";\n}\n\n/**\n * Run an OAuth-callback \"exchange\" exactly once on mount. Designed for\n * `/callback` routes that receive provider redirects and need to swap a\n * code/token for an app session via the backend.\n *\n * Runs `exchange` once per logical mount and keeps its result. StrictMode's\n * simulated unmount/remount in dev and a parent re-render with inline\n * callbacks used to cancel the only exchange and skip the second, leaving the\n * hook `\"pending\"` forever with the single-use code already spent. Now the\n * options live in a latest-value ref, the effect has no dependencies, and the\n * result is dropped only when the component is still unmounted when it lands.\n * The newest `onSuccess`/`onError` are the ones called.\n *\n * For a provider redirect, the exchange must carry the `state` along with the\n * `code`, or no backend can tell a forged callback from a real one (login\n * CSRF). `exchangeOAuthCallback` does that against a\n * `tempest-fastapi-sdk` backend; `readOAuthCallbackParams` returns both\n * values (or throws) for any other backend.\n *\n * @example\n * function OAuthCallback() {\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: ({ user_id, access_token }) => {\n * useAuthStore.getState().setSession({ user: { id: user_id }, token: access_token });\n * navigate(\"/dashboard\", { replace: true });\n * },\n * onError: () => navigate(\"/login?error=oauth\", { replace: true }),\n * });\n *\n * if (loading) return <Spinner />;\n * if (error) return <ErrorState description=\"OAuth falhou\" />;\n * return null;\n * }\n */\nexport function useOAuthCallback<T>(\n options: UseOAuthCallbackOptions<T>,\n): UseOAuthCallbackResult<T> {\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [status, setStatus] = useState<\"pending\" | \"success\" | \"error\">(\"pending\");\n const optionsRef = useRef<UseOAuthCallbackOptions<T>>(options);\n const ranRef = useRef<boolean>(false);\n const mountedRef = useRef<boolean>(false);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n mountedRef.current = true;\n if (!ranRef.current) {\n ranRef.current = true;\n optionsRef.current\n .exchange()\n .then((result) => {\n if (!mountedRef.current) return;\n setData(result);\n setStatus(\"success\");\n return optionsRef.current.onSuccess?.(result);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current) return;\n setError(err);\n setStatus(\"error\");\n optionsRef.current.onError?.(err);\n });\n }\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return { loading: status === \"pending\", data, error, status };\n}\n"],"mappings":"A,uBAyDA,SAAgBG,EACZ,EACyB,CACzB,GAAM,CAACC,EAAMC,IAAA,EAAWL,EAAAA,SAAAA,CAAmB,IAAI,EACzC,CAACM,EAAOC,IAAA,EAAYP,EAAAA,SAAAA,CAAkB,IAAI,EAC1C,CAACQ,EAAQC,IAAA,EAAaT,EAAAA,SAAAA,CAA0C,SAAS,EACzEU,GAAA,EAAaT,EAAAA,OAAAA,CAAmCU,CAAO,EACvDC,GAAA,EAASX,EAAAA,OAAAA,CAAgB,EAAK,EAC9BY,GAAA,EAAaZ,EAAAA,OAAAA,CAAgB,EAAK,EA8BxC,OA5BA,EAAAC,EAAA,UAAA,KAAgB,CACZ,EAAW,QAAUS,CACzB,CAAC,GAED,EAAAT,EAAA,UAAA,MACI,EAAW,QAAU,GAChBU,EAAO,UACR,EAAO,QAAU,GACjBF,EAAW,QACN,SAAS,CAAC,CACV,KAAM,GAAW,CACd,GAAKG,EAAW,QAGhB,OAFAR,EAAQS,CAAM,EACdL,EAAU,SAAS,EACZC,EAAW,QAAQ,YAAYI,CAAM,CAChD,CAAC,CAAC,CACD,MAAO,GAAiB,CAChBD,EAAW,UAChBN,EAASQ,CAAG,EACZN,EAAU,OAAO,EACjBC,EAAW,QAAQ,UAAUK,CAAG,EACpC,CAAC,OAEI,CACT,EAAW,QAAU,EACzB,GACD,CAAC,CAAC,EAEE,CAAE,QAASP,IAAW,UAAW,OAAM,QAAO,QAAO,CAChE,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-oauth-callback.js","names":[],"sources":["../../src/oauth/use-oauth-callback.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nexport interface UseOAuthCallbackOptions<T> {\n /** Function that exchanges the provider response for an app session. Called once on mount. */\n exchange: () => Promise<T>;\n /** Fired with the result on success. Receives the value resolved by `exchange`. */\n onSuccess?: (result: T) => void | Promise<void>;\n /** Fired when `exchange` throws or rejects. */\n onError?: (error: unknown) => void;\n}\n\nexport interface UseOAuthCallbackResult<T> {\n /** `true` while the exchange promise is pending. */\n loading: boolean;\n /** Last resolved value, when `status === \"success\"`. */\n data: T | null;\n /** Last rejection reason, when `status === \"error\"`. */\n error: unknown;\n /** Aggregated state — `\"pending\"`, `\"success\"`, or `\"error\"`. */\n status: \"pending\" | \"success\" | \"error\";\n}\n\n/**\n * Run an OAuth-callback \"exchange\" exactly once on mount. Designed for\n * `/callback` routes that receive provider redirects and need to swap a\n * code/token for an app session via the backend.\n *\n * Runs `exchange` once per logical mount and keeps its result. StrictMode's\n * simulated unmount/remount in dev and a parent re-render with inline\n * callbacks used to cancel the only exchange and skip the second, leaving the\n * hook `\"pending\"` forever with the single-use code already spent. Now the\n * options live in a latest-value ref, the effect has no dependencies, and the\n * result is dropped only when the component is still unmounted when it lands.\n * The newest `onSuccess`/`onError` are the ones called.\n *\n * For a provider redirect, the exchange must carry the `state` along with the\n * `code`, or no backend can tell a forged callback from a real one (login\n * CSRF). `exchangeOAuthCallback` does that against a\n * `tempest-fastapi-sdk` backend; `readOAuthCallbackParams` returns both\n * values (or throws) for any other backend.\n *\n * @example\n * function OAuthCallback() {\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: ({ user_id, access_token }) => {\n * useAuthStore.getState().setSession({ user: { id: user_id }, token: access_token });\n * navigate(\"/dashboard\", { replace: true });\n * },\n * onError: () => navigate(\"/login?error=oauth\", { replace: true }),\n * });\n *\n * if (loading) return <Spinner />;\n * if (error) return <ErrorState description=\"OAuth falhou\" />;\n * return null;\n * }\n */\nexport function useOAuthCallback<T>(\n options: UseOAuthCallbackOptions<T>,\n): UseOAuthCallbackResult<T> {\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [status, setStatus] = useState<\"pending\" | \"success\" | \"error\">(\"pending\");\n const optionsRef = useRef<UseOAuthCallbackOptions<T>>(options);\n const ranRef = useRef<boolean>(false);\n const mountedRef = useRef<boolean>(false);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n mountedRef.current = true;\n if (!ranRef.current) {\n ranRef.current = true;\n optionsRef.current\n .exchange()\n .then((result) => {\n if (!mountedRef.current) return;\n setData(result);\n setStatus(\"success\");\n return optionsRef.current.onSuccess?.(result);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current) return;\n setError(err);\n setStatus(\"error\");\n optionsRef.current.onError?.(err);\n });\n }\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return { loading: status === \"pending\", data, error, status };\n}\n"],"mappings":";;AAyDA,
|
|
1
|
+
{"version":3,"file":"use-oauth-callback.js","names":["useOAuthCallback","data","setData","useState","error","setError","status","setStatus","optionsRef","useRef","options","ranRef","mountedRef","useEffect","result","err"],"sources":["../../src/oauth/use-oauth-callback.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nexport interface UseOAuthCallbackOptions<T> {\n /** Function that exchanges the provider response for an app session. Called once on mount. */\n exchange: () => Promise<T>;\n /** Fired with the result on success. Receives the value resolved by `exchange`. */\n onSuccess?: (result: T) => void | Promise<void>;\n /** Fired when `exchange` throws or rejects. */\n onError?: (error: unknown) => void;\n}\n\nexport interface UseOAuthCallbackResult<T> {\n /** `true` while the exchange promise is pending. */\n loading: boolean;\n /** Last resolved value, when `status === \"success\"`. */\n data: T | null;\n /** Last rejection reason, when `status === \"error\"`. */\n error: unknown;\n /** Aggregated state — `\"pending\"`, `\"success\"`, or `\"error\"`. */\n status: \"pending\" | \"success\" | \"error\";\n}\n\n/**\n * Run an OAuth-callback \"exchange\" exactly once on mount. Designed for\n * `/callback` routes that receive provider redirects and need to swap a\n * code/token for an app session via the backend.\n *\n * Runs `exchange` once per logical mount and keeps its result. StrictMode's\n * simulated unmount/remount in dev and a parent re-render with inline\n * callbacks used to cancel the only exchange and skip the second, leaving the\n * hook `\"pending\"` forever with the single-use code already spent. Now the\n * options live in a latest-value ref, the effect has no dependencies, and the\n * result is dropped only when the component is still unmounted when it lands.\n * The newest `onSuccess`/`onError` are the ones called.\n *\n * For a provider redirect, the exchange must carry the `state` along with the\n * `code`, or no backend can tell a forged callback from a real one (login\n * CSRF). `exchangeOAuthCallback` does that against a\n * `tempest-fastapi-sdk` backend; `readOAuthCallbackParams` returns both\n * values (or throws) for any other backend.\n *\n * @example\n * function OAuthCallback() {\n * const { loading, error } = useOAuthCallback<LoginResponse>({\n * exchange: () => exchangeOAuthCallback<LoginResponse>(api, \"google\"),\n * onSuccess: ({ user_id, access_token }) => {\n * useAuthStore.getState().setSession({ user: { id: user_id }, token: access_token });\n * navigate(\"/dashboard\", { replace: true });\n * },\n * onError: () => navigate(\"/login?error=oauth\", { replace: true }),\n * });\n *\n * if (loading) return <Spinner />;\n * if (error) return <ErrorState description=\"OAuth falhou\" />;\n * return null;\n * }\n */\nexport function useOAuthCallback<T>(\n options: UseOAuthCallbackOptions<T>,\n): UseOAuthCallbackResult<T> {\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [status, setStatus] = useState<\"pending\" | \"success\" | \"error\">(\"pending\");\n const optionsRef = useRef<UseOAuthCallbackOptions<T>>(options);\n const ranRef = useRef<boolean>(false);\n const mountedRef = useRef<boolean>(false);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n mountedRef.current = true;\n if (!ranRef.current) {\n ranRef.current = true;\n optionsRef.current\n .exchange()\n .then((result) => {\n if (!mountedRef.current) return;\n setData(result);\n setStatus(\"success\");\n return optionsRef.current.onSuccess?.(result);\n })\n .catch((err: unknown) => {\n if (!mountedRef.current) return;\n setError(err);\n setStatus(\"error\");\n optionsRef.current.onError?.(err);\n });\n }\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n return { loading: status === \"pending\", data, error, status };\n}\n"],"mappings":";;AAyDA,SAAgBA,EACZ,GACyB;CACzB,IAAM,CAACC,GAAMC,KAAWC,EAAmB,IAAI,GACzC,CAACC,GAAOC,KAAYF,EAAkB,IAAI,GAC1C,CAACG,GAAQC,KAAaJ,EAA0C,SAAS,GACzEK,IAAaC,EAAmCC,CAAO,GACvDC,IAASF,EAAgB,EAAK,GAC9BG,IAAaH,EAAgB,EAAK;CA8BxC,OA5BAI,QAAgB;EACZ,EAAW,UAAUH;CACzB,CAAC,GAEDG,SACI,EAAW,UAAU,IAChBF,EAAO,YACR,EAAO,UAAU,IACjBH,EAAW,QACN,SAAS,CAAC,CACV,MAAM,MAAW;EACd,IAAKI,EAAW,SAGhB,OAFAV,EAAQY,CAAM,GACdP,EAAU,SAAS,GACZC,EAAW,QAAQ,YAAYM,CAAM;CAChD,CAAC,CAAC,CACD,OAAO,MAAiB;EACrB,AAAKF,EAAW,YAChBP,EAASU,CAAG,GACZR,EAAU,OAAO,GACjBC,EAAW,QAAQ,UAAUO,CAAG;CACpC,CAAC,UAEI;EACT,EAAW,UAAU;CACzB,IACD,CAAC,CAAC,GAEE;EAAE,SAAST,MAAW;EAAW;EAAM;EAAO;CAAO;AAChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict.cjs","names":[],"sources":["../../src/offline/conflict.ts"],"sourcesContent":["/**\n * Conflict-resolution helpers for the `applyRemote` callback of\n * {@link createOfflineSync}. Each takes the current local record (or\n * `undefined` when the record is new locally) and the incoming remote record,\n * and returns the winner. Ties resolve to the remote copy, treating the server\n * as authoritative.\n */\n\n/** Normalise a timestamp-ish value to epoch milliseconds. */\nfunction toMillis(value: number | string | Date): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === \"number\") return value;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\n/**\n * Resolve a conflict by keeping whichever record was written last, comparing a\n * timestamp field. The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getTimestamp - Reads the comparison timestamp (epoch ms, ISO string or `Date`).\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(lastWriteWins(local, dto, (r) => r.updatedAt));\n * }\n */\nexport function lastWriteWins<T>(\n local: T | undefined,\n remote: T,\n getTimestamp: (record: T) => number | string | Date,\n): T {\n if (local === undefined) return remote;\n return toMillis(getTimestamp(remote)) >= toMillis(getTimestamp(local)) ? remote : local;\n}\n\n/**\n * Resolve a conflict by keeping whichever record carries the higher version\n * number (monotonic counter / row version). The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getVersion - Reads the monotonic version number.\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(higherVersionWins(local, dto, (r) => r.version));\n * }\n */\nexport function higherVersionWins<T>(\n local: T | undefined,\n remote: T,\n getVersion: (record: T) => number,\n): T {\n if (local === undefined) return remote;\n return getVersion(remote) >= getVersion(local) ? remote : local;\n}\n"],"mappings":"AASA,
|
|
1
|
+
{"version":3,"file":"conflict.cjs","names":["toMillis","value","parsed","lastWriteWins","local","getTimestamp","remote","higherVersionWins","getVersion"],"sources":["../../src/offline/conflict.ts"],"sourcesContent":["/**\n * Conflict-resolution helpers for the `applyRemote` callback of\n * {@link createOfflineSync}. Each takes the current local record (or\n * `undefined` when the record is new locally) and the incoming remote record,\n * and returns the winner. Ties resolve to the remote copy, treating the server\n * as authoritative.\n */\n\n/** Normalise a timestamp-ish value to epoch milliseconds. */\nfunction toMillis(value: number | string | Date): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === \"number\") return value;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\n/**\n * Resolve a conflict by keeping whichever record was written last, comparing a\n * timestamp field. The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getTimestamp - Reads the comparison timestamp (epoch ms, ISO string or `Date`).\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(lastWriteWins(local, dto, (r) => r.updatedAt));\n * }\n */\nexport function lastWriteWins<T>(\n local: T | undefined,\n remote: T,\n getTimestamp: (record: T) => number | string | Date,\n): T {\n if (local === undefined) return remote;\n return toMillis(getTimestamp(remote)) >= toMillis(getTimestamp(local)) ? remote : local;\n}\n\n/**\n * Resolve a conflict by keeping whichever record carries the higher version\n * number (monotonic counter / row version). The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getVersion - Reads the monotonic version number.\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(higherVersionWins(local, dto, (r) => r.version));\n * }\n */\nexport function higherVersionWins<T>(\n local: T | undefined,\n remote: T,\n getVersion: (record: T) => number,\n): T {\n if (local === undefined) return remote;\n return getVersion(remote) >= getVersion(local) ? remote : local;\n}\n"],"mappings":"AASA,SAASA,EAAS,EAAuC,CACrD,GAAIC,aAAiB,KAAM,OAAOA,EAAM,QAAQ,EAChD,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAS,KAAK,MAAMD,CAAK,EAC/B,OAAO,OAAO,MAAMC,CAAM,EAAI,EAAIA,CACtC,CAkBA,SAAgBC,EACZ,EACA,EACA,EACC,CAED,OADIC,IAAU,IAAA,IACPJ,EAASK,EAAaC,CAAM,CAAC,GAAKN,EAASK,EAAaD,CAAK,CAAC,EADrCE,EACkDF,CACtF,CAkBA,SAAgBG,EACZ,EACA,EACA,EACC,CAED,OADIH,IAAU,IAAA,IACPI,EAAWF,CAAM,GAAKE,EAAWJ,CAAK,EADbE,EAC0BF,CAC9D,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict.js","names":[],"sources":["../../src/offline/conflict.ts"],"sourcesContent":["/**\n * Conflict-resolution helpers for the `applyRemote` callback of\n * {@link createOfflineSync}. Each takes the current local record (or\n * `undefined` when the record is new locally) and the incoming remote record,\n * and returns the winner. Ties resolve to the remote copy, treating the server\n * as authoritative.\n */\n\n/** Normalise a timestamp-ish value to epoch milliseconds. */\nfunction toMillis(value: number | string | Date): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === \"number\") return value;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\n/**\n * Resolve a conflict by keeping whichever record was written last, comparing a\n * timestamp field. The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getTimestamp - Reads the comparison timestamp (epoch ms, ISO string or `Date`).\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(lastWriteWins(local, dto, (r) => r.updatedAt));\n * }\n */\nexport function lastWriteWins<T>(\n local: T | undefined,\n remote: T,\n getTimestamp: (record: T) => number | string | Date,\n): T {\n if (local === undefined) return remote;\n return toMillis(getTimestamp(remote)) >= toMillis(getTimestamp(local)) ? remote : local;\n}\n\n/**\n * Resolve a conflict by keeping whichever record carries the higher version\n * number (monotonic counter / row version). The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getVersion - Reads the monotonic version number.\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(higherVersionWins(local, dto, (r) => r.version));\n * }\n */\nexport function higherVersionWins<T>(\n local: T | undefined,\n remote: T,\n getVersion: (record: T) => number,\n): T {\n if (local === undefined) return remote;\n return getVersion(remote) >= getVersion(local) ? remote : local;\n}\n"],"mappings":";AASA,
|
|
1
|
+
{"version":3,"file":"conflict.js","names":["toMillis","value","parsed","lastWriteWins","local","getTimestamp","remote","higherVersionWins","getVersion"],"sources":["../../src/offline/conflict.ts"],"sourcesContent":["/**\n * Conflict-resolution helpers for the `applyRemote` callback of\n * {@link createOfflineSync}. Each takes the current local record (or\n * `undefined` when the record is new locally) and the incoming remote record,\n * and returns the winner. Ties resolve to the remote copy, treating the server\n * as authoritative.\n */\n\n/** Normalise a timestamp-ish value to epoch milliseconds. */\nfunction toMillis(value: number | string | Date): number {\n if (value instanceof Date) return value.getTime();\n if (typeof value === \"number\") return value;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\n/**\n * Resolve a conflict by keeping whichever record was written last, comparing a\n * timestamp field. The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getTimestamp - Reads the comparison timestamp (epoch ms, ISO string or `Date`).\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(lastWriteWins(local, dto, (r) => r.updatedAt));\n * }\n */\nexport function lastWriteWins<T>(\n local: T | undefined,\n remote: T,\n getTimestamp: (record: T) => number | string | Date,\n): T {\n if (local === undefined) return remote;\n return toMillis(getTimestamp(remote)) >= toMillis(getTimestamp(local)) ? remote : local;\n}\n\n/**\n * Resolve a conflict by keeping whichever record carries the higher version\n * number (monotonic counter / row version). The remote record wins ties.\n *\n * @typeParam T - The record shape.\n * @param local - The current local record, or `undefined` when new.\n * @param remote - The incoming remote record.\n * @param getVersion - Reads the monotonic version number.\n * @returns The winning record.\n *\n * @example\n * applyRemote: async (dto) => {\n * const local = await store.get(dto.id);\n * await store.save(higherVersionWins(local, dto, (r) => r.version));\n * }\n */\nexport function higherVersionWins<T>(\n local: T | undefined,\n remote: T,\n getVersion: (record: T) => number,\n): T {\n if (local === undefined) return remote;\n return getVersion(remote) >= getVersion(local) ? remote : local;\n}\n"],"mappings":";AASA,SAASA,EAAS,GAAuC;CACrD,IAAIC,aAAiB,MAAM,OAAOA,EAAM,QAAQ;CAChD,IAAI,OAAOA,KAAU,UAAU,OAAOA;CACtC,IAAMC,IAAS,KAAK,MAAMD,CAAK;CAC/B,OAAO,OAAO,MAAMC,CAAM,IAAI,IAAIA;AACtC;AAkBA,SAAgBC,EACZ,GACA,GACA,GACC;CAED,OADIC,MAAU,KAAA,KACPJ,EAASK,EAAaC,CAAM,CAAC,KAAKN,EAASK,EAAaD,CAAK,CAAC,IADrCE,IACkDF;AACtF;AAkBA,SAAgBG,EACZ,GACA,GACA,GACC;CAED,OADIH,MAAU,KAAA,KACPI,EAAWF,CAAM,KAAKE,EAAWJ,CAAK,IADbE,IAC0BF;AAC9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-offline-database.cjs","names":[],"sources":["../../src/offline/create-offline-database.ts"],"sourcesContent":["import Dexie, { type Table } from \"dexie\";\n\nimport { buildStore, type OfflineStore, type OfflineStoreConfig } from \"./create-offline-store\";\n\nexport interface OfflineTableConfig<TItem> {\n /**\n * Dexie index definition for this table. Use `&` for a unique primary key,\n * e.g. `\"&id, service_id, created_at\"`.\n */\n indexes: string;\n /** Property used as the primary key (default: `\"id\"`). */\n keyPath?: keyof TItem & string;\n /**\n * Optional owner scoping for this table. Set per table, since one database\n * commonly mixes scoped and unscoped data.\n */\n ownerField?: keyof TItem & string;\n}\n\n/** Maps each table name to the record type it stores. */\nexport type OfflineSchema = Record<string, unknown>;\n\nexport type OfflineTablesConfig<TSchema extends OfflineSchema> = {\n [K in keyof TSchema]: OfflineTableConfig<TSchema[K]>;\n};\n\nexport interface OfflineDatabaseConfig<TSchema extends OfflineSchema> {\n /** IndexedDB database name. */\n databaseName: string;\n /** Schema version. Bump when changing any table's indexes. */\n version: number;\n /** One entry per object store, all inside this single database. */\n tables: OfflineTablesConfig<TSchema>;\n}\n\nexport interface OfflineDatabase<TSchema extends OfflineSchema> {\n /**\n * The {@link OfflineStore} for one table.\n *\n * The name is checked against the declared schema; the record type is\n * supplied by the caller — `store<Chat>(\"chats\")`. Deriving it from the\n * schema instead (`OfflineStore<TSchema[K], string>`) is what the shape\n * below documents as unavailable: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, and an unresolved indexed access there makes the\n * checker answer TS2589 no matter how the value is cast.\n *\n * Stores are created once and memoised, so repeated calls with the same\n * name return the same object.\n */\n store: <TItem>(name: keyof TSchema & string) => OfflineStore<TItem, string>;\n /** The Dexie instance shared by every store. */\n db: Dexie;\n /** Delete the whole database from the browser. */\n destroy: () => Promise<void>;\n}\n\nclass MultiTableDb extends Dexie {\n constructor(name: string, version: number, stores: Record<string, string>) {\n super(name);\n this.version(version).stores(stores);\n }\n}\n\n/**\n * Build several {@link OfflineStore}s that share one IndexedDB database.\n *\n * `createOfflineStore` gives each store a database of its own, which is the\n * right shape for one isolated cache. It is the wrong shape as soon as the\n * tables belong together: chats and their messages, an entity and its drafts,\n * anything you would read or clear as a unit. Splitting those across databases\n * costs a real transaction — Dexie runs one atomically only *within* a single\n * database — and it splits the version bump for a related change across two\n * places.\n *\n * This keeps them in one database at one version, so a schema change is one\n * bump and a multi-table write can be wrapped in `db.transaction(...)`.\n *\n * Stores are reached through `store<TItem>(name)` rather than a prebuilt map.\n * That is forced rather than chosen: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, so building `{ [K in keyof TSchema]: OfflineStore<…> }`\n * — or even naming `OfflineStore<TSchema[K], string>` inside the accessor —\n * makes the checker answer TS2589 (\"excessively deep\"). Taking the record type\n * as a parameter keeps it a plain type argument, which resolves fine. The table\n * name is still checked against the declared schema.\n *\n * The store surface is identical to `createOfflineStore`; only ownership of the\n * database changes. `ownerField` is set per table, since a database commonly\n * mixes per-user data with shared data.\n *\n * @param config - Database name, version, and one entry per table.\n * @returns A `store(name)` accessor, the shared Dexie instance, and a\n * `destroy()` that drops the database.\n *\n * @example\n * type Chat = { id: string; service_id: string; updated_at: string };\n * type Message = { id: string; service_chat_id: string; created_at: string };\n *\n * const database = createOfflineDatabase<{ chats: Chat; messages: Message }>({\n * databaseName: \"ChatDatabase\",\n * version: 1,\n * tables: {\n * chats: { indexes: \"&id, service_id, updated_at\" },\n * messages: { indexes: \"&id, service_chat_id, created_at\" },\n * },\n * });\n *\n * const chats = database.store<Chat>(\"chats\");\n * const messages = database.store<Message>(\"messages\");\n *\n * // Both tables in one atomic transaction — impossible across two databases.\n * await database.db.transaction(\"rw\", chats.raw, messages.raw, async () => {\n * await chats.put(chat);\n * await messages.bulkPut(pending);\n * });\n */\nexport function createOfflineDatabase<TSchema extends OfflineSchema>(\n config: OfflineDatabaseConfig<TSchema>,\n): OfflineDatabase<TSchema> {\n const { databaseName, version, tables } = config;\n\n const schema: Record<string, string> = {};\n for (const name of Object.keys(tables)) {\n schema[name] = tables[name as keyof TSchema].indexes;\n }\n\n const db = new MultiTableDb(databaseName, version, schema);\n const built = new Map<string, unknown>();\n\n function store<TItem>(name: keyof TSchema & string): OfflineStore<TItem, string> {\n const cached = built.get(name);\n if (cached) return cached as OfflineStore<TItem, string>;\n\n if (!(name in tables)) {\n throw new Error(\n `Table \"${name}\" is not declared in ${databaseName}. ` +\n `Available: ${Object.keys(tables).join(\", \")}.`,\n );\n }\n\n const table = db.table(name) as Table<TItem>;\n const tableConfig = tables[name] as Pick<\n OfflineStoreConfig<TItem>,\n \"keyPath\" | \"ownerField\"\n >;\n // Dexie's `Table<T>` drags in `UpdateSpec<T>`, which maps over the keys\n // of `T`. Instantiating that from inside a second generic function is\n // past what the checker will unfold, and it answers TS2589\n // (\"excessively deep\") — for every shape tried: `unknown`, `object`,\n // `Record<string, unknown>`, a closed interface, an explicit type\n // argument, and a cast through `never`. `createOfflineStore` calls this\n // same `buildStore` without complaint, so it is the nesting, not the\n // store.\n //\n // Suppressed rather than worked around: the emitted types and the\n // runtime are both correct — `create-offline-database.test.ts` covers\n // the full surface, cross-table transactions included.\n // `@ts-expect-error` over `@ts-ignore` on purpose: if a later\n // TypeScript raises the limit, this line starts failing and says so.\n // @ts-expect-error TS2589 — see above\n const created: OfflineStore<TItem> = buildStore<TItem>(db, table, tableConfig);\n built.set(name, created);\n return created;\n }\n\n return {\n store,\n db,\n destroy: () => db.delete(),\n };\n}\n"],"mappings":"qIAwDA,
|
|
1
|
+
{"version":3,"file":"create-offline-database.cjs","names":["Dexie","buildStore","require_runtime","require_create_offline_store","dexie","MultiTableDb","name","version","stores","createOfflineDatabase","config","schema","tables","db","databaseName","built","store","cached","table","tableConfig","created"],"sources":["../../src/offline/create-offline-database.ts"],"sourcesContent":["import Dexie, { type Table } from \"dexie\";\n\nimport { buildStore, type OfflineStore, type OfflineStoreConfig } from \"./create-offline-store\";\n\nexport interface OfflineTableConfig<TItem> {\n /**\n * Dexie index definition for this table. Use `&` for a unique primary key,\n * e.g. `\"&id, service_id, created_at\"`.\n */\n indexes: string;\n /** Property used as the primary key (default: `\"id\"`). */\n keyPath?: keyof TItem & string;\n /**\n * Optional owner scoping for this table. Set per table, since one database\n * commonly mixes scoped and unscoped data.\n */\n ownerField?: keyof TItem & string;\n}\n\n/** Maps each table name to the record type it stores. */\nexport type OfflineSchema = Record<string, unknown>;\n\nexport type OfflineTablesConfig<TSchema extends OfflineSchema> = {\n [K in keyof TSchema]: OfflineTableConfig<TSchema[K]>;\n};\n\nexport interface OfflineDatabaseConfig<TSchema extends OfflineSchema> {\n /** IndexedDB database name. */\n databaseName: string;\n /** Schema version. Bump when changing any table's indexes. */\n version: number;\n /** One entry per object store, all inside this single database. */\n tables: OfflineTablesConfig<TSchema>;\n}\n\nexport interface OfflineDatabase<TSchema extends OfflineSchema> {\n /**\n * The {@link OfflineStore} for one table.\n *\n * The name is checked against the declared schema; the record type is\n * supplied by the caller — `store<Chat>(\"chats\")`. Deriving it from the\n * schema instead (`OfflineStore<TSchema[K], string>`) is what the shape\n * below documents as unavailable: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, and an unresolved indexed access there makes the\n * checker answer TS2589 no matter how the value is cast.\n *\n * Stores are created once and memoised, so repeated calls with the same\n * name return the same object.\n */\n store: <TItem>(name: keyof TSchema & string) => OfflineStore<TItem, string>;\n /** The Dexie instance shared by every store. */\n db: Dexie;\n /** Delete the whole database from the browser. */\n destroy: () => Promise<void>;\n}\n\nclass MultiTableDb extends Dexie {\n constructor(name: string, version: number, stores: Record<string, string>) {\n super(name);\n this.version(version).stores(stores);\n }\n}\n\n/**\n * Build several {@link OfflineStore}s that share one IndexedDB database.\n *\n * `createOfflineStore` gives each store a database of its own, which is the\n * right shape for one isolated cache. It is the wrong shape as soon as the\n * tables belong together: chats and their messages, an entity and its drafts,\n * anything you would read or clear as a unit. Splitting those across databases\n * costs a real transaction — Dexie runs one atomically only *within* a single\n * database — and it splits the version bump for a related change across two\n * places.\n *\n * This keeps them in one database at one version, so a schema change is one\n * bump and a multi-table write can be wrapped in `db.transaction(...)`.\n *\n * Stores are reached through `store<TItem>(name)` rather than a prebuilt map.\n * That is forced rather than chosen: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, so building `{ [K in keyof TSchema]: OfflineStore<…> }`\n * — or even naming `OfflineStore<TSchema[K], string>` inside the accessor —\n * makes the checker answer TS2589 (\"excessively deep\"). Taking the record type\n * as a parameter keeps it a plain type argument, which resolves fine. The table\n * name is still checked against the declared schema.\n *\n * The store surface is identical to `createOfflineStore`; only ownership of the\n * database changes. `ownerField` is set per table, since a database commonly\n * mixes per-user data with shared data.\n *\n * @param config - Database name, version, and one entry per table.\n * @returns A `store(name)` accessor, the shared Dexie instance, and a\n * `destroy()` that drops the database.\n *\n * @example\n * type Chat = { id: string; service_id: string; updated_at: string };\n * type Message = { id: string; service_chat_id: string; created_at: string };\n *\n * const database = createOfflineDatabase<{ chats: Chat; messages: Message }>({\n * databaseName: \"ChatDatabase\",\n * version: 1,\n * tables: {\n * chats: { indexes: \"&id, service_id, updated_at\" },\n * messages: { indexes: \"&id, service_chat_id, created_at\" },\n * },\n * });\n *\n * const chats = database.store<Chat>(\"chats\");\n * const messages = database.store<Message>(\"messages\");\n *\n * // Both tables in one atomic transaction — impossible across two databases.\n * await database.db.transaction(\"rw\", chats.raw, messages.raw, async () => {\n * await chats.put(chat);\n * await messages.bulkPut(pending);\n * });\n */\nexport function createOfflineDatabase<TSchema extends OfflineSchema>(\n config: OfflineDatabaseConfig<TSchema>,\n): OfflineDatabase<TSchema> {\n const { databaseName, version, tables } = config;\n\n const schema: Record<string, string> = {};\n for (const name of Object.keys(tables)) {\n schema[name] = tables[name as keyof TSchema].indexes;\n }\n\n const db = new MultiTableDb(databaseName, version, schema);\n const built = new Map<string, unknown>();\n\n function store<TItem>(name: keyof TSchema & string): OfflineStore<TItem, string> {\n const cached = built.get(name);\n if (cached) return cached as OfflineStore<TItem, string>;\n\n if (!(name in tables)) {\n throw new Error(\n `Table \"${name}\" is not declared in ${databaseName}. ` +\n `Available: ${Object.keys(tables).join(\", \")}.`,\n );\n }\n\n const table = db.table(name) as Table<TItem>;\n const tableConfig = tables[name] as Pick<\n OfflineStoreConfig<TItem>,\n \"keyPath\" | \"ownerField\"\n >;\n // Dexie's `Table<T>` drags in `UpdateSpec<T>`, which maps over the keys\n // of `T`. Instantiating that from inside a second generic function is\n // past what the checker will unfold, and it answers TS2589\n // (\"excessively deep\") — for every shape tried: `unknown`, `object`,\n // `Record<string, unknown>`, a closed interface, an explicit type\n // argument, and a cast through `never`. `createOfflineStore` calls this\n // same `buildStore` without complaint, so it is the nesting, not the\n // store.\n //\n // Suppressed rather than worked around: the emitted types and the\n // runtime are both correct — `create-offline-database.test.ts` covers\n // the full surface, cross-table transactions included.\n // `@ts-expect-error` over `@ts-ignore` on purpose: if a later\n // TypeScript raises the limit, this line starts failing and says so.\n // @ts-expect-error TS2589 — see above\n const created: OfflineStore<TItem> = buildStore<TItem>(db, table, tableConfig);\n built.set(name, created);\n return created;\n }\n\n return {\n store,\n db,\n destroy: () => db.delete(),\n };\n}\n"],"mappings":"A,qIAwDA,IAAMK,EAAN,cAA2BL,EAAAA,OAAM,CAC7B,YAAY,EAAc,EAAiB,EAAgC,CACvE,MAAMM,CAAI,EACV,KAAK,QAAQC,CAAO,CAAC,CAAC,OAAOC,CAAM,CACvC,CACJ,EAsDA,SAAgBC,EACZ,EACwB,CACxB,GAAM,CAAE,eAAc,UAAS,UAAWC,EAEpCC,EAAiC,CAAC,EACxC,IAAK,IAAML,KAAQ,OAAO,KAAKM,CAAM,EACjC,EAAON,GAAQM,EAAON,EAAsB,CAAC,QAGjD,IAAMO,EAAK,IAAIR,EAAaS,EAAcP,EAASI,CAAM,EACnDI,EAAQ,IAAI,IAElB,SAASC,EAAa,EAA2D,CAC7E,IAAMC,EAASF,EAAM,IAAIT,CAAI,EAC7B,GAAIW,EAAQ,OAAOA,EAEnB,GAAI,EAAEX,KAAQM,GACV,MAAU,MACN,UAAUN,EAAK,uBAAuBQ,EAAa,eACjC,OAAO,KAAKF,CAAM,CAAC,CAAC,KAAK,IAAI,EAAE,EACrD,EAGJ,IAAMM,EAAQL,EAAG,MAAMP,CAAI,EACrBa,EAAcP,EAAON,GAmBrBc,EAA+BnB,EAAAA,WAAkBY,EAAIK,EAAOC,CAAW,EAE7E,OADAJ,EAAM,IAAIT,EAAMc,CAAO,EAChBA,CACX,CAEA,MAAO,CACH,QACA,KACA,YAAeP,EAAG,OAAO,CAC7B,CACJ,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-offline-database.js","names":[],"sources":["../../src/offline/create-offline-database.ts"],"sourcesContent":["import Dexie, { type Table } from \"dexie\";\n\nimport { buildStore, type OfflineStore, type OfflineStoreConfig } from \"./create-offline-store\";\n\nexport interface OfflineTableConfig<TItem> {\n /**\n * Dexie index definition for this table. Use `&` for a unique primary key,\n * e.g. `\"&id, service_id, created_at\"`.\n */\n indexes: string;\n /** Property used as the primary key (default: `\"id\"`). */\n keyPath?: keyof TItem & string;\n /**\n * Optional owner scoping for this table. Set per table, since one database\n * commonly mixes scoped and unscoped data.\n */\n ownerField?: keyof TItem & string;\n}\n\n/** Maps each table name to the record type it stores. */\nexport type OfflineSchema = Record<string, unknown>;\n\nexport type OfflineTablesConfig<TSchema extends OfflineSchema> = {\n [K in keyof TSchema]: OfflineTableConfig<TSchema[K]>;\n};\n\nexport interface OfflineDatabaseConfig<TSchema extends OfflineSchema> {\n /** IndexedDB database name. */\n databaseName: string;\n /** Schema version. Bump when changing any table's indexes. */\n version: number;\n /** One entry per object store, all inside this single database. */\n tables: OfflineTablesConfig<TSchema>;\n}\n\nexport interface OfflineDatabase<TSchema extends OfflineSchema> {\n /**\n * The {@link OfflineStore} for one table.\n *\n * The name is checked against the declared schema; the record type is\n * supplied by the caller — `store<Chat>(\"chats\")`. Deriving it from the\n * schema instead (`OfflineStore<TSchema[K], string>`) is what the shape\n * below documents as unavailable: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, and an unresolved indexed access there makes the\n * checker answer TS2589 no matter how the value is cast.\n *\n * Stores are created once and memoised, so repeated calls with the same\n * name return the same object.\n */\n store: <TItem>(name: keyof TSchema & string) => OfflineStore<TItem, string>;\n /** The Dexie instance shared by every store. */\n db: Dexie;\n /** Delete the whole database from the browser. */\n destroy: () => Promise<void>;\n}\n\nclass MultiTableDb extends Dexie {\n constructor(name: string, version: number, stores: Record<string, string>) {\n super(name);\n this.version(version).stores(stores);\n }\n}\n\n/**\n * Build several {@link OfflineStore}s that share one IndexedDB database.\n *\n * `createOfflineStore` gives each store a database of its own, which is the\n * right shape for one isolated cache. It is the wrong shape as soon as the\n * tables belong together: chats and their messages, an entity and its drafts,\n * anything you would read or clear as a unit. Splitting those across databases\n * costs a real transaction — Dexie runs one atomically only *within* a single\n * database — and it splits the version bump for a related change across two\n * places.\n *\n * This keeps them in one database at one version, so a schema change is one\n * bump and a multi-table write can be wrapped in `db.transaction(...)`.\n *\n * Stores are reached through `store<TItem>(name)` rather than a prebuilt map.\n * That is forced rather than chosen: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, so building `{ [K in keyof TSchema]: OfflineStore<…> }`\n * — or even naming `OfflineStore<TSchema[K], string>` inside the accessor —\n * makes the checker answer TS2589 (\"excessively deep\"). Taking the record type\n * as a parameter keeps it a plain type argument, which resolves fine. The table\n * name is still checked against the declared schema.\n *\n * The store surface is identical to `createOfflineStore`; only ownership of the\n * database changes. `ownerField` is set per table, since a database commonly\n * mixes per-user data with shared data.\n *\n * @param config - Database name, version, and one entry per table.\n * @returns A `store(name)` accessor, the shared Dexie instance, and a\n * `destroy()` that drops the database.\n *\n * @example\n * type Chat = { id: string; service_id: string; updated_at: string };\n * type Message = { id: string; service_chat_id: string; created_at: string };\n *\n * const database = createOfflineDatabase<{ chats: Chat; messages: Message }>({\n * databaseName: \"ChatDatabase\",\n * version: 1,\n * tables: {\n * chats: { indexes: \"&id, service_id, updated_at\" },\n * messages: { indexes: \"&id, service_chat_id, created_at\" },\n * },\n * });\n *\n * const chats = database.store<Chat>(\"chats\");\n * const messages = database.store<Message>(\"messages\");\n *\n * // Both tables in one atomic transaction — impossible across two databases.\n * await database.db.transaction(\"rw\", chats.raw, messages.raw, async () => {\n * await chats.put(chat);\n * await messages.bulkPut(pending);\n * });\n */\nexport function createOfflineDatabase<TSchema extends OfflineSchema>(\n config: OfflineDatabaseConfig<TSchema>,\n): OfflineDatabase<TSchema> {\n const { databaseName, version, tables } = config;\n\n const schema: Record<string, string> = {};\n for (const name of Object.keys(tables)) {\n schema[name] = tables[name as keyof TSchema].indexes;\n }\n\n const db = new MultiTableDb(databaseName, version, schema);\n const built = new Map<string, unknown>();\n\n function store<TItem>(name: keyof TSchema & string): OfflineStore<TItem, string> {\n const cached = built.get(name);\n if (cached) return cached as OfflineStore<TItem, string>;\n\n if (!(name in tables)) {\n throw new Error(\n `Table \"${name}\" is not declared in ${databaseName}. ` +\n `Available: ${Object.keys(tables).join(\", \")}.`,\n );\n }\n\n const table = db.table(name) as Table<TItem>;\n const tableConfig = tables[name] as Pick<\n OfflineStoreConfig<TItem>,\n \"keyPath\" | \"ownerField\"\n >;\n // Dexie's `Table<T>` drags in `UpdateSpec<T>`, which maps over the keys\n // of `T`. Instantiating that from inside a second generic function is\n // past what the checker will unfold, and it answers TS2589\n // (\"excessively deep\") — for every shape tried: `unknown`, `object`,\n // `Record<string, unknown>`, a closed interface, an explicit type\n // argument, and a cast through `never`. `createOfflineStore` calls this\n // same `buildStore` without complaint, so it is the nesting, not the\n // store.\n //\n // Suppressed rather than worked around: the emitted types and the\n // runtime are both correct — `create-offline-database.test.ts` covers\n // the full surface, cross-table transactions included.\n // `@ts-expect-error` over `@ts-ignore` on purpose: if a later\n // TypeScript raises the limit, this line starts failing and says so.\n // @ts-expect-error TS2589 — see above\n const created: OfflineStore<TItem> = buildStore<TItem>(db, table, tableConfig);\n built.set(name, created);\n return created;\n }\n\n return {\n store,\n db,\n destroy: () => db.delete(),\n };\n}\n"],"mappings":";;;AAwDA,
|
|
1
|
+
{"version":3,"file":"create-offline-database.js","names":["Dexie","MultiTableDb","name","version","stores","createOfflineDatabase","config","schema","tables","db","databaseName","built","store","cached","table","tableConfig","created","buildStore"],"sources":["../../src/offline/create-offline-database.ts"],"sourcesContent":["import Dexie, { type Table } from \"dexie\";\n\nimport { buildStore, type OfflineStore, type OfflineStoreConfig } from \"./create-offline-store\";\n\nexport interface OfflineTableConfig<TItem> {\n /**\n * Dexie index definition for this table. Use `&` for a unique primary key,\n * e.g. `\"&id, service_id, created_at\"`.\n */\n indexes: string;\n /** Property used as the primary key (default: `\"id\"`). */\n keyPath?: keyof TItem & string;\n /**\n * Optional owner scoping for this table. Set per table, since one database\n * commonly mixes scoped and unscoped data.\n */\n ownerField?: keyof TItem & string;\n}\n\n/** Maps each table name to the record type it stores. */\nexport type OfflineSchema = Record<string, unknown>;\n\nexport type OfflineTablesConfig<TSchema extends OfflineSchema> = {\n [K in keyof TSchema]: OfflineTableConfig<TSchema[K]>;\n};\n\nexport interface OfflineDatabaseConfig<TSchema extends OfflineSchema> {\n /** IndexedDB database name. */\n databaseName: string;\n /** Schema version. Bump when changing any table's indexes. */\n version: number;\n /** One entry per object store, all inside this single database. */\n tables: OfflineTablesConfig<TSchema>;\n}\n\nexport interface OfflineDatabase<TSchema extends OfflineSchema> {\n /**\n * The {@link OfflineStore} for one table.\n *\n * The name is checked against the declared schema; the record type is\n * supplied by the caller — `store<Chat>(\"chats\")`. Deriving it from the\n * schema instead (`OfflineStore<TSchema[K], string>`) is what the shape\n * below documents as unavailable: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, and an unresolved indexed access there makes the\n * checker answer TS2589 no matter how the value is cast.\n *\n * Stores are created once and memoised, so repeated calls with the same\n * name return the same object.\n */\n store: <TItem>(name: keyof TSchema & string) => OfflineStore<TItem, string>;\n /** The Dexie instance shared by every store. */\n db: Dexie;\n /** Delete the whole database from the browser. */\n destroy: () => Promise<void>;\n}\n\nclass MultiTableDb extends Dexie {\n constructor(name: string, version: number, stores: Record<string, string>) {\n super(name);\n this.version(version).stores(stores);\n }\n}\n\n/**\n * Build several {@link OfflineStore}s that share one IndexedDB database.\n *\n * `createOfflineStore` gives each store a database of its own, which is the\n * right shape for one isolated cache. It is the wrong shape as soon as the\n * tables belong together: chats and their messages, an entity and its drafts,\n * anything you would read or clear as a unit. Splitting those across databases\n * costs a real transaction — Dexie runs one atomically only *within* a single\n * database — and it splits the version bump for a related change across two\n * places.\n *\n * This keeps them in one database at one version, so a schema change is one\n * bump and a multi-table write can be wrapped in `db.transaction(...)`.\n *\n * Stores are reached through `store<TItem>(name)` rather than a prebuilt map.\n * That is forced rather than chosen: Dexie's `Table<T>` expands `UpdateSpec<T>`\n * over the keys of `T`, so building `{ [K in keyof TSchema]: OfflineStore<…> }`\n * — or even naming `OfflineStore<TSchema[K], string>` inside the accessor —\n * makes the checker answer TS2589 (\"excessively deep\"). Taking the record type\n * as a parameter keeps it a plain type argument, which resolves fine. The table\n * name is still checked against the declared schema.\n *\n * The store surface is identical to `createOfflineStore`; only ownership of the\n * database changes. `ownerField` is set per table, since a database commonly\n * mixes per-user data with shared data.\n *\n * @param config - Database name, version, and one entry per table.\n * @returns A `store(name)` accessor, the shared Dexie instance, and a\n * `destroy()` that drops the database.\n *\n * @example\n * type Chat = { id: string; service_id: string; updated_at: string };\n * type Message = { id: string; service_chat_id: string; created_at: string };\n *\n * const database = createOfflineDatabase<{ chats: Chat; messages: Message }>({\n * databaseName: \"ChatDatabase\",\n * version: 1,\n * tables: {\n * chats: { indexes: \"&id, service_id, updated_at\" },\n * messages: { indexes: \"&id, service_chat_id, created_at\" },\n * },\n * });\n *\n * const chats = database.store<Chat>(\"chats\");\n * const messages = database.store<Message>(\"messages\");\n *\n * // Both tables in one atomic transaction — impossible across two databases.\n * await database.db.transaction(\"rw\", chats.raw, messages.raw, async () => {\n * await chats.put(chat);\n * await messages.bulkPut(pending);\n * });\n */\nexport function createOfflineDatabase<TSchema extends OfflineSchema>(\n config: OfflineDatabaseConfig<TSchema>,\n): OfflineDatabase<TSchema> {\n const { databaseName, version, tables } = config;\n\n const schema: Record<string, string> = {};\n for (const name of Object.keys(tables)) {\n schema[name] = tables[name as keyof TSchema].indexes;\n }\n\n const db = new MultiTableDb(databaseName, version, schema);\n const built = new Map<string, unknown>();\n\n function store<TItem>(name: keyof TSchema & string): OfflineStore<TItem, string> {\n const cached = built.get(name);\n if (cached) return cached as OfflineStore<TItem, string>;\n\n if (!(name in tables)) {\n throw new Error(\n `Table \"${name}\" is not declared in ${databaseName}. ` +\n `Available: ${Object.keys(tables).join(\", \")}.`,\n );\n }\n\n const table = db.table(name) as Table<TItem>;\n const tableConfig = tables[name] as Pick<\n OfflineStoreConfig<TItem>,\n \"keyPath\" | \"ownerField\"\n >;\n // Dexie's `Table<T>` drags in `UpdateSpec<T>`, which maps over the keys\n // of `T`. Instantiating that from inside a second generic function is\n // past what the checker will unfold, and it answers TS2589\n // (\"excessively deep\") — for every shape tried: `unknown`, `object`,\n // `Record<string, unknown>`, a closed interface, an explicit type\n // argument, and a cast through `never`. `createOfflineStore` calls this\n // same `buildStore` without complaint, so it is the nesting, not the\n // store.\n //\n // Suppressed rather than worked around: the emitted types and the\n // runtime are both correct — `create-offline-database.test.ts` covers\n // the full surface, cross-table transactions included.\n // `@ts-expect-error` over `@ts-ignore` on purpose: if a later\n // TypeScript raises the limit, this line starts failing and says so.\n // @ts-expect-error TS2589 — see above\n const created: OfflineStore<TItem> = buildStore<TItem>(db, table, tableConfig);\n built.set(name, created);\n return created;\n }\n\n return {\n store,\n db,\n destroy: () => db.delete(),\n };\n}\n"],"mappings":";;;AAwDA,IAAMC,IAAN,cAA2BD,EAAM;CAC7B,YAAY,GAAc,GAAiB,GAAgC;EAEvE,AADA,MAAME,CAAI,GACV,KAAK,QAAQC,CAAO,CAAC,CAAC,OAAOC,CAAM;CACvC;AACJ;AAsDA,SAAgBC,EACZ,GACwB;CACxB,IAAM,EAAE,iBAAc,YAAS,cAAWC,GAEpCC,IAAiC,CAAC;CACxC,KAAK,IAAML,KAAQ,OAAO,KAAKM,CAAM,GACjC,EAAON,KAAQM,EAAON,EAAsB,CAAC;CAGjD,IAAMO,IAAK,IAAIR,EAAaS,GAAcP,GAASI,CAAM,GACnDI,oBAAQ,IAAI,IAAqB;CAEvC,SAASC,EAAa,GAA2D;EAC7E,IAAMC,IAASF,EAAM,IAAIT,CAAI;EAC7B,IAAIW,GAAQ,OAAOA;EAEnB,IAAI,EAAEX,KAAQM,IACV,MAAU,MACN,UAAUN,EAAK,uBAAuBQ,EAAa,eACjC,OAAO,KAAKF,CAAM,CAAC,CAAC,KAAK,IAAI,EAAE,EACrD;EAGJ,IAAMM,IAAQL,EAAG,MAAMP,CAAI,GACrBa,IAAcP,EAAON,IAmBrBc,IAA+BC,EAAkBR,GAAIK,GAAOC,CAAW;EAE7E,OADAJ,EAAM,IAAIT,GAAMc,CAAO,GAChBA;CACX;CAEA,OAAO;EACH;EACA;EACA,eAAeP,EAAG,OAAO;CAC7B;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs");let t=require("dexie");t=e.__toESM(t,1);var n=class extends t.default{store;constructor(e,t,n,r){super(e),this.version(t).stores({[n]:r}),this.store=this.table(n)}};function r(e){let{databaseName:t,version:r,tableName:a,indexes:o}=e,s=new n(t,r,a,o);return i(s,s.store,e)}function i(e,t,n){let{keyPath:r=`id`,ownerField:i}=n;function a(e,t){return!i||!t?e:{...e,[i]:t}}async function o(e,n={}){let{orderBy:a=r,reverse:o=!1,limit:s,offset:c,filter:l}=n,u=i&&e?t.where(i).equals(e):t.toCollection();l&&(u=u.filter(l));let d=a===r?await u.toArray():await u.sortBy(a);return o&&(d=d.reverse()),c&&(d=d.slice(c)),typeof s==`number`&&(d=d.slice(0,s)),d}return{put:(e,n)=>t.put(a(e,n)),bulkPut:(e,n)=>t.bulkPut(e.map(e=>a(e,n))),get:e=>t.get(e),list:o,update:(e,n)=>t.update(e,n),updateMany:async(e,n)=>{let r=n;return i&&e?t.where(i).equals(e).modify(r):t.toCollection().modify(r)},delete:e=>t.delete(e),clear:async e=>{
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs");let t=require("dexie");t=e.__toESM(t,1);var n=class extends t.default{store;constructor(e,t,n,r){super(e),this.version(t).stores({[n]:r}),this.store=this.table(n)}};function r(e){let{databaseName:t,version:r,tableName:a,indexes:o}=e,s=new n(t,r,a,o);return i(s,s.store,e)}function i(e,t,n){let{keyPath:r=`id`,ownerField:i}=n;function a(e,t){return!i||!t?e:{...e,[i]:t}}async function o(e,n={}){let{orderBy:a=r,reverse:o=!1,limit:s,offset:c,filter:l}=n,u=i&&e?t.where(i).equals(e):t.toCollection();l&&(u=u.filter(l));let d=a===r?await u.toArray():await u.sortBy(a);return o&&(d=d.reverse()),c&&(d=d.slice(c)),typeof s==`number`&&(d=d.slice(0,s)),d}return{put:(e,n)=>t.put(a(e,n)),bulkPut:(e,n)=>t.bulkPut(e.map(e=>a(e,n))),get:e=>t.get(e),list:o,update:(e,n)=>t.update(e,n),updateMany:async(e,n)=>{let r=n;return i&&e?t.where(i).equals(e).modify(r):t.toCollection().modify(r)},delete:e=>t.delete(e),clear:async e=>{i&&e?await t.where(i).equals(e).delete():await t.clear()},count:e=>i&&e?t.where(i).equals(e).count():t.count(),raw:t,db:e}}exports.buildStore=i,exports.createOfflineStore=r;
|
|
2
2
|
//# sourceMappingURL=create-offline-store.cjs.map
|