capnweb 0.0.0-d21e4ca → 0.0.0-e0d2f1d

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.
@@ -1,15 +1,15 @@
1
1
  import * as cfw from 'cloudflare:workers';
2
2
 
3
3
  // src/symbols.ts
4
- var WORKERS_MODULE_SYMBOL = Symbol("workers-module");
4
+ var WORKERS_MODULE_SYMBOL = /* @__PURE__ */ Symbol("workers-module");
5
5
  globalThis[WORKERS_MODULE_SYMBOL] = cfw;
6
6
 
7
7
  // src/core.ts
8
8
  if (!Symbol.dispose) {
9
- Symbol.dispose = Symbol.for("dispose");
9
+ Symbol.dispose = /* @__PURE__ */ Symbol.for("dispose");
10
10
  }
11
11
  if (!Symbol.asyncDispose) {
12
- Symbol.asyncDispose = Symbol.for("asyncDispose");
12
+ Symbol.asyncDispose = /* @__PURE__ */ Symbol.for("asyncDispose");
13
13
  }
14
14
  if (!Promise.withResolvers) {
15
15
  Promise.withResolvers = function() {
@@ -25,6 +25,8 @@ if (!Promise.withResolvers) {
25
25
  var workersModule = globalThis[WORKERS_MODULE_SYMBOL];
26
26
  var RpcTarget = workersModule ? workersModule.RpcTarget : class {
27
27
  };
28
+ var AsyncFunction = (async function() {
29
+ }).constructor;
28
30
  function typeForRpc(value) {
29
31
  switch (typeof value) {
30
32
  case "boolean":
@@ -49,6 +51,7 @@ function typeForRpc(value) {
49
51
  case Object.prototype:
50
52
  return "object";
51
53
  case Function.prototype:
54
+ case AsyncFunction.prototype:
52
55
  return "function";
53
56
  case Array.prototype:
54
57
  return "array";
@@ -56,6 +59,16 @@ function typeForRpc(value) {
56
59
  return "date";
57
60
  case Uint8Array.prototype:
58
61
  return "bytes";
62
+ case WritableStream.prototype:
63
+ return "writable";
64
+ case ReadableStream.prototype:
65
+ return "readable";
66
+ case Headers.prototype:
67
+ return "headers";
68
+ case Request.prototype:
69
+ return "request";
70
+ case Response.prototype:
71
+ return "response";
59
72
  // TODO: All other structured clone types.
60
73
  case RpcStub.prototype:
61
74
  return "stub";
@@ -83,7 +96,34 @@ function mapNotLoaded() {
83
96
  throw new Error("RPC map() implementation was not loaded.");
84
97
  }
85
98
  var mapImpl = { applyMap: mapNotLoaded, sendMap: mapNotLoaded };
99
+ function streamNotLoaded() {
100
+ throw new Error("Stream implementation was not loaded.");
101
+ }
102
+ var streamImpl = {
103
+ createWritableStreamHook: streamNotLoaded,
104
+ createWritableStreamFromHook: streamNotLoaded,
105
+ createReadableStreamHook: streamNotLoaded
106
+ };
86
107
  var StubHook = class {
108
+ // Like call(), but designed for streaming calls (e.g. WritableStream writes). Returns:
109
+ // - promise: A Promise<void> for the completion of the call.
110
+ // - size: If the call was remote, the byte size of the serialized message. For local calls,
111
+ // undefined is returned, indicating the caller should await the promise to serialize writes
112
+ // (no overlapping).
113
+ stream(path, args) {
114
+ let hook = this.call(path, args);
115
+ let pulled = hook.pull();
116
+ let promise;
117
+ if (pulled instanceof Promise) {
118
+ promise = pulled.then((p) => {
119
+ p.dispose();
120
+ });
121
+ } else {
122
+ pulled.dispose();
123
+ promise = Promise.resolve();
124
+ }
125
+ return { promise };
126
+ }
87
127
  };
88
128
  var ErrorStubHook = class extends StubHook {
89
129
  constructor(error) {
@@ -132,7 +172,7 @@ function withCallInterceptor(interceptor, callback) {
132
172
  doCall = oldValue;
133
173
  }
134
174
  }
135
- var RAW_STUB = Symbol("realStub");
175
+ var RAW_STUB = /* @__PURE__ */ Symbol("realStub");
136
176
  var PROXY_HANDLERS = {
137
177
  apply(target, thisArg, argumentsList) {
138
178
  let stub = target.raw;
@@ -308,10 +348,10 @@ async function pullPromise(promise) {
308
348
  }
309
349
  var RpcPayload = class _RpcPayload {
310
350
  // Private constructor; use factory functions above to construct.
311
- constructor(value, source, stubs, promises) {
351
+ constructor(value, source, hooks, promises) {
312
352
  this.value = value;
313
353
  this.source = source;
314
- this.stubs = stubs;
354
+ this.hooks = hooks;
315
355
  this.promises = promises;
316
356
  }
317
357
  // Create a payload from a value passed as params to an RPC from the app.
@@ -336,13 +376,13 @@ var RpcPayload = class _RpcPayload {
336
376
  // stubs is transferred from the inputs to the outputs, hence if the output is disposed, the
337
377
  // inputs should not be. (In case of exception, nothing is disposed, though.)
338
378
  static fromArray(array) {
339
- let stubs = [];
379
+ let hooks = [];
340
380
  let promises = [];
341
381
  let resultArray = [];
342
382
  for (let payload of array) {
343
383
  payload.ensureDeepCopied();
344
- for (let stub of payload.stubs) {
345
- stubs.push(stub);
384
+ for (let hook of payload.hooks) {
385
+ hooks.push(hook);
346
386
  }
347
387
  for (let promise of payload.promises) {
348
388
  if (promise.parent === payload) {
@@ -356,12 +396,12 @@ var RpcPayload = class _RpcPayload {
356
396
  }
357
397
  resultArray.push(payload.value);
358
398
  }
359
- return new _RpcPayload(resultArray, "owned", stubs, promises);
399
+ return new _RpcPayload(resultArray, "owned", hooks, promises);
360
400
  }
361
401
  // Create a payload from a value parsed off the wire using Evaluator.evaluate().
362
402
  //
363
- // A payload is constructed with a null value and the given stubs and promises arrays. The value
364
- // is expected to be filled in by the evaluator, and the stubs and promises arrays are expected
403
+ // A payload is constructed with a null value and the given hooks and promises arrays. The value
404
+ // is expected to be filled in by the evaluator, and the hooks and promises arrays are expected
365
405
  // to be extended with stubs found during parsing. (This weird usage model is necessary so that
366
406
  // if the root value turns out to be a promise, its `parent` in `promises` can be the payload
367
407
  // object itself.)
@@ -369,8 +409,8 @@ var RpcPayload = class _RpcPayload {
369
409
  // When done, the payload takes ownership of the final value and all the stubs within. It may
370
410
  // modify the value in preparation for delivery, and may deliver the value directly to the app
371
411
  // without copying.
372
- static forEvaluate(stubs, promises) {
373
- return new _RpcPayload(null, "owned", stubs, promises);
412
+ static forEvaluate(hooks, promises) {
413
+ return new _RpcPayload(null, "owned", hooks, promises);
374
414
  }
375
415
  // Deep-copy the given value, including dup()ing all stubs.
376
416
  //
@@ -392,14 +432,20 @@ var RpcPayload = class _RpcPayload {
392
432
  return result;
393
433
  }
394
434
  // For `source === "return"` payloads only, this tracks any StubHooks created around RpcTargets
395
- // found in the payload at the time that it is serialized (or deep-copied) for return, so that we
396
- // can make sure they are not disposed before the pipeline ends.
435
+ // or WritableStreams found in the payload at the time that it is serialized (or deep-copied) for
436
+ // return, so that we can make sure they are not disposed before the pipeline ends.
397
437
  //
398
438
  // This is initialized on first use.
399
439
  rpcTargets;
400
440
  // Get the StubHook representing the given RpcTarget found inside this payload.
401
441
  getHookForRpcTarget(target, parent, dupStubs = true) {
402
442
  if (this.source === "params") {
443
+ if (dupStubs) {
444
+ let dupable = target;
445
+ if (typeof dupable.dup === "function") {
446
+ target = dupable.dup();
447
+ }
448
+ }
403
449
  return TargetStubHook.create(target, parent);
404
450
  } else if (this.source === "return") {
405
451
  let hook = this.rpcTargets?.get(target);
@@ -426,6 +472,64 @@ var RpcPayload = class _RpcPayload {
426
472
  throw new Error("owned payload shouldn't contain raw RpcTargets");
427
473
  }
428
474
  }
475
+ // Get the StubHook representing the given WritableStream found inside this payload.
476
+ getHookForWritableStream(stream, parent, dupStubs = true) {
477
+ if (this.source === "params") {
478
+ return streamImpl.createWritableStreamHook(stream);
479
+ } else if (this.source === "return") {
480
+ let hook = this.rpcTargets?.get(stream);
481
+ if (hook) {
482
+ if (dupStubs) {
483
+ return hook.dup();
484
+ } else {
485
+ this.rpcTargets?.delete(stream);
486
+ return hook;
487
+ }
488
+ } else {
489
+ hook = streamImpl.createWritableStreamHook(stream);
490
+ if (dupStubs) {
491
+ if (!this.rpcTargets) {
492
+ this.rpcTargets = /* @__PURE__ */ new Map();
493
+ }
494
+ this.rpcTargets.set(stream, hook);
495
+ return hook.dup();
496
+ } else {
497
+ return hook;
498
+ }
499
+ }
500
+ } else {
501
+ throw new Error("owned payload shouldn't contain raw WritableStreams");
502
+ }
503
+ }
504
+ // Get the StubHook representing the given ReadableStream found inside this payload.
505
+ getHookForReadableStream(stream, parent, dupStubs = true) {
506
+ if (this.source === "params") {
507
+ return streamImpl.createReadableStreamHook(stream);
508
+ } else if (this.source === "return") {
509
+ let hook = this.rpcTargets?.get(stream);
510
+ if (hook) {
511
+ if (dupStubs) {
512
+ return hook.dup();
513
+ } else {
514
+ this.rpcTargets?.delete(stream);
515
+ return hook;
516
+ }
517
+ } else {
518
+ hook = streamImpl.createReadableStreamHook(stream);
519
+ if (dupStubs) {
520
+ if (!this.rpcTargets) {
521
+ this.rpcTargets = /* @__PURE__ */ new Map();
522
+ }
523
+ this.rpcTargets.set(stream, hook);
524
+ return hook.dup();
525
+ } else {
526
+ return hook;
527
+ }
528
+ }
529
+ } else {
530
+ throw new Error("owned payload shouldn't contain raw ReadableStreams");
531
+ }
532
+ }
429
533
  deepCopy(value, oldParent, property, parent, dupStubs, owner) {
430
534
  let kind = typeForRpc(value);
431
535
  switch (kind) {
@@ -469,22 +573,21 @@ var RpcPayload = class _RpcPayload {
469
573
  this.promises.push({ parent, property, promise });
470
574
  return promise;
471
575
  } else {
472
- let newStub = new RpcStub(hook);
473
- this.stubs.push(newStub);
474
- return newStub;
576
+ this.hooks.push(hook);
577
+ return new RpcStub(hook);
475
578
  }
476
579
  }
477
580
  case "function":
478
581
  case "rpc-target": {
479
582
  let target = value;
480
- let stub;
583
+ let hook;
481
584
  if (owner) {
482
- stub = new RpcStub(owner.getHookForRpcTarget(target, oldParent, dupStubs));
585
+ hook = owner.getHookForRpcTarget(target, oldParent, dupStubs);
483
586
  } else {
484
- stub = new RpcStub(TargetStubHook.create(target, oldParent));
587
+ hook = TargetStubHook.create(target, oldParent);
485
588
  }
486
- this.stubs.push(stub);
487
- return stub;
589
+ this.hooks.push(hook);
590
+ return new RpcStub(hook);
488
591
  }
489
592
  case "rpc-thenable": {
490
593
  let target = value;
@@ -497,6 +600,44 @@ var RpcPayload = class _RpcPayload {
497
600
  this.promises.push({ parent, property, promise });
498
601
  return promise;
499
602
  }
603
+ case "writable": {
604
+ let stream = value;
605
+ let hook;
606
+ if (owner) {
607
+ hook = owner.getHookForWritableStream(stream, oldParent, dupStubs);
608
+ } else {
609
+ hook = streamImpl.createWritableStreamHook(stream);
610
+ }
611
+ this.hooks.push(hook);
612
+ return stream;
613
+ }
614
+ case "readable": {
615
+ let stream = value;
616
+ let hook;
617
+ if (owner) {
618
+ hook = owner.getHookForReadableStream(stream, oldParent, dupStubs);
619
+ } else {
620
+ hook = streamImpl.createReadableStreamHook(stream);
621
+ }
622
+ this.hooks.push(hook);
623
+ return stream;
624
+ }
625
+ case "headers":
626
+ return new Headers(value);
627
+ case "request": {
628
+ let req = value;
629
+ if (req.body) {
630
+ this.deepCopy(req.body, req, "body", req, dupStubs, owner);
631
+ }
632
+ return new Request(req);
633
+ }
634
+ case "response": {
635
+ let resp = value;
636
+ if (resp.body) {
637
+ this.deepCopy(resp.body, resp, "body", resp, dupStubs, owner);
638
+ }
639
+ return new Response(resp.body, resp);
640
+ }
500
641
  default:
501
642
  throw new Error("unreachable");
502
643
  }
@@ -506,12 +647,12 @@ var RpcPayload = class _RpcPayload {
506
647
  ensureDeepCopied() {
507
648
  if (this.source !== "owned") {
508
649
  let dupStubs = this.source === "params";
509
- this.stubs = [];
650
+ this.hooks = [];
510
651
  this.promises = [];
511
652
  try {
512
653
  this.value = this.deepCopy(this.value, void 0, "value", this, dupStubs, this);
513
654
  } catch (err) {
514
- this.stubs = void 0;
655
+ this.hooks = void 0;
515
656
  this.promises = void 0;
516
657
  throw err;
517
658
  }
@@ -614,7 +755,7 @@ var RpcPayload = class _RpcPayload {
614
755
  }
615
756
  dispose() {
616
757
  if (this.source === "owned") {
617
- this.stubs.forEach((stub) => stub[Symbol.dispose]());
758
+ this.hooks.forEach((hook) => hook.dispose());
618
759
  this.promises.forEach((promise) => promise.promise[Symbol.dispose]());
619
760
  } else if (this.source === "return") {
620
761
  this.disposeImpl(this.value, void 0);
@@ -623,7 +764,7 @@ var RpcPayload = class _RpcPayload {
623
764
  }
624
765
  } else ;
625
766
  this.source = "owned";
626
- this.stubs = [];
767
+ this.hooks = [];
627
768
  this.promises = [];
628
769
  }
629
770
  // Recursive dispose, called only when `source` is "return".
@@ -676,6 +817,40 @@ var RpcPayload = class _RpcPayload {
676
817
  }
677
818
  case "rpc-thenable":
678
819
  return;
820
+ case "headers":
821
+ return;
822
+ case "request": {
823
+ let req = value;
824
+ if (req.body) this.disposeImpl(req.body, req);
825
+ return;
826
+ }
827
+ case "response": {
828
+ let resp = value;
829
+ if (resp.body) this.disposeImpl(resp.body, resp);
830
+ return;
831
+ }
832
+ case "writable": {
833
+ let stream = value;
834
+ let hook = this.rpcTargets?.get(stream);
835
+ if (hook) {
836
+ this.rpcTargets.delete(stream);
837
+ } else {
838
+ hook = streamImpl.createWritableStreamHook(stream);
839
+ }
840
+ hook.dispose();
841
+ return;
842
+ }
843
+ case "readable": {
844
+ let stream = value;
845
+ let hook = this.rpcTargets?.get(stream);
846
+ if (hook) {
847
+ this.rpcTargets.delete(stream);
848
+ } else {
849
+ hook = streamImpl.createReadableStreamHook(stream);
850
+ }
851
+ hook.dispose();
852
+ return;
853
+ }
679
854
  default:
680
855
  return;
681
856
  }
@@ -684,9 +859,9 @@ var RpcPayload = class _RpcPayload {
684
859
  // *would* be awaited if this payload were to be delivered. See the similarly-named method of
685
860
  // StubHook for explanation.
686
861
  ignoreUnhandledRejections() {
687
- if (this.stubs) {
688
- this.stubs.forEach((stub) => {
689
- unwrapStubOrParent(stub).ignoreUnhandledRejections();
862
+ if (this.hooks) {
863
+ this.hooks.forEach((hook) => {
864
+ hook.ignoreUnhandledRejections();
690
865
  });
691
866
  this.promises.forEach(
692
867
  (promise) => unwrapStubOrParent(promise.promise).ignoreUnhandledRejections()
@@ -707,6 +882,11 @@ var RpcPayload = class _RpcPayload {
707
882
  case "undefined":
708
883
  case "function":
709
884
  case "rpc-target":
885
+ case "writable":
886
+ case "readable":
887
+ case "headers":
888
+ case "request":
889
+ case "response":
710
890
  return;
711
891
  case "array": {
712
892
  let array = value;
@@ -779,11 +959,20 @@ function followPath(value, parent, path, owner) {
779
959
  let { hook, pathIfPromise } = unwrapStubAndPath(value);
780
960
  return { hook, remainingPath: pathIfPromise ? pathIfPromise.concat(path.slice(i)) : path.slice(i) };
781
961
  }
962
+ case "writable":
963
+ value = void 0;
964
+ break;
965
+ case "readable":
966
+ value = void 0;
967
+ break;
782
968
  case "primitive":
783
969
  case "bigint":
784
970
  case "bytes":
785
971
  case "date":
786
972
  case "error":
973
+ case "headers":
974
+ case "request":
975
+ case "response":
787
976
  value = void 0;
788
977
  break;
789
978
  case "undefined":
@@ -1018,6 +1207,14 @@ var PromiseStubHook = class _PromiseStubHook extends StubHook {
1018
1207
  args.ensureDeepCopied();
1019
1208
  return new _PromiseStubHook(this.promise.then((hook) => hook.call(path, args)));
1020
1209
  }
1210
+ stream(path, args) {
1211
+ args.ensureDeepCopied();
1212
+ let promise = this.promise.then((hook) => {
1213
+ let result = hook.stream(path, args);
1214
+ return result.promise;
1215
+ });
1216
+ return { promise };
1217
+ }
1021
1218
  map(path, captures, instructions) {
1022
1219
  return new _PromiseStubHook(this.promise.then(
1023
1220
  (hook) => hook.map(path, captures, instructions),
@@ -1090,6 +1287,9 @@ var NullExporter = class {
1090
1287
  }
1091
1288
  unexport(ids) {
1092
1289
  }
1290
+ createPipe(readable) {
1291
+ throw new Error("Cannot create pipes without an RPC session.");
1292
+ }
1093
1293
  onSendError(error) {
1094
1294
  }
1095
1295
  };
@@ -1194,6 +1394,73 @@ var Devaluator = class _Devaluator {
1194
1394
  ];
1195
1395
  }
1196
1396
  }
1397
+ case "headers":
1398
+ return ["headers", [...value]];
1399
+ case "request": {
1400
+ let req = value;
1401
+ let init = {};
1402
+ if (req.method !== "GET") init.method = req.method;
1403
+ let headers = [...req.headers];
1404
+ if (headers.length > 0) {
1405
+ init.headers = headers;
1406
+ }
1407
+ if (req.body) {
1408
+ init.body = this.devaluateImpl(req.body, req, depth + 1);
1409
+ init.duplex = req.duplex || "half";
1410
+ } else if (req.body === void 0 && !["GET", "HEAD", "OPTIONS", "TRACE", "DELETE"].includes(req.method)) {
1411
+ let bodyPromise = req.arrayBuffer();
1412
+ let readable = new ReadableStream({
1413
+ async start(controller) {
1414
+ try {
1415
+ controller.enqueue(new Uint8Array(await bodyPromise));
1416
+ controller.close();
1417
+ } catch (err) {
1418
+ controller.error(err);
1419
+ }
1420
+ }
1421
+ });
1422
+ let hook = streamImpl.createReadableStreamHook(readable);
1423
+ let importId = this.exporter.createPipe(readable, hook);
1424
+ init.body = ["readable", importId];
1425
+ init.duplex = req.duplex || "half";
1426
+ }
1427
+ if (req.cache && req.cache !== "default") init.cache = req.cache;
1428
+ if (req.redirect !== "follow") init.redirect = req.redirect;
1429
+ if (req.integrity) init.integrity = req.integrity;
1430
+ if (req.mode && req.mode !== "cors") init.mode = req.mode;
1431
+ if (req.credentials && req.credentials !== "same-origin") {
1432
+ init.credentials = req.credentials;
1433
+ }
1434
+ if (req.referrer && req.referrer !== "about:client") init.referrer = req.referrer;
1435
+ if (req.referrerPolicy) init.referrerPolicy = req.referrerPolicy;
1436
+ if (req.keepalive) init.keepalive = req.keepalive;
1437
+ let cfReq = req;
1438
+ if (cfReq.cf) init.cf = cfReq.cf;
1439
+ if (cfReq.encodeResponseBody && cfReq.encodeResponseBody !== "automatic") {
1440
+ init.encodeResponseBody = cfReq.encodeResponseBody;
1441
+ }
1442
+ return ["request", req.url, init];
1443
+ }
1444
+ case "response": {
1445
+ let resp = value;
1446
+ let body = this.devaluateImpl(resp.body, resp, depth + 1);
1447
+ let init = {};
1448
+ if (resp.status !== 200) init.status = resp.status;
1449
+ if (resp.statusText) init.statusText = resp.statusText;
1450
+ let headers = [...resp.headers];
1451
+ if (headers.length > 0) {
1452
+ init.headers = headers;
1453
+ }
1454
+ let cfResp = resp;
1455
+ if (cfResp.cf) init.cf = cfResp.cf;
1456
+ if (cfResp.encodeBody && cfResp.encodeBody !== "automatic") {
1457
+ init.encodeBody = cfResp.encodeBody;
1458
+ }
1459
+ if (cfResp.webSocket) {
1460
+ throw new TypeError("Can't serialize a Response containing a webSocket.");
1461
+ }
1462
+ return ["response", body, init];
1463
+ }
1197
1464
  case "error": {
1198
1465
  let e = value;
1199
1466
  let rewritten = this.exporter.onSendError(e);
@@ -1248,6 +1515,22 @@ var Devaluator = class _Devaluator {
1248
1515
  let hook = this.source.getHookForRpcTarget(value, parent);
1249
1516
  return this.devaluateHook("promise", hook);
1250
1517
  }
1518
+ case "writable": {
1519
+ if (!this.source) {
1520
+ throw new Error("Can't serialize WritableStream in this context.");
1521
+ }
1522
+ let hook = this.source.getHookForWritableStream(value, parent);
1523
+ return this.devaluateHook("writable", hook);
1524
+ }
1525
+ case "readable": {
1526
+ if (!this.source) {
1527
+ throw new Error("Can't serialize ReadableStream in this context.");
1528
+ }
1529
+ let ws = value;
1530
+ let hook = this.source.getHookForReadableStream(ws, parent);
1531
+ let importId = this.exporter.createPipe(ws, hook);
1532
+ return ["readable", importId];
1533
+ }
1251
1534
  default:
1252
1535
  throw new Error("unreachable");
1253
1536
  }
@@ -1272,16 +1555,27 @@ var NullImporter = class {
1272
1555
  getExport(idx) {
1273
1556
  return void 0;
1274
1557
  }
1558
+ getPipeReadable(exportId) {
1559
+ throw new Error("Cannot retrieve pipe readable without an RPC session.");
1560
+ }
1275
1561
  };
1276
1562
  var NULL_IMPORTER = new NullImporter();
1563
+ function fixBrokenRequestBody(request, body) {
1564
+ let promise = new Response(body).arrayBuffer().then((arrayBuffer) => {
1565
+ let bytes = new Uint8Array(arrayBuffer);
1566
+ let result = new Request(request, { body: bytes });
1567
+ return new PayloadStubHook(RpcPayload.fromAppReturn(result));
1568
+ });
1569
+ return new RpcPromise(new PromiseStubHook(promise), []);
1570
+ }
1277
1571
  var Evaluator = class _Evaluator {
1278
1572
  constructor(importer) {
1279
1573
  this.importer = importer;
1280
1574
  }
1281
- stubs = [];
1575
+ hooks = [];
1282
1576
  promises = [];
1283
1577
  evaluate(value) {
1284
- let payload = RpcPayload.forEvaluate(this.stubs, this.promises);
1578
+ let payload = RpcPayload.forEvaluate(this.hooks, this.promises);
1285
1579
  try {
1286
1580
  payload.value = this.evaluateImpl(value, payload, "value");
1287
1581
  return payload;
@@ -1351,6 +1645,56 @@ var Evaluator = class _Evaluator {
1351
1645
  return -Infinity;
1352
1646
  case "nan":
1353
1647
  return NaN;
1648
+ case "headers":
1649
+ if (value.length === 2 && value[1] instanceof Array) {
1650
+ return new Headers(value[1]);
1651
+ }
1652
+ break;
1653
+ case "request": {
1654
+ if (value.length !== 3 || typeof value[1] !== "string") break;
1655
+ let url = value[1];
1656
+ let init = value[2];
1657
+ if (typeof init !== "object" || init === null) break;
1658
+ if (init.body) {
1659
+ init.body = this.evaluateImpl(init.body, init, "body");
1660
+ if (init.body === null || typeof init.body === "string" || init.body instanceof Uint8Array || init.body instanceof ReadableStream) ; else {
1661
+ throw new TypeError("Request body must be of type ReadableStream.");
1662
+ }
1663
+ }
1664
+ if (init.signal) {
1665
+ init.signal = this.evaluateImpl(init.signal, init, "signal");
1666
+ if (!(init.signal instanceof AbortSignal)) {
1667
+ throw new TypeError("Request siganl must be of type AbortSignal.");
1668
+ }
1669
+ }
1670
+ if (init.headers && !(init.headers instanceof Array)) {
1671
+ throw new TypeError("Request headers must be serialized as an array of pairs.");
1672
+ }
1673
+ let result = new Request(url, init);
1674
+ if (init.body instanceof ReadableStream && result.body === void 0) {
1675
+ let promise = fixBrokenRequestBody(result, init.body);
1676
+ this.promises.push({ promise, parent, property });
1677
+ return promise;
1678
+ } else {
1679
+ return result;
1680
+ }
1681
+ }
1682
+ case "response": {
1683
+ if (value.length !== 3) break;
1684
+ let body = this.evaluateImpl(value[1], parent, property);
1685
+ if (body === null || typeof body === "string" || body instanceof Uint8Array || body instanceof ReadableStream) ; else {
1686
+ throw new TypeError("Response body must be of type ReadableStream.");
1687
+ }
1688
+ let init = value[2];
1689
+ if (typeof init !== "object" || init === null) break;
1690
+ if (init.webSocket) {
1691
+ throw new TypeError("Can't deserialize a Response containing a webSocket.");
1692
+ }
1693
+ if (init.headers && !(init.headers instanceof Array)) {
1694
+ throw new TypeError("Request headers must be serialized as an array of pairs.");
1695
+ }
1696
+ return new Response(body, init);
1697
+ }
1354
1698
  case "import":
1355
1699
  case "pipeline": {
1356
1700
  if (value.length < 2 || value.length > 4) {
@@ -1370,9 +1714,8 @@ var Evaluator = class _Evaluator {
1370
1714
  this.promises.push({ promise, parent, property });
1371
1715
  return promise;
1372
1716
  } else {
1373
- let stub = new RpcPromise(hook2, []);
1374
- this.stubs.push(stub);
1375
- return stub;
1717
+ this.hooks.push(hook2);
1718
+ return new RpcPromise(hook2, []);
1376
1719
  }
1377
1720
  };
1378
1721
  if (value.length == 2) {
@@ -1450,12 +1793,27 @@ var Evaluator = class _Evaluator {
1450
1793
  return promise;
1451
1794
  } else {
1452
1795
  let hook = this.importer.importStub(value[1]);
1453
- let stub = new RpcStub(hook);
1454
- this.stubs.push(stub);
1455
- return stub;
1796
+ this.hooks.push(hook);
1797
+ return new RpcStub(hook);
1456
1798
  }
1457
1799
  }
1458
1800
  break;
1801
+ case "writable":
1802
+ if (typeof value[1] == "number") {
1803
+ let hook = this.importer.importStub(value[1]);
1804
+ let stream = streamImpl.createWritableStreamFromHook(hook);
1805
+ this.hooks.push(hook);
1806
+ return stream;
1807
+ }
1808
+ break;
1809
+ case "readable":
1810
+ if (typeof value[1] == "number") {
1811
+ let stream = this.importer.getPipeReadable(value[1]);
1812
+ let hook = streamImpl.createReadableStreamHook(stream);
1813
+ this.hooks.push(hook);
1814
+ return stream;
1815
+ }
1816
+ break;
1459
1817
  }
1460
1818
  throw new TypeError(`unknown special value: ${JSON.stringify(value)}`);
1461
1819
  } else if (value instanceof Object) {
@@ -1595,6 +1953,14 @@ var RpcImportHook = class _RpcImportHook extends StubHook {
1595
1953
  return entry.session.sendCall(entry.importId, path, args);
1596
1954
  }
1597
1955
  }
1956
+ stream(path, args) {
1957
+ let entry = this.getEntry();
1958
+ if (entry.resolution) {
1959
+ return entry.resolution.stream(path, args);
1960
+ } else {
1961
+ return entry.session.sendStream(entry.importId, path, args);
1962
+ }
1963
+ }
1598
1964
  map(path, captures, instructions) {
1599
1965
  let entry;
1600
1966
  try {
@@ -1767,19 +2133,23 @@ var RpcSessionImpl = class {
1767
2133
  return payload;
1768
2134
  }
1769
2135
  };
2136
+ let autoRelease = exp.autoRelease;
1770
2137
  ++this.pullCount;
1771
2138
  exp.pull = resolve().then(
1772
2139
  (payload) => {
1773
2140
  let value = Devaluator.devaluate(payload.value, void 0, this, payload);
1774
2141
  this.send(["resolve", exportId, value]);
2142
+ if (autoRelease) this.releaseExport(exportId, 1);
1775
2143
  },
1776
2144
  (error) => {
1777
2145
  this.send(["reject", exportId, Devaluator.devaluate(error, void 0, this)]);
2146
+ if (autoRelease) this.releaseExport(exportId, 1);
1778
2147
  }
1779
2148
  ).catch(
1780
2149
  (error) => {
1781
2150
  try {
1782
2151
  this.send(["reject", exportId, Devaluator.devaluate(error, void 0, this)]);
2152
+ if (autoRelease) this.releaseExport(exportId, 1);
1783
2153
  } catch (error2) {
1784
2154
  this.abort(error2);
1785
2155
  }
@@ -1831,9 +2201,35 @@ var RpcSessionImpl = class {
1831
2201
  getExport(idx) {
1832
2202
  return this.exports[idx]?.hook;
1833
2203
  }
2204
+ getPipeReadable(exportId) {
2205
+ let entry = this.exports[exportId];
2206
+ if (!entry || !entry.pipeReadable) {
2207
+ throw new Error(`Export ${exportId} is not a pipe or its readable end was already consumed.`);
2208
+ }
2209
+ let readable = entry.pipeReadable;
2210
+ entry.pipeReadable = void 0;
2211
+ return readable;
2212
+ }
2213
+ createPipe(readable, readableHook) {
2214
+ if (this.abortReason) throw this.abortReason;
2215
+ this.send(["pipe"]);
2216
+ let importId = this.imports.length;
2217
+ let entry = new ImportTableEntry(this, importId, false);
2218
+ this.imports.push(entry);
2219
+ let hook = new RpcImportHook(
2220
+ /*isPromise=*/
2221
+ false,
2222
+ entry
2223
+ );
2224
+ let writable = streamImpl.createWritableStreamFromHook(hook);
2225
+ readable.pipeTo(writable).catch(() => {
2226
+ }).finally(() => readableHook.dispose());
2227
+ return importId;
2228
+ }
2229
+ // Serializes and sends a message. Returns the byte length of the serialized message.
1834
2230
  send(msg) {
1835
2231
  if (this.abortReason !== void 0) {
1836
- return;
2232
+ return 0;
1837
2233
  }
1838
2234
  let msgText;
1839
2235
  try {
@@ -1846,6 +2242,7 @@ var RpcSessionImpl = class {
1846
2242
  throw err;
1847
2243
  }
1848
2244
  this.transport.send(msgText).catch((err) => this.abort(err, false));
2245
+ return msgText.length;
1849
2246
  }
1850
2247
  sendCall(id, path, args) {
1851
2248
  if (this.abortReason) throw this.abortReason;
@@ -1863,6 +2260,34 @@ var RpcSessionImpl = class {
1863
2260
  entry
1864
2261
  );
1865
2262
  }
2263
+ sendStream(id, path, args) {
2264
+ if (this.abortReason) throw this.abortReason;
2265
+ let value = ["pipeline", id, path];
2266
+ let devalue = Devaluator.devaluate(args.value, void 0, this, args);
2267
+ value.push(devalue[0]);
2268
+ let size = this.send(["stream", value]);
2269
+ let importId = this.imports.length;
2270
+ let entry = new ImportTableEntry(
2271
+ this,
2272
+ importId,
2273
+ /*pulling=*/
2274
+ true
2275
+ );
2276
+ entry.remoteRefcount = 0;
2277
+ entry.localRefcount = 1;
2278
+ this.imports.push(entry);
2279
+ let promise = entry.awaitResolution().then(
2280
+ (p) => {
2281
+ p.dispose();
2282
+ delete this.imports[importId];
2283
+ },
2284
+ (err) => {
2285
+ delete this.imports[importId];
2286
+ throw err;
2287
+ }
2288
+ );
2289
+ return { promise, size };
2290
+ }
1866
2291
  sendMap(id, path, captures, instructions) {
1867
2292
  if (this.abortReason) {
1868
2293
  for (let cap of captures) {
@@ -1950,6 +2375,24 @@ var RpcSessionImpl = class {
1950
2375
  continue;
1951
2376
  }
1952
2377
  break;
2378
+ case "stream": {
2379
+ if (msg.length > 1) {
2380
+ let payload = new Evaluator(this).evaluate(msg[1]);
2381
+ let hook = new PayloadStubHook(payload);
2382
+ hook.ignoreUnhandledRejections();
2383
+ let exportId = this.exports.length;
2384
+ this.exports.push({ hook, refcount: 1, autoRelease: true });
2385
+ this.ensureResolvingExport(exportId);
2386
+ continue;
2387
+ }
2388
+ break;
2389
+ }
2390
+ case "pipe": {
2391
+ let { readable, writable } = new TransformStream();
2392
+ let hook = streamImpl.createWritableStreamHook(writable);
2393
+ this.exports.push({ hook, refcount: 1, pipeReadable: readable });
2394
+ continue;
2395
+ }
1953
2396
  case "pull": {
1954
2397
  let exportId = msg[1];
1955
2398
  if (typeof exportId == "number") {
@@ -2445,6 +2888,9 @@ var MapBuilder = class {
2445
2888
  }
2446
2889
  unexport(ids) {
2447
2890
  }
2891
+ createPipe(readable) {
2892
+ throw new Error("Cannot send ReadableStream inside a mapper function.");
2893
+ }
2448
2894
  onSendError(error) {
2449
2895
  }
2450
2896
  };
@@ -2554,6 +3000,9 @@ var MapApplicator = class {
2554
3000
  return this.variables[idx];
2555
3001
  }
2556
3002
  }
3003
+ getPipeReadable(exportId) {
3004
+ throw new Error("A mapper function cannot use pipe readables.");
3005
+ }
2557
3006
  };
2558
3007
  function applyMapToElement(input, parent, owner, captures, instructions) {
2559
3008
  let inputHook = new PayloadStubHook(RpcPayload.deepCopyFrom(input, parent, owner));
@@ -2594,6 +3043,333 @@ mapImpl.applyMap = (input, parent, owner, captures, instructions) => {
2594
3043
  }
2595
3044
  }
2596
3045
  };
3046
+
3047
+ // src/streams.ts
3048
+ var WritableStreamStubHook = class _WritableStreamStubHook extends StubHook {
3049
+ state;
3050
+ // undefined when disposed
3051
+ // Creates a new WritableStreamStubHook that is not duplicated from an existing hook.
3052
+ static create(stream) {
3053
+ let writer = stream.getWriter();
3054
+ return new _WritableStreamStubHook({ refcount: 1, writer, closed: false });
3055
+ }
3056
+ constructor(state, dupFrom) {
3057
+ super();
3058
+ this.state = state;
3059
+ if (dupFrom) {
3060
+ ++state.refcount;
3061
+ }
3062
+ }
3063
+ getState() {
3064
+ if (this.state) {
3065
+ return this.state;
3066
+ } else {
3067
+ throw new Error("Attempted to use a WritableStreamStubHook after it was disposed.");
3068
+ }
3069
+ }
3070
+ call(path, args) {
3071
+ try {
3072
+ let state = this.getState();
3073
+ if (path.length !== 1 || typeof path[0] !== "string") {
3074
+ throw new Error("WritableStream stub only supports direct method calls");
3075
+ }
3076
+ const method = path[0];
3077
+ if (method !== "write" && method !== "close" && method !== "abort") {
3078
+ args.dispose();
3079
+ throw new Error(`Unknown WritableStream method: ${method}`);
3080
+ }
3081
+ if (method === "close" || method === "abort") {
3082
+ state.closed = true;
3083
+ }
3084
+ let func = state.writer[method];
3085
+ let promise = args.deliverCall(func, state.writer);
3086
+ return new PromiseStubHook(promise.then((payload) => new PayloadStubHook(payload)));
3087
+ } catch (err) {
3088
+ return new ErrorStubHook(err);
3089
+ }
3090
+ }
3091
+ map(path, captures, instructions) {
3092
+ for (let cap of captures) {
3093
+ cap.dispose();
3094
+ }
3095
+ return new ErrorStubHook(new Error("Cannot use map() on a WritableStream"));
3096
+ }
3097
+ get(path) {
3098
+ return new ErrorStubHook(new Error("Cannot access properties on a WritableStream stub"));
3099
+ }
3100
+ dup() {
3101
+ let state = this.getState();
3102
+ return new _WritableStreamStubHook(state, this);
3103
+ }
3104
+ pull() {
3105
+ return Promise.reject(new Error("Cannot pull a WritableStream stub"));
3106
+ }
3107
+ ignoreUnhandledRejections() {
3108
+ }
3109
+ dispose() {
3110
+ let state = this.state;
3111
+ this.state = void 0;
3112
+ if (state) {
3113
+ if (--state.refcount === 0) {
3114
+ if (!state.closed) {
3115
+ state.writer.abort(new Error("WritableStream RPC stub was disposed without calling close()")).catch(() => {
3116
+ });
3117
+ }
3118
+ state.writer.releaseLock();
3119
+ }
3120
+ }
3121
+ }
3122
+ onBroken(callback) {
3123
+ }
3124
+ };
3125
+ var INITIAL_WINDOW = 256 * 1024;
3126
+ var MAX_WINDOW = 1024 * 1024 * 1024;
3127
+ var MIN_WINDOW = 64 * 1024;
3128
+ var STARTUP_GROWTH_FACTOR = 2;
3129
+ var STEADY_GROWTH_FACTOR = 1.25;
3130
+ var DECAY_FACTOR = 0.9;
3131
+ var STARTUP_EXIT_ROUNDS = 3;
3132
+ var FlowController = class {
3133
+ constructor(now) {
3134
+ this.now = now;
3135
+ }
3136
+ // The current window size in bytes. The sender blocks when bytesInFlight >= window.
3137
+ window = INITIAL_WINDOW;
3138
+ // Total bytes currently in flight (sent but not yet acked).
3139
+ bytesInFlight = 0;
3140
+ // Whether we're still in the startup phase.
3141
+ inStartupPhase = true;
3142
+ // ----- BDP estimation state (private) -----
3143
+ // Total bytes acked so far.
3144
+ delivered = 0;
3145
+ // Time of most recent ack.
3146
+ deliveredTime = 0;
3147
+ // Time when the very first ack was received.
3148
+ firstAckTime = 0;
3149
+ firstAckDelivered = 0;
3150
+ // Global minimum RTT observed (milliseconds).
3151
+ minRtt = Infinity;
3152
+ // For startup exit: count of consecutive RTT rounds where the window didn't meaningfully grow.
3153
+ roundsWithoutIncrease = 0;
3154
+ // Window size at the start of the current round, for startup exit detection.
3155
+ lastRoundWindow = 0;
3156
+ // Time when the current round started.
3157
+ roundStartTime = 0;
3158
+ // Called when a write of `size` bytes is about to be sent. Returns a token that must be
3159
+ // passed to onAck() when the ack arrives, and whether the sender should block (window full).
3160
+ onSend(size) {
3161
+ this.bytesInFlight += size;
3162
+ let token = {
3163
+ sentTime: this.now(),
3164
+ size,
3165
+ deliveredAtSend: this.delivered,
3166
+ deliveredTimeAtSend: this.deliveredTime,
3167
+ windowAtSend: this.window,
3168
+ windowFullAtSend: this.bytesInFlight >= this.window
3169
+ };
3170
+ return { token, shouldBlock: token.windowFullAtSend };
3171
+ }
3172
+ // Called when a previously-sent write fails. Restores bytesInFlight without updating
3173
+ // any BDP estimates.
3174
+ onError(token) {
3175
+ this.bytesInFlight -= token.size;
3176
+ }
3177
+ // Called when an ack is received for a previously-sent write. Updates BDP estimates and
3178
+ // the window. Returns whether a blocked sender should now unblock.
3179
+ onAck(token) {
3180
+ let ackTime = this.now();
3181
+ this.delivered += token.size;
3182
+ this.deliveredTime = ackTime;
3183
+ this.bytesInFlight -= token.size;
3184
+ let rtt = ackTime - token.sentTime;
3185
+ this.minRtt = Math.min(this.minRtt, rtt);
3186
+ if (this.firstAckTime === 0) {
3187
+ this.firstAckTime = ackTime;
3188
+ this.firstAckDelivered = this.delivered;
3189
+ } else {
3190
+ let baseTime;
3191
+ let baseDelivered;
3192
+ if (token.deliveredTimeAtSend === 0) {
3193
+ baseTime = this.firstAckTime;
3194
+ baseDelivered = this.firstAckDelivered;
3195
+ } else {
3196
+ baseTime = token.deliveredTimeAtSend;
3197
+ baseDelivered = token.deliveredAtSend;
3198
+ }
3199
+ let interval = ackTime - baseTime;
3200
+ let bytes = this.delivered - baseDelivered;
3201
+ let bandwidth = bytes / interval;
3202
+ let growthFactor = this.inStartupPhase ? STARTUP_GROWTH_FACTOR : STEADY_GROWTH_FACTOR;
3203
+ let newWindow = bandwidth * this.minRtt * growthFactor;
3204
+ newWindow = Math.min(newWindow, token.windowAtSend * growthFactor);
3205
+ if (token.windowFullAtSend) {
3206
+ newWindow = Math.max(newWindow, token.windowAtSend * DECAY_FACTOR);
3207
+ } else {
3208
+ newWindow = Math.max(newWindow, this.window);
3209
+ }
3210
+ this.window = Math.max(Math.min(newWindow, MAX_WINDOW), MIN_WINDOW);
3211
+ if (this.inStartupPhase && token.sentTime >= this.roundStartTime) {
3212
+ if (this.window > this.lastRoundWindow * STEADY_GROWTH_FACTOR) {
3213
+ this.roundsWithoutIncrease = 0;
3214
+ } else {
3215
+ if (++this.roundsWithoutIncrease >= STARTUP_EXIT_ROUNDS) {
3216
+ this.inStartupPhase = false;
3217
+ }
3218
+ }
3219
+ this.roundStartTime = ackTime;
3220
+ this.lastRoundWindow = this.window;
3221
+ }
3222
+ }
3223
+ return this.bytesInFlight < this.window;
3224
+ }
3225
+ };
3226
+ function createWritableStreamFromHook(hook) {
3227
+ let pendingError = void 0;
3228
+ let hookDisposed = false;
3229
+ let fc = new FlowController(() => performance.now());
3230
+ let windowResolve;
3231
+ let windowReject;
3232
+ const disposeHook = () => {
3233
+ if (!hookDisposed) {
3234
+ hookDisposed = true;
3235
+ hook.dispose();
3236
+ }
3237
+ };
3238
+ return new WritableStream({
3239
+ write(chunk, controller) {
3240
+ if (pendingError !== void 0) {
3241
+ throw pendingError;
3242
+ }
3243
+ const payload = RpcPayload.fromAppParams([chunk]);
3244
+ const { promise, size } = hook.stream(["write"], payload);
3245
+ if (size === void 0) {
3246
+ return promise.catch((err) => {
3247
+ if (pendingError === void 0) {
3248
+ pendingError = err;
3249
+ }
3250
+ throw err;
3251
+ });
3252
+ } else {
3253
+ let { token, shouldBlock } = fc.onSend(size);
3254
+ promise.then(() => {
3255
+ let hasCapacity = fc.onAck(token);
3256
+ if (hasCapacity && windowResolve) {
3257
+ windowResolve();
3258
+ windowResolve = void 0;
3259
+ windowReject = void 0;
3260
+ }
3261
+ }, (err) => {
3262
+ fc.onError(token);
3263
+ if (pendingError === void 0) {
3264
+ pendingError = err;
3265
+ controller.error(err);
3266
+ disposeHook();
3267
+ }
3268
+ if (windowReject) {
3269
+ windowReject(err);
3270
+ windowResolve = void 0;
3271
+ windowReject = void 0;
3272
+ }
3273
+ });
3274
+ if (shouldBlock) {
3275
+ return new Promise((resolve, reject) => {
3276
+ windowResolve = resolve;
3277
+ windowReject = reject;
3278
+ });
3279
+ }
3280
+ }
3281
+ },
3282
+ async close() {
3283
+ if (pendingError !== void 0) {
3284
+ disposeHook();
3285
+ throw pendingError;
3286
+ }
3287
+ const { promise } = hook.stream(["close"], RpcPayload.fromAppParams([]));
3288
+ try {
3289
+ await promise;
3290
+ } catch (err) {
3291
+ throw pendingError ?? err;
3292
+ } finally {
3293
+ disposeHook();
3294
+ }
3295
+ },
3296
+ abort(reason) {
3297
+ if (pendingError !== void 0) {
3298
+ return;
3299
+ }
3300
+ pendingError = reason ?? new Error("WritableStream was aborted");
3301
+ if (windowReject) {
3302
+ windowReject(pendingError);
3303
+ windowResolve = void 0;
3304
+ windowReject = void 0;
3305
+ }
3306
+ const { promise } = hook.stream(["abort"], RpcPayload.fromAppParams([reason]));
3307
+ promise.then(() => disposeHook(), () => disposeHook());
3308
+ }
3309
+ });
3310
+ }
3311
+ var ReadableStreamStubHook = class _ReadableStreamStubHook extends StubHook {
3312
+ state;
3313
+ // undefined when disposed
3314
+ // Creates a new ReadableStreamStubHook.
3315
+ static create(stream) {
3316
+ return new _ReadableStreamStubHook({ refcount: 1, stream, canceled: false });
3317
+ }
3318
+ constructor(state, dupFrom) {
3319
+ super();
3320
+ this.state = state;
3321
+ if (dupFrom) {
3322
+ ++state.refcount;
3323
+ }
3324
+ }
3325
+ call(path, args) {
3326
+ args.dispose();
3327
+ return new ErrorStubHook(new Error("Cannot call methods on a ReadableStream stub"));
3328
+ }
3329
+ map(path, captures, instructions) {
3330
+ for (let cap of captures) {
3331
+ cap.dispose();
3332
+ }
3333
+ return new ErrorStubHook(new Error("Cannot use map() on a ReadableStream"));
3334
+ }
3335
+ get(path) {
3336
+ return new ErrorStubHook(new Error("Cannot access properties on a ReadableStream stub"));
3337
+ }
3338
+ dup() {
3339
+ let state = this.state;
3340
+ if (!state) {
3341
+ throw new Error("Attempted to dup a ReadableStreamStubHook after it was disposed.");
3342
+ }
3343
+ return new _ReadableStreamStubHook(state, this);
3344
+ }
3345
+ pull() {
3346
+ return Promise.reject(new Error("Cannot pull a ReadableStream stub"));
3347
+ }
3348
+ ignoreUnhandledRejections() {
3349
+ }
3350
+ dispose() {
3351
+ let state = this.state;
3352
+ this.state = void 0;
3353
+ if (state) {
3354
+ if (--state.refcount === 0) {
3355
+ if (!state.canceled) {
3356
+ state.canceled = true;
3357
+ if (!state.stream.locked) {
3358
+ state.stream.cancel(
3359
+ new Error("ReadableStream RPC stub was disposed without being consumed")
3360
+ ).catch(() => {
3361
+ });
3362
+ }
3363
+ }
3364
+ }
3365
+ }
3366
+ }
3367
+ onBroken(callback) {
3368
+ }
3369
+ };
3370
+ streamImpl.createWritableStreamHook = WritableStreamStubHook.create;
3371
+ streamImpl.createWritableStreamFromHook = createWritableStreamFromHook;
3372
+ streamImpl.createReadableStreamHook = ReadableStreamStubHook.create;
2597
3373
  var RpcStub2 = RpcStub;
2598
3374
  var RpcPromise2 = RpcPromise;
2599
3375
  var RpcSession2 = RpcSession;