@darlean/core
Version:
Darlean core functionality for creating applications that define, expose and host actors
161 lines (160 loc) • 6.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TablePersistence = void 0;
const base_1 = require("@darlean/base");
/**
* For internal use. Helper class for {@link TablePersistence}.
*/
class TablePersistable extends base_1.CustomPersistable {
constructor(onLoad, onStore, value) {
super(value);
this.onLoad = onLoad;
this.onStore = onStore;
}
async _load() {
const result = await this.onLoad();
this._baseline = result[2];
return { value: result[0], version: result[1] };
}
async _persist(value, version) {
const result = await this.onStore(value, version, this._baseline);
this._baseline = result.baseline;
}
}
/**
* Implementation of persistence that uses a table as persistence.
*
* Although this class implements persistence, it does not implement {@link IPersistence}, because it is too fundamentally
* different. One such difference is that it only understands "just keys", not "partition" or "sort" keys.
*/
class TablePersistence {
constructor(service, indexer, deser, specifier) {
this.deser = deser;
this.service = service;
this.specifier = specifier;
this.indexer = indexer;
}
async search(options) {
if (!options.index) {
// Search on main table
const opts2 = {
keys: [...(options.keys ?? [])],
filter: options.filter,
keysOrder: options.keysOrder,
specifier: this.specifier,
tableProjection: options.tableProjection,
continuationToken: options.continuationToken,
maxChunkItems: options.maxChunkItems ?? options.maxItems,
indexRepresentation: options.indexRepresentation,
tableRepresentation: options.tableRepresentation
};
const results = this.deser.deserializeTyped(await this.service.searchBuffer(opts2));
const response = { items: [], continuationToken: results.continuationToken };
for (const item of results.items) {
response.items.push({
id: item.id,
tableFields: item.tableFields,
tableBuffer: item.tableBuffer
});
}
return response;
}
else {
// Search on index table (not the main table)
const opts2 = {
index: options.index,
keys: options.keys,
filter: options.filter,
keysOrder: options.keysOrder,
specifier: this.specifier,
tableProjection: options.tableProjection,
indexProjection: options.indexProjection,
continuationToken: options.continuationToken,
maxChunkItems: options.maxChunkItems,
tableRepresentation: options.tableRepresentation,
indexRepresentation: options.indexRepresentation
};
const results = this.deser.deserializeTyped(await this.service.searchBuffer(opts2));
const response = { items: [], continuationToken: results.continuationToken };
for (const item of results.items) {
response.items.push({
id: item.id,
keys: item.keys,
tableFields: item.tableFields,
indexFields: item.indexFields
});
}
return response;
}
}
async *searchChunks(options) {
let response;
let nRowsRemaining = options.maxTotalItems ?? undefined;
while ((!response || response.continuationToken) && (nRowsRemaining === undefined || nRowsRemaining > 0)) {
options.continuationToken = response?.continuationToken;
if (nRowsRemaining !== undefined) {
options.maxChunkItems =
(options.maxChunkItems ?? options.maxItems ?? 0) > nRowsRemaining
? nRowsRemaining
: options.maxChunkItems ?? options.maxItems;
}
response = await this.search(options);
yield response;
if (nRowsRemaining !== undefined) {
nRowsRemaining -= response.items.length;
}
}
}
async *searchItems(options) {
let response;
let nRowsRemaining = options.maxTotalItems ?? undefined;
while ((!response || response.continuationToken) && (nRowsRemaining === undefined || nRowsRemaining > 0)) {
options.continuationToken = response?.continuationToken;
if (nRowsRemaining !== undefined) {
options.maxChunkItems =
(options.maxChunkItems ?? options.maxItems ?? 0) > nRowsRemaining
? nRowsRemaining
: options.maxChunkItems ?? options.maxItems;
}
response = await this.search(options);
for (const item of response.items) {
if (nRowsRemaining !== undefined) {
nRowsRemaining--;
if (nRowsRemaining < 0) {
return;
}
}
yield item;
}
}
}
persistable(key, value) {
return new TablePersistable(() => this.loadImpl(key), (value, version, baseLine) => this.storeImpl(key, value, version, baseLine), value);
}
async load(key) {
const result = this.persistable(key, undefined);
await result.load();
return result;
}
async loadImpl(key) {
const result = await this.service.get({
specifier: this.specifier,
keys: key,
representation: 'fields'
});
const value = result.data;
return [value, result.version, result.baseline];
}
async storeImpl(key, value, version, baseline) {
const result = await this.service.put({
specifier: this.specifier,
indexes: value ? this.indexer(value) : [],
baseline,
id: key,
data: value,
version
});
return result;
}
}
exports.TablePersistence = TablePersistence;