mirror of
https://github.com/morluto/rea.git
synced 2026-10-29 02:45:58 +00:00
* fix(setup): preserve concurrent client configuration edits * fix(setup): normalize configuration transaction queue paths * fix(setup): report concurrent snapshot read conflicts * test(setup): isolate Pi workflows from installed Hopper * test: align inherited fixtures with current analysis contracts * test(ida): assert search recovery instead of diagnostic prose * fix(setup): share configuration queue keys across directory aliases Resolve parent-directory aliases for regular and missing configuration paths so a directory symlink and its real directory serialize setup instead of racing the same file. Co-authored-by: morluto <morluto@users.noreply.github.com> --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com>
28 lines
738 B
TypeScript
28 lines
738 B
TypeScript
import { resolve } from "node:path";
|
|
|
|
const activeTransactions = new Map<string, Promise<void>>();
|
|
|
|
/**
|
|
* Serialize the full read/merge/publish operation for one resolved
|
|
* configuration path.
|
|
*/
|
|
export const withClientConfigurationTransaction = async <Value>(
|
|
path: string,
|
|
operation: () => Promise<Value>,
|
|
): Promise<Value> => {
|
|
const key = resolve(path);
|
|
const previous = activeTransactions.get(key);
|
|
let release!: () => void;
|
|
const current = new Promise<void>((complete) => {
|
|
release = complete;
|
|
});
|
|
activeTransactions.set(key, current);
|
|
await previous;
|
|
try {
|
|
return await operation();
|
|
} finally {
|
|
release();
|
|
if (activeTransactions.get(key) === current) activeTransactions.delete(key);
|
|
}
|
|
};
|