makeFileWriter = (
  fileName,
  { fs, path },
  make = there => makeFileWriter(there, { fs, path }, make),
) => {
  const writeText = async (txt, opts) => {
    const promise = mutex;
    let release = Function.prototype;
    mutex = new Promise(resolve => {
      release = resolve;
    });
    await promise;
    try {
      return await fs.promises.writeFile(fileName, txt, opts);
    } finally {
      release(undefined);
    }
  };

  return harden({
    toString: () => fileName,
    writeText,
    readOnly: () => makeFileReader(fileName, { fs, path }),
    neighbor: ref => make(path.resolve(fileName, ref)),
    mkdir: opts => fs.promises.mkdir(fileName, opts),
    rm: opts => fs.promises.rm(fileName, opts),
    rename: newName =>
      fs.promises.rename(
        fileName,
        path.resolve(path.dirname(fileName), newName),
      ),
  });
}
@param {string} fileName
@param {{
  fs: Pick<import('fs'), 'existsSync'> &
    { promises: Pick<
        import('fs/promises'),
        'readFile' | 'stat' | 'writeFile' | 'mkdir' | 'rename' | 'rm'
      >,
    },
  path: Pick<import('path'), 'dirname' | 'resolve' | 'relative' | 'normalize'>,
}} io
@param {(there: string) => ReturnType<makeFileWriter>} make