@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 +5 -5
- package/fesm2022/angular-helpers-worker-http-backend.mjs +7 -7
- package/fesm2022/angular-helpers-worker-http-esbuild-plugin.mjs +2 -4
- package/fesm2022/angular-helpers-worker-http-interceptors.mjs +12 -6
- package/fesm2022/angular-helpers-worker-http-serializer.mjs +5 -7
- package/fesm2022/angular-helpers-worker-http-transport.mjs +2 -0
- package/package.json +2 -2
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
|
-
|
|
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 (`
|
|
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 (`
|
|
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
|
-
|
|
825
|
-
|
|
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.
|
|
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.
|
|
345
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
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.
|
|
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.
|
|
406
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
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.
|
|
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
|
|
105
|
-
|
|
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
|
-
|
|
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
|
|
603
|
-
|
|
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
|
|
26
|
-
|
|
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
|
|
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
|
|
79
|
-
|
|
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.
|
|
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
|
+
}
|