<commit_before>module('lively.lang.Runtime').requires("lively.lang.VM").toRun(function() {

Object.extend(lively.lang.Runtime, {

  _livelyRuntimeFileName: "lively-runtime.js",
  _noLivelyRuntimeFileMarker: "no lively-runtime file",

  loadLivelyRuntimeInProjectDir: function(dir, thenDo) {
      dir = dir || "./";
      var fn = lively.lang.Runtime._livelyRuntimeFileName,
          marker = lively.lang.Runtime._noLivelyRuntimeFileMarker,
          fullName = dir + (dir.endsWith("/") ? "" : "/") + fn

      lively.lang.fun.composeAsync(
          lively.shell.ls.curry(dir),
          function(files, next) {
              next(null, files && files.detect(function(ea) {
                  return ea.path.endsWith(fn); }));
          },
          function(file, next) {
              if (!file) return next(marker);
              lively.shell.readFile(file.path, function(cmd) {
                  next(cmd.getCode() ? marker : null, cmd.resultString()); });
          },
          function(livelyRuntimeSource, next) {
              lively.require("lively.lang.VM").toRun(function() {
                lively.lang.Runtime.loadRuntimeConfFile(
                  lively.lang.Runtime.Registry.default(),
                  fullName, livelyRuntimeSource, next); });
          }
      )(function(err, evalResult) {
          if (err === marker) err = null;
          else if (err) show("error loading lively-runtime.js:\n" + (err.stack || err))
          // else alertOK("lively runtime of\n" + dir + "\nloaded!");
          thenDo && thenDo(err);
      });

  },

  resourceChanged: function(registry, resourceId, source, dir, thenDo) {
      var runtime = lively.lang.Runtime;
      if (typeof registry === "string") {
        thenDo = dir;
        dir = source;
        source = resourceId;
        resourceId = registry;
        registry = runtime.Registry.default();
      }

      var runtimeConfFileName = lively.lang.Runtime._livelyRuntimeFileName;
      if (String(resourceId).split("/").last() === runtimeConfFileName) {
        runtime.loadRuntimeConfFile(registry, resourceId, source, thenDo);
      } else {
        lively.lang.fun.composeAsync(
          function(n) { runtime.findProjectForResource(registry, resourceId, n); },
          function(proj, n) { runtime.Project.processChange(proj, resourceId, source, n); }
        )(thenDo);
      }
  },

  loadRuntimeConfFile: function(registry, resourceId, source, thenDo) {
    var runtime = lively.lang.Runtime;
    if (typeof registry === "string") {
      thenDo = source;
      source = resourceId;
      resourceId = registry;
      registry = runtime.Registry.default();
    }

    var sepMatch = resourceId.match(/\\|\//), sep = sepMatch && sepMatch[0],
        rootDir = sep ? resourceId.split(sep).slice(0, -1).join(sep) : null,
        resetRegistry, t = Date.now();
    lively.lang.fun.composeAsync(
      function(n) { runtime.Registry.withCurrent(registry, function(reset) { resetRegistry = reset; n(); }); },
      function(n) { lively.lang.VM.runEval(source, {sourceURL: String(resourceId)}, function(err) { n(err); }); },
      function(n) { setTimeout(function() { n(); }, 100);},
      function(n) {
        var project = runtime.Registry.findFirstProjectUpdatedAfter(registry, t);
        if (rootDir && project) project.rootDir = rootDir;
        n(null, project);
      },
      function(project, n) {
        if (project && project.reloadAll) project.reloadAll(project, n);
        else n(null, null);
      }
    )(function(err) {
        if (err) $world.alert("Error loading " + resourceId + ":\n" + err);
        // else $world.alertOK("Runtime conf file " + resourceId + " loaded");
        resetRegistry && resetRegistry();
        thenDo && thenDo(err);
    });
  },

  findProjectForResource: function(registry, resourceId, thenDo) {
      var runtime = lively.lang.Runtime;
      if (typeof registry === "string") {
        thenDo = resourceId;
        resourceId = registry;
        registry = runtime.Registry.default();
      }

      var project = runtime.Registry.getProjectWithResource(registry, resourceId);
      return thenDo(project ? null : new Error("No project for " + resourceId + " found"), project);
  },

  readFiles: function(project, files, thenDo) {
    lively.lang.arr.mapAsyncSeries(files,
      function(fn,_,n) {
        lively.shell.cat(fn, {cwd: project.rootDir},
        function(err, c) { n(err, {name: fn, content: c}); });
      }, thenDo);
  },

  loadFiles: function(project, files, thenDo) {
    lively.lang.fun.composeAsync(
      lively.lang.Runtime.readFiles.curry(project, files),
      function(filesRead, next) {
        // filesRead = [{name: STRING, content: STRING}*]
        lively.lang.arr.mapAsyncSeries(filesRead,
          function(ea,_,n) {
            lively.lang.Runtime.Project.processChange(
              project, lively.lang.string.joinPath(project.rootDir, ea.name),
              ea.content, n);
          },
          next);
      }
    )(thenDo)
  },

  evalCode: function(project, code, state, resourceName, thenDo) {
    lively.lang.VM.runEval(code,
      {topLevelVarRecorder: state, context: state, sourceURL: resourceName},
      function(err, result) {
    		err && show("error when updating the runtime for " + resourceName + "\n" + (err.stack || err));
    		// !err && alertOK("runtime updated for " + resourceName);
    		thenDo && thenDo(err, result);
    	});
  }

});

lively.lang.Runtime.Registry = {

  default: function () {
    return this._defaultRegistry
        || (this._defaultRegistry = {projects: {}});
  },

  current: function() {
    // will be set when pre-specifying a registry and then running runtime
    // related code like lively-runtime.js
    return this._current || this.default();
  },

  withCurrent: function(registry, doFunc) {
    var self = this,
        former = self._current;
    self._current = registry;<commit_msg>lively.runtime loadFiles promise<commit_after>module('lively.lang.Runtime').requires("lively.lang.VM").toRun(function() {

Object.extend(lively.lang.Runtime, {

  _livelyRuntimeFileName: "lively-runtime.js",
  _noLivelyRuntimeFileMarker: "no lively-runtime file",

  loadLivelyRuntimeInProjectDir: function(dir, thenDo) {
      dir = dir || "./";
      var fn = lively.lang.Runtime._livelyRuntimeFileName,
          marker = lively.lang.Runtime._noLivelyRuntimeFileMarker,
          fullName = dir + (dir.endsWith("/") ? "" : "/") + fn

      lively.lang.fun.composeAsync(
          lively.shell.ls.curry(dir),
          function(files, next) {
              next(null, files && files.detect(function(ea) {
                  return ea.path.endsWith(fn); }));
          },
          function(file, next) {
              if (!file) return next(marker);
              lively.shell.readFile(file.path, function(cmd) {
                  next(cmd.getCode() ? marker : null, cmd.resultString()); });
          },
          function(livelyRuntimeSource, next) {
              lively.require("lively.lang.VM").toRun(function() {
                lively.lang.Runtime.loadRuntimeConfFile(
                  lively.lang.Runtime.Registry.default(),
                  fullName, livelyRuntimeSource, next); });
          }
      )(function(err, evalResult) {
          if (err === marker) err = null;
          else if (err) show("error loading lively-runtime.js:\n" + (err.stack || err))
          // else alertOK("lively runtime of\n" + dir + "\nloaded!");
          thenDo && thenDo(err);
      });

  },

  resourceChanged: function(registry, resourceId, source, dir, thenDo) {
      var runtime = lively.lang.Runtime;
      if (typeof registry === "string") {
        thenDo = dir;
        dir = source;
        source = resourceId;
        resourceId = registry;
        registry = runtime.Registry.default();
      }

      var runtimeConfFileName = lively.lang.Runtime._livelyRuntimeFileName;
      if (String(resourceId).split("/").last() === runtimeConfFileName) {
        runtime.loadRuntimeConfFile(registry, resourceId, source, thenDo);
      } else {
        lively.lang.fun.composeAsync(
          function(n) { runtime.findProjectForResource(registry, resourceId, n); },
          function(proj, n) { runtime.Project.processChange(proj, resourceId, source, n); }
        )(thenDo);
      }
  },

  loadRuntimeConfFile: function(registry, resourceId, source, thenDo) {
    var runtime = lively.lang.Runtime;
    if (typeof registry === "string") {
      thenDo = source;
      source = resourceId;
      resourceId = registry;
      registry = runtime.Registry.default();
    }

    var sepMatch = resourceId.match(/\\|\//), sep = sepMatch && sepMatch[0],
        rootDir = sep ? resourceId.split(sep).slice(0, -1).join(sep) : null,
        resetRegistry, t = Date.now();
    lively.lang.fun.composeAsync(
      function(n) { runtime.Registry.withCurrent(registry, function(reset) { resetRegistry = reset; n(); }); },
      function(n) { lively.lang.VM.runEval(source, {sourceURL: String(resourceId)}, function(err) { n(err); }); },
      function(n) { setTimeout(function() { n(); }, 100);},
      function(n) {
        var project = runtime.Registry.findFirstProjectUpdatedAfter(registry, t);
        if (rootDir && project) project.rootDir = rootDir;
        n(null, project);
      },
      function(project, n) {
        if (project && project.reloadAll) project.reloadAll(project, n);
        else n(null, null);
      }
    )(function(err) {
        if (err) $world.alert("Error loading " + resourceId + ":\n" + err);
        // else $world.alertOK("Runtime conf file " + resourceId + " loaded");
        resetRegistry && resetRegistry();
        thenDo && thenDo(err);
    });
  },

  findProjectForResource: function(registry, resourceId, thenDo) {
      var runtime = lively.lang.Runtime;
      if (typeof registry === "string") {
        thenDo = resourceId;
        resourceId = registry;
        registry = runtime.Registry.default();
      }

      var project = runtime.Registry.getProjectWithResource(registry, resourceId);
      return thenDo(project ? null : new Error("No project for " + resourceId + " found"), project);
  },

  readFiles: function(project, files, thenDo) {
    lively.lang.arr.mapAsyncSeries(files,
      function(fn,_,n) {
        lively.shell.cat(fn, {cwd: project.rootDir},
        function(err, c) { n(err, {name: fn, content: c}); });
      }, thenDo);
  },

  loadFiles: function(project, files, thenDo) {
    return lively.lang.fun.composeAsync(
      lively.lang.Runtime.readFiles.curry(project, files),
      function(filesRead, next) {
        // filesRead = [{name: STRING, content: STRING}*]
        lively.lang.arr.mapAsyncSeries(filesRead,
          function(ea,_,n) {
            lively.lang.Runtime.Project.processChange(
              project, lively.lang.string.joinPath(project.rootDir, ea.name),
              ea.content, n);
          },
          next);
      }
    )(thenDo);
  },

  evalCode: function(project, code, state, resourceName, thenDo) {
    lively.lang.VM.runEval(code,
      {topLevelVarRecorder: state, context: state, sourceURL: resourceName},
      function(err, result) {
    		err && show("error when updating the runtime for " + resourceName + "\n" + (err.stack || err));
    		// !err && alertOK("runtime updated for " + resourceName);
    		thenDo && thenDo(err, result);
    	});
  }

});

lively.lang.Runtime.Registry = {

  default: function () {
    return this._defaultRegistry
        || (this._defaultRegistry = {projects: {}});
  },

  current: function() {
    // will be set when pre-specifying a registry and then running runtime
    // related code like lively-runtime.js
    return this._current || this.default();
  },

  withCurrent: function(registry, doFunc) {
    var self = this,
        former = self._current;
    self._current = registry;
{'fraction_non_alphanumeric': 0.1450864614086883, 'fraction_numerical': 0.0010122311261071277, 'mean_word_length': 2.6047430830039526, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5600616', 'n_tokens_mistral': 3538, 'n_tokens_neox': 3451, 'n_words': 710}