MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve .json path for report

+54 -5
+44 -3
docs/reports/src/reports.ts
··· 5 5 import { frames as frameTable, reportFrames, reports, type CrashReport } from './schema'; 6 6 7 7 type ReportDb = ReturnType<typeof drizzle>; 8 + type ReportFrameRow = { 9 + frame: string; 10 + frameHash: string; 11 + frameIndex: number; 12 + }; 13 + 14 + export type RawReport = { 15 + id: string; 16 + trace: string; 17 + firstSeenAt: string; 18 + lastSeenAt: string; 19 + hitCount: number; 20 + expiresAt: string; 21 + report: CrashReport; 22 + frames: ReportFrameRow[]; 23 + }; 8 24 9 25 async function reportTrace(report: CrashReport): Promise<string> { 10 26 const traceInput = JSON.stringify({ ··· 24 40 25 41 const reportFromRows = ( 26 42 row: typeof reports.$inferSelect, 27 - frameRows: { frame: string }[], 43 + frameRows: ReportFrameRow[], 28 44 ): CrashReport => ({ 29 45 schema: 1, 30 46 runtime: 'ant', ··· 64 80 ); 65 81 } 66 82 67 - async function getReportFrames(db: ReportDb, reportId: string): Promise<{ frame: string }[]> { 83 + async function getReportFrames(db: ReportDb, reportId: string): Promise<ReportFrameRow[]> { 68 84 return db 69 85 .select({ 70 86 frame: frameTable.frame, 87 + frameHash: reportFrames.frameHash, 88 + frameIndex: reportFrames.frameIndex, 71 89 }) 72 90 .from(reportFrames) 73 91 .innerJoin(frameTable, eq(reportFrames.frameHash, frameTable.hash)) ··· 75 93 .orderBy(asc(reportFrames.frameIndex)); 76 94 } 77 95 96 + async function getReportRow(db: ReportDb, id: string): Promise<typeof reports.$inferSelect | null> { 97 + const [row] = await db.select().from(reports).where(eq(reports.id, id)).limit(1); 98 + return row ?? null; 99 + } 100 + 78 101 export async function getReport(db: ReportDb, id: string): Promise<CrashReport | null> { 79 - const [row] = await db.select().from(reports).where(eq(reports.id, id)).limit(1); 102 + const row = await getReportRow(db, id); 80 103 81 104 if (!row) return null; 82 105 const frames = await getReportFrames(db, row.id); 83 106 return reportFromRows(row, frames); 107 + } 108 + 109 + export async function getRawReport(db: ReportDb, id: string): Promise<RawReport | null> { 110 + const row = await getReportRow(db, id); 111 + 112 + if (!row) return null; 113 + const frames = await getReportFrames(db, row.id); 114 + 115 + return { 116 + id: row.id, 117 + trace: row.trace, 118 + firstSeenAt: row.firstSeenAt, 119 + lastSeenAt: row.lastSeenAt, 120 + hitCount: row.hitCount, 121 + expiresAt: row.expiresAt, 122 + report: reportFromRows(row, frames), 123 + frames, 124 + }; 84 125 } 85 126 86 127 export async function createReport(db: ReportDb, report: CrashReport): Promise<string> {
+10 -2
docs/reports/src/routes.ts
··· 4 4 import { drizzle } from 'drizzle-orm/d1'; 5 5 import { CrashReportSchema } from './schema'; 6 6 import { renderBlank, renderReport } from './view'; 7 - import { createReport, getReport } from './reports'; 7 + import { createReport, getRawReport, getReport } from './reports'; 8 8 9 9 import { 10 10 getAntLogoDataUrl, ··· 48 48 49 49 app.get('/:id', async c => { 50 50 const db = drizzle(c.env.DB); 51 - const id = c.req.param('id'); 51 + const pathId = c.req.param('id'); 52 + 53 + if (pathId.endsWith('.json')) { 54 + const report = await getRawReport(db, pathId.slice(0, -5)); 55 + if (!report) return c.json({ error: 'not found' }, 404); 56 + return c.json(report, 200); 57 + } 58 + 59 + const id = pathId; 52 60 const report = await getReport(db, id); 53 61 54 62 if (!report) return c.html(renderBlank(), 404);