Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Commit 313dd54

Browse files
author
Fabian Wiles
committed
feat(socket-engine): introduce package
1 parent 4dd9ac3 commit 313dd54

File tree

8 files changed

+726
-796
lines changed

8 files changed

+726
-796
lines changed

modules/socket-engine/BUILD.bazel

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
load("//tools:defaults.bzl", "ts_library", "ng_module", "ng_package")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
6+
7+
ng_module(
8+
name = "socket-engine",
9+
srcs = glob([
10+
"*.ts",
11+
"src/**/*.ts",
12+
]),
13+
module_name = "@nguniversal/socket-engine",
14+
deps = [
15+
"//modules/common",
16+
],
17+
)
18+
19+
ng_package(
20+
name = "npm_package",
21+
srcs = [
22+
":package.json",
23+
],
24+
entry_point = "modules/socket-engine/index.js",
25+
readme_md = ":README.md",
26+
deps = [
27+
":socket-engine",
28+
"//modules/common",
29+
],
30+
)
31+
32+
ts_library(
33+
name = "unit_test_lib",
34+
testonly = True,
35+
srcs = glob([
36+
"spec/**/*.spec.ts",
37+
]),
38+
deps = [
39+
":socket-engine",
40+
],
41+
)
42+
43+
jasmine_node_test(
44+
name = "unit_test",
45+
srcs = [":unit_test_lib"],
46+
)

modules/socket-engine/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Angular Socket Engine
2+
3+
Framework and Platform agnostic Angular Universal rendering.
4+
5+
## Usage Server
6+
7+
`npm install @nguniversal/socket-engine @nguniversal/common --save`
8+
9+
```js
10+
const socketEngine = require('@nguniversal/socket-engine');
11+
12+
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
13+
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');
14+
15+
socketEngine.startSocketEngine(AppServerModuleNgFactory);
16+
```
17+
This will the socket engine which internally hosts a TCP Socket server.
18+
The default port is `9090` and host of `localhost`
19+
You may want to leave this as a plain `.js` file since it is so simple and to make deploying it easier, but it can be easily transpiled from Typescript.
20+
21+
## Usage Client
22+
23+
Your client can be whatever language, framework or platform you like.
24+
Aslong as it can connect to a TCP Socket (which all frameworks can) then you're good to go.
25+
26+
This example will use JS for simplicity
27+
```typescript
28+
import * as net from 'net';
29+
30+
const client = net.createConnection(9090, 'localhost', () => {
31+
const renderOptions = {id: 1, url: '/path',
32+
document: '<app-root></app-root>'} as SocketEngineRenderOptions;
33+
client.write(JSON.stringify(renderOptions));
34+
});
35+
36+
client.on('data', data => {
37+
const res = JSON.parse(data.toString()) as SocketEngineResponse;
38+
expect(res.id).toEqual(1);
39+
expect(res.html).toEqual(template);
40+
server.close();
41+
done();
42+
});
43+
```

modules/socket-engine/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
export * from './public_api';

modules/socket-engine/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@nguniversal/socket-engine",
3+
"version": "0.0.0-PLACEHOLDER",
4+
"description": "Socket Engine for running Server Angular Apps",
5+
"license": "MIT",
6+
"keywords": [
7+
"socket",
8+
"ssr",
9+
"universal"
10+
],
11+
"peerDependencies": {
12+
"@nguniversal/common": "0.0.0-PLACEHOLDER",
13+
"@angular/core": "NG_VERSION"
14+
},
15+
"ng-update": {
16+
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
17+
},
18+
"repository": {
19+
"type": "git",
20+
"url": "https://github.com/angular/universal"
21+
},
22+
"bugs": {
23+
"url": "https://github.com/angular/universal/issues"
24+
},
25+
"homepage": "https://github.com/angular/universal"
26+
}

modules/socket-engine/public_api.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
export { startSocketEngine, SocketEngineResponse, SocketEngineRenderOptions } from './src/main';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
import { ServerModule } from '@angular/platform-server';
3+
import { NgModule, Component } from '@angular/core';
4+
import 'zone.js';
5+
6+
import { BrowserModule } from '@angular/platform-browser';
7+
import { startSocketEngine, SocketEngineResponse,
8+
SocketEngineRenderOptions } from '@nguniversal/socket-engine';
9+
import * as net from 'net';
10+
11+
export function makeTestingModule(template: string, component?: any): any {
12+
@Component({
13+
selector: 'root',
14+
template: template
15+
})
16+
class MockComponent {}
17+
@NgModule({
18+
imports: [ServerModule, BrowserModule.withServerTransition({appId: 'mock'})],
19+
declarations: [component || MockComponent],
20+
bootstrap: [component || MockComponent]
21+
})
22+
class MockServerModule {}
23+
return MockServerModule;
24+
}
25+
26+
describe('test runner', () => {
27+
it('should render a basic template', async (done) => {
28+
const template = `some template: ${new Date()}`;
29+
const appModule = makeTestingModule(template);
30+
const server = await startSocketEngine(appModule);
31+
32+
const client = net.createConnection(9090, 'localhost', () => {
33+
const renderOptions = {id: 1, url: '/path',
34+
document: '<root></root>'} as SocketEngineRenderOptions;
35+
client.write(JSON.stringify(renderOptions));
36+
});
37+
38+
client.on('data', data => {
39+
const res = JSON.parse(data.toString()) as SocketEngineResponse;
40+
expect(res.id).toEqual(1);
41+
expect(res.html).toEqual(template);
42+
server.close();
43+
done();
44+
});
45+
});
46+
});

modules/socket-engine/src/main.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { ɵCommonEngine as CommonEngine,
9+
ɵRenderOptions as RenderOptions } from '@nguniversal/common';
10+
import { NgModuleFactory, Type } from '@angular/core';
11+
import * as net from 'net';
12+
13+
export interface SocketEngineServer {
14+
close: () => void;
15+
}
16+
17+
export interface SocketEngineRenderOptions extends RenderOptions {
18+
id: number;
19+
}
20+
21+
export interface SocketEngineResponse {
22+
id: number;
23+
html: string;
24+
}
25+
26+
export function startSocketEngine(
27+
moduleOrFactory: Type<{}> | NgModuleFactory<{}>,
28+
host = 'localhost',
29+
port = 9090
30+
): Promise<SocketEngineServer> {
31+
return new Promise((resolve, _reject) => {
32+
const engine = new CommonEngine(moduleOrFactory);
33+
34+
const server = net.createServer(socket => {
35+
socket.on('data', async buff => {
36+
const message = buff.toString();
37+
const renderOptions = JSON.parse(message) as SocketEngineRenderOptions;
38+
const html = await engine.render(renderOptions);
39+
socket.write(JSON.stringify({html, id: renderOptions.id} as SocketEngineResponse));
40+
});
41+
});
42+
43+
server.listen(port, host);
44+
resolve({close: () => server.close()});
45+
});
46+
}
47+

0 commit comments

Comments
 (0)