capnweb 0.0.0-5eb7701 → 0.0.0-610ab3a
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 +172 -52
- package/dist/index-bun.cjs.map +1 -1
- package/dist/index-bun.d.cts +106 -58
- package/dist/index-bun.d.ts +106 -58
- package/dist/index-bun.js +171 -53
- package/dist/index-bun.js.map +1 -1
- package/dist/index-workers.cjs +184 -60
- package/dist/index-workers.cjs.map +1 -1
- package/dist/index-workers.d.cts +106 -58
- package/dist/index-workers.d.ts +106 -58
- package/dist/index-workers.js +171 -53
- package/dist/index-workers.js.map +1 -1
- package/dist/index.cjs +172 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -58
- package/dist/index.d.ts +106 -58
- package/dist/index.js +171 -53
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
1
2
|
|
|
2
3
|
//#region src/symbols.ts
|
|
3
4
|
let WORKERS_MODULE_SYMBOL = Symbol("workers-module");
|
|
@@ -91,6 +92,7 @@ var StubHook = class {
|
|
|
91
92
|
}
|
|
92
93
|
};
|
|
93
94
|
var ErrorStubHook = class extends StubHook {
|
|
95
|
+
error;
|
|
94
96
|
constructor(error) {
|
|
95
97
|
super();
|
|
96
98
|
this.error = error;
|
|
@@ -264,6 +266,10 @@ async function pullPromise(promise) {
|
|
|
264
266
|
return (await hook.pull()).deliverResolve();
|
|
265
267
|
}
|
|
266
268
|
var RpcPayload = class RpcPayload {
|
|
269
|
+
value;
|
|
270
|
+
source;
|
|
271
|
+
hooks;
|
|
272
|
+
promises;
|
|
267
273
|
static fromAppParams(value) {
|
|
268
274
|
return new RpcPayload(value, "params");
|
|
269
275
|
}
|
|
@@ -955,18 +961,22 @@ const ERROR_TYPES = {
|
|
|
955
961
|
AggregateError
|
|
956
962
|
};
|
|
957
963
|
var Devaluator = class Devaluator {
|
|
958
|
-
|
|
964
|
+
exporter;
|
|
965
|
+
source;
|
|
966
|
+
encodingLevel;
|
|
967
|
+
constructor(exporter, source, encodingLevel) {
|
|
959
968
|
this.exporter = exporter;
|
|
960
969
|
this.source = source;
|
|
970
|
+
this.encodingLevel = encodingLevel;
|
|
961
971
|
}
|
|
962
|
-
static devaluate(value, parent, exporter = NULL_EXPORTER, source) {
|
|
963
|
-
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);
|
|
964
974
|
try {
|
|
965
975
|
return devaluator.devaluateImpl(value, parent, 0);
|
|
966
976
|
} catch (err) {
|
|
967
977
|
if (devaluator.exports) try {
|
|
968
978
|
exporter.unexport(devaluator.exports);
|
|
969
|
-
} catch (err
|
|
979
|
+
} catch (err) {}
|
|
970
980
|
throw err;
|
|
971
981
|
}
|
|
972
982
|
}
|
|
@@ -983,10 +993,12 @@ var Devaluator = class Devaluator {
|
|
|
983
993
|
}
|
|
984
994
|
throw new TypeError(msg);
|
|
985
995
|
}
|
|
986
|
-
case "primitive": if (typeof value === "number" && !isFinite(value))
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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;
|
|
990
1002
|
case "object": {
|
|
991
1003
|
let object = value;
|
|
992
1004
|
let result = {};
|
|
@@ -1000,13 +1012,17 @@ var Devaluator = class Devaluator {
|
|
|
1000
1012
|
for (let i = 0; i < len; i++) result[i] = this.devaluateImpl(array[i], array, depth + 1);
|
|
1001
1013
|
return [result];
|
|
1002
1014
|
}
|
|
1003
|
-
case "bigint":
|
|
1015
|
+
case "bigint":
|
|
1016
|
+
if (this.encodingLevel === "structuredClonable") return value;
|
|
1017
|
+
return ["bigint", value.toString()];
|
|
1004
1018
|
case "date": {
|
|
1019
|
+
if (this.encodingLevel === "structuredClonable") return value;
|
|
1005
1020
|
const time = value.getTime();
|
|
1006
1021
|
return ["date", Number.isNaN(time) ? null : time];
|
|
1007
1022
|
}
|
|
1008
1023
|
case "bytes": {
|
|
1009
1024
|
let bytes = value;
|
|
1025
|
+
if (this.encodingLevel === "structuredClonable" || this.encodingLevel === "jsonCompatibleWithBytes") return ["bytes", bytes];
|
|
1010
1026
|
if (bytes.toBase64) return ["bytes", bytes.toBase64({ omitPadding: true })];
|
|
1011
1027
|
let b64;
|
|
1012
1028
|
if (typeof Buffer !== "undefined") b64 = (bytes instanceof Buffer ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)).toString("base64");
|
|
@@ -1131,7 +1147,9 @@ var Devaluator = class Devaluator {
|
|
|
1131
1147
|
} else if (rewritten && rewritten.stack) result.push(rewritten.stack);
|
|
1132
1148
|
return result;
|
|
1133
1149
|
}
|
|
1134
|
-
case "undefined":
|
|
1150
|
+
case "undefined":
|
|
1151
|
+
if (this.encodingLevel === "structuredClonable") return;
|
|
1152
|
+
return ["undefined"];
|
|
1135
1153
|
case "stub":
|
|
1136
1154
|
case "rpc-promise": {
|
|
1137
1155
|
if (!this.source) throw new Error("Can't serialize RPC stubs in this context.");
|
|
@@ -1213,8 +1231,11 @@ function streamToBlobPromise(stream, type) {
|
|
|
1213
1231
|
})), []);
|
|
1214
1232
|
}
|
|
1215
1233
|
var Evaluator = class Evaluator {
|
|
1216
|
-
|
|
1234
|
+
importer;
|
|
1235
|
+
encodingLevel;
|
|
1236
|
+
constructor(importer, encodingLevel = "string") {
|
|
1217
1237
|
this.importer = importer;
|
|
1238
|
+
this.encodingLevel = encodingLevel;
|
|
1218
1239
|
}
|
|
1219
1240
|
hooks = [];
|
|
1220
1241
|
promises = [];
|
|
@@ -1232,6 +1253,9 @@ var Evaluator = class Evaluator {
|
|
|
1232
1253
|
return this.evaluate(structuredClone(value));
|
|
1233
1254
|
}
|
|
1234
1255
|
evaluateImpl(value, parent, property) {
|
|
1256
|
+
if (this.encodingLevel === "structuredClonable") {
|
|
1257
|
+
if (value instanceof Date || typeof value === "bigint") return value;
|
|
1258
|
+
}
|
|
1235
1259
|
if (value instanceof Array) {
|
|
1236
1260
|
if (value.length == 1 && value[0] instanceof Array) {
|
|
1237
1261
|
let result = value[0];
|
|
@@ -1246,6 +1270,7 @@ var Evaluator = class Evaluator {
|
|
|
1246
1270
|
if (typeof value[1] == "number") return new Date(value[1]);
|
|
1247
1271
|
break;
|
|
1248
1272
|
case "bytes":
|
|
1273
|
+
if (value[1] instanceof Uint8Array) return value[1];
|
|
1249
1274
|
if (typeof value[1] == "string") if (typeof Buffer !== "undefined") return Buffer.from(value[1], "base64");
|
|
1250
1275
|
else if (Uint8Array.fromBase64) return Uint8Array.fromBase64(value[1]);
|
|
1251
1276
|
else {
|
|
@@ -1338,9 +1363,9 @@ var Evaluator = class Evaluator {
|
|
|
1338
1363
|
let hook = this.importer.getExport(value[1]);
|
|
1339
1364
|
if (!hook) throw new Error(`no such entry on exports table: ${value[1]}`);
|
|
1340
1365
|
let isPromise = value[0] == "pipeline";
|
|
1341
|
-
let addStub = (hook
|
|
1366
|
+
let addStub = (hook) => {
|
|
1342
1367
|
if (isPromise) {
|
|
1343
|
-
let promise = new RpcPromise$1(hook
|
|
1368
|
+
let promise = new RpcPromise$1(hook, []);
|
|
1344
1369
|
this.promises.push({
|
|
1345
1370
|
promise,
|
|
1346
1371
|
parent,
|
|
@@ -1348,8 +1373,8 @@ var Evaluator = class Evaluator {
|
|
|
1348
1373
|
});
|
|
1349
1374
|
return promise;
|
|
1350
1375
|
} else {
|
|
1351
|
-
this.hooks.push(hook
|
|
1352
|
-
return new RpcPromise$1(hook
|
|
1376
|
+
this.hooks.push(hook);
|
|
1377
|
+
return new RpcPromise$1(hook, []);
|
|
1353
1378
|
}
|
|
1354
1379
|
};
|
|
1355
1380
|
if (value.length == 2) if (isPromise) return addStub(hook.get([]));
|
|
@@ -1446,7 +1471,50 @@ function deserialize(value) {
|
|
|
1446
1471
|
|
|
1447
1472
|
//#endregion
|
|
1448
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
|
+
}
|
|
1449
1515
|
var ImportTableEntry = class {
|
|
1516
|
+
session;
|
|
1517
|
+
importId;
|
|
1450
1518
|
constructor(session, importId, pulling) {
|
|
1451
1519
|
this.session = session;
|
|
1452
1520
|
this.importId = importId;
|
|
@@ -1521,6 +1589,7 @@ var ImportTableEntry = class {
|
|
|
1521
1589
|
}
|
|
1522
1590
|
};
|
|
1523
1591
|
var RpcImportHook = class RpcImportHook extends StubHook {
|
|
1592
|
+
isPromise;
|
|
1524
1593
|
entry;
|
|
1525
1594
|
constructor(isPromise, entry) {
|
|
1526
1595
|
super();
|
|
@@ -1597,6 +1666,8 @@ var RpcMainHook = class extends RpcImportHook {
|
|
|
1597
1666
|
}
|
|
1598
1667
|
};
|
|
1599
1668
|
var RpcSessionImpl = class {
|
|
1669
|
+
transport;
|
|
1670
|
+
options;
|
|
1600
1671
|
exports = [];
|
|
1601
1672
|
reverseExports = /* @__PURE__ */ new Map();
|
|
1602
1673
|
imports = [];
|
|
@@ -1606,9 +1677,19 @@ var RpcSessionImpl = class {
|
|
|
1606
1677
|
onBatchDone;
|
|
1607
1678
|
pullCount = 0;
|
|
1608
1679
|
onBrokenCallbacks = [];
|
|
1680
|
+
encodingLevel;
|
|
1609
1681
|
constructor(transport, mainHook, options) {
|
|
1610
1682
|
this.transport = transport;
|
|
1611
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;
|
|
1612
1693
|
this.exports.push({
|
|
1613
1694
|
hook: mainHook,
|
|
1614
1695
|
refcount: 1
|
|
@@ -1689,7 +1770,7 @@ var RpcSessionImpl = class {
|
|
|
1689
1770
|
let autoRelease = exp.autoRelease;
|
|
1690
1771
|
++this.pullCount;
|
|
1691
1772
|
exp.pull = resolve().then((payload) => {
|
|
1692
|
-
let value = Devaluator.devaluate(payload.value, void 0, this, payload);
|
|
1773
|
+
let value = Devaluator.devaluate(payload.value, void 0, this, payload, this.encodingLevel);
|
|
1693
1774
|
this.send([
|
|
1694
1775
|
"resolve",
|
|
1695
1776
|
exportId,
|
|
@@ -1700,7 +1781,7 @@ var RpcSessionImpl = class {
|
|
|
1700
1781
|
this.send([
|
|
1701
1782
|
"reject",
|
|
1702
1783
|
exportId,
|
|
1703
|
-
Devaluator.devaluate(error, void 0, this)
|
|
1784
|
+
Devaluator.devaluate(error, void 0, this, void 0, this.encodingLevel)
|
|
1704
1785
|
]);
|
|
1705
1786
|
if (autoRelease) this.releaseExport(exportId, 1);
|
|
1706
1787
|
}).catch((error) => {
|
|
@@ -1708,7 +1789,7 @@ var RpcSessionImpl = class {
|
|
|
1708
1789
|
this.send([
|
|
1709
1790
|
"reject",
|
|
1710
1791
|
exportId,
|
|
1711
|
-
Devaluator.devaluate(error, void 0, this)
|
|
1792
|
+
Devaluator.devaluate(error, void 0, this, void 0, this.encodingLevel)
|
|
1712
1793
|
]);
|
|
1713
1794
|
if (autoRelease) this.releaseExport(exportId, 1);
|
|
1714
1795
|
} catch (error2) {
|
|
@@ -1764,17 +1845,33 @@ var RpcSessionImpl = class {
|
|
|
1764
1845
|
}
|
|
1765
1846
|
send(msg) {
|
|
1766
1847
|
if (this.abortReason !== void 0) return 0;
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
msgText = JSON.stringify(msg);
|
|
1770
|
-
} catch (err) {
|
|
1848
|
+
if (this.encodingLevel === "string") {
|
|
1849
|
+
let msgText;
|
|
1771
1850
|
try {
|
|
1772
|
-
|
|
1773
|
-
} catch (
|
|
1774
|
-
|
|
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;
|
|
1775
1874
|
}
|
|
1776
|
-
this.transport.send(msgText).catch((err) => this.abort(err, false));
|
|
1777
|
-
return msgText.length;
|
|
1778
1875
|
}
|
|
1779
1876
|
sendCall(id, path, args) {
|
|
1780
1877
|
if (this.abortReason) throw this.abortReason;
|
|
@@ -1784,7 +1881,7 @@ var RpcSessionImpl = class {
|
|
|
1784
1881
|
path
|
|
1785
1882
|
];
|
|
1786
1883
|
if (args) {
|
|
1787
|
-
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
1884
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args, this.encodingLevel);
|
|
1788
1885
|
value.push(devalue[0]);
|
|
1789
1886
|
}
|
|
1790
1887
|
this.send(["push", value]);
|
|
@@ -1799,9 +1896,11 @@ var RpcSessionImpl = class {
|
|
|
1799
1896
|
id,
|
|
1800
1897
|
path
|
|
1801
1898
|
];
|
|
1802
|
-
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
1899
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args, this.encodingLevel);
|
|
1803
1900
|
value.push(devalue[0]);
|
|
1804
|
-
let
|
|
1901
|
+
let msg = ["stream", value];
|
|
1902
|
+
let size = this.send(msg);
|
|
1903
|
+
if (size === void 0) size = estimateEncodedSize(msg);
|
|
1805
1904
|
let importId = this.imports.length;
|
|
1806
1905
|
let entry = new ImportTableEntry(this, importId, true);
|
|
1807
1906
|
entry.remoteRefcount = 0;
|
|
@@ -1857,7 +1956,14 @@ var RpcSessionImpl = class {
|
|
|
1857
1956
|
this.cancelReadLoop?.(error);
|
|
1858
1957
|
this.cancelReadLoop = void 0;
|
|
1859
1958
|
if (trySendAbortMessage) try {
|
|
1860
|
-
|
|
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
|
+
}
|
|
1861
1967
|
} catch (err) {}
|
|
1862
1968
|
if (error === void 0) error = "undefined";
|
|
1863
1969
|
this.abortReason = error;
|
|
@@ -1879,18 +1985,18 @@ var RpcSessionImpl = class {
|
|
|
1879
1985
|
while (!this.abortReason) {
|
|
1880
1986
|
let readCanceled = Promise.withResolvers();
|
|
1881
1987
|
this.cancelReadLoop = readCanceled.reject;
|
|
1882
|
-
let
|
|
1988
|
+
let raw;
|
|
1883
1989
|
try {
|
|
1884
|
-
|
|
1990
|
+
raw = await Promise.race([this.transport.receive(), readCanceled.promise]);
|
|
1885
1991
|
} finally {
|
|
1886
1992
|
if (this.cancelReadLoop === readCanceled.reject) this.cancelReadLoop = void 0;
|
|
1887
1993
|
}
|
|
1888
|
-
let msg = JSON.parse(msgText);
|
|
1889
1994
|
if (this.abortReason) break;
|
|
1995
|
+
let msg = this.encodingLevel === "string" ? JSON.parse(raw) : raw;
|
|
1890
1996
|
if (msg instanceof Array) switch (msg[0]) {
|
|
1891
1997
|
case "push":
|
|
1892
1998
|
if (msg.length > 1) {
|
|
1893
|
-
let hook = new PayloadStubHook(new Evaluator(this).evaluate(msg[1]));
|
|
1999
|
+
let hook = new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[1]));
|
|
1894
2000
|
hook.ignoreUnhandledRejections();
|
|
1895
2001
|
this.exports.push({
|
|
1896
2002
|
hook,
|
|
@@ -1901,7 +2007,7 @@ var RpcSessionImpl = class {
|
|
|
1901
2007
|
break;
|
|
1902
2008
|
case "stream":
|
|
1903
2009
|
if (msg.length > 1) {
|
|
1904
|
-
let hook = new PayloadStubHook(new Evaluator(this).evaluate(msg[1]));
|
|
2010
|
+
let hook = new PayloadStubHook(new Evaluator(this, this.encodingLevel).evaluate(msg[1]));
|
|
1905
2011
|
hook.ignoreUnhandledRejections();
|
|
1906
2012
|
let exportId = this.exports.length;
|
|
1907
2013
|
this.exports.push({
|
|
@@ -1936,13 +2042,13 @@ var RpcSessionImpl = class {
|
|
|
1936
2042
|
let importId = msg[1];
|
|
1937
2043
|
if (typeof importId == "number" && msg.length > 2) {
|
|
1938
2044
|
let imp = this.imports[importId];
|
|
1939
|
-
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])));
|
|
1940
2046
|
else {
|
|
1941
|
-
let payload = new Evaluator(this).evaluate(msg[2]);
|
|
2047
|
+
let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[2]);
|
|
1942
2048
|
payload.dispose();
|
|
1943
2049
|
imp.resolve(new ErrorStubHook(payload.value));
|
|
1944
2050
|
}
|
|
1945
|
-
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();
|
|
1946
2052
|
continue;
|
|
1947
2053
|
}
|
|
1948
2054
|
break;
|
|
@@ -1957,7 +2063,7 @@ var RpcSessionImpl = class {
|
|
|
1957
2063
|
break;
|
|
1958
2064
|
}
|
|
1959
2065
|
case "abort": {
|
|
1960
|
-
let payload = new Evaluator(this).evaluate(msg[1]);
|
|
2066
|
+
let payload = new Evaluator(this, this.encodingLevel).evaluate(msg[1]);
|
|
1961
2067
|
payload.dispose();
|
|
1962
2068
|
this.abort(payload, false);
|
|
1963
2069
|
break;
|
|
@@ -2029,9 +2135,14 @@ function newWorkersWebSocketRpcResponse(request, localMain, options) {
|
|
|
2029
2135
|
webSocket: pair[1]
|
|
2030
2136
|
});
|
|
2031
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
|
+
*/
|
|
2032
2142
|
var WebSocketTransport = class {
|
|
2033
2143
|
constructor(webSocket) {
|
|
2034
2144
|
this.#webSocket = webSocket;
|
|
2145
|
+
webSocket.binaryType = "arraybuffer";
|
|
2035
2146
|
if (webSocket.readyState === WebSocket.CONNECTING) {
|
|
2036
2147
|
this.#sendQueue = [];
|
|
2037
2148
|
webSocket.addEventListener("open", (event) => {
|
|
@@ -2044,12 +2155,12 @@ var WebSocketTransport = class {
|
|
|
2044
2155
|
});
|
|
2045
2156
|
}
|
|
2046
2157
|
webSocket.addEventListener("message", (event) => {
|
|
2047
|
-
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) {
|
|
2048
2159
|
this.#receiveResolver(event.data);
|
|
2049
2160
|
this.#receiveResolver = void 0;
|
|
2050
2161
|
this.#receiveRejecter = void 0;
|
|
2051
2162
|
} else this.#receiveQueue.push(event.data);
|
|
2052
|
-
else this.#receivedError(/* @__PURE__ */ new TypeError("Received
|
|
2163
|
+
else this.#receivedError(/* @__PURE__ */ new TypeError("Received unexpected message type from WebSocket."));
|
|
2053
2164
|
});
|
|
2054
2165
|
webSocket.addEventListener("close", (event) => {
|
|
2055
2166
|
this.#receivedError(/* @__PURE__ */ new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`));
|
|
@@ -2064,13 +2175,13 @@ var WebSocketTransport = class {
|
|
|
2064
2175
|
#receiveRejecter;
|
|
2065
2176
|
#receiveQueue = [];
|
|
2066
2177
|
#error;
|
|
2067
|
-
|
|
2178
|
+
send(message) {
|
|
2068
2179
|
if (this.#sendQueue === void 0) this.#webSocket.send(message);
|
|
2069
2180
|
else this.#sendQueue.push(message);
|
|
2070
2181
|
}
|
|
2071
|
-
|
|
2072
|
-
if (this.#receiveQueue.length > 0) return this.#receiveQueue.shift();
|
|
2073
|
-
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);
|
|
2074
2185
|
else return new Promise((resolve, reject) => {
|
|
2075
2186
|
this.#receiveResolver = resolve;
|
|
2076
2187
|
this.#receiveRejecter = reject;
|
|
@@ -2105,7 +2216,7 @@ var BatchClientTransport = class {
|
|
|
2105
2216
|
#aborted;
|
|
2106
2217
|
#batchToSend = [];
|
|
2107
2218
|
#batchToReceive = null;
|
|
2108
|
-
|
|
2219
|
+
send(message) {
|
|
2109
2220
|
if (this.#batchToSend !== null) this.#batchToSend.push(message);
|
|
2110
2221
|
}
|
|
2111
2222
|
async receive() {
|
|
@@ -2147,7 +2258,7 @@ var BatchServerTransport = class {
|
|
|
2147
2258
|
#batchToSend = [];
|
|
2148
2259
|
#batchToReceive;
|
|
2149
2260
|
#allReceived = Promise.withResolvers();
|
|
2150
|
-
|
|
2261
|
+
send(message) {
|
|
2151
2262
|
this.#batchToSend.push(message);
|
|
2152
2263
|
}
|
|
2153
2264
|
async receive() {
|
|
@@ -2196,7 +2307,11 @@ async function newHttpBatchRpcResponse(request, localMain, options) {
|
|
|
2196
2307
|
* @param options Optional RPC session options. You can also pass headers to set on the response.
|
|
2197
2308
|
*/
|
|
2198
2309
|
async function nodeHttpBatchRpcResponse(request, response, localMain, options) {
|
|
2199
|
-
if (request.method !== "POST")
|
|
2310
|
+
if (request.method !== "POST") {
|
|
2311
|
+
response.writeHead(405, "This endpoint only accepts POST requests.", options?.headers);
|
|
2312
|
+
response.end();
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2200
2315
|
let body = await new Promise((resolve, reject) => {
|
|
2201
2316
|
let chunks = [];
|
|
2202
2317
|
request.on("data", (chunk) => {
|
|
@@ -2221,17 +2336,17 @@ function newMessagePortRpcSession$1(port, localMain, options) {
|
|
|
2221
2336
|
return new RpcSession$1(new MessagePortTransport(port), localMain, options).getRemoteMain();
|
|
2222
2337
|
}
|
|
2223
2338
|
var MessagePortTransport = class {
|
|
2339
|
+
encodingLevel = "structuredClonable";
|
|
2224
2340
|
constructor(port) {
|
|
2225
2341
|
this.#port = port;
|
|
2226
2342
|
port.start();
|
|
2227
2343
|
port.addEventListener("message", (event) => {
|
|
2228
2344
|
if (this.#error) {} else if (event.data === null) this.#receivedError(/* @__PURE__ */ new Error("Peer closed MessagePort connection."));
|
|
2229
|
-
else if (
|
|
2345
|
+
else if (this.#receiveResolver) {
|
|
2230
2346
|
this.#receiveResolver(event.data);
|
|
2231
2347
|
this.#receiveResolver = void 0;
|
|
2232
2348
|
this.#receiveRejecter = void 0;
|
|
2233
2349
|
} else this.#receiveQueue.push(event.data);
|
|
2234
|
-
else this.#receivedError(/* @__PURE__ */ new TypeError("Received non-string message from MessagePort."));
|
|
2235
2350
|
});
|
|
2236
2351
|
port.addEventListener("messageerror", (event) => {
|
|
2237
2352
|
this.#receivedError(/* @__PURE__ */ new Error("MessagePort message error."));
|
|
@@ -2242,7 +2357,7 @@ var MessagePortTransport = class {
|
|
|
2242
2357
|
#receiveRejecter;
|
|
2243
2358
|
#receiveQueue = [];
|
|
2244
2359
|
#error;
|
|
2245
|
-
|
|
2360
|
+
send(message) {
|
|
2246
2361
|
if (this.#error) throw this.#error;
|
|
2247
2362
|
this.#port.postMessage(message);
|
|
2248
2363
|
}
|
|
@@ -2389,6 +2504,8 @@ function throwMapperBuilderUseError() {
|
|
|
2389
2504
|
throw new Error("Attempted to use an abstract placeholder from a mapper function. Please make sure your map function has no side effects.");
|
|
2390
2505
|
}
|
|
2391
2506
|
var MapVariableHook = class extends StubHook {
|
|
2507
|
+
mapper;
|
|
2508
|
+
idx;
|
|
2392
2509
|
constructor(mapper, idx) {
|
|
2393
2510
|
super();
|
|
2394
2511
|
this.mapper = mapper;
|
|
@@ -2418,6 +2535,7 @@ var MapVariableHook = class extends StubHook {
|
|
|
2418
2535
|
}
|
|
2419
2536
|
};
|
|
2420
2537
|
var MapApplicator = class {
|
|
2538
|
+
captures;
|
|
2421
2539
|
variables;
|
|
2422
2540
|
constructor(captures, input) {
|
|
2423
2541
|
this.captures = captures;
|
|
@@ -2558,6 +2676,7 @@ const STEADY_GROWTH_FACTOR = 1.25;
|
|
|
2558
2676
|
const DECAY_FACTOR = .9;
|
|
2559
2677
|
const STARTUP_EXIT_ROUNDS = 3;
|
|
2560
2678
|
var FlowController = class {
|
|
2679
|
+
now;
|
|
2561
2680
|
window = INITIAL_WINDOW;
|
|
2562
2681
|
bytesInFlight = 0;
|
|
2563
2682
|
inStartupPhase = true;
|
|
@@ -2926,6 +3045,7 @@ exports.RpcPromise = RpcPromise;
|
|
|
2926
3045
|
exports.RpcSession = RpcSession;
|
|
2927
3046
|
exports.RpcStub = RpcStub;
|
|
2928
3047
|
exports.RpcTarget = RpcTarget;
|
|
3048
|
+
exports.WebSocketTransport = WebSocketTransport;
|
|
2929
3049
|
exports.deserialize = deserialize;
|
|
2930
3050
|
exports.newBunWebSocketRpcHandler = newBunWebSocketRpcHandler;
|
|
2931
3051
|
exports.newBunWebSocketRpcSession = newBunWebSocketRpcSession;
|