Initial commit: New MoreminiMore website with fresh design

This commit is contained in:
MoreminiMore
2026-04-22 01:59:05 +07:00
commit 76409638cc
14010 changed files with 2052041 additions and 0 deletions

126
node_modules/@libsql/client/README.md generated vendored Normal file
View File

@@ -0,0 +1,126 @@
<p align="center">
<a href="https://tur.so/turso-ts">
<picture>
<img src="/.github/cover.png" alt="libSQL TypeScript" />
</picture>
</a>
<h1 align="center">libSQL TypeScript</h1>
</p>
<p align="center">
Databases for all TypeScript and JS multi-tenant apps.
</p>
<p align="center">
<a href="https://tur.so/turso-ts"><strong>Turso</strong></a> ·
<a href="https://docs.turso.tech"><strong>Docs</strong></a> ·
<a href="https://docs.turso.tech/sdk/ts/quickstart"><strong>Quickstart</strong></a> ·
<a href="https://docs.turso.tech/sdk/ts/reference"><strong>SDK Reference</strong></a> ·
<a href="https://turso.tech/blog"><strong>Blog &amp; Tutorials</strong></a>
</p>
<p align="center">
<a href="LICENSE">
<picture>
<img src="https://img.shields.io/github/license/tursodatabase/libsql-client-ts?color=0F624B" alt="MIT License" />
</picture>
</a>
<a href="https://tur.so/discord-ts">
<picture>
<img src="https://img.shields.io/discord/933071162680958986?color=0F624B" alt="Discord" />
</picture>
</a>
<a href="#contributors">
<picture>
<img src="https://img.shields.io/github/contributors/tursodatabase/libsql-client-ts?color=0F624B" alt="Contributors" />
</picture>
</a>
<a href="https://www.npmjs.com/package/@libsql/client">
<picture>
<img src="https://img.shields.io/npm/dw/%40libsql%2Fclient?color=0F624B" alt="Weekly downloads" />
</picture>
</a>
<a href="/examples">
<picture>
<img src="https://img.shields.io/badge/browse-examples-0F624B" alt="Examples" />
</picture>
</a>
</p>
## Features
- 🔌 Works offline with [Embedded Replicas](https://docs.turso.tech/features/embedded-replicas/introduction)
- 🌎 Works with remote Turso databases
- ✨ Works with Turso [AI & Vector Search](https://docs.turso.tech/features/ai-and-embeddings)
- 🔐 Supports [encryption at rest](https://docs.turso.tech/libsql#encryption-at-rest)
## Install
```bash
npm install @libsql/client
```
## Quickstart
The example below uses Embedded Replicas and syncs every minute from Turso.
```ts
import { createClient } from "@libsql/client";
export const turso = createClient({
url: "file:local.db",
syncUrl: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
syncInterval: 60000,
});
await turso.batch(
[
"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)",
{
sql: "INSERT INTO users(name) VALUES (?)",
args: ["Iku"],
},
],
"write",
);
await turso.execute({
sql: "SELECT * FROM users WHERE id = ?",
args: [1],
});
```
## Examples
| Example | Description |
| ------------------------------------- | --------------------------------------------------------------------------------------- |
| [local](examples/local) | Uses libsql with a local SQLite file. Creates database, inserts data, and queries. |
| [remote](examples/remote) | Connects to a remote database. Requires environment variables for URL and auth token. |
| [sync](examples/sync) | Demonstrates synchronization between local and remote databases. |
| [batch](examples/batch) | Executes multiple SQL statements in a single batch operation. |
| [transactions](examples/transactions) | Shows transaction usage: starting, performing operations, and committing/rolling back. |
| [memory](examples/memory) | Uses an in-memory SQLite database for temporary storage or fast access. |
| [vector](examples/vector) | Works with vector embeddings, storing and querying for similarity search. |
| [encryption](examples/encryption) | Creates and uses an encrypted SQLite database, demonstrating setup and data operations. |
| [ollama](examples/ollama) | Similarity search with Ollama and Mistral. |
## Documentation
Visit our [official documentation](https://docs.turso.tech/sdk/ts).
## Support
Join us [on Discord](https://tur.so/discord-ts) to get help using this SDK. Report security issues [via email](mailto:security@turso.tech).
## Contributors
See the [contributing guide](CONTRIBUTING.md) to learn how to get involved.
![Contributors](https://contrib.nn.ci/api?repo=tursodatabase/libsql-client-ts)
<a href="https://github.com/tursodatabase/libsql-client-ts/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22">
<picture>
<img src="https://img.shields.io/github/issues-search/tursodatabase/libsql-client-ts?label=good%20first%20issue&query=label%3A%22good%20first%20issue%22%20&color=0F624B" alt="good first issue" />
</picture>
</a>

341
node_modules/@libsql/client/lib-cjs/hrana.js generated vendored Normal file
View File

@@ -0,0 +1,341 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapHranaError = exports.resultSetFromHrana = exports.stmtToHrana = exports.executeHranaBatch = exports.HranaTransaction = void 0;
const hrana = __importStar(require("@libsql/hrana-client"));
const api_1 = require("@libsql/core/api");
const util_1 = require("@libsql/core/util");
class HranaTransaction {
#mode;
#version;
// Promise that is resolved when the BEGIN statement completes, or `undefined` if we haven't executed the
// BEGIN statement yet.
#started;
/** @private */
constructor(mode, version) {
this.#mode = mode;
this.#version = version;
this.#started = undefined;
}
execute(stmt) {
return this.batch([stmt]).then((results) => results[0]);
}
async batch(stmts) {
const stream = this._getStream();
if (stream.closed) {
throw new api_1.LibsqlError("Cannot execute statements because the transaction is closed", "TRANSACTION_CLOSED");
}
try {
const hranaStmts = stmts.map(stmtToHrana);
let rowsPromises;
if (this.#started === undefined) {
// The transaction hasn't started yet, so we need to send the BEGIN statement in a batch with
// `hranaStmts`.
this._getSqlCache().apply(hranaStmts);
const batch = stream.batch(this.#version >= 3);
const beginStep = batch.step();
const beginPromise = beginStep.run((0, util_1.transactionModeToBegin)(this.#mode));
// Execute the `hranaStmts` only if the BEGIN succeeded, to make sure that we don't execute it
// outside of a transaction.
let lastStep = beginStep;
rowsPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch
.step()
.condition(hrana.BatchCond.ok(lastStep));
if (this.#version >= 3) {
// If the Hrana version supports it, make sure that we are still in a transaction
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const rowsPromise = stmtStep.query(hranaStmt);
rowsPromise.catch(() => undefined); // silence Node warning
lastStep = stmtStep;
return rowsPromise;
});
// `this.#started` is resolved successfully only if the batch and the BEGIN statement inside
// of the batch are both successful.
this.#started = batch
.execute()
.then(() => beginPromise)
.then(() => undefined);
try {
await this.#started;
}
catch (e) {
// If the BEGIN failed, the transaction is unusable and we must close it. However, if the
// BEGIN suceeds and `hranaStmts` fail, the transaction is _not_ closed.
this.close();
throw e;
}
}
else {
if (this.#version < 3) {
// The transaction has started, so we must wait until the BEGIN statement completed to make
// sure that we don't execute `hranaStmts` outside of a transaction.
await this.#started;
}
else {
// The transaction has started, but we will use `hrana.BatchCond.isAutocommit()` to make
// sure that we don't execute `hranaStmts` outside of a transaction, so we don't have to
// wait for `this.#started`
}
this._getSqlCache().apply(hranaStmts);
const batch = stream.batch(this.#version >= 3);
let lastStep = undefined;
rowsPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch.step();
if (lastStep !== undefined) {
stmtStep.condition(hrana.BatchCond.ok(lastStep));
}
if (this.#version >= 3) {
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const rowsPromise = stmtStep.query(hranaStmt);
rowsPromise.catch(() => undefined); // silence Node warning
lastStep = stmtStep;
return rowsPromise;
});
await batch.execute();
}
const resultSets = [];
for (const rowsPromise of rowsPromises) {
const rows = await rowsPromise;
if (rows === undefined) {
throw new api_1.LibsqlError("Statement in a transaction was not executed, " +
"probably because the transaction has been rolled back", "TRANSACTION_CLOSED");
}
resultSets.push(resultSetFromHrana(rows));
}
return resultSets;
}
catch (e) {
throw mapHranaError(e);
}
}
async executeMultiple(sql) {
const stream = this._getStream();
if (stream.closed) {
throw new api_1.LibsqlError("Cannot execute statements because the transaction is closed", "TRANSACTION_CLOSED");
}
try {
if (this.#started === undefined) {
// If the transaction hasn't started yet, start it now
this.#started = stream
.run((0, util_1.transactionModeToBegin)(this.#mode))
.then(() => undefined);
try {
await this.#started;
}
catch (e) {
this.close();
throw e;
}
}
else {
// Wait until the transaction has started
await this.#started;
}
await stream.sequence(sql);
}
catch (e) {
throw mapHranaError(e);
}
}
async rollback() {
try {
const stream = this._getStream();
if (stream.closed) {
return;
}
if (this.#started !== undefined) {
// We don't have to wait for the BEGIN statement to complete. If the BEGIN fails, we will
// execute a ROLLBACK outside of an active transaction, which should be harmless.
}
else {
// We did nothing in the transaction, so there is nothing to rollback.
return;
}
// Pipeline the ROLLBACK statement and the stream close.
const promise = stream.run("ROLLBACK").catch((e) => {
throw mapHranaError(e);
});
stream.closeGracefully();
await promise;
}
catch (e) {
throw mapHranaError(e);
}
finally {
// `this.close()` may close the `hrana.Client`, which aborts all pending stream requests, so we
// must call it _after_ we receive the ROLLBACK response.
// Also note that the current stream should already be closed, but we need to call `this.close()`
// anyway, because it may need to do more cleanup.
this.close();
}
}
async commit() {
// (this method is analogous to `rollback()`)
try {
const stream = this._getStream();
if (stream.closed) {
throw new api_1.LibsqlError("Cannot commit the transaction because it is already closed", "TRANSACTION_CLOSED");
}
if (this.#started !== undefined) {
// Make sure to execute the COMMIT only if the BEGIN was successful.
await this.#started;
}
else {
return;
}
const promise = stream.run("COMMIT").catch((e) => {
throw mapHranaError(e);
});
stream.closeGracefully();
await promise;
}
catch (e) {
throw mapHranaError(e);
}
finally {
this.close();
}
}
}
exports.HranaTransaction = HranaTransaction;
async function executeHranaBatch(mode, version, batch, hranaStmts, disableForeignKeys = false) {
if (disableForeignKeys) {
batch.step().run("PRAGMA foreign_keys=off");
}
const beginStep = batch.step();
const beginPromise = beginStep.run((0, util_1.transactionModeToBegin)(mode));
let lastStep = beginStep;
const stmtPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch.step().condition(hrana.BatchCond.ok(lastStep));
if (version >= 3) {
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const stmtPromise = stmtStep.query(hranaStmt);
lastStep = stmtStep;
return stmtPromise;
});
const commitStep = batch.step().condition(hrana.BatchCond.ok(lastStep));
if (version >= 3) {
commitStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const commitPromise = commitStep.run("COMMIT");
const rollbackStep = batch
.step()
.condition(hrana.BatchCond.not(hrana.BatchCond.ok(commitStep)));
rollbackStep.run("ROLLBACK").catch((_) => undefined);
if (disableForeignKeys) {
batch.step().run("PRAGMA foreign_keys=on");
}
await batch.execute();
const resultSets = [];
await beginPromise;
for (const stmtPromise of stmtPromises) {
const hranaRows = await stmtPromise;
if (hranaRows === undefined) {
throw new api_1.LibsqlError("Statement in a batch was not executed, probably because the transaction has been rolled back", "TRANSACTION_CLOSED");
}
resultSets.push(resultSetFromHrana(hranaRows));
}
await commitPromise;
return resultSets;
}
exports.executeHranaBatch = executeHranaBatch;
function stmtToHrana(stmt) {
let sql;
let args;
if (Array.isArray(stmt)) {
[sql, args] = stmt;
}
else if (typeof stmt === "string") {
sql = stmt;
}
else {
sql = stmt.sql;
args = stmt.args;
}
const hranaStmt = new hrana.Stmt(sql);
if (args) {
if (Array.isArray(args)) {
hranaStmt.bindIndexes(args);
}
else {
for (const [key, value] of Object.entries(args)) {
hranaStmt.bindName(key, value);
}
}
}
return hranaStmt;
}
exports.stmtToHrana = stmtToHrana;
function resultSetFromHrana(hranaRows) {
const columns = hranaRows.columnNames.map((c) => c ?? "");
const columnTypes = hranaRows.columnDecltypes.map((c) => c ?? "");
const rows = hranaRows.rows;
const rowsAffected = hranaRows.affectedRowCount;
const lastInsertRowid = hranaRows.lastInsertRowid !== undefined
? hranaRows.lastInsertRowid
: undefined;
return new util_1.ResultSetImpl(columns, columnTypes, rows, rowsAffected, lastInsertRowid);
}
exports.resultSetFromHrana = resultSetFromHrana;
function mapHranaError(e) {
if (e instanceof hrana.ClientError) {
const code = mapHranaErrorCode(e);
return new api_1.LibsqlError(e.message, code, undefined, e);
}
return e;
}
exports.mapHranaError = mapHranaError;
function mapHranaErrorCode(e) {
if (e instanceof hrana.ResponseError && e.code !== undefined) {
return e.code;
}
else if (e instanceof hrana.ProtoError) {
return "HRANA_PROTO_ERROR";
}
else if (e instanceof hrana.ClosedError) {
return e.cause instanceof hrana.ClientError
? mapHranaErrorCode(e.cause)
: "HRANA_CLOSED_ERROR";
}
else if (e instanceof hrana.WebSocketError) {
return "HRANA_WEBSOCKET_ERROR";
}
else if (e instanceof hrana.HttpServerError) {
return "SERVER_ERROR";
}
else if (e instanceof hrana.ProtocolVersionError) {
return "PROTOCOL_VERSION_ERROR";
}
else if (e instanceof hrana.InternalError) {
return "INTERNAL_ERROR";
}
else {
return "UNKNOWN";
}
}

266
node_modules/@libsql/client/lib-cjs/http.js generated vendored Normal file
View File

@@ -0,0 +1,266 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpTransaction = exports.HttpClient = exports._createClient = exports.createClient = void 0;
const hrana = __importStar(require("@libsql/hrana-client"));
const api_1 = require("@libsql/core/api");
const config_1 = require("@libsql/core/config");
const hrana_js_1 = require("./hrana.js");
const sql_cache_js_1 = require("./sql_cache.js");
const uri_1 = require("@libsql/core/uri");
const util_1 = require("@libsql/core/util");
const promise_limit_1 = __importDefault(require("promise-limit"));
__exportStar(require("@libsql/core/api"), exports);
function createClient(config) {
return _createClient((0, config_1.expandConfig)(config, true));
}
exports.createClient = createClient;
/** @private */
function _createClient(config) {
if (config.scheme !== "https" && config.scheme !== "http") {
throw new api_1.LibsqlError('The HTTP client supports only "libsql:", "https:" and "http:" URLs, ' +
`got ${JSON.stringify(config.scheme + ":")}. For more information, please read ${util_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
if (config.encryptionKey !== undefined) {
throw new api_1.LibsqlError("Encryption key is not supported by the remote client.", "ENCRYPTION_KEY_NOT_SUPPORTED");
}
if (config.scheme === "http" && config.tls) {
throw new api_1.LibsqlError(`A "http:" URL cannot opt into TLS by using ?tls=1`, "URL_INVALID");
}
else if (config.scheme === "https" && !config.tls) {
throw new api_1.LibsqlError(`A "https:" URL cannot opt out of TLS by using ?tls=0`, "URL_INVALID");
}
const url = (0, uri_1.encodeBaseUrl)(config.scheme, config.authority, config.path);
return new HttpClient(url, config.authToken, config.intMode, config.fetch, config.concurrency);
}
exports._createClient = _createClient;
const sqlCacheCapacity = 30;
class HttpClient {
#client;
protocol;
#url;
#intMode;
#customFetch;
#concurrency;
#authToken;
#promiseLimitFunction;
/** @private */
constructor(url, authToken, intMode, customFetch, concurrency) {
this.#url = url;
this.#authToken = authToken;
this.#intMode = intMode;
this.#customFetch = customFetch;
this.#concurrency = concurrency;
this.#client = hrana.openHttp(this.#url, this.#authToken, this.#customFetch);
this.#client.intMode = this.#intMode;
this.protocol = "http";
this.#promiseLimitFunction = (0, promise_limit_1.default)(this.#concurrency);
}
async limit(fn) {
return this.#promiseLimitFunction(fn);
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
return this.limit(async () => {
try {
const hranaStmt = (0, hrana_js_1.stmtToHrana)(stmt);
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the statement and
// close the stream in a single HTTP request.
let rowsPromise;
const stream = this.#client.openStream();
try {
rowsPromise = stream.query(hranaStmt);
}
finally {
stream.closeGracefully();
}
const rowsResult = await rowsPromise;
return (0, hrana_js_1.resultSetFromHrana)(rowsResult);
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
async batch(stmts, mode = "deferred") {
return this.limit(async () => {
try {
const normalizedStmts = stmts.map((stmt) => {
if (Array.isArray(stmt)) {
return {
sql: stmt[0],
args: stmt[1] || [],
};
}
return stmt;
});
const hranaStmts = normalizedStmts.map(hrana_js_1.stmtToHrana);
const version = await this.#client.getVersion();
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the batch and
// close the stream in a single HTTP request.
let resultsPromise;
const stream = this.#client.openStream();
try {
// It makes sense to use a SQL cache even for a single batch, because it may contain the same
// statement repeated multiple times.
const sqlCache = new sql_cache_js_1.SqlCache(stream, sqlCacheCapacity);
sqlCache.apply(hranaStmts);
// TODO: we do not use a cursor here, because it would cause three roundtrips:
// 1. pipeline request to store SQL texts
// 2. cursor request
// 3. pipeline request to close the stream
const batch = stream.batch(false);
resultsPromise = (0, hrana_js_1.executeHranaBatch)(mode, version, batch, hranaStmts);
}
finally {
stream.closeGracefully();
}
const results = await resultsPromise;
return results;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
async migrate(stmts) {
return this.limit(async () => {
try {
const hranaStmts = stmts.map(hrana_js_1.stmtToHrana);
const version = await this.#client.getVersion();
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the batch and
// close the stream in a single HTTP request.
let resultsPromise;
const stream = this.#client.openStream();
try {
const batch = stream.batch(false);
resultsPromise = (0, hrana_js_1.executeHranaBatch)("deferred", version, batch, hranaStmts, true);
}
finally {
stream.closeGracefully();
}
const results = await resultsPromise;
return results;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
async transaction(mode = "write") {
return this.limit(async () => {
try {
const version = await this.#client.getVersion();
return new HttpTransaction(this.#client.openStream(), mode, version);
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
async executeMultiple(sql) {
return this.limit(async () => {
try {
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the sequence and
// close the stream in a single HTTP request.
let promise;
const stream = this.#client.openStream();
try {
promise = stream.sequence(sql);
}
finally {
stream.closeGracefully();
}
await promise;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
sync() {
throw new api_1.LibsqlError("sync not supported in http mode", "SYNC_NOT_SUPPORTED");
}
close() {
this.#client.close();
}
async reconnect() {
try {
if (!this.closed) {
// Abort in-flight ops and free resources
this.#client.close();
}
}
finally {
// Recreate the underlying hrana client
this.#client = hrana.openHttp(this.#url, this.#authToken, this.#customFetch);
this.#client.intMode = this.#intMode;
}
}
get closed() {
return this.#client.closed;
}
}
exports.HttpClient = HttpClient;
class HttpTransaction extends hrana_js_1.HranaTransaction {
#stream;
#sqlCache;
/** @private */
constructor(stream, mode, version) {
super(mode, version);
this.#stream = stream;
this.#sqlCache = new sql_cache_js_1.SqlCache(stream, sqlCacheCapacity);
}
/** @private */
_getStream() {
return this.#stream;
}
/** @private */
_getSqlCache() {
return this.#sqlCache;
}
close() {
this.#stream.close();
}
get closed() {
return this.#stream.closed;
}
}
exports.HttpTransaction = HttpTransaction;

41
node_modules/@libsql/client/lib-cjs/node.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createClient = void 0;
const config_1 = require("@libsql/core/config");
const sqlite3_js_1 = require("./sqlite3.js");
const ws_js_1 = require("./ws.js");
const http_js_1 = require("./http.js");
__exportStar(require("@libsql/core/api"), exports);
/** Creates a {@link Client} object.
*
* You must pass at least an `url` in the {@link Config} object.
*/
function createClient(config) {
return _createClient((0, config_1.expandConfig)(config, true));
}
exports.createClient = createClient;
function _createClient(config) {
if (config.scheme === "wss" || config.scheme === "ws") {
return (0, ws_js_1._createClient)(config);
}
else if (config.scheme === "https" || config.scheme === "http") {
return (0, http_js_1._createClient)(config);
}
else {
return (0, sqlite3_js_1._createClient)(config);
}
}

3
node_modules/@libsql/client/lib-cjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

91
node_modules/@libsql/client/lib-cjs/sql_cache.js generated vendored Normal file
View File

@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqlCache = void 0;
class SqlCache {
#owner;
#sqls;
capacity;
constructor(owner, capacity) {
this.#owner = owner;
this.#sqls = new Lru();
this.capacity = capacity;
}
// Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this
// function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,
// but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the
// server).
//
// In practice, this means that after calling this function, you can use the statements only up to the
// first `await`, because concurrent code may also use the cache and invalidate those statements.
apply(hranaStmts) {
if (this.capacity <= 0) {
return;
}
const usedSqlObjs = new Set();
for (const hranaStmt of hranaStmts) {
if (typeof hranaStmt.sql !== "string") {
continue;
}
const sqlText = hranaStmt.sql;
// Stored SQL cannot exceed 5kb.
// https://github.com/tursodatabase/libsql/blob/e9d637e051685f92b0da43849507b5ef4232fbeb/libsql-server/src/hrana/http/request.rs#L10
if (sqlText.length >= 5000) {
continue;
}
let sqlObj = this.#sqls.get(sqlText);
if (sqlObj === undefined) {
while (this.#sqls.size + 1 > this.capacity) {
const [evictSqlText, evictSqlObj] = this.#sqls.peekLru();
if (usedSqlObjs.has(evictSqlObj)) {
// The SQL object that we are trying to evict is already in use in this batch, so we
// must not evict and close it.
break;
}
evictSqlObj.close();
this.#sqls.delete(evictSqlText);
}
if (this.#sqls.size + 1 <= this.capacity) {
sqlObj = this.#owner.storeSql(sqlText);
this.#sqls.set(sqlText, sqlObj);
}
}
if (sqlObj !== undefined) {
hranaStmt.sql = sqlObj;
usedSqlObjs.add(sqlObj);
}
}
}
}
exports.SqlCache = SqlCache;
class Lru {
// This maps keys to the cache values. The entries are ordered by their last use (entires that were used
// most recently are at the end).
#cache;
constructor() {
this.#cache = new Map();
}
get(key) {
const value = this.#cache.get(key);
if (value !== undefined) {
// move the entry to the back of the Map
this.#cache.delete(key);
this.#cache.set(key, value);
}
return value;
}
set(key, value) {
this.#cache.set(key, value);
}
peekLru() {
for (const entry of this.#cache.entries()) {
return entry;
}
return undefined;
}
delete(key) {
this.#cache.delete(key);
}
get size() {
return this.#cache.size;
}
}

419
node_modules/@libsql/client/lib-cjs/sqlite3.js generated vendored Normal file
View File

@@ -0,0 +1,419 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Sqlite3Transaction = exports.Sqlite3Client = exports._createClient = exports.createClient = void 0;
const libsql_1 = __importDefault(require("libsql"));
const node_buffer_1 = require("node:buffer");
const api_1 = require("@libsql/core/api");
const config_1 = require("@libsql/core/config");
const util_1 = require("@libsql/core/util");
__exportStar(require("@libsql/core/api"), exports);
function createClient(config) {
return _createClient((0, config_1.expandConfig)(config, true));
}
exports.createClient = createClient;
/** @private */
function _createClient(config) {
if (config.scheme !== "file") {
throw new api_1.LibsqlError(`URL scheme ${JSON.stringify(config.scheme + ":")} is not supported by the local sqlite3 client. ` +
`For more information, please read ${util_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
const authority = config.authority;
if (authority !== undefined) {
const host = authority.host.toLowerCase();
if (host !== "" && host !== "localhost") {
throw new api_1.LibsqlError(`Invalid host in file URL: ${JSON.stringify(authority.host)}. ` +
'A "file:" URL with an absolute path should start with one slash ("file:/absolute/path.db") ' +
'or with three slashes ("file:///absolute/path.db"). ' +
`For more information, please read ${util_1.supportedUrlLink}`, "URL_INVALID");
}
if (authority.port !== undefined) {
throw new api_1.LibsqlError("File URL cannot have a port", "URL_INVALID");
}
if (authority.userinfo !== undefined) {
throw new api_1.LibsqlError("File URL cannot have username and password", "URL_INVALID");
}
}
let isInMemory = (0, config_1.isInMemoryConfig)(config);
if (isInMemory && config.syncUrl) {
throw new api_1.LibsqlError(`Embedded replica must use file for local db but URI with in-memory mode were provided instead: ${config.path}`, "URL_INVALID");
}
let path = config.path;
if (isInMemory) {
// note: we should prepend file scheme in order for SQLite3 to recognize :memory: connection query parameters
path = `${config.scheme}:${config.path}`;
}
const options = {
authToken: config.authToken,
encryptionKey: config.encryptionKey,
syncUrl: config.syncUrl,
syncPeriod: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
};
const db = new libsql_1.default(path, options);
executeStmt(db, "SELECT 1 AS checkThatTheDatabaseCanBeOpened", config.intMode);
return new Sqlite3Client(path, options, db, config.intMode);
}
exports._createClient = _createClient;
class Sqlite3Client {
#path;
#options;
#db;
#intMode;
closed;
protocol;
/** @private */
constructor(path, options, db, intMode) {
this.#path = path;
this.#options = options;
this.#db = db;
this.#intMode = intMode;
this.closed = false;
this.protocol = "file";
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
this.#checkNotClosed();
return executeStmt(this.#getDb(), stmt, this.#intMode);
}
async batch(stmts, mode = "deferred") {
this.#checkNotClosed();
const db = this.#getDb();
try {
executeStmt(db, (0, util_1.transactionModeToBegin)(mode), this.#intMode);
const resultSets = stmts.map((stmt) => {
if (!db.inTransaction) {
throw new api_1.LibsqlError("The transaction has been rolled back", "TRANSACTION_CLOSED");
}
const normalizedStmt = Array.isArray(stmt)
? { sql: stmt[0], args: stmt[1] || [] }
: stmt;
return executeStmt(db, normalizedStmt, this.#intMode);
});
executeStmt(db, "COMMIT", this.#intMode);
return resultSets;
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
}
}
async migrate(stmts) {
this.#checkNotClosed();
const db = this.#getDb();
try {
executeStmt(db, "PRAGMA foreign_keys=off", this.#intMode);
executeStmt(db, (0, util_1.transactionModeToBegin)("deferred"), this.#intMode);
const resultSets = stmts.map((stmt) => {
if (!db.inTransaction) {
throw new api_1.LibsqlError("The transaction has been rolled back", "TRANSACTION_CLOSED");
}
return executeStmt(db, stmt, this.#intMode);
});
executeStmt(db, "COMMIT", this.#intMode);
return resultSets;
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
executeStmt(db, "PRAGMA foreign_keys=on", this.#intMode);
}
}
async transaction(mode = "write") {
const db = this.#getDb();
executeStmt(db, (0, util_1.transactionModeToBegin)(mode), this.#intMode);
this.#db = null; // A new connection will be lazily created on next use
return new Sqlite3Transaction(db, this.#intMode);
}
async executeMultiple(sql) {
this.#checkNotClosed();
const db = this.#getDb();
try {
return executeMultiple(db, sql);
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
}
}
async sync() {
this.#checkNotClosed();
const rep = await this.#getDb().sync();
return {
frames_synced: rep.frames_synced,
frame_no: rep.frame_no,
};
}
async reconnect() {
try {
if (!this.closed && this.#db !== null) {
this.#db.close();
}
}
finally {
this.#db = new libsql_1.default(this.#path, this.#options);
this.closed = false;
}
}
close() {
this.closed = true;
if (this.#db !== null) {
this.#db.close();
this.#db = null;
}
}
#checkNotClosed() {
if (this.closed) {
throw new api_1.LibsqlError("The client is closed", "CLIENT_CLOSED");
}
}
// Lazily creates the database connection and returns it
#getDb() {
if (this.#db === null) {
this.#db = new libsql_1.default(this.#path, this.#options);
}
return this.#db;
}
}
exports.Sqlite3Client = Sqlite3Client;
class Sqlite3Transaction {
#database;
#intMode;
/** @private */
constructor(database, intMode) {
this.#database = database;
this.#intMode = intMode;
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
this.#checkNotClosed();
return executeStmt(this.#database, stmt, this.#intMode);
}
async batch(stmts) {
return stmts.map((stmt) => {
this.#checkNotClosed();
const normalizedStmt = Array.isArray(stmt)
? { sql: stmt[0], args: stmt[1] || [] }
: stmt;
return executeStmt(this.#database, normalizedStmt, this.#intMode);
});
}
async executeMultiple(sql) {
this.#checkNotClosed();
return executeMultiple(this.#database, sql);
}
async rollback() {
if (!this.#database.open) {
return;
}
this.#checkNotClosed();
executeStmt(this.#database, "ROLLBACK", this.#intMode);
}
async commit() {
this.#checkNotClosed();
executeStmt(this.#database, "COMMIT", this.#intMode);
}
close() {
if (this.#database.inTransaction) {
executeStmt(this.#database, "ROLLBACK", this.#intMode);
}
}
get closed() {
return !this.#database.inTransaction;
}
#checkNotClosed() {
if (this.closed) {
throw new api_1.LibsqlError("The transaction is closed", "TRANSACTION_CLOSED");
}
}
}
exports.Sqlite3Transaction = Sqlite3Transaction;
function executeStmt(db, stmt, intMode) {
let sql;
let args;
if (typeof stmt === "string") {
sql = stmt;
args = [];
}
else {
sql = stmt.sql;
if (Array.isArray(stmt.args)) {
args = stmt.args.map((value) => valueToSql(value, intMode));
}
else {
args = {};
for (const name in stmt.args) {
const argName = name[0] === "@" || name[0] === "$" || name[0] === ":"
? name.substring(1)
: name;
args[argName] = valueToSql(stmt.args[name], intMode);
}
}
}
try {
const sqlStmt = db.prepare(sql);
sqlStmt.safeIntegers(true);
let returnsData = true;
try {
sqlStmt.raw(true);
}
catch {
// raw() throws an exception if the statement does not return data
returnsData = false;
}
if (returnsData) {
const columns = Array.from(sqlStmt.columns().map((col) => col.name));
const columnTypes = Array.from(sqlStmt.columns().map((col) => col.type ?? ""));
const rows = sqlStmt.all(args).map((sqlRow) => {
return rowFromSql(sqlRow, columns, intMode);
});
// TODO: can we get this info from better-sqlite3?
const rowsAffected = 0;
const lastInsertRowid = undefined;
return new util_1.ResultSetImpl(columns, columnTypes, rows, rowsAffected, lastInsertRowid);
}
else {
const info = sqlStmt.run(args);
const rowsAffected = info.changes;
const lastInsertRowid = BigInt(info.lastInsertRowid);
return new util_1.ResultSetImpl([], [], [], rowsAffected, lastInsertRowid);
}
}
catch (e) {
throw mapSqliteError(e);
}
}
function rowFromSql(sqlRow, columns, intMode) {
const row = {};
// make sure that the "length" property is not enumerable
Object.defineProperty(row, "length", { value: sqlRow.length });
for (let i = 0; i < sqlRow.length; ++i) {
const value = valueFromSql(sqlRow[i], intMode);
Object.defineProperty(row, i, { value });
const column = columns[i];
if (!Object.hasOwn(row, column)) {
Object.defineProperty(row, column, {
value,
enumerable: true,
configurable: true,
writable: true,
});
}
}
return row;
}
function valueFromSql(sqlValue, intMode) {
if (typeof sqlValue === "bigint") {
if (intMode === "number") {
if (sqlValue < minSafeBigint || sqlValue > maxSafeBigint) {
throw new RangeError("Received integer which cannot be safely represented as a JavaScript number");
}
return Number(sqlValue);
}
else if (intMode === "bigint") {
return sqlValue;
}
else if (intMode === "string") {
return "" + sqlValue;
}
else {
throw new Error("Invalid value for IntMode");
}
}
else if (sqlValue instanceof node_buffer_1.Buffer) {
return sqlValue.buffer;
}
return sqlValue;
}
const minSafeBigint = -9007199254740991n;
const maxSafeBigint = 9007199254740991n;
function valueToSql(value, intMode) {
if (typeof value === "number") {
if (!Number.isFinite(value)) {
throw new RangeError("Only finite numbers (not Infinity or NaN) can be passed as arguments");
}
return value;
}
else if (typeof value === "bigint") {
if (value < minInteger || value > maxInteger) {
throw new RangeError("bigint is too large to be represented as a 64-bit integer and passed as argument");
}
return value;
}
else if (typeof value === "boolean") {
switch (intMode) {
case "bigint":
return value ? 1n : 0n;
case "string":
return value ? "1" : "0";
default:
return value ? 1 : 0;
}
}
else if (value instanceof ArrayBuffer) {
return node_buffer_1.Buffer.from(value);
}
else if (value instanceof Date) {
return value.valueOf();
}
else if (value === undefined) {
throw new TypeError("undefined cannot be passed as argument to the database");
}
else {
return value;
}
}
const minInteger = -9223372036854775808n;
const maxInteger = 9223372036854775807n;
function executeMultiple(db, sql) {
try {
db.exec(sql);
}
catch (e) {
throw mapSqliteError(e);
}
}
function mapSqliteError(e) {
if (e instanceof libsql_1.default.SqliteError) {
return new api_1.LibsqlError(e.message, e.code, e.rawCode, e);
}
return e;
}

41
node_modules/@libsql/client/lib-cjs/web.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports._createClient = exports.createClient = void 0;
const api_1 = require("@libsql/core/api");
const config_1 = require("@libsql/core/config");
const util_1 = require("@libsql/core/util");
const ws_js_1 = require("./ws.js");
const http_js_1 = require("./http.js");
__exportStar(require("@libsql/core/api"), exports);
function createClient(config) {
return _createClient((0, config_1.expandConfig)(config, true));
}
exports.createClient = createClient;
/** @private */
function _createClient(config) {
if (config.scheme === "ws" || config.scheme === "wss") {
return (0, ws_js_1._createClient)(config);
}
else if (config.scheme === "http" || config.scheme === "https") {
return (0, http_js_1._createClient)(config);
}
else {
throw new api_1.LibsqlError('The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, ' +
`got ${JSON.stringify(config.scheme + ":")}. For more information, please read ${util_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
}
exports._createClient = _createClient;

395
node_modules/@libsql/client/lib-cjs/ws.js generated vendored Normal file
View File

@@ -0,0 +1,395 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsTransaction = exports.WsClient = exports._createClient = exports.createClient = void 0;
const hrana = __importStar(require("@libsql/hrana-client"));
const api_1 = require("@libsql/core/api");
const config_1 = require("@libsql/core/config");
const hrana_js_1 = require("./hrana.js");
const sql_cache_js_1 = require("./sql_cache.js");
const uri_1 = require("@libsql/core/uri");
const util_1 = require("@libsql/core/util");
const promise_limit_1 = __importDefault(require("promise-limit"));
__exportStar(require("@libsql/core/api"), exports);
function createClient(config) {
return _createClient((0, config_1.expandConfig)(config, false));
}
exports.createClient = createClient;
/** @private */
function _createClient(config) {
if (config.scheme !== "wss" && config.scheme !== "ws") {
throw new api_1.LibsqlError('The WebSocket client supports only "libsql:", "wss:" and "ws:" URLs, ' +
`got ${JSON.stringify(config.scheme + ":")}. For more information, please read ${util_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
if (config.encryptionKey !== undefined) {
throw new api_1.LibsqlError("Encryption key is not supported by the remote client.", "ENCRYPTION_KEY_NOT_SUPPORTED");
}
if (config.scheme === "ws" && config.tls) {
throw new api_1.LibsqlError(`A "ws:" URL cannot opt into TLS by using ?tls=1`, "URL_INVALID");
}
else if (config.scheme === "wss" && !config.tls) {
throw new api_1.LibsqlError(`A "wss:" URL cannot opt out of TLS by using ?tls=0`, "URL_INVALID");
}
const url = (0, uri_1.encodeBaseUrl)(config.scheme, config.authority, config.path);
let client;
try {
client = hrana.openWs(url, config.authToken);
}
catch (e) {
if (e instanceof hrana.WebSocketUnsupportedError) {
const suggestedScheme = config.scheme === "wss" ? "https" : "http";
const suggestedUrl = (0, uri_1.encodeBaseUrl)(suggestedScheme, config.authority, config.path);
throw new api_1.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 ${util_1.supportedUrlLink}`, "WEBSOCKETS_NOT_SUPPORTED");
}
throw (0, hrana_js_1.mapHranaError)(e);
}
return new WsClient(client, url, config.authToken, config.intMode, config.concurrency);
}
exports._createClient = _createClient;
const maxConnAgeMillis = 60 * 1000;
const sqlCacheCapacity = 100;
class WsClient {
#url;
#authToken;
#intMode;
// State of the current connection. The `hrana.WsClient` inside may be closed at any moment due to an
// asynchronous error.
#connState;
// If defined, this is a connection that will be used in the future, once it is ready.
#futureConnState;
closed;
protocol;
#isSchemaDatabase;
#promiseLimitFunction;
/** @private */
constructor(client, url, authToken, intMode, concurrency) {
this.#url = url;
this.#authToken = authToken;
this.#intMode = intMode;
this.#connState = this.#openConn(client);
this.#futureConnState = undefined;
this.closed = false;
this.protocol = "ws";
this.#promiseLimitFunction = (0, promise_limit_1.default)(concurrency);
}
async limit(fn) {
return this.#promiseLimitFunction(fn);
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const hranaStmt = (0, hrana_js_1.stmtToHrana)(stmt);
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
streamState.conn.sqlCache.apply([hranaStmt]);
const hranaRowsPromise = streamState.stream.query(hranaStmt);
streamState.stream.closeGracefully();
const hranaRowsResult = await hranaRowsPromise;
return (0, hrana_js_1.resultSetFromHrana)(hranaRowsResult);
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
finally {
this._closeStream(streamState);
}
});
}
async batch(stmts, mode = "deferred") {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const normalizedStmts = stmts.map((stmt) => {
if (Array.isArray(stmt)) {
return {
sql: stmt[0],
args: stmt[1] || [],
};
}
return stmt;
});
const hranaStmts = normalizedStmts.map(hrana_js_1.stmtToHrana);
const version = await streamState.conn.client.getVersion();
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
streamState.conn.sqlCache.apply(hranaStmts);
const batch = streamState.stream.batch(version >= 3);
const resultsPromise = (0, hrana_js_1.executeHranaBatch)(mode, version, batch, hranaStmts);
const results = await resultsPromise;
return results;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
finally {
this._closeStream(streamState);
}
});
}
async migrate(stmts) {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const hranaStmts = stmts.map(hrana_js_1.stmtToHrana);
const version = await streamState.conn.client.getVersion();
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
const batch = streamState.stream.batch(version >= 3);
const resultsPromise = (0, hrana_js_1.executeHranaBatch)("deferred", version, batch, hranaStmts, true);
const results = await resultsPromise;
return results;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
finally {
this._closeStream(streamState);
}
});
}
async transaction(mode = "write") {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const version = await streamState.conn.client.getVersion();
// the BEGIN statement will be batched with the first statement on the transaction to save a
// network roundtrip
return new WsTransaction(this, streamState, mode, version);
}
catch (e) {
this._closeStream(streamState);
throw (0, hrana_js_1.mapHranaError)(e);
}
});
}
async executeMultiple(sql) {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
const promise = streamState.stream.sequence(sql);
streamState.stream.closeGracefully();
await promise;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
finally {
this._closeStream(streamState);
}
});
}
sync() {
throw new api_1.LibsqlError("sync not supported in ws mode", "SYNC_NOT_SUPPORTED");
}
async #openStream() {
if (this.closed) {
throw new api_1.LibsqlError("The client is closed", "CLIENT_CLOSED");
}
const now = new Date();
const ageMillis = now.valueOf() - this.#connState.openTime.valueOf();
if (ageMillis > maxConnAgeMillis &&
this.#futureConnState === undefined) {
// The existing connection is too old, let's open a new one.
const futureConnState = this.#openConn();
this.#futureConnState = futureConnState;
// However, if we used `futureConnState` immediately, we would introduce additional latency,
// because we would have to wait for the WebSocket handshake to complete, even though we may a
// have perfectly good existing connection in `this.#connState`!
//
// So we wait until the `hrana.Client.getVersion()` operation completes (which happens when the
// WebSocket hanshake completes), and only then we replace `this.#connState` with
// `futureConnState`, which is stored in `this.#futureConnState` in the meantime.
futureConnState.client.getVersion().then((_version) => {
if (this.#connState !== futureConnState) {
// We need to close `this.#connState` before we replace it. However, it is possible
// that `this.#connState` has already been replaced: see the code below.
if (this.#connState.streamStates.size === 0) {
this.#connState.client.close();
}
else {
// If there are existing streams on the connection, we must not close it, because
// these streams would be broken. The last stream to be closed will also close the
// connection in `_closeStream()`.
}
}
this.#connState = futureConnState;
this.#futureConnState = undefined;
}, (_e) => {
// If the new connection could not be established, let's just ignore the error and keep
// using the existing connection.
this.#futureConnState = undefined;
});
}
if (this.#connState.client.closed) {
// An error happened on this connection and it has been closed. Let's try to seamlessly reconnect.
try {
if (this.#futureConnState !== undefined) {
// We are already in the process of opening a new connection, so let's just use it
// immediately.
this.#connState = this.#futureConnState;
}
else {
this.#connState = this.#openConn();
}
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
}
const connState = this.#connState;
try {
// Now we wait for the WebSocket handshake to complete (if it hasn't completed yet). Note that
// this does not increase latency, because any messages that we would send on the WebSocket before
// the handshake would be queued until the handshake is completed anyway.
if (connState.useSqlCache === undefined) {
connState.useSqlCache =
(await connState.client.getVersion()) >= 2;
if (connState.useSqlCache) {
connState.sqlCache.capacity = sqlCacheCapacity;
}
}
const stream = connState.client.openStream();
stream.intMode = this.#intMode;
const streamState = { conn: connState, stream };
connState.streamStates.add(streamState);
return streamState;
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
}
#openConn(client) {
try {
client ??= hrana.openWs(this.#url, this.#authToken);
return {
client,
useSqlCache: undefined,
sqlCache: new sql_cache_js_1.SqlCache(client, 0),
openTime: new Date(),
streamStates: new Set(),
};
}
catch (e) {
throw (0, hrana_js_1.mapHranaError)(e);
}
}
async reconnect() {
try {
for (const st of Array.from(this.#connState.streamStates)) {
try {
st.stream.close();
}
catch { }
}
this.#connState.client.close();
}
catch { }
if (this.#futureConnState) {
try {
this.#futureConnState.client.close();
}
catch { }
this.#futureConnState = undefined;
}
const next = this.#openConn();
const version = await next.client.getVersion();
next.useSqlCache = version >= 2;
if (next.useSqlCache) {
next.sqlCache.capacity = sqlCacheCapacity;
}
this.#connState = next;
this.closed = false;
}
_closeStream(streamState) {
streamState.stream.close();
const connState = streamState.conn;
connState.streamStates.delete(streamState);
if (connState.streamStates.size === 0 &&
connState !== this.#connState) {
// We are not using this connection anymore and this is the last stream that was using it, so we
// must close it now.
connState.client.close();
}
}
close() {
this.#connState.client.close();
this.closed = true;
if (this.#futureConnState) {
try {
this.#futureConnState.client.close();
}
catch { }
this.#futureConnState = undefined;
}
this.closed = true;
}
}
exports.WsClient = WsClient;
class WsTransaction extends hrana_js_1.HranaTransaction {
#client;
#streamState;
/** @private */
constructor(client, state, mode, version) {
super(mode, version);
this.#client = client;
this.#streamState = state;
}
/** @private */
_getStream() {
return this.#streamState.stream;
}
/** @private */
_getSqlCache() {
return this.#streamState.conn.sqlCache;
}
close() {
this.#client._closeStream(this.#streamState);
}
get closed() {
return this.#streamState.stream.closed;
}
}
exports.WsTransaction = WsTransaction;

23
node_modules/@libsql/client/lib-esm/hrana.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
import * as hrana from "@libsql/hrana-client";
import type { InStatement, ResultSet, Transaction, TransactionMode, InArgs } from "@libsql/core/api";
import type { SqlCache } from "./sql_cache.js";
export declare abstract class HranaTransaction implements Transaction {
#private;
/** @private */
constructor(mode: TransactionMode, version: hrana.ProtocolVersion);
/** @private */
abstract _getStream(): hrana.Stream;
/** @private */
abstract _getSqlCache(): SqlCache;
abstract close(): void;
abstract get closed(): boolean;
execute(stmt: InStatement): Promise<ResultSet>;
batch(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
executeMultiple(sql: string): Promise<void>;
rollback(): Promise<void>;
commit(): Promise<void>;
}
export declare function executeHranaBatch(mode: TransactionMode, version: hrana.ProtocolVersion, batch: hrana.Batch, hranaStmts: Array<hrana.Stmt>, disableForeignKeys?: boolean): Promise<Array<ResultSet>>;
export declare function stmtToHrana(stmt: InStatement | [string, InArgs?]): hrana.Stmt;
export declare function resultSetFromHrana(hranaRows: hrana.RowsResult): ResultSet;
export declare function mapHranaError(e: unknown): unknown;

310
node_modules/@libsql/client/lib-esm/hrana.js generated vendored Normal file
View File

@@ -0,0 +1,310 @@
import * as hrana from "@libsql/hrana-client";
import { LibsqlError } from "@libsql/core/api";
import { transactionModeToBegin, ResultSetImpl } from "@libsql/core/util";
export class HranaTransaction {
#mode;
#version;
// Promise that is resolved when the BEGIN statement completes, or `undefined` if we haven't executed the
// BEGIN statement yet.
#started;
/** @private */
constructor(mode, version) {
this.#mode = mode;
this.#version = version;
this.#started = undefined;
}
execute(stmt) {
return this.batch([stmt]).then((results) => results[0]);
}
async batch(stmts) {
const stream = this._getStream();
if (stream.closed) {
throw new LibsqlError("Cannot execute statements because the transaction is closed", "TRANSACTION_CLOSED");
}
try {
const hranaStmts = stmts.map(stmtToHrana);
let rowsPromises;
if (this.#started === undefined) {
// The transaction hasn't started yet, so we need to send the BEGIN statement in a batch with
// `hranaStmts`.
this._getSqlCache().apply(hranaStmts);
const batch = stream.batch(this.#version >= 3);
const beginStep = batch.step();
const beginPromise = beginStep.run(transactionModeToBegin(this.#mode));
// Execute the `hranaStmts` only if the BEGIN succeeded, to make sure that we don't execute it
// outside of a transaction.
let lastStep = beginStep;
rowsPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch
.step()
.condition(hrana.BatchCond.ok(lastStep));
if (this.#version >= 3) {
// If the Hrana version supports it, make sure that we are still in a transaction
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const rowsPromise = stmtStep.query(hranaStmt);
rowsPromise.catch(() => undefined); // silence Node warning
lastStep = stmtStep;
return rowsPromise;
});
// `this.#started` is resolved successfully only if the batch and the BEGIN statement inside
// of the batch are both successful.
this.#started = batch
.execute()
.then(() => beginPromise)
.then(() => undefined);
try {
await this.#started;
}
catch (e) {
// If the BEGIN failed, the transaction is unusable and we must close it. However, if the
// BEGIN suceeds and `hranaStmts` fail, the transaction is _not_ closed.
this.close();
throw e;
}
}
else {
if (this.#version < 3) {
// The transaction has started, so we must wait until the BEGIN statement completed to make
// sure that we don't execute `hranaStmts` outside of a transaction.
await this.#started;
}
else {
// The transaction has started, but we will use `hrana.BatchCond.isAutocommit()` to make
// sure that we don't execute `hranaStmts` outside of a transaction, so we don't have to
// wait for `this.#started`
}
this._getSqlCache().apply(hranaStmts);
const batch = stream.batch(this.#version >= 3);
let lastStep = undefined;
rowsPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch.step();
if (lastStep !== undefined) {
stmtStep.condition(hrana.BatchCond.ok(lastStep));
}
if (this.#version >= 3) {
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const rowsPromise = stmtStep.query(hranaStmt);
rowsPromise.catch(() => undefined); // silence Node warning
lastStep = stmtStep;
return rowsPromise;
});
await batch.execute();
}
const resultSets = [];
for (const rowsPromise of rowsPromises) {
const rows = await rowsPromise;
if (rows === undefined) {
throw new LibsqlError("Statement in a transaction was not executed, " +
"probably because the transaction has been rolled back", "TRANSACTION_CLOSED");
}
resultSets.push(resultSetFromHrana(rows));
}
return resultSets;
}
catch (e) {
throw mapHranaError(e);
}
}
async executeMultiple(sql) {
const stream = this._getStream();
if (stream.closed) {
throw new LibsqlError("Cannot execute statements because the transaction is closed", "TRANSACTION_CLOSED");
}
try {
if (this.#started === undefined) {
// If the transaction hasn't started yet, start it now
this.#started = stream
.run(transactionModeToBegin(this.#mode))
.then(() => undefined);
try {
await this.#started;
}
catch (e) {
this.close();
throw e;
}
}
else {
// Wait until the transaction has started
await this.#started;
}
await stream.sequence(sql);
}
catch (e) {
throw mapHranaError(e);
}
}
async rollback() {
try {
const stream = this._getStream();
if (stream.closed) {
return;
}
if (this.#started !== undefined) {
// We don't have to wait for the BEGIN statement to complete. If the BEGIN fails, we will
// execute a ROLLBACK outside of an active transaction, which should be harmless.
}
else {
// We did nothing in the transaction, so there is nothing to rollback.
return;
}
// Pipeline the ROLLBACK statement and the stream close.
const promise = stream.run("ROLLBACK").catch((e) => {
throw mapHranaError(e);
});
stream.closeGracefully();
await promise;
}
catch (e) {
throw mapHranaError(e);
}
finally {
// `this.close()` may close the `hrana.Client`, which aborts all pending stream requests, so we
// must call it _after_ we receive the ROLLBACK response.
// Also note that the current stream should already be closed, but we need to call `this.close()`
// anyway, because it may need to do more cleanup.
this.close();
}
}
async commit() {
// (this method is analogous to `rollback()`)
try {
const stream = this._getStream();
if (stream.closed) {
throw new LibsqlError("Cannot commit the transaction because it is already closed", "TRANSACTION_CLOSED");
}
if (this.#started !== undefined) {
// Make sure to execute the COMMIT only if the BEGIN was successful.
await this.#started;
}
else {
return;
}
const promise = stream.run("COMMIT").catch((e) => {
throw mapHranaError(e);
});
stream.closeGracefully();
await promise;
}
catch (e) {
throw mapHranaError(e);
}
finally {
this.close();
}
}
}
export async function executeHranaBatch(mode, version, batch, hranaStmts, disableForeignKeys = false) {
if (disableForeignKeys) {
batch.step().run("PRAGMA foreign_keys=off");
}
const beginStep = batch.step();
const beginPromise = beginStep.run(transactionModeToBegin(mode));
let lastStep = beginStep;
const stmtPromises = hranaStmts.map((hranaStmt) => {
const stmtStep = batch.step().condition(hrana.BatchCond.ok(lastStep));
if (version >= 3) {
stmtStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const stmtPromise = stmtStep.query(hranaStmt);
lastStep = stmtStep;
return stmtPromise;
});
const commitStep = batch.step().condition(hrana.BatchCond.ok(lastStep));
if (version >= 3) {
commitStep.condition(hrana.BatchCond.not(hrana.BatchCond.isAutocommit(batch)));
}
const commitPromise = commitStep.run("COMMIT");
const rollbackStep = batch
.step()
.condition(hrana.BatchCond.not(hrana.BatchCond.ok(commitStep)));
rollbackStep.run("ROLLBACK").catch((_) => undefined);
if (disableForeignKeys) {
batch.step().run("PRAGMA foreign_keys=on");
}
await batch.execute();
const resultSets = [];
await beginPromise;
for (const stmtPromise of stmtPromises) {
const hranaRows = await stmtPromise;
if (hranaRows === undefined) {
throw new LibsqlError("Statement in a batch was not executed, probably because the transaction has been rolled back", "TRANSACTION_CLOSED");
}
resultSets.push(resultSetFromHrana(hranaRows));
}
await commitPromise;
return resultSets;
}
export function stmtToHrana(stmt) {
let sql;
let args;
if (Array.isArray(stmt)) {
[sql, args] = stmt;
}
else if (typeof stmt === "string") {
sql = stmt;
}
else {
sql = stmt.sql;
args = stmt.args;
}
const hranaStmt = new hrana.Stmt(sql);
if (args) {
if (Array.isArray(args)) {
hranaStmt.bindIndexes(args);
}
else {
for (const [key, value] of Object.entries(args)) {
hranaStmt.bindName(key, value);
}
}
}
return hranaStmt;
}
export function resultSetFromHrana(hranaRows) {
const columns = hranaRows.columnNames.map((c) => c ?? "");
const columnTypes = hranaRows.columnDecltypes.map((c) => c ?? "");
const rows = hranaRows.rows;
const rowsAffected = hranaRows.affectedRowCount;
const lastInsertRowid = hranaRows.lastInsertRowid !== undefined
? hranaRows.lastInsertRowid
: undefined;
return new ResultSetImpl(columns, columnTypes, rows, rowsAffected, lastInsertRowid);
}
export function mapHranaError(e) {
if (e instanceof hrana.ClientError) {
const code = mapHranaErrorCode(e);
return new LibsqlError(e.message, code, undefined, e);
}
return e;
}
function mapHranaErrorCode(e) {
if (e instanceof hrana.ResponseError && e.code !== undefined) {
return e.code;
}
else if (e instanceof hrana.ProtoError) {
return "HRANA_PROTO_ERROR";
}
else if (e instanceof hrana.ClosedError) {
return e.cause instanceof hrana.ClientError
? mapHranaErrorCode(e.cause)
: "HRANA_CLOSED_ERROR";
}
else if (e instanceof hrana.WebSocketError) {
return "HRANA_WEBSOCKET_ERROR";
}
else if (e instanceof hrana.HttpServerError) {
return "SERVER_ERROR";
}
else if (e instanceof hrana.ProtocolVersionError) {
return "PROTOCOL_VERSION_ERROR";
}
else if (e instanceof hrana.InternalError) {
return "INTERNAL_ERROR";
}
else {
return "UNKNOWN";
}
}

39
node_modules/@libsql/client/lib-esm/http.d.ts generated vendored Normal file
View File

@@ -0,0 +1,39 @@
/// <reference types="node" />
import * as hrana from "@libsql/hrana-client";
import type { Config, Client } from "@libsql/core/api";
import type { InStatement, ResultSet, Transaction, IntMode, InArgs, Replicated } from "@libsql/core/api";
import { TransactionMode } from "@libsql/core/api";
import type { ExpandedConfig } from "@libsql/core/config";
import { HranaTransaction } from "./hrana.js";
import { SqlCache } from "./sql_cache.js";
export * from "@libsql/core/api";
export declare function createClient(config: Config): Client;
/** @private */
export declare function _createClient(config: ExpandedConfig): Client;
export declare class HttpClient implements Client {
#private;
protocol: "http";
/** @private */
constructor(url: URL, authToken: string | undefined, intMode: IntMode, customFetch: Function | undefined, concurrency: number);
private limit;
execute(stmtOrSql: InStatement | string, args?: InArgs): Promise<ResultSet>;
batch(stmts: Array<InStatement | [string, InArgs?]>, mode?: TransactionMode): Promise<Array<ResultSet>>;
migrate(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
transaction(mode?: TransactionMode): Promise<HttpTransaction>;
executeMultiple(sql: string): Promise<void>;
sync(): Promise<Replicated>;
close(): void;
reconnect(): Promise<void>;
get closed(): boolean;
}
export declare class HttpTransaction extends HranaTransaction implements Transaction {
#private;
/** @private */
constructor(stream: hrana.HttpStream, mode: TransactionMode, version: hrana.ProtocolVersion);
/** @private */
_getStream(): hrana.Stream;
/** @private */
_getSqlCache(): SqlCache;
close(): void;
get closed(): boolean;
}

230
node_modules/@libsql/client/lib-esm/http.js generated vendored Normal file
View File

@@ -0,0 +1,230 @@
import * as hrana from "@libsql/hrana-client";
import { LibsqlError } from "@libsql/core/api";
import { expandConfig } from "@libsql/core/config";
import { HranaTransaction, executeHranaBatch, stmtToHrana, resultSetFromHrana, mapHranaError, } from "./hrana.js";
import { SqlCache } from "./sql_cache.js";
import { encodeBaseUrl } from "@libsql/core/uri";
import { supportedUrlLink } from "@libsql/core/util";
import promiseLimit from "promise-limit";
export * from "@libsql/core/api";
export function createClient(config) {
return _createClient(expandConfig(config, true));
}
/** @private */
export function _createClient(config) {
if (config.scheme !== "https" && config.scheme !== "http") {
throw new LibsqlError('The HTTP client supports only "libsql:", "https:" and "http:" URLs, ' +
`got ${JSON.stringify(config.scheme + ":")}. For more information, please read ${supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
if (config.encryptionKey !== undefined) {
throw new LibsqlError("Encryption key is not supported by the remote client.", "ENCRYPTION_KEY_NOT_SUPPORTED");
}
if (config.scheme === "http" && config.tls) {
throw new LibsqlError(`A "http:" URL cannot opt into TLS by using ?tls=1`, "URL_INVALID");
}
else if (config.scheme === "https" && !config.tls) {
throw new LibsqlError(`A "https:" URL cannot opt out of TLS by using ?tls=0`, "URL_INVALID");
}
const url = encodeBaseUrl(config.scheme, config.authority, config.path);
return new HttpClient(url, config.authToken, config.intMode, config.fetch, config.concurrency);
}
const sqlCacheCapacity = 30;
export class HttpClient {
#client;
protocol;
#url;
#intMode;
#customFetch;
#concurrency;
#authToken;
#promiseLimitFunction;
/** @private */
constructor(url, authToken, intMode, customFetch, concurrency) {
this.#url = url;
this.#authToken = authToken;
this.#intMode = intMode;
this.#customFetch = customFetch;
this.#concurrency = concurrency;
this.#client = hrana.openHttp(this.#url, this.#authToken, this.#customFetch);
this.#client.intMode = this.#intMode;
this.protocol = "http";
this.#promiseLimitFunction = promiseLimit(this.#concurrency);
}
async limit(fn) {
return this.#promiseLimitFunction(fn);
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
return this.limit(async () => {
try {
const hranaStmt = stmtToHrana(stmt);
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the statement and
// close the stream in a single HTTP request.
let rowsPromise;
const stream = this.#client.openStream();
try {
rowsPromise = stream.query(hranaStmt);
}
finally {
stream.closeGracefully();
}
const rowsResult = await rowsPromise;
return resultSetFromHrana(rowsResult);
}
catch (e) {
throw mapHranaError(e);
}
});
}
async batch(stmts, mode = "deferred") {
return this.limit(async () => {
try {
const normalizedStmts = stmts.map((stmt) => {
if (Array.isArray(stmt)) {
return {
sql: stmt[0],
args: stmt[1] || [],
};
}
return stmt;
});
const hranaStmts = normalizedStmts.map(stmtToHrana);
const version = await this.#client.getVersion();
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the batch and
// close the stream in a single HTTP request.
let resultsPromise;
const stream = this.#client.openStream();
try {
// It makes sense to use a SQL cache even for a single batch, because it may contain the same
// statement repeated multiple times.
const sqlCache = new SqlCache(stream, sqlCacheCapacity);
sqlCache.apply(hranaStmts);
// TODO: we do not use a cursor here, because it would cause three roundtrips:
// 1. pipeline request to store SQL texts
// 2. cursor request
// 3. pipeline request to close the stream
const batch = stream.batch(false);
resultsPromise = executeHranaBatch(mode, version, batch, hranaStmts);
}
finally {
stream.closeGracefully();
}
const results = await resultsPromise;
return results;
}
catch (e) {
throw mapHranaError(e);
}
});
}
async migrate(stmts) {
return this.limit(async () => {
try {
const hranaStmts = stmts.map(stmtToHrana);
const version = await this.#client.getVersion();
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the batch and
// close the stream in a single HTTP request.
let resultsPromise;
const stream = this.#client.openStream();
try {
const batch = stream.batch(false);
resultsPromise = executeHranaBatch("deferred", version, batch, hranaStmts, true);
}
finally {
stream.closeGracefully();
}
const results = await resultsPromise;
return results;
}
catch (e) {
throw mapHranaError(e);
}
});
}
async transaction(mode = "write") {
return this.limit(async () => {
try {
const version = await this.#client.getVersion();
return new HttpTransaction(this.#client.openStream(), mode, version);
}
catch (e) {
throw mapHranaError(e);
}
});
}
async executeMultiple(sql) {
return this.limit(async () => {
try {
// Pipeline all operations, so `hrana.HttpClient` can open the stream, execute the sequence and
// close the stream in a single HTTP request.
let promise;
const stream = this.#client.openStream();
try {
promise = stream.sequence(sql);
}
finally {
stream.closeGracefully();
}
await promise;
}
catch (e) {
throw mapHranaError(e);
}
});
}
sync() {
throw new LibsqlError("sync not supported in http mode", "SYNC_NOT_SUPPORTED");
}
close() {
this.#client.close();
}
async reconnect() {
try {
if (!this.closed) {
// Abort in-flight ops and free resources
this.#client.close();
}
}
finally {
// Recreate the underlying hrana client
this.#client = hrana.openHttp(this.#url, this.#authToken, this.#customFetch);
this.#client.intMode = this.#intMode;
}
}
get closed() {
return this.#client.closed;
}
}
export class HttpTransaction extends HranaTransaction {
#stream;
#sqlCache;
/** @private */
constructor(stream, mode, version) {
super(mode, version);
this.#stream = stream;
this.#sqlCache = new SqlCache(stream, sqlCacheCapacity);
}
/** @private */
_getStream() {
return this.#stream;
}
/** @private */
_getSqlCache() {
return this.#sqlCache;
}
close() {
this.#stream.close();
}
get closed() {
return this.#stream.closed;
}
}

7
node_modules/@libsql/client/lib-esm/node.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import type { Config, Client } from "@libsql/core/api";
export * from "@libsql/core/api";
/** Creates a {@link Client} object.
*
* You must pass at least an `url` in the {@link Config} object.
*/
export declare function createClient(config: Config): Client;

23
node_modules/@libsql/client/lib-esm/node.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
import { expandConfig } from "@libsql/core/config";
import { _createClient as _createSqlite3Client } from "./sqlite3.js";
import { _createClient as _createWsClient } from "./ws.js";
import { _createClient as _createHttpClient } from "./http.js";
export * from "@libsql/core/api";
/** Creates a {@link Client} object.
*
* You must pass at least an `url` in the {@link Config} object.
*/
export function createClient(config) {
return _createClient(expandConfig(config, true));
}
function _createClient(config) {
if (config.scheme === "wss" || config.scheme === "ws") {
return _createWsClient(config);
}
else if (config.scheme === "https" || config.scheme === "http") {
return _createHttpClient(config);
}
else {
return _createSqlite3Client(config);
}
}

7
node_modules/@libsql/client/lib-esm/sql_cache.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import type * as hrana from "@libsql/hrana-client";
export declare class SqlCache {
#private;
capacity: number;
constructor(owner: hrana.SqlOwner, capacity: number);
apply(hranaStmts: Array<hrana.Stmt>): void;
}

87
node_modules/@libsql/client/lib-esm/sql_cache.js generated vendored Normal file
View File

@@ -0,0 +1,87 @@
export class SqlCache {
#owner;
#sqls;
capacity;
constructor(owner, capacity) {
this.#owner = owner;
this.#sqls = new Lru();
this.capacity = capacity;
}
// Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this
// function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,
// but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the
// server).
//
// In practice, this means that after calling this function, you can use the statements only up to the
// first `await`, because concurrent code may also use the cache and invalidate those statements.
apply(hranaStmts) {
if (this.capacity <= 0) {
return;
}
const usedSqlObjs = new Set();
for (const hranaStmt of hranaStmts) {
if (typeof hranaStmt.sql !== "string") {
continue;
}
const sqlText = hranaStmt.sql;
// Stored SQL cannot exceed 5kb.
// https://github.com/tursodatabase/libsql/blob/e9d637e051685f92b0da43849507b5ef4232fbeb/libsql-server/src/hrana/http/request.rs#L10
if (sqlText.length >= 5000) {
continue;
}
let sqlObj = this.#sqls.get(sqlText);
if (sqlObj === undefined) {
while (this.#sqls.size + 1 > this.capacity) {
const [evictSqlText, evictSqlObj] = this.#sqls.peekLru();
if (usedSqlObjs.has(evictSqlObj)) {
// The SQL object that we are trying to evict is already in use in this batch, so we
// must not evict and close it.
break;
}
evictSqlObj.close();
this.#sqls.delete(evictSqlText);
}
if (this.#sqls.size + 1 <= this.capacity) {
sqlObj = this.#owner.storeSql(sqlText);
this.#sqls.set(sqlText, sqlObj);
}
}
if (sqlObj !== undefined) {
hranaStmt.sql = sqlObj;
usedSqlObjs.add(sqlObj);
}
}
}
}
class Lru {
// This maps keys to the cache values. The entries are ordered by their last use (entires that were used
// most recently are at the end).
#cache;
constructor() {
this.#cache = new Map();
}
get(key) {
const value = this.#cache.get(key);
if (value !== undefined) {
// move the entry to the back of the Map
this.#cache.delete(key);
this.#cache.set(key, value);
}
return value;
}
set(key, value) {
this.#cache.set(key, value);
}
peekLru() {
for (const entry of this.#cache.entries()) {
return entry;
}
return undefined;
}
delete(key) {
this.#cache.delete(key);
}
get size() {
return this.#cache.size;
}
}

35
node_modules/@libsql/client/lib-esm/sqlite3.d.ts generated vendored Normal file
View File

@@ -0,0 +1,35 @@
import Database from "libsql";
import type { Config, IntMode, Client, Transaction, TransactionMode, ResultSet, InStatement, InArgs, Replicated } from "@libsql/core/api";
import type { ExpandedConfig } from "@libsql/core/config";
export * from "@libsql/core/api";
export declare function createClient(config: Config): Client;
/** @private */
export declare function _createClient(config: ExpandedConfig): Client;
export declare class Sqlite3Client implements Client {
#private;
closed: boolean;
protocol: "file";
/** @private */
constructor(path: string, options: Database.Options, db: Database.Database, intMode: IntMode);
execute(stmtOrSql: InStatement | string, args?: InArgs): Promise<ResultSet>;
batch(stmts: Array<InStatement | [string, InArgs?]>, mode?: TransactionMode): Promise<Array<ResultSet>>;
migrate(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
transaction(mode?: TransactionMode): Promise<Transaction>;
executeMultiple(sql: string): Promise<void>;
sync(): Promise<Replicated>;
reconnect(): Promise<void>;
close(): void;
}
export declare class Sqlite3Transaction implements Transaction {
#private;
/** @private */
constructor(database: Database.Database, intMode: IntMode);
execute(stmt: InStatement): Promise<ResultSet>;
execute(sql: string, args?: InArgs): Promise<ResultSet>;
batch(stmts: Array<InStatement | [string, InArgs?]>): Promise<Array<ResultSet>>;
executeMultiple(sql: string): Promise<void>;
rollback(): Promise<void>;
commit(): Promise<void>;
close(): void;
get closed(): boolean;
}

395
node_modules/@libsql/client/lib-esm/sqlite3.js generated vendored Normal file
View File

@@ -0,0 +1,395 @@
import Database from "libsql";
import { Buffer } from "node:buffer";
import { LibsqlError } from "@libsql/core/api";
import { expandConfig, isInMemoryConfig } from "@libsql/core/config";
import { supportedUrlLink, transactionModeToBegin, ResultSetImpl, } from "@libsql/core/util";
export * from "@libsql/core/api";
export function createClient(config) {
return _createClient(expandConfig(config, true));
}
/** @private */
export function _createClient(config) {
if (config.scheme !== "file") {
throw new LibsqlError(`URL scheme ${JSON.stringify(config.scheme + ":")} is not supported by the local sqlite3 client. ` +
`For more information, please read ${supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
const authority = config.authority;
if (authority !== undefined) {
const host = authority.host.toLowerCase();
if (host !== "" && host !== "localhost") {
throw new LibsqlError(`Invalid host in file URL: ${JSON.stringify(authority.host)}. ` +
'A "file:" URL with an absolute path should start with one slash ("file:/absolute/path.db") ' +
'or with three slashes ("file:///absolute/path.db"). ' +
`For more information, please read ${supportedUrlLink}`, "URL_INVALID");
}
if (authority.port !== undefined) {
throw new LibsqlError("File URL cannot have a port", "URL_INVALID");
}
if (authority.userinfo !== undefined) {
throw new LibsqlError("File URL cannot have username and password", "URL_INVALID");
}
}
let isInMemory = isInMemoryConfig(config);
if (isInMemory && config.syncUrl) {
throw new LibsqlError(`Embedded replica must use file for local db but URI with in-memory mode were provided instead: ${config.path}`, "URL_INVALID");
}
let path = config.path;
if (isInMemory) {
// note: we should prepend file scheme in order for SQLite3 to recognize :memory: connection query parameters
path = `${config.scheme}:${config.path}`;
}
const options = {
authToken: config.authToken,
encryptionKey: config.encryptionKey,
syncUrl: config.syncUrl,
syncPeriod: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
};
const db = new Database(path, options);
executeStmt(db, "SELECT 1 AS checkThatTheDatabaseCanBeOpened", config.intMode);
return new Sqlite3Client(path, options, db, config.intMode);
}
export class Sqlite3Client {
#path;
#options;
#db;
#intMode;
closed;
protocol;
/** @private */
constructor(path, options, db, intMode) {
this.#path = path;
this.#options = options;
this.#db = db;
this.#intMode = intMode;
this.closed = false;
this.protocol = "file";
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
this.#checkNotClosed();
return executeStmt(this.#getDb(), stmt, this.#intMode);
}
async batch(stmts, mode = "deferred") {
this.#checkNotClosed();
const db = this.#getDb();
try {
executeStmt(db, transactionModeToBegin(mode), this.#intMode);
const resultSets = stmts.map((stmt) => {
if (!db.inTransaction) {
throw new LibsqlError("The transaction has been rolled back", "TRANSACTION_CLOSED");
}
const normalizedStmt = Array.isArray(stmt)
? { sql: stmt[0], args: stmt[1] || [] }
: stmt;
return executeStmt(db, normalizedStmt, this.#intMode);
});
executeStmt(db, "COMMIT", this.#intMode);
return resultSets;
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
}
}
async migrate(stmts) {
this.#checkNotClosed();
const db = this.#getDb();
try {
executeStmt(db, "PRAGMA foreign_keys=off", this.#intMode);
executeStmt(db, transactionModeToBegin("deferred"), this.#intMode);
const resultSets = stmts.map((stmt) => {
if (!db.inTransaction) {
throw new LibsqlError("The transaction has been rolled back", "TRANSACTION_CLOSED");
}
return executeStmt(db, stmt, this.#intMode);
});
executeStmt(db, "COMMIT", this.#intMode);
return resultSets;
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
executeStmt(db, "PRAGMA foreign_keys=on", this.#intMode);
}
}
async transaction(mode = "write") {
const db = this.#getDb();
executeStmt(db, transactionModeToBegin(mode), this.#intMode);
this.#db = null; // A new connection will be lazily created on next use
return new Sqlite3Transaction(db, this.#intMode);
}
async executeMultiple(sql) {
this.#checkNotClosed();
const db = this.#getDb();
try {
return executeMultiple(db, sql);
}
finally {
if (db.inTransaction) {
executeStmt(db, "ROLLBACK", this.#intMode);
}
}
}
async sync() {
this.#checkNotClosed();
const rep = await this.#getDb().sync();
return {
frames_synced: rep.frames_synced,
frame_no: rep.frame_no,
};
}
async reconnect() {
try {
if (!this.closed && this.#db !== null) {
this.#db.close();
}
}
finally {
this.#db = new Database(this.#path, this.#options);
this.closed = false;
}
}
close() {
this.closed = true;
if (this.#db !== null) {
this.#db.close();
this.#db = null;
}
}
#checkNotClosed() {
if (this.closed) {
throw new LibsqlError("The client is closed", "CLIENT_CLOSED");
}
}
// Lazily creates the database connection and returns it
#getDb() {
if (this.#db === null) {
this.#db = new Database(this.#path, this.#options);
}
return this.#db;
}
}
export class Sqlite3Transaction {
#database;
#intMode;
/** @private */
constructor(database, intMode) {
this.#database = database;
this.#intMode = intMode;
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
this.#checkNotClosed();
return executeStmt(this.#database, stmt, this.#intMode);
}
async batch(stmts) {
return stmts.map((stmt) => {
this.#checkNotClosed();
const normalizedStmt = Array.isArray(stmt)
? { sql: stmt[0], args: stmt[1] || [] }
: stmt;
return executeStmt(this.#database, normalizedStmt, this.#intMode);
});
}
async executeMultiple(sql) {
this.#checkNotClosed();
return executeMultiple(this.#database, sql);
}
async rollback() {
if (!this.#database.open) {
return;
}
this.#checkNotClosed();
executeStmt(this.#database, "ROLLBACK", this.#intMode);
}
async commit() {
this.#checkNotClosed();
executeStmt(this.#database, "COMMIT", this.#intMode);
}
close() {
if (this.#database.inTransaction) {
executeStmt(this.#database, "ROLLBACK", this.#intMode);
}
}
get closed() {
return !this.#database.inTransaction;
}
#checkNotClosed() {
if (this.closed) {
throw new LibsqlError("The transaction is closed", "TRANSACTION_CLOSED");
}
}
}
function executeStmt(db, stmt, intMode) {
let sql;
let args;
if (typeof stmt === "string") {
sql = stmt;
args = [];
}
else {
sql = stmt.sql;
if (Array.isArray(stmt.args)) {
args = stmt.args.map((value) => valueToSql(value, intMode));
}
else {
args = {};
for (const name in stmt.args) {
const argName = name[0] === "@" || name[0] === "$" || name[0] === ":"
? name.substring(1)
: name;
args[argName] = valueToSql(stmt.args[name], intMode);
}
}
}
try {
const sqlStmt = db.prepare(sql);
sqlStmt.safeIntegers(true);
let returnsData = true;
try {
sqlStmt.raw(true);
}
catch {
// raw() throws an exception if the statement does not return data
returnsData = false;
}
if (returnsData) {
const columns = Array.from(sqlStmt.columns().map((col) => col.name));
const columnTypes = Array.from(sqlStmt.columns().map((col) => col.type ?? ""));
const rows = sqlStmt.all(args).map((sqlRow) => {
return rowFromSql(sqlRow, columns, intMode);
});
// TODO: can we get this info from better-sqlite3?
const rowsAffected = 0;
const lastInsertRowid = undefined;
return new ResultSetImpl(columns, columnTypes, rows, rowsAffected, lastInsertRowid);
}
else {
const info = sqlStmt.run(args);
const rowsAffected = info.changes;
const lastInsertRowid = BigInt(info.lastInsertRowid);
return new ResultSetImpl([], [], [], rowsAffected, lastInsertRowid);
}
}
catch (e) {
throw mapSqliteError(e);
}
}
function rowFromSql(sqlRow, columns, intMode) {
const row = {};
// make sure that the "length" property is not enumerable
Object.defineProperty(row, "length", { value: sqlRow.length });
for (let i = 0; i < sqlRow.length; ++i) {
const value = valueFromSql(sqlRow[i], intMode);
Object.defineProperty(row, i, { value });
const column = columns[i];
if (!Object.hasOwn(row, column)) {
Object.defineProperty(row, column, {
value,
enumerable: true,
configurable: true,
writable: true,
});
}
}
return row;
}
function valueFromSql(sqlValue, intMode) {
if (typeof sqlValue === "bigint") {
if (intMode === "number") {
if (sqlValue < minSafeBigint || sqlValue > maxSafeBigint) {
throw new RangeError("Received integer which cannot be safely represented as a JavaScript number");
}
return Number(sqlValue);
}
else if (intMode === "bigint") {
return sqlValue;
}
else if (intMode === "string") {
return "" + sqlValue;
}
else {
throw new Error("Invalid value for IntMode");
}
}
else if (sqlValue instanceof Buffer) {
return sqlValue.buffer;
}
return sqlValue;
}
const minSafeBigint = -9007199254740991n;
const maxSafeBigint = 9007199254740991n;
function valueToSql(value, intMode) {
if (typeof value === "number") {
if (!Number.isFinite(value)) {
throw new RangeError("Only finite numbers (not Infinity or NaN) can be passed as arguments");
}
return value;
}
else if (typeof value === "bigint") {
if (value < minInteger || value > maxInteger) {
throw new RangeError("bigint is too large to be represented as a 64-bit integer and passed as argument");
}
return value;
}
else if (typeof value === "boolean") {
switch (intMode) {
case "bigint":
return value ? 1n : 0n;
case "string":
return value ? "1" : "0";
default:
return value ? 1 : 0;
}
}
else if (value instanceof ArrayBuffer) {
return Buffer.from(value);
}
else if (value instanceof Date) {
return value.valueOf();
}
else if (value === undefined) {
throw new TypeError("undefined cannot be passed as argument to the database");
}
else {
return value;
}
}
const minInteger = -9223372036854775808n;
const maxInteger = 9223372036854775807n;
function executeMultiple(db, sql) {
try {
db.exec(sql);
}
catch (e) {
throw mapSqliteError(e);
}
}
function mapSqliteError(e) {
if (e instanceof Database.SqliteError) {
return new LibsqlError(e.message, e.code, e.rawCode, e);
}
return e;
}

6
node_modules/@libsql/client/lib-esm/web.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import type { Config, Client } from "@libsql/core/api";
import type { ExpandedConfig } from "@libsql/core/config";
export * from "@libsql/core/api";
export declare function createClient(config: Config): Client;
/** @private */
export declare function _createClient(config: ExpandedConfig): Client;

22
node_modules/@libsql/client/lib-esm/web.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import { LibsqlError } from "@libsql/core/api";
import { expandConfig } from "@libsql/core/config";
import { supportedUrlLink } from "@libsql/core/util";
import { _createClient as _createWsClient } from "./ws.js";
import { _createClient as _createHttpClient } from "./http.js";
export * from "@libsql/core/api";
export function createClient(config) {
return _createClient(expandConfig(config, true));
}
/** @private */
export function _createClient(config) {
if (config.scheme === "ws" || config.scheme === "wss") {
return _createWsClient(config);
}
else if (config.scheme === "http" || config.scheme === "https") {
return _createHttpClient(config);
}
else {
throw new LibsqlError('The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, ' +
`got ${JSON.stringify(config.scheme + ":")}. For more information, please read ${supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
}

50
node_modules/@libsql/client/lib-esm/ws.d.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
/// <reference types="node" />
import * as hrana from "@libsql/hrana-client";
import type { Config, IntMode, Client, Transaction, ResultSet, InStatement, InArgs, Replicated } from "@libsql/core/api";
import { TransactionMode } from "@libsql/core/api";
import type { ExpandedConfig } from "@libsql/core/config";
import { HranaTransaction } from "./hrana.js";
import { SqlCache } from "./sql_cache.js";
export * from "@libsql/core/api";
export declare function createClient(config: Config): WsClient;
/** @private */
export declare function _createClient(config: ExpandedConfig): WsClient;
interface ConnState {
client: hrana.WsClient;
useSqlCache: boolean | undefined;
sqlCache: SqlCache;
openTime: Date;
streamStates: Set<StreamState>;
}
interface StreamState {
conn: ConnState;
stream: hrana.WsStream;
}
export declare class WsClient implements Client {
#private;
closed: boolean;
protocol: "ws";
/** @private */
constructor(client: hrana.WsClient, url: URL, authToken: string | undefined, intMode: IntMode, concurrency: number | undefined);
private limit;
execute(stmtOrSql: InStatement | string, args?: InArgs): Promise<ResultSet>;
batch(stmts: Array<InStatement | [string, InArgs?]>, mode?: TransactionMode): Promise<Array<ResultSet>>;
migrate(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
transaction(mode?: TransactionMode): Promise<WsTransaction>;
executeMultiple(sql: string): Promise<void>;
sync(): Promise<Replicated>;
reconnect(): Promise<void>;
_closeStream(streamState: StreamState): void;
close(): void;
}
export declare class WsTransaction extends HranaTransaction implements Transaction {
#private;
/** @private */
constructor(client: WsClient, state: StreamState, mode: TransactionMode, version: hrana.ProtocolVersion);
/** @private */
_getStream(): hrana.Stream;
/** @private */
_getSqlCache(): SqlCache;
close(): void;
get closed(): boolean;
}

359
node_modules/@libsql/client/lib-esm/ws.js generated vendored Normal file
View File

@@ -0,0 +1,359 @@
import * as hrana from "@libsql/hrana-client";
import { LibsqlError } from "@libsql/core/api";
import { expandConfig } from "@libsql/core/config";
import { HranaTransaction, executeHranaBatch, stmtToHrana, resultSetFromHrana, mapHranaError, } from "./hrana.js";
import { SqlCache } from "./sql_cache.js";
import { encodeBaseUrl } from "@libsql/core/uri";
import { supportedUrlLink } from "@libsql/core/util";
import promiseLimit from "promise-limit";
export * from "@libsql/core/api";
export function createClient(config) {
return _createClient(expandConfig(config, false));
}
/** @private */
export function _createClient(config) {
if (config.scheme !== "wss" && config.scheme !== "ws") {
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");
}
if (config.encryptionKey !== undefined) {
throw new LibsqlError("Encryption key is not supported by the remote client.", "ENCRYPTION_KEY_NOT_SUPPORTED");
}
if (config.scheme === "ws" && config.tls) {
throw new LibsqlError(`A "ws:" URL cannot opt into TLS by using ?tls=1`, "URL_INVALID");
}
else if (config.scheme === "wss" && !config.tls) {
throw new LibsqlError(`A "wss:" URL cannot opt out of TLS by using ?tls=0`, "URL_INVALID");
}
const url = encodeBaseUrl(config.scheme, config.authority, config.path);
let client;
try {
client = hrana.openWs(url, config.authToken);
}
catch (e) {
if (e instanceof hrana.WebSocketUnsupportedError) {
const suggestedScheme = config.scheme === "wss" ? "https" : "http";
const suggestedUrl = encodeBaseUrl(suggestedScheme, config.authority, config.path);
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");
}
throw mapHranaError(e);
}
return new WsClient(client, url, config.authToken, config.intMode, config.concurrency);
}
const maxConnAgeMillis = 60 * 1000;
const sqlCacheCapacity = 100;
export class WsClient {
#url;
#authToken;
#intMode;
// State of the current connection. The `hrana.WsClient` inside may be closed at any moment due to an
// asynchronous error.
#connState;
// If defined, this is a connection that will be used in the future, once it is ready.
#futureConnState;
closed;
protocol;
#isSchemaDatabase;
#promiseLimitFunction;
/** @private */
constructor(client, url, authToken, intMode, concurrency) {
this.#url = url;
this.#authToken = authToken;
this.#intMode = intMode;
this.#connState = this.#openConn(client);
this.#futureConnState = undefined;
this.closed = false;
this.protocol = "ws";
this.#promiseLimitFunction = promiseLimit(concurrency);
}
async limit(fn) {
return this.#promiseLimitFunction(fn);
}
async execute(stmtOrSql, args) {
let stmt;
if (typeof stmtOrSql === "string") {
stmt = {
sql: stmtOrSql,
args: args || [],
};
}
else {
stmt = stmtOrSql;
}
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const hranaStmt = stmtToHrana(stmt);
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
streamState.conn.sqlCache.apply([hranaStmt]);
const hranaRowsPromise = streamState.stream.query(hranaStmt);
streamState.stream.closeGracefully();
const hranaRowsResult = await hranaRowsPromise;
return resultSetFromHrana(hranaRowsResult);
}
catch (e) {
throw mapHranaError(e);
}
finally {
this._closeStream(streamState);
}
});
}
async batch(stmts, mode = "deferred") {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const normalizedStmts = stmts.map((stmt) => {
if (Array.isArray(stmt)) {
return {
sql: stmt[0],
args: stmt[1] || [],
};
}
return stmt;
});
const hranaStmts = normalizedStmts.map(stmtToHrana);
const version = await streamState.conn.client.getVersion();
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
streamState.conn.sqlCache.apply(hranaStmts);
const batch = streamState.stream.batch(version >= 3);
const resultsPromise = executeHranaBatch(mode, version, batch, hranaStmts);
const results = await resultsPromise;
return results;
}
catch (e) {
throw mapHranaError(e);
}
finally {
this._closeStream(streamState);
}
});
}
async migrate(stmts) {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const hranaStmts = stmts.map(stmtToHrana);
const version = await streamState.conn.client.getVersion();
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
const batch = streamState.stream.batch(version >= 3);
const resultsPromise = executeHranaBatch("deferred", version, batch, hranaStmts, true);
const results = await resultsPromise;
return results;
}
catch (e) {
throw mapHranaError(e);
}
finally {
this._closeStream(streamState);
}
});
}
async transaction(mode = "write") {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
const version = await streamState.conn.client.getVersion();
// the BEGIN statement will be batched with the first statement on the transaction to save a
// network roundtrip
return new WsTransaction(this, streamState, mode, version);
}
catch (e) {
this._closeStream(streamState);
throw mapHranaError(e);
}
});
}
async executeMultiple(sql) {
return this.limit(async () => {
const streamState = await this.#openStream();
try {
// Schedule all operations synchronously, so they will be pipelined and executed in a single
// network roundtrip.
const promise = streamState.stream.sequence(sql);
streamState.stream.closeGracefully();
await promise;
}
catch (e) {
throw mapHranaError(e);
}
finally {
this._closeStream(streamState);
}
});
}
sync() {
throw new LibsqlError("sync not supported in ws mode", "SYNC_NOT_SUPPORTED");
}
async #openStream() {
if (this.closed) {
throw new LibsqlError("The client is closed", "CLIENT_CLOSED");
}
const now = new Date();
const ageMillis = now.valueOf() - this.#connState.openTime.valueOf();
if (ageMillis > maxConnAgeMillis &&
this.#futureConnState === undefined) {
// The existing connection is too old, let's open a new one.
const futureConnState = this.#openConn();
this.#futureConnState = futureConnState;
// However, if we used `futureConnState` immediately, we would introduce additional latency,
// because we would have to wait for the WebSocket handshake to complete, even though we may a
// have perfectly good existing connection in `this.#connState`!
//
// So we wait until the `hrana.Client.getVersion()` operation completes (which happens when the
// WebSocket hanshake completes), and only then we replace `this.#connState` with
// `futureConnState`, which is stored in `this.#futureConnState` in the meantime.
futureConnState.client.getVersion().then((_version) => {
if (this.#connState !== futureConnState) {
// We need to close `this.#connState` before we replace it. However, it is possible
// that `this.#connState` has already been replaced: see the code below.
if (this.#connState.streamStates.size === 0) {
this.#connState.client.close();
}
else {
// If there are existing streams on the connection, we must not close it, because
// these streams would be broken. The last stream to be closed will also close the
// connection in `_closeStream()`.
}
}
this.#connState = futureConnState;
this.#futureConnState = undefined;
}, (_e) => {
// If the new connection could not be established, let's just ignore the error and keep
// using the existing connection.
this.#futureConnState = undefined;
});
}
if (this.#connState.client.closed) {
// An error happened on this connection and it has been closed. Let's try to seamlessly reconnect.
try {
if (this.#futureConnState !== undefined) {
// We are already in the process of opening a new connection, so let's just use it
// immediately.
this.#connState = this.#futureConnState;
}
else {
this.#connState = this.#openConn();
}
}
catch (e) {
throw mapHranaError(e);
}
}
const connState = this.#connState;
try {
// Now we wait for the WebSocket handshake to complete (if it hasn't completed yet). Note that
// this does not increase latency, because any messages that we would send on the WebSocket before
// the handshake would be queued until the handshake is completed anyway.
if (connState.useSqlCache === undefined) {
connState.useSqlCache =
(await connState.client.getVersion()) >= 2;
if (connState.useSqlCache) {
connState.sqlCache.capacity = sqlCacheCapacity;
}
}
const stream = connState.client.openStream();
stream.intMode = this.#intMode;
const streamState = { conn: connState, stream };
connState.streamStates.add(streamState);
return streamState;
}
catch (e) {
throw mapHranaError(e);
}
}
#openConn(client) {
try {
client ??= hrana.openWs(this.#url, this.#authToken);
return {
client,
useSqlCache: undefined,
sqlCache: new SqlCache(client, 0),
openTime: new Date(),
streamStates: new Set(),
};
}
catch (e) {
throw mapHranaError(e);
}
}
async reconnect() {
try {
for (const st of Array.from(this.#connState.streamStates)) {
try {
st.stream.close();
}
catch { }
}
this.#connState.client.close();
}
catch { }
if (this.#futureConnState) {
try {
this.#futureConnState.client.close();
}
catch { }
this.#futureConnState = undefined;
}
const next = this.#openConn();
const version = await next.client.getVersion();
next.useSqlCache = version >= 2;
if (next.useSqlCache) {
next.sqlCache.capacity = sqlCacheCapacity;
}
this.#connState = next;
this.closed = false;
}
_closeStream(streamState) {
streamState.stream.close();
const connState = streamState.conn;
connState.streamStates.delete(streamState);
if (connState.streamStates.size === 0 &&
connState !== this.#connState) {
// We are not using this connection anymore and this is the last stream that was using it, so we
// must close it now.
connState.client.close();
}
}
close() {
this.#connState.client.close();
this.closed = true;
if (this.#futureConnState) {
try {
this.#futureConnState.client.close();
}
catch { }
this.#futureConnState = undefined;
}
this.closed = true;
}
}
export class WsTransaction extends HranaTransaction {
#client;
#streamState;
/** @private */
constructor(client, state, mode, version) {
super(mode, version);
this.#client = client;
this.#streamState = state;
}
/** @private */
_getStream() {
return this.#streamState.stream;
}
/** @private */
_getSqlCache() {
return this.#streamState.conn.sqlCache;
}
close() {
this.#client._closeStream(this.#streamState);
}
get closed() {
return this.#streamState.stream.closed;
}
}

123
node_modules/@libsql/client/package.json generated vendored Normal file
View File

@@ -0,0 +1,123 @@
{
"name": "@libsql/client",
"version": "0.15.15",
"keywords": [
"libsql",
"database",
"sqlite",
"serverless",
"vercel",
"netlify",
"lambda"
],
"description": "libSQL driver for TypeScript and JavaScript",
"repository": {
"type": "git",
"url": "git+https://github.com/libsql/libsql-client-ts",
"directory": "packages/libsql-client"
},
"authors": [
"Jan Špaček <honza@chiselstrike.com>",
"Pekka Enberg <penberg@chiselstrike.com>",
"Jan Plhak <jp@chiselstrike.com>"
],
"license": "MIT",
"type": "module",
"main": "lib-cjs/node.js",
"types": "lib-esm/node.d.ts",
"exports": {
".": {
"types": "./lib-esm/node.d.ts",
"import": {
"workerd": "./lib-esm/web.js",
"deno": "./lib-esm/node.js",
"edge-light": "./lib-esm/web.js",
"netlify": "./lib-esm/web.js",
"node": "./lib-esm/node.js",
"browser": "./lib-esm/web.js",
"default": "./lib-esm/node.js"
},
"require": "./lib-cjs/node.js"
},
"./node": {
"types": "./lib-esm/node.d.ts",
"import": "./lib-esm/node.js",
"require": "./lib-cjs/node.js"
},
"./http": {
"types": "./lib-esm/http.d.ts",
"import": "./lib-esm/http.js",
"require": "./lib-cjs/http.js"
},
"./ws": {
"types": "./lib-esm/ws.d.ts",
"import": "./lib-esm/ws.js",
"require": "./lib-cjs/ws.js"
},
"./sqlite3": {
"types": "./lib-esm/sqlite3.d.ts",
"import": "./lib-esm/sqlite3.js",
"require": "./lib-cjs/sqlite3.js"
},
"./web": {
"types": "./lib-esm/web.d.ts",
"import": "./lib-esm/web.js",
"require": "./lib-cjs/web.js"
}
},
"typesVersions": {
"*": {
".": [
"./lib-esm/node.d.ts"
],
"http": [
"./lib-esm/http.d.ts"
],
"hrana": [
"./lib-esm/hrana.d.ts"
],
"sqlite3": [
"./lib-esm/sqlite3.d.ts"
],
"web": [
"./lib-esm/web.d.ts"
]
}
},
"files": [
"lib-cjs/**",
"lib-esm/**",
"README.md"
],
"scripts": {
"prepublishOnly": "npm run build",
"prebuild": "rm -rf ./lib-cjs ./lib-esm",
"build": "npm run build:cjs && npm run build:esm",
"build:cjs": "tsc -p tsconfig.build-cjs.json",
"build:esm": "tsc -p tsconfig.build-esm.json",
"format:check": "prettier --check .",
"postbuild": "cp package-cjs.json ./lib-cjs/package.json",
"test": "jest --runInBand",
"typecheck": "tsc --noEmit",
"typedoc": "rm -rf ./docs && typedoc",
"lint-staged": "lint-staged"
},
"dependencies": {
"@libsql/core": "^0.15.14",
"@libsql/hrana-client": "^0.7.0",
"js-base64": "^3.7.5",
"libsql": "^0.5.22",
"promise-limit": "^2.7.0"
},
"devDependencies": {
"@types/jest": "^29.2.5",
"@types/node": "^18.15.5",
"jest": "^29.3.1",
"lint-staged": "^15.2.2",
"msw": "^2.3.0",
"prettier": "3.2.5",
"ts-jest": "^29.0.5",
"typedoc": "^0.23.28",
"typescript": "^4.9.4"
}
}

20
node_modules/@libsql/core/lib-cjs/api.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LibsqlError = void 0;
/** Error thrown by the client. */
class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, rawCode, cause) {
if (code !== undefined) {
message = `${code}: ${message}`;
}
super(message, { cause });
this.code = code;
this.rawCode = rawCode;
this.name = "LibsqlError";
}
}
exports.LibsqlError = LibsqlError;

141
node_modules/@libsql/core/lib-cjs/config.js generated vendored Normal file
View File

@@ -0,0 +1,141 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.expandConfig = exports.isInMemoryConfig = void 0;
const api_js_1 = require("./api.js");
const uri_js_1 = require("./uri.js");
const util_js_1 = require("./util.js");
const inMemoryMode = ":memory:";
function isInMemoryConfig(config) {
return (config.scheme === "file" &&
(config.path === ":memory:" || config.path.startsWith(":memory:?")));
}
exports.isInMemoryConfig = isInMemoryConfig;
function expandConfig(config, preferHttp) {
if (typeof config !== "object") {
// produce a reasonable error message in the common case where users type
// `createClient("libsql://...")` instead of `createClient({url: "libsql://..."})`
throw new TypeError(`Expected client configuration as object, got ${typeof config}`);
}
let { url, authToken, tls, intMode, concurrency } = config;
// fill simple defaults right here
concurrency = Math.max(0, concurrency || 20);
intMode ??= "number";
let connectionQueryParams = []; // recognized query parameters which we sanitize through white list of valid key-value pairs
// convert plain :memory: url to URI format to make logic more uniform
if (url === inMemoryMode) {
url = "file::memory:";
}
// parse url parameters first and override config with update values
const uri = (0, uri_js_1.parseUri)(url);
const originalUriScheme = uri.scheme.toLowerCase();
const isInMemoryMode = originalUriScheme === "file" &&
uri.path === inMemoryMode &&
uri.authority === undefined;
let queryParamsDef;
if (isInMemoryMode) {
queryParamsDef = {
cache: {
values: ["shared", "private"],
update: (key, value) => connectionQueryParams.push(`${key}=${value}`),
},
};
}
else {
queryParamsDef = {
tls: {
values: ["0", "1"],
update: (_, value) => (tls = value === "1"),
},
authToken: {
update: (_, value) => (authToken = value),
},
};
}
for (const { key, value } of uri.query?.pairs ?? []) {
if (!Object.hasOwn(queryParamsDef, key)) {
throw new api_js_1.LibsqlError(`Unsupported URL query parameter ${JSON.stringify(key)}`, "URL_PARAM_NOT_SUPPORTED");
}
const queryParamDef = queryParamsDef[key];
if (queryParamDef.values !== undefined &&
!queryParamDef.values.includes(value)) {
throw new api_js_1.LibsqlError(`Unknown value for the "${key}" query argument: ${JSON.stringify(value)}. Supported values are: [${queryParamDef.values.map((x) => '"' + x + '"').join(", ")}]`, "URL_INVALID");
}
if (queryParamDef.update !== undefined) {
queryParamDef?.update(key, value);
}
}
// fill complex defaults & validate config
const connectionQueryParamsString = connectionQueryParams.length === 0
? ""
: `?${connectionQueryParams.join("&")}`;
const path = uri.path + connectionQueryParamsString;
let scheme;
if (originalUriScheme === "libsql") {
if (tls === false) {
if (uri.authority?.port === undefined) {
throw new api_js_1.LibsqlError('A "libsql:" URL with ?tls=0 must specify an explicit port', "URL_INVALID");
}
scheme = preferHttp ? "http" : "ws";
}
else {
scheme = preferHttp ? "https" : "wss";
}
}
else {
scheme = originalUriScheme;
}
if (scheme === "http" || scheme === "ws") {
tls ??= false;
}
else {
tls ??= true;
}
if (scheme !== "http" &&
scheme !== "ws" &&
scheme !== "https" &&
scheme !== "wss" &&
scheme !== "file") {
throw new api_js_1.LibsqlError('The client supports only "libsql:", "wss:", "ws:", "https:", "http:" and "file:" URLs, ' +
`got ${JSON.stringify(uri.scheme + ":")}. ` +
`For more information, please read ${util_js_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
if (intMode !== "number" && intMode !== "bigint" && intMode !== "string") {
throw new TypeError(`Invalid value for intMode, expected "number", "bigint" or "string", got ${JSON.stringify(intMode)}`);
}
if (uri.fragment !== undefined) {
throw new api_js_1.LibsqlError(`URL fragments are not supported: ${JSON.stringify("#" + uri.fragment)}`, "URL_INVALID");
}
if (isInMemoryMode) {
return {
scheme: "file",
tls: false,
path,
intMode,
concurrency,
syncUrl: config.syncUrl,
syncInterval: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
fetch: config.fetch,
authToken: undefined,
encryptionKey: undefined,
authority: undefined,
};
}
return {
scheme,
tls,
authority: uri.authority,
path,
authToken,
intMode,
concurrency,
encryptionKey: config.encryptionKey,
syncUrl: config.syncUrl,
syncInterval: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
fetch: config.fetch,
};
}
exports.expandConfig = expandConfig;

3
node_modules/@libsql/core/lib-cjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

125
node_modules/@libsql/core/lib-cjs/uri.js generated vendored Normal file
View File

@@ -0,0 +1,125 @@
"use strict";
// URI parser based on RFC 3986
// We can't use the standard `URL` object, because we want to support relative `file:` URLs like
// `file:relative/path/database.db`, which are not correct according to RFC 8089, which standardizes the
// `file` scheme.
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeBaseUrl = exports.parseUri = void 0;
const api_js_1 = require("./api.js");
function parseUri(text) {
const match = URI_RE.exec(text);
if (match === null) {
throw new api_js_1.LibsqlError(`The URL '${text}' is not in a valid format`, "URL_INVALID");
}
const groups = match.groups;
const scheme = groups["scheme"];
const authority = groups["authority"] !== undefined
? parseAuthority(groups["authority"])
: undefined;
const path = percentDecode(groups["path"]);
const query = groups["query"] !== undefined ? parseQuery(groups["query"]) : undefined;
const fragment = groups["fragment"] !== undefined
? percentDecode(groups["fragment"])
: undefined;
return { scheme, authority, path, query, fragment };
}
exports.parseUri = parseUri;
const URI_RE = (() => {
const SCHEME = "(?<scheme>[A-Za-z][A-Za-z.+-]*)";
const AUTHORITY = "(?<authority>[^/?#]*)";
const PATH = "(?<path>[^?#]*)";
const QUERY = "(?<query>[^#]*)";
const FRAGMENT = "(?<fragment>.*)";
return new RegExp(`^${SCHEME}:(//${AUTHORITY})?${PATH}(\\?${QUERY})?(#${FRAGMENT})?$`, "su");
})();
function parseAuthority(text) {
const match = AUTHORITY_RE.exec(text);
if (match === null) {
throw new api_js_1.LibsqlError("The authority part of the URL is not in a valid format", "URL_INVALID");
}
const groups = match.groups;
const host = percentDecode(groups["host_br"] ?? groups["host"]);
const port = groups["port"] ? parseInt(groups["port"], 10) : undefined;
const userinfo = groups["username"] !== undefined
? {
username: percentDecode(groups["username"]),
password: groups["password"] !== undefined
? percentDecode(groups["password"])
: undefined,
}
: undefined;
return { host, port, userinfo };
}
const AUTHORITY_RE = (() => {
return new RegExp(`^((?<username>[^:]*)(:(?<password>.*))?@)?((?<host>[^:\\[\\]]*)|(\\[(?<host_br>[^\\[\\]]*)\\]))(:(?<port>[0-9]*))?$`, "su");
})();
// Query string is parsed as application/x-www-form-urlencoded according to the Web URL standard:
// https://url.spec.whatwg.org/#urlencoded-parsing
function parseQuery(text) {
const sequences = text.split("&");
const pairs = [];
for (const sequence of sequences) {
if (sequence === "") {
continue;
}
let key;
let value;
const splitIdx = sequence.indexOf("=");
if (splitIdx < 0) {
key = sequence;
value = "";
}
else {
key = sequence.substring(0, splitIdx);
value = sequence.substring(splitIdx + 1);
}
pairs.push({
key: percentDecode(key.replaceAll("+", " ")),
value: percentDecode(value.replaceAll("+", " ")),
});
}
return { pairs };
}
function percentDecode(text) {
try {
return decodeURIComponent(text);
}
catch (e) {
if (e instanceof URIError) {
throw new api_js_1.LibsqlError(`URL component has invalid percent encoding: ${e}`, "URL_INVALID", undefined, e);
}
throw e;
}
}
function encodeBaseUrl(scheme, authority, path) {
if (authority === undefined) {
throw new api_js_1.LibsqlError(`URL with scheme ${JSON.stringify(scheme + ":")} requires authority (the "//" part)`, "URL_INVALID");
}
const schemeText = `${scheme}:`;
const hostText = encodeHost(authority.host);
const portText = encodePort(authority.port);
const userinfoText = encodeUserinfo(authority.userinfo);
const authorityText = `//${userinfoText}${hostText}${portText}`;
let pathText = path.split("/").map(encodeURIComponent).join("/");
if (pathText !== "" && !pathText.startsWith("/")) {
pathText = "/" + pathText;
}
return new URL(`${schemeText}${authorityText}${pathText}`);
}
exports.encodeBaseUrl = encodeBaseUrl;
function encodeHost(host) {
return host.includes(":") ? `[${encodeURI(host)}]` : encodeURI(host);
}
function encodePort(port) {
return port !== undefined ? `:${port}` : "";
}
function encodeUserinfo(userinfo) {
if (userinfo === undefined) {
return "";
}
const usernameText = encodeURIComponent(userinfo.username);
const passwordText = userinfo.password !== undefined
? `:${encodeURIComponent(userinfo.password)}`
: "";
return `${usernameText}${passwordText}@`;
}

60
node_modules/@libsql/core/lib-cjs/util.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResultSetImpl = exports.transactionModeToBegin = exports.supportedUrlLink = void 0;
const js_base64_1 = require("js-base64");
exports.supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
function transactionModeToBegin(mode) {
if (mode === "write") {
return "BEGIN IMMEDIATE";
}
else if (mode === "read") {
return "BEGIN TRANSACTION READONLY";
}
else if (mode === "deferred") {
return "BEGIN DEFERRED";
}
else {
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
}
}
exports.transactionModeToBegin = transactionModeToBegin;
class ResultSetImpl {
columns;
columnTypes;
rows;
rowsAffected;
lastInsertRowid;
constructor(columns, columnTypes, rows, rowsAffected, lastInsertRowid) {
this.columns = columns;
this.columnTypes = columnTypes;
this.rows = rows;
this.rowsAffected = rowsAffected;
this.lastInsertRowid = lastInsertRowid;
}
toJSON() {
return {
columns: this.columns,
columnTypes: this.columnTypes,
rows: this.rows.map(rowToJson),
rowsAffected: this.rowsAffected,
lastInsertRowid: this.lastInsertRowid !== undefined
? "" + this.lastInsertRowid
: null,
};
}
}
exports.ResultSetImpl = ResultSetImpl;
function rowToJson(row) {
return Array.prototype.map.call(row, valueToJson);
}
function valueToJson(value) {
if (typeof value === "bigint") {
return "" + value;
}
else if (value instanceof ArrayBuffer) {
return js_base64_1.Base64.fromUint8Array(new Uint8Array(value));
}
else {
return value;
}
}

449
node_modules/@libsql/core/lib-esm/api.d.ts generated vendored Normal file
View File

@@ -0,0 +1,449 @@
/** Configuration object for {@link createClient}. */
export interface Config {
/** The database URL.
*
* The client supports `libsql:`, `http:`/`https:`, `ws:`/`wss:` and `file:` URL. For more infomation,
* please refer to the project README:
*
* https://github.com/libsql/libsql-client-ts#supported-urls
*/
url: string;
/** Authentication token for the database. */
authToken?: string;
/** Encryption key for the database. */
encryptionKey?: string;
/** URL of a remote server to synchronize database with. */
syncUrl?: string;
/** Sync interval in seconds. */
syncInterval?: number;
/** Read your writes */
readYourWrites?: boolean;
/** Enable offline writes */
offline?: boolean;
/** Enables or disables TLS for `libsql:` URLs.
*
* By default, `libsql:` URLs use TLS. You can set this option to `false` to disable TLS.
*/
tls?: boolean;
/** How to convert SQLite integers to JavaScript values:
*
* - `"number"` (default): returns SQLite integers as JavaScript `number`-s (double precision floats).
* `number` cannot precisely represent integers larger than 2^53-1 in absolute value, so attempting to read
* larger integers will throw a `RangeError`.
* - `"bigint"`: returns SQLite integers as JavaScript `bigint`-s (arbitrary precision integers). Bigints can
* precisely represent all SQLite integers.
* - `"string"`: returns SQLite integers as strings.
*/
intMode?: IntMode;
/** Custom `fetch` function to use for the HTTP client.
*
* By default, the HTTP client uses `fetch` from the `@libsql/isomorphic-fetch` package, but you can pass
* your own function here. The argument to this function will be `Request` from
* `@libsql/isomorphic-fetch`, and it must return a promise that resolves to an object that is compatible
* with the Web `Response`.
*/
fetch?: Function;
/** Concurrency limit.
*
* By default, the client performs up to 20 concurrent requests. You can set this option to a higher
* number to increase the concurrency limit or set it to 0 to disable concurrency limits completely.
*/
concurrency?: number | undefined;
}
/** Representation of integers from database as JavaScript values. See {@link Config.intMode}. */
export type IntMode = "number" | "bigint" | "string";
/** Client object for a remote or local database.
*
* After you are done with the client, you **should** close it by calling {@link close}.
*/
export interface Client {
/** Execute a single SQL statement.
*
* Every statement executed with this method is executed in its own logical database connection. If you
* want to execute a group of statements in a transaction, use the {@link batch} or the {@link
* transaction} methods.
*
* ```javascript
* // execute a statement without arguments
* const rs = await client.execute("SELECT * FROM books");
*
* // execute a statement with positional arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE author = ?",
* args: ["Jane Austen"],
* });
*
* // execute a statement with named arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE published_at > $year",
* args: {year: 1719},
* });
* ```
*/
execute(stmt: InStatement): Promise<ResultSet>;
execute(sql: string, args?: InArgs): Promise<ResultSet>;
/** Execute a batch of SQL statements in a transaction.
*
* The batch is executed in its own logical database connection and the statements are wrapped in a
* transaction. This ensures that the batch is applied atomically: either all or no changes are applied.
*
* The `mode` parameter selects the transaction mode for the batch; please see {@link TransactionMode} for
* details. The default transaction mode is `"deferred"`.
*
* If any of the statements in the batch fails with an error, the batch is aborted, the transaction is
* rolled back and the returned promise is rejected.
*
* This method provides non-interactive transactions. If you need interactive transactions, please use the
* {@link transaction} method.
*
* ```javascript
* const rss = await client.batch([
* // batch statement without arguments
* "DELETE FROM books WHERE name LIKE '%Crusoe'",
*
* // batch statement with positional arguments
* {
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
* args: ["First Impressions", "Jane Austen", 1813],
* },
*
* // batch statement with named arguments
* {
* sql: "UPDATE books SET name = $new WHERE name = $old",
* args: {old: "First Impressions", new: "Pride and Prejudice"},
* },
* ], "write");
* ```
*/
batch(stmts: Array<InStatement | [string, InArgs?]>, mode?: TransactionMode): Promise<Array<ResultSet>>;
/** Execute a batch of SQL statements in a transaction with PRAGMA foreign_keys=off; before and PRAGMA foreign_keys=on; after.
*
* The batch is executed in its own logical database connection and the statements are wrapped in a
* transaction. This ensures that the batch is applied atomically: either all or no changes are applied.
*
* The transaction mode is `"deferred"`.
*
* If any of the statements in the batch fails with an error, the batch is aborted, the transaction is
* rolled back and the returned promise is rejected.
*
* ```javascript
* const rss = await client.migrate([
* // statement without arguments
* "CREATE TABLE test (a INT)",
*
* // statement with positional arguments
* {
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
* args: ["First Impressions", "Jane Austen", 1813],
* },
*
* // statement with named arguments
* {
* sql: "UPDATE books SET name = $new WHERE name = $old",
* args: {old: "First Impressions", new: "Pride and Prejudice"},
* },
* ]);
* ```
*/
migrate(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
/** Start an interactive transaction.
*
* Interactive transactions allow you to interleave execution of SQL statements with your application
* logic. They can be used if the {@link batch} method is too restrictive, but please note that
* interactive transactions have higher latency.
*
* The `mode` parameter selects the transaction mode for the interactive transaction; please see {@link
* TransactionMode} for details. The default transaction mode is `"deferred"`.
*
* You **must** make sure that the returned {@link Transaction} object is closed, by calling {@link
* Transaction.close}, {@link Transaction.commit} or {@link Transaction.rollback}. The best practice is
* to call {@link Transaction.close} in a `finally` block, as follows:
*
* ```javascript
* const transaction = client.transaction("write");
* try {
* // do some operations with the transaction here
* await transaction.execute({
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
* args: ["First Impressions", "Jane Austen"],
* });
* await transaction.execute({
* sql: "UPDATE books SET name = ? WHERE name = ?",
* args: ["Pride and Prejudice", "First Impressions"],
* });
*
* // if all went well, commit the transaction
* await transaction.commit();
* } finally {
* // make sure to close the transaction, even if an exception was thrown
* transaction.close();
* }
* ```
*/
transaction(mode?: TransactionMode): Promise<Transaction>;
/** Start an interactive transaction in `"write"` mode.
*
* Please see {@link transaction} for details.
*
* @deprecated Please specify the `mode` explicitly. The default `"write"` will be removed in the next
* major release.
*/
transaction(): Promise<Transaction>;
/** Execute a sequence of SQL statements separated by semicolons.
*
* The statements are executed sequentially on a new logical database connection. If a statement fails,
* further statements are not executed and this method throws an error. All results from the statements
* are ignored.
*
* We do not wrap the statements in a transaction, but the SQL can contain explicit transaction-control
* statements such as `BEGIN` and `COMMIT`.
*
* This method is intended to be used with existing SQL scripts, such as migrations or small database
* dumps. If you want to execute a sequence of statements programmatically, please use {@link batch}
* instead.
*
* ```javascript
* await client.executeMultiple(`
* CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT NOT NULL, author_id INTEGER NOT NULL);
* CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
* `);
* ```
*/
executeMultiple(sql: string): Promise<void>;
sync(): Promise<Replicated>;
/** Close the client and release resources.
*
* This method closes the client (aborting any operations that are currently in progress) and releases any
* resources associated with the client (such as a WebSocket connection).
*/
close(): void;
/** Reconnect after the client has been closed.
*/
reconnect(): void;
/** Is the client closed?
*
* This is set to `true` after a call to {@link close} or if the client encounters an unrecoverable
* error.
*/
closed: boolean;
/** Which protocol does the client use?
*
* - `"http"` if the client connects over HTTP
* - `"ws"` if the client connects over WebSockets
* - `"file"` if the client works with a local file
*/
protocol: string;
}
/** Interactive transaction.
*
* A transaction groups multiple SQL statements together, so that they are applied atomically: either all
* changes are applied, or none are. Other SQL statements on the database (including statements executed on
* the same {@link Client} object outside of this transaction) will not see any changes from the transaction
* until the transaction is committed by calling {@link commit}. You can also use {@link rollback} to abort
* the transaction and roll back the changes.
*
* You **must** make sure that the {@link Transaction} object is closed, by calling {@link close}, {@link
* commit} or {@link rollback}. The best practice is to call {@link close} in a `finally` block, as follows:
*
* ```javascript
* const transaction = client.transaction("write");
* try {
* // do some operations with the transaction here
* await transaction.execute({
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
* args: ["First Impressions", "Jane Austen"],
* });
* await transaction.execute({
* sql: "UPDATE books SET name = ? WHERE name = ?",
* args: ["Pride and Prejudice", "First Impressions"],
* });
*
* // if all went well, commit the transaction
* await transaction.commit();
* } finally {
* // make sure to close the transaction, even if an exception was thrown
* transaction.close();
* }
* ```
*/
export interface Transaction {
/** Execute an SQL statement in this transaction.
*
* If the statement makes any changes to the database, these changes won't be visible to statements
* outside of this transaction until you call {@link rollback}.
*
* ```javascript
* await transaction.execute({
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
* args: ["First Impressions", "Jane Austen"],
* });
* ```
*/
execute(stmt: InStatement): Promise<ResultSet>;
/** Execute a batch of SQL statements in this transaction.
*
* If any of the statements in the batch fails with an error, further statements are not executed and the
* returned promise is rejected with an error, but the transaction is not rolled back.
*/
batch(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
/** Execute a sequence of SQL statements separated by semicolons.
*
* The statements are executed sequentially in the transaction. If a statement fails, further statements
* are not executed and this method throws an error, but the transaction won't be rolled back. All results
* from the statements are ignored.
*
* This method is intended to be used with existing SQL scripts, such as migrations or small database
* dumps. If you want to execute statements programmatically, please use {@link batch} instead.
*/
executeMultiple(sql: string): Promise<void>;
/** Roll back any changes from this transaction.
*
* This method closes the transaction and undoes any changes done by the previous SQL statements on this
* transaction. You cannot call this method after calling {@link commit}, though.
*/
rollback(): Promise<void>;
/** Commit changes from this transaction to the database.
*
* This method closes the transaction and applies all changes done by the previous SQL statement on this
* transaction. Once the returned promise is resolved successfully, the database guarantees that the
* changes were applied.
*/
commit(): Promise<void>;
/** Close the transaction.
*
* This method closes the transaction and releases any resources associated with the transaction. If the
* transaction is already closed (perhaps by a previous call to {@link commit} or {@link rollback}), then
* this method does nothing.
*
* If the transaction wasn't already committed by calling {@link commit}, the transaction is rolled
* back.
*/
close(): void;
/** Is the transaction closed?
*
* This is set to `true` after a call to {@link close}, {@link commit} or {@link rollback}, or if we
* encounter an unrecoverable error.
*/
closed: boolean;
}
/** Transaction mode.
*
* The client supports multiple modes for transactions:
*
* - `"write"` is a read-write transaction, started with `BEGIN IMMEDIATE`. This transaction mode supports
* both read statements (`SELECT`) and write statements (`INSERT`, `UPDATE`, `CREATE TABLE`, etc). The libSQL
* server cannot process multiple write transactions concurrently, so if there is another write transaction
* already started, our transaction will wait in a queue before it can begin.
*
* - `"read"` is a read-only transaction, started with `BEGIN TRANSACTION READONLY` (a libSQL extension). This
* transaction mode supports only reads (`SELECT`) and will not accept write statements. The libSQL server can
* handle multiple read transactions at the same time, so we don't need to wait for other transactions to
* complete. A read-only transaction can also be executed on a local replica, so it provides lower latency.
*
* - `"deferred"` is a transaction started with `BEGIN DEFERRED`, which starts as a read transaction, but the
* first write statement will try to upgrade it to a write transaction. However, this upgrade may fail if
* there already is a write transaction executing on the server, so you should be ready to handle these
* failures.
*
* If your transaction includes only read statements, `"read"` is always preferred over `"deferred"` or
* `"write"`, because `"read"` transactions can be executed more efficiently and don't block other
* transactions.
*
* If your transaction includes both read and write statements, you should be using the `"write"` mode most of
* the time. Use the `"deferred"` mode only if you prefer to fail the write transaction instead of waiting for
* the previous write transactions to complete.
*/
export type TransactionMode = "write" | "read" | "deferred";
/** Result of executing an SQL statement.
*
* ```javascript
* const rs = await client.execute("SELECT name, title FROM books");
* console.log(`Found ${rs.rows.length} books`);
* for (const row in rs.rows) {
* console.log(`Book ${row[0]} by ${row[1]}`);
* }
*
* const rs = await client.execute("DELETE FROM books WHERE author = 'Jane Austen'");
* console.log(`Deleted ${rs.rowsAffected} books`);
* ```
*/
export interface ResultSet {
/** Names of columns.
*
* Names of columns can be defined using the `AS` keyword in SQL:
*
* ```sql
* SELECT author AS author, COUNT(*) AS count FROM books GROUP BY author
* ```
*/
columns: Array<string>;
/** Types of columns.
*
* The types are currently shown for types declared in a SQL table. For
* column types of function calls, for example, an empty string is
* returned.
*/
columnTypes: Array<string>;
/** Rows produced by the statement. */
rows: Array<Row>;
/** Number of rows that were affected by an UPDATE, INSERT or DELETE operation.
*
* This value is not specified for other SQL statements.
*/
rowsAffected: number;
/** ROWID of the last inserted row.
*
* This value is not specified if the SQL statement was not an INSERT or if the table was not a ROWID
* table.
*/
lastInsertRowid: bigint | undefined;
/** Converts the result set to JSON.
*
* This is used automatically by `JSON.stringify()`, but you can also call it explicitly.
*/
toJSON(): any;
}
/** Row returned from an SQL statement.
*
* The row object can be used as an `Array` or as an object:
*
* ```javascript
* const rs = await client.execute("SELECT name, title FROM books");
* for (const row in rs.rows) {
* // Get the value from column `name`
* console.log(row.name);
* // Get the value from second column (`title`)
* console.log(row[1]);
* }
* ```
*/
export interface Row {
/** Number of columns in this row.
*
* All rows in one {@link ResultSet} have the same number and names of columns.
*/
length: number;
/** Columns can be accessed like an array by numeric indexes. */
[index: number]: Value;
/** Columns can be accessed like an object by column names. */
[name: string]: Value;
}
export type Replicated = {
frame_no: number;
frames_synced: number;
} | undefined;
export type Value = null | string | number | bigint | ArrayBuffer;
export type InValue = Value | boolean | Uint8Array | Date;
export type InStatement = {
sql: string;
args?: InArgs;
} | string;
export type InArgs = Array<InValue> | Record<string, InValue>;
/** Error thrown by the client. */
export declare class LibsqlError extends Error {
/** Machine-readable error code. */
code: string;
/** Raw numeric error code */
rawCode?: number;
constructor(message: string, code: string, rawCode?: number, cause?: Error);
}

16
node_modules/@libsql/core/lib-esm/api.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
/** Error thrown by the client. */
export class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, rawCode, cause) {
if (code !== undefined) {
message = `${code}: ${message}`;
}
super(message, { cause });
this.code = code;
this.rawCode = rawCode;
this.name = "LibsqlError";
}
}

20
node_modules/@libsql/core/lib-esm/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import type { Config, IntMode } from "./api.js";
import type { Authority } from "./uri.js";
export interface ExpandedConfig {
scheme: ExpandedScheme;
tls: boolean;
authority: Authority | undefined;
path: string;
authToken: string | undefined;
encryptionKey: string | undefined;
syncUrl: string | undefined;
syncInterval: number | undefined;
readYourWrites: boolean | undefined;
offline: boolean | undefined;
intMode: IntMode;
fetch: Function | undefined;
concurrency: number;
}
export type ExpandedScheme = "wss" | "ws" | "https" | "http" | "file";
export declare function isInMemoryConfig(config: ExpandedConfig): boolean;
export declare function expandConfig(config: Readonly<Config>, preferHttp: boolean): ExpandedConfig;

136
node_modules/@libsql/core/lib-esm/config.js generated vendored Normal file
View File

@@ -0,0 +1,136 @@
import { LibsqlError } from "./api.js";
import { parseUri } from "./uri.js";
import { supportedUrlLink } from "./util.js";
const inMemoryMode = ":memory:";
export function isInMemoryConfig(config) {
return (config.scheme === "file" &&
(config.path === ":memory:" || config.path.startsWith(":memory:?")));
}
export function expandConfig(config, preferHttp) {
if (typeof config !== "object") {
// produce a reasonable error message in the common case where users type
// `createClient("libsql://...")` instead of `createClient({url: "libsql://..."})`
throw new TypeError(`Expected client configuration as object, got ${typeof config}`);
}
let { url, authToken, tls, intMode, concurrency } = config;
// fill simple defaults right here
concurrency = Math.max(0, concurrency || 20);
intMode ??= "number";
let connectionQueryParams = []; // recognized query parameters which we sanitize through white list of valid key-value pairs
// convert plain :memory: url to URI format to make logic more uniform
if (url === inMemoryMode) {
url = "file::memory:";
}
// parse url parameters first and override config with update values
const uri = parseUri(url);
const originalUriScheme = uri.scheme.toLowerCase();
const isInMemoryMode = originalUriScheme === "file" &&
uri.path === inMemoryMode &&
uri.authority === undefined;
let queryParamsDef;
if (isInMemoryMode) {
queryParamsDef = {
cache: {
values: ["shared", "private"],
update: (key, value) => connectionQueryParams.push(`${key}=${value}`),
},
};
}
else {
queryParamsDef = {
tls: {
values: ["0", "1"],
update: (_, value) => (tls = value === "1"),
},
authToken: {
update: (_, value) => (authToken = value),
},
};
}
for (const { key, value } of uri.query?.pairs ?? []) {
if (!Object.hasOwn(queryParamsDef, key)) {
throw new LibsqlError(`Unsupported URL query parameter ${JSON.stringify(key)}`, "URL_PARAM_NOT_SUPPORTED");
}
const queryParamDef = queryParamsDef[key];
if (queryParamDef.values !== undefined &&
!queryParamDef.values.includes(value)) {
throw new LibsqlError(`Unknown value for the "${key}" query argument: ${JSON.stringify(value)}. Supported values are: [${queryParamDef.values.map((x) => '"' + x + '"').join(", ")}]`, "URL_INVALID");
}
if (queryParamDef.update !== undefined) {
queryParamDef?.update(key, value);
}
}
// fill complex defaults & validate config
const connectionQueryParamsString = connectionQueryParams.length === 0
? ""
: `?${connectionQueryParams.join("&")}`;
const path = uri.path + connectionQueryParamsString;
let scheme;
if (originalUriScheme === "libsql") {
if (tls === false) {
if (uri.authority?.port === undefined) {
throw new LibsqlError('A "libsql:" URL with ?tls=0 must specify an explicit port', "URL_INVALID");
}
scheme = preferHttp ? "http" : "ws";
}
else {
scheme = preferHttp ? "https" : "wss";
}
}
else {
scheme = originalUriScheme;
}
if (scheme === "http" || scheme === "ws") {
tls ??= false;
}
else {
tls ??= true;
}
if (scheme !== "http" &&
scheme !== "ws" &&
scheme !== "https" &&
scheme !== "wss" &&
scheme !== "file") {
throw new LibsqlError('The client supports only "libsql:", "wss:", "ws:", "https:", "http:" and "file:" URLs, ' +
`got ${JSON.stringify(uri.scheme + ":")}. ` +
`For more information, please read ${supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
}
if (intMode !== "number" && intMode !== "bigint" && intMode !== "string") {
throw new TypeError(`Invalid value for intMode, expected "number", "bigint" or "string", got ${JSON.stringify(intMode)}`);
}
if (uri.fragment !== undefined) {
throw new LibsqlError(`URL fragments are not supported: ${JSON.stringify("#" + uri.fragment)}`, "URL_INVALID");
}
if (isInMemoryMode) {
return {
scheme: "file",
tls: false,
path,
intMode,
concurrency,
syncUrl: config.syncUrl,
syncInterval: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
fetch: config.fetch,
authToken: undefined,
encryptionKey: undefined,
authority: undefined,
};
}
return {
scheme,
tls,
authority: uri.authority,
path,
authToken,
intMode,
concurrency,
encryptionKey: config.encryptionKey,
syncUrl: config.syncUrl,
syncInterval: config.syncInterval,
readYourWrites: config.readYourWrites,
offline: config.offline,
fetch: config.fetch,
};
}

30
node_modules/@libsql/core/lib-esm/uri.d.ts generated vendored Normal file
View File

@@ -0,0 +1,30 @@
/// <reference types="node" />
export interface Uri {
scheme: string;
authority: Authority | undefined;
path: string;
query: Query | undefined;
fragment: string | undefined;
}
export interface HierPart {
authority: Authority | undefined;
path: string;
}
export interface Authority {
host: string;
port: number | undefined;
userinfo: Userinfo | undefined;
}
export interface Userinfo {
username: string;
password: string | undefined;
}
export interface Query {
pairs: Array<KeyValue>;
}
export interface KeyValue {
key: string;
value: string;
}
export declare function parseUri(text: string): Uri;
export declare function encodeBaseUrl(scheme: string, authority: Authority | undefined, path: string): URL;

120
node_modules/@libsql/core/lib-esm/uri.js generated vendored Normal file
View File

@@ -0,0 +1,120 @@
// URI parser based on RFC 3986
// We can't use the standard `URL` object, because we want to support relative `file:` URLs like
// `file:relative/path/database.db`, which are not correct according to RFC 8089, which standardizes the
// `file` scheme.
import { LibsqlError } from "./api.js";
export function parseUri(text) {
const match = URI_RE.exec(text);
if (match === null) {
throw new LibsqlError(`The URL '${text}' is not in a valid format`, "URL_INVALID");
}
const groups = match.groups;
const scheme = groups["scheme"];
const authority = groups["authority"] !== undefined
? parseAuthority(groups["authority"])
: undefined;
const path = percentDecode(groups["path"]);
const query = groups["query"] !== undefined ? parseQuery(groups["query"]) : undefined;
const fragment = groups["fragment"] !== undefined
? percentDecode(groups["fragment"])
: undefined;
return { scheme, authority, path, query, fragment };
}
const URI_RE = (() => {
const SCHEME = "(?<scheme>[A-Za-z][A-Za-z.+-]*)";
const AUTHORITY = "(?<authority>[^/?#]*)";
const PATH = "(?<path>[^?#]*)";
const QUERY = "(?<query>[^#]*)";
const FRAGMENT = "(?<fragment>.*)";
return new RegExp(`^${SCHEME}:(//${AUTHORITY})?${PATH}(\\?${QUERY})?(#${FRAGMENT})?$`, "su");
})();
function parseAuthority(text) {
const match = AUTHORITY_RE.exec(text);
if (match === null) {
throw new LibsqlError("The authority part of the URL is not in a valid format", "URL_INVALID");
}
const groups = match.groups;
const host = percentDecode(groups["host_br"] ?? groups["host"]);
const port = groups["port"] ? parseInt(groups["port"], 10) : undefined;
const userinfo = groups["username"] !== undefined
? {
username: percentDecode(groups["username"]),
password: groups["password"] !== undefined
? percentDecode(groups["password"])
: undefined,
}
: undefined;
return { host, port, userinfo };
}
const AUTHORITY_RE = (() => {
return new RegExp(`^((?<username>[^:]*)(:(?<password>.*))?@)?((?<host>[^:\\[\\]]*)|(\\[(?<host_br>[^\\[\\]]*)\\]))(:(?<port>[0-9]*))?$`, "su");
})();
// Query string is parsed as application/x-www-form-urlencoded according to the Web URL standard:
// https://url.spec.whatwg.org/#urlencoded-parsing
function parseQuery(text) {
const sequences = text.split("&");
const pairs = [];
for (const sequence of sequences) {
if (sequence === "") {
continue;
}
let key;
let value;
const splitIdx = sequence.indexOf("=");
if (splitIdx < 0) {
key = sequence;
value = "";
}
else {
key = sequence.substring(0, splitIdx);
value = sequence.substring(splitIdx + 1);
}
pairs.push({
key: percentDecode(key.replaceAll("+", " ")),
value: percentDecode(value.replaceAll("+", " ")),
});
}
return { pairs };
}
function percentDecode(text) {
try {
return decodeURIComponent(text);
}
catch (e) {
if (e instanceof URIError) {
throw new LibsqlError(`URL component has invalid percent encoding: ${e}`, "URL_INVALID", undefined, e);
}
throw e;
}
}
export function encodeBaseUrl(scheme, authority, path) {
if (authority === undefined) {
throw new LibsqlError(`URL with scheme ${JSON.stringify(scheme + ":")} requires authority (the "//" part)`, "URL_INVALID");
}
const schemeText = `${scheme}:`;
const hostText = encodeHost(authority.host);
const portText = encodePort(authority.port);
const userinfoText = encodeUserinfo(authority.userinfo);
const authorityText = `//${userinfoText}${hostText}${portText}`;
let pathText = path.split("/").map(encodeURIComponent).join("/");
if (pathText !== "" && !pathText.startsWith("/")) {
pathText = "/" + pathText;
}
return new URL(`${schemeText}${authorityText}${pathText}`);
}
function encodeHost(host) {
return host.includes(":") ? `[${encodeURI(host)}]` : encodeURI(host);
}
function encodePort(port) {
return port !== undefined ? `:${port}` : "";
}
function encodeUserinfo(userinfo) {
if (userinfo === undefined) {
return "";
}
const usernameText = encodeURIComponent(userinfo.username);
const passwordText = userinfo.password !== undefined
? `:${encodeURIComponent(userinfo.password)}`
: "";
return `${usernameText}${passwordText}@`;
}

12
node_modules/@libsql/core/lib-esm/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import { ResultSet, Row, TransactionMode } from "./api";
export declare const supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
export declare function transactionModeToBegin(mode: TransactionMode): string;
export declare class ResultSetImpl implements ResultSet {
columns: Array<string>;
columnTypes: Array<string>;
rows: Array<Row>;
rowsAffected: number;
lastInsertRowid: bigint | undefined;
constructor(columns: Array<string>, columnTypes: Array<string>, rows: Array<Row>, rowsAffected: number, lastInsertRowid: bigint | undefined);
toJSON(): any;
}

55
node_modules/@libsql/core/lib-esm/util.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
import { Base64 } from "js-base64";
export const supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
export function transactionModeToBegin(mode) {
if (mode === "write") {
return "BEGIN IMMEDIATE";
}
else if (mode === "read") {
return "BEGIN TRANSACTION READONLY";
}
else if (mode === "deferred") {
return "BEGIN DEFERRED";
}
else {
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
}
}
export class ResultSetImpl {
columns;
columnTypes;
rows;
rowsAffected;
lastInsertRowid;
constructor(columns, columnTypes, rows, rowsAffected, lastInsertRowid) {
this.columns = columns;
this.columnTypes = columnTypes;
this.rows = rows;
this.rowsAffected = rowsAffected;
this.lastInsertRowid = lastInsertRowid;
}
toJSON() {
return {
columns: this.columns,
columnTypes: this.columnTypes,
rows: this.rows.map(rowToJson),
rowsAffected: this.rowsAffected,
lastInsertRowid: this.lastInsertRowid !== undefined
? "" + this.lastInsertRowid
: null,
};
}
}
function rowToJson(row) {
return Array.prototype.map.call(row, valueToJson);
}
function valueToJson(value) {
if (typeof value === "bigint") {
return "" + value;
}
else if (value instanceof ArrayBuffer) {
return Base64.fromUint8Array(new Uint8Array(value));
}
else {
return value;
}
}

91
node_modules/@libsql/core/package.json generated vendored Normal file
View File

@@ -0,0 +1,91 @@
{
"name": "@libsql/core",
"version": "0.15.15",
"keywords": [
"libsql",
"database",
"sqlite",
"serverless",
"vercel",
"netlify",
"lambda"
],
"description": "libSQL driver for TypeScript and JavaScript",
"repository": {
"type": "git",
"url": "git+https://github.com/libsql/libsql-client-ts",
"directory": "packages/libsql-core"
},
"authors": [
"Jan Špaček <honza@chiselstrike.com>",
"Pekka Enberg <penberg@chiselstrike.com>",
"Jan Plhak <jp@chiselstrike.com>"
],
"license": "MIT",
"type": "module",
"exports": {
"./api": {
"types": "./lib-esm/api.d.ts",
"import": "./lib-esm/api.js",
"require": "./lib-cjs/api.js"
},
"./config": {
"types": "./lib-esm/config.d.ts",
"import": "./lib-esm/config.js",
"require": "./lib-cjs/config.js"
},
"./uri": {
"types": "./lib-esm/uri.d.ts",
"import": "./lib-esm/uri.js",
"require": "./lib-cjs/uri.js"
},
"./util": {
"types": "./lib-esm/util.d.ts",
"import": "./lib-esm/util.js",
"require": "./lib-cjs/util.js"
}
},
"typesVersions": {
"*": {
"api": [
"./lib-esm/api.d.ts"
],
"config": [
"./lib-esm/config.d.ts"
],
"uri": [
"./lib-esm/uri.d.ts"
],
"util": [
"./lib-esm/util.d.ts"
]
}
},
"files": [
"lib-cjs/**",
"lib-esm/**"
],
"scripts": {
"prepublishOnly": "npm run build",
"prebuild": "rm -rf ./lib-cjs ./lib-esm",
"build": "npm run build:cjs && npm run build:esm",
"build:cjs": "tsc -p tsconfig.build-cjs.json",
"build:esm": "tsc -p tsconfig.build-esm.json",
"format:check": "prettier --check .",
"postbuild": "cp package-cjs.json ./lib-cjs/package.json",
"test": "jest --runInBand",
"typecheck": "tsc --noEmit",
"typedoc": "rm -rf ./docs && typedoc"
},
"dependencies": {
"js-base64": "^3.7.5"
},
"devDependencies": {
"@types/jest": "^29.2.5",
"@types/node": "^18.15.5",
"jest": "^29.3.1",
"ts-jest": "^29.0.5",
"typedoc": "^0.23.28",
"typescript": "^4.9.4"
}
}

3
node_modules/@libsql/darwin-arm64/README.md generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# `@libsql/darwin-arm64`
Prebuilt binary package for `libsql` on `darwin-arm64`.

BIN
node_modules/@libsql/darwin-arm64/index.node generated vendored Executable file

Binary file not shown.

36
node_modules/@libsql/darwin-arm64/package.json generated vendored Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "@libsql/darwin-arm64",
"description": "Prebuilt binary package for `libsql` on `darwin-arm64`.",
"version": "0.5.29",
"os": [
"darwin"
],
"cpu": [
"arm64"
],
"main": "index.node",
"files": [
"index.node"
],
"neon": {
"type": "binary",
"rust": "aarch64-apple-darwin",
"node": "darwin-arm64",
"platform": "darwin",
"arch": "arm64",
"abi": null
},
"author": "Pekka Enberg <penberg@iki.fi>",
"repository": {
"type": "git",
"url": "git+https://github.com/tursodatabase/libsql-js.git"
},
"keywords": [
"libsql"
],
"bugs": {
"url": "https://github.com/tursodatabase/libsql-js/issues"
},
"homepage": "https://github.com/tursodatabase/libsql-js",
"license": "MIT"
}

20
node_modules/@libsql/hrana-client/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright 2023 the sqld authors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

59
node_modules/@libsql/hrana-client/README.md generated vendored Normal file
View File

@@ -0,0 +1,59 @@
# Hrana client for TypeScript
**[API docs][docs] | [Github][github] | [npm][npm]**
[docs]: https://libsql.org/hrana-client-ts/
[github]: https://github.com/libsql/hrana-client-ts/
[npm]: https://www.npmjs.com/package/@libsql/hrana-client
This package implements a Hrana client for TypeScript. Hrana is the protocol for connecting to sqld using WebSocket or HTTP.
> This package is intended mostly for internal use. Consider using the [`@libsql/client`][libsql-client] package, which will use Hrana automatically.
[libsql-client]: https://www.npmjs.com/package/@libsql/client
## Usage
```typescript
import * as hrana from "@libsql/hrana-client";
// Open a `hrana.Client`, which works like a connection pool in standard SQL
// databases.
const url = process.env.URL ?? "ws://localhost:8080"; // Address of the sqld server
const jwt = process.env.JWT; // JWT token for authentication
// Here we are using Hrana over WebSocket:
const client = hrana.openWs(url, jwt);
// But we can also use Hrana over HTTP:
// const client = hrana.openHttp(url, jwt);
// Open a `hrana.Stream`, which is an interactive SQL stream. This corresponds
// to a "connection" from other SQL databases
const stream = client.openStream();
// Fetch all rows returned by a SQL statement
const books = await stream.query("SELECT title, year FROM book WHERE author = 'Jane Austen'");
// The rows are returned in an Array...
for (const book of books.rows) {
// every returned row works as an array (`book[1]`) and as an object (`book.year`)
console.log(`${book.title} from ${book.year}`);
}
// Fetch a single row
const book = await stream.queryRow("SELECT title, MIN(year) FROM book");
if (book.row !== undefined) {
console.log(`The oldest book is ${book.row.title} from year ${book.row[1]}`);
}
// Fetch a single value, using a bound parameter
const year = await stream.queryValue(["SELECT MAX(year) FROM book WHERE author = ?", ["Jane Austen"]]);
if (year.value !== undefined) {
console.log(`Last book from Jane Austen was published in ${year.value}`);
}
// Execute a statement that does not return any rows
const res = await stream.run(["DELETE FROM book WHERE author = ?", ["J. K. Rowling"]])
console.log(`${res.affectedRowCount} books have been cancelled`);
// When you are done, remember to close the client
client.close();
```

277
node_modules/@libsql/hrana-client/lib-cjs/batch.js generated vendored Normal file
View File

@@ -0,0 +1,277 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BatchCond = exports.BatchStep = exports.Batch = void 0;
const errors_js_1 = require("./errors.js");
const result_js_1 = require("./result.js");
const stmt_js_1 = require("./stmt.js");
const util_js_1 = require("./util.js");
/** A builder for creating a batch and executing it on the server. */
class Batch {
/** @private */
_stream;
#useCursor;
/** @private */
_steps;
#executed;
/** @private */
constructor(stream, useCursor) {
this._stream = stream;
this.#useCursor = useCursor;
this._steps = [];
this.#executed = false;
}
/** Return a builder for adding a step to the batch. */
step() {
return new BatchStep(this);
}
/** Execute the batch. */
execute() {
if (this.#executed) {
throw new errors_js_1.MisuseError("This batch has already been executed");
}
this.#executed = true;
const batch = {
steps: this._steps.map((step) => step.proto),
};
if (this.#useCursor) {
return executeCursor(this._stream, this._steps, batch);
}
else {
return executeRegular(this._stream, this._steps, batch);
}
}
}
exports.Batch = Batch;
function executeRegular(stream, steps, batch) {
return stream._batch(batch).then((result) => {
for (let step = 0; step < steps.length; ++step) {
const stepResult = result.stepResults.get(step);
const stepError = result.stepErrors.get(step);
steps[step].callback(stepResult, stepError);
}
});
}
async function executeCursor(stream, steps, batch) {
const cursor = await stream._openCursor(batch);
try {
let nextStep = 0;
let beginEntry = undefined;
let rows = [];
for (;;) {
const entry = await cursor.next();
if (entry === undefined) {
break;
}
if (entry.type === "step_begin") {
if (entry.step < nextStep || entry.step >= steps.length) {
throw new errors_js_1.ProtoError("Server produced StepBeginEntry for unexpected step");
}
else if (beginEntry !== undefined) {
throw new errors_js_1.ProtoError("Server produced StepBeginEntry before terminating previous step");
}
for (let step = nextStep; step < entry.step; ++step) {
steps[step].callback(undefined, undefined);
}
nextStep = entry.step + 1;
beginEntry = entry;
rows = [];
}
else if (entry.type === "step_end") {
if (beginEntry === undefined) {
throw new errors_js_1.ProtoError("Server produced StepEndEntry but no step is active");
}
const stmtResult = {
cols: beginEntry.cols,
rows,
affectedRowCount: entry.affectedRowCount,
lastInsertRowid: entry.lastInsertRowid,
};
steps[beginEntry.step].callback(stmtResult, undefined);
beginEntry = undefined;
rows = [];
}
else if (entry.type === "step_error") {
if (beginEntry === undefined) {
if (entry.step >= steps.length) {
throw new errors_js_1.ProtoError("Server produced StepErrorEntry for unexpected step");
}
for (let step = nextStep; step < entry.step; ++step) {
steps[step].callback(undefined, undefined);
}
}
else {
if (entry.step !== beginEntry.step) {
throw new errors_js_1.ProtoError("Server produced StepErrorEntry for unexpected step");
}
beginEntry = undefined;
rows = [];
}
steps[entry.step].callback(undefined, entry.error);
nextStep = entry.step + 1;
}
else if (entry.type === "row") {
if (beginEntry === undefined) {
throw new errors_js_1.ProtoError("Server produced RowEntry but no step is active");
}
rows.push(entry.row);
}
else if (entry.type === "error") {
throw (0, result_js_1.errorFromProto)(entry.error);
}
else if (entry.type === "none") {
throw new errors_js_1.ProtoError("Server produced unrecognized CursorEntry");
}
else {
throw (0, util_js_1.impossible)(entry, "Impossible CursorEntry");
}
}
if (beginEntry !== undefined) {
throw new errors_js_1.ProtoError("Server closed Cursor before terminating active step");
}
for (let step = nextStep; step < steps.length; ++step) {
steps[step].callback(undefined, undefined);
}
}
finally {
cursor.close();
}
}
/** A builder for adding a step to the batch. */
class BatchStep {
/** @private */
_batch;
#conds;
/** @private */
_index;
/** @private */
constructor(batch) {
this._batch = batch;
this.#conds = [];
this._index = undefined;
}
/** Add the condition that needs to be satisfied to execute the statement. If you use this method multiple
* times, we join the conditions with a logical AND. */
condition(cond) {
this.#conds.push(cond._proto);
return this;
}
/** Add a statement that returns rows. */
query(stmt) {
return this.#add(stmt, true, result_js_1.rowsResultFromProto);
}
/** Add a statement that returns at most a single row. */
queryRow(stmt) {
return this.#add(stmt, true, result_js_1.rowResultFromProto);
}
/** Add a statement that returns at most a single value. */
queryValue(stmt) {
return this.#add(stmt, true, result_js_1.valueResultFromProto);
}
/** Add a statement without returning rows. */
run(stmt) {
return this.#add(stmt, false, result_js_1.stmtResultFromProto);
}
#add(inStmt, wantRows, fromProto) {
if (this._index !== undefined) {
throw new errors_js_1.MisuseError("This BatchStep has already been added to the batch");
}
const stmt = (0, stmt_js_1.stmtToProto)(this._batch._stream._sqlOwner(), inStmt, wantRows);
let condition;
if (this.#conds.length === 0) {
condition = undefined;
}
else if (this.#conds.length === 1) {
condition = this.#conds[0];
}
else {
condition = { type: "and", conds: this.#conds.slice() };
}
const proto = { stmt, condition };
return new Promise((outputCallback, errorCallback) => {
const callback = (stepResult, stepError) => {
if (stepResult !== undefined && stepError !== undefined) {
errorCallback(new errors_js_1.ProtoError("Server returned both result and error"));
}
else if (stepError !== undefined) {
errorCallback((0, result_js_1.errorFromProto)(stepError));
}
else if (stepResult !== undefined) {
outputCallback(fromProto(stepResult, this._batch._stream.intMode));
}
else {
outputCallback(undefined);
}
};
this._index = this._batch._steps.length;
this._batch._steps.push({ proto, callback });
});
}
}
exports.BatchStep = BatchStep;
class BatchCond {
/** @private */
_batch;
/** @private */
_proto;
/** @private */
constructor(batch, proto) {
this._batch = batch;
this._proto = proto;
}
/** Create a condition that evaluates to true when the given step executes successfully.
*
* If the given step fails error or is skipped because its condition evaluated to false, this
* condition evaluates to false.
*/
static ok(step) {
return new BatchCond(step._batch, { type: "ok", step: stepIndex(step) });
}
/** Create a condition that evaluates to true when the given step fails.
*
* If the given step succeeds or is skipped because its condition evaluated to false, this condition
* evaluates to false.
*/
static error(step) {
return new BatchCond(step._batch, { type: "error", step: stepIndex(step) });
}
/** Create a condition that is a logical negation of another condition.
*/
static not(cond) {
return new BatchCond(cond._batch, { type: "not", cond: cond._proto });
}
/** Create a condition that is a logical AND of other conditions.
*/
static and(batch, conds) {
for (const cond of conds) {
checkCondBatch(batch, cond);
}
return new BatchCond(batch, { type: "and", conds: conds.map(e => e._proto) });
}
/** Create a condition that is a logical OR of other conditions.
*/
static or(batch, conds) {
for (const cond of conds) {
checkCondBatch(batch, cond);
}
return new BatchCond(batch, { type: "or", conds: conds.map(e => e._proto) });
}
/** Create a condition that evaluates to true when the SQL connection is in autocommit mode (not inside an
* explicit transaction). This requires protocol version 3 or higher.
*/
static isAutocommit(batch) {
batch._stream.client()._ensureVersion(3, "BatchCond.isAutocommit()");
return new BatchCond(batch, { type: "is_autocommit" });
}
}
exports.BatchCond = BatchCond;
function stepIndex(step) {
if (step._index === undefined) {
throw new errors_js_1.MisuseError("Cannot add a condition referencing a step that has not been added to the batch");
}
return step._index;
}
function checkCondBatch(expectedBatch, cond) {
if (cond._batch !== expectedBatch) {
throw new errors_js_1.MisuseError("Cannot mix BatchCond objects for different Batch objects");
}
}

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByteQueue = void 0;
class ByteQueue {
#array;
#shiftPos;
#pushPos;
constructor(initialCap) {
this.#array = new Uint8Array(new ArrayBuffer(initialCap));
this.#shiftPos = 0;
this.#pushPos = 0;
}
get length() {
return this.#pushPos - this.#shiftPos;
}
data() {
return this.#array.slice(this.#shiftPos, this.#pushPos);
}
push(chunk) {
this.#ensurePush(chunk.byteLength);
this.#array.set(chunk, this.#pushPos);
this.#pushPos += chunk.byteLength;
}
#ensurePush(pushLength) {
if (this.#pushPos + pushLength <= this.#array.byteLength) {
return;
}
const filledLength = this.#pushPos - this.#shiftPos;
if (filledLength + pushLength <= this.#array.byteLength &&
2 * this.#pushPos >= this.#array.byteLength) {
this.#array.copyWithin(0, this.#shiftPos, this.#pushPos);
}
else {
let newCap = this.#array.byteLength;
do {
newCap *= 2;
} while (filledLength + pushLength > newCap);
const newArray = new Uint8Array(new ArrayBuffer(newCap));
newArray.set(this.#array.slice(this.#shiftPos, this.#pushPos), 0);
this.#array = newArray;
}
this.#pushPos = filledLength;
this.#shiftPos = 0;
}
shift(length) {
this.#shiftPos += length;
}
}
exports.ByteQueue = ByteQueue;

17
node_modules/@libsql/hrana-client/lib-cjs/client.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Client = void 0;
/** A client for the Hrana protocol (a "database connection pool"). */
class Client {
/** @private */
constructor() {
this.intMode = "number";
}
/** Representation of integers returned from the database. See {@link IntMode}.
*
* This value is inherited by {@link Stream} objects created with {@link openStream}, but you can
* override the integer mode for every stream by setting {@link Stream.intMode} on the stream.
*/
intMode;
}
exports.Client = Client;

6
node_modules/@libsql/hrana-client/lib-cjs/cursor.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cursor = void 0;
class Cursor {
}
exports.Cursor = Cursor;

12
node_modules/@libsql/hrana-client/lib-cjs/describe.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.describeResultFromProto = void 0;
function describeResultFromProto(result) {
return {
paramNames: result.params.map((p) => p.name),
columns: result.cols,
isExplain: result.isExplain,
isReadonly: result.isReadonly,
};
}
exports.describeResultFromProto = describeResultFromProto;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeProtobufMessage = exports.readProtobufMessage = exports.writeJsonObject = exports.readJsonObject = void 0;
var decode_js_1 = require("./json/decode.js");
Object.defineProperty(exports, "readJsonObject", { enumerable: true, get: function () { return decode_js_1.readJsonObject; } });
var encode_js_1 = require("./json/encode.js");
Object.defineProperty(exports, "writeJsonObject", { enumerable: true, get: function () { return encode_js_1.writeJsonObject; } });
var decode_js_2 = require("./protobuf/decode.js");
Object.defineProperty(exports, "readProtobufMessage", { enumerable: true, get: function () { return decode_js_2.readProtobufMessage; } });
var encode_js_2 = require("./protobuf/encode.js");
Object.defineProperty(exports, "writeProtobufMessage", { enumerable: true, get: function () { return encode_js_2.writeProtobufMessage; } });

View File

@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readJsonObject = exports.arrayObjectsMap = exports.object = exports.array = exports.boolean = exports.number = exports.stringOpt = exports.string = void 0;
const errors_js_1 = require("../../errors.js");
function string(value) {
if (typeof value === "string") {
return value;
}
throw typeError(value, "string");
}
exports.string = string;
function stringOpt(value) {
if (value === null || value === undefined) {
return undefined;
}
else if (typeof value === "string") {
return value;
}
throw typeError(value, "string or null");
}
exports.stringOpt = stringOpt;
function number(value) {
if (typeof value === "number") {
return value;
}
throw typeError(value, "number");
}
exports.number = number;
function boolean(value) {
if (typeof value === "boolean") {
return value;
}
throw typeError(value, "boolean");
}
exports.boolean = boolean;
function array(value) {
if (Array.isArray(value)) {
return value;
}
throw typeError(value, "array");
}
exports.array = array;
function object(value) {
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
return value;
}
throw typeError(value, "object");
}
exports.object = object;
function arrayObjectsMap(value, fun) {
return array(value).map((elemValue) => fun(object(elemValue)));
}
exports.arrayObjectsMap = arrayObjectsMap;
function typeError(value, expected) {
if (value === undefined) {
return new errors_js_1.ProtoError(`Expected ${expected}, but the property was missing`);
}
let received = typeof value;
if (value === null) {
received = "null";
}
else if (Array.isArray(value)) {
received = "array";
}
return new errors_js_1.ProtoError(`Expected ${expected}, received ${received}`);
}
function readJsonObject(value, fun) {
return fun(object(value));
}
exports.readJsonObject = readJsonObject;

View File

@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeJsonObject = exports.ObjectWriter = void 0;
class ObjectWriter {
#output;
#isFirst;
constructor(output) {
this.#output = output;
this.#isFirst = false;
}
begin() {
this.#output.push('{');
this.#isFirst = true;
}
end() {
this.#output.push('}');
this.#isFirst = false;
}
#key(name) {
if (this.#isFirst) {
this.#output.push('"');
this.#isFirst = false;
}
else {
this.#output.push(',"');
}
this.#output.push(name);
this.#output.push('":');
}
string(name, value) {
this.#key(name);
this.#output.push(JSON.stringify(value));
}
stringRaw(name, value) {
this.#key(name);
this.#output.push('"');
this.#output.push(value);
this.#output.push('"');
}
number(name, value) {
this.#key(name);
this.#output.push("" + value);
}
boolean(name, value) {
this.#key(name);
this.#output.push(value ? "true" : "false");
}
object(name, value, valueFun) {
this.#key(name);
this.begin();
valueFun(this, value);
this.end();
}
arrayObjects(name, values, valueFun) {
this.#key(name);
this.#output.push('[');
for (let i = 0; i < values.length; ++i) {
if (i !== 0) {
this.#output.push(',');
}
this.begin();
valueFun(this, values[i]);
this.end();
}
this.#output.push(']');
}
}
exports.ObjectWriter = ObjectWriter;
function writeJsonObject(value, fun) {
const output = [];
const writer = new ObjectWriter(output);
writer.begin();
fun(writer, value);
writer.end();
return output.join("");
}
exports.writeJsonObject = writeJsonObject;

View File

@@ -0,0 +1,155 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readProtobufMessage = exports.FieldReader = void 0;
const errors_js_1 = require("../../errors.js");
const util_js_1 = require("./util.js");
class MessageReader {
#array;
#view;
#pos;
constructor(array) {
this.#array = array;
this.#view = new DataView(array.buffer, array.byteOffset, array.byteLength);
this.#pos = 0;
}
varint() {
let value = 0;
for (let shift = 0;; shift += 7) {
const byte = this.#array[this.#pos++];
value |= (byte & 0x7f) << shift;
if (!(byte & 0x80)) {
break;
}
}
return value;
}
varintBig() {
let value = 0n;
for (let shift = 0n;; shift += 7n) {
const byte = this.#array[this.#pos++];
value |= BigInt(byte & 0x7f) << shift;
if (!(byte & 0x80)) {
break;
}
}
return value;
}
bytes(length) {
const array = new Uint8Array(this.#array.buffer, this.#array.byteOffset + this.#pos, length);
this.#pos += length;
return array;
}
double() {
const value = this.#view.getFloat64(this.#pos, true);
this.#pos += 8;
return value;
}
skipVarint() {
for (;;) {
const byte = this.#array[this.#pos++];
if (!(byte & 0x80)) {
break;
}
}
}
skip(count) {
this.#pos += count;
}
eof() {
return this.#pos >= this.#array.byteLength;
}
}
class FieldReader {
#reader;
#wireType;
constructor(reader) {
this.#reader = reader;
this.#wireType = -1;
}
setup(wireType) {
this.#wireType = wireType;
}
#expect(expectedWireType) {
if (this.#wireType !== expectedWireType) {
throw new errors_js_1.ProtoError(`Expected wire type ${expectedWireType}, got ${this.#wireType}`);
}
this.#wireType = -1;
}
bytes() {
this.#expect(util_js_1.LENGTH_DELIMITED);
const length = this.#reader.varint();
return this.#reader.bytes(length);
}
string() {
return new TextDecoder().decode(this.bytes());
}
message(def) {
return readProtobufMessage(this.bytes(), def);
}
int32() {
this.#expect(util_js_1.VARINT);
return this.#reader.varint();
}
uint32() {
return this.int32();
}
bool() {
return this.int32() !== 0;
}
uint64() {
this.#expect(util_js_1.VARINT);
return this.#reader.varintBig();
}
sint64() {
const value = this.uint64();
return (value >> 1n) ^ (-(value & 1n));
}
double() {
this.#expect(util_js_1.FIXED_64);
return this.#reader.double();
}
maybeSkip() {
if (this.#wireType < 0) {
return;
}
else if (this.#wireType === util_js_1.VARINT) {
this.#reader.skipVarint();
}
else if (this.#wireType === util_js_1.FIXED_64) {
this.#reader.skip(8);
}
else if (this.#wireType === util_js_1.LENGTH_DELIMITED) {
const length = this.#reader.varint();
this.#reader.skip(length);
}
else if (this.#wireType === util_js_1.FIXED_32) {
this.#reader.skip(4);
}
else {
throw new errors_js_1.ProtoError(`Unexpected wire type ${this.#wireType}`);
}
this.#wireType = -1;
}
}
exports.FieldReader = FieldReader;
function readProtobufMessage(data, def) {
const msgReader = new MessageReader(data);
const fieldReader = new FieldReader(msgReader);
let value = def.default();
while (!msgReader.eof()) {
const key = msgReader.varint();
const tag = key >> 3;
const wireType = key & 0x7;
fieldReader.setup(wireType);
const tagFun = def[tag];
if (tagFun !== undefined) {
const returnedValue = tagFun(fieldReader, value);
if (returnedValue !== undefined) {
value = returnedValue;
}
}
fieldReader.maybeSkip();
}
return value;
}
exports.readProtobufMessage = readProtobufMessage;

View File

@@ -0,0 +1,100 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeProtobufMessage = exports.MessageWriter = void 0;
const util_js_1 = require("./util.js");
class MessageWriter {
#buf;
#array;
#view;
#pos;
constructor() {
this.#buf = new ArrayBuffer(256);
this.#array = new Uint8Array(this.#buf);
this.#view = new DataView(this.#buf);
this.#pos = 0;
}
#ensure(extra) {
if (this.#pos + extra <= this.#buf.byteLength) {
return;
}
let newCap = this.#buf.byteLength;
while (newCap < this.#pos + extra) {
newCap *= 2;
}
const newBuf = new ArrayBuffer(newCap);
const newArray = new Uint8Array(newBuf);
const newView = new DataView(newBuf);
newArray.set(new Uint8Array(this.#buf, 0, this.#pos));
this.#buf = newBuf;
this.#array = newArray;
this.#view = newView;
}
#varint(value) {
this.#ensure(5);
value = 0 | value;
do {
let byte = value & 0x7f;
value >>>= 7;
byte |= (value ? 0x80 : 0);
this.#array[this.#pos++] = byte;
} while (value);
}
#varintBig(value) {
this.#ensure(10);
value = value & 0xffffffffffffffffn;
do {
let byte = Number(value & 0x7fn);
value >>= 7n;
byte |= (value ? 0x80 : 0);
this.#array[this.#pos++] = byte;
} while (value);
}
#tag(tag, wireType) {
this.#varint((tag << 3) | wireType);
}
bytes(tag, value) {
this.#tag(tag, util_js_1.LENGTH_DELIMITED);
this.#varint(value.byteLength);
this.#ensure(value.byteLength);
this.#array.set(value, this.#pos);
this.#pos += value.byteLength;
}
string(tag, value) {
this.bytes(tag, new TextEncoder().encode(value));
}
message(tag, value, fun) {
const writer = new MessageWriter();
fun(writer, value);
this.bytes(tag, writer.data());
}
int32(tag, value) {
this.#tag(tag, util_js_1.VARINT);
this.#varint(value);
}
uint32(tag, value) {
this.int32(tag, value);
}
bool(tag, value) {
this.int32(tag, value ? 1 : 0);
}
sint64(tag, value) {
this.#tag(tag, util_js_1.VARINT);
this.#varintBig((value << 1n) ^ (value >> 63n));
}
double(tag, value) {
this.#tag(tag, util_js_1.FIXED_64);
this.#ensure(8);
this.#view.setFloat64(this.#pos, value, true);
this.#pos += 8;
}
data() {
return new Uint8Array(this.#buf, 0, this.#pos);
}
}
exports.MessageWriter = MessageWriter;
function writeProtobufMessage(value, fun) {
const w = new MessageWriter();
fun(w, value);
return w.data();
}
exports.writeProtobufMessage = writeProtobufMessage;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FIXED_32 = exports.GROUP_END = exports.GROUP_START = exports.LENGTH_DELIMITED = exports.FIXED_64 = exports.VARINT = void 0;
exports.VARINT = 0;
exports.FIXED_64 = 1;
exports.LENGTH_DELIMITED = 2;
exports.GROUP_START = 3;
exports.GROUP_END = 4;
exports.FIXED_32 = 5;

116
node_modules/@libsql/hrana-client/lib-cjs/errors.js generated vendored Normal file
View File

@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MisuseError = exports.InternalError = exports.ProtocolVersionError = exports.LibsqlUrlParseError = exports.HttpServerError = exports.WebSocketError = exports.WebSocketUnsupportedError = exports.ClosedError = exports.ResponseError = exports.ProtoError = exports.ClientError = void 0;
/** Generic error produced by the Hrana client. */
class ClientError extends Error {
/** @private */
constructor(message) {
super(message);
this.name = "ClientError";
}
}
exports.ClientError = ClientError;
/** Error thrown when the server violates the protocol. */
class ProtoError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "ProtoError";
}
}
exports.ProtoError = ProtoError;
/** Error thrown when the server returns an error response. */
class ResponseError extends ClientError {
code;
/** @internal */
proto;
/** @private */
constructor(message, protoError) {
super(message);
this.name = "ResponseError";
this.code = protoError.code;
this.proto = protoError;
this.stack = undefined;
}
}
exports.ResponseError = ResponseError;
/** Error thrown when the client or stream is closed. */
class ClosedError extends ClientError {
/** @private */
constructor(message, cause) {
if (cause !== undefined) {
super(`${message}: ${cause}`);
this.cause = cause;
}
else {
super(message);
}
this.name = "ClosedError";
}
}
exports.ClosedError = ClosedError;
/** Error thrown when the environment does not seem to support WebSockets. */
class WebSocketUnsupportedError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "WebSocketUnsupportedError";
}
}
exports.WebSocketUnsupportedError = WebSocketUnsupportedError;
/** Error thrown when we encounter a WebSocket error. */
class WebSocketError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "WebSocketError";
}
}
exports.WebSocketError = WebSocketError;
/** Error thrown when the HTTP server returns an error response. */
class HttpServerError extends ClientError {
status;
/** @private */
constructor(message, status) {
super(message);
this.status = status;
this.name = "HttpServerError";
}
}
exports.HttpServerError = HttpServerError;
/** Error thrown when a libsql URL is not valid. */
class LibsqlUrlParseError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "LibsqlUrlParseError";
}
}
exports.LibsqlUrlParseError = LibsqlUrlParseError;
/** Error thrown when the protocol version is too low to support a feature. */
class ProtocolVersionError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "ProtocolVersionError";
}
}
exports.ProtocolVersionError = ProtocolVersionError;
/** Error thrown when an internal client error happens. */
class InternalError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "InternalError";
}
}
exports.InternalError = InternalError;
/** Error thrown when the API is misused. */
class MisuseError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "MisuseError";
}
}
exports.MisuseError = MisuseError;

View File

@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpClient = exports.checkEndpoints = void 0;
const isomorphic_fetch_1 = require("@libsql/isomorphic-fetch");
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;
#closed;
#streams;
/** @private */
_endpointPromise;
/** @private */
_endpoint;
/** @private */
constructor(url, jwt, customFetch, protocolVersion = 2) {
super();
this.#url = url;
this.#jwt = jwt;
this.#fetch = customFetch ?? isomorphic_fetch_1.fetch;
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.#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 isomorphic_fetch_1.Request(url.toString(), { method: "GET" });
const response = await fetch(request);
await response.arrayBuffer();
if (response.ok) {
return endpoint;
}
}
return fallbackEndpoint;
}

View File

@@ -0,0 +1,162 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpCursor = void 0;
const byte_queue_js_1 = require("../byte_queue.js");
const cursor_js_1 = require("../cursor.js");
const jsond = __importStar(require("../encoding/json/decode.js"));
const protobufd = __importStar(require("../encoding/protobuf/decode.js"));
const errors_js_1 = require("../errors.js");
const util_js_1 = require("../util.js");
const json_decode_js_1 = require("./json_decode.js");
const protobuf_decode_js_1 = require("./protobuf_decode.js");
const json_decode_js_2 = require("../shared/json_decode.js");
const protobuf_decode_js_2 = require("../shared/protobuf_decode.js");
class HttpCursor extends cursor_js_1.Cursor {
#stream;
#encoding;
#reader;
#queue;
#closed;
#done;
/** @private */
constructor(stream, encoding) {
super();
this.#stream = stream;
this.#encoding = encoding;
this.#reader = undefined;
this.#queue = new byte_queue_js_1.ByteQueue(16 * 1024);
this.#closed = undefined;
this.#done = false;
}
async open(response) {
if (response.body === null) {
throw new errors_js_1.ProtoError("No response body for cursor request");
}
this.#reader = response.body.getReader();
const respBody = await this.#nextItem(json_decode_js_1.CursorRespBody, protobuf_decode_js_1.CursorRespBody);
if (respBody === undefined) {
throw new errors_js_1.ProtoError("Empty response to cursor request");
}
return respBody;
}
/** Fetch the next entry from the cursor. */
next() {
return this.#nextItem(json_decode_js_2.CursorEntry, protobuf_decode_js_2.CursorEntry);
}
/** Close the cursor. */
close() {
this._setClosed(new errors_js_1.ClientError("Cursor was manually closed"));
}
/** @private */
_setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
this.#stream._cursorClosed(this);
if (this.#reader !== undefined) {
this.#reader.cancel();
}
}
/** True if the cursor is closed. */
get closed() {
return this.#closed !== undefined;
}
async #nextItem(jsonFun, protobufDef) {
for (;;) {
if (this.#done) {
return undefined;
}
else if (this.#closed !== undefined) {
throw new errors_js_1.ClosedError("Cursor is closed", this.#closed);
}
if (this.#encoding === "json") {
const jsonData = this.#parseItemJson();
if (jsonData !== undefined) {
const jsonText = new TextDecoder().decode(jsonData);
const jsonValue = JSON.parse(jsonText);
return jsond.readJsonObject(jsonValue, jsonFun);
}
}
else if (this.#encoding === "protobuf") {
const protobufData = this.#parseItemProtobuf();
if (protobufData !== undefined) {
return protobufd.readProtobufMessage(protobufData, protobufDef);
}
}
else {
throw (0, util_js_1.impossible)(this.#encoding, "Impossible encoding");
}
if (this.#reader === undefined) {
throw new errors_js_1.InternalError("Attempted to read from HTTP cursor before it was opened");
}
const { value, done } = await this.#reader.read();
if (done && this.#queue.length === 0) {
this.#done = true;
}
else if (done) {
throw new errors_js_1.ProtoError("Unexpected end of cursor stream");
}
else {
this.#queue.push(value);
}
}
}
#parseItemJson() {
const data = this.#queue.data();
const newlineByte = 10;
const newlinePos = data.indexOf(newlineByte);
if (newlinePos < 0) {
return undefined;
}
const jsonData = data.slice(0, newlinePos);
this.#queue.shift(newlinePos + 1);
return jsonData;
}
#parseItemProtobuf() {
const data = this.#queue.data();
let varintValue = 0;
let varintLength = 0;
for (;;) {
if (varintLength >= data.byteLength) {
return undefined;
}
const byte = data[varintLength];
varintValue |= (byte & 0x7f) << (7 * varintLength);
varintLength += 1;
if (!(byte & 0x80)) {
break;
}
}
if (data.byteLength < varintLength + varintValue) {
return undefined;
}
const protobufData = data.slice(varintLength, varintLength + varintValue);
this.#queue.shift(varintLength + varintValue);
return protobufData;
}
}
exports.HttpCursor = HttpCursor;

View File

@@ -0,0 +1,90 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorRespBody = exports.PipelineRespBody = void 0;
const errors_js_1 = require("../errors.js");
const d = __importStar(require("../encoding/json/decode.js"));
const json_decode_js_1 = require("../shared/json_decode.js");
function PipelineRespBody(obj) {
const baton = d.stringOpt(obj["baton"]);
const baseUrl = d.stringOpt(obj["base_url"]);
const results = d.arrayObjectsMap(obj["results"], StreamResult);
return { baton, baseUrl, results };
}
exports.PipelineRespBody = PipelineRespBody;
function StreamResult(obj) {
const type = d.string(obj["type"]);
if (type === "ok") {
const response = StreamResponse(d.object(obj["response"]));
return { type: "ok", response };
}
else if (type === "error") {
const error = (0, json_decode_js_1.Error)(d.object(obj["error"]));
return { type: "error", error };
}
else {
throw new errors_js_1.ProtoError("Unexpected type of StreamResult");
}
}
function StreamResponse(obj) {
const type = d.string(obj["type"]);
if (type === "close") {
return { type: "close" };
}
else if (type === "execute") {
const result = (0, json_decode_js_1.StmtResult)(d.object(obj["result"]));
return { type: "execute", result };
}
else if (type === "batch") {
const result = (0, json_decode_js_1.BatchResult)(d.object(obj["result"]));
return { type: "batch", result };
}
else if (type === "sequence") {
return { type: "sequence" };
}
else if (type === "describe") {
const result = (0, json_decode_js_1.DescribeResult)(d.object(obj["result"]));
return { type: "describe", result };
}
else if (type === "store_sql") {
return { type: "store_sql" };
}
else if (type === "close_sql") {
return { type: "close_sql" };
}
else if (type === "get_autocommit") {
const isAutocommit = d.boolean(obj["is_autocommit"]);
return { type: "get_autocommit", isAutocommit };
}
else {
throw new errors_js_1.ProtoError("Unexpected type of StreamResponse");
}
}
function CursorRespBody(obj) {
const baton = d.stringOpt(obj["baton"]);
const baseUrl = d.stringOpt(obj["base_url"]);
return { baton, baseUrl };
}
exports.CursorRespBody = CursorRespBody;

View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorReqBody = exports.PipelineReqBody = void 0;
const json_encode_js_1 = require("../shared/json_encode.js");
const util_js_1 = require("../util.js");
function PipelineReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string("baton", msg.baton);
}
w.arrayObjects("requests", msg.requests, StreamRequest);
}
exports.PipelineReqBody = PipelineReqBody;
function StreamRequest(w, msg) {
w.stringRaw("type", msg.type);
if (msg.type === "close") {
// do nothing
}
else if (msg.type === "execute") {
w.object("stmt", msg.stmt, json_encode_js_1.Stmt);
}
else if (msg.type === "batch") {
w.object("batch", msg.batch, json_encode_js_1.Batch);
}
else if (msg.type === "sequence") {
if (msg.sql !== undefined) {
w.string("sql", msg.sql);
}
if (msg.sqlId !== undefined) {
w.number("sql_id", msg.sqlId);
}
}
else if (msg.type === "describe") {
if (msg.sql !== undefined) {
w.string("sql", msg.sql);
}
if (msg.sqlId !== undefined) {
w.number("sql_id", msg.sqlId);
}
}
else if (msg.type === "store_sql") {
w.number("sql_id", msg.sqlId);
w.string("sql", msg.sql);
}
else if (msg.type === "close_sql") {
w.number("sql_id", msg.sqlId);
}
else if (msg.type === "get_autocommit") {
// do nothing
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of StreamRequest");
}
}
function CursorReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string("baton", msg.baton);
}
w.object("batch", msg.batch, json_encode_js_1.Batch);
}
exports.CursorReqBody = CursorReqBody;

View File

@@ -0,0 +1,18 @@
"use strict";
// Types for the structures specific to Hrana over HTTP.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("../shared/proto.js"), exports);

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorRespBody = exports.PipelineRespBody = void 0;
const protobuf_decode_js_1 = require("../shared/protobuf_decode.js");
exports.PipelineRespBody = {
default() { return { baton: undefined, baseUrl: undefined, results: [] }; },
1(r, msg) { msg.baton = r.string(); },
2(r, msg) { msg.baseUrl = r.string(); },
3(r, msg) { msg.results.push(r.message(StreamResult)); },
};
const StreamResult = {
default() { return { type: "none" }; },
1(r) { return { type: "ok", response: r.message(StreamResponse) }; },
2(r) { return { type: "error", error: r.message(protobuf_decode_js_1.Error) }; },
};
const StreamResponse = {
default() { return { type: "none" }; },
1(r) { return { type: "close" }; },
2(r) { return r.message(ExecuteStreamResp); },
3(r) { return r.message(BatchStreamResp); },
4(r) { return { type: "sequence" }; },
5(r) { return r.message(DescribeStreamResp); },
6(r) { return { type: "store_sql" }; },
7(r) { return { type: "close_sql" }; },
8(r) { return r.message(GetAutocommitStreamResp); },
};
const ExecuteStreamResp = {
default() { return { type: "execute", result: protobuf_decode_js_1.StmtResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.StmtResult); },
};
const BatchStreamResp = {
default() { return { type: "batch", result: protobuf_decode_js_1.BatchResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.BatchResult); },
};
const DescribeStreamResp = {
default() { return { type: "describe", result: protobuf_decode_js_1.DescribeResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.DescribeResult); },
};
const GetAutocommitStreamResp = {
default() { return { type: "get_autocommit", isAutocommit: false }; },
1(r, msg) { msg.isAutocommit = r.bool(); },
};
exports.CursorRespBody = {
default() { return { baton: undefined, baseUrl: undefined }; },
1(r, msg) { msg.baton = r.string(); },
2(r, msg) { msg.baseUrl = r.string(); },
};

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorReqBody = exports.PipelineReqBody = void 0;
const protobuf_encode_js_1 = require("../shared/protobuf_encode.js");
const util_js_1 = require("../util.js");
function PipelineReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string(1, msg.baton);
}
for (const req of msg.requests) {
w.message(2, req, StreamRequest);
}
}
exports.PipelineReqBody = PipelineReqBody;
function StreamRequest(w, msg) {
if (msg.type === "close") {
w.message(1, msg, CloseStreamReq);
}
else if (msg.type === "execute") {
w.message(2, msg, ExecuteStreamReq);
}
else if (msg.type === "batch") {
w.message(3, msg, BatchStreamReq);
}
else if (msg.type === "sequence") {
w.message(4, msg, SequenceStreamReq);
}
else if (msg.type === "describe") {
w.message(5, msg, DescribeStreamReq);
}
else if (msg.type === "store_sql") {
w.message(6, msg, StoreSqlStreamReq);
}
else if (msg.type === "close_sql") {
w.message(7, msg, CloseSqlStreamReq);
}
else if (msg.type === "get_autocommit") {
w.message(8, msg, GetAutocommitStreamReq);
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of StreamRequest");
}
}
function CloseStreamReq(_w, _msg) {
}
function ExecuteStreamReq(w, msg) {
w.message(1, msg.stmt, protobuf_encode_js_1.Stmt);
}
function BatchStreamReq(w, msg) {
w.message(1, msg.batch, protobuf_encode_js_1.Batch);
}
function SequenceStreamReq(w, msg) {
if (msg.sql !== undefined) {
w.string(1, msg.sql);
}
if (msg.sqlId !== undefined) {
w.int32(2, msg.sqlId);
}
}
function DescribeStreamReq(w, msg) {
if (msg.sql !== undefined) {
w.string(1, msg.sql);
}
if (msg.sqlId !== undefined) {
w.int32(2, msg.sqlId);
}
}
function StoreSqlStreamReq(w, msg) {
w.int32(1, msg.sqlId);
w.string(2, msg.sql);
}
function CloseSqlStreamReq(w, msg) {
w.int32(1, msg.sqlId);
}
function GetAutocommitStreamReq(_w, _msg) {
}
function CursorReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string(1, msg.baton);
}
w.message(2, msg.batch, protobuf_encode_js_1.Batch);
}
exports.CursorReqBody = CursorReqBody;

View File

@@ -0,0 +1,367 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpStream = void 0;
const isomorphic_fetch_1 = require("@libsql/isomorphic-fetch");
const errors_js_1 = require("../errors.js");
const index_js_1 = require("../encoding/index.js");
const id_alloc_js_1 = require("../id_alloc.js");
const queue_js_1 = require("../queue.js");
const queue_microtask_js_1 = require("../queue_microtask.js");
const result_js_1 = require("../result.js");
const sql_js_1 = require("../sql.js");
const stream_js_1 = require("../stream.js");
const util_js_1 = require("../util.js");
const cursor_js_1 = require("./cursor.js");
const json_encode_js_1 = require("./json_encode.js");
const protobuf_encode_js_1 = require("./protobuf_encode.js");
const json_encode_js_2 = require("./json_encode.js");
const protobuf_encode_js_2 = require("./protobuf_encode.js");
const json_decode_js_1 = require("./json_decode.js");
const protobuf_decode_js_1 = require("./protobuf_decode.js");
class HttpStream extends stream_js_1.Stream {
#client;
#baseUrl;
#jwt;
#fetch;
#baton;
#queue;
#flushing;
#cursor;
#closing;
#closeQueued;
#closed;
#sqlIdAlloc;
/** @private */
constructor(client, baseUrl, jwt, customFetch) {
super(client.intMode);
this.#client = client;
this.#baseUrl = baseUrl.toString();
this.#jwt = jwt;
this.#fetch = customFetch;
this.#baton = undefined;
this.#queue = new queue_js_1.Queue();
this.#flushing = false;
this.#closing = false;
this.#closeQueued = false;
this.#closed = undefined;
this.#sqlIdAlloc = new id_alloc_js_1.IdAlloc();
}
/** Get the {@link HttpClient} object that this stream belongs to. */
client() {
return this.#client;
}
/** @private */
_sqlOwner() {
return this;
}
/** Cache a SQL text on the server. */
storeSql(sql) {
const sqlId = this.#sqlIdAlloc.alloc();
this.#sendStreamRequest({ type: "store_sql", sqlId, sql }).then(() => undefined, (error) => this._setClosed(error));
return new sql_js_1.Sql(this, sqlId);
}
/** @private */
_closeSql(sqlId) {
if (this.#closed !== undefined) {
return;
}
this.#sendStreamRequest({ type: "close_sql", sqlId }).then(() => this.#sqlIdAlloc.free(sqlId), (error) => this._setClosed(error));
}
/** @private */
_execute(stmt) {
return this.#sendStreamRequest({ type: "execute", stmt }).then((response) => {
return response.result;
});
}
/** @private */
_batch(batch) {
return this.#sendStreamRequest({ type: "batch", batch }).then((response) => {
return response.result;
});
}
/** @private */
_describe(protoSql) {
return this.#sendStreamRequest({
type: "describe",
sql: protoSql.sql,
sqlId: protoSql.sqlId
}).then((response) => {
return response.result;
});
}
/** @private */
_sequence(protoSql) {
return this.#sendStreamRequest({
type: "sequence",
sql: protoSql.sql,
sqlId: protoSql.sqlId,
}).then((_response) => {
return undefined;
});
}
/** Check whether the SQL connection underlying this stream is in autocommit state (i.e., outside of an
* explicit transaction). This requires protocol version 3 or higher.
*/
getAutocommit() {
this.#client._ensureVersion(3, "getAutocommit()");
return this.#sendStreamRequest({
type: "get_autocommit",
}).then((response) => {
return response.isAutocommit;
});
}
#sendStreamRequest(request) {
return new Promise((responseCallback, errorCallback) => {
this.#pushToQueue({ type: "pipeline", request, responseCallback, errorCallback });
});
}
/** @private */
_openCursor(batch) {
return new Promise((cursorCallback, errorCallback) => {
this.#pushToQueue({ type: "cursor", batch, cursorCallback, errorCallback });
});
}
/** @private */
_cursorClosed(cursor) {
if (cursor !== this.#cursor) {
throw new errors_js_1.InternalError("Cursor was closed, but it was not associated with the stream");
}
this.#cursor = undefined;
(0, queue_microtask_js_1.queueMicrotask)(() => this.#flushQueue());
}
/** Immediately close the stream. */
close() {
this._setClosed(new errors_js_1.ClientError("Stream was manually closed"));
}
/** Gracefully close the stream. */
closeGracefully() {
this.#closing = true;
(0, queue_microtask_js_1.queueMicrotask)(() => this.#flushQueue());
}
/** True if the stream is closed. */
get closed() {
return this.#closed !== undefined || this.#closing;
}
/** @private */
_setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
if (this.#cursor !== undefined) {
this.#cursor._setClosed(error);
}
this.#client._streamClosed(this);
for (;;) {
const entry = this.#queue.shift();
if (entry !== undefined) {
entry.errorCallback(error);
}
else {
break;
}
}
if ((this.#baton !== undefined || this.#flushing) && !this.#closeQueued) {
this.#queue.push({
type: "pipeline",
request: { type: "close" },
responseCallback: () => undefined,
errorCallback: () => undefined,
});
this.#closeQueued = true;
(0, queue_microtask_js_1.queueMicrotask)(() => this.#flushQueue());
}
}
#pushToQueue(entry) {
if (this.#closed !== undefined) {
throw new errors_js_1.ClosedError("Stream is closed", this.#closed);
}
else if (this.#closing) {
throw new errors_js_1.ClosedError("Stream is closing", undefined);
}
else {
this.#queue.push(entry);
(0, queue_microtask_js_1.queueMicrotask)(() => this.#flushQueue());
}
}
#flushQueue() {
if (this.#flushing || this.#cursor !== undefined) {
return;
}
if (this.#closing && this.#queue.length === 0) {
this._setClosed(new errors_js_1.ClientError("Stream was gracefully closed"));
return;
}
const endpoint = this.#client._endpoint;
if (endpoint === undefined) {
this.#client._endpointPromise.then(() => this.#flushQueue(), (error) => this._setClosed(error));
return;
}
const firstEntry = this.#queue.shift();
if (firstEntry === undefined) {
return;
}
else if (firstEntry.type === "pipeline") {
const pipeline = [firstEntry];
for (;;) {
const entry = this.#queue.first();
if (entry !== undefined && entry.type === "pipeline") {
pipeline.push(entry);
this.#queue.shift();
}
else if (entry === undefined && this.#closing && !this.#closeQueued) {
pipeline.push({
type: "pipeline",
request: { type: "close" },
responseCallback: () => undefined,
errorCallback: () => undefined,
});
this.#closeQueued = true;
break;
}
else {
break;
}
}
this.#flushPipeline(endpoint, pipeline);
}
else if (firstEntry.type === "cursor") {
this.#flushCursor(endpoint, firstEntry);
}
else {
throw (0, util_js_1.impossible)(firstEntry, "Impossible type of QueueEntry");
}
}
#flushPipeline(endpoint, pipeline) {
this.#flush(() => this.#createPipelineRequest(pipeline, endpoint), (resp) => decodePipelineResponse(resp, endpoint.encoding), (respBody) => respBody.baton, (respBody) => respBody.baseUrl, (respBody) => handlePipelineResponse(pipeline, respBody), (error) => pipeline.forEach((entry) => entry.errorCallback(error)));
}
#flushCursor(endpoint, entry) {
const cursor = new cursor_js_1.HttpCursor(this, endpoint.encoding);
this.#cursor = cursor;
this.#flush(() => this.#createCursorRequest(entry, endpoint), (resp) => cursor.open(resp), (respBody) => respBody.baton, (respBody) => respBody.baseUrl, (_respBody) => entry.cursorCallback(cursor), (error) => entry.errorCallback(error));
}
#flush(createRequest, decodeResponse, getBaton, getBaseUrl, handleResponse, handleError) {
let promise;
try {
const request = createRequest();
const fetch = this.#fetch;
promise = fetch(request);
}
catch (error) {
promise = Promise.reject(error);
}
this.#flushing = true;
promise.then((resp) => {
if (!resp.ok) {
return errorFromResponse(resp).then((error) => {
throw error;
});
}
return decodeResponse(resp);
}).then((r) => {
this.#baton = getBaton(r);
this.#baseUrl = getBaseUrl(r) ?? this.#baseUrl;
handleResponse(r);
}).catch((error) => {
this._setClosed(error);
handleError(error);
}).finally(() => {
this.#flushing = false;
this.#flushQueue();
});
}
#createPipelineRequest(pipeline, endpoint) {
return this.#createRequest(new URL(endpoint.pipelinePath, this.#baseUrl), {
baton: this.#baton,
requests: pipeline.map((entry) => entry.request),
}, endpoint.encoding, json_encode_js_1.PipelineReqBody, protobuf_encode_js_1.PipelineReqBody);
}
#createCursorRequest(entry, endpoint) {
if (endpoint.cursorPath === undefined) {
throw new errors_js_1.ProtocolVersionError("Cursors are supported only on protocol version 3 and higher, " +
`but the HTTP server only supports version ${endpoint.version}.`);
}
return this.#createRequest(new URL(endpoint.cursorPath, this.#baseUrl), {
baton: this.#baton,
batch: entry.batch,
}, endpoint.encoding, json_encode_js_2.CursorReqBody, protobuf_encode_js_2.CursorReqBody);
}
#createRequest(url, reqBody, encoding, jsonFun, protobufFun) {
let bodyData;
let contentType;
if (encoding === "json") {
bodyData = (0, index_js_1.writeJsonObject)(reqBody, jsonFun);
contentType = "application/json";
}
else if (encoding === "protobuf") {
bodyData = (0, index_js_1.writeProtobufMessage)(reqBody, protobufFun);
contentType = "application/x-protobuf";
}
else {
throw (0, util_js_1.impossible)(encoding, "Impossible encoding");
}
const headers = new isomorphic_fetch_1.Headers();
headers.set("content-type", contentType);
if (this.#jwt !== undefined) {
headers.set("authorization", `Bearer ${this.#jwt}`);
}
return new isomorphic_fetch_1.Request(url.toString(), { method: "POST", headers, body: bodyData });
}
}
exports.HttpStream = HttpStream;
function handlePipelineResponse(pipeline, respBody) {
if (respBody.results.length !== pipeline.length) {
throw new errors_js_1.ProtoError("Server returned unexpected number of pipeline results");
}
for (let i = 0; i < pipeline.length; ++i) {
const result = respBody.results[i];
const entry = pipeline[i];
if (result.type === "ok") {
if (result.response.type !== entry.request.type) {
throw new errors_js_1.ProtoError("Received unexpected type of response");
}
entry.responseCallback(result.response);
}
else if (result.type === "error") {
entry.errorCallback((0, result_js_1.errorFromProto)(result.error));
}
else if (result.type === "none") {
throw new errors_js_1.ProtoError("Received unrecognized type of StreamResult");
}
else {
throw (0, util_js_1.impossible)(result, "Received impossible type of StreamResult");
}
}
}
async function decodePipelineResponse(resp, encoding) {
if (encoding === "json") {
const respJson = await resp.json();
return (0, index_js_1.readJsonObject)(respJson, json_decode_js_1.PipelineRespBody);
}
if (encoding === "protobuf") {
const respData = await resp.arrayBuffer();
return (0, index_js_1.readProtobufMessage)(new Uint8Array(respData), protobuf_decode_js_1.PipelineRespBody);
}
await resp.body?.cancel();
throw (0, util_js_1.impossible)(encoding, "Impossible encoding");
}
async function errorFromResponse(resp) {
const respType = resp.headers.get("content-type") ?? "text/plain";
let message = `Server returned HTTP status ${resp.status}`;
if (respType === "application/json") {
const respBody = await resp.json();
if ("message" in respBody) {
return (0, result_js_1.errorFromProto)(respBody);
}
return new errors_js_1.HttpServerError(message, resp.status);
}
if (respType === "text/plain") {
const respBody = (await resp.text()).trim();
if (respBody !== "") {
message += `: ${respBody}`;
}
return new errors_js_1.HttpServerError(message, resp.status);
}
await resp.body?.cancel();
return new errors_js_1.HttpServerError(message, resp.status);
}

51
node_modules/@libsql/hrana-client/lib-cjs/id_alloc.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IdAlloc = void 0;
const errors_js_1 = require("./errors.js");
// An allocator of non-negative integer ids.
//
// This clever data structure has these "ideal" properties:
// - It consumes memory proportional to the number of used ids (which is optimal).
// - All operations are O(1) time.
// - The allocated ids are small (with a slight modification, we could always provide the smallest possible
// id).
class IdAlloc {
// Set of all allocated ids
#usedIds;
// Set of all free ids lower than `#usedIds.size`
#freeIds;
constructor() {
this.#usedIds = new Set();
this.#freeIds = new Set();
}
// Returns an id that was free, and marks it as used.
alloc() {
// this "loop" is just a way to pick an arbitrary element from the `#freeIds` set
for (const freeId of this.#freeIds) {
this.#freeIds.delete(freeId);
this.#usedIds.add(freeId);
// maintain the invariant of `#freeIds`
if (!this.#usedIds.has(this.#usedIds.size - 1)) {
this.#freeIds.add(this.#usedIds.size - 1);
}
return freeId;
}
// the `#freeIds` set is empty, so there are no free ids lower than `#usedIds.size`
// this means that `#usedIds` is a set that contains all numbers from 0 to `#usedIds.size - 1`,
// so `#usedIds.size` is free
const freeId = this.#usedIds.size;
this.#usedIds.add(freeId);
return freeId;
}
free(id) {
if (!this.#usedIds.delete(id)) {
throw new errors_js_1.InternalError("Freeing an id that is not allocated");
}
// maintain the invariant of `#freeIds`
this.#freeIds.delete(this.#usedIds.size);
if (id < this.#usedIds.size) {
this.#freeIds.add(id);
}
}
}
exports.IdAlloc = IdAlloc;

77
node_modules/@libsql/hrana-client/lib-cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.openHttp = exports.openWs = exports.WsStream = exports.WsClient = exports.HttpStream = exports.HttpClient = exports.Stream = exports.Stmt = exports.Sql = exports.parseLibsqlUrl = exports.BatchCond = exports.BatchStep = exports.Batch = exports.Client = exports.Headers = exports.Request = exports.fetch = exports.WebSocket = void 0;
const isomorphic_ws_1 = require("@libsql/isomorphic-ws");
const client_js_1 = require("./ws/client.js");
const errors_js_1 = require("./errors.js");
const client_js_2 = require("./http/client.js");
const client_js_3 = require("./ws/client.js");
var isomorphic_ws_2 = require("@libsql/isomorphic-ws");
Object.defineProperty(exports, "WebSocket", { enumerable: true, get: function () { return isomorphic_ws_2.WebSocket; } });
var isomorphic_fetch_1 = require("@libsql/isomorphic-fetch");
Object.defineProperty(exports, "fetch", { enumerable: true, get: function () { return isomorphic_fetch_1.fetch; } });
Object.defineProperty(exports, "Request", { enumerable: true, get: function () { return isomorphic_fetch_1.Request; } });
Object.defineProperty(exports, "Headers", { enumerable: true, get: function () { return isomorphic_fetch_1.Headers; } });
var client_js_4 = require("./client.js");
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_js_4.Client; } });
__exportStar(require("./errors.js"), exports);
var batch_js_1 = require("./batch.js");
Object.defineProperty(exports, "Batch", { enumerable: true, get: function () { return batch_js_1.Batch; } });
Object.defineProperty(exports, "BatchStep", { enumerable: true, get: function () { return batch_js_1.BatchStep; } });
Object.defineProperty(exports, "BatchCond", { enumerable: true, get: function () { return batch_js_1.BatchCond; } });
var libsql_url_js_1 = require("./libsql_url.js");
Object.defineProperty(exports, "parseLibsqlUrl", { enumerable: true, get: function () { return libsql_url_js_1.parseLibsqlUrl; } });
var sql_js_1 = require("./sql.js");
Object.defineProperty(exports, "Sql", { enumerable: true, get: function () { return sql_js_1.Sql; } });
var stmt_js_1 = require("./stmt.js");
Object.defineProperty(exports, "Stmt", { enumerable: true, get: function () { return stmt_js_1.Stmt; } });
var stream_js_1 = require("./stream.js");
Object.defineProperty(exports, "Stream", { enumerable: true, get: function () { return stream_js_1.Stream; } });
var client_js_5 = require("./http/client.js");
Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return client_js_5.HttpClient; } });
var stream_js_2 = require("./http/stream.js");
Object.defineProperty(exports, "HttpStream", { enumerable: true, get: function () { return stream_js_2.HttpStream; } });
var client_js_6 = require("./ws/client.js");
Object.defineProperty(exports, "WsClient", { enumerable: true, get: function () { return client_js_6.WsClient; } });
var stream_js_3 = require("./ws/stream.js");
Object.defineProperty(exports, "WsStream", { enumerable: true, get: function () { return stream_js_3.WsStream; } });
/** Open a Hrana client over WebSocket connected to the given `url`. */
function openWs(url, jwt, protocolVersion = 2) {
if (typeof isomorphic_ws_1.WebSocket === "undefined") {
throw new errors_js_1.WebSocketUnsupportedError("WebSockets are not supported in this environment");
}
var subprotocols = undefined;
if (protocolVersion == 3) {
subprotocols = Array.from(client_js_1.subprotocolsV3.keys());
}
else {
subprotocols = Array.from(client_js_1.subprotocolsV2.keys());
}
const socket = new isomorphic_ws_1.WebSocket(url, subprotocols);
return new client_js_3.WsClient(socket, jwt);
}
exports.openWs = openWs;
/** Open a Hrana client over HTTP connected to the given `url`.
*
* If the `customFetch` argument is passed and not `undefined`, it is used in place of the `fetch` function
* from `@libsql/isomorphic-fetch`. This function is always called with a `Request` object from
* `@libsql/isomorphic-fetch`.
*/
function openHttp(url, jwt, customFetch, protocolVersion = 2) {
return new client_js_2.HttpClient(url instanceof URL ? url : new URL(url), jwt, customFetch, protocolVersion);
}
exports.openHttp = openHttp;

View File

@@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseLibsqlUrl = void 0;
const errors_js_1 = require("./errors.js");
;
/** Parses a URL compatible with the libsql client (`@libsql/client`). This URL may have the "libsql:" scheme
* and may contain query parameters. */
function parseLibsqlUrl(urlStr) {
const url = new URL(urlStr);
let authToken = undefined;
let tls = undefined;
for (const [key, value] of url.searchParams.entries()) {
if (key === "authToken") {
authToken = value;
}
else if (key === "tls") {
if (value === "0") {
tls = false;
}
else if (value === "1") {
tls = true;
}
else {
throw new errors_js_1.LibsqlUrlParseError(`Unknown value for the "tls" query argument: ${JSON.stringify(value)}`);
}
}
else {
throw new errors_js_1.LibsqlUrlParseError(`Unknown URL query argument ${JSON.stringify(key)}`);
}
}
let hranaWsScheme;
let hranaHttpScheme;
if ((url.protocol === "http:" || url.protocol === "ws:") && (tls === true)) {
throw new errors_js_1.LibsqlUrlParseError(`A ${JSON.stringify(url.protocol)} URL cannot opt into TLS using ?tls=1`);
}
else if ((url.protocol === "https:" || url.protocol === "wss:") && (tls === false)) {
throw new errors_js_1.LibsqlUrlParseError(`A ${JSON.stringify(url.protocol)} URL cannot opt out of TLS using ?tls=0`);
}
if (url.protocol === "http:" || url.protocol === "https:") {
hranaHttpScheme = url.protocol;
}
else if (url.protocol === "ws:" || url.protocol === "wss:") {
hranaWsScheme = url.protocol;
}
else if (url.protocol === "libsql:") {
if (tls === false) {
if (!url.port) {
throw new errors_js_1.LibsqlUrlParseError(`A "libsql:" URL with ?tls=0 must specify an explicit port`);
}
hranaHttpScheme = "http:";
hranaWsScheme = "ws:";
}
else {
hranaHttpScheme = "https:";
hranaWsScheme = "wss:";
}
}
else {
throw new errors_js_1.LibsqlUrlParseError(`This client does not support ${JSON.stringify(url.protocol)} URLs. ` +
'Please use a "libsql:", "ws:", "wss:", "http:" or "https:" URL instead.');
}
if (url.username || url.password) {
throw new errors_js_1.LibsqlUrlParseError("This client does not support HTTP Basic authentication with a username and password. " +
'You can authenticate using a token passed in the "authToken" URL query parameter.');
}
if (url.hash) {
throw new errors_js_1.LibsqlUrlParseError("URL fragments are not supported");
}
let hranaPath = url.pathname;
if (hranaPath === "/") {
hranaPath = "";
}
const hranaWsUrl = hranaWsScheme !== undefined
? `${hranaWsScheme}//${url.host}${hranaPath}` : undefined;
const hranaHttpUrl = hranaHttpScheme !== undefined
? `${hranaHttpScheme}//${url.host}${hranaPath}` : undefined;
return { hranaWsUrl, hranaHttpUrl, authToken };
}
exports.parseLibsqlUrl = parseLibsqlUrl;

View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

30
node_modules/@libsql/hrana-client/lib-cjs/queue.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Queue = void 0;
class Queue {
#pushStack;
#shiftStack;
constructor() {
this.#pushStack = [];
this.#shiftStack = [];
}
get length() {
return this.#pushStack.length + this.#shiftStack.length;
}
push(elem) {
this.#pushStack.push(elem);
}
shift() {
if (this.#shiftStack.length === 0 && this.#pushStack.length > 0) {
this.#shiftStack = this.#pushStack.reverse();
this.#pushStack = [];
}
return this.#shiftStack.pop();
}
first() {
return this.#shiftStack.length !== 0
? this.#shiftStack[this.#shiftStack.length - 1]
: this.#pushStack[0];
}
}
exports.Queue = Queue;

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.queueMicrotask = void 0;
// queueMicrotask() ponyfill
// https://github.com/libsql/libsql-client-ts/issues/47
let _queueMicrotask;
if (typeof queueMicrotask !== "undefined") {
exports.queueMicrotask = _queueMicrotask = queueMicrotask;
}
else {
const resolved = Promise.resolve();
exports.queueMicrotask = _queueMicrotask = (callback) => {
resolved.then(callback);
};
}

56
node_modules/@libsql/hrana-client/lib-cjs/result.js generated vendored Normal file
View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorFromProto = exports.valueResultFromProto = exports.rowResultFromProto = exports.rowsResultFromProto = exports.stmtResultFromProto = void 0;
const errors_js_1 = require("./errors.js");
const value_js_1 = require("./value.js");
function stmtResultFromProto(result) {
return {
affectedRowCount: result.affectedRowCount,
lastInsertRowid: result.lastInsertRowid,
columnNames: result.cols.map(col => col.name),
columnDecltypes: result.cols.map(col => col.decltype),
};
}
exports.stmtResultFromProto = stmtResultFromProto;
function rowsResultFromProto(result, intMode) {
const stmtResult = stmtResultFromProto(result);
const rows = result.rows.map(row => rowFromProto(stmtResult.columnNames, row, intMode));
return { ...stmtResult, rows };
}
exports.rowsResultFromProto = rowsResultFromProto;
function rowResultFromProto(result, intMode) {
const stmtResult = stmtResultFromProto(result);
let row;
if (result.rows.length > 0) {
row = rowFromProto(stmtResult.columnNames, result.rows[0], intMode);
}
return { ...stmtResult, row };
}
exports.rowResultFromProto = rowResultFromProto;
function valueResultFromProto(result, intMode) {
const stmtResult = stmtResultFromProto(result);
let value;
if (result.rows.length > 0 && stmtResult.columnNames.length > 0) {
value = (0, value_js_1.valueFromProto)(result.rows[0][0], intMode);
}
return { ...stmtResult, value };
}
exports.valueResultFromProto = valueResultFromProto;
function rowFromProto(colNames, values, intMode) {
const row = {};
// make sure that the "length" property is not enumerable
Object.defineProperty(row, "length", { value: values.length });
for (let i = 0; i < values.length; ++i) {
const value = (0, value_js_1.valueFromProto)(values[i], intMode);
Object.defineProperty(row, i, { value });
const colName = colNames[i];
if (colName !== undefined && !Object.hasOwn(row, colName)) {
Object.defineProperty(row, colName, { value, enumerable: true, configurable: true, writable: true });
}
}
return row;
}
function errorFromProto(error) {
return new errors_js_1.ResponseError(error.message, error);
}
exports.errorFromProto = errorFromProto;

View File

@@ -0,0 +1,138 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Value = exports.DescribeResult = exports.CursorEntry = exports.BatchResult = exports.StmtResult = exports.Error = void 0;
const js_base64_1 = require("js-base64");
const errors_js_1 = require("../errors.js");
const d = __importStar(require("../encoding/json/decode.js"));
function Error(obj) {
const message = d.string(obj["message"]);
const code = d.stringOpt(obj["code"]);
return { message, code };
}
exports.Error = Error;
function StmtResult(obj) {
const cols = d.arrayObjectsMap(obj["cols"], Col);
const rows = d.array(obj["rows"]).map((rowObj) => d.arrayObjectsMap(rowObj, Value));
const affectedRowCount = d.number(obj["affected_row_count"]);
const lastInsertRowidStr = d.stringOpt(obj["last_insert_rowid"]);
const lastInsertRowid = lastInsertRowidStr !== undefined
? BigInt(lastInsertRowidStr) : undefined;
return { cols, rows, affectedRowCount, lastInsertRowid };
}
exports.StmtResult = StmtResult;
function Col(obj) {
const name = d.stringOpt(obj["name"]);
const decltype = d.stringOpt(obj["decltype"]);
return { name, decltype };
}
function BatchResult(obj) {
const stepResults = new Map();
d.array(obj["step_results"]).forEach((value, i) => {
if (value !== null) {
stepResults.set(i, StmtResult(d.object(value)));
}
});
const stepErrors = new Map();
d.array(obj["step_errors"]).forEach((value, i) => {
if (value !== null) {
stepErrors.set(i, Error(d.object(value)));
}
});
return { stepResults, stepErrors };
}
exports.BatchResult = BatchResult;
function CursorEntry(obj) {
const type = d.string(obj["type"]);
if (type === "step_begin") {
const step = d.number(obj["step"]);
const cols = d.arrayObjectsMap(obj["cols"], Col);
return { type: "step_begin", step, cols };
}
else if (type === "step_end") {
const affectedRowCount = d.number(obj["affected_row_count"]);
const lastInsertRowidStr = d.stringOpt(obj["last_insert_rowid"]);
const lastInsertRowid = lastInsertRowidStr !== undefined
? BigInt(lastInsertRowidStr) : undefined;
return { type: "step_end", affectedRowCount, lastInsertRowid };
}
else if (type === "step_error") {
const step = d.number(obj["step"]);
const error = Error(d.object(obj["error"]));
return { type: "step_error", step, error };
}
else if (type === "row") {
const row = d.arrayObjectsMap(obj["row"], Value);
return { type: "row", row };
}
else if (type === "error") {
const error = Error(d.object(obj["error"]));
return { type: "error", error };
}
else {
throw new errors_js_1.ProtoError("Unexpected type of CursorEntry");
}
}
exports.CursorEntry = CursorEntry;
function DescribeResult(obj) {
const params = d.arrayObjectsMap(obj["params"], DescribeParam);
const cols = d.arrayObjectsMap(obj["cols"], DescribeCol);
const isExplain = d.boolean(obj["is_explain"]);
const isReadonly = d.boolean(obj["is_readonly"]);
return { params, cols, isExplain, isReadonly };
}
exports.DescribeResult = DescribeResult;
function DescribeParam(obj) {
const name = d.stringOpt(obj["name"]);
return { name };
}
function DescribeCol(obj) {
const name = d.string(obj["name"]);
const decltype = d.stringOpt(obj["decltype"]);
return { name, decltype };
}
function Value(obj) {
const type = d.string(obj["type"]);
if (type === "null") {
return null;
}
else if (type === "integer") {
const value = d.string(obj["value"]);
return BigInt(value);
}
else if (type === "float") {
return d.number(obj["value"]);
}
else if (type === "text") {
return d.string(obj["value"]);
}
else if (type === "blob") {
return js_base64_1.Base64.toUint8Array(d.string(obj["base64"]));
}
else {
throw new errors_js_1.ProtoError("Unexpected type of Value");
}
}
exports.Value = Value;

View File

@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Batch = exports.Stmt = void 0;
const js_base64_1 = require("js-base64");
const util_js_1 = require("../util.js");
function Stmt(w, msg) {
if (msg.sql !== undefined) {
w.string("sql", msg.sql);
}
if (msg.sqlId !== undefined) {
w.number("sql_id", msg.sqlId);
}
w.arrayObjects("args", msg.args, Value);
w.arrayObjects("named_args", msg.namedArgs, NamedArg);
w.boolean("want_rows", msg.wantRows);
}
exports.Stmt = Stmt;
function NamedArg(w, msg) {
w.string("name", msg.name);
w.object("value", msg.value, Value);
}
function Batch(w, msg) {
w.arrayObjects("steps", msg.steps, BatchStep);
}
exports.Batch = Batch;
function BatchStep(w, msg) {
if (msg.condition !== undefined) {
w.object("condition", msg.condition, BatchCond);
}
w.object("stmt", msg.stmt, Stmt);
}
function BatchCond(w, msg) {
w.stringRaw("type", msg.type);
if (msg.type === "ok" || msg.type === "error") {
w.number("step", msg.step);
}
else if (msg.type === "not") {
w.object("cond", msg.cond, BatchCond);
}
else if (msg.type === "and" || msg.type === "or") {
w.arrayObjects("conds", msg.conds, BatchCond);
}
else if (msg.type === "is_autocommit") {
// do nothing
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of BatchCond");
}
}
function Value(w, msg) {
if (msg === null) {
w.stringRaw("type", "null");
}
else if (typeof msg === "bigint") {
w.stringRaw("type", "integer");
w.stringRaw("value", "" + msg);
}
else if (typeof msg === "number") {
w.stringRaw("type", "float");
w.number("value", msg);
}
else if (typeof msg === "string") {
w.stringRaw("type", "text");
w.string("value", msg);
}
else if (msg instanceof Uint8Array) {
w.stringRaw("type", "blob");
w.stringRaw("base64", js_base64_1.Base64.fromUint8Array(msg));
}
else if (msg === undefined) {
// do nothing
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of Value");
}
}

View File

@@ -0,0 +1,3 @@
"use strict";
// Types for the protocol structures that are shared for WebSocket and HTTP
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,118 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DescribeResult = exports.CursorEntry = exports.BatchResult = exports.StmtResult = exports.Error = void 0;
exports.Error = {
default() { return { message: "", code: undefined }; },
1(r, msg) { msg.message = r.string(); },
2(r, msg) { msg.code = r.string(); },
};
exports.StmtResult = {
default() {
return {
cols: [],
rows: [],
affectedRowCount: 0,
lastInsertRowid: undefined,
};
},
1(r, msg) { msg.cols.push(r.message(Col)); },
2(r, msg) { msg.rows.push(r.message(Row)); },
3(r, msg) { msg.affectedRowCount = Number(r.uint64()); },
4(r, msg) { msg.lastInsertRowid = r.sint64(); },
};
const Col = {
default() { return { name: undefined, decltype: undefined }; },
1(r, msg) { msg.name = r.string(); },
2(r, msg) { msg.decltype = r.string(); },
};
const Row = {
default() { return []; },
1(r, msg) { msg.push(r.message(Value)); },
};
exports.BatchResult = {
default() { return { stepResults: new Map(), stepErrors: new Map() }; },
1(r, msg) {
const [key, value] = r.message(BatchResultStepResult);
msg.stepResults.set(key, value);
},
2(r, msg) {
const [key, value] = r.message(BatchResultStepError);
msg.stepErrors.set(key, value);
},
};
const BatchResultStepResult = {
default() { return [0, exports.StmtResult.default()]; },
1(r, msg) { msg[0] = r.uint32(); },
2(r, msg) { msg[1] = r.message(exports.StmtResult); },
};
const BatchResultStepError = {
default() { return [0, exports.Error.default()]; },
1(r, msg) { msg[0] = r.uint32(); },
2(r, msg) { msg[1] = r.message(exports.Error); },
};
exports.CursorEntry = {
default() { return { type: "none" }; },
1(r) { return r.message(StepBeginEntry); },
2(r) { return r.message(StepEndEntry); },
3(r) { return r.message(StepErrorEntry); },
4(r) { return { type: "row", row: r.message(Row) }; },
5(r) { return { type: "error", error: r.message(exports.Error) }; },
};
const StepBeginEntry = {
default() { return { type: "step_begin", step: 0, cols: [] }; },
1(r, msg) { msg.step = r.uint32(); },
2(r, msg) { msg.cols.push(r.message(Col)); },
};
const StepEndEntry = {
default() {
return {
type: "step_end",
affectedRowCount: 0,
lastInsertRowid: undefined,
};
},
1(r, msg) { msg.affectedRowCount = r.uint32(); },
2(r, msg) { msg.lastInsertRowid = r.uint64(); },
};
const StepErrorEntry = {
default() {
return {
type: "step_error",
step: 0,
error: exports.Error.default(),
};
},
1(r, msg) { msg.step = r.uint32(); },
2(r, msg) { msg.error = r.message(exports.Error); },
};
exports.DescribeResult = {
default() {
return {
params: [],
cols: [],
isExplain: false,
isReadonly: false,
};
},
1(r, msg) { msg.params.push(r.message(DescribeParam)); },
2(r, msg) { msg.cols.push(r.message(DescribeCol)); },
3(r, msg) { msg.isExplain = r.bool(); },
4(r, msg) { msg.isReadonly = r.bool(); },
};
const DescribeParam = {
default() { return { name: undefined }; },
1(r, msg) { msg.name = r.string(); },
};
const DescribeCol = {
default() { return { name: "", decltype: undefined }; },
1(r, msg) { msg.name = r.string(); },
2(r, msg) { msg.decltype = r.string(); },
};
const Value = {
default() { return undefined; },
1(r) { return null; },
2(r) { return r.sint64(); },
3(r) { return r.double(); },
4(r) { return r.string(); },
5(r) { return r.bytes(); },
};

View File

@@ -0,0 +1,90 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Batch = exports.Stmt = void 0;
const util_js_1 = require("../util.js");
function Stmt(w, msg) {
if (msg.sql !== undefined) {
w.string(1, msg.sql);
}
if (msg.sqlId !== undefined) {
w.int32(2, msg.sqlId);
}
for (const arg of msg.args) {
w.message(3, arg, Value);
}
for (const arg of msg.namedArgs) {
w.message(4, arg, NamedArg);
}
w.bool(5, msg.wantRows);
}
exports.Stmt = Stmt;
function NamedArg(w, msg) {
w.string(1, msg.name);
w.message(2, msg.value, Value);
}
function Batch(w, msg) {
for (const step of msg.steps) {
w.message(1, step, BatchStep);
}
}
exports.Batch = Batch;
function BatchStep(w, msg) {
if (msg.condition !== undefined) {
w.message(1, msg.condition, BatchCond);
}
w.message(2, msg.stmt, Stmt);
}
function BatchCond(w, msg) {
if (msg.type === "ok") {
w.uint32(1, msg.step);
}
else if (msg.type === "error") {
w.uint32(2, msg.step);
}
else if (msg.type === "not") {
w.message(3, msg.cond, BatchCond);
}
else if (msg.type === "and") {
w.message(4, msg.conds, BatchCondList);
}
else if (msg.type === "or") {
w.message(5, msg.conds, BatchCondList);
}
else if (msg.type === "is_autocommit") {
w.message(6, undefined, Empty);
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of BatchCond");
}
}
function BatchCondList(w, msg) {
for (const cond of msg) {
w.message(1, cond, BatchCond);
}
}
function Value(w, msg) {
if (msg === null) {
w.message(1, undefined, Empty);
}
else if (typeof msg === "bigint") {
w.sint64(2, msg);
}
else if (typeof msg === "number") {
w.double(3, msg);
}
else if (typeof msg === "string") {
w.string(4, msg);
}
else if (msg instanceof Uint8Array) {
w.bytes(5, msg);
}
else if (msg === undefined) {
// do nothing
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of Value");
}
}
function Empty(_w, _msg) {
// do nothing
}

51
node_modules/@libsql/hrana-client/lib-cjs/sql.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sqlToProto = exports.Sql = void 0;
const errors_js_1 = require("./errors.js");
/** Text of an SQL statement cached on the server. */
class Sql {
#owner;
#sqlId;
#closed;
/** @private */
constructor(owner, sqlId) {
this.#owner = owner;
this.#sqlId = sqlId;
this.#closed = undefined;
}
/** @private */
_getSqlId(owner) {
if (this.#owner !== owner) {
throw new errors_js_1.MisuseError("Attempted to use SQL text opened with other object");
}
else if (this.#closed !== undefined) {
throw new errors_js_1.ClosedError("SQL text is closed", this.#closed);
}
return this.#sqlId;
}
/** Remove the SQL text from the server, releasing resouces. */
close() {
this._setClosed(new errors_js_1.ClientError("SQL text was manually closed"));
}
/** @private */
_setClosed(error) {
if (this.#closed === undefined) {
this.#closed = error;
this.#owner._closeSql(this.#sqlId);
}
}
/** True if the SQL text is closed (removed from the server). */
get closed() {
return this.#closed !== undefined;
}
}
exports.Sql = Sql;
function sqlToProto(owner, sql) {
if (sql instanceof Sql) {
return { sqlId: sql._getSqlId(owner) };
}
else {
return { sql: "" + sql };
}
}
exports.sqlToProto = sqlToProto;

81
node_modules/@libsql/hrana-client/lib-cjs/stmt.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.stmtToProto = exports.Stmt = void 0;
const sql_js_1 = require("./sql.js");
const value_js_1 = require("./value.js");
/** A statement that can be evaluated by the database. Besides the SQL text, it also contains the positional
* and named arguments. */
class Stmt {
/** The SQL statement text. */
sql;
/** @private */
_args;
/** @private */
_namedArgs;
/** Initialize the statement with given SQL text. */
constructor(sql) {
this.sql = sql;
this._args = [];
this._namedArgs = new Map();
}
/** Binds positional parameters from the given `values`. All previous positional bindings are cleared. */
bindIndexes(values) {
this._args.length = 0;
for (const value of values) {
this._args.push((0, value_js_1.valueToProto)(value));
}
return this;
}
/** Binds a parameter by a 1-based index. */
bindIndex(index, value) {
if (index !== (index | 0) || index <= 0) {
throw new RangeError("Index of a positional argument must be positive integer");
}
while (this._args.length < index) {
this._args.push(null);
}
this._args[index - 1] = (0, value_js_1.valueToProto)(value);
return this;
}
/** Binds a parameter by name. */
bindName(name, value) {
this._namedArgs.set(name, (0, value_js_1.valueToProto)(value));
return this;
}
/** Clears all bindings. */
unbindAll() {
this._args.length = 0;
this._namedArgs.clear();
return this;
}
}
exports.Stmt = Stmt;
function stmtToProto(sqlOwner, stmt, wantRows) {
let inSql;
let args = [];
let namedArgs = [];
if (stmt instanceof Stmt) {
inSql = stmt.sql;
args = stmt._args;
for (const [name, value] of stmt._namedArgs.entries()) {
namedArgs.push({ name, value });
}
}
else if (Array.isArray(stmt)) {
inSql = stmt[0];
if (Array.isArray(stmt[1])) {
args = stmt[1].map((arg) => (0, value_js_1.valueToProto)(arg));
}
else {
namedArgs = Object.entries(stmt[1]).map(([name, value]) => {
return { name, value: (0, value_js_1.valueToProto)(value) };
});
}
}
else {
inSql = stmt;
}
const { sql, sqlId } = (0, sql_js_1.sqlToProto)(sqlOwner, inSql);
return { sql, sqlId, args, namedArgs, wantRows };
}
exports.stmtToProto = stmtToProto;

61
node_modules/@libsql/hrana-client/lib-cjs/stream.js generated vendored Normal file
View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Stream = void 0;
const batch_js_1 = require("./batch.js");
const describe_js_1 = require("./describe.js");
const result_js_1 = require("./result.js");
const sql_js_1 = require("./sql.js");
const stmt_js_1 = require("./stmt.js");
/** A stream for executing SQL statements (a "database connection"). */
class Stream {
/** @private */
constructor(intMode) {
this.intMode = intMode;
}
/** Execute a statement and return rows. */
query(stmt) {
return this.#execute(stmt, true, result_js_1.rowsResultFromProto);
}
/** Execute a statement and return at most a single row. */
queryRow(stmt) {
return this.#execute(stmt, true, result_js_1.rowResultFromProto);
}
/** Execute a statement and return at most a single value. */
queryValue(stmt) {
return this.#execute(stmt, true, result_js_1.valueResultFromProto);
}
/** Execute a statement without returning rows. */
run(stmt) {
return this.#execute(stmt, false, result_js_1.stmtResultFromProto);
}
#execute(inStmt, wantRows, fromProto) {
const stmt = (0, stmt_js_1.stmtToProto)(this._sqlOwner(), inStmt, wantRows);
return this._execute(stmt).then((r) => fromProto(r, this.intMode));
}
/** Return a builder for creating and executing a batch.
*
* If `useCursor` is true, the batch will be executed using a Hrana cursor, which will stream results from
* the server to the client, which consumes less memory on the server. This requires protocol version 3 or
* higher.
*/
batch(useCursor = false) {
return new batch_js_1.Batch(this, useCursor);
}
/** Parse and analyze a statement. This requires protocol version 2 or higher. */
describe(inSql) {
const protoSql = (0, sql_js_1.sqlToProto)(this._sqlOwner(), inSql);
return this._describe(protoSql).then(describe_js_1.describeResultFromProto);
}
/** Execute a sequence of statements separated by semicolons. This requires protocol version 2 or higher.
* */
sequence(inSql) {
const protoSql = (0, sql_js_1.sqlToProto)(this._sqlOwner(), inSql);
return this._sequence(protoSql);
}
/** Representation of integers returned from the database. See {@link IntMode}.
*
* This value affects the results of all operations on this stream.
*/
intMode;
}
exports.Stream = Stream;

8
node_modules/@libsql/hrana-client/lib-cjs/util.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.impossible = void 0;
const errors_js_1 = require("./errors.js");
function impossible(value, message) {
throw new errors_js_1.InternalError(message);
}
exports.impossible = impossible;

88
node_modules/@libsql/hrana-client/lib-cjs/value.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.valueFromProto = exports.valueToProto = void 0;
const errors_js_1 = require("./errors.js");
const util_js_1 = require("./util.js");
function valueToProto(value) {
if (value === null) {
return null;
}
else if (typeof value === "string") {
return value;
}
else if (typeof value === "number") {
if (!Number.isFinite(value)) {
throw new RangeError("Only finite numbers (not Infinity or NaN) can be passed as arguments");
}
return value;
}
else if (typeof value === "bigint") {
if (value < minInteger || value > maxInteger) {
throw new RangeError("This bigint value is too large to be represented as a 64-bit integer and passed as argument");
}
return value;
}
else if (typeof value === "boolean") {
return value ? 1n : 0n;
}
else if (value instanceof ArrayBuffer) {
return new Uint8Array(value);
}
else if (value instanceof Uint8Array) {
return value;
}
else if (value instanceof Date) {
return +value.valueOf();
}
else if (typeof value === "object") {
return "" + value.toString();
}
else {
throw new TypeError("Unsupported type of value");
}
}
exports.valueToProto = valueToProto;
const minInteger = -9223372036854775808n;
const maxInteger = 9223372036854775807n;
function valueFromProto(value, intMode) {
if (value === null) {
return null;
}
else if (typeof value === "number") {
return value;
}
else if (typeof value === "string") {
return value;
}
else if (typeof value === "bigint") {
if (intMode === "number") {
const num = Number(value);
if (!Number.isSafeInteger(num)) {
throw new RangeError("Received integer which is too large to be safely represented as a JavaScript number");
}
return num;
}
else if (intMode === "bigint") {
return value;
}
else if (intMode === "string") {
return "" + value;
}
else {
throw new errors_js_1.MisuseError("Invalid value for IntMode");
}
}
else if (value instanceof Uint8Array) {
// TODO: we need to copy data from `Uint8Array` to return an `ArrayBuffer`. Perhaps we should add a
// `blobMode` parameter, similar to `intMode`, which would allow the user to choose between receiving
// `ArrayBuffer` (default, convenient) and `Uint8Array` (zero copy)?
return value.slice().buffer;
}
else if (value === undefined) {
throw new errors_js_1.ProtoError("Received unrecognized type of Value");
}
else {
throw (0, util_js_1.impossible)(value, "Impossible type of Value");
}
}
exports.valueFromProto = valueFromProto;

322
node_modules/@libsql/hrana-client/lib-cjs/ws/client.js generated vendored Normal file
View File

@@ -0,0 +1,322 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsClient = exports.subprotocolsV3 = exports.subprotocolsV2 = void 0;
const client_js_1 = require("../client.js");
const index_js_1 = require("../encoding/index.js");
const errors_js_1 = require("../errors.js");
const id_alloc_js_1 = require("../id_alloc.js");
const result_js_1 = require("../result.js");
const sql_js_1 = require("../sql.js");
const util_js_1 = require("../util.js");
const stream_js_1 = require("./stream.js");
const json_encode_js_1 = require("./json_encode.js");
const protobuf_encode_js_1 = require("./protobuf_encode.js");
const json_decode_js_1 = require("./json_decode.js");
const protobuf_decode_js_1 = require("./protobuf_decode.js");
exports.subprotocolsV2 = new Map([
["hrana2", { version: 2, encoding: "json" }],
["hrana1", { version: 1, encoding: "json" }],
]);
exports.subprotocolsV3 = new Map([
["hrana3-protobuf", { version: 3, encoding: "protobuf" }],
["hrana3", { version: 3, encoding: "json" }],
["hrana2", { version: 2, encoding: "json" }],
["hrana1", { version: 1, encoding: "json" }],
]);
/** A client for the Hrana protocol over a WebSocket. */
class WsClient extends client_js_1.Client {
#socket;
// List of callbacks that we queue until the socket transitions from the CONNECTING to the OPEN state.
#openCallbacks;
// Have we already transitioned from CONNECTING to OPEN and fired the callbacks in #openCallbacks?
#opened;
// Stores the error that caused us to close the client (and the socket). If we are not closed, this is
// `undefined`.
#closed;
// Have we received a response to our "hello" from the server?
#recvdHello;
// Subprotocol negotiated with the server. It is only available after the socket transitions to the OPEN
// state.
#subprotocol;
// Has the `getVersion()` function been called? This is only used to validate that the API is used
// correctly.
#getVersionCalled;
// A map from request id to the responses that we expect to receive from the server.
#responseMap;
// An allocator of request ids.
#requestIdAlloc;
// An allocator of stream ids.
/** @private */
_streamIdAlloc;
// An allocator of cursor ids.
/** @private */
_cursorIdAlloc;
// An allocator of SQL text ids.
#sqlIdAlloc;
/** @private */
constructor(socket, jwt) {
super();
this.#socket = socket;
this.#openCallbacks = [];
this.#opened = false;
this.#closed = undefined;
this.#recvdHello = false;
this.#subprotocol = undefined;
this.#getVersionCalled = false;
this.#responseMap = new Map();
this.#requestIdAlloc = new id_alloc_js_1.IdAlloc();
this._streamIdAlloc = new id_alloc_js_1.IdAlloc();
this._cursorIdAlloc = new id_alloc_js_1.IdAlloc();
this.#sqlIdAlloc = new id_alloc_js_1.IdAlloc();
this.#socket.binaryType = "arraybuffer";
this.#socket.addEventListener("open", () => this.#onSocketOpen());
this.#socket.addEventListener("close", (event) => this.#onSocketClose(event));
this.#socket.addEventListener("error", (event) => this.#onSocketError(event));
this.#socket.addEventListener("message", (event) => this.#onSocketMessage(event));
this.#send({ type: "hello", jwt });
}
// Send (or enqueue to send) a message to the server.
#send(msg) {
if (this.#closed !== undefined) {
throw new errors_js_1.InternalError("Trying to send a message on a closed client");
}
if (this.#opened) {
this.#sendToSocket(msg);
}
else {
const openCallback = () => this.#sendToSocket(msg);
const errorCallback = () => undefined;
this.#openCallbacks.push({ openCallback, errorCallback });
}
}
// The socket transitioned from CONNECTING to OPEN
#onSocketOpen() {
const protocol = this.#socket.protocol;
if (protocol === undefined) {
this.#setClosed(new errors_js_1.ClientError("The `WebSocket.protocol` property is undefined. This most likely means that the WebSocket " +
"implementation provided by the environment is broken. If you are using Miniflare 2, " +
"please update to Miniflare 3, which fixes this problem."));
return;
}
else if (protocol === "") {
this.#subprotocol = { version: 1, encoding: "json" };
}
else {
this.#subprotocol = exports.subprotocolsV3.get(protocol);
if (this.#subprotocol === undefined) {
this.#setClosed(new errors_js_1.ProtoError(`Unrecognized WebSocket subprotocol: ${JSON.stringify(protocol)}`));
return;
}
}
for (const callbacks of this.#openCallbacks) {
callbacks.openCallback();
}
this.#openCallbacks.length = 0;
this.#opened = true;
}
#sendToSocket(msg) {
const encoding = this.#subprotocol.encoding;
if (encoding === "json") {
const jsonMsg = (0, index_js_1.writeJsonObject)(msg, json_encode_js_1.ClientMsg);
this.#socket.send(jsonMsg);
}
else if (encoding === "protobuf") {
const protobufMsg = (0, index_js_1.writeProtobufMessage)(msg, protobuf_encode_js_1.ClientMsg);
this.#socket.send(protobufMsg);
}
else {
throw (0, util_js_1.impossible)(encoding, "Impossible encoding");
}
}
/** Get the protocol version negotiated with the server, possibly waiting until the socket is open. */
getVersion() {
return new Promise((versionCallback, errorCallback) => {
this.#getVersionCalled = true;
if (this.#closed !== undefined) {
errorCallback(this.#closed);
}
else if (!this.#opened) {
const openCallback = () => versionCallback(this.#subprotocol.version);
this.#openCallbacks.push({ openCallback, errorCallback });
}
else {
versionCallback(this.#subprotocol.version);
}
});
}
// Make sure that the negotiated version is at least `minVersion`.
/** @private */
_ensureVersion(minVersion, feature) {
if (this.#subprotocol === undefined || !this.#getVersionCalled) {
throw new errors_js_1.ProtocolVersionError(`${feature} is supported only on protocol version ${minVersion} and higher, ` +
"but the version supported by the WebSocket server is not yet known. " +
"Use Client.getVersion() to wait until the version is available.");
}
else if (this.#subprotocol.version < minVersion) {
throw new errors_js_1.ProtocolVersionError(`${feature} is supported on protocol version ${minVersion} and higher, ` +
`but the WebSocket server only supports version ${this.#subprotocol.version}`);
}
}
// Send a request to the server and invoke a callback when we get the response.
/** @private */
_sendRequest(request, callbacks) {
if (this.#closed !== undefined) {
callbacks.errorCallback(new errors_js_1.ClosedError("Client is closed", this.#closed));
return;
}
const requestId = this.#requestIdAlloc.alloc();
this.#responseMap.set(requestId, { ...callbacks, type: request.type });
this.#send({ type: "request", requestId, request });
}
// The socket encountered an error.
#onSocketError(event) {
const eventMessage = event.message;
const message = eventMessage ?? "WebSocket was closed due to an error";
this.#setClosed(new errors_js_1.WebSocketError(message));
}
// The socket was closed.
#onSocketClose(event) {
let message = `WebSocket was closed with code ${event.code}`;
if (event.reason) {
message += `: ${event.reason}`;
}
this.#setClosed(new errors_js_1.WebSocketError(message));
}
// Close the client with the given error.
#setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
for (const callbacks of this.#openCallbacks) {
callbacks.errorCallback(error);
}
this.#openCallbacks.length = 0;
for (const [requestId, responseState] of this.#responseMap.entries()) {
responseState.errorCallback(error);
this.#requestIdAlloc.free(requestId);
}
this.#responseMap.clear();
this.#socket.close();
}
// We received a message from the socket.
#onSocketMessage(event) {
if (this.#closed !== undefined) {
return;
}
try {
let msg;
const encoding = this.#subprotocol.encoding;
if (encoding === "json") {
if (typeof event.data !== "string") {
this.#socket.close(3003, "Only text messages are accepted with JSON encoding");
this.#setClosed(new errors_js_1.ProtoError("Received non-text message from server with JSON encoding"));
return;
}
msg = (0, index_js_1.readJsonObject)(JSON.parse(event.data), json_decode_js_1.ServerMsg);
}
else if (encoding === "protobuf") {
if (!(event.data instanceof ArrayBuffer)) {
this.#socket.close(3003, "Only binary messages are accepted with Protobuf encoding");
this.#setClosed(new errors_js_1.ProtoError("Received non-binary message from server with Protobuf encoding"));
return;
}
msg = (0, index_js_1.readProtobufMessage)(new Uint8Array(event.data), protobuf_decode_js_1.ServerMsg);
}
else {
throw (0, util_js_1.impossible)(encoding, "Impossible encoding");
}
this.#handleMsg(msg);
}
catch (e) {
this.#socket.close(3007, "Could not handle message");
this.#setClosed(e);
}
}
// Handle a message from the server.
#handleMsg(msg) {
if (msg.type === "none") {
throw new errors_js_1.ProtoError("Received an unrecognized ServerMsg");
}
else if (msg.type === "hello_ok" || msg.type === "hello_error") {
if (this.#recvdHello) {
throw new errors_js_1.ProtoError("Received a duplicated hello response");
}
this.#recvdHello = true;
if (msg.type === "hello_error") {
throw (0, result_js_1.errorFromProto)(msg.error);
}
return;
}
else if (!this.#recvdHello) {
throw new errors_js_1.ProtoError("Received a non-hello message before a hello response");
}
if (msg.type === "response_ok") {
const requestId = msg.requestId;
const responseState = this.#responseMap.get(requestId);
this.#responseMap.delete(requestId);
if (responseState === undefined) {
throw new errors_js_1.ProtoError("Received unexpected OK response");
}
this.#requestIdAlloc.free(requestId);
try {
if (responseState.type !== msg.response.type) {
console.dir({ responseState, msg });
throw new errors_js_1.ProtoError("Received unexpected type of response");
}
responseState.responseCallback(msg.response);
}
catch (e) {
responseState.errorCallback(e);
throw e;
}
}
else if (msg.type === "response_error") {
const requestId = msg.requestId;
const responseState = this.#responseMap.get(requestId);
this.#responseMap.delete(requestId);
if (responseState === undefined) {
throw new errors_js_1.ProtoError("Received unexpected error response");
}
this.#requestIdAlloc.free(requestId);
responseState.errorCallback((0, result_js_1.errorFromProto)(msg.error));
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible ServerMsg type");
}
}
/** Open a {@link WsStream}, a stream for executing SQL statements. */
openStream() {
return stream_js_1.WsStream.open(this);
}
/** Cache a SQL text on the server. This requires protocol version 2 or higher. */
storeSql(sql) {
this._ensureVersion(2, "storeSql()");
const sqlId = this.#sqlIdAlloc.alloc();
const sqlObj = new sql_js_1.Sql(this, sqlId);
const responseCallback = () => undefined;
const errorCallback = (e) => sqlObj._setClosed(e);
const request = { type: "store_sql", sqlId, sql };
this._sendRequest(request, { responseCallback, errorCallback });
return sqlObj;
}
/** @private */
_closeSql(sqlId) {
if (this.#closed !== undefined) {
return;
}
const responseCallback = () => this.#sqlIdAlloc.free(sqlId);
const errorCallback = (e) => this.#setClosed(e);
const request = { type: "close_sql", sqlId };
this._sendRequest(request, { responseCallback, errorCallback });
}
/** Close the client and the WebSocket. */
close() {
this.#setClosed(new errors_js_1.ClientError("Client was manually closed"));
}
/** True if the client is closed. */
get closed() {
return this.#closed !== undefined;
}
}
exports.WsClient = WsClient;

84
node_modules/@libsql/hrana-client/lib-cjs/ws/cursor.js generated vendored Normal file
View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsCursor = void 0;
const errors_js_1 = require("../errors.js");
const cursor_js_1 = require("../cursor.js");
const queue_js_1 = require("../queue.js");
const fetchChunkSize = 1000;
const fetchQueueSize = 10;
class WsCursor extends cursor_js_1.Cursor {
#client;
#stream;
#cursorId;
#entryQueue;
#fetchQueue;
#closed;
#done;
/** @private */
constructor(client, stream, cursorId) {
super();
this.#client = client;
this.#stream = stream;
this.#cursorId = cursorId;
this.#entryQueue = new queue_js_1.Queue();
this.#fetchQueue = new queue_js_1.Queue();
this.#closed = undefined;
this.#done = false;
}
/** Fetch the next entry from the cursor. */
async next() {
for (;;) {
if (this.#closed !== undefined) {
throw new errors_js_1.ClosedError("Cursor is closed", this.#closed);
}
while (!this.#done && this.#fetchQueue.length < fetchQueueSize) {
this.#fetchQueue.push(this.#fetch());
}
const entry = this.#entryQueue.shift();
if (this.#done || entry !== undefined) {
return entry;
}
// we assume that `Cursor.next()` is never called concurrently
await this.#fetchQueue.shift().then((response) => {
if (response === undefined) {
return;
}
for (const entry of response.entries) {
this.#entryQueue.push(entry);
}
this.#done ||= response.done;
});
}
}
#fetch() {
return this.#stream._sendCursorRequest(this, {
type: "fetch_cursor",
cursorId: this.#cursorId,
maxCount: fetchChunkSize,
}).then((resp) => resp, (error) => {
this._setClosed(error);
return undefined;
});
}
/** @private */
_setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
this.#stream._sendCursorRequest(this, {
type: "close_cursor",
cursorId: this.#cursorId,
}).catch(() => undefined);
this.#stream._cursorClosed(this);
}
/** Close the cursor. */
close() {
this._setClosed(new errors_js_1.ClientError("Cursor was manually closed"));
}
/** True if the cursor is closed. */
get closed() {
return this.#closed !== undefined;
}
}
exports.WsCursor = WsCursor;

View File

@@ -0,0 +1,101 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerMsg = void 0;
const errors_js_1 = require("../errors.js");
const d = __importStar(require("../encoding/json/decode.js"));
const json_decode_js_1 = require("../shared/json_decode.js");
function ServerMsg(obj) {
const type = d.string(obj["type"]);
if (type === "hello_ok") {
return { type: "hello_ok" };
}
else if (type === "hello_error") {
const error = (0, json_decode_js_1.Error)(d.object(obj["error"]));
return { type: "hello_error", error };
}
else if (type === "response_ok") {
const requestId = d.number(obj["request_id"]);
const response = Response(d.object(obj["response"]));
return { type: "response_ok", requestId, response };
}
else if (type === "response_error") {
const requestId = d.number(obj["request_id"]);
const error = (0, json_decode_js_1.Error)(d.object(obj["error"]));
return { type: "response_error", requestId, error };
}
else {
throw new errors_js_1.ProtoError("Unexpected type of ServerMsg");
}
}
exports.ServerMsg = ServerMsg;
function Response(obj) {
const type = d.string(obj["type"]);
if (type === "open_stream") {
return { type: "open_stream" };
}
else if (type === "close_stream") {
return { type: "close_stream" };
}
else if (type === "execute") {
const result = (0, json_decode_js_1.StmtResult)(d.object(obj["result"]));
return { type: "execute", result };
}
else if (type === "batch") {
const result = (0, json_decode_js_1.BatchResult)(d.object(obj["result"]));
return { type: "batch", result };
}
else if (type === "open_cursor") {
return { type: "open_cursor" };
}
else if (type === "close_cursor") {
return { type: "close_cursor" };
}
else if (type === "fetch_cursor") {
const entries = d.arrayObjectsMap(obj["entries"], json_decode_js_1.CursorEntry);
const done = d.boolean(obj["done"]);
return { type: "fetch_cursor", entries, done };
}
else if (type === "sequence") {
return { type: "sequence" };
}
else if (type === "describe") {
const result = (0, json_decode_js_1.DescribeResult)(d.object(obj["result"]));
return { type: "describe", result };
}
else if (type === "store_sql") {
return { type: "store_sql" };
}
else if (type === "close_sql") {
return { type: "close_sql" };
}
else if (type === "get_autocommit") {
const isAutocommit = d.boolean(obj["is_autocommit"]);
return { type: "get_autocommit", isAutocommit };
}
else {
throw new errors_js_1.ProtoError("Unexpected type of Response");
}
}

View File

@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientMsg = void 0;
const json_encode_js_1 = require("../shared/json_encode.js");
const util_js_1 = require("../util.js");
function ClientMsg(w, msg) {
w.stringRaw("type", msg.type);
if (msg.type === "hello") {
if (msg.jwt !== undefined) {
w.string("jwt", msg.jwt);
}
}
else if (msg.type === "request") {
w.number("request_id", msg.requestId);
w.object("request", msg.request, Request);
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of ClientMsg");
}
}
exports.ClientMsg = ClientMsg;
function Request(w, msg) {
w.stringRaw("type", msg.type);
if (msg.type === "open_stream") {
w.number("stream_id", msg.streamId);
}
else if (msg.type === "close_stream") {
w.number("stream_id", msg.streamId);
}
else if (msg.type === "execute") {
w.number("stream_id", msg.streamId);
w.object("stmt", msg.stmt, json_encode_js_1.Stmt);
}
else if (msg.type === "batch") {
w.number("stream_id", msg.streamId);
w.object("batch", msg.batch, json_encode_js_1.Batch);
}
else if (msg.type === "open_cursor") {
w.number("stream_id", msg.streamId);
w.number("cursor_id", msg.cursorId);
w.object("batch", msg.batch, json_encode_js_1.Batch);
}
else if (msg.type === "close_cursor") {
w.number("cursor_id", msg.cursorId);
}
else if (msg.type === "fetch_cursor") {
w.number("cursor_id", msg.cursorId);
w.number("max_count", msg.maxCount);
}
else if (msg.type === "sequence") {
w.number("stream_id", msg.streamId);
if (msg.sql !== undefined) {
w.string("sql", msg.sql);
}
if (msg.sqlId !== undefined) {
w.number("sql_id", msg.sqlId);
}
}
else if (msg.type === "describe") {
w.number("stream_id", msg.streamId);
if (msg.sql !== undefined) {
w.string("sql", msg.sql);
}
if (msg.sqlId !== undefined) {
w.number("sql_id", msg.sqlId);
}
}
else if (msg.type === "store_sql") {
w.number("sql_id", msg.sqlId);
w.string("sql", msg.sql);
}
else if (msg.type === "close_sql") {
w.number("sql_id", msg.sqlId);
}
else if (msg.type === "get_autocommit") {
w.number("stream_id", msg.streamId);
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of Request");
}
}

18
node_modules/@libsql/hrana-client/lib-cjs/ws/proto.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
// Types for the structures specific to Hrana over WebSockets.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("../shared/proto.js"), exports);

View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerMsg = void 0;
const protobuf_decode_js_1 = require("../shared/protobuf_decode.js");
exports.ServerMsg = {
default() { return { type: "none" }; },
1(r) { return { type: "hello_ok" }; },
2(r) { return r.message(HelloErrorMsg); },
3(r) { return r.message(ResponseOkMsg); },
4(r) { return r.message(ResponseErrorMsg); },
};
const HelloErrorMsg = {
default() { return { type: "hello_error", error: protobuf_decode_js_1.Error.default() }; },
1(r, msg) { msg.error = r.message(protobuf_decode_js_1.Error); },
};
const ResponseErrorMsg = {
default() { return { type: "response_error", requestId: 0, error: protobuf_decode_js_1.Error.default() }; },
1(r, msg) { msg.requestId = r.int32(); },
2(r, msg) { msg.error = r.message(protobuf_decode_js_1.Error); },
};
const ResponseOkMsg = {
default() {
return {
type: "response_ok",
requestId: 0,
response: { type: "none" },
};
},
1(r, msg) { msg.requestId = r.int32(); },
2(r, msg) { msg.response = { type: "open_stream" }; },
3(r, msg) { msg.response = { type: "close_stream" }; },
4(r, msg) { msg.response = r.message(ExecuteResp); },
5(r, msg) { msg.response = r.message(BatchResp); },
6(r, msg) { msg.response = { type: "open_cursor" }; },
7(r, msg) { msg.response = { type: "close_cursor" }; },
8(r, msg) { msg.response = r.message(FetchCursorResp); },
9(r, msg) { msg.response = { type: "sequence" }; },
10(r, msg) { msg.response = r.message(DescribeResp); },
11(r, msg) { msg.response = { type: "store_sql" }; },
12(r, msg) { msg.response = { type: "close_sql" }; },
13(r, msg) { msg.response = r.message(GetAutocommitResp); },
};
const ExecuteResp = {
default() { return { type: "execute", result: protobuf_decode_js_1.StmtResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.StmtResult); },
};
const BatchResp = {
default() { return { type: "batch", result: protobuf_decode_js_1.BatchResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.BatchResult); },
};
const FetchCursorResp = {
default() { return { type: "fetch_cursor", entries: [], done: false }; },
1(r, msg) { msg.entries.push(r.message(protobuf_decode_js_1.CursorEntry)); },
2(r, msg) { msg.done = r.bool(); },
};
const DescribeResp = {
default() { return { type: "describe", result: protobuf_decode_js_1.DescribeResult.default() }; },
1(r, msg) { msg.result = r.message(protobuf_decode_js_1.DescribeResult); },
};
const GetAutocommitResp = {
default() { return { type: "get_autocommit", isAutocommit: false }; },
1(r, msg) { msg.isAutocommit = r.bool(); },
};

View File

@@ -0,0 +1,119 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientMsg = void 0;
const protobuf_encode_js_1 = require("../shared/protobuf_encode.js");
const util_js_1 = require("../util.js");
function ClientMsg(w, msg) {
if (msg.type === "hello") {
w.message(1, msg, HelloMsg);
}
else if (msg.type === "request") {
w.message(2, msg, RequestMsg);
}
else {
throw (0, util_js_1.impossible)(msg, "Impossible type of ClientMsg");
}
}
exports.ClientMsg = ClientMsg;
function HelloMsg(w, msg) {
if (msg.jwt !== undefined) {
w.string(1, msg.jwt);
}
}
function RequestMsg(w, msg) {
w.int32(1, msg.requestId);
const request = msg.request;
if (request.type === "open_stream") {
w.message(2, request, OpenStreamReq);
}
else if (request.type === "close_stream") {
w.message(3, request, CloseStreamReq);
}
else if (request.type === "execute") {
w.message(4, request, ExecuteReq);
}
else if (request.type === "batch") {
w.message(5, request, BatchReq);
}
else if (request.type === "open_cursor") {
w.message(6, request, OpenCursorReq);
}
else if (request.type === "close_cursor") {
w.message(7, request, CloseCursorReq);
}
else if (request.type === "fetch_cursor") {
w.message(8, request, FetchCursorReq);
}
else if (request.type === "sequence") {
w.message(9, request, SequenceReq);
}
else if (request.type === "describe") {
w.message(10, request, DescribeReq);
}
else if (request.type === "store_sql") {
w.message(11, request, StoreSqlReq);
}
else if (request.type === "close_sql") {
w.message(12, request, CloseSqlReq);
}
else if (request.type === "get_autocommit") {
w.message(13, request, GetAutocommitReq);
}
else {
throw (0, util_js_1.impossible)(request, "Impossible type of Request");
}
}
function OpenStreamReq(w, msg) {
w.int32(1, msg.streamId);
}
function CloseStreamReq(w, msg) {
w.int32(1, msg.streamId);
}
function ExecuteReq(w, msg) {
w.int32(1, msg.streamId);
w.message(2, msg.stmt, protobuf_encode_js_1.Stmt);
}
function BatchReq(w, msg) {
w.int32(1, msg.streamId);
w.message(2, msg.batch, protobuf_encode_js_1.Batch);
}
function OpenCursorReq(w, msg) {
w.int32(1, msg.streamId);
w.int32(2, msg.cursorId);
w.message(3, msg.batch, protobuf_encode_js_1.Batch);
}
function CloseCursorReq(w, msg) {
w.int32(1, msg.cursorId);
}
function FetchCursorReq(w, msg) {
w.int32(1, msg.cursorId);
w.uint32(2, msg.maxCount);
}
function SequenceReq(w, msg) {
w.int32(1, msg.streamId);
if (msg.sql !== undefined) {
w.string(2, msg.sql);
}
if (msg.sqlId !== undefined) {
w.int32(3, msg.sqlId);
}
}
function DescribeReq(w, msg) {
w.int32(1, msg.streamId);
if (msg.sql !== undefined) {
w.string(2, msg.sql);
}
if (msg.sqlId !== undefined) {
w.int32(3, msg.sqlId);
}
}
function StoreSqlReq(w, msg) {
w.int32(1, msg.sqlId);
w.string(2, msg.sql);
}
function CloseSqlReq(w, msg) {
w.int32(1, msg.sqlId);
}
function GetAutocommitReq(w, msg) {
w.int32(1, msg.streamId);
}

215
node_modules/@libsql/hrana-client/lib-cjs/ws/stream.js generated vendored Normal file
View File

@@ -0,0 +1,215 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsStream = void 0;
const errors_js_1 = require("../errors.js");
const queue_js_1 = require("../queue.js");
const stream_js_1 = require("../stream.js");
const cursor_js_1 = require("./cursor.js");
class WsStream extends stream_js_1.Stream {
#client;
#streamId;
#queue;
#cursor;
#closing;
#closed;
/** @private */
static open(client) {
const streamId = client._streamIdAlloc.alloc();
const stream = new WsStream(client, streamId);
const responseCallback = () => undefined;
const errorCallback = (e) => stream.#setClosed(e);
const request = { type: "open_stream", streamId };
client._sendRequest(request, { responseCallback, errorCallback });
return stream;
}
/** @private */
constructor(client, streamId) {
super(client.intMode);
this.#client = client;
this.#streamId = streamId;
this.#queue = new queue_js_1.Queue();
this.#cursor = undefined;
this.#closing = false;
this.#closed = undefined;
}
/** Get the {@link WsClient} object that this stream belongs to. */
client() {
return this.#client;
}
/** @private */
_sqlOwner() {
return this.#client;
}
/** @private */
_execute(stmt) {
return this.#sendStreamRequest({
type: "execute",
streamId: this.#streamId,
stmt,
}).then((response) => {
return response.result;
});
}
/** @private */
_batch(batch) {
return this.#sendStreamRequest({
type: "batch",
streamId: this.#streamId,
batch,
}).then((response) => {
return response.result;
});
}
/** @private */
_describe(protoSql) {
this.#client._ensureVersion(2, "describe()");
return this.#sendStreamRequest({
type: "describe",
streamId: this.#streamId,
sql: protoSql.sql,
sqlId: protoSql.sqlId,
}).then((response) => {
return response.result;
});
}
/** @private */
_sequence(protoSql) {
this.#client._ensureVersion(2, "sequence()");
return this.#sendStreamRequest({
type: "sequence",
streamId: this.#streamId,
sql: protoSql.sql,
sqlId: protoSql.sqlId,
}).then((_response) => {
return undefined;
});
}
/** Check whether the SQL connection underlying this stream is in autocommit state (i.e., outside of an
* explicit transaction). This requires protocol version 3 or higher.
*/
getAutocommit() {
this.#client._ensureVersion(3, "getAutocommit()");
return this.#sendStreamRequest({
type: "get_autocommit",
streamId: this.#streamId,
}).then((response) => {
return response.isAutocommit;
});
}
#sendStreamRequest(request) {
return new Promise((responseCallback, errorCallback) => {
this.#pushToQueue({ type: "request", request, responseCallback, errorCallback });
});
}
/** @private */
_openCursor(batch) {
this.#client._ensureVersion(3, "cursor");
return new Promise((cursorCallback, errorCallback) => {
this.#pushToQueue({ type: "cursor", batch, cursorCallback, errorCallback });
});
}
/** @private */
_sendCursorRequest(cursor, request) {
if (cursor !== this.#cursor) {
throw new errors_js_1.InternalError("Cursor not associated with the stream attempted to execute a request");
}
return new Promise((responseCallback, errorCallback) => {
if (this.#closed !== undefined) {
errorCallback(new errors_js_1.ClosedError("Stream is closed", this.#closed));
}
else {
this.#client._sendRequest(request, { responseCallback, errorCallback });
}
});
}
/** @private */
_cursorClosed(cursor) {
if (cursor !== this.#cursor) {
throw new errors_js_1.InternalError("Cursor was closed, but it was not associated with the stream");
}
this.#cursor = undefined;
this.#flushQueue();
}
#pushToQueue(entry) {
if (this.#closed !== undefined) {
entry.errorCallback(new errors_js_1.ClosedError("Stream is closed", this.#closed));
}
else if (this.#closing) {
entry.errorCallback(new errors_js_1.ClosedError("Stream is closing", undefined));
}
else {
this.#queue.push(entry);
this.#flushQueue();
}
}
#flushQueue() {
for (;;) {
const entry = this.#queue.first();
if (entry === undefined && this.#cursor === undefined && this.#closing) {
this.#setClosed(new errors_js_1.ClientError("Stream was gracefully closed"));
break;
}
else if (entry?.type === "request" && this.#cursor === undefined) {
const { request, responseCallback, errorCallback } = entry;
this.#queue.shift();
this.#client._sendRequest(request, { responseCallback, errorCallback });
}
else if (entry?.type === "cursor" && this.#cursor === undefined) {
const { batch, cursorCallback } = entry;
this.#queue.shift();
const cursorId = this.#client._cursorIdAlloc.alloc();
const cursor = new cursor_js_1.WsCursor(this.#client, this, cursorId);
const request = {
type: "open_cursor",
streamId: this.#streamId,
cursorId,
batch,
};
const responseCallback = () => undefined;
const errorCallback = (e) => cursor._setClosed(e);
this.#client._sendRequest(request, { responseCallback, errorCallback });
this.#cursor = cursor;
cursorCallback(cursor);
}
else {
break;
}
}
}
#setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
if (this.#cursor !== undefined) {
this.#cursor._setClosed(error);
}
for (;;) {
const entry = this.#queue.shift();
if (entry !== undefined) {
entry.errorCallback(error);
}
else {
break;
}
}
const request = { type: "close_stream", streamId: this.#streamId };
const responseCallback = () => this.#client._streamIdAlloc.free(this.#streamId);
const errorCallback = () => undefined;
this.#client._sendRequest(request, { responseCallback, errorCallback });
}
/** Immediately close the stream. */
close() {
this.#setClosed(new errors_js_1.ClientError("Stream was manually closed"));
}
/** Gracefully close the stream. */
closeGracefully() {
this.#closing = true;
this.#flushQueue();
}
/** True if the stream is closed or closing. */
get closed() {
return this.#closed !== undefined || this.#closing;
}
}
exports.WsStream = WsStream;

77
node_modules/@libsql/hrana-client/lib-esm/batch.d.ts generated vendored Normal file
View File

@@ -0,0 +1,77 @@
import type { RowsResult, RowResult, ValueResult, StmtResult } from "./result.js";
import type * as proto from "./shared/proto.js";
import type { InStmt } from "./stmt.js";
import { Stream } from "./stream.js";
/** A builder for creating a batch and executing it on the server. */
export declare class Batch {
#private;
/** @private */
_stream: Stream;
/** @private */
_steps: Array<BatchStepState>;
/** @private */
constructor(stream: Stream, useCursor: boolean);
/** Return a builder for adding a step to the batch. */
step(): BatchStep;
/** Execute the batch. */
execute(): Promise<void>;
}
interface BatchStepState {
proto: proto.BatchStep;
callback(stepResult: proto.StmtResult | undefined, stepError: proto.Error | undefined): void;
}
/** A builder for adding a step to the batch. */
export declare class BatchStep {
#private;
/** @private */
_batch: Batch;
/** @private */
_index: number | undefined;
/** @private */
constructor(batch: Batch);
/** Add the condition that needs to be satisfied to execute the statement. If you use this method multiple
* times, we join the conditions with a logical AND. */
condition(cond: BatchCond): this;
/** Add a statement that returns rows. */
query(stmt: InStmt): Promise<RowsResult | undefined>;
/** Add a statement that returns at most a single row. */
queryRow(stmt: InStmt): Promise<RowResult | undefined>;
/** Add a statement that returns at most a single value. */
queryValue(stmt: InStmt): Promise<ValueResult | undefined>;
/** Add a statement without returning rows. */
run(stmt: InStmt): Promise<StmtResult | undefined>;
}
export declare class BatchCond {
/** @private */
_batch: Batch;
/** @private */
_proto: proto.BatchCond;
/** @private */
constructor(batch: Batch, proto: proto.BatchCond);
/** Create a condition that evaluates to true when the given step executes successfully.
*
* If the given step fails error or is skipped because its condition evaluated to false, this
* condition evaluates to false.
*/
static ok(step: BatchStep): BatchCond;
/** Create a condition that evaluates to true when the given step fails.
*
* If the given step succeeds or is skipped because its condition evaluated to false, this condition
* evaluates to false.
*/
static error(step: BatchStep): BatchCond;
/** Create a condition that is a logical negation of another condition.
*/
static not(cond: BatchCond): BatchCond;
/** Create a condition that is a logical AND of other conditions.
*/
static and(batch: Batch, conds: Array<BatchCond>): BatchCond;
/** Create a condition that is a logical OR of other conditions.
*/
static or(batch: Batch, conds: Array<BatchCond>): BatchCond;
/** Create a condition that evaluates to true when the SQL connection is in autocommit mode (not inside an
* explicit transaction). This requires protocol version 3 or higher.
*/
static isAutocommit(batch: Batch): BatchCond;
}
export {};

271
node_modules/@libsql/hrana-client/lib-esm/batch.js generated vendored Normal file
View File

@@ -0,0 +1,271 @@
import { ProtoError, MisuseError } from "./errors.js";
import { stmtResultFromProto, rowsResultFromProto, rowResultFromProto, valueResultFromProto, errorFromProto, } from "./result.js";
import { stmtToProto } from "./stmt.js";
import { impossible } from "./util.js";
/** A builder for creating a batch and executing it on the server. */
export class Batch {
/** @private */
_stream;
#useCursor;
/** @private */
_steps;
#executed;
/** @private */
constructor(stream, useCursor) {
this._stream = stream;
this.#useCursor = useCursor;
this._steps = [];
this.#executed = false;
}
/** Return a builder for adding a step to the batch. */
step() {
return new BatchStep(this);
}
/** Execute the batch. */
execute() {
if (this.#executed) {
throw new MisuseError("This batch has already been executed");
}
this.#executed = true;
const batch = {
steps: this._steps.map((step) => step.proto),
};
if (this.#useCursor) {
return executeCursor(this._stream, this._steps, batch);
}
else {
return executeRegular(this._stream, this._steps, batch);
}
}
}
function executeRegular(stream, steps, batch) {
return stream._batch(batch).then((result) => {
for (let step = 0; step < steps.length; ++step) {
const stepResult = result.stepResults.get(step);
const stepError = result.stepErrors.get(step);
steps[step].callback(stepResult, stepError);
}
});
}
async function executeCursor(stream, steps, batch) {
const cursor = await stream._openCursor(batch);
try {
let nextStep = 0;
let beginEntry = undefined;
let rows = [];
for (;;) {
const entry = await cursor.next();
if (entry === undefined) {
break;
}
if (entry.type === "step_begin") {
if (entry.step < nextStep || entry.step >= steps.length) {
throw new ProtoError("Server produced StepBeginEntry for unexpected step");
}
else if (beginEntry !== undefined) {
throw new ProtoError("Server produced StepBeginEntry before terminating previous step");
}
for (let step = nextStep; step < entry.step; ++step) {
steps[step].callback(undefined, undefined);
}
nextStep = entry.step + 1;
beginEntry = entry;
rows = [];
}
else if (entry.type === "step_end") {
if (beginEntry === undefined) {
throw new ProtoError("Server produced StepEndEntry but no step is active");
}
const stmtResult = {
cols: beginEntry.cols,
rows,
affectedRowCount: entry.affectedRowCount,
lastInsertRowid: entry.lastInsertRowid,
};
steps[beginEntry.step].callback(stmtResult, undefined);
beginEntry = undefined;
rows = [];
}
else if (entry.type === "step_error") {
if (beginEntry === undefined) {
if (entry.step >= steps.length) {
throw new ProtoError("Server produced StepErrorEntry for unexpected step");
}
for (let step = nextStep; step < entry.step; ++step) {
steps[step].callback(undefined, undefined);
}
}
else {
if (entry.step !== beginEntry.step) {
throw new ProtoError("Server produced StepErrorEntry for unexpected step");
}
beginEntry = undefined;
rows = [];
}
steps[entry.step].callback(undefined, entry.error);
nextStep = entry.step + 1;
}
else if (entry.type === "row") {
if (beginEntry === undefined) {
throw new ProtoError("Server produced RowEntry but no step is active");
}
rows.push(entry.row);
}
else if (entry.type === "error") {
throw errorFromProto(entry.error);
}
else if (entry.type === "none") {
throw new ProtoError("Server produced unrecognized CursorEntry");
}
else {
throw impossible(entry, "Impossible CursorEntry");
}
}
if (beginEntry !== undefined) {
throw new ProtoError("Server closed Cursor before terminating active step");
}
for (let step = nextStep; step < steps.length; ++step) {
steps[step].callback(undefined, undefined);
}
}
finally {
cursor.close();
}
}
/** A builder for adding a step to the batch. */
export class BatchStep {
/** @private */
_batch;
#conds;
/** @private */
_index;
/** @private */
constructor(batch) {
this._batch = batch;
this.#conds = [];
this._index = undefined;
}
/** Add the condition that needs to be satisfied to execute the statement. If you use this method multiple
* times, we join the conditions with a logical AND. */
condition(cond) {
this.#conds.push(cond._proto);
return this;
}
/** Add a statement that returns rows. */
query(stmt) {
return this.#add(stmt, true, rowsResultFromProto);
}
/** Add a statement that returns at most a single row. */
queryRow(stmt) {
return this.#add(stmt, true, rowResultFromProto);
}
/** Add a statement that returns at most a single value. */
queryValue(stmt) {
return this.#add(stmt, true, valueResultFromProto);
}
/** Add a statement without returning rows. */
run(stmt) {
return this.#add(stmt, false, stmtResultFromProto);
}
#add(inStmt, wantRows, fromProto) {
if (this._index !== undefined) {
throw new MisuseError("This BatchStep has already been added to the batch");
}
const stmt = stmtToProto(this._batch._stream._sqlOwner(), inStmt, wantRows);
let condition;
if (this.#conds.length === 0) {
condition = undefined;
}
else if (this.#conds.length === 1) {
condition = this.#conds[0];
}
else {
condition = { type: "and", conds: this.#conds.slice() };
}
const proto = { stmt, condition };
return new Promise((outputCallback, errorCallback) => {
const callback = (stepResult, stepError) => {
if (stepResult !== undefined && stepError !== undefined) {
errorCallback(new ProtoError("Server returned both result and error"));
}
else if (stepError !== undefined) {
errorCallback(errorFromProto(stepError));
}
else if (stepResult !== undefined) {
outputCallback(fromProto(stepResult, this._batch._stream.intMode));
}
else {
outputCallback(undefined);
}
};
this._index = this._batch._steps.length;
this._batch._steps.push({ proto, callback });
});
}
}
export class BatchCond {
/** @private */
_batch;
/** @private */
_proto;
/** @private */
constructor(batch, proto) {
this._batch = batch;
this._proto = proto;
}
/** Create a condition that evaluates to true when the given step executes successfully.
*
* If the given step fails error or is skipped because its condition evaluated to false, this
* condition evaluates to false.
*/
static ok(step) {
return new BatchCond(step._batch, { type: "ok", step: stepIndex(step) });
}
/** Create a condition that evaluates to true when the given step fails.
*
* If the given step succeeds or is skipped because its condition evaluated to false, this condition
* evaluates to false.
*/
static error(step) {
return new BatchCond(step._batch, { type: "error", step: stepIndex(step) });
}
/** Create a condition that is a logical negation of another condition.
*/
static not(cond) {
return new BatchCond(cond._batch, { type: "not", cond: cond._proto });
}
/** Create a condition that is a logical AND of other conditions.
*/
static and(batch, conds) {
for (const cond of conds) {
checkCondBatch(batch, cond);
}
return new BatchCond(batch, { type: "and", conds: conds.map(e => e._proto) });
}
/** Create a condition that is a logical OR of other conditions.
*/
static or(batch, conds) {
for (const cond of conds) {
checkCondBatch(batch, cond);
}
return new BatchCond(batch, { type: "or", conds: conds.map(e => e._proto) });
}
/** Create a condition that evaluates to true when the SQL connection is in autocommit mode (not inside an
* explicit transaction). This requires protocol version 3 or higher.
*/
static isAutocommit(batch) {
batch._stream.client()._ensureVersion(3, "BatchCond.isAutocommit()");
return new BatchCond(batch, { type: "is_autocommit" });
}
}
function stepIndex(step) {
if (step._index === undefined) {
throw new MisuseError("Cannot add a condition referencing a step that has not been added to the batch");
}
return step._index;
}
function checkCondBatch(expectedBatch, cond) {
if (cond._batch !== expectedBatch) {
throw new MisuseError("Cannot mix BatchCond objects for different Batch objects");
}
}

View File

@@ -0,0 +1,8 @@
export declare class ByteQueue {
#private;
constructor(initialCap: number);
get length(): number;
data(): Uint8Array;
push(chunk: Uint8Array): void;
shift(length: number): void;
}

View File

@@ -0,0 +1,45 @@
export class ByteQueue {
#array;
#shiftPos;
#pushPos;
constructor(initialCap) {
this.#array = new Uint8Array(new ArrayBuffer(initialCap));
this.#shiftPos = 0;
this.#pushPos = 0;
}
get length() {
return this.#pushPos - this.#shiftPos;
}
data() {
return this.#array.slice(this.#shiftPos, this.#pushPos);
}
push(chunk) {
this.#ensurePush(chunk.byteLength);
this.#array.set(chunk, this.#pushPos);
this.#pushPos += chunk.byteLength;
}
#ensurePush(pushLength) {
if (this.#pushPos + pushLength <= this.#array.byteLength) {
return;
}
const filledLength = this.#pushPos - this.#shiftPos;
if (filledLength + pushLength <= this.#array.byteLength &&
2 * this.#pushPos >= this.#array.byteLength) {
this.#array.copyWithin(0, this.#shiftPos, this.#pushPos);
}
else {
let newCap = this.#array.byteLength;
do {
newCap *= 2;
} while (filledLength + pushLength > newCap);
const newArray = new Uint8Array(new ArrayBuffer(newCap));
newArray.set(this.#array.slice(this.#shiftPos, this.#pushPos), 0);
this.#array = newArray;
}
this.#pushPos = filledLength;
this.#shiftPos = 0;
}
shift(length) {
this.#shiftPos += length;
}
}

28
node_modules/@libsql/hrana-client/lib-esm/client.d.ts generated vendored Normal file
View File

@@ -0,0 +1,28 @@
import type { Stream } from "./stream.js";
import type { IntMode } from "./value.js";
export type ProtocolVersion = 1 | 2 | 3;
export type ProtocolEncoding = "json" | "protobuf";
/** A client for the Hrana protocol (a "database connection pool"). */
export declare abstract class Client {
/** @private */
constructor();
/** Get the protocol version negotiated with the server. */
abstract getVersion(): Promise<ProtocolVersion>;
/** @private */
abstract _ensureVersion(minVersion: ProtocolVersion, feature: string): void;
/** Open a {@link Stream}, a stream for executing SQL statements. */
abstract openStream(): Stream;
/** Immediately close the client.
*
* This closes the client immediately, aborting any pending operations.
*/
abstract close(): void;
/** True if the client is closed. */
abstract get closed(): boolean;
/** Representation of integers returned from the database. See {@link IntMode}.
*
* This value is inherited by {@link Stream} objects created with {@link openStream}, but you can
* override the integer mode for every stream by setting {@link Stream.intMode} on the stream.
*/
intMode: IntMode;
}

13
node_modules/@libsql/hrana-client/lib-esm/client.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
/** A client for the Hrana protocol (a "database connection pool"). */
export class Client {
/** @private */
constructor() {
this.intMode = "number";
}
/** Representation of integers returned from the database. See {@link IntMode}.
*
* This value is inherited by {@link Stream} objects created with {@link openStream}, but you can
* override the integer mode for every stream by setting {@link Stream.intMode} on the stream.
*/
intMode;
}

View File

@@ -0,0 +1,9 @@
import type * as proto from "./shared/proto.js";
export declare abstract class Cursor {
/** Fetch the next entry from the cursor. */
abstract next(): Promise<proto.CursorEntry | undefined>;
/** Close the cursor. */
abstract close(): void;
/** True if the cursor is closed. */
abstract get closed(): boolean;
}

2
node_modules/@libsql/hrana-client/lib-esm/cursor.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export class Cursor {
}

View File

@@ -0,0 +1,12 @@
import type * as proto from "./shared/proto.js";
export interface DescribeResult {
paramNames: Array<string | undefined>;
columns: Array<DescribeColumn>;
isExplain: boolean;
isReadonly: boolean;
}
export interface DescribeColumn {
name: string;
decltype: string | undefined;
}
export declare function describeResultFromProto(result: proto.DescribeResult): DescribeResult;

View File

@@ -0,0 +1,8 @@
export function describeResultFromProto(result) {
return {
paramNames: result.params.map((p) => p.name),
columns: result.cols,
isExplain: result.isExplain,
isReadonly: result.isReadonly,
};
}

View File

@@ -0,0 +1,4 @@
export { readJsonObject } from "./json/decode.js";
export { writeJsonObject } from "./json/encode.js";
export { readProtobufMessage } from "./protobuf/decode.js";
export { writeProtobufMessage } from "./protobuf/encode.js";

View File

@@ -0,0 +1,4 @@
export { readJsonObject } from "./json/decode.js";
export { writeJsonObject } from "./json/encode.js";
export { readProtobufMessage } from "./protobuf/decode.js";
export { writeProtobufMessage } from "./protobuf/encode.js";

Some files were not shown because too many files have changed in this diff Show More