@bquery/bquery 1.6.0 → 1.8.1

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 (402) hide show
  1. package/README.md +192 -18
  2. package/dist/a11y/announce.d.ts +43 -0
  3. package/dist/a11y/announce.d.ts.map +1 -0
  4. package/dist/a11y/audit.d.ts +42 -0
  5. package/dist/a11y/audit.d.ts.map +1 -0
  6. package/dist/a11y/index.d.ts +53 -0
  7. package/dist/a11y/index.d.ts.map +1 -0
  8. package/dist/a11y/media-preferences.d.ts +77 -0
  9. package/dist/a11y/media-preferences.d.ts.map +1 -0
  10. package/dist/a11y/roving-tab-index.d.ts +38 -0
  11. package/dist/a11y/roving-tab-index.d.ts.map +1 -0
  12. package/dist/a11y/skip-link.d.ts +37 -0
  13. package/dist/a11y/skip-link.d.ts.map +1 -0
  14. package/dist/a11y/trap-focus.d.ts +49 -0
  15. package/dist/a11y/trap-focus.d.ts.map +1 -0
  16. package/dist/a11y/types.d.ts +152 -0
  17. package/dist/a11y/types.d.ts.map +1 -0
  18. package/dist/a11y-DVBCy09c.js +421 -0
  19. package/dist/a11y-DVBCy09c.js.map +1 -0
  20. package/dist/a11y.es.mjs +14 -0
  21. package/dist/component/component.d.ts.map +1 -1
  22. package/dist/component/html.d.ts.map +1 -1
  23. package/dist/component/index.d.ts +2 -1
  24. package/dist/component/index.d.ts.map +1 -1
  25. package/dist/component/library.d.ts.map +1 -1
  26. package/dist/component/scope.d.ts +138 -0
  27. package/dist/component/scope.d.ts.map +1 -0
  28. package/dist/component/types.d.ts +53 -1
  29. package/dist/component/types.d.ts.map +1 -1
  30. package/dist/component-L3-JfOFz.js +684 -0
  31. package/dist/component-L3-JfOFz.js.map +1 -0
  32. package/dist/component.es.mjs +9 -6
  33. package/dist/{config-DRmZZno3.js → config-DhT9auRm.js} +4 -4
  34. package/dist/{config-DRmZZno3.js.map → config-DhT9auRm.js.map} +1 -1
  35. package/dist/constraints-D5RHQLmP.js +100 -0
  36. package/dist/constraints-D5RHQLmP.js.map +1 -0
  37. package/dist/core/collection.d.ts +134 -0
  38. package/dist/core/collection.d.ts.map +1 -1
  39. package/dist/core/element.d.ts +120 -0
  40. package/dist/core/element.d.ts.map +1 -1
  41. package/dist/core/env.d.ts +18 -0
  42. package/dist/core/env.d.ts.map +1 -0
  43. package/dist/core/index.d.ts +1 -0
  44. package/dist/core/index.d.ts.map +1 -1
  45. package/dist/core/shared.d.ts +14 -0
  46. package/dist/core/shared.d.ts.map +1 -1
  47. package/dist/core/utils/index.d.ts +52 -41
  48. package/dist/core/utils/index.d.ts.map +1 -1
  49. package/dist/core-DdtZHzsS.js +168 -0
  50. package/dist/core-DdtZHzsS.js.map +1 -0
  51. package/dist/{core-CCEabVHl.js → core-EMYSLzaT.js} +293 -194
  52. package/dist/core-EMYSLzaT.js.map +1 -0
  53. package/dist/core.es.mjs +48 -46
  54. package/dist/custom-directives-Dr4C5lVV.js +9 -0
  55. package/dist/custom-directives-Dr4C5lVV.js.map +1 -0
  56. package/dist/devtools/devtools.d.ts +212 -0
  57. package/dist/devtools/devtools.d.ts.map +1 -0
  58. package/dist/devtools/index.d.ts +20 -0
  59. package/dist/devtools/index.d.ts.map +1 -0
  60. package/dist/devtools/types.d.ts +69 -0
  61. package/dist/devtools/types.d.ts.map +1 -0
  62. package/dist/devtools-BhB2iDPT.js +122 -0
  63. package/dist/devtools-BhB2iDPT.js.map +1 -0
  64. package/dist/devtools.es.mjs +19 -0
  65. package/dist/dnd/draggable.d.ts +51 -0
  66. package/dist/dnd/draggable.d.ts.map +1 -0
  67. package/dist/dnd/droppable.d.ts +38 -0
  68. package/dist/dnd/droppable.d.ts.map +1 -0
  69. package/dist/dnd/index.d.ts +47 -0
  70. package/dist/dnd/index.d.ts.map +1 -0
  71. package/dist/dnd/sortable.d.ts +43 -0
  72. package/dist/dnd/sortable.d.ts.map +1 -0
  73. package/dist/dnd/types.d.ts +250 -0
  74. package/dist/dnd/types.d.ts.map +1 -0
  75. package/dist/dnd-NwZBYh4l.js +244 -0
  76. package/dist/dnd-NwZBYh4l.js.map +1 -0
  77. package/dist/dnd.es.mjs +6 -0
  78. package/dist/env-CTdvLaH2.js +19 -0
  79. package/dist/env-CTdvLaH2.js.map +1 -0
  80. package/dist/forms/create-form.d.ts +49 -0
  81. package/dist/forms/create-form.d.ts.map +1 -0
  82. package/dist/forms/index.d.ts +40 -0
  83. package/dist/forms/index.d.ts.map +1 -0
  84. package/dist/forms/types.d.ts +185 -0
  85. package/dist/forms/types.d.ts.map +1 -0
  86. package/dist/forms/use-field.d.ts +34 -0
  87. package/dist/forms/use-field.d.ts.map +1 -0
  88. package/dist/forms/validators.d.ts +204 -0
  89. package/dist/forms/validators.d.ts.map +1 -0
  90. package/dist/forms-UcRHsYxC.js +227 -0
  91. package/dist/forms-UcRHsYxC.js.map +1 -0
  92. package/dist/forms.es.mjs +16 -0
  93. package/dist/full.d.ts +30 -11
  94. package/dist/full.d.ts.map +1 -1
  95. package/dist/full.es.mjs +209 -93
  96. package/dist/full.iife.js +47 -31
  97. package/dist/full.iife.js.map +1 -1
  98. package/dist/full.umd.js +47 -31
  99. package/dist/full.umd.js.map +1 -1
  100. package/dist/function-Cybd57JV.js +33 -0
  101. package/dist/function-Cybd57JV.js.map +1 -0
  102. package/dist/i18n/formatting.d.ts +40 -0
  103. package/dist/i18n/formatting.d.ts.map +1 -0
  104. package/dist/i18n/i18n.d.ts +48 -0
  105. package/dist/i18n/i18n.d.ts.map +1 -0
  106. package/dist/i18n/index.d.ts +57 -0
  107. package/dist/i18n/index.d.ts.map +1 -0
  108. package/dist/i18n/translate.d.ts +83 -0
  109. package/dist/i18n/translate.d.ts.map +1 -0
  110. package/dist/i18n/types.d.ts +156 -0
  111. package/dist/i18n/types.d.ts.map +1 -0
  112. package/dist/i18n-kuF6Ekj6.js +89 -0
  113. package/dist/i18n-kuF6Ekj6.js.map +1 -0
  114. package/dist/i18n.es.mjs +6 -0
  115. package/dist/index.d.ts +11 -0
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.es.mjs +257 -143
  118. package/dist/media/battery.d.ts +35 -0
  119. package/dist/media/battery.d.ts.map +1 -0
  120. package/dist/media/breakpoints.d.ts +51 -0
  121. package/dist/media/breakpoints.d.ts.map +1 -0
  122. package/dist/media/clipboard.d.ts +30 -0
  123. package/dist/media/clipboard.d.ts.map +1 -0
  124. package/dist/media/device-sensors.d.ts +54 -0
  125. package/dist/media/device-sensors.d.ts.map +1 -0
  126. package/dist/media/geolocation.d.ts +38 -0
  127. package/dist/media/geolocation.d.ts.map +1 -0
  128. package/dist/media/index.d.ts +42 -0
  129. package/dist/media/index.d.ts.map +1 -0
  130. package/dist/media/media-query.d.ts +36 -0
  131. package/dist/media/media-query.d.ts.map +1 -0
  132. package/dist/media/network.d.ts +35 -0
  133. package/dist/media/network.d.ts.map +1 -0
  134. package/dist/media/types.d.ts +173 -0
  135. package/dist/media/types.d.ts.map +1 -0
  136. package/dist/media/viewport.d.ts +32 -0
  137. package/dist/media/viewport.d.ts.map +1 -0
  138. package/dist/media-i-fB5WxI.js +340 -0
  139. package/dist/media-i-fB5WxI.js.map +1 -0
  140. package/dist/media.es.mjs +12 -0
  141. package/dist/motion/index.d.ts +7 -3
  142. package/dist/motion/index.d.ts.map +1 -1
  143. package/dist/motion/morph.d.ts +27 -0
  144. package/dist/motion/morph.d.ts.map +1 -0
  145. package/dist/motion/parallax.d.ts +30 -0
  146. package/dist/motion/parallax.d.ts.map +1 -0
  147. package/dist/motion/reduced-motion.d.ts +36 -3
  148. package/dist/motion/reduced-motion.d.ts.map +1 -1
  149. package/dist/motion/types.d.ts +58 -0
  150. package/dist/motion/types.d.ts.map +1 -1
  151. package/dist/motion/typewriter.d.ts +31 -0
  152. package/dist/motion/typewriter.d.ts.map +1 -0
  153. package/dist/motion-BJsAuULb.js +530 -0
  154. package/dist/motion-BJsAuULb.js.map +1 -0
  155. package/dist/motion.es.mjs +27 -23
  156. package/dist/{view-C70lA3vf.js → mount-B4Y8bk8Z.js} +166 -160
  157. package/dist/mount-B4Y8bk8Z.js.map +1 -0
  158. package/dist/{object-qGpWr6-J.js → object-BCk-1c8T.js} +5 -4
  159. package/dist/{object-qGpWr6-J.js.map → object-BCk-1c8T.js.map} +1 -1
  160. package/dist/{platform-Dr9b6fsq.js → platform-Dw2gE3zI.js} +21 -22
  161. package/dist/{platform-Dr9b6fsq.js.map → platform-Dw2gE3zI.js.map} +1 -1
  162. package/dist/platform.es.mjs +2 -2
  163. package/dist/plugin/index.d.ts +22 -0
  164. package/dist/plugin/index.d.ts.map +1 -0
  165. package/dist/plugin/registry.d.ts +108 -0
  166. package/dist/plugin/registry.d.ts.map +1 -0
  167. package/dist/plugin/types.d.ts +110 -0
  168. package/dist/plugin/types.d.ts.map +1 -0
  169. package/dist/plugin-C2WuC8SF.js +66 -0
  170. package/dist/plugin-C2WuC8SF.js.map +1 -0
  171. package/dist/plugin.es.mjs +9 -0
  172. package/dist/reactive/async-data.d.ts +28 -3
  173. package/dist/reactive/async-data.d.ts.map +1 -1
  174. package/dist/reactive/computed.d.ts +10 -0
  175. package/dist/reactive/computed.d.ts.map +1 -1
  176. package/dist/reactive/effect.d.ts +3 -0
  177. package/dist/reactive/effect.d.ts.map +1 -1
  178. package/dist/reactive/http.d.ts +194 -0
  179. package/dist/reactive/http.d.ts.map +1 -0
  180. package/dist/reactive/index.d.ts +2 -2
  181. package/dist/reactive/index.d.ts.map +1 -1
  182. package/dist/reactive/pagination.d.ts +126 -0
  183. package/dist/reactive/pagination.d.ts.map +1 -0
  184. package/dist/reactive/polling.d.ts +55 -0
  185. package/dist/reactive/polling.d.ts.map +1 -0
  186. package/dist/reactive/readonly.d.ts +20 -1
  187. package/dist/reactive/readonly.d.ts.map +1 -1
  188. package/dist/reactive/rest.d.ts +293 -0
  189. package/dist/reactive/rest.d.ts.map +1 -0
  190. package/dist/reactive/scope.d.ts +140 -0
  191. package/dist/reactive/scope.d.ts.map +1 -0
  192. package/dist/reactive/signal.d.ts +16 -2
  193. package/dist/reactive/signal.d.ts.map +1 -1
  194. package/dist/reactive/to-value.d.ts +57 -0
  195. package/dist/reactive/to-value.d.ts.map +1 -0
  196. package/dist/reactive/websocket.d.ts +285 -0
  197. package/dist/reactive/websocket.d.ts.map +1 -0
  198. package/dist/reactive-DwkhUJfP.js +1148 -0
  199. package/dist/reactive-DwkhUJfP.js.map +1 -0
  200. package/dist/reactive.es.mjs +38 -20
  201. package/dist/registry-B08iilIh.js +26 -0
  202. package/dist/registry-B08iilIh.js.map +1 -0
  203. package/dist/router/bq-link.d.ts +112 -0
  204. package/dist/router/bq-link.d.ts.map +1 -0
  205. package/dist/router/constraints.d.ts +9 -0
  206. package/dist/router/constraints.d.ts.map +1 -0
  207. package/dist/router/index.d.ts +15 -7
  208. package/dist/router/index.d.ts.map +1 -1
  209. package/dist/router/match.d.ts +0 -1
  210. package/dist/router/match.d.ts.map +1 -1
  211. package/dist/router/path-pattern.d.ts +14 -0
  212. package/dist/router/path-pattern.d.ts.map +1 -0
  213. package/dist/router/query.d.ts.map +1 -1
  214. package/dist/router/router.d.ts +3 -1
  215. package/dist/router/router.d.ts.map +1 -1
  216. package/dist/router/state.d.ts +25 -2
  217. package/dist/router/state.d.ts.map +1 -1
  218. package/dist/router/types.d.ts +48 -4
  219. package/dist/router/types.d.ts.map +1 -1
  220. package/dist/router/use-route.d.ts +50 -0
  221. package/dist/router/use-route.d.ts.map +1 -0
  222. package/dist/router/utils.d.ts +3 -0
  223. package/dist/router/utils.d.ts.map +1 -1
  224. package/dist/router-CQikC9Ed.js +492 -0
  225. package/dist/router-CQikC9Ed.js.map +1 -0
  226. package/dist/router.es.mjs +14 -10
  227. package/dist/{sanitize-Bs2dkMby.js → sanitize-B1V4JswB.js} +2 -1
  228. package/dist/{sanitize-Bs2dkMby.js.map → sanitize-B1V4JswB.js.map} +1 -1
  229. package/dist/security/index.d.ts +2 -2
  230. package/dist/security/index.d.ts.map +1 -1
  231. package/dist/security.es.mjs +1 -1
  232. package/dist/ssr/hydrate.d.ts +65 -0
  233. package/dist/ssr/hydrate.d.ts.map +1 -0
  234. package/dist/ssr/index.d.ts +59 -0
  235. package/dist/ssr/index.d.ts.map +1 -0
  236. package/dist/ssr/render.d.ts +62 -0
  237. package/dist/ssr/render.d.ts.map +1 -0
  238. package/dist/ssr/serialize.d.ts +118 -0
  239. package/dist/ssr/serialize.d.ts.map +1 -0
  240. package/dist/ssr/types.d.ts +70 -0
  241. package/dist/ssr/types.d.ts.map +1 -0
  242. package/dist/ssr-_dAcGdzu.js +248 -0
  243. package/dist/ssr-_dAcGdzu.js.map +1 -0
  244. package/dist/ssr.es.mjs +9 -0
  245. package/dist/store/create-store.d.ts.map +1 -1
  246. package/dist/store/index.d.ts +1 -1
  247. package/dist/store/index.d.ts.map +1 -1
  248. package/dist/store/persisted.d.ts +38 -4
  249. package/dist/store/persisted.d.ts.map +1 -1
  250. package/dist/store/types.d.ts +138 -1
  251. package/dist/store/types.d.ts.map +1 -1
  252. package/dist/store/utils.d.ts +2 -2
  253. package/dist/store/utils.d.ts.map +1 -1
  254. package/dist/store-Cb3gPRve.js +338 -0
  255. package/dist/store-Cb3gPRve.js.map +1 -0
  256. package/dist/store.es.mjs +11 -10
  257. package/dist/storybook/index.d.ts.map +1 -1
  258. package/dist/storybook.es.mjs +1 -1
  259. package/dist/storybook.es.mjs.map +1 -1
  260. package/dist/testing/index.d.ts +23 -0
  261. package/dist/testing/index.d.ts.map +1 -0
  262. package/dist/testing/testing.d.ts +156 -0
  263. package/dist/testing/testing.d.ts.map +1 -0
  264. package/dist/testing/types.d.ts +134 -0
  265. package/dist/testing/types.d.ts.map +1 -0
  266. package/dist/testing-C5Sjfsna.js +224 -0
  267. package/dist/testing-C5Sjfsna.js.map +1 -0
  268. package/dist/testing.es.mjs +9 -0
  269. package/dist/type-guards-BMX2c0LP.js +44 -0
  270. package/dist/type-guards-BMX2c0LP.js.map +1 -0
  271. package/dist/untrack-D0fnO5k2.js +36 -0
  272. package/dist/untrack-D0fnO5k2.js.map +1 -0
  273. package/dist/view/custom-directives.d.ts +20 -0
  274. package/dist/view/custom-directives.d.ts.map +1 -0
  275. package/dist/view/evaluate.d.ts.map +1 -1
  276. package/dist/view/process.d.ts.map +1 -1
  277. package/dist/view.es.mjs +9 -9
  278. package/package.json +47 -11
  279. package/src/a11y/announce.ts +131 -0
  280. package/src/a11y/audit.ts +314 -0
  281. package/src/a11y/index.ts +68 -0
  282. package/src/a11y/media-preferences.ts +255 -0
  283. package/src/a11y/roving-tab-index.ts +164 -0
  284. package/src/a11y/skip-link.ts +255 -0
  285. package/src/a11y/trap-focus.ts +184 -0
  286. package/src/a11y/types.ts +183 -0
  287. package/src/component/component.ts +599 -524
  288. package/src/component/html.ts +153 -153
  289. package/src/component/index.ts +52 -50
  290. package/src/component/library.ts +540 -518
  291. package/src/component/scope.ts +212 -0
  292. package/src/component/types.ts +310 -256
  293. package/src/core/collection.ts +249 -1
  294. package/src/core/element.ts +252 -11
  295. package/src/core/env.ts +60 -0
  296. package/src/core/index.ts +1 -0
  297. package/src/core/shared.ts +64 -0
  298. package/src/core/utils/index.ts +66 -1
  299. package/src/devtools/devtools.ts +410 -0
  300. package/src/devtools/index.ts +48 -0
  301. package/src/devtools/types.ts +104 -0
  302. package/src/dnd/draggable.ts +296 -0
  303. package/src/dnd/droppable.ts +228 -0
  304. package/src/dnd/index.ts +62 -0
  305. package/src/dnd/sortable.ts +307 -0
  306. package/src/dnd/types.ts +293 -0
  307. package/src/forms/create-form.ts +320 -0
  308. package/src/forms/index.ts +70 -0
  309. package/src/forms/types.ts +203 -0
  310. package/src/forms/use-field.ts +231 -0
  311. package/src/forms/validators.ts +294 -0
  312. package/src/full.ts +554 -229
  313. package/src/i18n/formatting.ts +67 -0
  314. package/src/i18n/i18n.ts +200 -0
  315. package/src/i18n/index.ts +67 -0
  316. package/src/i18n/translate.ts +182 -0
  317. package/src/i18n/types.ts +171 -0
  318. package/src/index.ts +72 -0
  319. package/src/media/battery.ts +116 -0
  320. package/src/media/breakpoints.ts +129 -0
  321. package/src/media/clipboard.ts +80 -0
  322. package/src/media/device-sensors.ts +158 -0
  323. package/src/media/geolocation.ts +119 -0
  324. package/src/media/index.ts +76 -0
  325. package/src/media/media-query.ts +92 -0
  326. package/src/media/network.ts +115 -0
  327. package/src/media/types.ts +177 -0
  328. package/src/media/viewport.ts +84 -0
  329. package/src/motion/index.ts +11 -2
  330. package/src/motion/morph.ts +151 -0
  331. package/src/motion/parallax.ts +120 -0
  332. package/src/motion/reduced-motion.ts +52 -3
  333. package/src/motion/types.ts +63 -0
  334. package/src/motion/typewriter.ts +164 -0
  335. package/src/plugin/index.ts +37 -0
  336. package/src/plugin/registry.ts +284 -0
  337. package/src/plugin/types.ts +137 -0
  338. package/src/reactive/async-data.ts +250 -29
  339. package/src/reactive/computed.ts +53 -1
  340. package/src/reactive/effect.ts +29 -6
  341. package/src/reactive/http.ts +790 -0
  342. package/src/reactive/index.ts +60 -0
  343. package/src/reactive/pagination.ts +317 -0
  344. package/src/reactive/polling.ts +179 -0
  345. package/src/reactive/readonly.ts +52 -8
  346. package/src/reactive/rest.ts +859 -0
  347. package/src/reactive/scope.ts +276 -0
  348. package/src/reactive/signal.ts +61 -1
  349. package/src/reactive/to-value.ts +71 -0
  350. package/src/reactive/websocket.ts +849 -0
  351. package/src/router/bq-link.ts +279 -0
  352. package/src/router/constraints.ts +204 -0
  353. package/src/router/index.ts +15 -7
  354. package/src/router/match.ts +255 -49
  355. package/src/router/path-pattern.ts +52 -0
  356. package/src/router/query.ts +3 -0
  357. package/src/router/router.ts +258 -48
  358. package/src/router/state.ts +51 -3
  359. package/src/router/types.ts +50 -4
  360. package/src/router/use-route.ts +68 -0
  361. package/src/router/utils.ts +44 -3
  362. package/src/security/index.ts +12 -17
  363. package/src/security/sanitize.ts +70 -70
  364. package/src/security/trusted-html.ts +71 -71
  365. package/src/ssr/hydrate.ts +84 -0
  366. package/src/ssr/index.ts +70 -0
  367. package/src/ssr/render.ts +508 -0
  368. package/src/ssr/serialize.ts +296 -0
  369. package/src/ssr/types.ts +81 -0
  370. package/src/store/create-store.ts +146 -8
  371. package/src/store/define-store.ts +49 -49
  372. package/src/store/index.ts +5 -0
  373. package/src/store/mapping.ts +74 -74
  374. package/src/store/persisted.ts +245 -62
  375. package/src/store/types.ts +247 -92
  376. package/src/store/utils.ts +4 -10
  377. package/src/store/watch.ts +53 -53
  378. package/src/storybook/index.ts +480 -479
  379. package/src/testing/index.ts +42 -0
  380. package/src/testing/testing.ts +593 -0
  381. package/src/testing/types.ts +170 -0
  382. package/src/view/custom-directives.ts +28 -0
  383. package/src/view/evaluate.ts +2 -0
  384. package/src/view/process.ts +19 -3
  385. package/dist/component-BEQgt5hl.js +0 -600
  386. package/dist/component-BEQgt5hl.js.map +0 -1
  387. package/dist/core-BGQJVw0-.js +0 -35
  388. package/dist/core-BGQJVw0-.js.map +0 -1
  389. package/dist/core-CCEabVHl.js.map +0 -1
  390. package/dist/effect-AFRW_Plg.js +0 -84
  391. package/dist/effect-AFRW_Plg.js.map +0 -1
  392. package/dist/motion-D9TcHxOF.js +0 -415
  393. package/dist/motion-D9TcHxOF.js.map +0 -1
  394. package/dist/reactive-DSkct0dO.js +0 -254
  395. package/dist/reactive-DSkct0dO.js.map +0 -1
  396. package/dist/router-CbDhl8rS.js +0 -188
  397. package/dist/router-CbDhl8rS.js.map +0 -1
  398. package/dist/store-BwDvI45q.js +0 -263
  399. package/dist/store-BwDvI45q.js.map +0 -1
  400. package/dist/untrack-B0rVscTc.js +0 -7
  401. package/dist/untrack-B0rVscTc.js.map +0 -1
  402. package/dist/view-C70lA3vf.js.map +0 -1
@@ -5,7 +5,7 @@ import {
5
5
  type InsertableContent,
6
6
  } from './dom';
7
7
  import { BQueryElement } from './element';
8
- import { applyAll, toElementList } from './shared';
8
+ import { applyAll, getInnerSize, getOuterSize, isHTMLElement, toElementList } from './shared';
9
9
 
10
10
  /** Handler signature for delegated events */
11
11
  type DelegatedHandler = (event: Event, target: Element) => void;
@@ -381,6 +381,103 @@ export class BQueryCollection {
381
381
  return new BQueryCollection(replacements);
382
382
  }
383
383
 
384
+ /**
385
+ * Removes all elements from the DOM while keeping the wrapped nodes available
386
+ * for later reuse.
387
+ *
388
+ * @returns The instance for method chaining
389
+ */
390
+ detach(): this {
391
+ return this.remove();
392
+ }
393
+
394
+ /**
395
+ * Gets the zero-based sibling index of the first element in the collection.
396
+ *
397
+ * @returns Index of the first element, or -1 when unavailable
398
+ */
399
+ index(): number {
400
+ const first = this.first();
401
+ if (!first?.parentElement) {
402
+ return -1;
403
+ }
404
+ return Array.from(first.parentElement.children).indexOf(first);
405
+ }
406
+
407
+ /**
408
+ * Returns the child nodes of the first element, including text nodes and comments.
409
+ *
410
+ * @returns Array of child nodes from the first element
411
+ */
412
+ contents(): ChildNode[] {
413
+ return Array.from(this.first()?.childNodes ?? []);
414
+ }
415
+
416
+ /**
417
+ * Gets the offset parent of the first element in the collection.
418
+ *
419
+ * @returns Offset parent element, or null when unavailable
420
+ */
421
+ offsetParent(): Element | null {
422
+ const first = this.first();
423
+ return isHTMLElement(first) ? first.offsetParent : null;
424
+ }
425
+
426
+ /**
427
+ * Gets the position of the first element relative to its offset parent.
428
+ *
429
+ * @returns Position object with top and left coordinates
430
+ */
431
+ position(): { top: number; left: number } {
432
+ const first = this.first();
433
+ if (!isHTMLElement(first)) {
434
+ return { top: 0, left: 0 };
435
+ }
436
+
437
+ return {
438
+ top: first.offsetTop,
439
+ left: first.offsetLeft,
440
+ };
441
+ }
442
+
443
+ /**
444
+ * Gets the inner width of the first element (content + padding, excluding border).
445
+ *
446
+ * @returns Inner width in pixels, or 0 when the collection is empty
447
+ */
448
+ innerWidth(): number {
449
+ return getInnerSize(this.first(), 'width');
450
+ }
451
+
452
+ /**
453
+ * Gets the inner height of the first element (content + padding, excluding border).
454
+ *
455
+ * @returns Inner height in pixels, or 0 when the collection is empty
456
+ */
457
+ innerHeight(): number {
458
+ return getInnerSize(this.first(), 'height');
459
+ }
460
+
461
+ /**
462
+ * Gets the outer width of the first element, optionally including margins.
463
+ *
464
+ * @param includeMargin - When true, include horizontal margins
465
+ * @returns Outer width in pixels
466
+ */
467
+ outerWidth(includeMargin: boolean = false): number {
468
+ return getOuterSize(this.first(), 'width', includeMargin);
469
+ }
470
+
471
+ /**
472
+ * Gets the outer height of the first element, optionally including margins.
473
+ *
474
+ * @param includeMargin - When true, include vertical margins
475
+ * @returns Outer height in pixels
476
+ */
477
+ outerHeight(includeMargin: boolean = false): number {
478
+ return getOuterSize(this.first(), 'height', includeMargin);
479
+ }
480
+
384
481
  /**
385
482
  * Shows all elements.
386
483
  *
@@ -585,6 +682,157 @@ export class BQueryCollection {
585
682
  return new BQueryCollection(results);
586
683
  }
587
684
 
685
+ /**
686
+ * Gets the closest element or ancestor matching a selector for each element in
687
+ * the collection, including the element itself. Duplicates are removed from the
688
+ * result.
689
+ *
690
+ * @param selector - CSS selector to match
691
+ * @returns A new BQueryCollection with matching elements or ancestors
692
+ *
693
+ * @example
694
+ * ```ts
695
+ * $$('.item').closest('.container');
696
+ * ```
697
+ */
698
+ closest(selector: string): BQueryCollection {
699
+ const seen = new Set<Element>();
700
+ const results: Element[] = [];
701
+ for (const el of this.elements) {
702
+ const match = el.closest(selector);
703
+ if (match && !seen.has(match)) {
704
+ seen.add(match);
705
+ results.push(match);
706
+ }
707
+ }
708
+ return new BQueryCollection(results);
709
+ }
710
+
711
+ /**
712
+ * Gets the parent element of each element in the collection.
713
+ * Duplicates are removed (e.g. siblings sharing a parent).
714
+ *
715
+ * @returns A new BQueryCollection with unique parent elements
716
+ *
717
+ * @example
718
+ * ```ts
719
+ * $$('.item').parent().addClass('has-items');
720
+ * ```
721
+ */
722
+ parent(): BQueryCollection {
723
+ const seen = new Set<Element>();
724
+ const results: Element[] = [];
725
+ for (const el of this.elements) {
726
+ const p = el.parentElement;
727
+ if (p && !seen.has(p)) {
728
+ seen.add(p);
729
+ results.push(p);
730
+ }
731
+ }
732
+ return new BQueryCollection(results);
733
+ }
734
+
735
+ /**
736
+ * Gets the direct children of every element in the collection.
737
+ * Duplicates are removed from the result.
738
+ *
739
+ * @returns A new BQueryCollection with child elements
740
+ *
741
+ * @example
742
+ * ```ts
743
+ * $$('.list').children().addClass('child');
744
+ * ```
745
+ */
746
+ children(): BQueryCollection {
747
+ const seen = new Set<Element>();
748
+ const results: Element[] = [];
749
+ for (const el of this.elements) {
750
+ for (const child of Array.from(el.children)) {
751
+ if (!seen.has(child)) {
752
+ seen.add(child);
753
+ results.push(child);
754
+ }
755
+ }
756
+ }
757
+ return new BQueryCollection(results);
758
+ }
759
+
760
+ /**
761
+ * Gets all siblings of every element in the collection (excluding the
762
+ * elements themselves). Duplicates are removed.
763
+ *
764
+ * @returns A new BQueryCollection with sibling elements
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * $$('.active').siblings().removeClass('active');
769
+ * ```
770
+ */
771
+ siblings(): BQueryCollection {
772
+ const selfSet = new Set(this.elements);
773
+ const seen = new Set<Element>();
774
+ const results: Element[] = [];
775
+ for (const el of this.elements) {
776
+ const parent = el.parentElement;
777
+ if (!parent) continue;
778
+ for (const sibling of Array.from(parent.children)) {
779
+ if (!selfSet.has(sibling) && !seen.has(sibling)) {
780
+ seen.add(sibling);
781
+ results.push(sibling);
782
+ }
783
+ }
784
+ }
785
+ return new BQueryCollection(results);
786
+ }
787
+
788
+ /**
789
+ * Gets the next sibling element of each element in the collection.
790
+ * Elements without a next sibling are skipped.
791
+ *
792
+ * @returns A new BQueryCollection with next sibling elements
793
+ *
794
+ * @example
795
+ * ```ts
796
+ * $$('.current').next().addClass('upcoming');
797
+ * ```
798
+ */
799
+ next(): BQueryCollection {
800
+ const seen = new Set<Element>();
801
+ const results: Element[] = [];
802
+ for (const el of this.elements) {
803
+ const n = el.nextElementSibling;
804
+ if (n && !seen.has(n)) {
805
+ seen.add(n);
806
+ results.push(n);
807
+ }
808
+ }
809
+ return new BQueryCollection(results);
810
+ }
811
+
812
+ /**
813
+ * Gets the previous sibling element of each element in the collection.
814
+ * Elements without a previous sibling are skipped.
815
+ *
816
+ * @returns A new BQueryCollection with previous sibling elements
817
+ *
818
+ * @example
819
+ * ```ts
820
+ * $$('.current').prev().addClass('previous');
821
+ * ```
822
+ */
823
+ prev(): BQueryCollection {
824
+ const seen = new Set<Element>();
825
+ const results: Element[] = [];
826
+ for (const el of this.elements) {
827
+ const p = el.previousElementSibling;
828
+ if (p && !seen.has(p)) {
829
+ seen.add(p);
830
+ results.push(p);
831
+ }
832
+ }
833
+ return new BQueryCollection(results);
834
+ }
835
+
588
836
  /**
589
837
  * Removes all elements from the DOM.
590
838
  *
@@ -1,4 +1,6 @@
1
1
  import { createElementFromHtml, insertContent, setHtml } from './dom';
2
+ import { getInnerSize, getOuterSize, isHTMLElement } from './shared';
3
+ import { isPrototypePollutionKey } from './utils/object';
2
4
 
3
5
  /**
4
6
  * Wrapper for a single DOM element.
@@ -25,6 +27,95 @@ import { createElementFromHtml, insertContent, setHtml } from './dom';
25
27
  /** Handler signature for delegated events */
26
28
  type DelegatedHandler = (event: Event, target: Element) => void;
27
29
 
30
+ type SerializableFormControl = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
31
+
32
+ const isSerializableFormControl = (element: Element): element is SerializableFormControl => {
33
+ const tagName = element.tagName.toLowerCase();
34
+ return tagName === 'input' || tagName === 'textarea' || tagName === 'select';
35
+ };
36
+
37
+ const collectFormEntries = (form: HTMLFormElement): Array<[string, string]> => {
38
+ const entries: Array<[string, string]> = [];
39
+ const elementCtor = form.ownerDocument.defaultView?.Element ?? Element;
40
+
41
+ for (const control of Array.from(form.elements)) {
42
+ if (!(control instanceof elementCtor) || !isSerializableFormControl(control)) {
43
+ continue;
44
+ }
45
+
46
+ const name = control.name;
47
+ if (!name || control.disabled || isPrototypePollutionKey(name)) {
48
+ continue;
49
+ }
50
+
51
+ if (control.tagName.toLowerCase() === 'input') {
52
+ const input = control as HTMLInputElement;
53
+ const type = input.type.toLowerCase();
54
+
55
+ if (type === 'checkbox' || type === 'radio') {
56
+ if (input.checked) {
57
+ entries.push([name, input.value]);
58
+ }
59
+ continue;
60
+ }
61
+
62
+ if (
63
+ type === 'file' ||
64
+ type === 'submit' ||
65
+ type === 'button' ||
66
+ type === 'reset' ||
67
+ type === 'image'
68
+ ) {
69
+ continue;
70
+ }
71
+
72
+ entries.push([name, input.value]);
73
+ continue;
74
+ }
75
+
76
+ if (control.tagName.toLowerCase() === 'select') {
77
+ const select = control as HTMLSelectElement;
78
+
79
+ if (select.multiple) {
80
+ for (const option of Array.from(select.selectedOptions)) {
81
+ entries.push([name, option.value]);
82
+ }
83
+ } else {
84
+ entries.push([name, select.value]);
85
+ }
86
+ continue;
87
+ }
88
+
89
+ entries.push([name, (control as HTMLTextAreaElement).value]);
90
+ }
91
+
92
+ return entries;
93
+ };
94
+
95
+ const getFormEntries = (form: HTMLFormElement): Array<[string, string]> => {
96
+ if (typeof FormData === 'function') {
97
+ try {
98
+ const entries: Array<[string, string]> = [];
99
+
100
+ for (const [key, value] of new FormData(form).entries()) {
101
+ if (isPrototypePollutionKey(key) || typeof value !== 'string') {
102
+ continue;
103
+ }
104
+ entries.push([key, value]);
105
+ }
106
+
107
+ // Some environments expose FormData(form) but fail to populate entries for
108
+ // successful controls. Fall back to manual collection only in that zero-entry case.
109
+ return entries.length > 0 ? entries : collectFormEntries(form);
110
+ } catch {
111
+ // Fall back to manual collection when FormData is unavailable for this form
112
+ // or the environment does not fully support constructing it.
113
+ }
114
+ }
115
+
116
+ return collectFormEntries(form);
117
+ };
118
+
28
119
  export class BQueryElement {
29
120
  /**
30
121
  * Stores delegated event handlers for cleanup via undelegate().
@@ -307,6 +398,156 @@ export class BQueryElement {
307
398
  return new BQueryElement(newEl);
308
399
  }
309
400
 
401
+ /**
402
+ * Removes the element from the DOM while keeping the wrapped node available
403
+ * for later reuse.
404
+ *
405
+ * @returns The instance for method chaining
406
+ *
407
+ * @example
408
+ * ```ts
409
+ * const item = $('#item').detach();
410
+ * document.body.appendChild(item.raw);
411
+ * ```
412
+ */
413
+ detach(): this {
414
+ return this.remove();
415
+ }
416
+
417
+ /**
418
+ * Gets the zero-based index of the element among its element siblings.
419
+ *
420
+ * @returns Index within the parent element, or -1 when detached
421
+ *
422
+ * @example
423
+ * ```ts
424
+ * const index = $('#item').index();
425
+ * ```
426
+ */
427
+ index(): number {
428
+ const parent = this.element.parentElement;
429
+ if (!parent) {
430
+ return -1;
431
+ }
432
+ return Array.from(parent.children).indexOf(this.element);
433
+ }
434
+
435
+ /**
436
+ * Returns all child nodes, including text nodes and comments.
437
+ *
438
+ * @returns Array of child nodes
439
+ *
440
+ * @example
441
+ * ```ts
442
+ * const nodes = $('#content').contents();
443
+ * ```
444
+ */
445
+ contents(): ChildNode[] {
446
+ return Array.from(this.element.childNodes);
447
+ }
448
+
449
+ /**
450
+ * Gets the nearest positioned ancestor used for offset calculations.
451
+ *
452
+ * @returns The offset parent element, or null when unavailable
453
+ *
454
+ * @example
455
+ * ```ts
456
+ * const parent = $('#item').offsetParent();
457
+ * ```
458
+ */
459
+ offsetParent(): Element | null {
460
+ return isHTMLElement(this.element) ? this.element.offsetParent : null;
461
+ }
462
+
463
+ /**
464
+ * Gets the current position relative to the offset parent.
465
+ *
466
+ * @returns Position object with top and left coordinates
467
+ *
468
+ * @example
469
+ * ```ts
470
+ * const { top, left } = $('#item').position();
471
+ * ```
472
+ */
473
+ position(): { top: number; left: number } {
474
+ if (!isHTMLElement(this.element)) {
475
+ return { top: 0, left: 0 };
476
+ }
477
+
478
+ const el = this.element;
479
+ return {
480
+ top: el.offsetTop,
481
+ left: el.offsetLeft,
482
+ };
483
+ }
484
+
485
+ /**
486
+ * Gets the inner width of the element (content + padding, excluding border).
487
+ *
488
+ * This corresponds to the element's `clientWidth` and mirrors jQuery's
489
+ * `innerWidth()` method.
490
+ *
491
+ * @returns Inner width in pixels, or 0 for non-HTML elements
492
+ *
493
+ * @example
494
+ * ```ts
495
+ * const innerW = $('#panel').innerWidth();
496
+ * ```
497
+ */
498
+ innerWidth(): number {
499
+ return getInnerSize(this.element, 'width');
500
+ }
501
+
502
+ /**
503
+ * Gets the inner height of the element (content + padding, excluding border).
504
+ *
505
+ * This corresponds to the element's `clientHeight` and mirrors jQuery's
506
+ * `innerHeight()` method.
507
+ *
508
+ * @returns Inner height in pixels, or 0 for non-HTML elements
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * const innerH = $('#panel').innerHeight();
513
+ * ```
514
+ */
515
+ innerHeight(): number {
516
+ return getInnerSize(this.element, 'height');
517
+ }
518
+
519
+ /**
520
+ * Gets the outer width of the element, optionally including margins.
521
+ *
522
+ * @param includeMargin - When true, include horizontal margins
523
+ * @returns Outer width in pixels
524
+ *
525
+ * @example
526
+ * ```ts
527
+ * const width = $('#panel').outerWidth();
528
+ * const widthWithMargin = $('#panel').outerWidth(true);
529
+ * ```
530
+ */
531
+ outerWidth(includeMargin: boolean = false): number {
532
+ return getOuterSize(this.element, 'width', includeMargin);
533
+ }
534
+
535
+ /**
536
+ * Gets the outer height of the element, optionally including margins.
537
+ *
538
+ * @param includeMargin - When true, include vertical margins
539
+ * @returns Outer height in pixels
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * const height = $('#panel').outerHeight();
544
+ * const heightWithMargin = $('#panel').outerHeight(true);
545
+ * ```
546
+ */
547
+ outerHeight(includeMargin: boolean = false): number {
548
+ return getOuterSize(this.element, 'height', includeMargin);
549
+ }
550
+
310
551
  /**
311
552
  * Scrolls the element into view with configurable behavior.
312
553
  *
@@ -674,6 +915,11 @@ export class BQueryElement {
674
915
  * Serializes form data to a plain object.
675
916
  * Only works on form elements; returns empty object for non-forms.
676
917
  *
918
+ * For security hardening, the returned object uses a null prototype,
919
+ * so inherited members like `hasOwnProperty` are not available directly.
920
+ * Prefer `Object.keys()` or `Object.prototype.hasOwnProperty.call(...)`
921
+ * when checking for fields on the serialized result.
922
+ *
677
923
  * @returns Object with form field names as keys and values
678
924
  *
679
925
  * @example
@@ -681,6 +927,7 @@ export class BQueryElement {
681
927
  * // For a form with <input name="email" value="test@example.com">
682
928
  * const data = $('#myForm').serialize();
683
929
  * // { email: 'test@example.com' }
930
+ * Object.prototype.hasOwnProperty.call(data, 'email'); // true
684
931
  * ```
685
932
  */
686
933
  serialize(): Record<string, string | string[]> {
@@ -689,13 +936,10 @@ export class BQueryElement {
689
936
  return {};
690
937
  }
691
938
 
692
- const result: Record<string, string | string[]> = {};
693
- const formData = new FormData(form);
694
-
695
- for (const [key, value] of formData.entries()) {
696
- if (typeof value !== 'string') continue; // Skip File objects
939
+ const result = Object.create(null) as Record<string, string | string[]>;
697
940
 
698
- if (key in result) {
941
+ for (const [key, value] of getFormEntries(form)) {
942
+ if (Object.prototype.hasOwnProperty.call(result, key)) {
699
943
  // Handle multiple values (e.g., checkboxes)
700
944
  const existing = result[key];
701
945
  if (Array.isArray(existing)) {
@@ -728,13 +972,10 @@ export class BQueryElement {
728
972
  return '';
729
973
  }
730
974
 
731
- const formData = new FormData(form);
732
975
  const params = new URLSearchParams();
733
976
 
734
- for (const [key, value] of formData.entries()) {
735
- if (typeof value === 'string') {
736
- params.append(key, value);
737
- }
977
+ for (const [key, value] of getFormEntries(form)) {
978
+ params.append(key, value);
738
979
  }
739
980
 
740
981
  return params.toString();
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared environment detection helpers.
3
+ *
4
+ * @internal
5
+ */
6
+
7
+ type BQueryEnvGlobal = typeof globalThis & {
8
+ __BQUERY_DEV__?: boolean;
9
+ process?: {
10
+ env?: {
11
+ NODE_ENV?: string;
12
+ };
13
+ release?: {
14
+ name?: string;
15
+ };
16
+ versions?: {
17
+ node?: string;
18
+ };
19
+ };
20
+ };
21
+
22
+ /**
23
+ * Returns whether development-only diagnostics should be enabled.
24
+ *
25
+ * Priority:
26
+ * 1. Explicit global override via `globalThis.__BQUERY_DEV__`
27
+ * 2. `process.env.NODE_ENV`
28
+ * 3. Actual Node-like runtimes without `NODE_ENV` default to development
29
+ * 4. Production-safe fallback (`false`)
30
+ *
31
+ * @internal
32
+ */
33
+ export const detectDevEnvironment = (): boolean => {
34
+ try {
35
+ const globalObject = globalThis as BQueryEnvGlobal;
36
+
37
+ if (typeof globalObject.__BQUERY_DEV__ === 'boolean') {
38
+ return globalObject.__BQUERY_DEV__;
39
+ }
40
+
41
+ const nodeEnv = globalObject.process?.env?.NODE_ENV;
42
+ if (typeof nodeEnv === 'string') {
43
+ return nodeEnv !== 'production';
44
+ }
45
+
46
+ const nodeVersion = globalObject.process?.versions?.node;
47
+ if (typeof nodeVersion === 'string' && nodeVersion.length > 0) {
48
+ return true;
49
+ }
50
+
51
+ const releaseName = globalObject.process?.release?.name;
52
+ if (releaseName === 'node' || releaseName === 'io.js') {
53
+ return true;
54
+ }
55
+
56
+ return false;
57
+ } catch {
58
+ return false;
59
+ }
60
+ };
package/src/core/index.ts CHANGED
@@ -3,6 +3,7 @@ export { BQueryElement } from './element';
3
3
  export { $, $$ } from './selector';
4
4
  // Re-export the utils namespace for backward compatibility
5
5
  export { utils } from './utils';
6
+ export type { BQueryUtils } from './utils';
6
7
  // Export individual utilities (except internal helpers)
7
8
  export {
8
9
  chunk,
@@ -11,3 +11,67 @@ export const applyAll = (elements: ElementList, action: (el: Element) => void) =
11
11
  action(el);
12
12
  }
13
13
  };
14
+
15
+ /** @internal */
16
+ export const isHTMLElement = (element: Element | null | undefined): element is HTMLElement => {
17
+ if (!element) {
18
+ return false;
19
+ }
20
+
21
+ const view = element.ownerDocument?.defaultView;
22
+ const HTMLElementCtor = view?.HTMLElement ?? globalThis.HTMLElement;
23
+ return typeof HTMLElementCtor === 'function' && element instanceof HTMLElementCtor;
24
+ };
25
+
26
+ /**
27
+ * Gets an element's inner size (content + padding, excluding border and margin).
28
+ *
29
+ * @internal
30
+ */
31
+ export const getInnerSize = (
32
+ element: Element | null | undefined,
33
+ dimension: 'width' | 'height'
34
+ ): number => {
35
+ if (!isHTMLElement(element)) {
36
+ return 0;
37
+ }
38
+ return dimension === 'width' ? element.clientWidth : element.clientHeight;
39
+ };
40
+
41
+ /**
42
+ * Gets an element's outer size, optionally including margins.
43
+ *
44
+ * @internal
45
+ */
46
+ export const getOuterSize = (
47
+ element: Element | null | undefined,
48
+ dimension: 'width' | 'height',
49
+ includeMargin: boolean
50
+ ): number => {
51
+ if (!isHTMLElement(element)) {
52
+ return 0;
53
+ }
54
+
55
+ const size = dimension === 'width' ? element.offsetWidth : element.offsetHeight;
56
+ if (!includeMargin) {
57
+ return size;
58
+ }
59
+
60
+ const view = element.ownerDocument?.defaultView;
61
+ if (!view || typeof view.getComputedStyle !== 'function') {
62
+ return size;
63
+ }
64
+
65
+ const computedStyle = view.getComputedStyle(element);
66
+ const startMargin = Number.parseFloat(
67
+ computedStyle.getPropertyValue(dimension === 'width' ? 'margin-left' : 'margin-top')
68
+ );
69
+ const endMargin = Number.parseFloat(
70
+ computedStyle.getPropertyValue(dimension === 'width' ? 'margin-right' : 'margin-bottom')
71
+ );
72
+
73
+ const safeStartMargin = Number.isNaN(startMargin) ? 0 : startMargin;
74
+ const safeEndMargin = Number.isNaN(endMargin) ? 0 : endMargin;
75
+
76
+ return size + safeStartMargin + safeEndMargin;
77
+ };