@real-router/hash-plugin 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +92 -74
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.mts +92 -73
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +6 -6
- package/dist/cjs/metafile-cjs.json +0 -1
- package/dist/esm/metafile-esm.json +0 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,72 +1,81 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
interface State<P extends Params = Params, MP extends Params = Params> {
|
|
56
|
-
name: string;
|
|
57
|
-
params: P;
|
|
58
|
-
path: string;
|
|
59
|
-
meta?: StateMeta<MP> | undefined;
|
|
60
|
-
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
|
+
};
|
|
61
62
|
}
|
|
62
|
-
interface
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
interface State$1<P extends Params$1 = Params$1> {
|
|
64
|
+
name: string;
|
|
65
|
+
params: P;
|
|
66
|
+
path: string;
|
|
67
|
+
transition?: TransitionMeta | undefined;
|
|
65
68
|
}
|
|
66
|
-
interface Params {
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
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
|
|
70
79
|
/**
|
|
71
80
|
* Enhanced type guard for State with deep validation.
|
|
72
81
|
* Checks not only presence but also types of all required fields.
|
|
@@ -79,31 +88,40 @@ interface Params {
|
|
|
79
88
|
* isStateStrict({ name: 'home', params: {}, path: '/', meta: { id: 1 } }); // true
|
|
80
89
|
* isStateStrict({ name: 'home', params: 'invalid', path: '/' }); // false
|
|
81
90
|
*/
|
|
82
|
-
declare function isStateStrict<P extends Params = Params
|
|
83
|
-
|
|
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
|
|
84
101
|
/**
|
|
85
102
|
* Module augmentation for real-router.
|
|
86
103
|
* Extends Router interface with hash plugin methods.
|
|
87
104
|
*/
|
|
88
105
|
declare module "@real-router/core" {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
+
}
|
|
107
124
|
}
|
|
108
|
-
|
|
125
|
+
//#endregion
|
|
109
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
|
-
|
|
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
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"names":["i","f","c","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":"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"}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,72 +1,82 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
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;
|
|
61
69
|
}
|
|
62
|
-
interface
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
70
80
|
/**
|
|
71
81
|
* Enhanced type guard for State with deep validation.
|
|
72
82
|
* Checks not only presence but also types of all required fields.
|
|
@@ -79,31 +89,40 @@ interface Params {
|
|
|
79
89
|
* isStateStrict({ name: 'home', params: {}, path: '/', meta: { id: 1 } }); // true
|
|
80
90
|
* isStateStrict({ name: 'home', params: 'invalid', path: '/' }); // false
|
|
81
91
|
*/
|
|
82
|
-
declare function isStateStrict<P extends Params = Params
|
|
83
|
-
|
|
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
|
|
84
102
|
/**
|
|
85
103
|
* Module augmentation for real-router.
|
|
86
104
|
* Extends Router interface with hash plugin methods.
|
|
87
105
|
*/
|
|
88
106
|
declare module "@real-router/core" {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
+
}
|
|
107
125
|
}
|
|
108
|
-
|
|
126
|
+
//#endregion
|
|
109
127
|
export { type Browser, type HashPluginOptions, hashPluginFactory, isStateStrict as isState };
|
|
128
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{getPluginApi as e}from"@real-router/core/api";import{RouterError as t}from"@real-router/core";
|
|
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
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/constants.ts","../../src/hash-utils.ts","../../src/plugin.ts","../../src/validation.ts","../../src/factory.ts"],"names":["i","f","c"],"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.
|
|
3
|
+
"version": "0.2.8",
|
|
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.
|
|
46
|
+
"@real-router/core": "^0.42.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.
|
|
52
|
-
"type-guards": "^0.
|
|
51
|
+
"browser-env": "^0.2.2",
|
|
52
|
+
"type-guards": "^0.4.2"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"test": "vitest",
|
|
56
56
|
"test:properties": "vitest run --config vitest.config.properties.mts",
|
|
57
|
-
"build": "
|
|
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": "
|
|
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@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"../type-guards/dist/esm/index.mjs":{"bytes":3451,"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@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"../browser-env/dist/esm/index.mjs":{"bytes":4142,"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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/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@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/cjs/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":9103},"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":880},"../type-guards/dist/esm/index.mjs":{"bytesInOutput":2337},"../browser-env/dist/esm/index.mjs":{"bytesInOutput":4744},"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":10587}}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"inputs":{"../type-guards/dist/esm/index.mjs":{"bytes":3451,"imports":[],"format":"esm"},"../browser-env/dist/esm/index.mjs":{"bytes":4142,"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":9103},"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":880},"../type-guards/dist/esm/index.mjs":{"bytesInOutput":2337},"../browser-env/dist/esm/index.mjs":{"bytesInOutput":4744},"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":10587}}}
|