1 line
35 KiB
JSON
1 line
35 KiB
JSON
|
{"ast":null,"code":"import * as hrana from \"@libsql/hrana-client\";\nimport { LibsqlError } from \"@libsql/core/api\";\nimport { expandConfig } from \"@libsql/core/config\";\nimport { HranaTransaction, executeHranaBatch, stmtToHrana, resultSetFromHrana, mapHranaError } from \"./hrana.js\";\nimport { SqlCache } from \"./sql_cache.js\";\nimport { encodeBaseUrl } from \"@libsql/core/uri\";\nimport { supportedUrlLink } from \"@libsql/core/util\";\nimport promiseLimit from \"promise-limit\";\nexport * from \"@libsql/core/api\";\nexport function createClient(config) {\n return _createClient(expandConfig(config, false));\n}\n/** @private */\nexport function _createClient(config) {\n if (config.scheme !== \"wss\" && config.scheme !== \"ws\") {\n throw new LibsqlError('The WebSocket client supports only \"libsql:\", \"wss:\" and \"ws:\" URLs, ' + `got ${JSON.stringify(config.scheme + \":\")}. For more information, please read ${supportedUrlLink}`, \"URL_SCHEME_NOT_SUPPORTED\");\n }\n if (config.encryptionKey !== undefined) {\n throw new LibsqlError(\"Encryption key is not supported by the remote client.\", \"ENCRYPTION_KEY_NOT_SUPPORTED\");\n }\n if (config.scheme === \"ws\" && config.tls) {\n throw new LibsqlError(`A \"ws:\" URL cannot opt into TLS by using ?tls=1`, \"URL_INVALID\");\n } else if (config.scheme === \"wss\" && !config.tls) {\n throw new LibsqlError(`A \"wss:\" URL cannot opt out of TLS by using ?tls=0`, \"URL_INVALID\");\n }\n const url = encodeBaseUrl(config.scheme, config.authority, config.path);\n let client;\n try {\n client = hrana.openWs(url, config.authToken);\n } catch (e) {\n if (e instanceof hrana.WebSocketUnsupportedError) {\n const suggestedScheme = config.scheme === \"wss\" ? \"https\" : \"http\";\n const suggestedUrl = encodeBaseUrl(suggestedScheme, config.authority, config.path);\n throw new LibsqlError(\"This environment does not support WebSockets, please switch to the HTTP client by using \" + `a \"${suggestedScheme}:\" URL (${JSON.stringify(suggestedUrl)}). ` + `For more information, please read ${supportedUrlLink}`, \"WEBSOCKETS_NOT_SUPPORTED\");\n }\n throw mapHranaError(e);\n }\n return new WsClient(client, url, config.authToken, config.intMode, config.concurrency);\n}\nconst maxConnAgeMillis = 60 * 1000;\nconst sqlCacheCapacity = 100;\nexport class WsClient {\n #url;\n #authToken;\n #intMode;\n // State of the current connection. The `hrana.WsClient` inside may be closed at any moment due to an\n // asynchronous error.\n #connState;\n // If defined, this is a connection that will be used in the future, once it is ready.\n #futureConnState;\n closed;\n protocol;\n #isSchemaDatabase;\n #promiseLimitFunction;\n /** @private */\n constructor(client, url, authToken, intMode, concurrency) {\n this.#url = url;\n this.#authToken = authToken;\n this.#intMode = intMode;\n this.#connState = this.#openConn(client);\n this.#futureConnState = undefined;\n this.closed = false;\n this.protocol = \"ws\";\n this.#promiseLimitFunction = promiseLimit(concurrency);\n }\n async limit(fn) {\n return this.#promiseLimitFunction(fn);\n }\n async execute(stmtOrSql, args) {\n let stmt;\n if (typeof stmtOrSql === \"string\") {\n stmt = {\n sql: stmtOrSql,\n args: args || []\n };\n } else {\n stmt = stmtOrSql;\n }\n return this.limit(async () => {\n const streamState = await this.#openStream();\n try {\n const hranaStmt = stmtToHrana(stmt);\n // Schedule all operations synchronously, so they will be pipelined and executed in a single\n // network roundtrip.\n streamState.conn.sqlCache.apply([hranaStmt]);\n const hranaRowsPromise = streamState.stream.query(hranaStmt);\n streamState.stream.closeGracefully();\n const hranaRowsResult = await hranaRowsPromise;\n return resultSetFromHrana(hranaRowsResult);\n } catch (e) {\n throw mapHranaError(e);\n } finally {\n this._closeStream(streamState);\n
|