@thinkbun/plugin 1.0.0 → 1.0.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.
@@ -0,0 +1,10 @@
1
+ import { Plugin } from "@thinkbun/core";
2
+
3
+ //#region src/logger.d.ts
4
+ declare const LoggerPlugin: Plugin;
5
+ //#endregion
6
+ //#region src/server.d.ts
7
+ declare const ServerPlugin: Plugin;
8
+ //#endregion
9
+ export { LoggerPlugin, ServerPlugin };
10
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/logger.ts","../src/server.ts"],"sourcesContent":[],"mappings":";;;cAOa,cAAc;;;cCGd,cAAc"}
package/dist/index.mjs ADDED
@@ -0,0 +1,91 @@
1
+ import { invariant } from "@thinkbun/core";
2
+ import pc from "picocolors";
3
+ import cluster from "node:cluster";
4
+ import os from "node:os";
5
+ import { isNumber } from "lodash-es";
6
+
7
+ //#region src/logger.ts
8
+ const colorMap = {
9
+ app: "yellow",
10
+ PluginManager: "yellow"
11
+ };
12
+ const LoggerPlugin = {
13
+ name: "LoggerPlugin",
14
+ enforce: "pre",
15
+ setup(app) {
16
+ const genScope = (scope) => Array.isArray(scope) ? scope.map((el) => `[${el}]`) : `[${scope}]`;
17
+ app.logger = {
18
+ info: (msg, scope = "app") => console.log(pc[colorMap[scope] || "yellow"](genScope(scope)), msg),
19
+ error: (msg, scope = "app") => console.error(pc[colorMap[scope] || "yellow"](genScope(scope)), msg),
20
+ debug: (msg, scope = "app") => console.debug(pc[colorMap[scope] || "yellow"](genScope(scope)), msg),
21
+ warn: (msg, scope = "app") => console.warn(pc[colorMap[scope] || "yellow"](genScope(scope)), msg)
22
+ };
23
+ }
24
+ };
25
+
26
+ //#endregion
27
+ //#region src/server.ts
28
+ const isTest = typeof Bun !== "undefined" && Bun.env.NODE_ENV === "test";
29
+ let shuttingDown = false;
30
+ let isPrimary = false;
31
+ const ServerPlugin = {
32
+ name: "ServerPlugin",
33
+ enforce: "post",
34
+ run(app) {
35
+ isPrimary = cluster.isPrimary;
36
+ const { workers: configWorkers } = app.loader.config;
37
+ invariant(isNumber(configWorkers), "config.workers must be a number");
38
+ const cpuCount = os.cpus().length;
39
+ const workers = configWorkers === 0 ? cpuCount : Math.max(1, Math.min(cpuCount, configWorkers));
40
+ if (isPrimary && workers > 1) {
41
+ for (let i = 0; i < workers; i++) cluster.fork();
42
+ cluster.on("exit", () => {
43
+ if (shuttingDown) return;
44
+ cluster.fork();
45
+ });
46
+ } else {
47
+ app.server = Bun.serve({
48
+ port: app.loader.config.port,
49
+ hostname: app.loader.config.host,
50
+ reusePort: true,
51
+ routes: app.routes
52
+ });
53
+ process.on("message", async (msg) => {
54
+ if (typeof msg === "object" && msg !== null && msg.type === "shutdown") {
55
+ await app.server?.stop?.();
56
+ process.exit(0);
57
+ }
58
+ });
59
+ }
60
+ },
61
+ async close(app) {
62
+ if (isTest) {
63
+ await app.server?.stop?.();
64
+ return;
65
+ }
66
+ if (!isPrimary) {
67
+ await app.server?.stop?.();
68
+ process.exit(0);
69
+ }
70
+ if (shuttingDown) return;
71
+ shuttingDown = true;
72
+ for (const id in cluster.workers) cluster.workers[id]?.send({ type: "shutdown" });
73
+ await new Promise((resolve) => {
74
+ const timer = setTimeout(() => {
75
+ for (const id in cluster.workers) cluster.workers[id]?.kill("SIGKILL");
76
+ resolve();
77
+ }, 5e3);
78
+ cluster.on("exit", () => {
79
+ if (Object.keys(cluster?.workers || {}).length === 0) {
80
+ clearTimeout(timer);
81
+ resolve();
82
+ }
83
+ });
84
+ });
85
+ process.exit(0);
86
+ }
87
+ };
88
+
89
+ //#endregion
90
+ export { LoggerPlugin, ServerPlugin };
91
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["LoggerPlugin: Plugin","ServerPlugin: Plugin"],"sources":["../src/logger.ts","../src/server.ts"],"sourcesContent":["import { type Plugin } from '@thinkbun/core';\nimport pc from 'picocolors';\n\nconst colorMap = {\n app: 'yellow',\n PluginManager: 'yellow',\n};\nexport const LoggerPlugin: Plugin = {\n name: 'LoggerPlugin',\n enforce: 'pre',\n setup(app) {\n const genScope = (scope: string | string[]) => (Array.isArray(scope) ? scope.map((el) => `[${el}]`) : `[${scope}]`);\n app.logger = {\n // @ts-ignore\n info: (msg: string, scope = 'app') => console.log(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),\n // @ts-ignore\n error: (msg: string, scope = 'app') => console.error(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),\n // @ts-ignore\n debug: (msg: string, scope = 'app') => console.debug(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),\n // @ts-ignore\n warn: (msg: string, scope = 'app') => console.warn(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),\n };\n },\n};\n","import cluster from 'node:cluster';\nimport os from 'node:os';\n\nimport { invariant, type Plugin } from '@thinkbun/core';\nimport { isNumber } from 'lodash-es';\n\nconst isTest = typeof Bun !== 'undefined' && Bun.env.NODE_ENV === 'test';\n\nlet shuttingDown = false;\nlet isPrimary = false;\nexport const ServerPlugin: Plugin = {\n name: 'ServerPlugin',\n enforce: 'post',\n run(app) {\n isPrimary = cluster.isPrimary;\n const { workers: configWorkers } = app.loader.config;\n invariant(isNumber(configWorkers), 'config.workers must be a number');\n const cpuCount = os.cpus().length;\n const workers = configWorkers === 0 ? cpuCount : Math.max(1, Math.min(cpuCount, configWorkers));\n if (isPrimary && workers > 1) {\n for (let i = 0; i < workers; i++) {\n cluster.fork();\n }\n\n (cluster as any).on('exit', () => {\n if (shuttingDown) return;\n cluster.fork();\n });\n } else {\n app.server = Bun.serve({\n port: app.loader.config.port,\n hostname: app.loader.config.host,\n reusePort: true,\n routes: app.routes,\n });\n\n process.on('message', async (msg: { type: string }) => {\n if (typeof msg === 'object' && msg !== null && msg.type === 'shutdown') {\n await app.server?.stop?.();\n process.exit(0);\n }\n });\n }\n },\n async close(app) {\n if (isTest) {\n // 只关闭 server,不退出进程\n await app.server?.stop?.();\n return;\n }\n // 只允许 primary 主动关闭 cluster\n if (!isPrimary) {\n await app.server?.stop?.();\n process.exit(0);\n }\n\n if (shuttingDown) return;\n shuttingDown = true;\n\n // 通知所有 worker\n for (const id in cluster.workers) {\n cluster.workers[id]?.send({ type: 'shutdown' });\n }\n\n // 等待 worker 退出 or 强杀\n await new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n for (const id in cluster.workers) {\n cluster.workers[id]?.kill('SIGKILL');\n }\n resolve();\n }, 5000);\n (cluster as any).on('exit', () => {\n if (Object.keys(cluster?.workers || {}).length === 0) {\n clearTimeout(timer);\n resolve();\n }\n });\n });\n\n process.exit(0);\n },\n};\n"],"mappings":";;;;;;;AAGA,MAAM,WAAW;CACf,KAAK;CACL,eAAe;CAChB;AACD,MAAaA,eAAuB;CAClC,MAAM;CACN,SAAS;CACT,MAAM,KAAK;EACT,MAAM,YAAY,UAA8B,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,OAAO,IAAI,GAAG,GAAG,GAAG,IAAI,MAAM;AAChH,MAAI,SAAS;GAEX,OAAO,KAAa,QAAQ,UAAU,QAAQ,IAAI,GAAG,SAAS,UAAU,UAAU,SAAS,MAAM,CAAC,EAAE,IAAI;GAExG,QAAQ,KAAa,QAAQ,UAAU,QAAQ,MAAM,GAAG,SAAS,UAAU,UAAU,SAAS,MAAM,CAAC,EAAE,IAAI;GAE3G,QAAQ,KAAa,QAAQ,UAAU,QAAQ,MAAM,GAAG,SAAS,UAAU,UAAU,SAAS,MAAM,CAAC,EAAE,IAAI;GAE3G,OAAO,KAAa,QAAQ,UAAU,QAAQ,KAAK,GAAG,SAAS,UAAU,UAAU,SAAS,MAAM,CAAC,EAAE,IAAI;GAC1G;;CAEJ;;;;ACjBD,MAAM,SAAS,OAAO,QAAQ,eAAe,IAAI,IAAI,aAAa;AAElE,IAAI,eAAe;AACnB,IAAI,YAAY;AAChB,MAAaC,eAAuB;CAClC,MAAM;CACN,SAAS;CACT,IAAI,KAAK;AACP,cAAY,QAAQ;EACpB,MAAM,EAAE,SAAS,kBAAkB,IAAI,OAAO;AAC9C,YAAU,SAAS,cAAc,EAAE,kCAAkC;EACrE,MAAM,WAAW,GAAG,MAAM,CAAC;EAC3B,MAAM,UAAU,kBAAkB,IAAI,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,UAAU,cAAc,CAAC;AAC/F,MAAI,aAAa,UAAU,GAAG;AAC5B,QAAK,IAAI,IAAI,GAAG,IAAI,SAAS,IAC3B,SAAQ,MAAM;AAGhB,GAAC,QAAgB,GAAG,cAAc;AAChC,QAAI,aAAc;AAClB,YAAQ,MAAM;KACd;SACG;AACL,OAAI,SAAS,IAAI,MAAM;IACrB,MAAM,IAAI,OAAO,OAAO;IACxB,UAAU,IAAI,OAAO,OAAO;IAC5B,WAAW;IACX,QAAQ,IAAI;IACb,CAAC;AAEF,WAAQ,GAAG,WAAW,OAAO,QAA0B;AACrD,QAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,IAAI,SAAS,YAAY;AACtE,WAAM,IAAI,QAAQ,QAAQ;AAC1B,aAAQ,KAAK,EAAE;;KAEjB;;;CAGN,MAAM,MAAM,KAAK;AACf,MAAI,QAAQ;AAEV,SAAM,IAAI,QAAQ,QAAQ;AAC1B;;AAGF,MAAI,CAAC,WAAW;AACd,SAAM,IAAI,QAAQ,QAAQ;AAC1B,WAAQ,KAAK,EAAE;;AAGjB,MAAI,aAAc;AAClB,iBAAe;AAGf,OAAK,MAAM,MAAM,QAAQ,QACvB,SAAQ,QAAQ,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAIjD,QAAM,IAAI,SAAe,YAAY;GACnC,MAAM,QAAQ,iBAAiB;AAC7B,SAAK,MAAM,MAAM,QAAQ,QACvB,SAAQ,QAAQ,KAAK,KAAK,UAAU;AAEtC,aAAS;MACR,IAAK;AACR,GAAC,QAAgB,GAAG,cAAc;AAChC,QAAI,OAAO,KAAK,SAAS,WAAW,EAAE,CAAC,CAAC,WAAW,GAAG;AACpD,kBAAa,MAAM;AACnB,cAAS;;KAEX;IACF;AAEF,UAAQ,KAAK,EAAE;;CAElB"}
package/package.json CHANGED
@@ -1,8 +1,17 @@
1
1
  {
2
2
  "name": "@thinkbun/plugin",
3
- "version": "1.0.0",
4
- "module": "src/index.ts",
3
+ "version": "1.0.1",
5
4
  "type": "module",
5
+ "exports": {
6
+ ".": "./dist/index.mjs",
7
+ "./package.json": "./package.json"
8
+ },
9
+ "main": "./dist/index.mjs",
10
+ "module": "./dist/index.mjs",
11
+ "types": "./dist/index.d.mts",
12
+ "scripts": {
13
+ "build": "tsdown"
14
+ },
6
15
  "devDependencies": {
7
16
  "@types/bun": "latest"
8
17
  },
@@ -13,6 +22,9 @@
13
22
  "picocolors": "^1.1.1",
14
23
  "@thinkbun/core": "workspace:*"
15
24
  },
25
+ "files": [
26
+ "dist"
27
+ ],
16
28
  "publishConfig": {
17
29
  "access": "public"
18
30
  }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './logger.ts';
2
- export * from './server.ts';
package/src/logger.ts DELETED
@@ -1,24 +0,0 @@
1
- import { type Plugin } from '@thinkbun/core';
2
- import pc from 'picocolors';
3
-
4
- const colorMap = {
5
- app: 'yellow',
6
- PluginManager: 'yellow',
7
- };
8
- export const LoggerPlugin: Plugin = {
9
- name: 'LoggerPlugin',
10
- enforce: 'pre',
11
- setup(app) {
12
- const genScope = (scope: string | string[]) => (Array.isArray(scope) ? scope.map((el) => `[${el}]`) : `[${scope}]`);
13
- app.logger = {
14
- // @ts-ignore
15
- info: (msg: string, scope = 'app') => console.log(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),
16
- // @ts-ignore
17
- error: (msg: string, scope = 'app') => console.error(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),
18
- // @ts-ignore
19
- debug: (msg: string, scope = 'app') => console.debug(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),
20
- // @ts-ignore
21
- warn: (msg: string, scope = 'app') => console.warn(pc[colorMap[scope] || 'yellow'](genScope(scope)), msg),
22
- };
23
- },
24
- };
package/src/server.ts DELETED
@@ -1,83 +0,0 @@
1
- import cluster from 'node:cluster';
2
- import os from 'node:os';
3
-
4
- import { type Plugin } from '@thinkbun/core';
5
-
6
- const isTest = typeof Bun !== 'undefined' && Bun.env.NODE_ENV === 'test';
7
-
8
- let shuttingDown = false;
9
- let isPrimary = false;
10
- export const ServerPlugin: Plugin = {
11
- name: 'ServerPlugin',
12
- enforce: 'post',
13
- run(app) {
14
- isPrimary = cluster.isPrimary;
15
- isPrimary = cluster.isPrimary;
16
- const cpuCount = os.cpus().length;
17
- const workers = Math.max(1, Math.min(cpuCount, app.loader.config.workers));
18
-
19
- if (isPrimary && workers > 1) {
20
- for (let i = 0; i < workers; i++) {
21
- cluster.fork();
22
- }
23
-
24
- cluster.on('exit', () => {
25
- if (shuttingDown) return;
26
- cluster.fork();
27
- });
28
- } else {
29
- app.server = Bun.serve({
30
- port: app.loader.config.port,
31
- hostname: app.loader.config.host,
32
- reusePort: true,
33
- routes: app.routes,
34
- });
35
-
36
- process.on('message', async (msg: { type: string }) => {
37
- if (typeof msg === 'object' && msg !== null && msg.type === 'shutdown') {
38
- await app.server?.stop?.();
39
- process.exit(0);
40
- }
41
- });
42
- }
43
- },
44
- async close(app) {
45
- if (isTest) {
46
- // 只关闭 server,不退出进程
47
- await app.server?.stop?.();
48
- return;
49
- }
50
- // 只允许 primary 主动关闭 cluster
51
- if (!isPrimary) {
52
- await app.server?.stop?.();
53
- process.exit(0);
54
- }
55
-
56
- if (shuttingDown) return;
57
- shuttingDown = true;
58
-
59
- // 通知所有 worker
60
- for (const id in cluster.workers) {
61
- cluster.workers[id]?.send({ type: 'shutdown' });
62
- }
63
-
64
- // 等待 worker 退出 or 强杀
65
- await new Promise<void>((resolve) => {
66
- const timer = setTimeout(() => {
67
- for (const id in cluster.workers) {
68
- cluster.workers[id]?.kill('SIGKILL');
69
- }
70
- resolve();
71
- }, 5000);
72
-
73
- cluster.on('exit', () => {
74
- if (Object.keys(cluster?.workers || {}).length === 0) {
75
- clearTimeout(timer);
76
- resolve();
77
- }
78
- });
79
- });
80
-
81
- process.exit(0);
82
- },
83
- };
package/tsconfig.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "include": ["src"],
4
- }