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

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";

View File

@@ -0,0 +1,13 @@
export type Value = Obj | Array<Value> | string | number | true | false | null;
export type Obj = {
[key: string]: Value | undefined;
};
export type ObjectFun<T> = (obj: Obj) => T;
export declare function string(value: Value | undefined): string;
export declare function stringOpt(value: Value | undefined): string | undefined;
export declare function number(value: Value | undefined): number;
export declare function boolean(value: Value | undefined): boolean;
export declare function array(value: Value | undefined): Array<Value>;
export declare function object(value: Value | undefined): Obj;
export declare function arrayObjectsMap<T>(value: Value | undefined, fun: ObjectFun<T>): Array<T>;
export declare function readJsonObject<T>(value: unknown, fun: ObjectFun<T>): T;

View File

@@ -0,0 +1,59 @@
import { ProtoError } from "../../errors.js";
export function string(value) {
if (typeof value === "string") {
return value;
}
throw typeError(value, "string");
}
export function stringOpt(value) {
if (value === null || value === undefined) {
return undefined;
}
else if (typeof value === "string") {
return value;
}
throw typeError(value, "string or null");
}
export function number(value) {
if (typeof value === "number") {
return value;
}
throw typeError(value, "number");
}
export function boolean(value) {
if (typeof value === "boolean") {
return value;
}
throw typeError(value, "boolean");
}
export function array(value) {
if (Array.isArray(value)) {
return value;
}
throw typeError(value, "array");
}
export function object(value) {
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
return value;
}
throw typeError(value, "object");
}
export function arrayObjectsMap(value, fun) {
return array(value).map((elemValue) => fun(object(elemValue)));
}
function typeError(value, expected) {
if (value === undefined) {
return new 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 ProtoError(`Expected ${expected}, received ${received}`);
}
export function readJsonObject(value, fun) {
return fun(object(value));
}

View File

@@ -0,0 +1,14 @@
export type ObjectFun<T> = (w: ObjectWriter, value: T) => void;
export declare class ObjectWriter {
#private;
constructor(output: Array<string>);
begin(): void;
end(): void;
string(name: string, value: string): void;
stringRaw(name: string, value: string): void;
number(name: string, value: number): void;
boolean(name: string, value: boolean): void;
object<T>(name: string, value: T, valueFun: ObjectFun<T>): void;
arrayObjects<T>(name: string, values: Array<T>, valueFun: ObjectFun<T>): void;
}
export declare function writeJsonObject<T>(value: T, fun: ObjectFun<T>): string;

View File

@@ -0,0 +1,72 @@
export 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(']');
}
}
export function writeJsonObject(value, fun) {
const output = [];
const writer = new ObjectWriter(output);
writer.begin();
fun(writer, value);
writer.end();
return output.join("");
}

View File

@@ -0,0 +1,32 @@
export interface MessageDef<T> {
default(): T;
[tag: number]: (r: FieldReader, msg: T) => T | void;
}
declare class MessageReader {
#private;
constructor(array: Uint8Array);
varint(): number;
varintBig(): bigint;
bytes(length: number): Uint8Array;
double(): number;
skipVarint(): void;
skip(count: number): void;
eof(): boolean;
}
export declare class FieldReader {
#private;
constructor(reader: MessageReader);
setup(wireType: number): void;
bytes(): Uint8Array;
string(): string;
message<T>(def: MessageDef<T>): T;
int32(): number;
uint32(): number;
bool(): boolean;
uint64(): bigint;
sint64(): bigint;
double(): number;
maybeSkip(): void;
}
export declare function readProtobufMessage<T>(data: Uint8Array, def: MessageDef<T>): T;
export {};

View File

@@ -0,0 +1,150 @@
import { ProtoError } from "../../errors.js";
import { VARINT, FIXED_64, LENGTH_DELIMITED, FIXED_32 } from "./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;
}
}
export 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 ProtoError(`Expected wire type ${expectedWireType}, got ${this.#wireType}`);
}
this.#wireType = -1;
}
bytes() {
this.#expect(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(VARINT);
return this.#reader.varint();
}
uint32() {
return this.int32();
}
bool() {
return this.int32() !== 0;
}
uint64() {
this.#expect(VARINT);
return this.#reader.varintBig();
}
sint64() {
const value = this.uint64();
return (value >> 1n) ^ (-(value & 1n));
}
double() {
this.#expect(FIXED_64);
return this.#reader.double();
}
maybeSkip() {
if (this.#wireType < 0) {
return;
}
else if (this.#wireType === VARINT) {
this.#reader.skipVarint();
}
else if (this.#wireType === FIXED_64) {
this.#reader.skip(8);
}
else if (this.#wireType === LENGTH_DELIMITED) {
const length = this.#reader.varint();
this.#reader.skip(length);
}
else if (this.#wireType === FIXED_32) {
this.#reader.skip(4);
}
else {
throw new ProtoError(`Unexpected wire type ${this.#wireType}`);
}
this.#wireType = -1;
}
}
export 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;
}

View File

@@ -0,0 +1,15 @@
export type MessageFun<T> = (w: MessageWriter, msg: T) => void;
export declare class MessageWriter {
#private;
constructor();
bytes(tag: number, value: Uint8Array): void;
string(tag: number, value: string): void;
message<T>(tag: number, value: T, fun: MessageFun<T>): void;
int32(tag: number, value: number): void;
uint32(tag: number, value: number): void;
bool(tag: number, value: boolean): void;
sint64(tag: number, value: bigint): void;
double(tag: number, value: number): void;
data(): Uint8Array;
}
export declare function writeProtobufMessage<T>(value: T, fun: MessageFun<T>): Uint8Array;

View File

@@ -0,0 +1,95 @@
import { VARINT, FIXED_64, LENGTH_DELIMITED } from "./util.js";
export 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, 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, 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, VARINT);
this.#varintBig((value << 1n) ^ (value >> 63n));
}
double(tag, value) {
this.#tag(tag, FIXED_64);
this.#ensure(8);
this.#view.setFloat64(this.#pos, value, true);
this.#pos += 8;
}
data() {
return new Uint8Array(this.#buf, 0, this.#pos);
}
}
export function writeProtobufMessage(value, fun) {
const w = new MessageWriter();
fun(w, value);
return w.data();
}

View File

@@ -0,0 +1,7 @@
export type WireType = 0 | 1 | 2 | 3 | 4 | 5;
export declare const VARINT: WireType;
export declare const FIXED_64: WireType;
export declare const LENGTH_DELIMITED: WireType;
export declare const GROUP_START: WireType;
export declare const GROUP_END: WireType;
export declare const FIXED_32: WireType;

View File

@@ -0,0 +1,6 @@
export const VARINT = 0;
export const FIXED_64 = 1;
export const LENGTH_DELIMITED = 2;
export const GROUP_START = 3;
export const GROUP_END = 4;
export const FIXED_32 = 5;

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

@@ -0,0 +1,60 @@
import type * as proto from "./shared/proto.js";
/** Generic error produced by the Hrana client. */
export declare class ClientError extends Error {
/** @private */
constructor(message: string);
}
/** Error thrown when the server violates the protocol. */
export declare class ProtoError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when the server returns an error response. */
export declare class ResponseError extends ClientError {
code: string | undefined;
/** @internal */
proto: proto.Error;
/** @private */
constructor(message: string, protoError: proto.Error);
}
/** Error thrown when the client or stream is closed. */
export declare class ClosedError extends ClientError {
/** @private */
constructor(message: string, cause: Error | undefined);
}
/** Error thrown when the environment does not seem to support WebSockets. */
export declare class WebSocketUnsupportedError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when we encounter a WebSocket error. */
export declare class WebSocketError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when the HTTP server returns an error response. */
export declare class HttpServerError extends ClientError {
status: number;
/** @private */
constructor(message: string, status: number);
}
/** Error thrown when a libsql URL is not valid. */
export declare class LibsqlUrlParseError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when the protocol version is too low to support a feature. */
export declare class ProtocolVersionError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when an internal client error happens. */
export declare class InternalError extends ClientError {
/** @private */
constructor(message: string);
}
/** Error thrown when the API is misused. */
export declare class MisuseError extends ClientError {
/** @private */
constructor(message: string);
}

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

@@ -0,0 +1,102 @@
/** Generic error produced by the Hrana client. */
export class ClientError extends Error {
/** @private */
constructor(message) {
super(message);
this.name = "ClientError";
}
}
/** Error thrown when the server violates the protocol. */
export class ProtoError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "ProtoError";
}
}
/** Error thrown when the server returns an error response. */
export 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;
}
}
/** Error thrown when the client or stream is closed. */
export class ClosedError extends ClientError {
/** @private */
constructor(message, cause) {
if (cause !== undefined) {
super(`${message}: ${cause}`);
this.cause = cause;
}
else {
super(message);
}
this.name = "ClosedError";
}
}
/** Error thrown when the environment does not seem to support WebSockets. */
export class WebSocketUnsupportedError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "WebSocketUnsupportedError";
}
}
/** Error thrown when we encounter a WebSocket error. */
export class WebSocketError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "WebSocketError";
}
}
/** Error thrown when the HTTP server returns an error response. */
export class HttpServerError extends ClientError {
status;
/** @private */
constructor(message, status) {
super(message);
this.status = status;
this.name = "HttpServerError";
}
}
/** Error thrown when a libsql URL is not valid. */
export class LibsqlUrlParseError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "LibsqlUrlParseError";
}
}
/** Error thrown when the protocol version is too low to support a feature. */
export class ProtocolVersionError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "ProtocolVersionError";
}
}
/** Error thrown when an internal client error happens. */
export class InternalError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "InternalError";
}
}
/** Error thrown when the API is misused. */
export class MisuseError extends ClientError {
/** @private */
constructor(message) {
super(message);
this.name = "MisuseError";
}
}

View File

@@ -0,0 +1,34 @@
/// <reference types="node" />
import type { ProtocolVersion, ProtocolEncoding } from "../client.js";
import { Client } from "../client.js";
import { HttpStream } from "./stream.js";
export type Endpoint = {
versionPath: string;
pipelinePath: string;
cursorPath: string | undefined;
version: ProtocolVersion;
encoding: ProtocolEncoding;
};
export declare const checkEndpoints: Array<Endpoint>;
/** A client for the Hrana protocol over HTTP. */
export declare class HttpClient extends Client {
#private;
/** @private */
_endpointPromise: Promise<Endpoint>;
/** @private */
_endpoint: Endpoint | undefined;
/** @private */
constructor(url: URL, jwt: string | undefined, customFetch: unknown | undefined, protocolVersion?: ProtocolVersion);
/** Get the protocol version supported by the server. */
getVersion(): Promise<ProtocolVersion>;
/** @private */
_ensureVersion(minVersion: ProtocolVersion, feature: string): void;
/** Open a {@link HttpStream}, a stream for executing SQL statements. */
openStream(): HttpStream;
/** @private */
_streamClosed(stream: HttpStream): void;
/** Close the client and all its streams. */
close(): void;
/** True if the client is closed. */
get closed(): boolean;
}

View File

@@ -0,0 +1,124 @@
import { fetch, Request } from "@libsql/isomorphic-fetch";
import { Client } from "../client.js";
import { ClientError, ClosedError, ProtocolVersionError } from "../errors.js";
import { HttpStream } from "./stream.js";
export const 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. */
export class HttpClient extends 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 ?? 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 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 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 ClosedError("Client is closed", this.#closed);
}
const stream = new 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 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 ClosedError("Client was closed", error));
}
}
}
async function findEndpoint(customFetch, clientUrl) {
const fetch = customFetch;
for (const endpoint of checkEndpoints) {
const url = new URL(endpoint.versionPath, clientUrl);
const request = new Request(url.toString(), { method: "GET" });
const response = await fetch(request);
await response.arrayBuffer();
if (response.ok) {
return endpoint;
}
}
return fallbackEndpoint;
}

View File

@@ -0,0 +1,19 @@
import type { Response } from "@libsql/isomorphic-fetch";
import type { ProtocolEncoding } from "../client.js";
import { Cursor } from "../cursor.js";
import type * as proto from "./proto.js";
import type { HttpStream } from "./stream.js";
export declare class HttpCursor extends Cursor {
#private;
/** @private */
constructor(stream: HttpStream, encoding: ProtocolEncoding);
open(response: Response): Promise<proto.CursorRespBody>;
/** Fetch the next entry from the cursor. */
next(): Promise<proto.CursorEntry | undefined>;
/** Close the cursor. */
close(): void;
/** @private */
_setClosed(error: Error): void;
/** True if the cursor is closed. */
get closed(): boolean;
}

View File

@@ -0,0 +1,135 @@
import { ByteQueue } from "../byte_queue.js";
import { Cursor } from "../cursor.js";
import * as jsond from "../encoding/json/decode.js";
import * as protobufd from "../encoding/protobuf/decode.js";
import { ClientError, ClosedError, ProtoError, InternalError } from "../errors.js";
import { impossible } from "../util.js";
import { CursorRespBody as json_CursorRespBody } from "./json_decode.js";
import { CursorRespBody as protobuf_CursorRespBody } from "./protobuf_decode.js";
import { CursorEntry as json_CursorEntry } from "../shared/json_decode.js";
import { CursorEntry as protobuf_CursorEntry } from "../shared/protobuf_decode.js";
export class HttpCursor extends Cursor {
#stream;
#encoding;
#reader;
#queue;
#closed;
#done;
/** @private */
constructor(stream, encoding) {
super();
this.#stream = stream;
this.#encoding = encoding;
this.#reader = undefined;
this.#queue = new ByteQueue(16 * 1024);
this.#closed = undefined;
this.#done = false;
}
async open(response) {
if (response.body === null) {
throw new ProtoError("No response body for cursor request");
}
this.#reader = response.body.getReader();
const respBody = await this.#nextItem(json_CursorRespBody, protobuf_CursorRespBody);
if (respBody === undefined) {
throw new ProtoError("Empty response to cursor request");
}
return respBody;
}
/** Fetch the next entry from the cursor. */
next() {
return this.#nextItem(json_CursorEntry, protobuf_CursorEntry);
}
/** Close the cursor. */
close() {
this._setClosed(new 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 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 impossible(this.#encoding, "Impossible encoding");
}
if (this.#reader === undefined) {
throw new 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 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;
}
}

View File

@@ -0,0 +1,4 @@
import * as d from "../encoding/json/decode.js";
import * as proto from "./proto.js";
export declare function PipelineRespBody(obj: d.Obj): proto.PipelineRespBody;
export declare function CursorRespBody(obj: d.Obj): proto.CursorRespBody;

View File

@@ -0,0 +1,62 @@
import { ProtoError } from "../errors.js";
import * as d from "../encoding/json/decode.js";
import { Error, StmtResult, BatchResult, DescribeResult } from "../shared/json_decode.js";
export 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 };
}
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 = Error(d.object(obj["error"]));
return { type: "error", error };
}
else {
throw new 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 = StmtResult(d.object(obj["result"]));
return { type: "execute", result };
}
else if (type === "batch") {
const result = BatchResult(d.object(obj["result"]));
return { type: "batch", result };
}
else if (type === "sequence") {
return { type: "sequence" };
}
else if (type === "describe") {
const result = 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 ProtoError("Unexpected type of StreamResponse");
}
}
export function CursorRespBody(obj) {
const baton = d.stringOpt(obj["baton"]);
const baseUrl = d.stringOpt(obj["base_url"]);
return { baton, baseUrl };
}

View File

@@ -0,0 +1,4 @@
import * as e from "../encoding/json/encode.js";
import * as proto from "./proto.js";
export declare function PipelineReqBody(w: e.ObjectWriter, msg: proto.PipelineReqBody): void;
export declare function CursorReqBody(w: e.ObjectWriter, msg: proto.CursorReqBody): void;

View File

@@ -0,0 +1,55 @@
import { Stmt, Batch } from "../shared/json_encode.js";
import { impossible } from "../util.js";
export function PipelineReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string("baton", msg.baton);
}
w.arrayObjects("requests", msg.requests, StreamRequest);
}
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, Stmt);
}
else if (msg.type === "batch") {
w.object("batch", msg.batch, 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 impossible(msg, "Impossible type of StreamRequest");
}
}
export function CursorReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string("baton", msg.baton);
}
w.object("batch", msg.batch, Batch);
}

View File

@@ -0,0 +1,95 @@
export * from "../shared/proto.js";
import { int32, Error, Stmt, StmtResult, Batch, BatchResult, DescribeResult } from "../shared/proto.js";
export type PipelineReqBody = {
baton: string | undefined;
requests: Array<StreamRequest>;
};
export type PipelineRespBody = {
baton: string | undefined;
baseUrl: string | undefined;
results: Array<StreamResult>;
};
export type StreamResult = {
type: "none";
} | StreamResultOk | StreamResultError;
export type StreamResultOk = {
type: "ok";
response: StreamResponse;
};
export type StreamResultError = {
type: "error";
error: Error;
};
export type CursorReqBody = {
baton: string | undefined;
batch: Batch;
};
export type CursorRespBody = {
baton: string | undefined;
baseUrl: string | undefined;
};
export type StreamRequest = CloseStreamReq | ExecuteStreamReq | BatchStreamReq | SequenceStreamReq | DescribeStreamReq | StoreSqlStreamReq | CloseSqlStreamReq | GetAutocommitStreamReq;
export type StreamResponse = {
type: "none";
} | CloseStreamResp | ExecuteStreamResp | BatchStreamResp | SequenceStreamResp | DescribeStreamResp | StoreSqlStreamResp | CloseSqlStreamResp | GetAutocommitStreamResp;
export type CloseStreamReq = {
type: "close";
};
export type CloseStreamResp = {
type: "close";
};
export type ExecuteStreamReq = {
type: "execute";
stmt: Stmt;
};
export type ExecuteStreamResp = {
type: "execute";
result: StmtResult;
};
export type BatchStreamReq = {
type: "batch";
batch: Batch;
};
export type BatchStreamResp = {
type: "batch";
result: BatchResult;
};
export type SequenceStreamReq = {
type: "sequence";
sql: string | undefined;
sqlId: int32 | undefined;
};
export type SequenceStreamResp = {
type: "sequence";
};
export type DescribeStreamReq = {
type: "describe";
sql: string | undefined;
sqlId: int32 | undefined;
};
export type DescribeStreamResp = {
type: "describe";
result: DescribeResult;
};
export type StoreSqlStreamReq = {
type: "store_sql";
sqlId: int32;
sql: string;
};
export type StoreSqlStreamResp = {
type: "store_sql";
};
export type CloseSqlStreamReq = {
type: "close_sql";
sqlId: int32;
};
export type CloseSqlStreamResp = {
type: "close_sql";
};
export type GetAutocommitStreamReq = {
type: "get_autocommit";
};
export type GetAutocommitStreamResp = {
type: "get_autocommit";
isAutocommit: boolean;
};

View File

@@ -0,0 +1,2 @@
// Types for the structures specific to Hrana over HTTP.
export * from "../shared/proto.js";

View File

@@ -0,0 +1,4 @@
import * as d from "../encoding/protobuf/decode.js";
import * as proto from "./proto.js";
export declare const PipelineRespBody: d.MessageDef<proto.PipelineRespBody>;
export declare const CursorRespBody: d.MessageDef<proto.CursorRespBody>;

View File

@@ -0,0 +1,44 @@
import { Error, StmtResult, BatchResult, DescribeResult } from "../shared/protobuf_decode.js";
export const 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(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: StmtResult.default() }; },
1(r, msg) { msg.result = r.message(StmtResult); },
};
const BatchStreamResp = {
default() { return { type: "batch", result: BatchResult.default() }; },
1(r, msg) { msg.result = r.message(BatchResult); },
};
const DescribeStreamResp = {
default() { return { type: "describe", result: DescribeResult.default() }; },
1(r, msg) { msg.result = r.message(DescribeResult); },
};
const GetAutocommitStreamResp = {
default() { return { type: "get_autocommit", isAutocommit: false }; },
1(r, msg) { msg.isAutocommit = r.bool(); },
};
export const 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,4 @@
import * as e from "../encoding/protobuf/encode.js";
import * as proto from "./proto.js";
export declare function PipelineReqBody(w: e.MessageWriter, msg: proto.PipelineReqBody): void;
export declare function CursorReqBody(w: e.MessageWriter, msg: proto.CursorReqBody): void;

View File

@@ -0,0 +1,78 @@
import { Stmt, Batch } from "../shared/protobuf_encode.js";
import { impossible } from "../util.js";
export function PipelineReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string(1, msg.baton);
}
for (const req of msg.requests) {
w.message(2, req, StreamRequest);
}
}
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 impossible(msg, "Impossible type of StreamRequest");
}
}
function CloseStreamReq(_w, _msg) {
}
function ExecuteStreamReq(w, msg) {
w.message(1, msg.stmt, Stmt);
}
function BatchStreamReq(w, msg) {
w.message(1, msg.batch, 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) {
}
export function CursorReqBody(w, msg) {
if (msg.baton !== undefined) {
w.string(1, msg.baton);
}
w.message(2, msg.batch, Batch);
}

View File

@@ -0,0 +1,45 @@
/// <reference types="node" />
import type { fetch } from "@libsql/isomorphic-fetch";
import type { SqlOwner, ProtoSql } from "../sql.js";
import { Sql } from "../sql.js";
import { Stream } from "../stream.js";
import type { HttpClient } from "./client.js";
import { HttpCursor } from "./cursor.js";
import type * as proto from "./proto.js";
export declare class HttpStream extends Stream implements SqlOwner {
#private;
/** @private */
constructor(client: HttpClient, baseUrl: URL, jwt: string | undefined, customFetch: typeof fetch);
/** Get the {@link HttpClient} object that this stream belongs to. */
client(): HttpClient;
/** @private */
_sqlOwner(): SqlOwner;
/** Cache a SQL text on the server. */
storeSql(sql: string): Sql;
/** @private */
_closeSql(sqlId: number): void;
/** @private */
_execute(stmt: proto.Stmt): Promise<proto.StmtResult>;
/** @private */
_batch(batch: proto.Batch): Promise<proto.BatchResult>;
/** @private */
_describe(protoSql: ProtoSql): Promise<proto.DescribeResult>;
/** @private */
_sequence(protoSql: ProtoSql): Promise<void>;
/** 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(): Promise<boolean>;
/** @private */
_openCursor(batch: proto.Batch): Promise<HttpCursor>;
/** @private */
_cursorClosed(cursor: HttpCursor): void;
/** Immediately close the stream. */
close(): void;
/** Gracefully close the stream. */
closeGracefully(): void;
/** True if the stream is closed. */
get closed(): boolean;
/** @private */
_setClosed(error: Error): void;
}

View File

@@ -0,0 +1,363 @@
import { Request, Headers } from "@libsql/isomorphic-fetch";
import { ClientError, HttpServerError, ProtocolVersionError, ProtoError, ClosedError, InternalError, } from "../errors.js";
import { readJsonObject, writeJsonObject, readProtobufMessage, writeProtobufMessage, } from "../encoding/index.js";
import { IdAlloc } from "../id_alloc.js";
import { Queue } from "../queue.js";
import { queueMicrotask } from "../queue_microtask.js";
import { errorFromProto } from "../result.js";
import { Sql } from "../sql.js";
import { Stream } from "../stream.js";
import { impossible } from "../util.js";
import { HttpCursor } from "./cursor.js";
import { PipelineReqBody as json_PipelineReqBody } from "./json_encode.js";
import { PipelineReqBody as protobuf_PipelineReqBody } from "./protobuf_encode.js";
import { CursorReqBody as json_CursorReqBody } from "./json_encode.js";
import { CursorReqBody as protobuf_CursorReqBody } from "./protobuf_encode.js";
import { PipelineRespBody as json_PipelineRespBody } from "./json_decode.js";
import { PipelineRespBody as protobuf_PipelineRespBody } from "./protobuf_decode.js";
export class HttpStream extends 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();
this.#flushing = false;
this.#closing = false;
this.#closeQueued = false;
this.#closed = undefined;
this.#sqlIdAlloc = new 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(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 InternalError("Cursor was closed, but it was not associated with the stream");
}
this.#cursor = undefined;
queueMicrotask(() => this.#flushQueue());
}
/** Immediately close the stream. */
close() {
this._setClosed(new ClientError("Stream was manually closed"));
}
/** Gracefully close the stream. */
closeGracefully() {
this.#closing = true;
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;
queueMicrotask(() => this.#flushQueue());
}
}
#pushToQueue(entry) {
if (this.#closed !== undefined) {
throw new ClosedError("Stream is closed", this.#closed);
}
else if (this.#closing) {
throw new ClosedError("Stream is closing", undefined);
}
else {
this.#queue.push(entry);
queueMicrotask(() => this.#flushQueue());
}
}
#flushQueue() {
if (this.#flushing || this.#cursor !== undefined) {
return;
}
if (this.#closing && this.#queue.length === 0) {
this._setClosed(new 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 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 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_PipelineReqBody, protobuf_PipelineReqBody);
}
#createCursorRequest(entry, endpoint) {
if (endpoint.cursorPath === undefined) {
throw new 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_CursorReqBody, protobuf_CursorReqBody);
}
#createRequest(url, reqBody, encoding, jsonFun, protobufFun) {
let bodyData;
let contentType;
if (encoding === "json") {
bodyData = writeJsonObject(reqBody, jsonFun);
contentType = "application/json";
}
else if (encoding === "protobuf") {
bodyData = writeProtobufMessage(reqBody, protobufFun);
contentType = "application/x-protobuf";
}
else {
throw impossible(encoding, "Impossible encoding");
}
const headers = new Headers();
headers.set("content-type", contentType);
if (this.#jwt !== undefined) {
headers.set("authorization", `Bearer ${this.#jwt}`);
}
return new Request(url.toString(), { method: "POST", headers, body: bodyData });
}
}
function handlePipelineResponse(pipeline, respBody) {
if (respBody.results.length !== pipeline.length) {
throw new 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 ProtoError("Received unexpected type of response");
}
entry.responseCallback(result.response);
}
else if (result.type === "error") {
entry.errorCallback(errorFromProto(result.error));
}
else if (result.type === "none") {
throw new ProtoError("Received unrecognized type of StreamResult");
}
else {
throw impossible(result, "Received impossible type of StreamResult");
}
}
}
async function decodePipelineResponse(resp, encoding) {
if (encoding === "json") {
const respJson = await resp.json();
return readJsonObject(respJson, json_PipelineRespBody);
}
if (encoding === "protobuf") {
const respData = await resp.arrayBuffer();
return readProtobufMessage(new Uint8Array(respData), protobuf_PipelineRespBody);
}
await resp.body?.cancel();
throw 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 errorFromProto(respBody);
}
return new HttpServerError(message, resp.status);
}
if (respType === "text/plain") {
const respBody = (await resp.text()).trim();
if (respBody !== "") {
message += `: ${respBody}`;
}
return new HttpServerError(message, resp.status);
}
await resp.body?.cancel();
return new HttpServerError(message, resp.status);
}

View File

@@ -0,0 +1,6 @@
export declare class IdAlloc {
#private;
constructor();
alloc(): number;
free(id: number): void;
}

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

@@ -0,0 +1,47 @@
import { InternalError } from "./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).
export 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 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);
}
}
}

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

@@ -0,0 +1,34 @@
/// <reference types="node" />
import { HttpClient } from "./http/client.js";
import { WsClient } from "./ws/client.js";
import { ProtocolVersion } from "./client.js";
export { WebSocket } from "@libsql/isomorphic-ws";
export type { RequestInit, Response } from "@libsql/isomorphic-fetch";
export { fetch, Request, Headers } from "@libsql/isomorphic-fetch";
export type { ProtocolVersion, ProtocolEncoding } from "./client.js";
export { Client } from "./client.js";
export type { DescribeResult, DescribeColumn } from "./describe.js";
export * from "./errors.js";
export { Batch, BatchStep, BatchCond } from "./batch.js";
export type { ParsedLibsqlUrl } from "./libsql_url.js";
export { parseLibsqlUrl } from "./libsql_url.js";
export type { StmtResult, RowsResult, RowResult, ValueResult, Row } from "./result.js";
export type { InSql, SqlOwner } from "./sql.js";
export { Sql } from "./sql.js";
export type { InStmt, InStmtArgs } from "./stmt.js";
export { Stmt } from "./stmt.js";
export { Stream } from "./stream.js";
export type { Value, InValue, IntMode } from "./value.js";
export { HttpClient } from "./http/client.js";
export { HttpStream } from "./http/stream.js";
export { WsClient } from "./ws/client.js";
export { WsStream } from "./ws/stream.js";
/** Open a Hrana client over WebSocket connected to the given `url`. */
export declare function openWs(url: string | URL, jwt?: string, protocolVersion?: ProtocolVersion): WsClient;
/** 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`.
*/
export declare function openHttp(url: string | URL, jwt?: string, customFetch?: unknown | undefined, protocolVersion?: ProtocolVersion): HttpClient;

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

@@ -0,0 +1,42 @@
import { WebSocket } from "@libsql/isomorphic-ws";
import { subprotocolsV2, subprotocolsV3 } from "./ws/client.js";
import { WebSocketUnsupportedError } from "./errors.js";
import { HttpClient } from "./http/client.js";
import { WsClient } from "./ws/client.js";
export { WebSocket } from "@libsql/isomorphic-ws";
export { fetch, Request, Headers } from "@libsql/isomorphic-fetch";
export { Client } from "./client.js";
export * from "./errors.js";
export { Batch, BatchStep, BatchCond } from "./batch.js";
export { parseLibsqlUrl } from "./libsql_url.js";
export { Sql } from "./sql.js";
export { Stmt } from "./stmt.js";
export { Stream } from "./stream.js";
export { HttpClient } from "./http/client.js";
export { HttpStream } from "./http/stream.js";
export { WsClient } from "./ws/client.js";
export { WsStream } from "./ws/stream.js";
/** Open a Hrana client over WebSocket connected to the given `url`. */
export function openWs(url, jwt, protocolVersion = 2) {
if (typeof WebSocket === "undefined") {
throw new WebSocketUnsupportedError("WebSockets are not supported in this environment");
}
var subprotocols = undefined;
if (protocolVersion == 3) {
subprotocols = Array.from(subprotocolsV3.keys());
}
else {
subprotocols = Array.from(subprotocolsV2.keys());
}
const socket = new WebSocket(url, subprotocols);
return new WsClient(socket, jwt);
}
/** 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`.
*/
export function openHttp(url, jwt, customFetch, protocolVersion = 2) {
return new HttpClient(url instanceof URL ? url : new URL(url), jwt, customFetch, protocolVersion);
}

View File

@@ -0,0 +1,15 @@
/** Result of parsing a libsql URL using {@link parseLibsqlUrl}. */
export interface ParsedLibsqlUrl {
/** A WebSocket URL that can be used with {@link openWs} to open a {@link WsClient}. It is `undefined`
* if the parsed URL specified HTTP explicitly. */
hranaWsUrl: string | undefined;
/** A HTTP URL that can be used with {@link openHttp} to open a {@link HttpClient}. It is `undefined`
* if the parsed URL specified WebSockets explicitly. */
hranaHttpUrl: string | undefined;
/** The optional `authToken` query parameter that should be passed as `jwt` to
* {@link openWs}/{@link openHttp}. */
authToken: string | undefined;
}
/** Parses a URL compatible with the libsql client (`@libsql/client`). This URL may have the "libsql:" scheme
* and may contain query parameters. */
export declare function parseLibsqlUrl(urlStr: string): ParsedLibsqlUrl;

View File

@@ -0,0 +1,75 @@
import { LibsqlUrlParseError } from "./errors.js";
;
/** Parses a URL compatible with the libsql client (`@libsql/client`). This URL may have the "libsql:" scheme
* and may contain query parameters. */
export 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 LibsqlUrlParseError(`Unknown value for the "tls" query argument: ${JSON.stringify(value)}`);
}
}
else {
throw new LibsqlUrlParseError(`Unknown URL query argument ${JSON.stringify(key)}`);
}
}
let hranaWsScheme;
let hranaHttpScheme;
if ((url.protocol === "http:" || url.protocol === "ws:") && (tls === true)) {
throw new 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 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 LibsqlUrlParseError(`A "libsql:" URL with ?tls=0 must specify an explicit port`);
}
hranaHttpScheme = "http:";
hranaWsScheme = "ws:";
}
else {
hranaHttpScheme = "https:";
hranaWsScheme = "wss:";
}
}
else {
throw new 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 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 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 };
}

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

@@ -0,0 +1,8 @@
export declare class Queue<T> {
#private;
constructor();
get length(): number;
push(elem: T): void;
shift(): T | undefined;
first(): T | undefined;
}

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

@@ -0,0 +1,26 @@
export 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];
}
}

View File

@@ -0,0 +1,2 @@
declare let _queueMicrotask: (callback: () => void) => void;
export { _queueMicrotask as queueMicrotask };

View File

@@ -0,0 +1,13 @@
// queueMicrotask() ponyfill
// https://github.com/libsql/libsql-client-ts/issues/47
let _queueMicrotask;
if (typeof queueMicrotask !== "undefined") {
_queueMicrotask = queueMicrotask;
}
else {
const resolved = Promise.resolve();
_queueMicrotask = (callback) => {
resolved.then(callback);
};
}
export { _queueMicrotask as queueMicrotask };

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

@@ -0,0 +1,43 @@
import { ResponseError } from "./errors.js";
import type * as proto from "./shared/proto.js";
import type { Value, IntMode } from "./value.js";
/** Result of executing a database statement. */
export interface StmtResult {
/** Number of rows that were changed by the statement. This is meaningful only if the statement was an
* INSERT, UPDATE or DELETE, and the value is otherwise undefined. */
affectedRowCount: number;
/** The ROWID of the last successful insert into a rowid table. This is a 64-big signed integer. For other
* statements than INSERTs into a rowid table, the value is not specified. */
lastInsertRowid: bigint | undefined;
/** Names of columns in the result. */
columnNames: Array<string | undefined>;
/** Declared types of columns in the result. */
columnDecltypes: Array<string | undefined>;
}
/** An array of rows returned by a database statement. */
export interface RowsResult extends StmtResult {
/** The returned rows. */
rows: Array<Row>;
}
/** A single row returned by a database statement. */
export interface RowResult extends StmtResult {
/** The returned row. If the query produced zero rows, this is `undefined`. */
row: Row | undefined;
}
/** A single value returned by a database statement. */
export interface ValueResult extends StmtResult {
/** The returned value. If the query produced zero rows or zero columns, this is `undefined`. */
value: Value | undefined;
}
/** Row returned from the database. This is an Array-like object (it has `length` and can be indexed with a
* number), and in addition, it has enumerable properties from the named columns. */
export interface Row {
length: number;
[index: number]: Value;
[name: string]: Value;
}
export declare function stmtResultFromProto(result: proto.StmtResult): StmtResult;
export declare function rowsResultFromProto(result: proto.StmtResult, intMode: IntMode): RowsResult;
export declare function rowResultFromProto(result: proto.StmtResult, intMode: IntMode): RowResult;
export declare function valueResultFromProto(result: proto.StmtResult, intMode: IntMode): ValueResult;
export declare function errorFromProto(error: proto.Error): ResponseError;

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

@@ -0,0 +1,48 @@
import { ResponseError } from "./errors.js";
import { valueFromProto } from "./value.js";
export function stmtResultFromProto(result) {
return {
affectedRowCount: result.affectedRowCount,
lastInsertRowid: result.lastInsertRowid,
columnNames: result.cols.map(col => col.name),
columnDecltypes: result.cols.map(col => col.decltype),
};
}
export function rowsResultFromProto(result, intMode) {
const stmtResult = stmtResultFromProto(result);
const rows = result.rows.map(row => rowFromProto(stmtResult.columnNames, row, intMode));
return { ...stmtResult, rows };
}
export 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 };
}
export function valueResultFromProto(result, intMode) {
const stmtResult = stmtResultFromProto(result);
let value;
if (result.rows.length > 0 && stmtResult.columnNames.length > 0) {
value = valueFromProto(result.rows[0][0], intMode);
}
return { ...stmtResult, value };
}
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 = 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;
}
export function errorFromProto(error) {
return new ResponseError(error.message, error);
}

View File

@@ -0,0 +1,8 @@
import * as d from "../encoding/json/decode.js";
import * as proto from "./proto.js";
export declare function Error(obj: d.Obj): proto.Error;
export declare function StmtResult(obj: d.Obj): proto.StmtResult;
export declare function BatchResult(obj: d.Obj): proto.BatchResult;
export declare function CursorEntry(obj: d.Obj): proto.CursorEntry;
export declare function DescribeResult(obj: d.Obj): proto.DescribeResult;
export declare function Value(obj: d.Obj): proto.Value;

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