@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/dist/serve.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
package/dist/sse.d.ts DELETED
@@ -1,89 +0,0 @@
1
- import { Layer } from "effect";
2
- import { GraphQLSchema } from "graphql";
3
- import { type GraphQLSSEOptions } from "@effect-gql/core";
4
- /**
5
- * Options for Bun SSE handler
6
- */
7
- export interface BunSSEOptions<R> extends GraphQLSSEOptions<R> {
8
- /**
9
- * Path for SSE connections.
10
- * @default "/graphql/stream"
11
- */
12
- readonly path?: string;
13
- }
14
- /**
15
- * Create an SSE handler for Bun.serve().
16
- *
17
- * This function creates a handler that returns a streaming Response for SSE
18
- * subscription requests. It's designed to integrate with Bun.serve()'s fetch handler.
19
- *
20
- * @param schema - The GraphQL schema with subscription definitions
21
- * @param layer - Effect layer providing services required by resolvers
22
- * @param options - Optional lifecycle hooks and configuration
23
- * @returns A function that handles SSE requests and returns a Response
24
- *
25
- * @example
26
- * ```typescript
27
- * const sseHandler = createBunSSEHandler(schema, serviceLayer, {
28
- * path: "/graphql/stream",
29
- * })
30
- *
31
- * Bun.serve({
32
- * port: 4000,
33
- * fetch(req, server) {
34
- * const url = new URL(req.url)
35
- *
36
- * // Handle SSE subscriptions
37
- * if (url.pathname === "/graphql/stream" && req.method === "POST") {
38
- * return sseHandler(req)
39
- * }
40
- *
41
- * // Handle other requests...
42
- * },
43
- * })
44
- * ```
45
- */
46
- export declare const createBunSSEHandler: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => ((request: Request) => Promise<Response>);
47
- /**
48
- * Create SSE handlers that integrate with Bun.serve().
49
- *
50
- * This returns an object with methods to check if a request should be
51
- * handled as SSE and to handle it.
52
- *
53
- * @param schema - The GraphQL schema with subscription definitions
54
- * @param layer - Effect layer providing services required by resolvers
55
- * @param options - Optional lifecycle hooks and configuration
56
- *
57
- * @example
58
- * ```typescript
59
- * const { upgrade: wsUpgrade, websocket } = createBunWSHandlers(schema, layer)
60
- * const sse = createBunSSEHandlers(schema, layer)
61
- *
62
- * Bun.serve({
63
- * port: 4000,
64
- * fetch(req, server) {
65
- * // Try WebSocket upgrade first
66
- * if (wsUpgrade(req, server)) {
67
- * return
68
- * }
69
- *
70
- * // Try SSE subscriptions
71
- * if (sse.shouldHandle(req)) {
72
- * return sse.handle(req)
73
- * }
74
- *
75
- * // Handle other requests...
76
- * },
77
- * websocket,
78
- * })
79
- * ```
80
- */
81
- export declare const createBunSSEHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunSSEOptions<R>) => {
82
- /** Path this SSE handler responds to */
83
- readonly path: string;
84
- /** Check if a request should be handled as SSE */
85
- shouldHandle: (request: Request) => boolean;
86
- /** Handle an SSE request */
87
- handle: (request: Request) => Promise<Response>;
88
- };
89
- //# sourceMappingURL=sse.d.ts.map
package/dist/sse.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAU,MAAM,QAAQ,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,EAIL,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAA;AAEzB;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC5D;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,EACnC,QAAQ,aAAa,EACrB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB,UAAU,aAAa,CAAC,CAAC,CAAC,KACzB,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAgE1C,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,EACpC,QAAQ,aAAa,EACrB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB,UAAU,aAAa,CAAC,CAAC,CAAC,KACzB;IACD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,kDAAkD;IAClD,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IAC3C,4BAA4B;IAC5B,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAchD,CAAA"}
package/dist/sse.js DELETED
@@ -1,135 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBunSSEHandlers = exports.createBunSSEHandler = void 0;
4
- const effect_1 = require("effect");
5
- const core_1 = require("@effect-gql/core");
6
- /**
7
- * Create an SSE handler for Bun.serve().
8
- *
9
- * This function creates a handler that returns a streaming Response for SSE
10
- * subscription requests. It's designed to integrate with Bun.serve()'s fetch handler.
11
- *
12
- * @param schema - The GraphQL schema with subscription definitions
13
- * @param layer - Effect layer providing services required by resolvers
14
- * @param options - Optional lifecycle hooks and configuration
15
- * @returns A function that handles SSE requests and returns a Response
16
- *
17
- * @example
18
- * ```typescript
19
- * const sseHandler = createBunSSEHandler(schema, serviceLayer, {
20
- * path: "/graphql/stream",
21
- * })
22
- *
23
- * Bun.serve({
24
- * port: 4000,
25
- * fetch(req, server) {
26
- * const url = new URL(req.url)
27
- *
28
- * // Handle SSE subscriptions
29
- * if (url.pathname === "/graphql/stream" && req.method === "POST") {
30
- * return sseHandler(req)
31
- * }
32
- *
33
- * // Handle other requests...
34
- * },
35
- * })
36
- * ```
37
- */
38
- const createBunSSEHandler = (schema, layer, options) => {
39
- const sseHandler = (0, core_1.makeGraphQLSSEHandler)(schema, layer, options);
40
- return async (request) => {
41
- // Check Accept header for SSE support
42
- const accept = request.headers.get("accept") ?? "";
43
- if (!accept.includes("text/event-stream") && !accept.includes("*/*")) {
44
- return new Response(JSON.stringify({
45
- errors: [{ message: "Client must accept text/event-stream" }],
46
- }), { status: 406, headers: { "Content-Type": "application/json" } });
47
- }
48
- // Read and parse the request body
49
- let subscriptionRequest;
50
- try {
51
- const body = (await request.json());
52
- if (typeof body.query !== "string") {
53
- throw new Error("Missing query");
54
- }
55
- subscriptionRequest = {
56
- query: body.query,
57
- variables: body.variables,
58
- operationName: body.operationName,
59
- extensions: body.extensions,
60
- };
61
- }
62
- catch {
63
- return new Response(JSON.stringify({
64
- errors: [{ message: "Invalid GraphQL request body" }],
65
- }), { status: 400, headers: { "Content-Type": "application/json" } });
66
- }
67
- // Get the event stream
68
- const eventStream = sseHandler(subscriptionRequest, request.headers);
69
- // Create a ReadableStream from the Effect Stream
70
- const readableStream = new ReadableStream({
71
- async start(controller) {
72
- const encoder = new TextEncoder();
73
- await effect_1.Effect.runPromise(effect_1.Stream.runForEach(eventStream, (event) => effect_1.Effect.sync(() => {
74
- const message = (0, core_1.formatSSEMessage)(event);
75
- controller.enqueue(encoder.encode(message));
76
- })).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.logWarning("SSE stream error", error)), effect_1.Effect.ensuring(effect_1.Effect.sync(() => controller.close()))));
77
- },
78
- });
79
- return new Response(readableStream, {
80
- status: 200,
81
- headers: core_1.SSE_HEADERS,
82
- });
83
- };
84
- };
85
- exports.createBunSSEHandler = createBunSSEHandler;
86
- /**
87
- * Create SSE handlers that integrate with Bun.serve().
88
- *
89
- * This returns an object with methods to check if a request should be
90
- * handled as SSE and to handle it.
91
- *
92
- * @param schema - The GraphQL schema with subscription definitions
93
- * @param layer - Effect layer providing services required by resolvers
94
- * @param options - Optional lifecycle hooks and configuration
95
- *
96
- * @example
97
- * ```typescript
98
- * const { upgrade: wsUpgrade, websocket } = createBunWSHandlers(schema, layer)
99
- * const sse = createBunSSEHandlers(schema, layer)
100
- *
101
- * Bun.serve({
102
- * port: 4000,
103
- * fetch(req, server) {
104
- * // Try WebSocket upgrade first
105
- * if (wsUpgrade(req, server)) {
106
- * return
107
- * }
108
- *
109
- * // Try SSE subscriptions
110
- * if (sse.shouldHandle(req)) {
111
- * return sse.handle(req)
112
- * }
113
- *
114
- * // Handle other requests...
115
- * },
116
- * websocket,
117
- * })
118
- * ```
119
- */
120
- const createBunSSEHandlers = (schema, layer, options) => {
121
- const path = options?.path ?? "/graphql/stream";
122
- const handler = (0, exports.createBunSSEHandler)(schema, layer, options);
123
- return {
124
- path,
125
- shouldHandle: (request) => {
126
- if (request.method !== "POST")
127
- return false;
128
- const url = new URL(request.url);
129
- return url.pathname === path;
130
- },
131
- handle: handler,
132
- };
133
- };
134
- exports.createBunSSEHandlers = createBunSSEHandlers;
135
- //# sourceMappingURL=sse.js.map
package/dist/sse.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}
package/dist/ws.d.ts DELETED
@@ -1,78 +0,0 @@
1
- import { Effect, Queue, Deferred, Layer } from "effect";
2
- import { GraphQLSchema } from "graphql";
3
- import { type EffectWebSocket, type GraphQLWSOptions, WebSocketError, type CloseEvent } from "@effect-gql/core";
4
- import type { Server, ServerWebSocket } from "bun";
5
- /**
6
- * Data attached to each WebSocket connection
7
- */
8
- interface WebSocketData {
9
- messageQueue: Queue.Queue<string>;
10
- closedDeferred: Deferred.Deferred<CloseEvent, WebSocketError>;
11
- effectSocket: EffectWebSocket;
12
- }
13
- /**
14
- * Options for Bun WebSocket server
15
- */
16
- export interface BunWSOptions<R> extends GraphQLWSOptions<R> {
17
- /**
18
- * Path for WebSocket connections.
19
- * @default "/graphql"
20
- */
21
- readonly path?: string;
22
- }
23
- /**
24
- * Create WebSocket handlers for Bun.serve().
25
- *
26
- * Bun has built-in WebSocket support that's configured as part of Bun.serve().
27
- * This function returns the handlers needed to integrate GraphQL subscriptions.
28
- *
29
- * @param schema - The GraphQL schema with subscription definitions
30
- * @param layer - Effect layer providing services required by resolvers
31
- * @param options - Optional configuration and lifecycle hooks
32
- * @returns Object containing upgrade check and WebSocket handlers
33
- *
34
- * @example
35
- * ```typescript
36
- * const { upgrade, websocket } = createBunWSHandlers(schema, serviceLayer)
37
- *
38
- * Bun.serve({
39
- * port: 4000,
40
- * fetch(req, server) {
41
- * // Try WebSocket upgrade first
42
- * if (upgrade(req, server)) {
43
- * return // Upgraded to WebSocket
44
- * }
45
- * // Handle HTTP requests...
46
- * },
47
- * websocket,
48
- * })
49
- * ```
50
- */
51
- export declare const createBunWSHandlers: <R>(schema: GraphQLSchema, layer: Layer.Layer<R>, options?: BunWSOptions<R>) => {
52
- /**
53
- * Check if request should upgrade to WebSocket and perform upgrade.
54
- * Returns true if upgraded, false otherwise.
55
- */
56
- upgrade: (request: Request, server: Server<WebSocketData>) => boolean;
57
- /**
58
- * WebSocket event handlers for Bun.serve()
59
- */
60
- websocket: {
61
- open: (ws: ServerWebSocket<WebSocketData>) => void;
62
- message: (ws: ServerWebSocket<WebSocketData>, message: string | Buffer) => void;
63
- close: (ws: ServerWebSocket<WebSocketData>, code: number, reason: string) => void;
64
- error: (ws: ServerWebSocket<WebSocketData>, error: Error) => void;
65
- };
66
- };
67
- /**
68
- * Convert a Bun ServerWebSocket to an EffectWebSocket.
69
- *
70
- * This is a lower-level utility for custom WebSocket handling.
71
- * Most users should use createBunWSHandlers() instead.
72
- *
73
- * @param ws - The Bun ServerWebSocket instance
74
- * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler
75
- */
76
- export declare const toBunEffectWebSocket: (ws: ServerWebSocket<WebSocketData>) => Effect.Effect<EffectWebSocket, never, never>;
77
- export {};
78
- //# sourceMappingURL=ws.d.ts.map
package/dist/ws.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAElD;;GAEG;AACH,UAAU,aAAa;IACrB,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACjC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IAC7D,YAAY,EAAE,eAAe,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,EACnC,QAAQ,aAAa,EACrB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB,UAAU,YAAY,CAAC,CAAC,CAAC,KACxB;IACD;;;OAGG;IACH,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,KAAK,OAAO,CAAA;IACrE;;OAEG;IACH,SAAS,EAAE;QACT,IAAI,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;QAClD,OAAO,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAA;QAC/E,KAAK,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;QACjF,KAAK,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAClE,CAAA;CA0HF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAC/B,IAAI,eAAe,CAAC,aAAa,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,CAkC1C,CAAA"}
package/dist/ws.js DELETED
@@ -1,160 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toBunEffectWebSocket = exports.createBunWSHandlers = void 0;
4
- const effect_1 = require("effect");
5
- const core_1 = require("@effect-gql/core");
6
- /**
7
- * Create WebSocket handlers for Bun.serve().
8
- *
9
- * Bun has built-in WebSocket support that's configured as part of Bun.serve().
10
- * This function returns the handlers needed to integrate GraphQL subscriptions.
11
- *
12
- * @param schema - The GraphQL schema with subscription definitions
13
- * @param layer - Effect layer providing services required by resolvers
14
- * @param options - Optional configuration and lifecycle hooks
15
- * @returns Object containing upgrade check and WebSocket handlers
16
- *
17
- * @example
18
- * ```typescript
19
- * const { upgrade, websocket } = createBunWSHandlers(schema, serviceLayer)
20
- *
21
- * Bun.serve({
22
- * port: 4000,
23
- * fetch(req, server) {
24
- * // Try WebSocket upgrade first
25
- * if (upgrade(req, server)) {
26
- * return // Upgraded to WebSocket
27
- * }
28
- * // Handle HTTP requests...
29
- * },
30
- * websocket,
31
- * })
32
- * ```
33
- */
34
- const createBunWSHandlers = (schema, layer, options) => {
35
- const path = options?.path ?? "/graphql";
36
- const handler = (0, core_1.makeGraphQLWSHandler)(schema, layer, options);
37
- // Track active connection handlers for cleanup
38
- const activeHandlers = new Map();
39
- const upgrade = (request, server) => {
40
- const url = new URL(request.url);
41
- // Check if this is a WebSocket upgrade request for the GraphQL path
42
- if (url.pathname !== path) {
43
- return false;
44
- }
45
- const upgradeHeader = request.headers.get("upgrade");
46
- if (upgradeHeader?.toLowerCase() !== "websocket") {
47
- return false;
48
- }
49
- // Check for correct subprotocol
50
- const protocol = request.headers.get("sec-websocket-protocol");
51
- if (!protocol?.includes("graphql-transport-ws")) {
52
- return false;
53
- }
54
- // Perform upgrade - data will be set in open handler
55
- const success = server.upgrade(request, {
56
- data: {}, // Will be populated in open handler
57
- });
58
- return success;
59
- };
60
- const websocket = {
61
- open: (ws) => {
62
- // Create Effect-based socket wrapper
63
- const setupEffect = effect_1.Effect.gen(function* () {
64
- const messageQueue = yield* effect_1.Queue.unbounded();
65
- const closedDeferred = yield* effect_1.Deferred.make();
66
- const effectSocket = {
67
- protocol: ws.data?.effectSocket?.protocol || "graphql-transport-ws",
68
- send: (data) => effect_1.Effect.try({
69
- try: () => {
70
- ws.send(data);
71
- },
72
- catch: (error) => new core_1.WebSocketError({ cause: error }),
73
- }),
74
- close: (code, reason) => effect_1.Effect.sync(() => {
75
- ws.close(code ?? 1000, reason ?? "");
76
- }),
77
- messages: effect_1.Stream.fromQueue(messageQueue).pipe(effect_1.Stream.catchAll(() => effect_1.Stream.empty)),
78
- closed: effect_1.Deferred.await(closedDeferred),
79
- };
80
- // Store in WebSocket data
81
- ws.data = {
82
- messageQueue,
83
- closedDeferred,
84
- effectSocket,
85
- };
86
- return effectSocket;
87
- });
88
- // Run setup and handler
89
- const handlerPromise = effect_1.Effect.runPromise(setupEffect.pipe(effect_1.Effect.flatMap((effectSocket) => handler(effectSocket)), effect_1.Effect.catchAllCause(() => effect_1.Effect.void)));
90
- activeHandlers.set(ws, handlerPromise);
91
- },
92
- message: (ws, message) => {
93
- const data = ws.data;
94
- if (data?.messageQueue) {
95
- const messageStr = typeof message === "string" ? message : message.toString();
96
- effect_1.Effect.runPromise(effect_1.Queue.offer(data.messageQueue, messageStr)).catch(() => {
97
- // Queue might be shutdown
98
- });
99
- }
100
- },
101
- close: (ws, code, reason) => {
102
- const data = ws.data;
103
- if (data) {
104
- effect_1.Effect.runPromise(effect_1.Effect.all([
105
- effect_1.Queue.shutdown(data.messageQueue),
106
- effect_1.Deferred.succeed(data.closedDeferred, { code, reason }),
107
- ])).catch(() => {
108
- // Already completed
109
- });
110
- }
111
- activeHandlers.delete(ws);
112
- },
113
- error: (ws, error) => {
114
- const data = ws.data;
115
- if (data) {
116
- effect_1.Effect.runPromise(effect_1.Deferred.fail(data.closedDeferred, new core_1.WebSocketError({ cause: error }))).catch(() => {
117
- // Already completed
118
- });
119
- }
120
- },
121
- };
122
- return { upgrade, websocket };
123
- };
124
- exports.createBunWSHandlers = createBunWSHandlers;
125
- /**
126
- * Convert a Bun ServerWebSocket to an EffectWebSocket.
127
- *
128
- * This is a lower-level utility for custom WebSocket handling.
129
- * Most users should use createBunWSHandlers() instead.
130
- *
131
- * @param ws - The Bun ServerWebSocket instance
132
- * @returns An EffectWebSocket that can be used with makeGraphQLWSHandler
133
- */
134
- const toBunEffectWebSocket = (ws) => effect_1.Effect.gen(function* () {
135
- const messageQueue = yield* effect_1.Queue.unbounded();
136
- const closedDeferred = yield* effect_1.Deferred.make();
137
- const effectSocket = {
138
- protocol: "graphql-transport-ws",
139
- send: (data) => effect_1.Effect.try({
140
- try: () => {
141
- ws.send(data);
142
- },
143
- catch: (error) => new core_1.WebSocketError({ cause: error }),
144
- }),
145
- close: (code, reason) => effect_1.Effect.sync(() => {
146
- ws.close(code ?? 1000, reason ?? "");
147
- }),
148
- messages: effect_1.Stream.fromQueue(messageQueue).pipe(effect_1.Stream.catchAll(() => effect_1.Stream.empty)),
149
- closed: effect_1.Deferred.await(closedDeferred),
150
- };
151
- // Store in WebSocket data for event handlers
152
- ws.data = {
153
- messageQueue,
154
- closedDeferred,
155
- effectSocket,
156
- };
157
- return effectSocket;
158
- });
159
- exports.toBunEffectWebSocket = toBunEffectWebSocket;
160
- //# sourceMappingURL=ws.js.map
package/dist/ws.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"ws.js","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"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"}
package/src/index.ts DELETED
@@ -1,7 +0,0 @@
1
- export { serve, type ServeOptions, type SubscriptionsConfig } from "./serve"
2
-
3
- // WebSocket subscription support
4
- export { createBunWSHandlers, toBunEffectWebSocket, type BunWSOptions } from "./ws"
5
-
6
- // SSE (Server-Sent Events) subscription support
7
- export { createBunSSEHandler, createBunSSEHandlers, type BunSSEOptions } from "./sse"