0
2
import { defineQuery } from "$hatk";
import { hydrateStories, type StoryRow } from "../hydrate/stories.ts";
import { resolveHandle } from "../helpers/resolveHandle.ts";
export default defineQuery("social.grain.unspecced.getStoryArchive", async (ctx) => {
const { db, ok } = ctx;
const actor = ctx.params.actor ? await resolveHandle(db, ctx.params.actor) : null;
if (!actor) return ok({ stories: [] });
const limit = Math.min(Number(ctx.params.limit) || 50, 100);
const cursor = ctx.params.cursor as string | undefined;
const queryParams: (string | number)[] = [actor, limit + 1];
let cursorClause = "";
if (cursor) {
cursorClause = ` AND s.created_at < $3`;
queryParams.push(cursor);
}
const rows = (await db.query(
`SELECT s.uri, s.cid, s.did, s.media, s.aspect_ratio, s.location, s.address, s.created_at
FROM "social.grain.story" s
LEFT JOIN _repos r ON s.did = r.did
WHERE s.did = $1
AND (r.status IS NULL OR r.status NOT IN ('takendown', 'deactivated', 'deleted'))
${cursorClause}
ORDER BY s.created_at DESC
LIMIT $2`,
queryParams,
)) as StoryRow[];
const hasMore = rows.length > limit;
const pageRows = hasMore ? rows.slice(0, limit) : rows;
const stories = await hydrateStories(ctx, actor, pageRows);
const nextCursor = hasMore ? pageRows[pageRows.length - 1].created_at : undefined;
return ok({ stories, ...(nextCursor ? { cursor: nextCursor } : {}) });
});