'use strict';
class Model {
constructor() {
this.words = new Map();
}
add_words(words) {
for (let word of words) {
this.words.set(word,1+(this.words.get(word) || 0));
}
}
get_most_common_pairs(how_many) {
let pairs = [...this.words];
pairs.sort((a,b) => { return b[1] - a[1] });
pairs.splice(how_many);
return pairs;
}
};
class View {
words_from_input(input) {
return input.split(/\s+/).filter(word => word.length > 0);
}
table_from_ranked_pairs(ranked_pairs) {
return ranked_pairs.map( pair => View.vsprintf('%-15s %3d',pair) ).join("\n");
}
};
View.vsprintf = require('sprintf-js').vsprintf;
class HTTPController {
constructor(model,view) {
this.model = model;
this.view = view;
}
on_request(req,res) {
if (req.method == 'GET') {
this.get_words(req,res)
}
else if (req.method == 'POST') {
this.post_words(req,res)
}
}
respond(res,text) {
res.setHeader('Content-type','text/plain');
res.statusCode = 200;
res.write(`${text}\n`,'',() => { res.end() });
}
get_words(req,res) {
const query = HTTPController.url_parse(req.url,true).query;
const how_many = query.n || 10;
const most_common_pairs = this.model.get_most_common_pairs(how_many);
const table = this.view.table_from_ranked_pairs(most_common_pairs);
this.respond(res,table);
}
post_words(req,res) {
let buffer = '';
req.on('data', (chunk) => {
buffer += chunk;
});
req.on('end', () => {
const words = this.view.words_from_input(buffer);
this.model.add_words(words);
this.respond(res,'ok');
})
}
}
HTTPController.url_parse = require('url').parse;
const model = new Model();
const view = new View();
const http = require('http');
const httpcontroller = new HTTPController(model,view);
const httpserver = http.createServer((req,res) => {
httpcontroller.on_request(req,res);
});
httpserver.listen(8080,'localhost');