@vizejs/composable 0.426.2 → 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,553 @@
|
|
|
1
|
+
import { readonly, shallowRef, toValue, unref, watch } from "vue";
|
|
2
|
+
import type { MaybeRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
|
|
3
|
+
|
|
4
|
+
import { calculateRetryDelay } from "./retry-delay.ts";
|
|
5
|
+
import type { RetryDelayOptions } from "./retry-delay.ts";
|
|
6
|
+
import { tryOnScopeDispose } from "./scope.ts";
|
|
7
|
+
import type { TimeoutScheduler } from "./timeout-scheduler.ts";
|
|
8
|
+
|
|
9
|
+
/** Raw payload delivered by a WebSocket `message` event. */
|
|
10
|
+
export type WebSocketRawData = string | ArrayBuffer | Blob;
|
|
11
|
+
|
|
12
|
+
/** Payload accepted by `WebSocket.send`. */
|
|
13
|
+
export type WebSocketSendData = string | Blob | BufferSource;
|
|
14
|
+
|
|
15
|
+
/** Connection status exposed by {@link useWebSocket}. */
|
|
16
|
+
export type WebSocketStatus = "connecting" | "open" | "closing" | "closed";
|
|
17
|
+
|
|
18
|
+
/** Minimal WebSocket instance used by {@link useWebSocket}. */
|
|
19
|
+
export interface WebSocketLike {
|
|
20
|
+
/** Transmit data over the open connection. */
|
|
21
|
+
readonly send: (data: WebSocketSendData) => void;
|
|
22
|
+
/** Start the closing handshake. */
|
|
23
|
+
readonly close: (code?: number, reason?: string) => void;
|
|
24
|
+
/** Subscribe to `open`, `message`, `error`, or `close`. */
|
|
25
|
+
addEventListener(type: "open" | "message" | "error" | "close", listener: EventListener): void;
|
|
26
|
+
/** Remove a listener registered with `addEventListener`. */
|
|
27
|
+
removeEventListener(type: "open" | "message" | "error" | "close", listener: EventListener): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Constructor creating {@link WebSocketLike} connections (e.g. `WebSocket`). */
|
|
31
|
+
export type WebSocketConstructorLike = new (
|
|
32
|
+
url: string,
|
|
33
|
+
protocols?: string | string[],
|
|
34
|
+
) => WebSocketLike;
|
|
35
|
+
|
|
36
|
+
/** Discriminated failure reported by {@link useWebSocket}. */
|
|
37
|
+
export type WebSocketFailure =
|
|
38
|
+
| {
|
|
39
|
+
/** The socket dispatched an `error` event. */
|
|
40
|
+
readonly kind: "error";
|
|
41
|
+
/** The dispatched event. */
|
|
42
|
+
readonly event: Event;
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
/** The constructor threw (invalid URL, blocked port, ...). */
|
|
46
|
+
readonly kind: "connect";
|
|
47
|
+
/** Exact thrown value. */
|
|
48
|
+
readonly cause: unknown;
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
/** `parse` threw for an incoming message. */
|
|
52
|
+
readonly kind: "parse";
|
|
53
|
+
/** Exact thrown value. */
|
|
54
|
+
readonly cause: unknown;
|
|
55
|
+
}
|
|
56
|
+
| {
|
|
57
|
+
/** `validate` rejected a parsed message. */
|
|
58
|
+
readonly kind: "invalid";
|
|
59
|
+
/** Rejected message. */
|
|
60
|
+
readonly data: unknown;
|
|
61
|
+
}
|
|
62
|
+
| {
|
|
63
|
+
/** Automatic reconnection gave up. */
|
|
64
|
+
readonly kind: "reconnect-exhausted";
|
|
65
|
+
/** Reconnection attempts performed. */
|
|
66
|
+
readonly attempts: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Options for automatic reconnection. */
|
|
70
|
+
export interface WebSocketReconnectOptions extends RetryDelayOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Maximum consecutive reconnection attempts.
|
|
73
|
+
*
|
|
74
|
+
* @default Infinity
|
|
75
|
+
*/
|
|
76
|
+
readonly retries?: number;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Called once reconnection gives up.
|
|
80
|
+
*
|
|
81
|
+
* @default undefined
|
|
82
|
+
*/
|
|
83
|
+
readonly onFailed?: () => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Options for the keep-alive heartbeat. */
|
|
87
|
+
export interface WebSocketHeartbeatOptions {
|
|
88
|
+
/**
|
|
89
|
+
* Raw ping payload.
|
|
90
|
+
*
|
|
91
|
+
* @default "ping"
|
|
92
|
+
*/
|
|
93
|
+
readonly message?: WebSocketSendData;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Incoming payload treated as a pong and not exposed as data.
|
|
97
|
+
*
|
|
98
|
+
* @default the ping message when it is a string
|
|
99
|
+
*/
|
|
100
|
+
readonly responseMessage?: string;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Delay between pings in milliseconds.
|
|
104
|
+
*
|
|
105
|
+
* @default 30000
|
|
106
|
+
*/
|
|
107
|
+
readonly intervalMs?: number;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Close (and possibly reconnect) when no message arrives this long after a ping.
|
|
111
|
+
*
|
|
112
|
+
* @default 10000
|
|
113
|
+
*/
|
|
114
|
+
readonly pongTimeoutMs?: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Options for {@link useWebSocket}.
|
|
119
|
+
*
|
|
120
|
+
* Callbacks that consume message types use method syntax so options typed
|
|
121
|
+
* for concrete messages remain assignable to the implementation signature.
|
|
122
|
+
*/
|
|
123
|
+
export interface UseWebSocketOptions<Incoming, Outgoing> {
|
|
124
|
+
/**
|
|
125
|
+
* Sub-protocols requested from the server.
|
|
126
|
+
*
|
|
127
|
+
* @default undefined
|
|
128
|
+
*/
|
|
129
|
+
readonly protocols?: string | string[];
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* WebSocket constructor (a plain value or ref; never a getter, because a
|
|
133
|
+
* constructor is itself a function). Supplying one also enables automatic
|
|
134
|
+
* connection outside a browser.
|
|
135
|
+
*
|
|
136
|
+
* @default window.WebSocket when a browser window exists
|
|
137
|
+
*/
|
|
138
|
+
readonly host?: MaybeRef<WebSocketConstructorLike | null | undefined>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Connect as soon as a URL is available (browser or explicit host only).
|
|
142
|
+
*
|
|
143
|
+
* @default true
|
|
144
|
+
*/
|
|
145
|
+
readonly immediate?: boolean;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Reconnect after unexpected closes with exponential backoff.
|
|
149
|
+
*
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
readonly autoReconnect?: boolean | WebSocketReconnectOptions;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Send periodic pings and drop connections whose peer stops answering.
|
|
156
|
+
*
|
|
157
|
+
* @default false
|
|
158
|
+
*/
|
|
159
|
+
readonly heartbeat?: boolean | WebSocketHeartbeatOptions;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Decode incoming payloads.
|
|
163
|
+
*
|
|
164
|
+
* @default the raw payload
|
|
165
|
+
*/
|
|
166
|
+
readonly parse?: (raw: WebSocketRawData) => Incoming;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Encode outgoing messages.
|
|
170
|
+
*
|
|
171
|
+
* @default sends payloads as-is and JSON-encodes anything else
|
|
172
|
+
*/
|
|
173
|
+
serialize?(message: Outgoing): WebSocketSendData;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Reject parsed messages that fail this check (`"invalid"` failure).
|
|
177
|
+
*
|
|
178
|
+
* @default accepts every message
|
|
179
|
+
*/
|
|
180
|
+
validate?(message: Incoming): boolean;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Queue messages sent while connecting and flush them on open.
|
|
184
|
+
*
|
|
185
|
+
* @default true
|
|
186
|
+
*/
|
|
187
|
+
readonly bufferWhileConnecting?: boolean;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Timer host for reconnection and heartbeat.
|
|
191
|
+
*
|
|
192
|
+
* @default globalThis timer functions
|
|
193
|
+
*/
|
|
194
|
+
readonly scheduler?: TimeoutScheduler;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Observe every accepted incoming message.
|
|
198
|
+
*
|
|
199
|
+
* @default undefined
|
|
200
|
+
*/
|
|
201
|
+
onMessage?(message: Incoming, event: Event): void;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Observe failures.
|
|
205
|
+
*
|
|
206
|
+
* @default undefined
|
|
207
|
+
*/
|
|
208
|
+
readonly onError?: (failure: WebSocketFailure) => void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Reactive state and controls returned by {@link useWebSocket}. */
|
|
212
|
+
export interface WebSocketControls<Incoming, Outgoing> {
|
|
213
|
+
/** Connection status. */
|
|
214
|
+
readonly status: Readonly<Ref<WebSocketStatus>>;
|
|
215
|
+
/** Latest accepted incoming message. */
|
|
216
|
+
readonly data: Readonly<ShallowRef<Incoming | undefined>>;
|
|
217
|
+
/** Latest failure, cleared when a connection opens. */
|
|
218
|
+
readonly error: Readonly<ShallowRef<WebSocketFailure | undefined>>;
|
|
219
|
+
/** Consecutive reconnection attempts since the last successful open. */
|
|
220
|
+
readonly reconnectAttempts: Readonly<Ref<number>>;
|
|
221
|
+
/** Current underlying socket, if any. */
|
|
222
|
+
readonly socket: Readonly<ShallowRef<WebSocketLike | undefined>>;
|
|
223
|
+
/**
|
|
224
|
+
* Send a message, or queue it while connecting.
|
|
225
|
+
*
|
|
226
|
+
* @returns Whether the message was sent or queued.
|
|
227
|
+
*/
|
|
228
|
+
send(message: Outgoing): boolean;
|
|
229
|
+
/** Open (or reopen) the connection and re-enable reconnection. */
|
|
230
|
+
readonly open: () => void;
|
|
231
|
+
/** Close the connection and disable automatic reconnection. */
|
|
232
|
+
readonly close: (code?: number, reason?: string) => void;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function browserWebSocket(): WebSocketConstructorLike | undefined {
|
|
236
|
+
return typeof window !== "undefined" && typeof window.WebSocket === "function"
|
|
237
|
+
? window.WebSocket
|
|
238
|
+
: undefined;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function toSendData(value: unknown): WebSocketSendData | undefined {
|
|
242
|
+
if (typeof value === "string" || value instanceof ArrayBuffer) return value;
|
|
243
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return value;
|
|
244
|
+
if (ArrayBuffer.isView(value) && value.buffer instanceof ArrayBuffer) {
|
|
245
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
246
|
+
}
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function isRawData(value: unknown): value is WebSocketRawData {
|
|
251
|
+
return (
|
|
252
|
+
typeof value === "string" ||
|
|
253
|
+
value instanceof ArrayBuffer ||
|
|
254
|
+
(typeof Blob !== "undefined" && value instanceof Blob)
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function defaultScheduler(): TimeoutScheduler {
|
|
259
|
+
return {
|
|
260
|
+
setTimeout: (callback, delayMs) => {
|
|
261
|
+
const handle = globalThis.setTimeout(callback, delayMs);
|
|
262
|
+
return () => globalThis.clearTimeout(handle);
|
|
263
|
+
},
|
|
264
|
+
clearTimeout: (cancel) => {
|
|
265
|
+
if (typeof cancel === "function") cancel();
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Open a WebSocket with raw payloads.
|
|
272
|
+
*
|
|
273
|
+
* @param url Reactive URL; `null`/`undefined` keeps the socket closed.
|
|
274
|
+
* @param options Connection options.
|
|
275
|
+
* @returns Reactive state and controls.
|
|
276
|
+
*/
|
|
277
|
+
export function useWebSocket(
|
|
278
|
+
url: MaybeRefOrGetter<string | URL | null | undefined>,
|
|
279
|
+
options?: UseWebSocketOptions<WebSocketRawData, WebSocketSendData>,
|
|
280
|
+
): WebSocketControls<WebSocketRawData, WebSocketSendData>;
|
|
281
|
+
/**
|
|
282
|
+
* Open a WebSocket with typed messages. `parse` is required unless raw
|
|
283
|
+
* payloads fit `Incoming`; `serialize` is required unless `Outgoing` is
|
|
284
|
+
* already sendable.
|
|
285
|
+
*
|
|
286
|
+
* @param url Reactive URL; `null`/`undefined` keeps the socket closed.
|
|
287
|
+
* @param options Connection options with codecs.
|
|
288
|
+
* @returns Reactive state and controls.
|
|
289
|
+
*/
|
|
290
|
+
export function useWebSocket<Incoming = WebSocketRawData, Outgoing = WebSocketSendData>(
|
|
291
|
+
url: MaybeRefOrGetter<string | URL | null | undefined>,
|
|
292
|
+
options: UseWebSocketOptions<Incoming, Outgoing> & WebSocketCodecRequirements<Incoming, Outgoing>,
|
|
293
|
+
): WebSocketControls<Incoming, Outgoing>;
|
|
294
|
+
/**
|
|
295
|
+
* Reactive WebSocket with typed messages, auto-reconnect, and heartbeat.
|
|
296
|
+
*
|
|
297
|
+
* Unexpected closes reconnect with exponential backoff when `autoReconnect`
|
|
298
|
+
* is enabled; `close()` is always final until `open()` is called again.
|
|
299
|
+
* Messages sent while connecting are queued. The connection and all timers
|
|
300
|
+
* are released when the owning reactive scope stops; outside a scope the
|
|
301
|
+
* caller owns `close()`. Server rendering never connects: automatic
|
|
302
|
+
* connection requires a browser or an explicit `host`, and status stays
|
|
303
|
+
* `"closed"`.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* const chat = useWebSocket<ChatEvent, ChatCommand>("wss://example.test/chat", {
|
|
308
|
+
* parse: (raw) => parseChatEvent(String(raw)),
|
|
309
|
+
* serialize: (command) => JSON.stringify(command),
|
|
310
|
+
* autoReconnect: { retries: 5 },
|
|
311
|
+
* heartbeat: true,
|
|
312
|
+
* });
|
|
313
|
+
* chat.send({ type: "join", room: "general" });
|
|
314
|
+
* ```
|
|
315
|
+
*
|
|
316
|
+
* @param url Reactive URL; changing it reconnects.
|
|
317
|
+
* @param options Codecs, reconnection, heartbeat, and host options.
|
|
318
|
+
* @default options {}
|
|
319
|
+
* @returns Reactive state and controls.
|
|
320
|
+
*/
|
|
321
|
+
export function useWebSocket(
|
|
322
|
+
url: MaybeRefOrGetter<string | URL | null | undefined>,
|
|
323
|
+
options: UseWebSocketOptions<unknown, unknown> = {},
|
|
324
|
+
): WebSocketControls<unknown, unknown> {
|
|
325
|
+
const status = shallowRef<WebSocketStatus>("closed");
|
|
326
|
+
const data = shallowRef<unknown>(undefined);
|
|
327
|
+
const error = shallowRef<WebSocketFailure | undefined>(undefined);
|
|
328
|
+
const reconnectAttempts = shallowRef(0);
|
|
329
|
+
const socket = shallowRef<WebSocketLike | undefined>(undefined);
|
|
330
|
+
const scheduler = options.scheduler ?? defaultScheduler();
|
|
331
|
+
const reconnect = options.autoReconnect === true ? {} : options.autoReconnect || undefined;
|
|
332
|
+
const heartbeat = options.heartbeat === true ? {} : options.heartbeat || undefined;
|
|
333
|
+
const pingMessage = heartbeat?.message ?? "ping";
|
|
334
|
+
const pongMessage =
|
|
335
|
+
heartbeat?.responseMessage ?? (typeof pingMessage === "string" ? pingMessage : undefined);
|
|
336
|
+
const buffer: WebSocketSendData[] = [];
|
|
337
|
+
let manuallyClosed = false;
|
|
338
|
+
let reconnectTimer: unknown;
|
|
339
|
+
let pingTimer: unknown;
|
|
340
|
+
let pongTimer: unknown;
|
|
341
|
+
let detach: (() => void) | undefined;
|
|
342
|
+
|
|
343
|
+
const resolveHost = (): WebSocketConstructorLike | undefined =>
|
|
344
|
+
options.host === undefined ? browserWebSocket() : (unref(options.host) ?? undefined);
|
|
345
|
+
|
|
346
|
+
const fail = (failure: WebSocketFailure): void => {
|
|
347
|
+
error.value = failure;
|
|
348
|
+
options.onError?.(failure);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const clearTimer = (handle: unknown): undefined => {
|
|
352
|
+
if (handle !== undefined) scheduler.clearTimeout(handle);
|
|
353
|
+
return undefined;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
const stopHeartbeat = (): void => {
|
|
357
|
+
pingTimer = clearTimer(pingTimer);
|
|
358
|
+
pongTimer = clearTimer(pongTimer);
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const serialize = (message: unknown): WebSocketSendData =>
|
|
362
|
+
options.serialize
|
|
363
|
+
? options.serialize(message)
|
|
364
|
+
: (toSendData(message) ?? JSON.stringify(message));
|
|
365
|
+
|
|
366
|
+
const schedulePing = (target: WebSocketLike): void => {
|
|
367
|
+
if (!heartbeat) return;
|
|
368
|
+
pingTimer = scheduler.setTimeout(() => {
|
|
369
|
+
pingTimer = undefined;
|
|
370
|
+
target.send(pingMessage);
|
|
371
|
+
pongTimer = clearTimer(pongTimer);
|
|
372
|
+
pongTimer = scheduler.setTimeout(() => {
|
|
373
|
+
pongTimer = undefined;
|
|
374
|
+
target.close();
|
|
375
|
+
}, heartbeat.pongTimeoutMs ?? 10_000);
|
|
376
|
+
schedulePing(target);
|
|
377
|
+
}, heartbeat.intervalMs ?? 30_000);
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const teardown = (): void => {
|
|
381
|
+
stopHeartbeat();
|
|
382
|
+
detach?.();
|
|
383
|
+
detach = undefined;
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const scheduleReconnect = (): void => {
|
|
387
|
+
if (!reconnect || manuallyClosed) return;
|
|
388
|
+
const retries = reconnect.retries ?? Number.POSITIVE_INFINITY;
|
|
389
|
+
if (reconnectAttempts.value >= retries) {
|
|
390
|
+
fail({ kind: "reconnect-exhausted", attempts: reconnectAttempts.value });
|
|
391
|
+
reconnect.onFailed?.();
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
reconnectAttempts.value += 1;
|
|
395
|
+
const delay = calculateRetryDelay(reconnectAttempts.value, reconnect);
|
|
396
|
+
reconnectTimer = scheduler.setTimeout(() => {
|
|
397
|
+
reconnectTimer = undefined;
|
|
398
|
+
connect();
|
|
399
|
+
}, delay);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const connect = (): void => {
|
|
403
|
+
reconnectTimer = clearTimer(reconnectTimer);
|
|
404
|
+
const current = socket.value;
|
|
405
|
+
if (current) {
|
|
406
|
+
teardown();
|
|
407
|
+
current.close();
|
|
408
|
+
socket.value = undefined;
|
|
409
|
+
}
|
|
410
|
+
const target = toValue(url);
|
|
411
|
+
const Host = resolveHost();
|
|
412
|
+
if (target === null || target === undefined || Host === undefined) {
|
|
413
|
+
status.value = "closed";
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
let instance: WebSocketLike;
|
|
417
|
+
try {
|
|
418
|
+
instance =
|
|
419
|
+
options.protocols === undefined
|
|
420
|
+
? new Host(String(target))
|
|
421
|
+
: new Host(String(target), options.protocols);
|
|
422
|
+
} catch (cause) {
|
|
423
|
+
status.value = "closed";
|
|
424
|
+
fail({ kind: "connect", cause });
|
|
425
|
+
scheduleReconnect();
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
socket.value = instance;
|
|
429
|
+
status.value = "connecting";
|
|
430
|
+
|
|
431
|
+
const onOpen = (): void => {
|
|
432
|
+
status.value = "open";
|
|
433
|
+
error.value = undefined;
|
|
434
|
+
reconnectAttempts.value = 0;
|
|
435
|
+
for (const queued of buffer.splice(0)) instance.send(queued);
|
|
436
|
+
schedulePing(instance);
|
|
437
|
+
};
|
|
438
|
+
const onMessage = (event: Event): void => {
|
|
439
|
+
pongTimer = clearTimer(pongTimer);
|
|
440
|
+
const raw: unknown = "data" in event ? event.data : undefined;
|
|
441
|
+
if (!isRawData(raw)) return;
|
|
442
|
+
if (heartbeat && pongMessage !== undefined && raw === pongMessage) return;
|
|
443
|
+
let message: unknown;
|
|
444
|
+
try {
|
|
445
|
+
message = options.parse ? options.parse(raw) : raw;
|
|
446
|
+
} catch (cause) {
|
|
447
|
+
fail({ kind: "parse", cause });
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (options.validate && !options.validate(message)) {
|
|
451
|
+
fail({ kind: "invalid", data: message });
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
data.value = message;
|
|
455
|
+
options.onMessage?.(message, event);
|
|
456
|
+
};
|
|
457
|
+
const onError = (event: Event): void => fail({ kind: "error", event });
|
|
458
|
+
const onClose = (): void => {
|
|
459
|
+
teardown();
|
|
460
|
+
if (socket.value === instance) socket.value = undefined;
|
|
461
|
+
status.value = "closed";
|
|
462
|
+
scheduleReconnect();
|
|
463
|
+
};
|
|
464
|
+
instance.addEventListener("open", onOpen);
|
|
465
|
+
instance.addEventListener("message", onMessage);
|
|
466
|
+
instance.addEventListener("error", onError);
|
|
467
|
+
instance.addEventListener("close", onClose);
|
|
468
|
+
detach = () => {
|
|
469
|
+
instance.removeEventListener("open", onOpen);
|
|
470
|
+
instance.removeEventListener("message", onMessage);
|
|
471
|
+
instance.removeEventListener("error", onError);
|
|
472
|
+
instance.removeEventListener("close", onClose);
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const open = (): void => {
|
|
477
|
+
manuallyClosed = false;
|
|
478
|
+
reconnectAttempts.value = 0;
|
|
479
|
+
connect();
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
const close = (code?: number, reason?: string): void => {
|
|
483
|
+
manuallyClosed = true;
|
|
484
|
+
reconnectTimer = clearTimer(reconnectTimer);
|
|
485
|
+
buffer.length = 0;
|
|
486
|
+
const current = socket.value;
|
|
487
|
+
teardown();
|
|
488
|
+
socket.value = undefined;
|
|
489
|
+
if (!current) {
|
|
490
|
+
status.value = "closed";
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
status.value = "closing";
|
|
494
|
+
current.close(code, reason);
|
|
495
|
+
status.value = "closed";
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const send = (message: unknown): boolean => {
|
|
499
|
+
const payload = serialize(message);
|
|
500
|
+
if (status.value === "open" && socket.value) {
|
|
501
|
+
socket.value.send(payload);
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
if (status.value === "connecting" && (options.bufferWhileConnecting ?? true)) {
|
|
505
|
+
buffer.push(payload);
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
return false;
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
const automatic = options.host !== undefined || typeof window !== "undefined";
|
|
512
|
+
if (automatic) {
|
|
513
|
+
let initial = true;
|
|
514
|
+
const stop = watch(
|
|
515
|
+
[() => toValue(url), resolveHost],
|
|
516
|
+
([target]) => {
|
|
517
|
+
const first = initial;
|
|
518
|
+
initial = false;
|
|
519
|
+
if (first && !(options.immediate ?? true)) return;
|
|
520
|
+
if (!first && socket.value === undefined && reconnectTimer === undefined) return;
|
|
521
|
+
if (target === null || target === undefined) close();
|
|
522
|
+
else open();
|
|
523
|
+
},
|
|
524
|
+
{ immediate: true },
|
|
525
|
+
);
|
|
526
|
+
tryOnScopeDispose(stop);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
tryOnScopeDispose(() => close());
|
|
530
|
+
|
|
531
|
+
return {
|
|
532
|
+
status: readonly(status),
|
|
533
|
+
data,
|
|
534
|
+
error,
|
|
535
|
+
reconnectAttempts: readonly(reconnectAttempts),
|
|
536
|
+
socket,
|
|
537
|
+
send,
|
|
538
|
+
open,
|
|
539
|
+
close,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Codec options that become mandatory when the defaults cannot produce the
|
|
545
|
+
* message types: `parse` unless raw payloads fit `Incoming`, `serialize`
|
|
546
|
+
* unless `Outgoing` is already sendable.
|
|
547
|
+
*/
|
|
548
|
+
export type WebSocketCodecRequirements<Incoming, Outgoing> = ([WebSocketRawData] extends [Incoming]
|
|
549
|
+
? unknown
|
|
550
|
+
: { readonly parse: (raw: WebSocketRawData) => Incoming }) &
|
|
551
|
+
([Outgoing] extends [WebSocketSendData]
|
|
552
|
+
? unknown
|
|
553
|
+
: { readonly serialize: (message: Outgoing) => WebSocketSendData });
|