mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-20 09:01:19 +00:00
Compare commits
3 Commits
416ee841f6
...
f3db2e35e7
| Author | SHA1 | Date | |
|---|---|---|---|
| f3db2e35e7 | |||
| 46596e53d0 | |||
| bf309fce20 |
@@ -306,6 +306,10 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
|||||||
const enhancement = await processor(currentItems)
|
const enhancement = await processor(currentItems)
|
||||||
|
|
||||||
if (enhancement.additionalItems?.length) {
|
if (enhancement.additionalItems?.length) {
|
||||||
|
// Post-processors operate on FeedItem[] without knowledge of TItems.
|
||||||
|
// Additional items are merged untyped — this is intentional. The
|
||||||
|
// processor contract is "FeedItem in, FeedItem out"; type narrowing
|
||||||
|
// is the caller's responsibility when consuming FeedResult.
|
||||||
currentItems = [...currentItems, ...(enhancement.additionalItems as TItems[])]
|
currentItems = [...currentItems, ...(enhancement.additionalItems as TItems[])]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +331,17 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { items: currentItems, groupedItems: allGroupedItems, errors: allErrors }
|
// Remove stale item IDs from groups and drop empty groups
|
||||||
|
const itemIds = new Set(currentItems.map((item) => item.id))
|
||||||
|
const validGroups = allGroupedItems.reduce<ItemGroup[]>((acc, group) => {
|
||||||
|
const ids = group.itemIds.filter((id) => itemIds.has(id))
|
||||||
|
if (ids.length > 0) {
|
||||||
|
acc.push({ ...group, itemIds: ids })
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return { items: currentItems, groupedItems: validGroups, errors: allErrors }
|
||||||
}
|
}
|
||||||
|
|
||||||
private ensureGraph(): SourceGraph {
|
private ensureGraph(): SourceGraph {
|
||||||
|
|||||||
@@ -173,6 +173,32 @@ describe("FeedPostProcessor", () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("stale item IDs are removed from groups after suppression", async () => {
|
||||||
|
const engine = new FeedEngine()
|
||||||
|
.register(
|
||||||
|
createCalendarSource([calendarItem("c1", "Meeting A"), calendarItem("c2", "Meeting B")]),
|
||||||
|
)
|
||||||
|
.registerPostProcessor(async () => ({
|
||||||
|
groupedItems: [{ itemIds: ["c1", "c2"], summary: "Afternoon" }],
|
||||||
|
}))
|
||||||
|
.registerPostProcessor(async () => ({ suppress: ["c1"] }))
|
||||||
|
|
||||||
|
const result = await engine.refresh()
|
||||||
|
expect(result.groupedItems).toEqual([{ itemIds: ["c2"], summary: "Afternoon" }])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("groups with all items suppressed are dropped", async () => {
|
||||||
|
const engine = new FeedEngine()
|
||||||
|
.register(createCalendarSource([calendarItem("c1", "Meeting A")]))
|
||||||
|
.registerPostProcessor(async () => ({
|
||||||
|
groupedItems: [{ itemIds: ["c1"], summary: "Solo" }],
|
||||||
|
}))
|
||||||
|
.registerPostProcessor(async () => ({ suppress: ["c1"] }))
|
||||||
|
|
||||||
|
const result = await engine.refresh()
|
||||||
|
expect(result.groupedItems).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
test("groupedItems is omitted when no processors produce groups", async () => {
|
test("groupedItems is omitted when no processors produce groups", async () => {
|
||||||
const engine = new FeedEngine()
|
const engine = new FeedEngine()
|
||||||
.register(createWeatherSource([weatherItem("w1", 20)]))
|
.register(createWeatherSource([weatherItem("w1", 20)]))
|
||||||
|
|||||||
Reference in New Issue
Block a user