@angular-helpers/worker-http 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -406,6 +406,134 @@ manual control.
406
406
 
407
407
  ---
408
408
 
409
+ ## Telemetry
410
+
411
+ Main-thread extension point for APM / metrics. `withTelemetry(...)` registers
412
+ a subscriber that fires synchronously at three lifecycle points of every
413
+ request handled by `WorkerHttpBackend`:
414
+
415
+ - **`onRequest`** — after worker resolution, before dispatch
416
+ - **`onResponse`** — when a successful response is emitted
417
+ - **`onError`** — when the request fails (transport or non-2xx)
418
+
419
+ Events share a `requestId` so you can correlate the three emissions for one
420
+ request. `transport` is `'worker'` or `'fallback-fetch'` (SSR /
421
+ no-route). Errors in your subscriber are caught and logged — they **never**
422
+ affect the actual HTTP request.
423
+
424
+ Call `withTelemetry(...)` multiple times to attach independent subscribers
425
+ (e.g. one for Sentry, one for custom metrics). All subscribers receive every
426
+ event in registration order.
427
+
428
+ ```ts
429
+ provideWorkerHttpClient(
430
+ withWorkerConfigs([{ id: 'api', workerUrl: new URL('./workers/api.worker', import.meta.url) }]),
431
+ withWorkerRoutes([{ pattern: /\/api\//, worker: 'api' }]),
432
+
433
+ // Latency histogram
434
+ withTelemetry({
435
+ onResponse: (e) =>
436
+ histogram.record(e.durationMs, {
437
+ workerId: e.workerId,
438
+ status: e.status,
439
+ transport: e.transport,
440
+ }),
441
+ onError: (e) =>
442
+ histogram.record(e.durationMs, {
443
+ workerId: e.workerId,
444
+ status: 'error',
445
+ }),
446
+ }),
447
+
448
+ // Sentry breadcrumbs
449
+ withTelemetry({
450
+ onRequest: (e) =>
451
+ Sentry.addBreadcrumb({
452
+ category: 'worker-http',
453
+ message: `${e.method} ${e.url}`,
454
+ data: { requestId: e.requestId, workerId: e.workerId },
455
+ }),
456
+ onError: (e) =>
457
+ Sentry.captureException(e.error, {
458
+ tags: { workerId: e.workerId ?? 'fallback' },
459
+ }),
460
+ }),
461
+ );
462
+ ```
463
+
464
+ Event interface:
465
+
466
+ ```ts
467
+ interface WorkerHttpTelemetryEventBase {
468
+ readonly requestId: string; // unique per request, correlates events
469
+ readonly method: string;
470
+ readonly url: string;
471
+ readonly urlWithParams: string;
472
+ readonly workerId: string | null; // null = fallback fetch
473
+ readonly transport: 'worker' | 'fallback-fetch';
474
+ readonly timestamp: number; // performance.now() at emission
475
+ }
476
+ // onResponse adds: kind: 'response', status, durationMs
477
+ // onError adds: kind: 'error', error, durationMs
478
+ ```
479
+
480
+ ---
481
+
482
+ ## SSR + hydration
483
+
484
+ Worker HTTP integrates transparently with Angular SSR. The two problems SSR
485
+ creates for worker-based HTTP are handled out of the box:
486
+
487
+ **1. Workers do not exist on the server.**
488
+ During SSR, `typeof Worker === 'undefined'`. `WorkerHttpBackend` detects this
489
+ and falls back to `FetchBackend` automatically (controlled by
490
+ `withWorkerFallback()`). The request is fulfilled on the server thread
491
+ exactly like a plain `HttpClient.get()` would do.
492
+
493
+ **2. Avoiding a re-fetch after hydration.**
494
+ Add `provideClientHydration()` from `@angular/platform-browser` at the app
495
+ root (standard Angular SSR setup). That enables Angular's HTTP transfer
496
+ cache by default. The transfer cache interceptor sits in the `HttpClient`
497
+ pipeline — **before** `WorkerHttpBackend`:
498
+
499
+ - On the server: `WorkerHttpBackend` falls back to fetch → returns a
500
+ response → the interceptor captures it into `TransferState`.
501
+ - On the browser: a matching request hits the interceptor first → it replays
502
+ the cached response synchronously, **without ever reaching
503
+ `WorkerHttpBackend`**. No worker is booted for hydrated requests.
504
+
505
+ ```ts
506
+ // app.config.server.ts (or your SSR bootstrap)
507
+ export const serverConfig: ApplicationConfig = {
508
+ providers: [
509
+ provideServerRendering(),
510
+ provideWorkerHttpClient(
511
+ withWorkerConfigs([
512
+ { id: 'api', workerUrl: new URL('./workers/api.worker', import.meta.url) },
513
+ ]),
514
+ ),
515
+ ],
516
+ };
517
+
518
+ // app.config.ts (browser bootstrap)
519
+ export const appConfig: ApplicationConfig = {
520
+ providers: [
521
+ provideClientHydration(), // ← enables HTTP transfer cache automatically
522
+ provideWorkerHttpClient(
523
+ withWorkerConfigs([
524
+ { id: 'api', workerUrl: new URL('./workers/api.worker', import.meta.url) },
525
+ ]),
526
+ ),
527
+ ],
528
+ };
529
+ ```
530
+
531
+ To customise which headers are captured or to cache `POST` requests, pass
532
+ `withHttpTransferCacheOptions(...)` to `provideClientHydration()` — both are
533
+ re-exported from `@angular/platform-browser`.
534
+
535
+ ---
536
+
409
537
  ## Design principles
410
538
 
411
539
  - **Zero main-thread cost** — `fetch()` runs entirely in the worker; the main thread only handles the `postMessage` handoff
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, Injectable, makeEnvironmentProviders } from '@angular/core';
3
3
  import { HttpContextToken, HttpHeaders, HttpResponse, HttpBackend, FetchBackend, HttpErrorResponse, HttpClient, HttpContext, provideHttpClient, withFetch } from '@angular/common/http';
4
4
  import { throwError } from 'rxjs';
5
- import { map, catchError } from 'rxjs/operators';
5
+ import { map, tap, catchError } from 'rxjs/operators';
6
6
  import { createWorkerTransport } from '@angular-helpers/worker-http/transport';
7
7
 
8
8
  /**
@@ -53,6 +53,15 @@ const WORKER_HTTP_SERIALIZER_TOKEN = new InjectionToken('WorkerHttpSerializer',
53
53
  * Defaults to an empty map (no interceptors).
54
54
  */
55
55
  const WORKER_HTTP_INTERCEPTORS_TOKEN = new InjectionToken('WorkerHttpInterceptors', { factory: () => ({}) });
56
+ /**
57
+ * Telemetry subscribers registered via `withTelemetry()`.
58
+ *
59
+ * Multi-provider token — each `withTelemetry(...)` call appends one
60
+ * subscriber. All subscribers are invoked on every emission; a throwing
61
+ * subscriber is isolated (the backend swallows the error so it never
62
+ * affects the HTTP request).
63
+ */
64
+ const WORKER_HTTP_TELEMETRY_TOKEN = new InjectionToken('WorkerHttpTelemetry', { factory: () => [] });
56
65
 
57
66
  /**
58
67
  * Converts an Angular `HttpRequest` into a structured-clone-safe POJO
@@ -117,6 +126,16 @@ function matchWorkerRoute(url, routes) {
117
126
  return null;
118
127
  }
119
128
 
129
+ let telemetryRequestCounter = 0;
130
+ function nextTelemetryRequestId() {
131
+ telemetryRequestCounter = (telemetryRequestCounter + 1) >>> 0;
132
+ return `whttp-${telemetryRequestCounter.toString(36)}`;
133
+ }
134
+ function now() {
135
+ return typeof performance !== 'undefined' && typeof performance.now === 'function'
136
+ ? performance.now()
137
+ : Date.now();
138
+ }
120
139
  /**
121
140
  * Angular `HttpBackend` replacement that routes HTTP requests to web workers.
122
141
  *
@@ -136,14 +155,15 @@ class WorkerHttpBackend extends HttpBackend {
136
155
  serializer = inject(WORKER_HTTP_SERIALIZER_TOKEN);
137
156
  interceptorSpecs = inject(WORKER_HTTP_INTERCEPTORS_TOKEN);
138
157
  fetchBackend = inject(FetchBackend, { optional: true });
158
+ telemetry = inject(WORKER_HTTP_TELEMETRY_TOKEN);
139
159
  transports = new Map();
140
160
  handle(req) {
141
161
  if (typeof Worker === 'undefined') {
142
- return this.handleFallback(req, 'Web Workers are not available in this environment (SSR)');
162
+ return this.handleFallback(req, null, 'Web Workers are not available in this environment (SSR)');
143
163
  }
144
164
  const workerId = req.context.get(WORKER_TARGET) ?? matchWorkerRoute(req.url, this.routes);
145
165
  if (!workerId) {
146
- return this.handleFallback(req, `No worker route matched for URL: ${req.url}`);
166
+ return this.handleFallback(req, null, `No worker route matched for URL: ${req.url}`);
147
167
  }
148
168
  const config = this.configs.find((c) => c.id === workerId);
149
169
  if (!config) {
@@ -156,12 +176,22 @@ class WorkerHttpBackend extends HttpBackend {
156
176
  ? this.serializer.serialize(serializable.body).data
157
177
  : serializable.body;
158
178
  const payload = body !== serializable.body ? { ...serializable, body } : serializable;
159
- return transport.execute(payload).pipe(map((res) => toHttpResponse(res, req)), catchError((err) => throwError(() => new HttpErrorResponse({
160
- error: err,
161
- status: 0,
162
- statusText: 'Worker Error',
163
- url: req.urlWithParams,
164
- }))));
179
+ const base = this.buildEventBase(req, workerId, 'worker');
180
+ this.emitRequest(base);
181
+ return transport.execute(payload).pipe(map((res) => toHttpResponse(res, req)), tap((event) => {
182
+ if (event instanceof HttpResponse) {
183
+ this.emitResponse(base, event.status);
184
+ }
185
+ }), catchError((err) => {
186
+ const httpError = new HttpErrorResponse({
187
+ error: err,
188
+ status: 0,
189
+ statusText: 'Worker Error',
190
+ url: req.urlWithParams,
191
+ });
192
+ this.emitError(base, httpError);
193
+ return throwError(() => httpError);
194
+ }));
165
195
  }
166
196
  ngOnDestroy() {
167
197
  for (const transport of this.transports.values()) {
@@ -191,11 +221,73 @@ class WorkerHttpBackend extends HttpBackend {
191
221
  return wildcard;
192
222
  return [...wildcard, ...specific];
193
223
  }
194
- handleFallback(req, reason) {
224
+ handleFallback(req, workerId, reason) {
195
225
  if (this.fallback === 'error' || !this.fetchBackend) {
196
226
  return throwError(() => new Error(`[WorkerHttpBackend] ${reason}`));
197
227
  }
198
- return this.fetchBackend.handle(req);
228
+ const base = this.buildEventBase(req, workerId, 'fallback-fetch');
229
+ this.emitRequest(base);
230
+ return this.fetchBackend.handle(req).pipe(tap((event) => {
231
+ if (event instanceof HttpResponse) {
232
+ this.emitResponse(base, event.status);
233
+ }
234
+ }), catchError((err) => {
235
+ this.emitError(base, err);
236
+ return throwError(() => err);
237
+ }));
238
+ }
239
+ // --- Telemetry ---------------------------------------------------------
240
+ buildEventBase(req, workerId, transport) {
241
+ return {
242
+ requestId: nextTelemetryRequestId(),
243
+ method: req.method,
244
+ url: req.url,
245
+ urlWithParams: req.urlWithParams,
246
+ workerId,
247
+ transport,
248
+ timestamp: now(),
249
+ };
250
+ }
251
+ emitRequest(base) {
252
+ if (this.telemetry.length === 0)
253
+ return;
254
+ const event = { ...base, kind: 'request' };
255
+ this.dispatch((sub) => sub.onRequest?.(event));
256
+ }
257
+ emitResponse(base, status) {
258
+ if (this.telemetry.length === 0)
259
+ return;
260
+ const event = {
261
+ ...base,
262
+ kind: 'response',
263
+ status,
264
+ durationMs: now() - base.timestamp,
265
+ timestamp: now(),
266
+ };
267
+ this.dispatch((sub) => sub.onResponse?.(event));
268
+ }
269
+ emitError(base, error) {
270
+ if (this.telemetry.length === 0)
271
+ return;
272
+ const event = {
273
+ ...base,
274
+ kind: 'error',
275
+ error,
276
+ durationMs: now() - base.timestamp,
277
+ timestamp: now(),
278
+ };
279
+ this.dispatch((sub) => sub.onError?.(event));
280
+ }
281
+ dispatch(invoke) {
282
+ for (const subscriber of this.telemetry) {
283
+ try {
284
+ invoke(subscriber);
285
+ }
286
+ catch (telemetryError) {
287
+ // A throwing telemetry subscriber must never affect the HTTP request.
288
+ console.error('[WorkerHttpBackend] telemetry subscriber threw:', telemetryError);
289
+ }
290
+ }
199
291
  }
200
292
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpBackend, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
201
293
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpBackend });
@@ -423,9 +515,51 @@ function withWorkerInterceptors(specs) {
423
515
  providers: [{ provide: WORKER_HTTP_INTERCEPTORS_TOKEN, useValue: map }],
424
516
  };
425
517
  }
518
+ /**
519
+ * Registers a telemetry subscriber for `WorkerHttpBackend`.
520
+ *
521
+ * Telemetry hooks are a main-thread extension point for APM integrations
522
+ * (Sentry, Datadog, OpenTelemetry, ad-hoc logging). They fire synchronously
523
+ * at three lifecycle points of every HTTP request handled by the backend:
524
+ *
525
+ * - `onRequest` — after worker resolution, before dispatch
526
+ * - `onResponse` — when a successful response is emitted
527
+ * - `onError` — when the request fails
528
+ *
529
+ * The feature is repeatable — call `withTelemetry(...)` multiple times to
530
+ * attach independent subscribers. All of them receive every event, in
531
+ * registration order. A throwing subscriber is isolated: the backend
532
+ * catches and logs the error so telemetry bugs never break the request.
533
+ *
534
+ * @example Basic counter
535
+ * ```typescript
536
+ * const counters = { requests: 0, errors: 0 };
537
+ * provideWorkerHttpClient(
538
+ * withWorkerConfigs([...]),
539
+ * withTelemetry({
540
+ * onRequest: () => counters.requests++,
541
+ * onError: () => counters.errors++,
542
+ * }),
543
+ * );
544
+ * ```
545
+ *
546
+ * @example Latency histogram
547
+ * ```typescript
548
+ * withTelemetry({
549
+ * onResponse: (e) => histogram.record(e.durationMs, { workerId: e.workerId }),
550
+ * onError: (e) => histogram.record(e.durationMs, { workerId: e.workerId, error: true }),
551
+ * });
552
+ * ```
553
+ */
554
+ function withTelemetry(telemetry) {
555
+ return {
556
+ kind: 'Telemetry',
557
+ providers: [{ provide: WORKER_HTTP_TELEMETRY_TOKEN, useValue: telemetry, multi: true }],
558
+ };
559
+ }
426
560
 
427
561
  /**
428
562
  * Generated bundle index. Do not edit.
429
563
  */
430
564
 
431
- export { WORKER_HTTP_INTERCEPTORS_TOKEN, WORKER_HTTP_SERIALIZER_TOKEN, WORKER_TARGET, WorkerHttpBackend, WorkerHttpClient, matchWorkerRoute, provideWorkerHttpClient, toHttpResponse, toSerializableRequest, withWorkerConfigs, withWorkerFallback, withWorkerInterceptors, withWorkerRoutes, withWorkerSerialization };
565
+ export { WORKER_HTTP_INTERCEPTORS_TOKEN, WORKER_HTTP_SERIALIZER_TOKEN, WORKER_TARGET, WorkerHttpBackend, WorkerHttpClient, matchWorkerRoute, provideWorkerHttpClient, toHttpResponse, toSerializableRequest, withTelemetry, withWorkerConfigs, withWorkerFallback, withWorkerInterceptors, withWorkerRoutes, withWorkerSerialization };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-helpers/worker-http",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Angular HTTP over Web Workers — off-main-thread HTTP pipelines with configurable interceptors, WebCrypto security, and pluggable serialization",
5
5
  "keywords": [
6
6
  "angular",
@@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
9
9
  * Discriminated union for worker HTTP feature kinds.
10
10
  * Mirrors Angular's HttpFeatureKind pattern.
11
11
  */
12
- type WorkerHttpFeatureKind = 'WorkerConfigs' | 'WorkerRoutes' | 'WorkerFallback' | 'WorkerSerialization' | 'WorkerInterceptors';
12
+ type WorkerHttpFeatureKind = 'WorkerConfigs' | 'WorkerRoutes' | 'WorkerFallback' | 'WorkerSerialization' | 'WorkerInterceptors' | 'Telemetry';
13
13
  /**
14
14
  * Feature object — mirrors Angular's HttpFeature<K> shape.
15
15
  */
@@ -68,6 +68,82 @@ interface SerializableResponse {
68
68
  url: string;
69
69
  }
70
70
 
71
+ /**
72
+ * Telemetry hooks for `WorkerHttpBackend`.
73
+ *
74
+ * Extension point for APM integrations (Sentry, Datadog, OpenTelemetry,
75
+ * ad-hoc metrics). Fires on the main thread, synchronously, at three
76
+ * lifecycle points of every HTTP request that reaches
77
+ * `WorkerHttpBackend`:
78
+ *
79
+ * - `onRequest` — after worker resolution / fallback decision, BEFORE
80
+ * dispatch.
81
+ * - `onResponse` — when a successful response is returned from the worker
82
+ * (or the fallback `FetchBackend`).
83
+ * - `onError` — when the request fails in transport or surfaces as a
84
+ * non-2xx `HttpErrorResponse`.
85
+ *
86
+ * Subscribers are invoked inside a try/catch — a throwing or misbehaving
87
+ * subscriber is isolated from the HTTP request and from every other
88
+ * subscriber. Telemetry errors are logged via `console.error` and
89
+ * swallowed.
90
+ *
91
+ * Multiple subscribers are supported via a multi-provider DI token.
92
+ * Register with `withTelemetry(...)`; every call appends one subscriber.
93
+ */
94
+ /**
95
+ * How a request was dispatched.
96
+ *
97
+ * - `'worker'` — dispatched to a worker from the pool.
98
+ * - `'fallback-fetch'` — dispatched to the main-thread `FetchBackend`
99
+ * (SSR context, no matching route, unknown worker with `'main-thread'`
100
+ * fallback strategy).
101
+ */
102
+ type WorkerHttpTransportKind = 'worker' | 'fallback-fetch';
103
+ /**
104
+ * Base shape shared by every telemetry event.
105
+ */
106
+ interface WorkerHttpTelemetryEventBase {
107
+ /** Stable id unique to this request within the process. Correlates all three events. */
108
+ readonly requestId: string;
109
+ /** HTTP method (`'GET'`, `'POST'`, ...). */
110
+ readonly method: string;
111
+ /** URL without query params, as Angular sees it. */
112
+ readonly url: string;
113
+ /** URL with query params baked in. */
114
+ readonly urlWithParams: string;
115
+ /** Worker id that served the request. `null` when routed to fallback fetch. */
116
+ readonly workerId: string | null;
117
+ /** How the request was actually dispatched. */
118
+ readonly transport: WorkerHttpTransportKind;
119
+ /** `performance.now()` value at emission time. */
120
+ readonly timestamp: number;
121
+ }
122
+ /** Fires before the request is dispatched. */
123
+ interface WorkerHttpRequestEvent extends WorkerHttpTelemetryEventBase {
124
+ readonly kind: 'request';
125
+ }
126
+ /** Fires when a successful response is returned. */
127
+ interface WorkerHttpResponseEvent extends WorkerHttpTelemetryEventBase {
128
+ readonly kind: 'response';
129
+ readonly status: number;
130
+ readonly durationMs: number;
131
+ }
132
+ /** Fires when the request fails. */
133
+ interface WorkerHttpErrorEvent extends WorkerHttpTelemetryEventBase {
134
+ readonly kind: 'error';
135
+ readonly error: unknown;
136
+ readonly durationMs: number;
137
+ }
138
+ /**
139
+ * Telemetry subscriber — all callbacks are optional.
140
+ */
141
+ interface WorkerHttpTelemetry {
142
+ onRequest?(event: WorkerHttpRequestEvent): void;
143
+ onResponse?(event: WorkerHttpResponseEvent): void;
144
+ onError?(event: WorkerHttpErrorEvent): void;
145
+ }
146
+
71
147
  /**
72
148
  * Per-worker interceptor specs map. Key is the worker id from
73
149
  * `WorkerConfig.id`, plus the special `'*'` wildcard that applies to every
@@ -232,6 +308,43 @@ declare function withWorkerSerialization(serializer: WorkerSerializer): WorkerHt
232
308
  * ```
233
309
  */
234
310
  declare function withWorkerInterceptors(specs: readonly WorkerInterceptorSpec[] | WorkerInterceptorSpecsMap): WorkerHttpFeature<'WorkerInterceptors'>;
311
+ /**
312
+ * Registers a telemetry subscriber for `WorkerHttpBackend`.
313
+ *
314
+ * Telemetry hooks are a main-thread extension point for APM integrations
315
+ * (Sentry, Datadog, OpenTelemetry, ad-hoc logging). They fire synchronously
316
+ * at three lifecycle points of every HTTP request handled by the backend:
317
+ *
318
+ * - `onRequest` — after worker resolution, before dispatch
319
+ * - `onResponse` — when a successful response is emitted
320
+ * - `onError` — when the request fails
321
+ *
322
+ * The feature is repeatable — call `withTelemetry(...)` multiple times to
323
+ * attach independent subscribers. All of them receive every event, in
324
+ * registration order. A throwing subscriber is isolated: the backend
325
+ * catches and logs the error so telemetry bugs never break the request.
326
+ *
327
+ * @example Basic counter
328
+ * ```typescript
329
+ * const counters = { requests: 0, errors: 0 };
330
+ * provideWorkerHttpClient(
331
+ * withWorkerConfigs([...]),
332
+ * withTelemetry({
333
+ * onRequest: () => counters.requests++,
334
+ * onError: () => counters.errors++,
335
+ * }),
336
+ * );
337
+ * ```
338
+ *
339
+ * @example Latency histogram
340
+ * ```typescript
341
+ * withTelemetry({
342
+ * onResponse: (e) => histogram.record(e.durationMs, { workerId: e.workerId }),
343
+ * onError: (e) => histogram.record(e.durationMs, { workerId: e.workerId, error: true }),
344
+ * });
345
+ * ```
346
+ */
347
+ declare function withTelemetry(telemetry: WorkerHttpTelemetry): WorkerHttpFeature<'Telemetry'>;
235
348
 
236
349
  /**
237
350
  * Angular `HttpBackend` replacement that routes HTTP requests to web workers.
@@ -252,12 +365,18 @@ declare class WorkerHttpBackend extends HttpBackend implements OnDestroy {
252
365
  private readonly serializer;
253
366
  private readonly interceptorSpecs;
254
367
  private readonly fetchBackend;
368
+ private readonly telemetry;
255
369
  private readonly transports;
256
370
  handle(req: HttpRequest<unknown>): Observable<HttpEvent<unknown>>;
257
371
  ngOnDestroy(): void;
258
372
  private getOrCreateTransport;
259
373
  private resolveSpecsFor;
260
374
  private handleFallback;
375
+ private buildEventBase;
376
+ private emitRequest;
377
+ private emitResponse;
378
+ private emitError;
379
+ private dispatch;
261
380
  static ɵfac: i0.ɵɵFactoryDeclaration<WorkerHttpBackend, never>;
262
381
  static ɵprov: i0.ɵɵInjectableDeclaration<WorkerHttpBackend>;
263
382
  }
@@ -341,5 +460,5 @@ declare function matchWorkerRoute(url: string, routes: Array<{
341
460
  priority?: number;
342
461
  }>): string | null;
343
462
 
344
- export { WORKER_HTTP_INTERCEPTORS_TOKEN, WORKER_HTTP_SERIALIZER_TOKEN, WORKER_TARGET, WorkerHttpBackend, WorkerHttpClient, matchWorkerRoute, provideWorkerHttpClient, toHttpResponse, toSerializableRequest, withWorkerConfigs, withWorkerFallback, withWorkerInterceptors, withWorkerRoutes, withWorkerSerialization };
345
- export type { SerializableRequest, SerializableResponse, WorkerConfig, WorkerFallbackStrategy, WorkerHttpFeature, WorkerHttpFeatureKind, WorkerInterceptorSpecsMap, WorkerRequestOptions, WorkerRoute };
463
+ export { WORKER_HTTP_INTERCEPTORS_TOKEN, WORKER_HTTP_SERIALIZER_TOKEN, WORKER_TARGET, WorkerHttpBackend, WorkerHttpClient, matchWorkerRoute, provideWorkerHttpClient, toHttpResponse, toSerializableRequest, withTelemetry, withWorkerConfigs, withWorkerFallback, withWorkerInterceptors, withWorkerRoutes, withWorkerSerialization };
464
+ export type { SerializableRequest, SerializableResponse, WorkerConfig, WorkerFallbackStrategy, WorkerHttpErrorEvent, WorkerHttpFeature, WorkerHttpFeatureKind, WorkerHttpRequestEvent, WorkerHttpResponseEvent, WorkerHttpTelemetry, WorkerHttpTelemetryEventBase, WorkerHttpTransportKind, WorkerInterceptorSpecsMap, WorkerRequestOptions, WorkerRoute };