alabjs 0.1.0

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 (277) hide show
  1. package/dist/adapters/cloudflare.d.ts +31 -0
  2. package/dist/adapters/cloudflare.d.ts.map +1 -0
  3. package/dist/adapters/cloudflare.js +30 -0
  4. package/dist/adapters/cloudflare.js.map +1 -0
  5. package/dist/adapters/deno.d.ts +22 -0
  6. package/dist/adapters/deno.d.ts.map +1 -0
  7. package/dist/adapters/deno.js +21 -0
  8. package/dist/adapters/deno.js.map +1 -0
  9. package/dist/adapters/web.d.ts +47 -0
  10. package/dist/adapters/web.d.ts.map +1 -0
  11. package/dist/adapters/web.js +212 -0
  12. package/dist/adapters/web.js.map +1 -0
  13. package/dist/cli.d.ts +11 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +61 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/client/hooks.d.ts +119 -0
  18. package/dist/client/hooks.d.ts.map +1 -0
  19. package/dist/client/hooks.js +220 -0
  20. package/dist/client/hooks.js.map +1 -0
  21. package/dist/client/hooks.test.d.ts +2 -0
  22. package/dist/client/hooks.test.d.ts.map +1 -0
  23. package/dist/client/hooks.test.js +45 -0
  24. package/dist/client/hooks.test.js.map +1 -0
  25. package/dist/client/index.d.ts +6 -0
  26. package/dist/client/index.d.ts.map +1 -0
  27. package/dist/client/index.js +4 -0
  28. package/dist/client/index.js.map +1 -0
  29. package/dist/client/offline.d.ts +52 -0
  30. package/dist/client/offline.d.ts.map +1 -0
  31. package/dist/client/offline.js +90 -0
  32. package/dist/client/offline.js.map +1 -0
  33. package/dist/client/provider.d.ts +12 -0
  34. package/dist/client/provider.d.ts.map +1 -0
  35. package/dist/client/provider.js +10 -0
  36. package/dist/client/provider.js.map +1 -0
  37. package/dist/commands/build.d.ts +18 -0
  38. package/dist/commands/build.d.ts.map +1 -0
  39. package/dist/commands/build.js +173 -0
  40. package/dist/commands/build.js.map +1 -0
  41. package/dist/commands/dev.d.ts +8 -0
  42. package/dist/commands/dev.d.ts.map +1 -0
  43. package/dist/commands/dev.js +447 -0
  44. package/dist/commands/dev.js.map +1 -0
  45. package/dist/commands/info.d.ts +6 -0
  46. package/dist/commands/info.d.ts.map +1 -0
  47. package/dist/commands/info.js +92 -0
  48. package/dist/commands/info.js.map +1 -0
  49. package/dist/commands/ssg.d.ts +8 -0
  50. package/dist/commands/ssg.d.ts.map +1 -0
  51. package/dist/commands/ssg.js +124 -0
  52. package/dist/commands/ssg.js.map +1 -0
  53. package/dist/commands/start.d.ts +7 -0
  54. package/dist/commands/start.d.ts.map +1 -0
  55. package/dist/commands/start.js +26 -0
  56. package/dist/commands/start.js.map +1 -0
  57. package/dist/commands/test.d.ts +24 -0
  58. package/dist/commands/test.d.ts.map +1 -0
  59. package/dist/commands/test.js +87 -0
  60. package/dist/commands/test.js.map +1 -0
  61. package/dist/components/ErrorBoundary.d.ts +38 -0
  62. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  63. package/dist/components/ErrorBoundary.js +46 -0
  64. package/dist/components/ErrorBoundary.js.map +1 -0
  65. package/dist/components/Font.d.ts +57 -0
  66. package/dist/components/Font.d.ts.map +1 -0
  67. package/dist/components/Font.js +33 -0
  68. package/dist/components/Font.js.map +1 -0
  69. package/dist/components/Image.d.ts +74 -0
  70. package/dist/components/Image.d.ts.map +1 -0
  71. package/dist/components/Image.js +85 -0
  72. package/dist/components/Image.js.map +1 -0
  73. package/dist/components/Link.d.ts +23 -0
  74. package/dist/components/Link.d.ts.map +1 -0
  75. package/dist/components/Link.js +48 -0
  76. package/dist/components/Link.js.map +1 -0
  77. package/dist/components/Script.d.ts +37 -0
  78. package/dist/components/Script.d.ts.map +1 -0
  79. package/dist/components/Script.js +70 -0
  80. package/dist/components/Script.js.map +1 -0
  81. package/dist/components/index.d.ts +10 -0
  82. package/dist/components/index.d.ts.map +1 -0
  83. package/dist/components/index.js +6 -0
  84. package/dist/components/index.js.map +1 -0
  85. package/dist/i18n/i18n.test.d.ts +2 -0
  86. package/dist/i18n/i18n.test.d.ts.map +1 -0
  87. package/dist/i18n/i18n.test.js +132 -0
  88. package/dist/i18n/i18n.test.js.map +1 -0
  89. package/dist/i18n/index.d.ts +135 -0
  90. package/dist/i18n/index.d.ts.map +1 -0
  91. package/dist/i18n/index.js +189 -0
  92. package/dist/i18n/index.js.map +1 -0
  93. package/dist/index.d.ts +4 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +3 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/router/code-router.d.ts +204 -0
  98. package/dist/router/code-router.d.ts.map +1 -0
  99. package/dist/router/code-router.js +258 -0
  100. package/dist/router/code-router.js.map +1 -0
  101. package/dist/router/code-router.test.d.ts +2 -0
  102. package/dist/router/code-router.test.d.ts.map +1 -0
  103. package/dist/router/code-router.test.js +128 -0
  104. package/dist/router/code-router.test.js.map +1 -0
  105. package/dist/router/index.d.ts +4 -0
  106. package/dist/router/index.d.ts.map +1 -0
  107. package/dist/router/index.js +2 -0
  108. package/dist/router/index.js.map +1 -0
  109. package/dist/router/manifest.d.ts +12 -0
  110. package/dist/router/manifest.d.ts.map +1 -0
  111. package/dist/router/manifest.js +2 -0
  112. package/dist/router/manifest.js.map +1 -0
  113. package/dist/server/app.d.ts +13 -0
  114. package/dist/server/app.d.ts.map +1 -0
  115. package/dist/server/app.js +407 -0
  116. package/dist/server/app.js.map +1 -0
  117. package/dist/server/cache.d.ts +99 -0
  118. package/dist/server/cache.d.ts.map +1 -0
  119. package/dist/server/cache.js +161 -0
  120. package/dist/server/cache.js.map +1 -0
  121. package/dist/server/cache.test.d.ts +2 -0
  122. package/dist/server/cache.test.d.ts.map +1 -0
  123. package/dist/server/cache.test.js +150 -0
  124. package/dist/server/cache.test.js.map +1 -0
  125. package/dist/server/csrf.d.ts +28 -0
  126. package/dist/server/csrf.d.ts.map +1 -0
  127. package/dist/server/csrf.js +66 -0
  128. package/dist/server/csrf.js.map +1 -0
  129. package/dist/server/csrf.test.d.ts +2 -0
  130. package/dist/server/csrf.test.d.ts.map +1 -0
  131. package/dist/server/csrf.test.js +154 -0
  132. package/dist/server/csrf.test.js.map +1 -0
  133. package/dist/server/image.d.ts +18 -0
  134. package/dist/server/image.d.ts.map +1 -0
  135. package/dist/server/image.js +97 -0
  136. package/dist/server/image.js.map +1 -0
  137. package/dist/server/index.d.ts +57 -0
  138. package/dist/server/index.d.ts.map +1 -0
  139. package/dist/server/index.js +58 -0
  140. package/dist/server/index.js.map +1 -0
  141. package/dist/server/middleware.d.ts +53 -0
  142. package/dist/server/middleware.d.ts.map +1 -0
  143. package/dist/server/middleware.js +80 -0
  144. package/dist/server/middleware.js.map +1 -0
  145. package/dist/server/middleware.test.d.ts +2 -0
  146. package/dist/server/middleware.test.d.ts.map +1 -0
  147. package/dist/server/middleware.test.js +125 -0
  148. package/dist/server/middleware.test.js.map +1 -0
  149. package/dist/server/revalidate.d.ts +49 -0
  150. package/dist/server/revalidate.d.ts.map +1 -0
  151. package/dist/server/revalidate.js +62 -0
  152. package/dist/server/revalidate.js.map +1 -0
  153. package/dist/server/revalidate.test.d.ts +2 -0
  154. package/dist/server/revalidate.test.d.ts.map +1 -0
  155. package/dist/server/revalidate.test.js +93 -0
  156. package/dist/server/revalidate.test.js.map +1 -0
  157. package/dist/server/server-fn.test.d.ts +2 -0
  158. package/dist/server/server-fn.test.d.ts.map +1 -0
  159. package/dist/server/server-fn.test.js +105 -0
  160. package/dist/server/server-fn.test.js.map +1 -0
  161. package/dist/server/sitemap.d.ts +9 -0
  162. package/dist/server/sitemap.d.ts.map +1 -0
  163. package/dist/server/sitemap.js +26 -0
  164. package/dist/server/sitemap.js.map +1 -0
  165. package/dist/server/sitemap.test.d.ts +2 -0
  166. package/dist/server/sitemap.test.d.ts.map +1 -0
  167. package/dist/server/sitemap.test.js +61 -0
  168. package/dist/server/sitemap.test.js.map +1 -0
  169. package/dist/server/sse.d.ts +59 -0
  170. package/dist/server/sse.d.ts.map +1 -0
  171. package/dist/server/sse.js +91 -0
  172. package/dist/server/sse.js.map +1 -0
  173. package/dist/server/sse.test.d.ts +2 -0
  174. package/dist/server/sse.test.d.ts.map +1 -0
  175. package/dist/server/sse.test.js +68 -0
  176. package/dist/server/sse.test.js.map +1 -0
  177. package/dist/signals/index.d.ts +101 -0
  178. package/dist/signals/index.d.ts.map +1 -0
  179. package/dist/signals/index.js +149 -0
  180. package/dist/signals/index.js.map +1 -0
  181. package/dist/signals/signals.test.d.ts +2 -0
  182. package/dist/signals/signals.test.d.ts.map +1 -0
  183. package/dist/signals/signals.test.js +146 -0
  184. package/dist/signals/signals.test.js.map +1 -0
  185. package/dist/ssr/html.d.ts +27 -0
  186. package/dist/ssr/html.d.ts.map +1 -0
  187. package/dist/ssr/html.js +107 -0
  188. package/dist/ssr/html.js.map +1 -0
  189. package/dist/ssr/html.test.d.ts +2 -0
  190. package/dist/ssr/html.test.d.ts.map +1 -0
  191. package/dist/ssr/html.test.js +178 -0
  192. package/dist/ssr/html.test.js.map +1 -0
  193. package/dist/ssr/render.d.ts +46 -0
  194. package/dist/ssr/render.d.ts.map +1 -0
  195. package/dist/ssr/render.js +87 -0
  196. package/dist/ssr/render.js.map +1 -0
  197. package/dist/ssr/router-dev.d.ts +60 -0
  198. package/dist/ssr/router-dev.d.ts.map +1 -0
  199. package/dist/ssr/router-dev.js +205 -0
  200. package/dist/ssr/router-dev.js.map +1 -0
  201. package/dist/ssr/router-dev.test.d.ts +2 -0
  202. package/dist/ssr/router-dev.test.d.ts.map +1 -0
  203. package/dist/ssr/router-dev.test.js +189 -0
  204. package/dist/ssr/router-dev.test.js.map +1 -0
  205. package/dist/test/index.d.ts +93 -0
  206. package/dist/test/index.d.ts.map +1 -0
  207. package/dist/test/index.js +146 -0
  208. package/dist/test/index.js.map +1 -0
  209. package/dist/types/index.d.ts +117 -0
  210. package/dist/types/index.d.ts.map +1 -0
  211. package/dist/types/index.js +2 -0
  212. package/dist/types/index.js.map +1 -0
  213. package/dist/types/napi.d.ts +15 -0
  214. package/dist/types/napi.d.ts.map +1 -0
  215. package/dist/types/napi.js +2 -0
  216. package/dist/types/napi.js.map +1 -0
  217. package/package.json +107 -0
  218. package/src/adapters/cloudflare.ts +30 -0
  219. package/src/adapters/deno.ts +21 -0
  220. package/src/adapters/web.ts +259 -0
  221. package/src/cli.ts +68 -0
  222. package/src/client/hooks.test.ts +54 -0
  223. package/src/client/hooks.ts +329 -0
  224. package/src/client/index.ts +5 -0
  225. package/src/client/offline-sw.ts +191 -0
  226. package/src/client/offline.ts +114 -0
  227. package/src/client/provider.tsx +14 -0
  228. package/src/commands/build.ts +201 -0
  229. package/src/commands/dev.ts +509 -0
  230. package/src/commands/info.ts +111 -0
  231. package/src/commands/ssg.ts +177 -0
  232. package/src/commands/start.ts +32 -0
  233. package/src/commands/test.ts +102 -0
  234. package/src/components/ErrorBoundary.tsx +73 -0
  235. package/src/components/Font.tsx +100 -0
  236. package/src/components/Image.tsx +141 -0
  237. package/src/components/Link.tsx +64 -0
  238. package/src/components/Script.tsx +97 -0
  239. package/src/components/index.ts +9 -0
  240. package/src/i18n/i18n.test.tsx +169 -0
  241. package/src/i18n/index.tsx +256 -0
  242. package/src/index.ts +10 -0
  243. package/src/router/code-router.test.ts +146 -0
  244. package/src/router/code-router.tsx +459 -0
  245. package/src/router/index.ts +18 -0
  246. package/src/router/manifest.ts +13 -0
  247. package/src/server/app.ts +466 -0
  248. package/src/server/cache.test.ts +192 -0
  249. package/src/server/cache.ts +195 -0
  250. package/src/server/csrf.test.ts +199 -0
  251. package/src/server/csrf.ts +80 -0
  252. package/src/server/image.ts +112 -0
  253. package/src/server/index.ts +144 -0
  254. package/src/server/middleware.test.ts +151 -0
  255. package/src/server/middleware.ts +95 -0
  256. package/src/server/revalidate.test.ts +106 -0
  257. package/src/server/revalidate.ts +75 -0
  258. package/src/server/server-fn.test.ts +127 -0
  259. package/src/server/sitemap.test.ts +68 -0
  260. package/src/server/sitemap.ts +30 -0
  261. package/src/server/sse.test.ts +81 -0
  262. package/src/server/sse.ts +110 -0
  263. package/src/signals/index.ts +177 -0
  264. package/src/signals/signals.test.ts +164 -0
  265. package/src/ssr/html.test.ts +200 -0
  266. package/src/ssr/html.ts +140 -0
  267. package/src/ssr/render.ts +144 -0
  268. package/src/ssr/router-dev.test.ts +230 -0
  269. package/src/ssr/router-dev.ts +229 -0
  270. package/src/test/index.ts +206 -0
  271. package/src/types/compiler.d.ts +25 -0
  272. package/src/types/index.ts +147 -0
  273. package/src/types/napi.ts +20 -0
  274. package/src/types/plugins.d.ts +3 -0
  275. package/tsconfig.json +11 -0
  276. package/tsconfig.tsbuildinfo +1 -0
  277. package/vitest.config.ts +32 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Alab i18n — locale routing with zero runtime overhead.
3
+ *
4
+ * Locale is detected once per request (from URL prefix → cookie → Accept-Language)
5
+ * and injected into a React context. Pages are served at `/:locale/path`.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // i18n.ts (project root)
10
+ * import { createI18nConfig } from "alabjs/i18n";
11
+ *
12
+ * export const i18n = createI18nConfig({
13
+ * locales: ["en", "fil", "es"],
14
+ * defaultLocale: "en",
15
+ * });
16
+ * ```
17
+ *
18
+ * ```ts
19
+ * // middleware.ts — redirect bare paths to locale prefix
20
+ * import { i18n } from "./i18n.js";
21
+ * import { redirect } from "alabjs/middleware";
22
+ *
23
+ * export async function middleware(req: Request) {
24
+ * const locale = i18n.detectLocale(req);
25
+ * const { pathname } = new URL(req.url);
26
+ *
27
+ * // Already has a locale prefix — pass through
28
+ * if (i18n.hasLocalePrefix(pathname)) return;
29
+ *
30
+ * // Redirect /about → /en/about
31
+ * return redirect(`/${locale}${pathname}`);
32
+ * }
33
+ * ```
34
+ *
35
+ * ```tsx
36
+ * // app/[locale]/layout.tsx
37
+ * import { LocaleProvider } from "alabjs/i18n";
38
+ *
39
+ * export default function LocaleLayout({ params, children }) {
40
+ * return <LocaleProvider locale={params.locale}>{children}</LocaleProvider>;
41
+ * }
42
+ * ```
43
+ */
44
+ import { type ReactNode } from "react";
45
+ export interface I18nConfig {
46
+ /** All supported locale codes, e.g. `["en", "fil", "es"]`. */
47
+ locales: string[];
48
+ /** Locale used when no match is found. Must be in `locales`. */
49
+ defaultLocale: string;
50
+ }
51
+ export interface I18nInstance extends I18nConfig {
52
+ /**
53
+ * Detect the best locale for an incoming request.
54
+ *
55
+ * Priority order:
56
+ * 1. URL pathname prefix (`/en/`, `/fil/`)
57
+ * 2. `locale` cookie
58
+ * 3. `Accept-Language` header (first matching locale)
59
+ * 4. `defaultLocale`
60
+ */
61
+ detectLocale(req: Request): string;
62
+ /** Return true if the pathname already starts with a supported locale prefix. */
63
+ hasLocalePrefix(pathname: string): boolean;
64
+ /**
65
+ * Strip the locale prefix from a pathname.
66
+ * `/en/about` → `/about`, `/about` → `/about`
67
+ */
68
+ stripLocale(pathname: string): string;
69
+ /**
70
+ * Build a locale-prefixed path.
71
+ * `localePath("fil", "/about")` → `/fil/about`
72
+ */
73
+ localePath(locale: string, path: string): string;
74
+ }
75
+ /**
76
+ * Create an i18n configuration instance.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * export const i18n = createI18nConfig({ locales: ["en", "fil"], defaultLocale: "en" });
81
+ * ```
82
+ */
83
+ export declare function createI18nConfig(config: I18nConfig): I18nInstance;
84
+ export interface LocaleProviderProps {
85
+ locale: string;
86
+ children: ReactNode;
87
+ }
88
+ /**
89
+ * Provide the current locale to all child components.
90
+ * Place this in your `app/[locale]/layout.tsx`.
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * export default function LocaleLayout({ params, children }) {
95
+ * return <LocaleProvider locale={params.locale}>{children}</LocaleProvider>;
96
+ * }
97
+ * ```
98
+ */
99
+ export declare function LocaleProvider({ locale, children }: LocaleProviderProps): import("react/jsx-runtime").JSX.Element;
100
+ /**
101
+ * Read the current locale from context.
102
+ * Must be used inside a `<LocaleProvider>`.
103
+ *
104
+ * @example
105
+ * ```tsx
106
+ * const locale = useLocale(); // "en" | "fil" | "es"
107
+ * ```
108
+ */
109
+ export declare function useLocale(): string;
110
+ import type { AnchorHTMLAttributes } from "react";
111
+ export interface LocaleLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
112
+ href: string;
113
+ /**
114
+ * Override the locale for this link. Defaults to the current locale from context.
115
+ * Pass `false` to emit the href with no locale prefix.
116
+ */
117
+ locale?: string | false;
118
+ }
119
+ /**
120
+ * A `<Link>`-compatible anchor that automatically prefixes the `href` with
121
+ * the current (or specified) locale.
122
+ *
123
+ * @example
124
+ * ```tsx
125
+ * // Current locale is "en"
126
+ * <LocaleLink href="/about">About</LocaleLink>
127
+ * // renders: <a href="/en/about">About</a>
128
+ *
129
+ * // Switch to Filipino
130
+ * <LocaleLink href="/about" locale="fil">Filipino</LocaleLink>
131
+ * // renders: <a href="/fil/about">Filipino</a>
132
+ * ```
133
+ */
134
+ export declare function LocaleLink({ href, locale, children, onClick, ...rest }: LocaleLinkProps): import("react/jsx-runtime").JSX.Element;
135
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlE,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C;;;;;;;;OAQG;IACH,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,iFAAiF;IACjF,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAClD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAgDjE;AAMD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CAEvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAID,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElD,MAAM,WAAW,eAAgB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,2CAmBvF"}
@@ -0,0 +1,189 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Alab i18n — locale routing with zero runtime overhead.
4
+ *
5
+ * Locale is detected once per request (from URL prefix → cookie → Accept-Language)
6
+ * and injected into a React context. Pages are served at `/:locale/path`.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * // i18n.ts (project root)
11
+ * import { createI18nConfig } from "alabjs/i18n";
12
+ *
13
+ * export const i18n = createI18nConfig({
14
+ * locales: ["en", "fil", "es"],
15
+ * defaultLocale: "en",
16
+ * });
17
+ * ```
18
+ *
19
+ * ```ts
20
+ * // middleware.ts — redirect bare paths to locale prefix
21
+ * import { i18n } from "./i18n.js";
22
+ * import { redirect } from "alabjs/middleware";
23
+ *
24
+ * export async function middleware(req: Request) {
25
+ * const locale = i18n.detectLocale(req);
26
+ * const { pathname } = new URL(req.url);
27
+ *
28
+ * // Already has a locale prefix — pass through
29
+ * if (i18n.hasLocalePrefix(pathname)) return;
30
+ *
31
+ * // Redirect /about → /en/about
32
+ * return redirect(`/${locale}${pathname}`);
33
+ * }
34
+ * ```
35
+ *
36
+ * ```tsx
37
+ * // app/[locale]/layout.tsx
38
+ * import { LocaleProvider } from "alabjs/i18n";
39
+ *
40
+ * export default function LocaleLayout({ params, children }) {
41
+ * return <LocaleProvider locale={params.locale}>{children}</LocaleProvider>;
42
+ * }
43
+ * ```
44
+ */
45
+ import { createContext, useContext } from "react";
46
+ /**
47
+ * Create an i18n configuration instance.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * export const i18n = createI18nConfig({ locales: ["en", "fil"], defaultLocale: "en" });
52
+ * ```
53
+ */
54
+ export function createI18nConfig(config) {
55
+ const { locales, defaultLocale } = config;
56
+ if (!locales.includes(defaultLocale)) {
57
+ throw new Error(`[alabjs/i18n] defaultLocale "${defaultLocale}" must be in the locales array`);
58
+ }
59
+ const localeSet = new Set(locales);
60
+ function detectLocale(req) {
61
+ const url = new URL(req.url);
62
+ // 1. URL prefix
63
+ const firstSegment = url.pathname.split("/")[1] ?? "";
64
+ if (localeSet.has(firstSegment))
65
+ return firstSegment;
66
+ // 2. Cookie
67
+ const cookieHeader = req.headers.get("cookie") ?? "";
68
+ const localeCookie = parseCookieLocale(cookieHeader, locales);
69
+ if (localeCookie)
70
+ return localeCookie;
71
+ // 3. Accept-Language
72
+ const acceptLang = req.headers.get("accept-language") ?? "";
73
+ const detected = parseAcceptLanguage(acceptLang, locales);
74
+ if (detected)
75
+ return detected;
76
+ return defaultLocale;
77
+ }
78
+ function hasLocalePrefix(pathname) {
79
+ const first = pathname.split("/")[1] ?? "";
80
+ return localeSet.has(first);
81
+ }
82
+ function stripLocale(pathname) {
83
+ const first = pathname.split("/")[1] ?? "";
84
+ if (localeSet.has(first)) {
85
+ return pathname.slice(first.length + 1) || "/";
86
+ }
87
+ return pathname;
88
+ }
89
+ function localePath(locale, path) {
90
+ const clean = path.startsWith("/") ? path : `/${path}`;
91
+ return `/${locale}${clean}`;
92
+ }
93
+ return { locales, defaultLocale, detectLocale, hasLocalePrefix, stripLocale, localePath };
94
+ }
95
+ // ─── React context ────────────────────────────────────────────────────────────
96
+ const LocaleCtx = createContext("en");
97
+ /**
98
+ * Provide the current locale to all child components.
99
+ * Place this in your `app/[locale]/layout.tsx`.
100
+ *
101
+ * @example
102
+ * ```tsx
103
+ * export default function LocaleLayout({ params, children }) {
104
+ * return <LocaleProvider locale={params.locale}>{children}</LocaleProvider>;
105
+ * }
106
+ * ```
107
+ */
108
+ export function LocaleProvider({ locale, children }) {
109
+ return _jsx(LocaleCtx.Provider, { value: locale, children: children });
110
+ }
111
+ /**
112
+ * Read the current locale from context.
113
+ * Must be used inside a `<LocaleProvider>`.
114
+ *
115
+ * @example
116
+ * ```tsx
117
+ * const locale = useLocale(); // "en" | "fil" | "es"
118
+ * ```
119
+ */
120
+ export function useLocale() {
121
+ return useContext(LocaleCtx);
122
+ }
123
+ /**
124
+ * A `<Link>`-compatible anchor that automatically prefixes the `href` with
125
+ * the current (or specified) locale.
126
+ *
127
+ * @example
128
+ * ```tsx
129
+ * // Current locale is "en"
130
+ * <LocaleLink href="/about">About</LocaleLink>
131
+ * // renders: <a href="/en/about">About</a>
132
+ *
133
+ * // Switch to Filipino
134
+ * <LocaleLink href="/about" locale="fil">Filipino</LocaleLink>
135
+ * // renders: <a href="/fil/about">Filipino</a>
136
+ * ```
137
+ */
138
+ export function LocaleLink({ href, locale, children, onClick, ...rest }) {
139
+ const currentLocale = useLocale();
140
+ const targetLocale = locale === false ? null : (locale ?? currentLocale);
141
+ const resolvedHref = targetLocale ? `/${targetLocale}${href.startsWith("/") ? href : `/${href}`}` : href;
142
+ const handleClick = (e) => {
143
+ onClick?.(e);
144
+ if (e.defaultPrevented)
145
+ return;
146
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
147
+ return;
148
+ e.preventDefault();
149
+ if (typeof window !== "undefined" && "__alabjs_navigate" in window) {
150
+ window.__alabjs_navigate(resolvedHref);
151
+ }
152
+ else {
153
+ window.location.href = resolvedHref;
154
+ }
155
+ };
156
+ return _jsx("a", { href: resolvedHref, onClick: handleClick, ...rest, children: children });
157
+ }
158
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
159
+ function parseCookieLocale(cookieHeader, locales) {
160
+ for (const part of cookieHeader.split(";")) {
161
+ const [key, val] = part.trim().split("=");
162
+ if (key?.trim() === "locale" && val && locales.includes(val.trim())) {
163
+ return val.trim();
164
+ }
165
+ }
166
+ return null;
167
+ }
168
+ function parseAcceptLanguage(header, locales) {
169
+ // Parse "en-US,en;q=0.9,fil;q=0.8" → [["en-US", 1], ["en", 0.9], ["fil", 0.8]]
170
+ const entries = header
171
+ .split(",")
172
+ .map((part) => {
173
+ const [lang, q] = part.trim().split(";q=");
174
+ return { lang: lang?.trim() ?? "", q: parseFloat(q ?? "1") };
175
+ })
176
+ .sort((a, b) => b.q - a.q);
177
+ for (const { lang } of entries) {
178
+ // Exact match first (e.g. "fil")
179
+ if (locales.includes(lang))
180
+ return lang;
181
+ // Language-only match (e.g. "en" matches "en-US")
182
+ const base = lang.split("-")[0] ?? "";
183
+ const match = locales.find((l) => l === base || l.startsWith(base + "-"));
184
+ if (match)
185
+ return match;
186
+ }
187
+ return null;
188
+ }
189
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAoClE;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAE1C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,gCAAgC,aAAa,gCAAgC,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAEnC,SAAS,YAAY,CAAC,GAAY;QAChC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,gBAAgB;QAChB,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC;YAAE,OAAO,YAAY,CAAC;QAErD,YAAY;QACZ,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9D,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;QAEtC,qBAAqB;QACrB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,SAAS,eAAe,CAAC,QAAgB;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS,WAAW,CAAC,QAAgB;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QACjD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS,UAAU,CAAC,MAAc,EAAE,IAAY;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QACvD,OAAO,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAC5F,CAAC;AAED,iFAAiF;AAEjF,MAAM,SAAS,GAAG,aAAa,CAAS,IAAI,CAAC,CAAC;AAO9C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAuB;IACtE,OAAO,KAAC,SAAS,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,QAAQ,GAAsB,CAAC;AAC5E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAeD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,EAAmB;IACtF,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC;IAEzE,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEzG,MAAM,WAAW,GAA+C,CAAC,CAAC,EAAE,EAAE;QACpE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,CAAC,gBAAgB;YAAE,OAAO;QAC/B,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO;QAC7D,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,mBAAmB,IAAI,MAAM,EAAE,CAAC;YAClE,MAAqD,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,YAAG,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,KAAM,IAAI,YAAG,QAAQ,GAAK,CAAC;AAC/E,CAAC;AAED,iFAAiF;AAEjF,SAAS,iBAAiB,CAAC,YAAoB,EAAE,OAAiB;IAChE,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,QAAQ,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACpE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc,EAAE,OAAiB;IAC5D,+EAA+E;IAC/E,MAAM,OAAO,GAAG,MAAM;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;IAC/D,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7B,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;QAC/B,iCAAiC;QACjC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACxC,kDAAkD;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;QAC1E,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { defineServerFn } from "./server/index.js";
2
+ export type { ServerFn, ServerFnContext, AlabPage, PageMetadata, GenerateMetadata, RouteParams, } from "./types/index.js";
3
+ export { createApp } from "./server/app.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EACV,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { defineServerFn } from "./server/index.js";
2
+ export { createApp } from "./server/app.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Alab Code-Based Router — type-safe client-side navigation.
3
+ *
4
+ * The file-system router stays the default (zero config). This module is
5
+ * opt-in for large apps that need IDE searchability, typed `href` props,
6
+ * search param schemas, and co-located loaders.
7
+ *
8
+ * Inspired by TanStack Router.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * // routes.ts
13
+ * import { createRoute, createRouter } from "alabjs/router";
14
+ * import { z } from "zod";
15
+ * import UserPage from "./app/users/[id]/page.js";
16
+ * import UserError from "./app/users/[id]/error.js";
17
+ *
18
+ * export const userRoute = createRoute({
19
+ * path: "/users/$id",
20
+ * search: z.object({ tab: z.enum(["posts", "about"]).optional() }),
21
+ * loader: ({ params }) => getUser(params.id),
22
+ * component: UserPage,
23
+ * errorComponent: UserError,
24
+ * });
25
+ *
26
+ * export const router = createRouter([userRoute]);
27
+ * ```
28
+ *
29
+ * ```tsx
30
+ * // app/layout.tsx
31
+ * import { RouterProvider } from "alabjs/router";
32
+ * import { router } from "../routes.js";
33
+ *
34
+ * export default function RootLayout({ children }) {
35
+ * return <RouterProvider router={router}>{children}</RouterProvider>;
36
+ * }
37
+ * ```
38
+ */
39
+ import { type ComponentType, type ReactNode } from "react";
40
+ /** Extract `$param` names from a path string. */
41
+ type ExtractRouteParams<Path extends string> = Path extends `${string}$${infer Param}/${infer Rest}` ? Param | ExtractRouteParams<`/${Rest}`> : Path extends `${string}$${infer Param}` ? Param : never;
42
+ /** Typed record of path params for a route. */
43
+ export type RouteParams<Path extends string> = [
44
+ ExtractRouteParams<Path>
45
+ ] extends [never] ? Record<string, never> : {
46
+ readonly [K in ExtractRouteParams<Path>]: string;
47
+ };
48
+ interface SchemaLike<T> {
49
+ parse(input: unknown): T;
50
+ safeParse(input: unknown): {
51
+ success: true;
52
+ data: T;
53
+ } | {
54
+ success: false;
55
+ error: unknown;
56
+ };
57
+ }
58
+ type InferSchema<S> = S extends SchemaLike<infer T> ? T : Record<string, string>;
59
+ export interface RouteConfig<Path extends string, Search extends SchemaLike<unknown> | undefined, LoaderData> {
60
+ /** URL path using `$param` syntax: `"/users/$id"`, `"/posts/$slug/edit"`. */
61
+ path: Path;
62
+ /**
63
+ * Zod (or any schema) that validates + parses search params.
64
+ * Parsed value is available via `useSearch(route)`.
65
+ */
66
+ search?: Search;
67
+ /**
68
+ * Runs before the component mounts — blocks render until resolved.
69
+ * Data is available via `useLoaderData(route)`.
70
+ */
71
+ loader?: (ctx: {
72
+ params: RouteParams<Path>;
73
+ search: Search extends SchemaLike<unknown> ? InferSchema<Search> : Record<string, string>;
74
+ }) => Promise<LoaderData>;
75
+ /** The page component for this route. */
76
+ component: ComponentType<{
77
+ params: RouteParams<Path>;
78
+ search: Search extends SchemaLike<unknown> ? InferSchema<Search> : Record<string, string>;
79
+ loaderData: LoaderData;
80
+ }>;
81
+ /**
82
+ * Rendered when the loader throws or component throws during render.
83
+ * Equivalent to `error.tsx` in the file-system router.
84
+ */
85
+ errorComponent?: ComponentType<{
86
+ error: Error;
87
+ reset: () => void;
88
+ }>;
89
+ /**
90
+ * Rendered while the loader is running.
91
+ * Equivalent to `loading.tsx` in the file-system router.
92
+ */
93
+ pendingComponent?: ComponentType;
94
+ }
95
+ export interface RouteDescriptor<Path extends string = string, Search extends SchemaLike<unknown> | undefined = undefined, LoaderData = undefined> extends RouteConfig<Path, Search, LoaderData> {
96
+ /** @internal Compiled regex for matching this route's path. */
97
+ _regex: RegExp;
98
+ /** @internal Ordered param names extracted from the path. */
99
+ _paramNames: string[];
100
+ }
101
+ /**
102
+ * Define a type-safe route.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * export const postRoute = createRoute({
107
+ * path: "/posts/$id",
108
+ * loader: ({ params }) => fetchPost(params.id),
109
+ * component: PostPage,
110
+ * });
111
+ * ```
112
+ */
113
+ export declare function createRoute<Path extends string, Search extends SchemaLike<unknown> | undefined = undefined, LoaderData = undefined>(config: RouteConfig<Path, Search, LoaderData>): RouteDescriptor<Path, Search, LoaderData>;
114
+ export interface Router {
115
+ routes: RouteDescriptor[];
116
+ }
117
+ /** Assemble multiple routes into a router instance. */
118
+ export declare function createRouter(routes: RouteDescriptor[]): Router;
119
+ export interface RouterProviderProps {
120
+ router: Router;
121
+ children?: ReactNode;
122
+ }
123
+ /**
124
+ * Wrap your root layout with `RouterProvider` to enable typed navigation.
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * import { RouterProvider } from "alabjs/router";
129
+ * import { router } from "../routes.js";
130
+ *
131
+ * export default function RootLayout({ children }) {
132
+ * return <RouterProvider router={router}>{children}</RouterProvider>;
133
+ * }
134
+ * ```
135
+ */
136
+ export declare function RouterProvider({ router, children }: RouterProviderProps): import("react/jsx-runtime").JSX.Element;
137
+ /**
138
+ * Access typed path params for a specific route.
139
+ *
140
+ * @example
141
+ * ```tsx
142
+ * const params = useParams(userRoute);
143
+ * params.id; // string ✅
144
+ * params.foo; // TS error ✅
145
+ * ```
146
+ */
147
+ export declare function useParams<Path extends string, S extends SchemaLike<unknown> | undefined, L>(_route: RouteDescriptor<Path, S, L>): RouteParams<Path>;
148
+ /**
149
+ * Access typed, schema-validated search params for a specific route.
150
+ *
151
+ * @example
152
+ * ```tsx
153
+ * const search = useSearch(postRoute);
154
+ * search.tab; // "posts" | "about" | undefined ✅
155
+ * ```
156
+ */
157
+ export declare function useSearch<Path extends string, S extends SchemaLike<unknown> | undefined, L>(_route: RouteDescriptor<Path, S, L>): S extends SchemaLike<unknown> ? InferSchema<S> : Record<string, string>;
158
+ /**
159
+ * Access the data returned by the route's `loader` function.
160
+ *
161
+ * @example
162
+ * ```tsx
163
+ * const user = useLoaderData(userRoute);
164
+ * user.name; // typed from loader return ✅
165
+ * ```
166
+ */
167
+ export declare function useLoaderData<Path extends string, S extends SchemaLike<unknown> | undefined, L>(_route: RouteDescriptor<Path, S, L>): L;
168
+ /**
169
+ * Returns a typed `navigate` function.
170
+ *
171
+ * @example
172
+ * ```tsx
173
+ * const nav = useNavigate();
174
+ * nav("/users/42");
175
+ * nav("/users/42?tab=posts");
176
+ * ```
177
+ */
178
+ export declare function useNavigate(): (href: string) => void;
179
+ type LinkToRoute<Path extends string, S extends SchemaLike<unknown> | undefined, L> = {
180
+ /** Destination route descriptor (replaces `href`). */
181
+ to: RouteDescriptor<Path, S, L>;
182
+ /** Path params — required when the route has dynamic segments. */
183
+ params?: RouteParams<Path>;
184
+ /** Search params to append. */
185
+ search?: S extends SchemaLike<infer T> ? Partial<T & Record<string, string>> : Record<string, string>;
186
+ children?: ReactNode;
187
+ className?: string;
188
+ style?: React.CSSProperties;
189
+ onClick?: React.MouseEventHandler<HTMLAnchorElement>;
190
+ };
191
+ /**
192
+ * A type-safe `<Link>` bound to a route descriptor.
193
+ * Compile-time error if required params are missing or wrong type.
194
+ *
195
+ * @example
196
+ * ```tsx
197
+ * <RouteLink to={userRoute} params={{ id: "42" }}>
198
+ * View user
199
+ * </RouteLink>
200
+ * ```
201
+ */
202
+ export declare function RouteLink<Path extends string, S extends SchemaLike<unknown> | undefined, L>({ to, params, search, children, onClick, ...rest }: LinkToRoute<Path, S, L>): import("react/jsx-runtime").JSX.Element;
203
+ export {};
204
+ //# sourceMappingURL=code-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-router.d.ts","sourceRoot":"","sources":["../../src/router/code-router.tsx"],"names":[],"mappings":"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"}