reroute-js 0.25.2 → 0.26.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 (197) hide show
  1. package/README.md +150 -52
  2. package/cli/bin.d.ts +1 -1
  3. package/cli/bin.js +446 -150
  4. package/cli/bin.js.map +13 -9
  5. package/cli/index.d.ts +1 -1
  6. package/cli/index.js +4 -4
  7. package/cli/index.js.map +1 -1
  8. package/cli/src/cli.d.ts +1 -1
  9. package/cli/src/commands/analyze.d.ts +1 -1
  10. package/cli/src/commands/build.d.ts +1 -1
  11. package/cli/src/commands/dev.d.ts +1 -1
  12. package/cli/src/commands/gen.d.ts +1 -1
  13. package/cli/src/commands/gen.d.ts.map +1 -1
  14. package/cli/src/commands/index.d.ts +1 -1
  15. package/cli/src/commands/init.d.ts +1 -1
  16. package/cli/src/commands/lib/assets.d.ts +1 -1
  17. package/cli/src/commands/lib/bundler.d.ts +1 -1
  18. package/cli/src/commands/lib/command.d.ts +1 -1
  19. package/cli/src/commands/lib/env.d.ts +1 -1
  20. package/cli/src/commands/lib/index.d.ts +1 -1
  21. package/cli/src/commands/lib/log.d.ts +1 -1
  22. package/cli/src/commands/lib/markdown/availability.d.ts +1 -1
  23. package/cli/src/commands/lib/markdown/index.d.ts +1 -1
  24. package/cli/src/commands/lib/markdown/processor.d.ts +1 -1
  25. package/cli/src/commands/lib/production.d.ts +1 -1
  26. package/cli/src/commands/lib/server.d.ts +1 -1
  27. package/cli/src/commands/lib/streaming/analyzer.d.ts +1 -1
  28. package/cli/src/commands/lib/streaming/suspense.d.ts +1 -1
  29. package/cli/src/commands/lib/tailwind.d.ts +1 -1
  30. package/cli/src/commands/lib/terminal-ui.d.ts +1 -1
  31. package/cli/src/commands/lib/version.d.ts +1 -1
  32. package/cli/src/commands/og.d.ts +1 -1
  33. package/cli/src/commands/start.d.ts +1 -1
  34. package/cli/src/index.d.ts +1 -1
  35. package/core/index.d.ts +1 -1
  36. package/core/index.js +912 -589
  37. package/core/index.js.map +22 -14
  38. package/core/src/bundler/hash.d.ts +1 -1
  39. package/core/src/bundler/index.d.ts +1 -1
  40. package/core/src/config.d.ts +243 -2
  41. package/core/src/config.d.ts.map +1 -1
  42. package/core/src/content/discovery.d.ts +1 -1
  43. package/core/src/content/index.d.ts +1 -1
  44. package/core/src/content/metadata.d.ts +1 -1
  45. package/core/src/index.d.ts +1 -1
  46. package/core/src/llms/extractor.d.ts +1 -1
  47. package/core/src/llms/formatter.d.ts +1 -1
  48. package/core/src/llms/full-generator.d.ts +1 -1
  49. package/core/src/llms/index-generator.d.ts +1 -1
  50. package/core/src/llms/index.d.ts +1 -1
  51. package/core/src/og/discovery.d.ts +1 -1
  52. package/core/src/og/index.d.ts +1 -1
  53. package/core/src/og/meta.d.ts +1 -1
  54. package/core/src/og/render.d.ts +1 -1
  55. package/core/src/og/types.d.ts +1 -1
  56. package/core/src/robots/discovery.d.ts +1 -1
  57. package/core/src/robots/generator.d.ts +1 -1
  58. package/core/src/robots/index.d.ts +1 -1
  59. package/core/src/robots/policies.d.ts +1 -1
  60. package/core/src/rss/discovery.d.ts +1 -1
  61. package/core/src/rss/generator.d.ts +1 -1
  62. package/core/src/rss/index.d.ts +1 -1
  63. package/core/src/sitemap/discovery.d.ts +1 -1
  64. package/core/src/sitemap/generator.d.ts +1 -1
  65. package/core/src/sitemap/index.d.ts +1 -1
  66. package/core/src/ssr/index.d.ts +1 -1
  67. package/core/src/ssr/lib/cache.d.ts +1 -1
  68. package/core/src/ssr/lib/collections.d.ts +1 -1
  69. package/core/src/ssr/lib/compression.d.ts +1 -1
  70. package/core/src/ssr/lib/compute/content.d.ts +1 -1
  71. package/core/src/ssr/lib/compute/index.d.ts +1 -1
  72. package/core/src/ssr/lib/compute/layouts.d.ts +1 -1
  73. package/core/src/ssr/lib/compute/routes.d.ts +1 -1
  74. package/core/src/ssr/lib/data.d.ts +1 -1
  75. package/core/src/ssr/lib/html.d.ts +1 -1
  76. package/core/src/ssr/lib/imports.d.ts +1 -1
  77. package/core/src/ssr/lib/index.d.ts +1 -1
  78. package/core/src/ssr/lib/layouts.d.ts +1 -1
  79. package/core/src/ssr/lib/metadata.d.ts +1 -1
  80. package/core/src/ssr/lib/mime.d.ts +1 -1
  81. package/core/src/ssr/lib/modules.d.ts +1 -1
  82. package/core/src/ssr/lib/path.d.ts +1 -1
  83. package/core/src/ssr/lib/preload.d.ts +1 -1
  84. package/core/src/ssr/lib/scripts/collections.d.ts +1 -1
  85. package/core/src/ssr/lib/scripts/data.d.ts +2 -2
  86. package/core/src/ssr/lib/scripts/data.d.ts.map +1 -1
  87. package/core/src/ssr/lib/scripts/escape.d.ts +1 -1
  88. package/core/src/ssr/lib/scripts/feeds.d.ts +1 -1
  89. package/core/src/ssr/lib/scripts/index.d.ts +1 -1
  90. package/core/src/ssr/lib/seed.d.ts +1 -1
  91. package/core/src/ssr/lib/setup.d.ts +4 -2
  92. package/core/src/ssr/lib/setup.d.ts.map +1 -1
  93. package/core/src/ssr/lib/styles.d.ts +1 -1
  94. package/core/src/ssr/lib/template.d.ts +1 -1
  95. package/core/src/ssr/lib/types.d.ts +1 -1
  96. package/core/src/ssr/render.d.ts +4 -2
  97. package/core/src/ssr/render.d.ts.map +1 -1
  98. package/core/src/ssr/stream.d.ts +4 -2
  99. package/core/src/ssr/stream.d.ts.map +1 -1
  100. package/elysia/index.d.ts +1 -1
  101. package/elysia/index.js +715 -468
  102. package/elysia/index.js.map +15 -11
  103. package/elysia/src/index.d.ts +1 -1
  104. package/elysia/src/libs/assets.d.ts +1 -1
  105. package/elysia/src/libs/cache.d.ts +1 -1
  106. package/elysia/src/libs/caching.d.ts +1 -1
  107. package/elysia/src/libs/http.d.ts +1 -1
  108. package/elysia/src/libs/image.d.ts +1 -1
  109. package/elysia/src/libs/index.d.ts +1 -1
  110. package/elysia/src/libs/llms.d.ts +1 -1
  111. package/elysia/src/libs/response.d.ts +1 -1
  112. package/elysia/src/libs/serving.d.ts +1 -1
  113. package/elysia/src/plugin.d.ts +1 -1
  114. package/elysia/src/routes/artifacts.d.ts +1 -1
  115. package/elysia/src/routes/content.d.ts +1 -1
  116. package/elysia/src/routes/content.d.ts.map +1 -1
  117. package/elysia/src/routes/image.d.ts +1 -1
  118. package/elysia/src/routes/index.d.ts +1 -1
  119. package/elysia/src/routes/internal.d.ts +1 -1
  120. package/elysia/src/routes/llms.d.ts +1 -1
  121. package/elysia/src/routes/og.d.ts +1 -1
  122. package/elysia/src/routes/redirects.d.ts +1 -1
  123. package/elysia/src/routes/robots.d.ts +1 -1
  124. package/elysia/src/routes/rss.d.ts +1 -1
  125. package/elysia/src/routes/search.d.ts +1 -1
  126. package/elysia/src/routes/sitemap.d.ts +1 -1
  127. package/elysia/src/routes/ssr.d.ts +1 -1
  128. package/elysia/src/routes/ssr.d.ts.map +1 -1
  129. package/elysia/src/routes/static.d.ts +1 -1
  130. package/elysia/src/routes/static.d.ts.map +1 -1
  131. package/elysia/src/types.d.ts +1 -1
  132. package/package.json +2 -9
  133. package/react/index.d.ts +1 -1
  134. package/react/index.js +2 -2
  135. package/react/index.js.map +1 -1
  136. package/react/src/components/ClientOnly.d.ts +1 -1
  137. package/react/src/components/ContentRoute.d.ts +1 -1
  138. package/react/src/components/Image.d.ts +1 -1
  139. package/react/src/components/LazyRoute.d.ts +1 -1
  140. package/react/src/components/Link.d.ts +1 -1
  141. package/react/src/components/Markdown.d.ts +1 -1
  142. package/react/src/components/Outlet.d.ts +1 -1
  143. package/react/src/components/index.d.ts +1 -1
  144. package/react/src/hooks/index.d.ts +1 -1
  145. package/react/src/hooks/useContent.d.ts +1 -1
  146. package/react/src/hooks/useData.d.ts +1 -1
  147. package/react/src/hooks/useFeed.d.ts +1 -1
  148. package/react/src/hooks/useLayoutData.d.ts +1 -1
  149. package/react/src/hooks/useLlms.d.ts +1 -1
  150. package/react/src/hooks/useNavigate.d.ts +1 -1
  151. package/react/src/hooks/useParams.d.ts +1 -1
  152. package/react/src/hooks/useRouter.d.ts +1 -1
  153. package/react/src/hooks/useSearch.d.ts +1 -1
  154. package/react/src/hooks/useSearchParams.d.ts +1 -1
  155. package/react/src/hooks/useToc.d.ts +1 -1
  156. package/react/src/index.d.ts +1 -1
  157. package/react/src/lib/collection.d.ts +1 -1
  158. package/react/src/lib/content.d.ts +1 -1
  159. package/react/src/lib/head.d.ts +1 -1
  160. package/react/src/lib/index.d.ts +1 -1
  161. package/react/src/lib/lazy-route.d.ts +1 -1
  162. package/react/src/lib/route-loader.d.ts +1 -1
  163. package/react/src/providers/ContentProvider.d.ts +1 -1
  164. package/react/src/providers/RerouteProvider.d.ts +1 -1
  165. package/react/src/providers/RouterProvider.d.ts +1 -1
  166. package/react/src/providers/index.d.ts +1 -1
  167. package/react/src/types/any.d.ts +1 -1
  168. package/react/src/types/index.d.ts +1 -1
  169. package/react/src/types/router.d.ts +1 -1
  170. package/telemetry/react.d.ts +2 -2
  171. package/telemetry/react.d.ts.map +1 -1
  172. package/telemetry/react.js +167 -185
  173. package/telemetry/react.js.map +7 -6
  174. package/telemetry/{index.d.ts → server.d.ts} +2 -2
  175. package/telemetry/server.d.ts.map +1 -0
  176. package/telemetry/server.js +1134 -0
  177. package/telemetry/server.js.map +44 -0
  178. package/telemetry/src/{browser/react.d.ts → react/api.d.ts} +4 -12
  179. package/telemetry/src/react/api.d.ts.map +1 -0
  180. package/telemetry/{browser.d.ts → src/react/index.d.ts} +4 -3
  181. package/telemetry/src/react/index.d.ts.map +1 -0
  182. package/telemetry/src/{browser/index.d.ts → react/telemetry.d.ts} +13 -13
  183. package/telemetry/src/react/telemetry.d.ts.map +1 -0
  184. package/telemetry/src/server/index.d.ts +3 -101
  185. package/telemetry/src/server/index.d.ts.map +1 -1
  186. package/telemetry/src/server/instrumentation.d.ts +62 -0
  187. package/telemetry/src/server/instrumentation.d.ts.map +1 -0
  188. package/telemetry/src/server/plugin.d.ts +72 -0
  189. package/telemetry/src/server/plugin.d.ts.map +1 -0
  190. package/telemetry/browser.d.ts.map +0 -1
  191. package/telemetry/browser.js +0 -382
  192. package/telemetry/browser.js.map +0 -10
  193. package/telemetry/index.d.ts.map +0 -1
  194. package/telemetry/index.js +0 -509
  195. package/telemetry/index.js.map +0 -10
  196. package/telemetry/src/browser/index.d.ts.map +0 -1
  197. package/telemetry/src/browser/react.d.ts.map +0 -1
package/elysia/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * reroute-js v0.25.2
2
+ * reroute-js v0.26.0
3
3
  *
4
4
  * @license MIT
5
5
  * @copyright 2025 stewones <hi@stewan.io>
@@ -193,6 +193,153 @@ var init_content = __esm(() => {
193
193
  init_metadata();
194
194
  });
195
195
 
196
+ // packages/telemetry/src/server/instrumentation.ts
197
+ import { context, SpanStatusCode, trace } from "@opentelemetry/api";
198
+ function isOtelAvailable() {
199
+ if (otelAvailable !== undefined)
200
+ return otelAvailable;
201
+ try {
202
+ __require("@opentelemetry/api");
203
+ otelAvailable = true;
204
+ return true;
205
+ } catch {
206
+ otelAvailable = false;
207
+ return false;
208
+ }
209
+ }
210
+
211
+ class NoopSpan {
212
+ spanContext() {
213
+ return {
214
+ traceId: "",
215
+ spanId: "",
216
+ traceFlags: 0
217
+ };
218
+ }
219
+ setAttribute() {
220
+ return this;
221
+ }
222
+ setAttributes() {
223
+ return this;
224
+ }
225
+ addEvent() {
226
+ return this;
227
+ }
228
+ addLink() {
229
+ return this;
230
+ }
231
+ addLinks() {
232
+ return this;
233
+ }
234
+ setStatus() {
235
+ return this;
236
+ }
237
+ updateName() {
238
+ return this;
239
+ }
240
+ end() {}
241
+ isRecording() {
242
+ return false;
243
+ }
244
+ recordException() {}
245
+ }
246
+ async function withSpan(name, fn, attributes) {
247
+ if (!isOtelAvailable()) {
248
+ return fn(noopSpan);
249
+ }
250
+ const tracer = trace.getTracer("reroute");
251
+ return tracer.startActiveSpan(name, { attributes }, async (span) => {
252
+ try {
253
+ const result = await fn(span);
254
+ span.end();
255
+ return result;
256
+ } catch (error) {
257
+ span.recordException(error);
258
+ span.setStatus({
259
+ code: SpanStatusCode.ERROR,
260
+ message: error instanceof Error ? error.message : String(error)
261
+ });
262
+ span.end();
263
+ throw error;
264
+ }
265
+ });
266
+ }
267
+ function withSpanSync(name, fn, attributes) {
268
+ if (!isOtelAvailable()) {
269
+ return fn(noopSpan);
270
+ }
271
+ const tracer = trace.getTracer("reroute");
272
+ return tracer.startActiveSpan(name, { attributes }, (span) => {
273
+ try {
274
+ const result = fn(span);
275
+ span.end();
276
+ return result;
277
+ } catch (error) {
278
+ span.recordException(error);
279
+ span.setStatus({
280
+ code: SpanStatusCode.ERROR,
281
+ message: error instanceof Error ? error.message : String(error)
282
+ });
283
+ span.end();
284
+ throw error;
285
+ }
286
+ });
287
+ }
288
+ async function withParentSpan(parentSpan, fn) {
289
+ if (!(isOtelAvailable() && parentSpan)) {
290
+ return fn();
291
+ }
292
+ const ctx = trace.setSpan(context.active(), parentSpan);
293
+ return context.with(ctx, fn);
294
+ }
295
+ var otelAvailable, noopSpan;
296
+ var init_instrumentation = __esm(() => {
297
+ noopSpan = new NoopSpan;
298
+ });
299
+
300
+ // packages/telemetry/src/server/plugin.ts
301
+ import {
302
+ metrics,
303
+ SpanStatusCode as SpanStatusCode2,
304
+ trace as trace2
305
+ } from "@opentelemetry/api";
306
+ import { logs, SeverityNumber } from "@opentelemetry/api-logs";
307
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
308
+ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
309
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
310
+ import { resourceFromAttributes } from "@opentelemetry/resources";
311
+ import {
312
+ BatchLogRecordProcessor,
313
+ LoggerProvider
314
+ } from "@opentelemetry/sdk-logs";
315
+ import {
316
+ MeterProvider,
317
+ PeriodicExportingMetricReader
318
+ } from "@opentelemetry/sdk-metrics";
319
+ import {
320
+ BatchSpanProcessor,
321
+ NodeTracerProvider
322
+ } from "@opentelemetry/sdk-trace-node";
323
+ import {
324
+ ATTR_SERVICE_NAME,
325
+ ATTR_SERVICE_VERSION
326
+ } from "@opentelemetry/semantic-conventions";
327
+ import { ATTR_HOST_NAME } from "@opentelemetry/semantic-conventions/incubating";
328
+ var init_plugin = __esm(() => {
329
+ init_core();
330
+ });
331
+
332
+ // packages/telemetry/src/server/index.ts
333
+ var init_server = __esm(() => {
334
+ init_instrumentation();
335
+ init_plugin();
336
+ });
337
+
338
+ // packages/telemetry/server.ts
339
+ var init_server2 = __esm(() => {
340
+ init_server();
341
+ });
342
+
196
343
  // packages/core/src/ssr/lib/cache.ts
197
344
  class SSRDataCache {
198
345
  cache = new Map;
@@ -2009,12 +2156,25 @@ function createSSRExportsScript(pathname) {
2009
2156
  return "";
2010
2157
  }
2011
2158
  }
2012
- function createDataScript(ssrData, errorMsg, pathname) {
2159
+ function createTelemetryConfigScript(browserTelemetryConfig) {
2160
+ if (!browserTelemetryConfig || Object.keys(browserTelemetryConfig).length === 0) {
2161
+ return "";
2162
+ }
2163
+ try {
2164
+ const configJson = escapeJsonForScript(JSON.stringify(browserTelemetryConfig));
2165
+ return `<script>(function(){try{var w=(typeof window!=='undefined'?window:globalThis);w.__REROUTE_TELEMETRY_BROWSER__=${configJson};}catch(e){}})();</script>`;
2166
+ } catch (error) {
2167
+ console.error("[reroute] Failed to serialize browser telemetry config:", error);
2168
+ return "";
2169
+ }
2170
+ }
2171
+ function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig) {
2013
2172
  let script = "";
2014
2173
  script += createContentCaptureScript();
2015
2174
  if (pathname) {
2016
2175
  script += createSSRExportsScript(pathname);
2017
2176
  }
2177
+ script += createTelemetryConfigScript(browserTelemetryConfig);
2018
2178
  if (ssrData && Object.keys(ssrData).length > 0) {
2019
2179
  try {
2020
2180
  const duplicatedData = duplicateQueryParamData(ssrData);
@@ -2115,7 +2275,7 @@ async function performSSRSetup(options, streaming = false) {
2115
2275
  });
2116
2276
  try {
2117
2277
  return await Promise.race([
2118
- performSSRSetupInternal(options, streaming),
2278
+ withParentSpan(options.parentSpan, () => performSSRSetupInternal(options, streaming)),
2119
2279
  timeoutPromise
2120
2280
  ]);
2121
2281
  } catch (error) {
@@ -2146,34 +2306,70 @@ async function performSSRSetupInternal(options, streaming) {
2146
2306
  searchParams,
2147
2307
  ogConfig
2148
2308
  } = options;
2149
- await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode);
2150
- if (debug)
2151
- console.log(`[Setup] ${pathname} - seedModule: ${(performance.now() - t0).toFixed(2)}ms`);
2309
+ await withSpan("ssr.seed", async (span) => {
2310
+ span.setAttribute("pathname", pathname);
2311
+ span.setAttribute("streaming", streaming);
2312
+ await seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode);
2313
+ if (debug)
2314
+ console.log(`[Setup] ${pathname} - seedModule: ${(performance.now() - t0).toFixed(2)}ms`);
2315
+ });
2152
2316
  resetSSRAccessTracking();
2153
2317
  const bundlePreload = createBundlePreload(bundleUrl);
2154
- const preloadResult = await preloadContentModule(pathname, clientDir, cwd, isWatchMode);
2155
- if (debug)
2156
- console.log(`[Setup] ${pathname} - preloadContent: ${(performance.now() - t0).toFixed(2)}ms`);
2157
- const computeResult = await computeSSRData(pathname, clientDir, cwd, isWatchMode, { streaming, maxAge }, searchParams);
2158
- if (debug)
2159
- console.log(`[Setup] ${pathname} - computeSSRData: ${(performance.now() - t0).toFixed(2)}ms`);
2318
+ const preloadResult = await withSpan("ssr.preload", async (span) => {
2319
+ span.setAttribute("pathname", pathname);
2320
+ const result = await preloadContentModule(pathname, clientDir, cwd, isWatchMode);
2321
+ span.setAttribute("has_module", !!result.modulePath);
2322
+ if (debug)
2323
+ console.log(`[Setup] ${pathname} - preloadContent: ${(performance.now() - t0).toFixed(2)}ms`);
2324
+ return result;
2325
+ });
2326
+ const computeResult = await withSpan("ssr.compute.data", async (span) => {
2327
+ span.setAttribute("pathname", pathname);
2328
+ span.setAttribute("streaming", streaming);
2329
+ const result = await computeSSRData(pathname, clientDir, cwd, isWatchMode, { streaming, maxAge }, searchParams);
2330
+ span.setAttribute("has_error", !!result.error);
2331
+ span.setAttribute("has_data", Object.keys(result.data).length > 0);
2332
+ if (debug)
2333
+ console.log(`[Setup] ${pathname} - computeSSRData: ${(performance.now() - t0).toFixed(2)}ms`);
2334
+ return result;
2335
+ });
2160
2336
  setGlobalSSRData(computeResult.data);
2161
2337
  const usingCachedCollections = !!options.cachedCollections;
2162
- const byCollectionForSSR = options.cachedCollections ? options.cachedCollections : await loadCollections(cwd, isWatchMode);
2163
- if (debug)
2164
- console.log(`[Setup] ${pathname} - loadCollections (cached: ${usingCachedCollections}): ${(performance.now() - t0).toFixed(2)}ms`);
2338
+ const byCollectionForSSR = await withSpan("ssr.load.collections", async (span) => {
2339
+ span.setAttribute("pathname", pathname);
2340
+ span.setAttribute("cached", usingCachedCollections);
2341
+ const collections = options.cachedCollections ? options.cachedCollections : await loadCollections(cwd, isWatchMode);
2342
+ span.setAttribute("collection_count", Object.keys(collections).length);
2343
+ if (debug)
2344
+ console.log(`[Setup] ${pathname} - loadCollections (cached: ${usingCachedCollections}): ${(performance.now() - t0).toFixed(2)}ms`);
2345
+ return collections;
2346
+ });
2165
2347
  setGlobalCollections(byCollectionForSSR);
2166
2348
  const usingCachedCSS = !!options.cachedTailwindCSS;
2167
- const inlineStyleTag = options.cachedTailwindCSS ? options.cachedTailwindCSS : await inlineTailwindCSS(clientDir, !streaming, isWatchMode);
2168
- if (debug)
2169
- console.log(`[Setup] ${pathname} - inlineTailwindCSS (cached: ${usingCachedCSS}): ${(performance.now() - t0).toFixed(2)}ms`);
2349
+ const inlineStyleTag = await withSpan("ssr.inline.css", async (span) => {
2350
+ const css = options.cachedTailwindCSS ? options.cachedTailwindCSS : await inlineTailwindCSS(clientDir, !streaming, isWatchMode);
2351
+ span.setAttributes({
2352
+ "reroute.cached": usingCachedCSS,
2353
+ "reroute.css.size": css.length
2354
+ });
2355
+ if (debug)
2356
+ console.log(`[Setup] ${pathname} - inlineTailwindCSS (cached: ${usingCachedCSS}): ${(performance.now() - t0).toFixed(2)}ms`);
2357
+ return css;
2358
+ });
2170
2359
  let statusOverride = preloadResult.statusOverride;
2171
2360
  if (computeResult.statusContainer.value) {
2172
2361
  statusOverride = computeResult.statusContainer.value;
2173
2362
  }
2174
- const metadataResult = await extractPageMetadata(pathname, clientDir, cwd, isWatchMode, statusOverride, ogConfig);
2175
- if (debug)
2176
- console.log(`[Setup] ${pathname} - extractMetadata: ${(performance.now() - t0).toFixed(2)}ms`);
2363
+ const metadataResult = await withSpan("ssr.extract.metadata", async (span) => {
2364
+ const result = await extractPageMetadata(pathname, clientDir, cwd, isWatchMode, statusOverride, ogConfig);
2365
+ span.setAttributes({
2366
+ "reroute.pathname": pathname,
2367
+ "reroute.metadata.exists": !!result.perPageHead
2368
+ });
2369
+ if (debug)
2370
+ console.log(`[Setup] ${pathname} - extractMetadata: ${(performance.now() - t0).toFixed(2)}ms`);
2371
+ return result;
2372
+ });
2177
2373
  return {
2178
2374
  ssrData: computeResult.data,
2179
2375
  ssrError: computeResult.error,
@@ -2201,10 +2397,10 @@ function generateCollectionScripts(byCollectionForSSR) {
2201
2397
  } catch {}
2202
2398
  return "";
2203
2399
  }
2204
- function generateHydrationScripts(ssrData, isWatchMode, ssrError, collectionScripts = "", preloadScript = "", bundleUrl = "", pathname = "") {
2400
+ function generateHydrationScripts(ssrData, isWatchMode, ssrError, collectionScripts = "", preloadScript = "", bundleUrl = "", pathname = "", browserTelemetryConfig) {
2205
2401
  let scripts = preloadScript;
2206
2402
  scripts += collectionScripts;
2207
- scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname);
2403
+ scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname, browserTelemetryConfig);
2208
2404
  scripts += createFeedsScript();
2209
2405
  scripts += createLlmsScript();
2210
2406
  if (bundleUrl) {
@@ -2216,6 +2412,7 @@ function generateHydrationScripts(ssrData, isWatchMode, ssrError, collectionScri
2216
2412
  return scripts;
2217
2413
  }
2218
2414
  var init_setup = __esm(() => {
2415
+ init_server2();
2219
2416
  init_collections();
2220
2417
  init_compute();
2221
2418
  init_metadata2();
@@ -2284,6 +2481,7 @@ async function renderSSRDocument(options) {
2284
2481
  clientDir,
2285
2482
  cwd,
2286
2483
  isWatchMode,
2484
+ parentSpan: options.parentSpan,
2287
2485
  bundleUrl,
2288
2486
  maxAge,
2289
2487
  searchParams,
@@ -2293,14 +2491,29 @@ async function renderSSRDocument(options) {
2293
2491
  }, false);
2294
2492
  const duplicatedData = duplicateQueryParamData(setup2.ssrData);
2295
2493
  setGlobalSSRData(duplicatedData);
2296
- const componentWithPathname = cloneElement(rootComponent, {
2297
- pathname,
2298
- searchParams
2494
+ const appHtml = await withSpan("ssr.render.react", async (span) => {
2495
+ const componentWithPathname = cloneElement(rootComponent, {
2496
+ pathname,
2497
+ searchParams
2498
+ });
2499
+ span.setAttribute("reroute.pathname", pathname);
2500
+ const html3 = renderToString(componentWithPathname);
2501
+ span.setAttribute("reroute.html.final.size", html3.length);
2502
+ return html3;
2503
+ });
2504
+ const baseTemplate = await withSpan("ssr.load.template", async (span) => {
2505
+ const template2 = await loadIndexHtml(clientDir);
2506
+ span.setAttribute("reroute.template.size", template2.length);
2507
+ return template2;
2299
2508
  });
2300
- const appHtml = renderToString(componentWithPathname);
2301
- const baseTemplate = await loadIndexHtml(clientDir);
2302
2509
  const collectionScripts = generateCollectionScripts(setup2.byCollectionForSSR);
2303
- const hydrationScript = generateHydrationScripts(setup2.ssrData, isWatchMode, setup2.ssrError, collectionScripts, setup2.preloadHydrationScript, bundleUrl, pathname);
2510
+ const config = await loadConfig(cwd);
2511
+ const browserTelemetryConfig = config.telemetry?.browser;
2512
+ const hydrationScript = await withSpan("ssr.generate.scripts", async (span) => {
2513
+ const script = generateHydrationScripts(setup2.ssrData, isWatchMode, setup2.ssrError, collectionScripts, setup2.preloadHydrationScript, bundleUrl, pathname, browserTelemetryConfig);
2514
+ span.setAttribute("reroute.scripts.size", script.length);
2515
+ return script;
2516
+ });
2304
2517
  let statusOverride = setup2.preloadStatusOverride;
2305
2518
  if (setup2.statusContainer.value) {
2306
2519
  statusOverride = setup2.statusContainer.value;
@@ -2315,12 +2528,19 @@ async function renderSSRDocument(options) {
2315
2528
  dedent(setup2.metadataResult.perPageHead)
2316
2529
  ].filter(Boolean).join(`
2317
2530
  `));
2318
- const html2 = applyIndexTemplate(baseTemplate, appHtml, {
2319
- head: [setup2.inlineStyleTag, combinedHead].filter(Boolean).join(`
2531
+ const html2 = withSpanSync("ssr.apply.template", (span) => {
2532
+ const result = applyIndexTemplate(baseTemplate, appHtml, {
2533
+ head: [setup2.inlineStyleTag, combinedHead].filter(Boolean).join(`
2320
2534
  `),
2321
- hydrationScript,
2322
- lang: setup2.metadataResult.pageLang || lang,
2323
- appId
2535
+ hydrationScript,
2536
+ lang: setup2.metadataResult.pageLang || lang,
2537
+ appId
2538
+ });
2539
+ span.setAttributes({
2540
+ "reroute.html.final.size": result.length,
2541
+ "reroute.html.original.size": appHtml.length
2542
+ });
2543
+ return result;
2324
2544
  });
2325
2545
  return {
2326
2546
  html: html2,
@@ -2328,6 +2548,8 @@ async function renderSSRDocument(options) {
2328
2548
  };
2329
2549
  }
2330
2550
  var init_render = __esm(() => {
2551
+ init_server2();
2552
+ init_config();
2331
2553
  init_lib();
2332
2554
  init_html();
2333
2555
  });
@@ -4255,6 +4477,7 @@ async function renderSSRDocumentStream(options) {
4255
4477
  clientDir,
4256
4478
  cwd,
4257
4479
  isWatchMode,
4480
+ parentSpan: options.parentSpan,
4258
4481
  bundleUrl,
4259
4482
  maxAge,
4260
4483
  searchParams,
@@ -4276,14 +4499,19 @@ async function renderSSRDocumentStream(options) {
4276
4499
  const { readable, writable } = new TransformStream;
4277
4500
  const writer = writable.getWriter();
4278
4501
  const usingCache = !!options.cachedIndexHtml;
4279
- const tBeforeLoad = debug ? performance.now() : 0;
4280
- const baseTemplate = options.cachedIndexHtml ? options.cachedIndexHtml : await loadIndexHtml(clientDir);
4281
- if (debug)
4282
- console.log(`[renderStream] ${pathname} - loadIndexHtml (cached: ${usingCache}): ${(performance.now() - t0).toFixed(2)}ms (actual load: ${(performance.now() - tBeforeLoad).toFixed(2)}ms)`);
4283
- const tBeforeSplit = debug ? performance.now() : 0;
4284
- const { htmlHead, rootStart, rootEnd, htmlTail } = splitTemplate(baseTemplate, appId);
4285
- if (debug)
4286
- console.log(`[renderStream] ${pathname} - splitTemplate: ${(performance.now() - t0).toFixed(2)}ms (split took: ${(performance.now() - tBeforeSplit).toFixed(2)}ms)`);
4502
+ const { htmlHead, rootStart, rootEnd, htmlTail } = await withSpan("ssr.load.template", async (span) => {
4503
+ const template2 = options.cachedIndexHtml ? options.cachedIndexHtml : await loadIndexHtml(clientDir);
4504
+ span.setAttribute("reroute.cached", usingCache);
4505
+ span.setAttribute("reroute.template.size", template2.length);
4506
+ if (debug)
4507
+ console.log(`[renderStream] ${pathname} - loadIndexHtml (cached: ${usingCache}): ${(performance.now() - t0).toFixed(2)}ms`);
4508
+ const parts = splitTemplate(template2, appId);
4509
+ if (debug)
4510
+ console.log(`[renderStream] ${pathname} - splitTemplate: ${(performance.now() - t0).toFixed(2)}ms`);
4511
+ return {
4512
+ ...parts
4513
+ };
4514
+ });
4287
4515
  const pageLang = setup2.metadataResult.pageLang || lang;
4288
4516
  let headWithLang = htmlHead.replace(/<html([^>]*)>/i, `<html$1 lang="${pageLang}">`);
4289
4517
  const extraHead = setup2.bundlePreload + setup2.preloadExtraHead + setup2.metadataResult.perPageHead;
@@ -4293,6 +4521,8 @@ async function renderSSRDocumentStream(options) {
4293
4521
  if (/<meta\s+name\s*=\s*['"]description['"][^>]*>/i.test(extraHead)) {
4294
4522
  headWithLang = headWithLang.replace(/<meta\s+name\s*=\s*['"]description['"][^>]*>/i, "");
4295
4523
  }
4524
+ const config = await loadConfig(cwd);
4525
+ const browserTelemetryConfig = config.telemetry?.browser;
4296
4526
  streamSSRContent(writer, encoder, {
4297
4527
  rootComponent,
4298
4528
  pathname,
@@ -4311,82 +4541,102 @@ async function renderSSRDocumentStream(options) {
4311
4541
  ssrData: setup2.ssrData,
4312
4542
  ssrError: setup2.ssrError,
4313
4543
  byCollectionForSSR: setup2.byCollectionForSSR,
4314
- preloadHydrationScript: setup2.preloadHydrationScript
4544
+ preloadHydrationScript: setup2.preloadHydrationScript,
4545
+ browserTelemetryConfig,
4546
+ parentSpan: options.parentSpan
4315
4547
  });
4316
4548
  if (debug)
4317
4549
  console.log(`[renderStream] ${pathname} - returning stream: ${(performance.now() - t0).toFixed(2)}ms`);
4318
4550
  return { stream: readable, status: statusOverride || 200 };
4319
4551
  }
4320
4552
  async function streamSSRContent(writer, encoder, ctx) {
4321
- const t0 = ctx.debug ? performance.now() : 0;
4322
- const STREAM_TIMEOUT_MS = 60000;
4323
- let streamTimedOut = false;
4324
- let timeoutId = null;
4325
- const cleanup = () => {
4326
- if (timeoutId) {
4327
- clearTimeout(timeoutId);
4328
- timeoutId = null;
4329
- }
4330
- };
4331
- try {
4332
- const combinedHead = deduplicateMetaTags([ctx.inlineStyleTag, ctx.head, ctx.extraHead].filter(Boolean).join(`
4553
+ return withParentSpan(ctx.parentSpan, async () => {
4554
+ const t0 = ctx.debug ? performance.now() : 0;
4555
+ const STREAM_TIMEOUT_MS = 60000;
4556
+ let streamTimedOut = false;
4557
+ let timeoutId = null;
4558
+ const cleanup = () => {
4559
+ if (timeoutId) {
4560
+ clearTimeout(timeoutId);
4561
+ timeoutId = null;
4562
+ }
4563
+ };
4564
+ try {
4565
+ const combinedHead = deduplicateMetaTags([ctx.inlineStyleTag, ctx.head, ctx.extraHead].filter(Boolean).join(`
4333
4566
  `));
4334
- const headWithLangAndContent = ctx.headWithLang.replace(/<html([^>]*)>/i, `<html$1 lang="${ctx.pageLang}">`).replace(/<\/head>/i, `${combinedHead ? `${combinedHead}
4567
+ const headWithLangAndContent = ctx.headWithLang.replace(/<html([^>]*)>/i, `<html$1 lang="${ctx.pageLang}">`).replace(/<\/head>/i, `${combinedHead ? `${combinedHead}
4335
4568
  ` : ""}</head>`);
4336
- const headContent = `${headWithLangAndContent}<body>`;
4337
- await writer.write(encoder.encode(headContent));
4338
- if (ctx.debug)
4339
- console.log(`[Stream] ${ctx.pathname} - first byte written: ${(performance.now() - t0).toFixed(2)}ms`);
4340
- await writer.write(encoder.encode(ctx.rootStart));
4341
- const componentWithPathname = cloneElement2(ctx.rootComponent, {
4342
- pathname: ctx.pathname,
4343
- searchParams: ctx.searchParams
4344
- });
4345
- let streamError = null;
4346
- const streamPromise = renderToReadableStream(componentWithPathname, {
4347
- onError(error) {
4348
- console.error("[reroute] SSR stream error:", error);
4349
- streamError = error instanceof Error ? error : new Error(String(error));
4350
- }
4351
- }).catch((err) => {
4352
- streamError = err;
4353
- throw err;
4354
- });
4355
- const reactStream = await streamPromise;
4356
- if (streamError)
4357
- throw streamError;
4358
- const streamTimeoutPromise = new Promise((resolve) => {
4359
- timeoutId = setTimeout(() => {
4360
- console.warn(`[reroute] Stream timeout after ${STREAM_TIMEOUT_MS}ms for ${ctx.pathname}, forcing close`);
4361
- streamTimedOut = true;
4362
- resolve({ done: true, value: undefined });
4363
- }, STREAM_TIMEOUT_MS);
4364
- });
4365
- const reader = reactStream.getReader();
4366
- while (true) {
4367
- const result = await Promise.race([reader.read(), streamTimeoutPromise]);
4368
- if (result.done || streamTimedOut) {
4369
- try {
4370
- reader.releaseLock();
4371
- } catch {}
4372
- break;
4373
- }
4374
- if (result.value) {
4375
- await writer.write(result.value);
4376
- }
4569
+ const headContent = `${headWithLangAndContent}<body>`;
4570
+ await writer.write(encoder.encode(headContent));
4571
+ if (ctx.debug)
4572
+ console.log(`[Stream] ${ctx.pathname} - first byte written: ${(performance.now() - t0).toFixed(2)}ms`);
4573
+ await writer.write(encoder.encode(ctx.rootStart));
4574
+ await withSpan("ssr.document.stream", async (span) => {
4575
+ const componentWithPathname = cloneElement2(ctx.rootComponent, {
4576
+ pathname: ctx.pathname,
4577
+ searchParams: ctx.searchParams
4578
+ });
4579
+ span.setAttribute("reroute.pathname", ctx.pathname);
4580
+ let streamError = null;
4581
+ const streamPromise = renderToReadableStream(componentWithPathname, {
4582
+ onError(error) {
4583
+ console.error("[reroute] SSR stream error:", error);
4584
+ streamError = error instanceof Error ? error : new Error(String(error));
4585
+ }
4586
+ }).catch((err) => {
4587
+ streamError = err;
4588
+ throw err;
4589
+ });
4590
+ const reactStream = await streamPromise;
4591
+ if (streamError)
4592
+ throw streamError;
4593
+ const streamTimeoutPromise = new Promise((resolve) => {
4594
+ timeoutId = setTimeout(() => {
4595
+ console.warn(`[reroute] Stream timeout after ${STREAM_TIMEOUT_MS}ms for ${ctx.pathname}, forcing close`);
4596
+ streamTimedOut = true;
4597
+ resolve({ done: true, value: undefined });
4598
+ }, STREAM_TIMEOUT_MS);
4599
+ });
4600
+ const reader = reactStream.getReader();
4601
+ let chunkCount = 0;
4602
+ while (true) {
4603
+ const result = await Promise.race([
4604
+ reader.read(),
4605
+ streamTimeoutPromise
4606
+ ]);
4607
+ if (result.done || streamTimedOut) {
4608
+ try {
4609
+ reader.releaseLock();
4610
+ } catch {}
4611
+ break;
4612
+ }
4613
+ if (result.value) {
4614
+ await writer.write(result.value);
4615
+ chunkCount++;
4616
+ }
4617
+ }
4618
+ cleanup();
4619
+ span.setAttributes({
4620
+ "reroute.stream.chunks": chunkCount,
4621
+ "reroute.stream.timedOut": streamTimedOut
4622
+ });
4623
+ });
4624
+ await writer.write(encoder.encode(ctx.rootEnd));
4625
+ const allScripts = await withSpan("ssr.generate.scripts", async (span) => {
4626
+ const scripts2 = buildStreamingScripts(ctx);
4627
+ span.setAttribute("reroute.script_size", scripts2.length);
4628
+ return scripts2;
4629
+ });
4630
+ await writer.write(encoder.encode(allScripts + ctx.htmlTail));
4631
+ await writer.close();
4632
+ } catch (error) {
4633
+ cleanup();
4634
+ console.error("[reroute] Stream error:", error);
4635
+ try {
4636
+ await writer.abort(error);
4637
+ } catch {}
4377
4638
  }
4378
- cleanup();
4379
- await writer.write(encoder.encode(ctx.rootEnd));
4380
- const allScripts = buildStreamingScripts(ctx);
4381
- await writer.write(encoder.encode(allScripts + ctx.htmlTail));
4382
- await writer.close();
4383
- } catch (error) {
4384
- cleanup();
4385
- console.error("[reroute] Stream error:", error);
4386
- try {
4387
- await writer.abort(error);
4388
- } catch {}
4389
- }
4639
+ });
4390
4640
  }
4391
4641
  function buildStreamingScripts(ctx) {
4392
4642
  const collectionScripts = generateCollectionScripts(ctx.byCollectionForSSR);
@@ -4397,7 +4647,7 @@ function buildStreamingScripts(ctx) {
4397
4647
  ssrDataSnapshot[key] = value;
4398
4648
  }
4399
4649
  }
4400
- const dataScript = createDataScript(ssrDataSnapshot, ctx.isWatchMode ? ctx.ssrError : undefined, ctx.pathname);
4650
+ const dataScript = createDataScript(ssrDataSnapshot, ctx.isWatchMode ? ctx.ssrError : undefined, ctx.pathname, ctx.browserTelemetryConfig);
4401
4651
  const feedsScript = createFeedsScript();
4402
4652
  const llmsScript = createLlmsScript();
4403
4653
  let allScripts = dataScript + feedsScript + llmsScript + collectionScripts + ctx.preloadHydrationScript;
@@ -4408,6 +4658,8 @@ function buildStreamingScripts(ctx) {
4408
4658
  return allScripts;
4409
4659
  }
4410
4660
  var init_stream = __esm(() => {
4661
+ init_server2();
4662
+ init_config();
4411
4663
  init_lib();
4412
4664
  init_html();
4413
4665
  init_imports();
@@ -4955,12 +5207,19 @@ function registerArtifactsRoutes(app, cwd, fileCache, options) {
4955
5207
 
4956
5208
  // packages/elysia/src/routes/content.ts
4957
5209
  init_core();
5210
+ import { trace as trace3 } from "@opentelemetry/api";
4958
5211
  import { NotFoundError as NotFoundError3 } from "elysia";
4959
- function getOtelUtilities() {
5212
+ var otelAvailable2;
5213
+ function isOtelAvailable2() {
5214
+ if (otelAvailable2 !== undefined)
5215
+ return otelAvailable2;
4960
5216
  try {
4961
- return __require("@elysiajs/opentelemetry");
5217
+ __require("@opentelemetry/api");
5218
+ otelAvailable2 = true;
5219
+ return true;
4962
5220
  } catch {
4963
- return null;
5221
+ otelAvailable2 = false;
5222
+ return false;
4964
5223
  }
4965
5224
  }
4966
5225
  function registerContentRoutes(app, cwd, collectionCache, directive, maxAge, isWatchMode) {
@@ -4971,14 +5230,13 @@ function registerContentRoutes(app, cwd, collectionCache, directive, maxAge, isW
4971
5230
  const cacheKey = `content:${collectionPath}`;
4972
5231
  const cached = collectionCache.get(cacheKey);
4973
5232
  if (cached) {
4974
- const otel = getOtelUtilities();
4975
- const currentSpan = otel?.getCurrentSpan();
4976
- currentSpan?.setAttributes({
4977
- "http.request.method": "GET",
4978
- "http.response.status_code": 200,
4979
- "reroute.content.cache_hit": true,
4980
- "reroute.content.collection": collectionPath
4981
- });
5233
+ if (isOtelAvailable2()) {
5234
+ const currentSpan = trace3.getActiveSpan();
5235
+ currentSpan?.setAttributes({
5236
+ "reroute.cache.hit": true,
5237
+ "reroute.collection": collectionPath
5238
+ });
5239
+ }
4982
5240
  const response = cached.clone();
4983
5241
  response.headers.set("Reroute-Cache", "HIT");
4984
5242
  return response;
@@ -4987,14 +5245,10 @@ function registerContentRoutes(app, cwd, collectionCache, directive, maxAge, isW
4987
5245
  const collectionFile = join(cwd, ".reroute", "collections", `${collectionPath}.js`);
4988
5246
  const file = Bun.file(collectionFile);
4989
5247
  if (!await file.exists()) {
4990
- const otel2 = getOtelUtilities();
4991
- const currentSpan2 = otel2?.getCurrentSpan();
4992
- currentSpan2?.setAttributes({
4993
- "http.request.method": "GET",
4994
- "http.response.status_code": 404,
4995
- "reroute.content.not_found": true,
4996
- "reroute.content.collection": collectionPath
4997
- });
5248
+ if (isOtelAvailable2()) {
5249
+ const currentSpan = trace3.getActiveSpan();
5250
+ currentSpan?.setAttribute("reroute.collection", collectionPath);
5251
+ }
4998
5252
  throw new NotFoundError3;
4999
5253
  }
5000
5254
  const url = `${Bun.pathToFileURL(collectionFile).href}${isWatchMode ? `?t=${Date.now()}` : ""}`;
@@ -5010,29 +5264,23 @@ function registerContentRoutes(app, cwd, collectionCache, directive, maxAge, isW
5010
5264
  }
5011
5265
  });
5012
5266
  collectionCache.set(cacheKey, response);
5013
- const otel = getOtelUtilities();
5014
- const currentSpan = otel?.getCurrentSpan();
5015
- currentSpan?.setAttributes({
5016
- "http.request.method": "GET",
5017
- "http.response.status_code": 200,
5018
- "reroute.content.served": true,
5019
- "reroute.content.collection": collectionPath,
5020
- "reroute.content.items_count": items.length,
5021
- "reroute.content.cache_hit": false
5022
- });
5267
+ if (isOtelAvailable2()) {
5268
+ const currentSpan = trace3.getActiveSpan();
5269
+ currentSpan?.setAttributes({
5270
+ "reroute.collection": collectionPath,
5271
+ "reroute.collection.docs": items.length,
5272
+ "reroute.cache.hit": false
5273
+ });
5274
+ }
5023
5275
  return response.clone();
5024
5276
  } catch (e) {
5025
5277
  if (e instanceof NotFoundError3)
5026
5278
  throw e;
5027
5279
  console.error(`[reroute] Failed to serve collection ${collectionPath}:`, e);
5028
- const otel = getOtelUtilities();
5029
- const currentSpan = otel?.getCurrentSpan();
5030
- currentSpan?.setAttributes({
5031
- "http.request.method": "GET",
5032
- "http.response.status_code": 500,
5033
- "reroute.content.error": true,
5034
- "reroute.content.collection": collectionPath
5035
- });
5280
+ if (isOtelAvailable2()) {
5281
+ const currentSpan = trace3.getActiveSpan();
5282
+ currentSpan?.setAttribute("reroute.collection", collectionPath);
5283
+ }
5036
5284
  throw new NotFoundError3;
5037
5285
  }
5038
5286
  });
@@ -6681,7 +6929,9 @@ function registerSitemapRoutes(app, options) {
6681
6929
 
6682
6930
  // packages/elysia/src/routes/ssr.ts
6683
6931
  init_core();
6932
+ init_server2();
6684
6933
  import { join as join4 } from "node:path";
6934
+ import { trace as trace4 } from "@opentelemetry/api";
6685
6935
  import { NotFoundError as NotFoundError11 } from "elysia";
6686
6936
  if (typeof process !== "undefined") {
6687
6937
  process.on("unhandledRejection", (reason, _promise) => {
@@ -6691,16 +6941,17 @@ if (typeof process !== "undefined") {
6691
6941
  console.error("[reroute] Uncaught Exception:", error);
6692
6942
  });
6693
6943
  }
6694
- var cachedOtelUtilities;
6695
- function getOtelUtilities2() {
6696
- if (cachedOtelUtilities !== undefined)
6697
- return cachedOtelUtilities;
6944
+ var otelAvailable3;
6945
+ function isOtelAvailable3() {
6946
+ if (otelAvailable3 !== undefined)
6947
+ return otelAvailable3;
6698
6948
  try {
6699
- cachedOtelUtilities = __require("@elysiajs/opentelemetry");
6700
- return cachedOtelUtilities;
6949
+ __require("@opentelemetry/api");
6950
+ otelAvailable3 = true;
6951
+ return true;
6701
6952
  } catch {
6702
- cachedOtelUtilities = null;
6703
- return null;
6953
+ otelAvailable3 = false;
6954
+ return false;
6704
6955
  }
6705
6956
  }
6706
6957
  function registerSSRRoutes(app, options) {
@@ -6742,7 +6993,8 @@ function registerSSRRoutes(app, options) {
6742
6993
  }
6743
6994
  const handleSSR = async ({
6744
6995
  request,
6745
- set
6996
+ set,
6997
+ store
6746
6998
  }) => {
6747
6999
  const t0 = performance.now();
6748
7000
  const method = request.method || "GET";
@@ -6757,62 +7009,71 @@ function registerSSRRoutes(app, options) {
6757
7009
  const fullPath = pathname;
6758
7010
  const searchParams = url.searchParams;
6759
7011
  const acceptEncoding = request.headers.get("accept-encoding") || "";
6760
- if (!isWatchMode && SSR_HTML_TTL_MS > 0) {
6761
- try {
6762
- const ck = makeKey(pathname, acceptEncoding);
6763
- const cached = htmlCache.get(ck);
6764
- if (cached && cached.exp > Date.now()) {
6765
- const otel = getOtelUtilities2();
6766
- const currentSpan = otel?.getCurrentSpan();
6767
- currentSpan?.setAttributes({
6768
- "reroute.cache.hit": true,
6769
- "reroute.cache.key": ck,
6770
- "reroute.pathname": pathname,
6771
- "http.request.method": method,
6772
- "http.response.status_code": cached.status
6773
- });
6774
- set.status = cached.status;
6775
- Object.assign(set.headers, cached.headers);
6776
- set.headers["Reroute-Cache"] = "HIT";
6777
- return new Response(cached.body);
6778
- }
6779
- } catch {}
6780
- }
6781
- const tBeforeBundle = debug ? performance.now() : 0;
6782
- const bundleUrl = await getBundleUrl();
6783
- if (debug)
6784
- console.log(`[SSR] ${pathname} - bundleUrl: ${(performance.now() - t0).toFixed(2)}ms (actual call: ${(performance.now() - tBeforeBundle).toFixed(2)}ms)`);
6785
- const cachedCollections = await getCollections();
6786
- const cachedTailwindCSS = await getTailwindCSS();
6787
- const cachedIndexHtml = await getIndexHtml();
6788
- if (debug)
6789
- console.log(`[SSR] ${pathname} - cached setup: ${(performance.now() - t0).toFixed(2)}ms`);
6790
- try {
6791
- const linkValue = `<${bundleUrl}>; rel=modulepreload; as=script`;
7012
+ const parentSpan = store.telemetrySpan;
7013
+ return withParentSpan(parentSpan, async () => {
7014
+ if (!isWatchMode && SSR_HTML_TTL_MS > 0) {
7015
+ try {
7016
+ const ck = makeKey(pathname, acceptEncoding);
7017
+ const cached = htmlCache.get(ck);
7018
+ if (cached && cached.exp > Date.now()) {
7019
+ if (isOtelAvailable3()) {
7020
+ const currentSpan = trace4.getActiveSpan();
7021
+ currentSpan?.setAttributes({
7022
+ "reroute.cache.hit": true,
7023
+ "reroute.cache.key": ck,
7024
+ "reroute.pathname": pathname
7025
+ });
7026
+ }
7027
+ set.status = cached.status;
7028
+ Object.assign(set.headers, cached.headers);
7029
+ set.headers["Reroute-Cache"] = "HIT";
7030
+ return new Response(cached.body);
7031
+ }
7032
+ } catch {}
7033
+ }
7034
+ const bundleUrl = await withSpan("ssr.get.bundle", async (span) => {
7035
+ span.setAttribute("reroute.pathname", pathname);
7036
+ const url2 = await getBundleUrl();
7037
+ if (debug)
7038
+ console.log(`[SSR] ${pathname} - bundleUrl: ${(performance.now() - t0).toFixed(2)}ms`);
7039
+ return url2;
7040
+ });
7041
+ const { cachedCollections, cachedTailwindCSS, cachedIndexHtml } = await withSpan("ssr.load.cache", async (span) => {
7042
+ const collections2 = await getCollections();
7043
+ const tailwindCSS = await getTailwindCSS();
7044
+ const indexHtml = await getIndexHtml();
7045
+ span.setAttributes({
7046
+ "reroute.pathname": pathname,
7047
+ "reroute.collections.exists": !!collections2,
7048
+ "reroute.collections.count": Object.keys(collections2).length
7049
+ });
7050
+ if (debug)
7051
+ console.log(`[SSR] ${pathname} - cached setup: ${(performance.now() - t0).toFixed(2)}ms`);
7052
+ return {
7053
+ cachedCollections: collections2,
7054
+ cachedTailwindCSS: tailwindCSS,
7055
+ cachedIndexHtml: indexHtml
7056
+ };
7057
+ });
6792
7058
  try {
6793
- const hints = new Headers({ Link: linkValue });
6794
- request?.sendEarlyHints?.(hints);
7059
+ const linkValue = `<${bundleUrl}>; rel=modulepreload; as=script`;
7060
+ try {
7061
+ const hints = new Headers({ Link: linkValue });
7062
+ request?.sendEarlyHints?.(hints);
7063
+ } catch {}
7064
+ set.headers.link = set.headers.link ? `${set.headers.link}, ${linkValue}` : linkValue;
6795
7065
  } catch {}
6796
- set.headers.link = set.headers.link ? `${set.headers.link}, ${linkValue}` : linkValue;
6797
- } catch {}
6798
- const cacheControlHeader = isWatchMode ? "no-cache, no-store, must-revalidate" : `${directive}, max-age=${maxAge}`;
6799
- let response;
6800
- if (streamingEnabled) {
6801
- let stream2;
6802
- let status;
6803
- if (debug)
6804
- console.log(`[SSR] ${pathname} - starting stream: ${(performance.now() - t0).toFixed(2)}ms`);
6805
- try {
6806
- const otel = getOtelUtilities2();
6807
- const renderFn = async () => {
6808
- otel?.setAttributes({
6809
- "http.request.method": "GET",
6810
- "reroute.ssr.enabled": true,
6811
- "reroute.ssr.streaming": true,
6812
- "reroute.cache.hit": false,
6813
- "reroute.pathname": pathname
7066
+ const cacheControlHeader = isWatchMode ? "no-cache, no-store, must-revalidate" : `${directive}, max-age=${maxAge}`;
7067
+ let response;
7068
+ if (streamingEnabled) {
7069
+ if (debug)
7070
+ console.log(`[SSR] ${pathname} - starting stream: ${(performance.now() - t0).toFixed(2)}ms`);
7071
+ const { stream: stream2, status } = await withSpan("ssr.document.render", async (renderSpan) => {
7072
+ renderSpan?.setAttributes({
7073
+ "reroute.pathname": pathname,
7074
+ "reroute.cache.hit": false
6814
7075
  });
6815
- const result2 = await renderSSRDocumentStream({
7076
+ const result = await renderSSRDocumentStream({
6816
7077
  pathname: fullPath,
6817
7078
  rootComponent,
6818
7079
  clientDir,
@@ -6828,25 +7089,191 @@ function registerSSRRoutes(app, options) {
6828
7089
  appId,
6829
7090
  maxAge,
6830
7091
  searchParams,
6831
- ogConfig: options.ogConfig
7092
+ ogConfig: options.ogConfig,
7093
+ parentSpan: renderSpan
6832
7094
  });
6833
- otel?.setAttributes({
6834
- "http.response.status_code": result2.status
6835
- });
6836
- return result2;
6837
- };
6838
- const tBeforeRecord = debug ? performance.now() : 0;
6839
- const result = otel ? await otel.record("reroute.ssr.render_stream", renderFn) : await renderFn();
6840
- if (debug)
6841
- console.log(`[SSR] ${pathname} - otel.record completed: ${(performance.now() - t0).toFixed(2)}ms (record overhead: ${(performance.now() - tBeforeRecord - (performance.now() - t0)).toFixed(2)}ms)`);
6842
- const tBeforeExtract = debug ? performance.now() : 0;
6843
- stream2 = result.stream;
6844
- status = result.status;
7095
+ renderSpan?.setAttribute("http.response.status_code", result.status);
7096
+ if (debug)
7097
+ console.log(`[SSR] ${pathname} - render completed: ${(performance.now() - t0).toFixed(2)}ms`);
7098
+ return result;
7099
+ });
6845
7100
  if (debug)
6846
- console.log(`[SSR] ${pathname} - stream extracted from result: ${(performance.now() - t0).toFixed(2)}ms (extract: ${(performance.now() - tBeforeExtract).toFixed(2)}ms)`);
6847
- } catch (ssrError) {
6848
- console.error("[reroute] SSR streaming failed, returning error page:", ssrError);
6849
- const errorHtml = `<!DOCTYPE html>
7101
+ console.log(`[SSR] ${pathname} - before compression check: ${(performance.now() - t0).toFixed(2)}ms, compression=${compression2}, acceptEncoding=${!!acceptEncoding}`);
7102
+ if (compression2 && acceptEncoding) {
7103
+ const fullHtml = await withSpan("ssr.buffer.stream", async (span) => {
7104
+ const chunks = [];
7105
+ const reader = stream2.getReader();
7106
+ try {
7107
+ while (true) {
7108
+ const { done, value } = await reader.read();
7109
+ if (done)
7110
+ break;
7111
+ chunks.push(new Uint8Array(value));
7112
+ }
7113
+ } finally {
7114
+ reader.releaseLock();
7115
+ }
7116
+ const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
7117
+ const buffer = new Uint8Array(totalLength);
7118
+ let offset = 0;
7119
+ for (const chunk of chunks) {
7120
+ buffer.set(chunk, offset);
7121
+ offset += chunk.length;
7122
+ }
7123
+ span.setAttributes({
7124
+ "reroute.stream.chunks": chunks.length,
7125
+ "reroute.stream.bytes": totalLength
7126
+ });
7127
+ return buffer;
7128
+ });
7129
+ const { body, extraHeaders } = await withSpan("ssr.compress", async (span) => {
7130
+ const result = gzipIfAccepted(fullHtml, "text/html; charset=utf-8", acceptEncoding);
7131
+ span.setAttributes({
7132
+ "reroute.size.original": fullHtml.length,
7133
+ "reroute.size.compressed": result.body.length,
7134
+ "reroute.encoding": extraHeaders["Content-Encoding"] || "none"
7135
+ });
7136
+ return result;
7137
+ });
7138
+ if (!isWatchMode && SSR_HTML_TTL_MS > 0 && status === 200) {
7139
+ try {
7140
+ const ck = makeKey(pathname, acceptEncoding);
7141
+ const cacheHeaders = {
7142
+ "Content-Type": "text/html; charset=utf-8",
7143
+ "Cache-Control": cacheControlHeader,
7144
+ ...extraHeaders
7145
+ };
7146
+ if (set.headers.link) {
7147
+ cacheHeaders.Link = set.headers.link;
7148
+ }
7149
+ htmlCache.set(ck, {
7150
+ status,
7151
+ headers: cacheHeaders,
7152
+ body,
7153
+ exp: Date.now() + SSR_HTML_TTL_MS
7154
+ });
7155
+ } catch {}
7156
+ }
7157
+ const resHeaders = {
7158
+ "Content-Type": "text/html; charset=utf-8",
7159
+ "Cache-Control": cacheControlHeader,
7160
+ "Reroute-Cache": "MISS",
7161
+ ...extraHeaders
7162
+ };
7163
+ if (set.headers.link) {
7164
+ resHeaders.Link = set.headers.link;
7165
+ }
7166
+ set.status = status;
7167
+ response = new Response(body, {
7168
+ status,
7169
+ headers: resHeaders
7170
+ });
7171
+ } else {
7172
+ const shouldCache = !isWatchMode && SSR_HTML_TTL_MS > 0 && status === 200;
7173
+ if (debug)
7174
+ console.log(`[SSR] ${pathname} - no compression path, shouldCache=${shouldCache}`);
7175
+ if (shouldCache) {
7176
+ response = await withSpan("ssr.create.response", async (span) => {
7177
+ if (debug)
7178
+ console.log(`[SSR] ${pathname} - creating caching stream: ${(performance.now() - t0).toFixed(2)}ms`);
7179
+ const chunks = [];
7180
+ const cachingStream = stream2.pipeThrough(new TransformStream({
7181
+ transform(chunk, controller) {
7182
+ chunks.push(new Uint8Array(chunk));
7183
+ controller.enqueue(chunk);
7184
+ },
7185
+ flush() {
7186
+ try {
7187
+ const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
7188
+ const fullHtml = new Uint8Array(totalLength);
7189
+ let offset = 0;
7190
+ for (const chunk of chunks) {
7191
+ fullHtml.set(chunk, offset);
7192
+ offset += chunk.length;
7193
+ }
7194
+ const ck = makeKey(pathname, acceptEncoding);
7195
+ const cacheHeaders = {
7196
+ "Content-Type": "text/html; charset=utf-8",
7197
+ "Cache-Control": cacheControlHeader
7198
+ };
7199
+ if (set.headers.link) {
7200
+ cacheHeaders.Link = set.headers.link;
7201
+ }
7202
+ htmlCache.set(ck, {
7203
+ status,
7204
+ headers: cacheHeaders,
7205
+ body: fullHtml,
7206
+ exp: Date.now() + SSR_HTML_TTL_MS
7207
+ });
7208
+ } catch (e) {
7209
+ console.error("[reroute] Failed to cache stream:", e);
7210
+ }
7211
+ }
7212
+ }));
7213
+ set.status = status;
7214
+ const tBeforeResponse = debug ? performance.now() : 0;
7215
+ const res = new Response(cachingStream, {
7216
+ status,
7217
+ headers: {
7218
+ "Content-Type": "text/html; charset=utf-8",
7219
+ "Cache-Control": cacheControlHeader,
7220
+ "Reroute-Cache": "MISS"
7221
+ }
7222
+ });
7223
+ if (debug)
7224
+ console.log(`[SSR] ${pathname} - Response created (cached stream): ${(performance.now() - t0).toFixed(2)}ms (creation: ${(performance.now() - tBeforeResponse).toFixed(2)}ms)`);
7225
+ span.setAttribute("reroute.cached", true);
7226
+ return res;
7227
+ });
7228
+ } else {
7229
+ if (debug)
7230
+ console.log(`[SSR] ${pathname} - creating direct stream response: ${(performance.now() - t0).toFixed(2)}ms`);
7231
+ set.status = status;
7232
+ response = new Response(stream2, {
7233
+ status,
7234
+ headers: {
7235
+ "Content-Type": "text/html; charset=utf-8",
7236
+ "Cache-Control": cacheControlHeader,
7237
+ "Reroute-Cache": "MISS"
7238
+ }
7239
+ });
7240
+ if (debug)
7241
+ console.log(`[SSR] ${pathname} - Response created (direct stream): ${(performance.now() - t0).toFixed(2)}ms`);
7242
+ }
7243
+ }
7244
+ } else {
7245
+ let html2;
7246
+ let status;
7247
+ try {
7248
+ const result = await withSpan("ssr.render.sync", async (renderSpan) => {
7249
+ renderSpan?.setAttributes({
7250
+ "reroute.pathname": pathname,
7251
+ "reroute.cache.hit": false
7252
+ });
7253
+ const renderResult = await renderSSRDocument({
7254
+ pathname: fullPath,
7255
+ rootComponent,
7256
+ clientDir,
7257
+ cwd,
7258
+ isWatchMode,
7259
+ bundleUrl,
7260
+ head,
7261
+ lang,
7262
+ appId,
7263
+ maxAge,
7264
+ searchParams,
7265
+ ogConfig: options.ogConfig,
7266
+ parentSpan: renderSpan
7267
+ });
7268
+ renderSpan?.setAttribute("http.response.status_code", renderResult.status);
7269
+ return renderResult;
7270
+ });
7271
+ html2 = result.html;
7272
+ status = result.status;
7273
+ } catch (ssrError) {
7274
+ console.error("[reroute] SSR rendering failed, returning error page:", ssrError);
7275
+ set.status = 500;
7276
+ const errorHtml = `<!DOCTYPE html>
6850
7277
  <html lang="en">
6851
7278
  <head>
6852
7279
  <meta charset="UTF-8">
@@ -6865,53 +7292,20 @@ function registerSSRRoutes(app, options) {
6865
7292
  <script type="module" src="${bundleUrl}"></script>
6866
7293
  </body>
6867
7294
  </html>`;
6868
- return new Response(errorHtml, {
6869
- status: 500,
6870
- headers: { "Content-Type": "text/html; charset=utf-8" }
6871
- });
6872
- }
6873
- if (debug)
6874
- console.log(`[SSR] ${pathname} - before compression check: ${(performance.now() - t0).toFixed(2)}ms, compression=${compression2}, acceptEncoding=${!!acceptEncoding}`);
6875
- if (compression2 && acceptEncoding) {
6876
- const chunks = [];
6877
- const reader = stream2.getReader();
6878
- try {
6879
- while (true) {
6880
- const { done, value } = await reader.read();
6881
- if (done)
6882
- break;
6883
- chunks.push(new Uint8Array(value));
6884
- }
6885
- } finally {
6886
- reader.releaseLock();
6887
- }
6888
- const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
6889
- const fullHtml = new Uint8Array(totalLength);
6890
- let offset = 0;
6891
- for (const chunk of chunks) {
6892
- fullHtml.set(chunk, offset);
6893
- offset += chunk.length;
6894
- }
6895
- const { body, extraHeaders } = gzipIfAccepted(fullHtml, "text/html; charset=utf-8", acceptEncoding);
6896
- if (!isWatchMode && SSR_HTML_TTL_MS > 0 && status === 200) {
6897
- try {
6898
- const ck = makeKey(pathname, acceptEncoding);
6899
- const cacheHeaders = {
6900
- "Content-Type": "text/html; charset=utf-8",
6901
- "Cache-Control": cacheControlHeader,
6902
- ...extraHeaders
6903
- };
6904
- if (set.headers.link) {
6905
- cacheHeaders.Link = set.headers.link;
6906
- }
6907
- htmlCache.set(ck, {
6908
- status,
6909
- headers: cacheHeaders,
6910
- body,
6911
- exp: Date.now() + SSR_HTML_TTL_MS
6912
- });
6913
- } catch {}
7295
+ return new Response(errorHtml, {
7296
+ status: 500,
7297
+ headers: { "Content-Type": "text/html; charset=utf-8" }
7298
+ });
6914
7299
  }
7300
+ const { body, extraHeaders } = compression2 ? await withSpan("ssr.compress", async (span) => {
7301
+ const result = gzipIfAccepted(html2, "text/html; charset=utf-8", acceptEncoding);
7302
+ span.setAttributes({
7303
+ "reroute.size.original": html2.length,
7304
+ "reroute.size.compressed": typeof result.body === "string" ? result.body.length : result.body.length,
7305
+ "reroute.encoding": result.extraHeaders["Content-Encoding"] || "none"
7306
+ });
7307
+ return result;
7308
+ }) : { body: html2, extraHeaders: {} };
6915
7309
  const resHeaders = {
6916
7310
  "Content-Type": "text/html; charset=utf-8",
6917
7311
  "Cache-Control": cacheControlHeader,
@@ -6926,171 +7320,26 @@ function registerSSRRoutes(app, options) {
6926
7320
  status,
6927
7321
  headers: resHeaders
6928
7322
  });
6929
- } else {
6930
- const shouldCache = !isWatchMode && SSR_HTML_TTL_MS > 0 && status === 200;
6931
- if (debug)
6932
- console.log(`[SSR] ${pathname} - no compression path, shouldCache=${shouldCache}`);
6933
- if (shouldCache) {
6934
- if (debug)
6935
- console.log(`[SSR] ${pathname} - creating caching stream: ${(performance.now() - t0).toFixed(2)}ms`);
6936
- const chunks = [];
6937
- const cachingStream = stream2.pipeThrough(new TransformStream({
6938
- transform(chunk, controller) {
6939
- chunks.push(new Uint8Array(chunk));
6940
- controller.enqueue(chunk);
6941
- },
6942
- flush() {
6943
- try {
6944
- const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
6945
- const fullHtml = new Uint8Array(totalLength);
6946
- let offset = 0;
6947
- for (const chunk of chunks) {
6948
- fullHtml.set(chunk, offset);
6949
- offset += chunk.length;
6950
- }
6951
- const ck = makeKey(pathname, acceptEncoding);
6952
- const cacheHeaders = {
6953
- "Content-Type": "text/html; charset=utf-8",
6954
- "Cache-Control": cacheControlHeader
6955
- };
6956
- if (set.headers.link) {
6957
- cacheHeaders.Link = set.headers.link;
6958
- }
6959
- htmlCache.set(ck, {
6960
- status,
6961
- headers: cacheHeaders,
6962
- body: fullHtml,
6963
- exp: Date.now() + SSR_HTML_TTL_MS
6964
- });
6965
- } catch (e) {
6966
- console.error("[reroute] Failed to cache stream:", e);
6967
- }
6968
- }
6969
- }));
6970
- set.status = status;
6971
- const tBeforeResponse = debug ? performance.now() : 0;
6972
- response = new Response(cachingStream, {
6973
- status,
6974
- headers: {
6975
- "Content-Type": "text/html; charset=utf-8",
6976
- "Cache-Control": cacheControlHeader,
6977
- "Reroute-Cache": "MISS"
6978
- }
6979
- });
6980
- if (debug)
6981
- console.log(`[SSR] ${pathname} - Response created (cached stream): ${(performance.now() - t0).toFixed(2)}ms (creation: ${(performance.now() - tBeforeResponse).toFixed(2)}ms)`);
6982
- } else {
6983
- if (debug)
6984
- console.log(`[SSR] ${pathname} - creating direct stream response: ${(performance.now() - t0).toFixed(2)}ms`);
6985
- set.status = status;
6986
- const tBeforeResponse = debug ? performance.now() : 0;
6987
- response = new Response(stream2, {
6988
- status,
6989
- headers: {
6990
- "Content-Type": "text/html; charset=utf-8",
6991
- "Cache-Control": cacheControlHeader,
6992
- "Reroute-Cache": "MISS"
6993
- }
6994
- });
6995
- if (debug)
6996
- console.log(`[SSR] ${pathname} - Response created (direct stream): ${(performance.now() - t0).toFixed(2)}ms (creation: ${(performance.now() - tBeforeResponse).toFixed(2)}ms)`);
7323
+ if (!isWatchMode && SSR_HTML_TTL_MS > 0 && status >= 200 && status < 300) {
7324
+ try {
7325
+ const ck = makeKey(pathname, acceptEncoding);
7326
+ htmlCache.set(ck, {
7327
+ status,
7328
+ headers: resHeaders,
7329
+ body,
7330
+ exp: Date.now() + SSR_HTML_TTL_MS
7331
+ });
7332
+ } catch {}
6997
7333
  }
6998
7334
  }
6999
- } else {
7000
- let html2;
7001
- let status;
7002
- try {
7003
- const otel = getOtelUtilities2();
7004
- const renderFn = async () => {
7005
- otel?.setAttributes({
7006
- "http.request.method": "GET",
7007
- "reroute.ssr.enabled": true,
7008
- "reroute.ssr.streaming": false,
7009
- "reroute.cache.hit": false,
7010
- "reroute.pathname": pathname
7011
- });
7012
- const result2 = await renderSSRDocument({
7013
- pathname: fullPath,
7014
- rootComponent,
7015
- clientDir,
7016
- cwd,
7017
- isWatchMode,
7018
- bundleUrl,
7019
- head,
7020
- lang,
7021
- appId,
7022
- maxAge,
7023
- searchParams,
7024
- ogConfig: options.ogConfig
7025
- });
7026
- otel?.setAttributes({
7027
- "http.response.status_code": result2.status
7028
- });
7029
- return result2;
7030
- };
7031
- const result = otel ? await otel.record("reroute.ssr.render_sync", renderFn) : await renderFn();
7032
- html2 = result.html;
7033
- status = result.status;
7034
- } catch (ssrError) {
7035
- console.error("[reroute] SSR rendering failed, returning error page:", ssrError);
7036
- const errorHtml = `<!DOCTYPE html>
7037
- <html lang="en">
7038
- <head>
7039
- <meta charset="UTF-8">
7040
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7041
- <title>Error</title>
7042
- <style>
7043
- body { font-family: system-ui, sans-serif; padding: 2rem; background: #111; color: #fff; }
7044
- h1 { color: #f87171; }
7045
- pre { background: #222; padding: 1rem; border-radius: 0.5rem; overflow: auto; }
7046
- </style>
7047
- </head>
7048
- <body>
7049
- <h1>Server Error</h1>
7050
- <p>An error occurred while rendering this page.</p>
7051
- ${isWatchMode ? `<pre>${ssrError instanceof Error ? ssrError.stack : String(ssrError)}</pre>` : ""}
7052
- <script type="module" src="${bundleUrl}"></script>
7053
- </body>
7054
- </html>`;
7055
- return new Response(errorHtml, {
7056
- status: 500,
7057
- headers: { "Content-Type": "text/html; charset=utf-8" }
7058
- });
7059
- }
7060
- const { body, extraHeaders } = compression2 ? gzipIfAccepted(html2, "text/html; charset=utf-8", acceptEncoding) : { body: html2, extraHeaders: {} };
7061
- const resHeaders = {
7062
- "Content-Type": "text/html; charset=utf-8",
7063
- "Cache-Control": cacheControlHeader,
7064
- "Reroute-Cache": "MISS",
7065
- ...extraHeaders
7066
- };
7067
- if (set.headers.link) {
7068
- resHeaders.Link = set.headers.link;
7069
- }
7070
- set.status = status;
7071
- response = new Response(body, {
7072
- status,
7073
- headers: resHeaders
7074
- });
7075
- if (!isWatchMode && SSR_HTML_TTL_MS > 0 && status >= 200 && status < 300) {
7076
- try {
7077
- const ck = makeKey(pathname, acceptEncoding);
7078
- htmlCache.set(ck, {
7079
- status,
7080
- headers: resHeaders,
7081
- body,
7082
- exp: Date.now() + SSR_HTML_TTL_MS
7083
- });
7084
- } catch {}
7085
- }
7086
- }
7087
- const tBeforeReturn = debug ? performance.now() : 0;
7088
- if (debug)
7089
- console.log(`[SSR] ${pathname} - about to return response: ${(performance.now() - t0).toFixed(2)}ms`);
7090
- const returnValue = response;
7091
- if (debug)
7092
- console.log(`[SSR] ${pathname} - response returned: ${(performance.now() - t0).toFixed(2)}ms (return overhead: ${(performance.now() - tBeforeReturn).toFixed(2)}ms)`);
7093
- return returnValue;
7335
+ const tBeforeReturn = debug ? performance.now() : 0;
7336
+ if (debug)
7337
+ console.log(`[SSR] ${pathname} - about to return response: ${(performance.now() - t0).toFixed(2)}ms`);
7338
+ const returnValue = response;
7339
+ if (debug)
7340
+ console.log(`[SSR] ${pathname} - response returned: ${(performance.now() - t0).toFixed(2)}ms (return overhead: ${(performance.now() - tBeforeReturn).toFixed(2)}ms)`);
7341
+ return returnValue;
7342
+ });
7094
7343
  };
7095
7344
  const allRoutes = [...staticRoutes, ...contentRoutes, ...dynamicRoutes];
7096
7345
  for (const path2 of allRoutes) {
@@ -7101,12 +7350,19 @@ function registerSSRRoutes(app, options) {
7101
7350
 
7102
7351
  // packages/elysia/src/routes/static.ts
7103
7352
  init_core();
7353
+ import { trace as trace5 } from "@opentelemetry/api";
7104
7354
  import { NotFoundError as NotFoundError12 } from "elysia";
7105
- function getOtelUtilities3() {
7355
+ var otelAvailable4;
7356
+ function isOtelAvailable4() {
7357
+ if (otelAvailable4 !== undefined)
7358
+ return otelAvailable4;
7106
7359
  try {
7107
- return __require("@elysiajs/opentelemetry");
7360
+ __require("@opentelemetry/api");
7361
+ otelAvailable4 = true;
7362
+ return true;
7108
7363
  } catch {
7109
- return null;
7364
+ otelAvailable4 = false;
7365
+ return false;
7110
7366
  }
7111
7367
  }
7112
7368
  function registerStaticRoutes(app, options) {
@@ -7123,21 +7379,18 @@ function registerStaticRoutes(app, options) {
7123
7379
  compression: compression2 = true
7124
7380
  } = options;
7125
7381
  function setOtelAttributes(statusCode, cachHit, requestPath, encoding, reason) {
7126
- const otel = getOtelUtilities3();
7127
- const currentSpan = otel?.getCurrentSpan();
7382
+ if (!isOtelAvailable4())
7383
+ return;
7384
+ const currentSpan = trace5.getActiveSpan();
7128
7385
  const attrs = {
7129
- "http.request.method": "GET",
7130
- "http.response.status_code": statusCode,
7131
7386
  "reroute.static.path": requestPath
7132
7387
  };
7133
7388
  if (statusCode === 200) {
7134
- attrs["reroute.static.cache_hit"] = cachHit;
7389
+ attrs["reroute.cache.hit"] = cachHit;
7135
7390
  if (encoding)
7136
- attrs["reroute.static.encoding"] = encoding;
7137
- } else if (statusCode === 404) {
7138
- attrs["reroute.static.not_found"] = true;
7139
- if (reason)
7140
- attrs["reroute.static.reason"] = reason;
7391
+ attrs["reroute.encoding"] = encoding;
7392
+ } else if (reason) {
7393
+ attrs["reroute.error.reason"] = reason;
7141
7394
  }
7142
7395
  currentSpan?.setAttributes(attrs);
7143
7396
  }
@@ -7188,31 +7441,25 @@ function registerStaticRoutes(app, options) {
7188
7441
  }
7189
7442
  });
7190
7443
  fileCache.set(cacheKey, response);
7191
- const otel = getOtelUtilities3();
7192
- const currentSpan = otel?.getCurrentSpan();
7193
- currentSpan?.setAttributes({
7194
- "http.request.method": "GET",
7195
- "http.response.status_code": 200,
7196
- "reroute.static.served": true,
7197
- "reroute.static.path": requestPath,
7198
- "reroute.static.content_type": contentType,
7199
- "reroute.static.cache_hit": false,
7200
- "reroute.static.compressed": !!extraHeaders["Content-Encoding"]
7201
- });
7444
+ if (isOtelAvailable4()) {
7445
+ const currentSpan = trace5.getActiveSpan();
7446
+ currentSpan?.setAttributes({
7447
+ "reroute.static.path": requestPath,
7448
+ "reroute.content.type": contentType,
7449
+ "reroute.cache.hit": false,
7450
+ "reroute.compressed": !!extraHeaders["Content-Encoding"]
7451
+ });
7452
+ }
7202
7453
  return response.clone();
7203
7454
  } catch (error) {
7204
7455
  if (error instanceof NotFoundError12) {
7205
7456
  throw error;
7206
7457
  }
7207
7458
  console.error(`[reroute] Error serving ${filePath}:`, error);
7208
- const otel = getOtelUtilities3();
7209
- const currentSpan = otel?.getCurrentSpan();
7210
- currentSpan?.setAttributes({
7211
- "http.request.method": "GET",
7212
- "http.response.status_code": 500,
7213
- "reroute.static.error": true,
7214
- "reroute.static.path": requestPath
7215
- });
7459
+ if (isOtelAvailable4()) {
7460
+ const currentSpan = trace5.getActiveSpan();
7461
+ currentSpan?.setAttribute("reroute.static.path", requestPath);
7462
+ }
7216
7463
  throw new NotFoundError12;
7217
7464
  }
7218
7465
  });
@@ -7567,4 +7814,4 @@ export {
7567
7814
  reroute
7568
7815
  };
7569
7816
 
7570
- //# debugId=435341DAA645AB5564756E2164756E21
7817
+ //# debugId=2F8AA864C3640F9564756E2164756E21