@bquery/bquery 1.5.0 → 1.7.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/README.md +193 -23
- package/dist/a11y/announce.d.ts +43 -0
- package/dist/a11y/announce.d.ts.map +1 -0
- package/dist/a11y/audit.d.ts +42 -0
- package/dist/a11y/audit.d.ts.map +1 -0
- package/dist/a11y/index.d.ts +53 -0
- package/dist/a11y/index.d.ts.map +1 -0
- package/dist/a11y/media-preferences.d.ts +77 -0
- package/dist/a11y/media-preferences.d.ts.map +1 -0
- package/dist/a11y/roving-tab-index.d.ts +38 -0
- package/dist/a11y/roving-tab-index.d.ts.map +1 -0
- package/dist/a11y/skip-link.d.ts +37 -0
- package/dist/a11y/skip-link.d.ts.map +1 -0
- package/dist/a11y/trap-focus.d.ts +49 -0
- package/dist/a11y/trap-focus.d.ts.map +1 -0
- package/dist/a11y/types.d.ts +152 -0
- package/dist/a11y/types.d.ts.map +1 -0
- package/dist/a11y-C5QOVvRn.js +421 -0
- package/dist/a11y-C5QOVvRn.js.map +1 -0
- package/dist/a11y.es.mjs +14 -0
- package/dist/component/component.d.ts +13 -5
- package/dist/component/component.d.ts.map +1 -1
- package/dist/component/html.d.ts +40 -3
- package/dist/component/html.d.ts.map +1 -1
- package/dist/component/index.d.ts +3 -2
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/library.d.ts.map +1 -1
- package/dist/component/scope.d.ts +138 -0
- package/dist/component/scope.d.ts.map +1 -0
- package/dist/component/types.d.ts +184 -17
- package/dist/component/types.d.ts.map +1 -1
- package/dist/component-CuuTijA6.js +684 -0
- package/dist/component-CuuTijA6.js.map +1 -0
- package/dist/component.es.mjs +10 -6
- package/dist/{config-DRmZZno3.js → config-BW35FKuA.js} +4 -4
- package/dist/config-BW35FKuA.js.map +1 -0
- package/dist/constraints-3lV9yyBw.js +100 -0
- package/dist/constraints-3lV9yyBw.js.map +1 -0
- package/dist/core/collection.d.ts +48 -0
- package/dist/core/collection.d.ts.map +1 -1
- package/dist/core/element.d.ts +92 -0
- package/dist/core/element.d.ts.map +1 -1
- package/dist/core/env.d.ts +18 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/shared.d.ts +8 -0
- package/dist/core/shared.d.ts.map +1 -1
- package/dist/core/utils/index.d.ts +52 -41
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core-Cjl7GUu8.js +717 -0
- package/dist/core-Cjl7GUu8.js.map +1 -0
- package/dist/{core-DPdbItcq.js → core-DnlyjbF2.js} +1 -1
- package/dist/{core-DPdbItcq.js.map → core-DnlyjbF2.js.map} +1 -1
- package/dist/core.es.mjs +45 -44
- package/dist/custom-directives-7wAShnnd.js +9 -0
- package/dist/custom-directives-7wAShnnd.js.map +1 -0
- package/dist/devtools/devtools.d.ts +212 -0
- package/dist/devtools/devtools.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +20 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/types.d.ts +69 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools-D2fQLhDN.js +122 -0
- package/dist/devtools-D2fQLhDN.js.map +1 -0
- package/dist/devtools.es.mjs +19 -0
- package/dist/dnd/draggable.d.ts +51 -0
- package/dist/dnd/draggable.d.ts.map +1 -0
- package/dist/dnd/droppable.d.ts +38 -0
- package/dist/dnd/droppable.d.ts.map +1 -0
- package/dist/dnd/index.d.ts +47 -0
- package/dist/dnd/index.d.ts.map +1 -0
- package/dist/dnd/sortable.d.ts +43 -0
- package/dist/dnd/sortable.d.ts.map +1 -0
- package/dist/dnd/types.d.ts +250 -0
- package/dist/dnd/types.d.ts.map +1 -0
- package/dist/dnd-B8EgyzaI.js +244 -0
- package/dist/dnd-B8EgyzaI.js.map +1 -0
- package/dist/dnd.es.mjs +6 -0
- package/dist/env-NeVmr4Gf.js +19 -0
- package/dist/env-NeVmr4Gf.js.map +1 -0
- package/dist/forms/create-form.d.ts +49 -0
- package/dist/forms/create-form.d.ts.map +1 -0
- package/dist/forms/index.d.ts +39 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/types.d.ts +139 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/validators.d.ts +179 -0
- package/dist/forms/validators.d.ts.map +1 -0
- package/dist/forms-C3yovgH9.js +141 -0
- package/dist/forms-C3yovgH9.js.map +1 -0
- package/dist/forms.es.mjs +14 -0
- package/dist/full.d.ts +37 -9
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +186 -91
- package/dist/full.iife.js +47 -31
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +47 -31
- package/dist/full.umd.js.map +1 -1
- package/dist/i18n/formatting.d.ts +40 -0
- package/dist/i18n/formatting.d.ts.map +1 -0
- package/dist/i18n/i18n.d.ts +48 -0
- package/dist/i18n/i18n.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +57 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/translate.d.ts +83 -0
- package/dist/i18n/translate.d.ts.map +1 -0
- package/dist/i18n/types.d.ts +156 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n-BnnhTFOS.js +89 -0
- package/dist/i18n-BnnhTFOS.js.map +1 -0
- package/dist/i18n.es.mjs +6 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.mjs +233 -138
- package/dist/media/battery.d.ts +35 -0
- package/dist/media/battery.d.ts.map +1 -0
- package/dist/media/breakpoints.d.ts +51 -0
- package/dist/media/breakpoints.d.ts.map +1 -0
- package/dist/media/clipboard.d.ts +30 -0
- package/dist/media/clipboard.d.ts.map +1 -0
- package/dist/media/device-sensors.d.ts +54 -0
- package/dist/media/device-sensors.d.ts.map +1 -0
- package/dist/media/geolocation.d.ts +38 -0
- package/dist/media/geolocation.d.ts.map +1 -0
- package/dist/media/index.d.ts +42 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/media-query.d.ts +36 -0
- package/dist/media/media-query.d.ts.map +1 -0
- package/dist/media/network.d.ts +35 -0
- package/dist/media/network.d.ts.map +1 -0
- package/dist/media/types.d.ts +173 -0
- package/dist/media/types.d.ts.map +1 -0
- package/dist/media/viewport.d.ts +32 -0
- package/dist/media/viewport.d.ts.map +1 -0
- package/dist/media-Di2Ta22s.js +340 -0
- package/dist/media-Di2Ta22s.js.map +1 -0
- package/dist/media.es.mjs +12 -0
- package/dist/motion/index.d.ts +7 -3
- package/dist/motion/index.d.ts.map +1 -1
- package/dist/motion/morph.d.ts +27 -0
- package/dist/motion/morph.d.ts.map +1 -0
- package/dist/motion/parallax.d.ts +30 -0
- package/dist/motion/parallax.d.ts.map +1 -0
- package/dist/motion/reduced-motion.d.ts +36 -3
- package/dist/motion/reduced-motion.d.ts.map +1 -1
- package/dist/motion/types.d.ts +58 -0
- package/dist/motion/types.d.ts.map +1 -1
- package/dist/motion/typewriter.d.ts +31 -0
- package/dist/motion/typewriter.d.ts.map +1 -0
- package/dist/motion-qPj_TYGv.js +530 -0
- package/dist/motion-qPj_TYGv.js.map +1 -0
- package/dist/motion.es.mjs +27 -23
- package/dist/mount-SM07RUa6.js +403 -0
- package/dist/mount-SM07RUa6.js.map +1 -0
- package/dist/{object-qGpWr6-J.js → object-BCk-1c8T.js} +5 -4
- package/dist/{object-qGpWr6-J.js.map → object-BCk-1c8T.js.map} +1 -1
- package/dist/{platform-B7JhGBc7.js → platform-CPbCprb6.js} +3 -3
- package/dist/platform-CPbCprb6.js.map +1 -0
- package/dist/platform.es.mjs +2 -2
- package/dist/plugin/index.d.ts +22 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/registry.d.ts +108 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +110 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin-cPoOHFLY.js +64 -0
- package/dist/plugin-cPoOHFLY.js.map +1 -0
- package/dist/plugin.es.mjs +9 -0
- package/dist/reactive/computed.d.ts +7 -0
- package/dist/reactive/computed.d.ts.map +1 -1
- package/dist/reactive-Cfv0RK6x.js +233 -0
- package/dist/reactive-Cfv0RK6x.js.map +1 -0
- package/dist/reactive.es.mjs +18 -17
- package/dist/registry-CWf368tT.js +26 -0
- package/dist/registry-CWf368tT.js.map +1 -0
- package/dist/router/bq-link.d.ts +112 -0
- package/dist/router/bq-link.d.ts.map +1 -0
- package/dist/router/constraints.d.ts +9 -0
- package/dist/router/constraints.d.ts.map +1 -0
- package/dist/router/index.d.ts +14 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/match.d.ts +0 -1
- package/dist/router/match.d.ts.map +1 -1
- package/dist/router/path-pattern.d.ts +14 -0
- package/dist/router/path-pattern.d.ts.map +1 -0
- package/dist/router/query.d.ts.map +1 -1
- package/dist/router/router.d.ts +3 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/types.d.ts +48 -4
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/use-route.d.ts +50 -0
- package/dist/router/use-route.d.ts.map +1 -0
- package/dist/router/utils.d.ts +3 -0
- package/dist/router/utils.d.ts.map +1 -1
- package/dist/router-BrthaP_z.js +473 -0
- package/dist/router-BrthaP_z.js.map +1 -0
- package/dist/router.es.mjs +13 -10
- package/dist/{sanitize-jyJ2ryE2.js → sanitize-B1V4JswB.js} +95 -83
- package/dist/sanitize-B1V4JswB.js.map +1 -0
- package/dist/security/index.d.ts +2 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/sanitize.d.ts +4 -1
- package/dist/security/sanitize.d.ts.map +1 -1
- package/dist/security/trusted-html.d.ts +53 -0
- package/dist/security/trusted-html.d.ts.map +1 -0
- package/dist/security.es.mjs +10 -9
- package/dist/ssr/hydrate.d.ts +65 -0
- package/dist/ssr/hydrate.d.ts.map +1 -0
- package/dist/ssr/index.d.ts +59 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/render.d.ts +62 -0
- package/dist/ssr/render.d.ts.map +1 -0
- package/dist/ssr/serialize.d.ts +118 -0
- package/dist/ssr/serialize.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +70 -0
- package/dist/ssr/types.d.ts.map +1 -0
- package/dist/ssr-B2qd_WBB.js +248 -0
- package/dist/ssr-B2qd_WBB.js.map +1 -0
- package/dist/ssr.es.mjs +9 -0
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/define-store.d.ts +1 -1
- package/dist/store/define-store.d.ts.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/mapping.d.ts +1 -1
- package/dist/store/mapping.d.ts.map +1 -1
- package/dist/store/persisted.d.ts +38 -4
- package/dist/store/persisted.d.ts.map +1 -1
- package/dist/store/types.d.ts +140 -3
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/utils.d.ts +2 -2
- package/dist/store/utils.d.ts.map +1 -1
- package/dist/store/watch.d.ts +1 -1
- package/dist/store/watch.d.ts.map +1 -1
- package/dist/store-DWpyH6p5.js +338 -0
- package/dist/store-DWpyH6p5.js.map +1 -0
- package/dist/store.es.mjs +11 -10
- package/dist/storybook/index.d.ts +37 -0
- package/dist/storybook/index.d.ts.map +1 -0
- package/dist/storybook.es.mjs +151 -0
- package/dist/storybook.es.mjs.map +1 -0
- package/dist/testing/index.d.ts +23 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/testing.d.ts +156 -0
- package/dist/testing/testing.d.ts.map +1 -0
- package/dist/testing/types.d.ts +134 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing-CsqjNUyy.js +224 -0
- package/dist/testing-CsqjNUyy.js.map +1 -0
- package/dist/testing.es.mjs +9 -0
- package/dist/type-guards-Do9DWgNp.js +44 -0
- package/dist/type-guards-Do9DWgNp.js.map +1 -0
- package/dist/untrack-DJVQQ2WM.js +33 -0
- package/dist/untrack-DJVQQ2WM.js.map +1 -0
- package/dist/view/custom-directives.d.ts +20 -0
- package/dist/view/custom-directives.d.ts.map +1 -0
- package/dist/view/evaluate.d.ts.map +1 -1
- package/dist/view/process.d.ts.map +1 -1
- package/dist/view.es.mjs +11 -10
- package/package.json +52 -11
- package/src/a11y/announce.ts +131 -0
- package/src/a11y/audit.ts +314 -0
- package/src/a11y/index.ts +68 -0
- package/src/a11y/media-preferences.ts +255 -0
- package/src/a11y/roving-tab-index.ts +164 -0
- package/src/a11y/skip-link.ts +255 -0
- package/src/a11y/trap-focus.ts +184 -0
- package/src/a11y/types.ts +183 -0
- package/src/component/component.ts +345 -65
- package/src/component/html.ts +153 -53
- package/src/component/index.ts +12 -2
- package/src/component/library.ts +66 -28
- package/src/component/scope.ts +212 -0
- package/src/component/types.ts +238 -19
- package/src/core/collection.ts +707 -628
- package/src/core/element.ts +981 -774
- package/src/core/env.ts +60 -0
- package/src/core/index.ts +49 -48
- package/src/core/shared.ts +62 -13
- package/src/core/utils/index.ts +148 -83
- package/src/devtools/devtools.ts +410 -0
- package/src/devtools/index.ts +48 -0
- package/src/devtools/types.ts +104 -0
- package/src/dnd/draggable.ts +296 -0
- package/src/dnd/droppable.ts +228 -0
- package/src/dnd/index.ts +62 -0
- package/src/dnd/sortable.ts +307 -0
- package/src/dnd/types.ts +293 -0
- package/src/forms/create-form.ts +278 -0
- package/src/forms/index.ts +65 -0
- package/src/forms/types.ts +154 -0
- package/src/forms/validators.ts +265 -0
- package/src/full.ts +260 -3
- package/src/i18n/formatting.ts +67 -0
- package/src/i18n/i18n.ts +200 -0
- package/src/i18n/index.ts +67 -0
- package/src/i18n/translate.ts +182 -0
- package/src/i18n/types.ts +171 -0
- package/src/index.ts +108 -36
- package/src/media/battery.ts +116 -0
- package/src/media/breakpoints.ts +131 -0
- package/src/media/clipboard.ts +80 -0
- package/src/media/device-sensors.ts +158 -0
- package/src/media/geolocation.ts +119 -0
- package/src/media/index.ts +76 -0
- package/src/media/media-query.ts +92 -0
- package/src/media/network.ts +115 -0
- package/src/media/types.ts +177 -0
- package/src/media/viewport.ts +84 -0
- package/src/motion/index.ts +57 -48
- package/src/motion/morph.ts +151 -0
- package/src/motion/parallax.ts +120 -0
- package/src/motion/reduced-motion.ts +66 -17
- package/src/motion/transition.ts +97 -97
- package/src/motion/types.ts +63 -0
- package/src/motion/typewriter.ts +164 -0
- package/src/platform/announcer.ts +208 -208
- package/src/platform/config.ts +163 -163
- package/src/platform/cookies.ts +165 -165
- package/src/platform/index.ts +39 -39
- package/src/platform/meta.ts +168 -168
- package/src/plugin/index.ts +37 -0
- package/src/plugin/registry.ts +269 -0
- package/src/plugin/types.ts +137 -0
- package/src/reactive/async-data.ts +486 -486
- package/src/reactive/computed.ts +130 -92
- package/src/reactive/index.ts +37 -37
- package/src/reactive/signal.ts +29 -29
- package/src/router/bq-link.ts +279 -0
- package/src/router/constraints.ts +201 -0
- package/src/router/index.ts +49 -41
- package/src/router/match.ts +312 -106
- package/src/router/path-pattern.ts +52 -0
- package/src/router/query.ts +38 -35
- package/src/router/router.ts +402 -211
- package/src/router/types.ts +139 -93
- package/src/router/use-route.ts +68 -0
- package/src/router/utils.ts +157 -116
- package/src/security/constants.ts +211 -211
- package/src/security/index.ts +12 -10
- package/src/security/sanitize.ts +6 -2
- package/src/security/trusted-html.ts +71 -0
- package/src/ssr/hydrate.ts +82 -0
- package/src/ssr/index.ts +70 -0
- package/src/ssr/render.ts +508 -0
- package/src/ssr/serialize.ts +296 -0
- package/src/ssr/types.ts +81 -0
- package/src/store/create-store.ts +467 -329
- package/src/store/define-store.ts +2 -1
- package/src/store/index.ts +27 -22
- package/src/store/mapping.ts +2 -1
- package/src/store/persisted.ts +249 -61
- package/src/store/types.ts +247 -94
- package/src/store/utils.ts +135 -141
- package/src/store/watch.ts +2 -1
- package/src/storybook/index.ts +480 -0
- package/src/testing/index.ts +42 -0
- package/src/testing/testing.ts +593 -0
- package/src/testing/types.ts +170 -0
- package/src/view/custom-directives.ts +30 -0
- package/src/view/evaluate.ts +292 -290
- package/src/view/process.ts +108 -92
- package/dist/component-CY5MVoYN.js +0 -531
- package/dist/component-CY5MVoYN.js.map +0 -1
- package/dist/config-DRmZZno3.js.map +0 -1
- package/dist/core-CK2Mfpf4.js +0 -648
- package/dist/core-CK2Mfpf4.js.map +0 -1
- package/dist/motion-C5DRdPnO.js +0 -415
- package/dist/motion-C5DRdPnO.js.map +0 -1
- package/dist/platform-B7JhGBc7.js.map +0 -1
- package/dist/reactive-BDya-ia8.js +0 -253
- package/dist/reactive-BDya-ia8.js.map +0 -1
- package/dist/router-CijiICxt.js +0 -188
- package/dist/router-CijiICxt.js.map +0 -1
- package/dist/sanitize-jyJ2ryE2.js.map +0 -1
- package/dist/store-CPK9E62U.js +0 -262
- package/dist/store-CPK9E62U.js.map +0 -1
- package/dist/view-Cdi0g-qo.js +0 -396
- package/dist/view-Cdi0g-qo.js.map +0 -1
|
@@ -1,211 +1,211 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security constants and safe lists.
|
|
3
|
-
*
|
|
4
|
-
* @module bquery/security
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Trusted Types policy name.
|
|
9
|
-
*/
|
|
10
|
-
export const POLICY_NAME = 'bquery-sanitizer';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Default allowed HTML tags considered safe.
|
|
14
|
-
*/
|
|
15
|
-
export const DEFAULT_ALLOWED_TAGS = new Set([
|
|
16
|
-
'a',
|
|
17
|
-
'abbr',
|
|
18
|
-
'address',
|
|
19
|
-
'article',
|
|
20
|
-
'aside',
|
|
21
|
-
'b',
|
|
22
|
-
'bdi',
|
|
23
|
-
'bdo',
|
|
24
|
-
'blockquote',
|
|
25
|
-
'br',
|
|
26
|
-
'button',
|
|
27
|
-
'caption',
|
|
28
|
-
'cite',
|
|
29
|
-
'code',
|
|
30
|
-
'col',
|
|
31
|
-
'colgroup',
|
|
32
|
-
'data',
|
|
33
|
-
'dd',
|
|
34
|
-
'del',
|
|
35
|
-
'details',
|
|
36
|
-
'dfn',
|
|
37
|
-
'div',
|
|
38
|
-
'dl',
|
|
39
|
-
'dt',
|
|
40
|
-
'em',
|
|
41
|
-
'figcaption',
|
|
42
|
-
'figure',
|
|
43
|
-
'footer',
|
|
44
|
-
'form',
|
|
45
|
-
'h1',
|
|
46
|
-
'h2',
|
|
47
|
-
'h3',
|
|
48
|
-
'h4',
|
|
49
|
-
'h5',
|
|
50
|
-
'h6',
|
|
51
|
-
'header',
|
|
52
|
-
'hgroup',
|
|
53
|
-
'hr',
|
|
54
|
-
'i',
|
|
55
|
-
'img',
|
|
56
|
-
'input',
|
|
57
|
-
'ins',
|
|
58
|
-
'kbd',
|
|
59
|
-
'label',
|
|
60
|
-
'legend',
|
|
61
|
-
'li',
|
|
62
|
-
'main',
|
|
63
|
-
'mark',
|
|
64
|
-
'nav',
|
|
65
|
-
'ol',
|
|
66
|
-
'optgroup',
|
|
67
|
-
'option',
|
|
68
|
-
'p',
|
|
69
|
-
'picture',
|
|
70
|
-
'pre',
|
|
71
|
-
'progress',
|
|
72
|
-
'q',
|
|
73
|
-
'rp',
|
|
74
|
-
'rt',
|
|
75
|
-
'ruby',
|
|
76
|
-
's',
|
|
77
|
-
'samp',
|
|
78
|
-
'section',
|
|
79
|
-
'select',
|
|
80
|
-
'small',
|
|
81
|
-
'source',
|
|
82
|
-
'span',
|
|
83
|
-
'strong',
|
|
84
|
-
'sub',
|
|
85
|
-
'summary',
|
|
86
|
-
'sup',
|
|
87
|
-
'table',
|
|
88
|
-
'tbody',
|
|
89
|
-
'td',
|
|
90
|
-
'textarea',
|
|
91
|
-
'tfoot',
|
|
92
|
-
'th',
|
|
93
|
-
'thead',
|
|
94
|
-
'time',
|
|
95
|
-
'tr',
|
|
96
|
-
'u',
|
|
97
|
-
'ul',
|
|
98
|
-
'var',
|
|
99
|
-
'wbr',
|
|
100
|
-
]);
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Explicitly dangerous tags that should never be allowed.
|
|
104
|
-
* These are checked even if somehow added to allowTags.
|
|
105
|
-
*/
|
|
106
|
-
export const DANGEROUS_TAGS = new Set([
|
|
107
|
-
'script',
|
|
108
|
-
'iframe',
|
|
109
|
-
'frame',
|
|
110
|
-
'frameset',
|
|
111
|
-
'object',
|
|
112
|
-
'embed',
|
|
113
|
-
'applet',
|
|
114
|
-
'link',
|
|
115
|
-
'meta',
|
|
116
|
-
'style',
|
|
117
|
-
'base',
|
|
118
|
-
'template',
|
|
119
|
-
// 'slot' is intentionally excluded here so component shadow markup can opt in
|
|
120
|
-
// via sanitizeHtml(..., { allowTags: ['slot'] }). It remains disallowed by default
|
|
121
|
-
// for general HTML writes, because DEFAULT_ALLOWED_TAGS does not include it.
|
|
122
|
-
'math',
|
|
123
|
-
'svg',
|
|
124
|
-
'foreignobject',
|
|
125
|
-
'noscript',
|
|
126
|
-
]);
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Reserved IDs that could cause DOM clobbering attacks.
|
|
130
|
-
* These are prevented to avoid overwriting global browser objects.
|
|
131
|
-
*/
|
|
132
|
-
export const RESERVED_IDS = new Set([
|
|
133
|
-
// Global objects
|
|
134
|
-
'document',
|
|
135
|
-
'window',
|
|
136
|
-
'location',
|
|
137
|
-
'top',
|
|
138
|
-
'self',
|
|
139
|
-
'parent',
|
|
140
|
-
'frames',
|
|
141
|
-
'history',
|
|
142
|
-
'navigator',
|
|
143
|
-
'screen',
|
|
144
|
-
// Dangerous functions
|
|
145
|
-
'alert',
|
|
146
|
-
'confirm',
|
|
147
|
-
'prompt',
|
|
148
|
-
'eval',
|
|
149
|
-
'function',
|
|
150
|
-
// Document properties
|
|
151
|
-
'cookie',
|
|
152
|
-
'domain',
|
|
153
|
-
'referrer',
|
|
154
|
-
'body',
|
|
155
|
-
'head',
|
|
156
|
-
'forms',
|
|
157
|
-
'images',
|
|
158
|
-
'links',
|
|
159
|
-
'scripts',
|
|
160
|
-
// DOM traversal properties
|
|
161
|
-
'children',
|
|
162
|
-
'parentnode',
|
|
163
|
-
'firstchild',
|
|
164
|
-
'lastchild',
|
|
165
|
-
// Content manipulation
|
|
166
|
-
'innerhtml',
|
|
167
|
-
'outerhtml',
|
|
168
|
-
'textcontent',
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Default allowed attributes considered safe.
|
|
173
|
-
* Note: 'style' is excluded by default because inline CSS can be abused for:
|
|
174
|
-
* - UI redressing attacks
|
|
175
|
-
* - Data exfiltration via url() in CSS
|
|
176
|
-
* - CSS injection vectors
|
|
177
|
-
* If you need to allow inline styles, add 'style' to allowAttributes in your
|
|
178
|
-
* sanitizeHtml options, but ensure you implement proper CSS value validation.
|
|
179
|
-
*/
|
|
180
|
-
export const DEFAULT_ALLOWED_ATTRIBUTES = new Set([
|
|
181
|
-
'alt',
|
|
182
|
-
'class',
|
|
183
|
-
'dir',
|
|
184
|
-
'height',
|
|
185
|
-
'hidden',
|
|
186
|
-
'href',
|
|
187
|
-
'id',
|
|
188
|
-
'lang',
|
|
189
|
-
'loading',
|
|
190
|
-
'name',
|
|
191
|
-
'rel',
|
|
192
|
-
'role',
|
|
193
|
-
'src',
|
|
194
|
-
'srcset',
|
|
195
|
-
'tabindex',
|
|
196
|
-
'target',
|
|
197
|
-
'title',
|
|
198
|
-
'type',
|
|
199
|
-
'width',
|
|
200
|
-
'aria-*',
|
|
201
|
-
]);
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Dangerous attribute prefixes to always remove.
|
|
205
|
-
*/
|
|
206
|
-
export const DANGEROUS_ATTR_PREFIXES = ['on', 'formaction', 'xlink:', 'xmlns:'];
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Dangerous URL protocols to block.
|
|
210
|
-
*/
|
|
211
|
-
export const DANGEROUS_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'file:'];
|
|
1
|
+
/**
|
|
2
|
+
* Security constants and safe lists.
|
|
3
|
+
*
|
|
4
|
+
* @module bquery/security
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Trusted Types policy name.
|
|
9
|
+
*/
|
|
10
|
+
export const POLICY_NAME = 'bquery-sanitizer';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Default allowed HTML tags considered safe.
|
|
14
|
+
*/
|
|
15
|
+
export const DEFAULT_ALLOWED_TAGS = new Set([
|
|
16
|
+
'a',
|
|
17
|
+
'abbr',
|
|
18
|
+
'address',
|
|
19
|
+
'article',
|
|
20
|
+
'aside',
|
|
21
|
+
'b',
|
|
22
|
+
'bdi',
|
|
23
|
+
'bdo',
|
|
24
|
+
'blockquote',
|
|
25
|
+
'br',
|
|
26
|
+
'button',
|
|
27
|
+
'caption',
|
|
28
|
+
'cite',
|
|
29
|
+
'code',
|
|
30
|
+
'col',
|
|
31
|
+
'colgroup',
|
|
32
|
+
'data',
|
|
33
|
+
'dd',
|
|
34
|
+
'del',
|
|
35
|
+
'details',
|
|
36
|
+
'dfn',
|
|
37
|
+
'div',
|
|
38
|
+
'dl',
|
|
39
|
+
'dt',
|
|
40
|
+
'em',
|
|
41
|
+
'figcaption',
|
|
42
|
+
'figure',
|
|
43
|
+
'footer',
|
|
44
|
+
'form',
|
|
45
|
+
'h1',
|
|
46
|
+
'h2',
|
|
47
|
+
'h3',
|
|
48
|
+
'h4',
|
|
49
|
+
'h5',
|
|
50
|
+
'h6',
|
|
51
|
+
'header',
|
|
52
|
+
'hgroup',
|
|
53
|
+
'hr',
|
|
54
|
+
'i',
|
|
55
|
+
'img',
|
|
56
|
+
'input',
|
|
57
|
+
'ins',
|
|
58
|
+
'kbd',
|
|
59
|
+
'label',
|
|
60
|
+
'legend',
|
|
61
|
+
'li',
|
|
62
|
+
'main',
|
|
63
|
+
'mark',
|
|
64
|
+
'nav',
|
|
65
|
+
'ol',
|
|
66
|
+
'optgroup',
|
|
67
|
+
'option',
|
|
68
|
+
'p',
|
|
69
|
+
'picture',
|
|
70
|
+
'pre',
|
|
71
|
+
'progress',
|
|
72
|
+
'q',
|
|
73
|
+
'rp',
|
|
74
|
+
'rt',
|
|
75
|
+
'ruby',
|
|
76
|
+
's',
|
|
77
|
+
'samp',
|
|
78
|
+
'section',
|
|
79
|
+
'select',
|
|
80
|
+
'small',
|
|
81
|
+
'source',
|
|
82
|
+
'span',
|
|
83
|
+
'strong',
|
|
84
|
+
'sub',
|
|
85
|
+
'summary',
|
|
86
|
+
'sup',
|
|
87
|
+
'table',
|
|
88
|
+
'tbody',
|
|
89
|
+
'td',
|
|
90
|
+
'textarea',
|
|
91
|
+
'tfoot',
|
|
92
|
+
'th',
|
|
93
|
+
'thead',
|
|
94
|
+
'time',
|
|
95
|
+
'tr',
|
|
96
|
+
'u',
|
|
97
|
+
'ul',
|
|
98
|
+
'var',
|
|
99
|
+
'wbr',
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Explicitly dangerous tags that should never be allowed.
|
|
104
|
+
* These are checked even if somehow added to allowTags.
|
|
105
|
+
*/
|
|
106
|
+
export const DANGEROUS_TAGS = new Set([
|
|
107
|
+
'script',
|
|
108
|
+
'iframe',
|
|
109
|
+
'frame',
|
|
110
|
+
'frameset',
|
|
111
|
+
'object',
|
|
112
|
+
'embed',
|
|
113
|
+
'applet',
|
|
114
|
+
'link',
|
|
115
|
+
'meta',
|
|
116
|
+
'style',
|
|
117
|
+
'base',
|
|
118
|
+
'template',
|
|
119
|
+
// 'slot' is intentionally excluded here so component shadow markup can opt in
|
|
120
|
+
// via sanitizeHtml(..., { allowTags: ['slot'] }). It remains disallowed by default
|
|
121
|
+
// for general HTML writes, because DEFAULT_ALLOWED_TAGS does not include it.
|
|
122
|
+
'math',
|
|
123
|
+
'svg',
|
|
124
|
+
'foreignobject',
|
|
125
|
+
'noscript',
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Reserved IDs that could cause DOM clobbering attacks.
|
|
130
|
+
* These are prevented to avoid overwriting global browser objects.
|
|
131
|
+
*/
|
|
132
|
+
export const RESERVED_IDS = new Set([
|
|
133
|
+
// Global objects
|
|
134
|
+
'document',
|
|
135
|
+
'window',
|
|
136
|
+
'location',
|
|
137
|
+
'top',
|
|
138
|
+
'self',
|
|
139
|
+
'parent',
|
|
140
|
+
'frames',
|
|
141
|
+
'history',
|
|
142
|
+
'navigator',
|
|
143
|
+
'screen',
|
|
144
|
+
// Dangerous functions
|
|
145
|
+
'alert',
|
|
146
|
+
'confirm',
|
|
147
|
+
'prompt',
|
|
148
|
+
'eval',
|
|
149
|
+
'function',
|
|
150
|
+
// Document properties
|
|
151
|
+
'cookie',
|
|
152
|
+
'domain',
|
|
153
|
+
'referrer',
|
|
154
|
+
'body',
|
|
155
|
+
'head',
|
|
156
|
+
'forms',
|
|
157
|
+
'images',
|
|
158
|
+
'links',
|
|
159
|
+
'scripts',
|
|
160
|
+
// DOM traversal properties
|
|
161
|
+
'children',
|
|
162
|
+
'parentnode',
|
|
163
|
+
'firstchild',
|
|
164
|
+
'lastchild',
|
|
165
|
+
// Content manipulation
|
|
166
|
+
'innerhtml',
|
|
167
|
+
'outerhtml',
|
|
168
|
+
'textcontent',
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Default allowed attributes considered safe.
|
|
173
|
+
* Note: 'style' is excluded by default because inline CSS can be abused for:
|
|
174
|
+
* - UI redressing attacks
|
|
175
|
+
* - Data exfiltration via url() in CSS
|
|
176
|
+
* - CSS injection vectors
|
|
177
|
+
* If you need to allow inline styles, add 'style' to allowAttributes in your
|
|
178
|
+
* sanitizeHtml options, but ensure you implement proper CSS value validation.
|
|
179
|
+
*/
|
|
180
|
+
export const DEFAULT_ALLOWED_ATTRIBUTES = new Set([
|
|
181
|
+
'alt',
|
|
182
|
+
'class',
|
|
183
|
+
'dir',
|
|
184
|
+
'height',
|
|
185
|
+
'hidden',
|
|
186
|
+
'href',
|
|
187
|
+
'id',
|
|
188
|
+
'lang',
|
|
189
|
+
'loading',
|
|
190
|
+
'name',
|
|
191
|
+
'rel',
|
|
192
|
+
'role',
|
|
193
|
+
'src',
|
|
194
|
+
'srcset',
|
|
195
|
+
'tabindex',
|
|
196
|
+
'target',
|
|
197
|
+
'title',
|
|
198
|
+
'type',
|
|
199
|
+
'width',
|
|
200
|
+
'aria-*',
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Dangerous attribute prefixes to always remove.
|
|
205
|
+
*/
|
|
206
|
+
export const DANGEROUS_ATTR_PREFIXES = ['on', 'formaction', 'xlink:', 'xmlns:'];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Dangerous URL protocols to block.
|
|
210
|
+
*/
|
|
211
|
+
export const DANGEROUS_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'file:'];
|
package/src/security/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security module providing sanitization, CSP compatibility, and Trusted Types.
|
|
3
|
-
*
|
|
4
|
-
* @module bquery/security
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export { generateNonce, hasCSPDirective } from './csp';
|
|
8
|
-
export { escapeHtml, sanitizeHtml as sanitize, sanitizeHtml, stripTags } from './sanitize';
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
1
|
+
/**
|
|
2
|
+
* Security module providing sanitization, CSP compatibility, and Trusted Types.
|
|
3
|
+
*
|
|
4
|
+
* @module bquery/security
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { generateNonce, hasCSPDirective } from './csp';
|
|
8
|
+
export { escapeHtml, sanitizeHtml as sanitize, sanitizeHtml, stripTags } from './sanitize';
|
|
9
|
+
export { trusted } from './trusted-html';
|
|
10
|
+
export { createTrustedHtml, getTrustedTypesPolicy, isTrustedTypesSupported } from './trusted-types';
|
|
11
|
+
export type { SanitizedHtml, TrustedHtml } from './trusted-html';
|
|
12
|
+
export type { SanitizeOptions } from './types';
|
package/src/security/sanitize.ts
CHANGED
|
@@ -6,9 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { sanitizeHtmlCore } from './sanitize-core';
|
|
9
|
+
import { toSanitizedHtml } from './trusted-html';
|
|
10
|
+
import type { SanitizedHtml } from './trusted-html';
|
|
9
11
|
import type { SanitizeOptions } from './types';
|
|
10
12
|
export { generateNonce } from './csp';
|
|
11
13
|
export { isTrustedTypesSupported } from './trusted-types';
|
|
14
|
+
export { trusted } from './trusted-html';
|
|
15
|
+
export type { SanitizedHtml, TrustedHtml } from './trusted-html';
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Sanitize HTML string, removing dangerous elements and attributes.
|
|
@@ -24,8 +28,8 @@ export { isTrustedTypesSupported } from './trusted-types';
|
|
|
24
28
|
* // Returns: '<div>Hello</div>'
|
|
25
29
|
* ```
|
|
26
30
|
*/
|
|
27
|
-
export const sanitizeHtml = (html: string, options: SanitizeOptions = {}):
|
|
28
|
-
return sanitizeHtmlCore(html, options);
|
|
31
|
+
export const sanitizeHtml = (html: string, options: SanitizeOptions = {}): SanitizedHtml => {
|
|
32
|
+
return toSanitizedHtml(sanitizeHtmlCore(html, options));
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
/**
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
declare const sanitizedHtmlBrand: unique symbol;
|
|
2
|
+
const trustedHtmlBrand: unique symbol = Symbol('bquery.trusted-html.brand');
|
|
3
|
+
const TRUSTED_HTML_VALUE = Symbol('bquery.trusted-html');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Branded HTML string produced by bQuery's sanitization or escaping template helpers.
|
|
7
|
+
*
|
|
8
|
+
* Values returned from {@link sanitizeHtml} carry sanitized markup. Values returned from
|
|
9
|
+
* {@link safeHtml} preserve the template's static markup while escaping normal interpolations
|
|
10
|
+
* and splicing {@link trusted} fragments verbatim. This brand is not intended for arbitrary
|
|
11
|
+
* strings or manual concatenation outside those helpers.
|
|
12
|
+
*/
|
|
13
|
+
export type SanitizedHtml = string & { readonly [sanitizedHtmlBrand]: true };
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Marker object that safeHtml can splice into templates without escaping again.
|
|
17
|
+
*/
|
|
18
|
+
export type TrustedHtml = { readonly [trustedHtmlBrand]: true; toString(): string };
|
|
19
|
+
|
|
20
|
+
type TrustedHtmlValue = TrustedHtml & { readonly [TRUSTED_HTML_VALUE]: string };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Apply the internal {@link SanitizedHtml} brand to helper output.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export const toSanitizedHtml = (html: string): SanitizedHtml => html as SanitizedHtml;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Mark a sanitized HTML string for verbatim splicing into safeHtml templates.
|
|
31
|
+
*
|
|
32
|
+
* @param html - HTML previously produced by sanitizeHtml, safeHtml, or another trusted bQuery helper
|
|
33
|
+
* @returns Trusted HTML marker object for safeHtml interpolations
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const badge = trusted(sanitizeHtml('<strong onclick="alert(1)">New</strong>'));
|
|
38
|
+
* const markup = safeHtml`<span>${badge}</span>`;
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export const trusted = (html: SanitizedHtml): TrustedHtml => {
|
|
42
|
+
const value = String(html);
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
[trustedHtmlBrand]: true as const,
|
|
45
|
+
[TRUSTED_HTML_VALUE]: value,
|
|
46
|
+
toString: () => value,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a value is a trusted HTML marker created by trusted().
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export const isTrustedHtml = (value: unknown): value is TrustedHtml => {
|
|
56
|
+
return (
|
|
57
|
+
typeof value === 'object' &&
|
|
58
|
+
value !== null &&
|
|
59
|
+
trustedHtmlBrand in value &&
|
|
60
|
+
TRUSTED_HTML_VALUE in value
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Unwrap the raw HTML string stored inside a trusted HTML marker.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export const unwrapTrustedHtml = (value: TrustedHtml): string => {
|
|
70
|
+
return (value as TrustedHtmlValue)[TRUSTED_HTML_VALUE];
|
|
71
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hydration support for server-rendered DOM.
|
|
3
|
+
*
|
|
4
|
+
* Enables the client-side view system to reuse existing server-rendered DOM
|
|
5
|
+
* elements instead of re-rendering them, by attaching reactive bindings
|
|
6
|
+
* to the pre-existing DOM structure.
|
|
7
|
+
*
|
|
8
|
+
* @module bquery/ssr
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { BindingContext, MountOptions, View } from '../view/types';
|
|
12
|
+
import { mount } from '../view/mount';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Extended mount options that include hydration mode.
|
|
16
|
+
*/
|
|
17
|
+
export type HydrateMountOptions = MountOptions & {
|
|
18
|
+
/**
|
|
19
|
+
* When present, must be `true` so the mount operation reuses existing DOM elements
|
|
20
|
+
* instead of re-rendering them. Reactive bindings (effects) are
|
|
21
|
+
* still attached so the DOM updates reactively from that point on.
|
|
22
|
+
*
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
hydrate?: true;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Mounts a reactive view with optional hydration support.
|
|
30
|
+
*
|
|
31
|
+
* When `hydrate: true` is set, the existing server-rendered DOM is preserved
|
|
32
|
+
* and reactive bindings are attached on top. The DOM is NOT re-rendered;
|
|
33
|
+
* instead, effects begin tracking signals so future changes update the DOM.
|
|
34
|
+
*
|
|
35
|
+
* This is the client-side counterpart to `renderToString()`. The typical flow:
|
|
36
|
+
* 1. Server: `renderToString(template, data)` → send HTML to client
|
|
37
|
+
* 2. Client: `hydrateMount('#app', reactiveContext, { hydrate: true })`
|
|
38
|
+
*
|
|
39
|
+
* Under the hood, `hydrateMount` simply delegates to the standard `mount()`
|
|
40
|
+
* function. The `mount()` function already processes existing DOM elements
|
|
41
|
+
* and attaches reactive effects to them — it does not clear/replace content.
|
|
42
|
+
* The `hydrate` flag is a semantic marker indicating developer intent and
|
|
43
|
+
* ensures the existing DOM structure is preserved.
|
|
44
|
+
*
|
|
45
|
+
* @param selector - CSS selector or Element to hydrate
|
|
46
|
+
* @param context - Binding context with signals, computed values, and functions
|
|
47
|
+
* @param options - Mount options with `hydrate: true`
|
|
48
|
+
* @returns The mounted View instance
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { hydrateMount } from '@bquery/bquery/ssr';
|
|
53
|
+
* import { signal, computed } from '@bquery/bquery/reactive';
|
|
54
|
+
*
|
|
55
|
+
* // Server rendered:
|
|
56
|
+
* // <div id="app"><h1>Welcome</h1><p>Hello, World!</p></div>
|
|
57
|
+
*
|
|
58
|
+
* // Client hydration — attaches reactivity to existing DOM:
|
|
59
|
+
* const name = signal('World');
|
|
60
|
+
* const greeting = computed(() => `Hello, ${name.value}!`);
|
|
61
|
+
*
|
|
62
|
+
* const view = hydrateMount('#app', { name, greeting }, { hydrate: true });
|
|
63
|
+
*
|
|
64
|
+
* // Now updating `name.value` will reactively update the DOM
|
|
65
|
+
* name.value = 'Alice'; // <p> updates to "Hello, Alice!"
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export const hydrateMount = (
|
|
69
|
+
selector: string | Element,
|
|
70
|
+
context: BindingContext,
|
|
71
|
+
options: HydrateMountOptions = {}
|
|
72
|
+
): View => {
|
|
73
|
+
const { hydrate = true, ...mountOptions } = options;
|
|
74
|
+
|
|
75
|
+
if (!hydrate) {
|
|
76
|
+
throw new Error('bQuery ssr: hydrateMount() requires { hydrate: true } when options are provided.');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Hydration uses the standard mount which processes existing DOM
|
|
80
|
+
// and attaches reactive effects without clearing content.
|
|
81
|
+
return mount(selector, context, mountOptions);
|
|
82
|
+
};
|