@vizejs/composable 0.426.3 → 0.427.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (544) hide show
  1. package/dist/abort-signal.d.mts +1 -1
  2. package/dist/active-element.d.mts +37 -0
  3. package/dist/active-element.mjs +56 -0
  4. package/dist/animate.d.mts +114 -0
  5. package/dist/animate.mjs +157 -0
  6. package/dist/battery.d.mts +61 -0
  7. package/dist/battery.mjs +90 -0
  8. package/dist/breakpoints.d.mts +82 -0
  9. package/dist/breakpoints.mjs +91 -0
  10. package/dist/catalog-BeTXFKxF.d.mts +4188 -0
  11. package/dist/catalog-r4Z5nptX.mjs +5144 -0
  12. package/dist/catalog.d.mts +1 -1
  13. package/dist/catalog.mjs +1 -1
  14. package/dist/color-mode.d.mts +131 -0
  15. package/dist/color-mode.mjs +133 -0
  16. package/dist/computed-async.d.mts +63 -0
  17. package/dist/computed-async.mjs +43 -0
  18. package/dist/computed-with-control.d.mts +44 -0
  19. package/dist/computed-with-control.mjs +54 -0
  20. package/dist/create-event-hook.d.mts +77 -0
  21. package/dist/create-event-hook.mjs +66 -0
  22. package/dist/create-global-state.d.mts +24 -0
  23. package/dist/create-global-state.mjs +34 -0
  24. package/dist/create-injection-state.d.mts +51 -0
  25. package/dist/create-injection-state.mjs +19 -0
  26. package/dist/create-shared-composable.d.mts +38 -0
  27. package/dist/create-shared-composable.mjs +54 -0
  28. package/dist/device-motion.d.mts +71 -0
  29. package/dist/device-motion.mjs +75 -0
  30. package/dist/device-orientation.d.mts +82 -0
  31. package/dist/device-orientation.mjs +86 -0
  32. package/dist/device-pixel-ratio.d.mts +45 -0
  33. package/dist/device-pixel-ratio.mjs +50 -0
  34. package/dist/document-visibility.mjs +6 -2
  35. package/dist/draggable.d.mts +121 -0
  36. package/dist/draggable.mjs +153 -0
  37. package/dist/element-bounding.d.mts +87 -0
  38. package/dist/element-bounding.mjs +95 -0
  39. package/dist/element-by-point.d.mts +70 -0
  40. package/dist/element-by-point.mjs +69 -0
  41. package/dist/element-hover.d.mts +42 -0
  42. package/dist/element-hover.mjs +70 -0
  43. package/dist/element-ref.d.mts +34 -0
  44. package/dist/element-ref.mjs +23 -0
  45. package/dist/element-target-Crpxl4D9.d.mts +60 -0
  46. package/dist/element-target.d.mts +2 -0
  47. package/dist/element-target.mjs +58 -0
  48. package/dist/event-listener.mjs +7 -3
  49. package/dist/focus.d.mts +69 -0
  50. package/dist/focus.mjs +124 -0
  51. package/dist/fps.d.mts +59 -0
  52. package/dist/fps.mjs +64 -0
  53. package/dist/geolocation.d.mts +98 -0
  54. package/dist/geolocation.mjs +86 -0
  55. package/dist/i18n.d.mts +237 -0
  56. package/dist/i18n.mjs +215 -0
  57. package/dist/icu-message.d.mts +235 -0
  58. package/dist/icu-message.mjs +343 -0
  59. package/dist/idle.d.mts +79 -0
  60. package/dist/idle.mjs +90 -0
  61. package/dist/index.d.mts +172 -6
  62. package/dist/index.mjs +173 -7
  63. package/dist/infinite-scroll.d.mts +56 -0
  64. package/dist/infinite-scroll.mjs +72 -0
  65. package/dist/intersection-observer.d.mts +122 -0
  66. package/dist/intersection-observer.mjs +117 -0
  67. package/dist/magic-keys.d.mts +121 -0
  68. package/dist/magic-keys.mjs +163 -0
  69. package/dist/math.d.mts +96 -0
  70. package/dist/math.mjs +84 -0
  71. package/dist/media-query.d.mts +3 -1
  72. package/dist/media-query.mjs +5 -3
  73. package/dist/mouse-in-element.d.mts +49 -0
  74. package/dist/mouse-in-element.mjs +66 -0
  75. package/dist/mouse.d.mts +77 -0
  76. package/dist/mouse.mjs +100 -0
  77. package/dist/mutation-observer.d.mts +98 -0
  78. package/dist/mutation-observer.mjs +69 -0
  79. package/dist/network.d.mts +96 -0
  80. package/dist/network.mjs +117 -0
  81. package/dist/on-click-outside.d.mts +69 -0
  82. package/dist/on-click-outside.mjs +115 -0
  83. package/dist/on-key-stroke.d.mts +71 -0
  84. package/dist/on-key-stroke.mjs +79 -0
  85. package/dist/on-long-press.d.mts +82 -0
  86. package/dist/on-long-press.mjs +105 -0
  87. package/dist/on-start-typing.d.mts +44 -0
  88. package/dist/on-start-typing.mjs +61 -0
  89. package/dist/page-leave.d.mts +26 -0
  90. package/dist/page-leave.mjs +40 -0
  91. package/dist/parent-element.d.mts +16 -0
  92. package/dist/parent-element.mjs +27 -0
  93. package/dist/pinch.d.mts +73 -0
  94. package/dist/pinch.mjs +138 -0
  95. package/dist/pointer-lock.d.mts +79 -0
  96. package/dist/pointer-lock.mjs +126 -0
  97. package/dist/pointer.d.mts +78 -0
  98. package/dist/pointer.mjs +95 -0
  99. package/dist/preferences.d.mts +55 -0
  100. package/dist/preferences.mjs +63 -0
  101. package/dist/preferred-languages.d.mts +43 -0
  102. package/dist/preferred-languages.mjs +44 -0
  103. package/dist/reactify.d.mts +28 -0
  104. package/dist/reactify.mjs +7 -0
  105. package/dist/ref-auto-reset.d.mts +47 -0
  106. package/dist/ref-auto-reset.mjs +70 -0
  107. package/dist/ref-debounced.d.mts +29 -0
  108. package/dist/ref-debounced.mjs +29 -0
  109. package/dist/ref-default.d.mts +27 -0
  110. package/dist/ref-default.mjs +33 -0
  111. package/dist/resize-observer.d.mts +96 -0
  112. package/dist/resize-observer.mjs +111 -0
  113. package/dist/resolver.d.mts +124 -0
  114. package/dist/resolver.mjs +138 -0
  115. package/dist/retry-async.d.mts +2 -2
  116. package/dist/retry-delay-DYsdq4SE.d.mts +73 -0
  117. package/dist/retry-delay.d.mts +1 -72
  118. package/dist/screen-orientation.d.mts +77 -0
  119. package/dist/screen-orientation.mjs +74 -0
  120. package/dist/scroll-lock.d.mts +37 -0
  121. package/dist/scroll-lock.mjs +50 -0
  122. package/dist/scroll.d.mts +158 -0
  123. package/dist/scroll.mjs +172 -0
  124. package/dist/standard-schema-DmNgFVK5.d.mts +107 -0
  125. package/dist/standard-schema.d.mts +2 -0
  126. package/dist/standard-schema.mjs +60 -0
  127. package/dist/swipe.d.mts +125 -0
  128. package/dist/swipe.mjs +225 -0
  129. package/dist/sync-ref.d.mts +80 -0
  130. package/dist/sync-ref.mjs +43 -0
  131. package/dist/text-selection.d.mts +46 -0
  132. package/dist/text-selection.mjs +62 -0
  133. package/dist/textarea-autosize.d.mts +58 -0
  134. package/dist/textarea-autosize.mjs +54 -0
  135. package/dist/timeout-scheduler-CI8RVLZs.d.mts +18 -0
  136. package/dist/timeout-scheduler.d.mts +1 -17
  137. package/dist/to-reactive.d.mts +26 -0
  138. package/dist/to-reactive.mjs +46 -0
  139. package/dist/transition.d.mts +125 -0
  140. package/dist/transition.mjs +266 -0
  141. package/dist/until.d.mts +177 -0
  142. package/dist/until.mjs +111 -0
  143. package/dist/use-array.d.mts +112 -0
  144. package/dist/use-array.mjs +90 -0
  145. package/dist/use-async-queue.d.mts +109 -0
  146. package/dist/use-async-queue.mjs +96 -0
  147. package/dist/use-async-state.d.mts +86 -0
  148. package/dist/use-async-state.mjs +41 -0
  149. package/dist/use-barcode-detector.d.mts +159 -0
  150. package/dist/use-barcode-detector.mjs +143 -0
  151. package/dist/use-bluetooth.d.mts +164 -0
  152. package/dist/use-bluetooth.mjs +183 -0
  153. package/dist/use-broadcast-channel.d.mts +115 -0
  154. package/dist/use-broadcast-channel.mjs +121 -0
  155. package/dist/use-builtin-ai.d.mts +342 -0
  156. package/dist/use-builtin-ai.mjs +261 -0
  157. package/dist/use-clipboard.d.mts +169 -0
  158. package/dist/use-clipboard.mjs +226 -0
  159. package/dist/use-compression-stream.d.mts +173 -0
  160. package/dist/use-compression-stream.mjs +166 -0
  161. package/dist/use-confirm-dialog.d.mts +70 -0
  162. package/dist/use-confirm-dialog.mjs +57 -0
  163. package/dist/use-contact-picker.d.mts +117 -0
  164. package/dist/use-contact-picker.mjs +103 -0
  165. package/dist/use-cookie.d.mts +196 -0
  166. package/dist/use-cookie.mjs +259 -0
  167. package/dist/use-countdown.d.mts +85 -0
  168. package/dist/use-countdown.mjs +74 -0
  169. package/dist/use-css-var.d.mts +96 -0
  170. package/dist/use-css-var.mjs +104 -0
  171. package/dist/use-cycle-list.d.mts +76 -0
  172. package/dist/use-cycle-list.mjs +39 -0
  173. package/dist/use-date-format.d.mts +103 -0
  174. package/dist/use-date-format.mjs +147 -0
  175. package/dist/use-date-time-format.d.mts +75 -0
  176. package/dist/use-date-time-format.mjs +53 -0
  177. package/dist/use-debounced.d.mts +1 -1
  178. package/dist/use-display-media.d.mts +62 -0
  179. package/dist/use-display-media.mjs +46 -0
  180. package/dist/use-display-names.d.mts +75 -0
  181. package/dist/use-display-names.mjs +52 -0
  182. package/dist/use-document-title.d.mts +88 -0
  183. package/dist/use-document-title.mjs +100 -0
  184. package/dist/use-drop-zone.d.mts +128 -0
  185. package/dist/use-drop-zone.mjs +154 -0
  186. package/dist/use-event-source.d.mts +184 -0
  187. package/dist/use-event-source.mjs +226 -0
  188. package/dist/use-eye-dropper.d.mts +79 -0
  189. package/dist/use-eye-dropper.mjs +68 -0
  190. package/dist/use-favicon.d.mts +78 -0
  191. package/dist/use-favicon.mjs +68 -0
  192. package/dist/use-fetch.d.mts +230 -0
  193. package/dist/use-fetch.mjs +263 -0
  194. package/dist/use-field.d.mts +107 -0
  195. package/dist/use-field.mjs +117 -0
  196. package/dist/use-file-dialog.d.mts +139 -0
  197. package/dist/use-file-dialog.mjs +101 -0
  198. package/dist/use-file-system-access.d.mts +184 -0
  199. package/dist/use-file-system-access.mjs +151 -0
  200. package/dist/use-form-field-props.d.mts +235 -0
  201. package/dist/use-form-field-props.mjs +164 -0
  202. package/dist/use-form.d.mts +324 -0
  203. package/dist/use-form.mjs +482 -0
  204. package/dist/use-fullscreen.d.mts +104 -0
  205. package/dist/use-fullscreen.mjs +95 -0
  206. package/dist/use-gamepad.d.mts +242 -0
  207. package/dist/use-gamepad.mjs +218 -0
  208. package/dist/use-hid.d.mts +160 -0
  209. package/dist/use-hid.mjs +156 -0
  210. package/dist/use-id-generator.d.mts +44 -0
  211. package/dist/use-id-generator.mjs +38 -0
  212. package/dist/use-image.d.mts +125 -0
  213. package/dist/use-image.mjs +109 -0
  214. package/dist/use-indexed-db.d.mts +207 -0
  215. package/dist/use-indexed-db.mjs +251 -0
  216. package/dist/use-interval-BA55gTHT.d.mts +140 -0
  217. package/dist/use-interval.d.mts +2 -0
  218. package/dist/use-interval.mjs +100 -0
  219. package/dist/use-list-format.d.mts +60 -0
  220. package/dist/use-list-format.mjs +40 -0
  221. package/dist/use-machine.d.mts +90 -0
  222. package/dist/use-machine.mjs +78 -0
  223. package/dist/use-map.d.mts +90 -0
  224. package/dist/use-map.mjs +70 -0
  225. package/dist/use-media-controls.d.mts +198 -0
  226. package/dist/use-media-controls.mjs +264 -0
  227. package/dist/use-memoize.d.mts +73 -0
  228. package/dist/use-memoize.mjs +28 -0
  229. package/dist/use-mounted.d.mts +24 -0
  230. package/dist/use-mounted.mjs +29 -0
  231. package/dist/use-navigation-api.d.mts +360 -0
  232. package/dist/use-navigation-api.mjs +231 -0
  233. package/dist/use-notification.d.mts +139 -0
  234. package/dist/use-notification.mjs +131 -0
  235. package/dist/use-now.d.mts +137 -0
  236. package/dist/use-now.mjs +44 -0
  237. package/dist/use-number-format.d.mts +73 -0
  238. package/dist/use-number-format.mjs +58 -0
  239. package/dist/use-object-url.d.mts +47 -0
  240. package/dist/use-object-url.mjs +54 -0
  241. package/dist/use-offset-pagination.d.mts +91 -0
  242. package/dist/use-offset-pagination.mjs +80 -0
  243. package/dist/use-payment-request.d.mts +239 -0
  244. package/dist/use-payment-request.mjs +206 -0
  245. package/dist/use-performance-observer.d.mts +285 -0
  246. package/dist/use-performance-observer.mjs +132 -0
  247. package/dist/use-permission.d.mts +99 -0
  248. package/dist/use-permission.mjs +92 -0
  249. package/dist/use-plural-rules.d.mts +79 -0
  250. package/dist/use-plural-rules.mjs +59 -0
  251. package/dist/use-push-subscription.d.mts +154 -0
  252. package/dist/use-push-subscription.mjs +146 -0
  253. package/dist/use-queue.d.mts +89 -0
  254. package/dist/use-queue.mjs +116 -0
  255. package/dist/use-raf-fn.d.mts +87 -0
  256. package/dist/use-raf-fn.mjs +99 -0
  257. package/dist/use-relative-time-format.d.mts +111 -0
  258. package/dist/use-relative-time-format.mjs +119 -0
  259. package/dist/use-request-idle-callback.d.mts +122 -0
  260. package/dist/use-request-idle-callback.mjs +147 -0
  261. package/dist/use-route-query.d.mts +149 -0
  262. package/dist/use-route-query.mjs +86 -0
  263. package/dist/use-scheduler-post-task.d.mts +156 -0
  264. package/dist/use-scheduler-post-task.mjs +182 -0
  265. package/dist/use-screen-details.d.mts +205 -0
  266. package/dist/use-screen-details.mjs +188 -0
  267. package/dist/use-script-tag.d.mts +162 -0
  268. package/dist/use-script-tag.mjs +171 -0
  269. package/dist/use-segmenter.d.mts +78 -0
  270. package/dist/use-segmenter.mjs +66 -0
  271. package/dist/use-selection.d.mts +125 -0
  272. package/dist/use-selection.mjs +77 -0
  273. package/dist/use-serial.d.mts +165 -0
  274. package/dist/use-serial.mjs +205 -0
  275. package/dist/use-service-worker.d.mts +177 -0
  276. package/dist/use-service-worker.mjs +178 -0
  277. package/dist/use-set.d.mts +96 -0
  278. package/dist/use-set.mjs +74 -0
  279. package/dist/use-share.d.mts +92 -0
  280. package/dist/use-share.mjs +99 -0
  281. package/dist/use-sorted-locale.d.mts +62 -0
  282. package/dist/use-sorted-locale.mjs +52 -0
  283. package/dist/use-sorted.d.mts +29 -0
  284. package/dist/use-sorted.mjs +14 -0
  285. package/dist/use-speech-recognition.d.mts +150 -0
  286. package/dist/use-speech-recognition.mjs +168 -0
  287. package/dist/use-speech-synthesis.d.mts +148 -0
  288. package/dist/use-speech-synthesis.mjs +152 -0
  289. package/dist/use-stack.d.mts +83 -0
  290. package/dist/use-stack.mjs +93 -0
  291. package/dist/use-stepper.d.mts +79 -0
  292. package/dist/use-stepper.mjs +52 -0
  293. package/dist/use-storage-estimate.d.mts +151 -0
  294. package/dist/use-storage-estimate.mjs +170 -0
  295. package/dist/use-storage.d.mts +214 -0
  296. package/dist/use-storage.mjs +415 -0
  297. package/dist/use-style-tag.d.mts +102 -0
  298. package/dist/use-style-tag.mjs +91 -0
  299. package/dist/use-supported.d.mts +23 -0
  300. package/dist/use-supported.mjs +26 -0
  301. package/dist/use-throttled.d.mts +1 -1
  302. package/dist/use-time-ago.d.mts +163 -0
  303. package/dist/use-time-ago.mjs +95 -0
  304. package/dist/use-timeout.d.mts +122 -0
  305. package/dist/use-timeout.mjs +65 -0
  306. package/dist/use-url-hash.d.mts +88 -0
  307. package/dist/use-url-hash.mjs +145 -0
  308. package/dist/use-url-search-params.d.mts +223 -0
  309. package/dist/use-url-search-params.mjs +295 -0
  310. package/dist/use-usb.d.mts +212 -0
  311. package/dist/use-usb.mjs +137 -0
  312. package/dist/use-user-activation.d.mts +83 -0
  313. package/dist/use-user-activation.mjs +113 -0
  314. package/dist/use-user-media.d.mts +194 -0
  315. package/dist/use-user-media.mjs +214 -0
  316. package/dist/use-v-model.d.mts +113 -0
  317. package/dist/use-v-model.mjs +40 -0
  318. package/dist/use-vibrate.d.mts +81 -0
  319. package/dist/use-vibrate.mjs +90 -0
  320. package/dist/use-view-transition.d.mts +106 -0
  321. package/dist/use-view-transition.mjs +101 -0
  322. package/dist/use-visual-viewport.d.mts +105 -0
  323. package/dist/use-visual-viewport.mjs +104 -0
  324. package/dist/use-wake-lock.d.mts +96 -0
  325. package/dist/use-wake-lock.mjs +106 -0
  326. package/dist/use-web-authn.d.mts +404 -0
  327. package/dist/use-web-authn.mjs +323 -0
  328. package/dist/use-web-locks.d.mts +180 -0
  329. package/dist/use-web-locks.mjs +136 -0
  330. package/dist/use-web-midi.d.mts +148 -0
  331. package/dist/use-web-midi.mjs +140 -0
  332. package/dist/use-web-vitals.d.mts +142 -0
  333. package/dist/use-web-vitals.mjs +248 -0
  334. package/dist/use-websocket.d.mts +218 -0
  335. package/dist/use-websocket.mjs +257 -0
  336. package/dist/use-worker-fn.d.mts +119 -0
  337. package/dist/use-worker-fn.mjs +162 -0
  338. package/dist/virtual-list.d.mts +105 -0
  339. package/dist/virtual-list.mjs +128 -0
  340. package/dist/watch-debounced.d.mts +84 -0
  341. package/dist/watch-debounced.mjs +84 -0
  342. package/dist/watch-ignorable.d.mts +47 -0
  343. package/dist/watch-ignorable.mjs +61 -0
  344. package/dist/watch-once.d.mts +29 -0
  345. package/dist/watch-once.mjs +10 -0
  346. package/dist/watch-pausable.d.mts +51 -0
  347. package/dist/watch-pausable.mjs +23 -0
  348. package/dist/watch-source.d.mts +29 -0
  349. package/dist/watch-source.mjs +1 -0
  350. package/dist/watch-throttled.d.mts +70 -0
  351. package/dist/watch-throttled.mjs +94 -0
  352. package/dist/whenever.d.mts +39 -0
  353. package/dist/whenever.mjs +41 -0
  354. package/dist/window-size.d.mts +87 -0
  355. package/dist/window-size.mjs +65 -0
  356. package/package.json +846 -5
  357. package/registry/files/abort-signal.ts +292 -0
  358. package/registry/files/active-element.ts +93 -0
  359. package/registry/files/animate.ts +322 -0
  360. package/registry/files/async-resource.ts +190 -0
  361. package/registry/files/battery.ts +166 -0
  362. package/registry/files/breakpoints.ts +166 -0
  363. package/registry/files/capability.ts +171 -0
  364. package/registry/files/color-mode.ts +274 -0
  365. package/registry/files/computed-async.ts +123 -0
  366. package/registry/files/computed-with-control.ts +80 -0
  367. package/registry/files/create-event-hook.ts +139 -0
  368. package/registry/files/create-global-state.ts +34 -0
  369. package/registry/files/create-injection-state.ts +75 -0
  370. package/registry/files/create-shared-composable.ts +74 -0
  371. package/registry/files/device-motion.ts +152 -0
  372. package/registry/files/device-orientation.ts +168 -0
  373. package/registry/files/device-pixel-ratio.ts +100 -0
  374. package/registry/files/disposal-scope.ts +201 -0
  375. package/registry/files/document-visibility.ts +152 -0
  376. package/registry/files/draggable.ts +273 -0
  377. package/registry/files/element-bounding.ts +175 -0
  378. package/registry/files/element-by-point.ts +149 -0
  379. package/registry/files/element-hover.ts +104 -0
  380. package/registry/files/element-ref.ts +58 -0
  381. package/registry/files/element-target.ts +99 -0
  382. package/registry/files/event-listener.ts +188 -0
  383. package/registry/files/focus.ts +181 -0
  384. package/registry/files/fps.ts +133 -0
  385. package/registry/files/geolocation.ts +214 -0
  386. package/registry/files/i18n.ts +524 -0
  387. package/registry/files/icu-message.ts +701 -0
  388. package/registry/files/idle.ts +176 -0
  389. package/registry/files/infinite-scroll.ts +135 -0
  390. package/registry/files/intersection-observer.ts +261 -0
  391. package/registry/files/locale.ts +148 -0
  392. package/registry/files/magic-keys.ts +298 -0
  393. package/registry/files/math.ts +175 -0
  394. package/registry/files/media-query.ts +102 -0
  395. package/registry/files/mouse-in-element.ts +107 -0
  396. package/registry/files/mouse.ts +167 -0
  397. package/registry/files/mutation-observer.ts +183 -0
  398. package/registry/files/network.ts +229 -0
  399. package/registry/files/on-click-outside.ts +178 -0
  400. package/registry/files/on-key-stroke.ts +135 -0
  401. package/registry/files/on-long-press.ts +188 -0
  402. package/registry/files/on-start-typing.ts +88 -0
  403. package/registry/files/page-leave.ts +57 -0
  404. package/registry/files/parent-element.ts +29 -0
  405. package/registry/files/pinch.ts +187 -0
  406. package/registry/files/pointer-lock.ts +232 -0
  407. package/registry/files/pointer.ts +153 -0
  408. package/registry/files/preferences.ts +98 -0
  409. package/registry/files/preferred-languages.ts +88 -0
  410. package/registry/files/reactify.ts +39 -0
  411. package/registry/files/ref-auto-reset.ts +102 -0
  412. package/registry/files/ref-debounced.ts +34 -0
  413. package/registry/files/ref-default.ts +35 -0
  414. package/registry/files/resize-observer.ts +220 -0
  415. package/registry/files/retry-async.ts +261 -0
  416. package/registry/files/retry-delay.ts +132 -0
  417. package/registry/files/scope.ts +21 -0
  418. package/registry/files/screen-orientation.ts +165 -0
  419. package/registry/files/scroll-lock.ts +80 -0
  420. package/registry/files/scroll.ts +338 -0
  421. package/registry/files/standard-schema.ts +163 -0
  422. package/registry/files/swipe.ts +321 -0
  423. package/registry/files/sync-ref.ts +166 -0
  424. package/registry/files/temporal.ts +182 -0
  425. package/registry/files/text-selection.ts +110 -0
  426. package/registry/files/textarea-autosize.ts +114 -0
  427. package/registry/files/timeout-scheduler.ts +16 -0
  428. package/registry/files/to-reactive.ts +44 -0
  429. package/registry/files/transition.ts +271 -0
  430. package/registry/files/until.ts +352 -0
  431. package/registry/files/use-array.ts +201 -0
  432. package/registry/files/use-async-queue.ts +278 -0
  433. package/registry/files/use-async-state.ts +139 -0
  434. package/registry/files/use-barcode-detector.ts +321 -0
  435. package/registry/files/use-bluetooth.ts +409 -0
  436. package/registry/files/use-broadcast-channel.ts +250 -0
  437. package/registry/files/use-builtin-ai.ts +674 -0
  438. package/registry/files/use-clipboard.ts +425 -0
  439. package/registry/files/use-compression-stream.ts +364 -0
  440. package/registry/files/use-confirm-dialog.ts +137 -0
  441. package/registry/files/use-contact-picker.ts +246 -0
  442. package/registry/files/use-cookie.ts +500 -0
  443. package/registry/files/use-countdown.ts +161 -0
  444. package/registry/files/use-counter.ts +147 -0
  445. package/registry/files/use-css-var.ts +191 -0
  446. package/registry/files/use-cycle-list.ts +136 -0
  447. package/registry/files/use-date-format.ts +281 -0
  448. package/registry/files/use-date-time-format.ts +113 -0
  449. package/registry/files/use-debounced.ts +163 -0
  450. package/registry/files/use-display-media.ts +89 -0
  451. package/registry/files/use-display-names.ts +122 -0
  452. package/registry/files/use-document-title.ts +196 -0
  453. package/registry/files/use-drop-zone.ts +287 -0
  454. package/registry/files/use-event-source.ts +470 -0
  455. package/registry/files/use-eye-dropper.ts +134 -0
  456. package/registry/files/use-favicon.ts +140 -0
  457. package/registry/files/use-fetch.ts +578 -0
  458. package/registry/files/use-field.ts +247 -0
  459. package/registry/files/use-file-dialog.ts +257 -0
  460. package/registry/files/use-file-system-access.ts +383 -0
  461. package/registry/files/use-form-field-props.ts +381 -0
  462. package/registry/files/use-form.ts +980 -0
  463. package/registry/files/use-fullscreen.ts +214 -0
  464. package/registry/files/use-gamepad.ts +463 -0
  465. package/registry/files/use-hid.ts +359 -0
  466. package/registry/files/use-history.ts +231 -0
  467. package/registry/files/use-id-generator.ts +61 -0
  468. package/registry/files/use-image.ts +253 -0
  469. package/registry/files/use-indexed-db.ts +508 -0
  470. package/registry/files/use-interval.ts +253 -0
  471. package/registry/files/use-list-format.ts +85 -0
  472. package/registry/files/use-machine.ts +171 -0
  473. package/registry/files/use-map.ts +145 -0
  474. package/registry/files/use-media-controls.ts +545 -0
  475. package/registry/files/use-memoize.ts +118 -0
  476. package/registry/files/use-mounted.ts +30 -0
  477. package/registry/files/use-navigation-api.ts +641 -0
  478. package/registry/files/use-notification.ts +285 -0
  479. package/registry/files/use-now.ts +194 -0
  480. package/registry/files/use-number-format.ts +120 -0
  481. package/registry/files/use-object-url.ts +87 -0
  482. package/registry/files/use-offset-pagination.ts +168 -0
  483. package/registry/files/use-payment-request.ts +465 -0
  484. package/registry/files/use-performance-observer.ts +469 -0
  485. package/registry/files/use-permission.ts +220 -0
  486. package/registry/files/use-plural-rules.ts +134 -0
  487. package/registry/files/use-previous.ts +62 -0
  488. package/registry/files/use-push-subscription.ts +352 -0
  489. package/registry/files/use-queue.ts +197 -0
  490. package/registry/files/use-raf-fn.ts +176 -0
  491. package/registry/files/use-relative-time-format.ts +201 -0
  492. package/registry/files/use-request-idle-callback.ts +278 -0
  493. package/registry/files/use-route-query.ts +300 -0
  494. package/registry/files/use-scheduler-post-task.ts +397 -0
  495. package/registry/files/use-screen-details.ts +393 -0
  496. package/registry/files/use-script-tag.ts +341 -0
  497. package/registry/files/use-segmenter.ts +147 -0
  498. package/registry/files/use-selection.ts +233 -0
  499. package/registry/files/use-serial.ts +404 -0
  500. package/registry/files/use-service-worker.ts +413 -0
  501. package/registry/files/use-set.ts +154 -0
  502. package/registry/files/use-share.ts +168 -0
  503. package/registry/files/use-sorted-locale.ts +130 -0
  504. package/registry/files/use-sorted.ts +49 -0
  505. package/registry/files/use-speech-recognition.ts +357 -0
  506. package/registry/files/use-speech-synthesis.ts +333 -0
  507. package/registry/files/use-stack.ts +164 -0
  508. package/registry/files/use-stepper.ts +166 -0
  509. package/registry/files/use-storage-estimate.ts +352 -0
  510. package/registry/files/use-storage.ts +635 -0
  511. package/registry/files/use-style-tag.ts +200 -0
  512. package/registry/files/use-supported.ts +26 -0
  513. package/registry/files/use-throttled.ts +215 -0
  514. package/registry/files/use-time-ago.ts +276 -0
  515. package/registry/files/use-timeout.ts +218 -0
  516. package/registry/files/use-toggle.ts +54 -0
  517. package/registry/files/use-url-hash.ts +280 -0
  518. package/registry/files/use-url-search-params.ts +497 -0
  519. package/registry/files/use-usb.ts +395 -0
  520. package/registry/files/use-user-activation.ts +215 -0
  521. package/registry/files/use-user-media.ts +422 -0
  522. package/registry/files/use-v-model.ts +210 -0
  523. package/registry/files/use-vibrate.ts +174 -0
  524. package/registry/files/use-view-transition.ts +229 -0
  525. package/registry/files/use-visual-viewport.ts +228 -0
  526. package/registry/files/use-wake-lock.ts +206 -0
  527. package/registry/files/use-web-authn.ts +793 -0
  528. package/registry/files/use-web-locks.ts +363 -0
  529. package/registry/files/use-web-midi.ts +306 -0
  530. package/registry/files/use-web-vitals.ts +409 -0
  531. package/registry/files/use-websocket.ts +553 -0
  532. package/registry/files/use-worker-fn.ts +306 -0
  533. package/registry/files/virtual-list.ts +230 -0
  534. package/registry/files/watch-debounced.ts +206 -0
  535. package/registry/files/watch-ignorable.ts +128 -0
  536. package/registry/files/watch-once.ts +46 -0
  537. package/registry/files/watch-pausable.ts +93 -0
  538. package/registry/files/watch-source.ts +51 -0
  539. package/registry/files/watch-throttled.ts +201 -0
  540. package/registry/files/whenever.ts +70 -0
  541. package/registry/files/window-size.ts +151 -0
  542. package/registry/registry.json +5792 -0
  543. package/dist/catalog-D2AL3xYl.d.mts +0 -523
  544. package/dist/catalog-D5SYCsgW.mjs +0 -549
@@ -0,0 +1,363 @@
1
+ import {
2
+ computed,
3
+ hasInjectionContext,
4
+ readonly,
5
+ ref,
6
+ shallowRef,
7
+ toValue,
8
+ watchPostEffect,
9
+ } from "vue";
10
+ import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
11
+
12
+ import { tryOnScopeDispose } from "./scope.ts";
13
+
14
+ /** Lock modes defined by the Web Locks API. */
15
+ export type WebLockMode = "exclusive" | "shared";
16
+
17
+ /** Granted lock handed to a request callback. */
18
+ export interface WebLockLike {
19
+ /** Lock name. */
20
+ readonly name: string;
21
+
22
+ /** Granted mode. */
23
+ readonly mode: WebLockMode;
24
+ }
25
+
26
+ /** One entry of a lock manager snapshot. */
27
+ export interface WebLockInfo {
28
+ /** Lock name. */
29
+ readonly name?: string | undefined;
30
+
31
+ /** Requested or granted mode. */
32
+ readonly mode?: WebLockMode | undefined;
33
+
34
+ /** Identifier of the client holding or requesting the lock. */
35
+ readonly clientId?: string | undefined;
36
+ }
37
+
38
+ /** Snapshot returned by {@link WebLocksControls.query}. */
39
+ export interface WebLocksSnapshot {
40
+ /** Locks currently held by any client of the origin. */
41
+ readonly held: readonly WebLockInfo[];
42
+
43
+ /** Requests currently waiting for a lock. */
44
+ readonly pending: readonly WebLockInfo[];
45
+ }
46
+
47
+ /** Options forwarded to `LockManager.request`. */
48
+ export interface WebLockManagerRequestOptions {
49
+ /** Requested mode. */
50
+ readonly mode: WebLockMode;
51
+
52
+ /**
53
+ * Only grant the lock when it is immediately available.
54
+ *
55
+ * @default false
56
+ */
57
+ readonly ifAvailable?: boolean;
58
+
59
+ /**
60
+ * Release any held lock of the same name and grant this request.
61
+ *
62
+ * @default false
63
+ */
64
+ readonly steal?: boolean;
65
+
66
+ /**
67
+ * Abort the request while it is pending.
68
+ *
69
+ * @default undefined
70
+ */
71
+ readonly signal?: AbortSignal;
72
+ }
73
+
74
+ /** Minimal `LockManager` (`navigator.locks`) consumed by {@link useWebLocks}. */
75
+ export interface LockManagerLike {
76
+ /** Request a lock and run `callback` while it is held. */
77
+ request(
78
+ name: string,
79
+ options: WebLockManagerRequestOptions,
80
+ callback: (lock: WebLockLike | null) => unknown,
81
+ ): Promise<unknown>;
82
+
83
+ /** Snapshot the origin's held and pending locks. */
84
+ query(): Promise<{
85
+ /** Held locks. */
86
+ readonly held?: readonly WebLockInfo[] | undefined;
87
+ /** Pending requests. */
88
+ readonly pending?: readonly WebLockInfo[] | undefined;
89
+ }>;
90
+ }
91
+
92
+ /** Options for {@link useWebLocks}. */
93
+ export interface UseWebLocksOptions {
94
+ /**
95
+ * Lock manager for alternate runtimes and tests.
96
+ *
97
+ * @default window.navigator.locks when it exists
98
+ */
99
+ readonly locks?: MaybeRefOrGetter<LockManagerLike | null | undefined>;
100
+ }
101
+
102
+ /** Per-request options for {@link WebLocksControls.request}. */
103
+ export interface WebLockRequestOptions {
104
+ /**
105
+ * Requested mode.
106
+ *
107
+ * @default "exclusive"
108
+ */
109
+ readonly mode?: WebLockMode;
110
+
111
+ /**
112
+ * Resolve with `{ acquired: false }` instead of waiting when the lock is busy.
113
+ *
114
+ * @default false
115
+ */
116
+ readonly ifAvailable?: boolean;
117
+
118
+ /**
119
+ * Preempt any holder of the lock (exclusive mode only).
120
+ *
121
+ * @default false
122
+ */
123
+ readonly steal?: boolean;
124
+
125
+ /**
126
+ * Abort the request while it is still pending.
127
+ *
128
+ * @default undefined
129
+ */
130
+ readonly signal?: AbortSignal;
131
+ }
132
+
133
+ /** Outcome of an `ifAvailable` request. */
134
+ export type WebLockAttempt<Value> =
135
+ | {
136
+ /** The lock was granted and the callback ran. */
137
+ readonly acquired: true;
138
+ /** Callback result. */
139
+ readonly value: Value;
140
+ }
141
+ | {
142
+ /** The lock was busy; the callback did not run. */
143
+ readonly acquired: false;
144
+ };
145
+
146
+ /** Request function exposed by {@link WebLocksControls}. */
147
+ export interface WebLockRequest {
148
+ /**
149
+ * Request a lock that is only granted when immediately available.
150
+ *
151
+ * @param name Lock name.
152
+ * @param callback Work to run while the lock is held.
153
+ * @param options Request options with `ifAvailable: true`.
154
+ * @returns The callback result, or `{ acquired: false }` when busy.
155
+ */
156
+ <Value>(
157
+ name: string,
158
+ callback: (lock: WebLockLike) => Value | PromiseLike<Value>,
159
+ options: WebLockRequestOptions & { readonly ifAvailable: true },
160
+ ): Promise<WebLockAttempt<Value>>;
161
+
162
+ /**
163
+ * Request a lock and run `callback` while it is held.
164
+ *
165
+ * @param name Lock name.
166
+ * @param callback Work to run while the lock is held.
167
+ * @param options Mode, steal and abort options.
168
+ * @returns The callback result.
169
+ */
170
+ <Value>(
171
+ name: string,
172
+ callback: (lock: WebLockLike) => Value | PromiseLike<Value>,
173
+ options?: WebLockRequestOptions & { readonly ifAvailable?: false },
174
+ ): Promise<Value>;
175
+ }
176
+
177
+ /** Reactive state and actions returned by {@link useWebLocks}. */
178
+ export interface WebLocksControls {
179
+ /** Whether the Web Locks API is available. */
180
+ readonly supported: ComputedRef<boolean>;
181
+
182
+ /** Names of locks requested through this composable that are currently held. */
183
+ readonly held: Readonly<Ref<readonly string[]>>;
184
+
185
+ /** Names of locks requested through this composable that are still waiting. */
186
+ readonly pending: Readonly<Ref<readonly string[]>>;
187
+
188
+ /** Most recent request failure (including aborts), cleared by the next grant. */
189
+ readonly error: Readonly<ShallowRef<unknown>>;
190
+
191
+ /**
192
+ * Request a lock. Rejects with a tagged `TypeError` for invalid option
193
+ * combinations, a tagged `Error` when unsupported, the host's `AbortError`
194
+ * when aborted, or the callback's rejection.
195
+ */
196
+ readonly request: WebLockRequest;
197
+
198
+ /**
199
+ * Snapshot the origin's locks.
200
+ *
201
+ * @returns Held and pending locks; empty lists when unsupported or on failure.
202
+ */
203
+ readonly query: () => Promise<WebLocksSnapshot>;
204
+ }
205
+
206
+ function browserLocks(): LockManagerLike | undefined {
207
+ if (typeof window === "undefined") return undefined;
208
+ const { navigator } = window;
209
+ return "locks" in navigator && navigator.locks ? navigator.locks : undefined;
210
+ }
211
+
212
+ function without(names: readonly string[], name: string): readonly string[] {
213
+ const index = names.indexOf(name);
214
+ return index === -1 ? names : [...names.slice(0, index), ...names.slice(index + 1)];
215
+ }
216
+
217
+ /**
218
+ * Coordinate work across tabs and workers with the Web Locks API.
219
+ *
220
+ * `request` runs the callback while the named lock is held and resolves with
221
+ * its result; with `ifAvailable` it resolves with a discriminated
222
+ * `{ acquired }` outcome instead of waiting. `held` and `pending` track the
223
+ * lock names requested through this composable. Requests still waiting when
224
+ * the owning reactive scope stops are aborted; locks already held are
225
+ * released when their callbacks settle. Outside a scope, pass a `signal` to
226
+ * own cancellation.
227
+ *
228
+ * Server rendering: nothing is requested, `supported` is false and the name
229
+ * lists are empty.
230
+ *
231
+ * @example
232
+ * ```ts
233
+ * const locks = useWebLocks();
234
+ * await locks.request("sync", async () => syncOutbox());
235
+ * const attempt = await locks.request("leader", runLeader, { ifAvailable: true });
236
+ * ```
237
+ *
238
+ * @param options Lock manager override.
239
+ * @default options {}
240
+ * @returns Lock state and actions.
241
+ */
242
+ export function useWebLocks(options: UseWebLocksOptions = {}): WebLocksControls {
243
+ const held = ref<readonly string[]>([]);
244
+ const pending = ref<readonly string[]>([]);
245
+ const error = shallowRef<unknown>(undefined);
246
+ const controllers = new Set<AbortController>();
247
+
248
+ // Inside a component the host resolves only after mount (a post-flush
249
+ // job), so a hydrating client first renders the same unsupported state as
250
+ // the server. Outside components it resolves immediately.
251
+ const hydrated = shallowRef(!hasInjectionContext());
252
+ if (!hydrated.value) {
253
+ watchPostEffect(() => {
254
+ hydrated.value = true;
255
+ });
256
+ }
257
+ const resolveLocks = (): LockManagerLike | undefined =>
258
+ !hydrated.value
259
+ ? undefined
260
+ : options.locks === undefined
261
+ ? browserLocks()
262
+ : (toValue(options.locks) ?? undefined);
263
+
264
+ const run = async (
265
+ name: string,
266
+ callback: (lock: WebLockLike) => unknown,
267
+ requestOptions: WebLockRequestOptions = {},
268
+ ): Promise<WebLockAttempt<unknown>> => {
269
+ const { mode = "exclusive", ifAvailable = false, steal = false, signal } = requestOptions;
270
+ if (
271
+ (ifAvailable && steal) ||
272
+ (steal && mode === "shared") ||
273
+ (signal && (ifAvailable || steal))
274
+ ) {
275
+ throw new TypeError(
276
+ "[VIZE_COMPOSE_WEB_LOCKS_INVALID_OPTIONS] steal cannot be combined with ifAvailable, shared mode or signal, and signal cannot be combined with ifAvailable.",
277
+ );
278
+ }
279
+ const locks = resolveLocks();
280
+ if (!locks) {
281
+ throw new Error("[VIZE_COMPOSE_WEB_LOCKS_UNSUPPORTED] The Web Locks API is not available.");
282
+ }
283
+
284
+ const controller = ifAvailable || steal ? undefined : new AbortController();
285
+ const forwardAbort = (): void => controller?.abort(signal?.reason);
286
+ if (controller) {
287
+ if (signal?.aborted) forwardAbort();
288
+ else signal?.addEventListener("abort", forwardAbort, { once: true });
289
+ controllers.add(controller);
290
+ }
291
+ pending.value = [...pending.value, name];
292
+ let granted = false;
293
+ const managerOptions: WebLockManagerRequestOptions = controller
294
+ ? { mode, signal: controller.signal }
295
+ : { mode, ifAvailable, steal };
296
+
297
+ let outcome: WebLockAttempt<unknown> = { acquired: false };
298
+ try {
299
+ await locks.request(name, managerOptions, async (lock) => {
300
+ pending.value = without(pending.value, name);
301
+ if (controller) controllers.delete(controller);
302
+ if (!lock) return;
303
+ granted = true;
304
+ error.value = undefined;
305
+ held.value = [...held.value, name];
306
+ try {
307
+ outcome = { acquired: true, value: await callback(lock) };
308
+ } finally {
309
+ held.value = without(held.value, name);
310
+ }
311
+ });
312
+ return outcome;
313
+ } catch (cause) {
314
+ error.value = cause;
315
+ throw cause;
316
+ } finally {
317
+ if (!granted) pending.value = without(pending.value, name);
318
+ if (controller) controllers.delete(controller);
319
+ signal?.removeEventListener("abort", forwardAbort);
320
+ }
321
+ };
322
+
323
+ // The overloads share one implementation: `run` reports the attempt and
324
+ // this adapter unwraps it for waiting requests. The cast is confined here.
325
+ const request = ((
326
+ name: string,
327
+ callback: (lock: WebLockLike) => unknown,
328
+ requestOptions?: WebLockRequestOptions,
329
+ ): Promise<unknown> => {
330
+ const attempt = run(name, callback, requestOptions);
331
+ return requestOptions?.ifAvailable
332
+ ? attempt
333
+ : attempt.then((outcome) => (outcome.acquired ? outcome.value : undefined));
334
+ }) as WebLockRequest;
335
+
336
+ const query = async (): Promise<WebLocksSnapshot> => {
337
+ const locks = resolveLocks();
338
+ if (!locks) return { held: [], pending: [] };
339
+ try {
340
+ const snapshot = await locks.query();
341
+ return { held: snapshot.held ?? [], pending: snapshot.pending ?? [] };
342
+ } catch (cause) {
343
+ error.value = cause;
344
+ return { held: [], pending: [] };
345
+ }
346
+ };
347
+
348
+ tryOnScopeDispose(() => {
349
+ for (const controller of controllers) {
350
+ controller.abort(new DOMException("The owning scope was disposed.", "AbortError"));
351
+ }
352
+ controllers.clear();
353
+ });
354
+
355
+ return {
356
+ supported: computed(() => resolveLocks() !== undefined),
357
+ held: readonly(held),
358
+ pending: readonly(pending),
359
+ error: readonly(error),
360
+ request,
361
+ query,
362
+ };
363
+ }
@@ -0,0 +1,306 @@
1
+ import {
2
+ computed,
3
+ hasInjectionContext,
4
+ readonly,
5
+ ref,
6
+ shallowReadonly,
7
+ shallowRef,
8
+ toValue,
9
+ watchPostEffect,
10
+ } from "vue";
11
+ import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
12
+
13
+ import { tryOnScopeDispose } from "./scope.ts";
14
+
15
+ /** Minimal `MIDIPort` read by {@link useWebMIDI}. */
16
+ export interface MIDIPortLike extends EventTarget {
17
+ /** Stable port identifier. */
18
+ readonly id: string;
19
+ /** Port name. */
20
+ readonly name?: string | null;
21
+ /** Manufacturer name. */
22
+ readonly manufacturer?: string | null;
23
+ /** Device state. */
24
+ readonly state: string;
25
+ /** Connection state. */
26
+ readonly connection: string;
27
+ }
28
+
29
+ /** Minimal `MIDIOutput` used by {@link useWebMIDI}. */
30
+ export interface MIDIOutputLike extends MIDIPortLike {
31
+ /** Send one or more MIDI messages, optionally scheduled at `timestamp`. */
32
+ send(data: number[], timestamp?: number): void;
33
+ }
34
+
35
+ /** Minimal `MIDIAccess` used by {@link useWebMIDI}. */
36
+ export interface MIDIAccessLike extends EventTarget {
37
+ /** Available inputs. */
38
+ readonly inputs: { values(): Iterable<MIDIPortLike> };
39
+ /** Available outputs. */
40
+ readonly outputs: { values(): Iterable<MIDIOutputLike> };
41
+ }
42
+
43
+ /** Access request flags of `navigator.requestMIDIAccess`. */
44
+ export interface MIDIRequestFlags {
45
+ /** Request system-exclusive message access. */
46
+ readonly sysex?: boolean;
47
+ /** Include software synthesizers. */
48
+ readonly software?: boolean;
49
+ }
50
+
51
+ /** Navigator-like capability used by {@link useWebMIDI}. */
52
+ export interface MIDIHost {
53
+ /** Request MIDI access. */
54
+ requestMIDIAccess(options?: MIDIRequestFlags): Promise<MIDIAccessLike>;
55
+ }
56
+
57
+ /** Plain description of one MIDI port. */
58
+ export interface MIDIPortInfo {
59
+ /** Stable port identifier. */
60
+ readonly id: string;
61
+ /** Port name (empty when unknown). */
62
+ readonly name: string;
63
+ /** Manufacturer (empty when unknown). */
64
+ readonly manufacturer: string;
65
+ /** Device state, e.g. `"connected"` or `"disconnected"`. */
66
+ readonly state: string;
67
+ /** Connection state, e.g. `"open"`, `"closed"` or `"pending"`. */
68
+ readonly connection: string;
69
+ }
70
+
71
+ /** A message received on an input port. */
72
+ export interface MIDIInputMessage {
73
+ /** Raw message bytes. */
74
+ readonly data: Uint8Array;
75
+ /** Event timestamp in milliseconds. */
76
+ readonly timeStamp: number;
77
+ /** Identifier of the receiving input. */
78
+ readonly inputId: string;
79
+ }
80
+
81
+ /** Lifecycle of the access request. */
82
+ export type MIDIAccessStatus = "idle" | "pending" | "granted" | "denied";
83
+
84
+ /** Options for {@link useWebMIDI}. */
85
+ export interface UseWebMIDIOptions {
86
+ /**
87
+ * Navigator-like MIDI capability.
88
+ *
89
+ * @default window.navigator when `requestMIDIAccess` exists
90
+ */
91
+ readonly host?: MaybeRefOrGetter<MIDIHost | null | undefined>;
92
+
93
+ /**
94
+ * Request system-exclusive access.
95
+ *
96
+ * @default false
97
+ */
98
+ readonly sysex?: boolean;
99
+
100
+ /**
101
+ * Include software synthesizers.
102
+ *
103
+ * @default false
104
+ */
105
+ readonly software?: boolean;
106
+
107
+ /**
108
+ * Receives every input message. When set, `midimessage` listeners are
109
+ * attached to all inputs (which implicitly opens them).
110
+ *
111
+ * @default undefined
112
+ */
113
+ readonly onMessage?: (message: MIDIInputMessage) => void;
114
+ }
115
+
116
+ /** Reactive state and actions returned by {@link useWebMIDI}. */
117
+ export interface WebMIDIControls {
118
+ /** Whether Web MIDI is available. */
119
+ readonly supported: ComputedRef<boolean>;
120
+ /** Access request status. */
121
+ readonly status: Readonly<Ref<MIDIAccessStatus>>;
122
+ /** Input ports, refreshed on `statechange`. */
123
+ readonly inputs: Readonly<ShallowRef<readonly MIDIPortInfo[]>>;
124
+ /** Output ports, refreshed on `statechange`. */
125
+ readonly outputs: Readonly<ShallowRef<readonly MIDIPortInfo[]>>;
126
+ /** Most recent request or send failure. */
127
+ readonly error: Readonly<ShallowRef<unknown>>;
128
+ /**
129
+ * Request MIDI access (may prompt the user).
130
+ *
131
+ * @returns Whether access was granted.
132
+ */
133
+ readonly request: () => Promise<boolean>;
134
+ /**
135
+ * Send bytes to an output.
136
+ *
137
+ * @returns Whether the output exists and accepted the message.
138
+ */
139
+ readonly send: (
140
+ outputId: string,
141
+ data: Uint8Array | readonly number[],
142
+ timestamp?: number,
143
+ ) => boolean;
144
+ /** Remove every listener and forget the access object. Idempotent. */
145
+ readonly stop: () => void;
146
+ }
147
+
148
+ function browserMIDIHost(): MIDIHost | undefined {
149
+ if (typeof window === "undefined") return undefined;
150
+ const { navigator } = window;
151
+ return typeof navigator.requestMIDIAccess === "function" ? navigator : undefined;
152
+ }
153
+
154
+ function describe(port: MIDIPortLike): MIDIPortInfo {
155
+ return {
156
+ id: port.id,
157
+ name: port.name ?? "",
158
+ manufacturer: port.manufacturer ?? "",
159
+ state: port.state,
160
+ connection: port.connection,
161
+ };
162
+ }
163
+
164
+ function hasMessageData(event: Event): event is Event & { readonly data: Uint8Array | null } {
165
+ return "data" in event;
166
+ }
167
+
168
+ /**
169
+ * Access MIDI devices with the Web MIDI API.
170
+ *
171
+ * Nothing is requested until `request()` is called. Once granted, `inputs`
172
+ * and `outputs` follow `statechange` events, and `onMessage` receives
173
+ * messages from every input. Failures land in `error`. Listeners are removed
174
+ * when the owning reactive scope stops; outside a scope call `stop()`.
175
+ *
176
+ * Server rendering: `supported` is false, `status` stays `"idle"` and no
177
+ * access is requested.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const midi = useWebMIDI({ onMessage: ({ data }) => console.log(data) });
182
+ * await midi.request();
183
+ * midi.send(midi.outputs.value[0]!.id, [0x90, 60, 127]);
184
+ * ```
185
+ *
186
+ * @param options Host, access flags, and message callback.
187
+ * @default options {}
188
+ * @returns MIDI state and actions.
189
+ */
190
+ export function useWebMIDI(options: UseWebMIDIOptions = {}): WebMIDIControls {
191
+ const status = ref<MIDIAccessStatus>("idle");
192
+ const inputs = shallowRef<readonly MIDIPortInfo[]>([]);
193
+ const outputs = shallowRef<readonly MIDIPortInfo[]>([]);
194
+ const error = shallowRef<unknown>(undefined);
195
+ const listening = new Map<MIDIPortLike, (event: Event) => void>();
196
+ let access: MIDIAccessLike | undefined;
197
+ let generation = 0;
198
+
199
+ // Inside a component the host resolves only after mount (a post-flush
200
+ // job), so a hydrating client first renders the same unsupported state as
201
+ // the server. Outside components it resolves immediately.
202
+ const hydrated = shallowRef(!hasInjectionContext());
203
+ if (!hydrated.value) {
204
+ watchPostEffect(() => {
205
+ hydrated.value = true;
206
+ });
207
+ }
208
+ const resolveHost = (): MIDIHost | undefined =>
209
+ !hydrated.value
210
+ ? undefined
211
+ : options.host === undefined
212
+ ? browserMIDIHost()
213
+ : (toValue(options.host) ?? undefined);
214
+
215
+ const listen = (input: MIDIPortLike): void => {
216
+ const onMessage = options.onMessage;
217
+ if (!onMessage || listening.has(input)) return;
218
+ const listener = (event: Event): void => {
219
+ if (!hasMessageData(event) || !event.data) return;
220
+ onMessage({ data: event.data, timeStamp: event.timeStamp, inputId: input.id });
221
+ };
222
+ listening.set(input, listener);
223
+ input.addEventListener("midimessage", listener);
224
+ };
225
+
226
+ const unlisten = (): void => {
227
+ for (const [input, listener] of listening) input.removeEventListener("midimessage", listener);
228
+ listening.clear();
229
+ };
230
+
231
+ const refresh = (): void => {
232
+ if (!access) return;
233
+ const inputPorts = [...access.inputs.values()];
234
+ for (const input of inputPorts) listen(input);
235
+ inputs.value = inputPorts.map(describe);
236
+ outputs.value = [...access.outputs.values()].map(describe);
237
+ };
238
+
239
+ const stop = (): void => {
240
+ generation += 1;
241
+ unlisten();
242
+ access?.removeEventListener("statechange", refresh);
243
+ access = undefined;
244
+ inputs.value = [];
245
+ outputs.value = [];
246
+ if (status.value === "pending") status.value = "idle";
247
+ };
248
+
249
+ const request = async (): Promise<boolean> => {
250
+ const host = resolveHost();
251
+ if (!host) return false;
252
+ stop();
253
+ const current = generation;
254
+ status.value = "pending";
255
+ try {
256
+ const next = await host.requestMIDIAccess({
257
+ sysex: options.sysex ?? false,
258
+ software: options.software ?? false,
259
+ });
260
+ if (current !== generation) return false;
261
+ access = next;
262
+ next.addEventListener("statechange", refresh);
263
+ refresh();
264
+ status.value = "granted";
265
+ error.value = undefined;
266
+ return true;
267
+ } catch (cause) {
268
+ if (current !== generation) return false;
269
+ status.value = "denied";
270
+ error.value = cause;
271
+ return false;
272
+ }
273
+ };
274
+
275
+ const send = (
276
+ outputId: string,
277
+ data: Uint8Array | readonly number[],
278
+ timestamp?: number,
279
+ ): boolean => {
280
+ const output = access
281
+ ? [...access.outputs.values()].find((port) => port.id === outputId)
282
+ : undefined;
283
+ if (!output) return false;
284
+ try {
285
+ if (timestamp === undefined) output.send(Array.from(data));
286
+ else output.send(Array.from(data), timestamp);
287
+ return true;
288
+ } catch (cause) {
289
+ error.value = cause;
290
+ return false;
291
+ }
292
+ };
293
+
294
+ tryOnScopeDispose(stop);
295
+
296
+ return {
297
+ supported: computed(() => resolveHost() !== undefined),
298
+ status: readonly(status),
299
+ inputs: shallowReadonly(inputs),
300
+ outputs: shallowReadonly(outputs),
301
+ error: readonly(error),
302
+ request,
303
+ send,
304
+ stop,
305
+ };
306
+ }