@@ -22,6 +22,17 @@ function isRecord(value: unknown): value is Record<string, unknown> {
2222 return ! ! value && typeof value === 'object' && ! Array . isArray ( value ) ;
2323}
2424
25+ let configMutationLock : Promise < void > = Promise . resolve ( ) ;
26+
27+ function withConfigMutationLock < T > ( mutation : ( ) => Promise < T > ) : Promise < T > {
28+ const next = configMutationLock . then ( mutation ) ;
29+ configMutationLock = next . then (
30+ ( ) => { } ,
31+ ( ) => { } ,
32+ ) ;
33+ return next ;
34+ }
35+
2536export async function readConfig ( ) : Promise < Sh1ptConfig > {
2637 try {
2738 const raw = await fs . readFile ( configPath ( ) , 'utf8' ) ;
@@ -37,28 +48,36 @@ export async function readConfig(): Promise<Sh1ptConfig> {
3748 }
3849}
3950
40- export async function writeConfig ( cfg : Sh1ptConfig ) : Promise < void > {
51+ async function writeConfigFile ( cfg : Sh1ptConfig ) : Promise < void > {
4152 await fs . mkdir ( configDir ( ) , { recursive : true , mode : 0o700 } ) ;
42- const tmp = `${ configPath ( ) } .tmp` ;
53+ const tmp = `${ configPath ( ) } .${ process . pid } . ${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } . tmp` ;
4354 await fs . writeFile ( tmp , JSON . stringify ( cfg , null , 2 ) + '\n' , { mode : 0o600 } ) ;
4455 await fs . rename ( tmp , configPath ( ) ) ;
4556}
4657
58+ export function writeConfig ( cfg : Sh1ptConfig ) : Promise < void > {
59+ return withConfigMutationLock ( ( ) => writeConfigFile ( cfg ) ) ;
60+ }
61+
4762export async function getAdapterConfig < T = unknown > ( adapterId : string ) : Promise < T | undefined > {
4863 const cfg = await readConfig ( ) ;
4964 const entry = cfg . adapters [ adapterId ] ;
5065 return entry === undefined ? undefined : ( entry as T ) ;
5166}
5267
5368export async function setAdapterConfig ( adapterId : string , adapterConfig : unknown ) : Promise < void > {
54- const cfg = await readConfig ( ) ;
55- cfg . adapters [ adapterId ] = adapterConfig ;
56- await writeConfig ( cfg ) ;
69+ return withConfigMutationLock ( async ( ) => {
70+ const cfg = await readConfig ( ) ;
71+ cfg . adapters [ adapterId ] = adapterConfig ;
72+ await writeConfigFile ( cfg ) ;
73+ } ) ;
5774}
5875
5976export async function deleteAdapterConfig ( adapterId : string ) : Promise < void > {
60- const cfg = await readConfig ( ) ;
61- if ( ! ( adapterId in cfg . adapters ) ) return ;
62- delete cfg . adapters [ adapterId ] ;
63- await writeConfig ( cfg ) ;
77+ return withConfigMutationLock ( async ( ) => {
78+ const cfg = await readConfig ( ) ;
79+ if ( ! ( adapterId in cfg . adapters ) ) return ;
80+ delete cfg . adapters [ adapterId ] ;
81+ await writeConfigFile ( cfg ) ;
82+ } ) ;
6483}
0 commit comments