/* @flow */ const Transform = require('stream').Transform import type TemplateRenderer from './index' import type { ParsedTemplate } from './parse-template' export default class TemplateStream extends Transform { started: boolean; renderer: TemplateRenderer; template: ParsedTemplate; context: Object; inject: boolean; constructor ( renderer: TemplateRenderer, template: ParsedTemplate, context: Object ) { super() this.started = false this.renderer = renderer this.template = template this.context = context || {} this.inject = renderer.inject } _transform (data: Buffer | string, encoding: string, done: Function) { if (!this.started) { this.emit('beforeStart') this.start() } this.push(data) done() } start () { this.started = true this.push(this.template.head(this.context)) if (this.inject) { // inline server-rendered head meta information if (this.context.head) { this.push(this.context.head) } // inline preload/prefetch directives for initial/async chunks const links = this.renderer.renderResourceHints(this.context) if (links) { this.push(links) } // CSS files and inline server-rendered CSS collected by vue-style-loader const styles = this.renderer.renderStyles(this.context) if (styles) { this.push(styles) } } this.push(this.template.neck(this.context)) } _flush (done: Function) { this.emit('beforeEnd') if (this.inject) { // inline initial store state const state = this.renderer.renderState(this.context) if (state) { this.push(state) } // embed scripts needed const scripts = this.renderer.renderScripts(this.context) if (scripts) { this.push(scripts) } } this.push(this.template.tail(this.context)) done() } }