92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
|
|
// packages/contracts/src/realtime.ts
|
||
|
|
// WS 实时消息契约(P2,技术实施方案 §7):OpenAPI 不覆盖 WS 帧,本文件单独
|
||
|
|
// 维护,与 openapi.yaml 生成类型同属契约单一事实来源。消息一律为以 type 判别
|
||
|
|
// 的联合;新增/修改消息类型须同步 __tests__/realtime.test.ts 的穷尽断言。
|
||
|
|
|
||
|
|
/** 心跳间隔(毫秒):客户端周期发送 ping、服务端回 pong;超时无心跳的连接由服务端踢除。 */
|
||
|
|
export const HEARTBEAT_MS = 20000;
|
||
|
|
|
||
|
|
// ── server → client ──
|
||
|
|
|
||
|
|
/** 照片发布:副本应用后向相册房间广播(ov 侧,下同)。 */
|
||
|
|
export interface PhotoPublishedMessage {
|
||
|
|
type: 'photo.published';
|
||
|
|
photoId: string;
|
||
|
|
albumId: string;
|
||
|
|
publishedAt: string; // ISO UTC
|
||
|
|
entityVersion: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 照片隐藏。 */
|
||
|
|
export interface PhotoHiddenMessage {
|
||
|
|
type: 'photo.hidden';
|
||
|
|
photoId: string;
|
||
|
|
albumId: string;
|
||
|
|
entityVersion: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 照片删除(软删除的公开语义等同隐藏,客户端行为一致:即刻移出列表)。 */
|
||
|
|
export interface PhotoDeletedMessage {
|
||
|
|
type: 'photo.deleted';
|
||
|
|
photoId: string;
|
||
|
|
albumId: string;
|
||
|
|
entityVersion: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 点赞合并广播:短窗内同照片批次合并为一次 burst;originBatchIds 供客户端过滤自身批次。 */
|
||
|
|
export interface LikesBurstMessage {
|
||
|
|
type: 'likes.burst';
|
||
|
|
photoId: string;
|
||
|
|
albumId: string;
|
||
|
|
delta: number;
|
||
|
|
total: number; // 服务端权威累计
|
||
|
|
countVersion: number;
|
||
|
|
burstId: string;
|
||
|
|
originBatchIds: string[]; // 合并进本 burst 的批次 ID(含己则抑制自身动画)
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 相册浏览数更新。 */
|
||
|
|
export interface StatsUpdatedMessage {
|
||
|
|
type: 'stats.updated';
|
||
|
|
albumId: string;
|
||
|
|
viewCount: number;
|
||
|
|
countVersion: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 心跳应答:回显客户端 ping 携带的 ts。 */
|
||
|
|
export interface PongMessage {
|
||
|
|
type: 'pong';
|
||
|
|
ts: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export type ServerMessage =
|
||
|
|
| PhotoPublishedMessage
|
||
|
|
| PhotoHiddenMessage
|
||
|
|
| PhotoDeletedMessage
|
||
|
|
| LikesBurstMessage
|
||
|
|
| StatsUpdatedMessage
|
||
|
|
| PongMessage;
|
||
|
|
|
||
|
|
// ── client → server ──
|
||
|
|
|
||
|
|
/** 订阅相册房间;服务端校验相册公开后加入。 */
|
||
|
|
export interface SubscribeMessage {
|
||
|
|
type: 'subscribe';
|
||
|
|
albumToken: string;
|
||
|
|
sinceVersion?: number; // 缺省从订阅时刻起推送,不补播历史
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 退订相册房间。 */
|
||
|
|
export interface UnsubscribeMessage {
|
||
|
|
type: 'unsubscribe';
|
||
|
|
albumToken: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 心跳;服务端原样回 pong。 */
|
||
|
|
export interface PingMessage {
|
||
|
|
type: 'ping';
|
||
|
|
ts: number; // epoch 毫秒
|
||
|
|
}
|
||
|
|
|
||
|
|
export type ClientMessage = SubscribeMessage | UnsubscribeMessage | PingMessage;
|