@fuzionx/core 0.1.38 → 0.1.39

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/lib/app.js CHANGED
@@ -214,7 +214,8 @@ export class FuzionXApp {
214
214
  for (const id in cluster.workers) {
215
215
  cluster.workers[id].process.kill('SIGTERM');
216
216
  }
217
- setTimeout(() => process.exit(0), 3000);
217
+ const shutdownTimeout = this._appConfig?.shutdown_timeout || 5000;
218
+ setTimeout(() => process.exit(0), shutdownTimeout);
218
219
  };
219
220
  process.once('SIGTERM', () => gracefulShutdown('SIGTERM'));
220
221
  process.once('SIGINT', () => gracefulShutdown('SIGINT'));
@@ -227,7 +228,7 @@ export class FuzionXApp {
227
228
  }
228
229
  });
229
230
 
230
- if (callback) setTimeout(() => callback(), 100);
231
+ if (callback) setImmediate(() => callback());
231
232
  return this;
232
233
  }
233
234
 
@@ -252,7 +253,8 @@ export class FuzionXApp {
252
253
  shutdownCalled = true;
253
254
  console.log(`[fuzionx] ${signal} received — graceful shutdown (PID=${process.pid})`);
254
255
  this._bridge.stopFusionServer();
255
- setTimeout(() => process.exit(0), 2000);
256
+ const shutdownTimeout = this._appConfig?.shutdown_timeout || 5000;
257
+ setTimeout(() => process.exit(0), shutdownTimeout);
256
258
  };
257
259
  process.once('SIGTERM', () => gracefulShutdown('SIGTERM'));
258
260
  process.once('SIGINT', () => gracefulShutdown('SIGINT'));
@@ -272,13 +274,15 @@ export class FuzionXApp {
272
274
 
273
275
  // ── Error Recovery ──
274
276
  process.on('uncaughtException', (err) => {
275
- console.error('[fuzionx] uncaughtException:', err.message);
277
+ console.error('[fuzionx] uncaughtException:', err.message, err.stack);
278
+ // 불안정 상태 방지: 짧은 유예 후 프로세스 종료
279
+ setTimeout(() => process.exit(1), 1000);
276
280
  });
277
281
  process.on('unhandledRejection', (reason) => {
278
282
  console.error('[fuzionx] unhandledRejection:', reason);
279
283
  });
280
284
 
281
- if (callback) setTimeout(() => callback(), 100);
285
+ if (callback) setImmediate(() => callback());
282
286
  return this;
283
287
  }
284
288
 
package/lib/context.js CHANGED
@@ -176,8 +176,12 @@ const ResProto = {
176
176
  this._headers[key] = value;
177
177
  return this;
178
178
  },
179
- /** Fusion 응답 포맷으로 변환 — 공유 응답 객체 재사용 */
179
+ /** Fusion 응답 포맷으로 변환 — sync: 공유 객체, async: 새 객체 */
180
180
  _toFusionResponse() {
181
+ // async (비공유) 인스턴스면 새 객체 반환 → race condition 방지
182
+ if (this !== _sharedRes) {
183
+ return { status: this._statusCode, body: this._body, headers: this._headers };
184
+ }
181
185
  _sharedResponse.status = this._statusCode;
182
186
  _sharedResponse.body = this._body;
183
187
  _sharedResponse.headers = this._headers;
package/lib/middleware.js CHANGED
@@ -23,8 +23,14 @@ export function runMiddlewareChain(handlers, req, res) {
23
23
  const handler = handlers[index++];
24
24
  const result = handler(req, res, next);
25
25
 
26
- // 핸들러가 Promise를 리턴하면 (async 함수) → 전파
27
- // 이후 체인은 Promise 안에서 이미 next() 실행됨
26
+ // 핸들러가 Promise를 리턴하면 (async 함수) → 체인 완료까지 전파
27
+ // async 핸들러 내부에서 await next() 호출하므로 후속 체인은 Promise 안에서 실행됨
28
+ if (result && typeof result.then === 'function') {
29
+ return result.catch((e) => {
30
+ // async 핸들러의 unhandled rejection 방지
31
+ if (!res._sent) throw e;
32
+ });
33
+ }
28
34
  return result;
29
35
  }
30
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzionx/core",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "type": "module",
5
5
  "description": "Express-style Node.js framework powered by FuzionX native bridge — 167K RPS single process",
6
6
  "main": "index.js",
@@ -18,7 +18,7 @@
18
18
  "url": "https://github.com/saytohenry/fuzionx"
19
19
  },
20
20
  "dependencies": {
21
- "@fuzionx/bridge": "^0.1.38"
21
+ "@fuzionx/bridge": "^0.1.39"
22
22
  },
23
23
  "files": [
24
24
  "index.js",
package/types/index.d.ts CHANGED
@@ -78,8 +78,8 @@ export interface CryptoHelper {
78
78
  uuid(): string;
79
79
  md5(input: string): string;
80
80
  sha256(input: string): string;
81
- encrypt(plaintext: string, key: string): string;
82
- decrypt(ciphertext: string, key: string): string;
81
+ encrypt(key: string, plaintext: string): string;
82
+ decrypt(key: string, ciphertext: string): string;
83
83
  encryptCustom(plaintext: string, key: string): string;
84
84
  decryptCustom(ciphertext: string, key: string): string;
85
85
  getUaSlice(userAgent: string): string;