@angular-helpers/worker-http 21.2.2 → 21.2.4

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
@@ -75,7 +75,7 @@ ng add @angular-helpers/worker-http --installEsbuildPlugin=true
75
75
  ### Manual installation
76
76
 
77
77
  ```bash
78
- npm install @angular-helpers/worker-http
78
+ pnpm add @angular-helpers/worker-http
79
79
  ```
80
80
 
81
81
  Then follow the setup in the `/backend` section below.
@@ -320,7 +320,7 @@ import { structuredCloneSerializer } from '@angular-helpers/worker-http/serializ
320
320
 
321
321
  #### `createSerovalSerializer()` — Full type fidelity
322
322
 
323
- Requires `seroval` as an optional peer dependency (`npm install seroval`).
323
+ Requires `seroval` as an optional peer dependency (`pnpm add seroval`).
324
324
 
325
325
  Supports: `Date`, `Map`, `Set`, `BigInt`, `RegExp`, circular references, and more.
326
326
 
@@ -338,7 +338,7 @@ const original = serializer.deserialize(payload);
338
338
 
339
339
  #### `createToonSerializer()` — Token-Oriented Object Notation
340
340
 
341
- Requires `@toon-format/toon` as an optional peer dependency (`npm install @toon-format/toon`).
341
+ Requires `@toon-format/toon` as an optional peer dependency (`pnpm add @toon-format/toon`).
342
342
 
343
343
  [TOON](https://toonformat.dev) declares object keys once and emits values as CSV-like rows. For uniform arrays of objects (the most common API response shape — `User[]`, `Product[]`, paginated lists), it cuts payload size by **30–60%** compared to JSON, with negligible parsing overhead.
344
344
 
@@ -821,8 +821,8 @@ generation), so the only variable being compared is **where** the work runs.
821
821
  To run locally:
822
822
 
823
823
  ```bash
824
- npm run build:workers
825
- npm start
824
+ pnpm run build:workers
825
+ pnpm start
826
826
  # open https://localhost:4200/demo/worker-http-benchmark
827
827
  ```
828
828
 
@@ -117,7 +117,7 @@ function toSerializableRequest(req) {
117
117
  }
118
118
  return {
119
119
  method: req.method,
120
- url: req.urlWithParams,
120
+ url: req.url,
121
121
  headers,
122
122
  params,
123
123
  body: req.body,
@@ -341,10 +341,10 @@ class WorkerHttpBackend extends HttpBackend {
341
341
  }
342
342
  }
343
343
  }
344
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpBackend, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
345
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpBackend });
344
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpBackend, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
345
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpBackend });
346
346
  }
347
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpBackend, decorators: [{
347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpBackend, decorators: [{
348
348
  type: Injectable
349
349
  }] });
350
350
 
@@ -402,10 +402,10 @@ class WorkerHttpClient {
402
402
  }
403
403
  return { ...rest, context: ctx };
404
404
  }
405
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
406
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpClient });
405
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
406
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpClient });
407
407
  }
408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WorkerHttpClient, decorators: [{
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: WorkerHttpClient, decorators: [{
409
409
  type: Injectable
410
410
  }] });
411
411
 
@@ -101,10 +101,8 @@ function scanDirectory(dir, interceptors, rootDir) {
101
101
  * Converts relative paths to valid import specifiers.
102
102
  */
103
103
  function generateInterceptorImports(interceptorPaths, workerFilePath) {
104
- return interceptorPaths.map((interceptorPath, index) => {
105
- // Create a valid identifier from the path
106
- const identifier = `interceptor_${index}_${interceptorPath.replace(/[^a-zA-Z0-9]/g, '_')}`;
107
- return `import ${identifier} from '${interceptorPath}';`;
104
+ return interceptorPaths.map((interceptorPath) => {
105
+ return `import '${interceptorPath}';`;
108
106
  });
109
107
  }
110
108
  /**
@@ -1,3 +1,5 @@
1
+ import { detectTransferables } from '@angular-helpers/worker-http/transport';
2
+
1
3
  /**
2
4
  * Composes interceptor functions around a final handler, producing a single
3
5
  * `(req, signal?) => Promise<resp>` chain. Pure — no side effects.
@@ -94,7 +96,10 @@ function attachPortLoop(port, chain) {
94
96
  return;
95
97
  const responses = responseBuffer;
96
98
  responseBuffer = [];
97
- port.postMessage({ type: 'batch-response', responses });
99
+ const transferables = [
100
+ ...new Set(responses.flatMap((res) => res.type === 'response' && res.result ? detectTransferables(res.result.body) : [])),
101
+ ];
102
+ port.postMessage({ type: 'batch-response', responses }, transferables);
98
103
  });
99
104
  }
100
105
  const processMessage = async (msg) => {
@@ -134,10 +139,12 @@ function attachPortLoop(port, chain) {
134
139
  const data = event.data ?? {};
135
140
  if (data.type === 'batch') {
136
141
  for (const msg of data.messages || []) {
142
+ // oxlint-disable-next-line no-console
137
143
  processMessage(msg).catch(console.error);
138
144
  }
139
145
  }
140
146
  else {
147
+ // oxlint-disable-next-line no-console
141
148
  processMessage(data).catch(console.error);
142
149
  }
143
150
  };
@@ -597,13 +604,12 @@ function createConfigurableWorkerPipeline() {
597
604
  const specs = data.specs ?? [];
598
605
  const fns = specs.map((spec) => resolveSpec(spec));
599
606
  const chain = buildChain(fns, (req, signal) => executeFetch(req, signal));
607
+ // Clear initial handler to prevent double handling and infinite loops.
608
+ self.onmessage = null;
600
609
  // Swap to the regular request loop and replay any buffered messages.
601
610
  attachRequestLoop(chain);
602
- const handler = self.onmessage;
603
- if (handler) {
604
- for (const buffered of pending) {
605
- handler.call(self, buffered);
606
- }
611
+ for (const buffered of pending) {
612
+ self.dispatchEvent(buffered);
607
613
  }
608
614
  pending.length = 0;
609
615
  return;
@@ -22,12 +22,11 @@ let cachedSeroval = null;
22
22
  async function loadSeroval() {
23
23
  if (!cachedSeroval) {
24
24
  try {
25
- // Dynamic import via variable keeps seroval as optional peer dep (no static reference)
26
- const id = 'seroval';
27
- cachedSeroval = (await import(/* @vite-ignore */ id));
25
+ // Dynamic import — allows seroval to be an optional peer dep
26
+ cachedSeroval = (await import('seroval'));
28
27
  }
29
28
  catch {
30
- throw new Error('seroval is required as a peer dependency. Install it with: npm install seroval');
29
+ throw new Error('seroval is required to serialize complex types (Date, Map, Set, RegExp). Install it with: npm install seroval');
31
30
  }
32
31
  }
33
32
  return cachedSeroval;
@@ -75,9 +74,8 @@ let cachedToon = null;
75
74
  async function loadToon() {
76
75
  if (!cachedToon) {
77
76
  try {
78
- // Dynamic import via variable keeps @toon-format/toon as optional peer dep (no static reference)
79
- const id = '@toon-format/toon';
80
- cachedToon = (await import(/* @vite-ignore */ id));
77
+ // Dynamic import — allows @toon-format/toon to be an optional peer dep
78
+ cachedToon = (await import('@toon-format/toon'));
81
79
  }
82
80
  catch {
83
81
  throw new Error('@toon-format/toon is required as a peer dependency. ' +
@@ -252,6 +252,7 @@ function createWorkerTransport(config) {
252
252
  }
253
253
  if (streamsPolyfill && !polyfillLoaded) {
254
254
  loadStreamsPolyfill().catch((err) => {
255
+ // oxlint-disable-next-line no-console
255
256
  console.warn('[worker-http] Streams polyfill failed to load:', err);
256
257
  });
257
258
  }
@@ -356,6 +357,7 @@ function createWorkerTransport(config) {
356
357
  polyfillLoaded = true;
357
358
  }
358
359
  catch (err) {
360
+ // oxlint-disable-next-line no-console
359
361
  console.warn('[worker-http] Failed to load streams polyfill:', err);
360
362
  }
361
363
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-helpers/worker-http",
3
- "version": "21.2.2",
3
+ "version": "21.2.4",
4
4
  "description": "Angular HTTP over Web Workers — off-main-thread HTTP pipelines with configurable interceptors, WebCrypto security, and pluggable serialization",
5
5
  "schematics": "./schematics/collection.json",
6
6
  "exports": {
@@ -106,4 +106,4 @@
106
106
  "dependencies": {
107
107
  "tslib": "^2.3.0"
108
108
  }
109
- }
109
+ }