1 line
14 KiB
JSON
1 line
14 KiB
JSON
|
{"ast":null,"code":"import { ByteQueue } from \"../byte_queue.js\";\nimport { Cursor } from \"../cursor.js\";\nimport * as jsond from \"../encoding/json/decode.js\";\nimport * as protobufd from \"../encoding/protobuf/decode.js\";\nimport { ClientError, ClosedError, ProtoError, InternalError } from \"../errors.js\";\nimport { impossible } from \"../util.js\";\nimport { CursorRespBody as json_CursorRespBody } from \"./json_decode.js\";\nimport { CursorRespBody as protobuf_CursorRespBody } from \"./protobuf_decode.js\";\nimport { CursorEntry as json_CursorEntry } from \"../shared/json_decode.js\";\nimport { CursorEntry as protobuf_CursorEntry } from \"../shared/protobuf_decode.js\";\nexport class HttpCursor extends Cursor {\n #stream;\n #encoding;\n #reader;\n #queue;\n #closed;\n #done;\n /** @private */\n constructor(stream, encoding) {\n super();\n this.#stream = stream;\n this.#encoding = encoding;\n this.#reader = undefined;\n this.#queue = new ByteQueue(16 * 1024);\n this.#closed = undefined;\n this.#done = false;\n }\n async open(response) {\n if (response.body === null) {\n throw new ProtoError(\"No response body for cursor request\");\n }\n this.#reader = response.body.getReader();\n const respBody = await this.#nextItem(json_CursorRespBody, protobuf_CursorRespBody);\n if (respBody === undefined) {\n throw new ProtoError(\"Empty response to cursor request\");\n }\n return respBody;\n }\n /** Fetch the next entry from the cursor. */\n next() {\n return this.#nextItem(json_CursorEntry, protobuf_CursorEntry);\n }\n /** Close the cursor. */\n close() {\n this._setClosed(new ClientError(\"Cursor was manually closed\"));\n }\n /** @private */\n _setClosed(error) {\n if (this.#closed !== undefined) {\n return;\n }\n this.#closed = error;\n this.#stream._cursorClosed(this);\n if (this.#reader !== undefined) {\n this.#reader.cancel();\n }\n }\n /** True if the cursor is closed. */\n get closed() {\n return this.#closed !== undefined;\n }\n async #nextItem(jsonFun, protobufDef) {\n for (;;) {\n if (this.#done) {\n return undefined;\n } else if (this.#closed !== undefined) {\n throw new ClosedError(\"Cursor is closed\", this.#closed);\n }\n if (this.#encoding === \"json\") {\n const jsonData = this.#parseItemJson();\n if (jsonData !== undefined) {\n const jsonText = new TextDecoder().decode(jsonData);\n const jsonValue = JSON.parse(jsonText);\n return jsond.readJsonObject(jsonValue, jsonFun);\n }\n } else if (this.#encoding === \"protobuf\") {\n const protobufData = this.#parseItemProtobuf();\n if (protobufData !== undefined) {\n return protobufd.readProtobufMessage(protobufData, protobufDef);\n }\n } else {\n throw impossible(this.#encoding, \"Impossible encoding\");\n }\n if (this.#reader === undefined) {\n throw new InternalError(\"Attempted to read from HTTP cursor before it was opened\");\n }\n const {\n value,\n done\n } = await this.#reader.read();\n if (done && this.#queue.length === 0) {\n this.#done = true;\n } else if (done) {\n throw new ProtoError(\"Unexpected end of cursor stream\");\n } else {\n this.#queue.push(value);\n }\n }\n }\n #parseItemJson() {\n const data = this.#queue.data();\n const newlineByte = 10;\n const newlinePos = data.indexOf(newlineByte);\n if (newlinePos < 0) {\n return undefined;\n }\n const jsonData = data.slice(0, newlinePos);\n this.#queue.shift(newlinePos + 1);\n return jsonData;\n }\n #parseItemProtobuf() {\n const data = this.#queue.data();\n let varintValue = 0;\n let varintLength = 0;\n for (;;) {\n if (varintLength >= data.byteLength) {\n return undefined;\n }\n const byte = data[varintLength];\n varintValue |= (byte & 0x7f) << 7 * varintLength;\n varintLength += 1;\n i
|