@fluojs/prisma 1.1.1 → 2.0.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/README.ko.md +17 -22
- package/README.md +17 -22
- package/dist/integration.d.ts +93 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +145 -0
- package/dist/module.d.ts +11 -5
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +14 -7
- package/dist/service.d.ts +30 -2
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +29 -4
- package/dist/status.d.ts +45 -5
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +18 -4
- package/package.json +8 -8
package/README.ko.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<p><a href="./README.md"><kbd>English</kbd></a> <strong><kbd>한국어</kbd></strong></p>
|
|
4
4
|
|
|
5
|
-
fluo 애플리케이션을 위한 Node.js
|
|
5
|
+
fluo 애플리케이션을 위한 Node.js `>=24.0.0 <27` Prisma lifecycle 및 ALS 기반 transaction context입니다. `PrismaClient`를 모듈 시스템에 연결하고 자동 연결 관리와 요청 범위 트랜잭션을 제공합니다.
|
|
6
6
|
|
|
7
7
|
## 목차
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ pnpm add @prisma/client
|
|
|
31
31
|
|
|
32
32
|
## 사용 시점
|
|
33
33
|
|
|
34
|
-
- Node.js
|
|
34
|
+
- Node.js `>=24.0.0 <27`에서 Prisma를 ORM으로 사용하면서 fluo의 의존성 주입 및 라이프사이클 훅과 통합하고 싶을 때.
|
|
35
35
|
- 여러 서비스와 리포지토리 사이에서 `tx` 객체를 일일이 전달하지 않고도 트랜잭션 컨텍스트를 안정적으로 공유하고 싶을 때.
|
|
36
36
|
- 애플리케이션 시작 시 자동 `$connect`, 종료 시 자동 `$disconnect`가 필요할 때.
|
|
37
37
|
|
|
@@ -66,6 +66,7 @@ import { PrismaService, Transaction, type PrismaServiceFacade } from '@fluojs/pr
|
|
|
66
66
|
import { PrismaClient } from '@prisma/client';
|
|
67
67
|
import { UserRepository } from './user.repository';
|
|
68
68
|
|
|
69
|
+
@Inject(UserRepository)
|
|
69
70
|
export class UserService {
|
|
70
71
|
constructor(private readonly repo: UserRepository) {}
|
|
71
72
|
|
|
@@ -76,21 +77,6 @@ export class UserService {
|
|
|
76
77
|
return user;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
-
@Inject(PrismaService)
|
|
81
|
-
export class UserRepository {
|
|
82
|
-
constructor(private readonly prisma: PrismaServiceFacade<PrismaClient>) {}
|
|
83
|
-
|
|
84
|
-
async create(data: any) {
|
|
85
|
-
// facade 타입은 표준 PrismaClient delegate를 노출합니다.
|
|
86
|
-
// @Transaction() 내부에서 호출되면 자동으로 활성 트랜잭션에 참여합니다.
|
|
87
|
-
return this.prisma.user.create({ data });
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async initProfile(userId: string) {
|
|
91
|
-
return this.prisma.profile.create({ data: { userId } });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
80
|
```
|
|
95
81
|
|
|
96
82
|
`@Transaction()` 메서드 호출은 재진입(reentrant)이 가능합니다. 데코레이터가 적용된 메서드가 다른 데코레이터 적용 메서드를 호출하더라도 하나의 동일한 Prisma 트랜잭션 안에서 실행됩니다.
|
|
@@ -100,11 +86,16 @@ export class UserRepository {
|
|
|
100
86
|
`PrismaTransactionInterceptor`는 기존 `@UseInterceptors(...)` request-wide boundary를 위한 deprecated 1.x 호환성 export로 복원되었습니다. 이름 없는 `PrismaModule.forRoot(...)`와 `forRootAsync(...)` 등록이 이 interceptor를 provider 및 export로 제공하며, `PrismaService.requestTransaction(...)`에 위임하고 request `AbortSignal`을 전달합니다.
|
|
101
87
|
|
|
102
88
|
```typescript
|
|
89
|
+
import { Inject } from '@fluojs/core';
|
|
103
90
|
import { Controller, Post, UseInterceptors } from '@fluojs/http';
|
|
104
91
|
import { PrismaTransactionInterceptor } from '@fluojs/prisma';
|
|
92
|
+
import { OrdersService } from './orders.service';
|
|
105
93
|
|
|
106
94
|
@Controller('/orders')
|
|
95
|
+
@Inject(OrdersService)
|
|
107
96
|
export class OrdersController {
|
|
97
|
+
constructor(private readonly orders: OrdersService) {}
|
|
98
|
+
|
|
108
99
|
@Post('/')
|
|
109
100
|
@UseInterceptors(PrismaTransactionInterceptor)
|
|
110
101
|
createOrder() {
|
|
@@ -208,17 +199,18 @@ await this.prisma.transaction(async () => {
|
|
|
208
199
|
|
|
209
200
|
### 종료와 status 계약
|
|
210
201
|
|
|
211
|
-
`PrismaService.requestTransaction(...)`은 정상 serving 전과 중에는 사용할 수 있지만, 애플리케이션 shutdown이 시작된 뒤에는 새 요청 범위 트랜잭션을 거부합니다. 새 outer 수동 `transaction(...)` 및 서비스 `@Transaction()` boundary도 shutdown 시작 후에는 거부됩니다. 이미 열린 boundary는 `$disconnect()` 전에 drain되므로 shutdown이 활성 Prisma transaction과 경합하지 않습니다. 종료 중에는 열린 요청 트랜잭션을 abort하고, 가장 바깥 transaction boundary가 settle될 때까지 추적한 다음 `$disconnect()` 실행 전에 drain합니다. 기존 수동 `transaction(...)` boundary 안에서 열린 중첩 `requestTransaction(...)` 호출도 동일합니다. 해당 호출은 ambient Prisma transaction client를 재사용하고, 바깥 boundary가 끝날 때까지 `details.activeRequestTransactions`에 표시되며, 두 번째 Prisma transaction을 열지 않습니다.
|
|
202
|
+
`PrismaService.requestTransaction(...)`은 정상 serving 전과 중에는 사용할 수 있지만, 애플리케이션 shutdown이 시작된 뒤에는 새 요청 범위 트랜잭션을 거부합니다. 새 outer 수동 `transaction(...)` 및 서비스 `@Transaction()` boundary도 shutdown 시작 후에는 거부됩니다. 이미 열린 boundary는 `$disconnect()` 전에 drain되므로 shutdown이 활성 Prisma transaction과 경합하지 않습니다. Shutdown은 진행 중인 `$connect()`가 settle될 때까지 기다린 뒤 `$disconnect()`를 실행하며, shutdown 시작 뒤 늦게 완료된 connect는 ready 상태를 복원하거나 새 transaction work를 허용할 수 없습니다. 종료 중에는 열린 요청 트랜잭션을 abort하고, 가장 바깥 transaction boundary가 settle될 때까지 추적한 다음 `$disconnect()` 실행 전에 drain합니다. 기존 수동 `transaction(...)` boundary 안에서 열린 중첩 `requestTransaction(...)` 호출도 동일합니다. 해당 호출은 ambient Prisma transaction client를 재사용하고, 바깥 boundary가 끝날 때까지 `details.activeRequestTransactions`에 표시되며, 두 번째 Prisma transaction을 열지 않습니다.
|
|
212
203
|
|
|
213
204
|
`createPrismaPlatformStatusSnapshot(...)`와 `PrismaService.createPlatformStatusSnapshot()`은 같은 라이프사이클 계약을 진단 surface에 노출합니다.
|
|
214
205
|
|
|
215
206
|
- `readiness.status`는 `onModuleInit()`이 클라이언트를 연결하기 전, Prisma가 종료 중이거나 stopped 상태일 때, `strictTransactions`가 켜져 있는데 `$transaction(...)`을 지원하지 않을 때, 그리고 클라이언트가 interactive transaction을 지원하지만 호스트 런타임이 `AsyncLocalStorage`를 제공하지 않을 때 `not-ready`입니다. ALS 미지원 상태의 readiness reason은 `Prisma transaction context requires AsyncLocalStorage support from the host runtime.`이며 `details.transactionContext`가 `unavailable`로 보고됩니다. 이 상태는 Prisma 클라이언트 자체는 연결되어 있고 기능적으로 정상일 수 있으므로 일반 database readiness 실패와 구분됩니다.
|
|
216
|
-
- `health.status`는 종료 중
|
|
217
|
-
- `details.activeRequestTransactions`, `details.lifecycleState`, `details.strictTransactions`, `details.supportsTransaction`, `details.transactionAbortSignalSupport`는 현재
|
|
207
|
+
- `health.status`는 종료 중 열린 요청, 수동 또는 서비스 트랜잭션 경계를 drain하는 동안 `degraded`, disconnect 이후 `unhealthy`입니다.
|
|
208
|
+
- `details.activeRequestTransactions`, `details.activeTransactionBoundaries`, `details.lifecycleState`, `details.strictTransactions`, `details.supportsTransaction`, `details.transactionAbortSignalSupport`는 현재 트랜잭션과 트랜잭션 capability 상태를 설명합니다.
|
|
209
|
+
- `details.activeTransactionBoundaries`는 shutdown이 `$disconnect()` 전에 drain하는 현재 열린 바깥 `transaction(...)` 및 service `@Transaction()` boundary 수를 나타냅니다. 요청 전용 `requestTransaction(...)` activity는 포함하지 않으며, 해당 activity는 `details.activeRequestTransactions`에서 별도로 확인할 수 있습니다.
|
|
218
210
|
- `details.transactionContext: 'als'`는 요청 및 서비스 트랜잭션 경계가 사용하는 async-local transaction context를 식별합니다. `details.transactionContext: 'unavailable'`은 호스트 런타임이 사용 가능한 `AsyncLocalStorage`를 노출하지 않았음을 나타내며, 이 경우 `transaction()`과 `requestTransaction()`은 Prisma 트랜잭션을 열기 전에 예외를 던집니다.
|
|
219
211
|
- `ownership.externallyManaged: false`와 `ownership.ownsResources: true`는 패키지가 fluo 애플리케이션 라이프사이클 안에서 등록된 클라이언트의 `$connect()` / `$disconnect()` lifecycle hook을 소유한다는 의미입니다.
|
|
220
212
|
|
|
221
|
-
`details.transactionContext`가 `unavailable`이면 패키지는 동기 stack 기반 컨텍스트로 fallback하지 않습니다. async boundary 사이에서 `current()`를 잃기 때문입니다. fallback boundary는 애플리케이션이 소유합니다. 트랜잭션 컨텍스트 없이도 데이터베이스 접근이 필요한 호출자는 (예: `PRISMA_CLIENT` 토큰을 통해) 원시 `PrismaClient`를 직접 호출하고 자체 일관성 semantics를 관리하거나, `AsyncLocalStorage`를 제공하는 호스트 런타임(Node.js
|
|
213
|
+
`details.transactionContext`가 `unavailable`이면 패키지는 동기 stack 기반 컨텍스트로 fallback하지 않습니다. async boundary 사이에서 `current()`를 잃기 때문입니다. fallback boundary는 애플리케이션이 소유합니다. 트랜잭션 컨텍스트 없이도 데이터베이스 접근이 필요한 호출자는 (예: `PRISMA_CLIENT` 토큰을 통해) 원시 `PrismaClient`를 직접 호출하고 자체 일관성 semantics를 관리하거나, `AsyncLocalStorage`를 제공하는 호스트 런타임(Node.js `>=24.0.0 <27`가 문서화된 경로)에서 실행해야 합니다. `unavailable` readiness 상태는 운영적으로 실행 가능한 신호로 취급하세요. health check에 노출하고, 호스트가 ALS를 제공하거나 애플리케이션이 비트랜잭션 접근 경로로 전환할 때까지 트랜잭션 의존 handler로 트래픽을 라우팅하지 마세요.
|
|
222
214
|
|
|
223
215
|
### 비동기 설정과 격리
|
|
224
216
|
|
|
@@ -239,7 +231,7 @@ PrismaModule.forRootAsync({
|
|
|
239
231
|
|
|
240
232
|
하나의 컴파일된 애플리케이션 안에서는 하위 provider가 동일하게 resolve된 `PrismaService`, ALS 트랜잭션 컨텍스트, 라이프사이클 관리 대상 클라이언트를 공유합니다. 서로 다른 애플리케이션 컨테이너는 독립된 factory 결과를 받으므로 `$connect` / `$disconnect` 소유권과 요청 트랜잭션 상태가 격리됩니다.
|
|
241
233
|
|
|
242
|
-
트랜잭션 경계에는 호스트가 제공하는 `AsyncLocalStorage` 지원이 필요합니다. 패키지 manifest는 `engines.node >=
|
|
234
|
+
트랜잭션 경계에는 호스트가 제공하는 `AsyncLocalStorage` 지원이 필요합니다. 패키지 manifest는 `engines.node >=24.0.0 <27`을 선언하며, root wrapper는 문서화된 Node.js `>=24.0.0 <27` Prisma 통합 경로입니다. `@fluojs/prisma`는 런타임이 노출하는 `globalThis.AsyncLocalStorage` 또는 Node.js의 `process.getBuiltinModule('node:async_hooks')` 호스트 경계를 통해 ALS를 resolve합니다. 두 경로 모두 사용할 수 없거나 host builtin lookup이 실패하면 동기 stack fallback으로 async boundary 사이의 `current()`를 잃는 대신, Prisma 트랜잭션을 열기 전에 `transaction()`과 `requestTransaction()`이 예외를 던집니다. 이 상태는 `createPlatformStatusSnapshot().details.transactionContext`에 `unavailable`로 보고됩니다.
|
|
243
235
|
|
|
244
236
|
### 수동 모듈 조합
|
|
245
237
|
|
|
@@ -317,6 +309,7 @@ Provider가 `current()`, `transaction(...)`, `requestTransaction(...)`, `createP
|
|
|
317
309
|
|
|
318
310
|
### 관련 export 타입
|
|
319
311
|
|
|
312
|
+
- `PrismaAsyncModuleOptions<TClient, TTransactionClient, TTransactionOptions>`
|
|
320
313
|
- `PrismaModuleOptions`
|
|
321
314
|
- `PrismaClientLike`
|
|
322
315
|
- `PrismaHandleProvider`
|
|
@@ -324,6 +317,8 @@ Provider가 `current()`, `transaction(...)`, `requestTransaction(...)`, `createP
|
|
|
324
317
|
- `PrismaTransactionClient<TClient>`
|
|
325
318
|
- `InferPrismaTransactionClient<TClient>`
|
|
326
319
|
- `InferPrismaTransactionOptions<TClient>`
|
|
320
|
+
- `PrismaPlatformStatusSnapshotInput`
|
|
321
|
+
- `createPrismaPlatformStatusSnapshot(...)`의 입력 계약입니다. 바깥 service 또는 manual transaction boundary가 열려 있지 않다면 `activeTransactionBoundaries`를 생략할 수 있으며 snapshot은 `0`으로 보고합니다.
|
|
327
322
|
|
|
328
323
|
## 관련 패키지
|
|
329
324
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<p><strong><kbd>English</kbd></strong> <a href="./README.ko.md"><kbd>한국어</kbd></a></p>
|
|
4
4
|
|
|
5
|
-
Node.js
|
|
5
|
+
Node.js `>=24.0.0 <27` Prisma lifecycle and ALS-backed transaction context for fluo applications. Connects a `PrismaClient` to the module system with automatic connection management and request-scoped transactions.
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ pnpm add @prisma/client
|
|
|
31
31
|
|
|
32
32
|
## When to Use
|
|
33
33
|
|
|
34
|
-
- When using Prisma as your ORM on Node.js
|
|
34
|
+
- When using Prisma as your ORM on Node.js `>=24.0.0 <27` and you want it integrated with fluo's dependency injection and lifecycle hooks.
|
|
35
35
|
- When you need a reliable way to share a transaction context across multiple services and repositories without passing a `tx` object everywhere.
|
|
36
36
|
- When you want automatic `$connect` on startup and `$disconnect` on shutdown.
|
|
37
37
|
|
|
@@ -66,6 +66,7 @@ import { PrismaService, Transaction, type PrismaServiceFacade } from '@fluojs/pr
|
|
|
66
66
|
import { PrismaClient } from '@prisma/client';
|
|
67
67
|
import { UserRepository } from './user.repository';
|
|
68
68
|
|
|
69
|
+
@Inject(UserRepository)
|
|
69
70
|
export class UserService {
|
|
70
71
|
constructor(private readonly repo: UserRepository) {}
|
|
71
72
|
|
|
@@ -76,21 +77,6 @@ export class UserService {
|
|
|
76
77
|
return user;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
-
@Inject(PrismaService)
|
|
81
|
-
export class UserRepository {
|
|
82
|
-
constructor(private readonly prisma: PrismaServiceFacade<PrismaClient>) {}
|
|
83
|
-
|
|
84
|
-
async create(data: any) {
|
|
85
|
-
// The facade type exposes standard PrismaClient delegates.
|
|
86
|
-
// When called inside @Transaction(), they automatically participate in the ambient transaction.
|
|
87
|
-
return this.prisma.user.create({ data });
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async initProfile(userId: string) {
|
|
91
|
-
return this.prisma.profile.create({ data: { userId } });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
80
|
```
|
|
95
81
|
|
|
96
82
|
Calls to `@Transaction()` methods are reentrant. If a decorated method calls another decorated method, they share the same underlying Prisma transaction.
|
|
@@ -100,11 +86,16 @@ Calls to `@Transaction()` methods are reentrant. If a decorated method calls ano
|
|
|
100
86
|
`PrismaTransactionInterceptor` is restored as a deprecated 1.x compatibility export for existing `@UseInterceptors(...)` request-wide boundaries. The unnamed `PrismaModule.forRoot(...)` and `forRootAsync(...)` registrations provide and export it. It delegates to `PrismaService.requestTransaction(...)` and forwards the request `AbortSignal`.
|
|
101
87
|
|
|
102
88
|
```typescript
|
|
89
|
+
import { Inject } from '@fluojs/core';
|
|
103
90
|
import { Controller, Post, UseInterceptors } from '@fluojs/http';
|
|
104
91
|
import { PrismaTransactionInterceptor } from '@fluojs/prisma';
|
|
92
|
+
import { OrdersService } from './orders.service';
|
|
105
93
|
|
|
106
94
|
@Controller('/orders')
|
|
95
|
+
@Inject(OrdersService)
|
|
107
96
|
export class OrdersController {
|
|
97
|
+
constructor(private readonly orders: OrdersService) {}
|
|
98
|
+
|
|
108
99
|
@Post('/')
|
|
109
100
|
@UseInterceptors(PrismaTransactionInterceptor)
|
|
110
101
|
createOrder() {
|
|
@@ -209,17 +200,18 @@ When `transaction()` is called while a transaction context is already active, `P
|
|
|
209
200
|
|
|
210
201
|
### Shutdown and Status Contracts
|
|
211
202
|
|
|
212
|
-
`PrismaService.requestTransaction(...)` is available before and during normal serving, but new request-scoped transactions are rejected once application shutdown has started. New outer manual `transaction(...)` and service `@Transaction()` boundaries are also rejected after shutdown begins; boundaries that were already open are drained before `$disconnect()` so shutdown does not race an active Prisma transaction. During shutdown, open request transactions are aborted, tracked until their outer transaction boundary has settled, and drained before `$disconnect()` runs. This includes nested `requestTransaction(...)` calls opened inside an existing manual `transaction(...)` boundary: they reuse the ambient Prisma transaction client, stay visible in `details.activeRequestTransactions` until the outer boundary finishes, and do not open a second Prisma transaction.
|
|
203
|
+
`PrismaService.requestTransaction(...)` is available before and during normal serving, but new request-scoped transactions are rejected once application shutdown has started. New outer manual `transaction(...)` and service `@Transaction()` boundaries are also rejected after shutdown begins; boundaries that were already open are drained before `$disconnect()` so shutdown does not race an active Prisma transaction. Shutdown also waits for an in-flight `$connect()` to settle before `$disconnect()`; once shutdown starts, a late connect completion cannot restore ready state or admit new transaction work. During shutdown, open request transactions are aborted, tracked until their outer transaction boundary has settled, and drained before `$disconnect()` runs. This includes nested `requestTransaction(...)` calls opened inside an existing manual `transaction(...)` boundary: they reuse the ambient Prisma transaction client, stay visible in `details.activeRequestTransactions` until the outer boundary finishes, and do not open a second Prisma transaction.
|
|
213
204
|
|
|
214
205
|
`createPrismaPlatformStatusSnapshot(...)` and `PrismaService.createPlatformStatusSnapshot()` expose the same lifecycle contract to diagnostics surfaces:
|
|
215
206
|
|
|
216
207
|
- `readiness.status` is `not-ready` before `onModuleInit()` connects the client, while Prisma is shutting down or stopped, when `strictTransactions` is enabled without `$transaction(...)` support, and when the host runtime does not provide `AsyncLocalStorage` while the client supports interactive transactions. In the ALS-unavailable case the readiness reason is `Prisma transaction context requires AsyncLocalStorage support from the host runtime.` and `details.transactionContext` reports `unavailable`; this state is distinct from an ordinary database readiness failure because the Prisma client itself may be connected and otherwise functional.
|
|
217
|
-
- `health.status` is `degraded` while request
|
|
218
|
-
- `details.activeRequestTransactions`, `details.lifecycleState`, `details.strictTransactions`, `details.supportsTransaction`, and `details.transactionAbortSignalSupport` describe the current
|
|
208
|
+
- `health.status` is `degraded` while open request, manual, or service transaction boundaries are draining during shutdown and `unhealthy` after disconnect.
|
|
209
|
+
- `details.activeRequestTransactions`, `details.activeTransactionBoundaries`, `details.lifecycleState`, `details.strictTransactions`, `details.supportsTransaction`, and `details.transactionAbortSignalSupport` describe the current transaction and transaction-capability state.
|
|
210
|
+
- `details.activeTransactionBoundaries` counts currently open outer `transaction(...)` and service `@Transaction()` boundaries that shutdown drains before `$disconnect()`. It excludes request-only `requestTransaction(...)` activity, which remains visible separately through `details.activeRequestTransactions`.
|
|
219
211
|
- `details.transactionContext: 'als'` identifies the async-local transaction context used by request and service transaction boundaries. `details.transactionContext: 'unavailable'` indicates the host runtime did not expose a usable `AsyncLocalStorage`, so `transaction()` and `requestTransaction()` reject before opening a Prisma transaction.
|
|
220
212
|
- `ownership.externallyManaged: false` and `ownership.ownsResources: true` mean the package owns the registered client's `$connect()` / `$disconnect()` lifecycle hooks inside the fluo application lifecycle.
|
|
221
213
|
|
|
222
|
-
When `details.transactionContext` is `unavailable`, the package does not fall back to a synchronous stack-based context because that would lose `current()` across async boundaries. The application owns the fallback boundary: callers that still need database access without a transaction context must invoke the raw `PrismaClient` directly (for example through the `PRISMA_CLIENT` token) and manage their own consistency semantics, or run on a host runtime that provides `AsyncLocalStorage` (Node.js
|
|
214
|
+
When `details.transactionContext` is `unavailable`, the package does not fall back to a synchronous stack-based context because that would lose `current()` across async boundaries. The application owns the fallback boundary: callers that still need database access without a transaction context must invoke the raw `PrismaClient` directly (for example through the `PRISMA_CLIENT` token) and manage their own consistency semantics, or run on a host runtime that provides `AsyncLocalStorage` (Node.js `>=24.0.0 <27` is the documented path). Treat the `unavailable` readiness state as operationally actionable — surface it in health checks and route traffic away from transaction-dependent handlers until the host provides ALS or the application switches to a non-transactional access path.
|
|
223
215
|
|
|
224
216
|
### Async Configuration and Isolation
|
|
225
217
|
|
|
@@ -240,7 +232,7 @@ PrismaModule.forRootAsync({
|
|
|
240
232
|
|
|
241
233
|
Within one compiled application, downstream providers share the same resolved `PrismaService`, ALS transaction context, and lifecycle-managed client. Separate application containers receive independent factory results, so `$connect` / `$disconnect` ownership and request transaction state remain isolated.
|
|
242
234
|
|
|
243
|
-
Transaction boundaries require host-provided `AsyncLocalStorage` support. The package manifest declares `engines.node >=
|
|
235
|
+
Transaction boundaries require host-provided `AsyncLocalStorage` support. The package manifest declares `engines.node >=24.0.0 <27`, and the root wrapper is the documented Node.js `>=24.0.0 <27` Prisma integration path. `@fluojs/prisma` resolves ALS through `globalThis.AsyncLocalStorage` when a runtime exposes one, or through the host's `process.getBuiltinModule('node:async_hooks')` boundary on Node.js. If neither path is available or the host builtin lookup fails, `transaction()` and `requestTransaction()` reject before opening a Prisma transaction instead of using a synchronous stack fallback that would lose `current()` across async boundaries; `createPlatformStatusSnapshot().details.transactionContext` reports `unavailable` in that state.
|
|
244
236
|
|
|
245
237
|
### Manual Module Composition
|
|
246
238
|
|
|
@@ -320,6 +312,7 @@ token are deliberately not exported.
|
|
|
320
312
|
|
|
321
313
|
### Related exported types
|
|
322
314
|
|
|
315
|
+
- `PrismaAsyncModuleOptions<TClient, TTransactionClient, TTransactionOptions>`
|
|
323
316
|
- `PrismaModuleOptions`
|
|
324
317
|
- `PrismaClientLike`
|
|
325
318
|
- `PrismaHandleProvider`
|
|
@@ -327,6 +320,8 @@ token are deliberately not exported.
|
|
|
327
320
|
- `PrismaTransactionClient<TClient>`
|
|
328
321
|
- `InferPrismaTransactionClient<TClient>`
|
|
329
322
|
- `InferPrismaTransactionOptions<TClient>`
|
|
323
|
+
- `PrismaPlatformStatusSnapshotInput`
|
|
324
|
+
- The input contract for `createPrismaPlatformStatusSnapshot(...)`; omit `activeTransactionBoundaries` when no outer service or manual transaction boundary is open and the snapshot reports `0`.
|
|
330
325
|
|
|
331
326
|
## Related Packages
|
|
332
327
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Module, type Constructor, type Token } from '@fluojs/core';
|
|
2
|
+
import type { Provider } from '@fluojs/di';
|
|
3
|
+
import type { MiddlewareLike } from '@fluojs/http';
|
|
4
|
+
type PrismaModuleDefinition = Parameters<typeof Module>[0] & {
|
|
5
|
+
controllers?: Constructor[];
|
|
6
|
+
exports?: Token[];
|
|
7
|
+
imports?: PrismaModuleType[];
|
|
8
|
+
middleware?: MiddlewareLike[];
|
|
9
|
+
providers?: Provider[];
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Module class accepted by the Fluo runtime module graph.
|
|
13
|
+
*/
|
|
14
|
+
export type PrismaModuleType = Constructor & {
|
|
15
|
+
definition?: PrismaModuleDefinition;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Defines the lifecycle hook invoked after module initialization.
|
|
19
|
+
*/
|
|
20
|
+
export interface OnModuleInit {
|
|
21
|
+
onModuleInit(): Promise<void> | void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Defines the lifecycle hook invoked during application shutdown.
|
|
25
|
+
*/
|
|
26
|
+
export interface OnApplicationShutdown {
|
|
27
|
+
onApplicationShutdown(): Promise<void> | void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Defines one active request transaction.
|
|
31
|
+
*/
|
|
32
|
+
export type ActiveRequestTransaction = {
|
|
33
|
+
abort(reason?: unknown): void;
|
|
34
|
+
settled: Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Defines one active request transaction registration.
|
|
38
|
+
*/
|
|
39
|
+
export type ActiveRequestTransactionHandle = {
|
|
40
|
+
active: ActiveRequestTransaction;
|
|
41
|
+
settle(): void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Creates a module class with metadata consumed by the runtime module graph.
|
|
45
|
+
*
|
|
46
|
+
* @param definition Module composition metadata.
|
|
47
|
+
* @param moduleName Constructor name used by runtime diagnostics.
|
|
48
|
+
* @returns A new module class carrying the supplied metadata.
|
|
49
|
+
*/
|
|
50
|
+
export declare function definePrismaModule(definition: Parameters<typeof Module>[0], moduleName: string): PrismaModuleType;
|
|
51
|
+
/**
|
|
52
|
+
* Races an operation against an abort signal.
|
|
53
|
+
*
|
|
54
|
+
* @param fn Async operation to execute while observing the abort signal.
|
|
55
|
+
* @param signal Abort signal that can cancel the operation.
|
|
56
|
+
* @returns The resolved value from `fn` when no abort happens first.
|
|
57
|
+
*/
|
|
58
|
+
export declare function raceWithAbort<T>(fn: () => Promise<T>, signal: AbortSignal): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Normalizes an abort reason into an AbortError.
|
|
61
|
+
*
|
|
62
|
+
* @param reason Abort reason attached to the triggering signal.
|
|
63
|
+
* @returns A normalized abort error.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createAbortError(reason: unknown): Error;
|
|
66
|
+
/**
|
|
67
|
+
* Creates an abort context that forwards an optional caller signal.
|
|
68
|
+
*
|
|
69
|
+
* @param signal Optional caller-owned abort signal.
|
|
70
|
+
* @returns The owned controller, signal, and listener cleanup.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createRequestAbortContext(signal?: AbortSignal): {
|
|
73
|
+
controller: AbortController;
|
|
74
|
+
cleanup(): void;
|
|
75
|
+
signal: AbortSignal;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Tracks a request transaction until its caller settles it.
|
|
79
|
+
*
|
|
80
|
+
* @param activeRequestTransactions Active request transaction set.
|
|
81
|
+
* @param controller Controller used to abort the transaction.
|
|
82
|
+
* @returns The tracked transaction and its settlement function.
|
|
83
|
+
*/
|
|
84
|
+
export declare function trackActiveRequestTransaction(activeRequestTransactions: Set<ActiveRequestTransaction>, controller: AbortController): ActiveRequestTransactionHandle;
|
|
85
|
+
/**
|
|
86
|
+
* Stops tracking a settled request transaction.
|
|
87
|
+
*
|
|
88
|
+
* @param activeRequestTransactions Active request transaction set.
|
|
89
|
+
* @param handle Transaction registration to remove.
|
|
90
|
+
*/
|
|
91
|
+
export declare function untrackActiveRequestTransaction(activeRequestTransactions: Set<ActiveRequestTransaction>, handle: ActiveRequestTransactionHandle): void;
|
|
92
|
+
export {};
|
|
93
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;IAC3D,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG;IAC3C,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,EACxC,UAAU,EAAE,MAAM,GACjB,gBAAgB,CAalB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAuB5F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,KAAK,CAKvD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG;IAC/D,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;CACrB,CAiBA;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,yBAAyB,EAAE,GAAG,CAAC,wBAAwB,CAAC,EACxD,UAAU,EAAE,eAAe,GAC1B,8BAA8B,CAehC;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,yBAAyB,EAAE,GAAG,CAAC,wBAAwB,CAAC,EACxD,MAAM,EAAE,8BAA8B,GACrC,IAAI,CAGN"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Module } from '@fluojs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Module class accepted by the Fluo runtime module graph.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Defines the lifecycle hook invoked after module initialization.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Defines the lifecycle hook invoked during application shutdown.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Defines one active request transaction.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Defines one active request transaction registration.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a module class with metadata consumed by the runtime module graph.
|
|
25
|
+
*
|
|
26
|
+
* @param definition Module composition metadata.
|
|
27
|
+
* @param moduleName Constructor name used by runtime diagnostics.
|
|
28
|
+
* @returns A new module class carrying the supplied metadata.
|
|
29
|
+
*/
|
|
30
|
+
export function definePrismaModule(definition, moduleName) {
|
|
31
|
+
const moduleType = {
|
|
32
|
+
[moduleName]: class {}
|
|
33
|
+
}[moduleName];
|
|
34
|
+
Module(definition)(moduleType, {
|
|
35
|
+
addInitializer() {},
|
|
36
|
+
kind: 'class',
|
|
37
|
+
metadata: {},
|
|
38
|
+
name: moduleName
|
|
39
|
+
});
|
|
40
|
+
return moduleType;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Races an operation against an abort signal.
|
|
45
|
+
*
|
|
46
|
+
* @param fn Async operation to execute while observing the abort signal.
|
|
47
|
+
* @param signal Abort signal that can cancel the operation.
|
|
48
|
+
* @returns The resolved value from `fn` when no abort happens first.
|
|
49
|
+
*/
|
|
50
|
+
export async function raceWithAbort(fn, signal) {
|
|
51
|
+
if (signal.aborted) {
|
|
52
|
+
throw createAbortError(signal.reason);
|
|
53
|
+
}
|
|
54
|
+
return await new Promise((resolve, reject) => {
|
|
55
|
+
const onAbort = () => {
|
|
56
|
+
reject(createAbortError(signal.reason));
|
|
57
|
+
};
|
|
58
|
+
signal.addEventListener('abort', onAbort, {
|
|
59
|
+
once: true
|
|
60
|
+
});
|
|
61
|
+
let fnResultPromise;
|
|
62
|
+
try {
|
|
63
|
+
fnResultPromise = Promise.resolve(fn());
|
|
64
|
+
} catch (syncError) {
|
|
65
|
+
fnResultPromise = Promise.reject(syncError);
|
|
66
|
+
}
|
|
67
|
+
fnResultPromise.then(resolve, reject).finally(() => {
|
|
68
|
+
signal.removeEventListener('abort', onAbort);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Normalizes an abort reason into an AbortError.
|
|
75
|
+
*
|
|
76
|
+
* @param reason Abort reason attached to the triggering signal.
|
|
77
|
+
* @returns A normalized abort error.
|
|
78
|
+
*/
|
|
79
|
+
export function createAbortError(reason) {
|
|
80
|
+
const message = reason instanceof Error ? reason.message : 'Request aborted before response commit.';
|
|
81
|
+
const error = new Error(message);
|
|
82
|
+
error.name = 'AbortError';
|
|
83
|
+
return error;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates an abort context that forwards an optional caller signal.
|
|
88
|
+
*
|
|
89
|
+
* @param signal Optional caller-owned abort signal.
|
|
90
|
+
* @returns The owned controller, signal, and listener cleanup.
|
|
91
|
+
*/
|
|
92
|
+
export function createRequestAbortContext(signal) {
|
|
93
|
+
const controller = new AbortController();
|
|
94
|
+
const forwardAbort = () => controller.abort(signal?.reason);
|
|
95
|
+
if (signal?.aborted) {
|
|
96
|
+
forwardAbort();
|
|
97
|
+
} else {
|
|
98
|
+
signal?.addEventListener('abort', forwardAbort, {
|
|
99
|
+
once: true
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
controller,
|
|
104
|
+
cleanup: () => {
|
|
105
|
+
signal?.removeEventListener('abort', forwardAbort);
|
|
106
|
+
},
|
|
107
|
+
signal: controller.signal
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Tracks a request transaction until its caller settles it.
|
|
113
|
+
*
|
|
114
|
+
* @param activeRequestTransactions Active request transaction set.
|
|
115
|
+
* @param controller Controller used to abort the transaction.
|
|
116
|
+
* @returns The tracked transaction and its settlement function.
|
|
117
|
+
*/
|
|
118
|
+
export function trackActiveRequestTransaction(activeRequestTransactions, controller) {
|
|
119
|
+
let settle;
|
|
120
|
+
const settled = new Promise(resolve => {
|
|
121
|
+
settle = resolve;
|
|
122
|
+
});
|
|
123
|
+
const active = {
|
|
124
|
+
abort(reason) {
|
|
125
|
+
controller.abort(reason);
|
|
126
|
+
},
|
|
127
|
+
settled
|
|
128
|
+
};
|
|
129
|
+
activeRequestTransactions.add(active);
|
|
130
|
+
return {
|
|
131
|
+
active,
|
|
132
|
+
settle
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Stops tracking a settled request transaction.
|
|
138
|
+
*
|
|
139
|
+
* @param activeRequestTransactions Active request transaction set.
|
|
140
|
+
* @param handle Transaction registration to remove.
|
|
141
|
+
*/
|
|
142
|
+
export function untrackActiveRequestTransaction(activeRequestTransactions, handle) {
|
|
143
|
+
activeRequestTransactions.delete(handle.active);
|
|
144
|
+
handle.settle();
|
|
145
|
+
}
|
package/dist/module.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { AsyncModuleOptions } from '@fluojs/core';
|
|
2
|
-
import { type
|
|
2
|
+
import { type PrismaModuleType } from './integration.js';
|
|
3
3
|
import type { InferPrismaTransactionClient, InferPrismaTransactionOptions, PrismaClientLike, PrismaModuleOptions } from './types.js';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Configures an async Prisma module registration through an injected factory.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam TClient Root Prisma client shape registered in the module.
|
|
8
|
+
* @typeParam TTransactionClient Transaction-scoped client resolved inside transaction callbacks.
|
|
9
|
+
* @typeParam TTransactionOptions Options forwarded to Prisma interactive transactions.
|
|
10
|
+
*/
|
|
11
|
+
export type PrismaAsyncModuleOptions<TClient extends PrismaClientLike<TTransactionClient, TTransactionOptions>, TTransactionClient, TTransactionOptions> = AsyncModuleOptions<Omit<PrismaModuleOptions<TClient, TTransactionClient, TTransactionOptions>, 'global' | 'name'>> & {
|
|
5
12
|
global?: boolean;
|
|
6
13
|
name?: string;
|
|
7
14
|
};
|
|
@@ -15,14 +22,13 @@ export declare class PrismaModule {
|
|
|
15
22
|
* @param options Prisma module options with client handle and strict transaction mode.
|
|
16
23
|
* @returns A module definition that exports `PrismaService`, compatibility interceptor, and related Prisma tokens.
|
|
17
24
|
*/
|
|
18
|
-
static forRoot<TClient extends PrismaClientLike<TTransactionClient, TTransactionOptions>, TTransactionClient = InferPrismaTransactionClient<TClient>, TTransactionOptions = InferPrismaTransactionOptions<TClient>>(options: PrismaModuleOptions<TClient, TTransactionClient, TTransactionOptions>):
|
|
25
|
+
static forRoot<TClient extends PrismaClientLike<TTransactionClient, TTransactionOptions>, TTransactionClient = InferPrismaTransactionClient<TClient>, TTransactionOptions = InferPrismaTransactionOptions<TClient>>(options: PrismaModuleOptions<TClient, TTransactionClient, TTransactionOptions>): PrismaModuleType;
|
|
19
26
|
/**
|
|
20
27
|
* Registers Prisma providers from an async DI factory.
|
|
21
28
|
*
|
|
22
29
|
* @param options Async module options that resolve Prisma client/module configuration.
|
|
23
30
|
* @returns A module definition that resolves async options once per application container.
|
|
24
31
|
*/
|
|
25
|
-
static forRootAsync<TClient extends PrismaClientLike<TTransactionClient, TTransactionOptions>, TTransactionClient = InferPrismaTransactionClient<TClient>, TTransactionOptions = InferPrismaTransactionOptions<TClient>>(options: PrismaAsyncModuleOptions<TClient, TTransactionClient, TTransactionOptions>):
|
|
32
|
+
static forRootAsync<TClient extends PrismaClientLike<TTransactionClient, TTransactionOptions>, TTransactionClient = InferPrismaTransactionClient<TClient>, TTransactionOptions = InferPrismaTransactionOptions<TClient>>(options: PrismaAsyncModuleOptions<TClient, TTransactionClient, TTransactionOptions>): PrismaModuleType;
|
|
26
33
|
}
|
|
27
|
-
export {};
|
|
28
34
|
//# 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,EAAS,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAS,MAAM,cAAc,CAAC;AAG9D,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQ7E,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAapB;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,CAClC,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,EAClB,mBAAmB,IACjB,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG;IACvH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA2MF;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CACZ,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,EAC1D,mBAAmB,GAAG,6BAA6B,CAAC,OAAO,CAAC,EAE5D,OAAO,EAAE,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,GAC7E,gBAAgB;IAInB;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CACjB,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,EAC1D,mBAAmB,GAAG,6BAA6B,CAAC,OAAO,CAAC,EAE5D,OAAO,EAAE,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,GAClF,gBAAgB;CAGpB"}
|
package/dist/module.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { definePrismaModule } from './integration.js';
|
|
2
2
|
import { PrismaService } from './service.js';
|
|
3
3
|
import { getPrismaClientToken, getPrismaOptionsToken, getPrismaServiceToken } from './tokens.js';
|
|
4
4
|
import { PrismaTransactionInterceptor } from './transaction.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configures an async Prisma module registration through an injected factory.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam TClient Root Prisma client shape registered in the module.
|
|
10
|
+
* @typeParam TTransactionClient Transaction-scoped client resolved inside transaction callbacks.
|
|
11
|
+
* @typeParam TTransactionOptions Options forwarded to Prisma interactive transactions.
|
|
12
|
+
*/
|
|
13
|
+
|
|
5
14
|
const PRISMA_NORMALIZED_OPTIONS = Symbol('fluo.prisma.normalized-options');
|
|
6
15
|
function isObjectLike(value) {
|
|
7
16
|
return typeof value === 'object' && value !== null || typeof value === 'function';
|
|
@@ -61,22 +70,20 @@ function createPrismaRuntimeProviders(normalizedOptionsProvider, name) {
|
|
|
61
70
|
}, PrismaTransactionInterceptor] : [createPrismaServiceProvider(getPrismaServiceToken(name), clientToken, optionsToken)])];
|
|
62
71
|
}
|
|
63
72
|
function buildPrismaModule(options) {
|
|
64
|
-
class PrismaRootModuleDefinition {}
|
|
65
73
|
const normalizedOptions = normalizePrismaModuleOptions(options);
|
|
66
74
|
if (normalizedOptions.name !== undefined && normalizedOptions.global) {
|
|
67
75
|
throw new Error('Named Prisma registrations are scoped and cannot be registered globally.');
|
|
68
76
|
}
|
|
69
|
-
return
|
|
77
|
+
return definePrismaModule({
|
|
70
78
|
exports: normalizedOptions.name === undefined ? [PrismaService, PrismaTransactionInterceptor, getPrismaServiceToken(), getPrismaClientToken(), getPrismaOptionsToken()] : [getPrismaServiceToken(normalizedOptions.name), getPrismaClientToken(normalizedOptions.name), getPrismaOptionsToken(normalizedOptions.name)],
|
|
71
79
|
global: normalizedOptions.name === undefined ? normalizedOptions.global : false,
|
|
72
80
|
providers: createPrismaRuntimeProviders({
|
|
73
81
|
provide: getPrismaNormalizedOptionsToken(normalizedOptions.name),
|
|
74
82
|
useValue: normalizedOptions
|
|
75
83
|
}, normalizedOptions.name)
|
|
76
|
-
});
|
|
84
|
+
}, 'PrismaRootModuleDefinition');
|
|
77
85
|
}
|
|
78
86
|
function buildPrismaModuleAsync(options) {
|
|
79
|
-
class PrismaAsyncModuleDefinition {}
|
|
80
87
|
const factory = options.useFactory;
|
|
81
88
|
const normalizedName = normalizePrismaRegistrationName(options.name);
|
|
82
89
|
if (normalizedName !== undefined && options.global) {
|
|
@@ -95,11 +102,11 @@ function buildPrismaModuleAsync(options) {
|
|
|
95
102
|
});
|
|
96
103
|
}
|
|
97
104
|
};
|
|
98
|
-
return
|
|
105
|
+
return definePrismaModule({
|
|
99
106
|
exports: normalizedName === undefined ? [PrismaService, PrismaTransactionInterceptor, getPrismaServiceToken(), getPrismaClientToken(), getPrismaOptionsToken()] : [getPrismaServiceToken(normalizedName), getPrismaClientToken(normalizedName), getPrismaOptionsToken(normalizedName)],
|
|
100
107
|
global: normalizedName === undefined ? options.global ?? false : false,
|
|
101
108
|
providers: createPrismaRuntimeProviders(normalizedOptionsProvider, normalizedName)
|
|
102
|
-
});
|
|
109
|
+
}, 'PrismaAsyncModuleDefinition');
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
/**
|
package/dist/service.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type OnApplicationShutdown, type OnModuleInit } from './integration.js';
|
|
2
2
|
import type { InferPrismaTransactionClient, InferPrismaTransactionOptions, PrismaClientLike, PrismaHandleProvider } from './types.js';
|
|
3
3
|
interface PrismaServiceOptions {
|
|
4
4
|
strictTransactions: boolean;
|
|
@@ -16,6 +16,8 @@ export declare class PrismaService<TClient extends PrismaClientLike<TTransaction
|
|
|
16
16
|
private readonly transactions;
|
|
17
17
|
private readonly activeRequestTransactions;
|
|
18
18
|
private readonly activeTransactionBoundaries;
|
|
19
|
+
private connectTransition?;
|
|
20
|
+
private shutdownTransition?;
|
|
19
21
|
private transactionAbortSignalSupport;
|
|
20
22
|
private lifecycleState;
|
|
21
23
|
constructor(client: TClient, serviceOptions?: PrismaServiceOptions);
|
|
@@ -47,12 +49,38 @@ export declare class PrismaService<TClient extends PrismaClientLike<TTransaction
|
|
|
47
49
|
private runWithTransactionClient;
|
|
48
50
|
onModuleInit(): Promise<void>;
|
|
49
51
|
onApplicationShutdown(): Promise<void>;
|
|
52
|
+
private completeApplicationShutdown;
|
|
50
53
|
/**
|
|
51
54
|
* Creates a shared platform-status snapshot for runtime/CLI/Studio health surfaces.
|
|
52
55
|
*
|
|
53
56
|
* @returns Platform snapshot data reflecting lifecycle state and transaction capability diagnostics.
|
|
54
57
|
*/
|
|
55
|
-
createPlatformStatusSnapshot():
|
|
58
|
+
createPlatformStatusSnapshot(): {
|
|
59
|
+
details: Record<string, unknown>;
|
|
60
|
+
health: {
|
|
61
|
+
checks?: Array<{
|
|
62
|
+
message?: string;
|
|
63
|
+
name: string;
|
|
64
|
+
status: "pass" | "fail" | "degraded";
|
|
65
|
+
}>;
|
|
66
|
+
reason?: string;
|
|
67
|
+
status: "healthy" | "unhealthy" | "degraded";
|
|
68
|
+
};
|
|
69
|
+
ownership: {
|
|
70
|
+
externallyManaged: boolean;
|
|
71
|
+
ownsResources: boolean;
|
|
72
|
+
};
|
|
73
|
+
readiness: {
|
|
74
|
+
checks?: Array<{
|
|
75
|
+
message?: string;
|
|
76
|
+
name: string;
|
|
77
|
+
status: "pass" | "fail" | "degraded";
|
|
78
|
+
}>;
|
|
79
|
+
critical: boolean;
|
|
80
|
+
reason?: string;
|
|
81
|
+
status: "ready" | "not-ready" | "degraded";
|
|
82
|
+
};
|
|
83
|
+
};
|
|
56
84
|
/**
|
|
57
85
|
* Opens a Prisma interactive transaction boundary and executes the callback in that context.
|
|
58
86
|
*
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAIlB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC7B,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AASpB,UAAU,oBAAoB;IAC5B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAkHD;;;;;;GAMG;AACH,qBACa,aAAa,CACxB,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,EAC1D,mBAAmB,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAE5D,YAAW,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,EAAE,YAAY,EAAE,qBAAqB;IAWpH,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAVjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuD;IACpF,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAwC;IACpF,OAAO,CAAC,iBAAiB,CAAC,CAAgB;IAC1C,OAAO,CAAC,kBAAkB,CAAC,CAAgB;IAC3C,OAAO,CAAC,6BAA6B,CAA4C;IACjF,OAAO,CAAC,cAAc,CAAgE;gBAGnE,MAAM,EAAE,OAAO,EACf,cAAc,GAAE,oBAAoD;IAMvF;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,YAAY,CACjB,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,EAC1D,mBAAmB,GAAG,6BAA6B,CAAC,OAAO,CAAC,EAE5D,MAAM,EAAE,OAAO,EACf,cAAc,GAAE,oBAAoD,GACnE,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC;IAMxE,OAAO,CAAC,0BAA0B;IAkBlC;;;;;;;;;OASG;IACH,OAAO,IAAI,OAAO,GAAG,kBAAkB;YAIzB,wBAAwB;IAiDhC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAWnC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBxB,2BAA2B;IAqBzC;;;;OAIG;IACH,4BAA4B;;;;uBA1U5B,CAAA;;;;;;;;;;;;;uBARS,CAAC;;;;;;;;;IAgWV;;;;;;;;;;;;;;;;;OAiBG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAQrF;;;;;;;;;;;;;;;;;;OAkBG;IACG,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;YAkCpG,+BAA+B;YAyB/B,2BAA2B;IAqCzC,OAAO,CAAC,kCAAkC;IAM1C,OAAO,CAAC,oCAAoC;IAM5C,OAAO,CAAC,iCAAiC;IAMzC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,oCAAoC;IAY5C,OAAO,CAAC,sCAAsC;YAYhC,qCAAqC;IAyBnD,OAAO,CAAC,6BAA6B;IAUrC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,0BAA0B;IAWlC,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,+BAA+B;IAIvC,OAAO,CAAC,8BAA8B;IAatC,OAAO,CAAC,gCAAgC;CAIzC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,CAC7B,OAAO,SAAS,gBAAgB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,EACzE,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,EAC1D,mBAAmB,GAAG,6BAA6B,CAAC,OAAO,CAAC,IAC1D,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,GACjE,IAAI,CAAC,OAAO,EAAE,MAAM,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,CAAC,CAAC"}
|
package/dist/service.js
CHANGED
|
@@ -5,7 +5,7 @@ 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 { Inject } from '@fluojs/core';
|
|
8
|
-
import { createAbortError, createRequestAbortContext, raceWithAbort, trackActiveRequestTransaction, untrackActiveRequestTransaction } from '
|
|
8
|
+
import { createAbortError, createRequestAbortContext, raceWithAbort, trackActiveRequestTransaction, untrackActiveRequestTransaction } from './integration.js';
|
|
9
9
|
import { markPrismaServiceHandle } from './prisma-service-brand.js';
|
|
10
10
|
import { createPrismaPlatformStatusSnapshot } from './status.js';
|
|
11
11
|
import { PRISMA_CLIENT, PRISMA_OPTIONS } from './tokens.js';
|
|
@@ -81,6 +81,8 @@ class PrismaService {
|
|
|
81
81
|
transactions = createTransactionContextStore();
|
|
82
82
|
activeRequestTransactions = new Set();
|
|
83
83
|
activeTransactionBoundaries = new Set();
|
|
84
|
+
connectTransition;
|
|
85
|
+
shutdownTransition;
|
|
84
86
|
transactionAbortSignalSupport = 'unknown';
|
|
85
87
|
lifecycleState = 'created';
|
|
86
88
|
constructor(client, serviceOptions = {
|
|
@@ -172,17 +174,39 @@ class PrismaService {
|
|
|
172
174
|
}
|
|
173
175
|
async onModuleInit() {
|
|
174
176
|
if (typeof this.client.$connect === 'function') {
|
|
175
|
-
|
|
177
|
+
this.connectTransition = Promise.resolve(this.client.$connect());
|
|
178
|
+
await this.connectTransition;
|
|
179
|
+
}
|
|
180
|
+
if (this.lifecycleState === 'created') {
|
|
181
|
+
this.lifecycleState = 'ready';
|
|
176
182
|
}
|
|
177
|
-
this.lifecycleState = 'ready';
|
|
178
183
|
}
|
|
179
|
-
|
|
184
|
+
onApplicationShutdown() {
|
|
185
|
+
if (this.lifecycleState === 'stopped') {
|
|
186
|
+
return Promise.resolve();
|
|
187
|
+
}
|
|
188
|
+
if (this.shutdownTransition) {
|
|
189
|
+
return this.shutdownTransition;
|
|
190
|
+
}
|
|
191
|
+
const shutdownTransition = this.completeApplicationShutdown();
|
|
192
|
+
this.shutdownTransition = shutdownTransition;
|
|
193
|
+
void shutdownTransition.then(undefined, () => {
|
|
194
|
+
if (this.shutdownTransition === shutdownTransition) {
|
|
195
|
+
this.shutdownTransition = undefined;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
return shutdownTransition;
|
|
199
|
+
}
|
|
200
|
+
async completeApplicationShutdown() {
|
|
180
201
|
this.lifecycleState = 'shutting-down';
|
|
181
202
|
for (const transaction of this.activeRequestTransactions) {
|
|
182
203
|
transaction.abort(new Error('Application shutdown interrupted an open request transaction.'));
|
|
183
204
|
}
|
|
184
205
|
await Promise.allSettled(Array.from(this.activeRequestTransactions, transaction => transaction.settled));
|
|
185
206
|
await Promise.allSettled(Array.from(this.activeTransactionBoundaries, transaction => transaction.settled));
|
|
207
|
+
if (this.connectTransition) {
|
|
208
|
+
await Promise.allSettled([this.connectTransition]);
|
|
209
|
+
}
|
|
186
210
|
if (typeof this.client.$disconnect === 'function') {
|
|
187
211
|
await this.client.$disconnect();
|
|
188
212
|
}
|
|
@@ -196,6 +220,7 @@ class PrismaService {
|
|
|
196
220
|
*/
|
|
197
221
|
createPlatformStatusSnapshot() {
|
|
198
222
|
return createPrismaPlatformStatusSnapshot({
|
|
223
|
+
activeTransactionBoundaries: this.activeTransactionBoundaries.size,
|
|
199
224
|
activeRequestTransactions: this.activeRequestTransactions.size,
|
|
200
225
|
lifecycleState: this.lifecycleState,
|
|
201
226
|
strictTransactions: this.serviceOptions.strictTransactions,
|
package/dist/status.d.ts
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
type PlatformReadinessReport = {
|
|
2
|
+
checks?: Array<{
|
|
3
|
+
message?: string;
|
|
4
|
+
name: string;
|
|
5
|
+
status: 'pass' | 'fail' | 'degraded';
|
|
6
|
+
}>;
|
|
7
|
+
critical: boolean;
|
|
8
|
+
reason?: string;
|
|
9
|
+
status: 'ready' | 'not-ready' | 'degraded';
|
|
10
|
+
};
|
|
11
|
+
type PlatformHealthReport = {
|
|
12
|
+
checks?: Array<{
|
|
13
|
+
message?: string;
|
|
14
|
+
name: string;
|
|
15
|
+
status: 'pass' | 'fail' | 'degraded';
|
|
16
|
+
}>;
|
|
17
|
+
reason?: string;
|
|
18
|
+
status: 'healthy' | 'unhealthy' | 'degraded';
|
|
19
|
+
};
|
|
20
|
+
type PersistencePlatformStatusSnapshot = {
|
|
21
|
+
details: Record<string, unknown>;
|
|
22
|
+
health: PlatformHealthReport;
|
|
23
|
+
ownership: {
|
|
24
|
+
externallyManaged: boolean;
|
|
25
|
+
ownsResources: boolean;
|
|
26
|
+
};
|
|
27
|
+
readiness: PlatformReadinessReport;
|
|
28
|
+
};
|
|
2
29
|
type PrismaPlatformLifecycleState = 'created' | 'ready' | 'shutting-down' | 'stopped';
|
|
3
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Supplies lifecycle and transaction state for a Prisma platform status snapshot.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Omit `activeTransactionBoundaries` when no outer service or manual transaction boundary is open;
|
|
35
|
+
* the snapshot reports it as `0`.
|
|
36
|
+
*/
|
|
37
|
+
export type PrismaPlatformStatusSnapshotInput = {
|
|
38
|
+
activeTransactionBoundaries?: number;
|
|
4
39
|
activeRequestTransactions: number;
|
|
5
40
|
lifecycleState: PrismaPlatformLifecycleState;
|
|
6
41
|
strictTransactions: boolean;
|
|
@@ -11,10 +46,15 @@ type PrismaPlatformStatusSnapshotInput = {
|
|
|
11
46
|
transactionContext?: 'als' | 'unavailable';
|
|
12
47
|
};
|
|
13
48
|
/**
|
|
14
|
-
*
|
|
49
|
+
* Creates a Prisma platform status snapshot for diagnostics surfaces.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* `details.activeTransactionBoundaries` reports open outer service/manual transaction boundaries that
|
|
53
|
+
* shutdown drains before disconnecting. It is intentionally distinct from
|
|
54
|
+
* `details.activeRequestTransactions`, which reports abort-aware request transaction activity.
|
|
15
55
|
*
|
|
16
|
-
* @param input
|
|
17
|
-
* @returns
|
|
56
|
+
* @param input Lifecycle and transaction activity inputs for the registered Prisma client.
|
|
57
|
+
* @returns A snapshot containing lifecycle, health, readiness, ownership, and transaction diagnostics.
|
|
18
58
|
*/
|
|
19
59
|
export declare function createPrismaPlatformStatusSnapshot(input: PrismaPlatformStatusSnapshotInput): PersistencePlatformStatusSnapshot;
|
|
20
60
|
export {};
|
package/dist/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,KAAK,uBAAuB,GAAG;IAC7B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAA;KAAE,CAAC,CAAC;IACzF,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,CAAC;CAC5C,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAA;KAAE,CAAC,CAAC;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;CAC9C,CAAC;AAEF,KAAK,iCAAiC,GAAG;IACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE;QACT,iBAAiB,EAAE,OAAO,CAAC;QAC3B,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,SAAS,EAAE,uBAAuB,CAAC;CACpC,CAAC;AAEF,KAAK,4BAA4B,GAAG,SAAS,GAAG,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;AAEtF;;;;;;GAMG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,yBAAyB,EAAE,MAAM,CAAC;IAClC,cAAc,EAAE,4BAA4B,CAAC;IAC7C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,6BAA6B,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;IACvE,kBAAkB,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC;CAC5C,CAAC;AAqEF;;;;;;;;;;GAUG;AACH,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,iCAAiC,GACvC,iCAAiC,CAsBnC"}
|
package/dist/status.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supplies lifecycle and transaction state for a Prisma platform status snapshot.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Omit `activeTransactionBoundaries` when no outer service or manual transaction boundary is open;
|
|
6
|
+
* the snapshot reports it as `0`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
function createReadiness(input) {
|
|
2
10
|
if (input.lifecycleState === 'created') {
|
|
3
11
|
return {
|
|
@@ -48,7 +56,7 @@ function createHealth(input) {
|
|
|
48
56
|
}
|
|
49
57
|
if (input.lifecycleState === 'shutting-down') {
|
|
50
58
|
return {
|
|
51
|
-
reason: 'Prisma integration is draining
|
|
59
|
+
reason: 'Prisma integration is draining open transactions during shutdown.',
|
|
52
60
|
status: 'degraded'
|
|
53
61
|
};
|
|
54
62
|
}
|
|
@@ -58,15 +66,21 @@ function createHealth(input) {
|
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
/**
|
|
61
|
-
*
|
|
69
|
+
* Creates a Prisma platform status snapshot for diagnostics surfaces.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* `details.activeTransactionBoundaries` reports open outer service/manual transaction boundaries that
|
|
73
|
+
* shutdown drains before disconnecting. It is intentionally distinct from
|
|
74
|
+
* `details.activeRequestTransactions`, which reports abort-aware request transaction activity.
|
|
62
75
|
*
|
|
63
|
-
* @param input
|
|
64
|
-
* @returns
|
|
76
|
+
* @param input Lifecycle and transaction activity inputs for the registered Prisma client.
|
|
77
|
+
* @returns A snapshot containing lifecycle, health, readiness, ownership, and transaction diagnostics.
|
|
65
78
|
*/
|
|
66
79
|
export function createPrismaPlatformStatusSnapshot(input) {
|
|
67
80
|
const transactionContext = input.transactionContext ?? 'als';
|
|
68
81
|
return {
|
|
69
82
|
details: {
|
|
83
|
+
activeTransactionBoundaries: input.activeTransactionBoundaries ?? 0,
|
|
70
84
|
activeRequestTransactions: input.activeRequestTransactions,
|
|
71
85
|
lifecycleState: input.lifecycleState,
|
|
72
86
|
strictTransactions: input.strictTransactions,
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"transaction",
|
|
10
10
|
"als"
|
|
11
11
|
],
|
|
12
|
-
"version": "
|
|
12
|
+
"version": "2.0.0",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"directory": "packages/prisma"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
21
|
+
"node": ">=24.0.0 <27"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
|
@@ -36,10 +36,9 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@fluojs/core": "^
|
|
40
|
-
"@fluojs/http": "^
|
|
41
|
-
"@fluojs/di": "^
|
|
42
|
-
"@fluojs/runtime": "^2.0.1"
|
|
39
|
+
"@fluojs/core": "^2.0.0",
|
|
40
|
+
"@fluojs/http": "^3.0.0",
|
|
41
|
+
"@fluojs/di": "^3.0.0"
|
|
43
42
|
},
|
|
44
43
|
"peerDependencies": {
|
|
45
44
|
"@prisma/client": ">=5.0.0"
|
|
@@ -50,8 +49,9 @@
|
|
|
50
49
|
}
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
|
-
"vitest": "^
|
|
54
|
-
"@fluojs/
|
|
52
|
+
"vitest": "^4.1.11",
|
|
53
|
+
"@fluojs/runtime": "^3.0.0",
|
|
54
|
+
"@fluojs/validation": "^2.0.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|