text: /**
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * @emails oncall+relay
   * 
   * @format
   */
  'use strict';
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
  
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  
  var fs = require('fs');
  
  var invariant = require("fbjs/lib/invariant");
  
  /**
   * A filesystem wrapper that buffers file reads and writes until `commit()` is
   * called.
   */
  var BufferedFilesystem =
  /*#__PURE__*/
  function () {
    function BufferedFilesystem() {
      (0, _defineProperty2["default"])(this, "buffer", new Map());
      (0, _defineProperty2["default"])(this, "committed", false);
    }
  
    var _proto = BufferedFilesystem.prototype;
  
    _proto._assertNotComitted = function _assertNotComitted() {
      !!this.committed ? process.env.NODE_ENV !== "production" ? invariant(false, 'BufferedFilesystem: no operations allowed after commit().') : invariant(false) : void 0;
    };
  
    _proto.commit =
    /*#__PURE__*/
    function () {
      var _commit = _asyncToGenerator(function* (sourceControl) {
        this._assertNotComitted();
  
        this.committed = true;
        var removed = [];
        var added = [];
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;
  
        try {
          for (var _iterator = this.buffer[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var _step$value = _step.value,
                path = _step$value[0],
                data = _step$value[1];
  
            if (data == null) {
              removed.push(path);
              fs.unlinkSync(path);
            } else {
              var fileExisits = fs.existsSync(path);
              var currentData = fileExisits ? fs.readFileSync(path, 'utf8') : null;
  
              if (currentData !== data) {
                added.push(path);
                fs.writeFileSync(path, data, 'utf8');
              }
            }
          }
        } catch (err) {
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion && _iterator["return"] != null) {
              _iterator["return"]();
            }
          } finally {
            if (_didIteratorError) {
              throw _iteratorError;
            }
          }
        }
  
        if (sourceControl) {
          yield sourceControl.addRemove(added, removed);
        }
      });
  
      function commit(_x) {
        return _commit.apply(this, arguments);
      }
  
      return commit;
    }();
  
    _proto.hasChanges = function hasChanges() {
      this._assertNotComitted();
  
      return this.buffer.size > 0;
    };
  
    _proto.getAddedRemovedFiles = function getAddedRemovedFiles() {
      this._assertNotComitted();
  
      var added = [];
      var removed = [];
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;
  
      try {
        for (var _iterator2 = this.buffer[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var _step2$value = _step2.value,
              path = _step2$value[0],
              data = _step2$value[1];
  
          if (data == null) {
            removed.push(path);
          } else {
            if (!fs.existsSync(path)) {
              added.push(path);
            }
          }
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) {
            _iterator2["return"]();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }
  
      return {
        added: added,
        removed: removed
      };
    };
  
    _proto.existsSync = function existsSync(path) {
      this._assertNotComitted();
  
      return this.buffer.has(path) ? Boolean(this.buffer.get(path)) : fs.existsSync(path);
    };
  
    _proto.mkdirSync = function mkdirSync(path) {
      this._assertNotComitted();
  
      fs.mkdirSync(path);
    };
  
    _proto.readdirSync = function readdirSync(path) {
      this._assertNotComitted();
  
      throw new Error('BufferedFilesystem: readdirSync is not implemented.');
    };
  
    _proto.readFileSync = function readFileSync(path, encoding) {
      this._assertNotComitted();
  
      if (this.buffer.has(path)) {
        var data = this.buffer.get(path);
        !(data != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'BufferedFilesystem: trying to read deleted file.') : invariant(false) : void 0;
        return data;
      }
  
      return fs.readFileSync(path, encoding);
    };
  
    _proto.statSync = function statSync(path) {
      this._assertNotComitted();
  
      return fs.statSync(path);
    };
  
    _proto.unlinkSync = function unlinkSync(path) {
      this._assertNotComitted();
  
      this.buffer.set(path, null);
    };
  
    _proto.writeFileSync = function writeFileSync(filename, data, encoding) {
      this._assertNotComitted();
  
      this.buffer.set(filename, data);
    };
  
    _proto.changedFilesToJSON = function changedFilesToJSON() {
      this._assertNotComitted();
  
      var changed = [];
      var removed = [];
      var _iteratorNormalCompletion3 = true;
      var _didIteratorError3 = false;
      var _iteratorError3 = undefined;
  
      try {
        for (var _iterator3 = this.buffer[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
          var _step3$value = _step3.value,
              path = _step3$value[0],
              data = _step3$value[1];
  
          if (data == null) {
            removed.push({
              path: path
            });
          } else {
            changed.push({
              path: path,
              data: data
            });
          }
        }
      } catch (err) {
        _didIteratorError3 = true;
        _iteratorError3 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion3 && _iterator3["return"] != null) {
            _iterator3["return"]();
          }
        } finally {
          if (_didIteratorError3) {
            throw _iteratorError3;
          }
        }
      }
  
      return {
        removed: removed,
        changed: changed
      };
    };
  
    return BufferedFilesystem;
  }();
  
  module.exports = BufferedFilesystem;