@dooboostore/simple-boot-http-server-ssr 1.0.11 → 1.0.12

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.
Files changed (146) hide show
  1. package/README.MD +24 -209
  2. package/dist/cjs/bundle-entry.js +36 -0
  3. package/dist/cjs/bundle-entry.js.map +7 -0
  4. package/dist/cjs/codes/HttpHeaders.js.map +2 -2
  5. package/dist/cjs/filters/SSRFilter.js +4 -6
  6. package/dist/cjs/filters/SSRFilter.js.map +2 -2
  7. package/dist/cjs/filters/SSRWorker.js +1 -2
  8. package/dist/cjs/filters/SSRWorker.js.map +1 -1
  9. package/dist/cjs/index.js.map +2 -2
  10. package/dist/cjs/initializers/JsdomInitializer.js +1 -0
  11. package/dist/cjs/initializers/JsdomInitializer.js.map +2 -2
  12. package/dist/cjs/package.json +2 -0
  13. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +17 -2
  14. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +3 -3
  15. package/dist/esm/bundle-entry.js +9 -0
  16. package/dist/esm/bundle-entry.js.map +7 -0
  17. package/dist/esm/codes/HttpHeaders.js.map +2 -2
  18. package/dist/esm/filters/SSRFilter.js +4 -6
  19. package/dist/esm/filters/SSRFilter.js.map +2 -2
  20. package/dist/esm/filters/SSRWorker.js +1 -2
  21. package/dist/esm/filters/SSRWorker.js.map +1 -1
  22. package/dist/esm/index.js.map +2 -2
  23. package/dist/esm/initializers/JsdomInitializer.js +1 -0
  24. package/dist/esm/initializers/JsdomInitializer.js.map +2 -2
  25. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +18 -3
  26. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +3 -3
  27. package/dist/esm-bundle/dooboostore-simple-boot-http-server-ssr.esm.js +11372 -3
  28. package/dist/esm-bundle/dooboostore-simple-boot-http-server-ssr.esm.js.map +4 -4
  29. package/dist/{esm → types}/SimpleBootHttpSSRServer.d.ts +1 -1
  30. package/dist/types/bundle-entry.d.ts +9 -0
  31. package/dist/types/bundle-entry.d.ts.map +1 -0
  32. package/dist/types/codes/HttpHeaders.d.ts +45 -0
  33. package/dist/types/codes/HttpHeaders.d.ts.map +1 -0
  34. package/dist/{cjs → types}/filters/SSRFilter.d.ts.map +1 -1
  35. package/dist/types/index.d.ts +22 -0
  36. package/dist/{esm → types}/index.d.ts.map +1 -1
  37. package/dist/{cjs → types}/initializers/JsdomInitializer.d.ts.map +1 -1
  38. package/dist/{cjs → types}/proxy/SymbolIntentApiServiceProxy.d.ts.map +1 -1
  39. package/dist/umd-bundle/dooboostore-simple-boot-http-server-ssr.umd.js +11364 -6
  40. package/dist/umd-bundle/dooboostore-simple-boot-http-server-ssr.umd.js.map +4 -4
  41. package/package.json +30 -18
  42. package/src/SimpleBootHttpSSRFactory.ts +11 -0
  43. package/src/SimpleBootHttpSSRServer.ts +21 -0
  44. package/src/bundle-entry.ts +8 -0
  45. package/src/codes/HttpHeaders.ts +17 -0
  46. package/src/codes/Mimes.ts +6 -0
  47. package/src/codes/index.ts +2 -0
  48. package/src/decorators/LoadAroundBefore.ts +28 -0
  49. package/src/decorators/SaveAroundAfter.ts +27 -0
  50. package/src/decorators/index.ts +2 -0
  51. package/src/filters/IntentSchemeFilter.ts +66 -0
  52. package/src/filters/SSRFilter.ts +339 -0
  53. package/src/filters/SSRWorker.ts +76 -0
  54. package/{dist/esm/filters/index.d.ts → src/filters/index.ts} +1 -2
  55. package/src/index.ts +9 -0
  56. package/src/initializers/JsdomInitializer.ts +85 -0
  57. package/src/initializers/index.ts +1 -0
  58. package/src/option/HttpSSRServerOption.ts +4 -0
  59. package/src/option/index.ts +1 -0
  60. package/src/proxy/IntentSchemeFrontProxy.ts +67 -0
  61. package/src/proxy/IntentSchemeServerProxy.ts +35 -0
  62. package/src/proxy/SymbolIntentApiServiceProxy.ts +131 -0
  63. package/src/proxy/SymbolIntentApiServiceProxyBase.ts +97 -0
  64. package/{dist/esm/proxy/index.d.ts → src/proxy/index.ts} +1 -2
  65. package/tsconfig.json +24 -0
  66. package/dist/cjs/SimpleBootHttpSSRServer.d.ts +0 -9
  67. package/dist/cjs/codes/HttpHeaders.d.ts +0 -45
  68. package/dist/cjs/codes/HttpHeaders.d.ts.map +0 -1
  69. package/dist/cjs/index.d.ts +0 -3
  70. package/dist/cjs/index.d.ts.map +0 -1
  71. package/dist/esm/SimpleBootHttpSSRFactory.d.ts +0 -8
  72. package/dist/esm/SimpleBootHttpSSRFactory.d.ts.map +0 -1
  73. package/dist/esm/SimpleBootHttpSSRServer.d.ts.map +0 -1
  74. package/dist/esm/codes/HttpHeaders.d.ts +0 -45
  75. package/dist/esm/codes/HttpHeaders.d.ts.map +0 -1
  76. package/dist/esm/codes/Mimes.d.ts +0 -31
  77. package/dist/esm/codes/Mimes.d.ts.map +0 -1
  78. package/dist/esm/codes/index.d.ts +0 -3
  79. package/dist/esm/codes/index.d.ts.map +0 -1
  80. package/dist/esm/decorators/LoadAroundBefore.d.ts +0 -2
  81. package/dist/esm/decorators/LoadAroundBefore.d.ts.map +0 -1
  82. package/dist/esm/decorators/SaveAroundAfter.d.ts +0 -3
  83. package/dist/esm/decorators/SaveAroundAfter.d.ts.map +0 -1
  84. package/dist/esm/decorators/index.d.ts +0 -3
  85. package/dist/esm/decorators/index.d.ts.map +0 -1
  86. package/dist/esm/filters/IntentSchemeFilter.d.ts +0 -20
  87. package/dist/esm/filters/IntentSchemeFilter.d.ts.map +0 -1
  88. package/dist/esm/filters/SSRFilter.d.ts +0 -59
  89. package/dist/esm/filters/SSRFilter.d.ts.map +0 -1
  90. package/dist/esm/filters/SSRWorker.d.ts +0 -16
  91. package/dist/esm/filters/SSRWorker.d.ts.map +0 -1
  92. package/dist/esm/filters/index.d.ts.map +0 -1
  93. package/dist/esm/index.d.ts +0 -3
  94. package/dist/esm/initializers/JsdomInitializer.d.ts +0 -11
  95. package/dist/esm/initializers/JsdomInitializer.d.ts.map +0 -1
  96. package/dist/esm/initializers/index.d.ts +0 -2
  97. package/dist/esm/initializers/index.d.ts.map +0 -1
  98. package/dist/esm/option/HttpSSRServerOption.d.ts +0 -4
  99. package/dist/esm/option/HttpSSRServerOption.d.ts.map +0 -1
  100. package/dist/esm/option/index.d.ts +0 -2
  101. package/dist/esm/option/index.d.ts.map +0 -1
  102. package/dist/esm/proxy/IntentSchemeFrontProxy.d.ts +0 -4
  103. package/dist/esm/proxy/IntentSchemeFrontProxy.d.ts.map +0 -1
  104. package/dist/esm/proxy/IntentSchemeServerProxy.d.ts +0 -4
  105. package/dist/esm/proxy/IntentSchemeServerProxy.d.ts.map +0 -1
  106. package/dist/esm/proxy/SymbolIntentApiServiceProxy.d.ts +0 -16
  107. package/dist/esm/proxy/SymbolIntentApiServiceProxy.d.ts.map +0 -1
  108. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.d.ts +0 -13
  109. package/dist/esm/proxy/SymbolIntentApiServiceProxyBase.d.ts.map +0 -1
  110. package/dist/esm/proxy/index.d.ts.map +0 -1
  111. /package/dist/{cjs → types}/SimpleBootHttpSSRFactory.d.ts +0 -0
  112. /package/dist/{cjs → types}/SimpleBootHttpSSRFactory.d.ts.map +0 -0
  113. /package/dist/{cjs → types}/SimpleBootHttpSSRServer.d.ts.map +0 -0
  114. /package/dist/{cjs → types}/codes/Mimes.d.ts +0 -0
  115. /package/dist/{cjs → types}/codes/Mimes.d.ts.map +0 -0
  116. /package/dist/{cjs → types}/codes/index.d.ts +0 -0
  117. /package/dist/{cjs → types}/codes/index.d.ts.map +0 -0
  118. /package/dist/{cjs → types}/decorators/LoadAroundBefore.d.ts +0 -0
  119. /package/dist/{cjs → types}/decorators/LoadAroundBefore.d.ts.map +0 -0
  120. /package/dist/{cjs → types}/decorators/SaveAroundAfter.d.ts +0 -0
  121. /package/dist/{cjs → types}/decorators/SaveAroundAfter.d.ts.map +0 -0
  122. /package/dist/{cjs → types}/decorators/index.d.ts +0 -0
  123. /package/dist/{cjs → types}/decorators/index.d.ts.map +0 -0
  124. /package/dist/{cjs → types}/filters/IntentSchemeFilter.d.ts +0 -0
  125. /package/dist/{cjs → types}/filters/IntentSchemeFilter.d.ts.map +0 -0
  126. /package/dist/{cjs → types}/filters/SSRFilter.d.ts +0 -0
  127. /package/dist/{cjs → types}/filters/SSRWorker.d.ts +0 -0
  128. /package/dist/{cjs → types}/filters/SSRWorker.d.ts.map +0 -0
  129. /package/dist/{cjs → types}/filters/index.d.ts +0 -0
  130. /package/dist/{cjs → types}/filters/index.d.ts.map +0 -0
  131. /package/dist/{cjs → types}/initializers/JsdomInitializer.d.ts +0 -0
  132. /package/dist/{cjs → types}/initializers/index.d.ts +0 -0
  133. /package/dist/{cjs → types}/initializers/index.d.ts.map +0 -0
  134. /package/dist/{cjs → types}/option/HttpSSRServerOption.d.ts +0 -0
  135. /package/dist/{cjs → types}/option/HttpSSRServerOption.d.ts.map +0 -0
  136. /package/dist/{cjs → types}/option/index.d.ts +0 -0
  137. /package/dist/{cjs → types}/option/index.d.ts.map +0 -0
  138. /package/dist/{cjs → types}/proxy/IntentSchemeFrontProxy.d.ts +0 -0
  139. /package/dist/{cjs → types}/proxy/IntentSchemeFrontProxy.d.ts.map +0 -0
  140. /package/dist/{cjs → types}/proxy/IntentSchemeServerProxy.d.ts +0 -0
  141. /package/dist/{cjs → types}/proxy/IntentSchemeServerProxy.d.ts.map +0 -0
  142. /package/dist/{cjs → types}/proxy/SymbolIntentApiServiceProxy.d.ts +0 -0
  143. /package/dist/{cjs → types}/proxy/SymbolIntentApiServiceProxyBase.d.ts +0 -0
  144. /package/dist/{cjs → types}/proxy/SymbolIntentApiServiceProxyBase.d.ts.map +0 -0
  145. /package/dist/{cjs → types}/proxy/index.d.ts +0 -0
  146. /package/dist/{cjs → types}/proxy/index.d.ts.map +0 -0
package/package.json CHANGED
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-boot-http-server-ssr",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
7
7
  "module": "./dist/esm/index.js",
8
- "types": "./dist/esm/index.d.ts",
8
+ "types": "./dist/types/index.d.ts",
9
+ "typesVersions": {
10
+ ">=4.2": {
11
+ "*": [
12
+ "dist/types/*"
13
+ ]
14
+ }
15
+ },
9
16
  "description": "front end SPA frameworks SSR",
10
17
  "files": [
11
- "dist"
18
+ "dist",
19
+ "src",
20
+ "LICENSE.md",
21
+ "tsconfig.json"
12
22
  ],
13
23
  "keywords": [
14
24
  "front",
@@ -19,21 +29,21 @@
19
29
  "framwork",
20
30
  "node"
21
31
  ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
22
35
  "exports": {
23
36
  ".": {
24
- "types": "./dist/esm/index.d.ts",
37
+ "types": "./dist/types/index.d.ts",
25
38
  "import": "./dist/esm/index.js",
26
39
  "require": "./dist/cjs/index.js"
27
40
  },
28
41
  "./*": {
29
- "types": "./dist/esm/*.d.ts",
42
+ "types": "./dist/types/*.d.ts",
30
43
  "import": "./dist/esm/*.js",
31
44
  "require": "./dist/cjs/*.js"
32
45
  }
33
46
  },
34
- "publishConfig": {
35
- "access": "public"
36
- },
37
47
  "author": "dooboostore <dooboostore@gmail.com> (https://github.com/dooboostore)",
38
48
  "contributors": [
39
49
  "sewoo <sewooimda@nate.com> (https://github.com/sewoo)",
@@ -53,13 +63,13 @@
53
63
  },
54
64
  "peerDependencies": {
55
65
  "reflect-metadata": "^0.2.2",
56
- "@dooboostore/core": "1.0.18",
57
- "@dooboostore/core-web": "1.0.5",
58
- "@dooboostore/core-node": "1.0.6",
59
- "@dooboostore/simple-boot": "1.0.48",
60
- "@dooboostore/dom-render": "1.0.107",
61
- "@dooboostore/simple-boot-front": "1.0.126",
62
- "@dooboostore/simple-boot-http-server": "1.0.19"
66
+ "@dooboostore/core": "1.0.22",
67
+ "@dooboostore/core-node": "1.0.8",
68
+ "@dooboostore/core-web": "1.0.7",
69
+ "@dooboostore/dom-render": "1.0.109",
70
+ "@dooboostore/simple-boot-front": "1.0.128",
71
+ "@dooboostore/simple-boot-http-server": "1.0.21",
72
+ "@dooboostore/simple-boot": "1.0.51"
63
73
  },
64
74
  "dependencies": {
65
75
  "jsdom": "^26.0.0"
@@ -85,16 +95,18 @@
85
95
  },
86
96
  "scripts": {
87
97
  "clean": "rm -rf dist",
88
- "build:esm": "node build.mjs esm && tsc -p tsconfig.esm.json --emitDeclarationOnly",
98
+ "build:esm": "node build.mjs esm",
89
99
  "watch:esm": "pnpm run build:esm && node build.mjs esm --watch",
90
- "build:cjs": "node build.mjs cjs && tsc -p tsconfig.cjs.json --emitDeclarationOnly && cp package.cjs.json dist/cjs/package.json",
100
+ "build:cjs": "node build.mjs cjs",
91
101
  "watch:cjs": "pnpm run build:cjs && node build.mjs cjs --watch",
92
- "build": "pnpm run clean && node build.mjs all && tsc -p tsconfig.esm.json --emitDeclarationOnly && tsc -p tsconfig.cjs.json --emitDeclarationOnly && cp package.cjs.json dist/cjs/package.json",
102
+ "build": "pnpm run clean && node build.mjs all",
93
103
  "build:umd-bundle": "node build.mjs umd-bundle",
94
104
  "watch:umd-bundle": "pnpm run build:umd-bundle && node build.mjs umd-bundle --watch",
95
105
  "build:esm-bundle": "node build.mjs esm-bundle",
96
106
  "watch:esm-bundle": "pnpm run build:esm-bundle && node build.mjs esm-bundle --watch",
107
+ "watch": "node build.mjs all --watch",
97
108
  "publish:npm": "pnpm run build && cp package.json package.json.back && pnpm pack && TARBALL_NAME=$(ls dooboostore-simple-boot-http-server-ssr-*.tgz | head -n 1) && tar -xzf \"$TARBALL_NAME\" -C . --strip-components=1 package/package.json && rm \"$TARBALL_NAME\" && (pnpm publish --no-git-checks || true) && cp package.json.back package.json && rm -rf package.json.back ",
109
+ "ts:clean": "find . -name '*.js' -o -name '*.map' -o -name '*.d.ts' | xargs rm -f",
98
110
  "typecheck": "tsc --noEmit",
99
111
  "test": "echo test"
100
112
  }
@@ -0,0 +1,11 @@
1
+ import { SimpleBootFront } from '@dooboostore/simple-boot-front/SimpleBootFront';
2
+ import { ConstructorType } from '@dooboostore/core/types';
3
+ import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
4
+ export abstract class SimpleBootHttpSSRFactory {
5
+ public abstract factory(simFrontOption: SimFrontOption, using: (ConstructorType<any> | Function)[], domExcludes: ConstructorType<any>[]): Promise<SimpleBootFront> ;
6
+
7
+ public async create(simFrontOption: SimFrontOption, using: (ConstructorType<any> | Function)[] = [], domExcludes: ConstructorType<any>[] = []): Promise<SimpleBootFront> {
8
+ const front = await this.factory(simFrontOption, using, domExcludes);
9
+ return front;
10
+ }
11
+ }
@@ -0,0 +1,21 @@
1
+ import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
2
+ // import { SimstanceManager } from '@dooboostore/simple-boot/simstance/SimstanceManager';
3
+ import { HttpSSRServerOption } from './option/HttpSSRServerOption';
4
+ import { ConstructorType } from '@dooboostore/core/types';
5
+
6
+ export class SimpleBootHttpSSRServer extends SimpleBootHttpServer {
7
+ constructor(option?: HttpSSRServerOption) {
8
+ super(option)
9
+ }
10
+
11
+ run(otherInstanceSim?: Map<ConstructorType<any>, any>) {
12
+ const oi = new Map<ConstructorType<any>, any>()
13
+ otherInstanceSim?.forEach((value, key) => oi.set(key, value));
14
+ return super.run(oi);
15
+ }
16
+
17
+ // TODO: 나중에 뭐라도..
18
+ stop(){
19
+
20
+ }
21
+ }
@@ -0,0 +1,8 @@
1
+ export * from './codes';
2
+ export * from './decorators';
3
+ export * from './filters';
4
+ export * from './initializers';
5
+ export * from './option';
6
+ export * from './proxy';
7
+ export * from './SimpleBootHttpSSRFactory';
8
+ export * from './SimpleBootHttpSSRServer';
@@ -0,0 +1,17 @@
1
+ import { HttpHeaders as AHttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
2
+ import { Mimes } from './Mimes';
3
+
4
+ export const HttpHeaders = {
5
+ ...AHttpHeaders,
6
+ XSimpleBootSsrIntentScheme: 'x-simple-boot-ssr-intent-scheme'
7
+ };
8
+ export type HttpHeadersType = typeof HttpHeaders;
9
+
10
+ export const makeIntentHeaderBySymbol = (symbol: Symbol): HeadersInit => {
11
+ return {
12
+ [HttpHeaders.Accept]: Mimes.ApplicationJsonPostSimpleBootSsrIntentScheme,
13
+ [HttpHeaders.XSimpleBootSsrIntentScheme]: `Symbol.for(${symbol.description})`
14
+ }
15
+ };
16
+
17
+
@@ -0,0 +1,6 @@
1
+ import {Mimes as AMimes} from '@dooboostore/simple-boot-http-server/codes/Mimes';
2
+ export const Mimes = {
3
+ ...AMimes,
4
+ ApplicationJsonPostSimpleBootSsrIntentScheme:'application/json-post+simple-boot-ssr-intent-scheme',
5
+ Intent: 'intent'
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from './HttpHeaders';
2
+ export * from './Mimes';
@@ -0,0 +1,28 @@
1
+ import { getSim } from '@dooboostore/simple-boot/decorators/SimDecorator';
2
+ import { AroundForceReturn } from '@dooboostore/simple-boot/decorators/aop/AOPDecorator';
3
+ import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';
4
+
5
+ export const LoadAroundBefore = (obj: any, propertyKey: string, args: any[]) => {
6
+ const simstanceManager = obj._SimpleBoot_simstanceManager;
7
+ const simOption = obj._SimpleBoot_simOption;
8
+ const config = getSim(obj);
9
+ if (simstanceManager && simOption && config?.scheme) {
10
+ const key = config.scheme + '_' + propertyKey;
11
+ const type = ReflectUtils.getReturnType(obj, propertyKey);
12
+ const isHas = (key in (simOption.window.server_side_data ?? {}))
13
+ if (isHas) {
14
+ const data = simOption.window.server_side_data?.[key];
15
+ delete simOption.window.server_side_data?.[key];
16
+ let rdata;
17
+ if (type === Promise) {
18
+ rdata = Promise.resolve(data);
19
+ } else {
20
+ rdata = data;
21
+ }
22
+ throw new AroundForceReturn(rdata);
23
+ } else {
24
+ return args;
25
+ }
26
+ }
27
+ return args;
28
+ }
@@ -0,0 +1,27 @@
1
+ import { getSim } from '@dooboostore/simple-boot/decorators/SimDecorator';
2
+
3
+ export const SaveAroundAfter = (obj: any, propertyKey: string, args: any[], beforeReturn: any) => {
4
+ const simstanceManager = obj._SimpleBoot_simstanceManager;
5
+ const simOption = obj._SimpleBoot_simOption;
6
+ const config = getSim(obj);
7
+ if (simstanceManager && simOption && config?.scheme) {
8
+ if (!simOption.window.server_side_data) {
9
+ simOption.window.server_side_data = {};
10
+ }
11
+ const key = config.scheme+'_'+propertyKey;
12
+ if (beforeReturn instanceof Promise) {
13
+ beforeReturn.then((it) => {
14
+ simOption.window.server_side_data[key] = JSON.stringify(it);
15
+ return it;
16
+ });
17
+ } else {
18
+ simOption.window.server_side_data[key] = JSON.stringify(beforeReturn);
19
+ }
20
+ }
21
+ return beforeReturn;
22
+ }
23
+
24
+
25
+ export const getStorage = (window: Window) => {
26
+ return (window as any).aroundStorage;
27
+ }
@@ -0,0 +1,2 @@
1
+ export * from './LoadAroundBefore';
2
+ export * from './SaveAroundAfter';
@@ -0,0 +1,66 @@
1
+ import {Filter} from '@dooboostore/simple-boot-http-server/filters/Filter';
2
+ import {HttpHeaders} from '../codes/HttpHeaders';
3
+ import {Intent, PublishType} from '@dooboostore/simple-boot/intent/Intent';
4
+ import {IntentManager} from '@dooboostore/simple-boot/intent/IntentManager';
5
+ import {Sim} from '@dooboostore/simple-boot/decorators/SimDecorator';
6
+ import {HttpStatus} from '@dooboostore/simple-boot-http-server/codes/HttpStatus';
7
+ import {RequestResponse} from '@dooboostore/simple-boot-http-server/models/RequestResponse';
8
+ import {SimpleBootHttpServer} from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
9
+ import { Mimes } from '../codes/Mimes';
10
+
11
+ @Sim
12
+ export class IntentSchemeFilter implements Filter {
13
+ constructor(private intentManager: IntentManager) {
14
+ // (IntentManager as any).
15
+ // console.log('intent constructor', this.intentManager);
16
+ }
17
+
18
+ async onInit(app: SimpleBootHttpServer) {
19
+ }
20
+
21
+ async proceedBefore({rr, app}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {
22
+ // const rr = rrr;
23
+ const url = rr.reqUrl;
24
+ const contentLength = Number(rr.reqHeader(HttpHeaders.ContentLength.toLowerCase() ?? '0'));
25
+ const acceptType = rr.reqHeader(HttpHeaders.Accept);
26
+ const contentType = rr.reqHeader(HttpHeaders.ContentType);
27
+ const intentScheme = rr.reqHeader(HttpHeaders.XSimpleBootSsrIntentScheme);
28
+ if (acceptType === Mimes.ApplicationJsonPostSimpleBootSsrIntentScheme && intentScheme) {
29
+ let intent = new Intent(`${intentScheme}:/${url}`);
30
+ intent.publishType = PublishType.INLINE_DATA_PARAMETERS;
31
+ // const responseHeader = {} as any;
32
+ // responseHeader[HttpHeaders.ContentType] = Mimes.ApplicationJson;
33
+ if (contentLength > 0) {
34
+ if (contentType.includes(Mimes.ApplicationJson)) {
35
+ intent.data = [await rr.reqBodyJsonData(), rr];
36
+ } else if (contentType.includes(Mimes.MultipartFormData)) {
37
+ intent.data = [await rr.reqBodyMultipartFormDataObject(), rr];
38
+ }
39
+ const rdatas = await this.intentManager.publish(intent);
40
+ const rdata = rdatas[0];
41
+ const wdata = rdata instanceof Promise ? await rdata : rdata;
42
+ rr.resStatusCode(HttpStatus.Ok);
43
+ rr.resSetHeader(HttpHeaders.ContentType, [Mimes.ApplicationJson])
44
+ await rr.resEnd(wdata ? JSON.stringify(wdata) : undefined);
45
+ } else {
46
+ intent.data = rr.reqUrlSearchParamTuples.length > 0 ? [rr.reqUrlSearchParamsObj, rr] : [rr];
47
+ const rdatas = await this.intentManager.publish(intent);
48
+ const rdata = rdatas[0];
49
+ const wdata = rdata instanceof Promise ? await rdata : rdata;
50
+ // const wdata =undefined;
51
+ rr.resStatusCode(HttpStatus.Ok);
52
+ rr.resSetHeader(HttpHeaders.ContentType, [Mimes.ApplicationJson])
53
+ await rr.resEnd(wdata ? JSON.stringify(wdata) : undefined);
54
+ }
55
+ // console.log('---------3--intent request', rr.req.readable, rr.req.readableLength);
56
+ return false;
57
+ } else {
58
+ return true;
59
+ }
60
+ }
61
+
62
+ async proceedAfter({rr, app}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {
63
+ return true;
64
+ }
65
+
66
+ }
@@ -0,0 +1,339 @@
1
+ import { RequestResponse } from '@dooboostore/simple-boot-http-server/models/RequestResponse';
2
+ import { HttpHeaders } from '@dooboostore/simple-boot-http-server/codes/HttpHeaders';
3
+ import { SimpleBootHttpSSRFactory } from '../SimpleBootHttpSSRFactory';
4
+ import { ConstructorType } from '@dooboostore/core/types';
5
+ import { JsdomInitializer } from '../initializers/JsdomInitializer';
6
+ import { Filter } from '@dooboostore/simple-boot-http-server/filters/Filter';
7
+ import { Mimes } from '@dooboostore/simple-boot-http-server/codes/Mimes';
8
+ import { HttpStatus } from '@dooboostore/simple-boot-http-server/codes/HttpStatus';
9
+ import { SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server/SimpleBootHttpServer';
10
+ import { SimFrontOption } from '@dooboostore/simple-boot-front/option/SimFrontOption';
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
+ import * as JSDOM from 'jsdom';
15
+ import { NotFoundError } from '@dooboostore/simple-boot-http-server/errors/NotFoundError';
16
+ import { DomRenderProxy } from '@dooboostore/dom-render/DomRenderProxy';
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';
20
+
21
+ export type FactoryAndParams = {
22
+ frontDistPath: string;
23
+ frontDistIndexFileName?: string;
24
+ factorySimFrontOption: (window: any) => SimFrontOption;
25
+ factory: SimpleBootHttpSSRFactory;
26
+ poolOption: {
27
+ max: number;
28
+ min: number;
29
+ clearIntervalTime?: number;
30
+ };
31
+ using: ConstructorType<any>[];
32
+ domExcludes?: ConstructorType<any>[];
33
+ ssrExcludeFilter?: (rr: RequestResponse) => boolean;
34
+ simpleBootFront?: {
35
+ notFoundError?: boolean;
36
+ };
37
+ };
38
+
39
+ export class SSRFilter implements Filter {
40
+ private simpleBootFrontPool: SimpleBootFront[] = [];
41
+ private simpleBootFrontQueue = new AsyncBlockingQueue<SimpleBootFront>();
42
+ private indexHTML: string;
43
+ private welcomUrl = 'http://localhost';
44
+ private poolGeneration = 0;
45
+ private intervalId?: NodeJS.Timeout;
46
+
47
+ constructor(
48
+ public config: FactoryAndParams,
49
+ public otherInstanceSim?: Map<ConstructorType<any>, any>
50
+ ) {
51
+ config.frontDistIndexFileName = config.frontDistIndexFileName || 'index.html';
52
+ this.indexHTML = JsdomInitializer.loadFile(this.config.frontDistPath, config.frontDistIndexFileName);
53
+ }
54
+
55
+ async onInit(app: SimpleBootHttpServer) {
56
+ for (let i = 0; i < this.config.poolOption.min; i++) {
57
+ await this.pushQueue();
58
+ }
59
+
60
+ if (this.config.poolOption.clearIntervalTime && this.config.poolOption.clearIntervalTime > 0) {
61
+ this.intervalId = setInterval(() => {
62
+ this.poolGeneration++;
63
+ }, this.config.poolOption.clearIntervalTime);
64
+ }
65
+ // console.log('SimpleBootHttpSSRFactory init success ', + this.simpleBootFrontPool.length)
66
+ }
67
+
68
+ async onDestroy() {
69
+ if (this.intervalId) {
70
+ clearInterval(this.intervalId);
71
+ }
72
+ // this.simpleBootFrontQueue.clear();
73
+ this.simpleBootFrontPool.forEach(front => {
74
+ (front as any).jsdom?.window.close();
75
+ });
76
+ this.simpleBootFrontPool = [];
77
+ }
78
+
79
+ // workerTs(workerOptions: WorkerOptions) {
80
+ // workerOptions.eval = true;
81
+ // if (!workerOptions.workerData) {
82
+ // workerOptions.workerData = {};
83
+ // }
84
+ // workerOptions.workerData.__filename = '/Users/hyunhakim/source/visualkhh/pet-space/libs/simple-boot-http-ssr/dist/filters/SSRCreatorWorker.js';
85
+ // return new Worker(` const wk = require('worker_threads'); require('ts-node').register(); let file = wk.workerData.__filename; require(file); `, workerOptions,);
86
+ // }
87
+
88
+ async makeJsdom() {
89
+ const jsdom = await new JsdomInitializer(
90
+ this.config.frontDistPath,
91
+ this.config.frontDistIndexFileName || 'index.html',
92
+ { url: this.welcomUrl }
93
+ ).run();
94
+ return jsdom;
95
+ }
96
+
97
+ async makeFront(jsdom: JSDOM.JSDOM) {
98
+ const name = RandomUtils.uuid();
99
+ // const jsdom = await this.makeJsdom();
100
+ const window = jsdom.window as unknown as Window & typeof globalThis;
101
+ (window as any).ssrUse = false;
102
+ const option = this.config.factorySimFrontOption(DomRenderProxy.final(window));
103
+ const simpleBootFront = await this.config.factory.create(option, this.config.using, this.config.domExcludes);
104
+ simpleBootFront.run(this.otherInstanceSim);
105
+ (simpleBootFront as any).jsdom = jsdom;
106
+ (simpleBootFront as any).generation = this.poolGeneration;
107
+ return simpleBootFront;
108
+ }
109
+
110
+ enqueueFrontApp(simpleBootFront: SimpleBootFront) {
111
+ // this.simpleBootFrontPool.set(simpleBootFront.option.name!, simpleBootFront);
112
+ this.simpleBootFrontPool.push(simpleBootFront);
113
+ this.simpleBootFrontQueue.enqueue(simpleBootFront);
114
+ }
115
+
116
+ // async pushQueue(destorFront?: SimpleBootFront) {
117
+ // if (destorFront) {
118
+ // this.simpleBootFrontPool.delete(destorFront.option.name!);
119
+ // }
120
+ async pushQueue() {
121
+ if (this.simpleBootFrontPool.length < this.config.poolOption.max) {
122
+ this.enqueueFrontApp(await this.makeFront(await this.makeJsdom()));
123
+ }
124
+ }
125
+
126
+ async proceedBefore({ rr, app }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
127
+ if (this.config.ssrExcludeFilter?.(rr)) {
128
+ return false;
129
+ }
130
+ if (rr.reqHasAcceptHeader(Mimes.TextHtml) || rr.reqHasAcceptHeader(Mimes.All)) {
131
+ if (this.simpleBootFrontQueue.isEmpty()) {
132
+ await this.pushQueue();
133
+ }
134
+ const simpleBootFront = await this.simpleBootFrontQueue.dequeue();
135
+ try {
136
+ // console.log('SSRFilter before-->' , simpleBootFront.option.name, 'poolLength:',this.simpleBootFrontPool.size);
137
+ (simpleBootFront.option.window as any).ssrUse = true;
138
+ delete (simpleBootFront.option.window as any).server_side_data;
139
+
140
+ const url = rr.reqUrlObj({ host: 'localhost' });
141
+ if (this.config.simpleBootFront?.notFoundError) {
142
+ // intent router check first
143
+ const intent = await simpleBootFront.getIntent(url.pathname);
144
+ // route를 못찾은상태에서 router path까지 안맞으면 404 처리한다. route랑 router랑 다르니깐 헛갈리지말도록
145
+ if (intent.module === undefined && !intent.getRouterPathData(rr.reqUrlPathName)) {
146
+ throw new NotFoundError({ message: `Not Found: ${rr.reqUrlPathName}` });
147
+ }
148
+ }
149
+
150
+ // runRouting!!
151
+ const targetUrl = url.toString();
152
+ // console.log('rrrrr');
153
+ // simpleBootFront.routingSubjectObservable.subscribe(it => {
154
+ // if (it.state === 'end' && it.routerModule.intent.uri === targetUrl) {
155
+ // console.log('vvvvvvvvvvvv', it.state, it.routerModule.intent.uri);
156
+ // }
157
+ // });
158
+ await simpleBootFront.goRouting(targetUrl);
159
+ await new Promise(r => setTimeout(r, 0)); // <--중요: 이거 넣어야지 두번불러지는게 없어지는듯? 뭐지 event loop 변경된건가?
160
+ // TODO: 옵션으로 이거 키고 끄고할수있게 해야될까..?
161
+ // simpleBootFront.routingSubjectObservable.pipe(
162
+ // filter((it) =>
163
+ // it.state === 'end' &&
164
+ // typeof it.routerModule.intent.uri === 'string' &&
165
+ // targetUrl.endsWith(it.routerModule.intent.uri)
166
+ // ),
167
+ // // delay(1000),
168
+ // first()
169
+ // );
170
+ const data = await firstValueFrom(
171
+ // @ts-ignore
172
+ simpleBootFront.routingSubjectObservable.pipe(
173
+ // @ts-ignore
174
+ filter(
175
+ (it: any) =>
176
+ it.state === 'end' &&
177
+ typeof it.routerModule.intent.uri === 'string' &&
178
+ targetUrl.endsWith(it.routerModule.intent.uri)
179
+ ),
180
+ // delay(1000),
181
+ first()
182
+ )
183
+ );
184
+ // console.log('rrrrrssss');
185
+ // console.log('rrrrrssss122');
186
+ // await new Promise(r => setTimeout(r, 5000)); // <--중요: 이거 넣어야지 두번불러지는게 없어지는듯? 뭐지 event loop 변경된건가?
187
+ const html = this.makeHTML(simpleBootFront);
188
+ await this.writeOkHtmlAndEnd({ rr }, html);
189
+ } finally {
190
+ (simpleBootFront.option.window as any).ssrUse = false;
191
+ delete (simpleBootFront.option.window as any).server_side_data;
192
+ // console.log('--------->', simpleBootFront.option.window)
193
+ // simpleBootFront.ninitWriteRootRouter();
194
+ // ((simpleBootFront as any).jsdom as JSDOM.JSDOM)?.reconfigure({url: '/' });
195
+ // simpleBootFront.option.window.location.href = 'about:blank';
196
+ // console.log('ddddddddd', (simpleBootFront as any).generation, this.poolGeneration)
197
+ if ((simpleBootFront as any).generation < this.poolGeneration) {
198
+ // Stale instance, destroy it
199
+ const jsdom = (simpleBootFront as any).jsdom as JSDOM.JSDOM | undefined;
200
+ jsdom?.window.close();
201
+ const index = this.simpleBootFrontPool.indexOf(simpleBootFront);
202
+ if (index > -1) {
203
+ this.simpleBootFrontPool.splice(index, 1);
204
+ }
205
+ // Create a new one to maintain pool size
206
+ this.pushQueue();
207
+ } else {
208
+ // Current instance, return to queue
209
+ this.simpleBootFrontQueue.enqueue(simpleBootFront);
210
+ }
211
+ // simpleBootFront.option.window.document.body.innerHTML = this.rootJSDOM.window.document.body.innerHTML;
212
+ // simpleBootFront.writeRootRouter()
213
+ // await simpleBootFront.goRouting('/');
214
+
215
+ // ((simpleBootFront as any).jsdom as JSDOM.JSDOM)?.reconfigure({url: this.welcomUrl });
216
+
217
+ // simpleBootFront.option.window.location.href = this.welcomUrl;
218
+ // simpleBootFront.option.window.document.documentElement.outerHTML = this.indexHTML;
219
+ // this.simpleBootFrontQueue.enqueue(simpleBootFront);
220
+ // await new Promise((re, r) => setTimeout(() => re(true), 10000));
221
+ // new Promise((re, r) => setTimeout(() => re(true), 10000)).then(it => {
222
+ // console.log('ddddddddddd')
223
+ // });
224
+ // this.simpleBootFrontPool.delete(simpleBootFront.option.name!);
225
+ // if (isMainThread) { // 메인 스레드
226
+ // console.log('file-->', __filename)
227
+ // const worker = new Worker(__filename);
228
+ // worker.on('message', (value: any) => {
229
+ // console.log('워커로부터', value)
230
+ // })
231
+ // worker.on('exit', (value: any) => { // parentPort.close()가 일어나면 이벤트 발생
232
+ // console.log('워커 끝~');
233
+ // })
234
+ // worker.postMessage('ping'); // 워커스레드에게 메세지를 보낸다.
235
+ // } else { // 워커스레드
236
+ // parentPort.on('message', (value: any) => {
237
+ // console.log("부모로부터", value);
238
+ // parentPort.postMessage('pong');
239
+ // parentPort.close(); // 워커스레드 종료라고 메인스레드에 알려줘야 exit이벤트 발생
240
+ // })
241
+ // }
242
+
243
+ //worker thrad
244
+ // const workerPath = path.join(__dirname, 'SSRWorker.js');
245
+ // const worker = new Worker(workerPath);
246
+ // worker.once('message', (value: any) => {
247
+ // console.log('워커로부터', value)
248
+ // });
249
+ // const receiveWorker = new Worker('/Users/hyunhakim/source/visualkhh/pet-space/libs/simple-boot-http-ssr/dist/filters/SSRCreatorWorker.js');
250
+ // receiveWorker.on('message', (msg: JSDOM.JSDOM)=>{
251
+ // console.log('워커로부터', msg, msg.window.document.body.innerHTML)
252
+ // console.log('a message is sent! : ', msg)
253
+ //
254
+ // });
255
+ //
256
+ // receiveWorker.on('error', err=>{
257
+ // console.error(err);
258
+ // })
259
+ //
260
+ // receiveWorker.on('exit', ()=>console.log('exited!'));
261
+ // receiveWorker.postMessage(
262
+ // {
263
+ // frontDistPath: this.factory.frontDistPath,
264
+ // frontDistIndexFileName: this.factory.frontDistIndexFileName,
265
+ // }
266
+ // );
267
+
268
+ // const myWorkers = this.workerTs({});
269
+ // myWorkers.postMessage(this);
270
+ // myWorkers.on('message', (value: SimpleBootFront) => {
271
+ // this.pushQueue(value);
272
+ // })
273
+ // this
274
+ // this.pushQueue(simpleBootFront).then(it => {
275
+ // console.log('deee')
276
+ // });
277
+ // console.log('-1->', simpleBootFront.option.window.location.href);
278
+ // simpleBootFront.option.window.location.href = this.welcomUrl;
279
+ // simpleBootFront.option.window.location.reload();
280
+ // console.log('-2->', simpleBootFront.option.window.location.href);
281
+ // simpleBootFront.option.window.location.reload();
282
+ // console.log('-3->', simpleBootFront.option.window.location.href);
283
+ // this.simpleBootFrontQueue.enqueue(simpleBootFront);
284
+ // await this.makeJsdom();
285
+ // simpleBootFront.option.window.location.href = this.welcomUrl;
286
+ }
287
+ // console.log('----doen')
288
+ return false;
289
+ } else {
290
+ // console.log('----doen2')
291
+ return true;
292
+ }
293
+ }
294
+
295
+ // const e = Expression.Path.pathNameData(rr.reqUrlPathName, intent.getRouterPath())
296
+ // console.log('------intent', rr.reqUrl, rr.reqUrlPathName, intent.module, intent.getRouterPath(), e)
297
+ // simpleBootFront.option.window.document.documentElemenh
298
+ // "dr-"로 시작하는 모든 attribute를 가진 element에서 해당 attribute를 제거
299
+
300
+ makeHTML(simpleBootFront: SimpleBootFront) {
301
+ (simpleBootFront.option.window as any).document.querySelectorAll('*').forEach((el:HTMLElement )=> {
302
+ Array.from(el.attributes).forEach(attr => {
303
+ if (/^dr-/.test(attr.name) || /^domstyle/.test(attr.name) || /this-path/.test(attr.name)) {
304
+ el.removeAttribute(attr.name);
305
+ }
306
+ });
307
+ });
308
+ let html = simpleBootFront.option.window.document.documentElement.outerHTML;
309
+ html = '<!DOCTYPE html>' + html;
310
+ html = html.replace(/\$\{[\s\S]*?\}\$/g, '');
311
+ const serverSideData = (simpleBootFront.option.window as any).server_side_data;
312
+ if (serverSideData) {
313
+ const data = Object.entries(serverSideData)
314
+ .map(([k, v]) => {
315
+ if (typeof v === 'string') {
316
+ return `window.server_side_data.${k} = ${v}`;
317
+ } else {
318
+ return `window.server_side_data.${k} = ${JSON.stringify(v)}`;
319
+ }
320
+ })
321
+ .join(';');
322
+ if (data) {
323
+ html = html.replace('</head>', `<script> window.server_side_data={}; ${data}; </script></head>`);
324
+ }
325
+ }
326
+ return html;
327
+ }
328
+ async writeOkHtmlAndEnd({ rr, status = HttpStatus.Ok }: { rr: RequestResponse; status?: HttpStatus }, html: string) {
329
+ // rr.res.writeHead(status, {[HttpHeaders.ContentType]: Mimes.TextHtml});
330
+ rr.resStatusCode(status);
331
+ rr.resSetHeader(HttpHeaders.ContentType, Mimes.TextHtml);
332
+ await rr.resEnd(html);
333
+ }
334
+
335
+ async proceedAfter({ rr, app }: { rr: RequestResponse; app: SimpleBootHttpServer; carrier: Map<string, any> }) {
336
+ // console.log('done--------', sw)
337
+ return true;
338
+ }
339
+ }