@statewalker/webrun-http-browser 0.12.2 → 0.12.3
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/dist/index.js +76 -46
- package/dist/link/http-link.d.ts.map +1 -1
- package/dist/relay-sw.js +72 -45
- package/dist/relay-worker.js +72 -45
- package/dist/sw/worker-service.d.ts.map +1 -1
- package/dist/sw-worker.js +72 -45
- package/dist/sw.js +76 -46
- package/dist/worker.js +76 -46
- package/package.json +3 -3
- package/src/link/http-link.ts +41 -26
- package/src/sw/worker-service.ts +12 -1
package/dist/index.js
CHANGED
|
@@ -2230,7 +2230,10 @@ async function httpFetch(call, env, body, options = {}) {
|
|
|
2230
2230
|
}
|
|
2231
2231
|
const onAbort = () => void release();
|
|
2232
2232
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
2233
|
-
|
|
2233
|
+
options.keepAlive;
|
|
2234
|
+
drain(output).finally(() => {
|
|
2235
|
+
signal?.removeEventListener("abort", onAbort);
|
|
2236
|
+
});
|
|
2234
2237
|
};
|
|
2235
2238
|
let decoded;
|
|
2236
2239
|
try {
|
|
@@ -2626,7 +2629,8 @@ async function fetchOverDuplex(call, request, options = {}) {
|
|
|
2626
2629
|
}
|
|
2627
2630
|
const { envelope, body: respBody, release, finish } = await httpFetch(call, env, body, {
|
|
2628
2631
|
...options,
|
|
2629
|
-
signal: request.signal ?? void 0
|
|
2632
|
+
signal: request.signal ?? void 0,
|
|
2633
|
+
keepAlive: request
|
|
2630
2634
|
});
|
|
2631
2635
|
const responseInit = {
|
|
2632
2636
|
status: envelope.status,
|
|
@@ -2638,7 +2642,7 @@ async function fetchOverDuplex(call, request, options = {}) {
|
|
|
2638
2642
|
else await release?.();
|
|
2639
2643
|
return new Response(null, responseInit);
|
|
2640
2644
|
}
|
|
2641
|
-
return new Response(responseBody(respBody, request
|
|
2645
|
+
return new Response(responseBody(respBody, request, release), responseInit);
|
|
2642
2646
|
}
|
|
2643
2647
|
/**
|
|
2644
2648
|
* Wrap a `(Request) => Promise<Response>` handler as a `Duplex` so it can be
|
|
@@ -2791,7 +2795,9 @@ const CANCEL_GRACE_MS = 1e3;
|
|
|
2791
2795
|
* A cancel abandons the call too — unless the read in flight comes back with the
|
|
2792
2796
|
* body's end, which finishes it instead (see `cancel`).
|
|
2793
2797
|
*/
|
|
2794
|
-
function responseBody(body,
|
|
2798
|
+
function responseBody(body, request, release) {
|
|
2799
|
+
const keep = { request };
|
|
2800
|
+
const signal = request.signal ?? void 0;
|
|
2795
2801
|
const it = body[Symbol.asyncIterator]();
|
|
2796
2802
|
let controller;
|
|
2797
2803
|
let ended = false;
|
|
@@ -2799,6 +2805,7 @@ function responseBody(body, signal, release) {
|
|
|
2799
2805
|
const end = () => {
|
|
2800
2806
|
ended = true;
|
|
2801
2807
|
signal?.removeEventListener("abort", onAbort);
|
|
2808
|
+
keep.request = void 0;
|
|
2802
2809
|
};
|
|
2803
2810
|
const onAbort = () => {
|
|
2804
2811
|
if (ended) return;
|
|
@@ -3789,12 +3796,6 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
3789
3796
|
const producer = output;
|
|
3790
3797
|
const returnProducer = () => void Promise.resolve(producer.return?.()).catch(() => {});
|
|
3791
3798
|
if (framed !== output) signal.addEventListener("abort", returnProducer, { once: true });
|
|
3792
|
-
let onAborted = () => {};
|
|
3793
|
-
const aborted = new Promise((resolve) => {
|
|
3794
|
-
onAborted = () => resolve();
|
|
3795
|
-
});
|
|
3796
|
-
if (signal.aborted) onAborted();
|
|
3797
|
-
else signal.addEventListener("abort", onAborted, { once: true });
|
|
3798
3799
|
try {
|
|
3799
3800
|
await sendIterator(async ({ done, value, error }) => {
|
|
3800
3801
|
if (signal.aborted) return;
|
|
@@ -3816,7 +3817,7 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
3816
3817
|
});
|
|
3817
3818
|
touch();
|
|
3818
3819
|
if (done && !error) onSent();
|
|
3819
|
-
if (portBufferedAmount(port) > 0) await
|
|
3820
|
+
if (portBufferedAmount(port) > 0) await whenReadyOrAborted(port, signal);
|
|
3820
3821
|
return;
|
|
3821
3822
|
}
|
|
3822
3823
|
await callPort(port, chunk, {
|
|
@@ -3832,10 +3833,25 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
3832
3833
|
throw err;
|
|
3833
3834
|
} finally {
|
|
3834
3835
|
signal.removeEventListener("abort", returnProducer);
|
|
3835
|
-
signal.removeEventListener("abort", onAborted);
|
|
3836
3836
|
}
|
|
3837
3837
|
}
|
|
3838
3838
|
/**
|
|
3839
|
+
* A pipelined sender waits only for room in the window, or for the abort. The
|
|
3840
|
+
* abort listener lives for this one wait: a promise held for the whole stream
|
|
3841
|
+
* would keep one reaction per wait until the stream ends.
|
|
3842
|
+
*/
|
|
3843
|
+
function whenReadyOrAborted(port, signal) {
|
|
3844
|
+
if (signal.aborted) return Promise.resolve();
|
|
3845
|
+
return new Promise((resolve) => {
|
|
3846
|
+
const settle = () => {
|
|
3847
|
+
signal.removeEventListener("abort", settle);
|
|
3848
|
+
resolve();
|
|
3849
|
+
};
|
|
3850
|
+
signal.addEventListener("abort", settle, { once: true });
|
|
3851
|
+
whenPortReady(port).then(settle, settle);
|
|
3852
|
+
});
|
|
3853
|
+
}
|
|
3854
|
+
/**
|
|
3839
3855
|
* One virtual port.
|
|
3840
3856
|
*
|
|
3841
3857
|
* `deliver` and `markClosed` are deliberately not on `port`: the consumer holds
|
|
@@ -4833,7 +4849,12 @@ function trackedLink(send, release) {
|
|
|
4833
4849
|
finish();
|
|
4834
4850
|
return response;
|
|
4835
4851
|
}
|
|
4836
|
-
|
|
4852
|
+
failers.delete(fail);
|
|
4853
|
+
const body = guardBody(response.body, finish, request);
|
|
4854
|
+
fail = body.fail;
|
|
4855
|
+
if (closed) fail(lostReason);
|
|
4856
|
+
else if (!finished) failers.add(fail);
|
|
4857
|
+
return new Response(body.stream, {
|
|
4837
4858
|
status: response.status,
|
|
4838
4859
|
statusText: response.statusText,
|
|
4839
4860
|
headers: response.headers
|
|
@@ -4852,56 +4873,62 @@ function trackedLink(send, release) {
|
|
|
4852
4873
|
return asyncDisposable(link, () => link.close());
|
|
4853
4874
|
}
|
|
4854
4875
|
/**
|
|
4855
|
-
* A response body that reports its end (done, cancelled, failed or aborted)
|
|
4856
|
-
*
|
|
4857
|
-
*
|
|
4858
|
-
*
|
|
4876
|
+
* A response body that reports its end (done, cancelled, failed or aborted).
|
|
4877
|
+
* `fail(error)` ends it with `error` at once — the link calls it when it is lost
|
|
4878
|
+
* mid-stream. An abort of the request's signal does the same with the signal's
|
|
4879
|
+
* reason, read or not: the exchange is over (the layer below has given its port
|
|
4880
|
+
* back), so the request leaves `inflight` then. A read waits on the reader
|
|
4881
|
+
* alone, so nothing outlives the chunk it brings.
|
|
4859
4882
|
*/
|
|
4860
|
-
function guardBody(body,
|
|
4883
|
+
function guardBody(body, finish, request) {
|
|
4884
|
+
const keep = { request };
|
|
4885
|
+
const signal = request.signal ?? void 0;
|
|
4861
4886
|
const reader = body.getReader();
|
|
4862
4887
|
let controller;
|
|
4863
4888
|
let ended = false;
|
|
4864
4889
|
const end = () => {
|
|
4865
4890
|
ended = true;
|
|
4866
4891
|
signal?.removeEventListener("abort", onAbort);
|
|
4892
|
+
keep.request = void 0;
|
|
4867
4893
|
finish();
|
|
4868
4894
|
};
|
|
4869
|
-
const
|
|
4895
|
+
const fail = (error) => {
|
|
4870
4896
|
if (ended) return;
|
|
4871
4897
|
end();
|
|
4872
4898
|
reader.cancel().catch(() => {});
|
|
4873
4899
|
try {
|
|
4874
|
-
controller.error(
|
|
4900
|
+
controller.error(error);
|
|
4875
4901
|
} catch {}
|
|
4876
4902
|
};
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4903
|
+
const onAbort = () => fail(abortError(signal));
|
|
4904
|
+
return {
|
|
4905
|
+
stream: new ReadableStream({
|
|
4906
|
+
start(c) {
|
|
4907
|
+
controller = c;
|
|
4908
|
+
if (signal?.aborted) onAbort();
|
|
4909
|
+
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
4910
|
+
},
|
|
4911
|
+
async pull(controller) {
|
|
4912
|
+
try {
|
|
4913
|
+
const { done, value } = await reader.read();
|
|
4914
|
+
if (ended) return;
|
|
4915
|
+
if (done) {
|
|
4916
|
+
end();
|
|
4917
|
+
controller.close();
|
|
4918
|
+
return;
|
|
4919
|
+
}
|
|
4920
|
+
controller.enqueue(value);
|
|
4921
|
+
} catch (error) {
|
|
4922
|
+
fail(error);
|
|
4891
4923
|
}
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
if (ended) return;
|
|
4924
|
+
},
|
|
4925
|
+
cancel(why) {
|
|
4895
4926
|
end();
|
|
4896
|
-
reader.cancel().catch(() => {});
|
|
4897
|
-
controller.error(reason() ?? error);
|
|
4927
|
+
setTimeout(() => void reader.cancel(why).catch(() => {}), 0);
|
|
4898
4928
|
}
|
|
4899
|
-
},
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
await reader.cancel(why).catch(() => {});
|
|
4903
|
-
}
|
|
4904
|
-
});
|
|
4929
|
+
}),
|
|
4930
|
+
fail
|
|
4931
|
+
};
|
|
4905
4932
|
}
|
|
4906
4933
|
/** The signal's reason as an `Error` (`AbortError` when it gave none). */
|
|
4907
4934
|
function abortError(signal) {
|
|
@@ -8077,7 +8104,10 @@ function serveHttpInWorker(handler, options = {}) {
|
|
|
8077
8104
|
let WebSocketClass;
|
|
8078
8105
|
return {
|
|
8079
8106
|
fetch(input, init) {
|
|
8080
|
-
const request = input instanceof Request && init === void 0 ? input : new Request(input instanceof Request ? input : new URL(`${input}`, baseUrl()),
|
|
8107
|
+
const request = input instanceof Request && init === void 0 ? input : new Request(input instanceof Request ? input : new URL(`${input}`, baseUrl()), {
|
|
8108
|
+
...init,
|
|
8109
|
+
signal: init && "signal" in init ? init.signal : input instanceof Request ? input.signal : void 0
|
|
8110
|
+
});
|
|
8081
8111
|
return endpoint.fetch(request);
|
|
8082
8112
|
},
|
|
8083
8113
|
connectWebSocket,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-link.d.ts","sourceRoot":"","sources":["../../src/link/http-link.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAO,SAAuD,EAGzE;CACF;AASD,qEAAqE;AACrE,wBAAsB,eAAe,CACnC,IAAI,EAAE,WAAW,EACjB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAiC,EAAE,GAAE,eAAoB,GACnF,OAAO,CAAC,QAAQ,CAAC,CAcnB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAC3D,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAE,eAAoB,GAC/D,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAiB9B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC7C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAClC,QAAQ,
|
|
1
|
+
{"version":3,"file":"http-link.d.ts","sourceRoot":"","sources":["../../src/link/http-link.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAO,SAAuD,EAGzE;CACF;AASD,qEAAqE;AACrE,wBAAsB,eAAe,CACnC,IAAI,EAAE,WAAW,EACjB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAiC,EAAE,GAAE,eAAoB,GACnF,OAAO,CAAC,QAAQ,CAAC,CAcnB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAC3D,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAE,eAAoB,GAC/D,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAiB9B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC7C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAClC,QAAQ,CA4EV"}
|
package/dist/relay-sw.js
CHANGED
|
@@ -1138,7 +1138,10 @@
|
|
|
1138
1138
|
}
|
|
1139
1139
|
const onAbort = () => void release();
|
|
1140
1140
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1141
|
-
|
|
1141
|
+
options.keepAlive;
|
|
1142
|
+
drain(output).finally(() => {
|
|
1143
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1144
|
+
});
|
|
1142
1145
|
};
|
|
1143
1146
|
let decoded;
|
|
1144
1147
|
try {
|
|
@@ -1388,7 +1391,8 @@
|
|
|
1388
1391
|
}
|
|
1389
1392
|
const { envelope, body: respBody, release, finish } = await httpFetch(call, env, body, {
|
|
1390
1393
|
...options,
|
|
1391
|
-
signal: request.signal ?? void 0
|
|
1394
|
+
signal: request.signal ?? void 0,
|
|
1395
|
+
keepAlive: request
|
|
1392
1396
|
});
|
|
1393
1397
|
const responseInit = {
|
|
1394
1398
|
status: envelope.status,
|
|
@@ -1400,7 +1404,7 @@
|
|
|
1400
1404
|
else await release?.();
|
|
1401
1405
|
return new Response(null, responseInit);
|
|
1402
1406
|
}
|
|
1403
|
-
return new Response(responseBody(respBody, request
|
|
1407
|
+
return new Response(responseBody(respBody, request, release), responseInit);
|
|
1404
1408
|
}
|
|
1405
1409
|
/**
|
|
1406
1410
|
* How long a cancelled body waits for the read in flight before it abandons the call anyway.
|
|
@@ -1423,7 +1427,9 @@
|
|
|
1423
1427
|
* A cancel abandons the call too — unless the read in flight comes back with the
|
|
1424
1428
|
* body's end, which finishes it instead (see `cancel`).
|
|
1425
1429
|
*/
|
|
1426
|
-
function responseBody(body,
|
|
1430
|
+
function responseBody(body, request, release) {
|
|
1431
|
+
const keep = { request };
|
|
1432
|
+
const signal = request.signal ?? void 0;
|
|
1427
1433
|
const it = body[Symbol.asyncIterator]();
|
|
1428
1434
|
let controller;
|
|
1429
1435
|
let ended = false;
|
|
@@ -1431,6 +1437,7 @@
|
|
|
1431
1437
|
const end = () => {
|
|
1432
1438
|
ended = true;
|
|
1433
1439
|
signal?.removeEventListener("abort", onAbort);
|
|
1440
|
+
keep.request = void 0;
|
|
1434
1441
|
};
|
|
1435
1442
|
const onAbort = () => {
|
|
1436
1443
|
if (ended) return;
|
|
@@ -2394,12 +2401,6 @@
|
|
|
2394
2401
|
const producer = output;
|
|
2395
2402
|
const returnProducer = () => void Promise.resolve(producer.return?.()).catch(() => {});
|
|
2396
2403
|
if (framed !== output) signal.addEventListener("abort", returnProducer, { once: true });
|
|
2397
|
-
let onAborted = () => {};
|
|
2398
|
-
const aborted = new Promise((resolve) => {
|
|
2399
|
-
onAborted = () => resolve();
|
|
2400
|
-
});
|
|
2401
|
-
if (signal.aborted) onAborted();
|
|
2402
|
-
else signal.addEventListener("abort", onAborted, { once: true });
|
|
2403
2404
|
try {
|
|
2404
2405
|
await sendIterator(async ({ done, value, error }) => {
|
|
2405
2406
|
if (signal.aborted) return;
|
|
@@ -2421,7 +2422,7 @@
|
|
|
2421
2422
|
});
|
|
2422
2423
|
touch();
|
|
2423
2424
|
if (done && !error) onSent();
|
|
2424
|
-
if (portBufferedAmount(port) > 0) await
|
|
2425
|
+
if (portBufferedAmount(port) > 0) await whenReadyOrAborted(port, signal);
|
|
2425
2426
|
return;
|
|
2426
2427
|
}
|
|
2427
2428
|
await callPort(port, chunk, {
|
|
@@ -2437,10 +2438,25 @@
|
|
|
2437
2438
|
throw err;
|
|
2438
2439
|
} finally {
|
|
2439
2440
|
signal.removeEventListener("abort", returnProducer);
|
|
2440
|
-
signal.removeEventListener("abort", onAborted);
|
|
2441
2441
|
}
|
|
2442
2442
|
}
|
|
2443
2443
|
/**
|
|
2444
|
+
* A pipelined sender waits only for room in the window, or for the abort. The
|
|
2445
|
+
* abort listener lives for this one wait: a promise held for the whole stream
|
|
2446
|
+
* would keep one reaction per wait until the stream ends.
|
|
2447
|
+
*/
|
|
2448
|
+
function whenReadyOrAborted(port, signal) {
|
|
2449
|
+
if (signal.aborted) return Promise.resolve();
|
|
2450
|
+
return new Promise((resolve) => {
|
|
2451
|
+
const settle = () => {
|
|
2452
|
+
signal.removeEventListener("abort", settle);
|
|
2453
|
+
resolve();
|
|
2454
|
+
};
|
|
2455
|
+
signal.addEventListener("abort", settle, { once: true });
|
|
2456
|
+
whenPortReady(port).then(settle, settle);
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2459
|
+
/**
|
|
2444
2460
|
* One virtual port.
|
|
2445
2461
|
*
|
|
2446
2462
|
* `deliver` and `markClosed` are deliberately not on `port`: the consumer holds
|
|
@@ -3366,7 +3382,12 @@
|
|
|
3366
3382
|
finish();
|
|
3367
3383
|
return response;
|
|
3368
3384
|
}
|
|
3369
|
-
|
|
3385
|
+
failers.delete(fail);
|
|
3386
|
+
const body = guardBody(response.body, finish, request);
|
|
3387
|
+
fail = body.fail;
|
|
3388
|
+
if (closed) fail(lostReason);
|
|
3389
|
+
else if (!finished) failers.add(fail);
|
|
3390
|
+
return new Response(body.stream, {
|
|
3370
3391
|
status: response.status,
|
|
3371
3392
|
statusText: response.statusText,
|
|
3372
3393
|
headers: response.headers
|
|
@@ -3385,56 +3406,62 @@
|
|
|
3385
3406
|
return asyncDisposable(link, () => link.close());
|
|
3386
3407
|
}
|
|
3387
3408
|
/**
|
|
3388
|
-
* A response body that reports its end (done, cancelled, failed or aborted)
|
|
3389
|
-
*
|
|
3390
|
-
*
|
|
3391
|
-
*
|
|
3409
|
+
* A response body that reports its end (done, cancelled, failed or aborted).
|
|
3410
|
+
* `fail(error)` ends it with `error` at once — the link calls it when it is lost
|
|
3411
|
+
* mid-stream. An abort of the request's signal does the same with the signal's
|
|
3412
|
+
* reason, read or not: the exchange is over (the layer below has given its port
|
|
3413
|
+
* back), so the request leaves `inflight` then. A read waits on the reader
|
|
3414
|
+
* alone, so nothing outlives the chunk it brings.
|
|
3392
3415
|
*/
|
|
3393
|
-
function guardBody(body,
|
|
3416
|
+
function guardBody(body, finish, request) {
|
|
3417
|
+
const keep = { request };
|
|
3418
|
+
const signal = request.signal ?? void 0;
|
|
3394
3419
|
const reader = body.getReader();
|
|
3395
3420
|
let controller;
|
|
3396
3421
|
let ended = false;
|
|
3397
3422
|
const end = () => {
|
|
3398
3423
|
ended = true;
|
|
3399
3424
|
signal?.removeEventListener("abort", onAbort);
|
|
3425
|
+
keep.request = void 0;
|
|
3400
3426
|
finish();
|
|
3401
3427
|
};
|
|
3402
|
-
const
|
|
3428
|
+
const fail = (error) => {
|
|
3403
3429
|
if (ended) return;
|
|
3404
3430
|
end();
|
|
3405
3431
|
reader.cancel().catch(() => {});
|
|
3406
3432
|
try {
|
|
3407
|
-
controller.error(
|
|
3433
|
+
controller.error(error);
|
|
3408
3434
|
} catch {}
|
|
3409
3435
|
};
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3436
|
+
const onAbort = () => fail(abortError(signal));
|
|
3437
|
+
return {
|
|
3438
|
+
stream: new ReadableStream({
|
|
3439
|
+
start(c) {
|
|
3440
|
+
controller = c;
|
|
3441
|
+
if (signal?.aborted) onAbort();
|
|
3442
|
+
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
3443
|
+
},
|
|
3444
|
+
async pull(controller) {
|
|
3445
|
+
try {
|
|
3446
|
+
const { done, value } = await reader.read();
|
|
3447
|
+
if (ended) return;
|
|
3448
|
+
if (done) {
|
|
3449
|
+
end();
|
|
3450
|
+
controller.close();
|
|
3451
|
+
return;
|
|
3452
|
+
}
|
|
3453
|
+
controller.enqueue(value);
|
|
3454
|
+
} catch (error) {
|
|
3455
|
+
fail(error);
|
|
3424
3456
|
}
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
if (ended) return;
|
|
3457
|
+
},
|
|
3458
|
+
cancel(why) {
|
|
3428
3459
|
end();
|
|
3429
|
-
reader.cancel().catch(() => {});
|
|
3430
|
-
controller.error(reason() ?? error);
|
|
3460
|
+
setTimeout(() => void reader.cancel(why).catch(() => {}), 0);
|
|
3431
3461
|
}
|
|
3432
|
-
},
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
await reader.cancel(why).catch(() => {});
|
|
3436
|
-
}
|
|
3437
|
-
});
|
|
3462
|
+
}),
|
|
3463
|
+
fail
|
|
3464
|
+
};
|
|
3438
3465
|
}
|
|
3439
3466
|
/** The signal's reason as an `Error` (`AbortError` when it gave none). */
|
|
3440
3467
|
function abortError(signal) {
|
package/dist/relay-worker.js
CHANGED
|
@@ -1137,7 +1137,10 @@ async function httpFetch(call, env, body, options = {}) {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
const onAbort = () => void release();
|
|
1139
1139
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1140
|
-
|
|
1140
|
+
options.keepAlive;
|
|
1141
|
+
drain(output).finally(() => {
|
|
1142
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1143
|
+
});
|
|
1141
1144
|
};
|
|
1142
1145
|
let decoded;
|
|
1143
1146
|
try {
|
|
@@ -1387,7 +1390,8 @@ async function fetchOverDuplex(call, request, options = {}) {
|
|
|
1387
1390
|
}
|
|
1388
1391
|
const { envelope, body: respBody, release, finish } = await httpFetch(call, env, body, {
|
|
1389
1392
|
...options,
|
|
1390
|
-
signal: request.signal ?? void 0
|
|
1393
|
+
signal: request.signal ?? void 0,
|
|
1394
|
+
keepAlive: request
|
|
1391
1395
|
});
|
|
1392
1396
|
const responseInit = {
|
|
1393
1397
|
status: envelope.status,
|
|
@@ -1399,7 +1403,7 @@ async function fetchOverDuplex(call, request, options = {}) {
|
|
|
1399
1403
|
else await release?.();
|
|
1400
1404
|
return new Response(null, responseInit);
|
|
1401
1405
|
}
|
|
1402
|
-
return new Response(responseBody(respBody, request
|
|
1406
|
+
return new Response(responseBody(respBody, request, release), responseInit);
|
|
1403
1407
|
}
|
|
1404
1408
|
/**
|
|
1405
1409
|
* How long a cancelled body waits for the read in flight before it abandons the call anyway.
|
|
@@ -1422,7 +1426,9 @@ const CANCEL_GRACE_MS = 1e3;
|
|
|
1422
1426
|
* A cancel abandons the call too — unless the read in flight comes back with the
|
|
1423
1427
|
* body's end, which finishes it instead (see `cancel`).
|
|
1424
1428
|
*/
|
|
1425
|
-
function responseBody(body,
|
|
1429
|
+
function responseBody(body, request, release) {
|
|
1430
|
+
const keep = { request };
|
|
1431
|
+
const signal = request.signal ?? void 0;
|
|
1426
1432
|
const it = body[Symbol.asyncIterator]();
|
|
1427
1433
|
let controller;
|
|
1428
1434
|
let ended = false;
|
|
@@ -1430,6 +1436,7 @@ function responseBody(body, signal, release) {
|
|
|
1430
1436
|
const end = () => {
|
|
1431
1437
|
ended = true;
|
|
1432
1438
|
signal?.removeEventListener("abort", onAbort);
|
|
1439
|
+
keep.request = void 0;
|
|
1433
1440
|
};
|
|
1434
1441
|
const onAbort = () => {
|
|
1435
1442
|
if (ended) return;
|
|
@@ -2393,12 +2400,6 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
2393
2400
|
const producer = output;
|
|
2394
2401
|
const returnProducer = () => void Promise.resolve(producer.return?.()).catch(() => {});
|
|
2395
2402
|
if (framed !== output) signal.addEventListener("abort", returnProducer, { once: true });
|
|
2396
|
-
let onAborted = () => {};
|
|
2397
|
-
const aborted = new Promise((resolve) => {
|
|
2398
|
-
onAborted = () => resolve();
|
|
2399
|
-
});
|
|
2400
|
-
if (signal.aborted) onAborted();
|
|
2401
|
-
else signal.addEventListener("abort", onAborted, { once: true });
|
|
2402
2403
|
try {
|
|
2403
2404
|
await sendIterator(async ({ done, value, error }) => {
|
|
2404
2405
|
if (signal.aborted) return;
|
|
@@ -2420,7 +2421,7 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
2420
2421
|
});
|
|
2421
2422
|
touch();
|
|
2422
2423
|
if (done && !error) onSent();
|
|
2423
|
-
if (portBufferedAmount(port) > 0) await
|
|
2424
|
+
if (portBufferedAmount(port) > 0) await whenReadyOrAborted(port, signal);
|
|
2424
2425
|
return;
|
|
2425
2426
|
}
|
|
2426
2427
|
await callPort(port, chunk, {
|
|
@@ -2436,10 +2437,25 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
|
|
|
2436
2437
|
throw err;
|
|
2437
2438
|
} finally {
|
|
2438
2439
|
signal.removeEventListener("abort", returnProducer);
|
|
2439
|
-
signal.removeEventListener("abort", onAborted);
|
|
2440
2440
|
}
|
|
2441
2441
|
}
|
|
2442
2442
|
/**
|
|
2443
|
+
* A pipelined sender waits only for room in the window, or for the abort. The
|
|
2444
|
+
* abort listener lives for this one wait: a promise held for the whole stream
|
|
2445
|
+
* would keep one reaction per wait until the stream ends.
|
|
2446
|
+
*/
|
|
2447
|
+
function whenReadyOrAborted(port, signal) {
|
|
2448
|
+
if (signal.aborted) return Promise.resolve();
|
|
2449
|
+
return new Promise((resolve) => {
|
|
2450
|
+
const settle = () => {
|
|
2451
|
+
signal.removeEventListener("abort", settle);
|
|
2452
|
+
resolve();
|
|
2453
|
+
};
|
|
2454
|
+
signal.addEventListener("abort", settle, { once: true });
|
|
2455
|
+
whenPortReady(port).then(settle, settle);
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
/**
|
|
2443
2459
|
* One virtual port.
|
|
2444
2460
|
*
|
|
2445
2461
|
* `deliver` and `markClosed` are deliberately not on `port`: the consumer holds
|
|
@@ -3365,7 +3381,12 @@ function trackedLink(send, release) {
|
|
|
3365
3381
|
finish();
|
|
3366
3382
|
return response;
|
|
3367
3383
|
}
|
|
3368
|
-
|
|
3384
|
+
failers.delete(fail);
|
|
3385
|
+
const body = guardBody(response.body, finish, request);
|
|
3386
|
+
fail = body.fail;
|
|
3387
|
+
if (closed) fail(lostReason);
|
|
3388
|
+
else if (!finished) failers.add(fail);
|
|
3389
|
+
return new Response(body.stream, {
|
|
3369
3390
|
status: response.status,
|
|
3370
3391
|
statusText: response.statusText,
|
|
3371
3392
|
headers: response.headers
|
|
@@ -3384,56 +3405,62 @@ function trackedLink(send, release) {
|
|
|
3384
3405
|
return asyncDisposable(link, () => link.close());
|
|
3385
3406
|
}
|
|
3386
3407
|
/**
|
|
3387
|
-
* A response body that reports its end (done, cancelled, failed or aborted)
|
|
3388
|
-
*
|
|
3389
|
-
*
|
|
3390
|
-
*
|
|
3408
|
+
* A response body that reports its end (done, cancelled, failed or aborted).
|
|
3409
|
+
* `fail(error)` ends it with `error` at once — the link calls it when it is lost
|
|
3410
|
+
* mid-stream. An abort of the request's signal does the same with the signal's
|
|
3411
|
+
* reason, read or not: the exchange is over (the layer below has given its port
|
|
3412
|
+
* back), so the request leaves `inflight` then. A read waits on the reader
|
|
3413
|
+
* alone, so nothing outlives the chunk it brings.
|
|
3391
3414
|
*/
|
|
3392
|
-
function guardBody(body,
|
|
3415
|
+
function guardBody(body, finish, request) {
|
|
3416
|
+
const keep = { request };
|
|
3417
|
+
const signal = request.signal ?? void 0;
|
|
3393
3418
|
const reader = body.getReader();
|
|
3394
3419
|
let controller;
|
|
3395
3420
|
let ended = false;
|
|
3396
3421
|
const end = () => {
|
|
3397
3422
|
ended = true;
|
|
3398
3423
|
signal?.removeEventListener("abort", onAbort);
|
|
3424
|
+
keep.request = void 0;
|
|
3399
3425
|
finish();
|
|
3400
3426
|
};
|
|
3401
|
-
const
|
|
3427
|
+
const fail = (error) => {
|
|
3402
3428
|
if (ended) return;
|
|
3403
3429
|
end();
|
|
3404
3430
|
reader.cancel().catch(() => {});
|
|
3405
3431
|
try {
|
|
3406
|
-
controller.error(
|
|
3432
|
+
controller.error(error);
|
|
3407
3433
|
} catch {}
|
|
3408
3434
|
};
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3435
|
+
const onAbort = () => fail(abortError(signal));
|
|
3436
|
+
return {
|
|
3437
|
+
stream: new ReadableStream({
|
|
3438
|
+
start(c) {
|
|
3439
|
+
controller = c;
|
|
3440
|
+
if (signal?.aborted) onAbort();
|
|
3441
|
+
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
3442
|
+
},
|
|
3443
|
+
async pull(controller) {
|
|
3444
|
+
try {
|
|
3445
|
+
const { done, value } = await reader.read();
|
|
3446
|
+
if (ended) return;
|
|
3447
|
+
if (done) {
|
|
3448
|
+
end();
|
|
3449
|
+
controller.close();
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3452
|
+
controller.enqueue(value);
|
|
3453
|
+
} catch (error) {
|
|
3454
|
+
fail(error);
|
|
3423
3455
|
}
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
if (ended) return;
|
|
3456
|
+
},
|
|
3457
|
+
cancel(why) {
|
|
3427
3458
|
end();
|
|
3428
|
-
reader.cancel().catch(() => {});
|
|
3429
|
-
controller.error(reason() ?? error);
|
|
3459
|
+
setTimeout(() => void reader.cancel(why).catch(() => {}), 0);
|
|
3430
3460
|
}
|
|
3431
|
-
},
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
await reader.cancel(why).catch(() => {});
|
|
3435
|
-
}
|
|
3436
|
-
});
|
|
3461
|
+
}),
|
|
3462
|
+
fail
|
|
3463
|
+
};
|
|
3437
3464
|
}
|
|
3438
3465
|
/** The signal's reason as an `Error` (`AbortError` when it gave none). */
|
|
3439
3466
|
function abortError(signal) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-service.d.ts","sourceRoot":"","sources":["../../src/sw/worker-service.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,wBACf,SAAQ,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,WAAW,CAAC;IACnE,mFAAmF;IACnF,KAAK,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,qBAAqB,CAAC,CAAC;IACtE,8DAA8D;IAC9D,SAAS,CAAC,EAAE,qBAAqB,CAAC;CACnC;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE;;;OAGG;IACH,gBAAgB,CACd,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,8CAA8C;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"worker-service.d.ts","sourceRoot":"","sources":["../../src/sw/worker-service.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,wBACf,SAAQ,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,WAAW,CAAC;IACnE,mFAAmF;IACnF,KAAK,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,qBAAqB,CAAC,CAAC;IACtE,8DAA8D;IAC9D,SAAS,CAAC,EAAE,qBAAqB,CAAC;CACnC;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE;;;OAGG;IACH,gBAAgB,CACd,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,8CAA8C;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CA+FnB"}
|