code: function writeSync(props: {
    filePath: string,
    sourceCode: string,
    transformCacheKey: string,
    transformOptions: TransformOptions,
    result: CachedResult,
  }): void {
    const cacheFilePath = getCacheFilePaths(props);
    mkdirp.sync(path.dirname(cacheFilePath.transformedCode));
    const {result} = props;
    unlinkIfExistsSync(cacheFilePath.transformedCode);
    unlinkIfExistsSync(cacheFilePath.metadata);
    writeFileAtomicSync(cacheFilePath.transformedCode, result.code);
    writeFileAtomicSync(cacheFilePath.metadata, JSON.stringify([
      imurmurhash(result.code).result(),
      hashSourceCode(props),
      result.dependencies,
      result.dependencyOffsets,
      result.map,
    ]));
  }
docs: In the workers we are fine doing sync work because a worker is meant to
  process a single source file at a time.
  
  We store the transformed JS because it is likely to be much bigger than the
  rest of the data JSON. Probably the map should be stored separately as well.
  
  We make the write operation as much atomic as possible: indeed, if another
  process is reading the cache at the same time, there would be a risk it
  reads new transformed code, but old metadata. This is avoided by removing
  the files first.
  
  There is still a risk of conflincting writes, that is mitigated by hashing
  the result code, that is verified at the end. In case of writes happening
  close to each others, one of the workers is going to loose its results no
  matter what.