UNPKG

reactive-superglue

Version:

Stream-based middleware for I/O integration of sources and sinks

215 lines (190 loc) 5.83 kB
var _ = require("highland") var http = require("http") var https = require("https") var proto = _().constructor.prototype var url = require("url") var express = require("express") module.exports = _ //cases: //_.http(req, res) //=>infers type. Pasando //_.http("http://www.google.es") //=> parses and infers type, returning the appropriate stream //some_stream().post("some url", "text/csv") //converts and sends a continuous post stream //_.ingest("route, defaults to /", optional_express_app) //infers the incoming data and passes a formatted stream // //some_stream().post("some url", "ndjson") //stringifies and sends a continuous post stream //some_stream().post("some url", "text/plain") //sends a continuous post stream (http("http://myserver/samples/last1000") .filter(lib_signal.lpf, x=>x.value) //processor, replacement .save(db.collection("")) (db.collection("samples").aggregate([]).post("http://someendpoint/samples")) (db.collection("$collection").aggregate([]).post("http://someendpoint/$collection")) //(db.collection("$collection").aggregate("$aggregate").serve("/$collection/$aggregate")) http.serve("/$collection/$start/$end").from(p => db.collection(p.collection).find({start: p.start})) http.get("http://localhost/a") //=> url -> stream http.receive("/$collection").into(p => db.collection(p.collection)) _.http = function (u) { return _(function (push, next) { var p = u.indexOf("https://") > -1 ? https : http var req = p.get(u, (res)=> { if (!res.headers["content-type"]) var type = undefined; else var type = res.headers["content-type"].split(";")[0] push(null, infer_type(type, res)); }) }).flatten() } _.http.get=function(u){return _.http(u)} _.http.server=server function server(app){ if(!(this instanceof server)) return new server(app) this.app=app||express() if(!app) this.app.listen(3000) } server.prototype.serve=function(route, from){ if(!route) route="/" else if(typeof route!=="string") from = route var self=this; if(!from) return { from: function(stream){return self.serve(route, stream)} } this.app.all(route, function(req, res, next){ var input=from(req); input.pipe(res); }) } server.prototype.receive=function(route, into){ if(!route) route="/" else if(typeof route!=="string") into = route var self=this; if(!into) return { into: function(stream){return self.serve(route, stream)} } this.app.put(route, function(req, res){ var input=req; input.pipe(into(req)) }) } _.testserver = function (cb) { var cfg = { port: 3000, route: "/", ingester: function (req, res, next) { console.log("req!") var samples = [{a: 1, b: 2}, {a: 2, b: 4}] var str = _(samples).json().pipe(res) str.on("finish", ()=>res.end()) } } return _.ingest(cfg, cb) } _.ingest = function (config, cb) { console.log("cb", cb) if (!config) { config = {port: 3000, route: "/", app: express(), ingester: ingester} } if (!config.app) { config.app = express() config.app.listen(config.port); } setImmediate(cb) return _(function (push, next) { config.app.all(config.route, config.ingester) }).flatten() function ingester(req, res, express_next) { var type = req.get("content-type") var str = infer_type(type, req) str.fork().done(function () { res.end() }) push(null, str) next() } } function infer_type(type, res) { switch (type) { case "application/json": res.setEncoding("utf-8") var lines = "" var result = _(res).split().scan("", (prev, line) => { try { lines += line if (!line.trim().endsWith("}") && !line.trim().endsWith("]")) { //to speed it up a bit return null; } var result = JSON.parse(lines); lines = "" return result } catch (err) { console.log(err) return null; } }).compact() return result; break; default: return _(res) } } proto.post = function (u) { var req=http.request(u, function(res){ console.log("received res for", u, res.statusCode) }) req.on("error", function(err){ throw err }) var forked=this.fork(); var str=forked.pipe(req) return this; } /* _.http=function(obj, encoding){ if(obj instanceof http.IncomingMessage ||obj instanceof http.ClientRequest){ return infer_stream(obj).flatten() } if(typeof obj=="string"){ return _(function (push, next){ var req=http.get(obj, (res)=>{ if(!encoding) res.setEncoding("utf8") else res.setEncoding(encoding) push(null, infer_stream(req, res)) }) }).flatten() } return _(function(push, next){ var req=http.request(obj, (res)=>{ if(!encoding) res.setEncoding("utf8") else res.setEncoding(encoding) push(null, {req:req, res: res}); }) }) } _.http_server=function(config){ if(!config || config.port) { var app=express() app.listen(app.port||3000) return app; } else throw "Bad argument" } proto.post=function(u){ var opts=url.parse(u) opts.method="POST" var response; http.request(opts, function(res){ response=res; response.write(x, pending.next) }) var pending; return function(err, x, push, next){ if(err) return push(err) return push(null, x) if(x!==_.nil && response) { response.write(x, next); } else { pending.x=x pending.push=push pending.next=next } } } var writer=_.http({}) */