@segmentstream-cloud/app 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -698,6 +698,34 @@ Replace segmentstream.semantic with typed warehouse-backed entity aggregates. Se
698
698
  deployed with `@segmentstream-cloud/ontology` 0.17.0 or later. Requests that use none of
699
699
  them work as before.
700
700
 
701
+ ## Request timing
702
+
703
+ Wrap app Route Handlers to add `Server-Timing: app;dur=…`, `x-request-id` and safe
704
+ structured `app.request` runtime logs:
705
+
706
+ ```ts
707
+ import { withRequestTiming } from "@segmentstream-cloud/app";
708
+
709
+ export const GET = withRequestTiming(async (request: Request) => {
710
+ return Response.json({ ok: true });
711
+ });
712
+ ```
713
+
714
+ The wrapper passes handler arguments through and preserves response headers and
715
+ streaming bodies. It logs duration, method, HTTP status and a generated request ID,
716
+ excluding URLs, cookies, bodies and error details. Errors propagate unchanged.
717
+ Next.js redirects and `notFound()` log their HTTP status and propagate unchanged;
718
+ other Next.js control-flow exceptions log `status: null` because Next owns their eventual response.
719
+ Those exceptions cannot receive timing headers here;
720
+ return an explicit response when the wrapper needs to decorate its headers.
721
+ Read these logs with `segmentstream logs --service app` (deployment permission required).
722
+ Duration ends when the handler returns response headers; it excludes later stream
723
+ work and browser rendering. It is opt-in for Route Handlers, not a page renderer
724
+ or a web vitals collector. A Next.js proxy cannot time the downstream page render.
725
+
726
+ Ontology SDK 0.31.2 adds request timing for ontology calls automatically. Timings
727
+ are available in hosted logs; retained diagnostics are tracked in issue #520.
728
+
701
729
  ## Upgrading to 0.14
702
730
 
703
731
  - `segmentstream.ontology.aggregate()` accepts the measures of the model by their bare names, typed
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export declare function createSegmentStreamApp<O = unknown>(config: SegmentStrea
18
18
  export { NOT_INVITED, SIGN_IN_LINK_INVALID, SegmentStreamApiError } from "./errors.js";
19
19
  export { grants, isAllowed } from "./permissions.js";
20
20
  export { sql } from "./parameters.js";
21
+ export { withRequestTiming } from "./request-timing.js";
21
22
  export type { AuthenticationMethod, SegmentStreamApp } from "./app.js";
22
23
  export { CONSENT_PAGE } from "./oauth.js";
23
24
  export { AGENT_CONNECT_HANDLER, AGENT_CONNECT_PAGE } from "./agent.js";
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ export function createSegmentStreamApp(config) {
19
19
  export { NOT_INVITED, SIGN_IN_LINK_INVALID, SegmentStreamApiError } from "./errors.js";
20
20
  export { grants, isAllowed } from "./permissions.js";
21
21
  export { sql } from "./parameters.js";
22
+ export { withRequestTiming } from "./request-timing.js";
22
23
  export { CONSENT_PAGE } from "./oauth.js";
23
24
  export { AGENT_CONNECT_HANDLER, AGENT_CONNECT_PAGE } from "./agent.js";
24
25
  export { createBlobStorageClient, } from "./storage.js";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Time an app Route Handler until it returns response headers. Streaming/rendering after that
3
+ * point is excluded. Logs contain no URL, cookies, body or error text. Server Components need
4
+ * framework instrumentation for complete page timing; a Next.js proxy only times authentication.
5
+ */
6
+ export declare function withRequestTiming<R extends Request, A extends unknown[]>(handler: (request: R, ...args: A) => Promise<Response>): (request: R, ...args: A) => Promise<Response>;
@@ -0,0 +1,53 @@
1
+ import { unstable_rethrow } from "next/navigation";
2
+ import { getRedirectStatusCodeFromError } from "next/dist/client/components/redirect.js";
3
+ import { isRedirectError } from "next/dist/client/components/redirect-error.js";
4
+ import { getAccessFallbackHTTPStatus, isHTTPAccessFallbackError, } from "next/dist/client/components/http-access-fallback/http-access-fallback.js";
5
+ /**
6
+ * Time an app Route Handler until it returns response headers. Streaming/rendering after that
7
+ * point is excluded. Logs contain no URL, cookies, body or error text. Server Components need
8
+ * framework instrumentation for complete page timing; a Next.js proxy only times authentication.
9
+ */
10
+ export function withRequestTiming(handler) {
11
+ return async (request, ...args) => {
12
+ const started = performance.now();
13
+ const requestId = crypto.randomUUID();
14
+ let status = 500;
15
+ let durationMs;
16
+ try {
17
+ const response = await handler(request, ...args);
18
+ const headers = new Headers(response.headers);
19
+ durationMs = Math.round((performance.now() - started) * 100) / 100;
20
+ status = response.status;
21
+ headers.append("server-timing", `app;dur=${durationMs}`);
22
+ headers.set("x-request-id", requestId);
23
+ return new Response(response.body, {
24
+ status,
25
+ statusText: response.statusText,
26
+ headers,
27
+ });
28
+ }
29
+ catch (error) {
30
+ try {
31
+ unstable_rethrow(error);
32
+ }
33
+ catch {
34
+ // Next owns the eventual response for control-flow exceptions, outside this wrapper.
35
+ status = isRedirectError(error)
36
+ ? getRedirectStatusCodeFromError(error)
37
+ : isHTTPAccessFallbackError(error)
38
+ ? getAccessFallbackHTTPStatus(error)
39
+ : null;
40
+ }
41
+ throw error;
42
+ }
43
+ finally {
44
+ console.info(JSON.stringify({
45
+ event: "app.request",
46
+ requestId,
47
+ method: request.method,
48
+ status,
49
+ durationMs: durationMs ?? Math.round((performance.now() - started) * 100) / 100,
50
+ }));
51
+ }
52
+ };
53
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream-cloud/app",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Sign-in, users, permissions, the ontology client and warehouse data access for SegmentStream workspace apps built with Next.js.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "SegmentStream",