chore: generate

This commit is contained in:
opencode-agent[bot] 2026-06-27 07:43:42 +00:00
parent 3d072112ce
commit 6861fedd09
4 changed files with 28 additions and 41 deletions

View file

@ -61,7 +61,6 @@ describe("coalesceServerEvents", () => {
expect(result.map((event) => event.payload.id)).toEqual(["1", "2", "3"])
})
})
describe("enqueueServerEvent", () => {

View file

@ -26,10 +26,7 @@ const coalescedKey = (event: QueuedServerEvent) => {
return undefined
}
export function enqueueServerEvent(
queue: QueuedServerEvent[],
event: QueuedServerEvent,
) {
export function enqueueServerEvent(queue: QueuedServerEvent[], event: QueuedServerEvent) {
const key = coalescedKey(event)
const previous = queue[queue.length - 1]
if (key && previous && coalescedKey(previous) === key) {

View file

@ -264,7 +264,9 @@ describe("server session", () => {
const message = userMessage("message")
const stale = textPart(message.id, { id: "stale", text: "stale" })
const part = textPart(message.id, { id: "optimistic", text: "optimistic" })
const store = createServerSession(messageClient(response([{ info: message, parts: [] }]), pending.promise, response()))
const store = createServerSession(
messageClient(response([{ info: message, parts: [] }]), pending.promise, response()),
)
await store.sync("child")
const refreshing = store.sync("child", { force: true })
@ -372,10 +374,7 @@ describe("server session", () => {
const updated = { ...confirmed, text: "updated" }
const pendingPart = textPart(message.id, { id: "pending", text: "pending" })
const store = createServerSession(
messageClient(
response([{ info: message, parts: [confirmed] }]),
response([{ info: message, parts: [updated] }]),
),
messageClient(response([{ info: message, parts: [confirmed] }]), response([{ info: message, parts: [updated] }])),
)
store.optimistic.add({ sessionID: "child", message, parts: [confirmed, pendingPart] })
await store.sync("child")

View file

@ -53,10 +53,7 @@ type MessageLoadState = {
clearedMessageParts: Set<string>
}
function mergeOptimisticPage(
page: MessagePage,
items: OptimisticItem[],
) {
function mergeOptimisticPage(page: MessagePage, items: OptimisticItem[]) {
if (items.length === 0) return { ...page, observed: [] as { messageID: string; parts: Part[] }[] }
const session = [...page.session]
const part = new Map(page.part.map((item) => [item.id, item.part]))
@ -157,7 +154,10 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
const orphanParts = new Map<string, Set<string>>()
const removedMessages = new Map<string, Set<string>>()
const deltaBases = new Map<string, { base: string; sessionID: string }>()
const deleteMessageParts = (cache: { part: Record<string, Part[] | undefined>; part_text_accum_delta: Record<string, string | undefined> }, messageID: string) => {
const deleteMessageParts = (
cache: { part: Record<string, Part[] | undefined>; part_text_accum_delta: Record<string, string | undefined> },
messageID: string,
) => {
for (const part of cache.part[messageID] ?? []) {
delete cache.part_text_accum_delta[part.id]
deltaBases.delete(part.id)
@ -253,10 +253,7 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
)
generations.delete(sessionID)
}
void request.then(
cleanup,
cleanup,
)
void request.then(cleanup, cleanup)
return request
}
@ -339,7 +336,8 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
if (!load) return
// A part event keeps an existing parent when the fetched page omits it without overriding fetched metadata.
const messages = data.message[sessionID]
if (messages && Binary.search(messages, messageID, (message) => message.id).found) load.retainedMessages.add(messageID)
if (messages && Binary.search(messages, messageID, (message) => message.id).found)
load.retainedMessages.add(messageID)
const parts = load.touchedParts.get(messageID)
if (parts) {
parts.add(partID)
@ -504,11 +502,7 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
for (const partID of load?.carriedDeltaParts.get(item.id) ?? []) {
if (!fetchedIDs.has(partID)) touched.delete(partID)
}
const parts = reconcileFetched(
fetched,
data.part[item.id] ?? [],
{ touched },
)
const parts = reconcileFetched(fetched, data.part[item.id] ?? [], { touched })
if (!parts.length) {
orphanParts.get(sessionID)?.delete(item.id)
setData(produce((draft) => deleteMessageParts(draft, item.id)))
@ -542,19 +536,12 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
merged.observed.forEach((item) => {
if (!load?.clearedMessageParts.has(item.messageID)) confirmOptimistic(sessionID, item.messageID, item.parts)
})
const touchedMessages = new Set([
...(load?.touchedMessages ?? []),
...(removedMessages.get(sessionID) ?? []),
])
const messages = reconcileFetched(
merged.session,
data.message[sessionID] ?? [],
{
touched: touchedMessages,
retained: load?.retainedMessages,
preserveUnfetched,
},
)
const touchedMessages = new Set([...(load?.touchedMessages ?? []), ...(removedMessages.get(sessionID) ?? [])])
const messages = reconcileFetched(merged.session, data.message[sessionID] ?? [], {
touched: touchedMessages,
retained: load?.retainedMessages,
preserveUnfetched,
})
batch(() => {
const messageIDs = replaceMessages(sessionID, messages)
replaceParts(sessionID, merged.part, messageIDs, load)
@ -785,7 +772,9 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
// Outside a page load, accepting a part without its ordered parent event would create an unbounded orphan.
if (
missing &&
(!load || load.clearedMessageParts.has(part.messageID) || removedMessages.get(part.sessionID)?.has(part.messageID))
(!load ||
load.clearedMessageParts.has(part.messageID) ||
removedMessages.get(part.sessionID)?.has(part.messageID))
)
return
if (missing) {
@ -1003,7 +992,9 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
},
optimistic: {
add(input: { sessionID: string; message: Message; parts: Part[] }) {
const parts = input.parts.filter((part) => !!part?.id && !SKIP_PARTS.has(part.type)).sort((a, b) => cmp(a.id, b.id))
const parts = input.parts
.filter((part) => !!part?.id && !SKIP_PARTS.has(part.type))
.sort((a, b) => cmp(a.id, b.id))
const load = messageLoads.get(input.sessionID)
if (load?.clearedMessageParts.has(input.message.id)) {
const touched = load.touchedParts.get(input.message.id) ?? new Set<string>()
@ -1019,7 +1010,8 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
removedMessagesForSession?.delete(input.message.id)
if (removedMessagesForSession?.size === 0) removedMessages.delete(input.sessionID)
if (items) items.set(input.message.id, { ...input, parts, confirmedParts: [] })
if (!items) optimistic.set(input.sessionID, new Map([[input.message.id, { ...input, parts, confirmedParts: [] }]]))
if (!items)
optimistic.set(input.sessionID, new Map([[input.message.id, { ...input, parts, confirmedParts: [] }]]))
setData("message", input.sessionID, (messages = []) => merge(messages, [input.message]))
setData(
"part_text_accum_delta",