"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.NodeJsStorage = exports.readMeta = void 0;
var _blob = require("./blob");
var _source = require("../source");function _objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};var ownKeys = Object.keys(source);if (typeof Object.getOwnPropertySymbols === 'function') {ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {return Object.getOwnPropertyDescriptor(source, sym).enumerable;}));}ownKeys.forEach(function (key) {_defineProperty(target, key, source[key]);});}return target;}function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}

const readMeta = async (appDir, hash) => {
  const buf = await (0, _blob.readBlob)(appDir, hash);
  const metadata = JSON.parse(buf.toString('utf-8'));
  metadata.at = new Date(metadata.at);
  return metadata;
};exports.readMeta = readMeta;

class NodeJsStorage {




  constructor(appDir) {_defineProperty(this, "_appDir", void 0);_defineProperty(this, "_index", {});_defineProperty(this, "_init", void 0);
    this._appDir = appDir;

    this._init = this._createIndex();
  }

  async _updateIndex(metadata) {
    if (!(metadata.id in this._index)) {
      this._index[metadata.id] = [];
    }
    this._index[metadata.id].unshift(metadata);
  }

  async _createIndex() {
    const hashes = Array.from(new Set((await (0, _blob.listBlobs)(this._appDir, '.json'))));
    const metadataAr = await Promise.all(
    hashes.map(async hash => readMeta(this._appDir, hash)));

    const sortByDateDesc = (a, b) =>
    a.at.valueOf() - b.at.valueOf();

    metadataAr.sort(sortByDateDesc).forEach(metadata => {
      this._updateIndex(metadata);
    });
  }

  async toAppState(metadata) {
    const code = (await (0, _blob.readBlob)(this._appDir, metadata.codeHash)).toString(
    'utf-8');

    return _objectSpread({}, metadata, { code });
  }

  async readById(id) {
    await this._init;
    if (id in this._index) {
      return this.toAppState(this._index[id][0]);
    } else {
      return null;
    }
  }

  async updateAppState(id, code, results) {
    await this._init;

    const codeHash = await (0, _blob.writeBlob)(this._appDir, code, '.md');

    const { root } = await (0, _source.parse)(code);
    const found = root.children.find(
    child => child.type === 'heading');

    const title =
    found &&
    found.children &&
    found.children.
    map(child => child.value).
    filter(s => s).
    join(' ');

    const metadata = {
      title,
      codeHash,
      tags: [],
      at: new Date(),
      id,
      results };

    await (0, _blob.writeBlob)(this._appDir, JSON.stringify(metadata), '.json');

    await this._updateIndex(metadata);
  }

  async find() {
    await this._init;
    const appStates = await Promise.all(
    Object.keys(this._index).map(id => this.toAppState(this._index[id][0])));

    // FIXME sort

    return appStates;
  }}exports.NodeJsStorage = NodeJsStorage;