@timber-js/app 0.2.0-alpha.71 → 0.2.0-alpha.72

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 (248) hide show
  1. package/dist/_chunks/actions-Dg-ANYHb.js +421 -0
  2. package/dist/_chunks/actions-Dg-ANYHb.js.map +1 -0
  3. package/dist/_chunks/{als-registry-BJARkOcu.js → als-registry-HS0LGUl2.js} +1 -1
  4. package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
  5. package/dist/_chunks/{define-Dz1bqwaS.js → define-C77ScO0m.js} +14 -14
  6. package/dist/_chunks/define-C77ScO0m.js.map +1 -0
  7. package/dist/_chunks/{define-CGuYoRHU.js → define-CZqDwhSu.js} +15 -15
  8. package/dist/_chunks/define-CZqDwhSu.js.map +1 -0
  9. package/dist/_chunks/{define-cookie-B5mewxwM.js → define-cookie-C2IkoFGN.js} +9 -8
  10. package/dist/_chunks/{define-cookie-B5mewxwM.js.map → define-cookie-C2IkoFGN.js.map} +1 -1
  11. package/dist/_chunks/{format-Rn922VH2.js → dev-warnings-DpGRGoDi.js} +4 -26
  12. package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
  13. package/dist/_chunks/format-CYBGxKtc.js +14 -0
  14. package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
  15. package/dist/_chunks/{interception-CEdHHviP.js → interception-Dpn_UfAD.js} +2 -2
  16. package/dist/_chunks/{interception-CEdHHviP.js.map → interception-Dpn_UfAD.js.map} +1 -1
  17. package/dist/_chunks/{segment-context-hzuJ048X.js → merge-search-params-Cm_KIWDX.js} +2 -33
  18. package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
  19. package/dist/_chunks/{request-context-CywiO4jV.js → request-context-qMsWgy9C.js} +72 -36
  20. package/dist/_chunks/request-context-qMsWgy9C.js.map +1 -0
  21. package/dist/_chunks/{schema-bridge-C4SwjCQD.js → schema-bridge-C3xl_vfb.js} +1 -1
  22. package/dist/_chunks/{schema-bridge-C4SwjCQD.js.map → schema-bridge-C3xl_vfb.js.map} +1 -1
  23. package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
  24. package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
  25. package/dist/_chunks/ssr-data-DzuI0bIV.js +88 -0
  26. package/dist/_chunks/ssr-data-DzuI0bIV.js.map +1 -0
  27. package/dist/_chunks/{stale-reload-BLUC_Pl_.js → stale-reload-C2plcNtG.js} +1 -1
  28. package/dist/_chunks/{stale-reload-BLUC_Pl_.js.map → stale-reload-C2plcNtG.js.map} +1 -1
  29. package/dist/_chunks/{handler-store-BVePM7hp.js → tracing-CCYbKn5n.js} +60 -60
  30. package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
  31. package/dist/_chunks/use-params-B1AuhI1p.js +307 -0
  32. package/dist/_chunks/use-params-B1AuhI1p.js.map +1 -0
  33. package/dist/_chunks/{use-query-states-DAhgj8Gx.js → use-query-states-Lo_s_pw2.js} +4 -4
  34. package/dist/_chunks/use-query-states-Lo_s_pw2.js.map +1 -0
  35. package/dist/_chunks/{wrappers-LZbghvn0.js → wrappers-_DTmImGt.js} +1 -1
  36. package/dist/_chunks/{wrappers-LZbghvn0.js.map → wrappers-_DTmImGt.js.map} +1 -1
  37. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  38. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  39. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  40. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  41. package/dist/cache/index.d.ts +18 -4
  42. package/dist/cache/index.d.ts.map +1 -1
  43. package/dist/cache/index.js +78 -12
  44. package/dist/cache/index.js.map +1 -1
  45. package/dist/cache/sizeof.d.ts +22 -0
  46. package/dist/cache/sizeof.d.ts.map +1 -0
  47. package/dist/cli.d.ts +6 -1
  48. package/dist/cli.d.ts.map +1 -1
  49. package/dist/cli.js +6 -1
  50. package/dist/cli.js.map +1 -1
  51. package/dist/client/browser-dev.d.ts +27 -1
  52. package/dist/client/browser-dev.d.ts.map +1 -1
  53. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  54. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  55. package/dist/client/browser-entry/hmr.d.ts +21 -0
  56. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  57. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  58. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  59. package/dist/client/browser-entry/index.d.ts +30 -0
  60. package/dist/client/browser-entry/index.d.ts.map +1 -0
  61. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  62. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  63. package/dist/client/browser-entry/router-init.d.ts +23 -0
  64. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  65. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  66. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  67. package/dist/client/browser-entry/scroll.d.ts +19 -0
  68. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  69. package/dist/client/error-boundary.js +131 -1
  70. package/dist/client/error-boundary.js.map +1 -0
  71. package/dist/client/index.d.ts +4 -19
  72. package/dist/client/index.d.ts.map +1 -1
  73. package/dist/client/index.js +14 -1191
  74. package/dist/client/index.js.map +1 -1
  75. package/dist/client/internal.d.ts +18 -0
  76. package/dist/client/internal.d.ts.map +1 -0
  77. package/dist/client/internal.js +890 -0
  78. package/dist/client/internal.js.map +1 -0
  79. package/dist/client/navigation-context.d.ts.map +1 -1
  80. package/dist/client/router-ref.d.ts +1 -1
  81. package/dist/client/top-loader.d.ts +2 -2
  82. package/dist/client/use-link-status.d.ts +1 -1
  83. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  84. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  85. package/dist/client/use-router.d.ts +1 -1
  86. package/dist/codec.d.ts +10 -0
  87. package/dist/codec.d.ts.map +1 -1
  88. package/dist/codec.js +1 -1
  89. package/dist/config-types.d.ts +210 -0
  90. package/dist/config-types.d.ts.map +1 -0
  91. package/dist/content/index.d.ts +1 -10
  92. package/dist/content/index.d.ts.map +1 -1
  93. package/dist/content/index.js +0 -2
  94. package/dist/cookies/define-cookie.d.ts.map +1 -1
  95. package/dist/cookies/index.d.ts +0 -2
  96. package/dist/cookies/index.d.ts.map +1 -1
  97. package/dist/cookies/index.js +2 -3
  98. package/dist/index.d.ts +25 -288
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +261 -43
  101. package/dist/index.js.map +1 -1
  102. package/dist/plugin-context.d.ts +84 -0
  103. package/dist/plugin-context.d.ts.map +1 -0
  104. package/dist/plugins/adapter-build.d.ts +1 -1
  105. package/dist/plugins/adapter-build.d.ts.map +1 -1
  106. package/dist/plugins/build-manifest.d.ts +1 -1
  107. package/dist/plugins/build-manifest.d.ts.map +1 -1
  108. package/dist/plugins/build-report.d.ts +1 -1
  109. package/dist/plugins/build-report.d.ts.map +1 -1
  110. package/dist/plugins/content.d.ts +1 -1
  111. package/dist/plugins/content.d.ts.map +1 -1
  112. package/dist/plugins/dev-browser-logs.d.ts +1 -1
  113. package/dist/plugins/dev-browser-logs.d.ts.map +1 -1
  114. package/dist/plugins/dev-logs.d.ts +1 -1
  115. package/dist/plugins/dev-logs.d.ts.map +1 -1
  116. package/dist/plugins/dev-server.d.ts +1 -1
  117. package/dist/plugins/dev-server.d.ts.map +1 -1
  118. package/dist/plugins/entries.d.ts +1 -1
  119. package/dist/plugins/entries.d.ts.map +1 -1
  120. package/dist/plugins/fonts.d.ts +1 -1
  121. package/dist/plugins/fonts.d.ts.map +1 -1
  122. package/dist/plugins/mdx.d.ts +1 -1
  123. package/dist/plugins/mdx.d.ts.map +1 -1
  124. package/dist/plugins/routing.d.ts +1 -1
  125. package/dist/plugins/routing.d.ts.map +1 -1
  126. package/dist/plugins/shims.d.ts +1 -1
  127. package/dist/plugins/shims.d.ts.map +1 -1
  128. package/dist/plugins/static-build.d.ts +4 -4
  129. package/dist/plugins/static-build.d.ts.map +1 -1
  130. package/dist/routing/index.js +1 -1
  131. package/dist/search-params/define.d.ts +6 -6
  132. package/dist/search-params/define.d.ts.map +1 -1
  133. package/dist/search-params/index.d.ts +1 -2
  134. package/dist/search-params/index.d.ts.map +1 -1
  135. package/dist/search-params/index.js +4 -4
  136. package/dist/search-params/registry.d.ts +1 -1
  137. package/dist/search-params/registry.d.ts.map +1 -1
  138. package/dist/segment-params/define.d.ts +6 -6
  139. package/dist/segment-params/define.d.ts.map +1 -1
  140. package/dist/segment-params/index.d.ts +0 -1
  141. package/dist/segment-params/index.d.ts.map +1 -1
  142. package/dist/segment-params/index.js +3 -3
  143. package/dist/server/als-registry.d.ts +1 -1
  144. package/dist/server/dev-holding-server.d.ts +52 -0
  145. package/dist/server/dev-holding-server.d.ts.map +1 -0
  146. package/dist/server/dev-warnings.d.ts +1 -7
  147. package/dist/server/dev-warnings.d.ts.map +1 -1
  148. package/dist/server/index.d.ts +6 -45
  149. package/dist/server/index.d.ts.map +1 -1
  150. package/dist/server/index.js +7 -3272
  151. package/dist/server/index.js.map +1 -1
  152. package/dist/server/internal.d.ts +46 -0
  153. package/dist/server/internal.d.ts.map +1 -0
  154. package/dist/server/internal.js +2865 -0
  155. package/dist/server/internal.js.map +1 -0
  156. package/dist/server/pipeline.d.ts.map +1 -1
  157. package/dist/server/primitives.d.ts +41 -17
  158. package/dist/server/primitives.d.ts.map +1 -1
  159. package/dist/server/request-context.d.ts +45 -15
  160. package/dist/server/request-context.d.ts.map +1 -1
  161. package/dist/server/tracing.d.ts +4 -4
  162. package/dist/server/tracing.d.ts.map +1 -1
  163. package/dist/shims/headers.d.ts +2 -1
  164. package/dist/shims/headers.d.ts.map +1 -1
  165. package/dist/shims/navigation.d.ts +2 -1
  166. package/dist/shims/navigation.d.ts.map +1 -1
  167. package/package.json +19 -13
  168. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  169. package/src/cache/handler-store.ts +2 -2
  170. package/src/cache/index.ts +74 -15
  171. package/src/cache/sizeof.ts +31 -0
  172. package/src/cli.ts +6 -1
  173. package/src/client/browser-dev.ts +128 -1
  174. package/src/client/browser-entry/action-dispatch.ts +116 -0
  175. package/src/client/browser-entry/hmr.ts +81 -0
  176. package/src/client/browser-entry/hydrate.ts +145 -0
  177. package/src/client/browser-entry/index.ts +138 -0
  178. package/src/client/browser-entry/post-hydration.ts +119 -0
  179. package/src/client/browser-entry/router-init.ts +184 -0
  180. package/src/client/browser-entry/rsc-stream.ts +157 -0
  181. package/src/client/browser-entry/scroll.ts +27 -0
  182. package/src/client/index.ts +10 -38
  183. package/src/client/internal.ts +57 -0
  184. package/src/client/navigation-context.ts +6 -2
  185. package/src/client/navigation-root.tsx +1 -1
  186. package/src/client/router-ref.ts +1 -1
  187. package/src/client/top-loader.tsx +2 -2
  188. package/src/client/use-link-status.ts +1 -1
  189. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +5 -5
  190. package/src/client/use-query-states.ts +2 -2
  191. package/src/client/use-router.ts +1 -1
  192. package/src/codec.ts +15 -0
  193. package/src/config-types.ts +208 -0
  194. package/src/content/index.ts +5 -13
  195. package/src/cookies/define-cookie.ts +9 -7
  196. package/src/cookies/index.ts +6 -5
  197. package/src/index.ts +84 -416
  198. package/src/plugin-context.ts +200 -0
  199. package/src/plugins/adapter-build.ts +1 -1
  200. package/src/plugins/build-manifest.ts +1 -1
  201. package/src/plugins/build-report.ts +1 -1
  202. package/src/plugins/content.ts +1 -1
  203. package/src/plugins/dev-browser-logs.ts +1 -1
  204. package/src/plugins/dev-logs.ts +1 -1
  205. package/src/plugins/dev-server.ts +16 -1
  206. package/src/plugins/entries.ts +2 -2
  207. package/src/plugins/fonts.ts +4 -3
  208. package/src/plugins/mdx.ts +1 -1
  209. package/src/plugins/routing.ts +1 -1
  210. package/src/plugins/shims.ts +53 -5
  211. package/src/plugins/static-build.ts +8 -6
  212. package/src/search-params/define.ts +22 -22
  213. package/src/search-params/index.ts +3 -3
  214. package/src/search-params/registry.ts +1 -1
  215. package/src/segment-params/define.ts +18 -18
  216. package/src/segment-params/index.ts +2 -1
  217. package/src/server/action-handler.ts +1 -1
  218. package/src/server/als-registry.ts +3 -3
  219. package/src/server/dev-holding-server.ts +185 -0
  220. package/src/server/dev-warnings.ts +2 -21
  221. package/src/server/html-injectors.ts +3 -3
  222. package/src/server/index.ts +25 -180
  223. package/src/server/internal.ts +169 -0
  224. package/src/server/pipeline.ts +12 -7
  225. package/src/server/primitives.ts +71 -30
  226. package/src/server/request-context.ts +77 -39
  227. package/src/server/route-element-builder.ts +1 -1
  228. package/src/server/rsc-entry/index.ts +2 -2
  229. package/src/server/rsc-entry/ssr-renderer.ts +1 -1
  230. package/src/server/slot-resolver.ts +1 -1
  231. package/src/server/tracing.ts +6 -6
  232. package/src/server/tree-builder.ts +1 -1
  233. package/src/shims/headers.ts +5 -1
  234. package/src/shims/navigation.ts +5 -1
  235. package/dist/_chunks/als-registry-BJARkOcu.js.map +0 -1
  236. package/dist/_chunks/define-CGuYoRHU.js.map +0 -1
  237. package/dist/_chunks/define-Dz1bqwaS.js.map +0 -1
  238. package/dist/_chunks/error-boundary-D9hzsveV.js +0 -216
  239. package/dist/_chunks/error-boundary-D9hzsveV.js.map +0 -1
  240. package/dist/_chunks/format-Rn922VH2.js.map +0 -1
  241. package/dist/_chunks/handler-store-BVePM7hp.js.map +0 -1
  242. package/dist/_chunks/request-context-CywiO4jV.js.map +0 -1
  243. package/dist/_chunks/segment-context-hzuJ048X.js.map +0 -1
  244. package/dist/_chunks/use-query-states-DAhgj8Gx.js.map +0 -1
  245. package/dist/client/browser-entry.d.ts +0 -21
  246. package/dist/client/browser-entry.d.ts.map +0 -1
  247. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  248. package/src/client/browser-entry.ts +0 -846
package/dist/index.js CHANGED
@@ -1,16 +1,18 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./_chunks/chunk-DYhsFzuS.js";
2
- import { r as setViteServer, t as formatSize } from "./_chunks/format-Rn922VH2.js";
3
- import { i as scanRoutes, n as generateRouteMap, t as collectInterceptionRewrites } from "./_chunks/interception-CEdHHviP.js";
4
- import { existsSync, readFileSync } from "node:fs";
2
+ import { n as setViteServer } from "./_chunks/dev-warnings-DpGRGoDi.js";
3
+ import { i as scanRoutes, n as generateRouteMap, t as collectInterceptionRewrites } from "./_chunks/interception-Dpn_UfAD.js";
4
+ import { t as formatSize } from "./_chunks/format-CYBGxKtc.js";
5
5
  import { dirname, extname, join, normalize, resolve } from "node:path";
6
6
  import { createRequire } from "node:module";
7
7
  import react, { reactCompilerPreset } from "@vitejs/plugin-react";
8
+ import { existsSync, readFileSync } from "node:fs";
8
9
  import { constants, createGzip, gzipSync } from "node:zlib";
9
10
  import { Readable } from "node:stream";
10
11
  import { fileURLToPath } from "node:url";
11
12
  import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
12
13
  import { createHash, randomUUID } from "node:crypto";
13
14
  import { performance as performance$1 } from "node:perf_hooks";
15
+ import http from "node:http";
14
16
  //#region src/plugins/content.ts
15
17
  var CONFIG_FILE_NAMES$1 = [
16
18
  "content-collections.ts",
@@ -428,6 +430,15 @@ function timberDevServer(ctx) {
428
430
  setViteServer(server);
429
431
  listenForClientErrors(server, ctx.root);
430
432
  server.middlewares.use(createTimberMiddleware(server, ctx.root));
433
+ if (ctx.holdingServer) {
434
+ const originalListen = server.listen.bind(server);
435
+ const holdingRef = ctx.holdingServer;
436
+ ctx.holdingServer = null;
437
+ server.listen = async (port, isRestart) => {
438
+ await holdingRef.close().catch(() => {});
439
+ return originalListen(port, isRestart);
440
+ };
441
+ }
431
442
  ctx.timer.end("dev-server-setup");
432
443
  const summary = ctx.timer.formatSummary();
433
444
  if (summary) console.log(summary);
@@ -650,7 +661,7 @@ var VIRTUAL_IDS = {
650
661
  var ENTRY_FILE_MAP = {
651
662
  [VIRTUAL_IDS.rscEntry]: resolve(SRC_DIR, "server", "rsc-entry", "index.ts"),
652
663
  [VIRTUAL_IDS.ssrEntry]: resolve(SRC_DIR, "server", "ssr-entry.ts"),
653
- [VIRTUAL_IDS.browserEntry]: resolve(SRC_DIR, "client", "browser-entry.ts")
664
+ [VIRTUAL_IDS.browserEntry]: resolve(SRC_DIR, "client", "browser-entry", "index.ts")
654
665
  };
655
666
  /** The \0-prefixed resolved ID for virtual:timber-config */
656
667
  var RESOLVED_CONFIG_ID = `\0${VIRTUAL_IDS.config}`;
@@ -12197,11 +12208,8 @@ var CLIENT_ONLY_VIRTUAL = "\0timber:client-only";
12197
12208
  */
12198
12209
  var SUBPATH_SRC_MAP = {
12199
12210
  "cache": "cache/index.ts",
12200
- "content": "content/index.ts",
12201
12211
  "cookies": "cookies/index.ts",
12202
- "segment-params": "segment-params/index.ts",
12203
12212
  "search-params": "search-params/index.ts",
12204
- "routing": "routing/index.ts",
12205
12213
  "adapters/cloudflare": "adapters/cloudflare.ts",
12206
12214
  "adapters/cloudflare/dev": "adapters/cloudflare-dev.ts",
12207
12215
  "adapters/nitro": "adapters/nitro.ts"
@@ -12248,6 +12256,17 @@ function timberShims(_ctx) {
12248
12256
  if (this.environment?.name === "client" && cleanId === "next/navigation") return resolve(SHIMS_DIR, "navigation-client.ts");
12249
12257
  return SHIM_MAP[cleanId];
12250
12258
  }
12259
+ if (cleanId === "#server-internal") {
12260
+ if (this.environment?.name === "client") return "\0timber:server-empty";
12261
+ return resolve(PKG_ROOT, "src", "server", "internal.ts");
12262
+ }
12263
+ if (cleanId === "#client-internal") return resolve(PKG_ROOT, "src", "client", "internal.ts");
12264
+ if (cleanId === "#routing") return resolve(PKG_ROOT, "src", "routing", "index.ts");
12265
+ if (cleanId === "@timber-js/app/server/internal") {
12266
+ if (this.environment?.name === "client") return "\0timber:server-empty";
12267
+ return resolve(PKG_ROOT, "src", "server", "internal.ts");
12268
+ }
12269
+ if (cleanId === "@timber-js/app/client/internal") return resolve(PKG_ROOT, "src", "client", "internal.ts");
12251
12270
  if (cleanId === "@timber-js/app/server") {
12252
12271
  if (this.environment?.name === "client") return "\0timber:server-empty";
12253
12272
  return resolve(PKG_ROOT, "src", "server", "index.ts");
@@ -12287,6 +12306,12 @@ const msg = "[timber] @timber-js/app/server was imported from client code. " +
12287
12306
  function stub() { throw new Error(msg); }
12288
12307
  export const headers = stub;
12289
12308
  export const cookies = stub;
12309
+ export const getHeaders = stub;
12310
+ export const getHeader = stub;
12311
+ export const getCookies = stub;
12312
+ export const getCookie = stub;
12313
+ export const getSearchParams = stub;
12314
+ export const getSegmentParams = stub;
12290
12315
  export const searchParams = stub;
12291
12316
  export const deny = stub;
12292
12317
  export const notFound = stub;
@@ -12294,7 +12319,7 @@ export const redirect = stub;
12294
12319
  export const permanentRedirect = stub;
12295
12320
  export const redirectExternal = stub;
12296
12321
  export const waitUntil = stub;
12297
- export const RenderError = stub;
12322
+ export const DenyOptions = {};
12298
12323
  export const RedirectType = {};
12299
12324
  export const DenySignal = stub;
12300
12325
  export const RedirectSignal = stub;
@@ -13449,8 +13474,7 @@ function timberFonts(ctx) {
13449
13474
  googleFontFacesMap.set(font.id, faces);
13450
13475
  } catch (e) {
13451
13476
  const msg = e instanceof Error ? e.message : String(e);
13452
- console.warn(`[timber-fonts] Failed to resolve Google font "${font.family}": ${msg}`);
13453
- googleFontFacesMap.set(font.id, []);
13477
+ console.warn(`[timber-fonts] Failed to resolve Google font "${font.family}": ${msg}. Will retry on next request.`);
13454
13478
  }
13455
13479
  }
13456
13480
  const css = generateAllFontCss(registry, googleFontFacesMap);
@@ -13639,15 +13663,26 @@ function timberFonts(ctx) {
13639
13663
  *
13640
13664
  * We detect both import-level and call-level usage.
13641
13665
  */
13642
- var DYNAMIC_API_PATTERNS = [{
13643
- pattern: /\bcookies\s*\(/,
13644
- name: "cookies()"
13645
- }, {
13646
- pattern: /\bheaders\s*\(/,
13647
- name: "headers()"
13648
- }];
13666
+ var DYNAMIC_API_PATTERNS = [
13667
+ {
13668
+ pattern: /\bgetCookies\s*\(/,
13669
+ name: "getCookies()"
13670
+ },
13671
+ {
13672
+ pattern: /\bgetHeaders\s*\(/,
13673
+ name: "getHeaders()"
13674
+ },
13675
+ {
13676
+ pattern: /\bcookies\s*\(/,
13677
+ name: "cookies()"
13678
+ },
13679
+ {
13680
+ pattern: /\bheaders\s*\(/,
13681
+ name: "headers()"
13682
+ }
13683
+ ];
13649
13684
  /**
13650
- * Detect usage of dynamic per-request APIs (cookies(), headers())
13685
+ * Detect usage of dynamic per-request APIs (getCookies(), getHeaders())
13651
13686
  * that cannot work at build time in static mode.
13652
13687
  *
13653
13688
  * Returns an array of validation errors.
@@ -13701,7 +13736,7 @@ function detectDirectives(code, fileId, options) {
13701
13736
  * Run all static mode validations on a source file.
13702
13737
  *
13703
13738
  * Combines:
13704
- * - Dynamic API detection (cookies, headers) — always in static mode
13739
+ * - Dynamic API detection (getCookies, getHeaders) — always in static mode
13705
13740
  * - Directive detection ('use client', 'use server') — only when client JS is disabled
13706
13741
  */
13707
13742
  function validateStaticMode(code, fileId, options) {
@@ -14960,7 +14995,173 @@ function validateKeyFormat(key) {
14960
14995
  }
14961
14996
  }
14962
14997
  //#endregion
14963
- //#region src/index.ts
14998
+ //#region src/server/dev-holding-server.ts
14999
+ /**
15000
+ * Dev holding server — serves a loading page while Vite initializes.
15001
+ *
15002
+ * When `timber dev` (or `vite dev`) starts, Vite takes several seconds
15003
+ * to initialize all plugins, scan routes, and boot the RSC environment.
15004
+ * During this window, the port is unbound and browsers get
15005
+ * ERR_CONNECTION_REFUSED.
15006
+ *
15007
+ * This module creates a lightweight HTTP server that binds the port
15008
+ * immediately and serves a branded holding page with auto-refresh.
15009
+ * Once Vite is ready, the holding server is closed and Vite's server
15010
+ * takes over the port.
15011
+ *
15012
+ * The holding server is started in rootSync's config() hook (the
15013
+ * earliest Vite plugin lifecycle point where we know the port) and
15014
+ * closed in timber-dev-server's configureServer() hook (the last
15015
+ * plugin, right before Vite calls server.listen()).
15016
+ *
15017
+ * Browser requests (Accept: text/html) get the HTML holding page.
15018
+ * API requests (Accept: application/json) get a 503 JSON response.
15019
+ * All responses include Retry-After: 1.
15020
+ *
15021
+ * See design/21-dev-server.md, TIM-665.
15022
+ */
15023
+ /**
15024
+ * Minimal self-contained HTML holding page.
15025
+ *
15026
+ * Matches the timber.js docs site theme:
15027
+ * - Light mode: warm stone/grain background, timber/bark text
15028
+ * - Dark mode: stone-900 background, stone-200 text
15029
+ * - 🪵 timber.js branding
15030
+ *
15031
+ * Uses meta-refresh (1s) for auto-reload — works without JavaScript.
15032
+ * Inline CSS only, no external dependencies.
15033
+ */
15034
+ var HOLDING_PAGE_HTML = [
15035
+ "<!DOCTYPE html>",
15036
+ "<html lang=\"en\">",
15037
+ "<head>",
15038
+ " <meta charset=\"utf-8\">",
15039
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
15040
+ " <meta http-equiv=\"refresh\" content=\"2\">",
15041
+ " <title>timber — starting...</title>",
15042
+ " <style>",
15043
+ " *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }",
15044
+ " body {",
15045
+ " font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;",
15046
+ " background: #fafaf9;",
15047
+ " color: #44403c;",
15048
+ " display: flex;",
15049
+ " align-items: center;",
15050
+ " justify-content: center;",
15051
+ " min-height: 100vh;",
15052
+ " -webkit-font-smoothing: antialiased;",
15053
+ " }",
15054
+ " @media (prefers-color-scheme: dark) {",
15055
+ " body { background: #1c1917; color: #e7e5e4; }",
15056
+ " .message { color: #a8a29e; }",
15057
+ " .spinner { border-color: #57534e; border-top-color: #a1887f; }",
15058
+ " .logo { color: #e7e5e4; }",
15059
+ " }",
15060
+ " .container { text-align: center; padding: 2rem; }",
15061
+ " .logo {",
15062
+ " font-size: 1.5rem;",
15063
+ " font-weight: 700;",
15064
+ " letter-spacing: -0.02em;",
15065
+ " color: #5c3d2e;",
15066
+ " margin-bottom: 1.5rem;",
15067
+ " }",
15068
+ " .message {",
15069
+ " font-size: 0.95rem;",
15070
+ " color: #78716c;",
15071
+ " margin-bottom: 2rem;",
15072
+ " }",
15073
+ " .spinner {",
15074
+ " width: 24px;",
15075
+ " height: 24px;",
15076
+ " border: 2.5px solid #d7ccc8;",
15077
+ " border-top-color: #6d4c41;",
15078
+ " border-radius: 50%;",
15079
+ " animation: spin 0.8s linear infinite;",
15080
+ " margin: 0 auto;",
15081
+ " }",
15082
+ " @keyframes spin { to { transform: rotate(360deg); } }",
15083
+ " </style>",
15084
+ "</head>",
15085
+ "<body>",
15086
+ " <div class=\"container\">",
15087
+ " <div class=\"logo\">🪵 timber.js</div>",
15088
+ " <p class=\"message\">Dev server starting&hellip;</p>",
15089
+ " <div class=\"spinner\"></div>",
15090
+ " </div>",
15091
+ "</body>",
15092
+ "</html>"
15093
+ ].join("\n");
15094
+ /**
15095
+ * Create a holding HTTP server that serves a loading page during startup.
15096
+ *
15097
+ * Usage (inside Vite plugin):
15098
+ * ```ts
15099
+ * // In config() hook — earliest point where port is known
15100
+ * const holding = createHoldingServer();
15101
+ * holding.listen(config.server?.port ?? 5173);
15102
+ *
15103
+ * // In last plugin's configureServer() — wrap listen for seamless handoff
15104
+ * const originalListen = server.listen.bind(server);
15105
+ * server.listen = async (...args) => {
15106
+ * await holding.close();
15107
+ * return originalListen(...args);
15108
+ * };
15109
+ * ```
15110
+ */
15111
+ function createHoldingServer() {
15112
+ const server = http.createServer((req, res) => {
15113
+ const accept = req.headers.accept ?? "";
15114
+ if (accept.includes("application/json") && !accept.includes("text/html")) {
15115
+ res.writeHead(503, {
15116
+ "Content-Type": "application/json; charset=utf-8",
15117
+ "Retry-After": "1",
15118
+ "Cache-Control": "no-store"
15119
+ });
15120
+ res.end(JSON.stringify({
15121
+ error: "Service Unavailable",
15122
+ message: "timber dev server is starting — please retry shortly"
15123
+ }));
15124
+ return;
15125
+ }
15126
+ res.writeHead(503, {
15127
+ "Content-Type": "text/html; charset=utf-8",
15128
+ "Retry-After": "1",
15129
+ "Cache-Control": "no-store"
15130
+ });
15131
+ res.end(HOLDING_PAGE_HTML);
15132
+ });
15133
+ return {
15134
+ listen(port) {
15135
+ return new Promise((resolve, reject) => {
15136
+ server.once("error", reject);
15137
+ server.listen(port, () => {
15138
+ server.removeListener("error", reject);
15139
+ const addr = server.address();
15140
+ resolve(typeof addr === "object" && addr ? addr.port : port);
15141
+ });
15142
+ });
15143
+ },
15144
+ close() {
15145
+ return new Promise((resolve, reject) => {
15146
+ server.close((err) => {
15147
+ if (err) reject(err);
15148
+ else resolve();
15149
+ });
15150
+ });
15151
+ }
15152
+ };
15153
+ }
15154
+ //#endregion
15155
+ //#region src/plugin-context.ts
15156
+ /**
15157
+ * Plugin context — internal types and helpers for timber sub-plugins.
15158
+ *
15159
+ * These are NOT part of the user-facing API. They are consumed by
15160
+ * sub-plugins (routing, entries, shims, etc.) via relative imports.
15161
+ * The root entry point (index.ts) does not re-export them.
15162
+ *
15163
+ * Design doc: 18-build-system.md §"Shared Plugin Context"
15164
+ */
14964
15165
  /**
14965
15166
  * Resolve `clientJavascript` into a fully resolved config.
14966
15167
  */
@@ -15012,7 +15213,8 @@ function createPluginContext(config, root) {
15012
15213
  dev: false,
15013
15214
  buildManifest: null,
15014
15215
  deploymentId: null,
15015
- timer: createStartupTimer()
15216
+ timer: createStartupTimer(),
15217
+ holdingServer: null
15016
15218
  };
15017
15219
  }
15018
15220
  /**
@@ -15075,6 +15277,29 @@ function mergeFileConfig(ctx, fileConfig) {
15075
15277
  } } : {}
15076
15278
  };
15077
15279
  }
15280
+ //#endregion
15281
+ //#region src/index.ts
15282
+ /**
15283
+ * Type-safe helper for timber.config.ts files.
15284
+ *
15285
+ * A pass-through identity function that provides autocomplete and
15286
+ * type checking for timber configuration. No runtime validation —
15287
+ * purely a DX convenience (same pattern as Vite's defineConfig).
15288
+ *
15289
+ * @example
15290
+ * ```ts
15291
+ * // timber.config.ts
15292
+ * import { defineConfig } from '@timber-js/app';
15293
+ *
15294
+ * export default defineConfig({
15295
+ * output: 'server',
15296
+ * pageExtensions: ['tsx', 'ts', 'mdx'],
15297
+ * });
15298
+ * ```
15299
+ */
15300
+ function defineConfig(config) {
15301
+ return config;
15302
+ }
15078
15303
  /**
15079
15304
  * Resolve the React Compiler plugin via @rolldown/plugin-babel.
15080
15305
  *
@@ -15165,6 +15390,20 @@ function timber(config) {
15165
15390
  const hadCompilerInEarly = !config?.reactCompiler && earlyFileConfig?.reactCompiler;
15166
15391
  if (hasCompilerInReloaded && !hadCompilerInEarly) console.warn("[timber] reactCompiler is set in timber.config.ts but could not be registered because the config file is in a non-cwd root directory. Move reactCompiler to the inline timber() config in vite.config.ts, or run vite from the project root directory.");
15167
15392
  }
15393
+ if (command === "serve") {
15394
+ const port = userConfig.server?.port ?? 5173;
15395
+ try {
15396
+ ctx.holdingServer = createHoldingServer();
15397
+ ctx.holdingServer.listen(port).then((boundPort) => {
15398
+ const url = `http://localhost:${boundPort}`;
15399
+ console.log(`\n \x1b[2m🪵 timber.js dev server starting at\x1b[0m \x1b[36m${url}\x1b[0m\n`);
15400
+ }, () => {
15401
+ ctx.holdingServer = null;
15402
+ });
15403
+ } catch {
15404
+ ctx.holdingServer = null;
15405
+ }
15406
+ }
15168
15407
  if (command === "build") return { oxc: { jsx: { development: false } } };
15169
15408
  },
15170
15409
  configResolved(resolved) {
@@ -15203,28 +15442,7 @@ function timber(config) {
15203
15442
  timberDevServer(ctx)
15204
15443
  ];
15205
15444
  }
15206
- /**
15207
- * Type-safe helper for timber.config.ts files.
15208
- *
15209
- * A pass-through identity function that provides autocomplete and
15210
- * type checking for timber configuration. No runtime validation —
15211
- * purely a DX convenience (same pattern as Vite's defineConfig).
15212
- *
15213
- * @example
15214
- * ```ts
15215
- * // timber.config.ts
15216
- * import { defineConfig } from '@timber-js/app';
15217
- *
15218
- * export default defineConfig({
15219
- * output: 'server',
15220
- * pageExtensions: ['tsx', 'ts', 'mdx'],
15221
- * });
15222
- * ```
15223
- */
15224
- function defineConfig(config) {
15225
- return config;
15226
- }
15227
15445
  //#endregion
15228
- export { timber as default, timber, defineConfig, loadTimberConfigFile, resolveAppDir, resolveClientJavascript, warnConfigConflicts };
15446
+ export { timber as default, timber, defineConfig };
15229
15447
 
15230
15448
  //# sourceMappingURL=index.js.map