mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-14 13:46:55 +03:00
chore(deps): update socketcluster to v16 (major) (#1167)
* chore(deps): update socketcluster to v16 * Use the right packages * stash * stash * stash * Fixes * Fixes Co-authored-by: Renovate Bot <bot@renovateapp.com> Co-authored-by: Nathan Bierema <nbierema@gmail.com>
This commit is contained in:
parent
1ee787e353
commit
6c9ae2713f
|
@ -64,7 +64,7 @@
|
||||||
"react-redux": "^8.0.2",
|
"react-redux": "^8.0.2",
|
||||||
"redux": "^4.2.0",
|
"redux": "^4.2.0",
|
||||||
"redux-persist": "^6.0.0",
|
"redux-persist": "^6.0.0",
|
||||||
"socketcluster-client": "^14.3.2"
|
"socketcluster-client": "^16.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.17.10",
|
"@babel/cli": "^7.17.10",
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
"@types/node": "^16.11.38",
|
"@types/node": "^16.11.38",
|
||||||
"@types/react": "^18.0.12",
|
"@types/react": "^18.0.12",
|
||||||
"@types/react-dom": "^18.0.5",
|
"@types/react-dom": "^18.0.5",
|
||||||
"@types/socketcluster-client": "^13.0.5",
|
"@types/socketcluster-client": "^16.0.0",
|
||||||
"@types/styled-components": "^5.1.25",
|
"@types/styled-components": "^5.1.25",
|
||||||
"@types/testing-library__jest-dom": "^5.14.3",
|
"@types/testing-library__jest-dom": "^5.14.3",
|
||||||
"@types/webpack-env": "^1.17.0",
|
"@types/webpack-env": "^1.17.0",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SchemeName, ThemeName } from '@redux-devtools/ui';
|
import { SchemeName, ThemeName } from '@redux-devtools/ui';
|
||||||
import { AuthStates, States } from 'socketcluster-client/lib/scclientsocket';
|
import { AuthStates, States } from 'socketcluster-client/lib/clientsocket';
|
||||||
import { REHYDRATE } from 'redux-persist';
|
import { REHYDRATE } from 'redux-persist';
|
||||||
import {
|
import {
|
||||||
CHANGE_SECTION,
|
CHANGE_SECTION,
|
||||||
|
|
|
@ -16,7 +16,7 @@ export const {
|
||||||
AUTHENTICATED,
|
AUTHENTICATED,
|
||||||
PENDING,
|
PENDING,
|
||||||
UNAUTHENTICATED,
|
UNAUTHENTICATED,
|
||||||
} = socketCluster.SCClientSocket as unknown as States;
|
} = socketCluster.AGClientSocket as unknown as States;
|
||||||
export const CONNECT_REQUEST = 'socket/CONNECT_REQUEST';
|
export const CONNECT_REQUEST = 'socket/CONNECT_REQUEST';
|
||||||
export const CONNECT_SUCCESS = 'socket/CONNECT_SUCCESS';
|
export const CONNECT_SUCCESS = 'socket/CONNECT_SUCCESS';
|
||||||
export const CONNECT_ERROR = 'socket/CONNECT_ERROR';
|
export const CONNECT_ERROR = 'socket/CONNECT_ERROR';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import socketCluster, { SCClientSocket } from 'socketcluster-client';
|
import socketClusterClient, { AGClientSocket } from 'socketcluster-client';
|
||||||
import { stringify } from 'jsan';
|
import { stringify } from 'jsan';
|
||||||
import { Dispatch, MiddlewareAPI } from 'redux';
|
import { Dispatch, MiddlewareAPI } from 'redux';
|
||||||
import * as actions from '../constants/socketActionTypes';
|
import * as actions from '../constants/socketActionTypes';
|
||||||
|
@ -25,11 +25,16 @@ import {
|
||||||
import { nonReduxDispatch } from '../utils/monitorActions';
|
import { nonReduxDispatch } from '../utils/monitorActions';
|
||||||
import { StoreState } from '../reducers';
|
import { StoreState } from '../reducers';
|
||||||
|
|
||||||
let socket: SCClientSocket;
|
let socket: AGClientSocket;
|
||||||
let store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>;
|
let store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>;
|
||||||
|
|
||||||
function emit({ message: type, id, instanceId, action, state }: EmitAction) {
|
function emit({ message: type, id, instanceId, action, state }: EmitAction) {
|
||||||
socket.emit(id ? `sc-${id}` : 'respond', { type, action, state, instanceId });
|
void socket.transmit(id ? `sc-${id}` : 'respond', {
|
||||||
|
type,
|
||||||
|
action,
|
||||||
|
state,
|
||||||
|
instanceId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startMonitoring(channel: string) {
|
function startMonitoring(channel: string) {
|
||||||
|
@ -120,7 +125,7 @@ function monitoring(request: MonitoringRequest) {
|
||||||
instanceId === instances.selected &&
|
instanceId === instances.selected &&
|
||||||
(request.type === 'ACTION' || request.type === 'STATE')
|
(request.type === 'ACTION' || request.type === 'STATE')
|
||||||
) {
|
) {
|
||||||
socket.emit('respond', {
|
void socket.transmit('respond', {
|
||||||
type: 'SYNC',
|
type: 'SYNC',
|
||||||
state: stringify(instances.states[instanceId]),
|
state: stringify(instances.states[instanceId]),
|
||||||
id: request.id,
|
id: request.id,
|
||||||
|
@ -134,65 +139,84 @@ function subscribe(
|
||||||
subscription: typeof UPDATE_STATE | typeof UPDATE_REPORTS
|
subscription: typeof UPDATE_STATE | typeof UPDATE_REPORTS
|
||||||
) {
|
) {
|
||||||
const channel = socket.subscribe(channelName);
|
const channel = socket.subscribe(channelName);
|
||||||
if (subscription === UPDATE_STATE) channel.watch(monitoring);
|
if (subscription === UPDATE_STATE) {
|
||||||
else {
|
void (async () => {
|
||||||
|
for await (const data of channel) {
|
||||||
|
monitoring(data as MonitoringRequest);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
} else {
|
||||||
const watcher = (request: UpdateReportsRequest) => {
|
const watcher = (request: UpdateReportsRequest) => {
|
||||||
store.dispatch({ type: subscription, request });
|
store.dispatch({ type: subscription, request });
|
||||||
};
|
};
|
||||||
channel.watch(watcher);
|
void (async () => {
|
||||||
socket.on(channelName, watcher);
|
for await (const data of channel) {
|
||||||
|
watcher(data as UpdateReportsRequest);
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleConnection() {
|
function handleConnection() {
|
||||||
socket.on('connect', (status) => {
|
void (async () => {
|
||||||
store.dispatch({
|
for await (const data of socket.listener('connect')) {
|
||||||
type: actions.CONNECT_SUCCESS,
|
store.dispatch({
|
||||||
payload: {
|
type: actions.CONNECT_SUCCESS,
|
||||||
id: status.id,
|
payload: {
|
||||||
authState: socket.authState,
|
id: data.id,
|
||||||
socketState: socket.state,
|
authState: socket.authState,
|
||||||
},
|
socketState: socket.state,
|
||||||
error: status.authError,
|
},
|
||||||
});
|
// @ts-expect-error Is this legitimate?
|
||||||
if (socket.authState !== actions.AUTHENTICATED) {
|
error: data.authError,
|
||||||
store.dispatch({ type: actions.AUTH_REQUEST });
|
});
|
||||||
|
if (socket.authState !== actions.AUTHENTICATED) {
|
||||||
|
store.dispatch({ type: actions.AUTH_REQUEST });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
})();
|
||||||
socket.on('disconnect', (code) => {
|
void (async () => {
|
||||||
store.dispatch({ type: actions.DISCONNECTED, code });
|
for await (const data of socket.listener('disconnect')) {
|
||||||
});
|
store.dispatch({ type: actions.DISCONNECTED, code: data.code });
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
socket.on('subscribe', (channel) => {
|
void (async () => {
|
||||||
store.dispatch({ type: actions.SUBSCRIBE_SUCCESS, channel });
|
for await (const data of socket.listener('subscribe')) {
|
||||||
});
|
store.dispatch({
|
||||||
socket.on('unsubscribe', (channel) => {
|
type: actions.SUBSCRIBE_SUCCESS,
|
||||||
socket.unsubscribe(channel);
|
channel: data.channel,
|
||||||
socket.unwatch(channel);
|
});
|
||||||
socket.off(channel);
|
}
|
||||||
store.dispatch({ type: actions.UNSUBSCRIBE, channel });
|
})();
|
||||||
});
|
void (async () => {
|
||||||
socket.on('subscribeFail', (error) => {
|
for await (const data of socket.listener('unsubscribe')) {
|
||||||
store.dispatch({
|
void socket.unsubscribe(data.channel);
|
||||||
type: actions.SUBSCRIBE_ERROR,
|
store.dispatch({ type: actions.UNSUBSCRIBE, channel: data.channel });
|
||||||
error,
|
}
|
||||||
status: 'subscribeFail',
|
})();
|
||||||
});
|
void (async () => {
|
||||||
});
|
for await (const data of socket.listener('subscribeFail')) {
|
||||||
socket.on('dropOut', (error) => {
|
store.dispatch({
|
||||||
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'dropOut' });
|
type: actions.SUBSCRIBE_ERROR,
|
||||||
});
|
error: data.error,
|
||||||
|
status: 'subscribeFail',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
socket.on('error', (error) => {
|
void (async () => {
|
||||||
store.dispatch({ type: actions.CONNECT_ERROR, error });
|
for await (const data of socket.listener('error')) {
|
||||||
});
|
store.dispatch({ type: actions.CONNECT_ERROR, error: data.error });
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
if (process.env.NODE_ENV === 'test') return;
|
if (process.env.NODE_ENV === 'test') return;
|
||||||
const connection = store.getState().connection;
|
const connection = store.getState().connection;
|
||||||
try {
|
try {
|
||||||
socket = socketCluster.create(connection.options);
|
socket = socketClusterClient.create(connection.options);
|
||||||
handleConnection();
|
handleConnection();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
store.dispatch({ type: actions.CONNECT_ERROR, error: error as Error });
|
store.dispatch({ type: actions.CONNECT_ERROR, error: error as Error });
|
||||||
|
@ -205,43 +229,42 @@ function connect() {
|
||||||
function disconnect() {
|
function disconnect() {
|
||||||
if (socket) {
|
if (socket) {
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
socket.off();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function login() {
|
function login() {
|
||||||
socket.emit('login', {}, (error: Error, baseChannel: string) => {
|
void (async () => {
|
||||||
if (error) {
|
try {
|
||||||
store.dispatch({ type: actions.AUTH_ERROR, error });
|
const baseChannel = (await socket.invoke('login', {})) as string;
|
||||||
return;
|
store.dispatch({ type: actions.AUTH_SUCCESS, baseChannel });
|
||||||
|
store.dispatch({
|
||||||
|
type: actions.SUBSCRIBE_REQUEST,
|
||||||
|
channel: baseChannel,
|
||||||
|
subscription: UPDATE_STATE,
|
||||||
|
});
|
||||||
|
store.dispatch({
|
||||||
|
type: actions.SUBSCRIBE_REQUEST,
|
||||||
|
channel: 'report',
|
||||||
|
subscription: UPDATE_REPORTS,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
store.dispatch({ type: actions.AUTH_ERROR, error: error as Error });
|
||||||
}
|
}
|
||||||
store.dispatch({ type: actions.AUTH_SUCCESS, baseChannel });
|
})();
|
||||||
store.dispatch({
|
|
||||||
type: actions.SUBSCRIBE_REQUEST,
|
|
||||||
channel: baseChannel,
|
|
||||||
subscription: UPDATE_STATE,
|
|
||||||
});
|
|
||||||
store.dispatch({
|
|
||||||
type: actions.SUBSCRIBE_REQUEST,
|
|
||||||
channel: 'report',
|
|
||||||
subscription: UPDATE_REPORTS,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReport(reportId: unknown) {
|
function getReport(reportId: unknown) {
|
||||||
socket.emit(
|
void (async () => {
|
||||||
'getReport',
|
try {
|
||||||
reportId,
|
const data = (await socket.invoke('getReport', reportId)) as {
|
||||||
(error: Error, data: { payload: string }) => {
|
payload: string;
|
||||||
if (error) {
|
};
|
||||||
store.dispatch({ type: GET_REPORT_ERROR, error });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
store.dispatch({ type: GET_REPORT_SUCCESS, data });
|
store.dispatch({ type: GET_REPORT_SUCCESS, data });
|
||||||
store.dispatch(importState(data.payload));
|
store.dispatch(importState(data.payload));
|
||||||
|
} catch (error) {
|
||||||
|
store.dispatch({ type: GET_REPORT_ERROR, error: error as Error });
|
||||||
}
|
}
|
||||||
);
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function api(inStore: MiddlewareAPI<Dispatch<StoreAction>, StoreState>) {
|
export function api(inStore: MiddlewareAPI<Dispatch<StoreAction>, StoreState>) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AuthStates, States } from 'socketcluster-client/lib/scclientsocket';
|
import { AuthStates, States } from 'socketcluster-client/lib/clientsocket';
|
||||||
import * as actions from '../constants/socketActionTypes';
|
import * as actions from '../constants/socketActionTypes';
|
||||||
import { StoreAction } from '../actions';
|
import { StoreAction } from '../actions';
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
"react-dom": "^18.1.0",
|
"react-dom": "^18.1.0",
|
||||||
"react-is": "^18.1.0",
|
"react-is": "^18.1.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"socketcluster": "^14.4.2",
|
"socketcluster-server": "^16.2.1",
|
||||||
"sqlite3": "^5.0.8",
|
"sqlite3": "^5.0.8",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
|
@ -76,9 +76,8 @@
|
||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/node": "^16.11.38",
|
"@types/node": "^16.11.38",
|
||||||
"@types/semver": "^7.3.9",
|
"@types/semver": "^7.3.9",
|
||||||
"@types/socketcluster": "^14.0.4",
|
"@types/socketcluster-client": "^16.0.0",
|
||||||
"@types/socketcluster-client": "^13.0.5",
|
"@types/socketcluster-server": "^16.1.0",
|
||||||
"@types/socketcluster-server": "^14.2.6",
|
|
||||||
"@types/styled-components": "^5.1.25",
|
"@types/styled-components": "^5.1.25",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
|
@ -90,7 +89,7 @@
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"socketcluster-client": "^14.3.2",
|
"socketcluster-client": "^16.1.1",
|
||||||
"supertest": "^6.2.3",
|
"supertest": "^6.2.3",
|
||||||
"ts-jest": "^27.1.5",
|
"ts-jest": "^27.1.5",
|
||||||
"typescript": "~4.7.3"
|
"typescript": "~4.7.3"
|
||||||
|
|
|
@ -88,10 +88,9 @@ if (argv.injectserver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
server(argv).then(function (r) {
|
server(argv).then(async function (r) {
|
||||||
if (argv.open && argv.open !== 'false') {
|
if (argv.open && argv.open !== 'false') {
|
||||||
r.on('ready', async function () {
|
await r.listener('ready').once();
|
||||||
await openApp(argv.open as string, options);
|
await openApp(argv.open as string, options);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import knexModule, { Knex } from 'knex';
|
import knexModule, { Knex } from 'knex';
|
||||||
import { SCServer } from 'socketcluster-server';
|
import { AGServer } from 'socketcluster-server';
|
||||||
|
|
||||||
export default function connector(options: SCServer.SCServerOptions) {
|
export default function connector(options: AGServer.AGServerOptions) {
|
||||||
const dbOptions = options.dbOptions as Knex.Config;
|
const dbOptions = options.dbOptions as Knex.Config;
|
||||||
dbOptions.useNullAsDefault = true;
|
dbOptions.useNullAsDefault = true;
|
||||||
if (!(dbOptions as any).migrate) {
|
if (!(dbOptions as any).migrate) {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
import express from 'express';
|
||||||
|
import http from 'http';
|
||||||
import getPort from 'getport';
|
import getPort from 'getport';
|
||||||
import SocketCluster from 'socketcluster';
|
import socketClusterServer from 'socketcluster-server';
|
||||||
import getOptions, { Options } from './options';
|
import getOptions, { Options } from './options';
|
||||||
|
import routes from './routes';
|
||||||
|
import createStore from './store';
|
||||||
|
|
||||||
// var LOG_LEVEL_NONE = 0;
|
// var LOG_LEVEL_NONE = 0;
|
||||||
const LOG_LEVEL_ERROR = 1;
|
const LOG_LEVEL_ERROR = 1;
|
||||||
|
@ -8,16 +12,14 @@ const LOG_LEVEL_WARN = 2;
|
||||||
const LOG_LEVEL_INFO = 3;
|
const LOG_LEVEL_INFO = 3;
|
||||||
|
|
||||||
export interface ExtendedOptions extends Options {
|
export interface ExtendedOptions extends Options {
|
||||||
workerController: string;
|
|
||||||
allowClientPublish: boolean;
|
allowClientPublish: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (argv: { [arg: string]: any }): Promise<{
|
export default function (argv: { [arg: string]: any }): Promise<{
|
||||||
portAlreadyUsed?: boolean;
|
portAlreadyUsed?: boolean;
|
||||||
on: (status: 'ready', cb: (() => void) | (() => Promise<void>)) => void;
|
listener: (eventName: 'ready') => { once(): Promise<void> };
|
||||||
}> {
|
}> {
|
||||||
const options = Object.assign(getOptions(argv), {
|
const options = Object.assign(getOptions(argv), {
|
||||||
workerController: __dirname + '/worker.js',
|
|
||||||
allowClientPublish: false,
|
allowClientPublish: false,
|
||||||
});
|
});
|
||||||
const port = options.port;
|
const port = options.port;
|
||||||
|
@ -39,8 +41,12 @@ export default function (argv: { [arg: string]: any }): Promise<{
|
||||||
}
|
}
|
||||||
resolve({
|
resolve({
|
||||||
portAlreadyUsed: true,
|
portAlreadyUsed: true,
|
||||||
on: function (status: string, cb: () => void) {
|
listener: function (eventName: 'ready') {
|
||||||
cb();
|
return {
|
||||||
|
once() {
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +54,100 @@ export default function (argv: { [arg: string]: any }): Promise<{
|
||||||
console.log('[ReduxDevTools] Start server...');
|
console.log('[ReduxDevTools] Start server...');
|
||||||
console.log('-'.repeat(80) + '\n');
|
console.log('-'.repeat(80) + '\n');
|
||||||
}
|
}
|
||||||
resolve(new SocketCluster(options));
|
const httpServer = http.createServer();
|
||||||
|
const agServer = socketClusterServer.attach(httpServer, options);
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
httpServer.on('request', app);
|
||||||
|
const store = createStore(options);
|
||||||
|
app.use(routes(options, store, agServer));
|
||||||
|
|
||||||
|
agServer.setMiddleware(
|
||||||
|
agServer.MIDDLEWARE_INBOUND,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
async (middlewareStream) => {
|
||||||
|
for await (const action of middlewareStream) {
|
||||||
|
if (action.type === action.TRANSMIT) {
|
||||||
|
const channel = action.receiver;
|
||||||
|
const data = action.data;
|
||||||
|
if (
|
||||||
|
channel.substring(0, 3) === 'sc-' ||
|
||||||
|
channel === 'respond' ||
|
||||||
|
channel === 'log'
|
||||||
|
) {
|
||||||
|
void agServer.exchange.transmitPublish(channel, data);
|
||||||
|
} else if (channel === 'log-noid') {
|
||||||
|
void agServer.exchange.transmitPublish('log', {
|
||||||
|
id: action.socket.id,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (action.type === action.SUBSCRIBE) {
|
||||||
|
if (action.channel === 'report') {
|
||||||
|
store
|
||||||
|
.list()
|
||||||
|
.then(function (data) {
|
||||||
|
void agServer.exchange.transmitPublish('report', {
|
||||||
|
type: 'list',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.error(error); // eslint-disable-line no-console
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action.allow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
void (async () => {
|
||||||
|
for await (const { socket } of agServer.listener('connection')) {
|
||||||
|
let channelToWatch: string, channelToEmit: string;
|
||||||
|
void (async () => {
|
||||||
|
for await (const request of socket.procedure('login')) {
|
||||||
|
const credentials = request.data;
|
||||||
|
if (credentials === 'master') {
|
||||||
|
channelToWatch = 'respond';
|
||||||
|
channelToEmit = 'log';
|
||||||
|
} else {
|
||||||
|
channelToWatch = 'log';
|
||||||
|
channelToEmit = 'respond';
|
||||||
|
}
|
||||||
|
request.end(channelToWatch);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
void (async () => {
|
||||||
|
for await (const request of socket.procedure('getReport')) {
|
||||||
|
const id = request.data as string;
|
||||||
|
store
|
||||||
|
.get(id)
|
||||||
|
.then(function (data) {
|
||||||
|
request.end(data);
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.error(error); // eslint-disable-line no-console
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
void (async () => {
|
||||||
|
for await (const data of socket.listener('disconnect')) {
|
||||||
|
const channel = agServer.exchange.channel('sc-' + socket.id);
|
||||||
|
channel.unsubscribe();
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
void agServer.exchange.transmitPublish(channelToEmit!, {
|
||||||
|
id: socket.id,
|
||||||
|
type: 'DISCONNECTED',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
httpServer.listen(options.port);
|
||||||
|
// @ts-expect-error Shouldn't there be a 'ready' event?
|
||||||
|
resolve(agServer);
|
||||||
}
|
}
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ import morgan from 'morgan';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { SCServer } from 'socketcluster-server';
|
import { AGServer } from 'socketcluster-server';
|
||||||
import { ApolloServer } from 'apollo-server-express';
|
import { ApolloServer } from 'apollo-server-express';
|
||||||
import { AddData, ReportBaseFields, Store } from './store';
|
import { AddData, ReportBaseFields, Store } from './store';
|
||||||
import { resolvers, schema } from './api/schema';
|
import { resolvers, schema } from './api/schema';
|
||||||
|
@ -21,9 +21,9 @@ function serveUmdModule(name: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function routes(
|
function routes(
|
||||||
options: SCServer.SCServerOptions,
|
options: AGServer.AGServerOptions,
|
||||||
store: Store,
|
store: Store,
|
||||||
scServer: SCServer
|
scServer: AGServer
|
||||||
): Router {
|
): Router {
|
||||||
const limit = options.maxRequestBody;
|
const limit = options.maxRequestBody;
|
||||||
const logHTTPRequests = options.logHTTPRequests;
|
const logHTTPRequests = options.logHTTPRequests;
|
||||||
|
@ -65,7 +65,8 @@ function routes(
|
||||||
serveUmdModule('@redux-devtools/app');
|
serveUmdModule('@redux-devtools/app');
|
||||||
|
|
||||||
app.get('/port.js', function (req, res) {
|
app.get('/port.js', function (req, res) {
|
||||||
res.send(`reduxDevToolsPort = ${options.port!}`);
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
|
res.send(`reduxDevToolsPort = ${options.port}`);
|
||||||
});
|
});
|
||||||
app.get('*', function (req, res) {
|
app.get('*', function (req, res) {
|
||||||
res.sendFile(path.join(__dirname, '../app/index.html'));
|
res.sendFile(path.join(__dirname, '../app/index.html'));
|
||||||
|
@ -108,7 +109,7 @@ function routes(
|
||||||
id: (r as ReportBaseFields).id,
|
id: (r as ReportBaseFields).id,
|
||||||
error: (r as { error: string }).error,
|
error: (r as { error: string }).error,
|
||||||
});
|
});
|
||||||
scServer.exchange.publish('report', {
|
void scServer.exchange.transmitPublish('report', {
|
||||||
type: 'add',
|
type: 'add',
|
||||||
data: r,
|
data: r,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { v4 as uuidV4 } from 'uuid';
|
import { v4 as uuidV4 } from 'uuid';
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
import { SCServer } from 'socketcluster-server';
|
import { AGServer } from 'socketcluster-server';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import connector from './db/connector';
|
import connector from './db/connector';
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ export interface Store {
|
||||||
add: (data: AddData) => Promise<ReportBaseFields | { error: string }>;
|
add: (data: AddData) => Promise<ReportBaseFields | { error: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStore(options: SCServer.SCServerOptions): Store {
|
function createStore(options: AGServer.AGServerOptions): Store {
|
||||||
knex = connector(options);
|
knex = connector(options);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import SCWorker from 'socketcluster/scworker';
|
|
||||||
import express from 'express';
|
|
||||||
import routes from './routes';
|
|
||||||
import createStore from './store';
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
|
|
||||||
class Worker extends SCWorker {
|
|
||||||
run() {
|
|
||||||
const httpServer = this.httpServer;
|
|
||||||
const scServer = this.scServer;
|
|
||||||
const options = this.options;
|
|
||||||
const store = createStore(options);
|
|
||||||
|
|
||||||
httpServer.on('request', app);
|
|
||||||
|
|
||||||
app.use(routes(options, store, scServer));
|
|
||||||
|
|
||||||
scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, function (req, next) {
|
|
||||||
const channel = req.event;
|
|
||||||
const data = req.data;
|
|
||||||
if (
|
|
||||||
channel.substr(0, 3) === 'sc-' ||
|
|
||||||
channel === 'respond' ||
|
|
||||||
channel === 'log'
|
|
||||||
) {
|
|
||||||
scServer.exchange.publish(channel, data);
|
|
||||||
} else if (channel === 'log-noid') {
|
|
||||||
scServer.exchange.publish('log', { id: req.socket.id, data: data });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
scServer.addMiddleware(scServer.MIDDLEWARE_SUBSCRIBE, function (req, next) {
|
|
||||||
next();
|
|
||||||
if (req.channel === 'report') {
|
|
||||||
store
|
|
||||||
.list()
|
|
||||||
.then(function (data) {
|
|
||||||
req.socket.emit(req.channel!, { type: 'list', data: data });
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.error(error); // eslint-disable-line no-console
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scServer.on('connection', function (socket) {
|
|
||||||
let channelToWatch: string, channelToEmit: string;
|
|
||||||
socket.on('login', function (this: Worker, credentials, respond) {
|
|
||||||
if (credentials === 'master') {
|
|
||||||
channelToWatch = 'respond';
|
|
||||||
channelToEmit = 'log';
|
|
||||||
} else {
|
|
||||||
channelToWatch = 'log';
|
|
||||||
channelToEmit = 'respond';
|
|
||||||
}
|
|
||||||
this.exchange.subscribe('sc-' + socket.id).watch(function (msg) {
|
|
||||||
socket.emit(channelToWatch, msg);
|
|
||||||
});
|
|
||||||
respond(null, channelToWatch);
|
|
||||||
});
|
|
||||||
socket.on('getReport', function (id: string, respond) {
|
|
||||||
store
|
|
||||||
.get(id)
|
|
||||||
.then(function (data) {
|
|
||||||
respond(null, data);
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.error(error); // eslint-disable-line no-console
|
|
||||||
});
|
|
||||||
});
|
|
||||||
socket.on('disconnect', function (this: Worker) {
|
|
||||||
const channel = this.exchange.channel('sc-' + socket.id);
|
|
||||||
channel.unsubscribe();
|
|
||||||
channel.destroy();
|
|
||||||
scServer.exchange.publish(channelToEmit, {
|
|
||||||
id: socket.id,
|
|
||||||
type: 'DISCONNECTED',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new Worker();
|
|
|
@ -1,6 +1,6 @@
|
||||||
import childProcess from 'child_process';
|
import childProcess from 'child_process';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import scClient from 'socketcluster-client';
|
import socketClusterClient from 'socketcluster-client';
|
||||||
|
|
||||||
jest.setTimeout(10000);
|
jest.setTimeout(10000);
|
||||||
|
|
||||||
|
@ -44,20 +44,30 @@ describe('Server', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Realtime monitoring', function () {
|
describe('Realtime monitoring', function () {
|
||||||
let socket: scClient.SCClientSocket,
|
let socket: socketClusterClient.AGClientSocket,
|
||||||
socket2: scClient.SCClientSocket,
|
socket2: socketClusterClient.AGClientSocket,
|
||||||
channel;
|
channel;
|
||||||
beforeAll(function () {
|
beforeAll(function () {
|
||||||
socket = scClient.connect({ hostname: 'localhost', port: 8000 });
|
socket = socketClusterClient.create({
|
||||||
|
hostname: 'localhost',
|
||||||
|
port: 8000,
|
||||||
|
});
|
||||||
socket.connect();
|
socket.connect();
|
||||||
socket.on('error', function (error) {
|
void (async () => {
|
||||||
console.error('Socket1 error', error); // eslint-disable-line no-console
|
for await (const data of socket.listener('error')) {
|
||||||
|
console.error('Socket1 error', data.error); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
socket2 = socketClusterClient.create({
|
||||||
|
hostname: 'localhost',
|
||||||
|
port: 8000,
|
||||||
});
|
});
|
||||||
socket2 = scClient.connect({ hostname: 'localhost', port: 8000 });
|
|
||||||
socket2.connect();
|
socket2.connect();
|
||||||
socket.on('error', function (error) {
|
void (async () => {
|
||||||
console.error('Socket2 error', error); // eslint-disable-line no-console
|
for await (const data of socket2.listener('error')) {
|
||||||
});
|
console.error('Socket2 error', data.error); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
})();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(function () {
|
afterAll(function () {
|
||||||
|
@ -65,73 +75,50 @@ describe('Server', function () {
|
||||||
socket2.disconnect();
|
socket2.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should connect', function () {
|
it('should connect', async function () {
|
||||||
return new Promise<void>((done) => {
|
const data = await socket.listener('connect').once();
|
||||||
socket.on('connect', function (status) {
|
expect(data.id).toBeTruthy();
|
||||||
expect(status.id).toBeTruthy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should login', function () {
|
it('should login', async function () {
|
||||||
socket.emit(
|
try {
|
||||||
'login',
|
const channelName = (await socket.invoke('login', 'master')) as string;
|
||||||
'master',
|
expect(channelName).toBe('respond');
|
||||||
function (error: Error | undefined, channelName: string) {
|
channel = socket.subscribe(channelName);
|
||||||
if (error) {
|
expect(channel.SUBSCRIBED).toBe('subscribed');
|
||||||
/* eslint-disable-next-line no-console */
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
expect(channelName).toBe('respond');
|
|
||||||
channel = socket.subscribe(channelName);
|
|
||||||
expect(channel.SUBSCRIBED).toBe('subscribed');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send message', function () {
|
it('should send message', async function () {
|
||||||
return new Promise<void>((done) => {
|
const data = {
|
||||||
const data = {
|
type: 'ACTION',
|
||||||
type: 'ACTION',
|
payload: {
|
||||||
payload: {
|
todos: 'do some',
|
||||||
todos: 'do some',
|
},
|
||||||
},
|
action: {
|
||||||
|
timestamp: 1483349708506,
|
||||||
action: {
|
action: {
|
||||||
timestamp: 1483349708506,
|
type: 'ADD_TODO',
|
||||||
action: {
|
text: 'hggg',
|
||||||
type: 'ADD_TODO',
|
|
||||||
text: 'hggg',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
instanceId: 'tAmA7H5fclyWhvizAAAi',
|
},
|
||||||
name: 'LoggerInstance',
|
instanceId: 'tAmA7H5fclyWhvizAAAi',
|
||||||
id: 'tAmA7H5fclyWhvizAAAi',
|
name: 'LoggerInstance',
|
||||||
};
|
id: 'tAmA7H5fclyWhvizAAAi',
|
||||||
|
};
|
||||||
|
|
||||||
socket2.emit(
|
try {
|
||||||
'login',
|
const channelName = (await socket.invoke('login', '')) as string;
|
||||||
'',
|
expect(channelName).toBe('log');
|
||||||
function (error: Error | undefined, channelName: string) {
|
const channel2 = socket2.subscribe(channelName);
|
||||||
if (error) {
|
expect(channel2.SUBSCRIBED).toBe('subscribed');
|
||||||
/* eslint-disable-next-line no-console */
|
const message = await channel2.listener('subscribe').once();
|
||||||
console.log(error);
|
expect(message).toEqual(data);
|
||||||
return;
|
} catch (error) {
|
||||||
}
|
console.log(error);
|
||||||
expect(channelName).toBe('log');
|
}
|
||||||
const channel2 = socket2.subscribe(channelName);
|
|
||||||
expect(channel2.SUBSCRIBED).toBe('subscribed');
|
|
||||||
channel2.on('subscribe', function () {
|
|
||||||
channel2.watch(function (message) {
|
|
||||||
expect(message).toEqual(data);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
socket.emit(channelName, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -149,97 +136,61 @@ describe('Server', function () {
|
||||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) ' +
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) ' +
|
||||||
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36',
|
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36',
|
||||||
};
|
};
|
||||||
it('should add a report', function () {
|
it('should add a report', async function () {
|
||||||
return new Promise<void>((done) => {
|
const res = await request('http://localhost:8000')
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
.post('/')
|
||||||
request('http://localhost:8000')
|
.send(report)
|
||||||
.post('/')
|
.set('Accept', 'application/json')
|
||||||
.send(report)
|
.expect('Content-Type', /application\/json/)
|
||||||
.set('Accept', 'application/json')
|
.expect(200);
|
||||||
.expect('Content-Type', /application\/json/)
|
id = res.body.id;
|
||||||
.expect(200)
|
expect(id).toBeTruthy();
|
||||||
.then(function (res: { body: { id: string } }) {
|
|
||||||
id = res.body.id;
|
|
||||||
expect(id).toBeTruthy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get the report', function () {
|
it('should get the report', async function () {
|
||||||
return new Promise<void>((done) => {
|
const res = await request('http://localhost:8000')
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
.post('/')
|
||||||
request('http://localhost:8000')
|
.send({
|
||||||
.post('/')
|
op: 'get',
|
||||||
.send({
|
id: id,
|
||||||
op: 'get',
|
})
|
||||||
id: id,
|
.set('Accept', 'application/json')
|
||||||
})
|
.expect('Content-Type', /application\/json/)
|
||||||
.set('Accept', 'application/json')
|
.expect(200);
|
||||||
.expect('Content-Type', /application\/json/)
|
expect(res.body).toMatchObject(report);
|
||||||
.expect(200)
|
|
||||||
.then(function (res: { body: unknown }) {
|
|
||||||
expect(res.body).toMatchObject(report);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should list reports', function () {
|
it('should list reports', async function () {
|
||||||
return new Promise<void>((done) => {
|
const res = await request('http://localhost:8000')
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
.post('/')
|
||||||
request('http://localhost:8000')
|
.send({
|
||||||
.post('/')
|
op: 'list',
|
||||||
.send({
|
})
|
||||||
op: 'list',
|
.set('Accept', 'application/json')
|
||||||
})
|
.expect('Content-Type', /application\/json/)
|
||||||
.set('Accept', 'application/json')
|
.expect(200);
|
||||||
.expect('Content-Type', /application\/json/)
|
expect(res.body).toHaveLength(1);
|
||||||
.expect(200)
|
expect(res.body[0].id).toBe(id);
|
||||||
.then(function (res: {
|
expect(res.body[0].title).toBe('Test report');
|
||||||
body: { id: string; title: string | null; added: string | null }[];
|
expect(res.body[0].added).toBeTruthy();
|
||||||
}) {
|
|
||||||
expect(res.body).toHaveLength(1);
|
|
||||||
expect(res.body[0].id).toBe(id);
|
|
||||||
expect(res.body[0].title).toBe('Test report');
|
|
||||||
expect(res.body[0].added).toBeTruthy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GraphQL backend', function () {
|
describe('GraphQL backend', function () {
|
||||||
it('should get the report', function () {
|
it('should get the report', async function () {
|
||||||
return new Promise<void>((done) => {
|
const res = await request('http://localhost:8000')
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
.post('/graphql')
|
||||||
request('http://localhost:8000')
|
.send({
|
||||||
.post('/graphql')
|
query: '{ reports { id, type, title } }',
|
||||||
.send({
|
})
|
||||||
query: '{ reports { id, type, title } }',
|
.set('Accept', 'application/json')
|
||||||
})
|
.expect('Content-Type', /application\/json/)
|
||||||
.set('Accept', 'application/json')
|
.expect(200);
|
||||||
.expect('Content-Type', /application\/json/)
|
const reports = res.body.data.reports;
|
||||||
.expect(200)
|
expect(reports).toHaveLength(1);
|
||||||
.then(function (res: {
|
expect(reports[0].id).toBeTruthy();
|
||||||
body: {
|
expect(reports[0].title).toBe('Test report');
|
||||||
data: {
|
expect(reports[0].type).toBe('ACTIONS');
|
||||||
reports: {
|
|
||||||
id: string;
|
|
||||||
title: string | null;
|
|
||||||
type: string | null;
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}) {
|
|
||||||
const reports = res.body.data.reports;
|
|
||||||
expect(reports).toHaveLength(1);
|
|
||||||
expect(reports[0].id).toBeTruthy();
|
|
||||||
expect(reports[0].title).toBe('Test report');
|
|
||||||
expect(reports[0].type).toBe('ACTIONS');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
"jsan": "^3.1.14",
|
"jsan": "^3.1.14",
|
||||||
"querystring": "^0.2.1",
|
"querystring": "^0.2.1",
|
||||||
"rn-host-detect": "^1.2.0",
|
"rn-host-detect": "^1.2.0",
|
||||||
"socketcluster-client": "^14.3.2"
|
"socketcluster-client": "^16.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.17.10",
|
"@babel/cli": "^7.17.10",
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
"@types/jsan": "^3.1.2",
|
"@types/jsan": "^3.1.2",
|
||||||
"@types/node": "^16.11.38",
|
"@types/node": "^16.11.38",
|
||||||
"@types/rn-host-detect": "^1.2.0",
|
"@types/rn-host-detect": "^1.2.0",
|
||||||
"@types/socketcluster-client": "^13.0.5",
|
"@types/socketcluster-client": "^16.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
||||||
"@typescript-eslint/parser": "^5.27.0",
|
"@typescript-eslint/parser": "^5.27.0",
|
||||||
"eslint": "^8.17.0",
|
"eslint": "^8.17.0",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { stringify, parse } from 'jsan';
|
import { stringify, parse } from 'jsan';
|
||||||
import socketCluster, { SCClientSocket } from 'socketcluster-client';
|
import socketClusterClient, { AGClientSocket } from 'socketcluster-client';
|
||||||
import configureStore from './configureStore';
|
import configureStore from './configureStore';
|
||||||
import { defaultSocketOptions } from './constants';
|
import { defaultSocketOptions } from './constants';
|
||||||
import getHostForRN from 'rn-host-detect';
|
import getHostForRN from 'rn-host-detect';
|
||||||
|
@ -179,7 +179,7 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
store!: EnhancedStore<S, A, {}>;
|
store!: EnhancedStore<S, A, {}>;
|
||||||
filters: LocalFilter | undefined;
|
filters: LocalFilter | undefined;
|
||||||
instanceId?: string;
|
instanceId?: string;
|
||||||
socket?: SCClientSocket;
|
socket?: AGClientSocket;
|
||||||
sendTo?: string;
|
sendTo?: string;
|
||||||
instanceName: string | undefined;
|
instanceName: string | undefined;
|
||||||
appInstanceId!: string;
|
appInstanceId!: string;
|
||||||
|
@ -241,7 +241,8 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
) {
|
) {
|
||||||
const message: MessageToRelay = {
|
const message: MessageToRelay = {
|
||||||
type,
|
type,
|
||||||
id: this.socket!.id,
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
id: this.socket!.id!,
|
||||||
name: this.instanceName,
|
name: this.instanceName,
|
||||||
instanceId: this.appInstanceId,
|
instanceId: this.appInstanceId,
|
||||||
};
|
};
|
||||||
|
@ -279,7 +280,8 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
} else if (action) {
|
} else if (action) {
|
||||||
message.action = action as ActionCreatorObject[];
|
message.action = action as ActionCreatorObject[];
|
||||||
}
|
}
|
||||||
this.socket!.emit(this.socket!.id ? 'log' : 'log-noid', message);
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
void this.socket!.transmit(this.socket!.id ? 'log' : 'log-noid', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchRemotely(
|
dispatchRemotely(
|
||||||
|
@ -300,7 +302,9 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
if (
|
if (
|
||||||
message.type === 'IMPORT' ||
|
message.type === 'IMPORT' ||
|
||||||
(message.type === 'SYNC' &&
|
(message.type === 'SYNC' &&
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
this.socket!.id &&
|
this.socket!.id &&
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
message.id !== this.socket!.id)
|
message.id !== this.socket!.id)
|
||||||
) {
|
) {
|
||||||
this.store.liftedStore.dispatch({
|
this.store.liftedStore.dispatch({
|
||||||
|
@ -387,15 +391,22 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
login() {
|
login() {
|
||||||
this.socket!.emit('login', 'master', (err: Error, channelName: string) => {
|
void (async () => {
|
||||||
if (err) {
|
try {
|
||||||
console.log(err);
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
return;
|
const channelName = (await this.socket!.invoke(
|
||||||
|
'login',
|
||||||
|
'master'
|
||||||
|
)) as string;
|
||||||
|
this.channel = channelName;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
for await (const data of this.socket!.subscribe(channelName)) {
|
||||||
|
this.handleMessages(data as Message<S, A>);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
this.channel = channelName;
|
})();
|
||||||
this.socket!.subscribe(channelName).watch(this.handleMessages);
|
|
||||||
this.socket!.on(channelName, this.handleMessages);
|
|
||||||
});
|
|
||||||
this.started = true;
|
this.started = true;
|
||||||
this.relay('START');
|
this.relay('START');
|
||||||
}
|
}
|
||||||
|
@ -404,11 +415,9 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.isMonitored = false;
|
this.isMonitored = false;
|
||||||
if (!this.socket) return;
|
if (!this.socket) return;
|
||||||
this.socket.destroyChannel(this.channel!);
|
void this.socket.unsubscribe(this.channel!);
|
||||||
if (keepConnected) {
|
this.socket.closeChannel(this.channel!);
|
||||||
this.socket.off(this.channel, this.handleMessages);
|
if (!keepConnected) {
|
||||||
} else {
|
|
||||||
this.socket.off();
|
|
||||||
this.socket.disconnect();
|
this.socket.disconnect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -420,36 +429,48 @@ class DevToolsEnhancer<S, A extends Action<unknown>> {
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.socket = socketCluster.create(this.socketOptions);
|
this.socket = socketClusterClient.create(this.socketOptions);
|
||||||
|
|
||||||
this.socket.on('error', (err) => {
|
void (async () => {
|
||||||
// if we've already had this error before, increment it's counter, otherwise assign it '1' since we've had the error once.
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
// eslint-disable-next-line no-prototype-builtins
|
for await (const data of this.socket!.listener('error')) {
|
||||||
this.errorCounts[err.name] = this.errorCounts.hasOwnProperty(err.name)
|
// if we've already had this error before, increment it's counter, otherwise assign it '1' since we've had the error once.
|
||||||
? this.errorCounts[err.name] + 1
|
// eslint-disable-next-line no-prototype-builtins,@typescript-eslint/no-unsafe-argument
|
||||||
: 1;
|
this.errorCounts[data.error.name] = this.errorCounts.hasOwnProperty(
|
||||||
|
data.error.name
|
||||||
|
)
|
||||||
|
? this.errorCounts[data.error.name] + 1
|
||||||
|
: 1;
|
||||||
|
|
||||||
if (this.suppressConnectErrors) {
|
if (this.suppressConnectErrors) {
|
||||||
if (this.errorCounts[err.name] === 1) {
|
if (this.errorCounts[data.error.name] === 1) {
|
||||||
console.log(
|
console.log(
|
||||||
'remote-redux-devtools: Socket connection errors are being suppressed. ' +
|
'remote-redux-devtools: Socket connection errors are being suppressed. ' +
|
||||||
'\n' +
|
'\n' +
|
||||||
"This can be disabled by setting suppressConnectErrors to 'false'."
|
"This can be disabled by setting suppressConnectErrors to 'false'."
|
||||||
);
|
);
|
||||||
console.log(err);
|
console.log(data.error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(data.error);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log(err);
|
|
||||||
}
|
}
|
||||||
});
|
})();
|
||||||
this.socket.on('connect', () => {
|
|
||||||
console.log('connected to remotedev-server');
|
void (async () => {
|
||||||
this.errorCounts = {}; // clear the errorCounts object, so that we'll log any new errors in the event of a disconnect
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
this.login();
|
for await (const data of this.socket!.listener('connect')) {
|
||||||
});
|
console.log('connected to remotedev-server');
|
||||||
this.socket.on('disconnect', () => {
|
this.errorCounts = {}; // clear the errorCounts object, so that we'll log any new errors in the event of a disconnect
|
||||||
this.stop(true);
|
this.login();
|
||||||
});
|
}
|
||||||
|
})();
|
||||||
|
void (async () => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
for await (const data of this.socket!.listener('disconnect')) {
|
||||||
|
this.stop(true);
|
||||||
|
}
|
||||||
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
checkForReducerErrors = (liftedState = this.getLiftedStateRaw()) => {
|
checkForReducerErrors = (liftedState = this.getLiftedStateRaw()) => {
|
||||||
|
|
673
pnpm-lock.yaml
673
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user