Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
TypeScript
at sl/gitmirror
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165import { describe, expect, it } from "vitest";import { groupTimeline } from "$lib/components/timeline/group";import type * as ShTangledFeedGetTimeline from "$lib/api/lexicons/types/sh/tangled/feed/getTimeline";
type TimelineItem = ShTangledFeedGetTimeline.$output["feed"][number];
const alice = { did: "did:plc:alice", handle: "alice.test" };const bob = { did: "did:plc:bob", handle: "bob.test" };
let rkey = 0;
const repo = (owner: typeof alice, slug: string) => ({ did: owner.did, slug, owner });
const follow = (actor: typeof alice, subject: string, eventAt: string) => ({ event: { $type: "sh.tangled.feed.getTimeline#followEvent", uri: `at://${actor.did}/sh.tangled.graph.follow/${rkey++}`, actor, subject: { did: `did:plc:${subject}`, handle: subject } }, eventAt }) as unknown as TimelineItem;
const star = (actor: typeof alice, slug: string, eventAt: string) => ({ event: { $type: "sh.tangled.feed.getTimeline#starEvent", uri: `at://${actor.did}/sh.tangled.feed.star/${rkey++}`, actor, repo: repo(bob, slug) }, eventAt }) as unknown as TimelineItem;
const create = (owner: typeof alice, slug: string, eventAt: string) => ({ event: { $type: "sh.tangled.feed.getTimeline#repoEvent", uri: `at://${owner.did}/sh.tangled.repo/${rkey++}`, repo: repo(owner, slug) }, eventAt }) as unknown as TimelineItem;
const fork = (owner: typeof alice, slug: string, eventAt: string) => ({ event: { $type: "sh.tangled.feed.getTimeline#repoEvent", uri: `at://${owner.did}/sh.tangled.repo/${rkey++}`, repo: repo(owner, slug), source: repo(bob, slug) }, eventAt }) as unknown as TimelineItem;
const label = (item: TimelineItem) => { const event = item.event as { subject?: { handle: string }; repo?: { slug: string } }; return event.subject?.handle ?? event.repo!.slug;};
const shape = (feed: TimelineItem[]) => groupTimeline(feed).map((entry) => [ entry.kind, entry.actor.handle, ...entry.items.map((i) => label(i as TimelineItem)) ]);
describe("groupTimeline", () => { it("merges consecutive follows by the same actor", () => { expect( shape([ follow(alice, "a", "2026-01-01T12:00:00Z"), follow(alice, "b", "2026-01-01T11:30:00Z"), follow(alice, "c", "2026-01-01T11:00:01Z") ]) ).toEqual([["follow", "alice.test", "a", "b", "c"]]); });
it("merges stars, creations and forks the same way", () => { expect( shape([ star(alice, "a", "2026-01-01T12:00:00Z"), star(alice, "b", "2026-01-01T11:59:00Z"), create(alice, "c", "2026-01-01T11:58:00Z"), create(alice, "d", "2026-01-01T11:57:00Z"), fork(alice, "e", "2026-01-01T11:56:00Z"), fork(alice, "f", "2026-01-01T11:55:00Z") ]) ).toEqual([ ["star", "alice.test", "a", "b"], ["create", "alice.test", "c", "d"], ["fork", "alice.test", "e", "f"] ]); });
it("attributes repo events to the repo owner", () => { expect( shape([ create(alice, "a", "2026-01-01T12:00:00Z"), create(bob, "b", "2026-01-01T11:59:00Z") ]) ).toEqual([ ["create", "alice.test", "a"], ["create", "bob.test", "b"] ]); });
it("splits when an hour or more separates two events", () => { expect( shape([ star(alice, "a", "2026-01-01T12:00:00Z"), star(alice, "b", "2026-01-01T11:00:00Z") ]) ).toEqual([ ["star", "alice.test", "a"], ["star", "alice.test", "b"] ]); });
it("measures the window between neighbours, not from the first event", () => { expect( shape([ follow(alice, "a", "2026-01-01T12:00:00Z"), follow(alice, "b", "2026-01-01T11:20:00Z"), follow(alice, "c", "2026-01-01T10:40:00Z") ]) ).toEqual([["follow", "alice.test", "a", "b", "c"]]); });
it("splits on a different actor", () => { expect( shape([ follow(alice, "a", "2026-01-01T12:00:00Z"), follow(bob, "b", "2026-01-01T11:59:00Z") ]) ).toEqual([ ["follow", "alice.test", "a"], ["follow", "bob.test", "b"] ]); });
it("splits on an interleaved event of another kind", () => { expect( shape([ follow(alice, "a", "2026-01-01T12:00:00Z"), star(alice, "b", "2026-01-01T11:59:00Z"), follow(alice, "c", "2026-01-01T11:58:00Z") ]) ).toEqual([ ["follow", "alice.test", "a"], ["star", "alice.test", "b"], ["follow", "alice.test", "c"] ]); });
it("keys each entry by its first event uri", () => { const feed = [ follow(alice, "a", "2026-01-01T12:00:00Z"), follow(alice, "b", "2026-01-01T11:59:00Z") ]; expect(groupTimeline(feed).map((e) => e.key)).toEqual([feed[0].event.uri]); });});