@glasstrace/sdk 1.8.0 → 1.9.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/dist/async-context/index.cjs +15010 -0
- package/dist/async-context/index.cjs.map +1 -0
- package/dist/async-context/index.d.cts +174 -0
- package/dist/async-context/index.d.ts +174 -0
- package/dist/async-context/index.js +13 -0
- package/dist/{capture-error-Dzz7_-v4.d.ts → capture-error-BeuEXXJO.d.cts} +2 -2
- package/dist/{capture-error-C95zvSvF.d.cts → capture-error-D02pzB7q.d.ts} +2 -2
- package/dist/{chunk-JJL2M64Z.js → chunk-2F2MGFLO.js} +19 -10
- package/dist/chunk-2F2MGFLO.js.map +1 -0
- package/dist/chunk-CL3OVHPO.js +23 -0
- package/dist/chunk-CL3OVHPO.js.map +1 -0
- package/dist/{chunk-WL6BXEJ5.js → chunk-DKV53A2C.js} +2 -2
- package/dist/{chunk-3PJP5Y3U.js → chunk-GWIEUBFR.js} +3 -3
- package/dist/{chunk-H57MQGNU.js → chunk-H6WJ63X2.js} +2 -2
- package/dist/{chunk-NN5YCETI.js → chunk-HD6JIFKN.js} +2 -2
- package/dist/{chunk-P45NZR4J.js → chunk-JHUNLPSS.js} +35 -1
- package/dist/{chunk-P45NZR4J.js.map → chunk-JHUNLPSS.js.map} +1 -1
- package/dist/{chunk-UQKI476D.js → chunk-M6EWJCAT.js} +2 -2
- package/dist/chunk-QEXRCXSY.js +124 -0
- package/dist/chunk-QEXRCXSY.js.map +1 -0
- package/dist/chunk-QOHKZOKB.js +139 -0
- package/dist/chunk-QOHKZOKB.js.map +1 -0
- package/dist/{chunk-M2TLX6NM.js → chunk-QXITSNYM.js} +3 -3
- package/dist/cli/init.cjs +4 -4
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +7 -7
- package/dist/cli/mcp-add.cjs +1 -1
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +3 -3
- package/dist/cli/uninit.js +3 -3
- package/dist/cli/upgrade-instructions.cjs +1 -1
- package/dist/cli/upgrade-instructions.js +3 -3
- package/dist/cli/validate.cjs.map +1 -1
- package/dist/cli/validate.js +2 -2
- package/dist/{edge-entry-AWO70gje.d.ts → correlation-id-B_K8adD6.d.ts} +1 -1
- package/dist/{edge-entry-DaeG7D7S.d.cts → correlation-id-NAapJ5jn.d.cts} +1 -1
- package/dist/edge-entry.cjs +309 -26
- package/dist/edge-entry.cjs.map +1 -1
- package/dist/edge-entry.d.cts +5 -2
- package/dist/edge-entry.d.ts +5 -2
- package/dist/edge-entry.js +12 -3
- package/dist/index.cjs +55 -5
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-Dq33YwFT.d.cts → index.d-CkTf_boH.d.cts} +1 -1
- package/dist/{index.d-Dq33YwFT.d.ts → index.d-CkTf_boH.d.ts} +1 -1
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/middleware/index.cjs +15023 -0
- package/dist/middleware/index.cjs.map +1 -0
- package/dist/middleware/index.d.cts +191 -0
- package/dist/middleware/index.d.ts +191 -0
- package/dist/middleware/index.js +13 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/node-entry.cjs +55 -5
- package/dist/node-entry.cjs.map +1 -1
- package/dist/node-entry.d.cts +3 -3
- package/dist/node-entry.d.ts +3 -3
- package/dist/node-entry.js +8 -7
- package/dist/node-subpath.cjs.map +1 -1
- package/dist/node-subpath.d.cts +1 -1
- package/dist/node-subpath.d.ts +1 -1
- package/dist/node-subpath.js +3 -3
- package/dist/{source-map-uploader-XFUEVV7I.js → source-map-uploader-MMJ2WCL4.js} +3 -3
- package/dist/source-map-uploader-MMJ2WCL4.js.map +1 -0
- package/package.json +13 -1
- package/dist/chunk-JJL2M64Z.js.map +0 -1
- /package/dist/{source-map-uploader-XFUEVV7I.js.map → async-context/index.js.map} +0 -0
- /package/dist/{chunk-WL6BXEJ5.js.map → chunk-DKV53A2C.js.map} +0 -0
- /package/dist/{chunk-3PJP5Y3U.js.map → chunk-GWIEUBFR.js.map} +0 -0
- /package/dist/{chunk-H57MQGNU.js.map → chunk-H6WJ63X2.js.map} +0 -0
- /package/dist/{chunk-NN5YCETI.js.map → chunk-HD6JIFKN.js.map} +0 -0
- /package/dist/{chunk-UQKI476D.js.map → chunk-M6EWJCAT.js.map} +0 -0
- /package/dist/{chunk-M2TLX6NM.js.map → chunk-QXITSNYM.js.map} +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { AttributeValue } from './common/Attributes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-response async causality instrumentation for Glasstrace.
|
|
5
|
+
*
|
|
6
|
+
* Subpath: `@glasstrace/sdk/async-context`
|
|
7
|
+
*
|
|
8
|
+
* This module exposes {@link withAsyncCausality}, a continuation-
|
|
9
|
+
* passing wrapper that captures the active OTel `SpanContext` at call
|
|
10
|
+
* time and binds it to a callback. When the callback runs later
|
|
11
|
+
* (Next.js `after()`, queue dispatchers, webhook fire-and-forget),
|
|
12
|
+
* the wrapper opens a span linked to the originating trace via two
|
|
13
|
+
* channels:
|
|
14
|
+
*
|
|
15
|
+
* - An OTel `Link` to the captured `SpanContext` — the OTel-native
|
|
16
|
+
* pointer between two spans in different traces. Surfaces in
|
|
17
|
+
* standard OTel-aware UIs (Jaeger, Honeycomb, etc.) as a
|
|
18
|
+
* "follows from" relationship.
|
|
19
|
+
* - A `glasstrace.causal.post_response_async` attribute carrying
|
|
20
|
+
* the captured trace ID (32-char hex). Used by the product-side
|
|
21
|
+
* trace-summary transform (per DISC-1539's product handoff) to
|
|
22
|
+
* reconstruct ownership without resolving the Link. Two
|
|
23
|
+
* companion booleans
|
|
24
|
+
* (`glasstrace.causal.affects_http_status` and
|
|
25
|
+
* `glasstrace.causal.affects_http_duration`) document that the
|
|
26
|
+
* async work does NOT participate in the root request's outcome.
|
|
27
|
+
*
|
|
28
|
+
* Both channels are emitted together so the SDK is robust to
|
|
29
|
+
* downstream transforms that resolve causality through either form.
|
|
30
|
+
*
|
|
31
|
+
* Edge-runtime safety
|
|
32
|
+
* -------------------
|
|
33
|
+
* The wrapper is included in the SDK's edge bundle
|
|
34
|
+
* (`packages/sdk/src/edge-entry.ts`). Its closure imports only the
|
|
35
|
+
* OTel API, the protocol constants, and the
|
|
36
|
+
* `./optional-lifecycle.js` bridge — none of which reach into
|
|
37
|
+
* `node:*` built-ins or the `process` global. The F003 closure scan
|
|
38
|
+
* (`packages/sdk/scripts/check-edge-bundle.mjs`) enforces this on
|
|
39
|
+
* every build.
|
|
40
|
+
*
|
|
41
|
+
* Strategy: continuation-passing, NOT global ALS propagation
|
|
42
|
+
* ---------------------------------------------------------
|
|
43
|
+
* Per the SDK-046 brief §2.3: ALS continuity across Next.js `after()`
|
|
44
|
+
* is uncertain (the framework may schedule via `queueMicrotask`
|
|
45
|
+
* (preserves ALS) or via cross-tick scheduling (drops ALS)). Relying
|
|
46
|
+
* on ALS would couple the SDK to Next internals. Continuation-passing
|
|
47
|
+
* makes the causality explicit — the user wraps the callback they
|
|
48
|
+
* pass to `after()` / their queue, and the captured `SpanContext`
|
|
49
|
+
* travels with the closure regardless of how the framework schedules
|
|
50
|
+
* it.
|
|
51
|
+
*
|
|
52
|
+
* @module @glasstrace/sdk/async-context
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* INTERNAL — clears once-flags for unit tests; not part of the
|
|
57
|
+
* public surface.
|
|
58
|
+
*/
|
|
59
|
+
declare function _resetForTesting(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Options for {@link withAsyncCausality}.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { withAsyncCausality } from "@glasstrace/sdk/async-context";
|
|
66
|
+
* import { after } from "next/server";
|
|
67
|
+
*
|
|
68
|
+
* export async function POST(req: Request) {
|
|
69
|
+
* const result = await processRequest(req);
|
|
70
|
+
* after(
|
|
71
|
+
* withAsyncCausality(
|
|
72
|
+
* { name: "send-confirmation-email" },
|
|
73
|
+
* async () => sendEmail(result.userId),
|
|
74
|
+
* ),
|
|
75
|
+
* );
|
|
76
|
+
* return Response.json({ ok: true });
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
interface WithAsyncCausalityOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Span name for the async work. Required, non-empty string. Used as
|
|
83
|
+
* the OTel span name and appears in trace timelines. Names should
|
|
84
|
+
* be stable across runs (e.g., "send-confirmation-email",
|
|
85
|
+
* "enqueue-webhook-dispatch"); avoid embedding payload data in the
|
|
86
|
+
* name.
|
|
87
|
+
*/
|
|
88
|
+
name: string;
|
|
89
|
+
/**
|
|
90
|
+
* Optional attributes attached to the span before the wrapped
|
|
91
|
+
* callback runs. Forwarded to OTel as-is via `span.setAttributes()`.
|
|
92
|
+
* The SDK does not redact, sanitize, or scan values here — callers
|
|
93
|
+
* MUST avoid placing tokens, credentials, or other sensitive data
|
|
94
|
+
* in `attributes`.
|
|
95
|
+
*/
|
|
96
|
+
attributes?: Record<string, AttributeValue>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Capture the active OTel `SpanContext` at call time, bind it to a
|
|
100
|
+
* callback, and return a continuation that will emit a
|
|
101
|
+
* causally-linked span when invoked.
|
|
102
|
+
*
|
|
103
|
+
* The returned continuation:
|
|
104
|
+
*
|
|
105
|
+
* 1. Detects the SDK's registration state. When the OTel API is
|
|
106
|
+
* still on the noop tracer, runs the wrapped callback directly
|
|
107
|
+
* and emits an `async:skipped_uninstalled` lifecycle event (at
|
|
108
|
+
* most once per process). No span is opened.
|
|
109
|
+
* 2. Otherwise opens a span named `options.name` as a NEW root
|
|
110
|
+
* span (not parented to the captured context — `after()` /
|
|
111
|
+
* queue dispatchers run outside the originating request's OTel
|
|
112
|
+
* context, so the async work belongs to a separate trace).
|
|
113
|
+
* 3. When a captured `SpanContext` exists with a valid trace ID,
|
|
114
|
+
* attaches:
|
|
115
|
+
* - an OTel `Link` to that `SpanContext` (the OTel-native
|
|
116
|
+
* form),
|
|
117
|
+
* - the `glasstrace.causal.post_response_async` attribute
|
|
118
|
+
* carrying the trace ID (the transform-readable form),
|
|
119
|
+
* - `glasstrace.causal.affects_http_status = false` and
|
|
120
|
+
* `glasstrace.causal.affects_http_duration = false`
|
|
121
|
+
* documenting that the async work does NOT participate in
|
|
122
|
+
* the root request's outcome.
|
|
123
|
+
* When no valid `SpanContext` was captured, none of these are
|
|
124
|
+
* emitted (per SDK-046's "missing or unknown evidence is
|
|
125
|
+
* preferable to guessed evidence" rule) and an
|
|
126
|
+
* `async:no_originating_context` lifecycle event fires (at
|
|
127
|
+
* most once per process).
|
|
128
|
+
* 4. Awaits the wrapped callback.
|
|
129
|
+
* 5. On a thrown error: normalizes the throwable; sets `ERROR`
|
|
130
|
+
* status with `recordException`; rethrows the original error
|
|
131
|
+
* verbatim.
|
|
132
|
+
* 6. On a successful return: leaves status `UNSET`.
|
|
133
|
+
* 7. Always ends the span.
|
|
134
|
+
*
|
|
135
|
+
* The continuation returns a Promise resolving to the callback's
|
|
136
|
+
* return value (Promise-or-value semantics: a sync callback's value
|
|
137
|
+
* is wrapped in `Promise.resolve()`).
|
|
138
|
+
*
|
|
139
|
+
* @param options - Span name and optional pre-start attributes.
|
|
140
|
+
* @param fn - The async callback to run later. May be sync or async;
|
|
141
|
+
* the wrapper always returns a Promise to give a consistent
|
|
142
|
+
* continuation shape regardless of `fn`'s synchronicity.
|
|
143
|
+
* @returns A continuation `() => Promise<T>` that, when invoked,
|
|
144
|
+
* emits the causally-linked span and runs `fn`.
|
|
145
|
+
*
|
|
146
|
+
* @example Next.js after() — typical use
|
|
147
|
+
* ```ts
|
|
148
|
+
* import { withAsyncCausality } from "@glasstrace/sdk/async-context";
|
|
149
|
+
* import { after } from "next/server";
|
|
150
|
+
*
|
|
151
|
+
* export async function POST(req: Request) {
|
|
152
|
+
* const result = await processRequest(req);
|
|
153
|
+
* after(
|
|
154
|
+
* withAsyncCausality(
|
|
155
|
+
* { name: "send-confirmation-email" },
|
|
156
|
+
* async () => sendEmail(result.userId),
|
|
157
|
+
* ),
|
|
158
|
+
* );
|
|
159
|
+
* return Response.json({ ok: true });
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @example Queue dispatcher — capture before enqueue
|
|
164
|
+
* ```ts
|
|
165
|
+
* const dispatch = withAsyncCausality(
|
|
166
|
+
* { name: "process-webhook" },
|
|
167
|
+
* async () => handler(payload),
|
|
168
|
+
* );
|
|
169
|
+
* await queue.enqueue(dispatch);
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
declare function withAsyncCausality<T>(options: WithAsyncCausalityOptions, fn: () => Promise<T> | T): () => Promise<T>;
|
|
173
|
+
|
|
174
|
+
export { type WithAsyncCausalityOptions, _resetForTesting, withAsyncCausality };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { AttributeValue } from './common/Attributes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-response async causality instrumentation for Glasstrace.
|
|
5
|
+
*
|
|
6
|
+
* Subpath: `@glasstrace/sdk/async-context`
|
|
7
|
+
*
|
|
8
|
+
* This module exposes {@link withAsyncCausality}, a continuation-
|
|
9
|
+
* passing wrapper that captures the active OTel `SpanContext` at call
|
|
10
|
+
* time and binds it to a callback. When the callback runs later
|
|
11
|
+
* (Next.js `after()`, queue dispatchers, webhook fire-and-forget),
|
|
12
|
+
* the wrapper opens a span linked to the originating trace via two
|
|
13
|
+
* channels:
|
|
14
|
+
*
|
|
15
|
+
* - An OTel `Link` to the captured `SpanContext` — the OTel-native
|
|
16
|
+
* pointer between two spans in different traces. Surfaces in
|
|
17
|
+
* standard OTel-aware UIs (Jaeger, Honeycomb, etc.) as a
|
|
18
|
+
* "follows from" relationship.
|
|
19
|
+
* - A `glasstrace.causal.post_response_async` attribute carrying
|
|
20
|
+
* the captured trace ID (32-char hex). Used by the product-side
|
|
21
|
+
* trace-summary transform (per DISC-1539's product handoff) to
|
|
22
|
+
* reconstruct ownership without resolving the Link. Two
|
|
23
|
+
* companion booleans
|
|
24
|
+
* (`glasstrace.causal.affects_http_status` and
|
|
25
|
+
* `glasstrace.causal.affects_http_duration`) document that the
|
|
26
|
+
* async work does NOT participate in the root request's outcome.
|
|
27
|
+
*
|
|
28
|
+
* Both channels are emitted together so the SDK is robust to
|
|
29
|
+
* downstream transforms that resolve causality through either form.
|
|
30
|
+
*
|
|
31
|
+
* Edge-runtime safety
|
|
32
|
+
* -------------------
|
|
33
|
+
* The wrapper is included in the SDK's edge bundle
|
|
34
|
+
* (`packages/sdk/src/edge-entry.ts`). Its closure imports only the
|
|
35
|
+
* OTel API, the protocol constants, and the
|
|
36
|
+
* `./optional-lifecycle.js` bridge — none of which reach into
|
|
37
|
+
* `node:*` built-ins or the `process` global. The F003 closure scan
|
|
38
|
+
* (`packages/sdk/scripts/check-edge-bundle.mjs`) enforces this on
|
|
39
|
+
* every build.
|
|
40
|
+
*
|
|
41
|
+
* Strategy: continuation-passing, NOT global ALS propagation
|
|
42
|
+
* ---------------------------------------------------------
|
|
43
|
+
* Per the SDK-046 brief §2.3: ALS continuity across Next.js `after()`
|
|
44
|
+
* is uncertain (the framework may schedule via `queueMicrotask`
|
|
45
|
+
* (preserves ALS) or via cross-tick scheduling (drops ALS)). Relying
|
|
46
|
+
* on ALS would couple the SDK to Next internals. Continuation-passing
|
|
47
|
+
* makes the causality explicit — the user wraps the callback they
|
|
48
|
+
* pass to `after()` / their queue, and the captured `SpanContext`
|
|
49
|
+
* travels with the closure regardless of how the framework schedules
|
|
50
|
+
* it.
|
|
51
|
+
*
|
|
52
|
+
* @module @glasstrace/sdk/async-context
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* INTERNAL — clears once-flags for unit tests; not part of the
|
|
57
|
+
* public surface.
|
|
58
|
+
*/
|
|
59
|
+
declare function _resetForTesting(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Options for {@link withAsyncCausality}.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { withAsyncCausality } from "@glasstrace/sdk/async-context";
|
|
66
|
+
* import { after } from "next/server";
|
|
67
|
+
*
|
|
68
|
+
* export async function POST(req: Request) {
|
|
69
|
+
* const result = await processRequest(req);
|
|
70
|
+
* after(
|
|
71
|
+
* withAsyncCausality(
|
|
72
|
+
* { name: "send-confirmation-email" },
|
|
73
|
+
* async () => sendEmail(result.userId),
|
|
74
|
+
* ),
|
|
75
|
+
* );
|
|
76
|
+
* return Response.json({ ok: true });
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
interface WithAsyncCausalityOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Span name for the async work. Required, non-empty string. Used as
|
|
83
|
+
* the OTel span name and appears in trace timelines. Names should
|
|
84
|
+
* be stable across runs (e.g., "send-confirmation-email",
|
|
85
|
+
* "enqueue-webhook-dispatch"); avoid embedding payload data in the
|
|
86
|
+
* name.
|
|
87
|
+
*/
|
|
88
|
+
name: string;
|
|
89
|
+
/**
|
|
90
|
+
* Optional attributes attached to the span before the wrapped
|
|
91
|
+
* callback runs. Forwarded to OTel as-is via `span.setAttributes()`.
|
|
92
|
+
* The SDK does not redact, sanitize, or scan values here — callers
|
|
93
|
+
* MUST avoid placing tokens, credentials, or other sensitive data
|
|
94
|
+
* in `attributes`.
|
|
95
|
+
*/
|
|
96
|
+
attributes?: Record<string, AttributeValue>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Capture the active OTel `SpanContext` at call time, bind it to a
|
|
100
|
+
* callback, and return a continuation that will emit a
|
|
101
|
+
* causally-linked span when invoked.
|
|
102
|
+
*
|
|
103
|
+
* The returned continuation:
|
|
104
|
+
*
|
|
105
|
+
* 1. Detects the SDK's registration state. When the OTel API is
|
|
106
|
+
* still on the noop tracer, runs the wrapped callback directly
|
|
107
|
+
* and emits an `async:skipped_uninstalled` lifecycle event (at
|
|
108
|
+
* most once per process). No span is opened.
|
|
109
|
+
* 2. Otherwise opens a span named `options.name` as a NEW root
|
|
110
|
+
* span (not parented to the captured context — `after()` /
|
|
111
|
+
* queue dispatchers run outside the originating request's OTel
|
|
112
|
+
* context, so the async work belongs to a separate trace).
|
|
113
|
+
* 3. When a captured `SpanContext` exists with a valid trace ID,
|
|
114
|
+
* attaches:
|
|
115
|
+
* - an OTel `Link` to that `SpanContext` (the OTel-native
|
|
116
|
+
* form),
|
|
117
|
+
* - the `glasstrace.causal.post_response_async` attribute
|
|
118
|
+
* carrying the trace ID (the transform-readable form),
|
|
119
|
+
* - `glasstrace.causal.affects_http_status = false` and
|
|
120
|
+
* `glasstrace.causal.affects_http_duration = false`
|
|
121
|
+
* documenting that the async work does NOT participate in
|
|
122
|
+
* the root request's outcome.
|
|
123
|
+
* When no valid `SpanContext` was captured, none of these are
|
|
124
|
+
* emitted (per SDK-046's "missing or unknown evidence is
|
|
125
|
+
* preferable to guessed evidence" rule) and an
|
|
126
|
+
* `async:no_originating_context` lifecycle event fires (at
|
|
127
|
+
* most once per process).
|
|
128
|
+
* 4. Awaits the wrapped callback.
|
|
129
|
+
* 5. On a thrown error: normalizes the throwable; sets `ERROR`
|
|
130
|
+
* status with `recordException`; rethrows the original error
|
|
131
|
+
* verbatim.
|
|
132
|
+
* 6. On a successful return: leaves status `UNSET`.
|
|
133
|
+
* 7. Always ends the span.
|
|
134
|
+
*
|
|
135
|
+
* The continuation returns a Promise resolving to the callback's
|
|
136
|
+
* return value (Promise-or-value semantics: a sync callback's value
|
|
137
|
+
* is wrapped in `Promise.resolve()`).
|
|
138
|
+
*
|
|
139
|
+
* @param options - Span name and optional pre-start attributes.
|
|
140
|
+
* @param fn - The async callback to run later. May be sync or async;
|
|
141
|
+
* the wrapper always returns a Promise to give a consistent
|
|
142
|
+
* continuation shape regardless of `fn`'s synchronicity.
|
|
143
|
+
* @returns A continuation `() => Promise<T>` that, when invoked,
|
|
144
|
+
* emits the causally-linked span and runs `fn`.
|
|
145
|
+
*
|
|
146
|
+
* @example Next.js after() — typical use
|
|
147
|
+
* ```ts
|
|
148
|
+
* import { withAsyncCausality } from "@glasstrace/sdk/async-context";
|
|
149
|
+
* import { after } from "next/server";
|
|
150
|
+
*
|
|
151
|
+
* export async function POST(req: Request) {
|
|
152
|
+
* const result = await processRequest(req);
|
|
153
|
+
* after(
|
|
154
|
+
* withAsyncCausality(
|
|
155
|
+
* { name: "send-confirmation-email" },
|
|
156
|
+
* async () => sendEmail(result.userId),
|
|
157
|
+
* ),
|
|
158
|
+
* );
|
|
159
|
+
* return Response.json({ ok: true });
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @example Queue dispatcher — capture before enqueue
|
|
164
|
+
* ```ts
|
|
165
|
+
* const dispatch = withAsyncCausality(
|
|
166
|
+
* { name: "process-webhook" },
|
|
167
|
+
* async () => handler(payload),
|
|
168
|
+
* );
|
|
169
|
+
* await queue.enqueue(dispatch);
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
declare function withAsyncCausality<T>(options: WithAsyncCausalityOptions, fn: () => Promise<T> | T): () => Promise<T>;
|
|
173
|
+
|
|
174
|
+
export { type WithAsyncCausalityOptions, _resetForTesting, withAsyncCausality };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_resetForTesting,
|
|
3
|
+
withAsyncCausality
|
|
4
|
+
} from "../chunk-QEXRCXSY.js";
|
|
5
|
+
import "../chunk-CL3OVHPO.js";
|
|
6
|
+
import "../chunk-DQ25VOKK.js";
|
|
7
|
+
import "../chunk-JHUNLPSS.js";
|
|
8
|
+
import "../chunk-NSBPE2FW.js";
|
|
9
|
+
export {
|
|
10
|
+
_resetForTesting,
|
|
11
|
+
withAsyncCausality
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { G as GlasstraceEnvVars,
|
|
1
|
+
import { G as GlasstraceEnvVars, h as GlasstraceOptions, A as AnonApiKey, i as SdkInitResponse, C as CaptureConfig, j as SdkHealthReport, I as ImportGraphPayload, f as SdkDiagnosticCode } from './index.d-CkTf_boH.cjs';
|
|
2
2
|
import { ReadableSpan } from './export/ReadableSpan';
|
|
3
3
|
import { SpanExporter } from './export/SpanExporter';
|
|
4
4
|
import { ExportResult } from './ExportResult';
|
|
5
|
-
import { a as SessionManager } from './
|
|
5
|
+
import { a as SessionManager } from './correlation-id-NAapJ5jn.cjs';
|
|
6
6
|
import { SpanProcessor } from './SpanProcessor';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { G as GlasstraceEnvVars,
|
|
1
|
+
import { G as GlasstraceEnvVars, h as GlasstraceOptions, A as AnonApiKey, i as SdkInitResponse, C as CaptureConfig, j as SdkHealthReport, I as ImportGraphPayload, f as SdkDiagnosticCode } from './index.d-CkTf_boH.js';
|
|
2
2
|
import { ReadableSpan } from './export/ReadableSpan';
|
|
3
3
|
import { SpanExporter } from './export/SpanExporter';
|
|
4
4
|
import { ExportResult } from './ExportResult';
|
|
5
|
-
import { a as SessionManager } from './
|
|
5
|
+
import { a as SessionManager } from './correlation-id-B_K8adD6.js';
|
|
6
6
|
import { SpanProcessor } from './SpanProcessor';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_registerLifecycleEmitForBridge
|
|
3
|
+
} from "./chunk-CL3OVHPO.js";
|
|
1
4
|
import {
|
|
2
5
|
DiagLogLevel,
|
|
3
6
|
INVALID_SPAN_CONTEXT,
|
|
@@ -33,7 +36,7 @@ import {
|
|
|
33
36
|
performInit,
|
|
34
37
|
recordSpansDropped,
|
|
35
38
|
recordSpansExported
|
|
36
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-QXITSNYM.js";
|
|
37
40
|
import {
|
|
38
41
|
isAnonymousMode,
|
|
39
42
|
isProductionDisabled,
|
|
@@ -44,11 +47,11 @@ import {
|
|
|
44
47
|
getOrCreateAnonKey,
|
|
45
48
|
isSyncFsAvailable,
|
|
46
49
|
readAnonKey
|
|
47
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-DKV53A2C.js";
|
|
48
51
|
import {
|
|
49
52
|
GLASSTRACE_ATTRIBUTE_NAMES,
|
|
50
53
|
deriveSessionId
|
|
51
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-JHUNLPSS.js";
|
|
52
55
|
import {
|
|
53
56
|
isEndMarkerLine,
|
|
54
57
|
parseStartMarkerLine
|
|
@@ -249,6 +252,12 @@ function initLifecycle(options) {
|
|
|
249
252
|
}
|
|
250
253
|
_logger = options.logger;
|
|
251
254
|
_initialized = true;
|
|
255
|
+
_registerLifecycleEmitForBridge((event, payload) => {
|
|
256
|
+
emitLifecycleEvent(
|
|
257
|
+
event,
|
|
258
|
+
payload
|
|
259
|
+
);
|
|
260
|
+
});
|
|
252
261
|
}
|
|
253
262
|
function warnIfNotInitialized() {
|
|
254
263
|
if (!_initialized && !_initWarned) {
|
|
@@ -4968,11 +4977,11 @@ function registerGlasstrace(options) {
|
|
|
4968
4977
|
setCoreState(CoreState.REGISTERING);
|
|
4969
4978
|
maybeWarnStaleAgentInstructions({
|
|
4970
4979
|
projectRoot: process.cwd(),
|
|
4971
|
-
sdkVersion: "1.
|
|
4980
|
+
sdkVersion: "1.9.1"
|
|
4972
4981
|
});
|
|
4973
4982
|
startRuntimeStateWriter({
|
|
4974
4983
|
projectRoot: process.cwd(),
|
|
4975
|
-
sdkVersion: "1.
|
|
4984
|
+
sdkVersion: "1.9.1"
|
|
4976
4985
|
});
|
|
4977
4986
|
const config = resolveConfig(options);
|
|
4978
4987
|
if (config.verbose) {
|
|
@@ -5139,8 +5148,8 @@ async function backgroundInit(config, anonKeyForInit, generation) {
|
|
|
5139
5148
|
if (config.verbose) {
|
|
5140
5149
|
console.info("[glasstrace] Background init firing.");
|
|
5141
5150
|
}
|
|
5142
|
-
const healthReport = collectHealthReport("1.
|
|
5143
|
-
const initResult = await performInit(config, anonKeyForInit, "1.
|
|
5151
|
+
const healthReport = collectHealthReport("1.9.1");
|
|
5152
|
+
const initResult = await performInit(config, anonKeyForInit, "1.9.1", healthReport);
|
|
5144
5153
|
if (generation !== registrationGeneration) return;
|
|
5145
5154
|
const currentState = getCoreState();
|
|
5146
5155
|
if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
|
|
@@ -5163,7 +5172,7 @@ async function backgroundInit(config, anonKeyForInit, generation) {
|
|
|
5163
5172
|
}
|
|
5164
5173
|
maybeInstallConsoleCapture();
|
|
5165
5174
|
if (didLastInitSucceed()) {
|
|
5166
|
-
startHeartbeat(config, anonKeyForInit, "1.
|
|
5175
|
+
startHeartbeat(config, anonKeyForInit, "1.9.1", generation, (newApiKey, accountId) => {
|
|
5167
5176
|
setAuthState(AuthState.CLAIMING);
|
|
5168
5177
|
emitLifecycleEvent("auth:claim_started", { accountId });
|
|
5169
5178
|
setResolvedApiKey(newApiKey);
|
|
@@ -5460,7 +5469,7 @@ async function handleSourceMapUpload(distDir) {
|
|
|
5460
5469
|
);
|
|
5461
5470
|
return;
|
|
5462
5471
|
}
|
|
5463
|
-
const { discoverSourceMapFiles, computeBuildHash, uploadSourceMaps } = await import("./source-map-uploader-
|
|
5472
|
+
const { discoverSourceMapFiles, computeBuildHash, uploadSourceMaps } = await import("./source-map-uploader-MMJ2WCL4.js");
|
|
5464
5473
|
const files = await discoverSourceMapFiles(distDir);
|
|
5465
5474
|
if (files.length === 0) {
|
|
5466
5475
|
console.info("[glasstrace] No source map files found. Skipping upload.");
|
|
@@ -5563,4 +5572,4 @@ export {
|
|
|
5563
5572
|
withGlasstraceConfig,
|
|
5564
5573
|
captureError
|
|
5565
5574
|
};
|
|
5566
|
-
//# sourceMappingURL=chunk-
|
|
5575
|
+
//# sourceMappingURL=chunk-2F2MGFLO.js.map
|