@fluojs/mongoose 1.0.3 → 1.0.4
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/README.ko.md +3 -2
- package/README.md +3 -2
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +10 -5
- package/dist/module.d.ts +12 -2
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +17 -16
- package/package.json +5 -5
package/README.ko.md
CHANGED
|
@@ -50,7 +50,7 @@ const connection = mongoose.createConnection('mongodb://localhost:27017/test');
|
|
|
50
50
|
class AppModule {}
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
`MongooseModule.forRootAsync(...)`는 주입된 의존성과 동기 또는 비동기로 옵션을 반환하는 `useFactory`를 지원합니다. 여러 모듈에서 async 등록 helper를 공유할 때는 export된 `MongooseAsyncModuleOptions<TConnection>` 타입을 사용하세요. provider를 전역으로 노출해야 할 때는 최상위 async 등록 옵션에 `global`을 전달하세요. 해석된 옵션은
|
|
53
|
+
`MongooseModule.forRootAsync(...)`는 주입된 의존성과 동기 또는 비동기로 옵션을 반환하는 `useFactory`를 지원합니다. 여러 모듈에서 async 등록 helper를 공유할 때는 export된 `MongooseAsyncModuleOptions<TConnection>` 타입을 사용하세요. provider를 전역으로 노출해야 할 때는 최상위 async 등록 옵션에 `global`을 전달하세요. 해석된 옵션은 하나의 애플리케이션 container 안에서 재사용되므로 해당 container의 모든 provider에서 연결 설정과 dispose hook이 일관되게 유지됩니다. 테스트나 multi-app 프로세스에서 같은 async module definition을 재사용해도 memoize된 연결을 공유하지 않고 애플리케이션 container마다 새 옵션을 해석합니다.
|
|
54
54
|
|
|
55
55
|
## 라이프사이클과 종료
|
|
56
56
|
|
|
@@ -64,6 +64,7 @@ class AppModule {}
|
|
|
64
64
|
4. 설정한 `dispose(connection)` 훅은 활성 요청 트랜잭션과 ambient session scope가 모두 settled된 뒤에만 실행됩니다.
|
|
65
65
|
|
|
66
66
|
`createMongoosePlatformStatusSnapshot(...)`은 트래픽 처리 중에는 `ready`, 요청 트랜잭션 drain 중에는 `shutting-down`, dispose 훅 완료 뒤에는 `stopped`를 보고합니다. 상태 details에는 `sessionStrategy`, `transactionContext: 'als'`, 활성 요청/session 개수, 리소스 소유권, strict/session 지원 진단이 포함됩니다. 수동 `transaction()`도 요청 범위 트랜잭션과 같은 명시적 세션 계약을 사용하므로, 트랜잭션에 참여해야 하는 Mongoose 모델 작업에는 repository 코드가 `conn.currentSession()`을 전달해야 합니다. 감싼 Mongoose 연결이 `connection.transaction(...)`을 노출하면 fluo는 Mongoose 자체 ambient-session scope를 보존하기 위해 그 API에 transaction boundary를 위임하면서도 같은 session을 `currentSession()`으로 노출합니다. 요청 범위 트랜잭션은 session을 획득하는 동안과 위임된 `connection.transaction(...)` 작업을 시작하는 동안에도 request `AbortSignal`을 관찰하므로, 요청 취소가 사용자 callback 실행 전에 이러한 시작 단계를 중단할 수 있습니다.
|
|
67
|
+
기존 수동 `transaction(...)` boundary 안에서 열린 중첩 `requestTransaction(...)` 호출은 ambient session을 재사용하고 `details.activeRequestTransactions`에 계속 표시되며, 종료 중에 abort되어 바깥 수동 transaction이 `dispose(connection)` 실행 전에 rollback할 수 있습니다.
|
|
67
68
|
|
|
68
69
|
## 공통 패턴
|
|
69
70
|
|
|
@@ -114,7 +115,7 @@ import { MongooseTransactionInterceptor } from '@fluojs/mongoose';
|
|
|
114
115
|
class UserController {}
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
HTTP interceptor 밖에서 같은 request-aware transaction boundary가 필요하다면 `MongooseConnection.requestTransaction(...)`을 직접 사용할 수 있습니다. 중첩된 service transaction은 활성 session boundary를
|
|
118
|
+
HTTP interceptor 밖에서 같은 request-aware transaction boundary가 필요하다면 `MongooseConnection.requestTransaction(...)`을 직접 사용할 수 있습니다. 중첩된 service transaction은 활성 session boundary를 재사용하며, 수동 transaction 안에서 열린 중첩 request boundary도 request abort와 shutdown tracking에 참여합니다.
|
|
118
119
|
|
|
119
120
|
## 공개 API
|
|
120
121
|
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ const connection = mongoose.createConnection('mongodb://localhost:27017/test');
|
|
|
48
48
|
class AppModule {}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`MongooseModule.forRootAsync(...)` accepts injected dependencies and a `useFactory` that may return options synchronously or asynchronously. Use the exported `MongooseAsyncModuleOptions<TConnection>` type when sharing async registration helpers across modules. Pass `global` on the top-level async registration when the providers should be visible globally. The resolved options are reused
|
|
51
|
+
`MongooseModule.forRootAsync(...)` accepts injected dependencies and a `useFactory` that may return options synchronously or asynchronously. Use the exported `MongooseAsyncModuleOptions<TConnection>` type when sharing async registration helpers across modules. Pass `global` on the top-level async registration when the providers should be visible globally. The resolved options are reused within one application container, so connection setup and disposal hooks stay consistent across that container's providers. Reusing the same async module definition across tests or multi-app processes resolves fresh options per application container instead of sharing a memoized connection.
|
|
52
52
|
|
|
53
53
|
## Lifecycle and Shutdown
|
|
54
54
|
|
|
@@ -62,6 +62,7 @@ Shutdown preserves transaction cleanup order and rejects new manual or request-s
|
|
|
62
62
|
4. The configured `dispose(connection)` hook runs only after active request transactions and ambient session scopes have settled.
|
|
63
63
|
|
|
64
64
|
`createMongoosePlatformStatusSnapshot(...)` reports `ready` while serving traffic, `shutting-down` while request transactions are draining, and `stopped` after the dispose hook completes. The status details include `sessionStrategy`, `transactionContext: 'als'`, active request/session counts, resource ownership, and strict/session support diagnostics. Manual `transaction()` calls still use the same explicit-session contract as request-scoped transactions: repository code must pass `conn.currentSession()` into Mongoose model operations that participate in the transaction. If the wrapped Mongoose connection exposes `connection.transaction(...)`, fluo delegates the transaction boundary to that API so Mongoose's own ambient-session scope is preserved while still exposing the same session through `currentSession()`. Request-scoped transactions observe the request `AbortSignal` while acquiring sessions and while starting delegated `connection.transaction(...)` work, so request cancellation can interrupt those startup phases before user callbacks run.
|
|
65
|
+
Nested `requestTransaction(...)` calls opened inside an existing manual `transaction(...)` boundary reuse the ambient session, stay visible in `details.activeRequestTransactions`, and are aborted during shutdown so the outer manual transaction can roll back before `dispose(connection)` runs.
|
|
65
66
|
|
|
66
67
|
## Common Patterns
|
|
67
68
|
|
|
@@ -105,7 +106,7 @@ import { MongooseTransactionInterceptor } from '@fluojs/mongoose';
|
|
|
105
106
|
class UserController {}
|
|
106
107
|
```
|
|
107
108
|
|
|
108
|
-
Use `MongooseConnection.requestTransaction(...)` directly when you need the same request-aware transaction boundary outside an HTTP interceptor. Nested service transactions reuse the active session boundary.
|
|
109
|
+
Use `MongooseConnection.requestTransaction(...)` directly when you need the same request-aware transaction boundary outside an HTTP interceptor. Nested service transactions reuse the active session boundary, and nested request boundaries opened inside a manual transaction still participate in request abort and shutdown tracking.
|
|
109
110
|
|
|
110
111
|
## Public API
|
|
111
112
|
|
package/dist/connection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAS7D,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAuBpB,KAAK,sBAAsB,GAAG;IAC5B,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAmBF;;;;GAIG;AACH,qBACa,kBAAkB,CAAC,WAAW,SAAS,sBAAsB,GAAG,sBAAsB,CACjG,YAAW,sBAAsB,CAAC,WAAW,CAAC,EAAE,qBAAqB;IAQnE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IARpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgD;IACzE,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,cAAc,CAAkD;gBAGrD,UAAU,EAAE,WAAW,EACvB,OAAO,CAAC,GAAE,CAAC,UAAU,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,aAAA,EAC3D,iBAAiB,GAAE,sBAAsD;IAG5F;;;;;;;;;OASG;IACH,OAAO,IAAI,WAAW;IAItB;;;;;;;;;OASG;IACH,cAAc,IAAI,mBAAmB,GAAG,SAAS;IAIjD,qGAAqG;IAC/F,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5C,yFAAyF;IACzF,4BAA4B;IAY5B;;;;;;;;;;;;OAYG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBtD;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IA+CnF,OAAO,CAAC,2BAA2B;IAMnC,OAAO,CAAC,kCAAkC;YAM5B,2BAA2B;YAc3B,wBAAwB;YA4BxB,wBAAwB;IActC,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,+BAA+B;YAIzB,cAAc;CAW7B"}
|
package/dist/connection.js
CHANGED
|
@@ -5,10 +5,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
5
5
|
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
6
|
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
7
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
8
|
-
import { createRequestAbortContext, raceWithAbort, trackActiveRequestTransaction, untrackActiveRequestTransaction } from '@fluojs/runtime';
|
|
9
8
|
import { Inject } from '@fluojs/core';
|
|
10
|
-
import {
|
|
9
|
+
import { createRequestAbortContext, raceWithAbort, trackActiveRequestTransaction, untrackActiveRequestTransaction } from '@fluojs/runtime';
|
|
11
10
|
import { createMongoosePlatformStatusSnapshot } from './status.js';
|
|
11
|
+
import { MONGOOSE_CONNECTION, MONGOOSE_DISPOSE, MONGOOSE_OPTIONS } from './tokens.js';
|
|
12
12
|
const TRANSACTIONS_NOT_SUPPORTED_ERROR = 'Transaction not supported: Mongoose connection does not implement startSession.';
|
|
13
13
|
const TRANSACTION_UNAVAILABLE_ERROR = 'Mongoose transactions are unavailable during application shutdown.';
|
|
14
14
|
async function executeSessionTransaction(session, fn) {
|
|
@@ -147,10 +147,15 @@ class MongooseConnection {
|
|
|
147
147
|
async requestTransaction(fn, signal) {
|
|
148
148
|
const currentSession = this.sessions.getStore();
|
|
149
149
|
if (currentSession) {
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
this.assertRequestTransactionsAvailable();
|
|
151
|
+
const abortContext = createRequestAbortContext(signal);
|
|
152
|
+
const active = this.trackActiveRequestTransaction(abortContext.controller);
|
|
153
|
+
try {
|
|
154
|
+
return await raceWithAbort(fn, abortContext.signal);
|
|
155
|
+
} finally {
|
|
156
|
+
abortContext.cleanup();
|
|
157
|
+
this.untrackActiveRequestTransaction(active);
|
|
152
158
|
}
|
|
153
|
-
return fn();
|
|
154
159
|
}
|
|
155
160
|
this.assertRequestTransactionsAvailable();
|
|
156
161
|
const abortContext = createRequestAbortContext(signal);
|
package/dist/module.d.ts
CHANGED
|
@@ -26,9 +26,19 @@ export declare function createMongooseProviders<TConnection extends MongooseConn
|
|
|
26
26
|
* Module entrypoint for wiring a Mongoose connection into the Fluo runtime lifecycle.
|
|
27
27
|
*/
|
|
28
28
|
export declare class MongooseModule {
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Registers Mongoose providers from static options.
|
|
31
|
+
*
|
|
32
|
+
* @param options Mongoose module options with connection handle, optional dispose hook, and strict transaction mode.
|
|
33
|
+
* @returns A module definition that exports `MongooseConnection` and `MongooseTransactionInterceptor`.
|
|
34
|
+
*/
|
|
30
35
|
static forRoot<TConnection extends MongooseConnectionLike>(options: MongooseModuleOptions<TConnection>): ModuleType;
|
|
31
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Registers Mongoose providers from an async DI factory.
|
|
38
|
+
*
|
|
39
|
+
* @param options Async module options that resolve Mongoose connection/module configuration.
|
|
40
|
+
* @returns A module definition that resolves async options once per application container.
|
|
41
|
+
*/
|
|
32
42
|
static forRootAsync<TConnection extends MongooseConnectionLike>(options: MongooseAsyncModuleOptions<TConnection>): ModuleType;
|
|
33
43
|
}
|
|
34
44
|
//# sourceMappingURL=module.d.ts.map
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAahF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,CAAC,WAAW,SAAS,sBAAsB,IAAI,kBAAkB,CACrG,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CACnD,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAahF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,CAAC,WAAW,SAAS,sBAAsB,IAAI,kBAAkB,CACrG,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CACnD,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;AAiEvD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,sBAAsB,EAChF,OAAO,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC1C,QAAQ,EAAE,CAOZ;AA0BD;;GAEG;AACH,qBAAa,cAAc;IACzB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,WAAW,SAAS,sBAAsB,EAAE,OAAO,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAAG,UAAU;IAInH;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CAAC,WAAW,SAAS,sBAAsB,EAC5D,OAAO,EAAE,0BAA0B,CAAC,WAAW,CAAC,GAC/C,UAAU;CAGd"}
|
package/dist/module.js
CHANGED
|
@@ -39,25 +39,16 @@ function createMongooseRuntimeProviders(normalizedOptionsProvider) {
|
|
|
39
39
|
useFactory: options => createRuntimeOptionsProviderValue(options.strictTransactions)
|
|
40
40
|
}, MongooseConnection, MongooseTransactionInterceptor];
|
|
41
41
|
}
|
|
42
|
-
function createMemoizedMongooseOptionsResolver(options) {
|
|
43
|
-
let cachedResult;
|
|
44
|
-
return (...deps) => {
|
|
45
|
-
if (!cachedResult) {
|
|
46
|
-
cachedResult = Promise.resolve(options.useFactory(...deps)).then(resolved => normalizeMongooseModuleOptions(resolved));
|
|
47
|
-
}
|
|
48
|
-
if (!cachedResult) {
|
|
49
|
-
throw new Error('Mongoose module options resolver initialization failed.');
|
|
50
|
-
}
|
|
51
|
-
return cachedResult;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
42
|
function createMongooseProvidersAsync(options) {
|
|
55
|
-
const
|
|
43
|
+
const factory = options.useFactory;
|
|
56
44
|
const normalizedOptionsProvider = {
|
|
57
45
|
inject: options.inject,
|
|
58
46
|
provide: MONGOOSE_NORMALIZED_OPTIONS,
|
|
59
47
|
scope: 'singleton',
|
|
60
|
-
useFactory: async (...deps) =>
|
|
48
|
+
useFactory: async (...deps) => {
|
|
49
|
+
const resolvedOptions = await factory(...deps);
|
|
50
|
+
return normalizeMongooseModuleOptions(resolvedOptions);
|
|
51
|
+
}
|
|
61
52
|
};
|
|
62
53
|
return createMongooseRuntimeProviders(normalizedOptionsProvider);
|
|
63
54
|
}
|
|
@@ -101,12 +92,22 @@ function buildMongooseModuleAsync(options) {
|
|
|
101
92
|
* Module entrypoint for wiring a Mongoose connection into the Fluo runtime lifecycle.
|
|
102
93
|
*/
|
|
103
94
|
export class MongooseModule {
|
|
104
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* Registers Mongoose providers from static options.
|
|
97
|
+
*
|
|
98
|
+
* @param options Mongoose module options with connection handle, optional dispose hook, and strict transaction mode.
|
|
99
|
+
* @returns A module definition that exports `MongooseConnection` and `MongooseTransactionInterceptor`.
|
|
100
|
+
*/
|
|
105
101
|
static forRoot(options) {
|
|
106
102
|
return buildMongooseModule(options);
|
|
107
103
|
}
|
|
108
104
|
|
|
109
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Registers Mongoose providers from an async DI factory.
|
|
107
|
+
*
|
|
108
|
+
* @param options Async module options that resolve Mongoose connection/module configuration.
|
|
109
|
+
* @returns A module definition that resolves async options once per application container.
|
|
110
|
+
*/
|
|
110
111
|
static forRootAsync(options) {
|
|
111
112
|
return buildMongooseModuleAsync(options);
|
|
112
113
|
}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"transaction",
|
|
10
10
|
"odm"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.0.
|
|
12
|
+
"version": "1.0.4",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@fluojs/core": "^1.0.
|
|
40
|
-
"@fluojs/http": "^1.
|
|
41
|
-
"@fluojs/di": "^1.0.
|
|
42
|
-
"@fluojs/runtime": "^1.1.
|
|
39
|
+
"@fluojs/core": "^1.0.3",
|
|
40
|
+
"@fluojs/http": "^1.1.0",
|
|
41
|
+
"@fluojs/di": "^1.0.3",
|
|
42
|
+
"@fluojs/runtime": "^1.1.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"mongoose": ">=7.0.0"
|