feat(upload): add realtime SSE updates
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
type YoutubeSettings,
|
||||
} from "@/db/schema";
|
||||
import { and, desc, eq } from "drizzle-orm";
|
||||
import { sse } from "@/lib/realtime/sse";
|
||||
|
||||
const VIDEO_TYPES = new Set(["video/mp4", "video/quicktime", "video/webm"]);
|
||||
|
||||
@@ -338,6 +339,12 @@ export async function publishVideoJob(jobId: string) {
|
||||
error: null,
|
||||
})
|
||||
.where(eq(videoUploadJobs.id, job.id));
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
jobId: job.id,
|
||||
platform: job.platform,
|
||||
status: "processing",
|
||||
});
|
||||
try {
|
||||
const result =
|
||||
job.platform === "youtube"
|
||||
@@ -352,6 +359,12 @@ export async function publishVideoJob(jobId: string) {
|
||||
completedAt: new Date(),
|
||||
})
|
||||
.where(eq(videoUploadJobs.id, job.id));
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
jobId: job.id,
|
||||
platform: job.platform,
|
||||
status: "completed",
|
||||
});
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Platform upload failed.";
|
||||
@@ -359,6 +372,12 @@ export async function publishVideoJob(jobId: string) {
|
||||
.update(videoUploadJobs)
|
||||
.set({ status: "failed", error: message })
|
||||
.where(eq(videoUploadJobs.id, job.id));
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
jobId: job.id,
|
||||
platform: job.platform,
|
||||
status: "failed",
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -398,5 +417,9 @@ export async function processDueVideoUploads() {
|
||||
.update(videoUploads)
|
||||
.set({ status: nextStatus, updatedAt: new Date() })
|
||||
.where(eq(videoUploads.id, upload.id));
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
status: nextStatus,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import "server-only";
|
||||
|
||||
import { mkdir, readdir, stat, writeFile } from "node:fs/promises";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { sse } from "@/lib/realtime/sse";
|
||||
import { db } from "@/db";
|
||||
import {
|
||||
videoUploadJobs,
|
||||
@@ -107,6 +108,10 @@ export async function saveVideoUpload(formData: FormData, discordId: string) {
|
||||
{ uploadId: upload.id, platform: "tiktok" },
|
||||
])
|
||||
.returning({ id: videoUploadJobs.id });
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
status: scheduledAt ? "scheduled" : "processing",
|
||||
});
|
||||
if (!scheduledAt) {
|
||||
await Promise.allSettled(jobs.map((job) => publishVideoJob(job.id)));
|
||||
const remaining = await db.query.videoUploadJobs.findMany({
|
||||
@@ -120,6 +125,10 @@ export async function saveVideoUpload(formData: FormData, discordId: string) {
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(videoUploads.id, upload.id));
|
||||
await sse.uploads.pub("update", {
|
||||
uploadId: upload.id,
|
||||
status: remaining.length === 0 ? "completed" : "partial",
|
||||
});
|
||||
}
|
||||
return upload.id;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user