UNPKG

@hazae41/kcp

Version:

Zero-copy KCP protocol for the web

1 lines 5.98 kB
{"version":3,"file":"index.cjs","sources":["../../../../../src/mods/kcp/stream/index.ts"],"sourcesContent":["import { Opaque, Writable } from \"@hazae41/binary\";\nimport { FullDuplex } from \"@hazae41/cascade\";\nimport { Cursor } from \"@hazae41/cursor\";\nimport { Future } from \"@hazae41/future\";\nimport { Awaitable } from \"libs/promises/index.js\";\nimport { SecretKcpReader } from \"../reader/index.js\";\nimport { SecretKcpWriter } from \"../writer/index.js\";\n\nexport interface KcpDuplexParams {\n /**\n * Conversation ID (Uint32) (random if undefined)\n */\n readonly conversation?: number\n\n readonly lowDelay?: number\n readonly highDelay?: number\n\n close?(this: undefined): Awaitable<void>\n error?(this: undefined, reason?: unknown): Awaitable<void>\n}\n\nexport class KcpDuplex {\n\n readonly #secret: SecretKcpDuplex\n\n constructor(\n readonly params: KcpDuplexParams = {}\n ) {\n this.#secret = new SecretKcpDuplex(params)\n }\n\n [Symbol.dispose]() {\n this.close()\n }\n\n get conversation() {\n return this.#secret.conversation\n }\n\n get inner() {\n return this.#secret.inner\n }\n\n get outer() {\n return this.#secret.outer\n }\n\n get closing() {\n return this.#secret.closing\n }\n\n get closed() {\n return this.#secret.closed\n }\n\n error(reason?: unknown) {\n this.#secret.error(reason)\n }\n\n close() {\n this.#secret.close()\n }\n\n}\n\nexport class SecretKcpDuplex {\n\n readonly duplex: FullDuplex<Opaque, Writable>\n\n readonly reader: SecretKcpReader\n readonly writer: SecretKcpWriter\n\n readonly conversation: number\n\n readonly resolveOnClose = new Future<void>()\n readonly resolveOnError = new Future<unknown>()\n\n readonly resolveOnAckBySerial = new Map<number, Future<void>>()\n\n sendCounter = 0\n recvCounter = 0\n\n constructor(\n readonly params: KcpDuplexParams = {}\n ) {\n const {\n conversation = new Cursor(crypto.getRandomValues(new Uint8Array(4))).readUint32OrThrow(true)\n } = this.params\n\n this.conversation = conversation\n\n this.reader = new SecretKcpReader(this)\n this.writer = new SecretKcpWriter(this)\n\n this.duplex = new FullDuplex<Opaque, Writable>({\n input: {\n write: m => this.reader.onWrite(m)\n },\n output: {\n write: m => this.writer.onWrite(m)\n },\n close: () => this.#onDuplexClose(),\n error: e => this.#onDuplexError(e)\n })\n }\n\n [Symbol.dispose]() {\n this.close()\n }\n\n get inner() {\n return this.duplex.inner\n }\n\n get outer() {\n return this.duplex.outer\n }\n\n get input() {\n return this.duplex.input\n }\n\n get output() {\n return this.duplex.output\n }\n\n get closing() {\n return this.duplex.closing\n }\n\n get closed() {\n return this.duplex.closed\n }\n\n async #onDuplexClose() {\n this.resolveOnClose.resolve()\n await this.params.close?.call(undefined)\n }\n\n async #onDuplexError(cause?: unknown) {\n this.resolveOnError.resolve(cause)\n await this.params.error?.call(undefined, cause)\n }\n\n error(reason?: unknown) {\n this.duplex.error(reason)\n }\n\n close() {\n this.duplex.close()\n }\n\n}"],"names":["Future","Cursor","SecretKcpReader","SecretKcpWriter","FullDuplex"],"mappings":"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"}