@sigx/router 0.1.9 → 0.1.11

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 +1 @@
1
- {"version":3,"file":"RouterView.d.ts","sourceRoot":"","sources":["../src/RouterView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAmC,MAAM,MAAM,CAAC;AAG1G,KAAK,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAerG,eAAO,MAAM,UAAU,6CAuDG,CAAC"}
1
+ {"version":3,"file":"RouterView.d.ts","sourceRoot":"","sources":["../src/RouterView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAmC,MAAM,MAAM,CAAC;AAG1G,KAAK,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAerG,eAAO,MAAM,UAAU,6CAyDG,CAAC"}
package/dist/index.js CHANGED
@@ -191,6 +191,7 @@ function createRouter(options) {
191
191
  const initialLocation = history.location;
192
192
  const initialMatch = matchRoute(initialLocation, compiledRoutes);
193
193
  const currentRouteState = signal(createRouteLocation(initialLocation, initialMatch?.route || null, initialMatch?.params || {}));
194
+ let isNavigating = false;
194
195
  function resolve(to) {
195
196
  if (typeof to === "string") {
196
197
  const match = matchRoute(to, compiledRoutes);
@@ -267,12 +268,15 @@ function createRouter(options) {
267
268
  const resolveResult = await runGuards(resolved, from, beforeResolveGuards);
268
269
  if (resolveResult === false) return;
269
270
  if (resolveResult && typeof resolveResult === "object") return navigate(resolveResult, replace);
271
+ isNavigating = true;
272
+ finalizeNavigation(resolved, from);
270
273
  if (replace) history.replace(resolved.fullPath);
271
274
  else history.push(resolved.fullPath);
272
- finalizeNavigation(resolved, from);
275
+ isNavigating = false;
273
276
  return resolved;
274
277
  }
275
278
  history.listen((to, from, state) => {
279
+ if (isNavigating) return;
276
280
  const match = matchRoute(to, compiledRoutes);
277
281
  finalizeNavigation(createRouteLocation(to, match?.route || null, match?.params || {}), getCurrentRoute());
278
282
  });
@@ -632,7 +636,7 @@ const RouterView = component((ctx) => {
632
636
  ...componentProps,
633
637
  ...pageProps
634
638
  };
635
- return /* @__PURE__ */ jsx(Component, { ...componentProps });
639
+ return /* @__PURE__ */ jsx(Component, { ...componentProps }, match.path);
636
640
  };
637
641
  }, { name: "RouterView" });
638
642
  const Link = component(({ props, slots, emit }) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/matcher.ts","../src/router.ts","../src/history/web.ts","../src/history/memory.ts","../src/hooks.ts","../src/RouterView.tsx","../src/Link.tsx","../src/plugin.ts"],"sourcesContent":["/**\r\n * Route matching utilities\r\n * \r\n * Handles parsing route patterns and matching them against paths.\r\n */\r\n\r\nimport type { RouteRecordRaw, RouteParams, MatchedRouteRecord, RouteLocation, RouteQuery } from './types.js';\r\n\r\n/**\r\n * Parsed route segment\r\n */\r\ninterface ParsedSegment {\r\n /** Whether this is a parameter (e.g., :id) */\r\n isParam: boolean;\r\n /** Whether this is a wildcard (*) */\r\n isWildcard: boolean;\r\n /** Segment value (parameter name or literal value) */\r\n value: string;\r\n /** Whether this segment is optional (ends with ?) */\r\n isOptional: boolean;\r\n}\r\n\r\n/**\r\n * Compiled route for matching\r\n */\r\nexport interface CompiledRoute {\r\n /** Original route record */\r\n record: RouteRecordRaw;\r\n /** Parsed segments for matching */\r\n segments: ParsedSegment[];\r\n /** Regex for matching */\r\n regex: RegExp;\r\n /** Parameter names in order */\r\n paramNames: string[];\r\n /** Score for ranking matches (higher = more specific) */\r\n score: number;\r\n /** Parent route (for nested routes) */\r\n parent: CompiledRoute | null;\r\n}\r\n\r\n/**\r\n * Parse a route path into segments\r\n */\r\nfunction parseSegments(path: string): ParsedSegment[] {\r\n // Remove leading/trailing slashes and split\r\n const parts = path.replace(/^\\/|\\/$/g, '').split('/').filter(Boolean);\r\n \r\n return parts.map(part => {\r\n // Parameter: :name or :name?\r\n if (part.startsWith(':')) {\r\n const isOptional = part.endsWith('?');\r\n const value = isOptional ? part.slice(1, -1) : part.slice(1);\r\n return { isParam: true, isWildcard: false, value, isOptional };\r\n }\r\n \r\n // Wildcard: * or *name\r\n if (part.startsWith('*')) {\r\n const value = part.slice(1) || 'pathMatch';\r\n return { isParam: false, isWildcard: true, value, isOptional: false };\r\n }\r\n \r\n // Literal segment\r\n return { isParam: false, isWildcard: false, value: part, isOptional: false };\r\n });\r\n}\r\n\r\n/**\r\n * Calculate route score for ranking matches\r\n * Higher score = more specific match\r\n */\r\nfunction calculateScore(segments: ParsedSegment[]): number {\r\n let score = 0;\r\n \r\n for (const segment of segments) {\r\n if (segment.isWildcard) {\r\n score += 1;\r\n } else if (segment.isParam) {\r\n score += segment.isOptional ? 2 : 3;\r\n } else {\r\n score += 4; // Literal segments are most specific\r\n }\r\n }\r\n \r\n return score;\r\n}\r\n\r\n/**\r\n * Build regex for route matching\r\n */\r\nfunction buildRegex(segments: ParsedSegment[]): RegExp {\r\n const parts = segments.map(segment => {\r\n if (segment.isWildcard) {\r\n return '(?:\\\\/(.*))?';\r\n }\r\n if (segment.isParam) {\r\n const pattern = segment.isOptional \r\n ? '(?:\\\\/([^\\\\/]+))?' \r\n : '\\\\/([^\\\\/]+)';\r\n return pattern;\r\n }\r\n return `\\\\/${escapeRegex(segment.value)}`;\r\n });\r\n \r\n return new RegExp(`^${parts.join('')}\\\\/?$`);\r\n}\r\n\r\n/**\r\n * Escape special regex characters\r\n */\r\nfunction escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\n/**\r\n * Compile a route for efficient matching\r\n */\r\nexport function compileRoute(record: RouteRecordRaw, parent: CompiledRoute | null = null): CompiledRoute {\r\n const segments = parseSegments(record.path);\r\n const regex = buildRegex(segments);\r\n const paramNames = segments\r\n .filter(s => s.isParam || s.isWildcard)\r\n .map(s => s.value);\r\n const score = calculateScore(segments);\r\n \r\n return { record, segments, regex, paramNames, score, parent };\r\n}\r\n\r\n/**\r\n * Compile all routes (including nested routes)\r\n */\r\nexport function compileRoutes(routes: RouteRecordRaw[], parentPath = '', parentRoute: CompiledRoute | null = null): CompiledRoute[] {\r\n const compiled: CompiledRoute[] = [];\r\n \r\n for (const route of routes) {\r\n // Build full path\r\n const fullPath = joinPaths(parentPath, route.path);\r\n const routeWithFullPath = { ...route, path: fullPath };\r\n \r\n // Compile this route with parent reference\r\n const compiledRoute = compileRoute(routeWithFullPath, parentRoute);\r\n compiled.push(compiledRoute);\r\n \r\n // Compile children with this route as parent\r\n if (route.children) {\r\n compiled.push(...compileRoutes(route.children, fullPath, compiledRoute));\r\n }\r\n }\r\n \r\n // Sort by score (most specific first)\r\n compiled.sort((a, b) => b.score - a.score);\r\n \r\n return compiled;\r\n}\r\n\r\n/**\r\n * Join path segments\r\n */\r\nfunction joinPaths(parent: string, child: string): string {\r\n if (!parent) return child;\r\n if (child.startsWith('/')) return child; // Absolute path\r\n \r\n const parentNorm = parent.endsWith('/') ? parent.slice(0, -1) : parent;\r\n const childNorm = child.startsWith('/') ? child : '/' + child;\r\n \r\n return parentNorm + childNorm;\r\n}\r\n\r\n/**\r\n * Match a path against compiled routes\r\n */\r\nexport function matchRoute(\r\n path: string, \r\n compiledRoutes: CompiledRoute[]\r\n): { route: CompiledRoute; params: RouteParams } | null {\r\n // Strip query and hash for matching\r\n const [pathOnly] = path.split(/[?#]/);\r\n \r\n for (const compiled of compiledRoutes) {\r\n const match = compiled.regex.exec(pathOnly);\r\n \r\n if (match) {\r\n const params: RouteParams = {};\r\n \r\n // Extract parameters\r\n compiled.paramNames.forEach((name, index) => {\r\n const value = match[index + 1];\r\n if (value !== undefined) {\r\n params[name] = decodeURIComponent(value);\r\n }\r\n });\r\n \r\n return { route: compiled, params };\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n/**\r\n * Parse query string into object\r\n */\r\nexport function parseQuery(queryString: string): RouteQuery {\r\n const query: RouteQuery = {};\r\n \r\n if (!queryString || queryString === '?') return query;\r\n \r\n // Remove leading ?\r\n const qs = queryString.startsWith('?') ? queryString.slice(1) : queryString;\r\n \r\n for (const pair of qs.split('&')) {\r\n if (!pair) continue;\r\n \r\n const [key, value] = pair.split('=');\r\n const decodedKey = decodeURIComponent(key);\r\n const decodedValue = value !== undefined ? decodeURIComponent(value) : '';\r\n \r\n // Handle array values (same key multiple times)\r\n const existing = query[decodedKey];\r\n if (existing !== undefined) {\r\n if (Array.isArray(existing)) {\r\n existing.push(decodedValue);\r\n } else {\r\n query[decodedKey] = [existing, decodedValue];\r\n }\r\n } else {\r\n query[decodedKey] = decodedValue;\r\n }\r\n }\r\n \r\n return query;\r\n}\r\n\r\n/**\r\n * Stringify query object\r\n */\r\nexport function stringifyQuery(query: RouteQuery): string {\r\n const parts: string[] = [];\r\n \r\n for (const key in query) {\r\n const value = query[key];\r\n if (value === undefined) continue;\r\n \r\n if (Array.isArray(value)) {\r\n for (const v of value) {\r\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);\r\n }\r\n } else {\r\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\r\n }\r\n }\r\n \r\n return parts.length ? '?' + parts.join('&') : '';\r\n}\r\n\r\n/**\r\n * Parse full URL into components\r\n */\r\nexport function parseURL(url: string): { path: string; query: RouteQuery; hash: string } {\r\n let path = url;\r\n let queryString = '';\r\n let hash = '';\r\n \r\n // Extract hash\r\n const hashIndex = path.indexOf('#');\r\n if (hashIndex !== -1) {\r\n hash = path.slice(hashIndex);\r\n path = path.slice(0, hashIndex);\r\n }\r\n \r\n // Extract query\r\n const queryIndex = path.indexOf('?');\r\n if (queryIndex !== -1) {\r\n queryString = path.slice(queryIndex);\r\n path = path.slice(0, queryIndex);\r\n }\r\n \r\n return {\r\n path: path || '/',\r\n query: parseQuery(queryString),\r\n hash\r\n };\r\n}\r\n\r\n/**\r\n * Build a full path from components\r\n */\r\nexport function buildPath(\r\n path: string,\r\n query?: RouteQuery,\r\n hash?: string\r\n): string {\r\n let result = path;\r\n \r\n if (query && Object.keys(query).length > 0) {\r\n result += stringifyQuery(query);\r\n }\r\n \r\n if (hash) {\r\n result += hash.startsWith('#') ? hash : '#' + hash;\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Create a RouteLocation from matched route\r\n */\r\nexport function createRouteLocation(\r\n fullPath: string,\r\n matched: CompiledRoute | null,\r\n params: RouteParams\r\n): RouteLocation {\r\n const { path, query, hash } = parseURL(fullPath);\r\n \r\n // Build matched records array by traversing up the parent chain\r\n const matchedRecords: MatchedRouteRecord[] = [];\r\n \r\n if (matched) {\r\n // Collect all routes from root to leaf\r\n let current: CompiledRoute | null = matched;\r\n const routeChain: CompiledRoute[] = [];\r\n \r\n while (current) {\r\n routeChain.unshift(current); // Add to front to get root-first order\r\n current = current.parent;\r\n }\r\n \r\n // Convert to MatchedRouteRecord array\r\n for (const route of routeChain) {\r\n matchedRecords.push({\r\n path: route.record.path,\r\n name: route.record.name,\r\n component: route.record.component,\r\n meta: route.record.meta || {},\r\n props: route.record.props\r\n });\r\n }\r\n }\r\n \r\n return {\r\n fullPath,\r\n path,\r\n name: matched?.record.name,\r\n params,\r\n query,\r\n hash,\r\n matched: matchedRecords,\r\n meta: matched?.record.meta || {}\r\n };\r\n}\r\n","/**\r\n * Router implementation for @sigx/router\r\n * \r\n * Creates a router instance with navigation, guards, and SSR support.\r\n */\r\n\r\nimport { signal, defineInjectable } from 'sigx';\r\nimport type {\r\n Router,\r\n RouterOptions,\r\n RouteLocation,\r\n RouteLocationRaw,\r\n NavigationGuard,\r\n NavigationHookAfter,\r\n RouteRecordRaw,\r\n RouteParams,\r\n RouteMatchPatterns\r\n} from './types.js';\r\nimport {\r\n compileRoutes,\r\n matchRoute,\r\n createRouteLocation,\r\n parseURL,\r\n buildPath,\r\n type CompiledRoute\r\n} from './matcher.js';\r\n\r\n/**\r\n * Injectable for accessing the router instance.\r\n * Must be installed via app.use(router) before use.\r\n */\r\nexport const useRouter = defineInjectable<Router>(() => {\r\n throw new Error(\r\n 'useRouter() is called but no router is installed. ' +\r\n 'Make sure to install the router with app.use(router).'\r\n );\r\n});\r\n\r\n/**\r\n * Injectable for accessing the current route (reactive).\r\n * Must be installed via app.use(router) before use.\r\n */\r\nexport const useRoute = defineInjectable<RouteLocation>(() => {\r\n throw new Error(\r\n 'useRoute() is called but no router is installed. ' +\r\n 'Make sure to install the router with app.use(router).'\r\n );\r\n});\r\n\r\n/**\r\n * Create a router instance\r\n * \r\n * @example\r\n * ```ts\r\n * import { createRouter } from '@sigx/router';\r\n * import { createWebHistory } from '@sigx/router/history';\r\n * \r\n * const router = createRouter({\r\n * history: createWebHistory(),\r\n * routes: [\r\n * { path: '/', component: Home },\r\n * { path: '/about', component: About },\r\n * { path: '/blog/:slug', component: BlogPost }\r\n * ]\r\n * });\r\n * ```\r\n */\r\nexport function createRouter(options: RouterOptions): Router {\r\n const { history, routes } = options;\r\n const base = options.base || '';\r\n \r\n // Compile routes for efficient matching\r\n let compiledRoutes = compileRoutes(routes);\r\n \r\n // Route storage for dynamic routes\r\n const routeRecords = [...routes];\r\n \r\n // Navigation guards\r\n const beforeGuards: NavigationGuard[] = [];\r\n const beforeResolveGuards: NavigationGuard[] = [];\r\n const afterHooks: NavigationHookAfter[] = [];\r\n \r\n // Ready promise\r\n let readyPromise: Promise<void> | null = null;\r\n let readyResolve: (() => void) | null = null;\r\n \r\n // Create initial route\r\n const initialLocation = history.location;\r\n \r\n const initialMatch = matchRoute(initialLocation, compiledRoutes);\r\n \r\n const initialRoute = createRouteLocation(\r\n initialLocation,\r\n initialMatch?.route || null,\r\n initialMatch?.params || {}\r\n );\r\n \r\n // Reactive current route state\r\n const currentRouteState = signal(initialRoute);\r\n \r\n // Track pending navigation\r\n let pendingNavigation: Promise<RouteLocation | void> | null = null;\r\n \r\n /**\r\n * Resolve a raw location to a full RouteLocation\r\n */\r\n function resolve(to: RouteLocationRaw): RouteLocation {\r\n // String path\r\n if (typeof to === 'string') {\r\n const match = matchRoute(to, compiledRoutes);\r\n return createRouteLocation(to, match?.route || null, match?.params || {});\r\n }\r\n \r\n // Object location\r\n const { path, name, params = {}, query = {}, hash = '' } = to;\r\n \r\n // Named route\r\n if (name) {\r\n const route = compiledRoutes.find(r => r.record.name === name);\r\n if (!route) {\r\n console.warn(`Route with name \"${name}\" not found`);\r\n return createRouteLocation('/', null, {});\r\n }\r\n \r\n // Build path from params\r\n const resolvedPath = buildPathFromParams(route.record.path, params);\r\n const fullPath = buildPath(resolvedPath, query, hash);\r\n return createRouteLocation(fullPath, route, params);\r\n }\r\n \r\n // Path-based\r\n if (path) {\r\n const fullPath = buildPath(path, query, hash);\r\n const match = matchRoute(path, compiledRoutes);\r\n return createRouteLocation(fullPath, match?.route || null, match?.params || {});\r\n }\r\n \r\n // Invalid - return current\r\n return getCurrentRoute();\r\n }\r\n \r\n /**\r\n * Build path from params\r\n */\r\n function buildPathFromParams(pattern: string, params: RouteParams): string {\r\n let path = pattern;\r\n for (const key in params) {\r\n path = path.replace(`:${key}`, encodeURIComponent(params[key]));\r\n }\r\n // Remove optional params that weren't provided\r\n path = path.replace(/\\/:[^/]+\\?/g, '');\r\n return path;\r\n }\r\n \r\n /**\r\n * Get current route\r\n */\r\n function getCurrentRoute(): RouteLocation {\r\n // The signal object has the RouteLocation properties directly on it\r\n // We return the signal which has been assigned RouteLocation properties\r\n const state = currentRouteState;\r\n return {\r\n fullPath: state.fullPath,\r\n path: state.path,\r\n name: state.name,\r\n params: state.params,\r\n query: state.query,\r\n hash: state.hash,\r\n matched: state.matched,\r\n meta: state.meta,\r\n redirectedFrom: state.redirectedFrom\r\n };\r\n }\r\n \r\n /**\r\n * Run navigation guards\r\n */\r\n async function runGuards(\r\n to: RouteLocation,\r\n from: RouteLocation | null,\r\n guards: NavigationGuard[]\r\n ): Promise<boolean | RouteLocation | void> {\r\n for (const guard of guards) {\r\n const result = await guard(to, from);\r\n \r\n // Guard returned false - abort\r\n if (result === false) {\r\n return false;\r\n }\r\n \r\n // Guard returned string path - redirect\r\n if (typeof result === 'string') {\r\n return resolve(result);\r\n }\r\n \r\n // Guard returned location object - redirect\r\n if (result && typeof result === 'object') {\r\n return resolve(result);\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n \r\n /**\r\n * Finalize navigation\r\n */\r\n function finalizeNavigation(to: RouteLocation, from: RouteLocation | null): void {\r\n // Update reactive state using $set for proper reactivity triggering\r\n (currentRouteState as any).$set(to);\r\n \r\n // Run after hooks\r\n for (const hook of afterHooks) {\r\n hook(to, from);\r\n }\r\n }\r\n \r\n /**\r\n * Navigate to a location\r\n */\r\n async function navigate(\r\n to: RouteLocationRaw,\r\n replace = false\r\n ): Promise<RouteLocation | void> {\r\n const from = getCurrentRoute();\r\n const resolved = resolve(to);\r\n \r\n // Handle redirect - check the DEEPEST matched route (last in array) for redirect\r\n // Only the actual target route should trigger a redirect, not parent routes\r\n const matched = resolved.matched[resolved.matched.length - 1];\r\n if (matched) {\r\n const routeRecord = compiledRoutes.find(r => r.record.path === matched.path)?.record;\r\n if (routeRecord?.redirect) {\r\n const redirectTo = typeof routeRecord.redirect === 'function'\r\n ? routeRecord.redirect(resolved)\r\n : routeRecord.redirect;\r\n return navigate(redirectTo, replace);\r\n }\r\n }\r\n \r\n // Run before guards\r\n const beforeResult = await runGuards(resolved, from, beforeGuards);\r\n if (beforeResult === false) return;\r\n if (beforeResult && typeof beforeResult === 'object') {\r\n return navigate(beforeResult, replace);\r\n }\r\n \r\n // Run route-specific guards\r\n for (const record of resolved.matched) {\r\n const routeRecord = compiledRoutes.find(r => r.record.path === record.path)?.record;\r\n if (routeRecord?.beforeEnter) {\r\n const guards = Array.isArray(routeRecord.beforeEnter)\r\n ? routeRecord.beforeEnter\r\n : [routeRecord.beforeEnter];\r\n const result = await runGuards(resolved, from, guards);\r\n if (result === false) return;\r\n if (result && typeof result === 'object') {\r\n return navigate(result, replace);\r\n }\r\n }\r\n }\r\n \r\n // Run before resolve guards\r\n const resolveResult = await runGuards(resolved, from, beforeResolveGuards);\r\n if (resolveResult === false) return;\r\n if (resolveResult && typeof resolveResult === 'object') {\r\n return navigate(resolveResult, replace);\r\n }\r\n \r\n // Update history\r\n if (replace) {\r\n history.replace(resolved.fullPath);\r\n } else {\r\n history.push(resolved.fullPath);\r\n }\r\n \r\n // Finalize\r\n finalizeNavigation(resolved, from);\r\n \r\n return resolved;\r\n }\r\n \r\n // Listen for history changes (back/forward)\r\n history.listen((to, from, state) => {\r\n const match = matchRoute(to, compiledRoutes);\r\n const resolved = createRouteLocation(to, match?.route || null, match?.params || {});\r\n finalizeNavigation(resolved, getCurrentRoute());\r\n });\r\n \r\n const router: Router = {\r\n get currentRoute() {\r\n return getCurrentRoute();\r\n },\r\n \r\n get options() {\r\n return options;\r\n },\r\n \r\n push(to) {\r\n return navigate(to, false);\r\n },\r\n \r\n replace(to) {\r\n return navigate(to, true);\r\n },\r\n \r\n back() {\r\n history.go(-1);\r\n },\r\n \r\n forward() {\r\n history.go(1);\r\n },\r\n \r\n go(delta) {\r\n history.go(delta);\r\n },\r\n \r\n beforeEach(guard) {\r\n beforeGuards.push(guard);\r\n return () => {\r\n const index = beforeGuards.indexOf(guard);\r\n if (index !== -1) beforeGuards.splice(index, 1);\r\n };\r\n },\r\n \r\n beforeResolve(guard) {\r\n beforeResolveGuards.push(guard);\r\n return () => {\r\n const index = beforeResolveGuards.indexOf(guard);\r\n if (index !== -1) beforeResolveGuards.splice(index, 1);\r\n };\r\n },\r\n \r\n afterEach(hook) {\r\n afterHooks.push(hook);\r\n return () => {\r\n const index = afterHooks.indexOf(hook);\r\n if (index !== -1) afterHooks.splice(index, 1);\r\n };\r\n },\r\n \r\n hasRoute(name) {\r\n return routeRecords.some(r => r.name === name);\r\n },\r\n \r\n getRoutes() {\r\n return [...routeRecords];\r\n },\r\n \r\n addRoute(route, parentName) {\r\n if (parentName) {\r\n const parent = routeRecords.find(r => r.name === parentName);\r\n if (parent) {\r\n parent.children = parent.children || [];\r\n parent.children.push(route);\r\n }\r\n } else {\r\n routeRecords.push(route);\r\n }\r\n \r\n // Recompile routes\r\n compiledRoutes = compileRoutes(routeRecords);\r\n \r\n // Return a function to remove the route\r\n // If route has no name, we need to track it differently\r\n const routeRef = route;\r\n return () => {\r\n if (routeRef.name) {\r\n router.removeRoute(routeRef.name);\r\n } else {\r\n // Remove by reference\r\n const index = routeRecords.indexOf(routeRef);\r\n if (index !== -1) {\r\n routeRecords.splice(index, 1);\r\n compiledRoutes = compileRoutes(routeRecords);\r\n }\r\n }\r\n };\r\n },\r\n \r\n removeRoute(name) {\r\n const index = routeRecords.findIndex(r => r.name === name);\r\n if (index !== -1) {\r\n routeRecords.splice(index, 1);\r\n compiledRoutes = compileRoutes(routeRecords);\r\n }\r\n },\r\n \r\n resolve,\r\n \r\n match<T>(patterns: RouteMatchPatterns<T>): T | undefined {\r\n const route = getCurrentRoute();\r\n const routeName = route.name;\r\n \r\n // Try to match by route name\r\n if (routeName && routeName in patterns) {\r\n const pattern = patterns[routeName];\r\n if (typeof pattern === 'function') {\r\n return (pattern as (params: RouteParams) => T)(route.params);\r\n }\r\n return pattern as T;\r\n }\r\n \r\n // Fall back to catch-all pattern\r\n if ('_' in patterns) {\r\n const fallback = patterns._;\r\n if (typeof fallback === 'function') {\r\n return (fallback as (params: RouteParams) => T)(route.params);\r\n }\r\n return fallback as T;\r\n }\r\n \r\n return undefined;\r\n },\r\n \r\n install(app) {\r\n // Provide router and current route at app level\r\n app.defineProvide(useRouter, () => router);\r\n app.defineProvide(useRoute, () => currentRouteState as unknown as RouteLocation);\r\n \r\n // Mark router as ready\r\n if (readyResolve) {\r\n readyResolve();\r\n }\r\n },\r\n \r\n isReady() {\r\n if (!readyPromise) {\r\n readyPromise = new Promise(resolve => {\r\n readyResolve = resolve;\r\n });\r\n }\r\n return readyPromise;\r\n }\r\n };\r\n \r\n return router;\r\n}\r\n","/**\r\n * Browser history implementation using the History API\r\n * \r\n * This is the default history for client-side navigation.\r\n */\r\n\r\nimport type { RouterHistory, HistoryState } from '../types.js';\r\n\r\nexport interface BrowserHistoryOptions {\r\n /** Base path for the application */\r\n base?: string;\r\n}\r\n\r\n/**\r\n * Create a browser history instance that uses the HTML5 History API\r\n */\r\nexport function createWebHistory(options: BrowserHistoryOptions = {}): RouterHistory {\r\n const base = normalizeBase(options.base);\r\n const listeners: Set<(to: string, from: string, state: HistoryState | null) => void> = new Set();\r\n \r\n let currentLocation = getCurrentLocation(base);\r\n let currentState = (typeof window !== 'undefined' ? window.history.state : null) as HistoryState | null;\r\n \r\n // Handle browser back/forward\r\n const handlePopState = (event: PopStateEvent) => {\r\n const from = currentLocation;\r\n currentLocation = getCurrentLocation(base);\r\n currentState = event.state as HistoryState | null;\r\n \r\n listeners.forEach(callback => {\r\n callback(currentLocation, from, currentState);\r\n });\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', handlePopState);\r\n }\r\n \r\n const history: RouterHistory = {\r\n get location() {\r\n return currentLocation;\r\n },\r\n \r\n get state() {\r\n return currentState;\r\n },\r\n \r\n get base() {\r\n return base;\r\n },\r\n \r\n push(to: string, state?: HistoryState) {\r\n const from = currentLocation;\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n const fullPath = base === '/' ? to : base + to;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: (currentState?.position ?? 0) + 1\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.history.pushState(historyState, '', fullPath);\r\n }\r\n currentLocation = to;\r\n currentState = historyState;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n replace(to: string, state?: HistoryState) {\r\n const from = currentLocation;\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n const fullPath = base === '/' ? to : base + to;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentState?.position ?? 0\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.history.replaceState(historyState, '', fullPath);\r\n }\r\n currentLocation = to;\r\n currentState = historyState;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n go(delta: number) {\r\n if (typeof window !== 'undefined') {\r\n window.history.go(delta);\r\n }\r\n },\r\n \r\n listen(callback) {\r\n listeners.add(callback);\r\n return () => {\r\n listeners.delete(callback);\r\n };\r\n },\r\n \r\n createHref(path: string) {\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n return base === '/' ? path : base + path;\r\n },\r\n \r\n destroy() {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('popstate', handlePopState);\r\n }\r\n listeners.clear();\r\n }\r\n };\r\n \r\n return history;\r\n}\r\n\r\n/**\r\n * Normalize the base path\r\n */\r\nfunction normalizeBase(base?: string): string {\r\n if (!base) {\r\n // Use <base> tag if available\r\n if (typeof document !== 'undefined') {\r\n const baseTag = document.querySelector('base');\r\n if (baseTag) {\r\n base = baseTag.getAttribute('href') || '/';\r\n }\r\n }\r\n base = base || '/';\r\n }\r\n \r\n // Ensure base starts with /\r\n if (!base.startsWith('/')) {\r\n base = '/' + base;\r\n }\r\n \r\n // Remove trailing slash\r\n if (base !== '/' && base.endsWith('/')) {\r\n base = base.slice(0, -1);\r\n }\r\n \r\n return base;\r\n}\r\n\r\n/**\r\n * Get current location from window, stripping the base\r\n */\r\nfunction getCurrentLocation(base: string): string {\r\n if (typeof window === 'undefined') {\r\n return '/';\r\n }\r\n \r\n const { pathname, search, hash } = window.location;\r\n let path = pathname;\r\n \r\n // Strip base from path\r\n if (base !== '/' && pathname.startsWith(base)) {\r\n path = pathname.slice(base.length) || '/';\r\n }\r\n \r\n return path + search + hash;\r\n}\r\n","/**\r\n * Memory history implementation for SSR\r\n * \r\n * This history doesn't interact with the browser History API,\r\n * making it suitable for server-side rendering.\r\n */\r\n\r\nimport type { RouterHistory, HistoryState } from '../types.js';\r\n\r\nexport interface MemoryHistoryOptions {\r\n /** Base path for the application */\r\n base?: string;\r\n /** Initial location */\r\n initialLocation?: string;\r\n}\r\n\r\ninterface HistoryEntry {\r\n location: string;\r\n state: HistoryState | null;\r\n}\r\n\r\n/**\r\n * Create a memory history instance for SSR\r\n * \r\n * @example\r\n * ```ts\r\n * // Server-side\r\n * const history = createMemoryHistory({ initialLocation: req.url });\r\n * const router = createRouter({ routes, history });\r\n * ```\r\n */\r\nexport function createMemoryHistory(options: MemoryHistoryOptions = {}): RouterHistory {\r\n const base = options.base || '';\r\n const initialLocation = options.initialLocation || '/';\r\n \r\n const listeners: Set<(to: string, from: string, state: HistoryState | null) => void> = new Set();\r\n \r\n // History stack for back/forward navigation\r\n const entries: HistoryEntry[] = [\r\n { location: initialLocation, state: { path: initialLocation, position: 0 } }\r\n ];\r\n let currentIndex = 0;\r\n \r\n const history: RouterHistory = {\r\n get location() {\r\n return entries[currentIndex].location;\r\n },\r\n \r\n get state() {\r\n return entries[currentIndex].state;\r\n },\r\n \r\n get base() {\r\n return base;\r\n },\r\n \r\n push(to: string, state?: HistoryState) {\r\n const from = entries[currentIndex].location;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentIndex + 1\r\n };\r\n \r\n // Remove any forward entries\r\n entries.splice(currentIndex + 1);\r\n \r\n // Add new entry\r\n entries.push({ location: to, state: historyState });\r\n currentIndex = entries.length - 1;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n replace(to: string, state?: HistoryState) {\r\n const from = entries[currentIndex].location;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentIndex\r\n };\r\n \r\n // Replace current entry\r\n entries[currentIndex] = { location: to, state: historyState };\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n go(delta: number) {\r\n const newIndex = currentIndex + delta;\r\n \r\n if (newIndex < 0 || newIndex >= entries.length) {\r\n return;\r\n }\r\n \r\n const from = entries[currentIndex].location;\r\n currentIndex = newIndex;\r\n const to = entries[currentIndex].location;\r\n const state = entries[currentIndex].state;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, state);\r\n });\r\n },\r\n \r\n listen(callback) {\r\n listeners.add(callback);\r\n return () => {\r\n listeners.delete(callback);\r\n };\r\n },\r\n \r\n createHref(path: string) {\r\n return base + path;\r\n },\r\n \r\n destroy() {\r\n listeners.clear();\r\n }\r\n };\r\n \r\n return history;\r\n}\r\n","/**\r\n * Router hooks for @sigx/router\r\n * \r\n * These hooks provide access to router state and navigation within components.\r\n */\r\n\r\nimport { getCurrentInstance } from 'sigx';\r\nimport type { Router, RouteLocation, RouteParams, RouteQuery } from './types.js';\r\nimport { useRouter, useRoute } from './router.js';\r\n\r\n// Re-export the injectable hooks from router.ts\r\nexport { useRouter, useRoute };\r\n\r\n/**\r\n * Get route parameters (reactive)\r\n * \r\n * @example\r\n * ```tsx\r\n * const params = useParams();\r\n * console.log(params.id);\r\n * ```\r\n */\r\nexport function useParams(): RouteParams {\r\n const route = useRoute();\r\n return route.params;\r\n}\r\n\r\n/**\r\n * Get query parameters (reactive)\r\n * \r\n * @example\r\n * ```tsx\r\n * const query = useQuery();\r\n * console.log(query.search);\r\n * ```\r\n */\r\nexport function useQuery(): RouteQuery {\r\n const route = useRoute();\r\n return route.query;\r\n}\r\n\r\n/**\r\n * Get a navigate function for programmatic navigation\r\n * \r\n * @example\r\n * ```tsx\r\n * const navigate = useNavigate();\r\n * navigate('/about');\r\n * navigate({ path: '/blog', query: { page: '2' } });\r\n * ```\r\n */\r\nexport function useNavigate() {\r\n const router = useRouter();\r\n return router.push.bind(router);\r\n}\r\n\r\n/**\r\n * Guard type for route enter\r\n */\r\ntype RouteEnterGuard = (\r\n to: RouteLocation,\r\n from: RouteLocation | null,\r\n next: (to?: string | false | RouteLocation) => void\r\n) => void;\r\n\r\n/**\r\n * Guard type for route leave\r\n */\r\ntype RouteLeaveGuard = (\r\n to: RouteLocation,\r\n from: RouteLocation,\r\n next: (to?: string | false | RouteLocation) => void\r\n) => void;\r\n\r\n/**\r\n * Register a navigation guard that runs before leaving the current route\r\n * \r\n * @example\r\n * ```tsx\r\n * onBeforeRouteLeave((to, from, next) => {\r\n * if (hasUnsavedChanges) {\r\n * const answer = confirm('You have unsaved changes. Leave anyway?');\r\n * if (!answer) {\r\n * next(false);\r\n * return;\r\n * }\r\n * }\r\n * next();\r\n * });\r\n * ```\r\n */\r\nexport function onBeforeRouteLeave(guard: RouteLeaveGuard): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n console.warn('onBeforeRouteLeave() is called outside of component setup');\r\n return;\r\n }\r\n \r\n const router = useRouter();\r\n \r\n // Register guard\r\n const unregister = router.beforeEach((to, from) => {\r\n if (!from) return;\r\n \r\n // Only run if leaving current component's route\r\n const currentRoute = useRoute();\r\n if (from.path !== currentRoute.path) return;\r\n \r\n return new Promise((resolve) => {\r\n guard(to, from, (result) => {\r\n if (result === false) {\r\n resolve(false);\r\n } else if (typeof result === 'string') {\r\n resolve(result);\r\n } else if (result && typeof result === 'object') {\r\n resolve(result);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n });\r\n \r\n // Unregister when component unmounts\r\n ctx.onUnmounted(() => {\r\n unregister();\r\n });\r\n}\r\n\r\n/**\r\n * Register a navigation guard that runs when entering the current route\r\n * \r\n * @example\r\n * ```tsx\r\n * onBeforeRouteUpdate((to, from, next) => {\r\n * // Called when route params change but component is reused\r\n * next();\r\n * });\r\n * ```\r\n */\r\nexport function onBeforeRouteUpdate(guard: RouteEnterGuard): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n console.warn('onBeforeRouteUpdate() is called outside of component setup');\r\n return;\r\n }\r\n \r\n const router = useRouter();\r\n const currentRoute = useRoute();\r\n \r\n // Register guard\r\n const unregister = router.beforeEach((to, from) => {\r\n // Only run if route path is the same (update, not leave)\r\n if (to.path !== currentRoute.path) return;\r\n \r\n return new Promise((resolve) => {\r\n guard(to, from, (result) => {\r\n if (result === false) {\r\n resolve(false);\r\n } else if (typeof result === 'string') {\r\n resolve(result);\r\n } else if (result && typeof result === 'object') {\r\n resolve(result);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n });\r\n \r\n // Unregister when component unmounts\r\n ctx.onUnmounted(() => {\r\n unregister();\r\n });\r\n}\r\n","/**\r\n * RouterView component - renders the matched route component\r\n * \r\n * @example\r\n * ```tsx\r\n * <RouterView />\r\n * \r\n * // With named views (for nested routes)\r\n * <RouterView name=\"sidebar\" />\r\n * \r\n * // With page props (from SSG getStaticProps)\r\n * <RouterView pageProps={{ posts: [...] }} />\r\n * ```\r\n */\r\n\r\nimport { component, type DefineProp, type ComponentFactory, defineInjectable, defineProvide } from 'sigx';\r\nimport { useRoute } from './hooks.js';\r\n\r\ntype RouterViewProps = DefineProp<'name', string> & DefineProp<'pageProps', Record<string, unknown>>;\r\n\r\n/**\r\n * Injectable for tracking RouterView depth.\r\n * Each nested RouterView increments the depth to render the correct matched route.\r\n */\r\nconst useRouterViewDepth = defineInjectable<number>(() => 0);\r\n\r\n/**\r\n * Type guard to check if a component is a SignalX component factory\r\n */\r\nfunction isComponentFactory(component: unknown): component is ComponentFactory<any, any, any> {\r\n return typeof component === 'function' && '__setup' in component;\r\n}\r\n\r\nexport const RouterView = component<RouterViewProps>((ctx) => {\r\n // Read props reactively inside the render function\r\n const route = useRoute();\r\n \r\n // Get current depth from parent RouterView (0 if we're the root)\r\n const depth = useRouterViewDepth();\r\n \r\n // Provide incremented depth for child RouterViews\r\n defineProvide(useRouterViewDepth, () => depth + 1);\r\n \r\n return () => {\r\n // Read pageProps at render time for reactivity\r\n const { name = 'default', pageProps = {} } = ctx.props;\r\n const matched = route.matched;\r\n \r\n if (matched.length === 0 || depth >= matched.length) {\r\n // No matched route at this depth - render nothing or fallback\r\n return null;\r\n }\r\n \r\n // Get the matched route at current depth\r\n const match = matched[depth];\r\n const Component = match.component;\r\n \r\n if (!Component) {\r\n return null;\r\n }\r\n \r\n // Handle lazy components - check if it's a SignalX component factory\r\n if (!isComponentFactory(Component)) {\r\n // This is a lazy import function or other callable\r\n // TODO: Integrate with Suspense when available\r\n return null;\r\n }\r\n \r\n // Calculate props for component\r\n let componentProps: Record<string, any> = {};\r\n \r\n if (match.props === true) {\r\n // Pass route params as props\r\n componentProps = { ...route.params };\r\n } else if (typeof match.props === 'function') {\r\n componentProps = match.props(route);\r\n } else if (match.props && typeof match.props === 'object') {\r\n componentProps = { ...match.props };\r\n }\r\n \r\n // Merge in pageProps from getStaticProps (SSG)\r\n if (pageProps && Object.keys(pageProps).length > 0) {\r\n componentProps = { ...componentProps, ...pageProps };\r\n }\r\n \r\n // Render the component - Component is now properly typed as ComponentFactory\r\n return <Component {...componentProps} />;\r\n };\r\n}, { name: 'RouterView' });\r\n","/**\r\n * Link component - declarative navigation\r\n * \r\n * @example\r\n * ```tsx\r\n * <Link to=\"/about\">About</Link>\r\n * \r\n * <Link to={{ path: '/blog', query: { page: '2' } }}>Blog</Link>\r\n * \r\n * <Link to=\"/contact\" replace>Contact</Link>\r\n * ```\r\n */\r\n\r\nimport { component, type DefineProp, type DefineEvent, type DefineSlot } from 'sigx';\r\nimport { useRouter, useRoute } from './hooks.js';\r\nimport type { RouteLocationRaw } from './types.js';\r\n\r\ntype LinkProps = \r\n & DefineProp<'to', RouteLocationRaw, true>\r\n & DefineProp<'replace', boolean>\r\n & DefineProp<'activeClass', string>\r\n & DefineProp<'exactActiveClass', string>\r\n & DefineProp<'ariaCurrentValue', 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false'>\r\n & DefineEvent<'click', MouseEvent>\r\n & DefineSlot<'default'>;\r\n\r\nexport const Link = component<LinkProps>(({ props, slots, emit }) => {\r\n const router = useRouter();\r\n const currentRoute = useRoute();\r\n \r\n // Apply defaults\r\n const replace = () => props.replace ?? false;\r\n const activeClass = () => props.activeClass ?? 'router-link-active';\r\n const exactActiveClass = () => props.exactActiveClass ?? 'router-link-exact-active';\r\n const ariaCurrentValue = () => props.ariaCurrentValue ?? 'page';\r\n \r\n const handleClick = (event: MouseEvent) => {\r\n // Emit click event\r\n emit('click', event);\r\n \r\n // Don't navigate if:\r\n // - Default prevented\r\n // - Meta key pressed (new tab)\r\n // - Ctrl key pressed (new tab)\r\n // - Shift key pressed (new window)\r\n // - Right click\r\n if (\r\n event.defaultPrevented ||\r\n event.metaKey ||\r\n event.ctrlKey ||\r\n event.shiftKey ||\r\n event.button !== 0\r\n ) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n \r\n if (replace()) {\r\n router.replace(props.to);\r\n } else {\r\n router.push(props.to);\r\n }\r\n };\r\n \r\n return () => {\r\n const resolved = router.resolve(props.to);\r\n const href = resolved.fullPath;\r\n \r\n // Determine active state\r\n const isExactActive = currentRoute.path === resolved.path;\r\n const isActive = currentRoute.path.startsWith(resolved.path);\r\n \r\n // Build class list\r\n const classes: string[] = [];\r\n if (isActive && activeClass()) {\r\n classes.push(activeClass());\r\n }\r\n if (isExactActive && exactActiveClass()) {\r\n classes.push(exactActiveClass());\r\n }\r\n \r\n return (\r\n <a\r\n href={href}\r\n onClick={handleClick}\r\n class={classes.length > 0 ? classes.join(' ') : undefined}\r\n aria-current={isExactActive ? ariaCurrentValue() : undefined}\r\n >\r\n {slots.default()}\r\n </a>\r\n );\r\n };\r\n}, { name: 'Link' });\r\n\r\n/**\r\n * Alias for Link component\r\n */\r\nexport const RouterLink = Link;\r\n","/**\r\n * Router plugin for @sigx/router\r\n * \r\n * Integrates the router with the SignalX app system.\r\n */\r\n\r\nimport type { Plugin, App } from 'sigx';\r\nimport type { Router, RouterOptions, RouteRecordRaw, RouterHistory } from './types.js';\r\nimport { createRouter } from './router.js';\r\n\r\n/**\r\n * Router plugin options\r\n */\r\nexport interface RouterPluginOptions {\r\n /** Route definitions */\r\n routes: RouteRecordRaw[];\r\n /** History implementation */\r\n history: RouterHistory;\r\n /** Base URL */\r\n base?: string;\r\n}\r\n\r\n/**\r\n * Create a router plugin for use with app.use()\r\n * \r\n * @example\r\n * ```tsx\r\n * import { defineApp } from '@sigx/runtime-core';\r\n * import { createRouterPlugin, createWebHistory } from '@sigx/router';\r\n * \r\n * const routerPlugin = createRouterPlugin({\r\n * history: createWebHistory(),\r\n * routes: [\r\n * { path: '/', component: Home },\r\n * { path: '/about', component: About }\r\n * ]\r\n * });\r\n * \r\n * const app = defineApp(<App />);\r\n * app.use(routerPlugin);\r\n * app.mount('#app');\r\n * ```\r\n */\r\nexport function createRouterPlugin(options: RouterPluginOptions): Plugin & { router: Router } {\r\n const router = createRouter(options);\r\n \r\n return {\r\n name: '@sigx/router',\r\n router,\r\n \r\n install(app) {\r\n router.install(app);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Alternative API: Create router and install in one step\r\n * \r\n * @example\r\n * ```tsx\r\n * const router = createRouter({ routes, history });\r\n * \r\n * const app = defineApp(<App />);\r\n * app.use(router); // Router implements Plugin interface\r\n * ```\r\n */\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/matcher.ts","../src/router.ts","../src/history/web.ts","../src/history/memory.ts","../src/hooks.ts","../src/RouterView.tsx","../src/Link.tsx","../src/plugin.ts"],"sourcesContent":["/**\r\n * Route matching utilities\r\n * \r\n * Handles parsing route patterns and matching them against paths.\r\n */\r\n\r\nimport type { RouteRecordRaw, RouteParams, MatchedRouteRecord, RouteLocation, RouteQuery } from './types.js';\r\n\r\n/**\r\n * Parsed route segment\r\n */\r\ninterface ParsedSegment {\r\n /** Whether this is a parameter (e.g., :id) */\r\n isParam: boolean;\r\n /** Whether this is a wildcard (*) */\r\n isWildcard: boolean;\r\n /** Segment value (parameter name or literal value) */\r\n value: string;\r\n /** Whether this segment is optional (ends with ?) */\r\n isOptional: boolean;\r\n}\r\n\r\n/**\r\n * Compiled route for matching\r\n */\r\nexport interface CompiledRoute {\r\n /** Original route record */\r\n record: RouteRecordRaw;\r\n /** Parsed segments for matching */\r\n segments: ParsedSegment[];\r\n /** Regex for matching */\r\n regex: RegExp;\r\n /** Parameter names in order */\r\n paramNames: string[];\r\n /** Score for ranking matches (higher = more specific) */\r\n score: number;\r\n /** Parent route (for nested routes) */\r\n parent: CompiledRoute | null;\r\n}\r\n\r\n/**\r\n * Parse a route path into segments\r\n */\r\nfunction parseSegments(path: string): ParsedSegment[] {\r\n // Remove leading/trailing slashes and split\r\n const parts = path.replace(/^\\/|\\/$/g, '').split('/').filter(Boolean);\r\n \r\n return parts.map(part => {\r\n // Parameter: :name or :name?\r\n if (part.startsWith(':')) {\r\n const isOptional = part.endsWith('?');\r\n const value = isOptional ? part.slice(1, -1) : part.slice(1);\r\n return { isParam: true, isWildcard: false, value, isOptional };\r\n }\r\n \r\n // Wildcard: * or *name\r\n if (part.startsWith('*')) {\r\n const value = part.slice(1) || 'pathMatch';\r\n return { isParam: false, isWildcard: true, value, isOptional: false };\r\n }\r\n \r\n // Literal segment\r\n return { isParam: false, isWildcard: false, value: part, isOptional: false };\r\n });\r\n}\r\n\r\n/**\r\n * Calculate route score for ranking matches\r\n * Higher score = more specific match\r\n */\r\nfunction calculateScore(segments: ParsedSegment[]): number {\r\n let score = 0;\r\n \r\n for (const segment of segments) {\r\n if (segment.isWildcard) {\r\n score += 1;\r\n } else if (segment.isParam) {\r\n score += segment.isOptional ? 2 : 3;\r\n } else {\r\n score += 4; // Literal segments are most specific\r\n }\r\n }\r\n \r\n return score;\r\n}\r\n\r\n/**\r\n * Build regex for route matching\r\n */\r\nfunction buildRegex(segments: ParsedSegment[]): RegExp {\r\n const parts = segments.map(segment => {\r\n if (segment.isWildcard) {\r\n return '(?:\\\\/(.*))?';\r\n }\r\n if (segment.isParam) {\r\n const pattern = segment.isOptional \r\n ? '(?:\\\\/([^\\\\/]+))?' \r\n : '\\\\/([^\\\\/]+)';\r\n return pattern;\r\n }\r\n return `\\\\/${escapeRegex(segment.value)}`;\r\n });\r\n \r\n return new RegExp(`^${parts.join('')}\\\\/?$`);\r\n}\r\n\r\n/**\r\n * Escape special regex characters\r\n */\r\nfunction escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\n/**\r\n * Compile a route for efficient matching\r\n */\r\nexport function compileRoute(record: RouteRecordRaw, parent: CompiledRoute | null = null): CompiledRoute {\r\n const segments = parseSegments(record.path);\r\n const regex = buildRegex(segments);\r\n const paramNames = segments\r\n .filter(s => s.isParam || s.isWildcard)\r\n .map(s => s.value);\r\n const score = calculateScore(segments);\r\n \r\n return { record, segments, regex, paramNames, score, parent };\r\n}\r\n\r\n/**\r\n * Compile all routes (including nested routes)\r\n */\r\nexport function compileRoutes(routes: RouteRecordRaw[], parentPath = '', parentRoute: CompiledRoute | null = null): CompiledRoute[] {\r\n const compiled: CompiledRoute[] = [];\r\n \r\n for (const route of routes) {\r\n // Build full path\r\n const fullPath = joinPaths(parentPath, route.path);\r\n const routeWithFullPath = { ...route, path: fullPath };\r\n \r\n // Compile this route with parent reference\r\n const compiledRoute = compileRoute(routeWithFullPath, parentRoute);\r\n compiled.push(compiledRoute);\r\n \r\n // Compile children with this route as parent\r\n if (route.children) {\r\n compiled.push(...compileRoutes(route.children, fullPath, compiledRoute));\r\n }\r\n }\r\n \r\n // Sort by score (most specific first)\r\n compiled.sort((a, b) => b.score - a.score);\r\n \r\n return compiled;\r\n}\r\n\r\n/**\r\n * Join path segments\r\n */\r\nfunction joinPaths(parent: string, child: string): string {\r\n if (!parent) return child;\r\n if (child.startsWith('/')) return child; // Absolute path\r\n \r\n const parentNorm = parent.endsWith('/') ? parent.slice(0, -1) : parent;\r\n const childNorm = child.startsWith('/') ? child : '/' + child;\r\n \r\n return parentNorm + childNorm;\r\n}\r\n\r\n/**\r\n * Match a path against compiled routes\r\n */\r\nexport function matchRoute(\r\n path: string, \r\n compiledRoutes: CompiledRoute[]\r\n): { route: CompiledRoute; params: RouteParams } | null {\r\n // Strip query and hash for matching\r\n const [pathOnly] = path.split(/[?#]/);\r\n \r\n for (const compiled of compiledRoutes) {\r\n const match = compiled.regex.exec(pathOnly);\r\n \r\n if (match) {\r\n const params: RouteParams = {};\r\n \r\n // Extract parameters\r\n compiled.paramNames.forEach((name, index) => {\r\n const value = match[index + 1];\r\n if (value !== undefined) {\r\n params[name] = decodeURIComponent(value);\r\n }\r\n });\r\n \r\n return { route: compiled, params };\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n/**\r\n * Parse query string into object\r\n */\r\nexport function parseQuery(queryString: string): RouteQuery {\r\n const query: RouteQuery = {};\r\n \r\n if (!queryString || queryString === '?') return query;\r\n \r\n // Remove leading ?\r\n const qs = queryString.startsWith('?') ? queryString.slice(1) : queryString;\r\n \r\n for (const pair of qs.split('&')) {\r\n if (!pair) continue;\r\n \r\n const [key, value] = pair.split('=');\r\n const decodedKey = decodeURIComponent(key);\r\n const decodedValue = value !== undefined ? decodeURIComponent(value) : '';\r\n \r\n // Handle array values (same key multiple times)\r\n const existing = query[decodedKey];\r\n if (existing !== undefined) {\r\n if (Array.isArray(existing)) {\r\n existing.push(decodedValue);\r\n } else {\r\n query[decodedKey] = [existing, decodedValue];\r\n }\r\n } else {\r\n query[decodedKey] = decodedValue;\r\n }\r\n }\r\n \r\n return query;\r\n}\r\n\r\n/**\r\n * Stringify query object\r\n */\r\nexport function stringifyQuery(query: RouteQuery): string {\r\n const parts: string[] = [];\r\n \r\n for (const key in query) {\r\n const value = query[key];\r\n if (value === undefined) continue;\r\n \r\n if (Array.isArray(value)) {\r\n for (const v of value) {\r\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);\r\n }\r\n } else {\r\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\r\n }\r\n }\r\n \r\n return parts.length ? '?' + parts.join('&') : '';\r\n}\r\n\r\n/**\r\n * Parse full URL into components\r\n */\r\nexport function parseURL(url: string): { path: string; query: RouteQuery; hash: string } {\r\n let path = url;\r\n let queryString = '';\r\n let hash = '';\r\n \r\n // Extract hash\r\n const hashIndex = path.indexOf('#');\r\n if (hashIndex !== -1) {\r\n hash = path.slice(hashIndex);\r\n path = path.slice(0, hashIndex);\r\n }\r\n \r\n // Extract query\r\n const queryIndex = path.indexOf('?');\r\n if (queryIndex !== -1) {\r\n queryString = path.slice(queryIndex);\r\n path = path.slice(0, queryIndex);\r\n }\r\n \r\n return {\r\n path: path || '/',\r\n query: parseQuery(queryString),\r\n hash\r\n };\r\n}\r\n\r\n/**\r\n * Build a full path from components\r\n */\r\nexport function buildPath(\r\n path: string,\r\n query?: RouteQuery,\r\n hash?: string\r\n): string {\r\n let result = path;\r\n \r\n if (query && Object.keys(query).length > 0) {\r\n result += stringifyQuery(query);\r\n }\r\n \r\n if (hash) {\r\n result += hash.startsWith('#') ? hash : '#' + hash;\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Create a RouteLocation from matched route\r\n */\r\nexport function createRouteLocation(\r\n fullPath: string,\r\n matched: CompiledRoute | null,\r\n params: RouteParams\r\n): RouteLocation {\r\n const { path, query, hash } = parseURL(fullPath);\r\n \r\n // Build matched records array by traversing up the parent chain\r\n const matchedRecords: MatchedRouteRecord[] = [];\r\n \r\n if (matched) {\r\n // Collect all routes from root to leaf\r\n let current: CompiledRoute | null = matched;\r\n const routeChain: CompiledRoute[] = [];\r\n \r\n while (current) {\r\n routeChain.unshift(current); // Add to front to get root-first order\r\n current = current.parent;\r\n }\r\n \r\n // Convert to MatchedRouteRecord array\r\n for (const route of routeChain) {\r\n matchedRecords.push({\r\n path: route.record.path,\r\n name: route.record.name,\r\n component: route.record.component,\r\n meta: route.record.meta || {},\r\n props: route.record.props\r\n });\r\n }\r\n }\r\n \r\n return {\r\n fullPath,\r\n path,\r\n name: matched?.record.name,\r\n params,\r\n query,\r\n hash,\r\n matched: matchedRecords,\r\n meta: matched?.record.meta || {}\r\n };\r\n}\r\n","/**\r\n * Router implementation for @sigx/router\r\n * \r\n * Creates a router instance with navigation, guards, and SSR support.\r\n */\r\n\r\nimport { signal, defineInjectable } from 'sigx';\r\nimport type {\r\n Router,\r\n RouterOptions,\r\n RouteLocation,\r\n RouteLocationRaw,\r\n NavigationGuard,\r\n NavigationHookAfter,\r\n RouteRecordRaw,\r\n RouteParams,\r\n RouteMatchPatterns\r\n} from './types.js';\r\nimport {\r\n compileRoutes,\r\n matchRoute,\r\n createRouteLocation,\r\n parseURL,\r\n buildPath,\r\n type CompiledRoute\r\n} from './matcher.js';\r\n\r\n/**\r\n * Injectable for accessing the router instance.\r\n * Must be installed via app.use(router) before use.\r\n */\r\nexport const useRouter = defineInjectable<Router>(() => {\r\n throw new Error(\r\n 'useRouter() is called but no router is installed. ' +\r\n 'Make sure to install the router with app.use(router).'\r\n );\r\n});\r\n\r\n/**\r\n * Injectable for accessing the current route (reactive).\r\n * Must be installed via app.use(router) before use.\r\n */\r\nexport const useRoute = defineInjectable<RouteLocation>(() => {\r\n throw new Error(\r\n 'useRoute() is called but no router is installed. ' +\r\n 'Make sure to install the router with app.use(router).'\r\n );\r\n});\r\n\r\n/**\r\n * Create a router instance\r\n * \r\n * @example\r\n * ```ts\r\n * import { createRouter } from '@sigx/router';\r\n * import { createWebHistory } from '@sigx/router/history';\r\n * \r\n * const router = createRouter({\r\n * history: createWebHistory(),\r\n * routes: [\r\n * { path: '/', component: Home },\r\n * { path: '/about', component: About },\r\n * { path: '/blog/:slug', component: BlogPost }\r\n * ]\r\n * });\r\n * ```\r\n */\r\nexport function createRouter(options: RouterOptions): Router {\r\n const { history, routes } = options;\r\n const base = options.base || '';\r\n \r\n // Compile routes for efficient matching\r\n let compiledRoutes = compileRoutes(routes);\r\n \r\n // Route storage for dynamic routes\r\n const routeRecords = [...routes];\r\n \r\n // Navigation guards\r\n const beforeGuards: NavigationGuard[] = [];\r\n const beforeResolveGuards: NavigationGuard[] = [];\r\n const afterHooks: NavigationHookAfter[] = [];\r\n \r\n // Ready promise\r\n let readyPromise: Promise<void> | null = null;\r\n let readyResolve: (() => void) | null = null;\r\n \r\n // Create initial route\r\n const initialLocation = history.location;\r\n \r\n const initialMatch = matchRoute(initialLocation, compiledRoutes);\r\n \r\n const initialRoute = createRouteLocation(\r\n initialLocation,\r\n initialMatch?.route || null,\r\n initialMatch?.params || {}\r\n );\r\n \r\n // Reactive current route state\r\n const currentRouteState = signal(initialRoute);\r\n \r\n // Track pending navigation\r\n let pendingNavigation: Promise<RouteLocation | void> | null = null;\r\n \r\n // Guard to prevent double finalizeNavigation during programmatic navigation.\r\n // history.push() triggers the history listener which calls finalizeNavigation,\r\n // so we skip the listener during navigate() to avoid redundant reactive updates.\r\n let isNavigating = false;\r\n \r\n /**\r\n * Resolve a raw location to a full RouteLocation\r\n */\r\n function resolve(to: RouteLocationRaw): RouteLocation {\r\n // String path\r\n if (typeof to === 'string') {\r\n const match = matchRoute(to, compiledRoutes);\r\n return createRouteLocation(to, match?.route || null, match?.params || {});\r\n }\r\n \r\n // Object location\r\n const { path, name, params = {}, query = {}, hash = '' } = to;\r\n \r\n // Named route\r\n if (name) {\r\n const route = compiledRoutes.find(r => r.record.name === name);\r\n if (!route) {\r\n console.warn(`Route with name \"${name}\" not found`);\r\n return createRouteLocation('/', null, {});\r\n }\r\n \r\n // Build path from params\r\n const resolvedPath = buildPathFromParams(route.record.path, params);\r\n const fullPath = buildPath(resolvedPath, query, hash);\r\n return createRouteLocation(fullPath, route, params);\r\n }\r\n \r\n // Path-based\r\n if (path) {\r\n const fullPath = buildPath(path, query, hash);\r\n const match = matchRoute(path, compiledRoutes);\r\n return createRouteLocation(fullPath, match?.route || null, match?.params || {});\r\n }\r\n \r\n // Invalid - return current\r\n return getCurrentRoute();\r\n }\r\n \r\n /**\r\n * Build path from params\r\n */\r\n function buildPathFromParams(pattern: string, params: RouteParams): string {\r\n let path = pattern;\r\n for (const key in params) {\r\n path = path.replace(`:${key}`, encodeURIComponent(params[key]));\r\n }\r\n // Remove optional params that weren't provided\r\n path = path.replace(/\\/:[^/]+\\?/g, '');\r\n return path;\r\n }\r\n \r\n /**\r\n * Get current route\r\n */\r\n function getCurrentRoute(): RouteLocation {\r\n // The signal object has the RouteLocation properties directly on it\r\n // We return the signal which has been assigned RouteLocation properties\r\n const state = currentRouteState;\r\n return {\r\n fullPath: state.fullPath,\r\n path: state.path,\r\n name: state.name,\r\n params: state.params,\r\n query: state.query,\r\n hash: state.hash,\r\n matched: state.matched,\r\n meta: state.meta,\r\n redirectedFrom: state.redirectedFrom\r\n };\r\n }\r\n \r\n /**\r\n * Run navigation guards\r\n */\r\n async function runGuards(\r\n to: RouteLocation,\r\n from: RouteLocation | null,\r\n guards: NavigationGuard[]\r\n ): Promise<boolean | RouteLocation | void> {\r\n for (const guard of guards) {\r\n const result = await guard(to, from);\r\n \r\n // Guard returned false - abort\r\n if (result === false) {\r\n return false;\r\n }\r\n \r\n // Guard returned string path - redirect\r\n if (typeof result === 'string') {\r\n return resolve(result);\r\n }\r\n \r\n // Guard returned location object - redirect\r\n if (result && typeof result === 'object') {\r\n return resolve(result);\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n \r\n /**\r\n * Finalize navigation\r\n */\r\n function finalizeNavigation(to: RouteLocation, from: RouteLocation | null): void {\r\n // Update reactive state using $set for proper reactivity triggering\r\n (currentRouteState as any).$set(to);\r\n \r\n // Run after hooks\r\n for (const hook of afterHooks) {\r\n hook(to, from);\r\n }\r\n }\r\n \r\n /**\r\n * Navigate to a location\r\n */\r\n async function navigate(\r\n to: RouteLocationRaw,\r\n replace = false\r\n ): Promise<RouteLocation | void> {\r\n const from = getCurrentRoute();\r\n const resolved = resolve(to);\r\n \r\n // Handle redirect - check the DEEPEST matched route (last in array) for redirect\r\n // Only the actual target route should trigger a redirect, not parent routes\r\n const matched = resolved.matched[resolved.matched.length - 1];\r\n if (matched) {\r\n const routeRecord = compiledRoutes.find(r => r.record.path === matched.path)?.record;\r\n if (routeRecord?.redirect) {\r\n const redirectTo = typeof routeRecord.redirect === 'function'\r\n ? routeRecord.redirect(resolved)\r\n : routeRecord.redirect;\r\n return navigate(redirectTo, replace);\r\n }\r\n }\r\n \r\n // Run before guards\r\n const beforeResult = await runGuards(resolved, from, beforeGuards);\r\n if (beforeResult === false) return;\r\n if (beforeResult && typeof beforeResult === 'object') {\r\n return navigate(beforeResult, replace);\r\n }\r\n \r\n // Run route-specific guards\r\n for (const record of resolved.matched) {\r\n const routeRecord = compiledRoutes.find(r => r.record.path === record.path)?.record;\r\n if (routeRecord?.beforeEnter) {\r\n const guards = Array.isArray(routeRecord.beforeEnter)\r\n ? routeRecord.beforeEnter\r\n : [routeRecord.beforeEnter];\r\n const result = await runGuards(resolved, from, guards);\r\n if (result === false) return;\r\n if (result && typeof result === 'object') {\r\n return navigate(result, replace);\r\n }\r\n }\r\n }\r\n \r\n // Run before resolve guards\r\n const resolveResult = await runGuards(resolved, from, beforeResolveGuards);\r\n if (resolveResult === false) return;\r\n if (resolveResult && typeof resolveResult === 'object') {\r\n return navigate(resolveResult, replace);\r\n }\r\n \r\n // Finalize navigation first (updates reactive state)\r\n isNavigating = true;\r\n finalizeNavigation(resolved, from);\r\n \r\n // Then update history — the listener will skip because isNavigating is true\r\n if (replace) {\r\n history.replace(resolved.fullPath);\r\n } else {\r\n history.push(resolved.fullPath);\r\n }\r\n isNavigating = false;\r\n \r\n return resolved;\r\n }\r\n \r\n // Listen for history changes (back/forward)\r\n // Skips during programmatic navigation (push/replace) to avoid double finalizeNavigation.\r\n history.listen((to, from, state) => {\r\n if (isNavigating) return;\r\n const match = matchRoute(to, compiledRoutes);\r\n const resolved = createRouteLocation(to, match?.route || null, match?.params || {});\r\n finalizeNavigation(resolved, getCurrentRoute());\r\n });\r\n \r\n const router: Router = {\r\n get currentRoute() {\r\n return getCurrentRoute();\r\n },\r\n \r\n get options() {\r\n return options;\r\n },\r\n \r\n push(to) {\r\n return navigate(to, false);\r\n },\r\n \r\n replace(to) {\r\n return navigate(to, true);\r\n },\r\n \r\n back() {\r\n history.go(-1);\r\n },\r\n \r\n forward() {\r\n history.go(1);\r\n },\r\n \r\n go(delta) {\r\n history.go(delta);\r\n },\r\n \r\n beforeEach(guard) {\r\n beforeGuards.push(guard);\r\n return () => {\r\n const index = beforeGuards.indexOf(guard);\r\n if (index !== -1) beforeGuards.splice(index, 1);\r\n };\r\n },\r\n \r\n beforeResolve(guard) {\r\n beforeResolveGuards.push(guard);\r\n return () => {\r\n const index = beforeResolveGuards.indexOf(guard);\r\n if (index !== -1) beforeResolveGuards.splice(index, 1);\r\n };\r\n },\r\n \r\n afterEach(hook) {\r\n afterHooks.push(hook);\r\n return () => {\r\n const index = afterHooks.indexOf(hook);\r\n if (index !== -1) afterHooks.splice(index, 1);\r\n };\r\n },\r\n \r\n hasRoute(name) {\r\n return routeRecords.some(r => r.name === name);\r\n },\r\n \r\n getRoutes() {\r\n return [...routeRecords];\r\n },\r\n \r\n addRoute(route, parentName) {\r\n if (parentName) {\r\n const parent = routeRecords.find(r => r.name === parentName);\r\n if (parent) {\r\n parent.children = parent.children || [];\r\n parent.children.push(route);\r\n }\r\n } else {\r\n routeRecords.push(route);\r\n }\r\n \r\n // Recompile routes\r\n compiledRoutes = compileRoutes(routeRecords);\r\n \r\n // Return a function to remove the route\r\n // If route has no name, we need to track it differently\r\n const routeRef = route;\r\n return () => {\r\n if (routeRef.name) {\r\n router.removeRoute(routeRef.name);\r\n } else {\r\n // Remove by reference\r\n const index = routeRecords.indexOf(routeRef);\r\n if (index !== -1) {\r\n routeRecords.splice(index, 1);\r\n compiledRoutes = compileRoutes(routeRecords);\r\n }\r\n }\r\n };\r\n },\r\n \r\n removeRoute(name) {\r\n const index = routeRecords.findIndex(r => r.name === name);\r\n if (index !== -1) {\r\n routeRecords.splice(index, 1);\r\n compiledRoutes = compileRoutes(routeRecords);\r\n }\r\n },\r\n \r\n resolve,\r\n \r\n match<T>(patterns: RouteMatchPatterns<T>): T | undefined {\r\n const route = getCurrentRoute();\r\n const routeName = route.name;\r\n \r\n // Try to match by route name\r\n if (routeName && routeName in patterns) {\r\n const pattern = patterns[routeName];\r\n if (typeof pattern === 'function') {\r\n return (pattern as (params: RouteParams) => T)(route.params);\r\n }\r\n return pattern as T;\r\n }\r\n \r\n // Fall back to catch-all pattern\r\n if ('_' in patterns) {\r\n const fallback = patterns._;\r\n if (typeof fallback === 'function') {\r\n return (fallback as (params: RouteParams) => T)(route.params);\r\n }\r\n return fallback as T;\r\n }\r\n \r\n return undefined;\r\n },\r\n \r\n install(app) {\r\n // Provide router and current route at app level\r\n app.defineProvide(useRouter, () => router);\r\n app.defineProvide(useRoute, () => currentRouteState as unknown as RouteLocation);\r\n \r\n // Mark router as ready\r\n if (readyResolve) {\r\n readyResolve();\r\n }\r\n },\r\n \r\n isReady() {\r\n if (!readyPromise) {\r\n readyPromise = new Promise(resolve => {\r\n readyResolve = resolve;\r\n });\r\n }\r\n return readyPromise;\r\n }\r\n };\r\n \r\n return router;\r\n}\r\n","/**\r\n * Browser history implementation using the History API\r\n * \r\n * This is the default history for client-side navigation.\r\n */\r\n\r\nimport type { RouterHistory, HistoryState } from '../types.js';\r\n\r\nexport interface BrowserHistoryOptions {\r\n /** Base path for the application */\r\n base?: string;\r\n}\r\n\r\n/**\r\n * Create a browser history instance that uses the HTML5 History API\r\n */\r\nexport function createWebHistory(options: BrowserHistoryOptions = {}): RouterHistory {\r\n const base = normalizeBase(options.base);\r\n const listeners: Set<(to: string, from: string, state: HistoryState | null) => void> = new Set();\r\n \r\n let currentLocation = getCurrentLocation(base);\r\n let currentState = (typeof window !== 'undefined' ? window.history.state : null) as HistoryState | null;\r\n \r\n // Handle browser back/forward\r\n const handlePopState = (event: PopStateEvent) => {\r\n const from = currentLocation;\r\n currentLocation = getCurrentLocation(base);\r\n currentState = event.state as HistoryState | null;\r\n \r\n listeners.forEach(callback => {\r\n callback(currentLocation, from, currentState);\r\n });\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', handlePopState);\r\n }\r\n \r\n const history: RouterHistory = {\r\n get location() {\r\n return currentLocation;\r\n },\r\n \r\n get state() {\r\n return currentState;\r\n },\r\n \r\n get base() {\r\n return base;\r\n },\r\n \r\n push(to: string, state?: HistoryState) {\r\n const from = currentLocation;\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n const fullPath = base === '/' ? to : base + to;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: (currentState?.position ?? 0) + 1\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.history.pushState(historyState, '', fullPath);\r\n }\r\n currentLocation = to;\r\n currentState = historyState;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n replace(to: string, state?: HistoryState) {\r\n const from = currentLocation;\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n const fullPath = base === '/' ? to : base + to;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentState?.position ?? 0\r\n };\r\n \r\n if (typeof window !== 'undefined') {\r\n window.history.replaceState(historyState, '', fullPath);\r\n }\r\n currentLocation = to;\r\n currentState = historyState;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n go(delta: number) {\r\n if (typeof window !== 'undefined') {\r\n window.history.go(delta);\r\n }\r\n },\r\n \r\n listen(callback) {\r\n listeners.add(callback);\r\n return () => {\r\n listeners.delete(callback);\r\n };\r\n },\r\n \r\n createHref(path: string) {\r\n // Avoid double slashes when base is '/' and path also starts with '/'\r\n return base === '/' ? path : base + path;\r\n },\r\n \r\n destroy() {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('popstate', handlePopState);\r\n }\r\n listeners.clear();\r\n }\r\n };\r\n \r\n return history;\r\n}\r\n\r\n/**\r\n * Normalize the base path\r\n */\r\nfunction normalizeBase(base?: string): string {\r\n if (!base) {\r\n // Use <base> tag if available\r\n if (typeof document !== 'undefined') {\r\n const baseTag = document.querySelector('base');\r\n if (baseTag) {\r\n base = baseTag.getAttribute('href') || '/';\r\n }\r\n }\r\n base = base || '/';\r\n }\r\n \r\n // Ensure base starts with /\r\n if (!base.startsWith('/')) {\r\n base = '/' + base;\r\n }\r\n \r\n // Remove trailing slash\r\n if (base !== '/' && base.endsWith('/')) {\r\n base = base.slice(0, -1);\r\n }\r\n \r\n return base;\r\n}\r\n\r\n/**\r\n * Get current location from window, stripping the base\r\n */\r\nfunction getCurrentLocation(base: string): string {\r\n if (typeof window === 'undefined') {\r\n return '/';\r\n }\r\n \r\n const { pathname, search, hash } = window.location;\r\n let path = pathname;\r\n \r\n // Strip base from path\r\n if (base !== '/' && pathname.startsWith(base)) {\r\n path = pathname.slice(base.length) || '/';\r\n }\r\n \r\n return path + search + hash;\r\n}\r\n","/**\r\n * Memory history implementation for SSR\r\n * \r\n * This history doesn't interact with the browser History API,\r\n * making it suitable for server-side rendering.\r\n */\r\n\r\nimport type { RouterHistory, HistoryState } from '../types.js';\r\n\r\nexport interface MemoryHistoryOptions {\r\n /** Base path for the application */\r\n base?: string;\r\n /** Initial location */\r\n initialLocation?: string;\r\n}\r\n\r\ninterface HistoryEntry {\r\n location: string;\r\n state: HistoryState | null;\r\n}\r\n\r\n/**\r\n * Create a memory history instance for SSR\r\n * \r\n * @example\r\n * ```ts\r\n * // Server-side\r\n * const history = createMemoryHistory({ initialLocation: req.url });\r\n * const router = createRouter({ routes, history });\r\n * ```\r\n */\r\nexport function createMemoryHistory(options: MemoryHistoryOptions = {}): RouterHistory {\r\n const base = options.base || '';\r\n const initialLocation = options.initialLocation || '/';\r\n \r\n const listeners: Set<(to: string, from: string, state: HistoryState | null) => void> = new Set();\r\n \r\n // History stack for back/forward navigation\r\n const entries: HistoryEntry[] = [\r\n { location: initialLocation, state: { path: initialLocation, position: 0 } }\r\n ];\r\n let currentIndex = 0;\r\n \r\n const history: RouterHistory = {\r\n get location() {\r\n return entries[currentIndex].location;\r\n },\r\n \r\n get state() {\r\n return entries[currentIndex].state;\r\n },\r\n \r\n get base() {\r\n return base;\r\n },\r\n \r\n push(to: string, state?: HistoryState) {\r\n const from = entries[currentIndex].location;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentIndex + 1\r\n };\r\n \r\n // Remove any forward entries\r\n entries.splice(currentIndex + 1);\r\n \r\n // Add new entry\r\n entries.push({ location: to, state: historyState });\r\n currentIndex = entries.length - 1;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n replace(to: string, state?: HistoryState) {\r\n const from = entries[currentIndex].location;\r\n const historyState: HistoryState = {\r\n ...state,\r\n path: to,\r\n position: currentIndex\r\n };\r\n \r\n // Replace current entry\r\n entries[currentIndex] = { location: to, state: historyState };\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, historyState);\r\n });\r\n },\r\n \r\n go(delta: number) {\r\n const newIndex = currentIndex + delta;\r\n \r\n if (newIndex < 0 || newIndex >= entries.length) {\r\n return;\r\n }\r\n \r\n const from = entries[currentIndex].location;\r\n currentIndex = newIndex;\r\n const to = entries[currentIndex].location;\r\n const state = entries[currentIndex].state;\r\n \r\n listeners.forEach(callback => {\r\n callback(to, from, state);\r\n });\r\n },\r\n \r\n listen(callback) {\r\n listeners.add(callback);\r\n return () => {\r\n listeners.delete(callback);\r\n };\r\n },\r\n \r\n createHref(path: string) {\r\n return base + path;\r\n },\r\n \r\n destroy() {\r\n listeners.clear();\r\n }\r\n };\r\n \r\n return history;\r\n}\r\n","/**\r\n * Router hooks for @sigx/router\r\n * \r\n * These hooks provide access to router state and navigation within components.\r\n */\r\n\r\nimport { getCurrentInstance } from 'sigx';\r\nimport type { Router, RouteLocation, RouteParams, RouteQuery } from './types.js';\r\nimport { useRouter, useRoute } from './router.js';\r\n\r\n// Re-export the injectable hooks from router.ts\r\nexport { useRouter, useRoute };\r\n\r\n/**\r\n * Get route parameters (reactive)\r\n * \r\n * @example\r\n * ```tsx\r\n * const params = useParams();\r\n * console.log(params.id);\r\n * ```\r\n */\r\nexport function useParams(): RouteParams {\r\n const route = useRoute();\r\n return route.params;\r\n}\r\n\r\n/**\r\n * Get query parameters (reactive)\r\n * \r\n * @example\r\n * ```tsx\r\n * const query = useQuery();\r\n * console.log(query.search);\r\n * ```\r\n */\r\nexport function useQuery(): RouteQuery {\r\n const route = useRoute();\r\n return route.query;\r\n}\r\n\r\n/**\r\n * Get a navigate function for programmatic navigation\r\n * \r\n * @example\r\n * ```tsx\r\n * const navigate = useNavigate();\r\n * navigate('/about');\r\n * navigate({ path: '/blog', query: { page: '2' } });\r\n * ```\r\n */\r\nexport function useNavigate() {\r\n const router = useRouter();\r\n return router.push.bind(router);\r\n}\r\n\r\n/**\r\n * Guard type for route enter\r\n */\r\ntype RouteEnterGuard = (\r\n to: RouteLocation,\r\n from: RouteLocation | null,\r\n next: (to?: string | false | RouteLocation) => void\r\n) => void;\r\n\r\n/**\r\n * Guard type for route leave\r\n */\r\ntype RouteLeaveGuard = (\r\n to: RouteLocation,\r\n from: RouteLocation,\r\n next: (to?: string | false | RouteLocation) => void\r\n) => void;\r\n\r\n/**\r\n * Register a navigation guard that runs before leaving the current route\r\n * \r\n * @example\r\n * ```tsx\r\n * onBeforeRouteLeave((to, from, next) => {\r\n * if (hasUnsavedChanges) {\r\n * const answer = confirm('You have unsaved changes. Leave anyway?');\r\n * if (!answer) {\r\n * next(false);\r\n * return;\r\n * }\r\n * }\r\n * next();\r\n * });\r\n * ```\r\n */\r\nexport function onBeforeRouteLeave(guard: RouteLeaveGuard): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n console.warn('onBeforeRouteLeave() is called outside of component setup');\r\n return;\r\n }\r\n \r\n const router = useRouter();\r\n \r\n // Register guard\r\n const unregister = router.beforeEach((to, from) => {\r\n if (!from) return;\r\n \r\n // Only run if leaving current component's route\r\n const currentRoute = useRoute();\r\n if (from.path !== currentRoute.path) return;\r\n \r\n return new Promise((resolve) => {\r\n guard(to, from, (result) => {\r\n if (result === false) {\r\n resolve(false);\r\n } else if (typeof result === 'string') {\r\n resolve(result);\r\n } else if (result && typeof result === 'object') {\r\n resolve(result);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n });\r\n \r\n // Unregister when component unmounts\r\n ctx.onUnmounted(() => {\r\n unregister();\r\n });\r\n}\r\n\r\n/**\r\n * Register a navigation guard that runs when entering the current route\r\n * \r\n * @example\r\n * ```tsx\r\n * onBeforeRouteUpdate((to, from, next) => {\r\n * // Called when route params change but component is reused\r\n * next();\r\n * });\r\n * ```\r\n */\r\nexport function onBeforeRouteUpdate(guard: RouteEnterGuard): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n console.warn('onBeforeRouteUpdate() is called outside of component setup');\r\n return;\r\n }\r\n \r\n const router = useRouter();\r\n const currentRoute = useRoute();\r\n \r\n // Register guard\r\n const unregister = router.beforeEach((to, from) => {\r\n // Only run if route path is the same (update, not leave)\r\n if (to.path !== currentRoute.path) return;\r\n \r\n return new Promise((resolve) => {\r\n guard(to, from, (result) => {\r\n if (result === false) {\r\n resolve(false);\r\n } else if (typeof result === 'string') {\r\n resolve(result);\r\n } else if (result && typeof result === 'object') {\r\n resolve(result);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n });\r\n \r\n // Unregister when component unmounts\r\n ctx.onUnmounted(() => {\r\n unregister();\r\n });\r\n}\r\n","/**\r\n * RouterView component - renders the matched route component\r\n * \r\n * @example\r\n * ```tsx\r\n * <RouterView />\r\n * \r\n * // With named views (for nested routes)\r\n * <RouterView name=\"sidebar\" />\r\n * \r\n * // With page props (from SSG getStaticProps)\r\n * <RouterView pageProps={{ posts: [...] }} />\r\n * ```\r\n */\r\n\r\nimport { component, type DefineProp, type ComponentFactory, defineInjectable, defineProvide } from 'sigx';\r\nimport { useRoute } from './hooks.js';\r\n\r\ntype RouterViewProps = DefineProp<'name', string> & DefineProp<'pageProps', Record<string, unknown>>;\r\n\r\n/**\r\n * Injectable for tracking RouterView depth.\r\n * Each nested RouterView increments the depth to render the correct matched route.\r\n */\r\nconst useRouterViewDepth = defineInjectable<number>(() => 0);\r\n\r\n/**\r\n * Type guard to check if a component is a SignalX component factory\r\n */\r\nfunction isComponentFactory(component: unknown): component is ComponentFactory<any, any, any> {\r\n return typeof component === 'function' && '__setup' in component;\r\n}\r\n\r\nexport const RouterView = component<RouterViewProps>((ctx) => {\r\n // Read props reactively inside the render function\r\n const route = useRoute();\r\n \r\n // Get current depth from parent RouterView (0 if we're the root)\r\n const depth = useRouterViewDepth();\r\n \r\n // Provide incremented depth for child RouterViews\r\n defineProvide(useRouterViewDepth, () => depth + 1);\r\n \r\n return () => {\r\n // Read pageProps at render time for reactivity\r\n const { name = 'default', pageProps = {} } = ctx.props;\r\n const matched = route.matched;\r\n \r\n if (matched.length === 0 || depth >= matched.length) {\r\n // No matched route at this depth - render nothing or fallback\r\n return null;\r\n }\r\n \r\n // Get the matched route at current depth\r\n const match = matched[depth];\r\n const Component = match.component;\r\n \r\n if (!Component) {\r\n return null;\r\n }\r\n \r\n // Handle lazy components - check if it's a SignalX component factory\r\n if (!isComponentFactory(Component)) {\r\n // This is a lazy import function or other callable\r\n // TODO: Integrate with Suspense when available\r\n return null;\r\n }\r\n \r\n // Calculate props for component\r\n let componentProps: Record<string, any> = {};\r\n \r\n if (match.props === true) {\r\n // Pass route params as props\r\n componentProps = { ...route.params };\r\n } else if (typeof match.props === 'function') {\r\n componentProps = match.props(route);\r\n } else if (match.props && typeof match.props === 'object') {\r\n componentProps = { ...match.props };\r\n }\r\n \r\n // Merge in pageProps from getStaticProps (SSG)\r\n if (pageProps && Object.keys(pageProps).length > 0) {\r\n componentProps = { ...componentProps, ...pageProps };\r\n }\r\n \r\n // Render the component - Component is now properly typed as ComponentFactory\r\n // Use match.path as key to force unmount/remount when route changes.\r\n // This prevents lazy() components from stacking instead of replacing.\r\n return <Component key={match.path} {...componentProps} />;\r\n };\r\n}, { name: 'RouterView' });\r\n","/**\r\n * Link component - declarative navigation\r\n * \r\n * @example\r\n * ```tsx\r\n * <Link to=\"/about\">About</Link>\r\n * \r\n * <Link to={{ path: '/blog', query: { page: '2' } }}>Blog</Link>\r\n * \r\n * <Link to=\"/contact\" replace>Contact</Link>\r\n * ```\r\n */\r\n\r\nimport { component, type DefineProp, type DefineEvent, type DefineSlot } from 'sigx';\r\nimport { useRouter, useRoute } from './hooks.js';\r\nimport type { RouteLocationRaw } from './types.js';\r\n\r\ntype LinkProps = \r\n & DefineProp<'to', RouteLocationRaw, true>\r\n & DefineProp<'replace', boolean>\r\n & DefineProp<'activeClass', string>\r\n & DefineProp<'exactActiveClass', string>\r\n & DefineProp<'ariaCurrentValue', 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false'>\r\n & DefineEvent<'click', MouseEvent>\r\n & DefineSlot<'default'>;\r\n\r\nexport const Link = component<LinkProps>(({ props, slots, emit }) => {\r\n const router = useRouter();\r\n const currentRoute = useRoute();\r\n \r\n // Apply defaults\r\n const replace = () => props.replace ?? false;\r\n const activeClass = () => props.activeClass ?? 'router-link-active';\r\n const exactActiveClass = () => props.exactActiveClass ?? 'router-link-exact-active';\r\n const ariaCurrentValue = () => props.ariaCurrentValue ?? 'page';\r\n \r\n const handleClick = (event: MouseEvent) => {\r\n // Emit click event\r\n emit('click', event);\r\n \r\n // Don't navigate if:\r\n // - Default prevented\r\n // - Meta key pressed (new tab)\r\n // - Ctrl key pressed (new tab)\r\n // - Shift key pressed (new window)\r\n // - Right click\r\n if (\r\n event.defaultPrevented ||\r\n event.metaKey ||\r\n event.ctrlKey ||\r\n event.shiftKey ||\r\n event.button !== 0\r\n ) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n \r\n if (replace()) {\r\n router.replace(props.to);\r\n } else {\r\n router.push(props.to);\r\n }\r\n };\r\n \r\n return () => {\r\n const resolved = router.resolve(props.to);\r\n const href = resolved.fullPath;\r\n \r\n // Determine active state\r\n const isExactActive = currentRoute.path === resolved.path;\r\n const isActive = currentRoute.path.startsWith(resolved.path);\r\n \r\n // Build class list\r\n const classes: string[] = [];\r\n if (isActive && activeClass()) {\r\n classes.push(activeClass());\r\n }\r\n if (isExactActive && exactActiveClass()) {\r\n classes.push(exactActiveClass());\r\n }\r\n \r\n return (\r\n <a\r\n href={href}\r\n onClick={handleClick}\r\n class={classes.length > 0 ? classes.join(' ') : undefined}\r\n aria-current={isExactActive ? ariaCurrentValue() : undefined}\r\n >\r\n {slots.default()}\r\n </a>\r\n );\r\n };\r\n}, { name: 'Link' });\r\n\r\n/**\r\n * Alias for Link component\r\n */\r\nexport const RouterLink = Link;\r\n","/**\r\n * Router plugin for @sigx/router\r\n * \r\n * Integrates the router with the SignalX app system.\r\n */\r\n\r\nimport type { Plugin, App } from 'sigx';\r\nimport type { Router, RouterOptions, RouteRecordRaw, RouterHistory } from './types.js';\r\nimport { createRouter } from './router.js';\r\n\r\n/**\r\n * Router plugin options\r\n */\r\nexport interface RouterPluginOptions {\r\n /** Route definitions */\r\n routes: RouteRecordRaw[];\r\n /** History implementation */\r\n history: RouterHistory;\r\n /** Base URL */\r\n base?: string;\r\n}\r\n\r\n/**\r\n * Create a router plugin for use with app.use()\r\n * \r\n * @example\r\n * ```tsx\r\n * import { defineApp } from '@sigx/runtime-core';\r\n * import { createRouterPlugin, createWebHistory } from '@sigx/router';\r\n * \r\n * const routerPlugin = createRouterPlugin({\r\n * history: createWebHistory(),\r\n * routes: [\r\n * { path: '/', component: Home },\r\n * { path: '/about', component: About }\r\n * ]\r\n * });\r\n * \r\n * const app = defineApp(<App />);\r\n * app.use(routerPlugin);\r\n * app.mount('#app');\r\n * ```\r\n */\r\nexport function createRouterPlugin(options: RouterPluginOptions): Plugin & { router: Router } {\r\n const router = createRouter(options);\r\n \r\n return {\r\n name: '@sigx/router',\r\n router,\r\n \r\n install(app) {\r\n router.install(app);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Alternative API: Create router and install in one step\r\n * \r\n * @example\r\n * ```tsx\r\n * const router = createRouter({ routes, history });\r\n * \r\n * const app = defineApp(<App />);\r\n * app.use(router); // Router implements Plugin interface\r\n * ```\r\n */\r\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACR,MAAM,EACN,aAAa,EACb,aAAa,EAOhB,MAAM,YAAY,CAAC;AAUpB;;;GAGG;AACH,eAAO,MAAM,SAAS,yDAKpB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,QAAQ,gEAKnB,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAmX3D"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACR,MAAM,EACN,aAAa,EACb,aAAa,EAOhB,MAAM,YAAY,CAAC;AAUpB;;;GAGG;AACH,eAAO,MAAM,SAAS,yDAKpB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,QAAQ,gEAKnB,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CA4X3D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigx/router",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Router for SignalX with SSR support and hooks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,19 +33,19 @@
33
33
  "url": "https://github.com/signalxjs/core/issues"
34
34
  },
35
35
  "peerDependencies": {
36
- "sigx": "^0.1.9"
36
+ "sigx": "^0.1.11"
37
37
  },
38
38
  "dependencies": {
39
- "@sigx/reactivity": "^0.1.9",
40
- "@sigx/runtime-core": "^0.1.9",
41
- "@sigx/runtime-dom": "^0.1.9"
39
+ "@sigx/reactivity": "^0.1.11",
40
+ "@sigx/runtime-core": "^0.1.11",
41
+ "@sigx/runtime-dom": "^0.1.11"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^20.0.0",
45
45
  "typescript": "^5.9.3",
46
46
  "vite": "^8.0.0-beta.9",
47
- "@sigx/vite": "^0.1.9",
48
- "sigx": "^0.1.9"
47
+ "@sigx/vite": "^0.1.11",
48
+ "sigx": "^0.1.11"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "vite build && tsc --emitDeclarationOnly",