autotel-cloudflare 3.0.0 → 4.0.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.
Files changed (73) hide show
  1. package/dist/agents.d.ts +626 -123
  2. package/dist/agents.d.ts.map +1 -1
  3. package/dist/agents.js +260 -171
  4. package/dist/agents.js.map +1 -1
  5. package/package.json +8 -4
  6. package/src/actors/alarms.ts +0 -225
  7. package/src/actors/index.ts +0 -36
  8. package/src/actors/instrument-actor.test.ts +0 -179
  9. package/src/actors/instrument-actor.ts +0 -574
  10. package/src/actors/sockets.ts +0 -217
  11. package/src/actors/storage.ts +0 -263
  12. package/src/actors/traced-handler.ts +0 -300
  13. package/src/actors/types.ts +0 -98
  14. package/src/actors.ts +0 -50
  15. package/src/agents/index.ts +0 -42
  16. package/src/agents/otel-observability.test.ts +0 -336
  17. package/src/agents/otel-observability.ts +0 -474
  18. package/src/agents/types.ts +0 -167
  19. package/src/agents.ts +0 -76
  20. package/src/bindings/ai.test.ts +0 -170
  21. package/src/bindings/ai.ts +0 -73
  22. package/src/bindings/analytics-engine.test.ts +0 -175
  23. package/src/bindings/analytics-engine.ts +0 -78
  24. package/src/bindings/bindings-cache.test.ts +0 -80
  25. package/src/bindings/bindings-detection.test.ts +0 -235
  26. package/src/bindings/bindings-this-binding.test.ts +0 -294
  27. package/src/bindings/bindings.ts +0 -720
  28. package/src/bindings/browser-rendering.test.ts +0 -160
  29. package/src/bindings/browser-rendering.ts +0 -70
  30. package/src/bindings/common.ts +0 -84
  31. package/src/bindings/hyperdrive.test.ts +0 -176
  32. package/src/bindings/hyperdrive.ts +0 -74
  33. package/src/bindings/images.test.ts +0 -262
  34. package/src/bindings/images.ts +0 -182
  35. package/src/bindings/index.ts +0 -20
  36. package/src/bindings/queue-producer.test.ts +0 -224
  37. package/src/bindings/queue-producer.ts +0 -105
  38. package/src/bindings/rate-limiter.test.ts +0 -140
  39. package/src/bindings/rate-limiter.ts +0 -69
  40. package/src/bindings/vectorize.test.ts +0 -362
  41. package/src/bindings/vectorize.ts +0 -86
  42. package/src/bindings.ts +0 -6
  43. package/src/events.ts +0 -6
  44. package/src/execution-logger.test.ts +0 -127
  45. package/src/execution-logger.ts +0 -112
  46. package/src/global/cache.test.ts +0 -292
  47. package/src/global/cache.ts +0 -164
  48. package/src/global/fetch.test.ts +0 -399
  49. package/src/global/fetch.ts +0 -136
  50. package/src/global/index.ts +0 -7
  51. package/src/handlers/durable-objects.test.ts +0 -524
  52. package/src/handlers/durable-objects.ts +0 -250
  53. package/src/handlers/index.ts +0 -6
  54. package/src/handlers/workflows.test.ts +0 -411
  55. package/src/handlers/workflows.ts +0 -345
  56. package/src/handlers.ts +0 -6
  57. package/src/index.ts +0 -91
  58. package/src/logger.ts +0 -15
  59. package/src/native/native-tracing.test.ts +0 -54
  60. package/src/native/native-tracing.ts +0 -83
  61. package/src/native.ts +0 -12
  62. package/src/parse-error.ts +0 -1
  63. package/src/sampling.ts +0 -6
  64. package/src/testing.ts +0 -6
  65. package/src/wrappers/cf-attributes.test.ts +0 -334
  66. package/src/wrappers/define-worker-fetch.test.ts +0 -102
  67. package/src/wrappers/define-worker-fetch.ts +0 -71
  68. package/src/wrappers/index.ts +0 -13
  69. package/src/wrappers/instrument.integration.test.ts +0 -578
  70. package/src/wrappers/instrument.ts +0 -806
  71. package/src/wrappers/native-instrument.test.ts +0 -153
  72. package/src/wrappers/wrap-do.ts +0 -34
  73. package/src/wrappers/wrap-module.ts +0 -37
@@ -1,524 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import { instrumentDO } from './durable-objects';
3
- import { trace, SpanStatusCode, SpanKind } from '@opentelemetry/api';
4
- import type { DurableObjectState } from '@cloudflare/workers-types';
5
-
6
- describe('Durable Objects Instrumentation', () => {
7
- let mockTracer: any;
8
- let mockSpan: any;
9
- let getTracerSpy: any;
10
-
11
- beforeEach(() => {
12
- mockSpan = {
13
- spanContext: () => ({
14
- traceId: 'test-trace-id',
15
- spanId: 'test-span-id',
16
- traceFlags: 1,
17
- }),
18
- setAttribute: vi.fn(),
19
- setAttributes: vi.fn(),
20
- setStatus: vi.fn(),
21
- recordException: vi.fn(),
22
- end: vi.fn(),
23
- isRecording: () => true,
24
- updateName: vi.fn(),
25
- addEvent: vi.fn(),
26
- };
27
-
28
- mockTracer = {
29
- startActiveSpan: vi.fn((name, options, context, fn) => {
30
- if (typeof options === 'function') {
31
- return options(mockSpan);
32
- }
33
- if (typeof context === 'function') {
34
- return context(mockSpan);
35
- }
36
- if (typeof fn === 'function') {
37
- return fn(mockSpan);
38
- }
39
- return Promise.resolve();
40
- }),
41
- };
42
-
43
- getTracerSpy = vi.spyOn(trace, 'getTracer').mockReturnValue(mockTracer as any);
44
- });
45
-
46
- afterEach(() => {
47
- getTracerSpy.mockRestore();
48
- });
49
-
50
- describe('instrumentDO()', () => {
51
- it('should wrap DO class constructor', () => {
52
- class TestDO {
53
- constructor(public state: DurableObjectState, public env: any) {}
54
-
55
- async fetch(request: Request) {
56
- return new Response('Hello');
57
- }
58
- }
59
-
60
- const InstrumentedDO = instrumentDO(TestDO, {
61
- service: { name: 'test-do' },
62
- });
63
-
64
- expect(InstrumentedDO).toBeDefined();
65
- expect(typeof InstrumentedDO).toBe('function');
66
- });
67
-
68
- it('should create DO instance with instrumentation', () => {
69
- class TestDO {
70
- constructor(public state: DurableObjectState, public env: any) {}
71
-
72
- async fetch(request: Request) {
73
- return new Response('Hello');
74
- }
75
- }
76
-
77
- const InstrumentedDO = instrumentDO(TestDO, {
78
- service: { name: 'test-do' },
79
- });
80
-
81
- const mockState = {
82
- id: {
83
- toString: () => 'test-id-123',
84
- name: 'test-do-name',
85
- equals: () => false,
86
- },
87
- storage: {},
88
- blockConcurrencyWhile: vi.fn(),
89
- waitUntil: vi.fn(),
90
- } as unknown as DurableObjectState;
91
-
92
- const mockEnv = {};
93
-
94
- const instance = new InstrumentedDO(mockState, mockEnv);
95
-
96
- expect(instance).toBeDefined();
97
- expect(typeof instance.fetch).toBe('function');
98
- });
99
-
100
- it('should accept static config', () => {
101
- class TestDO {
102
- constructor(public state: DurableObjectState, public env: any) {}
103
-
104
- async fetch(request: Request) {
105
- return new Response('Hello');
106
- }
107
- }
108
-
109
- const InstrumentedDO = instrumentDO(TestDO, {
110
- service: { name: 'test-do', version: '1.0.0' },
111
- exporter: {
112
- url: 'http://localhost:4318/v1/traces',
113
- },
114
- });
115
-
116
- expect(InstrumentedDO).toBeDefined();
117
- });
118
-
119
- it('should accept config function', () => {
120
- class TestDO {
121
- constructor(public state: DurableObjectState, public env: any) {}
122
-
123
- async fetch(request: Request) {
124
- return new Response('Hello');
125
- }
126
- }
127
-
128
- interface Env {
129
- OTLP_ENDPOINT: string;
130
- }
131
-
132
- const InstrumentedDO = instrumentDO(TestDO, (env: Env) => ({
133
- service: { name: 'test-do' },
134
- exporter: {
135
- url: env.OTLP_ENDPOINT,
136
- },
137
- }));
138
-
139
- expect(InstrumentedDO).toBeDefined();
140
- });
141
- });
142
-
143
- describe('fetch() instrumentation', () => {
144
- it('should create span for fetch() calls', async () => {
145
- class TestDO {
146
- constructor(public state: DurableObjectState, public env: any) {}
147
-
148
- async fetch(request: Request) {
149
- return new Response('Hello from DO');
150
- }
151
- }
152
-
153
- const InstrumentedDO = instrumentDO(TestDO, {
154
- service: { name: 'test-do' },
155
- });
156
-
157
- const mockState = {
158
- id: {
159
- toString: () => 'test-id-123',
160
- name: 'test-do-name',
161
- equals: () => false,
162
- },
163
- storage: {},
164
- blockConcurrencyWhile: vi.fn(),
165
- waitUntil: vi.fn(),
166
- } as unknown as DurableObjectState;
167
-
168
- const instance = new InstrumentedDO(mockState, {});
169
- const request = new Request('http://example.com/test');
170
- const response = await instance.fetch(request);
171
-
172
- expect(mockTracer.startActiveSpan).toHaveBeenCalled();
173
-
174
- const spanName = mockTracer.startActiveSpan.mock.calls[0][0];
175
- expect(spanName).toContain('DO');
176
- expect(spanName).toContain('test-do-name');
177
- expect(spanName).toContain('GET');
178
-
179
- const text = await response.text();
180
- expect(text).toBe('Hello from DO');
181
- });
182
-
183
- it('should add HTTP attributes (method, URL, status)', async () => {
184
- class TestDO {
185
- constructor(public state: DurableObjectState, public env: any) {}
186
-
187
- async fetch(request: Request) {
188
- return new Response('OK', { status: 200 });
189
- }
190
- }
191
-
192
- const InstrumentedDO = instrumentDO(TestDO, {
193
- service: { name: 'test-do' },
194
- });
195
-
196
- const mockState = {
197
- id: {
198
- toString: () => 'test-id-123',
199
- name: 'counter',
200
- equals: () => false,
201
- },
202
- storage: {},
203
- blockConcurrencyWhile: vi.fn(),
204
- waitUntil: vi.fn(),
205
- } as unknown as DurableObjectState;
206
-
207
- const instance = new InstrumentedDO(mockState, {});
208
- const request = new Request('http://example.com/increment', { method: 'POST' });
209
- await instance.fetch(request);
210
-
211
- const options = mockTracer.startActiveSpan.mock.calls[0][1];
212
- expect(options.kind).toBe(SpanKind.SERVER);
213
- expect(options.attributes['http.request.method']).toBe('POST');
214
- expect(options.attributes['url.full']).toBe('http://example.com/increment');
215
- });
216
-
217
- it('should add DO-specific attributes (do.id, do.id.name)', async () => {
218
- class TestDO {
219
- constructor(public state: DurableObjectState, public env: any) {}
220
-
221
- async fetch(request: Request) {
222
- return new Response('OK');
223
- }
224
- }
225
-
226
- const InstrumentedDO = instrumentDO(TestDO, {
227
- service: { name: 'test-do' },
228
- });
229
-
230
- const mockState = {
231
- id: {
232
- toString: () => 'unique-do-id-456',
233
- name: 'my-counter',
234
- equals: () => false,
235
- },
236
- storage: {},
237
- blockConcurrencyWhile: vi.fn(),
238
- waitUntil: vi.fn(),
239
- } as unknown as DurableObjectState;
240
-
241
- const instance = new InstrumentedDO(mockState, {});
242
- const request = new Request('http://example.com/test');
243
- await instance.fetch(request);
244
-
245
- const options = mockTracer.startActiveSpan.mock.calls[0][1];
246
- expect(options.attributes['do.id']).toBe('unique-do-id-456');
247
- expect(options.attributes['do.id.name']).toBe('my-counter');
248
- expect(options.attributes['faas.trigger']).toBe('http');
249
- });
250
-
251
- it('should track cold starts (first call = true, subsequent = false)', async () => {
252
- class TestDO {
253
- constructor(public state: DurableObjectState, public env: any) {}
254
-
255
- async fetch(request: Request) {
256
- return new Response('OK');
257
- }
258
- }
259
-
260
- const InstrumentedDO = instrumentDO(TestDO, {
261
- service: { name: 'test-do' },
262
- });
263
-
264
- const mockState = {
265
- id: {
266
- toString: () => 'test-id',
267
- name: 'test',
268
- equals: () => false,
269
- },
270
- storage: {},
271
- blockConcurrencyWhile: vi.fn(),
272
- waitUntil: vi.fn(),
273
- } as unknown as DurableObjectState;
274
-
275
- const instance = new InstrumentedDO(mockState, {});
276
- const request = new Request('http://example.com/test');
277
-
278
- // First call - should be cold start
279
- await instance.fetch(request);
280
- const firstCallOptions = mockTracer.startActiveSpan.mock.calls[0][1];
281
- expect(firstCallOptions.attributes['faas.coldstart']).toBe(true);
282
-
283
- // Second call - should NOT be cold start
284
- await instance.fetch(request);
285
- const secondCallOptions = mockTracer.startActiveSpan.mock.calls[1][1];
286
- expect(secondCallOptions.attributes['faas.coldstart']).toBe(false);
287
- });
288
-
289
- it('should handle fetch() errors', async () => {
290
- class TestDO {
291
- constructor(public state: DurableObjectState, public env: any) {}
292
-
293
- async fetch(request: Request) {
294
- throw new Error('DO error');
295
- }
296
- }
297
-
298
- const InstrumentedDO = instrumentDO(TestDO, {
299
- service: { name: 'test-do' },
300
- });
301
-
302
- const mockState = {
303
- id: {
304
- toString: () => 'test-id',
305
- name: 'test',
306
- equals: () => false,
307
- },
308
- storage: {},
309
- blockConcurrencyWhile: vi.fn(),
310
- waitUntil: vi.fn(),
311
- } as unknown as DurableObjectState;
312
-
313
- const instance = new InstrumentedDO(mockState, {});
314
- const request = new Request('http://example.com/test');
315
-
316
- await expect(instance.fetch(request)).rejects.toThrow('DO error');
317
-
318
- expect(mockSpan.recordException).toHaveBeenCalled();
319
- expect(mockSpan.setStatus).toHaveBeenCalledWith({
320
- code: SpanStatusCode.ERROR,
321
- message: 'DO error',
322
- });
323
- expect(mockSpan.end).toHaveBeenCalled();
324
- });
325
-
326
- it('should preserve "this" binding', async () => {
327
- class TestDO {
328
- private counter = 0;
329
-
330
- constructor(public state: DurableObjectState, public env: any) {}
331
-
332
- async fetch(request: Request) {
333
- this.counter++;
334
- return new Response(`Count: ${this.counter}`);
335
- }
336
- }
337
-
338
- const InstrumentedDO = instrumentDO(TestDO, {
339
- service: { name: 'test-do' },
340
- });
341
-
342
- const mockState = {
343
- id: {
344
- toString: () => 'test-id',
345
- name: 'test',
346
- equals: () => false,
347
- },
348
- storage: {},
349
- blockConcurrencyWhile: vi.fn(),
350
- waitUntil: vi.fn(),
351
- } as unknown as DurableObjectState;
352
-
353
- const instance = new InstrumentedDO(mockState, {});
354
-
355
- const response1 = await instance.fetch(new Request('http://example.com/test'));
356
- const text1 = await response1.text();
357
- expect(text1).toBe('Count: 1');
358
-
359
- const response2 = await instance.fetch(new Request('http://example.com/test'));
360
- const text2 = await response2.text();
361
- expect(text2).toBe('Count: 2');
362
- });
363
- });
364
-
365
- describe('alarm() instrumentation', () => {
366
- it('should create span for alarm() calls', async () => {
367
- class TestDO {
368
- constructor(public state: DurableObjectState, public env: any) {}
369
-
370
- async fetch(request: Request) {
371
- return new Response('OK');
372
- }
373
-
374
- async alarm() {
375
- // Alarm logic
376
- }
377
- }
378
-
379
- const InstrumentedDO = instrumentDO(TestDO, {
380
- service: { name: 'test-do' },
381
- });
382
-
383
- const mockState = {
384
- id: {
385
- toString: () => 'test-id-alarm',
386
- name: 'alarm-do',
387
- equals: () => false,
388
- },
389
- storage: {},
390
- blockConcurrencyWhile: vi.fn(),
391
- waitUntil: vi.fn(),
392
- } as unknown as DurableObjectState;
393
-
394
- const instance = new InstrumentedDO(mockState, {});
395
- await instance.alarm();
396
-
397
- expect(mockTracer.startActiveSpan).toHaveBeenCalled();
398
-
399
- const spanName = mockTracer.startActiveSpan.mock.calls[0][0];
400
- expect(spanName).toContain('DO');
401
- expect(spanName).toContain('alarm-do');
402
- expect(spanName).toContain('alarm');
403
- });
404
-
405
- it('should add DO-specific attributes for alarm()', async () => {
406
- class TestDO {
407
- constructor(public state: DurableObjectState, public env: any) {}
408
-
409
- async fetch(request: Request) {
410
- return new Response('OK');
411
- }
412
-
413
- async alarm() {
414
- // Alarm logic
415
- }
416
- }
417
-
418
- const InstrumentedDO = instrumentDO(TestDO, {
419
- service: { name: 'test-do' },
420
- });
421
-
422
- const mockState = {
423
- id: {
424
- toString: () => 'alarm-id-123',
425
- name: 'cleanup-do',
426
- equals: () => false,
427
- },
428
- storage: {},
429
- blockConcurrencyWhile: vi.fn(),
430
- waitUntil: vi.fn(),
431
- } as unknown as DurableObjectState;
432
-
433
- const instance = new InstrumentedDO(mockState, {});
434
- await instance.alarm();
435
-
436
- const options = mockTracer.startActiveSpan.mock.calls[0][1];
437
- expect(options.kind).toBe(SpanKind.INTERNAL);
438
- expect(options.attributes['do.id']).toBe('alarm-id-123');
439
- expect(options.attributes['do.id.name']).toBe('cleanup-do');
440
- expect(options.attributes['faas.trigger']).toBe('timer');
441
- });
442
-
443
- it('should track cold starts for alarm()', async () => {
444
- class TestDO {
445
- constructor(public state: DurableObjectState, public env: any) {}
446
-
447
- async fetch(request: Request) {
448
- return new Response('OK');
449
- }
450
-
451
- async alarm() {
452
- // Alarm logic
453
- }
454
- }
455
-
456
- const InstrumentedDO = instrumentDO(TestDO, {
457
- service: { name: 'test-do' },
458
- });
459
-
460
- const mockState = {
461
- id: {
462
- toString: () => 'test-id',
463
- name: 'test',
464
- equals: () => false,
465
- },
466
- storage: {},
467
- blockConcurrencyWhile: vi.fn(),
468
- waitUntil: vi.fn(),
469
- } as unknown as DurableObjectState;
470
-
471
- const instance = new InstrumentedDO(mockState, {});
472
-
473
- // First alarm call - should be cold start
474
- await instance.alarm();
475
- const firstCallOptions = mockTracer.startActiveSpan.mock.calls[0][1];
476
- expect(firstCallOptions.attributes['faas.coldstart']).toBe(true);
477
-
478
- // Second alarm call - should NOT be cold start
479
- await instance.alarm();
480
- const secondCallOptions = mockTracer.startActiveSpan.mock.calls[1][1];
481
- expect(secondCallOptions.attributes['faas.coldstart']).toBe(false);
482
- });
483
-
484
- it('should handle alarm() errors', async () => {
485
- class TestDO {
486
- constructor(public state: DurableObjectState, public env: any) {}
487
-
488
- async fetch(request: Request) {
489
- return new Response('OK');
490
- }
491
-
492
- async alarm() {
493
- throw new Error('Alarm failed');
494
- }
495
- }
496
-
497
- const InstrumentedDO = instrumentDO(TestDO, {
498
- service: { name: 'test-do' },
499
- });
500
-
501
- const mockState = {
502
- id: {
503
- toString: () => 'test-id',
504
- name: 'test',
505
- equals: () => false,
506
- },
507
- storage: {},
508
- blockConcurrencyWhile: vi.fn(),
509
- waitUntil: vi.fn(),
510
- } as unknown as DurableObjectState;
511
-
512
- const instance = new InstrumentedDO(mockState, {});
513
-
514
- await expect(instance.alarm()).rejects.toThrow('Alarm failed');
515
-
516
- expect(mockSpan.recordException).toHaveBeenCalled();
517
- expect(mockSpan.setStatus).toHaveBeenCalledWith({
518
- code: SpanStatusCode.ERROR,
519
- message: 'Alarm failed',
520
- });
521
- expect(mockSpan.end).toHaveBeenCalled();
522
- });
523
- });
524
- });