phecda-server 5.1.0 → 5.1.1

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 (153) hide show
  1. package/README.md +10 -10
  2. package/bin/cli.mjs +189 -189
  3. package/bin/schema.json +55 -55
  4. package/dist/{chunk-OTHER3YM.mjs → chunk-2HKQPZDT.mjs} +1 -2
  5. package/dist/{chunk-GHOKWS5V.js → chunk-3BV2GRS7.js} +38 -39
  6. package/dist/{chunk-BZP6GKM6.mjs → chunk-665MB62T.mjs} +1 -2
  7. package/dist/{chunk-QG4X6H5Y.js → chunk-FSBD5R22.js} +65 -66
  8. package/dist/{chunk-423JPSEB.js → chunk-HMPTPTFL.js} +17 -18
  9. package/dist/{chunk-6MQP6OHU.mjs → chunk-UU6RHGRF.mjs} +2 -3
  10. package/dist/{chunk-4YVAW3L4.mjs → chunk-VLV3AO3H.mjs} +0 -1
  11. package/dist/{chunk-Z4YJHEXT.js → chunk-ZP7HNASU.js} +0 -1
  12. package/dist/index.js +39 -40
  13. package/dist/index.mjs +4 -5
  14. package/dist/rpc/bullmq/index.js +12 -13
  15. package/dist/rpc/bullmq/index.mjs +2 -3
  16. package/dist/rpc/kafka/index.js +10 -11
  17. package/dist/rpc/kafka/index.mjs +2 -3
  18. package/dist/rpc/nats/index.js +11 -12
  19. package/dist/rpc/nats/index.mjs +2 -3
  20. package/dist/rpc/rabbitmq/index.js +13 -14
  21. package/dist/rpc/rabbitmq/index.mjs +2 -3
  22. package/dist/rpc/redis/index.js +11 -12
  23. package/dist/rpc/redis/index.mjs +2 -3
  24. package/dist/server/elysia/index.js +20 -21
  25. package/dist/server/elysia/index.mjs +3 -4
  26. package/dist/server/express/index.js +18 -19
  27. package/dist/server/express/index.mjs +2 -3
  28. package/dist/server/fastify/index.js +19 -20
  29. package/dist/server/fastify/index.mjs +3 -4
  30. package/dist/server/h3/index.js +16 -17
  31. package/dist/server/h3/index.mjs +2 -3
  32. package/dist/server/hono/index.js +17 -18
  33. package/dist/server/hono/index.mjs +2 -3
  34. package/dist/server/hyper-express/index.js +17 -18
  35. package/dist/server/hyper-express/index.mjs +2 -3
  36. package/dist/server/koa/index.js +18 -19
  37. package/dist/server/koa/index.mjs +2 -3
  38. package/dist/test.js +6 -7
  39. package/dist/test.mjs +2 -3
  40. package/package.json +2 -2
  41. package/register/index.mjs +40 -40
  42. package/register/loader.mjs +354 -341
  43. package/register/utils.mjs +81 -81
  44. package/dist/chunk-423JPSEB.js.map +0 -1
  45. package/dist/chunk-4R55T3HG.js +0 -253
  46. package/dist/chunk-4R55T3HG.js.map +0 -1
  47. package/dist/chunk-4YVAW3L4.mjs.map +0 -1
  48. package/dist/chunk-5DOVDDO7.mjs +0 -295
  49. package/dist/chunk-5DOVDDO7.mjs.map +0 -1
  50. package/dist/chunk-5WQ2SMIK.js +0 -295
  51. package/dist/chunk-5WQ2SMIK.js.map +0 -1
  52. package/dist/chunk-6MQP6OHU.mjs.map +0 -1
  53. package/dist/chunk-6Q2PCC3A.mjs +0 -295
  54. package/dist/chunk-6Q2PCC3A.mjs.map +0 -1
  55. package/dist/chunk-6UQYEBAN.js +0 -253
  56. package/dist/chunk-6UQYEBAN.js.map +0 -1
  57. package/dist/chunk-6W7CGOZC.mjs +0 -565
  58. package/dist/chunk-6W7CGOZC.mjs.map +0 -1
  59. package/dist/chunk-7Y37NSBM.js +0 -88
  60. package/dist/chunk-7Y37NSBM.js.map +0 -1
  61. package/dist/chunk-BQBSVGMG.mjs +0 -253
  62. package/dist/chunk-BQBSVGMG.mjs.map +0 -1
  63. package/dist/chunk-BZP6GKM6.mjs.map +0 -1
  64. package/dist/chunk-C5JAHCS2.mjs +0 -88
  65. package/dist/chunk-C5JAHCS2.mjs.map +0 -1
  66. package/dist/chunk-DTBKDALR.mjs +0 -295
  67. package/dist/chunk-DTBKDALR.mjs.map +0 -1
  68. package/dist/chunk-GHOKWS5V.js.map +0 -1
  69. package/dist/chunk-H4N6SHNG.mjs +0 -76
  70. package/dist/chunk-H4N6SHNG.mjs.map +0 -1
  71. package/dist/chunk-ICYHM4UM.js +0 -565
  72. package/dist/chunk-ICYHM4UM.js.map +0 -1
  73. package/dist/chunk-LOLXPM4J.mjs +0 -529
  74. package/dist/chunk-LOLXPM4J.mjs.map +0 -1
  75. package/dist/chunk-MSS6A2TU.js +0 -585
  76. package/dist/chunk-MSS6A2TU.js.map +0 -1
  77. package/dist/chunk-NEM3FY7C.mjs +0 -537
  78. package/dist/chunk-NEM3FY7C.mjs.map +0 -1
  79. package/dist/chunk-OTHER3YM.mjs.map +0 -1
  80. package/dist/chunk-Q2FYFIEY.js +0 -295
  81. package/dist/chunk-Q2FYFIEY.js.map +0 -1
  82. package/dist/chunk-QG4X6H5Y.js.map +0 -1
  83. package/dist/chunk-QIEZ6YTG.mjs +0 -295
  84. package/dist/chunk-QIEZ6YTG.mjs.map +0 -1
  85. package/dist/chunk-QOAKHCM7.js +0 -295
  86. package/dist/chunk-QOAKHCM7.js.map +0 -1
  87. package/dist/chunk-QVUD6L5X.js +0 -565
  88. package/dist/chunk-QVUD6L5X.js.map +0 -1
  89. package/dist/chunk-RGLTGKAU.js +0 -537
  90. package/dist/chunk-RGLTGKAU.js.map +0 -1
  91. package/dist/chunk-SHRK3TVB.js +0 -295
  92. package/dist/chunk-SHRK3TVB.js.map +0 -1
  93. package/dist/chunk-TCH6S42Z.js +0 -529
  94. package/dist/chunk-TCH6S42Z.js.map +0 -1
  95. package/dist/chunk-UCGRFVHC.mjs +0 -253
  96. package/dist/chunk-UCGRFVHC.mjs.map +0 -1
  97. package/dist/chunk-VOISXWVF.mjs +0 -295
  98. package/dist/chunk-VOISXWVF.mjs.map +0 -1
  99. package/dist/chunk-W6BC5INO.mjs +0 -295
  100. package/dist/chunk-W6BC5INO.mjs.map +0 -1
  101. package/dist/chunk-X5WQRO4R.js +0 -295
  102. package/dist/chunk-X5WQRO4R.js.map +0 -1
  103. package/dist/chunk-XDMCVVD3.mjs +0 -585
  104. package/dist/chunk-XDMCVVD3.mjs.map +0 -1
  105. package/dist/chunk-XNTMYLK6.js +0 -76
  106. package/dist/chunk-XNTMYLK6.js.map +0 -1
  107. package/dist/chunk-Y6LI4FDO.js +0 -537
  108. package/dist/chunk-Y6LI4FDO.js.map +0 -1
  109. package/dist/chunk-YZ2AQ6IL.mjs +0 -537
  110. package/dist/chunk-YZ2AQ6IL.mjs.map +0 -1
  111. package/dist/chunk-Z4YJHEXT.js.map +0 -1
  112. package/dist/chunk-ZE336SKZ.js +0 -295
  113. package/dist/chunk-ZE336SKZ.js.map +0 -1
  114. package/dist/chunk-ZJD235TO.mjs +0 -565
  115. package/dist/chunk-ZJD235TO.mjs.map +0 -1
  116. package/dist/core-930ea883.d.ts +0 -131
  117. package/dist/core-eb646fe5.d.ts +0 -139
  118. package/dist/core-fd134ffa.d.ts +0 -130
  119. package/dist/helper-06d25b37.d.ts +0 -19
  120. package/dist/helper-48454c0b.d.ts +0 -20
  121. package/dist/helper-73e8d2f0.d.ts +0 -18
  122. package/dist/helper-867a598d.d.ts +0 -18
  123. package/dist/helper-88b19c66.d.ts +0 -12
  124. package/dist/helper-9e206c66.d.ts +0 -12
  125. package/dist/helper-f29f082f.d.ts +0 -19
  126. package/dist/index.js.map +0 -1
  127. package/dist/index.mjs.map +0 -1
  128. package/dist/rpc/bullmq/index.js.map +0 -1
  129. package/dist/rpc/bullmq/index.mjs.map +0 -1
  130. package/dist/rpc/kafka/index.js.map +0 -1
  131. package/dist/rpc/kafka/index.mjs.map +0 -1
  132. package/dist/rpc/nats/index.js.map +0 -1
  133. package/dist/rpc/nats/index.mjs.map +0 -1
  134. package/dist/rpc/rabbitmq/index.js.map +0 -1
  135. package/dist/rpc/rabbitmq/index.mjs.map +0 -1
  136. package/dist/rpc/redis/index.js.map +0 -1
  137. package/dist/rpc/redis/index.mjs.map +0 -1
  138. package/dist/server/elysia/index.js.map +0 -1
  139. package/dist/server/elysia/index.mjs.map +0 -1
  140. package/dist/server/express/index.js.map +0 -1
  141. package/dist/server/express/index.mjs.map +0 -1
  142. package/dist/server/fastify/index.js.map +0 -1
  143. package/dist/server/fastify/index.mjs.map +0 -1
  144. package/dist/server/h3/index.js.map +0 -1
  145. package/dist/server/h3/index.mjs.map +0 -1
  146. package/dist/server/hono/index.js.map +0 -1
  147. package/dist/server/hono/index.mjs.map +0 -1
  148. package/dist/server/hyper-express/index.js.map +0 -1
  149. package/dist/server/hyper-express/index.mjs.map +0 -1
  150. package/dist/server/koa/index.js.map +0 -1
  151. package/dist/server/koa/index.mjs.map +0 -1
  152. package/dist/test.js.map +0 -1
  153. package/dist/test.mjs.map +0 -1
@@ -1,341 +1,354 @@
1
- import { fileURLToPath, pathToFileURL } from 'url'
2
- import { writeFile } from 'fs/promises'
3
- import {
4
- basename,
5
- extname,
6
- isAbsolute,
7
- relative,
8
- resolve as resolvePath,
9
- } from 'path'
10
- import { createRequire } from 'module'
11
- import ts from 'typescript'
12
- import chokidar from 'chokidar'
13
- import { log } from '../dist/index.mjs'
14
- import { compile, genUnImportRet, handleClassTypes } from './utils.mjs'
15
-
16
- let port
17
-
18
- const isLowVersion = parseFloat(process.version.slice(1)) < 18.19
19
- // this part is important or not?
20
- const EXTENSIONS = [ts.Extension.Ts, ts.Extension.Tsx, ts.Extension.Mts]
21
- const tsconfig = {
22
- module: ts.ModuleKind.ESNext,
23
- moduleResolution: ts.ModuleResolutionKind.NodeNext,
24
- }
25
- const moduleResolutionCache = ts.createModuleResolutionCache(
26
- ts.sys.getCurrentDirectory(),
27
- x => x,
28
- tsconfig,
29
- )
30
- const host = {
31
- fileExists: ts.sys.fileExists,
32
- readFile: ts.sys.readFile,
33
- }
34
-
35
- let unimportRet
36
- const dtsPath = 'ps.d.ts'
37
-
38
- if (isLowVersion)
39
- await initialize()
40
-
41
- let config
42
- const require = createRequire(import.meta.url)
43
- export async function initialize(data) {
44
- if (data)
45
- port = data.port
46
- log('read config...')
47
-
48
- const configPath = resolvePath(
49
- process.cwd(),
50
- process.env.PS_CONFIG_FILE || 'ps.json',
51
- )
52
-
53
- config = require(configPath)
54
- if (!config.virtualFile)
55
- config.virtualFile = {}
56
-
57
- if (!process.env.PS_HMR_BAN) {
58
- chokidar.watch(configPath, { persistent: true }).on('change', () => {
59
- port.postMessage(
60
- JSON.stringify({
61
- type: 'relaunch',
62
- }),
63
- )
64
- })
65
- }
66
-
67
- if (!config.unimport)
68
- return
69
- unimportRet = await genUnImportRet(config.unimport)
70
- if (unimportRet) {
71
- log('auto import...')
72
- await unimportRet.init()
73
-
74
- writeFile(
75
- config.unimport.dtsPath || dtsPath,
76
- handleClassTypes(await unimportRet.generateTypeDeclarations()),
77
- )
78
- }
79
- }
80
-
81
- const watchFiles = new Set()
82
- const filesRecord = new Map()
83
- const moduleGraph = {}
84
-
85
- let entryUrl
86
-
87
- function addUrlToGraph(url, parent) {
88
- if (!(url in moduleGraph))
89
- moduleGraph[url] = new Set()
90
-
91
- moduleGraph[url].add(parent)
92
- return url + (filesRecord.has(url) ? `?t=${filesRecord.get(url)}` : '')
93
- }
94
-
95
- function getFileMid(file) {
96
- const filename = basename(file)
97
- const ret = filename.split('.')
98
- if (ret.length === 3)
99
- return ret[1]
100
- else return ''
101
- }
102
-
103
- export const resolve = async (specifier, context, nextResolve) => {
104
- // virtual file
105
- if (config.virtualFile[specifier]) {
106
- return {
107
- format: 'ts',
108
- url: specifier,
109
- shortCircuit: true,
110
- }
111
- }
112
- // entrypoint
113
- if (!context.parentURL) {
114
- entryUrl = specifier
115
- return {
116
- format: EXTENSIONS.some(ext => specifier.endsWith(ext))
117
- ? 'ts'
118
- : undefined,
119
- url: specifier,
120
- shortCircuit: true,
121
- }
122
- }
123
- // url import
124
- // it seems useless
125
- if (/^file:\/\/\//.test(specifier) && extname(specifier) === '.ts') {
126
- const url = addUrlToGraph(specifier, context.parentURL.split('?')[0])
127
- return {
128
- format: 'ts',
129
- url,
130
- shortCircuit: true,
131
- }
132
- }
133
-
134
- // hmr import
135
- if (
136
- context.parentURL.includes('/node_modules/phecda-server')
137
- && isAbsolute(specifier)
138
- ) {
139
- specifier = relative(fileURLToPath(entryUrl), specifier)
140
- .replace(/\.ts$/, '')
141
- .slice(1)
142
- context.parentURL = entryUrl
143
- }
144
-
145
- // import/require from external library
146
- if (context.parentURL.includes('/node_modules/'))
147
- return nextResolve(specifier)
148
- const { resolvedModule } = ts.resolveModuleName(
149
- specifier,
150
- fileURLToPath(context.parentURL),
151
- tsconfig,
152
- host,
153
- moduleResolutionCache,
154
- )
155
- // import between loacl projects
156
- if (
157
- resolvedModule
158
- && !resolvedModule.resolvedFileName.includes('/node_modules/')
159
- && EXTENSIONS.includes(resolvedModule.extension)
160
- ) {
161
- const url = addUrlToGraph(
162
- pathToFileURL(resolvedModule.resolvedFileName).href,
163
- context.parentURL.split('?')[0],
164
- )
165
-
166
- const importerMid = getFileMid(context.parentURL)
167
- const sourceMid = getFileMid(resolvedModule.resolvedFileName)
168
- if (config.resolve && importerMid && sourceMid) {
169
- const resolver = config.resolve.find(
170
- item => item.source === sourceMid && item.importer === importerMid,
171
- )
172
- if (resolver) {
173
- return {
174
- format: 'ts',
175
- url: pathToFileURL(resolvePath(process.cwd(), resolver.path)).href,
176
- shortCircuit: true,
177
- }
178
- }
179
- }
180
-
181
- return {
182
- format: 'ts',
183
- url,
184
- shortCircuit: true,
185
- }
186
- }
187
-
188
- return nextResolve(specifier)
189
- }
190
- // @todo the first params may be url or path, need to distinguish
191
-
192
- export const load = async (url, context, nextLoad) => {
193
- if (config.virtualFile[url]) {
194
- return {
195
- format: 'module',
196
- source: config.virtualFile[url],
197
- shortCircuit: true,
198
- }
199
- }
200
-
201
- url = url.split('?')[0]
202
- if (
203
- !url.includes('/node_modules/')
204
- && url.startsWith('file://')
205
- && !watchFiles.has(url)
206
- && !isLowVersion
207
- ) {
208
- watchFiles.add(url)
209
- // watch(
210
- // fileURLToPath(url),
211
- // debounce((type) => {
212
- // if (type === 'change') {
213
- // try {
214
- // const files = [...findTopScope(url, Date.now())].reverse()
215
-
216
- // port.postMessage(
217
- // JSON.stringify({
218
- // type: 'change',
219
- // files,
220
- // }),
221
- // )
222
- // }
223
- // catch (e) {
224
- // port.postMessage(
225
- // JSON.stringify({
226
- // type: 'relaunch',
227
- // }),
228
- // )
229
- // }
230
- // }
231
- // }),
232
- // )
233
-
234
- if (!process.env.PS_HMR_BAN) {
235
- chokidar.watch(fileURLToPath(url), { persistent: true }).on(
236
- 'change',
237
- debounce(() => {
238
- try {
239
- const files = [...findTopScope(url, Date.now())].reverse()
240
-
241
- port.postMessage(
242
- JSON.stringify({
243
- type: 'change',
244
- files,
245
- }),
246
- )
247
- }
248
- catch (e) {
249
- port.postMessage(
250
- JSON.stringify({
251
- type: 'relaunch',
252
- }),
253
- )
254
- }
255
- }),
256
- )
257
- }
258
- }
259
- // resolveModuleName failed
260
- // I don't know why it failed
261
- if (!context.format && url.endsWith('.ts'))
262
- context.format = 'ts'
263
-
264
- if (context.format === 'ts') {
265
- const { source } = await nextLoad(url, context)
266
-
267
- const code
268
- = typeof source === 'string' ? source : Buffer.from(source).toString()
269
- const compiled = await compile(code, url)
270
- if (unimportRet) {
271
- const { injectImports } = unimportRet
272
- return {
273
- format: 'module',
274
- source: (
275
- await injectImports(compiled, (url.startsWith('file://') ? fileURLToPath(url) : url).replace(/\\/g, '/'))
276
- ).code,
277
- shortCircuit: true,
278
- }
279
- }
280
- return {
281
- format: 'module',
282
- source: compiled,
283
- shortCircuit: true,
284
- }
285
- }
286
- else {
287
- return nextLoad(url, context)
288
- }
289
- }
290
-
291
- function findTopScope(url, time, modules = new Set()) {
292
- filesRecord.set(url, time)
293
- if (isModuleFileUrl(url)) {
294
- modules.add(fileURLToPath(url))
295
- }
296
- else {
297
- if (!moduleGraph[url])
298
- throw new Error('root file update')
299
- for (const i of [...moduleGraph[url]]) findTopScope(i, time, modules)
300
- }
301
-
302
- return modules
303
- }
304
-
305
- function debounce(cb, timeout = 500) {
306
- let timer
307
- return (...args) => {
308
- if (timer)
309
- return
310
-
311
- timer = setTimeout(() => {
312
- cb(...args)
313
- timer = undefined
314
- }, timeout)
315
- }
316
- }
317
-
318
- export function isModuleFileUrl(url) {
319
- const midName = getFileMid(url)
320
- if (!midName)
321
- return false
322
- if (
323
- [
324
- 'controller',
325
- 'rpc',
326
- 'service',
327
- 'module',
328
- 'extension',
329
- 'ext',
330
- 'guard',
331
- 'interceptor',
332
- 'plugin',
333
- 'filter',
334
- 'pipe',
335
- 'edge',
336
- ].includes(midName)
337
- )
338
- return true
339
-
340
- return config.moduleFile && config.moduleFile.includes(midName)
341
- }
1
+ import { fileURLToPath, pathToFileURL } from 'url'
2
+ import { writeFile } from 'fs/promises'
3
+ import {
4
+ basename,
5
+ extname,
6
+ isAbsolute,
7
+ relative,
8
+ resolve as resolvePath,
9
+ } from 'path'
10
+ import { createRequire } from 'module'
11
+ import ts from 'typescript'
12
+ import chokidar from 'chokidar'
13
+ import { log } from '../dist/index.mjs'
14
+ import { compile, genUnImportRet, handleClassTypes } from './utils.mjs'
15
+
16
+ let port
17
+
18
+ const isLowVersion = parseFloat(process.version.slice(1)) < 18.19
19
+ // this part is important or not?
20
+ const EXTENSIONS = [ts.Extension.Ts, ts.Extension.Tsx, ts.Extension.Mts]
21
+ const tsconfig = {
22
+ module: ts.ModuleKind.ESNext,
23
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
24
+ }
25
+ const moduleResolutionCache = ts.createModuleResolutionCache(
26
+ ts.sys.getCurrentDirectory(),
27
+ x => x,
28
+ tsconfig,
29
+ )
30
+ const host = {
31
+ fileExists: ts.sys.fileExists,
32
+ readFile: ts.sys.readFile,
33
+ }
34
+
35
+ let unimportRet
36
+ const dtsPath = 'ps.d.ts'
37
+
38
+ if (isLowVersion)
39
+ await initialize()
40
+
41
+ let config
42
+ const require = createRequire(import.meta.url)
43
+ export async function initialize(data) {
44
+ if (data)
45
+ port = data.port
46
+ log('read config...')
47
+
48
+ const configPath = resolvePath(
49
+ process.cwd(),
50
+ process.env.PS_CONFIG_FILE || 'ps.json',
51
+ )
52
+
53
+ config = require(configPath)
54
+ if (!config.virtualFile)
55
+ config.virtualFile = {}
56
+
57
+ if (!process.env.PS_HMR_BAN) {
58
+ chokidar.watch(configPath, { persistent: true }).on('change', () => {
59
+ port.postMessage(
60
+ JSON.stringify({
61
+ type: 'relaunch',
62
+ }),
63
+ )
64
+ })
65
+ }
66
+
67
+ if (!config.unimport)
68
+ return
69
+ unimportRet = await genUnImportRet(config.unimport)
70
+ if (unimportRet) {
71
+ log('auto import...')
72
+ await unimportRet.init()
73
+
74
+ writeFile(
75
+ config.unimport.dtsPath || dtsPath,
76
+ handleClassTypes(await unimportRet.generateTypeDeclarations()),
77
+ )
78
+ }
79
+ }
80
+
81
+ const watchFiles = new Set()
82
+ const filesRecord = new Map()
83
+ const moduleGraph = {}
84
+
85
+ let entryUrl
86
+
87
+ function addUrlToGraph(url, parent) {
88
+ if (!(url in moduleGraph))
89
+ moduleGraph[url] = new Set()
90
+
91
+ moduleGraph[url].add(parent)
92
+ return url + (filesRecord.has(url) ? `?t=${filesRecord.get(url)}` : '')
93
+ }
94
+
95
+ function getFileMid(file) {
96
+ const filename = basename(file)
97
+ const ret = filename.split('.')
98
+ if (ret.length === 3)
99
+ return ret[1]
100
+ else return ''
101
+ }
102
+
103
+ export const resolve = async (specifier, context, nextResolve) => {
104
+ // virtual file
105
+ if (config.virtualFile[specifier]) {
106
+ return {
107
+ format: 'ts',
108
+ url: specifier,
109
+ shortCircuit: true,
110
+ }
111
+ }
112
+ // entrypoint
113
+ if (!context.parentURL) {
114
+ entryUrl = specifier
115
+ return {
116
+ format: EXTENSIONS.some(ext => specifier.endsWith(ext))
117
+ ? 'ts'
118
+ : undefined,
119
+ url: specifier,
120
+ shortCircuit: true,
121
+ }
122
+ }
123
+ // url import
124
+ // it seems useless
125
+ if (/^file:\/\/\//.test(specifier) && extname(specifier) === '.ts') {
126
+ const url = addUrlToGraph(specifier, context.parentURL.split('?')[0])
127
+ return {
128
+ format: 'ts',
129
+ url,
130
+ shortCircuit: true,
131
+ }
132
+ }
133
+
134
+ // hmr import
135
+ if (
136
+ context.parentURL.includes('/node_modules/phecda-server')
137
+ && isAbsolute(specifier)
138
+ ) {
139
+ specifier = relative(fileURLToPath(entryUrl), specifier)
140
+ .replace(/\.ts$/, '')
141
+ .slice(1)
142
+ context.parentURL = entryUrl
143
+ }
144
+
145
+ // import/require from external library
146
+ if (context.parentURL.includes('/node_modules/'))
147
+ return nextResolve(specifier)
148
+ const { resolvedModule } = ts.resolveModuleName(
149
+ specifier,
150
+ fileURLToPath(context.parentURL),
151
+ tsconfig,
152
+ host,
153
+ moduleResolutionCache,
154
+ )
155
+
156
+ // import between loacl projects
157
+ if (
158
+ resolvedModule
159
+ && !resolvedModule.resolvedFileName.includes('/node_modules/')
160
+ && EXTENSIONS.includes(resolvedModule.extension)
161
+ ) {
162
+ const url = addUrlToGraph(
163
+ pathToFileURL(resolvedModule.resolvedFileName).href,
164
+ context.parentURL.split('?')[0],
165
+ )
166
+
167
+ const importerMid = getFileMid(context.parentURL)
168
+ const sourceMid = getFileMid(resolvedModule.resolvedFileName)
169
+ if (config.resolve && importerMid && sourceMid) {
170
+ const resolver = config.resolve.find(
171
+ item => item.source === sourceMid && item.importer === importerMid,
172
+ )
173
+ if (resolver) {
174
+ return {
175
+ format: 'ts',
176
+ url: pathToFileURL(resolvePath(process.cwd(), resolver.path)).href,
177
+ shortCircuit: true,
178
+ }
179
+ }
180
+ }
181
+
182
+ return {
183
+ format: 'ts',
184
+ url,
185
+ shortCircuit: true,
186
+ }
187
+ }
188
+
189
+ const resolveRet = await nextResolve(specifier)
190
+
191
+ // ts resolve fail in some cases
192
+ if (isAbsolute(resolveRet.url))
193
+ resolveRet.url = pathToFileURL(resolveRet.url).href
194
+
195
+ return resolveRet
196
+ }
197
+ // @todo the first params may be url or path, need to distinguish
198
+
199
+ export const load = async (url, context, nextLoad) => {
200
+ if (config.virtualFile[url]) {
201
+ return {
202
+ format: 'module',
203
+ source: config.virtualFile[url],
204
+ shortCircuit: true,
205
+ }
206
+ }
207
+
208
+ url = url.split('?')[0]
209
+ if (
210
+ !url.includes('/node_modules/')
211
+ && url.startsWith('file://')
212
+ && !watchFiles.has(url)
213
+ && !isLowVersion
214
+ ) {
215
+ watchFiles.add(url)
216
+ // watch(
217
+ // fileURLToPath(url),
218
+ // debounce((type) => {
219
+ // if (type === 'change') {
220
+ // try {
221
+ // const files = [...findTopScope(url, Date.now())].reverse()
222
+
223
+ // port.postMessage(
224
+ // JSON.stringify({
225
+ // type: 'change',
226
+ // files,
227
+ // }),
228
+ // )
229
+ // }
230
+ // catch (e) {
231
+ // port.postMessage(
232
+ // JSON.stringify({
233
+ // type: 'relaunch',
234
+ // }),
235
+ // )
236
+ // }
237
+ // }
238
+ // }),
239
+ // )
240
+
241
+ if (!process.env.PS_HMR_BAN) {
242
+ chokidar.watch(fileURLToPath(url), { persistent: true }).on(
243
+ 'change',
244
+ debounce(() => {
245
+ try {
246
+ const files = [...findTopScope(url, Date.now())].reverse()
247
+
248
+ port.postMessage(
249
+ JSON.stringify({
250
+ type: 'change',
251
+ files,
252
+ }),
253
+ )
254
+ }
255
+ catch (e) {
256
+ port.postMessage(
257
+ JSON.stringify({
258
+ type: 'relaunch',
259
+ }),
260
+ )
261
+ }
262
+ }),
263
+ )
264
+ }
265
+ }
266
+ // resolveModuleName failed
267
+ // I don't know why it failed
268
+ if (!context.format && url.endsWith('.ts'))
269
+ context.format = 'ts'
270
+
271
+ if (context.format === 'ts') {
272
+ const { source } = await nextLoad(url, context)
273
+
274
+ const code
275
+ = typeof source === 'string' ? source : Buffer.from(source).toString()
276
+ const compiled = await compile(code, url)
277
+ if (unimportRet) {
278
+ const { injectImports } = unimportRet
279
+ return {
280
+ format: 'module',
281
+ source: (
282
+ await injectImports(
283
+ compiled,
284
+ (url.startsWith('file://') ? fileURLToPath(url) : url).replace(
285
+ /\\/g,
286
+ '/',
287
+ ),
288
+ )
289
+ ).code,
290
+ shortCircuit: true,
291
+ }
292
+ }
293
+ return {
294
+ format: 'module',
295
+ source: compiled,
296
+ shortCircuit: true,
297
+ }
298
+ }
299
+ else {
300
+ return nextLoad(url, context)
301
+ }
302
+ }
303
+
304
+ function findTopScope(url, time, modules = new Set()) {
305
+ filesRecord.set(url, time)
306
+ if (isModuleFileUrl(url)) {
307
+ modules.add(fileURLToPath(url))
308
+ }
309
+ else {
310
+ if (!moduleGraph[url])
311
+ throw new Error('root file update')
312
+ for (const i of [...moduleGraph[url]]) findTopScope(i, time, modules)
313
+ }
314
+
315
+ return modules
316
+ }
317
+
318
+ function debounce(cb, timeout = 500) {
319
+ let timer
320
+ return (...args) => {
321
+ if (timer)
322
+ return
323
+
324
+ timer = setTimeout(() => {
325
+ cb(...args)
326
+ timer = undefined
327
+ }, timeout)
328
+ }
329
+ }
330
+
331
+ export function isModuleFileUrl(url) {
332
+ const midName = getFileMid(url)
333
+ if (!midName)
334
+ return false
335
+ if (
336
+ [
337
+ 'controller',
338
+ 'rpc',
339
+ 'service',
340
+ 'module',
341
+ 'extension',
342
+ 'ext',
343
+ 'guard',
344
+ 'interceptor',
345
+ 'plugin',
346
+ 'filter',
347
+ 'pipe',
348
+ 'edge',
349
+ ].includes(midName)
350
+ )
351
+ return true
352
+
353
+ return config.moduleFile && config.moduleFile.includes(midName)
354
+ }