@buzola/router 0.0.1

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.
Files changed (114) hide show
  1. package/dist/__tests__/create-page.test.d.ts +2 -0
  2. package/dist/__tests__/create-page.test.d.ts.map +1 -0
  3. package/dist/__tests__/create-page.test.js +457 -0
  4. package/dist/__tests__/create-page.test.js.map +1 -0
  5. package/dist/__tests__/define-routes.test.d.ts +2 -0
  6. package/dist/__tests__/define-routes.test.d.ts.map +1 -0
  7. package/dist/__tests__/define-routes.test.js +42 -0
  8. package/dist/__tests__/define-routes.test.js.map +1 -0
  9. package/dist/__tests__/matcher.test.d.ts +2 -0
  10. package/dist/__tests__/matcher.test.d.ts.map +1 -0
  11. package/dist/__tests__/matcher.test.js +108 -0
  12. package/dist/__tests__/matcher.test.js.map +1 -0
  13. package/dist/__tests__/router.test.d.ts +2 -0
  14. package/dist/__tests__/router.test.d.ts.map +1 -0
  15. package/dist/__tests__/router.test.js +327 -0
  16. package/dist/__tests__/router.test.js.map +1 -0
  17. package/dist/__tests__/type-safety.test.d.ts +15 -0
  18. package/dist/__tests__/type-safety.test.d.ts.map +1 -0
  19. package/dist/__tests__/type-safety.test.js +163 -0
  20. package/dist/__tests__/type-safety.test.js.map +1 -0
  21. package/dist/__tests__/types.test.d.ts +2 -0
  22. package/dist/__tests__/types.test.d.ts.map +1 -0
  23. package/dist/__tests__/types.test.js +22 -0
  24. package/dist/__tests__/types.test.js.map +1 -0
  25. package/dist/define/create-page.d.ts +87 -0
  26. package/dist/define/create-page.d.ts.map +1 -0
  27. package/dist/define/create-page.js +305 -0
  28. package/dist/define/create-page.js.map +1 -0
  29. package/dist/define/define-routes.d.ts +34 -0
  30. package/dist/define/define-routes.d.ts.map +1 -0
  31. package/dist/define/define-routes.js +53 -0
  32. package/dist/define/define-routes.js.map +1 -0
  33. package/dist/engine/matcher.d.ts +8 -0
  34. package/dist/engine/matcher.d.ts.map +1 -0
  35. package/dist/engine/matcher.js +79 -0
  36. package/dist/engine/matcher.js.map +1 -0
  37. package/dist/engine/navigation-adapter.d.ts +13 -0
  38. package/dist/engine/navigation-adapter.d.ts.map +1 -0
  39. package/dist/engine/navigation-adapter.js +156 -0
  40. package/dist/engine/navigation-adapter.js.map +1 -0
  41. package/dist/engine/route-tree.d.ts +21 -0
  42. package/dist/engine/route-tree.d.ts.map +1 -0
  43. package/dist/engine/route-tree.js +95 -0
  44. package/dist/engine/route-tree.js.map +1 -0
  45. package/dist/engine/router.d.ts +162 -0
  46. package/dist/engine/router.d.ts.map +1 -0
  47. package/dist/engine/router.js +400 -0
  48. package/dist/engine/router.js.map +1 -0
  49. package/dist/engine/schema.d.ts +46 -0
  50. package/dist/engine/schema.d.ts.map +1 -0
  51. package/dist/engine/schema.js +110 -0
  52. package/dist/engine/schema.js.map +1 -0
  53. package/dist/engine/types.d.ts +183 -0
  54. package/dist/engine/types.d.ts.map +1 -0
  55. package/dist/engine/types.js +2 -0
  56. package/dist/engine/types.js.map +1 -0
  57. package/dist/engine/utils.d.ts +7 -0
  58. package/dist/engine/utils.d.ts.map +1 -0
  59. package/dist/engine/utils.js +17 -0
  60. package/dist/engine/utils.js.map +1 -0
  61. package/dist/index.d.ts +14 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +12 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/react/context.d.ts +21 -0
  66. package/dist/react/context.d.ts.map +1 -0
  67. package/dist/react/context.js +7 -0
  68. package/dist/react/context.js.map +1 -0
  69. package/dist/react/error-boundary.d.ts +24 -0
  70. package/dist/react/error-boundary.d.ts.map +1 -0
  71. package/dist/react/error-boundary.js +37 -0
  72. package/dist/react/error-boundary.js.map +1 -0
  73. package/dist/react/hooks.d.ts +85 -0
  74. package/dist/react/hooks.d.ts.map +1 -0
  75. package/dist/react/hooks.js +161 -0
  76. package/dist/react/hooks.js.map +1 -0
  77. package/dist/react/index.d.ts +12 -0
  78. package/dist/react/index.d.ts.map +1 -0
  79. package/dist/react/index.js +7 -0
  80. package/dist/react/index.js.map +1 -0
  81. package/dist/react/link.d.ts +42 -0
  82. package/dist/react/link.d.ts.map +1 -0
  83. package/dist/react/link.js +38 -0
  84. package/dist/react/link.js.map +1 -0
  85. package/dist/react/outlet.d.ts +13 -0
  86. package/dist/react/outlet.d.ts.map +1 -0
  87. package/dist/react/outlet.js +46 -0
  88. package/dist/react/outlet.js.map +1 -0
  89. package/dist/react/provider.d.ts +22 -0
  90. package/dist/react/provider.d.ts.map +1 -0
  91. package/dist/react/provider.js +37 -0
  92. package/dist/react/provider.js.map +1 -0
  93. package/package.json +29 -0
  94. package/src/__tests__/create-page.test.ts +588 -0
  95. package/src/__tests__/matcher.test.ts +127 -0
  96. package/src/__tests__/router.test.ts +424 -0
  97. package/src/__tests__/type-safety.test.tsx +207 -0
  98. package/src/define/create-page.tsx +472 -0
  99. package/src/engine/matcher.ts +88 -0
  100. package/src/engine/navigation-adapter.ts +191 -0
  101. package/src/engine/route-tree.ts +129 -0
  102. package/src/engine/router.ts +471 -0
  103. package/src/engine/schema.ts +130 -0
  104. package/src/engine/types.ts +203 -0
  105. package/src/engine/utils.ts +16 -0
  106. package/src/env.d.ts +120 -0
  107. package/src/index.ts +61 -0
  108. package/src/react/context.ts +24 -0
  109. package/src/react/error-boundary.tsx +56 -0
  110. package/src/react/hooks.ts +211 -0
  111. package/src/react/index.ts +16 -0
  112. package/src/react/link.tsx +93 -0
  113. package/src/react/outlet.tsx +67 -0
  114. package/src/react/provider.tsx +60 -0
@@ -0,0 +1,12 @@
1
+ export { BuzolaProvider } from './provider';
2
+ export type { BuzolaProviderProps } from './provider';
3
+ export { Outlet } from './outlet';
4
+ export type { OutletProps } from './outlet';
5
+ export { Link } from './link';
6
+ export type { LinkProps } from './link';
7
+ export { ErrorBoundary } from './error-boundary';
8
+ export { useBlocker, useInvalidate, useNavigate, useNavigationState, useParams, useRoute, useRouter, useRouterState, useSearchParams } from './hooks';
9
+ export type { BlockerState } from './hooks';
10
+ export { RouteContext, RouterContext } from './context';
11
+ export type { RouteContextValue } from './context';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACrJ,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { BuzolaProvider } from './provider';
2
+ export { Outlet } from './outlet';
3
+ export { Link } from './link';
4
+ export { ErrorBoundary } from './error-boundary';
5
+ export { useBlocker, useInvalidate, useNavigate, useNavigationState, useParams, useRoute, useRouter, useRouterState, useSearchParams } from './hooks';
6
+ export { RouteContext, RouterContext } from './context';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGrJ,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import type { EffectivePageParams, RegisteredPage } from '../engine/types.js';
3
+ type LinkPropsBase = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> & {
4
+ /** Replace the current history entry instead of pushing. */
5
+ replace?: boolean;
6
+ /** State to associate with the navigation entry. */
7
+ state?: unknown;
8
+ /** Use View Transitions API for this navigation. */
9
+ viewTransition?: boolean;
10
+ /**
11
+ * Whether to reset scroll position after navigation.
12
+ * Default is `true`. Set to `false` to preserve current scroll position.
13
+ */
14
+ resetScroll?: boolean;
15
+ /**
16
+ * Use exact matching for active detection.
17
+ * When `true` (default), `data-active` is set only when the current path equals the link target.
18
+ * When `false`, `data-active` is also set when the current path starts with the link target.
19
+ */
20
+ activeExact?: boolean;
21
+ };
22
+ export type LinkProps<P extends RegisteredPage = RegisteredPage> = [keyof EffectivePageParams<P>] extends [never] ? LinkPropsBase & {
23
+ to: P;
24
+ params?: never;
25
+ } : {} extends EffectivePageParams<P> ? LinkPropsBase & {
26
+ to: P;
27
+ params?: EffectivePageParams<P>;
28
+ } : LinkPropsBase & {
29
+ to: P;
30
+ params: EffectivePageParams<P>;
31
+ };
32
+ /**
33
+ * Type-safe link component.
34
+ * Uses page IDs for navigation — the router looks up the route pattern from the page registry.
35
+ * For simple navigations, renders a native <a> and lets the Navigation API handle it.
36
+ * Uses programmatic navigation when state, replace, resetScroll, or viewTransition is needed.
37
+ *
38
+ * Sets `data-active` attribute when the link target matches the current URL.
39
+ */
40
+ export declare function Link<P extends RegisteredPage>(props: LinkProps<P>): React.ReactElement;
41
+ export {};
42
+ //# sourceMappingURL=link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/react/link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAK9F,KAAK,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,GAAG;IAClF,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,IAAI,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC9G,aAAa,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,GAEzC,EAAE,SAAS,mBAAmB,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAA;CAAE,GAC9F,aAAa,GAAG;IAAE,EAAE,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAA;CAAE,CAAA;AAE5D;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAoDtF"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useCallback } from 'react';
3
+ import { useRouter, useRouterState } from './hooks.js';
4
+ /**
5
+ * Type-safe link component.
6
+ * Uses page IDs for navigation — the router looks up the route pattern from the page registry.
7
+ * For simple navigations, renders a native <a> and lets the Navigation API handle it.
8
+ * Uses programmatic navigation when state, replace, resetScroll, or viewTransition is needed.
9
+ *
10
+ * Sets `data-active` attribute when the link target matches the current URL.
11
+ */
12
+ export function Link(props) {
13
+ const { to, params, replace, state, viewTransition, resetScroll, activeExact = true, onClick, children, ...rest } = props;
14
+ const router = useRouter();
15
+ const routerState = useRouterState();
16
+ const href = router.buildPagePath(to, params);
17
+ const needsProgrammaticNav = state !== undefined || replace || viewTransition || resetScroll === false;
18
+ // Active detection: compare route paths (without basePath)
19
+ const currentPath = router.stripBasePath(routerState.location.pathname);
20
+ const targetPath = router.stripBasePath(href.split('?')[0]);
21
+ const isExact = currentPath === targetPath;
22
+ const isPrefix = targetPath !== '/' && currentPath.startsWith(targetPath + '/');
23
+ const isActive = isExact || (!activeExact && isPrefix);
24
+ const handleClick = useCallback((e) => {
25
+ onClick?.(e);
26
+ if (e.defaultPrevented)
27
+ return;
28
+ // Only handle left clicks without modifier keys
29
+ if (e.button !== 0 || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)
30
+ return;
31
+ if (needsProgrammaticNav) {
32
+ e.preventDefault();
33
+ router.navigateToPage(to, params, { replace, state, viewTransition, resetScroll });
34
+ }
35
+ }, [onClick, needsProgrammaticNav, router, to, params, replace, state, viewTransition, resetScroll]);
36
+ return (_jsx("a", { href: href, onClick: handleClick, "data-active": isActive ? '' : undefined, ...rest, children: children }));
37
+ }
38
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/react/link.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AA8BtD;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAA2B,KAAmB;IACjE,MAAM,EACL,EAAE,EACF,MAAM,EACN,OAAO,EACP,KAAK,EACL,cAAc,EACd,WAAW,EACX,WAAW,GAAG,IAAI,EAClB,OAAO,EACP,QAAQ,EACR,GAAG,IAAI,EACP,GAAG,KAAwE,CAAA;IAE5E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,oBAAoB,GAAG,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,cAAc,IAAI,WAAW,KAAK,KAAK,CAAA;IAEtG,2DAA2D;IAC3D,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,WAAW,KAAK,UAAU,CAAA;IAC1C,MAAM,QAAQ,GAAG,UAAU,KAAK,GAAG,IAAI,WAAW,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAA;IAC/E,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAA;IAEtD,MAAM,WAAW,GAAG,WAAW,CAC9B,CAAC,CAAsC,EAAE,EAAE;QAC1C,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QACZ,IAAI,CAAC,CAAC,gBAAgB;YAAE,OAAM;QAE9B,gDAAgD;QAChD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ;YAAE,OAAM;QAE9E,IAAI,oBAAoB,EAAE,CAAC;YAC1B,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,MAAM,CAAC,cAAc,CACpB,EAAE,EACF,MAAM,EACN,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAqB,CAClE,CAAA;QACF,CAAC;IACF,CAAC,EACD,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,CAAC,CAChG,CAAA;IAED,OAAO,CACN,YAAG,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,iBAAe,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAM,IAAI,YACnF,QAAQ,GACN,CACJ,CAAA;AACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export interface OutletProps {
3
+ /** Fallback to show while lazy components load. */
4
+ fallback?: React.ReactNode;
5
+ /** Fallback to show when a route component throws an error. */
6
+ errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);
7
+ }
8
+ /**
9
+ * Renders the component for the current depth in the route match chain.
10
+ * Each Outlet increments the depth and renders the next matched route's component.
11
+ */
12
+ export declare function Outlet({ fallback, errorFallback }: OutletProps): React.ReactElement | null;
13
+ //# sourceMappingURL=outlet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlet.d.ts","sourceRoot":"","sources":["../../src/react/outlet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAA;AAIrD,MAAM,WAAW,WAAW;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;CACrE;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,WAAW,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAmD1F"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { Suspense, use, useMemo } from 'react';
3
+ import { RouteContext } from './context.js';
4
+ import { ErrorBoundary } from './error-boundary.js';
5
+ /**
6
+ * Renders the component for the current depth in the route match chain.
7
+ * Each Outlet increments the depth and renders the next matched route's component.
8
+ */
9
+ export function Outlet({ fallback, errorFallback }) {
10
+ const routeContext = use(RouteContext);
11
+ if (!routeContext) {
12
+ throw new Error('<Outlet /> must be used within a <BuzolaProvider>');
13
+ }
14
+ const { state, depth, matches } = routeContext;
15
+ // Find the next match that has a component, skipping componentless nodes
16
+ // (e.g. directory layout nodes without a layout.tsx file).
17
+ let effectiveDepth = depth;
18
+ let match = matches[effectiveDepth];
19
+ while (match && !match.node.component) {
20
+ effectiveDepth++;
21
+ match = matches[effectiveDepth];
22
+ }
23
+ const nextContext = useMemo(() => {
24
+ if (!match)
25
+ return null;
26
+ // Merge params from all skipped matches and the effective match
27
+ let mergedParams = { ...routeContext.params };
28
+ for (let i = depth; i <= effectiveDepth; i++) {
29
+ if (matches[i]) {
30
+ mergedParams = { ...mergedParams, ...matches[i].params };
31
+ }
32
+ }
33
+ return {
34
+ state,
35
+ depth: effectiveDepth + 1,
36
+ matches,
37
+ params: mergedParams,
38
+ };
39
+ }, [state, depth, effectiveDepth, matches, match, routeContext.params]);
40
+ if (!match) {
41
+ return null;
42
+ }
43
+ const Component = match.node.component;
44
+ return (_jsx(ErrorBoundary, { fallback: errorFallback, resetKey: match.node.id, children: _jsx(Suspense, { fallback: fallback ?? null, children: nextContext && (_jsx(RouteContext, { value: nextContext, children: _jsx(Component, {}) })) }) }));
45
+ }
46
+ //# sourceMappingURL=outlet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlet.js","sourceRoot":"","sources":["../../src/react/outlet.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,YAAY,EAA0B,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AASnD;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAe;IAC9D,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC,CAAA;IACtC,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACrE,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,YAAY,CAAA;IAE9C,yEAAyE;IACzE,2DAA2D;IAC3D,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,IAAI,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACnC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC,cAAc,EAAE,CAAA;QAChB,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAA2B,GAAG,EAAE;QAC1D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACvB,gEAAgE;QAChE,IAAI,YAAY,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,CAAA;QAC7C,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChB,YAAY,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;YACzD,CAAC;QACF,CAAC;QACD,OAAO;YACN,KAAK;YACL,KAAK,EAAE,cAAc,GAAG,CAAC;YACzB,OAAO;YACP,MAAM,EAAE,YAAY;SACpB,CAAA;IACF,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;IAEvE,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAU,CAAA;IAEvC,OAAO,CACN,KAAC,aAAa,IAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,YAC9D,KAAC,QAAQ,IAAC,QAAQ,EAAE,QAAQ,IAAI,IAAI,YAClC,WAAW,IAAI,CACf,KAAC,YAAY,IAAC,KAAK,EAAE,WAAW,YAC/B,KAAC,SAAS,KAAG,GACC,CACf,GACS,GACI,CAChB,CAAA;AACF,CAAC"}
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { Router } from '../engine/router.js';
3
+ import type { RouteNode } from '../engine/types.js';
4
+ export type BuzolaProviderProps = {
5
+ children?: React.ReactNode;
6
+ } & ({
7
+ router: Router;
8
+ routes?: never;
9
+ persistentParams?: never;
10
+ pageRegistry?: never;
11
+ } | {
12
+ router?: never;
13
+ routes: RouteNode[];
14
+ persistentParams?: () => Record<string, string>;
15
+ pageRegistry?: Record<string, string>;
16
+ });
17
+ /**
18
+ * Root provider for Buzola router.
19
+ * Subscribes to router state and provides context to the React tree.
20
+ */
21
+ export declare function BuzolaProvider({ routes, children, ...props }: BuzolaProviderProps): React.ReactElement;
22
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwE,MAAM,OAAO,CAAA;AAE5F,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAInD,MAAM,MAAM,mBAAmB,GAC5B;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,GACC,CACC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,GAClF;IACD,MAAM,CAAC,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC,CACD,CAAA;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAkCtG"}
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';
3
+ import { createBrowserNavigationAdapter } from '../engine/navigation-adapter.js';
4
+ import { Router } from '../engine/router.js';
5
+ import { RouteContext, RouterContext } from './context.js';
6
+ import { Outlet } from './outlet.js';
7
+ /**
8
+ * Root provider for Buzola router.
9
+ * Subscribes to router state and provides context to the React tree.
10
+ */
11
+ export function BuzolaProvider({ routes, children, ...props }) {
12
+ const routerRef = useRef(props.router);
13
+ if (!routerRef.current) {
14
+ routerRef.current = new Router({
15
+ routes: routes,
16
+ adapter: createBrowserNavigationAdapter(),
17
+ persistentParams: props.persistentParams,
18
+ pageRegistry: props.pageRegistry,
19
+ });
20
+ }
21
+ const router = routerRef.current;
22
+ const subscribe = useCallback((cb) => router.subscribe(cb), [router]);
23
+ const getSnapshot = useCallback(() => router.getState(), [router]);
24
+ const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
25
+ // Start navigation interception
26
+ useEffect(() => {
27
+ return router.start();
28
+ }, [router]);
29
+ const routeContextValue = useMemo(() => ({
30
+ state,
31
+ depth: 0,
32
+ matches: state.matches,
33
+ params: {},
34
+ }), [state]);
35
+ return (_jsx(RouterContext, { value: router, children: _jsx(RouteContext, { value: routeContextValue, children: children ?? _jsx(Outlet, {}) }) }));
36
+ }
37
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAC5F,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,YAAY,EAA0B,aAAa,EAAE,MAAM,cAAc,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAgBpC;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAuB;IACjF,MAAM,SAAS,GAAG,MAAM,CAAqB,KAAK,CAAC,MAAM,CAAC,CAAA;IAC1D,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACxB,SAAS,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC;YAC9B,MAAM,EAAE,MAAO;YACf,OAAO,EAAE,8BAA8B,EAAE;YACzC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,YAAY,EAAE,KAAK,CAAC,YAAY;SAChC,CAAC,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;IAChC,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IACjF,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;IAEvE,gCAAgC;IAChC,SAAS,CAAC,GAAG,EAAE;QACd,OAAO,MAAM,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,MAAM,iBAAiB,GAAG,OAAO,CAAoB,GAAG,EAAE,CAAC,CAAC;QAC3D,KAAK;QACL,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,EAAE;KACV,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEZ,OAAO,CACN,KAAC,aAAa,IAAC,KAAK,EAAE,MAAM,YAC3B,KAAC,YAAY,IAAC,KAAK,EAAE,iBAAiB,YACpC,QAAQ,IAAI,KAAC,MAAM,KAAG,GACT,GACA,CAChB,CAAA;AACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@buzola/router",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "bun": "./src/index.ts",
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./react": {
14
+ "bun": "./src/react/index.ts",
15
+ "types": "./dist/react/index.d.ts",
16
+ "default": "./dist/react/index.js"
17
+ }
18
+ },
19
+ "files": ["dist", "src"],
20
+ "peerDependencies": {
21
+ "react": "^18.0.0 || ^19.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "react": "^19.0.0",
25
+ "@types/react": "^19.0.0",
26
+ "@types/bun": "latest",
27
+ "typescript": "^5.7.0"
28
+ }
29
+ }