feat: 직접 writer를 내구성 변화 저널에 연결
86개 API mutation을 분류하고 메시지 mailbox, 베팅, 국가 설정, 예약 명령의 revision/outbox 표식을 소유 transaction에 연결한다. 공개 SSE는 식별자 없는 invalidation만 노출한다.
This commit is contained in:
@@ -2,6 +2,7 @@ export const READ_MODEL_DOMAINS = [
|
||||
'general.content',
|
||||
'city.content',
|
||||
'nation.content',
|
||||
'dashboard.global',
|
||||
'world.content',
|
||||
'map.world',
|
||||
'map.general',
|
||||
@@ -16,6 +17,7 @@ export const READ_MODEL_DOMAINS = [
|
||||
'lobby.general',
|
||||
'contacts.world',
|
||||
'reserved.general',
|
||||
'messages.mailbox',
|
||||
'tournament',
|
||||
'betting',
|
||||
] as const;
|
||||
|
||||
@@ -8,6 +8,13 @@ import { createEmptyRealtimeReadModelChanges, type RealtimeReadModelChanges } fr
|
||||
const uniqueSortedIds = (values: Iterable<number>): number[] =>
|
||||
[...new Set(values)].sort((left, right) => left - right);
|
||||
|
||||
export const readModelOutboxPayloadToMessageMailboxes = (
|
||||
payload: ReadModelOutboxPayloadV1
|
||||
): readonly number[] =>
|
||||
uniqueSortedIds(
|
||||
payload.changes.flatMap(([domain, entityId]) => (domain === 'messages.mailbox' ? [entityId] : []))
|
||||
);
|
||||
|
||||
export const parseReadModelOutboxPayload = (value: unknown): ReadModelOutboxPayloadV1 | null => {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
||||
return null;
|
||||
@@ -73,6 +80,8 @@ export const readModelOutboxPayloadToChanges = (
|
||||
case 'nation.content':
|
||||
nationIds.push(entityId);
|
||||
break;
|
||||
case 'dashboard.global':
|
||||
break;
|
||||
case 'world.content':
|
||||
changes.worldChanged = true;
|
||||
break;
|
||||
@@ -113,6 +122,7 @@ export const readModelOutboxPayloadToChanges = (
|
||||
reservedGeneralIds.push(entityId);
|
||||
break;
|
||||
case 'access.general':
|
||||
case 'messages.mailbox':
|
||||
case 'tournament':
|
||||
case 'betting':
|
||||
// These domains have no browser-wide dashboard invalidation.
|
||||
|
||||
@@ -206,6 +206,12 @@ export interface MessageCreatedEvent {
|
||||
senderId: number;
|
||||
}
|
||||
|
||||
/** Durable mailbox wake-up derived from committed read-model outbox rows. */
|
||||
export interface MessagesChangedEvent {
|
||||
type: 'messagesChanged';
|
||||
mailboxes: number[];
|
||||
}
|
||||
|
||||
export interface ReadModelInvalidatedEvent {
|
||||
type: 'readModelInvalidated';
|
||||
invalidation: RealtimeReadModelInvalidation;
|
||||
@@ -218,4 +224,4 @@ export interface MessagesInvalidatedEvent {
|
||||
/** Events safe to expose to an authenticated browser over SSE. */
|
||||
export type PublicRealtimeEvent = ReadModelInvalidatedEvent | MessagesInvalidatedEvent;
|
||||
|
||||
export type RealtimeEvent = TurnCompletedEvent | ReadModelChangedEvent | MessageCreatedEvent;
|
||||
export type RealtimeEvent = TurnCompletedEvent | ReadModelChangedEvent | MessageCreatedEvent | MessagesChangedEvent;
|
||||
|
||||
Reference in New Issue
Block a user