@statewalker/webrun-rpc 0.10.0 → 0.10.1

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 CHANGED
@@ -1106,12 +1106,6 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
1106
1106
  const producer = output;
1107
1107
  const returnProducer = () => void Promise.resolve(producer.return?.()).catch(() => {});
1108
1108
  if (framed !== output) signal.addEventListener("abort", returnProducer, { once: true });
1109
- let onAborted = () => {};
1110
- const aborted = new Promise((resolve) => {
1111
- onAborted = () => resolve();
1112
- });
1113
- if (signal.aborted) onAborted();
1114
- else signal.addEventListener("abort", onAborted, { once: true });
1115
1109
  try {
1116
1110
  await sendIterator(async ({ done, value, error }) => {
1117
1111
  if (signal.aborted) return;
@@ -1133,7 +1127,7 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
1133
1127
  });
1134
1128
  touch();
1135
1129
  if (done && !error) onSent();
1136
- if (portBufferedAmount(port) > 0) await Promise.race([whenPortReady(port), aborted]);
1130
+ if (portBufferedAmount(port) > 0) await whenReadyOrAborted(port, signal);
1137
1131
  return;
1138
1132
  }
1139
1133
  await callPort(port, chunk, {
@@ -1149,9 +1143,24 @@ async function sendChunks(port, channelName, output, { maxMessageSize, log }, si
1149
1143
  throw err;
1150
1144
  } finally {
1151
1145
  signal.removeEventListener("abort", returnProducer);
1152
- signal.removeEventListener("abort", onAborted);
1153
1146
  }
1154
1147
  }
1148
+ /**
1149
+ * A pipelined sender waits only for room in the window, or for the abort. The
1150
+ * abort listener lives for this one wait: a promise held for the whole stream
1151
+ * would keep one reaction per wait until the stream ends.
1152
+ */
1153
+ function whenReadyOrAborted(port, signal) {
1154
+ if (signal.aborted) return Promise.resolve();
1155
+ return new Promise((resolve) => {
1156
+ const settle = () => {
1157
+ signal.removeEventListener("abort", settle);
1158
+ resolve();
1159
+ };
1160
+ signal.addEventListener("abort", settle, { once: true });
1161
+ whenPortReady(port).then(settle, settle);
1162
+ });
1163
+ }
1155
1164
  //#endregion
1156
1165
  //#region src/virtual-port.ts
1157
1166
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statewalker/webrun-rpc",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Ports and RPC over them: a port multiplexer, and typed request/response and streaming primitives over any MessageTarget.",
@@ -766,13 +766,6 @@ async function sendChunks(
766
766
  const producer = output as Partial<AsyncIterator<Uint8Array>>;
767
767
  const returnProducer = () => void Promise.resolve(producer.return?.()).catch(() => {});
768
768
  if (framed !== output) signal.addEventListener("abort", returnProducer, { once: true });
769
- // A pipelined sender waits only for room in the window, or for the abort.
770
- let onAborted = () => {};
771
- const aborted = new Promise<void>((resolve) => {
772
- onAborted = () => resolve();
773
- });
774
- if (signal.aborted) onAborted();
775
- else signal.addEventListener("abort", onAborted, { once: true });
776
769
  try {
777
770
  await sendIterator<Uint8Array>(async ({ done, value, error }) => {
778
771
  if (signal.aborted) return;
@@ -788,7 +781,7 @@ async function sendChunks(
788
781
  port.postMessage({ type: CHUNK, channelName, chunk });
789
782
  touch();
790
783
  if (done && !error) onSent();
791
- if (portBufferedAmount(port) > 0) await Promise.race([whenPortReady(port), aborted]);
784
+ if (portBufferedAmount(port) > 0) await whenReadyOrAborted(port, signal);
792
785
  return;
793
786
  }
794
787
  await callPort<void, WireChunk>(port, chunk, {
@@ -806,6 +799,22 @@ async function sendChunks(
806
799
  throw err;
807
800
  } finally {
808
801
  signal.removeEventListener("abort", returnProducer);
809
- signal.removeEventListener("abort", onAborted);
810
802
  }
811
803
  }
804
+
805
+ /**
806
+ * A pipelined sender waits only for room in the window, or for the abort. The
807
+ * abort listener lives for this one wait: a promise held for the whole stream
808
+ * would keep one reaction per wait until the stream ends.
809
+ */
810
+ function whenReadyOrAborted(port: MessageTarget, signal: AbortSignal): Promise<void> {
811
+ if (signal.aborted) return Promise.resolve();
812
+ return new Promise<void>((resolve) => {
813
+ const settle = () => {
814
+ signal.removeEventListener("abort", settle);
815
+ resolve();
816
+ };
817
+ signal.addEventListener("abort", settle, { once: true });
818
+ whenPortReady(port).then(settle, settle);
819
+ });
820
+ }