<commit_before>@@library(io/reactors/debugger/lib/jquery/jquery-1.12.4.min.js)
@@library(io/reactors/debugger/js/event-bus.js)
@@component(io/reactors/debugger/com/config.html)


<template id="x-model">
  <div class="x-model-root">
    <!-- model -->
  </div>
</template>


<script>
  "use strict";

  var Model = Vue.extend({
    template: "#x-model",
    props: ["config", "api"],
    data: function() {
      return {
        heartbeatRate: this.config.model.heartbeatRate,
        running: true,
        suid: "",
        state: {
          reactors: {},
          channels: {},
          shellPendingOutput: {},
        },
        eventBus: new EventBus(),
        history: [],
        timestamp: 0
      };
    },
    attached: function() {
      var update = () => {
        if (!this.running) return;

        this.api.state(this.suid, this.timestamp, this.repluids()).done((data) => {
          // Update session uid.
          this.ensure(data.suid, "Session uid not found in state update.");
          this.suid = data.suid;

          // Update timestamp.
          this.ensure(data.ts, "Timestamp not found in state update.");
          this.timestamp = data.ts;

          // Update model state.
          if (data.state) {
            this.eventBus.post("state-reset");

            // Update reactor list.
            for (var uid in data.state.reactors) {
              if (data.state.reactors.hasOwnProperty(uid)) {
                this.state.reactors[uid] = data.state.reactors[uid];
                this.eventBus.post("reactor-seen", uid);
              }
            }

            // Update channel list.
            for (var uid in data.state.channels) {
              if (data.state.channels.hasOwnProperty(uid)) {
                this.state.channels[uid] = data.state.channels[uid];
              }
            }
          } else {
            this.ensure(data.deltas, "Neither state nor deltas found in state update.");
            for (var i = 0; i < data.deltas.length; i++) {
              var delta = data.deltas[i];
              this.history.push(this.enrichDelta(delta));
              this.apply(delta);
            }
            if (this.history.length > this.config.model.historySize) {
              var len = this.history.length - this.config.model.historySize;
              this.history.splice(0, len);
            }
          }

          // Update pending output.
          var pendingOutput = data["pending-output"];
          if (pendingOutput) {
            for (var ruid in pendingOutput) if (pendingOutput.hasOwnProperty(ruid)) {
              var buffer = this.state.shellPendingOutput[ruid];
              var output = pendingOutput[ruid];
              if (buffer && output ) buffer.push(output);
            }
          }

          this.eventBus.post("state-update-done");

          // Reset heartbeat and repeat.
          this.heartbeatRate = Math.max(
            this.heartbeatRate / 6, this.config.model.heartbeatRate);
          setTimeout(update, this.heartbeatRate * 1000);
        }).fail((err) => {
          // Slow down heartbeat and repeat.
          this.heartbeatRate = Math.min(
            this.heartbeatRate * 3 / 2, this.config.model.maxHeartbeatRate);
          setTimeout(update, this.heartbeatRate * 1000);
        });
      };

      update();
    },
    methods: {
      stop: function() {
        this.running = false;
      },
      ensure: function(cond, msg) {
        if (typeof cond == "undefined") this.$dispatch("critical-error", msg);
      },
      apply: function(delta) {
        switch (delta[0]) {
          case "start":
            this.state.reactors[delta[1]] = {
              name: delta[2]
            };
            this.eventBus.post("reactor-started", delta[1]);
            break;
          case "die":
            break;
          case "term":
            delete this.state.reactors[delta[1]];
            break;
          case "open":
            this.state.channels[delta[1]] = {
              name: delta[2],
              reactor: delta[3]
            };
            break;
          case "seal":
            delete this.state.channels[delta[1]];
            break;
        }
      },
      enrichDelta: function(delta) {
        var enriched = {
          tpe: delta[0],
          event: delta,
          time: Date.now()
        }
        switch (delta[0]) {
          case "start":
            enriched.reactorId = delta[1];
            enriched.reactorName = delta[2];
            break;
          case "die":
            enriched.reactorId = delta[1];
            enriched.reactorName = this.state.reactors[delta[1]].name;
            break;
          case "term":
            enriched.reactorId = delta[1];
            enriched.reactorName = this.state.reactors[delta[1]].name;
            break;
          case "open":
            enriched.channelId = delta[1];
            enriched.channelName = delta[2];
            enriched.reactorId = delta[3];
            enriched.reactorName = this.state.reactors[delta[3]].name;
            break;
          case "seal":
            enriched.channelId = delta[1];
            enriched.channelName = this.state.channels[delta[1]].name;
            enriched.reactorId = this.state.channels[delta[1]].reactor;
            enriched.reactorName = this.state.reactors[enriched.reactorId].name;
            break;
        }
        return enriched;
      },
      repluids: function() {
        return Object.keys(this.state.shellPendingOutput);
      }
    }
  });

  Vue.component("x-model", Model);
</script>


<style type="text/css">
</style>
<commit_msg>Add terminated event to event bus, and emit entire reactor instead of ID.<commit_after>@@library(io/reactors/debugger/lib/jquery/jquery-1.12.4.min.js)
@@library(io/reactors/debugger/js/event-bus.js)
@@component(io/reactors/debugger/com/config.html)


<template id="x-model">
  <div class="x-model-root">
    <!-- model -->
  </div>
</template>


<script>
  "use strict";

  var Model = Vue.extend({
    template: "#x-model",
    props: ["config", "api"],
    data: function() {
      return {
        heartbeatRate: this.config.model.heartbeatRate,
        running: true,
        suid: "",
        state: {
          reactors: {},
          channels: {},
          shellPendingOutput: {},
        },
        eventBus: new EventBus(),
        history: [],
        timestamp: 0
      };
    },
    attached: function() {
      var update = () => {
        if (!this.running) return;

        this.api.state(this.suid, this.timestamp, this.repluids()).done((data) => {
          // Update session uid.
          this.ensure(data.suid, "Session uid not found in state update.");
          this.suid = data.suid;

          // Update timestamp.
          this.ensure(data.ts, "Timestamp not found in state update.");
          this.timestamp = data.ts;

          // Update model state.
          if (data.state) {
            this.eventBus.post("state-reset");

            // Update reactor list.
            for (var uid in data.state.reactors) {
              if (data.state.reactors.hasOwnProperty(uid)) {
                this.state.reactors[uid] = data.state.reactors[uid];
                this.eventBus.post("reactor-seen", uid);
              }
            }

            // Update channel list.
            for (var uid in data.state.channels) {
              if (data.state.channels.hasOwnProperty(uid)) {
                this.state.channels[uid] = data.state.channels[uid];
              }
            }
          } else {
            this.ensure(data.deltas, "Neither state nor deltas found in state update.");
            for (var i = 0; i < data.deltas.length; i++) {
              var delta = data.deltas[i];
              this.history.push(this.enrichDelta(delta));
              this.apply(delta);
            }
            if (this.history.length > this.config.model.historySize) {
              var len = this.history.length - this.config.model.historySize;
              this.history.splice(0, len);
            }
          }

          // Update pending output.
          var pendingOutput = data["pending-output"];
          if (pendingOutput) {
            for (var ruid in pendingOutput) if (pendingOutput.hasOwnProperty(ruid)) {
              var buffer = this.state.shellPendingOutput[ruid];
              var output = pendingOutput[ruid];
              if (buffer && output ) buffer.push(output);
            }
          }

          this.eventBus.post("state-update-done");

          // Reset heartbeat and repeat.
          this.heartbeatRate = Math.max(
            this.heartbeatRate / 6, this.config.model.heartbeatRate);
          setTimeout(update, this.heartbeatRate * 1000);
        }).fail((err) => {
          // Slow down heartbeat and repeat.
          this.heartbeatRate = Math.min(
            this.heartbeatRate * 3 / 2, this.config.model.maxHeartbeatRate);
          setTimeout(update, this.heartbeatRate * 1000);
        });
      };

      update();
    },
    methods: {
      stop: function() {
        this.running = false;
      },
      ensure: function(cond, msg) {
        if (typeof cond == "undefined") this.$dispatch("critical-error", msg);
      },
      apply: function(delta) {
        switch (delta[0]) {
          case "start":
            var reactor = {
              uid: delta[1]
              name: delta[2]
            };
            this.state.reactors[delta[1]] = reactor
            this.eventBus.post("reactor-started", reactor);
            break;
          case "die":
            break;
          case "term":
            var reactor = this.state.reactors[delta[1]];
            delete this.state.reactors[delta[1]];
            this.eventBus.post("reactor-terminated", reactor);
            break;
          case "open":
            this.state.channels[delta[1]] = {
              uid: delta[1],
              name: delta[2],
              reactor: delta[3]
            };
            break;
          case "seal":
            delete this.state.channels[delta[1]];
            break;
        }
      },
      enrichDelta: function(delta) {
        var enriched = {
          tpe: delta[0],
          event: delta,
          time: Date.now()
        }
        switch (delta[0]) {
          case "start":
            enriched.reactorId = delta[1];
            enriched.reactorName = delta[2];
            break;
          case "die":
            enriched.reactorId = delta[1];
            enriched.reactorName = this.state.reactors[delta[1]].name;
            break;
          case "term":
            enriched.reactorId = delta[1];
            enriched.reactorName = this.state.reactors[delta[1]].name;
            break;
          case "open":
            enriched.channelId = delta[1];
            enriched.channelName = delta[2];
            enriched.reactorId = delta[3];
            enriched.reactorName = this.state.reactors[delta[3]].name;
            break;
          case "seal":
            enriched.channelId = delta[1];
            enriched.channelName = this.state.channels[delta[1]].name;
            enriched.reactorId = this.state.channels[delta[1]].reactor;
            enriched.reactorName = this.state.reactors[enriched.reactorId].name;
            break;
        }
        return enriched;
      },
      repluids: function() {
        return Object.keys(this.state.shellPendingOutput);
      }
    }
  });

  Vue.component("x-model", Model);
</script>


<style type="text/css">
</style>

{'fraction_non_alphanumeric': 0.13329270416158803, 'fraction_numerical': 0.007487375935921992, 'mean_word_length': 1.6112752898385996, 'pattern_counts': {'":': 20, '<': 23, '<?xml version=': 0, '>': 29, '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': '5833387', 'n_tokens_mistral': 3375, 'n_tokens_neox': 3268, 'n_words': 632}