index.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*globals angular:true, benchmarksman:true*/
  2. angular.module("app", [
  3. "ui.bootstrap",
  4. "ui.ace"
  5. ])
  6. .controller("MainCtrl",
  7. ["$scope", "$timeout", "$interpolate",
  8. function($scope, $timeout, $interpolate) {
  9. $scope.inputs = "";
  10. $scope.pipeline = "";
  11. $scope.output = "";
  12. $scope.isRunning = false;
  13. $scope.exampleName = "numbers";
  14. $scope.examples = {
  15. numbers: {
  16. inputs: [
  17. {n:0},
  18. {n:1},
  19. {n:2},
  20. {n:3},
  21. {n:4},
  22. {n:5},
  23. {n:6},
  24. {n:7},
  25. {n:8},
  26. {n:9},
  27. ],
  28. pipeline: [
  29. {$match:{
  30. n: {$gt: 3},
  31. }},
  32. {$project:{
  33. n: true,
  34. nn: {$multiply: ["$n", "$n"]},
  35. }},
  36. ],
  37. },
  38. strings: {
  39. inputs: [
  40. {c:"a"},
  41. {c:"b"},
  42. {c:"c"},
  43. {c:"d"},
  44. {c:"e"},
  45. {c:"f"},
  46. {c:"g"},
  47. {c:"h"},
  48. {c:"i"},
  49. {c:"j"},
  50. ],
  51. pipeline: [
  52. {$match:{
  53. c: {$lt: "e"},
  54. }},
  55. {$project:{
  56. c: true,
  57. cc: {$concat: ["$c", "$c"]},
  58. }},
  59. ],
  60. },
  61. };
  62. $scope.setExample = function(exName) {
  63. $scope.exampleName = exName;
  64. };
  65. var getFormattedDocs = function getFormattedDocs(docs) {
  66. return "[\n" +
  67. "\t" + docs.map(function(doc) {
  68. return JSON.stringify(doc, 0, 1)
  69. .replace(/\n\s*/g, " ");
  70. })
  71. .join(",\n\t") +
  72. "\n]\n";
  73. };
  74. $scope.$watch("exampleName", function onExampleNameChanged() {
  75. if (!($scope.exampleName in $scope.examples))
  76. throw new Error("invalid exampleName");
  77. var example = $scope.examples[$scope.exampleName];
  78. $scope.inputs = "exports.inputs = " + getFormattedDocs(example.inputs).trimRight() + ";\n";
  79. $scope.pipeline = "exports.pipeline = [\n" +
  80. "\n\t" +
  81. example.pipeline.map(function(docSrc) {
  82. for (var key in docSrc) break; // get first key
  83. return "{" + key + ": " +
  84. JSON.stringify(docSrc[key], 0, "\t") +
  85. "}";
  86. })
  87. .join(",\n\n")
  88. .split("\n")
  89. .join("\n\t") +
  90. "\n\n];\n";
  91. $scope.output = "";
  92. });
  93. $scope.run = function run() {
  94. $scope.output = "";
  95. $scope.isRunning = true;
  96. // force UI update if not in progress (i.e., from non-angular event)
  97. if (!$scope.$$phase)
  98. $scope.$apply();
  99. try {
  100. //jshint evil:true
  101. var inputs = eval("(exports={})," + $scope.inputs);
  102. var pipeline = eval("(exports={})," + $scope.pipeline);
  103. //jshint evil:false
  104. $timeout(function() { // defer a bit to allow UI to update
  105. var output = aggregate(pipeline, inputs);
  106. $scope.output = "exports.outputs = " + getFormattedDocs(output).trimRight() + ";\n";
  107. $scope.isRunning = false;
  108. }, 100);
  109. } catch (err) {
  110. $scope.isRunning = false;
  111. $scope.output = String(err);
  112. $scope.$apply();
  113. }
  114. };
  115. $scope.aceLoaded = function aceLoaded(editor) {
  116. // disable warning about deprecated autoscroll behavior
  117. editor.$blockScrolling = Infinity;
  118. // enable simple completion
  119. editor.setOptions({
  120. enableBasicAutocompletion: true,
  121. enableSnippets: false,
  122. });
  123. // Set Command-Enter to run
  124. editor.commands.addCommand({
  125. name: "run",
  126. bindKey: {
  127. mac: "Command-Enter",
  128. win: "Ctrl-Enter",
  129. },
  130. exec: function execRun(editor) {
  131. $scope.run();
  132. },
  133. });
  134. // Unset Command-L so that it selects location again
  135. editor.commands.addCommand({
  136. name: "location",
  137. bindKey: {
  138. mac: "Command-l",
  139. win: "Ctrl-l",
  140. },
  141. exec: null, // do nothing
  142. });
  143. };
  144. }]);