lambda-deadline-middleware 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -23
- package/dist/context-store.d.ts.map +1 -1
- package/dist/context-store.js +4 -12
- package/dist/context-store.js.map +1 -1
- package/dist/error.d.ts +3 -3
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/handler-wrapper.d.ts +4 -3
- package/dist/handler-wrapper.d.ts.map +1 -1
- package/dist/handler-wrapper.js +1 -1
- package/dist/handler-wrapper.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +4 -10
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +39 -53
- package/dist/middleware.js.map +1 -1
- package/dist/types.d.ts +0 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -10
- package/dist/types.js.map +1 -1
- package/package.json +4 -4
- package/src/context-store.ts +5 -19
- package/src/error.ts +3 -3
- package/src/handler-wrapper.ts +7 -8
- package/src/index.ts +2 -9
- package/src/middleware.ts +72 -87
- package/src/types.ts +2 -32
- package/dist/config.d.ts +0 -4
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -17
- package/dist/config.js.map +0 -1
- package/dist/registration.d.ts +0 -8
- package/dist/registration.d.ts.map +0 -1
- package/dist/registration.js +0 -17
- package/dist/registration.js.map +0 -1
- package/dist/telemetry.d.ts +0 -5
- package/dist/telemetry.d.ts.map +0 -1
- package/dist/telemetry.js +0 -82
- package/dist/telemetry.js.map +0 -1
- package/src/config.ts +0 -18
- package/src/registration.ts +0 -27
- package/src/telemetry.ts +0 -132
package/src/telemetry.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// SPDX-FileCopyrightText: 2026 lambda-deadline-middleware contributors
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
import type { DeadlineExceededError } from "./error.js";
|
|
5
|
-
import type { DeadlineMiddlewareConfig } from "./types.js";
|
|
6
|
-
|
|
7
|
-
// OpenTelemetry is detected dynamically rather than declared as a peerDependency.
|
|
8
|
-
// This avoids forcing all consumers to install @opentelemetry/api or suppress peer warnings.
|
|
9
|
-
// Detection happens once at first use and the result is cached for the process lifetime.
|
|
10
|
-
interface AbortDetails {
|
|
11
|
-
readonly deadlineMs: number;
|
|
12
|
-
readonly flushBufferMs: number;
|
|
13
|
-
readonly remainingMs: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface TelemetryEmitter {
|
|
17
|
-
recordDeadlineAbort: (details: AbortDetails) => void;
|
|
18
|
-
setDeadlineErrorStatus: (error: DeadlineExceededError) => void;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let emitter: TelemetryEmitter | undefined;
|
|
22
|
-
let detected = false;
|
|
23
|
-
|
|
24
|
-
const detectEmitter = async (): Promise<TelemetryEmitter | undefined> => {
|
|
25
|
-
if (detected) return emitter;
|
|
26
|
-
detected = true;
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
// Variable indirection prevents TypeScript from resolving the module
|
|
30
|
-
// at compile time — keeps @opentelemetry/api as a purely optional runtime dep.
|
|
31
|
-
const moduleName = "@opentelemetry/api";
|
|
32
|
-
// oxlint-disable-next-line typescript/no-unsafe-assignment -- dynamic import of optional runtime dependency
|
|
33
|
-
const otelApi: Record<string, unknown> = await import(/* webpackIgnore: true */ moduleName);
|
|
34
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing optional OTel API surface
|
|
35
|
-
const trace = otelApi["trace"] as { getActiveSpan: () => unknown } | undefined;
|
|
36
|
-
|
|
37
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing optional OTel API surface
|
|
38
|
-
const SpanStatusCode = otelApi["SpanStatusCode"] as
|
|
39
|
-
| {
|
|
40
|
-
ERROR: number;
|
|
41
|
-
}
|
|
42
|
-
| undefined;
|
|
43
|
-
|
|
44
|
-
if (!trace || !SpanStatusCode) {
|
|
45
|
-
emitter = undefined;
|
|
46
|
-
return emitter;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
emitter = {
|
|
50
|
-
recordDeadlineAbort(details: AbortDetails): void {
|
|
51
|
-
try {
|
|
52
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing OTel span from untyped getActiveSpan()
|
|
53
|
-
const span = trace.getActiveSpan() as Record<string, unknown> | undefined;
|
|
54
|
-
if (!span) return;
|
|
55
|
-
|
|
56
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing OTel span.addEvent method
|
|
57
|
-
const addEvent = span["addEvent"] as
|
|
58
|
-
| ((name: string, attributes: Record<string, unknown>) => void)
|
|
59
|
-
| undefined;
|
|
60
|
-
if (typeof addEvent !== "function") return;
|
|
61
|
-
|
|
62
|
-
addEvent.call(span, "lambda-deadline-middleware.abort", {
|
|
63
|
-
"deadline.duration_ms": details.deadlineMs,
|
|
64
|
-
"deadline.flush_buffer_ms": details.flushBufferMs,
|
|
65
|
-
"deadline.remaining_ms": details.remainingMs,
|
|
66
|
-
});
|
|
67
|
-
} catch {
|
|
68
|
-
// Telemetry must never disrupt request processing
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
setDeadlineErrorStatus(error: DeadlineExceededError): void {
|
|
73
|
-
try {
|
|
74
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing OTel span from untyped getActiveSpan()
|
|
75
|
-
const span = trace.getActiveSpan() as Record<string, unknown> | undefined;
|
|
76
|
-
if (!span) return;
|
|
77
|
-
|
|
78
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing OTel span.setStatus method
|
|
79
|
-
const setStatus = span["setStatus"] as
|
|
80
|
-
| ((status: { code: number; message: string }) => void)
|
|
81
|
-
| undefined;
|
|
82
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- duck-typing OTel span.setAttribute method
|
|
83
|
-
const setAttribute = span["setAttribute"] as
|
|
84
|
-
| ((key: string, value: unknown) => void)
|
|
85
|
-
| undefined;
|
|
86
|
-
|
|
87
|
-
if (typeof setStatus === "function") {
|
|
88
|
-
setStatus.call(span, {
|
|
89
|
-
code: SpanStatusCode.ERROR,
|
|
90
|
-
message: error.message,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (typeof setAttribute === "function") {
|
|
95
|
-
setAttribute.call(span, "error.type", "DeadlineExceededError");
|
|
96
|
-
setAttribute.call(span, "deadline.duration_ms", error.deadlineMs);
|
|
97
|
-
setAttribute.call(span, "deadline.flush_buffer_ms", error.flushBufferMs);
|
|
98
|
-
setAttribute.call(span, "deadline.remaining_ms", error.remainingMs);
|
|
99
|
-
}
|
|
100
|
-
} catch {
|
|
101
|
-
// Telemetry must never disrupt request processing
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
} catch {
|
|
106
|
-
emitter = undefined;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return emitter;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export const emitDeadlineAbort = async (
|
|
113
|
-
error: DeadlineExceededError,
|
|
114
|
-
config: DeadlineMiddlewareConfig,
|
|
115
|
-
): Promise<void> => {
|
|
116
|
-
try {
|
|
117
|
-
if (!config.telemetryEnabled) return;
|
|
118
|
-
|
|
119
|
-
const em = await detectEmitter();
|
|
120
|
-
if (!em) return;
|
|
121
|
-
|
|
122
|
-
em.recordDeadlineAbort({
|
|
123
|
-
deadlineMs: error.deadlineMs,
|
|
124
|
-
flushBufferMs: error.flushBufferMs,
|
|
125
|
-
remainingMs: error.remainingMs,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
em.setDeadlineErrorStatus(error);
|
|
129
|
-
} catch {
|
|
130
|
-
// Telemetry must never disrupt request processing
|
|
131
|
-
}
|
|
132
|
-
};
|