feat(events): process transactional invalidations
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
export const INVALIDATION_TYPES = [
|
||||
"directory.updated",
|
||||
"page.updated",
|
||||
"data-source.updated",
|
||||
"admin.updated",
|
||||
] as const;
|
||||
|
||||
export type InvalidationType = (typeof INVALIDATION_TYPES)[number];
|
||||
|
||||
export interface InvalidationEvent {
|
||||
type: InvalidationType;
|
||||
id: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface OutboxEventLike {
|
||||
aggregateId: string;
|
||||
eventType: string;
|
||||
payload: Record<string, unknown>;
|
||||
topic: string;
|
||||
}
|
||||
|
||||
function isInvalidationType(value: string): value is InvalidationType {
|
||||
return INVALIDATION_TYPES.some((type) => type === value);
|
||||
}
|
||||
|
||||
export function expectedTopic(event: InvalidationEvent): string {
|
||||
switch (event.type) {
|
||||
case "directory.updated":
|
||||
return "directory";
|
||||
case "page.updated":
|
||||
return `page:${event.id}`;
|
||||
case "data-source.updated":
|
||||
return `data-source:${event.id}`;
|
||||
case "admin.updated":
|
||||
return "admin";
|
||||
}
|
||||
}
|
||||
|
||||
export function toInvalidationEvent(
|
||||
record: OutboxEventLike,
|
||||
): InvalidationEvent | null {
|
||||
if (!isInvalidationType(record.eventType)) return null;
|
||||
const id = record.payload.id;
|
||||
const version = record.payload.version;
|
||||
if (
|
||||
typeof id !== "string" ||
|
||||
id !== record.aggregateId ||
|
||||
typeof version !== "number" ||
|
||||
!Number.isSafeInteger(version) ||
|
||||
version < 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const event: InvalidationEvent = {
|
||||
type: record.eventType,
|
||||
id,
|
||||
version,
|
||||
};
|
||||
return expectedTopic(event) === record.topic ? event : null;
|
||||
}
|
||||
|
||||
export function parseInvalidationEvent(value: string): InvalidationEvent | null {
|
||||
try {
|
||||
const parsed = JSON.parse(value) as Record<string, unknown>;
|
||||
const type = parsed.type;
|
||||
const id = parsed.id;
|
||||
const version = parsed.version;
|
||||
if (
|
||||
typeof type !== "string" ||
|
||||
!isInvalidationType(type) ||
|
||||
typeof id !== "string" ||
|
||||
typeof version !== "number" ||
|
||||
!Number.isSafeInteger(version) ||
|
||||
version < 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return { type, id, version };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user