summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/global-sync/queue.ts
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-06 10:02:31 -0600
committerGitHub <[email protected]>2026-02-06 10:02:31 -0600
commit2c58dd6203df7806f57ef6b29672091cb764e871 (patch)
tree10fca96d3098465b497f78e29de8d0a585c4dac3 /packages/app/src/context/global-sync/queue.ts
parenta4bc883595df9ea0f752079519081bc602408553 (diff)
downloadopencode-2c58dd6203df7806f57ef6b29672091cb764e871.tar.gz
opencode-2c58dd6203df7806f57ef6b29672091cb764e871.zip
chore: refactoring and tests, splitting up files (#12495)
Diffstat (limited to 'packages/app/src/context/global-sync/queue.ts')
-rw-r--r--packages/app/src/context/global-sync/queue.ts83
1 files changed, 83 insertions, 0 deletions
diff --git a/packages/app/src/context/global-sync/queue.ts b/packages/app/src/context/global-sync/queue.ts
new file mode 100644
index 000000000..c3468583b
--- /dev/null
+++ b/packages/app/src/context/global-sync/queue.ts
@@ -0,0 +1,83 @@
+type QueueInput = {
+ paused: () => boolean
+ bootstrap: () => Promise<void>
+ bootstrapInstance: (directory: string) => Promise<void> | void
+}
+
+export function createRefreshQueue(input: QueueInput) {
+ const queued = new Set<string>()
+ let root = false
+ let running = false
+ let timer: ReturnType<typeof setTimeout> | undefined
+
+ const tick = () => new Promise<void>((resolve) => setTimeout(resolve, 0))
+
+ const take = (count: number) => {
+ if (queued.size === 0) return [] as string[]
+ const items: string[] = []
+ for (const item of queued) {
+ queued.delete(item)
+ items.push(item)
+ if (items.length >= count) break
+ }
+ return items
+ }
+
+ const schedule = () => {
+ if (timer) return
+ timer = setTimeout(() => {
+ timer = undefined
+ void drain()
+ }, 0)
+ }
+
+ const push = (directory: string) => {
+ if (!directory) return
+ queued.add(directory)
+ if (input.paused()) return
+ schedule()
+ }
+
+ const refresh = () => {
+ root = true
+ if (input.paused()) return
+ schedule()
+ }
+
+ async function drain() {
+ if (running) return
+ running = true
+ try {
+ while (true) {
+ if (input.paused()) return
+ if (root) {
+ root = false
+ await input.bootstrap()
+ await tick()
+ continue
+ }
+ const dirs = take(2)
+ if (dirs.length === 0) return
+ await Promise.all(dirs.map((dir) => input.bootstrapInstance(dir)))
+ await tick()
+ }
+ } finally {
+ running = false
+ if (input.paused()) return
+ if (root || queued.size) schedule()
+ }
+ }
+
+ return {
+ push,
+ refresh,
+ clear(directory: string) {
+ queued.delete(directory)
+ },
+ dispose() {
+ if (!timer) return
+ clearTimeout(timer)
+ timer = undefined
+ },
+ }
+}