MCPcopy
hub / github.com/cloudflare/capnweb / RpcSessionImpl

Class RpcSessionImpl

src/rpc.ts:448–1081  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

446};
447
448class RpcSessionImpl implements Importer, Exporter {
449 private exports: Array<ExportTableEntry> = [];
450 private reverseExports: Map<StubHook, ExportId> = new Map();
451 private imports: Array<ImportTableEntry> = [];
452 private abortReason?: any;
453 private cancelReadLoop?: (error: any) => void;
454
455 // We assign positive numbers to imports we initiate, and negative numbers to exports we
456 // initiate. So the next import ID is just `imports.length`, but the next export ID needs
457 // to be tracked explicitly.
458 private nextExportId = -1;
459
460 // If set, call this when all incoming calls are complete.
461 private onBatchDone?: Omit<PromiseWithResolvers<void>, "promise">;
462
463 // How many promises is our peer expecting us to resolve?
464 private pullCount = 0;
465
466 // Sparse array of onBrokenCallback registrations. Items are strictly appended to the end but
467 // may be deleted from the middle (hence leaving the array sparse).
468 onBrokenCallbacks: ((error: any) => void)[] = [];
469
470 // Encoding level from the transport (defaults to "string")
471 private encodingLevel: EncodingLevel;
472
473 constructor(private transport: AnyRpcTransport, mainHook: StubHook,
474 private options: RpcSessionOptions) {
475 // `RpcTransport` has no `encodingLevel` field, so its presence is what marks a custom-encoding
476 // transport. Read it defensively: treat a present-but-`undefined` value (e.g. an uninitialized
477 // class field) as the default string level rather than mis-routing it down the custom-encoding
478 // path, and reject any other unrecognized value (e.g. a stale pre-rename level name) loudly
479 // instead of silently corrupting the wire.
480 let level: EncodingLevel = "string";
481 if ('encodingLevel' in transport) {
482 let raw = transport.encodingLevel as unknown;
483 if (raw !== undefined) {
484 if (raw !== "string" && raw !== "jsonCompatible" &&
485 raw !== "jsonCompatibleWithBytes" && raw !== "structuredClonable") {
486 throw new TypeError(`Unknown transport encodingLevel: ${String(raw)}`);
487 }
488 level = raw;
489 }
490 }
491 this.encodingLevel = level;
492 // Export zero is automatically the bootstrap object.
493 this.exports.push({hook: mainHook, refcount: 1});
494
495 // Import zero is the other side's bootstrap object.
496 this.imports.push(new ImportTableEntry(this, 0, false));
497
498 this.readLoop().catch(err => this.abort(err));
499 }
500
501 // Should only be called once immediately after construction.
502 getMainImport(): RpcImportHook {
503 return new RpcMainHook(this.imports[0]);
504 }
505

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…