evtstore
Version:
Event Sourcing with Node.JS
126 lines • 10.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrate = exports.createProvider = void 0;
const error_1 = require("./error");
const util_1 = require("./util");
function createProvider(opts) {
const { sql, bookmarks: bms, events: evts } = opts;
const onError = opts.onError ||
(() => {
/* NOOP */
});
return {
limit: opts.limit,
driver: 'postgres',
onError,
getPosition: async (bm) => {
const result = await sql `SELECT * FROM ${sql(bms)} WHERE bookmark = ${bm} LIMIT 1`;
if (result[0])
return result[0].position;
return 0;
},
setPosition: async (bm, pos) => {
const result = await sql `UPDATE ${sql(bms)} SET position = ${pos} WHERE bookmark = ${bm}`;
if (result.count === 0) {
await sql `INSERT INTO ${sql(bms)} (bookmark, position) VALUES (${bm}, ${pos})`;
}
},
getEventsFor: async (stream, aggregateId, fromPosition) => {
const from = fromPosition ? sql `AND position > ${fromPosition}` : sql ``;
const result = await sql `SELECT * FROM ${sql(evts)}
WHERE stream = ${stream}
AND aggregate_id = ${aggregateId} ${from}
ORDER BY version asc`;
return result.map(mapToEvent);
},
getLastEventFor: async (stream, aggregateId) => {
const streams = Array.isArray(stream) ? stream : [stream];
const agg = aggregateId ? sql `AND aggregate_id = ${aggregateId}` : sql ``;
const result = await sql `select * from ${sql(evts)} where stream in (${sql(streams)}) ${agg} order by position desc limit 1`;
return result.map(mapToEvent)[0];
},
getEventsFrom: async (stream, position, lim) => {
const streams = Array.isArray(stream) ? stream : [stream];
const limit = lim !== null && lim !== void 0 ? lim : opts.limit;
const limitClause = limit ? sql `LIMIT ${limit}` : sql ``;
const result = await sql `SELECT * FROM ${sql(evts)} WHERE stream IN ${sql(streams)} AND position > ${position} ORDER BY position ASC ${limitClause}`;
return result.map(mapToEvent);
},
createEvents: (0, util_1.createEventsMapper)(0),
append: async (_stream, _aggregateId, _version, newEvents) => {
try {
const result = await sql.begin(async (sql) => {
const toInsert = toStorableEvents(newEvents);
const result = await sql `insert into ${sql(evts)} ${sql(toInsert, 'stream', 'aggregate_id', 'event', 'version', 'timestamp')} returning position`;
for (let i = 0; i < result.length; i++) {
newEvents[i].position = Number(result[i].position);
}
return newEvents;
});
return result;
}
catch (ex) {
// TODO: Verify version conflict error
throw new error_1.VersionError(ex.message);
}
},
};
}
exports.createProvider = createProvider;
function toStorableEvents(events) {
const appendable = [];
for (let i = 0; i < events.length; i++) {
appendable.push({
stream: events[i].stream,
aggregate_id: events[i].aggregateId,
version: events[i].version,
event: JSON.stringify(events[i].event),
timestamp: events[i].timestamp.toISOString(),
});
}
return appendable;
}
/** Migrate using a PG.Pool object */
async function migrate(opts) {
const { bookmarks, events } = opts;
if (!bookmarks || !events)
return;
try {
await opts.sql.begin(async (sql) => {
await sql `CREATE TABLE ${sql(bookmarks)} (
bookmark text PRIMARY KEY,
position bigint
)`;
await sql `
CREATE TABLE ${sql(events)} (
position BIGSERIAL PRIMARY KEY,
version integer,
stream text,
aggregate_id text,
timestamp timestamptz,
event text
)`;
await sql `CREATE UNIQUE INDEX events_stream_position_unique ON ${sql(events)} (
stream, position
)`;
await sql `CREATE UNIQUE INDEX events_stream_aggregate_version_unique ON ${sql(events)} (
stream, aggregate_id, version
)`;
});
}
catch (ex) {
throw ex;
}
}
exports.migrate = migrate;
function mapToEvent(row) {
return {
aggregateId: row.aggregate_id,
event: JSON.parse(row.event),
position: row.position,
stream: row.stream,
timestamp: row.timestamp,
version: row.version,
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdGdyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwb3N0Z3Jlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxtQ0FBc0M7QUFDdEMsaUNBQTJDO0FBdUIzQyxTQUFnQixjQUFjLENBQWtCLElBQWE7SUFDM0QsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUE7SUFDbEQsTUFBTSxPQUFPLEdBQ1gsSUFBSSxDQUFDLE9BQU87UUFDWixDQUFDLEdBQUcsRUFBRTtZQUNKLFVBQVU7UUFDWixDQUFDLENBQUMsQ0FBQTtJQUNKLE9BQU87UUFDTCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7UUFDakIsTUFBTSxFQUFFLFVBQVU7UUFDbEIsT0FBTztRQUNQLFdBQVcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDeEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxHQUFHLENBQUEsaUJBQWlCLEdBQUcsQ0FBQyxHQUFHLENBQUMscUJBQXFCLEVBQUUsVUFBVSxDQUFBO1lBRWxGLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFBRSxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUE7WUFDeEMsT0FBTyxDQUFDLENBQUE7UUFDVixDQUFDO1FBQ0QsV0FBVyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxHQUFHLENBQUEsVUFBVSxHQUFHLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLHFCQUFxQixFQUFFLEVBQUUsQ0FBQTtZQUV6RixJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixNQUFNLEdBQUcsQ0FBQSxlQUFlLEdBQUcsQ0FBQyxHQUFHLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxHQUFHLEdBQUcsQ0FBQTthQUMvRTtR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