import * as plugins from './els.plugins.js'; import { Client as ElasticClient } from '@elastic/elasticsearch'; export interface IElasticKVStoreConstructorOptions { index: string; node: string; auth?: { username: string; password: string; }; } export class ElasticKVStore { public client: ElasticClient; public index: string; private readyDeferred: any; constructor(options: IElasticKVStoreConstructorOptions) { this.client = new ElasticClient({ node: options.node, ...(options.auth && { auth: options.auth }), }); this.index = options.index; this.readyDeferred = plugins.smartpromise.defer(); this.setupIndex(); } private async setupIndex() { try { const indexExists = await this.client.indices.exists({ index: this.index }); if (!indexExists) { await this.client.indices.create({ index: this.index, body: { mappings: { properties: { key: { type: 'keyword' }, value: { type: 'text' } } } } }); } this.readyDeferred.resolve(); } catch (err) { this.readyDeferred.reject(err); } } async set(key: string, value: string) { await this.readyDeferred.promise; await this.client.index({ index: this.index, id: key, body: { key, value } }); } async get(key: string): Promise { await this.readyDeferred.promise; try { const response = await this.client.get({ index: this.index, id: key }); return response._source['value']; } catch (error) { if (error.meta && error.meta.statusCode === 404) { return null; } throw error; } } async delete(key: string) { await this.readyDeferred.promise; try { await this.client.delete({ index: this.index, id: key }); } catch (error) { if (error.meta && error.meta.statusCode !== 404) { throw error; } } } async clear() { await this.readyDeferred.promise; await this.client.deleteByQuery({ index: this.index, body: { query: { match_all: {} } } }); } }