@real-router/hash-plugin 0.2.7 → 0.2.9

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.
@@ -1,67 +1,81 @@
1
- import { State as State$1, PluginFactory, Params as Params$1 } from '@real-router/core';
2
-
1
+ import { Params, PluginFactory, State } from "@real-router/core";
2
+ //#region src/types.d.ts
3
3
  /**
4
4
  * Hash-based routing plugin configuration.
5
5
  * Uses URL hash fragment for navigation (e.g., example.com/#/path).
6
6
  */
7
7
  interface HashPluginOptions {
8
- /**
9
- * Prefix for hash (e.g., "!" for "#!/path").
10
- *
11
- * @default ""
12
- */
13
- hashPrefix?: string;
14
- /**
15
- * Base path prepended before hash (e.g., "/app" → "/app#/path").
16
- *
17
- * @default ""
18
- */
19
- base?: string;
20
- /**
21
- * Force deactivation of current route even if canDeactivate returns false.
22
- *
23
- * @default true
24
- */
25
- forceDeactivate?: boolean;
8
+ /**
9
+ * Prefix for hash (e.g., "!" for "#!/path").
10
+ *
11
+ * @default ""
12
+ */
13
+ hashPrefix?: string;
14
+ /**
15
+ * Base path prepended before hash (e.g., "/app" → "/app#/path").
16
+ *
17
+ * @default ""
18
+ */
19
+ base?: string;
20
+ /**
21
+ * Force deactivation of current route even if canDeactivate returns false.
22
+ *
23
+ * @default true
24
+ */
25
+ forceDeactivate?: boolean;
26
26
  }
27
-
27
+ //#endregion
28
+ //#region ../browser-env/dist/esm/index.d.mts
29
+ //#region src/types.d.ts
28
30
  interface HistoryBrowser {
29
- pushState: (state: State$1, path: string) => void;
30
- replaceState: (state: State$1, path: string) => void;
31
- addPopstateListener: (fn: (evt: PopStateEvent) => void) => () => void;
32
- getHash: () => string;
31
+ pushState: (state: State, path: string) => void;
32
+ replaceState: (state: State, path: string) => void;
33
+ addPopstateListener: (fn: (evt: PopStateEvent) => void) => () => void;
34
+ getHash: () => string;
33
35
  }
34
36
  interface Browser extends HistoryBrowser {
35
- getLocation: () => string;
37
+ getLocation: () => string;
36
38
  }
37
-
39
+ /**
40
+ * Shared mutable state across plugin instances created by the same factory.
41
+ * Enables cleanup of a previous instance's popstate listener when the factory is reused.
42
+ */
43
+ //#endregion
44
+ //#region src/factory.d.ts
38
45
  declare function hashPluginFactory(opts?: Partial<HashPluginOptions>, browser?: Browser): PluginFactory;
39
-
46
+ //#endregion
47
+ //#region ../core-types/dist/esm/index.d.mts
40
48
  type TransitionPhase = "deactivating" | "activating";
41
49
  type TransitionReason = "success" | "blocked" | "cancelled" | "error";
42
50
  interface TransitionMeta {
43
- phase: TransitionPhase;
44
- reason: TransitionReason;
45
- reload?: boolean;
46
- redirected?: boolean;
47
- from?: string;
48
- blocker?: string;
49
- segments: {
50
- deactivated: string[];
51
- activated: string[];
52
- intersection: string;
53
- };
54
- }
55
- interface State<P extends Params = Params> {
56
- name: string;
57
- params: P;
58
- path: string;
59
- transition?: TransitionMeta | undefined;
51
+ phase: TransitionPhase;
52
+ reason: TransitionReason;
53
+ reload?: boolean;
54
+ redirected?: boolean;
55
+ from?: string;
56
+ blocker?: string;
57
+ segments: {
58
+ deactivated: string[];
59
+ activated: string[];
60
+ intersection: string;
61
+ };
60
62
  }
61
- interface Params {
62
- [key: string]: string | string[] | number | number[] | boolean | boolean[] | Params | Params[] | Record<string, string | number | boolean> | null | undefined;
63
+ interface State$1<P extends Params$1 = Params$1> {
64
+ name: string;
65
+ params: P;
66
+ path: string;
67
+ transition?: TransitionMeta | undefined;
63
68
  }
64
-
69
+ interface Params$1 {
70
+ [key: string]: string | string[] | number | number[] | boolean | boolean[] | Params$1 | Params$1[] | Record<string, string | number | boolean> | null | undefined;
71
+ } //#endregion
72
+ //#region src/limits.d.ts
73
+ /**
74
+ * Configuration for router resource limits.
75
+ * Controls maximum allowed values for various router operations to prevent resource exhaustion.
76
+ */
77
+ //#endregion
78
+ //#region ../type-guards/dist/esm/index.d.mts
65
79
  /**
66
80
  * Enhanced type guard for State with deep validation.
67
81
  * Checks not only presence but also types of all required fields.
@@ -74,31 +88,40 @@ interface Params {
74
88
  * isStateStrict({ name: 'home', params: {}, path: '/', meta: { id: 1 } }); // true
75
89
  * isStateStrict({ name: 'home', params: 'invalid', path: '/' }); // false
76
90
  */
77
- declare function isStateStrict<P extends Params = Params>(value: unknown): value is State<P>;
78
-
91
+ declare function isStateStrict<P extends Params$1 = Params$1>(value: unknown): value is State$1<P>; //#endregion
92
+ //#region src/guards/primitives.d.ts
93
+ /**
94
+ * Type guard for string type.
95
+ *
96
+ * @param value - Value to check
97
+ * @returns true if value is a string
98
+ */
99
+ //#endregion
100
+ //#region src/index.d.ts
79
101
  /**
80
102
  * Module augmentation for real-router.
81
103
  * Extends Router interface with hash plugin methods.
82
104
  */
83
105
  declare module "@real-router/core" {
84
- interface Router {
85
- /**
86
- * Builds full URL for a route with base path and hash prefix.
87
- * Added by hash plugin.
88
- */
89
- buildUrl: (name: string, params?: Params$1) => string;
90
- /**
91
- * Matches URL and returns corresponding state.
92
- * Added by hash plugin.
93
- */
94
- matchUrl: (url: string) => State$1 | undefined;
95
- /**
96
- * Replaces current history state without triggering navigation.
97
- * Added by hash plugin.
98
- */
99
- replaceHistoryState: (name: string, params?: Params$1, title?: string) => void;
100
- start(path?: string): Promise<State$1>;
101
- }
106
+ interface Router {
107
+ /**
108
+ * Builds full URL for a route with base path and hash prefix.
109
+ * Added by hash plugin.
110
+ */
111
+ buildUrl: (name: string, params?: Params) => string;
112
+ /**
113
+ * Matches URL and returns corresponding state.
114
+ * Added by hash plugin.
115
+ */
116
+ matchUrl: (url: string) => State | undefined;
117
+ /**
118
+ * Replaces current history state without triggering navigation.
119
+ * Added by hash plugin.
120
+ */
121
+ replaceHistoryState: (name: string, params?: Params, title?: string) => void;
122
+ start(path?: string): Promise<State>;
123
+ }
102
124
  }
103
-
125
+ //#endregion
104
126
  export { type Browser, type HashPluginOptions, hashPluginFactory, isStateStrict as isState };
127
+ //# sourceMappingURL=index.d.ts.map
package/dist/cjs/index.js CHANGED
@@ -1 +1,2 @@
1
- var e=require("@real-router/core/api"),t=require("@real-router/core"),r=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function o(e,t=new WeakSet){if(null==e)return!0;const r=typeof e;if("string"===r||"boolean"===r)return!0;if("number"===r)return Number.isFinite(e);if("function"===r||"symbol"===r)return!1;if(Array.isArray(e))return!t.has(e)&&(t.add(e),e.every(e=>o(e,t)));if("object"===r){if(t.has(e))return!1;t.add(e);const r=Object.getPrototypeOf(e);return(null===r||r===Object.prototype)&&Object.values(e).every(e=>o(e,t))}return!1}function n(e){if(null==e)return!0;const t=typeof e;return"string"===t||"boolean"===t||"number"===t&&Number.isFinite(e)}function a(e){if("object"!=typeof e||null===e||Array.isArray(e))return!1;const t=Object.getPrototypeOf(e);if(null!==t&&t!==Object.prototype)return!1;let r=!1;for(const t in e){if(!Object.hasOwn(e,t))continue;const o=e[t];if(!n(o)){const e=typeof o;if("function"===e||"symbol"===e)return!1;r=!0;break}}return!r||o(e)}function i(e){return"object"==typeof e&&null!==e&&!!function(e){return function(e){return"string"==typeof e&&(""===e||!(e.length>1e4)&&(!!e.startsWith("@@")||r.test(e)))}(e.name)&&"string"==typeof e.path&&a(e.params)}(e)}var s=(e,t)=>{globalThis.history.pushState(e,"",t)},c=(e,t)=>{globalThis.history.replaceState(e,"",t)},l=e=>(globalThis.addEventListener("popstate",e),()=>{globalThis.removeEventListener("popstate",e)}),u=()=>globalThis.location.hash,p=()=>{},h=e=>{let t=!1;return r=>{t||(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: "${e}"). Method "${r}" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),t=!0)}},f=e=>{const t=h(e);return{pushState:()=>{t("pushState")},replaceState:()=>{t("replaceState")},addPopstateListener:()=>(t("addPopstateListener"),p),getHash:()=>(t("getHash"),"")}};function d(e,t,r,o){const n={name:e.name,params:e.params,path:e.path};r?o.replaceState(n,t):o.pushState(n,t)}function g(e){let r=!1,o=null;async function n(a){if(r)return console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),void(o=a);r=!0;try{const t=function(e,t,r){if(i(e.state))return{name:e.state.name,params:e.state.params};const o=t.matchPath(r.getLocation());return o?{name:o.name,params:o.params}:void 0}(a,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(r){r instanceof t.RouterError||function(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{const t=e.router.getState();if(t){const r=e.buildUrl(t.name,t.params);e.browser.replaceState(t,r)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}(r)}finally{r=!1,function(){if(o){const t=o;o=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),n(t)}}()}}return e=>{n(e)}}function m(e,t,r,o){return(n,a={})=>{const i=e.buildState(n,a);if(!i)throw new Error(`[real-router] Cannot replace state: route "${n}" is not found`);d(e.makeState(i.name,i.params,t.buildPath(i.name,i.params),{params:i.meta}),o(n,a),!0,r)}}var b={hashPrefix:"",base:"",forceDeactivate:!0},v="hash-plugin";function w(e,t){return(t?e.replace(t,""):e.slice(1))||"/"}var y,S,P=class{#e;#t;#r;#o;#n;constructor(e,t,r,o,n,a,i){var s;this.#e=e,this.#t=o,this.#r=(s=o,t.addInterceptor("start",(e,t)=>e(t??s.getLocation())));const c=`${r.base}#${r.hashPrefix}`,l=(t,r)=>c+e.buildPath(t,r);this.#o=t.extendRouter({buildUrl:l,matchUrl:e=>{const r=function(e,t){const r=function(e,t){try{const r=new URL(e,globalThis.location.origin);return["http:","https:"].includes(r.protocol)?r:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(r){return console.warn(`[${t}] Could not parse url ${e}`,r),null}}(e,v);return r?w(r.hash,t)+r.search:null}(e,n);return r?t.matchPath(r):void 0},replaceHistoryState:m(t,e,o,l)});const u=g({router:e,api:t,browser:o,allowNotFound:t.getOptions().allowNotFound,transitionOptions:a,loggerContext:"hash-plugin",buildUrl:(t,r)=>e.buildUrl(t,r)});this.#n=function(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}({browser:o,shared:i,handler:u,cleanup:()=>{this.#r(),this.#o()}})}getPlugin(){return{...this.#n,onTransitionSuccess:(e,t,r)=>{const o=(a=t,((n=r).replace??!a)||!!n.reload&&e.path===a.path);var n,a;d(e,this.#e.buildUrl(e.name,e.params),o,this.#t)}}}},L=(y=b,S=v,e=>{if(e)for(const t of Object.keys(e))if(t in y){const r=e[t],o=typeof y[t],n=typeof r;if(void 0!==r&&n!==o)throw new Error(`[${S}] Invalid type for '${t}': expected ${o}, got ${n}`)}});exports.hashPluginFactory=function(t,r){L(t);const o={...b,...t};o.base=function(e){if(!e)return e;let t=e;return t.startsWith("/")||(t=`/${t}`),t.endsWith("/")&&(t=t.slice(0,-1)),t}(o.base);const n=(d=o.hashPrefix)?new RegExp(`^#${g=d,g.replaceAll(/[$()*+.?[\\\]^{|}-]/g,String.raw`\$&`)}`):null,a=r??function(e,t){if(void 0!==globalThis.window&&globalThis.history)return{pushState:s,replaceState:c,addPopstateListener:l,getLocation:e,getHash:u};const r=h(t);return{...f(t),getLocation:()=>(r("getLocation"),"")}}(()=>(e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path "${e}"`,t),e}})(w(globalThis.location.hash,n))+globalThis.location.search,"hash-plugin"),i={forceDeactivate:o.forceDeactivate,source:"popstate",replace:!0},p={removePopStateListener:void 0};var d,g;return function(t){return new P(t,e.getPluginApi(t),o,a,n,i,p).getPlugin()}},exports.isState=i;//# sourceMappingURL=index.js.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@real-router/core/api`),t=require(`@real-router/core`);const n=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function r(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:n.test(e):!1}function i(e,t=new WeakSet){if(e==null)return!0;let n=typeof e;if(n===`string`||n===`boolean`)return!0;if(n===`number`)return Number.isFinite(e);if(n===`function`||n===`symbol`)return!1;if(Array.isArray(e))return t.has(e)?!1:(t.add(e),e.every(e=>i(e,t)));if(n===`object`){if(t.has(e))return!1;t.add(e);let n=Object.getPrototypeOf(e);return n!==null&&n!==Object.prototype?!1:Object.values(e).every(e=>i(e,t))}return!1}function a(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}function o(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let r=e[t];if(!a(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return n?i(e):!0}function s(e){return r(e.name)&&typeof e.path==`string`&&o(e.params)}function c(e){return!(typeof e!=`object`||!e||!s(e))}const l=()=>globalThis.window!==void 0&&!!globalThis.history,u=(e,t)=>{globalThis.history.pushState(e,``,t)},d=(e,t)=>{globalThis.history.replaceState(e,``,t)},f=e=>(globalThis.addEventListener(`popstate`,e),()=>{globalThis.removeEventListener(`popstate`,e)}),p=()=>globalThis.location.hash;function m(e){if(!e)return e;let t=e;return t.startsWith(`/`)||(t=`/${t}`),t.endsWith(`/`)&&(t=t.slice(0,-1)),t}const h=e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path "${e}"`,t),e}},g=()=>{},_=e=>{let t=!1;return n=>{t||=(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: "${e}"). Method "${n}" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),!0)}},v=e=>{let t=_(e);return{pushState:()=>{t(`pushState`)},replaceState:()=>{t(`replaceState`)},addPopstateListener:()=>(t(`addPopstateListener`),g),getHash:()=>(t(`getHash`),``)}};function y(e,t,n){if(c(e.state))return{name:e.state.name,params:e.state.params};let r=t.matchPath(n.getLocation());return r?{name:r.name,params:r.params}:void 0}function b(e,t,n,r){let i={name:e.name,params:e.params,path:e.path};n?r.replaceState(i,t):r.pushState(i,t)}function x(e,t){return n=>{if(n){for(let r of Object.keys(n))if(r in e){let i=n[r],a=typeof e[r],o=typeof i;if(i!==void 0&&o!==a)throw Error(`[${t}] Invalid type for '${r}': expected ${a}, got ${o}`)}}}}function S(e,t){if(l())return{pushState:u,replaceState:d,addPopstateListener:f,getLocation:e,getHash:p};let n=_(t);return{...v(t),getLocation:()=>(n(`getLocation`),``)}}function C(e){let n=!1,r=null;function i(){if(r){let t=r;r=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),o(t)}}function a(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{let t=e.router.getState();if(t){let n=e.buildUrl(t.name,t.params);e.browser.replaceState(t,n)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}async function o(o){if(n){console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),r=o;return}n=!0;try{let t=y(o,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(e){e instanceof t.RouterError||a(e)}finally{n=!1,i()}}return e=>void o(e)}function w(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}function T(e,t){return e.addInterceptor(`start`,(e,n)=>e(n??t.getLocation()))}function E(e,t,n,r){return(i,a={})=>{let o=e.buildState(i,a);if(!o)throw Error(`[real-router] Cannot replace state: route "${i}" is not found`);b(e.makeState(o.name,o.params,t.buildPath(o.name,o.params),{params:o.meta}),r(i,a),!0,n)}}function D(e,t,n){return(e.replace??!n)||!!e.reload&&t.path===n.path}function O(e,t){try{let n=new URL(e,globalThis.location.origin);return[`http:`,`https:`].includes(n.protocol)?n:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(n){return console.warn(`[${t}] Could not parse url ${e}`,n),null}}const k={hashPrefix:``,base:``,forceDeactivate:!0},A=`hash-plugin`;function j(e){return e.replaceAll(/[$()*+.?[\\\]^{|}-]/g,String.raw`\$&`)}function M(e){return e?RegExp(`^#${j(e)}`):null}function N(e,t){return(t?e.replace(t,``):e.slice(1))||`/`}function P(e,t){let n=O(e,A);return n?N(n.hash,t)+n.search:null}var F=class{#e;#t;#n;#r;#i;constructor(e,t,n,r,i,a,o){this.#e=e,this.#t=r,this.#n=T(t,r);let s=`${n.base}#${n.hashPrefix}`,c=(t,n)=>s+e.buildPath(t,n);this.#r=t.extendRouter({buildUrl:c,matchUrl:e=>{let n=P(e,i);return n?t.matchPath(n):void 0},replaceHistoryState:E(t,e,r,c)}),this.#i=w({browser:r,shared:o,handler:C({router:e,api:t,browser:r,allowNotFound:t.getOptions().allowNotFound,transitionOptions:a,loggerContext:`hash-plugin`,buildUrl:(t,n)=>e.buildUrl(t,n)}),cleanup:()=>{this.#n(),this.#r()}})}getPlugin(){return{...this.#i,onTransitionSuccess:(e,t,n)=>{let r=D(n,e,t);b(e,this.#e.buildUrl(e.name,e.params),r,this.#t)}}}};const I=x(k,A);function L(t,n){I(t);let r={...k,...t};r.base=m(r.base);let i=M(r.hashPrefix),a=n??S(()=>h(N(globalThis.location.hash,i))+globalThis.location.search,`hash-plugin`),o={forceDeactivate:r.forceDeactivate,source:`popstate`,replace:!0},s={removePopStateListener:void 0};return function(t){return new F(t,(0,e.getPluginApi)(t),r,a,i,o,s).getPlugin()}}exports.hashPluginFactory=L,exports.isState=c;
2
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"names":["i","getPluginApi"],"mappings":"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","file":"index.js","sourcesContent":["// packages/hash-plugin/src/constants.ts\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const defaultOptions: Required<HashPluginOptions> = {\n hashPrefix: \"\",\n base: \"\",\n forceDeactivate: true,\n};\n\n/**\n * Source identifier for transitions triggered by browser events.\n */\nexport const source = \"popstate\";\n\nexport const LOGGER_CONTEXT = \"hash-plugin\";\n","// packages/hash-plugin/src/hash-utils.ts\n\nimport { safeParseUrl } from \"browser-env\";\n\nimport { LOGGER_CONTEXT } from \"./constants\";\n\nfunction escapeRegExp(str: string): string {\n return str.replaceAll(/[$()*+.?[\\\\\\]^{|}-]/g, String.raw`\\$&`);\n}\n\nexport function createHashPrefixRegex(hashPrefix: string): RegExp | null {\n if (!hashPrefix) {\n return null;\n }\n\n return new RegExp(`^#${escapeRegExp(hashPrefix)}`);\n}\n\n/**\n * Extract path from URL hash, stripping hash prefix.\n *\n * @param hash - URL hash (e.g., \"#/path\" or \"#!/path\")\n * @param prefixRegex - Pre-compiled regex for prefix stripping (null if no prefix)\n * @returns Extracted path (e.g., \"/path\")\n */\nexport function extractHashPath(\n hash: string,\n prefixRegex: RegExp | null,\n): string {\n const path = prefixRegex ? hash.replace(prefixRegex, \"\") : hash.slice(1);\n\n return path || \"/\";\n}\n\nexport function hashUrlToPath(\n url: string,\n prefixRegex: RegExp | null,\n): string | null {\n const parsedUrl = safeParseUrl(url, LOGGER_CONTEXT);\n\n return parsedUrl\n ? extractHashPath(parsedUrl.hash, prefixRegex) + parsedUrl.search\n : null;\n}\n","import {\n createPopstateHandler,\n createPopstateLifecycle,\n createStartInterceptor,\n createReplaceHistoryState,\n shouldReplaceHistory,\n updateBrowserState,\n} from \"browser-env\";\n\nimport { hashUrlToPath } from \"./hash-utils\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type {\n NavigationOptions,\n Params,\n Router,\n State,\n Plugin,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport class HashPlugin {\n readonly #router: Router;\n readonly #browser: Browser;\n readonly #removeStartInterceptor: () => void;\n readonly #removeExtensions: () => void;\n readonly #lifecycle: Pick<Plugin, \"onStart\" | \"onStop\" | \"teardown\">;\n\n constructor(\n router: Router,\n api: PluginApi,\n options: Required<HashPluginOptions>,\n browser: Browser,\n prefixRegex: RegExp | null,\n transitionOptions: {\n source: string;\n replace: true;\n forceDeactivate?: boolean;\n },\n shared: SharedFactoryState,\n ) {\n this.#router = router;\n this.#browser = browser;\n\n this.#removeStartInterceptor = createStartInterceptor(api, browser);\n\n const urlPrefix = `${options.base}#${options.hashPrefix}`;\n const pluginBuildUrl = (route: string, params?: Params) =>\n urlPrefix + router.buildPath(route, params);\n\n this.#removeExtensions = api.extendRouter({\n buildUrl: pluginBuildUrl,\n matchUrl: (url: string) => {\n const path = hashUrlToPath(url, prefixRegex);\n\n return path ? api.matchPath(path) : undefined;\n },\n replaceHistoryState: createReplaceHistoryState(\n api,\n router,\n browser,\n pluginBuildUrl,\n ),\n });\n\n const handler = createPopstateHandler({\n router,\n api,\n browser,\n allowNotFound: api.getOptions().allowNotFound,\n transitionOptions,\n loggerContext: \"hash-plugin\",\n buildUrl: (name: string, params?: Params) =>\n router.buildUrl(name, params),\n });\n\n this.#lifecycle = createPopstateLifecycle({\n browser,\n shared,\n handler,\n cleanup: () => {\n this.#removeStartInterceptor();\n this.#removeExtensions();\n },\n });\n }\n\n getPlugin(): Plugin {\n return {\n ...this.#lifecycle,\n\n onTransitionSuccess: (\n toState: State,\n fromState: State | undefined,\n navOptions: NavigationOptions,\n ) => {\n const replaceHistory = shouldReplaceHistory(\n navOptions,\n toState,\n fromState,\n );\n\n const url = this.#router.buildUrl(toState.name, toState.params);\n\n updateBrowserState(toState, url, replaceHistory, this.#browser);\n },\n };\n }\n}\n","import { createOptionsValidator } from \"browser-env\";\n\nimport { LOGGER_CONTEXT, defaultOptions } from \"./constants\";\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const validateOptions = createOptionsValidator<HashPluginOptions>(\n defaultOptions,\n LOGGER_CONTEXT,\n);\n","import { getPluginApi } from \"@real-router/core/api\";\nimport {\n createSafeBrowser,\n normalizeBase,\n safelyEncodePath,\n} from \"browser-env\";\n\nimport { defaultOptions, source } from \"./constants\";\nimport { createHashPrefixRegex, extractHashPath } from \"./hash-utils\";\nimport { HashPlugin } from \"./plugin\";\nimport { validateOptions } from \"./validation\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type { PluginFactory, Router } from \"@real-router/core\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport function hashPluginFactory(\n opts?: Partial<HashPluginOptions>,\n browser?: Browser,\n): PluginFactory {\n validateOptions(opts);\n\n const options: Required<HashPluginOptions> = { ...defaultOptions, ...opts };\n\n options.base = normalizeBase(options.base);\n\n const prefixRegex = createHashPrefixRegex(options.hashPrefix);\n const resolvedBrowser =\n browser ??\n createSafeBrowser(\n () =>\n safelyEncodePath(\n extractHashPath(globalThis.location.hash, prefixRegex),\n ) + globalThis.location.search,\n \"hash-plugin\",\n );\n\n const transitionOptions = {\n forceDeactivate: options.forceDeactivate,\n source,\n replace: true as const,\n };\n\n const shared: SharedFactoryState = { removePopStateListener: undefined };\n\n return function hashPlugin(routerBase) {\n const plugin = new HashPlugin(\n routerBase as Router,\n getPluginApi(routerBase),\n options,\n resolvedBrowser,\n prefixRegex,\n transitionOptions,\n shared,\n );\n\n return plugin.getPlugin();\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","names":["n","r","a","o","s","c","d","e","p","t","safeParseUrl","#router","#browser","#removeStartInterceptor","#removeExtensions","#lifecycle","createStartInterceptor","createReplaceHistoryState","createPopstateLifecycle","createPopstateHandler","shouldReplaceHistory","createOptionsValidator","normalizeBase","createSafeBrowser","safelyEncodePath"],"sources":["../../../type-guards/dist/esm/index.mjs","../../../browser-env/dist/esm/index.mjs","../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const e=[`replace`,`reload`,`force`,`forceDeactivate`,`redirected`];function t(t){if(typeof t!=`object`||!t||Array.isArray(t))return!1;let n=t;for(let t of e){let e=n[t];if(e!==void 0&&typeof e!=`boolean`)return!1}let r=n.signal;return!(r!==void 0&&!(r instanceof AbortSignal))}const n=/\\S/,r=/^[A-Z_a-z][\\w-]*(?:\\.[A-Z_a-z][\\w-]*)*$/;function i(e,t){return TypeError(`[router.${e}] ${t}`)}function a(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:r.test(e):!1}function o(e,t=new WeakSet){if(e==null)return!0;let n=typeof e;if(n===`string`||n===`boolean`)return!0;if(n===`number`)return Number.isFinite(e);if(n===`function`||n===`symbol`)return!1;if(Array.isArray(e))return t.has(e)?!1:(t.add(e),e.every(e=>o(e,t)));if(n===`object`){if(t.has(e))return!1;t.add(e);let n=Object.getPrototypeOf(e);return n!==null&&n!==Object.prototype?!1:Object.values(e).every(e=>o(e,t))}return!1}function s(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}function c(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let r=e[t];if(!s(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return n?o(e):!0}function l(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):Array.isArray(e)?e.every(e=>{let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}):!1}function u(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let n=e[t];if(!l(n))return!1}return!0}function d(e){return a(e.name)&&typeof e.path==`string`&&c(e.params)}function f(e){return typeof e!=`object`||!e?!1:d(e)}function p(e){return!(typeof e!=`object`||!e||!d(e))}function m(e){return typeof e==`string`}function h(e){return typeof e==`boolean`}function g(e,t){return e in t}function _(e){return typeof e==`number`?Number.isFinite(e):typeof e==`string`||typeof e==`boolean`}function v(e,t){if(typeof e!=`string`)throw i(t,`Route name must be a string, got ${typeof e}`);if(e!==``){if(!n.test(e))throw i(t,`Route name cannot contain only whitespace`);if(e.length>1e4)throw i(t,`Route name exceeds maximum length of 10000 characters. This is a technical safety limit.`);if(!e.startsWith(`@@`)&&!r.test(e))throw i(t,`Invalid route name \"${e}\". Each segment must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens. Segments are separated by dots (e.g., \"users.profile\").`)}}function y(e){return e===null?`null`:Array.isArray(e)?`array[${e.length}]`:typeof e==`object`?`constructor`in e&&e.constructor.name!==`Object`?e.constructor.name:`object`:typeof e}function b(e,t){if(!f(e))throw TypeError(`[${t}] Invalid state structure: ${y(e)}. Expected State object with name, params, and path properties.`)}export{y as getTypeDescription,h as isBoolean,t as isNavigationOptions,g as isObjKey,c as isParams,u as isParamsStrict,_ as isPrimitiveValue,a as isRouteName,f as isState,p as isStateStrict,m as isString,v as validateRouteName,b as validateState};\n//# sourceMappingURL=index.mjs.map","import{isStateStrict as e}from\"type-guards\";import{RouterError as t}from\"@real-router/core\";const n=()=>globalThis.window!==void 0&&!!globalThis.history,r=(e,t)=>{globalThis.history.pushState(e,``,t)},i=(e,t)=>{globalThis.history.replaceState(e,``,t)},a=e=>(globalThis.addEventListener(`popstate`,e),()=>{globalThis.removeEventListener(`popstate`,e)}),o=()=>globalThis.location.hash;function s(e){if(!e)return e;let t=e;return t.startsWith(`/`)||(t=`/${t}`),t.endsWith(`/`)&&(t=t.slice(0,-1)),t}const c=e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path \"${e}\"`,t),e}},l=()=>{},u=e=>{let t=!1;return n=>{t||=(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: \"${e}\"). Method \"${n}\" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),!0)}},d=e=>{let t=u(e);return{pushState:()=>{t(`pushState`)},replaceState:()=>{t(`replaceState`)},addPopstateListener:()=>(t(`addPopstateListener`),l),getHash:()=>(t(`getHash`),``)}};function f(t,n,r){if(e(t.state))return{name:t.state.name,params:t.state.params};let i=n.matchPath(r.getLocation());return i?{name:i.name,params:i.params}:void 0}function p(e,t,n,r){let i={name:e.name,params:e.params,path:e.path};n?r.replaceState(i,t):r.pushState(i,t)}function m(e,t){return n=>{if(n){for(let r of Object.keys(n))if(r in e){let i=n[r],a=typeof e[r],o=typeof i;if(i!==void 0&&o!==a)throw Error(`[${t}] Invalid type for '${r}': expected ${a}, got ${o}`)}}}}function h(e,t){if(n())return{pushState:r,replaceState:i,addPopstateListener:a,getLocation:e,getHash:o};let s=u(t);return{...d(t),getLocation:()=>(s(`getLocation`),``)}}function g(e){let n=!1,r=null;function i(){if(r){let t=r;r=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),o(t)}}function a(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{let t=e.router.getState();if(t){let n=e.buildUrl(t.name,t.params);e.browser.replaceState(t,n)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}async function o(o){if(n){console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),r=o;return}n=!0;try{let t=f(o,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(e){e instanceof t||a(e)}finally{n=!1,i()}}return e=>void o(e)}function _(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}function v(e,t){return e.addInterceptor(`start`,(e,n)=>e(n??t.getLocation()))}function y(e,t,n,r){return(i,a={})=>{let o=e.buildState(i,a);if(!o)throw Error(`[real-router] Cannot replace state: route \"${i}\" is not found`);p(e.makeState(o.name,o.params,t.buildPath(o.name,o.params),{params:o.meta}),r(i,a),!0,n)}}function b(e,t,n){return(e.replace??!n)||!!e.reload&&t.path===n.path}function x(e,t){try{let n=new URL(e,globalThis.location.origin);return[`http:`,`https:`].includes(n.protocol)?n:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(n){return console.warn(`[${t}] Could not parse url ${e}`,n),null}}export{a as addPopstateListener,d as createHistoryFallbackBrowser,m as createOptionsValidator,g as createPopstateHandler,_ as createPopstateLifecycle,y as createReplaceHistoryState,h as createSafeBrowser,v as createStartInterceptor,u as createWarnOnce,o as getHash,f as getRouteFromEvent,n as isBrowserEnvironment,s as normalizeBase,r as pushState,i as replaceState,x as safeParseUrl,c as safelyEncodePath,b as shouldReplaceHistory,p as updateBrowserState};\n//# sourceMappingURL=index.mjs.map","// packages/hash-plugin/src/constants.ts\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const defaultOptions: Required<HashPluginOptions> = {\n hashPrefix: \"\",\n base: \"\",\n forceDeactivate: true,\n};\n\n/**\n * Source identifier for transitions triggered by browser events.\n */\nexport const source = \"popstate\";\n\nexport const LOGGER_CONTEXT = \"hash-plugin\";\n","// packages/hash-plugin/src/hash-utils.ts\n\nimport { safeParseUrl } from \"browser-env\";\n\nimport { LOGGER_CONTEXT } from \"./constants\";\n\nfunction escapeRegExp(str: string): string {\n return str.replaceAll(/[$()*+.?[\\\\\\]^{|}-]/g, String.raw`\\$&`);\n}\n\nexport function createHashPrefixRegex(hashPrefix: string): RegExp | null {\n if (!hashPrefix) {\n return null;\n }\n\n return new RegExp(`^#${escapeRegExp(hashPrefix)}`);\n}\n\n/**\n * Extract path from URL hash, stripping hash prefix.\n *\n * @param hash - URL hash (e.g., \"#/path\" or \"#!/path\")\n * @param prefixRegex - Pre-compiled regex for prefix stripping (null if no prefix)\n * @returns Extracted path (e.g., \"/path\")\n */\nexport function extractHashPath(\n hash: string,\n prefixRegex: RegExp | null,\n): string {\n const path = prefixRegex ? hash.replace(prefixRegex, \"\") : hash.slice(1);\n\n return path || \"/\";\n}\n\nexport function hashUrlToPath(\n url: string,\n prefixRegex: RegExp | null,\n): string | null {\n const parsedUrl = safeParseUrl(url, LOGGER_CONTEXT);\n\n return parsedUrl\n ? extractHashPath(parsedUrl.hash, prefixRegex) + parsedUrl.search\n : null;\n}\n","import {\n createPopstateHandler,\n createPopstateLifecycle,\n createStartInterceptor,\n createReplaceHistoryState,\n shouldReplaceHistory,\n updateBrowserState,\n} from \"browser-env\";\n\nimport { hashUrlToPath } from \"./hash-utils\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type {\n NavigationOptions,\n Params,\n Router,\n State,\n Plugin,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport class HashPlugin {\n readonly #router: Router;\n readonly #browser: Browser;\n readonly #removeStartInterceptor: () => void;\n readonly #removeExtensions: () => void;\n readonly #lifecycle: Pick<Plugin, \"onStart\" | \"onStop\" | \"teardown\">;\n\n constructor(\n router: Router,\n api: PluginApi,\n options: Required<HashPluginOptions>,\n browser: Browser,\n prefixRegex: RegExp | null,\n transitionOptions: {\n source: string;\n replace: true;\n forceDeactivate?: boolean;\n },\n shared: SharedFactoryState,\n ) {\n this.#router = router;\n this.#browser = browser;\n\n this.#removeStartInterceptor = createStartInterceptor(api, browser);\n\n const urlPrefix = `${options.base}#${options.hashPrefix}`;\n const pluginBuildUrl = (route: string, params?: Params) =>\n urlPrefix + router.buildPath(route, params);\n\n this.#removeExtensions = api.extendRouter({\n buildUrl: pluginBuildUrl,\n matchUrl: (url: string) => {\n const path = hashUrlToPath(url, prefixRegex);\n\n return path ? api.matchPath(path) : undefined;\n },\n replaceHistoryState: createReplaceHistoryState(\n api,\n router,\n browser,\n pluginBuildUrl,\n ),\n });\n\n const handler = createPopstateHandler({\n router,\n api,\n browser,\n allowNotFound: api.getOptions().allowNotFound,\n transitionOptions,\n loggerContext: \"hash-plugin\",\n buildUrl: (name: string, params?: Params) =>\n router.buildUrl(name, params),\n });\n\n this.#lifecycle = createPopstateLifecycle({\n browser,\n shared,\n handler,\n cleanup: () => {\n this.#removeStartInterceptor();\n this.#removeExtensions();\n },\n });\n }\n\n getPlugin(): Plugin {\n return {\n ...this.#lifecycle,\n\n onTransitionSuccess: (\n toState: State,\n fromState: State | undefined,\n navOptions: NavigationOptions,\n ) => {\n const replaceHistory = shouldReplaceHistory(\n navOptions,\n toState,\n fromState,\n );\n\n const url = this.#router.buildUrl(toState.name, toState.params);\n\n updateBrowserState(toState, url, replaceHistory, this.#browser);\n },\n };\n }\n}\n","import { createOptionsValidator } from \"browser-env\";\n\nimport { LOGGER_CONTEXT, defaultOptions } from \"./constants\";\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const validateOptions = createOptionsValidator<HashPluginOptions>(\n defaultOptions,\n LOGGER_CONTEXT,\n);\n","import { getPluginApi } from \"@real-router/core/api\";\nimport {\n createSafeBrowser,\n normalizeBase,\n safelyEncodePath,\n} from \"browser-env\";\n\nimport { defaultOptions, source } from \"./constants\";\nimport { createHashPrefixRegex, extractHashPath } from \"./hash-utils\";\nimport { HashPlugin } from \"./plugin\";\nimport { validateOptions } from \"./validation\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type { PluginFactory, Router } from \"@real-router/core\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport function hashPluginFactory(\n opts?: Partial<HashPluginOptions>,\n browser?: Browser,\n): PluginFactory {\n validateOptions(opts);\n\n const options: Required<HashPluginOptions> = { ...defaultOptions, ...opts };\n\n options.base = normalizeBase(options.base);\n\n const prefixRegex = createHashPrefixRegex(options.hashPrefix);\n const resolvedBrowser =\n browser ??\n createSafeBrowser(\n () =>\n safelyEncodePath(\n extractHashPath(globalThis.location.hash, prefixRegex),\n ) + globalThis.location.search,\n \"hash-plugin\",\n );\n\n const transitionOptions = {\n forceDeactivate: options.forceDeactivate,\n source,\n replace: true as const,\n };\n\n const shared: SharedFactoryState = { removePopStateListener: undefined };\n\n return function hashPlugin(routerBase) {\n const plugin = new HashPlugin(\n routerBase as Router,\n getPluginApi(routerBase),\n options,\n resolvedBrowser,\n prefixRegex,\n transitionOptions,\n shared,\n );\n\n return plugin.getPlugin();\n };\n}\n"],"mappings":"yIAAsR,MAAaC,EAAE,0CAAiG,SAASC,EAAE,EAAE,CAAC,OAAO,OAAO,GAAG,SAAS,IAAI,GAAG,CAAC,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,EAAE,WAAW,KAAK,CAAC,CAAC,EAAED,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,SAASE,EAAE,EAAE,EAAE,IAAI,QAAQ,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,UAAU,IAAI,UAAU,MAAM,CAAC,EAAE,GAAG,IAAI,SAAS,OAAO,OAAO,SAAS,EAAE,CAAC,GAAG,IAAI,YAAY,IAAI,SAAS,MAAM,CAAC,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAGA,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,eAAe,EAAE,CAAC,OAAO,IAAI,MAAM,IAAI,OAAO,UAAU,CAAC,EAAE,OAAO,OAAO,EAAE,CAAC,MAAM,GAAGA,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,SAASC,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,UAAU,IAAI,UAAU,CAAC,EAAE,IAAI,SAAS,OAAO,SAAS,EAAE,CAAC,CAAC,EAAE,SAASC,EAAE,EAAE,CAAC,GAAG,OAAO,GAAG,UAAU,CAAC,GAAG,MAAM,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,eAAe,EAAE,CAAC,GAAG,IAAI,MAAM,IAAI,OAAO,UAAU,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,OAAO,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,GAAG,CAACD,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,YAAY,IAAI,SAAS,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,OAAO,EAAED,EAAE,EAAE,CAAC,CAAC,EAA4Y,SAASG,EAAE,EAAE,CAAC,OAAOJ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,UAAUG,EAAE,EAAE,OAAO,CAAqD,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG,CAACC,EAAE,EAAE,ECAhxD,MAAM,MAAM,WAAW,SAAS,IAAK,IAAG,CAAC,CAAC,WAAW,QAAQ,GAAG,EAAE,IAAI,CAAC,WAAW,QAAQ,UAAU,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,QAAQ,aAAa,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,WAAW,iBAAiB,WAAW,EAAE,KAAK,CAAC,WAAW,oBAAoB,WAAW,EAAE,GAAG,MAAM,WAAW,SAAS,KAAK,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,IAAI,KAAK,EAAE,SAAS,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,UAAU,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,QAAQ,KAAK,wCAAwC,EAAE,GAAG,EAAE,CAAC,IAAI,MAAM,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,MAAO,IAAG,CAAC,KAAK,QAAQ,KAAK,gFAAgF,EAAE,cAAc,EAAE,6GAA6G,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,iBAAiB,CAAC,EAAE,eAAe,EAAE,yBAAyB,EAAE,sBAAsB,CAAC,GAAG,aAAa,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,GAAGC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,OAAO,EAAE,OAAO,CAAC,IAAK,GAAE,SAASC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,OAAO,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,MAAO,IAAG,CAAC,GAAG,OAAO,IAAI,KAAK,OAAO,KAAK,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,IAAK,IAAG,IAAI,EAAE,MAAM,MAAM,IAAI,EAAE,sBAAsB,EAAE,cAAc,EAAE,QAAQ,IAAI,IAAI,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,QAAQ,KAAK,IAAI,EAAE,cAAc,sCAAsC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,QAAQ,MAAM,IAAI,EAAE,cAAc,gCAAgC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,QAAQ,aAAa,EAAE,EAAE,QAAQ,EAAE,CAAC,QAAQ,MAAM,IAAI,EAAE,cAAc,yCAAyC,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,KAAK,IAAI,EAAE,cAAc,oDAAoD,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,cAAc,EAAE,OAAO,mBAAmB,EAAE,QAAQ,aAAa,CAAC,CAAC,MAAM,EAAE,OAAO,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,aAAaC,EAAAA,aAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAO,IAAG,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,wBAAwB,EAAE,OAAO,wBAAwB,CAAC,EAAE,OAAO,uBAAuB,EAAE,QAAQ,oBAAoB,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,OAAO,yBAAyB,EAAE,OAAO,wBAAwB,CAAC,EAAE,OAAO,uBAAuB,IAAK,KAAI,aAAa,CAAC,EAAE,OAAO,yBAAyB,EAAE,OAAO,wBAAwB,CAAC,EAAE,OAAO,uBAAuB,IAAK,IAAG,EAAE,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,eAAe,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,8CAA8C,EAAE,gBAAgB,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,WAAW,SAAS,OAAO,CAAC,MAAM,CAAC,QAAQ,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,QAAQ,KAAK,IAAI,EAAE,4BAA4B,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,QAAQ,KAAK,IAAI,EAAE,wBAAwB,IAAI,EAAE,CAAC,MCIxhH,MAAa,EAA8C,CACzD,WAAY,GACZ,KAAM,GACN,gBAAiB,GAClB,CAOY,EAAiB,cCT9B,SAAS,EAAa,EAAqB,CACzC,OAAO,EAAI,WAAW,uBAAwB,OAAO,GAAG,MAAM,CAGhE,SAAgB,EAAsB,EAAmC,CAKvE,OAJK,EAIM,OAAO,KAAK,EAAa,EAAW,GAAG,CAHzC,KAaX,SAAgB,EACd,EACA,EACQ,CAGR,OAFa,EAAc,EAAK,QAAQ,EAAa,GAAG,CAAG,EAAK,MAAM,EAAE,GAEzD,IAGjB,SAAgB,EACd,EACA,EACe,CACf,IAAM,EAAYC,EAAa,EAAK,EAAe,CAEnD,OAAO,EACH,EAAgB,EAAU,KAAM,EAAY,CAAG,EAAU,OACzD,KCpBN,IAAa,EAAb,KAAwB,CACtB,GACA,GACA,GACA,GACA,GAEA,YACE,EACA,EACA,EACA,EACA,EACA,EAKA,EACA,CACA,MAAA,EAAe,EACf,MAAA,EAAgB,EAEhB,MAAA,EAA+BM,EAAuB,EAAK,EAAQ,CAEnE,IAAM,EAAY,GAAG,EAAQ,KAAK,GAAG,EAAQ,aACvC,GAAkB,EAAe,IACrC,EAAY,EAAO,UAAU,EAAO,EAAO,CAE7C,MAAA,EAAyB,EAAI,aAAa,CACxC,SAAU,EACV,SAAW,GAAgB,CACzB,IAAM,EAAO,EAAc,EAAK,EAAY,CAE5C,OAAO,EAAO,EAAI,UAAU,EAAK,CAAG,IAAA,IAEtC,oBAAqBC,EACnB,EACA,EACA,EACA,EACD,CACF,CAAC,CAaF,MAAA,EAAkBC,EAAwB,CACxC,UACA,SACA,QAdcC,EAAsB,CACpC,SACA,MACA,UACA,cAAe,EAAI,YAAY,CAAC,cAChC,oBACA,cAAe,cACf,UAAW,EAAc,IACvB,EAAO,SAAS,EAAM,EAAO,CAChC,CAAC,CAMA,YAAe,CACb,MAAA,GAA8B,CAC9B,MAAA,GAAwB,EAE3B,CAAC,CAGJ,WAAoB,CAClB,MAAO,CACL,GAAG,MAAA,EAEH,qBACE,EACA,EACA,IACG,CACH,IAAM,EAAiBC,EACrB,EACA,EACA,EACD,CAID,EAAmB,EAFP,MAAA,EAAa,SAAS,EAAQ,KAAM,EAAQ,OAAO,CAE9B,EAAgB,MAAA,EAAc,EAElE,GCrGL,MAAa,EAAkBC,EAC7B,EACA,EACD,CCOD,SAAgB,EACd,EACA,EACe,CACf,EAAgB,EAAK,CAErB,IAAM,EAAuC,CAAE,GAAG,EAAgB,GAAG,EAAM,CAE3E,EAAQ,KAAOC,EAAc,EAAQ,KAAK,CAE1C,IAAM,EAAc,EAAsB,EAAQ,WAAW,CACvD,EACJ,GACAC,MAEIC,EACE,EAAgB,WAAW,SAAS,KAAM,EAAY,CACvD,CAAG,WAAW,SAAS,OAC1B,cACD,CAEG,EAAoB,CACxB,gBAAiB,EAAQ,gBACzB,kBACA,QAAS,GACV,CAEK,EAA6B,CAAE,uBAAwB,IAAA,GAAW,CAExE,OAAO,SAAoB,EAAY,CAWrC,OAVe,IAAI,EACjB,GAAA,EAAA,EAAA,cACa,EAAW,CACxB,EACA,EACA,EACA,EACA,EACD,CAEa,WAAW"}
@@ -1,67 +1,82 @@
1
- import { State as State$1, PluginFactory, Params as Params$1 } from '@real-router/core';
1
+ import { Params, PluginFactory, State } from "@real-router/core";
2
2
 
3
+ //#region src/types.d.ts
3
4
  /**
4
5
  * Hash-based routing plugin configuration.
5
6
  * Uses URL hash fragment for navigation (e.g., example.com/#/path).
6
7
  */
7
8
  interface HashPluginOptions {
8
- /**
9
- * Prefix for hash (e.g., "!" for "#!/path").
10
- *
11
- * @default ""
12
- */
13
- hashPrefix?: string;
14
- /**
15
- * Base path prepended before hash (e.g., "/app" → "/app#/path").
16
- *
17
- * @default ""
18
- */
19
- base?: string;
20
- /**
21
- * Force deactivation of current route even if canDeactivate returns false.
22
- *
23
- * @default true
24
- */
25
- forceDeactivate?: boolean;
9
+ /**
10
+ * Prefix for hash (e.g., "!" for "#!/path").
11
+ *
12
+ * @default ""
13
+ */
14
+ hashPrefix?: string;
15
+ /**
16
+ * Base path prepended before hash (e.g., "/app" → "/app#/path").
17
+ *
18
+ * @default ""
19
+ */
20
+ base?: string;
21
+ /**
22
+ * Force deactivation of current route even if canDeactivate returns false.
23
+ *
24
+ * @default true
25
+ */
26
+ forceDeactivate?: boolean;
26
27
  }
27
-
28
+ //#endregion
29
+ //#region ../browser-env/dist/esm/index.d.mts
30
+ //#region src/types.d.ts
28
31
  interface HistoryBrowser {
29
- pushState: (state: State$1, path: string) => void;
30
- replaceState: (state: State$1, path: string) => void;
31
- addPopstateListener: (fn: (evt: PopStateEvent) => void) => () => void;
32
- getHash: () => string;
32
+ pushState: (state: State, path: string) => void;
33
+ replaceState: (state: State, path: string) => void;
34
+ addPopstateListener: (fn: (evt: PopStateEvent) => void) => () => void;
35
+ getHash: () => string;
33
36
  }
34
37
  interface Browser extends HistoryBrowser {
35
- getLocation: () => string;
38
+ getLocation: () => string;
36
39
  }
37
-
40
+ /**
41
+ * Shared mutable state across plugin instances created by the same factory.
42
+ * Enables cleanup of a previous instance's popstate listener when the factory is reused.
43
+ */
44
+ //#endregion
45
+ //#region src/factory.d.ts
38
46
  declare function hashPluginFactory(opts?: Partial<HashPluginOptions>, browser?: Browser): PluginFactory;
39
-
47
+ //#endregion
48
+ //#region ../core-types/dist/esm/index.d.mts
40
49
  type TransitionPhase = "deactivating" | "activating";
41
50
  type TransitionReason = "success" | "blocked" | "cancelled" | "error";
42
51
  interface TransitionMeta {
43
- phase: TransitionPhase;
44
- reason: TransitionReason;
45
- reload?: boolean;
46
- redirected?: boolean;
47
- from?: string;
48
- blocker?: string;
49
- segments: {
50
- deactivated: string[];
51
- activated: string[];
52
- intersection: string;
53
- };
52
+ phase: TransitionPhase;
53
+ reason: TransitionReason;
54
+ reload?: boolean;
55
+ redirected?: boolean;
56
+ from?: string;
57
+ blocker?: string;
58
+ segments: {
59
+ deactivated: string[];
60
+ activated: string[];
61
+ intersection: string;
62
+ };
54
63
  }
55
- interface State<P extends Params = Params> {
56
- name: string;
57
- params: P;
58
- path: string;
59
- transition?: TransitionMeta | undefined;
64
+ interface State$1<P extends Params$1 = Params$1> {
65
+ name: string;
66
+ params: P;
67
+ path: string;
68
+ transition?: TransitionMeta | undefined;
60
69
  }
61
- interface Params {
62
- [key: string]: string | string[] | number | number[] | boolean | boolean[] | Params | Params[] | Record<string, string | number | boolean> | null | undefined;
63
- }
64
-
70
+ interface Params$1 {
71
+ [key: string]: string | string[] | number | number[] | boolean | boolean[] | Params$1 | Params$1[] | Record<string, string | number | boolean> | null | undefined;
72
+ } //#endregion
73
+ //#region src/limits.d.ts
74
+ /**
75
+ * Configuration for router resource limits.
76
+ * Controls maximum allowed values for various router operations to prevent resource exhaustion.
77
+ */
78
+ //#endregion
79
+ //#region ../type-guards/dist/esm/index.d.mts
65
80
  /**
66
81
  * Enhanced type guard for State with deep validation.
67
82
  * Checks not only presence but also types of all required fields.
@@ -74,31 +89,40 @@ interface Params {
74
89
  * isStateStrict({ name: 'home', params: {}, path: '/', meta: { id: 1 } }); // true
75
90
  * isStateStrict({ name: 'home', params: 'invalid', path: '/' }); // false
76
91
  */
77
- declare function isStateStrict<P extends Params = Params>(value: unknown): value is State<P>;
78
-
92
+ declare function isStateStrict<P extends Params$1 = Params$1>(value: unknown): value is State$1<P>; //#endregion
93
+ //#region src/guards/primitives.d.ts
94
+ /**
95
+ * Type guard for string type.
96
+ *
97
+ * @param value - Value to check
98
+ * @returns true if value is a string
99
+ */
100
+ //#endregion
101
+ //#region src/index.d.ts
79
102
  /**
80
103
  * Module augmentation for real-router.
81
104
  * Extends Router interface with hash plugin methods.
82
105
  */
83
106
  declare module "@real-router/core" {
84
- interface Router {
85
- /**
86
- * Builds full URL for a route with base path and hash prefix.
87
- * Added by hash plugin.
88
- */
89
- buildUrl: (name: string, params?: Params$1) => string;
90
- /**
91
- * Matches URL and returns corresponding state.
92
- * Added by hash plugin.
93
- */
94
- matchUrl: (url: string) => State$1 | undefined;
95
- /**
96
- * Replaces current history state without triggering navigation.
97
- * Added by hash plugin.
98
- */
99
- replaceHistoryState: (name: string, params?: Params$1, title?: string) => void;
100
- start(path?: string): Promise<State$1>;
101
- }
107
+ interface Router {
108
+ /**
109
+ * Builds full URL for a route with base path and hash prefix.
110
+ * Added by hash plugin.
111
+ */
112
+ buildUrl: (name: string, params?: Params) => string;
113
+ /**
114
+ * Matches URL and returns corresponding state.
115
+ * Added by hash plugin.
116
+ */
117
+ matchUrl: (url: string) => State | undefined;
118
+ /**
119
+ * Replaces current history state without triggering navigation.
120
+ * Added by hash plugin.
121
+ */
122
+ replaceHistoryState: (name: string, params?: Params, title?: string) => void;
123
+ start(path?: string): Promise<State>;
124
+ }
102
125
  }
103
-
126
+ //#endregion
104
127
  export { type Browser, type HashPluginOptions, hashPluginFactory, isStateStrict as isState };
128
+ //# sourceMappingURL=index.d.mts.map
@@ -1 +1,2 @@
1
- import{getPluginApi as e}from"@real-router/core/api";import{RouterError as t}from"@real-router/core";var r=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function o(e,t=new WeakSet){if(null==e)return!0;const r=typeof e;if("string"===r||"boolean"===r)return!0;if("number"===r)return Number.isFinite(e);if("function"===r||"symbol"===r)return!1;if(Array.isArray(e))return!t.has(e)&&(t.add(e),e.every(e=>o(e,t)));if("object"===r){if(t.has(e))return!1;t.add(e);const r=Object.getPrototypeOf(e);return(null===r||r===Object.prototype)&&Object.values(e).every(e=>o(e,t))}return!1}function n(e){if(null==e)return!0;const t=typeof e;return"string"===t||"boolean"===t||"number"===t&&Number.isFinite(e)}function a(e){if("object"!=typeof e||null===e||Array.isArray(e))return!1;const t=Object.getPrototypeOf(e);if(null!==t&&t!==Object.prototype)return!1;let r=!1;for(const t in e){if(!Object.hasOwn(e,t))continue;const o=e[t];if(!n(o)){const e=typeof o;if("function"===e||"symbol"===e)return!1;r=!0;break}}return!r||o(e)}function s(e){return"object"==typeof e&&null!==e&&!!function(e){return function(e){return"string"==typeof e&&(""===e||!(e.length>1e4)&&(!!e.startsWith("@@")||r.test(e)))}(e.name)&&"string"==typeof e.path&&a(e.params)}(e)}var i=(e,t)=>{globalThis.history.pushState(e,"",t)},c=(e,t)=>{globalThis.history.replaceState(e,"",t)},l=e=>(globalThis.addEventListener("popstate",e),()=>{globalThis.removeEventListener("popstate",e)}),u=()=>globalThis.location.hash,p=()=>{},h=e=>{let t=!1;return r=>{t||(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: "${e}"). Method "${r}" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),t=!0)}},f=e=>{const t=h(e);return{pushState:()=>{t("pushState")},replaceState:()=>{t("replaceState")},addPopstateListener:()=>(t("addPopstateListener"),p),getHash:()=>(t("getHash"),"")}};function d(e,t,r,o){const n={name:e.name,params:e.params,path:e.path};r?o.replaceState(n,t):o.pushState(n,t)}function m(e){let r=!1,o=null;async function n(a){if(r)return console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),void(o=a);r=!0;try{const t=function(e,t,r){if(s(e.state))return{name:e.state.name,params:e.state.params};const o=t.matchPath(r.getLocation());return o?{name:o.name,params:o.params}:void 0}(a,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(r){r instanceof t||function(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{const t=e.router.getState();if(t){const r=e.buildUrl(t.name,t.params);e.browser.replaceState(t,r)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}(r)}finally{r=!1,function(){if(o){const t=o;o=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),n(t)}}()}}return e=>{n(e)}}function g(e,t,r,o){return(n,a={})=>{const s=e.buildState(n,a);if(!s)throw new Error(`[real-router] Cannot replace state: route "${n}" is not found`);d(e.makeState(s.name,s.params,t.buildPath(s.name,s.params),{params:s.meta}),o(n,a),!0,r)}}var b={hashPrefix:"",base:"",forceDeactivate:!0},v="hash-plugin";function w(e,t){return(t?e.replace(t,""):e.slice(1))||"/"}var y,S,P=class{#e;#t;#r;#o;#n;constructor(e,t,r,o,n,a,s){var i;this.#e=e,this.#t=o,this.#r=(i=o,t.addInterceptor("start",(e,t)=>e(t??i.getLocation())));const c=`${r.base}#${r.hashPrefix}`,l=(t,r)=>c+e.buildPath(t,r);this.#o=t.extendRouter({buildUrl:l,matchUrl:e=>{const r=function(e,t){const r=function(e,t){try{const r=new URL(e,globalThis.location.origin);return["http:","https:"].includes(r.protocol)?r:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(r){return console.warn(`[${t}] Could not parse url ${e}`,r),null}}(e,v);return r?w(r.hash,t)+r.search:null}(e,n);return r?t.matchPath(r):void 0},replaceHistoryState:g(t,e,o,l)});const u=m({router:e,api:t,browser:o,allowNotFound:t.getOptions().allowNotFound,transitionOptions:a,loggerContext:"hash-plugin",buildUrl:(t,r)=>e.buildUrl(t,r)});this.#n=function(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}({browser:o,shared:s,handler:u,cleanup:()=>{this.#r(),this.#o()}})}getPlugin(){return{...this.#n,onTransitionSuccess:(e,t,r)=>{const o=(a=t,((n=r).replace??!a)||!!n.reload&&e.path===a.path);var n,a;d(e,this.#e.buildUrl(e.name,e.params),o,this.#t)}}}},L=(y=b,S=v,e=>{if(e)for(const t of Object.keys(e))if(t in y){const r=e[t],o=typeof y[t],n=typeof r;if(void 0!==r&&n!==o)throw new Error(`[${S}] Invalid type for '${t}': expected ${o}, got ${n}`)}});function $(t,r){L(t);const o={...b,...t};o.base=function(e){if(!e)return e;let t=e;return t.startsWith("/")||(t=`/${t}`),t.endsWith("/")&&(t=t.slice(0,-1)),t}(o.base);const n=(d=o.hashPrefix)?new RegExp(`^#${m=d,m.replaceAll(/[$()*+.?[\\\]^{|}-]/g,String.raw`\$&`)}`):null,a=r??function(e,t){if(void 0!==globalThis.window&&globalThis.history)return{pushState:i,replaceState:c,addPopstateListener:l,getLocation:e,getHash:u};const r=h(t);return{...f(t),getLocation:()=>(r("getLocation"),"")}}(()=>(e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path "${e}"`,t),e}})(w(globalThis.location.hash,n))+globalThis.location.search,"hash-plugin"),s={forceDeactivate:o.forceDeactivate,source:"popstate",replace:!0},p={removePopStateListener:void 0};var d,m;return function(t){return new P(t,e(t),o,a,n,s,p).getPlugin()}}export{$ as hashPluginFactory,s as isState};//# sourceMappingURL=index.mjs.map
1
+ import{getPluginApi as e}from"@real-router/core/api";import{RouterError as t}from"@real-router/core";const n=/^[A-Z_a-z][\w-]*(?:\.[A-Z_a-z][\w-]*)*$/;function r(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:n.test(e):!1}function i(e,t=new WeakSet){if(e==null)return!0;let n=typeof e;if(n===`string`||n===`boolean`)return!0;if(n===`number`)return Number.isFinite(e);if(n===`function`||n===`symbol`)return!1;if(Array.isArray(e))return t.has(e)?!1:(t.add(e),e.every(e=>i(e,t)));if(n===`object`){if(t.has(e))return!1;t.add(e);let n=Object.getPrototypeOf(e);return n!==null&&n!==Object.prototype?!1:Object.values(e).every(e=>i(e,t))}return!1}function a(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}function o(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let r=e[t];if(!a(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return n?i(e):!0}function s(e){return r(e.name)&&typeof e.path==`string`&&o(e.params)}function c(e){return!(typeof e!=`object`||!e||!s(e))}const l=()=>globalThis.window!==void 0&&!!globalThis.history,u=(e,t)=>{globalThis.history.pushState(e,``,t)},d=(e,t)=>{globalThis.history.replaceState(e,``,t)},f=e=>(globalThis.addEventListener(`popstate`,e),()=>{globalThis.removeEventListener(`popstate`,e)}),p=()=>globalThis.location.hash;function m(e){if(!e)return e;let t=e;return t.startsWith(`/`)||(t=`/${t}`),t.endsWith(`/`)&&(t=t.slice(0,-1)),t}const h=e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path "${e}"`,t),e}},g=()=>{},_=e=>{let t=!1;return n=>{t||=(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: "${e}"). Method "${n}" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),!0)}},v=e=>{let t=_(e);return{pushState:()=>{t(`pushState`)},replaceState:()=>{t(`replaceState`)},addPopstateListener:()=>(t(`addPopstateListener`),g),getHash:()=>(t(`getHash`),``)}};function y(e,t,n){if(c(e.state))return{name:e.state.name,params:e.state.params};let r=t.matchPath(n.getLocation());return r?{name:r.name,params:r.params}:void 0}function b(e,t,n,r){let i={name:e.name,params:e.params,path:e.path};n?r.replaceState(i,t):r.pushState(i,t)}function x(e,t){return n=>{if(n){for(let r of Object.keys(n))if(r in e){let i=n[r],a=typeof e[r],o=typeof i;if(i!==void 0&&o!==a)throw Error(`[${t}] Invalid type for '${r}': expected ${a}, got ${o}`)}}}}function S(e,t){if(l())return{pushState:u,replaceState:d,addPopstateListener:f,getLocation:e,getHash:p};let n=_(t);return{...v(t),getLocation:()=>(n(`getLocation`),``)}}function C(e){let n=!1,r=null;function i(){if(r){let t=r;r=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),o(t)}}function a(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{let t=e.router.getState();if(t){let n=e.buildUrl(t.name,t.params);e.browser.replaceState(t,n)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}async function o(o){if(n){console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),r=o;return}n=!0;try{let t=y(o,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(e){e instanceof t||a(e)}finally{n=!1,i()}}return e=>void o(e)}function w(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}function T(e,t){return e.addInterceptor(`start`,(e,n)=>e(n??t.getLocation()))}function E(e,t,n,r){return(i,a={})=>{let o=e.buildState(i,a);if(!o)throw Error(`[real-router] Cannot replace state: route "${i}" is not found`);b(e.makeState(o.name,o.params,t.buildPath(o.name,o.params),{params:o.meta}),r(i,a),!0,n)}}function D(e,t,n){return(e.replace??!n)||!!e.reload&&t.path===n.path}function O(e,t){try{let n=new URL(e,globalThis.location.origin);return[`http:`,`https:`].includes(n.protocol)?n:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(n){return console.warn(`[${t}] Could not parse url ${e}`,n),null}}const k={hashPrefix:``,base:``,forceDeactivate:!0},A=`hash-plugin`;function j(e){return e.replaceAll(/[$()*+.?[\\\]^{|}-]/g,String.raw`\$&`)}function M(e){return e?RegExp(`^#${j(e)}`):null}function N(e,t){return(t?e.replace(t,``):e.slice(1))||`/`}function P(e,t){let n=O(e,A);return n?N(n.hash,t)+n.search:null}var F=class{#e;#t;#n;#r;#i;constructor(e,t,n,r,i,a,o){this.#e=e,this.#t=r,this.#n=T(t,r);let s=`${n.base}#${n.hashPrefix}`,c=(t,n)=>s+e.buildPath(t,n);this.#r=t.extendRouter({buildUrl:c,matchUrl:e=>{let n=P(e,i);return n?t.matchPath(n):void 0},replaceHistoryState:E(t,e,r,c)}),this.#i=w({browser:r,shared:o,handler:C({router:e,api:t,browser:r,allowNotFound:t.getOptions().allowNotFound,transitionOptions:a,loggerContext:`hash-plugin`,buildUrl:(t,n)=>e.buildUrl(t,n)}),cleanup:()=>{this.#n(),this.#r()}})}getPlugin(){return{...this.#i,onTransitionSuccess:(e,t,n)=>{let r=D(n,e,t);b(e,this.#e.buildUrl(e.name,e.params),r,this.#t)}}}};const I=x(k,A);function L(t,n){I(t);let r={...k,...t};r.base=m(r.base);let i=M(r.hashPrefix),a=n??S(()=>h(N(globalThis.location.hash,i))+globalThis.location.search,`hash-plugin`),o={forceDeactivate:r.forceDeactivate,source:`popstate`,replace:!0},s={removePopStateListener:void 0};return function(t){return new F(t,e(t),r,a,i,o,s).getPlugin()}}export{L as hashPluginFactory,c as isState};
2
+ //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"names":["i"],"mappings":"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","file":"index.mjs","sourcesContent":["// packages/hash-plugin/src/constants.ts\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const defaultOptions: Required<HashPluginOptions> = {\n hashPrefix: \"\",\n base: \"\",\n forceDeactivate: true,\n};\n\n/**\n * Source identifier for transitions triggered by browser events.\n */\nexport const source = \"popstate\";\n\nexport const LOGGER_CONTEXT = \"hash-plugin\";\n","// packages/hash-plugin/src/hash-utils.ts\n\nimport { safeParseUrl } from \"browser-env\";\n\nimport { LOGGER_CONTEXT } from \"./constants\";\n\nfunction escapeRegExp(str: string): string {\n return str.replaceAll(/[$()*+.?[\\\\\\]^{|}-]/g, String.raw`\\$&`);\n}\n\nexport function createHashPrefixRegex(hashPrefix: string): RegExp | null {\n if (!hashPrefix) {\n return null;\n }\n\n return new RegExp(`^#${escapeRegExp(hashPrefix)}`);\n}\n\n/**\n * Extract path from URL hash, stripping hash prefix.\n *\n * @param hash - URL hash (e.g., \"#/path\" or \"#!/path\")\n * @param prefixRegex - Pre-compiled regex for prefix stripping (null if no prefix)\n * @returns Extracted path (e.g., \"/path\")\n */\nexport function extractHashPath(\n hash: string,\n prefixRegex: RegExp | null,\n): string {\n const path = prefixRegex ? hash.replace(prefixRegex, \"\") : hash.slice(1);\n\n return path || \"/\";\n}\n\nexport function hashUrlToPath(\n url: string,\n prefixRegex: RegExp | null,\n): string | null {\n const parsedUrl = safeParseUrl(url, LOGGER_CONTEXT);\n\n return parsedUrl\n ? extractHashPath(parsedUrl.hash, prefixRegex) + parsedUrl.search\n : null;\n}\n","import {\n createPopstateHandler,\n createPopstateLifecycle,\n createStartInterceptor,\n createReplaceHistoryState,\n shouldReplaceHistory,\n updateBrowserState,\n} from \"browser-env\";\n\nimport { hashUrlToPath } from \"./hash-utils\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type {\n NavigationOptions,\n Params,\n Router,\n State,\n Plugin,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport class HashPlugin {\n readonly #router: Router;\n readonly #browser: Browser;\n readonly #removeStartInterceptor: () => void;\n readonly #removeExtensions: () => void;\n readonly #lifecycle: Pick<Plugin, \"onStart\" | \"onStop\" | \"teardown\">;\n\n constructor(\n router: Router,\n api: PluginApi,\n options: Required<HashPluginOptions>,\n browser: Browser,\n prefixRegex: RegExp | null,\n transitionOptions: {\n source: string;\n replace: true;\n forceDeactivate?: boolean;\n },\n shared: SharedFactoryState,\n ) {\n this.#router = router;\n this.#browser = browser;\n\n this.#removeStartInterceptor = createStartInterceptor(api, browser);\n\n const urlPrefix = `${options.base}#${options.hashPrefix}`;\n const pluginBuildUrl = (route: string, params?: Params) =>\n urlPrefix + router.buildPath(route, params);\n\n this.#removeExtensions = api.extendRouter({\n buildUrl: pluginBuildUrl,\n matchUrl: (url: string) => {\n const path = hashUrlToPath(url, prefixRegex);\n\n return path ? api.matchPath(path) : undefined;\n },\n replaceHistoryState: createReplaceHistoryState(\n api,\n router,\n browser,\n pluginBuildUrl,\n ),\n });\n\n const handler = createPopstateHandler({\n router,\n api,\n browser,\n allowNotFound: api.getOptions().allowNotFound,\n transitionOptions,\n loggerContext: \"hash-plugin\",\n buildUrl: (name: string, params?: Params) =>\n router.buildUrl(name, params),\n });\n\n this.#lifecycle = createPopstateLifecycle({\n browser,\n shared,\n handler,\n cleanup: () => {\n this.#removeStartInterceptor();\n this.#removeExtensions();\n },\n });\n }\n\n getPlugin(): Plugin {\n return {\n ...this.#lifecycle,\n\n onTransitionSuccess: (\n toState: State,\n fromState: State | undefined,\n navOptions: NavigationOptions,\n ) => {\n const replaceHistory = shouldReplaceHistory(\n navOptions,\n toState,\n fromState,\n );\n\n const url = this.#router.buildUrl(toState.name, toState.params);\n\n updateBrowserState(toState, url, replaceHistory, this.#browser);\n },\n };\n }\n}\n","import { createOptionsValidator } from \"browser-env\";\n\nimport { LOGGER_CONTEXT, defaultOptions } from \"./constants\";\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const validateOptions = createOptionsValidator<HashPluginOptions>(\n defaultOptions,\n LOGGER_CONTEXT,\n);\n","import { getPluginApi } from \"@real-router/core/api\";\nimport {\n createSafeBrowser,\n normalizeBase,\n safelyEncodePath,\n} from \"browser-env\";\n\nimport { defaultOptions, source } from \"./constants\";\nimport { createHashPrefixRegex, extractHashPath } from \"./hash-utils\";\nimport { HashPlugin } from \"./plugin\";\nimport { validateOptions } from \"./validation\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type { PluginFactory, Router } from \"@real-router/core\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport function hashPluginFactory(\n opts?: Partial<HashPluginOptions>,\n browser?: Browser,\n): PluginFactory {\n validateOptions(opts);\n\n const options: Required<HashPluginOptions> = { ...defaultOptions, ...opts };\n\n options.base = normalizeBase(options.base);\n\n const prefixRegex = createHashPrefixRegex(options.hashPrefix);\n const resolvedBrowser =\n browser ??\n createSafeBrowser(\n () =>\n safelyEncodePath(\n extractHashPath(globalThis.location.hash, prefixRegex),\n ) + globalThis.location.search,\n \"hash-plugin\",\n );\n\n const transitionOptions = {\n forceDeactivate: options.forceDeactivate,\n source,\n replace: true as const,\n };\n\n const shared: SharedFactoryState = { removePopStateListener: undefined };\n\n return function hashPlugin(routerBase) {\n const plugin = new HashPlugin(\n routerBase as Router,\n getPluginApi(routerBase),\n options,\n resolvedBrowser,\n prefixRegex,\n transitionOptions,\n shared,\n );\n\n return plugin.getPlugin();\n };\n}\n"]}
1
+ {"version":3,"file":"index.mjs","names":["n","r","a","o","s","c","d","e","p","t","safeParseUrl","#router","#browser","#removeStartInterceptor","#removeExtensions","#lifecycle","createStartInterceptor","createReplaceHistoryState","createPopstateLifecycle","createPopstateHandler","shouldReplaceHistory","createOptionsValidator","normalizeBase","createSafeBrowser","safelyEncodePath"],"sources":["../../../type-guards/dist/esm/index.mjs","../../../browser-env/dist/esm/index.mjs","../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const e=[`replace`,`reload`,`force`,`forceDeactivate`,`redirected`];function t(t){if(typeof t!=`object`||!t||Array.isArray(t))return!1;let n=t;for(let t of e){let e=n[t];if(e!==void 0&&typeof e!=`boolean`)return!1}let r=n.signal;return!(r!==void 0&&!(r instanceof AbortSignal))}const n=/\\S/,r=/^[A-Z_a-z][\\w-]*(?:\\.[A-Z_a-z][\\w-]*)*$/;function i(e,t){return TypeError(`[router.${e}] ${t}`)}function a(e){return typeof e==`string`?e===``?!0:e.length>1e4?!1:e.startsWith(`@@`)?!0:r.test(e):!1}function o(e,t=new WeakSet){if(e==null)return!0;let n=typeof e;if(n===`string`||n===`boolean`)return!0;if(n===`number`)return Number.isFinite(e);if(n===`function`||n===`symbol`)return!1;if(Array.isArray(e))return t.has(e)?!1:(t.add(e),e.every(e=>o(e,t)));if(n===`object`){if(t.has(e))return!1;t.add(e);let n=Object.getPrototypeOf(e);return n!==null&&n!==Object.prototype?!1:Object.values(e).every(e=>o(e,t))}return!1}function s(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}function c(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);if(t!==null&&t!==Object.prototype)return!1;let n=!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let r=e[t];if(!s(r)){let e=typeof r;if(e===`function`||e===`symbol`)return!1;n=!0;break}}return n?o(e):!0}function l(e){if(e==null)return!0;let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):Array.isArray(e)?e.every(e=>{let t=typeof e;return t===`string`||t===`boolean`?!0:t===`number`?Number.isFinite(e):!1}):!1}function u(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;for(let t in e){if(!Object.hasOwn(e,t))continue;let n=e[t];if(!l(n))return!1}return!0}function d(e){return a(e.name)&&typeof e.path==`string`&&c(e.params)}function f(e){return typeof e!=`object`||!e?!1:d(e)}function p(e){return!(typeof e!=`object`||!e||!d(e))}function m(e){return typeof e==`string`}function h(e){return typeof e==`boolean`}function g(e,t){return e in t}function _(e){return typeof e==`number`?Number.isFinite(e):typeof e==`string`||typeof e==`boolean`}function v(e,t){if(typeof e!=`string`)throw i(t,`Route name must be a string, got ${typeof e}`);if(e!==``){if(!n.test(e))throw i(t,`Route name cannot contain only whitespace`);if(e.length>1e4)throw i(t,`Route name exceeds maximum length of 10000 characters. This is a technical safety limit.`);if(!e.startsWith(`@@`)&&!r.test(e))throw i(t,`Invalid route name \"${e}\". Each segment must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens. Segments are separated by dots (e.g., \"users.profile\").`)}}function y(e){return e===null?`null`:Array.isArray(e)?`array[${e.length}]`:typeof e==`object`?`constructor`in e&&e.constructor.name!==`Object`?e.constructor.name:`object`:typeof e}function b(e,t){if(!f(e))throw TypeError(`[${t}] Invalid state structure: ${y(e)}. Expected State object with name, params, and path properties.`)}export{y as getTypeDescription,h as isBoolean,t as isNavigationOptions,g as isObjKey,c as isParams,u as isParamsStrict,_ as isPrimitiveValue,a as isRouteName,f as isState,p as isStateStrict,m as isString,v as validateRouteName,b as validateState};\n//# sourceMappingURL=index.mjs.map","import{isStateStrict as e}from\"type-guards\";import{RouterError as t}from\"@real-router/core\";const n=()=>globalThis.window!==void 0&&!!globalThis.history,r=(e,t)=>{globalThis.history.pushState(e,``,t)},i=(e,t)=>{globalThis.history.replaceState(e,``,t)},a=e=>(globalThis.addEventListener(`popstate`,e),()=>{globalThis.removeEventListener(`popstate`,e)}),o=()=>globalThis.location.hash;function s(e){if(!e)return e;let t=e;return t.startsWith(`/`)||(t=`/${t}`),t.endsWith(`/`)&&(t=t.slice(0,-1)),t}const c=e=>{try{return encodeURI(decodeURI(e))}catch(t){return console.warn(`[browser-env] Could not encode path \"${e}\"`,t),e}},l=()=>{},u=e=>{let t=!1;return n=>{t||=(console.warn(`[browser-env] Browser API is running in a non-browser environment (context: \"${e}\"). Method \"${n}\" is a no-op. This is expected for SSR, but may indicate misconfiguration if you expected browser behavior.`),!0)}},d=e=>{let t=u(e);return{pushState:()=>{t(`pushState`)},replaceState:()=>{t(`replaceState`)},addPopstateListener:()=>(t(`addPopstateListener`),l),getHash:()=>(t(`getHash`),``)}};function f(t,n,r){if(e(t.state))return{name:t.state.name,params:t.state.params};let i=n.matchPath(r.getLocation());return i?{name:i.name,params:i.params}:void 0}function p(e,t,n,r){let i={name:e.name,params:e.params,path:e.path};n?r.replaceState(i,t):r.pushState(i,t)}function m(e,t){return n=>{if(n){for(let r of Object.keys(n))if(r in e){let i=n[r],a=typeof e[r],o=typeof i;if(i!==void 0&&o!==a)throw Error(`[${t}] Invalid type for '${r}': expected ${a}, got ${o}`)}}}}function h(e,t){if(n())return{pushState:r,replaceState:i,addPopstateListener:a,getLocation:e,getHash:o};let s=u(t);return{...d(t),getLocation:()=>(s(`getLocation`),``)}}function g(e){let n=!1,r=null;function i(){if(r){let t=r;r=null,console.warn(`[${e.loggerContext}] Processing deferred popstate event`),o(t)}}function a(t){console.error(`[${e.loggerContext}] Critical error in onPopState`,t);try{let t=e.router.getState();if(t){let n=e.buildUrl(t.name,t.params);e.browser.replaceState(t,n)}}catch(t){console.error(`[${e.loggerContext}] Failed to recover from critical error`,t)}}async function o(o){if(n){console.warn(`[${e.loggerContext}] Transition in progress, deferring popstate event`),r=o;return}n=!0;try{let t=f(o,e.api,e.browser);t?await e.router.navigate(t.name,t.params,e.transitionOptions):e.allowNotFound?e.router.navigateToNotFound(e.browser.getLocation()):await e.router.navigateToDefault({...e.transitionOptions,reload:!0,replace:!0})}catch(e){e instanceof t||a(e)}finally{n=!1,i()}}return e=>void o(e)}function _(e){return{onStart:()=>{e.shared.removePopStateListener&&e.shared.removePopStateListener(),e.shared.removePopStateListener=e.browser.addPopstateListener(e.handler)},onStop:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0)},teardown:()=>{e.shared.removePopStateListener&&(e.shared.removePopStateListener(),e.shared.removePopStateListener=void 0),e.cleanup()}}}function v(e,t){return e.addInterceptor(`start`,(e,n)=>e(n??t.getLocation()))}function y(e,t,n,r){return(i,a={})=>{let o=e.buildState(i,a);if(!o)throw Error(`[real-router] Cannot replace state: route \"${i}\" is not found`);p(e.makeState(o.name,o.params,t.buildPath(o.name,o.params),{params:o.meta}),r(i,a),!0,n)}}function b(e,t,n){return(e.replace??!n)||!!e.reload&&t.path===n.path}function x(e,t){try{let n=new URL(e,globalThis.location.origin);return[`http:`,`https:`].includes(n.protocol)?n:(console.warn(`[${t}] Invalid URL protocol in ${e}`),null)}catch(n){return console.warn(`[${t}] Could not parse url ${e}`,n),null}}export{a as addPopstateListener,d as createHistoryFallbackBrowser,m as createOptionsValidator,g as createPopstateHandler,_ as createPopstateLifecycle,y as createReplaceHistoryState,h as createSafeBrowser,v as createStartInterceptor,u as createWarnOnce,o as getHash,f as getRouteFromEvent,n as isBrowserEnvironment,s as normalizeBase,r as pushState,i as replaceState,x as safeParseUrl,c as safelyEncodePath,b as shouldReplaceHistory,p as updateBrowserState};\n//# sourceMappingURL=index.mjs.map","// packages/hash-plugin/src/constants.ts\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const defaultOptions: Required<HashPluginOptions> = {\n hashPrefix: \"\",\n base: \"\",\n forceDeactivate: true,\n};\n\n/**\n * Source identifier for transitions triggered by browser events.\n */\nexport const source = \"popstate\";\n\nexport const LOGGER_CONTEXT = \"hash-plugin\";\n","// packages/hash-plugin/src/hash-utils.ts\n\nimport { safeParseUrl } from \"browser-env\";\n\nimport { LOGGER_CONTEXT } from \"./constants\";\n\nfunction escapeRegExp(str: string): string {\n return str.replaceAll(/[$()*+.?[\\\\\\]^{|}-]/g, String.raw`\\$&`);\n}\n\nexport function createHashPrefixRegex(hashPrefix: string): RegExp | null {\n if (!hashPrefix) {\n return null;\n }\n\n return new RegExp(`^#${escapeRegExp(hashPrefix)}`);\n}\n\n/**\n * Extract path from URL hash, stripping hash prefix.\n *\n * @param hash - URL hash (e.g., \"#/path\" or \"#!/path\")\n * @param prefixRegex - Pre-compiled regex for prefix stripping (null if no prefix)\n * @returns Extracted path (e.g., \"/path\")\n */\nexport function extractHashPath(\n hash: string,\n prefixRegex: RegExp | null,\n): string {\n const path = prefixRegex ? hash.replace(prefixRegex, \"\") : hash.slice(1);\n\n return path || \"/\";\n}\n\nexport function hashUrlToPath(\n url: string,\n prefixRegex: RegExp | null,\n): string | null {\n const parsedUrl = safeParseUrl(url, LOGGER_CONTEXT);\n\n return parsedUrl\n ? extractHashPath(parsedUrl.hash, prefixRegex) + parsedUrl.search\n : null;\n}\n","import {\n createPopstateHandler,\n createPopstateLifecycle,\n createStartInterceptor,\n createReplaceHistoryState,\n shouldReplaceHistory,\n updateBrowserState,\n} from \"browser-env\";\n\nimport { hashUrlToPath } from \"./hash-utils\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type {\n NavigationOptions,\n Params,\n Router,\n State,\n Plugin,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport class HashPlugin {\n readonly #router: Router;\n readonly #browser: Browser;\n readonly #removeStartInterceptor: () => void;\n readonly #removeExtensions: () => void;\n readonly #lifecycle: Pick<Plugin, \"onStart\" | \"onStop\" | \"teardown\">;\n\n constructor(\n router: Router,\n api: PluginApi,\n options: Required<HashPluginOptions>,\n browser: Browser,\n prefixRegex: RegExp | null,\n transitionOptions: {\n source: string;\n replace: true;\n forceDeactivate?: boolean;\n },\n shared: SharedFactoryState,\n ) {\n this.#router = router;\n this.#browser = browser;\n\n this.#removeStartInterceptor = createStartInterceptor(api, browser);\n\n const urlPrefix = `${options.base}#${options.hashPrefix}`;\n const pluginBuildUrl = (route: string, params?: Params) =>\n urlPrefix + router.buildPath(route, params);\n\n this.#removeExtensions = api.extendRouter({\n buildUrl: pluginBuildUrl,\n matchUrl: (url: string) => {\n const path = hashUrlToPath(url, prefixRegex);\n\n return path ? api.matchPath(path) : undefined;\n },\n replaceHistoryState: createReplaceHistoryState(\n api,\n router,\n browser,\n pluginBuildUrl,\n ),\n });\n\n const handler = createPopstateHandler({\n router,\n api,\n browser,\n allowNotFound: api.getOptions().allowNotFound,\n transitionOptions,\n loggerContext: \"hash-plugin\",\n buildUrl: (name: string, params?: Params) =>\n router.buildUrl(name, params),\n });\n\n this.#lifecycle = createPopstateLifecycle({\n browser,\n shared,\n handler,\n cleanup: () => {\n this.#removeStartInterceptor();\n this.#removeExtensions();\n },\n });\n }\n\n getPlugin(): Plugin {\n return {\n ...this.#lifecycle,\n\n onTransitionSuccess: (\n toState: State,\n fromState: State | undefined,\n navOptions: NavigationOptions,\n ) => {\n const replaceHistory = shouldReplaceHistory(\n navOptions,\n toState,\n fromState,\n );\n\n const url = this.#router.buildUrl(toState.name, toState.params);\n\n updateBrowserState(toState, url, replaceHistory, this.#browser);\n },\n };\n }\n}\n","import { createOptionsValidator } from \"browser-env\";\n\nimport { LOGGER_CONTEXT, defaultOptions } from \"./constants\";\n\nimport type { HashPluginOptions } from \"./types\";\n\nexport const validateOptions = createOptionsValidator<HashPluginOptions>(\n defaultOptions,\n LOGGER_CONTEXT,\n);\n","import { getPluginApi } from \"@real-router/core/api\";\nimport {\n createSafeBrowser,\n normalizeBase,\n safelyEncodePath,\n} from \"browser-env\";\n\nimport { defaultOptions, source } from \"./constants\";\nimport { createHashPrefixRegex, extractHashPath } from \"./hash-utils\";\nimport { HashPlugin } from \"./plugin\";\nimport { validateOptions } from \"./validation\";\n\nimport type { HashPluginOptions } from \"./types\";\nimport type { PluginFactory, Router } from \"@real-router/core\";\nimport type { Browser, SharedFactoryState } from \"browser-env\";\n\nexport function hashPluginFactory(\n opts?: Partial<HashPluginOptions>,\n browser?: Browser,\n): PluginFactory {\n validateOptions(opts);\n\n const options: Required<HashPluginOptions> = { ...defaultOptions, ...opts };\n\n options.base = normalizeBase(options.base);\n\n const prefixRegex = createHashPrefixRegex(options.hashPrefix);\n const resolvedBrowser =\n browser ??\n createSafeBrowser(\n () =>\n safelyEncodePath(\n extractHashPath(globalThis.location.hash, prefixRegex),\n ) + globalThis.location.search,\n \"hash-plugin\",\n );\n\n const transitionOptions = {\n forceDeactivate: options.forceDeactivate,\n source,\n replace: true as const,\n };\n\n const shared: SharedFactoryState = { removePopStateListener: undefined };\n\n return function hashPlugin(routerBase) {\n const plugin = new HashPlugin(\n routerBase as Router,\n getPluginApi(routerBase),\n options,\n resolvedBrowser,\n prefixRegex,\n transitionOptions,\n shared,\n );\n\n return plugin.getPlugin();\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-router/hash-plugin",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "type": "commonjs",
5
5
  "description": "Hash-based routing plugin for Real-Router",
6
6
  "main": "./dist/cjs/index.js",
@@ -43,22 +43,22 @@
43
43
  },
44
44
  "sideEffects": false,
45
45
  "dependencies": {
46
- "@real-router/core": "^0.41.0"
46
+ "@real-router/core": "^0.43.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@testing-library/jest-dom": "6.9.1",
50
50
  "jsdom": "28.1.0",
51
- "browser-env": "^0.2.1",
52
- "type-guards": "^0.4.1"
51
+ "browser-env": "^0.2.3",
52
+ "type-guards": "^0.4.3"
53
53
  },
54
54
  "scripts": {
55
55
  "test": "vitest",
56
56
  "test:properties": "vitest run --config vitest.config.properties.mts",
57
- "build": "tsup",
57
+ "build": "tsdown --config-loader unrun",
58
58
  "type-check": "tsc --noEmit",
59
59
  "lint": "eslint --cache --ext .ts src/ tests/ --fix --max-warnings 0",
60
60
  "lint:package": "publint",
61
61
  "lint:types": "attw --pack .",
62
- "build:dist-only": "tsup"
62
+ "build:dist-only": "tsdown --config-loader unrun"
63
63
  }
64
64
  }
@@ -1 +0,0 @@
1
- {"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"../type-guards/dist/esm/index.mjs":{"bytes":3269,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"../browser-env/dist/esm/index.mjs":{"bytes":4128,"imports":[{"path":"../type-guards/dist/esm/index.mjs","kind":"import-statement","original":"type-guards"},{"path":"@real-router/core","kind":"import-statement","external":true},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/constants.ts":{"bytes":367,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/hash-utils.ts":{"bytes":1119,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/plugin.ts":{"bytes":2745,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/hash-utils.ts","kind":"import-statement","original":"./hash-utils"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/validation.ts":{"bytes":282,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/factory.ts":{"bytes":1582,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"src/hash-utils.ts","kind":"import-statement","original":"./hash-utils"},{"path":"src/plugin.ts","kind":"import-statement","original":"./plugin"},{"path":"src/validation.ts","kind":"import-statement","original":"./validation"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":1283,"imports":[{"path":"src/factory.ts","kind":"import-statement","original":"./factory"},{"path":"../type-guards/dist/esm/index.mjs","kind":"import-statement","original":"type-guards"},{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/cjs/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":9072},"dist/cjs/index.js":{"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true}],"exports":["hashPluginFactory","isState"],"entryPoint":"src/index.ts","inputs":{"src/factory.ts":{"bytesInOutput":878},"../type-guards/dist/esm/index.mjs":{"bytesInOutput":1569},"../browser-env/dist/esm/index.mjs":{"bytesInOutput":4725},"src/constants.ts":{"bytesInOutput":141},"src/hash-utils.ts":{"bytesInOutput":568},"src/plugin.ts":{"bytesInOutput":1610},"src/validation.ts":{"bytesInOutput":63},"src/index.ts":{"bytesInOutput":0}},"bytes":9798}}}
@@ -1 +0,0 @@
1
- {"inputs":{"../type-guards/dist/esm/index.mjs":{"bytes":3269,"imports":[],"format":"esm"},"../browser-env/dist/esm/index.mjs":{"bytes":4128,"imports":[{"path":"../type-guards/dist/esm/index.mjs","kind":"import-statement","original":"type-guards"},{"path":"@real-router/core","kind":"import-statement","external":true}],"format":"esm"},"src/constants.ts":{"bytes":367,"imports":[],"format":"esm"},"src/hash-utils.ts":{"bytes":1119,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"}],"format":"esm"},"src/plugin.ts":{"bytes":2745,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/hash-utils.ts","kind":"import-statement","original":"./hash-utils"}],"format":"esm"},"src/validation.ts":{"bytes":282,"imports":[{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"}],"format":"esm"},"src/factory.ts":{"bytes":1582,"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"../browser-env/dist/esm/index.mjs","kind":"import-statement","original":"browser-env"},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"src/hash-utils.ts","kind":"import-statement","original":"./hash-utils"},{"path":"src/plugin.ts","kind":"import-statement","original":"./plugin"},{"path":"src/validation.ts","kind":"import-statement","original":"./validation"}],"format":"esm"},"src/index.ts":{"bytes":1283,"imports":[{"path":"src/factory.ts","kind":"import-statement","original":"./factory"},{"path":"../type-guards/dist/esm/index.mjs","kind":"import-statement","original":"type-guards"}],"format":"esm"}},"outputs":{"dist/esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9072},"dist/esm/index.mjs":{"imports":[{"path":"@real-router/core/api","kind":"import-statement","external":true},{"path":"@real-router/core","kind":"import-statement","external":true}],"exports":["hashPluginFactory","isState"],"entryPoint":"src/index.ts","inputs":{"src/factory.ts":{"bytesInOutput":878},"../type-guards/dist/esm/index.mjs":{"bytesInOutput":1569},"../browser-env/dist/esm/index.mjs":{"bytesInOutput":4725},"src/constants.ts":{"bytesInOutput":141},"src/hash-utils.ts":{"bytesInOutput":568},"src/plugin.ts":{"bytesInOutput":1610},"src/validation.ts":{"bytesInOutput":63},"src/index.ts":{"bytesInOutput":0}},"bytes":9798}}}