@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,253 @@
|
|
|
1
|
+
import { shallowRef, toValue, watch } from "vue";
|
|
2
|
+
import type { MaybeRefOrGetter, ShallowRef } from "vue";
|
|
3
|
+
|
|
4
|
+
import { tryOnScopeDispose } from "./scope.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Repeating timer host used by {@link useIntervalFn} and the clocks built
|
|
8
|
+
* on it.
|
|
9
|
+
*
|
|
10
|
+
* Implement this interface to integrate a deterministic test clock, a native
|
|
11
|
+
* runtime timer, or an application-owned scheduler. Handles are opaque: they
|
|
12
|
+
* are only handed back to {@link IntervalScheduler.clearInterval}.
|
|
13
|
+
*/
|
|
14
|
+
export interface IntervalScheduler {
|
|
15
|
+
/** Starts a repeating callback and returns its opaque cancellation handle. */
|
|
16
|
+
readonly setInterval: (callback: () => void, intervalMs: number) => unknown;
|
|
17
|
+
|
|
18
|
+
/** Cancels a handle previously returned by {@link IntervalScheduler.setInterval}. */
|
|
19
|
+
readonly clearInterval: (handle: unknown) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Pause/resume controls shared by the repeating timing composables. */
|
|
23
|
+
export interface PausableControls {
|
|
24
|
+
/**
|
|
25
|
+
* Whether the timer is logically running.
|
|
26
|
+
*
|
|
27
|
+
* On the server (without `runOnServer`) this reflects the requested state
|
|
28
|
+
* without starting a host timer, so server and client render the same
|
|
29
|
+
* initial value.
|
|
30
|
+
*/
|
|
31
|
+
readonly isActive: Readonly<ShallowRef<boolean>>;
|
|
32
|
+
|
|
33
|
+
/** Stop ticking. Idempotent. */
|
|
34
|
+
readonly pause: () => void;
|
|
35
|
+
|
|
36
|
+
/** Start (or keep) ticking. Idempotent. */
|
|
37
|
+
readonly resume: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Options for {@link useIntervalFn}. */
|
|
41
|
+
export interface UseIntervalFnOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Start ticking as soon as the composable is created.
|
|
44
|
+
*
|
|
45
|
+
* @default true
|
|
46
|
+
*/
|
|
47
|
+
readonly immediate?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Invoke the callback synchronously whenever the timer (re)starts, in
|
|
51
|
+
* addition to every tick.
|
|
52
|
+
*
|
|
53
|
+
* @default false
|
|
54
|
+
*/
|
|
55
|
+
readonly immediateCallback?: boolean;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Starts host timers when no browser `window` is available.
|
|
59
|
+
*
|
|
60
|
+
* Keep this disabled during server rendering: the controls then track the
|
|
61
|
+
* requested state but never schedule work. Enable it for native, desktop,
|
|
62
|
+
* worker, and test runtimes whose scheduler is lifecycle-bound.
|
|
63
|
+
*
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
readonly runOnServer?: boolean;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Owns the repeating timer.
|
|
70
|
+
*
|
|
71
|
+
* @default globalThis timer functions
|
|
72
|
+
*/
|
|
73
|
+
readonly scheduler?: IntervalScheduler;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Options for {@link useInterval}. */
|
|
77
|
+
export interface UseIntervalOptions<Controls extends boolean = false> extends UseIntervalFnOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Return the full control object instead of the bare counter ref.
|
|
80
|
+
*
|
|
81
|
+
* @default false
|
|
82
|
+
*/
|
|
83
|
+
readonly controls?: Controls;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Invoked after every increment with the new count.
|
|
87
|
+
*
|
|
88
|
+
* @default undefined
|
|
89
|
+
*/
|
|
90
|
+
readonly callback?: (count: number) => void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Counter and controls returned by `useInterval(ms, { controls: true })`. */
|
|
94
|
+
export interface IntervalControls extends PausableControls {
|
|
95
|
+
/** Number of ticks since creation or the last {@link IntervalControls.reset}. */
|
|
96
|
+
readonly counter: Readonly<ShallowRef<number>>;
|
|
97
|
+
|
|
98
|
+
/** Reset the counter to zero without touching the timer. */
|
|
99
|
+
readonly reset: () => void;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const defaultScheduler: IntervalScheduler = {
|
|
103
|
+
setInterval: (callback, intervalMs) => globalThis.setInterval(callback, intervalMs),
|
|
104
|
+
clearInterval: (handle) => {
|
|
105
|
+
globalThis.clearInterval(handle as ReturnType<typeof setInterval>);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
function resolveIntervalMs(value: number): number {
|
|
110
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
111
|
+
throw new RangeError(
|
|
112
|
+
`[VIZE_COMPOSE_INTERVAL_INVALID_DELAY] intervalMs must be finite and greater than zero; received ${String(value)}`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return Math.max(1, Math.trunc(value));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Call a function on a fixed, pausable interval.
|
|
120
|
+
*
|
|
121
|
+
* `intervalMs` is reactive: while active, a change replaces the running timer
|
|
122
|
+
* with one using the new period. The timer is cleared when the owning
|
|
123
|
+
* reactive scope stops; call inside an active scope, or call `pause()`
|
|
124
|
+
* yourself.
|
|
125
|
+
*
|
|
126
|
+
* Server rendering is hydration-stable: without a browser `window` (and
|
|
127
|
+
* with {@link UseIntervalFnOptions.runOnServer} disabled) `isActive` reports
|
|
128
|
+
* the requested state but no host timer is created, so nothing leaks and
|
|
129
|
+
* the server snapshot matches the client's initial render.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const { pause, resume, isActive } = useIntervalFn(() => poll(), 5_000);
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @param callback Invoked on every tick.
|
|
137
|
+
* @param intervalMs Reactive period in milliseconds; must be finite and
|
|
138
|
+
* greater than zero. Fractions are truncated.
|
|
139
|
+
* @param options Start, server, and scheduler policy.
|
|
140
|
+
* @default options {}
|
|
141
|
+
* @throws `RangeError` tagged `VIZE_COMPOSE_INTERVAL_INVALID_DELAY` when the
|
|
142
|
+
* resolved period is invalid, synchronously at creation and whenever a timer
|
|
143
|
+
* would start.
|
|
144
|
+
* @returns Pause/resume controls.
|
|
145
|
+
*/
|
|
146
|
+
export function useIntervalFn(
|
|
147
|
+
callback: () => void,
|
|
148
|
+
intervalMs: MaybeRefOrGetter<number>,
|
|
149
|
+
options: UseIntervalFnOptions = {},
|
|
150
|
+
): PausableControls {
|
|
151
|
+
const scheduler = options.scheduler ?? defaultScheduler;
|
|
152
|
+
const isActive = shallowRef(false);
|
|
153
|
+
let handle: unknown;
|
|
154
|
+
let running = false;
|
|
155
|
+
|
|
156
|
+
resolveIntervalMs(toValue(intervalMs));
|
|
157
|
+
|
|
158
|
+
const canSchedule = (): boolean =>
|
|
159
|
+
typeof window !== "undefined" || (options.runOnServer ?? false);
|
|
160
|
+
|
|
161
|
+
const clear = (): void => {
|
|
162
|
+
if (!running) return;
|
|
163
|
+
running = false;
|
|
164
|
+
scheduler.clearInterval(handle);
|
|
165
|
+
handle = undefined;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const start = (): void => {
|
|
169
|
+
const period = resolveIntervalMs(toValue(intervalMs));
|
|
170
|
+
clear();
|
|
171
|
+
if (!canSchedule()) return;
|
|
172
|
+
if (options.immediateCallback ?? false) callback();
|
|
173
|
+
if (!isActive.value) return;
|
|
174
|
+
running = true;
|
|
175
|
+
handle = scheduler.setInterval(callback, period);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const pause = (): void => {
|
|
179
|
+
isActive.value = false;
|
|
180
|
+
clear();
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const resume = (): void => {
|
|
184
|
+
if (isActive.value) return;
|
|
185
|
+
isActive.value = true;
|
|
186
|
+
start();
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
watch(
|
|
190
|
+
() => toValue(intervalMs),
|
|
191
|
+
() => {
|
|
192
|
+
if (isActive.value) start();
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (options.immediate ?? true) resume();
|
|
197
|
+
|
|
198
|
+
tryOnScopeDispose(pause);
|
|
199
|
+
|
|
200
|
+
return { isActive, pause, resume };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Count interval ticks reactively.
|
|
205
|
+
*
|
|
206
|
+
* A thin wrapper over {@link useIntervalFn} whose state is a counter. Pass
|
|
207
|
+
* `{ controls: true }` to receive pause/resume/reset alongside the counter;
|
|
208
|
+
* the return type follows the literal flag.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* const ticks = useInterval(1_000); // Readonly<ShallowRef<number>>
|
|
213
|
+
* const { counter, pause, reset } = useInterval(1_000, { controls: true });
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @param intervalMs Reactive period in milliseconds.
|
|
217
|
+
* @param options Interval options plus the `controls` flag.
|
|
218
|
+
* @default intervalMs 1000
|
|
219
|
+
* @default options {}
|
|
220
|
+
* @throws `RangeError` tagged `VIZE_COMPOSE_INTERVAL_INVALID_DELAY` for
|
|
221
|
+
* invalid periods (see {@link useIntervalFn}).
|
|
222
|
+
* @returns The counter ref, or the full controls when `controls` is `true`.
|
|
223
|
+
*/
|
|
224
|
+
export function useInterval(
|
|
225
|
+
intervalMs?: MaybeRefOrGetter<number>,
|
|
226
|
+
options?: UseIntervalOptions<false>,
|
|
227
|
+
): Readonly<ShallowRef<number>>;
|
|
228
|
+
export function useInterval(
|
|
229
|
+
intervalMs: MaybeRefOrGetter<number>,
|
|
230
|
+
options: UseIntervalOptions<true>,
|
|
231
|
+
): IntervalControls;
|
|
232
|
+
export function useInterval(
|
|
233
|
+
intervalMs: MaybeRefOrGetter<number> = 1_000,
|
|
234
|
+
options: UseIntervalOptions<boolean> = {},
|
|
235
|
+
): Readonly<ShallowRef<number>> | IntervalControls {
|
|
236
|
+
const counter = shallowRef(0);
|
|
237
|
+
const controls = useIntervalFn(
|
|
238
|
+
() => {
|
|
239
|
+
counter.value += 1;
|
|
240
|
+
options.callback?.(counter.value);
|
|
241
|
+
},
|
|
242
|
+
intervalMs,
|
|
243
|
+
options,
|
|
244
|
+
);
|
|
245
|
+
if (options.controls !== true) return counter;
|
|
246
|
+
return {
|
|
247
|
+
...controls,
|
|
248
|
+
counter,
|
|
249
|
+
reset: () => {
|
|
250
|
+
counter.value = 0;
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { computed, toValue } from "vue";
|
|
2
|
+
import type { ComputedRef, MaybeRefOrGetter } from "vue";
|
|
3
|
+
|
|
4
|
+
import { useLocale } from "./locale.ts";
|
|
5
|
+
|
|
6
|
+
/** Options for {@link useListFormat}. */
|
|
7
|
+
export interface UseListFormatOptions extends Intl.ListFormatOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Locale used for formatting. Pass it explicitly for hydration-stable
|
|
10
|
+
* server rendering.
|
|
11
|
+
*
|
|
12
|
+
* @default the browser language, otherwise "en"
|
|
13
|
+
*/
|
|
14
|
+
readonly locale?: string | Intl.Locale;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Reactive list formatting returned by {@link useListFormat}. */
|
|
18
|
+
export interface ListFormatControls {
|
|
19
|
+
/** Canonical locale in use. */
|
|
20
|
+
readonly locale: ComputedRef<string>;
|
|
21
|
+
|
|
22
|
+
/** Cached formatter for the current locale and options. */
|
|
23
|
+
readonly formatter: ComputedRef<Intl.ListFormat>;
|
|
24
|
+
|
|
25
|
+
/** Formatted list, for example `"apples, pears, and plums"`. */
|
|
26
|
+
readonly formatted: ComputedRef<string>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Format any list with the current formatter.
|
|
30
|
+
*
|
|
31
|
+
* @param items Items to join.
|
|
32
|
+
* @returns The formatted list.
|
|
33
|
+
*/
|
|
34
|
+
readonly format: (items: Iterable<string>) => string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Format any list into element and literal parts (for rich rendering).
|
|
38
|
+
*
|
|
39
|
+
* @param items Items to join.
|
|
40
|
+
* @returns The formatted parts.
|
|
41
|
+
*/
|
|
42
|
+
readonly formatToParts: (
|
|
43
|
+
items: Iterable<string>,
|
|
44
|
+
) => { type: "element" | "literal"; value: string }[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function browserLanguage(): string | undefined {
|
|
48
|
+
return typeof window === "undefined" ? undefined : window.navigator.language;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Join strings into a locale-aware list with `Intl.ListFormat`
|
|
53
|
+
* (`"a, b, and c"`, `"a、b、c"`, `"a, b or c"`).
|
|
54
|
+
*
|
|
55
|
+
* Follows reactive items and options; formatters are cached per locale and
|
|
56
|
+
* option set through {@link useLocale}. Invalid options surface as the
|
|
57
|
+
* platform's `RangeError`. No listeners or timers are created.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const { formatted } = useListFormat(names, { locale: "en", type: "disjunction" });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @param items Reactive list of strings.
|
|
65
|
+
* @param options Reactive locale and `Intl.ListFormat` options.
|
|
66
|
+
* @default options {}
|
|
67
|
+
* @returns Reactive formatted output and formatting helpers.
|
|
68
|
+
*/
|
|
69
|
+
export function useListFormat(
|
|
70
|
+
items: MaybeRefOrGetter<readonly string[]>,
|
|
71
|
+
options: MaybeRefOrGetter<UseListFormatOptions> = {},
|
|
72
|
+
): ListFormatControls {
|
|
73
|
+
const localeControls = useLocale(() => toValue(options).locale, { detect: browserLanguage });
|
|
74
|
+
const formatter = computed(() => {
|
|
75
|
+
const { locale: _locale, ...formatOptions } = toValue(options);
|
|
76
|
+
return localeControls.list(formatOptions);
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
locale: localeControls.locale,
|
|
80
|
+
formatter,
|
|
81
|
+
formatted: computed(() => formatter.value.format(toValue(items))),
|
|
82
|
+
format: (list) => formatter.value.format(list),
|
|
83
|
+
formatToParts: (list) => formatter.value.formatToParts(list),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { computed, shallowRef } from "vue";
|
|
2
|
+
import type { ComputedRef, ShallowRef } from "vue";
|
|
3
|
+
|
|
4
|
+
/** Guarded, effectful transition to `target`. */
|
|
5
|
+
export interface MachineTransition<State extends string, Context> {
|
|
6
|
+
/** State entered when the transition is taken. */
|
|
7
|
+
readonly target: State;
|
|
8
|
+
|
|
9
|
+
/** Take the transition only when this returns `true`. */
|
|
10
|
+
readonly guard?: (context: Context) => boolean;
|
|
11
|
+
|
|
12
|
+
/** Produce the next context while transitioning. */
|
|
13
|
+
readonly action?: (context: Context) => Context;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** One state of a {@link MachineConfig}. */
|
|
17
|
+
export interface MachineStateNode<State extends string, Event extends string, Context> {
|
|
18
|
+
/**
|
|
19
|
+
* Transitions keyed by event: a target state name, one transition object,
|
|
20
|
+
* or a list of guarded transitions where the first passing guard wins.
|
|
21
|
+
*/
|
|
22
|
+
readonly on?: {
|
|
23
|
+
readonly [Name in Event]?:
|
|
24
|
+
| State
|
|
25
|
+
| MachineTransition<State, Context>
|
|
26
|
+
| readonly MachineTransition<State, Context>[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Called with the context after the machine enters this state. */
|
|
30
|
+
readonly entry?: (context: Context) => void;
|
|
31
|
+
|
|
32
|
+
/** Called with the context before the machine leaves this state. */
|
|
33
|
+
readonly exit?: (context: Context) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Definition consumed by {@link useMachine}. */
|
|
37
|
+
export interface MachineConfig<State extends string, Event extends string, Context> {
|
|
38
|
+
/** State the machine starts (and resets) in. */
|
|
39
|
+
readonly initial: NoInfer<State>;
|
|
40
|
+
|
|
41
|
+
/** Initial extended state. */
|
|
42
|
+
readonly context: Context;
|
|
43
|
+
|
|
44
|
+
/** Every state, keyed by name. */
|
|
45
|
+
readonly states: { readonly [Name in State]: MachineStateNode<NoInfer<State>, Event, Context> };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Reactive machine returned by {@link useMachine}. */
|
|
49
|
+
export interface Machine<State extends string, Event extends string, Context> {
|
|
50
|
+
/** Current state name. */
|
|
51
|
+
readonly state: Readonly<ShallowRef<State>>;
|
|
52
|
+
|
|
53
|
+
/** Current extended state. */
|
|
54
|
+
readonly context: Readonly<ShallowRef<Context>>;
|
|
55
|
+
|
|
56
|
+
/** Events that would cause a transition from the current state right now. */
|
|
57
|
+
readonly nextEvents: ComputedRef<Event[]>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Deliver an event.
|
|
61
|
+
*
|
|
62
|
+
* @returns Whether a transition was taken.
|
|
63
|
+
*/
|
|
64
|
+
readonly send: (event: Event) => boolean;
|
|
65
|
+
|
|
66
|
+
/** Whether `event` would cause a transition right now (guards included). */
|
|
67
|
+
readonly can: (event: Event) => boolean;
|
|
68
|
+
|
|
69
|
+
/** Whether the current state is one of `states`. */
|
|
70
|
+
readonly matches: (...states: readonly State[]) => boolean;
|
|
71
|
+
|
|
72
|
+
/** Return to the initial state and context without running hooks. */
|
|
73
|
+
readonly reset: () => void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Shallow ref typed through an unconstrained parameter, so literal unions stay intact. */
|
|
77
|
+
function ownedRef<Value>(value: Value): ShallowRef<Value> {
|
|
78
|
+
return shallowRef(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Finite state machine with typed states, events, and targets.
|
|
83
|
+
*
|
|
84
|
+
* State names are inferred from the keys of `states`, event names from the
|
|
85
|
+
* keys of every `on` map, and every `target` (and `initial`) must name a
|
|
86
|
+
* declared state, so typos fail to compile. Transitions may carry guards
|
|
87
|
+
* (first passing guard wins) and actions that return the next context;
|
|
88
|
+
* `exit` runs on the old state before `entry` runs on the new one, and a
|
|
89
|
+
* self-transition runs both. Synchronous and free of globals: identical on
|
|
90
|
+
* server and client, nothing to dispose.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const fetcher = useMachine({
|
|
95
|
+
* initial: "idle",
|
|
96
|
+
* context: { retries: 0 },
|
|
97
|
+
* states: {
|
|
98
|
+
* idle: { on: { FETCH: "loading" } },
|
|
99
|
+
* loading: { on: { RESOLVE: "success", REJECT: "failure" } },
|
|
100
|
+
* failure: {
|
|
101
|
+
* on: {
|
|
102
|
+
* RETRY: { target: "loading", guard: (c) => c.retries < 3, action: (c) => ({ retries: c.retries + 1 }) },
|
|
103
|
+
* },
|
|
104
|
+
* },
|
|
105
|
+
* success: {},
|
|
106
|
+
* },
|
|
107
|
+
* });
|
|
108
|
+
* fetcher.send("FETCH");
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @param config States, events, context, and hooks.
|
|
112
|
+
* @returns The reactive machine.
|
|
113
|
+
*/
|
|
114
|
+
export function useMachine<State extends string, Event extends string = never, Context = undefined>(
|
|
115
|
+
config: MachineConfig<State, Event, Context>,
|
|
116
|
+
): Machine<State, Event, Context> {
|
|
117
|
+
const state = ownedRef<State>(config.initial);
|
|
118
|
+
const context = ownedRef<Context>(config.context);
|
|
119
|
+
|
|
120
|
+
const isTarget = (
|
|
121
|
+
option:
|
|
122
|
+
| State
|
|
123
|
+
| MachineTransition<State, Context>
|
|
124
|
+
| readonly MachineTransition<State, Context>[],
|
|
125
|
+
): option is State => typeof option === "string";
|
|
126
|
+
|
|
127
|
+
const resolve = (event: Event): MachineTransition<State, Context> | undefined => {
|
|
128
|
+
const node: MachineStateNode<State, Event, Context> = config.states[state.value];
|
|
129
|
+
const option = node.on?.[event];
|
|
130
|
+
if (option === undefined) return undefined;
|
|
131
|
+
if (isTarget(option)) return { target: option };
|
|
132
|
+
const candidates: readonly MachineTransition<State, Context>[] = Array.isArray(option)
|
|
133
|
+
? option
|
|
134
|
+
: [option];
|
|
135
|
+
return candidates.find((candidate) => candidate.guard?.(context.value) ?? true);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const send = (event: Event): boolean => {
|
|
139
|
+
const transition = resolve(event);
|
|
140
|
+
if (transition === undefined) return false;
|
|
141
|
+
const leaving: MachineStateNode<State, Event, Context> = config.states[state.value];
|
|
142
|
+
leaving.exit?.(context.value);
|
|
143
|
+
if (transition.action !== undefined) context.value = transition.action(context.value);
|
|
144
|
+
state.value = transition.target;
|
|
145
|
+
const entering: MachineStateNode<State, Event, Context> = config.states[transition.target];
|
|
146
|
+
entering.entry?.(context.value);
|
|
147
|
+
return true;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const can = (event: Event): boolean => resolve(event) !== undefined;
|
|
151
|
+
|
|
152
|
+
const nextEvents = computed(() => {
|
|
153
|
+
const node: MachineStateNode<State, Event, Context> = config.states[state.value];
|
|
154
|
+
const on = node.on ?? {};
|
|
155
|
+
const isEvent = (name: string): name is Event => name in on;
|
|
156
|
+
return Object.keys(on).filter(isEvent).filter(can);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
state,
|
|
161
|
+
context,
|
|
162
|
+
nextEvents,
|
|
163
|
+
send,
|
|
164
|
+
can,
|
|
165
|
+
matches: (...states) => states.some((candidate) => candidate === state.value),
|
|
166
|
+
reset: () => {
|
|
167
|
+
state.value = config.initial;
|
|
168
|
+
context.value = config.context;
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { computed, shallowReactive, shallowReadonly } from "vue";
|
|
2
|
+
import type { ComputedRef } from "vue";
|
|
3
|
+
|
|
4
|
+
/** Reactive map wrapper returned by {@link useMap}. */
|
|
5
|
+
export interface MapControls<Key, Value> {
|
|
6
|
+
/**
|
|
7
|
+
* Read-only reactive view of the map. `get`, `has`, iteration, and `size`
|
|
8
|
+
* on this view are tracked per key. Values are stored shallowly.
|
|
9
|
+
*/
|
|
10
|
+
readonly map: ReadonlyMap<Key, Value>;
|
|
11
|
+
|
|
12
|
+
/** Number of entries. */
|
|
13
|
+
readonly size: ComputedRef<number>;
|
|
14
|
+
|
|
15
|
+
/** Snapshot of the entries in insertion order. */
|
|
16
|
+
readonly entries: ComputedRef<readonly (readonly [Key, Value])[]>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Read the value for `key`. Reactive when read inside an effect.
|
|
20
|
+
*
|
|
21
|
+
* @param key Key to read.
|
|
22
|
+
* @returns The value, or `undefined` when absent.
|
|
23
|
+
*/
|
|
24
|
+
readonly get: (key: Key) => Value | undefined;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Whether `key` is present. Reactive when read inside an effect.
|
|
28
|
+
*
|
|
29
|
+
* @param key Key to test.
|
|
30
|
+
* @returns Whether the key exists.
|
|
31
|
+
*/
|
|
32
|
+
readonly has: (key: Key) => boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Store `value` under `key`.
|
|
36
|
+
*
|
|
37
|
+
* @param key Key to write.
|
|
38
|
+
* @param value Value to store.
|
|
39
|
+
*/
|
|
40
|
+
readonly set: (key: Key, value: Value) => void;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Remove `key`.
|
|
44
|
+
*
|
|
45
|
+
* @param key Key to remove.
|
|
46
|
+
* @returns Whether an entry was removed.
|
|
47
|
+
*/
|
|
48
|
+
readonly delete: (key: Key) => boolean;
|
|
49
|
+
|
|
50
|
+
/** Remove every entry. */
|
|
51
|
+
readonly clear: () => void;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Replace the value under `key` with the result of `updater`.
|
|
55
|
+
*
|
|
56
|
+
* @param key Key to update.
|
|
57
|
+
* @param updater Receives the current value (`undefined` when absent).
|
|
58
|
+
* @returns The stored value.
|
|
59
|
+
*/
|
|
60
|
+
readonly update: (key: Key, updater: (previous: Value | undefined) => Value) => Value;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Return the value under `key`, inserting `create(key)` first when absent.
|
|
64
|
+
*
|
|
65
|
+
* @param key Key to read or insert.
|
|
66
|
+
* @param create Factory for a missing value.
|
|
67
|
+
* @returns The existing or inserted value.
|
|
68
|
+
*/
|
|
69
|
+
readonly getOrInsert: (key: Key, create: (key: Key) => Value) => Value;
|
|
70
|
+
|
|
71
|
+
/** Restore the creation-time entries. */
|
|
72
|
+
readonly reset: () => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Narrow a `get` result using the matching `has` answer: when the key is
|
|
77
|
+
* present the result is a stored `Value`, even if that value is `undefined`.
|
|
78
|
+
*/
|
|
79
|
+
function isStored<Value>(value: Value | undefined, present: boolean): value is Value {
|
|
80
|
+
return present;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Create a reactive `Map` with typed helpers.
|
|
85
|
+
*
|
|
86
|
+
* Key and value types are inferred from the initial entries
|
|
87
|
+
* (`useMap([["a", 1]])` is a `Map<string, number>`); pass type arguments
|
|
88
|
+
* for an initially empty map. Reads through `get`, `has`, and `map` are
|
|
89
|
+
* tracked per key, so an effect reading one key does not re-run when an
|
|
90
|
+
* unrelated key changes. Values are stored as-is (not deeply reactive).
|
|
91
|
+
*
|
|
92
|
+
* Purely synchronous state: safe during server rendering (no host globals,
|
|
93
|
+
* no timers) and nothing to dispose.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const counts = useMap<string, number>();
|
|
98
|
+
* counts.update("clicks", (previous = 0) => previous + 1);
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @typeParam Key Key type, inferred from `initial`.
|
|
102
|
+
* @typeParam Value Value type, inferred from `initial`.
|
|
103
|
+
* @param initial Entries inserted at creation and restored by `reset`.
|
|
104
|
+
* @default initial []
|
|
105
|
+
* @returns The reactive map and its helpers.
|
|
106
|
+
*/
|
|
107
|
+
export function useMap<Key = unknown, Value = unknown>(
|
|
108
|
+
initial: Iterable<readonly [Key, Value]> = [],
|
|
109
|
+
): MapControls<Key, Value> {
|
|
110
|
+
const baseline: readonly (readonly [Key, Value])[] = [...initial];
|
|
111
|
+
const map = shallowReactive(new Map<Key, Value>(baseline));
|
|
112
|
+
|
|
113
|
+
const reset = (): void => {
|
|
114
|
+
map.clear();
|
|
115
|
+
for (const [key, value] of baseline) map.set(key, value);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
map: shallowReadonly(map),
|
|
120
|
+
size: computed(() => map.size),
|
|
121
|
+
entries: computed(() => [...map.entries()]),
|
|
122
|
+
get: (key) => map.get(key),
|
|
123
|
+
has: (key) => map.has(key),
|
|
124
|
+
set: (key, value) => {
|
|
125
|
+
map.set(key, value);
|
|
126
|
+
},
|
|
127
|
+
delete: (key) => map.delete(key),
|
|
128
|
+
clear: () => {
|
|
129
|
+
map.clear();
|
|
130
|
+
},
|
|
131
|
+
update: (key, updater) => {
|
|
132
|
+
const next = updater(map.get(key));
|
|
133
|
+
map.set(key, next);
|
|
134
|
+
return next;
|
|
135
|
+
},
|
|
136
|
+
getOrInsert: (key, create) => {
|
|
137
|
+
const existing = map.get(key);
|
|
138
|
+
if (isStored(existing, map.has(key))) return existing;
|
|
139
|
+
const created = create(key);
|
|
140
|
+
map.set(key, created);
|
|
141
|
+
return created;
|
|
142
|
+
},
|
|
143
|
+
reset,
|
|
144
|
+
};
|
|
145
|
+
}
|