phecda-server 6.1.0 → 7.0.0-alpha.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.
- package/assets/ps.json +24 -24
- package/bin/cli.mjs +165 -157
- package/dist/{chunk-NL6QBQAR.js → chunk-7YQ57BQS.js} +21 -22
- package/dist/chunk-GSPBHZBH.js +534 -0
- package/dist/{chunk-J7B24YSE.mjs → chunk-HMVLXNV3.mjs} +5 -14
- package/dist/{chunk-TVT62GIX.js → chunk-J5CFUN4V.js} +8 -1
- package/dist/{chunk-JDV2XJYE.js → chunk-MBCHNDAY.js} +27 -36
- package/dist/{chunk-2CFYUXPM.mjs → chunk-V7EI76QQ.mjs} +136 -141
- package/dist/{chunk-G7TD2VB7.mjs → chunk-WHJ5FALK.mjs} +7 -0
- package/dist/{chunk-3H3T54IC.mjs → chunk-XYVMNY2X.mjs} +4 -5
- package/dist/{core-P1CsH6jz.d.mts → core-BIcUwV18.d.mts} +1 -1
- package/dist/{core-BlN0Spy9.d.ts → core-CYwEPfN4.d.ts} +1 -1
- package/dist/helper.d.mts +4 -6
- package/dist/helper.d.ts +4 -6
- package/dist/helper.js +3 -3
- package/dist/helper.mjs +2 -2
- package/dist/{server → http}/elysia/index.d.mts +5 -5
- package/dist/{server → http}/elysia/index.d.ts +5 -5
- package/dist/{server → http}/elysia/index.js +80 -62
- package/dist/{server → http}/elysia/index.mjs +50 -32
- package/dist/{server → http}/express/index.d.mts +5 -5
- package/dist/{server → http}/express/index.d.ts +5 -5
- package/dist/{server → http}/express/index.js +71 -55
- package/dist/{server → http}/express/index.mjs +42 -26
- package/dist/{server → http}/fastify/index.d.mts +5 -5
- package/dist/{server → http}/fastify/index.d.ts +5 -5
- package/dist/{server → http}/fastify/index.js +72 -72
- package/dist/{server → http}/fastify/index.mjs +47 -47
- package/dist/{server → http}/h3/index.d.mts +5 -5
- package/dist/{server → http}/h3/index.d.ts +5 -5
- package/dist/http/h3/index.js +160 -0
- package/dist/{server → http}/h3/index.mjs +68 -62
- package/dist/{server → http}/hono/index.d.mts +5 -5
- package/dist/{server → http}/hono/index.d.ts +5 -5
- package/dist/{server → http}/hono/index.js +69 -54
- package/dist/{server → http}/hono/index.mjs +41 -26
- package/dist/{server → http}/hyper-express/index.d.mts +5 -5
- package/dist/{server → http}/hyper-express/index.d.ts +5 -5
- package/dist/{server → http}/hyper-express/index.js +69 -56
- package/dist/{server → http}/hyper-express/index.mjs +41 -28
- package/dist/{server → http}/koa/index.d.mts +5 -5
- package/dist/{server → http}/koa/index.d.ts +5 -5
- package/dist/{server → http}/koa/index.js +71 -55
- package/dist/{server → http}/koa/index.mjs +42 -26
- package/dist/index.d.mts +52 -41
- package/dist/index.d.ts +52 -41
- package/dist/index.js +59 -81
- package/dist/index.mjs +39 -61
- package/dist/{meta-KtfiBIde.d.ts → meta-BXKLFTgG.d.mts} +2 -3
- package/dist/{meta-KtfiBIde.d.mts → meta-BXKLFTgG.d.ts} +2 -3
- package/dist/rpc/bullmq/index.d.mts +6 -6
- package/dist/rpc/bullmq/index.d.ts +6 -6
- package/dist/rpc/bullmq/index.js +24 -24
- package/dist/rpc/bullmq/index.mjs +14 -14
- package/dist/rpc/kafka/index.d.mts +3 -3
- package/dist/rpc/kafka/index.d.ts +3 -3
- package/dist/rpc/kafka/index.js +25 -21
- package/dist/rpc/kafka/index.mjs +15 -11
- package/dist/rpc/nats/index.d.mts +3 -3
- package/dist/rpc/nats/index.d.ts +3 -3
- package/dist/rpc/nats/index.js +22 -21
- package/dist/rpc/nats/index.mjs +13 -12
- package/dist/rpc/rabbitmq/index.d.mts +3 -3
- package/dist/rpc/rabbitmq/index.d.ts +3 -3
- package/dist/rpc/rabbitmq/index.js +23 -22
- package/dist/rpc/rabbitmq/index.mjs +12 -11
- package/dist/rpc/redis/index.d.mts +3 -3
- package/dist/rpc/redis/index.d.ts +3 -3
- package/dist/rpc/redis/index.js +24 -20
- package/dist/rpc/redis/index.mjs +15 -11
- package/dist/test.d.mts +3 -3
- package/dist/test.d.ts +3 -3
- package/dist/test.js +6 -6
- package/dist/test.mjs +2 -2
- package/dist/{types-JVT0mgLD.d.ts → types-BtbL49Zs.d.mts} +2 -1
- package/dist/{types-DIw7B6Up.d.ts → types-VFzEM7LL.d.ts} +5 -5
- package/dist/{types-BvD3B5Ny.d.mts → types-h40T3cRG.d.mts} +5 -5
- package/dist/{types-t9D1fU6G.d.mts → types-m3IEDKjP.d.ts} +2 -1
- package/package.json +23 -23
- package/register/loader.mjs +366 -367
- package/dist/chunk-DVTBLV6I.js +0 -539
- package/dist/server/h3/index.js +0 -154
package/register/loader.mjs
CHANGED
|
@@ -1,367 +1,366 @@
|
|
|
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, slash } 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
|
-
|
|
43
|
-
const workdir = process.env.PS_WORKDIR || process.cwd()
|
|
44
|
-
|
|
45
|
-
const configPath = resolvePath(
|
|
46
|
-
workdir,
|
|
47
|
-
process.env.PS_CONFIG_FILE || 'ps.json',
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
const require = createRequire(import.meta.url)
|
|
51
|
-
export async function initialize(data) {
|
|
52
|
-
if (data)
|
|
53
|
-
port = data.port
|
|
54
|
-
log('read config...')
|
|
55
|
-
|
|
56
|
-
config = require(configPath)
|
|
57
|
-
if (!config.virtualFile)
|
|
58
|
-
config.virtualFile = {}
|
|
59
|
-
|
|
60
|
-
if (!process.env.PS_HMR_BAN) {
|
|
61
|
-
chokidar.watch(configPath, { persistent: true }).on('change', () => {
|
|
62
|
-
port.postMessage(
|
|
63
|
-
JSON.stringify({
|
|
64
|
-
type: 'relaunch',
|
|
65
|
-
}),
|
|
66
|
-
)
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!config.unimport)
|
|
71
|
-
return
|
|
72
|
-
unimportRet = await genUnImportRet(config.unimport)
|
|
73
|
-
if (unimportRet) {
|
|
74
|
-
log('auto import...')
|
|
75
|
-
await unimportRet.init()
|
|
76
|
-
|
|
77
|
-
writeFile(
|
|
78
|
-
resolvePath(workdir, config.unimport.dtsPath || dtsPath),
|
|
79
|
-
handleClassTypes(
|
|
80
|
-
await unimportRet.generateTypeDeclarations({
|
|
81
|
-
resolvePath: (i) => {
|
|
82
|
-
if (i.from.startsWith('.') || isAbsolute(i.from)) {
|
|
83
|
-
const related = slash(
|
|
84
|
-
relative(workdir, i.from).replace(/\.ts(x)?$/, ''),
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
return !related.startsWith('.') ? `./${related}` : related
|
|
88
|
-
}
|
|
89
|
-
return i.from
|
|
90
|
-
},
|
|
91
|
-
}),
|
|
92
|
-
),
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const watchFiles = new Set()
|
|
98
|
-
const filesRecord = new Map()
|
|
99
|
-
const moduleGraph = {}
|
|
100
|
-
|
|
101
|
-
let entryUrl
|
|
102
|
-
|
|
103
|
-
function addUrlToGraph(url, parent) {
|
|
104
|
-
if (!(url in moduleGraph))
|
|
105
|
-
moduleGraph[url] = new Set()
|
|
106
|
-
|
|
107
|
-
moduleGraph[url].add(parent)
|
|
108
|
-
return url + (filesRecord.has(url) ? `?t=${filesRecord.get(url)}` : '')
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function getFileMid(file) {
|
|
112
|
-
const filename = basename(file)
|
|
113
|
-
const ret = filename.split('.')
|
|
114
|
-
if (ret.length === 3)
|
|
115
|
-
return ret[1]
|
|
116
|
-
else return ''
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export const resolve = async (specifier, context, nextResolve) => {
|
|
120
|
-
// virtual file
|
|
121
|
-
if (config.virtualFile[specifier]) {
|
|
122
|
-
return {
|
|
123
|
-
format: 'ts',
|
|
124
|
-
url: specifier,
|
|
125
|
-
shortCircuit: true,
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// entrypoint
|
|
129
|
-
if (!context.parentURL) {
|
|
130
|
-
entryUrl = specifier
|
|
131
|
-
return {
|
|
132
|
-
format: EXTENSIONS.some(ext => specifier.endsWith(ext))
|
|
133
|
-
? 'ts'
|
|
134
|
-
: undefined,
|
|
135
|
-
url: specifier,
|
|
136
|
-
shortCircuit: true,
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// url import
|
|
140
|
-
// it seems useless
|
|
141
|
-
if (/^file:\/\/\//.test(specifier) && extname(specifier) === '.ts') {
|
|
142
|
-
const url = addUrlToGraph(specifier, context.parentURL.split('?')[0])
|
|
143
|
-
return {
|
|
144
|
-
format: 'ts',
|
|
145
|
-
url,
|
|
146
|
-
shortCircuit: true,
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// hmr import
|
|
151
|
-
if (
|
|
152
|
-
context.parentURL.includes('/node_modules/phecda-server')
|
|
153
|
-
&& isAbsolute(specifier)
|
|
154
|
-
) {
|
|
155
|
-
specifier = relative(fileURLToPath(entryUrl), specifier)
|
|
156
|
-
.replace(/\.ts$/, '')
|
|
157
|
-
.slice(1)
|
|
158
|
-
context.parentURL = entryUrl
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// import/require from external library
|
|
162
|
-
if (context.parentURL.includes('/node_modules/'))
|
|
163
|
-
return nextResolve(specifier)
|
|
164
|
-
const { resolvedModule } = ts.resolveModuleName(
|
|
165
|
-
specifier,
|
|
166
|
-
fileURLToPath(context.parentURL),
|
|
167
|
-
tsconfig,
|
|
168
|
-
host,
|
|
169
|
-
moduleResolutionCache,
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
// import between loacl projects
|
|
173
|
-
if (
|
|
174
|
-
resolvedModule
|
|
175
|
-
&& !resolvedModule.resolvedFileName.includes('/node_modules/')
|
|
176
|
-
&& EXTENSIONS.includes(resolvedModule.extension)
|
|
177
|
-
) {
|
|
178
|
-
const url = addUrlToGraph(
|
|
179
|
-
pathToFileURL(resolvedModule.resolvedFileName).href,
|
|
180
|
-
context.parentURL.split('?')[0],
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
const importerMid = getFileMid(context.parentURL)
|
|
184
|
-
const sourceMid = getFileMid(resolvedModule.resolvedFileName)
|
|
185
|
-
if (config.resolve && importerMid && sourceMid) {
|
|
186
|
-
const resolver = config.resolve.find(
|
|
187
|
-
item => item.source === sourceMid && item.importer === importerMid,
|
|
188
|
-
)
|
|
189
|
-
if (resolver) {
|
|
190
|
-
return {
|
|
191
|
-
format: 'ts',
|
|
192
|
-
url: pathToFileURL(resolvePath(workdir, resolver.path)).href,
|
|
193
|
-
shortCircuit: true,
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
format: 'ts',
|
|
200
|
-
url,
|
|
201
|
-
shortCircuit: true,
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const resolveRet = await nextResolve(specifier)
|
|
206
|
-
|
|
207
|
-
// ts resolve fail in some cases
|
|
208
|
-
if (resolveRet.url && isAbsolute(resolveRet.url))
|
|
209
|
-
resolveRet.url = pathToFileURL(resolveRet.url).href
|
|
210
|
-
|
|
211
|
-
return resolveRet
|
|
212
|
-
}
|
|
213
|
-
// @todo the first params may be url or path, need to distinguish
|
|
214
|
-
|
|
215
|
-
export const load = async (url, context, nextLoad) => {
|
|
216
|
-
if (config.virtualFile[url]) {
|
|
217
|
-
return {
|
|
218
|
-
format: 'module',
|
|
219
|
-
source: config.virtualFile[url],
|
|
220
|
-
shortCircuit: true,
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
url = url.split('?')[0]
|
|
225
|
-
if (
|
|
226
|
-
!url.includes('/node_modules/')
|
|
227
|
-
&& url.startsWith('file://')
|
|
228
|
-
&& !watchFiles.has(url)
|
|
229
|
-
&& !isLowVersion
|
|
230
|
-
) {
|
|
231
|
-
watchFiles.add(url)
|
|
232
|
-
// watch(
|
|
233
|
-
// fileURLToPath(url),
|
|
234
|
-
// debounce((type) => {
|
|
235
|
-
// if (type === 'change') {
|
|
236
|
-
// try {
|
|
237
|
-
// const files = [...findTopScope(url, Date.now())].reverse()
|
|
238
|
-
|
|
239
|
-
// port.postMessage(
|
|
240
|
-
// JSON.stringify({
|
|
241
|
-
// type: 'change',
|
|
242
|
-
// files,
|
|
243
|
-
// }),
|
|
244
|
-
// )
|
|
245
|
-
// }
|
|
246
|
-
// catch (e) {
|
|
247
|
-
// port.postMessage(
|
|
248
|
-
// JSON.stringify({
|
|
249
|
-
// type: 'relaunch',
|
|
250
|
-
// }),
|
|
251
|
-
// )
|
|
252
|
-
// }
|
|
253
|
-
// }
|
|
254
|
-
// }),
|
|
255
|
-
// )
|
|
256
|
-
|
|
257
|
-
if (!process.env.PS_HMR_BAN) {
|
|
258
|
-
chokidar.watch(fileURLToPath(url), { persistent: true }).on(
|
|
259
|
-
'change',
|
|
260
|
-
debounce(() => {
|
|
261
|
-
try {
|
|
262
|
-
const files = [...findTopScope(url, Date.now())].reverse()
|
|
263
|
-
|
|
264
|
-
port.postMessage(
|
|
265
|
-
JSON.stringify({
|
|
266
|
-
type: 'change',
|
|
267
|
-
files,
|
|
268
|
-
}),
|
|
269
|
-
)
|
|
270
|
-
}
|
|
271
|
-
catch (e) {
|
|
272
|
-
port.postMessage(
|
|
273
|
-
JSON.stringify({
|
|
274
|
-
type: 'relaunch',
|
|
275
|
-
}),
|
|
276
|
-
)
|
|
277
|
-
}
|
|
278
|
-
}),
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// resolveModuleName failed
|
|
283
|
-
// I don't know why it failed
|
|
284
|
-
if (!context.format && url.endsWith('.ts'))
|
|
285
|
-
context.format = 'ts'
|
|
286
|
-
|
|
287
|
-
if (context.format === 'ts') {
|
|
288
|
-
const { source } = await nextLoad(url, context)
|
|
289
|
-
|
|
290
|
-
const code
|
|
291
|
-
= typeof source === 'string' ? source : Buffer.from(source).toString()
|
|
292
|
-
const compiled = await compile(code, url)
|
|
293
|
-
if (unimportRet) {
|
|
294
|
-
const { injectImports } = unimportRet
|
|
295
|
-
return {
|
|
296
|
-
format: 'module',
|
|
297
|
-
source: (
|
|
298
|
-
await injectImports(
|
|
299
|
-
compiled,
|
|
300
|
-
slash(url.startsWith('file://') ? fileURLToPath(url) : url),
|
|
301
|
-
)
|
|
302
|
-
).code,
|
|
303
|
-
shortCircuit: true,
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return {
|
|
307
|
-
format: 'module',
|
|
308
|
-
source: compiled,
|
|
309
|
-
shortCircuit: true,
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
return nextLoad(url, context)
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function findTopScope(url, time, modules = new Set()) {
|
|
318
|
-
filesRecord.set(url, time)
|
|
319
|
-
if (isModuleFileUrl(url)) {
|
|
320
|
-
modules.add(fileURLToPath(url))
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
if (!moduleGraph[url])
|
|
324
|
-
throw new Error('root file update')
|
|
325
|
-
for (const i of [...moduleGraph[url]]) findTopScope(i, time, modules)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return modules
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function debounce(cb, timeout = 500) {
|
|
332
|
-
let timer
|
|
333
|
-
return (...args) => {
|
|
334
|
-
if (timer)
|
|
335
|
-
return
|
|
336
|
-
|
|
337
|
-
timer = setTimeout(() => {
|
|
338
|
-
cb(...args)
|
|
339
|
-
timer = undefined
|
|
340
|
-
}, timeout)
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export function isModuleFileUrl(url) {
|
|
345
|
-
const midName = getFileMid(url)
|
|
346
|
-
if (!midName)
|
|
347
|
-
return false
|
|
348
|
-
if (
|
|
349
|
-
[
|
|
350
|
-
'controller',
|
|
351
|
-
'rpc',
|
|
352
|
-
'service',
|
|
353
|
-
'module',
|
|
354
|
-
'extension',
|
|
355
|
-
'ext',
|
|
356
|
-
'guard',
|
|
357
|
-
'
|
|
358
|
-
'
|
|
359
|
-
'
|
|
360
|
-
'
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
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, slash } 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
|
+
|
|
43
|
+
const workdir = process.env.PS_WORKDIR || process.cwd()
|
|
44
|
+
|
|
45
|
+
const configPath = resolvePath(
|
|
46
|
+
workdir,
|
|
47
|
+
process.env.PS_CONFIG_FILE || 'ps.json',
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const require = createRequire(import.meta.url)
|
|
51
|
+
export async function initialize(data) {
|
|
52
|
+
if (data)
|
|
53
|
+
port = data.port
|
|
54
|
+
log('read config...')
|
|
55
|
+
|
|
56
|
+
config = require(configPath)
|
|
57
|
+
if (!config.virtualFile)
|
|
58
|
+
config.virtualFile = {}
|
|
59
|
+
|
|
60
|
+
if (!process.env.PS_HMR_BAN) {
|
|
61
|
+
chokidar.watch(configPath, { persistent: true }).on('change', () => {
|
|
62
|
+
port.postMessage(
|
|
63
|
+
JSON.stringify({
|
|
64
|
+
type: 'relaunch',
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!config.unimport)
|
|
71
|
+
return
|
|
72
|
+
unimportRet = await genUnImportRet(config.unimport)
|
|
73
|
+
if (unimportRet) {
|
|
74
|
+
log('auto import...')
|
|
75
|
+
await unimportRet.init()
|
|
76
|
+
|
|
77
|
+
writeFile(
|
|
78
|
+
resolvePath(workdir, config.unimport.dtsPath || dtsPath),
|
|
79
|
+
handleClassTypes(
|
|
80
|
+
await unimportRet.generateTypeDeclarations({
|
|
81
|
+
resolvePath: (i) => {
|
|
82
|
+
if (i.from.startsWith('.') || isAbsolute(i.from)) {
|
|
83
|
+
const related = slash(
|
|
84
|
+
relative(workdir, i.from).replace(/\.ts(x)?$/, ''),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return !related.startsWith('.') ? `./${related}` : related
|
|
88
|
+
}
|
|
89
|
+
return i.from
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
),
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const watchFiles = new Set()
|
|
98
|
+
const filesRecord = new Map()
|
|
99
|
+
const moduleGraph = {}
|
|
100
|
+
|
|
101
|
+
let entryUrl
|
|
102
|
+
|
|
103
|
+
function addUrlToGraph(url, parent) {
|
|
104
|
+
if (!(url in moduleGraph))
|
|
105
|
+
moduleGraph[url] = new Set()
|
|
106
|
+
|
|
107
|
+
moduleGraph[url].add(parent)
|
|
108
|
+
return url + (filesRecord.has(url) ? `?t=${filesRecord.get(url)}` : '')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function getFileMid(file) {
|
|
112
|
+
const filename = basename(file)
|
|
113
|
+
const ret = filename.split('.')
|
|
114
|
+
if (ret.length === 3)
|
|
115
|
+
return ret[1]
|
|
116
|
+
else return ''
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const resolve = async (specifier, context, nextResolve) => {
|
|
120
|
+
// virtual file
|
|
121
|
+
if (config.virtualFile[specifier]) {
|
|
122
|
+
return {
|
|
123
|
+
format: 'ts',
|
|
124
|
+
url: specifier,
|
|
125
|
+
shortCircuit: true,
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// entrypoint
|
|
129
|
+
if (!context.parentURL) {
|
|
130
|
+
entryUrl = specifier
|
|
131
|
+
return {
|
|
132
|
+
format: EXTENSIONS.some(ext => specifier.endsWith(ext))
|
|
133
|
+
? 'ts'
|
|
134
|
+
: undefined,
|
|
135
|
+
url: specifier,
|
|
136
|
+
shortCircuit: true,
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// url import
|
|
140
|
+
// it seems useless
|
|
141
|
+
if (/^file:\/\/\//.test(specifier) && extname(specifier) === '.ts') {
|
|
142
|
+
const url = addUrlToGraph(specifier, context.parentURL.split('?')[0])
|
|
143
|
+
return {
|
|
144
|
+
format: 'ts',
|
|
145
|
+
url,
|
|
146
|
+
shortCircuit: true,
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// hmr import
|
|
151
|
+
if (
|
|
152
|
+
context.parentURL.includes('/node_modules/phecda-server')
|
|
153
|
+
&& isAbsolute(specifier)
|
|
154
|
+
) {
|
|
155
|
+
specifier = relative(fileURLToPath(entryUrl), specifier)
|
|
156
|
+
.replace(/\.ts$/, '')
|
|
157
|
+
.slice(1)
|
|
158
|
+
context.parentURL = entryUrl
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// import/require from external library
|
|
162
|
+
if (context.parentURL.includes('/node_modules/'))
|
|
163
|
+
return nextResolve(specifier)
|
|
164
|
+
const { resolvedModule } = ts.resolveModuleName(
|
|
165
|
+
specifier,
|
|
166
|
+
fileURLToPath(context.parentURL),
|
|
167
|
+
tsconfig,
|
|
168
|
+
host,
|
|
169
|
+
moduleResolutionCache,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// import between loacl projects
|
|
173
|
+
if (
|
|
174
|
+
resolvedModule
|
|
175
|
+
&& !resolvedModule.resolvedFileName.includes('/node_modules/')
|
|
176
|
+
&& EXTENSIONS.includes(resolvedModule.extension)
|
|
177
|
+
) {
|
|
178
|
+
const url = addUrlToGraph(
|
|
179
|
+
pathToFileURL(resolvedModule.resolvedFileName).href,
|
|
180
|
+
context.parentURL.split('?')[0],
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
const importerMid = getFileMid(context.parentURL)
|
|
184
|
+
const sourceMid = getFileMid(resolvedModule.resolvedFileName)
|
|
185
|
+
if (config.resolve && importerMid && sourceMid) {
|
|
186
|
+
const resolver = config.resolve.find(
|
|
187
|
+
item => item.source === sourceMid && item.importer === importerMid,
|
|
188
|
+
)
|
|
189
|
+
if (resolver) {
|
|
190
|
+
return {
|
|
191
|
+
format: 'ts',
|
|
192
|
+
url: pathToFileURL(resolvePath(workdir, resolver.path)).href,
|
|
193
|
+
shortCircuit: true,
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
format: 'ts',
|
|
200
|
+
url,
|
|
201
|
+
shortCircuit: true,
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const resolveRet = await nextResolve(specifier)
|
|
206
|
+
|
|
207
|
+
// ts resolve fail in some cases
|
|
208
|
+
if (resolveRet.url && isAbsolute(resolveRet.url))
|
|
209
|
+
resolveRet.url = pathToFileURL(resolveRet.url).href
|
|
210
|
+
|
|
211
|
+
return resolveRet
|
|
212
|
+
}
|
|
213
|
+
// @todo the first params may be url or path, need to distinguish
|
|
214
|
+
|
|
215
|
+
export const load = async (url, context, nextLoad) => {
|
|
216
|
+
if (config.virtualFile[url]) {
|
|
217
|
+
return {
|
|
218
|
+
format: 'module',
|
|
219
|
+
source: config.virtualFile[url],
|
|
220
|
+
shortCircuit: true,
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
url = url.split('?')[0]
|
|
225
|
+
if (
|
|
226
|
+
!url.includes('/node_modules/')
|
|
227
|
+
&& url.startsWith('file://')
|
|
228
|
+
&& !watchFiles.has(url)
|
|
229
|
+
&& !isLowVersion
|
|
230
|
+
) {
|
|
231
|
+
watchFiles.add(url)
|
|
232
|
+
// watch(
|
|
233
|
+
// fileURLToPath(url),
|
|
234
|
+
// debounce((type) => {
|
|
235
|
+
// if (type === 'change') {
|
|
236
|
+
// try {
|
|
237
|
+
// const files = [...findTopScope(url, Date.now())].reverse()
|
|
238
|
+
|
|
239
|
+
// port.postMessage(
|
|
240
|
+
// JSON.stringify({
|
|
241
|
+
// type: 'change',
|
|
242
|
+
// files,
|
|
243
|
+
// }),
|
|
244
|
+
// )
|
|
245
|
+
// }
|
|
246
|
+
// catch (e) {
|
|
247
|
+
// port.postMessage(
|
|
248
|
+
// JSON.stringify({
|
|
249
|
+
// type: 'relaunch',
|
|
250
|
+
// }),
|
|
251
|
+
// )
|
|
252
|
+
// }
|
|
253
|
+
// }
|
|
254
|
+
// }),
|
|
255
|
+
// )
|
|
256
|
+
|
|
257
|
+
if (!process.env.PS_HMR_BAN) {
|
|
258
|
+
chokidar.watch(fileURLToPath(url), { persistent: true }).on(
|
|
259
|
+
'change',
|
|
260
|
+
debounce(() => {
|
|
261
|
+
try {
|
|
262
|
+
const files = [...findTopScope(url, Date.now())].reverse()
|
|
263
|
+
|
|
264
|
+
port.postMessage(
|
|
265
|
+
JSON.stringify({
|
|
266
|
+
type: 'change',
|
|
267
|
+
files,
|
|
268
|
+
}),
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
port.postMessage(
|
|
273
|
+
JSON.stringify({
|
|
274
|
+
type: 'relaunch',
|
|
275
|
+
}),
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
}),
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// resolveModuleName failed
|
|
283
|
+
// I don't know why it failed
|
|
284
|
+
if (!context.format && url.endsWith('.ts'))
|
|
285
|
+
context.format = 'ts'
|
|
286
|
+
|
|
287
|
+
if (context.format === 'ts') {
|
|
288
|
+
const { source } = await nextLoad(url, context)
|
|
289
|
+
|
|
290
|
+
const code
|
|
291
|
+
= typeof source === 'string' ? source : Buffer.from(source).toString()
|
|
292
|
+
const compiled = await compile(code, url)
|
|
293
|
+
if (unimportRet) {
|
|
294
|
+
const { injectImports } = unimportRet
|
|
295
|
+
return {
|
|
296
|
+
format: 'module',
|
|
297
|
+
source: (
|
|
298
|
+
await injectImports(
|
|
299
|
+
compiled,
|
|
300
|
+
slash(url.startsWith('file://') ? fileURLToPath(url) : url),
|
|
301
|
+
)
|
|
302
|
+
).code,
|
|
303
|
+
shortCircuit: true,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
format: 'module',
|
|
308
|
+
source: compiled,
|
|
309
|
+
shortCircuit: true,
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return nextLoad(url, context)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function findTopScope(url, time, modules = new Set()) {
|
|
318
|
+
filesRecord.set(url, time)
|
|
319
|
+
if (isModuleFileUrl(url)) {
|
|
320
|
+
modules.add(fileURLToPath(url))
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
if (!moduleGraph[url])
|
|
324
|
+
throw new Error('root file update')
|
|
325
|
+
for (const i of [...moduleGraph[url]]) findTopScope(i, time, modules)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return modules
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function debounce(cb, timeout = 500) {
|
|
332
|
+
let timer
|
|
333
|
+
return (...args) => {
|
|
334
|
+
if (timer)
|
|
335
|
+
return
|
|
336
|
+
|
|
337
|
+
timer = setTimeout(() => {
|
|
338
|
+
cb(...args)
|
|
339
|
+
timer = undefined
|
|
340
|
+
}, timeout)
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export function isModuleFileUrl(url) {
|
|
345
|
+
const midName = getFileMid(url)
|
|
346
|
+
if (!midName)
|
|
347
|
+
return false
|
|
348
|
+
if (
|
|
349
|
+
[
|
|
350
|
+
'controller',
|
|
351
|
+
'rpc',
|
|
352
|
+
'service',
|
|
353
|
+
'module',
|
|
354
|
+
'extension',
|
|
355
|
+
'ext',
|
|
356
|
+
'guard',
|
|
357
|
+
'addon',
|
|
358
|
+
'filter',
|
|
359
|
+
'pipe',
|
|
360
|
+
'edge',
|
|
361
|
+
].includes(midName)
|
|
362
|
+
)
|
|
363
|
+
return true
|
|
364
|
+
|
|
365
|
+
return config.moduleFile && config.moduleFile.includes(midName)
|
|
366
|
+
}
|