workers/media-events.ts
103 lines and 3 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| objectKeyOf | 13 to 19 | 7 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| handleMediaEvents | 24 to 42 | 4 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| indexOne | 45 to 116 | 14 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
Imports
It imports app/db/index.ts, app/lib/error-message.mjs, app/lib/media/backup.server.ts, app/lib/media/classify.mjs, app/lib/media/core.server.ts. Imported by workers/app.ts.
Source
import { deleteMediaRecord, upsertDerivedMedia } from "~/db";
import { bucketFor, classify, isRaster, roleOf, storageOf } from "~/lib/media/classify.mjs";
import { mirrorObject } from "~/lib/media/backup.server";
import { measureDimensions, placeholderFor } from "~/lib/media/core.server";
import { errorMessage } from "~/lib/error-message.mjs";
/**
* The authoritative media row writer, fed by R2 event notifications rather than a dual write. Must be
* idempotent: Queues delivers at least once and out of order, so the object is re-read, never trusted
* from the event, and R2 wins any disagreement.
*/
function objectKeyOf(body: unknown): string | null {
if (typeof body !== "object" || body === null) return null;
const object = (body as { object?: unknown }).object;
if (typeof object !== "object" || object === null) return null;
const key = (object as { key?: unknown }).key;
return typeof key === "string" && key.length > 0 ? key : null;
}
// A missing object deletes the row, so reading the wrong bucket for a key deletes it too. Use the
// shared `bucketFor`; never write a second copy.
export async function handleMediaEvents(batch: MessageBatch<unknown>, env: Env) {
for (const message of batch.messages) {
const key = objectKeyOf(message.body);
if (!key) {
console.error(JSON.stringify({ alert: "media-event-no-object-key", body: message.body }));
message.ack();
continue;
}
try {
await indexOne(env, key);
message.ack();
} catch (error) {
// Never ack a transient failure, or the row silently never appears.
console.error(JSON.stringify({ alert: "media-event-failed", key, detail: errorMessage(error) }));
message.retry();
}
}
}
/** Ignores the event's action on purpose: asking R2 what is true now makes reordering safe. */
async function indexOne(env: Env, key: string) {
const object = await bucketFor(env, key).get(key);
if (!object) {
// Logged, because a genuine delete and a key looked up in the wrong bucket both land here.
console.log(
JSON.stringify({
event: "media-event-no-object",
key,
bucket: storageOf(key) === "r2-derived" ? "OG" : "MEDIA",
action: "deleting any row",
}),
);
await deleteMediaRecord(env, key);
return;
}
const { kind, mime } = classify(key);
let width: number | null = null;
let height: number | null = null;
let placeholder: string | null = null;
// An unreadable image still gets a row, or the index would disagree with the bucket; the stored
// sizes are left alone and the failure is thrown after the write, so the message retries and a
// permanent failure lands in the dead-letter queue.
let measureFailure: unknown = null;
if (isRaster(key)) {
try {
const dimensions = await measureDimensions(env, object.body);
width = dimensions?.width ?? null;
height = dimensions?.height ?? null;
} catch (error) {
measureFailure = error;
}
// Derived here, or the upsert erases the bulk pass's placeholder. A second GET, because `.info()`
// consumed the first body stream.
const reread = await bucketFor(env, key).get(key);
if (reread) placeholder = await placeholderFor(env, reread.body);
}
await upsertDerivedMedia(env, {
key,
storage: storageOf(key),
kind,
role: roleOf(key),
mime,
bytes: object.size,
width,
height,
// From the object: a content-addressed key cannot yield a filename. Null means "do not touch".
originalName: object.customMetadata?.originalName ?? null,
// Null means "do not touch", not "erase".
placeholder,
uploadedAt:
object.uploaded instanceof Date ? object.uploaded.toISOString() : String(object.uploaded ?? ""),
});
// Nothing here deletes a backup twin: the backup is the copy that survives a delete. OG cards are
// regenerable, so not mirrored. A failed mirror is swallowed; the health poll sees the drift.
if (storageOf(key) === "r2") {
try {
await mirrorObject(env, key);
} catch (error) {
// The row stands; media-backup-drift will report it and backup_media repairs it.
console.log(JSON.stringify({ event: "media-mirror-failed", key, detail: errorMessage(error) }));
}
}
// Last, so the row and the mirror both happened before the retry is asked for.
if (measureFailure) throw measureFailure;
}