capnweb 0.0.0-bd22055 → 0.0.0-c70bbb7
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 +7 -0
- package/dist/index-bun.cjs +144 -46
- package/dist/index-bun.cjs.map +1 -1
- package/dist/index-bun.d.cts +82 -6
- package/dist/index-bun.d.ts +82 -6
- package/dist/index-bun.js +144 -47
- package/dist/index-bun.js.map +1 -1
- package/dist/index-workers.cjs +144 -46
- package/dist/index-workers.cjs.map +1 -1
- package/dist/index-workers.d.cts +82 -6
- package/dist/index-workers.d.ts +82 -6
- package/dist/index-workers.js +144 -47
- package/dist/index-workers.js.map +1 -1
- package/dist/index.cjs +144 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -6
- package/dist/index.d.ts +82 -6
- package/dist/index.js +144 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -776,3 +776,10 @@ let stub: RemoteMainInterface = session.getRemoteMain();
|
|
|
776
776
|
```
|
|
777
777
|
|
|
778
778
|
Note that sessions are entirely symmetric: neither side is defined as the "client" nor the "server". Each side can optionally expose a "main interface" to the other. In typical scenarios with a logical client and server, the server exposes a main interface but the client does not.
|
|
779
|
+
|
|
780
|
+
By default, `send()` accepts a string, and `receive()` returns a string, with Cap'n Web handling the encoding all the way to and from strings. However, transports that want more control over the serialization can declare the property `encodingLevel` to control how much encoding Cap'n Web does before passing off the message:
|
|
781
|
+
|
|
782
|
+
* `"string"` (default): Full JSON round-trip. The transport deals in strings only. Cap'n Web handles all encoding/decoding. This is what HTTP batch and WebSocket transports use.
|
|
783
|
+
* `"jsonCompatible"`: The transport works with JavaScript value trees, but they must be JSON-compatible. Cap'n Web still encodes special types, but skips the final `JSON.stringify`. The transport is responsible for serialization (e.g. to CBOR, MessagePack).
|
|
784
|
+
* `"jsonCompatibleWithBytes"`: Like `"jsonCompatible"` except that byte arrays are left as `Uint8Array` instead of base64-encoded, avoiding the ~33% base64 size overhead and the encode/decode CPU cost. Handy for use with serializations like CBOR or MessagePack that support this efficiently.
|
|
785
|
+
* `"structuredClonable"`: Messages are structured-clonable values. Cap'n Web passes through native structured-clone types where possible, while still handling RPC-specific values such as stubs. This is useful when the transport is a `MessagePort` or similar.
|
package/dist/index-bun.cjs
CHANGED
|
@@ -963,12 +963,14 @@ const ERROR_TYPES = {
|
|
|
963
963
|
var Devaluator = class Devaluator {
|
|
964
964
|
exporter;
|
|
965
965
|
source;
|
|
966
|
-
|
|
966
|
+
encodingLevel;
|
|
967
|
+
constructor(exporter, source, encodingLevel) {
|
|
967
968
|
this.exporter = exporter;
|
|
968
969
|
this.source = source;
|
|
970
|
+
this.encodingLevel = encodingLevel;
|
|
969
971
|
}
|
|
970
|
-
static devaluate(value, parent, exporter = NULL_EXPORTER, source) {
|
|
971
|
-
let devaluator = new Devaluator(exporter, source);
|
|
972
|
+
static devaluate(value, parent, exporter = NULL_EXPORTER, source, encodingLevel = "string") {
|
|
973
|
+
let devaluator = new Devaluator(exporter, source, encodingLevel);
|
|
972
974
|
try {
|
|
973
975
|
return devaluator.devaluateImpl(value, parent, 0);
|
|
974
976
|
} catch (err) {
|
|
@@ -991,10 +993,12 @@ var Devaluator = class Devaluator {
|
|
|
991
993
|
}
|
|
992
994
|
throw new TypeError(msg);
|
|
993
995
|
}
|
|
994
|
-
case "primitive": if (typeof value === "number" && !isFinite(value))
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
996
|
+
case "primitive": if (typeof value === "number" && !isFinite(value)) {
|
|
997
|
+
if (this.encodingLevel === "structuredClonable") return value;
|
|
998
|
+
if (value === Infinity) return ["inf"];
|
|
999
|
+
else if (value === -Infinity) return ["-inf"];
|
|
1000
|
+
else return ["nan"];
|
|
1001
|
+
} else return value;
|
|
998
1002
|
case "object": {
|
|
999
1003
|
let object = value;
|
|
1000
1004
|
let result = {};
|
|
@@ -1008,13 +1012,17 @@ var Devaluator = class Devaluator {
|
|
|
1008
1012
|
for (let i = 0; i < len; i++) result[i] = this.devaluateImpl(array[i], array, depth + 1);
|
|
1009
1013
|
return [result];
|
|
1010
1014
|
}
|
|
1011
|
-
case "bigint":
|
|
1015
|
+
case "bigint":
|
|
1016
|
+
if (this.encodingLevel === "structuredClonable") return value;
|
|
1017
|
+
return ["bigint", value.toString()];
|
|
1012
1018
|
case "date": {
|
|
1019
|
+
if (this.encodingLevel === "structuredClonable") return value;
|
|
1013
1020
|
const time = value.getTime();
|
|
1014
1021
|
return ["date", Number.isNaN(time) ? null : time];
|
|
1015
1022
|
}
|
|
1016
1023
|
case "bytes": {
|
|
1017
1024
|
let bytes = value;
|
|
1025
|
+
if (this.encodingLevel === "structuredClonable" || this.encodingLevel === "jsonCompatibleWithBytes") return ["bytes", bytes];
|
|
1018
1026
|
if (bytes.toBase64) return ["bytes", bytes.toBase64({ omitPadding: true })];
|
|
1019
1027
|
let b64;
|
|
1020
1028
|
if (typeof Buffer !== "undefined") b64 = (bytes instanceof Buffer ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)).toString("base64");
|
|
@@ -1139,7 +1147,9 @@ var Devaluator = class Devaluator {
|
|
|
1139
1147
|
} else if (rewritten && rewritten.stack) result.push(rewritten.stack);
|
|
1140
1148
|
return result;
|
|
1141
1149
|
}
|
|
1142
|
-
case "undefined":
|
|
1150
|
+
case "undefined":
|
|
1151
|
+
if (this.encodingLevel === "structuredClonable") return;
|
|
1152
|
+
return ["undefined"];
|
|
1143
1153
|
case "stub":
|
|
1144
1154
|
case "rpc-promise": {
|
|
1145
1155
|
if (!this.source) throw new Error("Can't serialize RPC stubs in this context.");
|
|
@@ -1222,8 +1232,10 @@ function streamToBlobPromise(stream, type) {
|
|
|
1222
1232
|
}
|
|
1223
1233
|
var Evaluator = class Evaluator {
|
|
1224
1234
|
importer;
|
|
1225
|
-
|
|
1235
|
+
encodingLevel;
|
|
1236
|
+
constructor(importer, encodingLevel = "string") {
|
|
1226
1237
|
this.importer = importer;
|
|
1238
|
+
this.encodingLevel = encodingLevel;
|
|
1227
1239
|
}
|
|
1228
1240
|
hooks = [];
|
|
1229
1241
|
promises = [];
|
|
@@ -1241,6 +1253,9 @@ var Evaluator = class Evaluator {
|
|
|
1241
1253
|
return this.evaluate(structuredClone(value));
|
|
1242
1254
|
}
|
|
1243
1255
|
evaluateImpl(value, parent, property) {
|
|
1256
|
+
if (this.encodingLevel === "structuredClonable") {
|
|
1257
|
+
if (value instanceof Date || typeof value === "bigint") return value;
|
|
1258
|
+
}
|
|
1244
1259
|
if (value instanceof Array) {
|
|
1245
1260
|
if (value.length == 1 && value[0] instanceof Array) {
|
|
1246
1261
|
let result = value[0];
|
|
@@ -1255,6 +1270,7 @@ var Evaluator = class Evaluator {
|
|
|
1255
1270
|
if (typeof value[1] == "number") return new Date(value[1]);
|
|
1256
1271
|
break;
|
|
1257
1272
|
case "bytes":
|
|
1273
|
+
if (value[1] instanceof Uint8Array) return value[1];
|
|
1258
1274
|
if (typeof value[1] == "string") if (typeof Buffer !== "undefined") return Buffer.from(value[1], "base64");
|
|
1259
1275
|
else if (Uint8Array.fromBase64) return Uint8Array.fromBase64(value[1]);
|
|
1260
1276
|
else {
|
|
@@ -1455,6 +1471,47 @@ function deserialize(value) {
|
|
|
1455
1471
|
|
|
1456
1472
|
//#endregion
|
|
1457
1473
|
//#region src/rpc.ts
|
|
1474
|
+
const ESTIMATED_OBJECT_OVERHEAD = 16;
|
|
1475
|
+
const ESTIMATED_ENTRY_OVERHEAD = 8;
|
|
1476
|
+
const ESTIMATED_BINARY_OVERHEAD = 16;
|
|
1477
|
+
const MAX_ESTIMATE_DEPTH = 64;
|
|
1478
|
+
function estimateStringSize(value) {
|
|
1479
|
+
return 2 + value.length * 3;
|
|
1480
|
+
}
|
|
1481
|
+
function estimateEncodedSize(value, seen, depth = 0) {
|
|
1482
|
+
if (depth >= MAX_ESTIMATE_DEPTH) return ESTIMATED_ENTRY_OVERHEAD;
|
|
1483
|
+
switch (typeof value) {
|
|
1484
|
+
case "string": return estimateStringSize(value);
|
|
1485
|
+
case "number": return 16;
|
|
1486
|
+
case "bigint": return 16;
|
|
1487
|
+
case "boolean": return 8;
|
|
1488
|
+
case "undefined": return 16;
|
|
1489
|
+
case "object": {
|
|
1490
|
+
if (value === null) return 8;
|
|
1491
|
+
if (ArrayBuffer.isView(value)) return ESTIMATED_BINARY_OVERHEAD + value.byteLength;
|
|
1492
|
+
if (value instanceof ArrayBuffer) return ESTIMATED_BINARY_OVERHEAD + value.byteLength;
|
|
1493
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return ESTIMATED_BINARY_OVERHEAD + value.size;
|
|
1494
|
+
if (value instanceof Date) return 16;
|
|
1495
|
+
seen ??= /* @__PURE__ */ new WeakSet();
|
|
1496
|
+
if (seen.has(value)) return ESTIMATED_ENTRY_OVERHEAD;
|
|
1497
|
+
seen.add(value);
|
|
1498
|
+
if (value instanceof Array) {
|
|
1499
|
+
let size = ESTIMATED_OBJECT_OVERHEAD;
|
|
1500
|
+
for (let item of value) size += ESTIMATED_ENTRY_OVERHEAD + estimateEncodedSize(item, seen, depth + 1);
|
|
1501
|
+
return size;
|
|
1502
|
+
}
|
|
1503
|
+
if (value instanceof Error) {
|
|
1504
|
+
let size = ESTIMATED_OBJECT_OVERHEAD + estimateStringSize(value.name) + estimateStringSize(value.message) + estimateStringSize(value.stack ?? "");
|
|
1505
|
+
for (let key of Object.keys(value)) size += ESTIMATED_ENTRY_OVERHEAD + estimateStringSize(key) + estimateEncodedSize(value[key], seen, depth + 1);
|
|
1506
|
+
return size;
|
|
1507
|
+
}
|
|
1508
|
+
let size = ESTIMATED_OBJECT_OVERHEAD;
|
|
1509
|
+
for (let key of Object.keys(value)) size += ESTIMATED_ENTRY_OVERHEAD + estimateStringSize(key) + estimateEncodedSize(value[key], seen, depth + 1);
|
|
1510
|
+
return size;
|
|
1511
|
+
}
|
|
1512
|
+
default: return 16;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1458
1515
|
var ImportTableEntry = class {
|
|
1459
1516
|
session;
|
|
1460
1517
|
importId;
|
|
@@ -1620,9 +1677,19 @@ var RpcSessionImpl = class {
|
|
|
1620
1677
|
onBatchDone;
|
|
1621
1678
|
pullCount = 0;
|
|
1622
1679
|
onBrokenCallbacks = [];
|
|
1680
|
+
encodingLevel;
|
|
1623
1681
|
constructor(transport, mainHook, options) {
|
|
1624
1682
|
this.transport = transport;
|
|
1625
1683
|
this.options = options;
|
|
1684
|
+
let level = "string";
|
|
1685
|
+
if ("encodingLevel" in transport) {
|
|
1686
|
+
let raw = transport.encodingLevel;
|
|
1687
|
+
if (raw !== void 0) {
|
|
1688
|
+
if (raw !== "string" && raw !== "jsonCompatible" && raw !== "jsonCompatibleWithBytes" && raw !== "structuredClonable") throw new TypeError(`Unknown transport encodingLevel: ${String(raw)}`);
|
|
1689
|
+
level = raw;
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
this.encodingLevel = level;
|
|
1626
1693
|
this.exports.push({
|
|
1627
1694
|
hook: mainHook,
|
|
1628
1695
|
refcount: 1
|
|
@@ -1703,7 +1770,7 @@ var RpcSessionImpl = class {
|
|
|
1703
1770
|
let autoRelease = exp.autoRelease;
|
|
1704
1771
|
++this.pullCount;
|
|
1705
1772
|
exp.pull = resolve().then((payload) => {
|
|
1706
|
-
let value = Devaluator.devaluate(payload.value, void 0, this, payload);
|
|
1773
|
+
let value = Devaluator.devaluate(payload.value, void 0, this, payload, this.encodingLevel);
|
|
1707
1774
|
this.send([
|
|
1708
1775
|
"resolve",
|
|
1709
1776
|
exportId,
|
|
@@ -1714,7 +1781,7 @@ var RpcSessionImpl = class {
|
|
|
1714
1781
|
this.send([
|
|
1715
1782
|
"reject",
|
|
1716
1783
|
exportId,
|
|
1717
|
-
Devaluator.devaluate(error, void 0, this)
|
|
1784
|
+
Devaluator.devaluate(error, void 0, this, void 0, this.encodingLevel)
|
|
1718
1785
|
]);
|
|
1719
1786
|
if (autoRelease) this.releaseExport(exportId, 1);
|
|
1720
1787
|
}).catch((error) => {
|
|
@@ -1722,7 +1789,7 @@ var RpcSessionImpl = class {
|
|
|
1722
1789
|
this.send([
|
|
1723
1790
|
"reject",
|
|
1724
1791
|
exportId,
|
|
1725
|
-
Devaluator.devaluate(error, void 0, this)
|
|
1792
|
+
Devaluator.devaluate(error, void 0, this, void 0, this.encodingLevel)
|
|
1726
1793
|
]);
|
|
1727
1794
|
if (autoRelease) this.releaseExport(exportId, 1);
|
|
1728
1795
|
} catch (error2) {
|
|
@@ -1778,17 +1845,33 @@ var RpcSessionImpl = class {
|
|
|
1778
1845
|
}
|
|
1779
1846
|
send(msg) {
|
|
1780
1847
|
if (this.abortReason !== void 0) return 0;
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
msgText = JSON.stringify(msg);
|
|
1784
|
-
} catch (err) {
|
|
1848
|
+
if (this.encodingLevel === "string") {
|
|
1849
|
+
let msgText;
|
|
1785
1850
|
try {
|
|
1786
|
-
|
|
1787
|
-
} catch (
|
|
1788
|
-
|
|
1851
|
+
msgText = JSON.stringify(msg);
|
|
1852
|
+
} catch (err) {
|
|
1853
|
+
try {
|
|
1854
|
+
this.abort(err);
|
|
1855
|
+
} catch (err2) {}
|
|
1856
|
+
throw err;
|
|
1857
|
+
}
|
|
1858
|
+
try {
|
|
1859
|
+
let sent = this.transport.send(msgText);
|
|
1860
|
+
if (sent !== void 0 && typeof sent.catch === "function") sent.catch((err) => this.abort(err, false));
|
|
1861
|
+
} catch (err) {
|
|
1862
|
+
queueMicrotask(() => this.abort(err, false));
|
|
1863
|
+
}
|
|
1864
|
+
return msgText.length;
|
|
1865
|
+
} else try {
|
|
1866
|
+
let size = this.transport.send(msg);
|
|
1867
|
+
if (typeof size === "number") return size;
|
|
1868
|
+
let thenable = size;
|
|
1869
|
+
if (thenable && typeof thenable.then === "function") Promise.resolve(thenable).catch((err) => this.abort(err, false));
|
|
1870
|
+
return;
|
|
1871
|
+
} catch (err) {
|
|
1872
|
+
queueMicrotask(() => this.abort(err, false));
|
|
1873
|
+
return;
|
|
1789
1874
|
}
|
|
1790
|
-
this.transport.send(msgText).catch((err) => this.abort(err, false));
|
|
1791
|
-
return msgText.length;
|
|
1792
1875
|
}
|
|
1793
1876
|
sendCall(id, path, args) {
|
|
1794
1877
|
if (this.abortReason) throw this.abortReason;
|
|
@@ -1798,7 +1881,7 @@ var RpcSessionImpl = class {
|
|
|
1798
1881
|
path
|
|
1799
1882
|
];
|
|
1800
1883
|
if (args) {
|
|
1801
|
-
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
1884
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args, this.encodingLevel);
|
|
1802
1885
|
value.push(devalue[0]);
|
|
1803
1886
|
}
|
|
1804
1887
|
this.send(["push", value]);
|
|
@@ -1813,9 +1896,11 @@ var RpcSessionImpl = class {
|
|
|
1813
1896
|
id,
|
|
1814
1897
|
path
|
|
1815
1898
|
];
|
|
1816
|
-
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
1899
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args, this.encodingLevel);
|
|
1817
1900
|
value.push(devalue[0]);
|
|
1818
|
-
let
|
|
1901
|
+
let msg = ["stream", value];
|
|
1902
|
+
let size = this.send(msg);
|
|
1903
|
+
if (size === void 0) size = estimateEncodedSize(msg);
|
|
1819
1904
|
let importId = this.imports.length;
|
|
1820
1905
|
let entry = new ImportTableEntry(this, importId, true);
|
|
1821
1906
|
entry.remoteRefcount = 0;
|
|
@@ -1871,7 +1956,14 @@ var RpcSessionImpl = class {
|
|
|
1871
1956
|
this.cancelReadLoop?.(error);
|
|
1872
1957
|
this.cancelReadLoop = void 0;
|
|
1873
1958
|
if (trySendAbortMessage) try {
|
|
1874
|
-
|
|
1959
|
+
let abortMsg = ["abort", Devaluator.devaluate(error, void 0, this, void 0, this.encodingLevel)];
|
|
1960
|
+
if (this.encodingLevel === "string") {
|
|
1961
|
+
let sent = this.transport.send(JSON.stringify(abortMsg));
|
|
1962
|
+
if (sent !== void 0 && typeof sent.catch === "function") sent.catch((err) => {});
|
|
1963
|
+
} else {
|
|
1964
|
+
let result = this.transport.send(abortMsg);
|
|
1965
|
+
if (result && typeof result.then === "function") Promise.resolve(result).catch((err) => {});
|
|
1966
|
+
}
|
|
1875
1967
|
} catch (err) {}
|
|
1876
1968
|
if (error === void 0) error = "undefined";
|
|
1877
1969
|
this.abortReason = error;
|
|
@@ -1893,18 +1985,18 @@ var RpcSessionImpl = class {
|
|
|
1893
1985
|
while (!this.abortReason) {
|
|
1894
1986
|
let readCanceled = Promise.withResolvers();
|
|
1895
1987
|
this.cancelReadLoop = readCanceled.reject;
|
|
1896
|
-
let
|
|
1988
|
+
let raw;
|
|
1897
1989
|
try {
|
|
1898
|
-
|
|
1990
|
+
raw = await Promise.race([this.transport.receive(), readCanceled.promise]);
|
|
1899
1991
|
} finally {
|
|
1900
1992
|
if (this.cancelReadLoop === readCanceled.reject) this.cancelReadLoop = void 0;
|
|
1901
1993
|
}
|
|
1902
|
-
let msg = JSON.parse(msgText);
|
|
1903
1994
|
if (this.abortReason) break;
|
|
1995
|
+
let msg = this.encodingLevel === "string" ? JSON.parse(raw) : raw;
|
|
1904
1996
|
if (msg instanceof Array) switch (msg[0]) {
|
|
1905
1997
|
case "push":
|
|
1906
1998
|
if (msg.length > 1) {
|
|
1907
|
-
let hook = new PayloadStubHook(new Evaluator(this).evaluate(msg[1]));
|
|
1999
|
+
let hook = new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[1]));
|
|
1908
2000
|
hook.ignoreUnhandledRejections();
|
|
1909
2001
|
this.exports.push({
|
|
1910
2002
|
hook,
|
|
@@ -1915,7 +2007,7 @@ var RpcSessionImpl = class {
|
|
|
1915
2007
|
break;
|
|
1916
2008
|
case "stream":
|
|
1917
2009
|
if (msg.length > 1) {
|
|
1918
|
-
let hook = new PayloadStubHook(new Evaluator(this).evaluate(msg[1]));
|
|
2010
|
+
let hook = new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[1]));
|
|
1919
2011
|
hook.ignoreUnhandledRejections();
|
|
1920
2012
|
let exportId = this.exports.length;
|
|
1921
2013
|
this.exports.push({
|
|
@@ -1950,13 +2042,13 @@ var RpcSessionImpl = class {
|
|
|
1950
2042
|
let importId = msg[1];
|
|
1951
2043
|
if (typeof importId == "number" && msg.length > 2) {
|
|
1952
2044
|
let imp = this.imports[importId];
|
|
1953
|
-
if (imp) if (msg[0] == "resolve") imp.resolve(new PayloadStubHook(new Evaluator(this).evaluate(msg[2])));
|
|
2045
|
+
if (imp) if (msg[0] == "resolve") imp.resolve(new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[2])));
|
|
1954
2046
|
else {
|
|
1955
|
-
let payload = new Evaluator(this).evaluate(msg[2]);
|
|
2047
|
+
let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[2]);
|
|
1956
2048
|
payload.dispose();
|
|
1957
2049
|
imp.resolve(new ErrorStubHook(payload.value));
|
|
1958
2050
|
}
|
|
1959
|
-
else if (msg[0] == "resolve") new Evaluator(this).evaluate(msg[2]).dispose();
|
|
2051
|
+
else if (msg[0] == "resolve") new Evaluator(this, this.encodingLevel).evaluate(msg[2]).dispose();
|
|
1960
2052
|
continue;
|
|
1961
2053
|
}
|
|
1962
2054
|
break;
|
|
@@ -1971,7 +2063,7 @@ var RpcSessionImpl = class {
|
|
|
1971
2063
|
break;
|
|
1972
2064
|
}
|
|
1973
2065
|
case "abort": {
|
|
1974
|
-
let payload = new Evaluator(this).evaluate(msg[1]);
|
|
2066
|
+
let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[1]);
|
|
1975
2067
|
payload.dispose();
|
|
1976
2068
|
this.abort(payload, false);
|
|
1977
2069
|
break;
|
|
@@ -2043,9 +2135,14 @@ function newWorkersWebSocketRpcResponse(request, localMain, options) {
|
|
|
2043
2135
|
webSocket: pair[1]
|
|
2044
2136
|
});
|
|
2045
2137
|
}
|
|
2138
|
+
/**
|
|
2139
|
+
* Generic WebSocket transport. Default `T = string` is backward-compatible and satisfies
|
|
2140
|
+
* `RpcTransport`. Use `T = ArrayBuffer` as a building block for binary transports.
|
|
2141
|
+
*/
|
|
2046
2142
|
var WebSocketTransport = class {
|
|
2047
2143
|
constructor(webSocket) {
|
|
2048
2144
|
this.#webSocket = webSocket;
|
|
2145
|
+
webSocket.binaryType = "arraybuffer";
|
|
2049
2146
|
if (webSocket.readyState === WebSocket.CONNECTING) {
|
|
2050
2147
|
this.#sendQueue = [];
|
|
2051
2148
|
webSocket.addEventListener("open", (event) => {
|
|
@@ -2058,12 +2155,12 @@ var WebSocketTransport = class {
|
|
|
2058
2155
|
});
|
|
2059
2156
|
}
|
|
2060
2157
|
webSocket.addEventListener("message", (event) => {
|
|
2061
|
-
if (this.#error) {} else if (typeof event.data === "string") if (this.#receiveResolver) {
|
|
2158
|
+
if (this.#error) {} else if (typeof event.data === "string" || event.data instanceof ArrayBuffer) if (this.#receiveResolver) {
|
|
2062
2159
|
this.#receiveResolver(event.data);
|
|
2063
2160
|
this.#receiveResolver = void 0;
|
|
2064
2161
|
this.#receiveRejecter = void 0;
|
|
2065
2162
|
} else this.#receiveQueue.push(event.data);
|
|
2066
|
-
else this.#receivedError(/* @__PURE__ */ new TypeError("Received
|
|
2163
|
+
else this.#receivedError(/* @__PURE__ */ new TypeError("Received unexpected message type from WebSocket."));
|
|
2067
2164
|
});
|
|
2068
2165
|
webSocket.addEventListener("close", (event) => {
|
|
2069
2166
|
this.#receivedError(/* @__PURE__ */ new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`));
|
|
@@ -2078,13 +2175,13 @@ var WebSocketTransport = class {
|
|
|
2078
2175
|
#receiveRejecter;
|
|
2079
2176
|
#receiveQueue = [];
|
|
2080
2177
|
#error;
|
|
2081
|
-
|
|
2178
|
+
send(message) {
|
|
2082
2179
|
if (this.#sendQueue === void 0) this.#webSocket.send(message);
|
|
2083
2180
|
else this.#sendQueue.push(message);
|
|
2084
2181
|
}
|
|
2085
|
-
|
|
2086
|
-
if (this.#receiveQueue.length > 0) return this.#receiveQueue.shift();
|
|
2087
|
-
else if (this.#error)
|
|
2182
|
+
receive() {
|
|
2183
|
+
if (this.#receiveQueue.length > 0) return Promise.resolve(this.#receiveQueue.shift());
|
|
2184
|
+
else if (this.#error) return Promise.reject(this.#error);
|
|
2088
2185
|
else return new Promise((resolve, reject) => {
|
|
2089
2186
|
this.#receiveResolver = resolve;
|
|
2090
2187
|
this.#receiveRejecter = reject;
|
|
@@ -2119,7 +2216,7 @@ var BatchClientTransport = class {
|
|
|
2119
2216
|
#aborted;
|
|
2120
2217
|
#batchToSend = [];
|
|
2121
2218
|
#batchToReceive = null;
|
|
2122
|
-
|
|
2219
|
+
send(message) {
|
|
2123
2220
|
if (this.#batchToSend !== null) this.#batchToSend.push(message);
|
|
2124
2221
|
}
|
|
2125
2222
|
async receive() {
|
|
@@ -2161,7 +2258,7 @@ var BatchServerTransport = class {
|
|
|
2161
2258
|
#batchToSend = [];
|
|
2162
2259
|
#batchToReceive;
|
|
2163
2260
|
#allReceived = Promise.withResolvers();
|
|
2164
|
-
|
|
2261
|
+
send(message) {
|
|
2165
2262
|
this.#batchToSend.push(message);
|
|
2166
2263
|
}
|
|
2167
2264
|
async receive() {
|
|
@@ -2235,17 +2332,17 @@ function newMessagePortRpcSession$1(port, localMain, options) {
|
|
|
2235
2332
|
return new RpcSession$1(new MessagePortTransport(port), localMain, options).getRemoteMain();
|
|
2236
2333
|
}
|
|
2237
2334
|
var MessagePortTransport = class {
|
|
2335
|
+
encodingLevel = "structuredClonable";
|
|
2238
2336
|
constructor(port) {
|
|
2239
2337
|
this.#port = port;
|
|
2240
2338
|
port.start();
|
|
2241
2339
|
port.addEventListener("message", (event) => {
|
|
2242
2340
|
if (this.#error) {} else if (event.data === null) this.#receivedError(/* @__PURE__ */ new Error("Peer closed MessagePort connection."));
|
|
2243
|
-
else if (
|
|
2341
|
+
else if (this.#receiveResolver) {
|
|
2244
2342
|
this.#receiveResolver(event.data);
|
|
2245
2343
|
this.#receiveResolver = void 0;
|
|
2246
2344
|
this.#receiveRejecter = void 0;
|
|
2247
2345
|
} else this.#receiveQueue.push(event.data);
|
|
2248
|
-
else this.#receivedError(/* @__PURE__ */ new TypeError("Received non-string message from MessagePort."));
|
|
2249
2346
|
});
|
|
2250
2347
|
port.addEventListener("messageerror", (event) => {
|
|
2251
2348
|
this.#receivedError(/* @__PURE__ */ new Error("MessagePort message error."));
|
|
@@ -2256,7 +2353,7 @@ var MessagePortTransport = class {
|
|
|
2256
2353
|
#receiveRejecter;
|
|
2257
2354
|
#receiveQueue = [];
|
|
2258
2355
|
#error;
|
|
2259
|
-
|
|
2356
|
+
send(message) {
|
|
2260
2357
|
if (this.#error) throw this.#error;
|
|
2261
2358
|
this.#port.postMessage(message);
|
|
2262
2359
|
}
|
|
@@ -2944,6 +3041,7 @@ exports.RpcPromise = RpcPromise;
|
|
|
2944
3041
|
exports.RpcSession = RpcSession;
|
|
2945
3042
|
exports.RpcStub = RpcStub;
|
|
2946
3043
|
exports.RpcTarget = RpcTarget;
|
|
3044
|
+
exports.WebSocketTransport = WebSocketTransport;
|
|
2947
3045
|
exports.deserialize = deserialize;
|
|
2948
3046
|
exports.newBunWebSocketRpcHandler = newBunWebSocketRpcHandler;
|
|
2949
3047
|
exports.newBunWebSocketRpcSession = newBunWebSocketRpcSession;
|