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,178 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { htmlShellBefore, htmlShellAfter } from "./html.js";
3
+ describe("htmlShellBefore", () => {
4
+ const baseOpts = {
5
+ metadata: {},
6
+ paramsJson: "{}",
7
+ searchParamsJson: "{}",
8
+ routeFile: "app/page.tsx",
9
+ ssr: false,
10
+ };
11
+ it("produces valid HTML doctype and structure", () => {
12
+ const html = htmlShellBefore(baseOpts);
13
+ expect(html).toContain("<!doctype html>");
14
+ expect(html).toContain('<html lang="en">');
15
+ expect(html).toContain('<meta charset="UTF-8" />');
16
+ expect(html).toContain('<div id="alabjs-root">');
17
+ });
18
+ it("includes alabjs-route meta tag", () => {
19
+ const html = htmlShellBefore(baseOpts);
20
+ expect(html).toContain('<meta name="alabjs-route" content="app/page.tsx" />');
21
+ });
22
+ it("includes alabjs-ssr meta tag set to false", () => {
23
+ const html = htmlShellBefore(baseOpts);
24
+ expect(html).toContain('<meta name="alabjs-ssr" content="false" />');
25
+ });
26
+ it("includes alabjs-ssr meta tag set to true", () => {
27
+ const html = htmlShellBefore({ ...baseOpts, ssr: true });
28
+ expect(html).toContain('<meta name="alabjs-ssr" content="true" />');
29
+ });
30
+ it("embeds params JSON", () => {
31
+ const html = htmlShellBefore({
32
+ ...baseOpts,
33
+ paramsJson: '{"id":"42"}',
34
+ });
35
+ expect(html).toContain('<meta name="alabjs-params" content="{&quot;id&quot;:&quot;42&quot;}" />');
36
+ });
37
+ it("includes title tag when metadata has title", () => {
38
+ const html = htmlShellBefore({
39
+ ...baseOpts,
40
+ metadata: { title: "My Page" },
41
+ });
42
+ expect(html).toContain("<title>My Page</title>");
43
+ });
44
+ it("escapes HTML in title", () => {
45
+ const html = htmlShellBefore({
46
+ ...baseOpts,
47
+ metadata: { title: "<script>alert(1)</script>" },
48
+ });
49
+ expect(html).not.toContain("<script>alert(1)</script>");
50
+ expect(html).toContain("&lt;script&gt;");
51
+ });
52
+ it("includes description meta tag", () => {
53
+ const html = htmlShellBefore({
54
+ ...baseOpts,
55
+ metadata: { description: "A test page" },
56
+ });
57
+ expect(html).toContain('<meta name="description" content="A test page" />');
58
+ });
59
+ it("includes canonical link", () => {
60
+ const html = htmlShellBefore({
61
+ ...baseOpts,
62
+ metadata: { canonical: "https://example.com/page" },
63
+ });
64
+ expect(html).toContain('<link rel="canonical" href="https://example.com/page" />');
65
+ });
66
+ it("includes robots meta tag", () => {
67
+ const html = htmlShellBefore({
68
+ ...baseOpts,
69
+ metadata: { robots: "noindex, nofollow" },
70
+ });
71
+ expect(html).toContain('<meta name="robots" content="noindex, nofollow" />');
72
+ });
73
+ it("includes theme-color meta tag", () => {
74
+ const html = htmlShellBefore({
75
+ ...baseOpts,
76
+ metadata: { themeColor: "#ff6600" },
77
+ });
78
+ expect(html).toContain('<meta name="theme-color" content="#ff6600" />');
79
+ });
80
+ it("includes Open Graph tags", () => {
81
+ const html = htmlShellBefore({
82
+ ...baseOpts,
83
+ metadata: {
84
+ og: {
85
+ title: "OG Title",
86
+ description: "OG Desc",
87
+ image: "https://example.com/og.png",
88
+ url: "https://example.com",
89
+ type: "website",
90
+ siteName: "Example",
91
+ },
92
+ },
93
+ });
94
+ expect(html).toContain('<meta property="og:title" content="OG Title" />');
95
+ expect(html).toContain('<meta property="og:description" content="OG Desc" />');
96
+ expect(html).toContain('<meta property="og:image" content="https://example.com/og.png" />');
97
+ expect(html).toContain('<meta property="og:url" content="https://example.com" />');
98
+ expect(html).toContain('<meta property="og:type" content="website" />');
99
+ expect(html).toContain('<meta property="og:site_name" content="Example" />');
100
+ });
101
+ it("includes Twitter Card tags", () => {
102
+ const html = htmlShellBefore({
103
+ ...baseOpts,
104
+ metadata: {
105
+ twitter: {
106
+ card: "summary_large_image",
107
+ title: "TW Title",
108
+ description: "TW Desc",
109
+ image: "https://example.com/tw.png",
110
+ creator: "@alabjs",
111
+ },
112
+ },
113
+ });
114
+ expect(html).toContain('<meta name="twitter:card" content="summary_large_image" />');
115
+ expect(html).toContain('<meta name="twitter:title" content="TW Title" />');
116
+ expect(html).toContain('<meta name="twitter:creator" content="@alabjs" />');
117
+ });
118
+ it("includes extra meta tags", () => {
119
+ const html = htmlShellBefore({
120
+ ...baseOpts,
121
+ metadata: {
122
+ extra: [
123
+ { name: "author", content: "AlabJS Team" },
124
+ { property: "article:author", content: "https://example.com" },
125
+ ],
126
+ },
127
+ });
128
+ expect(html).toContain('name="author"');
129
+ expect(html).toContain('content="AlabJS Team"');
130
+ expect(html).toContain('property="article:author"');
131
+ });
132
+ it("includes layouts meta tag when provided", () => {
133
+ const html = htmlShellBefore({
134
+ ...baseOpts,
135
+ layoutsJson: '["app/layout.tsx"]',
136
+ });
137
+ expect(html).toContain('name="alabjs-layouts"');
138
+ });
139
+ it("includes loading meta tag when provided", () => {
140
+ const html = htmlShellBefore({
141
+ ...baseOpts,
142
+ loadingFile: "app/loading.tsx",
143
+ });
144
+ expect(html).toContain('<meta name="alabjs-loading" content="app/loading.tsx" />');
145
+ });
146
+ it("includes headExtra content", () => {
147
+ const html = htmlShellBefore({
148
+ ...baseOpts,
149
+ headExtra: '<meta name="csrf-token" content="abc123" />',
150
+ });
151
+ expect(html).toContain('<meta name="csrf-token" content="abc123" />');
152
+ });
153
+ it("includes globals.css link", () => {
154
+ const html = htmlShellBefore(baseOpts);
155
+ expect(html).toContain('<link rel="stylesheet" href="/app/globals.css" />');
156
+ });
157
+ });
158
+ describe("htmlShellAfter", () => {
159
+ it("closes the alabjs-root div and body/html", () => {
160
+ const html = htmlShellAfter({});
161
+ expect(html).toContain("</div>");
162
+ expect(html).toContain("</body>");
163
+ expect(html).toContain("</html>");
164
+ });
165
+ it("includes the client script tag", () => {
166
+ const html = htmlShellAfter({});
167
+ expect(html).toContain('<script type="module" src="/@alabjs/client">');
168
+ });
169
+ it("includes nonce when provided", () => {
170
+ const html = htmlShellAfter({ nonce: "abc123" });
171
+ expect(html).toContain('nonce="abc123"');
172
+ });
173
+ it("escapes quotes in nonce", () => {
174
+ const html = htmlShellAfter({ nonce: 'test"nonce' });
175
+ expect(html).toContain("&quot;");
176
+ });
177
+ });
178
+ //# sourceMappingURL=html.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.test.js","sourceRoot":"","sources":["../../src/ssr/html.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { type ComponentType } from "react";
2
+ import type { ServerResponse } from "node:http";
3
+ import type { PageMetadata } from "../types/index.js";
4
+ export interface RenderOptions {
5
+ /** The React page component. */
6
+ Page: ComponentType<{
7
+ params: Record<string, string>;
8
+ searchParams: Record<string, string>;
9
+ }>;
10
+ /** Layout components to wrap the page, ordered outermost → innermost. */
11
+ layouts?: ComponentType<any>[];
12
+ /** Parsed route params (e.g. `{ id: "123" }`). */
13
+ params: Record<string, string>;
14
+ /** Parsed query params. */
15
+ searchParams: Record<string, string>;
16
+ /** Metadata exported by the page module (`export const metadata = ...`). */
17
+ metadata?: PageMetadata;
18
+ /** Relative path to the page module, embedded in the HTML for client hydration. */
19
+ routeFile: string;
20
+ /** JSON array of layout file paths for client-side hydration. */
21
+ layoutsJson?: string;
22
+ /** Relative path to nearest loading.tsx, for client Suspense fallback. */
23
+ loadingFile?: string | undefined;
24
+ /** Whether SSR is enabled for this route. */
25
+ ssr: boolean;
26
+ /** Extra HTML to inject into <head> (Vite injects its HMR tags here in dev). */
27
+ headExtra?: string;
28
+ /** CSP nonce (optional). */
29
+ nonce?: string;
30
+ }
31
+ /**
32
+ * Render a page component to a streaming HTTP response using React 19's
33
+ * `renderToPipeableStream`. The HTML shell is split at the `<div id="alab-root">`
34
+ * boundary: the opening fragment is flushed before React begins streaming, and
35
+ * the closing fragment is appended when the stream finishes.
36
+ */
37
+ export declare function renderToResponse(res: ServerResponse, opts: RenderOptions): void;
38
+ /**
39
+ * Render a page component to a full HTML string.
40
+ * Used in dev mode when streaming is not needed (faster iteration).
41
+ */
42
+ export declare function renderToString(Page: ComponentType<{
43
+ params: Record<string, string>;
44
+ searchParams: Record<string, string>;
45
+ }>, params: Record<string, string>, searchParams: Record<string, string>): Promise<string>;
46
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/ssr/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,IAAI,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9F,yEAAyE;IAEzE,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,6CAA6C;IAC7C,GAAG,EAAE,OAAO,CAAC;IACb,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CA2F/E;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,EAC7F,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CAAC,MAAM,CAAC,CAGjB"}
@@ -0,0 +1,87 @@
1
+ import { createElement } from "react";
2
+ import { renderToPipeableStream } from "react-dom/server";
3
+ import { Writable } from "node:stream";
4
+ import { htmlShellBefore, htmlShellAfter } from "./html.js";
5
+ /**
6
+ * Render a page component to a streaming HTTP response using React 19's
7
+ * `renderToPipeableStream`. The HTML shell is split at the `<div id="alab-root">`
8
+ * boundary: the opening fragment is flushed before React begins streaming, and
9
+ * the closing fragment is appended when the stream finishes.
10
+ */
11
+ export function renderToResponse(res, opts) {
12
+ const { Page, layouts = [], params, searchParams, metadata = {}, routeFile, layoutsJson, loadingFile, ssr, headExtra, nonce, } = opts;
13
+ const shellOpts = {
14
+ metadata,
15
+ paramsJson: JSON.stringify(params),
16
+ searchParamsJson: JSON.stringify(searchParams),
17
+ routeFile,
18
+ layoutsJson,
19
+ loadingFile,
20
+ ssr,
21
+ headExtra,
22
+ nonce,
23
+ };
24
+ const before = htmlShellBefore(shellOpts);
25
+ const after = htmlShellAfter({ nonce });
26
+ // Build element tree: Page wrapped by layouts outermost→innermost
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ const pageEl = createElement(Page, { params, searchParams });
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const rootEl = layouts.length
31
+ ? layouts.reduceRight((child, Layout) => createElement(Layout, {}, child), pageEl)
32
+ : pageEl;
33
+ let didError = false;
34
+ let headersSent = false;
35
+ const { pipe, abort } = renderToPipeableStream(rootEl, {
36
+ onShellReady() {
37
+ if (headersSent)
38
+ return;
39
+ headersSent = true;
40
+ res.statusCode = didError ? 500 : 200;
41
+ res.setHeader("content-type", "text/html; charset=utf-8");
42
+ res.write(before);
43
+ // Wrap the Node.js response in a Writable that appends the closing
44
+ // shell fragment once React finishes streaming.
45
+ const writable = new Writable({
46
+ write(chunk, _enc, cb) {
47
+ res.write(chunk, cb);
48
+ },
49
+ final(cb) {
50
+ res.write(after);
51
+ res.end();
52
+ cb();
53
+ },
54
+ });
55
+ pipe(writable);
56
+ },
57
+ onShellError(err) {
58
+ // React couldn't render even the shell boundary — send a plain error page.
59
+ if (!headersSent) {
60
+ headersSent = true;
61
+ res.statusCode = 500;
62
+ res.setHeader("content-type", "text/plain; charset=utf-8");
63
+ const msg = err instanceof Error ? err.message : String(err);
64
+ res.end(`[alabjs] SSR shell error in ${routeFile}: ${msg}`);
65
+ }
66
+ console.error(`[alabjs] SSR shell error in ${routeFile}:`, err);
67
+ },
68
+ onError(err) {
69
+ didError = true;
70
+ console.error(`[alabjs] SSR component error in ${routeFile}:`, err);
71
+ },
72
+ });
73
+ // Abort the stream if the client disconnects early.
74
+ res.on("close", () => {
75
+ if (!res.writableEnded)
76
+ abort();
77
+ });
78
+ }
79
+ /**
80
+ * Render a page component to a full HTML string.
81
+ * Used in dev mode when streaming is not needed (faster iteration).
82
+ */
83
+ export async function renderToString(Page, params, searchParams) {
84
+ const { renderToString: reactRenderToString } = await import("react-dom/server");
85
+ return reactRenderToString(createElement(Page, { params, searchParams }));
86
+ }
87
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/ssr/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ export interface DevRoute {
2
+ /** Regex that matches the URL pathname for this route. */
3
+ pattern: RegExp;
4
+ /** Ordered list of param names, matching regex capture groups. */
5
+ paramNames: string[];
6
+ /** Absolute path to the page module on disk. */
7
+ file: string;
8
+ /** Whether SSR is enabled (opt-out via `export const ssr = false`). */
9
+ ssr: boolean;
10
+ }
11
+ /**
12
+ * Scan `appDir` (the project's `app/` directory) for `page.tsx` / `page.ts`
13
+ * files and build a list of matchable routes for the dev server middleware.
14
+ *
15
+ * Only TypeScript files are considered — Alab is TypeScript-only.
16
+ */
17
+ export declare function scanDevRoutes(appDir: string): DevRoute[];
18
+ /**
19
+ * Find all layout.tsx files that apply to a given page file, ordered outermost → innermost.
20
+ *
21
+ * Given `app/dashboard/users/page.tsx`, returns:
22
+ * [ "app/layout.tsx", "app/dashboard/layout.tsx" ] (only those that exist)
23
+ */
24
+ export declare function findLayoutFiles(pageFile: string, appDir: string): string[];
25
+ /**
26
+ * Find the nearest error.tsx file for a given page file, searching innermost → outermost.
27
+ * Returns absolute path or null if none found.
28
+ */
29
+ export declare function findErrorFile(pageFile: string, appDir: string): string | null;
30
+ /**
31
+ * Find the nearest loading.tsx file for a given page file, searching innermost → outermost.
32
+ * Returns absolute path or null if none found.
33
+ */
34
+ export declare function findLoadingFile(pageFile: string, appDir: string): string | null;
35
+ export interface DevApiRoute {
36
+ pattern: RegExp;
37
+ paramNames: string[];
38
+ file: string;
39
+ }
40
+ /**
41
+ * Scan `appDir` for `route.ts` / `route.tsx` files and build a list of API routes.
42
+ * These handle HTTP method exports: GET, POST, PUT, PATCH, DELETE.
43
+ */
44
+ export declare function scanDevApiRoutes(appDir: string): DevApiRoute[];
45
+ /**
46
+ * Match a pathname against the API route list.
47
+ */
48
+ export declare function matchDevApiRoute(routes: DevApiRoute[], pathname: string): {
49
+ route: DevApiRoute;
50
+ params: Record<string, string>;
51
+ } | null;
52
+ /**
53
+ * Match an incoming URL pathname against the dev route list.
54
+ * Returns the matched route and extracted params, or `null` if no match.
55
+ */
56
+ export declare function matchDevRoute(routes: DevRoute[], pathname: string): {
57
+ route: DevRoute;
58
+ params: Record<string, string>;
59
+ } | null;
60
+ //# sourceMappingURL=router-dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-dev.d.ts","sourceRoot":"","sources":["../../src/ssr/router-dev.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAUxD;AAwED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB1E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS/E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAK9D;AAmBD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EAAE,EACrB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAU/D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAAE,EAClB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAY5D"}
@@ -0,0 +1,205 @@
1
+ import { readdirSync, statSync, existsSync } from "node:fs";
2
+ import { join, relative, sep, dirname } from "node:path";
3
+ /**
4
+ * Scan `appDir` (the project's `app/` directory) for `page.tsx` / `page.ts`
5
+ * files and build a list of matchable routes for the dev server middleware.
6
+ *
7
+ * Only TypeScript files are considered — Alab is TypeScript-only.
8
+ */
9
+ export function scanDevRoutes(appDir) {
10
+ const routes = [];
11
+ collectRoutes(appDir, appDir, routes);
12
+ // Sort so that static segments beat dynamic ones (/users/new before /users/[id]).
13
+ routes.sort((a, b) => {
14
+ const aScore = paramScore(a.paramNames.length);
15
+ const bScore = paramScore(b.paramNames.length);
16
+ return aScore - bScore;
17
+ });
18
+ return routes;
19
+ }
20
+ function collectRoutes(appDir, dir, out) {
21
+ let entries;
22
+ try {
23
+ entries = readdirSync(dir);
24
+ }
25
+ catch {
26
+ return;
27
+ }
28
+ for (const entry of entries) {
29
+ const full = join(dir, entry);
30
+ const stat = statSync(full);
31
+ if (stat.isDirectory()) {
32
+ collectRoutes(appDir, full, out);
33
+ }
34
+ else if (entry === "page.tsx" || entry === "page.ts") {
35
+ const rel = relative(appDir, full);
36
+ const urlPath = relFileToUrlPath(rel);
37
+ const { pattern, paramNames } = urlPathToRegex(urlPath);
38
+ out.push({ pattern, paramNames, file: full, ssr: false });
39
+ }
40
+ }
41
+ }
42
+ /**
43
+ * Convert a relative file path (from appDir) to a URL path pattern.
44
+ *
45
+ * Examples:
46
+ * page.tsx → /
47
+ * about/page.tsx → /about
48
+ * users/[id]/page.tsx → /users/[id]
49
+ * users/[id]/posts/page.tsx → /users/[id]/posts
50
+ */
51
+ function relFileToUrlPath(rel) {
52
+ // Normalise Windows separators
53
+ const parts = rel.split(sep).join("/").split("/");
54
+ // Remove the trailing `page.tsx` / `page.ts`
55
+ parts.pop();
56
+ if (parts.length === 0)
57
+ return "/";
58
+ return "/" + parts.join("/");
59
+ }
60
+ /**
61
+ * Convert an Alab URL path pattern to a regex and extract param names.
62
+ *
63
+ * `[id]` → capture group `([^/]+)`, param name `id`
64
+ */
65
+ function urlPathToRegex(urlPath) {
66
+ const paramNames = [];
67
+ const regexStr = urlPath
68
+ .split("/")
69
+ .map((segment) => {
70
+ const match = /^\[(.+)\]$/.exec(segment);
71
+ if (match) {
72
+ paramNames.push(match[1]);
73
+ return "([^/]+)";
74
+ }
75
+ return segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
76
+ })
77
+ .join("/");
78
+ // Match exact path (ignoring trailing slash for non-root paths)
79
+ const pattern = urlPath === "/" ? /^\/$/ : new RegExp(`^${regexStr}\\/?$`);
80
+ return { pattern, paramNames };
81
+ }
82
+ /** Lower score = higher priority (static routes beat dynamic ones). */
83
+ function paramScore(paramCount) {
84
+ return paramCount;
85
+ }
86
+ /**
87
+ * Find all layout.tsx files that apply to a given page file, ordered outermost → innermost.
88
+ *
89
+ * Given `app/dashboard/users/page.tsx`, returns:
90
+ * [ "app/layout.tsx", "app/dashboard/layout.tsx" ] (only those that exist)
91
+ */
92
+ export function findLayoutFiles(pageFile, appDir) {
93
+ const layouts = [];
94
+ let dir = dirname(pageFile);
95
+ // Collect directories from page dir up to (and including) appDir
96
+ const dirs = [];
97
+ while (dir.length >= appDir.length) {
98
+ dirs.unshift(dir); // prepend so we get outermost first
99
+ if (dir === appDir)
100
+ break;
101
+ dir = dirname(dir);
102
+ }
103
+ for (const d of dirs) {
104
+ const candidate = join(d, "layout.tsx");
105
+ if (existsSync(candidate))
106
+ layouts.push(candidate);
107
+ }
108
+ return layouts;
109
+ }
110
+ /**
111
+ * Find the nearest error.tsx file for a given page file, searching innermost → outermost.
112
+ * Returns absolute path or null if none found.
113
+ */
114
+ export function findErrorFile(pageFile, appDir) {
115
+ let dir = dirname(pageFile);
116
+ while (dir.length >= appDir.length) {
117
+ const candidate = join(dir, "error.tsx");
118
+ if (existsSync(candidate))
119
+ return candidate;
120
+ if (dir === appDir)
121
+ break;
122
+ dir = dirname(dir);
123
+ }
124
+ return null;
125
+ }
126
+ /**
127
+ * Find the nearest loading.tsx file for a given page file, searching innermost → outermost.
128
+ * Returns absolute path or null if none found.
129
+ */
130
+ export function findLoadingFile(pageFile, appDir) {
131
+ let dir = dirname(pageFile);
132
+ while (dir.length >= appDir.length) {
133
+ const candidate = join(dir, "loading.tsx");
134
+ if (existsSync(candidate))
135
+ return candidate;
136
+ if (dir === appDir)
137
+ break;
138
+ dir = dirname(dir);
139
+ }
140
+ return null;
141
+ }
142
+ /**
143
+ * Scan `appDir` for `route.ts` / `route.tsx` files and build a list of API routes.
144
+ * These handle HTTP method exports: GET, POST, PUT, PATCH, DELETE.
145
+ */
146
+ export function scanDevApiRoutes(appDir) {
147
+ const routes = [];
148
+ collectApiRoutes(appDir, appDir, routes);
149
+ routes.sort((a, b) => a.paramNames.length - b.paramNames.length);
150
+ return routes;
151
+ }
152
+ function collectApiRoutes(appDir, dir, out) {
153
+ let entries;
154
+ try {
155
+ entries = readdirSync(dir);
156
+ }
157
+ catch {
158
+ return;
159
+ }
160
+ for (const entry of entries) {
161
+ const full = join(dir, entry);
162
+ const stat = statSync(full);
163
+ if (stat.isDirectory()) {
164
+ collectApiRoutes(appDir, full, out);
165
+ }
166
+ else if (entry === "route.ts" || entry === "route.tsx") {
167
+ const rel = relative(appDir, full);
168
+ const urlPath = relFileToUrlPath(rel.replace(/route\.(tsx?)$/, "page.$1"));
169
+ const { pattern, paramNames } = urlPathToRegex(urlPath);
170
+ out.push({ pattern, paramNames, file: full });
171
+ }
172
+ }
173
+ }
174
+ /**
175
+ * Match a pathname against the API route list.
176
+ */
177
+ export function matchDevApiRoute(routes, pathname) {
178
+ for (const route of routes) {
179
+ const m = route.pattern.exec(pathname);
180
+ if (m) {
181
+ const params = {};
182
+ route.paramNames.forEach((name, i) => { params[name] = decodeURIComponent(m[i + 1] ?? ""); });
183
+ return { route, params };
184
+ }
185
+ }
186
+ return null;
187
+ }
188
+ /**
189
+ * Match an incoming URL pathname against the dev route list.
190
+ * Returns the matched route and extracted params, or `null` if no match.
191
+ */
192
+ export function matchDevRoute(routes, pathname) {
193
+ for (const route of routes) {
194
+ const m = route.pattern.exec(pathname);
195
+ if (m) {
196
+ const params = {};
197
+ route.paramNames.forEach((name, i) => {
198
+ params[name] = decodeURIComponent(m[i + 1] ?? "");
199
+ });
200
+ return { route, params };
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ //# sourceMappingURL=router-dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-dev.js","sourceRoot":"","sources":["../../src/ssr/router-dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=router-dev.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-dev.test.d.ts","sourceRoot":"","sources":["../../src/ssr/router-dev.test.ts"],"names":[],"mappings":""}