Files
orcs-code/src/utils/sequential.ts
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr d2542c9a62 asdf
Squash the current repository state back into one baseline commit while
preserving the README reframing and repository contents.

Constraint: User explicitly requested a single squashed commit with subject "asdf"
Confidence: high
Scope-risk: broad
Reversibility: clean
Directive: This commit intentionally rewrites published history; coordinate before future force-pushes
Tested: git status clean; local history rewritten to one commit; force-pushed main to origin and instructkr
Not-tested: Fresh clone verification after push
2026-03-31 03:34:03 -07:00

57 lines
1.6 KiB
TypeScript

type QueueItem<T extends unknown[], R> = {
args: T
resolve: (value: R) => void
reject: (reason?: unknown) => void
context: unknown
}
/**
* Creates a sequential execution wrapper for async functions to prevent race conditions.
* Ensures that concurrent calls to the wrapped function are executed one at a time
* in the order they were received, while preserving the correct return values.
*
* This is useful for operations that must be performed sequentially, such as
* file writes or database updates that could cause conflicts if executed concurrently.
*
* @param fn - The async function to wrap with sequential execution
* @returns A wrapped version of the function that executes calls sequentially
*/
export function sequential<T extends unknown[], R>(
fn: (...args: T) => Promise<R>,
): (...args: T) => Promise<R> {
const queue: QueueItem<T, R>[] = []
let processing = false
async function processQueue(): Promise<void> {
if (processing) return
if (queue.length === 0) return
processing = true
while (queue.length > 0) {
const { args, resolve, reject, context } = queue.shift()!
try {
const result = await fn.apply(context, args)
resolve(result)
} catch (error) {
reject(error)
}
}
processing = false
// Check if new items were added while we were processing
if (queue.length > 0) {
void processQueue()
}
}
return function (this: unknown, ...args: T): Promise<R> {
return new Promise((resolve, reject) => {
queue.push({ args, resolve, reject, context: this })
void processQueue()
})
}
}