summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/global-sync/session-prefetch.ts
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-12 11:31:52 -0500
committerGitHub <[email protected]>2026-03-12 11:31:52 -0500
commit0e077f748352df6d44c811829baff3c26b3436ac (patch)
tree1239dd7f492a528037c92ef695b31ef90b5c86cc /packages/app/src/context/global-sync/session-prefetch.ts
parent776e7a9c15f3e352c5abf0b0949a5d7b767adfa3 (diff)
downloadopencode-0e077f748352df6d44c811829baff3c26b3436ac.tar.gz
opencode-0e077f748352df6d44c811829baff3c26b3436ac.zip
feat: session load perf (#17186)
Diffstat (limited to 'packages/app/src/context/global-sync/session-prefetch.ts')
-rw-r--r--packages/app/src/context/global-sync/session-prefetch.ts85
1 files changed, 85 insertions, 0 deletions
diff --git a/packages/app/src/context/global-sync/session-prefetch.ts b/packages/app/src/context/global-sync/session-prefetch.ts
new file mode 100644
index 000000000..10877b063
--- /dev/null
+++ b/packages/app/src/context/global-sync/session-prefetch.ts
@@ -0,0 +1,85 @@
+const key = (directory: string, sessionID: string) => `${directory}\n${sessionID}`
+
+export const SESSION_PREFETCH_TTL = 15_000
+
+type Meta = {
+ limit: number
+ complete: boolean
+ at: number
+}
+
+const cache = new Map<string, Meta>()
+const inflight = new Map<string, Promise<Meta | undefined>>()
+const rev = new Map<string, number>()
+
+const version = (id: string) => rev.get(id) ?? 0
+
+export function getSessionPrefetch(directory: string, sessionID: string) {
+ return cache.get(key(directory, sessionID))
+}
+
+export function getSessionPrefetchPromise(directory: string, sessionID: string) {
+ return inflight.get(key(directory, sessionID))
+}
+
+export function clearSessionPrefetchInflight() {
+ inflight.clear()
+}
+
+export function isSessionPrefetchCurrent(directory: string, sessionID: string, value: number) {
+ return version(key(directory, sessionID)) === value
+}
+
+export function runSessionPrefetch(input: {
+ directory: string
+ sessionID: string
+ task: (value: number) => Promise<Meta | undefined>
+}) {
+ const id = key(input.directory, input.sessionID)
+ const pending = inflight.get(id)
+ if (pending) return pending
+
+ const value = version(id)
+
+ const promise = input.task(value).finally(() => {
+ if (inflight.get(id) === promise) inflight.delete(id)
+ })
+
+ inflight.set(id, promise)
+ return promise
+}
+
+export function setSessionPrefetch(input: {
+ directory: string
+ sessionID: string
+ limit: number
+ complete: boolean
+ at?: number
+}) {
+ cache.set(key(input.directory, input.sessionID), {
+ limit: input.limit,
+ complete: input.complete,
+ at: input.at ?? Date.now(),
+ })
+}
+
+export function clearSessionPrefetch(directory: string, sessionIDs: Iterable<string>) {
+ for (const sessionID of sessionIDs) {
+ if (!sessionID) continue
+ const id = key(directory, sessionID)
+ rev.set(id, version(id) + 1)
+ cache.delete(id)
+ inflight.delete(id)
+ }
+}
+
+export function clearSessionPrefetchDirectory(directory: string) {
+ const prefix = `${directory}\n`
+ const keys = new Set([...cache.keys(), ...inflight.keys()])
+ for (const id of keys) {
+ if (!id.startsWith(prefix)) continue
+ rev.set(id, version(id) + 1)
+ cache.delete(id)
+ inflight.delete(id)
+ }
+}