@callstack/repack-dev-server 0.0.0-canary-20240602190113
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/CHANGELOG.md +140 -0
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/createServer.d.ts +13 -0
- package/dist/createServer.js +147 -0
- package/dist/createServer.js.map +1 -0
- package/dist/img/favicon.ico +0 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/api/apiPlugin.d.ts +6 -0
- package/dist/plugins/api/apiPlugin.js +32 -0
- package/dist/plugins/api/apiPlugin.js.map +1 -0
- package/dist/plugins/api/index.d.ts +1 -0
- package/dist/plugins/api/index.js +2 -0
- package/dist/plugins/api/index.js.map +1 -0
- package/dist/plugins/compiler/compilerPlugin.d.ts +7 -0
- package/dist/plugins/compiler/compilerPlugin.js +75 -0
- package/dist/plugins/compiler/compilerPlugin.js.map +1 -0
- package/dist/plugins/compiler/index.d.ts +2 -0
- package/dist/plugins/compiler/index.js +3 -0
- package/dist/plugins/compiler/index.js.map +1 -0
- package/dist/plugins/compiler/types.d.ts +31 -0
- package/dist/plugins/compiler/types.js +2 -0
- package/dist/plugins/compiler/types.js.map +1 -0
- package/dist/plugins/devtools/devtoolsPlugin.d.ts +7 -0
- package/dist/plugins/devtools/devtoolsPlugin.js +47 -0
- package/dist/plugins/devtools/devtoolsPlugin.js.map +1 -0
- package/dist/plugins/devtools/index.d.ts +1 -0
- package/dist/plugins/devtools/index.js +2 -0
- package/dist/plugins/devtools/index.js.map +1 -0
- package/dist/plugins/favicon/faviconPlugin.d.ts +4 -0
- package/dist/plugins/favicon/faviconPlugin.js +17 -0
- package/dist/plugins/favicon/faviconPlugin.js.map +1 -0
- package/dist/plugins/favicon/index.d.ts +1 -0
- package/dist/plugins/favicon/index.js +2 -0
- package/dist/plugins/favicon/index.js.map +1 -0
- package/dist/plugins/multipart/index.d.ts +2 -0
- package/dist/plugins/multipart/index.js +3 -0
- package/dist/plugins/multipart/index.js.map +1 -0
- package/dist/plugins/multipart/multipartPlugin.d.ts +4 -0
- package/dist/plugins/multipart/multipartPlugin.js +55 -0
- package/dist/plugins/multipart/multipartPlugin.js.map +1 -0
- package/dist/plugins/multipart/types.d.ts +12 -0
- package/dist/plugins/multipart/types.js +2 -0
- package/dist/plugins/multipart/types.js.map +1 -0
- package/dist/plugins/symbolicate/Symbolicator.d.ts +46 -0
- package/dist/plugins/symbolicate/Symbolicator.js +208 -0
- package/dist/plugins/symbolicate/Symbolicator.js.map +1 -0
- package/dist/plugins/symbolicate/index.d.ts +3 -0
- package/dist/plugins/symbolicate/index.js +4 -0
- package/dist/plugins/symbolicate/index.js.map +1 -0
- package/dist/plugins/symbolicate/sybmolicatePlugin.d.ts +7 -0
- package/dist/plugins/symbolicate/sybmolicatePlugin.js +44 -0
- package/dist/plugins/symbolicate/sybmolicatePlugin.js.map +1 -0
- package/dist/plugins/symbolicate/types.d.ts +65 -0
- package/dist/plugins/symbolicate/types.js +2 -0
- package/dist/plugins/symbolicate/types.js.map +1 -0
- package/dist/plugins/wss/WebSocketRouter.d.ts +32 -0
- package/dist/plugins/wss/WebSocketRouter.js +57 -0
- package/dist/plugins/wss/WebSocketRouter.js.map +1 -0
- package/dist/plugins/wss/WebSocketServer.d.ts +38 -0
- package/dist/plugins/wss/WebSocketServer.js +45 -0
- package/dist/plugins/wss/WebSocketServer.js.map +1 -0
- package/dist/plugins/wss/WebSocketServerAdapter.d.ts +16 -0
- package/dist/plugins/wss/WebSocketServerAdapter.js +22 -0
- package/dist/plugins/wss/WebSocketServerAdapter.js.map +1 -0
- package/dist/plugins/wss/index.d.ts +3 -0
- package/dist/plugins/wss/index.js +4 -0
- package/dist/plugins/wss/index.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketApiServer.d.ts +32 -0
- package/dist/plugins/wss/servers/WebSocketApiServer.js +62 -0
- package/dist/plugins/wss/servers/WebSocketApiServer.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketDebuggerServer.d.ts +64 -0
- package/dist/plugins/wss/servers/WebSocketDebuggerServer.js +142 -0
- package/dist/plugins/wss/servers/WebSocketDebuggerServer.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketDevClientServer.d.ts +32 -0
- package/dist/plugins/wss/servers/WebSocketDevClientServer.js +86 -0
- package/dist/plugins/wss/servers/WebSocketDevClientServer.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketEventsServer.d.ts +75 -0
- package/dist/plugins/wss/servers/WebSocketEventsServer.js +180 -0
- package/dist/plugins/wss/servers/WebSocketEventsServer.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketHMRServer.d.ts +38 -0
- package/dist/plugins/wss/servers/WebSocketHMRServer.js +89 -0
- package/dist/plugins/wss/servers/WebSocketHMRServer.js.map +1 -0
- package/dist/plugins/wss/servers/WebSocketMessageServer.d.ts +140 -0
- package/dist/plugins/wss/servers/WebSocketMessageServer.js +350 -0
- package/dist/plugins/wss/servers/WebSocketMessageServer.js.map +1 -0
- package/dist/plugins/wss/types.d.ts +25 -0
- package/dist/plugins/wss/types.js +2 -0
- package/dist/plugins/wss/types.js.map +1 -0
- package/dist/plugins/wss/wssPlugin.d.ts +31 -0
- package/dist/plugins/wss/wssPlugin.js +56 -0
- package/dist/plugins/wss/wssPlugin.js.map +1 -0
- package/dist/types.d.ts +165 -0
- package/dist/types.js +24 -0
- package/dist/types.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/plugins/symbolicate/types.ts"],"sourcesContent":["/**\n * Raw React Native stack frame.\n */\nexport interface ReactNativeStackFrame {\n lineNumber: number | null;\n column: number | null;\n file: string | null;\n methodName: string;\n}\n\n/**\n * React Native stack frame used as input when processing by {@link Symbolicator}.\n */\nexport interface InputStackFrame extends ReactNativeStackFrame {\n file: string;\n}\n\n/**\n * Final symbolicated stack frame.\n */\nexport interface StackFrame extends InputStackFrame {\n collapse: boolean;\n}\n\n/**\n * Represents [@babel/core-frame](https://babeljs.io/docs/en/babel-code-frame).\n */\nexport interface CodeFrame {\n content: string;\n location: {\n row: number;\n column: number;\n };\n fileName: string;\n}\n\n/**\n * Represents results of running {@link process} method on {@link Symbolicator} instance.\n */\nexport interface SymbolicatorResults {\n codeFrame: CodeFrame | null;\n stack: StackFrame[];\n}\n\n/**\n * Delegate with implementation for symbolication functions.\n */\nexport interface SymbolicatorDelegate {\n /**\n * Get source code of file in the URL.\n *\n * @param fileUrl A full URL pointing to a file.\n */\n getSource: (fileUrl: string) => Promise<string | Buffer>;\n\n /**\n * Get source map for the file in the URL.\n *\n * @param fileUrl A full (usually `http:`) URL pointing to a compiled file.\n * The URL points to a file for which to return source map, not to the source map file itself,\n * e.g: `http://localhost:8081/index.bundle?platform=ios`.\n */\n getSourceMap: (fileUrl: string) => Promise<string | Buffer>;\n\n /**\n * Check if given stack frame should be included in the new symbolicated stack.\n *\n * @param frame Stack frame to check.\n */\n shouldIncludeFrame: (frame: StackFrame) => boolean;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import { WebSocketServerInterface } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Class for creating a WebSocket router to forward connections to the
|
|
5
|
+
* respective {@link WebSocketServer} as long as the connection is accepted for the upgrade by the
|
|
6
|
+
* server.
|
|
7
|
+
*
|
|
8
|
+
* If the connection is not accepted by any `WebSocketServer`, it will be destroyed to avoid
|
|
9
|
+
* creating handling connections and potentially throwing `ECONNRESET` errors.
|
|
10
|
+
*
|
|
11
|
+
* @category Development server
|
|
12
|
+
*/
|
|
13
|
+
export declare class WebSocketRouter {
|
|
14
|
+
private fastify;
|
|
15
|
+
/** The list of all register WebSocket servers. */
|
|
16
|
+
protected servers: WebSocketServerInterface[];
|
|
17
|
+
/**
|
|
18
|
+
* Create new instance of `WebSocketRouter` and attach it to the given Fastify instance.
|
|
19
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
20
|
+
*
|
|
21
|
+
* @param fastify Fastify instance to attach the WebSocket router to.
|
|
22
|
+
*/
|
|
23
|
+
constructor(fastify: FastifyInstance);
|
|
24
|
+
/**
|
|
25
|
+
* Register a new {@link WebSocketServer}. New connection will now
|
|
26
|
+
* check if the given server will accept them and forward them.
|
|
27
|
+
*
|
|
28
|
+
* @param server WebSocket server to register.
|
|
29
|
+
* @returns The same instance of the WebSocket server after it's been registered.
|
|
30
|
+
*/
|
|
31
|
+
registerServer<T extends WebSocketServerInterface>(server: T): T;
|
|
32
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class for creating a WebSocket router to forward connections to the
|
|
3
|
+
* respective {@link WebSocketServer} as long as the connection is accepted for the upgrade by the
|
|
4
|
+
* server.
|
|
5
|
+
*
|
|
6
|
+
* If the connection is not accepted by any `WebSocketServer`, it will be destroyed to avoid
|
|
7
|
+
* creating handling connections and potentially throwing `ECONNRESET` errors.
|
|
8
|
+
*
|
|
9
|
+
* @category Development server
|
|
10
|
+
*/
|
|
11
|
+
export class WebSocketRouter {
|
|
12
|
+
/** The list of all register WebSocket servers. */
|
|
13
|
+
servers = [];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create new instance of `WebSocketRouter` and attach it to the given Fastify instance.
|
|
17
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
18
|
+
*
|
|
19
|
+
* @param fastify Fastify instance to attach the WebSocket router to.
|
|
20
|
+
*/
|
|
21
|
+
constructor(fastify) {
|
|
22
|
+
this.fastify = fastify;
|
|
23
|
+
this.fastify.server.on('upgrade', (request, socket, head) => {
|
|
24
|
+
const {
|
|
25
|
+
pathname
|
|
26
|
+
} = new URL(request.url || '', 'http://localhost');
|
|
27
|
+
let matched = false;
|
|
28
|
+
for (const server of this.servers) {
|
|
29
|
+
if (server.shouldUpgrade(pathname)) {
|
|
30
|
+
matched = true;
|
|
31
|
+
server.upgrade(request, socket, head);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (!matched) {
|
|
36
|
+
this.fastify.log.debug({
|
|
37
|
+
msg: 'Destroying socket connection as no server was matched',
|
|
38
|
+
pathname
|
|
39
|
+
});
|
|
40
|
+
socket.destroy();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Register a new {@link WebSocketServer}. New connection will now
|
|
47
|
+
* check if the given server will accept them and forward them.
|
|
48
|
+
*
|
|
49
|
+
* @param server WebSocket server to register.
|
|
50
|
+
* @returns The same instance of the WebSocket server after it's been registered.
|
|
51
|
+
*/
|
|
52
|
+
registerServer(server) {
|
|
53
|
+
this.servers.push(server);
|
|
54
|
+
return server;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=WebSocketRouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketRouter.js","names":["WebSocketRouter","servers","constructor","fastify","server","on","request","socket","head","pathname","URL","url","matched","shouldUpgrade","upgrade","log","debug","msg","destroy","registerServer","push"],"sources":["../../../src/plugins/wss/WebSocketRouter.ts"],"sourcesContent":["import type { IncomingMessage } from 'node:http';\nimport type { Socket } from 'node:net';\nimport type { FastifyInstance } from 'fastify';\nimport { WebSocketServerInterface } from './types';\n\n/**\n * Class for creating a WebSocket router to forward connections to the\n * respective {@link WebSocketServer} as long as the connection is accepted for the upgrade by the\n * server.\n *\n * If the connection is not accepted by any `WebSocketServer`, it will be destroyed to avoid\n * creating handling connections and potentially throwing `ECONNRESET` errors.\n *\n * @category Development server\n */\nexport class WebSocketRouter {\n /** The list of all register WebSocket servers. */\n protected servers: WebSocketServerInterface[] = [];\n\n /**\n * Create new instance of `WebSocketRouter` and attach it to the given Fastify instance.\n * Any logging information, will be passed through standard `fastify.log` API.\n *\n * @param fastify Fastify instance to attach the WebSocket router to.\n */\n constructor(private fastify: FastifyInstance) {\n this.fastify.server.on(\n 'upgrade',\n (request: IncomingMessage, socket: Socket, head: Buffer) => {\n const { pathname } = new URL(request.url || '', 'http://localhost');\n let matched = false;\n for (const server of this.servers) {\n if (server.shouldUpgrade(pathname)) {\n matched = true;\n server.upgrade(request, socket, head);\n break;\n }\n }\n\n if (!matched) {\n this.fastify.log.debug({\n msg: 'Destroying socket connection as no server was matched',\n pathname,\n });\n socket.destroy();\n }\n }\n );\n }\n\n /**\n * Register a new {@link WebSocketServer}. New connection will now\n * check if the given server will accept them and forward them.\n *\n * @param server WebSocket server to register.\n * @returns The same instance of the WebSocket server after it's been registered.\n */\n registerServer<T extends WebSocketServerInterface>(server: T): T {\n this.servers.push(server);\n return server;\n }\n}\n"],"mappings":"AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,eAAe,CAAC;EAC3B;EACUC,OAAO,GAA+B,EAAE;;EAElD;AACF;AACA;AACA;AACA;AACA;EACEC,WAAWA,CAASC,OAAwB,EAAE;IAAA,KAA1BA,OAAwB,GAAxBA,OAAwB;IAC1C,IAAI,CAACA,OAAO,CAACC,MAAM,CAACC,EAAE,CACpB,SAAS,EACT,CAACC,OAAwB,EAAEC,MAAc,EAAEC,IAAY,KAAK;MAC1D,MAAM;QAAEC;MAAS,CAAC,GAAG,IAAIC,GAAG,CAACJ,OAAO,CAACK,GAAG,IAAI,EAAE,EAAE,kBAAkB,CAAC;MACnE,IAAIC,OAAO,GAAG,KAAK;MACnB,KAAK,MAAMR,MAAM,IAAI,IAAI,CAACH,OAAO,EAAE;QACjC,IAAIG,MAAM,CAACS,aAAa,CAACJ,QAAQ,CAAC,EAAE;UAClCG,OAAO,GAAG,IAAI;UACdR,MAAM,CAACU,OAAO,CAACR,OAAO,EAAEC,MAAM,EAAEC,IAAI,CAAC;UACrC;QACF;MACF;MAEA,IAAI,CAACI,OAAO,EAAE;QACZ,IAAI,CAACT,OAAO,CAACY,GAAG,CAACC,KAAK,CAAC;UACrBC,GAAG,EAAE,uDAAuD;UAC5DR;QACF,CAAC,CAAC;QACFF,MAAM,CAACW,OAAO,CAAC,CAAC;MAClB;IACF,CACF,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEC,cAAcA,CAAqCf,MAAS,EAAK;IAC/D,IAAI,CAACH,OAAO,CAACmB,IAAI,CAAChB,MAAM,CAAC;IACzB,OAAOA,MAAM;EACf;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import type { IncomingMessage } from 'http';
|
|
5
|
+
import type { Socket } from 'net';
|
|
6
|
+
import type { FastifyInstance } from 'fastify';
|
|
7
|
+
import { ServerOptions, WebSocket, WebSocketServer as WebSocketServerImpl } from 'ws';
|
|
8
|
+
import { WebSocketServerInterface } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Abstract class for providing common logic (eg routing) for all WebSocket servers.
|
|
11
|
+
*
|
|
12
|
+
* @category Development server
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class WebSocketServer implements WebSocketServerInterface {
|
|
15
|
+
/** An instance of the underlying WebSocket server. */
|
|
16
|
+
protected server: WebSocketServerImpl;
|
|
17
|
+
/** Fastify instance from which {@link server} will receive upgrade connections. */
|
|
18
|
+
protected fastify: FastifyInstance;
|
|
19
|
+
protected paths: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Create a new instance of the WebSocketServer.
|
|
22
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
23
|
+
*
|
|
24
|
+
* @param fastify Fastify instance to which the WebSocket will be attached to.
|
|
25
|
+
* @param path Path on which this WebSocketServer will be accepting connections.
|
|
26
|
+
* @param wssOptions WebSocket Server options.
|
|
27
|
+
*/
|
|
28
|
+
constructor(fastify: FastifyInstance, path: string | string[], wssOptions?: Omit<ServerOptions, 'noServer' | 'server' | 'host' | 'port' | 'path'>);
|
|
29
|
+
shouldUpgrade(pathname: string): boolean;
|
|
30
|
+
upgrade(request: IncomingMessage, socket: Socket, head: Buffer): void;
|
|
31
|
+
/**
|
|
32
|
+
* Process incoming WebSocket connection.
|
|
33
|
+
*
|
|
34
|
+
* @param socket Incoming WebSocket connection.
|
|
35
|
+
* @param request Upgrade request for the connection.
|
|
36
|
+
*/
|
|
37
|
+
abstract onConnection(socket: WebSocket, request: IncomingMessage): void;
|
|
38
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { WebSocketServer as WebSocketServerImpl } from 'ws';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract class for providing common logic (eg routing) for all WebSocket servers.
|
|
4
|
+
*
|
|
5
|
+
* @category Development server
|
|
6
|
+
*/
|
|
7
|
+
export class WebSocketServer {
|
|
8
|
+
/** An instance of the underlying WebSocket server. */
|
|
9
|
+
|
|
10
|
+
/** Fastify instance from which {@link server} will receive upgrade connections. */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a new instance of the WebSocketServer.
|
|
14
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
15
|
+
*
|
|
16
|
+
* @param fastify Fastify instance to which the WebSocket will be attached to.
|
|
17
|
+
* @param path Path on which this WebSocketServer will be accepting connections.
|
|
18
|
+
* @param wssOptions WebSocket Server options.
|
|
19
|
+
*/
|
|
20
|
+
constructor(fastify, path, wssOptions = {}) {
|
|
21
|
+
this.fastify = fastify;
|
|
22
|
+
this.server = new WebSocketServerImpl({
|
|
23
|
+
noServer: true,
|
|
24
|
+
...wssOptions
|
|
25
|
+
});
|
|
26
|
+
this.server.on('connection', this.onConnection.bind(this));
|
|
27
|
+
this.paths = Array.isArray(path) ? path : [path];
|
|
28
|
+
}
|
|
29
|
+
shouldUpgrade(pathname) {
|
|
30
|
+
return this.paths.includes(pathname);
|
|
31
|
+
}
|
|
32
|
+
upgrade(request, socket, head) {
|
|
33
|
+
this.server.handleUpgrade(request, socket, head, webSocket => {
|
|
34
|
+
this.server.emit('connection', webSocket, request);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Process incoming WebSocket connection.
|
|
40
|
+
*
|
|
41
|
+
* @param socket Incoming WebSocket connection.
|
|
42
|
+
* @param request Upgrade request for the connection.
|
|
43
|
+
*/
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=WebSocketServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketServer.js","names":["WebSocketServer","WebSocketServerImpl","constructor","fastify","path","wssOptions","server","noServer","on","onConnection","bind","paths","Array","isArray","shouldUpgrade","pathname","includes","upgrade","request","socket","head","handleUpgrade","webSocket","emit"],"sources":["../../../src/plugins/wss/WebSocketServer.ts"],"sourcesContent":["import type { IncomingMessage } from 'http';\nimport type { Socket } from 'net';\nimport type { FastifyInstance } from 'fastify';\nimport {\n ServerOptions,\n WebSocket,\n WebSocketServer as WebSocketServerImpl,\n} from 'ws';\nimport { WebSocketServerInterface } from './types';\n\n/**\n * Abstract class for providing common logic (eg routing) for all WebSocket servers.\n *\n * @category Development server\n */\nexport abstract class WebSocketServer implements WebSocketServerInterface {\n /** An instance of the underlying WebSocket server. */\n protected server: WebSocketServerImpl;\n\n /** Fastify instance from which {@link server} will receive upgrade connections. */\n protected fastify: FastifyInstance;\n\n protected paths: string[];\n\n /**\n * Create a new instance of the WebSocketServer.\n * Any logging information, will be passed through standard `fastify.log` API.\n *\n * @param fastify Fastify instance to which the WebSocket will be attached to.\n * @param path Path on which this WebSocketServer will be accepting connections.\n * @param wssOptions WebSocket Server options.\n */\n constructor(\n fastify: FastifyInstance,\n path: string | string[],\n wssOptions: Omit<\n ServerOptions,\n 'noServer' | 'server' | 'host' | 'port' | 'path'\n > = {}\n ) {\n this.fastify = fastify;\n this.server = new WebSocketServerImpl({ noServer: true, ...wssOptions });\n this.server.on('connection', this.onConnection.bind(this));\n this.paths = Array.isArray(path) ? path : [path];\n }\n\n shouldUpgrade(pathname: string) {\n return this.paths.includes(pathname);\n }\n\n upgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this.server.handleUpgrade(request, socket, head, (webSocket) => {\n this.server.emit('connection', webSocket, request);\n });\n }\n\n /**\n * Process incoming WebSocket connection.\n *\n * @param socket Incoming WebSocket connection.\n * @param request Upgrade request for the connection.\n */\n abstract onConnection(socket: WebSocket, request: IncomingMessage): void;\n}\n"],"mappings":"AAGA,SAGEA,eAAe,IAAIC,mBAAmB,QACjC,IAAI;AAGX;AACA;AACA;AACA;AACA;AACA,OAAO,MAAeD,eAAe,CAAqC;EACxE;;EAGA;;EAKA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEE,WAAWA,CACTC,OAAwB,EACxBC,IAAuB,EACvBC,UAGC,GAAG,CAAC,CAAC,EACN;IACA,IAAI,CAACF,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACG,MAAM,GAAG,IAAIL,mBAAmB,CAAC;MAAEM,QAAQ,EAAE,IAAI;MAAE,GAAGF;IAAW,CAAC,CAAC;IACxE,IAAI,CAACC,MAAM,CAACE,EAAE,CAAC,YAAY,EAAE,IAAI,CAACC,YAAY,CAACC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAACC,KAAK,GAAGC,KAAK,CAACC,OAAO,CAACT,IAAI,CAAC,GAAGA,IAAI,GAAG,CAACA,IAAI,CAAC;EAClD;EAEAU,aAAaA,CAACC,QAAgB,EAAE;IAC9B,OAAO,IAAI,CAACJ,KAAK,CAACK,QAAQ,CAACD,QAAQ,CAAC;EACtC;EAEAE,OAAOA,CAACC,OAAwB,EAAEC,MAAc,EAAEC,IAAY,EAAE;IAC9D,IAAI,CAACd,MAAM,CAACe,aAAa,CAACH,OAAO,EAAEC,MAAM,EAAEC,IAAI,EAAGE,SAAS,IAAK;MAC9D,IAAI,CAAChB,MAAM,CAACiB,IAAI,CAAC,YAAY,EAAED,SAAS,EAAEJ,OAAO,CAAC;IACpD,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;AACA;AACA;AAEA","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import type { IncomingMessage } from 'node:http';
|
|
5
|
+
import type { Socket } from 'node:net';
|
|
6
|
+
import type { FastifyInstance } from 'fastify';
|
|
7
|
+
import type { WebSocketServer as WebSocketServer } from 'ws';
|
|
8
|
+
import type { WebSocketServerInterface } from './types';
|
|
9
|
+
export declare class WebSocketServerAdapter implements WebSocketServerInterface {
|
|
10
|
+
private fastify;
|
|
11
|
+
private path;
|
|
12
|
+
private server?;
|
|
13
|
+
constructor(fastify: FastifyInstance, path: string, server?: WebSocketServer | undefined);
|
|
14
|
+
shouldUpgrade(pathname: string): boolean;
|
|
15
|
+
upgrade(request: IncomingMessage, socket: Socket, head: Buffer): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class WebSocketServerAdapter {
|
|
2
|
+
constructor(fastify, path, server) {
|
|
3
|
+
this.fastify = fastify;
|
|
4
|
+
this.path = path;
|
|
5
|
+
this.server = server;
|
|
6
|
+
}
|
|
7
|
+
shouldUpgrade(pathname) {
|
|
8
|
+
if (!this.server) {
|
|
9
|
+
this.fastify.log.warn({
|
|
10
|
+
msg: `No handler active for ${this.path}`
|
|
11
|
+
});
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return this.path === pathname;
|
|
15
|
+
}
|
|
16
|
+
upgrade(request, socket, head) {
|
|
17
|
+
this.server.handleUpgrade(request, socket, head, webSocket => {
|
|
18
|
+
this.server.emit('connection', webSocket, request);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=WebSocketServerAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketServerAdapter.js","names":["WebSocketServerAdapter","constructor","fastify","path","server","shouldUpgrade","pathname","log","warn","msg","upgrade","request","socket","head","handleUpgrade","webSocket","emit"],"sources":["../../../src/plugins/wss/WebSocketServerAdapter.ts"],"sourcesContent":["import type { IncomingMessage } from 'node:http';\nimport type { Socket } from 'node:net';\nimport type { FastifyInstance } from 'fastify';\nimport type { WebSocketServer as WebSocketServer } from 'ws';\nimport type { WebSocketServerInterface } from './types';\n\nexport class WebSocketServerAdapter implements WebSocketServerInterface {\n constructor(\n private fastify: FastifyInstance,\n private path: string,\n private server?: WebSocketServer\n ) {}\n\n shouldUpgrade(pathname: string) {\n if (!this.server) {\n this.fastify.log.warn({ msg: `No handler active for ${this.path}` });\n return false;\n }\n return this.path === pathname;\n }\n\n upgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this.server!.handleUpgrade(request, socket, head, (webSocket) => {\n this.server!.emit('connection', webSocket, request);\n });\n }\n}\n"],"mappings":"AAMA,OAAO,MAAMA,sBAAsB,CAAqC;EACtEC,WAAWA,CACDC,OAAwB,EACxBC,IAAY,EACZC,MAAwB,EAChC;IAAA,KAHQF,OAAwB,GAAxBA,OAAwB;IAAA,KACxBC,IAAY,GAAZA,IAAY;IAAA,KACZC,MAAwB,GAAxBA,MAAwB;EAC/B;EAEHC,aAAaA,CAACC,QAAgB,EAAE;IAC9B,IAAI,CAAC,IAAI,CAACF,MAAM,EAAE;MAChB,IAAI,CAACF,OAAO,CAACK,GAAG,CAACC,IAAI,CAAC;QAAEC,GAAG,EAAG,yBAAwB,IAAI,CAACN,IAAK;MAAE,CAAC,CAAC;MACpE,OAAO,KAAK;IACd;IACA,OAAO,IAAI,CAACA,IAAI,KAAKG,QAAQ;EAC/B;EAEAI,OAAOA,CAACC,OAAwB,EAAEC,MAAc,EAAEC,IAAY,EAAE;IAC9D,IAAI,CAACT,MAAM,CAAEU,aAAa,CAACH,OAAO,EAAEC,MAAM,EAAEC,IAAI,EAAGE,SAAS,IAAK;MAC/D,IAAI,CAACX,MAAM,CAAEY,IAAI,CAAC,YAAY,EAAED,SAAS,EAAEJ,OAAO,CAAC;IACrD,CAAC,CAAC;EACJ;AACF","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["default"],"sources":["../../../src/plugins/wss/index.ts"],"sourcesContent":["export { default } from './wssPlugin';\nexport * from './WebSocketServer';\nexport * from './types';\n"],"mappings":"SAASA,OAAO;AAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
import WebSocket from 'ws';
|
|
3
|
+
import { WebSocketServer } from '../WebSocketServer';
|
|
4
|
+
/**
|
|
5
|
+
* Class for creating a WebSocket server for API clients.
|
|
6
|
+
* Useful to listening for compilation events and new logs.
|
|
7
|
+
*
|
|
8
|
+
* @category Development server
|
|
9
|
+
*/
|
|
10
|
+
export declare class WebSocketApiServer extends WebSocketServer {
|
|
11
|
+
private clients;
|
|
12
|
+
private nextClientId;
|
|
13
|
+
/**
|
|
14
|
+
* Create new instance of WebSocketApiServer and attach it to the given Fastify instance.
|
|
15
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
16
|
+
*
|
|
17
|
+
* @param fastify Fastify instance to attach the WebSocket server to.
|
|
18
|
+
*/
|
|
19
|
+
constructor(fastify: FastifyInstance);
|
|
20
|
+
/**
|
|
21
|
+
* Send message to all connected API clients.
|
|
22
|
+
*
|
|
23
|
+
* @param event Event string or object to send.
|
|
24
|
+
*/
|
|
25
|
+
send(event: any): void;
|
|
26
|
+
/**
|
|
27
|
+
* Process new WebSocket connection from client application.
|
|
28
|
+
*
|
|
29
|
+
* @param socket Incoming client's WebSocket connection.
|
|
30
|
+
*/
|
|
31
|
+
onConnection(socket: WebSocket): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { WebSocketServer } from "../WebSocketServer.js";
|
|
2
|
+
/**
|
|
3
|
+
* Class for creating a WebSocket server for API clients.
|
|
4
|
+
* Useful to listening for compilation events and new logs.
|
|
5
|
+
*
|
|
6
|
+
* @category Development server
|
|
7
|
+
*/
|
|
8
|
+
export class WebSocketApiServer extends WebSocketServer {
|
|
9
|
+
clients = new Map();
|
|
10
|
+
nextClientId = 0;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create new instance of WebSocketApiServer and attach it to the given Fastify instance.
|
|
14
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
15
|
+
*
|
|
16
|
+
* @param fastify Fastify instance to attach the WebSocket server to.
|
|
17
|
+
*/
|
|
18
|
+
constructor(fastify) {
|
|
19
|
+
super(fastify, '/api');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Send message to all connected API clients.
|
|
24
|
+
*
|
|
25
|
+
* @param event Event string or object to send.
|
|
26
|
+
*/
|
|
27
|
+
send(event) {
|
|
28
|
+
const data = typeof event === 'string' ? event : JSON.stringify(event);
|
|
29
|
+
for (const [, socket] of this.clients.entries()) {
|
|
30
|
+
try {
|
|
31
|
+
socket.send(data);
|
|
32
|
+
} catch {
|
|
33
|
+
// NOOP
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Process new WebSocket connection from client application.
|
|
40
|
+
*
|
|
41
|
+
* @param socket Incoming client's WebSocket connection.
|
|
42
|
+
*/
|
|
43
|
+
onConnection(socket) {
|
|
44
|
+
const clientId = `client#${this.nextClientId++}`;
|
|
45
|
+
this.clients.set(clientId, socket);
|
|
46
|
+
this.fastify.log.info({
|
|
47
|
+
msg: 'API client connected',
|
|
48
|
+
clientId
|
|
49
|
+
});
|
|
50
|
+
this.clients.set(clientId, socket);
|
|
51
|
+
const onClose = () => {
|
|
52
|
+
this.fastify.log.info({
|
|
53
|
+
msg: 'API client disconnected',
|
|
54
|
+
clientId
|
|
55
|
+
});
|
|
56
|
+
this.clients.delete(clientId);
|
|
57
|
+
};
|
|
58
|
+
socket.addEventListener('error', onClose);
|
|
59
|
+
socket.addEventListener('close', onClose);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=WebSocketApiServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketApiServer.js","names":["WebSocketServer","WebSocketApiServer","clients","Map","nextClientId","constructor","fastify","send","event","data","JSON","stringify","socket","entries","onConnection","clientId","set","log","info","msg","onClose","delete","addEventListener"],"sources":["../../../../src/plugins/wss/servers/WebSocketApiServer.ts"],"sourcesContent":["import { FastifyInstance } from 'fastify';\nimport WebSocket from 'ws';\nimport { WebSocketServer } from '../WebSocketServer';\n\n/**\n * Class for creating a WebSocket server for API clients.\n * Useful to listening for compilation events and new logs.\n *\n * @category Development server\n */\nexport class WebSocketApiServer extends WebSocketServer {\n private clients = new Map<string, WebSocket>();\n private nextClientId = 0;\n\n /**\n * Create new instance of WebSocketApiServer and attach it to the given Fastify instance.\n * Any logging information, will be passed through standard `fastify.log` API.\n *\n * @param fastify Fastify instance to attach the WebSocket server to.\n */\n constructor(fastify: FastifyInstance) {\n super(fastify, '/api');\n }\n\n /**\n * Send message to all connected API clients.\n *\n * @param event Event string or object to send.\n */\n send(event: any) {\n const data = typeof event === 'string' ? event : JSON.stringify(event);\n\n for (const [, socket] of this.clients.entries()) {\n try {\n socket.send(data);\n } catch {\n // NOOP\n }\n }\n }\n\n /**\n * Process new WebSocket connection from client application.\n *\n * @param socket Incoming client's WebSocket connection.\n */\n onConnection(socket: WebSocket) {\n const clientId = `client#${this.nextClientId++}`;\n this.clients.set(clientId, socket);\n\n this.fastify.log.info({ msg: 'API client connected', clientId });\n this.clients.set(clientId, socket);\n\n const onClose = () => {\n this.fastify.log.info({\n msg: 'API client disconnected',\n clientId,\n });\n this.clients.delete(clientId);\n };\n\n socket.addEventListener('error', onClose);\n socket.addEventListener('close', onClose);\n }\n}\n"],"mappings":"SAESA,eAAe;AAExB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,kBAAkB,SAASD,eAAe,CAAC;EAC9CE,OAAO,GAAG,IAAIC,GAAG,CAAoB,CAAC;EACtCC,YAAY,GAAG,CAAC;;EAExB;AACF;AACA;AACA;AACA;AACA;EACEC,WAAWA,CAACC,OAAwB,EAAE;IACpC,KAAK,CAACA,OAAO,EAAE,MAAM,CAAC;EACxB;;EAEA;AACF;AACA;AACA;AACA;EACEC,IAAIA,CAACC,KAAU,EAAE;IACf,MAAMC,IAAI,GAAG,OAAOD,KAAK,KAAK,QAAQ,GAAGA,KAAK,GAAGE,IAAI,CAACC,SAAS,CAACH,KAAK,CAAC;IAEtE,KAAK,MAAM,GAAGI,MAAM,CAAC,IAAI,IAAI,CAACV,OAAO,CAACW,OAAO,CAAC,CAAC,EAAE;MAC/C,IAAI;QACFD,MAAM,CAACL,IAAI,CAACE,IAAI,CAAC;MACnB,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ;EACF;;EAEA;AACF;AACA;AACA;AACA;EACEK,YAAYA,CAACF,MAAiB,EAAE;IAC9B,MAAMG,QAAQ,GAAI,UAAS,IAAI,CAACX,YAAY,EAAG,EAAC;IAChD,IAAI,CAACF,OAAO,CAACc,GAAG,CAACD,QAAQ,EAAEH,MAAM,CAAC;IAElC,IAAI,CAACN,OAAO,CAACW,GAAG,CAACC,IAAI,CAAC;MAAEC,GAAG,EAAE,sBAAsB;MAAEJ;IAAS,CAAC,CAAC;IAChE,IAAI,CAACb,OAAO,CAACc,GAAG,CAACD,QAAQ,EAAEH,MAAM,CAAC;IAElC,MAAMQ,OAAO,GAAGA,CAAA,KAAM;MACpB,IAAI,CAACd,OAAO,CAACW,GAAG,CAACC,IAAI,CAAC;QACpBC,GAAG,EAAE,yBAAyB;QAC9BJ;MACF,CAAC,CAAC;MACF,IAAI,CAACb,OAAO,CAACmB,MAAM,CAACN,QAAQ,CAAC;IAC/B,CAAC;IAEDH,MAAM,CAACU,gBAAgB,CAAC,OAAO,EAAEF,OAAO,CAAC;IACzCR,MAAM,CAACU,gBAAgB,CAAC,OAAO,EAAEF,OAAO,CAAC;EAC3C;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { IncomingMessage } from 'http';
|
|
3
|
+
import type { FastifyInstance } from 'fastify';
|
|
4
|
+
import WebSocket from 'ws';
|
|
5
|
+
import { WebSocketServer } from '../WebSocketServer';
|
|
6
|
+
/**
|
|
7
|
+
* Class for creating a WebSocket server and providing a bridge between
|
|
8
|
+
* debugger UI (Remote JS debugger) and the running React Native application.
|
|
9
|
+
*
|
|
10
|
+
* React Native application (aka client) will send and receive messages from the debugger UI
|
|
11
|
+
* which runs inside a browser.
|
|
12
|
+
*
|
|
13
|
+
* @category Development server
|
|
14
|
+
*/
|
|
15
|
+
export declare class WebSocketDebuggerServer extends WebSocketServer {
|
|
16
|
+
/**
|
|
17
|
+
* A WebSocket connection with the debugger UI.
|
|
18
|
+
*/
|
|
19
|
+
private debuggerSocket;
|
|
20
|
+
/**
|
|
21
|
+
* A WebSocket connection with the client (React Native app).
|
|
22
|
+
*/
|
|
23
|
+
private clientSocket;
|
|
24
|
+
/**
|
|
25
|
+
* Create new instance of WebSocketDebuggerServer and attach it to the given Fastify instance.
|
|
26
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
27
|
+
*
|
|
28
|
+
* @param fastify Fastify instance to attach the WebSocket server to.
|
|
29
|
+
*/
|
|
30
|
+
constructor(fastify: FastifyInstance);
|
|
31
|
+
/**
|
|
32
|
+
* Check if debugger UI is connected to the WebSocketDebuggerServer.
|
|
33
|
+
*/
|
|
34
|
+
isDebuggerConnected(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Send a message to a given WebSocket connection.
|
|
37
|
+
*
|
|
38
|
+
* @param socket WebSocket connection to send the message to.
|
|
39
|
+
* @param message Message to send.
|
|
40
|
+
*/
|
|
41
|
+
send(socket: WebSocket | undefined, message: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Process new WebSocket connection. The upgrade request should contain `role` query param
|
|
44
|
+
* for determining the type of the connection.
|
|
45
|
+
*
|
|
46
|
+
* @param socket Incoming WebSocket connection.
|
|
47
|
+
* @param request Upgrade request for the connection.
|
|
48
|
+
*/
|
|
49
|
+
onConnection(socket: WebSocket, request: IncomingMessage): void;
|
|
50
|
+
/**
|
|
51
|
+
* Process new WebSocket connection from Debugger UI (Remote JS Debugger).
|
|
52
|
+
* If there's already open connection, the new one gets closed automatically.
|
|
53
|
+
*
|
|
54
|
+
* @param socket Incoming debugger WebSocket connection.
|
|
55
|
+
*/
|
|
56
|
+
onDebuggerConnection(socket: WebSocket): void;
|
|
57
|
+
/**
|
|
58
|
+
* Process new WebSocket connection from React Native app (client)
|
|
59
|
+
* and close any previous connection.
|
|
60
|
+
*
|
|
61
|
+
* @param socket Incoming client WebSocket connection.
|
|
62
|
+
*/
|
|
63
|
+
onClientConnection(socket: WebSocket): void;
|
|
64
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { WebSocketServer } from "../WebSocketServer.js";
|
|
2
|
+
/**
|
|
3
|
+
* Class for creating a WebSocket server and providing a bridge between
|
|
4
|
+
* debugger UI (Remote JS debugger) and the running React Native application.
|
|
5
|
+
*
|
|
6
|
+
* React Native application (aka client) will send and receive messages from the debugger UI
|
|
7
|
+
* which runs inside a browser.
|
|
8
|
+
*
|
|
9
|
+
* @category Development server
|
|
10
|
+
*/
|
|
11
|
+
export class WebSocketDebuggerServer extends WebSocketServer {
|
|
12
|
+
/**
|
|
13
|
+
* A WebSocket connection with the debugger UI.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A WebSocket connection with the client (React Native app).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create new instance of WebSocketDebuggerServer and attach it to the given Fastify instance.
|
|
22
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
23
|
+
*
|
|
24
|
+
* @param fastify Fastify instance to attach the WebSocket server to.
|
|
25
|
+
*/
|
|
26
|
+
constructor(fastify) {
|
|
27
|
+
super(fastify, '/debugger-proxy');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if debugger UI is connected to the WebSocketDebuggerServer.
|
|
32
|
+
*/
|
|
33
|
+
isDebuggerConnected() {
|
|
34
|
+
return Boolean(this.debuggerSocket);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Send a message to a given WebSocket connection.
|
|
39
|
+
*
|
|
40
|
+
* @param socket WebSocket connection to send the message to.
|
|
41
|
+
* @param message Message to send.
|
|
42
|
+
*/
|
|
43
|
+
send(socket, message) {
|
|
44
|
+
try {
|
|
45
|
+
socket?.send(message);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.fastify.log.warn({
|
|
48
|
+
msg: 'Failed to send data to socket',
|
|
49
|
+
error
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Process new WebSocket connection. The upgrade request should contain `role` query param
|
|
56
|
+
* for determining the type of the connection.
|
|
57
|
+
*
|
|
58
|
+
* @param socket Incoming WebSocket connection.
|
|
59
|
+
* @param request Upgrade request for the connection.
|
|
60
|
+
*/
|
|
61
|
+
onConnection(socket, request) {
|
|
62
|
+
const {
|
|
63
|
+
url = ''
|
|
64
|
+
} = request;
|
|
65
|
+
if (url.indexOf('role=debugger') >= 0) {
|
|
66
|
+
this.fastify.log.info({
|
|
67
|
+
msg: 'Chrome Remote JS debugger connected'
|
|
68
|
+
});
|
|
69
|
+
this.onDebuggerConnection(socket);
|
|
70
|
+
} else if (url.indexOf('role=client') >= 0) {
|
|
71
|
+
this.fastify.log.info({
|
|
72
|
+
msg: 'React Native app connected to debugger'
|
|
73
|
+
});
|
|
74
|
+
this.onClientConnection(socket);
|
|
75
|
+
} else {
|
|
76
|
+
socket.close(1011, 'Missing role param');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Process new WebSocket connection from Debugger UI (Remote JS Debugger).
|
|
82
|
+
* If there's already open connection, the new one gets closed automatically.
|
|
83
|
+
*
|
|
84
|
+
* @param socket Incoming debugger WebSocket connection.
|
|
85
|
+
*/
|
|
86
|
+
onDebuggerConnection(socket) {
|
|
87
|
+
if (this.debuggerSocket) {
|
|
88
|
+
socket.close(1011, 'Another debugger is already connected');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.debuggerSocket = socket;
|
|
92
|
+
const onClose = () => {
|
|
93
|
+
this.fastify.log.info({
|
|
94
|
+
msg: 'Chrome Remote JS debugger disconnected'
|
|
95
|
+
});
|
|
96
|
+
this.debuggerSocket = undefined;
|
|
97
|
+
if (this.clientSocket) {
|
|
98
|
+
this.clientSocket.removeAllListeners();
|
|
99
|
+
this.clientSocket.close(1011, 'Debugger was disconnected');
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
this.debuggerSocket.addEventListener('error', onClose);
|
|
103
|
+
this.debuggerSocket.addEventListener('close', onClose);
|
|
104
|
+
this.debuggerSocket.addEventListener('message', ({
|
|
105
|
+
data
|
|
106
|
+
}) => {
|
|
107
|
+
this.send(this.clientSocket, data.toString());
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Process new WebSocket connection from React Native app (client)
|
|
113
|
+
* and close any previous connection.
|
|
114
|
+
*
|
|
115
|
+
* @param socket Incoming client WebSocket connection.
|
|
116
|
+
*/
|
|
117
|
+
onClientConnection(socket) {
|
|
118
|
+
if (this.clientSocket) {
|
|
119
|
+
this.clientSocket.removeAllListeners();
|
|
120
|
+
this.clientSocket.close(1011, 'Another client is connected');
|
|
121
|
+
this.clientSocket = undefined;
|
|
122
|
+
}
|
|
123
|
+
const onClose = () => {
|
|
124
|
+
this.fastify.log.info({
|
|
125
|
+
msg: 'React Native app disconnected from debugger'
|
|
126
|
+
});
|
|
127
|
+
this.clientSocket = undefined;
|
|
128
|
+
this.send(this.debuggerSocket, JSON.stringify({
|
|
129
|
+
method: '$disconnected'
|
|
130
|
+
}));
|
|
131
|
+
};
|
|
132
|
+
this.clientSocket = socket;
|
|
133
|
+
this.clientSocket.addEventListener('error', onClose);
|
|
134
|
+
this.clientSocket.addEventListener('close', onClose);
|
|
135
|
+
this.clientSocket.addEventListener('message', ({
|
|
136
|
+
data
|
|
137
|
+
}) => {
|
|
138
|
+
this.send(this.debuggerSocket, data.toString());
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=WebSocketDebuggerServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketDebuggerServer.js","names":["WebSocketServer","WebSocketDebuggerServer","constructor","fastify","isDebuggerConnected","Boolean","debuggerSocket","send","socket","message","error","log","warn","msg","onConnection","request","url","indexOf","info","onDebuggerConnection","onClientConnection","close","onClose","undefined","clientSocket","removeAllListeners","addEventListener","data","toString","JSON","stringify","method"],"sources":["../../../../src/plugins/wss/servers/WebSocketDebuggerServer.ts"],"sourcesContent":["import type { IncomingMessage } from 'http';\nimport type { FastifyInstance } from 'fastify';\nimport WebSocket from 'ws';\nimport { WebSocketServer } from '../WebSocketServer';\n\n/**\n * Class for creating a WebSocket server and providing a bridge between\n * debugger UI (Remote JS debugger) and the running React Native application.\n *\n * React Native application (aka client) will send and receive messages from the debugger UI\n * which runs inside a browser.\n *\n * @category Development server\n */\nexport class WebSocketDebuggerServer extends WebSocketServer {\n /**\n * A WebSocket connection with the debugger UI.\n */\n private debuggerSocket: WebSocket | undefined;\n\n /**\n * A WebSocket connection with the client (React Native app).\n */\n private clientSocket: WebSocket | undefined;\n\n /**\n * Create new instance of WebSocketDebuggerServer and attach it to the given Fastify instance.\n * Any logging information, will be passed through standard `fastify.log` API.\n *\n * @param fastify Fastify instance to attach the WebSocket server to.\n */\n constructor(fastify: FastifyInstance) {\n super(fastify, '/debugger-proxy');\n }\n\n /**\n * Check if debugger UI is connected to the WebSocketDebuggerServer.\n */\n isDebuggerConnected() {\n return Boolean(this.debuggerSocket);\n }\n\n /**\n * Send a message to a given WebSocket connection.\n *\n * @param socket WebSocket connection to send the message to.\n * @param message Message to send.\n */\n send(socket: WebSocket | undefined, message: string) {\n try {\n socket?.send(message);\n } catch (error) {\n this.fastify.log.warn({ msg: 'Failed to send data to socket', error });\n }\n }\n\n /**\n * Process new WebSocket connection. The upgrade request should contain `role` query param\n * for determining the type of the connection.\n *\n * @param socket Incoming WebSocket connection.\n * @param request Upgrade request for the connection.\n */\n onConnection(socket: WebSocket, request: IncomingMessage) {\n const { url = '' } = request;\n if (url.indexOf('role=debugger') >= 0) {\n this.fastify.log.info({ msg: 'Chrome Remote JS debugger connected' });\n this.onDebuggerConnection(socket);\n } else if (url.indexOf('role=client') >= 0) {\n this.fastify.log.info({ msg: 'React Native app connected to debugger' });\n this.onClientConnection(socket);\n } else {\n socket.close(1011, 'Missing role param');\n }\n }\n\n /**\n * Process new WebSocket connection from Debugger UI (Remote JS Debugger).\n * If there's already open connection, the new one gets closed automatically.\n *\n * @param socket Incoming debugger WebSocket connection.\n */\n onDebuggerConnection(socket: WebSocket) {\n if (this.debuggerSocket) {\n socket.close(1011, 'Another debugger is already connected');\n return;\n }\n this.debuggerSocket = socket;\n const onClose = () => {\n this.fastify.log.info({ msg: 'Chrome Remote JS debugger disconnected' });\n this.debuggerSocket = undefined;\n if (this.clientSocket) {\n this.clientSocket.removeAllListeners();\n this.clientSocket.close(1011, 'Debugger was disconnected');\n }\n };\n this.debuggerSocket.addEventListener('error', onClose);\n this.debuggerSocket.addEventListener('close', onClose);\n this.debuggerSocket.addEventListener('message', ({ data }) => {\n this.send(this.clientSocket, data.toString());\n });\n }\n\n /**\n * Process new WebSocket connection from React Native app (client)\n * and close any previous connection.\n *\n * @param socket Incoming client WebSocket connection.\n */\n onClientConnection(socket: WebSocket) {\n if (this.clientSocket) {\n this.clientSocket.removeAllListeners();\n this.clientSocket.close(1011, 'Another client is connected');\n this.clientSocket = undefined;\n }\n\n const onClose = () => {\n this.fastify.log.info({\n msg: 'React Native app disconnected from debugger',\n });\n this.clientSocket = undefined;\n this.send(\n this.debuggerSocket,\n JSON.stringify({ method: '$disconnected' })\n );\n };\n\n this.clientSocket = socket;\n this.clientSocket.addEventListener('error', onClose);\n this.clientSocket.addEventListener('close', onClose);\n this.clientSocket.addEventListener('message', ({ data }) => {\n this.send(this.debuggerSocket, data.toString());\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import type { FastifyInstance } from 'fastify';
|
|
3
|
+
import { WebSocketServer } from '../WebSocketServer';
|
|
4
|
+
/**
|
|
5
|
+
* Class for creating a WebSocket server for communication with React Native clients.
|
|
6
|
+
* All client logs - logs from React Native application - are processed here.
|
|
7
|
+
*
|
|
8
|
+
* @category Development server
|
|
9
|
+
*/
|
|
10
|
+
export declare class WebSocketDevClientServer extends WebSocketServer {
|
|
11
|
+
private clients;
|
|
12
|
+
private nextClientId;
|
|
13
|
+
/**
|
|
14
|
+
* Create new instance of WebSocketDevClientServer and attach it to the given Fastify instance.
|
|
15
|
+
* Any logging information, will be passed through standard `fastify.log` API.
|
|
16
|
+
*
|
|
17
|
+
* @param fastify Fastify instance to attach the WebSocket server to.
|
|
18
|
+
*/
|
|
19
|
+
constructor(fastify: FastifyInstance);
|
|
20
|
+
/**
|
|
21
|
+
* Process client message.
|
|
22
|
+
*
|
|
23
|
+
* @param message Stringified client message.
|
|
24
|
+
*/
|
|
25
|
+
processMessage(message: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Process new WebSocket connection from client application.
|
|
28
|
+
*
|
|
29
|
+
* @param socket Incoming client's WebSocket connection.
|
|
30
|
+
*/
|
|
31
|
+
onConnection(socket: WebSocket): void;
|
|
32
|
+
}
|