decentralised message store

feat: websocket message schema

serenity 367504be d7611db8

Changed files
+48
src
lib
types
+40
src/lib/types/ws/index.ts
···
+
import { shardMessagesInsertSchema } from "@/db/schema/messages";
+
import { verificationRequestSchema } from "@/lib/types/ws/verify";
+
import { z } from "zod/v4";
+
+
export const WebSocketMessageType = {
+
SHARD_VERIFY: "shard/verify",
+
SHARD_MESSAGE: "shard/message",
+
} as const;
+
export const webSocketMessageTypeSchema = z.enum(WebSocketMessageType);
+
export type WebSocketMessageType = z.infer<typeof webSocketMessageTypeSchema>;
+
+
const webSocketMessageBase = z.object({
+
type: webSocketMessageTypeSchema,
+
data: z.unknown(),
+
});
+
+
export const verificationMessageSchema = webSocketMessageBase.safeExtend({
+
type: z.literal("shard/verify"),
+
data: verificationRequestSchema,
+
});
+
export type VerificationMessage = z.infer<typeof verificationMessageSchema>;
+
+
// there are only two difficult things in programming.
+
// 1. naming things
+
// 2. cache invalidation
+
// 3. off-by-one errors
+
export const shardMessageMessageSchema = webSocketMessageBase.safeExtend({
+
type: z.literal("shard/message"),
+
data: z.object({
+
message: shardMessagesInsertSchema,
+
sessionId: z.string(),
+
}),
+
});
+
export type ShardMessage = z.infer<typeof shardMessageMessageSchema>;
+
+
export const webSocketMessageSchema = z.union([
+
verificationMessageSchema,
+
shardMessageMessageSchema,
+
]);
+
export type WebSocketMessage = z.infer<typeof webSocketMessageSchema>;
+8
src/lib/types/ws/verify.ts
···
+
import { atUriSchema } from "@/lib/types/atproto";
+
import z from "zod/v4";
+
+
export const verificationRequestSchema = z.object({
+
interServiceJwt: z.unknown(),
+
channelAtUris: z.array(atUriSchema),
+
});
+
export type VerificationRequest = z.infer<typeof verificationRequestSchema>;