@getanthill/datastore
Version:
Event-Sourced Datastore
68 lines (55 loc) • 1.64 kB
text/typescript
import type { ModelConfig, Source, Telemetry } from '../typings';
import type PostgreSQLClient from '../services/pg';
import type Datastore from './Datastore';
import { EventEmitter } from 'events';
import merge from 'lodash/merge';
import * as utils from './utils';
export interface SyncerConfig {
telemetry?: Telemetry;
}
export default class Syncer extends EventEmitter {
static ERRORS = {};
public config: SyncerConfig = {};
private _datastores: Map<string, Datastore>;
private _pg: PostgreSQLClient;
private _telemetry?: Telemetry;
constructor(
config: Partial<SyncerConfig>,
datastores: Map<string, Datastore>,
pg: PostgreSQLClient,
) {
super();
this.config = merge({}, this.config, config);
this._datastores = datastores;
this._pg = pg;
this._telemetry = this.config.telemetry;
}
syncDataSource(
datastoreName: string,
modelConfigs: ModelConfig[],
source: Source,
opts?: any,
) {
return utils.walkMulti(
this._datastores,
modelConfigs.map((modelConfig) => ({
datastore: datastoreName,
model: modelConfig.name,
query: {},
source,
})),
1,
async (entity, query) => {
const modelConfig = modelConfigs.find((c) => c.name === query.model)!;
await this._pg.insert(modelConfig, query.source, entity);
return entity;
},
opts,
);
}
syncData(datastoreName: string, modelConfigs: ModelConfig[], opts?: any) {
return ['entities', 'events'].map((source) =>
this.syncDataSource(datastoreName, modelConfigs, source as Source, opts),
);
}
}