pierre-review 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -323,21 +323,40 @@ export async function getTimeline(filters) {
323
323
  for (const r of rows)
324
324
  reviewStateById.set(r.id, r.state);
325
325
  }
326
- const timelineEvents = evRows.map((e) => ({
327
- id: e.id,
328
- repoId: e.repoId,
329
- actorId: e.actorId,
330
- prId: e.prId,
331
- type: e.type,
332
- occurredAt: e.occurredAt.toISOString(),
333
- threadId: e.type === 'review_comment' && e.refTable === 'review_threads'
334
- ? e.refId
335
- : null,
336
- refId: e.refId,
337
- reviewState: e.type === 'review_submitted' && e.refTable === 'reviews' && e.refId != null
338
- ? (reviewStateById.get(e.refId) ?? null)
339
- : null,
340
- }));
326
+ // Batch-load the derived state of each review_comment event's thread, so the
327
+ // timeline's "Threads" filter can narrow markers to a specific thread state
328
+ // (e.g. only resolved) instead of every comment on a PR that has a matching
329
+ // thread. A single keyed lookup; the thread's id is the event's refId.
330
+ const threadRefIds = evRows
331
+ .filter((e) => e.type === 'review_comment' && e.refTable === 'review_threads' && e.refId != null)
332
+ .map((e) => e.refId);
333
+ const threadStateById = new Map();
334
+ if (threadRefIds.length > 0) {
335
+ const rows = await db
336
+ .select({ id: reviewThreads.id, state: reviewThreads.derivedState })
337
+ .from(reviewThreads)
338
+ .where(inArray(reviewThreads.id, threadRefIds))
339
+ .execute();
340
+ for (const r of rows)
341
+ threadStateById.set(r.id, r.state);
342
+ }
343
+ const timelineEvents = evRows.map((e) => {
344
+ const threadId = e.type === 'review_comment' && e.refTable === 'review_threads' ? e.refId : null;
345
+ return {
346
+ id: e.id,
347
+ repoId: e.repoId,
348
+ actorId: e.actorId,
349
+ prId: e.prId,
350
+ type: e.type,
351
+ occurredAt: e.occurredAt.toISOString(),
352
+ threadId,
353
+ derivedState: threadId != null ? (threadStateById.get(threadId) ?? null) : null,
354
+ refId: e.refId,
355
+ reviewState: e.type === 'review_submitted' && e.refTable === 'reviews' && e.refId != null
356
+ ? (reviewStateById.get(e.refId) ?? null)
357
+ : null,
358
+ };
359
+ });
341
360
  return { prs, events: timelineEvents };
342
361
  }
343
362
  export async function getOpenPrs(filters) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pierre-review",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "Dashboard for tracking your team's GitHub PR activity across repos — local (SQLite + gh) or self-hosted multi-tenant cloud (Postgres + GitHub App).",
5
5
  "type": "module",
6
6
  "author": "Alex Wakeman",