reduct-js
Version:
ReductStore Client SDK for Javascript/NodeJS/Typescript
121 lines (120 loc) • 3.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WritableRecord = exports.ReadableRecord = void 0;
const buffer_1 = require("buffer");
/**
* Represents a record in an entry for reading
*/
class ReadableRecord {
/**
* Constructor which should be call from Bucket
* @internal
*/
constructor(time, size, last, head, stream, labels, contentType) {
this.labels = {};
this.time = time;
this.size = size;
this.last = last;
this.stream = stream;
this.labels = labels;
this.contentType = contentType;
}
/**
* Read content of record
*/
async read() {
const reader = this.stream.getReader();
const chunks = [];
let done = false;
while (!done) {
const { value, done: isDone } = await reader.read();
done = isDone;
if (value) {
chunks.push(value);
}
}
const total = chunks.reduce((n, c) => n + c.length, 0);
const out = new Uint8Array(total);
let offset = 0;
for (const c of chunks) {
out.set(c, offset);
offset += c.length;
}
return buffer_1.Buffer.from(out);
}
/**
* Read content of record and convert to string
*/
async readAsString() {
return new TextDecoder().decode(await this.read());
}
}
exports.ReadableRecord = ReadableRecord;
/**
* Represents a record in an entry for writing
*/
class WritableRecord {
/**
* Constructor for stream
* @internal
*/
constructor(bucketName, entryName, options, httpClient) {
this.bucketName = bucketName;
this.entryName = entryName;
this.httpClient = httpClient;
this.options = options;
}
/**
* Write data to record asynchronously
* @param data stream or buffer with data
* @param size size of data in bytes (only for streams)
*/
async write(data, size) {
let contentLength = BigInt(size ?? 0);
let dataToSend = data;
if (data instanceof (ReadableStream)) {
if (size === undefined) {
throw new Error("Size must be set for stream");
}
}
else if (data instanceof buffer_1.Buffer || typeof data === "string") {
contentLength = BigInt(data.length);
}
else if (data["readable"] !== undefined) {
// a hack for Node.js streams
const stream = data;
if (stream.readable) {
dataToSend = new ReadableStream({
async pull(controller) {
const chunk = stream.read();
if (chunk) {
controller.enqueue(chunk);
}
else {
controller.close();
}
},
});
}
else {
throw new Error("Invalid stream");
}
}
else {
throw new Error("Invalid data type");
}
const { bucketName, entryName, options } = this;
const headers = {
"Content-Type": options.contentType ?? "application/octet-stream",
"Content-Length": contentLength.toString(),
};
for (const [key, value] of Object.entries(options.labels ?? {})) {
headers[`x-reduct-label-${key}`] = value.toString();
}
if (options.ts === undefined) {
throw new Error("Timestamp must be set");
}
await this.httpClient.post(`/b/${bucketName}/${entryName}?ts=${options.ts}`, dataToSend, headers);
}
}
exports.WritableRecord = WritableRecord;