Download packages/app/src/pages/session/timeline/projection.ts from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 2.85 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/src/pages/session/timeline/projection.ts
- Command line
-
hf download hf://SaylorTwift/opencode/packages/app/src/pages/session/timeline/projection.ts
-
curl -L -o projection.ts https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/src/pages/session/timeline/projection.ts
2.85 kB
| import type { SessionMessageInfo } from "@opencode-ai/client/promise" | |
| import type { AssistantMessage, Message, Part, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2" | |
| import { createMemo, type Accessor } from "solid-js" | |
| import { reuseTimelineRows } from "./row-reconciliation" | |
| import { Timeline, TimelineRow } from "./rows" | |
| export { reuseTimelineRows } from "./row-reconciliation" | |
| export function createTimelineProjection(input: { | |
| messages: Accessor<Message[]> | |
| userMessages: Accessor<UserMessage[]> | |
| sessionMessages: Accessor<SessionMessageInfo[]> | |
| parts: (messageID: string) => Part[] | |
| status: Accessor<SessionStatus> | |
| showReasoningSummaries: Accessor<boolean> | |
| inlineComments: Accessor<boolean> | |
| }) { | |
| const messageByID = createMemo(() => new Map(input.messages().map((message) => [message.id, message] as const))) | |
| const assistantMessagesByParent = createMemo(() => { | |
| const result = new Map<string, AssistantMessage[]>() | |
| input.messages().forEach((message) => { | |
| if (message.role !== "assistant") return | |
| const messages = result.get(message.parentID) | |
| if (messages) { | |
| messages.push(message) | |
| return | |
| } | |
| result.set(message.parentID, [message]) | |
| }) | |
| return result | |
| }) | |
| const projection = createMemo(() => | |
| Timeline.constructSessionMessageRows( | |
| input.sessionMessages(), | |
| (messageID) => messageByID().get(messageID) as UserMessage | AssistantMessage | undefined, | |
| input.parts, | |
| input.showReasoningSummaries(), | |
| input.status().type, | |
| input.inlineComments(), | |
| input.userMessages(), | |
| ), | |
| ) | |
| const activeMessageID = createMemo(() => projection().activeMessageID) | |
| const rows = createMemo((previous: TimelineRow.TimelineRow[] | undefined) => | |
| reuseTimelineRows(previous, projection().rows), | |
| ) | |
| const rowByKey = createMemo(() => new Map(rows().map((row) => [TimelineRow.key(row), row] as const))) | |
| const messageRowIndex = createMemo(() => { | |
| const result = new Map<string, number>() | |
| rows().forEach((row, index) => { | |
| if (!("userMessageID" in row) || result.has(row.userMessageID)) return | |
| result.set(row.userMessageID, index) | |
| }) | |
| return result | |
| }) | |
| const messageLastRowIndex = createMemo(() => { | |
| const result = new Map<string, number>() | |
| rows().forEach((row, index) => { | |
| if ("userMessageID" in row) result.set(row.userMessageID, index) | |
| }) | |
| return result | |
| }) | |
| const lastAssistantGroupKey = createMemo(() => { | |
| const result = new Map<string, string>() | |
| rows().forEach((row) => { | |
| if (row._tag === "AssistantPart") result.set(row.userMessageID, row.group.key) | |
| }) | |
| return result | |
| }) | |
| return { | |
| activeMessageID, | |
| assistantMessagesByParent, | |
| lastAssistantGroupKey, | |
| messageByID, | |
| messageRowIndex, | |
| messageLastRowIndex, | |
| rowByKey, | |
| rows, | |
| } | |
| } | |