kernl 0.12.4 → 0.12.6

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 (95) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +29 -0
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +2 -0
  6. package/dist/kernl/kernl.d.ts +6 -0
  7. package/dist/kernl/kernl.d.ts.map +1 -1
  8. package/dist/kernl/kernl.js +19 -0
  9. package/dist/kernl/types.d.ts +6 -0
  10. package/dist/kernl/types.d.ts.map +1 -1
  11. package/dist/lib/env.d.ts +2 -2
  12. package/dist/mcp/http.d.ts.map +1 -1
  13. package/dist/mcp/http.js +1 -5
  14. package/dist/mcp/sse.d.ts.map +1 -1
  15. package/dist/mcp/sse.js +1 -5
  16. package/dist/mcp/stdio.d.ts.map +1 -1
  17. package/dist/mcp/stdio.js +1 -5
  18. package/dist/task.d.ts.map +1 -1
  19. package/dist/task.js +0 -1
  20. package/dist/thread/thread.d.ts +5 -4
  21. package/dist/thread/thread.d.ts.map +1 -1
  22. package/dist/thread/thread.js +91 -22
  23. package/dist/thread/types.d.ts +5 -0
  24. package/dist/thread/types.d.ts.map +1 -1
  25. package/dist/tracing/__tests__/composite.test.d.ts +2 -0
  26. package/dist/tracing/__tests__/composite.test.d.ts.map +1 -0
  27. package/dist/tracing/__tests__/composite.test.js +146 -0
  28. package/dist/tracing/__tests__/dispatch.test.d.ts +2 -0
  29. package/dist/tracing/__tests__/dispatch.test.d.ts.map +1 -0
  30. package/dist/tracing/__tests__/dispatch.test.js +160 -0
  31. package/dist/tracing/__tests__/helpers.d.ts +69 -0
  32. package/dist/tracing/__tests__/helpers.d.ts.map +1 -0
  33. package/dist/tracing/__tests__/helpers.js +109 -0
  34. package/dist/tracing/__tests__/integration.test.d.ts +2 -0
  35. package/dist/tracing/__tests__/integration.test.d.ts.map +1 -0
  36. package/dist/tracing/__tests__/integration.test.js +675 -0
  37. package/dist/tracing/__tests__/span.test.d.ts +2 -0
  38. package/dist/tracing/__tests__/span.test.d.ts.map +1 -0
  39. package/dist/tracing/__tests__/span.test.js +188 -0
  40. package/dist/tracing/dispatch.d.ts +43 -0
  41. package/dist/tracing/dispatch.d.ts.map +1 -0
  42. package/dist/tracing/dispatch.js +70 -0
  43. package/dist/tracing/index.d.ts +8 -0
  44. package/dist/tracing/index.d.ts.map +1 -0
  45. package/dist/tracing/index.js +6 -0
  46. package/dist/tracing/span.d.ts +69 -0
  47. package/dist/tracing/span.d.ts.map +1 -0
  48. package/dist/tracing/span.js +64 -0
  49. package/dist/tracing/subscriber.d.ts +53 -0
  50. package/dist/tracing/subscriber.d.ts.map +1 -0
  51. package/dist/tracing/subscriber.js +1 -0
  52. package/dist/tracing/subscribers/composite.d.ts +26 -0
  53. package/dist/tracing/subscribers/composite.d.ts.map +1 -0
  54. package/dist/tracing/subscribers/composite.js +96 -0
  55. package/dist/tracing/subscribers/console.d.ts +22 -0
  56. package/dist/tracing/subscribers/console.d.ts.map +1 -0
  57. package/dist/tracing/subscribers/console.js +82 -0
  58. package/dist/tracing/types.d.ts +77 -0
  59. package/dist/tracing/types.d.ts.map +1 -0
  60. package/dist/tracing/types.js +1 -0
  61. package/package.json +5 -1
  62. package/src/agent.ts +2 -0
  63. package/src/index.ts +1 -0
  64. package/src/kernl/kernl.ts +21 -0
  65. package/src/kernl/types.ts +7 -0
  66. package/src/mcp/http.ts +1 -9
  67. package/src/mcp/sse.ts +1 -10
  68. package/src/mcp/stdio.ts +1 -10
  69. package/src/task.ts +0 -1
  70. package/src/thread/thread.ts +111 -24
  71. package/src/thread/types.ts +5 -0
  72. package/src/tracing/__tests__/composite.test.ts +218 -0
  73. package/src/tracing/__tests__/dispatch.test.ts +222 -0
  74. package/src/tracing/__tests__/helpers.ts +138 -0
  75. package/src/tracing/__tests__/integration.test.ts +808 -0
  76. package/src/tracing/__tests__/span.test.ts +250 -0
  77. package/src/tracing/dispatch.ts +114 -0
  78. package/src/tracing/index.ts +39 -0
  79. package/src/tracing/span.ts +115 -0
  80. package/src/tracing/subscriber.ts +62 -0
  81. package/src/tracing/subscribers/composite.ts +102 -0
  82. package/src/tracing/subscribers/console.ts +101 -0
  83. package/src/tracing/types.ts +115 -0
  84. package/dist/trace/processor.d.ts +0 -1
  85. package/dist/trace/processor.d.ts.map +0 -1
  86. package/dist/trace/processor.js +0 -1
  87. package/dist/trace/traces.d.ts +0 -1
  88. package/dist/trace/traces.d.ts.map +0 -1
  89. package/dist/trace/traces.js +0 -73
  90. package/dist/trace/utils.d.ts +0 -22
  91. package/dist/trace/utils.d.ts.map +0 -1
  92. package/dist/trace/utils.js +0 -30
  93. package/src/trace/processor.ts +0 -0
  94. package/src/trace/traces.ts +0 -86
  95. package/src/trace/utils.ts +0 -38
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=composite.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite.test.d.ts","sourceRoot":"","sources":["../../../src/tracing/__tests__/composite.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { CompositeSubscriber } from "../subscribers/composite.js";
3
+ import { TestSubscriber } from "./helpers.js";
4
+ describe("CompositeSubscriber", () => {
5
+ let sub1;
6
+ let sub2;
7
+ let composite;
8
+ beforeEach(() => {
9
+ sub1 = new TestSubscriber();
10
+ sub2 = new TestSubscriber();
11
+ composite = new CompositeSubscriber([sub1, sub2]);
12
+ });
13
+ describe("enabled", () => {
14
+ it("should return true if any subscriber is enabled", () => {
15
+ sub1.enabledKinds = new Set(["thread"]);
16
+ sub2.enabledKinds = new Set(["model.call"]);
17
+ expect(composite.enabled({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" })).toBe(true);
18
+ expect(composite.enabled({ kind: "model.call", provider: "test", modelId: "m1" })).toBe(true);
19
+ });
20
+ it("should return false if no subscriber is enabled", () => {
21
+ sub1.enabledKinds = new Set(["thread"]);
22
+ sub2.enabledKinds = new Set(["thread"]);
23
+ expect(composite.enabled({ kind: "model.call", provider: "test", modelId: "m1" })).toBe(false);
24
+ });
25
+ it("should return true if all subscribers are enabled (default)", () => {
26
+ expect(composite.enabled({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" })).toBe(true);
27
+ });
28
+ });
29
+ describe("span", () => {
30
+ it("should create span in all enabled subscribers", () => {
31
+ const data = { kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" };
32
+ composite.span(data, null);
33
+ expect(sub1.spans.size).toBe(1);
34
+ expect(sub2.spans.size).toBe(1);
35
+ const [, s1] = [...sub1.spans.entries()][0];
36
+ const [, s2] = [...sub2.spans.entries()][0];
37
+ expect(s1.data).toEqual(data);
38
+ expect(s2.data).toEqual(data);
39
+ });
40
+ it("should return composite span ID", () => {
41
+ const id = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
42
+ expect(id).toMatch(/^composite_\d+$/);
43
+ });
44
+ it("should skip disabled subscribers", () => {
45
+ sub1.enabledKinds = new Set(["thread"]);
46
+ sub2.enabledKinds = new Set(["model.call"]); // not enabled for thread
47
+ composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
48
+ expect(sub1.spans.size).toBe(1);
49
+ expect(sub2.spans.size).toBe(0);
50
+ });
51
+ it("should map parent span IDs correctly", () => {
52
+ // Create parent
53
+ const parentId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
54
+ // Create child with parent
55
+ composite.span({ kind: "model.call", provider: "test", modelId: "m1" }, parentId);
56
+ // Each subscriber should have correct parent mapping
57
+ const threadSpan1 = sub1.spansOfKind("thread")[0];
58
+ const modelSpan1 = sub1.spansOfKind("model.call")[0];
59
+ expect(modelSpan1.parent).toBe(threadSpan1.id);
60
+ const threadSpan2 = sub2.spansOfKind("thread")[0];
61
+ const modelSpan2 = sub2.spansOfKind("model.call")[0];
62
+ expect(modelSpan2.parent).toBe(threadSpan2.id);
63
+ });
64
+ });
65
+ describe("enter / exit", () => {
66
+ it("should dispatch to all subscribers", () => {
67
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
68
+ composite.enter(spanId);
69
+ expect(sub1.entered.size).toBe(1);
70
+ expect(sub2.entered.size).toBe(1);
71
+ composite.exit(spanId);
72
+ expect(sub1.exited.size).toBe(1);
73
+ expect(sub2.exited.size).toBe(1);
74
+ });
75
+ it("should skip disabled subscribers", () => {
76
+ sub2.enabledKinds = new Set(["model.call"]); // not enabled for thread
77
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
78
+ composite.enter(spanId);
79
+ expect(sub1.entered.size).toBe(1);
80
+ expect(sub2.entered.size).toBe(0);
81
+ });
82
+ });
83
+ describe("record", () => {
84
+ it("should dispatch to all subscribers", () => {
85
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
86
+ composite.record(spanId, { state: "running" });
87
+ const sub1SpanId = [...sub1.spans.keys()][0];
88
+ const sub2SpanId = [...sub2.spans.keys()][0];
89
+ expect(sub1.getRecorded(sub1SpanId)).toHaveLength(1);
90
+ expect(sub2.getRecorded(sub2SpanId)).toHaveLength(1);
91
+ });
92
+ });
93
+ describe("error", () => {
94
+ it("should dispatch to all subscribers", () => {
95
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
96
+ const err = new Error("test");
97
+ composite.error(spanId, err);
98
+ const sub1SpanId = [...sub1.spans.keys()][0];
99
+ const sub2SpanId = [...sub2.spans.keys()][0];
100
+ expect(sub1.errors.get(sub1SpanId)).toHaveLength(1);
101
+ expect(sub2.errors.get(sub2SpanId)).toHaveLength(1);
102
+ });
103
+ });
104
+ describe("close", () => {
105
+ it("should dispatch to all subscribers and clean up", () => {
106
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
107
+ composite.close(spanId);
108
+ expect(sub1.closed.size).toBe(1);
109
+ expect(sub2.closed.size).toBe(1);
110
+ });
111
+ });
112
+ describe("event", () => {
113
+ it("should dispatch to all subscribers", () => {
114
+ composite.event({ kind: "thread.error", message: "test" }, null);
115
+ expect(sub1.events).toHaveLength(1);
116
+ expect(sub2.events).toHaveLength(1);
117
+ });
118
+ it("should map parent span IDs correctly", () => {
119
+ const spanId = composite.span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
120
+ composite.event({ kind: "thread.error", message: "test" }, spanId);
121
+ const sub1SpanId = [...sub1.spans.keys()][0];
122
+ const sub2SpanId = [...sub2.spans.keys()][0];
123
+ expect(sub1.events[0].parent).toBe(sub1SpanId);
124
+ expect(sub2.events[0].parent).toBe(sub2SpanId);
125
+ });
126
+ it("should handle null parent", () => {
127
+ composite.event({ kind: "thread.error", message: "test" }, null);
128
+ expect(sub1.events[0].parent).toBeNull();
129
+ expect(sub2.events[0].parent).toBeNull();
130
+ });
131
+ });
132
+ describe("flush", () => {
133
+ it("should flush all subscribers", async () => {
134
+ await composite.flush();
135
+ expect(sub1.calls.some((c) => c.method === "flush")).toBe(true);
136
+ expect(sub2.calls.some((c) => c.method === "flush")).toBe(true);
137
+ });
138
+ });
139
+ describe("shutdown", () => {
140
+ it("should shutdown all subscribers", async () => {
141
+ await composite.shutdown(5000);
142
+ expect(sub1.calls.some((c) => c.method === "shutdown")).toBe(true);
143
+ expect(sub2.calls.some((c) => c.method === "shutdown")).toBe(true);
144
+ });
145
+ });
146
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dispatch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.test.d.ts","sourceRoot":"","sources":["../../../src/tracing/__tests__/dispatch.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { span, event, run, current, setSubscriber, clearSubscriber, getSubscriber, } from "../dispatch.js";
3
+ import { NoopSpan, SpanImpl } from "../span.js";
4
+ import { TestSubscriber } from "./helpers.js";
5
+ describe("dispatch", () => {
6
+ let subscriber;
7
+ beforeEach(() => {
8
+ subscriber = new TestSubscriber();
9
+ });
10
+ afterEach(() => {
11
+ clearSubscriber();
12
+ });
13
+ describe("setSubscriber / clearSubscriber / getSubscriber", () => {
14
+ it("should set and get subscriber", () => {
15
+ expect(getSubscriber()).toBeNull();
16
+ setSubscriber(subscriber);
17
+ expect(getSubscriber()).toBe(subscriber);
18
+ });
19
+ it("should throw if subscriber already set", () => {
20
+ setSubscriber(subscriber);
21
+ expect(() => setSubscriber(new TestSubscriber())).toThrow("Global subscriber already set");
22
+ });
23
+ it("should allow re-setting after clear", () => {
24
+ setSubscriber(subscriber);
25
+ clearSubscriber();
26
+ expect(getSubscriber()).toBeNull();
27
+ const newSubscriber = new TestSubscriber();
28
+ setSubscriber(newSubscriber);
29
+ expect(getSubscriber()).toBe(newSubscriber);
30
+ });
31
+ });
32
+ describe("span", () => {
33
+ it("should return NoopSpan when no subscriber is set", () => {
34
+ const s = span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" });
35
+ expect(s).toBeInstanceOf(NoopSpan);
36
+ expect(s.noop()).toBe(true);
37
+ });
38
+ it("should return NoopSpan when subscriber.enabled returns false", () => {
39
+ subscriber.enabledKinds = new Set(["model.call"]); // only model.call enabled
40
+ setSubscriber(subscriber);
41
+ const s = span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" });
42
+ expect(s).toBeInstanceOf(NoopSpan);
43
+ expect(subscriber.spans.size).toBe(0);
44
+ });
45
+ it("should return SpanImpl when subscriber is set and enabled", () => {
46
+ setSubscriber(subscriber);
47
+ const s = span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" });
48
+ expect(s).toBeInstanceOf(SpanImpl);
49
+ expect(s.noop()).toBe(false);
50
+ expect(s.id).toBeDefined();
51
+ });
52
+ it("should pass span data to subscriber", () => {
53
+ setSubscriber(subscriber);
54
+ const data = { kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" };
55
+ span(data);
56
+ expect(subscriber.spans.size).toBe(1);
57
+ const [, captured] = [...subscriber.spans.entries()][0];
58
+ expect(captured.data).toEqual(data);
59
+ });
60
+ it("should use null parent when parent=null", () => {
61
+ setSubscriber(subscriber);
62
+ span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
63
+ const [, captured] = [...subscriber.spans.entries()][0];
64
+ expect(captured.parent).toBeNull();
65
+ });
66
+ it("should use explicit parent when provided", () => {
67
+ setSubscriber(subscriber);
68
+ span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, "parent_123");
69
+ const [, captured] = [...subscriber.spans.entries()][0];
70
+ expect(captured.parent).toBe("parent_123");
71
+ });
72
+ it("should resolve parent from context when parent='current' (default)", () => {
73
+ setSubscriber(subscriber);
74
+ // Create parent span
75
+ const parentSpan = span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" }, null);
76
+ // Create child span within run() context
77
+ run(parentSpan.id, () => {
78
+ span({ kind: "model.call", provider: "test", modelId: "m1" });
79
+ });
80
+ const modelSpans = subscriber.spansOfKind("model.call");
81
+ expect(modelSpans).toHaveLength(1);
82
+ expect(modelSpans[0].parent).toBe(parentSpan.id);
83
+ });
84
+ it("should use null parent when parent='current' but no context", () => {
85
+ setSubscriber(subscriber);
86
+ // No run() context
87
+ span({ kind: "thread", threadId: "t1", agentId: "a1", namespace: "ns" });
88
+ const [, captured] = [...subscriber.spans.entries()][0];
89
+ expect(captured.parent).toBeNull();
90
+ });
91
+ });
92
+ describe("run / current", () => {
93
+ it("should return null when no context", () => {
94
+ expect(current()).toBeNull();
95
+ });
96
+ it("should return spanId within run context", () => {
97
+ const result = run("span_123", () => {
98
+ return current();
99
+ });
100
+ expect(result).toBe("span_123");
101
+ });
102
+ it("should return to null after run completes", () => {
103
+ run("span_123", () => {
104
+ expect(current()).toBe("span_123");
105
+ });
106
+ expect(current()).toBeNull();
107
+ });
108
+ it("should support nested run contexts", () => {
109
+ const results = [];
110
+ run("outer", () => {
111
+ results.push(current());
112
+ run("inner", () => {
113
+ results.push(current());
114
+ });
115
+ results.push(current());
116
+ });
117
+ expect(results).toEqual(["outer", "inner", "outer"]);
118
+ });
119
+ it("should handle null spanId in run", () => {
120
+ run("span_123", () => {
121
+ run(null, () => {
122
+ expect(current()).toBeNull();
123
+ });
124
+ });
125
+ });
126
+ });
127
+ describe("event", () => {
128
+ it("should do nothing when no subscriber is set", () => {
129
+ // Should not throw
130
+ event({ kind: "thread.error", message: "test" });
131
+ });
132
+ it("should emit event to subscriber", () => {
133
+ setSubscriber(subscriber);
134
+ event({ kind: "thread.error", message: "test error", stack: "stack" });
135
+ expect(subscriber.events).toHaveLength(1);
136
+ expect(subscriber.events[0].data).toEqual({
137
+ kind: "thread.error",
138
+ message: "test error",
139
+ stack: "stack",
140
+ });
141
+ });
142
+ it("should use null parent when parent=null", () => {
143
+ setSubscriber(subscriber);
144
+ event({ kind: "thread.error", message: "test" }, null);
145
+ expect(subscriber.events[0].parent).toBeNull();
146
+ });
147
+ it("should use explicit parent when provided", () => {
148
+ setSubscriber(subscriber);
149
+ event({ kind: "thread.error", message: "test" }, "parent_123");
150
+ expect(subscriber.events[0].parent).toBe("parent_123");
151
+ });
152
+ it("should resolve parent from context when parent='current' (default)", () => {
153
+ setSubscriber(subscriber);
154
+ run("span_123", () => {
155
+ event({ kind: "thread.error", message: "test" });
156
+ });
157
+ expect(subscriber.events[0].parent).toBe("span_123");
158
+ });
159
+ });
160
+ });
@@ -0,0 +1,69 @@
1
+ import type { SpanId, SpanData, EventData } from "../types.js";
2
+ import type { Subscriber } from "../subscriber.js";
3
+ /**
4
+ * A test subscriber that captures all tracing calls for assertions.
5
+ */
6
+ export declare class TestSubscriber implements Subscriber {
7
+ private nextId;
8
+ spans: Map<string, {
9
+ data: SpanData;
10
+ parent: SpanId | null;
11
+ }>;
12
+ recorded: Map<string, Partial<SpanData>[]>;
13
+ errors: Map<string, Error[]>;
14
+ events: {
15
+ data: EventData;
16
+ parent: SpanId | null;
17
+ }[];
18
+ calls: {
19
+ method: string;
20
+ spanId?: SpanId;
21
+ args?: unknown;
22
+ }[];
23
+ entered: Set<string>;
24
+ exited: Set<string>;
25
+ closed: Set<string>;
26
+ enabledKinds: Set<SpanData["kind"]> | null;
27
+ enabled(data: SpanData): boolean;
28
+ span(data: SpanData, parent: SpanId | null): SpanId;
29
+ enter(spanId: SpanId): void;
30
+ exit(spanId: SpanId): void;
31
+ record(spanId: SpanId, delta: Partial<SpanData>): void;
32
+ error(spanId: SpanId, err: Error): void;
33
+ close(spanId: SpanId): void;
34
+ event(data: EventData, parent: SpanId | null): void;
35
+ flush(): Promise<void>;
36
+ shutdown(_timeout?: number): Promise<void>;
37
+ /**
38
+ * Get all spans of a specific kind.
39
+ */
40
+ spansOfKind<K extends SpanData["kind"]>(kind: K): Array<{
41
+ id: SpanId;
42
+ data: Extract<SpanData, {
43
+ kind: K;
44
+ }>;
45
+ parent: SpanId | null;
46
+ }>;
47
+ /**
48
+ * Get events of a specific kind.
49
+ */
50
+ eventsOfKind<K extends EventData["kind"]>(kind: K): Array<{
51
+ data: Extract<EventData, {
52
+ kind: K;
53
+ }>;
54
+ parent: SpanId | null;
55
+ }>;
56
+ /**
57
+ * Get recorded data for a span.
58
+ */
59
+ getRecorded(spanId: SpanId): Partial<SpanData>[];
60
+ /**
61
+ * Check if a span was fully completed (entered, exited, closed).
62
+ */
63
+ isComplete(spanId: SpanId): boolean;
64
+ /**
65
+ * Reset all captured data.
66
+ */
67
+ reset(): void;
68
+ }
69
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/tracing/__tests__/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;GAEG;AACH,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,MAAM,CAAK;IAGnB,KAAK;cAA2B,QAAQ;gBAAU,MAAM,GAAG,IAAI;OAAM;IACrE,QAAQ,mCAA0C;IAClD,MAAM,uBAA8B;IACpC,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAM;IAG1D,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAM;IAGlE,OAAO,cAAqB;IAC5B,MAAM,cAAqB;IAC3B,MAAM,cAAqB;IAG3B,YAAY,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAQ;IAElD,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO;IAKhC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAOnD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;IAOtD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI;IAOvC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK3B,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD;;OAEG;IACH,WAAW,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,EACpC,IAAI,EAAE,CAAC,GACN,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAUrF;;OAEG;IACH,YAAY,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,EACtC,IAAI,EAAE,CAAC,GACN,KAAK,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE;YAAE,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAO1E;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE;IAIhD;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,KAAK,IAAI,IAAI;CAWd"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * A test subscriber that captures all tracing calls for assertions.
3
+ */
4
+ export class TestSubscriber {
5
+ nextId = 0;
6
+ // Captured data
7
+ spans = new Map();
8
+ recorded = new Map();
9
+ errors = new Map();
10
+ events = [];
11
+ // Call log for verifying order
12
+ calls = [];
13
+ // State tracking
14
+ entered = new Set();
15
+ exited = new Set();
16
+ closed = new Set();
17
+ // Configuration
18
+ enabledKinds = null; // null = all enabled
19
+ enabled(data) {
20
+ if (this.enabledKinds === null)
21
+ return true;
22
+ return this.enabledKinds.has(data.kind);
23
+ }
24
+ span(data, parent) {
25
+ const id = `test_span_${this.nextId++}`;
26
+ this.spans.set(id, { data, parent });
27
+ this.calls.push({ method: "span", spanId: id, args: { data, parent } });
28
+ return id;
29
+ }
30
+ enter(spanId) {
31
+ this.entered.add(spanId);
32
+ this.calls.push({ method: "enter", spanId });
33
+ }
34
+ exit(spanId) {
35
+ this.exited.add(spanId);
36
+ this.calls.push({ method: "exit", spanId });
37
+ }
38
+ record(spanId, delta) {
39
+ const existing = this.recorded.get(spanId) ?? [];
40
+ existing.push(delta);
41
+ this.recorded.set(spanId, existing);
42
+ this.calls.push({ method: "record", spanId, args: delta });
43
+ }
44
+ error(spanId, err) {
45
+ const existing = this.errors.get(spanId) ?? [];
46
+ existing.push(err);
47
+ this.errors.set(spanId, existing);
48
+ this.calls.push({ method: "error", spanId, args: err });
49
+ }
50
+ close(spanId) {
51
+ this.closed.add(spanId);
52
+ this.calls.push({ method: "close", spanId });
53
+ }
54
+ event(data, parent) {
55
+ this.events.push({ data, parent });
56
+ this.calls.push({ method: "event", args: { data, parent } });
57
+ }
58
+ async flush() {
59
+ this.calls.push({ method: "flush" });
60
+ }
61
+ async shutdown(_timeout) {
62
+ this.calls.push({ method: "shutdown" });
63
+ }
64
+ // --- Test helpers ---
65
+ /**
66
+ * Get all spans of a specific kind.
67
+ */
68
+ spansOfKind(kind) {
69
+ const result = [];
70
+ for (const [id, { data, parent }] of this.spans) {
71
+ if (data.kind === kind) {
72
+ result.push({ id, data: data, parent });
73
+ }
74
+ }
75
+ return result;
76
+ }
77
+ /**
78
+ * Get events of a specific kind.
79
+ */
80
+ eventsOfKind(kind) {
81
+ return this.events.filter((e) => e.data.kind === kind);
82
+ }
83
+ /**
84
+ * Get recorded data for a span.
85
+ */
86
+ getRecorded(spanId) {
87
+ return this.recorded.get(spanId) ?? [];
88
+ }
89
+ /**
90
+ * Check if a span was fully completed (entered, exited, closed).
91
+ */
92
+ isComplete(spanId) {
93
+ return this.entered.has(spanId) && this.exited.has(spanId) && this.closed.has(spanId);
94
+ }
95
+ /**
96
+ * Reset all captured data.
97
+ */
98
+ reset() {
99
+ this.nextId = 0;
100
+ this.spans.clear();
101
+ this.recorded.clear();
102
+ this.errors.clear();
103
+ this.events = [];
104
+ this.calls = [];
105
+ this.entered.clear();
106
+ this.exited.clear();
107
+ this.closed.clear();
108
+ }
109
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../src/tracing/__tests__/integration.test.ts"],"names":[],"mappings":""}