feat: add deployment reload controls

This commit is contained in:
2026-08-23 14:33:26 +00:00 Unverified
parent 25dccdfa4f
commit a630e0cc2f
11 changed files with 341 additions and 32 deletions
+21 -2
View File
@@ -19,8 +19,16 @@ type SubscriptionOptions = {
onopen?: (event: Event) => void;
};
type StreamOptions = {
type StreamMessage<T extends EventMap> = {
[K in Extract<keyof T, string>]: {
event: K;
data: z.input<T[K]>;
};
}[Extract<keyof T, string>];
type StreamOptions<T extends EventMap> = {
signal?: AbortSignal;
motd?: StreamMessage<T> | StreamMessage<T>[];
};
const redisEnvelopeSchema = z.object({
@@ -154,7 +162,11 @@ export class SseEndpoint<T extends EventMap> {
}
}
async stream({ signal }: StreamOptions = {}) {
async stream({ signal, motd }: StreamOptions<T> = {}) {
const initialMessages = (Array.isArray(motd) ? motd : motd ? [motd] : [])
.map(({ event, data }) =>
encodeEvent(event, this.events[event].parse(data)),
);
const subscriber = await getRedisSubscriber();
const topic = this.topic;
const channel = channelName(this.topic);
@@ -223,6 +235,7 @@ export class SseEndpoint<T extends EventMap> {
start(streamController) {
controller = streamController;
write(`retry: ${DEFAULT_RETRY_MS}\n\n: connected ${topic}\n\n`);
for (const message of initialMessages) write(message);
receive = handleMessage;
for (const message of pendingMessages.splice(0)) {
@@ -287,6 +300,12 @@ export function createSseEndpoints<
const updateActionSchema = z.enum(["created", "updated", "deleted"]);
export const sse = createSseEndpoints({
active: {
events: {
version: z.string().min(1),
refresh: z.string().min(1).nullable(),
},
},
forms: {
events: {
update: z.object({