@vizejs/composable 0.426.3 → 0.427.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/dist/abort-signal.d.mts +1 -1
- package/dist/active-element.d.mts +37 -0
- package/dist/active-element.mjs +56 -0
- package/dist/animate.d.mts +114 -0
- package/dist/animate.mjs +157 -0
- package/dist/battery.d.mts +61 -0
- package/dist/battery.mjs +90 -0
- package/dist/breakpoints.d.mts +82 -0
- package/dist/breakpoints.mjs +91 -0
- package/dist/catalog-BeTXFKxF.d.mts +4188 -0
- package/dist/catalog-r4Z5nptX.mjs +5144 -0
- package/dist/catalog.d.mts +1 -1
- package/dist/catalog.mjs +1 -1
- package/dist/color-mode.d.mts +131 -0
- package/dist/color-mode.mjs +133 -0
- package/dist/computed-async.d.mts +63 -0
- package/dist/computed-async.mjs +43 -0
- package/dist/computed-with-control.d.mts +44 -0
- package/dist/computed-with-control.mjs +54 -0
- package/dist/create-event-hook.d.mts +77 -0
- package/dist/create-event-hook.mjs +66 -0
- package/dist/create-global-state.d.mts +24 -0
- package/dist/create-global-state.mjs +34 -0
- package/dist/create-injection-state.d.mts +51 -0
- package/dist/create-injection-state.mjs +19 -0
- package/dist/create-shared-composable.d.mts +38 -0
- package/dist/create-shared-composable.mjs +54 -0
- package/dist/device-motion.d.mts +71 -0
- package/dist/device-motion.mjs +75 -0
- package/dist/device-orientation.d.mts +82 -0
- package/dist/device-orientation.mjs +86 -0
- package/dist/device-pixel-ratio.d.mts +45 -0
- package/dist/device-pixel-ratio.mjs +50 -0
- package/dist/document-visibility.mjs +6 -2
- package/dist/draggable.d.mts +121 -0
- package/dist/draggable.mjs +153 -0
- package/dist/element-bounding.d.mts +87 -0
- package/dist/element-bounding.mjs +95 -0
- package/dist/element-by-point.d.mts +70 -0
- package/dist/element-by-point.mjs +69 -0
- package/dist/element-hover.d.mts +42 -0
- package/dist/element-hover.mjs +70 -0
- package/dist/element-ref.d.mts +34 -0
- package/dist/element-ref.mjs +23 -0
- package/dist/element-target-Crpxl4D9.d.mts +60 -0
- package/dist/element-target.d.mts +2 -0
- package/dist/element-target.mjs +58 -0
- package/dist/event-listener.mjs +7 -3
- package/dist/focus.d.mts +69 -0
- package/dist/focus.mjs +124 -0
- package/dist/fps.d.mts +59 -0
- package/dist/fps.mjs +64 -0
- package/dist/geolocation.d.mts +98 -0
- package/dist/geolocation.mjs +86 -0
- package/dist/i18n.d.mts +237 -0
- package/dist/i18n.mjs +215 -0
- package/dist/icu-message.d.mts +235 -0
- package/dist/icu-message.mjs +343 -0
- package/dist/idle.d.mts +79 -0
- package/dist/idle.mjs +90 -0
- package/dist/index.d.mts +172 -6
- package/dist/index.mjs +173 -7
- package/dist/infinite-scroll.d.mts +56 -0
- package/dist/infinite-scroll.mjs +72 -0
- package/dist/intersection-observer.d.mts +122 -0
- package/dist/intersection-observer.mjs +117 -0
- package/dist/magic-keys.d.mts +121 -0
- package/dist/magic-keys.mjs +163 -0
- package/dist/math.d.mts +96 -0
- package/dist/math.mjs +84 -0
- package/dist/media-query.d.mts +3 -1
- package/dist/media-query.mjs +5 -3
- package/dist/mouse-in-element.d.mts +49 -0
- package/dist/mouse-in-element.mjs +66 -0
- package/dist/mouse.d.mts +77 -0
- package/dist/mouse.mjs +100 -0
- package/dist/mutation-observer.d.mts +98 -0
- package/dist/mutation-observer.mjs +69 -0
- package/dist/network.d.mts +96 -0
- package/dist/network.mjs +117 -0
- package/dist/on-click-outside.d.mts +69 -0
- package/dist/on-click-outside.mjs +115 -0
- package/dist/on-key-stroke.d.mts +71 -0
- package/dist/on-key-stroke.mjs +79 -0
- package/dist/on-long-press.d.mts +82 -0
- package/dist/on-long-press.mjs +105 -0
- package/dist/on-start-typing.d.mts +44 -0
- package/dist/on-start-typing.mjs +61 -0
- package/dist/page-leave.d.mts +26 -0
- package/dist/page-leave.mjs +40 -0
- package/dist/parent-element.d.mts +16 -0
- package/dist/parent-element.mjs +27 -0
- package/dist/pinch.d.mts +73 -0
- package/dist/pinch.mjs +138 -0
- package/dist/pointer-lock.d.mts +79 -0
- package/dist/pointer-lock.mjs +126 -0
- package/dist/pointer.d.mts +78 -0
- package/dist/pointer.mjs +95 -0
- package/dist/preferences.d.mts +55 -0
- package/dist/preferences.mjs +63 -0
- package/dist/preferred-languages.d.mts +43 -0
- package/dist/preferred-languages.mjs +44 -0
- package/dist/reactify.d.mts +28 -0
- package/dist/reactify.mjs +7 -0
- package/dist/ref-auto-reset.d.mts +47 -0
- package/dist/ref-auto-reset.mjs +70 -0
- package/dist/ref-debounced.d.mts +29 -0
- package/dist/ref-debounced.mjs +29 -0
- package/dist/ref-default.d.mts +27 -0
- package/dist/ref-default.mjs +33 -0
- package/dist/resize-observer.d.mts +96 -0
- package/dist/resize-observer.mjs +111 -0
- package/dist/resolver.d.mts +124 -0
- package/dist/resolver.mjs +138 -0
- package/dist/retry-async.d.mts +2 -2
- package/dist/retry-delay-DYsdq4SE.d.mts +73 -0
- package/dist/retry-delay.d.mts +1 -72
- package/dist/screen-orientation.d.mts +77 -0
- package/dist/screen-orientation.mjs +74 -0
- package/dist/scroll-lock.d.mts +37 -0
- package/dist/scroll-lock.mjs +50 -0
- package/dist/scroll.d.mts +158 -0
- package/dist/scroll.mjs +172 -0
- package/dist/standard-schema-DmNgFVK5.d.mts +107 -0
- package/dist/standard-schema.d.mts +2 -0
- package/dist/standard-schema.mjs +60 -0
- package/dist/swipe.d.mts +125 -0
- package/dist/swipe.mjs +225 -0
- package/dist/sync-ref.d.mts +80 -0
- package/dist/sync-ref.mjs +43 -0
- package/dist/text-selection.d.mts +46 -0
- package/dist/text-selection.mjs +62 -0
- package/dist/textarea-autosize.d.mts +58 -0
- package/dist/textarea-autosize.mjs +54 -0
- package/dist/timeout-scheduler-CI8RVLZs.d.mts +18 -0
- package/dist/timeout-scheduler.d.mts +1 -17
- package/dist/to-reactive.d.mts +26 -0
- package/dist/to-reactive.mjs +46 -0
- package/dist/transition.d.mts +125 -0
- package/dist/transition.mjs +266 -0
- package/dist/until.d.mts +177 -0
- package/dist/until.mjs +111 -0
- package/dist/use-array.d.mts +112 -0
- package/dist/use-array.mjs +90 -0
- package/dist/use-async-queue.d.mts +109 -0
- package/dist/use-async-queue.mjs +96 -0
- package/dist/use-async-state.d.mts +86 -0
- package/dist/use-async-state.mjs +41 -0
- package/dist/use-barcode-detector.d.mts +159 -0
- package/dist/use-barcode-detector.mjs +143 -0
- package/dist/use-bluetooth.d.mts +164 -0
- package/dist/use-bluetooth.mjs +183 -0
- package/dist/use-broadcast-channel.d.mts +115 -0
- package/dist/use-broadcast-channel.mjs +121 -0
- package/dist/use-builtin-ai.d.mts +342 -0
- package/dist/use-builtin-ai.mjs +261 -0
- package/dist/use-clipboard.d.mts +169 -0
- package/dist/use-clipboard.mjs +226 -0
- package/dist/use-compression-stream.d.mts +173 -0
- package/dist/use-compression-stream.mjs +166 -0
- package/dist/use-confirm-dialog.d.mts +70 -0
- package/dist/use-confirm-dialog.mjs +57 -0
- package/dist/use-contact-picker.d.mts +117 -0
- package/dist/use-contact-picker.mjs +103 -0
- package/dist/use-cookie.d.mts +196 -0
- package/dist/use-cookie.mjs +259 -0
- package/dist/use-countdown.d.mts +85 -0
- package/dist/use-countdown.mjs +74 -0
- package/dist/use-css-var.d.mts +96 -0
- package/dist/use-css-var.mjs +104 -0
- package/dist/use-cycle-list.d.mts +76 -0
- package/dist/use-cycle-list.mjs +39 -0
- package/dist/use-date-format.d.mts +103 -0
- package/dist/use-date-format.mjs +147 -0
- package/dist/use-date-time-format.d.mts +75 -0
- package/dist/use-date-time-format.mjs +53 -0
- package/dist/use-debounced.d.mts +1 -1
- package/dist/use-display-media.d.mts +62 -0
- package/dist/use-display-media.mjs +46 -0
- package/dist/use-display-names.d.mts +75 -0
- package/dist/use-display-names.mjs +52 -0
- package/dist/use-document-title.d.mts +88 -0
- package/dist/use-document-title.mjs +100 -0
- package/dist/use-drop-zone.d.mts +128 -0
- package/dist/use-drop-zone.mjs +154 -0
- package/dist/use-event-source.d.mts +184 -0
- package/dist/use-event-source.mjs +226 -0
- package/dist/use-eye-dropper.d.mts +79 -0
- package/dist/use-eye-dropper.mjs +68 -0
- package/dist/use-favicon.d.mts +78 -0
- package/dist/use-favicon.mjs +68 -0
- package/dist/use-fetch.d.mts +230 -0
- package/dist/use-fetch.mjs +263 -0
- package/dist/use-field.d.mts +107 -0
- package/dist/use-field.mjs +117 -0
- package/dist/use-file-dialog.d.mts +139 -0
- package/dist/use-file-dialog.mjs +101 -0
- package/dist/use-file-system-access.d.mts +184 -0
- package/dist/use-file-system-access.mjs +151 -0
- package/dist/use-form-field-props.d.mts +235 -0
- package/dist/use-form-field-props.mjs +164 -0
- package/dist/use-form.d.mts +324 -0
- package/dist/use-form.mjs +482 -0
- package/dist/use-fullscreen.d.mts +104 -0
- package/dist/use-fullscreen.mjs +95 -0
- package/dist/use-gamepad.d.mts +242 -0
- package/dist/use-gamepad.mjs +218 -0
- package/dist/use-hid.d.mts +160 -0
- package/dist/use-hid.mjs +156 -0
- package/dist/use-id-generator.d.mts +44 -0
- package/dist/use-id-generator.mjs +38 -0
- package/dist/use-image.d.mts +125 -0
- package/dist/use-image.mjs +109 -0
- package/dist/use-indexed-db.d.mts +207 -0
- package/dist/use-indexed-db.mjs +251 -0
- package/dist/use-interval-BA55gTHT.d.mts +140 -0
- package/dist/use-interval.d.mts +2 -0
- package/dist/use-interval.mjs +100 -0
- package/dist/use-list-format.d.mts +60 -0
- package/dist/use-list-format.mjs +40 -0
- package/dist/use-machine.d.mts +90 -0
- package/dist/use-machine.mjs +78 -0
- package/dist/use-map.d.mts +90 -0
- package/dist/use-map.mjs +70 -0
- package/dist/use-media-controls.d.mts +198 -0
- package/dist/use-media-controls.mjs +264 -0
- package/dist/use-memoize.d.mts +73 -0
- package/dist/use-memoize.mjs +28 -0
- package/dist/use-mounted.d.mts +24 -0
- package/dist/use-mounted.mjs +29 -0
- package/dist/use-navigation-api.d.mts +360 -0
- package/dist/use-navigation-api.mjs +231 -0
- package/dist/use-notification.d.mts +139 -0
- package/dist/use-notification.mjs +131 -0
- package/dist/use-now.d.mts +137 -0
- package/dist/use-now.mjs +44 -0
- package/dist/use-number-format.d.mts +73 -0
- package/dist/use-number-format.mjs +58 -0
- package/dist/use-object-url.d.mts +47 -0
- package/dist/use-object-url.mjs +54 -0
- package/dist/use-offset-pagination.d.mts +91 -0
- package/dist/use-offset-pagination.mjs +80 -0
- package/dist/use-payment-request.d.mts +239 -0
- package/dist/use-payment-request.mjs +206 -0
- package/dist/use-performance-observer.d.mts +285 -0
- package/dist/use-performance-observer.mjs +132 -0
- package/dist/use-permission.d.mts +99 -0
- package/dist/use-permission.mjs +92 -0
- package/dist/use-plural-rules.d.mts +79 -0
- package/dist/use-plural-rules.mjs +59 -0
- package/dist/use-push-subscription.d.mts +154 -0
- package/dist/use-push-subscription.mjs +146 -0
- package/dist/use-queue.d.mts +89 -0
- package/dist/use-queue.mjs +116 -0
- package/dist/use-raf-fn.d.mts +87 -0
- package/dist/use-raf-fn.mjs +99 -0
- package/dist/use-relative-time-format.d.mts +111 -0
- package/dist/use-relative-time-format.mjs +119 -0
- package/dist/use-request-idle-callback.d.mts +122 -0
- package/dist/use-request-idle-callback.mjs +147 -0
- package/dist/use-route-query.d.mts +149 -0
- package/dist/use-route-query.mjs +86 -0
- package/dist/use-scheduler-post-task.d.mts +156 -0
- package/dist/use-scheduler-post-task.mjs +182 -0
- package/dist/use-screen-details.d.mts +205 -0
- package/dist/use-screen-details.mjs +188 -0
- package/dist/use-script-tag.d.mts +162 -0
- package/dist/use-script-tag.mjs +171 -0
- package/dist/use-segmenter.d.mts +78 -0
- package/dist/use-segmenter.mjs +66 -0
- package/dist/use-selection.d.mts +125 -0
- package/dist/use-selection.mjs +77 -0
- package/dist/use-serial.d.mts +165 -0
- package/dist/use-serial.mjs +205 -0
- package/dist/use-service-worker.d.mts +177 -0
- package/dist/use-service-worker.mjs +178 -0
- package/dist/use-set.d.mts +96 -0
- package/dist/use-set.mjs +74 -0
- package/dist/use-share.d.mts +92 -0
- package/dist/use-share.mjs +99 -0
- package/dist/use-sorted-locale.d.mts +62 -0
- package/dist/use-sorted-locale.mjs +52 -0
- package/dist/use-sorted.d.mts +29 -0
- package/dist/use-sorted.mjs +14 -0
- package/dist/use-speech-recognition.d.mts +150 -0
- package/dist/use-speech-recognition.mjs +168 -0
- package/dist/use-speech-synthesis.d.mts +148 -0
- package/dist/use-speech-synthesis.mjs +152 -0
- package/dist/use-stack.d.mts +83 -0
- package/dist/use-stack.mjs +93 -0
- package/dist/use-stepper.d.mts +79 -0
- package/dist/use-stepper.mjs +52 -0
- package/dist/use-storage-estimate.d.mts +151 -0
- package/dist/use-storage-estimate.mjs +170 -0
- package/dist/use-storage.d.mts +214 -0
- package/dist/use-storage.mjs +415 -0
- package/dist/use-style-tag.d.mts +102 -0
- package/dist/use-style-tag.mjs +91 -0
- package/dist/use-supported.d.mts +23 -0
- package/dist/use-supported.mjs +26 -0
- package/dist/use-throttled.d.mts +1 -1
- package/dist/use-time-ago.d.mts +163 -0
- package/dist/use-time-ago.mjs +95 -0
- package/dist/use-timeout.d.mts +122 -0
- package/dist/use-timeout.mjs +65 -0
- package/dist/use-url-hash.d.mts +88 -0
- package/dist/use-url-hash.mjs +145 -0
- package/dist/use-url-search-params.d.mts +223 -0
- package/dist/use-url-search-params.mjs +295 -0
- package/dist/use-usb.d.mts +212 -0
- package/dist/use-usb.mjs +137 -0
- package/dist/use-user-activation.d.mts +83 -0
- package/dist/use-user-activation.mjs +113 -0
- package/dist/use-user-media.d.mts +194 -0
- package/dist/use-user-media.mjs +214 -0
- package/dist/use-v-model.d.mts +113 -0
- package/dist/use-v-model.mjs +40 -0
- package/dist/use-vibrate.d.mts +81 -0
- package/dist/use-vibrate.mjs +90 -0
- package/dist/use-view-transition.d.mts +106 -0
- package/dist/use-view-transition.mjs +101 -0
- package/dist/use-visual-viewport.d.mts +105 -0
- package/dist/use-visual-viewport.mjs +104 -0
- package/dist/use-wake-lock.d.mts +96 -0
- package/dist/use-wake-lock.mjs +106 -0
- package/dist/use-web-authn.d.mts +404 -0
- package/dist/use-web-authn.mjs +323 -0
- package/dist/use-web-locks.d.mts +180 -0
- package/dist/use-web-locks.mjs +136 -0
- package/dist/use-web-midi.d.mts +148 -0
- package/dist/use-web-midi.mjs +140 -0
- package/dist/use-web-vitals.d.mts +142 -0
- package/dist/use-web-vitals.mjs +248 -0
- package/dist/use-websocket.d.mts +218 -0
- package/dist/use-websocket.mjs +257 -0
- package/dist/use-worker-fn.d.mts +119 -0
- package/dist/use-worker-fn.mjs +162 -0
- package/dist/virtual-list.d.mts +105 -0
- package/dist/virtual-list.mjs +128 -0
- package/dist/watch-debounced.d.mts +84 -0
- package/dist/watch-debounced.mjs +84 -0
- package/dist/watch-ignorable.d.mts +47 -0
- package/dist/watch-ignorable.mjs +61 -0
- package/dist/watch-once.d.mts +29 -0
- package/dist/watch-once.mjs +10 -0
- package/dist/watch-pausable.d.mts +51 -0
- package/dist/watch-pausable.mjs +23 -0
- package/dist/watch-source.d.mts +29 -0
- package/dist/watch-source.mjs +1 -0
- package/dist/watch-throttled.d.mts +70 -0
- package/dist/watch-throttled.mjs +94 -0
- package/dist/whenever.d.mts +39 -0
- package/dist/whenever.mjs +41 -0
- package/dist/window-size.d.mts +87 -0
- package/dist/window-size.mjs +65 -0
- package/package.json +846 -5
- package/registry/files/abort-signal.ts +292 -0
- package/registry/files/active-element.ts +93 -0
- package/registry/files/animate.ts +322 -0
- package/registry/files/async-resource.ts +190 -0
- package/registry/files/battery.ts +166 -0
- package/registry/files/breakpoints.ts +166 -0
- package/registry/files/capability.ts +171 -0
- package/registry/files/color-mode.ts +274 -0
- package/registry/files/computed-async.ts +123 -0
- package/registry/files/computed-with-control.ts +80 -0
- package/registry/files/create-event-hook.ts +139 -0
- package/registry/files/create-global-state.ts +34 -0
- package/registry/files/create-injection-state.ts +75 -0
- package/registry/files/create-shared-composable.ts +74 -0
- package/registry/files/device-motion.ts +152 -0
- package/registry/files/device-orientation.ts +168 -0
- package/registry/files/device-pixel-ratio.ts +100 -0
- package/registry/files/disposal-scope.ts +201 -0
- package/registry/files/document-visibility.ts +152 -0
- package/registry/files/draggable.ts +273 -0
- package/registry/files/element-bounding.ts +175 -0
- package/registry/files/element-by-point.ts +149 -0
- package/registry/files/element-hover.ts +104 -0
- package/registry/files/element-ref.ts +58 -0
- package/registry/files/element-target.ts +99 -0
- package/registry/files/event-listener.ts +188 -0
- package/registry/files/focus.ts +181 -0
- package/registry/files/fps.ts +133 -0
- package/registry/files/geolocation.ts +214 -0
- package/registry/files/i18n.ts +524 -0
- package/registry/files/icu-message.ts +701 -0
- package/registry/files/idle.ts +176 -0
- package/registry/files/infinite-scroll.ts +135 -0
- package/registry/files/intersection-observer.ts +261 -0
- package/registry/files/locale.ts +148 -0
- package/registry/files/magic-keys.ts +298 -0
- package/registry/files/math.ts +175 -0
- package/registry/files/media-query.ts +102 -0
- package/registry/files/mouse-in-element.ts +107 -0
- package/registry/files/mouse.ts +167 -0
- package/registry/files/mutation-observer.ts +183 -0
- package/registry/files/network.ts +229 -0
- package/registry/files/on-click-outside.ts +178 -0
- package/registry/files/on-key-stroke.ts +135 -0
- package/registry/files/on-long-press.ts +188 -0
- package/registry/files/on-start-typing.ts +88 -0
- package/registry/files/page-leave.ts +57 -0
- package/registry/files/parent-element.ts +29 -0
- package/registry/files/pinch.ts +187 -0
- package/registry/files/pointer-lock.ts +232 -0
- package/registry/files/pointer.ts +153 -0
- package/registry/files/preferences.ts +98 -0
- package/registry/files/preferred-languages.ts +88 -0
- package/registry/files/reactify.ts +39 -0
- package/registry/files/ref-auto-reset.ts +102 -0
- package/registry/files/ref-debounced.ts +34 -0
- package/registry/files/ref-default.ts +35 -0
- package/registry/files/resize-observer.ts +220 -0
- package/registry/files/retry-async.ts +261 -0
- package/registry/files/retry-delay.ts +132 -0
- package/registry/files/scope.ts +21 -0
- package/registry/files/screen-orientation.ts +165 -0
- package/registry/files/scroll-lock.ts +80 -0
- package/registry/files/scroll.ts +338 -0
- package/registry/files/standard-schema.ts +163 -0
- package/registry/files/swipe.ts +321 -0
- package/registry/files/sync-ref.ts +166 -0
- package/registry/files/temporal.ts +182 -0
- package/registry/files/text-selection.ts +110 -0
- package/registry/files/textarea-autosize.ts +114 -0
- package/registry/files/timeout-scheduler.ts +16 -0
- package/registry/files/to-reactive.ts +44 -0
- package/registry/files/transition.ts +271 -0
- package/registry/files/until.ts +352 -0
- package/registry/files/use-array.ts +201 -0
- package/registry/files/use-async-queue.ts +278 -0
- package/registry/files/use-async-state.ts +139 -0
- package/registry/files/use-barcode-detector.ts +321 -0
- package/registry/files/use-bluetooth.ts +409 -0
- package/registry/files/use-broadcast-channel.ts +250 -0
- package/registry/files/use-builtin-ai.ts +674 -0
- package/registry/files/use-clipboard.ts +425 -0
- package/registry/files/use-compression-stream.ts +364 -0
- package/registry/files/use-confirm-dialog.ts +137 -0
- package/registry/files/use-contact-picker.ts +246 -0
- package/registry/files/use-cookie.ts +500 -0
- package/registry/files/use-countdown.ts +161 -0
- package/registry/files/use-counter.ts +147 -0
- package/registry/files/use-css-var.ts +191 -0
- package/registry/files/use-cycle-list.ts +136 -0
- package/registry/files/use-date-format.ts +281 -0
- package/registry/files/use-date-time-format.ts +113 -0
- package/registry/files/use-debounced.ts +163 -0
- package/registry/files/use-display-media.ts +89 -0
- package/registry/files/use-display-names.ts +122 -0
- package/registry/files/use-document-title.ts +196 -0
- package/registry/files/use-drop-zone.ts +287 -0
- package/registry/files/use-event-source.ts +470 -0
- package/registry/files/use-eye-dropper.ts +134 -0
- package/registry/files/use-favicon.ts +140 -0
- package/registry/files/use-fetch.ts +578 -0
- package/registry/files/use-field.ts +247 -0
- package/registry/files/use-file-dialog.ts +257 -0
- package/registry/files/use-file-system-access.ts +383 -0
- package/registry/files/use-form-field-props.ts +381 -0
- package/registry/files/use-form.ts +980 -0
- package/registry/files/use-fullscreen.ts +214 -0
- package/registry/files/use-gamepad.ts +463 -0
- package/registry/files/use-hid.ts +359 -0
- package/registry/files/use-history.ts +231 -0
- package/registry/files/use-id-generator.ts +61 -0
- package/registry/files/use-image.ts +253 -0
- package/registry/files/use-indexed-db.ts +508 -0
- package/registry/files/use-interval.ts +253 -0
- package/registry/files/use-list-format.ts +85 -0
- package/registry/files/use-machine.ts +171 -0
- package/registry/files/use-map.ts +145 -0
- package/registry/files/use-media-controls.ts +545 -0
- package/registry/files/use-memoize.ts +118 -0
- package/registry/files/use-mounted.ts +30 -0
- package/registry/files/use-navigation-api.ts +641 -0
- package/registry/files/use-notification.ts +285 -0
- package/registry/files/use-now.ts +194 -0
- package/registry/files/use-number-format.ts +120 -0
- package/registry/files/use-object-url.ts +87 -0
- package/registry/files/use-offset-pagination.ts +168 -0
- package/registry/files/use-payment-request.ts +465 -0
- package/registry/files/use-performance-observer.ts +469 -0
- package/registry/files/use-permission.ts +220 -0
- package/registry/files/use-plural-rules.ts +134 -0
- package/registry/files/use-previous.ts +62 -0
- package/registry/files/use-push-subscription.ts +352 -0
- package/registry/files/use-queue.ts +197 -0
- package/registry/files/use-raf-fn.ts +176 -0
- package/registry/files/use-relative-time-format.ts +201 -0
- package/registry/files/use-request-idle-callback.ts +278 -0
- package/registry/files/use-route-query.ts +300 -0
- package/registry/files/use-scheduler-post-task.ts +397 -0
- package/registry/files/use-screen-details.ts +393 -0
- package/registry/files/use-script-tag.ts +341 -0
- package/registry/files/use-segmenter.ts +147 -0
- package/registry/files/use-selection.ts +233 -0
- package/registry/files/use-serial.ts +404 -0
- package/registry/files/use-service-worker.ts +413 -0
- package/registry/files/use-set.ts +154 -0
- package/registry/files/use-share.ts +168 -0
- package/registry/files/use-sorted-locale.ts +130 -0
- package/registry/files/use-sorted.ts +49 -0
- package/registry/files/use-speech-recognition.ts +357 -0
- package/registry/files/use-speech-synthesis.ts +333 -0
- package/registry/files/use-stack.ts +164 -0
- package/registry/files/use-stepper.ts +166 -0
- package/registry/files/use-storage-estimate.ts +352 -0
- package/registry/files/use-storage.ts +635 -0
- package/registry/files/use-style-tag.ts +200 -0
- package/registry/files/use-supported.ts +26 -0
- package/registry/files/use-throttled.ts +215 -0
- package/registry/files/use-time-ago.ts +276 -0
- package/registry/files/use-timeout.ts +218 -0
- package/registry/files/use-toggle.ts +54 -0
- package/registry/files/use-url-hash.ts +280 -0
- package/registry/files/use-url-search-params.ts +497 -0
- package/registry/files/use-usb.ts +395 -0
- package/registry/files/use-user-activation.ts +215 -0
- package/registry/files/use-user-media.ts +422 -0
- package/registry/files/use-v-model.ts +210 -0
- package/registry/files/use-vibrate.ts +174 -0
- package/registry/files/use-view-transition.ts +229 -0
- package/registry/files/use-visual-viewport.ts +228 -0
- package/registry/files/use-wake-lock.ts +206 -0
- package/registry/files/use-web-authn.ts +793 -0
- package/registry/files/use-web-locks.ts +363 -0
- package/registry/files/use-web-midi.ts +306 -0
- package/registry/files/use-web-vitals.ts +409 -0
- package/registry/files/use-websocket.ts +553 -0
- package/registry/files/use-worker-fn.ts +306 -0
- package/registry/files/virtual-list.ts +230 -0
- package/registry/files/watch-debounced.ts +206 -0
- package/registry/files/watch-ignorable.ts +128 -0
- package/registry/files/watch-once.ts +46 -0
- package/registry/files/watch-pausable.ts +93 -0
- package/registry/files/watch-source.ts +51 -0
- package/registry/files/watch-throttled.ts +201 -0
- package/registry/files/whenever.ts +70 -0
- package/registry/files/window-size.ts +151 -0
- package/registry/registry.json +5792 -0
- package/dist/catalog-D2AL3xYl.d.mts +0 -523
- package/dist/catalog-D5SYCsgW.mjs +0 -549
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { tryOnScopeDispose } from "./scope.mjs";
|
|
2
|
+
import { computed, hasInjectionContext, readonly, ref, shallowRef, toValue, unref, watchPostEffect } from "vue";
|
|
3
|
+
//#region src/use-web-authn.ts
|
|
4
|
+
const transports = [
|
|
5
|
+
"usb",
|
|
6
|
+
"nfc",
|
|
7
|
+
"ble",
|
|
8
|
+
"hybrid",
|
|
9
|
+
"internal"
|
|
10
|
+
];
|
|
11
|
+
function isTransport(value) {
|
|
12
|
+
return transports.includes(value);
|
|
13
|
+
}
|
|
14
|
+
function isAttachment(value) {
|
|
15
|
+
return value === "platform" || value === "cross-platform";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Encode bytes as unpadded base64url.
|
|
19
|
+
*
|
|
20
|
+
* @param bytes Buffer or view to encode.
|
|
21
|
+
* @returns Base64url text without `=` padding.
|
|
22
|
+
*/
|
|
23
|
+
function encodeBase64Url(bytes) {
|
|
24
|
+
const view = bytes instanceof ArrayBuffer ? new Uint8Array(bytes) : new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
25
|
+
let binary = "";
|
|
26
|
+
for (const byte of view) binary += String.fromCharCode(byte);
|
|
27
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Decode base64url (padded or unpadded) into bytes.
|
|
31
|
+
*
|
|
32
|
+
* @param text Base64url text.
|
|
33
|
+
* @throws `TypeError` tagged `VIZE_COMPOSE_WEBAUTHN_INVALID_BASE64URL` for malformed input.
|
|
34
|
+
* @returns Decoded bytes.
|
|
35
|
+
*/
|
|
36
|
+
function decodeBase64Url(text) {
|
|
37
|
+
const body = text.replace(/=+$/u, "");
|
|
38
|
+
if (!/^[\w-]*$/u.test(body) || body.length % 4 === 1) throw new TypeError(`[VIZE_COMPOSE_WEBAUTHN_INVALID_BASE64URL] invalid base64url input`);
|
|
39
|
+
const binary = atob(body.replaceAll("-", "+").replaceAll("_", "/"));
|
|
40
|
+
const bytes = new Uint8Array(binary.length);
|
|
41
|
+
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
42
|
+
return bytes;
|
|
43
|
+
}
|
|
44
|
+
function parseDescriptors(list) {
|
|
45
|
+
return list.map((descriptor) => ({
|
|
46
|
+
type: descriptor.type,
|
|
47
|
+
id: decodeBase64Url(descriptor.id),
|
|
48
|
+
...descriptor.transports ? { transports: [...descriptor.transports] } : {}
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
function isRecord(value) {
|
|
52
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53
|
+
}
|
|
54
|
+
function parsePrfValues(value) {
|
|
55
|
+
if (!isRecord(value)) return value;
|
|
56
|
+
return {
|
|
57
|
+
...value,
|
|
58
|
+
...typeof value.first === "string" ? { first: decodeBase64Url(value.first) } : {},
|
|
59
|
+
...typeof value.second === "string" ? { second: decodeBase64Url(value.second) } : {}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function parseExtensions(extensions) {
|
|
63
|
+
const prf = extensions.prf;
|
|
64
|
+
if (!isRecord(prf)) return { ...extensions };
|
|
65
|
+
const byCredential = prf.evalByCredential;
|
|
66
|
+
return {
|
|
67
|
+
...extensions,
|
|
68
|
+
prf: {
|
|
69
|
+
...prf,
|
|
70
|
+
...prf.eval === void 0 ? {} : { eval: parsePrfValues(prf.eval) },
|
|
71
|
+
...isRecord(byCredential) ? { evalByCredential: Object.fromEntries(Object.entries(byCredential).map(([id, values]) => [id, parsePrfValues(values)])) } : {}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function serializeExtensionValue(value) {
|
|
76
|
+
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) return encodeBase64Url(value);
|
|
77
|
+
if (Array.isArray(value)) return value.map(serializeExtensionValue);
|
|
78
|
+
if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, serializeExtensionValue(entry)]));
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
function serializeExtensions(results) {
|
|
82
|
+
return serializeExtensionValue(results);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Convert server creation-options JSON into binary options for `create`.
|
|
86
|
+
*
|
|
87
|
+
* @param json Options with base64url `challenge`, `user.id`, and credential ids.
|
|
88
|
+
* @throws `TypeError` tagged `VIZE_COMPOSE_WEBAUTHN_INVALID_BASE64URL` for malformed fields.
|
|
89
|
+
* @returns Binary creation options.
|
|
90
|
+
*/
|
|
91
|
+
function parseCreationOptionsFromJSON(json) {
|
|
92
|
+
const { excludeCredentials, authenticatorSelection, hints, extensions, ...rest } = json;
|
|
93
|
+
return {
|
|
94
|
+
...rest,
|
|
95
|
+
rp: { ...json.rp },
|
|
96
|
+
user: {
|
|
97
|
+
...json.user,
|
|
98
|
+
id: decodeBase64Url(json.user.id)
|
|
99
|
+
},
|
|
100
|
+
challenge: decodeBase64Url(json.challenge),
|
|
101
|
+
pubKeyCredParams: json.pubKeyCredParams.map((parameter) => ({ ...parameter })),
|
|
102
|
+
...excludeCredentials ? { excludeCredentials: parseDescriptors(excludeCredentials) } : {},
|
|
103
|
+
...authenticatorSelection ? { authenticatorSelection: { ...authenticatorSelection } } : {},
|
|
104
|
+
...hints ? { hints: [...hints] } : {},
|
|
105
|
+
...extensions ? { extensions: parseExtensions(extensions) } : {}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Convert server request-options JSON into binary options for `get`.
|
|
110
|
+
*
|
|
111
|
+
* @param json Options with base64url `challenge` and credential ids.
|
|
112
|
+
* @throws `TypeError` tagged `VIZE_COMPOSE_WEBAUTHN_INVALID_BASE64URL` for malformed fields.
|
|
113
|
+
* @returns Binary request options.
|
|
114
|
+
*/
|
|
115
|
+
function parseRequestOptionsFromJSON(json) {
|
|
116
|
+
const { allowCredentials, hints, extensions, ...rest } = json;
|
|
117
|
+
return {
|
|
118
|
+
...rest,
|
|
119
|
+
challenge: decodeBase64Url(json.challenge),
|
|
120
|
+
...allowCredentials ? { allowCredentials: parseDescriptors(allowCredentials) } : {},
|
|
121
|
+
...hints ? { hints: [...hints] } : {},
|
|
122
|
+
...extensions ? { extensions: parseExtensions(extensions) } : {}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Serialize a registration credential into JSON-safe base64url fields.
|
|
127
|
+
*
|
|
128
|
+
* @param credential Credential resolved by `create`.
|
|
129
|
+
* @returns Server-ready registration response.
|
|
130
|
+
*/
|
|
131
|
+
function serializeRegistrationCredential(credential) {
|
|
132
|
+
const { response } = credential;
|
|
133
|
+
const publicKey = response.getPublicKey?.() ?? null;
|
|
134
|
+
const authenticatorData = response.getAuthenticatorData?.();
|
|
135
|
+
const algorithm = response.getPublicKeyAlgorithm?.();
|
|
136
|
+
const known = response.getTransports?.().filter(isTransport);
|
|
137
|
+
return {
|
|
138
|
+
id: credential.id,
|
|
139
|
+
rawId: encodeBase64Url(credential.rawId),
|
|
140
|
+
type: "public-key",
|
|
141
|
+
...isAttachment(credential.authenticatorAttachment) ? { authenticatorAttachment: credential.authenticatorAttachment } : {},
|
|
142
|
+
clientExtensionResults: serializeExtensions(credential.getClientExtensionResults()),
|
|
143
|
+
response: {
|
|
144
|
+
clientDataJSON: encodeBase64Url(response.clientDataJSON),
|
|
145
|
+
attestationObject: encodeBase64Url(response.attestationObject),
|
|
146
|
+
...known ? { transports: known } : {},
|
|
147
|
+
...publicKey ? { publicKey: encodeBase64Url(publicKey) } : {},
|
|
148
|
+
...algorithm === void 0 ? {} : { publicKeyAlgorithm: algorithm },
|
|
149
|
+
...authenticatorData ? { authenticatorData: encodeBase64Url(authenticatorData) } : {}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Serialize an authentication credential into JSON-safe base64url fields.
|
|
155
|
+
*
|
|
156
|
+
* @param credential Credential resolved by `get`.
|
|
157
|
+
* @returns Server-ready authentication response.
|
|
158
|
+
*/
|
|
159
|
+
function serializeAuthenticationCredential(credential) {
|
|
160
|
+
const { response } = credential;
|
|
161
|
+
return {
|
|
162
|
+
id: credential.id,
|
|
163
|
+
rawId: encodeBase64Url(credential.rawId),
|
|
164
|
+
type: "public-key",
|
|
165
|
+
...isAttachment(credential.authenticatorAttachment) ? { authenticatorAttachment: credential.authenticatorAttachment } : {},
|
|
166
|
+
clientExtensionResults: serializeExtensions(credential.getClientExtensionResults()),
|
|
167
|
+
response: {
|
|
168
|
+
clientDataJSON: encodeBase64Url(response.clientDataJSON),
|
|
169
|
+
authenticatorData: encodeBase64Url(response.authenticatorData),
|
|
170
|
+
signature: encodeBase64Url(response.signature),
|
|
171
|
+
...response.userHandle ? { userHandle: encodeBase64Url(response.userHandle) } : {}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function hasResponseField(value, field) {
|
|
176
|
+
if (typeof value !== "object" || value === null || !("response" in value)) return false;
|
|
177
|
+
const { response } = value;
|
|
178
|
+
return typeof response === "object" && response !== null && field in response;
|
|
179
|
+
}
|
|
180
|
+
function isRegistrationCredential(value) {
|
|
181
|
+
return hasResponseField(value, "attestationObject");
|
|
182
|
+
}
|
|
183
|
+
function isAuthenticationCredential(value) {
|
|
184
|
+
return hasResponseField(value, "signature");
|
|
185
|
+
}
|
|
186
|
+
function isStatics(candidate) {
|
|
187
|
+
return typeof candidate === "function";
|
|
188
|
+
}
|
|
189
|
+
function browserStatics() {
|
|
190
|
+
if (typeof window === "undefined") return void 0;
|
|
191
|
+
const candidate = Reflect.get(window, "PublicKeyCredential");
|
|
192
|
+
return isStatics(candidate) ? candidate : void 0;
|
|
193
|
+
}
|
|
194
|
+
function browserCredentials() {
|
|
195
|
+
if (browserStatics() === void 0) return void 0;
|
|
196
|
+
const container = window.navigator.credentials;
|
|
197
|
+
if (!container) return void 0;
|
|
198
|
+
return {
|
|
199
|
+
create: (options) => container.create(options),
|
|
200
|
+
get: (options) => container.get(options)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function isJSONOptions(input) {
|
|
204
|
+
return typeof input.challenge === "string";
|
|
205
|
+
}
|
|
206
|
+
function errorName(error) {
|
|
207
|
+
return typeof error === "object" && error !== null && "name" in error ? error.name : void 0;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Register and authenticate passkeys with the Web Authentication API.
|
|
211
|
+
*
|
|
212
|
+
* `create` and `get` accept binary options or server JSON, run one ceremony
|
|
213
|
+
* at a time (starting one aborts the previous), and resolve to a
|
|
214
|
+
* discriminated {@link WebAuthnResult}. Use the exported pure helpers to
|
|
215
|
+
* serialize results for the server. A pending ceremony is aborted when the
|
|
216
|
+
* owning reactive scope stops; outside a scope call `abort()`.
|
|
217
|
+
*
|
|
218
|
+
* Server rendering: nothing is requested, `supported` and `pending` are false.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const webAuthn = useWebAuthn();
|
|
223
|
+
* const result = await webAuthn.get(await fetchJSON("/login/options"));
|
|
224
|
+
* if (result.status === "success") await post(serializeAuthenticationCredential(result.credential));
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* @param options Capability hosts.
|
|
228
|
+
* @default options {}
|
|
229
|
+
* @returns Ceremony state and actions.
|
|
230
|
+
*/
|
|
231
|
+
function useWebAuthn(options = {}) {
|
|
232
|
+
const pending = ref(false);
|
|
233
|
+
const error = shallowRef(void 0);
|
|
234
|
+
let controller;
|
|
235
|
+
const hydrated = shallowRef(!hasInjectionContext());
|
|
236
|
+
if (!hydrated.value) watchPostEffect(() => {
|
|
237
|
+
hydrated.value = true;
|
|
238
|
+
});
|
|
239
|
+
const resolveCredentials = () => !hydrated.value ? void 0 : options.credentials === void 0 ? browserCredentials() : toValue(options.credentials) ?? void 0;
|
|
240
|
+
const resolveStatics = () => !hydrated.value ? void 0 : options.publicKeyCredential === void 0 ? browserStatics() : unref(options.publicKeyCredential) ?? void 0;
|
|
241
|
+
const abort = (reason) => {
|
|
242
|
+
const current = controller;
|
|
243
|
+
controller = void 0;
|
|
244
|
+
pending.value = false;
|
|
245
|
+
current?.abort(reason);
|
|
246
|
+
};
|
|
247
|
+
const run = async (ceremony, invoke, guard) => {
|
|
248
|
+
const host = resolveCredentials();
|
|
249
|
+
if (!host) return {
|
|
250
|
+
status: "unsupported",
|
|
251
|
+
error: void 0
|
|
252
|
+
};
|
|
253
|
+
abort();
|
|
254
|
+
const own = new AbortController();
|
|
255
|
+
controller = own;
|
|
256
|
+
const external = ceremony.signal;
|
|
257
|
+
const forward = () => own.abort(external?.reason);
|
|
258
|
+
if (external?.aborted) forward();
|
|
259
|
+
else external?.addEventListener("abort", forward, { once: true });
|
|
260
|
+
pending.value = true;
|
|
261
|
+
error.value = void 0;
|
|
262
|
+
try {
|
|
263
|
+
const value = await invoke(host, {
|
|
264
|
+
signal: own.signal,
|
|
265
|
+
...ceremony.mediation ? { mediation: ceremony.mediation } : {}
|
|
266
|
+
});
|
|
267
|
+
if (own.signal.aborted) return {
|
|
268
|
+
status: "aborted",
|
|
269
|
+
error: own.signal.reason
|
|
270
|
+
};
|
|
271
|
+
if (!guard(value)) throw new TypeError("[VIZE_COMPOSE_WEBAUTHN_NO_CREDENTIAL] no credential");
|
|
272
|
+
return {
|
|
273
|
+
status: "success",
|
|
274
|
+
credential: value
|
|
275
|
+
};
|
|
276
|
+
} catch (cause) {
|
|
277
|
+
if (own.signal.aborted || errorName(cause) === "AbortError") return {
|
|
278
|
+
status: "aborted",
|
|
279
|
+
error: cause
|
|
280
|
+
};
|
|
281
|
+
error.value = cause;
|
|
282
|
+
return {
|
|
283
|
+
status: errorName(cause) === "NotAllowedError" ? "not-allowed" : "failed",
|
|
284
|
+
error: cause
|
|
285
|
+
};
|
|
286
|
+
} finally {
|
|
287
|
+
external?.removeEventListener("abort", forward);
|
|
288
|
+
if (controller === own) {
|
|
289
|
+
controller = void 0;
|
|
290
|
+
pending.value = false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const create = (input, ceremony = {}) => run(ceremony, (host, request) => host.create({
|
|
295
|
+
...request,
|
|
296
|
+
publicKey: isJSONOptions(input) ? parseCreationOptionsFromJSON(input) : input
|
|
297
|
+
}), isRegistrationCredential);
|
|
298
|
+
const get = (input, ceremony = {}) => run(ceremony, (host, request) => host.get({
|
|
299
|
+
...request,
|
|
300
|
+
publicKey: isJSONOptions(input) ? parseRequestOptionsFromJSON(input) : input
|
|
301
|
+
}), isAuthenticationCredential);
|
|
302
|
+
const check = async (key) => {
|
|
303
|
+
const statics = resolveStatics();
|
|
304
|
+
try {
|
|
305
|
+
return await statics?.[key]?.call(statics) === true;
|
|
306
|
+
} catch {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
tryOnScopeDispose(() => abort());
|
|
311
|
+
return {
|
|
312
|
+
supported: computed(() => resolveCredentials() !== void 0),
|
|
313
|
+
pending: readonly(pending),
|
|
314
|
+
error: readonly(error),
|
|
315
|
+
create,
|
|
316
|
+
get,
|
|
317
|
+
abort,
|
|
318
|
+
isUserVerifyingPlatformAuthenticatorAvailable: () => check("isUserVerifyingPlatformAuthenticatorAvailable"),
|
|
319
|
+
isConditionalMediationAvailable: () => check("isConditionalMediationAvailable")
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
323
|
+
export { decodeBase64Url, encodeBase64Url, parseCreationOptionsFromJSON, parseRequestOptionsFromJSON, serializeAuthenticationCredential, serializeRegistrationCredential, useWebAuthn };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/use-web-locks.d.ts
|
|
4
|
+
/** Lock modes defined by the Web Locks API. */
|
|
5
|
+
type WebLockMode = "exclusive" | "shared";
|
|
6
|
+
/** Granted lock handed to a request callback. */
|
|
7
|
+
interface WebLockLike {
|
|
8
|
+
/** Lock name. */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
/** Granted mode. */
|
|
11
|
+
readonly mode: WebLockMode;
|
|
12
|
+
}
|
|
13
|
+
/** One entry of a lock manager snapshot. */
|
|
14
|
+
interface WebLockInfo {
|
|
15
|
+
/** Lock name. */
|
|
16
|
+
readonly name?: string | undefined;
|
|
17
|
+
/** Requested or granted mode. */
|
|
18
|
+
readonly mode?: WebLockMode | undefined;
|
|
19
|
+
/** Identifier of the client holding or requesting the lock. */
|
|
20
|
+
readonly clientId?: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Snapshot returned by {@link WebLocksControls.query}. */
|
|
23
|
+
interface WebLocksSnapshot {
|
|
24
|
+
/** Locks currently held by any client of the origin. */
|
|
25
|
+
readonly held: readonly WebLockInfo[];
|
|
26
|
+
/** Requests currently waiting for a lock. */
|
|
27
|
+
readonly pending: readonly WebLockInfo[];
|
|
28
|
+
}
|
|
29
|
+
/** Options forwarded to `LockManager.request`. */
|
|
30
|
+
interface WebLockManagerRequestOptions {
|
|
31
|
+
/** Requested mode. */
|
|
32
|
+
readonly mode: WebLockMode;
|
|
33
|
+
/**
|
|
34
|
+
* Only grant the lock when it is immediately available.
|
|
35
|
+
*
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
readonly ifAvailable?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Release any held lock of the same name and grant this request.
|
|
41
|
+
*
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
readonly steal?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Abort the request while it is pending.
|
|
47
|
+
*
|
|
48
|
+
* @default undefined
|
|
49
|
+
*/
|
|
50
|
+
readonly signal?: AbortSignal;
|
|
51
|
+
}
|
|
52
|
+
/** Minimal `LockManager` (`navigator.locks`) consumed by {@link useWebLocks}. */
|
|
53
|
+
interface LockManagerLike {
|
|
54
|
+
/** Request a lock and run `callback` while it is held. */
|
|
55
|
+
request(name: string, options: WebLockManagerRequestOptions, callback: (lock: WebLockLike | null) => unknown): Promise<unknown>;
|
|
56
|
+
/** Snapshot the origin's held and pending locks. */
|
|
57
|
+
query(): Promise<{
|
|
58
|
+
/** Held locks. */readonly held?: readonly WebLockInfo[] | undefined; /** Pending requests. */
|
|
59
|
+
readonly pending?: readonly WebLockInfo[] | undefined;
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
/** Options for {@link useWebLocks}. */
|
|
63
|
+
interface UseWebLocksOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Lock manager for alternate runtimes and tests.
|
|
66
|
+
*
|
|
67
|
+
* @default window.navigator.locks when it exists
|
|
68
|
+
*/
|
|
69
|
+
readonly locks?: MaybeRefOrGetter<LockManagerLike | null | undefined>;
|
|
70
|
+
}
|
|
71
|
+
/** Per-request options for {@link WebLocksControls.request}. */
|
|
72
|
+
interface WebLockRequestOptions {
|
|
73
|
+
/**
|
|
74
|
+
* Requested mode.
|
|
75
|
+
*
|
|
76
|
+
* @default "exclusive"
|
|
77
|
+
*/
|
|
78
|
+
readonly mode?: WebLockMode;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve with `{ acquired: false }` instead of waiting when the lock is busy.
|
|
81
|
+
*
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
readonly ifAvailable?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Preempt any holder of the lock (exclusive mode only).
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
readonly steal?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Abort the request while it is still pending.
|
|
93
|
+
*
|
|
94
|
+
* @default undefined
|
|
95
|
+
*/
|
|
96
|
+
readonly signal?: AbortSignal;
|
|
97
|
+
}
|
|
98
|
+
/** Outcome of an `ifAvailable` request. */
|
|
99
|
+
type WebLockAttempt<Value> = {
|
|
100
|
+
/** The lock was granted and the callback ran. */readonly acquired: true; /** Callback result. */
|
|
101
|
+
readonly value: Value;
|
|
102
|
+
} | {
|
|
103
|
+
/** The lock was busy; the callback did not run. */readonly acquired: false;
|
|
104
|
+
};
|
|
105
|
+
/** Request function exposed by {@link WebLocksControls}. */
|
|
106
|
+
interface WebLockRequest {
|
|
107
|
+
/**
|
|
108
|
+
* Request a lock that is only granted when immediately available.
|
|
109
|
+
*
|
|
110
|
+
* @param name Lock name.
|
|
111
|
+
* @param callback Work to run while the lock is held.
|
|
112
|
+
* @param options Request options with `ifAvailable: true`.
|
|
113
|
+
* @returns The callback result, or `{ acquired: false }` when busy.
|
|
114
|
+
*/
|
|
115
|
+
<Value>(name: string, callback: (lock: WebLockLike) => Value | PromiseLike<Value>, options: WebLockRequestOptions & {
|
|
116
|
+
readonly ifAvailable: true;
|
|
117
|
+
}): Promise<WebLockAttempt<Value>>;
|
|
118
|
+
/**
|
|
119
|
+
* Request a lock and run `callback` while it is held.
|
|
120
|
+
*
|
|
121
|
+
* @param name Lock name.
|
|
122
|
+
* @param callback Work to run while the lock is held.
|
|
123
|
+
* @param options Mode, steal and abort options.
|
|
124
|
+
* @returns The callback result.
|
|
125
|
+
*/
|
|
126
|
+
<Value>(name: string, callback: (lock: WebLockLike) => Value | PromiseLike<Value>, options?: WebLockRequestOptions & {
|
|
127
|
+
readonly ifAvailable?: false;
|
|
128
|
+
}): Promise<Value>;
|
|
129
|
+
}
|
|
130
|
+
/** Reactive state and actions returned by {@link useWebLocks}. */
|
|
131
|
+
interface WebLocksControls {
|
|
132
|
+
/** Whether the Web Locks API is available. */
|
|
133
|
+
readonly supported: ComputedRef<boolean>;
|
|
134
|
+
/** Names of locks requested through this composable that are currently held. */
|
|
135
|
+
readonly held: Readonly<Ref<readonly string[]>>;
|
|
136
|
+
/** Names of locks requested through this composable that are still waiting. */
|
|
137
|
+
readonly pending: Readonly<Ref<readonly string[]>>;
|
|
138
|
+
/** Most recent request failure (including aborts), cleared by the next grant. */
|
|
139
|
+
readonly error: Readonly<ShallowRef<unknown>>;
|
|
140
|
+
/**
|
|
141
|
+
* Request a lock. Rejects with a tagged `TypeError` for invalid option
|
|
142
|
+
* combinations, a tagged `Error` when unsupported, the host's `AbortError`
|
|
143
|
+
* when aborted, or the callback's rejection.
|
|
144
|
+
*/
|
|
145
|
+
readonly request: WebLockRequest;
|
|
146
|
+
/**
|
|
147
|
+
* Snapshot the origin's locks.
|
|
148
|
+
*
|
|
149
|
+
* @returns Held and pending locks; empty lists when unsupported or on failure.
|
|
150
|
+
*/
|
|
151
|
+
readonly query: () => Promise<WebLocksSnapshot>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Coordinate work across tabs and workers with the Web Locks API.
|
|
155
|
+
*
|
|
156
|
+
* `request` runs the callback while the named lock is held and resolves with
|
|
157
|
+
* its result; with `ifAvailable` it resolves with a discriminated
|
|
158
|
+
* `{ acquired }` outcome instead of waiting. `held` and `pending` track the
|
|
159
|
+
* lock names requested through this composable. Requests still waiting when
|
|
160
|
+
* the owning reactive scope stops are aborted; locks already held are
|
|
161
|
+
* released when their callbacks settle. Outside a scope, pass a `signal` to
|
|
162
|
+
* own cancellation.
|
|
163
|
+
*
|
|
164
|
+
* Server rendering: nothing is requested, `supported` is false and the name
|
|
165
|
+
* lists are empty.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* const locks = useWebLocks();
|
|
170
|
+
* await locks.request("sync", async () => syncOutbox());
|
|
171
|
+
* const attempt = await locks.request("leader", runLeader, { ifAvailable: true });
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* @param options Lock manager override.
|
|
175
|
+
* @default options {}
|
|
176
|
+
* @returns Lock state and actions.
|
|
177
|
+
*/
|
|
178
|
+
declare function useWebLocks(options?: UseWebLocksOptions): WebLocksControls;
|
|
179
|
+
//#endregion
|
|
180
|
+
export { LockManagerLike, UseWebLocksOptions, WebLockAttempt, WebLockInfo, WebLockLike, WebLockManagerRequestOptions, WebLockMode, WebLockRequest, WebLockRequestOptions, WebLocksControls, WebLocksSnapshot, useWebLocks };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { tryOnScopeDispose } from "./scope.mjs";
|
|
2
|
+
import { computed, hasInjectionContext, readonly, ref, shallowRef, toValue, watchPostEffect } from "vue";
|
|
3
|
+
//#region src/use-web-locks.ts
|
|
4
|
+
function browserLocks() {
|
|
5
|
+
if (typeof window === "undefined") return void 0;
|
|
6
|
+
const { navigator } = window;
|
|
7
|
+
return "locks" in navigator && navigator.locks ? navigator.locks : void 0;
|
|
8
|
+
}
|
|
9
|
+
function without(names, name) {
|
|
10
|
+
const index = names.indexOf(name);
|
|
11
|
+
return index === -1 ? names : [...names.slice(0, index), ...names.slice(index + 1)];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Coordinate work across tabs and workers with the Web Locks API.
|
|
15
|
+
*
|
|
16
|
+
* `request` runs the callback while the named lock is held and resolves with
|
|
17
|
+
* its result; with `ifAvailable` it resolves with a discriminated
|
|
18
|
+
* `{ acquired }` outcome instead of waiting. `held` and `pending` track the
|
|
19
|
+
* lock names requested through this composable. Requests still waiting when
|
|
20
|
+
* the owning reactive scope stops are aborted; locks already held are
|
|
21
|
+
* released when their callbacks settle. Outside a scope, pass a `signal` to
|
|
22
|
+
* own cancellation.
|
|
23
|
+
*
|
|
24
|
+
* Server rendering: nothing is requested, `supported` is false and the name
|
|
25
|
+
* lists are empty.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const locks = useWebLocks();
|
|
30
|
+
* await locks.request("sync", async () => syncOutbox());
|
|
31
|
+
* const attempt = await locks.request("leader", runLeader, { ifAvailable: true });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @param options Lock manager override.
|
|
35
|
+
* @default options {}
|
|
36
|
+
* @returns Lock state and actions.
|
|
37
|
+
*/
|
|
38
|
+
function useWebLocks(options = {}) {
|
|
39
|
+
const held = ref([]);
|
|
40
|
+
const pending = ref([]);
|
|
41
|
+
const error = shallowRef(void 0);
|
|
42
|
+
const controllers = /* @__PURE__ */ new Set();
|
|
43
|
+
const hydrated = shallowRef(!hasInjectionContext());
|
|
44
|
+
if (!hydrated.value) watchPostEffect(() => {
|
|
45
|
+
hydrated.value = true;
|
|
46
|
+
});
|
|
47
|
+
const resolveLocks = () => !hydrated.value ? void 0 : options.locks === void 0 ? browserLocks() : toValue(options.locks) ?? void 0;
|
|
48
|
+
const run = async (name, callback, requestOptions = {}) => {
|
|
49
|
+
const { mode = "exclusive", ifAvailable = false, steal = false, signal } = requestOptions;
|
|
50
|
+
if (ifAvailable && steal || steal && mode === "shared" || signal && (ifAvailable || steal)) throw new TypeError("[VIZE_COMPOSE_WEB_LOCKS_INVALID_OPTIONS] steal cannot be combined with ifAvailable, shared mode or signal, and signal cannot be combined with ifAvailable.");
|
|
51
|
+
const locks = resolveLocks();
|
|
52
|
+
if (!locks) throw new Error("[VIZE_COMPOSE_WEB_LOCKS_UNSUPPORTED] The Web Locks API is not available.");
|
|
53
|
+
const controller = ifAvailable || steal ? void 0 : new AbortController();
|
|
54
|
+
const forwardAbort = () => controller?.abort(signal?.reason);
|
|
55
|
+
if (controller) {
|
|
56
|
+
if (signal?.aborted) forwardAbort();
|
|
57
|
+
else signal?.addEventListener("abort", forwardAbort, { once: true });
|
|
58
|
+
controllers.add(controller);
|
|
59
|
+
}
|
|
60
|
+
pending.value = [...pending.value, name];
|
|
61
|
+
let granted = false;
|
|
62
|
+
const managerOptions = controller ? {
|
|
63
|
+
mode,
|
|
64
|
+
signal: controller.signal
|
|
65
|
+
} : {
|
|
66
|
+
mode,
|
|
67
|
+
ifAvailable,
|
|
68
|
+
steal
|
|
69
|
+
};
|
|
70
|
+
let outcome = { acquired: false };
|
|
71
|
+
try {
|
|
72
|
+
await locks.request(name, managerOptions, async (lock) => {
|
|
73
|
+
pending.value = without(pending.value, name);
|
|
74
|
+
if (controller) controllers.delete(controller);
|
|
75
|
+
if (!lock) return;
|
|
76
|
+
granted = true;
|
|
77
|
+
error.value = void 0;
|
|
78
|
+
held.value = [...held.value, name];
|
|
79
|
+
try {
|
|
80
|
+
outcome = {
|
|
81
|
+
acquired: true,
|
|
82
|
+
value: await callback(lock)
|
|
83
|
+
};
|
|
84
|
+
} finally {
|
|
85
|
+
held.value = without(held.value, name);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return outcome;
|
|
89
|
+
} catch (cause) {
|
|
90
|
+
error.value = cause;
|
|
91
|
+
throw cause;
|
|
92
|
+
} finally {
|
|
93
|
+
if (!granted) pending.value = without(pending.value, name);
|
|
94
|
+
if (controller) controllers.delete(controller);
|
|
95
|
+
signal?.removeEventListener("abort", forwardAbort);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const request = ((name, callback, requestOptions) => {
|
|
99
|
+
const attempt = run(name, callback, requestOptions);
|
|
100
|
+
return requestOptions?.ifAvailable ? attempt : attempt.then((outcome) => outcome.acquired ? outcome.value : void 0);
|
|
101
|
+
});
|
|
102
|
+
const query = async () => {
|
|
103
|
+
const locks = resolveLocks();
|
|
104
|
+
if (!locks) return {
|
|
105
|
+
held: [],
|
|
106
|
+
pending: []
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
const snapshot = await locks.query();
|
|
110
|
+
return {
|
|
111
|
+
held: snapshot.held ?? [],
|
|
112
|
+
pending: snapshot.pending ?? []
|
|
113
|
+
};
|
|
114
|
+
} catch (cause) {
|
|
115
|
+
error.value = cause;
|
|
116
|
+
return {
|
|
117
|
+
held: [],
|
|
118
|
+
pending: []
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
tryOnScopeDispose(() => {
|
|
123
|
+
for (const controller of controllers) controller.abort(new DOMException("The owning scope was disposed.", "AbortError"));
|
|
124
|
+
controllers.clear();
|
|
125
|
+
});
|
|
126
|
+
return {
|
|
127
|
+
supported: computed(() => resolveLocks() !== void 0),
|
|
128
|
+
held: readonly(held),
|
|
129
|
+
pending: readonly(pending),
|
|
130
|
+
error: readonly(error),
|
|
131
|
+
request,
|
|
132
|
+
query
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { useWebLocks };
|