@datastax/astra-db-ts
Version:
Data API TypeScript client
156 lines (155 loc) • 6.73 kB
JavaScript
"use strict";
// Copyright Datastax, Inc
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.FLCInternal = void 0;
const vector_js_1 = require("../../documents/datatypes/vector.js");
const ctx_js_1 = require("../../lib/api/ser-des/ctx.js");
const cursor_error_js_1 = require("../../documents/cursors/cursor-error.js");
class FLCInternal {
constructor(instance, parent, serdes, filter, options) {
Object.defineProperty(this, "_httpClient", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_serdes", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_parent", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_filter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_instance", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this._httpClient = parent._httpClient;
this._serdes = serdes;
this._parent = parent;
this._options = options ?? {};
this._filter = filter;
this._instance = instance;
}
withFilter(filter) {
if (this._instance.state !== 'idle') {
throw new cursor_error_js_1.CursorError(`Cannot set a new filter on a running/closed cursor`, this._instance);
}
return this._cloneFLC({ filter: filter && this._serdes.serialize(filter, ctx_js_1.SerDesTarget.Filter) });
}
withSort(sort) {
if (this._instance.state !== 'idle') {
throw new cursor_error_js_1.CursorError(`Cannot set a new sort on a running/closed cursor`, this._instance);
}
return this._cloneFLC({ options: { ...this._options, sort: sort && this._serdes.serialize(sort, ctx_js_1.SerDesTarget.Sort)[0] } });
}
withMap(map) {
if (this._instance.state !== 'idle') {
throw new cursor_error_js_1.CursorError('Cannot set a new mapping on a running/closed cursor', this._instance);
}
const mapping = this._instance._mapping
? (doc) => map(this._instance._mapping(doc))
: map;
return this._cloneFLC({ mapping });
}
withInitialPageState(pageState) {
if (this._instance.state !== 'idle') {
throw new cursor_error_js_1.CursorError('Cannot set an initial page state on a running/closed cursor', this._instance);
}
if (pageState === null) {
throw new cursor_error_js_1.CursorError('Cannot set an initial page state to `null`. If you want an unset page state, set it to `undefined` instead.', this._instance);
}
const initialPage = (pageState !== undefined)
? { nextPageState: pageState, result: [] }
: undefined;
return this._cloneFLC({ initialPage });
}
withOption(key, value) {
if (this._instance.state !== 'idle') {
throw new cursor_error_js_1.CursorError(`Cannot set a new ${key} on a running/closed cursor`, this._instance);
}
return this._cloneFLC({ options: { ...this._options, [key]: value } });
}
withPreMapOption(key, value) {
if (this._instance._mapping) {
throw new cursor_error_js_1.CursorError(`Cannot set a new ${key} after already using cursor.map(...)`, this._instance);
}
return this.withOption(key, value);
}
freshClone() {
return this._cloneFLC({ initialPage: undefined });
}
_cloneFLC(update) {
return new this._instance.constructor(this._parent, this._serdes, update?.filter ?? this._filter, update?.options ?? this._options, update?.mapping ?? this._instance._mapping, (update && 'initialPage' in update) ? update.initialPage : this._instance._currentPage);
}
async getSortVector() {
if (!this._instance._currentPage && this._options.includeSortVector) {
await this._instance._next(true, '.getSortVector');
}
return this._instance._currentPage?.sortVector ?? null;
}
async fetchNextPageMapped(opts) {
if (this._instance._currentPage && this._instance._currentPage.result.length !== 0) {
throw new cursor_error_js_1.CursorError('Cannot fetch next page when the current page (the buffer) is not empty', this._instance);
}
const nextPage = (await this.fetchNextPageRaw({ method: '.fetchNextPage' }, undefined, opts))[0];
const result = this._instance._mapping
? nextPage.result.map(r => this._instance._mapping(r))
: nextPage.result;
return { ...nextPage, result };
}
async fetchNextPageRaw(extra, tm, opts) {
const command = {
[opts.commandName]: {
filter: this._filter[0],
projection: this._options.projection,
sort: this._options.sort,
options: {
...Object.fromEntries(Object.entries(this._options).filter(([key]) => opts.commandOptions.includes(key))),
pageState: this._instance._currentPage?.nextPageState,
},
},
};
const raw = await this._httpClient.executeCommand(command, {
timeoutManager: tm ?? this._httpClient.tm.single('generalMethodTimeoutMs', this._options),
bigNumsPresent: this._filter[1],
extraLogInfo: extra,
});
this._options.includeSortVector = false;
const page = {
nextPageState: raw.data?.nextPageState,
result: raw.data?.documents ?? [],
};
if (raw.status?.sortVector) {
page.sortVector = (0, vector_js_1.vector)(raw.status.sortVector);
}
else if (this._instance._currentPage?.sortVector) {
page.sortVector = this._instance._currentPage.sortVector;
}
for (let i = 0, n = page.result.length; i < n; i++) {
page.result[i] = this._serdes.deserialize(page.result[i], raw, ctx_js_1.SerDesTarget.Record);
}
return [opts.mapPage(page, raw), !!raw.data?.nextPageState];
}
}
exports.FLCInternal = FLCInternal;