@dooboostore/simple-boot-http-server-ssr 1.0.14 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +131 -0
- package/dist/cjs/SimpleBootHttpSSRFactory.js.map +1 -1
- package/dist/cjs/SimpleBootHttpSSRServer.js +1 -0
- package/dist/cjs/SimpleBootHttpSSRServer.js.map +2 -2
- package/dist/cjs/bundle-entry.js +0 -2
- package/dist/cjs/bundle-entry.js.map +2 -2
- package/dist/cjs/decorators/LoadAroundBefore.js +2 -2
- package/dist/cjs/decorators/LoadAroundBefore.js.map +2 -2
- package/dist/cjs/filters/SSRDomParserFilter.js +54 -89
- package/dist/cjs/filters/SSRDomParserFilter.js.map +2 -2
- package/dist/cjs/filters/SSRFilter.js +10 -14
- package/dist/cjs/filters/SSRFilter.js.map +2 -2
- package/dist/cjs/filters/SSRLinkDomDomFilter.js +10 -14
- package/dist/cjs/filters/SSRLinkDomDomFilter.js.map +2 -2
- package/dist/cjs/filters/SSRSimpleWebComponentFilter.js +93 -0
- package/dist/cjs/filters/SSRSimpleWebComponentFilter.js.map +7 -0
- package/dist/cjs/filters/SSRWorker.js +2 -2
- package/dist/cjs/filters/SSRWorker.js.map +2 -2
- package/dist/cjs/filters/index.js +2 -2
- package/dist/cjs/filters/index.js.map +2 -2
- package/dist/cjs/index.js +18 -8
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/initializers/DomParserInitializer.js +5 -2
- package/dist/cjs/initializers/DomParserInitializer.js.map +2 -2
- package/dist/cjs/proxy/SSRDomParserFilterDataHydrationProxy.js +92 -0
- package/dist/cjs/proxy/SSRDomParserFilterDataHydrationProxy.js.map +7 -0
- package/dist/cjs/proxy/index.js +2 -8
- package/dist/cjs/proxy/index.js.map +2 -2
- package/dist/esm/SimpleBootHttpSSRFactory.js.map +1 -1
- package/dist/esm/SimpleBootHttpSSRServer.js +1 -0
- package/dist/esm/SimpleBootHttpSSRServer.js.map +2 -2
- package/dist/esm/bundle-entry.js +0 -1
- package/dist/esm/bundle-entry.js.map +2 -2
- package/dist/esm/decorators/LoadAroundBefore.js +1 -1
- package/dist/esm/decorators/LoadAroundBefore.js.map +1 -1
- package/dist/esm/filters/SSRDomParserFilter.js +52 -87
- package/dist/esm/filters/SSRDomParserFilter.js.map +2 -2
- package/dist/esm/filters/SSRFilter.js +7 -11
- package/dist/esm/filters/SSRFilter.js.map +2 -2
- package/dist/esm/filters/SSRLinkDomDomFilter.js +7 -11
- package/dist/esm/filters/SSRLinkDomDomFilter.js.map +2 -2
- package/dist/esm/filters/SSRSimpleWebComponentFilter.js +70 -0
- package/dist/esm/filters/SSRSimpleWebComponentFilter.js.map +7 -0
- package/dist/esm/filters/SSRWorker.js +1 -1
- package/dist/esm/filters/SSRWorker.js.map +2 -2
- package/dist/esm/filters/index.js +1 -1
- package/dist/esm/filters/index.js.map +1 -1
- package/dist/esm/index.js +7 -4
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/initializers/DomParserInitializer.js +6 -3
- package/dist/esm/initializers/DomParserInitializer.js.map +2 -2
- package/dist/esm/proxy/SSRDomParserFilterDataHydrationProxy.js +69 -0
- package/dist/esm/proxy/SSRDomParserFilterDataHydrationProxy.js.map +7 -0
- package/dist/esm/proxy/index.js +1 -4
- package/dist/esm/proxy/index.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-boot-http-server-ssr.esm.js +20723 -8294
- package/dist/esm-bundle/dooboostore-simple-boot-http-server-ssr.esm.js.map +4 -4
- package/dist/types/SimpleBootHttpSSRFactory.d.ts +1 -1
- package/dist/types/SimpleBootHttpSSRFactory.d.ts.map +1 -1
- package/dist/types/SimpleBootHttpSSRServer.d.ts +3 -2
- package/dist/types/SimpleBootHttpSSRServer.d.ts.map +1 -1
- package/dist/types/bundle-entry.d.ts +0 -1
- package/dist/types/bundle-entry.d.ts.map +1 -1
- package/dist/types/filters/SSRDomParserFilter.d.ts +10 -16
- package/dist/types/filters/SSRDomParserFilter.d.ts.map +1 -1
- package/dist/types/filters/SSRFilter.d.ts +1 -1
- package/dist/types/filters/SSRFilter.d.ts.map +1 -1
- package/dist/types/filters/SSRLinkDomDomFilter.d.ts +1 -1
- package/dist/types/filters/SSRLinkDomDomFilter.d.ts.map +1 -1
- package/dist/types/filters/SSRSimpleWebComponentFilter.d.ts +37 -0
- package/dist/types/filters/SSRSimpleWebComponentFilter.d.ts.map +1 -0
- package/dist/types/filters/SSRWorker.d.ts +1 -1
- package/dist/types/filters/SSRWorker.d.ts.map +1 -1
- package/dist/types/filters/index.d.ts +1 -1
- package/dist/types/filters/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +7 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/initializers/DomParserInitializer.d.ts +2 -0
- package/dist/types/initializers/DomParserInitializer.d.ts.map +1 -1
- package/dist/types/proxy/SSRDomParserFilterDataHydrationProxy.d.ts +7 -0
- package/dist/types/proxy/SSRDomParserFilterDataHydrationProxy.d.ts.map +1 -0
- package/dist/types/proxy/index.d.ts +1 -4
- package/dist/types/proxy/index.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-boot-http-server-ssr.umd.js +20726 -8301
- package/dist/umd-bundle/dooboostore-simple-boot-http-server-ssr.umd.js.map +4 -4
- package/package.json +16 -10
- package/src/SimpleBootHttpSSRFactory.ts +1 -1
- package/src/SimpleBootHttpSSRServer.ts +5 -3
- package/src/bundle-entry.ts +0 -1
- package/src/decorators/LoadAroundBefore.ts +1 -1
- package/src/filters/SSRDomParserFilter.ts +111 -124
- package/src/filters/SSRFilter.ts +7 -12
- package/src/filters/SSRLinkDomDomFilter.ts +7 -12
- package/src/filters/SSRSimpleWebComponentFilter.ts +103 -0
- package/src/filters/SSRWorker.ts +1 -2
- package/src/filters/index.ts +1 -1
- package/src/index.ts +7 -9
- package/src/initializers/DomParserInitializer.ts +9 -2
- package/src/proxy/SSRDomParserFilterDataHydrationProxy.ts +63 -0
- package/src/proxy/index.ts +1 -4
- package/tsconfig.json +1 -0
- package/dist/cjs/codes/HttpHeaders.js +0 -41
- package/dist/cjs/codes/HttpHeaders.js.map +0 -7
- package/dist/cjs/codes/Mimes.js +0 -33
- package/dist/cjs/codes/Mimes.js.map +0 -7
- package/dist/cjs/codes/index.js +0 -24
- package/dist/cjs/codes/index.js.map +0 -7
- package/dist/cjs/filters/IntentSchemeFilter.js +0 -92
- package/dist/cjs/filters/IntentSchemeFilter.js.map +0 -7
- package/dist/cjs/proxy/IntentSchemeFrontProxy.js +0 -87
- package/dist/cjs/proxy/IntentSchemeFrontProxy.js.map +0 -7
- package/dist/cjs/proxy/IntentSchemeServerProxy.js +0 -67
- package/dist/cjs/proxy/IntentSchemeServerProxy.js.map +0 -7
- package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +0 -138
- package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +0 -7
- package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js +0 -35
- package/dist/cjs/proxy/SymbolIntentApiServiceProxyBase.js.map +0 -7
- package/dist/esm/codes/HttpHeaders.js +0 -17
- package/dist/esm/codes/HttpHeaders.js.map +0 -7
- package/dist/esm/codes/Mimes.js +0 -10
- package/dist/esm/codes/Mimes.js.map +0 -7
- package/dist/esm/codes/index.js +0 -3
- package/dist/esm/codes/index.js.map +0 -7
- package/dist/esm/filters/IntentSchemeFilter.js +0 -69
- package/dist/esm/filters/IntentSchemeFilter.js.map +0 -7
- package/dist/esm/proxy/IntentSchemeFrontProxy.js +0 -64
- package/dist/esm/proxy/IntentSchemeFrontProxy.js.map +0 -7
- package/dist/esm/proxy/IntentSchemeServerProxy.js +0 -44
- package/dist/esm/proxy/IntentSchemeServerProxy.js.map +0 -7
- package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +0 -115
- package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +0 -7
- package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js +0 -12
- package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.js.map +0 -7
- package/dist/types/codes/HttpHeaders.d.ts +0 -45
- package/dist/types/codes/HttpHeaders.d.ts.map +0 -1
- package/dist/types/codes/Mimes.d.ts +0 -31
- package/dist/types/codes/Mimes.d.ts.map +0 -1
- package/dist/types/codes/index.d.ts +0 -3
- package/dist/types/codes/index.d.ts.map +0 -1
- package/dist/types/filters/IntentSchemeFilter.d.ts +0 -20
- package/dist/types/filters/IntentSchemeFilter.d.ts.map +0 -1
- package/dist/types/proxy/IntentSchemeFrontProxy.d.ts +0 -4
- package/dist/types/proxy/IntentSchemeFrontProxy.d.ts.map +0 -1
- package/dist/types/proxy/IntentSchemeServerProxy.d.ts +0 -4
- package/dist/types/proxy/IntentSchemeServerProxy.d.ts.map +0 -1
- package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts +0 -18
- package/dist/types/proxy/SymbolIntentApiServiceProxy.d.ts.map +0 -1
- package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts +0 -5
- package/dist/types/proxy/SymbolIntentApiServiceProxyBase.d.ts.map +0 -1
- package/src/codes/HttpHeaders.ts +0 -17
- package/src/codes/Mimes.ts +0 -6
- package/src/codes/index.ts +0 -2
- package/src/filters/IntentSchemeFilter.ts +0 -69
- package/src/proxy/IntentSchemeFrontProxy.ts +0 -67
- package/src/proxy/IntentSchemeServerProxy.ts +0 -35
- package/src/proxy/SymbolIntentApiServiceProxy.ts +0 -115
- package/src/proxy/SymbolIntentApiServiceProxyBase.ts +0 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dooboostore/simple-boot-http-server-ssr",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"import": "./dist/esm/index.js",
|
|
39
39
|
"require": "./dist/cjs/index.js"
|
|
40
40
|
},
|
|
41
|
+
"./bundle-entry": {
|
|
42
|
+
"types": "./dist/types/bundle-entry.d.ts",
|
|
43
|
+
"import": "./dist/esm/bundle-entry.js",
|
|
44
|
+
"require": "./dist/cjs/bundle-entry.js"
|
|
45
|
+
},
|
|
41
46
|
"./*": {
|
|
42
47
|
"types": "./dist/types/*.d.ts",
|
|
43
48
|
"import": "./dist/esm/*.js",
|
|
@@ -82,18 +87,19 @@
|
|
|
82
87
|
"@types/node-gzip": "^1.1.0",
|
|
83
88
|
"esbuild-plugin-tsc": "^0.5.0",
|
|
84
89
|
"esbuild": "^0.23.0",
|
|
85
|
-
"@dooboostore/core-node": "1.0.
|
|
86
|
-
"@dooboostore/core
|
|
87
|
-
"@dooboostore/
|
|
88
|
-
"@dooboostore/simple-
|
|
89
|
-
"@dooboostore/
|
|
90
|
-
"@dooboostore/simple-boot-
|
|
91
|
-
"@dooboostore/
|
|
90
|
+
"@dooboostore/core-node": "1.0.12",
|
|
91
|
+
"@dooboostore/core": "1.0.30",
|
|
92
|
+
"@dooboostore/core-web": "1.0.10",
|
|
93
|
+
"@dooboostore/simple-web-component": "1.0.20",
|
|
94
|
+
"@dooboostore/simple-boot-front": "1.0.131",
|
|
95
|
+
"@dooboostore/simple-boot-http-server": "1.0.24",
|
|
96
|
+
"@dooboostore/dom-parser": "1.0.5",
|
|
97
|
+
"@dooboostore/simple-boot": "1.0.54",
|
|
98
|
+
"@dooboostore/dom-render": "1.0.113"
|
|
92
99
|
},
|
|
93
100
|
"dependencies": {
|
|
94
101
|
"jsdom": "^26.0.0",
|
|
95
|
-
"linkedom": "0.18.12"
|
|
96
|
-
"@dooboostore/dom-parser": "1.0.1"
|
|
102
|
+
"linkedom": "0.18.12"
|
|
97
103
|
},
|
|
98
104
|
"scripts": {
|
|
99
105
|
"clean": "rm -rf dist",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SimpleBootFront } from '@dooboostore/simple-boot-front/SimpleBootFront';
|
|
2
|
-
import { ConstructorType } from '@dooboostore/core
|
|
2
|
+
import { ConstructorType } from '@dooboostore/core';
|
|
3
3
|
import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
|
|
4
4
|
export abstract class SimpleBootHttpSSRFactory {
|
|
5
5
|
public abstract factory(simFrontOption: SimFrontOption, using: (ConstructorType<any> | Function)[], domExcludes: ConstructorType<any>[]): Promise<SimpleBootFront> ;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
|
|
2
2
|
// import { SimstanceManager } from '@dooboostore/simple-boot/simstance/SimstanceManager';
|
|
3
3
|
import { HttpSSRServerOption } from './option/HttpSSRServerOption';
|
|
4
|
-
import { ConstructorType } from '@dooboostore/core
|
|
4
|
+
import { ConstructorType } from '@dooboostore/core';
|
|
5
|
+
import {SimConfig} from "@dooboostore/simple-boot/decorators/SimDecorator";
|
|
5
6
|
|
|
6
7
|
export class SimpleBootHttpSSRServer extends SimpleBootHttpServer {
|
|
7
8
|
constructor(option?: HttpSSRServerOption) {
|
|
8
9
|
super(option)
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
run(otherInstanceSim?: Map<ConstructorType<any
|
|
12
|
-
const oi = new Map<ConstructorType<any
|
|
12
|
+
run(otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | Symbol, any>) {
|
|
13
|
+
const oi = new Map<ConstructorType<any> | Function | SimConfig | Symbol, any>();
|
|
14
|
+
oi.set(SimpleBootHttpSSRServer, this);
|
|
13
15
|
otherInstanceSim?.forEach((value, key) => oi.set(key, value));
|
|
14
16
|
return super.run(oi);
|
|
15
17
|
}
|
package/src/bundle-entry.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getSim } from '@dooboostore/simple-boot/decorators/SimDecorator';
|
|
2
2
|
import { AroundForceReturn } from '@dooboostore/simple-boot/decorators/aop/AOPDecorator';
|
|
3
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
3
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
4
4
|
|
|
5
5
|
export const LoadAroundBefore = (obj: any, propertyKey: string, args: any[]) => {
|
|
6
6
|
const simstanceManager = obj._SimpleBoot_simstanceManager;
|
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
import { RequestResponse } from '@dooboostore/simple-boot-http-server/models/RequestResponse';
|
|
2
2
|
import { HttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
|
|
3
3
|
import { SimpleBootHttpSSRFactory } from '../SimpleBootHttpSSRFactory';
|
|
4
|
-
import { ConstructorType } from '@dooboostore/core
|
|
4
|
+
import { ConstructorType, AsyncBlockingQueue, RandomUtils, MessageOperator, MessageInternal, Promises } from '@dooboostore/core';
|
|
5
5
|
import { Filter } from '@dooboostore/simple-boot-http-server/filters/Filter';
|
|
6
6
|
import { Mimes } from '@dooboostore/simple-boot-http-server/codes/Mimes';
|
|
7
7
|
import { HttpStatus } from '@dooboostore/simple-boot-http-server/codes/HttpStatus';
|
|
8
8
|
import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
|
|
9
9
|
import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
|
|
10
10
|
import { SimpleBootFront } from '@dooboostore/simple-boot-front/SimpleBootFront';
|
|
11
|
-
import { AsyncBlockingQueue } from '@dooboostore/core/queues/AsyncBlockingQueue';
|
|
12
|
-
import { RandomUtils } from '@dooboostore/core/random/RandomUtils';
|
|
13
11
|
import * as JSDOM from 'jsdom';
|
|
14
12
|
import { NotFoundError } from '@dooboostore/simple-boot-http-server/errors/NotFoundError';
|
|
15
|
-
import { DomRenderProxy } from '@dooboostore/dom-render
|
|
16
|
-
import { filter } from '@dooboostore/core/message/operators/filter';
|
|
17
|
-
import { first } from '@dooboostore/core/message/operators/first';
|
|
18
|
-
import { delay } from '@dooboostore/core/message/operators/delay';
|
|
19
|
-
import { firstValueFrom } from '@dooboostore/core/message/internal/firstValueFrom';
|
|
13
|
+
import { DomRenderProxy } from '@dooboostore/dom-render';
|
|
20
14
|
import { parseHTML } from 'linkedom';
|
|
21
|
-
import {Promises} from '@dooboostore/core/promise/Promises';
|
|
22
15
|
import { DomParserInitializer } from '../initializers/DomParserInitializer';
|
|
16
|
+
import { JsdomInitializer } from '../initializers';
|
|
17
|
+
import { SimConfig } from '@dooboostore/simple-boot/decorators/SimDecorator';
|
|
23
18
|
|
|
24
19
|
export type FactoryAndParams = {
|
|
25
20
|
frontDistPath: string;
|
|
26
21
|
frontDistIndexFileName?: string;
|
|
27
22
|
factorySimFrontOption: (window: any) => SimFrontOption;
|
|
28
23
|
factory: SimpleBootHttpSSRFactory;
|
|
29
|
-
poolOption: {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
24
|
+
// poolOption: {
|
|
25
|
+
// max: number;
|
|
26
|
+
// min: number;
|
|
27
|
+
// clearIntervalTime?: number;
|
|
28
|
+
// };
|
|
34
29
|
using: ConstructorType<any>[];
|
|
35
30
|
domExcludes?: ConstructorType<any>[];
|
|
36
31
|
ssrExcludeFilter?: (rr: RequestResponse) => boolean;
|
|
@@ -40,150 +35,152 @@ export type FactoryAndParams = {
|
|
|
40
35
|
};
|
|
41
36
|
|
|
42
37
|
export class SSRDomParserFilter implements Filter {
|
|
43
|
-
private simpleBootFrontPool: SimpleBootFront[] = [];
|
|
44
|
-
private simpleBootFrontQueue = new AsyncBlockingQueue<SimpleBootFront>();
|
|
38
|
+
// private simpleBootFrontPool: SimpleBootFront[] = [];
|
|
39
|
+
// private simpleBootFrontQueue = new AsyncBlockingQueue<SimpleBootFront>();
|
|
45
40
|
// private indexHTML: string;
|
|
46
41
|
private welcomUrl = 'http://localhost';
|
|
47
|
-
private poolGeneration = 0;
|
|
48
|
-
private intervalId?: NodeJS.Timeout;
|
|
42
|
+
// private poolGeneration = 0;
|
|
43
|
+
// private intervalId?: NodeJS.Timeout;
|
|
49
44
|
|
|
50
45
|
constructor(
|
|
51
46
|
public config: FactoryAndParams,
|
|
52
|
-
public otherInstanceSim?: Map<ConstructorType<any
|
|
47
|
+
public otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | Symbol, any>
|
|
53
48
|
) {
|
|
54
49
|
config.frontDistIndexFileName = config.frontDistIndexFileName || 'index.html';
|
|
55
50
|
// this.indexHTML = JsdomInitializer.loadFile(this.config.frontDistPath, config.frontDistIndexFileName);
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
async onInit(app: SimpleBootHttpServer) {
|
|
59
|
-
for (let i = 0; i < this.config.poolOption.min; i++) {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
54
|
+
// for (let i = 0; i < this.config.poolOption.min; i++) {
|
|
55
|
+
// await this.pushQueue();
|
|
56
|
+
// }
|
|
57
|
+
// if (this.config.poolOption.clearIntervalTime && this.config.poolOption.clearIntervalTime > 0) {
|
|
58
|
+
// this.intervalId = setInterval(() => {
|
|
59
|
+
// this.poolGeneration++;
|
|
60
|
+
// }, this.config.poolOption.clearIntervalTime);
|
|
61
|
+
// }
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
async onDestroy() {
|
|
71
|
-
if (this.intervalId) {
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
// this.simpleBootFrontQueue.clear();
|
|
75
|
-
this.simpleBootFrontPool.forEach(front => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
// if (this.intervalId) {
|
|
66
|
+
// clearInterval(this.intervalId);
|
|
67
|
+
// }
|
|
68
|
+
// // this.simpleBootFrontQueue.clear();
|
|
69
|
+
// this.simpleBootFrontPool.forEach(front => {
|
|
70
|
+
// // JSDOM도 정리 (하위 호환성)
|
|
71
|
+
// (front as any).jsdom?.window.close();
|
|
72
|
+
// // Window close - 이것만으로 WindowBase.close()가 호출되어 메모리 정리됨
|
|
73
|
+
// (front.option.window as any)?.close?.();
|
|
74
|
+
// });
|
|
75
|
+
// this.simpleBootFrontPool = [];
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
async makePage() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
async makePage(url = this.welcomUrl) {
|
|
79
|
+
const domParserInitializer = new DomParserInitializer(this.config.frontDistPath, this.config.frontDistIndexFileName || 'index.html', { url: url });
|
|
80
|
+
const window = await domParserInitializer.run();
|
|
81
|
+
// window.document.querySelector('#app').setAttribute(('vvv'),'zzz')
|
|
82
|
+
// console.log('vvv', window.document.querySelector('#app'))
|
|
83
|
+
// console.log('------', window.document.documentElement.outerHTML);
|
|
84
|
+
return { window, domParserInitializer };
|
|
88
85
|
// const jsdom = await new JsdomInitializer(
|
|
89
86
|
// this.config.frontDistPath,
|
|
90
87
|
// this.config.frontDistIndexFileName || 'index.html',
|
|
91
88
|
// { url: this.welcomUrl }
|
|
92
89
|
// ).run();
|
|
90
|
+
// return { window: jsdom.window as any, domParserInitializer: {destroy: () => {jsdom.window.close()}} };
|
|
93
91
|
// return jsdom;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
async makeFront(window: Window) {
|
|
94
|
+
async makeFront(window: Window, otherInstanceSim?: Map<Function | ConstructorType<any> | SimConfig | Symbol, any>) {
|
|
97
95
|
const name = RandomUtils.uuid();
|
|
98
96
|
(window as any).ssrUse = false;
|
|
99
97
|
const option = this.config.factorySimFrontOption(DomRenderProxy.final(window));
|
|
100
|
-
const
|
|
101
|
-
simpleBootFront.
|
|
102
|
-
|
|
98
|
+
const domExcludes = [RequestResponse, ...(this.config.domExcludes || [])];
|
|
99
|
+
const simpleBootFront = await this.config.factory.create(option, this.config.using, domExcludes);
|
|
100
|
+
otherInstanceSim ??= new Map<Function | ConstructorType<any> | SimConfig | Symbol, any>();
|
|
101
|
+
this.otherInstanceSim?.forEach((v, k) => otherInstanceSim!.set(k, v));
|
|
102
|
+
|
|
103
|
+
simpleBootFront.run(otherInstanceSim);
|
|
104
|
+
// (simpleBootFront as any).generation = this.poolGeneration;
|
|
103
105
|
return simpleBootFront;
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
enqueueFrontApp(simpleBootFront: SimpleBootFront) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
108
|
+
// enqueueFrontApp(simpleBootFront: SimpleBootFront) {
|
|
109
|
+
// // this.simpleBootFrontPool.set(simpleBootFront.option.name!, simpleBootFront);
|
|
110
|
+
// this.simpleBootFrontPool.push(simpleBootFront);
|
|
111
|
+
// this.simpleBootFrontQueue.enqueue(simpleBootFront);
|
|
112
|
+
// }
|
|
113
|
+
//
|
|
114
|
+
// async pushQueue() {
|
|
115
|
+
// if (this.simpleBootFrontPool.length < this.config.poolOption.max) {
|
|
116
|
+
// this.enqueueFrontApp(await this.makeFront(await this.makePage()));
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
116
119
|
|
|
117
120
|
async proceedBefore({ rr, app }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
|
|
118
121
|
if (this.config.ssrExcludeFilter?.(rr)) {
|
|
119
122
|
return false;
|
|
120
123
|
}
|
|
121
124
|
if (rr.reqHasAcceptHeader(Mimes.TextHtml) || rr.reqHasAcceptHeader(Mimes.All)) {
|
|
122
|
-
if (this.simpleBootFrontQueue.isEmpty()) {
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
const simpleBootFront = await this.simpleBootFrontQueue.dequeue();
|
|
125
|
+
// if (this.simpleBootFrontQueue.isEmpty()) {
|
|
126
|
+
// await this.pushQueue();
|
|
127
|
+
// }
|
|
128
|
+
// const simpleBootFront = await this.simpleBootFrontQueue.dequeue();
|
|
129
|
+
const url = rr.reqUrlObj({ host: 'localhost' });
|
|
130
|
+
const targetUrl = url.toString() ?? this.welcomUrl;
|
|
131
|
+
const { window, domParserInitializer } = await this.makePage(targetUrl);
|
|
132
|
+
const otherSim = new Map<Function | ConstructorType<any> | SimConfig | Symbol, any>();
|
|
133
|
+
otherSim.set(RequestResponse, rr);
|
|
134
|
+
const simpleBootFront = await this.makeFront(window, otherSim);
|
|
126
135
|
try {
|
|
127
136
|
(simpleBootFront.option.window as any).ssrUse = true;
|
|
128
|
-
|
|
129
|
-
const url = rr.reqUrlObj({ host: 'localhost' });
|
|
137
|
+
// console.log(simpleBootFront.routing)
|
|
130
138
|
if (this.config.simpleBootFront?.notFoundError) {
|
|
131
139
|
// intent router check first
|
|
132
|
-
const intent = await simpleBootFront.
|
|
140
|
+
const intent = await simpleBootFront.routingRouterModule(url.pathname);
|
|
133
141
|
// route를 못찾은상태에서 router path까지 안맞으면 404 처리한다. route랑 router랑 다르니깐 헛갈리지말도록
|
|
134
142
|
if (intent.module === undefined && !intent.getRouterPathData(rr.reqUrlPathName)) {
|
|
135
143
|
throw new NotFoundError({ message: `Not Found: ${rr.reqUrlPathName}` });
|
|
136
144
|
}
|
|
137
145
|
}
|
|
138
146
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// simpleBootFront.routingSubjectObservable.subscribe(it=>{
|
|
148
|
-
// console.log('zzzzzzzzzzzzzzzzzzz', it);
|
|
149
|
-
// if (it.triggerPoint==='end') {
|
|
150
|
-
// console.log('zzz@@', it.routerModule.intent);
|
|
151
|
-
// }
|
|
152
|
-
// })
|
|
153
|
-
|
|
154
|
-
const data = await firstValueFrom(
|
|
155
|
-
simpleBootFront.routingSubjectObservable.pipe(
|
|
156
|
-
filter(
|
|
157
|
-
(it) =>
|
|
158
|
-
it.triggerPoint === 'end' &&
|
|
159
|
-
typeof it.routerModule.intent.uri === 'string' &&
|
|
160
|
-
targetUrl.endsWith(it.routerModule.intent.uri)
|
|
161
|
-
),
|
|
147
|
+
const data = await MessageInternal.firstValueFrom(
|
|
148
|
+
simpleBootFront.routingObservable.pipe(
|
|
149
|
+
MessageOperator.filter(it => {
|
|
150
|
+
|
|
151
|
+
const sw = it.triggerPoint === 'end' && typeof it.routerModule.intent.uri === 'string' && targetUrl.endsWith(it.routerModule.intent.uri);
|
|
152
|
+
return sw;
|
|
153
|
+
}),
|
|
162
154
|
// delay(1000),
|
|
163
|
-
first()
|
|
155
|
+
MessageOperator.first()
|
|
164
156
|
)
|
|
165
157
|
);
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
|
|
159
|
+
// [아키텍트님의 정석] 하이드레이션 데이터를 가상 윈도우의 body에 script 태그로 박제
|
|
160
|
+
// @ts-ignore: writeDataHydration is part of the 정석
|
|
161
|
+
simpleBootFront.writeDataHydration();
|
|
162
|
+
simpleBootFront.clearDataHydration();
|
|
163
|
+
|
|
168
164
|
const html = this.makeHTML(simpleBootFront);
|
|
169
|
-
// console.log('---------',html);
|
|
170
165
|
await this.writeOkHtmlAndEnd({ rr }, html);
|
|
171
166
|
} finally {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
this.pushQueue();
|
|
183
|
-
} else {
|
|
184
|
-
// Current instance, return to queue
|
|
185
|
-
this.simpleBootFrontQueue.enqueue(simpleBootFront);
|
|
167
|
+
try {
|
|
168
|
+
(simpleBootFront.option.window as any).ssrUse = false;
|
|
169
|
+
window.close();
|
|
170
|
+
simpleBootFront.onDestroy();
|
|
171
|
+
|
|
172
|
+
// window.close()만 호출하면 WindowBase.close()가 실행되어 메모리 정리됨
|
|
173
|
+
(simpleBootFront.option.window as any)?.close?.();
|
|
174
|
+
domParserInitializer.destroy();
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.log('eeeeee', e);
|
|
186
177
|
}
|
|
178
|
+
|
|
179
|
+
// const index = this.simpleBootPool.indexOf(simpleBootFront);
|
|
180
|
+
// if (index > -1) {
|
|
181
|
+
// this.simpleBootPool.splice(index, 1);
|
|
182
|
+
// }
|
|
183
|
+
// this.pushQueue();
|
|
187
184
|
}
|
|
188
185
|
return false;
|
|
189
186
|
} else {
|
|
@@ -192,7 +189,7 @@ export class SSRDomParserFilter implements Filter {
|
|
|
192
189
|
}
|
|
193
190
|
|
|
194
191
|
makeHTML(simpleBootFront: SimpleBootFront) {
|
|
195
|
-
(simpleBootFront.option.window as any).document.querySelectorAll('*').forEach((el:HTMLElement
|
|
192
|
+
(simpleBootFront.option.window as any).document.querySelectorAll('*').forEach((el: HTMLElement) => {
|
|
196
193
|
Array.from(el.attributes).forEach(attr => {
|
|
197
194
|
if (/^dr-/.test(attr.name) || /^domstyle/.test(attr.name) || /this-path/.test(attr.name)) {
|
|
198
195
|
el.removeAttribute(attr.name);
|
|
@@ -200,27 +197,17 @@ export class SSRDomParserFilter implements Filter {
|
|
|
200
197
|
});
|
|
201
198
|
});
|
|
202
199
|
let html = simpleBootFront.option.window.document.documentElement.outerHTML;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
html = html.replace(/\$\{[\s\S]*?\}\$/g, '');
|
|
207
|
-
const serverSideData = (simpleBootFront.option.window as any).server_side_data;
|
|
208
|
-
if (serverSideData) {
|
|
209
|
-
const data = Object.entries(serverSideData)
|
|
210
|
-
.map(([k, v]) => {
|
|
211
|
-
if (typeof v === 'string') {
|
|
212
|
-
return `window.server_side_data.${k} = ${v}`;
|
|
213
|
-
} else {
|
|
214
|
-
return `window.server_side_data.${k} = ${JSON.stringify(v)}`;
|
|
215
|
-
}
|
|
216
|
-
})
|
|
217
|
-
.join(';');
|
|
218
|
-
if (data) {
|
|
219
|
-
html = html.replace('</head>', `<script> window.server_side_data={}; ${data}; </script></head>`);
|
|
220
|
-
}
|
|
200
|
+
if (!/^<!DOCTYPE html>/i.test(html)) {
|
|
201
|
+
html = '<!DOCTYPE html>' + html;
|
|
221
202
|
}
|
|
203
|
+
html = html.replace(/\$\{[\s\S]*?\}\$/g, '');
|
|
204
|
+
|
|
205
|
+
// [아키텍트님의 정석]
|
|
206
|
+
// body에 직접 append된 script tag가 outerHTML에 이미 포함되어 있으므로 추가 조작은 불필요합니다.
|
|
207
|
+
|
|
222
208
|
return html;
|
|
223
209
|
}
|
|
210
|
+
|
|
224
211
|
async writeOkHtmlAndEnd({ rr, status = HttpStatus.Ok }: { rr: RequestResponse; status?: HttpStatus }, html: string) {
|
|
225
212
|
rr.resStatusCode(status);
|
|
226
213
|
rr.resSetHeader(HttpHeaders.ContentType, Mimes.TextHtml);
|
package/src/filters/SSRFilter.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequestResponse } from '@dooboostore/simple-boot-http-server/models/RequestResponse';
|
|
2
2
|
import { HttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
|
|
3
3
|
import { SimpleBootHttpSSRFactory } from '../SimpleBootHttpSSRFactory';
|
|
4
|
-
import { ConstructorType } from '@dooboostore/core
|
|
4
|
+
import { ConstructorType, AsyncBlockingQueue, RandomUtils, MessageOperator, MessageInternal } from '@dooboostore/core';
|
|
5
5
|
import { JsdomInitializer } from '../initializers/JsdomInitializer';
|
|
6
6
|
import { Filter } from '@dooboostore/simple-boot-http-server/filters/Filter';
|
|
7
7
|
import { Mimes } from '@dooboostore/simple-boot-http-server/codes/Mimes';
|
|
@@ -9,14 +9,9 @@ import { HttpStatus } from '@dooboostore/simple-boot-http-server/codes/HttpStatu
|
|
|
9
9
|
import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
|
|
10
10
|
import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
|
|
11
11
|
import { SimpleBootFront } from '@dooboostore/simple-boot-front/SimpleBootFront';
|
|
12
|
-
import { AsyncBlockingQueue } from '@dooboostore/core/queues/AsyncBlockingQueue';
|
|
13
|
-
import { RandomUtils } from '@dooboostore/core/random/RandomUtils';
|
|
14
12
|
import * as JSDOM from 'jsdom';
|
|
15
13
|
import { NotFoundError } from '@dooboostore/simple-boot-http-server/errors/NotFoundError';
|
|
16
|
-
import { DomRenderProxy } from '@dooboostore/dom-render
|
|
17
|
-
import { filter } from '@dooboostore/core/message/operators/filter';
|
|
18
|
-
import { first } from '@dooboostore/core/message/operators/first';
|
|
19
|
-
import { firstValueFrom } from '@dooboostore/core/message/internal/firstValueFrom';
|
|
14
|
+
import { DomRenderProxy } from '@dooboostore/dom-render';
|
|
20
15
|
|
|
21
16
|
export type FactoryAndParams = {
|
|
22
17
|
frontDistPath: string;
|
|
@@ -140,7 +135,7 @@ export class SSRFilter implements Filter {
|
|
|
140
135
|
const url = rr.reqUrlObj({ host: 'localhost' });
|
|
141
136
|
if (this.config.simpleBootFront?.notFoundError) {
|
|
142
137
|
// intent router check first
|
|
143
|
-
const intent = await simpleBootFront.
|
|
138
|
+
const intent = await simpleBootFront.routingRouterModule(url.pathname);
|
|
144
139
|
// route를 못찾은상태에서 router path까지 안맞으면 404 처리한다. route랑 router랑 다르니깐 헛갈리지말도록
|
|
145
140
|
if (intent.module === undefined && !intent.getRouterPathData(rr.reqUrlPathName)) {
|
|
146
141
|
throw new NotFoundError({ message: `Not Found: ${rr.reqUrlPathName}` });
|
|
@@ -167,18 +162,18 @@ export class SSRFilter implements Filter {
|
|
|
167
162
|
// // delay(1000),
|
|
168
163
|
// first()
|
|
169
164
|
// );
|
|
170
|
-
const data = await firstValueFrom(
|
|
165
|
+
const data = await MessageInternal.firstValueFrom(
|
|
171
166
|
// @ts-ignore
|
|
172
|
-
simpleBootFront.
|
|
167
|
+
simpleBootFront.routingObservable.pipe(
|
|
173
168
|
// @ts-ignore
|
|
174
|
-
filter(
|
|
169
|
+
MessageOperator.filter(
|
|
175
170
|
(it) =>
|
|
176
171
|
it.triggerPoint === 'end' &&
|
|
177
172
|
typeof it.routerModule.intent.uri === 'string' &&
|
|
178
173
|
targetUrl.endsWith(it.routerModule.intent.uri)
|
|
179
174
|
),
|
|
180
175
|
// delay(1000),
|
|
181
|
-
first()
|
|
176
|
+
MessageOperator.first()
|
|
182
177
|
)
|
|
183
178
|
);
|
|
184
179
|
// console.log('rrrrrssss');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequestResponse } from '@dooboostore/simple-boot-http-server/models/RequestResponse';
|
|
2
2
|
import { HttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
|
|
3
3
|
import { SimpleBootHttpSSRFactory } from '../SimpleBootHttpSSRFactory';
|
|
4
|
-
import { ConstructorType } from '@dooboostore/core
|
|
4
|
+
import { ConstructorType, AsyncBlockingQueue, RandomUtils, MessageOperator, MessageInternal } from '@dooboostore/core';
|
|
5
5
|
import { JsdomInitializer } from '../initializers/JsdomInitializer';
|
|
6
6
|
import { Filter } from '@dooboostore/simple-boot-http-server/filters/Filter';
|
|
7
7
|
import { Mimes } from '@dooboostore/simple-boot-http-server/codes/Mimes';
|
|
@@ -9,14 +9,9 @@ import { HttpStatus } from '@dooboostore/simple-boot-http-server/codes/HttpStatu
|
|
|
9
9
|
import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
|
|
10
10
|
import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
|
|
11
11
|
import { SimpleBootFront } from '@dooboostore/simple-boot-front/SimpleBootFront';
|
|
12
|
-
import { AsyncBlockingQueue } from '@dooboostore/core/queues/AsyncBlockingQueue';
|
|
13
|
-
import { RandomUtils } from '@dooboostore/core/random/RandomUtils';
|
|
14
12
|
import * as JSDOM from 'jsdom';
|
|
15
13
|
import { NotFoundError } from '@dooboostore/simple-boot-http-server/errors/NotFoundError';
|
|
16
|
-
import { DomRenderProxy } from '@dooboostore/dom-render
|
|
17
|
-
import { filter } from '@dooboostore/core/message/operators/filter';
|
|
18
|
-
import { first } from '@dooboostore/core/message/operators/first';
|
|
19
|
-
import { firstValueFrom } from '@dooboostore/core/message/internal/firstValueFrom';
|
|
14
|
+
import { DomRenderProxy } from '@dooboostore/dom-render';
|
|
20
15
|
import { parseHTML } from 'linkedom';
|
|
21
16
|
import { LinkedomInitializer } from '../initializers/LinkedomInitializer';
|
|
22
17
|
|
|
@@ -127,7 +122,7 @@ export class SSRLinkDomDomFilter implements Filter {
|
|
|
127
122
|
const url = rr.reqUrlObj({ host: 'localhost' });
|
|
128
123
|
if (this.config.simpleBootFront?.notFoundError) {
|
|
129
124
|
// intent router check first
|
|
130
|
-
const intent = await simpleBootFront.
|
|
125
|
+
const intent = await simpleBootFront.routingRouterModule(url.pathname);
|
|
131
126
|
// route를 못찾은상태에서 router path까지 안맞으면 404 처리한다. route랑 router랑 다르니깐 헛갈리지말도록
|
|
132
127
|
if (intent.module === undefined && !intent.getRouterPathData(rr.reqUrlPathName)) {
|
|
133
128
|
throw new NotFoundError({ message: `Not Found: ${rr.reqUrlPathName}` });
|
|
@@ -147,18 +142,18 @@ export class SSRLinkDomDomFilter implements Filter {
|
|
|
147
142
|
// }
|
|
148
143
|
// })
|
|
149
144
|
|
|
150
|
-
const data = await firstValueFrom(
|
|
145
|
+
const data = await MessageInternal.firstValueFrom(
|
|
151
146
|
// @ts-ignore
|
|
152
|
-
simpleBootFront.
|
|
147
|
+
simpleBootFront.routingObservable.pipe(
|
|
153
148
|
// @ts-ignore
|
|
154
|
-
filter(
|
|
149
|
+
MessageOperator.filter(
|
|
155
150
|
(it) =>
|
|
156
151
|
it.triggerPoint === 'end' &&
|
|
157
152
|
typeof it.routerModule.intent.uri === 'string' &&
|
|
158
153
|
targetUrl.endsWith(it.routerModule.intent.uri)
|
|
159
154
|
),
|
|
160
155
|
// delay(1000),
|
|
161
|
-
first()
|
|
156
|
+
MessageOperator.first()
|
|
162
157
|
)
|
|
163
158
|
);
|
|
164
159
|
// console.log('???????done');
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { RequestResponse } from '@dooboostore/simple-boot-http-server/models/RequestResponse';
|
|
2
|
+
import { HttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
|
|
3
|
+
import { Filter } from '@dooboostore/simple-boot-http-server/filters/Filter';
|
|
4
|
+
import { Mimes } from '@dooboostore/simple-boot-http-server/codes/Mimes';
|
|
5
|
+
import { HttpStatus } from '@dooboostore/simple-boot-http-server/codes/HttpStatus';
|
|
6
|
+
import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
|
|
7
|
+
import { DomParserInitializer } from '../initializers/DomParserInitializer';
|
|
8
|
+
import { HTMLElementBase } from '@dooboostore/dom-parser';
|
|
9
|
+
import { ConstructorType } from '@dooboostore/core';
|
|
10
|
+
import {getElementConfig} from "@dooboostore/simple-web-component";
|
|
11
|
+
|
|
12
|
+
export type SWCSSRConfig = {
|
|
13
|
+
frontDistPath: string;
|
|
14
|
+
frontDistIndexFileName?: string;
|
|
15
|
+
welcomUrl?: string;
|
|
16
|
+
ssrExcludeFilter?: (rr: RequestResponse) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Function to register components for each request.
|
|
19
|
+
*/
|
|
20
|
+
registerComponents?: (window: any) => Promise<void> | void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* SSR Filter specifically for Simple Web Component (SWC).
|
|
25
|
+
* It utilizes @dooboostore/dom-parser for rendering and DSD support.
|
|
26
|
+
*/
|
|
27
|
+
export class SSRSimpleWebComponentFilter implements Filter {
|
|
28
|
+
private welcomUrl = 'http://localhost';
|
|
29
|
+
|
|
30
|
+
constructor(public config: SWCSSRConfig) {
|
|
31
|
+
this.welcomUrl = config.welcomUrl || this.welcomUrl;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async onInit(app: SimpleBootHttpServer) {}
|
|
35
|
+
|
|
36
|
+
async onDestroy() {}
|
|
37
|
+
|
|
38
|
+
async proceedBefore({ rr }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
|
|
39
|
+
if (this.config.ssrExcludeFilter?.(rr)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (rr.reqHasAcceptHeader(Mimes.TextHtml) || rr.reqHasAcceptHeader(Mimes.All)) {
|
|
44
|
+
const url = rr.reqUrlObj({ host: 'localhost' });
|
|
45
|
+
const targetUrl = url.toString() ?? this.welcomUrl;
|
|
46
|
+
|
|
47
|
+
// 1. Initialize Virtual DOM Environment
|
|
48
|
+
const domParserInitializer = new DomParserInitializer(this.config.frontDistPath, this.config.frontDistIndexFileName || 'index.html', { url: targetUrl });
|
|
49
|
+
const window = await domParserInitializer.run();
|
|
50
|
+
|
|
51
|
+
// web component 경우 자기 tagName을 생성자 에게 HTMLElementBase에넘겨줘야되기떄문에
|
|
52
|
+
const getTagName = (type: ConstructorType<any>) => {
|
|
53
|
+
const zz = getElementConfig(type);
|
|
54
|
+
return zz.name;
|
|
55
|
+
};
|
|
56
|
+
(window as any).HTMLElement = class extends HTMLElementBase {
|
|
57
|
+
constructor(...args: any[]) {
|
|
58
|
+
const ctor = new.target as any; // 이런 슈가 기능이...
|
|
59
|
+
const resolvedTagName = getTagName(ctor);
|
|
60
|
+
super(resolvedTagName, args[0]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
// 2. Register Components if provided
|
|
67
|
+
// We use SwcApplication inside the callback or directly here.
|
|
68
|
+
if (this.config.registerComponents) {
|
|
69
|
+
await this.config.registerComponents(window);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 3. Generate Final HTML
|
|
73
|
+
const html = this.makeHTML(window);
|
|
74
|
+
|
|
75
|
+
await this.writeOkHtmlAndEnd({ rr }, html);
|
|
76
|
+
} finally {
|
|
77
|
+
// 4. Cleanup
|
|
78
|
+
(window as any).close?.();
|
|
79
|
+
domParserInitializer.destroy();
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
makeHTML(window: any) {
|
|
87
|
+
let html = window.document.documentElement.outerHTML;
|
|
88
|
+
if (!/^<!DOCTYPE html>/i.test(html)) {
|
|
89
|
+
html = '<!DOCTYPE html>\n' + html;
|
|
90
|
+
}
|
|
91
|
+
return html;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async writeOkHtmlAndEnd({ rr, status = HttpStatus.Ok }: { rr: RequestResponse; status?: HttpStatus }, html: string) {
|
|
95
|
+
rr.resStatusCode(status);
|
|
96
|
+
rr.resSetHeader(HttpHeaders.ContentType, Mimes.TextHtml);
|
|
97
|
+
await rr.resEnd(html);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async proceedAfter() {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|