UNPKG

derby

Version:

MVC framework making it easy to write realtime, collaborative applications that run in both Node.js and browsers.

103 lines (102 loc) 4.03 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PageForServer = void 0; var Page_1 = require("./Page"); var PageForServer = /** @class */ (function (_super) { __extends(PageForServer, _super); function PageForServer(app, model, req, res) { var _this = _super.call(this, app, model) || this; _this.req = req; _this.res = res; _this.page = _this; return _this; } PageForServer.prototype.render = function (ns, status) { var _this = this; this.app.emit('render', this); if (status) this.res.statusCode = status; // Prevent the browser from storing the HTML response in its back cache, since // that will cause it to render with the data from the initial load first this.res.setHeader('Cache-Control', 'no-store'); // Set HTML utf-8 content type unless already set if (!this.res.getHeader('Content-Type')) { this.res.setHeader('Content-Type', 'text/html; charset=utf-8'); } this._setRenderParams(ns); var pageHtml = this.get('Page', ns); this.res.write(pageHtml); this.app.emit('htmlDone', this); this.res.write('<script data-derby-app-state type="application/json">'); var tailHtml = this.get('Tail', ns); this.model.destroy('$components'); this.model.bundle(function (err, bundle) { if (_this.model.hasErrored) return; if (err) return _this.emit('error', err); var json = stringifyBundle(bundle); _this.res.write(json); _this.res.end('</script>' + tailHtml); _this.app.emit('routeDone', _this, 'render'); }); }; PageForServer.prototype.renderStatic = function (status, ns) { if (typeof status !== 'number') { ns = status; status = null; } this.app.emit('renderStatic', this); if (status) this.res.statusCode = status; this.params = pageParams(this.req); this._setRenderParams(ns); var pageHtml = this.get('Page', ns); var tailHtml = this.get('Tail', ns); this.res.send(pageHtml + tailHtml); this.app.emit('routeDone', this, 'renderStatic'); }; return PageForServer; }(Page_1.Page)); exports.PageForServer = PageForServer; function stringifyBundle(bundle) { var json = JSON.stringify(bundle); return json.replace(/<[/!]/g, function (match) { // Replace the end tag sequence with an equivalent JSON string to make // sure the script is not prematurely closed if (match === '</') return '<\\/'; // Replace the start of an HTML comment tag sequence with an equivalent // JSON string if (match === '<!') return '<\\u0021'; throw new Error('Unexpected match when escaping JSON'); }); } // TODO: Cleanup; copied from tracks function pageParams(req) { var params = Object.create(null); Object.assign(params, { url: req.url, body: req.body, query: req.query, }); for (var key in req.params) { params[key] = req.params[key]; } return params; }