phecda-server 7.0.0-alpha.1 → 7.0.0-alpha.10

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 (86) hide show
  1. package/assets/ps.json +1 -1
  2. package/assets/schema.json +55 -55
  3. package/bin/cli.mjs +31 -23
  4. package/dist/chunk-4LLLQOMF.js +152 -0
  5. package/dist/{chunk-7YQ57BQS.js → chunk-6OQ2SB5W.js} +137 -69
  6. package/dist/{chunk-GSPBHZBH.js → chunk-G7JFKM2M.js} +96 -80
  7. package/dist/{chunk-MBCHNDAY.js → chunk-KCPBITYZ.js} +24 -24
  8. package/dist/{chunk-HMVLXNV3.mjs → chunk-MUI6MTUO.mjs} +1 -1
  9. package/dist/chunk-NQ55PA2X.mjs +152 -0
  10. package/dist/{chunk-XYVMNY2X.mjs → chunk-YCES6ABN.mjs} +124 -56
  11. package/dist/{chunk-V7EI76QQ.mjs → chunk-Z7NAAE4M.mjs} +48 -32
  12. package/dist/{core-BIcUwV18.d.mts → core-CUTbX_IS.d.ts} +5 -3
  13. package/dist/{core-CYwEPfN4.d.ts → core-DIfgUKIU.d.mts} +5 -3
  14. package/dist/helper.d.mts +8 -6
  15. package/dist/helper.d.ts +8 -6
  16. package/dist/helper.js +8 -3
  17. package/dist/helper.mjs +10 -5
  18. package/dist/http/elysia/index.d.mts +4 -4
  19. package/dist/http/elysia/index.d.ts +4 -4
  20. package/dist/http/elysia/index.js +43 -44
  21. package/dist/http/elysia/index.mjs +9 -10
  22. package/dist/http/express/index.d.mts +4 -4
  23. package/dist/http/express/index.d.ts +4 -4
  24. package/dist/http/express/index.js +40 -41
  25. package/dist/http/express/index.mjs +9 -10
  26. package/dist/http/fastify/index.d.mts +4 -4
  27. package/dist/http/fastify/index.d.ts +4 -4
  28. package/dist/http/fastify/index.js +41 -42
  29. package/dist/http/fastify/index.mjs +9 -10
  30. package/dist/http/h3/index.d.mts +4 -4
  31. package/dist/http/h3/index.d.ts +4 -4
  32. package/dist/http/h3/index.js +41 -42
  33. package/dist/http/h3/index.mjs +9 -10
  34. package/dist/http/hono/index.d.mts +4 -4
  35. package/dist/http/hono/index.d.ts +4 -4
  36. package/dist/http/hono/index.js +37 -39
  37. package/dist/http/hono/index.mjs +5 -7
  38. package/dist/http/hyper-express/index.d.mts +4 -4
  39. package/dist/http/hyper-express/index.d.ts +4 -4
  40. package/dist/http/hyper-express/index.js +38 -39
  41. package/dist/http/hyper-express/index.mjs +8 -9
  42. package/dist/http/koa/index.d.mts +4 -4
  43. package/dist/http/koa/index.d.ts +4 -4
  44. package/dist/http/koa/index.js +40 -41
  45. package/dist/http/koa/index.mjs +9 -10
  46. package/dist/index.d.mts +44 -38
  47. package/dist/index.d.ts +44 -38
  48. package/dist/index.js +48 -42
  49. package/dist/index.mjs +21 -15
  50. package/dist/{meta-BXKLFTgG.d.mts → meta-CR-D39hQ.d.mts} +7 -5
  51. package/dist/{meta-BXKLFTgG.d.ts → meta-CR-D39hQ.d.ts} +7 -5
  52. package/dist/rpc/bullmq/index.d.mts +5 -5
  53. package/dist/rpc/bullmq/index.d.ts +5 -5
  54. package/dist/rpc/bullmq/index.js +15 -14
  55. package/dist/rpc/bullmq/index.mjs +4 -3
  56. package/dist/rpc/kafka/index.d.mts +4 -4
  57. package/dist/rpc/kafka/index.d.ts +4 -4
  58. package/dist/rpc/kafka/index.js +15 -14
  59. package/dist/rpc/kafka/index.mjs +3 -2
  60. package/dist/rpc/nats/index.d.mts +4 -4
  61. package/dist/rpc/nats/index.d.ts +4 -4
  62. package/dist/rpc/nats/index.js +14 -13
  63. package/dist/rpc/nats/index.mjs +4 -3
  64. package/dist/rpc/rabbitmq/index.d.mts +4 -4
  65. package/dist/rpc/rabbitmq/index.d.ts +4 -4
  66. package/dist/rpc/rabbitmq/index.js +16 -15
  67. package/dist/rpc/rabbitmq/index.mjs +4 -3
  68. package/dist/rpc/redis/index.d.mts +4 -4
  69. package/dist/rpc/redis/index.d.ts +4 -4
  70. package/dist/rpc/redis/index.js +14 -13
  71. package/dist/rpc/redis/index.mjs +4 -3
  72. package/dist/test.d.mts +3 -3
  73. package/dist/test.d.ts +3 -3
  74. package/dist/test.js +6 -6
  75. package/dist/test.mjs +2 -2
  76. package/dist/{types-h40T3cRG.d.mts → types-BF1TDbFV.d.ts} +4 -3
  77. package/dist/{types-BtbL49Zs.d.mts → types-DYRu0vic.d.ts} +4 -3
  78. package/dist/{types-VFzEM7LL.d.ts → types-DYviSl5B.d.mts} +4 -3
  79. package/dist/{types-m3IEDKjP.d.ts → types-DqH1qA-q.d.mts} +4 -3
  80. package/package.json +8 -5
  81. package/register/export.mjs +30 -0
  82. package/register/index.mjs +50 -40
  83. package/register/loader.mjs +84 -66
  84. package/register/utils.mjs +60 -56
  85. package/dist/chunk-J5CFUN4V.js +0 -73
  86. package/dist/chunk-WHJ5FALK.mjs +0 -73
package/dist/test.d.mts CHANGED
@@ -2,8 +2,8 @@ import * as supertest from 'supertest';
2
2
  import { Test } from 'supertest';
3
3
  import { Server } from 'node:http';
4
4
  import { Construct } from 'phecda-core';
5
- import { F as Factory } from './core-BIcUwV18.mjs';
6
- import { P as PickFunc } from './meta-BXKLFTgG.mjs';
5
+ import { F as Factory } from './core-DIfgUKIU.mjs';
6
+ import { P as PickFunc } from './meta-CR-D39hQ.mjs';
7
7
 
8
8
  declare function TestFactory<T extends Construct[]>(...Modules: T): Promise<{
9
9
  get<C extends T[number]>(Model: C): InstanceType<C>;
@@ -11,7 +11,7 @@ declare function TestFactory<T extends Construct[]>(...Modules: T): Promise<{
11
11
  type SuperTestRequest<T> = {
12
12
  [K in keyof T]: T[K] extends (...args: infer R) => any ? (...args: R) => Test : never;
13
13
  };
14
- declare function TestHttp(app: Server | any, { moduleMap, meta }: Awaited<ReturnType<typeof Factory>>, isAgent?: boolean): Promise<supertest.SuperTestWithHost<Test> & Pick<supertest.Request, "type" | "query" | "key" | "use" | "on" | "set" | "accept" | "auth" | "withCredentials" | "retry" | "ok" | "redirects" | "timeout" | "buffer" | "serialize" | "parse" | "ca" | "pfx" | "cert"> & {
14
+ declare function TestHttp(app: Server | any, { moduleMap, meta }: Awaited<ReturnType<typeof Factory>>, isAgent?: boolean): Promise<supertest.SuperTestWithHost<Test> & Pick<supertest.Request, "use" | "on" | "set" | "query" | "type" | "accept" | "auth" | "withCredentials" | "retry" | "ok" | "redirects" | "timeout" | "buffer" | "serialize" | "parse" | "ca" | "key" | "pfx" | "cert"> & {
15
15
  module: <T extends Construct>(Module: T) => SuperTestRequest<PickFunc<InstanceType<T>>>;
16
16
  }>;
17
17
 
package/dist/test.d.ts CHANGED
@@ -2,8 +2,8 @@ import * as supertest from 'supertest';
2
2
  import { Test } from 'supertest';
3
3
  import { Server } from 'node:http';
4
4
  import { Construct } from 'phecda-core';
5
- import { F as Factory } from './core-CYwEPfN4.js';
6
- import { P as PickFunc } from './meta-BXKLFTgG.js';
5
+ import { F as Factory } from './core-CUTbX_IS.js';
6
+ import { P as PickFunc } from './meta-CR-D39hQ.js';
7
7
 
8
8
  declare function TestFactory<T extends Construct[]>(...Modules: T): Promise<{
9
9
  get<C extends T[number]>(Model: C): InstanceType<C>;
@@ -11,7 +11,7 @@ declare function TestFactory<T extends Construct[]>(...Modules: T): Promise<{
11
11
  type SuperTestRequest<T> = {
12
12
  [K in keyof T]: T[K] extends (...args: infer R) => any ? (...args: R) => Test : never;
13
13
  };
14
- declare function TestHttp(app: Server | any, { moduleMap, meta }: Awaited<ReturnType<typeof Factory>>, isAgent?: boolean): Promise<supertest.SuperTestWithHost<Test> & Pick<supertest.Request, "type" | "query" | "key" | "use" | "on" | "set" | "accept" | "auth" | "withCredentials" | "retry" | "ok" | "redirects" | "timeout" | "buffer" | "serialize" | "parse" | "ca" | "pfx" | "cert"> & {
14
+ declare function TestHttp(app: Server | any, { moduleMap, meta }: Awaited<ReturnType<typeof Factory>>, isAgent?: boolean): Promise<supertest.SuperTestWithHost<Test> & Pick<supertest.Request, "use" | "on" | "set" | "query" | "type" | "accept" | "auth" | "withCredentials" | "retry" | "ok" | "redirects" | "timeout" | "buffer" | "serialize" | "parse" | "ca" | "key" | "pfx" | "cert"> & {
15
15
  module: <T extends Construct>(Module: T) => SuperTestRequest<PickFunc<InstanceType<T>>>;
16
16
  }>;
17
17
 
package/dist/test.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }
2
2
 
3
- var _chunk7YQ57BQSjs = require('./chunk-7YQ57BQS.js');
3
+ var _chunk6OQ2SB5Wjs = require('./chunk-6OQ2SB5W.js');
4
4
 
5
5
 
6
- var _chunkJ5CFUN4Vjs = require('./chunk-J5CFUN4V.js');
6
+ var _chunk4LLLQOMFjs = require('./chunk-4LLLQOMF.js');
7
7
 
8
8
  // src/test.ts
9
9
  var _phecdacore = require('phecda-core');
10
10
  async function TestFactory(...Modules) {
11
- const { moduleMap, modelMap } = await _chunk7YQ57BQSjs.Factory.call(void 0, Modules);
11
+ const { moduleMap, modelMap } = await _chunk6OQ2SB5Wjs.Factory.call(void 0, Modules);
12
12
  return {
13
13
  get(Model) {
14
14
  const tag = _phecdacore.getTag.call(void 0, Model);
@@ -19,7 +19,7 @@ async function TestFactory(...Modules) {
19
19
  }
20
20
  };
21
21
  }
22
- _chunkJ5CFUN4Vjs.__name.call(void 0, TestFactory, "TestFactory");
22
+ _chunk4LLLQOMFjs.__name.call(void 0, TestFactory, "TestFactory");
23
23
  async function TestHttp(app, { moduleMap, meta }, isAgent = true) {
24
24
  const { default: request, agent } = await Promise.resolve().then(() => _interopRequireWildcard(require("supertest")));
25
25
  const Agent = agent(app);
@@ -59,11 +59,11 @@ async function TestHttp(app, { moduleMap, meta }, isAgent = true) {
59
59
  }
60
60
  });
61
61
  }
62
- _chunkJ5CFUN4Vjs.__name.call(void 0, module, "module");
62
+ _chunk4LLLQOMFjs.__name.call(void 0, module, "module");
63
63
  Agent.module = module;
64
64
  return Agent;
65
65
  }
66
- _chunkJ5CFUN4Vjs.__name.call(void 0, TestHttp, "TestHttp");
66
+ _chunk4LLLQOMFjs.__name.call(void 0, TestHttp, "TestHttp");
67
67
 
68
68
 
69
69
 
package/dist/test.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Factory
3
- } from "./chunk-XYVMNY2X.mjs";
3
+ } from "./chunk-YCES6ABN.mjs";
4
4
  import {
5
5
  __name
6
- } from "./chunk-WHJ5FALK.mjs";
6
+ } from "./chunk-NQ55PA2X.mjs";
7
7
 
8
8
  // src/test.ts
9
9
  import { getTag } from "phecda-core";
@@ -1,5 +1,5 @@
1
1
  import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
2
- import { D as DefaultOptions, B as BaseContext } from './meta-BXKLFTgG.mjs';
2
+ import { D as DefaultOptions, B as BaseCtx } from './meta-CR-D39hQ.js';
3
3
 
4
4
  interface HttpOptions extends DefaultOptions {
5
5
  /**
@@ -15,13 +15,14 @@ interface HttpOptions extends DefaultOptions {
15
15
  */
16
16
  dynamic?: boolean;
17
17
  }
18
- interface HttpContext extends BaseContext {
18
+ interface HttpCtx extends BaseCtx {
19
19
  parallel?: true;
20
20
  index?: number;
21
21
  query: Record<string, any>;
22
22
  params: Record<string, string>;
23
23
  body: Record<string, any>;
24
24
  headers: IncomingHttpHeaders;
25
+ category: 'http';
25
26
  redirect: (url: string, status?: number) => void;
26
27
  getCookie(key: string): string | undefined;
27
28
  setCookie(key: string, value: string, opts?: CookieSerializeOptions): void;
@@ -44,4 +45,4 @@ interface CookieSerializeOptions {
44
45
  partitioned?: boolean;
45
46
  }
46
47
 
47
- export type { CookieSerializeOptions as C, HttpContext as H, HttpOptions as a };
48
+ export type { CookieSerializeOptions as C, HttpCtx as H, HttpOptions as a };
@@ -1,4 +1,4 @@
1
- import { D as DefaultOptions, B as BaseContext } from './meta-BXKLFTgG.mjs';
1
+ import { D as DefaultOptions, B as BaseCtx } from './meta-CR-D39hQ.js';
2
2
 
3
3
  interface RpcServerOptions extends DefaultOptions {
4
4
  defaultQueue?: string;
@@ -8,11 +8,12 @@ interface RpcClientOptions {
8
8
  timeout?: number;
9
9
  max?: number;
10
10
  }
11
- interface RpcContext extends BaseContext {
11
+ interface RpcCtx extends BaseCtx {
12
12
  args: any[];
13
13
  id: string;
14
14
  queue: string;
15
15
  isEvent?: boolean;
16
+ category: 'rpc';
16
17
  }
17
18
 
18
- export type { RpcContext as R, RpcServerOptions as a, RpcClientOptions as b };
19
+ export type { RpcCtx as R, RpcServerOptions as a, RpcClientOptions as b };
@@ -1,5 +1,5 @@
1
1
  import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
2
- import { D as DefaultOptions, B as BaseContext } from './meta-BXKLFTgG.js';
2
+ import { D as DefaultOptions, B as BaseCtx } from './meta-CR-D39hQ.mjs';
3
3
 
4
4
  interface HttpOptions extends DefaultOptions {
5
5
  /**
@@ -15,13 +15,14 @@ interface HttpOptions extends DefaultOptions {
15
15
  */
16
16
  dynamic?: boolean;
17
17
  }
18
- interface HttpContext extends BaseContext {
18
+ interface HttpCtx extends BaseCtx {
19
19
  parallel?: true;
20
20
  index?: number;
21
21
  query: Record<string, any>;
22
22
  params: Record<string, string>;
23
23
  body: Record<string, any>;
24
24
  headers: IncomingHttpHeaders;
25
+ category: 'http';
25
26
  redirect: (url: string, status?: number) => void;
26
27
  getCookie(key: string): string | undefined;
27
28
  setCookie(key: string, value: string, opts?: CookieSerializeOptions): void;
@@ -44,4 +45,4 @@ interface CookieSerializeOptions {
44
45
  partitioned?: boolean;
45
46
  }
46
47
 
47
- export type { CookieSerializeOptions as C, HttpContext as H, HttpOptions as a };
48
+ export type { CookieSerializeOptions as C, HttpCtx as H, HttpOptions as a };
@@ -1,4 +1,4 @@
1
- import { D as DefaultOptions, B as BaseContext } from './meta-BXKLFTgG.js';
1
+ import { D as DefaultOptions, B as BaseCtx } from './meta-CR-D39hQ.mjs';
2
2
 
3
3
  interface RpcServerOptions extends DefaultOptions {
4
4
  defaultQueue?: string;
@@ -8,11 +8,12 @@ interface RpcClientOptions {
8
8
  timeout?: number;
9
9
  max?: number;
10
10
  }
11
- interface RpcContext extends BaseContext {
11
+ interface RpcCtx extends BaseCtx {
12
12
  args: any[];
13
13
  id: string;
14
14
  queue: string;
15
15
  isEvent?: boolean;
16
+ category: 'rpc';
16
17
  }
17
18
 
18
- export type { RpcContext as R, RpcServerOptions as a, RpcClientOptions as b };
19
+ export type { RpcCtx as R, RpcServerOptions as a, RpcClientOptions as b };
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "phecda-server",
3
- "version": "7.0.0-alpha.1",
3
+ "version": "7.0.0-alpha.10",
4
4
  "description": "server framework that provide IOC/type-reuse/http&rpc-adaptor",
5
5
  "author": "fgsreally",
6
6
  "license": "MIT",
7
7
  "repository": "https://github.com/fgsreally/phecda/tree/main/packages/server",
8
8
  "keywords": [
9
9
  "server",
10
+ "http",
10
11
  "IOC",
11
12
  "rpc",
12
- "types-share"
13
+ "types-safe"
13
14
  ],
14
15
  "exports": {
15
16
  ".": {
@@ -129,7 +130,8 @@
129
130
  }
130
131
  },
131
132
  "bin": {
132
- "phecda": "bin/cli.mjs"
133
+ "phecda": "bin/cli.mjs",
134
+ "phecda-server": "bin/cli.mjs"
133
135
  },
134
136
  "files": [
135
137
  "dist",
@@ -143,11 +145,11 @@
143
145
  "chokidar": "^3.5.3",
144
146
  "debug": "^4.3.4",
145
147
  "fs-extra": "^11.2.0",
146
- "h3": "^1.12.0",
147
148
  "picocolors": "^1.0.0",
148
149
  "reflect-metadata": "^0.1.13",
149
150
  "ts-mixer": "^6.0.4",
150
- "phecda-core": "4.0.1"
151
+ "unconfig": "^0.6.0",
152
+ "phecda-core": "4.1.0-alpha.0"
151
153
  },
152
154
  "devDependencies": {
153
155
  "@koa/router": "^12.0.1",
@@ -164,6 +166,7 @@
164
166
  "elysia": "^1.0.17",
165
167
  "express": "^4.18.2",
166
168
  "fastify": "^4.25.1",
169
+ "h3": "^1.12.0",
167
170
  "hono": "^4.3.4",
168
171
  "hyper-express": "^6.15.2",
169
172
  "ioredis": "^5.3.2",
@@ -0,0 +1,30 @@
1
+ export default ['Addon', 'Arg', 'Assign', 'BadGatewayException', 'BadRequestException',
2
+ 'Base', 'Body', 'Clear',
3
+ 'ConflictException', 'Controller',
4
+ 'Ctx', 'CustomResponse',
5
+ 'Delete',
6
+ 'Define',
7
+ 'ERROR_SYMBOL',
8
+ 'Effect', 'Empty', 'Err', 'Exception', 'Expose', 'Factory', 'Filter', 'ForbiddenException',
9
+ 'FrameworkException',
10
+ 'Generator', 'Get', 'Global', 'Guard', 'HTTPGenerator', 'Head', 'Header', 'HttpBase',
11
+ 'If', 'Init', 'Inject', 'Injectable',
12
+ 'InvalidInputException', 'Isolate',
13
+ 'Mixin',
14
+ 'NotFoundException', 'PAddon', 'PExtension', 'PFilter', 'PGuard',
15
+ 'PPipe', 'Param', 'Patch', 'PayloadLargeException', 'Pipe', 'Pipeline', 'Post',
16
+ 'Provide', 'Put', 'Query', 'Queue', 'RPCGenerator', 'Route',
17
+ 'Rpc', 'RpcBase', 'Search', 'ServerBase', 'ServerPhecda', 'ServiceUnavailableException', 'Storage',
18
+ 'Tag', 'TimeoutException', 'TimerException', 'UnauthorizedException', 'UndefinedException',
19
+ 'Unique', 'Unmount', 'UnsupportedMediaTypeException', 'ValidateException',
20
+ 'Watcher', 'WorkerException',
21
+ 'addAddon', 'addDecoToClass',
22
+ 'addFilter', 'addGuard', 'addPipe', 'emitter',
23
+ 'getMergedMeta',
24
+ 'getMeta', 'getMetaKey', 'getMetaParams', 'getOwnMeta', 'getOwnMetaKey', 'getOwnMetaParams',
25
+ 'getTag',
26
+ 'isPhecda', 'log', 'phecdaNamespace', 'runMiddleware',
27
+ 'setInject',
28
+ 'setLogger',
29
+ 'setMeta',
30
+ 'useS', 'wait']
@@ -1,40 +1,50 @@
1
- import { register } from 'node:module'
2
- import { MessageChannel } from 'node:worker_threads'
3
- import { log } from '../dist/index.mjs'
4
- const { port1, port2 } = new MessageChannel()
5
-
6
- register('./loader.mjs', {
7
- parentURL: import.meta.url,
8
- data: { port: port2 },
9
- transferList: [port2],
10
- })
11
-
12
- let isRunning = true
13
-
14
- port1.on('message', async (data) => {
15
- const { type, files } = JSON.parse(data)
16
-
17
- if (!isRunning || !globalThis.__PS_HMR__ || type === 'relaunch')
18
- return process.exit(2)// file change -> relaunch
19
-
20
- if (type === 'change') {
21
- log('reload module...')
22
-
23
- for (const cb of globalThis.__PS_HMR__) await cb(files)
24
-
25
- log('reload done')
26
- }
27
- })
28
-
29
- process.on('uncaughtException', (err) => {
30
- log('Uncaught Exception:', 'error')
31
- isRunning = false
32
- console.error(err)
33
- })
34
-
35
- process.on('unhandledRejection', (err) => {
36
- log('Unhandled Promise Rejection:', 'error')
37
- isRunning = false
38
-
39
- console.error(err)
40
- })
1
+ import { register } from 'node:module'
2
+ import { MessageChannel } from 'node:worker_threads'
3
+ import { isPhecda, log } from '../dist/index.mjs'
4
+ import { RELAUNCH, RELOAD } from '../dist/helper.mjs'
5
+ const { port1, port2 } = new MessageChannel()
6
+
7
+ register('./loader.mjs', {
8
+ parentURL: import.meta.url,
9
+ data: { port: port2 },
10
+ transferList: [port2],
11
+ })
12
+
13
+ let isRunning = true
14
+
15
+ const fileModelMap = new Map()
16
+
17
+ port1.on('message', async (data) => {
18
+ const { type, files } = JSON.parse(data)
19
+
20
+ if (!isRunning || type === 'relaunch')
21
+ return RELAUNCH()// file change -> relaunch
22
+
23
+ if (type === 'change' || type === 'init') {
24
+ if (!files.length)
25
+ return
26
+ const oldModels = []
27
+ const newModels = []
28
+ for (const file of files) {
29
+ oldModels.push(...fileModelMap.get(file) || [])
30
+ const models = Object.values(await import(file)).filter(isPhecda)
31
+ fileModelMap.set(file, models)
32
+ newModels.push(...models)
33
+ }
34
+ if (type === 'change')
35
+ return RELOAD(oldModels, newModels)
36
+ }
37
+ })
38
+
39
+ process.on('uncaughtException', (err) => {
40
+ log('Uncaught Exception:', 'error')
41
+ isRunning = false
42
+ console.error(err)
43
+ })
44
+
45
+ process.on('unhandledRejection', (err) => {
46
+ log('Unhandled Promise Rejection:', 'error')
47
+ isRunning = false
48
+
49
+ console.error(err)
50
+ })
@@ -2,26 +2,57 @@ import { fileURLToPath, pathToFileURL } from 'url'
2
2
  import { writeFile } from 'fs/promises'
3
3
  import {
4
4
  basename,
5
+ dirname,
5
6
  extname,
6
7
  isAbsolute,
7
8
  relative,
8
9
  resolve as resolvePath,
9
10
  } from 'path'
10
- import { createRequire } from 'module'
11
+ import { existsSync } from 'fs'
11
12
  import ts from 'typescript'
12
13
  import chokidar from 'chokidar'
13
- import { log } from '../dist/index.mjs'
14
+ import Debug from 'debug'
15
+ import { loadConfig } from 'unconfig'
14
16
  import { compile, genUnImportRet, handleClassTypes, slash } from './utils.mjs'
15
17
 
16
- let port
18
+ const debug = Debug('phecda-server/loader')
17
19
 
18
20
  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 = {
21
+ const IS_DEV = process.env.NODE_ENV === 'development'
22
+ let port
23
+ let config
24
+ const workdir = process.cwd()
25
+ const configPath = resolvePath(
26
+ workdir,
27
+ process.env.PS_CONFIG_FILE || 'ps.json',
28
+ )
29
+
30
+ // unimport
31
+ let unimportRet
32
+ const dtsPath = process.env.PS_DTS_PATH || 'ps.d.ts'
33
+
34
+ // graph
35
+ let entryUrl
36
+ const watchFiles = new Set()
37
+ const filesRecord = new Map()
38
+ const moduleGraph = {}
39
+ // ts
40
+ let tsconfig = {
22
41
  module: ts.ModuleKind.ESNext,
23
42
  moduleResolution: ts.ModuleResolutionKind.NodeNext,
24
43
  }
44
+ const EXTENSIONS = [ts.Extension.Ts, ts.Extension.Tsx, ts.Extension.Mts]
45
+ const tsconfigPath = resolvePath(process.cwd(), 'tsconfig.json')
46
+ const tsRet = ts.readConfigFile(tsconfigPath, ts.sys.readFile)
47
+ if (!tsRet.error) {
48
+ const { error, options } = ts.parseJsonConfigFileContent(
49
+ tsRet.config,
50
+ ts.sys,
51
+ dirname(tsconfigPath),
52
+ )
53
+ if (!error)
54
+ tsconfig = options
55
+ }
25
56
  const moduleResolutionCache = ts.createModuleResolutionCache(
26
57
  ts.sys.getCurrentDirectory(),
27
58
  x => x,
@@ -32,32 +63,31 @@ const host = {
32
63
  readFile: ts.sys.readFile,
33
64
  }
34
65
 
35
- let unimportRet
36
- const dtsPath = 'ps.d.ts'
37
-
38
66
  if (isLowVersion)
39
67
  await initialize()
40
68
 
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
69
  export async function initialize(data) {
52
70
  if (data)
53
71
  port = data.port
54
- log('read config...')
55
72
 
56
- config = require(configPath)
73
+ debug('read config...')
74
+
75
+ const unconfigRet = await loadConfig({
76
+ sources: [
77
+ {
78
+ files: configPath,
79
+ extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json', ''],
80
+ },
81
+ ],
82
+ merge: false,
83
+ })
84
+ config = unconfigRet.config
57
85
  if (!config.virtualFile)
58
86
  config.virtualFile = {}
87
+ if (!config.paths)
88
+ config.paths = {}
59
89
 
60
- if (!process.env.PS_HMR_BAN) {
90
+ if (IS_DEV) {
61
91
  chokidar.watch(configPath, { persistent: true }).on('change', () => {
62
92
  port.postMessage(
63
93
  JSON.stringify({
@@ -71,17 +101,18 @@ export async function initialize(data) {
71
101
  return
72
102
  unimportRet = await genUnImportRet(config.unimport)
73
103
  if (unimportRet) {
74
- log('auto import...')
104
+ debug('auto import...')
75
105
  await unimportRet.init()
76
106
 
107
+ const unimportDtsPath = resolvePath(workdir, dtsPath)
77
108
  writeFile(
78
- resolvePath(workdir, config.unimport.dtsPath || dtsPath),
109
+ unimportDtsPath,
79
110
  handleClassTypes(
80
111
  await unimportRet.generateTypeDeclarations({
81
112
  resolvePath: (i) => {
82
113
  if (i.from.startsWith('.') || isAbsolute(i.from)) {
83
114
  const related = slash(
84
- relative(workdir, i.from).replace(/\.ts(x)?$/, ''),
115
+ relative(dirname(unimportDtsPath), i.from).replace(/\.ts(x)?$/, ''),
85
116
  )
86
117
 
87
118
  return !related.startsWith('.') ? `./${related}` : related
@@ -94,12 +125,6 @@ export async function initialize(data) {
94
125
  }
95
126
  }
96
127
 
97
- const watchFiles = new Set()
98
- const filesRecord = new Map()
99
- const moduleGraph = {}
100
-
101
- let entryUrl
102
-
103
128
  function addUrlToGraph(url, parent) {
104
129
  if (!(url in moduleGraph))
105
130
  moduleGraph[url] = new Set()
@@ -127,13 +152,20 @@ export const resolve = async (specifier, context, nextResolve) => {
127
152
  }
128
153
  // entrypoint
129
154
  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,
155
+ if (/^file:\/\/\//.test(specifier) && existsSync(fileURLToPath(specifier))) {
156
+ entryUrl = specifier
157
+
158
+ return {
159
+ format: EXTENSIONS.some(ext => specifier.endsWith(ext))
160
+ ? 'ts'
161
+ : undefined,
162
+ url: specifier,
163
+ shortCircuit: true,
164
+ }
165
+ }
166
+ else {
167
+ // won't resolve virtual file as entry in vite
168
+ return nextResolve(specifier)
137
169
  }
138
170
  }
139
171
  // url import
@@ -229,32 +261,17 @@ export const load = async (url, context, nextLoad) => {
229
261
  && !isLowVersion
230
262
  ) {
231
263
  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) {
264
+
265
+ if (IS_DEV) {
266
+ if (isModuleFileUrl(url)) {
267
+ port.postMessage(
268
+ JSON.stringify({
269
+ type: 'init',
270
+ files: [fileURLToPath(url)],
271
+ }),
272
+ )
273
+ }
274
+
258
275
  chokidar.watch(fileURLToPath(url), { persistent: true }).on(
259
276
  'change',
260
277
  debounce(() => {
@@ -289,7 +306,8 @@ export const load = async (url, context, nextLoad) => {
289
306
 
290
307
  const code
291
308
  = typeof source === 'string' ? source : Buffer.from(source).toString()
292
- const compiled = await compile(code, url)
309
+ const compiled = (await compile(code, url)).replace(/_ts_metadata\(\"design:paramtypes\"\,/g, '_ts_metadata("design:paramtypes",()=>')// handle cycle
310
+
293
311
  if (unimportRet) {
294
312
  const { injectImports } = unimportRet
295
313
  return {
@@ -357,7 +375,7 @@ export function isModuleFileUrl(url) {
357
375
  'addon',
358
376
  'filter',
359
377
  'pipe',
360
- 'edge',
378
+ 'solo',
361
379
  ].includes(midName)
362
380
  )
363
381
  return true