Angular universal no renderiza todo en el lado del servidor

Problema

estoy construyendo una solución con angular 4 + angular universal + knockout.
La idea es que la aplicación angular renderizará HTML para fines SEO en el lado del servidor, pero como parte del proceso de renderización, debe ser capaz de enlazar algún texto html con el modelo de vista usando knockoutjs para renderizar primero el html vinculado a knockout, luego completar la renderización del lado del servidor, y enviar el html resultante al navegador.
La razón para mezclar angular con knockout es que tenemos HTML (por ejemplo: '<span data-bind="text: test"></span>') como cadenas de terceros existentes que contienen etiquetas knockout.
Puedo usar knockout en el módulo angular y aplicar la Unión. El texto HTML muestra el contenido de las variables del modelo de vista... Sin embargo, cuando la aplicación angular se ejecuta en el lado del servidor, esta parte no se renderiza en el lado del servidor, funciona, pero se renderiza en el lado del cliente, lo que es una solución inaceptable para nosotros.
Esto es como si el motor de renderización javascript del lado del servidor no esperara a que las llamadas asincrónicas se utilizaran para aplicar la Unión knock - out antes de enviar el html renderizado final al cliente.
Rastreé el motor these steps to run Angular 4 with Universal.
Este es mi modelo de vista de eliminación simple mysample.ts:
import * as ko from 'knockout';

export interface IMySample {
    test: string;
}

export class MySample implements IMySample {
    public test: any = ko.observable("Hi, I'm a property from knockout");

    constructor(){
    }
}
Este es mi componente principal, home.component.ts, y tengo algunos html como texto que contiene enlaces knock - out que quiero renderizar en el lado del servidor.
import { Component, OnInit } from '@angular/core';
import { MySample } from '../ko/mysample';
import { KoRendererService } from '../ko-renderer.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
  providers: [KoRendererService]
})
export class HomeComponent implements OnInit {

  htmlWithKnockout: string = '<span data-bind="text: test"></span>';
  htmlAfterBinding: string = null;
  constructor(private koRendererService: KoRendererService) 
  { 
  }

  ngOnInit() {
    var mySample = new MySample();
    this.koRendererService.getHtmlRendered(this.htmlWithKnockout, mySample).then((htmlRendered: string) => {
      this.htmlAfterBinding = htmlRendered;
    });
  }
}
Su vista home.component.html debe mostrar el mismo HTML, con enlaces knock - out, pero renderizado en el servidor (sólo en el lado del cliente):
<p>This content should be part of the index page DOM</p>
<div id="ko-result" [innerHTML]="htmlAfterBinding"></div>
Este es el servicio ko-rendered.service.ts que creé para aplicar la Unión knockout. Lo puse asincrónico porque angular unviersal debe esperar a que la llamada asincrónica termine antes de que I read here renderize html en el lado del servidor.
import * as ko from 'knockout';

interface IKoRendererService {
    getHtmlRendered(htmlAsText: string, viewModel: any): Promise<string>;
}

export class KoRendererService implements IKoRendererService {
    constructor(){

    }

    getHtmlRendered(htmlAsText: string, viewModel: any): Promise<string> {
        return new Promise<string>((resolve, reject) => {
            var htmlDivElement: HTMLDivElement = document.createElement('div');
            htmlDivElement.innerHTML = htmlAsText;
            ko.applyBindings(viewModel, htmlDivElement.firstChild);
            var result = htmlDivElement.innerHTML;
            resolve(result);
        });
    }
}
Esta es la respuesta al índice. Página HTML en el navegador. Podemos ver aquí que el contenido angular se ha renderizado correctamente en el lado del servidor, pero la parte con la Unión knock - out no está en el Dom, sino que se recupera en el lado del cliente.
<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>Sample</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="styles.d41d8cd98f00b204e980.bundle.css" rel="stylesheet"><style ng-transition="carama"></style></head>
<body>
  <app-root _nghost-c0="" ng-version="4.1.3"><ul _ngcontent-c0="">
  <li _ngcontent-c0=""><a _ngcontent-c0="" routerLink="/" href="/">Home</a></li>
  <li _ngcontent-c0=""><a _ngcontent-c0="" routerLink="about" href="/about">About Us</a></li>
</ul>
<hr _ngcontent-c0="">

<h1 _ngcontent-c0="">Welcome to the server side rendering test with Angular Universal</h1>
<router-outlet _ngcontent-c0=""></router-outlet><app-home _nghost-c1=""><p _ngcontent-c1="">This content should be part of the index page DOM</p>
<div _ngcontent-c1="" id="ko-result"></div></app-home>
</app-root>
<script type="text/javascript" src="inline.77dfeeb563e4dcc7a506.bundle.js"></script><script type="text/javascript" src="polyfills.d90888e283bda7f009a0.bundle.js"></script><script type="text/javascript" src="vendor.451987311459166e7919.bundle.js"></script><script type="text/javascript" src="main.af6e993f16ecd4063c3b.bundle.js"></script>

</body></html>
Tenga en cuenta que el div con id="ko-result" está vacío. Más tarde, en el lado del cliente, el div se modifica correctamente en el Dom de la siguiente manera:
<div _ngcontent-c1="" id="ko-result"><span>Hi, I'm a property from knockout</span></div>
Pero necesito renderizar en el lado del servidor...
Cualquier ayuda será apreciada. Gracias!
Actualización 1: Este es mi paquete. Json y mis dependencias:
{
  "name": "server-side-rendering",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "prestart": "ng build --prod && ngc",
    "start": "ts-node src/server.ts"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.1.3",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/platform-server": "^4.1.3",
    "@angular/router": "^4.0.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.1.0",
    "zone.js": "^0.8.4",
    "knockout": "^3.4.2"
  },
  "devDependencies": {
    "@angular/cli": "1.0.6",
    "@angular/compiler-cli": "^4.0.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "protractor": "~5.1.0",
    "ts-node": "~2.0.0",
    "tslint": "~4.5.0",
    "typescript": "~2.2.0"
  }
}
Actualización 2: también funciona cuando se renderiza en el lado del cliente. Puedo ver el renderizado final en el navegador, pero como se esperaba, falta todo en el índice. Solicitud HTML, que más tarde será recuperada por javascript. Esta es la respuesta cuando se ejecuta la misma aplicación usando ng-serve (renderización del cliente):
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Sample</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root>Loading sample, you should not see this in client side...</app-root>
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="polyfills.bundle.js"></script><script type="text/javascript" src="styles.bundle.js"></script><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
</html>
Actualización 3: He leído here, y para que la aplicación angular sea compatible con el mundo, no deberíamos operar Dom directamente. Me pregunto si el hecho de que esté usando document para crear el elemento html necesario para knock - out applyBindings en mi ko-rendered.service.ts hace que el universo angular ignore este renderizado del lado del servidor, pero estoy tratando de crear el elemento Dom usando Renderer2 (por ejemplo: import { Component, OnInit, Renderer2 } from '@angular/core';), pero eso no resuelve el problema:
var htmlDivElement: any = renderer2.createElement('div')
            // var htmlDivElement: HTMLDivElement = document.createElement('div');
Actualización 4: durante la invocación ko.applyBindings, vi el siguiente error en el entorno del nodo del lado del servidor, por lo que sospecho que todo el método es problemático porque knockout js no está realmente diseñado para ser ejecutado en el lado del servidor en un entorno sin navegador. Es demasiado dependiente del Dom, como dice Angular Universal good practices:

Don't use any of the browser types provided in the global namespace such as navigator or document. Anything outside of Angular will not be detected when serializing your application into html


El siguiente es el error que causó que angular universal dejara de renderizar en el lado del servidor y pasara al navegador:
listening on http://localhost:4000!
ERROR { Error: Uncaught (in promise): TypeError: Cannot read property 'body' of undefined
TypeError: Cannot read property 'body' of undefined
    at Object.ko.applyBindings 

(C:\Dev\node_modules\knockout\build\output\knockout-latest.debug.js:3442:47)
..
ERROR { Error: Uncaught (in promise): TypeError: this.html.charCodeAt is not a function
TypeError: this.html.charCodeAt is not a function

Solución simple

knockout obviamente no es adecuado para el renderizado angular en el lado del servidor. Knockout entiende que hay un DOM, pero no hay tal cosa.

Respect the Angular rule: never use browser-specific APIs (like the DOM) directly. If you do so, your module won’t be compatible with Universal server rendering and other Angular advanced options