@effect-gql/bun 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.cts ADDED
@@ -0,0 +1,235 @@
1
+ import { Layer, Queue, Deferred, Effect } from 'effect';
2
+ import { HttpRouter } from '@effect/platform';
3
+ import { GraphQLSchema } from 'graphql';
4
+ import { GraphQLWSOptions, CloseEvent, WebSocketError, EffectWebSocket, GraphQLSSEOptions } from '@effect-gql/core';
5
+ import { Server, ServerWebSocket } from 'bun';
6
+
7
+ /**
8
+ * Configuration for WebSocket subscriptions
9
+ */
10
+ interface SubscriptionsConfig<R> extends GraphQLWSOptions<R> {
11
+ /**
12
+ * The GraphQL schema (required for subscriptions).
13
+ * Must be the same schema used to create the router.
14
+ */
15
+ readonly schema: GraphQLSchema;
16
+ /**
17
+ * Path for WebSocket connections.
18
+ * @default "/graphql"
19
+ */
20
+ readonly path?: string;
21
+ }
22
+ /**
23
+ * Options for the Bun GraphQL server
24
+ */
25
+ interface ServeOptions<R = never> {
26
+ /** Port to listen on (default: 4000) */
27
+ readonly port?: number;
28
+ /** Hostname to bind to (default: "0.0.0.0") */
29
+ readonly host?: string;
30
+ /** Callback when server starts */
31
+ readonly onStart?: (url: string) => void;
32
+ /**
33
+ * Enable WebSocket subscriptions.
34
+ * When provided, the server will handle WebSocket upgrade requests
35
+ * for GraphQL subscriptions using the graphql-ws protocol.
36
+ */
37
+ readonly subscriptions?: SubscriptionsConfig<R>;
38
+ }
39
+ /**
40
+ * Start a Bun HTTP server with the given router.
41
+ *
42
+ * This is the main entry point for running a GraphQL server on Bun.
43
+ * It handles all the Effect runtime setup and server lifecycle.
44
+ *
45
+ * @param router - The HttpRouter to serve (typically from makeGraphQLRouter or toRouter)
46
+ * @param layer - Layer providing the router's service dependencies
47
+ * @param options - Server configuration options
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * import { makeGraphQLRouter } from "@effect-gql/core"
52
+ * import { serve } from "@effect-gql/bun"
53
+ *
54
+ * const schema = GraphQLSchemaBuilder.empty
55
+ * .query("hello", { type: S.String, resolve: () => Effect.succeed("world") })
56
+ * .buildSchema()
57
+ *
58
+ * const router = makeGraphQLRouter(schema, Layer.empty, { graphiql: true })
59
+ *
60
+ * // Without subscriptions
61
+ * serve(router, serviceLayer, {
62
+ * port: 4000,
63
+ * onStart: (url) => console.log(`Server running at ${url}`)
64
+ * })
65
+ *
66
+ * // With subscriptions
67
+ * serve(router, serviceLayer, {
68
+ * port: 4000,
69
+ * subscriptions: { schema },
70
+ * onStart: (url) => console.log(`Server running at ${url}`)
71
+ * })
72
+ * ```
73
+ */
74
+ declare const serve: <E, R, RE>(router: HttpRouter.HttpRouter<E, R>, layer: Layer.Layer<R, RE>, options?: ServeOptions<R>) => void;
75
+
76
+ /**
77
+ * Data attached to each WebSocket connection
78
+ */
79
+ interface WebSocketData {
80
+ messageQueue: Queue.Queue<string>;
81
+ closedDeferred: Deferred.Deferred<CloseEvent, WebSocketError>;
82
+ effectSocket: EffectWebSocket;
83
+ }
84
+ /**
85
+ * Options for Bun WebSocket server
86
+ */
87
+ interface BunWSOptions<R> extends GraphQLWSOptions<R> {
88
+ /**
89
+ * Path for WebSocket connections.
90
+ * @default "/graphql"
91
+ */
92
+ readonly path?: string;
93
+ }
94
+ /**
95
+ * Create WebSocket handlers for Bun.serve().
96
+ *
97
+ * Bun has built-in WebSocket support that's configured as part of Bun.serve().
98
+ * This function returns the handlers needed to integrate GraphQL subscriptions.
99
+ *
100
+ * @param schema - The GraphQL schema with subscription definitions
101
+ * @param layer - Effect layer providing services required by resolvers
102
+ * @param options - Optional configuration and lifecycle hooks
103
+ * @returns Object containing upgrade check and WebSocket handlers
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const { upgrade, websocket } = createBunWSHandlers(schema, serviceLayer)
108
+ *
109
+ * Bun.serve({
110
+ * port: 4000,
111
+ * fetch(req, server) {
112
+ * // Try WebSocket upgrade first
113
+ * if (upgrade(req, server)) {
114
+ * return // Upgraded to WebSocket
115
+ * }
116
+ * // Handle HTTP requests...
117
+ * },
118
+ * websocket,
119
+ * })
120
+ * ```
121
+ */
122
+ declare const createBunWSHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunWSOptions<R>) => {
123
+ /**
124
+ * Check if request should upgrade to WebSocket and perform upgrade.
125
+ * Returns true if upgraded, false otherwise.
126
+ */
127
+ upgrade: (request: Request, server: Server<WebSocketData>) => boolean;
128
+ /**
129
+ * WebSocket event handlers for Bun.serve()
130
+ */
131
+ websocket: {
132
+ open: (ws: ServerWebSocket<WebSocketData>) => void;
133
+ message: (ws: ServerWebSocket<WebSocketData>, message: string | Buffer) => void;
134
+ close: (ws: ServerWebSocket<WebSocketData>, code: number, reason: string) => void;
135
+ error: (ws: ServerWebSocket<WebSocketData>, error: Error) => void;
136
+ };
137
+ };
138
+ /**
139
+ * Convert a Bun ServerWebSocket to an EffectWebSocket.
140
+ *
141
+ * This is a lower-level utility for custom WebSocket handling.
142
+ * Most users should use createBunWSHandlers() instead.
143
+ *
144
+ * @param ws - The Bun ServerWebSocket instance
145
+ * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler
146
+ */
147
+ declare const toBunEffectWebSocket: (ws: ServerWebSocket<WebSocketData>) => Effect.Effect<EffectWebSocket, never, never>;
148
+
149
+ /**
150
+ * Options for Bun SSE handler
151
+ */
152
+ interface BunSSEOptions<R> extends GraphQLSSEOptions<R> {
153
+ /**
154
+ * Path for SSE connections.
155
+ * @default "/graphql/stream"
156
+ */
157
+ readonly path?: string;
158
+ }
159
+ /**
160
+ * Create an SSE handler for Bun.serve().
161
+ *
162
+ * This function creates a handler that returns a streaming Response for SSE
163
+ * subscription requests. It's designed to integrate with Bun.serve()'s fetch handler.
164
+ *
165
+ * @param schema - The GraphQL schema with subscription definitions
166
+ * @param layer - Effect layer providing services required by resolvers
167
+ * @param options - Optional lifecycle hooks and configuration
168
+ * @returns A function that handles SSE requests and returns a Response
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const sseHandler = createBunSSEHandler(schema, serviceLayer, {
173
+ * path: "/graphql/stream",
174
+ * })
175
+ *
176
+ * Bun.serve({
177
+ * port: 4000,
178
+ * fetch(req, server) {
179
+ * const url = new URL(req.url)
180
+ *
181
+ * // Handle SSE subscriptions
182
+ * if (url.pathname === "/graphql/stream" && req.method === "POST") {
183
+ * return sseHandler(req)
184
+ * }
185
+ *
186
+ * // Handle other requests...
187
+ * },
188
+ * })
189
+ * ```
190
+ */
191
+ declare const createBunSSEHandler: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => ((request: Request) => Promise<Response>);
192
+ /**
193
+ * Create SSE handlers that integrate with Bun.serve().
194
+ *
195
+ * This returns an object with methods to check if a request should be
196
+ * handled as SSE and to handle it.
197
+ *
198
+ * @param schema - The GraphQL schema with subscription definitions
199
+ * @param layer - Effect layer providing services required by resolvers
200
+ * @param options - Optional lifecycle hooks and configuration
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * const { upgrade: wsUpgrade, websocket } = createBunWSHandlers(schema, layer)
205
+ * const sse = createBunSSEHandlers(schema, layer)
206
+ *
207
+ * Bun.serve({
208
+ * port: 4000,
209
+ * fetch(req, server) {
210
+ * // Try WebSocket upgrade first
211
+ * if (wsUpgrade(req, server)) {
212
+ * return
213
+ * }
214
+ *
215
+ * // Try SSE subscriptions
216
+ * if (sse.shouldHandle(req)) {
217
+ * return sse.handle(req)
218
+ * }
219
+ *
220
+ * // Handle other requests...
221
+ * },
222
+ * websocket,
223
+ * })
224
+ * ```
225
+ */
226
+ declare const createBunSSEHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => {
227
+ /** Path this SSE handler responds to */
228
+ readonly path: string;
229
+ /** Check if a request should be handled as SSE */
230
+ shouldHandle: (request: Request) => boolean;
231
+ /** Handle an SSE request */
232
+ handle: (request: Request) => Promise<Response>;
233
+ };
234
+
235
+ export { type BunSSEOptions, type BunWSOptions, type ServeOptions, type SubscriptionsConfig, createBunSSEHandler, createBunSSEHandlers, createBunWSHandlers, serve, toBunEffectWebSocket };
package/index.d.ts ADDED
@@ -0,0 +1,235 @@
1
+ import { Layer, Queue, Deferred, Effect } from 'effect';
2
+ import { HttpRouter } from '@effect/platform';
3
+ import { GraphQLSchema } from 'graphql';
4
+ import { GraphQLWSOptions, CloseEvent, WebSocketError, EffectWebSocket, GraphQLSSEOptions } from '@effect-gql/core';
5
+ import { Server, ServerWebSocket } from 'bun';
6
+
7
+ /**
8
+ * Configuration for WebSocket subscriptions
9
+ */
10
+ interface SubscriptionsConfig<R> extends GraphQLWSOptions<R> {
11
+ /**
12
+ * The GraphQL schema (required for subscriptions).
13
+ * Must be the same schema used to create the router.
14
+ */
15
+ readonly schema: GraphQLSchema;
16
+ /**
17
+ * Path for WebSocket connections.
18
+ * @default "/graphql"
19
+ */
20
+ readonly path?: string;
21
+ }
22
+ /**
23
+ * Options for the Bun GraphQL server
24
+ */
25
+ interface ServeOptions<R = never> {
26
+ /** Port to listen on (default: 4000) */
27
+ readonly port?: number;
28
+ /** Hostname to bind to (default: "0.0.0.0") */
29
+ readonly host?: string;
30
+ /** Callback when server starts */
31
+ readonly onStart?: (url: string) => void;
32
+ /**
33
+ * Enable WebSocket subscriptions.
34
+ * When provided, the server will handle WebSocket upgrade requests
35
+ * for GraphQL subscriptions using the graphql-ws protocol.
36
+ */
37
+ readonly subscriptions?: SubscriptionsConfig<R>;
38
+ }
39
+ /**
40
+ * Start a Bun HTTP server with the given router.
41
+ *
42
+ * This is the main entry point for running a GraphQL server on Bun.
43
+ * It handles all the Effect runtime setup and server lifecycle.
44
+ *
45
+ * @param router - The HttpRouter to serve (typically from makeGraphQLRouter or toRouter)
46
+ * @param layer - Layer providing the router's service dependencies
47
+ * @param options - Server configuration options
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * import { makeGraphQLRouter } from "@effect-gql/core"
52
+ * import { serve } from "@effect-gql/bun"
53
+ *
54
+ * const schema = GraphQLSchemaBuilder.empty
55
+ * .query("hello", { type: S.String, resolve: () => Effect.succeed("world") })
56
+ * .buildSchema()
57
+ *
58
+ * const router = makeGraphQLRouter(schema, Layer.empty, { graphiql: true })
59
+ *
60
+ * // Without subscriptions
61
+ * serve(router, serviceLayer, {
62
+ * port: 4000,
63
+ * onStart: (url) => console.log(`Server running at ${url}`)
64
+ * })
65
+ *
66
+ * // With subscriptions
67
+ * serve(router, serviceLayer, {
68
+ * port: 4000,
69
+ * subscriptions: { schema },
70
+ * onStart: (url) => console.log(`Server running at ${url}`)
71
+ * })
72
+ * ```
73
+ */
74
+ declare const serve: <E, R, RE>(router: HttpRouter.HttpRouter<E, R>, layer: Layer.Layer<R, RE>, options?: ServeOptions<R>) => void;
75
+
76
+ /**
77
+ * Data attached to each WebSocket connection
78
+ */
79
+ interface WebSocketData {
80
+ messageQueue: Queue.Queue<string>;
81
+ closedDeferred: Deferred.Deferred<CloseEvent, WebSocketError>;
82
+ effectSocket: EffectWebSocket;
83
+ }
84
+ /**
85
+ * Options for Bun WebSocket server
86
+ */
87
+ interface BunWSOptions<R> extends GraphQLWSOptions<R> {
88
+ /**
89
+ * Path for WebSocket connections.
90
+ * @default "/graphql"
91
+ */
92
+ readonly path?: string;
93
+ }
94
+ /**
95
+ * Create WebSocket handlers for Bun.serve().
96
+ *
97
+ * Bun has built-in WebSocket support that's configured as part of Bun.serve().
98
+ * This function returns the handlers needed to integrate GraphQL subscriptions.
99
+ *
100
+ * @param schema - The GraphQL schema with subscription definitions
101
+ * @param layer - Effect layer providing services required by resolvers
102
+ * @param options - Optional configuration and lifecycle hooks
103
+ * @returns Object containing upgrade check and WebSocket handlers
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const { upgrade, websocket } = createBunWSHandlers(schema, serviceLayer)
108
+ *
109
+ * Bun.serve({
110
+ * port: 4000,
111
+ * fetch(req, server) {
112
+ * // Try WebSocket upgrade first
113
+ * if (upgrade(req, server)) {
114
+ * return // Upgraded to WebSocket
115
+ * }
116
+ * // Handle HTTP requests...
117
+ * },
118
+ * websocket,
119
+ * })
120
+ * ```
121
+ */
122
+ declare const createBunWSHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunWSOptions<R>) => {
123
+ /**
124
+ * Check if request should upgrade to WebSocket and perform upgrade.
125
+ * Returns true if upgraded, false otherwise.
126
+ */
127
+ upgrade: (request: Request, server: Server<WebSocketData>) => boolean;
128
+ /**
129
+ * WebSocket event handlers for Bun.serve()
130
+ */
131
+ websocket: {
132
+ open: (ws: ServerWebSocket<WebSocketData>) => void;
133
+ message: (ws: ServerWebSocket<WebSocketData>, message: string | Buffer) => void;
134
+ close: (ws: ServerWebSocket<WebSocketData>, code: number, reason: string) => void;
135
+ error: (ws: ServerWebSocket<WebSocketData>, error: Error) => void;
136
+ };
137
+ };
138
+ /**
139
+ * Convert a Bun ServerWebSocket to an EffectWebSocket.
140
+ *
141
+ * This is a lower-level utility for custom WebSocket handling.
142
+ * Most users should use createBunWSHandlers() instead.
143
+ *
144
+ * @param ws - The Bun ServerWebSocket instance
145
+ * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler
146
+ */
147
+ declare const toBunEffectWebSocket: (ws: ServerWebSocket<WebSocketData>) => Effect.Effect<EffectWebSocket, never, never>;
148
+
149
+ /**
150
+ * Options for Bun SSE handler
151
+ */
152
+ interface BunSSEOptions<R> extends GraphQLSSEOptions<R> {
153
+ /**
154
+ * Path for SSE connections.
155
+ * @default "/graphql/stream"
156
+ */
157
+ readonly path?: string;
158
+ }
159
+ /**
160
+ * Create an SSE handler for Bun.serve().
161
+ *
162
+ * This function creates a handler that returns a streaming Response for SSE
163
+ * subscription requests. It's designed to integrate with Bun.serve()'s fetch handler.
164
+ *
165
+ * @param schema - The GraphQL schema with subscription definitions
166
+ * @param layer - Effect layer providing services required by resolvers
167
+ * @param options - Optional lifecycle hooks and configuration
168
+ * @returns A function that handles SSE requests and returns a Response
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const sseHandler = createBunSSEHandler(schema, serviceLayer, {
173
+ * path: "/graphql/stream",
174
+ * })
175
+ *
176
+ * Bun.serve({
177
+ * port: 4000,
178
+ * fetch(req, server) {
179
+ * const url = new URL(req.url)
180
+ *
181
+ * // Handle SSE subscriptions
182
+ * if (url.pathname === "/graphql/stream" && req.method === "POST") {
183
+ * return sseHandler(req)
184
+ * }
185
+ *
186
+ * // Handle other requests...
187
+ * },
188
+ * })
189
+ * ```
190
+ */
191
+ declare const createBunSSEHandler: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => ((request: Request) => Promise<Response>);
192
+ /**
193
+ * Create SSE handlers that integrate with Bun.serve().
194
+ *
195
+ * This returns an object with methods to check if a request should be
196
+ * handled as SSE and to handle it.
197
+ *
198
+ * @param schema - The GraphQL schema with subscription definitions
199
+ * @param layer - Effect layer providing services required by resolvers
200
+ * @param options - Optional lifecycle hooks and configuration
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * const { upgrade: wsUpgrade, websocket } = createBunWSHandlers(schema, layer)
205
+ * const sse = createBunSSEHandlers(schema, layer)
206
+ *
207
+ * Bun.serve({
208
+ * port: 4000,
209
+ * fetch(req, server) {
210
+ * // Try WebSocket upgrade first
211
+ * if (wsUpgrade(req, server)) {
212
+ * return
213
+ * }
214
+ *
215
+ * // Try SSE subscriptions
216
+ * if (sse.shouldHandle(req)) {
217
+ * return sse.handle(req)
218
+ * }
219
+ *
220
+ * // Handle other requests...
221
+ * },
222
+ * websocket,
223
+ * })
224
+ * ```
225
+ */
226
+ declare const createBunSSEHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => {
227
+ /** Path this SSE handler responds to */
228
+ readonly path: string;
229
+ /** Check if a request should be handled as SSE */
230
+ shouldHandle: (request: Request) => boolean;
231
+ /** Handle an SSE request */
232
+ handle: (request: Request) => Promise<Response>;
233
+ };
234
+
235
+ export { type BunSSEOptions, type BunWSOptions, type ServeOptions, type SubscriptionsConfig, createBunSSEHandler, createBunSSEHandlers, createBunWSHandlers, serve, toBunEffectWebSocket };