mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-09 13:23:22 +00:00
fix(app): lazy load decoder workers
This commit is contained in:
parent
067dfa341f
commit
842f1dcfdb
2 changed files with 66 additions and 42 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import SessionMessageDecoderWorkerUrl from "./session-message-decoder.worker.ts?worker&url"
|
||||
import type { DecodedLegacyMessagePage } from "./session-message-decode"
|
||||
import type { SessionInfo } from "@opencode-ai/client/promise"
|
||||
import type { Session } from "@opencode-ai/sdk/v2/client"
|
||||
|
|
@ -6,6 +5,7 @@ import type { Session } from "@opencode-ai/sdk/v2/client"
|
|||
type Response = { id: number; data?: unknown; error?: string }
|
||||
|
||||
let worker: Worker | undefined
|
||||
let workerLoad: Promise<Worker> | undefined
|
||||
let nextID = 0
|
||||
const pending = new Map<number, { resolve: (value: unknown) => void; reject: (error: Error) => void }>()
|
||||
|
||||
|
|
@ -29,29 +29,41 @@ function decode<T>(
|
|||
const id = ++nextID
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
pending.set(id, { resolve: (value) => resolve(value as T), reject })
|
||||
getWorker().postMessage({ id, type, buffer, options }, [buffer])
|
||||
void getWorker()
|
||||
.then((worker) => worker.postMessage({ id, type, buffer, options }, [buffer]))
|
||||
.catch((error) => {
|
||||
pending.delete(id)
|
||||
reject(error instanceof Error ? error : new Error(String(error)))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getWorker() {
|
||||
if (worker) return worker
|
||||
worker = new Worker(SessionMessageDecoderWorkerUrl, { type: "module" })
|
||||
worker.onmessage = (event: MessageEvent<Response>) => {
|
||||
const request = pending.get(event.data.id)
|
||||
if (!request) return
|
||||
pending.delete(event.data.id)
|
||||
if (event.data.error) {
|
||||
request.reject(new Error(event.data.error))
|
||||
return
|
||||
if (worker) return Promise.resolve(worker)
|
||||
if (workerLoad) return workerLoad
|
||||
workerLoad = (async () => {
|
||||
const { default: workerUrl } = await import("./session-message-decoder.worker.ts?worker&url")
|
||||
const next = new Worker(workerUrl, { type: "module" })
|
||||
next.onmessage = (event: MessageEvent<Response>) => {
|
||||
const request = pending.get(event.data.id)
|
||||
if (!request) return
|
||||
pending.delete(event.data.id)
|
||||
if (event.data.error) {
|
||||
request.reject(new Error(event.data.error))
|
||||
return
|
||||
}
|
||||
request.resolve(event.data.data)
|
||||
}
|
||||
request.resolve(event.data.data)
|
||||
}
|
||||
worker.onerror = (event) => {
|
||||
const error = new Error(event.message)
|
||||
pending.forEach((request) => request.reject(error))
|
||||
pending.clear()
|
||||
worker?.terminate()
|
||||
worker = undefined
|
||||
}
|
||||
return worker
|
||||
next.onerror = (event) => {
|
||||
const error = new Error(event.message)
|
||||
pending.forEach((request) => request.reject(error))
|
||||
pending.clear()
|
||||
next.terminate()
|
||||
worker = undefined
|
||||
workerLoad = undefined
|
||||
}
|
||||
worker = next
|
||||
return next
|
||||
})()
|
||||
return workerLoad
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { FileDiffInfo } from "@opencode-ai/client/promise"
|
||||
import VcsDiffDecoderWorkerUrl from "./vcs-diff-decoder.worker.ts?worker&url"
|
||||
|
||||
type Response = { id: number; data?: FileDiffInfo[]; error?: string }
|
||||
|
||||
let worker: Worker | undefined
|
||||
let workerLoad: Promise<Worker> | undefined
|
||||
let nextID = 0
|
||||
const pending = new Map<number, { resolve: (value: FileDiffInfo[]) => void; reject: (error: Error) => void }>()
|
||||
let lastInput = 0
|
||||
|
|
@ -19,31 +19,43 @@ export function decodeVcsDiff(buffer: ArrayBuffer) {
|
|||
const id = ++nextID
|
||||
return new Promise<FileDiffInfo[]>((resolve, reject) => {
|
||||
pending.set(id, { resolve, reject })
|
||||
getWorker().postMessage({ id, buffer }, [buffer])
|
||||
void getWorker()
|
||||
.then((worker) => worker.postMessage({ id, buffer }, [buffer]))
|
||||
.catch((error) => {
|
||||
pending.delete(id)
|
||||
reject(error instanceof Error ? error : new Error(String(error)))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getWorker() {
|
||||
if (worker) return worker
|
||||
worker = new Worker(VcsDiffDecoderWorkerUrl, { type: "module" })
|
||||
worker.onmessage = (event: MessageEvent<Response>) => {
|
||||
const request = pending.get(event.data.id)
|
||||
if (!request) return
|
||||
pending.delete(event.data.id)
|
||||
if (event.data.error) {
|
||||
request.reject(new Error(event.data.error))
|
||||
return
|
||||
if (worker) return Promise.resolve(worker)
|
||||
if (workerLoad) return workerLoad
|
||||
workerLoad = (async () => {
|
||||
const { default: workerUrl } = await import("./vcs-diff-decoder.worker.ts?worker&url")
|
||||
const next = new Worker(workerUrl, { type: "module" })
|
||||
next.onmessage = (event: MessageEvent<Response>) => {
|
||||
const request = pending.get(event.data.id)
|
||||
if (!request) return
|
||||
pending.delete(event.data.id)
|
||||
if (event.data.error) {
|
||||
request.reject(new Error(event.data.error))
|
||||
return
|
||||
}
|
||||
resolveWhenInputIdle(request.resolve, event.data.data ?? [])
|
||||
}
|
||||
resolveWhenInputIdle(request.resolve, event.data.data ?? [])
|
||||
}
|
||||
worker.onerror = (event) => {
|
||||
const error = new Error(event.message)
|
||||
pending.forEach((request) => request.reject(error))
|
||||
pending.clear()
|
||||
worker?.terminate()
|
||||
worker = undefined
|
||||
}
|
||||
return worker
|
||||
next.onerror = (event) => {
|
||||
const error = new Error(event.message)
|
||||
pending.forEach((request) => request.reject(error))
|
||||
pending.clear()
|
||||
next.terminate()
|
||||
worker = undefined
|
||||
workerLoad = undefined
|
||||
}
|
||||
worker = next
|
||||
return next
|
||||
})()
|
||||
return workerLoad
|
||||
}
|
||||
|
||||
function resolveWhenInputIdle(resolve: (value: FileDiffInfo[]) => void, value: FileDiffInfo[], initial = true) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue