egg 3.26.1 → 4.0.0-beta.0

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 (196) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +6 -5
  3. package/dist/commonjs/agent.d.ts +4 -0
  4. package/dist/commonjs/agent.js +10 -0
  5. package/dist/commonjs/app/middleware/body_parser.d.ts +2 -0
  6. package/dist/commonjs/app/middleware/body_parser.js +8 -0
  7. package/dist/commonjs/app/middleware/meta.d.ts +11 -0
  8. package/dist/commonjs/app/middleware/meta.js +22 -0
  9. package/dist/commonjs/app/middleware/notfound.d.ts +8 -0
  10. package/dist/commonjs/app/middleware/notfound.js +31 -0
  11. package/dist/commonjs/app/middleware/override_method.d.ts +2 -0
  12. package/dist/commonjs/app/middleware/override_method.js +8 -0
  13. package/dist/commonjs/app/middleware/site_file.d.ts +7 -0
  14. package/dist/commonjs/app/middleware/site_file.js +40 -0
  15. package/dist/commonjs/config/config.default.d.ts +9 -0
  16. package/dist/commonjs/config/config.default.js +378 -0
  17. package/dist/commonjs/config/config.local.d.ts +8 -0
  18. package/dist/commonjs/config/config.local.js +12 -0
  19. package/dist/commonjs/config/config.unittest.d.ts +7 -0
  20. package/dist/commonjs/config/config.unittest.js +11 -0
  21. package/dist/commonjs/config/plugin.d.ts +122 -0
  22. package/dist/commonjs/config/plugin.js +125 -0
  23. package/dist/commonjs/index.d.ts +61 -0
  24. package/dist/commonjs/index.js +89 -0
  25. package/dist/commonjs/lib/agent.d.ts +19 -0
  26. package/dist/commonjs/lib/agent.js +58 -0
  27. package/dist/commonjs/lib/application.d.ts +66 -0
  28. package/dist/commonjs/lib/application.js +281 -0
  29. package/dist/commonjs/lib/core/base_context_class.d.ts +14 -0
  30. package/dist/commonjs/lib/core/base_context_class.js +22 -0
  31. package/dist/commonjs/lib/core/base_context_logger.d.ts +36 -0
  32. package/dist/commonjs/lib/core/base_context_logger.js +64 -0
  33. package/dist/commonjs/lib/core/base_hook_class.d.ts +11 -0
  34. package/dist/commonjs/lib/core/base_hook_class.js +30 -0
  35. package/dist/commonjs/lib/core/context_httpclient.d.ts +16 -0
  36. package/dist/commonjs/lib/core/context_httpclient.js +30 -0
  37. package/dist/commonjs/lib/core/httpclient.d.ts +14 -0
  38. package/dist/commonjs/lib/core/httpclient.js +40 -0
  39. package/dist/commonjs/lib/core/logger.d.ts +3 -0
  40. package/dist/commonjs/lib/core/logger.js +40 -0
  41. package/dist/commonjs/lib/core/messenger/IMessenger.d.ts +50 -0
  42. package/dist/commonjs/lib/core/messenger/IMessenger.js +3 -0
  43. package/dist/commonjs/lib/core/messenger/index.d.ts +7 -0
  44. package/dist/commonjs/lib/core/messenger/index.js +14 -0
  45. package/dist/commonjs/lib/core/messenger/ipc.d.ts +57 -0
  46. package/dist/commonjs/lib/core/messenger/ipc.js +126 -0
  47. package/dist/commonjs/lib/core/messenger/local.d.ts +61 -0
  48. package/dist/commonjs/lib/core/messenger/local.js +134 -0
  49. package/dist/commonjs/lib/core/singleton.d.ts +23 -0
  50. package/dist/commonjs/lib/core/singleton.js +120 -0
  51. package/dist/commonjs/lib/core/utils.d.ts +2 -0
  52. package/dist/commonjs/lib/core/utils.js +77 -0
  53. package/dist/commonjs/lib/egg.d.ts +267 -0
  54. package/dist/commonjs/lib/egg.js +595 -0
  55. package/dist/commonjs/lib/loader/AgentWorkerLoader.d.ts +12 -0
  56. package/dist/commonjs/lib/loader/AgentWorkerLoader.js +24 -0
  57. package/dist/commonjs/lib/loader/AppWorkerLoader.d.ts +17 -0
  58. package/dist/commonjs/lib/loader/AppWorkerLoader.js +43 -0
  59. package/dist/commonjs/lib/loader/EggApplicationLoader.d.ts +4 -0
  60. package/dist/commonjs/lib/loader/EggApplicationLoader.js +8 -0
  61. package/dist/commonjs/lib/loader/index.d.ts +3 -0
  62. package/dist/commonjs/lib/loader/index.js +22 -0
  63. package/dist/commonjs/lib/start.d.ts +15 -0
  64. package/dist/commonjs/lib/start.js +49 -0
  65. package/dist/commonjs/lib/type.d.ts +295 -0
  66. package/dist/commonjs/lib/type.js +3 -0
  67. package/dist/commonjs/package.json +3 -0
  68. package/dist/esm/agent.d.ts +4 -0
  69. package/dist/esm/agent.js +7 -0
  70. package/dist/esm/app/middleware/body_parser.d.ts +2 -0
  71. package/dist/esm/app/middleware/body_parser.js +3 -0
  72. package/dist/esm/app/middleware/meta.d.ts +11 -0
  73. package/dist/esm/app/middleware/meta.js +20 -0
  74. package/dist/esm/app/middleware/notfound.d.ts +8 -0
  75. package/dist/esm/app/middleware/notfound.js +29 -0
  76. package/dist/esm/app/middleware/override_method.d.ts +2 -0
  77. package/dist/esm/app/middleware/override_method.js +3 -0
  78. package/dist/esm/app/middleware/site_file.d.ts +7 -0
  79. package/dist/esm/app/middleware/site_file.js +35 -0
  80. package/dist/esm/config/config.default.d.ts +9 -0
  81. package/dist/esm/config/config.default.js +373 -0
  82. package/dist/esm/config/config.local.d.ts +8 -0
  83. package/dist/esm/config/config.local.js +10 -0
  84. package/dist/esm/config/config.unittest.d.ts +7 -0
  85. package/dist/esm/config/config.unittest.js +9 -0
  86. package/dist/esm/config/favicon.png +0 -0
  87. package/dist/esm/config/plugin.d.ts +122 -0
  88. package/dist/esm/config/plugin.js +123 -0
  89. package/dist/esm/index.d.ts +61 -0
  90. package/dist/esm/index.js +65 -0
  91. package/dist/esm/lib/agent.d.ts +19 -0
  92. package/dist/esm/lib/agent.js +54 -0
  93. package/dist/esm/lib/application.d.ts +66 -0
  94. package/dist/esm/lib/application.js +274 -0
  95. package/dist/esm/lib/core/base_context_class.d.ts +14 -0
  96. package/dist/esm/lib/core/base_context_class.js +18 -0
  97. package/dist/esm/lib/core/base_context_logger.d.ts +36 -0
  98. package/dist/esm/lib/core/base_context_logger.js +60 -0
  99. package/dist/esm/lib/core/base_hook_class.d.ts +11 -0
  100. package/dist/esm/lib/core/base_hook_class.js +23 -0
  101. package/dist/esm/lib/core/context_httpclient.d.ts +16 -0
  102. package/dist/esm/lib/core/context_httpclient.js +26 -0
  103. package/dist/esm/lib/core/httpclient.d.ts +14 -0
  104. package/dist/esm/lib/core/httpclient.js +33 -0
  105. package/dist/esm/lib/core/logger.d.ts +3 -0
  106. package/dist/esm/lib/core/logger.js +37 -0
  107. package/dist/esm/lib/core/messenger/IMessenger.d.ts +50 -0
  108. package/dist/esm/lib/core/messenger/IMessenger.js +2 -0
  109. package/dist/esm/lib/core/messenger/index.d.ts +7 -0
  110. package/dist/esm/lib/core/messenger/index.js +11 -0
  111. package/dist/esm/lib/core/messenger/ipc.d.ts +57 -0
  112. package/dist/esm/lib/core/messenger/ipc.js +119 -0
  113. package/dist/esm/lib/core/messenger/local.d.ts +61 -0
  114. package/dist/esm/lib/core/messenger/local.js +127 -0
  115. package/dist/esm/lib/core/singleton.d.ts +23 -0
  116. package/dist/esm/lib/core/singleton.js +113 -0
  117. package/dist/esm/lib/core/utils.d.ts +2 -0
  118. package/dist/esm/lib/core/utils.js +70 -0
  119. package/dist/esm/lib/egg.d.ts +267 -0
  120. package/dist/esm/lib/egg.js +565 -0
  121. package/dist/esm/lib/loader/AgentWorkerLoader.d.ts +12 -0
  122. package/dist/esm/lib/loader/AgentWorkerLoader.js +20 -0
  123. package/dist/esm/lib/loader/AppWorkerLoader.d.ts +17 -0
  124. package/dist/esm/lib/loader/AppWorkerLoader.js +39 -0
  125. package/dist/esm/lib/loader/EggApplicationLoader.d.ts +4 -0
  126. package/dist/esm/lib/loader/EggApplicationLoader.js +4 -0
  127. package/dist/esm/lib/loader/index.d.ts +3 -0
  128. package/dist/esm/lib/loader/index.js +4 -0
  129. package/dist/esm/lib/start.d.ts +15 -0
  130. package/dist/esm/lib/start.js +43 -0
  131. package/dist/esm/lib/type.d.ts +295 -0
  132. package/dist/esm/lib/type.js +2 -0
  133. package/dist/esm/package.json +3 -0
  134. package/dist/package.json +4 -0
  135. package/package.json +83 -70
  136. package/src/agent.ts +7 -0
  137. package/src/app/middleware/body_parser.ts +3 -0
  138. package/{app/middleware/meta.js → src/app/middleware/meta.ts} +12 -4
  139. package/{app/middleware/notfound.js → src/app/middleware/notfound.ts} +9 -3
  140. package/src/app/middleware/override_method.ts +3 -0
  141. package/src/app/middleware/site_file.ts +49 -0
  142. package/{config/config.default.js → src/config/config.default.ts} +21 -42
  143. package/src/config/config.local.ts +11 -0
  144. package/src/config/config.unittest.ts +10 -0
  145. package/src/config/favicon.png +0 -0
  146. package/{config/plugin.js → src/config/plugin.ts} +1 -3
  147. package/src/index.ts +78 -0
  148. package/src/lib/agent.ts +66 -0
  149. package/{lib/application.js → src/lib/application.ts} +79 -120
  150. package/src/lib/core/base_context_class.ts +21 -0
  151. package/src/lib/core/base_context_logger.ts +67 -0
  152. package/src/lib/core/base_hook_class.ts +30 -0
  153. package/src/lib/core/context_httpclient.ts +33 -0
  154. package/src/lib/core/httpclient.ts +52 -0
  155. package/src/lib/core/logger.ts +42 -0
  156. package/src/lib/core/messenger/IMessenger.ts +58 -0
  157. package/src/lib/core/messenger/index.ts +15 -0
  158. package/{lib/core/messenger/ipc.js → src/lib/core/messenger/ipc.ts} +25 -29
  159. package/{lib/core/messenger/local.js → src/lib/core/messenger/local.ts} +27 -21
  160. package/{lib/core/singleton.js → src/lib/core/singleton.ts} +56 -33
  161. package/src/lib/core/utils.ts +77 -0
  162. package/{lib/egg.js → src/lib/egg.ts} +252 -218
  163. package/src/lib/loader/AgentWorkerLoader.ts +21 -0
  164. package/src/lib/loader/AppWorkerLoader.ts +42 -0
  165. package/src/lib/loader/EggApplicationLoader.ts +5 -0
  166. package/src/lib/loader/index.ts +3 -0
  167. package/src/lib/start.ts +56 -0
  168. package/src/lib/type.ts +329 -0
  169. package/agent.js +0 -11
  170. package/app/middleware/body_parser.js +0 -3
  171. package/app/middleware/override_method.js +0 -3
  172. package/app/middleware/site_file.js +0 -31
  173. package/config/config.local.js +0 -7
  174. package/config/config.unittest.js +0 -8
  175. package/index.d.ts +0 -1285
  176. package/index.js +0 -68
  177. package/lib/agent.js +0 -95
  178. package/lib/core/base_context_class.js +0 -20
  179. package/lib/core/base_context_logger.js +0 -64
  180. package/lib/core/base_hook_class.js +0 -31
  181. package/lib/core/context_httpclient.js +0 -26
  182. package/lib/core/dnscache_httpclient.js +0 -93
  183. package/lib/core/httpclient.js +0 -108
  184. package/lib/core/httpclient_next.js +0 -45
  185. package/lib/core/logger.js +0 -35
  186. package/lib/core/messenger/index.js +0 -14
  187. package/lib/core/utils.js +0 -73
  188. package/lib/loader/agent_worker_loader.js +0 -27
  189. package/lib/loader/app_worker_loader.js +0 -48
  190. package/lib/loader/index.js +0 -5
  191. package/lib/start.js +0 -39
  192. /package/{config → dist/commonjs/config}/favicon.png +0 -0
  193. /package/{app → src/app}/extend/context.js +0 -0
  194. /package/{app → src/app}/extend/helper.js +0 -0
  195. /package/{app → src/app}/extend/request.js +0 -0
  196. /package/{app → src/app}/extend/response.js +0 -0
@@ -1,15 +1,18 @@
1
- 'use strict';
2
1
 
3
- const debug = require('util').debuglog('egg:util:messenger:ipc');
4
- const is = require('is-type-of');
5
- const workerThreads = require('worker_threads');
6
- const sendmessage = require('sendmessage');
7
- const EventEmitter = require('events');
2
+ import { EventEmitter } from 'node:events';
3
+ import { debuglog } from 'node:util';
4
+ import workerThreads from 'node:worker_threads';
5
+ import sendmessage from 'sendmessage';
6
+ import type { IMessenger } from './IMessenger.js';
7
+
8
+ const debug = debuglog('egg:lib:core:messenger:ipc');
8
9
 
9
10
  /**
10
11
  * Communication between app worker and agent worker by IPC channel
11
12
  */
12
- class Messenger extends EventEmitter {
13
+ export class Messenger extends EventEmitter implements IMessenger {
14
+ readonly pid: string;
15
+ opids: string[] = [];
13
16
 
14
17
  constructor() {
15
18
  super();
@@ -17,14 +20,13 @@ class Messenger extends EventEmitter {
17
20
  // pids of agent or app managed by master
18
21
  // - retrieve app worker pids when it's an agent worker
19
22
  // - retrieve agent worker pids when it's an app worker
20
- this.opids = [];
21
23
  this.on('egg-pids', pids => {
22
24
  this.opids = pids;
23
25
  });
24
- this._onMessage = this._onMessage.bind(this);
25
- process.on('message', this._onMessage);
26
+ this.onMessage = this.onMessage.bind(this);
27
+ process.on('message', this.onMessage);
26
28
  if (!workerThreads.isMainThread) {
27
- workerThreads.parentPort.on('message', this._onMessage);
29
+ workerThreads.parentPort!.on('message', this.onMessage);
28
30
  }
29
31
  }
30
32
 
@@ -34,7 +36,7 @@ class Messenger extends EventEmitter {
34
36
  * @param {Object} data - message value
35
37
  * @return {Messenger} this
36
38
  */
37
- broadcast(action, data) {
39
+ broadcast(action: string, data?: unknown): Messenger {
38
40
  debug('[%s] broadcast %s with %j', this.pid, action, data);
39
41
  this.send(action, data, 'app');
40
42
  this.send(action, data, 'agent');
@@ -48,7 +50,7 @@ class Messenger extends EventEmitter {
48
50
  * @param {Object} data - message value
49
51
  * @return {Messenger} this
50
52
  */
51
- sendTo(pid, action, data) {
53
+ sendTo(pid: string, action: string, data?: unknown): Messenger {
52
54
  debug('[%s] send %s with %j to %s', this.pid, action, data, pid);
53
55
  sendmessage(process, {
54
56
  action,
@@ -66,10 +68,11 @@ class Messenger extends EventEmitter {
66
68
  * @param {Object} data - message value
67
69
  * @return {Messenger} this
68
70
  */
69
- sendRandom(action, data) {
71
+ sendRandom(action: string, data?: unknown): Messenger {
70
72
  /* istanbul ignore if */
71
- if (!this.opids.length) return this;
72
- const pid = random(this.opids);
73
+ if (this.opids.length === 0) return this;
74
+ const index = Math.floor(Math.random() * this.opids.length);
75
+ const pid = this.opids[index];
73
76
  this.sendTo(String(pid), action, data);
74
77
  return this;
75
78
  }
@@ -80,7 +83,7 @@ class Messenger extends EventEmitter {
80
83
  * @param {Object} data - message value
81
84
  * @return {Messenger} this
82
85
  */
83
- sendToApp(action, data) {
86
+ sendToApp(action: string, data?: unknown): Messenger {
84
87
  debug('[%s] send %s with %j to all app', this.pid, action, data);
85
88
  this.send(action, data, 'app');
86
89
  return this;
@@ -92,7 +95,7 @@ class Messenger extends EventEmitter {
92
95
  * @param {Object} data - message value
93
96
  * @return {Messenger} this
94
97
  */
95
- sendToAgent(action, data) {
98
+ sendToAgent(action: string, data?: unknown): Messenger {
96
99
  debug('[%s] send %s with %j to all agent', this.pid, action, data);
97
100
  this.send(action, data, 'agent');
98
101
  return this;
@@ -104,7 +107,7 @@ class Messenger extends EventEmitter {
104
107
  * @param {String} to - let master know how to send message
105
108
  * @return {Messenger} this
106
109
  */
107
- send(action, data, to) {
110
+ send(action: string, data: unknown | undefined, to: string): Messenger {
108
111
  sendmessage(process, {
109
112
  action,
110
113
  data,
@@ -113,8 +116,8 @@ class Messenger extends EventEmitter {
113
116
  return this;
114
117
  }
115
118
 
116
- _onMessage(message) {
117
- if (message && is.string(message.action)) {
119
+ onMessage(message: any) {
120
+ if (typeof message?.action === 'string') {
118
121
  debug('[%s] got message %s with %j, receiverPid: %s',
119
122
  this.pid, message.action, message.data, message.receiverPid);
120
123
  this.emit(message.action, message.data);
@@ -122,7 +125,7 @@ class Messenger extends EventEmitter {
122
125
  }
123
126
 
124
127
  close() {
125
- process.removeListener('message', this._onMessage);
128
+ process.removeListener('message', this.onMessage);
126
129
  this.removeAllListeners();
127
130
  }
128
131
 
@@ -132,10 +135,3 @@ class Messenger extends EventEmitter {
132
135
  * @param {Object} data - message value
133
136
  */
134
137
  }
135
-
136
- module.exports = Messenger;
137
-
138
- function random(arr) {
139
- const index = Math.floor(Math.random() * arr.length);
140
- return arr[index];
141
- }
@@ -1,17 +1,21 @@
1
- 'use strict';
1
+ import { debuglog } from 'node:util';
2
+ import EventEmitter from 'node:events';
3
+ import type { IMessenger } from './IMessenger.js';
4
+ import type { EggApplicationCore } from '../../egg.js';
2
5
 
3
- const debug = require('util').debuglog('egg:util:messenger:local');
4
- const is = require('is-type-of');
5
- const EventEmitter = require('events');
6
+ const debug = debuglog('egg:lib:core:messenger:local');
6
7
 
7
8
  /**
8
9
  * Communication between app worker and agent worker with EventEmitter
9
10
  */
10
- class Messenger extends EventEmitter {
11
+ export class Messenger extends EventEmitter implements IMessenger {
12
+ readonly pid: string;
13
+ readonly egg: EggApplicationCore;
11
14
 
12
- constructor(egg) {
15
+ constructor(egg: EggApplicationCore) {
13
16
  super();
14
17
  this.egg = egg;
18
+ this.pid = String(process.pid);
15
19
  }
16
20
 
17
21
  /**
@@ -20,7 +24,7 @@ class Messenger extends EventEmitter {
20
24
  * @param {Object} data - message value
21
25
  * @return {Messenger} this
22
26
  */
23
- broadcast(action, data) {
27
+ broadcast(action: string, data?: unknown): Messenger {
24
28
  debug('[%s] broadcast %s with %j', this.pid, action, data);
25
29
  this.send(action, data, 'both');
26
30
  return this;
@@ -35,9 +39,11 @@ class Messenger extends EventEmitter {
35
39
  * @param {Object} data - message value
36
40
  * @return {Messenger} this
37
41
  */
38
- sendTo(pid, action, data) {
42
+ sendTo(pid: string, action: string, data?: unknown): Messenger {
39
43
  debug('[%s] send %s with %j to %s', this.pid, action, data, pid);
40
- if (pid !== process.pid) return this;
44
+ if (String(pid) !== this.pid) {
45
+ return this;
46
+ }
41
47
  this.send(action, data, 'both');
42
48
  return this;
43
49
  }
@@ -51,7 +57,7 @@ class Messenger extends EventEmitter {
51
57
  * @param {Object} data - message value
52
58
  * @return {Messenger} this
53
59
  */
54
- sendRandom(action, data) {
60
+ sendRandom(action: string, data?: unknown): Messenger {
55
61
  debug('[%s] send %s with %j to opposite', this.pid, action, data);
56
62
  this.send(action, data, 'opposite');
57
63
  return this;
@@ -63,7 +69,7 @@ class Messenger extends EventEmitter {
63
69
  * @param {Object} data - message value
64
70
  * @return {Messenger} this
65
71
  */
66
- sendToApp(action, data) {
72
+ sendToApp(action: string, data?: unknown): Messenger {
67
73
  debug('[%s] send %s with %j to all app', this.pid, action, data);
68
74
  this.send(action, data, 'application');
69
75
  return this;
@@ -75,7 +81,7 @@ class Messenger extends EventEmitter {
75
81
  * @param {Object} data - message value
76
82
  * @return {Messenger} this
77
83
  */
78
- sendToAgent(action, data) {
84
+ sendToAgent(action: string, data?: unknown): Messenger {
79
85
  debug('[%s] send %s with %j to all agent', this.pid, action, data);
80
86
  this.send(action, data, 'agent');
81
87
  return this;
@@ -87,7 +93,7 @@ class Messenger extends EventEmitter {
87
93
  * @param {String} to - let master know how to send message
88
94
  * @return {Messenger} this
89
95
  */
90
- send(action, data, to) {
96
+ send(action: string, data: unknown | undefined, to: string): Messenger {
91
97
  // use nextTick to keep it async as IPC messenger
92
98
  process.nextTick(() => {
93
99
  const { egg } = this;
@@ -104,24 +110,26 @@ class Messenger extends EventEmitter {
104
110
  application = egg.application;
105
111
  opposite = application;
106
112
  }
107
- if (!to) to = egg.type === 'application' ? 'agent' : 'application';
113
+ if (!to) {
114
+ to = egg.type === 'application' ? 'agent' : 'application';
115
+ }
108
116
 
109
117
  if (application && application.messenger && (to === 'application' || to === 'both')) {
110
- application.messenger._onMessage({ action, data });
118
+ application.messenger.onMessage({ action, data });
111
119
  }
112
120
  if (agent && agent.messenger && (to === 'agent' || to === 'both')) {
113
- agent.messenger._onMessage({ action, data });
121
+ agent.messenger.onMessage({ action, data });
114
122
  }
115
123
  if (opposite && opposite.messenger && to === 'opposite') {
116
- opposite.messenger._onMessage({ action, data });
124
+ opposite.messenger.onMessage({ action, data });
117
125
  }
118
126
  });
119
127
 
120
128
  return this;
121
129
  }
122
130
 
123
- _onMessage(message) {
124
- if (message && is.string(message.action)) {
131
+ onMessage(message: any) {
132
+ if (typeof message?.action === 'string') {
125
133
  debug('[%s] got message %s with %j', this.pid, message.action, message.data);
126
134
  this.emit(message.action, message.data);
127
135
  }
@@ -137,5 +145,3 @@ class Messenger extends EventEmitter {
137
145
  * @param {Object} data - message value
138
146
  */
139
147
  }
140
-
141
- module.exports = Messenger;
@@ -1,36 +1,48 @@
1
- 'use strict';
1
+ import assert from 'node:assert';
2
+ import { isAsyncFunction } from 'is-type-of';
3
+ import type { EggApplicationCore } from '../egg.js';
2
4
 
3
- const assert = require('assert');
4
- const is = require('is-type-of');
5
+ export type SingletonCreateMethod =
6
+ (config: Record<string, any>, app: EggApplicationCore, clientName: string) => unknown | Promise<unknown>;
5
7
 
6
- class Singleton {
7
- constructor(options = {}) {
8
+ export interface SingletonOptions {
9
+ name: string;
10
+ app: EggApplicationCore;
11
+ create: SingletonCreateMethod;
12
+ }
13
+
14
+ export class Singleton {
15
+ readonly clients = new Map<string, any>();
16
+ readonly app: EggApplicationCore;
17
+ readonly create: SingletonCreateMethod;
18
+ readonly name: string;
19
+ readonly options: Record<string, any>;
20
+
21
+ constructor(options: SingletonOptions) {
8
22
  assert(options.name, '[egg:singleton] Singleton#constructor options.name is required');
9
23
  assert(options.app, '[egg:singleton] Singleton#constructor options.app is required');
10
24
  assert(options.create, '[egg:singleton] Singleton#constructor options.create is required');
11
- assert(!options.app[options.name], `${options.name} is already exists in app`);
12
- this.clients = new Map();
25
+ assert(!(options.name in options.app), `[egg:singleton] ${options.name} is already exists in app`);
13
26
  this.app = options.app;
14
27
  this.name = options.name;
15
28
  this.create = options.create;
16
- /* istanbul ignore next */
17
- this.options = options.app.config[this.name] || {};
29
+ this.options = options.app.config[this.name] ?? {};
18
30
  }
19
31
 
20
32
  init() {
21
- return is.asyncFunction(this.create) ? this.initAsync() : this.initSync();
33
+ return isAsyncFunction(this.create) ? this.initAsync() : this.initSync();
22
34
  }
23
35
 
24
36
  initSync() {
25
37
  const options = this.options;
26
38
  assert(!(options.client && options.clients),
27
- `egg:singleton ${this.name} can not set options.client and options.clients both`);
39
+ `[egg:singleton] ${this.name} can not set options.client and options.clients both`);
28
40
 
29
41
  // alias app[name] as client, but still support createInstance method
30
42
  if (options.client) {
31
43
  const client = this.createInstance(options.client, options.name);
32
- this.app[this.name] = client;
33
- this._extendDynamicMethods(client);
44
+ this.#setClientToApp(client);
45
+ this.#extendDynamicMethods(client);
34
46
  return;
35
47
  }
36
48
 
@@ -40,66 +52,76 @@ class Singleton {
40
52
  const client = this.createInstance(options.clients[id], id);
41
53
  this.clients.set(id, client);
42
54
  });
43
- this.app[this.name] = this;
55
+ this.#setClientToApp(this);
44
56
  return;
45
57
  }
46
58
 
47
59
  // no config.clients and config.client
48
- this.app[this.name] = this;
60
+ this.#setClientToApp(this);
49
61
  }
50
62
 
51
63
  async initAsync() {
52
64
  const options = this.options;
53
65
  assert(!(options.client && options.clients),
54
- `egg:singleton ${this.name} can not set options.client and options.clients both`);
66
+ `[egg:singleton] ${this.name} can not set options.client and options.clients both`);
55
67
 
56
68
  // alias app[name] as client, but still support createInstance method
57
69
  if (options.client) {
58
70
  const client = await this.createInstanceAsync(options.client, options.name);
59
- this.app[this.name] = client;
60
- this._extendDynamicMethods(client);
71
+ this.#setClientToApp(client);
72
+ this.#extendDynamicMethods(client);
61
73
  return;
62
74
  }
63
75
 
64
76
  // multi client, use app[name].getInstance(id)
65
77
  if (options.clients) {
66
- await Promise.all(Object.keys(options.clients).map(id => {
78
+ await Promise.all(Object.keys(options.clients).map((id: string) => {
67
79
  return this.createInstanceAsync(options.clients[id], id)
68
80
  .then(client => this.clients.set(id, client));
69
81
  }));
70
- this.app[this.name] = this;
82
+ this.#setClientToApp(this);
71
83
  return;
72
84
  }
73
85
 
74
86
  // no config.clients and config.client
75
- this.app[this.name] = this;
87
+ this.#setClientToApp(this);
76
88
  }
77
89
 
78
- get(id) {
90
+ #setClientToApp(client: unknown) {
91
+ Reflect.set(this.app, this.name, client);
92
+ }
93
+
94
+ get(id: string) {
79
95
  return this.clients.get(id);
80
96
  }
81
97
 
82
98
  // alias to `get(id)`
83
- getSingletonInstance(id) {
99
+ getSingletonInstance(id: string) {
84
100
  return this.clients.get(id);
85
101
  }
86
102
 
87
- createInstance(config, clientName) {
103
+ createInstance(config: Record<string, any>, clientName: string) {
88
104
  // async creator only support createInstanceAsync
89
- assert(!is.asyncFunction(this.create),
105
+ assert(!isAsyncFunction(this.create),
90
106
  `egg:singleton ${this.name} only support create asynchronous, please use createInstanceAsync`);
91
107
  // options.default will be merge in to options.clients[id]
92
- config = Object.assign({}, this.options.default, config);
93
- return this.create(config, this.app, clientName);
108
+ config = {
109
+ ...this.options.default,
110
+ ...config,
111
+ };
112
+ return (this.create as SingletonCreateMethod)(config, this.app, clientName);
94
113
  }
95
114
 
96
- async createInstanceAsync(config, clientName) {
115
+ async createInstanceAsync(config: Record<string, any>, clientName: string) {
97
116
  // options.default will be merge in to options.clients[id]
98
- config = Object.assign({}, this.options.default, config);
117
+ config = {
118
+ ...this.options.default,
119
+ ...config,
120
+ };
99
121
  return await this.create(config, this.app, clientName);
100
122
  }
101
123
 
102
- _extendDynamicMethods(client) {
124
+ #extendDynamicMethods(client: any) {
103
125
  assert(!client.createInstance, 'singleton instance should not have createInstance method');
104
126
  assert(!client.createInstanceAsync, 'singleton instance should not have createInstanceAsync method');
105
127
 
@@ -113,9 +135,10 @@ class Singleton {
113
135
  extendable.createInstance = this.createInstance.bind(this);
114
136
  extendable.createInstanceAsync = this.createInstanceAsync.bind(this);
115
137
  } catch (err) {
116
- this.app.logger.warn('egg:singleton %s dynamic create is disabled because of client is unextensible', this.name);
138
+ this.app.coreLogger.warn(
139
+ '[egg:singleton] %s dynamic create is disabled because of client is un-extendable',
140
+ this.name);
141
+ this.app.coreLogger.warn(err);
117
142
  }
118
143
  }
119
144
  }
120
-
121
- module.exports = Singleton;
@@ -0,0 +1,77 @@
1
+ import util from 'node:util';
2
+ import {
3
+ isSymbol, isRegExp, isPrimitive,
4
+ isClass, isFunction, isGeneratorFunction, isAsyncFunction,
5
+ } from 'is-type-of';
6
+
7
+ export function convertObject(obj: any, ignore: string | RegExp | (string | RegExp)[]) {
8
+ if (!Array.isArray(ignore)) {
9
+ ignore = [ ignore ];
10
+ }
11
+ for (const key of Object.keys(obj)) {
12
+ obj[key] = convertValue(key, obj[key], ignore);
13
+ }
14
+ return obj;
15
+ }
16
+
17
+ function convertValue(key: string, value: any, ignore: (string | RegExp)[]) {
18
+ if (value === null || value === undefined) {
19
+ return value;
20
+ }
21
+
22
+ let hit = false;
23
+ for (const matchKey of ignore) {
24
+ if (typeof matchKey === 'string' && matchKey === key) {
25
+ hit = true;
26
+ break;
27
+ } else if (isRegExp(matchKey) && matchKey.test(key)) {
28
+ hit = true;
29
+ break;
30
+ }
31
+ }
32
+ if (!hit) {
33
+ if (isSymbol(value) || isRegExp(value)) {
34
+ return value.toString();
35
+ }
36
+ if (isPrimitive(value) || Array.isArray(value)) {
37
+ return value;
38
+ }
39
+ }
40
+
41
+ // only convert recursively when it's a plain object,
42
+ // o = {}
43
+ if (Object.getPrototypeOf(value) === Object.prototype) {
44
+ return convertObject(value, ignore);
45
+ }
46
+
47
+ // support class
48
+ const name = value.name || 'anonymous';
49
+ if (isClass(value)) {
50
+ return `<Class ${name}>`;
51
+ }
52
+
53
+ // support generator function
54
+ if (isFunction(value)) {
55
+ if (isGeneratorFunction(value)) return `<GeneratorFunction ${name}>`;
56
+ if (isAsyncFunction(value)) return `<AsyncFunction ${name}>`;
57
+ return `<Function ${name}>`;
58
+ }
59
+
60
+ const typeName = value.constructor.name;
61
+ if (typeName) {
62
+ if (Buffer.isBuffer(value) || typeof value === 'string') {
63
+ return `<${typeName} len: ${value.length}>`;
64
+ }
65
+ return `<${typeName}>`;
66
+ }
67
+
68
+ return util.format(value);
69
+ }
70
+
71
+ export function safeParseURL(url: string) {
72
+ try {
73
+ return new URL(url);
74
+ } catch {
75
+ return null;
76
+ }
77
+ }