@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,163 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, expect, it } from 'bun:test';
3
+ import React from 'react';
4
+ import { createPage } from '../define/create-page.js';
5
+ // ─── Helper ─────────────────────────────────────────────────────────────────
6
+ function mockSchema() {
7
+ return { '~standard': { version: 1, vendor: 'test', validate: (v) => ({ value: v }) } };
8
+ }
9
+ // ─── createPage().route() type safety ───────────────────────────────────────
10
+ describe('createPage route type safety', () => {
11
+ it('allows static route without params', () => {
12
+ const _page = createPage().route('/about').render(() => null);
13
+ expect(true).toBe(true);
14
+ });
15
+ it('rejects dynamic route without params', () => {
16
+ // @ts-expect-error — :id in route but no .params() defined
17
+ const _page = createPage().route('/users/:id').render(() => null);
18
+ expect(true).toBe(true);
19
+ });
20
+ it('allows dynamic route when param is in schema', () => {
21
+ const _page = createPage()
22
+ .params(mockSchema())
23
+ .route('/users/:id')
24
+ .render(({ params }) => null);
25
+ expect(true).toBe(true);
26
+ });
27
+ it('rejects dynamic route when param is not in schema', () => {
28
+ const _page = createPage()
29
+ .params(mockSchema())
30
+ // @ts-expect-error — :id is not a key of { userId: string }
31
+ .route('/users/:id')
32
+ .render(({ params }) => null);
33
+ expect(true).toBe(true);
34
+ });
35
+ it('allows multiple route params when all are in schema', () => {
36
+ const _page = createPage()
37
+ .params(mockSchema())
38
+ .route('/users/:userId/posts/:postId')
39
+ .render(({ params }) => null);
40
+ expect(true).toBe(true);
41
+ });
42
+ it('rejects when one route param is missing from schema', () => {
43
+ const _page = createPage()
44
+ .params(mockSchema())
45
+ // @ts-expect-error — :postId is not in { userId: string }
46
+ .route('/users/:userId/posts/:postId')
47
+ .render(({ params }) => null);
48
+ expect(true).toBe(true);
49
+ });
50
+ it('allows schema params that are not in route (they become query params)', () => {
51
+ const _page = createPage()
52
+ .params(mockSchema())
53
+ .route('/users/:userId')
54
+ .render(({ params }) => null);
55
+ expect(true).toBe(true);
56
+ });
57
+ });
58
+ // ─── createPage().catch() type safety ────────────────────────────────────────
59
+ describe('createPage catch type safety', () => {
60
+ it('.catch() is available before .render()', () => {
61
+ const _page = createPage()
62
+ .catch(({ error }) => _jsx("div", { children: error.message }))
63
+ .render(() => null);
64
+ expect(true).toBe(true);
65
+ });
66
+ it('.catch() is available after .route()', () => {
67
+ const _page = createPage()
68
+ .route('/about')
69
+ .catch(({ error }) => _jsx("div", { children: error.message }))
70
+ .render(() => null);
71
+ expect(true).toBe(true);
72
+ });
73
+ it('no .catch() after .catch()', () => {
74
+ const withCatch = createPage().catch(({ error }) => _jsx("div", { children: error.message }));
75
+ // @ts-expect-error — .catch() should not be available after .catch()
76
+ withCatch.catch;
77
+ expect(true).toBe(true);
78
+ });
79
+ it('no .loader() after .catch()', () => {
80
+ const withCatch = createPage().catch(({ error }) => _jsx("div", { children: error.message }));
81
+ // @ts-expect-error — .loader() should not be available after .catch()
82
+ withCatch.loader;
83
+ expect(true).toBe(true);
84
+ });
85
+ });
86
+ // ─── LinkProps ──────────────────────────────────────────────────────────────
87
+ describe('LinkProps type safety', () => {
88
+ it('static page does not require params', () => {
89
+ const _a = { to: 'home' };
90
+ const _b = { to: 'about' };
91
+ expect(true).toBe(true);
92
+ });
93
+ it('static page rejects params', () => {
94
+ // @ts-expect-error — static page should not accept params
95
+ const _a = { to: 'about', params: { foo: 'bar' } };
96
+ expect(true).toBe(true);
97
+ });
98
+ it('dynamic page requires params', () => {
99
+ const _a = { to: 'users/detail', params: { userId: '1' } };
100
+ // @ts-expect-error — missing required params
101
+ const _b = { to: 'users/detail' };
102
+ expect(true).toBe(true);
103
+ });
104
+ it('dynamic page requires correct param names', () => {
105
+ // @ts-expect-error — wrong param name
106
+ const _a = { to: 'users/detail', params: { id: '1' } };
107
+ expect(true).toBe(true);
108
+ });
109
+ it('multi-param page requires all params', () => {
110
+ const _a = {
111
+ to: 'users/posts',
112
+ params: { userId: '1', postId: '2' },
113
+ };
114
+ const _b = {
115
+ to: 'users/posts',
116
+ // @ts-expect-error — missing postId
117
+ params: { userId: '1' },
118
+ };
119
+ expect(true).toBe(true);
120
+ });
121
+ it('rejects unregistered pages', () => {
122
+ // @ts-expect-error — page not in BuzolaPageMap
123
+ const _a = { to: 'unknown' };
124
+ expect(true).toBe(true);
125
+ });
126
+ });
127
+ // ─── Link JSX usage (generic inference) ─────────────────────────────────────
128
+ import { Link } from '../react/link.js';
129
+ describe('Link JSX generic inference', () => {
130
+ it('accepts static page without params', () => {
131
+ const _el = _jsx(Link, { to: "home", children: "Home" });
132
+ const _el2 = _jsx(Link, { to: "about", children: "About" });
133
+ expect(true).toBe(true);
134
+ });
135
+ it('rejects params on static page', () => {
136
+ // @ts-expect-error — static page should not accept params
137
+ const _el = _jsx(Link, { to: "about", params: { foo: 'bar' }, children: "About" });
138
+ expect(true).toBe(true);
139
+ });
140
+ it('requires params on dynamic page', () => {
141
+ const _el = _jsx(Link, { to: "users/detail", params: { userId: '1' }, children: "User" });
142
+ // @ts-expect-error — missing required params
143
+ const _el2 = _jsx(Link, { to: "users/detail", children: "User" });
144
+ expect(true).toBe(true);
145
+ });
146
+ it('rejects wrong param names', () => {
147
+ // @ts-expect-error — wrong param name
148
+ const _el = _jsx(Link, { to: "users/detail", params: { id: '1' }, children: "User" });
149
+ expect(true).toBe(true);
150
+ });
151
+ it('requires all params for multi-param page', () => {
152
+ const _ok = _jsx(Link, { to: "users/posts", params: { userId: '1', postId: '2' }, children: "Post" });
153
+ // @ts-expect-error — missing postId
154
+ const _bad = _jsx(Link, { to: "users/posts", params: { userId: '1' }, children: "Post" });
155
+ expect(true).toBe(true);
156
+ });
157
+ it('rejects unregistered pages', () => {
158
+ // @ts-expect-error — page not in BuzolaPageMap
159
+ const _el = _jsx(Link, { to: "nope", children: "Nope" });
160
+ expect(true).toBe(true);
161
+ });
162
+ });
163
+ //# sourceMappingURL=type-safety.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-safety.test.js","sourceRoot":"","sources":["../../src/__tests__/type-safety.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ describe('ParamsForPath type', () => {
3
+ it('extracts no params from static paths', () => {
4
+ // Type-level test: this should compile without error
5
+ const _test = {};
6
+ expect(true).toBe(true);
7
+ });
8
+ it('extracts a single param', () => {
9
+ const _test = { userId: 'abc' };
10
+ expect(_test.userId).toBe('abc');
11
+ });
12
+ it('extracts multiple params', () => {
13
+ const _test = { userId: '1', postId: '2' };
14
+ expect(_test.userId).toBe('1');
15
+ expect(_test.postId).toBe('2');
16
+ });
17
+ it('handles root path', () => {
18
+ const _test = {};
19
+ expect(true).toBe(true);
20
+ });
21
+ });
22
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UAAU,CAAA;AAG/C,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC/C,qDAAqD;QACrD,MAAM,KAAK,GAA4B,EAAwB,CAAA;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QAClC,MAAM,KAAK,GAAoC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;QAChE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACnC,MAAM,KAAK,GAAkD,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;QACzF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC5B,MAAM,KAAK,GAAuB,EAAwB,CAAA;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,87 @@
1
+ import { type ComponentType } from 'react';
2
+ import { type ParamLiteral } from '../engine/schema';
3
+ import type { RouteComponent, StandardSchema } from '../engine/types';
4
+ export interface PageProps<TParams> {
5
+ params: TParams;
6
+ }
7
+ export interface CatchContext {
8
+ error: Error;
9
+ retry: () => void;
10
+ }
11
+ type CatchHandler = React.ReactNode | ((ctx: CatchContext) => React.ReactNode);
12
+ export interface ParamMeta {
13
+ name: string;
14
+ optional: boolean;
15
+ array: boolean;
16
+ }
17
+ export interface PageDefinition<TParams = Record<string, never>> {
18
+ __buzolaPage: true;
19
+ component: RouteComponent;
20
+ route?: string;
21
+ paramsSchema?: StandardSchema;
22
+ paramsMeta: ParamMeta[];
23
+ loader?: (ctx: {
24
+ params: any;
25
+ }) => Promise<unknown>;
26
+ }
27
+ /**
28
+ * Extract dynamic parameter names from a route pattern at the type level.
29
+ * "/users/:userId/posts/:postId" → "userId" | "postId"
30
+ * "/:slug+" → "slug"
31
+ */
32
+ type ExtractRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? (Param extends `${infer P}+` ? P : Param) | ExtractRouteParams<Rest> : T extends `${string}:${infer Param}` ? (Param extends `${infer P}+` ? P : Param) : never;
33
+ type ParamField = StandardSchema | ParamLiteral;
34
+ type ParamsShape = Record<string, ParamField>;
35
+ type ScalarType<T extends string> = T extends 'string' ? string : T extends 'number' ? number : T extends 'uuid' ? string : never;
36
+ type LiteralToType<L extends string> = L extends `?${infer Base}[]` ? ScalarType<Base>[] | undefined : L extends `${infer Base}[]` ? ScalarType<Base>[] : L extends `?${infer Base}` ? ScalarType<Base> | undefined : ScalarType<L>;
37
+ type InferShape<T extends ParamsShape> = {
38
+ [K in keyof T]: T[K] extends StandardSchema<infer V> ? V : T[K] extends string ? LiteralToType<T[K]> : never;
39
+ };
40
+ interface WithCatch<TParams, TRenderProps> {
41
+ route<R extends string>(pattern: [ExtractRouteParams<R>] extends [keyof TParams & string] ? R : never): {
42
+ render(fn: ComponentType<TRenderProps>): PageDefinition<TParams>;
43
+ };
44
+ render(fn: ComponentType<TRenderProps>): PageDefinition<TParams>;
45
+ }
46
+ interface WithRoute<TParams, TRenderProps> {
47
+ catch(handler: CatchHandler): WithCatch<TParams, TRenderProps>;
48
+ route<R extends string>(pattern: [ExtractRouteParams<R>] extends [keyof TParams & string] ? R : never): {
49
+ catch(handler: CatchHandler): {
50
+ render(fn: ComponentType<TRenderProps>): PageDefinition<TParams>;
51
+ };
52
+ render(fn: ComponentType<TRenderProps>): PageDefinition<TParams>;
53
+ };
54
+ render(fn: ComponentType<TRenderProps>): PageDefinition<TParams>;
55
+ }
56
+ interface WithLoaderChain<TParams, TData> extends WithRoute<TParams, PageProps<TParams> & {
57
+ data: TData;
58
+ invalidate: () => void;
59
+ isLoading: boolean;
60
+ }> {
61
+ loader<TNew extends Record<string, unknown>>(fn: (ctx: {
62
+ params: TParams;
63
+ }) => Promise<TNew>): WithLoaderChain<TParams, TData & TNew>;
64
+ }
65
+ interface WithLoader<TParams> extends WithRoute<TParams, PageProps<TParams>> {
66
+ loader<TData extends Record<string, unknown>>(fn: (ctx: {
67
+ params: TParams;
68
+ }) => Promise<TData>): WithLoaderChain<TParams, TData>;
69
+ }
70
+ interface PageBuilder {
71
+ params<T extends ParamsShape>(shape: T): WithLoader<InferShape<T>>;
72
+ params<T extends Record<string, unknown>>(schema: StandardSchema<T>): WithLoader<T>;
73
+ loader<TData extends Record<string, unknown>>(fn: (ctx: {
74
+ params: Record<string, never>;
75
+ }) => Promise<TData>): WithLoaderChain<Record<string, never>, TData>;
76
+ catch(handler: CatchHandler): WithCatch<Record<string, never>, PageProps<Record<string, never>>>;
77
+ route<R extends string>(pattern: [ExtractRouteParams<R>] extends [never] ? R : never): {
78
+ catch(handler: CatchHandler): {
79
+ render(fn: ComponentType<PageProps<Record<string, never>>>): PageDefinition;
80
+ };
81
+ render(fn: ComponentType<PageProps<Record<string, never>>>): PageDefinition;
82
+ };
83
+ render(fn: ComponentType<PageProps<Record<string, never>>>): PageDefinition;
84
+ }
85
+ export declare function createPage(): PageBuilder;
86
+ export {};
87
+ //# sourceMappingURL=create-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-page.d.ts","sourceRoot":"","sources":["../../src/define/create-page.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,305 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { use, useCallback, useEffect, useMemo, useReducer, useState } from 'react';
3
+ import { isOptionalSchema, resolveParamLiteral } from '../engine/schema';
4
+ import { extractParamNames } from '../engine/utils';
5
+ import { RouteContext, RouterContext } from '../react/context';
6
+ import { ErrorBoundary } from '../react/error-boundary';
7
+ function isStandardSchema(value) {
8
+ return '~standard' in value;
9
+ }
10
+ function resolveParamsInput(input) {
11
+ if (isStandardSchema(input)) {
12
+ return {
13
+ schema: input,
14
+ paramsMeta: input.__buzolaKeys ?? [],
15
+ };
16
+ }
17
+ const shape = input;
18
+ const paramsMeta = [];
19
+ const fieldSchemas = {};
20
+ for (const [name, field] of Object.entries(shape)) {
21
+ if (typeof field === 'string') {
22
+ const resolved = resolveParamLiteral(field);
23
+ fieldSchemas[name] = resolved.schema;
24
+ paramsMeta.push({ name, optional: resolved.optional, array: resolved.array });
25
+ }
26
+ else {
27
+ fieldSchemas[name] = field;
28
+ paramsMeta.push({ name, optional: isOptionalSchema(field), array: false });
29
+ }
30
+ }
31
+ const schema = {
32
+ '~standard': {
33
+ version: 1,
34
+ vendor: 'buzola',
35
+ validate: (v) => {
36
+ const record = (v ?? {});
37
+ const result = {};
38
+ for (const [key, fs] of Object.entries(fieldSchemas)) {
39
+ const r = fs['~standard'].validate(record[key]);
40
+ if ('issues' in r)
41
+ return r;
42
+ result[key] = r.value;
43
+ }
44
+ return { value: result };
45
+ },
46
+ },
47
+ };
48
+ return { schema, paramsMeta };
49
+ }
50
+ function combineLoaders(loaders) {
51
+ if (loaders.length === 0)
52
+ return undefined;
53
+ if (loaders.length === 1)
54
+ return loaders[0];
55
+ return async (ctx) => Object.assign({}, ...await Promise.all(loaders.map(fn => fn(ctx))));
56
+ }
57
+ // ─── Component factory ──────────────────────────────────────────────────────
58
+ function createPageComponent(schema, paramsMeta, loaderFn, routePattern, RenderComponent, catchHandler) {
59
+ const arrayParams = new Set(paramsMeta.filter(m => m.array).map(m => m.name));
60
+ // Loader promise cache lives in the closure, outside React's render cycle.
61
+ // This is critical: when use() suspends during the initial render, React
62
+ // discards all uncommitted hook state (useRef, useState, useMemo).
63
+ // On retry, hooks reinitialize, and useMemo/useRef would create a new promise,
64
+ // causing an infinite suspend loop. The closure cache survives this.
65
+ // Active load state (current URL)
66
+ let activeUrlHref = null;
67
+ let activeCacheKey = null;
68
+ let activePromise = null;
69
+ let activeResolvedData = undefined;
70
+ let hasResolved = false;
71
+ let pendingBackgroundKey = null;
72
+ // LRU cache for previously visited URLs (url → resolved data)
73
+ const staleDataCache = new Map();
74
+ function evictStaleCache(maxSize) {
75
+ while (staleDataCache.size > maxSize) {
76
+ const first = staleDataCache.keys().next().value;
77
+ staleDataCache.delete(first);
78
+ }
79
+ }
80
+ function BuzolaPage() {
81
+ const routeContext = use(RouteContext);
82
+ if (!routeContext) {
83
+ throw new Error('createPage component must be used within a <BuzolaProvider>');
84
+ }
85
+ const router = use(RouterContext);
86
+ const params = useMemo(() => {
87
+ const { state, matches, params: pathParams } = routeContext;
88
+ const currentMatch = matches.find(m => m.node.component === BuzolaPage);
89
+ const pathParamNames = new Set(currentMatch ? extractParamNames(currentMatch.node.fullPath) : []);
90
+ const merged = {};
91
+ if (arrayParams.size > 0) {
92
+ for (const name of arrayParams) {
93
+ if (pathParamNames.has(name))
94
+ continue;
95
+ const values = [
96
+ ...state.location.searchParams.getAll(name),
97
+ ...state.location.searchParams.getAll(`${name}[]`),
98
+ ];
99
+ if (values.length > 0)
100
+ merged[name] = values;
101
+ }
102
+ }
103
+ state.location.searchParams.forEach((value, key) => {
104
+ const cleanKey = key.endsWith('[]') ? key.slice(0, -2) : key;
105
+ if (!pathParamNames.has(cleanKey) && !(cleanKey in merged)) {
106
+ merged[cleanKey] = value;
107
+ }
108
+ });
109
+ for (const [key, value] of Object.entries(pathParams)) {
110
+ if (arrayParams.has(key)) {
111
+ merged[key] = value.split(',');
112
+ }
113
+ else {
114
+ merged[key] = value;
115
+ }
116
+ }
117
+ if (schema) {
118
+ const result = schema['~standard'].validate(merged);
119
+ if ('issues' in result) {
120
+ throw new Error(`Page params validation failed: ${result.issues.map(i => i.message).join(', ')}`);
121
+ }
122
+ return result.value;
123
+ }
124
+ return merged;
125
+ }, [routeContext]);
126
+ const [loaderKey, setLoaderKey] = useState(0);
127
+ const [, forceUpdate] = useReducer(x => x + 1, 0);
128
+ const invalidate = useCallback(() => setLoaderKey(k => k + 1), []);
129
+ // Subscribe to router-level invalidation
130
+ useEffect(() => {
131
+ if (!router)
132
+ return;
133
+ return router.onInvalidate(() => setLoaderKey(k => k + 1));
134
+ }, [router]);
135
+ const cacheSize = router?.loaderCacheSize ?? 0;
136
+ let data = undefined;
137
+ let isLoading = false;
138
+ if (loaderFn) {
139
+ const currentUrlHref = routeContext.state.location.href;
140
+ const cacheKey = `${currentUrlHref}:${loaderKey}`;
141
+ // URL changed — save old data to stale cache, restore from stale cache if available
142
+ if (activeUrlHref !== null && activeUrlHref !== currentUrlHref) {
143
+ if (hasResolved && activeResolvedData !== undefined) {
144
+ staleDataCache.set(activeUrlHref, activeResolvedData);
145
+ evictStaleCache(cacheSize);
146
+ }
147
+ if (staleDataCache.has(currentUrlHref)) {
148
+ activeResolvedData = staleDataCache.get(currentUrlHref);
149
+ staleDataCache.delete(currentUrlHref);
150
+ hasResolved = true;
151
+ }
152
+ else {
153
+ hasResolved = false;
154
+ activeResolvedData = undefined;
155
+ }
156
+ pendingBackgroundKey = null;
157
+ }
158
+ else if (activeUrlHref === null && staleDataCache.has(currentUrlHref)) {
159
+ // Remount — restore from stale cache
160
+ activeResolvedData = staleDataCache.get(currentUrlHref);
161
+ staleDataCache.delete(currentUrlHref);
162
+ hasResolved = true;
163
+ }
164
+ activeUrlHref = currentUrlHref;
165
+ if (activeCacheKey === cacheKey) {
166
+ // Cache hit — check if background load is pending
167
+ if (pendingBackgroundKey === cacheKey) {
168
+ data = activeResolvedData;
169
+ isLoading = true;
170
+ }
171
+ else {
172
+ // Either resolved or first-time suspend
173
+ if (hasResolved) {
174
+ data = activeResolvedData;
175
+ }
176
+ else {
177
+ data = use(activePromise);
178
+ activeResolvedData = data;
179
+ hasResolved = true;
180
+ }
181
+ }
182
+ }
183
+ else if (hasResolved) {
184
+ // Cache key changed + we have stale data → background reload (SWR)
185
+ const promise = loaderFn({ params });
186
+ activeCacheKey = cacheKey;
187
+ activePromise = promise;
188
+ pendingBackgroundKey = cacheKey;
189
+ data = activeResolvedData;
190
+ isLoading = true;
191
+ promise.then((result) => {
192
+ // Only apply if this is still the active load
193
+ if (activeCacheKey === cacheKey) {
194
+ activeResolvedData = result;
195
+ pendingBackgroundKey = null;
196
+ forceUpdate();
197
+ }
198
+ }, (error) => {
199
+ // Store rejected promise so use() triggers ErrorBoundary
200
+ if (activeCacheKey === cacheKey) {
201
+ activePromise = promise;
202
+ hasResolved = false;
203
+ pendingBackgroundKey = null;
204
+ forceUpdate();
205
+ }
206
+ });
207
+ }
208
+ else {
209
+ // No stale data — first load, suspend via use()
210
+ const promise = loaderFn({ params });
211
+ activeCacheKey = cacheKey;
212
+ activePromise = promise;
213
+ data = use(promise);
214
+ activeResolvedData = data;
215
+ hasResolved = true;
216
+ }
217
+ }
218
+ // On unmount, save active data to stale cache and reset active state
219
+ useEffect(() => {
220
+ return () => {
221
+ if (hasResolved && activeResolvedData !== undefined && activeUrlHref) {
222
+ staleDataCache.set(activeUrlHref, activeResolvedData);
223
+ evictStaleCache(cacheSize);
224
+ }
225
+ hasResolved = false;
226
+ activeResolvedData = undefined;
227
+ activeCacheKey = null;
228
+ activePromise = null;
229
+ pendingBackgroundKey = null;
230
+ activeUrlHref = null;
231
+ };
232
+ }, []);
233
+ return _jsx(RenderComponent, { params: params, data: data, invalidate: invalidate, isLoading: isLoading });
234
+ }
235
+ function BuzolaPageWithCatch() {
236
+ const routeContext = use(RouteContext);
237
+ const [retryCount, setRetryCount] = useState(0);
238
+ const retry = useCallback(() => setRetryCount(c => c + 1), []);
239
+ const resetKey = `${routeContext?.state.location.href ?? ''}:${retryCount}`;
240
+ const boundFallback = typeof catchHandler === 'function'
241
+ ? (error) => catchHandler({ error, retry })
242
+ : catchHandler;
243
+ return (_jsx(ErrorBoundary, { fallback: boundFallback, resetKey: resetKey, children: _jsx(BuzolaPage, {}, retryCount) }));
244
+ }
245
+ const component = catchHandler ? BuzolaPageWithCatch : BuzolaPage;
246
+ return {
247
+ __buzolaPage: true,
248
+ component: component,
249
+ route: routePattern,
250
+ paramsSchema: schema,
251
+ paramsMeta,
252
+ loader: loaderFn,
253
+ };
254
+ }
255
+ function withCatchAndRender(schema, paramsMeta, loaders, catchHandler) {
256
+ return {
257
+ route(pattern) {
258
+ return {
259
+ render(fn) {
260
+ return createPageComponent(schema, paramsMeta, combineLoaders(loaders), pattern, fn, catchHandler);
261
+ },
262
+ };
263
+ },
264
+ render(fn) {
265
+ return createPageComponent(schema, paramsMeta, combineLoaders(loaders), undefined, fn, catchHandler);
266
+ },
267
+ };
268
+ }
269
+ function withRouteAndRender(schema, paramsMeta, loaders) {
270
+ return {
271
+ loader(loaderFn) {
272
+ return withRouteAndRender(schema, paramsMeta, [...loaders, loaderFn]);
273
+ },
274
+ catch(handler) {
275
+ return withCatchAndRender(schema, paramsMeta, loaders, handler);
276
+ },
277
+ route(pattern) {
278
+ return {
279
+ catch(handler) {
280
+ return {
281
+ render(fn) {
282
+ return createPageComponent(schema, paramsMeta, combineLoaders(loaders), pattern, fn, handler);
283
+ },
284
+ };
285
+ },
286
+ render(fn) {
287
+ return createPageComponent(schema, paramsMeta, combineLoaders(loaders), pattern, fn);
288
+ },
289
+ };
290
+ },
291
+ render(fn) {
292
+ return createPageComponent(schema, paramsMeta, combineLoaders(loaders), undefined, fn);
293
+ },
294
+ };
295
+ }
296
+ export function createPage() {
297
+ return {
298
+ params(input) {
299
+ const { schema, paramsMeta } = resolveParamsInput(input);
300
+ return withRouteAndRender(schema, paramsMeta, []);
301
+ },
302
+ ...withRouteAndRender(undefined, [], []),
303
+ };
304
+ }
305
+ //# sourceMappingURL=create-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-page.js","sourceRoot":"","sources":["../../src/define/create-page.tsx"],"names":[],"mappings":"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"}