next-ws 0.2.4 → 0.2.5-next.28f252e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ This module is inspired by the now outdated `next-plugin-websocket`, if you are
45
45
  In order to setup a WebSocket server, Next WS needs to patch your local Next.js installation. Next WS provides a CLI command to do this for you, it will automatically detect your Next.js version and patch it accordingly, however a minimum version of Next.js 13.1.1 is required.
46
46
 
47
47
  ```sh
48
- npx next-ws-cli patch
48
+ npx next-ws-cli@latest patch
49
49
  ```
50
50
 
51
51
  > If at any point your local Next.js installation is changed or updated you will need to re-run the patch command.
@@ -56,6 +56,16 @@ Once the patch is complete, you will need to install the Next WS package into yo
56
56
  npm install next-ws
57
57
  ```
58
58
 
59
+ ### 🚓 Verify Patch
60
+
61
+ It is recommended to add the following code to the top level of your `next.config.js`.
62
+
63
+ This will verify that Next WS has been patched correctly, and throw an error if it has not. Preventing you from accidentally deploying a broken setup.
64
+
65
+ ```ts
66
+ require('next-ws/server').verifyPatch();
67
+ ```
68
+
59
69
  ---
60
70
 
61
71
  ## 🚀 Usage
@@ -76,16 +86,6 @@ export function SOCKET(
76
86
 
77
87
  With this straightforward setup, you can fully leverage the capabilities of Next WS and efficiently handle WebSocket connections within your Next.js application.
78
88
 
79
- ### 🚓 Verify Patch
80
-
81
- It is recommended to add the following code to the top level of your `next.config.js`.
82
-
83
- This will verify that Next WS has been patched correctly, and throw an error if it has not. Preventing you from accidentally deploying a broken setup.
84
-
85
- ```ts
86
- require('next-ws/server').verifyPatch();
87
- ```
88
-
89
89
  ---
90
90
 
91
91
  ## 🌀 Example
@@ -135,6 +135,8 @@ export default function Layout() {
135
135
  }
136
136
  ```
137
137
 
138
+ To make it easier to connect to your new WebSocker server, Next WS also provides some client-side utilities. These are completely optional, you can use your own implementation if you wish.
139
+
138
140
  The following is the props interface for the `WebSocketProvider` component, containing all the available options.
139
141
 
140
142
  ```ts
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "next-ws",
3
- "version": "0.2.4",
3
+ "version": "0.2.5-next.28f252e",
4
4
  "description": "Add support for WebSockets in Next.js 13 app directory",
5
- "keywords": ["next", "websocket", "ws", "server", "client"],
5
+ "keywords": [
6
+ "next",
7
+ "websocket",
8
+ "ws",
9
+ "server",
10
+ "client"
11
+ ],
6
12
  "license": "MIT",
7
13
  "homepage": "https://github.com/apteryxxyz/next-ws#readme",
8
14
  "repository": {
@@ -13,7 +19,12 @@
13
19
  "bugs": {
14
20
  "url": "https://github.com/apteryxxyz/next-ws/issues"
15
21
  },
16
- "files": ["index.js", "index.d.ts", "client", "server"],
22
+ "files": [
23
+ "index.js",
24
+ "index.d.ts",
25
+ "client",
26
+ "server"
27
+ ],
17
28
  "main": "./index.js",
18
29
  "types": "./index.d.ts",
19
30
  "scripts": {
@@ -43,4 +54,4 @@
43
54
  "rimraf": "^5.0.1",
44
55
  "typescript": "<5.1.0"
45
56
  }
46
- }
57
+ }
package/server/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './utilities/patch';
2
2
  export type { SocketHandler } from './utilities/next';
3
+ export type * from './utilities/ws';
3
4
  export * from './setup';
package/server/setup.js CHANGED
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hookNextNodeServer = exports.setupWebSocketServer = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const Log = tslib_1.__importStar(require("next/dist/build/output/log"));
6
- const ws_1 = require("ws");
7
6
  const next_1 = require("./utilities/next");
7
+ const ws_1 = require("./utilities/ws");
8
8
  function setupWebSocketServer(nextServer) {
9
9
  const httpServer = (0, next_1.getHttpServer)(nextServer);
10
- const wsServer = new ws_1.WebSocketServer({ noServer: true });
10
+ const wsServer = (0, ws_1.getWsServer)();
11
11
  Log.ready('[next-ws] websocket server started successfully');
12
12
  httpServer.on('upgrade', async (request, socket, head) => {
13
- const url = new URL(request.url ?? '', 'http://next-ws');
13
+ const url = new URL(request.url ?? '', 'ws://next');
14
14
  const pathname = url.pathname;
15
15
  if (pathname.startsWith('/_next'))
16
16
  return;
@@ -13,7 +13,7 @@ const next_server_1 = tslib_1.__importDefault(require("next/dist/server/next-ser
13
13
  function getHttpServer(nextServer) {
14
14
  if (!nextServer || !(nextServer instanceof next_server_1.default))
15
15
  throw new Error('Next WS is missing access to the NextNodeServer');
16
- // @ts-expect-error serverOptions is protected
16
+ // @ts-expect-error - serverOptions is protected
17
17
  const httpServer = nextServer.serverOptions?.httpServer;
18
18
  if (!httpServer || !(httpServer instanceof node_http_1.Server))
19
19
  throw new Error('Next WS is missing access to the http.Server');
@@ -29,18 +29,41 @@ exports.getHttpServer = getHttpServer;
29
29
  async function resolvePathname(nextServer, pathname) {
30
30
  if (pathname.startsWith('/_next'))
31
31
  return null;
32
+ const pathParts = pathname.split('/');
32
33
  const appRoutes = {
33
- // @ts-expect-error appPathRoutes is protected
34
+ // @ts-expect-error - appPathRoutes is protected
34
35
  ...nextServer.appPathRoutes,
35
- // @ts-expect-error getAppPathRoutes is protected
36
+ // @ts-expect-error - getAppPathRoutes is protected
36
37
  ...nextServer.getAppPathRoutes(),
37
38
  };
38
- // TODO: 'appRoutes[pathname]' is an array of routes, need to investigate in which case that array has more than one item
39
- if (pathname in appRoutes) {
40
- const route = appRoutes[pathname][0];
41
- if (!route?.endsWith('/route'))
42
- return null;
43
- return route;
39
+ for (const [key, [path]] of Object.entries(appRoutes)) {
40
+ const hasDynamic = key.includes('[') && key.includes(']');
41
+ if (hasDynamic) {
42
+ const keyParts = key.split('/');
43
+ if (keyParts.length !== pathParts.length)
44
+ continue;
45
+ for (let i = 0; i < keyParts.length; i++) {
46
+ const keyPart = keyParts[i];
47
+ const pathPart = pathParts[i];
48
+ const isDynamic = keyPart.includes('[') && keyPart.includes(']');
49
+ if (isDynamic)
50
+ keyParts[i] = pathPart;
51
+ if (keyParts[i] !== pathParts[i])
52
+ break;
53
+ if (i === keyParts.length - 1) {
54
+ if (!path?.endsWith('/route'))
55
+ return null;
56
+ return path;
57
+ }
58
+ }
59
+ }
60
+ else {
61
+ if (key !== pathname)
62
+ continue;
63
+ if (!path?.endsWith('/route'))
64
+ return null;
65
+ return path;
66
+ }
44
67
  }
45
68
  return null;
46
69
  }
@@ -52,12 +75,12 @@ exports.resolvePathname = resolvePathname;
52
75
  * @returns The page module.
53
76
  */
54
77
  async function getPageModule(nextServer, filename) {
55
- // @ts-expect-error HotReloader is private
78
+ // @ts-expect-error - hotReloader is private
56
79
  await nextServer.hotReloader?.ensurePage({
57
80
  page: filename,
58
81
  clientOnly: false,
59
82
  });
60
- // @ts-expect-error getPagePath is protected
83
+ // @ts-expect-error - getPagePath is protected
61
84
  const builtPagePath = nextServer.getPagePath(filename);
62
85
  return require(builtPagePath);
63
86
  }
@@ -0,0 +1,7 @@
1
+ /// <reference types="ws" />
2
+ /// <reference types="node" />
3
+ /**
4
+ * Get the WebSocketServer instance.
5
+ * @returns The WebSocketServer instance.
6
+ */
7
+ export declare function getWsServer(): import("ws").Server<typeof import("ws"), typeof import("http").IncomingMessage>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWsServer = void 0;
4
+ const ws_1 = require("ws");
5
+ /**
6
+ * Get the WebSocketServer instance.
7
+ * @returns The WebSocketServer instance.
8
+ */
9
+ // prettier-ignore
10
+ function getWsServer() {
11
+ return new ws_1.WebSocketServer({ noServer: true });
12
+ }
13
+ exports.getWsServer = getWsServer;