@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
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for validating and normalizing route param constraints.
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const MAX_ROUTE_CONSTRAINT_CACHE_SIZE = 128;
|
|
7
|
+
const normalizedConstraintCache = new Map<string, string>();
|
|
8
|
+
const compiledConstraintRegexCache = new Map<string, RegExp>();
|
|
9
|
+
|
|
10
|
+
const setBoundedCacheEntry = <T>(cache: Map<string, T>, key: string, value: T): void => {
|
|
11
|
+
if (cache.has(key)) {
|
|
12
|
+
cache.delete(key);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
cache.set(key, value);
|
|
16
|
+
|
|
17
|
+
if (cache.size <= MAX_ROUTE_CONSTRAINT_CACHE_SIZE) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const oldestKey = cache.keys().next().value;
|
|
22
|
+
if (oldestKey !== undefined) {
|
|
23
|
+
cache.delete(oldestKey);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Detects potentially super-linear (ReDoS) patterns caused by quantified
|
|
29
|
+
* groups that already contain inner quantifiers, such as `(a+)+` or `(a*)*`.
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
const hasNestedQuantifier = (pattern: string): boolean => {
|
|
33
|
+
const groupQuantifierStack: boolean[] = [];
|
|
34
|
+
let inCharClass = false;
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
37
|
+
const ch = pattern[i];
|
|
38
|
+
|
|
39
|
+
if (ch === '\\' && i + 1 < pattern.length) {
|
|
40
|
+
i++;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (ch === '[' && !inCharClass) {
|
|
45
|
+
inCharClass = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (ch === ']' && inCharClass) {
|
|
49
|
+
inCharClass = false;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (inCharClass) continue;
|
|
53
|
+
|
|
54
|
+
if (ch === '(') {
|
|
55
|
+
groupQuantifierStack.push(false);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (ch === ')') {
|
|
60
|
+
const groupHasInnerQuantifier = groupQuantifierStack.pop() ?? false;
|
|
61
|
+
// Check if the closing paren is followed by a quantifier
|
|
62
|
+
const next = pattern[i + 1];
|
|
63
|
+
if (groupHasInnerQuantifier && (next === '+' || next === '*' || next === '?' || next === '{')) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (groupHasInnerQuantifier && groupQuantifierStack.length > 0) {
|
|
67
|
+
groupQuantifierStack[groupQuantifierStack.length - 1] = true;
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (groupQuantifierStack.length > 0) {
|
|
73
|
+
if (ch === '?' && i > 0 && pattern[i - 1] === '(') {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (ch === '+' || ch === '*' || ch === '?' || ch === '{') {
|
|
78
|
+
groupQuantifierStack[groupQuantifierStack.length - 1] = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return false;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const normalizeConstraintCaptures = (constraint: string): string => {
|
|
87
|
+
let normalized = '';
|
|
88
|
+
let inCharacterClass = false;
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < constraint.length; i++) {
|
|
91
|
+
const char = constraint[i];
|
|
92
|
+
|
|
93
|
+
if (char === '\\' && i + 1 < constraint.length) {
|
|
94
|
+
if (!inCharacterClass && constraint[i + 1] >= '1' && constraint[i + 1] <= '9') {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`bQuery router: Route constraints cannot use backreferences: "${constraint}".`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!inCharacterClass && constraint[i + 1] === 'k' && constraint[i + 2] === '<') {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`bQuery router: Route constraints cannot use backreferences: "${constraint}".`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
normalized += char + constraint[i + 1];
|
|
107
|
+
i++;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (char === '[' && !inCharacterClass) {
|
|
112
|
+
inCharacterClass = true;
|
|
113
|
+
normalized += char;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (char === ']' && inCharacterClass) {
|
|
118
|
+
inCharacterClass = false;
|
|
119
|
+
normalized += char;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!inCharacterClass && char === '(') {
|
|
124
|
+
if (i + 1 < constraint.length && constraint[i + 1] === '?') {
|
|
125
|
+
if (constraint[i + 2] === '<') {
|
|
126
|
+
if (constraint[i + 3] === '=' || constraint[i + 3] === '!') {
|
|
127
|
+
normalized += '(';
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const namedCaptureEnd = constraint.indexOf('>', i + 3);
|
|
132
|
+
if (namedCaptureEnd === -1) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`bQuery router: Invalid route constraint named capture group: "${constraint}".`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
normalized += '(?:';
|
|
138
|
+
i = namedCaptureEnd;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
normalized += '(';
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
normalized += '(?:';
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
normalized += char;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return normalized;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const getNormalizedRouteConstraint = (constraint: string): string => {
|
|
157
|
+
const cached = normalizedConstraintCache.get(constraint);
|
|
158
|
+
if (cached !== undefined) {
|
|
159
|
+
return cached;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const normalized = normalizeConstraintCaptures(constraint);
|
|
163
|
+
setBoundedCacheEntry(normalizedConstraintCache, constraint, normalized);
|
|
164
|
+
return normalized;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const getRouteConstraintRegex = (constraint: string): RegExp => {
|
|
168
|
+
const normalizedConstraint = getNormalizedRouteConstraint(constraint);
|
|
169
|
+
const cached = compiledConstraintRegexCache.get(normalizedConstraint);
|
|
170
|
+
if (cached) {
|
|
171
|
+
return cached;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (hasNestedQuantifier(normalizedConstraint)) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`bQuery router: Route constraint contains a potentially catastrophic (ReDoS) pattern. Nested quantifiers are not allowed: "${constraint}".`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const compiled = new RegExp(`^(?:${normalizedConstraint})$`);
|
|
182
|
+
setBoundedCacheEntry(compiledConstraintRegexCache, normalizedConstraint, compiled);
|
|
183
|
+
return compiled;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
if (error instanceof SyntaxError) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`bQuery router: Invalid route constraint regex "${constraint}": ${error.message}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const routeConstraintMatches = (constraint: string, value: string): boolean => {
|
|
195
|
+
return getRouteConstraintRegex(constraint).test(value);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export const clearRouteConstraintCache = (): void => {
|
|
199
|
+
normalizedConstraintCache.clear();
|
|
200
|
+
compiledConstraintRegexCache.clear();
|
|
201
|
+
};
|
package/src/router/index.ts
CHANGED
|
@@ -1,41 +1,49 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal SPA router with History API integration.
|
|
3
|
-
*
|
|
4
|
-
* This module provides a lightweight, signal-based router for single-page
|
|
5
|
-
* applications. Features include:
|
|
6
|
-
* - History API navigation
|
|
7
|
-
* - Route matching with params and
|
|
8
|
-
* - Lazy route loading
|
|
9
|
-
* - Navigation guards (beforeEach, afterEach)
|
|
10
|
-
* - Reactive current route via signals
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* }
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SPA router with History API integration.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a lightweight, signal-based router for single-page
|
|
5
|
+
* applications. Features include:
|
|
6
|
+
* - History API navigation
|
|
7
|
+
* - Route matching with params, wildcards, and regex constraints
|
|
8
|
+
* - Lazy route loading
|
|
9
|
+
* - Navigation guards (beforeEach, afterEach, per-route beforeEnter)
|
|
10
|
+
* - Reactive current route via signals
|
|
11
|
+
* - `useRoute()` composable for fine-grained reactive access
|
|
12
|
+
* - Route redirects via `redirectTo`
|
|
13
|
+
* - Scroll position restoration on back/forward
|
|
14
|
+
* - Multi-value query params (e.g., `?tag=a&tag=b` → `{ tag: ['a', 'b'] }`)
|
|
15
|
+
*
|
|
16
|
+
* @module bquery/router
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { createRouter, navigate, currentRoute, useRoute } from '@bquery/bquery/router';
|
|
21
|
+
* import { effect } from '@bquery/bquery/reactive';
|
|
22
|
+
*
|
|
23
|
+
* const router = createRouter({
|
|
24
|
+
* routes: [
|
|
25
|
+
* { path: '/', component: () => import('./Home') },
|
|
26
|
+
* { path: '/user/:id(\\d+)', component: () => import('./User') },
|
|
27
|
+
* { path: '/old', redirectTo: '/new' },
|
|
28
|
+
* { path: '*', component: () => import('./NotFound') },
|
|
29
|
+
* ],
|
|
30
|
+
* scrollRestoration: true,
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* const { path, params } = useRoute();
|
|
34
|
+
* effect(() => {
|
|
35
|
+
* console.log('Route changed:', path.value, params.value);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* navigate('/user/42');
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export { BqLinkElement, registerBqLink } from './bq-link';
|
|
43
|
+
export { interceptLinks, link } from './links';
|
|
44
|
+
export { back, forward, navigate } from './navigation';
|
|
45
|
+
export { createRouter } from './router';
|
|
46
|
+
export { currentRoute } from './state';
|
|
47
|
+
export type { NavigationGuard, Route, RouteDefinition, Router, RouterOptions } from './types';
|
|
48
|
+
export { useRoute, type UseRouteReturn } from './use-route';
|
|
49
|
+
export { isActive, isActiveSignal, resolve } from './utils';
|