@callstack/repack-dev-server 5.0.0-rc.11 → 5.0.0-rc.12

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.
@@ -53,8 +53,8 @@ export async function createServer(config) {
53
53
  platform,
54
54
  });
55
55
  },
56
- broadcastToHmrClients: (event, platform, clientIds) => {
57
- instance.wss.hmrServer.send(event, platform, clientIds);
56
+ broadcastToHmrClients: (event) => {
57
+ instance.wss.hmrServer.send(event);
58
58
  },
59
59
  broadcastToMessageClients: ({ method, params }) => {
60
60
  instance.wss.messageServer.broadcast(method, params);
@@ -18,8 +18,8 @@ async function compilerPlugin(instance, { delegate }) {
18
18
  let { platform } = request.query;
19
19
  if (!filename) {
20
20
  // This technically should never happen - this route should not be called if file is missing.
21
- request.log.error('File was not provided');
22
- return reply.notFound();
21
+ request.log.debug('File was not provided');
22
+ return reply.notFound('File was not provided');
23
23
  }
24
24
  // Let consumer infer the platform. If function is not provided fallback
25
25
  // to platform query param.
@@ -29,6 +29,7 @@ async function compilerPlugin(instance, { delegate }) {
29
29
  multipart?.writeChunk({ 'Content-Type': 'application/json' }, JSON.stringify({
30
30
  done: completed,
31
31
  total,
32
+ status: 'Bundling with Re.Pack',
32
33
  }));
33
34
  };
34
35
  try {
@@ -45,7 +46,7 @@ async function compilerPlugin(instance, { delegate }) {
45
46
  }
46
47
  }
47
48
  catch (error) {
48
- request.log.error(error);
49
+ request.log.debug(error);
49
50
  return reply.notFound(error.message);
50
51
  }
51
52
  },
@@ -2,7 +2,6 @@ import path from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import fastifyFavicon from 'fastify-favicon';
4
4
  import fastifyPlugin from 'fastify-plugin';
5
- // @ts-ignore
6
5
  const dirname = path.dirname(fileURLToPath(import.meta.url));
7
6
  const pathToImgDir = path.join(dirname, '../../../static');
8
7
  async function faviconPlugin(instance) {
@@ -1,35 +1,33 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
2
  import type { Socket } from 'node:net';
3
3
  import type { FastifyInstance } from 'fastify';
4
- import { type ServerOptions, type WebSocket, WebSocketServer as WebSocketServerImpl } from 'ws';
5
- import type { WebSocketServerInterface } from './types.js';
4
+ import { type WebSocket, WebSocketServer as WebSocketServerImpl } from 'ws';
5
+ import type { WebSocketServerInterface, WebSocketServerOptions } from './types.js';
6
6
  /**
7
7
  * Abstract class for providing common logic (eg routing) for all WebSocket servers.
8
8
  *
9
9
  * @category Development server
10
10
  */
11
- export declare abstract class WebSocketServer implements WebSocketServerInterface {
11
+ export declare abstract class WebSocketServer<T extends WebSocket = WebSocket> implements WebSocketServerInterface {
12
12
  /** An instance of the underlying WebSocket server. */
13
13
  protected server: WebSocketServerImpl;
14
14
  /** Fastify instance from which {@link server} will receive upgrade connections. */
15
15
  protected fastify: FastifyInstance;
16
+ protected name: string;
16
17
  protected paths: string[];
18
+ protected clients: Map<string, T>;
19
+ protected nextClientId: number;
20
+ private timer;
17
21
  /**
18
22
  * Create a new instance of the WebSocketServer.
19
23
  * Any logging information, will be passed through standard `fastify.log` API.
20
24
  *
21
25
  * @param fastify Fastify instance to which the WebSocket will be attached to.
22
26
  * @param path Path on which this WebSocketServer will be accepting connections.
23
- * @param wssOptions WebSocket Server options.
27
+ * @param options WebSocketServer options.
24
28
  */
25
- constructor(fastify: FastifyInstance, path: string | string[], wssOptions?: Omit<ServerOptions, 'noServer' | 'server' | 'host' | 'port' | 'path'>);
29
+ constructor(fastify: FastifyInstance, options: WebSocketServerOptions);
26
30
  shouldUpgrade(pathname: string): boolean;
27
31
  upgrade(request: IncomingMessage, socket: Socket, head: Buffer): void;
28
- /**
29
- * Process incoming WebSocket connection.
30
- *
31
- * @param socket Incoming WebSocket connection.
32
- * @param request Upgrade request for the connection.
33
- */
34
- abstract onConnection(socket: WebSocket, request: IncomingMessage): void;
32
+ onConnection(socket: T, _request: IncomingMessage): string;
35
33
  }
@@ -1,4 +1,4 @@
1
- import { WebSocketServer as WebSocketServerImpl, } from 'ws';
1
+ import { WebSocketServer as WebSocketServerImpl } from 'ws';
2
2
  /**
3
3
  * Abstract class for providing common logic (eg routing) for all WebSocket servers.
4
4
  *
@@ -11,13 +11,29 @@ export class WebSocketServer {
11
11
  *
12
12
  * @param fastify Fastify instance to which the WebSocket will be attached to.
13
13
  * @param path Path on which this WebSocketServer will be accepting connections.
14
- * @param wssOptions WebSocket Server options.
14
+ * @param options WebSocketServer options.
15
15
  */
16
- constructor(fastify, path, wssOptions = {}) {
16
+ constructor(fastify, options) {
17
+ this.nextClientId = 0;
18
+ this.timer = null;
17
19
  this.fastify = fastify;
18
- this.server = new WebSocketServerImpl({ noServer: true, ...wssOptions });
20
+ this.name = options.name;
21
+ this.paths = Array.isArray(options.path) ? options.path : [options.path];
22
+ this.server = new WebSocketServerImpl({ noServer: true, ...options.wss });
19
23
  this.server.on('connection', this.onConnection.bind(this));
20
- this.paths = Array.isArray(path) ? path : [path];
24
+ this.clients = new Map();
25
+ // setup heartbeat timer
26
+ this.timer = setInterval(() => {
27
+ this.clients.forEach((socket) => {
28
+ if (!socket.isAlive) {
29
+ socket.terminate();
30
+ }
31
+ else {
32
+ socket.isAlive = false;
33
+ socket.ping(() => { });
34
+ }
35
+ });
36
+ }, 30000);
21
37
  }
22
38
  shouldUpgrade(pathname) {
23
39
  return this.paths.includes(pathname);
@@ -27,4 +43,25 @@ export class WebSocketServer {
27
43
  this.server.emit('connection', webSocket, request);
28
44
  });
29
45
  }
46
+ onConnection(socket, _request) {
47
+ const clientId = `client#${this.nextClientId++}`;
48
+ this.clients.set(clientId, socket);
49
+ this.fastify.log.debug({ msg: `${this.name} client connected`, clientId });
50
+ const errorHandler = () => {
51
+ this.fastify.log.debug({
52
+ msg: `${this.name} client disconnected`,
53
+ clientId,
54
+ });
55
+ socket.removeAllListeners(); // should we do this?
56
+ this.clients.delete(clientId);
57
+ };
58
+ socket.addEventListener('error', errorHandler);
59
+ socket.addEventListener('close', errorHandler);
60
+ // heartbeat
61
+ socket.isAlive = true;
62
+ socket.on('pong', () => {
63
+ socket.isAlive = true;
64
+ });
65
+ return clientId;
66
+ }
30
67
  }
@@ -1,5 +1,4 @@
1
1
  import type { FastifyInstance } from 'fastify';
2
- import type WebSocket from 'ws';
3
2
  import { WebSocketServer } from '../WebSocketServer.js';
4
3
  /**
5
4
  * Class for creating a WebSocket server for API clients.
@@ -8,8 +7,6 @@ import { WebSocketServer } from '../WebSocketServer.js';
8
7
  * @category Development server
9
8
  */
10
9
  export declare class WebSocketApiServer extends WebSocketServer {
11
- private clients;
12
- private nextClientId;
13
10
  /**
14
11
  * Create new instance of WebSocketApiServer and attach it to the given Fastify instance.
15
12
  * Any logging information, will be passed through standard `fastify.log` API.
@@ -23,10 +20,4 @@ export declare class WebSocketApiServer extends WebSocketServer {
23
20
  * @param event Event string or object to send.
24
21
  */
25
22
  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
23
  }
@@ -13,9 +13,7 @@ export class WebSocketApiServer extends WebSocketServer {
13
13
  * @param fastify Fastify instance to attach the WebSocket server to.
14
14
  */
15
15
  constructor(fastify) {
16
- super(fastify, '/api');
17
- this.clients = new Map();
18
- this.nextClientId = 0;
16
+ super(fastify, { name: 'API', path: '/api' });
19
17
  }
20
18
  /**
21
19
  * Send message to all connected API clients.
@@ -33,24 +31,4 @@ export class WebSocketApiServer extends WebSocketServer {
33
31
  }
34
32
  }
35
33
  }
36
- /**
37
- * Process new WebSocket connection from client application.
38
- *
39
- * @param socket Incoming client's WebSocket connection.
40
- */
41
- onConnection(socket) {
42
- const clientId = `client#${this.nextClientId++}`;
43
- this.clients.set(clientId, socket);
44
- this.fastify.log.debug({ msg: 'API client connected', clientId });
45
- this.clients.set(clientId, socket);
46
- const onClose = () => {
47
- this.fastify.log.debug({
48
- msg: 'API client disconnected',
49
- clientId,
50
- });
51
- this.clients.delete(clientId);
52
- };
53
- socket.addEventListener('error', onClose);
54
- socket.addEventListener('close', onClose);
55
- }
56
34
  }
@@ -1,3 +1,4 @@
1
+ import type { IncomingMessage } from 'node:http';
1
2
  import type { FastifyInstance } from 'fastify';
2
3
  import type WebSocket from 'ws';
3
4
  import { WebSocketServer } from '../WebSocketServer.js';
@@ -8,8 +9,6 @@ import { WebSocketServer } from '../WebSocketServer.js';
8
9
  * @category Development server
9
10
  */
10
11
  export declare class WebSocketDevClientServer extends WebSocketServer {
11
- private clients;
12
- private nextClientId;
13
12
  /**
14
13
  * Create new instance of WebSocketDevClientServer and attach it to the given Fastify instance.
15
14
  * Any logging information, will be passed through standard `fastify.log` API.
@@ -23,10 +22,5 @@ export declare class WebSocketDevClientServer extends WebSocketServer {
23
22
  * @param message Stringified client message.
24
23
  */
25
24
  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;
25
+ onConnection(socket: WebSocket, request: IncomingMessage): string;
32
26
  }
@@ -13,9 +13,7 @@ export class WebSocketDevClientServer extends WebSocketServer {
13
13
  * @param fastify Fastify instance to attach the WebSocket server to.
14
14
  */
15
15
  constructor(fastify) {
16
- super(fastify, '/__client');
17
- this.clients = new Map();
18
- this.nextClientId = 0;
16
+ super(fastify, { name: 'React Native', path: '/__client' });
19
17
  }
20
18
  /**
21
19
  * Process client message.
@@ -44,26 +42,11 @@ export class WebSocketDevClientServer extends WebSocketServer {
44
42
  this.fastify.log.warn({ msg: 'Unknown client message', message });
45
43
  }
46
44
  }
47
- /**
48
- * Process new WebSocket connection from client application.
49
- *
50
- * @param socket Incoming client's WebSocket connection.
51
- */
52
- onConnection(socket) {
53
- const clientId = `client#${this.nextClientId++}`;
54
- this.clients.set(clientId, socket);
55
- this.fastify.log.debug({ msg: 'React Native client connected', clientId });
56
- const onClose = () => {
57
- this.fastify.log.debug({
58
- msg: 'React Native client disconnected',
59
- clientId,
60
- });
61
- this.clients.delete(clientId);
62
- };
63
- socket.addEventListener('error', onClose);
64
- socket.addEventListener('close', onClose);
45
+ onConnection(socket, request) {
46
+ const clientId = super.onConnection(socket, request);
65
47
  socket.addEventListener('message', (event) => {
66
48
  this.processMessage(event.data.toString());
67
49
  });
50
+ return clientId;
68
51
  }
69
52
  }
@@ -1,3 +1,4 @@
1
+ import type { IncomingMessage } from 'node:http';
1
2
  import type { FastifyInstance } from 'fastify';
2
3
  import type WebSocket from 'ws';
3
4
  import { WebSocketServer } from '../WebSocketServer.js';
@@ -36,8 +37,6 @@ export interface EventMessage {
36
37
  export declare class WebSocketEventsServer extends WebSocketServer {
37
38
  private config;
38
39
  static readonly PROTOCOL_VERSION = 2;
39
- private clients;
40
- private nextClientId;
41
40
  /**
42
41
  * Create new instance of WebSocketHMRServer and attach it to the given Fastify instance.
43
42
  * Any logging information, will be passed through standard `fastify.log` API.
@@ -66,10 +65,5 @@ export declare class WebSocketEventsServer extends WebSocketServer {
66
65
  * @param event Event message to broadcast.
67
66
  */
68
67
  broadcastEvent(event: EventMessage): void;
69
- /**
70
- * Process new client's WebSocket connection.
71
- *
72
- * @param socket Incoming WebSocket connection.
73
- */
74
- onConnection(socket: WebSocket): void;
68
+ onConnection(socket: WebSocket, request: IncomingMessage): string;
75
69
  }
@@ -16,14 +16,16 @@ export class WebSocketEventsServer extends WebSocketServer {
16
16
  * @param config Configuration object.
17
17
  */
18
18
  constructor(fastify, config) {
19
- super(fastify, '/events', {
20
- verifyClient: (({ origin }) => {
21
- return /^(https?:\/\/localhost|file:\/\/)/.test(origin);
22
- }),
19
+ super(fastify, {
20
+ name: 'Events',
21
+ path: '/events',
22
+ wss: {
23
+ verifyClient: (({ origin }) => {
24
+ return /^(https?:\/\/localhost|file:\/\/)/.test(origin);
25
+ }),
26
+ },
23
27
  });
24
28
  this.config = config;
25
- this.clients = new Map();
26
- this.nextClientId = 0;
27
29
  }
28
30
  /**
29
31
  * Parse received command message from connected client.
@@ -118,22 +120,8 @@ export class WebSocketEventsServer extends WebSocketServer {
118
120
  }
119
121
  }
120
122
  }
121
- /**
122
- * Process new client's WebSocket connection.
123
- *
124
- * @param socket Incoming WebSocket connection.
125
- */
126
- onConnection(socket) {
127
- const clientId = `client#${this.nextClientId++}`;
128
- this.clients.set(clientId, socket);
129
- this.fastify.log.debug({ msg: 'Events client connected', clientId });
130
- const onClose = () => {
131
- this.fastify.log.debug({ msg: 'Events client disconnected', clientId });
132
- socket.removeAllListeners();
133
- this.clients.delete(clientId);
134
- };
135
- socket.addEventListener('error', onClose);
136
- socket.addEventListener('close', onClose);
123
+ onConnection(socket, request) {
124
+ const clientId = super.onConnection(socket, request);
137
125
  socket.addEventListener('message', (event) => {
138
126
  const message = this.parseMessage(event.data.toString());
139
127
  if (!message) {
@@ -157,6 +145,7 @@ export class WebSocketEventsServer extends WebSocketServer {
157
145
  });
158
146
  }
159
147
  });
148
+ return clientId;
160
149
  }
161
150
  }
162
151
  WebSocketEventsServer.PROTOCOL_VERSION = 2;
@@ -1,37 +1,22 @@
1
- import type { IncomingMessage } from 'node:http';
2
1
  import type { FastifyInstance } from 'fastify';
3
- import type WebSocket from 'ws';
4
2
  import { WebSocketServer } from '../WebSocketServer.js';
5
- import type { HmrDelegate } from '../types.js';
6
3
  /**
7
4
  * Class for creating a WebSocket server for Hot Module Replacement.
8
5
  *
9
6
  * @category Development server
10
7
  */
11
8
  export declare class WebSocketHMRServer extends WebSocketServer {
12
- private delegate;
13
- private clients;
14
- private nextClientId;
15
9
  /**
16
10
  * Create new instance of WebSocketHMRServer and attach it to the given Fastify instance.
17
11
  * Any logging information, will be passed through standard `fastify.log` API.
18
12
  *
19
13
  * @param fastify Fastify instance to attach the WebSocket server to.
20
- * @param delegate HMR delegate instance.
21
14
  */
22
- constructor(fastify: FastifyInstance, delegate: HmrDelegate);
15
+ constructor(fastify: FastifyInstance);
23
16
  /**
24
17
  * Send action to all connected HMR clients.
25
18
  *
26
19
  * @param event Event to send to the clients.
27
- * @param platform Platform of clients to send the event to.
28
- * @param clientIds Ids of clients who should receive the event.
29
20
  */
30
- send(event: any, platform: string, clientIds?: string[]): void;
31
- /**
32
- * Process new WebSocket connection from HMR client.
33
- *
34
- * @param socket Incoming HMR client's WebSocket connection.
35
- */
36
- onConnection(socket: WebSocket, request: IncomingMessage): void;
21
+ send(event: any): void;
37
22
  }
@@ -1,4 +1,3 @@
1
- import { URL } from 'node:url';
2
1
  import { WebSocketServer } from '../WebSocketServer.js';
3
2
  /**
4
3
  * Class for creating a WebSocket server for Hot Module Replacement.
@@ -11,28 +10,21 @@ export class WebSocketHMRServer extends WebSocketServer {
11
10
  * Any logging information, will be passed through standard `fastify.log` API.
12
11
  *
13
12
  * @param fastify Fastify instance to attach the WebSocket server to.
14
- * @param delegate HMR delegate instance.
15
13
  */
16
- constructor(fastify, delegate) {
17
- super(fastify, delegate.getUriPath());
18
- this.delegate = delegate;
19
- this.clients = new Map();
20
- this.nextClientId = 0;
14
+ constructor(fastify) {
15
+ super(fastify, {
16
+ name: 'HMR',
17
+ path: '/__hmr',
18
+ });
21
19
  }
22
20
  /**
23
21
  * Send action to all connected HMR clients.
24
22
  *
25
23
  * @param event Event to send to the clients.
26
- * @param platform Platform of clients to send the event to.
27
- * @param clientIds Ids of clients who should receive the event.
28
24
  */
29
- send(event, platform, clientIds) {
25
+ send(event) {
30
26
  const data = typeof event === 'string' ? event : JSON.stringify(event);
31
- for (const [key, socket] of this.clients) {
32
- if (key.platform !== platform ||
33
- !(clientIds ?? [key.clientId]).includes(key.clientId)) {
34
- continue;
35
- }
27
+ this.clients.forEach((socket) => {
36
28
  try {
37
29
  socket.send(data);
38
30
  }
@@ -41,42 +33,8 @@ export class WebSocketHMRServer extends WebSocketServer {
41
33
  msg: 'Cannot send action to client',
42
34
  event,
43
35
  error,
44
- ...key,
45
36
  });
46
37
  }
47
- }
48
- }
49
- /**
50
- * Process new WebSocket connection from HMR client.
51
- *
52
- * @param socket Incoming HMR client's WebSocket connection.
53
- */
54
- onConnection(socket, request) {
55
- const { searchParams } = new URL(request.url || '', 'http://localhost');
56
- const platform = searchParams.get('platform');
57
- if (!platform) {
58
- this.fastify.log.debug({
59
- msg: 'HMR connection disconnected - missing platform',
60
- });
61
- socket.close();
62
- return;
63
- }
64
- const clientId = `client#${this.nextClientId++}`;
65
- const client = {
66
- clientId,
67
- platform,
68
- };
69
- this.clients.set(client, socket);
70
- this.fastify.log.debug({ msg: 'HMR client connected', ...client });
71
- const onClose = () => {
72
- this.fastify.log.debug({
73
- msg: 'HMR client disconnected',
74
- ...client,
75
- });
76
- this.clients.delete(client);
77
- };
78
- socket.addEventListener('error', onClose);
79
- socket.addEventListener('close', onClose);
80
- this.delegate.onClientConnected(platform, clientId);
38
+ });
81
39
  }
82
40
  }
@@ -21,9 +21,6 @@ export interface ReactNativeMessage {
21
21
  error?: Error;
22
22
  params?: Record<string, any>;
23
23
  }
24
- type WebSocketWithUpgradeReq = WebSocket & {
25
- upgradeReq?: IncomingMessage;
26
- };
27
24
  /**
28
25
  * Class for creating a WebSocket server and sending messages between development server
29
26
  * and the React Native applications.
@@ -56,8 +53,7 @@ export declare class WebSocketMessageServer extends WebSocketServer {
56
53
  * @returns True if message is a response.
57
54
  */
58
55
  static isResponse(message: Partial<ReactNativeMessage>): boolean;
59
- private clients;
60
- private nextClientId;
56
+ private upgradeRequests;
61
57
  /**
62
58
  * Create new instance of WebSocketMessageServer and attach it to the given Fastify instance.
63
59
  * Any logging information, will be passed through standard `fastify.log` API.
@@ -80,7 +76,7 @@ export declare class WebSocketMessageServer extends WebSocketServer {
80
76
  * @param clientId Id of the client.
81
77
  * @returns WebSocket connection.
82
78
  */
83
- getClientSocket(clientId: string): WebSocketWithUpgradeReq;
79
+ getClientSocket(clientId: string): WebSocket.WebSocket;
84
80
  /**
85
81
  * Process error by sending an error message to the client whose message caused the error
86
82
  * to occur.
@@ -128,12 +124,5 @@ export declare class WebSocketMessageServer extends WebSocketServer {
128
124
  * @param params Method parameters.
129
125
  */
130
126
  broadcast(method: string, params?: Record<string, any>): void;
131
- /**
132
- * Process new client's WebSocket connection.
133
- *
134
- * @param socket Incoming WebSocket connection.
135
- * @param request Upgrade request for the connection.
136
- */
137
- onConnection(socket: WebSocket, request: IncomingMessage): void;
127
+ onConnection(socket: WebSocket, request: IncomingMessage): string;
138
128
  }
139
- export {};
@@ -49,9 +49,8 @@ export class WebSocketMessageServer extends WebSocketServer {
49
49
  * @param fastify Fastify instance to attach the WebSocket server to.
50
50
  */
51
51
  constructor(fastify) {
52
- super(fastify, '/message');
53
- this.clients = new Map();
54
- this.nextClientId = 0;
52
+ super(fastify, { name: 'Message', path: '/message' });
53
+ this.upgradeRequests = {};
55
54
  }
56
55
  /**
57
56
  * Parse stringified message into a {@link ReactNativeMessage}.
@@ -202,9 +201,9 @@ export class WebSocketMessageServer extends WebSocketServer {
202
201
  break;
203
202
  case 'getpeers': {
204
203
  const output = {};
205
- this.clients.forEach((peerSocket, peerId) => {
204
+ this.clients.forEach((_, peerId) => {
206
205
  if (clientId !== peerId) {
207
- const { searchParams } = new URL(peerSocket.upgradeReq?.url || '');
206
+ const { searchParams } = new URL(this.upgradeRequests[peerId]?.url || '');
208
207
  output[peerId] = [...searchParams.entries()].reduce((acc, [key, value]) => {
209
208
  acc[key] = value;
210
209
  return acc;
@@ -271,25 +270,9 @@ export class WebSocketMessageServer extends WebSocketServer {
271
270
  broadcast(method, params) {
272
271
  this.sendBroadcast(undefined, { method, params });
273
272
  }
274
- /**
275
- * Process new client's WebSocket connection.
276
- *
277
- * @param socket Incoming WebSocket connection.
278
- * @param request Upgrade request for the connection.
279
- */
280
273
  onConnection(socket, request) {
281
- const clientId = `client#${this.nextClientId++}`;
282
- const client = socket;
283
- client.upgradeReq = request;
284
- this.clients.set(clientId, client);
285
- this.fastify.log.debug({ msg: 'Message client connected', clientId });
286
- const onClose = () => {
287
- this.fastify.log.debug({ msg: 'Message client disconnected', clientId });
288
- socket.removeAllListeners();
289
- this.clients.delete(clientId);
290
- };
291
- socket.addEventListener('error', onClose);
292
- socket.addEventListener('close', onClose);
274
+ const clientId = super.onConnection(socket, request);
275
+ this.upgradeRequests[clientId] = request;
293
276
  socket.addEventListener('message', (event) => {
294
277
  const message = this.parseMessage(event.data.toString(),
295
278
  // @ts-ignore
@@ -328,6 +311,7 @@ export class WebSocketMessageServer extends WebSocketServer {
328
311
  this.handleError(clientId, message, error);
329
312
  }
330
313
  });
314
+ return clientId;
331
315
  }
332
316
  }
333
317
  WebSocketMessageServer.PROTOCOL_VERSION = 2;
@@ -1,22 +1,12 @@
1
1
  import type { IncomingMessage } from 'node:http';
2
2
  import type { Socket } from 'node:net';
3
- /**
4
- * Delegate with implementation for HMR-specific functions.
5
- */
6
- export interface HmrDelegate {
7
- /** Get URI under which HMR server will be running, e.g: `/hmr` */
8
- getUriPath: () => string;
9
- /**
10
- * Callback for when the new HMR client is connected.
11
- *
12
- * Useful for running initial synchronization or any other side effect.
13
- *
14
- * @param platform Platform of the connected client.
15
- * @param clientId Id of the connected client.
16
- */
17
- onClientConnected: (platform: string, clientId: string) => void;
18
- }
3
+ import type { ServerOptions } from 'ws';
19
4
  export interface WebSocketServerInterface {
20
5
  shouldUpgrade(pathname: string): boolean;
21
6
  upgrade(request: IncomingMessage, socket: Socket, head: Buffer): void;
22
7
  }
8
+ export type WebSocketServerOptions = {
9
+ name: string;
10
+ path: string | string[];
11
+ wss?: Omit<ServerOptions, 'noServer' | 'server' | 'host' | 'port' | 'path'>;
12
+ };
@@ -22,7 +22,12 @@ declare module 'fastify' {
22
22
  };
23
23
  }
24
24
  }
25
- declare function wssPlugin(instance: FastifyInstance, { delegate, endpoints, }: {
25
+ declare module 'ws' {
26
+ interface WebSocket {
27
+ isAlive?: boolean;
28
+ }
29
+ }
30
+ declare function wssPlugin(instance: FastifyInstance, { endpoints, }: {
26
31
  delegate: Server.Delegate;
27
32
  endpoints?: Record<string, WebSocketServer>;
28
33
  }): Promise<void>;
@@ -12,7 +12,7 @@ import { WebSocketMessageServer } from './servers/WebSocketMessageServer.js';
12
12
  */
13
13
  const WS_DEVICE_URL = '/inspector/device';
14
14
  const WS_DEBUGGER_URL = '/inspector/debug';
15
- async function wssPlugin(instance, { delegate, endpoints, }) {
15
+ async function wssPlugin(instance, { endpoints, }) {
16
16
  const router = new WebSocketRouter(instance);
17
17
  const devClientServer = new WebSocketDevClientServer(instance);
18
18
  const messageServer = new WebSocketMessageServer(instance);
@@ -20,7 +20,7 @@ async function wssPlugin(instance, { delegate, endpoints, }) {
20
20
  webSocketMessageServer: messageServer,
21
21
  });
22
22
  const apiServer = new WebSocketApiServer(instance);
23
- const hmrServer = new WebSocketHMRServer(instance, delegate.hmr);
23
+ const hmrServer = new WebSocketHMRServer(instance);
24
24
  // @react-native/dev-middleware servers
25
25
  const deviceConnectionServer = new WebSocketServerAdapter(instance, WS_DEVICE_URL, endpoints?.[WS_DEVICE_URL]);
26
26
  const debuggerConnectionServer = new WebSocketServerAdapter(instance, WS_DEBUGGER_URL, endpoints?.[WS_DEBUGGER_URL]);
package/dist/types.d.ts CHANGED
@@ -2,11 +2,9 @@ import type { ServerOptions as HttpsServerOptions } from 'node:https';
2
2
  import type { FastifyBaseLogger } from 'fastify';
3
3
  import type { CompilerDelegate } from './plugins/compiler/types.js';
4
4
  import type { CodeFrame, InputStackFrame, ReactNativeStackFrame, StackFrame, SymbolicatorDelegate, SymbolicatorResults } from './plugins/symbolicate/types.js';
5
- import type { HmrDelegate } from './plugins/wss/types.js';
6
5
  import type { NormalizedOptions } from './utils/normalizeOptions.js';
7
6
  export type { CompilerDelegate };
8
7
  export type { CodeFrame, InputStackFrame, ReactNativeStackFrame, StackFrame, SymbolicatorDelegate, SymbolicatorResults, };
9
- export type { HmrDelegate };
10
8
  export interface DevServerOptions {
11
9
  /**
12
10
  * Hostname or IP address under which to run the development server.
@@ -51,8 +49,6 @@ export declare namespace Server {
51
49
  symbolicator: SymbolicatorDelegate;
52
50
  /** A logger delegate. */
53
51
  logger: LoggerDelegate;
54
- /** An HMR delegate. */
55
- hmr: HmrDelegate;
56
52
  /** An messages delegate. */
57
53
  messages: MessagesDelegate;
58
54
  /** An API delegate. */
@@ -76,11 +72,8 @@ export declare namespace Server {
76
72
  * Broadcast arbitrary event to all connected HMR clients for given `platform`.
77
73
  *
78
74
  * @param event Arbitrary event to broadcast.
79
- * @param platform Platform of the clients to which broadcast should be sent.
80
- * @param clientIds Ids of the client to which broadcast should be sent.
81
- * If `undefined` the broadcast will be sent to all connected clients for the given `platform`.
82
75
  */
83
- broadcastToHmrClients: <E = any>(event: E, platform: string, clientIds?: string[]) => void;
76
+ broadcastToHmrClients: <E = any>(event: E) => void;
84
77
  /**
85
78
  * Broadcast arbitrary method-like event to all connected message clients.
86
79
  *
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@callstack/repack-dev-server",
3
3
  "description": "A bundler-agnostic development server for React Native applications as part of @callstack/repack.",
4
4
  "license": "MIT",
5
- "version": "5.0.0-rc.11",
5
+ "version": "5.0.0-rc.12",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",