@fluojs/graphql 1.0.0-beta.5 → 1.0.0-beta.7

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 CHANGED
@@ -33,6 +33,8 @@ pnpm add @fluojs/graphql graphql graphql-yoga
33
33
 
34
34
  `GraphqlModule.forRoot(...)`를 등록하고 표준 데코레이터를 사용하여 resolver를 정의합니다. 현재 `@fluojs/graphql`는 동기 모듈 엔트리포인트만 제공하며 `GraphqlModule.forRootAsync(...)` 계약은 없습니다.
35
35
 
36
+ Code-first resolver discovery 대신 schema-first 통합을 원하면 executable `GraphQLSchema`를 `schema`로 전달할 수도 있습니다.
37
+
36
38
  ```typescript
37
39
  import { Module } from '@fluojs/core';
38
40
  import { bootstrapNodeApplication } from '@fluojs/runtime/node';
@@ -150,11 +152,14 @@ GraphqlModule.forRoot({
150
152
  })
151
153
  ```
152
154
 
155
+ `@Subscription({ topics })`는 지원하지 않습니다. Subscription resolver는 `AsyncIterable`을 반환해야 합니다.
156
+
153
157
  ## 운영 가드레일
154
158
 
155
159
  - `graphiql`을 명시적으로 켜거나 `introspection: true`를 설정하지 않으면 스키마 introspection은 기본적으로 비활성화됩니다.
156
160
  - 문서 depth, field complexity, aggregate query cost에 대한 request validation budget이 기본적으로 보수적인 값으로 활성화됩니다.
157
161
  - Streaming GraphQL 응답은 downstream response stream이 닫히거나 오류를 내면 upstream fetch body를 cancel하므로 SSE subscription 리소스를 즉시 해제합니다.
162
+ - GraphQL 스키마 해석 이후 bootstrap이 실패하면 임시 `graphql/jsutils/instanceOf` 패치를 원복한 뒤 원래 오류를 다시 던지므로, 실패한 시작 시도가 이후 애플리케이션 시작의 process-wide GraphQL 동작을 오염시키지 않습니다.
158
163
  - WebSocket 구독 경로에는 별도의 전송 budget이 기본 적용됩니다: 동시 연결 `100`, 최대 payload 크기 `64 KiB`, 연결당 활성 operation `25`개입니다.
159
164
  - 무제한 WebSocket 동작이 정말 필요할 때만 `subscriptions.websocket.limits = false`를 사용하고, 그 경우에도 동일한 수준의 외부 제어 수단을 마련해야 합니다.
160
165
  - 무제한 동작이 꼭 필요할 때만 `limits: false`를 사용하고, 그 경우에는 외부 제어 수단을 함께 두어야 합니다.
@@ -187,8 +192,11 @@ GraphqlModule.forRoot({
187
192
  - `GraphqlModule.forRoot(options)`: GraphQL 통합을 위한 메인 엔트리 포인트.
188
193
  - `Resolver`, `Query`, `Mutation`, `Subscription`: 작업 데코레이터.
189
194
  - `Arg`: Input DTO 필드를 GraphQL 인자로 매핑하는 데코레이터.
190
- - `createDataLoader`, `createDataLoaderMap`: DataLoader 팩토리 헬퍼.
191
- - `GraphQLContext`: GraphQL 실행 컨텍스트를 위한 타입 정의.
195
+ - `createDataLoader`, `createDataLoaderMap`, `getRequestScopedDataLoader`, `createRequestScopedDataLoaderFactory`, `DataLoader`: DataLoader factory helper와 type.
196
+ - `listOf`, `isGraphqlListTypeRef`: list output type reference helper.
197
+ - `GraphQLContext` 및 export되는 option/metadata type: GraphQL 실행과 module 설정을 위한 타입 정의.
198
+
199
+ 지원되는 module option에는 `schema`, `context`, `plugins`, `graphiql`, `introspection`, `limits`, `subscriptions.websocket.enabled`, `subscriptions.websocket.limits`, `connectionInitWaitTimeoutMs`, `keepAliveMs`가 포함됩니다.
192
200
 
193
201
  ## 관련 패키지
194
202
 
@@ -198,5 +206,5 @@ GraphqlModule.forRoot({
198
206
 
199
207
  ## 예제 소스
200
208
 
201
- - `packages/graphql/src/module.test.ts`: 통합 테스트 및 사용 예제.
202
- - `examples/graphql-yoga`: 전체 GraphQL 애플리케이션 예제.
209
+ - `packages/graphql/src/module.test.ts`: 모듈 등록, resolver 실행, request-scoped container, subscription, guardrail 기본값을 다루는 통합 테스트 및 사용 예제.
210
+ - `packages/graphql/field-resolver-rfc.md`: 현재 런타임 계약에 포함되지 않는 field-resolver 패턴의 설계 노트.
package/README.md CHANGED
@@ -33,6 +33,8 @@ pnpm add @fluojs/graphql graphql graphql-yoga
33
33
 
34
34
  Register `GraphqlModule.forRoot(...)` and define a resolver using standard decorators. `@fluojs/graphql` currently exposes a synchronous module entrypoint only; there is no `GraphqlModule.forRootAsync(...)` contract.
35
35
 
36
+ You can also pass an executable `GraphQLSchema` via `schema` when you want schema-first integration instead of code-first resolver discovery.
37
+
36
38
  ```typescript
37
39
  import { Module } from '@fluojs/core';
38
40
  import { bootstrapNodeApplication } from '@fluojs/runtime/node';
@@ -150,11 +152,14 @@ GraphqlModule.forRoot({
150
152
  })
151
153
  ```
152
154
 
155
+ `@Subscription({ topics })` is not supported. Subscription resolvers must return an `AsyncIterable`.
156
+
153
157
  ## Operational Guardrails
154
158
 
155
159
  - Schema introspection is disabled by default unless you explicitly enable `graphiql` or set `introspection: true`.
156
160
  - Request validation budgets are enabled by default with conservative limits for document depth, field complexity, and aggregate query cost.
157
161
  - Streaming GraphQL responses cancel the upstream fetch body when the downstream response stream closes or errors, so SSE subscription resources are released promptly.
162
+ - Bootstrap failures after GraphQL schema resolution restore the package's temporary `graphql/jsutils/instanceOf` patch before rethrowing, so failed startups do not leak process-wide GraphQL behavior into later app attempts.
158
163
  - WebSocket subscriptions use separate transport budgets by default: `100` concurrent connections, `64 KiB` maximum payload size, and `25` active operations per connection.
159
164
  - Set `subscriptions.websocket.limits = false` only when you intentionally need unbounded websocket behavior and can enforce equivalent controls elsewhere.
160
165
  - Pass `limits: false` only when you intentionally need unbounded behavior and can compensate with external controls.
@@ -187,8 +192,11 @@ GraphqlModule.forRoot({
187
192
  - `GraphqlModule.forRoot(options)`: Main entry point for GraphQL integration.
188
193
  - `Resolver`, `Query`, `Mutation`, `Subscription`: Operation decorators.
189
194
  - `Arg`: Input DTO field-to-GraphQL-argument mapping decorator.
190
- - `createDataLoader`, `createDataLoaderMap`: DataLoader factory helpers.
191
- - `GraphQLContext`: Type definition for the GraphQL execution context.
195
+ - `createDataLoader`, `createDataLoaderMap`, `getRequestScopedDataLoader`, `createRequestScopedDataLoaderFactory`, `DataLoader`: DataLoader factory helpers and types.
196
+ - `listOf`, `isGraphqlListTypeRef`: Helpers for list output type references.
197
+ - `GraphQLContext` and exported option/metadata types: Type definitions for GraphQL execution and module configuration.
198
+
199
+ Supported module options include `schema`, `context`, `plugins`, `graphiql`, `introspection`, `limits`, `subscriptions.websocket.enabled`, `subscriptions.websocket.limits`, `connectionInitWaitTimeoutMs`, and `keepAliveMs`.
192
200
 
193
201
  ## Related Packages
194
202
 
@@ -198,5 +206,5 @@ GraphqlModule.forRoot({
198
206
 
199
207
  ## Example Sources
200
208
 
201
- - `packages/graphql/src/module.test.ts`: Integration tests and usage examples.
202
- - `examples/graphql-yoga`: Complete GraphQL application example.
209
+ - `packages/graphql/src/module.test.ts`: Integration tests and usage examples for module registration, resolver execution, request-scoped containers, subscriptions, and guardrail defaults.
210
+ - `packages/graphql/field-resolver-rfc.md`: Design notes for field-resolver patterns that are not part of the current runtime contract.
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAoB,cAAc,EAAE,qBAAqB,EAA6C,MAAM,YAAY,CAAC;AAGrI,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAC1F,KAAK,yBAAyB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;AACjG,KAAK,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;AAE1H;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AACnD,KAAK,mBAAmB,GAAG,yBAAyB,CAAC;AACrD,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AAwGnD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQ9D;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAErG;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAmBxD"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAoB,cAAc,EAAE,qBAAqB,EAA6C,MAAM,YAAY,CAAC;AAGrI,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAC1F,KAAK,yBAAyB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;AACjG,KAAK,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;AAE1H;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AACnD,KAAK,mBAAmB,GAAG,yBAAyB,CAAC;AACrD,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AAyGnD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQ9D;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,mBAAmB,CAErG;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAmBxD"}
@@ -1,12 +1,12 @@
1
- import { metadataSymbol } from '@fluojs/core/internal';
1
+ import { ensureMetadataSymbol } from '@fluojs/core/internal';
2
2
  import { argMetadataSymbol, handlerMetadataSymbol, resolverMetadataSymbol } from './metadata.js';
3
3
 
4
4
  /**
5
5
  * Describes the resolver method options contract.
6
6
  */
7
7
 
8
+ ensureMetadataSymbol();
8
9
  function getStandardMetadataBag(metadata) {
9
- void metadataSymbol;
10
10
  return metadata;
11
11
  }
12
12
  function normalizeResolverTypeName(typeName, fallbackName) {
package/dist/service.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type HttpApplicationAdapter } from '@fluojs/http';
2
2
  import type { Container } from '@fluojs/di';
3
- import { type ApplicationLogger, type CompiledModule, type OnApplicationBootstrap, type OnApplicationShutdown } from '@fluojs/runtime';
3
+ import type { ApplicationLogger, CompiledModule, OnApplicationBootstrap, OnApplicationShutdown } from '@fluojs/runtime';
4
4
  import type { GraphqlModuleOptions } from './types.js';
5
5
  /**
6
6
  * Declares the HTTP endpoints that receive GraphQL GET and POST requests.
@@ -34,6 +34,7 @@ export declare class GraphqlLifecycleService implements OnApplicationBootstrap,
34
34
  constructor(runtimeContainer: Container, compiledModules: readonly CompiledModule[], logger: ApplicationLogger, adapter: HttpApplicationAdapter, options: GraphqlModuleOptions);
35
35
  onApplicationBootstrap(): Promise<void>;
36
36
  onApplicationShutdown(): Promise<void>;
37
+ private resetGraphqlRuntimeState;
37
38
  private resolveGraphiqlEnabled;
38
39
  private resolveIntrospectionEnabled;
39
40
  private resolveWebSocketLimits;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgD,KAAK,sBAAsB,EAAsD,MAAM,cAAc,CAAC;AAE7J,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AA2BzB,OAAO,KAAK,EAEV,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAmIpB;;GAEG;AACH,qBACa,yBAAyB;IAEpC,SAAS,IAAI,SAAS;IAKtB,UAAU,IAAI,SAAS;CAGxB;AA+ID;;GAEG;AACH,qBACa,uBAAwB,YAAW,sBAAsB,EAAE,qBAAqB;IA6DzF,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAhExB,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA6C;IAC1F,OAAO,CAAC,mBAAmB,CAAkD;IAC7E,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,wBAAwB,CAAkC;IAClE,OAAO,CAAC,sBAAsB,CAAgC;IAC9D,OAAO,CAAC,uBAAuB,CAAyD;IACxF,OAAO,CAAC,6BAA6B,CAA2B;IAChE,OAAO,CAAC,yBAAyB,CAAyD;IAC1F,OAAO,CAAC,IAAI,CAAuB;IAEnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CA4CzB;gBAGiB,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,sBAAsB,EACjC,OAAO,EAAE,oBAAoB;IAGxC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsCvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5C,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,0BAA0B;YAuEpB,4BAA4B;IAuC1C,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,oBAAoB;YAkBd,wBAAwB;IAwDtC,OAAO,CAAC,kCAAkC;IAwB1C,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,sCAAsC;YAchC,kCAAkC;YAqBlC,sCAAsC;IAkBpD,OAAO,CAAC,6BAA6B;YAYvB,yBAAyB;CAexC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgD,KAAK,sBAAsB,EAAsD,MAAM,cAAc,CAAC;AAE7J,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA2BxH,OAAO,KAAK,EAEV,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAmIpB;;GAEG;AACH,qBACa,yBAAyB;IAEpC,SAAS,IAAI,SAAS;IAKtB,UAAU,IAAI,SAAS;CAGxB;AA+ID;;GAEG;AACH,qBACa,uBAAwB,YAAW,sBAAsB,EAAE,qBAAqB;IA6DzF,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAhE1B,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA6C;IAC1F,OAAO,CAAC,mBAAmB,CAAkD;IAC7E,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,wBAAwB,CAAkC;IAClE,OAAO,CAAC,sBAAsB,CAAgC;IAC9D,OAAO,CAAC,uBAAuB,CAAyD;IACxF,OAAO,CAAC,6BAA6B,CAA2B;IAChE,OAAO,CAAC,yBAAyB,CAAyD;IAC1F,OAAO,CAAC,IAAI,CAAuB;IAEnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CA4CzB;gBAGiB,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,oBAAoB;IAG1C,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;YAI9B,wBAAwB;IAYtC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,0BAA0B;YAuEpB,4BAA4B;IAuC1C,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,oBAAoB;YAkBd,wBAAwB;IAwDtC,OAAO,CAAC,kCAAkC;IAwB1C,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,sCAAsC;YAchC,kCAAkC;YAqBlC,sCAAsC;IAkBpD,OAAO,CAAC,6BAA6B;YAYvB,yBAAyB;CAexC"}
package/dist/service.js CHANGED
@@ -284,30 +284,42 @@ class GraphqlLifecycleService {
284
284
  if (this.middlewareRegistered) {
285
285
  return;
286
286
  }
287
- const deps = await loadGraphqlDeps();
288
- const schema = this.resolveSchema(deps);
289
- this.executeGraphqlOperation = deps.execute;
290
- this.graphQLErrorConstructor = deps.GraphQLError;
291
- this.subscribeGraphqlOperation = deps.subscribe;
292
- const requestLimits = resolveGraphqlRequestLimits(this.options.limits);
293
- const validationPlugin = createGraphqlValidationPlugin({
294
- introspection: this.resolveIntrospectionEnabled(),
295
- limits: requestLimits
296
- });
297
- this.yoga = deps.createYoga({
298
- context: contextValue => contextValue[GRAPHQL_CONTEXT_OVERRIDE] ?? this.buildGraphqlContext(contextValue.request),
299
- graphqlEndpoint: '/graphql',
300
- graphiql: this.resolveGraphiqlEnabled(),
301
- ...(validationPlugin || this.options.plugins && this.options.plugins.length > 0 ? {
302
- plugins: [...(validationPlugin ? [validationPlugin] : []), ...(this.options.plugins ?? [])]
303
- } : {}),
304
- schema
305
- });
306
- this.registerWebSocketTransport();
307
- this.registerMiddleware();
308
- this.middlewareRegistered = true;
287
+ try {
288
+ const deps = await loadGraphqlDeps();
289
+ const schema = this.resolveSchema(deps);
290
+ this.executeGraphqlOperation = deps.execute;
291
+ this.graphQLErrorConstructor = deps.GraphQLError;
292
+ this.subscribeGraphqlOperation = deps.subscribe;
293
+ const requestLimits = resolveGraphqlRequestLimits(this.options.limits);
294
+ const validationPlugin = createGraphqlValidationPlugin({
295
+ introspection: this.resolveIntrospectionEnabled(),
296
+ limits: requestLimits
297
+ });
298
+ this.yoga = deps.createYoga({
299
+ context: contextValue => contextValue[GRAPHQL_CONTEXT_OVERRIDE] ?? this.buildGraphqlContext(contextValue.request),
300
+ graphqlEndpoint: '/graphql',
301
+ graphiql: this.resolveGraphiqlEnabled(),
302
+ ...(validationPlugin || this.options.plugins && this.options.plugins.length > 0 ? {
303
+ plugins: [...(validationPlugin ? [validationPlugin] : []), ...(this.options.plugins ?? [])]
304
+ } : {}),
305
+ schema
306
+ });
307
+ this.registerWebSocketTransport();
308
+ this.registerMiddleware();
309
+ this.middlewareRegistered = true;
310
+ } catch (error) {
311
+ try {
312
+ await this.resetGraphqlRuntimeState();
313
+ } catch (cleanupError) {
314
+ this.logger.error('Failed to clean up GraphQL runtime after bootstrap failure.', cleanupError, 'GraphqlLifecycleService');
315
+ }
316
+ throw error;
317
+ }
309
318
  }
310
319
  async onApplicationShutdown() {
320
+ await this.resetGraphqlRuntimeState();
321
+ }
322
+ async resetGraphqlRuntimeState() {
311
323
  await this.unregisterWebSocketTransport();
312
324
  this.unregisterMiddleware();
313
325
  this.middlewareRegistered = false;
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "yoga",
10
10
  "api"
11
11
  ],
12
- "version": "1.0.0-beta.5",
12
+ "version": "1.0.0-beta.7",
13
13
  "private": false,
14
14
  "license": "MIT",
15
15
  "repository": {
@@ -41,11 +41,11 @@
41
41
  "graphql-ws": "^5.16.2",
42
42
  "graphql-yoga": "^5.18.1",
43
43
  "ws": "^8.18.3",
44
- "@fluojs/core": "^1.0.0-beta.3",
45
- "@fluojs/di": "^1.0.0-beta.6",
46
- "@fluojs/http": "^1.0.0-beta.9",
47
- "@fluojs/runtime": "^1.0.0-beta.9",
48
- "@fluojs/validation": "^1.0.0-beta.2"
44
+ "@fluojs/core": "^1.0.0-beta.6",
45
+ "@fluojs/di": "^1.0.0-beta.8",
46
+ "@fluojs/http": "^1.0.0-beta.11",
47
+ "@fluojs/runtime": "^1.0.0-beta.12",
48
+ "@fluojs/validation": "^1.0.0-beta.4"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/ws": "^8.18.1",