@callstack/repack-dev-server 5.0.0-rc.9 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +18 -23
- package/dist/createServer.js +15 -15
- package/dist/plugins/compiler/compilerPlugin.js +4 -3
- package/dist/plugins/devtools/devtoolsPlugin.d.ts +2 -3
- package/dist/plugins/devtools/devtoolsPlugin.js +2 -2
- package/dist/plugins/favicon/faviconPlugin.js +0 -1
- package/dist/plugins/wss/WebSocketServer.d.ts +10 -12
- package/dist/plugins/wss/WebSocketServer.js +42 -5
- package/dist/plugins/wss/servers/WebSocketApiServer.d.ts +0 -9
- package/dist/plugins/wss/servers/WebSocketApiServer.js +1 -23
- package/dist/plugins/wss/servers/WebSocketDevClientServer.d.ts +2 -8
- package/dist/plugins/wss/servers/WebSocketDevClientServer.js +4 -21
- package/dist/plugins/wss/servers/WebSocketEventsServer.d.ts +2 -8
- package/dist/plugins/wss/servers/WebSocketEventsServer.js +11 -22
- package/dist/plugins/wss/servers/WebSocketHMRServer.d.ts +2 -17
- package/dist/plugins/wss/servers/WebSocketHMRServer.js +8 -50
- package/dist/plugins/wss/servers/WebSocketMessageServer.d.ts +3 -14
- package/dist/plugins/wss/servers/WebSocketMessageServer.js +7 -23
- package/dist/plugins/wss/types.d.ts +6 -16
- package/dist/plugins/wss/wssPlugin.d.ts +8 -2
- package/dist/plugins/wss/wssPlugin.js +4 -4
- package/dist/types.d.ts +25 -26
- package/dist/utils/normalizeOptions.d.ts +12 -0
- package/dist/utils/normalizeOptions.js +28 -0
- package/package.json +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
|
-
<
|
|
2
|
-
<img src="https://raw.githubusercontent.com/callstack/repack/HEAD/logo.png"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
</p>
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/callstack/repack/HEAD/logo.png" width="650" alt="Re.Pack logo" />
|
|
3
|
+
<h3>A toolkit to build your React Native application with Rspack or Webpack.</h3>
|
|
4
|
+
</div>
|
|
5
|
+
<div align="center">
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[![
|
|
11
|
-
[![Version][version-badge]][version]
|
|
12
|
-
[![MIT License][license-badge]][license]
|
|
7
|
+
[![mit licence][license-badge]][license]
|
|
8
|
+
[![npm downloads][npm-downloads-badge]][npm-downloads]
|
|
9
|
+
[![Chat][chat-badge]][chat]
|
|
13
10
|
[![PRs Welcome][prs-welcome-badge]][prs-welcome]
|
|
14
|
-
[![Code of Conduct][coc-badge]][coc]
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
`@callstack/repack-dev-server` is a bundler-agnostic development server for React Native applications as part of [`@callstack/repack`](https://github.com/callstack/repack).
|
|
17
15
|
|
|
18
16
|
Check out our website at https://re-pack.dev for more info and documentation or out GitHub: https://github.com/callstack/repack.
|
|
19
17
|
|
|
20
18
|
<!-- badges -->
|
|
21
19
|
|
|
22
|
-
[
|
|
23
|
-
[
|
|
24
|
-
[
|
|
25
|
-
[
|
|
26
|
-
[
|
|
27
|
-
[license-badge]: https://img.shields.io/npm/l/@callstack/repack-debugger-app?style=flat-square
|
|
28
|
-
[license]: https://github.com/callstack/repack/blob/master/LICENSE
|
|
29
|
-
[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
|
20
|
+
[license-badge]: https://img.shields.io/npm/l/@callstack/repack?style=for-the-badge
|
|
21
|
+
[license]: https://github.com/callstack/repack/blob/main/LICENSE
|
|
22
|
+
[npm-downloads-badge]: https://img.shields.io/npm/dm/@callstack/repack?style=for-the-badge
|
|
23
|
+
[npm-downloads]: https://www.npmjs.com/package/@callstack/repack
|
|
24
|
+
[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
|
|
30
25
|
[prs-welcome]: ./CONTRIBUTING.md
|
|
31
|
-
[
|
|
32
|
-
[
|
|
26
|
+
[chat-badge]: https://img.shields.io/discord/426714625279524876.svg?style=for-the-badge
|
|
27
|
+
[chat]: https://discord.gg/Q4yr2rTWYF
|
package/dist/createServer.js
CHANGED
|
@@ -11,6 +11,7 @@ import multipartPlugin from './plugins/multipart/multipartPlugin.js';
|
|
|
11
11
|
import symbolicatePlugin from './plugins/symbolicate/sybmolicatePlugin.js';
|
|
12
12
|
import wssPlugin from './plugins/wss/wssPlugin.js';
|
|
13
13
|
import { Internal } from './types.js';
|
|
14
|
+
import { normalizeOptions } from './utils/normalizeOptions.js';
|
|
14
15
|
/**
|
|
15
16
|
* Create instance of development server, powered by Fastify.
|
|
16
17
|
*
|
|
@@ -20,9 +21,10 @@ import { Internal } from './types.js';
|
|
|
20
21
|
export async function createServer(config) {
|
|
21
22
|
// biome-ignore lint/style/useConst: needed in fastify constructor
|
|
22
23
|
let delegate;
|
|
24
|
+
const options = normalizeOptions(config.options);
|
|
23
25
|
/** Fastify instance powering the development server. */
|
|
24
26
|
const instance = Fastify({
|
|
25
|
-
disableRequestLogging:
|
|
27
|
+
disableRequestLogging: options.disableRequestLogging,
|
|
26
28
|
logger: {
|
|
27
29
|
level: 'trace',
|
|
28
30
|
stream: new Writable({
|
|
@@ -34,9 +36,10 @@ export async function createServer(config) {
|
|
|
34
36
|
},
|
|
35
37
|
}),
|
|
36
38
|
},
|
|
37
|
-
...(
|
|
39
|
+
...(options.https ? { https: options.https } : {}),
|
|
38
40
|
});
|
|
39
|
-
delegate =
|
|
41
|
+
delegate = config.delegate({
|
|
42
|
+
options,
|
|
40
43
|
log: instance.log,
|
|
41
44
|
notifyBuildStart: (platform) => {
|
|
42
45
|
instance.wss.apiServer.send({
|
|
@@ -50,16 +53,16 @@ export async function createServer(config) {
|
|
|
50
53
|
platform,
|
|
51
54
|
});
|
|
52
55
|
},
|
|
53
|
-
broadcastToHmrClients: (event
|
|
54
|
-
instance.wss.hmrServer.send(event
|
|
56
|
+
broadcastToHmrClients: (event) => {
|
|
57
|
+
instance.wss.hmrServer.send(event);
|
|
55
58
|
},
|
|
56
59
|
broadcastToMessageClients: ({ method, params }) => {
|
|
57
60
|
instance.wss.messageServer.broadcast(method, params);
|
|
58
61
|
},
|
|
59
62
|
});
|
|
60
63
|
const devMiddleware = createDevMiddleware({
|
|
61
|
-
projectRoot:
|
|
62
|
-
serverBaseUrl:
|
|
64
|
+
projectRoot: options.rootDir,
|
|
65
|
+
serverBaseUrl: options.url,
|
|
63
66
|
logger: instance.log,
|
|
64
67
|
unstable_experiments: {
|
|
65
68
|
// @ts-expect-error removed in 0.76, keep this for backkwards compatibility
|
|
@@ -70,11 +73,8 @@ export async function createServer(config) {
|
|
|
70
73
|
await instance.register(fastifySensible);
|
|
71
74
|
await instance.register(middie);
|
|
72
75
|
await instance.register(wssPlugin, {
|
|
73
|
-
options: {
|
|
74
|
-
...config.options,
|
|
75
|
-
endpoints: devMiddleware.websocketEndpoints,
|
|
76
|
-
},
|
|
77
76
|
delegate,
|
|
77
|
+
endpoints: devMiddleware.websocketEndpoints,
|
|
78
78
|
});
|
|
79
79
|
await instance.register(multipartPlugin);
|
|
80
80
|
await instance.register(apiPlugin, {
|
|
@@ -85,7 +85,7 @@ export async function createServer(config) {
|
|
|
85
85
|
delegate,
|
|
86
86
|
});
|
|
87
87
|
await instance.register(devtoolsPlugin, {
|
|
88
|
-
|
|
88
|
+
rootDir: options.rootDir,
|
|
89
89
|
});
|
|
90
90
|
await instance.register(symbolicatePlugin, {
|
|
91
91
|
delegate,
|
|
@@ -95,7 +95,7 @@ export async function createServer(config) {
|
|
|
95
95
|
await instance.register(faviconPlugin);
|
|
96
96
|
instance.addHook('onSend', async (request, reply, payload) => {
|
|
97
97
|
reply.header('X-Content-Type-Options', 'nosniff');
|
|
98
|
-
reply.header('X-React-Native-Project-Root',
|
|
98
|
+
reply.header('X-React-Native-Project-Root', options.rootDir);
|
|
99
99
|
const [pathname] = request.url.split('?');
|
|
100
100
|
if (pathname.endsWith('.map')) {
|
|
101
101
|
reply.header('Access-Control-Allow-Origin', 'devtools://devtools');
|
|
@@ -110,8 +110,8 @@ export async function createServer(config) {
|
|
|
110
110
|
/** Start the development server. */
|
|
111
111
|
async function start() {
|
|
112
112
|
await instance.listen({
|
|
113
|
-
port:
|
|
114
|
-
host:
|
|
113
|
+
port: options.port,
|
|
114
|
+
host: options.host,
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
/** Stop the development server. */
|
|
@@ -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.
|
|
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.
|
|
49
|
+
request.log.debug(error);
|
|
49
50
|
return reply.notFound(error.message);
|
|
50
51
|
}
|
|
51
52
|
},
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { FastifyInstance } from 'fastify';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
options: Server.Options;
|
|
2
|
+
declare function devtoolsPlugin(instance: FastifyInstance, { rootDir }: {
|
|
3
|
+
rootDir: string;
|
|
5
4
|
}): Promise<void>;
|
|
6
5
|
declare const _default: typeof devtoolsPlugin;
|
|
7
6
|
export default _default;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { openStackFrameInEditorMiddleware, openURLMiddleware, } from '@react-native-community/cli-server-api';
|
|
2
2
|
import fastifyPlugin from 'fastify-plugin';
|
|
3
|
-
async function devtoolsPlugin(instance, {
|
|
3
|
+
async function devtoolsPlugin(instance, { rootDir }) {
|
|
4
4
|
instance.use('/open-url', openURLMiddleware);
|
|
5
5
|
instance.use('/open-stack-frame', openStackFrameInEditorMiddleware({
|
|
6
|
-
watchFolders: [
|
|
6
|
+
watchFolders: [rootDir],
|
|
7
7
|
}));
|
|
8
8
|
instance.route({
|
|
9
9
|
method: ['GET', 'POST', 'PUT'],
|
|
@@ -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
|
|
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
|
|
27
|
+
* @param options WebSocketServer options.
|
|
24
28
|
*/
|
|
25
|
-
constructor(fastify: FastifyInstance,
|
|
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
|
|
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
|
|
14
|
+
* @param options WebSocketServer options.
|
|
15
15
|
*/
|
|
16
|
-
constructor(fastify,
|
|
16
|
+
constructor(fastify, options) {
|
|
17
|
+
this.nextClientId = 0;
|
|
18
|
+
this.timer = null;
|
|
17
19
|
this.fastify = fastify;
|
|
18
|
-
this.
|
|
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.
|
|
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
|
-
|
|
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,
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
17
|
-
super(fastify,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
25
|
+
send(event) {
|
|
30
26
|
const data = typeof event === 'string' ? event : JSON.stringify(event);
|
|
31
|
-
|
|
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
|
|
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):
|
|
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.
|
|
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((
|
|
204
|
+
this.clients.forEach((_, peerId) => {
|
|
206
205
|
if (clientId !== peerId) {
|
|
207
|
-
const { searchParams } = new 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 =
|
|
282
|
-
|
|
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
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { WebSocketServer } from 'ws';
|
|
2
3
|
import type { Server } from '../../types.js';
|
|
3
4
|
import { WebSocketRouter } from './WebSocketRouter.js';
|
|
4
5
|
import { WebSocketServerAdapter } from './WebSocketServerAdapter.js';
|
|
@@ -21,9 +22,14 @@ declare module 'fastify' {
|
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
|
-
declare
|
|
25
|
-
|
|
25
|
+
declare module 'ws' {
|
|
26
|
+
interface WebSocket {
|
|
27
|
+
isAlive?: boolean;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
declare function wssPlugin(instance: FastifyInstance, { endpoints, }: {
|
|
26
31
|
delegate: Server.Delegate;
|
|
32
|
+
endpoints?: Record<string, WebSocketServer>;
|
|
27
33
|
}): Promise<void>;
|
|
28
34
|
declare const _default: typeof wssPlugin;
|
|
29
35
|
export default _default;
|
|
@@ -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, {
|
|
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,10 +20,10 @@ async function wssPlugin(instance, { options, delegate, }) {
|
|
|
20
20
|
webSocketMessageServer: messageServer,
|
|
21
21
|
});
|
|
22
22
|
const apiServer = new WebSocketApiServer(instance);
|
|
23
|
-
const hmrServer = new WebSocketHMRServer(instance
|
|
23
|
+
const hmrServer = new WebSocketHMRServer(instance);
|
|
24
24
|
// @react-native/dev-middleware servers
|
|
25
|
-
const deviceConnectionServer = new WebSocketServerAdapter(instance, WS_DEVICE_URL,
|
|
26
|
-
const debuggerConnectionServer = new WebSocketServerAdapter(instance, WS_DEBUGGER_URL,
|
|
25
|
+
const deviceConnectionServer = new WebSocketServerAdapter(instance, WS_DEVICE_URL, endpoints?.[WS_DEVICE_URL]);
|
|
26
|
+
const debuggerConnectionServer = new WebSocketServerAdapter(instance, WS_DEBUGGER_URL, endpoints?.[WS_DEBUGGER_URL]);
|
|
27
27
|
router.registerServer(devClientServer);
|
|
28
28
|
router.registerServer(messageServer);
|
|
29
29
|
router.registerServer(eventsServer);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
|
+
import type { ServerOptions as HttpsServerOptions } from 'node:https';
|
|
1
2
|
import type { FastifyBaseLogger } from 'fastify';
|
|
2
|
-
import type { WebSocketServer } from 'ws';
|
|
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 {
|
|
5
|
+
import type { NormalizedOptions } from './utils/normalizeOptions.js';
|
|
6
6
|
export type { CompilerDelegate };
|
|
7
7
|
export type { CodeFrame, InputStackFrame, ReactNativeStackFrame, StackFrame, SymbolicatorDelegate, SymbolicatorResults, };
|
|
8
|
-
export
|
|
8
|
+
export interface DevServerOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Hostname or IP address under which to run the development server.
|
|
11
|
+
* Can be 'local-ip', 'local-ipv4', 'local-ipv6' or a custom string.
|
|
12
|
+
* When left unspecified, it will listen on all available network interfaces.
|
|
13
|
+
*/
|
|
14
|
+
host?: 'local-ip' | 'local-ipv4' | 'local-ipv6' | string;
|
|
15
|
+
/** Port under which to run the development server. */
|
|
16
|
+
port?: number;
|
|
17
|
+
/** Whether to enable Hot Module Replacement. */
|
|
18
|
+
hot?: boolean;
|
|
19
|
+
/** Options for running the server as HTTPS. If `undefined`, the server will run as HTTP. */
|
|
20
|
+
server?: 'http' | 'https' | {
|
|
21
|
+
type: 'http';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'https';
|
|
24
|
+
options?: HttpsServerOptions;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
9
27
|
export declare namespace Server {
|
|
10
28
|
/** Development server configuration. */
|
|
11
29
|
interface Config {
|
|
@@ -15,25 +33,9 @@ export declare namespace Server {
|
|
|
15
33
|
delegate: (context: DelegateContext) => Delegate;
|
|
16
34
|
}
|
|
17
35
|
/** Development server options. */
|
|
18
|
-
interface Options {
|
|
36
|
+
interface Options extends DevServerOptions {
|
|
19
37
|
/** Root directory of the project. */
|
|
20
38
|
rootDir: string;
|
|
21
|
-
/** Port under which to run the development server. */
|
|
22
|
-
port: number;
|
|
23
|
-
/**
|
|
24
|
-
* Hostname or IP address under which to run the development server.
|
|
25
|
-
* When left unspecified, it will listen on all available network interfaces, similarly to listening on '0.0.0.0'.
|
|
26
|
-
*/
|
|
27
|
-
host?: string;
|
|
28
|
-
/** Options for running the server as HTTPS. If `undefined`, the server will run as HTTP. */
|
|
29
|
-
https?: {
|
|
30
|
-
/** Path to certificate when running server as HTTPS. */
|
|
31
|
-
cert?: string;
|
|
32
|
-
/** Path to certificate key when running server as HTTPS. */
|
|
33
|
-
key?: string;
|
|
34
|
-
};
|
|
35
|
-
/** Additional endpoints with pre-configured servers */
|
|
36
|
-
endpoints?: Record<string, WebSocketServer>;
|
|
37
39
|
/** Whether to enable logging requests. */
|
|
38
40
|
logRequests?: boolean;
|
|
39
41
|
}
|
|
@@ -47,8 +49,6 @@ export declare namespace Server {
|
|
|
47
49
|
symbolicator: SymbolicatorDelegate;
|
|
48
50
|
/** A logger delegate. */
|
|
49
51
|
logger: LoggerDelegate;
|
|
50
|
-
/** An HMR delegate. */
|
|
51
|
-
hmr: HmrDelegate;
|
|
52
52
|
/** An messages delegate. */
|
|
53
53
|
messages: MessagesDelegate;
|
|
54
54
|
/** An API delegate. */
|
|
@@ -60,6 +60,8 @@ export declare namespace Server {
|
|
|
60
60
|
* Allows to emit logs, notify about compilation events and broadcast events to connected clients.
|
|
61
61
|
*/
|
|
62
62
|
interface DelegateContext {
|
|
63
|
+
/** Normalized development server options. */
|
|
64
|
+
options: NormalizedOptions;
|
|
63
65
|
/** A logger instance, useful for emitting logs from the delegate. */
|
|
64
66
|
log: FastifyBaseLogger;
|
|
65
67
|
/** Send notification about compilation start for given `platform`. */
|
|
@@ -70,11 +72,8 @@ export declare namespace Server {
|
|
|
70
72
|
* Broadcast arbitrary event to all connected HMR clients for given `platform`.
|
|
71
73
|
*
|
|
72
74
|
* @param event Arbitrary event to broadcast.
|
|
73
|
-
* @param platform Platform of the clients to which broadcast should be sent.
|
|
74
|
-
* @param clientIds Ids of the client to which broadcast should be sent.
|
|
75
|
-
* If `undefined` the broadcast will be sent to all connected clients for the given `platform`.
|
|
76
75
|
*/
|
|
77
|
-
broadcastToHmrClients: <E = any>(event: E
|
|
76
|
+
broadcastToHmrClients: <E = any>(event: E) => void;
|
|
78
77
|
/**
|
|
79
78
|
* Broadcast arbitrary method-like event to all connected message clients.
|
|
80
79
|
*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ServerOptions as HttpsServerOptions } from 'node:https';
|
|
2
|
+
import type { Server } from '../types.js';
|
|
3
|
+
export interface NormalizedOptions {
|
|
4
|
+
host: string;
|
|
5
|
+
port: number;
|
|
6
|
+
https: HttpsServerOptions | undefined;
|
|
7
|
+
hot: boolean;
|
|
8
|
+
url: string;
|
|
9
|
+
disableRequestLogging: boolean;
|
|
10
|
+
rootDir: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function normalizeOptions(options: Server.Options): NormalizedOptions;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function normalizeHttpsOptions(serverOptions) {
|
|
2
|
+
if (serverOptions &&
|
|
3
|
+
typeof serverOptions === 'object' &&
|
|
4
|
+
serverOptions.type === 'https') {
|
|
5
|
+
return serverOptions.options;
|
|
6
|
+
}
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
export function normalizeOptions(options) {
|
|
10
|
+
const host = options.host ?? 'localhost';
|
|
11
|
+
const port = options.port ?? 8081;
|
|
12
|
+
const https = normalizeHttpsOptions(options.server);
|
|
13
|
+
const hot = options.hot ?? false;
|
|
14
|
+
const protocol = https ? 'https' : 'http';
|
|
15
|
+
const url = `${protocol}://${host}:${options.port}`;
|
|
16
|
+
return {
|
|
17
|
+
// webpack dev server compatible options
|
|
18
|
+
host,
|
|
19
|
+
port,
|
|
20
|
+
https,
|
|
21
|
+
hot,
|
|
22
|
+
url,
|
|
23
|
+
// fastify options
|
|
24
|
+
disableRequestLogging: !options.logRequests,
|
|
25
|
+
// project options
|
|
26
|
+
rootDir: options.rootDir,
|
|
27
|
+
};
|
|
28
|
+
}
|
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
|
|
5
|
+
"version": "5.0.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|