nitro-graphql 2.0.0-beta.70 → 2.0.0-beta.73

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.
Files changed (228) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/adapter.d.mts +0 -3
  3. package/dist/cli/adapter.mjs +7 -32
  4. package/dist/cli/commands/build.d.mts +2 -2
  5. package/dist/cli/commands/build.mjs +1 -3
  6. package/dist/cli/commands/dev.d.mts +2 -2
  7. package/dist/cli/commands/dev.mjs +1 -3
  8. package/dist/cli/commands/generate.mjs +10 -10
  9. package/dist/cli/commands/init.mjs +4 -4
  10. package/dist/cli/commands/validate.mjs +1 -3
  11. package/dist/cli/completions.mjs +1 -3
  12. package/dist/cli/config.d.mts +4 -5
  13. package/dist/cli/config.mjs +4 -3
  14. package/dist/cli/index.d.mts +3 -6
  15. package/dist/cli/index.mjs +2 -4
  16. package/dist/cli/server/debug-handler.mjs +2 -5
  17. package/dist/cli/server/dev-server.mjs +1 -3
  18. package/dist/cli/server/graphql-handler.mjs +3 -4
  19. package/dist/cli/server/health-handler.mjs +1 -2
  20. package/dist/cli/server/loader.mjs +1 -3
  21. package/dist/cli/server/sandbox-handler.mjs +1 -3
  22. package/dist/cli/server/watcher.mjs +2 -4
  23. package/dist/cli/server/ws-handler.mjs +1 -3
  24. package/dist/config.mjs +1 -2
  25. package/dist/core/codegen/client.d.mts +4 -27
  26. package/dist/core/codegen/client.mjs +26 -447
  27. package/dist/core/codegen/document-loader.mjs +1 -3
  28. package/dist/core/codegen/file-header.d.mts +7 -0
  29. package/dist/core/codegen/file-header.mjs +12 -0
  30. package/dist/core/codegen/index.d.mts +7 -5
  31. package/dist/core/codegen/index.mjs +7 -6
  32. package/dist/core/codegen/{runtime.d.mts → runtime-generator.d.mts} +1 -3
  33. package/dist/core/codegen/{runtime.mjs → runtime-generator.mjs} +7 -6
  34. package/dist/core/codegen/schema-loader.d.mts +2 -7
  35. package/dist/core/codegen/schema-loader.mjs +66 -73
  36. package/dist/core/codegen/server-type-helpers.d.mts +14 -0
  37. package/dist/core/codegen/server-type-helpers.mjs +76 -0
  38. package/dist/core/codegen/server.d.mts +1 -15
  39. package/dist/core/codegen/server.mjs +15 -107
  40. package/dist/core/codegen/subscription-extractor.d.mts +20 -0
  41. package/dist/core/codegen/subscription-extractor.mjs +30 -0
  42. package/dist/core/codegen/validation.mjs +1 -3
  43. package/dist/core/codegen/vue-subscription-builder.d.mts +10 -0
  44. package/dist/core/codegen/vue-subscription-builder.mjs +351 -0
  45. package/dist/core/constants.d.mts +5 -53
  46. package/dist/core/constants.mjs +13 -56
  47. package/dist/core/create-config.d.mts +31 -0
  48. package/dist/core/create-config.mjs +42 -0
  49. package/dist/core/debug/index.d.mts +2 -2
  50. package/dist/core/debug/index.mjs +2 -3
  51. package/dist/core/debug/template.d.mts +1 -5
  52. package/dist/core/debug/template.mjs +5 -4
  53. package/dist/core/extend/index.mjs +1 -2
  54. package/dist/core/extend/loader.d.mts +0 -1
  55. package/dist/core/extend/loader.mjs +60 -92
  56. package/dist/core/index.d.mts +22 -21
  57. package/dist/core/index.mjs +19 -16
  58. package/dist/core/manifest.mjs +4 -4
  59. package/dist/core/pubsub/index.d.mts +2 -109
  60. package/dist/core/pubsub/index.mjs +2 -148
  61. package/dist/core/pubsub/memory-pubsub.d.mts +109 -0
  62. package/dist/core/pubsub/memory-pubsub.mjs +146 -0
  63. package/dist/core/scanning/ast-scanner.mjs +5 -5
  64. package/dist/core/scanning/directives.mjs +3 -5
  65. package/dist/core/scanning/documents.d.mts +4 -3
  66. package/dist/core/scanning/documents.mjs +4 -5
  67. package/dist/core/scanning/{common.d.mts → file-scanner.d.mts} +1 -1
  68. package/dist/core/scanning/{common.mjs → file-scanner.mjs} +3 -13
  69. package/dist/core/scanning/index.d.mts +3 -3
  70. package/dist/core/scanning/index.mjs +3 -4
  71. package/dist/core/scanning/resolvers.mjs +9 -11
  72. package/dist/core/scanning/schemas.d.mts +1 -5
  73. package/dist/core/scanning/schemas.mjs +2 -26
  74. package/dist/core/schema/builder.d.mts +4 -2
  75. package/dist/core/schema/builder.mjs +4 -4
  76. package/dist/core/schema/federation.mjs +1 -3
  77. package/dist/core/schema/index.d.mts +2 -2
  78. package/dist/core/schema/index.mjs +2 -3
  79. package/dist/core/server/apollo.d.mts +20 -0
  80. package/dist/core/server/apollo.mjs +54 -0
  81. package/dist/core/server/index.d.mts +4 -2
  82. package/dist/core/server/index.mjs +3 -3
  83. package/dist/core/server/sandbox.mjs +1 -2
  84. package/dist/core/server/types.d.mts +7 -14
  85. package/dist/core/server/types.mjs +15 -1
  86. package/dist/core/server/yoga.d.mts +1 -7
  87. package/dist/core/server/yoga.mjs +4 -15
  88. package/dist/core/types/adapter.d.mts +3 -40
  89. package/dist/core/types/adapter.mjs +1 -1
  90. package/dist/core/types/codegen.d.mts +22 -45
  91. package/dist/core/types/codegen.mjs +1 -1
  92. package/dist/core/types/config.d.mts +33 -121
  93. package/dist/core/types/config.mjs +1 -1
  94. package/dist/core/types/define.d.mts +8 -5
  95. package/dist/core/types/define.mjs +1 -1
  96. package/dist/core/types/index.d.mts +5 -4
  97. package/dist/core/types/index.mjs +1 -1
  98. package/dist/core/types/scanning.d.mts +4 -1
  99. package/dist/core/types/scanning.mjs +1 -1
  100. package/dist/core/types/standard-schema.d.mts +64 -0
  101. package/dist/core/types/standard-schema.mjs +1 -0
  102. package/dist/core/utils/directive-parser.d.mts +8 -63
  103. package/dist/core/utils/directive-parser.mjs +114 -167
  104. package/dist/core/utils/errors.mjs +1 -3
  105. package/dist/core/utils/file-io.d.mts +1 -5
  106. package/dist/core/utils/file-io.mjs +1 -13
  107. package/dist/core/utils/imports.mjs +3 -4
  108. package/dist/core/utils/index.d.mts +5 -4
  109. package/dist/core/utils/index.mjs +6 -6
  110. package/dist/core/utils/logger.d.mts +1 -10
  111. package/dist/core/utils/logger.mjs +1 -21
  112. package/dist/core/utils/ofetch-templates.mjs +4 -6
  113. package/dist/core/utils/runtime.d.mts +1 -30
  114. package/dist/core/utils/runtime.mjs +2 -46
  115. package/dist/core/utils/string.d.mts +10 -0
  116. package/dist/core/utils/string.mjs +12 -0
  117. package/dist/core/utils/subscribe-templates.mjs +1 -2
  118. package/dist/core/validation/external-services.mjs +3 -3
  119. package/dist/core/validation/index.mjs +1 -2
  120. package/dist/core/watcher/create-watcher.d.mts +103 -0
  121. package/dist/core/watcher/create-watcher.mjs +143 -0
  122. package/dist/core/watcher/index.d.mts +2 -107
  123. package/dist/core/watcher/index.mjs +2 -141
  124. package/dist/define.d.mts +4 -2
  125. package/dist/define.mjs +8 -9
  126. package/dist/index.d.mts +4 -3
  127. package/dist/index.mjs +3 -4
  128. package/dist/nitro/adapter.d.mts +6 -11
  129. package/dist/nitro/adapter.mjs +12 -45
  130. package/dist/nitro/apollo.mjs +1 -3
  131. package/dist/nitro/codegen/client-types.d.mts +12 -0
  132. package/dist/nitro/codegen/client-types.mjs +73 -0
  133. package/dist/nitro/codegen/external-types.d.mts +8 -0
  134. package/dist/nitro/codegen/external-types.mjs +47 -0
  135. package/dist/nitro/codegen/index.d.mts +4 -0
  136. package/dist/nitro/codegen/index.mjs +4 -0
  137. package/dist/nitro/codegen/server-types.d.mts +12 -0
  138. package/dist/nitro/codegen/server-types.mjs +81 -0
  139. package/dist/nitro/defaults.d.mts +28 -0
  140. package/dist/nitro/defaults.mjs +34 -0
  141. package/dist/nitro/index.d.mts +11 -3
  142. package/dist/nitro/index.mjs +4 -6
  143. package/dist/nitro/paths.d.mts +3 -2
  144. package/dist/nitro/paths.mjs +14 -5
  145. package/dist/nitro/rollup.mjs +8 -8
  146. package/dist/nitro/routes/_ws-handler.d.mts +6 -0
  147. package/dist/nitro/routes/_ws-handler.mjs +49 -0
  148. package/dist/nitro/routes/apollo-sandbox-script.d.mts +2 -2
  149. package/dist/nitro/routes/apollo-sandbox-script.mjs +1 -3
  150. package/dist/nitro/routes/apollo-server-ws.d.mts +1 -1
  151. package/dist/nitro/routes/apollo-server-ws.mjs +10 -48
  152. package/dist/nitro/routes/apollo-server.d.mts +2 -2
  153. package/dist/nitro/routes/apollo-server.mjs +17 -58
  154. package/dist/nitro/routes/debug.d.mts +2 -2
  155. package/dist/nitro/routes/debug.mjs +4 -7
  156. package/dist/nitro/routes/graphql-yoga-ws.d.mts +3 -3
  157. package/dist/nitro/routes/graphql-yoga-ws.mjs +7 -48
  158. package/dist/nitro/routes/graphql-yoga.d.mts +2 -2
  159. package/dist/nitro/routes/graphql-yoga.mjs +8 -8
  160. package/dist/nitro/routes/health.d.mts +2 -2
  161. package/dist/nitro/routes/health.mjs +23 -27
  162. package/dist/nitro/setup/extend-loader.d.mts +6 -5
  163. package/dist/nitro/setup/extend-loader.mjs +31 -61
  164. package/dist/nitro/setup/file-watcher.mjs +9 -8
  165. package/dist/nitro/setup/logging.d.mts +1 -8
  166. package/dist/nitro/setup/logging.mjs +7 -24
  167. package/dist/nitro/setup/rollup-integration.mjs +36 -4
  168. package/dist/nitro/setup/routes.mjs +1 -3
  169. package/dist/nitro/setup/scanner.d.mts +8 -43
  170. package/dist/nitro/setup/scanner.mjs +56 -60
  171. package/dist/nitro/setup/security.d.mts +10 -0
  172. package/dist/nitro/setup/security.mjs +17 -0
  173. package/dist/nitro/setup/ts-config.mjs +1 -3
  174. package/dist/nitro/setup/type-generation.d.mts +13 -0
  175. package/dist/nitro/setup/type-generation.mjs +16 -0
  176. package/dist/nitro/setup.d.mts +4 -3
  177. package/dist/nitro/setup.mjs +88 -77
  178. package/dist/nitro/state.d.mts +32 -0
  179. package/dist/nitro/state.mjs +58 -0
  180. package/dist/nitro/types/augmentation.d.mts +59 -0
  181. package/dist/nitro/types/augmentation.mjs +1 -0
  182. package/dist/nitro/types/config.d.mts +327 -0
  183. package/dist/nitro/types/config.mjs +1 -0
  184. package/dist/nitro/types/define.d.mts +13 -0
  185. package/dist/nitro/types/define.mjs +1 -0
  186. package/dist/nitro/types/index.d.mts +10 -0
  187. package/dist/nitro/types/index.mjs +1 -0
  188. package/dist/nitro/virtual/debug-info.d.mts +9 -0
  189. package/dist/nitro/virtual/debug-info.mjs +35 -0
  190. package/dist/nitro/virtual/graphql-config.d.mts +9 -0
  191. package/dist/nitro/virtual/graphql-config.mjs +33 -0
  192. package/dist/nitro/virtual/index.d.mts +25 -0
  193. package/dist/nitro/virtual/index.mjs +45 -0
  194. package/dist/nitro/virtual/module-config.d.mts +9 -0
  195. package/dist/nitro/virtual/module-config.mjs +10 -0
  196. package/dist/nitro/virtual/pubsub.d.mts +9 -0
  197. package/dist/nitro/virtual/pubsub.mjs +17 -0
  198. package/dist/nitro/virtual/server-directives.d.mts +9 -0
  199. package/dist/nitro/virtual/server-directives.mjs +12 -0
  200. package/dist/nitro/virtual/server-resolvers.d.mts +9 -0
  201. package/dist/nitro/virtual/server-resolvers.mjs +17 -0
  202. package/dist/nitro/virtual/server-schemas.d.mts +9 -0
  203. package/dist/nitro/virtual/server-schemas.mjs +31 -0
  204. package/dist/nitro/virtual/stubs.d.mts +42 -10
  205. package/dist/nitro/virtual/stubs.mjs +1 -7
  206. package/dist/nitro/virtual/utils.d.mts +15 -0
  207. package/dist/nitro/virtual/utils.mjs +26 -0
  208. package/dist/nitro/virtual/validation-schemas.d.mts +9 -0
  209. package/dist/nitro/virtual/validation-schemas.mjs +33 -0
  210. package/dist/nuxt.mjs +4 -5
  211. package/dist/stubs/index.mjs +1 -1
  212. package/dist/subscribe/index.mjs +3 -4
  213. package/native/index.js +52 -52
  214. package/package.json +41 -41
  215. package/dist/cli/commands/index.d.mts +0 -5
  216. package/dist/cli/commands/index.mjs +0 -6
  217. package/dist/core/codegen/plugin.d.mts +0 -19
  218. package/dist/core/codegen/plugin.mjs +0 -30
  219. package/dist/core/config.d.mts +0 -45
  220. package/dist/core/config.mjs +0 -78
  221. package/dist/nitro/codegen.d.mts +0 -18
  222. package/dist/nitro/codegen.mjs +0 -173
  223. package/dist/nitro/config.d.mts +0 -50
  224. package/dist/nitro/config.mjs +0 -57
  225. package/dist/nitro/types.d.mts +0 -549
  226. package/dist/nitro/types.mjs +0 -1
  227. package/dist/nitro/virtual/generators.d.mts +0 -38
  228. package/dist/nitro/virtual/generators.mjs +0 -192
@@ -1,148 +1,2 @@
1
- import { EventEmitter } from "node:events";
2
-
3
- //#region src/core/pubsub/index.ts
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
- /**
15
- * Create a simple in-memory PubSub instance
16
- *
17
- * This implementation uses EventEmitter for lightweight pub/sub functionality.
18
- * Suitable for:
19
- * - Development environments
20
- * - Single-instance production deployments
21
- * - Testing
22
- *
23
- * NOT suitable for:
24
- * - Multi-instance/clustered deployments (events won't propagate across instances)
25
- * - High-throughput scenarios (consider Redis-based PubSub)
26
- *
27
- * @example
28
- * ```typescript
29
- * // Define your topic types
30
- * interface MyTopics {
31
- * 'user:created': { id: string; name: string }
32
- * 'message:sent': { channelId: string; content: string }
33
- * }
34
- *
35
- * // Create typed PubSub instance
36
- * const pubsub = createPubSub<MyTopics>()
37
- *
38
- * // Publish events
39
- * await pubsub.publish('user:created', { id: '123', name: 'John' })
40
- *
41
- * // Subscribe to events (in a resolver)
42
- * export const userSubscriptions = defineSubscription({
43
- * userCreated: {
44
- * subscribe: async function* () {
45
- * yield* pubsub.subscribe('user:created')
46
- * }
47
- * }
48
- * })
49
- * ```
50
- */
51
- function createPubSub() {
52
- const emitter = new EventEmitter();
53
- emitter.setMaxListeners(0);
54
- return {
55
- async publish(topic, payload) {
56
- emitter.emit(String(topic), payload);
57
- },
58
- subscribe(topic) {
59
- const topicStr = String(topic);
60
- return { [Symbol.asyncIterator]() {
61
- const queue = [];
62
- let resolve = null;
63
- let done = false;
64
- const listener = (payload) => {
65
- if (resolve) {
66
- resolve({
67
- value: payload,
68
- done: false
69
- });
70
- resolve = null;
71
- } else queue.push(payload);
72
- };
73
- emitter.on(topicStr, listener);
74
- return {
75
- next() {
76
- if (done) return Promise.resolve({
77
- value: void 0,
78
- done: true
79
- });
80
- if (queue.length > 0) return Promise.resolve({
81
- value: queue.shift(),
82
- done: false
83
- });
84
- return new Promise((r) => {
85
- resolve = r;
86
- });
87
- },
88
- return() {
89
- done = true;
90
- emitter.off(topicStr, listener);
91
- return Promise.resolve({
92
- value: void 0,
93
- done: true
94
- });
95
- },
96
- throw(error) {
97
- done = true;
98
- emitter.off(topicStr, listener);
99
- return Promise.reject(error);
100
- }
101
- };
102
- } };
103
- }
104
- };
105
- }
106
- /**
107
- * Filter subscription events based on a predicate
108
- *
109
- * @example
110
- * ```typescript
111
- * export const chatSubscriptions = defineSubscription({
112
- * messageAdded: {
113
- * subscribe: async function* (_, { channelId }) {
114
- * yield* withFilter(
115
- * pubsub.subscribe('message:added'),
116
- * (message) => message.channelId === channelId
117
- * )
118
- * }
119
- * }
120
- * })
121
- * ```
122
- */
123
- async function* withFilter(asyncIterable, filter) {
124
- for await (const value of asyncIterable) if (await filter(value)) yield value;
125
- }
126
- /**
127
- * Map subscription events to a different shape
128
- *
129
- * @example
130
- * ```typescript
131
- * export const chatSubscriptions = defineSubscription({
132
- * messageAdded: {
133
- * subscribe: async function* () {
134
- * yield* mapAsyncIterator(
135
- * pubsub.subscribe('message:added'),
136
- * (event) => ({ messageAdded: event.message })
137
- * )
138
- * }
139
- * }
140
- * })
141
- * ```
142
- */
143
- async function* mapAsyncIterator(asyncIterable, mapper) {
144
- for await (const value of asyncIterable) yield await mapper(value);
145
- }
146
-
147
- //#endregion
148
- export { createPubSub, mapAsyncIterator, withFilter };
1
+ import { createPubSub, mapAsyncIterator, withFilter } from "./memory-pubsub.mjs";
2
+ export { createPubSub, mapAsyncIterator, withFilter };
@@ -0,0 +1,109 @@
1
+ //#region src/core/pubsub/memory-pubsub.d.ts
2
+ /**
3
+ * Built-in PubSub implementation for GraphQL Subscriptions
4
+ * Simple EventEmitter-based implementation for single-instance deployments
5
+ *
6
+ * For multi-instance deployments, use external PubSub solutions like:
7
+ * - Redis (with ioredis)
8
+ * - Kafka
9
+ * - RabbitMQ
10
+ * - Cloud Pub/Sub services
11
+ */
12
+ /**
13
+ * Generic PubSub engine interface
14
+ * Compatible with various PubSub implementations
15
+ */
16
+ interface PubSubEngine<Topics extends Record<string, unknown> = Record<string, unknown>> {
17
+ /**
18
+ * Publish an event to a topic
19
+ * @param topic - Topic name to publish to
20
+ * @param payload - Event payload
21
+ */
22
+ publish: <K extends keyof Topics>(topic: K, payload: Topics[K]) => Promise<void>;
23
+ /**
24
+ * Subscribe to a topic
25
+ * @param topic - Topic name to subscribe to
26
+ * @returns AsyncIterable that yields events
27
+ */
28
+ subscribe: <K extends keyof Topics>(topic: K) => AsyncIterable<Topics[K]>;
29
+ }
30
+ /**
31
+ * Type alias for typed PubSub instances
32
+ */
33
+ type TypedPubSub<Topics extends Record<string, unknown>> = PubSubEngine<Topics>;
34
+ /**
35
+ * Create a simple in-memory PubSub instance
36
+ *
37
+ * This implementation uses EventEmitter for lightweight pub/sub functionality.
38
+ * Suitable for:
39
+ * - Development environments
40
+ * - Single-instance production deployments
41
+ * - Testing
42
+ *
43
+ * NOT suitable for:
44
+ * - Multi-instance/clustered deployments (events won't propagate across instances)
45
+ * - High-throughput scenarios (consider Redis-based PubSub)
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Define your topic types
50
+ * interface MyTopics {
51
+ * 'user:created': { id: string; name: string }
52
+ * 'message:sent': { channelId: string; content: string }
53
+ * }
54
+ *
55
+ * // Create typed PubSub instance
56
+ * const pubsub = createPubSub<MyTopics>()
57
+ *
58
+ * // Publish events
59
+ * await pubsub.publish('user:created', { id: '123', name: 'John' })
60
+ *
61
+ * // Subscribe to events (in a resolver)
62
+ * export const userSubscriptions = defineSubscription({
63
+ * userCreated: {
64
+ * subscribe: async function* () {
65
+ * yield* pubsub.subscribe('user:created')
66
+ * }
67
+ * }
68
+ * })
69
+ * ```
70
+ */
71
+ declare function createPubSub<Topics extends Record<string, unknown> = Record<string, unknown>>(): PubSubEngine<Topics>;
72
+ /**
73
+ * Filter subscription events based on a predicate
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * export const chatSubscriptions = defineSubscription({
78
+ * messageAdded: {
79
+ * subscribe: async function* (_, { channelId }) {
80
+ * yield* withFilter(
81
+ * pubsub.subscribe('message:added'),
82
+ * (message) => message.channelId === channelId
83
+ * )
84
+ * }
85
+ * }
86
+ * })
87
+ * ```
88
+ */
89
+ declare function withFilter<T>(asyncIterable: AsyncIterable<T>, filter: (value: T) => boolean | Promise<boolean>): AsyncIterable<T>;
90
+ /**
91
+ * Map subscription events to a different shape
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * export const chatSubscriptions = defineSubscription({
96
+ * messageAdded: {
97
+ * subscribe: async function* () {
98
+ * yield* mapAsyncIterator(
99
+ * pubsub.subscribe('message:added'),
100
+ * (event) => ({ messageAdded: event.message })
101
+ * )
102
+ * }
103
+ * }
104
+ * })
105
+ * ```
106
+ */
107
+ declare function mapAsyncIterator<T, U>(asyncIterable: AsyncIterable<T>, mapper: (value: T) => U | Promise<U>): AsyncIterable<U>;
108
+ //#endregion
109
+ export { PubSubEngine, TypedPubSub, createPubSub, mapAsyncIterator, withFilter };
@@ -0,0 +1,146 @@
1
+ import { EventEmitter } from "node:events";
2
+ //#region src/core/pubsub/memory-pubsub.ts
3
+ /**
4
+ * Built-in PubSub implementation for GraphQL Subscriptions
5
+ * Simple EventEmitter-based implementation for single-instance deployments
6
+ *
7
+ * For multi-instance deployments, use external PubSub solutions like:
8
+ * - Redis (with ioredis)
9
+ * - Kafka
10
+ * - RabbitMQ
11
+ * - Cloud Pub/Sub services
12
+ */
13
+ /**
14
+ * Create a simple in-memory PubSub instance
15
+ *
16
+ * This implementation uses EventEmitter for lightweight pub/sub functionality.
17
+ * Suitable for:
18
+ * - Development environments
19
+ * - Single-instance production deployments
20
+ * - Testing
21
+ *
22
+ * NOT suitable for:
23
+ * - Multi-instance/clustered deployments (events won't propagate across instances)
24
+ * - High-throughput scenarios (consider Redis-based PubSub)
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Define your topic types
29
+ * interface MyTopics {
30
+ * 'user:created': { id: string; name: string }
31
+ * 'message:sent': { channelId: string; content: string }
32
+ * }
33
+ *
34
+ * // Create typed PubSub instance
35
+ * const pubsub = createPubSub<MyTopics>()
36
+ *
37
+ * // Publish events
38
+ * await pubsub.publish('user:created', { id: '123', name: 'John' })
39
+ *
40
+ * // Subscribe to events (in a resolver)
41
+ * export const userSubscriptions = defineSubscription({
42
+ * userCreated: {
43
+ * subscribe: async function* () {
44
+ * yield* pubsub.subscribe('user:created')
45
+ * }
46
+ * }
47
+ * })
48
+ * ```
49
+ */
50
+ function createPubSub() {
51
+ const emitter = new EventEmitter();
52
+ emitter.setMaxListeners(0);
53
+ return {
54
+ async publish(topic, payload) {
55
+ emitter.emit(String(topic), payload);
56
+ },
57
+ subscribe(topic) {
58
+ const topicStr = String(topic);
59
+ return { [Symbol.asyncIterator]() {
60
+ const queue = [];
61
+ let resolve = null;
62
+ let done = false;
63
+ const listener = (payload) => {
64
+ if (resolve) {
65
+ resolve({
66
+ value: payload,
67
+ done: false
68
+ });
69
+ resolve = null;
70
+ } else queue.push(payload);
71
+ };
72
+ emitter.on(topicStr, listener);
73
+ return {
74
+ next() {
75
+ if (done) return Promise.resolve({
76
+ value: void 0,
77
+ done: true
78
+ });
79
+ if (queue.length > 0) return Promise.resolve({
80
+ value: queue.shift(),
81
+ done: false
82
+ });
83
+ return new Promise((r) => {
84
+ resolve = r;
85
+ });
86
+ },
87
+ return() {
88
+ done = true;
89
+ emitter.off(topicStr, listener);
90
+ return Promise.resolve({
91
+ value: void 0,
92
+ done: true
93
+ });
94
+ },
95
+ throw(error) {
96
+ done = true;
97
+ emitter.off(topicStr, listener);
98
+ return Promise.reject(error);
99
+ }
100
+ };
101
+ } };
102
+ }
103
+ };
104
+ }
105
+ /**
106
+ * Filter subscription events based on a predicate
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * export const chatSubscriptions = defineSubscription({
111
+ * messageAdded: {
112
+ * subscribe: async function* (_, { channelId }) {
113
+ * yield* withFilter(
114
+ * pubsub.subscribe('message:added'),
115
+ * (message) => message.channelId === channelId
116
+ * )
117
+ * }
118
+ * }
119
+ * })
120
+ * ```
121
+ */
122
+ async function* withFilter(asyncIterable, filter) {
123
+ for await (const value of asyncIterable) if (await filter(value)) yield value;
124
+ }
125
+ /**
126
+ * Map subscription events to a different shape
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * export const chatSubscriptions = defineSubscription({
131
+ * messageAdded: {
132
+ * subscribe: async function* () {
133
+ * yield* mapAsyncIterator(
134
+ * pubsub.subscribe('message:added'),
135
+ * (event) => ({ messageAdded: event.message })
136
+ * )
137
+ * }
138
+ * }
139
+ * })
140
+ * ```
141
+ */
142
+ async function* mapAsyncIterator(asyncIterable, mapper) {
143
+ for await (const value of asyncIterable) yield await mapper(value);
144
+ }
145
+ //#endregion
146
+ export { createPubSub, mapAsyncIterator, withFilter };
@@ -1,8 +1,8 @@
1
- import { scanDirectory } from "./common.mjs";
1
+ import { scanDirectory } from "./file-scanner.mjs";
2
2
  import { readFile } from "node:fs/promises";
3
+ import consola from "consola";
3
4
  import { basename, relative } from "pathe";
4
5
  import { parseSync } from "oxc-parser";
5
-
6
6
  //#region src/core/scanning/ast-scanner.ts
7
7
  /**
8
8
  * Scan files matching a pattern and parse their exports using AST
@@ -67,7 +67,8 @@ async function parseSingleFile(filePath, parseCall) {
67
67
  });
68
68
  if (result.resolver.imports.length > 0) return result.resolver;
69
69
  return null;
70
- } catch {
70
+ } catch (error) {
71
+ consola.debug(`[nitro-graphql] Failed to parse file ${filePath}:`, error);
71
72
  return null;
72
73
  }
73
74
  }
@@ -111,6 +112,5 @@ function parseExports(filePath, program, config) {
111
112
  warnings
112
113
  };
113
114
  }
114
-
115
115
  //#endregion
116
- export { parseSingleFile, scanWithAST };
116
+ export { parseSingleFile, scanWithAST };
@@ -1,7 +1,6 @@
1
1
  import { DIRECTIVE_GLOB_PATTERN } from "../constants.mjs";
2
2
  import { scanWithAST } from "./ast-scanner.mjs";
3
- import { hash } from "ohash";
4
-
3
+ import { getImportId } from "../utils/imports.mjs";
5
4
  //#region src/core/scanning/directives.ts
6
5
  /**
7
6
  * Parse a defineDirective call and return the import info
@@ -11,7 +10,7 @@ function parseDirectiveCall(calleeName, exportName, filePath) {
11
10
  return {
12
11
  name: exportName,
13
12
  type: "directive",
14
- as: `_${hash(exportName + filePath).replace(/-/g, "").slice(0, 6)}`
13
+ as: getImportId(exportName + filePath)
15
14
  };
16
15
  }
17
16
  /**
@@ -24,6 +23,5 @@ function scanDirectivesCore(ctx) {
24
23
  emitWarnings: false
25
24
  });
26
25
  }
27
-
28
26
  //#endregion
29
- export { parseDirectiveCall, scanDirectivesCore };
27
+ export { parseDirectiveCall, scanDirectivesCore };
@@ -1,4 +1,3 @@
1
- import { CoreExternalService } from "../types/config.mjs";
2
1
  import { ScanContext, ScanResult } from "../types/scanning.mjs";
3
2
 
4
3
  //#region src/core/scanning/documents.d.ts
@@ -6,8 +5,10 @@ import { ScanContext, ScanResult } from "../types/scanning.mjs";
6
5
  * Options for scanning documents
7
6
  */
8
7
  interface ScanDocumentsOptions {
9
- /** External services to exclude from main scan */
10
- externalServices?: CoreExternalService[];
8
+ /** External services to exclude from main scan (only documents field is used) */
9
+ externalServices?: Array<{
10
+ documents?: string[];
11
+ }>;
11
12
  /** Client directory relative path */
12
13
  clientDirRelative?: string;
13
14
  }
@@ -1,8 +1,8 @@
1
1
  import { GRAPHQL_GLOB_PATTERN } from "../constants.mjs";
2
- import { scanDirectory } from "./common.mjs";
2
+ import { scanDirectory } from "./file-scanner.mjs";
3
3
  import { relative } from "pathe";
4
-
5
4
  //#region src/core/scanning/documents.ts
5
+ const REGEX_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
6
6
  /**
7
7
  * Scan for GraphQL client documents (.graphql, .gql) in client directory
8
8
  * Excludes files from external service directories
@@ -17,7 +17,7 @@ async function scanDocumentsCore(ctx, options = {}) {
17
17
  return {
18
18
  items: allFiles.filter((f) => !f.path.startsWith("external/")).filter((f) => {
19
19
  const relativePath = f.path;
20
- for (const pattern of externalPatterns) if (pattern.replace(new RegExp(`^${clientDirRelative.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/`), "").split("/")[0] === relativePath.split("/")[0]) return false;
20
+ for (const pattern of externalPatterns) if (pattern.replace(new RegExp(`^${clientDirRelative.replace(REGEX_SPECIAL_CHARS_RE, "\\$&")}/`), "").split("/")[0] === relativePath.split("/")[0]) return false;
21
21
  return true;
22
22
  }).map((f) => f.fullPath),
23
23
  warnings,
@@ -32,6 +32,5 @@ async function scanDocumentsCore(ctx, options = {}) {
32
32
  };
33
33
  }
34
34
  }
35
-
36
35
  //#endregion
37
- export { scanDocumentsCore };
36
+ export { scanDocumentsCore };
@@ -1,6 +1,6 @@
1
1
  import { ScanContext, ScannedFile } from "../types/scanning.mjs";
2
2
 
3
- //#region src/core/scanning/common.d.ts
3
+ //#region src/core/scanning/file-scanner.d.ts
4
4
  /**
5
5
  * Scan a directory for files matching a glob pattern
6
6
  */
@@ -1,16 +1,7 @@
1
- import { GLOB_SCAN_PATTERN } from "../constants.mjs";
1
+ import { DEFAULT_IGNORE_PATTERNS, GLOB_SCAN_PATTERN } from "../constants.mjs";
2
2
  import { join, relative } from "pathe";
3
3
  import { glob } from "tinyglobby";
4
-
5
- //#region src/core/scanning/common.ts
6
- const DEFAULT_IGNORE_PATTERNS = [
7
- "**/node_modules/**",
8
- "**/.git/**",
9
- "**/.output/**",
10
- "**/.nitro/**",
11
- "**/.nuxt/**",
12
- "**/.graphql/**"
13
- ];
4
+ //#region src/core/scanning/file-scanner.ts
14
5
  /**
15
6
  * Scan a directory for files matching a glob pattern
16
7
  */
@@ -54,6 +45,5 @@ function filterByExtension(files, extensions) {
54
45
  function extractPaths(files) {
55
46
  return files.map((f) => f.fullPath);
56
47
  }
57
-
58
48
  //#endregion
59
- export { deduplicateFiles, extractPaths, filterByExtension, scanDirectory };
49
+ export { deduplicateFiles, extractPaths, filterByExtension, scanDirectory };
@@ -1,7 +1,7 @@
1
1
  import { ASTScanConfig, parseSingleFile, scanWithAST } from "./ast-scanner.mjs";
2
- import { deduplicateFiles, extractPaths, filterByExtension, scanDirectory } from "./common.mjs";
3
2
  import { parseDirectiveCall, scanDirectivesCore } from "./directives.mjs";
4
3
  import { ScanDocumentsOptions, scanDocumentsCore } from "./documents.mjs";
4
+ import { deduplicateFiles, extractPaths, filterByExtension, scanDirectory } from "./file-scanner.mjs";
5
5
  import { parseResolverCall, scanResolversCore } from "./resolvers.mjs";
6
- import { scanGraphqlCore, scanSchemasCore } from "./schemas.mjs";
7
- export { type ASTScanConfig, type ScanDocumentsOptions, deduplicateFiles, extractPaths, filterByExtension, parseDirectiveCall, parseResolverCall, parseSingleFile, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST };
6
+ import { scanSchemasCore } from "./schemas.mjs";
7
+ export { type ASTScanConfig, type ScanDocumentsOptions, deduplicateFiles, extractPaths, filterByExtension, parseDirectiveCall, parseResolverCall, parseSingleFile, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanResolversCore, scanSchemasCore, scanWithAST };
@@ -1,8 +1,7 @@
1
- import { deduplicateFiles, extractPaths, filterByExtension, scanDirectory } from "./common.mjs";
1
+ import { deduplicateFiles, extractPaths, filterByExtension, scanDirectory } from "./file-scanner.mjs";
2
2
  import { parseSingleFile, scanWithAST } from "./ast-scanner.mjs";
3
3
  import { parseDirectiveCall, scanDirectivesCore } from "./directives.mjs";
4
4
  import { scanDocumentsCore } from "./documents.mjs";
5
5
  import { parseResolverCall, scanResolversCore } from "./resolvers.mjs";
6
- import { scanGraphqlCore, scanSchemasCore } from "./schemas.mjs";
7
-
8
- export { deduplicateFiles, extractPaths, filterByExtension, parseDirectiveCall, parseResolverCall, parseSingleFile, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanGraphqlCore, scanResolversCore, scanSchemasCore, scanWithAST };
6
+ import { scanSchemasCore } from "./schemas.mjs";
7
+ export { deduplicateFiles, extractPaths, filterByExtension, parseDirectiveCall, parseResolverCall, parseSingleFile, scanDirectivesCore, scanDirectory, scanDocumentsCore, scanResolversCore, scanSchemasCore, scanWithAST };
@@ -1,44 +1,43 @@
1
1
  import { DEFINE_FUNCTIONS, RESOLVER_GLOB_PATTERN } from "../constants.mjs";
2
2
  import { scanWithAST } from "./ast-scanner.mjs";
3
- import { hash } from "ohash";
4
-
3
+ import { getImportId } from "../utils/imports.mjs";
5
4
  //#region src/core/scanning/resolvers.ts
6
5
  /**
7
6
  * Parse a define* function call and return the import info
8
7
  * Exported for use by manifest loader
9
8
  */
10
9
  function parseResolverCall(calleeName, exportName, filePath) {
11
- const aliasHash = `_${hash(exportName + filePath).replace(/-/g, "").slice(0, 6)}`;
10
+ const alias = getImportId(exportName + filePath);
12
11
  switch (calleeName) {
13
12
  case "defineResolver": return {
14
13
  name: exportName,
15
14
  type: "resolver",
16
- as: aliasHash
15
+ as: alias
17
16
  };
18
17
  case "defineQuery": return {
19
18
  name: exportName,
20
19
  type: "query",
21
- as: aliasHash
20
+ as: alias
22
21
  };
23
22
  case "defineMutation": return {
24
23
  name: exportName,
25
24
  type: "mutation",
26
- as: aliasHash
25
+ as: alias
27
26
  };
28
27
  case "defineField": return {
29
28
  name: exportName,
30
29
  type: "type",
31
- as: aliasHash
30
+ as: alias
32
31
  };
33
32
  case "defineSubscription": return {
34
33
  name: exportName,
35
34
  type: "subscription",
36
- as: aliasHash
35
+ as: alias
37
36
  };
38
37
  case "defineDirective": return {
39
38
  name: exportName,
40
39
  type: "directive",
41
- as: aliasHash
40
+ as: alias
42
41
  };
43
42
  default: return null;
44
43
  }
@@ -54,6 +53,5 @@ function scanResolversCore(ctx) {
54
53
  validFunctions: DEFINE_FUNCTIONS
55
54
  });
56
55
  }
57
-
58
56
  //#endregion
59
- export { parseResolverCall, scanResolversCore };
57
+ export { parseResolverCall, scanResolversCore };
@@ -5,9 +5,5 @@ import { ScanContext, ScanResult } from "../types/scanning.mjs";
5
5
  * Scan for GraphQL schema files (.graphql, .gql) in server directory
6
6
  */
7
7
  declare function scanSchemasCore(ctx: ScanContext): Promise<ScanResult<string>>;
8
- /**
9
- * Scan for GraphQL files (.graphql, .gql) in server directory
10
- */
11
- declare function scanGraphqlCore(ctx: ScanContext): Promise<ScanResult<string>>;
12
8
  //#endregion
13
- export { scanGraphqlCore, scanSchemasCore };
9
+ export { scanSchemasCore };
@@ -1,7 +1,6 @@
1
1
  import { GRAPHQL_GLOB_PATTERN } from "../constants.mjs";
2
- import { extractPaths, scanDirectory } from "./common.mjs";
2
+ import { extractPaths, scanDirectory } from "./file-scanner.mjs";
3
3
  import { relative } from "pathe";
4
-
5
4
  //#region src/core/scanning/schemas.ts
6
5
  /**
7
6
  * Scan for GraphQL schema files (.graphql, .gql) in server directory
@@ -25,28 +24,5 @@ async function scanSchemasCore(ctx) {
25
24
  };
26
25
  }
27
26
  }
28
- /**
29
- * Scan for GraphQL files (.graphql, .gql) in server directory
30
- */
31
- async function scanGraphqlCore(ctx) {
32
- const warnings = [];
33
- const errors = [];
34
- try {
35
- const serverDirRelative = relative(ctx.rootDir, ctx.serverDir);
36
- return {
37
- items: extractPaths(await scanDirectory(ctx, ctx.rootDir, serverDirRelative, "**/*.{graphql,gql}")),
38
- warnings,
39
- errors
40
- };
41
- } catch (error) {
42
- errors.push(`GraphQL scanning error: ${error}`);
43
- return {
44
- items: [],
45
- warnings,
46
- errors
47
- };
48
- }
49
- }
50
-
51
27
  //#endregion
52
- export { scanGraphqlCore, scanSchemasCore };
28
+ export { scanSchemasCore };