Spaces:
Sleeping
Sleeping
File size: 4,533 Bytes
65c617d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpClient = exports.checkEndpoints = void 0;
const client_js_1 = require("../client.js");
const errors_js_1 = require("../errors.js");
const stream_js_1 = require("./stream.js");
exports.checkEndpoints = [
{
versionPath: "v3-protobuf",
pipelinePath: "v3-protobuf/pipeline",
cursorPath: "v3-protobuf/cursor",
version: 3,
encoding: "protobuf",
},
/*
{
versionPath: "v3",
pipelinePath: "v3/pipeline",
cursorPath: "v3/cursor",
version: 3,
encoding: "json",
},
*/
];
const fallbackEndpoint = {
versionPath: "v2",
pipelinePath: "v2/pipeline",
cursorPath: undefined,
version: 2,
encoding: "json",
};
/** A client for the Hrana protocol over HTTP. */
class HttpClient extends client_js_1.Client {
#url;
#jwt;
#fetch;
#remoteEncryptionKey;
#closed;
#streams;
/** @private */
_endpointPromise;
/** @private */
_endpoint;
/** @private */
constructor(url, jwt, customFetch, remoteEncryptionKey, protocolVersion = 2) {
super();
this.#url = url;
this.#jwt = jwt;
this.#fetch = customFetch ?? globalThis.fetch;
this.#remoteEncryptionKey = remoteEncryptionKey;
this.#closed = undefined;
this.#streams = new Set();
if (protocolVersion == 3) {
this._endpointPromise = findEndpoint(this.#fetch, this.#url);
this._endpointPromise.then((endpoint) => this._endpoint = endpoint, (error) => this.#setClosed(error));
}
else {
this._endpointPromise = Promise.resolve(fallbackEndpoint);
this._endpointPromise.then((endpoint) => this._endpoint = endpoint, (error) => this.#setClosed(error));
}
}
/** Get the protocol version supported by the server. */
async getVersion() {
if (this._endpoint !== undefined) {
return this._endpoint.version;
}
return (await this._endpointPromise).version;
}
// Make sure that the negotiated version is at least `minVersion`.
/** @private */
_ensureVersion(minVersion, feature) {
if (minVersion <= fallbackEndpoint.version) {
return;
}
else if (this._endpoint === undefined) {
throw new errors_js_1.ProtocolVersionError(`${feature} is supported only on protocol version ${minVersion} and higher, ` +
"but the version supported by the HTTP server is not yet known. " +
"Use Client.getVersion() to wait until the version is available.");
}
else if (this._endpoint.version < minVersion) {
throw new errors_js_1.ProtocolVersionError(`${feature} is supported only on protocol version ${minVersion} and higher, ` +
`but the HTTP server only supports version ${this._endpoint.version}.`);
}
}
/** Open a {@link HttpStream}, a stream for executing SQL statements. */
openStream() {
if (this.#closed !== undefined) {
throw new errors_js_1.ClosedError("Client is closed", this.#closed);
}
const stream = new stream_js_1.HttpStream(this, this.#url, this.#jwt, this.#fetch, this.#remoteEncryptionKey);
this.#streams.add(stream);
return stream;
}
/** @private */
_streamClosed(stream) {
this.#streams.delete(stream);
}
/** Close the client and all its streams. */
close() {
this.#setClosed(new errors_js_1.ClientError("Client was manually closed"));
}
/** True if the client is closed. */
get closed() {
return this.#closed !== undefined;
}
#setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
for (const stream of Array.from(this.#streams)) {
stream._setClosed(new errors_js_1.ClosedError("Client was closed", error));
}
}
}
exports.HttpClient = HttpClient;
async function findEndpoint(customFetch, clientUrl) {
const fetch = customFetch;
for (const endpoint of exports.checkEndpoints) {
const url = new URL(endpoint.versionPath, clientUrl);
const request = new Request(url.toString(), { method: "GET" });
const response = await fetch(request);
await response.arrayBuffer();
if (response.ok) {
return endpoint;
}
}
return fallbackEndpoint;
}
|