phecda-server 8.0.2 → 8.1.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.
package/bin/cli.mjs CHANGED
@@ -191,8 +191,10 @@ cli
191
191
  console.log(`${pc.green('->')} press ${pc.green('e')} to exit`)
192
192
  console.log(`${pc.green('->')} press ${pc.green('r')} to relaunch`)
193
193
  console.log(`${pc.green('->')} press ${pc.green('c')} to clear terminal`)
194
+ console.log(`${pc.green('->')} press ${pc.green('i')} to debug`)
194
195
 
195
196
  process.stdin.on('data', async (data) => {
197
+ const args = [...nodeArgs]
196
198
  const input = data.toString().trim().toLocaleLowerCase()
197
199
  if (input === 'r') {
198
200
  if (child) {
@@ -200,12 +202,11 @@ cli
200
202
  if (closePromise)
201
203
  await closePromise
202
204
  log('relaunch...')
203
- startChild(file, nodeArgs)
205
+ startChild(file, args)
204
206
  }
205
207
  else {
206
208
  log('relaunch...')
207
-
208
- startChild(file, nodeArgs)
209
+ startChild(file, args)
209
210
  }
210
211
  }
211
212
  if (input === 'e')
@@ -213,6 +214,20 @@ cli
213
214
 
214
215
  if (input === 'c')
215
216
  console.clear()
217
+
218
+ if (input === 'i' || input.startsWith('i ')) {
219
+ const [, arg] = input.split(' ')
220
+
221
+ if (child) {
222
+ child.send({
223
+ type: 'inspect',
224
+ arg
225
+ })
226
+ } else {
227
+ args.push(`--inspect${arg ? `=${arg}` : ''}`)
228
+ startChild(file, args)
229
+ }
230
+ }
216
231
  })
217
232
  })
218
233
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phecda-server",
3
- "version": "8.0.2",
3
+ "version": "8.1.0",
4
4
  "description": "server framework that provide IOC/type-reuse/http&rpc-adaptor",
5
5
  "author": "fgsreally",
6
6
  "license": "MIT",
@@ -20,20 +20,20 @@ export default ['Addon', 'Arg', 'Assign', 'BadGatewayException', 'BadRequestExce
20
20
  'Watcher', 'WorkerException',
21
21
  'addAddon', 'addDecoToClass',
22
22
  'addFilter', 'addGuard', 'addPipe', 'emitter',
23
- 'getMergedMeta','getMeta', 'getMetaKey', 'getMetaParams', 'getOwnMeta', 'getOwnMetaKey', 'getOwnMetaParams',
23
+ 'getMergedMeta', 'getMeta', 'getMetaKey', 'getMetaParams', 'getOwnMeta', 'getOwnMetaKey', 'getOwnMetaParams',
24
24
  'getTag',
25
25
  'isPhecda', 'log', 'phecdaNamespace', 'runMiddleware',
26
26
  'setInject',
27
27
  'setLogger',
28
28
  'setMeta',
29
29
  'useS', 'wait', 'OneFile', 'ManyFiles',
30
- 'Rule','Required','Optional',
30
+ 'Rule', 'Required', 'Optional',
31
31
  'validate',
32
- 'Min','Max','Enum','OneOf','Nested',
33
-
34
- 'Doc','DocGenerator',
35
- 'pick','omit','partial',
36
- 'functionToClass','objectToClass'
32
+ 'Min', 'Max', 'Enum', 'OneOf', 'Nested',
33
+ 'Const',
34
+ 'Doc', 'DocGenerator',
35
+ 'pick', 'omit', 'partial',
36
+ 'functionToClass', 'objectToClass'
37
37
 
38
38
 
39
39
  ]
@@ -2,6 +2,7 @@ import { register } from 'node:module'
2
2
  import { MessageChannel } from 'node:worker_threads'
3
3
  import { isPhecda, log } from '../dist/index.mjs'
4
4
  import { RELAUNCH, RELOAD } from '../dist/helper.mjs'
5
+ import inspector from 'inspector'
5
6
  const { port1, port2 } = new MessageChannel()
6
7
 
7
8
  register('./loader.mjs', {
@@ -47,3 +48,29 @@ process.on('unhandledRejection', (err) => {
47
48
 
48
49
  console.error(err)
49
50
  })
51
+
52
+
53
+ process.on('message', (data) => {
54
+ if (data.type === 'inspect') {
55
+ if (inspector.url()) {
56
+ inspector.close();
57
+ log('close inspector', 'info');
58
+ } else {
59
+ const { arg } = data
60
+
61
+ if (arg) {
62
+ if (arg.includes(':')) {
63
+ const [host, port] = arg.split(':')
64
+ inspector.open(Number(port), host)
65
+ } else {
66
+ inspector.open(Number(arg))
67
+ }
68
+ }else {
69
+ inspector.open();
70
+ }
71
+ // address already in use
72
+ if (inspector.url())
73
+ log(`open "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=${inspector.url().replace("ws://", '')}" in browser`, 'info');
74
+ }
75
+ }
76
+ })
@@ -35,7 +35,7 @@ const dtsPath = process.env.PS_DTS_PATH || 'ps.d.ts'
35
35
  const watchFiles = new Set()
36
36
  const filesRecord = new Map()
37
37
  const moduleGraph = {}
38
- // ts
38
+ // ts
39
39
  let tsconfig = {
40
40
  module: ts.ModuleKind.ESNext,
41
41
  moduleResolution: ts.ModuleResolutionKind.NodeNext,
@@ -81,7 +81,7 @@ export async function initialize(data) {
81
81
 
82
82
  if (loaderPath) {
83
83
  const loader = await
84
- import (loaderPath.startsWith('.') ? resolvePath(workdir, loaderPath) : loaderPath)
84
+ import(loaderPath.startsWith('.') ? resolvePath(workdir, loaderPath) : loaderPath)
85
85
 
86
86
  if (typeof loader.load === 'function')
87
87
  customLoad = loader.load
@@ -147,80 +147,80 @@ function getFileMid(file) {
147
147
  return ret[1]
148
148
  }
149
149
 
150
- export const resolve = async(specifier, context, nextResolve) => {
151
- if (customResolve) {
152
- const url = await customResolve(specifier, context)
153
- if (url) {
154
- return {
155
- format: 'ts',
156
- url,
157
- shortCircuit: true,
158
- }
150
+ export const resolve = async (specifier, context, nextResolve) => {
151
+ if (customResolve) {
152
+ const url = await customResolve(specifier, context)
153
+ if (url) {
154
+ return {
155
+ format: 'ts',
156
+ url,
157
+ shortCircuit: true,
159
158
  }
160
159
  }
160
+ }
161
161
 
162
- // entrypoint
163
- if (!context.parentURL)
164
- return nextResolve(specifier)
162
+ // entrypoint
163
+ if (!context.parentURL)
164
+ return nextResolve(specifier)
165
165
 
166
- // @todo skip resolve to improve performance
167
- // if (context.parentURL.includes('/node_modules/') && specifier.includes('/node_modules/'))
168
- // return nextResolve(specifier)
166
+ // @todo skip resolve to improve performance
167
+ // if (context.parentURL.includes('/node_modules/') && specifier.includes('/node_modules/'))
168
+ // return nextResolve(specifier)
169
169
 
170
- const { resolvedModule } = ts.resolveModuleName(
171
- specifier,
172
- fileURLToPath(context.parentURL),
173
- tsconfig,
174
- host,
175
- moduleResolutionCache,
170
+ const { resolvedModule } = ts.resolveModuleName(
171
+ specifier,
172
+ fileURLToPath(context.parentURL),
173
+ tsconfig,
174
+ host,
175
+ moduleResolutionCache,
176
+ )
177
+
178
+ // import among files in local project
179
+ if (
180
+ resolvedModule &&
181
+ !resolvedModule.resolvedFileName.includes('/node_modules/') &&
182
+ EXTENSIONS.includes(resolvedModule.extension)
183
+ ) {
184
+ const url = addUrlToGraph(
185
+ pathToFileURL(resolvedModule.resolvedFileName).href,
186
+ context.parentURL.split('?')[0],
176
187
  )
177
188
 
178
- // import among files in local project
179
- if (
180
- resolvedModule &&
181
- !resolvedModule.resolvedFileName.includes('/node_modules/') &&
182
- EXTENSIONS.includes(resolvedModule.extension)
183
- ) {
184
- const url = addUrlToGraph(
185
- pathToFileURL(resolvedModule.resolvedFileName).href,
186
- context.parentURL.split('?')[0],
189
+ const importerMid = getFileMid(context.parentURL)
190
+ const sourceMid = getFileMid(resolvedModule.resolvedFileName)
191
+ if (config.resolve && importerMid && sourceMid) {
192
+ const resolver = config.resolve.find(
193
+ item => item.source === sourceMid && item.importer === importerMid,
187
194
  )
188
-
189
- const importerMid = getFileMid(context.parentURL)
190
- const sourceMid = getFileMid(resolvedModule.resolvedFileName)
191
- if (config.resolve && importerMid && sourceMid) {
192
- const resolver = config.resolve.find(
193
- item => item.source === sourceMid && item.importer === importerMid,
194
- )
195
- if (resolver) {
196
- return {
197
- format: 'ts',
198
- url: pathToFileURL(resolvePath(workdir, resolver.path)).href,
199
- shortCircuit: true,
200
- }
195
+ if (resolver) {
196
+ return {
197
+ format: 'ts',
198
+ url: pathToFileURL(resolvePath(workdir, resolver.path)).href,
199
+ shortCircuit: true,
201
200
  }
202
201
  }
203
-
204
- return {
205
- format: 'ts',
206
- url,
207
- shortCircuit: true,
208
- }
209
202
  }
210
203
 
211
- const resolveRet = await nextResolve(specifier)
212
-
213
- // ts resolve fail in some cases
214
- if (resolveRet.url && isAbsolute(resolveRet.url)) {
215
- const [path, query] = resolveRet.url.split('?')
216
- resolveRet.url = pathToFileURL(path).href + (query ? `?${query}` : '')
204
+ return {
205
+ format: 'ts',
206
+ url,
207
+ shortCircuit: true,
217
208
  }
209
+ }
210
+
211
+ const resolveRet = await nextResolve(specifier)
218
212
 
219
- return resolveRet
213
+ // ts resolve fail in some cases
214
+ if (resolveRet.url && isAbsolute(resolveRet.url)) {
215
+ const [path, query] = resolveRet.url.split('?')
216
+ resolveRet.url = pathToFileURL(path).href + (query ? `?${query}` : '')
220
217
  }
221
- // @todo the first params may be url or path, need to distinguish
222
218
 
223
- export const load = async(url, context, nextLoad) => {
219
+ return resolveRet
220
+ }
221
+ // @todo the first params may be url or path, need to distinguish
222
+
223
+ export const load = async (url, context, nextLoad) => {
224
224
  let mode
225
225
  if (context.importAttributes.ps) {
226
226
  mode = context.importAttributes.ps
@@ -281,13 +281,13 @@ export const load = async(url, context, nextLoad) => {
281
281
  }
282
282
  }
283
283
 
284
-
284
+
285
285
  // resolveModuleName failed
286
286
  // I don't know why it failed
287
- if ( url.endsWith('.ts'))
287
+ if (url.endsWith('.ts'))
288
288
  context.format = 'ts'
289
289
 
290
- // module-typescript???
290
+ // module-typescript???
291
291
 
292
292
  if (context.format === 'ts') {
293
293
  const { source } = await nextLoad(url, context)
@@ -298,7 +298,7 @@ export const load = async(url, context, nextLoad) => {
298
298
 
299
299
  if (unimportRet) {
300
300
  const { injectImports } = unimportRet
301
-
301
+
302
302
  return {
303
303
  format: 'module',
304
304
  source: (
@@ -327,7 +327,7 @@ function findTopScope(url, time, modules = new Set()) {
327
327
  } else {
328
328
  if (!moduleGraph[url])
329
329
  throw new Error('root file update')
330
- for (const i of[...moduleGraph[url]]) findTopScope(i, time, modules)
330
+ for (const i of [...moduleGraph[url]]) findTopScope(i, time, modules)
331
331
  }
332
332
 
333
333
  return modules
@@ -1,6 +1,9 @@
1
1
  import { basename } from 'path'
2
2
  import { transform } from '@swc-node/core'
3
3
  import psExports from './export.mjs'
4
+ import { fileURLToPath } from 'node:url'
5
+ import path from 'node:path'
6
+
4
7
  const injectInlineSourceMap = ({ code, map }) => {
5
8
  if (map) {
6
9
  const base64Map = Buffer.from(map, 'utf8').toString('base64')
@@ -10,33 +13,34 @@ const injectInlineSourceMap = ({ code, map }) => {
10
13
  return code
11
14
  }
12
15
 
13
- export async function compile(sourcecode, filename, config = {}) {
14
- if (filename.endsWith('.d.ts'))
16
+ export async function compile(sourcecode, url, config = {}) {
17
+ if (url.endsWith('.d.ts'))
15
18
  return ''
16
19
 
20
+ const filename = path.basename(url.startsWith('file:') ? fileURLToPath(url) : url)
21
+
17
22
  const { code, map } = await transform(sourcecode, filename, {
18
- sourcemap: true,
19
23
  module: 'es6',
20
24
  emitDecoratorMetadata: true,
21
25
  experimentalDecorators: true,
22
26
  esModuleInterop: false,
27
+ sourcemap:false,
23
28
  ...config
24
29
  })
25
-
26
30
  return injectInlineSourceMap({ code, map })
27
31
  }
28
32
 
29
33
  export async function genUnImportRet(opts) {
30
34
  try {
31
35
  const { createUnimport } = await
32
- import ('unimport')
36
+ import('unimport')
33
37
  return createUnimport({
34
38
  ...opts,
35
39
 
36
40
  presets: [{
37
- from: 'phecda-server',
38
- imports: psExports,
39
- }, ]
41
+ from: 'phecda-server',
42
+ imports: psExports,
43
+ },]
40
44
  .concat(opts.presets || []),
41
45
  })
42
46
  } catch (e) {