@sammorrowdrums/mcpi-telemetry 0.85.0-bootstrap.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.
@@ -0,0 +1,294 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import { deepStrictEqual, doesNotThrow, fail, ok, strictEqual } from "node:assert/strict";
54
+ function createCase(factory, group, name, test) {
55
+ return {
56
+ group,
57
+ name,
58
+ async run() {
59
+ const env_1 = { stack: [], error: void 0, hasError: false };
60
+ try {
61
+ const fixture = __addDisposableResource(env_1, await factory(), true);
62
+ await test(fixture);
63
+ }
64
+ catch (e_1) {
65
+ env_1.error = e_1;
66
+ env_1.hasError = true;
67
+ }
68
+ finally {
69
+ const result_1 = __disposeResources(env_1);
70
+ if (result_1)
71
+ await result_1;
72
+ }
73
+ },
74
+ };
75
+ }
76
+ function findSpan(spans, name) {
77
+ const span = spans.find((candidate) => candidate.name === name);
78
+ ok(span, `Expected recorded span ${name}`);
79
+ return span;
80
+ }
81
+ async function rejectsWithSameValue(operation, expected) {
82
+ try {
83
+ await operation;
84
+ fail("Expected operation to reject");
85
+ }
86
+ catch (error) {
87
+ strictEqual(error, expected);
88
+ }
89
+ }
90
+ function unreadable(value) {
91
+ return new Proxy(value, {
92
+ get: () => {
93
+ throw new Error("read");
94
+ },
95
+ getOwnPropertyDescriptor: () => {
96
+ throw new Error("inspect");
97
+ },
98
+ getPrototypeOf: () => {
99
+ throw new Error("prototype");
100
+ },
101
+ ownKeys: () => {
102
+ throw new Error("enumerate");
103
+ },
104
+ });
105
+ }
106
+ /** Creates runner-independent cases for the callback telemetry adapter contract. */
107
+ export function createTelemetryAdapterConformance(factory) {
108
+ return [
109
+ createCase(factory, "callback lifecycle", "admits once synchronously and preserves the result", async (fixture) => {
110
+ let admitted = false;
111
+ let calls = 0;
112
+ const expected = { value: 42 };
113
+ const result = fixture.context.startSpan({ name: "success" }, () => {
114
+ admitted = true;
115
+ calls++;
116
+ return expected;
117
+ });
118
+ strictEqual(admitted, true);
119
+ strictEqual(calls, 1);
120
+ strictEqual(await result, expected);
121
+ deepStrictEqual(findSpan(await fixture.getSpans(), "success").status, { status: "ok" });
122
+ strictEqual(findSpan(await fixture.getSpans(), "success").settled, true);
123
+ }),
124
+ createCase(factory, "callback lifecycle", "preserves synchronous and asynchronous rejection values", async (fixture) => {
125
+ const syncError = new Error("sync");
126
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "sync-error" }, () => {
127
+ throw syncError;
128
+ }), syncError);
129
+ const asyncError = { kind: "async" };
130
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "async-error" }, async () => {
131
+ throw asyncError;
132
+ }), asyncError);
133
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "undefined-error" }, () => Promise.reject(undefined)), undefined);
134
+ const unreadableError = unreadable({ kind: "unreadable" });
135
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "unreadable-error" }, () => {
136
+ throw unreadableError;
137
+ }), unreadableError);
138
+ const asyncUnreadableError = unreadable({ kind: "async-unreadable" });
139
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "async-unreadable-error" }, () => Promise.reject(asyncUnreadableError)), asyncUnreadableError);
140
+ const spans = await fixture.getSpans();
141
+ for (const name of [
142
+ "sync-error",
143
+ "async-error",
144
+ "undefined-error",
145
+ "unreadable-error",
146
+ "async-unreadable-error",
147
+ ]) {
148
+ strictEqual(findSpan(spans, name).status.status, "error");
149
+ }
150
+ }),
151
+ createCase(factory, "status", "uses last explicit status without automatic overwrite", async (fixture) => {
152
+ await fixture.context.startSpan({ name: "last-status" }, (span) => {
153
+ span.setStatus({ status: "error", error: { name: "Expected", message: "first" } });
154
+ span.setStatus({ status: "ok" });
155
+ });
156
+ const thrown = new Error("after explicit status");
157
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "explicit-before-throw" }, (span) => {
158
+ span.setStatus({ status: "ok" });
159
+ throw thrown;
160
+ }), thrown);
161
+ const rejected = new Error("after async explicit status");
162
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "explicit-before-rejection" }, (span) => {
163
+ span.setStatus({ status: "error", error: { name: "Expected", message: "async failure" } });
164
+ return Promise.reject(rejected);
165
+ }), rejected);
166
+ await fixture.context.startSpan({ name: "expected-failure" }, (span) => {
167
+ span.setStatus({ status: "error", error: { name: "Expected", message: "returned failure" } });
168
+ return { ok: false };
169
+ });
170
+ const spans = await fixture.getSpans();
171
+ deepStrictEqual(findSpan(spans, "last-status").status, { status: "ok" });
172
+ deepStrictEqual(findSpan(spans, "explicit-before-throw").status, { status: "ok" });
173
+ deepStrictEqual(findSpan(spans, "explicit-before-rejection").status, {
174
+ status: "error",
175
+ error: { name: "Expected", message: "async failure" },
176
+ });
177
+ deepStrictEqual(findSpan(spans, "expected-failure").status, {
178
+ status: "error",
179
+ error: { name: "Expected", message: "returned failure" },
180
+ });
181
+ }),
182
+ createCase(factory, "recording", "merges attributes and records ordered events", async (fixture) => {
183
+ await fixture.context.startSpan({
184
+ name: "recording",
185
+ attributes: { start: "value", overwrite: "start", ignored: undefined },
186
+ }, (span) => {
187
+ span.setAttributes({ count: 1, overwrite: "middle" });
188
+ span.setAttributes({ count: undefined, overwrite: "end" });
189
+ span.addEvent("first", { index: 1, ignored: undefined });
190
+ span.addEvent("second", { index: 2 });
191
+ });
192
+ const span = findSpan(await fixture.getSpans(), "recording");
193
+ deepStrictEqual(span.attributes, { start: "value", overwrite: "end", count: 1 });
194
+ deepStrictEqual(span.events, [
195
+ { name: "first", attributes: { index: 1 } },
196
+ { name: "second", attributes: { index: 2 } },
197
+ ]);
198
+ }),
199
+ createCase(factory, "recording", "ignores failed attribute calls atomically", async (fixture) => {
200
+ await fixture.context.startSpan({ name: "atomic-attributes", attributes: { retained: "value" } }, (span) => {
201
+ const attributes = {
202
+ partial: "must not survive",
203
+ unreadable: unreadable(["value"]),
204
+ };
205
+ doesNotThrow(() => span.setAttributes(attributes));
206
+ });
207
+ deepStrictEqual(findSpan(await fixture.getSpans(), "atomic-attributes").attributes, {
208
+ retained: "value",
209
+ });
210
+ }),
211
+ createCase(factory, "recording", "makes calls after settlement inert", async (fixture) => {
212
+ let settledSpan;
213
+ await fixture.context.startSpan({ name: "settled", attributes: { value: "initial" } }, (span) => {
214
+ settledSpan = span;
215
+ });
216
+ const capturedSpan = settledSpan;
217
+ if (!capturedSpan)
218
+ throw new Error("Expected callback span");
219
+ doesNotThrow(() => capturedSpan.setAttributes({ value: "late" }));
220
+ doesNotThrow(() => capturedSpan.addEvent("late", { value: true }));
221
+ doesNotThrow(() => capturedSpan.setStatus({ status: "error" }));
222
+ let childAdmitted = false;
223
+ const childResult = capturedSpan.startSpan({ name: "late-child" }, () => {
224
+ childAdmitted = true;
225
+ return 7;
226
+ });
227
+ strictEqual(childAdmitted, true);
228
+ strictEqual(await childResult, 7);
229
+ const spans = await fixture.getSpans();
230
+ strictEqual(spans.length, 1);
231
+ deepStrictEqual(spans[0]?.attributes, { value: "initial" });
232
+ deepStrictEqual(spans[0]?.events, []);
233
+ deepStrictEqual(spans[0]?.status, { status: "ok" });
234
+ }),
235
+ createCase(factory, "parentage", "records nested and concurrent child relationships", async (fixture) => {
236
+ let releaseFirst;
237
+ const firstGate = new Promise((resolve) => {
238
+ releaseFirst = resolve;
239
+ });
240
+ await fixture.context.startSpan({ name: "parent" }, async (parent) => {
241
+ const first = parent.startSpan({ name: "first-child" }, async () => {
242
+ await firstGate;
243
+ });
244
+ const second = parent.startSpan({ name: "second-child" }, () => "done");
245
+ strictEqual(await second, "done");
246
+ releaseFirst?.();
247
+ await first;
248
+ });
249
+ const spans = await fixture.getSpans();
250
+ const parent = findSpan(spans, "parent");
251
+ const first = findSpan(spans, "first-child");
252
+ const second = findSpan(spans, "second-child");
253
+ strictEqual(parent.parentId, null);
254
+ strictEqual(first.parentId, parent.id);
255
+ strictEqual(second.parentId, parent.id);
256
+ ok(second.endSequence !== undefined && first.endSequence !== undefined && parent.endSequence !== undefined);
257
+ ok(second.endSequence < first.endSequence);
258
+ ok(first.endSequence < parent.endSequence);
259
+ }),
260
+ createCase(factory, "passivity", "suppresses unreadable telemetry payload failures", async (fixture) => {
261
+ let calls = 0;
262
+ const options = unreadable({ name: "unreadable-options", attributes: { secret: "value" } });
263
+ const result = fixture.context.startSpan(options, () => {
264
+ calls++;
265
+ return 9;
266
+ });
267
+ strictEqual(calls, 1);
268
+ strictEqual(await result, 9);
269
+ deepStrictEqual(await fixture.getSpans(), []);
270
+ await fixture.context.startSpan({ name: "unreadable-recording" }, (span) => {
271
+ const attributes = unreadable({ secret: "value" });
272
+ const status = unreadable({ status: "ok" });
273
+ doesNotThrow(() => span.setAttributes(attributes));
274
+ doesNotThrow(() => span.addEvent("unreadable-event", attributes));
275
+ doesNotThrow(() => span.setStatus(status));
276
+ });
277
+ const recorded = await fixture.getSpans();
278
+ strictEqual(recorded.length, 1);
279
+ deepStrictEqual(recorded[0]?.attributes, {});
280
+ deepStrictEqual(recorded[0]?.events, []);
281
+ deepStrictEqual(recorded[0]?.status, { status: "ok" });
282
+ }),
283
+ createCase(factory, "passivity", "ignores failed status calls atomically", async (fixture) => {
284
+ const rejection = new Error("rejected after unreadable status");
285
+ await rejectsWithSameValue(fixture.context.startSpan({ name: "unreadable-status" }, (span) => {
286
+ const status = unreadable({ status: "ok" });
287
+ doesNotThrow(() => span.setStatus(status));
288
+ return Promise.reject(rejection);
289
+ }), rejection);
290
+ strictEqual(findSpan(await fixture.getSpans(), "unreadable-status").status.status, "error");
291
+ }),
292
+ ];
293
+ }
294
+ //# sourceMappingURL=conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../src/testing/conformance.ts"],"names":[],"mappings":"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","sourcesContent":["import { deepStrictEqual, doesNotThrow, fail, ok, strictEqual } from \"node:assert/strict\";\nimport type { SpanAttributes, SpanOptions, SpanStatus, TelemetrySpan } from \"../index.ts\";\nimport type { RecordedTelemetrySpan } from \"../memory.ts\";\nimport type {\n\tTelemetryAdapterConformanceCase,\n\tTelemetryAdapterFixture,\n\tTelemetryAdapterFixtureFactory,\n} from \"./types.ts\";\n\ntype ConformanceTest = (fixture: TelemetryAdapterFixture) => Promise<void>;\n\nfunction createCase(\n\tfactory: TelemetryAdapterFixtureFactory,\n\tgroup: string,\n\tname: string,\n\ttest: ConformanceTest,\n): TelemetryAdapterConformanceCase {\n\treturn {\n\t\tgroup,\n\t\tname,\n\t\tasync run() {\n\t\t\tawait using fixture = await factory();\n\t\t\tawait test(fixture);\n\t\t},\n\t};\n}\n\nfunction findSpan(spans: readonly RecordedTelemetrySpan[], name: string): RecordedTelemetrySpan {\n\tconst span = spans.find((candidate) => candidate.name === name);\n\tok(span, `Expected recorded span ${name}`);\n\treturn span;\n}\n\nasync function rejectsWithSameValue(operation: Promise<unknown>, expected: unknown): Promise<void> {\n\ttry {\n\t\tawait operation;\n\t\tfail(\"Expected operation to reject\");\n\t} catch (error) {\n\t\tstrictEqual(error, expected);\n\t}\n}\n\nfunction unreadable<T extends object>(value: T): T {\n\treturn new Proxy(value, {\n\t\tget: () => {\n\t\t\tthrow new Error(\"read\");\n\t\t},\n\t\tgetOwnPropertyDescriptor: () => {\n\t\t\tthrow new Error(\"inspect\");\n\t\t},\n\t\tgetPrototypeOf: () => {\n\t\t\tthrow new Error(\"prototype\");\n\t\t},\n\t\townKeys: () => {\n\t\t\tthrow new Error(\"enumerate\");\n\t\t},\n\t});\n}\n\n/** Creates runner-independent cases for the callback telemetry adapter contract. */\nexport function createTelemetryAdapterConformance(\n\tfactory: TelemetryAdapterFixtureFactory,\n): readonly TelemetryAdapterConformanceCase[] {\n\treturn [\n\t\tcreateCase(\n\t\t\tfactory,\n\t\t\t\"callback lifecycle\",\n\t\t\t\"admits once synchronously and preserves the result\",\n\t\t\tasync (fixture) => {\n\t\t\t\tlet admitted = false;\n\t\t\t\tlet calls = 0;\n\t\t\t\tconst expected = { value: 42 };\n\t\t\t\tconst result = fixture.context.startSpan({ name: \"success\" }, () => {\n\t\t\t\t\tadmitted = true;\n\t\t\t\t\tcalls++;\n\t\t\t\t\treturn expected;\n\t\t\t\t});\n\n\t\t\t\tstrictEqual(admitted, true);\n\t\t\t\tstrictEqual(calls, 1);\n\t\t\t\tstrictEqual(await result, expected);\n\t\t\t\tdeepStrictEqual(findSpan(await fixture.getSpans(), \"success\").status, { status: \"ok\" });\n\t\t\t\tstrictEqual(findSpan(await fixture.getSpans(), \"success\").settled, true);\n\t\t\t},\n\t\t),\n\n\t\tcreateCase(\n\t\t\tfactory,\n\t\t\t\"callback lifecycle\",\n\t\t\t\"preserves synchronous and asynchronous rejection values\",\n\t\t\tasync (fixture) => {\n\t\t\t\tconst syncError = new Error(\"sync\");\n\t\t\t\tawait rejectsWithSameValue(\n\t\t\t\t\tfixture.context.startSpan({ name: \"sync-error\" }, () => {\n\t\t\t\t\t\tthrow syncError;\n\t\t\t\t\t}),\n\t\t\t\t\tsyncError,\n\t\t\t\t);\n\n\t\t\t\tconst asyncError = { kind: \"async\" };\n\t\t\t\tawait rejectsWithSameValue(\n\t\t\t\t\tfixture.context.startSpan({ name: \"async-error\" }, async () => {\n\t\t\t\t\t\tthrow asyncError;\n\t\t\t\t\t}),\n\t\t\t\t\tasyncError,\n\t\t\t\t);\n\n\t\t\t\tawait rejectsWithSameValue(\n\t\t\t\t\tfixture.context.startSpan({ name: \"undefined-error\" }, () => Promise.reject(undefined)),\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\n\t\t\t\tconst unreadableError = unreadable({ kind: \"unreadable\" });\n\t\t\t\tawait rejectsWithSameValue(\n\t\t\t\t\tfixture.context.startSpan({ name: \"unreadable-error\" }, () => {\n\t\t\t\t\t\tthrow unreadableError;\n\t\t\t\t\t}),\n\t\t\t\t\tunreadableError,\n\t\t\t\t);\n\n\t\t\t\tconst asyncUnreadableError = unreadable({ kind: \"async-unreadable\" });\n\t\t\t\tawait rejectsWithSameValue(\n\t\t\t\t\tfixture.context.startSpan({ name: \"async-unreadable-error\" }, () =>\n\t\t\t\t\t\tPromise.reject(asyncUnreadableError),\n\t\t\t\t\t),\n\t\t\t\t\tasyncUnreadableError,\n\t\t\t\t);\n\n\t\t\t\tconst spans = await fixture.getSpans();\n\t\t\t\tfor (const name of [\n\t\t\t\t\t\"sync-error\",\n\t\t\t\t\t\"async-error\",\n\t\t\t\t\t\"undefined-error\",\n\t\t\t\t\t\"unreadable-error\",\n\t\t\t\t\t\"async-unreadable-error\",\n\t\t\t\t]) {\n\t\t\t\t\tstrictEqual(findSpan(spans, name).status.status, \"error\");\n\t\t\t\t}\n\t\t\t},\n\t\t),\n\n\t\tcreateCase(factory, \"status\", \"uses last explicit status without automatic overwrite\", async (fixture) => {\n\t\t\tawait fixture.context.startSpan({ name: \"last-status\" }, (span) => {\n\t\t\t\tspan.setStatus({ status: \"error\", error: { name: \"Expected\", message: \"first\" } });\n\t\t\t\tspan.setStatus({ status: \"ok\" });\n\t\t\t});\n\n\t\t\tconst thrown = new Error(\"after explicit status\");\n\t\t\tawait rejectsWithSameValue(\n\t\t\t\tfixture.context.startSpan({ name: \"explicit-before-throw\" }, (span) => {\n\t\t\t\t\tspan.setStatus({ status: \"ok\" });\n\t\t\t\t\tthrow thrown;\n\t\t\t\t}),\n\t\t\t\tthrown,\n\t\t\t);\n\n\t\t\tconst rejected = new Error(\"after async explicit status\");\n\t\t\tawait rejectsWithSameValue(\n\t\t\t\tfixture.context.startSpan({ name: \"explicit-before-rejection\" }, (span) => {\n\t\t\t\t\tspan.setStatus({ status: \"error\", error: { name: \"Expected\", message: \"async failure\" } });\n\t\t\t\t\treturn Promise.reject(rejected);\n\t\t\t\t}),\n\t\t\t\trejected,\n\t\t\t);\n\n\t\t\tawait fixture.context.startSpan({ name: \"expected-failure\" }, (span) => {\n\t\t\t\tspan.setStatus({ status: \"error\", error: { name: \"Expected\", message: \"returned failure\" } });\n\t\t\t\treturn { ok: false };\n\t\t\t});\n\n\t\t\tconst spans = await fixture.getSpans();\n\t\t\tdeepStrictEqual(findSpan(spans, \"last-status\").status, { status: \"ok\" });\n\t\t\tdeepStrictEqual(findSpan(spans, \"explicit-before-throw\").status, { status: \"ok\" });\n\t\t\tdeepStrictEqual(findSpan(spans, \"explicit-before-rejection\").status, {\n\t\t\t\tstatus: \"error\",\n\t\t\t\terror: { name: \"Expected\", message: \"async failure\" },\n\t\t\t});\n\t\t\tdeepStrictEqual(findSpan(spans, \"expected-failure\").status, {\n\t\t\t\tstatus: \"error\",\n\t\t\t\terror: { name: \"Expected\", message: \"returned failure\" },\n\t\t\t});\n\t\t}),\n\n\t\tcreateCase(factory, \"recording\", \"merges attributes and records ordered events\", async (fixture) => {\n\t\t\tawait fixture.context.startSpan(\n\t\t\t\t{\n\t\t\t\t\tname: \"recording\",\n\t\t\t\t\tattributes: { start: \"value\", overwrite: \"start\", ignored: undefined },\n\t\t\t\t},\n\t\t\t\t(span) => {\n\t\t\t\t\tspan.setAttributes({ count: 1, overwrite: \"middle\" });\n\t\t\t\t\tspan.setAttributes({ count: undefined, overwrite: \"end\" });\n\t\t\t\t\tspan.addEvent(\"first\", { index: 1, ignored: undefined });\n\t\t\t\t\tspan.addEvent(\"second\", { index: 2 });\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst span = findSpan(await fixture.getSpans(), \"recording\");\n\t\t\tdeepStrictEqual(span.attributes, { start: \"value\", overwrite: \"end\", count: 1 });\n\t\t\tdeepStrictEqual(span.events, [\n\t\t\t\t{ name: \"first\", attributes: { index: 1 } },\n\t\t\t\t{ name: \"second\", attributes: { index: 2 } },\n\t\t\t]);\n\t\t}),\n\n\t\tcreateCase(factory, \"recording\", \"ignores failed attribute calls atomically\", async (fixture) => {\n\t\t\tawait fixture.context.startSpan({ name: \"atomic-attributes\", attributes: { retained: \"value\" } }, (span) => {\n\t\t\t\tconst attributes: SpanAttributes = {\n\t\t\t\t\tpartial: \"must not survive\",\n\t\t\t\t\tunreadable: unreadable([\"value\"]),\n\t\t\t\t};\n\t\t\t\tdoesNotThrow(() => span.setAttributes(attributes));\n\t\t\t});\n\n\t\t\tdeepStrictEqual(findSpan(await fixture.getSpans(), \"atomic-attributes\").attributes, {\n\t\t\t\tretained: \"value\",\n\t\t\t});\n\t\t}),\n\n\t\tcreateCase(factory, \"recording\", \"makes calls after settlement inert\", async (fixture) => {\n\t\t\tlet settledSpan: TelemetrySpan | undefined;\n\t\t\tawait fixture.context.startSpan({ name: \"settled\", attributes: { value: \"initial\" } }, (span) => {\n\t\t\t\tsettledSpan = span;\n\t\t\t});\n\t\t\tconst capturedSpan = settledSpan;\n\t\t\tif (!capturedSpan) throw new Error(\"Expected callback span\");\n\n\t\t\tdoesNotThrow(() => capturedSpan.setAttributes({ value: \"late\" }));\n\t\t\tdoesNotThrow(() => capturedSpan.addEvent(\"late\", { value: true }));\n\t\t\tdoesNotThrow(() => capturedSpan.setStatus({ status: \"error\" }));\n\t\t\tlet childAdmitted = false;\n\t\t\tconst childResult = capturedSpan.startSpan({ name: \"late-child\" }, () => {\n\t\t\t\tchildAdmitted = true;\n\t\t\t\treturn 7;\n\t\t\t});\n\t\t\tstrictEqual(childAdmitted, true);\n\t\t\tstrictEqual(await childResult, 7);\n\n\t\t\tconst spans = await fixture.getSpans();\n\t\t\tstrictEqual(spans.length, 1);\n\t\t\tdeepStrictEqual(spans[0]?.attributes, { value: \"initial\" });\n\t\t\tdeepStrictEqual(spans[0]?.events, []);\n\t\t\tdeepStrictEqual(spans[0]?.status, { status: \"ok\" });\n\t\t}),\n\n\t\tcreateCase(factory, \"parentage\", \"records nested and concurrent child relationships\", async (fixture) => {\n\t\t\tlet releaseFirst: (() => void) | undefined;\n\t\t\tconst firstGate = new Promise<void>((resolve) => {\n\t\t\t\treleaseFirst = resolve;\n\t\t\t});\n\n\t\t\tawait fixture.context.startSpan({ name: \"parent\" }, async (parent) => {\n\t\t\t\tconst first = parent.startSpan({ name: \"first-child\" }, async () => {\n\t\t\t\t\tawait firstGate;\n\t\t\t\t});\n\t\t\t\tconst second = parent.startSpan({ name: \"second-child\" }, () => \"done\");\n\t\t\t\tstrictEqual(await second, \"done\");\n\t\t\t\treleaseFirst?.();\n\t\t\t\tawait first;\n\t\t\t});\n\n\t\t\tconst spans = await fixture.getSpans();\n\t\t\tconst parent = findSpan(spans, \"parent\");\n\t\t\tconst first = findSpan(spans, \"first-child\");\n\t\t\tconst second = findSpan(spans, \"second-child\");\n\t\t\tstrictEqual(parent.parentId, null);\n\t\t\tstrictEqual(first.parentId, parent.id);\n\t\t\tstrictEqual(second.parentId, parent.id);\n\t\t\tok(second.endSequence !== undefined && first.endSequence !== undefined && parent.endSequence !== undefined);\n\t\t\tok(second.endSequence < first.endSequence);\n\t\t\tok(first.endSequence < parent.endSequence);\n\t\t}),\n\n\t\tcreateCase(factory, \"passivity\", \"suppresses unreadable telemetry payload failures\", async (fixture) => {\n\t\t\tlet calls = 0;\n\t\t\tconst options = unreadable<SpanOptions>({ name: \"unreadable-options\", attributes: { secret: \"value\" } });\n\t\t\tconst result = fixture.context.startSpan(options, () => {\n\t\t\t\tcalls++;\n\t\t\t\treturn 9;\n\t\t\t});\n\n\t\t\tstrictEqual(calls, 1);\n\t\t\tstrictEqual(await result, 9);\n\t\t\tdeepStrictEqual(await fixture.getSpans(), []);\n\n\t\t\tawait fixture.context.startSpan({ name: \"unreadable-recording\" }, (span) => {\n\t\t\t\tconst attributes = unreadable<SpanAttributes>({ secret: \"value\" });\n\t\t\t\tconst status = unreadable<SpanStatus>({ status: \"ok\" });\n\t\t\t\tdoesNotThrow(() => span.setAttributes(attributes));\n\t\t\t\tdoesNotThrow(() => span.addEvent(\"unreadable-event\", attributes));\n\t\t\t\tdoesNotThrow(() => span.setStatus(status));\n\t\t\t});\n\n\t\t\tconst recorded = await fixture.getSpans();\n\t\t\tstrictEqual(recorded.length, 1);\n\t\t\tdeepStrictEqual(recorded[0]?.attributes, {});\n\t\t\tdeepStrictEqual(recorded[0]?.events, []);\n\t\t\tdeepStrictEqual(recorded[0]?.status, { status: \"ok\" });\n\t\t}),\n\n\t\tcreateCase(factory, \"passivity\", \"ignores failed status calls atomically\", async (fixture) => {\n\t\t\tconst rejection = new Error(\"rejected after unreadable status\");\n\t\t\tawait rejectsWithSameValue(\n\t\t\t\tfixture.context.startSpan({ name: \"unreadable-status\" }, (span) => {\n\t\t\t\t\tconst status = unreadable<SpanStatus>({ status: \"ok\" });\n\t\t\t\t\tdoesNotThrow(() => span.setStatus(status));\n\t\t\t\t\treturn Promise.reject(rejection);\n\t\t\t\t}),\n\t\t\t\trejection,\n\t\t\t);\n\n\t\t\tstrictEqual(findSpan(await fixture.getSpans(), \"unreadable-status\").status.status, \"error\");\n\t\t}),\n\t];\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { createTelemetryAdapterConformance } from "./conformance.ts";
2
+ export type { TelemetryAdapterConformanceCase, TelemetryAdapterFixture, TelemetryAdapterFixtureFactory, } from "./types.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EACX,+BAA+B,EAC/B,uBAAuB,EACvB,8BAA8B,GAC9B,MAAM,YAAY,CAAC","sourcesContent":["export { createTelemetryAdapterConformance } from \"./conformance.ts\";\nexport type {\n\tTelemetryAdapterConformanceCase,\n\tTelemetryAdapterFixture,\n\tTelemetryAdapterFixtureFactory,\n} from \"./types.ts\";\n"]}
@@ -0,0 +1,2 @@
1
+ export { createTelemetryAdapterConformance } from "./conformance.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { createTelemetryAdapterConformance } from \"./conformance.ts\";\nexport type {\n\tTelemetryAdapterConformanceCase,\n\tTelemetryAdapterFixture,\n\tTelemetryAdapterFixtureFactory,\n} from \"./types.ts\";\n"]}
@@ -0,0 +1,16 @@
1
+ import type { TelemetryContext } from "../index.ts";
2
+ import type { RecordedTelemetrySpan } from "../memory.ts";
3
+ /** A fresh adapter instance and normalized snapshot reader owned by one conformance case. */
4
+ export interface TelemetryAdapterFixture extends AsyncDisposable {
5
+ readonly context: TelemetryContext;
6
+ getSpans(): Promise<readonly RecordedTelemetrySpan[]>;
7
+ }
8
+ /** Creates an isolated adapter fixture for one conformance case. */
9
+ export type TelemetryAdapterFixtureFactory = () => Promise<TelemetryAdapterFixture>;
10
+ /** A runner-independent conformance case that can be registered with any test framework. */
11
+ export interface TelemetryAdapterConformanceCase {
12
+ readonly group: string;
13
+ readonly name: string;
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,6FAA6F;AAC7F,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC/D,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,IAAI,OAAO,CAAC,SAAS,qBAAqB,EAAE,CAAC,CAAC;CACtD;AAED,oEAAoE;AACpE,MAAM,MAAM,8BAA8B,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEpF,4FAA4F;AAC5F,MAAM,WAAW,+BAA+B;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB","sourcesContent":["import type { TelemetryContext } from \"../index.ts\";\nimport type { RecordedTelemetrySpan } from \"../memory.ts\";\n\n/** A fresh adapter instance and normalized snapshot reader owned by one conformance case. */\nexport interface TelemetryAdapterFixture extends AsyncDisposable {\n\treadonly context: TelemetryContext;\n\tgetSpans(): Promise<readonly RecordedTelemetrySpan[]>;\n}\n\n/** Creates an isolated adapter fixture for one conformance case. */\nexport type TelemetryAdapterFixtureFactory = () => Promise<TelemetryAdapterFixture>;\n\n/** A runner-independent conformance case that can be registered with any test framework. */\nexport interface TelemetryAdapterConformanceCase {\n\treadonly group: string;\n\treadonly name: string;\n\trun(): Promise<void>;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { TelemetryContext } from \"../index.ts\";\nimport type { RecordedTelemetrySpan } from \"../memory.ts\";\n\n/** A fresh adapter instance and normalized snapshot reader owned by one conformance case. */\nexport interface TelemetryAdapterFixture extends AsyncDisposable {\n\treadonly context: TelemetryContext;\n\tgetSpans(): Promise<readonly RecordedTelemetrySpan[]>;\n}\n\n/** Creates an isolated adapter fixture for one conformance case. */\nexport type TelemetryAdapterFixtureFactory = () => Promise<TelemetryAdapterFixture>;\n\n/** A runner-independent conformance case that can be registered with any test framework. */\nexport interface TelemetryAdapterConformanceCase {\n\treadonly group: string;\n\treadonly name: string;\n\trun(): Promise<void>;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@sammorrowdrums/mcpi-telemetry",
3
+ "version": "0.85.0-bootstrap.0",
4
+ "description": "Vendor-neutral telemetry contracts and typed schema utilities for mcpi",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./testing": {
14
+ "types": "./dist/testing/index.d.ts",
15
+ "import": "./dist/testing/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "scripts": {
24
+ "clean": "shx rm -rf dist",
25
+ "build": "tsgo -p tsconfig.build.json",
26
+ "test": "vitest --run",
27
+ "prepublishOnly": "npm run clean && npm run build"
28
+ },
29
+ "keywords": [
30
+ "telemetry",
31
+ "tracing",
32
+ "observability"
33
+ ],
34
+ "author": "Mario Zechner",
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/SamMorrowDrums/mcpi.git",
39
+ "directory": "packages/telemetry"
40
+ },
41
+ "homepage": "https://github.com/SamMorrowDrums/mcpi/tree/main/packages/telemetry#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/SamMorrowDrums/mcpi/issues"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "registry": "https://registry.npmjs.org/"
48
+ },
49
+ "engines": {
50
+ "node": ">=22.19.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "24.12.4",
54
+ "vitest": "4.1.9"
55
+ }
56
+ }