nitro-graphql 2.0.0-beta.56 → 2.0.0-beta.58

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.md CHANGED
@@ -82,5 +82,5 @@ See the [documentation](https://nitro-graphql.pages.dev) for Nuxt and Vite setup
82
82
  [docs-href]: https://nitro-graphql.pages.dev
83
83
  [beta-src]: https://img.shields.io/npm/v/nitro-graphql/beta?style=flat&logo=rocket&logoColor=white&label=beta&color=7c3aed&colorA=080f12
84
84
  [beta-href]: https://github.com/productdevbook/nitro-graphql/releases
85
- [coverage-src]: https://img.shields.io/badge/coverage-63%25-green?style=flat&colorA=080f12
85
+ [coverage-src]: https://img.shields.io/badge/coverage-71%25-green?style=flat&colorA=080f12
86
86
  [coverage-href]: https://github.com/productdevbook/nitro-graphql/actions/workflows/ci.yml
@@ -19,5 +19,25 @@ declare function generateClientTypesCore(input: ClientCodegenInput): Promise<Cli
19
19
  * Generate client types for external GraphQL service
20
20
  */
21
21
  declare function generateExternalClientTypesCore(service: ExternalServiceCodegenConfig, schema: GraphQLSchema, documents: Source[], virtualTypesPath?: string): Promise<ClientCodegenResult | false>;
22
+ /**
23
+ * Subscription info extracted from GraphQL documents
24
+ */
25
+ interface SubscriptionInfo {
26
+ /** Original operation name from GraphQL document (used for method names) */
27
+ name: string;
28
+ /** PascalCase version for type references (matches GraphQL codegen output) */
29
+ typeName: string;
30
+ fieldName: string;
31
+ hasVariables: boolean;
32
+ }
33
+ /**
34
+ * Extract subscription operations from GraphQL documents
35
+ */
36
+ declare function extractSubscriptions(docs: Source[]): SubscriptionInfo[];
37
+ /**
38
+ * Generate subscription builder code (Drizzle-style API) + Vue Composables
39
+ * Returns empty string if subscriptions are not enabled or no subscription operations found
40
+ */
41
+ declare function generateSubscriptionBuilder(docs: Source[], subscriptionsEnabled: boolean): string;
22
42
  //#endregion
23
- export { DEFAULT_CLIENT_CODEGEN_CONFIG, type GraphQLLoadSchemaOptions, type GraphQLTypeDefPointer, downloadAndSaveSchema, generateClientTypesCore, generateExternalClientTypesCore, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments };
43
+ export { DEFAULT_CLIENT_CODEGEN_CONFIG, type GraphQLLoadSchemaOptions, type GraphQLTypeDefPointer, SubscriptionInfo, downloadAndSaveSchema, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments };
@@ -10,7 +10,7 @@ import { plugin as plugin$1 } from "@graphql-codegen/typescript";
10
10
  import { plugin as plugin$2 } from "@graphql-codegen/typescript-generic-sdk";
11
11
  import { plugin as plugin$3 } from "@graphql-codegen/typescript-operations";
12
12
  import { printSchemaWithDirectives } from "@graphql-tools/utils";
13
- import { parse } from "graphql";
13
+ import { Kind, parse } from "graphql";
14
14
 
15
15
  //#region src/core/codegen/client.ts
16
16
  /**
@@ -145,6 +145,405 @@ async function generateExternalClientTypesCore(service, schema, documents, virtu
145
145
  virtualTypesPath
146
146
  });
147
147
  }
148
+ /**
149
+ * Convert first character to uppercase (PascalCase)
150
+ */
151
+ function toPascalCase(str) {
152
+ return str.charAt(0).toUpperCase() + str.slice(1);
153
+ }
154
+ /**
155
+ * Extract subscription operations from GraphQL documents
156
+ */
157
+ function extractSubscriptions(docs) {
158
+ const subscriptions = [];
159
+ for (const doc of docs) {
160
+ if (!doc.document) continue;
161
+ for (const def of doc.document.definitions) if (def.kind === Kind.OPERATION_DEFINITION && def.operation === "subscription") {
162
+ const operationDef = def;
163
+ const name = operationDef.name?.value;
164
+ if (!name) continue;
165
+ const firstSelection = operationDef.selectionSet.selections[0];
166
+ if (firstSelection.kind !== Kind.FIELD) continue;
167
+ const fieldName = firstSelection.name.value;
168
+ const hasVariables = (operationDef.variableDefinitions?.length || 0) > 0;
169
+ subscriptions.push({
170
+ name,
171
+ typeName: toPascalCase(name),
172
+ fieldName,
173
+ hasVariables
174
+ });
175
+ }
176
+ }
177
+ return subscriptions;
178
+ }
179
+ /**
180
+ * Generate subscription builder code (Drizzle-style API) + Vue Composables
181
+ * Returns empty string if subscriptions are not enabled or no subscription operations found
182
+ */
183
+ function generateSubscriptionBuilder(docs, subscriptionsEnabled) {
184
+ if (!subscriptionsEnabled) return "";
185
+ const subscriptions = extractSubscriptions(docs);
186
+ if (subscriptions.length === 0) return "";
187
+ let output = `
188
+ // === Subscription Imports ===
189
+ import { ref, onUnmounted, computed } from 'vue'
190
+ import type { Ref } from 'vue'
191
+ import type {
192
+ ConnectionState,
193
+ SubscriptionHandle,
194
+ SubscriptionSession,
195
+ SubscriptionTransport,
196
+ TransportOptions,
197
+ } from 'nitro-graphql/subscribe'
198
+ import { subscriptionClient } from './subscribe'
199
+
200
+ // === Subscription Types ===
201
+ export type { ConnectionState, SubscriptionHandle, SubscriptionSession, SubscriptionTransport, TransportOptions }
202
+
203
+ // Forward declaration for UseSubscriptionSessionReturn (defined below)
204
+ export interface UseSubscriptionSessionReturn {
205
+ /** The underlying session object */
206
+ session: SubscriptionSession
207
+ /** Subscribe using the shared session (updates reactive refs) */
208
+ subscribe: <TData = unknown>(
209
+ query: string,
210
+ variables: unknown,
211
+ onData?: (data: TData) => void,
212
+ onError?: (error: Error) => void,
213
+ ) => SubscriptionHandle
214
+ /** Close all subscriptions and the connection */
215
+ close: () => void
216
+ /** Is the session connected (reactive) */
217
+ isConnected: Ref<boolean>
218
+ /** Current connection state (reactive) */
219
+ state: Ref<ConnectionState>
220
+ /** Number of active subscriptions (reactive) */
221
+ subscriptionCount: Ref<number>
222
+ }
223
+
224
+ export interface UseSubscriptionOptions<T> {
225
+ /** Auto-start subscription on mount (default: false) */
226
+ immediate?: boolean
227
+ /** Callback when subscription starts */
228
+ onStart?: () => void
229
+ /** Callback when subscription stops */
230
+ onStop?: () => void
231
+ /** Callback when data is received */
232
+ onData?: (data: T) => void
233
+ /** Callback when error occurs */
234
+ onError?: (error: Error) => void
235
+ /** Callback when WebSocket connects */
236
+ onConnected?: () => void
237
+ /** Callback when WebSocket reconnects */
238
+ onReconnected?: () => void
239
+ /** Callback when WebSocket disconnects */
240
+ onDisconnected?: () => void
241
+ /** Callback when connection state changes */
242
+ onStateChange?: (state: ConnectionState) => void
243
+ /** Use existing session for multiplexing (pass result from useSubscriptionSession) */
244
+ session?: UseSubscriptionSessionReturn
245
+ /** Transport type: 'websocket' (default), 'sse', or 'auto' (WS first, SSE fallback) */
246
+ transport?: SubscriptionTransport
247
+ }
248
+
249
+ export interface UseSubscriptionReturn<T> {
250
+ /** Reactive subscription data */
251
+ data: Ref<T | null>
252
+ /** Reactive error state */
253
+ error: Ref<Error | null>
254
+ /** Is subscription active */
255
+ isActive: Ref<boolean>
256
+ /** Connection state */
257
+ state: Ref<ConnectionState>
258
+ /** Active transport type ('websocket' | 'sse') */
259
+ transport: Ref<'websocket' | 'sse'>
260
+ /** Start subscription */
261
+ start: () => void
262
+ /** Stop subscription */
263
+ stop: () => void
264
+ /** Restart subscription */
265
+ restart: () => void
266
+ }
267
+
268
+ // === Subscription Builder (Drizzle-style API) ===
269
+ interface SubscriptionBuilder<TData> {
270
+ onData(fn: (data: TData) => void): SubscriptionBuilder<TData>
271
+ onError(fn: (error: Error) => void): SubscriptionBuilder<TData>
272
+ start(): SubscriptionHandle
273
+ subscribe(fn: (data: TData) => void): SubscriptionHandle
274
+ }
275
+
276
+ function createSubscriptionBuilder<TData>(query: string, variables: unknown): SubscriptionBuilder<TData> {
277
+ let onDataFn: ((data: TData) => void) | undefined
278
+ let onErrorFn: ((error: Error) => void) | undefined
279
+
280
+ const builder: SubscriptionBuilder<TData> = {
281
+ onData(fn: (data: TData) => void) {
282
+ onDataFn = fn
283
+ return builder
284
+ },
285
+ onError(fn: (error: Error) => void) {
286
+ onErrorFn = fn
287
+ return builder
288
+ },
289
+ start(): SubscriptionHandle {
290
+ return subscriptionClient.subscribe(query, variables, onDataFn, onErrorFn)
291
+ },
292
+ subscribe(fn: (data: TData) => void): SubscriptionHandle {
293
+ return subscriptionClient.subscribe(query, variables, fn, undefined)
294
+ },
295
+ }
296
+
297
+ return builder
298
+ }
299
+
300
+ export const subscription = {
301
+ `;
302
+ for (const sub of subscriptions) if (sub.hasVariables) output += ` ${sub.typeName}(variables: Types.${sub.typeName}SubscriptionVariables): SubscriptionBuilder<Types.${sub.typeName}Subscription['${sub.fieldName}']> {
303
+ return createSubscriptionBuilder<Types.${sub.typeName}Subscription['${sub.fieldName}']>(${sub.typeName}Document, variables)
304
+ },
305
+ `;
306
+ else output += ` ${sub.typeName}(): SubscriptionBuilder<Types.${sub.typeName}Subscription['${sub.fieldName}']> {
307
+ return createSubscriptionBuilder<Types.${sub.typeName}Subscription['${sub.fieldName}']>(${sub.typeName}Document, undefined)
308
+ },
309
+ `;
310
+ output += `}
311
+
312
+ // === Framework-Agnostic Session (for non-Vue usage) ===
313
+ /**
314
+ * Create a multiplexed subscription session (framework-agnostic)
315
+ * All subscriptions share a single WebSocket connection.
316
+ *
317
+ * @example
318
+ * // Vanilla JS / Node.js / React / etc.
319
+ * const session = createSubscriptionSession()
320
+ * const sub1 = session.subscribe(query1, vars1, onData1)
321
+ * const sub2 = session.subscribe(query2, vars2, onData2)
322
+ * // Both use the same WebSocket connection
323
+ * sub1.unsubscribe()
324
+ * session.close() // Close all
325
+ *
326
+ * @returns SubscriptionSession - Framework-agnostic session object
327
+ */
328
+ export function createSubscriptionSession(): SubscriptionSession {
329
+ return subscriptionClient.createSession()
330
+ }
331
+
332
+ // === Vue Composable: useSubscriptionSession (Multiplexing) ===
333
+ export interface UseSubscriptionSessionReturn {
334
+ /** The underlying session object */
335
+ session: SubscriptionSession
336
+ /** Subscribe using the shared session */
337
+ subscribe: <TData = unknown>(
338
+ query: string,
339
+ variables: unknown,
340
+ onData?: (data: TData) => void,
341
+ onError?: (error: Error) => void,
342
+ ) => SubscriptionHandle
343
+ /** Close all subscriptions and the connection */
344
+ close: () => void
345
+ /** Is the session connected (reactive) */
346
+ isConnected: Ref<boolean>
347
+ /** Current connection state (reactive) */
348
+ state: Ref<ConnectionState>
349
+ /** Number of active subscriptions (reactive) */
350
+ subscriptionCount: Ref<number>
351
+ }
352
+
353
+ /**
354
+ * Vue composable for multiplexed subscription session
355
+ * Provides reactive state and automatic cleanup on unmount.
356
+ *
357
+ * @example
358
+ * // Vue 3 component
359
+ * const session = useSubscriptionSession()
360
+ * const { data } = useCountdown({ from: 10 }, { session })
361
+ * // Session auto-closes on component unmount
362
+ *
363
+ * @returns UseSubscriptionSessionReturn - Vue-reactive session wrapper
364
+ */
365
+ export function useSubscriptionSession(): UseSubscriptionSessionReturn {
366
+ const session = subscriptionClient.createSession()
367
+
368
+ // Use refs for reactivity (session getters are not reactive)
369
+ const isConnected = ref(session.isConnected)
370
+ const state = ref<ConnectionState>(session.state)
371
+ const subscriptionCount = ref(session.subscriptionCount)
372
+
373
+ // Update refs when session state changes
374
+ function updateRefs() {
375
+ isConnected.value = session.isConnected
376
+ state.value = session.state
377
+ subscriptionCount.value = session.subscriptionCount
378
+ }
379
+
380
+ // Subscribe to session state changes for automatic reactivity
381
+ const unsubscribeStateChange = session.onStateChange(() => {
382
+ updateRefs()
383
+ })
384
+
385
+ function subscribe<TData = unknown>(
386
+ query: string,
387
+ variables: unknown,
388
+ onData?: (data: TData) => void,
389
+ onError?: (error: Error) => void,
390
+ ): SubscriptionHandle {
391
+ return session.subscribe(query, variables, onData as (data: unknown) => void, onError)
392
+ }
393
+
394
+ function close() {
395
+ session.close()
396
+ }
397
+
398
+ onUnmounted(() => {
399
+ unsubscribeStateChange()
400
+ close()
401
+ })
402
+
403
+ return {
404
+ session,
405
+ subscribe,
406
+ close,
407
+ isConnected,
408
+ state,
409
+ subscriptionCount,
410
+ }
411
+ }
412
+
413
+ // === Vue Composables ===
414
+ function createUseSubscription<TData, TVariables = undefined>(
415
+ query: string,
416
+ getVariables: () => TVariables,
417
+ ): (options?: UseSubscriptionOptions<TData>) => UseSubscriptionReturn<TData> {
418
+ return (options: UseSubscriptionOptions<TData> = {}): UseSubscriptionReturn<TData> => {
419
+ const data = ref<TData | null>(null) as Ref<TData | null>
420
+ const error = ref<Error | null>(null)
421
+ const isActive = ref(false)
422
+ const state = ref<ConnectionState>('idle')
423
+ const transport = ref<'websocket' | 'sse'>('websocket')
424
+ let handle: SubscriptionHandle | null = null
425
+
426
+ // Resolve transport options
427
+ const transportOptions: TransportOptions = {
428
+ transport: options.transport,
429
+ }
430
+
431
+ function start() {
432
+ stop()
433
+ isActive.value = true
434
+ error.value = null
435
+ options.onStart?.()
436
+
437
+ const variables = getVariables()
438
+
439
+ if (options.session) {
440
+ // Use existing session for multiplexing (WebSocket only)
441
+ handle = options.session.subscribe<TData>(
442
+ query,
443
+ variables,
444
+ (d: TData) => {
445
+ data.value = d
446
+ options.onData?.(d)
447
+ },
448
+ (e: Error) => {
449
+ error.value = e
450
+ options.onError?.(e)
451
+ },
452
+ )
453
+ transport.value = 'websocket'
454
+ } else {
455
+ // Create dedicated connection with transport selection
456
+ handle = subscriptionClient.subscribe<TData>(
457
+ query,
458
+ variables,
459
+ (d: TData) => {
460
+ data.value = d
461
+ options.onData?.(d)
462
+ },
463
+ (e: Error) => {
464
+ error.value = e
465
+ options.onError?.(e)
466
+ },
467
+ transportOptions,
468
+ )
469
+ // Update transport ref from handle
470
+ transport.value = handle.transport
471
+ }
472
+ }
473
+
474
+ function stop() {
475
+ if (handle) {
476
+ handle.unsubscribe()
477
+ handle = null
478
+ isActive.value = false
479
+ options.onStop?.()
480
+ }
481
+ }
482
+
483
+ function restart() {
484
+ stop()
485
+ start()
486
+ }
487
+
488
+ if (options.immediate) {
489
+ start()
490
+ }
491
+
492
+ onUnmounted(stop)
493
+
494
+ return { data, error, isActive, state, transport, start, stop, restart }
495
+ }
496
+ }
497
+
498
+ // === Subscription Return Types ===
499
+ `;
500
+ for (const sub of subscriptions) {
501
+ const typeName = `Types.${sub.typeName}Subscription['${sub.fieldName}']`;
502
+ output += `/** Return type for use${sub.typeName} composable */
503
+ export type Use${sub.typeName}Return = UseSubscriptionReturn<${typeName}>
504
+ `;
505
+ }
506
+ output += `
507
+ // === Vue Composables ===
508
+ `;
509
+ for (const sub of subscriptions) {
510
+ const typeName = `Types.${sub.typeName}Subscription['${sub.fieldName}']`;
511
+ const varsType = `Types.${sub.typeName}SubscriptionVariables`;
512
+ if (sub.hasVariables) output += `/**
513
+ * Vue composable for ${sub.typeName} subscription
514
+ * @param variables - Subscription variables
515
+ * @param options - Subscription options (immediate, onData, onError, session, etc.)
516
+ * @returns Reactive subscription state: { data, error, isActive, state, start, stop, restart }
517
+ */
518
+ export function use${sub.typeName}(
519
+ variables: ${varsType},
520
+ options?: UseSubscriptionOptions<${typeName}>,
521
+ ): Use${sub.typeName}Return {
522
+ return createUseSubscription<${typeName}, ${varsType}>(
523
+ ${sub.typeName}Document,
524
+ () => variables,
525
+ )(options)
526
+ }
527
+
528
+ `;
529
+ else output += `/**
530
+ * Vue composable for ${sub.typeName} subscription
531
+ * @param options - Subscription options (immediate, onData, onError, session, etc.)
532
+ * @returns Reactive subscription state: { data, error, isActive, state, start, stop, restart }
533
+ */
534
+ export function use${sub.typeName}(
535
+ options?: UseSubscriptionOptions<${typeName}>,
536
+ ): Use${sub.typeName}Return {
537
+ return createUseSubscription<${typeName}, undefined>(
538
+ ${sub.typeName}Document,
539
+ () => undefined,
540
+ )(options)
541
+ }
542
+
543
+ `;
544
+ }
545
+ return output;
546
+ }
148
547
 
149
548
  //#endregion
150
- export { DEFAULT_CLIENT_CODEGEN_CONFIG, downloadAndSaveSchema, generateClientTypesCore, generateExternalClientTypesCore, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments };
549
+ export { DEFAULT_CLIENT_CODEGEN_CONFIG, downloadAndSaveSchema, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments };
@@ -1,8 +1,8 @@
1
1
  import { loadGraphQLDocuments } from "./document-loader.mjs";
2
2
  import { GraphQLLoadSchemaOptions, GraphQLTypeDefPointer, downloadAndSaveSchema, graphQLLoadSchemaSync, loadExternalSchema } from "./schema-loader.mjs";
3
- import { DEFAULT_CLIENT_CODEGEN_CONFIG, generateClientTypesCore, generateExternalClientTypesCore } from "./client.mjs";
3
+ import { DEFAULT_CLIENT_CODEGEN_CONFIG, SubscriptionInfo, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder } from "./client.mjs";
4
4
  import { GENERATED_FILE_HEADER, pluginContent } from "./plugin.mjs";
5
5
  import { generateResolverModule, generateRuntimeIndex, generateSchemaModule } from "./runtime.mjs";
6
6
  import { DEFAULT_SERVER_CODEGEN_CONFIG, generateServerTypesCore, generateTypes } from "./server.mjs";
7
7
  import { validateNoDuplicateTypes, validateSchemaFiles } from "./validation.mjs";
8
- export { DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_SERVER_CODEGEN_CONFIG, GENERATED_FILE_HEADER, type GraphQLLoadSchemaOptions, type GraphQLTypeDefPointer, downloadAndSaveSchema, generateClientTypesCore, generateExternalClientTypesCore, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateTypes, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments, pluginContent, validateNoDuplicateTypes, validateSchemaFiles };
8
+ export { DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_SERVER_CODEGEN_CONFIG, GENERATED_FILE_HEADER, type GraphQLLoadSchemaOptions, type GraphQLTypeDefPointer, type SubscriptionInfo, downloadAndSaveSchema, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateSubscriptionBuilder, generateTypes, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments, pluginContent, validateNoDuplicateTypes, validateSchemaFiles };
@@ -1,9 +1,9 @@
1
1
  import { GENERATED_FILE_HEADER, pluginContent } from "./plugin.mjs";
2
2
  import { loadGraphQLDocuments } from "./document-loader.mjs";
3
3
  import { downloadAndSaveSchema, graphQLLoadSchemaSync, loadExternalSchema } from "./schema-loader.mjs";
4
- import { DEFAULT_CLIENT_CODEGEN_CONFIG, generateClientTypesCore, generateExternalClientTypesCore } from "./client.mjs";
4
+ import { DEFAULT_CLIENT_CODEGEN_CONFIG, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder } from "./client.mjs";
5
5
  import { generateResolverModule, generateRuntimeIndex, generateSchemaModule } from "./runtime.mjs";
6
6
  import { DEFAULT_SERVER_CODEGEN_CONFIG, generateServerTypesCore, generateTypes } from "./server.mjs";
7
7
  import { validateNoDuplicateTypes, validateSchemaFiles } from "./validation.mjs";
8
8
 
9
- export { DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_SERVER_CODEGEN_CONFIG, GENERATED_FILE_HEADER, downloadAndSaveSchema, generateClientTypesCore, generateExternalClientTypesCore, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateTypes, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments, pluginContent, validateNoDuplicateTypes, validateSchemaFiles };
9
+ export { DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_SERVER_CODEGEN_CONFIG, GENERATED_FILE_HEADER, downloadAndSaveSchema, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateSubscriptionBuilder, generateTypes, graphQLLoadSchemaSync, loadExternalSchema, loadGraphQLDocuments, pluginContent, validateNoDuplicateTypes, validateSchemaFiles };
@@ -6,7 +6,7 @@ import { ResolverImport, ScanContext, ScanResult, ScannedFile, ScannedResolver }
6
6
  import "./types/index.mjs";
7
7
  import { loadGraphQLDocuments } from "./codegen/document-loader.mjs";
8
8
  import { GraphQLLoadSchemaOptions, GraphQLTypeDefPointer, downloadAndSaveSchema, graphQLLoadSchemaSync, loadExternalSchema } from "./codegen/schema-loader.mjs";
9
- import { DEFAULT_CLIENT_CODEGEN_CONFIG, generateClientTypesCore, generateExternalClientTypesCore } from "./codegen/client.mjs";
9
+ import { DEFAULT_CLIENT_CODEGEN_CONFIG, SubscriptionInfo, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder } from "./codegen/client.mjs";
10
10
  import { GENERATED_FILE_HEADER, pluginContent } from "./codegen/plugin.mjs";
11
11
  import { generateResolverModule, generateRuntimeIndex, generateSchemaModule } from "./codegen/runtime.mjs";
12
12
  import { DEFAULT_SERVER_CODEGEN_CONFIG, generateServerTypesCore, generateTypes } from "./codegen/server.mjs";
@@ -30,4 +30,4 @@ import { getImportId, relativeWithDot } from "./utils/imports.mjs";
30
30
  import { createLogger, createSilentLogger, defaultLogger } from "./utils/logger.mjs";
31
31
  import { OfetchTemplateOptions, generateOfetchTemplate } from "./utils/ofetch-templates.mjs";
32
32
  import { validateExternalServices } from "./validation/external-services.mjs";
33
- export { ASTScanConfig, BUILTIN_SCALARS, CHUNK_NAME_RESOLVERS, CHUNK_NAME_SCHEMAS, CHUNK_PATH_GRAPHQL, CHUNK_PATH_UNKNOWN, CODEGEN_EXTERNALS, ClientCodegenConfig, ClientCodegenInput, ClientCodegenResult, CoreClientUtilsConfig, CoreCodegenConfig, CoreConfig, CoreContext, CoreExternalService, CoreFederationConfig, CoreGraphQLOptions, CoreLogger, CorePathsConfig, CoreScaffoldConfig, CoreSdkConfig, CoreSecurityConfig, CoreTypesConfig, CreateCoreConfigOptions, CreateMergedSchemaOptions, DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_CLIENT_TYPES_PATH, DEFAULT_GRAPHQL_SCALARS, DEFAULT_SERVER_CODEGEN_CONFIG, DEFAULT_SERVER_TYPES_PATH, DEFINE_DIRECTIVE, DEFINE_FIELD, DEFINE_FUNCTIONS, DEFINE_GRAPHQL_CONFIG, DEFINE_MUTATION, DEFINE_QUERY, DEFINE_RESOLVER, DEFINE_SCHEMA, DEFINE_SUBSCRIPTION, DIRECTIVE_EXTENSIONS, DIRECTIVE_GLOB_PATTERN, DIR_APP_GRAPHQL, DIR_BUILD_NITRO, DIR_BUILD_NUXT, DIR_CLIENT_GRAPHQL, DIR_EXTERNAL, DIR_ROUTES_GRAPHQL, DIR_SERVER_GRAPHQL, DIR_SERVER_GRAPHQL_WIN, DefineDirectiveConfig, DefineFunction, DirectiveArgument, DirectiveDefinition, DirectiveFileRef, DirectiveParser, DirectiveWrapper, ENDPOINT_DEBUG, ENDPOINT_GRAPHQL, ENDPOINT_HEALTH, ExternalServiceCodegenConfig, FEDERATION_EXTERNALS, FILE_CLIENT_TYPES, FILE_CONFIG_TS, FILE_CONTEXT_DTS, FILE_CONTEXT_TS, FILE_DIRECTIVES_GRAPHQL, FILE_GRAPHQL_CONFIG, FILE_GRAPHQL_DTS, FILE_INDEX_TS, FILE_OFETCH_TS, FILE_SCHEMA_GRAPHQL, FILE_SCHEMA_TS, FILE_SDK_TS, FILE_SERVER_TYPES, FRAMEWORK_NITRO, FRAMEWORK_NUXT, FRAMEWORK_STANDALONE, Flatten, Framework, GENERATED_FILE_HEADER, GLOB_SCAN_PATTERN, GRAPHQL_EXTENSIONS, GRAPHQL_FRAMEWORK_APOLLO, GRAPHQL_FRAMEWORK_YOGA, GRAPHQL_GLOB_PATTERN, GRAPHQL_HTTP_METHODS, GraphQLArgumentType, GraphQLBaseType, GraphQLFramework, GraphQLLoadSchemaOptions, GraphQLScalarType, GraphQLTypeDefPointer, HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_INTERNAL_ERROR, LOG_TAG, MaskErrorOptions, ModuleConfig, OfetchTemplateOptions, PATTERN_CLIENT_EXTERNAL_TYPES, PLACEHOLDER_BUILD_DIR, PLACEHOLDER_CLIENT_DIR, PLACEHOLDER_FRAMEWORK, PLACEHOLDER_ROOT_DIR, PLACEHOLDER_SERVER_DIR, PLACEHOLDER_SERVICE_NAME, PLACEHOLDER_TYPES_DIR, PackageConfig, ParsedDirective, RESOLVER_EXTENSIONS, RESOLVER_GLOB_PATTERN, RESOLVER_TYPE_DIRECTIVE, RESOLVER_TYPE_MUTATION, RESOLVER_TYPE_QUERY, RESOLVER_TYPE_RESOLVER, RESOLVER_TYPE_SUBSCRIPTION, RESOLVER_TYPE_TYPE, ResolvedExtend, ResolvedPackage, ResolverDefinition, ResolverImport, ResolverType, SERVICE_DEFAULT, ScalarType, ScanContext, ScanDocumentsOptions, ScanResult, ScannedFile, ScannedResolver, SchemaDefinition, SchemaLoadOptions, SdkCodegenConfig, ServerCodegenConfig, ServerCodegenInput, ServerCodegenResult, buildGraphQLSchema, createCoreConfig, createCoreContext, createDefaultMaskError, createLogger, createMergedSchema, createScanContext, createSilentLogger, deduplicateFiles, defaultLogger, directiveParser, downloadAndSaveSchema, ensureDir, extractPaths, filterByExtension, generateClientTypesCore, generateDirectiveSchema, generateDirectiveSchemas, generateExternalClientTypesCore, generateOfetchTemplate, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateTypes, getImportId, graphQLLoadSchemaSync, isLocalPath, loadExternalSchema, loadFederationSupport, loadGraphQLDocuments, loadPackageConfig, mergeGraphQLOptions, parse, parseDirectiveCall, parseResolverCall, parseSingleFile, pluginContent, readFileSafe, relativeWithDot, resetFederationCache, resolvePackageFiles, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST, subscribe, validate, validateExternalServices, validateNoDuplicateTypes, validateSchemaFiles, warnFederationUnavailable, writeFile, writeFileIfChanged };
33
+ export { ASTScanConfig, BUILTIN_SCALARS, CHUNK_NAME_RESOLVERS, CHUNK_NAME_SCHEMAS, CHUNK_PATH_GRAPHQL, CHUNK_PATH_UNKNOWN, CODEGEN_EXTERNALS, ClientCodegenConfig, ClientCodegenInput, ClientCodegenResult, CoreClientUtilsConfig, CoreCodegenConfig, CoreConfig, CoreContext, CoreExternalService, CoreFederationConfig, CoreGraphQLOptions, CoreLogger, CorePathsConfig, CoreScaffoldConfig, CoreSdkConfig, CoreSecurityConfig, CoreTypesConfig, CreateCoreConfigOptions, CreateMergedSchemaOptions, DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_CLIENT_TYPES_PATH, DEFAULT_GRAPHQL_SCALARS, DEFAULT_SERVER_CODEGEN_CONFIG, DEFAULT_SERVER_TYPES_PATH, DEFINE_DIRECTIVE, DEFINE_FIELD, DEFINE_FUNCTIONS, DEFINE_GRAPHQL_CONFIG, DEFINE_MUTATION, DEFINE_QUERY, DEFINE_RESOLVER, DEFINE_SCHEMA, DEFINE_SUBSCRIPTION, DIRECTIVE_EXTENSIONS, DIRECTIVE_GLOB_PATTERN, DIR_APP_GRAPHQL, DIR_BUILD_NITRO, DIR_BUILD_NUXT, DIR_CLIENT_GRAPHQL, DIR_EXTERNAL, DIR_ROUTES_GRAPHQL, DIR_SERVER_GRAPHQL, DIR_SERVER_GRAPHQL_WIN, DefineDirectiveConfig, DefineFunction, DirectiveArgument, DirectiveDefinition, DirectiveFileRef, DirectiveParser, DirectiveWrapper, ENDPOINT_DEBUG, ENDPOINT_GRAPHQL, ENDPOINT_HEALTH, ExternalServiceCodegenConfig, FEDERATION_EXTERNALS, FILE_CLIENT_TYPES, FILE_CONFIG_TS, FILE_CONTEXT_DTS, FILE_CONTEXT_TS, FILE_DIRECTIVES_GRAPHQL, FILE_GRAPHQL_CONFIG, FILE_GRAPHQL_DTS, FILE_INDEX_TS, FILE_OFETCH_TS, FILE_SCHEMA_GRAPHQL, FILE_SCHEMA_TS, FILE_SDK_TS, FILE_SERVER_TYPES, FRAMEWORK_NITRO, FRAMEWORK_NUXT, FRAMEWORK_STANDALONE, Flatten, Framework, GENERATED_FILE_HEADER, GLOB_SCAN_PATTERN, GRAPHQL_EXTENSIONS, GRAPHQL_FRAMEWORK_APOLLO, GRAPHQL_FRAMEWORK_YOGA, GRAPHQL_GLOB_PATTERN, GRAPHQL_HTTP_METHODS, GraphQLArgumentType, GraphQLBaseType, GraphQLFramework, GraphQLLoadSchemaOptions, GraphQLScalarType, GraphQLTypeDefPointer, HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_INTERNAL_ERROR, LOG_TAG, MaskErrorOptions, ModuleConfig, OfetchTemplateOptions, PATTERN_CLIENT_EXTERNAL_TYPES, PLACEHOLDER_BUILD_DIR, PLACEHOLDER_CLIENT_DIR, PLACEHOLDER_FRAMEWORK, PLACEHOLDER_ROOT_DIR, PLACEHOLDER_SERVER_DIR, PLACEHOLDER_SERVICE_NAME, PLACEHOLDER_TYPES_DIR, PackageConfig, ParsedDirective, RESOLVER_EXTENSIONS, RESOLVER_GLOB_PATTERN, RESOLVER_TYPE_DIRECTIVE, RESOLVER_TYPE_MUTATION, RESOLVER_TYPE_QUERY, RESOLVER_TYPE_RESOLVER, RESOLVER_TYPE_SUBSCRIPTION, RESOLVER_TYPE_TYPE, ResolvedExtend, ResolvedPackage, ResolverDefinition, ResolverImport, ResolverType, SERVICE_DEFAULT, ScalarType, ScanContext, ScanDocumentsOptions, ScanResult, ScannedFile, ScannedResolver, SchemaDefinition, SchemaLoadOptions, SdkCodegenConfig, ServerCodegenConfig, ServerCodegenInput, ServerCodegenResult, SubscriptionInfo, buildGraphQLSchema, createCoreConfig, createCoreContext, createDefaultMaskError, createLogger, createMergedSchema, createScanContext, createSilentLogger, deduplicateFiles, defaultLogger, directiveParser, downloadAndSaveSchema, ensureDir, extractPaths, extractSubscriptions, filterByExtension, generateClientTypesCore, generateDirectiveSchema, generateDirectiveSchemas, generateExternalClientTypesCore, generateOfetchTemplate, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateSubscriptionBuilder, generateTypes, getImportId, graphQLLoadSchemaSync, isLocalPath, loadExternalSchema, loadFederationSupport, loadGraphQLDocuments, loadPackageConfig, mergeGraphQLOptions, parse, parseDirectiveCall, parseResolverCall, parseSingleFile, pluginContent, readFileSafe, relativeWithDot, resetFederationCache, resolvePackageFiles, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST, subscribe, validate, validateExternalServices, validateNoDuplicateTypes, validateSchemaFiles, warnFederationUnavailable, writeFile, writeFileIfChanged };
@@ -3,7 +3,7 @@ import { GENERATED_FILE_HEADER, pluginContent } from "./codegen/plugin.mjs";
3
3
  import { loadGraphQLDocuments } from "./codegen/document-loader.mjs";
4
4
  import { ensureDir, readFileSafe, writeFile, writeFileIfChanged } from "./utils/file-io.mjs";
5
5
  import { downloadAndSaveSchema, graphQLLoadSchemaSync, loadExternalSchema } from "./codegen/schema-loader.mjs";
6
- import { DEFAULT_CLIENT_CODEGEN_CONFIG, generateClientTypesCore, generateExternalClientTypesCore } from "./codegen/client.mjs";
6
+ import { DEFAULT_CLIENT_CODEGEN_CONFIG, extractSubscriptions, generateClientTypesCore, generateExternalClientTypesCore, generateSubscriptionBuilder } from "./codegen/client.mjs";
7
7
  import { generateResolverModule, generateRuntimeIndex, generateSchemaModule } from "./codegen/runtime.mjs";
8
8
  import { DEFAULT_SERVER_CODEGEN_CONFIG, generateServerTypesCore, generateTypes } from "./codegen/server.mjs";
9
9
  import { validateNoDuplicateTypes, validateSchemaFiles } from "./codegen/validation.mjs";
@@ -24,4 +24,4 @@ import { getImportId, relativeWithDot } from "./utils/imports.mjs";
24
24
  import { generateOfetchTemplate } from "./utils/ofetch-templates.mjs";
25
25
  import { validateExternalServices } from "./validation/external-services.mjs";
26
26
 
27
- export { BUILTIN_SCALARS, CHUNK_NAME_RESOLVERS, CHUNK_NAME_SCHEMAS, CHUNK_PATH_GRAPHQL, CHUNK_PATH_UNKNOWN, CODEGEN_EXTERNALS, DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_CLIENT_TYPES_PATH, DEFAULT_GRAPHQL_SCALARS, DEFAULT_SERVER_CODEGEN_CONFIG, DEFAULT_SERVER_TYPES_PATH, DEFINE_DIRECTIVE, DEFINE_FIELD, DEFINE_FUNCTIONS, DEFINE_GRAPHQL_CONFIG, DEFINE_MUTATION, DEFINE_QUERY, DEFINE_RESOLVER, DEFINE_SCHEMA, DEFINE_SUBSCRIPTION, DIRECTIVE_EXTENSIONS, DIRECTIVE_GLOB_PATTERN, DIR_APP_GRAPHQL, DIR_BUILD_NITRO, DIR_BUILD_NUXT, DIR_CLIENT_GRAPHQL, DIR_EXTERNAL, DIR_ROUTES_GRAPHQL, DIR_SERVER_GRAPHQL, DIR_SERVER_GRAPHQL_WIN, DirectiveParser, ENDPOINT_DEBUG, ENDPOINT_GRAPHQL, ENDPOINT_HEALTH, FEDERATION_EXTERNALS, FILE_CLIENT_TYPES, FILE_CONFIG_TS, FILE_CONTEXT_DTS, FILE_CONTEXT_TS, FILE_DIRECTIVES_GRAPHQL, FILE_GRAPHQL_CONFIG, FILE_GRAPHQL_DTS, FILE_INDEX_TS, FILE_OFETCH_TS, FILE_SCHEMA_GRAPHQL, FILE_SCHEMA_TS, FILE_SDK_TS, FILE_SERVER_TYPES, FRAMEWORK_NITRO, FRAMEWORK_NUXT, FRAMEWORK_STANDALONE, GENERATED_FILE_HEADER, GLOB_SCAN_PATTERN, GRAPHQL_EXTENSIONS, GRAPHQL_FRAMEWORK_APOLLO, GRAPHQL_FRAMEWORK_YOGA, GRAPHQL_GLOB_PATTERN, GRAPHQL_HTTP_METHODS, HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_INTERNAL_ERROR, LOG_TAG, PATTERN_CLIENT_EXTERNAL_TYPES, PLACEHOLDER_BUILD_DIR, PLACEHOLDER_CLIENT_DIR, PLACEHOLDER_FRAMEWORK, PLACEHOLDER_ROOT_DIR, PLACEHOLDER_SERVER_DIR, PLACEHOLDER_SERVICE_NAME, PLACEHOLDER_TYPES_DIR, RESOLVER_EXTENSIONS, RESOLVER_GLOB_PATTERN, RESOLVER_TYPE_DIRECTIVE, RESOLVER_TYPE_MUTATION, RESOLVER_TYPE_QUERY, RESOLVER_TYPE_RESOLVER, RESOLVER_TYPE_SUBSCRIPTION, RESOLVER_TYPE_TYPE, SERVICE_DEFAULT, buildGraphQLSchema, createCoreConfig, createCoreContext, createDefaultMaskError, createLogger, createMergedSchema, createScanContext, createSilentLogger, deduplicateFiles, defaultLogger, directiveParser, downloadAndSaveSchema, ensureDir, extractPaths, filterByExtension, generateClientTypesCore, generateDirectiveSchema, generateDirectiveSchemas, generateExternalClientTypesCore, generateOfetchTemplate, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateTypes, getImportId, graphQLLoadSchemaSync, isLocalPath, loadExternalSchema, loadFederationSupport, loadGraphQLDocuments, loadPackageConfig, mergeGraphQLOptions, parse, parseDirectiveCall, parseResolverCall, parseSingleFile, pluginContent, readFileSafe, relativeWithDot, resetFederationCache, resolvePackageFiles, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST, subscribe, validate, validateExternalServices, validateNoDuplicateTypes, validateSchemaFiles, warnFederationUnavailable, writeFile, writeFileIfChanged };
27
+ export { BUILTIN_SCALARS, CHUNK_NAME_RESOLVERS, CHUNK_NAME_SCHEMAS, CHUNK_PATH_GRAPHQL, CHUNK_PATH_UNKNOWN, CODEGEN_EXTERNALS, DEFAULT_CLIENT_CODEGEN_CONFIG, DEFAULT_CLIENT_TYPES_PATH, DEFAULT_GRAPHQL_SCALARS, DEFAULT_SERVER_CODEGEN_CONFIG, DEFAULT_SERVER_TYPES_PATH, DEFINE_DIRECTIVE, DEFINE_FIELD, DEFINE_FUNCTIONS, DEFINE_GRAPHQL_CONFIG, DEFINE_MUTATION, DEFINE_QUERY, DEFINE_RESOLVER, DEFINE_SCHEMA, DEFINE_SUBSCRIPTION, DIRECTIVE_EXTENSIONS, DIRECTIVE_GLOB_PATTERN, DIR_APP_GRAPHQL, DIR_BUILD_NITRO, DIR_BUILD_NUXT, DIR_CLIENT_GRAPHQL, DIR_EXTERNAL, DIR_ROUTES_GRAPHQL, DIR_SERVER_GRAPHQL, DIR_SERVER_GRAPHQL_WIN, DirectiveParser, ENDPOINT_DEBUG, ENDPOINT_GRAPHQL, ENDPOINT_HEALTH, FEDERATION_EXTERNALS, FILE_CLIENT_TYPES, FILE_CONFIG_TS, FILE_CONTEXT_DTS, FILE_CONTEXT_TS, FILE_DIRECTIVES_GRAPHQL, FILE_GRAPHQL_CONFIG, FILE_GRAPHQL_DTS, FILE_INDEX_TS, FILE_OFETCH_TS, FILE_SCHEMA_GRAPHQL, FILE_SCHEMA_TS, FILE_SDK_TS, FILE_SERVER_TYPES, FRAMEWORK_NITRO, FRAMEWORK_NUXT, FRAMEWORK_STANDALONE, GENERATED_FILE_HEADER, GLOB_SCAN_PATTERN, GRAPHQL_EXTENSIONS, GRAPHQL_FRAMEWORK_APOLLO, GRAPHQL_FRAMEWORK_YOGA, GRAPHQL_GLOB_PATTERN, GRAPHQL_HTTP_METHODS, HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_INTERNAL_ERROR, LOG_TAG, PATTERN_CLIENT_EXTERNAL_TYPES, PLACEHOLDER_BUILD_DIR, PLACEHOLDER_CLIENT_DIR, PLACEHOLDER_FRAMEWORK, PLACEHOLDER_ROOT_DIR, PLACEHOLDER_SERVER_DIR, PLACEHOLDER_SERVICE_NAME, PLACEHOLDER_TYPES_DIR, RESOLVER_EXTENSIONS, RESOLVER_GLOB_PATTERN, RESOLVER_TYPE_DIRECTIVE, RESOLVER_TYPE_MUTATION, RESOLVER_TYPE_QUERY, RESOLVER_TYPE_RESOLVER, RESOLVER_TYPE_SUBSCRIPTION, RESOLVER_TYPE_TYPE, SERVICE_DEFAULT, buildGraphQLSchema, createCoreConfig, createCoreContext, createDefaultMaskError, createLogger, createMergedSchema, createScanContext, createSilentLogger, deduplicateFiles, defaultLogger, directiveParser, downloadAndSaveSchema, ensureDir, extractPaths, extractSubscriptions, filterByExtension, generateClientTypesCore, generateDirectiveSchema, generateDirectiveSchemas, generateExternalClientTypesCore, generateOfetchTemplate, generateResolverModule, generateRuntimeIndex, generateSchemaModule, generateServerTypesCore, generateSubscriptionBuilder, generateTypes, getImportId, graphQLLoadSchemaSync, isLocalPath, loadExternalSchema, loadFederationSupport, loadGraphQLDocuments, loadPackageConfig, mergeGraphQLOptions, parse, parseDirectiveCall, parseResolverCall, parseSingleFile, pluginContent, readFileSafe, relativeWithDot, resetFederationCache, resolvePackageFiles, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST, subscribe, validate, validateExternalServices, validateNoDuplicateTypes, validateSchemaFiles, warnFederationUnavailable, writeFile, writeFileIfChanged };
@@ -1,7 +1,7 @@
1
1
  //#region src/core/pubsub/index.d.ts
2
2
  /**
3
3
  * Built-in PubSub implementation for GraphQL Subscriptions
4
- * Simple EventTarget-based implementation for single-instance deployments
4
+ * Simple EventEmitter-based implementation for single-instance deployments
5
5
  *
6
6
  * For multi-instance deployments, use external PubSub solutions like:
7
7
  * - Redis (with ioredis)
@@ -34,7 +34,7 @@ type TypedPubSub<Topics extends Record<string, unknown>> = PubSubEngine<Topics>;
34
34
  /**
35
35
  * Create a simple in-memory PubSub instance
36
36
  *
37
- * This implementation uses EventTarget for lightweight pub/sub functionality.
37
+ * This implementation uses EventEmitter for lightweight pub/sub functionality.
38
38
  * Suitable for:
39
39
  * - Development environments
40
40
  * - Single-instance production deployments
@@ -1,8 +1,20 @@
1
+ import { EventEmitter } from "node:events";
2
+
1
3
  //#region src/core/pubsub/index.ts
2
4
  /**
5
+ * Built-in PubSub implementation for GraphQL Subscriptions
6
+ * Simple EventEmitter-based implementation for single-instance deployments
7
+ *
8
+ * For multi-instance deployments, use external PubSub solutions like:
9
+ * - Redis (with ioredis)
10
+ * - Kafka
11
+ * - RabbitMQ
12
+ * - Cloud Pub/Sub services
13
+ */
14
+ /**
3
15
  * Create a simple in-memory PubSub instance
4
16
  *
5
- * This implementation uses EventTarget for lightweight pub/sub functionality.
17
+ * This implementation uses EventEmitter for lightweight pub/sub functionality.
6
18
  * Suitable for:
7
19
  * - Development environments
8
20
  * - Single-instance production deployments
@@ -37,11 +49,11 @@
37
49
  * ```
38
50
  */
39
51
  function createPubSub() {
40
- const eventTarget = new EventTarget();
52
+ const emitter = new EventEmitter();
53
+ emitter.setMaxListeners(0);
41
54
  return {
42
55
  async publish(topic, payload) {
43
- const event = new CustomEvent(String(topic), { detail: payload });
44
- eventTarget.dispatchEvent(event);
56
+ emitter.emit(String(topic), payload);
45
57
  },
46
58
  subscribe(topic) {
47
59
  const topicStr = String(topic);
@@ -49,8 +61,7 @@ function createPubSub() {
49
61
  const queue = [];
50
62
  let resolve = null;
51
63
  let done = false;
52
- const listener = (event) => {
53
- const payload = event.detail;
64
+ const listener = (payload) => {
54
65
  if (resolve) {
55
66
  resolve({
56
67
  value: payload,
@@ -59,7 +70,7 @@ function createPubSub() {
59
70
  resolve = null;
60
71
  } else queue.push(payload);
61
72
  };
62
- eventTarget.addEventListener(topicStr, listener);
73
+ emitter.on(topicStr, listener);
63
74
  return {
64
75
  next() {
65
76
  if (done) return Promise.resolve({
@@ -76,7 +87,7 @@ function createPubSub() {
76
87
  },
77
88
  return() {
78
89
  done = true;
79
- eventTarget.removeEventListener(topicStr, listener);
90
+ emitter.off(topicStr, listener);
80
91
  return Promise.resolve({
81
92
  value: void 0,
82
93
  done: true
@@ -84,7 +95,7 @@ function createPubSub() {
84
95
  },
85
96
  throw(error) {
86
97
  done = true;
87
- eventTarget.removeEventListener(topicStr, listener);
98
+ emitter.off(topicStr, listener);
88
99
  return Promise.reject(error);
89
100
  }
90
101
  };
@@ -0,0 +1,8 @@
1
+ //#region src/core/utils/subscribe-templates.d.ts
2
+ /**
3
+ * Template for GraphQL subscription client config
4
+ * Small config file that users can customize (like ofetch.ts pattern)
5
+ */
6
+ declare const subscribeClientTemplate = "// This file is auto-generated once by nitro-graphql for quick start\n// You can modify this file to customize the subscription client\n// The implementation comes from nitro-graphql/subscribe - you'll get updates automatically!\n//\n// Usage Examples:\n// ---------------\n// Basic subscription:\n// subscriptionClient.subscribe(query, variables, onData, onError)\n//\n// Multiplexed subscriptions (shared connection):\n// const session = subscriptionClient.createSession()\n// session.subscribe(query1, vars1, onData1)\n// session.subscribe(query2, vars2, onData2)\n//\n// With authentication:\n// Edit connectionParams below to add auth headers\n\nimport type {\n ConnectionState,\n SubscriptionClient,\n SubscriptionClientConfig,\n SubscriptionHandle,\n SubscriptionSession,\n} from 'nitro-graphql/subscribe'\nimport { createSubscriptionClient } from 'nitro-graphql/subscribe'\n\n// Re-export types for convenience\nexport type { ConnectionState, SubscriptionClient, SubscriptionHandle, SubscriptionSession }\n\n// Configure the subscription client\n// Customize these settings according to your needs\nconst config: SubscriptionClientConfig = {\n // WebSocket endpoint (default: '/api/graphql/ws')\n wsEndpoint: '/api/graphql/ws',\n\n // Connection timeout in ms (default: 10000)\n connectionTimeoutMs: 10000,\n\n // Max reconnection attempts (default: 5)\n maxRetries: 5,\n\n // Authentication params sent with connection_init\n // Can be a function for dynamic values (e.g., JWT tokens)\n // connectionParams: () => ({\n // authorization: `Bearer ${getToken()}`,\n // }),\n}\n\n// Export configured client instance\nexport const subscriptionClient = createSubscriptionClient(config)\n";
7
+ //#endregion
8
+ export { subscribeClientTemplate };