next-ws 2.0.13 → 2.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.
@@ -38,14 +38,13 @@ __export(client_exports, {
38
38
  module.exports = __toCommonJS(client_exports);
39
39
 
40
40
  // src/client/context.tsx
41
- var import_react = __toESM(require("react"), 1);
42
- var import_react2 = require("react");
43
- var WebSocketContext = (0, import_react2.createContext)(null);
41
+ var import_react = __toESM(require("react"));
42
+ var WebSocketContext = (0, import_react.createContext)(null);
44
43
  WebSocketContext.displayName = "WebSocketContext";
45
44
  var WebSocketConsumer = WebSocketContext.Consumer;
46
45
  function WebSocketProvider(p) {
47
46
  const clientRef = (0, import_react.useRef)(null);
48
- (0, import_react2.useEffect)(() => {
47
+ (0, import_react.useEffect)(() => {
49
48
  if (typeof window === "undefined") return;
50
49
  if (clientRef.current) {
51
50
  clientRef.current.close();
@@ -62,7 +61,7 @@ function WebSocketProvider(p) {
62
61
  return /* @__PURE__ */ import_react.default.createElement(WebSocketContext.Provider, { value: clientRef.current }, p.children);
63
62
  }
64
63
  function useWebSocket() {
65
- const context = (0, import_react2.useContext)(WebSocketContext);
64
+ const context = (0, import_react.useContext)(WebSocketContext);
66
65
  if (context === void 0)
67
66
  throw new Error("useWebSocket must be used within a WebSocketProvider");
68
67
  return context;
@@ -38,179 +38,237 @@ __export(server_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(server_exports);
40
40
 
41
+ // src/server/persistent.ts
42
+ function useGlobal(key) {
43
+ return [
44
+ function get() {
45
+ return Reflect.get(globalThis, key);
46
+ },
47
+ function set(value) {
48
+ return Reflect.set(globalThis, key, value);
49
+ },
50
+ function use(getter) {
51
+ const existing = Reflect.get(globalThis, key);
52
+ if (existing) return existing;
53
+ Reflect.set(globalThis, key, getter());
54
+ return Reflect.get(globalThis, key);
55
+ }
56
+ ];
57
+ }
58
+ var [getHttpServer, setHttpServer, useHttpServer] = (
59
+ //
60
+ useGlobal(
61
+ Symbol.for("next-ws.http-server")
62
+ //
63
+ )
64
+ );
65
+ var [getWebSocketServer, setWebSocketServer, useWebSocketServer] = (
66
+ //
67
+ useGlobal(
68
+ Symbol.for("next-ws.websocket-server")
69
+ //
70
+ )
71
+ );
72
+ var [getRequestStorage, setRequestStorage, useRequestStorage] = (
73
+ //
74
+ useGlobal(
75
+ Symbol.for("next-ws.request-store")
76
+ //
77
+ )
78
+ );
79
+
41
80
  // src/server/setup.ts
42
- var logger3 = __toESM(require("next/dist/build/output/log.js"), 1);
81
+ var import_node_async_hooks = require("async_hooks");
82
+ var logger2 = __toESM(require("next/dist/build/output/log.js"));
43
83
  var import_ws = require("ws");
44
84
 
45
- // src/server/helpers/persistent.ts
46
- var logger = __toESM(require("next/dist/build/output/log.js"), 1);
47
- function getEnvironmentMeta() {
48
- const isCustomServer = !process.title.startsWith("next-");
49
- const isMainProcess = process.env.NEXT_WS_MAIN_PROCESS === "1";
50
- const isDevelopment = process.env.NODE_ENV === "development";
51
- return { isCustomServer, isMainProcess, isDevelopment };
52
- }
53
- function mainProcessOnly(fnName) {
54
- if (process.env.NEXT_WS_SKIP_ENVIRONMENT_CHECK === "1") return;
55
- const meta = getEnvironmentMeta();
56
- if (!meta.isMainProcess) {
57
- throw new Error(
58
- `[next-ws] Attempt to invoke '${fnName}' outside the main process.
59
- You may be attempting to interact with the WebSocket server outside of a SOCKET handler. This will fail in production, as Next.js employs a worker process for routing, which do not have access to the WebSocket server on the main process.
60
- You can resolve this by using a custom server.`
61
- );
62
- } else if (!meta.isCustomServer) {
63
- logger.warnOnce(
64
- `[next-ws] Caution: The function '${fnName}' was invoked without a custom server.
65
- This could lead to unintended behaviour, especially if you're attempting to interact with the WebSocket server outside of a SOCKET handler.
66
- Please note, while such configurations might function during development, they will fail in production. This is because Next.js employs a worker process for routing in production, which do not have access to the WebSocket server on the main process.
67
- You can resolve this by using a custom server.`
68
- );
69
- }
70
- }
71
- var NextWsHttpServer = Symbol.for("NextWs_HttpServer");
72
- function setHttpServer(server) {
73
- Reflect.set(globalThis, NextWsHttpServer, server);
74
- }
75
- function getHttpServer() {
76
- mainProcessOnly("getHttpServer");
77
- return Reflect.get(globalThis, NextWsHttpServer);
78
- }
79
- function useHttpServer(server) {
80
- const existing = getHttpServer();
81
- if (existing) return existing;
82
- if (server) setHttpServer(server);
83
- return server;
84
- }
85
- var NextWsWebSocketServer = Symbol.for("NextWs_WebSocketServer");
86
- function setWebSocketServer(wsServer) {
87
- Reflect.set(globalThis, NextWsWebSocketServer, wsServer);
88
- }
89
- function getWebSocketServer() {
90
- mainProcessOnly("getWebSocketServer");
91
- return Reflect.get(globalThis, NextWsWebSocketServer);
92
- }
93
- function useWebSocketServer(wsServer) {
94
- const existing = getWebSocketServer();
95
- if (existing) return existing;
96
- if (wsServer) setWebSocketServer(wsServer);
97
- return wsServer;
98
- }
99
-
100
- // src/server/helpers/route.ts
101
- var import_node_url = require("url");
102
- var logger2 = __toESM(require("next/dist/build/output/log.js"), 1);
103
- function createRouteRegex(routePattern) {
85
+ // src/server/helpers/match.ts
86
+ function compileRoutePattern(routePattern) {
104
87
  const escapedPattern = routePattern.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
105
- const paramRegex = escapedPattern.replace(/\\\[([a-zA-Z0-9_]+)\\\]/g, "(?<$1>[^/]+)").replace(/\\\[(?:\\\.){3}([a-zA-Z0-9_]+)\\\]/g, "(?<rest_$1>.+)");
88
+ const paramRegex = escapedPattern.replace(/\\\[\\\[(?:\\\.){3}([a-z0-9_]+)\\\]\\\]/gi, "?(?<r_o_$1>.+)?").replace(/\\\[(?:\\\.){3}([a-z0-9_]+)\\\]/gi, "(?<r_$1>.+)").replace(/\\\[([a-z0-9_]+)\\\]/gi, "(?<$1>[^/]+)");
106
89
  return new RegExp(`^${paramRegex}$`);
107
90
  }
108
- function getRouteParams(routePattern, routePath) {
109
- const routeRegex = createRouteRegex(routePattern);
110
- const match = routePath.replace(/\/+$/, "").match(routeRegex);
91
+ function getRouteParams(routePattern, requestPathname) {
92
+ const routeRegex = compileRoutePattern(routePattern);
93
+ const match = requestPathname.replace(/\/+$/, "").match(routeRegex);
111
94
  if (!match) return null;
112
95
  if (!match.groups) return {};
113
96
  const params = {};
114
97
  for (let [k, v] of Object.entries(match.groups)) {
115
- if (k.startsWith("rest_")) {
116
- k = k.slice(5);
117
- v = v.split("/");
98
+ if (k.startsWith("r_")) {
99
+ const optional = k.startsWith("r_o_");
100
+ k = k.slice(optional ? 4 : 2);
101
+ v = v?.split("/");
118
102
  }
119
- Reflect.set(params, k, v);
103
+ if (v) Reflect.set(params, k, v);
120
104
  }
121
105
  return params;
122
106
  }
123
- function resolvePathToRoute(nextServer, requestPath) {
124
- const basePath = nextServer.serverOptions.conf.basePath;
125
- const routes = {
107
+ function findMatchingRoute(nextServer, requestPathname) {
108
+ const basePath = nextServer.serverOptions?.conf.basePath || "";
109
+ const appPathRoutes = {
126
110
  // @ts-expect-error - appPathRoutes is protected
127
111
  ...nextServer.appPathRoutes,
128
112
  // @ts-expect-error - getAppPathRoutes is protected
129
113
  ...nextServer.getAppPathRoutes()
130
114
  };
131
- let pathToRoute = null;
132
- for (const [routePath, [filePath]] of Object.entries(routes)) {
115
+ let matchedRoute = void 0;
116
+ for (const [routePath, [filePath]] of Object.entries(appPathRoutes)) {
117
+ if (!routePath || !filePath) continue;
133
118
  const realPath = `${basePath}${routePath}`;
134
- const routeParams = getRouteParams(realPath, requestPath);
135
- if (routeParams) pathToRoute = { filePath, routeParams };
119
+ const routeParams = getRouteParams(realPath, requestPathname);
120
+ if (routeParams) matchedRoute = { filename: filePath, params: routeParams };
136
121
  }
137
- return pathToRoute || null;
122
+ return matchedRoute;
138
123
  }
139
- async function importRouteModule(nextServer, filePath) {
124
+
125
+ // src/server/helpers/module.ts
126
+ var logger = __toESM(require("next/dist/build/output/log.js"));
127
+ async function importRouteModule(nextServer, filePathname) {
140
128
  try {
141
129
  if ("hotReloader" in nextServer) {
142
130
  await nextServer.hotReloader?.ensurePage({
143
- page: filePath,
131
+ page: filePathname,
144
132
  clientOnly: false
145
133
  });
146
134
  } else if ("ensurePage" in nextServer) {
147
- await nextServer.ensurePage({ page: filePath, clientOnly: false });
135
+ await nextServer.ensurePage({ page: filePathname, clientOnly: false });
148
136
  } else {
149
- logger2.warnOnce(
137
+ logger.warnOnce(
150
138
  "[next-ws] unable to ensure page, you may need to open the route in your browser first so Next.js compiles it"
151
139
  );
152
140
  }
153
141
  } catch {
154
142
  }
155
- const buildPagePath = nextServer.getPagePath(filePath);
156
- return importModule(buildPagePath);
157
- }
158
- async function importModule(modulePath) {
159
- const moduleUrl = (0, import_node_url.pathToFileURL)(modulePath).toString();
160
143
  try {
161
- return import(moduleUrl);
162
- } catch (requireError) {
163
- try {
164
- return require(modulePath);
165
- } catch (requireError2) {
166
- console.error(`Both import and require failed for ${modulePath}`);
167
- throw requireError2;
168
- }
144
+ const buildPagePath = nextServer.getPagePath(filePathname);
145
+ return (await require(buildPagePath)).routeModule;
146
+ } catch (cause) {
147
+ console.error(cause);
148
+ return void 0;
169
149
  }
170
150
  }
171
- async function getSocketHandler(routeModule) {
172
- if (routeModule.default instanceof Promise)
173
- return getSocketHandler(await routeModule.default);
174
- return routeModule?.default?.routeModule?.userland?.SOCKET ?? routeModule?.routeModule?.userland?.SOCKET ?? routeModule?.default?.handlers?.SOCKET ?? routeModule?.handlers?.SOCKET;
151
+
152
+ // src/server/helpers/request.ts
153
+ var import_server = require("next/server");
154
+ function toNextRequest(message) {
155
+ const controller = new AbortController();
156
+ const headers = new Headers(message.headers);
157
+ const protocol = "encrypted" in message.socket ? "https" : "http";
158
+ const url = `${protocol}://${headers.get("host")}${message.url}`;
159
+ message.once("aborted", () => controller.abort());
160
+ return new import_server.NextRequest(url, {
161
+ method: message.method,
162
+ headers,
163
+ body: message.method === "GET" || message.method === "HEAD" ? void 0 : message,
164
+ signal: controller.signal,
165
+ referrer: headers.get("referer") || void 0
166
+ });
167
+ }
168
+
169
+ // src/server/helpers/store.ts
170
+ var import_cookies = require("next/dist/compiled/@edge-runtime/cookies");
171
+ var ReadonlyHeaders = class extends Headers {
172
+ append() {
173
+ throw new Error("Headers are read-only");
174
+ }
175
+ set() {
176
+ throw new Error("Headers are read-only");
177
+ }
178
+ delete() {
179
+ throw new Error("Headers are read-only");
180
+ }
181
+ };
182
+ var ReadonlyRequestsCookies = class extends import_cookies.RequestCookies {
183
+ set() {
184
+ throw new Error("Cookies are read-only");
185
+ }
186
+ delete() {
187
+ throw new Error("Cookies are read-only");
188
+ }
189
+ };
190
+ function createRequestStore(request) {
191
+ return {
192
+ headers: new ReadonlyHeaders(request.headers),
193
+ cookies: new ReadonlyRequestsCookies(request.headers)
194
+ };
175
195
  }
176
196
 
177
197
  // src/server/setup.ts
178
198
  function setupWebSocketServer(nextServer) {
179
- process.env.NEXT_WS_MAIN_PROCESS = String(1);
180
- process.env.NEXT_WS_SKIP_ENVIRONMENT_CHECK = String(1);
181
- const httpServer = useHttpServer(nextServer.serverOptions?.httpServer);
182
- const wsServer = useWebSocketServer(new import_ws.WebSocketServer({ noServer: true }));
183
- process.env.NEXT_WS_SKIP_ENVIRONMENT_CHECK = String(0);
199
+ const httpServer = (
200
+ //
201
+ // @ts-expect-error - serverOptions is protected
202
+ useHttpServer(() => nextServer.serverOptions?.httpServer)
203
+ );
184
204
  if (!httpServer)
185
- return logger3.error("[next-ws] was not able to find the HTTP server");
186
- if (!wsServer)
187
- return logger3.error("[next-ws] was not able to find the WebSocket server");
188
- logger3.ready("[next-ws] has started the WebSocket server");
189
- httpServer.on("upgrade", async (request, socket, head) => {
190
- const url = new URL(request.url ?? "", "ws://next");
191
- const pathname = url.pathname;
205
+ return logger2.error("[next-ws] was not able to find the HTTP server");
206
+ const wsServer = (
207
+ //
208
+ useWebSocketServer(() => new import_ws.WebSocketServer({ noServer: true }))
209
+ );
210
+ const requestStorage = (
211
+ //
212
+ useRequestStorage(() => new import_node_async_hooks.AsyncLocalStorage())
213
+ );
214
+ logger2.ready("[next-ws] has started the WebSocket server");
215
+ const kAttached = Symbol.for("next-ws.http-server.attached");
216
+ if (Reflect.has(httpServer, kAttached)) return;
217
+ Reflect.set(httpServer, kAttached, true);
218
+ httpServer.on("upgrade", async (message, socket, head) => {
219
+ const request = toNextRequest(message);
220
+ const pathname = request.nextUrl.pathname;
192
221
  if (pathname.includes("/_next")) return;
193
- const routeInfo = resolvePathToRoute(nextServer, pathname);
194
- if (!routeInfo) {
195
- logger3.error(`[next-ws] could not find module for page ${pathname}`);
196
- return socket.destroy();
222
+ const route = findMatchingRoute(nextServer, pathname);
223
+ if (!route) {
224
+ logger2.error(`[next-ws] could not find route for page ${pathname}`);
225
+ return socket.end();
197
226
  }
198
- const routeModule = await importRouteModule(nextServer, routeInfo.filePath);
199
- if (!routeModule) {
200
- logger3.error(`[next-ws] could not find module for page ${pathname}`);
201
- return socket.destroy();
227
+ const module2 = await importRouteModule(nextServer, route.filename);
228
+ if (!module2) {
229
+ logger2.error(`[next-ws] could not import module for page ${pathname}`);
230
+ return socket.end();
202
231
  }
203
- const socketHandler = await getSocketHandler(routeModule);
204
- if (!socketHandler || typeof socketHandler !== "function") {
205
- logger3.error(`[next-ws] ${pathname} does not export a SOCKET handler`);
206
- return socket.destroy();
232
+ const handleUpgrade = module2.userland.UPGRADE;
233
+ const handleSocket = module2.userland.SOCKET;
234
+ if ((!handleUpgrade || typeof handleUpgrade !== "function") && (!handleSocket || typeof handleSocket !== "function")) {
235
+ logger2.error(`[next-ws] route '${pathname}' does not export a handler`);
236
+ return socket.end();
207
237
  }
208
- return wsServer.handleUpgrade(request, socket, head, async (c, r) => {
209
- const routeContext = { params: routeInfo.routeParams };
210
- const handleClose = await socketHandler(c, r, wsServer, routeContext);
211
- if (typeof handleClose === "function")
212
- c.once("close", () => handleClose());
238
+ if (handleSocket)
239
+ logger2.warnOnce(
240
+ "DeprecationWarning: [next-ws] SOCKET is deprecated, prefer UPGRADE instead, see https://github.com/apteryxxyz/next-ws#-usage"
241
+ );
242
+ wsServer.handleUpgrade(message, socket, head, async (client) => {
243
+ wsServer.emit("connection", client, message);
244
+ try {
245
+ const context = { params: route.params };
246
+ if (handleUpgrade) {
247
+ await requestStorage.run(
248
+ createRequestStore(request),
249
+ //
250
+ () => handleUpgrade(client, wsServer, request, context)
251
+ );
252
+ } else if (handleSocket) {
253
+ const handleClose = (
254
+ //
255
+ await handleSocket(client, message, wsServer, context)
256
+ );
257
+ if (typeof handleClose === "function")
258
+ client.once("close", () => handleClose());
259
+ }
260
+ } catch (cause) {
261
+ logger2.error(
262
+ `[next-ws] error in socket handler for '${pathname}'`,
263
+ cause
264
+ );
265
+ try {
266
+ client.close(1011, "Internal Server Error");
267
+ } catch {
268
+ }
269
+ }
213
270
  });
271
+ return;
214
272
  });
215
273
  }
216
274
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,32 +1,54 @@
1
+ import * as next_server from 'next/server';
2
+ import * as http from 'http';
3
+ import * as ws from 'ws';
1
4
  import NextNodeServer from 'next/dist/server/next-server.js';
2
- import { Server } from 'node:http';
3
- import { WebSocketServer } from 'ws';
4
-
5
- declare function setupWebSocketServer(nextServer: NextNodeServer): void;
6
5
 
7
6
  /**
8
- * Set the HTTP server that the WebSocket server should listen on, must be called before the WebSocket server is created.
9
- * @param server The HTTP server.
7
+ * WebSocket socket handler.
8
+ * @param client WebSocket client instance
9
+ * @param request Node.js HTTP incoming message instance
10
+ * @param server WebSocket server instance
11
+ * @param context Route context
12
+ * @deprecated Prefer UPGRADE and {@link UpgradeHandler}
13
+ */
14
+ type SocketHandler = (client: ws.WebSocket, request: http.IncomingMessage, server: ws.WebSocketServer, context: {
15
+ params: Record<string, string | string[]>;
16
+ }) => unknown;
17
+ /**
18
+ * WebSocket upgrade handler.
19
+ * @param client WebSocket client instance
20
+ * @param server WebSocket server instance
21
+ * @param request Next.js request instance
22
+ * @param context Route context
10
23
  */
11
- declare function setHttpServer(server: Server): void;
24
+ type UpgradeHandler = (client: ws.WebSocket, server: ws.WebSocketServer, request: next_server.NextRequest, context: RouteContext<string>) => unknown;
25
+
12
26
  /**
13
- * Get the HTTP server that the WebSocket server is listening on.
14
- * @remark If you want to access the HTTP server outside of a SOCKET handler, you must be using a custom server.
15
- * @returns The HTTP server.
16
- * @throws If attempting to access the HTTP server outside of the main process.
27
+ * Extract the parameters from a route pattern.
17
28
  */
18
- declare function getHttpServer(): Server;
29
+ type RouteParams<Pattern extends string> = Pattern extends `${infer Before}[[...${infer Param}]]${infer After}` ? RouteParams<Before> & {
30
+ [K in Param]?: string[];
31
+ } & RouteParams<After> : Pattern extends `${infer Before}[...${infer Param}]${infer After}` ? RouteParams<Before> & {
32
+ [K in Param]: string[];
33
+ } & RouteParams<After> : Pattern extends `${infer Before}[${infer Param}]${infer After}` ? RouteParams<Before> & {
34
+ [K in Param]: string;
35
+ } & RouteParams<After> : {};
19
36
  /**
20
- * Set the WebSocket server that the WebSocket server should listen on, must be called before the WebSocket server is created.
21
- * @param wsServer The WebSocket server.
37
+ * Route context object containing the parameters.
22
38
  */
23
- declare function setWebSocketServer(wsServer: WebSocketServer): void;
39
+ type RouteContext<Path extends string> = {
40
+ params: Record<string, string | string[] | undefined> & RouteParams<Path> & RouteParams<Path>;
41
+ };
42
+
43
+ declare const getHttpServer: () => http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
44
+ declare const setHttpServer: (value: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>) => boolean;
45
+ declare const getWebSocketServer: () => ws.WebSocketServer | undefined;
46
+ declare const setWebSocketServer: (value: ws.WebSocketServer) => boolean;
47
+
24
48
  /**
25
- * Get the WebSocket server that the WebSocket server is listening on.
26
- * @remark If you want to access the WebSocket server outside of a SOCKET handler, you must be using a custom server.
27
- * @returns The WebSocket server.
28
- * @throws If attempting to access the WebSocket server outside of the main process.
49
+ * Attach the WebSocket server to the HTTP server.
50
+ * @param nextServer Next.js Node server instance
29
51
  */
30
- declare function getWebSocketServer(): WebSocketServer;
52
+ declare function setupWebSocketServer(nextServer: NextNodeServer): void;
31
53
 
32
- export { getHttpServer, getWebSocketServer, setHttpServer, setWebSocketServer, setupWebSocketServer };
54
+ export { type RouteContext, type SocketHandler, type UpgradeHandler, getHttpServer, getWebSocketServer, setHttpServer, setWebSocketServer, setupWebSocketServer };
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "next-ws",
3
- "version": "2.0.13",
4
- "type": "module",
3
+ "version": "2.1.0",
5
4
  "description": "Add support for WebSockets in the Next.js app directory",
6
5
  "license": "MIT",
7
6
  "keywords": [
@@ -28,43 +27,49 @@
28
27
  "exports": {
29
28
  "./client": {
30
29
  "types": "./dist/client/index.d.ts",
31
- "import": "./dist/client/index.js",
32
- "require": "./dist/client/index.cjs"
30
+ "default": "./dist/client/index.cjs"
33
31
  },
34
32
  "./server": {
35
33
  "types": "./dist/server/index.d.ts",
36
- "import": "./dist/server/index.js",
37
- "require": "./dist/server/index.cjs"
34
+ "default": "./dist/server/index.cjs"
38
35
  },
39
36
  "./package.json": "./package.json"
40
37
  },
38
+ "dependencies": {
39
+ "jscodeshift": "^17.3.0",
40
+ "minimist": "^1.2.8",
41
+ "semver": "^7.7.2"
42
+ },
41
43
  "peerDependencies": {
42
- "next": ">=13.1.1",
44
+ "next": ">=13.5.1",
43
45
  "react": "*",
44
46
  "ws": "*"
45
47
  },
46
48
  "devDependencies": {
47
- "@biomejs/biome": "^1.9.4",
48
- "@changesets/changelog-git": "^0.2.0",
49
+ "@biomejs/biome": "^2.2.0",
50
+ "@changesets/changelog-git": "^0.2.1",
49
51
  "@changesets/cli": "^2.27.12",
50
- "@playwright/test": "^1.50.1",
52
+ "@favware/npm-deprecate": "^2.0.0",
53
+ "@playwright/test": "^1.55.0",
54
+ "@types/jscodeshift": "^17.3.0",
51
55
  "@types/minimist": "^1.2.5",
52
- "@types/node": "^22.13.1",
53
- "@types/react": "^19.0.8",
54
- "@types/semver": "^7.5.8",
55
- "@types/ws": "^8.5.14",
56
- "chalk": "^5.4.1",
56
+ "@types/node": "^24.3.0",
57
+ "@types/react": "19.1.10",
58
+ "@types/semver": "^7.7.0",
59
+ "@types/ws": "^8.18.1",
60
+ "chalk": "^5.6.0",
57
61
  "husky": "^9.1.7",
58
- "minimist": "^1.2.8",
62
+ "next": "15.5.0",
59
63
  "pinst": "^3.0.0",
60
- "semver": "^7.7.1",
61
- "tsup": "^8.3.6",
62
- "typescript": "^5.7.3"
64
+ "react": "19.1.1",
65
+ "react-dom": "19.1.1",
66
+ "tsup": "^8.5.0",
67
+ "typescript": "^5.9.2"
63
68
  },
64
69
  "scripts": {
70
+ "check": "tsc --noEmit",
65
71
  "lint": "biome ci .",
66
72
  "format": "biome check . --write",
67
- "check": "tsc --noEmit",
68
73
  "build": "tsup",
69
74
  "dev": "tsup --watch",
70
75
  "test": "playwright test",
@@ -1,10 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- export {
9
- __require
10
- };
@@ -1,27 +0,0 @@
1
- import React from 'react';
2
-
3
- declare const WebSocketContext: React.Context<WebSocket | null>;
4
- declare const WebSocketConsumer: React.Consumer<WebSocket | null>;
5
- /**
6
- * Provides a WebSocket client to its children via context,
7
- * allowing for easy access to the WebSocket from anywhere in the app.
8
- * @param props WebSocket parameters and children.
9
- * @returns JSX Element
10
- * @deprecated `WebSocketProvider` is deprecated, use your own implementation instead.
11
- */
12
- declare function WebSocketProvider(p: React.PropsWithChildren<{
13
- /** The URL for the WebSocket to connect to. */
14
- url: string;
15
- /** The subprotocols to use. */
16
- protocols?: string[] | string;
17
- /** The binary type to use. */
18
- binaryType?: BinaryType;
19
- }>): React.JSX.Element;
20
- /**
21
- * Access the websocket from anywhere in the app, so long as it's wrapped in a WebSocketProvider.
22
- * @returns WebSocket client when connected, null when disconnected.
23
- * @deprecated `useWebSocket` is deprecated, use your own implementation instead.
24
- */
25
- declare function useWebSocket(): WebSocket | null;
26
-
27
- export { WebSocketConsumer, WebSocketContext, WebSocketProvider, useWebSocket };
@@ -1,38 +0,0 @@
1
- import "../chunk-3RG5ZIWI.js";
2
-
3
- // src/client/context.tsx
4
- import React, { useRef } from "react";
5
- import { createContext, useContext, useEffect } from "react";
6
- var WebSocketContext = createContext(null);
7
- WebSocketContext.displayName = "WebSocketContext";
8
- var WebSocketConsumer = WebSocketContext.Consumer;
9
- function WebSocketProvider(p) {
10
- const clientRef = useRef(null);
11
- useEffect(() => {
12
- if (typeof window === "undefined") return;
13
- if (clientRef.current) {
14
- clientRef.current.close();
15
- clientRef.current = null;
16
- }
17
- const client = new WebSocket(p.url, p.protocols);
18
- if (p.binaryType) client.binaryType = p.binaryType;
19
- clientRef.current = client;
20
- return () => {
21
- client.close();
22
- clientRef.current = null;
23
- };
24
- }, [p.url, p.protocols, p.binaryType]);
25
- return /* @__PURE__ */ React.createElement(WebSocketContext.Provider, { value: clientRef.current }, p.children);
26
- }
27
- function useWebSocket() {
28
- const context = useContext(WebSocketContext);
29
- if (context === void 0)
30
- throw new Error("useWebSocket must be used within a WebSocketProvider");
31
- return context;
32
- }
33
- export {
34
- WebSocketConsumer,
35
- WebSocketContext,
36
- WebSocketProvider,
37
- useWebSocket
38
- };
@@ -1,32 +0,0 @@
1
- import NextNodeServer from 'next/dist/server/next-server.js';
2
- import { Server } from 'node:http';
3
- import { WebSocketServer } from 'ws';
4
-
5
- declare function setupWebSocketServer(nextServer: NextNodeServer): void;
6
-
7
- /**
8
- * Set the HTTP server that the WebSocket server should listen on, must be called before the WebSocket server is created.
9
- * @param server The HTTP server.
10
- */
11
- declare function setHttpServer(server: Server): void;
12
- /**
13
- * Get the HTTP server that the WebSocket server is listening on.
14
- * @remark If you want to access the HTTP server outside of a SOCKET handler, you must be using a custom server.
15
- * @returns The HTTP server.
16
- * @throws If attempting to access the HTTP server outside of the main process.
17
- */
18
- declare function getHttpServer(): Server;
19
- /**
20
- * Set the WebSocket server that the WebSocket server should listen on, must be called before the WebSocket server is created.
21
- * @param wsServer The WebSocket server.
22
- */
23
- declare function setWebSocketServer(wsServer: WebSocketServer): void;
24
- /**
25
- * Get the WebSocket server that the WebSocket server is listening on.
26
- * @remark If you want to access the WebSocket server outside of a SOCKET handler, you must be using a custom server.
27
- * @returns The WebSocket server.
28
- * @throws If attempting to access the WebSocket server outside of the main process.
29
- */
30
- declare function getWebSocketServer(): WebSocketServer;
31
-
32
- export { getHttpServer, getWebSocketServer, setHttpServer, setWebSocketServer, setupWebSocketServer };