autotel-cloudflare 2.12.0 → 2.14.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 (44) hide show
  1. package/dist/actors.js +1 -1
  2. package/dist/bindings.d.ts +113 -1
  3. package/dist/bindings.js +2 -2
  4. package/dist/chunk-4UG2QCPQ.js +1060 -0
  5. package/dist/chunk-4UG2QCPQ.js.map +1 -0
  6. package/dist/{chunk-5NL62W4L.js → chunk-O4IYKWPJ.js} +8 -3
  7. package/dist/chunk-O4IYKWPJ.js.map +1 -0
  8. package/dist/{chunk-ADWSZ5GY.js → chunk-WDNZVVRW.js} +8 -9
  9. package/dist/chunk-WDNZVVRW.js.map +1 -0
  10. package/dist/handlers.d.ts +5 -14
  11. package/dist/handlers.js +2 -2
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +34 -6
  14. package/dist/index.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/bindings/ai.test.ts +156 -0
  17. package/src/bindings/ai.ts +71 -0
  18. package/src/bindings/analytics-engine.test.ts +160 -0
  19. package/src/bindings/analytics-engine.ts +78 -0
  20. package/src/bindings/bindings-detection.test.ts +235 -0
  21. package/src/bindings/bindings.ts +98 -47
  22. package/src/bindings/browser-rendering.test.ts +144 -0
  23. package/src/bindings/browser-rendering.ts +70 -0
  24. package/src/bindings/common.ts +9 -0
  25. package/src/bindings/hyperdrive.test.ts +154 -0
  26. package/src/bindings/hyperdrive.ts +74 -0
  27. package/src/bindings/images.test.ts +229 -0
  28. package/src/bindings/images.ts +182 -0
  29. package/src/bindings/index.ts +8 -0
  30. package/src/bindings/queue-producer.test.ts +192 -0
  31. package/src/bindings/queue-producer.ts +105 -0
  32. package/src/bindings/rate-limiter.test.ts +124 -0
  33. package/src/bindings/rate-limiter.ts +69 -0
  34. package/src/bindings/vectorize.test.ts +340 -0
  35. package/src/bindings/vectorize.ts +86 -0
  36. package/src/handlers/workflows.test.ts +325 -0
  37. package/src/handlers/workflows.ts +51 -41
  38. package/src/index.ts +8 -0
  39. package/src/wrappers/cf-attributes.test.ts +275 -0
  40. package/src/wrappers/instrument.ts +38 -0
  41. package/dist/chunk-5NL62W4L.js.map +0 -1
  42. package/dist/chunk-ADWSZ5GY.js.map +0 -1
  43. package/dist/chunk-UPQE3J4I.js +0 -520
  44. package/dist/chunk-UPQE3J4I.js.map +0 -1
@@ -0,0 +1,325 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { instrumentWorkflow } from './workflows';
3
+ import { trace, SpanStatusCode, SpanKind } from '@opentelemetry/api';
4
+
5
+ describe('Workflow Instrumentation', () => {
6
+ let mockTracer: any;
7
+ let mockSpan: any;
8
+ let getTracerSpy: any;
9
+
10
+ beforeEach(() => {
11
+ mockSpan = {
12
+ spanContext: () => ({
13
+ traceId: 'test-trace-id',
14
+ spanId: 'test-span-id',
15
+ traceFlags: 1,
16
+ }),
17
+ setAttribute: vi.fn(),
18
+ setAttributes: vi.fn(),
19
+ setStatus: vi.fn(),
20
+ recordException: vi.fn(),
21
+ end: vi.fn(),
22
+ isRecording: () => true,
23
+ updateName: vi.fn(),
24
+ addEvent: vi.fn(),
25
+ };
26
+
27
+ mockTracer = {
28
+ startActiveSpan: vi.fn((name, options, context, fn) => {
29
+ if (typeof options === 'function') return options(mockSpan);
30
+ if (typeof context === 'function') return context(mockSpan);
31
+ if (typeof fn === 'function') return fn(mockSpan);
32
+ return Promise.resolve();
33
+ }),
34
+ };
35
+
36
+ getTracerSpy = vi.spyOn(trace, 'getTracer').mockReturnValue(mockTracer as any);
37
+ });
38
+
39
+ afterEach(() => {
40
+ getTracerSpy.mockRestore();
41
+ });
42
+
43
+ describe('instrumentWorkflow()', () => {
44
+ it('should wrap workflow class constructor', () => {
45
+ class TestWorkflow {
46
+ constructor(public ctx: any, public env: any) {}
47
+ async run() {}
48
+ }
49
+
50
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'test-workflow', {
51
+ service: { name: 'test' },
52
+ });
53
+
54
+ expect(Instrumented).toBeDefined();
55
+ expect(typeof Instrumented).toBe('function');
56
+ });
57
+
58
+ it('should create workflow instance with instrumented run()', () => {
59
+ class TestWorkflow {
60
+ constructor(public ctx: any, public env: any) {}
61
+ async run() { return 'done'; }
62
+ }
63
+
64
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'test-workflow', {
65
+ service: { name: 'test' },
66
+ });
67
+
68
+ const instance = new Instrumented({}, {});
69
+
70
+ expect(instance).toBeDefined();
71
+ expect(typeof instance.run).toBe('function');
72
+ });
73
+
74
+ it('should accept static config', () => {
75
+ class TestWorkflow {
76
+ constructor(public ctx: any, public env: any) {}
77
+ async run() {}
78
+ }
79
+
80
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'test-workflow', {
81
+ service: { name: 'test', version: '1.0.0' },
82
+ exporter: { url: 'http://localhost:4318/v1/traces' },
83
+ });
84
+
85
+ expect(Instrumented).toBeDefined();
86
+ });
87
+
88
+ it('should accept config function', () => {
89
+ class TestWorkflow {
90
+ constructor(public ctx: any, public env: any) {}
91
+ async run() {}
92
+ }
93
+
94
+ interface Env {
95
+ OTLP_ENDPOINT: string;
96
+ }
97
+
98
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'test-workflow', (env: Env) => ({
99
+ service: { name: 'test' },
100
+ exporter: { url: env.OTLP_ENDPOINT },
101
+ }));
102
+
103
+ expect(Instrumented).toBeDefined();
104
+ });
105
+ });
106
+
107
+ describe('run() instrumentation', () => {
108
+ it('should preserve run() return value', async () => {
109
+ const output = { status: 'ok', orderId: 'ord-123' };
110
+
111
+ class TestWorkflow {
112
+ constructor(public ctx: any, public env: any) {}
113
+ async run(event: any, step: any) {
114
+ return output;
115
+ }
116
+ }
117
+
118
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'return-test', {
119
+ service: { name: 'test' },
120
+ });
121
+
122
+ const instance = new Instrumented({}, {});
123
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-return' };
124
+ const step = { do: vi.fn(), sleep: vi.fn(), sleepUntil: vi.fn() };
125
+
126
+ await expect(instance.run(event, step)).resolves.toEqual(output);
127
+ });
128
+
129
+ it('should create span for run() with workflow attributes', async () => {
130
+ class TestWorkflow {
131
+ constructor(public ctx: any, public env: any) {}
132
+ async run(event: any, step: any) {}
133
+ }
134
+
135
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'test-workflow', {
136
+ service: { name: 'test' },
137
+ });
138
+
139
+ const instance = new Instrumented({}, {});
140
+ const event = { payload: { foo: 'bar' }, timestamp: new Date(), instanceId: 'wf-123' };
141
+ const step = { do: vi.fn(), sleep: vi.fn(), sleepUntil: vi.fn() };
142
+
143
+ await instance.run(event, step);
144
+
145
+ expect(mockTracer.startActiveSpan).toHaveBeenCalled();
146
+
147
+ const spanName = mockTracer.startActiveSpan.mock.calls[0][0];
148
+ expect(spanName).toBe('Workflow test-workflow: run');
149
+
150
+ const options = mockTracer.startActiveSpan.mock.calls[0][1];
151
+ expect(options.kind).toBe(SpanKind.INTERNAL);
152
+ expect(options.attributes['workflow.name']).toBe('test-workflow');
153
+ expect(options.attributes['workflow.instance_id']).toBe('wf-123');
154
+ expect(options.attributes['faas.trigger']).toBe('workflow');
155
+ });
156
+
157
+ it('should track cold starts', async () => {
158
+ class TestWorkflow {
159
+ constructor(public ctx: any, public env: any) {}
160
+ async run(event: any, step: any) {}
161
+ }
162
+
163
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'cold-test', {
164
+ service: { name: 'test' },
165
+ });
166
+
167
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-1' };
168
+ const step = { do: vi.fn(), sleep: vi.fn(), sleepUntil: vi.fn() };
169
+
170
+ const instance1 = new Instrumented({}, {});
171
+ await instance1.run(event, step);
172
+ const firstOptions = mockTracer.startActiveSpan.mock.calls[0][1];
173
+ expect(firstOptions.attributes['faas.coldstart']).toBe(true);
174
+
175
+ const instance2 = new Instrumented({}, {});
176
+ await instance2.run(event, step);
177
+ const secondOptions = mockTracer.startActiveSpan.mock.calls[1][1];
178
+ expect(secondOptions.attributes['faas.coldstart']).toBe(false);
179
+ });
180
+
181
+ it('should handle run() errors', async () => {
182
+ class TestWorkflow {
183
+ constructor(public ctx: any, public env: any) {}
184
+ async run() {
185
+ throw new Error('Workflow failed');
186
+ }
187
+ }
188
+
189
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'error-test', {
190
+ service: { name: 'test' },
191
+ });
192
+
193
+ const instance = new Instrumented({}, {});
194
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-err' };
195
+ const step = { do: vi.fn(), sleep: vi.fn(), sleepUntil: vi.fn() };
196
+
197
+ await expect(instance.run(event, step)).rejects.toThrow('Workflow failed');
198
+
199
+ expect(mockSpan.recordException).toHaveBeenCalled();
200
+ expect(mockSpan.setStatus).toHaveBeenCalledWith({
201
+ code: SpanStatusCode.ERROR,
202
+ message: 'Workflow failed',
203
+ });
204
+ expect(mockSpan.end).toHaveBeenCalled();
205
+ });
206
+ });
207
+
208
+ describe('step.do() instrumentation', () => {
209
+ it('should create span for step.do() calls', async () => {
210
+ const stepDoResult = { paymentId: 'pay_123' };
211
+ const mockStepDo = vi.fn().mockResolvedValue(stepDoResult);
212
+
213
+ class TestWorkflow {
214
+ constructor(public ctx: any, public env: any) {}
215
+ async run(event: any, step: any) {
216
+ return await step.do('process payment', async () => stepDoResult);
217
+ }
218
+ }
219
+
220
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'step-test', {
221
+ service: { name: 'test' },
222
+ });
223
+
224
+ const instance = new Instrumented({}, {});
225
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-step' };
226
+ const step = {
227
+ do: vi.fn(async (_name: string, cb: () => Promise<any>) => cb()),
228
+ sleep: vi.fn(),
229
+ sleepUntil: vi.fn(),
230
+ };
231
+
232
+ await instance.run(event, step);
233
+
234
+ // Should have spans for both run() and step.do()
235
+ expect(mockTracer.startActiveSpan.mock.calls.length).toBeGreaterThanOrEqual(2);
236
+
237
+ const stepSpanCall = mockTracer.startActiveSpan.mock.calls[1];
238
+ expect(stepSpanCall[0]).toBe('Workflow step-test: process payment');
239
+ expect(stepSpanCall[1].attributes['workflow.step.name']).toBe('process payment');
240
+ expect(stepSpanCall[1].attributes['workflow.name']).toBe('step-test');
241
+ });
242
+
243
+ it('should handle step.do() errors', async () => {
244
+ class TestWorkflow {
245
+ constructor(public ctx: any, public env: any) {}
246
+ async run(event: any, step: any) {
247
+ await step.do('failing step', async () => {
248
+ throw new Error('Step failed');
249
+ });
250
+ }
251
+ }
252
+
253
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'step-err', {
254
+ service: { name: 'test' },
255
+ });
256
+
257
+ const instance = new Instrumented({}, {});
258
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-step-err' };
259
+ const step = {
260
+ do: vi.fn(async (_name: string, cb: () => Promise<any>) => cb()),
261
+ sleep: vi.fn(),
262
+ sleepUntil: vi.fn(),
263
+ };
264
+
265
+ await expect(instance.run(event, step)).rejects.toThrow('Step failed');
266
+
267
+ expect(mockSpan.recordException).toHaveBeenCalled();
268
+ expect(mockSpan.end).toHaveBeenCalled();
269
+ });
270
+ });
271
+
272
+ describe('step.sleep() instrumentation', () => {
273
+ it('should create span for step.sleep() calls', async () => {
274
+ class TestWorkflow {
275
+ constructor(public ctx: any, public env: any) {}
276
+ async run(event: any, step: any) {
277
+ await step.sleep('wait for settlement', '2 hours');
278
+ }
279
+ }
280
+
281
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'sleep-test', {
282
+ service: { name: 'test' },
283
+ });
284
+
285
+ const instance = new Instrumented({}, {});
286
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-sleep' };
287
+ const step = {
288
+ do: vi.fn(),
289
+ sleep: vi.fn().mockResolvedValue(undefined),
290
+ sleepUntil: vi.fn(),
291
+ };
292
+
293
+ await instance.run(event, step);
294
+
295
+ const sleepSpanCall = mockTracer.startActiveSpan.mock.calls[1];
296
+ expect(sleepSpanCall[0]).toBe('Workflow sleep-test: sleep wait for settlement');
297
+ expect(sleepSpanCall[1].attributes['workflow.sleep.name']).toBe('wait for settlement');
298
+ expect(sleepSpanCall[1].attributes['workflow.sleep.duration']).toBe('2 hours');
299
+ expect(sleepSpanCall[1].attributes['workflow.name']).toBe('sleep-test');
300
+ });
301
+ });
302
+
303
+ describe('this binding', () => {
304
+ it('should preserve this context in run()', async () => {
305
+ class TestWorkflow {
306
+ private value = 42;
307
+ constructor(public ctx: any, public env: any) {}
308
+ async run(event: any, step: any) {
309
+ return this.value;
310
+ }
311
+ }
312
+
313
+ const Instrumented = instrumentWorkflow(TestWorkflow, 'this-test', {
314
+ service: { name: 'test' },
315
+ });
316
+
317
+ const instance = new Instrumented({}, {});
318
+ const event = { payload: {}, timestamp: new Date(), instanceId: 'wf-this' };
319
+ const step = { do: vi.fn(), sleep: vi.fn(), sleepUntil: vi.fn() };
320
+
321
+ // Should not throw — this.value should be accessible
322
+ await expect(instance.run(event, step)).resolves.not.toThrow();
323
+ });
324
+ });
325
+ });
@@ -14,25 +14,48 @@ import {
14
14
  SpanStatusCode,
15
15
  SpanKind,
16
16
  } from '@opentelemetry/api';
17
- import type { ConfigurationOption } from 'autotel-edge';
17
+ import type { ConfigurationOption, WorkflowTrigger } from 'autotel-edge';
18
18
  import { createInitialiser, setConfig, WorkerTracer } from 'autotel-edge';
19
19
  import { wrap } from '../bindings/common';
20
20
 
21
- // Workflow types (these would come from @cloudflare/workers-types when available)
22
- type WorkflowEvent = any;
23
- type WorkflowStep = any;
21
+ /**
22
+ * Workflow types matching the Cloudflare Workers Workflows API.
23
+ * @see https://developers.cloudflare.com/workflows/
24
+ */
25
+
26
+ interface WorkflowEvent<T = unknown> {
27
+ payload: Readonly<T>;
28
+ timestamp: Date;
29
+ instanceId: string;
30
+ }
31
+
32
+ interface WorkflowStepConfig {
33
+ retries?: {
34
+ limit: number;
35
+ delay?: string | number;
36
+ backoff?: 'constant' | 'linear' | 'exponential';
37
+ };
38
+ timeout?: string | number;
39
+ }
40
+
41
+ interface WorkflowStep {
42
+ do<T>(name: string, callback: () => Promise<T>): Promise<T>;
43
+ do<T>(name: string, config: WorkflowStepConfig, callback: () => Promise<T>): Promise<T>;
44
+ sleep(name: string, duration: string | number): Promise<void>;
45
+ sleepUntil(name: string, timestamp: Date | number): Promise<void>;
46
+ }
24
47
 
25
48
  type WorkflowRunFn = (
26
- event: WorkflowEvent,
49
+ event: Readonly<WorkflowEvent>,
27
50
  step: WorkflowStep,
28
- ) => Promise<void> | void;
51
+ ) => Promise<unknown> | void;
29
52
 
30
53
  /**
31
54
  * Track cold starts per Workflow class
32
55
  */
33
- const coldStarts = new WeakMap<any, boolean>();
56
+ const coldStarts = new WeakMap<object, boolean>();
34
57
 
35
- function isColdStart(workflowClass: any): boolean {
58
+ function isColdStart(workflowClass: object): boolean {
36
59
  if (!coldStarts.has(workflowClass)) {
37
60
  coldStarts.set(workflowClass, true);
38
61
  return true;
@@ -41,7 +64,7 @@ function isColdStart(workflowClass: any): boolean {
41
64
  }
42
65
 
43
66
  /**
44
- * Proxy the step object to instrument step.do() calls
67
+ * Proxy the step object to instrument step.do() and step.sleep() calls
45
68
  */
46
69
  function instrumentWorkflowStep(
47
70
  step: WorkflowStep,
@@ -55,7 +78,7 @@ function instrumentWorkflowStep(
55
78
  if (prop === 'do' && typeof value === 'function') {
56
79
  return new Proxy(value, {
57
80
  apply: (fnTarget, thisArg, args) => {
58
- const [stepName] = args as [string, () => Promise<any>];
81
+ const [stepName] = args as [string, ...unknown[]];
59
82
 
60
83
  const tracer = trace.getTracer('autotel-edge') as WorkerTracer;
61
84
 
@@ -148,13 +171,13 @@ function instrumentWorkflowStep(
148
171
  function instrumentWorkflowRun(
149
172
  runFn: WorkflowRunFn,
150
173
  workflowName: string,
151
- workflowClass: any,
174
+ workflowClass: object,
152
175
  ): WorkflowRunFn {
153
176
  return async function instrumentedRun(
154
- this: any,
155
- event: WorkflowEvent,
177
+ this: unknown,
178
+ event: Readonly<WorkflowEvent>,
156
179
  step: WorkflowStep,
157
- ): Promise<void> {
180
+ ): Promise<unknown> {
158
181
  const tracer = trace.getTracer('autotel-edge') as WorkerTracer;
159
182
 
160
183
  // Instrument the step object to track individual operations
@@ -168,17 +191,16 @@ function instrumentWorkflowRun(
168
191
  kind: SpanKind.INTERNAL,
169
192
  attributes: {
170
193
  'workflow.name': workflowName,
194
+ 'workflow.instance_id': event.instanceId,
171
195
  'faas.trigger': 'workflow',
172
196
  'faas.coldstart': isColdStart(workflowClass),
173
- // Add workflow event attributes if available
174
- ...(event?.workflowId && { 'workflow.id': event.workflowId }),
175
- ...(event?.runId && { 'workflow.run_id': event.runId }),
176
197
  },
177
198
  },
178
199
  async (span) => {
179
200
  try {
180
- await runFn.call(this, event, instrumentedStep);
201
+ const result = await runFn.call(this, event, instrumentedStep);
181
202
  span.setStatus({ code: SpanStatusCode.OK });
203
+ return result;
182
204
  } catch (error) {
183
205
  span.recordException(error as Error);
184
206
  span.setStatus({
@@ -198,17 +220,17 @@ function instrumentWorkflowRun(
198
220
  * Instrument a Workflow instance
199
221
  */
200
222
  function instrumentWorkflowInstance(
201
- workflowInstance: any,
223
+ workflowInstance: Record<string, unknown>,
202
224
  workflowName: string,
203
- workflowClass: any,
204
- ): any {
205
- const instanceHandler: ProxyHandler<any> = {
225
+ workflowClass: object,
226
+ ): Record<string, unknown> {
227
+ const instanceHandler: ProxyHandler<Record<string, unknown>> = {
206
228
  get(target, prop) {
207
229
  const value = Reflect.get(target, prop);
208
230
 
209
231
  if (prop === 'run' && typeof value === 'function') {
210
232
  return instrumentWorkflowRun(
211
- value.bind(target),
233
+ value.bind(target) as WorkflowRunFn,
212
234
  workflowName,
213
235
  workflowClass,
214
236
  );
@@ -235,12 +257,12 @@ function instrumentWorkflowInstance(
235
257
  * **Usage:**
236
258
  * ```typescript
237
259
  * import { WorkflowEntrypoint } from 'cloudflare:workers'
238
- * import { instrumentWorkflow } from 'autotel-edge'
260
+ * import { instrumentWorkflow } from 'autotel-cloudflare/handlers'
239
261
  *
240
- * export class CheckoutWorkflow extends WorkflowEntrypoint {
262
+ * class MyWorkflow extends WorkflowEntrypoint {
241
263
  * async run(event, step) {
242
264
  * await step.do('submit payment', async () => {
243
- * return await submitToPaymentProcessor(event.params.payment)
265
+ * return await submitToPaymentProcessor(event.payload.payment)
244
266
  * })
245
267
  *
246
268
  * await step.sleep('wait for feedback', '2 days')
@@ -249,9 +271,8 @@ function instrumentWorkflowInstance(
249
271
  * }
250
272
  * }
251
273
  *
252
- * // Wrap the class before exporting
253
- * export const CheckoutWorkflowInstrumented = instrumentWorkflow(
254
- * CheckoutWorkflow,
274
+ * export const CheckoutWorkflow = instrumentWorkflow(
275
+ * MyWorkflow,
255
276
  * 'checkout-workflow',
256
277
  * (env: Env) => ({
257
278
  * exporter: {
@@ -266,14 +287,6 @@ function instrumentWorkflowInstance(
266
287
  * )
267
288
  * ```
268
289
  *
269
- * **What you get:**
270
- * - 🎯 Automatic spans for workflow.run() execution
271
- * - 📋 Automatic spans for each step.do() operation
272
- * - ⏸️ Automatic spans for step.sleep() operations
273
- * - 🔄 Automatic retry tracking (via step.do retries)
274
- * - 🥶 Cold start tracking
275
- * - ⚡ Automatic span lifecycle management
276
- *
277
290
  * @param workflowClass - The WorkflowEntrypoint class to instrument
278
291
  * @param workflowName - The name of the workflow (used in span names)
279
292
  * @param config - Configuration or configuration function
@@ -293,9 +306,7 @@ export function instrumentWorkflow<
293
306
  // Extract env from constructor args (typically last arg)
294
307
  const env = args[args.length - 1] || {};
295
308
 
296
- // Initialize config for this workflow instance
297
- // Use Request as trigger type since workflows don't have a standard Trigger type yet
298
- const trigger = new Request('https://workflow.local/run');
309
+ const trigger: WorkflowTrigger = { type: 'workflow', name: workflowName };
299
310
  const workflowConfig = initialiser(env, trigger);
300
311
  const context = setConfig(workflowConfig);
301
312
 
@@ -315,4 +326,3 @@ export function instrumentWorkflow<
315
326
 
316
327
  return wrap(workflowClass, classHandler);
317
328
  }
318
-
package/src/index.ts CHANGED
@@ -51,6 +51,14 @@ export {
51
51
  instrumentD1,
52
52
  instrumentServiceBinding,
53
53
  instrumentBindings,
54
+ instrumentAI,
55
+ instrumentVectorize,
56
+ instrumentHyperdrive,
57
+ instrumentQueueProducer,
58
+ instrumentAnalyticsEngine,
59
+ instrumentImages,
60
+ instrumentRateLimiter,
61
+ instrumentBrowserRendering,
54
62
  } from './bindings';
55
63
 
56
64
  // Global instrumentations